OpenLiteSpeed ile Grafana ve İzleme Entegrasyonu

Production ortamında OpenLiteSpeed çalıştırıyorsunuz ve sunucunuzda ne olduğunu gerçek zamanlı görmek istiyorsunuz. “Neden yavaşladı?”, “Hangi saatte trafik patladı?”, “Memory neden bu kadar yüksek?” gibi soruların cevabını terminal çıktılarına bakarak bulmak artık yeterli değil. İşte tam bu noktada Grafana ve izleme stack’i devreye giriyor. Bu yazıda OpenLiteSpeed’i Prometheus, Node Exporter ve Grafana ile entegre ederek production-ready bir izleme sistemi kuracağız.

Genel Mimari ve Bileşenler

Kuruluma geçmeden önce ne inşa ettiğimizi netleştirelim. Sistemimiz şu bileşenlerden oluşacak:

  • OpenLiteSpeed: Web sunucumuz, access log ve status endpoint üretiyor
  • Node Exporter: Sunucu metrikleri (CPU, RAM, disk, network) topluyor
  • Prometheus: Metrikleri scrape edip depolayan time-series veritabanı
  • Grafana: Verileri görselleştiren dashboard katmanı
  • Loki (opsiyonel): Log aggregation için

Veri akışı şöyle işliyor: OpenLiteSpeed log üretiyor, Node Exporter sistem metriklerini expose ediyor, Prometheus bunları belirli aralıklarla çekip saklıyor, Grafana da Prometheus’u data source olarak kullanarak güzel dashboardlar çiziyor.

Bir e-ticaret sitesini düşünün. Black Friday öncesi trafik artışını önceden görmek, bottleneck’leri tespit etmek ve kapasite planlaması yapmak istiyorsunuz. Bu setup tam olarak bunu sağlıyor.

Sistem Hazırlığı

Ubuntu 22.04 üzerinde çalışıyoruz. OpenLiteSpeed’in zaten kurulu olduğunu varsayıyorum. Önce paket güncellemeleri:

sudo apt update && sudo apt upgrade -y
sudo apt install -y wget curl vim git unzip

Monitoring için ayrı bir kullanıcı oluşturalım:

sudo useradd --no-create-home --shell /bin/false prometheus
sudo useradd --no-create-home --shell /bin/false node_exporter

Dizin yapısını hazırlayalım:

sudo mkdir -p /etc/prometheus
sudo mkdir -p /var/lib/prometheus
sudo chown prometheus:prometheus /etc/prometheus
sudo chown prometheus:prometheus /var/lib/prometheus

Node Exporter Kurulumu

Node Exporter sisteminizin nabzını tutuyor. CPU kullanımı, memory, disk I/O, network trafiği gibi temel metriklerin hepsini /metrics endpoint’i üzerinden sunuyor.

# En güncel versiyonu indirin
wget https://github.com/prometheus/node_exporter/releases/download/v1.7.0/node_exporter-1.7.0.linux-amd64.tar.gz

tar xvf node_exporter-1.7.0.linux-amd64.tar.gz
sudo cp node_exporter-1.7.0.linux-amd64/node_exporter /usr/local/bin/
sudo chown node_exporter:node_exporter /usr/local/bin/node_exporter

Systemd service dosyası oluşturalım:

sudo vim /etc/systemd/system/node_exporter.service
[Unit]
Description=Node Exporter
Wants=network-online.target
After=network-online.target

[Service]
User=node_exporter
Group=node_exporter
Type=simple
ExecStart=/usr/local/bin/node_exporter 
    --collector.systemd 
    --collector.processes 
    --web.listen-address=127.0.0.1:9100

[Install]
WantedBy=multi-user.target

Dikkat edin, --web.listen-address=127.0.0.1:9100 ile sadece localhost’tan erişilebilir kıldık. Dışarıya expose etmek güvenlik riski oluşturur.

