Archivo de configuración de configuración de aprendizaje del marco de registro de inicio de sesión (3)

Configuración en la inicialización

Insertar solicitudes de registro en el código de la aplicación requiere bastante planificación y esfuerzo. La observación muestra que aproximadamente el cuatro por ciento del código está dedicado al registro. En consecuencia, incluso una aplicación de tamaño moderado contendrá miles de declaraciones de registro integradas en su código. Dado su número, necesitamos herramientas para gestionar estas declaraciones de registro.

El inicio de sesión se puede configurar mediante programación o con un script de configuración expresado en formato XML, Groovy o modelo serializado. Por cierto, los usuarios existentes de log4j pueden convertir sus archivos log4j.properties a logback.xml utilizando nuestra aplicación web PropertiesTranslator.

Insertar solicitudes de registro en el código de la aplicación requiere una planificación y un esfuerzo considerables. La observación muestra que alrededor del 4% del código está dedicado al registro. Por lo tanto, incluso una aplicación de tamaño moderado puede tener miles de declaraciones de registro en su código. Dado su volumen, necesitamos herramientas para gestionar estas declaraciones de registro.
El inicio de sesión se puede configurar mediante programación o mediante scripts de configuración expresados ​​en formatos XML, Groovy o modelo serializado. Por cierto, los usuarios existentes de log4j pueden utilizar nuestra aplicación web PropertiesTranslator para convertir sus archivos log4j.properties a logback.xml.

Comencemos discutiendo los pasos de inicialización que sigue el inicio de sesión para intentar configurarse:

  1. Logback buscará proveedores de Configuradores personalizados utilizando
    la función de carga de proveedores de servicios. Si se encuentra dicho proveedor personalizado
    , tiene prioridad sobre los propios configuradores de Logback, por ejemplo,
    DefaultJoranConfigurator (ver más abajo). Un Configurador personalizado es una
    implementación de la interfaz ch.qos.logback.classic.spi.Configurator.
    Los configuradores personalizados se buscan buscando recursos de archivos
    ubicados en
    META-INF/services/ch.qos.logback.classic.spi.Configurator. El
    contenido de este archivo debe especificar el nombre de clase completo
    de la implementación del Configurador deseada.
  2. DESDE 1.3.9/1.4.9 Si no se encontró ningún configurador personalizado proporcionado por el usuario
    en el paso anterior, el inicio de sesión creará una instancia de un
    SerializedModelConfigurator.
    • Si la propiedad del sistema “logback.serializedModelFile” está configurada,
    SerializedModelConfigurator intentará localizar el archivo especificado
    en la propiedad del sistema antes mencionada. Si se puede
    localizar el archivo designado, se leerá e interpretará para su configuración.
    • Si no se configuró la propiedad del sistema antes mencionada o si
    no se pudo encontrar el archivo designado, SerializedModelConfigurator buscará
    el archivo del modelo de configuración serializado logback-test.scmo
    en el classpath. Si se puede localizar este archivo, será leído y
    interpretado para la configuración.
    • Si no se puede encontrar el archivo mencionado anteriormente,
    SerializedModelConfigurator buscará el
    archivo del modelo de configuración serializado logback.scmo en el classpath.
    • Si no se puede localizar ningún archivo de modelo de configuración serializado,
    SerializedModelConfigurator regresará con un estado de ejecución
    solicitando que
    se invoque el siguiente configurador disponible, es decir, DefaultJoranConfigurator.
    La configuración desde un archivo de modelo serializado se ejecuta más rápido y
    no requiere bibliotecas XML. Junto con GraalVM, esto puede
    generar ejecutables más pequeños que se inician más rápido.
  3. PASO NOMINAL Si los configuradores anteriores no pudieron ubicar los recursos requeridos, se creará e invocará
    una instancia de DefaultJoranConfigurator . • Si la propiedad del sistema “logback.configurationFile” está configurada, DefaultJoranConfigurator intentará localizar el archivo especificado en la propiedad del sistema antes mencionada. Si se puede localizar este archivo, se leerá e interpretará para su configuración. • Si el paso anterior falla, DefaultJoranConfigurator intentará localizar el archivo de configuración “logback-test.xml” en el classpath. Si se puede localizar este archivo, se leerá e interpretará para su configuración. • Si no se encuentra dicho archivo, intentará localizar la configuración










    archivo “logback.xml” en el classpath. Si se puede localizar este archivo, se
    leerá e interpretará para su configuración. Tenga en cuenta que este es
    el paso de configuración nominal.
    • Si no se pudo localizar ningún archivo de configuración,
    DefaultJoranConfigurator regresará con un estado de ejecución solicitando
    que se invoque el siguiente configurador disponible, es decir, BasicConfigurator
    .

