Я пытаюсь распечатать отметку времени с точностью до наносекунды в журналах моего приложения весенней загрузки. Я использую logback 1.5.6 в Spring Boot 3.3 с Java 17. Я искал разные подходы и пришел к выводу, что у нас уже есть доступ к наносекундной точности из Java 9+, а log4j был обновлен с помощью SimpleDateFormatter, который поддерживает наносекундную точность. Мы можем реализовать то же самое, используя кодировщик в logback-spring.xml с форматом %d{HH:mm:ss.SSSSSSSS} или %date{HH:mm:ss.SSSSSSSSS}
Но, учитывая все обстоятельства, я получил в журналах наносекундный формат (дд: мм: сс.СССССССС), но, к сожалению, данные были в миллисекундах. (12:30:17:815000000).
Таким образом, хотя он поддерживает точность в наносекундах, данные поступают с точностью до миллисекунды. Кажется, это проблема с кастингом где-то в библиотеке журналов.
Я также обнаружил, что мы можем использовать собственный кодер или фильтр или переменную пользовательского формата MDC, чтобы вручную получать данные и преобразовывать их в наносекунды, но по умолчанию это не должно давать наносекунды, как это предложено в документации и вариантах использования? По сути, поскольку в библиотеке уже есть такая функциональность, почему я не могу ее использовать.
logback-spring.xml
<configuration status = "TRACE">
<appender name = "CONSOLE" class = "ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%d{HH:mm:ss.SSSSSSSSS} [%thread] [%logger] [%level] - %msg%n</pattern>
</encoder>
</appender>
<root level = "INFO">
<appender-ref ref = "CONSOLE" />
</root>
</configuration>
pom.xml
<?xml version = "1.0" encoding = "UTF-8"?>
<project xmlns = "http://maven.apache.org/POM/4.0.0"
xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation = "http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.3.0</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.demo.ems</groupId>
<artifactId>ems</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>pom</packaging>
<modules>
<module>employee-service</module>
<module>task-service</module>
<module>discovery-service</module>
<module>gateway-service</module>
<module>admin-server-service</module>
<module>config-service</module>
</modules>
<properties>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<spring-cloud.version>2023.0.0</spring-cloud.version>
<spring-boot-admin.version>3.2.1</spring-boot-admin.version>
</properties>
<dependencies>
<dependency>
<groupId>org.modelmapper</groupId>
<artifactId>modelmapper</artifactId>
<version>3.2.0</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>de.codecentric</groupId>
<artifactId>spring-boot-admin-dependencies</artifactId>
<version>${spring-boot-admin.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<excludes>
<exclude>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</exclude>
</excludes>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>17</source>
<target>17</target>
</configuration>
</plugin>
</plugins>
</build>
</project>
Также я отлаживал при входе в систему и обнаружил это. В журнале %d указан атрибут this.timeStamp, присутствующий в классе LoggingEvent.class пакета ch.qos.logback.classic.spi, который фактически формируется с использованием миллисекунд вместо наносекунд, хотя он доступен.
Также я отлаживал при входе в систему и обнаружил это. В журнале %d указан атрибут this.timeStamp, присутствующий в классе LoggingEvent.class пакета ch.qos.logback.classic.spi, который фактически формируется с использованием миллисекунд вместо наносекунд, хотя он доступен.
Я использую журнал 1.5.6. Не уверен, но, похоже, в серверной части используется log4j.
Ваши системные часы имеют наносекундную точность?
Как запечатлеть текущий момент с разрешением в наносекунды? Обычные компьютерные часы не могут отслеживать текущий момент с такой точностью. Современный Instant.now фиксирует текущий момент с разрешением микросекунд в Java 9+ (миллисекунд в Java 8). Наследие System.currentTimeMillis() сводится к считанным миллисекундам.




Для входа в систему вам необходимо написать собственный конвертер.
Это преобразователь клиентов, который возвращает время прошедшее с момента его создания в наносекундах:
public class MySampleConverter extends ClassicConverter {
long start = System.nanoTime();
@Override
public String convert(ILoggingEvent event) {
long nowInNanos = System.nanoTime();
return Long.toString(nowInNanos-start);
}
}
а затем укажите на него в файле конфигурации
<configuration>
<conversionRule conversionWord = "nanos"
converterClass = "chapters.;layouts.MySampleConverter" />
<appender name = "STDOUT" class = "ch.qos.logback.;core.ConsoleAppender">
<encoder>
<pattern>%-6nanos [%thread] -%kvp -%msg%n</pattern>
</encoder>
</appender>
<root level = "DEBUG">
<appender-ref ref = "STDOUT" />
</root>
</configuration>
Подробности смотрите https://logback.qos.ch/manual/layouts.html
Да, как я уже говорил, мы можем сделать это разными способами, но это требует дополнительных усилий, но по умолчанию, согласно справочному документу, должно работать, но не работать. Хотя в любом случае спасибо. Также нашел проблему: jira.qos.ch/browse/LOGBACK-1658
Вы используете log4j или log4j2? Log4j2 должен обеспечивать эту функциональность. Проверьте документацию: logging.apache.org/log4j/2.x/manual/…