Pine Blog

GLIB用户指南-日志

1.概述

程序中不免会出现错误,当错误发生时,您可以使用printf()或是g_print()在控制台 (Console)显示信息给用户,如果是在窗口程序中,可能是使用消息框,您也可能想针对某个层级的信息作个别处理,例如储存在log档案之中,在GLib中,您可以使用 Message Logging 中所介绍的函数来进行日志功能。
glib

2.功能函数

要进行日志,首先最基本的就是使用g_log()函数:

void g_log(const gchar *log_domain,
           GLogLevelFlags log_level,
           const gchar *format,
           ...);

第一个参数是log_domain,用来区别日志信息的发出者,若有设定日志的处理函数,则log_domain亦会传递给处理函数,如果您没有指定,则预设会使用G_LOG_DOMAIN,函数库会定义G_LOG_DOMAIN,以区别于其它的函数库,例如GTK在它的Makefine中定义为"Gtk":

INCLUDES = -DG_LOG_DOMAIN=\"Gtk\"

第二个参数是日志层级,可以设定为以下的值:

•G_LOG_LEVEL_ERROR(致命的,FATAL)
•G_LOG_LEVEL_CRITICAL
•G_LOG_LEVEL_WARNING
•G_LOG_LEVEL_MESSAGE
•G_LOG_LEVEL_INFO
•G_LOG_LEVEL_DEBUG

另外还有两个G_LOG_FLAG_FATAL与G_LOG_FLAG_RECURSION,作为内部的标志位使用,其中与 G_LOG_FLAG_FATAL相关联的,例如G_LOG_LEVEL_ERROR,是属于严重的致命信息,当日志时以这个层级输出时,应用程序会被中 止并呼叫核心倾印(dump)。

第三个参数是要输出的信息,其它则是额外的信息。
GLib还提供了五个宏函数,方便使用日志与相对应的信息层级:

#define g_message(...)
#define g_warning(...)
#define g_critical(...)
#define g_error(...)
#define g_debug(...)

先前说过,G_LOG_FLAG_FATAL是内部标志位,预设是G_LOG_LEVEL_ERROR与之关联,如果您想让其它层级的信息也成为FATAL 的,则可以使用g_log_set_always_fatal()函数,例如将DEBUG与CRITICAL设定为FATAL:

g_log_set_always_fatal(G_LOG_LEVEL_DEBUG | G_LOG_LEVEL_CRITICAL);

对于日志信息,您可以设定相对应的处理函数,这是使用g_log_set_handler()函数来达成:

guint g_log_set_handler(const gchar *log_domain,
                        GLogLevelFlags log_levels,
                        GLogFunc log_func,
                        gpointer user_data);

传回的整数值为Handler Id,其中GLogFunc为回调函数,它的宣告定义如下:

void (*GLogFunc) (const gchar *log_domain,
                  GLogLevelFlags log_level,
                  const gchar *message,
                  gpointer user_data);

设定信息处理函数之后,若想移除,则可以使用g_log_remove_handler()函数,根据Handler ID及log domain来移除:

void g_log_remove_handler(const gchar *log_domain,
                          guint handler_id);

2.设置glib的log级别

glib提供了一系列的log函数,像g_message、g_critical、g_warning、g_debug和g_error等,可以根据信息的类别调用不同的函数。

在我们的程序中,为了调试方便,很多地方调了g_debug,结果程序运行起来后,终端上的信息打印得眼花缭乱,不但影响性能,而且把真正有用的信息淹没掉了。

Glib既然提供了log级别,自然可以按log级别加以过滤。不过稍微有点麻烦,可以按下列方式实现:

static  void dummy_log(const gchar *log_domain, GLogLevelFlags log_level, const gchar *message, gpointer user_data) 
{ 
    return; 
} 
 
void set_log_level(const char* progname) 
{ 
    char* basename = strrchr(progname, '/'); 
    char* log_level_env_name = NULL; 
    char* log_level_evn_value = NULL; 
 
    basename = basename != NULL ? basename+1 : (char*)progname; 
 
    log_level_env_name  = g_strdup_printf("%s_LOG_LEVEL", basename); 
    log_level_evn_value = getenv(g_strup(log_level_env_name)); 
 
    if(log_level_evn_value != NULL) 
    { 
        unsigned int i = 1 << (~G_LOG_LEVEL_MASK); 
        unsigned int max_log_level = atoi(log_level_evn_value); 
        unsigned int log_level = 0; 
 
        for(; i > max_log_level; i--) 
        { 
            log_level = 1 << i; 
            g_log_set_handler(NULL, (GLogLevelFlags)log_level, dummy_log, NULL); 
        } 
    } 
 
    g_free(log_level_env_name); 
 
    return; 
} 

通过设置 ”可执行文件名(大写)_LOG_LEVEL”环境变量,可以过滤不同严重程度的LOG信息,其取值为1-7,值越大,打印的信息越多。

文章转载自:https://blog.csdn.net/l197803/article/details/138244885?spm=1001.2101.3001.6650.2&utm_medium=distribute.pc_relevant.none-task-blog-2%7Edefault%7EYuanLiJiHua%7EPosition-2-138244885-blog-52932358.235%5Ev43%5Epc_blog_bottom_relevance_base2&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2%7Edefault%7EYuanLiJiHua%7EPosition-2-138244885-blog-52932358.235%5Ev43%5Epc_blog_bottom_relevance_base2&utm_relevant_index=5,如有问题请联系删除。

未经允许不得转载:Pine Blog » GLIB用户指南-日志

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址

Pine Blog
Anywhere, Anytime
E-mail:59054872@qq.com
苏ICP备15059480号-1