본문으로 건너뛰기

© 2026 Molayo

Dev.to헤드라인2026. 06. 25. 11:26

이 AI 방식을 시도하기 전까지 나는 로그 파싱에 수 시간을 허비했다

요약

다양한 형식의 마이크로서비스 로그를 파싱하는 데 어려움을 겪던 저자가 LLM을 활용해 로그를 구조화된 데이터로 추출하는 방법을 소개합니다. 정규 표현식 대신 AI API를 사용하여 로그의 의미를 해석하고 JSON 객체로 변환하는 효율적인 워크플로우를 제안합니다.

핵심 포인트

  • 정규 표현식 대신 LLM을 사용하여 비정형 로그의 의미를 해석하고 구조화 가능
  • 간단한 스키마 정의를 통해 다양한 로그 형식에서 타임스탬프 및 에러 추출
  • 비용 절감을 위해 gpt-4o-mini와 같은 경량 모델 및 배치 처리 활용 권장
  • 대량 데이터 처리 시 비용, 지연 시간, 환각 현상에 대한 트레이드오프 고려 필요

상황을 설명해 보겠습니다. 저는 방금 수십 개의 마이크로서비스 (microservices)에서 생성된 방대한 로그 파일 모음을 물려받았습니다. 각 팀은 자신만의 로깅 형식을 만들어냈습니다. 어떤 팀은 JSON을 사용했고, 어떤 팀은 이상한 위치에 타임스탬프 (timestamps)가 포함된 일반 텍스트를 사용했으며, 한 서비스는 하이쿠 (haiku) 형식으로 로그를 남기겠다고 고집했습니다 (농담입니다, 하지만 그만큼이나 특이했습니다). 저의 임무는 모든 에러 메시지, 타임스탬프, 그리고 소스 서비스를 추출하여 통합된 타임라인을 생성하는 것이었습니다.

저는 정규 표현식 (regex) 패턴, awk 원라이너 (one-liners), 그리고 커스텀 Python 파서 (parsers)를 작성하는 데 3일을 보냈습니다. 작업이 끝났다고 생각할 때마다 새로운 예외 케이스 (edge case)가 나타났습니다. 타임스탬프가 Unix epoch 대신 ISO 형식으로 되어 있거나, 에러 메시지가 여러 줄에 걸쳐 나타나는 식이었죠. 좌절감은 실로 엄청났습니다.

내가 시도했던 것들 (그리고 실패한 것들)

  • 모든 것에 정규 표현식 (Regex) 적용: 알려진 각 형식에 대해 패턴을 작성했습니다. 그러자 새로운 형식이 나타났습니다. 유지보수의 악몽이었습니다.
  • 범용 파서 (Generic parsers): 구조를 추론할 수 있는 유연한 파서를 작성하려고 시도했습니다. 그것은 빠르게 로그 파싱에 관한 박사 학위 논문 주제로 변질되었습니다.
  • 수동 검토 (Manual review): 확장성이 없었고, 제 눈에서 피가 나기 시작했습니다.

이러한 접근 방식 중 어느 것도 작동하지 않았는데, 그 이유는 다양성이 무한했기 때문입니다. 저에게는 단순히 형식을 맞추는 것이 아니라, '의미'를 이해할 수 있는 무언가가 필요했습니다.

실제로 효과가 있었던 방식: LLM 기반 추출

저는 로그를 파싱할 필요가 있는 것이 아니라, 로그를 '해석'해야 한다는 것을 깨달았습니다. 대규모 언어 모델 (LLMs)은 텍스트를 이해하고 구조화된 정보를 추출하는 데 탁월합니다. 그래서 저는 각 로그 라인(또는 라인 묶음)을 AI API로 보내고, 제가 원하는 필드가 포함된 JSON 객체를 반환하도록 요청하는 작은 스크립트를 구축했습니다.

핵심 기술은 다음과 같습니다: 간단한 스키마 (schema)를 정의하고, 가공되지 않은 로그 텍스트를 보낸 뒤, 모델이 힘든 작업을 수행하도록 하는 것입니다.

