PHP高性能日志SeasLog


layout: post
title: "PHP高性能日志SeasLog"
date: 2016-04-29 09:59:55 +0800
comments: true
categories: [PHP]


PHP高性能日志SeasLog

一边灭、什么是SeasLog

SeasLog是一個(gè)C語(yǔ)言編寫的PHP擴(kuò)展挨摸,提供一組規(guī)范標(biāo)準(zhǔn)的功能函數(shù)厦酬,在PHP項(xiàng)目中方便、規(guī)范贫贝、高效地寫日志同窘,以及快速地讀取和查詢?nèi)罩尽?br>

二、為什么需要日志系統(tǒng)

  1. 了解系統(tǒng)運(yùn)行情況
  2. 記錄用戶操作信息
  3. 收集需要

三晨缴、為什么選擇SeasLog

  1. 高性能 帶有緩沖池功能。
  2. 無(wú)需配置
  3. 功能完善峡捡,使用簡(jiǎn)單

四击碗、SeasLog安裝

到[pecl](http://pecl.php.net/)搜索seaslog并下載
解壓后
可自行編譯。
$ cd seaslog //進(jìn)到解壓目錄
$ phpize
$ ./configure --with-php-config=/path/to/php-config //path to 為你的PHP安裝目錄
$ make && make install
當(dāng)然们拙,使用PECL管理工具會(huì)更方便:
$ pecl install seaslog

seaslog.ini的配置

; configuration for php SeasLog module 
extension = seaslog.so 
seaslog.default_basepath = /log/seaslog-test    ;默認(rèn)log根目錄 
seaslog.default_logger = default                ;默認(rèn)logger目錄 
seaslog.disting_type = 1                            ;是否以type分文件 1是 0否(默認(rèn)) 
seaslog.disting_by_hour = 1                      ;是否每小時(shí)劃分一個(gè)文件 1是 0否(默認(rèn)) 
seaslog.use_buffer = 1                              ;是否啟用buffer 1是 0否(默認(rèn)) 
seaslog.buffer_size = 100                         ;buffer中緩沖數(shù)量 默認(rèn)0(不使用buffer_size) 
seaslog.level = 0                                       ;記錄日志級(jí)別 默認(rèn)0(所有日志)

需要將這里面的數(shù)據(jù)寫到php.ini中去

seaslog.disting_type = 1 開(kāi)啟以type分文件稍途,即log文件區(qū)分info\warn\erro
seaslog.disting_by_hour = 1 開(kāi)啟每小時(shí)劃分一個(gè)文件
seaslog.use_buffer = 1 開(kāi)啟buffer。默認(rèn)關(guān)閉睛竣。當(dāng)開(kāi)啟此項(xiàng)時(shí)晰房,日志預(yù)存于內(nèi)存,當(dāng)請(qǐng)求結(jié)束時(shí)(或異常退出時(shí))一次寫入文件射沟。
seaslog.buffer_size = 100 設(shè)置緩沖數(shù)量為100. 默認(rèn)為0,即無(wú)緩沖數(shù)量限制.當(dāng)buffer_size大于0時(shí),緩沖量達(dá)到該值則寫一次文件.
seaslog.level = 3 記錄的日志級(jí)別.默認(rèn)為0,即所有日志均記錄。當(dāng)level為1時(shí),關(guān)注debug以上級(jí)別(包括debug)与境,以此類推验夯。level大于8時(shí),所有日志均不記錄摔刁。

默認(rèn)常量有哪些

遵循PSR-3標(biāo)準(zhǔn)挥转,SeasLog 共將日志分成8個(gè)級(jí)別

SEASLOG_DEBUG "debug"
SEASLOG_INFO "info"
SEASLOG_NOTICE "notice"
SEASLOG_WARNING "warning"
SEASLOG_ERROR "error"
SEASLOG_CRITICAL "critical"
SEASLOG_ALERT "alert"
SEASLOG_EMERGENCY "emergency"

都提供哪些方法


<?php 
/** 
 * @author neeke@php.net 云智慧 
 */ 
 
class SeasLog 
{ 
    public function __construct() 
    { 
        #SeasLog init 
    } 
 
    public function __destruct() 
    { 
        #SeasLog distroy 
    } 
 
    /** 
     * 設(shè)置basePath 
     * @param $basePath 
     * @return bool 
     */ 
    static public function setBasePath($basePath) 
    { 
        return TRUE; 
    } 
 
    /** 
     * 獲取basePath 
     * @return string 
     */ 
    static public function getBasePath() 
    { 
        return 'the base_path'; 
    } 
 
    /** 
     * 設(shè)置模塊目錄 
     * @param $module 
     * @return bool 
     */ 
    static public function setLogger($module) 
    { 
        return TRUE; 
    } 
 
    /** 
     * 獲取最后一次設(shè)置的模塊目錄 
     * @return string 
     */ 
    static public function getLastLogger() 
    { 
        return 'the lastLogger'; 
    } 
 
    /** 
     * 統(tǒng)計(jì)所有類型(或單個(gè)類型)行數(shù) 
     * @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(); 
    } 
 
    /** 
     * 以數(shù)組形式,快速取出某類型log的各行詳情 
     * @param $level 
     * @param string $log_path 
     * @param null $key_word 
     * @param int $start 
     * @param int $limit 
     * @return array 
     */ 
    static public function analyzerDetail($level = SEASLOG_INFO,$log_path = '*',$key_word = NULL, $start = 1,$limit = 20) 
    { 
        return array(); 
    } 
 
    /** 
     * 獲得當(dāng)前日志buffer中的內(nèi)容 
     * @return array 
     */ 
    static public function getBuffer() 
    { 
        return array(); 
    } 
 
    /** 
     * 記錄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 = '') 
    { 
 
    } 
} 

在項(xiàng)目中如何使用

獲取與設(shè)置basePatn

/**
 *靜態(tài)方法可以不實(shí)例化直接使用
 *
 */
$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)中設(shè)置的seaslog.default_basepath 的值绑谣。

使用 SeasLog::getBasePath() 函數(shù)党窜,將改變 seaslog_get_basepath() 的取值。

設(shè)置logger與獲取lastLogger

$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)中設(shè)置的seaslog.default_logger 的值。

