简介

GLib提供了一套日志输出接口,包括不同日志级别的输出以及与systemd日志系统的对接。

数据结构

日志输出最主要的数据结构是日志级别。
GLib提供了debug、info、message、warning、critical和error这六种日志输出级别。
其中,error默认是FATAL级别日志输出,输出该级别日志会调用abort()导致程序退出

enum GLogLevelFlags

函数列表

void     g_log ()
void    g_logv ()
#define     g_message()
#define     g_warning()
#define     g_critical()
#define     g_error()
#define     g_info()
#define     g_debug()
guint   g_log_set_handler ()
guint   g_log_set_handler_full ()
void    g_log_remove_handler ()
GLogLevelFlags  g_log_set_always_fatal ()
GLogLevelFlags  g_log_set_fatal_mask ()
void    g_log_default_handler ()
GLogFunc    g_log_set_default_handler ()
void    g_log_structured ()
void    g_log_variant ()
void    g_log_structured_array ()
#define     G_DEBUG_HERE
GLogWriterOutput    (*GLogWriterFunc) ()
void    g_log_set_writer_func ()
gboolean    g_log_writer_supports_color ()
gboolean    g_log_writer_is_journald ()
gchar *     g_log_writer_format_fields ()
GLogWriterOutput    g_log_writer_journald ()
GLogWriterOutput    g_log_writer_standard_streams ()
GLogWriterOutput    g_log_writer_default ()

函数功能分类

// 日志输出函数,g_logv接受valist变量
void    g_log ()
void    g_logv ()// 不同的调试输出日志函数
// 按级别排序:debug<info<message<warning<critical<error
#define     g_message()
#define     g_warning()
#define     g_critical()
#define     g_error()
#define     g_info()
#define     g_debug()// 设置和取消自定义日志函数
guint   g_log_set_handler ()
guint   g_log_set_handler_full ()
void    g_log_remove_handler ()// 给参数中指定的输出日志级别设置一个全局的fatal
// 如果设置了fatal,则在运行时,该日志输出之后会调用到abort()继而出现段错误。
// 默认情况下,只有error级别的输出,会导致段错误
GLogLevelFlags  g_log_set_always_fatal ()// 与g_log_set_always_fatal相似,但只对某一domain设置fatal,而非全局
GLogLevelFlags  g_log_set_fatal_mask ()// 设置默认输出函数
void    g_log_default_handler ()
GLogFunc    g_log_set_default_handler ()// 与systemd日志相关的结构化日志输出函数
void    g_log_structured ()
// 参数为泛型的结构化日志输出函数
void    g_log_variant ()
// 参数为数组的结构化日志输出函数
void    g_log_structured_array ()// 设置写函数
void    g_log_set_writer_func ()
// 是否支持ANSI颜色转义序列
gboolean    g_log_writer_supports_color ()
// 判断给定的文件描述符是否与systemd日志文件有关
gboolean    g_log_writer_is_journald ()// 将结构化日志输出到systemd日志系统
GLogWriterOutput    g_log_writer_journald ()
// 将结构化日志输出到标准输出stdout或标准错误输出stderr
GLogWriterOutput    g_log_writer_standard_streams ()
// 将结构化日志输出到系统默认日志系统(一般是systemd),如果从终端运行或被重定向到文件,则会输出到标准输出
GLogWriterOutput    g_log_writer_default ()

函数功能说明及综合演示

g_log函数用法演示

示例代码如下:
源码见glib_examples\glib_log\glib_log_g_log

#include <glib.h>static void my_log_handler(const gchar *log_domain, GLogLevelFlags log_level, const gchar *message, gpointer user_data)
{g_print("[%s]my_log_handler : %s \n",user_data,message);}gint main(gint argc, gchar **argv)
{g_log_set_default_handler(my_log_handler, "User_Data");g_setenv ("G_MESSAGES_DEBUG", "all", TRUE);g_log ("foo", G_LOG_LEVEL_DEBUG, "6");g_log ("bar", G_LOG_LEVEL_DEBUG, "6");g_log ("baz", G_LOG_LEVEL_DEBUG, "6");return 0;
}

运行结果:

[root@centos7_6 build]# ./glib_log_g_log
[User_Data]my_log_handler : 6
[User_Data]my_log_handler : 6
[User_Data]my_log_handler : 6

不同级别的日志输出

示例代码如下:
源码见glib_examples\glib_log\glib_log_handler

