SMALL

Observability 15

Tempo vs Jaeger v2, 결국 우리가 Tempo로 옮긴 이유

들어가며작년 말부터 트레이싱 백엔드를 갈아엎자는 얘기가 팀 내부에서 계속 나왔다. 직접적인 계기는 Jaeger v1이 2025년 12월 31일부로 EOL을 맞은 것이었다. 어차피 손을 대야 한다면 Jaeger v2로 갈지, Tempo로 옮길지 둘 중 하나를 골라야 했다. 결론부터 말하면 우리는 Tempo로 갔다. 그런데 솔직히 말해서 이 결정이 모든 팀에 정답은 아니다.두 솔루션이 지금 어디쯤 와 있는지Jaeger v2는 2024년 11월에 정식 릴리즈됐는데, 기존 코드베이스를 거의 다 버리고 OpenTelemetry Collector 위에 다시 쌓아 올린 구조다. 그러니까 Jaeger v2는 사실 "Jaeger 구성요소가 추가된 OTel Collector distribution"에 가깝다. 최근 2.1..

IT/모니터링 2026.06.08

Loki structured metadata, 이거 모르면 라벨 카디널리티로 계속 운다

라벨 vs structured metadata, 결정 기준오늘 알게 된 건데, 아직 Loki에서 pod나 trace_id를 라벨로 박고 계신 분들 꽤 많더라. Loki 3.x부터는 structured metadata가 정식으로 들어왔는데 활용 안 하면 진짜 손해다. 라벨 카디널리티 폭증 없이 검색 가능한 메타데이터를 붙일 수 있는 기능이다.Loki에서 라벨은 인덱스가 만들어지는 대상이라 카디널리티가 곧 비용이다. namespace, app 같은 저카디널리티 값만 라벨로 두고, trace_id, request_id, pod_name, thread_id 같은 고카디널리티 값은 structured metadata로 옮기는 게 정석이다. Grafana 공식 가이드도 "OpenTelemetry 데이터 ingest..

IT/모니터링 2026.06.02

Prometheus native histogram, 사실 내부적으로는 이렇게 동작한다

요즘 운영하는 클러스터에서 메트릭 카디널리티가 슬슬 부담스러워졌다. http_request_duration_seconds 하나만 봐도 le 버킷이 12개씩 붙고, 거기에 method/status/route 라벨까지 곱해지면 한 서비스가 5만 series를 우습게 넘긴다. 그래서 작년부터 native histogram 으로 옮기는 작업을 조금씩 해왔는데, v3.8 부터 stable 표기가 붙으면서 본격적으로 손을 댔다.이번 글은 "어떻게 켜는지"가 아니라 "왜 이게 그렇게 효율적인지"에 대한 이야기다. 사실 내부 구조를 모르고 켜면 ingester 메모리만 튀어서 한참 헤매게 된다.classic histogram 의 비효율은 어디서 오는가classic histogram 은 도구라기보다 관행에 가깝다. le..

IT/모니터링 2026.05.31

OTel Collector head sampling vs tail sampling, 우리 팀은 결국 뭘 골랐나

작년 말부터 트레이스 양이 폭증했다. 서비스가 늘어난 것도 있고, 한 요청이 마이크로서비스 7~8개를 거치다 보니 한 트랜잭션에 span이 200개 가까이 붙는 케이스도 생겼다. 그대로 Tempo에 다 밀어 넣었더니 스토리지 비용이 분기마다 1.6배씩 뛰었다. 샘플링을 손봐야 한다는 결론은 너무 자명했는데, 막상 head냐 tail이냐를 고르는 자리에선 팀 안에서도 의견이 갈렸다.결론부터 말하면 우리는 두 개를 섞었다. 그래서 이 글은 어느 한쪽이 정답이라는 얘기가 아니다. 각각의 결을 보고, 어디서 어떤 걸 골랐는지 정리한다.Head sampling — 빠르고 가난한 선택지Head sampling은 트레이스가 시작되는 시점, 그러니까 SDK가 root span을 만들 때 보낼지 말지를 결정한다. Par..

IT/모니터링 2026.05.27

OpenTelemetry Collector가 자꾸 OOM 나서, 결국 memory_limiter와 GOMEMLIMIT을 다시 봤다

지난주 새벽에 페이지가 울렸다. OTel Collector DaemonSet이 또 OOMKilled. 이번 분기에만 세 번째다. 솔직히 처음 두 번은 "그냥 limit을 올리지" 하고 넘어갔는데, 이번엔 메모리를 2Gi → 4Gi로 올렸는데도 또 죽으니까 멘탈이 살짝 나갔다.근본 원인을 보려고 새벽 3시에 노트북을 열었다. 결론부터 말하면 memory_limiter 설정과 GOMEMLIMIT이 둘 다 잘못 잡혀 있었고, batch processor의 순서까지 어긋나 있었다. 우리 팀은 1년 전에 OTel Collector를 처음 도입했을 때 공식 예제 그대로 복붙해 놓고 그동안 트래픽이 4배가 늘었는데도 손을 안 댔던 거다. 부끄럽다.일단 무슨 일이 일어났던 건가우리 클러스터는 노드 80대 정도 되고 각..

IT/모니터링 2026.05.26

