欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 新闻 > 社会 > Linux中是如何进行日志管理的?

Linux中是如何进行日志管理的?

2025/3/10 5:27:59 来源:https://blog.csdn.net/qq_28576837/article/details/146029262  浏览:    关键词:Linux中是如何进行日志管理的?

在 Linux 中,日志打印是系统运行和应用程序调试的重要部分。日志可以记录系统的运行状态、错误信息、调试信息等,帮助开发者和系统管理员诊断问题。以下是 Linux 中常见的日志打印方式:

使用标准库函数

printffprintf

printf:将日志打印到标准输出(stdout)。

#include <stdio.h>
int main() {printf("This is a log message.\n");return 0;
}

fprintf:将日志打印到指定文件流(如 stderr 或文件)。

#include <stdio.h>
int main() {fprintf(stderr, "This is an error message.\n");return 0;
}

适合简单打印的场景。 

syslog

syslog:将日志发送到系统日志服务(如 rsyslogsystemd-journald)。

#include <syslog.h>
int main() {openlog("myapp", LOG_PID, LOG_USER); // 打开日志连接syslog(LOG_INFO, "This is an info message."); // 记录日志closelog(); // 关闭日志连接return 0;
}

日志级别

LOG_EMERG:紧急情况(系统不可用)。

LOG_ALERT:需要立即采取行动。

LOG_CRIT:严重错误。

LOG_ERR:一般错误。

LOG_WARNING:警告。

LOG_NOTICE:需要注意的情况。

LOG_INFO:一般信息。

LOG_DEBUG:调试信息。

使用系统日志服务

(1)rsyslog

简介rsyslog 是 Linux 中常用的系统日志服务,负责收集、存储和管理日志。

配置:编辑 /etc/rsyslog.conf 文件,定义日志的存储位置和规则。

示例

# 将所有日志存储到 /var/log/myapp.log
local0.* /var/log/myapp.log

应用程序使用

#include <syslog.h>
int main() {openlog("myapp", LOG_PID, LOG_LOCAL0);syslog(LOG_INFO, "This is a log message.");closelog();return 0;
}

(2)systemd-journald

简介systemd-journaldsystemd 的一部分,负责收集和存储日志。

查看日志

journalctl -xe # 查看最新日志
journalctl -u sshd # 查看 sshd 服务的日志

更多待补充 

使用日志库

(1)log4c

简介log4c 是一个 C 语言日志库,支持灵活的日志配置。

示例

#include <log4c.h>
int main() {log4c_init();log4c_category_t *log = log4c_category_get("myapp");log4c_category_log(log, LOG4C_PRIORITY_INFO, "This is a log message.");log4c_fini();return 0;
}

(2)zlog

简介zlog 是一个高性能的 C 语言日志库,支持多线程和多输出。

示例

#include <zlog.h>
int main() {zlog_init("zlog.conf");zlog_category_t *log = zlog_get_category("myapp");zlog_info(log, "This is a log message.");zlog_fini();return 0;
}

更多待补充 

自定义日志文件

直接写入文件

#include <stdio.h>
int main() {FILE *log_file = fopen("/var/log/myapp.log", "a");if (log_file) {fprintf(log_file, "This is a log message.\n");fclose(log_file);}return 0;
}

更多待补充 

日志打印建议

分级记录:根据日志的重要性分级记录(如 DEBUG、INFO、WARN、ERROR)。

格式化输出:使用统一的格式记录日志,便于后续分析。

异步日志:在高性能场景下,使用异步日志减少对主线程的影响。

日志轮转:使用 logrotate 定期轮转日志文件,避免日志文件过大。

安全性:保护日志文件,防止未经授权的访问和篡改。

示例:

综合使用 syslog 和文件日志

#include <stdio.h>
#include <syslog.h>void log_to_file(const char *message) {FILE *log_file = fopen("/var/log/myapp.log", "a");if (log_file) {fprintf(log_file, "%s\n", message);fclose(log_file);}
}int main() {// 使用 syslogopenlog("myapp", LOG_PID, LOG_USER);syslog(LOG_INFO, "Application started.");// 使用文件日志log_to_file("Application started.");closelog();return 0;
}

总结

在 Linux 中,日志打印可以通过标准库函数(如 printffprintf)、系统日志服务(如 syslogrsyslogsystemd-journald)或第三方日志库(如 log4czlog)实现。开发者应根据需求选择合适的日志打印方式,并遵循日志管理的最佳实践,确保日志的可读性、安全性和可维护性。

