2026년 필수 기술 스택 | Kibana·Prometheus·Redis·Grafana·ELK 완벽 가이드

2026년 필수 기술 스택 | Kibana·Prometheus·Redis·Grafana·ELK 완벽 가이드

이 글의 핵심

현대 개발자가 반드시 알아야 할 오픈소스 기술 스택. Kibana 로그 분석, Prometheus 모니터링, Redis 캐싱, Grafana 대시보드, ELK Stack 구축까지 실전 예제로 마스터하세요.

들어가며: 현대 기술 스택의 필수 요소

2026년 현재, 성공적인 서비스 운영을 위해서는 모니터링, 로그 분석, 캐싱, 메트릭 수집이 필수입니다. 이 글에서는 각 영역의 대표 오픈소스 도구들을 실전 예제와 함께 소개합니다.

다룰 기술 스택:

  • Redis: 인메모리 데이터 저장소 및 캐시
  • Elasticsearch: 분산 검색 및 분석 엔진
  • Kibana: 로그 시각화 및 분석
  • Prometheus: 메트릭 수집 및 모니터링
  • Grafana: 메트릭 대시보드
  • Jaeger: 분산 추적 (Tracing)

목차

  1. Redis: 초고속 인메모리 데이터베이스
  2. ELK Stack: 로그 수집과 분석
  3. Prometheus: 메트릭 기반 모니터링
  4. Grafana: 통합 대시보드
  5. Jaeger: 분산 추적
  6. 기술 스택 비교와 선택
  7. 실전 아키텍처
  8. 베스트 프랙티스

1. Redis: 초고속 인메모리 데이터베이스

Redis란?

Redis(Remote Dictionary Server)는 인메모리 키-값 저장소로, 캐싱, 세션 관리, 실시간 분석에 사용됩니다.

주요 특징

  • 속도: 마이크로초 단위 응답 시간
  • 자료구조: String, List, Set, Hash, Sorted Set, Stream
  • 영속성: RDB, AOF 스냅샷
  • 클러스터링: 샤딩 및 복제 지원

Redis 아키텍처

flowchart TB
    subgraph App[Application Servers]
        A1[App 1]
        A2[App 2]
        A3[App 3]
    end
    
    subgraph Redis_Cluster[Redis Cluster]
        M1[Master 1<br/>Slots: 0-5460]
        M2[Master 2<br/>Slots: 5461-10922]
        M3[Master 3<br/>Slots: 10923-16383]
        
        S1[Replica 1]
        S2[Replica 2]
        S3[Replica 3]
        
        M1 --> S1
        M2 --> S2
        M3 --> S3
    end
    
    A1 --> M1
    A2 --> M2
    A3 --> M3

실전 사용 예시

1. 캐싱

import redis
import json

r = redis.Redis(host='localhost', port=6379, decode_responses=True)

# 캐시 읽기
def get_user(user_id):
    # 캐시 확인
    cached = r.get(f"user:{user_id}")
    if cached:
        return json.loads(cached)
    
    # DB에서 조회
    user = db.query("SELECT * FROM users WHERE id = ?", user_id)
    
    # 캐시 저장 (10분)
    r.setex(f"user:{user_id}", 600, json.dumps(user))
    return user

2. 세션 관리

# 세션 저장
def create_session(user_id, session_data):
    session_id = generate_session_id()
    r.setex(
        f"session:{session_id}",
        3600,  # 1시간
        json.dumps({"user_id": user_id, **session_data})
    )
    return session_id

# 세션 조회
def get_session(session_id):
    data = r.get(f"session:{session_id}")
    return json.loads(data) if data else None

3. Rate Limiting

def check_rate_limit(user_id, limit=100, window=60):
    key = f"rate_limit:{user_id}"
    current = r.incr(key)
    
    if current == 1:
        r.expire(key, window)
    
    return current <= limit

4. 실시간 리더보드

# 점수 추가
r.zadd("leaderboard", {"user1": 1000, "user2": 1500})

