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

Sentry Laravel Package

lingoda/sentry

Lingoda Sentry provides Sentry error-monitoring integration for Laravel and PHP applications. It helps connect your app to Sentry so exceptions and runtime issues can be captured, reported, and investigated from a central dashboard, improving visibility into production errors.

View on GitHub
Deep Wiki
Context7

Getting Started

Before anything else: confirm the target framework. Despite the Laravel framing, this package is a Symfony bundle ("Lingoda Sentry Bundle"). There is no Laravel service provider in it. If your app is Laravel, the correct move is almost always sentry/sentry-laravel — you would only reach for this package to read/copy its configuration conventions, not to install it. The 4.0.0 release does not change that recommendation. The instructions below assume a Symfony application.

  1. Vet the package and the 4.0.0 diff first. With 0 stars, 0 dependents, and a single-vendor namespace, you are adopting an internal artifact, not a community library. Open the repo and read these in order:

    • composer.json — the require block tells you which sentry/sentry-symfony / sentry/sentry version it pins. That pin, not the bundle, dictates your upgrade path.
    • README.md — for the bundle alias and the config root key (typically lingoda_sentry).
    • src/DependencyInjection/*Extension.php — the real source of truth for every config option; treat README drift as likely.
    • The 3.4.0...4.0.0 diff and PR #10 — 4.0.0 is a major release whose only listed change is message-based fingerprinting to split over-grouped Sentry issues. Treat that as a behavioral/grouping change, not a cosmetic bugfix.
  2. Install. If it is not on Packagist, add a VCS repository entry and pin to the 4.0.0 tag or a SHA:

    "repositories": [{ "type": "vcs", "url": "https://github.com/lingoda/sentry" }],
    "require": { "lingoda/sentry": "4.0.0" }
    

    Pin a tag plus SHA rather than a branch — with no dependents, nobody else is pressure-testing releases.

  3. Register and configure. Enable in config/bundles.php (or bundles.php), then create the config file:

    # config/packages/lingoda_sentry.yaml
    lingoda_sentry:
        dsn: '%env(SENTRY_DSN)%'
        environment: '%kernel.environment%'
        release: '%env(APP_VERSION)%'
        # options below must be verified against the Extension class
    
  4. Verify with a deliberate failure. Send one real event before wiring anything else:

    bin/console sentry:test          # provided by sentry/sentry-symfony, usually still available
    

    Then throw from a controller in dev and confirm the event lands with environment, release, and a stack trace pointing at your file, not a vendor path. For 4.0.0 specifically, throw two variants of the same exception with different messages and confirm you agree with how Sentry groups them.

First real use case: replace ad-hoc try/catch { $logger->error(...) } blocks in your HTTP kernel and console commands with a single global capture path. The payoff is one place that attaches user id, tenant, request id, release, and a deliberate fingerprint to every error.

Implementation Patterns

Global exception capture, not per-controller. In Symfony, errors are already funnelled through kernel.exception. Let the bundle's listener (or sentry/sentry-symfony's) handle it. The only thing you should write is enrichment:

final class SentryContextListener
{
    public function __invoke(ExceptionEvent $event): void
    {
        $request = $event->getRequest();
        \Sentry\configureScope(function (Scope $scope) use ($request): void {
            $scope->setTag('tenant', (string) $request->attributes->get('_tenant'));
            $scope->setTag('route', (string) $request->attributes->get('_route'));
            $scope->setUser(['id' => (string) $request->attributes->get('_user_id')]);
        });
    }
}

Treat 4.0.0 fingerprinting as a grouping policy, not just a bugfix. The release splits over-grouped issues by fingerprinting messages. Before upgrading, inspect PR #10 to see exactly which message components enter the fingerprint. After upgrading, compare issue counts and saved searches in staging. If you already set custom fingerprints, make sure they do not conflict with the new default:

\Sentry\configureScope(function (Scope $scope) use ($exception): void {
    $scope->setFingerprint([
        '{{ default }}',
        get_class($exception),
        // Add only stable, low-cardinality dimensions.
        // Do not include user IDs, request IDs, timestamps, or raw messages.
    ]);
});

Use fingerprints sparingly. The goal is separating genuinely different failure modes, not creating one issue per request.

Route Monolog to Sentry, errors only. The highest-value integration is usually not the bundle's listener but a Monolog handler. Route ERROR and above to Sentry and keep INFO out — it destroys your event quota:

monolog:
    handlers:
        sentry:
            type: fingers_crossed
            action_level: error
            handler: sentry_native
        sentry_native:
            type: sentry
            level: error

fingers_crossed gives you the preceding DEBUG breadcrumbs for free while only shipping the error event. This remains the single best quota-to-value trade in the whole setup.

Tag everything that lets you filter later. Environment and release are table stakes. Add, at minimum: deploy/app version, tenant or customer tier, queue name for workers, and a correlation id echoed in your HTTP response header so support can find the event. A Sentry event with no tags is a stack trace you cannot slice.

Cover the non-HTTP surfaces explicitly. Web requests are the easy case. Wire up:

  • Console commands — ConsoleEvents::ERROR; otherwise cron failures are invisible.
  • Messenger workers — failed-message events. A worker that dies mid-retry will not surface through kernel.exception.
  • Scheduler / crons — send a heartbeat or a low-priority message so silence is detectable.

Separate sampling per environment. traces_sample_rate: 1.0 in dev, a fraction in prod, and errors_sample_rate at 1.0 (you rarely want to miss errors). Keep the DSN-per-environment pattern so staging noise never pollutes production dashboards.

Scrub before send, not after. Lingoda is an EU company; assume GDPR obligations attach to anything you ship. The reliable pattern is a before_send hook that strips known-sensitive keys and drops events flagged as expected business exceptions:

'before_send' => function (\Sentry\Event $event): ?\Sentry\Event {
    $event->setRequest(\Sentry\Request::createFromGlobals()); // then unset body/cookies
    return $event;
}

Deny-list the request body, cookies, Authorization, and email/name fields by default. An allow-list is safer than a deny-list if you can afford the enumeration.

Suppress expected exceptions. Domain exceptions you already handle (validation, auth, 404s) should never reach Sentry. Either add them to an ignore list or throw them as non-reportable types — otherwise your signal drowns within a week. With 4.0.0's finer grouping, unhandled expected exceptions become even more visible and noisy.

Gotchas and Tips

The framework mismatch is the biggest trap. If you are on Laravel, stop: install sentry/sentry-laravel, configure config/sentry.php, and use Integration::handles() for exception reporting. Installing a Symfony bundle in Laravel yields a package that autoloads but never registers — you get silent no-ops, which is worse than a hard failure.

4.0.0 is a major version for a one-line changelog. The listed change — fingerprinting messages to split over-grouped issues — can invalidate issue history, saved searches, alert rules, dashboards, and on-call routing. Do not roll it out during an incident. Upgrade in staging first and compare before/after grouping for the same exception types.

Fingerprinting can split too far. Message-based fingerprints often accidentally include request IDs, tenant names, URLs, or interpolated user data. That turns one actionable issue into thousands of one-off issues. Inspect the implementation in PR #10, and if the fingerprint is too message-specific, normalize or override it before relying on the new behavior.

Zero dependents means zero field testing. Nobody outside Lingoda has run this against your Symfony/PHP versions. Expect friction on minor upgrades. Mitigations: pin the 4.0.0 tag/SHA, keep sentry/sentry-symfony as the thing you actually depend on where possible, and budget a day to fork it if the vendor abandons it. A bundle this thin is usually reproducible in an afternoon — the value is in the conventions, not the code.

Version-lock conflicts. The bundle's pinned Sentry SDK will fight your other packages on symfony/http-kernel and psr/log. If composer update wants to downgrade Symfony, do not let it — alias or fork instead. Check composer why sentry/sentry after install to see who actually won.

Verify the 4.0.0 release provenance. The release notes are sparse and a major bump for a single fingerprinting change is unusual. Inspect git log, the tag author/signature, and the full 3.4.0...4.0.0 diff before trusting it in production.

Debugging checklist when nothing arrives:

  1. Is SENTRY_DSN actually set in the running environment? (bin/console debug:container --env-vars | grep -i sentry)
  2. Is the bundle enabled for this env? Bundles are frequently registered only in config/bundles.php under dev.
  3. Does sentry:test work? If yes, your config is fine and the problem is an exception being swallowed or filtered.
  4. Check before_send — a return null there silently drops everything and looks identical to a DSN failure.
  5. Check the ignore/deny list for the exception class you are trying to test.
  6. After 4.0.0, check whether fingerprinting split the event into a new issue group you are not looking at, or whether a custom fingerprint is suppressing the grouping you expect.

Extension points worth knowing. before_send (scrub/drop), before_send_transaction (sampling decisions), Scope::setFingerprint() (grouping policy), a custom Serializer for complex domain objects in extra, and Scope configuration in a kernel listener. Those cover nearly every production need. Anything requiring deeper surgery means you are patching the bundle, not configuring it — a signal to fork.

Treat it as a reference implementation. Given the adoption profile, the honest recommendation for a new project is still: use sentry/sentry-symfony directly and borrow this bundle's configuration shape for tags, sampling, scrubbing, and now fingerprinting. You get the operational value without inheriting an unmaintained dependency — and a Laravel team avoids the framework mismatch entirely.

Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
frankyso/ipaymu
3mdikram/worldmoneywords
snowsoft/config
itmosoft/laravel-subscriptions
larva/laravel-ai-qwen
diephp/sequences
users-au/socialite-provider
twidpay/twid-logger
mrnewport/laravel-plaid
mrnewport/laravel-repo
mrnewport/laravel-docsign
mrnewport/laravel-stow
mrnewport/laravel-flow
mrnewport/laravel-priceable
mrnewport/laravel-nestedterms
fredmeng/laravel-apidoc-generator
itstructure/laravel-multilingual-tools
pdustdar/elasticsearch
markupai/php-sdk
rlacerda83/lumem-microservice-shipment