PHPackages                             ivuorinen/monolog-gdpr-filter - 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. ivuorinen/monolog-gdpr-filter

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

ivuorinen/monolog-gdpr-filter
=============================

Monolog processor for GDPR masking with regex and dot-notation paths

1.0.0(9mo ago)126[1 issues](https://github.com/ivuorinen/monolog-gdpr-filter/issues)[4 PRs](https://github.com/ivuorinen/monolog-gdpr-filter/pulls)MITPHPPHP ^8.2CI passing

Since Jul 28Pushed 1mo agoCompare

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

READMEChangelog (1)Dependencies (10)Versions (12)Used By (0)

Monolog GDPR Filter
===================

[](#monolog-gdpr-filter)

A PHP library providing a Monolog processor for GDPR compliance. Mask, remove, or replace sensitive data in logs using regex patterns, field-level configuration, custom callbacks, and advanced features like streaming, rate limiting, and k-anonymity.

Features
--------

[](#features)

### Core Masking

[](#core-masking)

- **Regex-based masking** for patterns like SSNs, credit cards, emails, IPs, and more
- **Field-level masking** using dot-notation paths with flexible configuration
- **Custom callbacks** for advanced per-field masking logic
- **Data type masking** to mask values based on their PHP type
- **Serialized data support** for JSON, print\_r, var\_export, and serialize formats

### Enterprise Features

[](#enterprise-features)

- **Fluent builder API** for readable processor configuration
- **Streaming processor** for memory-efficient large file processing
- **Rate-limited audit logging** to prevent log flooding
- **Plugin system** for extensible pre/post-processing hooks
- **K-anonymity support** for statistical privacy guarantees
- **Retry and recovery** with configurable failure modes
- **Conditional masking** based on log level, channel, or context

### Framework Integration

[](#framework-integration)

- **Monolog 3.x compatible** with ProcessorInterface implementation
- **Laravel integration** with service provider, middleware, and console commands
- **Audit logging** for compliance tracking and debugging

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

[](#requirements)

- PHP 8.4 or higher
- Monolog 3.x

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

[](#installation)

```
composer require ivuorinen/monolog-gdpr-filter
```

Quick Start
-----------

[](#quick-start)

```
use Monolog\Logger;
use Monolog\Handler\StreamHandler;
use Monolog\Level;
use Ivuorinen\MonologGdprFilter\GdprProcessor;
use Ivuorinen\MonologGdprFilter\FieldMaskConfig;

// Create processor with default GDPR patterns
$processor = new GdprProcessor(
    patterns: GdprProcessor::getDefaultPatterns(),
    fieldPaths: [
        'user.email' => FieldMaskConfig::remove(),
        'user.ssn' => FieldMaskConfig::replace('[REDACTED]'),
    ]
);

// Integrate with Monolog
$logger = new Logger('app');
$logger->pushHandler(new StreamHandler('app.log', Level::Warning));
$logger->pushProcessor($processor);

// Sensitive data is automatically masked
$logger->warning('User login', [
    'user' => [
        'email' => 'john@example.com',  // Will be removed
        'ssn' => '123-45-6789',         // Will be replaced with [REDACTED]
    ]
]);
```

Core Concepts
-------------

[](#core-concepts)

### Regex Patterns

[](#regex-patterns)

Define regex patterns to mask sensitive data in log messages and context values:

```
$patterns = [
    '/\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,}\b/' => '***EMAIL***',
    '/\b\d{3}-\d{2}-\d{4}\b/' => '***SSN***',
    '/\b\d{4}[\s-]?\d{4}[\s-]?\d{4}[\s-]?\d{4}\b/' => '***CARD***',
];

$processor = new GdprProcessor(patterns: $patterns);
```

Use `GdprProcessor::getDefaultPatterns()` for a comprehensive set of pre-configured patterns covering SSNs, credit cards, emails, phone numbers, IBANs, IP addresses, and more.

### Field Path Masking (FieldMaskConfig)

[](#field-path-masking-fieldmaskconfig)

Configure masking for specific fields using dot-notation paths:

```
use Ivuorinen\MonologGdprFilter\FieldMaskConfig;

$fieldPaths = [
    // Remove field entirely from logs
    'user.password' => FieldMaskConfig::remove(),

    // Replace with static value
    'payment.card_number' => FieldMaskConfig::replace('[CARD]'),

    // Apply processor's regex patterns to this field
    'user.bio' => FieldMaskConfig::useProcessorPatterns(),

    // Apply custom regex pattern
    'user.phone' => FieldMaskConfig::regexMask('/\d{3}-\d{4}/', '***-****'),
];
```

### Custom Callbacks

[](#custom-callbacks)

Provide custom masking functions for complex scenarios:

```
$customCallbacks = [
    'user.name' => fn($value) => strtoupper(substr($value, 0, 1)) . '***',
    'user.id' => fn($value) => hash('sha256', (string) $value),
];

$processor = new GdprProcessor(
    patterns: [],
    fieldPaths: [],
    customCallbacks: $customCallbacks
);
```

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

[](#basic-usage)

### Direct GdprProcessor Usage

[](#direct-gdprprocessor-usage)

```
use Ivuorinen\MonologGdprFilter\GdprProcessor;
use Ivuorinen\MonologGdprFilter\FieldMaskConfig;

$processor = new GdprProcessor(
    patterns: GdprProcessor::getDefaultPatterns(),
    fieldPaths: [
        'user.ssn' => FieldMaskConfig::remove(),
        'payment.card' => FieldMaskConfig::replace('[REDACTED]'),
        'contact.email' => FieldMaskConfig::useProcessorPatterns(),
    ],
    customCallbacks: [
        'user.name' => fn($v) => strtoupper($v),
    ],
    auditLogger: function($path, $original, $masked) {
        // Log masking operations for compliance
        error_log("Masked: $path");
    },
    maxDepth: 100,
);
```

### Using GdprProcessorBuilder (Recommended)

[](#using-gdprprocessorbuilder-recommended)

The builder provides a fluent, readable API:

```
use Ivuorinen\MonologGdprFilter\Builder\GdprProcessorBuilder;
use Ivuorinen\MonologGdprFilter\FieldMaskConfig;

$processor = GdprProcessorBuilder::create()
    ->withDefaultPatterns()
    ->addPattern('/custom-secret-\w+/', '[SECRET]')
    ->addFieldPath('user.email', FieldMaskConfig::remove())
    ->addFieldPath('user.ssn', FieldMaskConfig::replace('[SSN]'))
    ->addCallback('user.id', fn($v) => hash('sha256', (string) $v))
    ->withMaxDepth(50)
    ->withAuditLogger(function($path, $original, $masked) {
        // Audit logging
    })
    ->build();
```

Advanced Features
-----------------

[](#advanced-features)

### Conditional Masking

[](#conditional-masking)

Apply masking only when specific conditions are met:

```
use Ivuorinen\MonologGdprFilter\ConditionalRuleFactory;
use Monolog\Level;

$processor = new GdprProcessor(
    patterns: GdprProcessor::getDefaultPatterns(),
    conditionalRules: [
        // Only mask error-level logs
        'error_only' => ConditionalRuleFactory::createLevelBasedRule([Level::Error]),

        // Only mask specific channels
        'app_channel' => ConditionalRuleFactory::createChannelBasedRule(['app', 'security']),

        // Custom condition
        'has_user' => fn($record) => isset($record->context['user']),
    ]
);
```

### Data Type Masking

[](#data-type-masking)

Mask values based on their PHP type:

```
use Ivuorinen\MonologGdprFilter\MaskConstants;

$processor = new GdprProcessor(
    patterns: [],
    dataTypeMasks: [
        'integer' => MaskConstants::MASK_INT,
        'double' => MaskConstants::MASK_FLOAT,
        'boolean' => MaskConstants::MASK_BOOL,
    ]
);
```

### Rate-Limited Audit Logging

[](#rate-limited-audit-logging)

Prevent audit log flooding in high-volume applications:

```
use Ivuorinen\MonologGdprFilter\RateLimitedAuditLogger;

$baseLogger = function($path, $original, $masked) {
    // Your audit logging logic
};

// Create rate-limited wrapper (100 logs per minute)
$rateLimitedLogger = new RateLimitedAuditLogger($baseLogger, 100, 60);

$processor = new GdprProcessor(
    patterns: GdprProcessor::getDefaultPatterns(),
    auditLogger: $rateLimitedLogger
);

// Available rate limit profiles via factory
$strictLogger = RateLimitedAuditLogger::create($baseLogger, 'strict');   // 50/min
$defaultLogger = RateLimitedAuditLogger::create($baseLogger, 'default'); // 100/min
$relaxedLogger = RateLimitedAuditLogger::create($baseLogger, 'relaxed'); // 200/min
```

### Streaming Large Files

[](#streaming-large-files)

Process large log files with memory-efficient streaming:

```
use Ivuorinen\MonologGdprFilter\Streaming\StreamingProcessor;
use Ivuorinen\MonologGdprFilter\MaskingOrchestrator;

$orchestrator = new MaskingOrchestrator(GdprProcessor::getDefaultPatterns());
$streaming = new StreamingProcessor($orchestrator, chunkSize: 1000);

// Process file line by line
$lineParser = fn(string $line) => ['message' => $line, 'context' => []];

foreach ($streaming->processFile('large-app.log', $lineParser) as $maskedRecord) {
    // Write to output file or process further
    fwrite($output, $maskedRecord['message'] . "\n");
}

// Or process to file directly
$formatter = fn(array $record) => json_encode($record);
$count = $streaming->processToFile($records, 'masked-output.log', $formatter);
```

Laravel Integration
-------------------

[](#laravel-integration)

### Service Provider

[](#service-provider)

```
// app/Providers/AppServiceProvider.php
namespace App\Providers;

use Illuminate\Support\ServiceProvider;
use Ivuorinen\MonologGdprFilter\GdprProcessor;
use Ivuorinen\MonologGdprFilter\FieldMaskConfig;

class AppServiceProvider extends ServiceProvider
{
    public function boot(): void
    {
        $processor = new GdprProcessor(
            patterns: GdprProcessor::getDefaultPatterns(),
            fieldPaths: [
                'user.email' => FieldMaskConfig::remove(),
                'user.password' => FieldMaskConfig::remove(),
            ]
        );

        $this->app['log']->getLogger()->pushProcessor($processor);
    }
}
```

### Tap Class

[](#tap-class)

```
// app/Logging/GdprTap.php
namespace App\Logging;

use Monolog\Logger;
use Ivuorinen\MonologGdprFilter\GdprProcessor;
use Ivuorinen\MonologGdprFilter\FieldMaskConfig;

class GdprTap
{
    public function __invoke(Logger $logger): void
    {
        $processor = new GdprProcessor(
            patterns: GdprProcessor::getDefaultPatterns(),
            fieldPaths: [
                'user.email' => FieldMaskConfig::remove(),
                'payment.card' => FieldMaskConfig::replace('[CARD]'),
            ]
        );

        $logger->pushProcessor($processor);
    }
}
```

Reference in `config/logging.php`:

```
'channels' => [
    'single' => [
        'driver' => 'single',
        'path' => storage_path('logs/laravel.log'),
        'level' => 'debug',
        'tap' => [App\Logging\GdprTap::class],
    ],
],
```

### Console Commands

[](#console-commands)

The library provides Artisan commands for testing and debugging:

```
# Test a pattern against sample data
php artisan gdpr:test-pattern '/\b\d{3}-\d{2}-\d{4}\b/' 'SSN: 123-45-6789'

# Debug current GDPR configuration
php artisan gdpr:debug
```

Plugin System
-------------

[](#plugin-system)

Extend the processor with custom pre/post-processing hooks:

```
use Ivuorinen\MonologGdprFilter\Contracts\MaskingPluginInterface;
use Ivuorinen\MonologGdprFilter\Builder\GdprProcessorBuilder;

class CustomPlugin implements MaskingPluginInterface
{
    public function getName(): string
    {
        return 'custom-plugin';
    }

    public function getPriority(): int
    {
        return 10; // Lower = earlier execution
    }

    public function preProcessMessage(string $message): string
    {
        // Modify message before masking
        return $message;
    }

    public function postProcessMessage(string $message): string
    {
        // Modify message after masking
        return $message;
    }

    public function preProcessContext(array $context): array
    {
        return $context;
    }

    public function postProcessContext(array $context): array
    {
        return $context;
    }
}

$processor = GdprProcessorBuilder::create()
    ->withDefaultPatterns()
    ->addPlugin(new CustomPlugin())
    ->buildWithPlugins();
```

Default Patterns Reference
--------------------------

[](#default-patterns-reference)

`GdprProcessor::getDefaultPatterns()` includes patterns for:

CategoryData TypesPersonal IDsFinnish SSN (HETU), US SSN, Passport numbers, National IDsFinancialCredit cards, IBAN, Bank account numbersContactEmail addresses, Phone numbers (E.164)TechnicalIPv4/IPv6 addresses, MAC addresses, API keys, Bearer tokensHealthMedicare numbers, European Health Insurance Card (EHIC)DatesBirth dates in multiple formatsPerformance Considerations
--------------------------

[](#performance-considerations)

### Pattern Optimization

[](#pattern-optimization)

Order patterns from most specific to most general:

```
// Recommended: specific patterns first
$patterns = [
    '/\b\d{3}-\d{2}-\d{4}\b/' => '***SSN***',     // Specific format
    '/\b\d+\b/' => '***NUMBER***',                // Generic fallback
];
```

### Memory-Efficient Processing

[](#memory-efficient-processing)

For large datasets:

- Use `StreamingProcessor` for file-based processing
- Configure appropriate `maxDepth` to limit recursion
- Use rate-limited audit logging to prevent memory growth

### Pattern Caching

[](#pattern-caching)

Patterns are validated and cached internally. For high-throughput applications, the library automatically caches compiled patterns.

Troubleshooting
---------------

[](#troubleshooting)

### Pattern Not Matching

[](#pattern-not-matching)

```
// Test pattern in isolation
$pattern = '/your-pattern/';
if (preg_match($pattern, $testString)) {
    echo 'Pattern matches';
}

// Validate pattern safety
try {
    GdprProcessor::validatePatternsArray([
        '/your-pattern/' => '***MASKED***'
    ]);
} catch (PatternValidationException $e) {
    echo 'Invalid pattern: ' . $e->getMessage();
}
```

### Performance Issues

[](#performance-issues)

- Reduce pattern count to essential patterns only
- Use field-specific masking instead of broad regex patterns
- Profile with audit logging to identify slow operations

### Audit Logger Issues

[](#audit-logger-issues)

```
// Safe audit logging (never log original sensitive data)
$auditLogger = function($path, $original, $masked) {
    error_log(sprintf(
        'GDPR Audit: %s - type=%s, masked=%s',
        $path,
        gettype($original),
        $original !== $masked ? 'yes' : 'no'
    ));
};
```

Testing and Quality
-------------------

[](#testing-and-quality)

```
# Run tests
composer test

# Run tests with coverage report
composer test:coverage

# Run all linters
composer lint

# Auto-fix code style issues
composer lint:fix
```

Security
--------

[](#security)

- All patterns are validated for safety before use to prevent regex injection attacks
- The library includes ReDoS (Regular Expression Denial of Service) protection
- Dangerous patterns with recursive structures or excessive backtracking are rejected

For security vulnerabilities, please see [SECURITY.md](SECURITY.md) for responsible disclosure guidelines.

Legal Disclaimer
----------------

[](#legal-disclaimer)

This library helps mask and filter sensitive data for GDPR compliance, but it is your responsibility to ensure your application fully complies with all applicable legal requirements. This tool is provided as-is without warranty. Review your logging and data handling policies regularly with legal counsel.

Contributing
------------

[](#contributing)

Contributions are welcome. Please read [CONTRIBUTING.md](CONTRIBUTING.md) for development setup and guidelines.

License
-------

[](#license)

This project is licensed under the MIT License. See the [LICENSE](LICENSE) file for details.

###  Health Score

35

—

LowBetter than 80% of packages

Maintenance57

Moderate activity, may be stable

Popularity8

Limited adoption so far

Community9

Small or concentrated contributor base

Maturity55

Maturing project, gaining track record

 Bus Factor1

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

288d ago

### Community

Maintainers

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

---

Top Contributors

[![renovate[bot]](https://avatars.githubusercontent.com/in/2740?v=4)](https://github.com/renovate[bot] "renovate[bot] (73 commits)")[![ivuorinen](https://avatars.githubusercontent.com/u/11024?v=4)](https://github.com/ivuorinen "ivuorinen (19 commits)")[![dependabot[bot]](https://avatars.githubusercontent.com/in/29110?v=4)](https://github.com/dependabot[bot] "dependabot[bot] (1 commits)")

---

Tags

gdprgdpr-compliancelaravelloggingmonolog-processor

###  Code Quality

TestsPHPUnit

Static AnalysisPsalm, Rector

Code StylePHP\_CodeSniffer

Type Coverage Yes

### Embed Badge

![Health badge](/badges/ivuorinen-monolog-gdpr-filter/health.svg)

```
[![Health](https://phpackages.com/badges/ivuorinen-monolog-gdpr-filter/health.svg)](https://phpackages.com/packages/ivuorinen-monolog-gdpr-filter)
```

###  Alternatives

[symfony/monolog-bridge

Provides integration for Monolog with various Symfony components

2.6k189.7M258](/packages/symfony-monolog-bridge)[rollbar/rollbar

Monitors errors and exceptions and reports them to Rollbar

33723.7M82](/packages/rollbar-rollbar)[illuminate/log

The Illuminate Log package.

6224.3M518](/packages/illuminate-log)[honeybadger-io/honeybadger-php

Honeybadger PHP library

381.5M4](/packages/honeybadger-io-honeybadger-php)[graycore/magento2-stdlogging

A Magento 2 module that changes all logging handlers to stdout

2382.6k](/packages/graycore-magento2-stdlogging)

PHPackages © 2026

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