Personalizzazione di 1.6.x Agent di registrazione per supportare l'analisi multilinea personalizzata per le applicazioni Java con Log4j in ambienti non orchestrati

Questa esercitazione mostra come configurare la gestione dei log multilinea di IBM® Cloud Logs Agent di registrazione per un'applicazione Java utilizzando il framework Log4j framework per il logging. Questa configurazione è per ambienti non orchestrati, ad esempio Linux e Windows, e modifica il file di configurazione. Questa configurazione assicura che le tracce dello stack e i log multilinea siano raggruppati correttamente in IBM Cloud Logs.

Questa esercitazione richiede il programma IBM Cloud Logs Agent di registrazione 1.6.2 o successivo.

Prima di iniziare

Prima di iniziare a utilizzare questa esercitazione, è necessario rivedere le seguenti informazioni per comprendere i concetti di Agent di registrazione e multilinea.

Questa esercitazione presuppone anche che siate in possesso di:

  • Un'istanza di IBM Cloud Logs è stata fornita e configurata.

  • Il sito Agent di registrazione è stato implementato in un ambiente non orchestrato.

I file di configurazione di questa esercitazione si trovano nel punto in cui sono stati scaricati i file del pacchetto al momento dell'installazione di Agent di registrazione.

Esempio di configurazione di Log4j

Supponiamo che l'applicazione Java Log4j da registrare nella console (stdout) sia simile alla seguente:

<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN">
    <Appenders>
        <Console name="Console" target="SYSTEM_OUT">
            <PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n" />
        </Console>
    </Appenders>
    <Loggers>
        <Root level="info">
            <AppenderRef ref="Console"/>
        </Root>
    </Loggers>
</Configuration>

Questa configurazione produce i log nel formato: yyyy-MM-dd HH:mm:ss.SSS [thread] LEVEL logger - message, seguito da una newline. I messaggi su più righe, come le tracce di stack, appariranno su righe successive senza il prefisso del timestamp. Ad esempio:

2025-07-28 10:32:15.423 [main] INFO com.example.logging.Main - Application starting up
2025-07-28 10:32:16.191 [main] INFO com.example.logging.Main - This is an info message
2025-07-18 10:32:18.801 [main] ERROR com.example.logging.Main - This is an error message
java.lang.NullPointerException: null
at com.example.logging.Main.lambda$main$3(Main.java:30) ~[java-log4j-1.0.0.jar:?]
at spark.RouteImpl$1.handle(RouteImpl.java:72) ~[java-log4j-1.0.0.jar:?]
at spark.http.matching.Routes.execute(Routes.java:61) ~[java-log4j-1.0.0.jar:?]
at spark.http.matching.MatcherFilter.doFilter(MatcherFilter.java:134) ~[java-log4j-1.0.0.jar:?]
at spark.embeddedserver.jetty.JettyHandler.doHandle(JettyHandler.java:50) ~[java-log4j-1.0.0.jar:?]
at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:1584) ~[java-log4j-1.0.0.jar:?]
at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:141) ~[java-log4j-1.0.0.jar:?]
at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:127) ~[java-log4j-1.0.0.jar:?]
at org.eclipse.jetty.server.Server.handle(Server.java:501) ~[java-log4j-1.0.0.jar:?]
at org.eclipse.jetty.server.HttpChannel.lambda$handle$1(HttpChannel.java:383) ~[java-log4j-1.0.0.jar:?]
at org.eclipse.jetty.server.HttpChannel.dispatch(HttpChannel.java:556) [java-log4j-1.0.0.jar:?]
at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:375) [java-log4j-1.0.0.jar:?]
at org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:273) [java-log4j-1.0.0.jar:?]
at org.eclipse.jetty.io.AbstractConnection$ReadCallback.succeeded(AbstractConnection.java:311) [java-log4j-1.0.0.jar:?]
at org.eclipse.jetty.io.FillInterest.fillable(FillInterest.java:105) [java-log4j-1.0.0.jar:?]
at org.eclipse.jetty.io.ChannelEndPoint$1.run(ChannelEndPoint.java:104) [java-log4j-1.0.0.jar:?]
at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:806) [java-log4j-1.0.0.jar:?]
at org.eclipse.jetty.util.thread.QueuedThreadPool$Runner.run(QueuedThreadPool.java:938) [java-log4j-1.0.0.jar:?]
at java.lang.Thread.run(Unknown Source) [?:?]

Configurazione manuale del parsing multilinea tramite un file di configurazione

Se si configura Agent di registrazione manualmente tramite un file di configurazione, è possibile configurare l'analisi multilinea modificando il file di configurazione appropriato Agent di registrazione.

È importante che lo schema definito nel file log4j.xml sia allineato con la regex del parser multilinea per garantire un corretto raggruppamento dei registri.

Definire il parser multilinea

Definire un parser multilinea personalizzato che corrisponda allo schema di output Log4j. La regex identifica le righe che iniziano con il timestamp come nuove voci e tratta le righe successive senza timestamp come continuazione della voce precedente. Aggiungete questo al vostro file Agent di registrazione parsers.conf.

Esempio:

[MULTILINE_PARSER]
    Name            multiline-java-example
    Type            regex
    Flush_timeout   500
    Rule            "start_state"     "/^(\d+-\d+-\d+ \d+:\d+:\d+\.\d+)(.*)$/"     "cont"
    Rule            "cont"            "/^(?!\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}\.\d{3}).*$/"     "cont"

La regex presuppone che ogni nuova riga di log inizi con un timestamp nel formato yyyy-MM-dd HH:mm:ss.SSS. La prima regola cattura le righe iniziali con i timestamp e passa a uno stato di continuazione. La seconda regola corrisponde a qualsiasi riga che non inizia con un timestamp.

Questo approccio è solo un esempio per mostrare come garantire che le righe di log multilinea, come le tracce dello stack Java e le eccezioni, siano raggruppate come una singola voce di log prima di inoltrarle a IBM Cloud Logs. Ci sono diversi modi per ottenere la stessa cosa.

Applicare il parser con il filtro multilinea

Aggiungere un filtro al file Agent di registrazione filters.conf per applicare il parser personalizzato ai log che corrispondono ai tag dell'applicazione.

Ad esempio:

[FILTER]
    Name              multiline
    Match             kube.*
    Multiline.key_content log
    Multiline.parser  multiline-java-example
    Emitter_Name      multiline-java

Riavviare l'agent

Dopo aver aggiornato la mappa di configurazione, riavviare l'agente.

  • Linux Per gli ambienti Linux, eseguire:

    systemctl daemon-reload && systemctl restart fluent-bit
    
  • Windows Per gli ambienti Windows, eseguire:

    sc.exe stop fluent-bit && sc.exe start fluent-bit
    

Verificare i log multilinea

Accedere all'istanza di IBM Cloud Logs e verificare che le voci multilinea (ad esempio, le tracce di stack) siano raggruppate correttamente.

  1. Accedere all'istanza IBM Cloud Logs.

  2. Utilizzando la vista Registri Icona Esplora registri, verificare che le voci multilinea siano raggruppate correttamente.

    I dati di log raggruppati sono inclusi nel campo log.