对比补充

在实际的 Linux 开发中,直接使用 printf 打印日志并不是最佳实践,尤其是在生产环境或复杂的项目中。虽然 printf 简单易用,但它缺乏灵活性、功能单一,且不适合高性能、多线程或分布式系统。以下是实际开发中更常见的日志打印方式及其优缺点分析:

1. 直接使用 printf 的局限性

优点:

简单易用,适合快速调试和小型项目。

不需要额外的库或配置。

缺点:

无日志级别:无法区分日志的重要性(如 DEBUG、INFO、ERROR)。

无输出控制:无法动态调整日志输出目标(如文件、控制台、网络)。

性能问题:在高性能场景下,printf 可能成为性能瓶颈。

线程不安全:在多线程环境中,直接使用 printf 可能导致输出混乱。

无格式化选项:缺乏灵活的日志格式化功能。

难以维护:日志分散在代码中,难以统一管理和分析。

2. 实际开发中的日志打印方式

(1)使用 syslog

适用场景:系统级应用程序、服务、守护进程。

优点

支持日志级别(如 LOG_INFO、LOG_ERR)。

日志由系统日志服务(如 rsyslogsystemd-journald)统一管理。

支持远程日志传输(通过 TCP/UDP)。

缺点

配置复杂,需要了解系统日志服务。

不适合高性能场景。

示例

#include <syslog.h>
int main() {openlog("myapp", LOG_PID, LOG_USER);syslog(LOG_INFO, "This is an info message.");closelog();return 0;
}

(2)使用日志库

常用日志库

log4c:C 语言的日志库,功能强大。

zlog:高性能的 C 语言日志库,支持多线程和多输出。

glib 的日志功能:适用于基于 GLib 的项目。

优点

支持日志级别、格式化、异步输出等功能。

适合大型项目和高性能场景。

缺点

需要引入额外的库。

配置和使用较复杂。

示例(使用 zlog

#include <zlog.h>
int main() {zlog_init("zlog.conf");zlog_category_t *log = zlog_get_category("myapp");zlog_info(log, "This is a log message.");zlog_fini();return 0;
}

(3)自定义日志模块

适用场景:需要高度定制化的日志功能。

优点

完全控制日志格式、输出目标和行为。

适合特定需求的项目。

缺点

需要自行实现日志功能,增加开发成本。

示例

#include <stdio.h>
#include <time.h>void log_message(const char *level, const char *message) {time_t now = time(NULL);char timestamp[20];strftime(timestamp, sizeof(timestamp), "%Y-%m-%d %H:%M:%S", localtime(&now));printf("[%s] [%s] %s\n", timestamp, level, message);
}int main() {log_message("INFO", "This is an info message.");log_message("ERROR", "This is an error message.");return 0;
}

(4)使用文件日志

适用场景:需要将日志保存到文件中。

优点

日志可以长期保存,便于后续分析。

适合需要持久化日志的场景。

缺点

需要手动管理日志文件(如轮转、清理)。

示例

#include <stdio.h>
void log_to_file(const char *message) {FILE *log_file = fopen("/var/log/myapp.log", "a");if (log_file) {fprintf(log_file, "%s\n", message);fclose(log_file);}
}int main() {log_to_file("This is a log message.");return 0;
}

3. 总结

在实际的 Linux 开发中,直接使用 printf 打印日志通常只适合快速调试和小型项目。对于生产环境或复杂的项目,更推荐使用以下方式:

syslog:适合系统级应用程序。

日志库(如 zloglog4c):适合需要高性能和灵活性的场景。

自定义日志模块:适合需要高度定制化的项目。

通过合理选择日志打印方式,可以提高代码的可维护性、性能和安全性。

关于syslog的使用,更多参考:

Unix/Linux编程:syslog进程与日志输出_linux syslog()函数 输出信息到哪个文件-CSDN博客

syslog具体使用 



Linux日志管理之详解syslog/vsyslog-CSDN博客

在实际的使用过程中,我们可以通过配置文件和查看相应的日志文件来使用syslog。然而,在许多应用场景下,我们往往需要通过程序产生输出信息并进行记录,也就是说要把一些信息写成日志文件,正常情况下运行程序的人不用关心日志里的内容,只有在出现问题的时候才会查看日志文件里的内容以确定问题所在。因此,下面将详细介绍如何通过syslog日志系统提供的API调用接口,来使用程序实现对syslog的使用。

