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

Log Laravel Package

cakephp/log

A flexible logging library for CakePHP applications, offering configurable engines, log scopes, and PSR-3-compatible interfaces. It helps route messages to files, syslog, or custom handlers with minimal setup.

Deep Wiki
Context7

Getting Started

cakephp/log is the logging subsystem extracted from CakePHP: a static Log facade, a BaseLog engine base class, and a handful of engines (FileLog, ConsoleLog, SyslogLog, ArrayLog). It is a PSR-3 logger, but it is not a framework — there is no service provider, no config file, no container.

composer require cakephp/log

Watch the version you pull. cakephp/log ^4 requires psr/log ^1|^2; ^5 requires psr/log ^3. Laravel 10/11 ship Monolog 3, which needs psr/log ^3, so prefer cakephp/log ^5 on modern Laravel. It drags in cakephp/core (small) but not the full framework.

Where to look first:

  1. src/Log.php — the whole public API (setConfig, getConfig, write, engine, drop, reset, and the debug()/error()/… shortcuts).
  2. src/Engine/BaseLog.php — what your custom engines extend (_format(), getConfig()).
  3. src/Engine/FileLog.php — the canonical example of level filtering, file/path config, and scope handling.

Minimal standalone setup (note: LOGS is a CakePHP constant that does not exist in Laravel):

use Cake\Log\Log;
use Cake\Log\Engine\FileLog;

Log::setConfig('default', [
    'engine' => FileLog::class,
    'path'   => storage_path('logs'),
    'file'   => 'cakephp.log',
    'levels' => ['error', 'warning', 'info'],
]);

Log::write('info', 'hello from CakePHP logging');

First real use case on a Laravel project: you've installed a CakePHP-adjacent library (or a legacy module) that calls Log::write() / uses LogTrait, and you want those calls to land in your existing Laravel channel instead of a second, orphaned log file. See the forwarding engine in the next section.

Implementation Patterns

Bootstrap once, in a provider. The Log class is a global static registry. Configure it in register() so it is set before any library code runs, and never inside a request path.

// app/Providers/CakeLogServiceProvider.php
public function register(): void
{
    Log::setConfig('default', [
        'engine' => LaravelLogEngine::class,
        'channel' => 'stack',
    ]);
}

Forward to Laravel instead of duplicating sinks. The highest-value pattern is a custom engine that extends BaseLog and proxies to Illuminate\Support\Facades\Log. This keeps one log destination, one set of handlers, one log-shipping pipeline.

use Cake\Log\Engine\BaseLog;

class LaravelLogEngine extends BaseLog
{
    public function log($level, \Stringable|string $message, array $context = []): void
    {
        \Illuminate\Support\Facades\Log::channel($this->getConfig('channel', 'stack'))
            ->log($level, (string)$message, $context);
    }
}

Channel-per-engine. Log::setConfig('name', [...]) is really "named engine", not "channel". Use several — payments, audit, slow — each with its own levels and destination, then target them per call:

Log::setConfig('audit', [
    'engine' => FileLog::class,
    'path' => storage_path('logs'),
    'file' => 'audit.log',
    'levels' => ['notice', 'info', 'warning', 'error'],
]);

Log::write('notice', 'order 42 refunded', ['scope' => ['audit'], 'actor' => 7]);

scope is the routing key. A scope in the context array is how you fan a single engine config across multiple files: 'file' => '{scope}.log' causes scope: ['orders'] to write orders.log. Scope also lets one setConfig('default') serve several logical loggers without extra engine instances.

Per-engine level filtering. levels accepts an array or comma string. Filtering happens inside the engine, so filtered-out writes still cost the call. For high-volume debug traffic, add a cheap guard (Log::engine('debug') returns false when unconfigured) rather than relying on the engine to swallow it.

LogTrait for library classes. Any class using Cake\Log\LogTrait gains a log() method that forwards to Log::write(). This is why the package exists standalone — third-party CakePHP code expects it. You don't need to adopt it in your own classes; you just need it to work when a dependency uses it.

Test with ArrayLog. Swap the engine in a test bootstrap and assert on captured entries; reset afterwards.

Log::setConfig('default', ['engine' => ArrayLog::class]);
// ... exercise code ...
$this->assertStringContainsString('refunded', Log::engine('default')->read()[0]);

Bridging the other direction. If you're porting CakePHP code into Laravel, keep Log::write() calls in the library layer and configure a forwarding engine at the boundary. Don't sprinkle Log:: calls through your Laravel app code — use Laravel's Log there and treat cakephp/log as an adapter layer only.

Gotchas and Tips

  • Static state leaks between tests. Engines are cached in Log::$_engines and config in Log::$_config. Always Log::reset() in tearDown() (or Log::drop($name) for one), otherwise a config from an earlier test silently wins.
  • Engine instantiation is lazy and sticky. Calling setConfig() after an engine has already been materialized for that name will not rebuild it. Use Log::drop($name) to force re-creation. In Octane/long-running workers this matters: config changed in a request is invisible to the next.
  • LOGS, APP, DS constants are CakePHP-only. Any tutorial snippet referencing LOGS will fatal in a Laravel app. Substitute storage_path('logs').
  • Plugin-dot notation won't resolve. 'engine' => 'MyPlugin.MyEngine' relies on App::className() from cakephp/core's class loader, which is not wired up outside CakePHP. Always pass Fully\Qualified\ClassName::class.
  • FileLog does not rotate. It appends forever. Point it at a storage/logs/*.log path covered by your existing logrotate config, or use the forwarding engine and let Laravel/Monolog handle rotation.
  • FileLog does not interpolate PSR-3 placeholders. Monolog expands {user} from context; this package's engines do not. Build the message yourself or normalize in your forwarding engine.
  • Unknown levels throw. Log::write('warn', ...) (instead of 'warning') raises InvalidArgumentException; an unconfigured engine name raises RuntimeException — the debug()/error() shorthands are safer than string levels in dynamic code.
  • FileLog fails loudly on a missing directory. path must exist and be writable by the PHP user; there's a mask option if your umask produces group-unreadable files.
  • PSR-3 signature drift across majors. CakePHP 3-era engines implement write($level, $message, array $context); 4.x/5.x use PSR-3's log($level, $message, array $context). If you copy an engine from an old blog post, it will be silently skipped or fatal depending on the version.
  • This repo is read-only. It's a split of cakephp/cakephp. Issues/PRs opened here get closed; file them against the monorepo, and pin a released tag rather than a branch alias. Low star count reflects the split, not the maturity — but it also means no community support channel of its own.
  • Score it honestly. For a greenfield Laravel app there is no reason to add this over Monolog. Its value is purely interoperability: making code that assumes Cake\Log\Log exists behave correctly inside a Laravel codebase. Adopt it as a compatibility shim, not a logging strategy.
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.
middlewares/firewall
qubiqx/montapacking
nyoncode/laravel-package-console
pnscripts/filament-broadquill-lite
pnscripts/laravel-sentfold-lite
vleap/mx-sdk-laravel-internal
twidpay/utils
htetmyathlaing/scout-elasticsearch-driver
artisan-toolbox/front-awesome
ls/client-assistant
users-au/laravel-client
cgv/localized-resource
noith/settings
kda/laravel-package
kda/filament-dynamic-navigation
bypersoft/signbox
pairus/product-data
fayne/laravel-filament-cms-core
nodisrupt/laravel-agent
sierratecnologia/media-manager