Когда мы используем Splunk, ELK и другие инструменты для работы с журналами, мы хотим иметь возможность поиска всех журналов связанных с запросом служб по одному traceId. Также мы хотим видеть названия вышестоящих служб и количество пройденных уровней в запросе. Это поможет нам более эффективно определять проблемы.
Пример журнала:
2022-12-04 17:24:33.015 DEBUG [service-sample,reactor-netty-sample,3a13f40b0ac24c0bb6b981ffde658ff6,0.1.1.1.1.1.1] 22456 --- [nio-9000-exec-1] c.l.t.servlet.TracerServletInterceptor : Built logging tracer context: {X-B3-TraceId=3a13f40b0ac24c0bb6b981ffde658ff6, X-B3-SpanName=service-sample, X-B3-SpanId=0.1.1.1.1.1.1, X-B3-Parent-SpanName=reactor-netty-sample}
2022-12-04 17:24:33.028 INFO [service-sample,reactor-netty-sample,3a13f40b0ac24c0bb6b981ffde658ff6,0.1.1.1.1.1.1] 22456 --- [nio-9000-exec-1] c.l.t.s.service.ServiceSampleController : Received new request for hello api.
2022-12-04 17:24:33.028 INFO [service-sample,reactor-netty-sample,3a13f40b0ac24c0bb6b981ffde658ff6,0.1.1.1.1.1.1] 22456 --- [nio-9000-exec-1] c.l.t.s.service.ServiceSampleController : Request header with [user-agent: ReactorNetty/1.0.25]
[service-sample,webclient-sample,3a13f40b0ac24c0bb6b981ffde658ff6,0.1.1.1.1]:
* service-sample — название текущей службы.
* webclient-sample — имя вышестоящей службы.
* 3a13f40b0ac24c0bb6b981ffde658ff6 — идентификатор цепочки (traceId).
* 0.1.1.1.1.1 — уровень запроса в цепочке служб.
* Если уровень равен 0, это означает, что запрос не прошёл через нижестоящие службы.
* Если уровень равен 0.1, это означает, что запрос прошёл через одну нижестоящую службу.
* И так далее...
### **Быстрое использование**
*logging-tracer-spring-boot-starter также поддерживает SpringBoot 3.*
> Версия logging-tracer-spring-boot-starter 3.0.0 и выше предназначена только для пользователей SpringBoot 3. Пользователи SpringBoot 2 должны использовать версии logging-tracer-spring-boot-starter ниже 3.0.0. Обе версии будут обновляться синхронно без потери функциональности.
#### **Импорт зависимостей**
Зависимости уже опубликованы в центральном репозитории Maven, их можно импортировать напрямую.
— Maven:
```xml
<dependency>
<groupId>com.lzhpo</groupId>
<artifactId>logging-tracer-spring-boot-starter</artifactId>
<version>${latest-version}</version>
</dependency>
— Gradle:
implementation 'com.lzhpo:logging-tracer-spring-boot-starter:${latest-version}'
PS: если вам не нужно настраивать проект, просто импортируйте соответствующие зависимости согласно приведённым ниже компонентам и используйте их как обычно.
В этом примере имитируется многозвенный вызов службы, который выполняется в следующем порядке:
Порядок | Название службы | Пример части trace |
---|---|---|
1 | feign-sample | [feign-sample,N/A,3a13f40b0ac24c0bb6b981ffde658ff6,0] |
2 | httpclient-sample | [httpclient-sample,feign-sample,3a13f40b0ac24c0bb6b981ffde658ff6,0.1] |
3 | okhttp-sample | [okhttp-sample,httpclient-sample,3a13f40b0ac24c0bb6b981ffde658ff6,0.1.1] |
4 | resttemplate-sample | [resttemplate-sample,okhttp-sample,3a13f40b0ac24c0bb6b981ffde658ff6,0.1.1.1] |
5 | webclient-sample | [webclient-sample,okhttp-sample,3a13f40b0ac24c0bb6b981ffde658ff6,0.1.1.1.1] |
6 | reactor-netty-sample | [reactor-netty-sample,webclient-sample,3a13f40b0ac24c0bb6b981ffde658ff6,0.1.1.1.1.1] |
7 | service-sample | [service-sample,reactor-netty-sample,3a13f40b0ac24c0bb6b981ffde658ff6,0.1.1.1.1.1.1] |
Импортирование зависимости feign автоматически активирует эту функцию.
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
Пример: logging-tracer-feign-sample
Импортирование зависимости httpclient автоматически активирует эту функцию.
<dependency>
И так далее... **Инициализация зависимостей для работы с HTTP-клиентами в Spring Boot**
<groupId>org.apache.httpcomponents.client5</groupId>
<artifactId>httpclient5</artifactId>
<version>${httpclient.version}</version>
Здесь используется Bean типа TracerHttpClients, который аналогичен методу HttpClients.
**Пример**: logging-tracer-httpclient-sample
#### 3. Okhttp
Импорт зависимости okhttp будет работать автоматически.
```xml
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp</artifactId>
<version>${okhttp.version}</version>
</dependency>
Ранее:
OkHttpClient okHttpClient = new OkHttpClient();
Теперь: внедрить OkHttpClient.BuilderBean напрямую и использовать его, вместо того чтобы создавать новый объект.
@Autowired
private OkHttpClient.Builder okHttpClientBuilder;
// Опущено...
OkHttpClient okHttpClient = okHttpClientBuilder.build();
Пример: logging-tracer-okhttp-sample
Можно напрямую внедрить RestTemplateBean и использовать его.
Пример: logging-tracer-resttemplate-sample
Можно напрямую внедрить WebclientBean и использовать его.
Пример: logging-tracer-webclient-sample
Можно напрямую внедрить HttpClientBean и использовать его.
Пример: logging-tracer-reactor-netty-sample
Добавьте зависимость logging-tracer-spring-boot-starter, и она будет автоматически активирована в среде SpringCloud-Gateway.
Импортируйте зависимость dubbo, и она будет активирована автоматически.
Примеры: logging-tracer-dubbo-api-sample, logging-tracer-dubbo-consumer-sample, logging-tracer-dubbo-provider-sample.
logging:
tracer:
pattern: '%5p [${spring.application.name:},%X{X-B3-Parent-SpanName},%X{X-B3-TraceId},%X{X-B3-SpanId}]'
Конечно, вы также можете настроить его так же, как и раньше, и он будет работать одинаково. Если настроены оба варианта, то будет использоваться верхний.
logging:
pattern:
level: '%5p [${spring.application.name:},%X{X-B3-Parent-SpanName},%X{X-B3-TraceId},%X{X-B3-SpanId}]'
logging:
tracer:
proxy-headers:
- Authorization
- User-Id
Затем эти заголовки запросов будут автоматически пересылаться на нижестоящие службы. Например, если вам нужно отобразить только один User-Id в журнале, вы можете настроить его следующим образом:
logging:
pattern:
level: '%5p [%X{User-Id}]'
Если их несколько, разделите их запятыми.
logging:
tracer:
enabled: false
Вы можете обратиться к модулю logging-tracer-resttemplate-sample и контроллеру RestTemplateSampleController для получения примеров кода.
ThreadPoolTaskExecutor (рекомендуется): если вы используете пул потоков ThreadPoolTaskExecutor для выполнения задач с несколькими потоками, вы можете использовать его как обычно, и logging-tracer автоматически обработает соответствующую логику.
@Autowired
private ThreadPoolTaskExecutor threadPoolTaskExecutor;
// Опущено...
threadPoolTaskExecutor.execute(() -> log.info("[threadPool] Hello, I'm threadPool."));
Thread: поскольку logging-tracer зависит от MDC, если вы используете Thread, вам необходимо вручную поддерживать контекст MDC в дочерних и родительских потоках.
Map<String, String> context = MDC.getCopyOfContextMap();
Thread thread = new Thread(() -> {
MDC.setContextMap(context);
log.info("[multiThread] Hello, I'm multiThread.");
});
thread.start();
Другие способы аналогичны.
Реализуйте интерфейс TracerContextCustomizer и добавьте его в контейнер Spring.
Например, когда вам нужно добавить заголовки запроса для пересылки на нижестоящие сервисы или вам нужно настроить формат журнала цепочки вызовов, если в заголовке запроса или текущем контексте нет этой переменной, вам нужно добавить соответствующие переменные в контекст.
@Component
public class SampleTracerContextCustomizer implements TracerContextCustomizer {
@Override
public void customize(Map<String, String> context) {
context.put("abc", "123");
context.put("def", "456");
}
}
Спасибо Jetbrains за предоставленную лицензию!
Вы можете оставить комментарий после Вход в систему
Неприемлемый контент может быть отображен здесь и не будет показан на странице. Вы можете проверить и изменить его с помощью соответствующей функции редактирования.
Если вы подтверждаете, что содержание не содержит непристойной лексики/перенаправления на рекламу/насилия/вульгарной порнографии/нарушений/пиратства/ложного/незначительного или незаконного контента, связанного с национальными законами и предписаниями, вы можете нажать «Отправить» для подачи апелляции, и мы обработаем ее как можно скорее.
Комментарии ( 0 )