Ctrl + Shift + ESC

Upstage Solar API를 이용해 자동으로 에러 로그 요약하기 본문

DevOps

Upstage Solar API를 이용해 자동으로 에러 로그 요약하기

단축키실행해보세요 2026. 2. 1. 21:47

문제 정의

현재 우리 시스템의 로그 수집 구조는 다음과 같다.

EC2 로그
→ Promtail
→ Loki (로그 저장)
→ Grafana (조회, 알림, 시각화)

 

Promtail은 로그 파일이 존재하는 서버에 설치되어 로그를 수집하고, 이를 Loki로 전송한다.
Loki는 Promtail로부터 전달받은 로그를 저장하고, Grafana로부터 들어오는 로그 쿼리 요청에 대해 결과를 반환한다.
개발자는 Grafana를 통해 로그를 조회하거나, 특정 조건에 대한 알림을 설정할 수 있다.

 

 

문제는 로그의 양이다.
실제 운영 환경에서는 Loki뿐 아니라 CloudWatch Agent 등 다양한 방식으로 로그를 수집하고 있을 것이다. 하지만 이렇게 수집된 로그들은 분석되지 않으면 그저 쌓이기만 하는 데이터에 불과하다.

 

에러 로그는 여러 서버와 여러 서비스에 흩어져 있고, 하루에도 몇 초 간격으로 새로운 로그가 쌓인다.

모든 로그를 사람이 일일이 확인하며 모든 에러를 파악하고 대응하기에는 시간과 인력이 절대적으로 부족하다.
결국 중요한 로그를 놓치거나, 문제를 인지하는 시점이 늦어질 수밖에 없다.

 

해결 방안

그래서 우리는 이 문제를 해결하기 위해 LLM을 활용해 로그를 분석하는 봇을 만들기로 했다.
수많은 로그 중에서 의미 있는 로그를 선별하고, 중요한 에러를 요약·분석해 개발자가 빠르게 대응할 수 있도록 돕는 것이 목표다.

 

아키텍처

 

전체 시스템은 로그 수집 → 스케줄링 → 분석 및 요약 → 결과 전달의 흐름으로 동작한다.

 

1. 로그 수집

서버(예: EC2 인스턴스)에서 발생하는 Spring Boot 로그를 Promtail을 통해 Grafana Loki로 전달한다.
Promtail은 로그 파일이 존재하는 서버에서 로그를 수집하고, Loki는 이를 저장 및 조회 가능한 형태로 관리한다.

현재 구조에서는 Promtail + Loki + Grafana 조합을 사용하고 있지만, 핵심은 로그가 S3 또는 조회 가능한 저장소에 적재되어 있다는 것이다.
즉, S3에 로그를 저장하는 구조라면 동일한 방식으로 확장해 적용할 수 있다.

 

2. 스케줄링

Amazon EventBridge를 사용해 정해진 주기(KST 기준)에 분석 작업을 자동으로 트리거한다.
예를 들어 매일 자정이나 업무 시작 전에 실행되도록 설정할 수 있으며, 사람이 직접 실행하지 않아도 주기적으로 로그 요약 리포트를 생성할 수 있다.

 

3. 분석 및 요약

EventBridge에 의해 호출된 AWS Lambda 함수는 다음 작업을 수행한다.

  • Loki에 로그 쿼리를 보내 비정상 로그(에러, 경고 등)만 조회
  • 조회된 로그를 AI 서비스인 Upstage Solar LLM에 전달
  • 로그를 사람이 이해하기 쉬운 요약 형태로 변환

이 단계에서 핵심은 모든 로그가 아니라 의미 있는 로그만 선별해 분석한다는 점이다.
이를 통해 요약 결과의 밀도를 높이고, 불필요한 정보는 줄인다.

 

4. 요약 결과 전달

최종적으로 생성된 요약 리포트는 SNS를 통해 전송된다.
Discord와 같은 메신저로 결과를 받아볼 수 있으며, 개발자는 별도의 대시보드에 접속하지 않아도 주요 로그 이슈를 바로 확인할 수 있다.

 

핵심 기술

핵심적으로 사용된 기술은 다음과 같다.