使用 SeasLog::setLogger() 函數(shù)壤玫,將改變 SeasLog::getLastLogger() 的取值豁护。

SeasLog Logger的使用

獲取與設(shè)置basePath

$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)中設(shè)置的 seaslog.default_basepath 的值欲间。

使用 SeasLog::setBasePath() 函數(shù)楚里,將改變 SeasLog::getBasePath() 的取值。

設(shè)置logger與獲取lastLogger

$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)中設(shè)置的 seaslog.default_logger 的值。

使用 SeasLog::setLogger() 函數(shù)她渴,將改變 SeasLog::getLastLogger() 的取值达址。
快速寫入log

上面已經(jīng)設(shè)置過(guò)了basePath與logger,于是log記錄的目錄已經(jīng)產(chǎn)生了惹骂,

log記錄目錄 = basePath / logger / {fileName}.log log文件名苏携,以 年月日 分文件,如今天是2014年02月18日期对粪,那么 {fileName} = 20140218;
還記得 php.ini 中設(shè)置的 seaslog.disting_type 嗎右冻?

默認(rèn)的 seaslog.disting_type = 0,如果今天我使用了 SeasLog 著拭,那么將產(chǎn)生最終的log文件:

* LogFile = basePath / logger / 20140218.log
如果 seaslog.disting_type = 1纱扭,則最終的log文件將是這樣的三個(gè)文件

  • 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'));


/*
這些函數(shù)同時(shí)也接受第3個(gè)參數(shù)為logger的設(shè)置項(xiàng)
注意,當(dāng)last_logger == 'default'時(shí)等同于:
SeasLog::setLogger('test/new/path');
SeasLog::error('test error 3');
如果已經(jīng)在前文使用過(guò)SeasLog::setLogger()函數(shù)儡遮,第3個(gè)參數(shù)的log只在此處臨時(shí)使用乳蛾,不影響下文。
*/

log格式統(tǒng)一為: {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 Analyzer的使用

快速統(tǒng)計(jì)某類型log的count值

SeasLog在擴(kuò)展中使用管道調(diào)用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)

*/

獲取某類型log列表

SeasLog在擴(kuò)展中使用管道調(diào)用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,'*');
取當(dāng)前模塊下所有l(wèi)evel為 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()));
只取得當(dāng)前模塊下因惭,當(dāng)前一天內(nèi),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 "
}

同理,取當(dāng)月
$detailErrorArray_mouth = SeasLog::analyzerDetail(SEASLOG_ERROR,date('Ym',time()));

*/
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末绩衷,一起剝皮案震驚了整個(gè)濱河市蹦魔,隨后出現(xiàn)的幾起案子激率,更是在濱河造成了極大的恐慌,老刑警劉巖勿决,帶你破解...
    沈念sama閱讀 206,378評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件乒躺,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡低缩,警方通過(guò)查閱死者的電腦和手機(jī)嘉冒,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,356評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人,你說(shuō)我怎么就攤上這事砂竖。” “怎么了娜遵?”我有些...
    開(kāi)封第一講書(shū)人閱讀 152,702評(píng)論 0 342
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)壤短。 經(jīng)常有香客問(wèn)我设拟,道長(zhǎng),這世上最難降的妖魔是什么久脯? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 55,259評(píng)論 1 279
  • 正文 為了忘掉前任纳胧,我火速辦了婚禮,結(jié)果婚禮上帘撰,老公的妹妹穿的比我還像新娘跑慕。我一直安慰自己,他們只是感情好摧找,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,263評(píng)論 5 371
  • 文/花漫 我一把揭開(kāi)白布核行。 她就那樣靜靜地躺著,像睡著了一般蹬耘。 火紅的嫁衣襯著肌膚如雪芝雪。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 49,036評(píng)論 1 285
  • 那天综苔,我揣著相機(jī)與錄音惩系,去河邊找鬼。 笑死如筛,一個(gè)胖子當(dāng)著我的面吹牛堡牡,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播杨刨,決...
    沈念sama閱讀 38,349評(píng)論 3 400
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼悴侵,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了拭嫁?” 一聲冷哼從身側(cè)響起可免,我...
    開(kāi)封第一講書(shū)人閱讀 36,979評(píng)論 0 259
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎做粤,沒(méi)想到半個(gè)月后浇借,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,469評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡怕品,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,938評(píng)論 2 323
  • 正文 我和宋清朗相戀三年妇垢,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片肉康。...
    茶點(diǎn)故事閱讀 38,059評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡闯估,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出吼和,到底是詐尸還是另有隱情涨薪,我是刑警寧澤,帶...
    沈念sama閱讀 33,703評(píng)論 4 323
  • 正文 年R本政府宣布炫乓,位于F島的核電站刚夺,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏末捣。R本人自食惡果不足惜侠姑,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,257評(píng)論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望箩做。 院中可真熱鬧莽红,春花似錦、人聲如沸邦邦。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,262評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)圃酵。三九已至柳畔,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間郭赐,已是汗流浹背薪韩。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,485評(píng)論 1 262
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留捌锭,地道東北人俘陷。 一個(gè)月前我還...
    沈念sama閱讀 45,501評(píng)論 2 354
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像观谦,于是被迫代替她去往敵國(guó)和親拉盾。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,792評(píng)論 2 345

推薦閱讀更多精彩內(nèi)容