Lager库使用介绍

本文详细介绍了如何使用Lager库来管理和扩展Erlang应用的日志,包括基础使用、配置、日志扩展、日志格式化、过载保护等。Lager提供了一套完善的日志解决方案,支持日志等级设定、文件轮转、自定义backend等功能,且能与OTP 21.0后的Logger模块兼容。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

使用Lager库来管理erlang应用的日志模块

erlang本身已经提供了基础的日志模块error_logger还有OTP 21.0之后的Logger模块,这些模块在项目比较轻量,日志可控,功能简单的情况下完全可以满足需要,但是Lager提供了一个更加成熟的完整的解决方案,从日志文件的配置,等级设定,到跟踪,日志文件轮转提供了完整的生态接口,通过Lager几乎可以满足所有的日志需求,而且不需要考虑erlang版本变更带来的问题。

基础使用

Lager的ReadMe已经描述了最基础的使用范例,简单来说需要以下几步:

  1. 需要在编译选项中加入{parse_transform, lager_transform},因为Lager是通过parse_transform来完成了lager:info这种函数的具体实现,不像传统的日志模块,直接调用,所有的module都必须在该编译选项下才能调用lager

对于使用rebar的项目,只需要在rebar.config中修改或者增加erl_opts项,加入{parse_transform, lager_transform}即可,MakeFile同理
如果只给单个文件提供日志功能,可以在erl中加入编译选项声明-compile([{parse_transform, lager_transform}]).

不要在自己项目的基础模块中将lager调用包装成函数,然后其他模块再调用函数,这样会影响后续lager的功能,只能通过宏来完成,宏到时候会进行代码替换,确保lager功能都是直接原生调用

  1. 编写测试代码,加入lager调用,创建lage_test.erl 把下列代码写入到文件中,使用带编译项的第一步配置进行编译
-module(lager_test).
%% API
-export([test/0]).
test() ->
    application:ensure_all_started(lager),
    lager:error("error msg"),
    lager:warning("warning msg"),
    lager:debug("debug msg"),
    lager:info("info msg"),
    lager:critical("critical msg"),
    erlang:spawn_link(fun() -> erlang:throw("this is test") end).
  1. 启动命令行,执行lager_test:test(). 命令行启动的时候通过-pa把lager加入到代码加载路径

执行后在当前目录的log目录下会生成error.logconsole.log,因为lager的默认日志handle配置就是

-define(DEFAULT_HANDLER_CONF,
        [{lager_console_backend, [{level, info}]},
         {lager_file_backend,
          [{file, "log/error.log"}, {level, error},
           {size, 10485760}, {date, "$D0"}, {count, 5}]
         },
         {lager_file_backend,
          [{file, "log/console.log"}, {level, info},
           {size, 10485760}, {date, "$D0"}, {count, 5}]
         }
        ]).

lager提供的日志等级定义在

-define(LEVELS,
    [debug, info, notice, warning, error, critical, alert, emergency, none]).

列表中的值都可以使用,lager:LEVEL进行调用

配置

Lager配置主要通过配置Lager的application环境变量来实现,也就是他的一部分基础配置来自于lager.app,也就是lager.app.src中

