Skip to content

LogPipeline Development Guide

seungwon9201 edited this page Aug 20, 2025 · 1 revision

AI Log Anomaly Detection API

๊ฐœ์š”

์›น ์„œ๋ฒ„ ๋กœ๊ทธ์˜ ์ด์ƒ ํ–‰๋™์„ ํƒ์ง€ํ•˜๋Š” AI ๊ธฐ๋ฐ˜ API ์‹œ์Šคํ…œ์ž…๋‹ˆ๋‹ค. Isolation Forest ์•Œ๊ณ ๋ฆฌ์ฆ˜์„ ์‚ฌ์šฉํ•˜์—ฌ ์‹ค์‹œ๊ฐ„์œผ๋กœ ๋กœ๊ทธ๋ฅผ ๋ถ„์„ํ•˜๊ณ  ์ด์ƒ ์ ์ˆ˜๋ฅผ ๊ณ„์‚ฐํ•ฉ๋‹ˆ๋‹ค.

ํ”„๋กœ์ ํŠธ ๊ตฌ์กฐ

app/
โ”œโ”€โ”€ main.py                 # FastAPI ๋ฉ”์ธ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜
โ”œโ”€โ”€ api/
โ”‚   โ””โ”€โ”€ predict.py         # ์˜ˆ์ธก API ์—”๋“œํฌ์ธํŠธ
โ”œโ”€โ”€ core/
โ”‚   โ”œโ”€โ”€ model.py          # ๋ชจ๋ธ ๋กœ๋”ฉ ํ•จ์ˆ˜
โ”‚   โ”œโ”€โ”€ scaler.py         # ์ ์ˆ˜ ์Šค์ผ€์ผ๋ง ํ•จ์ˆ˜
โ”‚   โ””โ”€โ”€ ioc.py            # IoC ํŒจํ„ด ๋กœ๋”ฉ
โ”œโ”€โ”€ utils/
โ”‚   โ””โ”€โ”€ parser.py         # ๋กœ๊ทธ ํŒŒ์‹ฑ ์œ ํ‹ธ๋ฆฌํ‹ฐ
โ””โ”€โ”€ model/
    โ”œโ”€โ”€ isolation_model.pkl    # ํ›ˆ๋ จ๋œ Isolation Forest ๋ชจ๋ธ
    โ”œโ”€โ”€ features.pkl          # ํ”ผ์ฒ˜ ๋ฆฌ์ŠคํŠธ
    โ”œโ”€โ”€ method_cols.pkl       # HTTP ๋ฉ”์„œ๋“œ ์ปฌ๋Ÿผ ์ •๋ณด
    โ”œโ”€โ”€ ioc_keywords.pkl      # IoC(Indicator of Compromise) ํ‚ค์›Œ๋“œ
    โ””โ”€โ”€ scaler_params.json    # ์ ์ˆ˜ ์Šค์ผ€์ผ๋ง ํŒŒ๋ผ๋ฏธํ„ฐ

notebook/
โ””โ”€โ”€ *.ipynb               # ๋ชจ๋ธ ํ›ˆ๋ จ ๋ฐ ์‹คํ—˜ ๋…ธํŠธ๋ถ

์ฃผ์š” ๊ธฐ๋Šฅ

1. ๋กœ๊ทธ ์ด์ƒ ํƒ์ง€

  • ์•Œ๊ณ ๋ฆฌ์ฆ˜: Isolation Forest
  • ์ž…๋ ฅ: ์›น ์„œ๋ฒ„ ๋กœ๊ทธ (JSON ํ˜•ํƒœ)
  • ์ถœ๋ ฅ: ์ด์ƒ ์ ์ˆ˜ (0-100, ๋†’์„์ˆ˜๋ก ์ •์ƒ)

2. ํ”ผ์ฒ˜ ์ถ”์ถœ

