当前位置: 首页 > news >正文

QNX系统动态配置动态库.so文件日志打印级别的方法

背景

通常我们会在量产的产品上,配置软件仅打印少量日志,以提升产品的运行性能。同时我们要考虑预留方法让软件能够拥有能力可以在烧录版本后能够通过修改默写配置,打印更多日志。因为量产后的软件通常开启熔断与加密,不能够轻松替换动态库,或者镜像文件。

分析

一种比较简单的方法是,通过读取文件来重新配置。一般我们尽可能要让动态库独立配置,而不是让可执行程序从main()函数入口读取配置。这样动态库对可执行程序的依赖比较大,同时如果是乙方只提供.so,可执行程序入口由甲方提供,那么这样实现的方法就更麻烦了。为了方便各个动态库单独配置,我们可以利用 C语言的__attribute__ 特性来实现。参考实现方案如下。

方案

 my_log.c 参考代码如下:

#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
#include <stdio.h>
#include <stdarg.h>#define INPUT_LOG_LEVEL_FILE_PATH        "/mnt/data/log-level"char my_printf_str[1024];
static int gLogLevel = MY_LOG_LEVEL_INFO;int my_log_print(int level, const char* fmt, ...){if (level > gLogLevel) return 0;va_list args;int val;va_start( args, fmt );if(Callback_register.print != NULL) {vsprintf(BTF_printf_str, fmt, args);Callback_register.print("%d ", pthread_self());val = Callback_register.print(my_printf_str);}else {printf("%d-", pthread_self());val = vprintf(fmt, args );}va_end(args);return val;
}int init_log_level(){char out = '0';FILE* fLogLevel = fopen(INPUT_LOG_LEVEL_FILE_PATH, "rb");do {if (NULL == fLogLevel) {printf("heyang: success log level file does not exist %s. Exiting.\n", INPUT_LOG_LEVEL_FILE_PATH);break;}if ((fread(&out, 1, 1, fLogLevel)) != 0) {rintf("read log level from file: %c\n", out);}fclose(fLogLevel);} while(0);int ret = atoi(&out);return ret > 0 ? ret : gLogLevel;
}static int __attribute__((constructor(101))) _________very_long_function_name__________log_init() {gLogLevel = init_log_level();return 0;
}

my_log.h定义如下:

#define MY_LOG_LEVEL_FATAL 0
#define MY_LOG_LEVEL_ERROR 1
#define MY_LOG_LEVEL_WARNING 2
#define MY_LOG_LEVEL_INFO 3
#define MY_LOG_LEVEL_DEBUG 4
#define MY_LOG_LEVEL_VERBOSE 5int my_log_print(int level, const char* fmt, ...);

这样就能能够通过读取 /mnt/data/log-level文件节写的等级来动态配置了。

注意,加载这个.so的可执行程序需要配置好读取文件的sepolicy权限(如果需要)

测试

在代码中使用:

   my_log_print(MY_LOG_LEVEL_VERBOSE, "BTF: heyang print verbose level\n");my_log_print(MY_LOG_LEVEL_DEBUG, "BTF: heyang print debug level\n");my_log_print(MY_LOG_LEVEL_INFO, "BTF: heyang print info level\n");my_log_print(MY_LOG_LEVEL_WARNING, "BTF: heyang print warning level\n");my_log_print(MY_LOG_LEVEL_ERROR, "BTF: heyang print error level\n");my_log_print(MY_LOG_LEVEL_FATAL, "BTF: heyang print fatal level\n");

在文件节点写入配置

touch /mnt/data/log-levelecho 3 > /mnt/data/log-levelreset

重启后运行可执行文件,在终端查看打印发现,so的 __attribute__((constructor(101))) 代码成功执行。调用相关接口能够打印对应等级的日志。

再换个配置试试:

echo 5 > /mnt/data/log-levelreset

然后测试能够打印全部日志:

其他

 以上仅是通过printf()演示。实际使用,建议更换为slog或者其他的高级日志系统。

相关文章:

  • 7.13 GitHub Sentinel全链路测试实战:自动化框架+零误差传输,QPS提升6倍!
  • 进行物联网安全PoC时的注意事项
  • 深度探索:DeepSeek赋能WPS图表绘制
  • 可视化性能分析工具火焰图
  • Astro canvas大屏从iotDA上抽取设备影子的参数的详细操作实施路径
  • 【Java并发】【原子类】适合初学体质的原子类入门
  • 树状数组底层逻辑探讨 / 模版代码-P3374-P3368
  • 精益数据分析(29/126):深入剖析电子商务商业模式
  • Spring和Spring Boot集成MyBatis的完整对比示例,包含从项目创建到测试的全流程代码
  • Windows 安装 MongoDB 教程
  • 【OpenCV】第二章——图像处理基础
  • 计算机学报 2024年 区块链论文 录用汇总 附pdf下载
  • WPS中论文如何加参考文献
  • 树状数组详解
  • 在Linux虚拟机下使用vscode,#include无法跳转问题
  • ZYNQ笔记(十四):基于 BRAM 的 PS、PL 数据交互
  • 【Token系列】01 | Token不是词:GPT如何切分语言的最小单元
  • 云服务器 —— 公有 IP 与 私有 IP
  • 【计算机视觉】CV项目实战- 深度解析TorchVision_Maskrcnn:基于PyTorch的实例分割实战指南
  • 深入解析Spring Boot配置处理器:机制、架构与实践
  • 上海市市管干部任职前公示:赵亮拟为地区区长人选
  • 价格周报|猪价继续回暖:二次育肥热度仍存,对猪价仍有一定支撑
  • 远程控制、窃密、挖矿!我国境内捕获“银狐”木马病毒变种
  • 特朗普签署行政命令推动深海采矿,被指无视国际规则,引发环境担忧
  • 最高法:“盗链”属于信息网络传播行为,构成侵犯著作权罪
  • 特朗普支持率降至新低:宣布关税后骤降,选民最不满经济表现