ThinkPHP 如何在生产环境中配置日志?

在ThinkPHP生产环境中配置日志时,需要重点关注稳定性、性能和安全。以下是最佳实践配置方案:

生产环境推荐配置 (config/log.php)

return [
    'default' => env('log.channel', 'stack'),
    'channels' => [
        // 组合通道(核心配置)
        'stack' => [
            'type' => 'stack',
            'channels' => ['daily', 'error_file', 'emergency'],
        ],
        
        // 按日分割的常规日志
        'daily' => [
            'type' => 'file',
            'path' => runtime_path('logs/daily'),
            'level' => ['info', 'notice', 'warning'],
            'max_files' => 30, // 保留30天
            'file_size' => 10485760, // 10MB分割文件
            'json' => false,
            'format' => '[%s][%s] %s %s', // 简化格式
        ],
        
        // 错误日志单独通道
        'error_file' => [
            'type' => 'file',
            'path' => runtime_path('logs/error'),
            'level' => ['error', 'critical'],
            'max_files' => 90, // 保留90天
            'apart_level' => true, // 每个级别单独文件
            'file_size' => 20971520, // 20MB分割
            'json' => true, // JSON格式便于分析
        ],
        
        // 紧急事件单独处理
        'emergency' => [
            'type' => 'file',
            'path' => runtime_path('logs/emergency'),
            'level' => ['emergency'],
            'max_files' => 365, // 保留1年
        ],
        
        // 数据库日志(审计需要)
        'audit' => [
            'type' => 'database',
            'table' => 'system_logs',
            'connection' => 'log_db',
            'level' => ['info', 'notice'],
            'ignore_fields' => ['password', 'token'], // 忽略敏感字段
        ],
        
        // 外部日志服务
        'cloud' => [
            'type' => 'custom',
            'driver' => \app\log\driver\CloudLogger::class, // 自定义驱动
            'level' => ['error', 'emergency'],
            'endpoint' => 'https://log.example.com/api',
        ]
    ]
];

关键配置说明

1. 日志分级存储策略
'stack' => [
    'type' => 'stack',
    'channels' => ['daily', 'error_file', 'emergency'],
]
  • 优势:不同级别日志分离存储
  • 日志分布
    • 常规日志:30天轮转
    • 错误日志:90天保留
    • 紧急日志:1年保留
2. 性能优化配置
'daily' => [
    'file_size' => 10485760, // 10MB分割文件
    'max_files' => 30,       // 最多保留30个文件
],
  • 避免大文件:超过10MB自动分割
  • 自动清理:仅保留最近30天日志
3. 安全增强措施
'database' => [
    'ignore_fields' => ['password', 'token'], // 过滤敏感数据
],

在自定义格式化类中添加过滤:

class SafeLogFormatter {
    protected function format($msg, $type, $context) {
        // 过滤敏感信息
        $context = array_filter($context, function($key) {
            return !in_array($key, ['password', 'credit_card']);
        }, ARRAY_FILTER_USE_KEY);
        
        return json_encode(['msg'=>$msg, 'ctx'=>$context]);
    }
}
4. 高可用方案
'cloud' => [
    'type' => 'custom',
    'driver' => \app\log\driver\CloudLogger::class,
]

自定义云日志驱动示例

class CloudLogger {
    public function save(array $log) {
        try {
            // 主服务写入
            $this->sendToElasticSearch($log);
        } catch (\Exception $e) {
            // 失败时写入本地备份
            Log::channel('local_fallback')->error($log);
        }
    }
}
5. 日志文件权限控制

在入口文件(public/index.php)添加:

// 设置日志目录权限 (640)
umask(0027);

.env 环境变量配置

# 日志默认通道
LOG_CHANNEL=stack

# 错误通知阈值
LOG_ERROR_THRESHOLD=50

# 云日志配置
LOG_CLOUD_ENDPOINT=https://logs.prod.example.com
LOG_CLOUD_KEY=your_api_key_here

生产环境最佳实践

  1. 日志监控报警

    // 在全局异常处理中
    report(function (\Throwable $e) {
        Log::channel('error_file')->error($e->getMessage());
        
        // 每小时错误超过阈值报警
        if (Log::getErrorCount() > env('LOG_ERROR_THRESHOLD', 50)) {
            Alert::sendToOpsTeam();
        }
    });
    
  2. 日志压缩归档

    # 每日凌晨压缩旧日志
    0 2 * * * find /path/to/runtime/logs -name "*.log" -mtime +30 -exec gzip {} \;
    
  3. 访问控制(Nginx)

    location ~ ^/runtime/logs/ {
        deny all;
        return 403;
    }
    
  4. 性能关键位置禁用日志

    // 高并发接口中
    public function paymentNotify()
    {
        // 临时关闭日志
        Log::close();
        
        // 业务逻辑...
        
        // 恢复日志
        Log::init();
    }
    

灾难恢复方案

  1. 双写策略

    'channels' => [
        'local_and_cloud' => [
            'type' => 'stack',
            'channels' => ['daily', 'cloud'],
        ]
    ]
    
  2. 日志完整性校验

    class LogVerifier {
        public static function verifyIntegrity($logFile) {
            $hash = md5_file($logFile);
            file_put_contents($logFile.'.md5', $hash);
        }
    }
    
  3. 关键操作审计跟踪

    Log::channel('audit')->info('用户权限变更', [
        'operator' => Auth::id(),
        'target_user' => $userId,
        'changes' => $permissionChanges,
        'ip' => request()->ip()
    ]);
    

验证配置是否生效

创建校验路由:

Route::get('log-check', function() {
    // 测试各级别日志
    Log::debug('Debug test - should not appear in prod');
    Log::info('Info message');
    Log::error('Error test');
    Log::emergency('Emergency test!');
    
    // 检查日志目录结构
    $tree = shell_exec('tree '.runtime_path('logs'));
    
    return '<pre>Log test completed. Directory structure:\n'.$tree;
})->middleware('auth:admin');

生产环境日志配置的核心原则:

  1. 分级存储:不同级别日志分离处理
  2. 生命周期管理:自动轮转和清理
  3. 安全防护:敏感数据过滤和访问控制
  4. 灾难恢复:本地+云端的双保险方案
  5. 性能优化:避免日志成为系统瓶颈

遵循这些原则可确保在生产环境中既保留足够的排查线索,又不会影响系统性能和安全性。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值