【科普】关于C 语言日志系统实战:如何同时输出到终端和文件?

1.概述

c语言没有现成的日志库,如果要记录日志,需要自己封装一个日志库。如果要实现日志级别和参数打印,还是比较麻烦的,正好在github找到了一个c语言开源日志库,可以实现日志级别打印,参数打印,而且还会记录日期和行号,最重要的是代码非常少,只有100多行,可以直接包含在我们自己的工程代码中,不需要任何依赖。

2.源码地址

GitCode - 全球开发者的开源社区,开源代码托管平台

3.使用介绍

3.1直接把工程目录下的log.c和log.h下载下来,包含到工程代码中即可,没有其他依赖。

3.2日志级别由低到高,分别为 LOG_TRACE、LOG_DEBUG、LOG_INFO、LOG_WARN、LOG_ERROR、LOG_FATAL

3.3如果设置日志级别为LOG_TRACE,则所有级别日志都会打印,如果设置日志级别为LOG_WARN,则只会打印LOG_WARN以及更高级别(即LOG_ERROR和LOG_FATAL)的日志

4.测试代码

log.c

#include "log.h"
#include <stdio.h>int main() {FILE *fp = fopen("log.txt", "a+");if(fp == NULL){printf("create log file failed.\n");return -1;}//设置日志级别(在终端打印)log_set_level(LOG_TRACE);//设置日志级别(在文件中打印)log_add_fp(fp, LOG_INFO);log_trace("start trace.");log_debug("start debug.");log_info("start info.");log_warn("start warn.");log_error("start error.");log_fatal("start fatal");// 支持参数打印log_info("number is %d, string is %s", 10010, "helloword");fclose(fp);
}

log.h

/*** Copyright (c) 2020 rxi** This library is free software; you can redistribute it and/or modify it* under the terms of the MIT license. See `log.c` for details.*/#ifndef LOG_H
#define LOG_H#include <stdio.h>
#include <stdarg.h>
#include <stdbool.h>
#include <time.h>#define LOG_VERSION "0.1.0"typedef struct {va_list ap;const char *fmt;const char *file;struct tm *time;void *udata;int line;int level;
} log_Event;typedef void (*log_LogFn)(log_Event *ev);
typedef void (*log_LockFn)(bool lock, void *udata);enum { LOG_TRACE, LOG_DEBUG, LOG_INFO, LOG_WARN, LOG_ERROR, LOG_FATAL };#define log_trace(...) log_log(LOG_TRACE, __FILE__, __LINE__, __VA_ARGS__)
#define log_debug(...) log_log(LOG_DEBUG, __FILE__, __LINE__, __VA_ARGS__)
#define log_info(...)  log_log(LOG_INFO,  __FILE__, __LINE__, __VA_ARGS__)
#define log_warn(...)  log_log(LOG_WARN,  __FILE__, __LINE__, __VA_ARGS__)
#define log_error(...) log_log(LOG_ERROR, __FILE__, __LINE__, __VA_ARGS__)
#define log_fatal(...) log_log(LOG_FATAL, __FILE__, __LINE__, __VA_ARGS__)const char* log_level_string(int level);
void log_set_lock(log_LockFn fn, void *udata);
void log_set_level(int level);
void log_set_quiet(bool enable);
int log_add_callback(log_LogFn fn, void *udata, int level);
int log_add_fp(FILE *fp, int level);void log_log(int level, const char *file, int line, const char *fmt, ...);#endif

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/diannao/90341.shtml
繁体地址,请注明出处:http://hk.pswp.cn/diannao/90341.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

2025,数字人借直播场景迈过“真假线”丨数智化观察

作者 | 曾响铃文 | 响铃说一夜带货超5500万GMV、观看人次1300万&#xff0c;罗永浩数字人在百度电商的直播首秀正在掀起新的行业浪潮——2025&#xff0c;数字人直播带货成功出圈&#xff0c;加速进入大众视野&#xff0c;被更多的消费者所认可。成就这场热潮的关键点之一&…

