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