Compare commits
475 Commits
Author | SHA1 | Date |
---|---|---|
|
4274371493 | |
|
49aca4a36f | |
|
87a145a3b6 | |
|
9fb9e549bf | |
|
d5fd499752 | |
|
d4c16332af | |
|
99a35dadf2 | |
|
7981956060 | |
|
9d68afb238 | |
|
4afe0aad8a | |
|
6d14251299 | |
|
a54f48bbb9 | |
|
e54a43d262 | |
|
9c3ae60164 | |
|
776bed563b | |
|
2d9097492c | |
|
2421c64c51 | |
|
dc52549640 | |
|
7033191a74 | |
|
e27aac84f6 | |
|
3968f7459a | |
|
33715fddc1 | |
|
768c387068 | |
|
526b8eb33d | |
|
443c662653 | |
|
5ed1ec09db | |
|
5451d57dbf | |
|
95229b7bf8 | |
|
04acb40874 | |
|
dcf96ddf96 | |
|
873a39c4fd | |
|
07d1da976a | |
|
78bd695c02 | |
|
65c2979523 | |
|
38351980a6 | |
|
23c3cdae61 | |
|
acf6dc7e5b | |
|
691c0d43ae | |
|
2fcafabc81 | |
|
389fa3fd50 | |
|
5fdfac284a | |
|
f0f5a2a83f | |
|
b5a5ac79ff | |
|
4851a4e03b | |
|
3679ada34e | |
|
91e05d9f1f | |
|
351aa18abe | |
|
39cd6e2f09 | |
|
ab05329ffe | |
|
821b7543c9 | |
|
e2f24eb494 | |
|
39a2b486b1 | |
|
e253da3e8b | |
|
64821d89a5 | |
|
fadec4c8da | |
|
d084288a12 | |
|
1413c3470e | |
|
68b6d4f6ee | |
|
5c0004b515 | |
|
6ed191498e | |
|
59a4f7730b | |
|
2b5ce6c611 | |
|
8028f9715f | |
|
5899a9e287 | |
|
a354f46612 | |
|
015da800aa | |
|
968083597f | |
|
08c88605b4 | |
|
68462e0bb2 | |
|
88c79091ca | |
|
656f5db415 | |
|
8316c50e93 | |
|
66c8ce8059 | |
|
5d24db8fca | |
|
31d902b6c6 | |
|
96ce422b6a | |
|
3e8ae81e35 | |
|
420b5ef6df | |
|
e3f77b7ada | |
|
b24a30c31a | |
|
7eb3abb276 | |
|
a4119f9e32 | |
|
29b7da48c4 | |
|
83cddd9157 | |
|
4b575e6b6c | |
|
32e301ea6a | |
|
7aa3e02eb0 | |
|
b515b6b6ff | |
|
f73bcfa22c | |
|
4a021fbaec | |
|
f1c982734b | |
|
8857b0c103 | |
|
7b5cbb5078 | |
|
38633fba0e | |
|
ea908b161d | |
|
39cc549f04 | |
|
1aae9dd619 | |
|
93f2068d0b | |
|
fd654b99c7 | |
|
d2b15077df | |
|
01d0fd3618 | |
|
2c1da9aaec | |
|
c632d960a5 | |
|
f29277abc0 | |
|
cd8c0e3124 | |
|
0ae272373d | |
|
fd24607c10 | |
|
20bf3cff3e | |
|
91f4735b3a | |
|
7d744e0086 | |
|
439447b286 | |
|
6a2242d46a | |
|
8ed62b1e43 | |
|
3be58cff57 | |
|
068086347b | |
|
bee9c64ae9 | |
|
4fc170002d | |
|
653e453f95 | |
|
f4b52c4b49 | |
|
5276df3171 | |
|
69825d395a | |
|
80e97da6eb | |
|
41dd113030 | |
|
382331e062 | |
|
d2ec5e6d0b | |
|
10b8d9732b | |
|
68b1b43cab | |
|
4ed0d870f7 | |
|
1271f1ed69 | |
|
e4f9604411 | |
|
17ad56a3f3 | |
|
a822c455a4 | |
|
36f29a37cb | |
|
b6f9afb5af | |
|
a90f18cc72 | |
|
fc28032748 | |
|
6bf422c0f1 | |
|
eebf23a21d | |
|
600d8a5f53 | |
|
39f81a3cc6 | |
|
eaba9e3228 | |
|
fbdb103590 | |
|
4f32817065 | |
|
500f6ee1bd | |
|
8031c78512 | |
|
8e810c6598 | |
|
82b191b984 | |
|
100e593bd6 | |
|
80114317f8 | |
|
5747fac40c | |
|
f2cba82c28 | |
|
fc161a8548 | |
|
9fe6aa0cd7 | |
|
cea2d7c4cb | |
|
8a6dd4750d | |
|
5a395e09da | |
|
5019361068 | |
|
43339294f5 | |
|
fda522a90b | |
|
6cd7a8af2c | |
|
e44f5a97d9 | |
|
bb9eb40a50 | |
|
7ec0e90402 | |
|
6dd255deac | |
|
a1489d3081 | |
|
639d8e2561 | |
|
4cb04999d9 | |
|
1753fbe32b | |
|
01c46a2350 | |
|
bb07aca7a2 | |
|
f798bb6f01 | |
|
cc56628c4d | |
|
258e58644a | |
|
b20c45df10 | |
|
1f187c7837 | |
|
e522d9d81f | |
|
36e2b7f613 | |
|
91f5e20ffc | |
|
84cf0a5635 | |
|
f2ab3c5e1d | |
|
810aa2f95a | |
|
1af83342f7 | |
|
102f5dc187 | |
|
2390dc07b0 | |
|
521940d988 | |
|
3928b13152 | |
|
25726f6cb9 | |
|
925ae9b12f | |
|
596d4a2cea | |
|
82c0f8ed59 | |
|
a196c13425 | |
|
7c45db059d | |
|
bf8119c420 | |
|
4ff6ae4dbe | |
|
d4149990a3 | |
|
d8827f9681 | |
|
d3765662f9 | |
|
a6d15cf26e | |
|
a568dde3f3 | |
|
28657a9ec1 | |
|
d6c4c89bf4 | |
|
30b73d948c | |
|
42a8b95501 | |
|
a325a8f0bd | |
|
842aa4121d | |
|
f22ffa0137 | |
|
ea86fe1891 | |
|
b5170bf202 | |
|
75bb45fa71 | |
|
8809c2a0b5 | |
|
3032304c3b | |
|
1852d514ca | |
|
73ff5adcb8 | |
|
197a7a4c2c | |
|
62a14d1c20 | |
|
82f0c4477e | |
|
55c08f3f44 | |
|
9f358617f1 | |
|
c61f148d64 | |
|
ff15cc7037 | |
|
7b8daff5ef | |
|
1905dbfcd5 | |
|
4d9720f19e | |
|
29cff8b991 | |
|
926f6e5583 | |
|
cf8be76463 | |
|
a60d0ad80c | |
|
da219a9829 | |
|
5853adabf1 | |
|
c9c83117e7 | |
|
3246ca8e4d | |
|
cc92a07eac | |
|
638799275c | |
|
5e827ab7fc | |
|
cb45b4a75d | |
|
d6e0689604 | |
|
a0601c41ec | |
|
dc9501e8a9 | |
|
49638eae02 | |
|
58e19760e3 | |
|
51137bfea6 | |
|
fed6413a76 | |
|
4913926ec1 | |
|
29dc1a414f | |
|
8fe898bdb4 | |
|
1caf77b436 | |
|
1aea1f23b9 | |
|
d81874ed11 | |
|
ea09e53519 | |
|
22542528af | |
|
e8ee4363e7 | |
|
2601eaafe8 | |
|
32c161b167 | |
|
6a77cf5ba4 | |
|
23cc194da1 | |
|
1b63a3b1c3 | |
|
82b30dc437 | |
|
65491ab66b | |
|
5d35c998e7 | |
|
593fa344bc | |
|
e7be05c73e | |
|
bd02259089 | |
|
efe696f285 | |
|
c701693c25 | |
|
952c069792 | |
|
1976f53f92 | |
|
4890bd4a27 | |
|
77da9503fb | |
|
a7a28616b2 | |
|
6fd6a3c180 | |
|
9bccde9f03 | |
|
80ac91fddd | |
|
659a705d95 | |
|
8f70a6d19f | |
|
0e61e95f3c | |
|
23762dbbd3 | |
|
a06e5e4e45 | |
|
c687df160d | |
|
e22007a98e | |
|
653a726959 | |
|
ca2df9f307 | |
|
72e9f56fbb | |
|
502df0eded | |
|
a3abdcdb0d | |
|
0a6d7cb8e4 | |
|
dd23c8d0ea | |
|
711ebf98c6 | |
|
4544cbd94a | |
|
83bacc9d40 | |
|
a2a4d4d0a1 | |
|
c899f08dc1 | |
|
41945220b9 | |
|
ac1d03784f | |
|
615917f5d4 | |
|
c058a646f6 | |
|
0538a5a7c7 | |
|
640b6f53a0 | |
|
88ea7c3024 | |
|
746d25a7d1 | |
|
20f39b6a74 | |
|
da05ab83ce | |
|
2a0a9e33e6 | |
|
19b9326751 | |
|
5f3e9cae9d | |
|
c6b0be7c89 | |
|
e59f2c3cff | |
|
24af6ac173 | |
|
c4161a0ebe | |
|
4b9f1200bf | |
|
7b5ca0ce97 | |
|
ee26eaa5d8 | |
|
2bd6bc5ff7 | |
|
558e7ce30e | |
|
c98866b3fa | |
|
425ebaf4f9 | |
|
02c1782667 | |
|
616b356b83 | |
|
602ea8539f | |
|
0073d6dfe6 | |
|
5a51249c6b | |
|
f5698c8864 | |
|
7bfc1218d6 | |
|
02d94216e1 | |
|
311afa265a | |
|
dc5ef24bd3 | |
|
a1e8aff01e | |
|
587bc5aaf0 | |
|
fd8ac30f07 | |
|
0ce2fda813 | |
|
2e96621b0f | |
|
80afb1d948 | |
|
017c3e1c76 | |
|
c735471aef | |
|
1ffd7e80eb | |
|
17f2fac397 | |
|
d37d4490d9 | |
|
01378ecf8a | |
|
22c78cfd3b | |
|
904da75ee6 | |
|
116e46d964 | |
|
f083b10909 | |
|
92e7a0d070 | |
|
0b43fac729 | |
|
ba9899278f | |
|
87989731ed | |
|
32d04f6a1d | |
|
4489eeca2e | |
|
f6777575de | |
|
f6671ddd79 | |
|
f73a835ed2 | |
|
10830f2683 | |
|
3866a82d92 | |
|
a167add2df | |
|
47f8ab977d | |
|
7940773a31 | |
|
8562d0d510 | |
|
a3a47a6ba4 | |
|
0e0c67d326 | |
|
215731f639 | |
|
c0a62795e4 | |
|
be3f88fa6c | |
|
deeb07a890 | |
|
15ebaeb98c | |
|
b551294d3f | |
|
84142d35e9 | |
|
c000590a53 | |
|
6196d7a809 | |
|
ad3ccd8139 | |
|
f5e66e91dd | |
|
776273ca8a | |
|
6e385b96f9 | |
|
ac3a35d85c | |
|
651f949cd8 | |
|
2cb5d6b0df | |
|
e6e13b2561 | |
|
c3170e3bd2 | |
|
9c8ce2fa91 | |
|
ea83a0cff3 | |
|
77838b3b9c | |
|
0f308492a1 | |
|
2457c76015 | |
|
74eda3d89d | |
|
cb002a80b1 | |
|
d05ea65186 | |
|
4dd375fdb8 | |
|
3ac64f6a28 | |
|
d0a600fb68 | |
|
0013e472a0 | |
|
c62d443c74 | |
|
e946dc7b9d | |
|
2f6658f101 | |
|
73f5106fd3 | |
|
bf912ed7bd | |
|
32c43840f7 | |
|
08c9180b6d | |
|
5a64c0d000 | |
|
7f2e974972 | |
|
ea5b7c153e | |
|
d3facad7b5 | |
|
90036b1c7e | |
|
ae6b620489 | |
|
37a8c8efa1 | |
|
82b0135695 | |
|
f33b623683 | |
|
24ada8c270 | |
|
6a14cf9e28 | |
|
305c1c7a12 | |
|
8e30ea0762 | |
|
19e09f53ca | |
|
aaa93eed7a | |
|
b973c52162 | |
|
5f318cdb7a | |
|
47ee3e9e80 | |
|
e3564e2fe9 | |
|
4c10268162 | |
|
7c0c71ccab | |
|
739f212ba9 | |
|
409dd52c40 | |
|
79ff159c94 | |
|
13ce2da243 | |
|
06d74a737e | |
|
b2a7b62b2a | |
|
5c3109ae4d | |
|
0e4ad525c4 | |
|
41f74d2aff | |
|
025b239adc | |
|
8f7f399f12 | |
|
122aff0c74 | |
|
ac95256062 | |
|
6b80fd1340 | |
|
31bdeaa8f1 | |
|
a22f9f1077 | |
|
345f8bf35b | |
|
3c6c53bf2f | |
|
90edbd3a58 | |
|
f3e9bdbe7c | |
|
3fb033d86b | |
|
3ca87a8878 | |
|
7dda601851 | |
|
60f7045c1f | |
|
e728c53065 | |
|
88db9039fa | |
|
2070be6116 | |
|
a8a6025382 | |
|
e3736450d4 | |
|
f3aedcdb60 | |
|
40775bc61f | |
|
499c58adab | |
|
17264f7caa | |
|
1326f17eb6 | |
|
8b63849da4 | |
|
2e4c849b2f | |
|
85282b5af4 | |
|
25cfcfb6e9 | |
|
8ae46f20e1 | |
|
4592a27cdf | |
|
4e3264578b | |
|
9138d78b8f | |
|
5de0986f86 | |
|
1d5283b9e4 | |
|
6d993586b0 | |
|
7ce599bab1 | |
|
c242c37db0 | |
|
99fba0d720 | |
|
57076b50d5 | |
|
e096e529bb | |
|
72816bb324 | |
|
80a6d63f51 | |
|
5f71d3cfe3 | |
|
445e932ee0 | |
|
f2ad2fcb5b | |
|
0bc3731ca6 | |
|
169bdbee57 | |
|
ca05f51481 | |
|
178cc9e292 |
|
@ -12,7 +12,9 @@ trim_trailing_whitespace = true
|
|||
[*.md]
|
||||
trim_trailing_whitespace = false
|
||||
|
||||
[docker-compose.*.yaml]
|
||||
[*.yaml]
|
||||
indent_size = 2
|
||||
[*.yml]
|
||||
indent_size = 2
|
||||
|
||||
[Makefile]
|
||||
|
|
|
@ -1,2 +1,5 @@
|
|||
PHP_USER=php
|
||||
XDEBUG_MODE=debug
|
||||
PHP_CS_FIXER_IGNORE_ENV=true
|
||||
#docker-compose or "docker compose" for v1/v2 respectively, note that v1 support ends 06/2023
|
||||
DOCKER_COMPOSE=docker compose
|
||||
|
|
|
@ -17,3 +17,5 @@ What did you see instead?
|
|||
|
||||
**Additional context**
|
||||
Add any other context about the problem here.
|
||||
|
||||
<sub>**Tip**: [React](https://github.blog/news-insights/product-news/add-reactions-to-pull-requests-issues-and-comments/) with 👍 to help prioritize this issue. Please use comments to provide useful context, avoiding `+1` or `me too`, to help us triage it. Learn more [here](https://opentelemetry.io/community/end-user/issue-participation/).</sub>
|
||||
|
|
|
@ -17,3 +17,5 @@ Which alternative solutions or features have you considered?
|
|||
|
||||
**Additional context**
|
||||
Add any other context about the feature request here.
|
||||
|
||||
<sub>**Tip**: [React](https://github.blog/news-insights/product-news/add-reactions-to-pull-requests-issues-and-comments/) with 👍 to help prioritize this issue. Please use comments to provide useful context, avoiding `+1` or `me too`, to help us triage it. Learn more [here](https://opentelemetry.io/community/end-user/issue-participation/).</sub>
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
# configuration for new-issue-welcome bot https://github.com/behaviorbot/new-issue-welcome
|
||||
newPRWelcomeComment: >
|
||||
Thanks for opening your first pull request! If you haven't yet signed our Contributor License Agreement (CLA),
|
||||
then please do so that we can accept your contribution.
|
||||
A link should appear shortly in this PR if you have not already signed one.
|
|
@ -0,0 +1,22 @@
|
|||
---
|
||||
version: 2
|
||||
updates:
|
||||
- package-ecosystem: "composer"
|
||||
directory: "/"
|
||||
schedule:
|
||||
interval: "daily"
|
||||
|
||||
- package-ecosystem: "docker"
|
||||
directory: "/docker"
|
||||
schedule:
|
||||
interval: "daily"
|
||||
|
||||
- package-ecosystem: "github-actions"
|
||||
directory: "/"
|
||||
schedule:
|
||||
interval: "daily"
|
||||
|
||||
- package-ecosystem: "docker-compose"
|
||||
directory: "/"
|
||||
schedule:
|
||||
interval: "daily"
|
|
@ -0,0 +1,20 @@
|
|||
name: FOSSA scanning
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
fossa:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
||||
|
||||
- uses: fossas/fossa-action@3ebcea1862c6ffbd5cf1b4d0bd6b3fe7bd6f2cac # v1.7.0
|
||||
with:
|
||||
api-key: ${{secrets.FOSSA_API_KEY}}
|
||||
team: OpenTelemetry
|
|
@ -0,0 +1,50 @@
|
|||
name: OSSF Scorecard
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
schedule:
|
||||
- cron: "17 0 * * 1" # once a week
|
||||
workflow_dispatch:
|
||||
|
||||
permissions: read-all
|
||||
|
||||
jobs:
|
||||
analysis:
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
# Needed for Code scanning upload
|
||||
security-events: write
|
||||
# Needed for GitHub OIDC token if publish_results is true
|
||||
id-token: write
|
||||
steps:
|
||||
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
||||
with:
|
||||
persist-credentials: false
|
||||
|
||||
- uses: ossf/scorecard-action@05b42c624433fc40578a4040d5cf5e36ddca8cde # v2.4.2
|
||||
with:
|
||||
results_file: results.sarif
|
||||
results_format: sarif
|
||||
publish_results: true
|
||||
# file_mode is needed in this repo because .gitattributes excludes the .github directory
|
||||
# (see https://github.com/ossf/scorecard/issues/4679#issuecomment-3013550752)
|
||||
file_mode: git
|
||||
|
||||
# Upload the results as artifacts (optional). Commenting out will disable
|
||||
# uploads of run results in SARIF format to the repository Actions tab.
|
||||
# https://docs.github.com/en/actions/advanced-guides/storing-workflow-data-as-artifacts
|
||||
- name: "Upload artifact"
|
||||
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
|
||||
with:
|
||||
name: SARIF file
|
||||
path: results.sarif
|
||||
retention-days: 5
|
||||
|
||||
# Upload the results to GitHub's code scanning dashboard (optional).
|
||||
# Commenting out will disable upload of results to your repo's Code Scanning dashboard
|
||||
- name: "Upload to code-scanning"
|
||||
uses: github/codeql-action/upload-sarif@76621b61decf072c1cee8dd1ce2d2a82d33c17ed # v3.29.5
|
||||
with:
|
||||
sarif_file: results.sarif
|
|
@ -1,5 +1,4 @@
|
|||
|
||||
name: PHP Composer
|
||||
name: PHP QA
|
||||
|
||||
on:
|
||||
push:
|
||||
|
@ -7,30 +6,70 @@ on:
|
|||
pull_request:
|
||||
branches: [ main ]
|
||||
|
||||
jobs:
|
||||
build:
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
runs-on: ${{ matrix.os }}
|
||||
jobs:
|
||||
php:
|
||||
runs-on: ubuntu-latest
|
||||
continue-on-error: ${{ matrix.experimental }}
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
php-version: ['7.4', '8.0']
|
||||
os: [ubuntu-latest]
|
||||
extensions: ['ast, grpc', 'ast, grpc, protobuf']
|
||||
php-version: ['8.1', '8.2', '8.3']
|
||||
experimental: [false]
|
||||
composer_args: [""]
|
||||
include:
|
||||
- php-version: 8.1
|
||||
extensions: 'ast, grpc'
|
||||
os: ubuntu-latest
|
||||
experimental: true
|
||||
- php-version: 8.1
|
||||
extensions: 'ast, grpc, protobuf'
|
||||
os: ubuntu-latest
|
||||
- php-version: 8.4
|
||||
experimental: false
|
||||
composer_args: "--ignore-platform-reqs"
|
||||
- php-version: 8.5
|
||||
experimental: true
|
||||
composer_args: "--ignore-platform-reqs"
|
||||
env:
|
||||
extensions: ast, grpc, opentelemetry, protobuf
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Set cache key
|
||||
id: key
|
||||
run: |
|
||||
echo "key=$(date +'%Y-%U')" >> $GITHUB_ENV
|
||||
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- uses: gacts/run-and-post-run@v1
|
||||
id: post-run-command
|
||||
with:
|
||||
post: |
|
||||
echo "::group::Steps"
|
||||
echo "composer=${{steps.composer.outcome}}"
|
||||
echo "style=${{steps.style.outcome}}"
|
||||
echo "deps=${{steps.deps.outcome}}"
|
||||
echo "phan=${{steps.phan.outcome}}"
|
||||
echo "psalm=${{steps.psalm.outcome}}"
|
||||
echo "phpstan=${{steps.phpstan.outcome}}"
|
||||
echo "unit=${{steps.unit.outcome}}"
|
||||
echo "integration=${{steps.integration.outcome}}"
|
||||
echo "::endgroup::"
|
||||
|
||||
if [ ${{ steps.composer.outcome == 'failure' || steps.style.outcome == 'failure' || steps.deps.outcome == 'failure' || steps.phan.outcome == 'failure' || steps.psalm.outcome == 'failure' || steps.phpstan.outcome == 'failure' || steps.unit.outcome == 'failure' || steps.integration.outcome == 'failure' }} == true ]; then \
|
||||
echo "::error::One or more steps failed"; \
|
||||
fi
|
||||
|
||||
- name: Setup cache environment
|
||||
id: extcache
|
||||
uses: shivammathur/cache-extensions@v1
|
||||
with:
|
||||
php-version: ${{ matrix.php-version }}
|
||||
extensions: ${{ env.extensions }}
|
||||
key: ${{ env.key }}
|
||||
|
||||
- name: Cache extensions
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: ${{ steps.extcache.outputs.dir }}
|
||||
key: ${{ steps.extcache.outputs.key }}
|
||||
restore-keys: ${{ steps.extcache.outputs.key }}
|
||||
|
||||
- name: Setup PHP
|
||||
uses: shivammathur/setup-php@v2
|
||||
|
@ -38,49 +77,99 @@ jobs:
|
|||
php-version: ${{ matrix.php-version }}
|
||||
coverage: xdebug
|
||||
tools: php-cs-fixer
|
||||
extensions: ${{ matrix.extensions }}
|
||||
extensions: ${{ env.extensions }}
|
||||
|
||||
- name: Validate composer.json and composer.lock
|
||||
- name: Validate composer.json
|
||||
run: composer validate
|
||||
|
||||
- name: Cache Composer packages
|
||||
id: composer-cache
|
||||
uses: actions/cache@v2
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: vendor
|
||||
key: ${{ runner.os }}-php-${{ hashFiles('**/composer.json') }}
|
||||
key: ${{ runner.os }}-${{ matrix.php-version }}-vendor-${{ hashFiles('composer.json') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-php-
|
||||
${{ runner.os }}-${{ matrix.php-version }}-vendor-
|
||||
- name: Cache test tools
|
||||
id: test-tools-cache
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: vendor-bin
|
||||
key: ${{ runner.os }}-${{ matrix.php-version }}-vendor-bin-${{ hashFiles('vendor-bin/*/composer.json') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-${{ matrix.php-version }}-vendor-bin-
|
||||
|
||||
- name: Install dependencies
|
||||
id: composer
|
||||
if: steps.composer-cache.outputs.cache-hit != 'true'
|
||||
run: composer install --prefer-dist --no-progress --no-suggest
|
||||
|
||||
- name: Update Composer
|
||||
run: composer update
|
||||
run: |
|
||||
composer --version
|
||||
composer install --prefer-dist --no-progress ${{ matrix.composer_args }}
|
||||
|
||||
- name: Check Style
|
||||
run: vendor/bin/php-cs-fixer fix --config=.php-cs-fixer.php --dry-run --stop-on-violation --using-cache=no -vvv
|
||||
id: style
|
||||
continue-on-error: ${{ matrix.experimental }}
|
||||
env:
|
||||
PHP_CS_FIXER_IGNORE_ENV: 1
|
||||
run: |
|
||||
vendor-bin/php-cs-fixer/vendor/bin/php-cs-fixer --version
|
||||
vendor-bin/php-cs-fixer/vendor/bin/php-cs-fixer fix --config=.php-cs-fixer.php --dry-run --stop-on-violation --using-cache=no -vvv
|
||||
|
||||
- name: Check Dependencies
|
||||
run: vendor/bin/deptrac --formatter=github-actions
|
||||
id: deps
|
||||
continue-on-error: ${{ matrix.experimental }}
|
||||
run: |
|
||||
vendor-bin/deptrac/vendor/bin/deptrac --version
|
||||
vendor-bin/deptrac/vendor/bin/deptrac --formatter=github-actions --report-uncovered
|
||||
|
||||
- name: Run Phan
|
||||
id: phan
|
||||
continue-on-error: ${{ matrix.experimental }}
|
||||
env:
|
||||
XDEBUG_MODE: off
|
||||
PHAN_DISABLE_XDEBUG_WARN: 1
|
||||
run: vendor/bin/phan
|
||||
run: |
|
||||
vendor-bin/phan/vendor/bin/phan --version
|
||||
vendor-bin/phan/vendor/bin/phan
|
||||
|
||||
- name: Run Psalm
|
||||
run: vendor/bin/psalm --output-format=github
|
||||
id: psalm
|
||||
continue-on-error: ${{ matrix.experimental }}
|
||||
run: |
|
||||
vendor-bin/psalm/vendor/bin/psalm --version
|
||||
vendor-bin/psalm/vendor/bin/psalm --output-format=github
|
||||
|
||||
- name: Run Phpstan
|
||||
run: vendor/bin/phpstan analyse --error-format=github
|
||||
id: phpstan
|
||||
continue-on-error: ${{ matrix.experimental }}
|
||||
run: |
|
||||
vendor/bin/phpstan --version
|
||||
vendor/bin/phpstan analyse --error-format=github
|
||||
|
||||
- name: Run PHPUnit (unit tests)
|
||||
run: vendor/bin/phpunit --coverage-text --coverage-clover=coverage.clover --testsuite unit
|
||||
id: unit
|
||||
continue-on-error: ${{ matrix.experimental }}
|
||||
run: |
|
||||
vendor/bin/phpunit --version
|
||||
php -dzend.assertions=1 vendor/bin/phpunit --coverage-text --coverage-clover=coverage.clover --testsuite unit
|
||||
|
||||
- name: Run PHPUnit (integration tests)
|
||||
id: integration
|
||||
continue-on-error: ${{ matrix.experimental }}
|
||||
run: vendor/bin/phpunit --testsuite integration
|
||||
|
||||
- name: Code Coverage
|
||||
run: bash <(curl -s https://codecov.io/bash) -F ${{ matrix.php-version }}
|
||||
uses: codecov/codecov-action@v5
|
||||
with:
|
||||
token: ${{ secrets.CODECOV_TOKEN }}
|
||||
files: ./coverage.clover
|
||||
flags: ${{ matrix.php-version }}
|
||||
verbose: false
|
||||
|
||||
packages:
|
||||
uses: opentelemetry-php/gh-workflows/.github/workflows/validate-packages.yml@main
|
||||
needs: php
|
||||
with:
|
||||
matrix_extension: '["ast, json, grpc"]'
|
||||
matrix_php_version: '["8.1", "8.2", "8.3"]'
|
||||
install_directory: '~/.test/.packages'
|
||||
|
|
|
@ -0,0 +1,34 @@
|
|||
name: "Generate API Documentation"
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- "main"
|
||||
workflow_dispatch:
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
documentation:
|
||||
permissions:
|
||||
pages: write # required for GitHub Pages deployment
|
||||
id-token: write # required for GitHub Pages deployment
|
||||
name: "Documentation"
|
||||
runs-on: "ubuntu-latest"
|
||||
steps:
|
||||
- name: "Checkout"
|
||||
uses: "actions/checkout@v4"
|
||||
- name: "Build"
|
||||
uses: "phpDocumentor/phpDocumentor@v3.8.1"
|
||||
with:
|
||||
target: "docs/build"
|
||||
- name: Setup Pages
|
||||
uses: actions/configure-pages@v5
|
||||
- name: Upload artifact
|
||||
uses: actions/upload-pages-artifact@v3
|
||||
with:
|
||||
path: 'docs/build'
|
||||
- name: Deploy to GitHub Pages
|
||||
id: deployment
|
||||
uses: actions/deploy-pages@v4
|
|
@ -1,29 +0,0 @@
|
|||
---
|
||||
name: Psalm Security Analysis
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
branches: [main]
|
||||
paths-ignore:
|
||||
- '**/*.md'
|
||||
- '**/*.txt'
|
||||
jobs:
|
||||
psalm:
|
||||
name: Psalm
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v2
|
||||
|
||||
- name: Psalm
|
||||
uses: docker://vimeo/psalm-github-actions
|
||||
with:
|
||||
composer_require_dev: true
|
||||
composer_ignore_platform_reqs: true
|
||||
security_analysis: true
|
||||
report_file: results.sarif
|
||||
|
||||
- name: Upload Security Analysis results to GitHub
|
||||
uses: github/codeql-action/upload-sarif@v1
|
||||
with:
|
||||
sarif_file: results.sarif
|
|
@ -3,35 +3,57 @@ on:
|
|||
schedule:
|
||||
- cron: "0 0 * * 0"
|
||||
workflow_dispatch:
|
||||
push:
|
||||
paths:
|
||||
- docker/Dockerfile
|
||||
- .github/workflows/publish-otel-php-base-docker-image.yml
|
||||
pull_request:
|
||||
paths:
|
||||
- docker/Dockerfile
|
||||
- .github/workflows/publish-otel-php-base-docker-image.yml
|
||||
permissions:
|
||||
contents: read
|
||||
jobs:
|
||||
push_to_registry:
|
||||
name: OpenTelemetry PHP base docker image creation
|
||||
strategy:
|
||||
matrix:
|
||||
php-version: ['7.4', '8.0', '8.1']
|
||||
php-version: ['8.1', '8.2', '8.3', '8.4']
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
packages: write
|
||||
contents: read
|
||||
timeout-minutes: 500
|
||||
steps:
|
||||
|
||||
- name: check out the repo
|
||||
uses: actions/checkout@v2
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v1
|
||||
uses: docker/setup-buildx-action@v3
|
||||
|
||||
- name: Login to GitHub Container Registry
|
||||
uses: docker/login-action@v1
|
||||
uses: docker/login-action@v3
|
||||
with:
|
||||
registry: ghcr.io
|
||||
username: ${{ github.repository_owner }}
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Build and push ${{ matrix.php-version }} to ghcr.io
|
||||
uses: docker/build-push-action@v2
|
||||
uses: docker/build-push-action@v6
|
||||
if: github.ref != 'refs/heads/main'
|
||||
with:
|
||||
push: false
|
||||
file: docker/Dockerfile
|
||||
build-args: PHP_VERSION=${{ matrix.php-version }}
|
||||
platforms: linux/amd64,linux/arm/v8,linux/arm64
|
||||
|
||||
- name: Build and push ${{ matrix.php-version }} to ghcr.io
|
||||
uses: docker/build-push-action@v6
|
||||
if: github.ref == 'refs/heads/main'
|
||||
with:
|
||||
push: true
|
||||
file: docker/Dockerfile
|
||||
build-args: PHP_VERSION=${{ matrix.php-version }}
|
||||
platforms: linux/amd64,linux/arm/v8,linux/arm64
|
||||
tags: ghcr.io/open-telemetry/opentelemetry-php/opentelemetry-php-base:${{ matrix.php-version }}
|
||||
|
|
|
@ -0,0 +1,22 @@
|
|||
name: Shellcheck
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ main ]
|
||||
pull_request:
|
||||
branches: [ main ]
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
shellcheck:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Install shellcheck
|
||||
run: sudo apt update && sudo apt install --assume-yes shellcheck
|
||||
|
||||
- name: Run shellcheck
|
||||
run: find . -name \*.sh | xargs shellcheck --severity=warning
|
|
@ -0,0 +1,26 @@
|
|||
name: gitsplit
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
- split
|
||||
release:
|
||||
types: [published]
|
||||
create:
|
||||
workflow_dispatch:
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
gitsplit:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: checkout
|
||||
run: git clone "$GITHUB_SERVER_URL/$GITHUB_REPOSITORY" "$GITHUB_WORKSPACE" && cd "$GITHUB_WORKSPACE" && git checkout $GITHUB_SHA
|
||||
- name: Split repositories
|
||||
uses: docker://jderusse/gitsplit:latest
|
||||
with:
|
||||
args: gitsplit
|
||||
env:
|
||||
GH_TOKEN: ${{ secrets.GITSPLIT_TOKEN }}
|
|
@ -2,6 +2,8 @@ composer.phar
|
|||
composer.lock
|
||||
var/
|
||||
vendor/
|
||||
vendor-bin/**/vendor/
|
||||
vendor-bin/**/composer.lock
|
||||
coverage.clover
|
||||
tests/coverage
|
||||
.php-cs-fixer.cache
|
||||
|
@ -28,3 +30,9 @@ tests/TraceContext/W3CTestService/trace-context
|
|||
|
||||
# deptrac cache
|
||||
/.deptrac.cache
|
||||
|
||||
# output from phpdoc
|
||||
docs/build
|
||||
|
||||
# cache from phpdoc
|
||||
.phpdoc
|
||||
|
|
|
@ -0,0 +1,37 @@
|
|||
# Path to a cache directory Used to speed up the split over time by reusing git's objects
|
||||
cache_url: "/cache/gitsplit"
|
||||
|
||||
# Path to the repository to split (default = current path)
|
||||
project_url: "https://github.com/open-telemetry/opentelemetry-php.git"
|
||||
|
||||
# List of splits.
|
||||
splits:
|
||||
- prefix: "proto/otel"
|
||||
target: "https://${GH_TOKEN}@github.com/opentelemetry-php/gen-otlp-protobuf.git"
|
||||
- prefix: "src/Context"
|
||||
target: "https://${GH_TOKEN}@github.com/opentelemetry-php/context.git"
|
||||
- prefix: "src/SemConv"
|
||||
target: "https://${GH_TOKEN}@github.com/opentelemetry-php/sem-conv.git"
|
||||
- prefix: "src/API"
|
||||
target: "https://${GH_TOKEN}@github.com/opentelemetry-php/api.git"
|
||||
- prefix: "src/SDK"
|
||||
target: "https://${GH_TOKEN}@github.com/opentelemetry-php/sdk.git"
|
||||
- prefix: "src/Config/SDK"
|
||||
target: "https://${GH_TOKEN}@github.com/opentelemetry-php/config-sdk.git"
|
||||
- prefix: "src/Contrib/Otlp"
|
||||
target: "https://${GH_TOKEN}@github.com/opentelemetry-php/exporter-otlp.git"
|
||||
- prefix: "src/Contrib/Grpc"
|
||||
target: "https://${GH_TOKEN}@github.com/opentelemetry-php/transport-grpc.git"
|
||||
- prefix: "src/Contrib/Zipkin"
|
||||
target: "https://${GH_TOKEN}@github.com/opentelemetry-php/exporter-zipkin.git"
|
||||
- prefix: "src/Extension/Propagator/B3"
|
||||
target: "https://${GH_TOKEN}@github.com/opentelemetry-php/extension-propagator-b3.git"
|
||||
- prefix: "src/Extension/Propagator/CloudTrace"
|
||||
target: "https://${GH_TOKEN}@github.com/opentelemetry-php/extension-propagator-cloudtrace.git"
|
||||
- prefix: "src/Extension/Propagator/Jaeger"
|
||||
target: "https://${GH_TOKEN}@github.com/opentelemetry-php/extension-propagator-jaeger.git"
|
||||
|
||||
# List of references to split (defined as regexp)
|
||||
origins:
|
||||
- ^main$
|
||||
- ^split$
|
|
@ -1,5 +1,7 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
use Phan\Issue;
|
||||
|
||||
/**
|
||||
|
@ -42,7 +44,7 @@ return [
|
|||
//
|
||||
// Note that the **only** effect of choosing `'5.6'` is to infer that functions removed in php 7.0 exist.
|
||||
// (See `backward_compatibility_checks` for additional options)
|
||||
'target_php_version' => '7.4',
|
||||
'target_php_version' => '8.1',
|
||||
|
||||
// If enabled, missing properties will be created when
|
||||
// they are first seen. If false, we'll report an
|
||||
|
@ -278,7 +280,14 @@ return [
|
|||
|
||||
// Add any issue types (such as `'PhanUndeclaredMethod'`)
|
||||
// to this deny-list to inhibit them from being reported.
|
||||
'suppress_issue_types' => [],
|
||||
'suppress_issue_types' => [
|
||||
'PhanAccessClassInternal',
|
||||
'PhanAccessMethodInternal',
|
||||
'PhanAccessPropertyInternal',
|
||||
'PhanTypeMismatchPropertyReal',
|
||||
'PhanTemplateTypeNotUsedInFunctionReturn',
|
||||
'PhanUndeclaredClassAttribute',
|
||||
],
|
||||
|
||||
// A regular expression to match files to be excluded
|
||||
// from parsing and analysis and will not be read at all.
|
||||
|
@ -294,7 +303,9 @@ return [
|
|||
//
|
||||
// This is useful for excluding hopelessly unanalyzable
|
||||
// files that can't be removed for whatever reason.
|
||||
'exclude_file_list' => [],
|
||||
'exclude_file_list' => [
|
||||
'vendor/composer/composer/src/Composer/InstalledVersions.php',
|
||||
],
|
||||
|
||||
// A directory list that defines files that will be excluded
|
||||
// from static analysis, but whose class and method
|
||||
|
@ -310,7 +321,7 @@ return [
|
|||
'exclude_analysis_directory_list' => [
|
||||
'vendor/',
|
||||
'proto/',
|
||||
'thrift/'
|
||||
'src/Config/SDK',
|
||||
],
|
||||
|
||||
// Enable this to enable checks of require/include statements referring to valid paths.
|
||||
|
@ -359,19 +370,19 @@ return [
|
|||
// your application should be included in this list.
|
||||
'directory_list' => [
|
||||
'src',
|
||||
'proto',
|
||||
'thrift',
|
||||
'vendor/packaged/thrift',
|
||||
'proto/otel/GPBMetadata',
|
||||
'proto/otel/Opentelemetry',
|
||||
'vendor/composer',
|
||||
'vendor/grpc/grpc/src/lib',
|
||||
'vendor/guzzlehttp',
|
||||
'vendor/tbachert/spi/src',
|
||||
'vendor/psr',
|
||||
'vendor/php-http',
|
||||
'vendor/phan/phan/src/Phan',
|
||||
'vendor/phpunit/phpunit/src',
|
||||
'vendor/promphp/prometheus_client_php/src',
|
||||
'vendor/google/protobuf/src',
|
||||
'vendor/nyholm/dsn/src',
|
||||
'vendor/brick/math/src',
|
||||
'vendor/ramsey/uuid/src',
|
||||
'vendor/nyholm/psr7-server/src',
|
||||
'vendor/symfony/config',
|
||||
],
|
||||
|
||||
// A list of individual files to include in analysis
|
||||
|
|
|
@ -25,10 +25,11 @@ return $config->setRules([
|
|||
'blank_line_before_statement' => true,
|
||||
'cast_spaces' => true,
|
||||
'declare_strict_types' => true,
|
||||
'function_typehint_space' => true,
|
||||
'type_declaration_spaces' => true,
|
||||
'include' => true,
|
||||
'lowercase_cast' => true,
|
||||
'new_with_braces' => true,
|
||||
'new_with_parentheses' => true,
|
||||
'no_blank_lines_after_class_opening' => true,
|
||||
'no_extra_blank_lines' => true,
|
||||
'no_leading_import_slash' => true,
|
||||
'no_trailing_whitespace' => true,
|
||||
|
@ -41,9 +42,9 @@ return $config->setRules([
|
|||
'phpdoc_scalar' => true,
|
||||
'phpdoc_types' => true,
|
||||
'short_scalar_cast' => true,
|
||||
'single_blank_line_before_namespace' => true,
|
||||
'blank_lines_before_namespace' => true,
|
||||
'single_quote' => true,
|
||||
'trailing_comma_in_multiline' => true,
|
||||
'trailing_comma_in_multiline' => ['elements' => ['arrays', 'parameters', 'match']],
|
||||
])
|
||||
->setRiskyAllowed(true)
|
||||
->setFinder($finder);
|
||||
|
|
|
@ -12,4 +12,4 @@
|
|||
# https://help.github.com/en/articles/about-code-owners
|
||||
#
|
||||
|
||||
* @bobstrecansky @zsistla @tidal @brettmc
|
||||
* @open-telemetry/php-approvers
|
||||
|
|
321
CONTRIBUTING.md
321
CONTRIBUTING.md
|
@ -1,34 +1,319 @@
|
|||
Maintainers ([@open-telemetry/php-maintainers](https://github.com/orgs/open-telemetry/teams/php-maintainers)):
|
||||
# Contributing Guide
|
||||
|
||||
- [Bob Strecansky](https://github.com/bobstrecansky)
|
||||
- [Timo Michna](https://github.com/tidal/)
|
||||
- [Brett McBride](https://github.com/brettmc/)
|
||||
## Introduction
|
||||
|
||||
Find more about the maintainer role in [community repository](https://github.com/open-telemetry/community/blob/master/community-membership.md#maintainer)
|
||||
Welcome to the OpenTelemetry PHP repository! We appreciate your interest in contributing and helping improve this project. No contribution is too small—whether you're fixing a typo, improving documentation, or implementing a major feature, we value your help.
|
||||
|
||||
Approvers ([@open-telemetry/php-approvers](https://github.com/orgs/open-telemetry/teams/php-approvers)):
|
||||
This repository is part of the larger OpenTelemetry ecosystem, aimed at providing observability solutions for PHP applications. If you have any questions, feel free to ask in our community channels (See further help below). Your contributions make a difference!
|
||||
|
||||
- [Levi Morrison](https://github.com/morrisonlevi)
|
||||
## Pre-requisites
|
||||
|
||||
To contribute effectively, ensure you have the following tools installed:
|
||||
|
||||
* PHP 8.1 or higher (Check supported PHP versions)
|
||||
|
||||
We aim to support officially supported PHP versions, according to https://www.php.net/supported-versions.php. The
|
||||
developer image `ghcr.io/open-telemetry/opentelemetry-php/opentelemetry-php-base` is tagged as `8.1`, `8.2` and `8.3`
|
||||
respectively, with `8.1` being the default. You can execute the test suite against other PHP versions by running the
|
||||
following command:
|
||||
|
||||
```bash
|
||||
PHP_VERSION=8.1 make all
|
||||
#or
|
||||
PHP_VERSION=8.3 make all
|
||||
```
|
||||
For repeatability and consistency across different operating systems, we use the [3 Musketeers pattern](https://3musketeers.pages.dev/). If you're on Windows, it might be a good idea to use Git bash for following the steps below.
|
||||
|
||||
**Note: After cloning the repository, copy `.env.dist` to `.env`.**
|
||||
|
||||
Skipping the step above would result in a "`The "PHP_USER" variable is not set. Defaulting to a blank string`" warning
|
||||
|
||||
We use `docker` and `docker compose` to perform a lot of our static analysis and testing. If you're planning to develop for this library, it'll help to install
|
||||
[docker engine](https://docs.docker.com/engine/install/) and the [compose plugin](https://docs.docker.com/compose/install/).
|
||||
|
||||
Development tasks are generally run through a `Makefile`. Running `make` or `make help` will list available targets.
|
||||
|
||||
## Workflow
|
||||
|
||||
### Pull Requests
|
||||
|
||||
To propose changes to the codebase, you need
|
||||
to [open a pull request](https://docs.github.com/en/github/collaborating-with-issues-and-pull-requests/creating-a-pull-request)
|
||||
to the opentelemetry-php project.
|
||||
|
||||
After you open the pull request, the CI will run all the
|
||||
associated [github actions](https://github.com/open-telemetry/opentelemetry-php/actions/workflows/php.yml).
|
||||
|
||||
To ensure your PR doesn't emit a failure with GitHub actions, it's recommended that you run the important CI tests locally with the following command:
|
||||
|
||||
```bash
|
||||
make all # composer update, then run all checks
|
||||
make all-lowest # composer update to lowest dependencies, then run all checks
|
||||
```
|
||||
|
||||
This does the following things:
|
||||
|
||||
* Installs/updates all the required dependencies for the project
|
||||
* Uses [Rector](https://github.com/rectorphp/rector) to refactor your code according to our standards.
|
||||
* Uses [php-cs-fixer](https://github.com/FriendsOfPHP/PHP-CS-Fixer) to style your code using our style preferences.
|
||||
* Uses [Deptrac](https://github.com/qossmic/deptrac) to check for dependency violations inside our code base
|
||||
* Makes sure the composer files for the different components are valid
|
||||
* Runs all of our [phpunit](https://phpunit.de/) unit tests.
|
||||
* Performs static analysis with [Phan](https://github.com/phan/phan), [Psalm](https://psalm.dev/)
|
||||
and [PHPStan](https://phpstan.org/user-guide/getting-started)
|
||||
|
||||
## Local Run/Build
|
||||
|
||||
To ensure you have all the correct packages installed locally in your dev environment, you can run
|
||||
|
||||
```bash
|
||||
make install
|
||||
```
|
||||
|
||||
This will install all the library dependencies to
|
||||
the `/vendor` directory.
|
||||
|
||||
To update these dependencies, you can run
|
||||
|
||||
```bash
|
||||
make update
|
||||
```
|
||||
|
||||
To downgrade to the lowest dependencies, you can run
|
||||
|
||||
```shell
|
||||
make update-lowest
|
||||
```
|
||||
|
||||
To run all checks without doing a composer update:
|
||||
|
||||
```shell
|
||||
make all-checks
|
||||
```
|
||||
## Testing
|
||||
|
||||
To make sure the tests in this repo work as you expect, you can use the included docker test wrapper.
|
||||
To run the test suite, execute
|
||||
|
||||
```bash
|
||||
make test
|
||||
```
|
||||
|
||||
This will output the test output as well as a test coverage analysis (text + html - see `tests/coverage/html`). Code
|
||||
that doesn't pass our currently defined tests will emit a failure in CI
|
||||
|
||||
## Contributing Rules
|
||||
|
||||
Even though it may not be reflected everywhere in the codebase yet, we aim to provide software which is easy to read and change.
|
||||
The methods described in Clean Code book(s) by Robert C. Martin (Uncle Bob) are a de facto industry standards nowadays.
|
||||
Reading those books is highly recommended, however you can take a look at the examples given at [Clean Code PHP](https://github.com/jupeter/clean-code-php).
|
||||
While we have no rule to strictly follow said methods and patterns, they are highly recommended as an orientation for
|
||||
your pull requests and to be referenced in reviews.
|
||||
|
||||
We might add additional guidelines regarding for example testing in the future.
|
||||
|
||||
## Additional Information
|
||||
|
||||
### Automatic Refactoring and Upgrading
|
||||
|
||||
We use [Rector](https://github.com/rectorphp/rector) to automatically refactor our code according to given standards
|
||||
and upgrade the code to supported PHP versions.
|
||||
The associated configuration can be found [here](./.rector.php)
|
||||
|
||||
If you want to check what changes would be applied by rector, you can run:
|
||||
|
||||
```bash
|
||||
make rector
|
||||
```
|
||||
This command will simply print out the changes `rector` would make without actually changing any code.
|
||||
|
||||
To refactor your code following our given standards, you can run:
|
||||
|
||||
```bash
|
||||
make rector-write
|
||||
```
|
||||
|
||||
This command applies the changes to the code base.
|
||||
Make sure to run `make style` (see below) after running the `rector`command as the changes might not follow our coding standard.
|
||||
|
||||
### Styling
|
||||
|
||||
We use [PHP-CS-Fixer](https://github.com/FriendsOfPHP/PHP-CS-Fixer) for our code linting and standards fixer. The
|
||||
associated configuration can be found [here](./.php-cs-fixer.php)
|
||||
|
||||
To ensure that your code follows our coding standards, you can run:
|
||||
|
||||
```bash
|
||||
make style
|
||||
```
|
||||
|
||||
This command executes a required check that also runs during CI. This process performs the required fixes and prints them
|
||||
out. Code that doesn't meet the style pattern will emit a failure with GitHub actions.
|
||||
|
||||
### Static Analysis
|
||||
|
||||
We use [Phan](https://github.com/phan/phan/) for static analysis. Currently, our phan configuration is just a standard
|
||||
default analysis configuration. You can use our phan docker wrapper to easily perform static analysis on your changes.
|
||||
|
||||
To run Phan, one can run the following command:
|
||||
|
||||
```bash
|
||||
make phan
|
||||
```
|
||||
|
||||
This process will return 0 on success. Usually this process is performed as part of a code checkin. This process runs
|
||||
during CI and is a required check. Code that doesn't match the standards that we have defined in
|
||||
our [phan config](https://github.com/open-telemetry/opentelemetry-php/blob/master/.phan/config.php) will emit a failure
|
||||
in CI.
|
||||
|
||||
We also use [Psalm](https://psalm.dev/) as a second static analysis tool.
|
||||
You can use our psalm docker wrapper to easily perform static analysis on your changes.
|
||||
|
||||
To run Psalm, one can run the following command:
|
||||
|
||||
```bash
|
||||
make psalm
|
||||
```
|
||||
|
||||
This process will return 0 on success. Usually this process is performed as part of a code checkin. This process runs
|
||||
during CI and is a required check. Code that doesn't match the standards that we have defined in
|
||||
our [psalm config](https://github.com/open-telemetry/opentelemetry-php/blob/main/psalm.xml.dist) will emit a failure in
|
||||
CI.
|
||||
|
||||
We use [PHPStan](https://github.com/phpstan/phpstan) as our third tool for static analysis. You can use our PHPStan
|
||||
docker wrapper to easily perform static analysis on your changes.
|
||||
|
||||
To perform static analysis with PHPStan run:
|
||||
|
||||
```bash
|
||||
make phpstan
|
||||
```
|
||||
|
||||
This process will return 0 on success. Usually this process is performed as part of a code checkin. This process runs
|
||||
during CI and is a required check. Code that doesn't match the standards that we have defined in
|
||||
our [PHPStan config](https://github.com/open-telemetry/opentelemetry-php/blob/main/phpstan.neon.dist) will emit a
|
||||
failure in CI.
|
||||
|
||||
### Code Coverage
|
||||
We use [codecov.io](https://about.codecov.io/) to track code coverage for this repo. This is configured in the [php.yaml github action](https://github.com/open-telemetry/opentelemetry-php/blob/main/.github/workflows/php.yml#L71-L72). We don't require a specific level of code coverage for PRs to pass - we just use this tool in order to understand how a PR will potentially change the amount of code coverage we have across the code base. This tool isn't perfect - sometimes we'll see small deltas in code coverage where there shouldn't be any - this is nothing to fret about.
|
||||
|
||||
If code coverage does decrease on a pull request, you will see a red X in the CI for the repo, but that's ok - the reviewer will use their judgement to determine whether or not we have sufficient code coverage for the change.
|
||||
|
||||
### Dependency Validation
|
||||
|
||||
To make sure the different components of the library are distributable as separate packages, we have to check
|
||||
for dependency violations inside the code base. Dependencies must create a [DAC](https://en.wikipedia.org/wiki/Directed_acyclic_graph) in order to not create recursive dependencies.
|
||||
For this purpose we use [Deptrac](https://github.com/qossmic/deptrac) and the respective configuration can be found
|
||||
[here](./deptrac.yaml)
|
||||
|
||||
To validate the dependencies inside the code base, you can run:
|
||||
|
||||
```bash
|
||||
make deptrac
|
||||
```
|
||||
This command will create an error for any violation of the defined dependencies. If you add new dependencies to the code base,
|
||||
please configure them in the rector configuration.
|
||||
|
||||
## PhpMetrics
|
||||
|
||||
To generate a report showing a variety of metrics for the library and its classes, you can run:
|
||||
|
||||
```bash
|
||||
make phpmetrics
|
||||
```
|
||||
|
||||
This will generate a HTML PhpMetrics report in the `var/metrics` directory. Make sure to run `make test` before to
|
||||
create the test log-file, used by the metrics report.
|
||||
|
||||
### Proto Generation
|
||||
|
||||
Our protobuf files are committed to the repository into the `/proto` folder. These are used in gRPC connections to the
|
||||
upstream. These get updated when the [opentelemetry-proto](https://github.com/open-telemetry/opentelemetry-proto)
|
||||
repo has a meaningful update. The maintainer SIG is discussing a way to make this more automatic in the future.
|
||||
|
||||
To generate protobuf files for use with this repository, you can run the following command:
|
||||
|
||||
```bash
|
||||
make protobuf
|
||||
```
|
||||
|
||||
This will replace `proto/otel/Opentelemetry` and `proto/otel/GPBMetadata` with freshly generated code based on the
|
||||
latest tag from `opentelemetry-proto`, which can then be committed.
|
||||
|
||||
### Semantic Conventions Generation
|
||||
|
||||
Autogenerated semantic convention files are committed to the repository in the `/src/SemConv` directory. These files are
|
||||
updated manually when a new version of [semantic-conventions](https://github.com/open-telemetry/semantic-conventions) is
|
||||
released.
|
||||
|
||||
```bash
|
||||
SEMCONV_VERSION=1.8.0 make semconv
|
||||
```
|
||||
|
||||
Run this command in the root of this repository.
|
||||
|
||||
### API Documentation
|
||||
|
||||
We use [phpDocumentor](https://phpdoc.org/) to automatically generate API documentation from DocBlocks in the code.
|
||||
|
||||
To generate a recent version of the API documentation, you can run:
|
||||
|
||||
```bash
|
||||
make phpdoc
|
||||
```
|
||||
|
||||
To preview the documentation and changes you might expect, you can run:
|
||||
|
||||
```bash
|
||||
make phpdoc-preview
|
||||
```
|
||||
|
||||
This will start a HTTP server running at <http://localhost:8080> serving the updated documentation files.
|
||||
|
||||
## Maintainers
|
||||
|
||||
- [Bob Strecansky](https://github.com/bobstrecansky), Intuit
|
||||
- [Brett McBride](https://github.com/brettmc/), Deakin University
|
||||
|
||||
For more information about the maintainer role, see the [community repository](https://github.com/open-telemetry/community/blob/main/community-membership.md#maintainer).
|
||||
|
||||
## Approvers
|
||||
|
||||
- [Ago Allikmaa](https://github.com/agoallikmaa)
|
||||
- [Cedriz Ziel](https://github.com/cedricziel)
|
||||
- [Chris Lightfoot-Wild](https://github.com/ChrisLightfootWild)
|
||||
|
||||
For more information about the approver role, see the [community repository](https://github.com/open-telemetry/community/blob/main/community-membership.md#approver).
|
||||
|
||||
## Triagers
|
||||
|
||||
For more information about the triager role, see the [community repository](https://github.com/open-telemetry/community/blob/main/community-membership.md#triagers).
|
||||
|
||||
## Emeritus maintainers/approvers/triagers
|
||||
|
||||
- [Amber Zsistla](https://github.com/zsistla)
|
||||
- [Beniamin Calota](https://github.com/beniamin)
|
||||
- [Fahmy Mohammed](https://github.com/Fahmy-Mohammed)
|
||||
- [Amber Zsistla](https://github.com/zsistla)
|
||||
|
||||
Find more information about the approver role in the [community repository](https://github.com/open-telemetry/community/blob/master/community-membership.md#approver)
|
||||
|
||||
Triagers ([@open-telemetry/php-triagers](https://github.com/orgs/open-telemetry/teams/php-triagers)):
|
||||
|
||||
- [Jodee Varney](https://github.com/jodeev)
|
||||
- [Levi Morrison](https://github.com/morrisonlevi)
|
||||
- [Przemek Delewski](https://github.com/pdelewski)
|
||||
- [Timo Michna](https://github.com/tidal/)
|
||||
|
||||
Find more information about the triager role in the [community repository](https://github.com/open-telemetry/community/blob/master/community-membership.md#triager)
|
||||
For more information about the emeritus role, see the [community repository](https://github.com/open-telemetry/community/blob/main/guides/contributor/membership.md#emeritus-maintainerapprovertriager).
|
||||
|
||||
Members:
|
||||
## Further Help
|
||||
|
||||
- [Kishan Sangani](https://github.com/kishannsangani)
|
||||
Most of our communication is done on CNCF Slack in the channel [otel-php](https://cloud-native.slack.com/archives/C01NFPCV44V).
|
||||
To sign up, create a CNCF Slack account [here](http://slack.cncf.io/)
|
||||
|
||||
Our meetings are held weekly on zoom on Wednesdays at 10:30am PST / 1:30pm EST.
|
||||
A Google calendar invite with the included zoom link can be found [here](https://calendar.google.com/event?action=TEMPLATE&tmeid=N2VtZXZmYnVmbzZkYjZkbTYxdjZvYTdxN21fMjAyMDA5MTZUMTczMDAwWiBrYXJlbnlyeHVAbQ&tmsrc=google.com_b79e3e90j7bbsa2n2p5an5lf60%40group.calendar.google.com&scp=ALL)
|
||||
|
||||
Our open issues can all be found in the [GitHub issues tab](https://github.com/open-telemetry/opentelemetry-php/issues). Feel free to reach out on Slack if you have any additional questions about these issues; we are always happy to talk through implementation details.
|
||||
|
||||
Find more information about the member role in the [community repository](https://github.com/open-telemetry/community/blob/master/community-membership.md#member)
|
||||
|
||||
#### Thanks to all the people who already contributed!
|
||||
|
||||
<a href="https://github.com/open-telemetry/opentelemetry-php/graphs/contributors">
|
||||
<img src="https://contributors-img.web.app/image?repo=open-telemetry/opentelemetry-php" />
|
||||
</a>
|
||||
</a>
|
||||
|
|
155
Makefile
155
Makefile
|
@ -1,63 +1,114 @@
|
|||
PHP_VERSION ?= 7.4
|
||||
DC_RUN_PHP = docker-compose run --rm php
|
||||
include .env
|
||||
|
||||
all: update style deptrac phan psalm phpstan test
|
||||
install:
|
||||
PHP_VERSION ?= 8.1
|
||||
DOCKER_COMPOSE ?= docker compose
|
||||
DC_RUN_PHP = $(DOCKER_COMPOSE) run --rm php
|
||||
|
||||
.DEFAULT_GOAL : help
|
||||
.PHONY: deptrac
|
||||
|
||||
help: ## Show this help
|
||||
@printf "\033[33m%s:\033[0m\n" 'Available commands'
|
||||
@awk 'BEGIN {FS = ":.*?## "} /^[a-zA-Z0-9_-]+:.*?## / {printf " \033[32m%-18s\033[0m %s\n", $$1, $$2}' $(MAKEFILE_LIST)
|
||||
all: update all-checks ## Update to latest and run all checks
|
||||
all-lowest: update-lowest all-checks ## Update to lowest dependencies and run all checks
|
||||
all-checks: rector style deptrac packages-composer phan psalm phpstan test ## Run all checks
|
||||
pull: ## Pull latest developer image
|
||||
$(DOCKER_COMPOSE) pull php
|
||||
build: ## Build developer image locally
|
||||
docker build docker/ --build-arg PHP_VERSION=${PHP_VERSION} -t ghcr.io/open-telemetry/opentelemetry-php/opentelemetry-php-base:${PHP_VERSION}
|
||||
install: ## Install dependencies
|
||||
$(DC_RUN_PHP) env XDEBUG_MODE=off composer install
|
||||
update:
|
||||
update: ## Update dependencies
|
||||
$(DC_RUN_PHP) env XDEBUG_MODE=off composer update
|
||||
test: test-unit test-integration
|
||||
test-unit:
|
||||
$(DC_RUN_PHP) env XDEBUG_MODE=coverage vendor/bin/phpunit --testsuite unit --colors=always --coverage-text --testdox --coverage-clover coverage.clover --coverage-html=tests/coverage/html --log-junit=junit.xml
|
||||
test-integration:
|
||||
update-lowest: ## Update dependencies to lowest supported versions
|
||||
$(DC_RUN_PHP) env XDEBUG_MODE=off composer update --prefer-lowest
|
||||
test: test-unit test-integration ## Run unit and integration tests
|
||||
test-unit: ## Run unit tests
|
||||
$(DC_RUN_PHP) env XDEBUG_MODE=coverage vendor/bin/phpunit --testsuite unit --colors=always
|
||||
test-integration: ## Run integration tests
|
||||
$(DC_RUN_PHP) env XDEBUG_MODE=off vendor/bin/phpunit --testsuite integration --colors=always
|
||||
test-coverage:
|
||||
test-verbose: ## Run unit tests with verbose (testdox) output
|
||||
$(DC_RUN_PHP) env XDEBUG_MODE=coverage vendor/bin/phpunit --testsuite unit --colors=always --testdox --coverage-clover coverage.clover --coverage-html=tests/coverage/html --log-junit=junit.xml
|
||||
test-coverage: ## Run units tests and generate code coverage
|
||||
$(DC_RUN_PHP) env XDEBUG_MODE=coverage vendor/bin/phpunit --testsuite unit --coverage-html=tests/coverage/html
|
||||
phan:
|
||||
$(DC_RUN_PHP) env XDEBUG_MODE=off env PHAN_DISABLE_XDEBUG_WARN=1 vendor/bin/phan
|
||||
psalm:
|
||||
$(DC_RUN_PHP) env XDEBUG_MODE=off vendor/bin/psalm --threads=1 --no-cache
|
||||
psalm-info:
|
||||
$(DC_RUN_PHP) env XDEBUG_MODE=off vendor/bin/psalm --show-info=true --threads=1
|
||||
phpstan:
|
||||
$(DC_RUN_PHP) env XDEBUG_MODE=off vendor/bin/phpstan analyse
|
||||
benchmark:
|
||||
$(DC_RUN_PHP) env XDEBUG_MODE=off vendor/bin/phpbench run --report=default
|
||||
phpmetrics:
|
||||
$(DC_RUN_PHP) env XDEBUG_MODE=off vendor/bin/phpmetrics --config=./phpmetrics.json --junit=junit.xml
|
||||
trace examples: FORCE
|
||||
docker-compose up -d --remove-orphans
|
||||
$(DC_RUN_PHP) php ./examples/AlwaysOnZipkinExample.php
|
||||
$(DC_RUN_PHP) php ./examples/AlwaysOffTraceExample.php
|
||||
$(DC_RUN_PHP) php ./examples/AlwaysOnJaegerExample.php
|
||||
# The following examples do not use the DC_RUN_PHP global because they need environment variables.
|
||||
docker-compose run -e NEW_RELIC_ENDPOINT -e NEW_RELIC_INSERT_KEY --rm php php ./examples/AlwaysOnNewrelicExample.php
|
||||
docker-compose run -e NEW_RELIC_ENDPOINT -e NEW_RELIC_INSERT_KEY --rm php php ./examples/AlwaysOnZipkinToNewrelicExample.php
|
||||
docker-compose stop
|
||||
collector:
|
||||
docker-compose -f docker-compose-collector.yaml up -d --remove-orphans
|
||||
docker-compose -f docker-compose-collector.yaml run -e OTEL_EXPORTER_OTLP_ENDPOINT=otel-collector:4317 --rm php php ./examples/AlwaysOnOTLPGrpcExample2.php
|
||||
docker-compose -f docker-compose-collector.yaml stop
|
||||
|
||||
fiber-ffi-example:
|
||||
@docker-compose -f docker-compose.fiber-ffi.yaml -p opentelemetry-php_fiber-ffi-example up -d web
|
||||
test-compliance: ## Run compliance tests
|
||||
$(DC_RUN_PHP) env XDEBUG_MODE=coverage vendor/bin/phpunit --group compliance
|
||||
test-trace-compliance: ## Run trace compliance tests
|
||||
$(DC_RUN_PHP) env XDEBUG_MODE=coverage vendor/bin/phpunit --group trace-compliance
|
||||
phan: ## Run phan
|
||||
$(DC_RUN_PHP) env XDEBUG_MODE=off env PHAN_DISABLE_XDEBUG_WARN=1 vendor-bin/phan/vendor/bin/phan
|
||||
psalm: ## Run psalm
|
||||
$(DC_RUN_PHP) env XDEBUG_MODE=off vendor-bin/psalm/vendor/bin/psalm --threads=1 --no-cache
|
||||
psalm-info: ## Run psalm and show info
|
||||
$(DC_RUN_PHP) env XDEBUG_MODE=off vendor-bin/psalm/vendor/bin/psalm --show-info=true --threads=1
|
||||
phpdoc: ## Run phpdoc
|
||||
$(DOCKER_COMPOSE) -f docker-compose.phpDocumentor.yaml run --rm phpdoc
|
||||
phpdoc-preview:
|
||||
$(DOCKER_COMPOSE) -f docker-compose.phpDocumentor.yaml run --service-ports --rm preview
|
||||
phpstan: ## Run phpstan
|
||||
$(DC_RUN_PHP) env XDEBUG_MODE=off vendor/bin/phpstan analyse --memory-limit=256M
|
||||
infection: ## Run infection (mutation testing)
|
||||
$(DC_RUN_PHP) env XDEBUG_MODE=coverage php -d memory_limit=1024M vendor-bin/infection/vendor/bin/infection --threads=max
|
||||
packages-composer: ## Validate composer packages
|
||||
$(DC_RUN_PHP) env XDEBUG_MODE=off vendor/bin/otel packages:composer:validate
|
||||
benchmark: ## Run phpbench
|
||||
$(DC_RUN_PHP) env XDEBUG_MODE=off vendor-bin/phpbench/vendor/bin/phpbench run --report=default
|
||||
phpmetrics: ## Run php metrics
|
||||
$(DC_RUN_PHP) env XDEBUG_MODE=off vendor-bin/phpmetrics/vendor/bin/phpmetrics --config=./phpmetrics.json --junit=junit.xml
|
||||
smoke-test-examples: smoke-test-isolated-examples smoke-test-exporter-examples smoke-test-collector-integration smoke-test-prometheus-example ## Run smoke test examples
|
||||
smoke-test-isolated-examples: ## Run smoke test isolated examples
|
||||
$(DC_RUN_PHP) php ./examples/traces/getting_started.php
|
||||
$(DC_RUN_PHP) php ./examples/traces/features/batch_exporting.php
|
||||
$(DC_RUN_PHP) php ./examples/traces/features/concurrent_spans.php
|
||||
$(DC_RUN_PHP) php ./examples/traces/features/configuration_from_environment.php
|
||||
$(DC_RUN_PHP) php ./examples/traces/features/creating_a_new_trace_in_the_same_process.php
|
||||
$(DC_RUN_PHP) php ./examples/traces/features/resource_detectors.php
|
||||
$(DC_RUN_PHP) php ./examples/traces/features/span_resources.php
|
||||
$(DC_RUN_PHP) php ./examples/traces/troubleshooting/air_gapped_trace_debugging.php
|
||||
$(DC_RUN_PHP) php ./examples/traces/troubleshooting/logging_of_span_data.php
|
||||
$(DC_RUN_PHP) php ./examples/traces/troubleshooting/setting_up_logging.php
|
||||
smoke-test-exporter-examples: FORCE ## Run (some) exporter smoke test examples
|
||||
# Note this does not include every exporter at the moment
|
||||
$(DOCKER_COMPOSE) up -d --remove-orphans
|
||||
$(DC_RUN_PHP) php ./examples/traces/exporters/zipkin.php
|
||||
$(DC_RUN_PHP) php ./examples/traces/features/parent_span_example.php
|
||||
smoke-test-collector-integration: ## Run smoke test collector integration
|
||||
$(DOCKER_COMPOSE) -f docker-compose.collector.yaml up -d --remove-orphans
|
||||
sleep 5
|
||||
$(DOCKER_COMPOSE) -f docker-compose.collector.yaml run --rm php php ./examples/traces/exporters/otlp_grpc.php
|
||||
$(DOCKER_COMPOSE) -f docker-compose.collector.yaml run --rm php php ./examples/traces/exporters/otlp_http.php
|
||||
$(DOCKER_COMPOSE) -f docker-compose.collector.yaml stop
|
||||
smoke-test-collector-metrics-integration:
|
||||
$(DOCKER_COMPOSE) -f docker-compose.collector.yaml up -d --force-recreate collector
|
||||
COMPOSE_IGNORE_ORPHANS=TRUE $(DOCKER_COMPOSE) -f docker-compose.yaml run --rm php php ./examples/metrics/features/exporters/otlp_http.php
|
||||
$(DOCKER_COMPOSE) -f docker-compose.collector.yaml logs collector
|
||||
$(DOCKER_COMPOSE) -f docker-compose.collector.yaml stop collector
|
||||
smoke-test-prometheus-example: metrics-prometheus-example stop-prometheus
|
||||
metrics-prometheus-example:
|
||||
@docker-compose -f docker-compose.prometheus.yaml -p opentelemetry-php_metrics-prometheus-example up -d web
|
||||
@docker-compose -f docker-compose.prometheus.yaml -p opentelemetry-php_metrics-prometheus-example run --rm php php examples/prometheus/PrometheusMetricsExample.php
|
||||
@$(DOCKER_COMPOSE) -f docker-compose.prometheus.yaml -p opentelemetry-php_metrics-prometheus-example up -d web
|
||||
# This is slow because it's building the image from scratch (and parts of that, like installing the gRPC extension, are slow)
|
||||
@$(DOCKER_COMPOSE) -f docker-compose.prometheus.yaml -p opentelemetry-php_metrics-prometheus-example run --rm php php examples/metrics/prometheus/prometheus_metrics_example.php
|
||||
stop-prometheus:
|
||||
@docker-compose -f docker-compose.prometheus.yaml -p opentelemetry-php_metrics-prometheus-example stop
|
||||
protobuf:
|
||||
@docker-compose -f docker-compose.proto.yaml up proto
|
||||
thrift:
|
||||
./script/thrift_gen.sh
|
||||
bash:
|
||||
@$(DOCKER_COMPOSE) -f docker-compose.prometheus.yaml -p opentelemetry-php_metrics-prometheus-example stop
|
||||
fiber-ffi-example:
|
||||
@$(DOCKER_COMPOSE) -f docker-compose.fiber-ffi.yaml -p opentelemetry-php_fiber-ffi-example up -d web
|
||||
protobuf: ## Generate protobuf files
|
||||
./script/proto_gen.sh
|
||||
bash: ## bash shell into container
|
||||
$(DC_RUN_PHP) bash
|
||||
style:
|
||||
$(DC_RUN_PHP) env XDEBUG_MODE=off vendor/bin/php-cs-fixer fix --config=.php-cs-fixer.php --using-cache=no -vvv
|
||||
deptrac:
|
||||
$(DC_RUN_PHP) env XDEBUG_MODE=off vendor/bin/deptrac --formatter=table --report-uncovered
|
||||
style: ## Run style check/fix
|
||||
$(DC_RUN_PHP) env XDEBUG_MODE=off env PHP_CS_FIXER_IGNORE_ENV=1 vendor-bin/php-cs-fixer/vendor/bin/php-cs-fixer fix --config=.php-cs-fixer.php --using-cache=no -vvv
|
||||
rector-write: ## Run rector
|
||||
$(DC_RUN_PHP) env XDEBUG_MODE=off vendor-bin/rector/vendor/bin/rector process
|
||||
rector: ## Run rector (dry-run)
|
||||
$(DC_RUN_PHP) env XDEBUG_MODE=off vendor-bin/rector/vendor/bin/rector process --dry-run
|
||||
deptrac: ## Run deptrac
|
||||
$(DC_RUN_PHP) env XDEBUG_MODE=off vendor-bin/deptrac/vendor/bin/deptrac --formatter=table --report-uncovered --no-cache
|
||||
w3c-test-service:
|
||||
@docker-compose -f docker-compose.w3cTraceContext.yaml run --rm php ./tests/TraceContext/W3CTestService/symfony-setup
|
||||
semconv:
|
||||
@$(DOCKER_COMPOSE) -f docker-compose.w3cTraceContext.yaml run --rm php ./tests/TraceContext/W3CTestService/trace-context-test.sh
|
||||
semconv: ## Generate semconv files
|
||||
./script/semantic-conventions/semconv.sh
|
||||
split: ## Run git split
|
||||
$(DOCKER_COMPOSE) -f docker/gitsplit/docker-compose.yaml --env-file ./.env up
|
||||
FORCE:
|
||||
|
|
304
README.md
304
README.md
|
@ -1,292 +1,56 @@
|
|||
# OpenTelemetry php library
|
||||
# OpenTelemetry for PHP
|
||||
|
||||

|
||||

|
||||
[](https://codecov.io/gh/open-telemetry/opentelemetry-php)
|
||||
[](https://cloud-native.slack.com/archives/D03FAB6GN0K)
|
||||
|
||||
## Current Project Status
|
||||

|
||||
This is the **[monorepo](https://en.wikipedia.org/wiki/Monorepo)** for the **main** components of [OpenTelemetry](https://opentelemetry.io/) for PHP.
|
||||
|
||||
This project currently lives in a pre-alpha status. Our current release is not production ready; it has been created in order to receive feedback from the community.
|
||||
## Documentation
|
||||
|
||||
There is a supplemental repository for OpenTelemetry PHP contributions that are not part of the core distribution of the library. Typically, these contributions are vendor specific receivers/exporters and/or components that are only useful to a relatively small number of users. This repository can be found here:
|
||||
https://github.com/open-telemetry/opentelemetry-php-contrib/
|
||||
Please read the official documentation: https://opentelemetry.io/docs/instrumentation/php/
|
||||
|
||||
We attempt to keep the [OpenTelemetry Specification Matrix](https://github.com/open-telemetry/opentelemetry-specification/blob/master/spec-compliance-matrix.md) up to date in order to show which features are available and which have not yet been implemented.
|
||||
API Documentation is available here: https://open-telemetry.github.io/opentelemetry-php/
|
||||
|
||||
If you find an inconsistency in the data in the matrix vs. the data in this repository, please let us know in our slack channel and we'll get it rectified.
|
||||
## Packages and versions
|
||||
|
||||
## Communication
|
||||
Most of our communication is done on CNCF Slack, in the [otel-php](https://cloud-native.slack.com/archives/C01NFPCV44V) channel. To sign up, create a CNCF slack account here http://slack.cncf.io/
|
||||
| Package | Latest |
|
||||
|----------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||
| API | [](https://packagist.org/packages/open-telemetry/api/) [](https://packagist.org/packages/open-telemetry/api/) |
|
||||
| SDK | [](https://packagist.org/packages/open-telemetry/sdk/) [](https://packagist.org/packages/open-telemetry/sdk/) |
|
||||
| Context | [](https://packagist.org/packages/open-telemetry/context/) [](https://packagist.org/packages/open-telemetry/context/) |
|
||||
| Semantic Conventions | [](https://packagist.org/packages/open-telemetry/sem-conv/) [](https://packagist.org/packages/open-telemetry/sem-conv/) |
|
||||
| OTLP Exporter | [](https://packagist.org/packages/open-telemetry/exporter-otlp/) [](https://packagist.org/packages/open-telemetry/exporter-otlp/) |
|
||||
| gRPC Transport | [](https://packagist.org/packages/open-telemetry/transport-grpc/) [](https://packagist.org/packages/open-telemetry/transport-grpc/) |
|
||||
| OTLP Protobuf Files | [](https://packagist.org/packages/open-telemetry/gen-otlp-protobuf/) [](https://packagist.org/packages/open-telemetry/gen-otlp-protobuf/) |
|
||||
| B3 Propagator | [](https://packagist.org/packages/open-telemetry/extension-propagator-b3/) [](https://packagist.org/packages/open-telemetry/extension-propagator-b3/) |
|
||||
|
||||
Our meetings are held weekly on zoom on Wednesdays at 10:30am PST / 1:30pm EST.
|
||||
A Google calendar invite with the included zoom link can be found [here](https://calendar.google.com/event?action=TEMPLATE&tmeid=N2VtZXZmYnVmbzZkYjZkbTYxdjZvYTdxN21fMjAyMDA5MTZUMTczMDAwWiBrYXJlbnlyeHVAbQ&tmsrc=google.com_b79e3e90j7bbsa2n2p5an5lf60%40group.calendar.google.com&scp=ALL)
|
||||
Releases for both this repository and [contrib](https://github.com/open-telemetry/opentelemetry-php-contrib) are
|
||||
based on read-only [git subtree splits](https://github.com/splitsh/lite) from our monorepo. You should refer to
|
||||
[packagist.org](https://packagist.org/packages/open-telemetry/) for all packages, their versions and details.
|
||||
|
||||
Our open issues can all be found in the [github issues tab](https://github.com/open-telemetry/opentelemetry-php/issues). Feel free to reach out on Slack if you have any additional questions about these issues; we are always happy to talk through implementation details.
|
||||
You can also look at the read-only repositories, which live in the
|
||||
[opentelemetry-php](https://github.com/opentelemetry-php) organization.
|
||||
|
||||
## Requirements
|
||||
The library requires a PHP version of 7.4.x or 8.0.x (PHP 8.1 compability is in the works)
|
||||
## Contributing
|
||||
|
||||
### Dependencies
|
||||
[](https://github.com/open-telemetry/opentelemetry-php/issues?q=is%3Aopen+is%3Aissue+label%3A%22good+first+issue%22) [](https://github.com/open-telemetry/opentelemetry-php/issues?q=is%3Aopen+is%3Aissue+label%3A%22help+wanted%22) [](https://github.com/open-telemetry/opentelemetry-php/pulls?q=is%3Aopen+is%3Aissue+label%3A%22help+wanted%22) [](https://github.com/open-telemetry/opentelemetry-php/issues?q=is%3Aopen)
|
||||
|
||||
---
|
||||
We would love to have you on board, please see our [Contributing README](./CONTRIBUTING.md)
|
||||
|
||||
#### REQUIRED DEPENDENCIES
|
||||
#### 1.) Install PSR17/18 implementations
|
||||
## Specification conformance
|
||||
|
||||
The library has a dependency on both a [HTTP Factories (PSR17)](https://www.php-fig.org/psr/psr-17/)
|
||||
and a [php-http/async-client](https://docs.php-http.org/en/latest/clients.html) implementation.
|
||||
You can find appropriate composer packages implementing given standards on [packagist.org](https://packagist.org/).
|
||||
Follow [this link](https://packagist.org/providers/psr/http-factory-implementation) to find a `PSR17 (HTTP factories)` implementation,
|
||||
and [this link](https://packagist.org/providers/php-http/async-client-implementation) to find a `php-http/async-client` implementation.
|
||||
We attempt to keep the [OpenTelemetry Specification Matrix](https://github.com/open-telemetry/opentelemetry-specification/blob/master/spec-compliance-matrix.md) up to date in order to show which features are available and which have not yet been implemented.
|
||||
|
||||
---
|
||||
If you find an inconsistency in the data in the matrix, please let us know in our slack channel and we'll get it rectified.
|
||||
|
||||
#### OPTIONAL DEPENDENCIES
|
||||
## Backwards compatibility
|
||||
|
||||
#### 1.) Install PHP [ext-grpc](https://pecl.php.net/package/gRPC)
|
||||
See [compatibility readme](src/SDK/Common/Dev/Compatibility/README.md).
|
||||
|
||||
**The PHP gRPC extension is only needed, if you want to use the OTLP GRPC Exporter.**
|
||||
|
||||
There are basically three ways to install the gRPC extension which will be described below. Keep in mind, that whatever way
|
||||
to install the extension you choose, the compilation can take up to 10-15 minutes. (As an alternative you can search for
|
||||
a pre-compiled extension binary for your OS and PHP version, or you might be lucky and the package manager of your OS
|
||||
provides a package for the extension)
|
||||
- **Installation with pecl installer** (which should come with your PHP installation):
|
||||
|
||||
```bash
|
||||
[sudo] pecl install grpc
|
||||
```
|
||||
|
||||
- **Installation with pickle installer** (which you can find [here](https://github.com/FriendsOfPHP/pickle)):
|
||||
|
||||
```bash
|
||||
[sudo] pickle install grpc
|
||||
```
|
||||
- **Manually compiling the extension**, which is not really complicated either, but you should know
|
||||
what you are doing, so we won't cover it here.
|
||||
|
||||
> Notice: The artifact of the gRPC extension can be as large as 100mb (!!!), there are 'hacks' to reduce that size,
|
||||
> which you can find [in this thread](https://github.com/grpc/grpc/issues/23626). Use at your own risk.
|
||||
|
||||
#### 2.) Install PHP [ext-mbstring](https://www.php.net/manual/en/book.mbstring.php)
|
||||
|
||||
The library will load the `symfony/polyfill-mbstring` package, but for better performance you should install
|
||||
the PHP mbstring extension. You can use the same install methods as described for the gRPC extension above,
|
||||
however most OS` package managers provide a package for the extension.
|
||||
|
||||
#### 3.) Install PHP [ext-zlib](https://www.php.net/manual/en/book.zlib.php)
|
||||
|
||||
In order to use compression in HTTP requests you should install
|
||||
the PHP zlib extension. You can use the same install methods as described for the gRPC extension above,
|
||||
however most OS` package managers provide a package for the extension.
|
||||
|
||||
#### 4.) Install PHP [ext-ffi](https://www.php.net/manual/en/book.ffi.php)
|
||||
|
||||
_Experimental_ support for using fibers in PHP 8.1 for Context storage requires the `ffi` extension, and can
|
||||
be enabled by setting the `OTEL_PHP_FIBERS_ENABLED` environment variable to a truthy value (`1`, `true`, `on`).
|
||||
|
||||
Using fibers with non-`CLI` SAPIs may require pre-loading of bindings. One way to achieve this is setting [`ffi.preload`](https://www.php.net/manual/en/ffi.configuration.php#ini.ffi.preload) to `src/Context/fiber/zend_observer_fiber.h` and setting [`opcache.preload`](https://www.php.net/manual/en/opcache.preloading.php) to `vendor/autoload.php`.
|
||||
|
||||
#### 5.) Install PHP [ext-protobuf](https://pecl.php.net/package/protobuf)
|
||||
|
||||
** The PHP protobuf extension is optional when using either the `OTLPHttp` or `OTLPGrpc` exporters.**
|
||||
|
||||
The protobuf extension makes both exporters more performant. _Note: there are some deprecation warnings with protobuf and PHP 8.1_
|
||||
|
||||
---
|
||||
|
||||
## Installation
|
||||
The recommended way to install the library is through [Composer](http://getcomposer.org):
|
||||
|
||||
1.) Install the composer package using [Composer's installation instructions](https://getcomposer.org/doc/00-intromd#installation-linux-unix-macos).
|
||||
|
||||
2.) Add
|
||||
```bash
|
||||
"minimum-stability": "dev"
|
||||
```
|
||||
|
||||
To your project's `composer.json` file, as this utility has not reached a stable release status yet.
|
||||
|
||||
2.) Install the dependency with composer:
|
||||
|
||||
```bash
|
||||
$ composer require open-telemetry/opentelemetry
|
||||
```
|
||||
|
||||
## Development
|
||||
We use `docker` and `docker-compose` to perform a lot of our static analysis and testing.
|
||||
|
||||
If you're planning to develop for this library, it'll help to install `docker engine` and `docker-compose`.
|
||||
|
||||
You can find installation instructions for these packages can be found [here](https://docs.docker.com/install/), under the `Docker Engine` and `Docker Compose` submenus respectively.
|
||||
|
||||
To ensure you have all the correct packages installed locally in your dev environment, you can run
|
||||
|
||||
```bash
|
||||
make install
|
||||
```
|
||||
|
||||
From your bash compatible shell. This will install all of the necessary vendored libraries that the project uses to
|
||||
the `/vendor` directory.
|
||||
|
||||
To update these dependencies, you can run
|
||||
|
||||
```bash
|
||||
make update
|
||||
```
|
||||
|
||||
In order to update all the vendored libraries in the `/vendor` directory.
|
||||
|
||||
|
||||
## Pull Requests
|
||||
|
||||
Once you've made the update to the codebase that you'd like to submit, you may [create a pull request](https://docs.github.com/en/github/collaborating-with-issues-and-pull-requests/creating-a-pull-request) to the opentelemetry-php project.
|
||||
|
||||
After you open the pull request, the CI/CD pipeline will run all of the associated [github actions](https://github.com/open-telemetry/opentelemetry-php/actions/workflows/php.yml).
|
||||
|
||||
You can simulate the important github actions locally before you submit your PR by running the following command:
|
||||
|
||||
```bash
|
||||
make all
|
||||
```
|
||||
|
||||
from your bash compatible shell. This does the following things:
|
||||
|
||||
* Installs/updates all the required dependencies for the project
|
||||
* Uses [php-cs-fixer](https://github.com/FriendsOfPHP/PHP-CS-Fixer) to style your code using our style preferences.
|
||||
* Runs all of our [phpunit](https://phpunit.de/) unit tests.
|
||||
* Performs static analysis with [Phan](https://github.com/phan/phan), [Psalm](https://psalm.dev/) and [PHPStan](https://phpstan.org/user-guide/getting-started)
|
||||
|
||||
### Other PHP versions
|
||||
|
||||
We aim to support officially supported PHP versions, according to https://www.php.net/supported-versions.php. The developer image `ghcr.io/open-telemetry/opentelemetry-php/opentelemetry-php-base` is tagged as `7.4`, `8.0` and `8.1` respectively, with `7.4` being the default.
|
||||
You can execute the test suite against other PHP versions by running the following command:
|
||||
|
||||
```bash
|
||||
PHP_VERSION=8.0 make all
|
||||
#or
|
||||
PHP_VERSION=8.1 make all
|
||||
```
|
||||
|
||||
## Proto Generation
|
||||
Our protobuf files are committed to the repository into the `/proto` folder. These are used in gRPC connections to the
|
||||
upstream. These get updated when the [opentelemetry-proto](https://github.com/open-telemetry/opentelemetry-proto)
|
||||
repo has a meaningful update. The maintainer SIG is discussing a way to make this more automatic in the future.
|
||||
|
||||
If you'd like to generate protobuf files for use with this repository, one can run the following command:
|
||||
|
||||
```bash
|
||||
make protobuf
|
||||
```
|
||||
|
||||
From your bash compatible shell in the root of this directory. This wil create a `/proto` folder in the root
|
||||
directory of the
|
||||
repository.
|
||||
|
||||
|
||||
## Semantic Conventions Generation
|
||||
A generated semantic convention files are committed to the repository in the `/src/SemConv` directory. These files
|
||||
get updated when new version of [opentelemetry-specification](https://github.com/open-telemetry/opentelemetry-specification)
|
||||
released.
|
||||
|
||||
```bash
|
||||
SEMCONV_VERSION=1.8.0 make semconv
|
||||
```
|
||||
|
||||
Run it from you bash compatible shell in the root of this repository.
|
||||
|
||||
## Styling
|
||||
We use [PHP-CS-Fixer](https://github.com/FriendsOfPHP/PHP-CS-Fixer) for our code linting and standards fixer. The associated configuration for this standards fixer can be found in the root of the repository [here](https://github.com/open-telemetry/opentelemetry-php/blob/master/.php_cs)
|
||||
|
||||
To ensure that your code is stylish, you can run the follwing command:
|
||||
```bash
|
||||
make style
|
||||
```
|
||||
|
||||
from your bash compatible shell. This process will print out the fixes that it is making to your
|
||||
associated files. Usually this process is performed as part of a code checkin. This process runs during CI and is a required check. Code that doesn't follow this style pattern will emit a failure in CI.
|
||||
|
||||
## Static Analysis
|
||||
We use [Phan](https://github.com/phan/phan/) for static analysis. Currently our phan configuration is just a standard default analysis configuration. You can use our phan docker wrapper to easily perform static analysis on your changes.
|
||||
|
||||
To run Phan, one can run the following command:
|
||||
```bash
|
||||
make phan
|
||||
```
|
||||
from your bash compatible shell.
|
||||
This process will return 0 on success.
|
||||
Usually this process is performed as part of a code checkin. This process runs during CI and is a required check. Code that doesn't match the standards that we have defined in our [phan config](https://github.com/open-telemetry/opentelemetry-php/blob/master/.phan/config.php) will emit a failure in CI.
|
||||
|
||||
We also use [Psalm](https://psalm.dev/) as a second static analysis tool.
|
||||
You can use our psalm docker wrapper to easily perform static analysis on your changes.
|
||||
|
||||
To run Psalm, one can run the following command:
|
||||
```bash
|
||||
make psalm
|
||||
```
|
||||
from your bash compatible shell. This process will return 0 on success. Usually this process is performed as part of a code checkin. This process runs during CI and is a required check. Code that doesn't match the standards that we have defined in our [psalm config](https://github.com/open-telemetry/opentelemetry-php/blob/main/psalm.xml.dist) will emit a failure in CI.
|
||||
|
||||
We use [PHPStan](https://github.com/phpstan/phpstan) as our third tool for static analysis.
|
||||
You can use our PHPStan docker wrapper to easily perform static analysis on your changes.
|
||||
|
||||
Execute `make phpstan` from your bash compatible shell. This process will return 0 on success. Usually this process is
|
||||
performed as part of a code checkin. This process runs during CI and is a required check. Code that doesn't match the
|
||||
standards that we have defined in
|
||||
our [PHPStan config](https://github.com/open-telemetry/opentelemetry-php/blob/main/phpstan.neon.dist) will emit a failure
|
||||
in CI.
|
||||
|
||||
## Testing
|
||||
To make sure the tests in this repo work as you expect, you can use the included docker test wrapper.
|
||||
To run the test suite, execute
|
||||
```bash
|
||||
make test
|
||||
```
|
||||
from your bash compatible shell. This will output the test output as well
|
||||
as a test coverage analysis (text + html - see `tests/coverage/html`). Code that doesn't pass our currently defined tests will emit a failure in CI
|
||||
|
||||
## PhpMetrics
|
||||
To generate a report showing a variety of metrics for the library and its classes, you can run:
|
||||
```bash
|
||||
make phpmetrics
|
||||
```
|
||||
This will generate a HTML PhpMetrics report in the `var/metrics` directory. Make sure to run `make test` before to create the test log-file, used by the metrics report.
|
||||
|
||||
## Examples
|
||||
|
||||
### Trace
|
||||
You can use the [examples/AlwaysOnZipkinExample.php](/examples/AlwaysOnZipkinExample.php) file to test out the reference implementation we have for zipkin. This example perfoms a sample trace with a grouping of 5 spans and POSTs the result to a local zipkin instance.
|
||||
|
||||
You can also use the [examples/AlwaysOnJaegerExample.php](/examples/AlwaysOnJaegerExample.php) file to test out the reference implementation we have for jaegar. This example perfoms a sample trace with a grouping of 5 spans and POSTs the result to a local jaegar instance.
|
||||
|
||||
You can use the [examples/AlwaysOnZipkinToNewrelicExample.php](/examples/AlwaysOnZipkinToNewrelicExample.php) file to test out the reference implementation we have for zipkin to Newrelic. This example perfoms a sample trace with spans and POSTs the result to a Newrelic endpoint. This requires a license key (free accounts available) to be set in the environment (NEW_RELIC_INSERT_KEY) to authenticate to the backend.
|
||||
|
||||
You can use the [examples/AlwaysOnNewrelicExample.php](/examples/AlwaysOnNewrelicExample.php) file to test out the reference implementation we have for Newrelic. This example perfoms a sample trace with spans and POSTs the result to a Newrelic endpoint. This requires a license key (free accounts available) set in the environment (NEW_RELIC_INSERT_KEY) to authenticate to the backend.
|
||||
|
||||
The PHP for all examples should execute by itself (if you have a zipkin or jaegar instance running on localhost), but if you'd like a no-fuss way to test this out with docker and docker-compose, you can perform the following simple steps:
|
||||
|
||||
1.) Install the necessary dependencies by running `make install`. This will install the composer dependencies and store them in `/vendor`
|
||||
2.) Execute the example trace using `make trace examples`.
|
||||
|
||||
Exported spans can be seen in zipkin at [http://127.0.0.1:9411](http://127.0.0.1:9411)
|
||||
|
||||
Exported spans can also be seen in jaeger at [http://127.0.0.1:16686](http://127.0.0.1:16686)
|
||||
|
||||
### Metrics
|
||||
You can use the [examples/prometheus/PrometheusMetricsExample.php](/examples/prometheus/PrometheusMetricsExample.php) file to test out the reference implementation we have. This example will create a counter that will be scraped by local Prometheus instance.
|
||||
|
||||
The easy way to test the example out with docker and docker-compose is:
|
||||
|
||||
1.) Run `make metrics-prometheus-example`. Make sure that local ports 8080, 6379 and 9090 are available.
|
||||
|
||||
2.) Open local Prometheus instance: http://localhost:9090
|
||||
|
||||
3.) Go to Graph section, type "opentelemetry_prometheus_counter" in the search field or select it in the dropdown menu. You will see the counter value. Every other time you run `make metrics-prometheus-example` will increment the counter but remember that Prometheus scrapes values once in 10 seconds.
|
||||
|
||||
4.) In order to stop docker containers for this example just run `make stop-prometheus`
|
||||
|
||||
## User Integration Guides
|
||||
* [Integrating OpenTelemetry PHP into Laravel Applications](./docs/laravel-integration.md)
|
||||
* [Integrating OpenTelemetry PHP into Symfony Applications](./docs/symfony-integration.md)
|
||||
## Versioning
|
||||
|
||||
OpenTelemetry for PHP aims to support all officially supported PHP versions according to https://www.php.net/supported-versions.php, and
|
||||
support will be dropped for PHP versions within 12 months of that version going _End of life_.
|
||||
|
||||
Versioning rationale can be found in the [Versioning Documentation](/docs/versioning.md)
|
||||
|
|
212
composer.json
212
composer.json
|
@ -1,98 +1,208 @@
|
|||
{
|
||||
"name": "open-telemetry/opentelemetry",
|
||||
"description": "OpenTelemetry makes robust, portable telemetry a built-in feature of cloud-native software.",
|
||||
"keywords": ["opentelemetry", "otel", "open-telemetry", "tracing", "logging", "metrics"],
|
||||
"type": "library",
|
||||
"homepage": "https://opentelemetry.io/docs/php",
|
||||
"readme": "./README.md",
|
||||
"license": "Apache-2.0",
|
||||
"require": {
|
||||
"php": "^7.4 || ^8.0",
|
||||
"ext-json": "*",
|
||||
"google/protobuf": "^3.3.0",
|
||||
"grpc/grpc": "^1.30",
|
||||
"nyholm/dsn": "^2.0.0",
|
||||
"packaged/thrift": "^0.15.0",
|
||||
"php-http/async-client-implementation": "^1.0",
|
||||
"php": "^8.1",
|
||||
"google/protobuf": "^3.22 || ^4.0",
|
||||
"nyholm/psr7-server": "^1.1",
|
||||
"php-http/discovery": "^1.14",
|
||||
"promphp/prometheus_client_php": "^2.2.1",
|
||||
"psr/http-client": "^1.0",
|
||||
"psr/http-client-implementation": "^1.0",
|
||||
"psr/http-factory-implementation": "^1.0",
|
||||
"psr/http-message": "^1.0.1|^2.0",
|
||||
"psr/log": "^1.1|^2.0|^3.0",
|
||||
"symfony/polyfill-mbstring": "^1.23"
|
||||
"ramsey/uuid": "^3.0 || ^4.0",
|
||||
"symfony/config": "^5.4 || ^6.4 || ^7.0",
|
||||
"symfony/polyfill-mbstring": "^1.23",
|
||||
"symfony/polyfill-php82": "^1.26",
|
||||
"symfony/polyfill-php83": "^1.32",
|
||||
"symfony/polyfill-php84": "^1.32",
|
||||
"tbachert/spi": "^1.0.1"
|
||||
},
|
||||
"config": {
|
||||
"sort-packages": true,
|
||||
"allow-plugins": {
|
||||
"composer/package-versions-deprecated": true
|
||||
"bamarni/composer-bin-plugin": true,
|
||||
"composer/package-versions-deprecated": true,
|
||||
"php-http/discovery": true,
|
||||
"symfony/runtime": true,
|
||||
"tbachert/spi": true
|
||||
}
|
||||
},
|
||||
"authors": [
|
||||
{
|
||||
"name": "Bob Strecansky",
|
||||
"email": "bob.strecansky@gmail.com"
|
||||
},
|
||||
{
|
||||
"name": "Dmitry Krokhin",
|
||||
"email": "nekufa@gmail.com"
|
||||
},
|
||||
{
|
||||
"name": "Levi Morrison",
|
||||
"email": "levim@php.net"
|
||||
"name": "opentelemetry-php contributors",
|
||||
"homepage": "https://github.com/open-telemetry/opentelemetry-php/graphs/contributors"
|
||||
}
|
||||
],
|
||||
"replace": {
|
||||
"open-telemetry/api": "self.version",
|
||||
"open-telemetry/context": "self.version",
|
||||
"open-telemetry/proto-otel": "self.version",
|
||||
"open-telemetry/sdk": "self.version",
|
||||
"open-telemetry/sdk-contrib": "self.version",
|
||||
"open-telemetry/sem-conv": "self.version"
|
||||
"open-telemetry/api": "1.0.x-dev",
|
||||
"open-telemetry/context": "1.0.x-dev",
|
||||
"open-telemetry/exporter-otlp": "1.0.x-dev",
|
||||
"open-telemetry/exporter-zipkin": "1.0.x-dev",
|
||||
"open-telemetry/extension-propagator-b3": "1.0.x-dev",
|
||||
"open-telemetry/extension-propagator-cloudtrace": "1.0.x-dev",
|
||||
"open-telemetry/extension-propagator-jaeger": "0.0.2",
|
||||
"open-telemetry/gen-otlp-protobuf": "1.0.x-dev",
|
||||
"open-telemetry/sdk": "1.0.x-dev",
|
||||
"open-telemetry/sdk-configuration": "0.1.x-dev",
|
||||
"open-telemetry/sdk-contrib": "1.0.x-dev",
|
||||
"open-telemetry/sem-conv": "1.0.x-dev",
|
||||
"open-telemetry/transport-grpc": "1.0.x-dev"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"OpenTelemetry\\": "src/",
|
||||
"Opentelemetry\\Proto\\": "proto/otel/Opentelemetry/Proto/",
|
||||
"GPBMetadata\\Opentelemetry\\": "proto/otel/GPBMetadata/Opentelemetry/",
|
||||
"Jaeger\\Thrift\\": "thrift/jaeger/"
|
||||
"GPBMetadata\\Opentelemetry\\": "proto/otel/GPBMetadata/Opentelemetry/"
|
||||
},
|
||||
"files": [
|
||||
"src/Context/fiber/initialize_fiber_handler.php",
|
||||
"src/SDK/Common/Dev/Compatibility/_load.php"
|
||||
"src/API/Trace/functions.php",
|
||||
"src/Contrib/Otlp/_register.php",
|
||||
"src/Contrib/Grpc/_register.php",
|
||||
"src/Contrib/Zipkin/_register.php",
|
||||
"src/Extension/Propagator/B3/_register.php",
|
||||
"src/Extension/Propagator/CloudTrace/_register.php",
|
||||
"src/Extension/Propagator/Jaeger/_register.php",
|
||||
"src/SDK/Logs/Exporter/_register.php",
|
||||
"src/SDK/Metrics/MetricExporter/_register.php",
|
||||
"src/SDK/Propagation/_register.php",
|
||||
"src/SDK/Trace/SpanExporter/_register.php",
|
||||
"src/SDK/Common/Dev/Compatibility/_load.php",
|
||||
"src/SDK/Common/Util/functions.php",
|
||||
"src/SDK/_autoload.php"
|
||||
]
|
||||
},
|
||||
"autoload-dev": {
|
||||
"psr-4": {
|
||||
"OpenTelemetry\\Tests\\": "tests/"
|
||||
"OpenTelemetry\\Tests\\": "tests/",
|
||||
"OpenTelemetry\\Example\\": "examples/src/",
|
||||
"ExampleSDK\\ComponentProvider\\": "tests/Unit/Config/SDK/Configuration/ExampleSdk/"
|
||||
}
|
||||
},
|
||||
"require-dev": {
|
||||
"ext-grpc": "*",
|
||||
"assertwell/phpunit-global-state": "^0.2",
|
||||
"composer/xdebug-handler": "^2.0",
|
||||
"dg/bypass-finals": "^1.3",
|
||||
"friendsofphp/php-cs-fixer": "^3.4",
|
||||
"bamarni/composer-bin-plugin": "^1.8",
|
||||
"dg/bypass-finals": "^1.4",
|
||||
"grpc/grpc": "^1.30",
|
||||
"guzzlehttp/guzzle": "^7.4",
|
||||
"guzzlehttp/psr7": "^2.1",
|
||||
"mikey179/vfsstream": "^1.6",
|
||||
"mockery/mockery": "^1.4",
|
||||
"monolog/monolog": "^2.3",
|
||||
"mikey179/vfsstream": "^1.6.11",
|
||||
"mockery/mockery": "^1.5.1",
|
||||
"monolog/monolog": "^3.0",
|
||||
"nyholm/psr7": "^1.4",
|
||||
"phan/phan": "^5.0",
|
||||
"open-telemetry/dev-tools": "dev-main",
|
||||
"php-http/mock-client": "^1.5",
|
||||
"phpbench/phpbench": "^1.2",
|
||||
"phpmetrics/phpmetrics": "^2.7",
|
||||
"phpstan/phpstan": "^1.1",
|
||||
"phpstan/phpstan-mockery": "^1.0",
|
||||
"phpstan/phpstan-phpunit": "^1.0",
|
||||
"phpunit/phpunit": "^9.3",
|
||||
"psalm/plugin-mockery": "^0.9",
|
||||
"psalm/plugin-phpunit": "^0.16",
|
||||
"psalm/psalm": "^4.0",
|
||||
"qossmic/deptrac-shim": "^0.18",
|
||||
"symfony/http-client": "^5.2"
|
||||
"phpdocumentor/reflection-docblock": "^5.3",
|
||||
"phpspec/prophecy": "^1.22",
|
||||
"phpspec/prophecy-phpunit": "^2",
|
||||
"phpstan/phpstan": "^1.10.13",
|
||||
"phpstan/phpstan-mockery": "^1.1",
|
||||
"phpstan/phpstan-phpunit": "^1.3",
|
||||
"phpunit/phpunit": "^10 || ^11",
|
||||
"sebastian/exporter": "<= 6.0.1 || >= 6.1.3",
|
||||
"symfony/http-client": "^5.2",
|
||||
"symfony/var-exporter": "^5.4 || ^6.4 || ^7.0",
|
||||
"symfony/yaml": "^5.4 || ^6.4 || ^7.0"
|
||||
},
|
||||
"conflict": {
|
||||
"mockery/mockery": "1.6.12"
|
||||
},
|
||||
"suggest": {
|
||||
"ext-gmp": "To support unlimited number of synchronous metric readers",
|
||||
"ext-grpc": "To use the OTLP GRPC Exporter",
|
||||
"ext-protobuf": "For more performant protobuf/grpc exporting",
|
||||
"ext-sockets": "To use the Thrift UDP Exporter for the Jaeger Agent"
|
||||
"ext-yaml": "Allows loading config from yaml files",
|
||||
"symfony/yaml": "Allows loading config from yaml files"
|
||||
},
|
||||
"extra": {
|
||||
"bamarni-bin": {
|
||||
"bin-links": false,
|
||||
"target-directory": "vendor-bin",
|
||||
"forward-command": true
|
||||
},
|
||||
"spi": {
|
||||
"OpenTelemetry\\API\\Configuration\\Config\\ComponentProvider": [
|
||||
"OpenTelemetry\\Config\\SDK\\ComponentProvider\\Propagator\\TextMapPropagatorB3",
|
||||
"OpenTelemetry\\Config\\SDK\\ComponentProvider\\Propagator\\TextMapPropagatorB3Multi",
|
||||
"OpenTelemetry\\Config\\SDK\\ComponentProvider\\Propagator\\TextMapPropagatorBaggage",
|
||||
"OpenTelemetry\\Config\\SDK\\ComponentProvider\\Propagator\\TextMapPropagatorComposite",
|
||||
"OpenTelemetry\\Config\\SDK\\ComponentProvider\\Propagator\\TextMapPropagatorJaeger",
|
||||
"OpenTelemetry\\Config\\SDK\\ComponentProvider\\Propagator\\TextMapPropagatorTraceContext",
|
||||
|
||||
"OpenTelemetry\\Config\\SDK\\ComponentProvider\\Trace\\SamplerAlwaysOff",
|
||||
"OpenTelemetry\\Config\\SDK\\ComponentProvider\\Trace\\SamplerAlwaysOn",
|
||||
"OpenTelemetry\\Config\\SDK\\ComponentProvider\\Trace\\SamplerParentBased",
|
||||
"OpenTelemetry\\Config\\SDK\\ComponentProvider\\Trace\\SamplerTraceIdRatioBased",
|
||||
"OpenTelemetry\\Config\\SDK\\ComponentProvider\\Trace\\SpanExporterConsole",
|
||||
"OpenTelemetry\\Config\\SDK\\ComponentProvider\\Trace\\SpanExporterMemory",
|
||||
"OpenTelemetry\\Config\\SDK\\ComponentProvider\\Trace\\SpanExporterOtlpFile",
|
||||
"OpenTelemetry\\Config\\SDK\\ComponentProvider\\Trace\\SpanExporterOtlpGrpc",
|
||||
"OpenTelemetry\\Config\\SDK\\ComponentProvider\\Trace\\SpanExporterOtlpHttp",
|
||||
"OpenTelemetry\\Config\\SDK\\ComponentProvider\\Trace\\SpanExporterZipkin",
|
||||
"OpenTelemetry\\Config\\SDK\\ComponentProvider\\Trace\\SpanProcessorBatch",
|
||||
"OpenTelemetry\\Config\\SDK\\ComponentProvider\\Trace\\SpanProcessorSimple",
|
||||
|
||||
"OpenTelemetry\\Config\\SDK\\ComponentProvider\\Metrics\\AggregationResolverDefault",
|
||||
"OpenTelemetry\\Config\\SDK\\ComponentProvider\\Metrics\\MetricExporterConsole",
|
||||
"OpenTelemetry\\Config\\SDK\\ComponentProvider\\Metrics\\MetricExporterMemory",
|
||||
"OpenTelemetry\\Config\\SDK\\ComponentProvider\\Metrics\\MetricExporterOtlpFile",
|
||||
"OpenTelemetry\\Config\\SDK\\ComponentProvider\\Metrics\\MetricExporterOtlpGrpc",
|
||||
"OpenTelemetry\\Config\\SDK\\ComponentProvider\\Metrics\\MetricExporterOtlpHttp",
|
||||
"OpenTelemetry\\Config\\SDK\\ComponentProvider\\Metrics\\MetricReaderPeriodic",
|
||||
|
||||
"OpenTelemetry\\Config\\SDK\\ComponentProvider\\Logs\\LogRecordExporterConsole",
|
||||
"OpenTelemetry\\Config\\SDK\\ComponentProvider\\Logs\\LogRecordExporterMemory",
|
||||
"OpenTelemetry\\Config\\SDK\\ComponentProvider\\Logs\\LogRecordExporterOtlpFile",
|
||||
"OpenTelemetry\\Config\\SDK\\ComponentProvider\\Logs\\LogRecordExporterOtlpGrpc",
|
||||
"OpenTelemetry\\Config\\SDK\\ComponentProvider\\Logs\\LogRecordExporterOtlpHttp",
|
||||
"OpenTelemetry\\Config\\SDK\\ComponentProvider\\Logs\\LogRecordProcessorBatch",
|
||||
"OpenTelemetry\\Config\\SDK\\ComponentProvider\\Logs\\LogRecordProcessorSimple",
|
||||
|
||||
"OpenTelemetry\\Config\\SDK\\ComponentProvider\\Detector\\Composer",
|
||||
"OpenTelemetry\\Config\\SDK\\ComponentProvider\\Detector\\Host",
|
||||
"OpenTelemetry\\Config\\SDK\\ComponentProvider\\Detector\\Process",
|
||||
|
||||
"OpenTelemetry\\Config\\SDK\\ComponentProvider\\Instrumentation\\General\\HttpConfigProvider",
|
||||
"OpenTelemetry\\Config\\SDK\\ComponentProvider\\Instrumentation\\General\\PeerConfigProvider",
|
||||
|
||||
"OpenTelemetry\\Example\\ExampleConfigProvider",
|
||||
|
||||
"OpenTelemetry\\Tests\\Integration\\Config\\ComponentProvider\\Detector\\Container",
|
||||
"OpenTelemetry\\Tests\\Integration\\Config\\ComponentProvider\\Detector\\Os",
|
||||
"OpenTelemetry\\Tests\\Integration\\Config\\ComponentProvider\\Metrics\\AggregationResolverExplicitBucketHistogram",
|
||||
"OpenTelemetry\\Tests\\Integration\\Config\\ComponentProvider\\Metrics\\MetricExporterPrometheus",
|
||||
"OpenTelemetry\\Tests\\Integration\\Config\\ComponentProvider\\Metrics\\MetricReaderPull",
|
||||
"OpenTelemetry\\Tests\\Integration\\Config\\ComponentProvider\\Propagator\\TextMapPropagatorXray",
|
||||
"OpenTelemetry\\Tests\\Integration\\Config\\ComponentProvider\\Propagator\\TextMapPropagatorOtTrace"
|
||||
],
|
||||
"OpenTelemetry\\API\\Configuration\\ConfigEnv\\EnvComponentLoader": [
|
||||
"OpenTelemetry\\API\\Instrumentation\\Configuration\\General\\ConfigEnv\\EnvComponentLoaderHttpConfig",
|
||||
"OpenTelemetry\\API\\Instrumentation\\Configuration\\General\\ConfigEnv\\EnvComponentLoaderPeerConfig",
|
||||
|
||||
"OpenTelemetry\\Example\\ExampleConfigLoader"
|
||||
],
|
||||
"OpenTelemetry\\API\\Instrumentation\\AutoInstrumentation\\HookManagerInterface": [
|
||||
"OpenTelemetry\\API\\Instrumentation\\AutoInstrumentation\\ExtensionHookManager"
|
||||
],
|
||||
"OpenTelemetry\\API\\Instrumentation\\AutoInstrumentation\\Instrumentation": [
|
||||
"OpenTelemetry\\Example\\ExampleInstrumentation"
|
||||
],
|
||||
"OpenTelemetry\\SDK\\Common\\Configuration\\Resolver\\ResolverInterface": [
|
||||
"OpenTelemetry\\SDK\\Common\\Configuration\\Resolver\\SdkConfigurationResolver"
|
||||
],
|
||||
"OpenTelemetry\\Config\\SDK\\Configuration\\Environment\\EnvSourceProvider": [
|
||||
"OpenTelemetry\\Config\\SDK\\Configuration\\Environment\\Adapter\\SymfonyDotenvProvider",
|
||||
"OpenTelemetry\\Config\\SDK\\Configuration\\Environment\\Adapter\\VlucasPhpdotenvProvider",
|
||||
|
||||
"OpenTelemetry\\Tests\\Integration\\SDK\\Common\\Configuration\\TestEnvSourceProvider"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
111
depfile.yaml
111
depfile.yaml
|
@ -1,111 +0,0 @@
|
|||
#baseline: depfile.baseline.yml
|
||||
paths:
|
||||
- ./src
|
||||
- ./proto
|
||||
exclude_files:
|
||||
- '#.*test.*#'
|
||||
layers:
|
||||
- name: API
|
||||
collectors:
|
||||
- type: className
|
||||
regex: ^OpenTelemetry\\API\\*
|
||||
- name: SDK
|
||||
collectors:
|
||||
- type: className
|
||||
regex: ^OpenTelemetry\\SDK\\*
|
||||
- name: Context
|
||||
collectors:
|
||||
- type: className
|
||||
regex: ^OpenTelemetry\\Context\\*
|
||||
- name: SemConv
|
||||
collectors:
|
||||
- type: className
|
||||
regex: ^OpenTelemetry\\SemConv\\*
|
||||
- name: Contrib
|
||||
collectors:
|
||||
- type: className
|
||||
regex: ^OpenTelemetry\\Contrib\\*
|
||||
- name: OtelProto
|
||||
collectors:
|
||||
- type: className
|
||||
regex: ^OpenTelemetry\\Proto\\*
|
||||
- type: className
|
||||
regex: ^GPBMetadata\\Opentelemetry\\*
|
||||
- name: GoogleProtobuf
|
||||
collectors:
|
||||
- type: className
|
||||
regex: ^Google\\Protobuf\\*
|
||||
- name: Grpc
|
||||
collectors:
|
||||
- type: className
|
||||
regex: ^Grpc\\
|
||||
- name: PsrLog
|
||||
collectors:
|
||||
- type: className
|
||||
regex: ^Psr\\Log\\
|
||||
- name: PsrHttp
|
||||
collectors:
|
||||
- type: className
|
||||
regex: ^Psr\\Http\\
|
||||
- name: Http
|
||||
collectors:
|
||||
- type: className
|
||||
regex: ^Http\\
|
||||
- name: NyholmDsn
|
||||
collectors:
|
||||
- type: className
|
||||
regex: ^Nyholm\\Dsn\\
|
||||
- name: Prometheus
|
||||
collectors:
|
||||
- type: className
|
||||
regex: ^Prometheus\\
|
||||
- name: FFI
|
||||
collectors:
|
||||
- type: className
|
||||
regex: ^FFI\\
|
||||
- name: Composer
|
||||
collectors:
|
||||
- type: className
|
||||
regex: ^Composer\\
|
||||
- name: Thrift
|
||||
collectors:
|
||||
- type: className
|
||||
regex: ^Thrift\\
|
||||
- name: JaegerThrift
|
||||
collectors:
|
||||
- type: className
|
||||
regex: ^Jaeger\\Thrift\\
|
||||
|
||||
ruleset:
|
||||
Context:
|
||||
- FFI
|
||||
SemConv: ~
|
||||
API:
|
||||
- Context
|
||||
- SemConv
|
||||
SDK:
|
||||
- API
|
||||
- Context
|
||||
- SemConv
|
||||
- PsrLog
|
||||
- PsrHttp
|
||||
- Http
|
||||
- NyholmDsn
|
||||
- Composer
|
||||
OtelProto:
|
||||
- GoogleProtobuf
|
||||
- Grpc
|
||||
Contrib:
|
||||
- API
|
||||
- SDK
|
||||
- Context
|
||||
- SemConv
|
||||
- OtelProto
|
||||
- Grpc
|
||||
- PsrLog
|
||||
- PsrHttp
|
||||
- Http
|
||||
- NyholmDsn
|
||||
- Prometheus
|
||||
- Thrift
|
||||
- JaegerThrift
|
|
@ -0,0 +1,14 @@
|
|||
deptrac:
|
||||
skip_violations:
|
||||
/src/Extension/Propagator/B3/_register.php:
|
||||
- OpenTelemetry\SDK\Registry
|
||||
/src/Extension/Propagator/CloudTrace/_register.php:
|
||||
- OpenTelemetry\SDK\Registry
|
||||
/src/Extension/Propagator/Jaeger/_register.php:
|
||||
- OpenTelemetry\SDK\Registry
|
||||
OpenTelemetry\API\Configuration\Config\ComponentProvider:
|
||||
- Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition
|
||||
- Symfony\Component\Config\Definition\Builder\NodeBuilder
|
||||
OpenTelemetry\API\Configuration\Config\ComponentProviderRegistry:
|
||||
- Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition
|
||||
- Symfony\Component\Config\Definition\Builder\NodeDefinition
|
|
@ -0,0 +1,168 @@
|
|||
|
||||
imports:
|
||||
- deptrac.baseline.yaml
|
||||
deptrac:
|
||||
analyser:
|
||||
types:
|
||||
- class
|
||||
- class_superglobal
|
||||
- use
|
||||
- file
|
||||
- function
|
||||
- function_superglobal
|
||||
paths:
|
||||
- ./src
|
||||
- ./proto
|
||||
- ./tests
|
||||
- ./deptrac/polyfills
|
||||
- ./vendor/symfony/polyfill-php83/Resources/stubs
|
||||
exclude_files:
|
||||
- '#.*test.*#'
|
||||
layers:
|
||||
- name: API
|
||||
collectors:
|
||||
- type: directory
|
||||
value: src/API/.*
|
||||
- name: SDK
|
||||
collectors:
|
||||
- type: directory
|
||||
value: src/SDK/.*
|
||||
- name: ConfigSDK
|
||||
collectors:
|
||||
- type: directory
|
||||
value: src/Config/SDK/.*
|
||||
- name: Context
|
||||
collectors:
|
||||
- type: directory
|
||||
value: src/Context/.*
|
||||
- name: SemConv
|
||||
collectors:
|
||||
- type: directory
|
||||
value: src/SemConv/.*
|
||||
- name: Contrib
|
||||
collectors:
|
||||
- type: directory
|
||||
value: src/Contrib/.*
|
||||
- name: Extension
|
||||
collectors:
|
||||
- type: directory
|
||||
value: src/Extension/.*
|
||||
- name: OtelProto
|
||||
collectors:
|
||||
- type: directory
|
||||
value: proto/otel/.*
|
||||
- name: GoogleProtobuf
|
||||
collectors:
|
||||
- type: className
|
||||
regex: ^Google\\Protobuf\\*
|
||||
- name: Grpc
|
||||
collectors:
|
||||
- type: className
|
||||
regex: ^Grpc\\*
|
||||
- name: PsrLog
|
||||
collectors:
|
||||
- type: className
|
||||
regex: ^Psr\\Log\\*
|
||||
- name: PsrHttp
|
||||
collectors:
|
||||
- type: className
|
||||
regex: ^Psr\\Http\\*
|
||||
- name: HttpPlug
|
||||
collectors:
|
||||
- type: className
|
||||
regex: ^Http\\*
|
||||
- name: Prometheus
|
||||
collectors:
|
||||
- type: className
|
||||
regex: ^Prometheus\\*
|
||||
- name: FFI
|
||||
collectors:
|
||||
- type: className
|
||||
regex: ^FFI\\*
|
||||
- name: Composer
|
||||
collectors:
|
||||
- type: className
|
||||
regex: ^Composer\\*
|
||||
- name: HttpClients
|
||||
collectors:
|
||||
- type: className
|
||||
value: ^Symfony\\Component\\HttpClient\\*
|
||||
- type: className
|
||||
value: ^GuzzleHttp\\*
|
||||
- type: className
|
||||
value: ^Buzz\\*
|
||||
- name: SPI
|
||||
collectors:
|
||||
- type: className
|
||||
value: ^Nevay\\SPI\\*
|
||||
- name: SymfonyConfig
|
||||
collectors:
|
||||
- type: className
|
||||
value: ^Symfony\\Component\\Config\\*
|
||||
- type: className
|
||||
value: ^Symfony\\Component\\Yaml\\*
|
||||
- type: className
|
||||
value: ^Symfony\\Component\\VarExporter\\*
|
||||
- name: RamseyUuid
|
||||
collectors:
|
||||
- type: className
|
||||
regex: ^Ramsey\\Uuid\\*
|
||||
- name: NyholmPsr7Server
|
||||
collectors:
|
||||
- type: className
|
||||
regex: ^Nyholm\\Psr7Server\\*
|
||||
- name: Polyfills
|
||||
collectors:
|
||||
- type: directory
|
||||
value: deptrac/polyfills/.*
|
||||
- type: directory
|
||||
value: vendor/symfony/polyfill-php83
|
||||
- name: DotenvProvider
|
||||
collectors:
|
||||
- type: className
|
||||
regex: ^Symfony\\Component\\Dotenv\\*
|
||||
- type: className
|
||||
regex: ^Dotenv\\*
|
||||
ruleset:
|
||||
Context:
|
||||
- FFI
|
||||
- Polyfills
|
||||
SemConv: ~
|
||||
ConfigSDK:
|
||||
- SymfonyConfig
|
||||
- API
|
||||
- SDK
|
||||
- SPI
|
||||
- PsrLog
|
||||
- Composer
|
||||
- Context
|
||||
- Contrib
|
||||
- Extension
|
||||
- Polyfills
|
||||
- DotenvProvider
|
||||
API:
|
||||
- Context
|
||||
- PsrLog
|
||||
- SPI
|
||||
- Polyfills
|
||||
SDK:
|
||||
- +API
|
||||
- ConfigSDK
|
||||
- SemConv
|
||||
- PsrHttp
|
||||
- HttpPlug
|
||||
- Composer
|
||||
- HttpClients
|
||||
- SPI
|
||||
- RamseyUuid
|
||||
- NyholmPsr7Server
|
||||
Contrib:
|
||||
- +SDK
|
||||
- +OtelProto
|
||||
- Grpc
|
||||
- Prometheus
|
||||
Extension:
|
||||
- +API
|
||||
OtelProto:
|
||||
- GoogleProtobuf
|
||||
- Grpc
|
|
@ -0,0 +1,5 @@
|
|||
<?php
|
||||
|
||||
namespace OpenTelemetry\Config\SDK\Configuration;
|
||||
|
||||
class ComponentPlugin {}
|
|
@ -0,0 +1,5 @@
|
|||
<?php
|
||||
|
||||
namespace OpenTelemetry\Config\SDK\Configuration;
|
||||
|
||||
class ComponentProvider {}
|
|
@ -0,0 +1,5 @@
|
|||
<?php
|
||||
|
||||
namespace OpenTelemetry\Config\SDK\Configuration;
|
||||
|
||||
class ComponentProviderRegistry {}
|
|
@ -0,0 +1,5 @@
|
|||
<?php
|
||||
|
||||
namespace OpenTelemetry\Config\SDK\Configuration;
|
||||
|
||||
class Context {}
|
|
@ -0,0 +1,3 @@
|
|||
Polyfills for deptrac, which represent classes missing from some PHP versions, or classes
|
||||
that deptrac does not understand.
|
||||
We also use some symfony polyfills for deptrac, under `vendor/symfony/polyfill-*`.
|
|
@ -1,13 +1,11 @@
|
|||
version: '3.7'
|
||||
services:
|
||||
php:
|
||||
build:
|
||||
context: .
|
||||
dockerfile: docker/Dockerfile
|
||||
image: ghcr.io/open-telemetry/opentelemetry-php/opentelemetry-php-base:${PHP_VERSION:-8.1}
|
||||
volumes:
|
||||
- ./:/usr/src/myapp
|
||||
depends_on:
|
||||
- otel-collector
|
||||
- collector
|
||||
zipkin:
|
||||
image: openzipkin/zipkin-slim
|
||||
ports:
|
||||
|
@ -19,8 +17,7 @@ services:
|
|||
ports:
|
||||
- 9412:9412
|
||||
- 16686:16686
|
||||
otel-collector:
|
||||
platform: linux/amd64
|
||||
collector:
|
||||
image: otel/opentelemetry-collector-contrib
|
||||
command: ["--config=/etc/otel-collector-config.yml"]
|
||||
volumes:
|
|
@ -0,0 +1,11 @@
|
|||
services:
|
||||
phpdoc:
|
||||
image: phpdoc/phpdoc:3
|
||||
volumes:
|
||||
- ./:/data
|
||||
preview:
|
||||
image: nginx:alpine
|
||||
ports:
|
||||
- 8080:80
|
||||
volumes:
|
||||
- ./docs/build:/usr/share/nginx/html
|
|
@ -23,7 +23,7 @@ services:
|
|||
context: .
|
||||
dockerfile: docker/examples/Dockerfile
|
||||
args:
|
||||
- PHP_VERSION=7.4-fpm
|
||||
- PHP_VERSION=8.0-fpm
|
||||
- EXT_ENABLE=redis
|
||||
volumes:
|
||||
- ./examples/prometheus/index.php:/var/www/public/index.php
|
||||
|
|
|
@ -1,7 +0,0 @@
|
|||
version: '3.7'
|
||||
services:
|
||||
proto:
|
||||
image: socialpoint/protobuf-tools
|
||||
volumes:
|
||||
- ./:/mnt
|
||||
command: sh -c "/mnt/script/proto_gen.sh"
|
|
@ -1,9 +1,11 @@
|
|||
version: '3.7'
|
||||
services:
|
||||
php:
|
||||
build:
|
||||
context: .
|
||||
dockerfile: docker/Dockerfile
|
||||
image: ghcr.io/open-telemetry/opentelemetry-php/opentelemetry-php-base:${PHP_VERSION:-8.1}
|
||||
volumes:
|
||||
- ./:/usr/src/myapp
|
||||
- ./:/usr/src/open-telemetry/
|
||||
user: "${PHP_USER}:root"
|
||||
environment:
|
||||
XDEBUG_MODE: ${XDEBUG_MODE:-off}
|
||||
XDEBUG_CONFIG: ${XDEBUG_CONFIG:-''}
|
||||
|
|
|
@ -1,13 +1,11 @@
|
|||
version: '3.7'
|
||||
services:
|
||||
php:
|
||||
image: ghcr.io/open-telemetry/opentelemetry-php/opentelemetry-php-base:${PHP_VERSION:-7.4}
|
||||
image: ghcr.io/open-telemetry/opentelemetry-php/opentelemetry-php-base:${PHP_VERSION:-8.1}
|
||||
volumes:
|
||||
- ./:/usr/src/myapp
|
||||
user: "${PHP_USER}:root"
|
||||
environment:
|
||||
XDEBUG_MODE: ${XDEBUG_MODE:-off}
|
||||
XDEBUG_CONFIG: ${XDEBUG_CONFIG:-''}
|
||||
env_file:
|
||||
- .env
|
||||
zipkin:
|
||||
image: openzipkin/zipkin-slim
|
||||
ports:
|
||||
|
@ -19,3 +17,8 @@ services:
|
|||
ports:
|
||||
- 9412:9412
|
||||
- 16686:16686
|
||||
collector:
|
||||
image: otel/opentelemetry-collector-contrib
|
||||
command: [ "--config=/etc/otel-collector-config.yml" ]
|
||||
volumes:
|
||||
- ./files/collector/otel-collector-config.yml:/etc/otel-collector-config.yml
|
||||
|
|
|
@ -1,33 +1,46 @@
|
|||
ARG PHP_VERSION=7.4
|
||||
FROM php:${PHP_VERSION}-cli-alpine as php_build
|
||||
|
||||
ADD https://github.com/mlocati/docker-php-extension-installer/releases/latest/download/install-php-extensions /usr/local/bin/
|
||||
|
||||
RUN chmod +x /usr/local/bin/install-php-extensions; \
|
||||
apk add --update binutils; \
|
||||
install-php-extensions \
|
||||
ast-1.0.14 \
|
||||
xdebug \
|
||||
zip \
|
||||
pcntl \
|
||||
grpc \
|
||||
sockets \
|
||||
@composer \
|
||||
; \
|
||||
# strip debug symbols from extensions to reduce size
|
||||
find /usr/local/lib/php/extensions -name "*.so" -exec strip --strip-debug {} \;;
|
||||
|
||||
FROM php_build
|
||||
|
||||
FROM composer:2.8 AS composer
|
||||
FROM debian:bullseye
|
||||
WORKDIR /usr/src/myapp
|
||||
|
||||
RUN apk add --no-cache bash git; \
|
||||
find /usr/local/lib/php/extensions -type d -exec chmod +x -R {} \;; \
|
||||
addgroup -g "1000" -S php; \
|
||||
adduser --system \
|
||||
--gecos "" \
|
||||
--ingroup "php" \
|
||||
--uid "1000" \
|
||||
"php";
|
||||
RUN apt-get update \
|
||||
&& apt-get install -y --no-install-recommends git wget gnupg2 \
|
||||
&& rm -rf /var/lib/apt/lists/* \
|
||||
&& groupadd --gid 1000 php \
|
||||
&& useradd --system --uid 1000 --gid php --shell /bin/bash --create-home php
|
||||
|
||||
RUN apt-get update && apt-get install -y lsb-release apt-transport-https ca-certificates \
|
||||
&& echo "deb https://packages.sury.org/php/ $(lsb_release -sc) main" > /etc/apt/sources.list.d/php.list \
|
||||
&& wget -qO - https://packages.sury.org/php/apt.gpg | apt-key add - \
|
||||
&& apt-get update
|
||||
|
||||
ARG PHP_VERSION=8.3
|
||||
|
||||
RUN apt-get install -y \
|
||||
php${PHP_VERSION}-ast \
|
||||
php${PHP_VERSION}-cli \
|
||||
php${PHP_VERSION}-curl \
|
||||
php${PHP_VERSION}-dev \
|
||||
php${PHP_VERSION}-grpc \
|
||||
php${PHP_VERSION}-intl \
|
||||
php${PHP_VERSION}-mbstring \
|
||||
php${PHP_VERSION}-opcache \
|
||||
php${PHP_VERSION}-opentelemetry \
|
||||
php${PHP_VERSION}-protobuf \
|
||||
php${PHP_VERSION}-simplexml \
|
||||
php${PHP_VERSION}-sockets \
|
||||
php${PHP_VERSION}-xdebug \
|
||||
php${PHP_VERSION}-zip \
|
||||
php${PHP_VERSION}-mongodb \
|
||||
php${PHP_VERSION}-amqp \
|
||||
php${PHP_VERSION}-rdkafka \
|
||||
php${PHP_VERSION}-mysqli \
|
||||
php${PHP_VERSION}-pgsql \
|
||||
unzip
|
||||
|
||||
COPY --from=composer /usr/bin/composer /usr/local/bin/composer
|
||||
|
||||
RUN echo "grpc.enable_fork_support = 1" > $(php-config --ini-dir)/40-otel-dev.ini \
|
||||
&& echo "grpc.poll_strategy = epoll1" >> $(php-config --ini-dir)/40-otel-dev.ini \
|
||||
&& echo "zend.assertions = 1" >> $(php-config --ini-dir)/40-otel-dev.ini
|
||||
|
||||
USER php
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
version: '3.7'
|
||||
services:
|
||||
gitsplit:
|
||||
image: jderusse/gitsplit
|
||||
volumes:
|
||||
- ../../:/srv
|
||||
- ../../var/cache/gitsplit:/cache/gitsplit
|
||||
environment:
|
||||
GH_TOKEN: ${GITSPLIT_TOKEN:-''}
|
|
@ -1,255 +0,0 @@
|
|||
# Integrating Opentelemetry PHP into Laravel Applications
|
||||
|
||||
## Introduction
|
||||
Distributed tracing helps developers and management gain insights into how well applications perform in terms of traces, metrics, and logs. This guide shows how developers can integrate OpenTelemetry PHP into their Laravel applications for the above benefits. Our example application visualizes exceptions from a Laravel application using both Jaeger and Zipkin.
|
||||
|
||||
To follow this guide you will need:
|
||||
|
||||
* PHP Installed; this example uses PHP 7.4.
|
||||
* [Composer](https://getcomposer.org/download/ ) for dependency management.
|
||||
* [Docker](https://docs.docker.com/get-docker/) for bundling our visualization tools. We have setup instructions for docker on this project's [readme](https://github.com/open-telemetry/opentelemetry-php#development).
|
||||
|
||||
This example uses Laravel version 8.40 .
|
||||
|
||||
## Step 1 - Creating a Laravel Application
|
||||
|
||||
The Laravel framework supports creating applications using composer. To do that, run `composer create-project <project-name>` . We are naming our project `otel-php-laravel-basic-example`, so the command is as follows:
|
||||
|
||||
`composer create-project laravel/laravel otel-php-laravel-basic-example`
|
||||
|
||||
To confirm that our application works, we can move to the application directory using `cd otel-php-laravel-basic-example` , then serve the application with `php artisan serve` .
|
||||
|
||||

|
||||
|
||||
Let's navigate to `http://127.0.0.1:8000` on our browser to see the default Laravel welcome page.
|
||||
|
||||

|
||||
## Step 2 - Require OpenTelemetry PHP Package
|
||||
|
||||
Starting from version `v.0.0.2`, the open-telemetry php package allows users to use their preferred HTTP layers for exporting traces. The benefit of this is that users can reuse already existing HTTP configurations for their applications. Hence, there is need to require packages that satisfy both `psr/http-client-implementation` and `psr/http-factory-implementation` before requiring the opentelemetry-php package.
|
||||
|
||||
By default, the Laravel framework utilizes `guzzlehttp/guzzle` and this satisfies `psr/http-client-implementation`, so we need to require the `guzzlehttp/psr7` to meet the `psr/http-factory-implementation` requirement. Let's run `composer require guzzlehttp/psr7:2.0.0-rc1`.
|
||||
|
||||
Note: We are specifying `2.0.0-rc1` as that is the release for `guzzlehttp/psr7` that includes HTTP factories as at the time of writing this guide.
|
||||
|
||||
Next, let's run `composer require open-telemetry/opentelemetry` to pull in the openTelemetry-php package.
|
||||
|
||||
## Step 3 - Bundle Zipkin and Jaeger into the Application
|
||||
|
||||
To visualize traces exported from our application, we need to integrate open source tracing tools [Zipkin](https://zipkin.io/) and [Jaeger](https://www.jaegertracing.io/) into our setup using docker.
|
||||
|
||||
First, we create a `docker-compose.yaml` file in the root of our project, with content as follows:
|
||||
|
||||
```yaml
|
||||
version: '3.7'
|
||||
services:
|
||||
zipkin:
|
||||
image: openzipkin/zipkin-slim
|
||||
ports:
|
||||
- 9411:9411
|
||||
jaeger:
|
||||
image: jaegertracing/all-in-one
|
||||
environment:
|
||||
COLLECTOR_ZIPKIN_HOST_PORT: 9412
|
||||
|
||||
ports:
|
||||
- 9412:9412
|
||||
- 16686:16686
|
||||
```
|
||||
|
||||
Next, we pull in Zipkin and Jaeger by running `docker-compose up -d`. This might take some time, depending on your internet connection speed.
|
||||
|
||||

|
||||
|
||||
We can confirm that Zipkin is up by navigating to `http://localhost:9411/` on our browser. For Jaeger, navigating to `http://localhost:16686/` on our browser should display the Jaeger home page.
|
||||
|
||||

|
||||
|
||||

|
||||
|
||||
## Step 5 - Instrument Laravel Application
|
||||
|
||||
For this step, we will utilize our OpenTelemetry PHP Library to export traces to both Zipkin and Jaeger.
|
||||
|
||||
The default entry point for Laravel applications is the `index.php` file located in the `public` folder. If we navigate to `public\index.php` we can see that the index file autoloads classes from packages within our vendor folder, making them easily useable within our application.
|
||||
|
||||
```php
|
||||
require __DIR__.'/../vendor/autoload.php';
|
||||
```
|
||||
|
||||
The other parts of the `index.php` file enable request and response resolution using the application kernel.
|
||||
|
||||
```php
|
||||
$app = require_once __DIR__.'/../bootstrap/app.php';
|
||||
|
||||
$kernel = $app->make(Kernel::class);
|
||||
|
||||
$response = tap($kernel->handle(
|
||||
$request = Request::capture()
|
||||
))->send();
|
||||
|
||||
$kernel->terminate($request, $response);
|
||||
```
|
||||
It is worthy of note that resources(namespaces, classes, variables) created within the `index.php` file are available within the entire application.
|
||||
|
||||
To use open-telemetry specific classes within our application we have to import them at the top of our index file, using the `use` keyword. This is what our list of open-telemetry imported classes should look like:
|
||||
|
||||
```php
|
||||
use OpenTelemetry\Contrib\Jaeger\Exporter as JaegerExporter;
|
||||
use OpenTelemetry\Contrib\Zipkin\Exporter as ZipkinExporter;
|
||||
use OpenTelemetry\Context\Context;
|
||||
use OpenTelemetry\SDK\Trace\Sampler\AlwaysOnSampler;
|
||||
use OpenTelemetry\SDK\Trace\SamplingResult;
|
||||
use OpenTelemetry\SDK\Trace\SpanProcessor\BatchSpanProcessor;
|
||||
use OpenTelemetry\SDK\Trace\TracerProvider;
|
||||
use OpenTelemetry\API\Trace as API;
|
||||
use GuzzleHttp\Client;
|
||||
use GuzzleHttp\Psr7\HttpFactory;
|
||||
```
|
||||
|
||||
Remember that these imports should go side by side with the default class imports that come with the `index.php` file.
|
||||
|
||||
Next, we create a sample recording trace using the [AlwaysOnSampler](https://github.com/open-telemetry/opentelemetry-php/blob/main/sdk/Trace/Sampler/AlwaysOnSampler.php) class, just before the app instance is created like below:
|
||||
|
||||
```php
|
||||
$sampler = new AlwaysOnSampler();
|
||||
$samplingResult = $sampler->shouldSample(
|
||||
new Context(),
|
||||
md5((string) microtime(true)),
|
||||
'io.opentelemetry.example',
|
||||
API\SpanKind::KIND_INTERNAL
|
||||
);
|
||||
```
|
||||
|
||||
Since we are looking to export traces to both Zipkin and Jaeger we have to make use of their exporters;
|
||||
|
||||
```php
|
||||
$jaegerExporter = new JaegerExporter(
|
||||
'Hello World Web Server Jaeger',
|
||||
'http://localhost:9412/api/v2/spans',
|
||||
new Client(),
|
||||
new HttpFactory(),
|
||||
new HttpFactory()
|
||||
);
|
||||
|
||||
$zipkinExporter = new ZipkinExporter(
|
||||
'Hello World Web Server Zipkin',
|
||||
'http://localhost:9411/api/v2/spans',
|
||||
new Client(),
|
||||
new HttpFactory(),
|
||||
new HttpFactory()
|
||||
);
|
||||
```
|
||||
|
||||
Next, we create a trace then add processors for each trace(One for Jaeger and another for Zipkin). Then we proceed to start and activate a span for each trace. We create a trace only if the RECORD AND SAMPLED sampling result condition passes as follows;
|
||||
|
||||
```php
|
||||
if (SamplingResult::RECORD_AND_SAMPLE === $samplingResult->getDecision()) {
|
||||
|
||||
$jaegerTracer = (new TracerProvider(null, $sampler))
|
||||
->addSpanProcessor(new BatchSpanProcessor($jaegerExporter, Clock::get()))
|
||||
->getTracer('io.opentelemetry.contrib.php');
|
||||
|
||||
$zipkinTracer = (new TracerProvider(null, $sampler))
|
||||
->addSpanProcessor(new BatchSpanProcessor($zipkinExporter, Clock::get()))
|
||||
->getTracer('io.opentelemetry.contrib.php');
|
||||
|
||||
$request = Request::createFromGlobals();
|
||||
$jaegerSpan = $jaegerTracer->startAndActivateSpan($request->getUri());
|
||||
$zipkinSpan = $zipkinTracer->startAndActivateSpan($request->getUri());
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
Finally, we end the active spans if sampling is complete, by adding the following block at the end of the `index.php` file;
|
||||
|
||||
```php
|
||||
if (SamplingResult::RECORD_AND_SAMPLE === $samplingResult->getDecision()) {
|
||||
$zipkinSpan->end();
|
||||
$jaegerSpan->end();
|
||||
}
|
||||
```
|
||||
|
||||
Let's confirm that we can see exported traces on both Zipkin and Jaeger. To do that, we need to reload `http://127.0.0.1:8000` on our browser;
|
||||
|
||||
We also need reload both Zipkin and Jaeger on our browser, using the URLs `http://localhost:9411/` and `http://localhost:16686/`. Do ensure that both your Laravel server and docker instance are running for this step.
|
||||
|
||||
For Jaeger under service, you should see a `Hello World Web Server Jaeger` service. Go ahead and click find traces to see exported traces.
|
||||
|
||||

|
||||
|
||||
|
||||
Once we click on `Find Traces`, you should be able to see traces like below:
|
||||
|
||||

|
||||
|
||||
|
||||
|
||||
We can click on a trace to get more information about the trace.
|
||||
|
||||

|
||||
|
||||
|
||||
For Zipkin, we can visualize our trace by clicking on `Run Query`
|
||||
|
||||

|
||||
|
||||
|
||||
Since resources in Laravel's `public\index.php` file are available to the entire application, we can use any of the already instantiated tracers to further instrument controllers or any other parts of our application.
|
||||
|
||||
Let's create a `Hello` controller to check this out. Run the command `php artisan make:controller HelloController`
|
||||
|
||||

|
||||
|
||||
|
||||
Next we need to add a route for accessing the controller. To do this we need to utilize the `HelloController` class within our web routes file located in the `routes\web.php` as follows:
|
||||
|
||||
```php
|
||||
use App\Http\Controllers\HelloController;
|
||||
```
|
||||
Next we need to add a route and method for the controller.
|
||||
|
||||
```php
|
||||
Route::get('/hello', [HelloController::class, 'index']);
|
||||
```
|
||||
The above snippet routes every GET request from the `/hello` route on the browser to an index method within the `HelloController` class. For now, this method does not exist, so we have to add it to our controller as follows
|
||||
|
||||
```php
|
||||
public function index(){
|
||||
return "hello";
|
||||
}
|
||||
```
|
||||
Let's confirm that everything works well by visiting the `/hello` route on our browser.
|
||||
|
||||

|
||||
|
||||
|
||||
Now that we have the `index` method working, we can simulate adding an exception event to our Zipkin trace as follows:
|
||||
|
||||
```php
|
||||
global $zipkinTracer;
|
||||
if ($zipkinTracer) {
|
||||
/** @var Span $span */
|
||||
$span = $zipkinTracer->getActiveSpan();
|
||||
|
||||
$span->setAttribute('foo', 'bar');
|
||||
$span->updateName('New name');
|
||||
|
||||
$childSpan = $zipkinTracer->startAndActivateSpan('Child span');
|
||||
try {
|
||||
throw new \Exception('Exception Example');
|
||||
} catch (\Exception $exception) {
|
||||
$span->setSpanStatus($exception->getCode(), $exception->getMessage());
|
||||
}
|
||||
$childSpan->end();
|
||||
}
|
||||
```
|
||||
In the above snippet we change the span name and attributes for our Zipkin trace, we also add an exception event to the span.
|
||||
|
||||
We need to reload our `http://127.0.0.1:8000/hello` route, then navigate to Zipkin like before, to see that our span name gets updated to `new name` and our `Exception Example` is visible.
|
||||
|
||||

|
||||
|
||||
|
||||
## Summary
|
||||
With the above example we have been able to instrument a Laravel application using the OpenTelemetry PHP library. You can fork the example project [here](https://github.com/prondubuisi/otel-php-laravel-basic-example).
|
|
@ -0,0 +1,291 @@
|
|||
# Exploring Opentelemetry in Laravel Applications
|
||||
|
||||
## Introduction
|
||||
|
||||
Distributed tracing helps developers and management gain insights into how well applications perform in terms of traces,
|
||||
metrics, and logs. This guide shows how developers can integrate OpenTelemetry PHP into their Laravel applications for
|
||||
the above benefits. Our example application visualizes exceptions from a Laravel application using both Jaeger and
|
||||
Zipkin.
|
||||
|
||||
To follow this guide you will need:
|
||||
|
||||
* PHP Installed; this example uses PHP 7.4.
|
||||
* [Composer](https://getcomposer.org/download/ ) for dependency management.
|
||||
* [Docker](https://docs.docker.com/get-docker/) for bundling our visualization tools. We have setup instructions for
|
||||
docker on this project's [readme](https://github.com/open-telemetry/opentelemetry-php#development).
|
||||
|
||||
This example uses Laravel version `9.1` and OpenTelemetry PHP SDK version `0.0.11`.
|
||||
|
||||
> ⚠ This example is only intended to introduce how OpenTelemetry can be used in a Laravel application. The
|
||||
> example code is not suited for production applications, and must not be consulted for any code that goes into
|
||||
> production.
|
||||
|
||||
## Step 1 - Creating a Laravel Application
|
||||
|
||||
The Laravel framework supports creating applications using composer. To do that,
|
||||
run `composer create-project <project-name>`. We are naming our project `otel-php-laravel-basic-example`, so the
|
||||
command is as follows:
|
||||
|
||||
`composer create-project laravel/laravel otel-php-laravel-basic-example`
|
||||
|
||||
To confirm that our application works, we can move to the application directory
|
||||
using `cd otel-php-laravel-basic-example` , then serve the application with `php artisan serve` .
|
||||
|
||||

|
||||
|
||||
Let's navigate to `http://127.0.0.1:8000` on our browser to see the default Laravel welcome page.
|
||||
|
||||

|
||||
|
||||
## Step 2 - Require OpenTelemetry PHP Package
|
||||
|
||||
Starting from version `v.0.0.2`, the open-telemetry php package allows users to use their preferred HTTP layers for
|
||||
exporting traces. The benefit of this is that users can reuse already existing HTTP configurations for their
|
||||
applications. Hence, there is need to require packages that satisfy both `psr/http-client-implementation`
|
||||
and `psr/http-factory-implementation` before requiring the opentelemetry-php package.
|
||||
|
||||
By default, the Laravel framework utilizes `guzzlehttp/guzzle` and this satisfies `psr/http-client-implementation`, so
|
||||
we need to require the `guzzlehttp/psr7` to meet the `psr/http-factory-implementation` requirement. Let's
|
||||
run `composer require guzzlehttp/psr7:2.1`.
|
||||
|
||||
Note: We are specifying `2.1` as that is the release for `guzzlehttp/psr7` that includes HTTP factories as at the
|
||||
time of writing this guide.
|
||||
|
||||
Starting from version `v.0.0.4`, opentelemetry-php package also requires `php-http/async-client-implementation`. Any
|
||||
client implementation would work, but for this example, let's go ahead with `php-http/guzzle7-adapter`. Run
|
||||
`composer require php-http/guzzle7-adapter` to install `php-http/guzzle7-adapter`.
|
||||
|
||||
Next, let's run `composer require open-telemetry/opentelemetry` to pull in the openTelemetry-php package. It is worthy
|
||||
of note that this command pulls in the last stable release for the library.
|
||||
|
||||
## Step 3 - Bundle Zipkin and Jaeger into the Application
|
||||
|
||||
To visualize traces exported from our application, we need to integrate open source tracing
|
||||
tools [Zipkin](https://zipkin.io/) and [Jaeger](https://www.jaegertracing.io/) into our setup using docker.
|
||||
|
||||
First, we create a `docker-compose.yaml` file in the root of our project, with content as follows:
|
||||
|
||||
```yaml
|
||||
version: '3.7'
|
||||
services:
|
||||
zipkin:
|
||||
image: openzipkin/zipkin-slim
|
||||
ports:
|
||||
- "9411:9411"
|
||||
jaeger:
|
||||
image: jaegertracing/all-in-one
|
||||
environment:
|
||||
COLLECTOR_ZIPKIN_HOST_PORT: 9412
|
||||
|
||||
ports:
|
||||
- "9412:9412"
|
||||
- "16686:16686"
|
||||
```
|
||||
|
||||
Next, we pull in Zipkin and Jaeger by running `docker-compose up -d`. This might take some time, depending on your
|
||||
internet connection speed.
|
||||
|
||||

|
||||
|
||||
We can confirm that Zipkin is up by navigating to `http://localhost:9411/` on our browser. For Jaeger, navigating
|
||||
to `http://localhost:16686/` on our browser should display the Jaeger home page.
|
||||
|
||||

|
||||
|
||||

|
||||
|
||||
## Step 5 - Instrument Laravel Application
|
||||
|
||||
For this step, we will utilize our OpenTelemetry PHP Library to export traces to both Zipkin and Jaeger.
|
||||
|
||||
The default entry point for Laravel applications is the `index.php` file located in the `public` folder. If we navigate
|
||||
to `public\index.php` we can see that the index file autoloads classes from packages within our vendor folder, making
|
||||
them easily usable within our application.
|
||||
|
||||
```php
|
||||
require __DIR__.'/../vendor/autoload.php';
|
||||
```
|
||||
|
||||
The other parts of the `index.php` file enable request and response resolution using the application kernel.
|
||||
|
||||
```php
|
||||
$app = require_once __DIR__.'/../bootstrap/app.php';
|
||||
|
||||
$kernel = $app->make(Kernel::class);
|
||||
|
||||
$response = tap($kernel->handle(
|
||||
$request = Request::capture()
|
||||
))->send();
|
||||
|
||||
$kernel->terminate($request, $response);
|
||||
```
|
||||
|
||||
It is worthy of note that resources(namespaces, classes, variables) created within the `index.php` file are available
|
||||
within the entire application.
|
||||
|
||||
To use open-telemetry specific classes within our application we have to import them at the top of our index file, using
|
||||
the `use` keyword. This is what our list of open-telemetry imported classes should look like:
|
||||
|
||||
```php
|
||||
use GuzzleHttp\Client;
|
||||
use GuzzleHttp\Psr7\HttpFactory;
|
||||
use OpenTelemetry\API\Trace\Span;
|
||||
use OpenTelemetry\API\Trace\StatusCode;
|
||||
use OpenTelemetry\API\Trace\TracerInterface;
|
||||
use OpenTelemetry\Contrib\Zipkin\Exporter as ZipkinExporter;
|
||||
use OpenTelemetry\SDK\Common\Export\Http\PsrTransportFactory;
|
||||
use OpenTelemetry\SDK\Trace\Sampler\AlwaysOnSampler;
|
||||
use OpenTelemetry\SDK\Trace\SpanProcessor\BatchSpanProcessor;
|
||||
use OpenTelemetry\SDK\Trace\SpanProcessor\SimpleSpanProcessor;
|
||||
use OpenTelemetry\SDK\Trace\TracerProvider;
|
||||
```
|
||||
|
||||
Remember that these imports should go side by side with the default class imports that come with the `index.php` file.
|
||||
|
||||
Next, we create a sample recording trace using
|
||||
the [AlwaysOnSampler](https://github.com/open-telemetry/opentelemetry-php/blob/main/sdk/Trace/Sampler/AlwaysOnSampler.php)
|
||||
class, which is default. Since we are looking to export traces to both Zipkin and Jaeger, we configure a tracer with exporters for both the
|
||||
services just before the app instance is created like below;
|
||||
|
||||
```php
|
||||
$httpClient = new Client();
|
||||
$httpFactory = new HttpFactory();
|
||||
|
||||
$tracer = (new TracerProvider(
|
||||
[
|
||||
new SimpleSpanProcessor(
|
||||
new OpenTelemetry\Contrib\Zipkin\Exporter(
|
||||
PsrTransportFactory::discover()->create('http://zipkin:9411/api/v2/spans', 'application/json')
|
||||
),
|
||||
),
|
||||
],
|
||||
new AlwaysOnSampler(),
|
||||
))->getTracer('Hello World Laravel Web Server');
|
||||
```
|
||||
|
||||
Next we create a span from our tracer;
|
||||
|
||||
```php
|
||||
$request = Request::capture();
|
||||
$span = $tracer->spanBuilder($request->url())->startSpan();
|
||||
$spanScope = $span->activate();
|
||||
```
|
||||
|
||||
Finally, we end the active spans once and detach the span scope by adding the following block at the end of
|
||||
the `index.php` file;
|
||||
|
||||
```php
|
||||
$span->end();
|
||||
$spanScope->detach();
|
||||
```
|
||||
|
||||
Let's confirm that we can see exported traces on both Zipkin and Jaeger. To do that, we need to
|
||||
reload `http://127.0.0.1:8000` on our browser;
|
||||
|
||||
We also need reload both Zipkin and Jaeger on our browser, using the URLs `http://localhost:9411/`
|
||||
and `http://localhost:16686/`. Do ensure that both your Laravel server and docker instance are running for this step.
|
||||
|
||||
For Jaeger under service, you should see a `Hello World Web Server Jaeger` service. Go ahead and click find traces to
|
||||
see exported traces.
|
||||
|
||||

|
||||
|
||||
Once we click on `Find Traces`, you should be able to see traces like below:
|
||||
|
||||

|
||||
|
||||
We can click on a trace to get more information about the trace.
|
||||
|
||||

|
||||
|
||||
For Zipkin, we can visualize our trace by clicking on `Run Query`
|
||||
|
||||

|
||||
|
||||
Since resources in Laravel's `public\index.php` file are available to the entire application, we can use any of the
|
||||
already instantiated tracers to further instrument controllers or any other parts of our application.
|
||||
|
||||
Let's create a `Hello` controller to check this out. Run the command `php artisan make:controller HelloController`
|
||||
|
||||

|
||||
|
||||
Next we need to add a route for accessing the controller. To do this we need to utilize the `HelloController` class
|
||||
within our web routes file located in the `routes\web.php` as follows:
|
||||
|
||||
```php
|
||||
use App\Http\Controllers\HelloController;
|
||||
```
|
||||
|
||||
Next we need to add a route and method for the controller.
|
||||
|
||||
```php
|
||||
Route::get('/hello', [HelloController::class, 'index']);
|
||||
```
|
||||
|
||||
The above snippet routes every GET request from the `/hello` route on the browser to an index method within
|
||||
the `HelloController` class. For now, this method does not exist, so we have to add it to our controller in
|
||||
`app\Http\Controllers\HelloController.php` as follows:
|
||||
|
||||
```php
|
||||
public function index(){
|
||||
return "hello";
|
||||
}
|
||||
```
|
||||
|
||||
Let's confirm that everything works well by visiting the `/hello` route on our browser.
|
||||
|
||||

|
||||
|
||||
Now that we have the `index` method working, let's make changes to the existing rootSpan and create an exception in a
|
||||
child span of the rootSpan. We can do the same as follows:
|
||||
|
||||
- Import the required functions on top of the file:
|
||||
|
||||
```php
|
||||
use OpenTelemetry\API\Trace\Span;
|
||||
use OpenTelemetry\API\Trace\StatusCode;
|
||||
use OpenTelemetry\SDK\Trace\TracerProvider;
|
||||
```
|
||||
|
||||
- Put the below snippet in `index()` function before the `return` statement:
|
||||
|
||||
```php
|
||||
/** @var TracerProvider $tracer */
|
||||
$tracer = TracerProvider::getDefaultTracer();
|
||||
if ($tracer) {
|
||||
/** @var Span $span */
|
||||
$span = Span::getCurrent();
|
||||
|
||||
$span->setAttribute('foo', 'bar');
|
||||
$span->setAttribute('Application', 'Laravel');
|
||||
$span->setAttribute('foo', 'bar1');
|
||||
$span->updateName('New name');
|
||||
|
||||
$childSpan = $tracer->spanBuilder('Child span')->startSpan();
|
||||
$childScope = $childSpan->activate();
|
||||
try {
|
||||
throw new \Exception('Exception Example');
|
||||
} catch (\Exception $exception) {
|
||||
$childSpan->recordException($exception);
|
||||
}
|
||||
$childSpan->end();
|
||||
$childScope->detach();
|
||||
}
|
||||
```
|
||||
|
||||
In the above snippet, we set two new attributes for the current span, and then change the value for one of the attribute
|
||||
and the trace reflects the latest value. We also change the name of our current span and add an exception event to the
|
||||
child span.
|
||||
|
||||
* Point to note: all the variables in `index.php` are available in this file. But we use inbuilt functions to get `$tracer`
|
||||
rather than using the global variables.
|
||||
|
||||
We need to reload our `http://127.0.0.1:8000/hello` route, then navigate to Zipkin and Jaeger like before, to see that our
|
||||
span name gets updated to `new name` and our `Exception Example` is visible.
|
||||
|
||||

|
||||
|
||||
## Summary
|
||||
|
||||
With the above example we have been able to instrument a Laravel application using the OpenTelemetry PHP library. You
|
||||
can fork the example project [here](https://github.com/prondubuisi/otel-php-laravel-basic-example).
|
|
@ -1,239 +0,0 @@
|
|||
# Integrating Opentelemetry PHP into Symfony Applications
|
||||
|
||||
## Introduction
|
||||
|
||||
As a developer, you might be wondering how OpenTelemetry could be beneficial to you. Without practical examples, the usefulness of distributed tracing can be difficult to grasp for persons without a cloud or site reliability engineering background. This user guide shows how OpenTelemetry could be useful to gain insights into exceptions happening within an application. This example uses the OpenTelemtry PHP library integrated into a Symfony application, bundled with Jaeger and Zipkin, for visualizing data.
|
||||
## Prerequisites
|
||||
To follow this guide you will need:
|
||||
|
||||
* PHP Installed, this example uses PHP 7.4.
|
||||
* [Composer](https://getcomposer.org/download/ ) for dependency management.
|
||||
* [Symfony CLI](https://symfony.com/download) for managing your Symfony application.
|
||||
* [Docker](https://docs.docker.com/get-docker/) for bundling our visualization tools. We have setup instructions for docker on this project's [readme](https://github.com/open-telemetry/opentelemetry-php#development).
|
||||
|
||||
This example uses Symfony version 5.2 .
|
||||
|
||||
## Step 1 - Creating a Symfony Application
|
||||
|
||||
Create a Symfony application by running the command `symfony new my_project_name`. We are calling this example `otel-php-symfony-basic-example`, so the command is as follows;
|
||||
|
||||
`symfony new otel-php-symfony-basic-example` .
|
||||
|
||||
## Step 2 - Require and Test Symfony Dependencies
|
||||
|
||||
To define our routes within our controller methods, let's require the Doctrine annotation library by running the command `composer require doctrine/annotations`.
|
||||
|
||||
We can test that routes defined within Controllers work by creating a `HelloController.php` file within the `src\Controller` folder as follows:
|
||||
```php
|
||||
<?php
|
||||
|
||||
namespace App\Controller;
|
||||
|
||||
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
use Symfony\Component\Routing\Annotation\Route;
|
||||
|
||||
class HelloController extends AbstractController
|
||||
{
|
||||
/**
|
||||
* @Route("/hello", name="hello")
|
||||
*/
|
||||
public function index(): Response
|
||||
{
|
||||
return new Response('Hello World');
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
To check out the routes available in our current project run `php bin/console debug:router`.
|
||||
|
||||

|
||||
|
||||
|
||||
|
||||
Let's confirm that our application works by running the command `symfony server:start`.
|
||||
|
||||

|
||||
|
||||
|
||||
|
||||
You can navigate to `http://127.0.0.1:8000/hello` route to see the `Hello world` response returned from the HelloController index method above.
|
||||
|
||||

|
||||
|
||||
|
||||
|
||||
## Step 3 - Require the OpenTelemetry PHP Library
|
||||
|
||||
For this step, we require the OpenTelemetry PHP Library by running the command `composer require open-telemetry/opentelemetry`. It is worthy of note that this command pulls in the last stable release for the library.
|
||||
|
||||
## Step 4 - Bundle Zipkin and Jaeger into the Application
|
||||
|
||||
To visualize traces from our application, we have to bundle open source tracing tools [Zipkin](https://zipkin.io/) and [Jaeger](https://www.jaegertracing.io/) into our application using docker.
|
||||
|
||||
Let's add a `docker-compose.yaml` file in the root of our project with the content as follows:
|
||||
|
||||
```yaml
|
||||
version: '3.7'
|
||||
services:
|
||||
zipkin:
|
||||
image: openzipkin/zipkin-slim
|
||||
ports:
|
||||
- 9411:9411
|
||||
jaeger:
|
||||
image: jaegertracing/all-in-one
|
||||
environment:
|
||||
COLLECTOR_ZIPKIN_HOST_PORT: 9412 # Before version 1.22.0 use COLLECTOR_ZIPKIN_HTTP_PORT
|
||||
ports:
|
||||
- 9412:9412
|
||||
- 16686:16686
|
||||
```
|
||||
|
||||
To confirm that docker is installed and running on our system, we can run the hello world docker example using the command `docker run -it --rm hello-world`. If everything works well, run `docker-compose up -d` to pull in Zipkin and Jaeger. This might take some time, depending on your internet connection speed.
|
||||
|
||||

|
||||
|
||||
|
||||
We can confirm that Zipkin is up by navigating to `http://localhost:9411/` on our browser. For Jaeger, navigating to `http://localhost:16686/` on our browser should display the Jaeger home page.
|
||||
|
||||

|
||||
|
||||

|
||||
|
||||
|
||||
Now it is time to utilize our OpenTelemetry PHP Library to export traces to both Zipkin and Jaeger.
|
||||
|
||||
## Step 5 - Instrument Symfony Application
|
||||
|
||||
The entry point for all Symfony applications is the `index.php` file located in the `public` folder. Let's navigate to `public\index.php` to see what is happening. It is worthy of note that resources(namespaces, classes, variables) created within the `index.php` file are available within the entire application, by default the index file imports all auto loaded classes within the vendor folder. It also imports contents of the `.env` file. The other parts of the `index.php` file enable debugging as well as support request and response resolution using the application kernel.
|
||||
|
||||
To use open-telemetry specific classes we have to import them at the top of our index file, using the `use` keyword. This is what our imports look like:
|
||||
|
||||
```php
|
||||
use App\Kernel;
|
||||
use OpenTelemetry\Contrib\Jaeger\Exporter as JaegerExporter;
|
||||
use OpenTelemetry\Contrib\Zipkin\Exporter as ZipkinExporter;
|
||||
use OpenTelemetry\SDK\Trace\Sampler\AlwaysOnSampler;
|
||||
use OpenTelemetry\SDK\Trace\SamplingResult;
|
||||
use OpenTelemetry\SDK\Trace\SpanProcessor\BatchSpanProcessor;
|
||||
use OpenTelemetry\SDK\Trace\TracerProvider;
|
||||
use OpenTelemetry\API\Trace as API;
|
||||
use Symfony\Component\Dotenv\Dotenv;
|
||||
use Symfony\Component\ErrorHandler\Debug;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
```
|
||||
|
||||
Next, we create a sample recording trace using the [AlwaysOnSampler](https://github.com/open-telemetry/opentelemetry-php/blob/main/sdk/Trace/Sampler/AlwaysOnSampler.php) class, just before the Kernel instance is created like below:
|
||||
|
||||
```php
|
||||
$sampler = new AlwaysOnSampler();
|
||||
$samplingResult = $sampler->shouldSample(
|
||||
null,
|
||||
md5((string) microtime(true)),
|
||||
substr(md5((string) microtime(true)), 16),
|
||||
'io.opentelemetry.example',
|
||||
API\SpanKind::KIND_INTERNAL
|
||||
);
|
||||
```
|
||||
|
||||
Since we are looking to export traces to both Zipkin and Jaeger we have to make use of their individual exporters;
|
||||
|
||||
```php
|
||||
$jaegerExporter = new JaegerExporter(
|
||||
'Hello World Web Server Jaeger',
|
||||
'http://localhost:9412/api/v2/spans'
|
||||
);
|
||||
|
||||
$zipkinExporter = new ZipkinExporter(
|
||||
'Hello World Web Server Zipkin',
|
||||
'http://localhost:9411/api/v2/spans'
|
||||
);
|
||||
```
|
||||
|
||||
Next we create a trace, and add processors for each trace(One for Jaeger and another for Zipkin). Then we proceed to start and activate a span for each trace. We create a trace only if the RECORD AND SAMPLED sampling result condition passes as follows;
|
||||
|
||||
```php
|
||||
if (SamplingResult::RECORD_AND_SAMPLED === $samplingResult->getDecision()) {
|
||||
|
||||
$jaegerTracer = (new TracerProvider(null, $sampler))
|
||||
->addSpanProcessor(new BatchSpanProcessor($jaegerExporter, Clock::get()))
|
||||
->getTracer('io.opentelemetry.contrib.php');
|
||||
|
||||
$zipkinTracer = (new TracerProvider(null, $sampler))
|
||||
->addSpanProcessor(new BatchSpanProcessor($zipkinExporter, Clock::get()))
|
||||
->getTracer('io.opentelemetry.contrib.php');
|
||||
|
||||
$request = Request::createFromGlobals();
|
||||
$jaegerSpan = $jaegerTracer->startAndActivateSpan($request->getUri());
|
||||
$zipkinSpan = $zipkinTracer->startAndActivateSpan($request->getUri());
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
Finally we end the active spans if sampling is complete, by adding the following block at the end of the `index.php` file;
|
||||
|
||||
```php
|
||||
if (SamplingResult::RECORD_AND_SAMPLED === $samplingResult->getDecision()) {
|
||||
$zipkinSpan->end();
|
||||
$jaegerSpan->end();
|
||||
}
|
||||
```
|
||||
|
||||
lets confirm that we can see exported traces on both Zipkin and Jaeger. To do that we need to reload `http://127.0.0.1:8000/hello` or any other route on our symfony server;
|
||||
|
||||

|
||||
|
||||
We also need reload both Zipkin and Jaeger on our browser, using the URLs `http://localhost:9411/` and `http://localhost:16686/`. Do ensure that both your symfony server and docker instance are running for this step.
|
||||
|
||||
For Jaeger under service, you should see a `Hello World Web Server Jaeger` service, go ahead and click find traces to see exported traces.
|
||||
|
||||
)
|
||||

|
||||
|
||||
|
||||
Once we click on `Find Traces` you should be able to see traces like below:
|
||||
|
||||

|
||||
|
||||
|
||||
We can click on a trace to get more information about the trace.
|
||||
|
||||

|
||||
|
||||
|
||||
For Zipkin, we can visualize our trace by clicking on `Run Query`
|
||||
|
||||
|
||||

|
||||
|
||||
Since resources in Symfony's `public\index.php` file are available to the entire application, we can use any of the already instantiated tracers within `HelloController`. In addition to the tracers, we can also utilize associated properties, methods and events.
|
||||
|
||||
Lets try using the `addEvent` method, to capture errors within our controller as follows:
|
||||
|
||||
```php
|
||||
global $zipkinTracer;
|
||||
if ($zipkinTracer) {
|
||||
/** @var Span $span */
|
||||
$span = $zipkinTracer->getActiveSpan();
|
||||
|
||||
$span->setAttribute('foo', 'bar');
|
||||
$span->updateName('New name');
|
||||
|
||||
$zipkinTracer->startAndActivateSpan('Child span');
|
||||
try {
|
||||
throw new \Exception('Exception Example');
|
||||
} catch (\Exception $exception) {
|
||||
$span->setSpanStatus($exception->getCode(), $exception->getMessage());
|
||||
}
|
||||
$span->end();
|
||||
}
|
||||
```
|
||||
In the above snippet we change the span name and attributes for our Zipkin trace, we also add an exception event to the span.
|
||||
|
||||
We need to reload our `http://127.0.0.1:8000/hello` route, then navigate to Zipkin like before to see that our span name gets updated to `new name` and our `Exception Example` is visible
|
||||
|
||||

|
||||
|
||||
## Summary
|
||||
|
||||
With the above example we have been able to instrument a Symfony application using the OpenTelemetry php library. You can fork the example project [here](https://github.com/prondubuisi/otel-php-symfony-basic-example). You can also checkout the original test application [here](https://github.com/dkarlovi/opentelemetry-php-user-test).
|
|
@ -1,46 +0,0 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
require __DIR__ . '/../vendor/autoload.php';
|
||||
|
||||
use OpenTelemetry\API\Trace as API;
|
||||
use OpenTelemetry\Context\Context;
|
||||
use OpenTelemetry\SDK\Common\Attribute\Attributes;
|
||||
use OpenTelemetry\SDK\Common\Time\ClockFactory;
|
||||
use OpenTelemetry\SDK\Trace\Sampler\AlwaysOffSampler;
|
||||
use OpenTelemetry\SDK\Trace\SamplingResult;
|
||||
use OpenTelemetry\SDK\Trace\TracerProvider;
|
||||
|
||||
$sampler = new AlwaysOffSampler();
|
||||
$samplingResult = $sampler->shouldSample(
|
||||
Context::getCurrent(),
|
||||
md5((string) microtime(true)),
|
||||
'io.opentelemetry.example',
|
||||
API\SpanKind::KIND_INTERNAL
|
||||
);
|
||||
|
||||
if (SamplingResult::RECORD_AND_SAMPLE === $samplingResult->getDecision()) {
|
||||
$tracer = (new TracerProvider())
|
||||
->getTracer('io.opentelemetry.contrib.php');
|
||||
|
||||
// start a span, register some events
|
||||
$span = $tracer->startAndActivateSpan('session.generate');
|
||||
$span->setAttribute('remote_ip', '1.2.3.4');
|
||||
$span->setAttribute('country', 'USA');
|
||||
|
||||
$timestamp = ClockFactory::getDefault()->timestamp();
|
||||
$span->addEvent('found_login', new Attributes([
|
||||
'id' => 12345,
|
||||
'username' => 'otuser',
|
||||
]), $timestamp);
|
||||
$span->addEvent('generated_session', new Attributes([
|
||||
'id' => md5((string) microtime(true)),
|
||||
]), $timestamp);
|
||||
|
||||
$span->end(); // pass status as an optional argument
|
||||
print_r($span); // print the span as a resulting output
|
||||
} else {
|
||||
echo PHP_EOL . 'Sampling is not enabled';
|
||||
}
|
||||
|
||||
echo PHP_EOL;
|
|
@ -1,58 +0,0 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
require __DIR__ . '/../vendor/autoload.php';
|
||||
|
||||
use OpenTelemetry\Contrib\Jaeger\Exporter as JaegerExporter;
|
||||
use OpenTelemetry\SDK\Common\Attribute\Attributes;
|
||||
use OpenTelemetry\SDK\Trace\Sampler\AlwaysOnSampler;
|
||||
use OpenTelemetry\SDK\Trace\SpanProcessor\SimpleSpanProcessor;
|
||||
use OpenTelemetry\SDK\Trace\TracerProvider;
|
||||
|
||||
$exporter = JaegerExporter::fromConnectionString('http://jaeger:9412/api/v2/spans', 'AlwaysOnJaegerExample');
|
||||
$tracerProvider = new TracerProvider(
|
||||
new SimpleSpanProcessor($exporter),
|
||||
new AlwaysOnSampler(),
|
||||
);
|
||||
|
||||
echo 'Starting AlwaysOnJaegerExample';
|
||||
|
||||
$tracer = $tracerProvider->getTracer();
|
||||
|
||||
$rootSpan = $tracer->spanBuilder('root')->startSpan();
|
||||
$rootSpan->activate();
|
||||
|
||||
for ($i = 0; $i < 5; $i++) {
|
||||
// start a span, register some events
|
||||
$span = $tracer->spanBuilder('session.generate.span-' . $i)->startSpan();
|
||||
|
||||
echo sprintf(
|
||||
PHP_EOL . 'Exporting Trace: %s, Parent: %s, Span: %s',
|
||||
$span->getContext()->getTraceId(),
|
||||
$span->getParentContext()->getSpanId() ?: 'None',
|
||||
$span->getContext()->getSpanId()
|
||||
);
|
||||
|
||||
$span->setAttribute('remote_ip', '1.2.3.4')
|
||||
->setAttribute('country', 'USA');
|
||||
|
||||
$span->addEvent('found_login' . $i, new Attributes([
|
||||
'id' => $i,
|
||||
'username' => 'otuser' . $i,
|
||||
]));
|
||||
$span->addEvent('generated_session', new Attributes([
|
||||
'id' => md5((string) microtime(true)),
|
||||
]));
|
||||
|
||||
try {
|
||||
throw new Exception('Record exception test event');
|
||||
} catch (Exception $exception) {
|
||||
$span->recordException($exception);
|
||||
}
|
||||
|
||||
$span->end();
|
||||
}
|
||||
$rootSpan->end();
|
||||
echo PHP_EOL . 'AlwaysOnJaegerExample complete! See the results at http://localhost:16686/';
|
||||
|
||||
echo PHP_EOL;
|
|
@ -1,71 +0,0 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
require __DIR__ . '/../vendor/autoload.php';
|
||||
|
||||
use Monolog\Handler\StreamHandler;
|
||||
use Monolog\Logger;
|
||||
use OpenTelemetry\Contrib\Jaeger\AgentExporter;
|
||||
use OpenTelemetry\SDK\Attributes;
|
||||
use OpenTelemetry\SDK\GlobalLoggerHolder;
|
||||
use OpenTelemetry\SDK\Trace\Sampler\AlwaysOnSampler;
|
||||
use OpenTelemetry\SDK\Trace\SpanProcessor\SimpleSpanProcessor;
|
||||
use OpenTelemetry\SDK\Trace\TracerProvider;
|
||||
use Psr\Log\LogLevel;
|
||||
|
||||
$logger = new Logger('otel-php', [new StreamHandler(STDOUT, LogLevel::DEBUG)]);
|
||||
GlobalLoggerHolder::set($logger);
|
||||
|
||||
$exporter = new AgentExporter('jaeger-thrift', 'jaeger:6831');
|
||||
$tracerProvider = new TracerProvider(
|
||||
new SimpleSpanProcessor($exporter),
|
||||
new AlwaysOnSampler(),
|
||||
);
|
||||
|
||||
echo 'Starting JaegerThriftExample';
|
||||
|
||||
$tracer = $tracerProvider->getTracer();
|
||||
|
||||
$rootSpan = $tracer->spanBuilder('root')->startSpan();
|
||||
$rootSpan->activate();
|
||||
echo PHP_EOL . sprintf(
|
||||
'Root Span: %s, Parent: %s, Span: %s',
|
||||
$rootSpan->getContext()->getTraceId(),
|
||||
$rootSpan->getParentContext()->getSpanId(),
|
||||
$rootSpan->getContext()->getSpanId()
|
||||
) . PHP_EOL;
|
||||
|
||||
for ($i = 0; $i < 1; $i++) {
|
||||
// start a span, register some events
|
||||
$span = $tracer->spanBuilder('session.generate.span-' . $i)->startSpan();
|
||||
|
||||
echo sprintf(
|
||||
PHP_EOL . 'Exporting Trace: %s, Parent: %s, Span: %s',
|
||||
$span->getContext()->getTraceId(),
|
||||
$span->getParentContext()->getSpanId() ?: 'None',
|
||||
$span->getContext()->getSpanId()
|
||||
) . PHP_EOL;
|
||||
|
||||
$span->setAttribute('remote_ip', '1.2.3.4')
|
||||
->setAttribute('country', 'USA');
|
||||
|
||||
$span->addEvent('found_login' . $i, new Attributes([
|
||||
'id' => $i,
|
||||
'username' => 'otuser' . $i,
|
||||
]));
|
||||
$span->addEvent('generated_session', new Attributes([
|
||||
'id' => md5((string) microtime(true)),
|
||||
]));
|
||||
|
||||
try {
|
||||
throw new Exception('Record exception test event');
|
||||
} catch (Exception $exception) {
|
||||
$span->recordException($exception);
|
||||
}
|
||||
|
||||
$span->end();
|
||||
}
|
||||
$rootSpan->end();
|
||||
echo PHP_EOL . 'JaegerThriftExample complete! See the results at http://localhost:16686/';
|
||||
|
||||
echo PHP_EOL;
|
|
@ -1,99 +0,0 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
require __DIR__ . '/../vendor/autoload.php';
|
||||
|
||||
use GuzzleHttp\Client;
|
||||
use GuzzleHttp\Psr7\HttpFactory;
|
||||
use OpenTelemetry\API\Trace as API;
|
||||
use OpenTelemetry\Context\Context;
|
||||
use OpenTelemetry\Contrib\Newrelic\Exporter as NewrelicExporter;
|
||||
use OpenTelemetry\SDK\Common\Attribute\Attributes;
|
||||
use OpenTelemetry\SDK\Common\Time\ClockFactory;
|
||||
use OpenTelemetry\SDK\Trace\Sampler\AlwaysOnSampler;
|
||||
use OpenTelemetry\SDK\Trace\SamplingResult;
|
||||
use OpenTelemetry\SDK\Trace\SpanProcessor\SimpleSpanProcessor;
|
||||
use OpenTelemetry\SDK\Trace\TracerProvider;
|
||||
|
||||
/*
|
||||
* Experimental example to send trace data to New Relic.
|
||||
* It will send PHP Otel trace data end to end across the internet to a functional backend.
|
||||
* Needs a license key to connect. For a free account/key, go to: https://newrelic.com/signup/
|
||||
*/
|
||||
|
||||
$sampler = new AlwaysOnSampler();
|
||||
$samplingResult = $sampler->shouldSample(
|
||||
Context::getCurrent(),
|
||||
md5((string) microtime(true)),
|
||||
'io.opentelemetry.example',
|
||||
API\SpanKind::KIND_INTERNAL
|
||||
);
|
||||
|
||||
$licenseKey = getenv('NEW_RELIC_INSERT_KEY');
|
||||
|
||||
// Needs a license key in the environment to connect to the backend server.
|
||||
|
||||
if ($licenseKey == false) {
|
||||
echo PHP_EOL . 'NEW_RELIC_INSERT_KEY not found in environment. Newrelic Example tracing is not enabled.';
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Default Trace API endpoint: https://trace-api.newrelic.com/trace/v1
|
||||
* EU data centers: https://trace-api.eu.newrelic.com/trace/v1
|
||||
*/
|
||||
|
||||
$endpointUrl = getenv('NEW_RELIC_ENDPOINT');
|
||||
|
||||
if ($endpointUrl == false) {
|
||||
$endpointUrl = 'https://trace-api.newrelic.com/trace/v1';
|
||||
}
|
||||
|
||||
$newrelicExporter = new NewrelicExporter(
|
||||
'alwaysOnNewrelicExample',
|
||||
$endpointUrl,
|
||||
$licenseKey,
|
||||
new Client(),
|
||||
new HttpFactory(),
|
||||
new HttpFactory()
|
||||
);
|
||||
|
||||
if (SamplingResult::RECORD_AND_SAMPLE === $samplingResult->getDecision()) {
|
||||
echo 'Starting AlwaysOnNewrelicExample';
|
||||
$tracer = (new TracerProvider())
|
||||
->addSpanProcessor(new SimpleSpanProcessor($newrelicExporter))
|
||||
->getTracer('io.opentelemetry.contrib.php');
|
||||
|
||||
for ($i = 0; $i < 5; $i++) {
|
||||
// start a span, register some events
|
||||
$timestamp = ClockFactory::getDefault()->now();
|
||||
$span = $tracer->startAndActivateSpan('session.generate.span.' . microtime(true));
|
||||
|
||||
$spanParent = $span->getParentContext();
|
||||
echo sprintf(
|
||||
PHP_EOL . 'Exporting Trace: %s, Parent: %s, Span: %s',
|
||||
$span->getContext()->getTraceId(),
|
||||
$spanParent ? $spanParent->getSpanId() : 'None',
|
||||
$span->getContext()->getSpanId()
|
||||
);
|
||||
|
||||
$span->setAttribute('remote_ip', '1.2.3.4')
|
||||
->setAttribute('country', 'USA');
|
||||
|
||||
$span->addEvent('found_login' . $i, new Attributes([
|
||||
'id' => $i,
|
||||
'username' => 'otuser' . $i,
|
||||
]), $timestamp);
|
||||
$span->addEvent('generated_session', new Attributes([
|
||||
'id' => md5((string) microtime(true)),
|
||||
]), $timestamp);
|
||||
|
||||
$span->end();
|
||||
}
|
||||
echo PHP_EOL . 'NewrelicExample complete! See the results at https://one.newrelic.com/launcher/distributed-tracing.launcher?pane=eyJuZXJkbGV0SWQiOiJkaXN0cmlidXRlZC10cmFjaW5nLmhvbWUiLCJzb3J0SW5kZXgiOjAsInNvcnREaXJlY3Rpb24iOiJERVNDIiwicXVlcnkiOnsib3BlcmF0b3IiOiJBTkQiLCJpbmRleFF1ZXJ5Ijp7ImNvbmRpdGlvblR5cGUiOiJJTkRFWCIsIm9wZXJhdG9yIjoiQU5EIiwiY29uZGl0aW9uU2V0cyI6W119LCJzcGFuUXVlcnkiOnsib3BlcmF0b3IiOiJBTkQiLCJjb25kaXRpb25TZXRzIjpbeyJjb25kaXRpb25UeXBlIjoiU1BBTiIsIm9wZXJhdG9yIjoiQU5EIiwiY29uZGl0aW9ucyI6W3siYXR0ciI6InNlcnZpY2UubmFtZSIsIm9wZXJhdG9yIjoiRVEiLCJ2YWx1ZSI6ImFsd2F5c09uTmV3cmVsaWNFeGFtcGxlIn1dfV19fX0=&platform[timeRange][duration]=1800000&platform[$isFallbackTimeRange]=true';
|
||||
} else {
|
||||
echo PHP_EOL . 'NewrelicExample tracing is not enabled';
|
||||
}
|
||||
|
||||
echo PHP_EOL;
|
|
@ -1,52 +0,0 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
require __DIR__ . '/../vendor/autoload.php';
|
||||
|
||||
use GuzzleHttp\Client;
|
||||
use GuzzleHttp\Psr7\HttpFactory;
|
||||
use OpenTelemetry\Contrib\OtlpHttp\Exporter as OTLPExporter;
|
||||
use OpenTelemetry\SDK\Common\Attribute\Attributes;
|
||||
use OpenTelemetry\SDK\Trace\SpanProcessor\SimpleSpanProcessor;
|
||||
use OpenTelemetry\SDK\Trace\TracerProvider;
|
||||
|
||||
putenv('OTEL_EXPORTER_OTLP_ENDPOINT=http://collector:4318/v1/traces');
|
||||
$exporter = new OTLPExporter(
|
||||
new Client(),
|
||||
new HttpFactory(),
|
||||
new HttpFactory()
|
||||
);
|
||||
|
||||
echo 'Starting OTLPExample';
|
||||
|
||||
$tracerProvider = new TracerProvider(
|
||||
new SimpleSpanProcessor(
|
||||
$exporter
|
||||
)
|
||||
);
|
||||
$tracer = $tracerProvider->getTracer();
|
||||
|
||||
$root = $span = $tracer->spanBuilder('root')->startSpan();
|
||||
$span->activate();
|
||||
|
||||
for ($i = 0; $i < 3; $i++) {
|
||||
// start a span, register some events
|
||||
$span = $tracer->spanBuilder('loop-' . $i)->startSpan();
|
||||
|
||||
$span->setAttribute('remote_ip', '1.2.3.4')
|
||||
->setAttribute('country', 'USA');
|
||||
|
||||
$span->addEvent('found_login' . $i, new Attributes([
|
||||
'id' => $i,
|
||||
'username' => 'otuser' . $i,
|
||||
]));
|
||||
$span->addEvent('generated_session', new Attributes([
|
||||
'id' => md5((string) microtime(true)),
|
||||
]));
|
||||
|
||||
$span->end();
|
||||
}
|
||||
$root->end();
|
||||
echo PHP_EOL . 'OTLPExample complete! ';
|
||||
|
||||
echo PHP_EOL;
|
|
@ -1,73 +0,0 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
require __DIR__ . '/../vendor/autoload.php';
|
||||
|
||||
use OpenTelemetry\API\Trace as API;
|
||||
use OpenTelemetry\Context\Context;
|
||||
use OpenTelemetry\Contrib\OtlpGrpc\Exporter as OTLPExporter;
|
||||
use OpenTelemetry\SDK\Common\Attribute\Attributes;
|
||||
use OpenTelemetry\SDK\Common\Time\ClockFactory;
|
||||
use OpenTelemetry\SDK\Trace\Sampler\AlwaysOnSampler;
|
||||
use OpenTelemetry\SDK\Trace\SamplingResult;
|
||||
use OpenTelemetry\SDK\Trace\SpanProcessor\SimpleSpanProcessor;
|
||||
use OpenTelemetry\SDK\Trace\TracerProvider;
|
||||
|
||||
$sampler = new AlwaysOnSampler();
|
||||
$samplingResult = $sampler->shouldSample(
|
||||
Context::getCurrent(),
|
||||
md5((string) microtime(true)),
|
||||
'io.opentelemetry.example',
|
||||
API\SpanKind::KIND_INTERNAL
|
||||
);
|
||||
|
||||
$Exporter = new OTLPExporter();
|
||||
|
||||
if (SamplingResult::RECORD_AND_SAMPLE === $samplingResult->getDecision()) {
|
||||
echo 'Starting OTLPGrpcExample';
|
||||
$tracer = (new TracerProvider())
|
||||
->addSpanProcessor(new SimpleSpanProcessor($Exporter))
|
||||
->getTracer('io.opentelemetry.contrib.php');
|
||||
|
||||
for ($i = 0; $i < 5; $i++) {
|
||||
// start a span, register some events
|
||||
$timestamp = ClockFactory::getDefault()->now();
|
||||
$span = $tracer->startAndActivateSpan('session.generate.span' . microtime(true));
|
||||
//startAndActivateSpan('session.generate.span.' . microtime(true));
|
||||
|
||||
$childSpan = $tracer->startSpan('child');
|
||||
|
||||
// Temporarily setting service name here. It should eventually be pulled from tracer.resources.
|
||||
$span->setAttribute('service.name', 'alwaysOnOTLPGrpcExample');
|
||||
|
||||
$span->setAttribute('remote_ip', '1.2.3.4')
|
||||
->setAttribute('country', 'USA');
|
||||
|
||||
$span->addEvent('found_login' . $i, new Attributes([
|
||||
'id' => $i,
|
||||
'username' => 'otuser' . $i,
|
||||
]), $timestamp);
|
||||
$span->addEvent('generated_session', new Attributes([
|
||||
'id' => md5((string) microtime(true)),
|
||||
]), $timestamp);
|
||||
|
||||
// temporarily setting service name here. It should eventually be pulled from tracer.resources.
|
||||
$childSpan->setAttribute('service.name', 'alwaysOnOTLPGrpcExample');
|
||||
|
||||
$childSpan->setAttribute('attr_one', 'one')
|
||||
->setAttribute('attr_two', 'two');
|
||||
|
||||
$childSpan->addEvent('found_event1' . $i, new Attributes([
|
||||
'id' => $i,
|
||||
'username' => 'child' . $i,
|
||||
]), $timestamp);
|
||||
|
||||
$childSpan->end();
|
||||
$span->end();
|
||||
}
|
||||
echo PHP_EOL . 'OTLPGrpcExample complete! ';
|
||||
} else {
|
||||
echo PHP_EOL . 'OTLPGrpcExample tracing is not enabled';
|
||||
}
|
||||
|
||||
echo PHP_EOL;
|
|
@ -1,97 +0,0 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
require __DIR__ . '/../vendor/autoload.php';
|
||||
|
||||
use OpenTelemetry\API\Trace as API;
|
||||
use OpenTelemetry\Context\Context;
|
||||
use OpenTelemetry\Contrib\OtlpGrpc\Exporter as OTLPExporter;
|
||||
use OpenTelemetry\SDK\Common\Attribute\Attributes;
|
||||
use OpenTelemetry\SDK\Common\Time\ClockFactory;
|
||||
use OpenTelemetry\SDK\Trace\Sampler\AlwaysOnSampler;
|
||||
use OpenTelemetry\SDK\Trace\SamplingResult;
|
||||
use OpenTelemetry\SDK\Trace\SpanProcessor\SimpleSpanProcessor;
|
||||
use OpenTelemetry\SDK\Trace\TracerProvider;
|
||||
|
||||
$sampler = new AlwaysOnSampler();
|
||||
$samplingResult = $sampler->shouldSample(
|
||||
Context::getCurrent(),
|
||||
md5((string) microtime(true)),
|
||||
'io.opentelemetry.example',
|
||||
API\SpanKind::KIND_SERVER
|
||||
);
|
||||
|
||||
$Exporter = new OTLPExporter();
|
||||
|
||||
if (SamplingResult::RECORD_AND_SAMPLE === $samplingResult->getDecision()) {
|
||||
echo 'Starting OTLPGrpcExample';
|
||||
$tracer = (new TracerProvider())
|
||||
->addSpanProcessor(new SimpleSpanProcessor($Exporter))
|
||||
->getTracer('io.opentelemetry.contrib.php');
|
||||
$rootSpan = $tracer->startSpan('root-span', null, API\SpanKind::KIND_SERVER);
|
||||
|
||||
// temporarily setting service name here. It should eventually be pulled from tracer.resources.
|
||||
$rootSpan->setAttribute('service.name', 'alwaysOnOTLPGrpcExample');
|
||||
|
||||
$rootSpan->setAttribute('remote_ip', '1.2.3.4')
|
||||
->setAttribute('country', 'USA');
|
||||
$timestamp = ClockFactory::getDefault()->now();
|
||||
$rootSpan->addEvent('found_login', new Attributes([
|
||||
'id' => 1,
|
||||
'username' => 'otuser',
|
||||
]), $timestamp);
|
||||
$rootSpan->addEvent('generated_session', new Attributes([
|
||||
'id' => md5((string) microtime(true)),
|
||||
]), $timestamp);
|
||||
sleep(1);
|
||||
|
||||
$rootScope = $rootSpan->activate(); // set the root span active in the current context
|
||||
|
||||
try {
|
||||
$span1 = $tracer->startSpan('child-span-1', null, API\SpanKind::KIND_SERVER);
|
||||
$internalScope = $span1->activate(); // set the child span active in the context
|
||||
|
||||
try {
|
||||
for ($i = 0; $i < 3; $i++) {
|
||||
$loopSpan = $tracer->startSpan('loop-' . $i, null, API\SpanKind::KIND_CLIENT);
|
||||
$loopSpan->setAttribute('db.statement', 'select foo from bar');
|
||||
$loopSpan->setAttribute('db.system', 'mysql');
|
||||
$loopSpan->setAttribute('db.query', 'select foo from bar');
|
||||
usleep((int) (0.5 * 1e6));
|
||||
$loopSpan->end();
|
||||
}
|
||||
} finally {
|
||||
$internalScope->close(); // deactivate child span, the rootSpan is set back as active
|
||||
}
|
||||
$span1->end();
|
||||
|
||||
$span2 = $tracer->startSpan('child-span-2', null, API\SpanKind::KIND_SERVER);
|
||||
$span2->setAttribute('error.message', 'this is an error');
|
||||
$span2->setAttribute('error.class', 'error.class.this.is');
|
||||
sleep(1);
|
||||
$internalScope = $span2->activate(); // set the child span active in the context
|
||||
|
||||
try {
|
||||
$internalSpan = $tracer->startSpan('internal', null, API\SpanKind::KIND_CLIENT);
|
||||
usleep((int) (0.5 * 1e6));
|
||||
$internalSpan->end();
|
||||
|
||||
$internalSpan = $tracer->startSpan('external', null, API\SpanKind::KIND_CLIENT);
|
||||
usleep((int) (0.5 * 1e6));
|
||||
$internalSpan->setAttribute('http.method', 'GET');
|
||||
$internalSpan->end();
|
||||
} finally {
|
||||
$internalScope->close(); // deactivate child span, the rootSpan is set back as active
|
||||
}
|
||||
$span2->end();
|
||||
} finally {
|
||||
$rootScope->close(); // close the scope of the root span, no active span in the context now
|
||||
}
|
||||
$rootSpan->end();
|
||||
|
||||
echo PHP_EOL . 'OTLPGrpcExample complete! ';
|
||||
} else {
|
||||
echo PHP_EOL . 'OTLPGrpcExample tracing is not enabled';
|
||||
}
|
||||
|
||||
echo PHP_EOL;
|
|
@ -1,99 +0,0 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
require __DIR__ . '/../vendor/autoload.php';
|
||||
|
||||
use GuzzleHttp\Client;
|
||||
use GuzzleHttp\Psr7\HttpFactory;
|
||||
use OpenTelemetry\API\Trace as API;
|
||||
use OpenTelemetry\Context\Context;
|
||||
use OpenTelemetry\Contrib\ZipkinToNewrelic\Exporter as ZipkinToNewrelicExporter;
|
||||
use OpenTelemetry\SDK\Common\Attribute\Attributes;
|
||||
use OpenTelemetry\SDK\Common\Time\ClockFactory;
|
||||
use OpenTelemetry\SDK\Trace\Sampler\AlwaysOnSampler;
|
||||
use OpenTelemetry\SDK\Trace\SamplingResult;
|
||||
use OpenTelemetry\SDK\Trace\SpanProcessor\SimpleSpanProcessor;
|
||||
use OpenTelemetry\SDK\Trace\TracerProvider;
|
||||
|
||||
/*
|
||||
* Experimental example to send trace data to New Relic.
|
||||
* It will send PHP Otel trace data end to end across the internet to a functional backend.
|
||||
* Needs a license key to connect. For a free account/key, go to: https://newrelic.com/signup/
|
||||
*/
|
||||
|
||||
$sampler = new AlwaysOnSampler();
|
||||
$samplingResult = $sampler->shouldSample(
|
||||
Context::getCurrent(),
|
||||
md5((string) microtime(true)),
|
||||
'io.opentelemetry.example',
|
||||
API\SpanKind::KIND_INTERNAL
|
||||
);
|
||||
|
||||
$licenseKey = getenv('NEW_RELIC_INSERT_KEY');
|
||||
|
||||
// Needs a license key in the environment to connect to the backend server.
|
||||
|
||||
if ($licenseKey == false) {
|
||||
echo PHP_EOL . 'NEW_RELIC_INSERT_KEY not found in environment. Newrelic Example tracing is not enabled.';
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Default Trace API endpoint: https://trace-api.newrelic.com/trace/v1
|
||||
* EU data centers: https://trace-api.eu.newrelic.com/trace/v1
|
||||
*/
|
||||
|
||||
$endpointUrl = getenv('NEW_RELIC_ENDPOINT');
|
||||
|
||||
if ($endpointUrl == false) {
|
||||
$endpointUrl = 'https://trace-api.newrelic.com/trace/v1';
|
||||
}
|
||||
|
||||
$zipkinToNewrelicExporter = new ZipkinToNewrelicExporter(
|
||||
'alwaysOnZipkinToNewrelicExample',
|
||||
$endpointUrl,
|
||||
$licenseKey,
|
||||
new Client(),
|
||||
new HttpFactory(),
|
||||
new HttpFactory()
|
||||
);
|
||||
|
||||
if (SamplingResult::RECORD_AND_SAMPLE === $samplingResult->getDecision()) {
|
||||
echo 'Starting AlwaysOnZipkinToNewRelicExample';
|
||||
$tracer = (new TracerProvider())
|
||||
->addSpanProcessor(new SimpleSpanProcessor($zipkinToNewrelicExporter))
|
||||
->getTracer('io.opentelemetry.contrib.php');
|
||||
|
||||
for ($i = 0; $i < 5; $i++) {
|
||||
// start a span, register some events
|
||||
$timestamp = ClockFactory::getDefault()->now();
|
||||
$span = $tracer->startAndActivateSpan('session.generate.span.' . microtime(true));
|
||||
|
||||
$spanParent = $span->getParentContext();
|
||||
echo sprintf(
|
||||
PHP_EOL . 'Exporting Trace: %s, Parent: %s, Span: %s',
|
||||
$span->getContext()->getTraceId(),
|
||||
$spanParent ? $spanParent->getSpanId() : 'None',
|
||||
$span->getContext()->getSpanId()
|
||||
);
|
||||
|
||||
$span->setAttribute('remote_ip', '1.2.3.4')
|
||||
->setAttribute('country', 'USA');
|
||||
|
||||
$span->addEvent('found_login' . $i, new Attributes([
|
||||
'id' => $i,
|
||||
'username' => 'otuser' . $i,
|
||||
]), $timestamp);
|
||||
$span->addEvent('generated_session', new Attributes([
|
||||
'id' => md5((string) microtime(true)),
|
||||
]), $timestamp);
|
||||
|
||||
$span->end();
|
||||
}
|
||||
echo PHP_EOL . 'AlwaysOnZipkinToNewrelicExample complete! See the results at https://one.newrelic.com/launcher/distributed-tracing.launcher?pane=eyJuZXJkbGV0SWQiOiJkaXN0cmlidXRlZC10cmFjaW5nLmhvbWUiLCJzb3J0SW5kZXgiOjAsInNvcnREaXJlY3Rpb24iOiJERVNDIiwicXVlcnkiOnsib3BlcmF0b3IiOiJBTkQiLCJpbmRleFF1ZXJ5Ijp7ImNvbmRpdGlvblR5cGUiOiJJTkRFWCIsIm9wZXJhdG9yIjoiQU5EIiwiY29uZGl0aW9uU2V0cyI6W119LCJzcGFuUXVlcnkiOnsib3BlcmF0b3IiOiJBTkQiLCJjb25kaXRpb25TZXRzIjpbeyJjb25kaXRpb25UeXBlIjoiU1BBTiIsIm9wZXJhdG9yIjoiQU5EIiwiY29uZGl0aW9ucyI6W3siYXR0ciI6InNlcnZpY2UubmFtZSIsIm9wZXJhdG9yIjoiRVEiLCJ2YWx1ZSI6ImFsd2F5c09uWmlwa2luVG9OZXdyZWxpY0V4YW1wbGUifV19XX19fQ==&platform[timeRange][duration]=1800000&platform[$isFallbackTimeRange]=true';
|
||||
} else {
|
||||
echo PHP_EOL . 'AlwaysOnZipkinToNewrelicExample tracing is not enabled';
|
||||
}
|
||||
|
||||
echo PHP_EOL;
|
|
@ -1,29 +0,0 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
require __DIR__ . '/../vendor/autoload.php';
|
||||
|
||||
use OpenTelemetry\SDK\Trace\TracerProviderFactory;
|
||||
|
||||
//@see https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/sdk-environment-variables.md
|
||||
putenv('OTEL_RESOURCE_ATTRIBUTES=service.version=1.0.0');
|
||||
putenv('OTEL_SERVICE_NAME=example-app');
|
||||
putenv('OTEL_LOG_LEVEL=warning');
|
||||
putenv('OTEL_TRACES_SAMPLER=traceidratio');
|
||||
putenv('OTEL_TRACES_SAMPLER_ARG=0.95');
|
||||
putenv('OTEL_TRACES_EXPORTER=console');
|
||||
putenv('OTEL_PHP_TRACES_PROCESSOR=batch');
|
||||
putenv('OTEL_BSP_SCHEDULE_DELAY=10000');
|
||||
|
||||
echo 'Creating Exporter From Environment' . PHP_EOL;
|
||||
|
||||
$tracerProvider = (new TracerProviderFactory('example'))->create();
|
||||
|
||||
$tracer = $tracerProvider->getTracer();
|
||||
|
||||
echo 'Starting Tracer' . PHP_EOL;
|
||||
|
||||
$rootSpan = $tracer->spanBuilder('root')->startSpan();
|
||||
$rootSpan->activate();
|
||||
$rootSpan->addEvent('my_event')->setAttribute('fruit', 'apple');
|
||||
$rootSpan->end();
|
|
@ -1,25 +0,0 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
require __DIR__ . '/../vendor/autoload.php';
|
||||
|
||||
use OpenTelemetry\SDK\Trace\TracerProvider;
|
||||
|
||||
echo 'Starting DefaultTracer example' . PHP_EOL;
|
||||
|
||||
//Until a tracer is created, default is a NoopTracer
|
||||
$initialDefault = TracerProvider::getDefaultTracer();
|
||||
echo sprintf('Initial default tracer: %s', get_class($initialDefault)) . PHP_EOL;
|
||||
|
||||
$tracerProvider = new TracerProvider();
|
||||
|
||||
//create a tracer, which is now the default and is available from anywhere via TracerProvider::getDefaultTracer()
|
||||
$tracer = $tracerProvider->getTracer();
|
||||
echo sprintf('Created tracer: %s', get_class($tracer)) . PHP_EOL;
|
||||
|
||||
$rootSpan = $tracer->spanBuilder('root')->startSpan();
|
||||
$rootSpan->activate();
|
||||
|
||||
$default = TracerProvider::getDefaultTracer();
|
||||
echo sprintf('Default tracer: %s', get_class($default)) . PHP_EOL;
|
||||
$rootSpan->end();
|
|
@ -1,36 +0,0 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
require __DIR__ . '/../vendor/autoload.php';
|
||||
|
||||
use OpenTelemetry\SDK\Trace\SpanExporter\ConsoleSpanExporter;
|
||||
use OpenTelemetry\SDK\Trace\SpanProcessor\SimpleSpanProcessor;
|
||||
use OpenTelemetry\SDK\Trace\TracerProvider;
|
||||
|
||||
echo 'Starting ConsoleSpanExporter' . PHP_EOL;
|
||||
|
||||
$tracerProvider = new TracerProvider(
|
||||
new SimpleSpanProcessor(
|
||||
new ConsoleSpanExporter()
|
||||
)
|
||||
);
|
||||
|
||||
$tracer = $tracerProvider->getTracer();
|
||||
|
||||
$rootSpan = $tracer->spanBuilder('root')->startSpan();
|
||||
$rootSpan->activate();
|
||||
|
||||
try {
|
||||
$span1 = $tracer->spanBuilder('foo')->startSpan();
|
||||
$span1->activate();
|
||||
|
||||
try {
|
||||
$span2 = $tracer->spanBuilder('bar')->startSpan();
|
||||
echo 'OpenTelemetry welcomes PHP' . PHP_EOL;
|
||||
} finally {
|
||||
$span2->end();
|
||||
}
|
||||
} finally {
|
||||
$span1->end();
|
||||
}
|
||||
$rootSpan->end();
|
|
@ -1,82 +0,0 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
require __DIR__ . '/../vendor/autoload.php';
|
||||
|
||||
use GuzzleHttp\Client;
|
||||
use GuzzleHttp\Psr7\HttpFactory;
|
||||
use OpenTelemetry\Contrib\Jaeger\Exporter as JaegerExporter;
|
||||
use OpenTelemetry\Contrib\Zipkin\Exporter as ZipkinExporter;
|
||||
use OpenTelemetry\SDK\Resource\ResourceInfoFactory;
|
||||
use OpenTelemetry\SDK\Trace\Sampler\AlwaysOnSampler;
|
||||
use OpenTelemetry\SDK\Trace\Span;
|
||||
use OpenTelemetry\SDK\Trace\SpanProcessor\SimpleSpanProcessor;
|
||||
use OpenTelemetry\SDK\Trace\TracerProvider;
|
||||
|
||||
$serviceName = 'ParentSpanExample';
|
||||
$resource = ResourceInfoFactory::defaultResource();
|
||||
$sampler = new AlwaysOnSampler();
|
||||
$tracerProvider = new TracerProvider($resource, $sampler);
|
||||
|
||||
// zipkin exporter
|
||||
$zipkinExporter = new ZipkinExporter(
|
||||
$serviceName,
|
||||
'http://zipkin:9411/api/v2/spans',
|
||||
new Client(),
|
||||
new HttpFactory(),
|
||||
new HttpFactory()
|
||||
);
|
||||
$tracerProvider->addSpanProcessor(new SimpleSpanProcessor($zipkinExporter));
|
||||
|
||||
// jaeger exporter
|
||||
$jaegerExporter = new JaegerExporter(
|
||||
$serviceName,
|
||||
'http://jaeger:9412/api/v2/spans',
|
||||
new Client(),
|
||||
new HttpFactory(),
|
||||
new HttpFactory()
|
||||
);
|
||||
$tracerProvider->addSpanProcessor(new SimpleSpanProcessor($jaegerExporter));
|
||||
|
||||
$tracer = $tracerProvider->getTracer('example.php.opentelemetry.io', '0.0.1');
|
||||
|
||||
$rootSpan = $tracer->startSpan('root-span');
|
||||
sleep(1);
|
||||
|
||||
$rootScope = $rootSpan->activate(); // set the root span active in the current context
|
||||
|
||||
try {
|
||||
$span1 = $tracer->startSpan('child-span-1');
|
||||
$internalScope = $span1->activate(); // set the child span active in the context
|
||||
|
||||
try {
|
||||
for ($i = 0; $i < 3; $i++) {
|
||||
$loopSpan = $tracer->startSpan('loop-' . $i);
|
||||
usleep((int) (0.5 * 1e6));
|
||||
$loopSpan->end();
|
||||
}
|
||||
} finally {
|
||||
$internalScope->close(); // deactivate child span, the rootSpan is set back as active
|
||||
}
|
||||
$span1->end();
|
||||
|
||||
$span2 = $tracer->startSpan('child-span-2');
|
||||
sleep(1);
|
||||
$span2->end();
|
||||
} finally {
|
||||
$rootScope->close(); // close the scope of the root span, no active span in the context now
|
||||
}
|
||||
$rootSpan->end();
|
||||
|
||||
// start the second root span
|
||||
$secondRootSpan = $tracer->startSpan('root-span-2');
|
||||
sleep(2);
|
||||
$secondRootSpan->end();
|
||||
|
||||
echo 'This example generates two traces:' . PHP_EOL;
|
||||
echo ' - ' . $rootSpan->getContext()->getTraceId() . PHP_EOL;
|
||||
echo ' - ' . $secondRootSpan->getContext()->getTraceId() . PHP_EOL;
|
||||
echo PHP_EOL;
|
||||
echo 'See the results at' . PHP_EOL;
|
||||
echo 'Jaeger: http://localhost:16686/' . PHP_EOL;
|
||||
echo 'Zipkin: http://localhost:9411/' . PHP_EOL;
|
|
@ -1,20 +0,0 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
require __DIR__ . '/../vendor/autoload.php';
|
||||
|
||||
use OpenTelemetry\SDK\Trace\TracerProviderFactory;
|
||||
|
||||
putenv('OTEL_PHP_DETECTORS=env,sdk,sdk_provided');
|
||||
|
||||
echo 'Handling Resource Detectors From Environment' . PHP_EOL;
|
||||
|
||||
$tracerProvider = (new TracerProviderFactory('example'))->create();
|
||||
|
||||
$tracer = $tracerProvider->getTracer();
|
||||
|
||||
echo 'Starting Tracer' . PHP_EOL;
|
||||
|
||||
$rootSpan = $tracer->spanBuilder('root')->startSpan();
|
||||
$rootSpan->activate();
|
||||
$rootSpan->end();
|
|
@ -1,29 +0,0 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
require __DIR__ . '/../vendor/autoload.php';
|
||||
|
||||
use Monolog\Handler\StreamHandler;
|
||||
use Monolog\Logger;
|
||||
use OpenTelemetry\Contrib\OtlpGrpc\Exporter as OtlpGrpcExporter;
|
||||
use OpenTelemetry\SDK\Common\Log\LoggerHolder;
|
||||
use OpenTelemetry\SDK\Trace\SpanProcessor\SimpleSpanProcessor;
|
||||
use OpenTelemetry\SDK\Trace\TracerProvider;
|
||||
use Psr\Log\LogLevel;
|
||||
|
||||
echo 'Starting SettingUpLogging example' . PHP_EOL;
|
||||
|
||||
//create a Logger, and register it with the global logger holder. The library will use this logger
|
||||
//for all of its internal logging (errors, warnings, etc)
|
||||
LoggerHolder::set(
|
||||
new Logger('otel-php', [new StreamHandler(STDOUT, LogLevel::DEBUG)])
|
||||
);
|
||||
|
||||
$tracerProvider = new TracerProvider(
|
||||
new SimpleSpanProcessor(
|
||||
new OtlpGrpcExporter(), //default endpoint unavailable, so exporting will fail
|
||||
)
|
||||
);
|
||||
$tracer = $tracerProvider->getTracer();
|
||||
$span = $tracer->spanBuilder('root-span')->startSpan();
|
||||
$span->end();
|
|
@ -0,0 +1,26 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace OpenTelemetry\Example;
|
||||
|
||||
putenv('OTEL_PHP_AUTOLOAD_ENABLED=true');
|
||||
putenv('OTEL_TRACES_EXPORTER=otlp');
|
||||
putenv('OTEL_METRICS_EXPORTER=otlp');
|
||||
putenv('OTEL_LOGS_EXPORTER=otlp');
|
||||
putenv('OTEL_EXPORTER_OTLP_PROTOCOL=grpc');
|
||||
putenv('OTEL_EXPORTER_OTLP_ENDPOINT=http://collector:4317');
|
||||
putenv('OTEL_PROPAGATORS=b3,baggage,tracecontext');
|
||||
|
||||
echo 'autoloading SDK example starting...' . PHP_EOL;
|
||||
|
||||
// Composer autoloader will execute SDK/_autoload.php which will register global instrumentation from environment configuration
|
||||
require dirname(__DIR__) . '/vendor/autoload.php';
|
||||
|
||||
$instrumentation = new \OpenTelemetry\API\Instrumentation\CachedInstrumentation('demo');
|
||||
|
||||
$instrumentation->tracer()->spanBuilder('root')->startSpan()->end();
|
||||
$instrumentation->meter()->createCounter('cnt')->add(1);
|
||||
$instrumentation->eventLogger()->emit('foo', 'hello, otel');
|
||||
|
||||
echo 'Finished!' . PHP_EOL;
|
|
@ -0,0 +1,62 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace OpenTelemetry\Example;
|
||||
|
||||
putenv('OTEL_PHP_AUTOLOAD_ENABLED=true');
|
||||
putenv('OTEL_TRACES_EXPORTER=otlp');
|
||||
putenv('OTEL_EXPORTER_OTLP_PROTOCOL=grpc');
|
||||
putenv('OTEL_METRICS_EXPORTER=otlp');
|
||||
putenv('OTEL_EXPORTER_OTLP_METRICS_PROTOCOL=grpc');
|
||||
putenv('OTEL_EXPORTER_OTLP_ENDPOINT=http://collector:4317');
|
||||
putenv('OTEL_PHP_TRACES_PROCESSOR=batch');
|
||||
|
||||
echo 'autoloading SDK example starting...' . PHP_EOL;
|
||||
|
||||
// Composer autoloader will execute SDK/_autoload.php which will register global instrumentation from environment configuration
|
||||
require dirname(__DIR__) . '/vendor/autoload.php';
|
||||
|
||||
/**
|
||||
* create a transport factory to override the default grpc one (for both traces and metrics):
|
||||
* @psalm-suppress InvalidReturnType
|
||||
* @psalm-suppress InvalidReturnStatement
|
||||
* @psalm-suppress MissingTemplateParam
|
||||
*/
|
||||
$factory = new class() implements \OpenTelemetry\SDK\Common\Export\TransportFactoryInterface {
|
||||
#[\Override]
|
||||
public function create(string $endpoint, string $contentType, array $headers = [], $compression = null, float $timeout = 10., int $retryDelay = 100, int $maxRetries = 3, ?string $cacert = null, ?string $cert = null, ?string $key = null): \OpenTelemetry\SDK\Common\Export\TransportInterface
|
||||
{
|
||||
return new class() implements \OpenTelemetry\SDK\Common\Export\TransportInterface {
|
||||
#[\Override]
|
||||
public function contentType(): string
|
||||
{
|
||||
return 'application/x-protobuf';
|
||||
}
|
||||
#[\Override]
|
||||
public function send(string $payload, ?\OpenTelemetry\SDK\Common\Future\CancellationInterface $cancellation = null): \OpenTelemetry\SDK\Common\Future\FutureInterface
|
||||
{
|
||||
return new \OpenTelemetry\SDK\Common\Future\CompletedFuture(null);
|
||||
}
|
||||
#[\Override]
|
||||
public function shutdown(?\OpenTelemetry\SDK\Common\Future\CancellationInterface $cancellation = null): bool
|
||||
{
|
||||
return true;
|
||||
}
|
||||
#[\Override]
|
||||
public function forceFlush(?\OpenTelemetry\SDK\Common\Future\CancellationInterface $cancellation = null): bool
|
||||
{
|
||||
return true;
|
||||
}
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
\OpenTelemetry\SDK\Registry::registerTransportFactory('grpc', $factory, true);
|
||||
|
||||
$instrumentation = new \OpenTelemetry\API\Instrumentation\CachedInstrumentation('demo');
|
||||
|
||||
$instrumentation->tracer()->spanBuilder('root')->startSpan()->end();
|
||||
$instrumentation->meter()->createCounter('cnt')->add(1);
|
||||
|
||||
echo 'Finished!' . PHP_EOL;
|
|
@ -0,0 +1,52 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace OpenTelemetry\Example;
|
||||
|
||||
require __DIR__ . '/../../vendor/autoload.php';
|
||||
|
||||
echo 'Starting baggage example' . PHP_EOL;
|
||||
|
||||
$propagator = \OpenTelemetry\API\Baggage\Propagation\BaggagePropagator::getInstance();
|
||||
$scopes = [];
|
||||
|
||||
//extract baggage from a carrier (eg, inbound http request headers), and store in context
|
||||
$carrier = [
|
||||
'baggage' => 'key1=value1,key2=value2;property1',
|
||||
];
|
||||
echo 'Initial baggage input: ' . json_encode($carrier) . PHP_EOL;
|
||||
echo 'Extracting baggage from carrier...' . PHP_EOL;
|
||||
$context = $propagator->extract($carrier);
|
||||
$scopes[] = $context->activate();
|
||||
|
||||
//get the baggage, and extract values from it
|
||||
echo 'Retrieving baggage values...' . PHP_EOL;
|
||||
$baggage = \OpenTelemetry\API\Baggage\Baggage::getCurrent();
|
||||
echo 'key1: ' . $baggage->getValue('key1') . PHP_EOL;
|
||||
echo 'key2: ' . $baggage->getValue('key2') . PHP_EOL;
|
||||
$entry = $baggage->getEntry('key2');
|
||||
echo 'key2 metadata: ' . ($entry !== null ? $entry->getMetadata()->getValue() : '-unset-') . PHP_EOL;
|
||||
|
||||
//remove a value from baggage and add a value
|
||||
echo 'removing key1, adding key3 to baggage...' . PHP_EOL;
|
||||
$scopes[] = $baggage->toBuilder()->remove('key1')->set('key3', 'value3')->build()->activate();
|
||||
|
||||
//extract baggage from context, and store in a different carrier (eg, outbound http request headers)
|
||||
$out = [];
|
||||
$propagator->inject($out);
|
||||
echo 'Extracted baggage: ' . json_encode($out) . PHP_EOL;
|
||||
|
||||
//clear baggage (to avoid sending to an untrusted process), see https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/baggage/api.md#clear-baggage-in-the-context
|
||||
echo 'Clearing baggage...' . PHP_EOL;
|
||||
$scopes[] = \OpenTelemetry\API\Baggage\Baggage::getEmpty()->activate();
|
||||
$cleared = [];
|
||||
$propagator->extract($cleared);
|
||||
echo 'Extracted baggage: ' . json_encode($cleared) . PHP_EOL;
|
||||
|
||||
//detach scopes
|
||||
foreach (array_reverse($scopes) as $scope) {
|
||||
$scope->detach();
|
||||
}
|
||||
|
||||
echo 'Finished baggage example' . PHP_EOL;
|
|
@ -0,0 +1,50 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace OpenTelemetry\Example;
|
||||
|
||||
require __DIR__ . '/../../vendor/autoload.php';
|
||||
|
||||
use OpenTelemetry\API\Baggage\Baggage;
|
||||
use OpenTelemetry\API\Baggage\Propagation\BaggagePropagator;
|
||||
use OpenTelemetry\Context\Propagation\EnvironmentGetterSetter;
|
||||
|
||||
$propagator = BaggagePropagator::getInstance();
|
||||
$envGetterSetter = EnvironmentGetterSetter::getInstance();
|
||||
|
||||
$isChild = isset($argv[1]) && $argv[1] === 'child';
|
||||
|
||||
if (!$isChild) {
|
||||
$baggage = Baggage::getBuilder()
|
||||
->set('key1', 'value1')
|
||||
->set('key2', 'value2')
|
||||
->build();
|
||||
$baggageScope = $baggage->activate();
|
||||
|
||||
// Inject baggage into environment variables
|
||||
$carrier = [];
|
||||
$propagator->inject($carrier, $envGetterSetter);
|
||||
|
||||
// Execute child process
|
||||
$command = sprintf('%s %s %s', PHP_BINARY, escapeshellarg(__FILE__), 'child');
|
||||
$handle = popen($command, 'w');
|
||||
if ($handle === false) {
|
||||
echo 'Failed to execute child process.' . PHP_EOL;
|
||||
} else {
|
||||
pclose($handle);
|
||||
}
|
||||
|
||||
$baggageScope->detach();
|
||||
} else {
|
||||
// Extract baggage from environment variables
|
||||
$context = $propagator->extract([], $envGetterSetter);
|
||||
$scope = $context->activate();
|
||||
|
||||
// Get values from baggage
|
||||
$baggage = Baggage::getCurrent();
|
||||
echo 'key1: ' . $baggage->getValue('key1') . PHP_EOL;
|
||||
echo 'key2: ' . $baggage->getValue('key2') . PHP_EOL;
|
||||
|
||||
$scope->detach();
|
||||
}
|
|
@ -0,0 +1,47 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace OpenTelemetry\Example;
|
||||
|
||||
use OpenTelemetry\API\Common\Time\Clock;
|
||||
use OpenTelemetry\Contrib\Otlp\MetricExporter;
|
||||
use OpenTelemetry\SDK\Common\Attribute\Attributes;
|
||||
use OpenTelemetry\SDK\Common\Export\Stream\StreamTransportFactory;
|
||||
use OpenTelemetry\SDK\Common\Instrumentation\InstrumentationScopeFactory;
|
||||
use OpenTelemetry\SDK\Metrics\Exemplar\ExemplarFilter\WithSampledTraceExemplarFilter;
|
||||
use OpenTelemetry\SDK\Metrics\MeterProvider;
|
||||
use OpenTelemetry\SDK\Metrics\MetricReader\ExportingReader;
|
||||
use OpenTelemetry\SDK\Metrics\StalenessHandler\ImmediateStalenessHandlerFactory;
|
||||
use OpenTelemetry\SDK\Metrics\View\CriteriaViewRegistry;
|
||||
use OpenTelemetry\SDK\Resource\ResourceInfoFactory;
|
||||
use OpenTelemetry\SDK\Trace\TracerProvider;
|
||||
|
||||
require __DIR__ . '/../vendor/autoload.php';
|
||||
|
||||
//@see https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/configuration/sdk-environment-variables.md#general-sdk-configuration
|
||||
putenv('OTEL_SDK_DISABLED=true');
|
||||
|
||||
echo 'Creating (disabled) signals' . PHP_EOL;
|
||||
|
||||
//trace
|
||||
$tracer = (new TracerProvider())->getTracer('io.opentelemetry.contrib.php');
|
||||
echo get_class($tracer) . PHP_EOL;
|
||||
|
||||
//metrics
|
||||
$clock = Clock::getDefault();
|
||||
$reader = new ExportingReader(new MetricExporter((new StreamTransportFactory())->create(STDOUT, 'application/x-ndjson')));
|
||||
$views = new CriteriaViewRegistry();
|
||||
$meterProvider = new MeterProvider(
|
||||
null,
|
||||
ResourceInfoFactory::emptyResource(),
|
||||
$clock,
|
||||
Attributes::factory(),
|
||||
new InstrumentationScopeFactory(Attributes::factory()),
|
||||
[$reader],
|
||||
$views,
|
||||
new WithSampledTraceExemplarFilter(),
|
||||
new ImmediateStalenessHandlerFactory(),
|
||||
);
|
||||
$meter = $meterProvider->getMeter('io.opentelemetry.contrib.php');
|
||||
echo get_class($meter) . PHP_EOL;
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,24 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace OpenTelemetry\Example;
|
||||
|
||||
use OpenTelemetry\API\Globals;
|
||||
|
||||
/**
|
||||
* The OpenTelemetry SDK is able to emit some metrics about its internal state. For example,
|
||||
* batch span and log processor state.
|
||||
* This feature can be enabled via the OTEL_PHP_INTERNAL_METRICS_ENABLED setting.
|
||||
*/
|
||||
|
||||
putenv('OTEL_PHP_INTERNAL_METRICS_ENABLED=true');
|
||||
putenv('OTEL_PHP_AUTOLOAD_ENABLED=true');
|
||||
putenv('OTEL_TRACES_EXPORTER=console');
|
||||
putenv('OTEL_METRICS_EXPORTER=console');
|
||||
putenv('OTEL_LOGS_EXPORTER=console');
|
||||
|
||||
require __DIR__ . '/../vendor/autoload.php';
|
||||
|
||||
$tracerProvider = Globals::tracerProvider();
|
||||
$tracerProvider->getTracer('demo')->spanBuilder('root')->startSpan()->end();
|
|
@ -0,0 +1,40 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
use OpenTelemetry\API\Globals;
|
||||
use OpenTelemetry\API\Instrumentation\Configurator;
|
||||
use OpenTelemetry\SDK\Trace\SpanExporter\ConsoleSpanExporterFactory;
|
||||
use OpenTelemetry\SDK\Trace\SpanProcessor\SimpleSpanProcessor;
|
||||
use OpenTelemetry\SDK\Trace\TracerProvider;
|
||||
|
||||
require __DIR__ . '/../vendor/autoload.php';
|
||||
|
||||
/**
|
||||
* Example of globally registering <Signal>Provider instances.
|
||||
* Generally this is hidden inside the SDK builder or SDK autoloading,
|
||||
* but you can also do it manually. The providers are stored in
|
||||
* context, and reset to previous values or defaults when the
|
||||
* scope is detached.
|
||||
*/
|
||||
|
||||
//before, a no-op provider is provided by default
|
||||
echo 'Before: ' . get_class(Globals::tracerProvider()) . PHP_EOL;
|
||||
|
||||
$tracerProvider = TracerProvider::builder()->addSpanProcessor(
|
||||
new SimpleSpanProcessor(
|
||||
(new ConsoleSpanExporterFactory())->create()
|
||||
)
|
||||
)->build();
|
||||
|
||||
$configurator = Configurator::create()
|
||||
->withTracerProvider($tracerProvider);
|
||||
|
||||
$scope = $configurator->activate();
|
||||
//activated, now our $tracerProvider is globally available
|
||||
echo 'During: ' . get_class(Globals::tracerProvider()) . PHP_EOL;
|
||||
|
||||
$scope->detach();
|
||||
|
||||
//after scope detached, back to default no-op providers:
|
||||
echo 'After: ' . get_class(Globals::tracerProvider()) . PHP_EOL;
|
|
@ -0,0 +1,32 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace _;
|
||||
|
||||
use Nevay\SPI\ServiceLoader;
|
||||
use OpenTelemetry\API\Configuration\Context;
|
||||
use OpenTelemetry\API\Globals;
|
||||
use OpenTelemetry\API\Instrumentation\AutoInstrumentation\ExtensionHookManager;
|
||||
use OpenTelemetry\API\Instrumentation\AutoInstrumentation\Instrumentation;
|
||||
use OpenTelemetry\Config\SDK\Configuration;
|
||||
use OpenTelemetry\Example\Example;
|
||||
use const PHP_EOL;
|
||||
|
||||
/**
|
||||
* This example uses SPI (see root composer.json extra.spi) to configure an example auto-instrumentation from a YAML file
|
||||
*/
|
||||
// EXAMPLE_INSTRUMENTATION_SPAN_NAME=test1234 php examples/instrumentation/configure_instrumentation.php
|
||||
|
||||
require __DIR__ . '/../../vendor/autoload.php';
|
||||
|
||||
Configuration::parseFile(__DIR__ . '/otel-sdk.yaml')->create(new Context())->setAutoShutdown(true)->buildAndRegisterGlobal();
|
||||
$configuration = \OpenTelemetry\Config\SDK\Instrumentation::parseFile(__DIR__ . '/otel-sdk.yaml')->create();
|
||||
$hookManager = new ExtensionHookManager();
|
||||
$context = new \OpenTelemetry\API\Instrumentation\AutoInstrumentation\Context(Globals::tracerProvider(), Globals::meterProvider(), Globals::loggerProvider(), Globals::propagator());
|
||||
|
||||
foreach (ServiceLoader::load(Instrumentation::class) as $instrumentation) {
|
||||
$instrumentation->register($hookManager, $configuration, $context);
|
||||
}
|
||||
|
||||
echo (new Example())->test(), PHP_EOL;
|
|
@ -0,0 +1,23 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace _;
|
||||
|
||||
use OpenTelemetry\Example\Example;
|
||||
use const PHP_EOL;
|
||||
use function putenv;
|
||||
|
||||
/**
|
||||
* This example uses SPI (see root composer.json extra.spi) to configure an example auto-instrumentation from environment variables.
|
||||
*/
|
||||
// php examples/instrumentation/configure_instrumentation_env.php
|
||||
putenv('OTEL_PHP_AUTOLOAD_ENABLED=true');
|
||||
putenv('OTEL_PHP_EXAMPLE_INSTRUMENTATION_SPAN_NAME=example span');
|
||||
putenv('OTEL_TRACES_EXPORTER=console');
|
||||
putenv('OTEL_METRICS_EXPORTER=none');
|
||||
putenv('OTEL_LOGS_EXPORTER=none');
|
||||
|
||||
require __DIR__ . '/../../vendor/autoload.php';
|
||||
|
||||
echo (new Example())->test(), PHP_EOL;
|
|
@ -0,0 +1,20 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace _;
|
||||
|
||||
use OpenTelemetry\Example\Example;
|
||||
use const PHP_EOL;
|
||||
|
||||
/**
|
||||
* This example uses SPI (see root composer.json extra.spi) to configure an example auto-instrumentation from a YAML file.
|
||||
* The YAML file paths are relative to the current working directory.
|
||||
*/
|
||||
// EXAMPLE_INSTRUMENTATION_SPAN_NAME=test1234 php examples/instrumentation/configure_instrumentation_global.php
|
||||
putenv('OTEL_PHP_AUTOLOAD_ENABLED=true');
|
||||
putenv('OTEL_EXPERIMENTAL_CONFIG_FILE=examples/instrumentation/otel-sdk.yaml');
|
||||
|
||||
require __DIR__ . '/../../vendor/autoload.php';
|
||||
|
||||
echo (new Example())->test(), PHP_EOL;
|
|
@ -0,0 +1,18 @@
|
|||
file_format: '0.4'
|
||||
|
||||
propagator:
|
||||
composite: []
|
||||
|
||||
tracer_provider:
|
||||
processors:
|
||||
- simple:
|
||||
exporter:
|
||||
console:
|
||||
sampler:
|
||||
always_on:
|
||||
|
||||
instrumentation:
|
||||
general:
|
||||
php:
|
||||
example_instrumentation:
|
||||
span_name: ${EXAMPLE_INSTRUMENTATION_SPAN_NAME:-example span}
|
|
@ -0,0 +1,29 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
use OpenTelemetry\Config\SDK\Configuration;
|
||||
|
||||
require __DIR__ . '/../vendor/autoload.php';
|
||||
|
||||
echo 'load config SDK example starting...' . PHP_EOL;
|
||||
|
||||
$config = Configuration::parseFile(__DIR__ . '/load_config.yaml');
|
||||
$sdk = $config
|
||||
->create()
|
||||
->setAutoShutdown(true)
|
||||
->build();
|
||||
|
||||
$tracer = $sdk->getTracerProvider()->getTracer('demo');
|
||||
$meter = $sdk->getMeterProvider()->getMeter('demo');
|
||||
$eventLogger = $sdk->getEventLoggerProvider()->getEventLogger('demo');
|
||||
|
||||
$span = $tracer->spanBuilder('root')->startSpan();
|
||||
$scope = $span->activate();
|
||||
$meter->createCounter('cnt')->add(1);
|
||||
|
||||
$eventLogger->emit('foo', 'hello, otel');
|
||||
$scope->detach();
|
||||
$span->end();
|
||||
|
||||
echo 'Finished!' . PHP_EOL;
|
|
@ -0,0 +1,46 @@
|
|||
file_format: '0.3'
|
||||
|
||||
resource:
|
||||
attributes:
|
||||
- name: service.name
|
||||
value: opentelemetry-demo
|
||||
attributes_list: service.name=unused,example.foo=foo_value,example.bar=bar_value
|
||||
|
||||
propagators:
|
||||
composite: [ tracecontext, baggage ]
|
||||
|
||||
exporters:
|
||||
otlp: &otlp-exporter
|
||||
protocol: http/protobuf
|
||||
endpoint: http://collector:4318
|
||||
|
||||
tracer_provider:
|
||||
sampler:
|
||||
parent_based:
|
||||
root:
|
||||
always_on:
|
||||
processors:
|
||||
- simple:
|
||||
exporter:
|
||||
console:
|
||||
- batch:
|
||||
exporter:
|
||||
otlp: *otlp-exporter
|
||||
meter_provider:
|
||||
readers:
|
||||
- periodic:
|
||||
exporter:
|
||||
console:
|
||||
- periodic:
|
||||
exporter:
|
||||
otlp:
|
||||
<<: *otlp-exporter
|
||||
temporality_preference: lowmemory
|
||||
logger_provider:
|
||||
processors:
|
||||
- simple:
|
||||
exporter:
|
||||
console:
|
||||
- batch:
|
||||
exporter:
|
||||
otlp: *otlp-exporter
|
|
@ -0,0 +1,30 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
use OpenTelemetry\Config\SDK\Configuration;
|
||||
|
||||
require __DIR__ . '/../vendor/autoload.php';
|
||||
|
||||
echo 'load config SDK example starting...' . PHP_EOL;
|
||||
|
||||
$_SERVER['OTEL_SERVICE_NAME'] = 'opentelemetry-demo';
|
||||
$_SERVER['OTEL_EXPORTER_OTLP_PROTOCOL'] = 'http/protobuf';
|
||||
$_SERVER['OTEL_EXPORTER_OTLP_ENDPOINT'] = 'http://collector:4318';
|
||||
$_SERVER['OTEL_TRACES_SAMPLER_ARG'] = '0.5';
|
||||
|
||||
$config = Configuration::parseFile(__DIR__ . '/load_config_env.yaml');
|
||||
$sdk = $config
|
||||
->create()
|
||||
->setAutoShutdown(true)
|
||||
->build();
|
||||
|
||||
$tracer = $sdk->getTracerProvider()->getTracer('demo');
|
||||
$meter = $sdk->getMeterProvider()->getMeter('demo');
|
||||
$eventLogger = $sdk->getEventLoggerProvider()->getEventLogger('demo');
|
||||
|
||||
$tracer->spanBuilder('root')->startSpan()->end();
|
||||
$meter->createCounter('cnt')->add(1);
|
||||
$eventLogger->emit('foo', 'hello, otel');
|
||||
|
||||
echo 'Finished!' . PHP_EOL;
|
|
@ -0,0 +1,50 @@
|
|||
file_format: '0.3'
|
||||
|
||||
disabled: ${OTEL_SDK_DISABLED}
|
||||
|
||||
resource:
|
||||
attributes:
|
||||
- name: service.name
|
||||
value: ${OTEL_SERVICE_NAME}
|
||||
|
||||
propagators:
|
||||
composite: [ tracecontext, baggage ]
|
||||
|
||||
attribute_limits:
|
||||
attribute_value_length_limit: ${OTEL_ATTRIBUTE_VALUE_LENGTH_LIMIT}
|
||||
attribute_count_limit: ${OTEL_ATTRIBUTE_COUNT_LIMIT}
|
||||
|
||||
exporters:
|
||||
otlp: &otlp-exporter
|
||||
protocol: ${OTEL_EXPORTER_OTLP_PROTOCOL}
|
||||
endpoint: ${OTEL_EXPORTER_OTLP_ENDPOINT}
|
||||
certificate: ${OTEL_EXPORTER_OTLP_CERTIFICATE}
|
||||
client_key: ${OTEL_EXPORTER_OTLP_CLIENT_KEY}
|
||||
client_certificate: ${OTEL_EXPORTER_OTLP_CLIENT_CERTIFICATE}
|
||||
compression: ${OTEL_EXPORTER_OTLP_COMPRESSION}
|
||||
timeout: ${OTEL_EXPORTER_OTLP_TIMEOUT}
|
||||
|
||||
tracer_provider:
|
||||
sampler:
|
||||
parent_based:
|
||||
root:
|
||||
trace_id_ratio_based:
|
||||
ratio: ${OTEL_TRACES_SAMPLER_ARG}
|
||||
limits:
|
||||
attribute_value_length_limit: ${OTEL_SPAN_ATTRIBUTE_VALUE_LENGTH_LIMIT}
|
||||
attribute_count_limit: ${OTEL_SPAN_ATTRIBUTE_COUNT_LIMIT}
|
||||
event_count_limit: ${OTEL_SPAN_EVENT_COUNT_LIMIT}
|
||||
link_count_limit: ${OTEL_SPAN_LINK_COUNT_LIMIT}
|
||||
event_attribute_count_limit: ${OTEL_EVENT_ATTRIBUTE_COUNT_LIMIT}
|
||||
link_attribute_count_limit: ${OTEL_LINK_ATTRIBUTE_COUNT_LIMIT}
|
||||
processors:
|
||||
- simple:
|
||||
exporter:
|
||||
console: {}
|
||||
- batch:
|
||||
schedule_delay: ${OTEL_BSP_SCHEDULE_DELAY}
|
||||
export_timeout: ${OTEL_BSP_EXPORT_TIMEOUT}
|
||||
max_queue_size: ${OTEL_BSP_MAX_QUEUE_SIZE}
|
||||
max_export_batch_size: ${OTEL_BSP_MAX_EXPORT_BATCH_SIZE}
|
||||
exporter:
|
||||
otlp: *otlp-exporter
|
|
@ -0,0 +1,46 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace OpenTelemetry\Example;
|
||||
|
||||
use OpenTelemetry\API\Common\Time\Clock;
|
||||
use OpenTelemetry\API\Logs\Severity;
|
||||
use OpenTelemetry\API\Signals;
|
||||
use OpenTelemetry\Contrib\Grpc\GrpcTransportFactory;
|
||||
use OpenTelemetry\Contrib\Otlp\LogsExporter;
|
||||
use OpenTelemetry\Contrib\Otlp\OtlpUtil;
|
||||
use OpenTelemetry\SDK\Common\Instrumentation\InstrumentationScopeFactory;
|
||||
use OpenTelemetry\SDK\Logs\EventLoggerProvider;
|
||||
use OpenTelemetry\SDK\Logs\LoggerProvider;
|
||||
use OpenTelemetry\SDK\Logs\LogRecordLimitsBuilder;
|
||||
use OpenTelemetry\SDK\Logs\Processor\BatchLogRecordProcessor;
|
||||
|
||||
require __DIR__ . '/../../../vendor/autoload.php';
|
||||
|
||||
$transport = (new GrpcTransportFactory())->create('http://collector:4317' . OtlpUtil::method(Signals::LOGS));
|
||||
$exporter = new LogsExporter($transport);
|
||||
$loggerProvider = new LoggerProvider(
|
||||
new BatchLogRecordProcessor(
|
||||
$exporter,
|
||||
Clock::getDefault()
|
||||
),
|
||||
new InstrumentationScopeFactory(
|
||||
(new LogRecordLimitsBuilder())->build()->getAttributeFactory()
|
||||
)
|
||||
);
|
||||
$eventLoggerProvider = new EventLoggerProvider($loggerProvider);
|
||||
$eventLogger = $eventLoggerProvider->getEventLogger('demo', '1.0', 'http://schema.url', ['foo' => 'bar']);
|
||||
|
||||
$eventLogger->emit(
|
||||
name: 'foo',
|
||||
body: ['foo' => 'bar', 'baz' => 'bat', 'msg' => 'hello world'],
|
||||
severityNumber: Severity::INFO
|
||||
);
|
||||
|
||||
$eventLogger->emit(
|
||||
'bar',
|
||||
'otel is great'
|
||||
);
|
||||
|
||||
$loggerProvider->shutdown();
|
|
@ -0,0 +1,38 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace OpenTelemetry\Example;
|
||||
|
||||
use OpenTelemetry\API\Logs\LogRecord;
|
||||
use OpenTelemetry\API\Logs\Severity;
|
||||
use OpenTelemetry\Contrib\Otlp\LogsExporter;
|
||||
use OpenTelemetry\Contrib\Otlp\OtlpHttpTransportFactory;
|
||||
use OpenTelemetry\SDK\Common\Instrumentation\InstrumentationScopeFactory;
|
||||
use OpenTelemetry\SDK\Logs\EventLoggerProvider;
|
||||
use OpenTelemetry\SDK\Logs\LoggerProvider;
|
||||
use OpenTelemetry\SDK\Logs\LogRecordLimitsBuilder;
|
||||
use OpenTelemetry\SDK\Logs\Processor\SimpleLogRecordProcessor;
|
||||
|
||||
require __DIR__ . '/../../../vendor/autoload.php';
|
||||
|
||||
$transport = (new OtlpHttpTransportFactory())->create('http://collector:4318/v1/logs', 'application/json');
|
||||
$exporter = new LogsExporter($transport);
|
||||
|
||||
$loggerProvider = new LoggerProvider(
|
||||
new SimpleLogRecordProcessor(
|
||||
$exporter
|
||||
),
|
||||
new InstrumentationScopeFactory(
|
||||
(new LogRecordLimitsBuilder())->build()->getAttributeFactory()
|
||||
)
|
||||
);
|
||||
$eventLoggerProvider = new EventLoggerProvider($loggerProvider);
|
||||
$eventLogger = $eventLoggerProvider->getEventLogger('demo', '1.0', 'https://opentelemetry.io/schemas/1.7.1', ['foo' => 'bar']);
|
||||
|
||||
$eventLogger->emit(
|
||||
name: 'foo',
|
||||
body: ['foo' => 'bar', 'baz' => 'bat', 'msg' => 'hello world'],
|
||||
timestamp: (new \DateTime())->getTimestamp() * LogRecord::NANOS_PER_SECOND,
|
||||
severityNumber: Severity::INFO,
|
||||
);
|
|
@ -0,0 +1,38 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace OpenTelemetry\Example;
|
||||
|
||||
use OpenTelemetry\API\Common\Time\Clock;
|
||||
use OpenTelemetry\API\Logs\Severity;
|
||||
use OpenTelemetry\SDK\Common\Attribute\Attributes;
|
||||
use OpenTelemetry\SDK\Common\Instrumentation\InstrumentationScopeFactory;
|
||||
use OpenTelemetry\SDK\Logs\EventLogger;
|
||||
use OpenTelemetry\SDK\Logs\EventLoggerProvider;
|
||||
use OpenTelemetry\SDK\Logs\Exporter\ConsoleExporterFactory;
|
||||
use OpenTelemetry\SDK\Logs\LoggerProvider;
|
||||
use OpenTelemetry\SDK\Logs\Processor\BatchLogRecordProcessor;
|
||||
|
||||
require __DIR__ . '/../../../vendor/autoload.php';
|
||||
|
||||
$loggerProvider = new LoggerProvider(
|
||||
new BatchLogRecordProcessor(
|
||||
(new ConsoleExporterFactory())->create(),
|
||||
Clock::getDefault()
|
||||
),
|
||||
new InstrumentationScopeFactory(Attributes::factory())
|
||||
);
|
||||
$eventLoggerProvider = new EventLoggerProvider($loggerProvider);
|
||||
//get a logger, and emit a log record from an EventLogger.
|
||||
$eventLoggerOne = $eventLoggerProvider->getEventLogger('demo', '1.0');
|
||||
$eventLoggerTwo = $eventLoggerProvider->getEventLogger('demo', '2.0');
|
||||
|
||||
$payload = ['foo' => 'bar', 'baz' => 'bat', 'msg' => 'hello world'];
|
||||
|
||||
$eventLoggerOne->emit(name: 'foo', body: $payload, severityNumber: Severity::INFO);
|
||||
$eventLoggerOne->emit('bar', 'hello world');
|
||||
$eventLoggerTwo->emit(name: 'foo', body: $payload, severityNumber: Severity::INFO);
|
||||
|
||||
//shut down logger provider
|
||||
$loggerProvider->shutdown();
|
|
@ -0,0 +1,81 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace OpenTelemetry\Example;
|
||||
|
||||
use Monolog\Handler\AbstractProcessingHandler;
|
||||
use Monolog\Handler\StreamHandler;
|
||||
use Monolog\Logger;
|
||||
use Monolog\LogRecord as MonologLogRecord;
|
||||
use OpenTelemetry\API\Globals;
|
||||
use OpenTelemetry\API\Logs\LoggerInterface;
|
||||
use OpenTelemetry\API\Logs\LoggerProviderInterface;
|
||||
use OpenTelemetry\API\Logs\LogRecord;
|
||||
use OpenTelemetry\API\Logs\Severity;
|
||||
use Psr\Log\LogLevel;
|
||||
|
||||
/**
|
||||
* This example creates a monolog handler which integrates with opentelemetry. In this example, the logger is
|
||||
* configured from environment, and autoloaded as part of composer where is can be retrieved from `Globals`.
|
||||
*
|
||||
* @see https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/logs/bridge-api.md#usage
|
||||
*
|
||||
* We have an official monolog handler, @see https://packagist.org/packages/open-telemetry/opentelemetry-logger-monolog
|
||||
*/
|
||||
|
||||
// create env vars before requiring composer
|
||||
putenv('OTEL_PHP_AUTOLOAD_ENABLED=true');
|
||||
putenv('OTEL_METRICS_EXPORTER=none');
|
||||
putenv('OTEL_LOGS_EXPORTER=otlp');
|
||||
putenv('OTEL_LOGS_PROCESSOR=batch');
|
||||
putenv('OTEL_EXPORTER_OTLP_PROTOCOL=grpc');
|
||||
putenv('OTEL_EXPORTER_OTLP_ENDPOINT=http://collector:4317');
|
||||
|
||||
require __DIR__ . '/../../../vendor/autoload.php';
|
||||
$streamHandler = new StreamHandler(STDOUT, LogLevel::DEBUG);
|
||||
$tracer = Globals::tracerProvider()->getTracer('monolog-demo');
|
||||
|
||||
//otel handler for Monolog v3
|
||||
$otelHandler = new class(LogLevel::INFO) extends AbstractProcessingHandler {
|
||||
private LoggerInterface $logger;
|
||||
|
||||
/**
|
||||
* @psalm-suppress ArgumentTypeCoercion
|
||||
*/
|
||||
public function __construct(string $level, bool $bubble = true, ?LoggerProviderInterface $provider = null)
|
||||
{
|
||||
parent::__construct($level, $bubble);
|
||||
$provider ??= Globals::loggerProvider();
|
||||
$this->logger = $provider->getLogger('monolog-demo', null, null, ['logging.library' => 'monolog']);
|
||||
}
|
||||
|
||||
#[\Override]
|
||||
protected function write(MonologLogRecord $record): void
|
||||
{
|
||||
$this->logger->emit($this->convert($record));
|
||||
}
|
||||
|
||||
private function convert(MonologLogRecord $record): LogRecord
|
||||
{
|
||||
return (new LogRecord($record['message']))
|
||||
->setSeverityText($record->level->toPsrLogLevel())
|
||||
->setTimestamp((int) (microtime(true) * (float) LogRecord::NANOS_PER_SECOND))
|
||||
->setObservedTimestamp((int) $record->datetime->format('U') * LogRecord::NANOS_PER_SECOND)
|
||||
->setSeverityNumber(Severity::fromPsr3($record->level->toPsrLogLevel()))
|
||||
->setAttributes($record->context + $record->extra);
|
||||
}
|
||||
};
|
||||
|
||||
//start a span so that logs contain span context
|
||||
$span = $tracer->spanBuilder('foo')->startSpan();
|
||||
$scope = $span->activate();
|
||||
|
||||
$monolog = new Logger('otel-php-monolog', [$otelHandler, $streamHandler]);
|
||||
|
||||
$monolog->debug('debug message');
|
||||
$monolog->info('hello world', ['extra_one' => 'value_one']);
|
||||
$monolog->alert('foo', ['extra_two' => 'value_two']);
|
||||
|
||||
$scope->detach();
|
||||
$span->end();
|
|
@ -0,0 +1,48 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
use OpenTelemetry\API\Logs\Severity;
|
||||
use OpenTelemetry\SDK\Common\Attribute\Attributes;
|
||||
use OpenTelemetry\SDK\Common\Instrumentation\InstrumentationScopeFactory;
|
||||
use OpenTelemetry\SDK\Logs\EventLoggerProvider;
|
||||
use OpenTelemetry\SDK\Logs\Exporter\ConsoleExporterFactory;
|
||||
use OpenTelemetry\SDK\Logs\LoggerProvider;
|
||||
use OpenTelemetry\SDK\Logs\Processor\SimpleLogRecordProcessor;
|
||||
use OpenTelemetry\SDK\Trace\TracerProvider;
|
||||
|
||||
require __DIR__ . '/../../vendor/autoload.php';
|
||||
|
||||
/**
|
||||
* Example of logging used in conjunction with tracing. The trace id and span id
|
||||
* will be injected into the logged record.
|
||||
* Note that logging output is human-readable JSON, and is not compatible with the
|
||||
* OTEL format.
|
||||
*/
|
||||
|
||||
$loggerProvider = new LoggerProvider(
|
||||
new SimpleLogRecordProcessor(
|
||||
(new ConsoleExporterFactory())->create()
|
||||
),
|
||||
new InstrumentationScopeFactory(Attributes::factory())
|
||||
);
|
||||
$eventLoggerProvider = new EventLoggerProvider($loggerProvider);
|
||||
$tracerProvider = new TracerProvider();
|
||||
$tracer = $tracerProvider->getTracer('demo-tracer');
|
||||
|
||||
//start and activate a span
|
||||
$span = $tracer->spanBuilder('root')->startSpan();
|
||||
$scope = $span->activate();
|
||||
echo 'Trace id: ' . $span->getContext()->getTraceId() . PHP_EOL;
|
||||
echo 'Span id: ' . $span->getContext()->getSpanId() . PHP_EOL;
|
||||
|
||||
//get an event logger, and emit an event. The active context (trace id + span id) will be
|
||||
//attached to the log record
|
||||
$eventLogger = $eventLoggerProvider->getEventLogger('demo', '1.0', 'http://schema.url', ['foo' => 'bar']);
|
||||
$payload = ['foo' => 'bar', 'baz' => 'bat', 'msg' => 'hello world'];
|
||||
|
||||
$eventLogger->emit(name: 'foo', body: $payload, severityNumber: Severity::INFO);
|
||||
|
||||
//end span
|
||||
$span->end();
|
||||
$scope->detach();
|
|
@ -0,0 +1,34 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
use OpenTelemetry\API\Logs\LogRecord;
|
||||
use OpenTelemetry\SDK\Common\Attribute\Attributes;
|
||||
use OpenTelemetry\SDK\Logs\Exporter\ConsoleExporterFactory;
|
||||
use OpenTelemetry\SDK\Logs\LoggerProvider;
|
||||
use OpenTelemetry\SDK\Logs\Processor\SimpleLogRecordProcessor;
|
||||
use OpenTelemetry\SDK\Resource\ResourceInfo;
|
||||
|
||||
require __DIR__ . '/../../vendor/autoload.php';
|
||||
|
||||
$loggerProvider = LoggerProvider::builder()
|
||||
->addLogRecordProcessor(
|
||||
new SimpleLogRecordProcessor(
|
||||
(new ConsoleExporterFactory())->create()
|
||||
)
|
||||
)
|
||||
->setResource(ResourceInfo::create(Attributes::create(['foo' => 'bar'])))
|
||||
->build();
|
||||
|
||||
$logger = $loggerProvider->getLogger('demo', '1.0', 'http://schema.url', ['foo' => 'bar']);
|
||||
|
||||
$record = (new LogRecord(['foo' => 'bar', 'baz' => 'bat', 'msg' => 'hello world']))
|
||||
->setSeverityText('INFO')
|
||||
->setSeverityNumber(9);
|
||||
|
||||
/**
|
||||
* Note that Loggers should only be used directly by a log appender.
|
||||
* @see https://github.com/open-telemetry/opentelemetry-specification/blob/v1.32.0/specification/logs/bridge-api.md#logs-bridge-api
|
||||
*/
|
||||
$logger->emit($record);
|
||||
$loggerProvider->shutdown();
|
|
@ -0,0 +1,79 @@
|
|||
<?php
|
||||
|
||||
// Example based on https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/supplementary-guidelines.md#synchronous-example
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace OpenTelemetry\Example;
|
||||
|
||||
require_once __DIR__ . '/../../vendor/autoload.php';
|
||||
|
||||
use OpenTelemetry\API\Common\Time\Clock;
|
||||
use OpenTelemetry\Contrib\Otlp\MetricExporter;
|
||||
use OpenTelemetry\SDK\Common\Attribute\Attributes;
|
||||
use OpenTelemetry\SDK\Common\Export\Stream\StreamTransportFactory;
|
||||
use OpenTelemetry\SDK\Common\Instrumentation\InstrumentationScopeFactory;
|
||||
use OpenTelemetry\SDK\Metrics\Aggregation\ExplicitBucketHistogramAggregation;
|
||||
use OpenTelemetry\SDK\Metrics\Exemplar\ExemplarFilter\WithSampledTraceExemplarFilter;
|
||||
use OpenTelemetry\SDK\Metrics\MeterProvider;
|
||||
use OpenTelemetry\SDK\Metrics\MetricReader\ExportingReader;
|
||||
use OpenTelemetry\SDK\Metrics\StalenessHandler\ImmediateStalenessHandlerFactory;
|
||||
use OpenTelemetry\SDK\Metrics\View\CriteriaViewRegistry;
|
||||
use OpenTelemetry\SDK\Metrics\View\SelectionCriteria\InstrumentNameCriteria;
|
||||
use OpenTelemetry\SDK\Metrics\View\ViewTemplate;
|
||||
use OpenTelemetry\SDK\Resource\ResourceInfoFactory;
|
||||
|
||||
$clock = Clock::getDefault();
|
||||
$reader = new ExportingReader(new MetricExporter((new StreamTransportFactory())->create(STDOUT, 'application/x-ndjson'), /*Temporality::CUMULATIVE*/));
|
||||
|
||||
// Let's imagine we export the metrics as Histogram, and to simplify the story we will only have one histogram bucket (-Inf, +Inf):
|
||||
$views = new CriteriaViewRegistry();
|
||||
$views->register(
|
||||
new InstrumentNameCriteria('http.server.duration'),
|
||||
ViewTemplate::create()
|
||||
->withAttributeKeys(['http.method', 'http.status_code'])
|
||||
->withAggregation(new ExplicitBucketHistogramAggregation([])),
|
||||
);
|
||||
|
||||
$meterProvider = new MeterProvider(
|
||||
null,
|
||||
ResourceInfoFactory::emptyResource(),
|
||||
$clock,
|
||||
Attributes::factory(),
|
||||
new InstrumentationScopeFactory(Attributes::factory()),
|
||||
[$reader],
|
||||
$views,
|
||||
new WithSampledTraceExemplarFilter(),
|
||||
new ImmediateStalenessHandlerFactory(),
|
||||
);
|
||||
|
||||
$serverDuration = $meterProvider->getMeter('io.opentelemetry.contrib.php')->createHistogram(
|
||||
'http.server.duration',
|
||||
'ms',
|
||||
'measures the duration inbound HTTP requests',
|
||||
);
|
||||
|
||||
// During the time range (T0, T1]:
|
||||
$serverDuration->record(50, ['http.method' => 'GET', 'http.status_code' => 200]);
|
||||
$serverDuration->record(100, ['http.method' => 'GET', 'http.status_code' => 200]);
|
||||
$serverDuration->record(1, ['http.method' => 'GET', 'http.status_code' => 500]);
|
||||
$reader->collect();
|
||||
|
||||
// During the time range (T1, T2]:
|
||||
$reader->collect();
|
||||
|
||||
// During the time range (T2, T3]:
|
||||
$serverDuration->record(5, ['http.method' => 'GET', 'http.status_code' => 500]);
|
||||
$serverDuration->record(2, ['http.method' => 'GET', 'http.status_code' => 500]);
|
||||
$reader->collect();
|
||||
|
||||
// During the time range (T3, T4]:
|
||||
$serverDuration->record(100, ['http.method' => 'GET', 'http.status_code' => 200]);
|
||||
$reader->collect();
|
||||
|
||||
// During the time range (T4, T5]:
|
||||
$serverDuration->record(100, ['http.method' => 'GET', 'http.status_code' => 200]);
|
||||
$serverDuration->record(30, ['http.method' => 'GET', 'http.status_code' => 200]);
|
||||
$serverDuration->record(50, ['http.method' => 'GET', 'http.status_code' => 200]);
|
||||
$reader->collect();
|
||||
|
||||
$meterProvider->shutdown();
|
|
@ -0,0 +1,25 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace OpenTelemetry\Example;
|
||||
|
||||
use OpenTelemetry\SDK\Metrics\MeterProviderFactory;
|
||||
|
||||
require __DIR__ . '/../../../vendor/autoload.php';
|
||||
|
||||
/**
|
||||
* Create a console exporter from environment variables, and generate a histogram.
|
||||
*/
|
||||
|
||||
putenv('OTEL_METRICS_EXPORTER=console');
|
||||
|
||||
$meterProvider = (new MeterProviderFactory())->create();
|
||||
|
||||
$meter = $meterProvider->getMeter('io.opentelemetry.contrib.php');
|
||||
$hist = $meter ->createHistogram('example', 'bytes', 'The number of bytes received.');
|
||||
for ($i=0; $i<=5000; $i++) {
|
||||
$hist->record(rand(0, 1024));
|
||||
}
|
||||
|
||||
$meterProvider->shutdown();
|
|
@ -0,0 +1,25 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace OpenTelemetry\Example;
|
||||
|
||||
require __DIR__ . '/../../../vendor/autoload.php';
|
||||
|
||||
use OpenTelemetry\API\Common\Time\Clock;
|
||||
use OpenTelemetry\API\Signals;
|
||||
use OpenTelemetry\Contrib\Grpc\GrpcTransportFactory;
|
||||
use OpenTelemetry\Contrib\Otlp\MetricExporter;
|
||||
use OpenTelemetry\Contrib\Otlp\OtlpUtil;
|
||||
use OpenTelemetry\SDK\Metrics\MetricReader\ExportingReader;
|
||||
|
||||
$clock = Clock::getDefault();
|
||||
|
||||
$reader = new ExportingReader(
|
||||
new MetricExporter(
|
||||
(new GrpcTransportFactory())->create('http://collector:4317' . OtlpUtil::method(Signals::METRICS))
|
||||
)
|
||||
);
|
||||
|
||||
$metricsGenerator = new ExampleMetricsGenerator($reader, $clock);
|
||||
$metricsGenerator->generate();
|
|
@ -0,0 +1,22 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace OpenTelemetry\Example;
|
||||
|
||||
require __DIR__ . '/../../../vendor/autoload.php';
|
||||
|
||||
use OpenTelemetry\API\Common\Time\Clock;
|
||||
use OpenTelemetry\Contrib\Otlp\MetricExporter;
|
||||
use OpenTelemetry\SDK\Common\Export\Http\PsrTransportFactory;
|
||||
use OpenTelemetry\SDK\Metrics\MetricReader\ExportingReader;
|
||||
|
||||
$clock = Clock::getDefault();
|
||||
$reader = new ExportingReader(
|
||||
new MetricExporter(
|
||||
(new PsrTransportFactory())->create('http://collector:4318/v1/metrics', \OpenTelemetry\Contrib\Otlp\ContentTypes::JSON)
|
||||
)
|
||||
);
|
||||
|
||||
$metricsGenerator = new ExampleMetricsGenerator($reader, $clock);
|
||||
$metricsGenerator->generate();
|
|
@ -0,0 +1,23 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace OpenTelemetry\Example;
|
||||
|
||||
require __DIR__ . '/../../../vendor/autoload.php';
|
||||
|
||||
use OpenTelemetry\API\Common\Time\Clock;
|
||||
use OpenTelemetry\Contrib\Otlp\MetricExporter;
|
||||
use OpenTelemetry\SDK\Common\Export\Stream\StreamTransportFactory;
|
||||
use OpenTelemetry\SDK\Metrics\MetricReader\ExportingReader;
|
||||
|
||||
$clock = Clock::getDefault();
|
||||
// @psalm-suppress InternalMethod
|
||||
$reader = new ExportingReader(
|
||||
new MetricExporter(
|
||||
(new StreamTransportFactory())->create(STDOUT, 'application/x-ndjson')
|
||||
)
|
||||
);
|
||||
|
||||
$metricsGenerator = new ExampleMetricsGenerator($reader, $clock);
|
||||
$metricsGenerator->generate();
|
|
@ -0,0 +1,37 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
use OpenTelemetry\API\Metrics\ObserverInterface;
|
||||
use OpenTelemetry\SDK\Metrics\Data\Temporality;
|
||||
use OpenTelemetry\SDK\Metrics\MeterProvider;
|
||||
use OpenTelemetry\SDK\Metrics\MetricExporter\ConsoleMetricExporter;
|
||||
use OpenTelemetry\SDK\Metrics\MetricReader\ExportingReader;
|
||||
use OpenTelemetry\SDK\Resource\ResourceInfoFactory;
|
||||
|
||||
require_once __DIR__ . '/../../vendor/autoload.php';
|
||||
|
||||
/**
|
||||
* Basic async/observable metrics generation example. This uses the console
|
||||
* metrics exporter to print metrics out in a human-readable format (but does
|
||||
* not require protobuf or the OTLP exporter)
|
||||
*/
|
||||
|
||||
$reader = new ExportingReader(
|
||||
new ConsoleMetricExporter(Temporality::DELTA)
|
||||
);
|
||||
|
||||
$meterProvider = MeterProvider::builder()
|
||||
->setResource(ResourceInfoFactory::emptyResource())
|
||||
->addReader($reader)
|
||||
->build();
|
||||
|
||||
$meterProvider
|
||||
->getMeter('demo_meter')
|
||||
->createObservableGauge('number', 'items', 'Random number')
|
||||
->observe(static function (ObserverInterface $observer): void {
|
||||
$observer->observe(random_int(0, 256));
|
||||
});
|
||||
|
||||
//metrics are collected every time `collect()` is called
|
||||
$reader->collect();
|
|
@ -0,0 +1,53 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace OpenTelemetry\Example;
|
||||
|
||||
use OpenTelemetry\API\Metrics\ObserverInterface;
|
||||
use OpenTelemetry\SDK\Metrics\MeterProvider;
|
||||
use OpenTelemetry\SDK\Metrics\MetricExporter\ConsoleMetricExporterFactory;
|
||||
use OpenTelemetry\SDK\Metrics\MetricReader\ExportingReader;
|
||||
|
||||
require_once __DIR__ . '/../../vendor/autoload.php';
|
||||
|
||||
/**
|
||||
* This example uses the meter provider builder, then two different methods to achieve a
|
||||
* similar result: export metrics about the length of a job queue.
|
||||
*
|
||||
* First, an up/down meter is manually increased/decreased (eg as jobs are added/removed)
|
||||
* Second, an async callback is used to generate a point-in-time observation of the queue
|
||||
* length. The callback is executed when `reader::collect()` is called.
|
||||
*/
|
||||
|
||||
$reader = new ExportingReader((new ConsoleMetricExporterFactory())->create());
|
||||
|
||||
$meterProvider = MeterProvider::builder()
|
||||
->addReader($reader)
|
||||
->build();
|
||||
|
||||
//example 1: manually adjust an up/down counter to track job queue length
|
||||
$up_down = $meterProvider
|
||||
->getMeter('demo')
|
||||
->createUpDownCounter('queued', 'jobs', 'The number of jobs enqueued (non-async)');
|
||||
$up_down->add(3); //jobs added
|
||||
$up_down->add(-1); //job completed
|
||||
$up_down->add(1); //job added
|
||||
|
||||
//example 2: observe the "queue", which happens every time `$reader->collect()` is called
|
||||
$queue = [
|
||||
'job1',
|
||||
'job2',
|
||||
'job3',
|
||||
];
|
||||
$meterProvider
|
||||
->getMeter('demo')
|
||||
->createObservableGauge('queued', 'jobs', 'The number of jobs enqueued (async)')
|
||||
->observe(static function (ObserverInterface $observer) use ($queue): void {
|
||||
$observer->observe(count($queue));
|
||||
});
|
||||
$reader->collect();
|
||||
array_pop($queue); //job completed
|
||||
$reader->collect();
|
||||
|
||||
$meterProvider->shutdown();
|
|
@ -0,0 +1,27 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
require_once __DIR__ . '/../../vendor/autoload.php';
|
||||
|
||||
use OpenTelemetry\Contrib\Otlp\MetricExporter;
|
||||
use OpenTelemetry\SDK\Common\Export\Stream\StreamTransportFactory;
|
||||
use OpenTelemetry\SDK\Metrics\MeterProvider;
|
||||
use OpenTelemetry\SDK\Metrics\MetricReader\ExportingReader;
|
||||
|
||||
/**
|
||||
* @psalm-suppress InternalMethod
|
||||
*/
|
||||
$reader = new ExportingReader(new MetricExporter((new StreamTransportFactory())->create(STDOUT, 'application/x-ndjson'), /*Temporality::CUMULATIVE*/));
|
||||
|
||||
$meterProvider = MeterProvider::builder()
|
||||
->addReader($reader)
|
||||
->build();
|
||||
|
||||
$histogram = $meterProvider->getMeter('io.opentelemetry.contrib.php')->createHistogram('demo');
|
||||
|
||||
$histogram->record(50);
|
||||
$histogram->record(7);
|
||||
$reader->collect();
|
||||
|
||||
$meterProvider->shutdown();
|
|
@ -0,0 +1,44 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
use OpenTelemetry\API\Metrics\ObserverInterface;
|
||||
use OpenTelemetry\SDK\Metrics\Data\Temporality;
|
||||
use OpenTelemetry\SDK\Metrics\MeterProvider;
|
||||
use OpenTelemetry\SDK\Metrics\MetricExporter\ConsoleMetricExporter;
|
||||
use OpenTelemetry\SDK\Metrics\MetricReader\ExportingReader;
|
||||
use OpenTelemetry\SDK\Resource\ResourceInfoFactory;
|
||||
|
||||
require 'vendor/autoload.php';
|
||||
|
||||
/**
|
||||
* Example of using weakly referenced observer callbacks. Binds the lifetime of
|
||||
* a callback to its bound object, the returned `ObserverCallbackInterface` is
|
||||
* ignored to automatically detach the callback once the original object is
|
||||
* garbage collected.
|
||||
*/
|
||||
|
||||
$reader = new ExportingReader(
|
||||
new ConsoleMetricExporter(Temporality::DELTA)
|
||||
);
|
||||
|
||||
$meterProvider = MeterProvider::builder()
|
||||
->setResource(ResourceInfoFactory::emptyResource())
|
||||
->addReader($reader)
|
||||
->build();
|
||||
|
||||
$callback = new class() {
|
||||
public function __invoke(ObserverInterface $observer)
|
||||
{
|
||||
$observer->observe(random_int(1, 10));
|
||||
}
|
||||
};
|
||||
|
||||
$meterProvider
|
||||
->getMeter('demo_meter')
|
||||
->createObservableGauge('number', 'items', 'Random number')
|
||||
->observe($callback); //weak-ref to callback
|
||||
|
||||
$reader->collect(); //metrics (data-points) collected (callback invoked)
|
||||
unset($callback);
|
||||
$reader->collect(); //no metrics (data-points) collected, because the callback was garbage-collected due to weak-ref
|
|
@ -1,29 +0,0 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
require __DIR__ . '/../../vendor/autoload.php';
|
||||
|
||||
use OpenTelemetry\Contrib\Prometheus\PrometheusExporter;
|
||||
use OpenTelemetry\SDK\Metrics\Counter;
|
||||
use Prometheus\CollectorRegistry;
|
||||
use Prometheus\Storage\Redis;
|
||||
|
||||
Redis::setDefaultOptions(
|
||||
[
|
||||
'host' => 'redis',
|
||||
'port' => 6379,
|
||||
'password' => null,
|
||||
'timeout' => 0.1, // in seconds
|
||||
'read_timeout' => '10', // in seconds
|
||||
'persistent_connections' => false,
|
||||
]
|
||||
);
|
||||
|
||||
$counter = new Counter('opentelemetry_prometheus_counter', 'Just a quick measurement');
|
||||
|
||||
$counter->increment();
|
||||
|
||||
$exporter = new PrometheusExporter(CollectorRegistry::getDefault());
|
||||
|
||||
$exporter->export([$counter]);
|
|
@ -1,22 +0,0 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
\Prometheus\Storage\Redis::setDefaultOptions(
|
||||
[
|
||||
'host' => 'redis',
|
||||
'port' => 6379,
|
||||
'password' => null,
|
||||
'timeout' => 0.1, // in seconds
|
||||
'read_timeout' => '10', // in seconds
|
||||
'persistent_connections' => false,
|
||||
]
|
||||
);
|
||||
|
||||
$registry = \Prometheus\CollectorRegistry::getDefault();
|
||||
|
||||
$renderer = new \Prometheus\RenderTextFormat();
|
||||
$result = $renderer->render($registry->getMetricFamilySamples());
|
||||
|
||||
header('Content-type: ' . \Prometheus\RenderTextFormat::MIME_TYPE);
|
||||
echo $result;
|
|
@ -0,0 +1,82 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
use OpenTelemetry\API\Instrumentation\CachedInstrumentation;
|
||||
use OpenTelemetry\API\Trace\Propagation\TraceContextPropagator;
|
||||
use OpenTelemetry\Contrib\Otlp\MetricExporter;
|
||||
use OpenTelemetry\SDK\Common\Export\Http\PsrTransportFactory;
|
||||
use OpenTelemetry\SDK\Logs\LoggerProvider;
|
||||
use OpenTelemetry\SDK\Logs\Processor\SimpleLogRecordProcessor;
|
||||
use OpenTelemetry\SDK\Metrics\MeterProvider;
|
||||
use OpenTelemetry\SDK\Metrics\MetricReader\ExportingReader;
|
||||
use OpenTelemetry\SDK\Resource\ResourceInfoFactory;
|
||||
use OpenTelemetry\SDK\Sdk;
|
||||
use OpenTelemetry\SDK\Trace\Sampler\AlwaysOnSampler;
|
||||
use OpenTelemetry\SDK\Trace\Sampler\ParentBased;
|
||||
use OpenTelemetry\SDK\Trace\SpanExporter\InMemoryExporter;
|
||||
use OpenTelemetry\SDK\Trace\SpanProcessor\BatchSpanProcessor;
|
||||
use OpenTelemetry\SDK\Trace\TracerProvider;
|
||||
|
||||
require __DIR__ . '/../vendor/autoload.php';
|
||||
|
||||
echo 'Starting SDK builder example' . PHP_EOL;
|
||||
|
||||
$resource = ResourceInfoFactory::defaultResource();
|
||||
$spanExporter = new InMemoryExporter();
|
||||
$logRecordExporter = new \OpenTelemetry\SDK\Logs\Exporter\InMemoryExporter();
|
||||
|
||||
$reader = new ExportingReader(
|
||||
new MetricExporter(
|
||||
(new PsrTransportFactory())->create('http://collector:4318/v1/metrics', 'application/x-protobuf')
|
||||
)
|
||||
);
|
||||
|
||||
$meterProvider = MeterProvider::builder()
|
||||
->setResource($resource)
|
||||
->addReader($reader)
|
||||
->build();
|
||||
|
||||
$loggerProvider = LoggerProvider::builder()
|
||||
->addLogRecordProcessor(
|
||||
new SimpleLogRecordProcessor($logRecordExporter)
|
||||
)
|
||||
->build();
|
||||
|
||||
$tracerProvider = TracerProvider::builder()
|
||||
->addSpanProcessor(
|
||||
BatchSpanProcessor::builder($spanExporter)
|
||||
->setMeterProvider($meterProvider)
|
||||
->build()
|
||||
)
|
||||
->setResource($resource)
|
||||
->setSampler(new ParentBased(new AlwaysOnSampler()))
|
||||
->build();
|
||||
|
||||
Sdk::builder()
|
||||
->setTracerProvider($tracerProvider)
|
||||
->setMeterProvider($meterProvider)
|
||||
->setLoggerProvider($loggerProvider)
|
||||
->setPropagator(TraceContextPropagator::getInstance())
|
||||
->setAutoShutdown(true)
|
||||
->buildAndRegisterGlobal();
|
||||
|
||||
$instrumentation = new CachedInstrumentation('example');
|
||||
$tracer = $instrumentation->tracer();
|
||||
|
||||
$root = $tracer->spanBuilder('root')->startSpan();
|
||||
$scope = $root->activate();
|
||||
for ($i=0; $i < 100; $i++) {
|
||||
if ($i%8 === 0) {
|
||||
$reader->collect();
|
||||
}
|
||||
$tracer->spanBuilder('span-' . $i)
|
||||
->startSpan()
|
||||
->end();
|
||||
usleep(50000);
|
||||
}
|
||||
$scope->detach();
|
||||
$root->end();
|
||||
$reader->shutdown();
|
||||
|
||||
echo 'Finished SDK builder example' . PHP_EOL;
|
|
@ -0,0 +1,13 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace OpenTelemetry\Example;
|
||||
|
||||
final class Example
|
||||
{
|
||||
public function test(): int
|
||||
{
|
||||
return 42;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace OpenTelemetry\Example;
|
||||
|
||||
use OpenTelemetry\API\Instrumentation\AutoInstrumentation\InstrumentationConfiguration;
|
||||
|
||||
final class ExampleConfig implements InstrumentationConfiguration
|
||||
{
|
||||
public function __construct(
|
||||
public readonly string $spanName = 'example',
|
||||
public readonly bool $enabled = true,
|
||||
) {
|
||||
}
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace OpenTelemetry\Example;
|
||||
|
||||
use OpenTelemetry\API\Configuration\ConfigEnv\EnvComponentLoader;
|
||||
use OpenTelemetry\API\Configuration\ConfigEnv\EnvComponentLoaderRegistry;
|
||||
use OpenTelemetry\API\Configuration\ConfigEnv\EnvResolver;
|
||||
use OpenTelemetry\API\Configuration\Context;
|
||||
use OpenTelemetry\API\Instrumentation\AutoInstrumentation\InstrumentationConfiguration;
|
||||
|
||||
/**
|
||||
* @implements EnvComponentLoader<InstrumentationConfiguration>
|
||||
*/
|
||||
final class ExampleConfigLoader implements EnvComponentLoader
|
||||
{
|
||||
#[\Override]
|
||||
public function load(EnvResolver $env, EnvComponentLoaderRegistry $registry, Context $context): InstrumentationConfiguration
|
||||
{
|
||||
return new ExampleConfig(
|
||||
spanName: $env->string('OTEL_PHP_EXAMPLE_INSTRUMENTATION_SPAN_NAME') ?? 'example',
|
||||
);
|
||||
}
|
||||
|
||||
#[\Override]
|
||||
public function name(): string
|
||||
{
|
||||
return ExampleConfig::class;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,52 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace OpenTelemetry\Example;
|
||||
|
||||
use OpenTelemetry\API\Configuration\Config\ComponentProvider;
|
||||
use OpenTelemetry\API\Configuration\Config\ComponentProviderRegistry;
|
||||
use OpenTelemetry\API\Configuration\Context;
|
||||
use OpenTelemetry\API\Instrumentation\AutoInstrumentation\InstrumentationConfiguration;
|
||||
use OpenTelemetry\Config\SDK\Configuration\Validation;
|
||||
use Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition;
|
||||
use Symfony\Component\Config\Definition\Builder\NodeBuilder;
|
||||
|
||||
/**
|
||||
* @implements ComponentProvider<InstrumentationConfiguration>
|
||||
*/
|
||||
final class ExampleConfigProvider implements ComponentProvider
|
||||
{
|
||||
/**
|
||||
* @psalm-suppress MoreSpecificImplementedParamType
|
||||
* @param array{
|
||||
* span_name: string,
|
||||
* enabled: bool,
|
||||
* } $properties
|
||||
*/
|
||||
#[\Override]
|
||||
public function createPlugin(array $properties, Context $context): InstrumentationConfiguration
|
||||
{
|
||||
return new ExampleConfig(
|
||||
spanName: $properties['span_name'],
|
||||
enabled: $properties['enabled'],
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @psalm-suppress UndefinedInterfaceMethod,PossiblyNullReference
|
||||
*/
|
||||
#[\Override]
|
||||
public function getConfig(ComponentProviderRegistry $registry, NodeBuilder $builder): ArrayNodeDefinition
|
||||
{
|
||||
$node = $builder->arrayNode('example_instrumentation');
|
||||
$node
|
||||
->children()
|
||||
->scalarNode('span_name')->isRequired()->validate()->always(Validation::ensureString())->end()->end()
|
||||
->end()
|
||||
->canBeDisabled()
|
||||
;
|
||||
|
||||
return $node;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,51 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace OpenTelemetry\Example;
|
||||
|
||||
use OpenTelemetry\API\Configuration\ConfigProperties;
|
||||
use OpenTelemetry\API\Instrumentation\AutoInstrumentation\Context as InstrumentationContext;
|
||||
use OpenTelemetry\API\Instrumentation\AutoInstrumentation\HookManagerInterface;
|
||||
use OpenTelemetry\API\Instrumentation\AutoInstrumentation\Instrumentation;
|
||||
use OpenTelemetry\API\Trace\Span;
|
||||
use OpenTelemetry\Context\Context;
|
||||
|
||||
final class ExampleInstrumentation implements Instrumentation
|
||||
{
|
||||
#[\Override]
|
||||
public function register(HookManagerInterface $hookManager, ConfigProperties $configuration, InstrumentationContext $context): void
|
||||
{
|
||||
$config = $configuration->get(ExampleConfig::class) ?? new ExampleConfig();
|
||||
if (!$config->enabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
$tracer = $context->tracerProvider->getTracer('example-instrumentation');
|
||||
|
||||
$hookManager->hook(
|
||||
Example::class,
|
||||
'test',
|
||||
static function () use ($tracer, $config): void {
|
||||
$context = Context::getCurrent();
|
||||
|
||||
$span = $tracer
|
||||
->spanBuilder($config->spanName)
|
||||
->setParent($context)
|
||||
->startSpan();
|
||||
|
||||
Context::storage()->attach($span->storeInContext($context));
|
||||
},
|
||||
static function (): void {
|
||||
if (!$scope = Context::storage()->scope()) {
|
||||
return;
|
||||
}
|
||||
|
||||
$scope->detach();
|
||||
|
||||
$span = Span::fromContext($scope->context());
|
||||
$span->end();
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,79 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace OpenTelemetry\Example;
|
||||
|
||||
use OpenTelemetry\API\Common\Time\ClockInterface;
|
||||
use OpenTelemetry\API\Metrics\ObserverInterface;
|
||||
use OpenTelemetry\SDK\Common\Attribute\Attributes;
|
||||
use OpenTelemetry\SDK\Common\Instrumentation\InstrumentationScopeFactory;
|
||||
use OpenTelemetry\SDK\Metrics\Exemplar\ExemplarFilter\WithSampledTraceExemplarFilter;
|
||||
use OpenTelemetry\SDK\Metrics\MeterProvider;
|
||||
use OpenTelemetry\SDK\Metrics\MetricReader\ExportingReader;
|
||||
use OpenTelemetry\SDK\Metrics\StalenessHandler\ImmediateStalenessHandlerFactory;
|
||||
use OpenTelemetry\SDK\Metrics\View\CriteriaViewRegistry;
|
||||
use OpenTelemetry\SDK\Resource\ResourceInfoFactory;
|
||||
|
||||
class ExampleMetricsGenerator
|
||||
{
|
||||
private ExportingReader $reader;
|
||||
private ClockInterface $clock;
|
||||
|
||||
public function __construct(ExportingReader $reader, ClockInterface $clock)
|
||||
{
|
||||
$this->reader = $reader;
|
||||
$this->clock = $clock;
|
||||
}
|
||||
|
||||
public function generate(): void
|
||||
{
|
||||
$meterProvider = new MeterProvider(
|
||||
null,
|
||||
ResourceInfoFactory::defaultResource(),
|
||||
$this->clock,
|
||||
Attributes::factory(),
|
||||
new InstrumentationScopeFactory(Attributes::factory()),
|
||||
[$this->reader],
|
||||
new CriteriaViewRegistry(),
|
||||
new WithSampledTraceExemplarFilter(),
|
||||
new ImmediateStalenessHandlerFactory(),
|
||||
);
|
||||
|
||||
$meter = $meterProvider->getMeter('io.opentelemetry.contrib.php');
|
||||
$meter
|
||||
->createObservableUpDownCounter('process.memory.usage', 'By', 'The amount of physical memory in use.')
|
||||
->observe(static function (ObserverInterface $observer): void {
|
||||
$observer->observe(memory_get_usage(true));
|
||||
});
|
||||
|
||||
$serverDuration = $meter
|
||||
->createHistogram('http.server.duration', 'ms', 'measures the duration inbound HTTP requests');
|
||||
|
||||
// During the time range (T0, T1]:
|
||||
$serverDuration->record(50, ['http.method' => 'GET', 'http.status_code' => 200]);
|
||||
$serverDuration->record(100, ['http.method' => 'GET', 'http.status_code' => 200]);
|
||||
$serverDuration->record(1, ['http.method' => 'GET', 'http.status_code' => 500]);
|
||||
$this->reader->collect();
|
||||
|
||||
// During the time range (T1, T2]:
|
||||
$this->reader->collect();
|
||||
|
||||
// During the time range (T2, T3]:
|
||||
$serverDuration->record(5, ['http.method' => 'GET', 'http.status_code' => 500]);
|
||||
$serverDuration->record(2, ['http.method' => 'GET', 'http.status_code' => 500]);
|
||||
$this->reader->collect();
|
||||
|
||||
// During the time range (T3, T4]:
|
||||
$serverDuration->record(100, ['http.method' => 'GET', 'http.status_code' => 200]);
|
||||
$this->reader->collect();
|
||||
|
||||
// During the time range (T4, T5]:
|
||||
$serverDuration->record(100, ['http.method' => 'GET', 'http.status_code' => 200]);
|
||||
$serverDuration->record(30, ['http.method' => 'GET', 'http.status_code' => 200]);
|
||||
$serverDuration->record(50, ['http.method' => 'GET', 'http.status_code' => 200]);
|
||||
$this->reader->collect();
|
||||
|
||||
$meterProvider->shutdown();
|
||||
}
|
||||
}
|
|
@ -4,8 +4,8 @@ receivers:
|
|||
grpc:
|
||||
|
||||
exporters:
|
||||
logging:
|
||||
logLevel: debug
|
||||
debug:
|
||||
verbosity: detailed
|
||||
zipkin:
|
||||
endpoint: "http://zipkin:9411/api/v2/spans"
|
||||
jaeger:
|
||||
|
@ -19,6 +19,6 @@ service:
|
|||
receivers:
|
||||
- otlp
|
||||
exporters:
|
||||
- logging
|
||||
- debug
|
||||
- zipkin
|
||||
- jaeger
|
|
@ -1,16 +1,17 @@
|
|||
x-otel-common: &otel-common
|
||||
OTEL_LOG_LEVEL: warning
|
||||
x-otel-common:
|
||||
&otel-common
|
||||
OTEL_LOG_LEVEL: warning # The library does not respect this environment variable as of this writing
|
||||
OTEL_TRACES_SAMPLER: parentbased_always_on
|
||||
OTEL_TRACES_EXPORTER: otlp
|
||||
OTEL_EXPORTER_OTLP_TRACES_PROTOCOL: grpc
|
||||
OTEL_EXPORTER_OTLP_ENDPOINT: collector:4317
|
||||
OTEL_EXPORTER_OTLP_ENDPOINT: http://collector:4317
|
||||
OTEL_PHP_TRACES_PROCESSOR: simple
|
||||
|
||||
version: '3.7'
|
||||
services:
|
||||
service-one:
|
||||
image: ghcr.io/open-telemetry/opentelemetry-php/opentelemetry-php-base:latest
|
||||
command: ['php', '-S', '0.0.0.0:8000']
|
||||
image: ghcr.io/open-telemetry/opentelemetry-php/opentelemetry-php-base:8.1
|
||||
command: [ 'php', '-S', '0.0.0.0:8000' ]
|
||||
volumes:
|
||||
- './src:/usr/src/myapp'
|
||||
ports:
|
||||
|
@ -21,8 +22,8 @@ services:
|
|||
OTEL_RESOURCE_ATTRIBUTES: 'service.version=0.1'
|
||||
|
||||
service-two:
|
||||
image: ghcr.io/open-telemetry/opentelemetry-php/opentelemetry-php-base:latest
|
||||
command: ['php', '-S', '0.0.0.0:8000']
|
||||
image: ghcr.io/open-telemetry/opentelemetry-php/opentelemetry-php-base:8.1
|
||||
command: [ 'php', '-S', '0.0.0.0:8000' ]
|
||||
volumes:
|
||||
- './src:/usr/src/myapp'
|
||||
environment:
|
||||
|
@ -31,8 +32,8 @@ services:
|
|||
OTEL_RESOURCE_ATTRIBUTES: 'service.version=0.2'
|
||||
|
||||
service-three:
|
||||
image: ghcr.io/open-telemetry/opentelemetry-php/opentelemetry-php-base:latest
|
||||
command: ['php', '-S', '0.0.0.0:8000']
|
||||
image: ghcr.io/open-telemetry/opentelemetry-php/opentelemetry-php-base:8.1
|
||||
command: [ 'php', '-S', '0.0.0.0:8000' ]
|
||||
volumes:
|
||||
- './src:/usr/src/myapp'
|
||||
environment:
|
||||
|
@ -40,9 +41,11 @@ services:
|
|||
OTEL_SERVICE_NAME: service-three
|
||||
|
||||
collector:
|
||||
image: otel/opentelemetry-collector-contrib:0.39.0
|
||||
image: otel/opentelemetry-collector-contrib
|
||||
volumes:
|
||||
- './collector:/etc/otel'
|
||||
ports:
|
||||
- '4317:4317'
|
||||
|
||||
zipkin:
|
||||
image: openzipkin/zipkin-slim
|
Before Width: | Height: | Size: 39 KiB After Width: | Height: | Size: 39 KiB |
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue