Skip to main content
Glama
Suteerth03
by Suteerth03

LogLens

로그 분석을 위한 MCP(Model Context Protocol) 서버입니다. 로그 파일을 채팅에 붙여넣고 LLM에게 디버깅을 요청하는 대신, LogLens는 로그 검색, 컨텍스트 조회, 인시던트 요약을 **도구(tool)**로 노출하여 MCP 호환 클라이언트(Claude Desktop, Claude Code, 또는 직접 만든 에이전트)가 바로 호출할 수 있게 합니다. 컨텍스트 스터핑을 하지 않고 표적화된 검색을 수행하며, 근거 없는 근본 원인 주장이 반환되기 전에 걸러 내는 자체 검증 단계도 함께 갖추고 있습니다.

왜 만들었나

내부 해커톤에서 1위를 차지한 AI 기반 로그 분석기의 공개·포트폴리오 버전으로 만든 것입니다. 채팅에 붙여넣기보다 나은 이유를 요약해 보면, 운영 로그는 컨텍스트 창에 다 들어가지 않고, 채팅에 붙여 넣은 내용은 다른 시스템이 호출할 수도 없으며, 원시 프롬프팅만으로는 모델의 답변이 실제로 로그 데이터에 근거하는지 확인할 메커니즘이 없습니다.

Related MCP server: Log Analyzer MCP

현재 상태

  • 핵심 서버 + 도구 3개 — 샘플 로그를 사용해 종단 간 동작 확인 완료. ✅

  • LLM 기반 근본 원인 생성 — 가설을 두 독립 축으로 검증하고, 어느 한 축에서 통과하지 못하면 한 번 더 재시도하는 환각(hallucination) 검증 루프를 갖췄습니다. ✅

  • 혼합 공급자 아키텍처(Groq + Gemini) — 검증기가 생성기와 다른 모델 계열로 동작하므로 검증이 생성기의 맹점을 그대로 공유하지 않습니다. ✅

  • 8개 사례 평가 스위트(eval suite) — 결정론적 채점, 8/8 통과. ✅

  • Docker화 완료 — 네트워크로 접근할 수 있는 HTTP 서버로 실행되며, 실제 컨테이너로 종단 간 검증 완료. ✅

  • 다음 단계: 클라우드 배포(Azure Container Apps 등) 및 데모 GIF 제작.

도구

도구

기능

search_logs

로그 파일에서 키워드를 검색하고, 일치 항목과 주변 컨텍스트 및 줄 id를 반환합니다.

get_error_context

id가 주어지면 해당 줄의 더 넓은 범위를 반환합니다 — 전체 스택 트레이스, 이벤트 시퀀스 등.

summarize_incident

자연어 질문에서 검색어를 추출하고, 증거를 수집한 뒤(어휘 + 시간 창 + 전역 이상치 확장), 근본 원인 가설을 생성하고, 두 축으로 독립 검증합니다. 검증기 verifier가 기각하면 한 번 재시도합니다.

아키텍처

Question ──▶ extract search terms (Groq, gpt-oss-20b)
                 │
                 ▼
         search_logs (lexical match)
                 │
                 ▼
    + time-window expansion (asymmetric: 900s before / 180s after —
      causes precede symptoms)
                 │
                 ▼
    + global anomaly scan (all WARN/ERROR lines, not just in-window —
      the explaining line is often itself a warning)
                 │
                 ▼
       generate hypothesis (Groq, gpt-oss-120b)
                 │
                 ▼
    verify: soundness + completeness (Gemini — DIFFERENT provider
    from the generator, on purpose; falls back to same-provider
    Groq if Gemini is unavailable, and reports which happened)
                 │
          unsound/incomplete? ──▶ regenerate once, feeding back
                 │                the lines the first pass overlooked
                 ▼
              answer

의도적으로 두 공급자 — 단순한 비용 회피가 아님

