承接 webparking/laravel-sentry-throttling 相关项目开发

从需求分析到上线部署,全程专人跟进,保证项目质量与交付效率

邮箱:yvsm@zunyunkeji.com | QQ:316430983 | 微信:yvsm316

webparking/laravel-sentry-throttling

Composer 安装命令:

composer require webparking/laravel-sentry-throttling

包简介

Throttle exceptions before they are sent to Sentry, tagging survivors with their occurrence count.

README 文档

README

Latest Version on Packagist Total Downloads run-tests

Laravel has a built-in mechanism for throttling exceptions, but it can't define throttling rules per reportable. This package throttles exceptions specifically before they are sent to Sentry, so you can keep logging everything locally while avoiding repeated reports of the same exception in Sentry.

Compared to Sentry's own percentage-based sample_rate, this is exception-specific. On top of that, every event that survives a throttle, whether rate-limited or sampled, is tagged so you don't lose sight of how noisy it really was:

  • throttled = true: the event passed through a throttle.
  • throttle_occurrences = <count>: how many matching exceptions occurred (dropped and sent) since the previous event of this kind was reported.

Because those tags are indexed by Sentry, you can search and alert on them (e.g. throttled:true, or sort by throttle_occurrences).

Installation

Install via composer:

composer require webparking/laravel-sentry-throttling

The package registers itself as sentry.before_send automatically, but only if your project hasn't already configured one, so it never silently clobbers an existing callback. You do not need to touch config/sentry.php unless one of the cases below applies.

If you already have a before_send

Auto-registration backs off when sentry.before_send is already set. Call the throttle from within your own callback to keep both behaviors:

// config/sentry.php
use Webparking\SentryThrottling\SentryThrottling;

return [
    // ...existing config...
    'before_send' => function (\Sentry\Event $event, ?\Sentry\EventHint $hint): ?\Sentry\Event {
        $event = SentryThrottling::beforeSend($event, $hint);

        // Your own logic; $event is null when the throttle dropped the event.
        return $event;
    },
];

Registering it explicitly

If you prefer to be explicit rather than rely on auto-registration:

// config/sentry.php
return [
    // ...existing config...
    'before_send' => [\Webparking\SentryThrottling\SentryThrottling::class, 'beforeSend'],
];

Usage

Implement the ThrottlesSentryReports interface in a class of your own. For each exception it returns a Limit (rate-limit), a Lottery (probabilistic sample), or null to let the exception through untouched (Limit::none() does the same). Both a rate-limited survivor and a sampled survivor are tagged with throttled and throttle_occurrences.

<?php

declare(strict_types=1);

namespace App\Sentry;

use Illuminate\Broadcasting\BroadcastException;
use Illuminate\Cache\RateLimiting\Limit;
use Illuminate\Support\Lottery;
use Throwable;
use Webparking\SentryThrottling\Contracts\ThrottlesSentryReports;

final class SentryThrottler implements ThrottlesSentryReports
{
    public function throttleSentry(Throwable $exception): Limit|Lottery|null
    {
        return match (true) {
            // At most one report per minute, across all instances.
            $exception instanceof BroadcastException => Limit::perMinute(1),

            // One bucket per unique message, so distinct errors aren't collapsed.
            $exception instanceof \App\Exceptions\ApiException =>
                Limit::perHour(1)->by($exception->getMessage()),

            // Send roughly one in a hundred of a very noisy exception.
            $exception instanceof \App\Exceptions\NoisyException => Lottery::odds(1, 100),

            // Let everything else through.
            default => Limit::none(),
        };
    }
}

Then bind it in the container, typically in App\Providers\AppServiceProvider::register():

use App\Sentry\SentryThrottler;
use Webparking\SentryThrottling\Contracts\ThrottlesSentryReports;

public function register(): void
{
    $this->app->bind(ThrottlesSentryReports::class, SentryThrottler::class);
}

The class can live anywhere and be named anything. The package only cares that something is bound to ThrottlesSentryReports. If you're on Laravel 10 or earlier and prefer to co-locate the logic with your existing App\Exceptions\Handler, implement the interface there and bind ThrottlesSentryReports::class to it instead. If nothing is bound, the throttle stays out of the way and every event is sent as usual.

How the throttle bucket is keyed

Each exception is counted and throttled against a bucket. For a Limit, the bucket is whatever you pass to Limit::by(); without it, the bucket defaults to the exception's class, so all instances share one bucket. A Lottery has no key, so it always buckets by exception class.

// One bucket for every instance of the exception:
Limit::perHour(1),

// One bucket per unique message / code:
Limit::perHour(1)->by($exception->getMessage()),
Limit::perMinute(5)->by($exception::class.':'.$exception->getCode()),

Migrating from esign/laravel-sentry-throttling

This package is a behavioral superset of esign/laravel-sentry-throttling: the ThrottlesSentryReports interface and its throttleSentry() signature are identical, so your existing throttling rules keep working. On top of that you get the throttled / throttle_occurrences tags and automatic before_send registration.

Migration is a find/replace:

  1. Swap the dependency:
    composer remove esign/laravel-sentry-throttling
    composer require webparking/laravel-sentry-throttling
  2. Replace Esign\SentryThrottling with Webparking\SentryThrottling throughout your code (the interface import, the before_send reference, the provider).
  3. Optionally drop your manual before_send line from config/sentry.php, since the package now registers it for you when it isn't already set.

Supported versions

Every combination below is exercised in CI:

PHP Laravel Testbench
8.1 9 7
8.2 10 8
8.3 11 9
8.4 12 10
8.5 13 11

Testing & local development

The full PHP × Laravel matrix runs locally via act, executing the exact CI workflow in Docker:

make test               # run the whole matrix (needs `act` + Docker)
make test-job php=8.3   # run a single PHP version from the matrix

For day-to-day work there's a Docker workspace pinned to the newest supported combination (PHP 8.5 / Laravel 13):

make build     # build the workspace image
make install   # composer install (resolves to Laravel 13)
make phpunit   # run the test suite once
make cs-fix    # apply code style
make help      # list all targets

Prefer running things yourself? composer install && composer test works too.

Thanks

This package is heavily inspired by, and builds directly on the ideas of, esign/laravel-sentry-throttling by Esign. The ThrottlesSentryReports interface, the before_send throttling approach, and the test setup all originate from their excellent work. Thank you. 🙏

License

The MIT License (MIT). Please see the License File for more information.

统计信息

  • 总下载量: 0
  • 月度下载量: 0
  • 日度下载量: 0
  • 收藏数: 0
  • 点击次数: 2
  • 依赖项目数: 0
  • 推荐数: 0

GitHub 信息

  • Stars: 0
  • Watchers: 0
  • Forks: 0
  • 开发语言: PHP

其他信息

  • 授权协议: MIT
  • 更新时间: 2026-07-03

承接程序开发

PHP开发

VUE

Vue开发

前端开发

小程序开发

公众号开发

系统定制

数据库设计

云部署

网站建设

安全加固