기술 역할
Python 3.12 Lambda 함수 및 분석 로직 실행
AWS Lambda 서버리스로 로그 분석 실행 자동화
Amazon EventBridge 정기 트리거 scheduling
Grafana Loki + Promtail 로그 수집 및 저장
Upstage Solar LLM AI 기반 로그 요약
Docker & GitHub Actions CI/CD 자동 배포

 

주요 코드 설명

전체 코드는 아래 Github에서 확인할 수 있다.

https://github.com/snorose/daily-log-summarizer

 

GitHub - snorose/daily-log-summarizer: 로그 분석 람다

로그 분석 람다. Contribute to snorose/daily-log-summarizer development by creating an account on GitHub.

github.com

 

# Upstage API 키 로드
def get_api_key():
    try:
        response = ssm_client.get_parameter(Name=UPSTAGE_API_KEY_PARAMETER_NAME, WithDecryption=True)
        return response['Parameter']['Value']
    except Exception as e:
        print(f"Error retrieving API Key: {e}")
        raise e

# Upstage 클라이언트 초기화
UPSTAGE_API_KEY = get_api_key()
client = OpenAI(
    api_key=UPSTAGE_API_KEY,
    base_url="https://api.upstage.ai/v1"
)

 

이 코드는 Upstage API 키를 소스 코드에 직접 노출하지 않고, AWS Systems Manager Parameter Store에서 안전하게 불러와 Upstage API 클라이언트를 초기화하는 역할을 한다.

먼저 get_api_key() 함수는 ssm_client.get_parameter()를 사용해 암호화된 API 키를 복호화하여 조회한다.

이를 통해 API 키를 코드나 Git 저장소에 포함하지 않아도 되고, 운영 환경에서도 인증 정보를 안전하게 관리할 수 있다.

이렇게 불러온 API 키를 사용해 OpenAI 클라이언트를 초기화하되, base_url을 https://api.upstage.ai/v1로 지정해 Upstage Solar API 엔드포인트를 사용하도록 설정한다.
이 방식의 장점은 기존 OpenAI SDK 인터페이스를 그대로 유지하면서도, 별도의 복잡한 설정 없이 Upstage LLM을 연동할 수 있다는 점이다.

 

Upstage는 모델에 대한 문서가 매우 잘 되어 있고, Upstage Education 홈페이지를 통해 모델을 이용한 프로젝트도 할 수 있다.

https://console.upstage.ai/docs/getting-started?api=chat-reasoning

https://edu.upstage.ai/home

 

Home

본 강의는 자연어 처리(NLP) 분야에 관심이 있는 학습자를 대상으로 한 심화 과정입니다. 참가자들은 자연어 처리 문제를 이해하고, 분석하여 구현 가능한 적절한 형태로 정의하는 방법에 대해

edu.upstage.ai

 

SYSTEM_INSTRUCTION = f"""
당신은 SRE 팀을 위한 로그 분석 AI입니다.
목표: 주어진 로그만으로 사건(incident)을 감지하고, 유사 로그를 하나로 묶어(지문/패턴) 요약하며, 영향도·가설·다음 조치·조회용 질의를 제시합니다.

규칙:
- 외부 지식 추정 금지. 주어진 로그 범위 내에서만 판단.
- 불확실하면 "불확실"로 표기하고 confidence를 낮게 설정.
- 엔터티 정규화: service, env, region, host, error_code.
- 지문(fingerprint)은 변수값 마스킹(예: ID/IP 등) 후 간결하게.
- 샘플 로그(sample_logs)는 3개 이하, 비밀키/토큰/개인정보는 마스킹.
- 한국어로 작성.

[중요] 반드시 다음 JSON 형식을 준수하여 응답해야 합니다:
{json.dumps(JSON_SCHEMA, ensure_ascii=False)}
"""

 

AI가 로그를 요약하는 과정에서 엉뚱한 해석이나 불필요한 추정을 하지 않도록 시스템 프롬프트를 통해 명확한 규칙을 정의했다.

 

먼저 AI의 역할을 분명히 했다.
“당신은 SRE 팀을 위한 로그 분석 AI입니다.”라는 식으로 아이덴티티를 고정해, 일반적인 설명형 답변이 아니라 운영 관점에서 로그를 해석하는 역할에 집중하도록 유도했다.

 

