Ön Hazırlık: Gereksinimler ve Ortam Kurulumu
Projeye başlamadan önce sisteminizde PHP 8.1 veya daha güncel bir sürümün, MySQL 8.0+ veritabanı sunucusunun ve PDO (PHP Data Objects) eklentisinin aktif olduğundan emin olmalısınız. PDO, veritabanı işlemlerinde SQL Injection saldırılarını önlemek için hazırlanan sorguları (prepared statements) desteklediği için standart bir gerekliliktir.
- PHP 8.2+: Modern sözdizimi ve tip güvenliği için.
- MySQL/MariaDB: Verilerin kalıcı olarak saklanması için.
- Composer: Gerekli durumlarda bağımlılık yönetimi için (bu rehberde saf PHP kullanacağız).
- Veritabanı İstemcisi: phpMyAdmin veya DBeaver gibi bir araç.
Adım 1: Aktivite Günlüğü İçin Veritabanı Tasarımı
Veritabanı tasarımı, loglama sisteminin performansını doğrudan etkiler. Aktivite günlüğü tablosu, çok fazla veri birikeceği için doğru indekslenmelidir. Aşağıdaki SQL komutu, aktivite günlüğü için gerekli olan tablo yapısını oluşturur.
CREATE TABLE user_activity_logs (
id INT AUTO_INCREMENT PRIMARY KEY,
user_id INT NOT NULL,
action VARCHAR(255) NOT NULL,
ip_address VARCHAR(45) NOT NULL,
user_agent TEXT,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
INDEX(user_id),
INDEX(created_at)
);
Bu tablo yapısında user_id ve created_at alanlarına indeks eklememizin sebebi, ileride "belirli bir kullanıcının son 30 günlük hareketleri" gibi sorguları çok daha hızlı çalıştırmaktır.
Adım 2: Veritabanı Bağlantısını Yapılandırma
PHP ile veritabanına bağlanırken güvenliği elden bırakmamak gerekir. PDO kullanarak bağlantı kurmak, veritabanı hatalarını kontrollü bir şekilde yönetmenize olanak tanır. Aşağıdaki kod bloğu, veritabanı bağlantısını güvenli bir sınıfta toplar.
Burada utf8mb4 karakter setini kullandık; bu, emoji ve özel karakterlerin veritabanında bozulmadan saklanmasını sağlar.
Adım 3: Log Kaydetme Fonksiyonunu Oluşturma
Loglama işlemini her sayfada tekrar tekrar yazmak yerine, merkezi bir fonksiyon kullanmak en iyi pratiktir. Bu fonksiyon, kullanıcının IP adresi ve tarayıcı bilgisi gibi verileri otomatik olarak yakalamalıdır.
function logActivity(PDO $pdo, int $userId, string $action): void {
$sql = "INSERT INTO user_activity_logs (user_id, action, ip_address, user_agent) VALUES (?, ?, ?, ?)";
$stmt = $pdo->prepare($sql);
$stmt->execute([
$userId,
$action,
$_SERVER['REMOTE_ADDR'],
$_SERVER['HTTP_USER_AGENT']
]);
}
Bu fonksiyonu, kullanıcı giriş yaptığında, profil güncellediğinde veya kritik bir butona tıkladığında çağırarak veritabanına kayıt atabilirsiniz.
Adım 4: Güvenlik ve Performans Karşılaştırması
Loglama sistemlerinde kullanılan farklı yöntemlerin avantaj ve dezavantajlarını anlamak, projenin geleceği için önemlidir.
| Yöntem | Avantajı | Dezavantajı |
|---|---|---|
| Veritabanı (MySQL) | Kolay sorgulanabilir, raporlanabilir. | Yüksek trafikli sitelerde veritabanını yorabilir. |
| Dosya (Log Files) | Çok hızlıdır, veritabanını etkilemez. | Sorgulama yapmak ve analiz etmek zordur. |
| Redis/NoSQL | Çok yüksek performanslıdır. | Ekstra altyapı ve kurulum gerektirir. |
Adım 5: Log Verilerini Okuma ve Listeleme
Kaydettiğiniz verileri bir yönetici panelinde görüntülemek için PDO ile basit bir SELECT sorgusu kullanabilirsiniz. Güvenlik için verileri ekrana basarken mutlaka htmlspecialchars() fonksiyonunu kullanarak XSS (Cross-Site Scripting) saldırılarını engellemelisiniz.
$stmt = $pdo->query("SELECT * FROM user_activity_logs ORDER BY created_at DESC LIMIT 50");
$logs = $stmt->fetchAll();
foreach ($logs as $log) {
echo "Kullanıcı ID: " . htmlspecialchars($log['user_id']) . " - ";
echo "İşlem: " . htmlspecialchars($log['action']) . " - ";
echo "Tarih: " . $log['created_at'] . "
";
}
Kritik Güvenlik Uyarısı: Log verilerini asla doğrudan HTML içine gömmeyin. Kullanıcı tarafından girilen veriler, başka bir kullanıcı tarafından görüntülenecekse mutlaka çıktı filtreleme (output escaping) yöntemlerini kullanın. Ayrıca, üretim ortamında (production) hata mesajlarını doğrudan ekrana basmayın; bunları log dosyalarına yönlendirin.
Adım 6: Yaygın Hatalar ve Debug İpuçları
Loglama sistemlerinde karşılaşılan en yaygın hata, veritabanı bağlantısının her loglama işleminde yeniden açılmasıdır. Bu, bağlantı havuzunu (connection pool) tüketebilir. Bunun yerine, uygulamanızın genelinde tek bir PDO örneğini (Singleton pattern veya Dependency Injection) kullanın.
Bir diğer hata ise user_agent verisinin aşırı uzun olmasıdır. Tarayıcılar bazen çok uzun stringler gönderebilir, bu yüzden veritabanında TEXT veya VARCHAR(500) gibi uygun veri tiplerini tercih edin.
Sıkça Sorulan Sorular
Log tablosu çok büyürse ne yapmalıyım?
Log tablosu milyonlarca satıra ulaştığında "Table Partitioning" (tablo bölümlendirme) yöntemini veya belirli bir süreden eski kayıtları arşivleyip silen bir "Cron Job" (zamanlanmış görev) mekanizmasını kullanmalısınız.
Kullanıcının gerçek IP adresini nasıl alırım?
Eğer uygulamanız Cloudflare veya bir Proxy arkasındaysa, $_SERVER['REMOTE_ADDR'] yerine $_SERVER['HTTP_X_FORWARDED_FOR'] başlığını kontrol etmeniz gerekebilir.
Loglama işlemi sayfa yüklenme süresini yavaşlatır mı?
Evet, her loglama işlemi veritabanına bir yazma isteği gönderir. Eğer çok yüksek trafikli bir siteye sahipseniz, logları önce bir kuyruk sistemine (Redis veya RabbitMQ) atıp, arka planda (asenkron) veritabanına yazan bir yapı kurmanız önerilir.
Hangi işlemleri loglamalıyım?
Kullanıcı girişi, şifre değişikliği, e-posta değişikliği, ödeme işlemleri ve yönetici paneli erişimleri gibi "kritik" olarak tanımladığınız tüm işlemleri loglamanız güvenlik açısından zorunludur.
Loglarımı nasıl silebilir veya temizleyebilirim?
Veritabanı üzerinden DELETE FROM user_activity_logs WHERE created_at < DATE_SUB(NOW(), INTERVAL 6 MONTH) gibi bir sorgu ile 6 aydan eski logları düzenli olarak temizleyebilirsiniz.
İleri Düzey Loglama: Monolog Kütüphanesi ile Entegrasyon
Kendi loglama sisteminizi yazmak, temel prensipleri anlamak için harika bir yoldur. Ancak, büyük ölçekli ve kurumsal projelerde tekerleği yeniden icat etmek yerine, endüstri standardı olan Monolog kütüphanesini kullanmak çok daha güvenli ve esnektir. Monolog, loglarınızı aynı anda hem veritabanına, hem bir dosyaya, hem de Slack veya e-posta gibi kanallara göndermenize olanak tanır.
Composer aracılığıyla projeye dahil ettikten sonra, veritabanı handler'ını şu şekilde yapılandırabilirsiniz:
require 'vendor/autoload.php';
use Monolog\Logger;
use Monolog\Handler\PDOHandler;
$pdo = new PDO('mysql:host=localhost;dbname=uygulama', 'user', 'pass');
$logger = new Logger('kullanici_aktivite');
// PDOHandler ile logları doğrudan veritabanına yazma
$logger->pushHandler(new PDOHandler($pdo, 'log_tablosu'));
$logger->info('Kullanıcı giriş yaptı', ['user_id' => 42]);
$logger->error('Veritabanı bağlantı hatası', ['code' => 500]);
Log Verilerini Görselleştirme ve Dashboard Stratejileri
Logları sadece veritabanında tutmak yeterli değildir; bu verilerin anlamlı bir şekilde okunması gerekir. Yönetim paneli (Dashboard) üzerinde bir filtreleme sistemi kurarken, performans kaybını önlemek için mutlaka sayfalama (pagination) ve tarih aralığı indekslemesi kullanmalısınız.
Aşağıdaki SQL sorgusu, belirli bir kullanıcıya ait son 24 saatlik logları en verimli şekilde çekmenizi sağlar:
SELECT id, action, created_at
FROM activity_logs
WHERE user_id = :user_id
AND created_at >= NOW() - INTERVAL 1 DAY
ORDER BY created_at DESC
LIMIT 50 OFFSET 0;
Dashboard İçin İpuçları:
- Veri Görselleştirme: Chart.js veya ApexCharts kullanarak günlük aktivite yoğunluğunu grafiklerle gösterin.
- Kritik Uyarılar: "Hata" (Error) seviyesindeki loglar için bir "Bildirim Merkezi" oluşturarak, sistem yöneticisini anlık uyarın.
- Dışa Aktarma: Yöneticilerin logları CSV veya Excel formatında indirebilmesi için
fputcsvfonksiyonunu kullanın.
Bu yapı, uygulamanızın sadece bir "günlük" tutmasını değil, aynı zamanda sistemin sağlık durumunu izleyen bir "analiz aracı"na dönüşmesini sağlayacaktır. Loglama sisteminizi kurarken her zaman GDPR (KVKK) uyumluluğunu göz önünde bulundurarak, kullanıcıların hassas verilerini (şifre, kredi kartı vb.) asla log dosyalarına kaydetmediğinizden emin olun.
Sonuç
PHP ile veritabanı destekli bir kullanıcı aktivite günlüğü oluşturmak, uygulamanızın şeffaflığını ve güvenliğini artıran temel bir adımdır. Bu rehberde öğrendiğiniz PDO kullanımı, SQL indeksleme ve veri sanitizasyonu teknikleri, profesyonel bir yazılım geliştirme sürecinin yapı taşlarıdır. Bir sonraki adım olarak, bu logları bir arayüzde filtreleyebileceğiniz (tarihe veya kullanıcıya göre) gelişmiş bir dashboard tasarlamayı deneyebilirsiniz.
Sorumluluk Reddi: Bu makaledeki kod örnekleri eğitim amaçlıdır. Canlıya almadan önce kendi güvenlik testlerinizi yapmalı ve veritabanı bağlantı bilgilerini çevre değişkenlerinde (environment variables) saklamalısınız. Yazılım güvenliği sürekli güncellenen bir süreçtir; PHP ve veritabanı sürümlerinizi her zaman güncel tutun.


Yorumlar (0)
Yorum Yaz