惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

雷峰网
雷峰网
GbyAI
GbyAI
Stack Overflow Blog
Stack Overflow Blog
Apple Machine Learning Research
Apple Machine Learning Research
The Cloudflare Blog
WordPress大学
WordPress大学
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
F
Fortinet All Blogs
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
Microsoft Azure Blog
Microsoft Azure Blog
酷 壳 – CoolShell
酷 壳 – CoolShell
博客园 - 聂微东
L
LangChain Blog
云风的 BLOG
云风的 BLOG
Jina AI
Jina AI
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
I
InfoQ
大猫的无限游戏
大猫的无限游戏
MyScale Blog
MyScale Blog
人人都是产品经理
人人都是产品经理
小众软件
小众软件
量子位
The GitHub Blog
The GitHub Blog
博客园 - 【当耐特】

C

C 语言快速通关教程 2026(共 96 集) - V2EX 各位大佬, C 語言該怎麼練習啊 分享一个代码优化导致的死循环 人再笨还能写不出内存安全的 C? 想念 C C11 的 _Generic,现实当中用得多不多?(尤其是公司项目) 坑爹的 GBK:大家都应该去用 UTF-8 分享一个用 AI 学习 C 语言的例子 一个简单的 C 程序,但是不明白区别在哪里 我这段 C 代码可以在编译时候输出结构体的大小,你们还有什么好点子, show me the code! 这段话是否正确?「取余这个运算,只有 Python 是对的。当初 C 这个老师教错了,那么一大票学生也就只敢跟着老师错。只有 Python 敢于站出来坚持正确答案。」 C 中可变参数如何直接传递到 printf() C 的内存打印实现 函数能否实现透传不定长度参数,最终由 printf 打印 请大佬帮忙修改一份 elf 文件里的数值 Linux 上 C 的程序遇到个异常退出问题,局部变量大小有限制?? C 语言新手求助:如何在 vscode 中使用第三方库? 将资源嵌入到可执行文件中并保持目录结构 一个简单实用的 C 工程示例, 附简洁的 Makefile 关于 C 语言的相关问题 轮子更新: C/C++ 跨平台小工具库 为什么下列程序进行的是无符号乘法? 用 riscv64- Linux -gnu-gcc 编译的 c 文件为啥能在 x8664 下运行? char *s = "0123"和 char s[] = "0123"的区别 有人能完整地解释一下 int (*daytab) [13]和 int *daytab[13]吗 在 c 语言中, int a;是 declaration 还是 definition 一个简单(奇怪)的 C 语言问题 c 语言中打印指针的值打印的是 OS 分配的虚拟地址的值吗?要怎么知道 OS 给这个 c 程序进程分配的虚拟地址的大小呢? gcc 是怎么找到 system 函数的定义(实现)的? 用 C 实现轻量级表达式完成策略定制化和模板内容生成
百变开源 C 语言库日志模块
monkeyNik · 2023-09-12 · via C

本文向大家介绍一个名为Melon的开源 C 语言库的日志模块。

简述 Melon

Melon 是一个包含了开发中常用的各类组件的开源 C 语言库,支持 Linux 、MacOS 、Windows 系统,可用于服务器开发亦可用于嵌入式开发,无第三方软件依赖,安装简单,开箱即用,中英文文档配套齐全。

日志模块

日志是 Melon 库提供的通用组建之一,在介绍其特性前,我们先来看一下它的简单使用示例。

#include "mln_log.h"

int main(int argc, char *argv[])
{
    mln_log(debug, "This will be outputted to stderr\n");
    mln_log_init(NULL);
    mln_log(debug, "This will be outputted to stderr and log file\n");
    return 0;
}

可以看到,使用与我们常用的printffprintf很相似。

同时,从这个例子中也可以看到这个日志模块允许在未初始化情况下使用。在未初始化时,这些日志都将被输出至stderr中。

当然,我们也可以使用mln_log_init对日志模块进行初始化。初始化后将获得两种能力:

  1. 日志会跟据不同等级显示不同的颜色
  2. 日志内容既会被输出到 stderr ,也会被输出到 Melon 配置中指定的日志文件中(关于配置,请参见官方手册)。

进阶

显然,我们的日志不仅仅可以做这些事情。

下一步我们将讨论如何将日志内容做自定义处理,我们将介绍日志回调函数。

这里涉及到两个日志模块的函数:

  • mln_log_logger_get 获取当前日志处理函数
  • mln_log_logger_set 设置日志处理函数为某个指定的函数

我们看一下简单的例子,我们对上面的例子进行一顿改造:

#include <stdio.h>
#include "mln_log.h"

mln_logger_t old = NULL;

static void mylogger(mln_log_t *log, mln_log_level_t level, const char *file,
                     const char *func, int line, char *fmt, va_list args)
{
    printf("%s:%s:%d: %s\n", file, func, line, fmt);
    if (old != NULL)
        old(log, level, file, func, line, fmt, args);
}

int main(int argc, char *argv[])
{
    mln_log(debug, "This will be outputted to stderr\n");
    mln_log_init(NULL);
  
    old = mln_log_logger_get();
    mln_log_logger_set(mylogger);
  
    mln_log(debug, "This will be outputted to stderr and log file\n");
    return 0;
}

我们增加了一个自己的日志处理函数名为mylogger,它将截获日志的内容及其关联信息,使用printf将这些信息输出到标准输出(stdout)中。然后再使用原有的日志处理函数将日志输出到终端的stderr和日志文件中。

这样,我们就可以随意地对日志内容进行处理了。

结语

Melon 的日志模块允许开发者对其进行任意扩展来满足自己的需求。

另外,要补充一点,这个mln_log是允许多线程使用的。并且对于x86 架构,在不调用mln_log_init对日志进行初始化的情况下,这个函数就是多线程可用的。

感谢阅读!