Logger
Miko's Logger writes to separate channel files. All methods are static. There is no new Logger('logs/app.log') instance API.
Namespace: Miko\Log\Logger.
Log directory: Miko/Log/ (sibling of the Miko/Miko library folder). Files rotate when they exceed LOG_MAX_SIZE_MB (default 3).
Channels
| Channel method | File | Use for |
|---|---|---|
Logger::queryBuilder($message, $context, $level) | querybuilder.log | SQL / query builder |
Logger::connection($message, $context, $level) | connection.log | PDO / connection |
Logger::api($message, $context, $level) | api.log | HTTP / API |
Logger::business($message, $context, $level) | business.log | Domain logic |
Logger::general($message, $context, $level) | application.log | Everything else |
$level defaults to 'ERROR'. Allowed: DEBUG, INFO, WARNING, ERROR, CRITICAL.
use Miko\Log\Logger;
Logger::api('User logged in', ['user_id' => 123], 'INFO');
Logger::connection('Reconnect failed', ['host' => 'localhost']);
Logger::business('Invoice total mismatch', ['invoice_id' => 88], 'WARNING');
Logger::general('Unhandled case', ['code' => 'X1'], 'DEBUG');
PHP error handlers
autoload.php already calls this. Call it yourself only if you load files without the autoloader:
Logger::registerPhpErrorHandlers();
PHP errors and uncaught exceptions go to application.log. Native PHP error_log is pointed at Log/php_error.log so a cwd error_log file is not created.
Helpers
Logger::logQuery($sql, $bindings, $error = null);
Logger::logApiRequest($method, $endpoint, $params = [], $error = null);
Logger::logConnectionError($message, $context = []);
Logger::logBusinessError($message, $context = []);
$removed = Logger::clearOldLogs(30); // delete files older than N days
$size = Logger::getLogSize('general'); // bytes
$lines = Logger::readLastLines('api', 100); // last N lines of a channel
Query logger (separate class)
Miko\Database\Log\QueryLogger records SQL in memory when enabled. Timing key is time_ms, not time.
use Miko\Database\Log\QueryLogger;
QueryLogger::enable();
QueryLogger::setSlowThreshold(100); // milliseconds
$users = User::where('IsActive', true)->get();
foreach (QueryLogger::getQueries() as $query) {
echo $query['sql'] . "\n";
echo 'Time: ' . $query['time_ms'] . "ms\n";
}
$slow = QueryLogger::getSlowQueries();
$stats = QueryLogger::getStats();
QueryLogger::clear();