文档章节

lager与lager_transform

hncscwc
 hncscwc
发布于 2014/06/16 18:06
字数 577
阅读 127
收藏 0
点赞 0
评论 0

lager是一个erlang的日志库,详解介绍参考 这里

在使用lager进行日志记录时, 只需要调用lager:Level/2,3即可(Level包括debug,info,notice,warning等等).例如:

lager:info("hello world").
在编译时使用lager写日志的模块都需要指定编译选项:
-compile([{parse_transform, lager_transform}]).
如果使用的是rebar, 也可以在配置文件中增加对应的参数, 而不需要在每个模块中都增加编译选项.
{erl_opts, [{parse_transform, lager_transform}]}.
上述都是使用的简单介绍,那么重点是在lager模块中找不到debug/2,debug/3,info/2等函数的实现。

实际上是erlang将编译源文件生成的Abstract code交由lager_transform模块的parse_transform函数再次进行处理,这个函数会将debug/2, debug/3这些函数直接转换为Abstract code。这也就是需要指定编译选项{parse_transform, lager_transform}的原因。

什么是Abstract code? 其格式是怎样的? 这里不多解释,直接翻看官方文档

代码 lager:info("hello world"). 通过转换后的Abstract code为:

[{'case',34,
           {tuple,34,
            [{call,34,{atom,34,whereis},[{atom,34,lager_event}]},
             {call,34,
              {remote,34,{atom,34,lager_config},{atom,34,get}},
              [{atom,34,loglevel},{tuple,34,[{integer,34,0},{nil,34}]}]}]},
           [{clause,34,
             [{tuple,34,[{atom,34,undefined},{var,34,'_'}]}],
             [],
             [{call,34,
               {'fun',34,
                {clauses,
                 [{clause,34,[],[],
                   [{tuple,34,
                     [{atom,34,error},{atom,34,lager_not_running}]}]}]}},
               []}]},
            {clause,34,
             [{tuple,34,
               [{var,34,'__Pidtest34'},
                {tuple,34,
                 [{var,34,'__Leveltest34'},{var,34,'__Tracestest34'}]}]}],
             [[{op,34,'orelse',
                {op,34,'/=',
                 {op,34,'band',{var,34,'__Leveltest34'},{integer,34,64}},
                 {integer,34,0}},
                {op,34,'/=',{var,34,'__Tracestest34'},{nil,34}}}]],
             [{call,34,
               {remote,34,{atom,34,lager},{atom,34,do_log}},
               [{atom,34,info},
                {cons,34,
                 {tuple,34,[{atom,34,application},{atom,34,upu}]},
                 {cons,34,
                  {tuple,34,[{atom,34,module},{atom,34,test}]},
                  {cons,34,
                   {tuple,34,[{atom,34,function},{atom,34,start}]},
                   {cons,34,
                    {tuple,34,[{atom,34,line},{integer,34,34}]},
                    {cons,34,
                     {tuple,34,
                      [{atom,34,pid},
                       {call,34,
                        {atom,34,pid_to_list},
                        [{call,34,{atom,34,self},[]}]}]},
                     {cons,34,
                      {tuple,34,[{atom,34,node},{call,34,{atom,34,node},[]}]},
                      {call,34,{remote,34,{atom,34,lager},{atom,34,md}},[]}}}}}}},
                {string,34,"hello world"},
                {atom,34,none},
                {integer,34,4096},
                {integer,34,64},
                {var,34,'__Leveltest34'},
                {var,34,'__Tracestest34'},
                {var,34,'__Pidtest34'}]}]},
            {clause,34,[{var,34,'_'}],[],[{atom,34,ok}]}]}]}]}
翻译成erlang代码为:

case {whereis(lager_event), lager_config:get(loglevel, {0,[]})} of
    {undefined, _} ->
        fun() ->
            {error, lager_not_running}
        end();
    {__Pidtest15, {__Leveltest15, __Tracestest15}}
        when (__Leveltest15 band 64) /= 0 orelse
             __Tracetest /= [] ->
            lager:do_log(info, [{application, App},
                                {module, Module},
                                {function, Function},
                                {line, LINE},
                                {pid, pid_to_list(self())},
                                {node, node()} | lager:md()],
                         "hello world",
                         none, 4096, 64
                         __Leveltest15, __Tracestest15, __Pidtest15);
    _ ->
        ok
end.
注: 上述代码中 App, Module, Function, Line分别表示实际应用的名称,模块的名称,函数的名称,所在行数。


© 著作权归作者所有

共有 人打赏支持
hncscwc
粉丝 64
博文 66
码字总数 76137
作品 0
杭州
程序员
解析Erlang日志组件lager的lager_transform模块

使用 lager 的时候,在编译应用的时候,需要加入选项 {parsetransform, lagertransform} erlc 会在编译你的项目源代码的时候,把生成的 abstract format forms 交给 lagertransform 模块的 ...

智深 ⋅ 2013/03/19 ⋅ 2

lager:error()调用的完整流程分析

这一节分析一条日志记录的完整流程 假设源代码中要打印日志,有这么一行 lager:error([{request, RequestID},{vhost, Vhost}], "Permission denied ~s", [User]) 经过上一节的分析,那么经过...

智深 ⋅ 2013/03/30 ⋅ 0

解析Erlang日志组件lager的监督树和模块

