현재 진행중인 프로젝트의 spring boot 를 사용하는 서비스(api, batch, worker 등)는 기존의 모니터링 시스템으로 문제없이 개발할 수 있었다.
하지만, 이번에 새로 추가되는 서비스들은 다양한 언어와 프레임워크로 구성되어있다.
예를들어, typescript 기반의 nestjs 애플리케이션과 python 기반의 fastapi 애플리케이션을 추가로 개발해야한다.
이 경우, 새로운 서비스에 맞는 모니터링, 로깅 구성을 해야한다.
우선 현재 구성은 아래와 같다.
각 서비스의 sidecar 로 grafana agent 를 사용해 로깅, 모니터링 하고있다.
모든 서비스의 진입점은 spring gateway
애플리케이션이고 요청이 들어오면 spring cloud sleuth
를 사용한 트레이싱을 시작한다.
spring gateway, spring boot 서비스는 logback 으로 로그를 남기고있다.
opentelemetry 는 다양한 언어와 환경을 위한 라이브러리를 제공하고있다.
implementation("org.springframework.cloud:spring-cloud-starter-sleuth:$sleuthVersion") {
// otel 의존성을 사용하면, 아래 의존성은 제외해야 함, 반대로 otel 의존성이 없으면 제외하면 안된다.
exclude(group = "org.springframework.cloud", module = "spring-cloud-sleuth-brave")
}
implementation("org.springframework.cloud:spring-cloud-sleuth-otel-autoconfigure:1.1.4")
implementation("io.opentelemetry:opentelemetry-exporter-otlp:1.34.1")
예를들어, spring boot의 경우 위와같이 적절한 의존성을 설치하고
spring:
...
sleuth:
jdbc:
datasource-proxy:
slow-query:
enable-logging: true
otel:
exporter:
otlp:
endpoint: "http://localhost:4317"
트레이싱 정보를 전달받을 endpoint 를 명시하면된다.
다른 언어를 사용할때도 이와 크게 다르지 않은데, 로그포맷을 맞추는데 다소 어려움이 있었다.
기존에 사용하고있던 logback 의 데이터포맷에 맞춰 로그를 수집하려한다.
implementation("net.logstash.logback:logstash-logback-encoder:$logbackEncoderVersion")
logstash-logback-encoder 를 사용하고 있었고, 아래 형태로 로그를 저장하고있다.
<encoder class="net.logstash.logback.encoder.LoggingEventCompositeJsonEncoder">
<providers>
<pattern>
<omitEmptyFields>true</omitEmptyFields>
<pattern>
{
"timestamp": "%d{yyyy-MM-dd HH:mm:ss.SSS}",
"logger": "%logger",
"level": "%level",
"requestIp": "%mdc{REQUEST_IP}",
"thread": "%thread",
"traceId": "%mdc{traceId}",
"spanId": "%mdc{spanId}",
"message": "%message"
}
</pattern>
</pattern>
...
기존 grafana 의 로그 대시보드에 아래 5개의 필드는 반드시 필요하다.
위 데이터를 문제없이 전송할 수 있는 적절한 otlp exporter 와, 로거가 필요하다.