通過唯一ID實現簡單的日誌跟蹤實現

在實際項目中,通知我們需要記錄一些日誌,方便問題覈查。但是日誌多了就很容易混亂,請求,響應,執行中的日誌無法對應,這時就需要爲請求進行標記唯一ID來進行跟蹤。

/**
 * 記錄請求日誌
 *
 * Class ApiLog
 * @package App\Library\Components\Elog
 */
class ApiLog
{
    static $logPath;

    private static $singleton;

    
    /**
     * 單例
     * @return ApiLog
     */
    public static function singleton()
    {

        if (false == self::$singleton instanceof ApiLog) {
            self::$singleton = new static();
        }

        return self::$singleton;
    }

    protected function __construct($logPath = '')
    {
        if (empty($logPath)) {
            self::$logPath = ROOT_PATH . 'logs/request/';
        } else {
            self::$logPath = ROOT_PATH . $logPath;
        }

        if (!is_dir(self::$logPath)) {
            mkdir(self::$logPath, 0777, true);
        }
    }

    public function record($action, $request = [], $type = 'requestLog')
    {
        $headers = [];
        if (!function_exists('getallheaders')) {
            foreach ($_SERVER as $name => $value) {
                if (substr($name, 0, 5) == 'HTTP_') {
                    $headers[str_replace(' ', '-', strtolower(str_replace('_', ' ', substr($name, 5))))] = $value;
                }
            }
        } else {
            $headers = getallheaders();
        }

        //==============  加密用戶登錄密碼
        if (isset($request['password'])) {
            $request['password'] = md5(md5($request['password']));
        }

        //==============  加密郵箱
        if (isset($request['email'])) {
            $request['email'] = encrypt_email($request['email']);
        }
        // ...... 日誌中對關鍵信息進行加密
        
        // 請求日誌記錄詳細一點
        if ('requestLog' == $type) {
            $data = [
                'action' => $action,
                'platform' => PHONE_SYSTEM,
                'ip' => real_ip(),
                'request' => $request,
                'REQUEST_URI' => isset($_SERVER['REQUEST_URI']) ? $_SERVER['REQUEST_URI'] : '',
                'headers' => $headers,
            ];
        } else {
            $data = [
                'action' => $action,
                'response' => $request
            ];
        }

        $this->write($data, $type);
    }

    protected function write($logData, $type)
    {
    
        $minutes = date('i');

        $file = date('Y-m-d-H') . '-v' . (intval($minutes / 10)) . '.log';

        $logData = ['request_id' => static::getRequestId(), 'add_time' => time(), 'type' => $type, 'content' => $logData];

        file_put_contents(self::$logPath . $file, json_encode($logData) . PHP_EOL, FILE_APPEND);
    }

    protected static function getRequestId()
    {
        static $requestId = '';

        if (!empty($requestId)) {
            return $requestId;
        }

        if (function_exists('session_create_id')) {
            $hash = session_create_id();
        } else {
            $uid = uniqid('', true);
            $data = '';
            $data .= isset($_SERVER['REQUEST_TIME']) ? $_SERVER['REQUEST_TIME'] : '';
            $data .= isset($_SERVER['HTTP_USER_AGENT']) ? $_SERVER['HTTP_USER_AGENT'] : '';
            $data .= isset($_SERVER['LOCAL_ADDR']) ? $_SERVER['LOCAL_ADDR'] : '';
            $data .= isset($_SERVER['LOCAL_PORT']) ? $_SERVER['LOCAL_PORT'] : '';
            $data .= isset($_SERVER['REMOTE_ADDR']) ? $_SERVER['REMOTE_ADDR'] : '';
            $data .= isset($_SERVER['REMOTE_PORT']) ? $_SERVER['REMOTE_PORT'] : '';
            $hash = hash('ripemd128', $uid . md5($data));
        }

        $hash = strtoupper($hash);

        return $requestId = substr($hash, 0, 8) . '-' . substr($hash, 8, 4) . '-' . substr($hash, 12, 4) . '-' . substr($hash, 16, 4) . '-' . substr($hash, 20, 12);
    }
}

使用單例,保證一次請求的ID一致


ApiLog::singleton()->record($action,$request);

ApiLog::singleton()->record($action,$actionData,'createOrder');
       
ApiLog::singleton()->record($action,$response,'ResponseLog');
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章