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() {
    // 使用 syslog
    openlog("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();
}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

HTML label 标签使用

点击 <label> 标签通常会使与之关联的表单控件获得焦点或被激活。 通过正确使用 <label> 标签&#xff0c;可以使表单更加友好和易于使用&#xff0c;同时提高整体的可访问性。 基本用法 <label> 标签通过 for 属性与 id 为 username 的 <input> 元素…

数字万用表的使用教程

福禄克经济型数字万用表前面板按键功能介绍示意图 1. 万用表简单介绍 万用表是一种带有整流器的、可以测量交、直流电流、电压及电阻等多种电学参量的磁电式仪表。分为数字万用表&#xff0c;钳形万用表&#xff0c; &#xff08;1&#xff09;表笔分为红、黑二只。使用时黑色…

Python 爬取唐诗宋词三百首

你可以使用 requests 和 BeautifulSoup 来爬取《唐诗三百首》和《宋词三百首》的数据。以下是一个基本的 Python 爬虫示例&#xff0c;它从 中华诗词网 或类似的网站获取数据并保存为 JSON 文件。 import requests from bs4 import BeautifulSoup import json import time# 爬取…

2025年AI PPT工具精选:让演示文稿更智能、更高效

&#x1f4a1; 做PPT太难&#xff1f;没灵感&#xff1f;排版不好看&#xff1f;别怕&#xff0c;AI已经帮你安排好了&#xff01; 想知道2025年最值得推荐的AI PPT工具是哪款&#xff1f;答案就是——秒出PPT&#xff01;&#x1f680; 不仅能一键生成PPT&#xff0c;还能自…

qt-C++笔记之ubuntu22.04源码安装Qt6.8.2

qt-C笔记之ubuntu22.04源码安装Qt6.8.2 code review! 文章目录 qt-C笔记之ubuntu22.04源码安装Qt6.8.21.作者环境&#xff1a;ubuntu22.04、cmake202.安装3.关联已安装的 Qt6 到 Qt Creator4.附&#xff1a;ubuntu18.0的处理&#xff0c;可尝试&#xff0c;作者没有遇到这个问题…

单例模式(线程案例)

单例模式可以分为两种&#xff1a;1.饿汉模式 2.懒汉模式 一.饿汉模式 //饿汉模式&#x1f447; class MySingleTon{//因为这是一个静态成员变量&#xff0c;在类加载的时候&#xff0c;就创建了private static MySingleTon mySingleTon new MySingleTon();//创建一个静…

基于Matlab的多目标粒子群优化

在复杂系统的设计、决策与优化问题中&#xff0c;常常需要同时兼顾多个相互冲突的目标&#xff0c;多目标粒子群优化&#xff08;MOPSO&#xff09;算法应运而生&#xff0c;作为群体智能优化算法家族中的重要成员&#xff0c;它为解决此类棘手难题提供了高效且富有创新性的解决…

(2025年)工会考试该如何高效备考?有学习方法吗?

工会考试备考文章 工会考试高效备考指南 工会在维护职工权益、促进企业和谐发展中扮演着重要角色&#xff0c;工会考试则是选拔优秀工会工作者的关键途径。面对工会考试涉及的法律法规、组织管理以及维权服务等多方面知识&#xff0c;掌握科学备考方法是成功的关键。 法律法规是…

《机器学习数学基础》补充资料:向量范数

《机器学习数学基础》第1章1.5.3节介绍了向量范数的基本定义。 本文在上述基础上&#xff0c;介绍向量范数的有关性质。 注意&#xff1a; 以下均在欧几里得空间讨论&#xff0c;即欧氏范数。 1. 性质 实&#xff08;或复&#xff09;向量 x \pmb{x} x &#xff0c;范数 ∥…

Unity NGUI新手向几个问题记录

1.点Button没反应 制作Button组件时&#xff0c;不光要挂载Button脚本&#xff0c;还有挂载BoxCollider BoxCollider 接收事件 2.Button点击事件的增加与删除 使用.onClick.add增加事件&#xff0c;使用.onClick.Remove,.onClick.RemoveAt,onClick.RemoveRang,onClick.Clear移…

servlet tomcat

在spring-mvc demo程序运行到DispatcherServlet的mvc处理 一文中&#xff0c;我们实践了浏览器输入一个请求&#xff0c;然后到SpringMvc的DispatcherServlet处理的整个流程. 设计上这些都是tomcat servlet的处理 那么究竟这是怎么到DispatcherServlet处理的&#xff0c;本文将…

UniApp 中封装 HTTP 请求与 Token 管理(附Demo)

目录 1. 基本知识2. Demo3. 拓展 1. 基本知识 从实战代码中学习&#xff0c;上述实战代码来源&#xff1a;芋道源码/yudao-mall-uniapp 该代码中&#xff0c;通过自定义 request 函数对 HTTP 请求进行了统一管理&#xff0c;并且结合了 Token 认证机制 请求封装原理&#xff…

【音视频】ffmpeg命令分类查询

一、ffmpeg命令分类查询 -version&#xff1a;显示版本 ffmpeg -version-buildconf&#xff1a;显示编译配置&#xff0c;这里指的是你编译好的ffmpeg的选项 ffmpeg -buildconf-formats:显示可用格式&#xff08;muxersdemuxers&#xff09;&#xff0c;复用器和解复用器&am…

基于Windows11的DockerDesktop安装和布署方法简介

基于Windows11的DockerDesktop安装和布署方法简介 一、下载安装Docker docker 下载地址 https://www.docker.com/ Download Docker Desktop 选择Download for Winodws AMD64下载Docker Desktop Installer.exe 双点击 Docker Desktop Installer.exe 进行安装 测试Docker安装是…

C++发展

目录 ​编辑C 的发展总结&#xff1a;​编辑 1. C 的早期发展&#xff08;1979-1985&#xff09; 2. C 标准化过程&#xff08;1985-1998&#xff09; 3. C 标准演化&#xff08;2003-2011&#xff09; 4. C11&#xff08;2011年&#xff09; 5. C14&#xff08;2014年&a…

爬虫Incapsula reese84加密案例:Etihad航空

声明: 该文章为学习使用,严禁用于商业用途和非法用途,违者后果自负,由此产生的一切后果均与作者无关 一、找出需要加密的参数 1.js运行 atob(‘aHR0cHM6Ly93d3cuZXRpaGFkLmNvbS96aC1jbi8=’) 拿到网址,F12打开调试工具,随便搜索航班,切换到network搜索一个时间点可以找…

【分享】网间数据摆渡系统,如何打破传输瓶颈,实现安全流转?

在数字化浪潮中&#xff0c;企业对数据安全愈发重视&#xff0c;网络隔离成为保护核心数据的重要手段。内外网隔离、办公网与研发网隔离等措施&#xff0c;虽为数据筑牢了防线&#xff0c;却也给数据传输带来了诸多难题。传统的数据传输方式在安全性、效率、管理等方面暴露出明…

uploadlabs经验总结

目录 一、基础上传漏洞&#xff08;太过简单目前环境不可能存在&#xff09; 1、抓包然后改后缀进行绕过 2、抓包然后改上传文件类型进行绕过 3、改后缀大小写绕过&#xff0c;以及收尾加空格&#xff0c;加::$DATA,加点等等 4、黑名单不完整绕过&#xff0c;复习后缀绕过&…

数据结构:二叉树的链式结构及相关算法详解

目录 一.链式结构的实现 1.二叉树结点基本结构&#xff0c;初始化与销毁&#xff1a; 二.链式结构二叉树的几种遍历算法 1.几种算法的简单区分&#xff1a; 2.前序遍历&#xff1a; 3.中序遍历&#xff1a; 4.后序遍历&#xff1a; 5.层序遍历&#xff08;广度优先遍历B…

VSCode 移除EmmyLua插件的红色波浪线提示

VSCode 中安装插件EmmyLua&#xff0c;然后打开lua文件的时候&#xff0c;如果lua代码引用了C#脚本的变量&#xff0c;经常出现 “undefined global variable: UnityEngineEmmyLua(undefined-global)” 的红色波浪线提示&#xff0c;这个提示看着比较烦人&#xff0c;我们可以通…