ユニークIDによる簡単なログ追跡の実現
4646 ワード
実際のプロジェクトでは、問題のチェックを容易にするために、ログを記録する必要があることを通知します.しかし,ログが多くなると混乱しやすく,要求,応答,実行中のログが対応できない場合,要求に一意の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,$errorMessage,'errorHandler');
ApiLog::singleton()->record($action,$response,'ResponseLog');