- 标题:RPC框架的日志设计核心点
概述
- 服务的日志主要用来快速排查各类问题,包括:框架启动失败、服务运行异常、业务逻辑失败等等
- 因此日志的设计目标就是:能否快速解决业务问题,同时也要有成本、性能和易用性的考量.
- 主要打法就是:框架日志清晰齐全、框架日志固定目录文件、访问日志灵活可控制(解决主调、耗时等类型问题)、远程日志(索引、排序、trace关联、离线日志等)
- 从日志处于的位置分为本地日志和远程日志
本地日志
框架日志
日志路径
- 日志根路径:/data/app/taf/app_log/app/{app}/app/{servname}/
- 框架日志:/data/app/taf/app_log/app/{app}/app/{servname}/framework/{servname}.log
设计
- 在框架启动的时候,会默认创建框架日志的配置(logger和appender),同时支持logback和log4j2,异步分日志和文件大小滚动
- 固定路径和文件的必要性就在于,方便框架类问题的排查.
- 初始化业务日志配置的路径: ,框架在服务启动的时候,会注入一些业务配置需要的环境变量,比如loghome/servname等,方便日志配置中引用.
框架日志打印规范
- 一些较早执行的逻辑日志,需要用replay重放的方式来打印(spirngboot的日志加载逻辑)
- 打印关键日志:比如启动时候打印各个步骤的日志(配置初始化、tafclient初始化、配置加载、端口监听、tafnode keepalive等等)、网络调用异常明细(ip-port、耗时、异常类型、服务、接口等等)、过载日志等等
- 不要影响服务性能:比如过载时候的日志,如果过多打印日志,反而会让服务性能受到影响,可以通过采样打印日志指标上报等观测过载情况; 要用异步可丢弃的日志打印方式
- 框架日志不要多,业务默认开启info级别日志即可,一天的框架日志量在几百k左右,这样能够定位框架类的问题,同时不影响性能以及成本.
访问日志(accesslog)
- accesslog在很多框架中都存在的概念,比如nginx、dubbo,作用是用来分析一些访问的数据,比如查询主调信息、请求异常、请求高耗时等问题问题
- 打印逻辑:特殊请求全采样(框架异常错误码、超过3s的高耗时请求),正常请求是万分之五的采样率(避免高并发服务的日志爆炸问题)
- 参数可控制
采样率可以通过tafadmin的指令下发:taf.setAccessLogRatio 0.1(第二个参数为采样率),通过环境变量控制:ACCESSLOG_RATIO - 高耗时可以通过代码设置:ACCESS_LOG_SLOW_REQ
- 日志打印格式:traceId|requestId|主调服务名|主调方ip|接口名|框架状态码|耗时|qps
远程日志
方案选型
方案一:进程内上报日志信息到日志服务器
方案二:通过单独的采集agent采集日志到日志服务器
优劣:方案一可控制性更强,方案二的解耦会更好.
我们采用方案一,方案一的已知好处:
- 可以做到默认日志全部采集,开发基本无感知
- 可以上报时间戳给服务器,这样服务器可以按照时间去做排序,更符合开发的顺序日志的习惯
- 可以上报trace信息给服务器,比如traceid和采样信息,这样服务器可以打通trace平台,去跳转trace明细或者搜索采样trace的日志
实现
- 实现一个远程日志的appdener,比如叫做TafLogAppender,appender中会将日志丢到内存队列中,然后一个线程轮询去获取并上报到日志服务器
- appender中需要注意处理循环日志的问题,就是上报逻辑不断产生新的日志,重新进入到appender当中,这里是通过日志特殊标签的方式去区分从而不上报.
- 在框架启动的时候,去轮询所有的logger,然后给logger挂一个taflogappender,这样就可以自动上报日志,当然appender的配置也可以在日志配置文件中去配置,做到个性化配置.
离线日志
- 日志服务器除了提供在线的日志搜索功能外,还可以提供离线日志查询,比如hive表
- 作用一:节约成本,并且可以查询一个月内的日志
- 作用二:可以清洗日志,做一些数据统计分析
日志告警
- 通过消息队列等消费实时日志,去做一些日志告警功能,感知系统问题.