Gereksinimler ve Ön Hazırlık
Bu sistemi kurmak için sisteminizde en az Laravel 11 veya 12 sürümünün yüklü olması önerilir. PHP 8.2 ve üzeri sürümler, modern tip belirleme (type hinting) ve performans iyileştirmeleri için gereklidir. Ayrıca, veritabanı işlemlerinde yüksek trafikle başa çıkabilmek için MySQL veya PostgreSQL kullanmanız tavsiye edilir.
- PHP 8.2+ ve Composer yüklü bir geliştirme ortamı.
- Laravel framework kurulumu tamamlanmış bir proje.
- Veritabanı bağlantısı yapılandırılmış bir ortam (.env dosyası).
Adım 1: Veritabanı Şemasının Oluşturulması
Etkinlikleri saklamak için esnek bir tabloya ihtiyacımız var. Kullanıcı kimliği, etkinlik türü, hedef URL ve ek verileri (payload) tutacak bir "user_activities" tablosu oluşturmalıyız. Laravel'in migration (göç) sistemini kullanarak bu yapıyı tanımlayalım.
php artisan make:migration create_user_activities_table
Oluşturulan migration dosyasını aşağıdaki gibi düzenleyerek, verilerin JSON formatında saklanmasını sağlayarak dinamik bir yapı kuruyoruz:
public function up(): void
{
Schema::create('user_activities', function (Blueprint $table) {
$table->id();
$table->foreignId('user_id')->nullable()->constrained()->onDelete('set null');
$table->string('event_type'); // Örneğin: 'login', 'page_view', 'update'
$table->string('url');
$table->ipAddress('ip_address');
$table->text('user_agent');
$table->json('payload')->nullable(); // Ekstra veriler için JSON sütunu
$table->timestamp('created_at')->useCurrent();
});
}
Adım 2: Etkinlik Kaydedici Servis Sınıfı
Kod tekrarını önlemek ve iş mantığını (business logic) merkezileştirmek için bir servis sınıfı oluşturacağız. Bu sınıf, etkinlik verilerini veritabanına yazmaktan sorumlu olacak.
namespace App\Services;
use App\Models\UserActivity;
use Illuminate\Support\Facades\Auth;
class ActivityLogger
{
public static function log(string $type, array $payload = []): void
{
UserActivity::create([
'user_id' => Auth::id(),
'event_type' => $type,
'url' => request()->fullUrl(),
'ip_address' => request()->ip(),
'user_agent' => request()->userAgent(),
'payload' => $payload,
]);
}
}
Adım 3: Middleware ile Otomatik İzleme
Her controller içinde tek tek loglama yapmak yerine, bir middleware kullanarak tüm istekleri merkezi olarak izleyebiliriz. Bu, uygulamanın genelinde tutarlı bir izleme sağlar.
namespace App\Http\Middleware;
use App\Services\ActivityLogger;
use Closure;
class TrackUserActivity
{
public function handle($request, Closure $next)
{
$response = $next($request);
if ($request->isMethod('post') || $request->isMethod('put')) {
ActivityLogger::log($request->path(), $request->except(['password', 'password_confirmation']));
}
return $response;
}
}
Güvenlik Uyarısı: Kullanıcı etkinliklerini izlerken, şifreler, kredi kartı bilgileri veya kişisel veriler (PII) gibi hassas bilgileri asla loglamayın. $request->except() metodunu kullanarak bu alanları mutlaka filtreleyin.
Adım 4: Laravel Event ve Listener Yapısı
Daha karmaşık süreçler için (örneğin e-posta gönderimi veya bildirimler), Laravel'in Event sistemini kullanmak performansı artırır. Senkron işlemler yerine asenkron kuyruklar (queues) kullanarak loglama işleminin kullanıcı deneyimini yavaşlatmasını engelleyebilirsiniz.
// Event sınıfı
class UserPerformedAction {
public function __construct(public string $action, public array $data) {}
}
// Listener sınıfı
class LogActivityListener {
public function handle(UserPerformedAction $event) {
ActivityLogger::log($event->action, $event->data);
}
}
Karşılaştırma: İzleme Yöntemleri
| Yöntem | Avantaj | Dezavantaj |
|---|---|---|
| Middleware | Kolay kurulum, merkezi kontrol | Her istekte veritabanı yükü |
| Event/Listener | Asenkron işlem, yüksek performans | Daha karmaşık mimari |
| Model Observers | Veri değişimlerini takip etme | Sadece Eloquent işlemleri ile sınırlı |
Sıkça Sorulan Sorular
Loglama sistemi veritabanımı yavaşlatır mı?
Evet, eğer her istekte senkron olarak veritabanına yazarsanız performans kaybı yaşanabilir. Bunu önlemek için "Queue" (kuyruk) yapısını kullanarak loglama işlemlerini arka planda çalıştırmalısınız.
Kullanıcı gizliliğine nasıl uyum sağlarım?
KVKK ve GDPR gereği, kullanıcıdan onay almalı ve logları belirli bir süre sonra silen bir "Retention Policy" (saklama politikası) oluşturmalısınız.
Sadece belirli sayfaları izlemek istersem ne yapmalıyım?
Middleware'i tüm uygulamaya uygulamak yerine, sadece belirli rotalara (route) veya route gruplarına atayarak izleme kapsamını daraltabilirsiniz.
JSON sütununda arama yapmak performanslı mıdır?
Evet, MySQL 5.7+ ve PostgreSQL'de JSON sütunları üzerinde indeksleme yapabilirsiniz. Ancak çok büyük verilerde özel bir loglama servisi (Elasticsearch gibi) kullanmak daha mantıklıdır.
Logları nasıl raporlayabilirim?
Laravel'in Eloquent sorgularını kullanarak belirli bir zaman aralığındaki veya belirli bir kullanıcıya ait etkinlikleri kolayca filtreleyip bir dashboard üzerinde gösterebilirsiniz.
Sorumluluk Reddi: Bu rehberdeki kod örnekleri eğitim amaçlıdır. Üretim ortamında (production) kullanmadan önce mutlaka yük testi yapın ve veri gizliliği yasalarına uygunluk denetiminden geçirin.
İleri Seviye İpuçları: Veri Birleştirme ve Optimizasyon
Etkinlik izleme sisteminizi ölçeklendirirken, veritabanı üzerindeki yükü minimize etmek ve veri bütünlüğünü korumak için bazı ileri teknikler uygulamanız gerekebilir. Özellikle yüksek trafikli uygulamalarda, her etkinlik için veritabanına anlık yazma işlemi yapmak yerine kuyruk (queue) sistemlerini kullanmak en sağlıklı yaklaşımdır.
Redis ve Queue Kullanımı ile Asenkron Kayıt
Kullanıcı etkileşimlerini doğrudan veritabanına yazmak yerine, Laravel'in Job yapısını kullanarak bu verileri bir kuyruğa atabilir ve arka planda işleyebilirsiniz. Bu, kullanıcının sayfa yükleme süresini doğrudan etkilemez.
// app/Jobs/LogUserActivity.php
public function handle()
{
ActivityLog::create([
'user_id' => $this->userId,
'action' => $this->action,
'payload' => $this->data,
'created_at' => now(),
]);
}
// Controller veya Middleware içerisinde
LogUserActivity::dispatch($userId, 'login', $data);
Etkinlik İzleme Sisteminde Hata Ayıklama (Debugging)
Sistemin düzgün çalışıp çalışmadığını izlemek, özellikle karmaşık kullanıcı akışlarında kritiktir. İzleme mekanizmanızın hata verip vermediğini anlamak için Laravel'in yerleşik Log facade'ini kullanabilirsiniz.
Hata Yakalama Mekanizması
Middleware veya Listener içerisinde oluşabilecek veritabanı hatalarını, uygulamanın ana akışını bozmadan yakalamak için try-catch bloklarını tercih edin.
try {
ActivityLog::create($data);
} catch (\Exception $e) {
\Log::error('Etkinlik kaydedilemedi: ' . $e->getMessage());
}
Alternatif: Paket Kullanımı vs. Özel Çözüm
Kendi sisteminizi yazmak size tam kontrol sağlasa da, topluluk tarafından desteklenen paketler karmaşık ihtiyaçlar için daha hızlı çözüm sunabilir. spatie/laravel-activitylog gibi popüler paketler, model değişikliklerini otomatik takip etme ve logları temizleme gibi gelişmiş özelliklerle gelir.
| Özellik | Özel Çözüm | Paket (Spatie) |
|---|---|---|
| Esneklik | Çok Yüksek | Orta |
| Bakım Maliyeti | Yüksek | Düşük |
| Öğrenme Eğrisi | Düşük | Orta |
Veri Temizleme (Pruning) Stratejisi
Log tabloları zamanla milyonlarca satıra ulaşabilir. Laravel'in Prunable özelliğini kullanarak, belirli bir süreden eski olan logları otomatik olarak silebilirsiniz.
// app/Models/ActivityLog.php
use Illuminate\Database\Eloquent\Prunable;
class ActivityLog extends Model
{
use Prunable;
public function prunable()
{
return static::where('created_at', '
Sonuç
Laravel ile dinamik bir kullanıcı etkinlik izleme sistemi kurmak, uygulamanızın şeffaflığını ve güvenliğini artırır. Middleware ile başlayıp, ihtiyaç duyduğunuzda Event/Listener yapısına geçiş yaparak uygulamanızı ölçeklendirebilirsiniz. Bir sonraki adım olarak, toplanan bu verileri görselleştiren bir admin paneli arayüzü geliştirmeyi düşünebilirsiniz.


Yorumlar (0)
Yorum Yaz