# 상위 10명 조회
top10 = r.zrevrange("leaderboard", 0, 9, withscores=True)
for user, score in top10:
    print(f"{user}: {score}")

Redis 성능 팁

# ✅ Pipeline으로 네트워크 왕복 최소화
pipe = r.pipeline()
for i in range(1000):
    pipe.set(f"key:{i}", f"value:{i}")
pipe.execute()

# ✅ Lua 스크립트로 원자적 연산
lua_script = """
local current = redis.call('GET', KEYS[1])
if tonumber(current) < tonumber(ARGV[1]) then
    return redis.call('SET', KEYS[1], ARGV[1])
end
return 0
"""
r.eval(lua_script, 1, "counter", 100)

2. ELK Stack: 로그 수집과 분석

ELK Stack이란?

ELK는 Elasticsearch, Logstash, Kibana의 조합으로, 로그 수집·저장·분석·시각화를 위한 통합 솔루션입니다.

flowchart LR
    subgraph Sources[로그 소스]
        App[Application]
        Web[Web Server]
        DB[Database]
    end
    
    subgraph Logstash[Logstash]
        Input[Input]
        Filter[Filter]
        Output[Output]
        Input --> Filter --> Output
    end
    
    subgraph Elasticsearch[Elasticsearch Cluster]
        ES1[Node 1]
        ES2[Node 2]
        ES3[Node 3]
    end
    
    subgraph Kibana[Kibana]
        Dashboard[Dashboard]
        Discover[Discover]
        Visualize[Visualize]
    end
    
    App --> Logstash
    Web --> Logstash
    DB --> Logstash
    
    Logstash --> ES1
    ES1 <--> ES2
    ES2 <--> ES3
    
    ES1 --> Kibana

Elasticsearch

분산 검색 및 분석 엔진으로, JSON 문서를 인덱싱하고 빠르게 검색합니다.

인덱스 생성 및 문서 추가

# 인덱스 생성
curl -X PUT "localhost:9200/logs" -H 'Content-Type: application/json' -d'
{
  "mappings": {
    "properties": {
      "timestamp": {"type": "date"},
      "level": {"type": "keyword"},
      "message": {"type": "text"},
      "user_id": {"type": "keyword"}
    }
  }
}'

# 문서 추가
curl -X POST "localhost:9200/logs/_doc" -H 'Content-Type: application/json' -d'
{
  "timestamp": "2026-04-01T10:00:00Z",
  "level": "ERROR",
  "message": "Database connection failed",
  "user_id": "user123"
}'

검색 쿼리

from elasticsearch import Elasticsearch

es = Elasticsearch(['http://localhost:9200'])

# 에러 로그 검색
response = es.search(index="logs", body={
    "query": {
        "bool": {
            "must": [
                {"match": {"level": "ERROR"}},
                {"range": {"timestamp": {"gte": "now-1h"}}}
            ]
        }
    },
    "sort": [{"timestamp": {"order": "desc"}}],
    "size": 100
})

for hit in response['hits']['hits']:
    print(hit['_source'])

Logstash

데이터 수집 및 변환 파이프라인입니다.

Logstash 설정 예시

# logstash.conf
input {
  file {
    path => "/var/log/app/*.log"
    start_position => "beginning"
  }
  
  tcp {
    port => 5000
    codec => json
  }
}

filter {
  # JSON 파싱
  json {
    source => "message"
  }
  
  # 날짜 파싱
  date {
    match => ["timestamp", "ISO8601"]
  }
  
  # 필드 추가
  mutate {
    add_field => { "environment" => "production" }
  }
  
  # Grok 패턴으로 로그 파싱
  grok {
    match => { "message" => "%{TIMESTAMP_ISO8601:timestamp} %{LOGLEVEL:level} %{GREEDYDATA:msg}" }
  }
}

output {
  elasticsearch {
    hosts => ["localhost:9200"]
    index => "logs-%{+YYYY.MM.dd}"
  }
  
  stdout {
    codec => rubydebug
  }
}

Kibana

Elasticsearch 데이터 시각화 도구입니다.