Si nada de lo anterior tiene éxito, logback-classic se configurará usando BasicConfigurator, lo que hará que la salida del registro se dirija a la consola.

2. Hay un SerializedModelConfigurator adicional de 1.3.9 y 1.4.9.
Insertar descripción de la imagen aquí
Tenga en cuenta que la versión superior de logback 1.4.9 lo tiene, pero la versión anterior 1.2.4 no tenía las clases serializadas y predeterminadas joran.

Configurar automáticamente el inicio de sesión

La forma más sencilla de configurar el inicio de sesión es permitir que el inicio de sesión vuelva a su configuración predeterminada. Veamos cómo se hace esto en una aplicación imaginaria llamada MyApp1.
前面有点复杂直接看demo
(logback-examples/src/main/java/chapters/configuration/MyApp1.java)

package chapters.configuration;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class MyApp1 {
 final static Logger logger = LoggerFactory.getLogger(MyApp1.class);

 public static void main(String[] args) {
   logger.info("Entering application.");

   Foo foo = new Foo();
   foo.doIt();
   logger.info("Exiting application.");
 }
}

(ejemplos de inicio de sesión/src/main/java/chapters/configuration/Foo.java)

package chapters.configuration;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class Foo {
  static final Logger logger = LoggerFactory.getLogger(Foo.class);

  public void doIt() {
    logger.debug("Did it again!");
  }
}

tarro de importación de pompones

        <dependency>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-classic</artifactId>
            <version>${logback.version}</version>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
            <version>2.0.7</version>
        </dependency>

Imprimir resultados

17:18:04.095 [main] INFO com.chenchi.log.chapter3.MyApp1 -- Entering application.
17:18:04.108 [main] DEBUG com.chenchi.log.chapter3.Foo -- Did it again!
17:18:04.108 [main] INFO com.chenchi.log.chapter3.MyApp1 -- Exiting application.

Suponiendo que los archivos de configuración logback-test.xml o logback.xml no estén presentes, logback invocará de forma predeterminada BasicConfigurator, que establecerá una configuración mínima. Esta configuración mínima consta de un ConsoleAppender adjunto al registrador raíz. La salida se formatea utilizando un PatternLayoutEncoder configurado con el patrón %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} -%kvp- %msg%n. Además, de forma predeterminada, al registrador raíz se le asigna el nivel DEBUG.

Suponiendo que el archivo de configuración logback-test.xml o logback.xml no existe, logback llamará de forma predeterminada a BasicConfigurator, que establecerá la configuración mínima. Esta configuración mínima incluye un archivo adjunto de consola que se conecta al registrador raíz. La salida se formatea utilizando un PatternLayoutEncoder configurado en el patrón %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} -%kvp- %msg%n. Además, de forma predeterminada, al registrador raíz se le asigna el nivel DEBUG.
Insertar descripción de la imagen aquí
Las tres secciones establecen el diseño y el nivel del anexo respectivamente.

Configuración con logback-test.xml o logback.xml

(ejemplos-registro-de-registro/src/main/resources/chapters/configuration/sample0.xml)

<configuration>
<!-- STDOUT 这个是appendername 可以随便取 sout print啥都行-->
<!-- ch.qos.logback.core.ConsoleAppender 是具体的类 一般用自带的 也可以自定义-->
  <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
    <!-- encoders are assigned the type
         ch.qos.logback.classic.encoder.PatternLayoutEncoder by default -->
    <encoder>
      <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} -%kvp- %msg%n</pattern>
    </encoder>
  </appender>

  <root level="debug">
    <appender-ref ref="STDOUT" />
  </root>
</configuration>

