Logging
Sockeon provides a comprehensive logging system for debugging and monitoring your applications. This guide covers how to use logging effectively.
Overview
Sockeon's logging system is built into the framework. You can:
- Log messages at different levels
- Configure logging for different environments
- Log HTTP requests and WebSocket events
- Handle errors with detailed logging
Basic Logging
Creating a Logger
use Sockeon\Sockeon\Logging\Logger;
use Sockeon\Sockeon\Logging\LogLevel;
// Development logger
$logger = new Logger(
LogLevel::DEBUG, // Minimum log level
true, // Log to console
true, // Log to file
'logs', // Log directory
true // Separate log files
);
// Production logger
$logger = new Logger(
LogLevel::ERROR, // Only log errors and above
false, // Don't log to console
true, // Log to file
'logs',
true
);
Using Logger in Controllers
class ChatController extends SocketController
{
#[SocketOn('chat.message')]
public function handleMessage(int $clientId, array $data): void
{
// Log info message
$this->getLogger()->info('Chat message received', [
'clientId' => $clientId,
'message' => $data['message'] ?? ''
]);
$this->broadcast('chat.message', [
'user' => $clientId,
'message' => $data['message']
]);
}
#[OnConnect]
public function onConnect(int $clientId): void
{
// Log debug message
$this->getLogger()->debug('Client connected', [
'clientId' => $clientId,
'timestamp' => time()
]);
$this->emit($clientId, 'welcome', ['message' => 'Welcome!']);
}
#[OnDisconnect]
public function onDisconnect(int $clientId): void
{
// Log warning message
$this->getLogger()->warning('Client disconnected', [
'clientId' => $clientId,
'timestamp' => time()
]);
}
}
Log Levels
Sockeon supports standard log levels:
use Sockeon\Sockeon\Logging\LogLevel;
// Emergency - System is unusable
$logger->emergency('System is down');
// Alert - Action must be taken immediately
$logger->alert('Database connection failed');
// Critical - Critical conditions
$logger->critical('Application crash detected');
// Error - Error conditions
$logger->error('Failed to process request');
// Warning - Warning conditions
$logger->warning('High memory usage detected');
// Notice - Normal but significant events
$logger->notice('User logged in');
// Info - Informational messages
$logger->info('Request processed successfully');
// Debug - Debug-level messages
$logger->debug('Processing step 1 of 3');
Log Level Hierarchy
EMERGENCY (highest priority)
↓
ALERT
↓
CRITICAL
↓
ERROR
↓
WARNING
↓
NOTICE
↓
INFO
↓
DEBUG (lowest priority)
HTTP Request Logging
class ApiController extends SocketController
{
#[HttpRoute('POST', '/api/users')]
public function createUser(Request $request): Response
{
$startTime = microtime(true);
// Log request details
$this->getLogger()->info('HTTP request received', [
'method' => $request->getMethod(),
'path' => $request->getPath(),
'clientIp' => $request->getClientIp(),
'userAgent' => $request->getHeader('User-Agent')
]);
try {
$data = $request->all();
// Process request...
$user = $this->createUser($data);
$processingTime = (microtime(true) - $startTime) * 1000;
// Log successful response
$this->getLogger()->info('HTTP request completed', [
'statusCode' => 201,
'processingTime' => round($processingTime, 2) . 'ms'
]);
return Response::json(['user' => $user], 201);
} catch (Exception $e) {
$processingTime = (microtime(true) - $startTime) * 1000;
// Log error
$this->getLogger()->error('HTTP request failed', [
'error' => $e->getMessage(),
'processingTime' => round($processingTime, 2) . 'ms'
]);
return Response::json(['error' => 'Failed to create user'], 500);
}
}
}
Error Logging
class ErrorController extends SocketController
{
#[SocketOn('risky.operation')]
public function handleRiskyOperation(int $clientId, array $data): void
{
try {
// Perform risky operation
$result = $this->performRiskyOperation($data);
$this->emit($clientId, 'success', ['result' => $result]);
} catch (Exception $e) {
// Log error with context
$this->getLogger()->error('Risky operation failed', [
'clientId' => $clientId,
'error' => $e->getMessage(),
'trace' => $e->getTraceAsString(),
'data' => $data
]);
$this->emit($clientId, 'error', [
'message' => 'Operation failed'
]);
}
}
}
Logger Configuration
Logger Factory
class LoggerFactory
{
public static function createForEnvironment(string $environment): Logger
{
switch ($environment) {
case 'development':
return new Logger(
LogLevel::DEBUG,
true, // Console logging
true, // File logging
'logs',
true // Separate files
);
case 'production':
return new Logger(
LogLevel::ERROR,
false, // No console logging
true, // File logging
'logs',
true // Separate files
);
case 'testing':
return new Logger(
LogLevel::DEBUG,
false, // No console logging
false, // No file logging
'logs',
false
);
default:
return new Logger(
LogLevel::INFO,
true,
true,
'logs',
true
);
}
}
}
// Usage
$logger = LoggerFactory::createForEnvironment($_ENV['APP_ENV'] ?? 'development');
Logger Methods
$logger = new Logger(LogLevel::INFO);
// Change log level
$logger->setMinLogLevel(LogLevel::WARNING);
// Enable/disable console logging
$logger->setLogToConsole(false);
// Enable/disable file logging
$logger->setLogToFile(true);
// Set log directory
$logger->setLogDirectory('custom/logs');
// Enable/disable separate log files
$logger->setSeparateLogFiles(true);
Best Practices
Use Appropriate Log Levels
// Use DEBUG for detailed information
$logger->debug('Processing step 1 of 3');
// Use INFO for general information
$logger->info('User logged in', ['userId' => 123]);
// Use WARNING for potential issues
$logger->warning('High memory usage', ['usage' => '85%']);
// Use ERROR for actual errors
$logger->error('Database connection failed', ['error' => $e->getMessage()]);
Include Context
// Good - includes relevant context
$logger->info('User action', [
'userId' => $userId,
'action' => 'profile_update',
'timestamp' => time()
]);
// Bad - no context
$logger->info('User did something');
Don't Log Sensitive Information
// Good - log user ID but not password
$logger->info('User login attempt', [
'userId' => $userId,
'success' => $success
]);
// Bad - logs sensitive data
$logger->info('User login attempt', [
'userId' => $userId,
'password' => $password, // Don't log passwords!
'success' => $success
]);
Use Structured Logging
// Structured logging with consistent format
$logger->info('API request', [
'method' => 'POST',
'endpoint' => '/api/users',
'statusCode' => 201,
'processingTime' => '45ms',
'clientIp' => '192.168.1.1'
]);
Summary
Logging in Sockeon is:
- Built-in: Framework provides logging infrastructure
- Configurable: Different settings for different environments
- Comprehensive: Support for all log levels
- Contextual: Include relevant information in log messages
Use logging to monitor your application and debug issues effectively.