HTML表格导出为Excel文件的实现方案

1、前端javascript可通过mime类型、blob对象或专业库&#xff08;如sheetjs&#xff09;实现html表格导出excel&#xff0c;适用于中小型数据量&#xff1b;2、服务器端方案利用后端语言&#xff08;如python的openpyxl、java的apache poi&#xff09;处理复杂报表和大数据&…

企业微信iPad协议端强制拉群漏洞深度分析

正常一次最多邀请40人进群 超过40人的拉群&#xff0c;会变成邀请&#xff0c;需要对方同意 新版本修复了漏洞&#xff0c;但还是可以用老版本进行强制拉群 虽然官方也做了版本过低的限制&#xff0c;但还是有办法绕过 要么修改版本号或者登录几天新版本&#xff0c;之后就可以…

Python编译器(Pycharm Jupyter)

Pycharm下载不过多赘述pycharm导入anaconda创建的python环境选择想要的环境 Jupyter Jupyter 是一个开源的交互式计算环境&#xff0c;能够让用户将代码、文本&#xff08;包括 Markdown&#xff09;、可视化结果等内容整合在一个文档中&#xff0c;非常适合进行数据分析、科学…

漏洞修复与Fiddler抓包工具的使用

漏洞描述 1. 短信轰炸漏洞 Type:存在三个不同的值。Login是登录处,register是注册账号处的短信验证码获取值,还有一个update值。未注册的用户也可以进行发送短信。 2. 手机号绕过,修改密码漏洞(逻辑漏洞) 目前注册使用手机号与忘记密码的手机号验证测试都可以绕过, …

对象存储-OSS

目录 对象存储背景 阿里云OSS 对象存储背景 单节点环境下&#xff0c;文件往往存储在tomcat服务器内&#xff0c;随着业务需求的增多&#xff0c;单节点已不能满足需求&#xff0c;项目架构需要扩展到多节点&#xff08;见下图&#xff09;&#xff0c;此时文…

C语言函数的声明

1定义&#xff1a;在C语言中&#xff0c;函数是一段具有特定功能的独立代码块&#xff0c;它可以接收输入参数、执行相关操作并返回结果。2为什么需要函数&#xff08;1&#xff09;代码复用&#xff1a;避免重复编写相同功能的代码&#xff0c; &#xff08;2&#xff09;模块…

AI人工智能名片小程序源码系统,名片小程序+分销商城+AI客服,包含完整搭建教程

智能名片核心功能AI人工智能名片小程序的核心功能设计旨在彻底改变传统商务交流方式&#xff0c;为用户提供前所未有的智能化体验。个性化名片展示是系统的基础功能&#xff0c;用户可以通过丰富的模板库和自定义设计工具&#xff0c;创建独具特色的电子名片。系统提供多种预设…

React 教程:井字棋游戏

React 教程&#xff1a;井字棋游戏 使用 React 实现一个交互式的井字棋游戏&#xff0c;并配上好看的样式 // 导入必要的CSS样式和React库 import "./App.css"; import { useState } from "react";// Square组件 - 表示棋盘上的一个格子 function Square({…

React源码2 React中的工厂函数:createRoot()

#React V18.2 源码前置基础知识&#xff1a;工厂函数工厂函数是一种设计模式&#xff0c;用于动态创建对象或函数实例。其核心思想是通过封装对象创建的细节&#xff0c;提供统一的接口&#xff0c;从而增强代码的灵活性和可维护性&#xff0c;有一些核心作用&#xff1a;解耦创…

《UE5_C++多人TPS完整教程》学习笔记42 ——《P43 瞄准(Aiming)》

本文为B站系列教学视频 《UE5_C多人TPS完整教程》 —— 《P43 瞄准&#xff08;Aiming&#xff09;》 的学习笔记&#xff0c;该系列教学视频为计算机工程师、程序员、游戏开发者、作家&#xff08;Engineer, Programmer, Game Developer, Author&#xff09; Stephen Ulibarri…

