📊 Sesi 11 dari 16 — QA Cerdas

Analisis Log & Deteksi Anomali
Berbasis AI

Sistem produksi modern menghasilkan jutaan baris log per hari. AI membantu menemukan jarum anomali dalam tumpukan jerami log — sebelum pengguna merasakan dampaknya.

📋 Log Parsing & Drain Algorithm
🤖 LSTM & Isolation Forest
ELK Stack & AIOps
3 × 50 menit
🏭 Bagian 1 — Mengapa Log Analysis Butuh AI?

Dari 10 Baris Sehari Menjadi 10 Juta Baris per Jam

💡 ANALOGI — Dokter IGD di Hari Bencana

Tanpa AI: Seorang dokter IGD harus membaca 10 juta rekam medis dalam satu jam untuk menemukan pasien yang kritis. Mustahil dilakukan secara manual.

Dengan AI: Sistem triage otomatis langsung memflag pasien yang vital sign-nya anomali — dokter hanya perlu menangani kasus yang sudah diprioritaskan. AI melakukan screening, manusia melakukan judgment.

Inilah peran AI dalam analisis log: menyaring jutaan baris log untuk menemukan pola abnormal yang menandakan masalah, sebelum sistem benar-benar down.

10M+
baris log per jam dari satu microservice berskala medium
97%
log yang dihasilkan adalah noise tanpa nilai diagnostik langsung
3%
log yang mengandung sinyal penting — inilah yang harus ditemukan AI

📋 Contoh nyata: Netflix memproses lebih dari 500 miliar event log per hari. Manual analysis tidak mungkin — mereka menggunakan Anomaly Detection berbasis ML untuk mendeteksi degradasi performa sebelum pengguna melapor.

📋 Bagian 2 — Anatomi Log & Tantangan Parsing

Memahami Struktur Log Sistem

💡 ANALOGI — Rekam Medis yang Tidak Terstandar

Bayangkan 100 dokter di satu rumah sakit masing-masing menulis rekam medis dengan format berbeda — ada yang dalam Bahasa Indonesia, Inggris, ada yang menggunakan singkatan sendiri. Itulah masalah log parsing: setiap library, framework, dan developer menulis log dengan format berbeda. AI harus bisa memahami semuanya dan mengekstrak informasi yang sama.

2024-03-15 08:23:01.123 [INFO] payment-service — Transaction TX-9821 processed successfully for user U-4421, amount=Rp150.000
2024-03-15 08:23:01.891 [INFO] payment-service — Transaction TX-9822 processed successfully for user U-8832, amount=Rp75.000
2024-03-15 08:23:02.445 [WARN] payment-service — DB query latency=342ms (threshold=200ms) for operation=getUserBalance
2024-03-15 08:23:03.112 [ANOMALY] payment-service — 47 failed login attempts from IP 203.0.113.42 in 60s — possible brute force
2024-03-15 08:23:04.778 [ERROR] payment-service — Connection pool exhausted: 0/50 connections available
2024-03-15 08:23:05.002 [ERROR] payment-service — Transaction TX-9823 FAILED: timeout after 5000ms — NullPointerException at PaymentGateway.java:142
2024-03-15 08:23:05.891 [INFO] alert-manager — Alert CRITICAL triggered: payment-service error rate exceeded 30% threshold

Tantangan Log Parsing

Masalah Format
  • Timestamp berbeda: ISO 8601, Unix epoch, custom
  • Level log: DEBUG/INFO/WARN/ERROR/FATAL — tidak seragam
  • Free-text message: sulit di-parse secara rule-based
  • Multi-line stack traces dalam satu log entry
Solusi AI
  • Drain algorithm: clustering log templates otomatis
  • Regex + NLP: ekstraksi entitas dari free-text
  • Log schema inference: deduksi struktur otomatis
  • Logpai toolkit: parsing 16+ format log berbeda
🪐 Bagian 3 — Drain Algorithm: Log Template Mining

Mengekstrak Pola dari Log yang Tidak Terstruktur

💡 ANALOGI — Mengelompokkan Keluhan Pelanggan

Bayangkan 100.000 pesan keluhan customer service: "Pembayaran saya gagal jam 10:32", "Transaksi saya error jam 14:15", "Transfer saya tidak berhasil jam 09:00". Drain algorithm seperti staf yang cerdas yang mengelompokkan semua ini menjadi satu template: "Pembayaran/Transaksi/Transfer [USER_ACTION] [STATUS] jam [TIME]" — lalu bisa mendeteksi kapan template ini muncul secara anomali.

Cara Kerja Drain Algorithm

