Teknik rehber

Production Hata Ayıklama: Log Bağlamı ve Güvenli Hata Raporlama

Production ortamında hata ayıklarken log bağlamını zenginleştirin ve hassas verileri sızdırmadan güvenli raporlama yapın. Laravel 13 ve PHP 8.3+ ile uygulanabilir yöntemler.

Yazılım geliştirme ve kodlama görseli
Görsel: Unsplash · Görsel kaynağı

Production ortamında bir hata meydana geldiğinde, geliştiriciler genellikle yetersiz log kaydıyla karşı karşıya kalır. Hata mesajı ve stack trace olsa da, hatanın hangi kullanıcı, istek veya işlem bağlamında oluştuğunu anlamak zordur. Ayrıca, hata raporlama sürecinde kullanıcı verileri, token'lar veya veritabanı kimlik bilgileri gibi hassas bilgilerin loglara sızması ciddi güvenlik açıklarına yol açabilir. Bu yazıda, Laravel 13 ve PHP 8.3+ kullanarak production hata ayıklama sürecinizi nasıl iyileştireceğinizi, log bağlamını nasıl zenginleştireceğinizi ve güvenli hata raporlamayı nasıl uygulayacağınızı ele alacağız.

Log Bağlamı Nedir ve Neden Önemlidir?

Log bağlamı, bir log kaydına eklenen ek bilgilerdir: kullanıcı ID'si, istek ID'si, oturum bilgisi, çalışan işlem adı, ilgili nesne kimlikleri vb. Bu bağlam, bir hatanın kök nedenini bulmayı kolaylaştırır. Laravel'de Log::withContext veya Log::shareContext yöntemleriyle global bağlam ekleyebilirsiniz. Örneğin, her isteğe bir request_id eklemek, dağıtık sistemlerde izlenebilirliği artırır.

Laravel'de Global Log Bağlamı Ekleme

Laravel 13'te Log::shareContext ile tüm log kayıtlarına otomatik olarak bağlam ekleyebilirsiniz. Bunu bir service provider içinde yapabilirsiniz:

// app/Providers/AppServiceProvider.php

use Illuminate\Support\Facades\Log;
use Illuminate\Support\Str;

public function boot(): void
{
    Log::shareContext([
        'request_id' => Str::uuid()->toString(),
        'user_id' => auth()->id(),
    ]);
}

Ancak dikkat: auth()->id() henüz kullanıcı doğrulanmadan çalışmayabilir. Bu nedenle, middleware içinde bağlam eklemek daha güvenlidir. Resmi dokümantasyonda (Laravel Logging - Contextual Information) belirtildiği üzere, Log::withContext ile istek bazlı bağlam ekleyebilirsiniz.

Middleware ile İstek Bazlı Bağlam

// app/Http/Middleware/LogContext.php

namespace App\Http\Middleware;

use Closure;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Str;
use Symfony\Component\HttpFoundation\Response;

class LogContext
{
    public function handle(Request $request, Closure $next): Response
    {
        Log::withContext([
            'request_id' => Str::uuid()->toString(),
            'user_id' => $request->user()?->id,
            'ip' => $request->ip(),
            'route' => $request->route()?->getName(),
        ]);

        return $next($request);
    }
}

Bu middleware'i app/Http/Kernel.php içinde global middleware olarak kaydedin.

Güvenli Hata Raporlama: Hassas Verileri Maskeleme

Hata raporlama sırasında, exception mesajları veya log bağlamı hassas veriler içerebilir. Örneğin, bir SQL hatası veritabanı şifresini veya kullanıcı e-postasını loglara yazabilir. Laravel'in config/logging.php dosyasında redact seçeneği ile belirli anahtarları maskeleyebilirsiniz. Laravel 13'te bu özellik monolog yapılandırmasında mevcuttur.

Log Maskeleme Yapılandırması

// config/logging.php

'channels' => [
    'stack' => [
        'driver' => 'stack',
        'channels' => ['daily'],
        'ignore_exceptions' => false,
    ],

    'daily' => [
        'driver' => 'daily',
        'path' => storage_path('logs/laravel.log'),
        'level' => 'debug',
        'days' => 14,
        'redact' => [
            'password',
            'password_confirmation',
            'credit_card',
            'token',
            'secret',
            'authorization',
        ],
    ],
],

Bu yapılandırma, log kayıtlarındaki belirtilen anahtarların değerlerini [REDACTED] olarak değiştirir. Resmi dokümantasyonda (Laravel Logging - Redacting Sensitive Data) daha fazla detay bulabilirsiniz.

Exception Handler'da Özel Raporlama

Laravel 13'te app/Exceptions/Handler.php içinde report metodunu override ederek, raporlama öncesi hassas verileri temizleyebilirsiniz. Örneğin, bir exception'ın mesajından e-posta adreslerini çıkarabilirsiniz:

// app/Exceptions/Handler.php

namespace App\Exceptions;

use Illuminate\Foundation\Exceptions\Handler as BaseHandler;
use Throwable;

class Handler extends BaseHandler
{
    public function report(Throwable $e): void
    {
        // Hassas verileri temizle
        $message = preg_replace('/[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}/', '[EMAIL]', $e->getMessage());
        $e = new \Exception($message, $e->getCode(), $e);

        parent::report($e);
    }
}

Ancak bu yöntem, orijinal exception'ın stack trace'ini kaybetmenize neden olabilir. Daha güvenli bir yaklaşım, log bağlamını zenginleştirirken hassas verileri zaten dışarıda bırakmaktır.

Uygulanabilir Kod Örneği: Bağlam ve Maskeleme Birlikte

Aşağıda, hem log bağlamını zenginleştiren hem de hassas verileri maskeleyen bir örnek verilmiştir. Bu örnek, bir kullanıcı kaydı sırasında oluşan hatayı raporlar.

// app/Services/UserService.php

namespace App\Services;

use App\Models\User;
use Illuminate\Support\Facades\Log;
use Throwable;

class UserService
{
    public function createUser(array $data): User
    {
        try {
            $user = User::create([
                'name' => $data['name'],
                'email' => $data['email'],
                'password' => bcrypt($data['password']),
            ]);

            Log::info('User created', ['user_id' => $user->id]);

            return $user;
        } catch (Throwable $e) {
            Log::error('User creation failed', [
                'email' => $data['email'], // Bu log'da maskelenecek
                'error' => $e->getMessage(),
            ]);

            throw $e;
        }
    }
}

config/logging.php içinde redact anahtarına email eklerseniz, bu log kaydındaki e-posta adresi [REDACTED] olarak görünür. Böylece hem hata ayıklama için gerekli bağlamı elde edersiniz hem de hassas verileri korursunuz.

Sonuç

Production hata ayıklama, doğru log bağlamı ve güvenli raporlama ile çok daha etkili hale gelir. Laravel 13'ün sunduğu Log::shareContext, Log::withContext ve redact gibi özellikler, bu süreci kolaylaştırır. Unutmayın: loglara asla hassas veri yazmayın; yazmanız gerekiyorsa mutlaka maskeleyin. Resmi dokümantasyonu takip ederek (Laravel Logging ve PHP Error Handling) uygulamanızı güvenli ve izlenebilir hale getirebilirsiniz.

🍪
Çerez Kullanımı

Kodumun Hatası, web sitesinin çalışmasını sağlamak ve kullanıcı deneyimini geliştirmek için çerezler kullanabilir. Zorunlu olmayan çerezler için tercihlerinizi belirleyebilir, ayrıntılı bilgiye Çerez Politikamızdan ulaşabilirsiniz.