Groq가 추출 및 가설 생성을 담당하고, Gemini가 검증을 담당합니다. 처음에는 공짜 티어에 대한 쿼터 회피로 시작했지만(Gemini의 무료 티어는 하루 20회 요청 제한, Groq는 거기에 비해 훨씬 넉넉) 사실은 제대로 된 아키텍처 개선이 되었습니다. 주장을 생성문에 있는 모델과 같은 모델에서 실행되는 검증자는 그 모델의 맹점을 고스라히 공유합니다. 다른 모델 계열로 확인하면 환각 검사가 정말 독립적이기 때문에, 같은 출처의 두 번째 의견이 아닌 별도의 검증이 되는 것입니다. Verification.independent는 특정 답변이 실제 크로스-프로바이더 검증을 받았는지, 아니면 동일 프로바이더(Groq) 검증으로 폴백되었는지를 알려줍니다(Gemini 장애 또는 미구성시). 숨기지 않고 표면화하는 방식입니다.

cross-service 검색 공백 — 테스트 중 발견, 해결 지점은 올바른 계층

테스트 초기에 드러난 실제 한계가 있었습니다. summarize_incident는 체크아웃 실패의 직접적인 원인(DB 풀 고갈)은 찾았지만, 다른 서비스의 오래 실행되는 쿼리가 커넥션을 잡고 있어 끌고 들어온 것과 같은 사전 조건/상위 원인을 샘플 로그가 담고 있는데도 놓쳤습니다. 구조적 문제는 크게 두 가지입니다.

  • 검색이 순수 어휘 기반이었습니다. 추출된 검색어가 checkout 관련에 한정되어 있었기 때문에, 아무리 추론이 좋아도 inventory-service 라인은 증거 집합에 들어올 수 없었습니다. 이 문제는 시간 창 확장으로 해결했는데 의도적으로 비대칭(원인은 전후보다 앞서 있는 경우가 흔하기 때문에 900초 전 / 180초 후)으로 만들어졌고, 창에 관계 없이 WARN/ERROR 같은 전역 이상 라인을 스캔하는 방식도 추가했습니다. 설명이 되는 라인이 때로 그 자체가 경고인 경우가 많으므로(“NTP sync failed”, “rotation skipped”)입니다.

  • 검증하는 것은 도장을 찍어 주는 기능뿐이었습니다. — 상황: 원래는 주장이 인용한 라인만 볼 수 있어서 불완전한 답변을 구조적으로 발견하지 못했습니다. — 증상만 설명하는 주장은 냉자기가 고른 라인에서 지지를 받는 것처럼 보일 수밖에 없죠. 이제는 전체 증거 집합을 보고 soundnesscompleteness를 각각 독립적으로 점수화합니다. 타당하지만 불완전한 판정은 놓쳤던 라인을 다음 재생성 대에 다시 피드백해 줍니다.

평가 스위트

npx tsx evals/run-evals.ts          # all 8 cases
npx tsx evals/run-evals.ts 03 08    # a subset, by id substring

서로 다른 장애 유형 원형을 아라내는 8개 사례가 있습니다: 지횡 서비스 리소스 경쟁, 커지지 않는 캐시로 인한 OOM, 재시도 폭풍 증폭, 잘못된 배포, 두 개의 복합 원인, 잘못된 노드 하나 때문의 시간 오차(clock skew), 정상 로그의 경우(정답은 “nothing failed”), 그리고 소리가 큰 증상에 미묘한 원인이 가려진 경우 — completeness(완전성) 축을 시험하려고 특별히 만든 케이스입니다. 채점은 결정적으로 합니다 — 동의어를 포함하는 개념 그룹과 필수적인 증거 인용에 의존하며, LLM 판정자 없이 실행되기 때문에 결과의 재현성이 있습니다. 리포트는 회수 실패(retrieval misses)(증거가 모델에 도달하지 못한 경우)와 추론 실패(reasoning misses)(증거는 있었지만 답을 틀린 경우)를 나란히 놓고 보여주는데, 이 둘은 다른 수정이 필요하기 때문입니다.

현재 결과: 8/8 통과, 검색 누락 0건, 추론 누락 0건.