sudo systemctl daemon-reload
sudo systemctl start node_exporter
sudo systemctl enable node_exporter
sudo systemctl status node_exporter

Test edelim:

curl http://127.0.0.1:9100/metrics | head -20

Çıktıda go_gc_duration_seconds, node_cpu_seconds_total gibi metrikler görüyorsanız node_exporter çalışıyor demektir.

OpenLiteSpeed Status Endpoint’i Aktive Etme

OpenLiteSpeed’in kendi içinde bir server status modülü var. Bunu aktif etmeden Prometheus OLS’dan direkt metrik çekemez. Admin panel üzerinden yapılandıralım.

Admin paneline girin (varsayılan: https://sunucu-ip:7080). Server Configuration > General Settings altında Enable Status URL‘i aktif edin.

Alternatif olarak config dosyasını doğrudan düzenleyebilirsiniz:

sudo vim /usr/local/lsws/conf/httpd_config.conf

Config içinde şu bloğun var olduğundan emin olun:

statusURI               /.lstats
statusNSock             /tmp/lshttpd/.rtreport

Graceful restart uygulayın:

sudo /usr/local/lsws/bin/lswsctrl restart

OLS’nin status sayfasını test edelim:

curl http://127.0.0.1:80/.lstats

Çıktı şuna benzemelidir: REQ_RATE []: cur: 5, max: 143, limit: 0 gibi istatistikler. Bu verileri Prometheus’un anlayacağı formata çevirmek için bir exporter’a ihtiyacımız var.

LiteSpeed Prometheus Exporter Kurulumu

OpenLiteSpeed’in native Prometheus exporter’ı mevcut değil, ancak community tarafından geliştirilmiş çözümler var. litespeed_exporter kullanacağız:

# Exporter'ı derlemek için Go gerekiyor
wget https://go.dev/dl/go1.21.0.linux-amd64.tar.gz
sudo tar -C /usr/local -xzf go1.21.0.linux-amd64.tar.gz
export PATH=$PATH:/usr/local/go/bin

# Exporter'ı indir ve derle
git clone https://github.com/bjin/litespeed_exporter.git
cd litespeed_exporter
go build -o litespeed_exporter .
sudo cp litespeed_exporter /usr/local/bin/

Alternatif yaklaşım olarak Python tabanlı basit bir exporter yazabiliriz. Gerçek dünya senaryolarında bazen hazır araçları özelleştirmek gerekiyor:

sudo vim /usr/local/bin/ols_exporter.py
#!/usr/bin/env python3
"""
Basit OpenLiteSpeed Prometheus Exporter
/.lstats endpoint'ini parse ederek metrikleri expose eder
"""

import re
import time
import urllib.request
from http.server import HTTPServer, BaseHTTPRequestHandler

LSTATS_URL = "http://127.0.0.1:80/.lstats"
LISTEN_PORT = 9101

def fetch_ols_stats():
    try:
        with urllib.request.urlopen(LSTATS_URL, timeout=5) as response:
            return response.read().decode('utf-8')
    except Exception as e:
        print(f"Hata: {e}")
        return ""

def parse_stats(raw):
    metrics = []
    
    # REQ_RATE parse
    req_pattern = r'REQ_RATE [(S*)]: cur: (d+), max: (d+)'
    for match in re.finditer(req_pattern, raw):
        vhost = match.group(1) if match.group(1) else 'global'
        metrics.append(f'ols_req_rate_cur{{vhost="{vhost}"}} {match.group(2)}')
        metrics.append(f'ols_req_rate_max{{vhost="{vhost}"}} {match.group(3)}')
    
    # CONN_STATS parse
    conn_pattern = r'BPS_IN: (d+), BPS_OUT: (d+)'
    match = re.search(conn_pattern, raw)
    if match:
        metrics.append(f'ols_bps_in {match.group(1)}')
        metrics.append(f'ols_bps_out {match.group(2)}')
    
    return 'n'.join(metrics)

class MetricsHandler(BaseHTTPRequestHandler):
    def do_GET(self):
        if self.path == '/metrics':
            raw = fetch_ols_stats()
            output = parse_stats(raw)
            self.send_response(200)
            self.send_header('Content-Type', 'text/plain; version=0.0.4')
            self.end_headers()
            self.wfile.write(output.encode())
        else:
            self.send_response(404)
            self.end_headers()
    
    def log_message(self, format, *args):
        pass  # Log gürültüsünü bastır

if __name__ == '__main__':
    server = HTTPServer(('127.0.0.1', LISTEN_PORT), MetricsHandler)
    print(f"OLS Exporter port {LISTEN_PORT}'de başlatıldı")
    server.serve_forever()

Systemd service olarak ekleyelim:

sudo vim /etc/systemd/system/ols_exporter.service
[Unit]
Description=OpenLiteSpeed Prometheus Exporter
After=network.target

[Service]
Type=simple
User=nobody
ExecStart=/usr/bin/python3 /usr/local/bin/ols_exporter.py
Restart=always
RestartSec=5

[Install]
WantedBy=multi-user.target
sudo systemctl daemon-reload
sudo systemctl start ols_exporter
sudo systemctl enable ols_exporter

Prometheus Kurulumu ve Konfigürasyonu

wget https://github.com/prometheus/prometheus/releases/download/v2.48.0/prometheus-2.48.0.linux-amd64.tar.gz
tar xvf prometheus-2.48.0.linux-amd64.tar.gz
sudo cp prometheus-2.48.0.linux-amd64/prometheus /usr/local/bin/
sudo cp prometheus-2.48.0.linux-amd64/promtool /usr/local/bin/
sudo cp -r prometheus-2.48.0.linux-amd64/consoles /etc/prometheus
sudo cp -r prometheus-2.48.0.linux-amd64/console_libraries /etc/prometheus
sudo chown -R prometheus:prometheus /etc/prometheus

Ana konfigürasyon dosyasını oluşturalım:

sudo vim /etc/prometheus/prometheus.yml
global:
  scrape_interval: 15s
  evaluation_interval: 15s
  scrape_timeout: 10s

alerting:
  alertmanagers:
    - static_configs:
        - targets: []

rule_files:
  - "ols_alerts.yml"

scrape_configs:
  - job_name: 'prometheus'
    static_configs:
      - targets: ['localhost:9090']

  - job_name: 'node_exporter'
    static_configs:
      - targets: ['localhost:9100']
    relabel_configs:
      - source_labels: [__address__]
        target_label: instance
        regex: '([^:]+)(:[0-9]+)?'
        replacement: '${1}'

  - job_name: 'openlitespeed'
    static_configs:
      - targets: ['localhost:9101']
    metrics_path: /metrics
    scrape_interval: 10s

  - job_name: 'blackbox'
    metrics_path: /probe
    params:
      module: [http_2xx]
    static_configs:
      - targets:
          - https://siteniz.com
          - https://siteniz.com/health
    relabel_configs:
      - source_labels: [__address__]
        target_label: __param_target
      - source_labels: [__param_target]
        target_label: instance
      - target_label: __address__
        replacement: localhost:9115

Alert kuralları dosyasını oluşturalım:

sudo vim /etc/prometheus/ols_alerts.yml
groups:
  - name: openlitespeed_alerts
    rules:
      - alert: OLSHighCPU
        expr: 100 - (avg by(instance)(irate(node_cpu_seconds_total{mode="idle"}[5m])) * 100) > 80
        for: 5m
        labels:
          severity: warning
        annotations:
          summary: "Yüksek CPU kullanımı: {{ $value }}%"
          description: "{{ $labels.instance }} sunucusunda CPU kullanımı 5 dakikadır %80 üzerinde"

      - alert: OLSHighMemory
        expr: (node_memory_MemTotal_bytes - node_memory_MemAvailable_bytes) / node_memory_MemTotal_bytes * 100 > 85
        for: 3m
        labels:
          severity: critical
        annotations:
          summary: "Kritik RAM kullanımı tespit edildi"
          description: "Mevcut kullanım: {{ $value | printf "%.1f" }}%"

      - alert: OLSDiskWarning
        expr: (node_filesystem_size_bytes{fstype!="tmpfs"} - node_filesystem_free_bytes{fstype!="tmpfs"}) / node_filesystem_size_bytes{fstype!="tmpfs"} * 100 > 75
        for: 10m
        labels:
          severity: warning
        annotations:
          summary: "Disk doluluk uyarısı"
          description: "{{ $labels.mountpoint }} bölümü %75'in üzerine çıktı"

Prometheus systemd servisini oluşturalım:

sudo vim /etc/systemd/system/prometheus.service
[Unit]
Description=Prometheus Monitoring
Wants=network-online.target
After=network-online.target

[Service]
User=prometheus
Group=prometheus
Type=simple
ExecStart=/usr/local/bin/prometheus 
    --config.file /etc/prometheus/prometheus.yml 
    --storage.tsdb.path /var/lib/prometheus/ 
    --web.console.templates=/etc/prometheus/consoles 
    --web.console.libraries=/etc/prometheus/console_libraries 
    --storage.tsdb.retention.time=30d 
    --web.listen-address=127.0.0.1:9090

[Install]
WantedBy=multi-user.target
sudo systemctl daemon-reload
sudo systemctl start prometheus
sudo systemctl enable prometheus

Config dosyasını doğrulayalım:

promtool check config /etc/prometheus/prometheus.yml

Grafana Kurulumu

sudo apt-get install -y apt-transport-https software-properties-common
wget -q -O - https://packages.grafana.com/gpg.key | sudo apt-key add -
echo "deb https://packages.grafana.com/oss/deb stable main" | sudo tee /etc/apt/sources.list.d/grafana.list
sudo apt-get update && sudo apt-get install -y grafana
sudo systemctl start grafana-server
sudo systemctl enable grafana-server

Grafana varsayılan olarak 3000 portunda çalışıyor. Onu OpenLiteSpeed üzerinden reverse proxy ile sunacağız.

OpenLiteSpeed Reverse Proxy Konfigürasyonu

Grafana’yı doğrudan 3000 portu üzerinden açmak yerine OLS üzerinden monitor.siteniz.com gibi bir subdomain ile sunmak hem güvenli hem de profesyonel. Admin panelden yapılandıralım.

Admin panelinde Virtual Hosts > Yeni VHost Ekle ile monitor.siteniz.com için yeni bir virtual host oluşturun. Sonra External App altında Proxy ekleyin:

Config dosyası üzerinden de yapabilirsiniz:

sudo vim /usr/local/lsws/conf/vhosts/monitor/vhconf.conf
docRoot                   /var/www/html/monitor/
enableGzip                1
enableIpGeo               0

extprocessor grafana {
  type                    proxy
  address                 127.0.0.1:3000
  maxConns                100
  pcKeepAliveTimeout      60
  initTimeout             60
  retryTimeout            0
  respBuffer              0
}

context / {
  type                    proxy
  handler                 grafana
  addDefaultCharset       off
}

rewrite  {
  enable                  1
  rules                   <<<END_rules
RewriteCond %{HTTP:Upgrade} websocket [NC]
RewriteCond %{HTTP:Connection} upgrade [NC]
RewriteRule ^/?(.*) "ws://127.0.0.1:3000/$1" [P,L]
  END_rules
}

WebSocket desteği kritik, çünkü Grafana live dashboard güncellemeleri için WebSocket kullanıyor.

Grafana Dashboard Yapılandırması

Grafana’ya ilk kez giriş yapın (admin/admin), şifreyi değiştirin. Ardından data source ekleyin:

Configuration > Data Sources > Add data source > Prometheus

  • URL: http://127.0.0.1:9090
  • Access: Server (default)
  • Scrape interval: 15s

Save & Test butonuna tıklayın. “Data source is working” mesajı görmelisiniz.

Dashboard import için +Import kısmına gidin. Hazır dashboard ID’leri:

  • 1860: Node Exporter Full (sistem metrikleri için mükemmel)
  • 11074: Node Exporter for Prometheus Dashboard
  • 13659: BlackBox Exporter dashboard

Bu dashboard’ları import ettikten sonra kendi özel panellerinizi ekleyebilirsiniz.

Özel Grafana Panelleri ve PromQL Sorguları

Grafana’da yeni bir dashboard açın ve şu PromQL sorgularını içeren paneller oluşturun:

5 dakikalık request rate:

rate(ols_req_rate_cur[5m])

CPU kullanım yüzdesi:

100 - (avg(irate(node_cpu_seconds_total{mode="idle"}[5m])) * 100)

Memory kullanımı:

(node_memory_MemTotal_bytes - node_memory_MemAvailable_bytes) / node_memory_MemTotal_bytes * 100

Disk I/O:

rate(node_disk_read_bytes_total[5m])

Network throughput:

rate(node_network_receive_bytes_total{device!="lo"}[5m]) * 8

Bu sorgular gerçek zamanlı olarak güncelleniyor ve panel refresh interval’ını 30 saniyeye ayarlamanızı öneririm.

Log Tabanlı İzleme: OpenLiteSpeed Access Logları

Sadece metrikler yeterli değil. Access log analizi de kritik. OLS log formatını JSON’a çevirelim, bu Grafana Loki entegrasyonunu kolaylaştırır.

Admin panelde Log > Access Log kısmında log formatını düzenleyin:

# /usr/local/lsws/conf/httpd_config.conf içinde
logFormat "%h %l %u %t "%r" %>s %b "%{Referer}i" "%{User-agent}i" %D"
accessLog /usr/local/lsws/logs/access.log {
  rollingSize 100M
  keepDays 30
  compressArchive 1
}

Log analizi için basit bir bash scripti:

#!/bin/bash
# /usr/local/bin/ols_log_analyze.sh
# Son 1 saatin top IP ve URL'lerini raporla

LOG_FILE="/usr/local/lsws/logs/access.log"
REPORT_FILE="/tmp/ols_hourly_report.txt"

echo "=== OLS Saatlik Rapor: $(date) ===" > $REPORT_FILE
echo "" >> $REPORT_FILE

echo "--- Top 10 IP (istek sayısına göre) ---" >> $REPORT_FILE
awk '{print $1}' $LOG_FILE | sort | uniq -c | sort -rn | head -10 >> $REPORT_FILE

echo "" >> $REPORT_FILE
echo "--- HTTP Durum Kodu Dağılımı ---" >> $REPORT_FILE
awk '{print $9}' $LOG_FILE | sort | uniq -c | sort -rn >> $REPORT_FILE

echo "" >> $REPORT_FILE
echo "--- Top 10 Yavaş İstek (ms) ---" >> $REPORT_FILE
awk '{print $NF, $7}' $LOG_FILE | sort -rn | head -10 >> $REPORT_FILE

cat $REPORT_FILE

Bu scripti cron’a ekleyin:

# Her saat başı çalıştır
0 * * * * /usr/local/bin/ols_log_analyze.sh | mail -s "OLS Saatlik Rapor" [email protected]

Alertmanager ile Bildirim Sistemi

Alertmanager kurarak kritik durumlarda e-posta veya Slack bildirimi alabilirsiniz:

wget https://github.com/prometheus/alertmanager/releases/download/v0.26.0/alertmanager-0.26.0.linux-amd64.tar.gz
tar xvf alertmanager-0.26.0.linux-amd64.tar.gz
sudo cp alertmanager-0.26.0.linux-amd64/alertmanager /usr/local/bin/
sudo mkdir -p /etc/alertmanager

sudo vim /etc/alertmanager/alertmanager.yml
global:
  smtp_smarthost: 'smtp.gmail.com:587'
  smtp_from: '[email protected]'
  smtp_auth_username: '[email protected]'
  smtp_auth_password: 'uygulama-sifresi'

route:
  group_by: ['alertname', 'severity']
  group_wait: 30s
  group_interval: 5m
  repeat_interval: 4h
  receiver: 'email-alerts'
  routes:
    - match:
        severity: critical
      receiver: 'email-alerts'
      repeat_interval: 1h

receivers:
  - name: 'email-alerts'
    email_configs:
      - to: '[email protected]'
        subject: '[OLS Alert] {{ .GroupLabels.alertname }}'
        body: |
          {{ range .Alerts }}
          Alert: {{ .Annotations.summary }}
          Detay: {{ .Annotations.description }}
          Zaman: {{ .StartsAt }}
          {{ end }}

Güvenlik Sertleştirmesi

İzleme sistemini internete açarken dikkatli olun. Grafana için authentication zorunlu, Prometheus ve exporterlar için basic auth ekleyelim:

# Prometheus basic auth için htpasswd oluştur
sudo apt install apache2-utils -y
htpasswd -nBC 12 admin
# Oluşan hash'i not alın

sudo vim /etc/prometheus/web.yml
basic_auth_users:
  admin: $2y$12$xxxx...  # htpasswd çıktısı

Prometheus’u şu flag ile başlatın:

--web.config.file=/etc/prometheus/web.yml

Ayrıca UFW ile portları kısıtlayın:

# Sadece gerekli portları aç
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw allow 7080/tcp  # OLS admin, sadece güvendiğiniz IP'den
# 9090, 9100, 9101 portlarını dışarıya AÇMAYIN
sudo ufw enable

Performans Baselining ve Kapasite Planlaması

Gerçek dünyadaki değerini şurada görüyorsunuz: 2 haftalık veri toplandıktan sonra Grafana’da trend analizi yapabilirsiniz. “Her cuma akşamı 20:00-22:00 arası CPU %70’e çıkıyor” gibi pattern’lar ortaya çıkar.

Grafana’da Explore sekmesine gidin ve şu sorguyu çalıştırın:

avg_over_time(node_load1[7d])

Bu sorgu 7 günlük ortalama load average’ı gösterir. Bunu günün saatlerine göre breakdown ederek peak saatlerinizi net görürsünüz. Bu veri ile hangi saatte ek kapasite planlaması yapmanız gerektiğini, auto-scaling threshold’larını veya CDN cache stratejinizi revize etmeniz gerekip gerekmediğini somut veriye dayalı karar verebilirsiniz.

Sonuç

OpenLiteSpeed ile Grafana entegrasyonu başlangıçta biraz setup gerektiriyor ama bir kez kurulduktan sonra değeri tartışmasız. Artık “sunucu neden yavaşladı?” sorusuna “bilmiyorum” demek yerine tam olarak ne zaman, nerede ve neden yavaşladığını grafik üzerinde gösterebiliyorsunuz.

Pratik tavsiyelerim şunlar: İlk kurulumda hazır dashboard’larla başlayın, üretim ortamını tanıdıkça kendi custom panellerinizi ekleyin. Alert threshold’larını gerçek baseline veriye göre ayarlayın, çok düşük set ederseniz alert fatigue yaşarsınız. Prometheus retention süresini disk kapasitenize göre belirleyin, 30 gün genellikle makul. Ve son olarak, izleme sisteminin kendisini de izleyin: Prometheus down olduğunda haberiniz olsun diye harici bir uptime monitoring servisi (UptimeRobot gibi) paralelde çalıştırın.

Bu stack ile artık reactive değil, proactive bir sysadmin olarak çalışabilirsiniz.

Yorum yapın