IT/모니터링 48

OpenTelemetry Collector batch processor에서 삽질한 이야기

지난주에 OTel Collector가 메모리를 계속 먹다가 OOMKilled로 재시작되는 사고를 겪었다. 클러스터 전체 트레이스가 5분 단위로 뚝뚝 끊기는데, 그 시점 대시보드는 그냥 흰 도화지였다. 새벽 2시에 페이지가 울렸고, 눈을 뜨자마자 "batch processor" 4글자가 머리에 떠올랐다. 왜 하필이면 걔였는지, 지금 돌아보면 뻔한 이유가 있었지만 당시엔 한참을 헤맸다.우리 팀은 OTel Collector를 Deployment 3replica로 돌리고 있다. Ingress-nginx, 애플리케이션 SDK, kube-state-metrics에서 오는 트레이스/메트릭/로그를 모아 Tempo, Prometheus, Loki로 흘려보낸다. 트래픽 자체는 초당 스팬 8만개 정도. 그리 크지 않다. 그..

IT/모니터링 2026.08.01

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

absent_over_time, 이거 모르는 분 꽤 많더라

문제 상황오늘 알게 된 건 아니고, 최근에 신규 팀원한테 알림 튜닝 인수인계하다가 "이 함수 처음 봐요"라는 말을 들었다. 생각해 보니 나도 예전에 absent()랑 헷갈려서 쓰다가 알람을 놓친 적이 있었다. 짧게 정리해 둔다.Prometheus 알림 대부분은 "값이 얼마 이상이면 발동"이다. 근데 실제 사고는 오히려 "메트릭 자체가 안 오는" 순간에 터진다. exporter 프로세스가 죽었거나, 파드가 재시작되면서 라벨이 살짝 바뀌었거나, scrape job이 config reload 때 조용히 빠졌거나.이럴 때 up == 0만 걸어두면 반쯤은 놓친다. up은 scrape target이 등록돼 있어야 값이 있는 거고, target이 아예 discovery에서 사라지면 up{job="X"} 시리즈 자체가..

IT/모니터링 2026.07.25

Grafana Agent에서 Alloy로 넘어가는 실전 가이드

왜 지금 넘어가야 하나Grafana Agent(Static/Flow/Operator)가 2025년 11월 1일에 공식적으로 EOL을 맞았다. 우리 팀도 그 전에 다 넘겨야 했는데, 막상 문서를 보면 "convert 명령어 쓰세요" 정도로 뭉뚱그려져 있어서 실무에서 걸리는 지점이 꽤 있었다. 이 글은 프로덕션 클러스터 3개(스테이징 1, 프로덕션 2 — 노드 합쳐서 80대 정도)에서 넘긴 기록을 정리한 것이다.Alloy는 이제 단순히 Agent 후속작이 아니라 Grafana Labs가 OpenTelemetry Collector를 자기네 방식으로 배포하는 형태에 가깝다. 이게 왜 중요하냐면, 기존에 metrics {}, logs {} 블록으로 쪼개 놓던 것이 otelcol.* 파이프라인과 나란히 놓이면서 c..

IT/모니터링 2026.07.17

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

Loki 라벨 하나로 인제스터가 죽었다

Loki 라벨 하나로 인제스터가 죽었다지난주 금요일 오후, Slack 알람이 미친 듯이 울렸다. loki-ingester가 OOMKilled로 재시작 루프에 빠진 것이다. 그날 배포한 건 아무것도 없었다. 근데 왜 갑자기?결론부터 말하면 개발팀 한 곳이 애플리케이션 로그에 trace_id를 라벨로 추가했다. 그거 하나 때문에 클러스터가 죽을 뻔했다. 이 삽질을 공유한다.처음엔 그냥 트래픽 스파이크인 줄 알았다인제스터 3대 중 2대가 메모리 12Gi 리밋을 찍고 OOMKilled. 남은 1대에 부하가 몰리면서 그것도 죽고. 클래식한 캐스케이딩 실패였다.처음엔 그냥 로그가 늘어난 줄 알았다. 배포 이력을 봐도 로키 관련 변경은 2주 전이 마지막이었고, 그라파나 대시보드에서 로그 인입량(loki_distrib..

IT/모니터링 2026.07.13

Fluent Bit vs OpenTelemetry Collector, 로그 파이프라인 뭘 쓸까

Fluent Bit vs OpenTelemetry Collector, 로그 파이프라인 뭘 쓸까로그 파이프라인 얘기가 나올 때마다 팀 내부에서 도는 논쟁이 하나 있다. "그냥 Fluent Bit 계속 쓰면 되지 않냐" vs "이제 OpenTelemetry Collector로 통합해야 하지 않냐". 사실 둘 다 맞는 말이라 답이 애매하다. 몇 달간 두 도구를 병렬로 굴려보고 정리한 감상을 적어둔다.어디서 마주치는 문제인가우리 팀 클러스터는 노드 40대 규모다. 로그는 원래 Fluent Bit DaemonSet으로 수집해서 사내 Loki로 밀어넣고 있었다. 문제는 그 다음 단계다. 트레이스는 OTel Collector로, 메트릭은 Prometheus로, 로그만 Fluent Bit로 각각 다른 파이프라인이 돌고..

IT/모니터링 2026.07.08

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

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

IT/모니터링 2026.07.05

Prometheus absent()로 알람 걸 때, unless도 같이 봐야 하는 이유

오늘 알게 된 건데, 이거 모르고 쓰는 분이 꽤 많더라. absent() 함수. Prometheus에서 "메트릭이 사라졌을 때" 알람 거는 그 함수 말이다.뭐가 문제냐면우리 팀이 최근에 배치 job 상태를 감시하려고 이런 룰을 넣었다.- alert: JobMetricMissing expr: absent(batch_job_last_success_timestamp) for: 5m문제는 이거다. 배치가 서버 2대에 떠 있고, 한쪽 서버만 죽었을 때 이 알람이 안 울린다. absent()는 "메트릭 전체가 사라졌을 때"만 1을 반환한다. 나머지 한 서버가 살아있으면 시리즈는 여전히 존재하니까 조용하다. 근데 우리는 인스턴스 단위로 놓치고 싶지 않았다.unless가 답인 경우이럴 땐 unless를 쓴다.- a..

IT/모니터링 2026.07.03