2017-11-10 1 views
0

Ich möchte eine API finden, die es mir ermöglicht, einen spezifischen kanonischen Satz von Informationen in allen meinen kritischen Protokollpunkten meiner Anwendung bereitzustellen. Genauer gesagt, es wäre eine mehrzeiligen Nachricht mit den folgenden Informationen (zusätzlich zu den Grundlagen) sein:Java Logging API für detaillierte (und mehrzeilige) Logs

  1. Logging Kategorie
  2. Kurzbeschreibung Titel
  3. Beschreibung
  4. Antwortaktion (Schadensbegrenzung) meine Anwendung
  5. -Details (Ausnahme Informationen usw.)

Mit einem einzigen Multi-line-Log suchen, für e nehmen xample, etwa so:

2017-11-10 14:26:59,156 [main] WARN o.s.t.c.s.ExampleClass: 
    Caption: Unconformable data 
    Description: The data provided from the X datasource in order to perform Y operation could not be translated 
    Response Action: Application will discard unusable data into this component's DLQ 
    Details: The data string "x" was not of expected Integer type 
     <Some stacktrace>.... 

Dies ist eine ausführliche Erklärung, die über genau das sehr informativ sein würde, was passiert ist, wo es aufgetreten ist, und das, was die Anwendung in Reaktion auf das Ereignis der Ausnahme machen.

Das nächste, was ich finden konnte, war die JBoss Logging API und ein Beispiel für einen Code, den ich in der ActiveMQ Artemis source gefunden habe. Das Nachrichtenformat Erklärung kann wie so in einer einzigen Datei definiert werden:

@LogMessage(level = Logger.Level.WARN) 
    @Message(id = 202008, value = "Failed to check Address list {0}.", 
     format = Message.Format.MESSAGE_FORMAT) 
    void failedToParseAddressList(@Cause Exception e, String addressList); 

Und man würde einen line with this message in ihrem Code durch Schreiben log:

ActiveMQUtilLogger.LOGGER.failedToParseAddressList(e, addressList); 

, die am nächsten, das ich zu dem, was finden konnte ich war auf der Suche nach. Sehr cool. Ich benutze JBoss jedoch nicht (und möchte auch nicht in diese API eindringen).

Ich kann LOG4J verwenden, die eine StructuredDataMessage and Structured Data Lookup hat, die in einem Layout verwendet werden kann, und ich werde standardmäßig verwenden; Mein Code könnte an einige StructuredDataMessage Fabrik delegieren, um dies zu lösen. Es ist jedoch ein bisschen sperriger als mit dieser JBoss-API.

Hat jemand irgendwelche Vorschläge für dieses Problem - ob es eine andere API, ein Codemuster oder ein raffinierter Trick ist?

+0

Laufen Sie in einer Art Container? Sie könnten es wahrscheinlich mit einem Muster tun, aber es würde wahrscheinlich von dem Log-Manager abhängen, den Sie verwenden. –

Antwort

1

Sie haben keine spezifischen Gründe angegeben, warum Sie log4j2 nicht verwenden würden, also würde ich vorschlagen, diesen Weg zu gehen. Wie Sie darauf hinweisen, bietet es die StructuredDataMessage, die Sie verwenden können, um Ihre Bedürfnisse zu erfüllen. In diesem Fall würde ich jedoch vorschlagen, MapMessage zu verwenden, da Ihr Beispiel keine id und type Elemente enthält, die in die Klasse StructuredDataMessage integriert sind.

Hier einige kurze Beispielcode:

import org.apache.logging.log4j.LogManager; 
import org.apache.logging.log4j.Logger; 
import org.apache.logging.log4j.message.MapMessage; 

public class MapMessageExample { 

    private static final Logger log = LogManager.getLogger(); 

    public static void main(String[] args){ 
     log.info(buildMsg("My title", "This is the description", 
       "No response needed", "Some details here"));   
    } 

    // This could be moved into a factory class 
    public static MapMessage buildMsg(String title, String description, 
      String responseAction, String details) 
    { 
     MapMessage mapMsg = new MapMessage(); 
     mapMsg.put("title", title); 
     mapMsg.put("desc", description); 
     mapMsg.put("response", responseAction); 
     mapMsg.put("details", details); 
     return mapMsg; 
    } 
} 

und ein log4j2.XML-Konfigurationsdatei mit ihm zu gehen zusammen:

<?xml version="1.0" encoding="UTF-8"?> 
<Configuration status="WARN"> 
    <Appenders> 
     <Console name="Console" target="SYSTEM_OUT"> 
      <PatternLayout pattern="%d{HH:mm:ss.SSS} [%M] %-5level %logger{36}%n\tCaption: ${map:title}%n\tDescription: ${map:desc}%n\tResponse Action: ${map:response}%n\tDetails: ${map:details}%n" /> 
     </Console> 
    </Appenders> 

    <Loggers> 
     <Root level="debug"> 
      <AppenderRef ref="Console" /> 
     </Root> 
    </Loggers> 
</Configuration> 

Hier einige Beispielausgabe:

00:40:45.810 [main] INFO example.MapMessageExample 
    Caption: My title 
    Description: This is the description 
    Response Action: No response needed 
    Details: Some details here 

Einige abschließende Gedanken:

meinen Code zu einem gewissen StructuredDataMessage Fabrik delegieren könnte dies zu lösen

Ich stimme zu, das Fabrikmuster wäre ein guter cho Eis hier. Wie ich im Beispielcode kommentierte, konnten Sie die buildMsg Methode zu einer Fabrikklasse verschieben.

Es ist jedoch ein bisschen sperriger als mit dieser JBoss API.

Ich sehe nicht wirklich, wie es sperriger ist. Wenn Sie feststellen, dass sich in der Regel nur ein oder zwei der Einträge in MapMessage ändern, können Sie ganz einfach sehr spezifische Methoden schreiben, die der von Ihnen erwähnten API ähneln. Um das obige Beispiel hinzu:

public static MapMessage reallySpecificLogMessage(String details){ 
    return buildMsg("My specific message title", "My specific description", 
      "My specific response action", details); 
} 

würden Sie wollen wahrscheinlich zuweisen Konstanten auf die Saiten in diesem Verfahren verwendet wird, aber wie gesagt das ist nur ein kleines Beispiel.

+0

Ja, ich dachte, ich würde es einfach so benutzen, aber ich wollte sehen, ob es da draußen noch andere Ideen gibt. Vielen Dank – Dovmo