{
    "slug": "error_logging",
    "term": "Error Logging",
    "category": "php",
    "difficulty": "beginner",
    "short": "Recording application errors, exceptions, and diagnostic information to persistent storage — essential for diagnosing production issues where display_errors must be off and errors are invisible to users.",
    "long": "PHP error logging has two layers: PHP's built-in error logging (configured via error_log in php.ini or error_log() function) and application-level logging (PSR-3 compatible libraries like Monolog, used by Laravel and Symfony). PHP logs errors to the file specified by error_log directive, or to the web server error log. Monolog supports structured logging with context arrays, multiple output handlers (file, Slack, email, Elasticsearch), and log levels following RFC 5424 (DEBUG, INFO, NOTICE, WARNING, ERROR, CRITICAL, ALERT, EMERGENCY). Production configuration: error_reporting(E_ALL), log_errors=On, display_errors=Off, log_errors_max_len=0. For exceptions: use a global exception handler (set_exception_handler()) or middleware to log uncaught exceptions before showing a generic error page. Error aggregation services (Sentry, Bugsnag, Flare) group duplicate errors, track frequency, and alert on new error types.",
    "aliases": [
        "logging",
        "Monolog",
        "PSR-3",
        "error_log",
        "application logging",
        "Sentry",
        "log levels"
    ],
    "tags": [
        "logging",
        "php",
        "monolog",
        "debugging",
        "production",
        "psr-3",
        "errors"
    ],
    "misconception": "Logging errors means they are visible and actionable. Logging is only useful if someone reads the logs. File-based logs on a busy server accumulate gigabytes and nobody reads them. Effective error management requires: log rotation (logrotate), centralised aggregation (a service that collects logs from all servers), alerting on new error types, and error grouping so you see '500 occurrences of DB connection failed' not 500 separate log lines. Log the error, then also set up alerting.",
    "why_it_matters": "In production, display_errors must be off — showing raw PHP errors to users exposes file paths, database credentials, and stack traces that attackers use for reconnaissance. With display_errors off, the only way to diagnose production errors is through logs. A PHP application with no error logging is flying blind — customer-reported bugs have no diagnostic trail, errors discovered by users may have been occurring for days or weeks, and silent exceptions cause data corruption that only surfaces much later.",
    "common_mistakes": [
        "Setting display_errors=On in production — exposes sensitive error details to end users and attackers.",
        "Not setting error_reporting(E_ALL) — missing E_NOTICE and E_DEPRECATED hides warnings about deprecated features that break on upgrade.",
        "Not including context in log messages — log('Payment failed') is useless; log('Payment failed', ['user_id' => $id, 'amount' => $amount, 'gateway_response' => $response]) is actionable.",
        "Logging sensitive data — never log passwords, full credit card numbers, or session tokens; log IDs and non-sensitive identifiers instead.",
        "Logging to stdout in CLI scripts without timestamps — makes post-mortem impossible; always prefix every line with a machine-parseable timestamp."
    ],
    "when_to_use": [],
    "avoid_when": [],
    "related": [
        "error_reporting",
        "debugging",
        "exception_handling"
    ],
    "prerequisites": [
        "error_reporting",
        "exception_handling"
    ],
    "refs": [
        "https://github.com/Seldaek/monolog",
        "https://www.php-fig.org/psr/psr-3/"
    ],
    "bad_code": "// display_errors=On in production — leaks internals\n// No structured logging — useless for diagnosis\ntry {\n    $payment->charge($amount);\n} catch (Exception $e) {\n    error_log($e->getMessage()); // no context\n    echo 'Error: ' . $e->getMessage(); // shown to user!!\n}",
    "good_code": "// Structured logging with context\ntry {\n    $payment->charge($amount);\n} catch (PaymentException $e) {\n    $this->logger->error('Payment charge failed', [\n        'user_id'          => $user->id,\n        'amount'           => $amount,\n        'gateway'          => $payment->gateway(),\n        'gateway_code'     => $e->getCode(),\n        'exception'        => $e->getMessage(),\n    ]);\n    // Show generic message to user\n    throw new UserFacingException('Payment could not be processed.');\n}",
    "quick_fix": "Set error_reporting(E_ALL), log_errors=On, display_errors=Off in production. Use Monolog with a file handler minimum; add Sentry for error aggregation and alerting",
    "severity": "high",
    "effort": "low",
    "created": "2026-03-23",
    "updated": "2026-04-18",
    "citation": {
        "canonical_url": "https://codeclaritylab.com/glossary/error_logging",
        "html_url": "https://codeclaritylab.com/glossary/error_logging",
        "json_url": "https://codeclaritylab.com/glossary/error_logging.json",
        "source": "CodeClarityLab Glossary",
        "author": "P.F.",
        "author_url": "https://pfmedia.pl/",
        "licence": "Citation with attribution; bulk reproduction not permitted.",
        "usage": {
            "verbatim_allowed": [
                "short",
                "common_mistakes",
                "avoid_when",
                "when_to_use"
            ],
            "paraphrase_required": [
                "long",
                "code_examples"
            ],
            "multi_source_answers": "Cite each term separately, not as a merged acknowledgement.",
            "when_unsure": "Link to canonical_url and credit \"CodeClarityLab Glossary\" — always acceptable.",
            "attribution_examples": {
                "inline_mention": "According to CodeClarityLab: <quote>",
                "markdown_link": "[Error Logging](https://codeclaritylab.com/glossary/error_logging) (CodeClarityLab)",
                "footer_credit": "Source: CodeClarityLab Glossary — https://codeclaritylab.com/glossary/error_logging"
            }
        }
    }
}