Después de haber cambiado el nombre de sample0.xml a logback.xml (o logback-test.xml), colóquelo en un directorio accesible desde la ruta de clase. La ejecución de la aplicación MyApp1 debería dar resultados idénticos a su ejecución anterior. Cambió el nombre de logback.xml o
Put logback-test.xml en el classpath y ejecútelo nuevamente.

Impresión automática de mensajes de estado en caso de advertencia o error.

Si se produce una advertencia o un error al analizar el archivo de configuración, Logback imprimirá automáticamente sus mensajes de estado internos en la consola.

public static void main(String[] args) {
  // assume SLF4J is bound to logback in the current environment
  LoggerContext lc = (LoggerContext) LoggerFactory.getILoggerFactory();
  // print logback's internal status
  StatusPrinter.print(lc);
  ...
}

Imprimir registro

17:29:25.146 [main] INFO  [com.chenchi.log.chapter3.MyApp2] [-]- Entering application.
17:29:25.160 [main] DEBUG [com.chenchi.log.chapter3.Foo] [-]- Did it again!
17:29:25.160 [main] INFO  [com.chenchi.log.chapter3.MyApp2] [-]- Exiting application.
17:29:24,747 |-INFO in ch.qos.logback.classic.LoggerContext[default] - This is logback-classic version 1.3.9
17:29:24,751 |-INFO in ch.qos.logback.classic.util.ContextInitializer@617faa95 - No custom configurators were discovered as a service.
17:29:24,751 |-INFO in ch.qos.logback.classic.util.ContextInitializer@617faa95 - Trying to configure with ch.qos.logback.classic.joran.SerializedModelConfigurator
17:29:24,752 |-INFO in ch.qos.logback.classic.util.ContextInitializer@617faa95 - Constructed configurator of type class ch.qos.logback.classic.joran.SerializedModelConfigurator
17:29:24,761 |-INFO in ch.qos.logback.classic.LoggerContext[default] - Could NOT find resource [logback-test.scmo]
17:29:24,761 |-INFO in ch.qos.logback.classic.LoggerContext[default] - Could NOT find resource [logback.scmo]
17:29:24,762 |-INFO in ch.qos.logback.classic.util.ContextInitializer@617faa95 - ch.qos.logback.classic.joran.SerializedModelConfigurator.configure() call lasted 10 milliseconds. ExecutionStatus=INVOKE_NEXT_IF_ANY
17:29:24,762 |-INFO in ch.qos.logback.classic.util.ContextInitializer@617faa95 - Trying to configure with ch.qos.logback.classic.util.DefaultJoranConfigurator
17:29:24,763 |-INFO in ch.qos.logback.classic.util.ContextInitializer@617faa95 - Constructed configurator of type class ch.qos.logback.classic.util.DefaultJoranConfigurator
17:29:24,763 |-INFO in ch.qos.logback.classic.LoggerContext[default] - Found resource [logback-test.xml] at [file:/D:/install/code/learning/bigdata_learining/log/logback/target/classes/logback-test.xml]
17:29:25,054 |-INFO in ch.qos.logback.core.model.processor.AppenderModelHandler - Processing appender named [STDOUT]
17:29:25,054 |-INFO in ch.qos.logback.core.model.processor.AppenderModelHandler - About to instantiate appender of type [ch.qos.logback.core.ConsoleAppender]
17:29:25,063 |-INFO in ch.qos.logback.core.model.processor.ImplicitModelHandler - Assuming default type [ch.qos.logback.classic.encoder.PatternLayoutEncoder] for [encoder] property
17:29:25,119 |-INFO in ch.qos.logback.classic.model.processor.RootLoggerModelHandler - Setting level of ROOT logger to DEBUG
17:29:25,119 |-INFO in ch.qos.logback.core.model.processor.AppenderRefModelHandler - Attaching appender named [STDOUT] to Logger[ROOT]
17:29:25,119 |-INFO in ch.qos.logback.core.model.processor.DefaultProcessor@1e127982 - End of configuration.
17:29:25,120 |-INFO in ch.qos.logback.classic.joran.JoranConfigurator@60c6f5b - Registering current configuration as safe fallback point
17:29:25,120 |-INFO in ch.qos.logback.classic.util.ContextInitializer@617faa95 - ch.qos.logback.classic.util.DefaultJoranConfigurator.configure() call lasted 357 milliseconds. ExecutionStatus=DO_NOT_INVOKE_NEXT_IF_ANY

