PageRenderTime 51ms CodeModel.GetById 35ms RepoModel.GetById 0ms app.codeStats 0ms

/README.md

https://gitlab.com/lcp0578/SeasLog
Markdown | 580 lines | 485 code | 95 blank | 0 comment | 0 complexity | 35d575d5537f334ca4325ff8c16bc808 MD5 | raw file
Possible License(s): Apache-2.0
  1. # SeasLog
  2. A effective,fast,stable log extension for PHP
  3. @author Chitao.Gao [neeke@php.net]
  4. @交流群 312910117
  5. > ---
  6. - **[简介](#简介)**
  7. - **[为什么使用SeasLog](#为什么使用seaslog)**
  8. - **[目前提供了什么](#目前提供了什么)**
  9. - **[目标是怎样的](#目标是怎样的)**
  10. - **[安装](#安装)**
  11. - **[编译安装 SeasLog](#编译安装-seaslog)**
  12. - **[seaslog.ini的配置](#seaslogini的配置)**
  13. - **[使用](#使用)**
  14. - **[常量与函数](#常量与函数)**
  15. - [常量列表](#常量列表)
  16. - [函数列表](#函数列表)
  17. - **[SeasLog Logger的使用](#seaslog-logger的使用)**
  18. - [获取与设置basePath](#获取与设置basepath)
  19. - [设置logger与获取lastLogger](#设置logger与获取lastlogger)
  20. - [快速写入log](#快速写入log)
  21. - **[SeasLog Analyzer的使用](#seaslog-analyzer的使用)**
  22. - [快速统计某类型log的count值](#快速统计某类型log的count值)
  23. - [获取某类型log列表](#获取某类型log列表)
  24. - **[使用SeasLog进行健康预警](#使用seaslog进行健康预警)**
  25. - [预警的配置](#预警的配置)
  26. - [crontab配置](#crontab配置)
  27. - **[目前已知使用SeasLog的企业](#目前已知使用SeasLog的企业)**
  28. - [企业名单](#企业名单)
  29. > ---
  30. ## 简介
  31. ### 为什么使用SeasLog
  32. log日志通常是系统或软件应用的运行记录通过log的分析可以方便用户了解系统或软件应用的运行情况如果你的应用log足够丰富也可以分析以往用户的操作行为类型喜好地域分布或其他更多信息如果一个应用的log同时也分了多个级别那么可以很轻易地分析得到该应用的健康状况及时发现问题并快速定位解决问题补救损失
  33. php内置error_logsyslog函数功能强大且性能极好但由于各种缺陷(error_log无错误级别无固定格式syslog不分模块与系统日志混合)灵活度降低了很多不能满足应用需求
  34. 好消息是有不少第三方的log类库弥补了上述缺陷如log4phpplogAnalog等(当然也有很多应用在项目中自己开发的log类)其中以[log4php](http://logging.apache.org/log4php/)最为著名,设计精良、格式完美、文档完善、功能强大。推荐。
  35. 不过log4php在性能方面表现非常差,下图是SeasLog与log4php的ab并发性能测试( 测试环境:Ubuntu12.04单机,CPU I3,内存 16G,硬盘 SATA 7200):
  36. ![SeasLogVSlog4php](https://raw.githubusercontent.com/Neeke/SeasLog/master/tests/SeasLogVSlog4php.png)
  37. 那么有没有一种log类库满足以下需求呢
  38. * 分模块分级别
  39. * 配置简单(最好是勿须配置)
  40. * 日志格式清晰易读
  41. * 应用简单性能很棒
  42. `SeasLog` 正是应此需求而生
  43. ### 目前提供了什么
  44. * 在PHP项目中便捷规范地记录log
  45. * 可配置的默认log目录与模块
  46. * 指定log目录与获取当前配置
  47. * 初步的分析预警框架
  48. * 高效的日志缓冲便捷的缓冲debug
  49. * 遵循 PSR-3 日志接口规范
  50. * 自动记录错误信息
  51. * 自动记录异常信息
  52. ### 目标是怎样的
  53. * 便捷规范的log记录
  54. * 高效的海量log分析
  55. * 可配置多途径的log预警
  56. ## 安装
  57. ### 编译安装 SeasLog
  58. ```sh
  59. $ /path/to/phpize
  60. $ ./configure --with-php-config=/path/to/php-config
  61. $ make && make install
  62. ```
  63. ### PECL安装SeasLog
  64. ```sh
  65. $ pecl install seaslog
  66. ```
  67. ### seaslog.ini的配置
  68. ```conf
  69. ; configuration for php SeasLog module
  70. extension = seaslog.so
  71. seaslog.default_basepath = /log/seaslog-test ;默认log根目录
  72. seaslog.default_logger = default ;默认logger目录
  73. seaslog.disting_type = 1 ;是否以type分文件 1是 0否(默认)
  74. seaslog.disting_by_hour = 1 ;是否每小时划分一个文件 1是 0否(默认)
  75. seaslog.use_buffer = 1 ;是否启用buffer 1是 0否(默认)
  76. seaslog.buffer_size = 100 ;buffer中缓冲数量 默认0(不使用buffer_size)
  77. seaslog.level = 0 ;记录日志级别 默认0(所有日志)
  78. seaslog.trace_error = 1 ;自动记录错误 默认1(开启)
  79. seaslog.trace_exception = 0 ;自动记录异常信息 默认0(关闭)
  80. ```
  81. > `seaslog.disting_type = 1` 开启以type分文件即log文件区分info\warn\erro
  82. > `seaslog.disting_by_hour = 1` 开启每小时划分一个文件
  83. > `seaslog.use_buffer = 1` 开启buffer默认关闭当开启此项时日志预存于内存当请求结束时(或异常退出时)一次写入文件
  84. > `seaslog.buffer_size = 100` 设置缓冲数量为100. 默认为0,即无缓冲数量限制.当buffer_size大于0时,缓冲量达到该值则写一次文件.
  85. > `seaslog.level = 3` 记录的日志级别.默认为0,即所有日志均记录当level为1时,关注debug以上级别(包括debug)以此类推level大于8时所有日志均不记录
  86. ## 使用
  87. ### 常量与函数
  88. #### 常量列表
  89. `SeasLog 共将日志分成8个级别`
  90. * SEASLOG_DEBUG "debug"
  91. * SEASLOG_INFO "info"
  92. * SEASLOG_NOTICE "notice"
  93. * SEASLOG_WARNING "warning"
  94. * SEASLOG_ERROR "error"
  95. * SEASLOG_CRITICAL "critical"
  96. * SEASLOG_ALERT "alert"
  97. * SEASLOG_EMERGENCY "emergency"
  98. ```php
  99. var_dump(SEASLOG_DEBUG,SEASLOG_INFO,SEASLOG_NOTICE);
  100. /*
  101. string('debug') debug级别
  102. string('info') info级别
  103. string('notice') notice级别
  104. */
  105. ```
  106. #### 函数列表
  107. `SeasLog` 提供了这样一组函数可以方便地获取与设置根目录模块目录快速写入与统计log
  108. 相信从下述伪代码的注释中您可以快速获取函数信息具体使用将紧接其后
  109. ```php
  110. <?php
  111. /**
  112. * @author ciogao@gmail.com
  113. * Date: 14-1-27 下午4:47
  114. */
  115. class SeasLog
  116. {
  117. public function __construct()
  118. {
  119. #SeasLog init
  120. }
  121. public function __destruct()
  122. {
  123. #SeasLog distroy
  124. }
  125. /**
  126. * 设置basePath
  127. * @param $basePath
  128. * @return bool
  129. */
  130. static public function setBasePath($basePath)
  131. {
  132. return TRUE;
  133. }
  134. /**
  135. * 获取basePath
  136. * @return string
  137. */
  138. static public function getBasePath()
  139. {
  140. return 'the base_path';
  141. }
  142. /**
  143. * 设置模块目录
  144. * @param $module
  145. * @return bool
  146. */
  147. static public function setLogger($module)
  148. {
  149. return TRUE;
  150. }
  151. /**
  152. * 获取最后一次设置的模块目录
  153. * @return string
  154. */
  155. static public function getLastLogger()
  156. {
  157. return 'the lastLogger';
  158. }
  159. /**
  160. * 统计所有类型(或单个类型)行数
  161. * @param string $level
  162. * @param string $log_path
  163. * @param null $key_word
  164. * @return array | long
  165. */
  166. static public function analyzerCount($level = 'all',$log_path = '*',$key_word = NULL)
  167. {
  168. return array();
  169. }
  170. /**
  171. * 以数组形式,快速取出某类型log的各行详情
  172. *
  173. * @param $level
  174. * @param string $log_path
  175. * @param null $key_word
  176. * @param int $start
  177. * @param int $limit
  178. * @param $order
  179. *
  180. * @return array
  181. */
  182. static public function analyzerDetail($level = SEASLOG_INFO, $log_path = '*', $key_word = NULL, $start = 1, $limit = 20, $order = SEASLOG_DETIAL_ORDER_ASC)
  183. {
  184. return array();
  185. }
  186. /**
  187. * 获得当前日志buffer中的内容
  188. * @return array
  189. */
  190. static public function getBuffer()
  191. {
  192. return array();
  193. }
  194. /**
  195. * 将buffer中的日志立刻刷到硬盘
  196. *
  197. * @return bool
  198. */
  199. static public function flushBuffer()
  200. {
  201. return TRUE;
  202. }
  203. /**
  204. * 记录debug日志
  205. * @param $message
  206. * @param array $content
  207. * @param string $module
  208. */
  209. static public function debug($message,array $content = array(),$module = '')
  210. {
  211. #$level = SEASLOG_DEBUG
  212. }
  213. /**
  214. * 记录info日志
  215. * @param $message
  216. * @param array $content
  217. * @param string $module
  218. */
  219. static public function info($message,array $content = array(),$module = '')
  220. {
  221. #$level = SEASLOG_INFO
  222. }
  223. /**
  224. * 记录notice日志
  225. * @param $message
  226. * @param array $content
  227. * @param string $module
  228. */
  229. static public function notice($message,array $content = array(),$module = '')
  230. {
  231. #$level = SEASLOG_NOTICE
  232. }
  233. /**
  234. * 记录warning日志
  235. * @param $message
  236. * @param array $content
  237. * @param string $module
  238. */
  239. static public function warning($message,array $content = array(),$module = '')
  240. {
  241. #$level = SEASLOG_WARNING
  242. }
  243. /**
  244. * 记录error日志
  245. * @param $message
  246. * @param array $content
  247. * @param string $module
  248. */
  249. static public function error($message,array $content = array(),$module = '')
  250. {
  251. #$level = SEASLOG_ERROR
  252. }
  253. /**
  254. * 记录critical日志
  255. * @param $message
  256. * @param array $content
  257. * @param string $module
  258. */
  259. static public function critical($message,array $content = array(),$module = '')
  260. {
  261. #$level = SEASLOG_CRITICAL
  262. }
  263. /**
  264. * 记录alert日志
  265. * @param $message
  266. * @param array $content
  267. * @param string $module
  268. */
  269. static public function alert($message,array $content = array(),$module = '')
  270. {
  271. #$level = SEASLOG_ALERT
  272. }
  273. /**
  274. * 记录emergency日志
  275. * @param $message
  276. * @param array $content
  277. * @param string $module
  278. */
  279. static public function emergency($message,array $content = array(),$module = '')
  280. {
  281. #$level = SEASLOG_EMERGENCY
  282. }
  283. /**
  284. * 通用日志方法
  285. * @param $level
  286. * @param $message
  287. * @param array $content
  288. * @param string $module
  289. */
  290. static public function log($level,$message,array $content = array(),$module = '')
  291. {
  292. }
  293. }
  294. ```
  295. ### SeasLog Logger的使用
  296. #### 获取与设置basePath
  297. ```php
  298. $basePath_1 = SeasLog::getBasePath();
  299. SeasLog::setBasePath('/log/base_test');
  300. $basePath_2 = SeasLog::getBasePath();
  301. var_dump($basePath_1,$basePath_2);
  302. /*
  303. string(19) "/log/seaslog-ciogao"
  304. string(14) "/log/base_test"
  305. */
  306. ```
  307. > 直接使用 `SeasLog::getBasePath()`将获取php.ini(seaslog.ini)中设置的 `seaslog.default_basepath` 的值
  308. > 使用 `SeasLog::setBasePath()` 函数将改变 `SeasLog::getBasePath()` 的取值
  309. #### 设置logger与获取lastLogger
  310. ```php
  311. $lastLogger_1 = SeasLog::getLastLogger();
  312. SeasLog::setLogger('testModule/app1');
  313. $lastLogger_2 = SeasLog::getLastLogger();
  314. var_dump($lastLogger_1,$lastLogger_2);
  315. /*
  316. string(7) "default"
  317. string(15) "testModule/app1"
  318. */
  319. ```
  320. > 与basePath相类似的
  321. > 直接使用 `SeasLog::getLastLogger()`将获取php.ini(seaslog.ini)中设置的 `seaslog.default_logger` 的值
  322. > 使用 `SeasLog::setLogger()` 函数将改变 `SeasLog::getLastLogger()` 的取值
  323. #### 快速写入log
  324. 上面已经设置过了basePath与logger于是log记录的目录已经产生了
  325. > log记录目录 = basePath / logger / {fileName}.log
  326. log文件名 `年月日` 分文件如今天是2014年02月18日期那么 `{fileName}` = `20140218`;
  327. 还记得 `php.ini` 中设置的 `seaslog.disting_type`
  328. 默认的 `seaslog.disting_type = 0`如果今天我使用了 `SeasLog` 那么将产生最终的log文件
  329. * LogFile = basePath / logger / 20140218.log
  330. 如果 `seaslog.disting_type = 1`则最终的log文件将是这样的三个文件
  331. * infoLogFile = basePath / logger / INFO.20140218.log
  332. * warnLogFile = basePath / logger / WARN.20140218.log
  333. * erroLogFile = basePath / logger / ERRO.20140218.log
  334. ```php
  335. SeasLog::log(SEASLOG_ERROR,'this is a error test by ::log');
  336. SeasLog::debug('this is a {userName} debug',array('{userName}' => 'neeke'));
  337. SeasLog::info('this is a info log');
  338. SeasLog::notice('this is a notice log');
  339. SeasLog::warning('your {website} was down,please {action} it ASAP!',array('{website}' => 'github.com','{action}' => 'rboot'));
  340. SeasLog::error('a error log');
  341. SeasLog::critical('some thing was critical');
  342. SeasLog::alert('yes this is a {messageName}',array('{messageName}' => 'alertMSG'));
  343. SeasLog::emergency('Just now, the house next door was completely burnt out! {note}',array('{note}' => 'it`s a joke'));
  344. /*
  345. 这些函数同时也接受第3个参数为logger的设置项
  346. 注意,当last_logger == 'default'时等同于:
  347. SeasLog::setLogger('test/new/path');
  348. SeasLog::error('test error 3');
  349. 如果已经在前文使用过SeasLog::setLogger()函数,第3个参数的log只在此处临时使用,不影响下文。
  350. */
  351. ```
  352. > log格式统一为: `{type} | {pid} | {timeStamp} |{dateTime} | {logInfo}`
  353. ```sh
  354. error | 23625 | 1406422432.786 | 2014:07:27 08:53:52 | this is a error test by log
  355. debug | 23625 | 1406422432.786 | 2014:07:27 08:53:52 | this is a neeke debug
  356. info | 23625 | 1406422432.787 | 2014:07:27 08:53:52 | this is a info log
  357. notice | 23625 | 1406422432.787 | 2014:07:27 08:53:52 | this is a notice log
  358. warning | 23625 | 1406422432.787 | 2014:07:27 08:53:52 | your github.com was down,please rboot it ASAP!
  359. error | 23625 | 1406422432.787 | 2014:07:27 08:53:52 | a error log
  360. critical | 23625 | 1406422432.787 | 2014:07:27 08:53:52 | some thing was critical
  361. emergency | 23625 | 1406422432.787 | 2014:07:27 08:53:52 | Just now, the house next door was completely burnt out! it is a joke
  362. ```
  363. ### SeasLog Analyzer的使用
  364. #### 快速统计某类型log的count值
  365. `SeasLog`在扩展中使用管道调用shell命令 `grep -wc`快速地取得count值,并返回值(array || int)给PHP。
  366. ```php
  367. $countResult_1 = SeasLog::analyzerCount();
  368. $countResult_2 = SeasLog::analyzerCount(SEASLOG_WARNING);
  369. $countResult_3 = SeasLog::analyzerCount(SEASLOG_ERROR,date('Ymd',time()));
  370. var_dump($countResult_1,$countResult_2,$countResult_3);
  371. /*
  372. array(8) {
  373. ["debug"]=>
  374. int(3)
  375. ["info"]=>
  376. int(3)
  377. ["notice"]=>
  378. int(3)
  379. ["warning"]=>
  380. int(3)
  381. ["error"]=>
  382. int(6)
  383. ["critical"]=>
  384. int(3)
  385. ["alert"]=>
  386. int(3)
  387. ["emergency"]=>
  388. int(3)
  389. }
  390. int(7)
  391. int(1)
  392. */
  393. ```
  394. #### 获取某类型log列表
  395. `SeasLog`在扩展中使用管道调用shell命令 `grep -w`快速地取得列表,并返回array给PHP。
  396. ```php
  397. $detailErrorArray_inAll = SeasLog::analyzerDetail(SEASLOG_ERROR);
  398. $detailErrorArray_today = SeasLog::analyzerDetail(SEASLOG_ERROR,date('Ymd',time()));
  399. var_dump($detailErrorArray_inAll,$detailErrorArray_today);
  400. /*
  401. SeasLog::analyzerDetail(SEASLOG_ERROR) == SeasLog::analyzerDetail(SEASLOG_ERROR,'*');
  402. 取当前模块下所有level为 SEASLOG_ERROR 的信息列表:
  403. array(6) {
  404. [0] =>
  405. string(66) "error | 8568 | 1393172042.717 | 2014:02:24 00:14:02 | test error 3 "
  406. [1] =>
  407. string(66) "error | 8594 | 1393172044.104 | 2014:02:24 00:14:04 | test error 3 "
  408. [2] =>
  409. string(66) "error | 8620 | 1393172044.862 | 2014:02:24 00:14:04 | test error 3 "
  410. [3] =>
  411. string(66) "error | 8646 | 1393172045.989 | 2014:02:24 00:14:05 | test error 3 "
  412. [4] =>
  413. string(66) "error | 8672 | 1393172047.882 | 2014:02:24 00:14:07 | test error 3 "
  414. [5] =>
  415. string(66) "error | 8698 | 1393172048.736 | 2014:02:24 00:14:08 | test error 3 "
  416. }
  417. SeasLog::analyzerDetail(SEASLOG_ERROR,date('Ymd',time()));
  418. 只取得当前模块下,当前一天内,level为SEASLOG_ERROR 的信息列表:
  419. array(2) {
  420. [0] =>
  421. string(66) "error | 8568 | 1393172042.717 | 2014:02:24 00:14:02 | test error 3 "
  422. [1] =>
  423. string(66) "error | 8594 | 1393172044.104 | 2014:02:24 00:14:04 | test error 3 "
  424. }
  425. 同理,取当月
  426. $detailErrorArray_mouth = SeasLog::analyzerDetail(SEASLOG_ERROR,date('Ym',time()));
  427. */
  428. ```
  429. ### 使用SeasLog进行健康预警
  430. #### 预警的配置
  431. ```conf
  432. [base]
  433. wait_analyz_log_path = /log/base_test
  434. [fork]
  435. ;是否开启多线程 1开启 0关闭
  436. fork_open = 1
  437. ;线程个数
  438. fork_count = 3
  439. [warning]
  440. email[smtp_host] = smtp.163.com
  441. email[smtp_port] = 25
  442. email[subject_pre] = 预警邮件 -
  443. email[smtp_user] = seaslogdemo@163.com
  444. email[smtp_pwd] = seaslog#demo
  445. email[mail_from] = seaslogdemo@163.com
  446. email[mail_to] = gaochitao@weiboyi.com
  447. email[mail_cc] = ciogao@gmail.com
  448. email[mail_bcc] =
  449. [analyz]
  450. ; enum
  451. ; SEASLOG_DEBUG "debug"
  452. ; SEASLOG_INFO "info"
  453. ; SEASLOG_NOTICE "notice"
  454. ; SEASLOG_WARNING "warning"
  455. ; SEASLOG_ERROR "error"
  456. ; SEASLOG_CRITICAL "critical"
  457. ; SEASLOG_ALERT "alert"
  458. ; SEASLOG_EMERGENCY "emergency"
  459. test1[module] = test/bb
  460. test1[level] = SEASLOG_ERROR
  461. test1[bar] = 1
  462. test1[mail_to] = gaochitao@weiboyi.com
  463. test2[module] = 222
  464. test2[level] = SEASLOG_WARNING
  465. test3[module] = 333
  466. test3[level] = SEASLOG_CRITICAL
  467. test4[module] = 444
  468. test4[level] = SEASLOG_EMERGENCY
  469. test5[module] = 555
  470. test5[level] = SEASLOG_DEBUG
  471. ```
  472. #### crontab配置
  473. ```conf
  474. ;每天凌晨3点执行
  475. 0 3 * * * /path/to/php /path/to/SeasLog/Analyzer/SeasLogAnalyzer.php
  476. ```
  477. ## 目前已知使用SeasLog的企业
  478. ### 企业名单
  479. - 云智慧 www.cloudwise.com
  480. - 高德(部分项目)
  481. - 腾讯(部分项目)
  482. - Formax www.jrq.com
  483. - 重庆易宠科技(中国最大的独立宠物平台) www.epet.com
  484. - 微财富 www.weicaifu.com
  485. - 更多请提交PR