#include <glib.h>static void my_log_handler(const gchar *log_domain, GLogLevelFlags log_level, const gchar *message, gpointer user_data)
{g_print("[%s]my_log_handler : %s \n",user_data,message);}
gint main(gint argc, gchar **argv)
{guint handler_id = 0;g_print("set handler: G_LOG_LEVEL_MASK|G_LOG_FLAG_FATAL|G_LOG_FLAG_RECURSION \n");handler_id = g_log_set_handler(NULL, G_LOG_LEVEL_MASK|G_LOG_FLAG_FATAL|G_LOG_FLAG_RECURSION, my_log_handler, "APP_TAG");g_debug("debug");g_info("info");g_message("message");g_warning("warning");g_critical("critical");//g_error("error");g_log_remove_handler(NULL, handler_id);g_print("set handler: G_LOG_LEVEL_INFO|G_LOG_FLAG_FATAL|G_LOG_FLAG_RECURSION \n");handler_id = g_log_set_handler(NULL, G_LOG_LEVEL_INFO|G_LOG_FLAG_FATAL|G_LOG_FLAG_RECURSION, my_log_handler, "APP_TAG");g_debug("debug");g_info("info");g_message("message");g_warning("warning");g_critical("critical");g_log_remove_handler(NULL, handler_id);g_print("set handler: G_LOG_LEVEL_INFO|G_LOG_LEVEL_WARNING|G_LOG_FLAG_FATAL|G_LOG_FLAG_RECURSION \n");handler_id = g_log_set_handler(NULL, G_LOG_LEVEL_INFO|G_LOG_LEVEL_WARNING|G_LOG_FLAG_FATAL|G_LOG_FLAG_RECURSION, my_log_handler, "APP_TAG");g_debug("debug");g_info("info");g_message("message");g_warning("warning");g_critical("critical");g_log_remove_handler(NULL, handler_id);g_print("set handler: G_LOG_LEVEL_MASK|G_LOG_FLAG_FATAL|G_LOG_FLAG_RECURSION \n");handler_id = g_log_set_handler(NULL, G_LOG_LEVEL_MASK|G_LOG_FLAG_FATAL|G_LOG_FLAG_RECURSION, my_log_handler, "APP_TAG");g_log_set_always_fatal(G_LOG_LEVEL_MESSAGE);g_debug("debug");g_info("info");g_message("message");g_warning("warning");g_critical("critical");return 0;
}

运行结果:

[root@centos7_6 build]# ./glib_log_handler
set handler: G_LOG_LEVEL_MASK|G_LOG_FLAG_FATAL|G_LOG_FLAG_RECURSION
[APP_TAG]my_log_handler : debug
[APP_TAG]my_log_handler : info
[APP_TAG]my_log_handler : message
[APP_TAG]my_log_handler : warning
[APP_TAG]my_log_handler : critical
set handler: G_LOG_LEVEL_INFO|G_LOG_FLAG_FATAL|G_LOG_FLAG_RECURSION
[APP_TAG]my_log_handler : info
** Message: 15:10:31.479: message** (process:6101): WARNING **: 15:10:31.479: warning** (process:6101): CRITICAL **: 15:10:31.479: critical
set handler: G_LOG_LEVEL_INFO|G_LOG_LEVEL_WARNING|G_LOG_FLAG_FATAL|G_LOG_FLAG_RECURSION
[APP_TAG]my_log_handler : info
** Message: 15:10:31.479: message
[APP_TAG]my_log_handler : warning** (process:6101): CRITICAL **: 15:10:31.479: critical
set handler: G_LOG_LEVEL_MASK|G_LOG_FLAG_FATAL|G_LOG_FLAG_RECURSION
[APP_TAG]my_log_handler : debug
[APP_TAG]my_log_handler : info
[APP_TAG]my_log_handler : message
Trace/breakpoint trap(吐核)

在上述例子中,对日志输出的handler进行了多次设置和取消设置,G_LOG_LEVEL_MASK会将所有的日志输出都重定向到hander设置的输出函数,也可以单独设置某一项或某几项。
注意:设置低级别时,高级别的日志也会输出,但不会走设置的输出函数,而是走默认输出函数。例如,如果设置的是info级别,则debug不会输出,但message会输出日志,因为debug的级别比info低,但message的级别比info要高。

设置全局或域FATAL错误

FATAL错误是一种无法恢复的错误,当出现FATAL时,需要退出程序,GLib通过调用abort()使程序退出。默认情况下,只有error输出为FATAL级别,会导致段错误使程序退出,但可以使用g_log_set_always_fatal或者g_log_set_fatal_mask为某一域设置FATAL错误。

