Blame programming-guidelines/cs/logging.page

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="cs">
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>Ladicí záznamy a informační výstup z knihoven a programů</desc>
Packit 1470ea
  </info>
Packit 1470ea
Packit 1470ea
  <title>Záznamy (log)</title>
Packit 1470ea
Packit 1470ea
  <synopsis>
Packit 1470ea
    <title>Shrnutí</title>
Packit 1470ea
Packit 1470ea
    

Záznam ladicího a informačního výstupu z knihoven a programů je stále otevřený problém a existuje řada metod pro převod více datových proudů s výstupními záznamy do vlastních datových proudů stdout a stderr. Níže jsou uvedena některá doporučení, jak zaznamenávání implementovat. Nejdůležitější věcí ale je zajistit, aby záznamy byly konzistentní, takže k nim bude jednoduchý přístup a půjde v nich snadno vyhledávat, protože to je přesně to, k čemu slouží. Používat odlišné mechanizmy záznamu a odlišné formáty u různých projektů není ten pravý přístup.

Packit 1470ea
Packit 1470ea
    <list>
Packit 1470ea
      <item>

Místo záznamů přímo do stderr a stdout používejte framework GLib pro záznamy. (<link xref="#glib-logging-framework"/>)

</item>
Packit 1470ea
      <item>

Když může být projekt závislý na systemd, zvažte přímé použití záznamů v žurnálu. (<link xref="#journald-integration"/>)

</item>
Packit 1470ea
      <item>

Neimplementujte rotaci a mazání záznamů. Ponechte to na systémových službách. (<link xref="#log-rotation"/>)

</item>
Packit 1470ea
    </list>
Packit 1470ea
  </synopsis>
Packit 1470ea
Packit 1470ea
  <section id="glib-logging-framework">
Packit 1470ea
    <title>Framework GLib pro záznamy</title>
Packit 1470ea
Packit 1470ea
    

GLib poskytuje <link href="https://developer.gnome.org/glib/stable/glib-Message-Logging.html">framework pro zaznamenávání</link>, který je postavený na funkci <link href="https://developer.gnome.org/glib/stable/glib-Message-Logging.html#g-log">g_log()</link> spolu s obalujícími funkcemi <link href="https://developer.gnome.org/glib/stable/glib-Message-Logging.html#g-debug">g_debug()</link>, <link href="https://developer.gnome.org/glib/stable/glib-Message-Logging.html#g-message">g_message()</link>, <link href="https://developer.gnome.org/glib/stable/glib-Message-Logging.html#g-warning">g_warning()</link> a <link href="https://developer.gnome.org/glib/stable/glib-Message-Logging.html#g-error">g_error()</link> pro větší pohodlí. Tento framework má pár užitečných vlastností:

Packit 1470ea
    <list>
Packit 1470ea
      <item>

Programové přesměrování záznamu zpráv pomocí <link href="https://developer.gnome.org/glib/stable/glib-Message-Logging.html#g-log-set-handler">g_log_set_handler()</link>.

</item>
Packit 1470ea
      <item>

Více domén záznamů, které mohou být zpracovány odděleně.

</item>
Packit 1470ea
      <item>

Více úrovní záznamů, které mohou být zpracovány odděleně. Například to umožňuje za běhu zapnout a vypnout ladicí zprávy.

</item>
Packit 1470ea
      <item>

Podpora pro automatické přerušení programu u „kritických“ zpráv.

</item>
Packit 1470ea
    </list>
Packit 1470ea
Packit 1470ea
    

Uvedeným postupům byste měli dát přednost před funkcemi jako jsou printf(), <link href="https://developer.gnome.org/glib/stable/glib-Warnings-and-Assertions.html#g-print">g_print()</link> a <link href="https://developer.gnome.org/glib/stable/glib-Warnings-and-Assertions.html#g-printerr">g_printerr()</link>, protože je to daleko flexibilnější. Funkce pro zaznamenávání umožňují provádět zaznamenávání přímo z kódu, namísto pomocí externích shellových skriptů, čímž se vše zjednoduší.

Packit 1470ea
Packit 1470ea
    

Klíčovým důvodem pro používání frameworku pro záznamy je, že jej používá GLib a ostatní související knihovny. Když jej budete používat i vy, půjdou všechny zprávy skrz ten samý systém a mohou být zpracovány podobně.

Packit 1470ea
Packit 1470ea
    

Když chcete používat framework GLib pro záznamy, definujte pro projekt jedinečnou <link href="https://developer.gnome.org/glib/stable/glib-Message-Logging.html#G-LOG-DOMAIN:CAPS">G_LOG_DOMAIN</link>, lišící se od ostatních projektů. Ladicí zprávu zaznamenáte zavoláním g_debug("Zpráva").

Packit 1470ea
Packit 1470ea
    

V případě, že výchozí obsluha záznamů v GLib není dostačující, například když potřebujete zaznamenávané zprávy ve vlastním formátu nebo potřebujete <link xref="#journald-integration">integraci s journald</link>, nastavte obsluhu záznamů pomocí následujícího kódu:

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
  /* Když je vypnuto ladění, ignorovat ladicí zprávy. */
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
  /* Použít g_printerr() pro varování a g_print() v ostatních případech. */
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>Výjimky</title>
Packit 1470ea
Packit 1470ea
      <list>
Packit 1470ea
        <item>

Nepoužívejte g_message() v normálním kódu k výpisům. Výpisy by se měly dělat jen v nejvyšší úrovni aplikace pomocí g_print() a měly by být jen zřídkavé, tj. prováděné jen v aplikacích pro příkazový řádek.

</item>
Packit 1470ea
        <item>

Nepoužívejte g_warning() v programovém kódu knihoven. Místo toho použijte <link xref="gerror">GError</link>.

</item>
Packit 1470ea
        <item>

Obdobně, nenastavujte obsluhu záznamů v kódu knihovny. Zprávy do záznamu by měly být propagovány z kódu knihovny ven a obslouženy v obsluze záznamu v nejvyšší úrovni aplikace.

</item>
Packit 1470ea
      </list>
Packit 1470ea
    </section>
Packit 1470ea
  </section>
Packit 1470ea
Packit 1470ea
  <section id="journald-integration">
Packit 1470ea
    <title>Integrace journald</title>
Packit 1470ea
Packit 1470ea
    

Ve srovnání s tradičními záznamy ve stylu syslog, journald podporuje ukládání záznamů ve strukturované podobě, co usnadňuje následnou analýzu záznamů. Můžete přidat systemd-journal jako závislost do svého projektu a jako funkce pro obsluhu záznamů pak můžete použít <link href="http://0pointer.de/public/systemd-man/sd_journal_send.html">sd_journal_print() a sd_journal_send()</link>, na místo g_print() a g_printerr().

Packit 1470ea
Packit 1470ea
    

Další informace najdete v tomto <link href="http://0pointer.de/blog/projects/journal-submit.html">článku o záznamu do žurnálu</link>.

Packit 1470ea
  </section>
Packit 1470ea
Packit 1470ea
  <section id="log-rotation">
Packit 1470ea
    <title>Rotování záznamů</title>
Packit 1470ea
Packit 1470ea
    

Rotování záznamů je jedna z funkcí, která jde mimo rozsah systému záznamů v GLib. Mělo by být obsluhováno normálním mechanizmem systému záznamů, jako je <cmd>logrotate</cmd> nebo <cmd>systemd-journald</cmd>.

Packit 1470ea
  </section>
Packit 1470ea
</page>