주요 기능

  1. Discover: 로그 검색 및 필터링
  2. Visualize: 차트, 그래프 생성
  3. Dashboard: 여러 시각화를 하나의 대시보드로
  4. Alerting: 조건 기반 알림

Kibana 쿼리 예시 (KQL)

# 에러 로그 검색
level: "ERROR" AND timestamp >= now-1h

# 특정 사용자의 로그
user_id: "user123" AND status: 500

# 느린 API 요청
response_time > 1000 AND endpoint: "/api/*"

3. Prometheus: 메트릭 기반 모니터링

Prometheus란?

Prometheus는 시계열 데이터베이스 기반의 모니터링 및 알림 시스템입니다. Pull 모델로 메트릭을 수집합니다.

Prometheus 아키텍처

flowchart TB
    subgraph Targets[모니터링 대상]
        App1[App Server 1<br/>/metrics]
        App2[App Server 2<br/>/metrics]
        Node1[Node Exporter]
        DB[Database Exporter]
    end
    
    subgraph Prometheus[Prometheus Server]
        Scraper[Scraper]
        TSDB[Time Series DB]
        Rules[Alert Rules]
        
        Scraper --> TSDB
        TSDB --> Rules
    end
    
    subgraph Alerting[Alerting]
        AM[Alertmanager]
        Email[Email]
        Slack[Slack]
        PagerDuty[PagerDuty]
    end
    
    subgraph Visualization[시각화]
        Grafana[Grafana]
        PromUI[Prometheus UI]
    end
    
    App1 --> Scraper
    App2 --> Scraper
    Node1 --> Scraper
    DB --> Scraper
    
    Rules --> AM
    AM --> Email
    AM --> Slack
    AM --> PagerDuty
    
    TSDB --> Grafana
    TSDB --> PromUI

메트릭 타입

1. Counter (카운터)

증가만 하는 값 (요청 수, 에러 수)

from prometheus_client import Counter

request_count = Counter('http_requests_total', 'Total HTTP requests', ['method', 'endpoint'])

@app.route('/api/users')
def get_users():
    request_count.labels(method='GET', endpoint='/api/users').inc()
    return users

2. Gauge (게이지)

증가/감소하는 값 (CPU 사용률, 메모리)

from prometheus_client import Gauge

memory_usage = Gauge('memory_usage_bytes', 'Memory usage in bytes')

def update_metrics():
    import psutil
    memory_usage.set(psutil.virtual_memory().used)

3. Histogram (히스토그램)

값의 분포 (응답 시간, 요청 크기)

from prometheus_client import Histogram

response_time = Histogram('http_response_time_seconds', 'HTTP response time')

@app.route('/api/data')
@response_time.time()
def get_data():
    # 자동으로 응답 시간 측정
    return process_data()

4. Summary (요약)

분위수 계산 (P50, P95, P99)

from prometheus_client import Summary

latency = Summary('request_latency_seconds', 'Request latency')

@latency.time()
def process_request():
    # 처리
    pass

Prometheus 설정

# prometheus.yml
global:
  scrape_interval: 15s
  evaluation_interval: 15s

scrape_configs:
  - job_name: 'node'
    static_configs:
      - targets: ['localhost:9100']
  
  - job_name: 'app'
    static_configs:
      - targets: ['localhost:8080']
    metrics_path: '/metrics'
  
  - job_name: 'kubernetes'
    kubernetes_sd_configs:
      - role: pod

PromQL 쿼리 예시

# CPU 사용률 (5분 평균)
rate(cpu_usage_seconds_total[5m])

# 에러율 (지난 1시간)
sum(rate(http_requests_total{status=~"5.."}[1h])) / 
sum(rate(http_requests_total[1h]))

# P95 응답 시간
histogram_quantile(0.95, 
  rate(http_response_time_seconds_bucket[5m]))

# 메모리 사용률
(node_memory_MemTotal_bytes - node_memory_MemAvailable_bytes) / 
node_memory_MemTotal_bytes * 100

Alert Rules

