8 분 소요

학습 내용 요약 (2025-11-14)

오늘은 실시간 보안 로그 모니터링 시스템 구축과 LLM(대형 언어 모델), LangChain을 활용한 RAG(Retrieval-Augmented Generation) 챗봇 구현을 중심으로 학습하였습니다. 데이터 분석과 시각화, LLM 연동, 환경 변수 관리, 실시간 대시보드 설계, 그리고 보안 로그 데이터의 임베딩 및 검색 기반 챗봇까지, 실제 보안 현장에서 활용할 수 있는 기술들을 단계별로 익혔습니다. 여태 배운 내용을 총 정리하고 실습 및 구현하는 시간을 가졌습니다.


1. 실시간 보안 로그 모니터링 시스템의 개요와 환경 설정

1.1. 프로젝트의 목적과 전체 구조

실시간 보안 로그 모니터링 시스템은 대량의 로그 데이터를 신속하게 분석하여, 잠재적인 위협을 조기에 감지하고 대응하는 것을 목표로 합니다. 최근에는 LLM과 같은 인공지능 기술을 접목하여, 단순히 데이터를 보여주는 수준을 넘어 자동화된 분석과 질의응답, 요약, 설명 기능까지 제공하는 것이 중요해졌습니다.

이 시스템은 크게 다음과 같은 흐름으로 구성됩니다.

  1. 데이터 분석 및 시각화 도구 준비: 로그 데이터를 효율적으로 처리하고 시각화하기 위한 라이브러리 준비
  2. 환경 변수 및 API 키 관리: 보안 강화를 위한 환경 변수 활용
  3. 실시간 데이터 로드 및 캐싱: 대용량 로그 데이터를 빠르게 불러오고, 반복 사용 시 속도 최적화
  4. Streamlit 대시보드 설계: 실시간 로그 모니터링 UI 구현
  5. LLM 및 LangChain 연동: 로그 데이터에 대한 자동 분석, 질의응답, 요약 등 고급 기능 추가

1.2. 주요 라이브러리 및 도구

실제 구현을 위해서는 여러 파이썬 라이브러리를 조합하여 사용합니다. 각 라이브러리의 역할과 특징을 명확히 이해하는 것이 중요합니다.

  • pandas, numpy: 데이터프레임 기반의 데이터 처리 및 수치 연산
  • streamlit: 웹 대시보드 및 UI 구현
  • plotly.express: 대화형 데이터 시각화
  • openai: LLM API 연동
  • dotenv, os: 환경 변수 및 API 키 관리
  • langchain: LLM 기반 워크플로우 및 RAG 챗봇 구현

2. 데이터 분석 및 시각화 도구 준비

실시간 로그 모니터링의 첫걸음은 데이터를 효율적으로 읽고, 가공하며, 시각화할 수 있는 환경을 갖추는 것입니다. pandas와 numpy는 데이터프레임 처리와 수치 연산에 필수적이며, streamlit과 plotly는 웹 기반 대시보드와 시각화에 활용됩니다.

제목: 데이터 분석 및 시각화 라이브러리 임포트

import pandas as pd           # 데이터프레임 처리용 라이브러리
import numpy as np            # 수치 연산 및 배열 처리용 라이브러리
import streamlit as st        # 웹 대시보드 및 UI 개발용 라이브러리
import plotly.express as px   # 대화형 시각화 라이브러리

이렇게 준비된 라이브러리들은 데이터의 전처리, 분석, 그리고 시각적 표현에 핵심적인 역할을 합니다. 특히 streamlit은 웹 개발 지식이 없어도 대시보드를 빠르게 만들 수 있다는 점에서 매우 유용합니다.

팁: streamlit 대시보드는 터미널에서 streamlit run 파일명.py로 실행해야 정상적으로 동작합니다.


3. 환경 변수 및 API 키 관리

보안 시스템에서 API 키와 같은 민감 정보는 코드에 직접 입력하지 않고, 환경 변수로 관리하는 것이 필수적입니다. 이를 위해 dotenv와 os 모듈을 활용합니다.

제목: 환경 변수 로드 및 API 키 추출

from dotenv import load_dotenv  # .env 파일을 읽기 위한 모듈
import os                      # 운영체제 환경 변수 접근 모듈

load_dotenv()  # .env 파일의 환경 변수를 시스템 환경 변수로 등록
api_key = os.getenv('OPENAI_API_KEY')  # 환경 변수에서 OpenAI API 키 추출
  • .env 파일에는 OPENAI_API_KEY=발급받은키 형식으로 저장합니다.