示例代码如下:
源码见glib_examples\glib_log_fatal\glib_log_fatal

#include <glib.h>static void my_log_handler(const gchar *log_domain, GLogLevelFlags log_level, const gchar *message, gpointer user_data)
{g_print("[domain:%s][LEVEL:%3d][%s]my_log_handler : %s \n",log_domain,log_level,user_data,message);
}gint main(gint argc, gchar **argv)
{g_log_set_default_handler(my_log_handler, "User_Data");g_setenv ("G_MESSAGES_DEBUG", "all", TRUE);g_log ("foo", G_LOG_LEVEL_DEBUG, "foo debug");g_log ("foo", G_LOG_LEVEL_INFO, "foo info");g_log ("bar", G_LOG_LEVEL_MESSAGE, "bar message");g_log ("bar", G_LOG_LEVEL_WARNING, "bar warning");g_log ("baz", G_LOG_LEVEL_CRITICAL, "bar critical");g_print("set fatal mask: baz G_LOG_LEVEL_MESSAGE \n");g_log_set_fatal_mask("baz", G_LOG_LEVEL_MESSAGE);g_log ("foo", G_LOG_LEVEL_DEBUG, "foo debug");g_log ("foo", G_LOG_LEVEL_INFO, "foo info");g_log ("foo", G_LOG_LEVEL_MESSAGE, "foo message");g_log ("bar", G_LOG_LEVEL_MESSAGE, "bar message");g_log ("bar", G_LOG_LEVEL_WARNING, "bar warning");g_log ("baz", G_LOG_LEVEL_INFO, "baz info");g_log ("baz", G_LOG_LEVEL_CRITICAL, "baz critical");g_print("set always fatal: G_LOG_LEVEL_MESSAGE \n");g_log_set_always_fatal(G_LOG_LEVEL_MESSAGE);g_log ("foo", G_LOG_LEVEL_DEBUG, "foo debug");g_log ("foo", G_LOG_LEVEL_INFO, "foo info");g_log ("bar", G_LOG_LEVEL_MESSAGE, "bar message");g_log ("bar", G_LOG_LEVEL_WARNING, "bar warning");g_log ("baz", G_LOG_LEVEL_CRITICAL, "baz critical");return 0;
}

运行结果:

[root@centos7_6 build]# ./glib_log_fatal
[domain:foo][LEVEL:128][User_Data]my_log_handler : foo debug
[domain:foo][LEVEL: 64][User_Data]my_log_handler : foo info
[domain:bar][LEVEL: 32][User_Data]my_log_handler : bar message
[domain:bar][LEVEL: 16][User_Data]my_log_handler : bar warning
[domain:baz][LEVEL:  8][User_Data]my_log_handler : bar critical
set fatal mask: baz G_LOG_LEVEL_MESSAGE
[domain:foo][LEVEL:128][User_Data]my_log_handler : foo debug
[domain:foo][LEVEL: 64][User_Data]my_log_handler : foo info
[domain:foo][LEVEL: 32][User_Data]my_log_handler : foo message
[domain:bar][LEVEL: 32][User_Data]my_log_handler : bar message
[domain:bar][LEVEL: 16][User_Data]my_log_handler : bar warning
[domain:baz][LEVEL: 64][User_Data]my_log_handler : baz info
[domain:baz][LEVEL:  8][User_Data]my_log_handler : baz critical
set always fatal: G_LOG_LEVEL_MESSAGE
[domain:foo][LEVEL:128][User_Data]my_log_handler : foo debug
[domain:foo][LEVEL: 64][User_Data]my_log_handler : foo info
[domain:bar][LEVEL: 34][User_Data]my_log_handler : bar message
Trace/breakpoint trap(吐核)