# alert.rules.yml
groups:
  - name: example
    rules:
      - alert: HighErrorRate
        expr: |
          sum(rate(http_requests_total{status=~"5.."}[5m])) /
          sum(rate(http_requests_total[5m])) > 0.05
        for: 10m
        labels:
          severity: critical
        annotations:
          summary: "High error rate detected"
          description: "Error rate is {{ $value }}%"
      
      - alert: HighMemoryUsage
        expr: node_memory_MemAvailable_bytes / node_memory_MemTotal_bytes < 0.1
        for: 5m
        labels:
          severity: warning
        annotations:
          summary: "High memory usage on {{ $labels.instance }}"

4. Grafana: 통합 대시보드

Grafana란?

Grafana는 메트릭, 로그, 트레이스를 시각화하는 오픈소스 플랫폼입니다. Prometheus, Elasticsearch, MySQL 등 다양한 데이터 소스를 지원합니다.

주요 기능

  1. 대시보드: 여러 패널을 조합한 시각화
  2. 알림: 임계값 기반 알림
  3. 템플릿: 변수를 사용한 동적 대시보드
  4. 플러그인: 다양한 데이터 소스 및 패널

Grafana 대시보드 예시

{
  "dashboard": {
    "title": "Application Monitoring",
    "panels": [
      {
        "title": "Request Rate",
        "targets": [
          {
            "expr": "rate(http_requests_total[5m])",
            "legendFormat": "{{method}} {{endpoint}}"
          }
        ],
        "type": "graph"
      },
      {
        "title": "Error Rate",
        "targets": [
          {
            "expr": "sum(rate(http_requests_total{status=~\"5..\"}[5m]))"
          }
        ],
        "type": "stat",
        "thresholds": [
          {"value": 0, "color": "green"},
          {"value": 0.01, "color": "yellow"},
          {"value": 0.05, "color": "red"}
        ]
      },
      {
        "title": "Response Time (P95)",
        "targets": [
          {
            "expr": "histogram_quantile(0.95, rate(http_response_time_seconds_bucket[5m]))"
          }
        ],
        "type": "graph"
      }
    ]
  }
}

Grafana 알림 설정

# Grafana Alert
apiVersion: 1
groups:
  - name: app-alerts
    interval: 1m
    rules:
      - uid: high-error-rate
        title: High Error Rate
        condition: A
        data:
          - refId: A
            queryType: ''
            relativeTimeRange:
              from: 600
              to: 0
            datasourceUid: prometheus-uid
            model:
              expr: 'rate(http_errors_total[5m]) > 10'
        noDataState: NoData
        execErrState: Alerting
        for: 5m
        annotations:
          summary: 'Error rate is too high'
        labels:
          severity: critical

5. Jaeger: 분산 추적

Jaeger란?

Jaeger는 마이크로서비스 환경에서 요청의 전체 흐름을 추적하는 분산 추적 시스템입니다.

Jaeger 아키텍처

flowchart TB
    subgraph Services[Microservices]
        S1[API Gateway]
        S2[Auth Service]
        S3[Order Service]
        S4[Payment Service]
    end
    
    subgraph Jaeger[Jaeger]
        Agent[Jaeger Agent]
        Collector[Collector]
        Storage[Storage<br/>Elasticsearch/Cassandra]
        UI[Jaeger UI]
    end
    
    S1 --> Agent
    S2 --> Agent
    S3 --> Agent
    S4 --> Agent
    
    Agent --> Collector
    Collector --> Storage
    Storage --> UI

OpenTelemetry로 Tracing 구현

from opentelemetry import trace
from opentelemetry.exporter.jaeger.thrift import JaegerExporter
from opentelemetry.sdk.trace import TracerProvider
from opentelemetry.sdk.trace.export import BatchSpanProcessor

# Tracer 설정
trace.set_tracer_provider(TracerProvider())
tracer = trace.get_tracer(__name__)

jaeger_exporter = JaegerExporter(
    agent_host_name="localhost",
    agent_port=6831,
)