1

Preprocessing — Hapus Token Dinamis

Identifikasi dan mask token yang berubah-ubah: IP address, timestamp, user ID, angka. Contoh: "user U-4421 login from 192.168.1.1" menjadi "user <ID> login from <IP>"

2

Prefix Tree Matching — Temukan Template

Drain membangun parse tree berdasarkan panjang kata dan token pertama. Log baru diarahkan ke cabang yang paling cocok, lalu dibandingkan token per token.

3

Template Update — Generalisasi Pola

Jika dua log di cabang yang sama memiliki token berbeda di posisi yang sama, token itu digantikan dengan wildcard "<*>". Template menjadi semakin general seiring data baru masuk.

4

Output — Event Templates & Parameter Extraction

Setiap log dipetakan ke event template-nya. Parameter dinamis diekstrak secara terpisah. Hasilnya: structured log yang bisa dianalisis secara statistik dan ML.

🤖 Bagian 4 — Algoritma Deteksi Anomali

Dari Statistik Sederhana hingga Deep Learning

📋
Drain + Counting
Setelah log di-parse ke template, hitung frekuensi tiap template per window waktu. Spike atau drop tiba-tiba = anomali. Sederhana tapi efektif.
Unsupervised Count-Based
🧠
LSTM (DeepLog)
Mempelajari urutan normal log events. Jika event berikutnya tidak ada dalam top-k prediksi LSTM, itu anomali. State-of-the-art untuk sequential anomaly.
Deep Learning Sequential
🌳
Isolation Forest
Membangun isolation trees secara acak. Anomali lebih mudah "diisolasi" (path lebih pendek). Sangat cepat, efektif untuk high-dimensional data metric.
Tree-Based Unsupervised
🔁
Autoencoder
Neural network yang belajar merekonstruksi log normal. Error rekonstruksi tinggi pada log anomali. Cocok untuk mendeteksi pola kompleks yang tidak terdefinisi.
Deep Learning Reconstruction
📈
PCA-Based Detection
Log event counts diproyeksikan ke principal components. Data yang tidak cocok dengan subspace normal = anomali. Cepat, interpretable, cocok untuk baseline.
Statistical Linear

Perbandingan Algoritma

Algoritma Kecepatan Akurasi Kapan Digunakan
Drain + CountingSangat cepatMediumBaseline, real-time alerting sederhana
Isolation ForestCepatTinggiMetric anomaly, high-dim data, production
LSTM / DeepLogLambat (training)TertinggiComplex sequential patterns, critical systems
AutoencoderMediumTinggiUnknown anomaly patterns, unsupervised
PCA-BasedCepatMediumInterpretable, audit trail needed
📦 Bagian 5 — ELK Stack: Infrastruktur Log Analitik

Ekosistem Standar Industri untuk Log Management

💡 ANALOGI — Sistem Arsip Perpustakaan Modern

Elasticsearch = gudang arsip raksasa dengan index cepat — bisa mencari di antara miliaran dokumen dalam milidetik. Logstash = kurir yang mengumpulkan, memformat, dan mengantarkan dokumen ke gudang. Kibana = ruang baca interaktif di mana Anda bisa memvisualisasikan dan menganalisis apa pun yang ada di gudang. Beats = agen ringan di setiap server yang mengumpulkan log lokal untuk dikirim ke Logstash.

📊
Beats / Fluent Bit
Agen ringan di setiap server. Kumpulkan log, metric, uptime, network data.
🔧
Logstash / Kafka
Pipeline: filter, parse, enrich, transform. Routing ke berbagai output.
🔍
Elasticsearch
Distributed search engine. Index dan simpan miliaran log. Query dalam ms.
📉
Kibana + ML
Dashboard, visualisasi, alert. Built-in anomaly detection dengan ML jobs.

💡 Elastic ML Jobs adalah fitur built-in Kibana yang bisa membuat anomaly detection model secara otomatis dari time-series data di Elasticsearch — tanpa perlu kode Python sama sekali. Sangat populer di tim DevOps dan SRE.

⚡ Bagian 6 — AIOps: AI for IT Operations

Dari Reactive ke Predictive Operations

💡 ANALOGI — Dari Pemadam Kebakaran ke Pencegah Kebakaran

Ops tradisional (Reactive): Seperti pemadam kebakaran — tunggu ada api, baru bertindak. Alarm berbunyi saat database down, engineer terbangun jam 3 pagi, baru investigasi.

