|
Packit |
1470ea |
|
|
Packit |
1470ea |
<page xmlns="http://projectmallard.org/1.0/" xmlns:its="http://www.w3.org/2005/11/its" xmlns:xi="http://www.w3.org/2003/XInclude" type="topic" id="logging" xml:lang="es">
|
|
Packit |
1470ea |
|
|
Packit |
1470ea |
<info>
|
|
Packit |
1470ea |
<link type="guide" xref="index#specific-how-tos"/>
|
|
Packit |
1470ea |
|
|
Packit |
1470ea |
<credit type="author copyright">
|
|
Packit |
1470ea |
<name>Philip Withnall</name>
|
|
Packit |
1470ea |
<email its:translate="no">philip.withnall@collabora.co.uk</email>
|
|
Packit |
1470ea |
<years>2015</years>
|
|
Packit |
1470ea |
</credit>
|
|
Packit |
1470ea |
|
|
Packit |
1470ea |
<include xmlns="http://www.w3.org/2001/XInclude" href="cc-by-sa-3-0.xml"/>
|
|
Packit |
1470ea |
|
|
Packit |
1470ea |
<desc>
|
|
Packit |
1470ea |
Logging debug and information output from libraries and programs
|
|
Packit |
1470ea |
</desc>
|
|
Packit |
1470ea |
|
|
Packit |
1470ea |
<mal:credit xmlns:mal="http://projectmallard.org/1.0/" type="translator copyright">
|
|
Packit |
1470ea |
<mal:name>Daniel Mustieles</mal:name>
|
|
Packit |
1470ea |
<mal:email>daniel.mustieles@gmail.com</mal:email>
|
|
Packit |
1470ea |
<mal:years>2016</mal:years>
|
|
Packit |
1470ea |
</mal:credit>
|
|
Packit |
1470ea |
|
|
Packit |
1470ea |
<mal:credit xmlns:mal="http://projectmallard.org/1.0/" type="translator copyright">
|
|
Packit |
1470ea |
<mal:name>Javier Mazorra</mal:name>
|
|
Packit |
1470ea |
<mal:email>mazi.debian@gmail.com</mal:email>
|
|
Packit |
1470ea |
<mal:years>2016</mal:years>
|
|
Packit |
1470ea |
</mal:credit>
|
|
Packit |
1470ea |
</info>
|
|
Packit |
1470ea |
|
|
Packit |
1470ea |
<title>Registro</title>
|
|
Packit |
1470ea |
|
|
Packit |
1470ea |
<synopsis>
|
|
Packit |
1470ea |
<title>Resumen</title>
|
|
Packit |
1470ea |
|
|
Packit |
1470ea |
|
|
Packit |
1470ea |
Logging debug and informational output from libraries and programs is an
|
|
Packit |
1470ea |
open problem, and there are various methods for converting multiple
|
|
Packit |
1470ea |
streams of log output into the customary stdout and stderr streams. Below
|
|
Packit |
1470ea |
are some suggestions for how to implement logging. However, the most
|
|
Packit |
1470ea |
important thing is to ensure that logging is consistent, so that log data
|
|
Packit |
1470ea |
can be accessed and searched with a minimum of effort, since that’s what
|
|
Packit |
1470ea |
it’s used for. Using different logging mechanisms and formats in different
|
|
Packit |
1470ea |
projects is not the right approach.
|
|
Packit |
1470ea |
|
|
Packit |
1470ea |
|
|
Packit |
1470ea |
<list>
|
|
Packit |
1470ea |
<item>
|
|
Packit |
1470ea |
Use the GLib logging framework instead of logging directly to stderr and
|
|
Packit |
1470ea |
stdout. (<link xref="#glib-logging-framework"/>)
|
|
Packit |
1470ea |
</item>
|
|
Packit |
1470ea |
<item>
|
|
Packit |
1470ea |
If systemd can be a dependency of the project, consider logging directly
|
|
Packit |
1470ea |
to the journal. (<link xref="#journald-integration"/>)
|
|
Packit |
1470ea |
</item>
|
|
Packit |
1470ea |
<item>
|
|
Packit |
1470ea |
Do not implement log rotation and deletion; leave that to system
|
|
Packit |
1470ea |
services. (<link xref="#log-rotation"/>)
|
|
Packit |
1470ea |
</item>
|
|
Packit |
1470ea |
</list>
|
|
Packit |
1470ea |
</synopsis>
|
|
Packit |
1470ea |
|
|
Packit |
1470ea |
<section id="glib-logging-framework">
|
|
Packit |
1470ea |
<title>Entorno de trabajo de registro de GLib</title>
|
|
Packit |
1470ea |
|
|
Packit |
1470ea |
|
|
Packit |
1470ea |
GLib provides
|
|
Packit |
1470ea |
<link href="https://developer.gnome.org/glib/stable/glib-Message-Logging.html">a
|
|
Packit |
1470ea |
logging framework</link> based around the
|
|
Packit |
1470ea |
<link href="https://developer.gnome.org/glib/stable/glib-Message-Logging.html#g-log">g_log() </link>
|
|
Packit |
1470ea |
function, with convenience wrappers
|
|
Packit |
1470ea |
<link href="https://developer.gnome.org/glib/stable/glib-Message-Logging.html#g-debug">g_debug() </link>,
|
|
Packit |
1470ea |
<link href="https://developer.gnome.org/glib/stable/glib-Message-Logging.html#g-message">g_message() </link>,
|
|
Packit |
1470ea |
<link href="https://developer.gnome.org/glib/stable/glib-Message-Logging.html#g-warning">g_warning() </link>
|
|
Packit |
1470ea |
and
|
|
Packit |
1470ea |
<link href="https://developer.gnome.org/glib/stable/glib-Message-Logging.html#g-error">g_error() </link>.
|
|
Packit |
1470ea |
The GLib logging framework has a few useful features:
|
|
Packit |
1470ea |
|
|
Packit |
1470ea |
<list>
|
|
Packit |
1470ea |
<item>
|
|
Packit |
1470ea |
Programmatic redirection of log messages using
|
|
Packit |
1470ea |
<link href="https://developer.gnome.org/glib/stable/glib-Message-Logging.html#g-log-set-handler">g_log_set_handler() </link>.
|
|
Packit |
1470ea |
</item>
|
|
Packit |
1470ea |
<item>
|
|
Packit |
1470ea |
Multiple logging domains, which can be processed separately.
|
|
Packit |
1470ea |
</item>
|
|
Packit |
1470ea |
<item>
|
|
Packit |
1470ea |
Multiple log levels, which can be processed separately. For example,
|
|
Packit |
1470ea |
this allows debug messages to be turned on and off at runtime.
|
|
Packit |
1470ea |
</item>
|
|
Packit |
1470ea |
<item>
|
|
Packit |
1470ea |
Support for automatically aborting a program on ‘fatal’ messages.
|
|
Packit |
1470ea |
</item>
|
|
Packit |
1470ea |
</list>
|
|
Packit |
1470ea |
|
|
Packit |
1470ea |
|
|
Packit |
1470ea |
These should be used in preference to functions like
|
|
Packit |
1470ea |
printf() ,
|
|
Packit |
1470ea |
<link href="https://developer.gnome.org/glib/stable/glib-Warnings-and-Assertions.html#g-print">g_print() </link>
|
|
Packit |
1470ea |
and
|
|
Packit |
1470ea |
<link href="https://developer.gnome.org/glib/stable/glib-Warnings-and-Assertions.html#g-printerr">g_printerr() </link>,
|
|
Packit |
1470ea |
due to their enhanced flexibility. The logging functions allow log
|
|
Packit |
1470ea |
processing to be done in code, rather than by external shell scripting,
|
|
Packit |
1470ea |
which simplifies everything.
|
|
Packit |
1470ea |
|
|
Packit |
1470ea |
|
|
Packit |
1470ea |
|
|
Packit |
1470ea |
A key reason to use the logging framework is that it is used in GLib and
|
|
Packit |
1470ea |
other related libraries already; by using it, all log messages are then
|
|
Packit |
1470ea |
going through the same system and can be processed similarly.
|
|
Packit |
1470ea |
|
|
Packit |
1470ea |
|
|
Packit |
1470ea |
|
|
Packit |
1470ea |
To use the GLib logging framework, define
|
|
Packit |
1470ea |
<link href="https://developer.gnome.org/glib/stable/glib-Message-Logging.html#G-LOG-DOMAIN:CAPS">G_LOG_DOMAIN </link>
|
|
Packit |
1470ea |
for the project so it’s unique from all other projects. Call
|
|
Packit |
1470ea |
g_debug("Message") to log a debug message.
|
|
Packit |
1470ea |
|
|
Packit |
1470ea |
|
|
Packit |
1470ea |
|
|
Packit |
1470ea |
If the default GLib log handlers are not sufficient, for example if log
|
|
Packit |
1470ea |
messages need to be in a custom format or
|
|
Packit |
1470ea |
<link xref="#journald-integration">journald integration</link> is needed,
|
|
Packit |
1470ea |
set up a log handler with the following code:
|
|
Packit |
1470ea |
|
|
Packit |
1470ea |
|
|
Packit |
1470ea |
static const gchar *
|
|
Packit |
1470ea |
log_level_to_string (GLogLevelFlags level)
|
|
Packit |
1470ea |
{
|
|
Packit |
1470ea |
switch (level)
|
|
Packit |
1470ea |
{
|
|
Packit |
1470ea |
case G_LOG_LEVEL_ERROR: return "ERROR";
|
|
Packit |
1470ea |
case G_LOG_LEVEL_CRITICAL: return "CRITICAL";
|
|
Packit |
1470ea |
case G_LOG_LEVEL_WARNING: return "WARNING";
|
|
Packit |
1470ea |
case G_LOG_LEVEL_MESSAGE: return "MESSAGE";
|
|
Packit |
1470ea |
case G_LOG_LEVEL_INFO: return "INFO";
|
|
Packit |
1470ea |
case G_LOG_LEVEL_DEBUG: return "DEBUG";
|
|
Packit |
1470ea |
default: return "UNKNOWN";
|
|
Packit |
1470ea |
}
|
|
Packit |
1470ea |
}
|
|
Packit |
1470ea |
|
|
Packit |
1470ea |
static void
|
|
Packit |
1470ea |
log_handler_cb (const gchar *log_domain,
|
|
Packit |
1470ea |
GLogLevelFlags log_level,
|
|
Packit |
1470ea |
const gchar *message,
|
|
Packit |
1470ea |
gpointer user_data)
|
|
Packit |
1470ea |
{
|
|
Packit |
1470ea |
const gchar *log_level_str;
|
|
Packit |
1470ea |
|
|
Packit |
1470ea |
/* Ignore debug messages if disabled. */
|
|
Packit |
1470ea |
if (!debug_enabled && (log_level & G_LOG_LEVEL_DEBUG))
|
|
Packit |
1470ea |
{
|
|
Packit |
1470ea |
return;
|
|
Packit |
1470ea |
}
|
|
Packit |
1470ea |
|
|
Packit |
1470ea |
log_level_str = log_level_to_string (log_level & G_LOG_LEVEL_MASK);
|
|
Packit |
1470ea |
|
|
Packit |
1470ea |
/* Use g_printerr() for warnings and g_print() otherwise. */
|
|
Packit |
1470ea |
if (flags <= G_LOG_LEVEL_WARNING)
|
|
Packit |
1470ea |
{
|
|
Packit |
1470ea |
g_printerr ("%s: %s: %s\n", log_domain, log_level_str, message);
|
|
Packit |
1470ea |
}
|
|
Packit |
1470ea |
else
|
|
Packit |
1470ea |
{
|
|
Packit |
1470ea |
g_print ("%s: %s: %s\n", log_domain, log_level_str, message);
|
|
Packit |
1470ea |
}
|
|
Packit |
1470ea |
}
|
|
Packit |
1470ea |
|
|
Packit |
1470ea |
g_log_set_handler ("log-domain",
|
|
Packit |
1470ea |
G_LOG_LEVEL_MASK | G_LOG_FLAG_FATAL | G_LOG_FLAG_RECURSION,
|
|
Packit |
1470ea |
log_handler_cb, NULL);
|
|
Packit |
1470ea |
|
|
Packit |
1470ea |
<section id="exceptions">
|
|
Packit |
1470ea |
<title>Excepciones</title>
|
|
Packit |
1470ea |
|
|
Packit |
1470ea |
<list>
|
|
Packit |
1470ea |
<item>
|
|
Packit |
1470ea |
Do not use g_message() in normal code to print output.
|
|
Packit |
1470ea |
Printing output should be done at the top level of an application,
|
|
Packit |
1470ea |
using g_print() , and should be quite rare; i.e. only done
|
|
Packit |
1470ea |
in command line applications.
|
|
Packit |
1470ea |
</item>
|
|
Packit |
1470ea |
<item>
|
|
Packit |
1470ea |
Do not use g_warning() in library code. Use
|
|
Packit |
1470ea |
<link xref="gerror">GError s</link> instead.
|
|
Packit |
1470ea |
</item>
|
|
Packit |
1470ea |
<item>
|
|
Packit |
1470ea |
Similarly, do not set up log handlers in library code. Log messages
|
|
Packit |
1470ea |
should propagate through library code and be handled in a log handler
|
|
Packit |
1470ea |
at the top level of an application.
|
|
Packit |
1470ea |
</item>
|
|
Packit |
1470ea |
</list>
|
|
Packit |
1470ea |
</section>
|
|
Packit |
1470ea |
</section>
|
|
Packit |
1470ea |
|
|
Packit |
1470ea |
<section id="journald-integration">
|
|
Packit |
1470ea |
<title>Integración con journald</title>
|
|
Packit |
1470ea |
|
|
Packit |
1470ea |
|
|
Packit |
1470ea |
Compared to conventional syslog-style logs, journald supports storage of
|
|
Packit |
1470ea |
structured logging data, which can make post-hoc analysis of logs much
|
|
Packit |
1470ea |
easier. If it’s possible to add systemd-journal as a
|
|
Packit |
1470ea |
dependency to a project, the project’s log handling function could be
|
|
Packit |
1470ea |
extended to use
|
|
Packit |
1470ea |
<link href="http://0pointer.de/public/systemd-man/sd_journal_send.html">sd_journal_print()
|
|
Packit |
1470ea |
and sd_journal_send() </link> instead of
|
|
Packit |
1470ea |
g_print() and g_printerr() .
|
|
Packit |
1470ea |
|
|
Packit |
1470ea |
|
|
Packit |
1470ea |
|
|
Packit |
1470ea |
For more information, see this
|
|
Packit |
1470ea |
<link href="http://0pointer.de/blog/projects/journal-submit.html">article
|
|
Packit |
1470ea |
on logging to the journal</link>.
|
|
Packit |
1470ea |
|
|
Packit |
1470ea |
</section>
|
|
Packit |
1470ea |
|
|
Packit |
1470ea |
<section id="log-rotation">
|
|
Packit |
1470ea |
<title>Rotación de registros</title>
|
|
Packit |
1470ea |
|
|
Packit |
1470ea |
|
|
Packit |
1470ea |
Log file rotation is one feature which is out of scope of the GLib logging
|
|
Packit |
1470ea |
system. It should be handled by the normal system logging mechanisms, such
|
|
Packit |
1470ea |
as <cmd>logrotate</cmd> or <cmd>systemd-journald</cmd>.
|
|
Packit |
1470ea |
|
|
Packit |
1470ea |
</section>
|
|
Packit |
1470ea |
</page>
|