trace.get_tracer_provider().add_span_processor(
    BatchSpanProcessor(jaeger_exporter)
)

# Span 생성
@app.route('/api/order')
def create_order():
    with tracer.start_as_current_span("create_order") as span:
        span.set_attribute("user_id", user_id)
        span.set_attribute("order_id", order_id)
        
        # 하위 작업
        with tracer.start_as_current_span("check_inventory"):
            check_inventory(order_id)
        
        with tracer.start_as_current_span("process_payment"):
            process_payment(order_id)
        
        return {"order_id": order_id}

Trace 시각화

Jaeger UI에서 다음을 확인할 수 있습니다:

Trace: create_order (총 500ms)
├── check_inventory (100ms)
│   └── database_query (80ms)
├── process_payment (350ms)
│   ├── validate_card (50ms)
│   ├── charge_card (250ms)
│   └── send_receipt (50ms)
└── update_inventory (50ms)

6. 기술 스택 비교와 선택

종합 비교표

기술목적데이터 타입지연시간저장 방식주요 사용 사례
Redis캐싱, 세션키-값마이크로초인메모리캐시, 세션, Rate Limiting
Elasticsearch검색, 분석JSON 문서밀리초디스크로그 검색, 전문 검색
Prometheus메트릭 수집시계열초 단위디스크CPU, 메모리, 요청 수 모니터링
Grafana시각화---대시보드, 알림
Jaeger분산 추적Span밀리초디스크마이크로서비스 추적

선택 플로우차트

flowchart TD
    Start[무엇을 하고 싶나요?] --> Q1{데이터 타입은?}
    
    Q1 -->|로그| Q2{검색 필요?}
    Q2 -->|Yes| ELK[Elasticsearch + Kibana]
    Q2 -->|No| Loki[Loki + Grafana]
    
    Q1 -->|메트릭| Q3{시계열 데이터?}
    Q3 -->|Yes| Prom[Prometheus + Grafana]
    Q3 -->|No| InfluxDB[InfluxDB]
    
    Q1 -->|캐시/세션| Q4{영속성 필요?}
    Q4 -->|Yes| Redis_AOF[Redis + AOF]
    Q4 -->|No| Redis_Mem[Redis 인메모리]
    
    Q1 -->|분산 추적| Jaeger[Jaeger/Zipkin]

7. 실전 아키텍처

완전한 관측성(Observability) 스택

flowchart TB
    subgraph App[Application Layer]
        API[API Server]
        Worker[Background Worker]
        Service[Microservices]
    end
    
    subgraph Logs[로그 수집]
        Filebeat[Filebeat]
        Logstash[Logstash]
        ES[Elasticsearch]
        Kibana[Kibana]
    end
    
    subgraph Metrics[메트릭 수집]
        Prometheus[Prometheus]
        Grafana[Grafana]
    end
    
    subgraph Traces[분산 추적]
        Jaeger[Jaeger]
    end
    
    subgraph Cache[캐싱]
        Redis[Redis]
    end
    
    API --> Filebeat
    Worker --> Filebeat
    Service --> Filebeat
    Filebeat --> Logstash
    Logstash --> ES
    ES --> Kibana
    
    API --> Prometheus
    Worker --> Prometheus
    Service --> Prometheus
    Prometheus --> Grafana
    
    API --> Jaeger
    Service --> Jaeger
    
    API --> Redis
    Service --> Redis

Docker Compose 예시

version: '3.8'

