{"id":15177389,"url":"https://github.com/open-telemetry/opentelemetry-php-instrumentation","last_synced_at":"2025-04-05T05:05:00.130Z","repository":{"id":61888056,"uuid":"537093129","full_name":"open-telemetry/opentelemetry-php-instrumentation","owner":"open-telemetry","description":"OpenTelemetry PHP auto-instrumentation extension","archived":false,"fork":false,"pushed_at":"2025-02-18T22:26:22.000Z","size":202,"stargazers_count":109,"open_issues_count":0,"forks_count":28,"subscribers_count":21,"default_branch":"main","last_synced_at":"2025-03-29T04:05:57.956Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"C","has_issues":false,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/open-telemetry.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":"CODEOWNERS","security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2022-09-15T15:35:21.000Z","updated_at":"2025-03-10T10:05:26.000Z","dependencies_parsed_at":"2023-02-19T07:20:27.592Z","dependency_job_id":"aff1b96c-142e-4aa0-8334-4eec72f5911f","html_url":"https://github.com/open-telemetry/opentelemetry-php-instrumentation","commit_stats":null,"previous_names":[],"tags_count":27,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/open-telemetry%2Fopentelemetry-php-instrumentation","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/open-telemetry%2Fopentelemetry-php-instrumentation/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/open-telemetry%2Fopentelemetry-php-instrumentation/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/open-telemetry%2Fopentelemetry-php-instrumentation/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/open-telemetry","download_url":"https://codeload.github.com/open-telemetry/opentelemetry-php-instrumentation/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247289426,"owners_count":20914464,"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":[],"created_at":"2024-09-27T14:21:55.875Z","updated_at":"2025-04-05T05:05:00.094Z","avatar_url":"https://github.com/open-telemetry.png","language":"C","funding_links":[],"categories":[],"sub_categories":[],"readme":"# OpenTelemetry auto-instrumentation extension\n\n[![Build and test](https://github.com/open-telemetry/opentelemetry-php-instrumentation/actions/workflows/build.yml/badge.svg)](https://github.com/open-telemetry/opentelemetry-php-instrumentation/actions/workflows/build.yml)\n\n## Current Project Status\nFor more information, please consult the documentation of the main [OpenTelemetry PHP project](https://github.com/open-telemetry/opentelemetry-php).\n\n## Issues\n\nIssues have been disabled for this repo in order to help maintain consistency between this repo and the main [OpenTelemetry PHP project](https://github.com/open-telemetry/opentelemetry-php) repo. If you have an issue you'd like to raise about this issue, please use the [OpenTelemetry PHP Issue section](https://github.com/open-telemetry/opentelemetry-php/issues/new/choose). Please prefix the title of the issue with [opentelemetry-php-instrumentation].\n\n## Description\nThis is a PHP extension for OpenTelemetry, to enable auto-instrumentation.\nIt is based on [zend_observer](https://www.datadoghq.com/blog/engineering/php-8-observability-baked-right-in/) and requires php8+\n\nThe extension allows:\n\n- creating `pre` and `post` hook functions to arbitrary PHP functions and methods, which allows those methods to be wrapped with telemetry\n- adding attributes to functions and methods to enable observers at runtime\n\nIn PHP 8.2+, internal/built-in PHP functions can also be observed.\n\n## Requirements\n- PHP 8+\n- [OpenTelemetry PHP library](https://github.com/open-telemetry/opentelemetry-php)\n\n## Installation\n\nThe extension can be installed in all of the usual ways:\n\n### pecl\n\n```shell\npecl install opentelemetry\n```\n\n### php-extension-installer\n\nIf you are using the [official PHP docker images](https://hub.docker.com/_/php) then you can use\n[php-extension-installer](https://github.com/mlocati/docker-php-extension-installer)\n\nFrom github:\n```shell\ninstall-php-extensions opentelemetry-php/ext-opentelemetry@main\n```\n\nVia pecl/pickle:\n```shell\ninstall-php-extensions opentelemetry[-beta|-stable|-latest]\n```\n\n### Windows\n\nPre-built windows binaries are available from the [releases page](https://github.com/open-telemetry/opentelemetry-php-instrumentation/releases)\n\nSee https://wiki.php.net/internals/windows/stepbystepbuild_sdk_2#building_pecl_extensions_with_phpize\nfor generic advice on building from source under Windows.\n\n## Verify that the extension is installed and enabled\n\n```shell\nphp --ri  opentelemetry\n```\n\n## Known issues\n\n### Conflicting extensions\n\nThe extension can be configured to not run if a conflicting extension is installed. The following extensions\nare known to not work when installed alongside OpenTelemetry:\n\n* SourceGuardian\n\nIf the conflicting extension is a regular PHP extension (i.e, not a\n[zend_extension](https://www.phpinternalsbook.com/php7/extensions_design/zend_extensions.html)), you can control\nconflicts via the `opentelemetry.conflicts` ini setting.\n\nIf a conflicting extension is found, then the OpenTelemetry extension will disable itself:\n\n```shell\nphp --ri opentelemetry\n\nNotice: PHP Startup: Conflicting extension found (blackfire), disabling OpenTelemetry in Unknown on line 0\n\nopentelemetry\n\nopentelemetry hooks =\u003e disabled (conflict)\nextension version =\u003e 1.0.0beta6\n\nDirective =\u003e Local Value =\u003e Master Value\nopentelemetry.conflicts =\u003e blackfire =\u003e blackfire\nopentelemetry.validate_hook_functions =\u003e On =\u003e On\n```\n\n### Invalid pre/post hooks\n\nInvalid argument types in `pre` and `post` callbacks can cause fatal errors. Runtime checking is performed on the\nhook functions to ensure they are compatible. If not, the hook will not be executed and an error will be generated.\n\nThis feature can be disabled by setting the `opentelemetry.validate_hook_functions` ini value to `Off`;\n\n### Increasing function argument count\n\nBy default, increasing the number of arguments provided to a function in the pre hook is allowed only if that does\nnot require the stack frame of the function call to be extended in size. For internal functions, adding arguments\nnot provided at the callsite always requires stack extension. For PHP functions, it is required only if the\nargument is not included in the function definition.\n\nExtending stack frame automatically can be enabled by setting `opentelemetry.allow_stack_extension` ini value to `On`.\nThis enables extending the stack frame by up to another 16 arguments.\n\n## Usage\n\nThe `pre` method starts and activates a span. The `post` method ends the span after the observed method has finished.\n\n```php\n\u003c?php\n\n$tracer = new Tracer(...);\n\nOpenTelemetry\\Instrumentation\\hook(\n    DemoClass::class,\n    'run',\n    pre: static function (DemoClass $demo, array $params, string $class, string $function, ?string $filename, ?int $lineno) use ($tracer) {\n        $span = $tracer-\u003espanBuilder($class)\n            -\u003estartSpan();\n        Context::storage()-\u003eattach($span-\u003estoreInContext(Context::getCurrent()));\n    },\n    post: static function (DemoClass $demo, array $params, $returnValue, ?Throwable $exception) use ($tracer) {\n        $scope = Context::storage()-\u003escope();\n        $scope?-\u003edetach();\n        $span = Span::fromContext($scope-\u003econtext());\n        $exception \u0026\u0026 $span-\u003erecordException($exception);\n        $span-\u003esetStatus($exception ? StatusCode::STATUS_ERROR : StatusCode::STATUS_OK);\n        $span-\u003eend();\n    }\n);\n```\n\nThere are more examples in the [tests directory](ext/tests/)\n\n### Static methods\n\nNote that if hooking a static class method, the first parameter to `pre` and `post` callbacks is a `string` containing the method's class name.\n\n### Caveats\n\n- Be aware that trivial functions are candidates for optimizations.\nOptimizer can optimize them out and replace user function call with more optimal set of instructions (inlining).\nIn this case hooks will not be invoked as there will be no function.\n- Hooks must be registered _before_ a function is first executed. You may encounter race conditions where\nthe composer autoloader runs code that uses functions you wish to hook prior to the hooks being registered.\n\n# Modifying parameters, exceptions and return values of the observed function\n\n## Parameters\n\nFrom a `pre` hook function, you may modify the parameters before they are received by the observed function.\nThe arguments are passed in as a numerically-indexed array. The returned array from the `pre` hook is used\nto modify (_not_ replace) the existing parameters:\n\n```php\n\u003c?php\nOpenTelemetry\\Instrumentation\\hook(\n    null,\n    'hello',\n     function($obj, array $params) {\n        return [\n          0 =\u003e null,  //make first param null\n          2 =\u003e 'baz', //replace 3rd param\n          3 =\u003e 'bat', //add 4th param\n        ];\n    }\n);\nfunction hello($one = null, $two = null, $three = null, $four = null) {\n  var_dump(func_get_args());\n}\n\nhello('a', 'b', 'c');\n```\n\ngives output:\n```\narray(4) {\n  [0]=\u003e\n  NULL\n  [1]=\u003e\n  string(1) \"b\"\n  [2]=\u003e\n  string(3) \"baz\"\n  [3]=\u003e\n  string(3) \"bat\"\n}\n```\n\n## Return values\n\n`post` hook methods can modify the observed function's return value:\n\n```php\n\u003c?php\n\\OpenTelemetry\\Instrumentation\\hook(null, 'hello', post: fn(mixed $object, array $params, string $return): int =\u003e ++$return);\n\nfunction hello(int $val) {\n    return $val;\n}\n\nvar_dump(hello(1));\n```\n\ngives output:\n```\nint(2)\n```\n\n*Important*: the post method _must_ provide a return type-hint, otherwise the return value will be ignored. The return type\nhint in the example above is `: int`.\n\n## Exceptions\n\n`post` hook methods can modify an exception thrown from the observed function:\n\n```php\n\u003c?php\n\\OpenTelemetry\\Instrumentation\\hook(null, 'hello', post: function(mixed $object, array $params, mixed $return, ?Throwable $throwable) {\n    throw new Exception('new', previous: $throwable);\n});\n\nfunction hello() {\n    throw new Exception('original');\n}\n\ntry {\n    hello();\n} catch (\\Throwable $t) {\n    var_dump($t-\u003egetMessage());\n    var_dump($t-\u003egetPrevious()?-\u003egetMessage());\n}\n```\n\ngives output:\n```php\nstring(3) \"new\"\nstring(8) \"original\"\n```\n\n## Attribute-based hooking\n\nBy applying attributes to source code, the OpenTelemetry extension can add hooks at runtime.\n\nDefault pre and post hook methods are provided by the OpenTelemetry API: `OpenTelemetry\\API\\Instrumentation\\Handler::pre`\nand `::post`.\n\nThis feature is disabled by default, but can be enabled by setting `opentelemetry.attr_hooks_enabled = On` in php.ini\n\n## Restrictions\n\nAttribute-based hooks can only be applied to a function/method that does not already have\nhooks applied.\nOnly one hook can be applied to a function/method, including via interfaces.\n\nSince the attributes are evaluated at runtime, the extension checks whether a hook already\nexists to decide whether it should apply a new runtime hook.\n\n## Configuration\n\nThis feature can be configured via `.ini` by modifying the following entries:\n\n- `opentelemetry.attr_hooks_enabled` - boolean, default Off\n- `opentelemetry.attr_pre_handler_function` - FQN of pre method/function\n- `opentelemetry.attr_post_handler_function` - FQN of post method/function\n\n## `OpenTelemetry\\API\\Instrumentation\\WithSpan` attribute\n\nThis attribute is provided by the OpenTelemetry API can be applied to a function or class method.\n\nYou can also provide optional parameters to the attribute, which control:\n- span name\n- span kind\n- attributes\n\n```php\nuse OpenTelemetry\\API\\Instrumentation\\WithSpan\n\nclass MyClass\n{\n    #[WithSpan]\n    public function trace_me(): void\n    {\n        /* ... */\n    }\n\n    #[WithSpan('custom_span_name', SpanKind::KIND_INTERNAL, ['my-attr' =\u003e 'value'])]\n    public function trace_me_with_customization(): void\n    {\n        /* ... */\n    }\n}\n\n#[WithSpan]\nfunction my_function(): void\n{\n    /* ... */\n}\n```\n\n## `OpenTelemetry\\API\\Instrumentation\\SpanAttribute` attribute\n\nThis attribute should be used in conjunction with `WithSpan`. It is applied to function/method\nparameters, and causes those parameters and values to be passed through to the `pre` hook function\nwhere they can be added as trace attributes.\nThere is one optional parameter, which controls the attribute key. If not set, the parameter name\nis used.\n\n```php\nuse OpenTelemetry\\API\\Instrumentation\\WithSpan\nuse OpenTelemetry\\API\\Instrumentation\\SpanAttribute\n\nclass MyClass\n{\n    #[WithSpan]\n    public function add_user(\n        #[SpanAttribute] string $username,\n        string $password,\n        #[SpanAttribute('a_better_attribute_name')] string $foo_bar_baz,\n    ): void\n    {\n        /* ... */\n    }\n```\n\n## Contributing\nSee [DEVELOPMENT.md](DEVELOPMENT.md) and https://github.com/open-telemetry/opentelemetry-php/blob/main/CONTRIBUTING.md\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fopen-telemetry%2Fopentelemetry-php-instrumentation","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fopen-telemetry%2Fopentelemetry-php-instrumentation","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fopen-telemetry%2Fopentelemetry-php-instrumentation/lists"}