+1

[Symfony 4] Ẩn một số log không cần thiết với custom handler

Bối cảnh

Symfony phát sinh khá nhiều log như, như process init, begin transaction, ini, . Hầu như những log này cung cấp thông tin ít quan trọng, nhưng lại gây nhiễu hệ thống log và đặc biệt là tốn tiền khách hàng (khi dùng các dịch vụ cloud như AWS Cloudwatch log để lưu trữ và filter log). Sau đây là các cách để ẩn bớt đi nhé

Giải phát

Dùng log level setting

Trong file monolog.yml, set biến log level tới 1 cấp đó mà bạn cảm thấy cần thiết, phục vụ tốt thông tin cho việc debug và các task điều tra

        cloudWatch:
            type: service
            action_level: "%env(LOG_LEVEL)%"
            id: cloudwatch_handler
            channels: ["!event", "!doctrine", "!php"]

Các cấp độ setting log level các bạn có thể tham khảo

DEBUG: Detailed debug information.
INFO: Interesting events or information.
NOTICE: Normal but significant events.
WARNING: Exceptional occurrences that are not errors.
ERROR: Runtime errors that do not require immediate action.
CRITICAL: Critical conditions.
ALERT: Action must be taken immediately.
EMERGENCY: System is unusable.

Dùng custom handler (xịn hơn)

Vì các log dư này đa phần là log debug và log info, nó cũng cùng cấp độ với các log mình hay add vào để điều tra, nên rất khó dùng cách trên, vậy nên dùng 1 handle đứng đầu để lọc bớt các message chỉ định cụ thể là giải pháp mình thấy khá ổn

  • Tạo 1 custom handle đừng đầu chuỗi log.
handlers:
        main:
            type: service
            id: monolog.custom_handler.service            
            level: debug 
            handler: cloudWatch
  • Trong service.yml thêm define class.
    monolog.custom_handler.service:
        class: Customize\Log\CustomHandler
  • Trong folder Customize/Log thêm class:
<?php

namespace Customize\Log;

use Monolog\Handler\AbstractHandler;

class CustomHandler extends AbstractHandler
{
    public function handle(array $record) {
        // Check if handling level was reached
        if ($record['level'] < $this->level) 
            return false;

        $listMessageRemoved = [
            'INIT',
            'PROCESS START',
            'PROCESS END',
            'User was reloaded',
            'Checking support on guard authenticator',
            'Guard authenticator does not support the request',
            'Checking for guard authentication credentials',
            'Read existing security token from the session',
            'Stored the security token in the session',
            'Matched route',
            'LOGIC START',
            'LOGIC END',
            'Begin Transaction',
            'Commit executed',
            'fallback to PC layout',
        ];

        foreach ($listMessageRemoved as $messageRemoved) {
            if ($this->startsWith($record['message'], $messageRemoved)) {
                return true;
            }
        }

        return false;
    }

    /**
     * Check string start with.
     */
    private function startsWith($string, $startString)
    {
        $len = strlen($startString);
        return (substr($string, 0, $len) === $startString);
    }
}

Như bạn có thể thấy ở trên, biến $listMessageRemoved chứa các message mà bạn muốn remove ra khỏi log, cơ chế ở đây là dựa vào method handle(), trả về true có nghĩa là message này đã được xử lí nên nó không cần gửi qua handle tiếp theo (ở đây chính là cloudwatch handler), theo documention:

   /**
     * Handles a record.
     *
     * All records may be passed to this method, and the handler should discard
     * those that it does not want to handle.
     *
     * The return value of this function controls the bubbling process of the handler stack.
     * Unless the bubbling is interrupted (by returning true), the Logger class will keep on
     * calling further handlers in the stack with a given log record.
     *
     * @param  array   $record The record to handle
     * @return bool true means that this handler handled the record, and that bubbling is not permitted.
     *                        false means the record was either not processed or that this handler allows bubbling.
     */
    public function handle(array $record);

=> Cuối cùng chúng ta cũng có 1 giải pháp ngon nghẻ, để remove bớt log để tốn tiền khách hàng, hy vọng sẽ giúp ích được cho mọi người 😃


All rights reserved

Viblo
Hãy đăng ký một tài khoản Viblo để nhận được nhiều bài viết thú vị hơn.
Đăng kí