이 eval suite를 디버깅하는 것 자체가 값진 엔지니어링 사례였습니다. 비대칭 시간 창과 전역 이상 검색이 실제 검색 취약점을 해결했고, Groq 무료 티어에서 max_tokens는 “분당 토큰 예산”에 대해서 해당 budget에 값을 저장하는 것이지, 실제 사용만 청구되는 상한이 아닙니다. 실제 프롬프트 크기와는 무관함이 커도 소스 값은 413을 반환하게 됩니다. 또한 gpt—oss 모델에서 reasoning_effort: "low"가 필요했습니다. 그렇지 않으면 예산을 추론 토큰에 전부 펑팅하고 유효한 JSON을 만들기 전에 잘려버리기 때문입니다. 그리고 테스트 하네스 자체에도 채점 버그 두 개가 있었는데(유니코드 문장부호 변종, 그리고 동일한 복합 식별자의 평범한 공백 변종) 이는 정상적 답을 실패로 오판했었습니다 — 자기 평가 하네스도 디버깅이 필요하다는 습픈 교훈입니다.

Docker

docker build -t loglens:local .
docker run -d -p 3000:3000 \
  -e GROQ_API_KEY=your-key \
  -e GEMINI_API_KEY=your-key \
  loglens:local
curl http://localhost:3000/health

멀티 스테이지 빌드로(devDependencies로 컴파일하고, 프로덕션 거치는 프로덕레-전용 의존성 + 비권한 사용자 + 컨테이너 /health 헬스체크 ) 구성했습니다. 컨테이너는 stdio가 아니라 HTTP 전송(MCP_TRANSPORT=http, 이미지에서 기본값)을 사용합니다. 배포된 컨테이너에는 Claude Desktop/Code가 로컬에서 하는 것처럼 스폰해 줄 부모 프로세스가 없기 때문입니다.

연결 과정에서 발견했고 고쳐 두어 실제로 익숙해야 하는 버그가 있습니다 — 직접 자체의 무상태(stateless) Streamable-HTTP MCP 서버를 만든다면 알아 두세요: SDK의 무상태 모드가 요청마다 새 transport를 요구한다는 것입니다. 하나의 transport를 여러 요청에 재사용하면 첫 번째 요청 이후부터 조용히 에러가 발생해서 요청마다 500을 반환하며, 잡을 수 있는 예외도 없습니다. 그리고 별개로, 단일 McpServer는 한 번에 하나의 transport에만 연결만 하면 됩니다 (“already connected to a transport”). 해결책은 createServer()src/index.ts에 있는 HTTP 처리기로 구현했으며, 각 요청에 대해 새 McpServer와 새 StreamableHTTPServerTransport를 생성합니다. 서버는 단지 도구 「정의」만 보유하고 연결별 상태를 갖고 있지 않으므로(이 도구들은 갈수를 면했든 상태를 실어 보내지 않습니다) 아주 저렴한 방식입니다. 실제 실행 중인 컨테이너에 대해 확인했습니다. search_logs와 전체 summarize_incident 패스가 수정 후에는 둘 다 종단 간 정상적으로 완료되었습니다.

환경 변수

변수

필요한 경우

설명

GROQ_API_KEY

summarize_incident(추출 + 가설 생성)

console.groq.com/keys에서 무료로 받을 수 있습니다. search_logsget_error_context는 이 키 없이도 동작합니다.

GEMINI_API_KEY

독립적인 검증

aistudio.google.com/apikey에서 무료로 받을 수 있습니다. 이 키가 없으면 검증이 동일 공급자(Groq)로 폴백되어 더는 독립적으로 처리되지 않습니다 — 조용히 누락이 아니라 Verification.independent로 알려집니다.

LOGLENS_LOG_FILE

선택

번들된 샘플 대신 실제 로그 파일로 바꿔 읽을 때 경로 설정.

MCP_TRANSPORT

선택

http는 네트워크 접근 가능한 서버(Docker가 사용)로 동작합니다. 미설정 또는 다른 값은 stdio(Claude Desktop/Code처럼)로 실행됩니다.

PORT

선택

HTTP 포트, 기본값은 3000.

설정

npm install
npm run build

기본적으로 서버는 fixtures/sample.log를 읽습니다. 이 샘플은 inventory-service에서 오래 실행되는 인덱스 없는 쿼리가 공유 DB 커넥션 풀을 소모하고, 그 뒤로 checkout-service 오류가 계단된 합성 인시던트입니다. 실제 로그 파일로 바꿔려면 다음과 같이 지정 않습니다:

LOGLENS_LOG_FILE=/path/to/real.log node dist/index.js