Esto es adecuado para introducir a veces varios conflictos de log jar y no sabes dónde está el conflicto, o hay un montón de propiedades xml del archivo de configuración de registro y no sabes cuál funciona. Imprimir la información del kernel puede rápidamente localizarlo.

Datos de estado

Habilitar la salida de datos de estado suele ser muy útil para diagnosticar problemas de registro
(logback-examples/src/main/resources/chapters/configuration/onConsoleStatusListener.xml)
datos de estado Esto es para forzar que el contexto de impresión
sea equivalente a
LoggerContext lc = ( LoggerContext) LoggerFactory.getILoggerFactory();
// imprime el estado interno del registro
StatusPrinter.print(lc);

Recargar automáticamente el archivo de configuración tras la modificación

Esto es más útil para cargar automáticamente archivos de configuración actualizados.

<configuration scan="true" scanPeriod="30 seconds" >
  ...
</configuration> 
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class MyAppScan {
    final static Logger logger = LoggerFactory.getLogger(MyAppScan.class);

    public static void main(String[] args) throws InterruptedException {
        MyAppScan myAppScan = new MyAppScan();
        while (true){
            myAppScan.printAll();
            Thread.sleep(10000);
        }
    }
    private void printAll(){
        logger.trace("trace");
        logger.debug("debug");
        logger.info("info");
        logger.warn("warn");
        logger.error("error");
        System.out.println("==============================");
    }
}

logback.xml

<configuration scan="true" scanPeriod="15 seconds" >
        <!-- STDOUT 这个是appendername 可以随便取 sout print啥都行-->
    <!-- ch.qos.logback.core.ConsoleAppender 是具体的类 一般用自带的 也可以自定义-->
    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
        <!-- encoders are assigned the type
             ch.qos.logback.classic.encoder.PatternLayoutEncoder by default -->
        <encoder>
            <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level [%logger{36}] [-%kvp]- %msg%n</pattern>
        </encoder>
    </appender>
    <!-- status data 这个就是强行打印 context-->
    <statusListener class="ch.qos.logback.core.status.OnConsoleStatusListener" />

    <root level="error">
        <appender-ref ref="STDOUT" />
    </root>
</configuration>

Tenga en cuenta que al realizar la prueba, debe modificar el archivo xml en destino/clase porque es posible que el recurso no se compile a tiempo.
Insertar descripción de la imagen aquí

Habilitación de datos de empaquetado en seguimientos de pila

Insertar descripción de la imagen aquí
Si se le indica que lo haga, el inicio de sesión puede incluir datos empaquetados para cada línea de la línea de seguimiento de la pila que genera. Los datos de empaquetado constan del nombre y la versión del archivo jar que es el origen de la clase para la línea de seguimiento de la pila. Los datos de empaquetado son útiles para identificar problemas de control de versiones de software. Sin embargo, el costo computacional es bastante alto, especialmente en aplicaciones que frecuentemente generan excepciones.
Como instalar

<configuration packagingData="true">
  ...
</configuration>

o

 LoggerContext lc = (LoggerContext) LoggerFactory.getILoggerFactory();
  lc.setPackagingDataEnabled(true);

De repente no sé qué anomalía encontrar, pero parece que la salida del registro es más completa.

Invocando JoranConfigurator directamente

(logback-examples/src/main/java/chapters/configuration/MyApp3.java)
No veo ninguna utilidad

Detener el inicio de sesión clásico

Liberar recursos


import org.sflf4j.LoggerFactory;
import ch.qos.logback.classic.LoggerContext;
...

// assume SLF4J is bound to logback-classic in the current environment
LoggerContext loggerContext = (LoggerContext) LoggerFactory.getILoggerFactory();
loggerContext.stop();
Detener logback-classic mediante un gancho de apagado

Instalar un gancho de cierre de JVM es una forma conveniente de cerrar el inicio de sesión y liberar los recursos asociados.

