Bez wątpienia logowanie zdarzeń to istotna praktyka. Logi są nieocenioną pomocą, w sytuacji, gdy próbujemy zidentyfikować potencjalne problemy jakie wystąpiły w czasie działania aplikacji.

Niestety, w praktyce logi logom nie są równe. Czasem mamy ich w nadmiarze, a czasem zbyt mało, aby znaleźć przyczynę błędu. Niekiedy logi są zbyt precyzyjne, a niekiedy zbyt szczątkowe w informacje. To wciąż otwarty temat.

W tej notce chciałbym poruszyć kwestię kiedy warto logować.

Czy na przykład poniższa funkcja, która odpowiada na pytanie, czy elementy są posortowane, powinna cokolwiek logować?

def ordered(xs):
    for i in len(range(xs) - 1):
        if xs[i] > xs[i+1]:
            return False
    return True

Moim zdaniem nie, ponieważ ta funkcja jest oderwana od kontekstu użycia i trudno oczekiwać, by logowanie z jej wnętrza wnosiło większą wartość.

A teraz trochę trudniejszy przypadek. Mamy tu przykład klasy, która odzwierciedla pewne biznesowe wymagania. Czy w tej sytuacji warto włączyć logowanie?

class Battery:

    def __init__(self, value, limit):
    	if limit < 0:
            raise ValueError('Required positive limit')
        
        self._value = 0
        self._limit = limit
        
        self.charge(value)

    def charge(self, delta):
        if delta < 0:
            raise ValueError('Required non-negative value')
        self._value = min(self._value + delta, self._limit)

    @property
    def percents(self):
        return self._value / self._limit * 100

Mimo biznesowej logiki nie zastosowałbym tutaj żadnego logowania, ponieważ ta klasa jest oderwana od jej docelowego przypadku użycia. Warto zwrócić uwagę, że trudniejsze sytuacje, które mogą wpłynąć negatywnie na jej stan, są chronione poprzez wyjątki.

Kiedy warto logować?

Najlepszym miejscem do logowania są procedury biznesowe, czyli funkcje na najwyższym poziomie, które odpowiadają za realizację biznesowych zadań. To właśnie tam dysponujemy kontekstem na podstawie którego warto logować zdarzenia jakie mają miejsce w aplikacji.