V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
爱意满满的作品展示区。
Akagi201
V2EX  ›  分享创造

自己写了个 header-only 轻量级 C 语言日志库 lw-clogger, 适用于嵌入式环境, 分享给需要的朋友.

  •  
  •   Akagi201 ·
    Akagi201 · 2014-09-02 00:52:41 +08:00 · 3500 次点击
    这是一个创建于 3737 天前的主题,其中的信息可能已经有所发展或是发生改变。
    类似的轮子挺多的, 看了一下感觉没必要太复杂, thread-safe还是依赖于线程库, 或者保险情况下自己控制一下最好了, 就算用printf在pthread下也是线程不安全的.

    学习了一下别的开源代码, 还有结合了一些自己使用宏的经验, 分享给有需要的朋友.

    ## 项目地址
    * <https://github.com/Akagi201/lw-clogger>;
    13 条回复    2014-09-03 06:31:35 +08:00
    dbbbit
        1
    dbbbit  
       2014-09-02 07:09:51 +08:00
    吐槽下这个函数的命名

    clog_debug(l, LOG_INFO, "LOG_INFO");
    clog_debug(l, LOG_NOTICE, "LOG_NOTICE");
    clog_debug(l, LOG_DEBUG, "LOG_DEBUG");
    auser
        2
    auser  
       2014-09-02 07:20:43 +08:00 via iPad
    时间颗粒度不够,推荐gettimeofday
    每次都调用write,系统调用开销影响多大?
    另外,为什么printf在多线程下不是安全的?

    我只接触服务端,如果嵌入式环境下较为特殊,当我没说。
    soli
        3
    soli  
       2014-09-02 10:30:13 +08:00
    clog_file 和 _clog_debug 并不是太复杂,可以合并到一个函数里,减少一次函数调用。

    接口可以定义成:

    ```
    void clog_write(clogger *l, int level, const char *fmt, ...);
    ```

    然后,用宏定义把 file、func、line 加进去。这样就可以在 debug 以上级别的日志里省掉这些内容。

    比如:

    ```
    #define CLOG_ERRO(log, fmt, args...) clog_write(log, CLOG_LEVEL_ERRO, fmt, ##args)
    #define CLOG_WARN(log, fmt, args...) clog_write(log, CLOG_LEVEL_WARN, fmt, ##args)
    #define CLOG_INFO(log, fmt, args...) clog_write(log, CLOG_LEVEL_INFO, fmt, ##args)
    #define CLOG_DEBUG(log, fmt, args...) clog_write(log, CLOG_LEVEL_DEBUG, __FILE__":"__FUNCTION__"():"__LINE__" "fmt, ##args)
    ```

    仅供参考。
    soli
        4
    soli  
       2014-09-02 10:32:45 +08:00
    呃,说好的 Markdown 呢。。。
    soli
        5
    soli  
       2014-09-02 10:40:47 +08:00
    另外,建议把日志级别、PID 等写成相同的长度,这样打印出来的日志漂亮一些。


    比如(我喜欢把时间放到最前面):

    ```
    2014-09-02 00:28:10,INFO,[00658] test.c:main():19: LOG_INFO
    2014-09-02 00:28:10,NOTE,[13658] test.c:main():20: LOG_NOTICE
    2014-09-02 00:28:10,WARN,[13650] test.c:main():24: Foo[Information
    2014-09-02 00:28:10,ERRO,[03658] test.c:main():24: Foo[Information
    ```
    semicircle21
        6
    semicircle21  
       2014-09-02 11:36:24 +08:00
    每次都 write, 这样恐怕不行, 至少不是常规手段.
    并不是性能问题, 也不是线程安全, 而是:
    可靠的 Log() 是不会阻塞的, 现在直接 write 操作, 谁知道底层驱动会干啥, 用个1s 去整理下 Flash 碎片啥的, 谁都说不清.

    当然, 如果就是要用来 Debug,有特殊需求, 那在 write 后面加个 flush 也不为过.
    Akagi201
        7
    Akagi201  
    OP
       2014-09-02 14:40:45 +08:00
    @semicircle21 我用write而不用C库是为了避免使用带缓存的函数, 在嵌入式里应该更需要, 当然是个人看法.
    Akagi201
        8
    Akagi201  
    OP
       2014-09-02 14:41:53 +08:00
    @auser 感谢你的建议, 我后面会考虑改良. 关于线程安全要看具体的C库和线程库实现, 我觉得要是想确定还是要自己控制比较保险. 一个参考链接 http://stackoverflow.com/questions/467938/stdout-thread-safe-in-c-on-linux
    Akagi201
        9
    Akagi201  
    OP
       2014-09-02 14:43:02 +08:00
    @dbbbit 接口我的考虑是只用一个函数, 不行用clog_err, clog_warn....这样, 容易忘, 而是用跟syslog一样的log等级, 当然是个人想法而已
    Akagi201
        10
    Akagi201  
    OP
       2014-09-02 14:44:49 +08:00
    @soli 好吧, 这点dirty代码被你发现了, 我写着写着也觉得合并会比较好, 我有空更新下. 排版我后面考虑下加点对齐代码, 谢谢, 很好的建议
    semicircle21
        11
    semicircle21  
       2014-09-02 16:21:24 +08:00
    @Akagi201 "C库"和"带缓存的函数"是指 printf 吗? 可能我描述的不太清楚,
    重新描述一下: 用 write 没问题. 问题在于直接调用了:
    _clog_debug -> clog_file -> write
    这样, 调用 _clog_debug 时可能由于 write 而阻塞, 这样会影响调用了_clog_debug的thread的行为, 不时的阻塞一下, 之类.
    Akagi201
        12
    Akagi201  
    OP
       2014-09-02 17:21:48 +08:00
    @semicircle21 理解你的意思了, 默认的write是不是阻塞不确定, 可以用fcntl设置为非阻塞, 就可以了.
    semicircle21
        13
    semicircle21  
       2014-09-03 06:31:35 +08:00
    @Akagi201 默认的是阻塞的, 如果用了 NON_BLOCK, 那write 的行为是会彻底变掉的, 也需要做相应的处理, 比如建个 buffer把一次没写完的部分先缓存住等等. 另外, 对于嵌入式, 还需要确认驱动是不是靠谱, 是不是真的按 NON_BLOCK执行了...
    我又想了下, 如果不是对可靠性和实时性要求特别高的话, 这样估计也没什么问题. 不用在意这些细节..
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1174 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 24ms · UTC 23:41 · PVG 07:41 · LAX 15:41 · JFK 18:41
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.