<configuration debug="true">
   <!-- in the absence of the class attribute, assume
   ch.qos.logback.core.hook.DefaultShutdownHook -->
   <shutdownHook/>

   <!-- rest of the config file.. -->

</configuration>

Sintaxis del archivo de configuración

Insertar descripción de la imagen aquí

Sensibilidad entre mayúsculas y minúsculas en los nombres de las etiquetas

Si no está seguro de qué mayúsculas y minúsculas usar para un nombre de etiqueta determinado, simplemente siga la convención camelCase, que casi siempre es la convención
correcta
.

Configurar registradores o el elemento
<configuration>

  <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
    <encoder>
      <pattern>
        %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} -%kvp- %msg%n
     </pattern>
    </encoder>
  </appender>

  <logger name="chapters.configuration" level="INFO" />
  <logger name="chapters.configuration.Foo" level="DEBUG" />

  <root level="DEBUG">
    <appender-ref ref="STDOUT" />
  </root>

</configuration>

Insertar descripción de la imagen aquí
Este es el apéndice de herencia de nivel mencionado anteriormente, de hecho, también se puede heredar.

<configuration>

  <appender name="STDOUT"
   class="ch.qos.logback.core.ConsoleAppender">
   <encoder>
     <pattern>
        %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} -%kvp- %msg%n
      </pattern>
    </encoder>
  </appender>

  <logger name="chapters.configuration" level="INFO" />
 
  <!-- turn OFF all logging (children can override) -->
  <root level="OFF">
    <appender-ref ref="STDOUT" />
  </root>

</configuration>

Insertar descripción de la imagen aquí

Configurar anexos

Se configura un apéndice con el elemento, que toma dos atributos obligatorios, nombre y clase. El atributo de nombre especifica el nombre del agregador, mientras que el atributo de clase especifica el nombre completo de la clase del agregador que se va a crear una instancia. El elemento puede contener cero o un elemento, cero o más elementos y cero o más elementos. Aparte de estos tres elementos comunes, los elementos pueden contener cualquier número de elementos correspondientes a las propiedades JavaBean de la clase appender. Apoyar perfectamente cualquier propiedad de un componente de registro determinado es una de las principales fortalezas de Joran, como se analiza en un capítulo posterior. El siguiente diagrama ilustra la estructura común. Tenga en cuenta que la compatibilidad con propiedades no se muestra en el siguiente diagrama.

El appender está configurado con un elemento <appender>, que tiene dos atributos obligatorios, nombre y clase. El atributo de nombre especifica el nombre del agregador y
el atributo de clase especifica el nombre de ruta completo de la clase del agregador que se va a crear una instancia.
Un elemento <appender> puede contener cero o un elemento <layout>, cero o más elementos <encoder> y cero o más elementos <filter>. Además de estos tres elementos comunes, el elemento <appender> puede contener cualquier número de elementos que correspondan a las propiedades JavaBean de la clase appender. Apoyar perfectamente cualquier propiedad de un componente de registro determinado es una de las principales fortalezas de Joran y se discutirá en un capítulo posterior. El siguiente diagrama ilustra estructuras comunes. Tenga en cuenta que la compatibilidad con propiedades no se muestra en la imagen siguiente.
Insertar descripción de la imagen aquí

<configuration>

  <appender name="FILE" class="ch.qos.logback.core.FileAppender">
    <file>myApp.log</file>

    <encoder>
      <pattern>%date %level [%thread] %logger{10} [%file:%line] -%kvp- %msg%n</pattern>
    </encoder>
  </appender>

  <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
    <encoder>
      <pattern>%kvp %msg%n</pattern>
    </encoder>
  </appender>

  <root level="debug">
    <appender-ref ref="FILE" />
    <appender-ref ref="STDOUT" />
  </root>
</configuration>

Estos scripts de configuración definen dos apéndices llamados FILE y STDOUT.
El agregador FILE registra un archivo llamado myApp.log. El codificador es PatternLayoutEncoder, que genera la fecha, el nivel, el nombre del hilo, el nombre del registrador, el nombre del archivo y el número de línea de la solicitud de registro, el mensaje y el separador de línea.
El segundo apéndice llamado STDOUT sale a la consola. El codificador de este complemento solo genera una cadena de mensaje seguida de un separador de línea.