5_02_GLib库入门与实践_日志和调试相关推荐

  1. 3_01_GLib库入门与实践_测试框架

    简介 GLib提供了一套测试框架,可以帮助我们实现自动测试,而且还能生成报告,下面简单介绍一下这个框架的基本使用方法. 数据结构 enum GTestFileType enum GTestTrapFl ...

  2. Git - 入门到熟悉_日志管理

    文章目录 Pre 常用命令 演示 Pre Git - 入门到熟悉_Git基本概念与核心命令 Git - 入门到熟悉_分支管理 Git - 入门到熟悉_远程仓库管理 在使用 Git 提交了若干更新之后, ...

  3. android开发入门与实践_我的新书《Android App开发入门与实战》已经出版

    前言 工作之余喜欢在CSDN平台上写一些技术文章,算下时间也有两三年了.写文章的目的一方面是自己对技术的总结,另一方面也是将平时遇到的问题和解决方案与大家分享,还有就是在这个平台上能和大家共同交流. ...

  4. 1_01_GLib库入门与实践_GLib库简介

    GLib库是用C语言实现的一个通用的.可移植的实用程序库,由GNOME的GTK小组开发并维护,最早用在GTK+程序开发上,后来被越来越多的程序所引用.刚开始,GLib库叫GLib-1.0,形成于约19 ...

  5. 2_01_GLib库入门与实践_GLib库版本与兼容性

    GLib库不断更新,有些函数新增进来,有些函数已过时被废弃,所以,如果不是使用静态编译或不是自带动态库,则基于GLib的应用程序在运行时可能会出现找不到符号的错误. 版本命名规则 GLib-2.0版本 ...

  6. Python爬虫基础库(RBX)的实践_田超凡

    转载请注明原作者:田超凡 20190410 CSDN博客:https://blog.csdn.net/qq_30056341# Python爬虫基础库RBX指的是:Requests Beautiful ...

  7. 博客基础_django_python从入门到实践_创建项目_创建应用

    创建项目 制定规范 创建一简单博客网页,有固定分类,每个分类下又可以添加具体博客条目,每个条目保留作者,发布时间. 创建虚拟环境 虚拟环境是系统的一个位置,可以在其中安装包,与其他python包隔离. ...

  8. 解题报告——Python编程:从入门到实践_动手试一试_参考答案(第四章)

    注意: 做4.11时,习惯性的使用等号解题,结果发现:用等号会关联二者地址,修改其中任意一位,另一方也被修改, 因此需要使用切片方法去解题. # 习题4.1:想出至少三种你喜欢的披萨,将其名称存储在一 ...

  9. (第2版)Python编程从入门到实践_外星人项目习题13-1-13-2答案更逼真的星星_pygame练习题_python项目练习题

    13_1-13_2  图片命名:star.png,在上述代码文件夹中,新建文件夹images,将图片放置在新文件夹即可  13_1 星星主程序: import sysimport pygamefrom ...

最新文章

  1. python字符串和字节串有什么区别_对于Python中的字节串bytes和字符串以及转义字符的新的认识...
  2. 寻找GridView中模板列中的控件
  3. 数据结构(JAVA)--图
  4. VIO-为什么要进行在线时间标定
  5. LuoguP3674 小清新人渣的本愿 BZOJ4810: [Ynoi2017]由乃的玉米田
  6. 山东单招计算机什么学校好考,2021山东单招最好的公办学校有哪些 山东单招好考的公办学校一览...
  7. 在玩图像分类和图像分割?来挑战基于 TensorFlow 的图像注解生成!
  8. ssh 端口转发实现外网 80 端口映射到内网 80 端口
  9. 计算机硬盘的全球与中国市场2022-2028年:技术、参与者、趋势、市场规模及占有率研究报告
  10. RobotStudio码垛机器人创建过程
  11. CAS:1537170-85-6_DBCO-PEG4-COOH_PEG-DBCO衍生物
  12. 52单片机定时器0-2实现1ms定时
  13. Vulnhub靶机系列:SecTalks: BNE0x03 - Simple
  14. hadoop心跳机制解析
  15. duffing matlab,duffing方程matlab
  16. IN 与 DISTINCT
  17. 深度学习之灾难性遗忘问题
  18. 公众号如何开通留言功能?
  19. elasticSearch学习笔记04-同义词,停用词,拼音,高亮,拼写纠错
  20. 超超超 简单构造者模式

热门文章

  1. python显示等待隐式等待
  2. lighttpd URL重写
  3. 权威大赛|2022 CCF大数据与计算智能大赛火热报名中
  4. 运动想象EEG背景知识
  5. eBPF系列学习(4)了解libbpf、CO-RE (Compile Once – Run Everywhe) | 使用go开发ebpf程序(云原生利器cilium ebpf )
  6. 软件架构风格整理(6 CS,BS等)
  7. PyQt5 QPushButton 设置文字对齐方式(基于setStyleSheet)
  8. 关于在Idea里面修改html代码后,打开网页没改变的问题
  9. 计算机无法加载加密文件,win10电脑加密,win10加密文件无法解密
  10. 戴尔 R730xd 服务器更改管理口密码 图文教程