주의: .env 파일은 반드시 .gitignore에 추가하여 깃허브 등 외부 저장소에 노출되지 않도록 해야 합니다.


4. 데이터 로드 및 캐싱

실시간 로그 모니터링에서는 데이터 로드 속도가 매우 중요합니다. streamlit의 캐싱 기능을 활용하면 동일한 데이터를 반복해서 불러올 때 속도를 크게 개선할 수 있습니다.

제목: 로그 데이터 로드 및 캐싱

@st.cache_data
def load_data():
    frm = pd.read_csv('../data/attack_stream_logs.csv')  # CSV 파일에서 로그 데이터 읽기
    return frm

frm = load_data()  # 데이터프레임 형태로 반환
# 실행 결과: frm 변수에 로그 데이터프레임이 저장됨
  • @st.cache_data 데코레이터는 함수 실행 결과를 캐싱하여, 동일한 입력에 대해 반복 실행 시 속도를 높입니다.

5. 세션 상태 관리와 실시간 로그 누적

streamlit의 세션 상태(st.session_state)를 활용하면, 사용자별로 독립적인 로그 누적, 챗봇 대화 이력 등 다양한 상태 정보를 관리할 수 있습니다.

제목: 세션 상태 초기화

# 로그 누적용 데이터프레임 초기화
if 'logs' not in st.session_state:
    st.session_state['logs'] = pd.DataFrame(columns=frm.columns)
  • 세션 상태는 웹앱이 새로고침되거나 사용자가 접속을 종료할 때까지 유지됩니다.

6. 실시간 로그 모니터링 대시보드 구현

실제 로그 모니터링 시스템에서는 새로운 로그가 발생할 때마다 실시간으로 화면에 출력되고, 위험도가 높은 이벤트는 즉시 경고 메시지로 표시되어야 합니다.

실시간 로그 모니터링 뷰 함수

def view():
    st.set_page_config(page_title='모니터링')  # 대시보드 페이지 제목 설정
    st.caption('리얼타임 로그 감지 시뮬레이션 feat. attack_stream_logs.csv')  # 캡션 출력

    if 'logs' not in st.session_state:
        st.session_state['logs'] = pd.DataFrame(columns=frm.columns)

    logPrt = st.empty()      # 로그 출력 공간
    warningPrt = st.empty()  # 경고 메시지 공간
    st.markdown('---')
    st.write('리얼타임으로 로그를 스트링 중.......(5초마다)')

    for idx, row in frm.iterrows():
        newLog = row.to_dict()  # 현재 행을 딕셔너리로 변환

        # 로그 누적 (최신 로그가 위에)
        st.session_state['logs'] = pd.concat(
            [pd.DataFrame([newLog]), st.session_state['logs']]
        )

        # 위험 점수에 따라 경고 메시지
        if newLog['risk_score'] >= 85:
            warningPrt.warning('고위험 공격 감지!! 집중')
        else:
            warningPrt.info('시스템 정상 작동 중!! 집중하지마')

        logPrt.dataframe(st.session_state['logs'])  # 로그 출력

        time.sleep(5)  # 5초 대기
  • 5초마다 새로운 로그가 누적되어 출력되며, 위험 점수(risk_score)가 85 이상이면 경고 메시지가 표시됩니다.

7. LLM 및 LangChain을 활용한 RAG 챗봇 구현

7.1. LLM(대형 언어 모델) 활용의 필요성

대량의 로그 데이터를 사람이 직접 분석하는 것은 한계가 있습니다. LLM을 활용하면 로그 데이터의 요약, 분류, 위험도 평가, 자동 질의응답 등 반복적이고 방대한 데이터 처리에 효율성을 높일 수 있습니다. 다만, LLM의 응답 형식이 항상 일관적이지 않기 때문에, 후처리 과정이 반드시 필요합니다.

7.2. 프롬프트 엔지니어링

LLM을 효과적으로 활용하려면, 명확한 프롬프트(지시문)를 설계해야 합니다. 출력 형식(예: JSON)과 예시를 반드시 포함하여, LLM이 불필요한 텍스트를 포함하지 않도록 해야 합니다.

제목: LLM 프롬프트 설계 예시

system_content = """
너는 아주 멋진 사이버 보안 전문가야.
내가 업로드한 로그데이터를 기반으로 공격 유형, 국가, 위험도 등을 분석해줘.
json 형식 이외의 다른 텍스트는 절대 포함하지마(매우 중요).
예시)
[
    {"ip" : "1.2.3.4", "country" : "South Korea", "attack_type" : "SQL Injection", "status": "Blocked", "risk_level" : 8,  "latitude": 37.5665, "longitude": 126.9780}
]
"""