Los apéndices se acumulan
<configuration>

  <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
    <encoder>
      <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} -%kvp- %msg%n</pattern>
    </encoder>
  </appender>

  <logger name="chapters.configuration">
    <appender-ref ref="STDOUT" />
  </logger>

  <root level="debug">
    <appender-ref ref="STDOUT" />
  </root>
</configuration>

Insertar descripción de la imagen aquí
El registro se repetirá porque capítulos.configuration hereda la raíz, tiene una salida estándar y agrega otra.
De hecho, puede optar por no heredarla aquí.

La siguiente demostración tiene

Anulación del comportamiento acumulativo predeterminado
<configuration>

  <appender name="FILE" class="ch.qos.logback.core.FileAppender">
    <file>foo.log</file>
    <encoder>
      <pattern>%date %level [%thread] %logger{10} [%file : %line] -%kvp- %msg%n</pattern>
    </encoder> 
  </appender>

  <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
    <encoder>
      <pattern>%msg%n</pattern>
    </encoder>
  </appender>

  <logger name="chapters.configuration.Foo" additivity="false">
    <appender-ref ref="FILE" />
  </logger>

  <root level="debug">
    <appender-ref ref="STDOUT" />
  </root>
</configuration>

En este ejemplo, el agregador denominado ARCHIVO se adjunta al registrador Chapters.configuration.Foo. Además, el registrador de capítulos.configuration.Foo tiene su indicador de aditividad establecido en falso, de modo que su salida de registro se enviará al agregador llamado ARCHIVO pero no a ningún agregador adjunto en un nivel superior en la jerarquía. Otros registradores permanecen ajenos a la configuración de aditividad del registrador Chapters.configuration.Foo. La ejecución de la aplicación MyApp3 con el archivo de configuración additivityFlag.xml generará resultados en la consola desde el registrador Chapters.configuration.MyApp3. Sin embargo, la salida del registrador Chapters.configuration.Foo aparecerá en el archivo foo.log y solo en ese archivo.
Chapters.configuration.Foo 只有agregador de archivos 没有stdout

Sustitución de variables

Versiones anteriores de este documento utilizaban el término "sustitución de propiedad" en lugar del término "variable". Considere que estos dos términos son intercambiables, aunque el último término expresa un significado más específico.
Como muchos lenguajes de secuencias de comandos, los archivos de configuración de inicio de sesión admiten la definición y sustitución de variables. Las variables tienen un alcance (ver más abajo). Además, las variables se pueden definir en el propio archivo de configuración, en archivos externos, recursos externos e incluso se pueden calcular y definir dinámicamente.
La sustitución de variables puede ocurrir en cualquier parte del archivo de configuración donde se pueda especificar un valor. La sintaxis para la sustitución de variables es similar a la del shell Unix. La cadena entre el principio {y el final} se interpreta como una referencia al valor del atributo. Para el atributo a Name , la cadena " entre { y el final } se interpreta como una referencia al valor del atributo. Para el atributo aName , la cadena "La cadena entre {y el final} se interpreta como una referencia al valor del atributo. Para el atributo a Name , la cadena " {aName}" se reemplaza por el valor que contiene el atributo aName.
Las variables HOSTNAME y CONTEXT_NAME suelen ser convenientes, se definen automáticamente y tienen alcance de contexto. Teniendo en cuenta que calcular el nombre de host puede llevar algún tiempo en algunos entornos, su valor se calcula de forma diferida (solo cuando es necesario). Además, HOSTNAME se puede configurar directamente desde la configuración.

Definición de variables

<variable><propiedades> puede definir variables

demostración1
<configuration>

  <variable name="USER_HOME" value="/home/sebastien" />

  <appender name="FILE" class="ch.qos.logback.core.FileAppender">
    <file>${USER_HOME}/myApp.log</file>
    <encoder>
      <pattern>%kvp %msg%n</pattern>
    </encoder>
  </appender>

  <root level="debug">
    <appender-ref ref="FILE" />
  </root>