Vector vs Fluent Bit, 6개월 둘 다 굴려본 노트

작년 말쯤 로그 파이프라인을 다시 손볼 일이 생겼다. 기존엔 모든 노드에 Fluent Bit DaemonSet으로 쓰고 있었는데, 트랜스폼 규칙이 복잡해지면서 Lua 필터가 점점 괴물이 되어가는 게 보였다. 그래서 한쪽 클러스터에 Vector를 시범 도입했고, 결국 6개월 동안 두 도구를 같은 워크로드에 나란히 굴려보게 됐다. 이 글은 그 결과 정리다. 결론부터 말하면, 둘 다 자리가 있다. 다만 자리가 다르다.우리 환경먼저 맥락. 이걸 안 깔면 비교가 의미가 없다.EKS 클러스터 2개, 합쳐서 노드 약 90대 (m6i.2xlarge ~ m7i.4xlarge 혼재)로그 발생량: 평시 평균 35k logs/sec, 피크 110k logs/sec목적지: S3 (장기), OpenSearch (검색), Kafk..

IT/모니터링 2026.05.23

Prometheus absent 알람, 이거 모르고 쓰면 새벽에 안 울린다

오늘 알게 된 건데, 아니 정확히는 어제 새벽 4시쯤 깨달은 건데, absent() 알람을 그냥 쓰면 staleness 때문에 정말 중요한 순간에 침묵할 수 있다. 이거 모르는 분 꽤 많더라. 우리 팀도 6개월째 이 룰을 쓰고 있다가 한 번 데였다.무슨 일이 있었나배치 잡 하나가 죽었다. 정확히는 메트릭을 push하는 사이드카가 OOM으로 재시작되면서 job_last_success_timestamp 시리즈가 사라졌다. 알람 룰은 이렇게 생겼었다.- alert: BatchJobMissing expr: absent(job_last_success_timestamp{job="nightly-etl"}) for: 10m근데 안 울렸다. 왜냐, Prometheus 3.x부터(사실 2.x 후반부터지만) stalen..

IT/모니터링 2026.05.21

OpenTelemetry Collector가 새벽마다 OOM 나던 이야기

며칠 전 새벽 2시 반쯤, 핸드폰이 또 울렸다. 또 otel-collector 파드 OOMKilled 알람. 이번 주만 네 번째다.처음에는 그냥 메모리 limit이 작다고 생각해서 1Gi → 2Gi → 4Gi 까지 올렸다. 그래도 죽었다. 8Gi로 올렸더니 죽기 직전까지 가서 GC가 미친듯이 돌면서 export 큐가 밀리고, 결국 백엔드(Tempo)로 가는 trace 데이터가 통째로 30분쯤 누락됐다. 멘탈이 나갔다.상황우리 환경은 좀 흔하다. EKS 1.30, otel-collector v0.115 (contrib), DaemonSet으로 노드 28대에 깔려있고, Receiver는 OTLP gRPC/HTTP, Processor는 batch + memory_limiter + resource, Export..

IT/모니터링 2026.05.18

Loki 인덱스가 무릎 꿇은 새벽 — 라벨 카디널리티 삽질 노트

어쩌다 라벨에 request_id를 박았나지난주 새벽 2시 17분에 핸드폰이 울렸다. PagerDuty였다. "Loki ingester OOM, 로그 쿼리 응답 없음." 평소 같으면 "내일 보자" 하고 자야 하는데, 마침 다음날 오전에 장애 회고 미팅이 잡혀 있었다. 거기서 로그가 안 보이면 곤란해진다. 노트북을 켰다.결론부터 말하면, 우리 팀에서 무심코 라벨에 박아놓은 request_id 하나 때문에 Loki 인덱스가 통째로 부풀어 올랐고, ingester가 메모리 한계에 부딪혀 차례로 죽었다. 그 후로 1주일 동안 카디널리티를 줄이느라 정신없이 보냈다. 그 기록이다.이게 좀 부끄러운 이야기인데, 처음부터 그런 건 아니었다. 우리 팀이 Loki를 도입한 건 작년 봄이었고, 그때는 그냥 namespace..

IT/모니터링 2026.05.14

Prometheus remote_write 큐가 메모리를 잡아먹은 새벽

지난 주말, 새벽 2시쯤 PagerDuty가 울렸다. central monitoring 클러스터의 Prometheus가 OOMKill로 재시작 루프를 돌고 있다는 알람이었다. 메모리 limit을 32Gi로 잡아둔 인스턴스인데, 이게 몇 분 만에 한계를 찍고 죽고 있었다. 멘탈이 좀 흔들렸다. 평소엔 14~16Gi 정도에서 안정적으로 돌던 녀석이었다.원인을 추적하다 보니 결국 remote_write 큐 동작에 대해 내가 잘못 알고 있었던 부분이 꽤 있었다. 이번 글은 그날 새벽 삽질의 기록이다.배경: 우리 팀의 metric pipeline우리는 Thanos 대신 Mimir로 1년 전쯤 옮겼고, 각 워크로드 클러스터의 Prometheus가 remote_write로 Mimir 게이트웨이에 메트릭을 밀어넣는 구..

IT/모니터링 2026.05.10
BIG