Personalización de 1.6.x Agente de registro para admitir el análisis sintáctico multilínea personalizado para aplicaciones Java con Log4j en entornos no orquestados

Este tutorial muestra cómo configurar el manejo de registros multilínea IBM® Cloud Logs Agente de registro para una aplicación Java utilizando el Log4j logging framework. Esta configuración es para entornos no orquestados, por ejemplo Linux y Windows, y modifica el archivo de configuración. Esta configuración garantiza que las trazas de pila y los registros multilínea se agrupen correctamente en IBM Cloud Logs.

Este tutorial requiere la versión IBM Cloud Logs Agente de registro 1.6.2 o posterior.

Antes de empezar

Antes de empezar a utilizar este tutorial, revise la siguiente información para comprender los conceptos de Agente de registro y multilínea.

Este tutorial también asume que usted tiene:

  • Una instancia de IBM Cloud Logs aprovisionada y configurada.

  • El Agente de registro desplegado en un entorno no orquestado.

Los archivos de configuración de este tutorial se encuentran en el lugar donde se descargaron los archivos del paquete al instalar Agente de registro.

Ejemplo de configuración de Log4j

Log4j Supongamos que el registro de su aplicación Java en la consola (stdout) es similar al siguiente:

<?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>

Esta configuración muestra los registros en el formato: yyyy-MM-dd HH:mm:ss.SSS [thread] LEVEL logger - message seguido de una nueva línea. Los mensajes multilínea, como las trazas de pila, aparecerán en líneas posteriores sin prefijo de fecha y hora. Por ejemplo:

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) [?:?]

Configuración manual del análisis sintáctico multilínea mediante un archivo de configuración

Si configura Agente de registro manualmente mediante un archivo de configuración, puede configurar el análisis multilínea editando el archivo de configuración Agente de registro correspondiente.

Es importante que el patrón definido en el archivo log4j.xml coincida con el regex del analizador multilínea para garantizar una agrupación correcta de los registros.

Definir el analizador sintáctico multilínea

Defina su analizador multilínea personalizado que coincida con el patrón de salida Log4j. La expresión regular identifica las líneas que comienzan con la marca de tiempo como nuevas entradas y trata las líneas posteriores sin marca de tiempo como continuaciones de la entrada anterior. Añádalo a su archivo Agente de registro parsers.conf.

Ejemplo:

[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 asume que cada nueva línea de registro comienza con una marca de tiempo en el formato yyyy-MM-dd HH:mm:ss.SSS. La primera regla captura las líneas de inicio con marcas de tiempo y pasa a un estado de continuación. La segunda regla coincide con cualquier línea que no empiece por una marca de tiempo.

Este enfoque es sólo un ejemplo para mostrarle cómo asegurarse de que las líneas de registro multilínea, como Java stack traces y excepciones, se agrupan como una única entrada de registro antes de reenviarlas a IBM Cloud Logs. Hay diferentes maneras de conseguir lo mismo.

Aplicar el analizador sintáctico con el filtro multilínea

Añada un filtro a su archivo Agente de registro filters.conf para aplicar el analizador personalizado a los registros que coincidan con las etiquetas de su aplicación.

Por ejemplo:

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

Reinicie el agente

Tras actualizar el mapa de configuración, reinicie el agente.

  • Linux Para entornos Linux, ejecute:

    systemctl daemon-reload && systemctl restart fluent-bit
    
  • Windows Para entornos Windows, ejecute:

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

Verifique sus registros multilínea

Acceda a su instancia IBM Cloud Logs y confirme que sus entradas multilínea (por ejemplo, stack traces) están agrupadas correctamente.

  1. Acceda a su instancia IBM Cloud Logs.

  2. Uso del icono de registros Explorar registros y verifique que sus entradas de varias líneas estén agrupadas correctamente.

    Los datos de registro agrupados se incluyen en el campo log.