{env, [
            %% Note: application:start(lager) overwrites previously defined environment variables
            %%       thus declaration of default handlers is done at lager_app.erl

            %% What colors to use with what log levels
            {colored, false},
            {colors, [
              {debug,     "\e[0;38m" },
              {info,      "\e[1;37m" },
              {notice,    "\e[1;36m" },
              {warning,   "\e[1;33m" },
              {error,     "\e[1;31m" },
              {critical,  "\e[1;35m" },
              {alert,     "\e[1;44m" },
              {emergency, "\e[1;41m" }

            ]},

            %% Whether to write a crash log, and where. False means no crash logger.
            {crash_log, "log/crash.log"},
            %% Maximum size in bytes of events in the crash log - defaults to 65536
            {crash_log_msg_size, 65536},
            %% Maximum size of the crash log in bytes, before its rotated, set
            %% to 0 to disable rotation - default is 0
            {crash_log_size, 10485760},
            %% What time to rotate the crash log - default is no time
            %% rotation. See the README for a description of this format.
            {crash_log_date, "$D0"},
            %% Number of rotated crash logs to keep, 0 means keep only the
            %% current one - default is 0
            {crash_log_count, 5},
            %% Crash Log Rotator Module - default is lager_rotator_default
            {crash_log_rotator, lager_rotator_default},
            %% Whether to redirect error_logger messages into the default lager_event sink - defaults to true
            {error_logger_redirect, true},
            %% How many messages per second to allow from error_logger before we start dropping them
            {error_logger_hwm, 50},
            %% How big the gen_event mailbox can get before it is
            %% switched into sync mode.  This value only applies to
            %% the default sink; extra sinks can supply their own.
            {async_threshold, 20},
            %% Switch back to async mode, when gen_event mailbox size
            %% decrease from `async_threshold' to async_threshold -
            %% async_threshold_window. This value only applies to the
            %% default sink; extra sinks can supply their own.
            {async_threshold_window, 5}
        ]},

这部分的内容都是可以通过beam启动的时候通过设置配置文件来覆盖,类似于 erl -config app.config,而app.config中内容也就是对lager的env进行扩展,一份简单的内容如下:

{lager, [
  {log_root, "/var/log/hello"},
  {handlers, [
    {lager_console_backend, [{level, info}]},
    {lager_file_backend, [{file, "error.log"}, {level, error}]},
    {lager_file_backend, [{file, "console.log"}, {level, info}]}
  ]}
]}.

通过log_root指定了日志文件所在的目录,如果是相对路径就是相对的Lager启动的时候pwd()函数返回的路径
handles就是日志处理模块指定,也是配置的核心内容,上述配置中启用了1个lager_console_backend接收器用来将日志输出到命令行中,两个将日志输出到文件中的lager_file_backend分别将error级别以上的日志和info级别以上的日志分别写入到"error.log"和"console.log"中

日志扩展

上一步中讲到的日志都是基于内建的lager_event事件来进行的配置,因为类似lager:info这种调用最终调用的就是lager:d

### 集成JSON至STM32F407项目 为了在STM32F407项目中成功集成并配置JSON,需遵循一系列具体操作来确保能够被正确编译和链接。以下是针对此过程的详细介绍。 #### 准备工作 首先确认所使用的开发环境已经按照标准流程完成初始化设置[^1]。这包括但不限于安装必要的工具链(如Keil MDK)、创建新的工程项目,并导入基础外设驱动程序包等前置条件。 #### JSON的选择与下载 对于嵌入式系统而言,推荐采用轻量级且易于移植的`Jansson`作为JSON解析器。可以从官方网站获取最新版本的源代码压缩包,解压后得到包含`.c`和`.h`在内的多个文件夹结构。 #### 文件结构调整 将下载下来的`Jansson`中的核心组件——即`src`目录下的所有C语言源文件(`*.c`)及其对应的头文件(`*.h`)复制粘贴到当前项目的指定位置,比如新建名为`jsonlib`的子文件夹内以便管理和维护[^3]。 #### 修改工程设置 - **添加路径**:前往IDE内的“Options for Target -> C/C++ -> Include Paths”,新增一条记录指向刚才放置第三方依赖项的位置; - **引入目标**:同样是在上述界面里,“Define”区域输入宏定义`WITH_JANSSON=1`用于告知预处理器开启特定功能支持; - **注册源码**:切换到“Source Group 1”,通过右键菜单选项把先前拷贝过来的相关实现单元加入构建序列当中去。 #### 调整内存分配策略 考虑到嵌入式平台资源有限的特点,在实际应用过程中可能会遇到因动态申请空间失败而导致的功能异常现象。因此建议适当增大默认堆尺寸以满足更多复杂场景的需求: ```assembly Heap_Size EQU 0xA00 ; Adjusted heap size to accommodate larger data structures and operations. ``` 以上修改位于启动脚本`startup_stm32f4xx.s`之中,请参照具体情况调整数值大小直至稳定运行为止。 #### 测试验证 编写简单的测试案例用来检验整个集成工作的有效性是非常重要的一步。下面给出了一段示范性的代码片段展示了如何利用刚刚接入的API接口来进行基本的数据交换活动。 ```c #include "jansson.h" int main(void){ json_t *root; const char* output; /* 创建一个新的对象 */ root = json_object(); /* 添加成员 */ json_object_set_new(root, "name", json_string("world")); json_object_set_new(root, "number", json_integer(42)); /* 序列化为字符串形式输出 */ output = json_dumps(root, 0); printf("%s\n",output); /* 清理释放占用的空间 */ json_decref(root); } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值