PHPackages                             cumulati/monolog-context - 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. cumulati/monolog-context

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

cumulati/monolog-context
========================

A utility to create monolog context, timers and counters.

2.2.0(1y ago)217.9k↑23.3%1[1 issues](https://github.com/cumulati/monolog-context/issues)MITPHPPHP &gt;=8.0.0

Since Oct 30Pushed 1y agoCompare

[ Source](https://github.com/cumulati/monolog-context)[ Packagist](https://packagist.org/packages/cumulati/monolog-context)[ Docs](https://github.com/cumulati/monolog-context)[ RSS](/packages/cumulati-monolog-context/feed)WikiDiscussions master Synced 2d ago

READMEChangelogDependencies (1)Versions (14)Used By (0)

- [About](#about)
- [Create a logger](#create-a-logger)
- [Create a LogContext](#create-a-logcontext)
- [Add Context](#add-context)
- [Counters](#counters)
- [Timers](#timers)
- [Context Ids](#context-ids)
- [Levels](#levels)

About
=====

[](#about)

Easily maintain [monolog](https://github.com/Seldaek/monolog) context, timers and counters.

Installation
============

[](#installation)

You can install the package via composer:

```
composer require cumulati/monolog-context
```

Create a logger
===============

[](#create-a-logger)

```
require 'vendor/autoload.php';

use Monolog\Logger;
use Monolog\Handler\StreamHandler;
use Cumulati\Monolog\LogContext;
use Monolog\Formatter\LineFormatter;

// create a simple monolog logger
$lineFormat = '%level_name% > %message% %context% %extra%' . PHP_EOL;
$formatter = new LineFormatter($lineFormat);
$logger = new Logger('context');
$handler = new StreamHandler('php://stdout');
$handler->setFormatter($formatter);
$logger->pushHandler($handler);
$logger->info('Generic Logger');
```

```
INFO > Generic Logger [] []

```

Create a LogContext
===================

[](#create-a-logcontext)

```
$cx = new LogContext();
$cx->setLogger($logger);
$cx->info('Using manually set logger');
# Using manually set logger [] []

// Logging with the default logger
$cx = new LogContext();

// clear the default logger
LogContext::setDefaultLogger();
$cx->info('This will not log');

// set the default logger
LogContext::setDefaultLogger($logger);
$cx->info('Using the default logger');
```

```
INFO > Using manually set logger [] []
INFO > Using the default logger [] []

```

Add Context
===========

[](#add-context)

```
$cx = new LogContext(['Tyrion' => 'good']);

// log with context
$cx->info('This will log with context');

// update context
$cx->addContext(['Tyrion' => 'Lannister']);
$cx->info('This will replace context');

// override context
$cx->info('This will override context', ['Tyrion' => 'bad']);

// replace all context
$cx->setContext(['Dolores' => 'Evan Rachel Wood']);
$cx->info('This will log with replaced context');

$cx->addContext(['Bernard' => 'Jeffrey Wright']);
$cx->info('Add context');
$cx->deleteContext('Bernard');
$cx->deleteContext(['multiple', 'removes']);
$cx->info('Delete some context');

// remove all context
$cx->setContext();
$cx->info('No context added');
```

```
INFO > This will log with context {"Tyrion":"good"} []
INFO > This will replace context {"Tyrion":"Lannister"} []
INFO > This will override context {"Tyrion":"bad"} []
INFO > This will log with replaced context {"Dolores":"Evan Rachel Wood"} []
INFO > Add context {"Dolores":"Evan Rachel Wood","Bernard":"Jeffrey Wright"} []
INFO > Delete some context {"Dolores":"Evan Rachel Wood"} []
INFO > No context added [] []

```

Counters
========

[](#counters)

```
$cx = new LogContext();

$cx->addCounter('apples');
$cx->info('Log with a counter', ['_counter' => 'apples']);
$cx->info('Log with a counter', ['_counter' => 'apples']);
$cx->info('Not incrementing a counter');
// log with multiple counters, creating one on the fly
$cx->info('Log with a counter', ['_counter' => ['apples', 'bananas']]);

// get the counters
print_r($cx->getCounters());

// reset a counter
$cx->addCounter('apples');
$cx->info('Counter is reset', ['_counter' => 'apples']);

// add multiple counters
$cx->addCounter(['apples', 'bananas']);
$cx->addCounter('pears', 'grapes');

// inline counters
$cx->withCounter('universe')
	->info('With a counter');
$cx->withCounter('hello', 'world')
	->info('With multiple counters');

// set the counter key
$cx->setCounterKey('_c');
$cx->info('Using a different counter key', ['_c' => 'fruits']);

// Set the default counter key
LogContext::setDefaultKeyCounter('C');
$cx = new LogContext();
$cx->addCounter('t');
$cx->info('This has default counter key', ['C' => 't']);
```

```
INFO > Log with a counter {"_counter":{"apples":1}} []
INFO > Log with a counter {"_counter":{"apples":2}} []
INFO > Not incrementing a counter [] []
INFO > Log with a counter {"_counter":{"apples":3,"bananas":1}} []
Array
(
    [apples] => 3
    [bananas] => 1
)
INFO > Counter is reset {"_counter":{"apples":1}} []
INFO > With a counter {"_counter":{"universe":1}} []
INFO > With multiple counters {"_counter":{"hello":1,"world":1}} []
INFO > Using a different counter key {"_c":{"fruits":1}} []
INFO > This has default counter key {"C":{"t":1}} []

```

Timers
======

[](#timers)

```
$cx = new LogContext();

// create a timer
$cx->addTimer('start');

usleep(20000);
// log with the timer
$cx->info('Log with a timer', ['_timer' => 'start']);

// add multiple timers
$cx->addTimer(['go0', 'go1']);
$cx->addTimer('go2', 'go3');

usleep(10000);
// with an inline timer
$cx->withTimer('start')
->info('Log with a timer inline');

// get the counters
print_r($cx->getCounters());

// set the counter key
$cx->setTimerKey('_t');
$cx->info('Using a different timer key', ['_t' => 'start']);

// Set the default timer key
LogContext::setDefaultKeyTimer('T');
$cx = new LogContext();
$cx->addTimer('x');
usleep(10000);
$cx->info('This has default timer key', ['T' => 'x']);
```

```
INFO > Log with a timer {"_timer":{"start":0.022}} []
INFO > Log with a timer inline {"_timer":{"start":0.034}} []
INFO > Using a different timer key {"_t":{"start":0.034}} []
INFO > This has default timer key {"T":{"x":0.012}} []

```

Context Ids
===========

[](#context-ids)

```
$cx = new LogContext();
$cx->setAppendCtxId(true);
$cx->info('Add context id');
$cx->info('Which is shared with all messages through this context');

// set the ctxId key
$cx->setCtxIdKey('_');
$cx->info('Different ctx key');

// remove custom ctxIdKey
$cx->setCtxIdKey(null);

// Set default ctxId key
LogContext::setDefaultKeyCtxId('___');
$cx->info('Apple');
```

```
INFO > Add context id {"_ctx":"a554920f5edb20d1"} []
INFO > Which is shared with all messages through this context {"_ctx":"a554920f5edb20d1"} []
INFO > Different ctx key {"_":"a554920f5edb20d1"} []
INFO > Apple {"___":"73ae2580f5b59a9e"} []

```

Levels
======

[](#levels)

All levels defined in [RFC 5424](http://tools.ietf.org/html/rfc5424) are supported.

```
$cx = new LogContext();
$cx->debug('This is a debug message');
$cx->info('This is a info message');
$cx->notice('This is a notice message');
$cx->warning('This is a warning message');
$cx->error('This is a error message');
$cx->critical('This is a critical message');
$cx->alert('This is a alert message');
$cx->emergency('This is fine.');
```

```
DEBUG > This is a debug message [] []
INFO > This is a info message [] []
NOTICE > This is a notice message [] []
WARNING > This is a warning message [] []
ERROR > This is a error message [] []
CRITICAL > This is a critical message [] []
ALERT > This is a alert message [] []
EMERGENCY > This is fine. [] []

```

###  Health Score

41

—

FairBetter than 87% of packages

Maintenance39

Infrequent updates — may be unmaintained

Popularity29

Limited adoption so far

Community9

Small or concentrated contributor base

Maturity70

Established project with proven stability

 Bus Factor1

Top contributor holds 92% 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

Every ~188 days

Recently: every ~339 days

Total

12

Last Release

372d ago

Major Versions

0.1.0 → 1.0.02021-10-09

1.0.2 → 2.0.02022-07-12

### Community

Maintainers

![](https://www.gravatar.com/avatar/bb10a70207eb285de11f7afc1fb1b1e5e882a0d81dcd0fef03eb3b5a36442667?d=identicon)[pmccarren](/maintainers/pmccarren)

---

Top Contributors

[![pmccarren](https://avatars.githubusercontent.com/u/4959702?v=4)](https://github.com/pmccarren "pmccarren (23 commits)")[![travierm](https://avatars.githubusercontent.com/u/3410152?v=4)](https://github.com/travierm "travierm (2 commits)")

---

Tags

logContexttimerloggercountermonolog

### Embed Badge

![Health badge](/badges/cumulati-monolog-context/health.svg)

```
[![Health](https://phpackages.com/badges/cumulati-monolog-context/health.svg)](https://phpackages.com/packages/cumulati-monolog-context)
```

###  Alternatives

[theorchard/monolog-cascade

Monolog extension to configure multiple loggers in the blink of an eye and access them from anywhere

1482.2M9](/packages/theorchard-monolog-cascade)[inpsyde/wonolog

Monolog-based logging package for WordPress.

184637.3k7](/packages/inpsyde-wonolog)[logtail/monolog-logtail

Logtail handler for Monolog

243.6M3](/packages/logtail-monolog-logtail)[glopgar/monolog-timer-processor

A processor for Monolog that adds timing info to the message contexts

1570.6k](/packages/glopgar-monolog-timer-processor)[bitrix-expert/monolog-adapter

Monolog adapter for Bitrix CMS

6566.7k](/packages/bitrix-expert-monolog-adapter)[yzen.dev/mono-processor

This Processor will display in the logs bread crumbs by which you can more quickly and accurately identify the cause of the error.

116.1k](/packages/yzendev-mono-processor)

PHPackages © 2026

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