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

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

solophp/logger
==============

PSR-3 compatible logger implementation

v1.0.0(2mo ago)0751MITPHPPHP &gt;=8.1

Since Apr 19Pushed 2mo ago1 watchersCompare

[ Source](https://github.com/SoloPHP/Logger)[ Packagist](https://packagist.org/packages/solophp/logger)[ RSS](/packages/solophp-logger/feed)WikiDiscussions main Synced today

READMEChangelog (1)Dependencies (11)Versions (4)Used By (1)

Solo PSR-3 Logger
=================

[](#solo-psr-3-logger)

[![Latest Version on Packagist](https://camo.githubusercontent.com/439ef5503956de39980d3684b9b9c98340643744731ea82afeac7494f4c93704/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f736f6c6f7068702f6c6f676765722e737667)](https://packagist.org/packages/solophp/logger)[![License](https://camo.githubusercontent.com/3cc39e6378985c813181da4d5d642be42ff2ce63cbad67d3b38201da481a024c/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f6c2f736f6c6f7068702f6c6f676765722e737667)](https://github.com/solophp/logger/blob/main/LICENSE)[![PHP Version](https://camo.githubusercontent.com/86756fc76870990540989eb6f5278f31c39a1fbb6cec65257112731a71c168b8/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f7068702d762f736f6c6f7068702f6c6f676765722e737667)](https://packagist.org/packages/solophp/logger)[![Test Coverage](https://camo.githubusercontent.com/b3545ae1bcdb4ea486f71f87b43001e82dd21933bc8035d44601706c851265da/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f636f7665726167652d3130302532352d627269676874677265656e2e737667)](#development)

A lightweight PSR-3 compliant logger with timezone-aware log rotation, pluggable formatters (line / JSON / logfmt), context interpolation and safe, lock-based file writes.

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

[](#installation)

Install via composer:

```
composer require solophp/logger
```

Usage
-----

[](#usage)

Basic usage:

```
use Psr\Log\LogLevel;
use Solo\Logger\Logger;

// Initialize logger
$logger = new Logger('/path/to/log/file.log');

// Log messages
$logger->info('Application started');
$logger->error('Failed to charge user {user_id}', ['user_id' => 42, 'error_code' => 500]);

// Only WARNING and above will be written
$logger->setMinLevel(LogLevel::WARNING);
```

With custom timezone for rotation file timestamps:

```
$logger = new Logger('/path/to/log/file.log', 'America/New_York');
```

Change log file or rotation timezone at runtime:

```
$logger->setLogFile('/path/to/another/file.log');
$logger->setTimezone('Asia/Tokyo');
```

Features
--------

[](#features)

- PSR-3 `LoggerInterface` compliance (`psr/log` ^3.0)
- Pluggable formatters: **Line**, **JSON (NDJSON)**, **Logfmt** — or your own via `FormatterInterface`
- Context interpolation for PSR-3 `{placeholder}` tokens
- Log rotation with **size**, **time**, or **combined** strategies
- Timezone-aware rotation timestamps
- Retention via `maxFiles` — oldest rotated files are auto-pruned
- Minimum level filtering via `setMinLevel()`
- Automatic log directory creation
- Safe append-with-lock writes (`LOCK_EX`)
- Throws `RuntimeException` on write/directory-create failures instead of silent drop
- Modular architecture with a clear separation of concerns

Requirements
------------

[](#requirements)

- PHP 8.1 or higher
- psr/log package

Log Levels
----------

[](#log-levels)

The logger supports all PSR-3 log levels:

- emergency
- alert
- critical
- error
- warning
- notice
- info
- debug

Log Rotation
------------

[](#log-rotation)

The logger supports automatic log rotation with multiple strategies to prevent disk overflow and simplify log management.

### Rotation Strategies

[](#rotation-strategies)

#### Size-based rotation

[](#size-based-rotation)

Rotates logs when the file reaches a specified size limit:

```
// Rotate when file reaches 1MB, keep maximum 5 files
$logger = new Logger('app.log', '', 1024 * 1024, 5, 'size');
```

#### Time-based rotation

[](#time-based-rotation)

Rotates logs at specified time intervals:

```
// Rotate every 6 hours, keep maximum 10 files
$logger = new Logger('app.log', '', 0, 10, 'time', 6 * 3600);
```

#### Combined rotation

[](#combined-rotation)

Rotates logs when either size OR time condition is met:

```
// Rotate when file reaches 2MB OR every 12 hours, keep maximum 7 files
$logger = new Logger('app.log', '', 2 * 1024 * 1024, 7, 'both', 12 * 3600);
```

### Runtime Configuration

[](#runtime-configuration)

You can change rotation settings at runtime:

```
$logger->setMaxFileSize(1024 * 1024); // 1MB
$logger->setMaxFiles(10);
$logger->setRotationStrategy('both');
$logger->setRotationInterval(3600); // 1 hour
// Record WARNING and higher only
$logger->setMinLevel(LogLevel::WARNING);
```

### File Naming

[](#file-naming)

When rotation occurs, files are created with timestamps:

```
original_name_YYYY-MM-DD_HH-MM-SS.ext

```

Examples:

- `app_2025-08-03_14-30-15.log`
- `error_2025-08-03_09-45-30.log`

### Best Practices

[](#best-practices)

- **Size limits**: Set reasonable limits (1-10MB) to prevent disk overflow
- **File count**: Limit the number of files to save space
- **Time intervals**: Use standard intervals (1 hour, 6 hours, 1 day)
- **Monitoring**: Regularly check log directory size
- **Archiving**: Consider archiving old logs for long-term storage

### Examples

[](#examples)

#### Daily rotation with 30-day retention

[](#daily-rotation-with-30-day-retention)

```
$logger = new Logger('logs/daily.log', '', 0, 30, 'time', 86400);
```

#### Size-based with 50MB total limit

[](#size-based-with-50mb-total-limit)

```
$logger = new Logger('logs/large.log', '', 5 * 1024 * 1024, 10, 'size');
```

#### Combined strategy for high-traffic applications

[](#combined-strategy-for-high-traffic-applications)

```
$logger = new Logger(
    'logs/combined.log',
    '',
    2 * 1024 * 1024,  // 2MB limit
    20,                 // 20 files max
    'both',             // both size and time
    6 * 3600           // 6 hours
);
```

Formatters
----------

[](#formatters)

Every log record is rendered by a `FormatterInterface` implementation. The default is `LineFormatter`; pass a different one via the constructor or `setFormatter()` at runtime.

```
use Solo\Logger\Formatter\JsonFormatter;
use Solo\Logger\Formatter\LineFormatter;
use Solo\Logger\Formatter\LogfmtFormatter;
use Solo\Logger\Logger;

// Via constructor (last argument)
$logger = new Logger('app.log', '', 0, 0, 'size', 86400, new JsonFormatter());

// Or swap at runtime
$logger->setFormatter(new LogfmtFormatter());
```

### LineFormatter (default)

[](#lineformatter-default)

Plain text with a configurable template and PSR-3 `{placeholder}` interpolation.

```
[2026-04-19T10:15:30+00:00] INFO: User 42 logged in

```

```
// Defaults: template = "[{time}] {level}: {message}", date format = DateTimeInterface::ATOM
$formatter = new LineFormatter(
    template: '{time} [{level}] {message}',
    dateFormat: 'Y-m-d H:i:s',
);
```

Template tokens: `{time}`, `{level}`, `{message}`. Context keys referenced inside the message (e.g. `"User {user_id}"`) are resolved against the `$context` array.

### JsonFormatter

[](#jsonformatter)

Single-line JSON (NDJSON) — fits ELK / Loki / Graylog / Datadog pipelines. Context keys are merged into the top-level record; reserved keys (`time`, `level`, `message`) are namespaced under `context` to avoid collisions. `\Throwable`, `\DateTimeInterface` and `\Stringable` objects are normalised.

```
{"time":"2026-04-19T10:15:30+00:00","level":"info","message":"Job queued","id":3}
```

### LogfmtFormatter

[](#logfmtformatter)

Heroku/Splunk-style `key=value` pairs. Values with whitespace or quotes are escaped.

```
time=2026-04-19T10:15:30+00:00 level=info message="Job queued" id=3

```

### Writing a custom formatter

[](#writing-a-custom-formatter)

Implement `Solo\Logger\Formatter\FormatterInterface` — a single `format()` method. The returned string MUST NOT include a trailing newline (the Logger appends one).

```
use Solo\Logger\Formatter\FormatterInterface;

final class MyFormatter implements FormatterInterface
{
    public function format(string $level, string|\Stringable $message, array $context, \DateTimeInterface $time): string
    {
        return sprintf('%s %s %s', $time->format('c'), strtoupper($level), $message);
    }
}
```

Error Handling
--------------

[](#error-handling)

If writing a log record fails (unwritable path, full disk, unable to create directory), the logger throws `\RuntimeException` rather than silently dropping the record. Wrap calls in a `try/catch` if your application must tolerate log-sink failures.

Development
-----------

[](#development)

```
# Install dependencies
composer install

# Run the full suite: PSR-12 + PHPStan L8 + PHPUnit
composer check

# Individual commands
composer test          # PHPUnit
composer test-coverage # PHPUnit + HTML coverage report
composer analyze       # PHPStan
composer cs            # PSR-12 style check
composer cs-fix        # PSR-12 auto-fix
```

License
-------

[](#license)

MIT License. See LICENSE file for details.

###  Health Score

39

—

LowBetter than 84% of packages

Maintenance85

Actively maintained with recent releases

Popularity9

Limited adoption so far

Community9

Small or concentrated contributor base

Maturity45

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

Every ~96 days

Total

3

Last Release

76d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/2f29817cec408d033cd4441c8f760e3ae40248dc0f66856a09080d282aee6959?d=identicon)[Vitaliy Olos](/maintainers/Vitaliy%20Olos)

---

Top Contributors

[![SoloPHP](https://avatars.githubusercontent.com/u/175482616?v=4)](https://github.com/SoloPHP "SoloPHP (9 commits)")

---

Tags

psr-3phplogger

###  Code Quality

TestsPHPUnit

Static AnalysisPHPStan

Code StylePHP\_CodeSniffer

Type Coverage Yes

### Embed Badge

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

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

PHPackages © 2026

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