Weave 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

Laravel Multiple Logs Laravel Package

csun-metalab/laravel-multiple-logs

Laravel package for configuring and using multiple log channels in one application. It helps route logs to separate files or handlers, making it easier to organize, isolate, and troubleshoot logs across different parts of a Laravel project.

View on GitHub
Deep Wiki
Context7

Getting Started

Start by reading the package's README.md, composer.json, and src/ directory in that order — this is a zero-star, zero-dependent package, so the source is the documentation. Identify the service provider (usually auto-discovered via extra.laravel.providers) and any config file it registers (typically config/multiple-logs.php or similar).

Minimal install:

composer require csun-metalab/laravel-multiple-logs
php artisan vendor:publish --provider="CSUNMetalab\MultipleLogs\MultipleLogsServiceProvider" --tag=config

Then confirm the package actually registers channels with Laravel's logging stack by inspecting config/logging.php after a test boot. A "multiple logs" package typically either (a) adds a custom Monolog handler that fans a single Log:: call out to N destinations, or (b) registers dynamically-named channels per user/tenant/context. Figure out which model this one uses before writing application code — it dictates everything downstream.

First use case: replace your single stack channel with purpose-specific channels — e.g. app (general), audit (model events), payments (financial events) — so that when something breaks you can tail the exact file you need instead of grepping one monolithic laravel.log. This is the lowest-risk, highest-value adoption path and doesn't require touching domain logic.

Implementation Patterns

Per-context log channels. The most common pattern for packages like this is a method that returns a channel name derived from request context:

Log::channel(multiple_logs()->channelFor(auth()->user()))->info('...');

The important shift is from Log::info() everywhere to a small helper or facade that resolves the channel. Centralize that resolution so you can change the strategy (per-user, per-tenant, per-queue-job) in one place.

Fan-out / stack composition. If the package provides a custom driver, you can drive it from a normal stack channel in config/logging.php:

'stack' => [
    'driver' => 'stack',
    'channels' => ['single', 'multiple-logs'],
],

This lets you adopt the package incrementally — keep existing channels, add the package's driver alongside. If the package is a stack replacement, mirror this pattern with the package's own config key so you don't lose existing destinations.

Audit / domain-event logging. Wire model events to a dedicated channel via an observer:

class AuditObserver
{
    public function created(Model $m): void
    {
        Log::channel('audit')->info('created', ['model' => $m::class, 'id' => $m->getKey()]);
    }
}

Register observers in a service provider rather than scattering Log:: calls in controllers. This keeps the "which channel" decision declarative.

Middleware-scoped logging. For per-request or per-user logs, push the resolved channel/user into a container binding in middleware, then have your logging helper read from the container. Avoid calling auth()->user() inside the package's resolution layer — queue workers, console commands, and event listeners often have no authenticated user, and you'll get null-dereferences in production long before you see them in local dev.

Testing. Use Log::spy() / Log::shouldReceive() against the resolved channel name. Assert on the channel, not just the message — the whole point of the package is routing, so a test that only checks "something was logged" is worthless. If the package wraps LoggerInterface, bind a fake logger into the container in TestCase::setUp().

Gotchas and Tips

  • config:cache will bite you. Dynamically-generated channel names computed at runtime must not depend on config values that get frozen during php artisan config:cache. Verify by running config:cache locally and exercising the log path — a surprising number of these packages pass in local and silently fail in production.
  • Directory and permission assumptions. Multiple log files often implies per-user files under storage/logs/users/. Confirm the package creates directories (many don't) and that your deploy pipeline's storage/logs permissions survive git clean -fdx. Add a mkdir -p to your deploy script if unsure.
  • Channel name collisions. If the package registers channels in config/logging.php at boot, it can overwrite a channel you defined manually (e.g. a channel also named audit). Grep config/logging.php for the package's channel names and namespace yours (e.g. app-audit rather than audit).
  • Log rotation and disk usage. Per-user or per-tenant logs explode in count and often aren't picked up by Laravel's daily driver. Add a scheduled storage:prune or a custom RotatingFileHandler — otherwise a busy multi-tenant app can fill a disk in weeks.
  • Queue and job context. Logs written from queued jobs lose auth()->user() and request(). If the package resolves channel names from these, jobs will crash or write to a fallback channel. Explicitly pass context via job payloads or a scoped container binding.
  • Don't log secrets into new channels. Audit-style channels are tempting targets for dumping full models — including password hashes, tokens, and PII. Add $hidden/$visible guards on any model whose events you log, and prefer an explicit toLogArray() on your models.
  • Monolog handler duplication. If you're stacking the package and a standard single handler, check whether both write to laravel.log. You'll get duplicate lines and confusing timestamps. Inspect the resolved handler stack with logger()->getHandlers() in a tinker session.
  • Low adoption = high support risk. This repo has zero stars and zero dependents. Vendor the package in a fork you control (or pin an exact commit in composer.json), read the entire src/ (~a few hundred lines at most), and be prepared to own the code. The license is MIT, so forking is safe. Treat the package as reference code rather than a maintained dependency.
  • Extension points to look for: if the package exposes an interface for channel resolution (e.g. a ChannelResolver contract), bind your own implementation in a service provider rather than editing published config — that's the one place where your customizations will survive a composer update.
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.
xiloryx/log-collector
a21ns1g4ts/filament-stripe
la-php/laravel-admin
artisan-build/community-prompts
vleroy/smart
ayles-software/laravel-australian-public-holidays
cboxdk/laravel-id-spatie
cboxdk/laravel-id-billing
cboxdk/laravel-id-billing-bridge
simple-as-fuck/php-performance-log
hsluv/hsluv
seampact/codegen
seampact/hooks
seampact/ir
mehedimi/laravel-amp-mail
happones/laravel-vue-i18n-generator
jwerd/inertia-table
siberfx/flysystem-wasabi
hollyit/token-replace
ippanelcom/laravel-sdk