그 다음으로는 동작 규칙을 세밀하게 설정했다.
로그에 포함되지 않은 내용을 추정하거나 외부 지식을 끌어오는 행위를 금지했고, 모든 응답은 한국어로 작성하도록 제한했다.
또한 실제 운영 로그를 다루는 만큼, IP 주소나 토큰과 같은 민감 정보는 반드시 마스킹하도록 가이드라인을 포함했다.

 

마지막으로, 응답 형식을 프로그램이 바로 후처리할 수 있도록 JSON 형식으로만 응답하도록 제한했다.
이를 통해 요약 결과를 알림 메시지로 보내거나, 추가 자동화를 연결하는 작업이 훨씬 수월해졌다.

 

 

결과 및 기대 효과

all_error_logs = [
	"[2025-02-01 14:05:01] ERROR o.a.c.c.C.[Tomcat].[localhost] - Servlet.service() for servlet [dispatcherServlet] threw exception",
	"[2025-02-01 14:05:01] ERROR o.s.b.w.s.ErrorPageFilter - Forwarding to error page from request [/api/users/me] due to exception",
	"[2025-02-01 14:05:01] ERROR o.h.e.jdbc.spi.SqlExceptionHelper - SQL Error: 0, SQLState: 08001",
	"[2025-02-01 14:05:01] ERROR o.h.e.jdbc.spi.SqlExceptionHelper - Communications link failure",
	"[2025-02-01 14:05:01] ERROR c.z.h.HikariPool - HikariPool-1 - Connection is not available, request timed out after 30000ms",
	"[2025-02-01 14:05:05] FATAL c.z.h.HikariPool - HikariPool-1 - Pool is exhausted, shutting down",
	"[2025-02-01 14:05:06] ERROR o.s.b.SpringApplication - Application run failed",
	"[2025-02-01 14:05:06] ERROR o.s.b.d.LoggingFailureAnalysisReporter - APPLICATION FAILED TO START",
	"[2025-02-01 14:05:06] ERROR o.s.b.d.LoggingFailureAnalysisReporter - Description: Failed to initialize database connection",
	"[2025-02-01 14:05:06] ERROR o.s.b.d.LoggingFailureAnalysisReporter - Action: Check database availability and credentials"
]

 

테스트를 위해 다음과 같은 에러 코드를 준비했다.

Spring Boot, Tomcat, Hibernate, HikariCP, 그리고 DB를 사용하는 환경에서 흔히 볼 수 있는 로그다.
처음에는 단순한 SQL 오류처럼 보이지만, 로그를 시간 순서대로 따라가다 보면 DB 연결 장애 → 커넥션 풀 고갈 → 애플리케이션 종료로 이어지는 전형적인 장애 시나리오라는 것을 알 수 있다.

 

이런 에러가 실제로 발생했을 경우, 기존 방식이라면 다음과 같은 과정이 필요하다.

  • 누군가 로그를 발견한다
  • 여러 줄로 흩어진 에러 로그를 시간 순서로 정리한다
  • DB 문제인지, 애플리케이션 문제인지 추측한다
  • 관련 명령어를 찾아 DB 상태, 커넥션 수, 애플리케이션 상태를 하나씩 확인한다

이 모든 과정은 결국 사람의 경험과 시간에 크게 의존한다.
야간이나 주말이라면 대응은 더 늦어질 수밖에 없다.

 

로그봇 분석 결과

 

Daily Log Summarizer를 도입하면 이 흐름이 달라진다.

 

시스템은 발생한 에러 로그를 자동으로 수집하고, AI가 로그 간의 흐름을 분석해 어떤 문제가 발생했고, 어떻게 확산되었는지를 요약한다.
개발자나 운영자는 더 이상 모든 로그를 직접 읽지 않아도, DB 연결 장애로 인해 커넥션 풀이 고갈되었고, 그 결과 애플리케이션이 종료되었다는 핵심만 빠르게 파악할 수 있다.

 

또한 대응을 위한 쿼리문을 제시해 어느 부분을 어떻게 살펴보면 될지 제시한다.

이를 통해 원인 분석에 대한 시간 뿐만 아니라 누구든지 이 알림을 본 사람은 해당 문제에 대해 1차적으로 대응할 수 있다.

 

결과적으로 Daily Log Summarizer는 로그를 단순한 기록이 아니라, 운영 판단을 돕는 요약된 정보로 바꿔주는 역할을 한다.