관측성 24

OpenTelemetry Collector tail sampling, 메모리 압박 없이 쓰는 법

트레이스 샘플링을 tail 기반으로 돌리면 늘 만나는 문제가 있다. Collector 메모리가 훅훅 튀어 오른다. num_traces를 조금만 크게 잡아도 OOMKilled를 반복하고, 반대로 줄이면 span drop이 쌓인다. 우리 팀도 얼마 전까지 gateway 뒤에 붙은 tail-sampling collector 4대가 매일 새벽마다 OOM으로 재시작되는 걸 보고 있었다.이 글은 그 상황을 정리한 실무 가이드다. 최근에 OpenTelemetry Collector 쪽에서 나온 변화도 짚는다. 사실 이번 달(2026년 7월) Elastic이 upstream에 기여한 span-ingest 샘플링과 Pebble 기반 tail storage extension이 머지되면서 메모리 65%까지 줄었다는 리포트가 ..

IT/모니터링 2026.07.30

OpenTelemetry Collector Tail Sampling 내부 동작 파헤치기

트레이스 저장 비용이 슬금슬금 오르기 시작한 게 지난 분기부터였다. 우리 팀은 마이크로서비스 40여 개에서 초당 8만 스팬 정도를 뽑아내고 있었는데, 벤더 청구서가 예산의 두 배를 찍은 걸 보고 "샘플링을 진지하게 다시 봐야겠다"는 결론에 도달했다.Head sampling은 이미 걷어냈다. 어차피 랜덤으로 10% 남기는 방식은 정작 봐야 할 P99 지연이나 에러 트레이스를 놓치기 일쑤였다. 그래서 tail sampling으로 갈아탔는데, 처음 도입할 때는 "결정을 뒤로 미룬다" 정도의 개념만 알고 시작했다가, 운영하면서 그 안에서 벌어지는 일들이 훨씬 복잡하다는 걸 알게 됐다. 이 글은 그때 내가 코드를 뜯어보며 정리한 노트에 가깝다.Decision Wait의 의미와 함정Tail sampling proc..

IT/모니터링 2026.07.26

OTel Collector tail sampling에서 OOM으로 세 번 죽은 이야기

지난주에 OpenTelemetry Collector가 새벽에 세 번이나 OOM으로 재시작됐다. 알림이 잔뜩 쌓여있었고, 아침에 슬랙 열자마자 "이거 뭐야" 소리가 절로 나왔다. 원인은 결국 tail sampling processor였는데, 문제를 잡기까지 꽤 돌아왔다. 기록 삼아 남긴다.처음엔 그냥 트래픽 스파이크인 줄 알았다우리 팀은 최근에 head sampling에서 tail sampling으로 옮겼다. 이유는 명확했다. 에러 트레이스나 P99 넘어가는 느린 트레이스는 무조건 살려두고 싶은데, head sampling으로는 그게 불가능하니까. 트레이스 전체가 다 모여야 판단할 수 있는 정책들, 예를 들어 "이 트레이스에 5xx가 하나라도 있으면 keep" 같은 것들 말이다.옮긴 지 2주 정도는 조용했..

IT/모니터링 2026.07.15

PromQL의 rate()랑 irate(), 언제 뭘 쓸지 헷갈릴 때

PromQL의 rate()랑 irate(), 언제 뭘 쓰는지 헷갈릴 때오늘 알림 룰 리뷰하다가 팀 주니어가 물어봤다. "이거 왜 rate() 썼어요? irate()가 더 최신 값 반영하는 거 아닌가요?" 아, 이거 은근히 헷갈려하는 사람 많더라. 짧게 정리한다.한 줄 요약대시보드와 알림에는 대부분 rate(). irate()는 진짜 필요할 때만.왜 그런지rate([5m])은 5분 범위 안의 첫 샘플과 마지막 샘플을 보고 초당 증가율의 평균을 낸다. 값이 부드럽다. 짧은 스파이크 하나가 튀어도 완만해진다.반면 irate([5m])은 범위 안의 가장 최근 두 샘플만 본다. 5분 범위를 줘도 실제로는 마지막 두 점만 쓴다는 얘기다. 그래서 반응은 빠른데 그래프가 지글지글하다.문제는 알림 룰에서 이걸 잘못 쓰면..

IT/모니터링 2026.07.05

