loreal-global-kickoff/ApplicationLogger.php
DJP 0571ce403f Add comprehensive logging for OMG API debugging and application tracking
OMG API Debug Logging:
- Log full URL being called
- Log API key (first 20 chars for security)
- Log HTTP response code
- Log response body (first 500 chars)
- Log campaign number and business area extraction
- Log business unit mapping result

ApplicationLogger Class:
- Structured JSON logging to logs/application.log
- Track all actions: master_asset_submission, global_to_local_transform, box_upload
- Capture user email, timestamp, IP address, user agent
- Methods for reporting: getRecentLogs(), getLogsByAction(), getLogsByUser()
- Generate statistics: total actions, by user, by action, errors

Email Configuration:
- Configured SMTP via Mailgun (smtp.mailgun.org:587)
- Using twist@mail.dev.oliver.solutions
- Emails sent to logged-in user

This enables full audit trail and troubleshooting capability.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-18 08:26:20 -05:00

200 lines
6.1 KiB
PHP

<?php
/**
* Application Logger
* Tracks all application actions for reporting and auditing
*/
class ApplicationLogger {
private $logFile;
private $config;
public function __construct() {
$appConfig = require __DIR__ . '/config.php';
$this->config = $appConfig;
// Create logs directory if it doesn't exist
$logsDir = __DIR__ . '/logs';
if (!file_exists($logsDir)) {
mkdir($logsDir, 0755, true);
}
$this->logFile = $logsDir . '/application.log';
}
/**
* Log action with structured data
*/
public function log($action, $user, $data = [], $status = 'success') {
$logEntry = [
'timestamp' => date('Y-m-d H:i:s'),
'action' => $action,
'user_email' => $user['email'] ?? 'unknown',
'user_name' => $user['name'] ?? 'unknown',
'status' => $status,
'data' => $data,
'ip_address' => $_SERVER['REMOTE_ADDR'] ?? 'unknown',
'user_agent' => $_SERVER['HTTP_USER_AGENT'] ?? 'unknown'
];
$logLine = json_encode($logEntry) . "\n";
// Append to log file
file_put_contents($this->logFile, $logLine, FILE_APPEND | LOCK_EX);
// Also log to PHP error log for debugging
error_log('[APP LOG] ' . $action . ' - ' . $status . ' - ' . ($user['email'] ?? 'unknown'));
return $logEntry;
}
/**
* Log Master Asset Submission
*/
public function logAssetSubmission($user, $boxId, $masterCampaignNumber, $dates, $status = 'success', $error = null) {
return $this->log('master_asset_submission', $user, [
'box_id' => $boxId,
'master_campaign_number' => $masterCampaignNumber,
'supply_date' => $dates['supply'] ?? null,
'live_date' => $dates['live'] ?? null,
'end_date' => $dates['end'] ?? null,
'error' => $error
], $status);
}
/**
* Log Global to Local Transformation
*/
public function logGlobalToLocal($user, $campaignNumber, $businessUnit, $inputRows, $outputFiles, $status = 'success', $error = null) {
return $this->log('global_to_local_transform', $user, [
'campaign_number' => $campaignNumber,
'business_unit' => $businessUnit,
'input_rows' => $inputRows,
'output_file_count' => $outputFiles,
'total_output_rows' => $inputRows * $outputFiles,
'error' => $error
], $status);
}
/**
* Log Box Upload
*/
public function logBoxUpload($user, $fileCount, $folderId, $status = 'success', $error = null) {
return $this->log('box_upload', $user, [
'file_count' => $fileCount,
'folder_id' => $folderId,
'error' => $error
], $status);
}
/**
* Log OMG API Call
*/
public function logOMGAPICall($user, $campaignNumber, $businessArea, $businessUnit, $status = 'success', $error = null) {
return $this->log('omg_api_lookup', $user, [
'campaign_number' => $campaignNumber,
'business_area' => $businessArea,
'business_unit' => $businessUnit,
'error' => $error
], $status);
}
/**
* Get recent logs
*/
public function getRecentLogs($limit = 100) {
if (!file_exists($this->logFile)) {
return [];
}
$lines = file($this->logFile, FILE_IGNORE_NEW_LINES);
$lines = array_reverse($lines); // Most recent first
$lines = array_slice($lines, 0, $limit);
$logs = [];
foreach ($lines as $line) {
$log = json_decode($line, true);
if ($log) {
$logs[] = $log;
}
}
return $logs;
}
/**
* Get logs by action type
*/
public function getLogsByAction($action, $limit = 100) {
$allLogs = $this->getRecentLogs(1000);
$filtered = array_filter($allLogs, function($log) use ($action) {
return $log['action'] === $action;
});
return array_slice(array_values($filtered), 0, $limit);
}
/**
* Get logs by user
*/
public function getLogsByUser($userEmail, $limit = 100) {
$allLogs = $this->getRecentLogs(1000);
$filtered = array_filter($allLogs, function($log) use ($userEmail) {
return $log['user_email'] === $userEmail;
});
return array_slice(array_values($filtered), 0, $limit);
}
/**
* Generate report statistics
*/
public function getStatistics($startDate = null, $endDate = null) {
$allLogs = $this->getRecentLogs(10000);
// Filter by date if provided
if ($startDate || $endDate) {
$allLogs = array_filter($allLogs, function($log) use ($startDate, $endDate) {
$timestamp = strtotime($log['timestamp']);
if ($startDate && $timestamp < strtotime($startDate)) return false;
if ($endDate && $timestamp > strtotime($endDate)) return false;
return true;
});
}
$stats = [
'total_actions' => count($allLogs),
'by_action' => [],
'by_user' => [],
'by_status' => [],
'errors' => []
];
foreach ($allLogs as $log) {
// Count by action
$action = $log['action'];
$stats['by_action'][$action] = ($stats['by_action'][$action] ?? 0) + 1;
// Count by user
$user = $log['user_email'];
$stats['by_user'][$user] = ($stats['by_user'][$user] ?? 0) + 1;
// Count by status
$status = $log['status'];
$stats['by_status'][$status] = ($stats['by_status'][$status] ?? 0) + 1;
// Collect errors
if ($status === 'error') {
$stats['errors'][] = [
'timestamp' => $log['timestamp'],
'action' => $log['action'],
'user' => $log['user_email'],
'error' => $log['data']['error'] ?? 'Unknown error'
];
}
}
return $stats;
}
}