čtvrtek 10. října 2013

Časté chyby při logování - chybějící kontext a hint

Logování (logging) a jeho výstup je mnohdy jediným prostředkem k diagnostikovávání problémů, které vznikají za běhu aplikace. Jednou z chyb, které se často dopouštíme, je chybějící kontext, který umožňuje i bez znalosti zdrojového kódu určit k čemu mohlo dojít. Budu to vysvětlovat na účelově sestrojeném kousku kódu s nákupním košíkem.

public class ShoppingCart {
  private List items;

  public void addItem(Object o) {
    if(o instanceof Item) {
      items.add(o);
    } else {
      LOGGER.warn("Object is not of type Item");
    }
  }
}

Problém té logovací hlášky je v tom, že říká jenom to co se stalo, ale to je informace, která je vám užitečná pouze pokud máte zdrojový kód a chápete důsledky toho k čemu došlo. Pokud dojde k nějakému problému, typicky o několik pater abstrakce výše, těžko se vám bude hledat příčina. Správně by ta logovací hláška měla říkat nejenom to k čemu došlo, ale i jaký to má dopad.


LOGGER.warn("Cannot add item {} to shopping basket because is not of type Item.", o);

Kromě původní informace nám do logovací zprávy přibylo vysvětlení k čemu došlo (není možné přidat položku), ze kterého plyne jasný důsledek (v košíku nebude). Pokud například víme, jak k takové situaci, došlo je dobré to rovněž zalogovat. Může to být hint, který ušetří spoustu práce.


LOGGER.warn("Cannot add item {} to shopping basket because is not of type Item. It may be caused by using an old version of client. Please check the log, version 2.0 or higher is required by add item operation.", o);

Pokud hrozí zanesení logu těmito logovacími zprávami, a vy potřebujete ušetřit místo, lze přidat vysvětlení ve formě odkazu ať již klíčem do slovníku logovacích událostí a nebo na konkrétní stránku, kde lze získat ten samý kontext.


LOGGER.warn("Cannot add item {} to shopping basket because is not of type Item. See WARN-123", o);

LOGGER.warn("Cannot add item {} to shopping basket because is not of type Item. See http://bit.ly/1g3eFoK", o);

S trochou snahy se dá velmi jednoduše vytvořit kontext, pomocí kterého i člověk neznalý zdrojového kódu pochopí k čemu došlo, jaký to má dopad a ideálně jak k tomu mohlo dojít. Nepodceňujte logování ani pokud máte vždy zdrojové kódy k dispozici. V našem modelovém případě nám hint slouží jako permanentní vysvětlení nějakého externí podmínky, kterou bychom si po nějakém čase už těžko vybavili - není přímo zřejmá z kódu vlastní třídy.


Starší články na téma logování: Pár tipů na lepší logy