Spring Boot Series: explicación detallada de la configuración dinámica de registros

1. Introducción

Versión de Spring Boot: 2.3.4.RELEASE

No sé si alguna vez ha necesitado algunos registros DEBUG cuando hay problemas en línea, pero INFO se está utilizando actualmente.

Si desea habilitar DEBUG, debe volver a empaquetar y liberar la versión, pero en algunos escenarios, es posible que el problema no se repita después de reiniciar, lo cual es realmente doloroso.

Hoy hablaremos sobre el ajuste dinámico de la configuración del registro en Spring Boot, para que su nivel de registro pueda moverse como desee.

Registro de arranque de primavera

Spring Boot Series: explicación detallada de la configuración dinámica de registros

Lo que realmente se usa dentro de Spring Boot es Commons Logging, y el mecanismo de carga de configuración basado en Spring Boot nos proporciona varios métodos de registro: Java Util Logging, Log4j2 y Logback.

Logback es su marco de registro predeterminado. Si no hay una necesidad especial, no se recomienda reemplazarlo. (No hables de rendimiento)

Formato de registro

No subestime aspectos como el formato, que es algo importante en la aplicación real.

No sé si su empresa tiene un componente básico de registro unificado. Por supuesto, no existe, y probablemente, un archivo de configuración de registro unificado.

Piense si su formato de registro no es uniforme, si cada proyecto tiene su propio estilo, ¿cómo puede pedirle a su socio de operación y mantenimiento que lo ayude a dividir el registro? ¿Llamas a la policía? Eso es realmente escribir hasta la muerte, confiando completamente en el amor para generar electricidad. (Por ejemplo, si el Loghub que usamos no es uniforme, será eliminado por operación y mantenimiento)

Echemos un vistazo a nuestra configuración de formato de registro, aquí solo PATRÓN

-|%d{yyyy-MM-dd HH:mm:ss.SSS}|%-5level|%X{tid}|%thread|%logger{36}.%M:%L-%msg%n

Primero explica cada posición:

  • % d {aaaa-MM-dd HH: mm: ss.SSS}: hora
  • % -5level: nivel de registro
  • % X {tid}: nuestro ID de seguimiento distribuido personalizado
  • % hilo: hilo
  • % logger {36}.% M:% L: el nombre completo de la clase (36 representa el carácter más largo). Número de línea de información
  • % msg% n: información de salida para ajustar

No sé si puedes entender por qué hay un ... ¿delante de él? De hecho, es por la conveniencia de distinguir el registro de nueva línea cuando la segmentación regular, como la información de la pila de excepciones.

Varios puntos de conocimiento

Hablemos de algunos otros puntos pequeños utilizados por Spring Boot, vayamos al tema

  • Aquí, Logback no tiene un nivel FATAL y se clasifica como ERROR
  • Puede configurar debug = true en application.properties para habilitar el modo de depuración, también puede configurar trace = true para habilitar el modo de rastreo
  • Puede usar logging.level. = En application.properties para configurar varios niveles de registro, como org.hibernate level está configurado en ERROR logging.level.org.hibernate = error
  • El concepto de grupo de registros, si tal configuración es molesta, puede establecer un grupo para su configuración general. Por ejemplo: logging.group.tomcat = org.apache.catalina, el nivel de configuración org.apache.coyote es TRACE logging.level.tomcat = TRACE
  • Si usa el archivo de configuración de Logback, la recomendación oficial es usar un nombre como logback-spring.xml. Si usa logback.xml, la inicialización del registro de Spring debería ser un problema.
  • Si controla la configuración de registro, pero no desea utilizar logback.xml como el nombre de la configuración de Logback, puede especificar un nombre personalizado a través de la propiedad logging.config en el archivo de configuración application.properties: logging.config = classpath: xxx-log.xml

Dos, modificar dinámicamente el nivel de registro

Hablemos de cómo la aplicación Spring Boot en estado de ejecución cambia el nivel de registro dinámico

Actuador de arranque de resorte

El actuador debe conocer el nombre de Spring Boot, monitoreo, auditoría, información de medición, etc. El cierre elegante, la verificación de estado y la información de registro que usamos se logran a través de estas cosas.

Después de usar Actuator, podemos usar su interfaz REST de Logger para manipular nuestros registros, hay tres de la siguiente manera

  • GET http://127.0.0.1:6080/actuator/loggers devuelve toda la información del nivel de registro de la aplicación actual (lo que desea o lo que)
  • GET http://127.0.0.1:6080/actuator/loggers/{name} devuelve el nivel de registro de {name}
  • POST http://127.0.0.1:6080/actuator/loggers/{name} parámetros de configuración {"configurationLevel": "INFO", "EffectLevel": "INFO"} modificar el nivel de registro