스모크 테스트(MCP 클라이언트를 필요로 하지 않음)

npx tsx scripts/smoke-test.ts                              # stdio transport
npx tsx scripts/smoke-test-http.ts http://localhost:3000/mcp  # HTTP transport

서버를 스폰하거나(또는 기존 서버에 연결) 세 도구를 그리고 여러 번 호출해 확인합니다 — 구실 클라이언트를 연결하기 전에 제대로 동작하는지 확인할 때 유용합니다. summarize_incident를 한 번 꽉 채워 통과하면 34번의 순차 LLM 호출이 있고, 길게는 3090초까지 걸릴 수 있습니다. 프로그램으로 호출할 때는 느슨한 timeout을 주세요(두 스크립트 모두 그런 방식으로 만듭니다).

Claude Desktop에 연결

Windows에서 %APPDATA%\Claude\claude_desktop_config.json을 편집하고 다음을 추가하세요:

{
  "mcpServers": {
    "loglens": {
      "command": "node",
      "args": ["C:\\Users\\sarve\\OneDrive\\Desktop\\LogLens\\dist\\index.js"],
      "env": {
        "GROQ_API_KEY": "your-groq-key",
        "GEMINI_API_KEY": "your-gemini-key"
      }
    }
  }
}

The env block is required, not optional — MCP 클라이언트는 기본적으로 셸의 전체 환경이 아니라 정리된(sanitized) 환경으로 서버를 스폰합니다. 따라서 컴퓨터에서 전역적으로 키를 설정했더라도 이 환경 블록이 없으면 그 키들은 summarize_incident에서 감추어질 수 있습니다.

Claude Desktop을 재시작한 뒤, "로그에서 'pool exhausted' 검색해 줄래" 와 같은 질문을 해 보세요 — search_logs를 자동으로 호출할 것입니다.

Claude Code에 연결

claude mcp add loglens --scope user --env GROQ_API_KEY=your-groq-key --env GEMINI_API_KEY=your-gemini-key -- node C:\Users\sarve\OneDrive\Desktop\LogLens\dist\index.js

(위와 같은 이유에서요 — --env는 스폰된 프로세스가 셸의 전체 환경을 기본적으로 상속하지 않으므로, 키를 명시적으로 넘겨 줍니다.)

프로젝트 구조

src/
  index.ts       MCP server (dual transport: stdio + HTTP) + tool registration
  logParser.ts   log loading, search, time-window expansion, anomaly scan
  summarize.ts   the summarize_incident pipeline: extract -> retrieve -> hypothesize -> verify -> retry
  providers.ts   Groq + Gemini clients, model config, schema-constrained JSON generation
fixtures/
  sample.log     synthetic incident for local testing
evals/
  cases.ts       8 eval case definitions
  run-evals.ts   deterministic scoring harness
  logs/          synthetic logs for eval cases 02-08
scripts/
  smoke-test.ts       stdio transport smoke test
  smoke-test-http.ts  HTTP transport smoke test
Dockerfile       multi-stage build, non-root user, container healthcheck
A
license - permissive license
Not graded
quality - not tested
B
maintenance

Maintenance

Maintainers
Response time
Release cycle
Releases (12mo)
Commit activity

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Servers

  • -
    license
    Not graded
    quality
    Not graded
    maintenance
    Provides comprehensive logging and monitoring capabilities for MCP services with real-time log tailing, advanced search, error analysis, and anomaly detection. Enables centralized log aggregation, correlation tracking, and health monitoring across all MCP ecosystem services.
  • F
    license
    B
    quality
    C
    maintenance
    Enables AI-assisted analysis of log files through advanced searching, filtering, and test execution capabilities. Supports time-based queries, pattern matching, test summarization, and code coverage reporting directly within compatible MCP clients.
    12

View all related MCP servers

Related MCP Connectors

  • Read-only access to Auralogs production logs: search logs, inspect errors, review AI analyses.

  • A paid remote MCP for AI SDK data query MCP, built to return verdicts, receipts, usage logs, and aud

  • Remote MCP for A2A failure replay MCP, structured receipts, audit logs, and reviewer-ready evidence.

View all MCP Connectors

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/Suteerth03/LogLens'

If you have feedback or need assistance with the MCP directory API, please join our Discord server