Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Shadow Logger Bundle Laravel Package

aubes/shadow-logger-bundle

Symfony bundle adding a Monolog processor to transform/anonymize sensitive log data for GDPR compliance. Supports IP anonymization, hashing, encryption, and field removal via configurable mappings for context/extra, with strict and debug modes.

View on GitHub
Deep Wiki
Context7

Getting Started

  1. Installation:

    composer require aubes/shadow-logger-bundle
    
  2. Publish Configuration:

    php artisan vendor:publish --tag=shadow-logger
    

    This creates config/packages/shadow_logger.yaml.

  3. Basic Setup: Configure the bundle in config/packages/shadow_logger.yaml to target specific handlers/channels (e.g., handlers: ['app']). Define field mappings for anonymization (e.g., user_ip: ['ip']).

  4. First Use Case: Log a request with sensitive data:

    $logger = $this->container->get('logger');
    $logger->info('User action', [
        'user_ip' => $request->ip(),
        'user_name' => $user->name,
    ]);
    

    The user_ip and user_name fields will be anonymized based on your configuration.


Implementation Patterns

1. Field-Specific Anonymization

  • IP Anonymization:
    shadow_logger:
        mapping:
            context:
                user_ip: ['ip']  # Replaces with anonymized IP (e.g., 192.0.2.0/24)
    
  • Hashing Sensitive Data:
    shadow_logger:
        mapping:
            context:
                user_email: ['hash']  # One-way hash with salt
    
  • Removing PII:
    shadow_logger:
        mapping:
            extra:
                credit_card: ['remove']  # Replaced with `--obfuscated--`
    

2. Chaining Transformers

Combine multiple transformations for complex fields:

shadow_logger:
    mapping:
        context:
            user_token: ['string', 'hash']  # Ensure Stringable objects are hashed
            user_birthdate: ['truncate']    # Mask dates (e.g., "1990-01-**")

3. Encryption for Reversible Anonymization

Use encryption when you need to recover original values (e.g., for GDPR requests):

shadow_logger:
    encryptor:
        key: '%env(SHADOW_LOGGER_ENCRYPTOR_KEY)%'
    mapping:
        context:
            user_password_hash: ['encrypt']  # Stored as `['iv' => '...', 'value' => '...']`

4. Nested Field Handling

Target nested arrays using dot notation:

shadow_logger:
    mapping:
        extra:
            user.address.city: ['remove']  # Removes nested `city` field
            user.metadata.token: ['hash']   # Hashes nested `token`

5. Debugging in Development

Enable debug mode to log transformer errors:

shadow_logger:
    debug: '%kernel.debug%'  # Only active in dev
    strict: true             # Set field to `null` on transformer errors

6. Custom Transformers

Extend functionality by creating a custom transformer:

// app/Transformer/CustomTransformer.php
namespace App\Transformer;

use Aubes\ShadowLoggerBundle\Transformer\TransformerInterface;

class CustomTransformer implements TransformerInterface {
    public function transform(mixed $data): mixed {
        return strtoupper($data); // Example: uppercase all strings
    }
}

Register it in config/services.yaml:

services:
    App\Transformer\CustomTransformer:
        tags:
            - { name: 'shadow_logger.transformer', alias: 'uppercase' }

Use it in config:

shadow_logger:
    mapping:
        context:
            user_name: ['uppercase']

Gotchas and Tips

1. Performance Considerations

  • Avoid Global Application: Scope the ShadowProcessor to specific handlers/channels (e.g., handlers: ['app']) to minimize overhead.
  • Nested Fields: Dot notation uses PropertyAccessor, which is slower than direct key access. Prefer flat field names where possible.

2. Configuration Quirks

  • Strict Mode: When strict: true, transformer errors set the field to null. Set to false to preserve original values.
  • Debug Mode: Only enable debug: true in development to avoid logging sensitive errors in production.
  • Salt Management: Store the encoder.salt in .env and rotate it periodically (requires re-hashing all existing logs).

3. Encryption Pitfalls

  • Key Rotation: Rotating encryption keys breaks decryption of old logs. Plan key rotation carefully.
  • IV Exposure: Encrypted fields include the IV, which may reveal data presence (e.g., non-empty fields). Use remove for truly sensitive metadata.
  • Base64 Decoding: Always validate encrypted data before decryption (e.g., check for malformed base64 in v1.3.1+).

4. Debugging Tips

  • Check Logs: Enable debug: true to log transformer errors in development.
  • Inspect Output: Verify anonymized logs by inspecting the context/extra arrays in Monolog handlers.
  • Test Edge Cases: Test with empty strings, nested arrays, and non-string values (e.g., Stringable objects).

5. GDPR Compliance

  • Right to Access: Use encrypt for reversible anonymization to fulfill GDPR requests.
  • Right to Erasure: Combine remove or hash with log retention policies to delete or pseudonymize data.
  • Correlation: Hashing the same input always produces the same output, enabling user activity correlation without storing PII.

6. Extending the Bundle

  • Custom Encryptors: Implement EncryptorInterface for algorithm-specific needs (e.g., AES-GCM).
  • Transformer Aliases: Register custom transformers with unique aliases to avoid conflicts.
  • Event Listeners: Listen for monolog.logger events to log or audit anonymization actions.

7. Common Errors

  • Transformer Not Found: Ensure custom transformers are tagged with shadow_logger.transformer and have a unique alias.
  • Circular References: Avoid mapping nested fields that reference each other (e.g., user.data.user).
  • Non-Scalar Values: Transformers expect scalar values. Use string first to cast objects (e.g., ['string', 'hash']).
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
calmfox/watch-sylius
damienfern/grpc-symfony-bundle
atoolo/index-bundle
atoolo/genai-bundle
coprotoai/laravel-ticket
davidjln/llm-carbon-bundle
cryonighter/valid-request-bundle
coolms/taxonomy-bundle
coolms/field-bundle
articulate-orm/symfony
aaix/laravel-tall-architect
ephoto/akeneo-connector
emmanuelballery/eb-plantumlbundle
emielburgman/symfony-visitor-beacon
emielburgman/symfony-visit-storage
emielburgman/symfony-security-headers
emielburgman/symfony-log-viewer
emarref/xdebug-bundle
emarref/pubnub-bundle
elriseio/finance-money-bundle