|
@@ -1,435 +0,0 @@
|
|
-<?php
|
|
|
|
-namespace App\Library\Logger;
|
|
|
|
-
|
|
|
|
-/**
|
|
|
|
- * Created by PhpStorm.
|
|
|
|
- * User: lhz
|
|
|
|
- * Date: 2016-5-31
|
|
|
|
- * Time: 8:50
|
|
|
|
- * 日志器
|
|
|
|
- */
|
|
|
|
-
|
|
|
|
-use Fluent\Logger\FluentLogger;
|
|
|
|
-
|
|
|
|
-class Logger {
|
|
|
|
- //常量定义
|
|
|
|
- const DEBUG = 0b00000001; //Debug: debug-level messages
|
|
|
|
- const INFO = 0b00000010; //Informational: informational messages
|
|
|
|
- const NOTICE = 0b00000100; //Notice: normal but significant condition
|
|
|
|
- const WARNING = 0b00001000; //Warning: warning conditions
|
|
|
|
- const ERROR = 0b00010000; //Error: error conditions
|
|
|
|
- const FATAL = 0b00100000; //Critical: critical conditions
|
|
|
|
- const ALERT = 0b01000000; //Alert: action must be taken immediately
|
|
|
|
- const EMERGENCY = 0b10000000; //Emergency: system is unusable
|
|
|
|
- const PRE_DEFINE_ALL = self::EMERGENCY | self::ALERT | self::FATAL | self::ERROR | self::WARNING | self::NOTICE | self::INFO | self::DEBUG;
|
|
|
|
- const PRE_DEFINE_ERROR = self::EMERGENCY | self::ALERT | self::FATAL | self::ERROR;
|
|
|
|
- const PRE_DEFINE_WARN = self::PRE_DEFINE_ERROR | self::WARNING;
|
|
|
|
- const PRE_DEFINE_INFO = self::WARNING | self::NOTICE | self::INFO | self::DEBUG;
|
|
|
|
-
|
|
|
|
- const DEVELOP = 'development';
|
|
|
|
- const PRODUCT = 'production';
|
|
|
|
-
|
|
|
|
- //单例对象
|
|
|
|
- static $_instance = NULL;
|
|
|
|
-
|
|
|
|
- //邮件
|
|
|
|
- static $_mailer = NULL;
|
|
|
|
-
|
|
|
|
- //fluentd
|
|
|
|
- private $_fluentd = NULL;
|
|
|
|
-
|
|
|
|
- //日志句柄
|
|
|
|
- private $_fp = NULL;
|
|
|
|
-
|
|
|
|
- //日志级别
|
|
|
|
- private $_level = self::FATAL;
|
|
|
|
-
|
|
|
|
- //应用环境
|
|
|
|
- private $_env = self::DEVELOP;
|
|
|
|
-
|
|
|
|
- //项目ID
|
|
|
|
- private $_project = '';
|
|
|
|
-
|
|
|
|
- //邮件错误通知开关
|
|
|
|
- private $_mailSwitch = 'auto';//auto表示自动,级别在error及以上发邮件;on表示全部发送邮件;off表示关闭邮件警告
|
|
|
|
-
|
|
|
|
- //debug_backtrace开关
|
|
|
|
- private $_debugBackTrace = true;
|
|
|
|
-
|
|
|
|
- //日志类型枚举
|
|
|
|
- private $_TYPES = [
|
|
|
|
- self::DEBUG => 'DEBUG',
|
|
|
|
- self::INFO => 'INFO',
|
|
|
|
- self::NOTICE => 'NOTICE',
|
|
|
|
- self::WARNING => 'WARNING',
|
|
|
|
- self::ERROR => 'ERROR',
|
|
|
|
- self::FATAL => 'FATAL',
|
|
|
|
- self::ALERT => 'ALERT',
|
|
|
|
- self::EMERGENCY => 'EMERGENCY',
|
|
|
|
- ];
|
|
|
|
-
|
|
|
|
- //日志类型分类
|
|
|
|
- private $_CATEGORIES = [
|
|
|
|
- self::DEBUG => 'INFO',
|
|
|
|
- self::INFO => 'INFO',
|
|
|
|
- self::NOTICE => 'INFO',
|
|
|
|
- self::WARNING => 'INFO',
|
|
|
|
- self::ERROR => 'ERROR',
|
|
|
|
- self::FATAL => 'ERROR',
|
|
|
|
- self::ALERT => 'ERROR',
|
|
|
|
- self::EMERGENCY => 'ERROR',
|
|
|
|
- ];
|
|
|
|
-
|
|
|
|
- public function __construct($path = NULL)
|
|
|
|
- {
|
|
|
|
- $this->setPath($path);
|
|
|
|
- $this->setLevel(self::EMERGENCY | self::ALERT | self::FATAL | self::ERROR | self::WARNING);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- private function __clone() {
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- private function _formatMsg($msg, $type, $file = null, $line = null) {
|
|
|
|
- $extra = '';
|
|
|
|
- if ($this->_debugBackTrace && $file === null && $line === null) {
|
|
|
|
- $traceLevel = 10;
|
|
|
|
- $trace = debug_backtrace(DEBUG_BACKTRACE_PROVIDE_OBJECT, $traceLevel);
|
|
|
|
- $cnt = count($trace);
|
|
|
|
- if ($cnt > 0) {
|
|
|
|
- foreach ($trace as $l) {
|
|
|
|
- if (isset($l['file']) && isset($l['line'])) {
|
|
|
|
- $extra .= sprintf("%s(%d)\n", $l['file'], $l['line']);
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- $file = $trace[$cnt-1]['file'];
|
|
|
|
- $line = $trace[$cnt-1]['line'];
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- if ($file === null) {
|
|
|
|
- $file = __FILE__;
|
|
|
|
- }
|
|
|
|
- if ($line === null) {
|
|
|
|
- $line = __LINE__;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- return sprintf("%s [%-5s] [%-25s :%5d] %s\n%s\n", date('Y-m-d H:i:s'), $this->_TYPES[$type], substr($file, -24), $line, $msg, $extra);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- private function _sendFluentd($data, $type, $errFile = null, $errLine = null) {
|
|
|
|
- $tag = sprintf("%s.%s.%s", $this->_project, $this->_CATEGORIES[$type], $this->_TYPES[$type]);
|
|
|
|
-
|
|
|
|
- $subject = sprintf("[%s][%s]%s", $this->_project, $this->_TYPES[$type], substr($data, 0, 40));
|
|
|
|
-
|
|
|
|
- $reqMicro = explode('.', $_SERVER['REQUEST_TIME_FLOAT']);
|
|
|
|
- $reqTime = new \DateTime(date('Y-m-d H:i:s.' . $reqMicro[1], $_SERVER['REQUEST_TIME']));
|
|
|
|
- $curMicro = microtime(true);
|
|
|
|
- $tMicro = sprintf("%06d", ($curMicro - floor($curMicro)) * 1000000);
|
|
|
|
- $curTime = new \DateTime(date('Y-m-d H:i:s.' . $tMicro, $curMicro));
|
|
|
|
-
|
|
|
|
- $msg = [
|
|
|
|
- 'title' => $subject,
|
|
|
|
- 'server_name' => $_SERVER['SERVER_NAME'],
|
|
|
|
- 'server_ip' => $_SERVER['SERVER_ADDR'],
|
|
|
|
- 'server_port' => $_SERVER['SERVER_PORT'],
|
|
|
|
- 'client_ip' => $_SERVER['REMOTE_ADDR'],
|
|
|
|
- 'request_uri' => $_SERVER['REQUEST_URI'],
|
|
|
|
- 'request_time' => $reqTime->format('Y-m-d H:i:s.u'),
|
|
|
|
- 'current_time' => $curTime->format('Y-m-d H:i:s.u'),
|
|
|
|
- 'server_info' => print_r($_SERVER, true),
|
|
|
|
- 'get_info' => print_r($_GET, true),
|
|
|
|
- 'post_info' => print_r($_POST, true),
|
|
|
|
- 'data' => $data,
|
|
|
|
- 'trace' => $this->_formatMsg($data, $type, $errFile, $errLine),
|
|
|
|
- ];
|
|
|
|
-
|
|
|
|
- $this->_fluentd->post($tag, $msg);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- private function _write($msg, $type, $errFile = null, $errLine = null) {
|
|
|
|
- if ($type & $this->_level) {
|
|
|
|
- if (is_object($msg) || is_array($msg)) {
|
|
|
|
- $data = print_r($msg, true);
|
|
|
|
- } else {
|
|
|
|
- $data = strval($msg);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- //发送fluentd
|
|
|
|
- if ($this->_fluentd !== null) {
|
|
|
|
- $this->_sendFluentd($data, $type, $errFile, $errLine);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- $data = $this->_formatMsg($data, $type, $errFile, $errLine);
|
|
|
|
-
|
|
|
|
- //记录日志
|
|
|
|
- fwrite($this->_fp, $data);
|
|
|
|
-
|
|
|
|
- //发送邮件
|
|
|
|
-// if ($this->_mailSwitch == 'on' ||
|
|
|
|
-// ($this->_mailSwitch == 'auto' &&
|
|
|
|
-// ($type & self::ERROR || $type & self::FATAL))) {
|
|
|
|
-// if (self::$_mailer !== null) {
|
|
|
|
-// $subject = sprintf("[ERROR_MAIL][%s][%s]Error info from logger", $this->_TYPES[$type], $this->_project);
|
|
|
|
-// self::$_mailer->subject($subject);
|
|
|
|
-// self::$_mailer->msgHTML($data);
|
|
|
|
-// if (!self::$_mailer->send()) {//邮件发送失败,写日志
|
|
|
|
-// $err = self::$_mailer->ErrorInfo();
|
|
|
|
-// fwrite($this->_fp, $this->_formatMsg($err, self::ERROR));
|
|
|
|
-// }
|
|
|
|
-// }
|
|
|
|
-// }
|
|
|
|
-
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- private function parseArgs($args) {
|
|
|
|
- $ret = "";
|
|
|
|
- foreach ($args as $arg) {
|
|
|
|
- if (is_object($arg) || is_array($arg)) {
|
|
|
|
- $data = print_r($arg, true);
|
|
|
|
- } else {
|
|
|
|
- $data = strval($arg);
|
|
|
|
- }
|
|
|
|
- $ret .= $data . " ";
|
|
|
|
- }
|
|
|
|
- return $ret;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- /**
|
|
|
|
- * @param string $path
|
|
|
|
- * @return Logger|null
|
|
|
|
- * 单例对象,参数为日志路径
|
|
|
|
- */
|
|
|
|
- public static function getInstance($path = '') {
|
|
|
|
- if (!(self::$_instance instanceof self)) {
|
|
|
|
- self::$_instance = new self($path);
|
|
|
|
- }
|
|
|
|
- return self::$_instance;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- /**
|
|
|
|
- * @param string $path
|
|
|
|
- * @throws Exception
|
|
|
|
- * 设置log路径,默认标准输出
|
|
|
|
- */
|
|
|
|
- public function setPath($path = '') {
|
|
|
|
- if (empty($path)) {
|
|
|
|
- $this->_fp = fopen('php://stdout', 'w');
|
|
|
|
- } else {
|
|
|
|
- if (is_dir($path)) {
|
|
|
|
- throw new \Exception('Cannot be a path, must be a file ' . $path);
|
|
|
|
- }
|
|
|
|
- $dn = dirname($path);
|
|
|
|
- if (!file_exists($dn)) {
|
|
|
|
- @mkdir($dn, 0777, true);
|
|
|
|
- }
|
|
|
|
- if (!file_exists($path)) {
|
|
|
|
- @touch($path);
|
|
|
|
- }
|
|
|
|
- if (!is_writable($path)) {
|
|
|
|
- throw new \Exception('Log file cannot be written! ' . $path);
|
|
|
|
- }
|
|
|
|
- $this->_fp = fopen($path, 'a');
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- /**
|
|
|
|
- * @param string $host
|
|
|
|
- * @param int $port
|
|
|
|
- * @param array $options
|
|
|
|
- * 配置fluentd
|
|
|
|
- */
|
|
|
|
- public function setFluentd($host = '127.0.0.1', $port = 24224, $options = []) {
|
|
|
|
- $this->_fluentd = new FluentLogger($host, $port, $options);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- /**
|
|
|
|
- * @param $val [development | production]
|
|
|
|
- * 设置应用环境,默认development
|
|
|
|
- * 关联日志级别
|
|
|
|
- */
|
|
|
|
- public function setEnv($val) {
|
|
|
|
- if ($val == self::DEVELOP) {
|
|
|
|
- $this->_env = $val;
|
|
|
|
- $this->setLevel(self::EMERGENCY | self::ALERT | self::FATAL | self::ERROR | self::WARNING | self::NOTICE | self::INFO | self::DEBUG);
|
|
|
|
- } elseif ($val == self::PRODUCT) {
|
|
|
|
- $this->_env = $val;
|
|
|
|
- $this->setLevel(self::EMERGENCY | self::ALERT | self::FATAL | self::ERROR | self::WARNING);
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- /**
|
|
|
|
- * @param $val
|
|
|
|
- * 设置日志级别,默认self::EMERGENCY | self::ALERT | self::FATAL | self::ERROR | self::WARNING
|
|
|
|
- */
|
|
|
|
- public function setLevel($val) {
|
|
|
|
- $this->_level = $val;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- /**
|
|
|
|
- * @param $val true/false
|
|
|
|
- * debug back trace开关,默认打开
|
|
|
|
- */
|
|
|
|
- public function setDebugBackTrace($val) {
|
|
|
|
- $this->_debugBackTrace = $val;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- public function setMailer(Mailer $mailer) {
|
|
|
|
- self::$_mailer = $mailer;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- /**
|
|
|
|
- * @param $mail array
|
|
|
|
- * key as mail address
|
|
|
|
- * value as mail name
|
|
|
|
- */
|
|
|
|
- public function addMailTo($mail) {
|
|
|
|
- foreach ($mail as $addr => $name) {
|
|
|
|
- if (strpos($addr, '@') !== false) {
|
|
|
|
- self::$_mailer->addAddress($addr, $name);
|
|
|
|
- } elseif (strpos($name, '@') !== false) {
|
|
|
|
- self::$_mailer->addAddress($name);
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- public function setProjectId($projectId) {
|
|
|
|
- $this->_project = $projectId;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- /**
|
|
|
|
- * @param null $msg
|
|
|
|
- * 调试输出
|
|
|
|
- */
|
|
|
|
- public function Debug() {
|
|
|
|
- if (func_num_args() == 0) {
|
|
|
|
- return;
|
|
|
|
- }
|
|
|
|
- $args = func_get_args();
|
|
|
|
- $msg = $this->parseArgs($args);
|
|
|
|
-
|
|
|
|
- $this->_write($msg, self::DEBUG);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- /**
|
|
|
|
- * @param null $msg
|
|
|
|
- * 信息输出
|
|
|
|
- */
|
|
|
|
- public function Info() {
|
|
|
|
- if (func_num_args() == 0) {
|
|
|
|
- return;
|
|
|
|
- }
|
|
|
|
- $args = func_get_args();
|
|
|
|
- $msg = $this->parseArgs($args);
|
|
|
|
-
|
|
|
|
- $this->_write($msg, self::INFO);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- /**
|
|
|
|
- * @param null $msg
|
|
|
|
- * 注意输出
|
|
|
|
- */
|
|
|
|
- public function Notice() {
|
|
|
|
- if (func_num_args() == 0) {
|
|
|
|
- return;
|
|
|
|
- }
|
|
|
|
- $args = func_get_args();
|
|
|
|
- $msg = $this->parseArgs($args);
|
|
|
|
-
|
|
|
|
- $this->_write($msg, self::NOTICE);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- /**
|
|
|
|
- * @param null $msg
|
|
|
|
- * 警告输出
|
|
|
|
- */
|
|
|
|
- public function Warning() {
|
|
|
|
- if (func_num_args() == 0) {
|
|
|
|
- return;
|
|
|
|
- }
|
|
|
|
- $args = func_get_args();
|
|
|
|
- $msg = $this->parseArgs($args);
|
|
|
|
-
|
|
|
|
- $this->_write($msg, self::WARNING);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- /**
|
|
|
|
- * @param null $msg
|
|
|
|
- * 错误输出
|
|
|
|
- */
|
|
|
|
- public function Error() {
|
|
|
|
- if (func_num_args() == 0) {
|
|
|
|
- return;
|
|
|
|
- }
|
|
|
|
- $args = func_get_args();
|
|
|
|
- $msg = $this->parseArgs($args);
|
|
|
|
-
|
|
|
|
- $this->_write($msg, self::ERROR);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- /**
|
|
|
|
- * @param null $msg
|
|
|
|
- * 致命错误输出
|
|
|
|
- */
|
|
|
|
- public function Fatal() {
|
|
|
|
- if (func_num_args() == 0) {
|
|
|
|
- return;
|
|
|
|
- }
|
|
|
|
- $args = func_get_args();
|
|
|
|
- $msg = $this->parseArgs($args);
|
|
|
|
-
|
|
|
|
- $this->_write($msg, self::FATAL);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- /**
|
|
|
|
- * @param null $msg
|
|
|
|
- * 警报错误输出
|
|
|
|
- */
|
|
|
|
- public function Alert() {
|
|
|
|
- if (func_num_args() == 0) {
|
|
|
|
- return;
|
|
|
|
- }
|
|
|
|
- $args = func_get_args();
|
|
|
|
- $msg = $this->parseArgs($args);
|
|
|
|
-
|
|
|
|
- $this->_write($msg, self::ALERT);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- /**
|
|
|
|
- * @param null $msg
|
|
|
|
- * 紧急错误输出
|
|
|
|
- */
|
|
|
|
- public function Emergency() {
|
|
|
|
- if (func_num_args() == 0) {
|
|
|
|
- return;
|
|
|
|
- }
|
|
|
|
- $args = func_get_args();
|
|
|
|
- $msg = $this->parseArgs($args);
|
|
|
|
-
|
|
|
|
- $this->_write($msg, self::EMERGENCY);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- /**
|
|
|
|
- * @param $errno
|
|
|
|
- * @param $errstr
|
|
|
|
- * @param $errfile
|
|
|
|
- * @param $errline
|
|
|
|
- * 系统错误捕获器
|
|
|
|
- */
|
|
|
|
- public function cbErrorHandler($errno, $errstr, $errfile, $errline) {
|
|
|
|
- switch ($errno) {
|
|
|
|
- case E_ERROR:
|
|
|
|
- case E_USER_ERROR:
|
|
|
|
- case E_CORE_ERROR:
|
|
|
|
- $errType = self::FATAL;
|
|
|
|
- break;
|
|
|
|
- case E_WARNING:
|
|
|
|
- case E_USER_WARNING:
|
|
|
|
- case E_CORE_WARNING:
|
|
|
|
- $errType = self::ERROR;
|
|
|
|
- break;
|
|
|
|
- default:
|
|
|
|
- $errType = self::WARNING;
|
|
|
|
- }
|
|
|
|
- $this->_write($errstr, $errType, $errfile, $errline);
|
|
|
|
- }
|
|
|
|
-}
|
|
|