lager的使用
haogongju、人人IT网、59n南龙、360doc不要抄我的烂博客了,私人备忘用。
erlang本身提供了日志管理,但这与其它语言中常见的log4xxx的日志框架很不同:
日志文件是二进制的,查看起来很不方便;
每条日志跨多行文本,也不方便查找和分析。
总之,这自带的日志系统让用惯log4xxx系列的人用起来很不习惯。后来陆续有log4erl这样的应用,lager算是后来者,不过在性能等方面有独到之处,这是因为它使用parse_transformation机制的原因。
一、lager使用的步骤
直接在代码中用lager:debug, lager:info, lager:warning, lager:error系列函数输出日志就行了。这些函数的参数和io:format基本一样,除了一点,日志字符串结尾不用自己手动加回车。
麻烦的是其它工作,包括编译方式、参数配置,lager应用的启动,不过好在都是一次性的:
1. 编译选项 parse_transformation
最笨的办法是在每个模块的开头使用编译指令
-compile([{parse_transform, lager_transform}]}.
所有要使用lager的模块都加上这个指令代码无疑是很烦的事情,好在erlang编译器提供了一个选项,见compile。
当然如果用rebar的话更加简单,只要在rebar.config配置文件中添加:
{erl_opts, [{parse_transform, lager_transform}]}.
这样的编译就会自动织入lager代码,不需要给每个模块添加编译指令了。
2. lager应用的启动
这包括它依赖的两个erlang的lib应用:syntax_tools和compiler,一般用发布工具发布时会自动包含进来。但是开发中我们一般比较少直接使用发布工具,所以erl启动时lager不会也随之自动启动,lager本身作为应用要预先启动,有很多办法:
最直观的,我们当然可以用 application:start(lager) 手工启动lager应用。但是lager还依赖compiler和syntax_tools,这两个应用要先启动,lager才能正常启动。虽然在lager应用的lager.app文件有在applications属性中指出这些依赖,但是这似乎只对发布有效,application:start/1不会坚持这些依赖并启动这些依赖。
如果是用工具发布的应用系统,例如rebar发布配置文件(reltool.config)中,在'rel' 列出的应用里增加lager,这样,发布后lager会自动在系统初始化时启动,如下
{sys, [
{lib_dirs, ["../../", "../deps/"]},
{rel, "rts", "1",
[
kernel,
stdlib,
sasl,
lager,
rts
]},
3. lager的配置
可以在发布的app.config(后来rebar改名成sys.config)中配置。配置参数很多,日志输出级别,日志输出方式,如果是以文件的方式,又包括日志文件名,日志文件大小,循环日志文件等等。列出哲学配置参数很枯燥,还是直接看手册
二、常见问题和陷阱
lager:info/debug/warning/error函数未定义错误
当运行时出现有如下片断的错误:
... {'EXIT',{undef,[{lager,info, ...
(其中的info可以是 debug, warning等)
这是因为编译时的parse_transform没有“正确”设置的缘故,原因很多,以下是可能碰到的两个陷阱:
1. 只是修改配置信息(如修改rebar.config文件,加入{erl_opts, [{parse_transform, lager_transform}]} ),然后rebar compile是不会自动重新编译之前已有的编译好的代码的,必须清空已编译好的代码重新编译才行:rebar clean compile
原因其实也简单:rebar compile只会根据源代码的时间戳判断是否有必要重新编译,而编译配置选项的修改显然与之无关。
2. 对于rebar.config里的erl_opts配置,顺序很重要,{parse_transform, lager_transform} 必须在其他erl_opts的前面。也就是说rebar.config中必须是这样:
{erl_opts, [{parse_transform, lager_transform}]}.
{erl_opts, [debug_info, warnings_as_errors]}.
如果parse_transform排在后面了,是没有效果的:
{erl_opts, [debug_info, warnings_as_errors]}.
{erl_opts, [{parse_transform, lager_transform}]}.
这个陷阱很让人恼火。
其它问题
1. 直接在控制台上是不能直接使用lager:debug, lager:info等输出日志的
2. 警告级别的日志是lager:warning,不是lager:warn
3. 使用tail -f察看日志时会发现略有延迟,不过能够接受。
4. 如果没有日志生成,看不到日志信息,原因很多: