loki를 사용하는 이유는 다음과 같다
loki4j와 logback을 사용해서 log를 남기도록 하겠다.
// grafana-datasources.yml
- name: Loki
type: loki
access: proxy
orgId: 1
url: http://loki:3100
basicAuth: false
isDefault: true
version: 1
editable: false
jsonData:
# 로그에서 TraceID 발견하면 Tempo로 연결해주는 설정
derivedFields:
- datasourceUid: tempo_uid_registration
matcherRegex: "traceId=(\\w+)" # 로그에서 traceId=... 패턴을 찾음 (또는 JSON 필드 매칭)
name: TraceID
url: "$${__value.raw}" # 찾은 ID로 URL 생성
derivedFields를 사용하면 로그에서 trace로 이동할 수 있다.
프로메테우스도 비슷한 설정으로 매트릭스에서 trace로 이동할 수 있다.
logback의 appender는 여러가지가 있지만, 이번에는 loki에다가 비동기로 송신하는 loki4j appender를 사용하도록 하겠다.
implementation 'com.github.loki4j:loki-logback-appender:2.0.1'
logback.xml대신 logback-spring.xml을 사용한다.
왜냐하면 logback.xml은 spring 실행하기 이전에 로드되어 실행되기 때문이다.
logback-spring을 사용하면 spring의 설정값 등을 사용할 수 있다.
대표적으로는 springProfile이나 springProperty가 있다.
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<springProperty scope="context" name="APP_NAME" source="spring.application.name"/>
<springProperty scope="context" name="LOKI_ENDPOINT" source="loki.endpoint"/>
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%d{yyyy-MM-dd} %d{HH:mm:ss.SSS} traceId=%X{traceId:-} spanId=%X{spanId:-} flags=0 %level [%thread] --- %msg%n</pattern>
</encoder>
</appender>
<appender name="LOKI" class="com.github.loki4j.logback.Loki4jAppender">
<http>
<url>${LOKI_ENDPOINT}</url>
</http>
<labels>
compose_service=app-${APP_NAME}
app=${APP_NAME}
host=${HOSTNAME}
level=%level
</labels>
<structuredMetadata>
* = %%mdc
</structuredMetadata>
<message>
<pattern>%d{yyyy-MM-dd} %d{HH:mm:ss.SSS} traceId=%X{traceId:-} spanId=%X{spanId:-} flags=0 %level [%thread] --- %msg%n</pattern>
</message>
</appender>
<root level="INFO">
<appender-ref ref="CONSOLE" />
<appender-ref ref="LOKI" />
</root>
</configuration>
앞에서 regex로 traceId에 대한 link를 찾기로 하였기 때문에 traceId= 형태로 남겨주어야한다
derivedFields 기능이 잘 작동하면 이렇게 같은 traceId를 공유하는 Tempo로 링크를 찾아갈 수 있다.
https://grafana.com/grafana/dashboards/17175-spring-boot-observability/
패턴은 사용하는 대시보드에 맞게 작성되었다