philiprehberger/php-exception-reporter
Composer 安装命令:
composer require philiprehberger/php-exception-reporter
包简介
Lightweight exception reporting to log channels and webhooks
README 文档
README
Lightweight exception reporting to log channels and webhooks.
Requirements
- PHP 8.2+
Installation
composer require philiprehberger/php-exception-reporter
Usage
Basic reporting with a callback
use PhilipRehberger\ExceptionReporter\ExceptionReporter; use PhilipRehberger\ExceptionReporter\Channels\CallbackChannel; $reporter = new ExceptionReporter(); $reporter->addChannel(new CallbackChannel(function ($report) { error_log("[{$report->class}] {$report->message} in {$report->file}:{$report->line}"); })); try { riskyOperation(); } catch (\Throwable $e) { $reporter->capture($e); }
File channel
use PhilipRehberger\ExceptionReporter\Channels\FileChannel; $reporter->addChannel(new FileChannel('/var/log/app-exceptions.log')); // Each report is written as a JSON line $reporter->capture(new \RuntimeException('Something failed'));
Multiple channels
$reporter ->addChannel(new CallbackChannel(function ($report) { // Send to your monitoring service })) ->addChannel(new FileChannel('/var/log/exceptions.log'));
Deduplication
Prevent the same exception (same class, file, and line) from being reported more than once:
$reporter->enableDeduplication(); $exception = new \RuntimeException('flaky'); $reporter->capture($exception); // Reported $reporter->capture($exception); // Skipped (duplicate) $reporter->resetFingerprints(); // Clear dedup state $reporter->capture($exception); // Reported again
Adding context
$reporter->capture($exception, [ 'user_id' => 42, 'request_url' => '/checkout', ]);
Persistent context
Attach context fields that are included in every subsequent report. withContext() returns a new immutable instance:
$reporter = $reporter->withContext([ 'request_id' => 'abc-123', 'user_id' => 42, ]); // Both reports will include request_id and user_id $reporter->capture(new \RuntimeException('first')); $reporter->capture(new \LogicException('second')); // Per-call context is merged with persistent context $reporter->capture($exception, ['action' => 'checkout']);
Filtering exceptions
Skip certain exceptions from being reported using a filter callable:
$reporter->setFilter(function (\Throwable $e): bool { // Return false to skip reporting return !$e instanceof \DeprecationException; }); $reporter->capture(new \DeprecationException('old API')); // Skipped $reporter->capture(new \RuntimeException('real error')); // Reported
Webhook channel
Send exception reports to an HTTP endpoint:
use PhilipRehberger\ExceptionReporter\Channels\WebhookChannel; $reporter->addChannel(new WebhookChannel('https://example.com/webhook')); // With custom headers $reporter->addChannel(new WebhookChannel( 'https://example.com/webhook', ['Authorization' => 'Bearer secret'], )); // With a custom payload transformer $reporter->addChannel(new WebhookChannel( 'https://example.com/webhook', [], fn ($report) => ['text' => "[{$report->class}] {$report->message}"], ));
Rate limiting
Prevent flooding during cascading failures by limiting how many reports are dispatched:
$reporter->rateLimit(maxReports: 10, windowSeconds: 60); // Only the first 10 reports per fingerprint (and 10 globally) within 60 seconds are sent for ($i = 0; $i < 100; $i++) { $reporter->capture(new \RuntimeException('storm')); }
Summary reports
Access an aggregated summary of captured exceptions:
$reporter->capture(new \RuntimeException('db timeout')); $reporter->capture(new \RuntimeException('db timeout')); $reporter->capture(new \LogicException('bad state')); $summary = $reporter->summary(); $summary->totalCount(); // 3 $summary->uniqueCount(); // 2 $summary->since(); // DateTimeImmutable of earliest report $summary->until(); // DateTimeImmutable of latest report $summary->topExceptions(); // [{message, count, lastSeen}] sorted by frequency $reporter->clearHistory(); // Reset stored reports
Tracking report count
$reporter->capture(new \RuntimeException('one')); $reporter->capture(new \LogicException('two')); echo $reporter->count(); // 2
Custom channels
Implement the ReportChannel interface to build your own channel:
use PhilipRehberger\ExceptionReporter\Contracts\ReportChannel; use PhilipRehberger\ExceptionReporter\ExceptionReport; class SlackChannel implements ReportChannel { public function report(ExceptionReport $report): void { // POST to Slack webhook with $report->toArray() } }
API
ExceptionReporter
| Method | Description |
|---|---|
addChannel(ReportChannel $channel): self |
Register a reporting channel |
enableDeduplication(): self |
Enable fingerprint-based deduplication |
capture(Throwable $e, array $context = []): ExceptionReport |
Capture and report an exception |
resetFingerprints(): void |
Clear deduplication state |
withContext(array $context): self |
Return a new instance with persistent context fields |
setFilter(callable $filter): self |
Set a filter; return false to skip reporting |
count(): int |
Number of exceptions reported by this instance |
rateLimit(int $maxReports, int $windowSeconds = 60): self |
Enable rate limiting to cap reports per window |
summary(): ReportSummary |
Return an aggregated summary of stored reports |
clearHistory(): void |
Clear the stored report history |
ExceptionReport
| Property / Method | Description |
|---|---|
string $class |
Exception class name |
string $message |
Exception message |
string $file |
File where the exception was thrown |
int $line |
Line number |
string $trace |
Stack trace as string |
DateTimeImmutable $timestamp |
When the exception was captured |
array $context |
Additional context data |
?string $previousClass |
Previous exception class, if any |
?string $previousMessage |
Previous exception message, if any |
fingerprint(): string |
MD5 hash of class + file + line |
toArray(): array |
Serialize to array |
fromThrowable(Throwable, array): self |
Create from a throwable |
Channels
| Channel | Description |
|---|---|
CallbackChannel |
Invokes a user-provided callable |
FileChannel |
Appends JSON-encoded reports to a file |
WebhookChannel |
Sends JSON-encoded reports to an HTTP endpoint via POST |
RateLimiter
| Method | Description |
|---|---|
__construct(int $maxReports = 100, int $windowSeconds = 60) |
Create a rate limiter with per-fingerprint and global limits |
shouldReport(string $fingerprint): bool |
Check if a report should be allowed within the current window |
ReportSummary
| Method | Description |
|---|---|
totalCount(): int |
Total number of stored reports |
uniqueCount(): int |
Count of unique exception fingerprints |
topExceptions(int $limit = 5): array |
Top exceptions sorted by frequency with message, count, and lastSeen |
since(): ?DateTimeImmutable |
Earliest report timestamp |
until(): ?DateTimeImmutable |
Latest report timestamp |
Development
composer install vendor/bin/phpunit vendor/bin/pint --test vendor/bin/phpstan analyse
Support
If you find this project useful:
License
philiprehberger/php-exception-reporter 适用场景与选型建议
philiprehberger/php-exception-reporter 是一款 基于 PHP 开发的 Composer 扩展包,目前已累计 48 次下载、GitHub Stars 达 1, 最近一次更新时间为 2026 年 03 月 13 日, 在 PHP 生态内属于活跃度较高的组件。
它主要适用于以下技术方向: 「logging」 「exception」 「error」 「reporting」 「webhook」 等业务场景。在实际项目中,围绕这些方向常见需要落地的问题包括:接口对接、性能调优、并发安全、与既有框架(Laravel / ThinkPHP / Yii / Webman 等)的兼容适配,以及生产环境的日志埋点与稳定性保障。
我们在过去多个企业项目中使用过 philiprehberger/php-exception-reporter 或与其功能相近的方案,如果你在选型或落地过程中遇到问题,例如 版本兼容、二次改造、私有化封装、与内部系统对接、生产 BUG 排查,欢迎联系我们协助评估。
基于 philiprehberger/php-exception-reporter 在你已有业务上做功能扩展、字段裁剪、UI 适配、与内部账号 / 权限 / 日志系统的深度对接。
线上偶发问题、内存泄漏、慢查询、并发异常等排查修复;针对高流量场景做缓存、队列、索引层面的调优。
承接完整的项目从需求 → 设计 → 开发 → 上线 → 长期运维;也可按月提供技术保姆服务。
与 philiprehberger/php-exception-reporter 相关的其它包
同方向 / 同关键字的高下载量 PHP Composer 包推荐,方便对比选型:
A Zend Framework module that sets up Monolog for logging in applications.
Asynchronous Sentry for Symfony - Fire and forget
Stackdriver handler for Monolog (codeinternetapplications/monolog-stackdriver Fork).
High-performance, zero-dependency PSR-3 logger for MonkeysLegion with structured logging, handlers, processors, and PHP 8.4 features.
PHP Error Handler module that captures and displays all throwable errors in a given format, making debugging easier and more efficient
Error and Exception override and observers.
统计信息
- 总下载量: 48
- 月度下载量: 0
- 日度下载量: 0
- 收藏数: 1
- 点击次数: 28
- 依赖项目数: 0
- 推荐数: 0
其他信息
- 授权协议: MIT
- 更新时间: 2026-03-13