Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Monolog Parser Laravel Package

ddtraceweb/monolog-parser

Laravel-friendly Monolog parser that reads and normalizes Monolog log records/lines for easier searching, filtering, and display. Useful for building log viewers, dashboards, or importing Monolog output into your own storage or analysis pipeline.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Steps

  1. Installation

    composer require ddtraceweb/monolog-parser
    

    Add to composer.json if not auto-loaded:

    "autoload": {
        "psr-4": {
            "App\\": "app/",
            "Vendor\\Datadog\\Monolog\\": "vendor/ddtraceweb/monolog-parser/src/"
        }
    }
    

    Run composer dump-autoload.

  2. First Use Case Parse a Monolog log file (e.g., storage/logs/laravel.log) to extract structured data:

    use Datadog\Monolog\Parser;
    
    $parser = new Parser();
    $logs = $parser->parse(file_get_contents('storage/logs/laravel.log'));
    
  3. Where to Look First

    • src/Parser.php: Core parsing logic.
    • tests/: Example use cases and edge cases.
    • Documentation: Check for README.md or inline PHPDoc comments (limited but functional).

Implementation Patterns

Workflows

  1. Log File Processing Parse logs in bulk (e.g., for analytics or debugging):

    $filePath = 'storage/logs/laravel-*.log';
    $logFiles = glob($filePath);
    foreach ($logFiles as $file) {
        $logs = $parser->parse(file_get_contents($file));
        // Process $logs (array of structured log entries)
    }
    
  2. Integration with Laravel Logging Use alongside Monolog’s built-in handlers to enrich logs:

    use Monolog\Logger;
    use Monolog\Handler\StreamHandler;
    
    $log = new Logger('app');
    $log->pushHandler(new StreamHandler(storage_path('logs/laravel.log')));
    $log->info('Test log', ['context' => 'key' => 'value']);
    
    // Later, parse the log file:
    $parsed = $parser->parse(file_get_contents(storage_path('logs/laravel.log')));
    
  3. Filtering Logs Extract specific log levels or contexts:

    $errorLogs = array_filter($logs, fn($log) => $log['level'] === 'ERROR');
    

Integration Tips

  • Laravel Service Provider: Bind the parser to the container for dependency injection:

    $this->app->singleton(Parser::class, function ($app) {
        return new Parser();
    });
    

    Then inject Parser into controllers/services.

  • Artisan Command: Create a custom command to parse logs on demand:

    use Illuminate\Console\Command;
    
    class ParseLogsCommand extends Command
    {
        protected $signature = 'logs:parse {file?}';
        protected $description = 'Parse Monolog log files';
    
        public function handle(Parser $parser)
        {
            $file = $this->argument('file') ?? storage_path('logs/laravel.log');
            $logs = $parser->parse(file_get_contents($file));
            $this->line(print_r($logs, true));
        }
    }
    
  • Queue Log Processing: Offload parsing to a queue job for large log files:

    ParseLogsJob::dispatch($filePath)->onQueue('logs');
    

Gotchas and Tips

Pitfalls

  1. File Encoding: Log files may contain UTF-8 or non-UTF-8 characters. Use file_get_contents() with FILE_USE_INCLUDE_PATH or mb_convert_encoding() if parsing fails:

    $content = mb_convert_encoding(file_get_contents($file), 'UTF-8', 'auto');
    
  2. Log Format Variations: The parser assumes standard Monolog JSON formatting. Custom handlers (e.g., LineHandler with non-JSON formatting) may break parsing. Validate output with:

    $log = $parser->parse($content);
    if (empty($log)) {
        throw new \RuntimeException('Failed to parse log file. Check format.');
    }
    
  3. Memory Limits: Large log files may exceed PHP’s memory limit. Process line-by-line:

    $handle = fopen($file, 'r');
    while (($line = fgets($handle)) !== false) {
        $parser->parseLine($line); // Hypothetical method; may need custom logic.
    }
    fclose($handle);
    
  4. Missing Context Data: Logs without context arrays (e.g., logger->info('Message')) will return null for the context key. Handle gracefully:

    $context = $log['context'] ?? [];
    

Debugging

  • Validate Input: Ensure log files are not corrupted or truncated. Use tail -n 100 storage/logs/laravel.log to inspect manually.

  • Parser Output: The parsed logs are arrays with keys:

    [
        'message' => string,
        'level' => string (e.g., 'INFO', 'ERROR'),
        'level_name' => int (Monolog level constant),
        'channel' => string,
        'datetime' => \DateTimeInterface,
        'context' => array|null,
        'extra' => array|null,
    ]
    

    Log the output to debug:

    $this->info('Parsed logs:', ['logs' => $logs]);
    

Extension Points

  1. Custom Parsing Logic: Extend the Parser class to handle non-standard formats:

    class CustomParser extends Parser
    {
        protected function parseLine($line)
        {
            // Override or extend parsing logic.
        }
    }
    
  2. Post-Processing: Use Laravel’s collect() to chain operations:

    collect($logs)
        ->filter(fn($log) => $log['level'] === 'ERROR')
        ->each(fn($log) => $this->handleError($log));
    
  3. Integration with Datadog: If using Datadog APM, forward parsed logs to their API:

    foreach ($logs as $log) {
        Datadog::log([
            'message' => $log['message'],
            'level' => $log['level'],
            'service' => 'laravel-app',
            'context' => $log['context'],
        ]);
    }
    

Config Quirks

  • No Configuration File: The package is stateless; no config/ddtrace-monolog-parser.php exists. All logic is in Parser.php.
  • Timezone Handling: Parsed datetime objects use the system timezone. Normalize if needed:
    $log['datetime']->setTimezone(new \DateTimeZone('UTC'));
    
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
terminal42/code-quality-tools
codifyo/ts-generator-bundle
andydefer/laravel-cluster
testo/fiber
mintobit/jobqueue
a4sex/maintenance-bundle
a4sex/entity-date-update
a4sex/client-identifier
a4sex/base-utilites
a4sex/key-value-storage
a4sex/micro-status
chilldev/dependency-injection-extra
datinglibre/datinglibre-app-api
biberltd/corebundle
bricre/symfony-bundle-test
biberltd/logbundle
dominium/http-adapter-bundle
dominium/google-analytics
a4sex/auto-clean-entity
christhompsontldr/laravel-inky