PHP code example of kirschbaum-development / monitor

1. Go to this page and download the library: Download kirschbaum-development/monitor library. Choose the download type require.

2. Extract the ZIP file and open the index.php.

3. Add this code to the index.php.
    
        
<?php
require_once('vendor/autoload.php');

/* Start to develop here. Best regards https://php-download.com/ */

    

kirschbaum-development / monitor example snippets


use Kirschbaum\Monitor\Facades\Monitor;

// In App\Http\Controllers\Api\UserController
class UserController extends Controller
{
    public function login(LoginRequest $request)
    {
        // Automatic origin resolution from full namespace
        Monitor::log($this)->info('User login attempt', [
            'email' => $request->email,
            'ip' => $request->ip()
        ]);
    }
}

// In App\Services\Payment\StripePaymentService  
class StripePaymentService
{
    public function processPayment($amount)
    {
        // Origin automatically resolved to clean, readable format
        Monitor::log($this)->info('Processing payment', [
            'amount' => $amount,
            'processor' => 'stripe'
        ]);
    }
}

// config/monitor.php
'origin_path_replacers' => [
    'App\\' => 'Monitor\\',                  // Default: Replace App\ with Monitor\
    // 'App\\Http\\Controllers\\' => '',     // Example: Remove controller namespace
    // 'App\\Services\\Payment\\' => 'Pay\\', // Example: Shorten payment services
    // 'App\\Services\\' => 'Svc\\',         // Example: General service shortening
],
'origin_separator' => ':',           // App\Http\Controllers\Api\UserController → Monitor:Http:Controllers:Api:UserController  
'origin_path_wrapper' => 'square',   // Monitor:Http:Controllers:Api:UserController → [Monitor:Http:Controllers:Api:UserController]

use Kirschbaum\Monitor\Facades\Monitor;

// Create and execute controlled block
$result = Monitor::controlled('payment_processing', $this)
    ->run(function() {
        return processPayment($data);
    });

/*
 * Adds additional context to the structured logger.
 */
Monitor::controlled('payment_processing', $this)
    ->addContext([
        'transaction_id' => 'txn_456',
        'gateway' => 'stripe'
    ]);

/*
 * Will completely replace structured logger context.
 * ⚠️ Not recommended unless you have a good reason to do so.
 */
Monitor::controlled('payment_processing', $this)
    ->overrideContext([
        'user_id' => 123,
        'operation' => 'payment',
        'amount' => 99.99
    ]);

Monitor::controlled('payment_processing', $this)
    ->catching([
        DatabaseException::class => function($exception, $meta) {
            $cachedData = ExampleModel::getCachedData();
            return $cachedData; // Recovery value
        },
        NetworkException::class => function($exception, $meta) {
            $this->exampleRetryLater($meta);
            // No return = just handle, don't recover
        },
        PaymentException::class => function($exception, $meta) {
            $this->exampleNotifyFinanceTeam($exception, $meta);
            throw $exception; // Re-throw if needed
        },
        // Other exception types remain uncaught.
    ])

Monitor::controlled('payment_processing', $this)
    ->onUncaughtException(function($exception, $meta) {
        // Example actions, the exception will remain uncaught
        $this->alertOpsTeam($exception, $meta);
        $this->sendToErrorTracking($exception);
    })

Monitor::controlled('payment_processing', $this)
    ->withCircuitBreaker('payment_gateway', 3, 60) // 3 failures, 60s timeout
    ->withDatabaseTransaction(2, [DeadlockException::class], [ValidationException::class])

// bootstrap/app.php or register as route middleware
->withMiddleware(function (Middleware $middleware) {
    $middleware->alias([
        'circuit' => \Kirschbaum\Monitor\Http\Middleware\CheckCircuitBreakers::class,
    ]);
})

// In your routes
Route::middleware(['circuit:payment_gateway,external_api'])
    ->group(function () {
        Route::post('/payments', [PaymentController::class, 'store']);
        Route::get('/external-data', [DataController::class, 'fetch']);
    });

// Or on individual routes
Route::get('/api/data')
    ->middleware('circuit:slow_service')
    ->name('data.fetch');

Monitor::controlled('payment_processing', $this)
    ->overrideTraceId('custom-trace-12345')
    // Origin is automatically set from the second parameter ($this)

class PaymentService
{
    public function processPayment($amount, $userId)
    {
        return Monitor::controlled('payment_processing', $this)
            ->addContext([
                'user_id' => $userId,
                'amount' => $amount,
                'currency' => 'USD'
            ])
            ->withCircuitBreaker('payment_gateway', 3, 120)
            ->withDatabaseTransaction(1, [DeadlockException::class])
            ->catching([
                PaymentDeclinedException::class => function($e, $meta) {
                    return ['status' => 'declined', 'reason' => $e->getMessage()];
                },
                InsufficientFundsException::class => function($e, $meta) {
                    return ['status' => 'insufficient_funds'];
                }
            ])
            ->onUncaughtException(fn($e, $meta) => SomeEscalationLogic::run($e, $meta))
            ->run(function() use ($amount) {
                return $this->chargeCard($amount);
            });
    }
}