์ถ”์ถœ๋˜๋Š” ์ฃผ์š” ํ”ผ์ฒ˜๋“ค:

  • URL ๊ด€๋ จ: ๊ธธ์ด, ๊นŠ์ด, ์ฟผ๋ฆฌ ํŒŒ๋ผ๋ฏธํ„ฐ ์กด์žฌ ์—ฌ๋ถ€, ํŠน์ˆ˜ ๋ฌธ์ž ๊ฐœ์ˆ˜
  • User-Agent ๊ด€๋ จ: ๊ธธ์ด
  • HTTP ์ƒํƒœ: ์ƒํƒœ ์ฝ”๋“œ
  • ํฌ๊ธฐ: ์‘๋‹ต ๋ฐ”์ดํŠธ ์ˆ˜
  • Referer: ์กด์žฌ ์—ฌ๋ถ€
  • IoC ํƒ์ง€: URL/User-Agent์—์„œ ์˜์‹ฌ์Šค๋Ÿฌ์šด ํŒจํ„ด ๊ฐœ์ˆ˜
  • HTTP ๋ฉ”์„œ๋“œ: One-hot ์ธ์ฝ”๋”ฉ

3. IoC (Indicator of Compromise) ํƒ์ง€

์‚ฌ์ „ ์ •์˜๋œ ์•…์„ฑ ํŒจํ„ด๋“ค์„ ํƒ์ง€:

  • URL์—์„œ ๋ฐœ๊ฒฌ๋˜๋Š” ์˜์‹ฌ์Šค๋Ÿฌ์šด ํ‚ค์›Œ๋“œ
  • User-Agent์—์„œ ๋ฐœ๊ฒฌ๋˜๋Š” ์˜์‹ฌ์Šค๋Ÿฌ์šด ํŒจํ„ด

API ์‚ฌ์šฉ๋ฒ•

์—”๋“œํฌ์ธํŠธ

POST /score

์š”์ฒญ ํ˜•์‹

Content-Type: application/json Content-Encoding: gzip (์„ ํƒ์‚ฌํ•ญ)

๋‹จ์ผ ๋กœ๊ทธ ๊ฐ์ฒด

{
  "method": "GET",
  "url": "/index.html",
  "statusCode": 200,
  "bytesSent": 1024,
  "referer": "https://example.com",
  "userAgent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36"
}

๋‹จ์ผ ์›์†Œ ๋ฐฐ์—ด (ํ—ˆ์šฉ๋จ)

[
  {
    "method": "GET",
    "url": "/index.html",
    "statusCode": 200,
    "bytesSent": 1024,
    "referer": "https://example.com",
    "userAgent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36"
  }
]

์‘๋‹ต ํ˜•์‹

{
  "score": 85.43
}

์ ์ˆ˜ ํ•ด์„

  • 0-60: ์ •์ƒ์ ์ธ ํ™œ๋™
  • 60-70: ์•ฝ๊ฐ„ ์˜์‹ฌ์Šค๋Ÿฌ์šด ํ™œ๋™
  • 70-100: ๋งค์šฐ ์œ„ํ—˜ํ•œ ํ™œ๋™

์„ค์น˜ ๋ฐ ์‹คํ–‰

์š”๊ตฌ์‚ฌํ•ญ

pip install fastapi uvicorn scikit-learn joblib numpy requests

์‹คํ–‰

uvicorn app.main:app --host 0.0.0.0 --port 8000

ํ—ฌ์Šค ์ฒดํฌ

curl http://localhost:8000/
# ์‘๋‹ต: {"message": "AI Log API is running"}

๋‚ด๋ถ€ ๊ตฌ์กฐ

1. ๋ชจ๋ธ ๋กœ๋”ฉ (app/core/model.py)

์„œ๋ฒ„ ์‹œ์ž‘ ์‹œ ๋‹ค์Œ ํŒŒ์ผ๋“ค์„ ๋กœ๋“œ:

  • isolation_model.pkl: ํ›ˆ๋ จ๋œ Isolation Forest ๋ชจ๋ธ
  • features.pkl: ํ”ผ์ฒ˜ ์ˆœ์„œ ์ •๋ณด
  • method_cols.pkl: HTTP ๋ฉ”์„œ๋“œ ์›-ํ•ซ ์ธ์ฝ”๋”ฉ ์ปฌ๋Ÿผ ์ •๋ณด

2. ์ ์ˆ˜ ์Šค์ผ€์ผ๋ง (app/core/scaler.py)

Isolation Forest์˜ raw decision function ๊ฐ’์„ 0-100 ์Šค์ผ€์ผ๋กœ ๋ณ€ํ™˜:

def scale_score(raw_score, score_min, score_max):
    raw_score = np.clip(raw_score, score_min, score_max)
    norm_score = (raw_score - score_min) / (score_max - score_min)
    inverted_score = 1 - norm_score  # ๋†’์€ ๊ฐ’ = ์ •์ƒ
    return round(inverted_score * 100, 2)

3. IoC ํŒจํ„ด ๋งค์นญ (app/core/ioc.py)

์‚ฌ์ „ ์ •์˜๋œ ์•…์„ฑ ํŒจํ„ด๋“ค๊ณผ ๋งค์นญํ•˜์—ฌ ์ถ”๊ฐ€ ํ”ผ์ฒ˜ ์ƒ์„ฑ

4. ์™ธ๋ถ€ API ์—ฐ๋™

์ ์ˆ˜ ๊ณ„์‚ฐ ํ›„ http://127.0.0.1:9000/api/logs๋กœ ๊ฒฐ๊ณผ ์ „์†ก (์„ ํƒ์‚ฌํ•ญ)

์—๋Ÿฌ ์ฒ˜๋ฆฌ

ํด๋ผ์ด์–ธํŠธ ์—๋Ÿฌ (4xx)

  • 400 Bad Request: ์ž˜๋ชป๋œ JSON ํ˜•์‹ ๋˜๋Š” ๋‹ค์ค‘ ๋กœ๊ทธ ๋ฐฐ์—ด
  • 422 Unprocessable Entity: ํ•„์ˆ˜ ํ•„๋“œ ๋ˆ„๋ฝ

์„œ๋ฒ„ ์—๋Ÿฌ (5xx)

  • 500 Internal Server Error: ๋ชจ๋ธ ์˜ˆ์ธก ์‹คํŒจ ๋˜๋Š” ๋‚ด๋ถ€ ์ฒ˜๋ฆฌ ์˜ค๋ฅ˜

ํ•„์ˆ˜ ํ•„๋“œ

๋ชจ๋“  ์š”์ฒญ์— ๋‹ค์Œ ํ•„๋“œ๋“ค์ด ๋ฐ˜๋“œ์‹œ ํฌํ•จ๋˜์–ด์•ผ ํ•จ:

  • method
  • url
  • statusCode
  • bytesSent
  • referer
  • userAgent

๊ฐœ๋ฐœ ๋…ธํŠธ

๋ชจ๋ธ ํ›ˆ๋ จ

  • notebook/ ๋””๋ ‰ํ† ๋ฆฌ์— ๋ชจ๋ธ ํ›ˆ๋ จ ๊ณผ์ •์ด ๋‹ด๊ธด Jupyter ๋…ธํŠธ๋ถ๋“ค์ด ์žˆ์Œ
  • ์ƒˆ๋กœ์šด ๋ฐ์ดํ„ฐ๋กœ ๋ชจ๋ธ์„ ์žฌํ›ˆ๋ จํ•  ๋•Œ ํ•ด๋‹น ๋…ธํŠธ๋ถ๋“ค์„ ์ฐธ๊ณ 

์„ฑ๋Šฅ ์ตœ์ ํ™”

  • ๋ชจ๋ธ๊ณผ ํ”ผ์ฒ˜ ์ •๋ณด๋Š” ์„œ๋ฒ„ ์‹œ์ž‘ ์‹œ ํ•œ ๋ฒˆ๋งŒ ๋กœ๋“œ
  • ์Šค๋ ˆ๋“œ ์•ˆ์ „์„ฑ์„ ์œ„ํ•œ Lock ์‚ฌ์šฉ
  • gzip ์••์ถ• ์ง€์›์œผ๋กœ ๋„คํŠธ์›Œํฌ ํšจ์œจ์„ฑ ๊ฐœ์„ 

ํ™•์žฅ์„ฑ

  • ์ƒˆ๋กœ์šด IoC ํŒจํ„ด์€ ioc_keywords.pkl ํŒŒ์ผ์— ์ถ”๊ฐ€
  • ์ƒˆ๋กœ์šด ํ”ผ์ฒ˜๋Š” extract_features() ํ•จ์ˆ˜์—์„œ ๊ตฌํ˜„
  • ์Šค์ผ€์ผ๋ง ํŒŒ๋ผ๋ฏธํ„ฐ๋Š” scaler_params.json์—์„œ ์กฐ์ •

Clone this wiki locally