코드 예시 (Python)

import openai
import json

...

이 방식은 가장 이상한 형식에도 작동합니다. 모델은 문맥 (context)을 이해하며, 형식에 관계없이 타임스탬프를 추출할 수 있습니다.

성능을 위한 배치 처리 (Batching)

수천 개의 로그를 처리하기 위해, 저는 이를 배치 (batch)로 처리합니다:

def batch_extract(log_lines: list[str], batch_size=50):
    results = []
    for i in range(0, len(log_lines), batch_size):
...

교훈 및 트레이드오프 (Lessons Learned & Trade-offs)

이 방식이 만능 해결책(silver bullet)은 아닙니다. 제가 발견한 점들은 다음과 같습니다:

  • 비용 (Cost): 호출마다 비용이 발생합니다. 로그 양이 매우 많은 경우(하루 수백만 줄), 이는 비용 부담이 커집니다. 저는 비용을 줄이기 위해 더 저렴한 모델(예: gpt-4o-mini)과 배치 처리 (batching)를 사용했습니다.
  • 지연 시간 (Latency): 동기식 (Synchronous) 호출은 느립니다. 실시간에 가까운 처리가 필요한 경우, 비동기 (async) 또는 스트리밍 (streaming) 방식을 고려하십시오.
  • 환각 (Hallucination): 때때로 모델이 필드를 만들어내거나 모호한 텍스트를 잘못 해석합니다. 저는 Pydantic을 사용하여 사후 처리 검증 (post-processing validation) 단계를 추가했습니다.
  • 컨텍스트 윈도우 (Context window): 매우 긴 로그 라인(예: 스택 트레이스 (stack traces))은 토큰 제한을 초과할 수 있습니다. 저는 이를 자르거나(truncate) 분할합니다.
  • 정확도 (Accuracy): 100% 완벽하지는 않습니다. 중요한 시스템의 경우 하이브리드 접근 방식이 필요할 수 있습니다. 즉, 모호한 필드에는 AI를 사용하고 엄격한 필드에는 정규 표현식 (regex)을 사용하는 방식입니다.

이 방식을 사용하지 말아야 할 때

  • 로그가 매우 구조화되어 있고 예측 가능한 경우 (예: 항상 JSON 형식인 경우). 정규 표현식 (regex)이 더 빠르고 저렴합니다.
  • 높은 처리량 (throughput)으로 실시간 처리가 필요한 경우 (네트워크 오버헤드가 성능을 저하시킵니다).
  • 민감한 데이터: 로그를 외부 API로 전송하는 것은 컴플라이언스 (compliance)를 위반할 수 있습니다. 데이터를 내부적으로 유지하려면 로컬 모델 (Llama, Mistral 등)을 사용하십시오.

다음에 다시 한다면 다르게 할 점

첫째, 모든 데이터를 처리하기 전에 작은 샘플로 시작하여 스키마 (schema)를 검증하겠습니다. 둘째, 많은 로그가 반복되기 때문에 파싱된 결과를 캐싱 (cache)하겠습니다. 셋째, 지연 시간과 비용 문제를 제거하기 위해 Ollama를 통해 로컬 모델을 시도해 보겠습니다. 다만, 이 경우 정확도가 떨어질 수 있습니다.

전반적으로, 이 기술은 저의 유지보수 시간을 몇 시간이나 절약해 주었습니다. 이제 새로운 마이크로서비스 (microservice)가 또 다른 로그 형식을 가지고 나타나더라도 당황하지 않습니다. 모델이 처리해 줄 테니까요.

지저분한 로그를 처리하는 여러분만의 방식은 무엇인가요? AI를 시도해 보셨나요, 아니면 정규 표현식 (regex)을 고수하시나요? 여러분에게 효과가 있었던 방식(혹은 그렇지 않았던 방식)에 대해 듣고 싶습니다.

AI 자동 생성 콘텐츠

본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.

원문 바로가기
0

댓글

0