ody/logger
Composer 安装命令:
composer require ody/logger
包简介
logging integration for ODY Framework
README 文档
README
Logging is configured in config/logging.php and provides various channels for logging:
// Using the logger $logger->info('User logged in', ['id' => $userId]); $logger->error('Failed to process payment', ['order_id' => $orderId]); // Using the logger helper function logger()->info('Processing request');
Custom Loggers in ODY Framework
Creating Custom Loggers
Basic Requirements
All custom loggers must:
- Extend
Ody\Logger\AbstractLogger - Implement a static
create(array $config)method - Override the
write(string $level, string $message, array $context = [])method
Example: Creating a Custom Logger
Here's a simple example of a custom logger that logs to Redis:
<?php namespace App\Logging; use Ody\Logger\AbstractLogger;use Ody\Logger\Formatters\FormatterInterface;use Ody\Logger\Formatters\JsonFormatter;use Ody\Logger\Formatters\LineFormatter;use Psr\Log\LoggerInterface;use Psr\Log\LogLevel;use Redis; class RedisLogger extends AbstractLogger { /** * @var Redis */ protected Redis $redis; /** * @var string */ protected string $channel; /** * Constructor */ public function __construct( Redis $redis, string $channel = 'logs', string $level = LogLevel::DEBUG, ?FormatterInterface $formatter = null ) { parent::__construct($level, $formatter); $this->redis = $redis; $this->channel = $channel; } /** * Create a Redis logger from configuration */ public static function create(array $config): LoggerInterface { // Create Redis connection $redis = new Redis(); $redis->connect( $config['host'] ?? '127.0.0.1', $config['port'] ?? 6379 ); if (isset($config['password'])) { $redis->auth($config['password']); } // Create formatter $formatter = null; if (isset($config['formatter'])) { $formatter = self::createFormatter($config); } // Return new logger instance return new self( $redis, $config['channel'] ?? 'logs', $config['level'] ?? LogLevel::DEBUG, $formatter ); } /** * Create a formatter based on configuration */ protected static function createFormatter(array $config): FormatterInterface { $formatterType = $config['formatter'] ?? 'json'; if ($formatterType === 'line') { return new LineFormatter( $config['format'] ?? null, $config['date_format'] ?? null ); } return new JsonFormatter(); } /** * {@inheritdoc} */ protected function write(string $level, string $message, array $context = []): void { // Format log data $logData = [ 'timestamp' => time(), 'level' => $level, 'message' => $message, 'context' => $context ]; // Publish to Redis channel $this->redis->publish( $this->channel, json_encode($logData) ); } }
The create() Method
The static create() method is responsible for instantiating your logger based on configuration:
public static function create(array $config): LoggerInterface { // Create dependencies based on configuration // ... // Return new logger instance return new self(...); }
This method receives the channel configuration from the logging.php config file and should:
- Create any dependencies the logger needs
- Configure those dependencies based on the config array
- Return a new instance of the logger
The write() Method
The write() method is where the actual logging happens:
protected function write(string $level, string $message, array $context = []): void { // Implement logging logic here }
This method is called by the parent AbstractLogger class when a log message needs to be written. It receives:
$level: The log level (debug, info, warning, etc.)$message: The formatted log message$context: Additional context data
Using Custom Loggers
Method 1: Configuration-Based Discovery
The simplest way to use a custom logger is to specify the fully-qualified class name in your logging configuration:
// In config/logging.php 'channels' => [ 'redis' => [ 'driver' => 'redis', 'class' => \App\Logging\RedisLogger::class, 'host' => env('REDIS_HOST', '127.0.0.1'), 'port' => env('REDIS_PORT', 6379), 'channel' => 'application_logs', 'level' => 'debug', ], ]
When you specify a class parameter, that class will be used regardless of the driver name.
Method 2: Driver Name Registration
You can register your logger with a driver name, which allows you to reference it using just the driver name:
// In a service provider's register method $this->app->make(\Ody\Logger\LogManager::class) ->registerDriver('redis', \App\Logging\RedisLogger::class);
Then in your configuration:
// In config/logging.php 'channels' => [ 'redis' => [ 'driver' => 'redis', // This will use the registered RedisLogger 'host' => env('REDIS_HOST', '127.0.0.1'), 'port' => env('REDIS_PORT', 6379), 'channel' => 'application_logs', 'level' => 'debug', ], ]
Method 3: Automatic Discovery
If your logger follows the naming convention {Driver}Logger and is in one of the registered namespaces, it will be discovered automatically:
// In config/logging.php 'channels' => [ 'redis' => [ 'driver' => 'redis', // Will look for RedisLogger // Configuration... ], ]
The framework will search for RedisLogger in the registered namespaces (\Ody\Logger\ and \App\Logging\ by default).
Creating Custom Formatters
If the standard formatters don't meet your needs, you can create your own by implementing the FormatterInterface:
namespace App\Logging; use Ody\Logger\Formatters\FormatterInterface; class CustomFormatter implements FormatterInterface { public function format(string $level, string $message, array $context = []): string { // Custom formatting logic return "[$level] $message " . json_encode($context); } }
Complete Example: Using Redis Logger
Configuration
// In config/logging.php 'channels' => [ // Using explicit class 'redis' => [ 'driver' => 'redis', 'class' => \App\Logging\RedisLogger::class, 'host' => env('REDIS_HOST', '127.0.0.1'), 'port' => env('REDIS_PORT', 6379), 'password' => env('REDIS_PASSWORD', null), 'channel' => 'app_logs', 'formatter' => 'json', 'level' => 'debug', ], // Using it in a stack 'production' => [ 'driver' => 'group', 'channels' => ['file', 'redis'], ], ],
Usage
// Send to redis channel logger('User registered', ['id' => 123], 'redis'); // Or use the stack logger('API request processed', ['endpoint' => '/users']);
With this system, you can create custom loggers that integrate seamlessly with the ODY Framework logging infrastructure.
ody/logger 适用场景与选型建议
ody/logger 是一款 基于 PHP 开发的 Composer 扩展包,目前已累计 35 次下载、GitHub Stars 达 0, 最近一次更新时间为 2025 年 03 月 15 日, 在 PHP 生态内属于活跃度较高的组件。
它主要适用于以下技术方向: 「logging」 「ody」 等业务场景。在实际项目中,围绕这些方向常见需要落地的问题包括:接口对接、性能调优、并发安全、与既有框架(Laravel / ThinkPHP / Yii / Webman 等)的兼容适配,以及生产环境的日志埋点与稳定性保障。
我们在过去多个企业项目中使用过 ody/logger 或与其功能相近的方案,如果你在选型或落地过程中遇到问题,例如 版本兼容、二次改造、私有化封装、与内部系统对接、生产 BUG 排查,欢迎联系我们协助评估。
基于 ody/logger 在你已有业务上做功能扩展、字段裁剪、UI 适配、与内部账号 / 权限 / 日志系统的深度对接。
线上偶发问题、内存泄漏、慢查询、并发异常等排查修复;针对高流量场景做缓存、队列、索引层面的调优。
承接完整的项目从需求 → 设计 → 开发 → 上线 → 长期运维;也可按月提供技术保姆服务。
与 ody/logger 相关的其它包
同方向 / 同关键字的高下载量 PHP Composer 包推荐,方便对比选型:
A Zend Framework module that sets up Monolog for logging in applications.
Asynchronous Sentry for Symfony - Fire and forget
Stackdriver handler for Monolog (codeinternetapplications/monolog-stackdriver Fork).
High-performance, zero-dependency PSR-3 logger for MonkeysLegion with structured logging, handlers, processors, and PHP 8.4 features.
Audit changes of your Eloquent models in Laravel/Lumen
Ship logs and exceptions from a Laravel app to a Log Central server.
统计信息
- 总下载量: 35
- 月度下载量: 0
- 日度下载量: 0
- 收藏数: 0
- 点击次数: 17
- 依赖项目数: 2
- 推荐数: 0
其他信息
- 授权协议: MIT
- 更新时间: 2025-03-15