日志系统是项目开发/运维当中非常重要的一部分,提供产品使用情况,跟踪调试信息等。以前都是各个项目各自实现日志记录,比如PHP、JAVA各自实现一套,如果要跨项目/服务器进行查询/跟踪/统计,则比较麻烦,比如Web后台–>业务模块–>基础组件,客户端–>公共接口–>业务模块等等。
目前的项目都是将日志写入本地,首先需要定义统一的规范:
格式 DateTime | ServerIP | ClientIP | PID | RequestID| Type | Level | Message| Code 解释 DateTime:记录日志的当前时间戳 ServerIP:当前服务器IP ClientIP:客户端IP PID:进程ID RequestID:交易号,即请求的唯一标识,使用uniqid(+UserCode)或UUID或,一次请求会有多条日志,,用于关联本次请求内的相关日志 Type:日志类型,比如统计,操作(审计),业务等 Level:日志等级 Message:日志内容,当为值为数组或者对象时转为JSON Type为RUNTIME时,表示运行日志,属性:自定义 Type为HTTP时,表示来源请求,属性:Url,Method(Get/Post),Params,RemoteIP,UserAgent,ReferUrl[,Action,Method] Type为REST时,表示外部调用,属性:Type(Http/Https),Url,Port,RequestParams,Response,RunTime; Type为SQL时,表示SQL执行,属性:Sql,RunTime Code:标识码,记录错误码、响应码、统计码、版本、自定义信息,方便统计
这里的RequestID由入口处自动产生,用于标识一次请求,关联所产生的所有日志,需要在各个项目之间传递。为了减少日志,Level通常为Info级别,避免产生过多日志。为了方便调试追踪,RequestID和Level也可以在其他参数中指明,比如HTTP头里面附加。
然后是日志收集:客户端收走日志系统,发送给日志系统服务端。
然后分析处理呈现:服务端将接收到的日志,发给处理其他组件分析处理,提供Web界面的查询系统。研发人员,可以错误信息,定位问题;获悉程序运行情况进行调优;大数据分析日志,得出产品使用情况;运维平台则可以进行业务报警。
日志产生由个语言依照规范自行实现,收集、保持则由Flume和Kafka实现。Flume是一个分布式的日志收集、合并、移动系统,能够监控文件变化,将变化部分传输出去。Kafka是一个分布式的发布/订阅的消息流平台,包括Broker,Consumer,Producer都支持分布式,依赖Zookeeper实现。
在PHP上面的实现,一开始使用log4php,看起来很美好,但是性能很差,对业务影响较大。决定再次简化,砍掉不必要的东西(Socket,邮件等等),在C语言开发的PHP日志扩展SeasLog基础上在做开发,将日志文件保存在本地。为了减少日志所占用内存,每超过一定的大小的日志即进行保存,否则在最后进行保存,利用了Nginx的fastcgi_finish_request特性。生产上发现,每天产生的文件日志太大了,需要控制日志信息大小、等级,并及时清理。
对于Web后台,还结合FirePHP,将日志直接输出到浏览器,方便边运行变调试。
参考链接:
最佳日志实践
Optimal Logging
Flume+Kafka收集Docker容器内分布式日志应用实践
基于Flume的美团日志收集系统(一)架构和设计
Twitter是如何构建高性能分布式日志的
开源日志系统比较
Kafka剖析(一):Kafka背景及架构介绍
基于Flume的野狗实时日志系统的演进和优化
EVODelavega/phpkafka
有赞统一日志平台初探
RabbitMQ和kafka从几个角度简单的对比
Flume-ng的原理和使用
利用flume+kafka+storm+mysql构建大数据实时系统