📊 Güncel Durum
30 model aktif olarak activity_log'a yazılıyor. User aktiviteleri şu anda loglanmıyor, bu raporda implementasyon planı ve hazır kod örnekleri sunulacak.
✅ Şu Anda Loglanan Modeller (30 Adet)
Müzik Modülü (6)
- Song - Şarkılar
- Album - Albümler
- Artist - Sanatçılar
- Playlist - Çalma Listeleri
- Genre - Türler
- Muzibu - Özel Kategoriler
İçerik Modülü (6)
- Page - Sayfalar
- Blog - Blog Yazıları
- Portfolio - Portföy
- Announcement - Duyurular
- Favorite - Favoriler
- ReviewSystem - İncelemeler
E-Ticaret + Diğer (4)
- ShopProduct - Ürünler
- Coupon - Kuponlar
- Payment - Ödemeler
- Service - Hizmetler
Tüm bu modellerde created,
updated, deleted,
restored event'leri tam olarak loglanıyor.
forceDeleted (kalıcı silme) bazı modellerde loglanmıyor
(tasarım kararı - sadece Laravel log'una yazılıyor).
👤 User Aktiviteleri İmplementasyonu
Kullanıcı aktivitelerini activity_log'a eklemek için detaylı plan ve kod örnekleri
Loglanacak User Aktiviteleri
Kullanıcı sisteme giriş yaptı, IP adresi ve cihaz bilgisi kaydedilecek
Kullanıcı sistemden çıkış yaptı
İsim, email, telefon, bio gibi profil alanları değiştirildi (Observer ile otomatik)
Kullanıcı şifresini değiştirdi (eski şifre loglanmayacak - güvenlik)
Email adresi doğrulandı (email_verified_at alanı set edildi)
İki faktörlü doğrulama aktif/pasif edildi
Kullanıcının rolü değiştirildi (admin, user, moderator...)
Hesap kilitlendi/kilidi açıldı (locked_until alanı)
1. UserObserver Oluşturma
Dosya Konumu: /Modules/UserManagement/App/Observers/UserObserver.php
<?php
namespace Modules\UserManagement\App\Observers;
use App\Models\User;
use Illuminate\Support\Facades\Log;
class UserObserver
{
/**
* Handle the User "created" event.
* Admin tarafından yeni kullanıcı oluşturulduğunda
*/
public function created(User $user): void
{
// Activity log
if (function_exists('log_activity')) {
log_activity($user, 'oluşturuldu');
}
Log::info('User created', [
'user_id' => $user->id,
'name' => $user->name,
'email' => $user->email,
'created_by' => auth()->id()
]);
}
/**
* Handle the User "updated" event.
* Profil güncelleme, email değişikliği vb.
*/
public function updated(User $user): void
{
$changes = $user->getChanges();
// Bu alanları loglama (güvenlik)
unset($changes['password']);
unset($changes['remember_token']);
unset($changes['updated_at']);
unset($changes['last_login_at']); // Login zaten ayrı loglanıyor
if (!empty($changes)) {
// Özel durumlar için ek bilgi
$eventDescription = 'güncellendi';
$extraInfo = [];
// Email değişikliği
if (isset($changes['email'])) {
$extraInfo['eski_email'] = $user->getOriginal('email');
$extraInfo['yeni_email'] = $changes['email'];
}
// Email doğrulama
if (isset($changes['email_verified_at'])) {
$eventDescription = 'email doğrulandı';
}
// 2FA aktivasyon
if (isset($changes['two_factor_secret'])) {
$eventDescription = empty($changes['two_factor_secret'])
? '2FA deaktif edildi'
: '2FA aktif edildi';
}
// Hesap kilitleme
if (isset($changes['locked_until'])) {
$eventDescription = empty($changes['locked_until'])
? 'hesap kilidi kaldırıldı'
: 'hesap kilitlendi';
$extraInfo['locked_until'] = $changes['locked_until'];
}
log_activity($user, $eventDescription, array_keys($changes), $user->getOriginal('name'));
Log::info('User updated', [
'user_id' => $user->id,
'changed_fields' => array_keys($changes),
'updated_by' => auth()->id()
]);
}
}
/**
* Handle the User "deleted" event.
* Soft delete
*/
public function deleted(User $user): void
{
if (function_exists('log_activity')) {
log_activity($user, 'silindi');
}
Log::info('User deleted', [
'user_id' => $user->id,
'name' => $user->name,
'deleted_by' => auth()->id()
]);
}
/**
* Handle the User "restored" event.
* Silinmiş kullanıcı geri yüklendi
*/
public function restored(User $user): void
{
if (function_exists('log_activity')) {
log_activity($user, 'geri yüklendi');
}
Log::info('User restored', [
'user_id' => $user->id,
'name' => $user->name,
'restored_by' => auth()->id()
]);
}
}
password, remember_token
gibi hassas alanlar ASLA activity_log'a yazılmamalı. Observer'da bu alanlar otomatik filtreleniyor.
2. Observer'ı Kaydetme
Dosya: /Modules/UserManagement/App/Providers/UserManagementServiceProvider.php
use App\Models\User;
use Modules\UserManagement\App\Observers\UserObserver;
public function boot(): void
{
// User Observer'ı kaydet
User::observe(UserObserver::class);
// ... diğer kod
}
3. Login/Logout Aktivitelerini Loglama
Login ve Logout işlemleri model değişikliği olmadığı için Observer ile yakalanamaz. Bu yüzden manuel olarak authentication işlemlerinden sonra loglanmalı.
Login Event Listener:
Dosya: /Modules/UserManagement/App/Listeners/LogSuccessfulLogin.php
<?php
namespace Modules\UserManagement\App\Listeners;
use Illuminate\Auth\Events\Login;
use Illuminate\Support\Facades\Log;
class LogSuccessfulLogin
{
public function handle(Login $event): void
{
$user = $event->user;
// Activity log
if (function_exists('log_activity')) {
activity()
->causedBy($user)
->performedOn($user)
->event('login')
->withProperties([
'baslik' => $user->name,
'modul' => 'User',
'event_key' => 'giriş yaptı',
'ip_address' => request()->ip(),
'user_agent' => request()->userAgent(),
])
->log('giriş yaptı');
}
// User modelindeki last_login_at'i güncelle
$user->last_login_at = now();
$user->saveQuietly(); // Observer tetiklenmesin
Log::info('User login', [
'user_id' => $user->id,
'ip' => request()->ip()
]);
}
}
Logout Event Listener:
Dosya: /Modules/UserManagement/App/Listeners/LogSuccessfulLogout.php
<?php
namespace Modules\UserManagement\App\Listeners;
use Illuminate\Auth\Events\Logout;
use Illuminate\Support\Facades\Log;
class LogSuccessfulLogout
{
public function handle(Logout $event): void
{
$user = $event->user;
if ($user && function_exists('log_activity')) {
activity()
->causedBy($user)
->performedOn($user)
->event('logout')
->withProperties([
'baslik' => $user->name,
'modul' => 'User',
'event_key' => 'çıkış yaptı',
])
->log('çıkış yaptı');
}
Log::info('User logout', [
'user_id' => $user?->id
]);
}
}
EventServiceProvider'a Kaydetme:
Dosya: /Modules/UserManagement/App/Providers/EventServiceProvider.php
<?php
namespace Modules\UserManagement\App\Providers;
use Illuminate\Foundation\Support\Providers\EventServiceProvider as ServiceProvider;
use Illuminate\Auth\Events\Login;
use Illuminate\Auth\Events\Logout;
use Modules\UserManagement\App\Listeners\LogSuccessfulLogin;
use Modules\UserManagement\App\Listeners\LogSuccessfulLogout;
class EventServiceProvider extends ServiceProvider
{
protected $listen = [
Login::class => [
LogSuccessfulLogin::class,
],
Logout::class => [
LogSuccessfulLogout::class,
],
];
public function boot(): void
{
//
}
}
4. Şifre Değiştirme Özel Loglama
Şifre değiştirme işlemi UserObserver'da otomatik yakalanır, ancak password alanı filtrelendiği için sadece "şifre değiştirildi" event'i loglanır (şifrenin kendisi ASLA loglanmaz).
Controller'da Ekstra Log (opsiyonel):
// Password update sonrası
public function updatePassword(Request $request)
{
// ... validasyon ve şifre güncelleme ...
$user->password = Hash::make($request->new_password);
$user->save(); // Observer otomatik tetiklenir
// Ekstra bilgi eklemek isterseniz (opsiyonel)
if (function_exists('log_activity')) {
activity()
->causedBy(auth()->user())
->performedOn($user)
->event('password_changed')
->withProperties([
'baslik' => $user->name,
'modul' => 'User',
'event_key' => 'şifre değiştirildi',
'ip_address' => request()->ip(),
])
->log('şifre değiştirildi');
}
return response()->json(['message' => 'Şifre güncellendi']);
}
📄 Örnek User Activity Log Kayıtları
1. Login (Giriş Yaptı):
{
"log_name": "User",
"description": "giriş yaptı",
"subject_type": "App\\Models\\User",
"subject_id": 5,
"causer_type": "App\\Models\\User",
"causer_id": 5,
"event": "login",
"properties": {
"baslik": "Ahmet Yılmaz",
"modul": "User",
"event_key": "giriş yaptı",
"ip_address": "192.168.1.100",
"user_agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64)..."
},
"created_at": "2026-01-30 15:30:00"
}
2. Profil Güncelleme:
{
"log_name": "User",
"description": "güncellendi",
"subject_type": "App\\Models\\User",
"subject_id": 5,
"causer_type": "App\\Models\\User",
"causer_id": 5,
"event": "updated",
"properties": {
"baslik": "Ahmet Yılmaz",
"modul": "User",
"degisenler": {
"changed_fields": ["name", "phone", "bio"]
},
"event_key": "güncellendi",
"eski_baslik": "Ahmet Y."
},
"created_at": "2026-01-30 16:15:00"
}
3. Email Değişikliği:
{
"log_name": "User",
"description": "güncellendi",
"subject_type": "App\\Models\\User",
"subject_id": 5,
"causer_type": "App\\Models\\User",
"causer_id": 1,
"event": "updated",
"properties": {
"baslik": "Ahmet Yılmaz",
"modul": "User",
"degisenler": {
"changed_fields": ["email"]
},
"event_key": "güncellendi",
"eski_email": "ahmet@example.com",
"yeni_email": "ahmet.yilmaz@newdomain.com"
},
"created_at": "2026-01-30 17:00:00"
}
4. 2FA Aktivasyon:
{
"log_name": "User",
"description": "2FA aktif edildi",
"subject_type": "App\\Models\\User",
"subject_id": 5,
"causer_type": "App\\Models\\User",
"causer_id": 5,
"event": "updated",
"properties": {
"baslik": "Ahmet Yılmaz",
"modul": "User",
"degisenler": {
"changed_fields": ["two_factor_secret"]
},
"event_key": "2FA aktif edildi"
},
"created_at": "2026-01-30 18:00:00"
}
5. Logout (Çıkış Yaptı):
{
"log_name": "User",
"description": "çıkış yaptı",
"subject_type": "App\\Models\\User",
"subject_id": 5,
"causer_type": "App\\Models\\User",
"causer_id": 5,
"event": "logout",
"properties": {
"baslik": "Ahmet Yılmaz",
"modul": "User",
"event_key": "çıkış yaptı"
},
"created_at": "2026-01-30 20:00:00"
}
🚀 İmplementasyon Adımları (Sıralı)
/Modules/UserManagement/App/Observers/UserObserver.php
dosyasını oluştur (yukarıdaki kod örneğini kullan)
UserManagementServiceProvider.php içinde
boot() metoduna User::observe(UserObserver::class); ekle
/Modules/UserManagement/App/Listeners/LogSuccessfulLogin.php oluştur
/Modules/UserManagement/App/Listeners/LogSuccessfulLogout.php oluştur
EventServiceProvider.php içinde $listen array'ine
Login ve Logout event'lerini ekle
php artisan cache:clear && php artisan config:clear
Login/logout yap, profil güncelle, /admin/activity-logs sayfasından kontrol et
Implementasyondan sonra test ortamında önce deneyin. Login/logout ve profil güncellemelerinin doğru loglandığından emin olun.
📊 Güncellenmiş Durum Tablosu
| Model | Created | Updated | Deleted | Restored | Durum |
|---|---|---|---|---|---|
| MÜZİK MODÜLÜ | |||||
| Song | ✓ Tam | ||||
| Album | ✓ Tam | ||||
| Artist, Playlist, Genre, Muzibu | ✓ Tam | ||||
| İÇERİK MODÜLÜ | |||||
| Page, Blog, Portfolio, Announcement | ✓ Tam | ||||
| Favorite, ReviewSystem | ✓ Tam | ||||
| E-TİCARET + DİĞER | |||||
| ShopProduct, Coupon, Payment, Service | ✓ Tam | ||||
| KULLANICI MODÜLÜ (İMPLEMENTE EDİLECEK) | |||||
| User (Observer ile) | ⏳ Bekliyor | ||||
| Login/Logout (Event Listener ile) | Event bazlı (model değişikliği yok) | ⏳ Bekliyor | |||
forceDeleted (kalıcı silme) event'i bazı modellerde
activity_log'a yazılmıyor. Bu bir tasarım kararı - kalıcı silme işlemleri nadir olduğu için
sadece Laravel log dosyasına yazılıyor.
🎯 Sonuç ve Öneriler
Mevcut sistemde 30 model tam olarak loglanıyor. User aktiviteleri için yukarıdaki implementasyon planı uygulandığında sistem %100 kapsama ulaşacak.
✅ Mevcut Güçlü Yönler:
- • Observer pattern ile otomatik loglama
- • 30 model aktif olarak takip ediliyor
- • Değişen alanlar detaylıca kaydediliyor
- • Multi-language başlık desteği
- • Soft delete ve restore takibi
⏳ User İmplementasyonu Sonrası:
- • Login/logout tam takip
- • Profil değişiklikleri otomatik log
- • Şifre değiştirme güvenli kayıt
- • 2FA aktivasyon/deaktivasyon
- • Email doğrulama takibi
- • Role/permission değişiklikleri
User implementasyonunu test ortamında önce deneyin.
Login/logout trafiği yüksek olduğu için activity_log
tablosunun hızla büyüyeceğini unutmayın. Eski kayıtları otomatik temizleme
(config: delete_records_older_than_days) zaten aktif.
password, remember_token
gibi hassas alanlar ASLA activity_log'a yazılmamalı. Yukarıdaki kod örneklerinde
bu alanlar zaten filtrelenmiş durumda.