### Install Wiretap and Publish Migrations/Config Source: https://context7.com/nordkit/wiretap/llms.txt Install the package via Composer, then publish and run migrations to set up the database schema. Finally, publish the configuration file. ```bash composer require nordkit/wiretap php artisan vendor:publish --tag="wiretap-migrations" php artisan migrate php artisan vendor:publish --tag="wiretap-config" ``` -------------------------------- ### Install Project Dependencies Source: https://github.com/nordkit/wiretap/blob/main/CONTRIBUTING.md Run this command to install all necessary project dependencies using Composer. ```bash composer install ``` -------------------------------- ### Install Wiretap via Composer Source: https://github.com/nordkit/wiretap/blob/main/README.md Use this command to install the Wiretap package in your project. ```bash composer require nordkit/wiretap ``` -------------------------------- ### Usage examples after fix Source: https://github.com/nordkit/wiretap/blob/main/wiretap-bug-report.md Demonstrates the expected usage patterns after the macro is correctly registered. ```php Http::withTraceable($order)->acceptJson()->post($url, $payload); // or mid-chain: Http::acceptJson()->withTraceable($order)->post($url, $payload); ``` -------------------------------- ### Re-publish Migrations with Force Flag Source: https://github.com/nordkit/wiretap/blob/main/README.md If upgrading from an earlier version and you previously published migration files, use the --force flag to get the latest files before migrating. ```bash php artisan vendor:publish --tag="wiretap-migrations" --force php artisan migrate ``` -------------------------------- ### Implement Custom TraceWriter for Non-Laravel Usage Source: https://context7.com/nordkit/wiretap/llms.txt Implement the `TraceWriter` contract to handle trace storage in standalone PHP applications. This example shows a `PdoWriter` that inserts trace data into a database table. ```php use Nordkit\Wiretap\Contracts\TraceWriter; use Nordkit\Wiretap\HttpDirection; use Nordkit\Wiretap\HttpExchange; use Nordkit\Wiretap\Pipeline\TraceFilter; use Nordkit\Wiretap\Pipeline\TraceRedactor; use Nordkit\Wiretap\Wiretap; // 1. Implement custom writer class PdoWriter implements TraceWriter { public function __construct(private \PDO $pdo) {} public function write(HttpExchange $exchange): void { $stmt = $this->pdo->prepare(' INSERT INTO http_traces (direction, url, method, response_status, duration_ms, created_at) VALUES (?, ?, ?, ?, ?, NOW()) '); $stmt->execute([ $exchange->direction->value, $exchange->url, $exchange->method, $exchange->responseStatus, $exchange->durationMs, ]); } } // 2. Bootstrap Wiretap manually $filter = new TraceFilter([ 'enabled' => true, 'include_hosts' => [], 'exclude_hosts' => [], 'include_paths' => [], 'exclude_paths' => [], 'inbound_include_hosts' => [], 'inbound_exclude_hosts' => [], 'inbound_include_paths' => [], 'inbound_exclude_paths' => [], ]); $redactor = new TraceRedactor([ 'redact_string' => '[REDACTED]', 'store_request_body' => true, 'store_response_body' => true, 'max_body_bytes' => 65536, 'redact_request_headers' => ['authorization'], 'redact_response_headers' => ['set-cookie'], 'redact_body_keys' => ['password', 'token'], ]); $writer = new PdoWriter($pdo); $wiretap = new Wiretap($writer, $filter, $redactor); // 3. Use the Wiretap instance $timer = $wiretap->start(); // ... make HTTP request ... $wiretap->trace( direction: HttpDirection::Outbound, driver: 'custom', url: 'https://api.example.com/data', method: 'GET', requestHeaders: [], requestBody: null, responseStatus: 200, responseHeaders: [], responseBody: '{"data": "..."}', timer: $timer, ); ``` -------------------------------- ### Implement Custom TraceWriter Source: https://context7.com/nordkit/wiretap/llms.txt Create a custom storage backend by implementing the TraceWriter interface and binding it in a service provider. ```php use Nordkit\Wiretap\Contracts\TraceWriter; use Nordkit\Wiretap\HttpExchange; class ElasticsearchWriter implements TraceWriter { public function __construct(private \Elasticsearch\Client $client) {} public function write(HttpExchange $exchange): void { $this->client->index([ 'index' => 'http-traces-' . date('Y-m'), 'body' => [ 'direction' => $exchange->direction->value, 'driver' => $exchange->driver, 'url' => $exchange->url, 'method' => $exchange->method, 'request_headers' => $exchange->requestHeaders, 'request_body' => $exchange->requestBody, 'response_status' => $exchange->responseStatus, 'response_headers' => $exchange->responseHeaders, 'response_body' => $exchange->responseBody, 'duration_ms' => $exchange->durationMs, 'error_message' => $exchange->errorMessage, 'ip_address' => $exchange->ipAddress, 'timestamp' => now()->toIso8601String(), ], ]); } } // Register in a service provider $this->app->bind(TraceWriter::class, ElasticsearchWriter::class); ``` -------------------------------- ### Run Tests Source: https://github.com/nordkit/wiretap/blob/main/README.md Execute the project test suite. ```bash composer test ``` -------------------------------- ### Publish and Run Wiretap Migrations Source: https://github.com/nordkit/wiretap/blob/main/README.md For Laravel projects, publish the migration files and then run the migrations to set up the database schema for Wiretap. ```bash php artisan vendor:publish --tag="wiretap-migrations" php artisan migrate ``` -------------------------------- ### Implement Custom TraceWriter Interface Source: https://github.com/nordkit/wiretap/blob/main/README.md For standalone PHP applications, implement the `TraceWriter` interface to handle trace storage using custom solutions like raw PDO or Monolog. ```php use Nordkit\Wiretap\Contracts\TraceWriter; use Nordkit\Wiretap\HttpExchange; class MyPdoWriter implements TraceWriter { public function write(HttpExchange $exchange): void { // Insert $exchange data using raw PDO, e.g.: // $exchange->ipAddress — caller IP (null unless explicitly passed) } } ``` -------------------------------- ### Configure Inbound HTTP Tracing Source: https://context7.com/nordkit/wiretap/llms.txt Enable inbound HTTP tracing by setting `WIRETAP_INBOUND=true` in the `.env` file. Configure specific paths, hosts, and IP storage options in `config/wiretap.php` to control which incoming requests are traced. ```php // .env WIRETAP_INBOUND=true WIRETAP_INBOUND_STORE_IP=true // Optional: capture caller IP address // config/wiretap.php 'inbound' => [ 'laravel_http' => true, 'store_ip' => true, // Only trace webhook endpoints 'include_paths' => ['#^/webhooks#', '#^/api/callbacks#'], // Skip health checks 'exclude_paths' => ['#^/health#', '#^/ping#'], // Limit to specific subdomain 'include_hosts' => ['webhooks.myapp.com'], ], // Traces are automatically captured for all matching inbound requests: // POST /webhooks/stripe -> traced with direction='inbound' // GET /health -> skipped (excluded path) ``` -------------------------------- ### Manual Tracing with Wiretap::trace() Source: https://context7.com/nordkit/wiretap/llms.txt Record manual traces for custom HTTP clients or raw cURL requests, ensuring exceptions do not interrupt application flow. ```php use Nordkit\\Wiretap\\HttpDirection; use Nordkit\\Wiretap\\Laravel\\Facades\\Wiretap; // 1. Start the timer before the request $timer = Wiretap::start(); // 2. Perform the manual HTTP request $ch = curl_init('https://api.legacy-system.com/data'); curl_setopt_array($ch, [ CURLOPT_RETURNTRANSFER => true, CURLOPT_HTTPHEADER => ['Authorization: Bearer secret123', 'Content-Type: application/json'], CURLOPT_POST => true, CURLOPT_POSTFIELDS => json_encode(['action' => 'sync']), ]); $responseBody = curl_exec($ch); $statusCode = curl_getinfo($ch, CURLINFO_HTTP_CODE); $error = curl_error($ch) ?: null; curl_close($ch); // 3. Record the trace with the timer closure Wiretap::trace( direction: HttpDirection::Outbound, driver: 'curl', url: 'https://api.legacy-system.com/data', method: 'POST', requestHeaders: ['Authorization: Bearer secret123', 'Content-Type: application/json'], requestBody: json_encode(['action' => 'sync']), responseStatus: $statusCode ?: null, responseHeaders: [], responseBody: $responseBody ?: null, timer: $timer, // Automatically calculates duration errorMessage: $error, ); ``` -------------------------------- ### Update CHANGELOG.md comparison links Source: https://github.com/nordkit/wiretap/blob/main/RELEASING.md Format for updating the comparison links at the bottom of the changelog file. ```markdown [Unreleased]: https://github.com/nordkit/wiretap/compare/v1.3.0...HEAD [1.3.0]: https://github.com/nordkit/wiretap/compare/v1.2.0...v1.3.0 ``` -------------------------------- ### Commit and push changelog changes Source: https://github.com/nordkit/wiretap/blob/main/RELEASING.md Commands to stage, commit, and push the updated changelog to the main branch. ```bash git add CHANGELOG.md git commit -m "chore: prepare release v1.3.0" git push origin main ``` -------------------------------- ### Format Code with Laravel Pint Source: https://github.com/nordkit/wiretap/blob/main/CONTRIBUTING.md Apply code style formatting to the project using Laravel Pint. This should be run before submitting a Pull Request. ```bash vendor/bin/pint ``` -------------------------------- ### Run Project Tests Source: https://github.com/nordkit/wiretap/blob/main/CONTRIBUTING.md Execute this command to run all automated tests for the project using Pest. ```bash vendor/bin/pest ``` -------------------------------- ### TraceWriter Interface - Custom Storage Backend Source: https://context7.com/nordkit/wiretap/llms.txt Implement the `TraceWriter` interface to create custom storage backends for non-Laravel projects or specialized requirements. ```APIDOC ## TraceWriter Interface - Custom Storage Backend ### Description Implement the `TraceWriter` interface to create custom storage backends for non-Laravel projects or specialized requirements. ### Method Signature `write(HttpExchange $exchange): void` ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example ```php use Nordkit\Wiretap\Contracts\TraceWriter; use Nordkit\Wiretap\HttpExchange; class ElasticsearchWriter implements TraceWriter { public function __construct(private \Elasticsearch\Client $client) {} public function write(HttpExchange $exchange): void { $this->client->index([ 'index' => 'http-traces-' . date('Y-m'), 'body' => [ 'direction' => $exchange->direction->value, 'driver' => $exchange->driver, 'url' => $exchange->url, 'method' => $exchange->method, 'request_headers' => $exchange->requestHeaders, 'request_body' => $exchange->requestBody, 'response_status' => $exchange->responseStatus, 'response_headers' => $exchange->responseHeaders, 'response_body' => $exchange->responseBody, 'duration_ms' => $exchange->durationMs, 'error_message' => $exchange->errorMessage, 'ip_address' => $exchange->ipAddress, 'timestamp' => now()->toIso8601String(), ], ]); } } // Register in a service provider $this->app->bind(TraceWriter::class, ElasticsearchWriter::class); ``` ### Response This method does not return a value. It is responsible for writing the `HttpExchange` data to a storage backend. ``` -------------------------------- ### WiretapClient Guzzle Wrapper Source: https://context7.com/nordkit/wiretap/llms.txt Utilize the pre-wired Guzzle client for automatic tracing and polymorphic model association. ```php use Nordkit\\Wiretap\\Guzzle\\WiretapClient; class PaymentGatewayService { public function __construct(private readonly WiretapClient $http) {} public function chargeCard(Order $order, array $cardDetails): array { $response = $this->http ->withTraceable($order) ->post('https://api.stripe.com/v1/charges', [ 'json' => [ 'amount' => $order->total_cents, 'currency' => 'usd', 'source' => $cardDetails['token'], ], 'headers' => [ 'Authorization' => 'Bearer ' . config('services.stripe.secret'), ], ]); return json_decode((string) $response->getBody(), true); } } // Create with custom Guzzle config $client = WiretapClient::make(app(\\Nordkit\\Wiretap\\Wiretap::class), [ 'base_uri' => 'https://api.example.com', 'timeout' => 30, 'headers' => ['Accept' => 'application/json'], ]); $response = $client->get('/users/123'); ``` -------------------------------- ### Update CHANGELOG.md version section Source: https://github.com/nordkit/wiretap/blob/main/RELEASING.md Format for defining a new versioned section in the changelog. ```markdown ## [Unreleased] ## [1.3.0] - 2026-05-01 ### Added - ... ### Fixed - ... ``` -------------------------------- ### Workaround for TraceableScope Source: https://github.com/nordkit/wiretap/blob/main/wiretap-bug-report.md Temporary solution to push to the scope directly before executing the request. ```php app(TraceableScope::class)->push($order); Http::acceptJson()->post($url, $payload); ``` -------------------------------- ### Trace Inbound HTTP Request with IP Source: https://github.com/nordkit/wiretap/blob/main/README.md Use Wiretap::trace() to manually log inbound requests, including the caller's IP address. Ensure necessary imports are present. ```php use Nordkit\Wiretap\HttpDirection; $timer = $wiretap->start(); // ... dispatch the request through your application ... $wiretap->trace( direction: HttpDirection::Inbound, driver: 'my-framework', url: 'https://api.myapp.com' . $_SERVER['REQUEST_URI'], method: $_SERVER['REQUEST_METHOD'], requestHeaders: getallheaders(), requestBody: file_get_contents('php://input') ?: null, responseStatus: http_response_code(), responseHeaders: [], responseBody: null, timer: $timer, ipAddress: $_SERVER['REMOTE_ADDR'] ?? null, ); ``` -------------------------------- ### Enable Inbound HTTP Traffic (dotenv) Source: https://github.com/nordkit/wiretap/blob/main/README.md Enable inbound HTTP traffic tracing by setting the WIRETAP_INBOUND environment variable to true. This is disabled by default. ```dotenv WIRETAP_INBOUND=true ``` -------------------------------- ### Trace Model - Querying Stored Traces Source: https://context7.com/nordkit/wiretap/llms.txt Query the `Trace` Eloquent model directly to analyze stored HTTP traffic, debug issues, or build monitoring dashboards. ```APIDOC ## Trace Model - Querying Stored Traces ### Description Query the `Trace` Eloquent model directly to analyze stored HTTP traffic, debug issues, or build monitoring dashboards. ### Method `Trace::query()` ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example ```php use Nordkit\Wiretap\Laravel\Models\Trace; use Nordkit\Wiretap\HttpDirection; // Find all failed requests in the last hour $failedRequests = Trace::query() ->where('created_at', '>=', now()->subHour()) ->where(function ($q) { $q->whereNull('response_status') ->orWhere('response_status', '>=', 400); }) ->orderByDesc('created_at') ->get(); // Get slowest outbound API calls $slowRequests = Trace::query() ->where('direction', HttpDirection::Outbound) ->where('duration_ms', '>', 1000) ->orderByDesc('duration_ms') ->limit(10) ->get(); // Aggregate stats by endpoint $stats = Trace::query() ->selectRaw('url, COUNT(*) as count, AVG(duration_ms) as avg_duration') ->where('created_at', '>=', now()->subDay()) ->groupBy('url') ->orderByDesc('count') ->get(); // Find traces for a specific model $orderTraces = Trace::query() ->where('traceable_type', Order::class) ->where('traceable_id', $orderId) ->get(); ``` ### Response Returns an Eloquent Collection of `Trace` models matching the query criteria. ``` -------------------------------- ### Publish Wiretap Configuration Source: https://github.com/nordkit/wiretap/blob/main/README.md Publish the configuration file to customize Wiretap's behavior in your Laravel project. ```bash php artisan vendor:publish --tag="wiretap-config" ``` -------------------------------- ### Register macro on PendingRequest Source: https://github.com/nordkit/wiretap/blob/main/wiretap-bug-report.md Correct implementation by registering the macro specifically on the PendingRequest class. ```php PendingRequest::macro('withTraceable', function (object $traceable): PendingRequest { /** @var PendingRequest $this */ app(TraceableScope::class)->push($traceable); return $this; }); ``` -------------------------------- ### Capture HttpExchange Manually Source: https://context7.com/nordkit/wiretap/llms.txt Use Wiretap::capture to manually record HTTP exchanges or pass them through Http::pool options for concurrent requests. ```php use Nordkit\Wiretap\HttpDirection; use Nordkit\Wiretap\HttpExchange; use Nordkit\Wiretap\Laravel\Facades\Wiretap; // Build the exchange manually $exchange = new HttpExchange( direction: HttpDirection::Outbound, driver: 'custom-sdk', url: 'https://api.example.com/batch', method: 'POST', requestHeaders: ['Content-Type' => 'application/json', 'X-Request-ID' => 'abc123'], requestBody: '{"items": [1, 2, 3]}', responseStatus: 200, responseHeaders: ['Content-Type' => 'application/json'], responseBody: '{"processed": 3}', durationMs: 156, errorMessage: null, ipAddress: null, traceable: $order, // Optional model association ); // Capture passes through filter -> redactor -> writer pipeline Wiretap::capture($exchange); // For Http::pool() concurrent requests, build exchanges with explicit traceables Http::pool(fn (Pool $pool) => [ $pool->as('order1')->withOptions(['wiretap_exchange' => $exchange1])->get($url1), $pool->as('order2')->withOptions(['wiretap_exchange' => $exchange2])->get($url2), ]); ``` -------------------------------- ### Wiretap Database Schema SQL Source: https://github.com/nordkit/wiretap/blob/main/README.md For non-Laravel projects using the built-in database writer, execute this raw SQL to create the necessary `wiretap_traces` table. ```sql CREATE TABLE `wiretap_traces` ( `id` CHAR(26) NOT NULL, `direction` VARCHAR(10) NOT NULL, `driver` VARCHAR(20) NOT NULL, `url` TEXT NOT NULL, `method` VARCHAR(10) NOT NULL, `request_headers` JSON NULL, `request_body` LONGTEXT NULL, `response_status` INT NULL, `response_headers` JSON NULL, `response_body` LONGTEXT NULL, `duration_ms` INT UNSIGNED NOT NULL, `error_message` TEXT NULL, `ip_address` VARCHAR(45) NULL, `traceable_type` VARCHAR(255) NULL, `traceable_id` CHAR(26) NULL, `created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (`id`), INDEX `wiretap_traces_traceable_type_traceable_id_created_at_index` (`traceable_type`, `traceable_id`, `created_at`) ); ``` -------------------------------- ### Enable Inbound HTTP Traffic (PHP Config) Source: https://github.com/nordkit/wiretap/blob/main/README.md Enable inbound HTTP traffic tracing by setting 'laravel_http' to true in the Wiretap configuration. This is disabled by default. ```php 'inbound' => [ 'laravel_http' => true, ] ``` -------------------------------- ### Configure Wiretap Filtering and Redaction Source: https://context7.com/nordkit/wiretap/llms.txt This configuration file defines Wiretap's behavior for tracing and sanitizing HTTP requests. Adjust settings for enabled status, drivers, host/path filtering, body capture, header redaction, and JSON body key scrubbing. ```php // config/wiretap.php return [ 'enabled' => env('WIRETAP_ENABLED', true), 'debug' => env('WIRETAP_DEBUG', false), 'driver' => env('WIRETAP_DRIVER', 'database'), // 'database' or 'log' 'outbound' => [ 'laravel_http' => true, 'guzzle' => true, // Only trace requests to these hosts (empty = all hosts) 'include_hosts' => ['api.stripe.com', 'api.shipping.com'], // Never trace these hosts 'exclude_hosts' => ['*.internal.myapp.com', 'localhost'], // Regex patterns for path filtering 'include_paths' => [], // Empty = all paths 'exclude_paths' => ['#^/health#', '#^/metrics#'], ], 'inbound' => [ 'laravel_http' => env('WIRETAP_INBOUND', false), 'store_ip' => env('WIRETAP_INBOUND_STORE_IP', false), 'include_hosts' => [], 'exclude_hosts' => [], 'include_paths' => ['#^/webhooks#', '#^/api/callbacks#'], 'exclude_paths' => ['#^/health#'], ], // Body capture settings 'store_request_body' => true, 'store_response_body' => true, 'max_body_bytes' => 65536, // 64KB, null for unlimited // Sensitive header redaction (case-insensitive) 'redact_string' => '[REDACTED]', 'redact_request_headers' => ['authorization', 'x-api-key', 'cookie'], 'redact_response_headers' => ['set-cookie'], // JSON body key redaction (recursive, case-insensitive) 'redact_body_keys' => [ 'password', 'token', 'secret', 'api_key', 'access_token', 'refresh_token', 'card_number', 'cvv', ], // Automatic pruning 'pruning' => [ 'enabled' => env('WIRETAP_PRUNING_ENABLED', false), 'keep_days' => env('WIRETAP_PRUNING_KEEP_DAYS', 90), ], ]; ``` -------------------------------- ### Attach Route Traceable Macro Source: https://context7.com/nordkit/wiretap/llms.txt Use the traceable route macro to automatically associate incoming webhook requests with specific Eloquent models. ```php use App\\Models\\Order; use Illuminate\\Support\\Facades\\Route; // The trace will be associated with the resolved Order model Route::post('/orders/{order}/webhooks/shipping', ShippingWebhookController::class) ->traceable(Order::class); Route::post('/payments/{payment}/confirm', PaymentConfirmController::class) ->traceable(Payment::class); // In the controller, the trace is automatically linked to the model class ShippingWebhookController { public function __invoke(Order $order, Request $request) { // Process webhook... // The inbound trace is automatically associated with $order return response()->json(['status' => 'received']); } } ``` -------------------------------- ### Inject WiretapClient for Automatic Logging Source: https://github.com/nordkit/wiretap/blob/main/README.md Use the WiretapClient wrapper to automatically log requests and responses when injected into services. ```php use Nordkit\Wiretap\Guzzle\WiretapClient; class GitHubService { public function __construct(private readonly WiretapClient $http) {} public function getUser(string $username): array { $response = $this->http->get("https://api.github.com/users/{$username}"); // The request and response are automatically logged. return json_decode((string) $response->getBody(), true); } } ``` -------------------------------- ### Store Caller IP Address (dotenv) Source: https://github.com/nordkit/wiretap/blob/main/README.md Enable storing the caller's IP address by setting the WIRETAP_INBOUND_STORE_IP environment variable to true. This is disabled by default due to privacy regulations. ```dotenv WIRETAP_INBOUND_STORE_IP=true ``` -------------------------------- ### Resolve WiretapClient Manually Source: https://github.com/nordkit/wiretap/blob/main/README.md Use WiretapClient::make to pass custom Guzzle configuration options like base_uri or timeout. ```php use Nordkit\Wiretap\Guzzle\WiretapClient; use Nordkit\Wiretap\Wiretap; $client = WiretapClient::make(app(\Nordkit\Wiretap\Wiretap::class), [ 'base_uri' => 'https://api.example.com', 'timeout' => 10, ]); ``` -------------------------------- ### Access HTTP Traces from Model Source: https://github.com/nordkit/wiretap/blob/main/README.md Retrieve all associated HTTP traces for a model instance directly using the 'traces' property, which is available after using the 'HasTraces' trait. ```php $traces = $order->traces; ``` -------------------------------- ### Enable Wiretap Pruning with Custom Retention Source: https://github.com/nordkit/wiretap/blob/main/README.md Configure Wiretap to automatically prune old traces by setting environment variables for enabling pruning and specifying the number of days to keep traces. This is crucial for managing database size. ```dotenv WIRETAP_PRUNING_ENABLED=true WIRETAP_PRUNING_KEEP_DAYS=90 # default: 90 days ``` -------------------------------- ### Trace Manual HTTP Requests Source: https://github.com/nordkit/wiretap/blob/main/README.md Use the Wiretap::trace helper to manually record requests made outside of standard Guzzle or Laravel HTTP clients. The trace method is exception-safe. ```php use Nordkit\Wiretap\HttpDirection; use Nordkit\Wiretap\Laravel\Facades\Wiretap; // 1. Start the internal timer — returns a Closure that yields elapsed ms when called $timer = Wiretap::start(); // 2. Perform your manual request/interaction... $response = $customSdk->syncData(['foo' => 'bar']); // 3. Trace the execution using the timer Closure Wiretap::trace( direction: HttpDirection::Outbound, driver: 'custom-sdk', url: 'https://api.example.com/sync', method: 'POST', requestHeaders: ['Content-Type' => 'application/json'], requestBody: json_encode(['data' => 'sync-me']), responseStatus: 200, responseHeaders: ['Content-Type' => 'application/json'], responseBody: json_encode(['status' => 'success']), timer: $timer, // Automagically resolves the request duration errorMessage: null, // Populate if your manual implementation encountered an error ); ``` -------------------------------- ### Capture Inbound HTTP Exchange Directly Source: https://github.com/nordkit/wiretap/blob/main/README.md Construct an HttpExchange object directly for full control over inbound request capture, including IP address logging. This method is useful when you need to manage the exchange object explicitly. ```php use Nordkit\Wiretap\HttpExchange; use Nordkit\Wiretap\HttpDirection; $wiretap->capture(new HttpExchange( direction: HttpDirection::Inbound, driver: 'my-framework', url: $request->getUri(), method: $request->getMethod(), requestHeaders: $request->getHeaders(), requestBody: $request->getBody(), responseStatus: $response->getStatusCode(), responseHeaders: $response->getHeaders(), responseBody: $response->getBody(), durationMs: $durationMs, ipAddress: $request->getServerParam('REMOTE_ADDR'), )); ``` -------------------------------- ### WiretapMiddleware for Guzzle Source: https://context7.com/nordkit/wiretap/llms.txt Inject tracing into existing Guzzle clients or third-party SDKs by pushing the middleware onto a HandlerStack. ```php use GuzzleHttp\\Client; use GuzzleHttp\\HandlerStack; use Nordkit\\Wiretap\\Guzzle\\WiretapMiddleware; use Nordkit\\Wiretap\\Wiretap; // Add to existing HandlerStack $stack = HandlerStack::create(); $stack->push(WiretapMiddleware::make(app(Wiretap::class))); $client = new Client([ 'handler' => $stack, 'base_uri' => 'https://api.github.com', ]); // All requests through this client are now traced $response = $client->request('GET', '/repos/laravel/laravel'); $response = $client->post('/repos/owner/repo/issues', [ 'json' => ['title' => 'Bug report', 'body' => 'Description...'] ]); // Wrap a third-party SDK's client $sdkStack = $thirdPartySdk->getGuzzleClient()->getConfig('handler'); $sdkStack->push(WiretapMiddleware::make(app(Wiretap::class))); ``` -------------------------------- ### Store Caller IP Address (PHP Config) Source: https://github.com/nordkit/wiretap/blob/main/README.md Enable storing the caller's IP address by setting 'store_ip' to true in the Wiretap configuration. This is disabled by default. ```php 'inbound' => [ 'store_ip' => true, ] ``` -------------------------------- ### Query Stored Traces Source: https://context7.com/nordkit/wiretap/llms.txt Use the Trace Eloquent model to filter, aggregate, and retrieve stored HTTP traffic data. ```php use Nordkit\Wiretap\Laravel\Models\Trace; use Nordkit\Wiretap\HttpDirection; // Find all failed requests in the last hour $failedRequests = Trace::query() ->where('created_at', '>=', now()->subHour()) ->where(function ($q) { $q->whereNull('response_status') ->orWhere('response_status', '>=', 400); }) ->orderByDesc('created_at') ->get(); // Get slowest outbound API calls $slowRequests = Trace::query() ->where('direction', HttpDirection::Outbound) ->where('duration_ms', '>', 1000) ->orderByDesc('duration_ms') ->limit(10) ->get(); // Aggregate stats by endpoint $stats = Trace::query() ->selectRaw('url, COUNT(*) as count, AVG(duration_ms) as avg_duration') ->where('created_at', '>=', now()->subDay()) ->groupBy('url') ->orderByDesc('count') ->get(); // Find traces for a specific model $orderTraces = Trace::query() ->where('traceable_type', Order::class) ->where('traceable_id', $orderId) ->get(); ``` -------------------------------- ### Reproduce the TypeError Source: https://github.com/nordkit/wiretap/blob/main/wiretap-bug-report.md This call triggers the TypeError because the macro is currently bound to the Factory instance. ```php Http::withTraceable($order)->acceptJson()->post($url, $payload); ``` -------------------------------- ### Run Wiretap Pruning Manually Source: https://github.com/nordkit/wiretap/blob/main/README.md Execute the Wiretap trace pruning command manually using Artisan. You can specify a custom number of days for trace retention. ```bash php artisan wiretap:prune php artisan wiretap:prune --days=30 ``` -------------------------------- ### Filter Inbound Requests by Host (PHP Config) Source: https://github.com/nordkit/wiretap/blob/main/README.md Restrict inbound request tracing to specific hosts using 'include_hosts'. This option matches against the 'Host' header of the incoming request. ```php 'inbound' => [ 'laravel_http' => true, 'include_hosts' => ['webhooks.myapp.com'], ] ``` -------------------------------- ### Filter Inbound Requests by Path (PHP Config) Source: https://github.com/nordkit/wiretap/blob/main/README.md Limit inbound request tracing to specific paths using 'include_paths' and exclude others using 'exclude_paths'. Paths are matched using regular expressions. ```php 'inbound' => [ 'laravel_http' => true, 'include_paths' => ['#^/webhooks#'], 'exclude_paths' => ['#^/health#'], ] ``` -------------------------------- ### Attach Model to Inbound HTTP Request Trace Source: https://github.com/nordkit/wiretap/blob/main/README.md Use the '->traceable()' route macro to attach an Eloquent model to an inbound HTTP request trace. This relies on route model binding being resolved. ```php use App\Models\Order; Route::post('/orders/{order}/sync', OrderSyncController::class) ->traceable(Order::class); ``` -------------------------------- ### Attach Wiretap Middleware to Guzzle Source: https://github.com/nordkit/wiretap/blob/main/README.md Push the WiretapMiddleware into a Guzzle HandlerStack to enable logging for existing clients or third-party SDKs. ```php use GuzzleHttp\Client; use GuzzleHttp\HandlerStack; use Nordkit\Wiretap\Guzzle\WiretapMiddleware; use Nordkit\Wiretap\Wiretap; $stack = HandlerStack::create(); $stack->push(WiretapMiddleware::make(app(\Nordkit\Wiretap\Wiretap::class))); $client = new Client(['handler' => $stack]); $client->request('GET', 'https://api.github.com/repos/guzzle/guzzle'); ``` -------------------------------- ### Associate HTTP Traces with Eloquent Models Source: https://context7.com/nordkit/wiretap/llms.txt Use `Http::withTraceable()` to associate HTTP traces with specific Eloquent models, enabling querying of HTTP traffic related to a record. The trace is automatically linked to the provided model. ```php use App\Models\Order; use Illuminate\Support\Facades\Http; $order = Order::find(1); // Associate the trace with the Order model Http::withTraceable($order) ->post('https://api.shipping.com/v1/shipments', [ 'order_id' => $order->id, 'address' => $order->shipping_address, ]); // Later, retrieve all traces for this order $traces = $order->traces; // Returns Collection of Trace models $traces = $order->traces()->where('response_status', '>=', 400)->get(); ``` -------------------------------- ### Delete Traces Older Than Retention Period Source: https://context7.com/nordkit/wiretap/llms.txt This PHP code demonstrates how to programmatically delete traces older than a specified number of days, equivalent to running the `wiretap:prune --days=30` command. ```php // The command deletes traces older than the configured retention use Nordkit\Wiretap\Laravel\Models\Trace; // Equivalent to running: php artisan wiretap:prune --days=30 Trace::where('created_at', '<=', now()->subDays(30))->delete(); ``` -------------------------------- ### Wiretap::capture() - Direct HttpExchange Capture Source: https://context7.com/nordkit/wiretap/llms.txt Capture a pre-built HttpExchange object directly for full control over all trace properties. This method is useful for concurrent requests or complex scenarios. ```APIDOC ## Wiretap::capture() - Direct HttpExchange Capture ### Description Capture a pre-built `HttpExchange` object directly for full control over all trace properties. Useful for concurrent requests or complex scenarios. ### Method `Wiretap::capture(HttpExchange $exchange)` ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example ```php use Nordkit\Wiretap\HttpDirection; use Nordkit\Wiretap\HttpExchange; use Nordkit\Wiretap\Laravel\Facades\Wiretap; // Build the exchange manually $exchange = new HttpExchange( direction: HttpDirection::Outbound, driver: 'custom-sdk', url: 'https://api.example.com/batch', method: 'POST', requestHeaders: ['Content-Type' => 'application/json', 'X-Request-ID' => 'abc123'], requestBody: '{"items": [1, 2, 3]}', responseStatus: 200, responseHeaders: ['Content-Type' => 'application/json'], responseBody: '{"processed": 3}', durationMs: 156, errorMessage: null, ipAddress: null, traceable: $order, // Optional model association ); // Capture passes through filter -> redactor -> writer pipeline Wiretap::capture($exchange); // For Http::pool() concurrent requests, build exchanges with explicit traceables Http::pool(fn (Pool $pool) => [ $pool->as('order1')->withOptions(['wiretap_exchange' => $exchange1])->get($url1), $pool->as('order2')->withOptions(['wiretap_exchange' => $exchange2])->get($url2), ]); ``` ### Response This method does not return a value. It processes the `HttpExchange` through the Wiretap pipeline. ``` -------------------------------- ### Automatic Laravel HTTP Client Integration Source: https://github.com/nordkit/wiretap/blob/main/README.md Wiretap automatically integrates with Laravel's HTTP Client. Outbound requests made via `Http::get()`, `Http::post()`, etc., are automatically traced and stored without additional configuration. ```php use Illuminate\Support\Facades\Http; $response = Http::withHeaders(['X-First' => 'foo']) ->get('https://api.github.com/users/octocat'); // The request and response are now automatically stored in the database. ``` -------------------------------- ### Associate Requests with Eloquent Models Source: https://github.com/nordkit/wiretap/blob/main/README.md Use withTraceable to link a request to an Eloquent model. Note that the traceable state is reset after the request is dispatched. ```php $response = $this->http ->withTraceable($order) ->post('https://api.example.com/orders/sync', ['json' => $order->toArray()]); ``` -------------------------------- ### Attach Model to Outbound HTTP Request Source: https://github.com/nordkit/wiretap/blob/main/README.md Use the 'withTraceable()' macro to attach an Eloquent model to an outgoing HTTP request. Note: This is designed for sequential requests and may not work as expected with Http::pool() due to concurrent requests. ```php use Illuminate\Support\Facades\Http; $order = Order::find(1); Http::withTraceable($order) ->post('https://api.example.com/orders/sync', $order->toArray()); ``` -------------------------------- ### Trace Laravel HTTP Client Requests Source: https://context7.com/nordkit/wiretap/llms.txt Wiretap automatically captures all Laravel HTTP Client requests, including headers, body, status code, and timing, without requiring explicit configuration. ```php use Illuminate\Support\Facades\Http; // Basic request - automatically traced $response = Http::withHeaders(['X-Custom-Header' => 'value']) ->get('https://api.github.com/users/octocat'); // The request/response is now stored in the wiretap_traces table: // - url: https://api.github.com/users/octocat // - method: GET // - request_headers: {"X-Custom-Header": "value", ...} // - response_status: 200 // - response_body: {"login": "octocat", ...} // - duration_ms: 234 ``` -------------------------------- ### Eloquent Model with HasTraces Trait Source: https://github.com/nordkit/wiretap/blob/main/README.md Include the 'HasTraces' trait in your Eloquent model to easily access associated HTTP traces via the 'traces' relationship. ```php use Illuminate\Database\Eloquent\Model; use Nordkit\Wiretap\Laravel\Concerns\HasTraces; class Order extends Model { use HasTraces; } ``` -------------------------------- ### Implement HasTraces Trait for Model Relationship Source: https://context7.com/nordkit/wiretap/llms.txt Add the `HasTraces` trait to an Eloquent model to automatically provide a polymorphic relationship for retrieving associated HTTP traces. This allows easy querying of traces directly from the model instance. ```php use Illuminate\Database\Eloquent\Model; use Nordkit\Wiretap\Laravel\Concerns\HasTraces; class Order extends Model { use HasTraces; // The trait adds: public function traces(): MorphMany } // Query traces from the model $order = Order::find(1); // Get all traces $allTraces = $order->traces; // Get failed requests only $failedTraces = $order->traces() ->whereNull('response_status') ->orWhere('response_status', '>=', 400) ->get(); // Get recent outbound API calls $recentCalls = $order->traces() ->where('direction', 'outbound') ->where('created_at', '>=', now()->subHour()) ->orderByDesc('created_at') ->get(); ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.