수백만 건 로그 노이즈 제거 LLM용 압축 도구
Ctrlb-decompose는 LLM(대형 언어 모델)에 로그를 입력하기 전, 전처리하여 노이즈를 제거해 주는 오픈소스 도구입니다. 방대한 원본 로그를 통계, 이상 징후, 상관관계가 포함된 소수의 핵심 패턴으로 압축하여 분석 효율을 극대화합니다. CLI 명령어나 브라우저(WASM), 러스트(Rust) 라이브러리 형태로 실행할 수 있어 실무자의 로그 분석 및 LLM 활용 비용을 크게 줄여줍니다.
ctrlb-decompose는 원본 로그 라인을 통계, 이상 징후, 상관관계가 포함된 구조적 패턴으로 압축해 줍니다. 타입이 지정된 변수, 분위수(quantile) 통계, 이상 징후 플래그, 심각도 점수를 활용하여 수백만 건의 잡음(노이즈)이 많은 로그를 소수의 실행 가능한 패턴으로 변환합니다. CLI(명령 줄 인터페이스), 브라우저(WASM) 또는 Rust 라이브러리로 실행할 수 있습니다.
$ cat server.log | ctrlb-decompose
┌────────────────────────────────────────────────────────────────────┐
│ ctrlb-decompose: 1,247,831 라인 -> 43개 패턴 (99.9% 감소) │
└────────────────────────────────────────────────────────────────────┘
#1 [ERROR] ██████████████████████ 18,402 (1.5%)
<TS> ERROR [<*>] Connection to <ip> timed out after <duration>
ip IPv4 unique=12 top: 10.0.1.15 (34%), 10.0.1.22 (28%)
duration Duration p50=120ms p99=4.8s
#2 [INFO] ████████████████████ 904,221 (72.5%)
<TS> INFO [<*>] Request from <ip> completed in <duration> status=<status>
ip IPv4 unique=1,847 top: 10.0.1.15 (12%), 10.0.1.22 (8%)
duration Duration p50=23ms p99=312ms
status Enum unique=3 values: 200 (91%), 404 (6%), 500 (3%)
웹사이트가 곧 오픈될 예정입니다.
작동 원리
ctrlb-decompose는 정규화(Normalization)와 클러스터링이라는 2단계 파이프라인을 사용하여 로그를 단일 스트리밍 패스로 처리하며, 메모리 사용량을 최소화합니다.
┌──────────────────────────────────────────────┐
│ ctrlb-decompose 파이프라인 │
└──────────────────────────────────────────────┘
원본 로그 라인
│
▼
┌──────────────┐
│ 타임스탬프 │ 타임스탬프(ISO 8601, Apache, syslog,
│ 추출 │ Unix epoch 등)를 추출하여 DateTime 값이
└──────┬───────┘ 포함된 정규화된 <TS> 마커로 변환합니다.
│
▼
┌──────────────┐
│ CLP 인코딩 │ 정수, 소수, IP, 문자열을 간결한 자리 표시
│ │ 자(Placeholder) 바이트로 대체합니다. 구조가
└──────┬───────┘ 동일한 라인은 동일한 '로그 유형'을 생성합니다.
│
▼
┌──────────────┐
│ Drain3 │ 트리 기반 유사도 클러스터링(Drain3)으로
│ 클러스터링 │ 로그 유형을 패턴으로 그룹화합니다. 다른 토큰은
└──────┬───────┘ <*> 와일드카드가 됩니다. 2번의 패스가 필요 없는 증분 방식입니다.
│
▼
┌──────────────┐
│ 변수 추출 │ CLP로 디코딩된 값을 Drain3 와일드카드 위치와
│ 및 타이핑 │ 병합합니다. 각 변수를 IPv4, UUID, Duration,
└──────┬───────┘ Enum, Integer 등 의미론적 유형으로 분류합니다.
│
▼
┌──────────────┐
│ 통계 │ DDSketch 분위수(p50/p99), HyperLogLog
│ 누적 │ 카디널리티 추정치, 상위 k개 값, 시간별 버킷팅,
└──────┬───────┘ 리저버 샘플링된 예제 라인을 제공합니다.
│
▼
┌──────────────┐
│ 이상 징후 │ 빈도 급증, 에러 연쇄(Error cascade),
│ 탐지 │ 저카디널리티 플래그, 이중봉 분포(Bimodal),
└──────┬───────┘ 클러스터링된 숫자를 탐지합니다.
│
▼
┌──────────────┐
│ 점수 책정 │ 키워드 기반 심각도(ERROR > WARN > INFO > DEBUG),
│ 및 상관관계 │ 시간적 동시 발생, 공유 변수 상관관계,
└──────┬───────┘ 패턴 간의 에러 연쇄 탐지를 수행합니다.
│
▼
┌──────────────┐
│ 출력 │---- 사람용(ANSI 터미널) / LLM용(간결한 마크다운) / JSON
└──────────────┘
1단계 — CLP 인코딩
CLP(Compressed Log Processor) 인코딩은 변수 토큰을 타입이 지정된 자리 표시자로 정규화하므로, 실제 값과 관계없이 구조적으로 동일한 라인은 동일한 로그 유형을 생성합니다.
- 입력:
Request from 10.0.1.15 completed in 45ms status=200 - 로그 유형:
Request from <dict> completed in <float>ms status=<int>
2단계 — Drain3 클러스터링
Drain 알고리즘은 로그 유형 위에 접두사 트리(Prefix tree)를 구축하고 토큰 유사도(구성 가능한 임계값, 기본값 0.4)를 기준으로 그룹화합니다. 토큰이 달라지는 부분은 템플릿에 <*> 와일드카드가 부여됩니다. 이는 각 라인을 한 번만 처리하고 두 번째 패스가 필요 없는 증분(Incremental) 방식으로 실행됩니다.
변수 분류
추출된 변수는 더 풍부한 분석을 위해 의미론적 타입으로 분류됩니다:
- IPv4 / IPv6:
10.0.1.15(CIDR 패턴 일치) - UUID:
550e8400-e29b-...(8-4-4-4-12 16진수 형식) - Duration:
45ms,3.2s(숫자 + 시간 단위 접미사) - HexID:
0x1a2b3c(4자리 이상의 16진수) - Integer:
200(i64로 파싱됨) - Float:
3.14(.포함, f64로 파싱됨) - Enum:
ERROR(저카디널리티: 고유 값 20개 이하, 상위 3개가 80% 이상) - Timestamp:
2024-01-15T14:22:01Z(RFC 3339 패턴) - String: 그 외 모든 항목