[英]Is it possible to set different writer functions per domain/log_level in GLib new structured logging?
GLib had an interesting feature: ability to set different logging (ie: displaying or saving, etc.) functions per different domains and log-levels, eg: GLib 有一个有趣的特性:能够为每个不同的域和日志级别设置不同的日志记录(即:显示或保存等)功能,例如:
/* Set handler for warnings from empty (application) domain */
g_log_set_handler (NULL, G_LOG_LEVEL_WARNING, my_log_handler, NULL);
/* Set handler for critical messages from Gtk+ */
g_log_set_handler ("Gtk", G_LOG_LEVEL_CRITICAL, my_log_handler, NULL);
However, as docs say:但是,正如文档所说:
This has no effect if structured logging is enabled;
如果启用了结构化日志记录,这将无效; see Using Structured Logging.
请参阅使用结构化日志记录。
I didn't find anything else related to this feature (ie: to per-domain/level handlers).我没有找到与此功能相关的任何其他内容(即:针对每个域/级别的处理程序)。 Is this not possible?
这不可能吗? Why would GLib resign of such an useful feature?
为什么 GLib 会放弃这样一个有用的功能?
Is this not possible?
这不可能吗?
It still is if you really want to, but depending on the use case, it might be wiser not to (see the second part of the answer).如果您真的想这样做,它仍然是,但根据用例,不这样做可能更明智(请参阅答案的第二部分)。
The new way of implementing custom handling logs with structured logging is by g_log_set_writer_func()
.使用结构化日志实现自定义处理日志的新方法是
g_log_set_writer_func()
。
For example:例如:
#define G_LOG_USE_STRUCTURED
#include <glib.h>
static GLogWriterOutput
my_log_writer_func (GLogLevelFlags log_level,
const GLogField *fields,
size_t n_fields,
void *user_data)
{
if (log_level & G_LOG_LEVEL_CRITICAL) {
// Do something special with criticals
// For example purposes, let's just log it to stdout/stderr
return g_log_writer_standard_streams (log_level, fields, n_fields, user_data);
}
if (log_level & G_LOG_LEVEL_DEBUG) {
// This is not something you should do since it will make
// debugging harder, but let's just do it for example purposes:
// by returning G_LOG_WRITER_HANDLED without actually logging it,
// the log message will not be outputted anywhere
return G_LOG_WRITER_HANDLED;
}
// If you _really_ want to, you can still check on the GLib domain,
// as it will be set in one of the GLogFields
// Default case: use the default logger
return g_log_writer_default (log_level, fields, n_fields, user_data);
}
int
main (int argc, char *argv[])
{
g_log_set_writer_func (my_log_writer_func, NULL, NULL);
// Run your application
}
Why would GLib resign of such an useful feature?
为什么 GLib 会放弃这样一个有用的功能?
As I mentioned earlier, GLib is not hard dropping support for custom log implementations (note that this all only works if you explicitly enable structured logging).正如我之前提到的,GLib 不难放弃对自定义日志实现的支持(请注意,这一切只有在您明确启用结构化日志记录时才有效)。 I believe the general idea is that more and more GUI apps are being launched from the desktop (eg GNOME Shell) or other UI means, so to see logs, you already have to look at the system journal, for example using
journalctl
.我相信总体思路是越来越多的 GUI 应用程序从桌面(例如 GNOME Shell)或其他 UI 方式启动,因此要查看日志,您已经必须查看系统日志,例如使用
journalctl
。
At that point, when you can use the system journal, it's much easier to filter log messages on log level, log domain, and so on.此时,当您可以使用系统日志时,在日志级别、日志域等上过滤日志消息会容易得多。 It also prevents having to tell users to "run it again, but now use these random environment variables like
G_MESSAGES_DEBUG=all
", as they might not have a clue how to run commands.它还可以避免告诉用户“再次运行它,但现在使用这些随机环境变量,如
G_MESSAGES_DEBUG=all
”,因为他们可能不知道如何运行命令。 It might also be something that is very hard to reproduce, so having the debug logs already at hand can be useful.它也可能是很难重现的东西,因此手头有调试日志可能会很有用。
Some example commands with journalctl are: (note that you can easily combine filters) journalctl 的一些示例命令是:(请注意,您可以轻松组合过滤器)
# Only show logs of the application with the given commandline name
$ journalctl _COMM=my-application-name
# Only show logs of your application with a given pid
$ journalctl _PID=$YOUR_APPS_PID
# Only show logs of your application with level WARNING or higher
$ journalctl -p warning
# Only show logs with with the given GLib domain
$ journalctl -f GLIB_DOMAIN=Gtk
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.