OpenTelemetry Collector, Agent와 Gateway 두 층으로 굴리기

OTel Collector 배포할 때 처음에는 다들 하나만 띄우고 시작한다. 우리 팀도 그러다. Deployment 하나 만들어서 어플리케이션들이 다 거기로 OTLP 쏘게. 초기엔 잘 돌아간다. 그러다 트래픽 늘고, tail sampling 붙이고, k8s 노드 라벨을 span에 붙이기 시작하면 슬슬 얘가 무너진다.이번 글은 그 다음 단계 — Agent(DaemonSet) + Gateway(Deployment) 두 층 구조로 가는 실전 셋업이다. 최근 릴리스 몇 개(현재 v0.154 기준)에서 바뀐 것들도 같이 정리한다.왜 두 층인가한 층으로 유지하다 보면 결국 이런 문제가 나온다.첫째, 노드 로컬 정보를 붙이기 어렵다. Pod의 IP는 알지만 노드 이름, 커널 버전, 인스턴스 타입 같은 건 어디선가 리..

IT/모니터링 2026.07.02

OTel Collector backpressure, 사실 내부적으로는 뭐가 도는가

OpenTelemetry Collector를 운영하다 보면 refused_spans, enqueue_failed, OOMKilled 같은 시그널을 한 번쯤은 본다. 다들 "memory_limiter 처음에 두면 된다"고 말하지만, 정작 메모리가 한계에 닿았을 때 collector 내부에서 무슨 일이 일어나는지는 의외로 흐릿하게 알고 있는 경우가 많다. 나도 처음엔 그랬다. 어느 날 traces 파이프라인이 갑자기 데이터를 흘리기 시작해서 메트릭을 파보다가, 그때서야 batch와 queue, retry가 메모리 한계 앞에서 어떻게 상호작용하는지 본격적으로 파악하게 됐다.이 글은 그 흐름을 정리한 노트다. 2026년 2월 즈음 oneuptime이나 dash0 쪽에서 모범 사례 가이드가 다시 한번 정리됐는데,..

IT/모니터링 2026.06.25

VictoriaMetrics vs Mimir, 1년 굴려보고 뭘 쓸까

작년 이맘때쯤 우리 팀은 Prometheus 단일 인스턴스로 버티는 게 한계에 다다랐다. 노드 800대, 활성 시리즈 3천만개를 넘기면서 메모리는 80GB를 넘어가고, 재시작 시 WAL 리플레이에 20분이 걸렸다. 장기 저장도 필요했다. 그래서 VictoriaMetrics 클러스터와 Grafana Mimir 두 개를 PoC로 띄워서 6개월씩 돌려봤고, 결국 메인을 VictoriaMetrics로 갔다. 이 글은 그 1년치 의사결정 기록이다.근데 미리 말해두면, 이건 "VM이 무조건 좋다"는 글이 아니다. 우리 팀 상황에 VM이 맞았던 거지, 다른 팀은 Mimir가 더 나을 수 있다. 그 경계가 어디인지 정리해보려고 한다.리소스 사용량 차이가 진짜였다벤치마크 자료들이 "VM이 메모리 5배 효율"이라고 떠드는..

IT/모니터링 2026.06.15

OTel Collector에 memory_limiter 안 걸어서 OOM 무한루프 겪은 이야기

지난주 새벽에 알림으로 깼다. otel-collector 데몬셋의 절반이 CrashLoopBackOff로 떨어졌다는 메시지. 그 시점에 트레이스 수집이 사실상 끊겨 있어서 우리 팀이 운영하는 서비스 절반 정도의 트레이스 대시보드가 비어 있었다. 평일 새벽 두 시였고 멘탈은 그닥이었다.처음엔 단순히 노드 메모리 압박이려니 했다. 그런데 살펴보니까 콜렉터만 죽는 거다. 다른 파드는 다 멀쩡. OOMKilled가 한두 번이 아니라 5분에 3-4번씩 반복되고 있었다. 메모리 limit이 1Gi였는데, 어떻게 잡힌 메모리가 그 한도를 매번 풀로 채우고 떨어졌다 다시 살아나고를 반복.일단 상황 정리kubectl describe로 보니까 Last State가 Terminated, Reason: OOMKilled, E..

IT/모니터링 2026.06.03

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