Access Log #
Access log (log akses) adalah catatan kronologis terstruktur dari setiap permintaan HTTP (HTTP request) yang diterima dan diproses oleh server web Caddy. Log akses berfungsi sebagai kotak hitam pesawat bagi infrastruktur web kita—merekam siapa yang meminta sumber daya, halaman apa yang diakses, kapan transaksi terjadi, berapa status respons yang dikembalikan, berapa lama waktu pemrosesan berlangsung, hingga ukuran data yang ditransmisikan. Memiliki log akses yang dikonfigurasi dengan baik sangat krusial untuk memantau performa latensi respons, melakukan audit keamanan pasca-insiden, mendeteksi serangan siber secara real-time, serta memenuhi standar regulasi kepatuhan (compliance audit). Caddy menyediakan direktif log bawaan yang sangat kuat, modular, dan secara native merekam informasi dalam format JSON terstruktur yang ramah terhadap mesin pengumpul log modern. Kita akan membahas secara mendalam peran strategis log akses, mempraktikkan konfigurasi logging modular per situs (per-site logging), mengupas anatomi skema JSON log Caddy, mempelajari taktik penyaringan log (filtering) untuk menghemat ruang disk, serta menyusun konfigurasi log sampling untuk menyeimbangkan performa server di bawah lalu lintas tinggi.
Peran Strategis Access Log di Lingkungan Produksi #
Dalam pengelolaan server skala industri, mengabaikan atau mematikan log akses demi alasan performa adalah keputusan yang sangat berisiko. Log akses bukan sekadar baris teks sampah yang memenuhi kapasitas hard disk; ia adalah sumber data mentah tak ternilai bagi operasional dan bisnis kita.
Ada empat peran utama log akses di lingkungan produksi:
1. Audit Trail Keamanan (Security Auditing) #
Jika server kita mengalami pembobolan atau percobaan eksploitasi celah keamanan (seperti SQL injection atau bypass otentikasi), log akses adalah satu-satunya saksi bisu yang mencatat alamat IP pelaku, waktu penyerangan secara presisi, User-Agent yang digunakan, serta payload parameter URL yang dicoba dikirimkan.
2. Pemantauan Kinerja Aplikasi (Performance Monitoring) #
Caddy mencatat metrik durasi pemrosesan permintaan hingga tingkat mikrodetik. Dengan menganalisis log akses secara berkala, kita dapat mendeteksi jika ada endpoint API tertentu yang tiba-tiba mengalami lonjakan latensi (slow response), membantu kita melakukan tindakan optimasi database atau penambahan kapasitas server sebelum pengguna akhir merasakan kelambatan aplikasi.
3. Analisis Bisnis dan Perilaku Pengguna #
Meskipun ada alat pelacak sisi klien seperti Google Analytics, alat tersebut sering kali diblokir oleh ekstensi ad-blocker browser klien. Log akses mencatat lalu lintas murni di tingkat server jaringan, memberikan data yang 100% akurat mengenai jumlah hits, sistem operasi pengunjung, dan distribusi geografis akses.
4. Integrasi Deteksi Ancaman Otomatis #
Alat keamanan otomatis seperti Fail2ban atau skrip monitoring internal kita mengandalkan pembacaan log akses secara dinamis untuk mendeteksi pola akses mencurigakan (seperti ribuan request error 404 dalam hitungan detik yang menandakan serangan directory brute force), lalu memicu blokir otomatis di tingkat firewall sistem operasi.
Direktif log di Caddy: Modular dan Per-Site Logging
#
Caddy memiliki pendekatan yang sangat modular dalam penanganan log. Tidak seperti Nginx yang secara bawaan menyatukan log seluruh virtual host ke dalam satu file global access.log sebelum dipisah manual, Caddy membolehkan kita mendefinisikan aturan logging secara indeks independen langsung di dalam masing-masing blok server (per-site logging).
Sintaks dasar direktif log adalah sebagai berikut:
log [<name>] {
output <writer_module> ...
format <encoder_module> ...
level <level_name>
}
Contoh Konfigurasi Produksi Per-Site Logging #
# Contoh: Logging Terpisah untuk Subdomain Berbeda
api.example.com {
# 1. Aktifkan access log khusus untuk domain API
# Log disimpan di file terpisah dengan format JSON
log {
output file /var/log/caddy/api_access.log
format json
}
reverse_proxy localhost:8080
}
dashboard.example.com {
# 2. Aktifkan access log khusus untuk domain Dashboard
log {
output file /var/log/caddy/dashboard_access.log
format json
}
root * /var/www/dashboard
file_server
}
Dengan memisahkan berkas log seperti di atas, tim pengembang API dapat fokus memantau berkas api_access.log tanpa terganggu oleh catatan lalu lintas berkas gambar statis dari subdomain dashboard.
Keunggulan dan Struktur JSON Log Format Caddy #
Secara bawaan, jika kita tidak menentukan modul format secara eksplisit, Caddy akan merekam data log dalam format JSON terstruktur (structured JSON). Keputusan desain ini adalah lompatan besar dibanding server web tradisional yang masih menggunakan format teks baris biasa (Common Log Format atau CLF).
Mengapa Harus JSON Terstruktur? #
Format Baris Biasa (Apache/Nginx CLF):
127.0.0.1 - - [16/Jun/2026:18:30:00 +0700] "GET /api/data HTTP/1.1" 200 2326
✗ JANGAN gunakan ini di sistem modern: Membutuhkan regex kompleks untuk parsing.
✗ Rentan error jika user-agent mengandung karakter spasi atau tanda kutip ganda.
Format JSON Terstruktur (Caddy):
{"level":"info","ts":1781609400,"request":{"remote_ip":"127.0.0.1","proto":"HTTP/1.1","method":"GET","uri":"/api/data"},"status":200,"size":2326}
✓ BENAR: Bisa dibaca langsung oleh semua bahasa pemrograman tanpa regex.
✓ Siap dikirim ke log aggregator (Loki, Elasticsearch, Datadog) tanpa parser tambahan.
Anatomi Field Utama JSON Log Caddy #
Mari kita bedah struktur file JSON log nyata yang dihasilkan oleh Caddy:
{
"level": "info",
"ts": 1781609400.123456,
"logger": "http.log.access.log0",
"msg": "handled request",
"request": {
"remote_ip": "203.0.113.50",
"remote_port": "54321",
"client_ip": "203.0.113.50",
"proto": "HTTP/2.0",
"method": "GET",
"host": "api.example.com",
"uri": "/v1/users?limit=10",
"headers": {
"User-Agent": ["Mozilla/5.0 ..."],
"Accept": ["application/json"]
},
"tls": {
"resumed": false,
"version": 772,
"cipher_suite": 4865,
"proto": "h2",
"server_name": "api.example.com"
}
},
"user_id": "",
"duration": 0.045231,
"size": 1240,
"status": 200,
"resp_headers": {
"Content-Type": ["application/json"],
"Server": ["Caddy"]
}
}
Berikut adalah penjelasan detail mengenai field yang dihasilkan pada payload JSON log di atas:
| Nama Field JSON | Tipe Data | Deskripsi Fungsionalitas Data |
|---|---|---|
ts | float64 | Waktu saat request diproses, ditulis dalam format Unix epoch (detik desimal). |
duration | float64 | Waktu respons pemrosesan Caddy mulai dari pembacaan koneksi TCP hingga akhir respons (detik desimal). |
size | int64 | Ukuran bodi respons HTTP yang dikirimkan ke klien (dalam satuan byte). |
status | int | Status kode respons HTTP (e.g. 200, 404, 500). |
request.remote_ip | string | Alamat IP klien yang terhubung secara fisik (koneksi TCP socket). |
request.client_ip | string | IP pengunjung asli setelah memproses header proxy tepercaya (seperti X-Forwarded-For). |
request.proto | string | Protokol HTTP yang digunakan (HTTP/1.1, HTTP/2.0, HTTP/3.0). |
request.tls | object | Informasi parameter jabat tangan SSL/TLS (versi SSL, sandi cipher suite, SNI server_name). |
Hasil Kompilasi Adapter Caddy (Caddy Adapt) untuk Log #
Saat kita memicu perintah caddy adapt untuk mengubah Caddyfile deklaratif kita menjadi berkas JSON konfigurasi asli Caddy, modul adapter secara otomatis akan menyusun blok logging global yang dipadukan dengan konfigurasi per rute.
Berikut adalah ilustrasi cuplikan format kompilasi Caddy JSON hasil adaptasi untuk blok logging access log kita:
{
"logging": {
"logs": {
"log0": {
"writer": {
"output": "file",
"filename": "/var/log/caddy/api_access.log"
},
"encoder": {
"format": "json"
},
"include": [
"http.log.access.log0"
]
}
}
}
}
Dalam representasi JSON di atas, kita melihat bahwa Caddy memetakan pengidentifikasi internal log0 ke dalam format writer biner lokal, yang membuktikan betapa terstruktur dan modularnya seluruh sistem logging di bawah kap mesin runtime Caddy.
Log Filtering (Penyaringan Log) #
Di situs web dengan lalu lintas tinggi, berkas log akses dapat membengkak hingga puluhan gigabyte dalam hitungan hari. Sebagian besar isi berkas log tersebut biasanya dipenuhi oleh pemanggilan aset statis (seperti berkas .png, .jpg, .css, atau .js) atau request pemeriksaan kesehatan (health check) berkala dari load balancer depan yang tidak bernilai tinggi untuk audit keamanan.
Kita dapat mengonfigurasi filter rute di Caddy untuk mengecualikan (exclude) request-request non-penting tersebut dari pencatatan log akses guna menghemat kapasitas hard disk secara signifikan.
Sintaksis Penulisan Log Filter di Caddyfile #
# Contoh: Konfigurasi Filter Log Produksi
example.com {
# 1. Definisikan named matcher untuk rute yang TIDAK ingin dicatat di log
# Kita menyaring aset statis dan rute health check
@non_loggable {
path *.png *.jpg *.jpeg *.gif *.svg *.css *.js *.ico
path /healthz /ping
}
# 2. Konfigurasikan log dengan opsi filter
log {
output file /var/log/caddy/access.log
format json
# ✓ BENAR: Abaikan logging untuk request yang cocok dengan matcher @non_loggable
exclude @non_loggable
}
root * /var/www/html
file_server
}
Dengan konfigurasi di atas, jika klien meminta berkas /logo.png atau memanggil rute /healthz, Caddy tetap akan memproses dan menyajikan berkas tersebut dengan status 200 OK, namun Caddy tidak akan menuliskan satu baris pun ke dalam berkas /var/log/caddy/access.log. Ini menghemat kapasitas tulis disk I/O kita.
Log Sampling untuk Infrastruktur Traffic Tinggi #
Jika situs kita melayani traffic yang sangat ekstrem (misalnya puluhan ribu request per detik), menuliskan log akses untuk setiap transaksi tunggal ke dalam media penyimpanan lokal dapat menyebabkan degradasi performa I/O disk serius (disk bottleneck).
Untuk mengatasi skenario ini tanpa mematikan log akses sepenuhnya, Caddy menyediakan fitur Log Sampling (Pengambilan Sampel Log). Fitur ini membolehkan kita menetapkan aturan untuk hanya menulis sebagian persentase log ke dalam berkas secara acak atau berdasarkan kelipatan kuota.
Penulisan Caddyfile Log Sampling #
# Contoh: Log Sampling untuk Lalu Lintas Ekstrem
example.com {
log {
output file /var/log/caddy/access.log
format json
# Konfigurasi Sampling:
# Hanya catat 10% dari total log akses yang sukses (status 200)
# Parameter: interval pengamatan & batas maksimal log yang ditulis per interval
sampling {
# Interval waktu sampling (misal 1 detik)
interval 1s
# Batas maksimal log pertama yang selalu ditulis secara lengkap per interval
first 100
# Kelipatan pencatatan log setelah batas "first" terlampaui
# Nilai 10 artinya: Caddy hanya mencatat 1 dari setiap 10 request berikutnya
thereafter 10
}
}
reverse_proxy localhost:8080
}
Logika Pengambilan Sampel #
Pada konfigurasi di atas, dalam durasi setiap 1 detik:
- 100 request pertama yang masuk akan selalu dicatat secara lengkap 100% tanpa ada yang dilewatkan.
- Setelah request ke-100 terlampaui dalam detik yang sama, Caddy hanya akan mencatat request ke-110, ke-120, ke-130, dan seterusnya.
- Begitu detik berikutnya dimulai, counter akan di-reset kembali ke nol.
Taktik ini menjamin kita tetap memiliki data statistik representatif yang cukup akurat untuk menghitung performa latensi rata-rata backend kita tanpa membahayakan kesehatan disk I/O server.
Integrasi dengan Log Aggregator (Grafana Loki & ELK Stack) #
Membiarkan data log JSON menumpuk di berkas lokal server VM individual membuat kita kesulitan memantau kesehatan sistem jika VM kita berskala puluhan unit (scaling groups). Praktik terbaik di industri adalah mengirimkan data log ke pengumpul terpusat (log aggregator).
Karena log Caddy sudah berformat JSON terstruktur secara bawaan, kita tidak membutuhkan integrasi regex Grok pattern yang rumit pada pengumpul log kita.
1. Integrasi dengan Grafana Loki (Menggunakan Promtail) #
Kita dapat memasang Promtail di server Caddy kita untuk membaca file /var/log/caddy/access.log secara real-time dan meneruskannya ke Grafana Loki:
# Contoh Konfigurasi promtail-config.yaml
server:
http_listen_port: 9080
clients:
- url: http://loki-server:3100/loki/api/v1/push
scrape_configs:
- job_name: caddy-logs
static_configs:
- targets: [localhost]
labels:
job: caddy-access
env: production
__path__: /var/log/caddy/*.log
pipeline_stages:
# Karena log Caddy adalah JSON, kita hanya perlu mendefinisikan stage JSON
- json:
expressions:
status: status
duration: duration
method: request.method
uri: request.uri
2. Integrasi dengan ELK Stack (Menggunakan Filebeat) #
Jika kita menggunakan Elasticsearch dan Logstash, Filebeat dapat dikonfigurasi untuk langsung mem-parsing entri log Caddy sebagai dokumen JSON asli:
# Contoh Konfigurasi filebeat.yml
filebeat.inputs:
- type: log
enabled: true
paths:
- /var/log/caddy/access.log
# Mengurai format JSON secara langsung di Filebeat
json.keys_under_root: true
json.overwrite_keys: true
json.add_error_key: true
Siklus Hidup Request terhadap Pencatatan Log Akses #
Untuk menghindari kesalahan pemahaman mengenai kapan data log ditulis dan apa saja variabel yang terekam, kita harus mempelajari alur hidup pemrosesan data log oleh Caddy. Log akses tidak ditulis di awal request tiba, melainkan tepat setelah respons selesai dikirim ke browser klien.
Mari kita perhatikan alur visual di bawah ini menggunakan diagram flowchart:
flowchart TD
A["1. Request HTTP Masuk Klien"] --> B["2. Caddy mencatat waktu mulai (ts)"]
B --> C["3. Caddy memproses request lewat middleware/backend"]
C --> D["4. Backend mengembalikan data respons"]
D --> E["5. Caddy selesai mengirimkan respons ke Klien"]
E --> F["6. Hitung durasi pemrosesan (duration = ts_akhir - ts)"]
F --> G{"7. Apakah request cocok dengan filter 'exclude'?"}
G -- "Ya" --> H["8. Abaikan pencatatan (Request tidak ditulis ke log)"]
G -- "Tidak" --> I{"9. Apakah fitur 'sampling' aktif?"}
I -- "Ya" --> J{"Apakah request lolos seleksi sampling?"}
I -- "Tidak" --> K["11. Susun struktur JSON log lengkap"]
J -- "Ya" --> K
J -- "Tidak" --> H
K --> L["12. Kirim biner JSON log ke modul Output\n(e.g., tulis ke file access.log)"]Ringkasan #
- Fungsi Utama: Log akses merekam kronologi transaksi HTTP klien di server, esensial untuk audit keamanan siber, analisis latensi, dan integrasi Fail2ban.
- Kelebihan JSON: Caddy merekam log akses secara bawaan dalam format JSON terstruktur yang kaya data dan ramah terhadap pustaka log aggregator modern.
- Per-Site Logging: Direktif
logditulis langsung di dalam masing-masing blok server guna mengisolasi penyimpanan berkas log secara mandiri.- Log Filtering: Gunakan direktif
excludedipadukan dengan named matcher untuk mengabaikan logging aset statis guna menghemat penggunaan kapasitas disk.- Log Sampling: Batasi volume penulisan log pada infrastruktur lalu lintas tinggi menggunakan opsi
samplingguna meminimalkan hambatan I/O hard disk.- Integrasi Modern: Data JSON Caddy siap dikirim langsung ke Grafana Loki atau Elasticsearch tanpa perlu parsing ekspresi reguler (regex) tambahan yang rumit.
- Kompilasi Adapter: Pipa JSON logging asli dapat diamati secara terstruktur dengan memicu utilitas
caddy adaptpada konfigurasi Caddyfile kita.- Timing Penulisan: Log akses selalu ditulis tepat setelah seluruh respons selesai dikirim kembali ke klien untuk menghitung durasi waktu pemrosesan secara presisi.