1.主要的函数

在Linux中,提供了四个有关syslog日志系统的系统调用,供用户使用:

  • openlog:打开日志设备,以供读取和写入,与文件系统调用的open类似;

  • syslog:写入日志,与文件系统调用的write类似;

  • closelog:关闭日志设备,与文件系统调用的close类似;

  • vsyslog:它和syslog功能一样,负责写入日志,只是参数格式不同。

(1)openlog函数

该函数的声明如下:

void openlog(const char *ident, int option, int facility);

此函数用来打开一个到系统日志记录程序的连接,打开之后就可以用syslog或vsyslog函数向系统日志里添加信息了。而closelog函数就是用来关闭此连接的。

openlog 的第一个参数ident是一个标记,ident所表示的字符串将固定地加在每行日志的前面以标识这个日志,通常就写成当前程序的名称以作标记。第二个参数 option一般是下列选项值取“与”运算(使用“|”表示,如“LOG_CONS | LOG_PID”)的结果:

  • LOG_CONS:如果送到system logger时发生问题,直接写入系统终端;

  • LOG_NDELAY:立即开启连接,通常连接是在第一次写入消息时才打开的;

  • LOG_PERROR:将消息也同时送到stderr设备;

  • LOG_PID:将进程PID含入所有消息中。

第三个参数facility指明记录日志的程序的类型,它主要具有如下几类日志类型:

  • LOG_AUTH :安全/授权消息

  • LOG_AUTHPRIV:安全/授权消息

  • LOG_CRON:时间守护进程(cron和at)专用

  • LOG_DAEMON:其它系统守护进程

  • LOG_KERN:核心消息

  • LOG_LOCAL0到LOG_LOCAL7:系统保留

  • LOG_LPR:printer子系统

  • LOG_MAIL:mail子系统

  • LOG_NEWS:USENET新闻子系统

  • LOG_SYSLOG:syslogd进程内部所产生的消息

  • LOG_USER(缺省):一般使用者缺省使用消息

  • LOG_UUCP:UUCP子系统

  • LOG_FTP:FTP子系统使用

(2)syslog函数

syslog函数的声明如下:

void syslog(int priority, const char * message, ...);

第一个参数是消息的紧急级别priority,第二个参数是消息及其格式,之后是格式对应的参数,如同C语言里面printf输出函数一样使用,具体的格式这里就不再详述,它不是本文介绍的重点。

这里还需要详细介绍一下第一个参数priority,它是由severity level和facility组成的。Facility已经在上面介绍了,下面介绍一下severity level,也就是消息的重要级别,它主要包括:

  • LOG_EMERG:紧急状况

  • LOG_ALERT:高优先级问题,比如说数据库崩溃等,必须要立即采取反应行动

  • LOG_CRIT:重要状况发生,比如硬件故障

  • LOG_ERR:错误发生

  • LOG_WARNING:警告发生

  • LOG_NOTICE:一般状况,需要引起注意

  • LOG_INFO:信息状况

  • LOG_DEBUG:调试消息

在实际使用中,如果我们的程序要使用系统日志功能,只需要在程序启动时使用openlog函数来连接syslogd程序,后面随时用syslog函数写日志就行了。

(3)closelog函数

相对上述2个函数来说,该函数非常简单,其声明如下:

void closelog( void );

值得注意的是,虽然该函数的使用和调用情况非常简单,但是是必不可少的,因为在Linux系统中,打开的日志也是资源,如果只使用openlog函数打开日志,而忘记使用closelog关闭日志的话,当打开的日志数量累积到一定程度,便会造成内存不足,从而引起系统问题。所以,提醒用户在使用中特别注意。

2.一个实际的程序调用例子

下面给出一个使用上述几个函数写日志的例子,以供大家参考:

 

#include <syslog.h>
#include <stdio.h>
#include <stdarg.h>
int main(void)
{
int log_test;/*打开日志*/
openlog("log_test ", LOG_PID|LOG_CONS, LOG_USER);/*写日志*/
syslog(LOG_INFO, "PID information, pid=%d", getpid());
syslog(LOG_DEBUG,"debug message ");/*关闭日志*/
closelog();
}

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词