我是靠谱客的博主 漂亮草莓,这篇文章主要介绍基于Linux C的简单日志库,现在分享给大家,希望可以做个参考。

        最近由于接手了几个小的开发项目,一直苦于寻找一个调用简单,方便调试,占用资源小的日志库,因为我大部分的嵌入式开发项目都是C/C++的开发。就想着做一个小的日志调用接口C/C++库。最近有时间整理一下。

        alog 由此而生,目前我几个项目中都用到了这个库,个人觉得非常简单,容易理解,使用简单,能马上融入到小型嵌入式项目中去。

首先看调用示例:

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include "alog_printf.h" int main(void) { alog_printf(ALOG_LVL_DEBUG, TURE,"n************TEST START**************n"); int a = 0; while (1) { alog_printf(ALOG_LVL_DEBUG, TURE, "test a=%d n", a); a++; sleep(1); } return 0; }

        示例中可以看到,这个日志调用类似于打印函数(其实就是改造的),说是一个日志库文件,不如说就是一个头文件,(这里主要是为了简单-不用去引用其他东西)是不是很简单。

调用原型:alog_printf(level, outputEnable, ...);

首先这个日志库具备这几个功能:

  • 可以设置输出到指定路径下保存成文件-方便导出查看
  • 日志文件以创建时间先后命名
  • 日志文件的大小和个数可设置,当超出设置限制后根据创建时间循环覆盖
  • 日志的保存等级可设置
  • 可控制是否打印在终端
  • 可输出打印时间、调用函数名和行数,方便定位打印

附一段核心实现:

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
/** * @brief : Ari日志打印 * @param {unsigned char} level * @param {_BOOL} outputEnable * @param {const char} *func * @param {const long} line * @param {const char} *fmt * @return {*} * @author: LR * @Date: 2021-06-25 12:11:49 */ static void log_printf(unsigned char level, bool outputEnable, const char *file, const long line, const char *fmt, ...) { if (level < ALOG_LVL_SET) return; pthread_mutex_lock(&alogMutex); /* 日志部分上锁 */ char printf_buf[ALOG_BUF_MAX_SIZE]={0}; va_list args; int printed; va_start(args, fmt); printed = vsnprintf(printf_buf, ALOG_BUF_MAX_SIZE, fmt, args); va_end(args); char buf[ALOG_BUF_MAX_SIZE + 200] = {0}; int g_Count = 0; char temp[256]; char logFileName[50] = {0}; char logFileNameTemp[50] = {0}; char logFileNameLast[50] = {"1580-05-05_00-00-00.log"}; char logFileNameMix[50] = {"3000-05-05_00-00-00.log"}; int iMax = ALOG_MAX_SIZE; FILE *fp = NULL; time_t timep; struct tm *p; time(&timep); p = localtime(&timep); //获取当前系统时间 //将要保存的日志信息和时间戳信息整合 memset(buf, 0, sizeof(buf)); sprintf(buf, "▶[%d-%02d-%02d %02d:%02d:%02d -> %s:%ld] : ", (1900 + p->tm_year), (1 + p->tm_mon), p->tm_mday, (p->tm_hour + 8) % 24, p->tm_min, p->tm_sec, file, line); //星期p->tm_wday strcat(buf, printf_buf); //strcat(buf, ""); if (outputEnable == true) puts(buf); DIR *dir; struct dirent *ptr; if ((dir = opendir(ALOG_PATH)) == NULL) //打开日志的文件目录,如果没有则建立 { sprintf(temp, "mkdir -p %s", ALOG_PATH); system(temp); dir = opendir(ALOG_PATH); } while ((ptr = readdir(dir)) != NULL) //循环读取当前目录下到所有文件 { if (strcmp(ptr->d_name, ".") == 0 || strcmp(ptr->d_name, "..") == 0) continue; strcpy(logFileNameTemp, ptr->d_name); if (strlen(logFileNameTemp) < 18) { //g_Count++; //统计符合要求的文件个数 continue; } if (strcmp(logFileNameTemp, logFileNameLast) > 0) //找到最新的文件 { strcpy(logFileNameLast, logFileNameTemp); //将最新日期的文件名字保存在logFileNameLast } if (strcmp(logFileNameTemp, logFileNameMix) < 0) //找到最老的文件 { strcpy(logFileNameMix, logFileNameTemp); //将最老日期的文件名字保存在logFileNameMix } g_Count++; //统计符合要求的文件个数 } closedir(dir); sprintf(logFileName, "%s%s", ALOG_PATH, logFileNameLast); //将最新的文件名字匹配到路径中去,如果没有用默认文件名 fp = fopen(logFileName, "r+"); if (fp == NULL) { //进入这个里面证明没有日志文件产生过,第一次创建+ sprintf(logFileName, "%s%d-%02d-%02d_%02d-%02d-%02d.log", ALOG_PATH, (1900 + p->tm_year), (1 + p->tm_mon), p->tm_mday, (p->tm_hour + 8) % 24, p->tm_min, p->tm_sec); fp = fopen(logFileName, "w+"); } else { fseek(fp, 0, 2); //SEEK_END值为2 if (ftell(fp) >= iMax) //如果大小已经超出限制 { fclose(fp); if (g_Count >= ALOG_MAX_NUM) //如果日志文件的个数达到路限制10个,则按日期进行循环覆盖 { sprintf(logFileName, "%s%s", ALOG_PATH, logFileNameMix); remove(logFileName); //删除最老的一个日志文件 sprintf(logFileName, "%s%d-%02d-%02d_%02d-%02d-%02d.log", ALOG_PATH, (1900 + p->tm_year), (1 + p->tm_mon), p->tm_mday, (p->tm_hour + 8) % 24, p->tm_min, p->tm_sec); } else { sprintf(logFileName, "%s%d-%02d-%02d_%02d-%02d-%02d.log", ALOG_PATH, (1900 + p->tm_year), (1 + p->tm_mon), p->tm_mday, (p->tm_hour + 8) % 24, p->tm_min, p->tm_sec); } fp = fopen(logFileName, "w+"); } else { fclose(fp); fp = fopen(logFileName, "a+"); //以追加的方式打开文件 } } fwrite(buf, 1, strlen(buf), fp); fflush(fp); //立即刷新缓存区到指定文件流中 //fsync(fileno(fp)); //将缓存区数据写入磁盘,并等待操作结束 //fdatasync(fileno(fp)); fclose(fp); pthread_mutex_unlock(&alogMutex); /*写日志部分解锁 */ }

        这里面最关键的,个人认为根据设定来把时间段内的日志发片。然后根据时间来循环的覆盖日志,这样在我们有限的嵌入式资源中就能把握日志的占用大小。不用人为的去维护,在有需要的时候下载下来,方便记录调试定位问题。

        当然这个只是项目需要写的一个东西,里面我现在想到的就还有很多可以优化增加的功能。现在只是记录一下,拿来用还是没问题的。大家有想法的也可以给我留言。

完整的实现+示例请下载:

CSDN:alog_printf.h-C文档类资源-CSDN下载

GitHub:GitHub - HelloAriLiu/alog: 一个简单的Linux 日志库适用于小型嵌入式


创作不易,您的点赞、评论、收藏是对我最大的支持!

        

最后

以上就是漂亮草莓最近收集整理的关于基于Linux C的简单日志库的全部内容,更多相关基于Linux内容请搜索靠谱客的其他文章。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(73)

评论列表共有 0 条评论

立即
投稿
返回
顶部