AIOps (Predictive): Seperti sensor asap yang mendeteksi panas berlebih sebelum api muncul. AI menganalisis tren metrik (memori naik perlahan, query time meningkat gradual) dan memperingatkan engineer sebelum terjadi kegagalan, sehingga bisa dicegah di jam kerja normal.

Kapabilitas AIOps

  • Event correlation — kaitkan alert dari 50+ sistem berbeda ke 1 root cause
  • Noise reduction — filter 90%+ alert redundan yang mengganggu
  • Anomaly detection — deteksi deviasi metrik sebelum threshold terlampaui
  • Root cause analysis otomatis — kurangi MTTR dari jam ke menit
  • Capacity prediction — prediksi kapan storage/CPU akan penuh
  • Incident prediction — peringatan dini sebelum SLA dilanggar

Tools AIOps Populer

  • Dynatrace Davis AI — auto-root cause dari ratusan alert dalam detik
  • Datadog ML — anomaly detection, forecast, watchdog
  • New Relic Applied Intelligence — incident intelligence & correlation
  • Grafana + Prometheus — open source monitoring & alerting stack
  • Splunk ITSI — enterprise-grade AIOps dengan glass table view
  • PagerDuty AIOps — intelligent alert routing & suppression

Metrik Keberhasilan AIOps

MTTR
Mean Time to Repair — target turun >50%
Alert Noise
Reduksi false alerts — target kurang dari 10% noise
Detection Lead
Waktu sebelum insiden terdeteksi — target 15+ menit
Coverage
% insiden yang diprediksi sebelum terjadi
🐍 Bagian 7 — Praktik: Anomali Detection pada Log

Implementasi dengan Isolation Forest & LSTM Konsep

Log Anomaly Detection — Isolation Forest + Log Pattern Analysis Python · scikit-learn · pandas · re
# ================================================================
# S11409 - Sesi 11: Log Anomaly Detection Pipeline
# Dosen: Riadi Marta Dinata, S.Ti., M.Kom. | ISTN Jakarta
# pip install scikit-learn pandas numpy matplotlib
# ================================================================

import re, json
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from sklearn.ensemble import IsolationForest
from sklearn.preprocessing import StandardScaler
from collections import Counter, defaultdict
from datetime import datetime, timedelta
import warnings; warnings.filterwarnings('ignore')

# ── STEP 1: GENERATE SYNTHETIC LOG DATA ──────────────────────
np.random.seed(42)

def generate_logs(n_normal=500, n_anomaly=30):
    """Generate simulated payment service logs"""
    logs = []
    base_time = datetime(2024, 3, 15, 8, 0, 0)

    # Normal logs - gaussian distributed latency
    for i in range(n_normal):
        t = base_time + timedelta(seconds=i * 0.5)
        latency = max(10, int(np.random.normal(120, 30)))  # ~120ms normal
        tx_id = f"TX-{9000 + i}"
        user_id = f"U-{np.random.randint(1000, 9999)}"
        amount = np.random.choice([50000, 75000, 100000, 150000, 200000])
        level = "INFO" if latency < 200 else "WARN"
        msg = f"Transaction {tx_id} processed for {user_id}, amount={amount}, latency={latency}ms"
        logs.append({"timestamp": t, "level": level, "latency": latency,
                     "msg": msg, "is_anomaly": 0})

    # Anomaly block - spike in errors and latency
    anomaly_start = base_time + timedelta(seconds=n_normal * 0.5 + 10)
    for i in range(n_anomaly):
        t = anomaly_start + timedelta(seconds=i * 0.3)
        latency = int(np.random.normal(800, 150))  # 800ms anomaly spike
        tx_id = f"TX-{9500 + i}"
        user_id = f"U-{np.random.randint(1000, 9999)}"
        level = np.random.choice(["ERROR", "WARN", "ERROR"], p=[0.6, 0.2, 0.2])
        if level == "ERROR":
            msg = f"Transaction {tx_id} FAILED: connection timeout after {latency}ms"
        else:
            msg = f"Transaction {tx_id} slow warning: latency={latency}ms exceeds threshold"
        logs.append({"timestamp": t, "level": level, "latency": latency,
                     "msg": msg, "is_anomaly": 1})

    df = pd.DataFrame(logs).sort_values("timestamp").reset_index(drop=True)
    return df

df = generate_logs()
print("=" * 60)
print("    LOG ANOMALY DETECTION PIPELINE")
print("    S11409 ISTN Jakarta | Sesi 11")
print("=" * 60)
print(f"\nTotal logs   : {len(df)}")
print(f"Normal logs  : {(df['is_anomaly']==0).sum()}")
print(f"Anomaly logs : {(df['is_anomaly']==1).sum()}")

# ── STEP 2: FEATURE ENGINEERING FROM LOGS ────────────────────
def engineer_features(df, window_size=20):
    """Extract time-window features for each log entry"""
    features = []
    for i in range(len(df)):
        start = max(0, i - window_size)
        window = df.iloc[start:i+1]

        feat = {
            "latency": df.iloc[i]["latency"],
            "is_error": 1 if df.iloc[i]["level"] == "ERROR" else 0,
            "is_warn":  1 if df.iloc[i]["level"] == "WARN"  else 0,
            # Window-based features
            "window_error_rate":  (window["level"] == "ERROR").mean(),
            "window_warn_rate":   (window["level"] == "WARN").mean(),
            "window_mean_latency": window["latency"].mean(),
            "window_max_latency":  window["latency"].max(),
            "window_std_latency":  window["latency"].std() if len(window) > 1 else 0,
            "window_p95_latency":  window["latency"].quantile(0.95),
        }
        features.append(feat)

    return pd.DataFrame(features)

print("\nEngineering features from log windows...")
X = engineer_features(df, window_size=20)
y_true = df["is_anomaly"].values

# ── STEP 3: ISOLATION FOREST ANOMALY DETECTION ───────────────
scaler = StandardScaler()
X_scaled = scaler.fit_transform(X)

# contamination = expected fraction of anomalies
iso_forest = IsolationForest(
    n_estimators=200,
    contamination=0.07,   # ~7% anomali yang kita harapkan
    max_samples="auto",
    random_state=42,
    n_jobs=-1
)

print("Training Isolation Forest...")
y_pred_raw = iso_forest.fit_predict(X_scaled)
y_pred = (y_pred_raw == -1).astype(int)  # -1 = anomali, 1 = normal
anomaly_scores = -iso_forest.score_samples(X_scaled)  # makin tinggi = lebih anomali

# ── STEP 4: EVALUATE ─────────────────────────────────────────
from sklearn.metrics import classification_report, confusion_matrix

print("\n--- Anomaly Detection Results ---")
print(classification_report(y_true, y_pred,
      target_names=["Normal", "Anomaly"]))

tp = ((y_pred==1) & (y_true==1)).sum()
fp = ((y_pred==1) & (y_true==0)).sum()
fn = ((y_pred==0) & (y_true==1)).sum()
tn = ((y_pred==0) & (y_true==0)).sum()
print(f"  True Positives  (caught anomalies): {tp}")
print(f"  False Positives (false alarms)    : {fp}")
print(f"  False Negatives (missed anomalies): {fn}")

# ── STEP 5: VISUALIZE ─────────────────────────────────────────
fig, axes = plt.subplots(2, 2, figsize=(14, 8))
fig.patch.set_facecolor('#0A0608')
fig.suptitle('Log Anomaly Detection Dashboard — S11409 ISTN',
             color='white', fontsize=13, fontweight='bold', y=1.01)

# Plot 1: Latency timeline with anomalies
ax1 = axes[0, 0]; ax1.set_facecolor('#160C0E')
ax1.plot(df.index, df['latency'], color='#9B7A80', alpha=0.5, linewidth=0.8, label='Latency')
anomaly_idx = np.where(y_pred == 1)[0]
ax1.scatter(anomaly_idx, df['latency'].iloc[anomaly_idx],
            color='#E8374F', s=25, zorder=5, label='Detected Anomaly')
ax1.axhline(y=200, color='#D4A017', linestyle='--', alpha=0.6, label='Threshold 200ms')
ax1.set_title('Response Latency Timeline', color='white')
ax1.tick_params(colors='#9B7A80')
ax1.legend(fontsize=8, facecolor='#160C0E', labelcolor='white')

# Plot 2: Anomaly score distribution
ax2 = axes[0, 1]; ax2.set_facecolor('#160C0E')
ax2.hist(anomaly_scores[y_true==0], bins=40, color='#22C55E', alpha=0.6, label='Normal')
ax2.hist(anomaly_scores[y_true==1], bins=20, color='#E8374F', alpha=0.7, label='Anomaly')
ax2.set_title('Anomaly Score Distribution', color='white')
ax2.tick_params(colors='#9B7A80')
ax2.legend(fontsize=9, facecolor='#160C0E', labelcolor='white')

# Plot 3: Log level distribution
ax3 = axes[1, 0]; ax3.set_facecolor('#160C0E')
level_counts = df['level'].value_counts()
colors_bar = ['#22C55E', '#F97316', '#E8374F'][:len(level_counts)]
ax3.bar(level_counts.index, level_counts.values, color=colors_bar, edgecolor='none')
ax3.set_title('Log Level Distribution', color='white')
ax3.tick_params(colors='#9B7A80')