Utilice el mecanismo del actuador para modificar dinámicamente el nivel

1), confíe en la configuración necesaria Spring Boot Actuator (si hereda el padre, no necesita una versión)

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-actuator</artifactId>
    <version>2.3.4.RELEASE</version>
</dependency>

2), archivo de configuración

#注意,这里我只开启了loggers,health两个Actuator
management.endpoints.web.exposure.include=loggers,health
management.endpoint.loggers.enabled=true

3), crea un controlador

@RestController
@RequestMapping("/log")
public class TestLogController {

    private Logger log = LoggerFactory.getLogger(TestLogController.class);

    @GetMapping
    public String log() {
        log.trace("This is a TRACE level message");
        log.debug("This is a DEBUG level message");
        log.info("This is an INFO level message");
        log.warn("This is a WARN level message");
        log.error("This is an ERROR level message");
        return "See the log for details";
    }
}

4), inicie la aplicación

En este punto, después de iniciar la aplicación, si usa IDEA, puede ver el siguiente Mapeo, hay tres interfaces REST sobre logger

Spring Boot Series: explicación detallada de la configuración dinámica de registros

5), prueba

En este punto, ejecuto GET http://127.0.0.1:6080/log primero, y la consola imprime la siguiente información

2020-10-15 23:14:51.204  INFO 52628 --- [nio-6080-exec-7] c.q.chapter1.failure.TestLogController   : This is an INFO level message
2020-10-15 23:14:51.220  WARN 52628 --- [nio-6080-exec-7] c.q.chapter1.failure.TestLogController   : This is a WARN level message
2020-10-15 23:14:51.221 ERROR 52628 --- [nio-6080-exec-7] c.q.chapter1.failure.TestLogController   : This is an ERROR level message

En este momento, ejecutamos GET http://127.0.0.1:6080/actuator/loggers/ROOT y devolvemos {"ConfigurationLevel": "INFO", "EffectLevel": "INFO"}, lo que significa que el nivel de registro de nuestra aplicación es INFO en este momento. ROOT representa el nodo raíz.

6), modificar el nivel

En este momento, ya no queremos ver la información INFO. Si queremos cambiar todo el nivel de registro de la aplicación a WARN, ejecutemos POST http://127.0.0.1:6080/actuator/loggers/ROOT El parámetro es {"configurationLevel": "TRACE", "EffectiveLevel": "TRACE"}

En este punto, ejecutaremos GET http://127.0.0.1:6080/log nuevamente, y la consola imprimirá la siguiente información

2020-10-15 23:24:11.481 TRACE 53552 --- [nio-6080-exec-3] c.q.chapter1.failure.TestLogController   : This is a TRACE level message
2020-10-15 23:24:11.481 DEBUG 53552 --- [nio-6080-exec-3] c.q.chapter1.failure.TestLogController   : This is a DEBUG level message
2020-10-15 23:24:11.481  INFO 53552 --- [nio-6080-exec-3] c.q.chapter1.failure.TestLogController   : This is an INFO level message
2020-10-15 23:24:11.481  WARN 53552 --- [nio-6080-exec-3] c.q.chapter1.failure.TestLogController   : This is a WARN level message
2020-10-15 23:24:11.481 ERROR 53552 --- [nio-6080-exec-3] c.q.chapter1.failure.TestLogController   : This is an ERROR level message

Otros metodos

  • Análisis de archivos de configuración: es el nivel de modificación de funciones del análisis automático de Logback. Con logback-spring.xml habilitado, puede modificar dinámicamente el nivel de registro interno de logback-spring.xml. Si está interesado, puede probarlo usted mismo.
  • arthas modificación dinámica
  • Combinado con el centro de configuración remota, como Apollo para lograr la modificación de nivel dinámico

Tres, principio de realización

Aquí utilizamos principalmente Spring Boot Actuator Log, por lo que también hablaremos sobre su principio.

Carga de punto final

Primero, encontramos nuestro LoggersEndpoint del actuador de arranque de resorte dependiente (todos los actuadores son de este número), como se muestra en la figura:

Spring Boot Series: explicación detallada de la configuración dinámica de registros

Los amigos que están familiarizados con el mecanismo de carga de Spring Boot saben que detrás de cada punto final del actuador, debe haber un xxxEndpointAutoConfiguration para cargar el punto final por nosotros.

Todos estos mecanismos de carga se almacenan en spring-boot-actuator-autoconfigure, donde podemos encontrar LoggersEndpointAutoConfiguration para cargar la clase de configuración de LoggersEndpoint.

Eche un vistazo a su núcleo:

@Bean
	@ConditionalOnBean(LoggingSystem.class)
	@Conditional(OnEnabledLoggingSystemCondition.class)
	@ConditionalOnMissingBean
	public LoggersEndpoint loggersEndpoint(LoggingSystem loggingSystem,
			ObjectProvider<LoggerGroups> springBootLoggerGroups) {
		return new LoggersEndpoint(loggingSystem, springBootLoggerGroups.getIfAvailable(LoggerGroups::new));
	}

Puede ver dos parámetros importantes:

  • LoggingSystem: una clase abstracta de nivel superior
  • springBootLoggerGroups: almacena los datos del grupo de registro actual

Para resumir:

1. Después de confiar en el paquete spring-boot-starter-actuator, se basa en spring-boot-actuator-autoconfigure

2. Al comenzar a escanear a META-INF / spring.factories bajo spring-boot-actuator-autoconfigure, LoggersEndpointAutoConfiguration se cargará en

3. LoggersEndpoin se declara en LoggersEndpointAutoConfiguration y se le asigna LoggingSystem y springBootLoggerGroups como sus parámetros

4. Una vez iniciado el proyecto, accederemos a los datos de registro a través de la interfaz LoggersEndpoint

Sistema de registro

Herencia del sistema de registro

De lo anterior, podemos entender que LoggingSystem es el núcleo de la administración de operaciones de registro, así que primero echemos un vistazo a sus diagramas.

Spring Boot Series: explicación detallada de la configuración dinámica de registros

A través de la relación de herencia, podemos ver de un vistazo que LogbackLoggingSystem es nuestro maestro. Aunque conocemos al maestro, ¿cómo se carga nuestro LoggingSystem?

Carga del sistema de registro

Los principales participantes son los siguientes:

  • LoggingApplicationListener
  • ApplicationStartingEvent
  • LogbackLoggingSystem
  • Sistema de registro

No hay mucho que decir, primera foto

Spring Boot Series: explicación detallada de la configuración dinámica de registros

1. La aplicación usa SpringApplication.run (Chapter1Application.class, args); comience

2. Enviar eventos de inicio ApplicationStartingEvent, ApplicationEnvironmentPreparedEvent, etc.

3. LoggingApplicationListener recibe eventos para su distribución

4. LoggingApplicationListener recibe el evento ApplicationStartingEvent

5. LoggingApplicationListener llama al método interno onApplicationStartingEvent (evento ApplicationStartingEvent) e inicializa LoggingSystem mediante LoggingSystem.get (cargador de clases).

6. Luego llame a LogbackLoggingSystem.beforeInitialize () (porque estamos usando logback aquí)

7, LoggingApplicationListener recibe el evento ApplicationEnvironmentPreparedEvent

8. LoggingApplicationListener llama al método interno onApplicationEnvironmentPreparedEvent (evento ApplicationEnvironmentPreparedEvent)

9. onApplicationEnvironmentPreparedEvent llama al método initialize (ConfigurableEnvironment environment, ClassLoader classLoader), que inicializará el sistema de registro de acuerdo con la configuración de la variable de entorno

Registradores

Finalmente, echemos un vistazo a LoggersEndpoint. No los copiaré todos aquí para facilitar la interpretación. ¿Dónde elegir?

Primero observe nuestras tres interfaces para operaciones de registro:

  • GET / actuator / loggers corresponde al método público Map <String, Object> loggers ()
  • GET / actuator / loggers / {name} 对应 public LoggerLevels loggerLevels (@Selector String name) 方法
  • POST / actuator / loggers / {name} 对应 public void configureLogLevel (@Selector String name, @Nullable LogLevel configurationLevel) 方法

Aquí hay un ejemplo del método público Map <String, Object> loggers (), los otros son similares

@ReadOperation
	public LoggerLevels loggerLevels(@Selector String name) {
		Assert.notNull(name, "Name must not be null");
		LoggerGroup group = this.loggerGroups.get(name);
		if (group != null) {
			return new GroupLoggerLevels(group.getConfiguredLevel(), group.getMembers());
		}
		LoggerConfiguration configuration = this.loggingSystem.getLoggerConfiguration(name);
		return (configuration != null) ? new SingleLoggerLevels(configuration) : null;
	}

El código es realmente muy simple, por lo que no haré demasiada interpretación.

Cuatro, habla

De hecho, los registros son muy importantes en las aplicaciones de nuestro sistema y también son evidencia importante para la resolución de problemas. Según la experiencia, el registro de nuestro sistema debería hacer algunas cosas:

  • Formato de registro unificado
  • Es mejor proporcionar un componente de registro unificado, por ejemplo, usamos el componente público logback-spring.xml. Si necesitamos modificar ciertas características del registro, como agregar registros de APM, etc., solo necesitamos cambiar un punto, y todo el estado del registro de nuestro sistema cambiará.

Supongo que te gusta

Origin blog.csdn.net/doubututou/article/details/109129411
Recomendado
Clasificación