mirror of
https://github.com/ivuorinen/monolog-gdpr-filter.git
synced 2026-01-26 03:34:00 +00:00
* fix(style): resolve PHPCS line-length warnings in source files * fix(style): resolve PHPCS line-length warnings in test files * feat(audit): add structured audit logging with ErrorContext and AuditContext - ErrorContext: standardized error information with sensitive data sanitization - AuditContext: structured context for audit entries with operation types - StructuredAuditLogger: enhanced audit logger wrapper with timing support * feat(recovery): add recovery mechanism for failed masking operations - FailureMode enum: FAIL_OPEN, FAIL_CLOSED, FAIL_SAFE modes - RecoveryStrategy interface and RecoveryResult value object - RetryStrategy: exponential backoff with configurable attempts - FallbackMaskStrategy: type-aware fallback values * feat(strategies): add CallbackMaskingStrategy for custom masking logic - Wraps custom callbacks as MaskingStrategy implementations - Factory methods: constant(), hash(), partial() for common use cases - Supports exact match and prefix match for field paths * docs: add framework integration guides and examples - symfony-integration.md: Symfony service configuration and Monolog setup - psr3-decorator.md: PSR-3 logger decorator pattern implementation - framework-examples.md: CakePHP, CodeIgniter 4, Laminas, Yii2, PSR-15 - docker-development.md: Docker development environment guide * chore(docker): add Docker development environment - Dockerfile: PHP 8.2-cli-alpine with Xdebug for coverage - docker-compose.yml: development services with volume mounts * feat(demo): add interactive GDPR pattern tester playground - PatternTester.php: pattern testing utility with strategy support - index.php: web API endpoint with JSON response handling - playground.html: interactive web interface for testing patterns * docs(todo): update with completed medium priority items - Mark all PHPCS warnings as fixed (81 → 0) - Document new Audit and Recovery features - Update test count to 1,068 tests with 2,953 assertions - Move remaining items to low priority * feat: add advanced architecture, documentation, and coverage improvements - Add architecture improvements: - ArrayAccessorInterface and DotArrayAccessor for decoupled array access - MaskingOrchestrator for single-responsibility masking coordination - GdprProcessorBuilder for fluent configuration - MaskingPluginInterface and AbstractMaskingPlugin for plugin architecture - PluginAwareProcessor for plugin hook execution - AuditLoggerFactory for instance-based audit logger creation - Add advanced features: - SerializedDataProcessor for handling print_r/var_export/serialize output - KAnonymizer with GeneralizationStrategy for GDPR k-anonymity - RetentionPolicy for configurable data retention periods - StreamingProcessor for memory-efficient large log processing - Add comprehensive documentation: - docs/performance-tuning.md - benchmarking, optimization, caching - docs/troubleshooting.md - common issues and solutions - docs/logging-integrations.md - ELK, Graylog, Datadog, etc. - docs/plugin-development.md - complete plugin development guide - Improve test coverage (84.41% → 85.07%): - ConditionalRuleFactoryInstanceTest (100% coverage) - GdprProcessorBuilderEdgeCasesTest (100% coverage) - StrategyEdgeCasesTest for ReDoS detection and type parsing - 78 new tests, 119 new assertions - Update TODO.md with current statistics: - 141 PHP files, 1,346 tests, 85.07% line coverage * chore: tests, update actions, sonarcloud issues * chore: rector * fix: more sonarcloud fixes * chore: more fixes * refactor: copilot review fix * chore: rector
175 lines
6.4 KiB
PHP
175 lines
6.4 KiB
PHP
<?php
|
|
|
|
/**
|
|
* Rate Limiting for Audit Logging Examples
|
|
*
|
|
* This file demonstrates how to use rate limiting to prevent
|
|
* audit log flooding while maintaining system performance.
|
|
*/
|
|
|
|
declare(strict_types=1);
|
|
|
|
require_once __DIR__ . '/../vendor/autoload.php';
|
|
|
|
use Ivuorinen\MonologGdprFilter\GdprProcessor;
|
|
use Ivuorinen\MonologGdprFilter\RateLimitedAuditLogger;
|
|
use Monolog\Logger;
|
|
use Monolog\LogRecord;
|
|
use Monolog\Handler\StreamHandler;
|
|
use Monolog\Level;
|
|
|
|
// Example 1: Basic Rate-Limited Audit Logging
|
|
echo "=== Example 1: Basic Rate-Limited Audit Logging ===\n";
|
|
|
|
$auditLogs = [];
|
|
$baseAuditLogger = function (string $path, mixed $original, mixed $masked) use (&$auditLogs): void {
|
|
$auditLogs[] = [
|
|
'timestamp' => date('Y-m-d H:i:s'),
|
|
'path' => $path,
|
|
'original' => $original,
|
|
'masked' => $masked
|
|
];
|
|
echo sprintf('AUDIT: %s - %s -> %s%s', $path, $original, $masked, PHP_EOL);
|
|
};
|
|
|
|
// Wrap with rate limiting (100 per minute by default)
|
|
$rateLimitedLogger = new RateLimitedAuditLogger($baseAuditLogger, 5, 60); // 5 per minute for demo
|
|
|
|
$processor = new GdprProcessor(
|
|
['/\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,}\b/' => '***EMAIL***'],
|
|
['user.email' => 'masked@example.com'],
|
|
[],
|
|
$rateLimitedLogger
|
|
);
|
|
|
|
$logger = new Logger('rate-limited');
|
|
$logger->pushHandler(new StreamHandler('php://stdout', Level::Debug));
|
|
$logger->pushProcessor($processor);
|
|
|
|
// Simulate high-volume logging that would exceed rate limits
|
|
for ($i = 0; $i < 10; $i++) {
|
|
$logger->info('User activity', [
|
|
'user' => ['email' => sprintf('user%d@example.com', $i)],
|
|
'action' => 'login'
|
|
]);
|
|
}
|
|
|
|
echo "\nTotal audit logs: " . count($auditLogs) . "\n";
|
|
echo "Expected: 5 regular logs + rate limit warnings\n\n";
|
|
|
|
// Example 2: Using Predefined Rate Limiting Profiles
|
|
echo "=== Example 2: Rate Limiting Profiles ===\n";
|
|
|
|
$auditLogs2 = [];
|
|
/** @psalm-suppress DeprecatedMethod - Example demonstrates deprecated factory method */
|
|
$baseLogger2 = GdprProcessor::createArrayAuditLogger($auditLogs2, false);
|
|
|
|
// Available profiles: 'strict', 'default', 'relaxed', 'testing'
|
|
$strictLogger = RateLimitedAuditLogger::create($baseLogger2, 'strict'); // 50/min
|
|
$relaxedLogger = RateLimitedAuditLogger::create($baseLogger2, 'relaxed'); // 200/min
|
|
$testingLogger = RateLimitedAuditLogger::create($baseLogger2, 'testing'); // 1000/min
|
|
|
|
echo "Strict profile: " . ($strictLogger->isOperationAllowed('general_operations')
|
|
? 'Available' : 'Rate limited') . "\n";
|
|
echo "Relaxed profile: " . ($relaxedLogger->isOperationAllowed('general_operations')
|
|
? 'Available' : 'Rate limited') . "\n";
|
|
echo "Testing profile: " . ($testingLogger->isOperationAllowed('general_operations')
|
|
? 'Available' : 'Rate limited') . "\n\n";
|
|
|
|
// Example 3: Using GdprProcessor Helper Methods
|
|
echo "=== Example 3: GdprProcessor Helper Methods ===\n";
|
|
|
|
$auditLogs3 = [];
|
|
// Create rate-limited logger using GdprProcessor helper
|
|
/** @psalm-suppress DeprecatedMethod - Example demonstrates deprecated factory methods */
|
|
$rateLimitedAuditLogger = GdprProcessor::createRateLimitedAuditLogger(
|
|
GdprProcessor::createArrayAuditLogger($auditLogs3, false),
|
|
'default'
|
|
);
|
|
|
|
$processor3 = new GdprProcessor(
|
|
['/\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,}\b/' => '***EMAIL***'],
|
|
['sensitive_data' => '***REDACTED***'],
|
|
[],
|
|
$rateLimitedAuditLogger
|
|
);
|
|
|
|
// Process some logs
|
|
for ($i = 0; $i < 3; $i++) {
|
|
$logRecord = new LogRecord(
|
|
new DateTimeImmutable(),
|
|
'app',
|
|
Level::Info,
|
|
sprintf('Processing user%d@example.com', $i),
|
|
['sensitive_data' => 'secret_value_' . $i]
|
|
);
|
|
|
|
$result = $processor3($logRecord);
|
|
echo "Processed: " . $result->message . "\n";
|
|
}
|
|
|
|
echo "Audit logs generated: " . count($auditLogs3) . "\n\n";
|
|
|
|
// Example 4: Rate Limit Statistics and Monitoring
|
|
echo "=== Example 4: Rate Limit Statistics ===\n";
|
|
|
|
$rateLimitedLogger4 = new RateLimitedAuditLogger($baseAuditLogger, 10, 60);
|
|
|
|
// Generate some activity
|
|
for ($i = 0; $i < 5; $i++) {
|
|
$rateLimitedLogger4('test_operation', 'value_' . $i, 'masked_' . $i);
|
|
}
|
|
|
|
// Check statistics
|
|
$stats = $rateLimitedLogger4->getRateLimitStats();
|
|
echo "Rate Limit Statistics:\n";
|
|
foreach ($stats as $operationType => $stat) {
|
|
if ($stat['current_requests'] > 0) {
|
|
echo " {$operationType}:\n";
|
|
echo sprintf(' Current requests: %d%s', $stat['current_requests'], PHP_EOL);
|
|
echo sprintf(' Remaining requests: %d%s', $stat['remaining_requests'], PHP_EOL);
|
|
echo " Time until reset: {$stat['time_until_reset']} seconds\n";
|
|
}
|
|
}
|
|
|
|
echo "\n";
|
|
|
|
// Example 5: Different Operation Types
|
|
echo "=== Example 5: Operation Type Classification ===\n";
|
|
|
|
$rateLimitedLogger5 = new RateLimitedAuditLogger($baseAuditLogger, 2, 60); // Very restrictive
|
|
|
|
echo "Testing different operation types (2 per minute limit):\n";
|
|
|
|
// These will be classified into different operation types
|
|
$rateLimitedLogger5('json_masked', '{"key": "value"}', '{"key": "***MASKED***"}');
|
|
$rateLimitedLogger5('conditional_skip', 'skip_reason', 'Level not matched');
|
|
$rateLimitedLogger5('regex_error', '/invalid[/', 'Pattern compilation failed');
|
|
$rateLimitedLogger5('preg_replace_error', 'input', 'PCRE error occurred');
|
|
|
|
// Try to exceed limits for each type
|
|
echo "\nTesting rate limiting per operation type:\n";
|
|
$rateLimitedLogger5('json_encode_error', 'data', 'JSON encoding failed'); // json_operations
|
|
$rateLimitedLogger5('json_decode_error', 'data', 'JSON decoding failed'); // json_operations (should be limited)
|
|
$rateLimitedLogger5('conditional_error', 'rule', 'Rule evaluation failed'); // conditional_operations
|
|
$rateLimitedLogger5('regex_validation', 'pattern', 'Pattern is invalid'); // regex_operations
|
|
|
|
echo "\nOperation type stats:\n";
|
|
$stats5 = $rateLimitedLogger5->getRateLimitStats();
|
|
foreach ($stats5 as $type => $stat) {
|
|
if ($stat['current_requests'] > 0) {
|
|
$current = $stat['current_requests'];
|
|
$all = $stat['current_requests'] + $stat['remaining_requests'];
|
|
echo " {$type}: {$current}/{$all} used\n";
|
|
}
|
|
}
|
|
|
|
echo "\n=== Rate Limiting Examples Completed ===\n";
|
|
echo "\nKey Benefits:\n";
|
|
echo "• Prevents audit log flooding during high-volume operations\n";
|
|
echo "• Maintains system performance by limiting resource usage\n";
|
|
echo "• Provides configurable rate limits for different environments\n";
|
|
echo "• Separate rate limits for different operation types\n";
|
|
echo "• Built-in statistics and monitoring capabilities\n";
|
|
echo "• Graceful degradation with rate limit warnings\n";
|