2017-04-06 6 views
3

Ich bin auf der Suche nach der Anfrage und Antwort auf einen Web-Service zu protokollieren. Ich verwende slf4j mit der zugrunde liegenden log4j2-Implementierung. Meine Logger-Anweisung sieht wie folgt aus.slf4j-log4j konvertiert Objekte in eine Zeichenfolge vor der Übergabe an Asynchronus Logger

LOGGER.info ("{}", neues CustomObject (Anfrage, Antwort, param1, param2));

Ich habe die toString-Methoden in allen erforderlichen Objekten und in der CustomObject-Klasse implementiert, um alle Attribute dieses Objekts zu protokollieren.

Ich sehe, dass die ToString-Methode des CustomObject aufgerufen wird, bevor es die Protokollnachricht an den Asynch-Logger übergibt.

Gibt es trotzdem, dass der Aufruf der Serialisierung/toString-Methode des benutzerdefinierten Objekts verschoben wird, wenn die eigentliche Protokollierung stattfindet?

+0

War meine Antwort akzeptabel/nützlich? –

Antwort

3

Dies ist beabsichtigt: Wenn ein Objekt protokolliert wird, ist es möglich, dass es mutiert wird, bevor der Hintergrundthread es protokollieren kann, und Sie würden mit einem Protokolleintrag enden, der anders ist, als Sie beabsichtigten.

In Ihrem Beispiel enthält Ihre Anwendung keinen Verweis auf das CustomObject, daher kann sie nicht geändert werden, aber Log4j2 kann das nicht wissen, daher ist der konservative Ansatz erforderlich.

Es gibt eine system property dies auszuschalten, wobei jedoch bedeutet dies alle Objekte protokolliert müssen effektiv unveränderlich sein oder Sie werden Ihre Protokolle liegen Sie ... (ich bin auch nicht 100% sicher, dass die finden Systemeigenschaft funktioniert noch, seit Log4j2 in Version 2.6 müllfrei wurde.)

Update (2017-12-09): Die Systemeigenschaft funktioniert immer noch in Post 2.6-Versionen. (Ich würde jedoch nicht empfehlen, die Nachricht im Hintergrund-Thread darzustellen, es sei denn, Sie sind sehr zuversichtlich, dass die Anwendung die protokollierten Objekte nicht ändert.)

+0

Das hat funktioniert, danke! Die toString-Methode wurde nicht aufgerufen, nachdem Sie diese log4j.format.msg.async auf true festgelegt haben. Es stimmt, dass die Objektattribute, wenn sie vom Hauptthread geändert werden, für einen Toss aus der Protokollierung gehen. Für meinen Anwendungsfall funktioniert das jedoch. –

+0

Wenn die Antwort nützlich war, können Sie sie annehmen und/oder aufwerten? –

+0

Möchte hinzufügen, dass, wenn das System andere Logger definiert hat, es auch für diese Logger anwendbar wäre. Und zu diesem Zeitpunkt müssen wir vorsichtig sein, veränderbare Objekte zu protokollieren. –

Verwandte Themen