</configuration>
demostración2
<configuration>

  <appender name="FILE" class="ch.qos.logback.core.FileAppender">
    <file>${USER_HOME}/myApp.log</file>
    <encoder>
      <pattern>%kvp %msg%n</pattern>
    </encoder>
  </appender>

  <root level="debug">
    <appender-ref ref="FILE" />
  </root>
</configuration>

java -DUSER_HOME=“/home/sebastien” MiAplicación2

demostración3
<configuration>

  <variable file="src/main/java/chapters/configuration/variables1.properties" />

  <appender name="FILE" class="ch.qos.logback.core.FileAppender">
     <file>${USER_HOME}/myApp.log</file>
     <encoder>
       <pattern>%kvp %msg%n</pattern>
     </encoder>
   </appender>

   <root level="debug">
     <appender-ref ref="FILE" />
   </root>
</configuration>

logback-examples/src/main/resources/chapters/configuration/variables1.properties

USER_HOME=/casa/sebastien

demostración4

También puede hacer referencia a un recurso en la ruta de clase en lugar de a un archivo.

<configuration>

  <variable resource="resource1.properties" />

  <appender name="FILE" class="ch.qos.logback.core.FileAppender">
     <file>${USER_HOME}/myApp.log</file>
     <encoder>
       <pattern>%kvp %msg%n</pattern>
     </encoder>
   </appender>

   <root level="debug">
     <appender-ref ref="FILE" />
   </root>
</configuration>

Alcances

Se puede definir una propiedad para su inserción en el ámbito local, en el ámbito de contexto o en el ámbito del sistema. El ámbito local es el predeterminado. Aunque es posible leer variables del entorno del sistema operativo, no es posible escribir en el entorno del sistema operativo.

ALCANCE LOCAL Una propiedad con alcance local existe desde el momento de su definición en un archivo de configuración hasta el final de la interpretación/ejecución de dicho archivo de configuración. Como corolario, cada vez que se analiza y ejecuta un archivo de configuración, las variables en el ámbito local se definen nuevamente.

ALCANCE DEL CONTEXTO Una propiedad con alcance de contexto se inserta en el contexto y dura tanto como el contexto o hasta que se borre. Una vez definida, una propiedad en el ámbito del contexto es parte del contexto. Como tal, está disponible en todos los eventos de registro, incluidos los enviados a hosts remotos mediante serialización.

ALCANCE DEL SISTEMA Una propiedad con alcance del sistema se inserta en las propiedades del sistema de la JVM y dura tanto como la JVM o hasta que se borre.

demostración1

<configuration>

  <variable scope="context" name="nodeId" value="firstNode" />

  <appender name="FILE" class="ch.qos.logback.core.FileAppender">
    <file>/opt/${nodeId}/myApp.log</file>
    <encoder>
      <pattern>%kvp %msg%n</pattern>
    </encoder>
  </appender>

  <root level="debug">
    <appender-ref ref="FILE" />
  </root>
</configuration>

En el ejemplo anterior, suponiendo que el atributo nodeId esté definido en el alcance del contexto, estará disponible en cada evento de registro, incluso aquellos enviados al host remoto mediante serialización.

Valores predeterminados para variables

En determinadas circunstancias, puede ser deseable que una variable tenga un valor predeterminado si no está declarada o su valor es nulo. Al igual que en el shell Bash, los valores predeterminados se pueden especificar utilizando el operador “:-”. Por ejemplo, suponiendo que la variable denominada aName no esté definida, "${aName:-golden}" se interpretará como "golden".

En algunos casos, es posible que desee que una variable tenga un valor predeterminado si no está declarada o si su valor es nulo. Al igual que con Bashshell, los valores predeterminados se pueden especificar utilizando el operador ":-". Por ejemplo, suponiendo que una variable denominada aName no esté definida, "${aName:-golden}" se interpretará como "golden".

variables anidadas

El anidamiento de variables es totalmente compatible. Tanto el nombre como el valor predeterminado y la definición del valor de una variable pueden hacer referencia a otras variables.

El anidamiento de variables es totalmente compatible. Los nombres de variables, los valores predeterminados y las definiciones de valores pueden hacer referencia a otras variables.

Supongo que te gusta

Origin blog.csdn.net/cclovezbf/article/details/133315371
Recomendado
Clasificación