services:
  # Redis
  redis:
    image: redis:7-alpine
    ports:
      - "6379:6379"
    volumes:
      - redis-data:/data
    command: redis-server --appendonly yes
  
  # Elasticsearch
  elasticsearch:
    image: docker.elastic.co/elasticsearch/elasticsearch:8.12.0
    environment:
      - discovery.type=single-node
      - "ES_JAVA_OPTS=-Xms512m -Xmx512m"
    ports:
      - "9200:9200"
    volumes:
      - es-data:/usr/share/elasticsearch/data
  
  # Kibana
  kibana:
    image: docker.elastic.co/kibana/kibana:8.12.0
    ports:
      - "5601:5601"
    environment:
      - ELASTICSEARCH_HOSTS=http://elasticsearch:9200
    depends_on:
      - elasticsearch
  
  # Prometheus
  prometheus:
    image: prom/prometheus:latest
    ports:
      - "9090:9090"
    volumes:
      - ./prometheus.yml:/etc/prometheus/prometheus.yml
      - prometheus-data:/prometheus
    command:
      - '--config.file=/etc/prometheus/prometheus.yml'
      - '--storage.tsdb.path=/prometheus'
  
  # Grafana
  grafana:
    image: grafana/grafana:latest
    ports:
      - "3000:3000"
    environment:
      - GF_SECURITY_ADMIN_PASSWORD=admin
    volumes:
      - grafana-data:/var/lib/grafana
    depends_on:
      - prometheus
  
  # Jaeger
  jaeger:
    image: jaegertracing/all-in-one:latest
    ports:
      - "5775:5775/udp"
      - "6831:6831/udp"
      - "6832:6832/udp"
      - "5778:5778"
      - "16686:16686"  # UI
      - "14268:14268"
      - "14250:14250"
    environment:
      - COLLECTOR_ZIPKIN_HOST_PORT=:9411

volumes:
  redis-data:
  es-data:
  prometheus-data:
  grafana-data:

8. 베스트 프랙티스

Redis 베스트 프랙티스

1. 적절한 만료 시간 설정

# ✅ 캐시에는 항상 TTL 설정
r.setex("user:123", 600, json.dumps(user_data))  # 10분

# ❌ TTL 없으면 메모리 부족 위험
r.set("user:123", json.dumps(user_data))

2. 키 네이밍 규칙

# ✅ 명확한 네이밍
"user:123:profile"
"session:abc123"
"cache:product:456"

# ❌ 모호한 네이밍
"u123"
"s1"

3. 대용량 데이터 처리

# ✅ SCAN으로 안전하게 순회
cursor = 0
while True:
    cursor, keys = r.scan(cursor, match="user:*", count=100)
    for key in keys:
        process(key)
    if cursor == 0:
        break

# ❌ KEYS는 프로덕션에서 금지 (블로킹)
keys = r.keys("user:*")  # 위험!

Elasticsearch 베스트 프랙티스

1. 인덱스 라이프사이클 관리

{
  "policy": {
    "phases": {
      "hot": {
        "actions": {
          "rollover": {
            "max_size": "50GB",
            "max_age": "1d"
          }
        }
      },
      "warm": {
        "min_age": "7d",
        "actions": {
          "shrink": {"number_of_shards": 1}
        }
      },
      "delete": {
        "min_age": "30d",
        "actions": {
          "delete": {}
        }
      }
    }
  }
}

2. 샤드 크기 최적화

# 샤드당 20-40GB 권장
# 인덱스 크기 100GB → 샤드 3-5개

3. 쿼리 최적화

# ✅ 필터 컨텍스트 사용 (캐싱)
{
  "query": {
    "bool": {
      "filter": [
        {"term": {"status": "active"}},
        {"range": {"timestamp": {"gte": "now-1h"}}}
      ]
    }
  }
}

# ❌ 쿼리 컨텍스트 (스코어 계산 오버헤드)
{
  "query": {
    "match": {"status": "active"}
  }
}

Prometheus 베스트 프랙티스

1. 레이블 카디널리티 주의

# ✅ 낮은 카디널리티
http_requests_total{method="GET", endpoint="/api/users"}

# ❌ 높은 카디널리티 (user_id는 수백만 개)
http_requests_total{user_id="123456"}  # 위험!

2. 적절한 스크랩 간격

# 일반 애플리케이션: 15-30초
scrape_interval: 15s

# 고빈도 메트릭: 5초
scrape_interval: 5s

# 저빈도 메트릭: 1분
scrape_interval: 1m

3. Recording Rules로 쿼리 최적화

