PHPackages                             northrook/logger - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Logging &amp; Monitoring](/categories/logging)
4. /
5. northrook/logger

ActiveLibrary[Logging &amp; Monitoring](/categories/logging)

northrook/logger
================

PSR-3 compliant logging, and global stopwatch timer.

0398PHP

Since Jun 17Pushed 11mo agoCompare

[ Source](https://github.com/northrook/logger)[ Packagist](https://packagist.org/packages/northrook/logger)[ RSS](/packages/northrook-logger/feed)WikiDiscussions main Synced 1mo ago

READMEChangelogDependenciesVersions (1)Used By (0)

Logger
======

[](#logger)

[PSR-3 compliant](https://www.php-fig.org/psr/psr-3/) logging implementation, for easy global logging.

The package provides two key classes:

```
Northrook\Logger();     // a PSR-3 compliant logger.
Northrook\Logger\Log(); // a static accessor to any PSR-3 compliant logger.
```

The goal of this package is to provide easy logging across your PHP application, especially in scenarios where dependency injection may be cumbersome or impractical.

Using the static `Log` class, you can easily log directly to a `LoggerInterface` instance.

Think of it as a *facade* or *proxy* to a `LoggerInterface` instance.

If you are a stickler for OOP, you can just use the `Logger` class directly.

Installation
------------

[](#installation)

Install the latest version with composer:

```
composer require northrook/logger
```

Basic Usage
-----------

[](#basic-usage)

The `Log` class is a static accessor to a set `LoggerInterface`..

```
use Northrook\Logger\Log;

Log::info( 'Hello World!' );
```

When any of the `Log` methods are called, the logger will instantiate a new `Logger` object if it has not been instantiated yet.

The included `Logger` will be the default.

### Assigning a Logger

[](#assigning-a-logger)

You can manually assign a `LoggerInterface` using `Log::setLogger()`:

```
use Northrook\Logger\Log;

Log::setLogger(
    logger: new Logger(), // LoggerInterface
    import: true,         // bool - default: true
);
```

If `setLogger` is provided a `Northrook\Logger` instance, it will import any log entries any previous `LoggerInterface`.

If you want to just override the current `LoggerInterface` without importing, pass `false` as the second argument:

```
Log::setLogger(
    logger: new Logger(),
    import: false,
);
```

This is useful when you need to instantiate an arbitrary `LoggerInterface` earlier in your code, and later use the included `Northrook\Logger` class.

The `Log` will act as a proxy to the `LoggerInterface` instance, using the included `Northrook\Logger` class is not required at all.

Log - Static Accessor
---------------------

[](#log---static-accessor)

It provides all the PSR-3 methods, with a few extras.

The arbitrary `log()` is replaced by the `Log::entry()` method.

### Logging Exceptions

[](#logging-exceptions)

The `Log` class provides a method to easily log exceptions:

```
use Northrook\Logger\Log;

try {
    $variable = \file_get_contents( 'data.json' );
} catch( \Exception $exception ) {
    Log::exception(
        $exception,   // required
        level: null,  // optional
        message: null // optional
        context: [],  // optional
     );
}

// logged as:
0 => 'warning',
1 => 'ile_get_contents(data.json): Failed to open stream: No such file or directory',
2 => [ 'exception' => $exception ],
```

It will parse the exception and log it accordingly.

It will not overwrite the `$level` or `$message` if they are provided.

The `$context['exception']` will be set to the provided `$$exception`.

### Precision Timestamps

[](#precision-timestamps)

When setting a `LoggerInterfacing` using `Log::setLogger()`, you can pass a `bool $precision` argument, setting the static `$enablePrecision` property.

Important

The default value is `true`. It is recommended to set this value according to your environment, as it can be expensive in production.

When `Log::setLogger()` is first called, a static `int` will be assigned to the `hrtime(true)`. This is used to calculate the `DeltaMs` and `OffsetMs` values.

Each `Log::entry()` has the `?bool $precision` argument, which is `null` by default, using the static `$enablePrecision` property.

Use this to set `$precision` for the current `Log::entry()` call.

```
use Northrook\Logger\Log;

Log::setLogger(
    logger: new Logger(),
    import: true,
    precision: true, // default: true
);

// enable precision for the current entry
Log::entry( 'Hello World!', precision: true );

// disable precision for the current entry
Log::entry( 'Hello World!', precision: false );
```

Entries logged with `$precision` will have the following keys added to the `$context` array:

```
'precision' => [
    "hrTime" => 330531205286100 // The hrtime at the time of the log entry
    "hrDelta" => 1081000        // The difference the current entry and first `Log::entry()` call
    "DeltaMs" => "1.08ms"       // Time since initial `Log::setLogger()` call in milliseconds
    "OffsetMs" => "0.0079ms"    // Time since the previous `Log::entry( .. precision: true )` call in milliseconds
]
```

Logger
------

[](#logger-1)

The provided `Logger` class is a PSR-3 compliant logger, extending the `Psr\Log\AbstractLogger`, implementing the `Psr\Log\LoggerInterface` interface.

It provides access to all the PSR-3 methods, and is a drop-in replacement for any `Psr\Log\LoggerInterface` instance.

In addition, it a few simple methods for managing log entries:

```
$logger = new Northrook\Logger();

$logger->log( ... )          // log an entry using the PSR-3 standard
$logger->hasLogs() : bool    // check if there are any log entries
$logger->getLogs() : array   // get all log entries, without manipulating them
$logger->cleanLogs() : array // get all log entries, and clear them
$logger->clear()             // clear all log entries, without getting them
$logger->count() : int       // count all log entries
$logger->import( $logger )   // import log entries from another LoggerInterface
$logger->printLogs() : array // get an array of each entry as a human-readable string
```

The `printLogs()` method is useful for quickly printing all log entries.

It will **not** prefix a timestamp by default. Pass `true` as the first argument to prefix the timestamp.

```
// example:
$logger->entries = [
    0 => 'warning',
    1 => 'ile_get_contents(data.json): Failed to open stream: No such file or directory',
    2 => [ 'exception' => $exception ],
];

// default:
0 => 'Warning: file_get_contents(data.json): Failed to open stream: No such file or directory'

// with timestamp:
0 => '[2024-06-20T06:47:47+00:00] Warning: file_get_contents(data.json): Failed to open stream: No such file or directory'
```

If the Logger is destroyed without first calling `cleanLogs()`, the `printLogs()` method will print the logs to the PHP error log.

License
-------

[](#license)

Licensed under the [MIT Licence](LICENSE), and is free to use in any project.

### Credits

[](#credits)

[BufferingLogger](https://github.com/symfony/error-handler/blob/master/BufferingLogger.php) - Nicolas Grekas

###  Health Score

18

—

LowBetter than 8% of packages

Maintenance38

Infrequent updates — may be unmaintained

Popularity12

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity14

Early-stage or recently created project

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

### Community

Maintainers

![](https://www.gravatar.com/avatar/6ea0cb455f9912f9649c15f87435485f0e5ee9197e8cd767680689bb75cd2888?d=identicon)[martinlikescoffee](/maintainers/martinlikescoffee)

---

Top Contributors

[![martinlikescoffee](https://avatars.githubusercontent.com/u/60818044?v=4)](https://github.com/martinlikescoffee "martinlikescoffee (59 commits)")

---

Tags

composer-packageloggingphppsr-3

### Embed Badge

![Health badge](/badges/northrook-logger/health.svg)

```
[![Health](https://phpackages.com/badges/northrook-logger/health.svg)](https://phpackages.com/packages/northrook-logger)
```

###  Alternatives

[psr/log

Common interface for logging libraries

10.4k1.2B9.2k](/packages/psr-log)[itsgoingd/clockwork

php dev tools in your browser

5.9k27.6M94](/packages/itsgoingd-clockwork)[graylog2/gelf-php

A php implementation to send log-messages to a GELF compatible backend like Graylog2.

41838.2M138](/packages/graylog2-gelf-php)[bugsnag/bugsnag-psr-logger

Official Bugsnag PHP PSR Logger.

32132.5M2](/packages/bugsnag-bugsnag-psr-logger)[consolidation/log

Improved Psr-3 / Psr\\Log logger based on Symfony Console components.

15462.2M7](/packages/consolidation-log)[datadog/php-datadogstatsd

An extremely simple PHP datadogstatsd client

19124.6M15](/packages/datadog-php-datadogstatsd)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