use Kirschbaum\Monitor\Facades\Monitor;

class OrderController extends Controller
{
    public function store()
    {
        // Start trace (typically via middleware)
        Monitor::trace()->start();
        
        Monitor::log($this)->info('Processing order');
        
        // All subsequent operations share the same trace ID
        $this->paymentService->charge($amount);
        
        // Queue job with trace context
        ProcessOrderJob::dispatch($order);
    }
}

class PaymentService
{
    public function charge($amount)
    {
        // Automatically 

// Manual control
Monitor::trace()->start();            // Generate new UUID (throws if already started)
Monitor::trace()->override($traceId); // Use specific ID (overwrites existing)
Monitor::trace()->pickup($traceId);   // Start if not started, optionally with specific ID
Monitor::trace()->id();               // Get current ID (throws if not started)
Monitor::trace()->hasStarted();       // Check if active
Monitor::trace()->hasNotStarted();    // Check if not active

// bootstrap/app.php
->withMiddleware(function (Middleware $middleware) {
    $middleware->append(\Kirschbaum\Monitor\Http\Middleware\StartMonitorTrace::class);
})

// Service A
$response = Http::withHeaders([
    'X-Trace-Id' => Monitor::trace()->id()
])->get('https://service-b.example.com/api/data');

// Service B automatically uses the same trace ID

use Kirschbaum\Monitor\Facades\Monitor;

class DataProcessor
{
    public function processData()
    {
        $timer = Monitor::time(); // Auto-starts
        
        // Your processing code
        $this->heavyOperation();
        
        $elapsed = $timer->elapsed(); // Milliseconds
        
        Monitor::log($this)->info('Processing complete', [
            'duration_ms' => $elapsed
        ]);
    }
}

use Kirschbaum\Monitor\Facades\Monitor;

// Check circuit breaker state
$isOpen = Monitor::breaker()->isOpen('payment_gateway');
$state = Monitor::breaker()->getState('payment_gateway');

// Manual state management
Monitor::breaker()->recordFailure('api_service', 300); // Record failure with 300s decay
Monitor::breaker()->recordSuccess('api_service');      // Record success (resets failures)
Monitor::breaker()->reset('api_service');              // Force reset
Monitor::breaker()->forceOpen('api_service');          // Force open state

class ExternalApiService
{
    public function makeRequest()
    {
        if (Monitor::breaker()->isOpen('external_api')) {
            return $this->getCachedResponse();
        }
        
        try {
            $response = $this->performApiCall();
            Monitor::breaker()->recordSuccess('external_api');
            return $response;
        } catch (Exception $e) {
            Monitor::breaker()->recordFailure('external_api', 120);
            throw $e;
        }
    }
}

use Kirschbaum\Monitor\Facades\Monitor;

// Direct redaction using configured profile
$redactedData = Monitor::redactor()->redact($sensitiveData);

// Custom profile redaction
$redactedData = Monitor::redactor()->redact($sensitiveData, 'strict');

// Example usage
class UserDataProcessor
{
    public function processUserData(array $userData)
    {
        // Redact before logging or storing
        $safeData = Monitor::redactor()->redact($userData);
        
        Monitor::log($this)->info('Processing user data', $safeData);
        
        return $this->process($userData); // Use original for processing
    }
}

'redactor' => [
    'enabled' => true,
    'redactor_profile' => 'default', // Uses Kirschbaum Redactor profiles
],

Monitor::log($this)->info('User data', [
    'id' => 123,
    'email' => '[email protected]',    // → '[REDACTED]' based on profile rules
    'password' => 'secret123',        // → '[REDACTED]' based on profile rules
    'api_token' => 'sk-1234567890abcdef...', // → '[REDACTED]' based on profile rules
    'name' => 'John Doe',             // → 'John Doe' (if allowed by profile)
]);

use Kirschbaum\Monitor\Facades\Monitor;

// Structured logging
Monitor::log($origin)->info('message', $context);

// Controlled execution blocks
Monitor::controlled($name, $origin)->run($callback);

// Distributed tracing
Monitor::trace()->start();
Monitor::trace()->pickup($traceId);

// Performance timing
Monitor::time()->elapsed();

// Circuit breaker management
Monitor::breaker()->isOpen($name);

// Log redaction
Monitor::redactor()->redact($data);

// config/logging.php
'channels' => [
    'monitor' => [
        'driver' => 'daily',
        'path' => storage_path('logs/monitor.log'),
        'level' => 'debug',
        'days' => 14,
        'tap' => [
            \Kirschbaum\Monitor\Taps\StructuredLoggingTap::class,
        ],
    ],
],
bash
php artisan vendor:publish --tag="monitor-config"