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. ()
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);
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.
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ů 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