PHPackages                             shays/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. shays/logger

ActiveLibrary

shays/logger
============

A simpler unopinionated logger library

v0.1(6y ago)05PHPPHP ^7.2CI failing

Since Feb 8Pushed 5y ago1 watchersCompare

[ Source](https://github.com/shaysegev/logger)[ Packagist](https://packagist.org/packages/shays/logger)[ RSS](/packages/shays-logger/feed)WikiDiscussions develop Synced 6d ago

READMEChangelog (1)Dependencies (8)Versions (3)Used By (0)

Logger library
==============

[](#logger-library)

This is an MVP for a simpler yet efficient logging library.

Following the [PSR-3 Logging standard](https://www.php-fig.org/psr/psr-3/) and inspired by [Monolog](https://github.com/Seldaek/monolog), the library comes with a handy functionality to get you started, though it's extremely unopinionated (if you want it to be), and is adjustable to suit various technical needs.

This means that with a few lines of code you can have a logger that is capturing and storing all PHP errors and exceptions to the path of your choice, as well as any custom logging you might want to do across your application. And with a few more lines, you can override or add any customisations you could think of, which essentially hooks into the library internal processing.

The documentation is assuming you are familiar with logging in PHP, and with the PSR-3 standard.

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

[](#installation)

You can install the latest version with composer:

```
composer require shays/logger

```

Get Started
-----------

[](#get-started)

The Logger library uses the builder design pattern, which helps providing the flexibility and extendability that could be used by the library, which the examples would soon help clarify.

To get started with the most basic and simple logger:

### The Basic Example

[](#the-basic-example)

```
use Shays\Logger;
use Shays\Logger\Stream\FileStream;

$log = (new Logger('MyApp'))->addStream(new FileStream('application.log'));
$log->notice('Log message');
```

And that's it. In the example we've created a `logger` instance with the application's name, that stores any PHP notices/warnings/errors and exceptions occurring in the application to the path of your choice, in a JSON format which includes the error message, the log severity, and a timestamp. Any exceptions would also be added in details.

### Timezones

[](#timezones)

You might find that you need to specify the timezone in which the log timestamps will be generated. You can do that with the `setTimezone` method, and passing a `DateTimeZone` instance:

```
use DateTimeZone;
use Shays\Logger;
use Shays\Logger\Stream\FileStream;

$log = (new Logger('MyApp'))
    ->addStream(new FileStream('application.log'))
    ->setTimezone(new DateTimeZone('Europe/London'));

$log->notice('Log message');
```

### Additional Context

[](#additional-context)

You might want to include additional data in the log, such as environment or user related information. You can specify them with `addContext`, which accepts an associative array of the information you would like to add:

```
use Shays\Logger;
use Shays\Logger\Stream\FileStream;

$log = (new Logger('MyApp'))
    ->addStream(new FileStream('application.log'))
    ->addContext([
        'environment' => 'local',
    ]);

$log->notice('Log message');
```

The context added on the `logger` instance level would be added to each individual log entry.

#### Adding Context To Logs

[](#adding-context-to-logs)

You can add context to individual logs, such as added relevant information, exceptions objects, etc.

```
// Simple log context added
$log->notice('User not found', ['id' => 123]);
```

##### Capturing Exceptions

[](#capturing-exceptions)

Exceptions can be added as context, which would then be parsed and extracted by the logger to provide the relevant details.

```
// Adding captured exception information
try {
    // Trying an API connection
} catch (\Throwable $e) {
    $log->error('API connection failed', ['exception' => $e]);
}
```

### Logging Errors Only

[](#logging-errors-only)

As an example, it's possible to set a second argument to the `addStream` method to tell the file logger which is the least severe log level that you are interested in logging to the file (In this case, all log levels from errors up to the most severe errors would be stored, skipping notices, warnings, etc).

```
use Shays\Logger;
use Shays\Logger\LogLevel;
use Shays\Logger\Stream\FileStream;

$log = (new Logger('MyApp'))
    ->addStream(new FileStream('application.log', LogLevel::ERROR));

// This won't be logged to the file
$log->notice('Log message');
```

Advanced Usages
---------------

[](#advanced-usages)

The logger library comes with powerful extended abilities. Pretty much everything is allowed to be customised, you can even create your own `Log` object which is used by the handlers and log streams, and rename the fields and serialize the data the way you wish to.

Let's start with some basic examples.

### Custom Log Levels

[](#custom-log-levels)

It's possible to add custom log levels dynamically via the `addLogLevel` method, which takes the log level number and the name (which will be used to invoke it from the `logger` instance).

It's recommended creating a new class for the custom levels, which can then be passed around the app when needed:

```
// CustomLogLevel.php

class CustomLogLevel {
   /** @var int New progress log level (e.g. for logging cron task requests) */
   const PROGRESS = 50;
}
```

And in the app:

```
use CustomLogLevel;
use Shays\Logger;
use Shays\Logger\Stream\FileStream;

$log = (new Logger('MyApp'))
    ->addStream(new FileStream('application.log', CustomLogLevel::PROGRESS))
    ->addLogLevel(CustomLogLevel::PROGRESS, 'PROGRESS');

// This is now possible to call it directly
$log->progress('Log message');
```

### Custom Handlers

[](#custom-handlers)

You can add your custom handlers to the `logger` instance, which would be called whenever a log is created. The custom handlers should follow the [LogHandlerInterface](src/Logger/Handlers/LogHandlerInterface.php) which is consisted of two methods, `handle` and `shouldHandle`.

```
// MyCustomHandler.php

use Shays\Logger\Handlers\LogHandlerInterface;
use Shays\Logger\LogInterface;
use Shays\Logger\LogLevel;

class MyCustomHandler implements LogHandlerInterface
{
   public function handle(LogInterface $log): void
   {
       // Do anything with the log object
       // (e.g. get the message, context, etc)
       // (read more about the Log object below)
   }

   public function shouldHandle(LogInterface $log): bool
   {
       // e.g. handle notices and the more severe logs
       return $log->getLevel() >= LogLevel::NOTICE;
   }
}
```

And in the app:

```
use MyCustomHandler;
use Shays\Logger;

$log = (new Logger('MyApp'))
    ->addHandler(new MyCustomHandler());
```

Using the custom handlers you can send messages to Slack or use any third party integrations that helps monitoring the health of your application.

### Custom Streamers

[](#custom-streamers)

Custom streamers are similar to custom handlers, only they are intended for streaming and saving serialized logs. The custom streamers should follow the [StreamInterface](src/Logger/Stream/StreamInterface.php), which is consisted of two methods: `write` and `shouldWrite`.

In the examples above, we've used the library's `FileStream` class to store logs to a particular file, though we can use our own Stream class to create our unique functionality:

```
// XmlStream.php

use Shays\Logger\LogInterface;
use Shays\Logger\Stream\StreamInterface;

class XmlStream implements StreamInterface
{
   /** @var int Lowest log level for handling log */
   private $lowestLevel;

   public function __construct(int $lowestLevel)
   {
       $this->lowestlevel = $lowestLevel;
   }

   public function write(string $log): void
   {
       // Write the serialized log to the database or system file
   }

   public function shouldWrite(LogInterface $log): bool
   {
       return $log->getLevel() >= $this->lowestLevel;
   }
}
```

And in the app:

```
use Shays\Logger;
use XmlStream;

 $log = (new Logger('MyApp'))
     ->addStream(new XmlStream(LogLevel::ERROR));
```

#### Streaming Serializers

[](#streaming-serializers)

By default the log is being serialized to JSON when passed to the `write` method, though more serializers can be added, and can be passed down the Logger instance, as long as they follow the [SerializerInterface](src/Logger/Serializer/SerializerInterface.php).

```
// XmlSerializer.php

use Shays\Logger\LogInterface;
use Shays\Logger\Serializer\SerializerInterface;
use Symfony\Component\Serializer\Encoder\XmlEncoder;

class XmlSerializer implements SerializerInterface
{
    private $encoder;

    public function __construct()
    {
        $this->encoder = new XmlEncoder();
    }

    public function serialize(LogInterface $log)
    {
        // Serialize the data to XML format which would
        // be then passed to the streaming classes.

        // The $log->toArray() method is transforming the
        // log object to an array with the relevant
        // log information, ready to be serialized
        return $this->encoder->encode($log->toArray(), 'xml');
    }
}
```

And in the app:

```
use XmlSerializer;
use XmlStream;
use Shays\Logger;

 $log = (new Logger('MyApp', new XmlSerializer()))
     ->addStream(new XmlStream(LogLevel::ERROR));
```

And all the custom streamers would now be handled with XML.

### The Log Object

[](#the-log-object)

[The library's log object](src/Logger/Log.php) provides a few handy methods for getting the data stored in each individual log.

Considering the custom handler example earlier:

```
class MyCustomHandler implements LogHandlerInterface
{
    public function handle(LogInterface $log): void
    {
        // Handle log
    }
}
```

You can now use the log object to access its data, such as the log message:

```
$log->getMessage();
```

The log channel:

```
$log->getChannel();
```

The log level:

```
$log->getLevel();
```

The log level name (e.g. warning, error, etc):

```
$log->getLevelName();
```

The log timestamp:

```
$log->getTimestamp();
```

You can also get the context array:

```
$log->getAllContext();
```

Or just a single context:

```
// Check if exists
$log->hasContext('userId');

// Get the context
$log->getContext('userId');
```

You can also use the dynamic shorthand `get` method:

```
// Gets the log message
$log->get('message');

// Gets the log level
$log->get('level');

// Gets the userId context (fallback to context)
$log->get('userId');
```

#### Customising the Log Object

[](#customising-the-log-object)

The custom log object provides additional flexibility over the data being passed down to the handlers and streamers. By default the library's [Log object](src/Logger/Log.php) covers the most minimal data you can expect from each log entry, though there's no control over the structure (e.g. what goes in context stays in context!)

When the log is passed to serializers (e.g. to write the log to a JSON file), before the data is serialized a `$log->toArray()` method is called to determine the data we're interested in passing through.

While the default provides the basic structure and would be enough for most cases, extending it helps us creating the desired data structure which will eventually be stored in the exact same way. This works extremely well for important global context being passed down as it's always going to be included. For example:

```
// CustomLog.php
use Shays\Logger\Log;

class CustomLog extends Log
{
    public function toArray(): array
    {
        $context = $this->getAllContext();
        // Remove environment from context (which will be used on the top array level)
        unset($context['environment']);
        return [
            'timestamp' => $this->getTimestamp(),
            'level' => $this->getLevel(),
            'message' => $this->getMessage(),
            'levelName' => $this->getLevelName(),
            'environment' => $this->getContext('environment'),
            'additionalData' => $context,
        ];
    }
}
```

And we can now pass the new object in the app:

```
use CustomLog;
use Shays\Logger;
use Shays\Logger\Stream\FileStream;

 $log = (new Logger('MyApp', null, CustomLog::class))
    ->addStream(new FileStream('application.log'))
    ->addContext([
        'environment' => 'debug',
        'ipAddress' => '127.0.0.1',
    ]);

$log->info('Info message');
```

###  Health Score

20

—

LowBetter than 14% of packages

Maintenance20

Infrequent updates — may be unmaintained

Popularity4

Limited adoption so far

Community7

Small or concentrated contributor base

Maturity42

Maturing project, gaining track record

 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.

###  Release Activity

Cadence

Unknown

Total

1

Last Release

2291d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/090b186044ad143eca586082bb4cfd4e7b0f20427afb22e1d8cde0397e3433c2?d=identicon)[shaysegev](/maintainers/shaysegev)

---

Top Contributors

[![shaysegev](https://avatars.githubusercontent.com/u/11139571?v=4)](https://github.com/shaysegev "shaysegev (1 commits)")

---

Tags

logging-libraryphp7

###  Code Quality

TestsPHPUnit

Static AnalysisPHPStan

Code StylePHP\_CodeSniffer

Type Coverage Yes

### Embed Badge

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

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

###  Alternatives

[sylius/sylius

E-Commerce platform for PHP, based on Symfony framework.

8.4k5.6M651](/packages/sylius-sylius)[shopware/platform

The Shopware e-commerce core

3.3k1.5M3](/packages/shopware-platform)[sulu/sulu

Core framework that implements the functionality of the Sulu content management system

1.3k1.3M152](/packages/sulu-sulu)[drupal/core

Drupal is an open source content management platform powering millions of websites and applications.

19462.3M1.3k](/packages/drupal-core)[prestashop/prestashop

PrestaShop is an Open Source e-commerce platform, committed to providing the best shopping cart experience for both merchants and customers.

9.0k15.4k](/packages/prestashop-prestashop)[shopware/core

Shopware platform is the core for all Shopware ecommerce products.

595.2M386](/packages/shopware-core)

PHPackages © 2026

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