### Install Excimer via apt-get Source: https://docs.sentry.io/platforms/php/guides/laravel/profiling Install the Excimer PHP extension using the apt-get package manager on Linux. ```bash apt-get install php-excimer ``` -------------------------------- ### Build Excimer from Source Source: https://docs.sentry.io/platforms/php/guides/laravel/profiling Clone the Excimer repository, compile it from source, and install the extension. ```bash git clone https://github.com/wikimedia/mediawiki-php-excimer.git cd excimer/ phpize && ./configure && make && sudo make install ``` -------------------------------- ### Install Excimer via PECL Source: https://docs.sentry.io/platforms/php/guides/laravel/profiling Install the Excimer PHP extension using PECL, a package manager for PHP extensions. ```bash pecl install excimer ``` -------------------------------- ### Basic SDK Fingerprinting Example Source: https://docs.sentry.io/platforms/php/guides/laravel/usage/sdk-fingerprinting Use this to set a static fingerprint for exceptions. Ensure the Sentry SDK is initialized and exceptions are captured within a scope. ```php try { // Run code that possibly throws an exception } catch (\Throwable $e) { \Sentry\withScope(function (\Sentry\State\Scope $scope) use ($e) { $scope->setFingerprint(['example-exception-group']); \Sentry\captureException($e); }); } ``` -------------------------------- ### Debug Output Example Source: https://docs.sentry.io/platforms/php/guides/laravel/troubleshooting Example of the log output generated by Sentry's debug logger, showing integration status, transaction details, and sending results. ```bash sentry/sentry: [debug] The "Sentry\Integration\ExceptionListenerIntegration, Sentry\Integration\ErrorListenerIntegration, Sentry\Integration\FatalErrorListenerIntegration, Sentry\Integration\RequestIntegration, Sentry\Integration\TransactionIntegration, Sentry\Integration\FrameContextifierIntegration, Sentry\Integration\EnvironmentIntegration, Sentry\Integration\ModulesIntegration" integration(s) have been installed. sentry/sentry: [info] Transaction [e2919a7b0f954478b6994c7282b060de] was started and sampled, decided by config:traces_sample_rate. sentry/sentry: [info] Transaction [e2919a7b0f954478b6994c7282b060de] started profiling because it was sampled. sentry/sentry: [info] Sending transaction [59390dc9dd934c0290d8cdc7a589da82] to o1.ingest.sentry.io [project:1]. sentry/sentry: [warning] The profile does not contain enough samples, the profile will be discarded. sentry/sentry: [info] Sent transaction [59390dc9dd934c0290d8cdc7a589da82] to o1.ingest.sentry.io [project:1]. Result: "success" (status: 200). ``` -------------------------------- ### Install Sentry Laravel Package Source: https://docs.sentry.io/platforms/php/guides/laravel Install the official Sentry SDK for Laravel using Composer. This is the first step to integrating Sentry with your application. ```bash composer require sentry/sentry-laravel ``` -------------------------------- ### Sample Transaction Events Uniformly Source: https://docs.sentry.io/platforms/php/guides/laravel/configuration/sampling Set the 'traces_sample_rate' option to a value between 0 and 1 to send a uniform percentage of transactions. For example, 0.2 sends approximately 20% of transactions. ```php 'traces_sample_rate' => 0.2, ``` -------------------------------- ### Emit a Distribution Metric Source: https://docs.sentry.io/platforms/php/guides/laravel/metrics Use distributions to gain insights from data aggregations like p90, min, max, and avg. This example adds a page load time of 15.0 milliseconds to a distribution. ```php use \Sentry\Metrics\Unit; // Add '15.0' to a distribution used for tracking the loading times per page. \Sentry\traceMetrics()->distribution('page-load', 15.0, ['page' => '/home'], Unit::millisecond()); ``` -------------------------------- ### Implement Check-In Event Filtering Logic Source: https://docs.sentry.io/platforms/php/guides/laravel/configuration/filtering Implement the `beforeSendCheckIn` callback to define custom logic for filtering check-in events. This example discards check-ins not from the 'production' environment. ```php class Sentry { public static function beforeSendCheckIn(\Sentry\Event $event): ?\Sentry\Event { $checkIn = $event->getCheckIn(); $checkInEnvironment = $checkIn->getEnvironment(); if ($checkInEnvironment !== 'production') { return null; } return $event; } } ``` -------------------------------- ### Start and Finish Transaction and Spans Source: https://docs.sentry.io/platforms/php/guides/laravel/tracing/instrumentation/custom-instrumentation Manually create, start, and finish a transaction and its child spans to capture custom performance data. Ensure the current span is managed correctly throughout the process. ```php // Setup context for the full transaction $transactionContext = \Sentry\Tracing\TransactionContext::make() ->setName('Example Transaction') ->setOp('http.server'); // Start the transaction $transaction = \Sentry\startTransaction($transactionContext); // Set the current transaction as the current span so we can retrieve it later \Sentry\SentrySdk::getCurrentHub()->setSpan($transaction); // Setup the context for the expensive operation span $spanContext = \Sentry\Tracing\SpanContext::make() ->setOp('expensive_operation'); // Start the span $span1 = $transaction->startChild($spanContext); // Set the current span to the span we just started \Sentry\SentrySdk::getCurrentHub()->setSpan($span1); // Calling expensive_operation() expensive_operation(); // Finish the span $span1->finish(); // Set the current span back to the transaction since we just finished the previous span \Sentry\SentrySdk::getCurrentHub()->setSpan($transaction); // Finish the transaction, this submits the transaction and it's span to Sentry $transaction->finish(); ``` -------------------------------- ### Emit a Counter Metric Source: https://docs.sentry.io/platforms/php/guides/laravel/metrics Use this to count occurrences of specific events. This example records five button clicks with associated browser and app version attributes. ```php // Record five total button clicks \Sentry\traceMetrics()->count('button-click', 5, ['browser' => 'Firefox', 'app_version' => '1.0.0']); ``` -------------------------------- ### Emit a Gauge Metric Source: https://docs.sentry.io/platforms/php/guides/laravel/metrics Gauges are suitable for aggregates like min, max, avg, sum, and count when percentiles are not important. This example adds a page load time of 15.0 milliseconds to a gauge. ```php use \Sentry\Metrics\Unit; // Add '15.0' to a gauge used for tracking the loading times per page. \Sentry\traceMetrics()->gauge('page-load', 15.0, ['page' => '/home'], Unit::millisecond()); ``` -------------------------------- ### Customize Integrations with a Callable Source: https://docs.sentry.io/platforms/php/guides/laravel/integrations Use a callable for the `integrations` option to dynamically modify the list of enabled Sentry integrations. This example removes the `ExceptionListenerIntegration`. ```php \Sentry\init([ 'dsn' => 'https://@o.ingest.sentry.io/', 'integrations' => static function (array $integrations) { $integrations = array_filter($integrations, static function (\Sentry\Integration\IntegrationInterface $integration) { // Check if the integration if an instance of the exception listener and return false to remove it from the array if ($integration instanceof \Sentry\Integration\ExceptionListenerIntegration) { return false; } return true; }); return $integrations; }, ]); ``` -------------------------------- ### Group Errors With Greater Granularity Source: https://docs.sentry.io/platforms/php/guides/laravel/usage/sdk-fingerprinting This example demonstrates how to create more granular fingerprints by including dynamic values from the exception object, such as function name and status code. This is useful when dealing with external service calls where the stack trace might be similar but the request details differ. ```php class MyRpcException extends \Exception { private string $functionName; private int $statusCode; /** * For example the name of the RPC function that was called (e.g. "getAllBlogArticles"). */ public function getFunctionName(): string { return $this->functionName; } /** * For example a HTTP status code returned by the server. */ public function getStatusCode(): int { return $this->statusCode; } } try { // Run code that for example throws a MyRpcException } catch (MyRpcException $e) { \Sentry\withScope(function (\Sentry\State\Scope $scope) use ($e) { $scope->setFingerprint([ '{{ default }}', $e->getFunctionName(), $e->getStatusCode(), ]); \Sentry\captureException($e); }); } ``` -------------------------------- ### Add Custom Sampling Context Data Source: https://docs.sentry.io/platforms/php/guides/laravel/configuration/sampling Pass custom data to the `SamplingContext` when starting a transaction using `Sentry\startTransaction`. This data is accessible to the sampler but not attached to the transaction's tags or data. ```php \Sentry\startTransaction( new \Sentry\Tracing\TransactionContext( $name = 'Search from navbar', $parentSampled = false ), $customSamplingContext = [ // PII 'userId' => '12312012', // too big to send 'resultsFromLastSearch' => [ ... ] ] ); ``` -------------------------------- ### Implement Advanced Traces Sampler Source: https://docs.sentry.io/platforms/php/guides/laravel/configuration/laravel-options Use a callable for more granular control over which requests are monitored for tracing. This allows custom sampling logic. ```php 'traces_sampler' => [App\Exceptions\Sentry::class, 'tracesSampler'], ``` ```php class Sentry { public static function tracesSampler(\Sentry\Tracing\SamplingContext $context): float { // Keep front-end and back-end traces connected. if ($context->getParentSampled()) { return 1.0; } if (some_condition()) { // Drop this transaction. return 0.0; } // Default sample rate for all other transactions. return 0.25; } } ``` -------------------------------- ### Set Current Transaction Manually Source: https://docs.sentry.io/platforms/php/guides/laravel/tracing/instrumentation/custom-instrumentation Manually set the current transaction on the hub after starting it. This ensures that subsequent operations correctly associate spans with this transaction. ```php $transactionContext = \Sentry\Tracing\TransactionContext::make() ->setName('Example Transaction'); ->setOp('http.server'); $transaction = \Sentry\startTransaction($transactionContext); // A transaction is a span so we set it using `setSpan` \Sentry\SentrySdk::getCurrentHub()->setSpan($transaction); ``` -------------------------------- ### Implement Custom Traces Sampler Source: https://docs.sentry.io/platforms/php/guides/laravel/tracing Implement a custom traces sampler function to dynamically determine the sampling rate based on context. This allows for conditional sampling, such as sampling all parent transactions. ```php class Sentry { public static function tracesSampler(\Sentry\Tracing\SamplingContext $context): float { // Return a value between 0 and 1. return $context->getParentSampled() ? 1.0 : 0.2; } } ``` -------------------------------- ### Configure All Disks for Storage Instrumentation Source: https://docs.sentry.io/platforms/php/guides/laravel/tracing/instrumentation/automatic-instrumentation Wrap all disk configurations with `Sentry\Laravel\Features\Storage\Integration::configureDisks()` to enable spans and breadcrumbs for filesystem access. Spans and breadcrumbs are enabled by default. ```php 'disks' => Sentry\Laravel\Features\Storage\Integration::configureDisks([ 'local' => [ 'driver' => 'local', 'root' => storage_path('app'), 'throw' => false, ], // ... ], /* enableSpans: */ true, /* enableBreadcrumbs: */ true) ``` -------------------------------- ### Enable Tracing with Sample Rate Source: https://docs.sentry.io/platforms/php/guides/laravel/configuration/laravel-options Set the sample rate for distributed tracing. A value greater than 0.0 enables tracing. Adjust in production to manage quota. ```bash # You may need to adjust this value in your production environment to prevent quota issues SENTRY_TRACES_SAMPLE_RATE=1.0 ``` -------------------------------- ### Inject Tracing Information Into HTTP Requests Source: https://docs.sentry.io/platforms/php/guides/laravel/tracing/trace-propagation/custom-instrumentation Generate and inject 'sentry-trace' and 'baggage' headers into outgoing HTTP requests using \Sentry\getTraceparent() and \Sentry\getBaggage(). This example uses Guzzle. ```php $client = new GuzzleHttp\Client(); $res = $client->request('GET', 'https://example.com', [ 'headers' => [ 'baggage' => \Sentry\getBaggage(), 'sentry-trace' => \Sentry\getTraceparent(), ] ]); ``` -------------------------------- ### Test Sentry Configuration with Artisan Source: https://docs.sentry.io/platforms/php/guides/laravel Run the sentry:test Artisan command to verify that your Sentry configuration is working correctly and reporting test errors. ```shell php artisan sentry:test ``` -------------------------------- ### Modify or Discard Transactions with before_send_transaction Source: https://docs.sentry.io/platforms/php/guides/laravel/configuration/filtering Use `before_send_transaction` with a callable to modify transaction events or discard them by returning null. This example shows a basic implementation that returns the transaction unmodified. ```php 'before_send_transaction' => [App\Exceptions\Sentry::class, 'beforeSendTransaction'] ``` ```php class Sentry { public static function beforeSendTransaction(\Sentry\Event $transaction): ?\Sentry\Event { return $transaction; } } ``` -------------------------------- ### Example of Truncated Tag Value Source: https://docs.sentry.io/platforms/php/guides/laravel/troubleshooting Illustrates how a tag value exceeding the 200-character limit is truncated. Consider splitting long data across multiple tags to retain information. ```text https://empowerplant.io/api/0/projects/ep/setup_form/?user_id=314159265358979323846264338327&tracking_id=EasyAsABC123OrSimpleAsDoReMi&product_name=PlantToHumanTranslator&product_id=161803398874989484820458683436563811772030917980576 ``` ```text https://empowerplant.io/api/0/projects/ep/setup_form/?user_id=314159265358979323846264338327&tracking_id=EasyAsABC123OrSimpleAsDoReMi&product_name=PlantToHumanTranslator&product_id=1618033988749894848 ``` -------------------------------- ### Configure Log Channels in .env Source: https://docs.sentry.io/platforms/php/guides/laravel/logs Set these variables in your .env file to enable Sentry logging. Ensure LOG_CHANNEL is set to 'stack' and includes 'sentry_logs'. ```bash # ... LOG_CHANNEL=stack LOG_STACK=single,sentry_logs # ... ``` ```bash # ... SENTRY_ENABLE_LOGS=true # ... ``` ```bash # ... LOG_LEVEL=info # defaults to debug SENTRY_LOG_LEVEL=warning # defaults to LOG_LEVEL # ... ``` -------------------------------- ### Add Span When Retrieving Data From Cache Source: https://docs.sentry.io/platforms/php/guides/laravel/tracing/instrumentation/caches-module Use this snippet to emit custom Sentry spans for cache GET operations when auto-instrumentation is not available. Ensure you have the Sentry SDK initialized. ```php $key = 'cache_key'; $value = null; $parentSpan = \Sentry\SentrySdk::getCurrentHub()->getSpan(); if ($parentSpan !== null) { $context = \Sentry\Tracing\SpanContext::make() ->setOp('cache.get'); $span = $parentSpan->startChild($context); \Sentry\SentrySdk::getCurrentHub()->setSpan($span); // Perform you cache operation $value = Cache::get($key); $span->setData([ // Describe the cache server you are accessing 'network.peer.address' => '127.0.0.1', 'network.peer.port' => 9000, // Add the key you just retrieved from the cache 'cache.key' => $key ]); if ($value !== null) { $span->setData([ // If you retrieved a value, the cache was hit 'cache.hit' => true, // Optionally, add the size of the value you retrieved 'cache.item_size' => strlen($value), ]); } else { $span->setData([ // If you could not retrieve a value, it was a miss 'cache.hit' => false, ]); } $span->finish(); \Sentry\SentrySdk::getCurrentHub()->setSpan($parentSpan); } ``` -------------------------------- ### Configure before_send_metric Option Source: https://docs.sentry.io/platforms/php/guides/laravel/metrics Filter or update metrics before they are sent to Sentry using the 'before_send_metric' option. If the callback returns null, the metric is discarded. This example shows how to prevent 'removed-metric' from being sent. ```php 'before_send_metric' => [App\Exceptions\Sentry::class, 'beforeSendMetric'], ``` ```php class Sentry { public static function beforeSendMetric(\Sentry\Metrics\Types\Metric $metric): ?\Sentry\Metrics\Types\Metric { if ($metric->getName() === 'removed-metric') { return null; } return $metric; } } ``` -------------------------------- ### Sample Error Events Source: https://docs.sentry.io/platforms/php/guides/laravel/configuration/sampling Configure a static rate to send a representative sample of errors to Sentry. Set the 'sample_rate' option to a value between 0 (0% sent) and 1 (100% sent). ```php 'sample_rate' => 0.25, ``` -------------------------------- ### Publish Sentry Configuration Source: https://docs.sentry.io/platforms/php/guides/laravel Use the Artisan command to publish the Sentry configuration and set your DSN. This creates the config file and updates your .env. ```shell php artisan sentry:publish --dsn=https://@o.ingest.sentry.io/ ``` -------------------------------- ### Configure Prefixes for Stacktrace Normalization Source: https://docs.sentry.io/platforms/php/guides/laravel/configuration/options Use the 'prefixes' option to strip common path prefixes from filenames in stack traces. This helps normalize paths across different deployment environments. ```php \Sentry\init([ 'dsn' => 'https://@o.ingest.sentry.io/', 'prefixes' => [ '/var/www/', '/home/user/projects/', ], ]); ``` -------------------------------- ### Initialize Sentry with a Debug Logger Source: https://docs.sentry.io/platforms/php/guides/laravel/troubleshooting Configure Sentry SDK to log internal events to a file or standard output for debugging purposes. This helps in diagnosing SDK-related issues. ```php \Sentry\init([ 'logger' => new \Sentry\Logger\DebugFileLogger('/path/to/your/logfile.log'), ]); // or \Sentry\init([ 'logger' => new \Sentry\Logger\DebugStdOutLogger(), ]); ``` -------------------------------- ### Set Environment Source: https://docs.sentry.io/platforms/php/guides/laravel/configuration/options Configure the environment for Sentry events. Defaults to 'production' or the Laravel environment if not explicitly set. ```php 'environment' => 'production', ``` -------------------------------- ### Implement `before_send` Callback Source: https://docs.sentry.io/platforms/php/guides/laravel/data-management/sensitive-data Implement the static callback method defined in the `before_send` configuration. This method receives the Sentry event object and can modify it or return null to discard the event. ```php class Sentry { public static function beforeSend(\Sentry\Event $event): ?\Sentry\Event { return $event; } } ``` -------------------------------- ### Configure Traces Sampler Option Source: https://docs.sentry.io/platforms/php/guides/laravel/configuration/sampling Set the `traces_sampler` option in your Sentry configuration to point to a static method that will handle sampling logic. This replaces `traces_sample_rate` when both are configured. ```php 'traces_sampler' => [App\Exceptions\Sentry::class, 'tracesSampler'], ``` -------------------------------- ### Configure Tracing Sample Rate Source: https://docs.sentry.io/platforms/php/guides/laravel/tracing Set a fixed sample rate for all transactions or provide a custom callable function for more granular control. The `traces_sampler` option takes precedence if both are set. ```php // Specify a fixed sample rate: 'traces_sample_rate' => 0.2, // Or provide a custom sampler as a callable: 'traces_sampler' => [App\Exceptions\Sentry::class, 'tracesSampler'], ``` -------------------------------- ### Enable Excimer Extension Source: https://docs.sentry.io/platforms/php/guides/laravel/profiling Enable the Excimer extension for PHP's FastCGI Process Manager (FPM) or Apache. ```bash phpenmod -s fpm excimer ``` ```bash phpenmod -s apache2 excimer ``` -------------------------------- ### Implement Traces Sampler Method Source: https://docs.sentry.io/platforms/php/guides/laravel/configuration/sampling Implement the `tracesSampler` method to define custom sampling logic. This method accepts a `SamplingContext` object and should return a float between 0 and 1. It allows conditional sampling based on parent decisions or custom conditions. ```php class Sentry { // `traces_sampler` replaces `traces_sample_rate` when both are configured. public static function tracesSampler(\Sentry\Tracing\SamplingContext $context): float { if ($context->getParentSampled()) { // If the parent transaction (for example a JavaScript front-end) // is sampled, also sample the current transaction. return 1.0; } if (some_condition()) { // Drop this transaction by setting its sample rate to 0. return 0.0; } // Default sample rate for all other transactions. return 0.25; } } ``` -------------------------------- ### Enable Tracing Sample Rate Source: https://docs.sentry.io/platforms/php/guides/laravel Set the traces_sample_rate in your Sentry configuration or .env file to enable performance tracing. A value greater than 0.0 transmits traces. ```dotenv # Be sure to lower this value in production otherwise you could burn through your quota quickly. SENTRY_TRACES_SAMPLE_RATE=1.0 ``` -------------------------------- ### Configure Environment in Laravel Source: https://docs.sentry.io/platforms/php/guides/laravel/configuration/environments Set the 'environment' key in your Sentry configuration to specify the current environment. If left empty or null, the Laravel environment will be used. ```php // When left empty or `null` the Laravel environment will be used 'environment' => 'production', ``` -------------------------------- ### Enable Tracing in Laravel Source: https://docs.sentry.io/platforms/php/guides/laravel/profiling Configure the 'traces_sample_rate' in your Laravel application's Sentry configuration to enable tracing. ```php 'traces_sample_rate' => 1.0, ``` -------------------------------- ### Laravel Logging Configuration Source: https://docs.sentry.io/platforms/php/guides/laravel/logs Ensure your `config/logging.php` file allows environment variable configuration for default and stack channels. This allows dynamic control over logging behavior. ```php // ... 'default' => env('LOG_CHANNEL', 'stack'), // ... 'channels' => [ 'stack' => [ 'driver' => 'stack', 'channels' => explode(',', (string) env('LOG_STACK', 'single')), 'ignore_exceptions' => false, ], // ... ``` -------------------------------- ### Consistent Attribute Naming Convention Source: https://docs.sentry.io/platforms/php/guides/laravel/logs Demonstrates inconsistent vs. consistent attribute naming for logs. Adhering to a convention like snake_case is crucial for effective log querying. ```php // ❌ Inconsistent naming ['user' => '123'] ['userId' => '123'] ['user_id' => '123'] ['UserID' => '123'] ``` ```php // ✅ Consistent snake_case [ 'user_id' => '123', 'order_id' => '456', 'cart_value' => 99.99, 'item_count' => 3, ] ``` -------------------------------- ### Create Span using trace function Source: https://docs.sentry.io/platforms/php/guides/laravel/tracing/instrumentation/custom-instrumentation Utilize the `trace` function for a more concise way to create and manage a span for a specific operation. This reduces boilerplate code compared to manual span creation. ```php function expensive_operation(): void { $spanContext = \Sentry\Tracing\SpanContext::make() ->setOp('some_operation') ->setDescription('This is a description'); \Sentry\trace(function () { // Do the expensive operation... }, $spanContext); } ``` -------------------------------- ### Enable Profiling in Laravel Source: https://docs.sentry.io/platforms/php/guides/laravel/profiling Configure both 'traces_sample_rate' and 'profiles_sample_rate' in your Laravel application's Sentry configuration to enable profiling. ```php 'traces_sample_rate' => 1.0, // Set a sampling rate for profiling - this is relative to traces_sample_rate 'profiles_sample_rate' => 1.0, ``` -------------------------------- ### Configure Specific Disks for Storage Instrumentation Source: https://docs.sentry.io/platforms/php/guides/laravel/tracing/instrumentation/automatic-instrumentation Use `Sentry\Laravel\Features\Storage\Integration::configureDisk()` to selectively enable spans and breadcrumbs for specific filesystem disks. Spans and breadcrumbs are enabled by default. ```php 'disks' => [ 'local' => [ 'driver' => 'local', 'root' => storage_path('app'), 'throw' => false, ], 's3' => Sentry\Laravel\Features\Storage\Integration::configureDisk('s3', [ // ... ], /* enableSpans: */ true, /* enableBreadcrumbs: */ true), ] ``` -------------------------------- ### Register Custom Facade in Laravel Source: https://docs.sentry.io/platforms/php/guides/laravel/usage Add your custom Sentry facade to the `config/app.php` file under the 'aliases' section. ```php 'aliases' => array( // ... 'SentryLaravel' => App\Support\SentryLaravelFacade::class, ) ``` -------------------------------- ### Debug Logging to File Source: https://docs.sentry.io/platforms/php/guides/laravel/configuration/options Configure the Sentry SDK to log debug messages to a specified file. Useful for troubleshooting. ```php 'logger' => new \Sentry\Logger\DebugFileLogger(filePath: storage_path('logs/sentry.log')), ``` -------------------------------- ### Create and Manage Child Spans Source: https://docs.sentry.io/platforms/php/guides/laravel/tracing/instrumentation/custom-instrumentation Use `getSpan()` to retrieve the current span and `startChild()` to create a new span. Restore the parent span using `setSpan()` after the child span finishes. ```php $parentSpan = \Sentry\SentrySdk::getCurrentHub()->getSpan(); if ($parentSpan !== null) { $context = \Sentry\Tracing\SpanContext::make() ->setOp('some_operation'); $span = $parentSpan->startChild($context); // Set the span we just started as the current span \Sentry\SentrySdk::getCurrentHub()->setSpan($span); // ... $span->finish(); // Restore the span back to the parent span \Sentry\SentrySdk::getCurrentHub()->setSpan($parentSpan); } ``` -------------------------------- ### Debug Logging to Stdout Source: https://docs.sentry.io/platforms/php/guides/laravel/configuration/options Configure the Sentry SDK to log debug messages to standard output. Useful for containerized environments. ```php 'logger' => new \Sentry\Logger\DebugStdOutLogger(), ``` -------------------------------- ### Implement before_send_log Callback Source: https://docs.sentry.io/platforms/php/guides/laravel/logs Use the 'before_send_log' option in your Sentry configuration to filter or modify logs before they are sent. Implement a static method that accepts a Sentry Log object and returns it or null to discard. ```php 'before_send_log' => [App\Exceptions\Sentry::class, 'beforeSendLog'], ``` ```php class Sentry { public static function beforeSendLog(\Sentry\Logs\Log $log): ?\Sentry\Logs\Log { if ($log->getLevel() === \Sentry\Logs\LogLevel::info()) { // Filter out all info logs. return null; } return $log; } } ``` -------------------------------- ### Filter Events Based on Exception Type using `before_send` and Hints Source: https://docs.sentry.io/platforms/php/guides/laravel/configuration/filtering Use the `hint` object within the `before_send` callback to access the original exception. This allows you to ignore events if the exception matches a specific type, such as `MyException`. ```php class Sentry { public static function beforeSend(\Sentry\Event $event, ?\Sentry\EventHint $hint): ?\Sentry\Event { // Ignore the event if the original exception is an instance of MyException. if ($hint !== null && $hint->exception instanceof MyException) { return null; } return $event; } } ``` -------------------------------- ### Set Trace Sample Rate Source: https://docs.sentry.io/platforms/php/guides/laravel/configuration/options Configure the sampling rate for traces in your Laravel application using an environment variable. ```bash SENTRY_TRACES_SAMPLE_RATE=1.0 ``` -------------------------------- ### Configure Sentry Log Channel in config/logging.php Source: https://docs.sentry.io/platforms/php/guides/laravel/logs Add this configuration to the 'channels' section of your config/logging.php file to define the Sentry log driver and its level. ```php 'channels' => [ // ... 'sentry_logs' => [ 'driver' => 'sentry_logs', // The minimum logging level at which this handler will be triggered // Available levels: debug, info, notice, warning, error, critical, alert, emergency 'level' => env('LOG_LEVEL', 'info'), // defaults to `debug` if not set ], ], ``` -------------------------------- ### Filter Transactions with traces_sampler Source: https://docs.sentry.io/platforms/php/guides/laravel/configuration/filtering Use `traces_sampler` to provide a function that evaluates transactions and drops unwanted ones. If the parent transaction is sampled, inherit that decision. Otherwise, apply custom logic to drop or sample. ```php 'traces_sampler' => [App\Exceptions\Sentry::class, 'tracesSampler'] ``` ```php class Sentry { // `traces_sampler` replaces `traces_sample_rate` when both are configured. public static function tracesSampler(\Sentry\Tracing\SamplingContext $context): float { if ($context->getParentSampled()) { // If the parent transaction (for example a JavaScript front-end) // is sampled, also sample the current transaction. return 1.0; } if (some_condition()) { // Drop this transaction by setting its sample rate to 0. return 0.0; } // Default sample rate for all other transactions. return 0.25; } } ``` -------------------------------- ### Include Sentry JavaScript SDK Source: https://docs.sentry.io/platforms/php/guides/laravel/user-feedback Add this script tag to your HTML to include the Sentry JavaScript SDK. Ensure it's available in your application. ```html ``` -------------------------------- ### Send Structured Logs with Monolog LogsHandler Source: https://docs.sentry.io/platforms/php/guides/laravel/integrations/monolog Use the ` Sentry\Monolog\LogsHandler` to send structured Monolog messages as searchable logs to Sentry. Configure the minimum log level to capture. The context array passed to Monolog methods becomes searchable attributes in Sentry. ```php 'https://@o.ingest.sentry.io/', 'enable_logs' => true, // Enable Sentry logging ]); // Create a Monolog channel with a logs handler $logger = new Logger('sentry_logs'); $logger->pushHandler(new \Sentry\Monolog\LogsHandler( LogLevel::info(), // Minimum level to send logs )); // Send logs to Sentry $logger->info('User logged in', [ 'user_id' => 12345, 'email' => 'user@example.com', 'login_method' => 'password', ]); $logger->warning('API rate limit approaching', [ 'endpoint' => '/api/users', 'requests_remaining' => 10, 'window_seconds' => 60, ]); ``` -------------------------------- ### Set Structured Context for All Events Source: https://docs.sentry.io/platforms/php/guides/laravel/enriching-events/context Use `configureScope` to set context that will be applied to all events captured by the Sentry SDK within its lifecycle. ```php \Sentry\configureScope(function (\Sentry\State\Scope $scope): void { $scope->setContext('character', [ 'name' => 'Mighty Fighter', 'age' => 19, 'attack_type' => 'melee' ]); }); ``` -------------------------------- ### Advanced Cron Job Monitor Configuration (Older Versions) Source: https://docs.sentry.io/platforms/php/guides/laravel/crons Configure advanced parameters like check-in margin, max runtime, and failure thresholds for job monitors in Laravel 10.x, 9.x, & 8.x. ```php protected function schedule(Schedule $schedule) { $schedule->command('emails:send') ->everyHour() ->sentryMonitor( // Specify the slug of the job monitor in case of duplicate commands or if the monitor was created in the UI. monitorSlug: null, // Number of minutes before a check-in is considered missed. checkInMargin: 5, // Number of minutes before an in-progress check-in is marked timed out. maxRuntime: 15, // Create a new issue when this many consecutive missed or error check-ins are processed. failureIssueThreshold: 1, // Resolve the issue when this many consecutive healthy check-ins are processed. recoveryThreshold: 1, // In case you want to configure the job monitor exclusively in the UI, you can turn off sending the monitor config with the check-in. // Passing a monitor-slug is required in this case. updateMonitorConfig: false, ) } ``` -------------------------------- ### Including Business Context in Logs Source: https://docs.sentry.io/platforms/php/guides/laravel/logs Enhance logs with business-specific attributes such as user context, transaction data, feature flags, and request metadata. This aids in prioritizing and debugging logs based on business value. ```php \Sentry\logger()->info('API request completed', attributes: [ // User context 'user_id' => $user->id, 'user_tier' => $user->plan, // "free" | "pro" | "enterprise" 'account_age_days' => $user->ageDays, // Request data 'endpoint' => '/api/orders', 'method' => 'POST', 'duration_ms' => 234, // Business context 'order_value' => 149.99, 'feature_flags' => ['new-checkout', 'discount-v2'], ]); ``` -------------------------------- ### Basic Cron Job Monitoring in Laravel (Older Versions) Source: https://docs.sentry.io/platforms/php/guides/laravel/crons For Laravel 10.x, 9.x, & 8.x, add the sentryMonitor() macro within the schedule method in app/Console/Kernel.php. ```php protected function schedule(Schedule $schedule) { $schedule->command('emails:send') ->everyHour() ->sentryMonitor(); // add this line } ``` -------------------------------- ### Configure Lazy Loading Violation Reporter Options Source: https://docs.sentry.io/platforms/php/guides/laravel/integrations/eloquent Customize the lazy loading violation reporter to control immediate reporting and suppression of duplicate violations within a single request. ```php use Illuminate\Database\Eloquent\Model; use Sentry\Laravel\Integration; Model::handleLazyLoadingViolationUsing( Integration::lazyLoadingViolationReporter( reportAfterResponse: true, // set to false to send the violation immediately suppressDuplicateReports: true, // set to false to send all violations, even if reported before in the same request ) ); ``` -------------------------------- ### Inherit Parent Sampling Decision Source: https://docs.sentry.io/platforms/php/guides/laravel/configuration/sampling Implement the `tracesSampler` to always inherit the parent sampling decision when available. This is crucial for maintaining distributed traces and avoiding broken trace chains. ```php class Sentry { public static function tracesSampler(\Sentry\Tracing\SamplingContext $context): float { // Always inherit the parent sampling decision. if ($context->getParentSampled()) { return 1.0; } // The rest of your sampling logic. return 0.25; } } ``` -------------------------------- ### CSP Report-Only Headers for Violations Source: https://docs.sentry.io/platforms/php/guides/laravel/security-policy-reporting Configure Content-Security-Policy-Report-Only headers to log CSP violations without enforcing the policy. Includes `report-uri`, `report-to`, and `Reporting-Endpoints` for broad browser compatibility. ```bash Content-Security-Policy-Report-Only: ...; report-uri https://o.ingest.sentry.io/api//security/?sentry_key=; report-to csp-endpoint Report-To: {"group":"csp-endpoint","max_age":10886400,"endpoints":[{"url":"https://o.ingest.sentry.io/api//security/?sentry_key="}],"include_subdomains":true} Reporting-Endpoints: csp-endpoint="https://o.ingest.sentry.io/api//security/?sentry_key=" ``` -------------------------------- ### Register Custom Service Provider in Laravel Source: https://docs.sentry.io/platforms/php/guides/laravel/usage Add your custom Sentry service provider to the `config/app.php` file to ensure it's registered by Laravel. ```php 'providers' => array( // ... App\Support\SentryLaravelServiceProvider::class, ) ``` -------------------------------- ### Advanced Cron Job Monitor Configuration Source: https://docs.sentry.io/platforms/php/guides/laravel/crons Configure advanced parameters like check-in margin, max runtime, and failure thresholds for job monitors in Laravel 12.x & 11.x. ```php Schedule::command(SendEmailsCommand::class) ->everyHour() ->sentryMonitor( // Specify the slug of the job monitor in case of duplicate commands or if the monitor was created in the UI. monitorSlug: null, // Number of minutes before a check-in is considered missed. checkInMargin: 5, // Number of minutes before an in-progress check-in is marked timed out. maxRuntime: 15, // Create a new issue when this many consecutive missed or error check-ins are processed. failureIssueThreshold: 1, // Resolve the issue when this many consecutive healthy check-ins are processed. recoveryThreshold: 1, // In case you want to configure the job monitor exclusively in the UI, you can turn off sending the monitor config with the check-in. // Passing a monitor-slug is required in this case. updateMonitorConfig: false, ) ``` -------------------------------- ### Add User Context via Middleware Source: https://docs.sentry.io/platforms/php/guides/laravel/usage Use a middleware to add user information to the Sentry scope if a user is logged in. This ensures that user-specific data is associated with captured events. ```php namespace App\Http\Middleware; use Closure; use Sentry\State\Scope; class SentryContext { /** * Handle an incoming request. * * @param \Illuminate\Http\Request $request * @param \Closure $next * * @return mixed */ public function handle($request, Closure $next) { if (auth()->check() && app()->bound('sentry')) { \Sentry\configureScope(function (Scope $scope): void { $scope->setUser([ 'id' => auth()->user()->id, 'email' => auth()->user()->email, ]); }); } return $next($request); } } ``` -------------------------------- ### Basic Cron Job Monitoring in Laravel Source: https://docs.sentry.io/platforms/php/guides/laravel/crons Add the sentryMonitor() macro to your scheduled tasks in routes/console.php for Laravel 12.x & 11.x to enable basic monitoring. ```php Schedule::command(SendEmailsCommand::class) ->everyHour() ->sentryMonitor(); // add this line ``` -------------------------------- ### Set a Tag on the Scope Source: https://docs.sentry.io/platforms/php/guides/laravel/enriching-events/tags Use `configureScope` to set a tag with a specific key and value. This tag will be associated with the current scope and sent with events. ```php \Sentry\configureScope(function (\Sentry\State\Scope $scope): void { $scope->setTag('page.locale', 'de-at'); }); ``` -------------------------------- ### Scattered vs. Wide Logs Source: https://docs.sentry.io/platforms/php/guides/laravel/logs Contrast emitting many small logs with a single comprehensive log for an operation. Use wide logs to include all relevant context for faster debugging. ```php // ❌ Scattered thin logs \Sentry\logger()->info('Starting checkout'); \Sentry\logger()->info('Validating cart'); \Sentry\logger()->info('Processing payment'); \Sentry\logger()->info('Checkout complete'); ``` ```php // ✅ One wide event with full context \Sentry\logger()->info('Checkout completed', attributes: [ 'order_id' => $order->id, 'user_id' => $user->id, 'user_tier' => $user->subscription, 'cart_value' => $cart->total, 'item_count' => count($cart->items), 'payment_method' => 'stripe', 'duration_ms' => (microtime(true) - $startTime) * 1000, ]); ```