erlang的日志记录

OTP自带的日志机制很强大,但总是不习惯,我使用时发现日志记录量大时(比如上万的进程同时写日志,超过200MB后)很容易拖累系统。一个例子如图,这是一次崩溃后的dump文件,可以看到error_logger占用了大量的内存空间,而且还有160多万条消息等待处理中。这是在一次大量进程同时记录一个超时错误时发生的。日志文件也超过200MB。

 

如果使用多个文件间轮换的方式进行日志记录(rotating log),生成的并不是易读的文本日志,要在erlang中通过rb解读。

 

许多erlang应用都没有直接采用error_logger记录日志。

例如:

1. couchdb自己专门写了日志记录的模块couch_log,用一个supervisor模块管理couch_log,couch_log是一个gen_event的模块,显然日志的记录也是异步的,收到日志事件后负责往文件上写格式化后的日志信息。日志信息也是分级的。

2.当前版本的scalaris也有两个专门的日志记录模块,boot_logger和log,前者类似gen_server,接收日志信息并输出到终端或者文件,这个过程是同步的,后者其实就是一个文件写入的包装,不过写入之前会格式化日志信息加上时间标志。scalaris没有分级日志。

 

因此couchdb的日志要做得更像日志些。而提到专业的日志记录,这时不免怀念Java下的log4j,还好有log4erl了,用过log4j的会很熟悉,上手也容易。

 

0. 原理

log4erl是一个application,所以要使用必须先启动才行,log4erl做为application启动后会运行一个gen_server类型的模块接收记录日志请求,该模块最终调用一个gen_event的模块异步写日志。

 

1.  安装

直接在erlang安装目录的lib下解压文件,make后即可使用

 

2. 使用

记得要先启动作为application的log4erl:

 

application:start(log4erl)

 

与error_logger不同,log4erl不能直接将erlang term作为日志信息记录,log4erl的日志的使用类似与io:format。

 

 其它与log4erl的使用相同,五级日志信息:warn | info | error | fatal | debug。

 

系统中有多个日志记录器(logger),用户根据自己的需要可以用不同的日志记录器记录不同类型的日志,这样我们可以按各种标准划分日志,例如不同功能模块的日志信息由不同的日志记录器负责。

 

这些日志记录器由用户自己定义的atom标识,还有一个缺省的日志记录器,如果你不指定哪个日志记录器记录,就会用缺省的那个。

 

每个日志记录器(logger)可以有一个或多个输出方式(这被称为appender),每个appender都有一个atom标识,各个appender可能各不相同,可以是输出到终端屏幕上的,可以是记录在文件上的,smtp的,未来还有记录到数据库上的、SNMP的、SMTP的。一个日志记录器有多个appender使得同一个日志信息可以记录在多个地方。

 

日志信息中还可包含格式化的时间信息。

 

例子:

1. 为缺省日志记录器添加一个终端输出的appender,日志记录格式加入时间格式和日志级别:

 

16> log4erl:add_console_appender(cmd_logs, {info, "%j %T [%L] %l%n"}).
17> log4erl:get_appenders().
[{console_appender,cmd_logs}]

18> log4erl:log(info, "received message ~p", [abc]).
18-03-2009 22:16:45,911948 [info] received message abc

19> log4erl:warn("~p", [{a,{b,[c,d,e]}}]).
18-03-2009 22:17:48,920603 [warn] {a,{b,[c,d,e]}}

 

 

 

具体看文档,帮助很详细。

 

 

update

 

新版本的scalaris开始使用log4erl记录日志,这是log4erl当前的一个比较大的应用了吧

 

你可能感兴趣的:(C++,c,log4j,erlang,CouchDB)