Philip Withnall philip.withnall@collabora.co.uk 2015 Ladicí záznamy a informační výstup z knihoven a programů Záznamy (log) Shrnutí

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.

Místo záznamů přímo do stderr a stdout používejte framework GLib pro záznamy. ()

Když může být projekt závislý na systemd, zvažte přímé použití záznamů v žurnálu. ()

Neimplementujte rotaci a mazání záznamů. Ponechte to na systémových službách. ()

Framework GLib pro záznamy

GLib poskytuje framework pro zaznamenávání, který je postavený na funkci g_log() spolu s obalujícími funkcemi g_debug(), g_message(), g_warning() a g_error() pro větší pohodlí. Tento framework má pár užitečných vlastností:

Programové přesměrování záznamu zpráv pomocí g_log_set_handler().

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

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.

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

Uvedeným postupům byste měli dát přednost před funkcemi jako jsou printf(), g_print() a g_printerr(), 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ší.

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ě.

Když chcete používat framework GLib pro záznamy, definujte pro projekt jedinečnou G_LOG_DOMAIN, lišící se od ostatních projektů. Ladicí zprávu zaznamenáte zavoláním g_debug("Zpráva").

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 integraci s journald, nastavte obsluhu záznamů pomocí následujícího kódu:

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; /* Když je vypnuto ladění, ignorovat ladicí zprávy. */ if (!debug_enabled && (log_level & G_LOG_LEVEL_DEBUG)) { return; } log_level_str = log_level_to_string (log_level & G_LOG_LEVEL_MASK); /* Použít g_printerr() pro varování a g_print() v ostatních případech. */ if (flags <= 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);
Výjimky

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.

Nepoužívejte g_warning() v programovém kódu knihoven. Místo toho použijte GError.

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.

Integrace journald

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 sd_journal_print() a sd_journal_send(), na místo g_print() a g_printerr().

Další informace najdete v tomto článku o záznamu do žurnálu.

Rotování záznamů

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 logrotate nebo systemd-journald.