SQL Server 临时表、表变量与WITH语句的用法与区别

引言 在SQL Server数据处理中,临时表、表变量和WITH语句(CTE)是关键的中间结果集管理工具。临时表适合大数据量操作,表变量优化小数据量场景,而CTE则简化复杂查询逻辑。三者选择需综合考量数据量级、事务需求及代码可读性。本文将深入解析其工作机制,通过实测对比指导场…

【Android】组件及布局介绍

一&#xff1a;代码分析 1&#xff1a;Android界面开发方式 &#xff08;1&#xff09;JavaView&#xff08;传统视图系统&#xff09; 这是 Android 早期的开发方式&#xff0c;用 Java 或 Kotlin 代码配合 XML 布局文件 来构建界面。&#xff08;简单了解即可&#xff09; 分…

Android 音视频 IPC序列化工具-Flattenable

Android Binder与AIDL与Service使用案例及分析-CSDN博客 讲讲这个类,被用在Android音视频中,跨进程序列化反序列化用。与Binder驱动有很强的联系。位于: feameworks/native/utils/Flattenable.h Flattenable, 译为令人满意的。可能是作者十分满意自己的这些作品吧,起了这…

文献学习|全面绘制和建模水稻调控组景观揭示了复杂性状背后的调控架构。

摘要&#xff1a; 解析调控复杂性状的机制对于推进作物改良至关重要。在此&#xff0c;我们提出了一个全面的水稻&#xff08;Oryza sativa&#xff09;调控组图谱&#xff0c;涵盖了来自三个代表性品种的23种不同组织的染色质可及性。我们的研究揭示了117,176个独特的开放染色…

Linux的压缩与解压缩

一、使用tar命令进行打包与解包 1.0、tar命令简介和常用选项 tar命令是Linux中经常使用的归档工具&#xff0c;它的主要功能是【对文件或者目录进行打包归档】&#xff0c;归档为一个文件&#xff0c;但是并不进行压缩&#xff1b;tar命令的归档操作效果如下&#xff1a; tar命…

OpenCV+OCR实现弧形文字识别

以下是基于OpenCV与OCR实现弧形文字识别的完整技术方案&#xff0c;结合了图像预处理、几何变换与OCR引擎调用等关键步骤&#xff0c;并提供优化技巧&#xff1a;&#x1f50d; 一、技术原理弧形文字识别的核心在于​​将弯曲文本转换为水平直线​​&#xff0c;便于OCR引擎处理…

【保姆级目标检测教程】Ubuntu 20.04 部署 YOLOv13 全流程(附训练/推理代码)

前言 YOLOv13 是 YOLO 系列的全新一代实时目标检测框架&#xff0c;在保持极高推理速度的同时显著提升了检测精度&#xff0c;广泛适用于嵌入式部署、工业质检、智能安防等多种场景。该版本提供了 Nano、Small、Large、X-Large 四种模型规格&#xff0c;用户可以根据计算资源和…

【大模型】到底什么是Function Calling和MCP,以及和ReAct推理的关系是什么?

文章目录背景&#xff1a;什么是Agent&#xff1f;背景&#xff1a;为什么需要Function Calling或者MCP&#xff1f;Function Calling和MCP在用户请求中的整体流程Function Calling&#xff08;函数/工具调用&#xff09;MCP (Model Context Protocol)ReAct (Reasoning and Act…

CANDENCE 17.4 进行元器件缓存更新

在我从立创商城导入CANDENCE元器件后&#xff0c;在ORCAD放置元器件时出现了下面的错误解决办法&#xff1a;1、在左边找到 Design Cache文件夹&#xff0c;在文件夹上鼠标右击选择 Cleanup Cache2、再放置该元器件&#xff0c;不管这个&#xff0c;点击确定3、这时候成功放上…