Khái niệm Logger

Rất nhiều ứng dụng tự xây dựng cho mình các cơ chế ghi lại nhưng thông tin hoạt động của ứng dụng, đó là các dấu vết để sử dụng với nhiều mục đích, thường các thông tin ghi lại trên một (log file), cơ chế để có thể ghi lại thông tin mới mục đích giám sát hoạt động như vậy được gọi là logger.

Trong tiêu chuẩn PSR-3 đưa ra giao diện mẫu dùng để xây dựng nên các thư viện Logger. Về cơ bản ứng dụng phải làm việc được với đối tượng tạo ra từ giao diện Psr\Log\LoggerInterface và ghi lại log ra file một cách đơn giản, sau đây là các vấn đề xoay quanh LoggerInterface.

Đặc tính kỹ thuật Logger

Những điều cơ bản về logger

Giao diện LoggerInterface đưa ra tám cấp độ khi ghi lại các log gồm có: debug, info, notice, warning, error, critical, alert, emergency mỗi mức độ này có một hàm cùng tên tương ứng. Có một hàm thứ chín tên là log nó chấp nhận cấp độ như tham số để ghi lại log. Tiêu chuẩn đưa ra là việc gọi hàm log đi kèm tham số là hằng số cấp độ PHẢI có kết quả tương ứng với gọi hàm thành phần (8 hàm trên). Khi gọi hàm này với hằng số cấp độ không được định nghĩa thì throw một exception Psr\Log\InvalidArgumentException.

Thông tin (Message) ghi lại

  • Mọi phương thức của giao diện đều có chấp nhận một chuỗi ký tự như là thông điệp cần ghi lại, hoặc một đối tượng có hàm __toString(), khi triển khai giao diện CÓ THỂ đưa ra các sử lý đặc biệt cho các đối tượng chuyển đến, nếu không đưa ra thì lớp triển khai cần chuyển đối tượng (cast) thành chuỗi.
  • Các message chuyển đến hàm log có thể có chứa các placeholder (giữ chỗ),  lớp triển khai CÓ THỂ thay thế các placeholder bằng các giá trị từ một mảng chuyển tới.
    Các tên placeholder PHẢI tương ứng với key của mảng dữ liệu chuyển tới. Tên này trong message PHẢI được xác định bắt đầu từ ký tự { và kết thúc bởi }. KHÔNG ĐƯỢC CÓ khoảng trắng trong tên placeholder, và NÊN sử dụng các ký tự A-Z a-z 0-9 _ . các ký tự khác để dành. 

Đây là một ví dụ về placeholder dùng để cập nhật mảng $context vào $message tham khảo:

<?php
 
function interpolate($message, array $context = array())
{
    $replace = array();
    foreach ($context as $key => $val) {
        // check that the value can be casted to string
        if (!is_array($val) && (!is_object($val) || method_exists($val, '__toString'))) {
            $replace['{' . $key . '}'] = $val;
        }
    }

    return strtr($message, $replace);
}

$message = "User {username} created";

$context = array('username' => 'bolivar');

echo interpolate($message, $context);

Dữ liệu Context

Mọi phương thức đều chấp nhận một mảng dữ liệu (gọi là context), về nguyên tắc mảng có thể chứa bất kỳ thứ gì. Lớp triển khải PHẢI đảm bảo xử lý thỏa đáng dữ liệu context này ngoài ra các giá trị trong context KHÔNG ĐƯỢC phát sinh các exceptions.

Package

Từ các khái niệm, yêu cầu tiêu chuẩn ở trên, đây là các giao diện mẫu bạn cần áp dụng để tuân thủ PRS-3.

<?php

namespace Psr\Log;

interface LoggerInterface
{
    
    public function emergency($message, array $context = array());

   
    public function alert($message, array $context = array());

 
    public function critical($message, array $context = array());

    
    public function error($message, array $context = array());

  
    public function warning($message, array $context = array());

    
    public function notice($message, array $context = array());

    
    public function info($message, array $context = array());

 
    public function debug($message, array $context = array());

 
    public function log($level, $message, array $context = array());
}
<?php

namespace Psr\Log;
interface LoggerAwareInterface
{
 
    public function setLogger(LoggerInterface $logger);
}
<?php

namespace Psr\Log;
class LogLevel
{
    const EMERGENCY = 'emergency';
    const ALERT     = 'alert';
    const CRITICAL  = 'critical';
    const ERROR     = 'error';
    const WARNING   = 'warning';
    const NOTICE    = 'notice';
    const INFO      = 'info';
    const DEBUG     = 'debug';
}

Các file giao diện Logger tải về tại: https://github.com/php-fig/log/tree/master/Psr/Log

Kết luận PRS-3

Nếu bạn muốn viết một Logger riêng, để dễ dàng trao đổi, sử dụng lại bạn cần triển khai đúng các interface đưa ra ở PRS-3 ở trên.

Ngoài ra bạn cũng có thể dùng ngay các thư viện, framework mà support PRS-3 (đã xây dựng đúng chuẩn trên) như:

  • Zend Log: https://github.com/zendframework/zend-log
  • monolog: https://github.com/Seldaek/monolog (bộ logger này được sử dụng bởi: Symfony2, Laravel 4 & 5, CakePHP, Slim, Yii 2) 
Đăng ký theo dõi ủng hộ kênh