github: https://github.com/Neeke/SeasLogphp
@author Chitao.Gao [neeke@php.net]html
@交流羣 312910117git
log日誌,一般是系統或軟件、應用的運行記錄。經過log的分析,能夠方便用戶瞭解系統或軟件、應用的運行狀況;若是你的應用log足夠豐富,也 能夠分析以往用戶的操做行爲、類型喜愛、地域分佈或其餘更多信息;若是一個應用的log同時也分了多個級別,那麼能夠很輕易地分析獲得該應用的健康情況, 及時發現問題並快速定位、解決問題,補救損失。github
php內置error_log、syslog函數功能強大且性能極好,但因爲各類缺陷(error_log無錯誤級別、無固定格式,syslog不分模塊、與系統日誌混合),靈活度下降了不少,不能知足應用需求。web
好消息是,有很多第三方的log類庫彌補了上述缺陷,如log4php、plog、Analog等(固然也有不少應用在項目中本身開發的log類)。其中以log4php最爲著名,設計精良、格式完美、文檔完善、功能強大。推薦。shell
不過log4php在性能方面表現很是差,下圖是SeasLog與log4php的ab併發性能測試( 測試環境:Ubuntu12.04單機,CPU I3,內存 16G,硬盤 SATA 7200): apache
那麼有沒有一種log類庫知足如下需求呢:數組
SeasLog
正是應此需求而生。多線程
$ /path/to/phpize
$ ./configure --with-php-config=/path/to/php-config
$ make && make install
$ pecl install seaslog
; configuration for php SeasLog module extension = seaslog.so seaslog.default_basepath = /log/seaslog-test ;默認log根目錄 seaslog.default_logger = default ;默認logger目錄 seaslog.disting_type = 1 ;是否以type分文件 1是 0否(默認) seaslog.disting_by_hour = 1 ;是否每小時劃分一個文件 1是 0否(默認) seaslog.use_buffer = 1 ;是否啓用buffer 1是 0否(默認) seaslog.buffer_size = 100 ;buffer中緩衝數量 默認0(不使用buffer_size) seaslog.level = 0 ;記錄日誌級別 默認0(全部日誌) seaslog.trace_error = 1 ;自動記錄錯誤 默認1(開啓) seaslog.trace_exception = 0 ;自動記錄異常信息 默認0(關閉) seaslog.default_datetime_format = "Y:m:d H:i:s" ;日期格式配置 默認"Y:m:d H:i:s"
seaslog.disting_type = 1
開啓以type分文件,即log文件區分info\warn\erro併發
seaslog.disting_by_hour = 1
開啓每小時劃分一個文件
seaslog.use_buffer = 1
開啓buffer。默認關閉。當開啓此項時,日誌預存於內存,當請求結束時(或異常退出時)一次寫入文件。
seaslog.buffer_size = 100
設置緩衝數量爲100. 默認爲0,即無緩衝數量限制.當buffer_size大於0時,緩衝量達到該值則寫一次文件.
seaslog.level = 3
記錄的日誌級別.默認爲0,即全部日誌均記錄。當level爲1時,關注debug以上級別(包括debug),以此類推。level大於8時,全部日誌均不記錄。使用
SeasLog 共將日誌分紅8個級別
var_dump(SEASLOG_DEBUG,SEASLOG_INFO,SEASLOG_NOTICE); /* string('debug') debug級別 string('info') info級別 string('notice') notice級別 */
SeasLog
提供了這樣一組函數,能夠方便地獲取與設置根目錄、模塊目錄、快速寫入與統計log。 相信從下述僞代碼的註釋中,您能夠快速獲取函數信息,具體使用將緊接其後:
<?php /** * @author neeke@php.net * Date: 14-1-27 下午4:47 */ class SeasLog { public function __construct() { #SeasLog init } public function __destruct() { #SeasLog distroy } /** * 設置basePath * * @param $basePath * * @return bool */ static public function setBasePath($basePath) { return TRUE; } /** * 獲取basePath * * @return string */ static public function getBasePath() { return 'the base_path'; } /** * 設置模塊目錄 * @param $module * * @return bool */ static public function setLogger($module) { return TRUE; } /** * 獲取最後一次設置的模塊目錄 * @return string */ static public function getLastLogger() { return 'the lastLogger'; } /** * 設置DatetimeFormat配置 * @param $format * * @return bool */ static public function setDatetimeFormat($format) { return TRUE; } /** * 返回當前DatetimeFormat配置格式 * @return string */ static public function getDatetimeFormat() { return 'the datetimeFormat'; } /** * 統計全部類型(或單個類型)行數 * @param string $level * @param string $log_path * @param null $key_word * * @return array | long */ static public function analyzerCount($level = 'all', $log_path = '*', $key_word = NULL) { return array(); } /** * 以數組形式,快速取出某類型log的各行詳情 * * @param $level * @param string $log_path * @param null $key_word * @param int $start * @param int $limit * @param $order * * @return array */ static public function analyzerDetail($level = SEASLOG_INFO, $log_path = '*', $key_word = NULL, $start = 1, $limit = 20, $order = SEASLOG_DETIAL_ORDER_ASC) { return array(); } /** * 得到當前日誌buffer中的內容 * * @return array */ static public function getBuffer() { return array(); } /** * 將buffer中的日誌馬上刷到硬盤 * * @return bool */ static public function flushBuffer() { return TRUE; } /** * 記錄debug日誌 * * @param $message * @param array $content * @param string $module */ static public function debug($message, array $content = array(), $module = '') { #$level = SEASLOG_DEBUG } /** * 記錄info日誌 * * @param $message * @param array $content * @param string $module */ static public function info($message, array $content = array(), $module = '') { #$level = SEASLOG_INFO } /** * 記錄notice日誌 * * @param $message * @param array $content * @param string $module */ static public function notice($message, array $content = array(), $module = '') { #$level = SEASLOG_NOTICE } /** * 記錄warning日誌 * * @param $message * @param array $content * @param string $module */ static public function warning($message, array $content = array(), $module = '') { #$level = SEASLOG_WARNING } /** * 記錄error日誌 * * @param $message * @param array $content * @param string $module */ static public function error($message, array $content = array(), $module = '') { #$level = SEASLOG_ERROR } /** * 記錄critical日誌 * * @param $message * @param array $content * @param string $module */ static public function critical($message, array $content = array(), $module = '') { #$level = SEASLOG_CRITICAL } /** * 記錄alert日誌 * * @param $message * @param array $content * @param string $module */ static public function alert($message, array $content = array(), $module = '') { #$level = SEASLOG_ALERT } /** * 記錄emergency日誌 * * @param $message * @param array $content * @param string $module */ static public function emergency($message, array $content = array(), $module = '') { #$level = SEASLOG_EMERGENCY } /** * 通用日誌方法 * @param $level * @param $message * @param array $content * @param string $module */ static public function log($level, $message, array $content = array(), $module = '') { } }
$basePath_1 = SeasLog::getBasePath(); SeasLog::setBasePath('/log/base_test'); $basePath_2 = SeasLog::getBasePath(); var_dump($basePath_1,$basePath_2); /* string(19) "/log/seaslog-ciogao" string(14) "/log/base_test" */
直接使用
SeasLog::getBasePath()
,將獲取php.ini(seaslog.ini)中設置的seaslog.default_basepath
的值。使用
SeasLog::setBasePath()
函數,將改變SeasLog::getBasePath()
的取值。
$lastLogger_1 = SeasLog::getLastLogger(); SeasLog::setLogger('testModule/app1'); $lastLogger_2 = SeasLog::getLastLogger(); var_dump($lastLogger_1,$lastLogger_2); /* string(7) "default" string(15) "testModule/app1" */
與basePath相相似的,
直接使用
SeasLog::getLastLogger()
,將獲取php.ini(seaslog.ini)中設置的seaslog.default_logger
的值。使用
SeasLog::setLogger()
函數,將改變SeasLog::getLastLogger()
的取值。
上面已經設置過了basePath與logger,因而log記錄的目錄已經產生了,
log記錄目錄 = basePath / logger / {fileName}.log log文件名,以
年月日
分文件,現在天是2014年02月18日期,那麼{fileName}
=20140218
;
還記得 php.ini
中設置的 seaslog.disting_type
嗎?
默認的 seaslog.disting_type = 0
,若是今天我使用了 SeasLog
,那麼將產生最終的log文件:
若是 seaslog.disting_type = 1
,則最終的log文件將是這樣的三個文件
infoLogFile = basePath / logger / INFO.20140218.log
warnLogFile = basePath / logger / WARN.20140218.log
erroLogFile = basePath / logger / ERRO.20140218.log
SeasLog::log(SEASLOG_ERROR,'this is a error test by ::log'); SeasLog::debug('this is a {userName} debug',array('{userName}' => 'neeke')); SeasLog::info('this is a info log'); SeasLog::notice('this is a notice log'); SeasLog::warning('your {website} was down,please {action} it ASAP!',array('{website}' => 'github.com','{action}' => 'rboot')); SeasLog::error('a error log'); SeasLog::critical('some thing was critical'); SeasLog::alert('yes this is a {messageName}',array('{messageName}' => 'alertMSG')); SeasLog::emergency('Just now, the house next door was completely burnt out! {note}',array('{note}' => 'it`s a joke')); /* 這些函數同時也接受第3個參數爲logger的設置項 注意,當last_logger == 'default'時等同於: SeasLog::setLogger('test/new/path'); SeasLog::error('test error 3'); 若是已經在前文使用過SeasLog::setLogger()函數,第3個參數的log只在此處臨時使用,不影響下文。 */
log格式統一爲:
{type} | {pid} | {timeStamp} |{dateTime} | {logInfo}
error | 23625 | 1406422432.786 | 2014:07:27 08:53:52 | this is a error test by log debug | 23625 | 1406422432.786 | 2014:07:27 08:53:52 | this is a neeke debug info | 23625 | 1406422432.787 | 2014:07:27 08:53:52 | this is a info log notice | 23625 | 1406422432.787 | 2014:07:27 08:53:52 | this is a notice log warning | 23625 | 1406422432.787 | 2014:07:27 08:53:52 | your github.com was down,please rboot it ASAP! error | 23625 | 1406422432.787 | 2014:07:27 08:53:52 | a error log critical | 23625 | 1406422432.787 | 2014:07:27 08:53:52 | some thing was critical emergency | 23625 | 1406422432.787 | 2014:07:27 08:53:52 | Just now, the house next door was completely burnt out! it is a joke
SeasLog
在擴展中使用管道調用shell命令 grep -wc
快速地取得count值,並返回值(array || int)給PHP。
$countResult_1 = SeasLog::analyzerCount(); $countResult_2 = SeasLog::analyzerCount(SEASLOG_WARNING); $countResult_3 = SeasLog::analyzerCount(SEASLOG_ERROR,date('Ymd',time())); var_dump($countResult_1,$countResult_2,$countResult_3); /* array(8) { ["debug"]=> int(3) ["info"]=> int(3) ["notice"]=> int(3) ["warning"]=> int(3) ["error"]=> int(6) ["critical"]=> int(3) ["alert"]=> int(3) ["emergency"]=> int(3) } int(7) int(1) */
SeasLog
在擴展中使用管道調用shell命令 grep -w
快速地取得列表,並返回array給PHP。
$detailErrorArray_inAll = SeasLog::analyzerDetail(SEASLOG_ERROR); $detailErrorArray_today = SeasLog::analyzerDetail(SEASLOG_ERROR,date('Ymd',time())); var_dump($detailErrorArray_inAll,$detailErrorArray_today); /* SeasLog::analyzerDetail(SEASLOG_ERROR) == SeasLog::analyzerDetail(SEASLOG_ERROR,'*'); 取當前模塊下全部level爲 SEASLOG_ERROR 的信息列表: array(6) { [0] => string(66) "error | 8568 | 1393172042.717 | 2014:02:24 00:14:02 | test error 3 " [1] => string(66) "error | 8594 | 1393172044.104 | 2014:02:24 00:14:04 | test error 3 " [2] => string(66) "error | 8620 | 1393172044.862 | 2014:02:24 00:14:04 | test error 3 " [3] => string(66) "error | 8646 | 1393172045.989 | 2014:02:24 00:14:05 | test error 3 " [4] => string(66) "error | 8672 | 1393172047.882 | 2014:02:24 00:14:07 | test error 3 " [5] => string(66) "error | 8698 | 1393172048.736 | 2014:02:24 00:14:08 | test error 3 " } SeasLog::analyzerDetail(SEASLOG_ERROR,date('Ymd',time())); 只取得當前模塊下,當前一天內,level爲SEASLOG_ERROR 的信息列表: array(2) { [0] => string(66) "error | 8568 | 1393172042.717 | 2014:02:24 00:14:02 | test error 3 " [1] => string(66) "error | 8594 | 1393172044.104 | 2014:02:24 00:14:04 | test error 3 " } 同理,取當月 $detailErrorArray_mouth = SeasLog::analyzerDetail(SEASLOG_ERROR,date('Ym',time())); */
[base] wait_analyz_log_path = /log/base_test [fork] ;是否開啓多線程 1開啓 0關閉 fork_open = 1 ;線程個數 fork_count = 3 [warning] email[smtp_host] = smtp.163.com email[smtp_port] = 25 email[subject_pre] = 預警郵件 - email[smtp_user] = seaslogdemo@163.com email[smtp_pwd] = seaslog#demo email[mail_from] = seaslogdemo@163.com email[mail_to] = gaochitao@weiboyi.com email[mail_cc] = ciogao@gmail.com email[mail_bcc] = [analyz] ; enum ; SEASLOG_DEBUG "debug" ; SEASLOG_INFO "info" ; SEASLOG_NOTICE "notice" ; SEASLOG_WARNING "warning" ; SEASLOG_ERROR "error" ; SEASLOG_CRITICAL "critical" ; SEASLOG_ALERT "alert" ; SEASLOG_EMERGENCY "emergency" test1[module] = test/bb test1[level] = SEASLOG_ERROR test1[bar] = 1 test1[mail_to] = gaochitao@weiboyi.com test2[module] = 222 test2[level] = SEASLOG_WARNING test3[module] = 333 test3[level] = SEASLOG_CRITICAL test4[module] = 444 test4[level] = SEASLOG_EMERGENCY test5[module] = 555 test5[level] = SEASLOG_DEBUG
;天天凌晨3點執行 0 3 * * * /path/to/php /path/to/SeasLog/Analyzer/SeasLogAnalyzer.php