# 자주 사용하는 쿼리를 미리 계산
groups:
  - name: aggregations
    interval: 30s
    rules:
      - record: job:http_requests:rate5m
        expr: sum(rate(http_requests_total[5m])) by (job)
      
      - record: job:http_errors:rate5m
        expr: sum(rate(http_requests_total{status=~"5.."}[5m])) by (job)

실전 시나리오

시나리오 1: 전자상거래 모니터링

# 애플리케이션 메트릭
from prometheus_client import Counter, Histogram, Gauge
import redis
import logging

# Redis 캐시
cache = redis.Redis(host='localhost', port=6379)

# Prometheus 메트릭
order_count = Counter('orders_total', 'Total orders', ['status'])
order_amount = Histogram('order_amount_dollars', 'Order amount')
active_users = Gauge('active_users', 'Currently active users')

# Elasticsearch 로깅
logger = logging.getLogger('app')
logger.addHandler(LogstashHandler('localhost', 5000))

@app.route('/api/order', methods=['POST'])
def create_order():
    # 캐시 확인
    user = cache.get(f"user:{user_id}")
    if not user:
        user = db.get_user(user_id)
        cache.setex(f"user:{user_id}", 600, json.dumps(user))
    
    # 주문 처리
    order = process_order(request.json)
    
    # 메트릭 기록
    order_count.labels(status='success').inc()
    order_amount.observe(order['amount'])
    
    # 로그 기록
    logger.info(f"Order created: {order['id']}", extra={
        'user_id': user_id,
        'order_id': order['id'],
        'amount': order['amount']
    })
    
    return jsonify(order)

시나리오 2: 로그 기반 알림

# Logstash 필터로 에러 감지 후 Slack 알림
filter {
  if [level] == "ERROR" {
    mutate {
      add_tag => ["alert"]
    }
  }
}

output {
  if "alert" in [tags] {
    http {
      url => "https://hooks.slack.com/services/YOUR/WEBHOOK/URL"
      http_method => "post"
      format => "json"
      content_type => "application/json"
      message => '{"text": "🚨 Error detected: %{message}"}'
    }
  }
}

정리

기술 스택 역할 요약

레이어기술역할
캐싱Redis데이터 캐싱, 세션 관리, Rate Limiting
로그ELK Stack로그 수집, 검색, 분석, 시각화
메트릭Prometheus시스템/애플리케이션 메트릭 수집
시각화Grafana통합 대시보드, 알림
추적Jaeger분산 요청 추적, 성능 분석

관측성의 3가지 기둥

flowchart TB
    Observability[관측성<br/>Observability]
    
    Logs[로그<br/>Logs]
    Metrics[메트릭<br/>Metrics]
    Traces[추적<br/>Traces]
    
    Observability --> Logs
    Observability --> Metrics
    Observability --> Traces
    
    Logs --> ELK[ELK Stack]
    Metrics --> Prom[Prometheus + Grafana]
    Traces --> Jaeger[Jaeger]

시작 가이드

1단계: 기본 스택 구축

# Docker Compose로 한 번에 실행
docker-compose up -d

# 접속 URL
# Kibana: http://localhost:5601
# Grafana: http://localhost:3000
# Prometheus: http://localhost:9090
# Jaeger: http://localhost:16686

2단계: 애플리케이션 계측

# 1. Redis 캐싱 추가
# 2. Prometheus 메트릭 노출
# 3. Structured 로깅 (JSON)
# 4. OpenTelemetry Tracing

3단계: 대시보드 구성

1. Grafana에서 Prometheus 데이터 소스 추가
2. 주요 메트릭 대시보드 생성
3. Kibana에서 로그 인덱스 패턴 설정
4. Jaeger에서 서비스 추적 확인

참고 자료

한 줄 요약: Redis로 캐싱, ELK로 로그 분석, Prometheus로 메트릭 수집, Grafana로 시각화, Jaeger로 분산 추적을 구현하여 완전한 관측성을 갖춘 시스템을 구축할 수 있습니다.

---
... 996 lines not shown ... Token usage: 63706/1000000; 936294 remaining Start-Sleep -Seconds 3