首页 > 其他分享 >再谈日志系统

再谈日志系统

时间:2024-12-22 11:30:45浏览次数:5  
标签:crash g2 打印 系统 再谈 API 模块 日志

1. 面相抽象:不直接使用 printf / std::cout

直接使用 printf 或 std::cout 的弊端在于:不够规模化,修改起来麻烦。

例如,除了想往控制台打印,还希望往文件打印; 想确保每一处打印都有 flush; 想通过 CMake Option, 用一个简单的开关来控制日志的开启和关闭。

使用专门的日志库提供的 宏/函数, 而不是直接使用 printf / std::cout, 是基本的要求。

而 Debug/Info/Warning/Error 等级的划分, 算是日志库的基本功能, 这里不探讨了。

2. 有区分度的打印:专属的 tag

在多人协作、多 SDK 集成的场景下, 所有 log 都输出到控制台时, 怎样区分不同模块的日志? 每个模块应当有自己独特的 tag, 也就是显示在日志打印的每一行的最开头部分的, 如:

[D] module1: xxxxx
[D] module2: xxxxx

这里的 module1module2 就是 tag。 当程序出现 crash,根据 crash 前最后一次打印的 tag, 来判定职责在哪个模块(SDK)中,对应的开发负责人负责排查(也就是甩锅、背锅)。

3. 自证清白:API函数的进入-离开 log

当调用子模块时,子模块的某个 API 函数是否运行完毕, 决定了谁来背锅。例如有 f 和 g 两个模块, f 负责调用 g 模块的 g1(), g2() 两个 API 函数:

f1()
  - g1()
  - g2()
f2()

当最终的日志打印中,看到了 g2( ) 内的日志打印、没看到 f2() 的日志打印, 并且 f2() 代码中确实写了日志打印, 这时候如何裁定职责呢?

由于我负责 g 模块, 无法主导 f 模块的排查, 只能在 g1(), g2() 函数中自证清白: 在 API 函数执行的最开头、最末尾, 增加日志打印:

class AutoLogger
{
public:
    AutoLogger(const char* name):
        m_name(name)
    {
        XX_LOGD("%s begin()", name);
    }
    ~AutoLogger()
    {
        XX_LOGD("%s end()", name);
    }
private:
    std::string m_name;
};

void g2()
{
    AutoLogger logger(__FUNCTION__);

    ... // 原有代码
    // XX_LOGD("g2() end"); // 原本有这句,但是无法保证是 g2() 最后执行的内容,因为可能有类实例的析构函数在这句之后执行
}

为了进一步简化代码,以及避免 logger 命名冲突,改为宏定义:

#define API_ENTER_LEAVE_LOG AutoLogger logger##__LINE__(__FUNCTION__)

这样一来,看到的日志一定是这两种之一:

// g 模块没crash
[D] module_g: g2() begin()
[D] module_g: .....
[D] module_g: g2() end()
crash info
// crash 在 g 模块内
[D] module_g: g2() begin()
[D] module_g: .....
crash info

4. 保存现场: 多重输出

一个合格的日志库, 应当能让调用者同时往控制台、文件写入日志,并且支持用户往其他地方写入日志,例如 Android logcat, 或 QNX 系统的 slog。

那么作为使用者,就需要这样写:


static void custom_logger(char* line, FILE* fp)
{
    char buf[1024];
    sprintf(buf, "%s\n", line);
    
    fprintf(stdout, "%s", buf);
    fflush(stdout);

    if (!fp && fp!=stdout)
    {
        fprintf(fp, "%s", buf);
        fflush(fp);
    }
#ifdef ENABLE_SLOG
    {
        slog2(DEBUG1, "%s\n", buf);
    }
#endif
}

static FILE* s_file = NULL;
void g_init()
{
    API_ENTER_LEAVE_LOG();

    if (s_file) 
        fclose(s_file);
    s_file = fopen("xxx.log", "wt");
    xx_log_register_logger(custom_logger);
}

void g_run()
{
    API_ENTER_LEAVE_LOG();
     ...
}

5. 有效性探讨

个人认为上述 log 内容有一定正向作用,但是只能起到有限作用。 当 f 模块遇到了 "Malloc failed: xxxx" 的报错时,那看起来应该是 glibc 的作者们写 bug 了,我们应当找 glibc 的作者去修改 bug 吗?有这种可能,但是也可能是调用者出了问题。

