Sebelum memulai praktik, pastikan Anda telah memahami konsep dasar pada materi kelas AI Agent & PHP di infokoding.

BAB 16

Menambahkan Logging System

Implementasi sistem logging komprehensif untuk AI Agent PHP: mencatat request, response, tool calls, error, dan mode debug untuk memudahkan pemeliharaan aplikasi.

Terakhir diperbarui:

TL;DR (Ringkasan Cepat)

  • Logging yang baik adalah nyawa debugging aplikasi AI Agent.
  • Log setidaknya: waktu, level, session ID, token usage, tool yang dipanggil, dan error.
  • Gunakan format JSON per baris agar log mudah di-parse dan dicari.
  • Rotasi log harian untuk mencegah file log tumbuh tidak terkendali.

Logger Class

<?php

namespace App\Logger;

class Logger
{
    private string $logFile;
    private string $level;
    private bool $echoToConsole;
    private static array $levels = ['debug' => 0, 'info' => 1, 'warning' => 2, 'error' => 3];

    public function __construct(
        string $logFile = './logs/agent.log',
        string $level = 'info',
        bool $echoToConsole = false
    ) {
        $this->logFile       = $logFile;
        $this->level         = $level;
        $this->echoToConsole = $echoToConsole;

        $logDir = dirname($this->logFile);
        if (!is_dir($logDir)) {
            mkdir($logDir, 0755, true);
        }
    }

    public function debug(string $message, array $context = []): void
    {
        $this->log('debug', $message, $context);
    }

    public function info(string $message, array $context = []): void
    {
        $this->log('info', $message, $context);
    }

    public function warning(string $message, array $context = []): void
    {
        $this->log('warning', $message, $context);
    }

    public function error(string $message, array $context = []): void
    {
        $this->log('error', $message, $context);
    }

    private function log(string $level, string $message, array $context): void
    {
        if ((self::$levels[$level] ?? 0) < (self::$levels[$this->level] ?? 0)) {
            return; // Skip jika level lebih rendah dari threshold
        }

        $entry = json_encode([
            'timestamp'  => date('Y-m-d H:i:s'),
            'level'      => strtoupper($level),
            'message'    => $message,
            'context'    => $context,
        ], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES) . PHP_EOL;

        file_put_contents($this->logFile, $entry, FILE_APPEND | LOCK_EX);

        if ($this->echoToConsole) {
            $icon = match ($level) {
                'debug'   => '🔍',
                'info'    => 'â„šī¸',
                'warning' => 'âš ī¸',
                'error'   => '❌',
                default   => '📝',
            };
            echo "$icon [$level] $message" . (!empty($context) ? ' ' . json_encode($context) : '') . "\n";
        }
    }
}

Mengintegrasikan Logger ke Agent

// Dalam Agent::run()
$this->logger->info('Agent mulai', ['task' => substr($task, 0, 100), 'session_id' => session_id()]);

// Setelah tool call
$this->logger->debug('Tool dipanggil', [
    'tool'    => $toolName,
    'args'    => $args,
    'result'  => substr(json_encode($result), 0, 200),
]);

// Setelah mendapat respons
$this->logger->info('Request ke OpenAI', [
    'tokens_used'  => $response['usage']['total_tokens'],
    'prompt_tokens' => $response['usage']['prompt_tokens'],
    'iteration'    => $i + 1,
]);

// Error
try {
    // ... kode agent
} catch (\Throwable $e) {
    $this->logger->error('Agent error', [
        'error'   => $e->getMessage(),
        'file'    => $e->getFile(),
        'line'    => $e->getLine(),
        'session' => session_id(),
    ]);
    throw $e;
}

Poin Kunci Bab 16

Logging yang komprehensif akan menghemat jam-jam debugging di masa mendatang. Jangan biarkan AI Agent berjalan di "ruang gelap" — setiap aksi, keputusan, dan error harus tercatat.