Der Kontext: Wir arbeiten an einer Multithread-Anwendung (Linux-C), die einem Pipeline-Modell folgt.
Jedes Modul verfügt über einen privaten Thread und gekapselte Objekte, die Daten verarbeiten. und jede Stufe hat eine Standardform des Datenaustauschs mit der nächsten Einheit.
Die Anwendung ist frei von Speicherverlusten und ist threadsicher, indem Sperren an dem Punkt verwendet werden, an dem sie Daten austauschen. Die Gesamtzahl der Threads beträgt ungefähr 15 und jeder Thread kann 1 bis 4 Objekte haben. Erstellen von etwa 25 bis 30 ungeraden Objekten, für die alle eine kritische Protokollierung erforderlich ist.
Die meisten Diskussionen habe ich über verschiedene Ebenen wie in Log4J und seinen anderen Übersetzungen gesehen. Die wirklich großen Fragen sind, wie die gesamte Protokollierung wirklich ablaufen soll.
Ein Ansatz ist , alle lokale Protokollierung tut fprintf
zu stderr
. Der stderr wird zu einer Datei umgeleitet. Dieser Ansatz ist sehr schlecht, wenn die Protokolle zu groß werden.
Wenn alle Objekte ihre einzelnen Logger instanziieren - (ungefähr 30-40 von ihnen), gibt es zu viele Dateien. Und anders als oben wird man nicht die Idee einer wahren Reihenfolge der Ereignisse haben. Zeitstempelung ist eine Möglichkeit - aber es ist immer noch ein Chaos, sie zusammenzustellen.
Wenn es ein einzelnes globales Logger-Muster (Singleton-Muster) gibt, blockiert es indirekt so viele Threads, während einer damit beschäftigt ist, Protokolle zu erstellen. Dies ist nicht akzeptabel, wenn die Verarbeitung der Threads schwer ist.
Was sollte also der ideale Weg sein, um die Protokollierungsobjekte zu strukturieren? Was sind einige der Best Practices in tatsächlichen Großanwendungen?
Ich würde auch gerne von einigen der realen Designs von Großanwendungen lernen, um Inspirationen zu erhalten!
======
BEARBEITEN:
Basierend auf beiden Antworten hier ist die Frage, die mir jetzt bleibt:
Was ist die beste Vorgehensweise beim Zuweisen von Loggern (Protokollierungswarteschlangen) zum Objekt: Sollten sie global_api () aufrufen oder sollte ihnen der Logger im Konstruktor zugewiesen werden. Wenn sich die Objekte in einer tiefen Hierarchie befinden, wird dieser spätere Ansatz mühsam. Wenn sie global_api () aufrufen, ist dies eine Art Kopplung mit der Anwendung. Wenn Sie also versuchen, dieses Objekt in einer anderen Anwendung zu verwenden, wird diese Abhängigkeit ausgelöst. Gibt es dafür einen saubereren Weg?