标签:crash,g2,打印,系统,再谈,API,模块,日志
From: https://www.cnblogs.com/zjutzz/p/18621944

相关文章

  • docker desktop 需要使用ubantu 子系统,需要在应用商店下载,window打开应用商店无法使用
     解决方案:更新证书。1、以管理员身份打开PowerShell。2、从WindowsUpdate下载根证书更新文件,本示例中文件存储路径c:\roots.sst。certutil-generateSSTFromWUC:\roots.sst3、批量导入证书到受信任根证书。$sstStore=(Get-ChildItem-PathC:\roots.sst)$sstSt......
  • windows 启动时弹出【选择操作系统】的解决办法
    原因因为台式机重装,原来的旧硬盘没拔,插上新硬盘后电脑有两个硬盘,开机时识别到有两个系统所以出现上述情况,新硬盘的分区方式中,引导分区记录了这个双系统信息解决办法win+R进入运行界面输入MSConfig,点击回车,进入启动设置上点击“引导”,可以看到有两个启动盘,把多余那个......
  • 基于PHP的公交查询系统
    计算机毕业设计案例Java毕业设计案例ASP.NET毕业设计案例PHP毕业设计案例微信小程序毕业设计案例基于Java后台的HTML5个人博客App的设计与实现基于ASP.NET的酒店管理系统基于PHP的学前教育平台–2024计算机毕业设计家校微信小程序的设计和开发基于Java的家居装潢销售与服......
  • 基于微信小程序的乡村旅游系统
      博主介绍:java高级开发,从事互联网行业六年,熟悉各种主流语言,精通java、python、php、爬虫、web开发,已经做了多年的设计程序开发,开发过上千套设计程序,没有什么华丽的语言,只有实实在在的写点程序。......
  • 基于Java的动态交通信息服务系统设计与实现
    计算机毕业设计案例Java毕业设计案例ASP.NET毕业设计案例PHP毕业设计案例微信小程序毕业设计案例基于Java的村镇社区数据管理系统基于ASPNETMVC的网站式音乐播放基于php的微信小程序在线考试系统基于Java的“free美妆榜”微信小程序【12/19/02】基于Java后台的口罩查询......
  • 医药垃圾分类管理系统|Java|SSM|JSP|
                           【技术栈】1⃣️:架构:B/S、MVC2⃣️:系统环境:Windowsh/Mac3⃣️:开发环境:IDEA、JDK1.8、Maven、Mysql5.7+4⃣️:技术栈:Java、Mysql、SSM、Mybatis-Plus、JSP、jquery,html5⃣️数据库可视化工具:navicat6⃣️服务......
  • 网上球鞋竞拍系统|Java|SSM|VUE| 前后端分离
                  【技术栈】1⃣️:架构:B/S、MVC2⃣️:系统环境:Windowsh/Mac3⃣️:开发环境:IDEA、JDK1.8、Maven、Mysql5.7+4⃣️:技术栈:Java、Mysql、SSM、Mybatis-Plus、VUE、jquery,html5⃣️数据库可视化工具:navicat6⃣️服务器:SpringBoot自带apacheto......
  • 推荐一个开源大模型呼叫中心系统FreeAICC
    推荐一个开源大模型呼叫中心系统FreeAICC在当今这个快节奏、高效率的商业环境中,企业与客户之间的有效沟通成为了决定业务成败的关键因素之一。为了帮助企业精准触达目标客户,提升服务效率与质量,我们找到了这个开源大模型呼叫中心系统——一款集智能外呼、呼入机器人、人工坐席......
  • 【Java毕业设计】基于SpringBoot+Vue的自习室预订系统
    源码获取:https://download.csdn.net/download/u011832806/89432119基于SpringBoot+Vue的自习室预订系统开发语言:Java数据库:MySQL技术:SpringBoot+MyBatis+Vue.js工具:IDEA/Ecilpse、Navicat、Maven系统演示视频:链接:https://pan.baidu.com/s/1Z_0AbOrbgL0Hpn_E0f0ACA?pwd=......
  • 【Java项目】基于SpringBoot+Vue的自习室预订系统
    源码获取:https://download.csdn.net/download/u011832806/89432119基于SpringBoot+Vue的自习室预订系统开发语言:Java数据库:MySQL技术:SpringBoot+MyBatis+Vue.js工具:IDEA/Ecilpse、Navicat、Maven系统演示视频:链接:https://pan.baidu.com/s/1Z_0AbOrbgL0Hpn_E0f0ACA?pwd=......