<?xml version="1.0" encoding="utf-8"?>
<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">

  <info>
    <link type="guide" xref="index#specific-how-tos"/>

    <credit type="author copyright">
      <name>Philip Withnall</name>
      <email its:translate="no">philip.withnall@collabora.co.uk</email>
      <years>2015</years>
    </credit>

    <include xmlns="http://www.w3.org/2001/XInclude" href="cc-by-sa-3-0.xml"/>

    <desc>Registro de depuración y salida de información de bibliotecas y programas</desc>
  
    <mal:credit xmlns:mal="http://projectmallard.org/1.0/" type="translator copyright">
      <mal:name>Daniel Mustieles</mal:name>
      <mal:email>daniel.mustieles@gmail.com</mal:email>
      <mal:years>2016-2020</mal:years>
    </mal:credit>
  
    <mal:credit xmlns:mal="http://projectmallard.org/1.0/" type="translator copyright">
      <mal:name>Javier Mazorra</mal:name>
      <mal:email>mazi.debian@gmail.com</mal:email>
      <mal:years>2016, 2020</mal:years>
    </mal:credit>
  </info>

  <title>Registro</title>

  <synopsis>
    <title>Resumen</title>

    <p>El registro de la depuración y la salida informativa de bibliotecas y programas es un problema abierto, y existen varios métodos para convertir múltiples flujos de salida de registro en los flujos stdout y stderr habituales. A continuación se presentan algunas sugerencias sobre cómo implementar el registro. Sin embargo, lo más importante es garantizar que el registro sea coherente, de modo que se pueda acceder a los datos de registro y buscarlos con un mínimo de esfuerzo, ya que para eso se utilizan. El uso de diferentes mecanismos y formatos de registro en diferentes proyectos no es el enfoque correcto.</p>

    <list>
      <item><p>
        Use the GLib logging framework instead of logging directly to stderr and
        stdout. (<link xref="#glib-logging-framework"/>)
      </p></item>
      <item><p>
        If systemd can be a dependency of the project, consider logging directly
        to the journal. (<link xref="#journald-integration"/>)
      </p></item>
      <item><p>
        Do not implement log rotation and deletion; leave that to system
        services. (<link xref="#log-rotation"/>)
      </p></item>
    </list>
  </synopsis>

  <section id="glib-logging-framework">
    <title>Entorno de trabajo de registro de GLib</title>

    <p>
      GLib provides
      <link href="https://developer.gnome.org/glib/stable/glib-Message-Logging.html">a
      logging framework</link> based around the
      <link href="https://developer.gnome.org/glib/stable/glib-Message-Logging.html#g-log"><code>g_log()</code></link>
      function, with convenience wrappers
      <link href="https://developer.gnome.org/glib/stable/glib-Message-Logging.html#g-debug"><code>g_debug()</code></link>,
      <link href="https://developer.gnome.org/glib/stable/glib-Message-Logging.html#g-message"><code>g_message()</code></link>,
      <link href="https://developer.gnome.org/glib/stable/glib-Message-Logging.html#g-warning"><code>g_warning()</code></link>
      and
      <link href="https://developer.gnome.org/glib/stable/glib-Message-Logging.html#g-error"><code>g_error()</code></link>.
      The GLib logging framework has a few useful features:
    </p>
    <list>
      <item><p>
        Programmatic redirection of log messages using
        <link href="https://developer.gnome.org/glib/stable/glib-Message-Logging.html#g-log-set-handler"><code>g_log_set_handler()</code></link>.
      </p></item>
      <item><p>
        Multiple logging domains, which can be processed separately.
      </p></item>
      <item><p>
        Multiple log levels, which can be processed separately. For example,
        this allows debug messages to be turned on and off at runtime.
      </p></item>
      <item><p>
        Support for automatically aborting a program on ‘fatal’ messages.
      </p></item>
    </list>

    <p>
      These should be used in preference to functions like
      <code>printf()</code>,
      <link href="https://developer.gnome.org/glib/stable/glib-Warnings-and-Assertions.html#g-print"><code>g_print()</code></link>
      and
      <link href="https://developer.gnome.org/glib/stable/glib-Warnings-and-Assertions.html#g-printerr"><code>g_printerr()</code></link>,
      due to their enhanced flexibility. The logging functions allow log
      processing to be done in code, rather than by external shell scripting,
      which simplifies everything.
    </p>

    <p>
      A key reason to use the logging framework is that it is used in GLib and
      other related libraries already; by using it, all log messages are then
      going through the same system and can be processed similarly.
    </p>

    <p>
      To use the GLib logging framework, define
      <link href="https://developer.gnome.org/glib/stable/glib-Message-Logging.html#G-LOG-DOMAIN:CAPS"><code>G_LOG_DOMAIN</code></link>
      for the project so it’s unique from all other projects. Call
      <code>g_debug("Message")</code> to log a debug message.
    </p>

    <p>
      If the default GLib log handlers are not sufficient, for example if log
      messages need to be in a custom format or
      <link xref="#journald-integration">journald integration</link> is needed,
      set up a log handler with the following code:
    </p>
    <code mime="text/x-csrc">
