{"id":27180382,"url":"https://github.com/kodus/sentry","last_synced_at":"2025-04-09T14:35:29.590Z","repository":{"id":33183789,"uuid":"154290966","full_name":"kodus/sentry","owner":"kodus","description":"Lightweight alternative to the official PHP client for Sentry","archived":false,"fork":false,"pushed_at":"2025-01-29T08:57:40.000Z","size":97,"stargazers_count":8,"open_issues_count":1,"forks_count":3,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-03-30T14:35:28.957Z","etag":null,"topics":["php","sentry-client"],"latest_commit_sha":null,"homepage":"","language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/kodus.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2018-10-23T08:26:15.000Z","updated_at":"2025-01-21T10:47:29.000Z","dependencies_parsed_at":"2025-01-09T13:50:10.098Z","dependency_job_id":"c0240dd5-222f-4e37-b995-aef58fa2b1be","html_url":"https://github.com/kodus/sentry","commit_stats":{"total_commits":60,"total_committers":4,"mean_commits":15.0,"dds":"0.050000000000000044","last_synced_commit":"f8522f3bf3ec53ef570c592cc0327e20cefae2c1"},"previous_names":[],"tags_count":6,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kodus%2Fsentry","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kodus%2Fsentry/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kodus%2Fsentry/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kodus%2Fsentry/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/kodus","download_url":"https://codeload.github.com/kodus/sentry/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248055293,"owners_count":21040151,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["php","sentry-client"],"created_at":"2025-04-09T14:35:26.721Z","updated_at":"2025-04-09T14:35:29.581Z","avatar_url":"https://github.com/kodus.png","language":"PHP","funding_links":[],"categories":[],"sub_categories":[],"readme":"`kodus/sentry`\n==============\n\nLightweight [Sentry](https://sentry.io/welcome/) client with no dependencies.\n\n[![PHP Version](https://img.shields.io/badge/php-7.1%2B-blue.svg)](https://packagist.org/packages/kodus/sentry)\n![Build Status](https://github.com/kodus/sentry/actions/workflows/test.yml/badge.svg)\n\n### About\n\nThis package is an alternative to the [official PHP client](https://github.com/getsentry/sentry-php) for Sentry.\n\nThe library consists of a client class, an event-model model that matches the shape of the Sentry API, and\nan interface for extensions.\n\nThe API deviates from the [Unified API](https://docs.sentry.io/clientdev/unified-api/) recommendation - our\ngoal is to log detailed exceptions, and capture log-entries leading up to those exceptions, with as little\ncoupling and dependency on the client as possible.\n\nWith most members declared as `protected`, you can further extend and override/enhance various aspects\nof exception/error/request-processing with simple code that modifies the (fully type-hinted) model.\n\n### Features\n\nThis client has most of the features of the official client plus some extras.\n\nAll features are opt-in, and the package ships with the following extensions:\n\n  * `EnvironmentReporter`: Reports PHP and OS versions, server name, site name, etc.\n  * `RequestReporter`: Reports details about the (PSR-7) HTTP Request.\n  * `ExceptionReporter`: Provides detailed stack-traces with source-code context, paths/filenames, line-numbers, etc.\n  * `ClientSniffer`: Parses `User-Agent` for client (browser or bot) name/version/OS and adds useful tags.\n  * `ClientIPDetector`: Parses `X-Forwarded-For` and `Forwarded` headers for User IP logging behind proxies.\n  * `BreadcrumbLogger`: Reports [PSR-3](https://www.php-fig.org/psr/psr-3/) log-events\n     as \"[breadcrumbs](https://docs.sentry.io/clientdev/interfaces/breadcrumbs/)\".\n\nNon-features:\n\n  * No built-in error-handler: your framework/stack/app probably has one, and this client should be\n    very easy to integrate just about anywhere.\n  * No post-data recording: scrubbing/sanitization is unreliable. (if you're willing to take the risk,\n    the fields are there in the model, and you can implement your own extension.)\n\n### Usage\n\nMost modern frameworks by now have some sort of DI container and an error-handler.\n\nTo avoid getting caught up in the specifics of various frameworks, in this section, we'll demonstrate\nhow to bootstrap and integrate the client independently of any specific framework.\n\nTo bootstrap the client itself, you need a [Sentry DSN](https://docs.sentry.io/learn/configuration/?platform=node#dsn),\nan `EventCapture` implementation, and a your choice of extensions - this example uses `DirectEventCapture`\nand most of the built-in extensions:\n\n```php\n$client = new SentryClient(\n    new DirectEventCapture(\n        new DSN(\"https://0123456789abcdef0123456789abcdef@sentry.io/1234567\"),\n        \"tcp://proxy.example.com:5100\" // optional: required if you're behind a proxy\n    ),\n    [\n        new EnvironmentReporter(),\n        new RequestReporter(),\n        new ExceptionReporter(),\n        new ClientSniffer(),\n        new ClientIPDetector(),\n    ]\n);\n\n$client-\u003esample_rate = 50; // optional: percentage of calls to `captureException()` to actually capture\n```\n\nSome extensions support additional options, which will be described in the [Configuration](#configuration) section.\n\nTo capture PHP errors, we'll need to add an error-handler that maps errors to instances of the\nbuilt-in [`ErrorException`](http://php.net/manual/en/class.errorexception.php) class.\n\nNote that most frameworks and error-handlers already have something like this built-in - an existing\nerror-handler likely is designed to be the only global error-handler, and will likely offer an abstraction\nand some sort of API over `set_error_handler()`.\n\nThe following simplified error-handler throws for all error-levels except `E_NOTICE` and `E_WARNING`, which it\nsilently captures to the `$client` instance we created above:\n\n```php\nset_error_handler(\n    function ($severity, $message, $file, $line) use ($client) {\n        $error = new ErrorException($message, 0, $severity, $file, $line);\n        \n        if ($severity \u0026 (E_ALL \u0026 ~E_NOTICE \u0026 ~E_WARNING)) {\n            throw $error;\n        } else {\n            $client-\u003ecaptureException($error);\n        }\n    },\n);\n```\n\nNow that we have `ErrorException` being thrown for PHP errors, we can handle any error/exception\nconsistently with a `try`/`catch`-statement surrounding any statements in the top-level script:\n\n```php\ntry {\n    // ... dispatch your router or middleware-stack, etc. ...\n} catch (Throwable $error) {\n    $client-\u003ecaptureException($error);\n    \n    // ... render an apology page for disappointed users ...\n}\n```\n\nWe now have basic error-handling and silent capture of warnings and notices.\n\nIn a [PSR-15](https://www.php-fig.org/psr/psr-7/) middleware context, we can capture useful additional\ninformation about the `ServerRequestInterface` instance that initiated the error - typically, we'll do this\nwith a middleware at the top of the middleware-stack, which will delegate to the next middleware from\na `try`/`catch`-block.\n\nHere's a basic example of an anonymous middleware being added to an array of middlewares:\n\n```php\n$middlewares = [\n    new class ($client) implements MiddlewareInterface {\n        /**\n         * @var SentryClient\n         */\n        private $client;\n    \n        public function __construct(SentryClient $client)\n        {\n            $this-\u003eclient = $client;\n        }\n    \n        public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface\n        {\n            try {\n                return $handler-\u003ehandle($request);\n            } catch (Throwable $error) {\n                $this-\u003eclient-\u003ecaptureException($error, $request);\n    \n                // ... return an apology response for disappointed users ...\n            }\n        }\n    },\n    // ... the rest of your middleware stack ...\n];\n```\n\nAny error caught by this middleware *won't* bubble to our first `try`/`catch`-statement in the\ntop-level script - instead, the call to `captureException()` from the middleware includes both the\n`$error` and the `$request` (which doesn't exist yet in the top-level script) from which the client\ncan capture a lot more detail.\n\nIn addition, your application may log incidental useful information (such as database queries) during\nnormal operation - on failure, this information can help you diagnose the events leading up to an error.\n\nThese log entries can be captured as so-called \"breadcrumbs\" using the provided `BreadcrumbLogger`,\nwhich is both a [PSR-3](https://www.php-fig.org/psr/psr-3/) `LoggerInterface` implementation and\na `SentryClientExtension`.\n\nYou *might* want to bootstrap this as your primary logger - maybe you only care about log-entries that\nlead to an error condition. However, it's more likely you'll want another logger to send log-events to\na persisted log, as well as recording them as breadcrumbs. (For example, you may try the\n[`monolog/monolog`](https://packagist.org/packages/monolog/monolog) package, which allows you to log to\nany combination of PSR-3 and monolog-handlers, filter the log-entries, and so on - or\n[`mouf/utils.log.psr.multi-logger`](https://github.com/thecodingmachine/utils.log.psr.multi-logger),\nif you prefer something simple.)\n\nNote that log-entries will buffer *in the logger* until you capture an exception - if your\napplication is a CLI script handling many requests, you will need to manually call `clear()`\non the logger instance at the end of a successful request, since otherwise log-entries will\naccumulate across requests.\n\nNotice: PHP 7.4 introduced a new [ini setting](https://www.php.net/manual/en/ini.core.php#ini.zend.exception-ignore-args) (`zend.exception_ignore_args`) for excluding arguments from stack traces.\nIf you want arguments to be passed on to Sentry you will need to turn this setting off.\n\n#### Configuration\n\nA few of the extensions support optional constructor arguments to configure some optional features.\n\n##### `ExceptionReporter`\n\nThe constructor accepts two optional argument:\n\n  * `$root_path` - if specified, the project root-path will be removed from visible filenames in stack-traces.\n  * `$max_string_length` - specifies the maximum length at which reported PHP values will be truncated.\n  * `$filters` - specifies one or more filename patterns to be filtered from stack-traces.\n\nIn addition, the public `$error_levels` property lets you customize how PHP error-levels map to\nSentry severity-levels. The default configuration matches that of the official 2.0 client.\n\n##### `ClientSniffer`\n\nIf your client base uses rare or exotic clients, you can add your own regular expression patterns to\nto the public `$browser_patterns` and `$os_patterns` properties to enhance the browser classifications.\nThe default configuration will recognize most common browsers and versions, operating systems and bots.\n\n##### `ClientIPDetector`\n\nReplace or add to `$user_ip_headers` to detect client IP addresses in unusual environments.\nThe built-in patterns support most ordinary cache/proxy-servers.\n\n##### `BreadcrumbLogger`\n\nThe default `$log_levels` match those of the official (2.0) client - if needed, you can\noverride with custom mappings from PSR-5 log-level to Sentry severity-level.\n\n#### `BufferedEventCapture`\n\nA buffered `EventCapture` implementation is available.\n\nIf you're capturing exceptions/errors only, you probably don't need this - but if you're mapping\nwarnings and notices to `ErrorException` with an error-handler, you may wish to avoid blocking the\nresponse while posting to Sentry.\n\nYou can accomplish this using the `BufferedEventCapture` decorator, which allows you to defer the\nactual HTTP request(s) until after you've sent the response to the user.\n\nIn this case, you will need to bootstrap the capture and client instances separately:\n\n```php\n$buffer = new BufferedEventCapture(\n   new DirectEventCapture(\n       new DSN(\"https://0123456789abcdef0123456789abcdef@sentry.io/1234567\")\n   ),\n);\n\n$client = new SentryClient($buffer);\n```\n\nSince Events will now get buffered rather than directly posted to Sentry, you will need to manually\nflush the Events at the of the request.\n\nIn a typical PHP FCGI SAPI-environment, you can accomplish this by explicitly closing the HTTP\nresponse immediately before flushing the events to Sentry - for example, from an `index.php` file:\n\n```php\nregister_shutdown_function(function () use ($buffer) {\n    fastcgi_finish_request();\n    \n    $buffer-\u003eflush();\n});\n``` \n\n#### Customization\n\nThe client class and extensions were designed with project-specific extensions in mind and\ncontain many `protected` methods designed for you to extend and override their behavior.\n\nUsing `protected` overrides, you can customize how events get created and captured, how\nexceptions and requests get processed, client IP detection and filtering, how PHP values are\nformatted in stack-traces, and many other details.\n\nPlease refer to the source-code for available `protected` methods - and note that we're\ncommitted to versioning this package semantically: any breaking changes to `protected` methods\nwill be versioned as major releases.\n\n### Why?\n\n*Openly opinionated fluff:*\n\nVersion 1.x of the official Sentry PHP client is dated, and not a good fit for a modern (PSR-7/15) application stack.\n\nVersion 2.0 (currently in development) is an architectural masterpiece - which is not what we need/want\nfrom something that's going to essentially collect some data and perform a simple JSON POST request.\n\nSpecifically:\n\n  * We don't need an error-handler - every modern application stack has one already.\n  * We don't want a complex architecture and custom middleware - simple functions will do.\n  * We don't want to record post-data - there are too many risks.\n  * Fewer lines of code ~\u003e fewer bugs (hopefully; you don't want the error-logger itself to break down.)\n  * No dependencies: no conflicts, no fuss.\n\nWe want something simple, fast and transparent.\n\nWe also insist on code with good IDE support, which provides better insight for someone reading/modifying the\ncode, and reduces the potential for silent errors - the official client juggles `array` values, whereas our\nmodel formally describes the JSON body-shape with a plain PHP class-hierarchy that implements `JsonSerializable`.\n\nNote that we only model the portion of the JSON body shape that makes sense in a PHP context - if you find\nsomething to be missing or incorrect, pull-requests are more than welcome.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkodus%2Fsentry","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fkodus%2Fsentry","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkodus%2Fsentry/lists"}