lager_app 应用行为模式实现 Handlers = [{lagerconsolebackend, info}, {lagerfilebackend, [ {"log/error.log", error, 10485760, "", 5}, {"log/console.log", info, 10485760, "", 5} ]}......

智深 ⋅ 2013/03/21 ⋅ 1

lager trace file的流程和实现分析

tracing是跟踪的意思,在lager中指的是跟踪用户打印的日志,根据属性做日志消息的重定向,如果没有tracing,那么lager没法做到按模块打印日志。 调用 lager:trace_file("logs/trace.log", [...

智深 ⋅ 2013/03/28 ⋅ 0

定制lager的输出

lager的输出可以定制,这里是我的定制方案。 在lager/ebin/lager.app里面的env字段里添加: {env,[... {log_root, "log"}, {handlers, [ {lagerconsolebackend, error}, {lagerfilebackend,......

格通 ⋅ 2016/03/17 ⋅ 0

RabbitMQ 3.7.0 Milestone 1 发布

RabbitMQ 3.7.0 Milestone 1发布,此版本的更新内容如下: 服务器改进内容: Lager-based logging: pluggable backends, debug log level, more flexibility in configuration. RabbitMQ no......

oschina ⋅ 2016/01/14 ⋅ 1

RabbitMQ 3.7.0 Milestone 2 发布

RabbitMQ 3.7.0 Milestone 2 发布了。RabbitMQ 是由 LShift 提供的一个 Advanced Message Queuing Protocol (AMQP) 的开源实现,由以高性能、健壮以及可伸缩性出名的 Erlang 写成,因此也是继...

oschina ⋅ 2016/03/29 ⋅ 1

RabbitMQ 3.7.0 Milestone 4 发布

RabbitMQ 3.7.0 Milestone 4 发布了,这是里程碑式的第四个版本,一个功能特性预览版。对Erlang/OTP的最低要求版本18.3。 该版本服务端的一些提升: New configuration file format I Rabbit...

oschina ⋅ 2016/05/18 ⋅ 1

erlagi 1.3 发布,AGI 的 Erlang 客户端

erlagi 1.3 发布了,erlagi 是 AGI (asterisk gateway interface) 的 Erlang 客户端实现。 新版本修复了一些小 bug,使用 lager 作为日志后端。...

oschina ⋅ 2013/04/29 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

Linux kernel脉络和主干总结

写在前面 前人常说,对Linux操作系统/内核的理解,是计算机行业从业者的内功,决定了你在技术领域想走多远。但内核的庞大以及学习曲线之陡峭,总让我在学习途中觉得犹如“管中窥豹”。 随着工...

Markz0928 ⋅ 28分钟前 ⋅ 0

在gcc中使用intel风格的内联汇编

很简单,内联汇编使用asm(“.intel_syntax noprefix/n”)声明一下,以后的内联汇编就可以用intel风格了,构建可执行文件时给gcc加上-masm=intel参数。 先写一个小程序测试一下: [cpp] view...

simpower ⋅ 38分钟前 ⋅ 0

NIO 之 ByteBuffer实现原理

相关文章 BIO、NIO、AIO 内部原理分析 NIO 之 Selector实现原理 NIO 之 Channel实现原理 前言 Java NIO 主要由下面3部分组成: Buffer Channel Selector 在传统IO中,流是基于字节的方式进行...

轨迹_ ⋅ 48分钟前 ⋅ 0

Jenkins docker权限问题

环境Ubuntu Server 工具 jenkins-war:2.89.2 报错信息 Cannot connect to the Docker daemon. Is the docker daemon running on this host?Build step 'Execute shell' marked build as fai......

Pulsar-V ⋅ 48分钟前 ⋅ 0

180621-一个简单的时间窗口设计与实现

如何设计一个计数的时间窗口 时间窗口,通常对于一些实时信息展示中用得比较多,比如维持一个五分钟的交易明细时间窗口,就需要记录当前时间,到五分钟之前的所有交易明细,而五分钟之前的数...

小灰灰Blog ⋅ 今天 ⋅ 0

Android之Dalvik、ART、JIT、AOT

Android之Dalvik、ART、JIT、AOT 本文内容:Dalvik、ART、JIT、AOT之间关系 本文定位:知识记录 学习过程记录,加深理解,提升文字组合表达能力。也希望能给学习的同学一些灵感 本文整理于[...

lichuangnk ⋅ 今天 ⋅ 0

Thrift RPC实战(五) thrift连接池

Thrift本身没有提供连接池,我们可以用Apache Commons Pool2来实现一个 一、定义对象工厂 BasePooledObjectFactory<T> extends BaseObject implements PooledObjectFactory<T> public class......

lemonLove ⋅ 今天 ⋅ 0

git 命令简写

简写 命令 g git gst git status gd git diff gdc git diff --cached gdv git diff -w "$@" | view - gl git pull gup git pull --rebase gp git push gc git commit -v gc! git commit -v ......

charley158 ⋅ 今天 ⋅ 0

Java中的锁使用与实现

1.Lock接口 锁是用来控制多个线程访问共享资源的方式,一般来说,一个锁能够防止多个线程同时访问共享资源。 在Lock出现之前,java程序是靠synchronized关键字实现锁功能的,而Java SE5之后,...

ZH-JSON ⋅ 今天 ⋅ 0

Intellij IDEA神器常用技巧四-类和方法注释模板设置

IDEA自带的注释模板不是太好用,我本人到网上搜集了很多资料系统的整理了一下制作了一份比较完整的模板来分享给大家,我不是专业玩博客的,写这篇文章只是为了让大家省事。 这里设置的注释模...

Mkeeper ⋅ 今天 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部