static const gchar *
log_level_to_string (GLogLevelFlags level)
{
  switch (level)
    {
      case G_LOG_LEVEL_ERROR: return "ERROR";
      case G_LOG_LEVEL_CRITICAL: return "CRITICAL";
      case G_LOG_LEVEL_WARNING: return "WARNING";
      case G_LOG_LEVEL_MESSAGE: return "MESSAGE";
      case G_LOG_LEVEL_INFO: return "INFO";
      case G_LOG_LEVEL_DEBUG: return "DEBUG";
      default: return "UNKNOWN";
    }
}

static void
log_handler_cb (const gchar    *log_domain,
                GLogLevelFlags  log_level,
                const gchar    *message,
                gpointer        user_data)
{
  const gchar *log_level_str;

  /* Ignore debug messages if disabled. */
  if (!debug_enabled &amp;&amp; (log_level &amp; G_LOG_LEVEL_DEBUG))
    {
      return;
    }

  log_level_str = log_level_to_string (log_level &amp; G_LOG_LEVEL_MASK);

  /* Use g_printerr() for warnings and g_print() otherwise. */
  if (flags &lt;= G_LOG_LEVEL_WARNING)
    {
      g_printerr ("%s: %s: %s\n", log_domain, log_level_str, message);
    }
  else
    {
      g_print ("%s: %s: %s\n", log_domain, log_level_str, message);
    }
}

g_log_set_handler ("log-domain",
                   G_LOG_LEVEL_MASK | G_LOG_FLAG_FATAL | G_LOG_FLAG_RECURSION,
                   log_handler_cb, NULL);</code>

    <section id="exceptions">
      <title>Excepciones</title>

      <list>
        <item><p>
          Do not use <code>g_message()</code> in normal code to print output.
          Printing output should be done at the top level of an application,
          using <code>g_print()</code>, and should be quite rare; i.e. only done
          in command line applications.
        </p></item>
        <item><p>
          Do not use  <code>g_warning()</code> in library code. Use
          <link xref="gerror"><code>GError</code>s</link> instead.
        </p></item>
        <item><p>Del mismo modo, no configure controladores de registro en el código de la biblioteca. Los mensajes de registro deben propagarse a través del código de la biblioteca y manejarse en un controlador de registro en el nivel superior de una aplicación.</p></item>
      </list>
    </section>
  </section>

  <section id="journald-integration">
    <title>Integración con journald</title>

    <p>
      Compared to conventional syslog-style logs, journald supports storage of
      structured logging data, which can make post-hoc analysis of logs much
      easier. If it’s possible to add <code>systemd-journal</code> as a
      dependency to a project, the project’s log handling function could be
      extended to use
      <link href="http://0pointer.de/public/systemd-man/sd_journal_send.html"><code>sd_journal_print()</code>
      and <code>sd_journal_send()</code></link> instead of
      <code>g_print()</code> and <code>g_printerr()</code>.
    </p>

    <p>
      For more information, see this
      <link href="http://0pointer.de/blog/projects/journal-submit.html">article
      on logging to the journal</link>.
    </p>
  </section>

  <section id="log-rotation">
    <title>Rotación de registros</title>

    <p>
      Log file rotation is one feature which is out of scope of the GLib logging
      system. It should be handled by the normal system logging mechanisms, such
      as <cmd>logrotate</cmd> or <cmd>systemd-journald</cmd>.
    </p>
  </section>
</page>
