Erlang中日志管理
http://blog.sina.com.cn/s/blog_96b8a1540101317g.html
一、基本概念
在Erlang中,通过两个概念管理错误事情:事件管理器(event manager)和事件处理句柄(event handles)。通常各种错误、警告和消息事件都会有Erlang运行时系统发送给事件管理器。在Erlang中,默认的事情管理器为error logger,其进程名注册为error_logger。默认情况下error_logger把这些事件直接输出到控制台上。
在系统启动的一开始,error_logger只有一个简单的事件处理句柄,该处理句柄只是做缓冲和原始格式的打印操作。查看error_logger的源码,可以看到其启动过程如下:
-spec start() -> {'ok', pid()} | {'error', any()}.
start() ->
case gen_event:start({local, error_logger}) of
{ok, Pid} ->
simple_logger(?buffer_size),
{ok, Pid};
Error -> Error
end.
-spec start_link() -> {'ok', pid()} | {'error', any()}.
start_link() ->
case gen_event:start_link({local, error_logger}) of
{ok, Pid} ->
simple_logger(?buffer_size),
{ok, Pid};
Error -> Error
end.
OK,只是简单的注册了一个进程,看看simple_logger的内容:
simple_logger(Buffer_size) when is_integer(Buffer_size) ->
gen_event:add_handler(error_logger, error_logger, Buffer_size).
看来error_logger在一开始的时候除了充当manager,也担当了handler的角色。
在启动的过程中,kernel application使用一个标准的事件处理句柄来代替之前的那个简单版本,这个版本会将输出到控制台的结果做个漂亮的格式化。当然,可以通过kernel的配置选项来修改上述行为,例如将结果输出到文件或者干脆什么都不干(忽略任何event)。口说无凭,还是继续看源码吧:
kernel.erl文件:
start(_, []) ->
case supervisor:start_link({local, kernel_sup}, kernel, []) of
{ok, Pid} ->
Type = get_error_logger_type(),
error_logger:swap_handler(Type),
{ok, Pid, []};
Error -> Error
end.
首先,kernel把自己注册为一个名为kernel_sup的监控树进程,其次立刻就更换了error_logger的处理句柄。go on:
get_error_logger_type() ->
case application:get_env(kernel, error_logger) of
{ok, tty} -> tty;
{ok, {file, File}} when is_list(File) -> {logfile, File};
{ok, false} -> false;
{ok, silent} -> silent;
undefined -> tty; % default value
{ok, Bad} -> exit({bad_config, {kernel, {error_logger, Bad}}})
end.
代码很容易理解,根据配置来决定以何种方式处理日志。
二、定制Kernel选项
继续接着上面的代码往下走:
swap_handler(tty) ->
gen_event:swap_handler(error_logger, {error_logger, swap},
{error_logger_tty_h, []}),
simple_logger();
swap_handler({logfile, File}) ->
gen_event:swap_handler(error_logger, {error_logger, swap},
{error_logger_file_h, File}),
simple_logger();
swap_handler(silent) ->
gen_event:delete_handler(error_logger, error_logger, delete),
simple_logger();
swap_handler(false) ->
ok. % keep primitive event handler as-is
可以看出,如果我们真的希望什么都不做,那么应该传递参数 silent,而不是false,因为false情况下原来的原始处理句柄并没有被移除掉。
打开命令提示符,做个简单的实验(>表示命令提示符):
实验一,定制为false参数:
> erl -kernel error_logger false //传递false参数
2> error_logger:error_msg("Haha"). // 尝试产生一个error event
ok{error_logger,{{
2010,2> 3,10},{15,9,1}},"Haha",[]} //这里是结果
实验二,定制为silent参数:
> erl -kernel error_logger silent //传递silent 参数
1> error_logger:error_msg("Haha").
ok // 看到这里只有ok,没有其他任何信息了!
2>
三、SASL
SASL全称System Architecture Support Libraries,提供如下几个服务:
alarm_handler
overload
rb
release_handler
systools
SASL带有error_logger的事件处理句柄用于格式化SASL错误和crash报告,这些句柄如下:
sasl_report_tty_h sasl_report_file_h error_logger_mf_h
细节参考OTP文档可知。
SASL的默认event handler会将crash报告、supervisor和进程报告输出到控制台,如果你希望看到这些信息,那么在erlang启动时需要加上指定的参数以启动sasl。
为了方便日志的查看,通常sasl和其他日志是分开输出的,可以在启动erl时使用如下命令行参数:
-sasl sasl_error_logger {file,"/data/ log/sasl.log"}
四、站在巨人的肩膀上
这里并不打算介绍一个gen_event behavior模块的写法,而是想介绍一个非常强大、成熟的一个日志系统:ejabberd的日志系统。它包含两个部分:
dynamic_compile.erl 动态编译基础模块
ejabberd_logger_h.erl 这是个gen_event behavior模块,可以定制我们写日志的行为
ejabberd_loglevel.h 这个是ejabberd日志系统的精华,可以在运行时动态调节日志的输出级别。
用法很简单:
error_logger:add_report_handler(ejabberd_logger_h, LogPath),
ejabberd_loglevel:set(4) //级别4是info日志
原理很简单,利用code模块的load_binary来实现动态代码替换,但是确实非常强大,可以在需要的时候打开某些特定级别的日志,在系统负载高的时候或者不需要的时候关闭它。
Erlang中日志管理的更多相关文章
- web项目中日志管理工具的使用
在web项目中,很多时候会用到日志管理工具,常见的日志管理用具有:JDK logging(配置文件:logging.properties) 和log4j(配置文件:log4j.properties) ...
- Django中日志管理
在settings中设置日志的相关信息,然后再逻辑代码区就可以保存相应的信息了 #简单设置: LOGGING = { 'version': 1, 'disable_existing_loggers': ...
- SpringBoot | 第二十三章:日志管理之整合篇
前言 在本系列<第四章:日志管理>中,由于工作中日志这块都是走默认配置,也没有深入了解过,因为部署过程中直接使用了linux中的输出重定向功能,如java -jar xx.jar > ...
- 利用log4j+mongodb实现分布式系统中日志统一管理
背景 在分布式系统当中,我们有各种各样的WebService,这些服务可能分别部署在不同的服务器上,并且有各自的日志输出.为了方便对这些日志进行统一管理和分析.我们可以将日志统一输出到指定的数 ...
- 如何在 ETL 项目中统一管理上百个 SSIS 包的日志和包配置框架
一直准备写这么一篇有关 SSIS 日志系统的文章,但是发现很难一次写的很完整.因为这篇文章的内容可扩展的性太强,每多扩展一部分就意味着需要更多代码,示例和理论支撑.因此,我选择我觉得比较通用的 LOG ...
- SQL Server中的事务日志管理(7/9):处理日志过度增长
当一切正常时,没有必要特别留意什么是事务日志,它是如何工作的.你只要确保每个数据库都有正确的备份.当出现问题时,事务日志的理解对于采取修正操作是重要的,尤其在需要紧急恢复数据库到指定点时.这系列文章会 ...
- SQL Server中的事务日志管理(9/9):监控事务日志
当一切正常时,没有必要特别留意什么是事务日志,它是如何工作的.你只要确保每个数据库都有正确的备份.当出现问题时,事务日志的理解对于采取修正操作是重要的,尤其在需要紧急恢复数据库到指定点时.这系列文章会 ...
- SQL Server中的事务日志管理(5/9):完整恢复模式里的日志管理
当一切正常时,没有必要特别留意什么是事务日志,它是如何工作的.你只要确保每个数据库都有正确的备份.当出现问题时,事务日志的理解对于采取修正操作是重要的,尤其在需要紧急恢复数据库到指定点时.这系列文章会 ...
- SQL Server中的事务日志管理(3/9):事务日志,备份与恢复
当一切正常时,没有必要特别留意什么是事务日志,它是如何工作的.你只要确保每个数据库都有正确的备份.当出现问题时,事务日志的理解对于采取修正操作是重要的,尤其在需要紧急恢复数据库到指定点时.这系列文章会 ...
随机推荐
- Ubuntu配置图形桌面LXDE和VNC、中文语言包、中文输入法
Ubuntu配置图形桌面LXDE和VNC.中文语言包.中文输入法 http://www.lijiejie.com/ubuntu-vps-config-lxde-vnc/ LXDE是Ubuntu图形桌面 ...
- .less为后缀的文件是什么
.less为后缀的文件是什么 一.总结 1.less是什么:LESS 为 Web 开发者带来了福音,它在 CSS 的语法基础之上,引入了变量,Mixin(混入),运算以及函数等功能,大大简化了 CSS ...
- HTML基础第十二讲---链接标志
转自:https://i.cnblogs.com/posts?categoryid=1121494 没有链接,WWW将失去存在的意义!WWW之所以受欢迎,乃在于她除了有精美的图文之外,更有方便且多样化 ...
- js日期常用方法
js获取日期时间格式 export function formatDateTime(timeStamp) { var date = new Date(); date.setTime(timeStamp ...
- postman带cookie进行请求
接口地址: https://m.xxxx.com/api/front/activity/xs/session 打开postman的headers, 然后复制fiddler中接口的cookie,设置co ...
- 一个简单http请求的jmeter压测实战流程
1.新建线程组 2.创建http请求 注意:接口路径中的参数值要写变量 3.创建txt文件,存多个参数值 4.创建csv文件,在csv中上传txt文件 5.variable name填写txt中参数值 ...
- javasciprt cookies 操作
<script type="text/javascript"> function getCookie(c_name){ if (document.cookie.leng ...
- Javascript和jquery事件--鼠标事件的小结
1.鼠标事件的主要事件应该是mouseup, mousedown, mousewheel, mousemove, mouseover, moveout. <1>其中mouseup和mous ...
- JS学习笔记 - 透明度运动框
该练习的笔记如下: 1. var cur=0; //先声明一个变量. 2. parseInt会舍掉小数,而opacity值恰恰是小数,所以对于opacity,必须用parseFloat. cur ...
- 2013腾讯编程马拉松初赛第〇场(HDU 4504)威威猫系列故事——篮球梦
http://acm.hdu.edu.cn/showproblem.php?pid=4504 题目大意: 篮球赛假如我们现在已经知道当前比分 A:B,A代表我方的比分,B代表对方的比分,现在比赛还剩下 ...