# Plot 4: Window error rate
ax4 = axes[1, 1]; ax4.set_facecolor('#160C0E')
ax4.fill_between(range(len(X)), X['window_error_rate'],
                 color='#A78BFA', alpha=0.4, label='Error Rate (window)')
ax4.scatter(anomaly_idx, X['window_error_rate'].iloc[anomaly_idx],
            color='#E8374F', s=20, zorder=5, label='Anomaly Points')
ax4.set_title('Window Error Rate', color='white')
ax4.tick_params(colors='#9B7A80')
ax4.legend(fontsize=8, facecolor='#160C0E', labelcolor='white')

plt.tight_layout()
plt.savefig('log_anomaly_detection.png', dpi=150,
            facecolor='#0A0608', bbox_inches='tight')
print("\nVisualisasi tersimpan: log_anomaly_detection.png")

# ── STEP 6: ALERTING SIMULATION ──────────────────────────────
print("\n--- Alert Simulation (last 10 anomalies) ---")
anomaly_logs = df[y_pred == 1].tail(10)
for _, row in anomaly_logs.iterrows():
    score = anomaly_scores[row.name]
    severity = "CRITICAL" if score > 0.6 else "HIGH"
    print(f"  [{severity}] {row['timestamp'].strftime('%H:%M:%S')} "
          f"| Latency={row['latency']}ms | {row['level']} "
          f"| Score={score:.3f}")

print("\nDone! Jalankan dengan: python log_anomaly.py")
✎️ Latihan Mandiri
KUIS SESI 11

Uji Pemahaman Anda

Soal 1 — Drain Algorithm

Berikut 4 baris log dari payment service: (1) "User U-4421 paid Rp150000 at 08:01", (2) "User U-8832 paid Rp75000 at 08:02", (3) "User U-1234 paid Rp200000 at 08:05", (4) "User U-9999 FAILED payment at 08:06". Terapkan konsep Drain: (a) Identifikasi token dinamis, (b) Tulis 2 template log yang dihasilkan, (c) Mana yang anomali dan mengapa?

Soal 2 — Pemilihan Algoritma

Sistem e-commerce ingin mendeteksi: (a) Lonjakan tiba-tiba jumlah error dalam 1 menit, (b) Pola urutan login yang mencurigakan (login-gagal berulang lalu berhasil), (c) CPU usage yang naik gradual selama 2 jam sebelum crash. Rekomendasikan algoritma yang paling tepat untuk setiap kasus dan jelaskan alasannya.

Soal 3 — Isolation Forest

Isolation Forest memberikan anomaly score 0.82 untuk sebuah log entry. Jelaskan: (a) Apa arti score ini secara intuitif? (b) Mengapa anomali mendapat score lebih tinggi dari data normal dalam Isolation Forest? (c) Bagaimana Anda menentukan threshold yang tepat antara normal dan anomali?

Soal 4 — ELK Stack Design

ISTN ingin membangun sistem monitoring untuk SIAKAD yang melayani 5.000 mahasiswa. Log dihasilkan dari: web server, application server, database, dan payment gateway. Desain pipeline ELK Stack yang tepat: (a) Komponen mana yang dipasang di server mana? (b) Bagaimana Logstash memproses log berbeda format? (c) Alert apa yang harus dikonfigurasi di Kibana?

Soal 5 — Python Challenge

Modifikasi kode di atas: (a) Tambahkan deteksi "brute force login" — jika lebih dari 5 ERROR dalam 60 detik dari satu IP yang sama, flagging sebagai anomali keamanan; (b) Implementasikan rolling window statistic dengan window 50 log; (c) Tambahkan feature "log volume per second" dan amati apakah meningkatkan akurasi deteksi.

Rangkuman Kunci Sesi 11

97% log adalah noise — AI membantu menemukan 3% sinyal penting tanpa manusia membaca jutaan baris

Drain algorithm mengubah log teks bebas menjadi template terstruktur — fondasi untuk analisis statistik dan ML

Isolation Forest adalah pilihan terbaik untuk production: cepat, tidak butuh label, efektif untuk high-dimensional metrics

LSTM/DeepLog terbaik untuk sequential anomaly tapi butuh data training dan waktu komputasi lebih besar

ELK Stack adalah standar industri — Elasticsearch + Logstash + Kibana + Beats, tersedia versi open source

AIOps mengubah operasi dari reaktif ke prediktif — target utama: kurangi MTTR dan false alert >50%