7.3. LLM 호출 및 응답 데이터 전처리

LLM의 응답에는 종종 마크다운 코드 블록(````json)이나 불필요한 텍스트가 포함될 수 있습니다. 이를 제거하기 위해 정규표현식(re` 모듈)을 사용합니다.

제목: LLM 응답 파싱 및 데이터프레임 변환

import re           # 정규표현식 모듈 임포트
import json         # JSON 파싱 모듈 임포트
import pandas as pd # 데이터프레임 모듈 임포트

csv_text = response.choices[0].message.content  # LLM 응답 텍스트

# 코드 블록 시작 부분 제거 (예: ```json 또는 ``` 제거)
csv_text = re.sub(r"^```[a-zA-Z]*\n?", "", csv_text)
# 코드 블록 끝 부분 제거 (예: ``` 제거)
csv_text = re.sub(r"```$", "", csv_text).strip()

data = json.loads(csv_text)  # JSON 문자열을 파이썬 객체로 변환
df = pd.DataFrame(data)      # 데이터프레임으로 변환
print(df)
# 출력 예시:
#         ip      country       attack_type      status  risk_level  latitude  longitude
# 0  1.2.3.4  South Korea  SQL Injection     Blocked          8   37.5665   126.9780

8. LangChain 기반 RAG 벡터스토어 및 챗봇 체인 구축

8.1. 로그 데이터 임베딩 및 벡터스토어 생성

RAG 챗봇을 구현하려면, 로그 데이터를 임베딩하여 벡터 데이터베이스(FAISS)에 저장해야 합니다. 이를 통해 사용자의 질문과 유사한 로그를 빠르게 검색할 수 있습니다.

제목: 벡터스토어 생성 함수

from langchain.embeddings.openai import OpenAIEmbeddings  # 텍스트 임베딩 생성용
from langchain.vectorstores import FAISS                 # 벡터 저장소(빠른 검색용)
from langchain.text_splitter import RecursiveCharacterTextSplitter  # 텍스트 분할

@st.cache_resource
def create_vector_store(frm):
    database = []
    for idx, row in frm.iterrows():
        # 로그 정보를 텍스트로 변환
        txt = f"time: {row['time']}, ip: {row['ip']}, country: {row['country']}, attack: {row['attack_type']}, description: {row['description']}"
        database.append(txt)

    # 텍스트 분할 (문서 단위)
    splitter = RecursiveCharacterTextSplitter(chunk_size=200, chunk_overlap=20)
    docs = splitter.create_documents(database)  # 문서 리스트 생성

    # OpenAI 임베딩 모델로 벡터화
    embeddings = OpenAIEmbeddings()
    vectorDB = FAISS.from_documents(docs, embeddings)  # FAISS 벡터스토어 생성

    return vectorDB

vectorDB = create_vector_store(frm)

8.2. LLM QA 체인 및 챗봇 인터페이스 구현

LangChain의 ConversationalRetrievalChain을 활용하면, 벡터스토어 기반 검색과 LLM을 결합한 RAG 챗봇을 쉽게 만들 수 있습니다.

제목: LLM QA 체인 생성 및 챗봇 응답

from langchain.chat_models import ChatOpenAI
from langchain.chains import ConversationalRetrievalChain

@st.cache_resource
def model():
    retriever = vectorDB.as_retriever(search_kwargs={'k': 10})  # top-10 유사 문서 검색
    llm = ChatOpenAI(model='gpt-4o-mini', temperature=0.9)      # OpenAI LLM 인스턴스
    qaChain = ConversationalRetrievalChain.from_llm(llm=llm, retriever=retriever)
    return qaChain

# 챗봇 인터페이스 예시
prompt = "이 IP가 최근 공격에 사용된 적이 있습니까?"
chain = model()
response = chain({
    "question": prompt,
    "chat_history": []
})
answer = response['answer']
print(answer)
# 출력: "IP 1.2.3.4는 최근 SQL Injection 공격에 사용되었습니다."

9. Plotly를 활용한 위험도 시각화

로그 데이터의 위험도 분포를 시각적으로 분석하면, 공격 패턴이나 이상 징후를 한눈에 파악할 수 있습니다. Plotly의 scatter_geo를 활용하면, 공격 IP의 지리적 분포도 시각화할 수 있습니다.

제목: Plotly 지도 시각화 예시

import plotly.express as px  # Plotly 시각화 모듈 임포트

# 예시 데이터프레임 생성
df = pd.DataFrame({
    'ip': ['1.2.3.4'],
    'latitude': [37.5665],
    'longitude': [126.9780],
    'risk_level': [8]
})

fig = px.scatter_geo(
    df,  # 데이터프레임
    lat='latitude',  # 위도 컬럼명
    lon='longitude',  # 경도 컬럼명
    color='risk_level',  # 색상 기준 컬럼명
    size='risk_level',  # 점 크기 기준 컬럼명
    hover_name='ip',  # 마우스 오버 시 표시할 정보
    projection='natural earth'  # 지도 투영 방식
)
fig.show()
# 실행 결과: 세계 지도 위에 공격 IP의 위치와 위험도가 시각화됨

주의: 지도 시각화가 정확하게 이루어지려면 위도/경도 값이 반드시 숫자형이고, 데이터가 정확해야 합니다.


10. 전체 코드 구조 및 실행 흐름

실제 프로젝트에서는 위의 모든 요소가 하나의 파이썬 파일에 통합되어 동작합니다. 주요 흐름은 다음과 같습니다.

  1. 라이브러리 임포트 및 환경 변수 로드
  2. 데이터 로드 및 캐싱
  3. 세션 상태 초기화
  4. 벡터스토어 및 LLM QA 체인 생성
  5. 실시간 로그 모니터링 및 챗봇 UI 구현
  6. if __name__ == '__main__': 블록에서 대시보드 실행

전체 흐름 요약

오늘 학습한 내용은 실시간 보안 로그 모니터링 시스템을 구축하는 전체 과정을 다룹니다. 데이터 분석, 시각화, LLM 및 LangChain 연동, 환경 변수 관리, 실시간 대시보드 설계, 그리고 RAG 챗봇 구현까지, 실제 현장에서 바로 활용할 수 있는 기술을 단계별로 익혔습니다. 각 단계에서 실무적인 주의사항과 팁, 그리고 초급자도 이해할 수 있도록 상세한 개념 설명과 코드 예시를 포함하였습니다.


주요 개념 요약표

개념 설명 예시/비고
LLM (대형 언어 모델) 대량의 텍스트 데이터를 이해하고 생성하는 인공지능 모델 OpenAI GPT-4o-mini 등
환경 변수(.env) 민감 정보(API 키 등)를 안전하게 관리하는 파일 .env 파일에 OPENAI_API_KEY=키값 저장
pandas, numpy 데이터프레임 처리 및 수치 연산용 라이브러리 pd.read_csv(), np.array() 등
streamlit 웹 대시보드 및 UI 구현 프레임워크 st.set_page_config(), st.dataframe()
plotly.express 대화형 데이터 시각화 라이브러리 px.scatter_geo()로 지도 시각화
LangChain LLM과 데이터, 워크플로우를 연결하는 프레임워크 RetrievalQA, ConversationalRetrievalChain 등
벡터스토어(FAISS) 임베딩된 텍스트를 빠르게 검색할 수 있는 벡터 데이터베이스 FAISS.from_documents()
프롬프트 엔지니어링 LLM이 일관된 형식으로 응답하도록 지시문을 설계하는 기법 JSON 형식 예시 포함, 불필요한 텍스트 금지 지시
정규표현식(re) 문자열에서 특정 패턴을 찾아 처리하는 파이썬 모듈 re.sub(), re.search() 등
세션 상태(st.session_state) streamlit에서 사용자별 상태(로그, 챗봇 이력 등) 관리 st.session_state[‘logs’] 등
@st.cache_data, @st.cache_resource streamlit의 함수/리소스 캐싱 데코레이터 데이터/모델 캐싱으로 성능 향상
실시간 로그 모니터링 5초마다 로그를 누적 출력, 위험도에 따라 경고 표시 time.sleep(5)로 시뮬레이션
RAG(Retrieval-Augmented Generation) 검색 기반 LLM 응답 생성, 로그 데이터와 챗봇 결합 LangChain의 ConversationalRetrievalChain 활용

공부 후기

오늘은 보안 로그 분석의 자동화와 실시간 시각화, 그리고 LLM 기반 챗봇 구현까지, 실제 보안 현장에서 활용할 수 있는 다양한 기술을 체계적으로 학습하였다. 각 단계별로 필요한 파이썬 라이브러리와 프레임워크의 역할을 명확히 이해할 수 있었고, 실무에서 자주 발생하는 실수와 주의사항도 함께 익혀 실전 감각을 높일 수 있었다. 특히 프롬프트 엔지니어링과 데이터 전처리, 그리고 벡터스토어 기반 RAG 챗봇 구현 과정이 인상적이었다. 앞으로 실제 프로젝트에 적용해보며, 더 깊이 있는 경험을 쌓고 싶다.

댓글 남기기