Compare commits

...

1099 Commits

Author SHA1 Message Date
Alexandru-Liviu Bratosin 063107068c
fix(async-processor): concurrent exports actually serialised (#3028) 2025-07-14 10:37:21 -07:00
Reiley Yang 8925f064d2
chore: Remove file .github/repository-settings.md (#3067) 2025-07-14 10:31:30 -07:00
Lalit Kumar Bhasin 8aba0913e9
chore: Bump semantic-conventions to v1.36.0 (#3064) 2025-07-14 10:04:21 -07:00
OpenTelemetry Bot 34d6d5082e
Sort contributor listings and remove affiliation from emeriti (#3060) 2025-07-09 22:11:59 +02:00
Berkus Decker 5e447d02cc
chore: Switch from unmaintained hex dependency to const-hex (#3053) 2025-07-09 08:54:12 -07:00
Whoemoon Jang 8d46c40b60
fix: Support HttpClient implementation for HyperClient with custom connectors (#3057) 2025-07-07 11:36:38 -07:00
Copilot eac368a7e4
chore: Fix spelling errors and typos in documentation (#3044)
Co-authored-by: Cijo Thomas <cijo.thomas@gmail.com>
2025-07-02 09:53:05 -07:00
dependabot[bot] 2bf8175d07
chore(deps): bump taiki-e/install-action from 2.52.4 to 2.56.0 (#3051)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Cijo Thomas <cijo.thomas@gmail.com>
2025-07-01 13:33:02 -07:00
dependabot[bot] 3fc7194796
chore(deps): bump EmbarkStudios/cargo-deny-action from 2.0.11 to 2.0.12 (#3052)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-07-01 13:24:26 -07:00
dependabot[bot] db15ecb541
chore(deps): bump obi1kenobi/cargo-semver-checks-action from 2.6 to 2.8 (#3050)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-07-01 13:24:14 -07:00
dependabot[bot] 674914a8ef
chore(deps): bump github/codeql-action from 3.28.16 to 3.29.2 (#3049)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Utkarsh Umesan Pillai <66651184+utpilla@users.noreply.github.com>
2025-07-01 13:23:57 -07:00
dependabot[bot] 6bc2b19b85
chore(deps): bump step-security/harden-runner from 2.12.0 to 2.12.2 (#3048)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-07-01 12:49:44 -07:00
Lushe Shipkov d59aded375
docs: A few small doc touch-ups in some of the various in_memory_exporter modules (#3042) 2025-06-30 09:24:40 -07:00
OpenTelemetry Bot e7784bb78f
docs: Update community member listings (#3038)
Co-authored-by: otelbot <197425009+otelbot@users.noreply.github.com>
Co-authored-by: Utkarsh Umesan Pillai <66651184+utpilla@users.noreply.github.com>
Co-authored-by: Cijo Thomas <cijo.thomas@gmail.com>
2025-06-27 09:43:55 -06:00
Anton Grübel 5e29598369
chore: fix format lint (#3039) 2025-06-27 09:33:16 -06:00
yoshi-taka af2f1449e8
chore: remove unused glob (#3035) 2025-06-22 17:00:42 -07:00
Scott Gerring 0c2f808ec2
ci: Run benchmarks on main on the new oracle dedicated workers (#2942) 2025-06-20 08:37:17 -07:00
Cijo Thomas d4eb35a0cc
docs: on how to set right cardinality limit (#2998)
Co-authored-by: Lalit Kumar Bhasin <lalit_fin@yahoo.com>
2025-06-12 17:03:39 -07:00
Lalit Kumar Bhasin 1f0d9a9f62
chore: Prepare for opentelemetry-appender-tracing 0.30.1 - bump tracing-opentelemetry to 0.31 (#3022) 2025-06-05 11:43:18 -07:00
dependabot[bot] 51dc2f04b7
chore(deps): update dtolnay/rust-toolchain requirement to b3b07ba8b418998c39fb20f53e8b695cdcc8de1b (#3016)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Lalit Kumar Bhasin <lalit_fin@yahoo.com>
2025-06-05 10:43:48 -07:00
Igor Unanua eaca267d04
feat: support multi-value key propagation extraction (#3008)
Co-authored-by: Cijo Thomas <cijo.thomas@gmail.com>
2025-06-04 14:52:57 -07:00
Lalit Kumar Bhasin 7b3db0b6a6
chore: Bump otel-proto v1.7.0 (#3018) 2025-06-03 08:20:25 -07:00
Lalit Kumar Bhasin 082213e4e9
chore: bump semcon 1.34.0 (#3019) 2025-06-02 11:24:51 -07:00
dependabot[bot] c473db0788
chore(deps): bump taiki-e/install-action from 2.50.4 to 2.52.4 (#3015) 2025-06-01 21:31:03 -07:00
dependabot[bot] 85e639aef9
chore(deps): bump ossf/scorecard-action from 2.4.1 to 2.4.2 (#3014) 2025-06-01 21:21:45 -07:00
dependabot[bot] f1a541c3ca
chore(deps): bump codecov/codecov-action from 5.4.2 to 5.4.3 (#3013)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Utkarsh Umesan Pillai <66651184+utpilla@users.noreply.github.com>
2025-06-01 20:34:16 -07:00
dependabot[bot] c30dc37002
chore(deps): bump fossas/fossa-action from 1.6.0 to 1.7.0 (#3012)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-06-01 13:22:45 -07:00
Gabriel 28becc0674
fix: with_cleared_baggage (#3006)
Co-authored-by: Cijo Thomas <cijo.thomas@gmail.com>
2025-05-30 08:19:46 -07:00
Joonas Bergius cab5565ba1
fix: use default endpoint for endpoint when provided empty string (#3000)
Signed-off-by: Joonas Bergius <joonas@cosmonic.com>
Co-authored-by: Cijo Thomas <cijo.thomas@gmail.com>
2025-05-30 07:51:40 -07:00
Cijo Thomas 62790608e1
fix: Small improvement to OTLP Exporter logs (#3007) 2025-05-30 07:13:26 -07:00
paullegranddc 167c94663a
fix(span_processor): only call on_start with recording spans (#3011) 2025-05-30 06:53:57 -07:00
Cijo Thomas 8e47d84922
chore: Add release notes for 0.30 (#3001)
Co-authored-by: Zhongyang Wu <zhongyang.wu@outlook.com>
2025-05-27 06:43:34 -07:00
Cijo Thomas 8882c31c95
chore: Nit fixes to examples (#3002) 2025-05-23 10:56:42 -07:00
Cijo Thomas c811cde1ae
chore: Prepare release 0.30.0 (#2999) 2025-05-23 09:52:50 -07:00
SF-Zhou 200885a6c3
fix: fix trace id in logs when using set_parent nested in a trace span (#2924)
Co-authored-by: Cijo Thomas <cijo.thomas@gmail.com>
2025-05-23 08:01:46 -07:00
Cijo Thomas c24369e86a
chore: Update metric sdk to stable status (#2996) 2025-05-23 07:51:41 -07:00
Cijo Thomas bf22aeb7cc
fix: Remove pub fields and replace with getter method consistently across … (#2997) 2025-05-22 22:41:49 -07:00
Cijo Thomas 4be1a32d3f
fix: remove cardinality capping via instrument advice (#2995) 2025-05-22 13:46:27 -07:00
Cijo Thomas 3d04c16e39
docs: Add metric doc (#2946)
Co-authored-by: Lalit Kumar Bhasin <lalit_fin@yahoo.com>
Co-authored-by: Utkarsh Umesan Pillai <66651184+utpilla@users.noreply.github.com>
2025-05-22 13:32:37 -07:00
Cijo Thomas 2018959eec
fix: Fix validation in Metric stream (#2991) 2025-05-22 11:18:44 -07:00
Anton Grübel 8c29ca7e21
chore: leverage fallback resolver for MSRV check (#2993) 2025-05-22 08:39:53 -07:00
Cijo Thomas 4b3a383267
chore: add required features to benches (#2990) 2025-05-21 20:45:20 -07:00
Cijo Thomas ebbebf57ba
fix: Further trim public API on views (#2989)
Co-authored-by: Utkarsh Umesan Pillai <66651184+utpilla@users.noreply.github.com>
2025-05-21 19:07:08 -07:00
Cijo Thomas e123996d80
feat: View cleanups (#2988) 2025-05-21 16:40:32 -07:00
Adrian Garcia Badaracco 3cdc62e716
feat: add generated proto models for profiles signal (#2979)
Co-authored-by: Cijo Thomas <cijo.thomas@gmail.com>
2025-05-21 09:24:47 -07:00
Cijo Thomas f04e9ec6cd
feat: Use builder pattern for constructing Metric Streams (#2984) 2025-05-21 07:37:16 -07:00
Cijo Thomas 7cfe8cd883
chore: fix changelogs (#2983) 2025-05-21 07:07:07 -07:00
Cijo Thomas aeb38a02c1
feat: Promote subset of Metric Views to stable (#2982) 2025-05-20 21:09:20 -07:00
Elichai Turkel 857a38b191
fix: Expose SpanExporterBuilder and MetricExporterBuilder (#2966)
Co-authored-by: Cijo Thomas <cijo.thomas@gmail.com>
2025-05-20 20:21:04 -07:00
Cijo Thomas cc93ead2df
fix: Metrics Views - fix a bug that causes unit, description to be lost when applying views that influence other aspects (#2981) 2025-05-20 17:59:17 -07:00
Cijo Thomas d52dcef07d
fix: MetricExporters use getter methods instead of direct access (#2973)
Co-authored-by: Lalit Kumar Bhasin <lalit_fin@yahoo.com>
2025-05-20 10:07:07 -07:00
Lalit Kumar Bhasin 84999140a7
chore: bump semconv 1.33.0 (#2975) 2025-05-16 20:14:16 -07:00
Cijo Thomas 9a0099ab8d
chore: remove unused (and incorrect!) doc links (#2974) 2025-05-16 13:21:00 -07:00
Mohammad Vatandoost c5f97180a3
feat: add shutdown with timeout for traces (#2956)
Co-authored-by: Lalit Kumar Bhasin <lalit_fin@yahoo.com>
Co-authored-by: Cijo Thomas <cijo.thomas@gmail.com>
2025-05-16 07:12:50 -07:00
Cijo Thomas 8f4fe23bb1
fix: Avoid exposing HistogramBuckets and bounds (#2969) 2025-05-14 22:11:59 -07:00
StepSecurity Bot fed6fee190
ci: Harden GitHub Actions (#2971)
Signed-off-by: StepSecurity Bot <bot@stepsecurity.io>
2025-05-14 22:03:27 -07:00
Cijo Thomas 970bb1e4b6
fix: Avoid exposing implementation detail in public API for PushMetricExporter (#2968) 2025-05-14 10:15:50 -07:00
Utkarsh Umesan Pillai a4575af593
fix: Update ResourceMetrics public API (#2965)
Co-authored-by: Cijo Thomas <cijo.thomas@gmail.com>
2025-05-14 07:39:02 -07:00
Cijo Thomas 82e5ed405e
fix: PeriodicReader to reuse data structures across collect (#2963) 2025-05-14 07:29:37 -07:00
paullegranddc 8fe3dcccc4
fix(CI): patch dependencies before running external-types check (#2967) 2025-05-14 06:44:27 -07:00
Cijo Thomas 3f29f6d8bf
chore: fix cargo deny check by updating unicode allowed list (#2964) 2025-05-14 06:39:46 +02:00
Björn Antonsson f771404f82
fix: allow span links to be added to a SpanRef (#2959) 2025-05-07 08:34:42 -07:00
Lalit Kumar Bhasin 1d9bd25ec8
chore: Fix CI coverage error for failing to install llvm-cov (#2958) 2025-05-05 11:32:10 -07:00
Lalit Kumar Bhasin 377fe5db7c
chore: publish otel-proto v1.6.0 (#2955) 2025-05-05 10:32:16 -07:00
Cijo Thomas 3d589d6449
ci: Try to build examples in CI (#2711)
Co-authored-by: Harold Dost <h.dost@criteo.com>
2025-05-05 08:08:50 +02:00
dependabot[bot] fa692d8c5c
chore(deps): bump taiki-e/install-action from 2.49.45 to 2.50.4 (#2952)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Utkarsh Umesan Pillai <66651184+utpilla@users.noreply.github.com>
2025-05-01 14:13:49 -07:00
dependabot[bot] c6c2453ac4
chore(deps): update dtolnay/rust-toolchain requirement to b3b07ba8b418998c39fb20f53e8b695cdcc8de1b (#2953)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Utkarsh Umesan Pillai <66651184+utpilla@users.noreply.github.com>
2025-05-01 14:05:18 -07:00
dependabot[bot] 06c6dfd6a8
chore(deps): bump github/codeql-action from 3.28.13 to 3.28.16 (#2954)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Utkarsh Umesan Pillai <66651184+utpilla@users.noreply.github.com>
2025-05-01 13:57:25 -07:00
dependabot[bot] 175c7c6e9c
chore(deps): bump step-security/harden-runner from 2.11.1 to 2.12.0 (#2951)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Utkarsh Umesan Pillai <66651184+utpilla@users.noreply.github.com>
2025-05-01 13:43:03 -07:00
dependabot[bot] 225bc0ebfa
chore(deps): bump codecov/codecov-action from 4.6.0 to 5.4.2 (#2950)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-05-01 13:17:20 -07:00
Mohammad Vatandoost 1d37e07529
feat: add-shutdown-with-timeout-for-log-provider-and-processor (#2941)
Co-authored-by: Lalit Kumar Bhasin <lalit_fin@yahoo.com>
Co-authored-by: Cijo Thomas <cijo.thomas@gmail.com>
2025-05-01 09:09:01 -07:00
Cijo Thomas 4f2de12350
fix: Pass immutable metrics to PushMetricExporter (#2947) 2025-04-30 10:01:52 -07:00
Mathieu Tricoire 1d610a211a
feat(otlp): Re-export tonic crate (#2898)
Co-authored-by: Cijo Thomas <cijo.thomas@gmail.com>
Co-authored-by: Lalit Kumar Bhasin <lalit_fin@yahoo.com>
2025-04-30 09:44:23 -07:00
Cijo Thomas 409713d2d9
fix: Allow Histograms with no buckets (#2948) 2025-04-30 09:19:05 -07:00
bestgopher 7f8adcc3f5
docs(semconv): fix some invalid urls (#2944) 2025-04-29 10:49:48 -07:00
Anton Grübel 02c290de84
chore: change webpki-roots exception license to CDLA (#2945) 2025-04-28 16:18:24 -07:00
Cijo Thomas 9dc727ef58
chore: Add Bjorn as approver (#2937)
Björn has been actively helping the repo for last few months, and is leading the exploration/development of tokio-tracing interop, among many other contributions/reviews.
He has agreed to volunteer time as an Approver for the repo.

In my view, https://github.com/open-telemetry/community/blob/main/guides/contributor/membership.md#requirements-2 requirements have been met.
2025-04-22 22:25:22 +02:00
Mohammad Vatandoost 5c60f12f04
feat: add shutdown with timeout for log exporter (#2909)
Co-authored-by: Cijo Thomas <cijo.thomas@gmail.com>
2025-04-21 18:17:42 -07:00
Utkarsh Umesan Pillai d7f824486a
ci: Add cargo deny license check (#2936) 2025-04-21 14:55:29 -07:00
Utkarsh Umesan Pillai d8d57d834d
ci: Add cargo deny checks for bans and sources (#2935) 2025-04-21 11:34:20 +02:00
Gilles Henaux b5d31f11fa
docs: fix the HTTP and gRPC transports quickstart guides (#2933) 2025-04-17 07:43:06 -07:00
Lalit Kumar Bhasin 9cdc93161d
chore: bump semconv 1.32.0 (#2932) 2025-04-15 13:28:43 -07:00
Cijo Thomas 10cf02c458
chore: Fix changelogs and few nits (#2929) 2025-04-13 18:24:26 -07:00
Cijo Thomas 4ce765567c
feat: Hide MetricReader and friends (#2928) 2025-04-11 16:48:34 -07:00
Cijo Thomas 64cf2916c4
chore: Patch release prometheus to fix security vulnerability (#2927)
Co-authored-by: Utkarsh Umesan Pillai <66651184+utpilla@users.noreply.github.com>
2025-04-10 21:55:25 -07:00
houseme 431689dd04
chore: Upgrade `prometheus` to 0.14 and clean up protobuf-related code in `lib.rs` (#2920)
Co-authored-by: Cijo Thomas <cijo.thomas@gmail.com>
2025-04-10 19:33:36 -07:00
Utkarsh Umesan Pillai 8b3fc06555
ci: Update permissions for workflow (#2923) 2025-04-09 15:51:59 -07:00
Utkarsh Umesan Pillai 130e178ad3
docs: Add openssf scorecard badge (#2919) 2025-04-08 16:32:20 -07:00
Utkarsh Umesan Pillai 6b5251f0d0
ci: Update CodeQL workflow (#2918) 2025-04-08 14:46:01 -07:00
Cijo Thomas 4ff8e02031
fix: Cardinality overflow to use bool value instead of string (#2916) 2025-04-08 12:52:16 -07:00
Cijo Thomas d4c646738f
fix: cleanup MetricError (#2906) 2025-04-08 08:23:51 -07:00
Cijo Thomas df262401da
feat: Add ability to specify cardinality limit via Instrument advice (#2903) 2025-04-07 22:52:25 -07:00
Utkarsh Umesan Pillai 1760889e27
ci: Harden GitHub Actions (#2915) 2025-04-07 22:41:11 -07:00
Utkarsh Umesan Pillai e680514e4f
ci: Harden GitHub Actions (#2913) 2025-04-07 19:55:50 -07:00
Utkarsh Umesan Pillai bef0523b68
ci: Harden GitHub Actions (#2914) 2025-04-07 19:46:09 -07:00
StepSecurity Bot 72fc1b60a5
ci: [StepSecurity] Harden GitHub Actions (#2910)
Signed-off-by: StepSecurity Bot <bot@stepsecurity.io>
Co-authored-by: Utkarsh Umesan Pillai <66651184+utpilla@users.noreply.github.com>
2025-04-07 18:03:12 -07:00
StepSecurity Bot f99f20a87d
ci: [StepSecurity] Harden GitHub Actions (#2912)
Signed-off-by: StepSecurity Bot <bot@stepsecurity.io>
Co-authored-by: Utkarsh Umesan Pillai <66651184+utpilla@users.noreply.github.com>
2025-04-07 17:28:49 -07:00
Utkarsh Umesan Pillai 940ec2304b
ci: Harden GitHub Actions (#2911) 2025-04-07 15:25:42 -07:00
StepSecurity Bot 9a0ffc4adf
fix: [StepSecurity] ci: Harden GitHub Actions (#2907)
Signed-off-by: StepSecurity Bot <bot@stepsecurity.io>
Co-authored-by: Utkarsh Umesan Pillai <66651184+utpilla@users.noreply.github.com>
2025-04-07 13:01:32 -07:00
Lalit Kumar Bhasin 16ff4b0575
chore: CI lint fix for dead link (#2908) 2025-04-07 12:22:18 -07:00
Cijo Thomas bc82d4f66d
fix: Cleanup MetricError and use OTelSdkResult instead (#2905) 2025-04-06 11:29:55 -07:00
Mohammad Vatandoost e9ae9f90ef
feat: add shutdown with timeout for metric reader and provider (#2890)
Co-authored-by: Lalit Kumar Bhasin <lalit_fin@yahoo.com>
Co-authored-by: Cijo Thomas <cijo.thomas@gmail.com>
2025-04-06 09:37:37 -07:00
Cijo Thomas 4791aae19f
test: Add ignored code in test to prove known issue (#2872) 2025-04-06 07:59:30 -07:00
Cijo Thomas 4b56ee354c
fix: Remove logging for cardinality overflow (#2904) 2025-04-06 07:38:55 -07:00
Cijo Thomas 2564a71808
feat: Add and enabled Metric cardinality capping by default (#2901) 2025-04-04 16:04:45 -07:00
Björn Antonsson 86e842ca5e
chore: fix clippy lint errors for rust 1.86.0 (#2896) 2025-04-03 09:14:04 -07:00
dependabot[bot] 24b92cb7c7
chore(deps): bump fossas/fossa-action from 1.5.0 to 1.6.0 (#2892)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-04-01 12:50:07 -07:00
dependabot[bot] 93a151e720
chore(deps): bump github/codeql-action from 3.28.12 to 3.28.13 (#2891)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-04-01 12:49:36 -07:00
Scott Gerring 7bdd2f4160
fix: re-export WithContext in the same place (#2879)
Co-authored-by: Cijo Thomas <cijo.thomas@gmail.com>
2025-04-01 08:26:38 -07:00
Mohammad Vatandoost af3a33e1b3
feat: Add shutdown with timeout for metric exporter (#2854)
Co-authored-by: Braden Steffaniak <BradenSteffaniak+github@gmail.com>
Co-authored-by: Cijo Thomas <cijo.thomas@gmail.com>
Co-authored-by: Cijo Thomas <cithomas@microsoft.com>
2025-04-01 08:02:17 -07:00
Scott Gerring 37d794788e
chore: Move 'main' benchmark to shared workers temporarily (#2889) 2025-04-01 07:49:30 -07:00
OpenTelemetry Bot 36633015ab
ci: Add ossf-scorecard scanning workflow (#2887)
Co-authored-by: otelbot <197425009+otelbot@users.noreply.github.com>
2025-04-01 07:43:12 -07:00
Björn Antonsson 867e2a172c
perf: Run all benchmarks in one action (#2885)
Co-authored-by: Cijo Thomas <cijo.thomas@gmail.com>
2025-03-31 08:03:31 -07:00
Anton Grübel d5e409ce1f
refactor: re-export tracing for internal-logs (#2867)
Co-authored-by: Cijo Thomas <cijo.thomas@gmail.com>
2025-03-31 07:47:41 -07:00
Cijo Thomas 99cb67d19c
perf: Nit fix to benchmarks (#2884) 2025-03-28 15:33:23 -07:00
Cijo Thomas 303803e304
chore: Add Anton Grübel as approver (#2863) 2025-03-28 14:55:40 -07:00
Cijo Thomas 62e43c5489
feat: Leverage Suppression Context in Sdk (#2868)
Co-authored-by: Utkarsh Umesan Pillai <66651184+utpilla@users.noreply.github.com>
2025-03-28 10:51:40 -07:00
Björn Antonsson 50f0bb82f8
ci: run clippy on features separately to find issues (#2866)
Co-authored-by: Cijo Thomas <cijo.thomas@gmail.com>
2025-03-28 09:38:51 -07:00
Björn Antonsson da2029ea17
perf: Run all benchmarks for shorter time (#2870) 2025-03-28 09:23:06 -07:00
Anton Grübel b2de6cc5a3
chore: update tonic to 0.13 (#2876) 2025-03-27 14:47:02 -07:00
Anton Grübel a071d8fc39
ci: update deny GHA and its config (#2875) 2025-03-27 12:03:54 -07:00
Cijo Thomas 297146701d
feat: Add Suppression flag to context (#2821)
Co-authored-by: Lalit Kumar Bhasin <lalit_fin@yahoo.com>
2025-03-26 16:14:41 -07:00
Mindaugas Vinkelis f3e93a09ea
refactor: AggregatedMetrics as enum instead of dyn Aggregation (#2857)
Co-authored-by: Cijo Thomas <cijo.thomas@gmail.com>
2025-03-26 10:39:57 -07:00
Cijo Thomas f12833f383
docs: Modify example to use logs, baggage (#2855)
Co-authored-by: Zhongyang Wu <zhongyang.wu@outlook.com>
2025-03-26 07:55:06 -07:00
Scott Gerring fb3699bc05
chore: Update error handling ADR - mention non_exhaustive (#2865) 2025-03-26 06:41:38 -07:00
Anton Grübel a711ae91c7
ci: add cargo machete and remove unused dependencies (#2864) 2025-03-25 15:01:24 -07:00
Cijo Thomas 5bfa70ef23
chore: Add company affiliation to maintainers and approvers (#2859) 2025-03-25 10:26:49 -07:00
houseme e9b27a4df6
chore: update from tracing-opentelemetry 0.29.0 to 0.30.0 (#2856)
Co-authored-by: Cijo Thomas <cijo.thomas@gmail.com>
2025-03-24 09:56:56 -07:00
Cijo Thomas f1c7ce9225
chore: fix few nit build warnings (#2848) 2025-03-24 08:11:49 -07:00
Cijo Thomas fa170f3258
fix: LogEnabled benchmarks to use blackbox (#2853) 2025-03-23 17:09:58 -07:00
tison 369b952baf
chore: Add link to sdk's CHANGELOG.md (#2850) 2025-03-22 10:28:12 -07:00
Braden Steffaniak e994d5237e
chore: Upgrade opentelemetry-prometheus to 0.29 (#2851) 2025-03-22 10:15:28 -07:00
Anton Grübel c5d5a1cc69
perf: small perf improvements in OTel API (#2842)
Co-authored-by: Cijo Thomas <cijo.thomas@gmail.com>
2025-03-21 20:20:52 -07:00
Cijo Thomas d32d34c8e0
chore: fix and release appender-tracing (#2847) 2025-03-21 17:47:50 -07:00
Cijo Thomas ad0552a6a9
chore: Prepare 0.29 release (#2844) 2025-03-21 17:10:01 -07:00
Anton Grübel 14d8f749ac
ci: replace actions-rs/cargo GHA (#2846) 2025-03-21 15:18:06 -07:00
Lalit Kumar Bhasin 5881f99528
chore: bump semconv 1.31.0 (#2845) 2025-03-21 15:03:28 -07:00
Cijo Thomas 34835a89e5
chore: Prepare docs before 0.29 (#2837)
Co-authored-by: Utkarsh Umesan Pillai <66651184+utpilla@users.noreply.github.com>
2025-03-21 12:10:29 -07:00
Cijo Thomas 1ecd1a8718
fix: KeyValueMetadata to not expose its fields public (#2843) 2025-03-21 12:00:35 -07:00
Cijo Thomas 3e77a22ca3
fix: Error cleanups continued (#2838) 2025-03-21 11:42:30 -07:00
Scott Gerring 36c48db5fd
chore: context stabilization tests & logging pieces (#2833)
Co-authored-by: Cijo Thomas <cijo.thomas@gmail.com>
2025-03-20 16:04:05 -07:00
Cijo Thomas b03296cc3a
chore: Add warning on Prometheus crate (#2831) 2025-03-20 07:26:48 -07:00
Cijo Thomas 969bedf1a7
fix: Cleanup zipkin build error (#2839) 2025-03-20 07:09:01 -07:00
Anton Grübel 702c61dcee
test: validate code-based config is preferred over env vars in ZipkinExporterBuilder (#2836)
Co-authored-by: Cijo Thomas <cijo.thomas@gmail.com>
2025-03-19 18:54:03 -07:00
Cijo Thomas dc580ff54b
fix: Report error using OTel convention (#2808)
Co-authored-by: Anton Grübel <anton.gruebel@gmail.com>
Co-authored-by: Utkarsh Umesan Pillai <66651184+utpilla@users.noreply.github.com>
2025-03-19 17:24:41 -07:00
Anton Grübel bece03ba59
fix: validate Baggage key by W3C standards (#2804)
Co-authored-by: Lalit Kumar Bhasin <lalit_fin@yahoo.com>
Co-authored-by: Cijo Thomas <cijo.thomas@gmail.com>
2025-03-19 15:46:11 -07:00
Scott Gerring 31b494bccb
ci: fix filter for benchmark pushes on branch (#2834) 2025-03-19 08:25:15 -07:00
Scott Gerring 75485dcd07
ci: Use bare-metal OTEL runners for benchmark CI for pushes to main (#2832) 2025-03-19 07:19:53 -07:00
Anton Grübel 5be79c7477
refactor: prioritize code-based config over env vars in OTLP exporter (#2827)
Co-authored-by: Lalit Kumar Bhasin <lalit_fin@yahoo.com>
Co-authored-by: Cijo Thomas <cithomas@microsoft.com>
Co-authored-by: Cijo Thomas <cijo.thomas@gmail.com>
2025-03-18 21:02:29 -07:00
Anton Grübel 06abe3dbf9
ci: use GHCR otel-collector image (#2830) 2025-03-18 16:03:41 -07:00
Cijo Thomas d2859dc8c0
docs: Add docs to tracing appender (#2811) 2025-03-18 13:02:53 -07:00
Cijo Thomas 01898be24a
perf: LogEnabled inline more (#2828) 2025-03-18 10:32:43 -07:00
Cijo Thomas e43f3dfa4a
perf: Inline enabled check in Logger (#2823) 2025-03-18 10:08:56 -07:00
Cijo Thomas 40effae08a
fix: Remove async std (#2820)
Co-authored-by: Utkarsh Umesan Pillai <66651184+utpilla@users.noreply.github.com>
2025-03-18 07:47:43 -07:00
Cijo Thomas 9569b0f816
docs: Add few more notes about Logs design doc (#2816) 2025-03-17 16:18:00 -07:00
Cijo Thomas 2070e6cf90
chore: Modify OTLP doc to show jaeger usage instead of a full example (#2805) 2025-03-17 14:05:03 -07:00
Julian Tescher 0ff8c34b06
chore: Move jtescher from Maintainer to Emeritus (#2815) 2025-03-17 13:02:41 -07:00
Cijo Thomas a80dc0c686
test: Improve OTLP Builder test (#2817) 2025-03-17 12:54:00 -07:00
Cijo Thomas 233d11a5fd
docs: OTLP Examples to shutdown all signals (#2806) 2025-03-17 09:49:56 -07:00
Scott Gerring 1bce83fcda
chore: Move FutureExt into context (#2776)
Co-authored-by: Cijo Thomas <cijo.thomas@gmail.com>
2025-03-17 07:45:22 -07:00
Anton Grübel e48e6f4e16
chore: remove deprecated functions/methods in trace::Config (#2810) 2025-03-16 06:19:40 -07:00
Anton Grübel e5f8a48d3b
test: validate code based config is preferrred over env vars in trace BatchConfig (#2809) 2025-03-15 18:46:03 -07:00
Cijo Thomas a442d623e5
fix: Byte arrays represented as Anyvalue::Byte instead of string (#2807) 2025-03-14 19:05:34 -07:00
Cijo Thomas 6e58810080
docs: Include context, baggage etc to main readme (#2785)
Co-authored-by: Zhongyang Wu <zhongyang.wu@outlook.com>
2025-03-14 08:28:46 -07:00
Cijo Thomas 8872bf810d
feat: OTLP Exporter builders to return specific Error type (#2790) 2025-03-14 08:22:23 -07:00
Cijo Thomas ddac8e1ef3
fix: LogProcessor.SetResource to require mutable self (#2801) 2025-03-13 18:06:18 -07:00
Cijo Thomas 07b3b4056d
perf: Small perf optimization for logs (#2799) 2025-03-13 10:55:21 -07:00
Cijo Thomas 6b221e496b
fix: Avoid stringifying int values unless necessary (#2795) 2025-03-13 10:11:49 -07:00
Anton Grübel 66579ac47e
fix: Change logger scope in log appender (#2796) 2025-03-13 07:48:50 -07:00
Marcus Griep ad886152d5
docs: fix unit in metrics semantic conventions example (#2794)
Co-authored-by: Lalit Kumar Bhasin <lalit_fin@yahoo.com>
2025-03-12 09:40:06 -07:00
Cijo Thomas 5bcaf30581
chore: Update BUG-REPORT.yml (#2791) 2025-03-12 08:41:34 -07:00
Cijo Thomas 8aa5b00493
feat: Add experimental concurrent processor for logs (#2780) 2025-03-11 16:01:38 -07:00
Cijo Thomas 52cd0e9ef1
test: Add test to confirm programmatic config wins over env in BatchConfig (#2781) 2025-03-11 11:04:04 -07:00
paullegranddc 51dda2f0a1
test: fix otlp log integration tests failing with some set of features (#2784) 2025-03-11 10:51:44 -07:00
paullegranddc dac8bd5cde
test: fix span_processor test failing with default features (#2782) 2025-03-11 07:42:33 -07:00
Cijo Thomas 68c9133867
fix: Remove mut ref requirement for shutdown LogExporter (#2764)
Co-authored-by: Utkarsh Umesan Pillai <66651184+utpilla@users.noreply.github.com>
2025-03-10 14:58:15 -07:00
Cijo Thomas 9d3a5079f6
test: Add test showing Baggage and Context interation with Tracing (#2732)
Co-authored-by: Lalit Kumar Bhasin <lalit_fin@yahoo.com>
2025-03-06 05:57:25 -08:00
Scott Gerring 69c4adee46
docs: Add ADR dir and error handling ADR (#2664)
Co-authored-by: Cijo Thomas <cijo.thomas@gmail.com>
Co-authored-by: Zhongyang Wu <zhongyang.wu@outlook.com>
Co-authored-by: Cijo Thomas <cithomas@microsoft.com>
2025-03-06 05:42:05 -08:00
Pixels b33f0cc56c
fix: typo in metrics.rs (#2761)
Co-authored-by: Cijo Thomas <cijo.thomas@gmail.com>
2025-03-05 12:19:11 -08:00
Cijo Thomas 36cbe8dc1f
test: Modify perf tests to pass event name correctly to avoid string allocation (#2762) 2025-03-05 11:09:11 -08:00
Cijo Thomas f013b3d474
test: Stress test for logs modified to show throughput when enabled()… (#2760) 2025-03-05 10:31:32 -08:00
Anton Grübel a317856787
refactor: refactor Baggage with Context interaction (#2748)
Co-authored-by: Zhongyang Wu <zhongyang.wu@outlook.com>
Co-authored-by: Cijo Thomas <cijo.thomas@gmail.com>
2025-03-05 06:40:55 -08:00
Björn Antonsson baf4bfd61e
fix: Allow overlapping context scopes (#2378)
Co-authored-by: Cijo Thomas <cijo.thomas@gmail.com>
2025-03-04 17:03:45 -08:00
Cijo Thomas ff33638d1e
feat: Allow event name to be provided to IsEnabled check in Logger (#2756) 2025-03-04 15:39:58 -08:00
Cijo Thomas c5a4b7f436
doc: Update CONTRIBUTING.md with meeting notes (#2755) 2025-03-04 10:04:48 -08:00
Cijo Thomas 88cae2cf7d
test: Add test to show how to add baggage to logrecords via processor (#2738) 2025-03-03 21:40:49 -08:00
Cijo Thomas f15a3379f8
fix: Fix Logger scope in Tracing Appender (#2735) 2025-03-03 19:11:33 -08:00
Anton Grübel 5a77fb2b50
chore: enable Rust 2024 edition lints (#2728)
Co-authored-by: Lalit Kumar Bhasin <lalit_fin@yahoo.com>
Co-authored-by: Cijo Thomas <cijo.thomas@gmail.com>
2025-03-03 13:46:22 -08:00
Cijo Thomas 1ddecb04d9
perf: Nit additions to Baggage benchmarks (#2740) 2025-03-03 11:33:41 -08:00
Anton Grübel 2493fecc40
fix: align baggage.remove() implementation (#2734) 2025-03-03 11:31:25 -08:00
Cijo Thomas 46a7cd623c
perf: Add benchmarks to show the cost of attributes in Log (#2741) 2025-03-03 11:13:09 -08:00
Anton Grübel 92303b6f72
test: add benchmark tests for baggage (#2737) 2025-03-02 11:00:51 -08:00
Shunsuke Tokunaga 13fafcb0ab
test: Add Scope attributes test cases for metrics (#2736)
Signed-off-by: Shunpoco <tkngsnsk313320@gmail.com>
Co-authored-by: Cijo Thomas <cijo.thomas@gmail.com>
2025-03-02 09:41:42 -08:00
Mindaugas Vinkelis 1583e70c2f
perf: Baggage insert & BaggageExt::with_baggage & updated constants to latest standard (#2284) 2025-03-02 08:02:34 -08:00
Anton Grübel 5e47487427
fix: change value type of Baggage to StringValue (#2729)
Co-authored-by: Cijo Thomas <cijo.thomas@gmail.com>
2025-03-01 12:03:32 -08:00
dependabot[bot] 382bad420b
Bump ytanikin/pr-conventional-commits from 1.4.0 to 1.4.1 (#2733)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-03-01 12:01:46 -08:00
Anton Grübel a423ad2aa9
ci: fix rate limiting of setup-protoc in CI (#2731) 2025-02-28 12:47:02 -08:00
Anton Grübel d581ae170d
test: fix and enable doctests (#2730) 2025-02-28 12:46:30 -08:00
Cijo Thomas 91ae096206
test : Add test to confirm Context expected behavior (#2724) 2025-02-28 07:04:54 -08:00
martintmk fb74565453
feat: Refine runtime trait (#2641) 2025-02-27 10:09:43 -08:00
Cijo Thomas 367e484686
ci: Run perf tests on demand (#2722) 2025-02-26 14:00:26 -08:00
Cijo Thomas edb0d5857f
docs: Modify examples to show best practices - reuse tracer (#2709) 2025-02-26 12:08:01 -08:00
Cijo Thomas 11ed8e0af7
docs: Fix tracing grpc example (#2710) 2025-02-26 11:05:55 -08:00
Cijo Thomas 08a1f52e18
test: Try fix a flaky test (#2719) 2025-02-26 10:05:28 -08:00
Scott Gerring 4830a3cf3b
ci: comment out intermittent failing assertion (#2714) 2025-02-26 08:01:43 -08:00
Björn Antonsson f9ccdfff1c
chore: Fix small nits on benchmarks and remove throughput (#2713) 2025-02-26 07:18:48 -08:00
Scott Gerring 261ac75ab5
ci: Add criterion performance regressions to PR workflows (#2706) 2025-02-25 23:37:37 -08:00
Björn Antonsson 2bf05f6161
perf: More Context benchmarks (#2707) 2025-02-25 23:03:55 -08:00
Cijo Thomas 7954252154
test: Nit improvement to Logger test logic (#2708) 2025-02-25 15:32:44 -08:00
Mohammad Vatandoost 29eda05337
Modify batch processor test use flush instead of sleeptime (#2675)
Co-authored-by: Braden Steffaniak <BradenSteffaniak+github@gmail.com>
Co-authored-by: Cijo Thomas <cijo.thomas@gmail.com>
2025-02-25 14:43:58 -08:00
Dimitris Apostolou 81fea0747c
Avoid duplicate crates (#2703)
Co-authored-by: Cijo Thomas <cijo.thomas@gmail.com>
2025-02-25 08:07:55 -08:00
Scott Gerring bfd9f3139b
ci: add pr naming workflow (#2698) 2025-02-25 07:15:18 -08:00
Scott Gerring 59af7e2277
chore: Prevent libtest being added to bench builds (#2705) 2025-02-25 07:13:26 -08:00
Josh W Lewis 64549d741f
Fix `.with_headers` to support multiple k/v pairs (#2699)
Co-authored-by: Cijo Thomas <cijo.thomas@gmail.com>
2025-02-24 15:52:59 -08:00
Spencer Judge edab145d6a
Reduce various info logs to debug (#2700) 2025-02-24 11:28:38 -08:00
Cijo Thomas bc5e6cea61
InstrumentationScope to include attributes in hash and eq check (#2701) 2025-02-21 12:06:10 -08:00
Cijo Thomas 27d364b105
Fix: BatchLogProcessor to invoke shutdown on exporter (#2696) 2025-02-21 11:55:36 -08:00
Cijo Thomas cb81eb6873
Add Scott Gerring as an Approver (#2679)
Co-authored-by: Zhongyang Wu <zhongyang.wu@outlook.com>
2025-02-21 07:07:10 -08:00
Cijo Thomas ee76205a8a
Add few more notes to design docs for Logs (#2694) 2025-02-20 17:45:41 -08:00
Lalit Kumar Bhasin a70affd3e3
Remove `mut` self reference from SpanExporter::export() method. (#2695) 2025-02-20 17:39:03 -08:00
Cijo Thomas c072629648
Use Duration for const for delays (#2688) 2025-02-20 16:43:31 -08:00
Cijo Thomas 19dba6964e
Appender-Tracing - extend spl treatment of message when recording str (#2689)
Co-authored-by: Lalit Kumar Bhasin <lalit_fin@yahoo.com>
2025-02-20 16:10:15 -08:00
Cijo Thomas 6648d74cb2
Nit fix to changelogs (#2693) 2025-02-20 16:02:05 -08:00
Anton Grübel 5ce50ae4ed
simplify async trait impl (#2692) 2025-02-20 15:42:43 -08:00
Anton Grübel 37efb88e55
move TraceError, TraceResult and ExportError to opentelemetry-sdk (#2680)
Co-authored-by: Cijo Thomas <cijo.thomas@gmail.com>
2025-02-20 11:11:02 -08:00
martintmk f01e8f4682
Calls to `with_resource` for signal builders (Metrics, Logs, Traces) are now additive (#2677)
Co-authored-by: Lalit Kumar Bhasin <lalit_fin@yahoo.com>
Co-authored-by: Cijo Thomas <cithomas@microsoft.com>
2025-02-20 10:25:43 -08:00
Lalit Kumar Bhasin dc9a5c87d6
Span Exporter async native (#2685) 2025-02-20 00:16:48 -08:00
Anton Grübel ac69af6a0a
update rand dependency (#2681)
Co-authored-by: Cijo Thomas <cijo.thomas@gmail.com>
Co-authored-by: Lalit Kumar Bhasin <lalit_fin@yahoo.com>
2025-02-19 16:35:06 -08:00
Lalit Kumar Bhasin f4690f18b3
chore: CI fix - msrv patching for native-tls. (#2687) 2025-02-19 13:42:34 -08:00
Luc van Kampen 64868d239e
Update typo (#2686) 2025-02-19 11:32:58 -08:00
houseme 1f0e361dff
Fix typos (#2684) 2025-02-18 21:35:36 -08:00
Shunsuke Tokunaga b5c9fdc409
Fix 2638: Use absolute URL for LICENSE/CHANGELOG in README (#2682)
Signed-off-by: Shunpoco <tkngsnsk313320@gmail.com>
Co-authored-by: Cijo Thomas <cijo.thomas@gmail.com>
2025-02-18 19:00:29 -08:00
OpenTelemetry Bot 58c7644ac8
Add FOSSA scanning workflow (#2676)
Co-authored-by: otelbot <197425009+otelbot@users.noreply.github.com>
2025-02-18 14:58:21 -08:00
Anton Grübel 1b1ba899cf
use workspace lint configuration (#2674) 2025-02-17 18:18:13 -08:00
Cijo Thomas eca1ce8708
Temp fix flaky test for BatchSpanprocessors (#2671) 2025-02-15 10:26:53 -08:00
Anton Grübel a9a5cbf7a0
leverage native async trait in MetricsClient (#2672) 2025-02-15 09:50:47 -08:00
Cijo Thomas 06ca4a12f2
Nit cleanup of method signature for async export (#2669) 2025-02-14 19:31:27 -08:00
Anton Grübel bc931b151f
make force_flush() in PushMetricExporter synchronous (#2663)
Co-authored-by: Cijo Thomas <cijo.thomas@gmail.com>
Co-authored-by: Lalit Kumar Bhasin <lalit_fin@yahoo.com>
2025-02-14 16:37:29 -08:00
Cijo Thomas dbd44a3486
Fix OTel Appender for tracing from suppressing other layers (#2668) 2025-02-14 15:26:08 -08:00
Mohammad Vatandoost 41b381ae80
Chang timeout value to miliseconds (#2656)
Co-authored-by: Braden Steffaniak <BradenSteffaniak+github@gmail.com>
Co-authored-by: Cijo Thomas <cijo.thomas@gmail.com>
Co-authored-by: Lalit Kumar Bhasin <lalit_fin@yahoo.com>
2025-02-14 12:58:35 -08:00
Cijo Thomas 2997c4bb89
Show using tracing layer filters in examples (#2667) 2025-02-14 09:44:33 -08:00
tison 32a43caada
build: drop unused tonic server deps (#2666)
Signed-off-by: tison <wander4096@gmail.com>
2025-02-14 06:59:42 -08:00
Drew Relmas cd9bbcfa0d
Split SimpleLogProcessor and BatchLogProcessor out of single file (#2661) 2025-02-13 18:00:24 -08:00
Anton Grübel 00ebc98e63
leverage native async trait in PushMetricExporter (#2662) 2025-02-13 17:45:14 -08:00
Cijo Thomas ac66848ae8
Add design docs (#2657)
Co-authored-by: Lalit Kumar Bhasin <lalit_fin@yahoo.com>
2025-02-13 10:56:06 -08:00
Cijo Thomas 1aca212a72
Simplifiy OTLP Example Resource creation (#2660) 2025-02-13 10:13:11 -08:00
martintmk e68fe94500
Enable per-thread instances for histogram stress test (#2659) 2025-02-13 08:46:54 -08:00
Drew Relmas 0592075930
Update appender-tracing pprof usage with Windows exclusion (#2655) 2025-02-12 14:11:23 -08:00
Lalit Kumar Bhasin f88d930be7
chore: Prepare for opentelemetry-appender-tracing v0.28.1 (#2653) 2025-02-12 10:05:20 -08:00
Lalit Kumar Bhasin f657b5522d
chore: fix doc tests (#2652) 2025-02-12 09:33:28 -08:00
Cijo Thomas 6ea208652a
Fix link in migration guide (#2647) 2025-02-11 14:36:43 -08:00
Braden Steffaniak b3582021b0
Upgrade opentelemetry-prometheus to 0.28 (#2650) 2025-02-11 12:01:16 -08:00
Cijo Thomas f3a375cb48
Update CI for ARM to use public image (#2646) 2025-02-11 10:48:08 -08:00
Drew Relmas 2d7e7d6936
Add missing Windows exclusion for pprof crate in sdk/benches (#2648) 2025-02-11 10:35:46 -08:00
tison 5236670f8d
chore: fix CHANGELOG.md (#2642) 2025-02-11 07:03:05 -08:00
Cijo Thomas de197e4011
Fix zipkin deadlink (#2640) 2025-02-10 12:26:29 -08:00
Lalit Kumar Bhasin 189078d7a9
Bump otel-appender-tracing version to 0.28 (#2637) 2025-02-10 10:18:49 -08:00
Lalit Kumar Bhasin 062c9d6589
Prepare v0.28.0 (#2635) 2025-02-10 09:52:55 -08:00
Cijo Thomas b6783a1098
Changelog refactoring (#2632) 2025-02-07 15:25:55 -08:00
Cijo Thomas c56a03ebbc
Separate logger and loggerprovider mod (#2633) 2025-02-07 11:53:55 -08:00
Tom Tan 34742d02dc
Set pwd for precommit.sh script to support running it in any directory (#2535)
Co-authored-by: Cijo Thomas <cijo.thomas@gmail.com>
Co-authored-by: Lalit Kumar Bhasin <lalit_fin@yahoo.com>
2025-02-07 11:32:25 -08:00
Cijo Thomas eeb367d933
Nit fixes to doc and tests (#2626) 2025-02-06 22:05:43 -08:00
Cijo Thomas c2a2b8dd9b
Fix stress test for Logs to use OTelSdkResult (#2627) 2025-02-06 20:43:02 -08:00
Cijo Thomas 3a8ceddd5e
Rearrange trace integration tests (#2628) 2025-02-06 20:16:06 -08:00
Cijo Thomas 1fc86da1c6
0.28 migration guide and OTLP Example fixes (#2622) 2025-02-06 19:11:38 -08:00
Anton Grübel 61e539f491
leverage tracer provider to set service name for Zipkin exporter (#2624)
Co-authored-by: Cijo Thomas <cijo.thomas@gmail.com>
2025-02-06 17:12:11 -08:00
Lalit Kumar Bhasin 420416f2bf
Logs SDK - use OTelSdkError, OTelSdkResult (#2625) 2025-02-06 16:33:35 -08:00
Cijo Thomas 41464d1c1a
Readme updates in prep for release (#2623) 2025-02-06 12:48:05 -08:00
Cijo Thomas 69e7e89b47
Remove ExportResult and TraceError as no longer required/used (#2620) 2025-02-05 14:35:43 -08:00
Mindaugas Vinkelis d79950da59
ObservableGauge collect data points since previous collection (#2618)
Co-authored-by: Cijo Thomas <cijo.thomas@gmail.com>
2025-02-05 13:53:44 -08:00
Cijo Thomas ad3830383f
Add conditional compilation to avoid build warnings (#2619) 2025-02-05 13:01:24 -08:00
Cijo Thomas 1fbaaf2ac3
Rename LogRecord to SdkLogRecord (#2617) 2025-02-05 12:02:23 -08:00
Lalit Kumar Bhasin 5f7f2d5b7f
Remove export timeout configuration for PeriodicReader (#2598) 2025-02-05 11:52:47 -08:00
Cijo Thomas 15b5fa4e20
Move traceid spanid traceflags to common (#2609) 2025-02-05 11:07:56 -08:00
Cijo Thomas dfeeac7a7d
Rename TracerProvider to SdkTracerProvider (#2614)
Co-authored-by: Lalit Kumar Bhasin <lalit_fin@yahoo.com>
2025-02-05 11:01:29 -08:00
Lalit Kumar Bhasin d01c1137cf
Trace subsystem - use OTelSdkResult/OTelSdkError (#2613) 2025-02-05 10:20:34 -08:00
Adrian Garcia Badaracco 0e751b4a2b
json: ser/de bytes as base64 strings not an array of bytes (#2471)
Co-authored-by: Cijo Thomas <cijo.thomas@gmail.com>
2025-02-05 09:09:34 -08:00
anujnegi270 775f1f9a3e
Disabling the Instrument Name Validation under a new feature flag (#2543)
Co-authored-by: Cijo Thomas <cijo.thomas@gmail.com>
Co-authored-by: Lalit Kumar Bhasin <lalit_fin@yahoo.com>
2025-02-05 08:08:18 -08:00
Cijo Thomas fdc1151251
Rename LoggerProvider, Logger to SdkLoggerProvider, SdkLogger (#2612) 2025-02-05 07:37:45 -08:00
Lalit Kumar Bhasin 5bebbcc6d7
Refine error messages for OTelSdkError variants (#2608)
Co-authored-by: Cijo Thomas <cijo.thomas@gmail.com>
2025-02-04 16:05:57 -08:00
Mohammad Vatandoost d481be5a4f
Use opentelemetry:time::now instead of systemtime (final part) (#2607)
Co-authored-by: Cijo Thomas <cijo.thomas@gmail.com>
2025-02-04 15:57:48 -08:00
Cijo Thomas 4a76c96344
Use OTelSdkResult for metric flush (#2606) 2025-02-04 15:49:47 -08:00
Cijo Thomas 4783b64467
Assert explicitly that shutdown succeeded in Integration tests (#2605) 2025-02-04 13:33:33 -08:00
Cijo Thomas 4cdc64fc77
Metric export to use common OTelSdkResult (#2604) 2025-02-04 13:08:09 -08:00
Lalit Kumar Bhasin f5b44a54ea
Shutdown in separate thread for Logs integration tests in current_thread mode. (#2601) 2025-02-04 12:19:54 -08:00
Cijo Thomas 6bdb4c69b6
Make a common Error enum for export shutdown and flush operations (#2603) 2025-02-04 12:00:57 -08:00
Cijo Thomas b017c7b9c4
Fix PeriodicReader panic due to timeout (#2586)
Co-authored-by: Lalit Kumar Bhasin <lalit_fin@yahoo.com>
2025-02-03 15:42:25 -08:00
Cijo Thomas 5e6b3d622e
Add easier way to add periodicreader to meterprovider (#2597) 2025-02-03 13:50:23 -08:00
Cijo Thomas 013d51af6e
Doc additions to warn about tokio current (#2594)
Co-authored-by: Lalit Kumar Bhasin <lalit_fin@yahoo.com>
2025-02-03 13:35:53 -08:00
Lalit Kumar Bhasin 7ca4a85a24
Remove export timeout configuration for BatchSpanProcessor (#2596)
Co-authored-by: Cijo Thomas <cijo.thomas@gmail.com>
2025-02-03 13:01:46 -08:00
Mohammad Vatandoost 6c88d31aa2
Use opentelemetry:time::now instead of systemtime (#2595) 2025-02-03 12:35:25 -08:00
Lalit Kumar Bhasin a81ad249ec
Enable reqwest and reqwest-blocking client creation with custom timeout (#2584)
Co-authored-by: Cijo Thomas <cijo.thomas@gmail.com>
2025-02-03 11:17:01 -08:00
Lalit Kumar Bhasin 7c9447ff6c
Remove export timeout configuration for BatchLogProcessor. (#2587)
Co-authored-by: Cijo Thomas <cijo.thomas@gmail.com>
2025-02-03 10:22:41 -08:00
Cijo Thomas dde68a073c
Nit fix to log message on LogProcessor (#2590)
Co-authored-by: Lalit Kumar Bhasin <lalit_fin@yahoo.com>
2025-02-03 09:47:39 -08:00
Cijo Thomas aece6419eb
Few fixes to PeriodicReader tests (#2589) 2025-02-03 09:38:02 -08:00
Cijo Thomas 3fc8485067
Add more metric integration tests (#2582) 2025-02-03 06:54:29 -08:00
Shunsuke Tokunaga 8c5daa2557
Version up sample code/Cargo.toml on README.md (#2585)
Signed-off-by: Shunpoco <tkngsnsk313320@gmail.com>
2025-02-02 09:41:23 -08:00
Cijo Thomas a1860eb7a8
Better handling of shutdown in BatchLogProcessor (#2581) 2025-01-31 11:36:25 -08:00
Cijo Thomas 9dfcff1f55
Use dedicated ShutdownResult for Metric SDK shutdown (#2573) 2025-01-31 10:20:22 -08:00
Cijo Thomas b50da912b4
Remove unwanted Arc insider PeriodicReader (#2579) 2025-01-31 09:59:38 -08:00
Cijo Thomas 732b938e59
Removed unnecessary public methods from OTLP Exporter (#2575) 2025-01-30 10:01:31 -08:00
Yury Yarashevich 85206105f8
Use bytes::Bytes as the HTTP request body in HttpClient. (#2485)
Co-authored-by: Zhongyang Wu <zhongyang.wu@outlook.com>
Co-authored-by: Cijo Thomas <cijo.thomas@gmail.com>
Co-authored-by: Lalit Kumar Bhasin <lalit_fin@yahoo.com>
2025-01-29 08:41:22 -08:00
Anton Grübel 17cce839c3
feat: Replace Zipkin pipeline with exporter builders (#2565)
Co-authored-by: Cijo Thomas <cijo.thomas@gmail.com>
2025-01-28 21:57:48 -08:00
Cijo Thomas 144fdd961c
Print histogram bucket info in stdout exporter (#2569) 2025-01-28 12:09:20 -08:00
Lalit Kumar Bhasin 45f4d7c24a
chore: bump semantic convention 1.30.0 (#2572) 2025-01-28 11:40:17 -08:00
Cijo Thomas 3ec4c186ad
Nit doc update for OTLP Exporter (#2567) 2025-01-27 12:59:29 -08:00
David Pitoniak 6fa9ae2f09
doc(resource): update docs to be accurate with current behavior (#2568) 2025-01-27 09:23:51 -08:00
Dylan Thacker-Smith 18834f53af
appender-tracing: Include trace ID and span ID in logs when nested in tracing crate's spans (#2438)
Co-authored-by: Zhongyang Wu <zhongyang.wu@outlook.com>
Co-authored-by: Lalit Kumar Bhasin <lalit_fin@yahoo.com>
Co-authored-by: Cijo Thomas <cijo.thomas@gmail.com>
Co-authored-by: Cijo Thomas <cithomas@microsoft.com>
2025-01-25 12:00:15 -08:00
Cijo Thomas b3879b6781
Minor fixes, stdout to print scope info for logs (#2563) 2025-01-24 18:46:10 -08:00
Cijo Thomas 879f4d7964
Rename provider builders (#2562) 2025-01-24 16:40:50 -08:00
Cijo Thomas bd0ee846e5
Rename log emitter to provider (#2559) 2025-01-24 11:30:05 -08:00
Cijo Thomas a1ac8065c5
Use opentelemetry:time::now instead of systemtime in LogEmitter (#2558) 2025-01-24 10:58:00 -08:00
Cijo Thomas b2d3d74962
Remove unsupported feature from BatchSpanProcessor (#2556) 2025-01-24 09:46:31 -08:00
Cijo Thomas 14faca3fbe
Resource.get modified to only need a reference (#2552) 2025-01-24 09:27:30 -08:00
Cijo Thomas 4f472a8c67
Run integration tests on all PRs (#2554) 2025-01-24 08:35:49 -08:00
Cijo Thomas de2b25ee89
Update pprof version (#2553) 2025-01-24 08:20:14 -08:00
Lalit Kumar Bhasin 8a4e5ca419
Restrict LogRecord creation access outside opentelemetry_sdk crate. (#2549) 2025-01-24 07:08:49 -08:00
Cijo Thomas 6a8db83871
Move Metric inmemory exporter (#2548) 2025-01-23 21:39:47 -08:00
Cijo Thomas 6a13678421
Move inmemory exporter for spans to diff namespace (#2544) 2025-01-23 18:44:14 -08:00
Cijo Thomas 97cf951396
Cleanup unused Error struct - PropagationError (#2547) 2025-01-23 18:33:01 -08:00
Lalit Kumar Bhasin 4c77c89999
More integration tests added (#2545)
Co-authored-by: Cijo Thomas <cijo.thomas@gmail.com>
2025-01-23 18:04:37 -08:00
Cijo Thomas 95fa209669
Remove unused Error enum (#2546) 2025-01-23 17:47:24 -08:00
Cijo Thomas fdf4a63a5b
Move inmemory exporter for logs to diff namespace (#2538) 2025-01-23 11:44:00 -08:00
Cijo Thomas 5935ccac93
Move span exporter module (#2540) 2025-01-23 11:34:10 -08:00
Utkarsh Umesan Pillai a0e50615cd
Update documentation for Metrics API (#2280)
Co-authored-by: Cijo Thomas <cijo.thomas@gmail.com>
Co-authored-by: Zhongyang Wu <zhongyang.wu@outlook.com>
2025-01-23 11:24:42 -08:00
Lalit Kumar Bhasin 927a08c902
Enable hyper client tests for SimpleLogProcessor integration tests (#2541) 2025-01-22 18:47:38 -08:00
Cijo Thomas 38be4d98f4
Nit leftovers from previous PR (#2537) 2025-01-22 17:37:00 -08:00
Cijo Thomas 3042aa0cac
Simplify metric::data imports (#2536) 2025-01-22 17:23:10 -08:00
Cijo Thomas 57d129734c
Refactor LogExporter mod (#2534) 2025-01-22 16:50:18 -08:00
Tom Tan b1debf0797
Short circuit the event_enabled check (#2533) 2025-01-22 15:10:02 -08:00
Cijo Thomas acaa98d814
Doc additions for Simple and Batch processors (#2529)
Co-authored-by: Lalit Kumar Bhasin <lalit_fin@yahoo.com>
2025-01-22 10:15:42 -08:00
Cijo Thomas 90b0dd46c8
Remove cardinality capping in Metrics (#2528) 2025-01-21 17:38:46 -08:00
Lalit Kumar Bhasin d2a6b3b2fc
BatchSpanProcessor optimizations - Separate control signal queue, and wake up background thread only when required. (#2526)
Co-authored-by: Cijo Thomas <cijo.thomas@gmail.com>
2025-01-21 15:00:40 -08:00
Lalit Kumar Bhasin 78db32c58d
Add the full log validation test in Integration test (#2525) 2025-01-21 14:33:20 -08:00
Cijo Thomas 68af3bb038
Add reqwest client to integration test (#2523) 2025-01-16 19:23:59 -08:00
Cijo Thomas dace0ca7fa
Add simple processor to integration test (#2522) 2025-01-16 17:18:34 -08:00
Cijo Thomas 27410b0031
Integration test for non tokio main (#2520) 2025-01-16 16:07:25 -08:00
Lalit Kumar Bhasin c51c4b2c71
Add runtime traits under experimental flag. (#2519) 2025-01-15 17:18:08 -08:00
William Perron a719d0d1a6
Allow values containing '=' in OTEL_RESOURCE_ATTRIBUTES (#2120)
Values passed in to OTEL_RESOURCE_ATTRIBUTES containing an equal sign "=" are currently ignored by the Resource constructor, but should be accepted as it is part of the W3C Baggage octet
range.
2025-01-16 00:22:53 +01:00
Cijo Thomas b53c19e2e6
Few fixes to OTLP Exporter Examples (#2518) 2025-01-15 12:41:41 -08:00
Cijo Thomas 1904d4b8eb
Remove redundant shutdown check in batchlogprocessor (#2514) 2025-01-15 10:39:34 -08:00
Cijo Thomas 9aea82698a
OTLPExporter - change to http as default feature flag (#2516) 2025-01-15 09:52:30 -08:00
Cijo Thomas f46bccceab
PeriodicReader shutdown modified to enforce timeout (#2513) 2025-01-14 20:21:53 -08:00
Utkarsh Umesan Pillai 5aa9120f1e
Fix BatchLogProcessor (#2510) 2025-01-14 13:53:35 -08:00
Utkarsh Umesan Pillai 888d5a34ad
Refactor BatchLogProcessor (#2494)
Co-authored-by: Lalit Kumar Bhasin <lalit_fin@yahoo.com>
Co-authored-by: Cijo Thomas <cijo.thomas@gmail.com>
2025-01-14 03:31:39 -08:00
Utkarsh Umesan Pillai 73859c3bd7
Add internal-logs feature to opentelemetry-proto (#2507) 2025-01-13 18:01:25 -08:00
Utkarsh Umesan Pillai 6cc327d555
Update metrics benchmarks (#2502) 2025-01-09 11:42:56 -08:00
Utkarsh Umesan Pillai e05979d6d7
Update the link to Meeting Notes doc (#2501) 2025-01-07 22:57:07 -08:00
Joe Burnard a1dda220de
OTLP documentation: Fix typo where webkpi is used instead of webpki (#2498) 2025-01-07 07:58:36 -08:00
Mindaugas Vinkelis 82ed8e05f4
Sepatate Aggregate measure and collect functions (#2492) 2025-01-04 16:40:33 -08:00
Lalit Kumar Bhasin 37d2e51c23
chore: disable failing integration tests (#2495)
Co-authored-by: Utkarsh Umesan Pillai <66651184+utpilla@users.noreply.github.com>
2025-01-04 02:02:28 +05:30
Utkarsh Umesan Pillai 42b4f2fbd8
Minor refactoring- Rename the variants of LogBatchData enum (#2490) 2025-01-01 06:14:37 -08:00
Takahiro Ebato 17855be169
Retain empty tracer name as is instead of using default name (#2486)
Co-authored-by: Cijo Thomas <cijo.thomas@gmail.com>
2024-12-31 07:53:33 +00:00
Utkarsh Umesan Pillai 56e7fae000
Avoid vec allocation during each export for BatchLogProcessor - Part 2 (#2488) 2024-12-31 07:46:06 +00:00
Utkarsh Umesan Pillai 9a8ad95ee8
Avoid vec allocation during each export for BatchLogProcessor (#2483)
Co-authored-by: Cijo Thomas <cijo.thomas@gmail.com>
2024-12-27 17:56:14 -08:00
Utkarsh Umesan Pillai f3b5fd3af2
Minor refactoring (#2484) 2024-12-27 17:48:11 -08:00
Cijo Thomas d52fec7939
Minor cleanup in Stdout exporter (#2481) 2024-12-27 12:21:03 -08:00
Cijo Thomas 8fde6eb3b2
Remove unnecessary featureflag for eventname (#2480) 2024-12-27 10:45:39 -08:00
Cijo Thomas e378bc8776
Fix PeriodicReader shutdown to invoke shutdown on exporter (#2477) 2024-12-26 14:55:07 -08:00
Cijo Thomas 36f9caf45e
Fix changelog and few spell check issues (#2474)
Co-authored-by: Zhongyang Wu <zhongyang.wu@outlook.com>
2024-12-26 11:56:36 -08:00
Lalit Kumar Bhasin 5b86b7fd2c
Add doc-comment for SimpleLogProcessor and BatchLogProcessor (#2468) 2024-12-24 09:33:19 -08:00
Cijo Thomas 6e1032f9af
Nit fix to LogProcessor tests (#2467) 2024-12-24 05:23:32 -08:00
Cijo Thomas 8d5f2226df
Nit improvements to batchprocessors (#2466) 2024-12-23 17:17:37 -08:00
Cijo Thomas ef49833f4d
Minor followups to LogProcessor (#2464) 2024-12-23 12:46:53 -08:00
Lalit Kumar Bhasin 1f354674d6
BatchSpanProcessor with dedicated thread. (#2456) 2024-12-23 11:15:48 -08:00
Cijo Thomas 6209c06db5
Move BatchLogProcessor with runtime to separate module (#2463) 2024-12-20 22:14:39 -08:00
Lalit Kumar Bhasin 23f6ae2992
Use native Rust support for async traits in LogExporter::export() method (11% improvement) (#2374)
Co-authored-by: Cijo Thomas <cijo.thomas@gmail.com>
Co-authored-by: Zhongyang Wu <zhongyang.wu@outlook.com>
2024-12-20 08:03:49 -08:00
Cijo Thomas 80629c8161
Minor update to stdout exporter example to show log correlation (#2459) 2024-12-19 20:50:27 -08:00
Cijo Thomas 3694ff9fe7
Modify OTLP Http example to use reqwest blocking (#2460) 2024-12-19 20:27:57 -08:00
Cijo Thomas f911ed5d7b
Cleanup leftover feature flag (#2458) 2024-12-19 10:38:38 -08:00
Lalit Kumar Bhasin c617be7449
chore: bring back BatchLogProcessorWithAsyncRuntime unit tests (#2457) 2024-12-19 09:27:42 -08:00
Scott Gerring 0fc0764ffd
chore: Test sync exporters (#2455) 2024-12-19 07:47:23 -08:00
Cijo Thomas acf16ed451
Tweaks to logs integration test (#2453) 2024-12-18 18:33:15 -08:00
Cijo Thomas 0a7ad690fc
Add internal logging to HTTP libraries (#2452) 2024-12-18 18:21:06 -08:00
Tom Tan 938893c526
Handle batch log processing in a dedicated background thread (#2436) 2024-12-18 16:12:02 -08:00
Mindaugas Vinkelis 06053411bd
Directly implement Measure trait for metric aggregates (#2371)
Co-authored-by: Cijo Thomas <cijo.thomas@gmail.com>
2024-12-18 10:52:38 -08:00
Cijo Thomas fbcba3b003
Enable metric integration test for req-blocking (#2445) 2024-12-18 06:28:32 -08:00
Cijo Thomas 9011f63ff6
Nit spelling fixes (#2443) 2024-12-17 18:00:31 -08:00
Mindaugas Vinkelis b9a422b39e
Directly implement ComputeAggregation (#2425)
Co-authored-by: Cijo Thomas <cijo.thomas@gmail.com>
Co-authored-by: Cijo Thomas <cithomas@microsoft.com>
2024-12-17 17:36:29 -08:00
Lalit Kumar Bhasin 551760b220
chore: publish otel-proto v1.5.0 (#2439)
Co-authored-by: Cijo Thomas <cijo.thomas@gmail.com>
2024-12-17 08:43:25 -08:00
Cijo Thomas 6a3b04dc0b
Add observable instruments to periodicreader tests (#2428) 2024-12-17 08:15:33 -08:00
Lalit Kumar Bhasin 4e5255401f
chore: cleanup unused dependencies (#2440)
Co-authored-by: Cijo Thomas <cijo.thomas@gmail.com>
2024-12-17 07:26:31 -08:00
Scott Gerring 9173ddf93f
chore: refactor integration tests and add metrics coverage (#2432)
Co-authored-by: Cijo Thomas <cijo.thomas@gmail.com>
2024-12-17 07:08:31 -08:00
David Pitoniak eb8d7c69ce
otlp: spawn thread to create blocking reqwest client (#2431)
Co-authored-by: Lalit Kumar Bhasin <lalit_fin@yahoo.com>
2024-12-17 06:59:02 -08:00
Cijo Thomas 9cf7a40b21
Add a minor log to help debug when Meter is obtained from noops (#2435) 2024-12-16 17:16:43 -08:00
Cijo Thomas 967dc93055
Move shutdown checks to MeterProvider (#2433) 2024-12-16 07:51:09 -08:00
Lalit Kumar Bhasin c726c4d97a
Version pinning for tracing and tracing-core (#2418)
Co-authored-by: Cijo Thomas <cijo.thomas@gmail.com>
2024-12-15 22:28:53 +05:30
Lalit Kumar Bhasin fbc3c70c27
Make LogRecord fields private and add getters for encapsulation (#2314) 2024-12-15 20:28:55 +05:30
David Pitoniak b8380ebfa4
resource: remove vec allocations for attributes (#2429) 2024-12-13 17:15:21 -08:00
Mindaugas Vinkelis d2e179eb5d
Aggregate time initiator (#2423)
Co-authored-by: Cijo Thomas <cijo.thomas@gmail.com>
2024-12-13 12:33:59 -08:00
David Pitoniak 9aeae0f03f
Feat/add resource builder (#2322)
Co-authored-by: Lalit Kumar Bhasin <lalit_fin@yahoo.com>
2024-12-13 12:16:03 -08:00
Cijo Thomas 15d69b1840
Improve shutdown handling in PeriodicReader (#2422) 2024-12-13 07:56:19 -08:00
Cijo Thomas 9b0ccce04e
Small improvements to PeriodicReader (#2421)
Co-authored-by: Lalit Kumar Bhasin <lalit_fin@yahoo.com>
2024-12-13 05:44:26 -08:00
Lalit Kumar Bhasin ce550e36bb
bump MSRV to 1.75.0 for all crates (#2417) 2024-12-12 21:12:41 -08:00
Mindaugas Vinkelis dcaff0d7c1
Update CHANGELOGs for time changes in metrics aggregations (#2412)
Co-authored-by: Cijo Thomas <cijo.thomas@gmail.com>
Co-authored-by: Cijo Thomas <cithomas@microsoft.com>
2024-12-12 09:00:54 -08:00
Björn Antonsson d0ef36510f
Include SpanContext information in Context Debug (#2365)
Co-authored-by: Cijo Thomas <cijo.thomas@gmail.com>
2024-12-11 20:03:40 -08:00
Cijo Thomas 1da35a99a2
Enable Feature in otlp http example (#2416) 2024-12-11 17:40:58 -08:00
Lalit Kumar Bhasin e8a28788b9
fix: missing thiserror crate when building with --no-default-features (#2413)
Co-authored-by: Utkarsh Umesan Pillai <66651184+utpilla@users.noreply.github.com>
Co-authored-by: Cijo Thomas <cijo.thomas@gmail.com>
2024-12-11 09:32:34 -08:00
Utkarsh Umesan Pillai f9581f545f
Add internal logging for OTLP Exporter tonic client (#2415) 2024-12-11 09:05:26 -08:00
Mindaugas Vinkelis e4cba9457e
Move time from DataPoint to Histogram/ExpoHistogram (#2411) 2024-12-11 07:27:43 -08:00
Cijo Thomas 1a4e931fe5
Minor fixes to PeriodicReader and examples (#2409) 2024-12-10 20:13:46 -08:00
Cijo Thomas 238a8f2a74
Make PeriodicReader with own Thread the default (#2403) 2024-12-10 16:08:00 -08:00
Mindaugas Vinkelis d67d1fc558
Move time from DataPoint to Sum/Gauge (#2377) 2024-12-10 13:14:58 -08:00
David Pitoniak f513768305
test: use rstest for table testing sdk resource (#2407)
Co-authored-by: Cijo Thomas <cijo.thomas@gmail.com>
2024-12-10 12:16:48 -08:00
Cijo Thomas 540cdb3613
Remove self diagnostics example (#2404) 2024-12-10 11:53:13 -08:00
Dirkjan Ochtman 257377315d
Upgrade to thiserror 2 (#2406)
Co-authored-by: Cijo Thomas <cijo.thomas@gmail.com>
2024-12-10 07:53:08 -08:00
Dirkjan Ochtman e8ccb01676
sdk: set correct span limit in builder (#2405) 2024-12-10 07:36:29 -08:00
Mindaugas Vinkelis 902baa9161
Gauge start-time is optional (#2389)
Co-authored-by: Cijo Thomas <cijo.thomas@gmail.com>
2024-12-09 15:20:31 -08:00
Lalit Kumar Bhasin de3ea4ee97
Remov deprecated LogData structure (#2398) 2024-12-09 18:33:31 +00:00
Cijo Thomas a16fac6ca6
OTLP Example fixes (#2394) 2024-12-09 10:19:05 -08:00
Cijo Thomas 2030f8f77f
Modify logs basic example to use tracing (#2397)
Co-authored-by: Lalit Kumar Bhasin <lalit_fin@yahoo.com>
2024-12-09 09:38:48 -08:00
Lalit Kumar Bhasin 3df15a1b59
chore: Update semantic conventions v1.29.0, weaver v0.11.0 (#2395) 2024-12-08 11:02:31 -08:00
Lalit Kumar Bhasin b417e848dd
Remove Deprecated Logger Method (#2396) 2024-12-08 06:45:43 -08:00
Karol Fuksiewicz 01561465cb
feat: update otel versions for prometheus to 0.27 (#2309)
Co-authored-by: Lalit Kumar Bhasin <lalit_fin@yahoo.com>
Co-authored-by: Cijo Thomas <cijo.thomas@gmail.com>
Co-authored-by: ttys3 <ttys3.rust@gmail.com>
2024-12-05 16:12:33 -08:00
Lalit Kumar Bhasin 96b7acc73d
Remove `mut` self reference from LogExporter::export() method. (#2380) 2024-12-05 13:36:08 -08:00
Lalit Kumar Bhasin 957659fac9
chore: ARM64 CI fix. (#2382) 2024-12-04 09:48:31 -08:00
David Pitoniak 6d1a765c41
chore: remove the global::shutdown_tracer_provider function (#2369) 2024-12-04 06:03:46 -08:00
David Pitoniak b35c0d6b99
Feat/remove timeout from detectors (#2332) 2024-12-03 21:09:16 -08:00
Utkarsh Umesan Pillai 506a4f9fb2
[Metrics] Remove unnecessary box (#2376)
Co-authored-by: Cijo Thomas <cijo.thomas@gmail.com>
2024-12-02 20:01:35 -08:00
Utkarsh Umesan Pillai c73c938c4a
Fix CI (#2375) 2024-12-02 19:27:37 -08:00
Lalit Kumar Bhasin c225c82784
Add OTLP integration test for hyper and request client for logs and traces (#2312)
Co-authored-by: Zhongyang Wu <zhongyang.wu@outlook.com>
Co-authored-by: Cijo Thomas <cijo.thomas@gmail.com>
2024-12-02 15:47:57 -08:00
Mindaugas Vinkelis 5b6e9b952f
Time is not optional in DataPoints (#2367)
Co-authored-by: Cijo Thomas <cijo.thomas@gmail.com>
2024-12-02 12:15:56 -08:00
Cijo Thomas 6b71301b99
Use static dispatch in SimpleLogProcessor (#2338)
Co-authored-by: Lalit Kumar Bhasin <lalit_fin@yahoo.com>
2024-12-02 10:01:08 -08:00
Lalit Kumar Bhasin a3c469b1a6
Fix CI lint error from new stable toolchain v1.83 (#2370) 2024-12-02 08:20:55 -08:00
Cijo Thomas e0159ad91f
Bump version of sdk release 0.27.1 (#2362) 2024-11-27 12:05:00 -08:00
Cijo Thomas b7276d824e
Minor Internal logs (#2361) 2024-11-27 11:45:03 -08:00
Scott Gerring cbe9ebe91e
Track dropped spans and logs due to full buffer (#2357)
Co-authored-by: Cijo Thomas <cithomas@microsoft.com>
Co-authored-by: Utkarsh Umesan Pillai <66651184+utpilla@users.noreply.github.com>
Co-authored-by: Cijo Thomas <cijo.thomas@gmail.com>
2024-11-27 10:24:06 -08:00
Cijo Thomas 195dea8070
Few doc updates for opentelemetry (#2353) 2024-11-27 10:04:27 -08:00
Cijo Thomas ab332b06c9
Let CI check for stable run even if beta run fails (#2360) 2024-11-27 09:56:47 -08:00
Cijo Thomas 53e892a2ca
Nit fix by avoiding bound validation unless View feature is enabled (#2355) 2024-11-26 17:55:06 -08:00
Cijo Thomas 0e221c1d43
Bugfix - add validation for custom buckets provided for Histograms (#2351)
Co-authored-by: Utkarsh Umesan Pillai <66651184+utpilla@users.noreply.github.com>
2024-11-26 17:30:29 -08:00
Lalit Kumar Bhasin fa6e6cd289
Replace once_cell::Lazy with std::sync::OnceLock for global Initialization in otel-sdk crate (#2342) 2024-11-26 17:09:04 -08:00
Utkarsh Umesan Pillai 8e6b479684
Avoid additional HashMap allocation for Cumulative aggregation (#2352) 2024-11-26 16:00:51 -08:00
Cijo Thomas 1cecaeabf4
Add few internal logs for Metrics sdks (#2350) 2024-11-26 14:05:26 -08:00
Lalit Kumar Bhasin 91370d23cf
Deprecate logger::provider() and logger::instrumentation_scope() (#2349)
Co-authored-by: Cijo Thomas <cithomas@microsoft.com>
2024-11-26 13:04:18 -08:00
Cijo Thomas c9388e4753
Preallocate and keep memory for HashMap in Metric aggregation (#2343) 2024-11-26 10:25:12 -08:00
Cijo Thomas 3a4d12af9a
Minor fix to main readme (#2348) 2024-11-26 10:15:49 -08:00
Björn Antonsson 9a85ce1c0c
Remove non-default feature from doc test (#2346) 2024-11-26 07:22:15 -08:00
Lalit Kumar Bhasin 1541a330e2
attempt to fix stress test CI by pinning libc (#2344) 2024-11-25 19:20:32 -08:00
Lalit Kumar Bhasin 1119549b0d
Remove async-trait crate as dependency for traces (#2339) 2024-11-25 12:24:15 -08:00
Cijo Thomas e6c351f2d7
More consistent readme for msrv (#2336)
Co-authored-by: Lalit Kumar Bhasin <lalit_fin@yahoo.com>
2024-11-25 10:40:27 -08:00
David Pitoniak 129ca03128
feat: add concurrency options to ci workflow (#2337) 2024-11-24 17:38:29 -08:00
Cijo Thomas dd982e3501
InternalLog fixes for GlobalMeterProvider (#2333) 2024-11-24 12:35:48 -08:00
Lalit Kumar Bhasin a6e2cd6e91
Remove default logger name (#2316)
Co-authored-by: Cijo Thomas <cithomas@microsoft.com>
Co-authored-by: Cijo Thomas <cijo.thomas@gmail.com>
2024-11-24 11:39:18 -08:00
Cijo Thomas 882e1c2d25
Empty MeterName retained as is instead of using default name (#2334) 2024-11-24 10:33:03 -08:00
Cijo Thomas 5de2caf5de
Emit internal log for global meter provider (#2331) 2024-11-23 18:37:01 -08:00
Cijo Thomas 8c9babbda8
Minor additions to internal logs (#2330) 2024-11-23 12:52:32 -08:00
Lalit Kumar Bhasin ebeeea1724
Replace `once_cell::Lazy` with `std::sync::OnceLock` for global Initialization in OpenTelemetry API crate (#2326)
Co-authored-by: Cijo Thomas <cijo.thomas@gmail.com>
2024-11-23 12:22:53 -08:00
Lalit Kumar Bhasin 3d352d870a
[Logs SDK] Deprecate LogData struct (#2325)
Co-authored-by: Cijo Thomas <cijo.thomas@gmail.com>
2024-11-22 18:42:22 -08:00
Lalit Kumar Bhasin 2ba2e7fffe
[CI fix] msrv patch for rustls (#2327) 2024-11-22 17:05:54 -08:00
Lalit Kumar Bhasin 6ca7881f7c
CI fix: patch msrv for rustls-native-certs (#2318) 2024-11-22 13:43:41 -08:00
Cijo Thomas 465fcc2eda
AttributeSet cleanup, better perf for overflows (#2313) 2024-11-20 19:41:40 -08:00
Lalit Kumar Bhasin af9d925736
chore: update proto definition to v1.4.0 (#2315) 2024-11-20 17:33:37 -08:00
Cijo Thomas ca6c67e752
Remove building examples twice (#2311) 2024-11-20 11:27:48 -08:00
Mindaugas Vinkelis 3b652aca29
Use ValueMap in ExpoHistogram (#2282)
Co-authored-by: Cijo Thomas <cijo.thomas@gmail.com>
2024-11-20 11:13:24 -08:00
Cijo Thomas cd54f24224
Update benchmark results for metrics (#2307) 2024-11-20 10:36:09 -08:00
Cijo Thomas a4f602b4cb
Doc CI to use stable rust (#2310) 2024-11-20 10:25:09 -08:00
David Pitoniak 849778d524
Refactor/deprecate trace config (#2303) 2024-11-18 18:11:46 -08:00
Utkarsh Umesan Pillai 41afd7f916
Make stress tests independent of batch size (#2306) 2024-11-18 10:53:52 -08:00
Raphael Deem 3ac2d9fb64
cleanup imports in examples (#2300) 2024-11-14 07:49:32 -08:00
Lalit Kumar Bhasin 45ed2e061a
Publish otel-appender-log : add version to semconv (#2299) 2024-11-11 17:43:34 -08:00
Lalit Kumar Bhasin ade08cb1a3
Prepare for v0.27.0 - update Metrics API and Log(bridge) API to RC, Metrics SDK & OTLP Exporter to Beta. (#2290) 2024-11-11 16:18:20 -08:00
Utkarsh Umesan Pillai 648710edf1
Move Views under feature flag (#2298) 2024-11-11 16:05:00 -08:00
Cijo Thomas 47d501670e
Add PeriodicReaderWithOwnThread (#2292) 2024-11-11 15:29:07 -08:00
Lalit Kumar Bhasin b83311845d
Rename `logs_level_enabled` flag to `spec_unstable_logs_enabled` (#2291) 2024-11-11 12:39:20 -08:00
Lalit Kumar Bhasin 0cc2cd571f
Add usage doc comment for AnyValue type (#2293)
Co-authored-by: Cijo Thomas <cithomas@microsoft.com>
2024-11-08 15:57:21 -08:00
Cijo Thomas 845cf21e51
Move Temporality enum opentelemetry_sdk::metrics::data:: to opentelemetry_sdk::metrics:: (#2289)
Co-authored-by: Utkarsh Umesan Pillai <66651184+utpilla@users.noreply.github.com>
2024-11-08 13:49:26 -08:00
Utkarsh Umesan Pillai a707bb938b
Update code documentation for Metric instruments (#2281) 2024-11-07 21:46:48 -08:00
Mindaugas Vinkelis c322a50d3e
Histogram implementation cleanup (#2283) 2024-11-07 14:12:30 -08:00
Cijo Thomas 540c6f17fc
Few fixes to changelog for breaking changes (#2287) 2024-11-07 12:05:28 -08:00
Mindaugas Vinkelis 52f6d9214e
Remove Counter/Add benchmark for delta temporality (#2285) 2024-11-07 09:40:03 -08:00
Lalit Kumar Bhasin ebf1bb6eba
Move Logs and Metrics error constructs to SDK (#2266)
Co-authored-by: Cijo Thomas <cijo.thomas@gmail.com>
2024-11-06 15:05:35 -08:00
Lalit Kumar Bhasin 31bea196b4
Add `name` attribute in logging macros (#2279) 2024-11-06 13:48:09 -08:00
Mindaugas Vinkelis ac0ea9f17d
Add collect methods on ValueMap (#2267)
Co-authored-by: Cijo Thomas <cijo.thomas@gmail.com>
Co-authored-by: Lalit Kumar Bhasin <labhas@microsoft.com>
2024-11-06 13:08:46 -08:00
stormshield-fabs 1fd871a012
Remove Cow from InstrumentationScope (#2275)
Co-authored-by: Lalit Kumar Bhasin <labhas@microsoft.com>
Co-authored-by: Cijo Thomas <cijo.thomas@gmail.com>
2024-11-06 13:00:28 -08:00
Lalit Kumar Bhasin 0b716a708a
fix integration test (#2278) 2024-11-06 12:52:29 -08:00
Cijo Thomas 500d913e31
Add few debug level internal logs to PeriodicReader (#2277) 2024-11-06 08:34:12 -08:00
Cijo Thomas dd7b53159f
Simplified self-diagnostics example (#2274) 2024-11-05 08:59:21 -08:00
Lalit Kumar Bhasin 91f44ff249
Remove Global Error handler. (#2260) 2024-11-04 18:12:00 -08:00
Lalit Kumar Bhasin eca53b2fdd
CI fix: pin url for msrv build (#2272) 2024-11-04 11:42:52 -08:00
Lalit Kumar Bhasin 6a079eb977
nit - collector config fix for self-diagnostic example (#2271) 2024-11-04 10:35:37 -08:00
Mindaugas Vinkelis 16f80c2ee6
Remove redundant generic argument from Aggregator (#2269) 2024-11-03 15:11:00 -08:00
Lalit Kumar Bhasin fcd7cae39b
Global error handler cleanup - Trace SDK (#2256)
Co-authored-by: Cijo Thomas <cijo.thomas@gmail.com>
2024-11-02 20:37:13 -07:00
Lalit Kumar Bhasin 374295381f
Enable hyper client for opentelemetry-otlp (#2263) 2024-11-01 09:49:26 -07:00
Cijo Thomas 9f6c725cd3
Update links to log api spec (#2265) 2024-11-01 09:40:14 -07:00
Mindaugas Vinkelis 706a067b12
ValueMap interface change (#2117)
Co-authored-by: Lalit Kumar Bhasin <labhas@microsoft.com>
Co-authored-by: Cijo Thomas <cijo.thomas@gmail.com>
2024-11-01 09:31:47 -07:00
Lalit Kumar Bhasin e1860c7b91
[chore] Revert pinning of pin-project-lite crate after upstream fix, and CI fix (#2264) 2024-11-01 05:52:00 -07:00
Lalit Kumar Bhasin a5e2061162
Global error handler cleanup - Jaeger Remote sampler (#2257) 2024-10-29 13:05:12 -07:00
Lalit Kumar Bhasin 40b18699a1
Global error handler cleanup - Metrics data-point overflow (#2259)
Co-authored-by: Cijo Thomas <cijo.thomas@gmail.com>
2024-10-28 21:30:30 -07:00
David Pitoniak 1b2d841e37
refactor: InMemoryLogsExporter non plural (#2258)
Co-authored-by: Lalit Kumar Bhasin <labhas@microsoft.com>
2024-10-28 20:48:34 -07:00
Cijo Thomas a736604ea2
Add Utkarsh as maintainer (#2226)
Co-authored-by: Zhongyang Wu <zhongyang.wu@outlook.com>
Co-authored-by: Utkarsh Umesan Pillai <66651184+utpilla@users.noreply.github.com>
2024-10-28 07:43:07 -07:00
David Pitoniak 17f4627ab8
Refactor/metric exporters non plural (#2255)
Co-authored-by: Cijo Thomas <cijo.thomas@gmail.com>
Co-authored-by: Lalit Kumar Bhasin <labhas@microsoft.com>
2024-10-27 20:26:15 -07:00
Lalit Kumar Bhasin afc8ff516e
Global error handler cleanup - UpDown Counter, Historgram, Gauge. (#2242)
Co-authored-by: Cijo Thomas <cijo.thomas@gmail.com>
Co-authored-by: Utkarsh Umesan Pillai <66651184+utpilla@users.noreply.github.com>
2024-10-26 22:13:44 -07:00
Lalit Kumar Bhasin 3bc9b3d93d
Global error handler cleanup - Metrics Pipeline (#2244) 2024-10-26 21:59:53 -07:00
Lalit Kumar Bhasin 4a405fdfa2
Global error handler cleanup - otel-proto (#2248) 2024-10-26 19:13:30 -07:00
Lalit Kumar Bhasin 9e9b8384ae
Global error handler cleanup - baggage propagator (#2251)
Co-authored-by: Cijo Thomas <cijo.thomas@gmail.com>
2024-10-26 17:08:31 -07:00
Lalit Kumar Bhasin ed4d37913e
Global error handler cleanup - Metrics View (#2249) 2024-10-26 16:54:09 -07:00
Lalit Kumar Bhasin 1a73d52bb3
Global error handler cleanup - Jaeger Propagator (#2250) 2024-10-25 22:38:53 -07:00
David Pitoniak f3be05bb6f
refactor: update metrics Result to be MetricResult (#2241)
Co-authored-by: Cijo Thomas <cijo.thomas@gmail.com>
2024-10-25 21:52:22 -07:00
Lalit Kumar Bhasin 9382bfb1cc
Global error handler cleanup - trace API (#2252) 2024-10-25 21:27:25 -07:00
Lalit Kumar Bhasin 4c7bf582e5
Global error handler cleanup - ObservableUpDownCounter, ObservableGauge (#2240)
Co-authored-by: Cijo Thomas <cijo.thomas@gmail.com>
2024-10-24 23:49:46 -07:00
Lalit Kumar Bhasin b90c9fb09a
Global error handler cleanup - PeriodicReader (#2243)
Co-authored-by: Cijo Thomas <cijo.thomas@gmail.com>
2024-10-24 22:14:36 -07:00
stormshield-fabs e2db7a0a37
Unify builders across signals (#2220)
Co-authored-by: Lalit Kumar Bhasin <labhas@microsoft.com>
Co-authored-by: Lalit Kumar Bhasin <lalit_fin@yahoo.com>
Co-authored-by: Cijo Thomas <cijo.thomas@gmail.com>
2024-10-24 21:55:24 -07:00
Jialun Cai 5628f66395
Exclude benchmark setup duration using iter_batched (#2233) 2024-10-24 21:34:40 -07:00
Lalit Kumar Bhasin a18853e47a
Global error handler cleanup - exponential histogram (#2235)
Co-authored-by: Zhongyang Wu <zhongyang.wu@outlook.com>
Co-authored-by: Cijo Thomas <cithomas@microsoft.com>
2024-10-24 13:43:46 -07:00
Lalit Kumar Bhasin d3b1c47e1a
Global error handler cleanup - MeterProvider (#2237) 2024-10-24 13:41:41 -07:00
Lalit Kumar Bhasin 0202299dd7
Pin pin_project_lite to older version due to external_type_check compatibility (#2239) 2024-10-24 13:04:26 -07:00
Lalit Kumar Bhasin 2f65b5406f
Global error handler cleanup - ManualReader (#2236)
Co-authored-by: Cijo Thomas <cijo.thomas@gmail.com>
2024-10-24 10:05:16 -07:00
Lalit Kumar Bhasin 45b4f8294e
Global error handler cleanup - Counter and Observable counter creation (#2234) 2024-10-24 02:04:45 -07:00
David Pitoniak 80dc298cf4
feat: replace OtlpPipeline with exporter builders (#2221)
Co-authored-by: Lalit Kumar Bhasin <labhas@microsoft.com>
Co-authored-by: Cijo Thomas <cijo.thomas@gmail.com>
2024-10-23 21:20:10 -07:00
Utkarsh Umesan Pillai a7de955e16
[Metrics API] Rename `init` to `build` (#2232) 2024-10-23 18:33:37 -07:00
Utkarsh Umesan Pillai 8bd529a6d6
[Metrics API] Update Instrument Provider and remove `try_init` methods (#2227) 2024-10-22 22:42:13 -07:00
Utkarsh Umesan Pillai f45e840ed5
[Metrics API] Mark KeyValue types non-exhaustive (#2228) 2024-10-22 22:30:47 -07:00
Lalit Kumar Bhasin a47b429001
Avoid redundant shutdown in TracerProvider::drop when already shut down (#2197)
Co-authored-by: Cijo Thomas <cijo.thomas@gmail.com>
Co-authored-by: Utkarsh Umesan Pillai <66651184+utpilla@users.noreply.github.com>
Co-authored-by: Cijo Thomas <cithomas@microsoft.com>
2024-10-22 21:21:30 -07:00
Lalit Kumar Bhasin 2bb53b4fc6
[Logs API] Mark Anyvalue enum as non-exhaustive (#2230) 2024-10-22 19:38:09 -07:00
Lalit Kumar Bhasin ea4b5e4d99
Add Unit Tests for Sync and Async Log Exporters - with and without runtime - for SimpleLogProcessor (#2218) 2024-10-21 15:30:50 -07:00
slim e91138351a
feat: update otel versions for prometheus to 0.26 (#2183)
Co-authored-by: Cijo Thomas <cijo.thomas@gmail.com>
Co-authored-by: Lalit Kumar Bhasin <labhas@microsoft.com>
2024-10-21 12:23:20 -07:00
Lalit Kumar Bhasin 84c151c0b6
Fix integration tests failure for traces. (#2223) 2024-10-20 18:41:27 -07:00
David Pitoniak 4852a5e323
example: add temporality selector option to metrics-basic (#2217)
Co-authored-by: Cijo Thomas <cijo.thomas@gmail.com>
2024-10-18 07:39:13 -07:00
Lalit Kumar Bhasin f677458768
fix integration test (#2219) 2024-10-17 21:30:14 -07:00
Utkarsh Umesan Pillai e6965bd004
[Metrics API] Remove unnecessary auto trait implementations (#2215)
Co-authored-by: Cijo Thomas <cijo.thomas@gmail.com>
2024-10-16 12:50:28 -07:00
Renato Lochetti 20f1204d01
docs: Remove mention to unexisting `tls-tonic` feature flag (#2216) 2024-10-16 10:35:34 -07:00
Utkarsh Umesan Pillai 8d84a76b8f
[Metrics-API] Update asynchronous instruments to not allow calling `observe` outside of a callback (#2210)
Co-authored-by: Cijo Thomas <cijo.thomas@gmail.com>
2024-10-15 15:27:34 -07:00
Lalit Kumar Bhasin 16c0e10343
Global Log handler cleanup - Logs SDK (#2184) 2024-10-14 14:29:11 -07:00
David Pitoniak 3f5c230ecb
Chore/metrics advanced (#2204)
Co-authored-by: Cijo Thomas <cijo.thomas@gmail.com>
2024-10-13 17:30:48 -07:00
Utkarsh Umesan Pillai 42685e8e0d
[Metrics API] Simplify public API contract of instruments for SDK (#2207)
Co-authored-by: Cijo Thomas <cijo.thomas@gmail.com>
2024-10-13 17:14:11 -07:00
Cijo Thomas c5cfa4064e
Fix CI (#2209) 2024-10-13 12:11:21 -07:00
Toby Dimmick 0c414249f7
`opentelemetry-appender-log`: Add code attributes to logs (#2193) 2024-10-13 10:40:46 -07:00
Utkarsh Umesan Pillai d78930a486
[Metrics API] Remove unnecessary auto trait implementations (#2206)
Co-authored-by: Cijo Thomas <cijo.thomas@gmail.com>
2024-10-13 10:32:18 -07:00
Lalit Kumar Bhasin bacb3dab78
Prevent lint warnings if internal-logs features is not enabled. (#2196) 2024-10-13 00:14:11 -07:00
Utkarsh Umesan Pillai c3687d4fb6
[Metrics-API] Mark no-op structs as pub(crate) (#2203)
Co-authored-by: Cijo Thomas <cijo.thomas@gmail.com>
2024-10-12 19:12:15 -07:00
Utkarsh Umesan Pillai f1a6e16485
[Metrics API] Mark structs non-exhaustive (#2202) 2024-10-12 18:27:38 -07:00
Cijo Thomas caa4246ca3
Add tests to confirm known deadlock issues (#2199) 2024-10-12 10:29:11 -07:00
Lalit Kumar Bhasin b6a108eedf
Avoid redundant shutdown in LoggerProvider::drop when already shut down (#2195)
Co-authored-by: Cijo Thomas <cijo.thomas@gmail.com>
2024-10-12 09:58:40 -07:00
Vaalla 20fd454c4b
Use the correct format when deserializing body field from logs (#2178) 2024-10-12 09:44:58 -07:00
Lalit Kumar Bhasin e524bdb935
Remove redundant Arc's in MeterProviderInner (#2198) 2024-10-11 14:07:38 -07:00
Lalit Kumar Bhasin f344b5b7ff
chore: update semantic convention version v1.28.0 (#2192) 2024-10-10 13:40:47 -07:00
Utkarsh Umesan Pillai acdc4003a0
[Metrics API] Mark NoopMeterProvider as pub(crate) (#2191)
Co-authored-by: Cijo Thomas <cijo.thomas@gmail.com>
2024-10-10 13:23:53 -07:00
Utkarsh Umesan Pillai 78a684cc38
[Metrics API] Remove unnecessary public observe methods (#2190) 2024-10-10 13:03:32 -07:00
Utkarsh Umesan Pillai af4527c11f
[Metrics API] Remove as_any methods (#2187) 2024-10-08 18:26:37 -07:00
Utkarsh Umesan Pillai 21e1ba5a61
[Metrics API] Update HistogramBuilder (#2186) 2024-10-08 17:35:31 -07:00
Utkarsh Umesan Pillai c3794c0cff
[Public API cleanup] Remove unnecessary conversion methods for builder and instruments (#2138)
Co-authored-by: Cijo Thomas <cijo.thomas@gmail.com>
Co-authored-by: Zhongyang Wu <zhongyang.wu@outlook.com>
2024-10-08 16:33:50 -07:00
Dirkjan Ochtman 99d24b7b8c
proto: bump dependency requirement to match generated code (#2168) 2024-10-08 07:45:10 -07:00
Lalit Kumar Bhasin 720c62d395
nit cleanups after upgrde to rustc 1.70.0 (#2182) 2024-10-07 19:03:35 -07:00
Dirkjan Ochtman 58e0904d9e
Bump MSRV to 1.70 (#2179)
Co-authored-by: Cijo Thomas <cijo.thomas@gmail.com>
2024-10-07 16:33:38 -07:00
Cijo Thomas 80771d3b55
Nits: Collect config fix in examples (#2180) 2024-10-07 13:24:13 -07:00
Ashley Mannix 6aad3dbc99
Add a set_trace_context method to LogRecord trait (#2129) 2024-10-05 18:15:26 -07:00
Nikita Moshenskiy 9cbf6934b1
Docs: Remove unnecessary indentation for better readability (#2174) 2024-10-04 09:24:54 -07:00
Cijo Thomas a941c0a82a
Remove comments that are not relevant anymore (#2171) 2024-10-04 07:43:16 -07:00
Lalit Kumar Bhasin 2ff7ec0380
Improve internal opentelemetry logging (#2128)
Co-authored-by: Zhongyang Wu <zhongyang.wu@outlook.com>
Co-authored-by: Utkarsh Umesan Pillai <66651184+utpilla@users.noreply.github.com>
2024-10-03 20:09:36 -07:00
Cijo Thomas 86dd4863dd
Metrics - Instrument Name Validation fixes (#2166) 2024-10-02 15:37:37 -07:00
Cijo Thomas ed276119cc
Nit fixes to bug template (#2161) 2024-10-01 16:06:52 -07:00
Cijo Thomas 21fc16c0da
Prepare 0.26.0 release, update Metrics API to Beta (#2160)
Co-authored-by: Lalit Kumar Bhasin <lalit_fin@yahoo.com>
2024-10-01 15:07:17 -07:00
Cijo Thomas 167baf8555
Minor cleanups in Metrics module (#2155) 2024-09-30 16:05:05 -07:00
Cijo Thomas 380a709162
MeterProvider modified to not do shutdown if user has already shut down (#2156)
Co-authored-by: Lalit Kumar Bhasin <labhas@microsoft.com>
2024-09-30 15:45:31 -07:00
Lalit Kumar Bhasin 81a95e308b
Improve internal opentelemetry logging - directly using tracing mcros (#2152)
Co-authored-by: Cijo Thomas <cithomas@microsoft.com>
2024-09-30 15:31:13 -07:00
Cijo Thomas 8bdd18995d
For Delta Temporarlity, avoid exporting when no new measurements are made (#2153) 2024-09-30 14:02:31 -07:00
Lalit Kumar Bhasin 6ed2b4394e
Fix CI - Regenerate proto files, and selective msrv-patching (#2159) 2024-09-30 13:46:08 -07:00
Laurent Quérel 161929d8b6
Use weaver for semantic convention codegen (#2098)
Co-authored-by: Zhongyang Wu <zhongyang.wu@outlook.com>
Co-authored-by: Lalit Kumar Bhasin <labhas@microsoft.com>
2024-09-26 06:11:37 -07:00
Utkarsh Umesan Pillai 0f15d21ed2
Update doc comments (#2149) 2024-09-25 14:44:22 -07:00
Cijo Thomas 88023d9a28
Add tests for periodic reader from various RT combinations (#2147)
These tests should help with testing #2142
2024-09-25 22:05:05 +02:00
Utkarsh Umesan Pillai c8136d9b46
Add `with_boundaries` hint API for explicit bucket histograms (#2135)
Co-authored-by: Cijo Thomas <cijo.thomas@gmail.com>
2024-09-24 10:55:40 -07:00
Tom Tan b244673a4a
[TEST] Add test about batch processor with current_thread async runtime (#2123)
Co-authored-by: Cijo Thomas <cijo.thomas@gmail.com>
2024-09-23 19:04:03 -07:00
Utkarsh Umesan Pillai c93cf26bb3
Fix CI and bump the msrv of OTLP to 1.71.1 (#2140) 2024-09-23 16:38:36 -07:00
Cijo Thomas d652dc82fc
Minor - exclude pprof in windows (#2134) 2024-09-20 09:52:34 -07:00
Utkarsh Umesan Pillai 13ee7a8318
Update builder for ObservableCounter, ObservableUpDownCounter, and ObservableGauge (#2132)
Co-authored-by: Cijo Thomas <cijo.thomas@gmail.com>
2024-09-20 09:18:40 -07:00
Mindaugas Vinkelis a8d62c1fb6
PeriodicReader::build make interval registration in same thread/task (#2133) 2024-09-20 08:03:22 -07:00
Utkarsh Umesan Pillai 3347bde903
Update builder for Counter, UpDownCounter, and Gauge (#2131) 2024-09-19 17:16:51 -07:00
Utkarsh Umesan Pillai 606a3cd7cc
Update Histogram Builder (#2130) 2024-09-19 15:41:57 -07:00
Matthew Boddewyn 26b3320eef
Implement clone for ExponentialBucket and ExponentialHistogramDataPoint (#2126)
Co-authored-by: Cijo Thomas <cijo.thomas@gmail.com>
2024-09-19 11:31:36 -07:00
Utkarsh Umesan Pillai 1a4e245cb1
[Cleanup] Remove `Value` to `AnyValue` conversion methods (#2127) 2024-09-19 10:24:25 -07:00
Utkarsh Umesan Pillai 8e21c75fc2
Update CHANGELOG (#2125) 2024-09-18 15:21:17 -07:00
Utkarsh Umesan Pillai 3976f3d486
[Breaking] Enforce meter name, version schema_url to be static string slices (#2112)
Co-authored-by: Cijo Thomas <cijo.thomas@gmail.com>
Co-authored-by: Lalit Kumar Bhasin <labhas@microsoft.com>
Co-authored-by: Zhongyang Wu <zhongyang.wu@outlook.com>
2024-09-17 13:26:30 -07:00
Tom Tan d0a4fd0466
[BUILD] Add required features for test build (#2121) 2024-09-17 13:13:30 -07:00
Charles Samborski 7a074b53ae
feature: expose `SimpleSpanProcessor::new` (#2119) 2024-09-16 09:20:06 -07:00
Oliver Evans 7ab5e0fbbe
Don't impl HttpClient for reqwest::blocking::Client on wasm32 (#2073)
Co-authored-by: Lalit Kumar Bhasin <labhas@microsoft.com>
2024-09-13 11:27:53 -07:00
Utkarsh Umesan Pillai ff9d50bc43
Mark SdkMeter as pub(crate) (#2113)
Co-authored-by: Cijo Thomas <cijo.thomas@gmail.com>
2024-09-12 16:13:47 -07:00
Mindaugas Vinkelis 8bd3294b86
update trait `Number<T>` to `Number` (#2109) 2024-09-12 15:18:33 -07:00
Utkarsh Umesan Pillai b2e5640e48
Mark `ObjectSafeProvider` and `GlobalMeterProvider::new()` as private (#2108) 2024-09-12 07:25:42 -07:00
Cijo Thomas 921f25327b
Remove unused multi callback (#2107) 2024-09-11 17:34:38 -07:00
Cijo Thomas eb0d997a04
Remove MetricProducer (#2105) 2024-09-11 17:12:57 -07:00
Franco Posa 24da59e1e1
note breaking change in opentlemetry-otlp v0.17.0 CHANGELOG (#2104) 2024-09-11 16:19:30 -07:00
Mindaugas Vinkelis 5873cae3f5
AggregationSelector is not needed anymore (#2085) 2024-09-11 13:59:07 -07:00
John Vandenberg 5269660e70
Upgrade async-std v1.13 (#2082)
Co-authored-by: Cijo Thomas <cijo.thomas@gmail.com>
2024-09-11 08:01:58 -07:00
Lalit Kumar Bhasin 8f4d64e83a
Remove `target` from LogRecord::attributes for `log` events emitted through `tracing` pipeline (#2101) 2024-09-11 07:37:13 -07:00
Emostar 38f7fd517b
Update README.md (#2092)
Co-authored-by: Cijo Thomas <cijo.thomas@gmail.com>
2024-09-10 19:05:14 -07:00
Charles Samborski e206533785
fix: JSON serialization of `metrics::Examplar` and `trace::span::Link… (#2069) 2024-09-10 18:13:03 -07:00
Aumetra Weisman c3b59ba610
Remove range requirement, patch in shell script (#2095) 2024-09-10 10:58:57 -07:00
Utkarsh Umesan Pillai 089d9fbb3b
Update code samples to use `KeyValue::new()` (#2091) 2024-09-10 07:27:14 -07:00
Cijo Thomas 66f29b876f
Prepare for 0.25 release (#2088) 2024-09-09 13:34:42 -07:00
Lalit Kumar Bhasin 6c4f50ee51
msrv patch for tokio-stream, and other lint changes (#2086) 2024-09-09 11:24:41 -07:00
Lalit Kumar Bhasin a50e3ff46d
CI failure: msrv patch tokio-util (#2081) 2024-09-07 06:52:43 -07:00
Utkarsh Umesan Pillai 4a86e167b5
Add benchmarks (#2080) 2024-09-04 12:52:53 -07:00
Utkarsh Umesan Pillai 3aa50261a7
Update SDK CHANGELOG with metric improvements (#2076)
Co-authored-by: Cijo Thomas <cijo.thomas@gmail.com>
Co-authored-by: Lalit Kumar Bhasin <labhas@microsoft.com>
2024-09-04 12:21:56 -07:00
Lalit Kumar Bhasin 54a3ad1a84
fix msrv (#2079) 2024-09-04 08:45:52 -07:00
Lalit Kumar Bhasin 4bc02f41e1
Regenerate otlp proto files to fix CI (#2077) 2024-09-04 07:38:17 -07:00
Lalit Kumar Bhasin 976bc54dba
Introduce LogBatch Struct to Replace Vec in LogExporter Interface (#2057) 2024-08-30 11:43:27 -07:00
Utkarsh Umesan Pillai 8e713e42ac
nit: Remove unnecessary clippy suppressions (#2067) 2024-08-29 13:54:05 -07:00
Utkarsh Umesan Pillai 29fd682203
Update attributes benchmarks (#2064) 2024-08-28 16:32:36 -07:00
Lalit Kumar Bhasin 7d47bf213d
Update Log benchmarks (#2061) 2024-08-28 05:40:57 -07:00
tsfotis 7ad7ab3fba
fix broken docs.rs build (#2052)
Co-authored-by: Zhongyang Wu <zhongyang.wu@outlook.com>
2024-08-27 10:17:34 -07:00
Cijo Thomas a2c8c7dea1
Simplified stdout exporter for logs and traces (#2040)
Co-authored-by: Lalit Kumar Bhasin <labhas@microsoft.com>
Co-authored-by: Utkarsh Umesan Pillai <66651184+utpilla@users.noreply.github.com>
2024-08-26 10:57:23 -07:00
Cijo Thomas 322c98533f
Use event.name as attribute key for exporting Log event name (#2050) 2024-08-26 09:11:08 -07:00
Lalit Kumar Bhasin b24bb9c2f1
Preallocate storage for log attributes on stack (#1965) 2024-08-23 10:05:21 -07:00
Lalit Kumar Bhasin 4c854108e6
Update log stress and benchmark results (#2049)
Co-authored-by: Cijo Thomas <cijo.thomas@gmail.com>
2024-08-23 09:50:56 -07:00
Utkarsh Umesan Pillai 916a11782a
Update visibility of AttributeSet from pub to pub(crate) (#2045) 2024-08-23 07:30:44 -07:00
Lalit Kumar Bhasin 673c328522
Log SDK optimization - Improve perf 15%-30% (#2043) 2024-08-22 08:24:44 -07:00
Utkarsh Umesan Pillai 90ca577d42
Use arrays instead of vec in the documentation (#2042) 2024-08-21 19:42:43 -07:00
Lalit Kumar Bhasin 3193320fa6
Simplify LogExporter::Export interface (#2041)
Co-authored-by: Cijo Thomas <cijo.thomas@gmail.com>
2024-08-21 07:43:26 -07:00
Utkarsh Umesan Pillai 056d2ae8ac
Add multithreaded test for Histogram for f64 values (#2038)
Co-authored-by: Cijo Thomas <cijo.thomas@gmail.com>
2024-08-19 14:52:09 -07:00
Utkarsh Umesan Pillai ceb4e714f0
Update test markdown (#2039) 2024-08-19 14:34:53 -07:00
Utkarsh Umesan Pillai 3a4b17aed3
Move precomputed sum code to a new file (#2036)
Co-authored-by: Cijo Thomas <cijo.thomas@gmail.com>
2024-08-19 11:56:32 -07:00
Utkarsh Umesan Pillai 20625f9b8a
Rename metrics benchmarks (#2037)
Co-authored-by: Cijo Thomas <cijo.thomas@gmail.com>
2024-08-19 11:41:55 -07:00
Cijo Thomas 241431e690
Refactor Metric Tests - Part2 (#2034) 2024-08-19 11:35:06 -07:00
Utkarsh Umesan Pillai fcada1775b
Use ValueMap for Histogram- Throughput increased by 5x (#2033) 2024-08-16 16:35:36 -07:00
Utkarsh Umesan Pillai 7742587c83
Add multithreaded test for Histogram (#2032) 2024-08-16 14:25:10 -07:00
Cijo Thomas 108161c12e
Add log export benchmark to measure the cost paid for async abstraction (#2027)
Co-authored-by: Zhongyang Wu <zhongyang.wu@outlook.com>
2024-08-16 09:51:39 -07:00
Utkarsh Umesan Pillai 72ac56f71a
Add benchmark for Histogram (#2030) 2024-08-16 08:05:31 -07:00
Utkarsh Umesan Pillai 16d927bed9
Update Histogram min max computation (#2029) 2024-08-15 08:46:44 -07:00
Utkarsh Umesan Pillai 0097d16d9f
Simplify Histogram code (#2028) 2024-08-14 22:12:17 -07:00
Cijo Thomas cb1ffb5275
Add benchmark for logprocessor and its cloning costs (#2026)
Co-authored-by: Lalit Kumar Bhasin <labhas@microsoft.com>
2024-08-14 09:29:06 -07:00
Cijo Thomas 286cb6ca23
Provide default implementation for event_enabled trait in LogProcessor (#2025) 2024-08-13 21:03:28 -07:00
Utkarsh Umesan Pillai b8ef2a744f
Increase test coverage for AtomicTracker (#2022)
Co-authored-by: Cijo Thomas <cijo.thomas@gmail.com>
2024-08-13 19:35:07 -07:00
Cijo Thomas 884b86d575
Refactor Metric test - part1 (#2024) 2024-08-13 19:19:10 -07:00
Utkarsh Umesan Pillai b6ab7287ff
Fix start_time exporter for Gauge (#2023) 2024-08-13 17:43:56 -07:00
Utkarsh Umesan Pillai d2fafa41a4
Fix aggregation for Gauge (#2021)
Co-authored-by: Cijo Thomas <cijo.thomas@gmail.com>
2024-08-13 16:40:41 -07:00
Cijo Thomas df91db34fd
Nit fix to opentelemetry doc (#2019) 2024-08-13 15:31:57 -07:00
Utkarsh Umesan Pillai f2e9df28dd
Fix metrics aggregation bug for Sum and Precomputed Sum to avoid duplicate export (#2018)
Co-authored-by: Cijo Thomas <cijo.thomas@gmail.com>
2024-08-13 12:54:56 -07:00
Cijo Thomas 07b918d2ef
Remove ability to specify observable callback on Meter (#2015) 2024-08-13 12:31:52 -07:00
Utkarsh Umesan Pillai 17b99a19ba
Lock free updates for floating point metrics - Throughput increased by up to 50% (#2016)
Co-authored-by: Cijo Thomas <cijo.thomas@gmail.com>
2024-08-13 10:27:34 -07:00
Utkarsh Umesan Pillai b24608ed7b
Use ValueMap for Gauge - Throughput increased around 8x (#2017) 2024-08-13 08:38:21 -07:00
Lalit Kumar Bhasin 399846ea4c
Remove CoW for `LogRecord::event_name` and `LogRecord::severity_text` (#2014) 2024-08-12 21:05:10 -07:00
Utkarsh Umesan Pillai 5d89aee9db
Add stress test for Synchronous Gauge (#2013)
Co-authored-by: Cijo Thomas <cithomas@microsoft.com>
2024-08-12 17:44:27 -07:00
Utkarsh Umesan Pillai d583695d30
Move ValueMap to mod file to allow for code reuse (#2012) 2024-08-12 15:45:15 -07:00
Utkarsh Umesan Pillai ed82d78eb8
Add a special test for synchronous instruments (cumulative aggregation) (#2010) 2024-08-12 12:48:56 -07:00
Cijo Thomas 6c3cffb739
Nit update to stress test (#2009) 2024-08-09 15:08:20 -07:00
Utkarsh Umesan Pillai ce96b43f86
Add test coverage for observable gauge (#2007)
Co-authored-by: Cijo Thomas <cijo.thomas@gmail.com>
2024-08-09 12:47:34 -07:00
Cijo Thomas fe2fb96b79
Add a benchmark to sdk logs that is comparable to tracing appender (#2006) 2024-08-09 11:42:39 -07:00
Cijo Thomas 60f332432b
Appender-Tracing benchmark to pass message as attribute - 10% faster (#2001) 2024-08-09 11:06:38 -07:00
stormshield-fabs 2bba6b04ca
Use generics to dispatch updates in `ValueMap` (#2004)
Co-authored-by: Cijo Thomas <cijo.thomas@gmail.com>
Co-authored-by: Cijo Thomas <cithomas@microsoft.com>
Co-authored-by: Utkarsh Umesan Pillai <66651184+utpilla@users.noreply.github.com>
2024-08-09 10:14:32 -07:00
Lalit Kumar Bhasin 6a16baf055
Export event-name in OTLP Exporter optionally, if the feature-flag is enabled (#1994) 2024-08-08 15:01:34 -07:00
Lalit Kumar Bhasin e905cf7274
chore: update semantic convention version v1.27.0 (#2000) 2024-08-07 21:02:11 -07:00
Lalit Kumar Bhasin 2409c18a75
Box complex types in AnyValue enum (Improve perf by 10%, and size reduction by ~60%) (#1993)
Co-authored-by: Utkarsh Umesan Pillai <66651184+utpilla@users.noreply.github.com>
Co-authored-by: Cijo Thomas <cijo.thomas@gmail.com>
2024-08-07 17:46:10 -07:00
Utkarsh Umesan Pillai fe10ab1065
[logs-appender-tracing] Use method from tracing-core instead of creating our own (#1999) 2024-08-07 16:18:02 -07:00
Cijo Thomas 83ba87f671
LogAppender - 5% perf gain and reduce heap alloc for SeverityText (#1997) 2024-08-07 14:16:25 -07:00
Cijo Thomas d8bb7648cc
Add benchmarks for measuring cost of Logger, Provider creation (#1996) 2024-08-07 13:17:28 -07:00
Cijo Thomas 528e0a6c14
Metric refactor - 2x perf and allocation free (#1989)
Co-authored-by: Utkarsh Umesan Pillai <66651184+utpilla@users.noreply.github.com>
2024-08-06 17:29:02 -07:00
Cijo Thomas 76b40ba630
Metric benchmark - more isolation (#1991) 2024-08-06 15:00:01 -07:00
Utkarsh Umesan Pillai 75eb96d974
Fix metrics counter benchmarks (#1990) 2024-08-06 12:42:14 -07:00
Cijo Thomas 20226cd550
Nit additions to Metrics tests (#1988) 2024-08-06 09:06:34 -07:00
Lalit Kumar Bhasin 171924452b
Hide LogRecord attributes Implementation Details from exporters (#1985)
Co-authored-by: Cijo Thomas <cithomas@microsoft.com>
2024-08-05 17:21:32 -07:00
Mark Ingram 9f716528c3
[opentelemetry-otlp] fix example when running with OTEL Collector 0.104+ (#1982) 2024-08-05 09:42:41 -07:00
dependabot[bot] d3c10f84fa
Bump obi1kenobi/cargo-semver-checks-action from 2.4 to 2.6 (#1981) 2024-08-01 17:45:08 -07:00
Cijo Thomas 8710248dc1
Add Utkarsh as approver (#1978)
Co-authored-by: Lalit Kumar Bhasin <labhas@microsoft.com>
2024-08-01 10:11:10 -07:00
Lalit Kumar Bhasin dae1081400
[CI fix] Fix community contributing hyperlink (#1980) 2024-08-01 08:12:38 -07:00
Cijo Thomas ac7343f374
MetricRefactor - Part1 - Move AttributeSet inside aggregations (#1977) 2024-07-31 16:48:55 -07:00
Utkarsh Umesan Pillai cfbd1c30f0
Update counter multi-threaded test (#1976) 2024-07-31 07:39:52 -07:00
Cijo Thomas 7a9076032d
Apply changes from Span BatchProcessor to Log BatchProcessor (#1973) 2024-07-29 11:07:07 -07:00
Cijo Thomas cd59346af5
BatchSpanProcessor to trigger first export after the interval instead of right away (#1971) 2024-07-26 20:52:16 -07:00
Lalit Kumar Bhasin 4d31408dda
Remove SimpleLogProcessor from log benchmark (#1969)
Co-authored-by: Cijo Thomas <cijo.thomas@gmail.com>
2024-07-26 19:06:53 -07:00
Lalit Kumar Bhasin f9076ea92c
CI fix (#1970) 2024-07-26 18:47:43 -07:00
John Howard 2eba546f7b
Fix shutdown of single threaded trace batch provider (#1964) 2024-07-26 18:10:32 -07:00
Sebastian Bernauer 383c7d13b6
[opentelemetry-prometheus]: Prepare 0.17.0 release using opentelemetry 0.24 (#1957) 2024-07-24 09:32:20 -07:00
Gary Coady 2b026d9759
Fix PartialEq for Value in opentelemetry-stdout (#1955)
Co-authored-by: Lalit Kumar Bhasin <labhas@microsoft.com>
2024-07-23 19:42:20 -07:00
Lalit Kumar Bhasin 57bcd59989
fix ci (#1960) 2024-07-23 16:39:59 -07:00
harscoet 406e31b76b
zstd compression for tonic exporter (#1947) 2024-07-23 10:21:21 -07:00
Lalit Kumar Bhasin a1f02faf7c
chore: update proto definition to v1.3.2 (#1945)
Co-authored-by: Cijo Thomas <cijo.thomas@gmail.com>
2024-07-18 16:45:14 -07:00
Pato Sandaña acd6cbe4f7
Adding `PartialEq` for `LogRecord` and `SpanContext` to help unit testing (#1944)
Co-authored-by: Lalit Kumar Bhasin <lalit_fin@yahoo.com>
2024-07-18 16:12:40 -07:00
Razvan Rotari e1a3494c34
When deserializing JSON, accept both int and string in 'intValue' (#1906)
Co-authored-by: Zhongyang Wu <zhongyang.wu@outlook.com>
Co-authored-by: Lalit Kumar Bhasin <labhas@microsoft.com>
2024-07-18 13:51:35 -07:00
Dirkjan Ochtman 0e8f259cf3
sdk: expose hidden Tracer::should_sample() method (#1937)
Co-authored-by: Lalit Kumar Bhasin <labhas@microsoft.com>
2024-07-18 08:04:34 -07:00
Howard a9b8621cd1
Flatten field + fix u64 to string serde (#1911)
Co-authored-by: Lalit Kumar Bhasin <labhas@microsoft.com>
Co-authored-by: Zhongyang Wu <zhongyang.wu@outlook.com>
2024-07-16 15:24:32 -07:00
Utkarsh Umesan Pillai 47e52f1feb
Fix Stress Test (#1935) 2024-07-16 11:56:02 -07:00
Dirkjan Ochtman 5922205d07
sdk: expose Tracer::id_generator() (#1934) 2024-07-15 09:13:45 -07:00
Cijo Thomas cdf5f03abe
Prepare .24 release (#1932) 2024-07-12 20:47:03 -07:00
Lalit Kumar Bhasin 6207882b4b
Insert tracing event name into LogRecord::event_name instead of attributes (#1928)
Co-authored-by: Cijo Thomas <cithomas@microsoft.com>
2024-07-12 17:16:06 -07:00
Utkarsh Umesan Pillai a2e435f25b
[opentelemetry-otlp][tonic] Add more information to error message for Unknown status code (#1931) 2024-07-12 12:26:58 -07:00
Theodore Brockman 597327f199
Initial attempt at adding metric semconvs. (#1918)
Co-authored-by: Lalit Kumar Bhasin <labhas@microsoft.com>
2024-07-12 08:07:30 -07:00
Aumetra Weisman 621a5a9737
Upgrade to hyper/http v1.0 (#1674)
Co-authored-by: Lalit Kumar Bhasin <labhas@microsoft.com>
2024-07-12 07:27:25 -07:00
Shawn 166a12734c
Update CHANGELOG.md (#1927) 2024-07-11 11:38:49 -07:00
Utkarsh Umesan Pillai df815bdc7f
Simplify OTLP example (#1926) 2024-07-10 18:03:05 -07:00
Ramji 3882b2288d
Update http example with json protocol (#1912)
Co-authored-by: Cijo Thomas <cijo.thomas@gmail.com>
Co-authored-by: Lalit Kumar Bhasin <labhas@microsoft.com>
2024-07-10 10:06:02 -07:00
Aumetra Weisman 224289e9e0
Remove `isahc` support (#1924) 2024-07-10 09:45:19 -07:00
Cijo Thomas c53c5f1fcb
Add code comment about default Log attribute size (#1914) 2024-07-08 12:52:04 -07:00
Utkarsh Umesan Pillai 31a3491b14
Update metric benchmarks (#1907)
Co-authored-by: Cijo Thomas <cithomas@microsoft.com>
Co-authored-by: Cijo Thomas <cijo.thomas@gmail.com>
2024-07-03 16:09:30 -07:00
Lalit Kumar Bhasin ae6e2ffa9a
Predefine Vector Capacity for LogRecord Attributes (#1908) 2024-07-03 12:26:16 -07:00
Utkarsh Umesan Pillai ad990d6d33
[Baggage] Simplify Get APIs (#1902)
Co-authored-by: Zhongyang Wu <zhongyang.wu@outlook.com>
2024-07-01 19:33:37 -07:00
Mark Ingram d5c86d9adc
[opentelemetry-otlp] adds an example HTTP exporter backed by Hyper (#1861)
Co-authored-by: Cijo Thomas <cijo.thomas@gmail.com>
2024-07-01 15:44:01 -07:00
Cijo Thomas 028d3e7efb
Benchmarks for AnyValue (#1901) 2024-07-01 15:20:04 -07:00
Lalit Kumar Bhasin 0cfc8d95c3
Add self-diagnostics example (#1846)
Example to demonstrate using tracing as a global error handler for errors generated by the OpenTelemetry Metrics SDK. In this example, measurements are recorded to exceed the cardinality limit, which triggers the error to be logged. This error is then emitted to `stdout` using `opentelemetry-appender-tracing` subscriber.
2024-07-01 12:57:21 +02:00
Cijo Thomas 0303a38758
Add flamegraph for some benchmarks (#1899)
Co-authored-by: Lalit Kumar Bhasin <labhas@microsoft.com>
2024-06-27 17:20:00 -07:00
Utkarsh Umesan Pillai 16410d7555
Use arrays instead of vec for creating resource in examples (#1900) 2024-06-27 17:06:18 -07:00
Cijo Thomas d54c18b80c
Use as many threads as logical cores for achieving full utilization (#1897) 2024-06-27 13:25:04 -07:00
Cijo Thomas 4df74e85ef
Nit fix to benchmark results (#1895) 2024-06-26 16:41:24 -07:00
Lalit Kumar Bhasin 9b746e0288
Group Logs and Spans by Resource and Instrumentation Scope in OTLP Exporter (#1873)
Co-authored-by: Cijo Thomas <cithomas@microsoft.com>
2024-06-26 11:17:11 -07:00
Tom Tan b3315f2804
Make the stress threads number configurable via command line argument (#1871)
Co-authored-by: Harold Dost <h.dost@criteo.com>
2024-06-21 13:19:13 +02:00
Lalit Kumar Bhasin c1f351cd67
Add CI for ARM (#1884)
Co-authored-by: Cijo Thomas <cijo.thomas@gmail.com>
2024-06-20 12:13:05 -07:00
Lalit Kumar Bhasin 4d455062ab
Adding target as LogRecord field, and using it as scope.name in OTLP exporter (#1869)
Co-authored-by: Zhongyang Wu <zhongyang.wu@outlook.com>
Co-authored-by: Cijo Thomas <cijo.thomas@gmail.com>
Co-authored-by: Cijo Thomas <cithomas@microsoft.com>
2024-06-20 11:45:00 -07:00
Lalit Kumar Bhasin e0fb7fe3b7
fix otlp/json exporter (#1882) 2024-06-18 13:53:41 -07:00
Utkarsh Umesan Pillai da368d4085
Simplify tracing-grpc example (#1886) 2024-06-17 15:55:13 -07:00
Utkarsh Umesan Pillai 3e49f2313e
Remove "logs_level_enabled" from cargo toml for appender crates (#1885) 2024-06-14 17:40:41 -07:00
Utkarsh Umesan Pillai 50c574a18b
Add criterion to workspace dependencies (#1883) 2024-06-13 18:05:27 -07:00
Mark Ingram 66e3ea5335
[opentelemetry-otlp] basic-otlp-http example - trivial cleanup (#1878)
Co-authored-by: Cijo Thomas <cijo.thomas@gmail.com>
2024-06-13 13:02:26 -07:00
Lalit Kumar Bhasin 64aa5061b8
fix msrv (#1877) 2024-06-13 11:21:33 -07:00
Utkarsh Umesan Pillai b933bdd82d
Update collector config to use debug exporter (#1876) 2024-06-10 15:55:46 -07:00
Zhongyang Wu 2ac2b180ae
feat: add `shutdown` in `TracerProvider` (#1855)
Co-authored-by: Lalit Kumar Bhasin <lalit_fin@yahoo.com>
Co-authored-by: Lalit Kumar Bhasin <labhas@microsoft.com>
2024-06-10 09:57:48 -07:00
Utkarsh Umesan Pillai bc1f94ce72
Remove unused dev/test dependencies (#1872) 2024-06-07 22:28:32 -07:00
Lalit Kumar Bhasin 36ad46ae28
update msrv check, and bump opentelemetry-proto to v1.70.0 (#1864) 2024-06-06 10:35:22 -07:00
Utkarsh Umesan Pillai f1cdaca447
Improve multi-threaded test for Counter (#1858)
Co-authored-by: Zhongyang Wu <zhongyang.wu@outlook.com>
Co-authored-by: Cijo Thomas <cijo.thomas@gmail.com>
2024-06-04 10:39:44 -07:00
Lalit Kumar Bhasin f488006858
Small change to return error from periodic exporter (#1857)
Co-authored-by: Cijo Thomas <cijo.thomas@gmail.com>
2024-06-04 09:24:17 -07:00
Utkarsh Umesan Pillai 406cc3101c
[opentelemetry-otlp] Use recommended API for config in examples (#1859) 2024-06-03 18:07:35 -07:00
dependabot[bot] 935610612c
Bump obi1kenobi/cargo-semver-checks-action from 2.3 to 2.4 (#1853)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-06-03 09:16:43 -07:00
Zhongyang Wu 19854021af
test: fix MockLogExporter (#1854) 2024-06-03 09:16:16 -07:00
Utkarsh Umesan Pillai 54b807fe0b
Remove unnecessary features from command-line args (#1852) 2024-06-01 11:52:41 -07:00
Lalit Kumar Bhasin 91c685f433
Small cleanup in Logs SDK. (#1850)
Co-authored-by: Cijo Thomas <cijo.thomas@gmail.com>
2024-05-31 12:23:27 -07:00
Lalit Kumar Bhasin 300f8e5fca
[SEMANTIC CONVENTIONS] Upgrade to version 1.26.0 (#1851) 2024-05-31 12:13:29 -07:00
Zhongyang Wu 82fa485359
feat: clean up trace SDK APIs (#1755)
Co-authored-by: Cijo Thomas <cijo.thomas@gmail.com>
2024-05-30 10:04:08 -07:00
Lalit Kumar Bhasin 84c23a3017
[Trace SDK] Send resource once to processor and exporter, and not with every span (#1830)
Co-authored-by: Cijo Thomas <cijo.thomas@gmail.com>
Co-authored-by: Zhongyang Wu <zhongyang.wu@outlook.com>
2024-05-30 09:40:14 -07:00
EAimTY 1beffd2149
Fix typos in webpki feature name (#1842)
Signed-off-by: EAimTY <EAimTY@users.noreply.github.com>
Co-authored-by: Zhongyang Wu <zhongyang.wu@outlook.com>
Co-authored-by: Cijo Thomas <cijo.thomas@gmail.com>
2024-05-30 09:24:09 -07:00
Expyron 7cad751cab
Remove unused dependency (#1847) 2024-05-30 07:29:34 -07:00
Utkarsh Umesan Pillai e2e6a6e2a8
Add multi-threaded test for Counter (#1845)
Co-authored-by: Cijo Thomas <cijo.thomas@gmail.com>
2024-05-29 16:17:18 -07:00
Utkarsh Umesan Pillai 3825edcc85
Update metrics tests (#1844) 2024-05-29 16:00:08 -07:00
Cijo Thomas 78943fd674
Add more validations to Metrics tests (#1841) 2024-05-29 12:41:38 -07:00
Zhongyang Wu d0c8105446
chore: bump the msrv of OTLP to 1.70 (#1840) 2024-05-29 05:22:34 -07:00
Utkarsh Umesan Pillai 2dd47fd578
Fix tests to make precommit.sh run on Windows (#1831)
Co-authored-by: Zhongyang Wu <zhongyang.wu@outlook.com>
Co-authored-by: Cijo Thomas <cijo.thomas@gmail.com>
2024-05-28 21:46:38 -07:00
Utkarsh Umesan Pillai e521083cd2
Minor refactoring (#1839) 2024-05-28 21:27:21 -07:00
Cijo Thomas 0f6de5a946
Metrics Aggregation - Improve throughput by 10x (#1833)
Co-authored-by: Zhongyang Wu <zhongyang.wu@outlook.com>
2024-05-28 18:26:50 -07:00
Cijo Thomas 6ee5579838
Add tests for Histogram metrics (#1834) 2024-05-28 18:12:16 -07:00
Utkarsh Umesan Pillai 14c038d5bf
Fix external-types check (#1838) 2024-05-28 17:18:39 -07:00
Zhongyang Wu 0ce6a6dc36
fix: make `shutdown` `&self` in span processor (#1836) 2024-05-28 07:04:06 -07:00
Cijo Thomas 91397fc64f
Add memory and cpu stats to Stress test (#1832) 2024-05-25 09:50:28 -07:00
Utkarsh Umesan Pillai e699233bcc
Fix typos (#1828)
Co-authored-by: Cijo Thomas <cijo.thomas@gmail.com>
2024-05-24 14:44:21 -07:00
Utkarsh Umesan Pillai b1a80eed9f
OtlpTracePipeline fixed to no longer set global provider (#1812)
Co-authored-by: Zhongyang Wu <zhongyang.wu@outlook.com>
Co-authored-by: Cijo Thomas <cijo.thomas@gmail.com>
2024-05-24 13:22:29 -07:00
Cijo Thomas 28f8dbca39
Add note about using newer protoc in contributing doc (#1824) 2024-05-24 13:01:56 -07:00
Cijo Thomas ec9fd62d2e
Run msrv check for all crates (#1826) 2024-05-24 12:52:35 -07:00
Cijo Thomas ac741c2186
Remove env_logger from cargo (#1825) 2024-05-24 11:45:49 -07:00
Cijo Thomas 57f87d68ff
Add more observable counter tests (#1818) 2024-05-24 10:55:24 -07:00
Cijo Thomas f8ee5518d7
Improve CI speed by removing duplicate run of tests (#1822) 2024-05-24 10:10:20 -07:00
Cijo Thomas 1b410d08dd
Remove AWSid generator (#1820)
Co-authored-by: Zhongyang Wu <zhongyang.wu@outlook.com>
2024-05-24 09:45:17 -07:00
Cijo Thomas 98741c7cc7
[Metrics] - Remove unit abstraction (#1821)
Co-authored-by: Zhongyang Wu <zhongyang.wu@outlook.com>
2024-05-24 09:35:29 -07:00
Cijo Thomas 74b0ad41eb
Fix metrics overflow stress test (#1819) 2024-05-24 08:48:02 -07:00
Cijo Thomas bded5989ef
Fix overflow for counter metric (#1815)
Co-authored-by: Utkarsh Umesan Pillai <66651184+utpilla@users.noreply.github.com>
2024-05-23 20:43:18 -07:00
Cijo Thomas ca03c79ee1
Add bench for gauge instrument (#1816) 2024-05-23 19:20:09 -07:00
Lalit Kumar Bhasin aca4b52e20
Remove temporary vector in tracer appender (#1814) 2024-05-23 14:38:17 -07:00
Cijo Thomas 5c7c695c6c
Run semver CI on demand (#1813) 2024-05-23 12:15:13 -07:00
Lalit Kumar Bhasin 4883d2d350
Support LogProcessors chaining through mutable reference (#1726) 2024-05-23 11:30:28 -07:00
Cijo Thomas 33abef2a78
Log SDK, OTLP builders to accept Resource directly instead of wrapping in Config (#1788)
Co-authored-by: Zhongyang Wu <zhongyang.wu@outlook.com>
2024-05-23 09:49:39 -07:00
Lalit Kumar Bhasin d21b13ae1e
Integration tests for Logs (#1759)
Co-authored-by: Zhongyang Wu <zhongyang.wu@outlook.com>
2024-05-23 09:08:35 -07:00
Cijo Thomas 35f9a60d5c
Removes ordered-float dependency, and make own implementation for f64 hashing. (#1806) 2024-05-22 16:09:27 -07:00
Utkarsh Umesan Pillai f82dd14d06
[opentelemetry-otlp] Update example output (#1807) 2024-05-22 15:29:40 -07:00
Cijo Thomas f64bdd2e1c
Use better random generation in benchmark and stress tests (#1800)
Co-authored-by: Zhongyang Wu <zhongyang.wu@outlook.com>
2024-05-22 11:54:59 -07:00
Cijo Thomas 6d3bea7282
Add name to info logs in OTLP Example (#1802) 2024-05-22 09:05:26 -07:00
Lalit Kumar Bhasin 6d4ae8718d
Nit fix for review comments from #1798 (#1803) 2024-05-22 08:31:11 -07:00
Utkarsh Umesan Pillai 9fa13bc7c4
[opentelemetryt-stdout] Remove `default_features = false` (#1791)
Co-authored-by: Zhongyang Wu <zhongyang.wu@outlook.com>
2024-05-21 22:57:18 -07:00
Lalit Kumar Bhasin d3b3f70578
Update OTLP examples to use opentelemetry-appender-tracing, with filtering of the events from specific crates. (#1798) 2024-05-21 21:54:17 -07:00
Cijo Thomas d08a861234
[Metric SDK] - Avoid exposing AttributeSet to exporters - Part2 (#1794)
Co-authored-by: Zhongyang Wu <zhongyang.wu@outlook.com>
2024-05-21 16:10:32 -07:00
Cijo Thomas 5937065f6f
Nit fixes to Resource docs (#1796)
Co-authored-by: Zhongyang Wu <zhongyang.wu@outlook.com>
2024-05-21 11:40:48 -04:00
Zhongyang Wu 21bc36c958
chore: add prometheus back with API and SDK pinned at 0.23 (#1795) 2024-05-20 23:23:46 -07:00
Cijo Thomas 66b00d6e32
[Metric SDK] - Avoid exposing AttributeSet to exporters - Part1 (#1792) 2024-05-20 21:06:28 -04:00
Utkarsh Umesan Pillai 5c17ed1995
Add semver check to CI (#1793) 2024-05-20 20:52:34 -04:00
Cijo Thomas cb149bf6a7
Use warning in rustdocs for stdout (#1789) 2024-05-20 11:04:22 -07:00
Cijo Thomas 595ad05bc5
Minor cleanups of readme files (#1785) 2024-05-20 12:43:39 -04:00
Cijo Thomas 426a1ddd1b
OTLPMetricPipeline fixed to no longer set global provider (#1787) 2024-05-20 09:56:08 -04:00
Zhongyang Wu 4d2ac7fa9e
fix: broken link in jaeger docs (#1786) 2024-05-19 19:31:55 -04:00
Cijo Thomas 79189a88ac
Add logs and metrics to default features in api, sdk and otlp crate (#1783) 2024-05-19 12:22:50 -04:00
Cijo Thomas 29ac005986
Move codeowners to a single place (#1784) 2024-05-18 22:16:32 -07:00
Cijo Thomas 2210d7b5de
Remove opentelemetry-jaeger (#1782) 2024-05-18 11:20:41 -07:00
David Cook 1580105b65
Move a changelog entry to the correct version (#1781) 2024-05-16 19:25:44 -04:00
Cijo Thomas 2863632af3
Add script to tag and publish to crates.io (#1774)
Co-authored-by: Zhongyang Wu <zhongyang.wu@outlook.com>
2024-05-15 18:40:15 -04:00
Lalit Kumar Bhasin 349d804496
Enhance LogRecord Deserialization with Default Values for Missing Fields (#1773)
Co-authored-by: Cijo Thomas <cijo.thomas@gmail.com>
2024-05-15 16:23:58 -04:00
Cijo Thomas 5b238eb8ce
Fix appender-tracing features to remove sdk dependency (#1775) 2024-05-15 14:32:46 -04:00
Cijo Thomas 4042f511d7
Use token for code cov (#1772) 2024-05-15 13:32:10 -04:00
Cijo Thomas 1faa9a7c7b
Prepare v0.23 release (#1738)
Co-authored-by: Zhongyang Wu <zhongyang.wu@outlook.com>
2024-05-15 12:44:13 -04:00
Cijo Thomas 49c88ea550
Minor fix to OTLP doc and integration test (#1758)
Co-authored-by: Zhongyang Wu <zhongyang.wu@outlook.com>
2024-05-15 08:29:59 -07:00
Lalit Kumar Bhasin 10f99bf9d6
Update serialization format for LogRecord fields. (#1771)
Co-authored-by: Zhongyang Wu <zhongyang.wu@outlook.com>
Co-authored-by: Cijo Thomas <cijo.thomas@gmail.com>
2024-05-14 20:40:00 -07:00
Cijo Thomas 1733da5560
more stable metrics sdk tests (#1768) 2024-05-14 23:22:04 -04:00
Cijo Thomas 06ed50d1b9
Remove OTLPExporter dependency on sem conventions (#1769) 2024-05-14 22:47:14 -04:00
Lalit Kumar Bhasin 6d7a16cba4
Update msrv version to 1.65 in docs (#1770) 2024-05-14 19:33:28 -07:00
Cijo Thomas 48112e0f44
Fix periodic reader to trigger first exporter at the interval (#1766) 2024-05-14 20:52:06 -04:00
Cijo Thomas 0cc7228559
Try to use authenticated request to install protoc in GH (#1767) 2024-05-14 20:39:53 -04:00
Cijo Thomas c8ca03ea91
Add http-json warning to OTLP Exporter (#1765) 2024-05-14 17:09:21 -07:00
Cijo Thomas a4d92119e6
Make readme for api,sdk,stdout,otlp consistent (#1760)
Co-authored-by: Zhongyang Wu <zhongyang.wu@outlook.com>
2024-05-14 14:01:35 -04:00
Lalit Kumar Bhasin d34de1a11a
Add macos-latest in CI test (#1762) 2024-05-14 10:01:37 -07:00
Cijo Thomas 4bc2d8cfd9
Show working example for OTLP Http (#1756) 2024-05-13 22:47:29 -04:00
Cijo Thomas d2668e6c7e
OTLP Examples fixed to be consistent (#1752)
Co-authored-by: Zhongyang Wu <zhongyang.wu@outlook.com>
2024-05-13 22:11:10 -04:00
Cijo Thomas 06d8b6c49d
Fix stdout traceexporter to show scope attributes (#1747)
Co-authored-by: Zhongyang Wu <zhongyang.wu@outlook.com>
2024-05-13 20:42:43 -04:00
Cijo Thomas cdd9309cd3
Use updated image for jaeger ui (#1754)
Co-authored-by: Zhongyang Wu <zhongyang.wu@outlook.com>
2024-05-13 20:27:18 -04:00
Lalit Kumar Bhasin 656b1e6fa9
Enable integration test for Span validation (#1753)
Co-authored-by: Zhongyang Wu <zhongyang.wu@outlook.com>
2024-05-13 20:00:46 -04:00
Cijo Thomas e726892e16
Modify loggerprovider shutdown, flush to return single Result and handle repeat shutdown calls (#1750) 2024-05-13 16:45:00 -07:00
Cijo Thomas b98b5896d2 revert 2024-05-13 12:22:14 -07:00
Cijo Thomas 4ec536bf44 fix yml 2024-05-13 12:18:36 -07:00
Cijo Thomas a58404ebc8
Few doc updates, mostly cleanups. (#1749) 2024-05-13 12:52:32 -04:00
Cijo Thomas 78c5c084d8
Remove global shutdown from metrics and doc fixes (#1743)
Co-authored-by: Zhongyang Wu <zhongyang.wu@outlook.com>
2024-05-13 10:47:45 -04:00
Cijo Thomas 2fcd65e46a
Add Resource validation to Log SDK test (#1748) 2024-05-12 13:02:25 -07:00
Cijo Thomas bf20372116
Refactor Metrics tests and add more (#1737)
Co-authored-by: Zhongyang Wu <zhongyang.wu@outlook.com>
2024-05-12 11:16:27 -07:00
Chielo 2a526d7618
Fix feature flags (#1746) 2024-05-12 09:44:29 -07:00
Lalit Kumar Bhasin de3147aa9c
Enhance LogRecord::add_attributes interface to accept generic Iterables (#1741)
Co-authored-by: Zhongyang Wu <zhongyang.wu@outlook.com>
2024-05-11 17:14:52 -04:00
Cijo Thomas 161d28d34e
Metrics examples to stop using global shutdown (#1742) 2024-05-11 13:24:53 -07:00
Cijo Thomas bf7b4a0f20
Modify metrics example to shutdown without global shutdown method (#1739) 2024-05-11 12:13:36 -07:00
Utkarsh Umesan Pillai 736712d005
Use shared slices instead of references to owned vectors as return types (#1729)
Co-authored-by: Cijo Thomas <cijo.thomas@gmail.com>
2024-05-10 14:35:46 -04:00
Cijo Thomas 01d584ac0b
Add logs to stdout example (#1735) 2024-05-10 13:24:32 -04:00
Cijo Thomas 5e02f38a29
Stdout example to default to all features (#1734) 2024-05-10 12:36:36 -04:00
Cijo Thomas 6d50e5fc02
Remove SDK's attributeset usage in stdout, add tests (#1730)
Co-authored-by: Zhongyang Wu <zhongyang.wu@outlook.com>
2024-05-09 23:46:43 -04:00
Cijo Thomas 6da455b28e
Fix changelog nit (#1731) 2024-05-09 20:37:06 -07:00
Lalit Kumar Bhasin 60a3cbe8c8
[Logs] fixing couple of issues in LogRecord move (#1725)
Co-authored-by: Zhongyang Wu <zhongyang.wu@outlook.com>
Co-authored-by: Cijo Thomas <cijo.thomas@gmail.com>
2024-05-09 15:04:16 -04:00
Lalit Kumar Bhasin 431baf6515
upgrade codecov/codecov-action from v3 to v4 (#1728)
Co-authored-by: Cijo Thomas <cijo.thomas@gmail.com>
2024-05-09 12:11:51 -04:00
Zhongyang Wu 8f8c259bef
chore: remove flaky tests (#1727) 2024-05-09 11:51:16 -04:00
Cijo Thomas feb8d48645
[Metrics API] InstrumentBuilder modified to take instrumentprovider instead of meter (#1707) 2024-05-08 14:03:20 -04:00
Cijo Thomas 5fba0de083
Minor: Add tests to confirm Meter creation behavior (#1724) 2024-05-08 13:40:48 -04:00
Zhongyang Wu 19d3223e24
fix: URLs in OTLP exporters (#1706)
Co-authored-by: Cijo Thomas <cijo.thomas@gmail.com>
2024-05-08 11:52:00 -04:00
Lalit Kumar Bhasin b5fe16edd3
Moving LogRecord implementation to SDK (#1702)
Co-authored-by: Zhongyang Wu <zhongyang.wu@outlook.com>
Co-authored-by: Cijo Thomas <cithomas@microsoft.com>
Co-authored-by: Cijo Thomas <cijo.thomas@gmail.com>
2024-05-07 21:01:49 -07:00
Cijo Thomas 845f2f04d1
Simpler usage of Observable instruments (#1715) 2024-05-07 20:01:46 -07:00
Cijo Thomas 348ec9e583
Metric attributes need sort with keys only (#1718) 2024-05-07 20:23:04 -04:00
Lalit Kumar Bhasin ecfad5fd6a
Upgrade opentelemetry-proto v1.3.1 (#1721) 2024-05-07 14:51:14 -04:00
Lalit Kumar Bhasin 8fd83e29ba
fix ci (#1720) 2024-05-07 13:59:40 -04:00
Cijo Thomas cb67a4b470
Document github repo settings (#1717) 2024-05-06 21:28:01 -04:00
Utkarsh Umesan Pillai c7e0d5023d
Add CI coverage for Windows (#1714) 2024-05-06 20:46:13 -04:00
Utkarsh Umesan Pillai 6c9385ca0f
Minor changes (#1711) 2024-05-06 15:25:06 -04:00
Utkarsh Umesan Pillai a99438af99
Code changes for the new Clippy version and running test on Windows (#1704) 2024-05-06 11:46:23 -04:00
Cijo Thomas ccd5f08c00
Add test to confirm known bug (#1700) 2024-05-01 21:48:42 -04:00
Utkarsh Umesan Pillai 0b78252d24
Stabilize Gauge (#1701) 2024-05-01 21:39:02 -04:00
Ashley Mannix 9eb548ab2b
Treat log's key-values as attributes in log bridge (#1628)
Co-authored-by: Zhongyang Wu <zhongyang.wu@outlook.com>
Co-authored-by: Cijo Thomas <cijo.thomas@gmail.com>
2024-05-01 17:03:59 -07:00
Cijo Thomas 832fad414b
Minor cleanups to Metrics API docs (#1695)
Co-authored-by: Lalit Kumar Bhasin <lalit_fin@yahoo.com>
2024-05-01 00:37:03 -04:00
Cijo Thomas 943bb7a03f
Reflect status of each component (#1694) 2024-04-30 16:22:09 -04:00
Cijo Thomas d5dd14baa4
Add repository settings log (#1693) 2024-04-30 14:47:07 -04:00
Lalit Kumar Bhasin 8c60749eb8
[Logs SDK] Send resource once to processor and exporter, and not for every event. (#1636) 2024-04-30 14:38:24 -04:00
Lalit Kumar Bhasin 213fa3f001
[Logs API] Remove global provider for Logs (#1691)
Co-authored-by: Zhongyang Wu <zhongyang.wu@outlook.com>
2024-04-30 14:20:29 -04:00
Zhongyang Wu 0ba4cbd2de
feat(logs): make logger shutdown &self (#1643) 2024-04-28 23:01:08 -07:00
Lalit Kumar Bhasin 8a9a569d21
Upgrade to Semantic Convention v1.25.0 (#1681)
Co-authored-by: Zhongyang Wu <zhongyang.wu@outlook.com>
2024-04-24 19:56:35 -04:00
Zhongyang Wu 0bb0be2186
Update RELEASING.md (#1677) 2024-04-24 15:46:02 -07:00
Ramji cc80ec6aa4
Support http/json protocol (#1585)
Co-authored-by: Zhongyang Wu <zhongyang.wu@outlook.com>
Co-authored-by: Lalit Kumar Bhasin <lalit_fin@yahoo.com>
2024-04-22 21:55:36 -04:00
Cijo Thomas 97b229edc3
Nit fix to gh issue template about slack; (#1676) 2024-04-22 19:40:13 -04:00
Tom Tan 9854bb54a9
Run a stress thread for each logical core (#1675) 2024-04-22 14:38:33 -04:00
Daniel Izquierdo 7a51e75f53
Use a builder pattern for loggers and tracers (#1567)
Co-authored-by: Zhongyang Wu <zhongyang.wu@outlook.com>
Co-authored-by: Harold Dost <h.dost@criteo.com>
Co-authored-by: Cijo Thomas <cijo.thomas@gmail.com>
Co-authored-by: Cijo Thomas <cithomas@microsoft.com>
2024-04-21 16:58:29 -04:00
Lev1ty 6952f290a0
Add feature webkpi-roots for reqwest and tonic exporter backends (#1672)
adds for both opentelemetry-http and opentelemetry-otlp
2024-04-21 20:04:02 +02:00
Lalit Kumar Bhasin 8f27e2676c
Refactor SdkMeterProvider with Inner Structure for Better Lifecycle Control (#1663)
Co-authored-by: Cijo Thomas <cijo.thomas@gmail.com>
Co-authored-by: Zhongyang Wu <zhongyang.wu@outlook.com>
2024-04-19 12:58:17 -07:00
Cijo Thomas 9242ed1d3a
Add Lalit as maintainer (#1669)
Co-authored-by: Lalit Kumar Bhasin <labhas@microsoft.com>
2024-04-19 12:54:12 -04:00
Lalit Kumar Bhasin 6386f4599f
upgrade otel-proto v1.2.0 (#1668)
Co-authored-by: Zhongyang Wu <zhongyang.wu@outlook.com>
2024-04-19 11:40:23 -04:00
Zhongyang Wu fc6f970b80
fix: fail open when upload code coverage fails (#1671) 2024-04-18 16:58:48 -07:00
Severin Neumann 5d214761a0
fix: revert modifications to Apache license (#1664)
Signed-off-by: svrnm <neumanns@cisco.com>
Co-authored-by: Lalit Kumar Bhasin <labhas@microsoft.com>
2024-04-18 16:30:52 -07:00
Cijo Thomas 590c7ab602
Add benchmarks to show cost of random generation (#1667) 2024-04-17 16:02:04 -07:00
Lalit Kumar Bhasin 758cdd7fc0
Add custom serde encoding/decoding for timestamp (#1666) 2024-04-17 11:57:23 -04:00
Lalit Kumar Bhasin 2286378632
CI fix (#1665) 2024-04-16 14:53:59 -04:00
Lalit Kumar Bhasin f203b0327f
Replace unmaintained actions-rs/toolchain action. (#1655)
Co-authored-by: Zhongyang Wu <zhongyang.wu@outlook.com>
2024-04-15 12:59:00 -04:00
Lalit Kumar Bhasin d5392dc1df
[CI fix] Compile proto files with latest prost (#1658) 2024-04-07 13:05:30 -07:00
Roger Coll ed1d128498
test: wrap default batch test with temp_env (#1653)
Co-authored-by: Zhongyang Wu <zhongyang.wu@outlook.com>
2024-04-04 11:14:24 -07:00
Roger Coll 04a800c1b6
test: increase Telemetry resource testing coverage (#1646) 2024-04-03 09:18:55 -07:00
Lalit Kumar Bhasin 278f5c7092
Add benchmark for opentelemetry-appender-tracing (#1649) 2024-03-29 11:58:27 -04:00
Cijo Thomas 5b5cb618cd
Nit fixes to releasing doc (#1648) 2024-03-28 23:01:53 -04:00
Cijo Thomas aa7065fb08
Prepare for opentelemetry-http release (#1647) 2024-03-28 15:00:25 -04:00
Zhongyang Wu 8483914c52
fix: send propagator error to global error handler (#1640) 2024-03-28 14:47:29 -04:00
Luis Osta 936c46639a
Add Rust TLS Feature Flag For `opentelemetry-http` (#1638)
Similar issue to what #472 but for opentelemetry-http
Please provide a brief description of the changes here.
Added new feature flag for the opentelemetry-http crate to enable rustls instead of openssl
2024-03-25 20:01:06 +01:00
Yuta Yamaguchi 815e3874a2
Use semantic conventions in examples (#1639)
Co-authored-by: Cijo Thomas <cijo.thomas@gmail.com>
2024-03-25 12:27:25 -04:00
Zhongyang Wu 9fe943d535
chore: fix rust 1.77 lints (#1641) 2024-03-25 11:53:39 -04:00
Cijo Thomas e0bb2b6b03
Remove unwanted dependency on sdk in tracingappender (#1634) 2024-03-20 13:23:13 -04:00
Harold Dost e98c61ce73
opentelemetry-sdk: Update changelog (#1633) 2024-03-19 15:49:55 -07:00
Harold Dost 1e36840903
Simplify the workspace. (#1632) 2024-03-19 18:02:10 -04:00
Lalit Kumar Bhasin ab39fd2df8
Add add_link API (#1515)
Co-authored-by: Harold Dost <github@hdost.com>
Co-authored-by: Cijo Thomas <cijo.thomas@gmail.com>
Co-authored-by: Zhongyang Wu <zhongyang.wu@outlook.com>
2024-03-19 13:43:22 -04:00
Roger Coll 13c9dc5104
Remove os and process resource detectors (#1624)
Co-authored-by: Cijo Thomas <cithomas@microsoft.com>
Co-authored-by: Zhongyang Wu <zhongyang.wu@outlook.com>
Co-authored-by: Cijo Thomas <cijo.thomas@gmail.com>
2024-03-19 13:19:31 -04:00
Sreeraj Rajan a7a47a745d
replace usages of TestSpanExporter with InMemorySpanExporter (#1626) 2024-03-17 10:59:51 -07:00
Lalit Kumar Bhasin bae8fb3321
Add global::meter_provider_shutdown (#1623)
Co-authored-by: Cijo Thomas <cithomas@microsoft.com>
Co-authored-by: Zhongyang Wu <zhongyang.wu@outlook.com>
2024-03-15 21:33:12 -04:00
Cijo Thomas a4fae95bd6
Remove unnecessary flush from tests (#1622) 2024-03-15 01:12:47 -04:00
Cijo Thomas 9f0ac7daab
Add test to validate log shutdown (#1620) 2024-03-14 11:40:06 -04:00
Sreeraj Rajan b7b7d7ea5d
remove dependency of urlencoding crate (#1615)
Co-authored-by: Cijo Thomas <cijo.thomas@gmail.com>
Co-authored-by: Lalit Kumar Bhasin <lalit_fin@yahoo.com>
2024-03-14 02:33:45 -04:00
masato-hi 5ef3fd31df
Fixed a problem that caused response errors when compression is enabled. (#1621) 2024-03-14 02:21:47 -04:00
Cijo Thomas a8b308ae92
Fix aggregation bug due to stale hash value (#1422) 2024-03-12 21:27:48 -07:00
Zhongyang Wu 69f50f5256
feat: allow user to attach resource to every metrics. (#1608)
Co-authored-by: Cijo Thomas <cijo.thomas@gmail.com>
2024-03-12 15:09:40 -04:00
Cijo Thomas 35c7803c5b
More nit fixes to opentelemetry benches (#1617) 2024-03-12 11:13:34 -04:00
Cijo Thomas a80dedf37c
Add more tests to Metric SDK aggregation (#1600) 2024-03-12 01:56:07 -04:00
Cijo Thomas d5bf258cc8
Use regular lock for simplespanprocessor (#1612) 2024-03-12 01:43:35 -04:00
Cijo Thomas a34c5ee35f
Refactory opentelemetry benchmarks (#1614) 2024-03-11 17:39:16 -07:00
Lalit Kumar Bhasin df12c2cce0
Disable compiler optimization for noop benchmark tests (#1613)
Co-authored-by: Cijo Thomas <cijo.thomas@gmail.com>
2024-03-11 18:16:31 -04:00
Lalit Kumar Bhasin 440725ed69
Fix CI (#1611) 2024-03-11 18:02:51 -04:00
Lalit Kumar Bhasin e816cb926d
Adding noop metrics benchmark (#1607) 2024-03-10 19:51:48 -07:00
Harold Dost 1904d34e15
Add RELEASING.md documentation. (#1555)
Co-authored-by: Cijo Thomas <cithomas@microsoft.com>
Co-authored-by: Lalit Kumar Bhasin <lalit_fin@yahoo.com>
Co-authored-by: Zhongyang Wu <zhongyang.wu@outlook.com>
Co-authored-by: Cijo Thomas <cijo.thomas@gmail.com>
2024-03-08 11:08:05 -05:00
Harold Dost bcf1205799
Add External Type Checking (#1603)
The purpose of this is to ensure we understand the API surface area. Anything exposed by a crate like a type can affect the possible compatibility. This means that if we bump an external type it could cause breaking changes. This tracks them to limit this possibility.

Affected Crates:

opentelemetry-otlp
opentelemetry-zipkin
2024-03-08 15:19:15 +08:00
Lalit Kumar Bhasin 4aa4827191
Update semantic convention to v1.24.0 (#1596)
Co-authored-by: Cijo Thomas <cithomas@microsoft.com>
2024-03-05 01:28:33 -05:00
Cijo Thomas 7cff678865
Add test to confirm bug in metrics sdk (#1597) 2024-03-05 00:39:34 -05:00
Johannes Tax 58ec379c2a
Support URL-encoded values for `OTEL_EXPORTER_OTLP_HEADERS` (#1578)
Co-authored-by: Lalit Kumar Bhasin <lalit_fin@yahoo.com>
Co-authored-by: Cijo Thomas <cijo.thomas@gmail.com>
2024-02-29 21:34:03 -05:00
David Cook 7bdbc47a44
Fix errors in changelogs (#1584)
Co-authored-by: Cijo Thomas <cijo.thomas@gmail.com>
2024-02-29 12:30:23 -05:00
Cijo Thomas 1f7b6c4e3f
Tweaks to readme docs (#1588) 2024-02-28 22:12:28 -08:00
Dimitris Apostolou 5e67cae020
fix: fix feature = "cargo-clippy" deprecation (#1587)
Co-authored-by: Cijo Thomas <cijo.thomas@gmail.com>
2024-02-28 11:40:07 -05:00
Cijo Thomas eb1a09bd64
Rewrite readme page for opentelemetry crate (#1586) 2024-02-28 10:38:29 -05:00
Jonas Platte ef4701055c
otlp: Add DeltaTemporalitySelector (#1568)
Co-authored-by: Cijo Thomas <cijo.thomas@gmail.com>
2024-02-27 12:50:01 -05:00
Cijo Thomas fe85521c89
Readme fixes part2 (#1583) 2024-02-26 22:15:47 -08:00
Cijo Thomas 186c0b0727
Modify main readme and contrib guide (#1581) 2024-02-27 00:07:09 -05:00
Cijo Thomas 19b9878ccb
Prepare for SDK 0.22.1 hotfix release (#1579) 2024-02-26 13:30:20 -05:00
Cijo Thomas 5542f37b46
Fix span kind being always internal (#1576) 2024-02-26 12:33:25 -05:00
Dirkjan Ochtman ab9415a8cd
Bump versions to prepare for release v0.22 (#1539)
Co-authored-by: Zhongyang Wu <zhongyang.wu@outlook.com>
2024-02-24 19:46:48 -08:00
Zhongyang Wu 64225243c0
fix: disable workspace default feature (#1562)
Co-authored-by: Harold Dost <github@hdost.com>
Co-authored-by: Ed Morley <501702+edmorley@users.noreply.github.com>
Co-authored-by: Cijo Thomas <cijo.thomas@gmail.com>
2024-02-24 16:27:57 -08:00
Marcus Pettersen Irgens d88e83d3b8
Fix invalid import paths under "Getting Started" (#1574) 2024-02-25 00:45:00 +08:00
Sreeraj Rajan 27cf653ffd
Deprecate AWS XrayIdGenerator (#1573)
Deprecates the XrayIdGenerator in the opentelemetry core sdk.

Now available in opentelemetry-aws
Relates #1489
2024-02-25 00:03:15 +08:00
Ed Morley 188a26c802
Switch from the chrono `clock` feature to `now` (#1569)
In #1192, chrono was added as a dependency of the opentelemetry-stdout crate in order to support outputting timestamps in human readable format.

In that PR, all Chrono features were disabled apart from the clock feature.

However, since that change landed, chrono v0.4.32 has added support for an even finer-grained feature named now, which is a subset of the clock feature - that excludes timezone support, and so avoids pulling in many timezone related crates.
2024-02-24 15:18:30 +08:00
Robert Collins 47b928ebf0
Disable default features on reqwest (#1570) 2024-02-23 20:35:27 -08:00
Zhongyang Wu 98cd103234
chore: skip coverage check for dependencies update (#1558)
skip coverage check if the PR is labeled dependencies
2024-02-23 15:53:58 +08:00
Harold Dost 36c2a8e0a3
deprecation(opentelemetry-jaeger): Add deprecation notice. (#1560)
- Add deprecation flags to the various components to give notices in users compilers.
- Add more definition around the deprecation in the README.
- Add a deprecation badge for crates.io.

Relates #995
2024-02-19 10:01:44 +08:00
Harold Dost 11694455a9
opentelemetry-otlp: Default the port correctly. (#1556)
Signed-off-by: Harold Dost <h.dost@criteo.com>
Co-authored-by: Cijo Thomas <cijo.thomas@gmail.com>
2024-02-18 12:28:11 -05:00
James Lucas 4c22cf67ba
Safer endpoint Uri construction (#1553)
Make endpoint Uri construction less fragile by stripping out duplicate slashes.

Fixes #997

The functionality to append the signal path to a user-supplied tracing endpoint is already in place. However, it does so in a way that is likely to break for any user who's passing the string value of a Uri or Url, which will have a trailing slash appended to them. This attempts to fix that issue.

There were other possible changes discussed but ever implemented/merged in #1056. This PR attempts to keep it simple by just changing existing behavior to not break in a common use case.
2024-02-18 14:19:37 +01:00
Lalit Kumar Bhasin 1be83bbfea
Add markdown link CI check (#1540)
Co-authored-by: Cijo Thomas <cijo.thomas@gmail.com>
2024-02-17 00:50:45 -08:00
dependabot[bot] 59f53713c0
Bump arduino/setup-protoc from 1 to 3 (#1541)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-02-17 00:03:15 -08:00
dependabot[bot] 895334e1e0
Update typed-builder requirement from 0.12 to 0.18 (#1549)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-02-17 00:02:54 -08:00
dependabot[bot] 1b39800172
Bump actions/checkout from 1 to 4 (#1542)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-02-17 14:57:29 +08:00
Vasiliy Taranov ed7a7099d1
Add dependabot (#1522)
Co-authored-by: Lalit Kumar Bhasin <lalit_fin@yahoo.com>
Co-authored-by: Lalit Kumar Bhasin <labhas@microsoft.com>
2024-02-16 16:48:37 -05:00
Dirkjan Ochtman 93f206a1eb
Remove support for surf HTTP client (#1537) 2024-02-16 12:29:18 -05:00
Yuta Yamaguchi d96d59fe7f
fix(doc): update EnvResourceDetector specification link (#1538)
Co-authored-by: Cijo Thomas <cijo.thomas@gmail.com>
2024-02-16 10:41:52 -05:00
Dirkjan Ochtman fe2b2d54e8
Upgrade to tonic 0.11 and prost 0.12 (#1536) 2024-02-16 10:24:22 -05:00
Dirkjan Ochtman c05b23d48d
Clean up dependencies (#1535)
Co-authored-by: Cijo Thomas <cijo.thomas@gmail.com>
2024-02-15 18:03:19 -05:00
Dirkjan Ochtman cad63b69dd
Remove the option of using grpcio for gRPC (#1534) 2024-02-15 17:41:00 -05:00
Lalit Kumar Bhasin 476f2c11a9
Optimize Resource Sharing Across Exporters with Arc Implementation (#1526)
Co-authored-by: Cijo Thomas <cijo.thomas@gmail.com>
Co-authored-by: Cijo Thomas <cithomas@microsoft.com>
2024-02-15 12:43:48 -05:00
Matthew Shapiro 650904f8b6
Reduce cost of no attribute counters (#1519)
Co-authored-by: Cijo Thomas <cijo.thomas@gmail.com>
2024-02-15 12:06:55 -05:00
Lalit Kumar Bhasin b35bf380b7
CI failure fix for external-type-check (#1532) 2024-02-15 08:17:31 -08:00
Cijo Thomas f80d7547c4
Make stress test more realistic (#1531) 2024-02-14 15:58:47 -05:00
Matthew Boddewyn 054b0c891d
Ignore flaky opentelemetry-jaeger tests (#1529) 2024-02-14 11:47:24 -05:00
Daniel Izquierdo 87153d30fa
Test successful collection by PeriodicReader (#1521)
Add a success scenario test for PeriodicReader as suggested in #1481 (comment)
2024-02-14 10:06:28 +01:00
Cijo Thomas 49f1be6164
Add basic doc comments for opentelemetry-http (#1528) 2024-02-14 00:45:19 -05:00
Zhongyang Wu 64b11e04b9
fix: don't return empty string when trace header is not present (#1523) 2024-02-14 00:05:48 -05:00
Daniel Izquierdo 3f327a1ecb
Fix error message caused by race condition when using PeriodicReader (#1481)
Co-authored-by: Cijo Thomas <cijo.thomas@gmail.com>
Co-authored-by: Lalit Kumar Bhasin <lalit_fin@yahoo.com>
2024-02-08 13:53:04 -05:00
Cijo Thomas c60a178f3a
Use consistent style of passing attributes to metrics (#1518) 2024-02-08 12:50:40 -05:00
Zhongyang Wu d7c9ef0eb5
feat(otlp): add integration test setup for traces (#1477) 2024-02-07 21:03:08 -05:00
Harold Dost 80da6564e6
Change to owned LoggerProvider (#1455) 2024-02-07 10:29:56 -05:00
Cijo Thomas 8688e7eaa4
Minor readme fixes for examples (#1513) 2024-02-06 20:01:53 -05:00
Matthew Shapiro aba0af5d66
Revert "Allow precreation of AttributeSets for metrics (#1421)" (#1512) 2024-02-06 17:00:48 -05:00
Zhongyang Wu dd4c13bd69
fix(sdk): fix incorrect doc (#1499)
Co-authored-by: Cijo Thomas <cijo.thomas@gmail.com>
2024-02-02 00:33:30 -05:00
James Lucas 270c857bc6
http: surface errors based on status code (#1484)
Co-authored-by: Cijo Thomas <cijo.thomas@gmail.com>
2024-02-01 15:43:12 -05:00
Mohammad Mustakim Ali d19187db46
chore: Add error logging for failed OpenTelemetry HTTP export (#1498)
Co-authored-by: Lalit Kumar Bhasin <labhas@microsoft.com>
Co-authored-by: Cijo Thomas <cijo.thomas@gmail.com>
2024-02-01 06:46:07 -08:00
Lalit Kumar Bhasin 57c3aa3189
Enable doc generation for testing module for InMemory*Exporters. (#1503)
Co-authored-by: Cijo Thomas <cijo.thomas@gmail.com>
2024-01-31 22:58:23 -08:00
Mike Goldsmith 989fa3b595
Move MikeGoldsmith to emeritus (#1504) 2024-01-31 14:22:58 -05:00
Matthew Boddewyn d4a6b3e812
Add initial tests to opentelemetry-appender-log (#1501) 2024-01-31 02:33:32 -05:00
Cijo Thomas 0b2c70398e
Add warning about Log API that is it not for app users (#1502) 2024-01-30 16:15:05 -05:00
Zhongyang Wu e3bee4e5c7
fix(doc): update feature flag lists (#1486) 2024-01-30 13:32:41 -05:00
Matthew Boddewyn 4ea4a61581
Use temp_env when constructing BatchConfig from environment variables in log_processor.rs test (#1496)
Co-authored-by: Cijo Thomas <cijo.thomas@gmail.com>
2024-01-29 23:48:15 -05:00
Bhargav 8237f87f42
Add event_name field to `LogRecord` (#1488) 2024-01-26 18:21:26 -05:00
Matthew Boddewyn 0101233973
Create new opentelemetry-jaeger-propagator library (#1487) 2024-01-26 11:54:16 -05:00
Cijo Thomas 433c1b34e2
Fix tracing grpc example (#1493)
Cleaned up readme as we already removed tracing-opentelemetry and jaeger
from it.
2024-01-25 17:53:23 -08:00
Cosmin Lazar 85f678a601
Remove Batch LogRecord&Span Processor configuration via non-standard environment variables (#1495) 2024-01-25 17:12:31 -05:00
Cosmin Lazar 26600476b3
Consolidate BatchConfig creation and validation via BatchConfigBuilder (#1480) 2024-01-25 12:17:47 -05:00
Lalit Kumar Bhasin 27b19b6026
Update OTLP proto version to 1.1.0 (#1482) 2024-01-24 23:08:55 -05:00
Lalit Kumar Bhasin c7ab26b6ef
Code coverage config cleanup (#1492) 2024-01-24 21:26:41 -05:00
Cijo Thomas de8e7506c5
Add note about stdout exporter (#1491) 2024-01-24 20:55:52 -05:00
Matthew Shapiro 16fd1abb87
Allow precreation of AttributeSets for metrics (#1421) 2024-01-24 15:10:30 -05:00
Zhongyang Wu 5b456ddfde
fix(proto): add `serde(default)` to `Events` and `Status` (#1485)
This should allow all fields in event to be optional, which is needed to
decode JSON strings

## Changes
- add `serde(default)` to `Events` for tonic generated types
- add `serde(default)` to `Status` for tonic generated types

## Merge requirement checklist

* [x]
[CONTRIBUTING](https://github.com/open-telemetry/opentelemetry-rust/blob/main/CONTRIBUTING.md)
guidelines followed
* [x] Unit tests added/updated (if applicable)
* [ ] Appropriate `CHANGELOG.md` files updated for non-trivial,
user-facing changes
* [ ] Changes in public API reviewed (if applicable)
2024-01-22 11:53:16 -08:00
Cosmin Lazar 67e6a71d8c
Expose log batchconfig (#1471) 2024-01-22 12:12:32 -05:00
Olivier Soucy 27d338dd95
Add new benches for logs (#1450)
Implement new bench ideas from this
[PR](https://github.com/open-telemetry/opentelemetry-rust/pull/1431)’s
comments.

Please provide a brief description of the changes here.

## Merge requirement checklist

* [ ]
[CONTRIBUTING](https://github.com/open-telemetry/opentelemetry-rust/blob/main/CONTRIBUTING.md)
guidelines followed
* [ ] Unit tests added/updated (if applicable)
* [ ] Appropriate `CHANGELOG.md` files updated for non-trivial,
user-facing changes
* [ ] Changes in public API reviewed (if applicable)

Co-authored-by: Lalit Kumar Bhasin <lalit_fin@yahoo.com>
2024-01-07 20:43:42 -08:00
Zhongyang Wu 306286e382
fix(proto): use camelCase for json (de)serialization. (#1462)
Part of the effort of #1327 as we need json formats for assertation in
integration tests.

## Changes

- add configuration to serde to deserialize the json in camelCase field
name
- add custom (de)serialization for traceId, spanId as they are
case-insensitive hex encoded string(see
[here](https://opentelemetry.io/docs/specs/otlp/#json-protobuf-encoding))
- add custom (de)serialization for `KeyValue`
- add tests for above, and a test using example json files

## Merge requirement checklist

* [ x]
[CONTRIBUTING](https://github.com/open-telemetry/opentelemetry-rust/blob/main/CONTRIBUTING.md)
guidelines followed
* [x] Unit tests added/updated (if applicable)
* [x] Appropriate `CHANGELOG.md` files updated for non-trivial,
user-facing changes
* [] Changes in public API reviewed (if applicable)
2024-01-05 08:56:35 -08:00
Julian Tescher 7eb4c2704e
Prepare for v0.21.2 release (#1463)
Backport #1434 and #1452 to v0.21.x.
2024-01-04 12:31:44 -05:00
Jesse White 4c5c101253
Fix StatusCode in stdout exporter (#1453) (#1454)
Fixes https://github.com/open-telemetry/opentelemetry-rust/issues/1453

## Changes

Swap the ordinals to match the spec.

Co-authored-by: Lalit Kumar Bhasin <lalit_fin@yahoo.com>
2024-01-04 10:50:00 -05:00
Rodolfo P A f31c4dd1b1
Workspace dependencies (#1457)
Adds shared dependencies to the workspace.
It improves the experience while managing the dependencies.

## Changes

Picked the shared dependencies of the member projects and used added
then to the workspace dependencies, https://crates.io/crates/work_dep
can help with that.

## Merge requirement checklist

* [ ]
[CONTRIBUTING](https://github.com/open-telemetry/opentelemetry-rust/blob/main/CONTRIBUTING.md)
guidelines followed
* [ ] Unit tests added/updated (if applicable)
* [ ] Appropriate `CHANGELOG.md` files updated for non-trivial,
user-facing changes
* [ ] Changes in public API reviewed (if applicable)
2023-12-30 15:46:34 -08:00
Zhongyang Wu 5aa0311de8 chore: fix 1.75 linter errors 2023-12-28 23:34:42 +01:00
Harold Dost f9b08c1080 chore: Pin nightly version for check-external-types
This is is because the versions are extremely tied to each other.
2023-12-27 10:18:49 +01:00
Olivier Soucy ce64d9fa81
Use good OpenTelemetry conventions for attributes in appender-tracing (#1448)
Also, only removed duplicates attributes from the log crate. I think it
is a good compromise for a little more performance.

Fixes #1445
2023-12-26 23:21:03 +01:00
Ameer Ghani bd572d5469
Fix max_scale validation of exponential histogram configuration (#1452)
`metrics::Aggregation::validate()` has a bug that limits `max_scale` of
a `Base2ExponentialHistogram` to the interval `[10, 20]` instead of the
expected `[-10, 20]`.
2023-12-21 21:23:51 -05:00
Jasper Zeng 7f77ec69f4
feat: make trace state can be propagated for dropped sampler (#1435) 2023-12-19 21:13:13 -05:00
Bouke van der Bijl 09ae384174
Add impl Into to some logs methods (#1442)
This adds `impl Into` to two logs methods, the first to match the
equivalent metrics/traces method and the other to make `with_body` more
ergonomic so you can do `with_body("hello")`
2023-12-19 07:20:42 +01:00
Cijo Thomas d3497392fb
Minor doc fix to reflect correct crate for runtime (#1449)
Fixes https://github.com/open-telemetry/opentelemetry-rust/issues/1357
2023-12-18 21:33:27 -05:00
Cijo Thomas 03b42ac4e4
Fix changelog (#1447) 2023-12-18 20:50:19 -05:00
Olivier Soucy 4e80e3a2eb
Fix opentelemetry appender tracing test (#1441) 2023-12-13 15:06:54 -05:00
Julian Tescher 7d0b80ea85
Fix delta aggregation metric reuse (#1434) 2023-12-12 21:29:07 -05:00
Olivier Soucy fdacd58e70
Bench for logs (#1431) 2023-12-12 20:01:39 -05:00
Jacob Rothstein bd3ba65546
Add await to async trace documentation (#1440) 2023-12-12 18:22:26 -05:00
Lalit Kumar Bhasin 038b91b651
Add experimental synchronous gauge (#1410) 2023-12-12 15:23:42 -05:00
Cijo Thomas 1dd269af45
Update meeting time to 9 AM PT (#1438) 2023-12-11 21:15:23 -05:00
Thomas Knickman 8f237f9d99
fix(docs): dead examples link in README.md (#1436) 2023-12-11 18:21:34 -05:00
Jacob Rothstein 443f68b1b8
Add trillium-opentelemetry to readme (#1430) 2023-12-07 19:54:25 -08:00
Olivier Soucy 66c1d5f734
Normalized metadata in opentelemetry-appender-tracing. (#1380) 2023-12-07 13:53:30 -05:00
Lalit Kumar Bhasin 670d34a460
Remove `tracing-opentelemetry` dependency from `tracing-grpc` example (#1426) 2023-12-07 13:12:49 -05:00
Jasper Zeng 1a3f368347
feat: omit empty otel_scope_info and otel_target_info metrics (#1428)
Fixes #1282 

* omit otel_scope_info and otel_target_info metrics when scope
attributes and resource attributes are empty.
* Update `CHANGELOG.md`
2023-12-06 09:43:09 +01:00
Olivier Soucy ec38660f69
Fix metric_counter bench (#1424) 2023-12-04 19:59:54 -05:00
Ho Kim 10456d4684
Add schemars support for opentelemetry-proto (#1419) 2023-12-01 12:49:12 -05:00
Cijo Thomas 0862af1285
Add tests to validate spatial aggregation (#1416) 2023-11-30 18:26:59 -05:00
Matthew Shapiro 359424776c
Ignore intellij directory (#1417) 2023-11-30 17:32:43 -05:00
Cijo Thomas 772f75ad48
Invalid View to proceed as if view did not exist (#1408) 2023-11-30 12:24:14 -05:00
Cijo Thomas 8b838fc07e
Add tests for tracing appender (#1415) 2023-11-30 08:53:18 -08:00
Julian Tescher cd23ec279a
Remove old global meter provider shutdown method (#1412)
This change removes the old `global::shutdown_meter_provider` method
which is not part of the metrics API spec, and properly documents the
`SdkMeterProvider::shutdown` method which is spec compliant.
2023-11-29 23:56:20 +01:00
Matthew Shapiro c0104d3f54
Precalculated attribute set hashes (#1407)
The hash of `AttributeSet`s are expensive to compute, as they have to be
computed for each key and value in the attribute set. This hash is used
by the `ValueMap` to look up if we are already aggregating a time series
for this set of attributes or not. Since this hashmap lookup occurs
inside a mutex lock, no other counters can execute their `add()` calls
while this hash is being calculated, and therefore contention in high
throughput scenarios exists.

This PR calculates and caches the hashmap at creation time. This
improves throughput because the hashmap is calculated by the thread
creating the `AttributeSet` and is performed outside of any mutex locks,
meaning hashes can be computed in parallel and the time spent within a
mutex lock is reduced. As larger sets of attributes are used for time
series, the benefits of reduction of lock times should be greater.

The stress test results of this change for different thread counts are:

| Thread Count | Main        |  PR           |
| -------------- | ---------- | --------- |
| 2                       | 3,376,040 | 3,310,920 |
| 3                       | 5,908,640 | 5,807,240 |
| 4                       | 3,382,040 | 8,094,960 |
| 5                       | 1,212,640 | 9,086,520 |
| 6                       | 1,225,280 | 6,595,600 |

The non-precomputed hashes starts feeling contention with 4 threads, and
drops substantially after that while precomputed hashes doesn't start
seeing contention until 6 threads, and even then we still have 5-6x more
throughput after contention due to reduced locking times.

While these benchmarks may not be "realistic" (since most applications
will be doing more work in between counter updates) it does show a
benefit of better parallelism and the opportunity to reduce lock
contention at the cost of only 8 bytes per time series (so a total of
16KB additional memory at maximum cardinality).
2023-11-28 18:05:44 +01:00
Lalit Kumar Bhasin 897e70a093
Add tracing-http example (#1404)
Modified version of the
[tracingresponse](https://github.com/open-telemetry/opentelemetry-rust-contrib/tree/main/examples/traceresponse)
example (in `contrib` repo) to demonstrate context propagation from
client to server. The example
- Removes the code to propagate trace-context as part of response
headers from server to client, as the W3C specs is still in draft
(https://w3c.github.io/trace-context/#trace-context-http-response-headers-format),
and also the propagator is part of contrib repo.
- Modify the HTTP server and client code to look more complete and also
demonstrate the context propagation across async delegates.
**_Server_** - Enhance the server's request handling, by adding support
for `/echo` and `/health` endpoints. Upon receiving the request, the
server now creates a child span, linked to the originating remote span,
and the request is forwarded to its respective delegate async task.
Furthermore, within each async task, a subsequent child span is spawned,
parented by the initial child span. This nested span creation
exemplifies the effective propagation of tracing context through the
multiple layers of async execution.
**_Client_** - The client sends requests for `/echo` and `/health`
within the context of the client root span.
2023-11-28 09:32:55 +01:00
Cijo Thomas fcd12eb2c2
Fix CI check for docs (#1406) 2023-11-27 17:29:29 -05:00
Kevin Sun d52ff83f30
opentelemetry-proto-support-feature-gen-grpcio-messages (#1316)
In some cases (e.g. rust wasm), it is not possible to have
network-related crates (e.g. grpcio) included, and we would like to
support protobuf encoding support. so similar to the already existing
feature `gen-tonic-messages`, here introduce a feature
`gen-grpcio-messages` to support protobuf encoding without any network
client/server included.

## Changes

replaces some of existing `gen-grpcio` to `gen-grpcio-messages`
enables feature `gen-grpcio` will automatically enable
`gen-grpcio-messages`
2023-11-27 11:55:00 -05:00
Zhongyang Wu f2d57b13cc
fix(sdk, zipkin, otlp): use `temp_env` for testing (#1403)
Fixes #1383
2023-11-27 08:58:54 +01:00
Matthew Shapiro 075d26cf23
Improve cost of creating AttributeSets (#1379) 2023-11-22 15:24:40 -05:00
Cijo Thomas 073f7a6b6a
Remove jaeger crate from tracing example deps (#1393) 2023-11-22 13:54:48 -05:00
Cijo Thomas 6e1c8c1844
Cleanup indexmap from allowed external types (#1392)
More cleanups following
https://github.com/open-telemetry/opentelemetry-rust/pull/1381/files
2023-11-22 10:26:27 -08:00
Cijo Thomas 04c863e560
Add focused benchmark for metric hotpath (#1389) 2023-11-22 12:50:33 -05:00
Rene B 32299790f1
Add missing event timestamps to `opentelemetry-stdout` (#1391) 2023-11-22 12:19:31 -05:00
Cijo Thomas 3939ab58fe
Test to validate identical instruments are merged (#1385) 2023-11-21 12:33:51 -05:00
Zhongyang Wu 7848755c71
fix(api): move composite propagator to API (#1373)
Move `TextMapCompositePropagator` from `opentelemetry-sdk` to `opentelemetry` crate. 

Fixes #1013
2023-11-21 09:26:46 +01:00
Cijo Thomas 28aca997e5
Attempt to write metric tests with inmemoryexp (#1382) 2023-11-20 12:31:02 -05:00
harscoet abc23c166b
Run opentelemetry-jaeger tests consecutively (#1384)
Limit threads to 1 (to force tests to run
consecutively) to temporarily fix random [failures](https://github.com/open-telemetry/opentelemetry-rust/actions/runs/6915742069/job/18815025248)
during `opentelemetry-jaeger` tests, due to environment variable updates
from parallel tests
If you run this command line multiple times, you should be able to
reproduce it (`test_resolve_timeout` and `test_resolve_endpoint` are
updating some environment variables)
```shell
cargo test --manifest-path=opentelemetry-jaeger/Cargo.toml --all-features collector -- --test-threads=5
```
2023-11-19 08:38:02 +01:00
harscoet 9e2e3db72d
OTLP tonic metadata from env variable (#1377)
Fixes https://github.com/open-telemetry/opentelemetry-rust/issues/1336

As per the
[specs](https://github.com/open-telemetry/opentelemetry-specification/blob/v1.25.0/specification/protocol/exporter.md#specifying-headers-via-environment-variables),
the custom headers for OTLP exporter can be specified through env
variables - `OTEL_EXPORTER_OTLP_HEADERS`,
`OTEL_EXPORTER_OTLP_TRACES_HEADERS`,
`OTEL_EXPORTER_OTLP_METRICS_HEADERS`.
This PR completes the work already done in PR
open-telemetry/opentelemetry-rust#1290 adding support for tonic metadata
To reproduce the same behavior as http exporter, the env-variable takes
precedence (as discussed in
open-telemetry/opentelemetry-rust-contrib#10)

* Move common code for http and tonic exporters in `exporter/mod.rs`
(function to parse header from string and test helper to run tests with
isolated env variables)
I wanted to minimize the changes but maybe it should be a good idea to
use a crate like https://crates.io/crates/temp-env for environment
related testing
2023-11-19 08:32:10 +01:00
Cijo Thomas a70bb74080
Remove evicted q and hmap (#1381) 2023-11-17 12:08:21 -05:00
Lalit Kumar Bhasin 33b5e9b4e2
Fix metric collections during PeriodicReader shutdown (#1375) 2023-11-15 21:07:37 -05:00
Lalit Kumar Bhasin c06c04bb12
Remove API for Creating Histograms with signed integers. (#1371)
As per the OTel [specs], the value to be recorded with histogram instrument SHOULD be non-negative. Removing the existing method to record signed integer values.

> The value is expected to be non-negative. This API SHOULD be documented in a way to communicate to users that > this value is expected to be non-negative. This API SHOULD NOT validate this value, that is left to implementations
> of the API.

[specs]: https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/api.md#histogram
2023-11-15 15:58:31 +01:00
Shaun Cox a2c0dd8d10
make severity of level computations const (#1369) 2023-11-15 10:39:55 +01:00
K.J. Valencik 41c6ea8956
Use custom channel in exporters if configured (#1335) 2023-11-14 17:28:55 -05:00
Harold Dost 59728c8947
Remove contrib crates. (#1366) 2023-11-13 22:11:09 +01:00
Julian Tescher 6175c3f1ed
Prepare for patch release (#1368) 2023-11-13 15:18:30 -05:00
Cijo Thomas cb2d127fe0
Flush fix for SimpleLogProcessor (#1308)
SimpleLogProcessor's `force_flush` was incorrectly implemented as it did not do anything assuming there was nothing to flush. But the SimpleLogProcessor uses a queue with pub-sub mechanism to operate, so flush is not a no-op. This is handled correctly for SimpleSpanProcessor.

Instead of borrowing the approach from SimpleSpanProcessor, I have refactored the SimpleLogProcessor to use no queue and instead use a simple Mutex protected exporter/shutdown. I feel this is sufficient (and want to port this to SimpleSpanProcessor as well), but would like to get feedback on the approach - was there some scenario which prompted the queue/pub-sub for SimpleProcessors? Or this approach is sufficient?

There should not be any perf concerns as SimpleProcessors are used for learning/dev scenarios, and not for production. (Except when you are exporting to operating system native tracing like etw, user_events, but for them we have written RentrantProcessor separately.)
2023-11-12 22:32:38 +01:00
Kristopher Wuollett dd03fdae1e
Add generated modules that output const &str for `tracing` compatibility (#1334)
* feat: add generated modules that output const &str for tracing compatibility

* fix: add tracing as a dev-dependency for doc examples

* fix: remove unused code

* fix: remove tracing examples from semconv docs

* docs: remove extra whitespace that was added previously
2023-11-12 10:37:04 -08:00
Harold Dost 5fc4101826
Use faster Rng in RandomIdGenerator (0%-6% performance improvement) (#1106)
Move to SmallRng from ThreadRng

SmallRng provides 0-6% improvement in Traces.

Relates #808
2023-11-12 16:48:42 +01:00
Julian Tescher 7bb97d5e30
Return consistent `Meter` for a given `MeterProvider` (#1351) 2023-11-10 15:10:58 -05:00
Lalit Kumar Bhasin a74ecd1316
[Tracing Appender] Propagate event name to exporters (#1346) 2023-11-10 12:39:06 -05:00
Cijo Thomas 500fdfca09
Nit fixes to md file to reduce warnings (#1364) 2023-11-10 10:50:22 -05:00
Cijo Thomas ddfe9ffa2b
Requesting to move Cijo Thomas from Approver to Maintainer (#1355) 2023-11-09 18:32:28 -05:00
Julian Tescher 5527a11b69
Fix metric export data for unused gauges (#1363) 2023-11-09 18:24:28 -05:00
Cijo Thomas 4f1c3a26ff
Improve contributing guidelines (#1354) 2023-11-09 15:26:21 -05:00
Cijo Thomas d7e46292fd
Span events stored as Vector instead of EvictedQueue (#1350) 2023-11-09 10:48:47 -05:00
Dirkjan Ochtman 747895423e
Move @djc to emeritus (#1359) 2023-11-09 10:42:17 -05:00
Cijo Thomas 154644013f
Use HashMap instead of IndexMap in LogRecord (#1353) 2023-11-09 10:33:50 -05:00
Julian Tescher 74d294c18d
prometheus: Ignore unknown instrument units (#1348)
## Motivation

The [metric unit semantic conventions] suggest that integer counts
should use annotations (e.g. `{packet}`), which breaks the current unit
appending logic as they are not properly escaped.

[metric unit semantic conventions]: https://github.com/open-telemetry/semantic-conventions/blob/v1.23.0/docs/general/metrics.md#instrument-units

## Solution

Ignore unknown units (including annotations) as other language
implementations currently do. This change also removes the `$` mapping
as it is not UCUM.
2023-11-08 11:18:13 -05:00
Harold Dost b8ea7c10e8
Add config.yml for Templates. (#1352) 2023-11-08 11:12:57 -05:00
Shaun Cox 5d5296b138
More distinct naming of metrics constructs in the SDK (#1328) 2023-11-08 11:12:26 -05:00
Harold Dost 4c3f8a0484
Add Issue Templates. (#1347)
Signed-off-by: Harold Dost <h.dost@criteo.com>
2023-11-07 11:40:04 -05:00
Cijo Thomas 6c3dc789fb
Add jaeger tracing example to main examples (#1345) 2023-11-07 11:38:50 -05:00
Harold Dost ab969bf571
Requesting Maintainership for h.dost (#1342) 2023-11-07 11:36:49 -05:00
Cijo Thomas 4cff5c69b3
Span links stored as Vector instead of EvictedQueue (#1313) 2023-11-07 11:19:12 -05:00
Julian Tescher 47881b20a2
Prepare for v0.21.0 release (#1343) 2023-11-06 18:35:16 -05:00
Zhongyang Wu 4dd54a2ab3
Env over compling time config (#1323)
* feat: favor env vars in jaeger exporters

* feat: collectors

* fix unit tests

* unit tests

* unit tests

* add change logs
2023-11-05 21:56:51 -08:00
Kristopher Wuollett e265d24fe4
fix: specify portable sed arguments (#1332)
Copied from ca08c5a34a/tools/format.sh (L16-L19).
2023-11-01 10:37:55 -07:00
Harold Dost ed97a1bd9e
Remove opentelemetry-dynatrace source. (#1321)
We will no longer build/support it as Dynatrace is migrating towards
OTLP ingestion.

Relates #1099
2023-10-26 22:11:57 -07:00
Jan Kühle 2022ace7b4
Move RuntimeChannel type arg T to associated types (#1314)
RuntimeChannel::batch_message_channel needs to be generic over the
message type. The type used to be declared on the RuntimeChannel<T>
trait. This means a RuntimeChannel can only be used with one particular
message type, which feels unfortunate.

    fn install<R: RuntimeChannel<??::BatchMessage>>(runtime: R) {
        // Can't use the same runtime here. :-(
	TracerProvider::builder().with_batch_exporter(e, runtime);
	LoggerProvider::builder().with_batch_exporter(e, runtime);
    }

This change moves the type argument to the batch_message_channel<T>
function and the associated types Receiver<T> and Sender<T>. Channels
are still specific to a message type, but a RuntimeChannel can be used
with any number of message types.

    fn install<R: RuntimeChannel>(runtime: R) {
        // It works. :-)
	TracerProvider::builder().with_batch_exporter(e, runtime);
	LoggerProvider::builder().with_batch_exporter(e, runtime);
    }

This also means the BatchMessage types no longer need to be public.
2023-10-26 22:11:30 -07:00
Harold Dost ad18037d75
opentelemetry-dynatrace: Release 0.4.0 [#1319] (#1319)
Add additional warning.

NOTE: Not going to bump the Otel Version since this crate will be
removed after this.

Signed-off-by: Harold Dost <h.dost@criteo.com>
2023-10-26 16:30:23 -04:00
Harold Dost bcab756503 Bump MSRV in Cargo.toml files.
Signed-off-by: Harold Dost <h.dost@criteo.com>
2023-10-26 10:33:28 +02:00
Harold Dost dd9ff55c45 Bump the MSRV to 1.65
The goal of this is to enable GATs https://blog.rust-lang.org/2022/10/28/gats-stabilization.html

Relates to #1314

Signed-off-by: Harold Dost <h.dost@criteo.com>
2023-10-26 10:33:28 +02:00
Harold Dost 28d8cf9b6f
Add files to expose the currently used external types. (#1303)
To get ready for release candidate, we should keep track of these as it
affects how stable we can consider being.

Add check to CI.
2023-10-23 14:27:06 -07:00
Lalit Kumar Bhasin aa586cbf7e
Fix semconv template files (#1312)
* fix links

* fix

* fix template

* fix template further

* add generated resource file

* fix the doc comments
2023-10-22 14:34:03 -07:00
Ruihang Xia 4db67d52fe
chore: fix unused_doc_comments warning (#1309)
Signed-off-by: Ruihang Xia <waynestxia@gmail.com>
2023-10-20 10:22:53 -07:00
Cijo Thomas a612972c20
SpanAttributes modified to use Vec instead of OrderMap/EvictedHashMap (#1293)
* Use Vec for span attributes instead of HashMaps

* fix bench

* revert

* add dropped_attributes_count back

* fix more exporters

* fix datadog exporter

* fix stackdriver exporter

* fix changelogs

* fix doc

* fix lint and other issues

* more fix

* more fixes

* fix clippy

* add comment

* refix test

* ignore dd tests

* fmt

* tests added

* fix comment and tes

* fmr
2023-10-20 10:21:56 -07:00
Eric Zhang e848caf577
Remove extra generic from with_http_client (#1307)
* Remove extra generic from with_http_client

This generic type parameter is not being used anywhere, so when you try to use `with_http_client`, it requires you to specify a dummy type that implements `HttpClient + 'static`.

So this does not work:

```rust
new_pipeline().with_http_client(Arc::new(client))
```

But these work, even though they don't necessarily match the actual type of `client`:

```rust
new_pipeline::<Arc<dyn HttpClient>>().with_http_client(Arc::new(client))

new_pipeline::<reqwest::Client>().with_http_client(Arc::new(client))
```

* Add test and CHANGELOG entry
2023-10-20 10:14:27 -07:00
Cijo Thomas 2fb0c2e29f
Add tracing tests using inmemoryexporter (#1305)
* Add tracing tests using inmemoryexporter

* fix format

* no test postfx
2023-10-20 10:12:31 -07:00
Lalit Kumar Bhasin 03b94b35c9
Add OTLP HTTP Log Exporter example using tracing appender. (#1294)
* initial commit

* fix

* remove jaeger exporter

* add service_name as CARGO_BIN_NAME

* remove jaeger container, as we instead use Debug Exporter

* Update opentelemetry-otlp/examples/basic-otlp-http/README.md

Co-authored-by: Cijo Thomas <cithomas@microsoft.com>

* only keep required ports

* read binary name at compile time

---------

Co-authored-by: Cijo Thomas <cithomas@microsoft.com>
2023-10-17 08:23:24 -07:00
Julian Tescher 9700219dee
Use display for standard trace and span id formats (#1299)
Have consistent padding and hex casing by using the `Display` impl of
trace and span ids which is in accordance with the [spec].

[spec]: https://github.com/open-telemetry/opentelemetry-specification/blob/v1.26.0/specification/trace/api.md#retrieving-the-traceid-and-spanid
2023-10-16 18:20:50 -04:00
Lalit Kumar Bhasin 175f1cfe4d
Replace regex crate with glob crate (#1301)
* remove regex crate

* update cargo.toml

* fix dependency

* add unittest

* add changelog

* order tests

* fix unit test

* do disk cleanup before tests

* fix disk cleanup

* fix disk cleanup

* fix disk cleanup

* fix disk cleanup

* fix disk cleanup
2023-10-16 12:25:06 -07:00
Lalit Kumar Bhasin 5eaaf53053
Allow specifying OTLP HTTP headers from env variable (#1290) 2023-10-08 15:20:48 -04:00
John Kelly 2e6a43dbfc
Add `opentelemetry::sdk::logs::config()` for parity with `open telemetry::sdk::trace::config()` (#1197) 2023-10-08 15:19:18 -04:00
Shaun Cox 79244e46c6
Use FnOnce instead of Fn in contrib APIs (#1292) 2023-10-06 20:47:02 -07:00
Cijo Thomas d87fc75c2f
Fix temporarlity and aggregation for usereventexporter (#1287)
Co-authored-by: Leighton Chen <lechen@microsoft.com>
2023-10-06 14:25:59 -04:00
Leighton Chen df2551b8a3
Include diagnosing error messages for userevents metrics exporter (#1273) 2023-10-06 14:25:07 -04:00
Cijo Thomas 6713143b59 unwrap_or_default 2023-10-06 12:10:42 +02:00
Cijo Thomas 19dc93cf14 Fix CI 2023-10-06 12:10:42 +02:00
Shaun Cox 17316b1253
Upgrade dependencies (#1279) 2023-10-05 13:17:22 -04:00
Cijo Thomas b26b20a18f
Add basic stress test for tracing (#1286) 2023-10-05 13:13:59 -04:00
Julian Tescher 6c2ce12593
Add Exponential histogram (#1267) 2023-10-05 13:12:26 -04:00
Shaun Cox 08c3d48dc8
Add attach method to Contextualized (#1277) 2023-09-25 12:29:55 -04:00
Zhongyang Wu 16a866ed59
feat: force user to add exporter builder pipeline. (#1272)
feat: force user to add exporter builder pipeline.

Currently, when users don't configure a builder pipeline. We will throw a runtime error.

This change force user to call `with_exporter` before building exporters or installing pipeline and eliminate the `NoExporterBuilder` error
2023-09-23 11:30:20 -07:00
Shaun Cox bea0aa5497
Cleanup crate documentation (#1278)
* Cleanup crate documentation

- mainly this removes circular dev-dependencies between the api,
  sdk, and stdout crates.

* Some things need to be behind "trace" feature
2023-09-23 09:00:16 -07:00
Shaun Cox f7684b0dad
Prefer use of const to static where possible (#1270)
- Changed NOOP_SPAN from a lazy static to a const
- Remove branch in build_with_context for the noop tracer.
  The current context's span() method already returns &NOOP_SPAN in the
  case when no active span is present, which already has the right span
  context value to use.
- Changed other constituents of span context to use const default values too.
2023-09-20 21:43:35 -07:00
Shaun Cox ab9972f0eb
Context holds SynchronizedSpan directly, not via HashMap (#1268)
- lookup on TypeId and downcasting isn't necesary
- Context::with_value and current_with_value are more efficient
  as they no longer clone and overwrite the entry in the map
  which represens the current span
2023-09-20 21:40:49 -07:00
Leighton Chen e7fb708dc5
meter (#1274) 2023-09-19 16:47:47 -07:00
Yuta Yamaguchi cf46a55420
Move metric validation from api to sdk (#1269)
* Move metric validation from api to sdk

* moved validation process for metrics instrument from api to sdk.
* included hyphens in instrument names as valid values.
* increase instrument name maximum length from 63 to 255 characters.

* refactor(metrics): rename InstProvider to InstrumentProvider

* refactor(metrics): define spec limitation to const
2023-09-14 21:33:29 -07:00
Julian Tescher 3ee22ced04
Re-use memory via aggregate functions (#1266)
This simplifies memory reuse on subsequent collection cycles.

Also small ergonomics changes:

* Move `MetricsProducer` config to builders to match other config
* Remove the need for separate `Delta*` and `Cumulative*` aggregate
  types
* Return error earlier if readers are shut down
* Log warning if two instruments have the same name with different
  casing
* Log warning if view is created with empty criteria
2023-09-13 13:58:42 -04:00
Shaun Cox bfb61de163
opentelemetry-contrib api enhancements with new_span benchmark (#1232) 2023-09-12 21:49:10 -04:00
Cijo Thomas c36db502b3
Stdout to print temporality in user readable format (#1260) 2023-09-09 12:43:48 -04:00
Cijo Thomas 52dd8d3eab
Nit updates to OTLP Exmples readme (#1259) 2023-09-09 12:43:13 -04:00
Cijo Thomas e0c9087355
Metric advanced examples - change histogram buckets (#1257) 2023-09-09 12:40:25 -04:00
Cijo Thomas 2b5f4b17d2
Propose Shaun Cox as an approver (#1251) 2023-09-09 12:36:03 -04:00
Cijo Thomas f0da10f41e
Remove dev deps on log appender (#1249)
* Remove dev deps on log appender

* comment
2023-09-08 09:52:41 -07:00
Shaun Cox 9d6bdd15c1 Use edition 2021 resolver
- eliminates a warning when doing cargo update
2023-09-07 15:58:45 +02:00
Max Bruckner 4d26d7ae95
Add Sync bound on the LogExporter and SpanExporter traits (#1240) 2023-09-05 13:27:12 -04:00
Kacz 6412dcd078
feat: add InMemoryLogsExporter (#1231)
* feat: addInMemoryLogExporter

* linting

* Update CHANGELOG.md

* changed finished to emitted logs, moved example

* replace clone_log with cloned()

* remove proj example in favor of single file

* corrected dependency, removed repeated code

* changed finished to emitted logs, moved example

* remove proj example in favor of single file

* corrected dependency, removed repeated code

* corrected dependency, removed repeated code

* fix: endpoint urls for otlp http exporter. (#1210)

* Move opentelemetry_api code back into opentelemetry and remove the former (#1226)

* [user_events log exporter] Upgrade eventheader-dynamic dependency (#1230)

* feat: addInMemoryLogExporter

* linting

* Update CHANGELOG.md

* remove the example from examples

* fixes after rebase

* missing doc, added no_run in examples

* fix ci test(stable) and docs

* more examples ci fixes

* added dev-dependencies to resolve ci issue

* corrected required features

* remove comments about returning error

* Update example description

Co-authored-by: Cijo Thomas <cithomas@microsoft.com>

---------

Co-authored-by: Zhongyang Wu <zhongyang.wu@outlook.com>
Co-authored-by: Shaun Cox <shaunco@microsoft.com>
Co-authored-by: Lalit Kumar Bhasin <lalit_fin@yahoo.com>
Co-authored-by: Cijo Thomas <cithomas@microsoft.com>
2023-09-02 15:26:35 -07:00
Cijo Thomas 2a2e4b17c7
Remove context from metrics force_flush (#1245) 2023-09-01 17:15:41 -04:00
Jasper Zeng b776b1ec38
feat: add InMemorySpanExporter (#1216) 2023-09-01 17:12:45 -04:00
Max Bruckner b6e91a9baf Add missing env! macro around "CARGO_PKG_VERSION" 2023-08-31 10:48:29 +02:00
Midas Lambrichts 88f271dd13 Bump tokio-streams minimum version to 0.1.1
The `Stream` wrappers that are used were added in 0.1.1:
https://github.com/tokio-rs/tokio/blob/master/tokio-stream/CHANGELOG.md#011-january-4-2021
2023-08-30 13:35:43 +02:00
Midas Lambrichts baa7199b1a Update minimal `thiserror` requirement
The repository uses `transparent`, which was added in v1.0.7:
https://github.com/dtolnay/thiserror/releases/tag/1.0.7
2023-08-30 13:35:43 +02:00
Shaun Cox 8748fb82f4 use futures-util instead of futures and with no default features 2023-08-30 10:03:57 +02:00
Shaun Cox d6f0cfc9e9 smaller dependency footprint to futures by opentelemetry crate 2023-08-30 10:03:57 +02:00
Shaun Cox 25e545f3de
Add .cspell.json configuration file (#1233) 2023-08-29 12:53:51 -07:00
Shaun Cox 08119c44be
opentelemetry crate no longer depends on futures-channel (#1229) 2023-08-28 17:27:42 -04:00
Cijo Thomas 1f9e7652af
Also print datetime in human friendly format for stdout (#1206) 2023-08-28 17:26:12 -04:00
Lalit Kumar Bhasin 6603a5818f
[user_events log exporter] Upgrade eventheader-dynamic dependency (#1230) 2023-08-28 11:21:35 -04:00
Shaun Cox 42e58fc356
Move opentelemetry_api code back into opentelemetry and remove the former (#1226) 2023-08-28 11:20:30 -04:00
Zhongyang Wu f66e9626cb
fix: endpoint urls for otlp http exporter. (#1210) 2023-08-28 11:14:40 -04:00
Shaun Cox 1688ec6824 chore: fix new lints from rustc 1.72 update 2023-08-24 17:29:58 +02:00
Leighton Chen b22f7d1bd4
Update user_events metrics exporter to reflect new schema (#1224)
* cli

* update

* Update mod.rs

* lint
2023-08-23 21:34:59 -07:00
Shaun Cox 759556d590
Change opentelemetry crate to contain only the API, not the SDK #1186 (#1199) 2023-08-23 21:01:28 -07:00
Zhongyang Wu 3c560d9576
fix(zpages): use tonic based generated files. (#1214)
* fix(zpages): use tonic based generated files.

The reason zpages cannot compile after #1202 is prost backed grpcio compiler no longer allow us to add `serde` macros onto the types. Thus, instead of using grpcio types, use tonic types in zpages fixes it.

* add changelog
2023-08-23 09:51:40 -07:00
Leighton Chen 6f7f8bbc1c
Create doc/unit tests for SDK MeterProvider (#1220)
* meter provider

* meterprovider

* lint
2023-08-23 08:49:23 -07:00
Cijo Thomas 2c3017e347
Pretty print stdout in examples (#1212)
* Modify examples to pretty print stdout

* a

* a

* fmt
2023-08-23 08:48:37 -07:00
Max Bruckner a3e0ab6f9e
Make LogData constructible by removing #[non_exhaustive], fixes #1217 (#1222) 2023-08-23 08:47:08 -07:00
Cijo Thomas 495330f635
Try to fix docs CI (#1218) 2023-08-22 10:50:45 -07:00
Leighton Chen 2ba8f9fe10
Add doc tests to opentelemetry metrics api (#1213)
* meter + instrument tests

* provider

* lint
2023-08-20 17:06:55 -07:00
Cijo Thomas 523adb1c5d
Fix stress test for logs to use a noop processor (#1207)
* Fix stress test for logs to use a noop processor

* lint
2023-08-15 22:17:23 -07:00
Julian Tescher 41e8d63652
Add `grpcio` metrics exporter (#1202)
Co-authored-by: Zhongyang Wu <zhongyang.wu@outlook.com>
2023-08-14 18:18:47 -07:00
Leighton Chen 2848836a2f
fix pprof (#1205) 2023-08-11 17:56:36 -07:00
Shaun Cox 4fd68e319c Update CHANGELOGs for MSRV bump 2023-08-11 23:40:30 +02:00
Shaun Cox 53ae991a00 bump MSRV to 1.64 and indexmap to 2.0 2023-08-11 23:40:30 +02:00
Cijo Thomas 2d427667db
Metric stdout exporter to print timestamp in human readable format (#1192) 2023-08-11 11:03:28 -07:00
Zhongyang Wu 1d4db1580f
fix: allow user to set arbitrary units in promethus suffix. (#1188) 2023-08-08 16:50:19 -07:00
Cijo Thomas a505104fa6
Default resource to include Telemetry SDK (#1194) 2023-08-08 16:49:18 -07:00
Lalit Kumar Bhasin 17715c8263
[user_events exporter] Fix the exporter log format (#1190) 2023-08-07 18:19:16 -07:00
Cijo Thomas bacefbfbc2
Add Cijo and Lalit to list of approvers (#1193) 2023-08-07 17:52:19 -07:00
Julian Tescher 77db498ead
Restructure OTLP config (#1187) 2023-08-07 09:36:04 -07:00
Julian Tescher 7607ad371e
Implement tonic metrics proto transformations (#1184) 2023-08-04 11:37:38 -07:00
Yunchi Luo 3df6a047bd
datadog: do not set invalid remote context (#1185) 2023-08-03 17:21:54 -07:00
Julian Tescher e12247e9ca
Rename `traces` feature to the more standard `trace` (#1183) 2023-08-03 09:50:58 -07:00
Cijo Thomas fbe789d015
Fix timestamps in log-appenders (#1180) 2023-08-03 09:50:38 -07:00
Julian Tescher a22c822103
Add log appender versions to loggers (#1182) 2023-08-02 17:53:09 -07:00
Shaun Cox 3768a7dd15
Export InstrumentationLibrary attributes (#1179)
- change conversion From<InstrumentationLibrary> to move data rather than copy it in some Cow::Owned cases
2023-08-02 13:53:21 -07:00
Lalit Kumar Bhasin 8dd1a63c70
[Logs API/SDK] - Populate ObservedTimestamp within the SDK (#1178)
* observed ts mandatory

* rename var

* fix lint

* implement default for LogRecord
2023-08-02 11:46:55 -07:00
Cijo Thomas f67dc5c3e1
Fix basic-otlp example dependencies (#1177) 2023-08-01 21:57:41 -07:00
Cijo Thomas a00793c7b9
Set timestamp correctly in log appenders (#1175) 2023-08-01 21:56:19 -07:00
610 changed files with 70009 additions and 64575 deletions

3
.cargo/config.toml Normal file
View File

@ -0,0 +1,3 @@
[resolver]
# https://doc.rust-lang.org/cargo/reference/config.html#resolverincompatible-rust-versions
incompatible-rust-versions = "fallback"

148
.cspell.json Normal file
View File

@ -0,0 +1,148 @@
// http://cspell.org/configuration/
{
"version": "0.2",
"language": "en,en-US",
"useGitignore": true,
"minWordLength": 4,
"ignorePaths": [
"target/**"
],
// list of words to be ignored. unlike `words` below, these won't be
// suggested as corrections for misspelled words.
"ignoreWords": [
"otel",
"rustdoc",
"rustfilt",
"webkpi"
],
// these are words that are always considered incorrect.
"flagWords": [
"recieve",
"reciever",
"seperate",
"hte",
"teh"
],
// these are words that are always correct and can be thought of as our
// workspace dictionary.
"words": [
"actix",
"Antonsson",
"anyvalue",
"appender",
"appenders",
"autobenches",
"Bhasin",
"Björn",
"BLRP",
"chrono",
"Cijo",
"clippy",
"clonable",
"codecov",
"dashmap",
"datapoint",
"deque",
"Dirkjan",
"docsrs",
"Dwarnings",
"eprintln",
"EPYC",
"flamegraph",
"Gerring",
"grpcio",
"Grübel",
"hasher",
"impls",
"isahc",
"Isobel",
"jaegertracing",
"Kühle",
"Kumar",
"Lalit",
"LIBCLANG",
"logrecord",
"MILLIS",
"mpsc",
"msrv",
"mykey",
"myunit",
"myvalue",
"nocapture",
"Ochtman",
"opentelemetry",
"openzipkin",
"otcorrelations",
"OTELCOL",
"OTLP",
"periodicreader",
"Pillai",
"pprof",
"protos",
"prost",
"protoc",
"quantile",
"quantiles",
"Redelmeier",
"reqwest",
"rstest",
"runtimes",
"rustc",
"rustls",
"schemars",
"semconv",
"serde",
"shoppingcart",
"struct",
"Tescher",
"testcontainers",
"testresults",
"thiserror",
"traceparent",
"Traceparent",
"tracerprovider",
"tracestate",
"UCUM",
"Umesan",
"unsampled",
"updown",
"urlencoding",
"usize",
"Utkarsh",
"webpki",
"Zhongyang",
"zipkin"
],
"enabledLanguageIds": [
"jsonc",
"markdown",
"plaintext",
"rust",
"shellscript"
],
"languageSettings": [
{
"languageId": "jsonc",
"includeRegExpList": [
"CStyleComment"
]
},
{
"languageId": "markdown",
"caseSensitive": false
},
{
"languageId": "rust",
"includeRegExpList": [
"CStyleComment",
"strings"
]
},
{
"languageId": "shellscript",
"includeRegExpList": [
"/#.*/g"
]
}
]
}

7
.github/CODEOWNERS vendored Normal file
View File

@ -0,0 +1,7 @@
# Code owners file
## This file controls who is tagged for review for any given pull request.
## For anything not explicitly taken by someone else
* @open-telemetry/rust-approvers

52
.github/ISSUE_TEMPLATE/BUG-REPORT.yml vendored Normal file
View File

@ -0,0 +1,52 @@
name: Bug Report
description: File a bug report
title: "[Bug]: "
labels: ["bug", "triage:todo"]
projects: ["open-telemetry/opentelemetry-rust"]
body:
- type: markdown
attributes:
value: |
Thanks for taking the time to fill out this bug report!
- type: textarea
id: what-happened
attributes:
label: What happened?
description: Also tell us, what did you expect to happen?
placeholder: Tell us what you see!
value: "A bug happened!"
validations:
required: true
- type: textarea
id: api-version
attributes:
label: OpenTelemetry API Version (i.e version of `opentelemetry` crate)
description: What version of the `opentelemetry` crate are you using?
placeholder: 0.x, 1.x, etc.
validations:
required: true
- type: textarea
id: sdk-version
attributes:
label: OpenTelemetry SDK Version (i.e version of `opentelemetry_sdk` crate)
description: What version of the `opentelemetry_sdk` crate are you using?
placeholder: 0.x, 1.x, etc.
validations:
required: true
- type: dropdown
id: browsers
attributes:
label: What Exporter(s) are you seeing the problem on?
multiple: true
options:
- stdout
- OTLP
- Zipkin
- Prometheus
- N/A
- type: textarea
id: logs
attributes:
label: Relevant log output
description: Please copy and paste any relevant log output. This will be automatically formatted into code, so no need for backticks.
render: shell

View File

@ -0,0 +1,48 @@
---
name: "Feature Request"
description: Request a feature for the OpenTelemetry Rust implementation.
title: "[Feature]: "
labels: ["enhancement", "triage:todo"]
projects: ["open-telemetry/opentelemetry-rust"]
body:
- type: markdown
attributes:
value: |
Thanks for using our library and trying to make it better!
Before opening a feature request against this repo, consider whether the feature
should/could be implemented in the [other OpenTelemetry client
libraries](https://github.com/open-telemetry/). If so, please [open an issue on
opentelemetry-specification](https://github.com/open-telemetry/opentelemetry-specification/issues/new) first.
- type: textarea
id: related-problem
attributes:
label: Related Problems?
description: Is your feature request related to a problem? If so, provide a concise description of the problem.
placeholder: Include the Issue ID from this or other repos.
validations:
required: false
- type: textarea
id: solution
attributes:
label: "Describe the solution you'd like:"
description: What do you want to happen instead? What is the expected behavior?
placeholder: I'd like the api to ...
validations:
required: true
- type: textarea
id: alternatives
attributes:
label: Considered Alternatives
description: Which alternative solutions or features have you considered?
placeholder: Some potential solutions
validations:
required: false
- type: textarea
id: additional-context
attributes:
label: Additional Context
description: Add any other context about the feature request here.
placeholder: Some related requests in other project or upstream spec proposals.
validations:
required: false

11
.github/ISSUE_TEMPLATE/config.yml vendored Normal file
View File

@ -0,0 +1,11 @@
contact_links:
- name: GitHub Discussions
url: https://github.com/open-telemetry/opentelemetry-rust/discussions/new/choose
about: Please ask questions here.
- name: Slack
url: https://cloud-native.slack.com/archives/C03GDP0H023
about: Or the `#otel-rust` channel in the CNCF Slack instance.
- name: "⚠️ Report a security vulnerability"
url: "https://github.com/open-telemetry/opentelemetry-rust/security/advisories/new"
about: "Report a security vulnerability."

11
.github/codecov.yaml vendored
View File

@ -13,18 +13,15 @@ coverage:
ignore:
- "opentelemetry/src/testing" # test harnesses
- "opentelemetry-jaeger/src/testing" # test harness
- "opentelemetry-jaeger/src/exporter/thrift" # auto generated files
- "opentelemetry-otlp/src/proto" # auto generated files
- "opentelemetry-proto/src/proto" # auto generated files
# examples below
- "examples"
- "opentelemetry-jaeger/examples"
- "opentelemetry-zipkin/examples"
- "opentelemetry-otlp/examples"
- "opentelemetry-aws/examples"
- "opentelemetry-datadog/examples"
- "opentelemetry-dynatrace/examples"
- "opentelemetry-http/examples"
- "opentelemetry-prometheus/examples"
- "opentelemetry-zpages/examples"
- "opentelemetry-appender-tracing/examples"
- "opentelemetry-appender-log/examples"
# stress test
- "stress"

15
.github/dependabot.yml vendored Normal file
View File

@ -0,0 +1,15 @@
version: 2
updates:
- package-ecosystem: "cargo"
directory: "/"
schedule:
interval: "monthly"
open-pull-requests-limit: 10
- package-ecosystem: "docker"
directory: "/"
schedule:
interval: "monthly"
- package-ecosystem: "github-actions"
directory: "/"
schedule:
interval: "monthly"

59
.github/workflows/benchmark.yml vendored Normal file
View File

@ -0,0 +1,59 @@
# This workflow runs a Criterion benchmark on a PR and compares the results against the base branch.
# It is triggered on a PR or a push to main.
#
# The workflow is gated on the presence of the "performance" label on the PR.
#
# The workflow runs on a self-hosted runner pool. We can't use the shared runners for this,
# because they are only permitted to run on the default branch to preserve resources.
#
# In the future, we might like to consider using bencher.dev or the framework used by otel-golang here.
on:
pull_request:
push:
branches:
- main
name: benchmark pull requests
permissions:
contents: read
jobs:
runBenchmark:
name: run benchmark
permissions:
pull-requests: write
# If we're running on main, use our oracle bare-metal runner for accuracy.
# If we're running on a PR, use github's shared workers to save resources.
runs-on: ${{ github.event_name == 'pull_request' && 'ubuntu-latest' || 'oracle-bare-metal-64cpu-512gb-x86-64' }}
if: ${{ (github.event_name == 'pull_request' && contains(github.event.pull_request.labels.*.name, 'performance')) || github.event_name == 'push' }}
container:
image: rust:slim-bullseye
env:
# For PRs, compare against the base branch - e.g., 'main'.
# For pushes to main, compare against the previous commit
BRANCH_NAME: ${{ github.event_name == 'pull_request' && github.base_ref || github.event.before }}
GIT_DISCOVERY_ACROSS_FILESYSTEM: 1
steps:
- name: Harden the runner (Audit all outbound calls)
uses: step-security/harden-runner@6c439dc8bdf85cadbbce9ed30d1c7b959517bc49 # v2.12.2
with:
egress-policy: audit
- name: Setup container environment
run: |
apt-get update && apt-get install --fix-missing -y unzip cmake build-essential pkg-config curl git
cargo install cargo-criterion
- name: Make repo safe for Git inside container
run: git config --global --add safe.directory "$GITHUB_WORKSPACE"
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
fetch-depth: 10 # Fetch a bit of history so we can do perf diffs
- uses: arduino/setup-protoc@c65c819552d16ad3c9b72d9dfd5ba5237b9c906b # v3.0.0
with:
repo-token: ${{ secrets.GITHUB_TOKEN }}
- uses: boa-dev/criterion-compare-action@adfd3a94634fe2041ce5613eb7df09d247555b87 # v3.2.4
with:
branchName: ${{ env.BRANCH_NAME }}

View File

@ -1,103 +1,185 @@
name: CI
env:
CI: true
permissions:
contents: read
on:
pull_request:
push:
branches:
- main
paths-ignore:
- '**.md'
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
test:
strategy:
matrix:
# test both stable and beta versions of Rust on ubuntu-latest
os: [ubuntu-latest]
rust: [stable, beta]
runs-on: ubuntu-latest
# test only stable version of Rust on Windows and MacOS
include:
- rust: stable
os: windows-latest
- rust: stable
os: macos-latest
- rust: stable
os: ubuntu-22.04-arm
runs-on: ${{ matrix.os }}
continue-on-error: ${{ matrix.rust == 'beta' }}
steps:
- uses: actions/checkout@v1
- name: Harden the runner (Audit all outbound calls)
uses: step-security/harden-runner@6c439dc8bdf85cadbbce9ed30d1c7b959517bc49 # v2.12.2
with:
egress-policy: audit
- name: Free disk space
if: ${{ matrix.os == 'ubuntu-latest'}}
run: |
df -h
sudo rm -rf /usr/local/lib/android
sudo rm -rf /usr/share/dotnet
df -h
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
submodules: true
- uses: actions-rs/toolchain@v1
- uses: dtolnay/rust-toolchain@b3b07ba8b418998c39fb20f53e8b695cdcc8de1b
with:
toolchain: ${{ matrix.rust }}
components: rustfmt
profile: minimal
- uses: arduino/setup-protoc@v1
- name: "Set rustup profile"
run: rustup set profile minimal
- uses: arduino/setup-protoc@c65c819552d16ad3c9b72d9dfd5ba5237b9c906b # v3.0.0
with:
repo-token: ${{ secrets.GITHUB_TOKEN }}
- name: Test
run: ./scripts/test.sh
run: bash ./scripts/test.sh
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v1
- name: Harden the runner (Audit all outbound calls)
uses: step-security/harden-runner@6c439dc8bdf85cadbbce9ed30d1c7b959517bc49 # v2.12.2
with:
egress-policy: audit
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
submodules: true
- uses: actions-rs/toolchain@v1
- uses: dtolnay/rust-toolchain@b3b07ba8b418998c39fb20f53e8b695cdcc8de1b
with:
toolchain: stable
components: rustfmt
profile: minimal
- uses: arduino/setup-protoc@v1
- uses: actions-rs/cargo@v1
components: rustfmt, clippy
- uses: taiki-e/install-action@0eee80d37f55e834144deec670972c19e81a85b0 # v2.56.0
with:
command: fmt
args: --all -- --check
tool: cargo-hack
- uses: arduino/setup-protoc@c65c819552d16ad3c9b72d9dfd5ba5237b9c906b # v3.0.0
with:
repo-token: ${{ secrets.GITHUB_TOKEN }}
- name: Format
run: cargo fmt --all -- --check
- name: Lint
run: ./scripts/lint.sh
non-default-examples:
run: bash ./scripts/lint.sh
external-types:
strategy:
matrix:
example: [opentelemetry-otlp/examples/external-otlp-grpcio-async-std]
runs-on: ubuntu-latest
member: [opentelemetry, opentelemetry-sdk, opentelemetry-otlp, opentelemetry-zipkin]
runs-on: ubuntu-latest # TODO: Check if this could be covered for Windows. The step used currently fails on Windows.
steps:
- uses: actions/checkout@v1
with:
submodules: true
- uses: actions-rs/toolchain@v1
with:
toolchain: stable
components: rustfmt
profile: minimal
- uses: arduino/setup-protoc@v1
- name: Build
run: |
cd ${{ matrix.example }}
cargo build --verbose
- name: Harden the runner (Audit all outbound calls)
uses: step-security/harden-runner@6c439dc8bdf85cadbbce9ed30d1c7b959517bc49 # v2.12.2
with:
egress-policy: audit
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- uses: dtolnay/rust-toolchain@b3b07ba8b418998c39fb20f53e8b695cdcc8de1b
with:
# Rust version should be kept in sync with the one the release was tested with
# https://github.com/awslabs/cargo-check-external-types/releases
toolchain: nightly-2025-05-04
components: rustfmt
- uses: taiki-e/install-action@0eee80d37f55e834144deec670972c19e81a85b0 # v2.56.0
with:
tool: cargo-check-external-types@0.2.0
- name: external-type-check
working-directory: ${{ matrix.member }}
run: cargo check-external-types --all-features --config allowed-external-types.toml
msrv:
runs-on: ubuntu-latest
strategy:
matrix:
os: [windows-latest, ubuntu-latest]
runs-on: ${{ matrix.os }}
continue-on-error: true
steps:
- uses: actions/checkout@v1
with:
submodules: true
- uses: actions-rs/toolchain@v1
with:
profile: minimal
toolchain: 1.60.0
override: true
- name: Patch dependencies versions # some dependencies bump MSRV without major version bump
run: ./scripts/patch_dependencies.sh
- name: Run tests
run: cargo --version &&
cargo test --manifest-path=opentelemetry/Cargo.toml --features trace,metrics,rt-tokio,testing &&
cargo test --manifest-path=opentelemetry-jaeger/Cargo.toml --features rt-tokio &&
cargo test --manifest-path=opentelemetry-zipkin/Cargo.toml
- name: Harden the runner (Audit all outbound calls)
uses: step-security/harden-runner@6c439dc8bdf85cadbbce9ed30d1c7b959517bc49 # v2.12.2
with:
egress-policy: audit
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
submodules: true
- uses: dtolnay/rust-toolchain@b3b07ba8b418998c39fb20f53e8b695cdcc8de1b
with:
toolchain: stable
- uses: taiki-e/install-action@0eee80d37f55e834144deec670972c19e81a85b0 # v2.56.0
with:
tool: cargo-msrv
- uses: arduino/setup-protoc@c65c819552d16ad3c9b72d9dfd5ba5237b9c906b # v3.0.0
with:
repo-token: ${{ secrets.GITHUB_TOKEN }}
- name: Check MSRV for all crates
run: bash ./scripts/msrv.sh
cargo-deny:
runs-on: ubuntu-latest
runs-on: ubuntu-latest # This uses the step `EmbarkStudios/cargo-deny-action@v1` which is only supported on Linux
continue-on-error: true # Prevent sudden announcement of a new advisory from failing ci
steps:
- uses: actions/checkout@v2
- uses: EmbarkStudios/cargo-deny-action@v1
- name: Harden the runner (Audit all outbound calls)
uses: step-security/harden-runner@6c439dc8bdf85cadbbce9ed30d1c7b959517bc49 # v2.12.2
with:
egress-policy: audit
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: Check advisories
uses: EmbarkStudios/cargo-deny-action@30f817c6f72275c6d54dc744fbca09ebc958599f # v2.0.12
with:
command: check advisories
- name: Check licenses
uses: EmbarkStudios/cargo-deny-action@30f817c6f72275c6d54dc744fbca09ebc958599f # v2.0.12
with:
command: check licenses
- name: Check bans
uses: EmbarkStudios/cargo-deny-action@30f817c6f72275c6d54dc744fbca09ebc958599f # v2.0.12
with:
command: check bans
- name: Check sources
uses: EmbarkStudios/cargo-deny-action@30f817c6f72275c6d54dc744fbca09ebc958599f # v2.0.12
with:
command: check sources
docs:
continue-on-error: true
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions-rs/toolchain@v1
- name: Harden the runner (Audit all outbound calls)
uses: step-security/harden-runner@6c439dc8bdf85cadbbce9ed30d1c7b959517bc49 # v2.12.2
with:
toolchain: nightly
egress-policy: audit
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- uses: dtolnay/rust-toolchain@b3b07ba8b418998c39fb20f53e8b695cdcc8de1b
with:
toolchain: stable
components: rustfmt
override: true
- uses: arduino/setup-protoc@v1
- uses: arduino/setup-protoc@c65c819552d16ad3c9b72d9dfd5ba5237b9c906b # v3.0.0
with:
repo-token: ${{ secrets.GITHUB_TOKEN }}
- name: doc
run: cargo doc --no-deps --all-features
env:
@ -106,24 +188,74 @@ jobs:
coverage:
continue-on-error: true
runs-on: ubuntu-latest
if: ${{ ! contains(github.event.pull_request.labels.*.name, 'dependencies') }}
steps:
- uses: actions/checkout@v3
- name: Harden the runner (Audit all outbound calls)
uses: step-security/harden-runner@6c439dc8bdf85cadbbce9ed30d1c7b959517bc49 # v2.12.2
with:
egress-policy: audit
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
submodules: true
- uses: actions-rs/toolchain@v1
- uses: dtolnay/rust-toolchain@b3b07ba8b418998c39fb20f53e8b695cdcc8de1b
with:
toolchain: stable
components: rustfmt,llvm-tools-preview
override: true
- uses: arduino/setup-protoc@v1
- name: cargo install cargo-llvm-cov
uses: taiki-e/install-action@cargo-llvm-cov
- uses: arduino/setup-protoc@c65c819552d16ad3c9b72d9dfd5ba5237b9c906b # v3.0.0
with:
repo-token: ${{ secrets.GITHUB_TOKEN }}
- name: Install cargo-llvm-cov
uses: taiki-e/install-action@0eee80d37f55e834144deec670972c19e81a85b0 # v2.56.0
with:
tool: cargo-llvm-cov
- name: cargo generate-lockfile
if: hashFiles('Cargo.lock') == ''
run: cargo generate-lockfile
- name: cargo llvm-cov
run: cargo llvm-cov --locked --all-features --workspace --lcov --output-path lcov.info
run: cargo llvm-cov --locked --all-features --workspace --lcov --lib --output-path lcov.info
- name: Upload to codecov.io
uses: codecov/codecov-action@v3
uses: codecov/codecov-action@18283e04ce6e62d37312384ff67231eb8fd56d24 # v5.4.3
env:
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
with:
fail_ci_if_error: true
build-examples:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- uses: dtolnay/rust-toolchain@b3b07ba8b418998c39fb20f53e8b695cdcc8de1b # stable
with:
toolchain: stable
components: rustfmt
- uses: arduino/setup-protoc@c65c819552d16ad3c9b72d9dfd5ba5237b9c906b # v3.0.0
with:
repo-token: ${{ secrets.GITHUB_TOKEN }}
- name: Build examples
run: |
for example in examples/*; do
if [ -d "$example" ]; then
echo "Building $example"
cargo build
fi
done
cargo-machete:
continue-on-error: true
runs-on: ubuntu-latest
steps:
- name: Harden the runner (Audit all outbound calls)
uses: step-security/harden-runner@6c439dc8bdf85cadbbce9ed30d1c7b959517bc49 # v2.12.2
with:
egress-policy: audit
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
submodules: true
- uses: dtolnay/rust-toolchain@b3b07ba8b418998c39fb20f53e8b695cdcc8de1b
with:
toolchain: stable
- uses: taiki-e/install-action@0eee80d37f55e834144deec670972c19e81a85b0 # v2.56.0
with:
tool: cargo-machete
- name: cargo machete
run: cargo machete

45
.github/workflows/codeql-analysis.yml vendored Normal file
View File

@ -0,0 +1,45 @@
name: "CodeQL Analysis"
env:
CODEQL_ENABLE_EXPERIMENTAL_FEATURES : true # CodeQL support for Rust is experimental
permissions:
contents: read
on:
pull_request:
push:
branches: [main]
workflow_dispatch:
jobs:
analyze:
name: Analyze
runs-on: ubuntu-latest
permissions:
security-events: write # for github/codeql-action/autobuild to send a status report
strategy:
fail-fast: false
steps:
- name: Harden the runner (Audit all outbound calls)
uses: step-security/harden-runner@6c439dc8bdf85cadbbce9ed30d1c7b959517bc49 # v2.12.2
with:
egress-policy: audit
- name: Checkout repository
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
submodules: true
- name: Initialize CodeQL
uses: github/codeql-action/init@181d5eefc20863364f96762470ba6f862bdef56b # v3.29.2
with:
languages: rust
- name: Autobuild
uses: github/codeql-action/autobuild@181d5eefc20863364f96762470ba6f862bdef56b # v3.29.2
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@181d5eefc20863364f96762470ba6f862bdef56b # v3.29.2

25
.github/workflows/fossa.yml vendored Normal file
View File

@ -0,0 +1,25 @@
name: FOSSA scanning
on:
push:
branches:
- main
permissions:
contents: read
jobs:
fossa:
runs-on: ubuntu-latest
steps:
- name: Harden the runner (Audit all outbound calls)
uses: step-security/harden-runner@6c439dc8bdf85cadbbce9ed30d1c7b959517bc49 # v2.12.2
with:
egress-policy: audit
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- uses: fossas/fossa-action@3ebcea1862c6ffbd5cf1b4d0bd6b3fe7bd6f2cac # v1.7.0
with:
api-key: ${{secrets.FOSSA_API_KEY}}
team: OpenTelemetry

View File

@ -5,13 +5,34 @@ on:
pull_request:
types: [ labeled, synchronize, opened, reopened ]
permissions:
contents: read
jobs:
integration_tests:
runs-on: ubuntu-latest
timeout-minutes: 10
if: ${{ github.event.label.name == 'integration tests' || contains(github.event.pull_request.labels.*.name, 'integration tests') }}
steps:
- name: Checkout
uses: actions/checkout@v2
- name: Run integration tests using docker compose
- name: Harden the runner (Audit all outbound calls)
uses: step-security/harden-runner@6c439dc8bdf85cadbbce9ed30d1c7b959517bc49 # v2.12.2
with:
egress-policy: audit
- name: Free disk space
run: |
df -h
sudo rm -rf /usr/local/lib/android
sudo rm -rf /usr/share/dotnet
df -h
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
submodules: true
- uses: dtolnay/rust-toolchain@b3b07ba8b418998c39fb20f53e8b695cdcc8de1b
with:
toolchain: stable
components: rustfmt
- uses: arduino/setup-protoc@c65c819552d16ad3c9b72d9dfd5ba5237b9c906b # v3.0.0
with:
repo-token: ${{ secrets.GITHUB_TOKEN }}
- name: Run integration tests
run: ./scripts/integration_tests.sh

View File

@ -0,0 +1,33 @@
name: Markdown link check
on:
pull_request:
push:
branches:
- main
paths:
- '**/*.md'
permissions:
contents: read
jobs:
markdown-link-check:
runs-on: ubuntu-latest
steps:
- name: Harden the runner (Audit all outbound calls)
uses: step-security/harden-runner@6c439dc8bdf85cadbbce9ed30d1c7b959517bc49 # v2.12.2
with:
egress-policy: audit
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: Install markdown-link-check
run: npm install -g "git://github.com/tcort/markdown-link-check.git#ef7e09486e579ba7479700b386e7ca90f34cbd0a" # v3.13.7
- name: Run markdown-link-check
run: |
find . -type f \
-name '*.md' \
-not -path '**/CHANGELOG.md' \
| xargs ./scripts/markdown-link-check-with-retry.sh

53
.github/workflows/ossf-scorecard.yml vendored Normal file
View File

@ -0,0 +1,53 @@
name: OSSF Scorecard
on:
push:
branches:
- main
schedule:
- cron: "50 3 * * 0" # once a week
workflow_dispatch:
permissions:
contents: read
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:
- name: Harden the runner (Audit all outbound calls)
uses: step-security/harden-runner@6c439dc8bdf85cadbbce9ed30d1c7b959517bc49 # v2.12.2
with:
egress-policy: audit
- 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
# 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@181d5eefc20863364f96762470ba6f862bdef56b # v3.29.2
with:
sarif_file: results.sarif

23
.github/workflows/pr_naming.yml vendored Normal file
View File

@ -0,0 +1,23 @@
name: PR Conventional Commit Validation
on:
pull_request:
types: [opened, synchronize, reopened, edited]
permissions:
contents: read
jobs:
validate-pr-title:
runs-on: ubuntu-latest
steps:
- name: Harden the runner (Audit all outbound calls)
uses: step-security/harden-runner@6c439dc8bdf85cadbbce9ed30d1c7b959517bc49 # v2.12.2
with:
egress-policy: audit
- name: PR Conventional Commit Validation
uses: ytanikin/pr-conventional-commits@8267db1bacc237419f9ed0228bb9d94e94271a1d # 1.4.1
with:
task_types: '["build","chore","ci","docs","feat","fix","perf","refactor","revert","test"]'
add_label: 'false'

29
.github/workflows/semver.yml vendored Normal file
View File

@ -0,0 +1,29 @@
name: Semver compliance
env:
CI: true
permissions:
contents: read
on:
pull_request:
types: [ labeled, synchronize, opened, reopened ]
jobs:
semver-compliance: # This job uses the latest published crate as baseline for comparison.
runs-on: ubuntu-latest
timeout-minutes: 10
if: ${{ github.event.label.name == 'semver-check' || contains(github.event.pull_request.labels.*.name, 'semver-check') }}
steps:
- name: Harden the runner (Audit all outbound calls)
uses: step-security/harden-runner@6c439dc8bdf85cadbbce9ed30d1c7b959517bc49 # v2.12.2
with:
egress-policy: audit
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
submodules: true
- name: Install stable
uses: dtolnay/rust-toolchain@b3b07ba8b418998c39fb20f53e8b695cdcc8de1b
with:
toolchain: stable
components: rustfmt
- name: cargo-semver-checks
uses: obi1kenobi/cargo-semver-checks-action@5b298c9520f7096a4683c0bd981a7ac5a7e249ae # v2.8

6
.gitignore vendored
View File

@ -1,4 +1,10 @@
/.vscode/
/target/
*/target/
**/*.rs.bk
Cargo.lock
/.idea/
.cosine
opentelemetry-otlp/tests/integration_test/result.json

2
.gitmodules vendored
View File

@ -1,4 +1,4 @@
[submodule "opentelemetry-proto/src/proto/opentelemetry-proto"]
path = opentelemetry-proto/src/proto/opentelemetry-proto
url = https://github.com/open-telemetry/opentelemetry-proto
branch = tags/v1.0.0
branch = tags/v1.5.0

View File

@ -1,5 +0,0 @@
# Code owners file.
# This file controls who is tagged for review for any given pull request.
# For anything not explicitly taken by someone else:
* @open-telemetry/rust-approvers

View File

@ -1,27 +1,47 @@
# Contributing to opentelemetry-rust
The Rust special interest group (SIG) meets regularly. See the
OpenTelemetry
[community](https://github.com/open-telemetry/community#implementation-sigs)
repo for information on this and other language SIGs.
The Rust special interest group (SIG) meets weekly on Tuesdays at 9 AM Pacific
Time. The meeting is subject to change depending on contributors'
availability. Check the [OpenTelemetry community
calendar](https://github.com/open-telemetry/community?tab=readme-ov-file#calendar)
for specific dates and for Zoom meeting links. "OTel Rust SIG" is the name of
meeting for this group.
See the [public meeting
notes](https://docs.google.com/document/d/1tGKuCsSnyT2McDncVJrMgg74_z8V06riWZa0Sr79I_4/edit)
for a summary description of past meetings. To request edit access,
join the meeting or get in touch on
Meeting notes are available as a public [Google
doc](https://docs.google.com/document/d/12upOzNk8c3SFTjsL6IRohCWMgzLKoknSCOOdMakbWo4/edit).
If you have trouble accessing the doc, please get in touch on
[Slack](https://cloud-native.slack.com/archives/C03GDP0H023).
The meeting is open for all to join. We invite everyone to join our meeting,
regardless of your experience level. Whether you're a seasoned OpenTelemetry
developer, just starting your journey, or simply curious about the work we do,
you're more than welcome to participate!
Even though, anybody can contribute, there are benefits of being a member of our
community. See to the [community membership
document](https://github.com/open-telemetry/community/blob/main/guides/contributor/membership.md)
on how to become a
[**Member**](https://github.com/open-telemetry/community/blob/main/guides/contributor/membership.md#member),
[**Approver**](https://github.com/open-telemetry/community/blob/main/guides/contributor/membership.md#approver)
and
[**Maintainer**](https://github.com/open-telemetry/community/blob/main/guides/contributor/membership.md#maintainer).
## Pull Requests
### Prerequisites
Crate `opentelemetry-otlp` uses gRPC + Protocol Buffers.<br>
Crate `opentelemetry-otlp` uses gRPC + Protocol Buffers.
You can provide the protocol compiler protoc path programmatically (only works with tonic) or build it from source
```sh
export PROTOC=$(which protoc)
```
It is recommended to use "3.15" or newer of protoc, as some of the proto
definitions include "optional" fields, that are not supported in older versions,
resulting in errors as shown
[here](https://github.com/open-telemetry/opentelemetry-proto/issues/451).
Prerequisites to build the protocol compiler protoc from source
- [protoc](https://github.com/protocolbuffers/protobuf)
@ -34,13 +54,13 @@ Everyone is welcome to contribute code to `opentelemetry-rust` via
GitHub pull requests (PRs).
```sh
$ git clone --recurse-submodule https://github.com/open-telemetry/opentelemetry-rust
git clone --recurse-submodule https://github.com/open-telemetry/opentelemetry-rust
```
Enter the newly created directory and add your fork as a new remote:
```sh
$ git remote add <YOUR_FORK> git@github.com:<YOUR_GITHUB_USERNAME>/opentelemetry-rust
git remote add <YOUR_FORK> git@github.com:<YOUR_GITHUB_USERNAME>/opentelemetry-rust
```
Check out a new branch, make modifications, run linters and tests, and
@ -58,26 +78,42 @@ Open a pull request against the main
[opentelemetry-rust](https://github.com/open-telemetry/opentelemetry-rust)
repo.
Your pull request should be named according to the
[conventional commits](https://www.conventionalcommits.org/en/v1.0.0/) standard. This ensures that
when the PR is squashed into `main`, the resulting commit message is consistent and makes it easier
for us to generate a changelog standard.
> **Note**
> It is recommended to run [pre-commit script](precommit.sh) from the root of
the repo to catch any issues locally.
> It is recommended to run [pre-commit script](scripts/precommit.sh) to catch any issues locally.
### How to Receive Comments
* If the PR is not ready for review, please put `[WIP]` in the title,
tag it as `work-in-progress`, or mark it as
[`draft`](https://github.blog/2019-02-14-introducing-draft-pull-requests/).
* Make sure CLA is signed and CI is clear.
- If the PR is not ready for review, please put `[WIP]` in the title or mark it
as [`draft`](https://github.blog/2019-02-14-introducing-draft-pull-requests/).
- Make sure CLA is signed and all required CI checks are clear.
- Submit small, focused PRs addressing a single concern/issue.
- Make sure the PR title reflects the contribution.
- Write a summary that helps understand the change.
- Include usage examples in the summary, where applicable.
- Include benchmarks (before/after) in the summary, for contributions that are
performance enhancements.
### How to Get PRs Merged
A PR is considered to be **ready to merge** when:
* It has received approval from Collaborators/Maintainers.
* Major feedback is resolved.
- It has received approval from
[Approvers](https://github.com/open-telemetry/community/blob/main/guides/contributor/membership.md#approver).
/
[Maintainers](https://github.com/open-telemetry/community/blob/main/guides/contributor/membership.md#maintainer).
- Major feedbacks are resolved.
Any Collaborator/Maintainer can merge the PR once it is **ready to
merge**.
Any Maintainer can merge the PR once it is **ready to merge**. Note, that some
PRs may not be merged immediately if the repo is in the process of a release and
the maintainers decided to defer the PR to the next release train. Also,
maintainers may decide to wait for more than one approval for certain PRs,
particularly ones that are affecting multiple areas, or topics that may warrant
more discussion.
## Design Choices
@ -102,57 +138,67 @@ language rather than conform to specific API names or argument
patterns in the spec.
For a deeper discussion, see:
https://github.com/open-telemetry/opentelemetry-specification/issues/165
<https://github.com/open-telemetry/opentelemetry-specification/issues/165>
### Error Handling
Currently, the Opentelemetry Rust SDK has two ways to handle errors. In the situation where errors are not allowed to return. One should call global error handler to process the errors. Otherwise, one should return the errors.
The Opentelemetry Rust SDK comes with an error type `openetelemetry::Error`. For different function, one error has been defined. All error returned by trace module MUST be wrapped in `opentelemetry::trace::TraceError`. All errors returned by metrics module MUST be wrapped in `opentelemetry::metrics::MetricsError`.
Currently, the Opentelemetry Rust SDK has two ways to handle errors. In the situation where errors are not allowed to return. One should call global error handler to process the errors. Otherwise, one should return the errors.
For users that want to implement their own exporters. It's RECOMMENDED to wrap all errors from the exporter into a crate-level error type, and implement `ExporterError` trait.
The Opentelemetry Rust SDK comes with an error type `opentelemetry::Error`. For different function, one error has been defined. All error returned by trace module MUST be wrapped in `opentelemetry::trace::TraceError`. All errors returned by metrics module MUST be wrapped in `opentelemetry::metrics::MetricError`. All errors returned by logs module MUST be wrapped in `opentelemetry::logs::LogsError`.
For users that want to implement their own exporters. It's RECOMMENDED to wrap all errors from the exporter into a crate-level error type, and implement `ExporterError` trait.
### Priority of configurations
OpenTelemetry supports multiple ways to configure the API, SDK and other components. The priority of configurations is as follows:
- Environment variables
- Compiling time configurations provided in the source code
### Experimental/Unstable features
Use `otel_unstable` feature flag for implementation of specification with [experimental](https://github.com/open-telemetry/opentelemetry-specification/blob/v1.27.0/specification/document-status.md) status. This approach ensures clear demarcation and safe integration of new or evolving features. Utilize the following structure:
```rust
#[cfg(feature = "otel_unstable")]
{
// Your feature implementation
}
```
It's important to regularly review and remove the `otel_unstable` flag from the code once the feature becomes stable. This cleanup process is crucial to maintain the overall code quality and to ensure that stable features are accurately reflected in the main build.
### Optional features
The potential features include:
- Stable and non-experimental features that are compliant with the specification and have a feature flag to minimize compilation size. Example: feature flags for signals (like `logs`, `traces`, `metrics`) and runtimes (`rt-tokio`, `rt-tokio-current-thread`).
- Stable and non-experimental features, although not part of the specification, are crucial for enhancing the tracing/log crate's functionality or boosting performance. These features are also subject to discussion and approval by the OpenTelemetry Rust Maintainers.
All such features should adhere to naming convention `<signal>_<feature_name>`
## Style Guide
* Run `cargo clippy --all` - this will catch common mistakes and improve
- Run `cargo clippy --all` - this will catch common mistakes and improve
your Rust code
* Run `cargo fmt` - this will find and fix code formatting
- Run `cargo fmt` - this will find and fix code formatting
issues.
## Testing and Benchmarking
* Run `cargo test --all` - this will execute code and doc tests for all
- Run `cargo test --all` - this will execute code and doc tests for all
projects in this workspace.
* Run `cargo bench` - this will run benchmarks to show performance
- Run `cargo bench` - this will run benchmarks to show performance
- Run `cargo bench` - this will run benchmarks to show performance
regressions
## Approvers and Maintainers
For GitHub groups see the [code owners](CODEOWNERS) file.
### Maintainers
* [Dirkjan Ochtman](https://github.com/djc)
* [Julian Tescher](https://github.com/jtescher)
* [Zhongyang Wu](https://github.com/TommyCpp)
### Approvers
* [Harold Dost](https://github.com/hdost)
### Emeritus
* [Jan Kühle](https://github.com/frigus02)
* [Isobel Redelmeier](https://github.com/iredelmeier)
### Become an Approver or a Maintainer
See the [community membership document in OpenTelemetry community
repo](https://github.com/open-telemetry/community/blob/master/community-membership.md).
### Thanks to all the people who have contributed
[![contributors](https://contributors-img.web.app/image?repo=open-telemetry/opentelemetry-rust)](https://github.com/open-telemetry/opentelemetry-rust/graphs/contributors)
## FAQ
### Where should I put third party propagators/exporters, contrib or standalone crates?
As of now, the specification classify the propagators into three categories: Fully opened standards, platform-specific standards, proprietary headers. The conclusion is only the fully opened standards should live in SDK packages/repos. So here, only fully opened standards should live as independent crate. For more detail and discussion, see [this pr](https://github.com/open-telemetry/opentelemetry-specification/pull/1144).
As of now, the specification classify the propagators into three categories:
Fully opened standards, platform-specific standards, proprietary headers. The
conclusion is only the fully opened standards should live in SDK packages/repos.
So here, only fully opened standards should live as independent crate. For more
detail and discussion, see [this
pr](https://github.com/open-telemetry/opentelemetry-specification/pull/1144).

View File

@ -1,41 +1,94 @@
[workspace]
members = [
"opentelemetry",
"opentelemetry-api",
"opentelemetry-aws",
"opentelemetry-contrib",
"opentelemetry-datadog",
"opentelemetry-dynatrace",
"opentelemetry-http",
"opentelemetry-jaeger",
"opentelemetry-jaeger/examples/actix-udp",
"opentelemetry-jaeger/examples/remote-sampler",
"opentelemetry-appender-log",
"opentelemetry-appender-tracing",
"opentelemetry-otlp",
"opentelemetry-prometheus",
"opentelemetry-proto",
"opentelemetry-sdk",
"opentelemetry-semantic-conventions",
"opentelemetry-stackdriver",
"opentelemetry-stdout",
"opentelemetry-user-events-logs",
"opentelemetry-user-events-metrics",
"opentelemetry-zipkin",
"opentelemetry-zpages",
"opentelemetry-otlp/examples/basic-otlp",
"opentelemetry-otlp/examples/basic-otlp-http",
"opentelemetry-otlp/examples/external-otlp-grpcio-async-std",
"examples/metrics-basic",
"examples/metrics-advanced",
"examples/logs-basic",
"examples/traceresponse",
"examples/tracing-grpc",
"opentelemetry-*",
"opentelemetry-*/examples/*",
"opentelemetry-otlp/tests/*",
"examples/*",
"stress",
]
resolver = "2"
# Avoid applying patch to force use of workspace members for this
# not actively maintained crate
exclude = ["opentelemetry-prometheus"]
[profile.bench]
# https://doc.rust-lang.org/cargo/reference/profiles.html#bench
# See function names in profiling reports.
# 2/true is too much, 0 is not enough, 1 is just right for back traces
debug = 1
[workspace.dependencies]
async-trait = "0.1"
bytes = "1"
criterion = "0.5"
futures-core = "0.3"
futures-executor = "0.3"
futures-util = { version = "0.3", default-features = false }
http = { version = "1.1", default-features = false, features = ["std"] }
http-body-util = "0.1"
hyper = { version = "1.3", default-features = false }
hyper-util = "0.1"
log = "0.4.21"
once_cell = "1.13"
pin-project-lite = "0.2"
prost = "0.13"
prost-build = "0.13"
prost-types = "0.13"
rand = { version = "0.9", default-features = false }
reqwest = { version = "0.12", default-features = false }
serde = { version = "1.0", default-features = false }
serde_json = "1.0"
temp-env = "0.3.6"
thiserror = { version = "2", default-features = false }
tonic = { version = "0.13", default-features = false }
tonic-build = "0.13"
tokio = { version = "1", default-features = false }
tokio-stream = "0.1"
# Using `tracing 0.1.40` because 0.1.39 (which is yanked) introduces the ability to set event names in macros,
# required for OpenTelemetry's internal logging macros.
tracing = { version = ">=0.1.40", default-features = false }
# `tracing-core >=0.1.33` is required for compatibility with `tracing >=0.1.40`.
tracing-core = { version = ">=0.1.33", default-features = false }
tracing-subscriber = { version = "0.3", default-features = false }
url = { version = "2.5", default-features = false }
anyhow = "1.0.94"
base64 = "0.22.1"
chrono = { version = "0.4.34", default-features = false }
ctor = "0.2.9"
ctrlc = "3.2.5"
futures-channel = "0.3"
futures-sink = "0.3"
const-hex = "1.14.1"
lazy_static = "1.4.0"
num-format = "0.4.4"
num_cpus = "1.15.0"
opentelemetry-appender-tracing = { path = "opentelemetry-appender-tracing", default-features = false }
opentelemetry-otlp = { path = "opentelemetry-otlp" }
opentelemetry-stdout = { path = "opentelemetry-stdout" }
percent-encoding = "2.0"
rstest = "0.23.0"
schemars = "0.8"
sysinfo = "0.32"
tempfile = "3.3.0"
testcontainers = "0.23.1"
tracing-log = "0.2"
tracing-opentelemetry = "0.31"
typed-builder = "0.20"
uuid = "1.3"
# Aviod use of crates.io version of these crates through the tracing-opentelemetry dependencies
[patch.crates-io]
opentelemetry = { path = "opentelemetry" }
opentelemetry_sdk = { path = "opentelemetry-sdk" }
opentelemetry-stdout = { path = "opentelemetry-stdout" }
[workspace.lints.rust]
rust_2024_compatibility = { level = "warn", priority = -1 }
# No need to enable those, because it either not needed or results in ugly syntax
edition_2024_expr_fragment_specifier = "allow"
if_let_rescope = "allow"
tail_expr_drop_order = "allow"
[workspace.lints.clippy]
all = { level = "warn", priority = 1 }

View File

@ -186,7 +186,7 @@
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright The OpenTelemetry Authors
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.

234
README.md
View File

@ -1,22 +1,15 @@
![OpenTelemetry — An observability framework for cloud-native software.][splash]
[splash]: https://raw.githubusercontent.com/open-telemetry/opentelemetry-rust/main/assets/logo-text.png
# OpenTelemetry Rust
The Rust [OpenTelemetry](https://opentelemetry.io/) implementation.
[![Crates.io: opentelemetry](https://img.shields.io/crates/v/opentelemetry.svg)](https://crates.io/crates/opentelemetry)
[![Documentation](https://docs.rs/opentelemetry/badge.svg)](https://docs.rs/opentelemetry)
[![LICENSE](https://img.shields.io/crates/l/opentelemetry)](./LICENSE)
[![GitHub Actions CI](https://github.com/open-telemetry/opentelemetry-rust/workflows/CI/badge.svg)](https://github.com/open-telemetry/opentelemetry-rust/actions?query=workflow%3ACI+branch%3Amain)
[![Documentation](https://docs.rs/opentelemetry/badge.svg)](https://docs.rs/opentelemetry)
[![codecov](https://codecov.io/gh/open-telemetry/opentelemetry-rust/branch/main/graph/badge.svg)](https://codecov.io/gh/open-telemetry/opentelemetry-rust)
[![OpenSSF Scorecard](https://api.scorecard.dev/projects/github.com/open-telemetry/opentelemetry-rust/badge)](https://scorecard.dev/viewer/?uri=github.com/open-telemetry/opentelemetry-rust)
[![Slack](https://img.shields.io/badge/slack-@cncf/otel/rust-brightgreen.svg?logo=slack)](https://cloud-native.slack.com/archives/C03GDP0H023)
[Website](https://opentelemetry.io/) |
[Slack](https://cloud-native.slack.com/archives/C03GDP0H023) |
[Documentation](https://docs.rs/opentelemetry)
## Overview
OpenTelemetry is a collection of tools, APIs, and SDKs used to instrument,
@ -25,150 +18,134 @@ analysis in order to understand your software's performance and behavior. You
can export and analyze them using [Prometheus], [Jaeger], and other
observability tools.
*Compiler support: [requires `rustc` 1.60+][msrv]*
*[Supported Rust Versions](#supported-rust-versions)*
[Prometheus]: https://prometheus.io
[Jaeger]: https://www.jaegertracing.io
[msrv]: #supported-rust-versions
## Project Status
| Signal | Status |
| ------- | ---------- |
| Logs | Alpha* |
| Metrics | Alpha |
| Traces | Beta |
The table below summarizes the overall status of each component. Some components
include unstable features, which are documented in their respective crate
documentation.
| Signal/Component | Overall Status |
| -------------------- | ------------------ |
| Context | Beta |
| Baggage | RC |
| Propagators | Beta |
| Logs-API | Stable* |
| Logs-SDK | Stable |
| Logs-OTLP Exporter | RC |
| Logs-Appender-Tracing | Stable |
| Metrics-API | Stable |
| Metrics-SDK | Stable |
| Metrics-OTLP Exporter | RC |
| Traces-API | Beta |
| Traces-SDK | Beta |
| Traces-OTLP Exporter | Beta |
*OpenTelemetry Rust is not introducing a new end user callable Logging API.
Instead, it provides [Logs Bridge
API](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/logs/bridge-api.md),
API](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/logs/api.md),
that allows one to write log appenders that can bridge existing logging
libraries to the OpenTelemetry log data model. The following log appenders are
available:
* [opentelemetry-appender-log](opentelemetry-appender-log/README.md)
* [opentelemetry-appender-tracing](opentelemetry-appender-tracing/README.md)
* opentelemetry-appender-slog // TODO: Add link once available
If you already use the logging APIs from above, continue to use them, and use
the appenders above to bridge the logs to OpenTelemetry. If you are using a
library not listed here, feel free to contribute a new appender for the same.
If you are starting fresh, then consider using
If you are starting fresh, we recommend using
[tracing](https://github.com/tokio-rs/tracing) as your logging API. It supports
structured logging and is actively maintained.
structured logging and is actively maintained. `OpenTelemetry` itself uses
`tracing` for its internal logging.
Project versioning information and stability guarantees can be found
[here](VERSIONING.md).
## Getting Started
```rust
use opentelemetry::{
global,
sdk::trace::TracerProvider,
trace::{Tracer, TracerProvider as _},
};
If you are new to OpenTelemetry, start with the [Stdout
Example](./opentelemetry-stdout/examples/basic.rs). This example demonstrates
how to use OpenTelemetry for logs, metrics, and traces, and display
telemetry data on your console.
fn main() {
// Create a new trace pipeline that prints to stdout
let provider = TracerProvider::builder()
.with_simple_exporter(opentelemetry_stdout::SpanExporter::default())
.build();
let tracer = provider.tracer("readme_example");
For those using OTLP, the recommended OpenTelemetry Exporter for production
scenarios, refer to the [OTLP Example -
HTTP](./opentelemetry-otlp/examples/basic-otlp-http/README.md) and the [OTLP
Example - gRPC](./opentelemetry-otlp/examples/basic-otlp/README.md).
tracer.in_span("doing_work", |cx| {
// Traced app logic here...
});
Additional examples for various integration patterns can be found in the
[examples](./examples) directory.
// Shutdown trace pipeline
global::shutdown_tracer_provider();
}
```
## Overview of crates
See the [examples](./examples) directory for different integration patterns.
The following crates are maintained in this repo:
## Ecosystem
### Related Crates
In addition to `opentelemetry`, the [`open-telemetry/opentelemetry-rust`]
repository contains several additional crates designed to be used with the
`opentelemetry` ecosystem. This includes a collection of trace `SpanExporter`
and metrics pull and push controller implementations, as well as utility and
adapter crates to assist in propagating state and instrumenting applications.
In particular, the following crates are likely to be of interest:
- [`opentelemetry-aws`] provides unofficial propagators for AWS X-ray.
- [`opentelemetry-datadog`] provides additional exporters to [`Datadog`].
- [`opentelemetry-dynatrace`] provides additional exporters to Dynatrace.
- [`opentelemetry-contrib`] provides additional exporters and propagators that
are experimental.
- [`opentelemetry-http`] provides an interface for injecting and extracting
trace information from [`http`] headers.
- [`opentelemetry-jaeger`] provides a pipeline and exporter for sending trace
information to [`Jaeger`].
- [`opentelemetry-otlp`] exporter for sending trace and metric data in the OTLP
format to the OpenTelemetry collector.
- [`opentelemetry-prometheus`] provides a pipeline and exporter for sending
metrics information to [`Prometheus`].
- [`opentelemetry-semantic-conventions`] provides standard names and semantic
* [`opentelemetry`] This is the OpenTelemetry API crate, and is the crate
required to instrument libraries and applications. It contains Context API,
Baggage API, Propagators API, Logging Bridge API, Metrics API, and Tracing
API.
* [`opentelemetry-sdk`] This is the OpenTelemetry SDK crate, and contains the
official OpenTelemetry SDK implementation. It contains Logging SDK, Metrics
SDK, and Tracing SDK. It also contains propagator implementations.
* [`opentelemetry-otlp`] - exporter to send telemetry (logs, metrics and traces)
in the [OTLP
format](https://github.com/open-telemetry/opentelemetry-specification/tree/main/specification/protocol)
to an endpoint accepting OTLP. This could be the [OTel
Collector](https://github.com/open-telemetry/opentelemetry-collector),
telemetry backends like [Jaeger](https://www.jaegertracing.io/),
[Prometheus](https://prometheus.io/docs/prometheus/latest/feature_flags/#otlp-receiver)
or [vendor specific endpoints](https://opentelemetry.io/ecosystem/vendors/).
* [`opentelemetry-stdout`] exporter for sending logs, metrics and traces to
stdout, for learning/debugging purposes.
* [`opentelemetry-http`] This crate contains utility functions to help with
exporting telemetry, propagation, over [`http`].
* [`opentelemetry-appender-log`] This crate provides logging appender to route
logs emitted using the [log](https://docs.rs/log/latest/log/) crate to
opentelemetry.
* [`opentelemetry-appender-tracing`] This crate provides logging appender to
route logs emitted using the [tracing](https://crates.io/crates/tracing) crate
to opentelemetry.
* [`opentelemetry-jaeger-propagator`] provides context propagation using [jaeger
propagation
format](https://www.jaegertracing.io/docs/1.18/client-libraries/#propagation-format).
* [`opentelemetry-prometheus`] provides a pipeline and exporter for sending
metrics to [`Prometheus`].
* [`opentelemetry-semantic-conventions`] provides standard names and semantic
otel conventions.
- [`opentelemetry-stackdriver`] provides an exporter for Google's [Cloud Trace]
(which used to be called StackDriver).
- [`opentelemetry-zipkin`] provides a pipeline and exporter for sending trace
information to [`Zipkin`].
* [`opentelemetry-zipkin`] provides a pipeline and exporter for sending traces
to [`Zipkin`].
Additionally, there are also several third-party crates which are not
maintained by the `opentelemetry` project. These include:
In addition, there are several other useful crates in the [OTel Rust Contrib
repo](https://github.com/open-telemetry/opentelemetry-rust-contrib). A lot of
crates maintained outside OpenTelemetry owned repos can be found in the
[OpenTelemetry
Registry](https://opentelemetry.io/ecosystem/registry/?language=rust).
- [`tracing-opentelemetry`] provides integration for applications instrumented
using the [`tracing`] API and ecosystem.
- [`actix-web-opentelemetry`] provides integration for the [`actix-web`] web
server and ecosystem.
- [`opentelemetry-application-insights`] provides an unofficial [Azure
Application Insights] exporter.
- [`opentelemetry-tide`] provides integration for the [`Tide`] web server and
ecosystem.
If you're the maintainer of an `opentelemetry` ecosystem crate not listed
above, please let us know! We'd love to add your project to the list!
[`open-telemetry/opentelemetry-rust`]: https://github.com/open-telemetry/opentelemetry-rust
[`opentelemetry-jaeger`]: https://crates.io/crates/opentelemetry-jaeger
[`Jaeger`]: https://www.jaegertracing.io
[`opentelemetry-otlp`]: https://crates.io/crates/opentelemetry-otlp
[`opentelemetry`]: https://crates.io/crates/opentelemetry
[`opentelemetry-sdk`]: https://crates.io/crates/opentelemetry-sdk
[`opentelemetry-appender-log`]: https://crates.io/crates/opentelemetry-appender-log
[`opentelemetry-appender-tracing`]: https://crates.io/crates/opentelemetry-appender-tracing
[`opentelemetry-http`]: https://crates.io/crates/opentelemetry-http
[`opentelemetry-otlp`]: https://crates.io/crates/opentelemetry-otlp
[`opentelemetry-stdout`]: https://crates.io/crates/opentelemetry-stdout
[`opentelemetry-jaeger-propagator`]: https://crates.io/crates/opentelemetry-jaeger-propagator
[`opentelemetry-prometheus`]: https://crates.io/crates/opentelemetry-prometheus
[`opentelemetry-aws`]: https://crates.io/crates/opentelemetry-aws
[`Prometheus`]: https://prometheus.io
[`opentelemetry-zipkin`]: https://crates.io/crates/opentelemetry-zipkin
[`Zipkin`]: https://zipkin.io
[`opentelemetry-contrib`]: https://crates.io/crates/opentelemetry-contrib
[`Datadog`]: https://www.datadoghq.com
[`opentelemetry-datadog`]: https://crates.io/crates/opentelemetry-datadog
[`Dynatrace`]: https://www.dynatrace.com/
[`opentelemetry-dynatrace`]: https://crates.io/crates/opentelemetry-dynatrace
[`opentelemetry-semantic-conventions`]: https://crates.io/crates/opentelemetry-semantic-conventions
[`http`]: https://crates.io/crates/http
[`tracing-opentelemetry`]: https://crates.io/crates/tracing-opentelemetry
[`tracing`]: https://crates.io/crates/tracing
[`actix-web-opentelemetry`]: https://crates.io/crates/actix-web-opentelemetry
[`actix-web`]: https://crates.io/crates/actix-web
[`opentelemetry-application-insights`]: https://crates.io/crates/opentelemetry-application-insights
[Azure Application Insights]: https://docs.microsoft.com/en-us/azure/azure-monitor/app/app-insights-overview
[`opentelemetry-tide`]: https://crates.io/crates/opentelemetry-tide
[`Tide`]: https://crates.io/crates/tide
[`opentelemetry-stackdriver`]: https://crates.io/crates/opentelemetry-stackdriver
[Cloud Trace]: https://cloud.google.com/trace/
## Supported Rust Versions
OpenTelemetry is built against the latest stable release. The minimum supported
version is 1.60. The current OpenTelemetry version is not guaranteed to build
version is 1.75. The current OpenTelemetry version is not guaranteed to build
on Rust versions earlier than the minimum supported version.
The current stable Rust compiler and the three most recent minor versions
@ -183,14 +160,14 @@ this policy.
See the [contributing file](CONTRIBUTING.md).
The Rust special interest group (SIG) meets weekly on Tuesdays at 9 AM Pacific
Time (16:00 UTC). The meeting is subject to change depending on contributors'
availability. Check the [OpenTelemetry community
calendar](https://calendar.google.com/calendar/embed?src=google.com_b79e3e90j7bbsa2n2p5an5lf60%40group.calendar.google.com)
Time. The meeting is subject to change depending on contributors' availability.
Check the [OpenTelemetry community
calendar](https://github.com/open-telemetry/community?tab=readme-ov-file#calendar)
for specific dates and for Zoom meeting links. "OTel Rust SIG" is the name of
meeting for this group.
Meeting notes are available as a public [Google
doc](https://docs.google.com/document/d/1tGKuCsSnyT2McDncVJrMgg74_z8V06riWZa0Sr79I_4/edit).
doc](https://docs.google.com/document/d/12upOzNk8c3SFTjsL6IRohCWMgzLKoknSCOOdMakbWo4/edit).
If you have trouble accessing the doc, please get in touch on
[Slack](https://cloud-native.slack.com/archives/C03GDP0H023).
@ -198,3 +175,38 @@ The meeting is open for all to join. We invite everyone to join our meeting,
regardless of your experience level. Whether you're a seasoned OpenTelemetry
developer, just starting your journey, or simply curious about the work we do,
you're more than welcome to participate!
## Approvers and Maintainers
### Maintainers
* [Cijo Thomas](https://github.com/cijothomas), Microsoft
* [Harold Dost](https://github.com/hdost)
* [Lalit Kumar Bhasin](https://github.com/lalitb), Microsoft
* [Utkarsh Umesan Pillai](https://github.com/utpilla), Microsoft
* [Zhongyang Wu](https://github.com/TommyCpp)
For more information about the maintainer role, see the [community repository](https://github.com/open-telemetry/community/blob/main/guides/contributor/membership.md#maintainer).
### Approvers
* [Anton Grübel](https://github.com/gruebel), Baz
* [Björn Antonsson](https://github.com/bantonsson), Datadog
* [Scott Gerring](https://github.com/scottgerring), Datadog
* [Shaun Cox](https://github.com/shaun-cox), Microsoft
For more information about the approver role, see the [community repository](https://github.com/open-telemetry/community/blob/main/guides/contributor/membership.md#approver).
### Emeritus
* [Dirkjan Ochtman](https://github.com/djc)
* [Isobel Redelmeier](https://github.com/iredelmeier)
* [Jan Kühle](https://github.com/frigus02)
* [Julian Tescher](https://github.com/jtescher)
* [Mike Goldsmith](https://github.com/MikeGoldsmith)
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).
### Thanks to all the people who have contributed
[![contributors](https://contributors-img.web.app/image?repo=open-telemetry/opentelemetry-rust)](https://github.com/open-telemetry/opentelemetry-rust/graphs/contributors)

View File

@ -1,20 +1,39 @@
exclude=[
"actix-http",
"actix-http-tracing",
"actix-udp",
"actix-udp-example",
"tracing-grpc",
"http"
]
[graph]
exclude=[]
[licenses]
unlicensed = "deny"
allow = [
"MIT",
"Apache-2.0",
"ISC",
"BSD-3-Clause",
"OpenSSL"
]
exceptions = [
{ allow = ["CDLA-Permissive-2.0"], crate = "webpki-roots" }, # This crate is a dependency of `reqwest`.
{ allow = ["Unicode-3.0"], crate = "icu_collections" }, # This crate gets used transitively by `reqwest`.
{ allow = ["Unicode-3.0"], crate = "icu_locid" }, # This crate gets used transitively by `reqwest`.
{ allow = ["Unicode-3.0"], crate = "icu_locid_transform" }, # This crate gets used transitively by `reqwest`.
{ allow = ["Unicode-3.0"], crate = "icu_locid_transform_data" }, # This crate gets used transitively by `reqwest`.
{ allow = ["Unicode-3.0"], crate = "icu_locale_core" }, # This crate gets used transitively by `reqwest`.
{ allow = ["Unicode-3.0"], crate = "icu_normalizer" }, # This crate gets used transitively by `reqwest`.
{ allow = ["Unicode-3.0"], crate = "icu_normalizer_data" }, # This crate gets used transitively by `reqwest`.
{ allow = ["Unicode-3.0"], crate = "icu_properties" }, # This crate gets used transitively by `reqwest`.
{ allow = ["Unicode-3.0"], crate = "icu_properties_data" }, # This crate gets used transitively by `reqwest`.
{ allow = ["Unicode-3.0"], crate = "icu_provider" }, # This crate gets used transitively by `reqwest`.
{ allow = ["Unicode-3.0"], crate = "icu_provider_macros" }, # This crate gets used transitively by `reqwest`.
{ allow = ["Unicode-3.0"], crate = "potential_utf" }, # This crate gets used transitively by `reqwest`.
{ allow = ["Unicode-3.0"], crate = "litemap" }, # This crate gets used transitively by `reqwest`.
{ allow = ["Unicode-3.0"], crate = "tinystr" }, # This crate gets used transitively by `reqwest`.
{ allow = ["Unicode-3.0"], crate = "writeable" }, # This crate gets used transitively by `reqwest`.
{ allow = ["Unicode-3.0"], crate = "unicode-ident" }, # This crate gets used transitively by `reqwest` and other crates.
{ allow = ["Unicode-3.0"], crate = "yoke" }, # This crate gets used transitively by `reqwest`.
{ allow = ["Unicode-3.0"], crate = "yoke-derive" }, # This crate gets used transitively by `reqwest`.
{ allow = ["Unicode-3.0"], crate = "zerovec" }, # This crate gets used transitively by `reqwest`.
{ allow = ["Unicode-3.0"], crate = "zerotrie" }, # This crate gets used transitively by `reqwest`.
{ allow = ["Unicode-3.0"], crate = "zerovec-derive" }, # This crate gets used transitively by `reqwest`.
{ allow = ["Unicode-3.0"], crate = "zerofrom" }, # This crate gets used transitively by `reqwest`.
{ allow = ["Unicode-3.0"], crate = "zerofrom-derive" }, # This crate gets used transitively by `reqwest`.
]
[licenses.private]
@ -28,11 +47,31 @@ license-files = [
{ path = "LICENSE", hash = 0xbd0eed23 }
]
# This section is considered when running `cargo deny check advisories`
# More documentation for the advisories section can be found here:
# https://embarkstudios.github.io/cargo-deny/checks/advisories/cfg.html
[advisories]
ignore = [
# unsoundness in indirect dependencies without a safe upgrade below
"RUSTSEC-2021-0145",
"RUSTSEC-2019-0036"
]
unmaintained = "allow"
yanked = "allow"
unmaintained = "none"
yanked = "deny"
# This section is considered when running `cargo deny check bans`.
# More documentation about the 'bans' section can be found here:
# https://embarkstudios.github.io/cargo-deny/checks/bans/cfg.html
[bans]
# Lint level for when multiple versions of the same crate are detected
multiple-versions = "warn"
# Lint level for when a crate version requirement is `*`
wildcards = "warn"
# The graph highlighting used when creating dotgraphs for crates
# with multiple versions
# * lowest-version - The path to the lowest versioned duplicate is highlighted
# * simplest-path - The path to the version with the fewest edges is highlighted
# * all - Both lowest-version and simplest-path are used
highlight = "all"
# This section is considered when running `cargo deny check sources`.
# More documentation about the 'sources' section can be found here:
# https://embarkstudios.github.io/cargo-deny/checks/sources/cfg.html
[sources]
unknown-registry = "deny"
unknown-git = "deny"

View File

@ -0,0 +1,175 @@
# Error handling patterns in public API interfaces
## Date
27 Feb 2025
## Summary
This ADR describes the general pattern we will follow when modelling errors in public API interfaces - that is, APIs that are exposed to users of the project's published crates. It summarizes the discussion and final option from [#2571](https://github.com/open-telemetry/opentelemetry-rust/issues/2571); for more context check out that issue.
We will focus on the exporter traits in this example, but the outcome should be applied to _all_ public traits and their fallible operations.
These include [SpanExporter](https://github.com/open-telemetry/opentelemetry-rust/blob/eca1ce87084c39667061281e662d5edb9a002882/opentelemetry-sdk/src/trace/export.rs#L18), [LogExporter](https://github.com/open-telemetry/opentelemetry-rust/blob/eca1ce87084c39667061281e662d5edb9a002882/opentelemetry-sdk/src/logs/export.rs#L115), and [PushMetricExporter](https://github.com/open-telemetry/opentelemetry-rust/blob/eca1ce87084c39667061281e662d5edb9a002882/opentelemetry-sdk/src/metrics/exporter.rs#L11) which form part of the API surface of `opentelemetry-sdk`.
There are various ways to handle errors on trait methods, including swallowing them and logging, panicking, returning a shared global error, or returning a method-specific error. We strive for consistency, and we want to be sure that we've put enough thought into what this looks like that we don't have to make breaking interface changes unnecessarily in the future.
## Design Guidance
### 1. No panics from SDK APIs
Failures during regular operation should not panic, instead returning errors to the caller where appropriate, _or_ logging an error if not appropriate.
Some of the opentelemetry SDK interfaces are dictated by the specification in way such that they may not return errors.
### 2. Consolidate error types within a trait where we can, let them diverge when we can't**
We aim to consolidate error types where possible _without indicating a function may return more errors than it can actually return_.
**Don't do this** - each function's signature indicates that it returns errors it will _never_ return, forcing the caller to write handlers for dead paths:
```rust
enum MegaError {
TooBig,
TooSmall,
TooLong,
TooShort
}
trait MyTrait {
// Will only ever return TooBig,TooSmall errors
fn action_one() -> Result<(), MegaError>;
// These will only ever return TooLong,TooShort errors
fn action_two() -> Result<(), MegaError>;
fn action_three() -> Result<(), MegaError>;
}
```
**Instead, do this** - each function's signature indicates only the errors it can return, providing an accurate contract to the caller:
```rust
enum ErrorOne {
TooBig,
TooSmall,
}
enum ErrorTwo {
TooLong,
TooShort
}
trait MyTrait {
fn action_one() -> Result<(), ErrorOne>;
// Action two and three share the same error type.
// We do not introduce a common error MyTraitError for all operations, as this would
// force all methods on the trait to indicate they return errors they do not return,
// complicating things for the caller.
fn action_two() -> Result<(), ErrorTwo>;
fn action_three() -> Result<(), ErrorTwo>;
}
```
## 3. Consolidate error types between signals where we can, let them diverge where we can't
Consider the `Exporter`s mentioned earlier. Each of them has the same failure indicators - as dictated by the OpenTelemetry spec - and we will
share the error types accordingly:
**Don't do this** - each signal has its own error type, despite having exactly the same failure cases:
```rust
#[derive(Error, Debug)]
pub enum OtelTraceError {
#[error("Shutdown already invoked")]
AlreadyShutdown,
#[error("Operation failed: {0}")]
InternalFailure(String),
/** ... additional errors ... **/
}
#[derive(Error, Debug)]
pub enum OtelLogError {
#[error("Shutdown already invoked")]
AlreadyShutdown,
#[error("Operation failed: {0}")]
InternalFailure(String),
/** ... additional errors ... **/
}
```
**Instead, do this** - error types are consolidated between signals where this can be done appropriately:
```rust
/// opentelemetry-sdk::error
#[derive(Error, Debug)]
pub enum OTelSdkError {
#[error("Shutdown already invoked")]
AlreadyShutdown,
#[error("Operation failed: {0}")]
InternalFailure(String),
/** ... additional errors ... **/
}
pub type OTelSdkResult = Result<(), OTelSdkError>;
/// signal-specific exporter traits all share the same
/// result types for the exporter operations.
// pub trait LogExporter {
// pub trait SpanExporter {
pub trait PushMetricExporter {
fn export(&self, /* ... */) -> OtelSdkResult;
fn force_flush(&self, /* ... */ ) -> OTelSdkResult;
fn shutdown(&self, /* ... */ ) -> OTelSdkResult;
```
If this were _not_ the case - if we needed to mark an extra error for instance for `LogExporter` that the caller could reasonably handle -
we would let that error traits diverge at that point.
### 4. Box custom errors where a savvy caller may be able to handle them, stringify them if not
Note above that we do not box any `Error` into `InternalFailure`. Our rule here is that if the caller cannot reasonably be expected to handle a particular error variant, we will use a simplified interface that returns only a descriptive string. In the concrete example we are using with the exporters, we have a [strong signal in the opentelemetry-specification](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/logs/sdk.md#export) that indicates that the error types _are not actionable_ by the caller.
If the caller may potentially recover from an error, we will follow the generally-accepted best practice (e.g., see [canonical's guide](https://canonical.github.io/rust-best-practices/error-and-panic-discipline.html) and instead preserve the nested error:
**Don't do this if the OtherError is potentially recoverable by a savvy caller**:
```rust
#[derive(Debug, Error)]
pub enum MyError {
#[error("Error one occurred")]
ErrorOne,
#[error("Operation failed: {0}")]
OtherError(String),
```
**Instead, do this**, allowing the caller to match on the nested error:
```rust
#[derive(Debug, Error)]
pub enum MyError {
#[error("Error one occurred")]
ErrorOne,
#[error("Operation failed: {source}")]
OtherError {
#[from]
source: Box<dyn Error + Send + Sync>,
},
}
```
Note that at the time of writing, there is no instance we have identified within the project that has required this.
### 5. Use thiserror by default
We will use [thiserror](https://docs.rs/thiserror/latest/thiserror/) by default to implement Rust's [error trait](https://doc.rust-lang.org/core/error/trait.Error.html).
This keeps our code clean, and as it does not appear in our interface, we can choose to replace any particular usage with a hand-rolled implementation should we need to.
### 6. Don't use `#[non_exhaustive]` by default
If an `Error` response set is closed - if we can confidently say it is very unlikely to gain new variants in the future - we should not annotate it with `#[non_exhaustive]`. By way of example, the variants of the exporter error types described above are exhaustively documented in the OpenTelemetry Specification, and we can confidently say that we do not expect new variants.

5
docs/adr/README.md Normal file
View File

@ -0,0 +1,5 @@
# Architectural Decision Records
This directory contains architectural decision records made for the opentelemetry-rust project. These allow us to consolidate discussion, options, and outcomes, around key architectural decisions.
* [001 - Error Handling](001_error_handling.md)

378
docs/design/logs.md Normal file
View File

@ -0,0 +1,378 @@
# OpenTelemetry Rust Logs Design
Status:
[Development](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/document-status.md)
## Overview
[OpenTelemetry (OTel)
Logs](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/logs/README.md)
support differs from Metrics and Traces as it does not introduce a new logging
API for end users. Instead, OTel recommends leveraging existing logging
libraries such as [log](https://crates.io/crates/log) and
[tracing](https://crates.io/crates/tracing), while providing bridges (appenders)
to route logs through OpenTelemetry.
OTel took this different approach due to the long history of existing logging
solutions. In Rust, these are [log](https://crates.io/crates/log) and
[tracing](https://crates.io/crates/tracing), and have been embraced in the
community for some time. OTel Rust maintains appenders for these libraries,
allowing users to seamlessly integrate with OpenTelemetry without changing their
existing logging instrumentation.
The `tracing` appender is particularly optimized for performance due to its
widespread adoption and the fact that `tracing` itself has a bridge from the
`log` crate. Notably, OpenTelemetry Rust itself is instrumented using `tracing`
for internal logs. Additionally, when OTel began supporting logging as a signal,
the `log` crate lacked structured logging support, reinforcing the decision to
prioritize `tracing`.
## Benefits of OpenTelemetry Logs
- **Unified configuration** across Traces, Metrics, and Logs.
- **Automatic correlation** with Traces.
- **Consistent Resource attributes** across signals.
- **Multiple destinations support**: Logs can continue flowing to existing
destinations like stdout etc. while also being sent to an
OpenTelemetry-capable backend, typically via an OTLP Exporter or exporters
that export to operating system native systems like `Windows ETW` or `Linux
user_events`.
- **Standalone logging support** for applications that use OpenTelemetry as
their primary logging mechanism.
## Key Design Principles
- High performance - no locks/contention in the hot path with minimal/no heap
allocation where possible.
- Capped resource (memory) usage - well-defined behavior when overloaded.
- Self-observable - exposes telemetry about itself to aid in troubleshooting
etc.
- Robust error handling, returning Result where possible instead of panicking.
- Minimal public API, exposing based on need only.
## Architecture Overview
```mermaid
graph TD
subgraph Application
A1[Application Code]
end
subgraph Logging Libraries
B1[log crate]
B2[tracing crate]
end
subgraph OpenTelemetry
C1[OpenTelemetry Appender for log]
C2[OpenTelemetry Appender for tracing]
C3[OpenTelemetry Logs API]
C4[OpenTelemetry Logs SDK]
C5[OTLP Exporter]
end
subgraph Observability Backend
D1[OTLP-Compatible Backend]
end
A1 --> |Emits Logs| B1
A1 --> |Emits Logs| B2
B1 --> |Bridged by| C1
B2 --> |Bridged by| C2
C1 --> |Sends to| C3
C2 --> |Sends to| C3
C3 --> |Processes with| C4
C4 --> |Exports via| C5
C5 --> |Sends to| D1
```
## Logs API
Logs API is part of the [opentelemetry](https://crates.io/crates/opentelemetry)
crate.
The OTel Logs API is not intended for direct end-user usage. Instead, it is
designed for appender/bridge authors to integrate existing logging libraries
with OpenTelemetry. However, there is nothing preventing it from being used by
end-users.
### API Components
1. **Key-Value Structs**: Used in `LogRecord`, where `Key` struct is shared
across signals but `Value` struct differ from Metrics and Traces. This is
because values in Logs can contain more complex structures than those in
Traces and Metrics.
2. **Traits**:
- `LoggerProvider` - provides methods to obtain Logger.
- `Logger` - provides methods to create LogRecord and emit the created
LogRecord.
- `LogRecord` - provides methods to populate LogRecord.
3. **No-Op Implementations**: By default, the API performs no operations until
an SDK is attached.
### Logs Flow
1. Obtain a `LoggerProvider` implementation.
2. Use the `LoggerProvider` to create `Logger` instances, specifying a scope
name (module/component emitting logs). Optional attributes and version are
also supported.
3. Use the `Logger` to create an empty `LogRecord` instance.
4. Populate the `LogRecord` with body, timestamp, attributes, etc.
5. Call `Logger.emit(LogRecord)` to process and export the log.
If only the Logs API is used (without an SDK), all the above steps result in no
operations, following OpenTelemetrys philosophy of separating API from SDK. The
official Logs SDK provides real implementations to process and export logs.
Users or vendors can also provide alternative SDK implementations.
## Logs SDK
Logs SDK is part of the
[opentelemetry_sdk](https://crates.io/crates/opentelemetry_sdk) crate.
The OpenTelemetry Logs SDK provides an OTel specification-compliant
implementation of the Logs API, handling log processing and export.
### Core Components
#### `SdkLoggerProvider`
This is the implementation of the `LoggerProvider` and deals with concerns such
as processing and exporting Logs.
- Implements the `LoggerProvider` trait.
- Creates and manages `SdkLogger` instances.
- Holds logging configuration, including `Resource` and processors.
- Does not retain a list of created loggers. Instead, it passes an owned clone
of itself to each logger created. This is done so that loggers get a hold of
the configuration (like which processor to invoke).
- Uses an `Arc<LoggerProviderInner>` and delegates all configuration to
`LoggerProviderInner`. This allows cheap cloning of itself and ensures all
clones point to the same underlying configuration.
- As `SdkLoggerProvider` only holds an `Arc` of its inner, it can only take
`&self` in its methods like flush and shutdown. Else it needs to rely on
interior mutability that comes with runtime performance costs. Since methods
like shutdown usually need to mutate interior state, but this component can
only take `&self`, it defers to components like exporter to use interior
mutability to handle shutdown. (More on this in the exporter section)
- An alternative design was to let `SdkLogger` hold a `Weak` reference to the
`SdkLoggerProvider`. This would be a `weak->arc` upgrade in every log
emission, significantly affecting throughput.
- `LoggerProviderInner` implements `Drop`, triggering `shutdown()` when no
references remain. However, in practice, loggers are often stored statically
inside appenders (like tracing-appender), so explicit shutdown by the user is
required.
#### `SdkLogger`
This is an implementation of the `Logger`, and contains functionality to create
and emit logs.
- Implements the `Logger` trait.
- Creates `SdkLogRecord` instances and emits them.
- Calls `OnEmit()` on all registered processors when emitting logs.
- Passes mutable references to each processor (`&mut log_record`), i.e.,
ownership is not passed to the processor. This ensures that the logger avoids
cloning costs. Since a mutable reference is passed, processors can modify the
log, and it will be visible to the next processor in the chain.
- Since the processor only gets a reference to the log, it cannot store it
beyond the `OnEmit()`. If a processor needs to buffer logs, it must explicitly
copy them to the heap.
- This design allows for stack-only log processing when exporting to operating
system native facilities like `Windows ETW` or `Linux user_events`.
- OTLP Exporting requires network calls (HTTP/gRPC) and batching of logs for
efficiency purposes. These exporters buffer log records by copying them to the
heap. (More on this in the BatchLogRecordProcessor section)
#### `LogRecord`
- Holds log data, including attributes.
- Uses an inline array for up to 5 attributes to optimize stack usage.
- Falls back to a heap-allocated `Vec` if more attributes are required.
- Inspired by Gos `slog` library for efficiency.
#### LogRecord Processors
`SdkLoggerProvider` allows being configured with any number of LogProcessors.
They get called in the order of registration. Log records are passed to the
`OnEmit` method of LogProcessor. LogProcessors can be used to process the log
records, enrich them, filter them, and export to destinations by leveraging
LogRecord Exporters.
Similar to [LoggerProvider](#sdkloggerprovider), methods on the `LogProcessor`
trait also takes a immutable self (`&self`) only, forcing the need to use
interior mutability, if any mutation is required. The exception to this is
`set_resource`, which takes a `&mut self`. This is acceptable as `set_resource`
is called by the `SdkLoggerProvider` during build() method only, and is not
required after that.
Following built-in Log processors are provided in the Log SDK:
##### SimpleLogProcessor
This processor is designed to be used for exporting purposes. Export is handled
by an Exporter (which is a separate component). SimpleLogProcessor is "simple"
in the sense that it does not attempt to do any processing - it just calls the
exporter and passes the log record to it. To comply with OTel specification, it
synchronizes calls to the `Export()` method, i.e., only one `Export()` call will
be done at any given time.
SimpleLogProcessor is only used for test/learning purposes and is often used
along with a `stdout` exporter.
##### BatchLogProcessor
This is another "exporting" processor. As with SimpleLogProcessor, a different
component named LogExporter handles the actual export logic. BatchLogProcessor
buffers/batches the logs it receives into an in-memory buffer. It invokes the
exporter every 1 second or when 512 items are in the batch (customizable). It
uses a background thread to do the export, and communication between the user
thread (where logs are emitted) and the background thread occurs with `mpsc`
channels.
The max amount of items the buffer holds is 2048 (customizable). Once the limit
is reached, any *new* logs are dropped. It *does not* apply back-pressure to the
user thread and instead drops logs.
As with SimpleLogProcessor, this component also ensures only one export is
active at a given time. A modified version of this is required to achieve higher
throughput in some environments.
In this design, at most 2048+512 logs can be in memory at any given point. In
other words, that many logs can be lost if the app crashes in the middle.
## LogExporters
LogExporters are responsible for exporting logs to a destination.
`SdkLoggerProvider` does not have a direct knowledge of the `LogExporter`, as it
only deals with `LogProcessors`. It is the `LogProcessor`s that invokes
`LogExporter` methods. Most methods on `LogExporter` trait also only takes
`&self`, following the same reasoning as [LogProcessors](#logrecord-processors)
Some of the exporters are:
1. **InMemoryExporter** - exports to an in-memory list, primarily for
unit-testing. This is used extensively in the repo itself, and external users
are also encouraged to use this.
2. **Stdout exporter** - prints telemetry to stdout. Only for debugging/learning
purposes. The output format is not defined and also is not performance
optimized. A production-recommended version with a standardized output format
is in the plan.
3. **OTLP Exporter** - OTel's official exporter which uses the OTLP protocol
that is designed with the OTel data model in mind. Both HTTP and gRPC-based
exporting is offered.
4. **Exporters to OS Kernel facilities** - These exporters are not maintained in
the core repo but listed for completion. They export telemetry to Windows ETW
or Linux user_events. They are designed for high-performance workloads. Due
to their nature of synchronous exporting, they do not require
buffering/batching. This allows logs to operate entirely on the stack and can
scale easily with the number of CPU cores. (Kernel uses per-CPU buffers for
the events, ensuring no contention)
## `tracing` Log Appender
Tracing appender is part of the
[opentelemetry-appender-tracing](https://crates.io/crates/opentelemetry-appender-tracing)
crate.
The `tracing` appender bridges `tracing` logs to OpenTelemetry. Logs emitted via
`tracing` macros (`info!`, `warn!`, etc.) are forwarded to OpenTelemetry through
this integration.
- `tracing` is designed for high performance, using *layers* or *subscribers* to
handle emitted logs (events).
- The appender implements a `Layer`, receiving logs from `tracing`.
- Uses the OTel Logs API to create `LogRecord`, populate it, and emit it via
`Logger.emit(LogRecord)`.
- If no Logs SDK is present, the process is a no-op.
Note on terminology: Within OpenTelemetry, "tracing" refers to distributed
tracing (i.e creation of Spans) and not in-process structured logging and
execution traces. The crate "tracing" has notion of creating Spans as well as
Events. The events from "tracing" crate is what gets converted to OTel Logs,
when using this appender. Spans created using "tracing" crate is not handled by
this crate.
## Performance
// Call out things done specifically for performance
// Rough draft
1. `LogRecord` is stack allocated and not Boxed unless required by the component
needing to store it beyond the logging call. (eg: BatchProcessor)
2. LogRecords's Attribute storage is specially designed struct, that holds up to
five attributes in stack.
3. When passing `LogRecord`s to processor, a mutable ref is passed. This allows
calling multiple processors one after another, without the need for cloning.
4. `Logger` provides a `Enabled` check which can optimize performance when
no-one is interested in the log. The check is passed from `Logger` to the
processor, which may consult its exporter to make the decision. An example use
case - an ETW or user-events exporter can check for the presence of listener and
convey that decision back to logger, allowing appender to avoid even the cost of
creating a `LogRecord` in the first place if there is no listener. This check is
done for each log emission, and can react dynamically to changes in interest, by
enabling/disabling ETW/user-event listener.
5. `tracing` has a notion of "target", which is expected to be mapped to OTel's
concept of Instrumentation Scope for Logs, when `OpenTelemetry-Tracing-Appender`
bridges `tracing` to OpenTelemetry. Since scopes are tied to Loggers, a naive
approach would require creating a separate logger for each unique target. This
would necessitate an RWLock-protected HashMap lookup, introducing contention and
reducing throughput. To avoid this, `OpenTelemetry-Tracing-Appender` instead
stores the target directly in the LogRecord as a top-level field, ensuring fast
access in the hot path. Components processing the LogRecord can retrieve the
target via LogRecord.target(), treating it as the scope. The OTLP Exporter
already handles this automatically, so end-users will see “target” reflected in
the Instrumentation Scope. An alternative design would be to use thread-local
HashMaps - but it can cause increased memory usage, as there can be 100s of
unique targets. (because `tracing` defaults to using module path as target).
### Perf test - benchmarks
// Share ~~ numbers
### Perf test - stress test
// Share ~~ numbers
## Internal logs
OTel itself is instrumented with `tracing` crate to emit internal logs about its
operations. This is feature gated under "internal-logs", and is enabled by
default for all components. The `opentelemetry` provide few helper macros
`otel_warn` etc., which in turn invokes various `tracing` macros like `warn!`
etc. The cargo package name will be set as `target` when using `tracing`. For
example, logs from `opentelemetry-otlp` will have target set to
"opentelemetry-otlp".
The helper macros are part of public API, so can be used by anyone. But it is
only meant for OTel components itself and anyone writing extensions like custom
Exporters etc.
// TODO: Document the principles followed when selecting severity for internal
logs
When OpenTelemetry components generate logs that could potentially feed back
into OpenTelemetry, this can result in what is known as "telemetry-induced
telemetry." To address this, OpenTelemetry provides a mechanism to suppress such
telemetry using the `Context`. Components are expected to mark telemetry as
suppressed within a specific `Context` by invoking
`Context::enter_telemetry_suppressed_scope()`. The Logs SDK implementation
checks this flag in the current `Context` and ignores logs if suppression is
enabled.
This mechanism relies on proper in-process propagation of the `Context`.
However, external libraries like `hyper` and `tonic`, which are used by
OpenTelemetry in its OTLP Exporters, do not propagate OpenTelemetry's `Context`.
As a result, the suppression mechanism does not work out-of-the-box to suppress
logs originating from these libraries.
// TODO: Document how OTLP can solve this issue without asking external
crates to respect and propagate OTel Context.
## Summary
- OpenTelemetry Logs does not provide a user-facing logging API.
- Instead, it integrates with existing logging libraries (`log`, `tracing`).
- The Logs API defines key traits but performs no operations unless an SDK is
installed.
- The Logs SDK enables log processing, transformation, and export.
- The Logs SDK is performance optimized to minimize copying and heap allocation,
wherever feasible.
- The `tracing` appender efficiently routes logs to OpenTelemetry without
modifying existing logging workflows.

6
docs/design/metrics.md Normal file
View File

@ -0,0 +1,6 @@
# OpenTelemetry Rust Metrics Design
Status:
[Development](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/document-status.md)
TODO:

6
docs/design/traces.md Normal file
View File

@ -0,0 +1,6 @@
# OpenTelemetry Rust Traces Design
Status:
[Development](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/document-status.md)
TODO:

767
docs/metrics.md Normal file
View File

@ -0,0 +1,767 @@
# OpenTelemetry Rust Metrics
Status: **Work-In-Progress**
<details>
<summary>Table of Contents</summary>
* [Introduction](#introduction)
* [Best Practices](#best-practices)
* [Metrics API](#metrics-api)
* [Meter](#meter)
* [Instruments](#instruments)
* [Reporting measurements - use array slices for
attributes](#reporting-measurements---use-array-slices-for-attributes)
* [Reporting measurements via synchronous
instruments](#reporting-measurements-via-synchronous-instruments)
* [Reporting measurements via asynchronous
instruments](#reporting-measurements-via-asynchronous-instruments)
* [MeterProvider Management](#meterprovider-management)
* [Memory Management](#memory-management)
* [Example](#example)
* [Pre-Aggregation](#pre-aggregation)
* [Pre-Aggregation Benefits](#pre-aggregation-benefits)
* [Cardinality Limits](#cardinality-limits)
* [Cardinality Limits - Implications](#cardinality-limits---implications)
* [Cardinality Limits - Example](#cardinality-limits---example)
* [Memory Preallocation](#memory-preallocation)
* [Metrics Correlation](#metrics-correlation)
* [Modelling Metric Attributes](#modelling-metric-attributes)
* [Common Issues Leading to Missing
Metrics](#common-issues-that-lead-to-missing-metrics)
</details>
## Introduction
This document provides comprehensive guidance on leveraging OpenTelemetry
metrics in Rust applications. Whether you're tracking request counts, monitoring
response times, or analyzing resource utilization, this guide equips you with
the knowledge to implement robust and efficient metrics collection.
It covers best practices, API usage patterns, memory management techniques, and
advanced topics to help you design effective metrics solutions while steering
clear of common challenges.
## Best Practices
// TODO: Add link to the examples, once they are modified to show best
practices.
## Metrics API
### Meter
[Meter](https://docs.rs/opentelemetry/latest/opentelemetry/metrics/struct.Meter.html)
provides the ability to create instruments for recording measurements or
accepting callbacks to report measurements.
:stop_sign: You should avoid creating duplicate
[`Meter`](https://docs.rs/opentelemetry/latest/opentelemetry/metrics/struct.Meter.html)
instances with the same name. `Meter` is fairly expensive and meant to be reused
throughout the application. For most applications, a `Meter` should be obtained
from `global` and saved for re-use.
> [!IMPORTANT] Create your `Meter` instance once at initialization time and
> store it for reuse throughout your application's lifecycle.
The fully qualified module name might be a good option for the Meter name.
Optionally, one may create a meter with version, schema_url, and additional
meter-level attributes as well. Both approaches are demonstrated below.
```rust
use opentelemetry::global;
use opentelemetry::InstrumentationScope;
use opentelemetry::KeyValue;
let scope = InstrumentationScope::builder("my_company.my_product.my_library")
.with_version("0.17")
.with_schema_url("https://opentelemetry.io/schema/1.2.0")
.with_attributes([KeyValue::new("key", "value")])
.build();
// creating Meter with InstrumentationScope, comprising of
// name, version, schema and attributes.
let meter = global::meter_with_scope(scope);
// creating Meter with just name
let meter = global::meter("my_company.my_product.my_library");
```
### Instruments
OpenTelemetry defines several types of metric instruments, each optimized for
specific usage patterns. The following table maps OpenTelemetry Specification
instruments to their corresponding Rust SDK types.
:heavy_check_mark: You should understand and pick the right instrument type.
> [!NOTE] Picking the right instrument type for your use case is crucial to
> ensure the correct semantics and performance. Check the [Instrument
Selection](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/supplementary-guidelines.md#instrument-selection)
section from the supplementary guidelines for more information.
| OpenTelemetry Specification | OpenTelemetry Rust Instrument Type |
| --------------------------- | -------------------- |
| [Asynchronous Counter](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/api.md#asynchronous-counter) | [`ObservableCounter`](https://docs.rs/opentelemetry/latest/opentelemetry/metrics/struct.ObservableCounter.html) |
| [Asynchronous Gauge](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/api.md#asynchronous-gauge) | [`ObservableGauge`](https://docs.rs/opentelemetry/latest/opentelemetry/metrics/struct.ObservableGauge.html) |
| [Asynchronous UpDownCounter](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/api.md#asynchronous-updowncounter) | [`ObservableUpDownCounter`](https://docs.rs/opentelemetry/latest/opentelemetry/metrics/struct.ObservableUpDownCounter.html) |
| [Counter](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/api.md#counter) | [`Counter`](https://docs.rs/opentelemetry/latest/opentelemetry/metrics/struct.Counter.html) |
| [Gauge](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/api.md#gauge) | [`Gauge`](https://docs.rs/opentelemetry/latest/opentelemetry/metrics/struct.Gauge.html) |
| [Histogram](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/api.md#histogram) | [`Histogram`](https://docs.rs/opentelemetry/latest/opentelemetry/metrics/struct.Histogram.html) |
| [UpDownCounter](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/api.md#updowncounter) | [`UpDownCounter`](https://docs.rs/opentelemetry/latest/opentelemetry/metrics/struct.UpDownCounter.html) |
:stop_sign: You should avoid creating duplicate instruments (e.g., `Counter`)
with the same name. Instruments are fairly expensive and meant to be reused
throughout the application. For most applications, an instrument should be
created once and saved for re-use. Instruments can also be cloned to create
multiple handles to the same instrument, but cloning should not occur on the hot
path. Instead, the cloned instance should be stored and reused.
:stop_sign: Do NOT use invalid instrument names.
> [!NOTE] OpenTelemetry will not collect metrics from instruments that are using
> invalid names. Refer to the [OpenTelemetry
Specification](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/api.md#instrument-name-syntax)
for the valid syntax.
:stop_sign: You should avoid changing the order of attributes while reporting
measurements.
> [!WARNING] The last line of code has bad performance since the attributes are
> not following the same order as before:
```rust
let counter = meter.u64_counter("fruits_sold").build();
counter.add(2, &[KeyValue::new("color", "red"), KeyValue::new("name", "apple")]);
counter.add(3, &[KeyValue::new("color", "green"), KeyValue::new("name", "lime")]);
counter.add(5, &[KeyValue::new("color", "yellow"), KeyValue::new("name", "lemon")]);
counter.add(8, &[KeyValue::new("name", "lemon"), KeyValue::new("color", "yellow")]); // bad performance
```
:heavy_check_mark: If feasible, provide the attributes sorted by `Key`s in
ascending order to minimize memory usage within the Metrics SDK. Using
consistent attribute ordering allows the SDK to efficiently reuse internal data
structures.
```rust
// Good practice: Consistent attribute ordering
let counter = meter.u64_counter("fruits_sold").build();
counter.add(2, &[KeyValue::new("color", "red"), KeyValue::new("name", "apple")]);
```
### Reporting measurements - use array slices for attributes
:heavy_check_mark: When reporting measurements, use array slices for attributes
rather than creating vectors. Arrays are more efficient as they avoid
unnecessary heap allocations on the measurement path. This is true for both
synchronous and observable instruments.
```rust
// Good practice: Using an array slice directly
counter.add(2, &[KeyValue::new("color", "red"), KeyValue::new("name", "apple")]);
// Observable instrument
let _observable_counter = meter
.u64_observable_counter("request_count")
.with_description("Counts HTTP requests")
.with_unit("requests") // Optional: Adding units improves context
.with_callback(|observer| {
// Good practice: Using an array slice directly
observer.observe(
100,
&[KeyValue::new("endpoint", "/api")]
)
})
.build();
// Avoid this: Creating a Vec is unnecessary, and it allocates on the heap each time
// counter.add(2, &vec![KeyValue::new("color", "red"), KeyValue::new("name", "apple")]);
```
### Reporting measurements via synchronous instruments
:heavy_check_mark: Use synchronous Counter when you need to increment counts at
specific points in your code:
```rust
// Example: Using Counter when incrementing at specific code points
use opentelemetry::KeyValue;
fn process_item(counter: &opentelemetry::metrics::Counter<u64>, item_type: &str) {
// Process item...
// Increment the counter with the item type as an attribute
counter.add(1, &[KeyValue::new("type", item_type)]);
}
```
### Reporting measurements via asynchronous instruments
Asynchronous instruments like `ObservableCounter` are ideal for reporting
metrics that are already being tracked or stored elsewhere in your application.
These instruments allow you to observe and report the current state of such
metric.
:heavy_check_mark: Use `ObservableCounter` when you already have a variable
tracking a count:
```rust
// Example: Using ObservableCounter when you already have a variable tracking counts
use opentelemetry::KeyValue;
use std::sync::atomic::{AtomicU64, Ordering};
// An existing variable in your application
static REQUEST_COUNT: AtomicU64 = AtomicU64::new(0);
// In your application code, you update this directly
fn handle_request() {
// Process request...
REQUEST_COUNT.fetch_add(1, Ordering::SeqCst);
}
// When setting up metrics, register an observable counter that reads from your variable
fn setup_metrics(meter: &opentelemetry::metrics::Meter) {
let _observable_counter = meter
.u64_observable_counter("request_count")
.with_description("Number of requests processed")
.with_unit("requests")
.with_callback(|observer| {
// Read the current value from your existing counter
observer.observe(
REQUEST_COUNT.load(Ordering::SeqCst),
&[KeyValue::new("endpoint", "/api")]
)
})
.build();
}
```
> [!NOTE] The callbacks in the Observable instruments are invoked by the SDK
> during each export cycle.
## MeterProvider Management
Most use-cases require you to create ONLY one instance of MeterProvider. You
should NOT create multiple instances of MeterProvider unless you have some
unusual requirement of having different export strategies within the same
application. Using multiple instances of MeterProvider requires users to
exercise caution.
// TODO: Mention about creating per-thread MeterProvider // as shown in
[this](https://github.com/open-telemetry/opentelemetry-rust/pull/2659) // PR
:heavy_check_mark: Properly manage the lifecycle of `MeterProvider` instances if
you create them. Creating a MeterProvider is typically done at application
startup. Follow these guidelines:
* **Cloning**: A `MeterProvider` is a handle to an underlying provider. Cloning
it creates a new handle pointing to the same provider. Clone the
`MeterProvider` when necessary, but re-use the cloned instead of repeatedly
cloning.
* **Set as Global Provider**: Use `opentelemetry::global::set_meter_provider` to
set a clone of the `MeterProvider` as the global provider. This ensures
consistent usage across the application, allowing applications and libraries
to obtain `Meter` from the global instance.
* **Shutdown**: Explicitly call `shutdown` on the `MeterProvider` at the end of
your application to ensure all metrics are properly flushed and exported.
> [!NOTE] If you did not use `opentelemetry::global::set_meter_provider` to set
> a clone of the `MeterProvider` as the global provider, then you should be
> aware that dropping the last instance of `MeterProvider` implicitly calls
> shutdown on the provider.
:heavy_check_mark: Always call `shutdown` on the `MeterProvider` at the end of
your application to ensure proper cleanup.
## Memory Management
In OpenTelemetry,
[measurements](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/api.md#measurement)
are reported via the metrics API. The SDK
[aggregates](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/sdk.md#aggregation)
metrics using certain algorithms and memory management strategies to achieve
good performance and efficiency. Here are the rules which OpenTelemetry Rust
follows while implementing the metrics aggregation logic:
1. [**Pre-Aggregation**](#pre-aggregation): aggregation occurs within the SDK.
2. [**Cardinality Limits**](#cardinality-limits): the aggregation logic respects
[cardinality
limits](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/sdk.md#cardinality-limits),
so the SDK does not use an indefinite amount of memory in the event of a
cardinality explosion.
3. [**Memory Preallocation**](#memory-preallocation): SDK tries to pre-allocate
the memory it needs at each instrument creation time.
### Example
Let us take the following example of OpenTelemetry Rust metrics being used to
track the number of fruits sold:
* During the time range (T0, T1]:
* value = 1, color = `red`, name = `apple`
* value = 2, color = `yellow`, name = `lemon`
* During the time range (T1, T2]:
* no fruit has been sold
* During the time range (T2, T3]:
* value = 5, color = `red`, name = `apple`
* value = 2, color = `green`, name = `apple`
* value = 4, color = `yellow`, name = `lemon`
* value = 2, color = `yellow`, name = `lemon`
* value = 1, color = `yellow`, name = `lemon`
* value = 3, color = `yellow`, name = `lemon`
### Example - Cumulative Aggregation Temporality
If we aggregate and export the metrics using [Cumulative Aggregation
Temporality](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/data-model.md#temporality):
* (T0, T1]
* attributes: {color = `red`, name = `apple`}, count: `1`
* attributes: {color = `yellow`, name = `lemon`}, count: `2`
* (T0, T2]
* attributes: {color = `red`, name = `apple`}, count: `1`
* attributes: {color = `yellow`, name = `lemon`}, count: `2`
* (T0, T3]
* attributes: {color = `red`, name = `apple`}, count: `6`
* attributes: {color = `green`, name = `apple`}, count: `2`
* attributes: {color = `yellow`, name = `lemon`}, count: `12`
Note that the start time is not advanced, and the exported values are the
cumulative total of what happened since the beginning.
### Example - Delta Aggregation Temporality
If we aggregate and export the metrics using [Delta Aggregation
Temporality](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/data-model.md#temporality):
* (T0, T1]
* attributes: {color = `red`, name = `apple`}, count: `1`
* attributes: {color = `yellow`, name = `lemon`}, count: `2`
* (T1, T2]
* nothing since we do not have any measurement received
* (T2, T3]
* attributes: {color = `red`, name = `apple`}, count: `5`
* attributes: {color = `green`, name = `apple`}, count: `2`
* attributes: {color = `yellow`, name = `lemon`}, count: `10`
Note that the start time is advanced after each export, and only the delta since
last export is exported, allowing the SDK to "forget" previous state.
### Pre-Aggregation
Rather than exporting every individual measurement to the backend, OpenTelemetry
Rust aggregates data locally and only exports the aggregated metrics.
Using the [fruit example](#example), there are six measurements reported during
the time range `(T2, T3]`. Instead of exporting each individual measurement
event, the SDK aggregates them and exports only the summarized results. This
summarization process, illustrated in the following diagram, is known as
pre-aggregation:
```mermaid
graph LR
subgraph SDK
Instrument --> | Measurements | Pre-Aggregation[Pre-Aggregation]
end
subgraph Collector
Aggregation
end
Pre-Aggregation --> | Metrics | Aggregation
```
In addition to the in-process aggregation performed by the OpenTelemetry Rust
Metrics SDK, further aggregations can be carried out by the Collector and/or the
metrics backend.
### Pre-Aggregation Benefits
Pre-aggregation offers several advantages:
1. **Reduced Data Volume**: Summarizes measurements before export, minimizing
network overhead and improving efficiency.
2. **Predictable Resource Usage**: Ensures consistent resource consumption by
applying [cardinality limits](#cardinality-limits) and [memory
preallocation](#memory-preallocation) during SDK initialization. In other
words, metrics memory/network usage remains capped, regardless of the volume
of measurements being made.This ensures that resource utilization remains
stable despite fluctuations in traffic volume.
3. **Improved Performance**: Reduces serialization costs as we work with
aggregated data and not the numerous individual measurements. It also reduces
computational load on downstream systems, enabling them to focus on analysis
and storage.
> [!NOTE] There is no ability to opt out of pre-aggregation in OpenTelemetry.
### Cardinality Limits
The number of distinct combinations of attributes for a given metric is referred
to as the cardinality of that metric. Taking the [fruit example](#example), if
we know that we can only have apple/lemon as the name, red/yellow/green as the
color, then we can say the cardinality is 6 (i.e., 2 names × 3 colors = 6
combinations). No matter how many fruits we sell, we can always use the
following table to summarize the total number of fruits based on the name and
color.
| Color | Name | Count |
| ------ | ----- | ----- |
| red | apple | 6 |
| yellow | apple | 0 |
| green | apple | 2 |
| red | lemon | 0 |
| yellow | lemon | 12 |
| green | lemon | 0 |
In other words, we know how much memory and network are needed to collect and
transmit these metrics, regardless of the traffic pattern or volume.
In real world applications, the cardinality can be extremely high. Imagine if we
have a long running service and we collect metrics with 7 attributes and each
attribute can have 30 different values. We might eventually end up having to
remember the complete set of 30⁷ - or 21.87 billion combinations! This
cardinality explosion is a well-known challenge in the metrics space. For
example, it can cause:
* Surprisingly high costs in the observability system
* Excessive memory consumption in your application
* Poor query performance in your metrics backend
* Potential denial-of-service vulnerability that could be exploited by bad
actors
[Cardinality
limit](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/sdk.md#cardinality-limits)
is a throttling mechanism which allows the metrics collection system to have a
predictable and reliable behavior when there is a cardinality explosion, be it
due to a malicious attack or developer making mistakes while writing code.
OpenTelemetry has a default cardinality limit of `2000` per metric. This limit
can be configured at the individual metric level using the [View
API](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/sdk.md#view)
leveraging the
[`cardinality_limit`](https://docs.rs/opentelemetry_sdk/latest/opentelemetry_sdk/metrics/struct.Stream.html#structfield.cardinality_limit)
setting.
It's important to understand that this cardinality limit applies only at the
OpenTelemetry SDK level, not to the ultimate cardinality of the metric as seen
by the backend system. For example, while a single process might be limited to
2000 attribute combinations per metric, the actual backend metrics system might
see much higher cardinality due to:
1. Resource attributes (such as `service.instance.id`, `host.name`, etc.) that
can be added to each metric
2. Multiple process instances running the same application across your
infrastructure
3. The possibility of reporting different key-value pair combinations in each
export interval, as the cardinality limit only applies to the number of
distinct attribute combinations tracked during a single export interval.
(This is only applicable to Delta temporality)
Therefore, the actual cardinality in your metrics backend can be orders of
magnitude higher than what any single OpenTelemetry SDK process handles in an
export cycle.
#### Cardinality Limits - Implications
Cardinality limits are enforced for each export interval, meaning the metrics
aggregation system only allows up to the configured cardinality limit of
distinct attribute combinations per metric. Understanding how this works in
practice is important:
* **Cardinality Capping**: When the limit is reached within an export interval,
any new attribute combination is not individually tracked but instead folded
into a single aggregation with the attribute `{"otel.metric.overflow": true}`.
This preserves the overall accuracy of aggregates (such as Sum, Count, etc.)
even though information about specific attribute combinations is lost. Every
measurement is accounted for - either with its original attributes or within
the overflow bucket.
* **Temporality Effects**: The impact of cardinality limits differs based on the
temporality mode:
* **Delta Temporality**: The SDK "forgets" the state after each
collection/export cycle. This means in each new interval, the SDK can track
up to the cardinality limit of distinct attribute combinations. Over time,
your metrics backend might see far more than the configured limit of
distinct combinations from a single process.
* **Cumulative Temporality**: Since the SDK maintains state across export
intervals, once the cardinality limit is reached, new attribute combinations
will continue to be folded into the overflow bucket. The total number of
distinct attribute combinations exported cannot exceed the cardinality limit
for the lifetime of that metric instrument.
* **Impact on Monitoring**: While cardinality limits protect your system from
unbounded resource consumption, they do mean that high-cardinality attributes
may not be fully represented in your metrics. Since cardinality capping can
cause metrics to be folded into the overflow bucket, it becomes impossible to
predict which specific attribute combinations were affected across multiple
collection cycles or different service instances.
This unpredictability creates several important considerations when querying
metrics in any backend system:
* **Total Accuracy**: OpenTelemetry Metrics always ensures the total
aggregation (sum of metric values across all attributes) remains accurate,
even when overflow occurs.
* **Attribute-Based Query Limitations**: Any metric query based on specific
attributes could be misleading, as it's possible that measurements recorded
with a superset of those attributes were folded into the overflow bucket due
to cardinality capping.
* **All Attributes Affected**: When overflow occurs, it's not just
high-cardinality attributes that are affected. The entire attribute
combination is replaced with the `{"otel.metric.overflow": true}` attribute,
meaning queries for any attribute in that combination will miss data points.
#### Cardinality Limits - Example
Extending our fruit sales tracking example, imagine we set a cardinality limit
of 3 and we're tracking sales with attributes for `name`, `color`, and
`store_location`:
During a busy sales period at time (T3, T4], we record:
1. 10 red apples sold at Downtown store
2. 5 yellow lemons sold at Uptown store
3. 8 green apples sold at Downtown store
4. 3 red apples sold at Midtown store (at this point, the cardinality limit is
hit, and attributes are replaced with overflow attribute.)
The exported metrics would be:
* attributes: {color = `red`, name = `apple`, store_location = `Downtown`},
count: `10`
* attributes: {color = `yellow`, name = `lemon`, store_location = `Uptown`},
count: `5`
* attributes: {color = `green`, name = `apple`, store_location = `Downtown`},
count: `8`
* attributes: {`otel.metric.overflow` = `true`}, count: `3` ← Notice this
special overflow attribute
If we later query "How many red apples were sold?" the answer would be 10, not
13, because the Midtown sales were folded into the overflow bucket. Similarly,
queries about "How many items were sold in Midtown?" would return 0, not 3.
However, the total count across all attributes (i.e How many total fruits were
sold in (T3, T4] would correctly give 26) would be accurate.
This limitation applies regardless of whether the attribute in question is
naturally high-cardinality. Even low-cardinality attributes like "color"
become unreliable for querying if they were part of attribute combinations
that triggered overflow.
OpenTelemetry's cardinality capping is only applied to attributes provided
when reporting measurements via the [Metrics API](#metrics-api). In other
words, attributes used to create `Meter` or `Resource` attributes are not
subject to this cap.
#### Cardinality Limits - How to Choose the Right Limit
Choosing the right cardinality limit is crucial for maintaining efficient memory
usage and predictable performance in your metrics system. The optimal limit
depends on your temporality choice and application characteristics.
Setting the limit incorrectly can have consequences:
* **Limit too high**: Due to the SDK's [memory
preallocation](#memory-preallocation) strategy, excess memory will be
allocated upfront and remain unused, leading to resource waste.
* **Limit too low**: Measurements will be folded into the overflow bucket
(`{"otel.metric.overflow": true}`), losing granular attribute information and
making attribute-based queries unreliable.
Consider these guidelines when determining the appropriate limit:
##### Choosing the Right Limit for Cumulative Temporality
Cumulative metrics retain every unique attribute combination that has *ever*
been observed since the start of the process.
* You must account for the theoretical maximum number of attribute combinations.
* This can be estimated by multiplying the number of possible values for each
attribute.
* If certain attribute combinations are invalid or will never occur in practice,
you can reduce the limit accordingly.
###### Example - Fruit Sales Scenario
Attributes:
* `name` can be "apple" or "lemon" (2 values)
* `color` can be "red", "yellow", or "green" (3 values)
The theoretical maximum is 2 × 3 = 6 unique attribute sets.
For this example, the simplest approach is to use the theoretical maximum and **set the cardinality limit to 6**.
However, if you know that certain combinations will never occur (for example, if "red lemons" don't exist in your application domain), you could reduce the limit to only account for valid combinations. In this case, if only 5 combinations are valid, **setting the cardinality limit to 5** would be more memory-efficient.
##### Choosing the Right Limit for Delta Temporality
Delta metrics reset their aggregation state after every export interval. This
approach enables more efficient memory utilization by focusing only on attributes
observed during each interval rather than maintaining state for all combinations.
* **When attributes are low-cardinality** (as in the fruit example), use the
same calculation method as with cumulative temporality.
* **When high-cardinality attribute(s) exist** like `user_id`, leverage Delta
temporality's "forget state" nature to set a much lower limit based on active
usage patterns. This is where Delta temporality truly excels - when the set of
active values changes dynamically and only a small subset is active during any
given interval.
###### Example - High Cardinality Attribute Scenario
Export interval: 60 sec
Attributes:
* `user_id` (up to 1 million unique users)
* `success` (true or false, 2 values)
Theoretical limit: 1 million users × 2 = 2 million attribute sets
But if only 10,000 users are typically active during a 60 sec export interval:
10,000 × 2 = 20,000
**You can set the limit to 20,000, dramatically reducing memory usage during
normal operation.**
###### Export Interval Tuning
Shorter export intervals further reduce the required cardinality:
* If your interval is halved (e.g., from 60 sec to 30 sec), the number of unique
attribute sets seen per interval may also be halved.
> [!NOTE] More frequent exports increase CPU/network overhead due to
> serialization and transmission costs.
##### Choosing the Right Limit - Backend Considerations
While delta temporality offers certain advantages for cardinality management,
your choice may be constrained by backend support:
* **Backend Restrictions:** Some metrics backends only support cumulative
temporality. For example, Prometheus requires cumulative temporality and
cannot directly consume delta metrics.
* **Collector Conversion:** To leverage delta temporality's memory advantages
while maintaining backend compatibility, configure your SDK to use delta
temporality and deploy an OpenTelemetry Collector with a delta-to-cumulative
conversion processor. This approach pushes the memory overhead from your
application to the collector, which can be more easily scaled and managed
independently.
TODO: Add the memory cost incurred by each data points, so users can know the
memory impact of setting a higher limits.
TODO: Add example of how query can be affected when overflow occurs, use
[Aspire](https://github.com/dotnet/aspire/pull/7784) tool.
### Memory Preallocation
OpenTelemetry Rust SDK aims to avoid memory allocation on the hot code path.
When this is combined with [proper use of Metrics API](#metrics-api), heap
allocation can be avoided on the hot code path.
## Metrics Correlation
Including `TraceId` and `SpanId` as attributes in metrics might seem like an
intuitive way to achieve correlation with traces or logs. However, this approach
is ineffective and can make metrics practically unusable. Moreover, it can
quickly lead to cardinality issues, resulting in metrics being capped.
A better alternative is to use a concept in OpenTelemetry called
[Exemplars](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/sdk.md#exemplar).
Exemplars provide a mechanism to correlate metrics with traces by sampling
specific measurements and attaching trace context to them.
> [!NOTE] Currently, exemplars are not yet implemented in the OpenTelemetry Rust
> SDK.
## Modelling Metric Attributes
When metrics are being collected, they normally get stored in a [time series
database](https://en.wikipedia.org/wiki/Time_series_database). From storage and
consumption perspective, metrics can be multi-dimensional. Taking the [fruit
example](#example), there are two attributes - "name" and "color". For basic
scenarios, all the attributes can be reported during the [Metrics
API](#metrics-api) invocation, however, for less trivial scenarios, the
attributes can come from different sources:
* [Measurements](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/api.md#measurement)
reported via the [Metrics API](#metrics-api).
* Additional attributes provided at meter creation time via
[`meter_with_scope`](https://docs.rs/opentelemetry/latest/opentelemetry/metrics/trait.MeterProvider.html#tymethod.meter_with_scope).
* [Resources](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/resource/sdk.md)
configured at the `MeterProvider` level.
* Additional attributes provided by the collector. For example, [jobs and
instances](https://prometheus.io/docs/concepts/jobs_instances/) in Prometheus.
### Best Practices for Modeling Attributes
Follow these guidelines when deciding where to attach metric attributes:
* **For static attributes** (constant throughout the process lifetime):
* **Resource-level attributes**: If the dimension applies to all metrics
(e.g., hostname, datacenter), model it as a Resource attribute, or better
yet, let the collector add these automatically.
```rust
// Example: Setting resource-level attributes
let resource = Resource::new(vec![
KeyValue::new("service.name", "payment-processor"),
KeyValue::new("deployment.environment", "production"),
]);
```
* **Meter-level attributes**: If the dimension applies only to a subset of
metrics (e.g., library version), model it as meter-level attributes via
`meter_with_scope`.
```rust
// Example: Setting meter-level attributes
let scope = InstrumentationScope::builder("payment_library")
.with_version("1.2.3")
.with_attributes([KeyValue::new("payment.gateway", "stripe")])
.build();
let meter = global::meter_with_scope(scope);
```
* **For dynamic attributes** (values that change during execution):
* Report these via the Metrics API with each measurement.
* Be mindful that [cardinality limits](#cardinality-limits) apply to these
attributes.
```rust
// Example: Using dynamic attributes with each measurement
counter.add(1, &[
KeyValue::new("customer.tier", customer.tier),
KeyValue::new("transaction.status", status.to_string()),
]);
```
## Common issues that lead to missing metrics
Common pitfalls that can result in missing metrics include:
1. **Invalid instrument names** - OpenTelemetry will not collect metrics from
instruments using invalid names. See the [specification for valid
syntax](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/api.md#instrument-name-syntax).
2. **Not calling `shutdown` on the MeterProvider** - Ensure you properly call
`shutdown` at application termination to flush any pending metrics.
3. **Cardinality explosion** - When too many unique attribute combinations are
used, some metrics may be placed in the overflow bucket.
// TODO: Add more specific examples
## References
[OTel Metrics Specification - Supplementary Guidelines](https://opentelemetry.io/docs/specs/otel/metrics/supplementary-guidelines/)

187
docs/migration_0.28.md Normal file
View File

@ -0,0 +1,187 @@
# Migration guide from 0.27 to 0.28
OpenTelemetry Rust 0.28 introduces a large number of breaking changes that
impact all signals (logs/metrics/traces). This guide is intended to help with a
smooth migration for the common use cases of using `opentelemetry`,
`opentelemetry_sdk` `opentelemetry-otlp`, `opentelemetry-appender-tracing`
crates. The detailed changelog for each crate that you use can be consulted for
the full set of changes. This doc covers only the common scenario.
## Tracing Shutdown changes
`opentelemetry::global::shutdown_tracer_provider()` is removed. Now, you should
explicitly call shutdown() on the created tracer provider.
Before (0.27):
```rust
opentelemetry::global::shutdown_tracer_provider();
```
After (0.28):
```rust
let tracer_provider = opentelemetry_sdk::trace::SdkTracerProvider::builder()
.build();
// Clone and set the tracer provider globally. Retain the original to invoke shutdown later.
opentelemetry::global::set_tracer_provider(tracer_provider.clone());
// Shutdown the provider when application is exiting.
tracer_provider.shutdown();
```
This now makes shutdown consistent across signals.
## Rename SDK Structs
`LoggerProvider`, `TracerProvider` are renamed to `SdkLoggerProvider` and
`SdkTracerProvider` respectively. `MeterProvider` was already named
`SdkMeterProvider` and this now ensures consistency across signals.
### Async Runtime Requirements removed
When using OTLP Exporter for Logs, Traces a "batching" exporter is recommended.
Also, metrics always required a component named `PeriodicReader`. These
components previously needed user to pass in an async runtime and enable
appropriate feature flag depending on the runtime.
These components have been re-written to no longer require an async runtime.
Instead they operate by spawning dedicated background thread, and making
blocking calls from the same.
PeriodicReader, BatchSpanProcessor, BatchLogProcessor are the components
affected.
For Logs,Traces replace `.with_batch_exporter(exporter, runtime::Tokio)` with
`.with_batch_exporter(exporter)`.
For Metrics, replace `let reader =
PeriodicReader::builder(exporter, runtime::Tokio).build();` with `let reader =
PeriodicReader::builder(exporter).build();` or more conveniently,
`.with_periodic_exporter(exporter)`.
Please note the following:
* With the new approach, only the following grpc/http clients are supported in
`opentelemetry-otlp`.
`grpc-tonic` (OTLP
Exporter must be created from within a Tokio runtime)
`reqwest-blocking-client`
In other words,
`reqwest` and `hyper` are not supported.
If using exporters other than `opentelemetry-otlp`, consult the docs
for the same to know if there are any restrictions/requirements on async
runtime.
* Timeout enforcement is now moved to Exporters. i.e
BatchProcessor,PeriodicReader does not enforce timeouts. For logs and traces,
`max_export_timeout` (on Processors) or `OTEL_BLRP_EXPORT_TIMEOUT` or
`OTEL_BSP_EXPORT_TIMEOUT` is no longer supported. For metrics, `with_timeout` on
PeriodicReader is no longer supported.
`OTEL_EXPORTER_OTLP_TIMEOUT` can be used to setup timeout for OTLP Exporters
via environment variables, or `.with_tonic().with_timeout()` or
`.with_http().with_timeout()` programmatically.
* If you need the old behavior (your application cannot spawn a new thread, or
need to use another networking client etc.) use appropriate feature flag(s) from
below.
“experimental_metrics_periodicreader_with_async_runtime”
"experimental_logs_batch_log_processor_with_async_runtime"
"experimental_trace_batch_span_processor_with_async_runtime"
**and** adjust the namespace:
Example, when using Tokio runtime.
```rust
let reader = opentelemetry_sdk::metrics::periodic_reader_with_async_runtime::PeriodicReader::builder(exporter, runtime::Tokio).build();
let tracer_provider = SdkTracerProvider::builder()
.with_span_processor(span_processor_with_async_runtime::BatchSpanProcessor::builder(exporter, runtime::Tokio).build())
.build();
let logger_provider = SdkLoggerProvider::builder()
.with_log_processor(log_processor_with_async_runtime::BatchLogProcessor::builder(exporter, runtime::Tokio).build())
.build();
```
## OTLP Default change
"grpc-tonic" feature flag is no longer enabled by default in
`opentelemetry-otlp`. "http-proto" and "reqwest-blocking-client" features are
added as default, to align with the OTel specification.
## Resource Changes
`Resource` creation is moved to a builder pattern, and `Resource::{new, empty,
from_detectors, new_with_defaults, from_schema_url, merge, default}` are
replaced with `Resource::builder()`.
Before:
```rust
Resource::default().with_attributes([
KeyValue::new("service.name", "test_service"),
KeyValue::new("key", "value"),
]);
```
After:
```rust
Resource::builder()
.with_service_name("test_service")
.with_attribute(KeyValue::new("key", "value"))
.build();
```
## Improved internal logging
OpenTelemetry internally used `tracing` to emit its internal logs. This is under
feature-flag "internal-logs" that is enabled by default in all crates. When
using OTel Logging, care must be taken to avoid OTel's own internal log being
fed back to OTel, creating an circular dependency. This can be achieved via proper
filtering. The OTLP Examples in the repo shows how to achieve this. It also
shows how to send OTel's internal logs to stdout using `tracing::Fmt`.
## Full example
A fully runnable example application using OTLP Exporter is provided in this
repo. Comparing the 0.27 vs 0.28 of the example would give a good overview of
the changes required to be made.
[Basic OTLP Example
(0.27)](https://github.com/open-telemetry/opentelemetry-rust/tree/opentelemetry-otlp-0.27.0/opentelemetry-otlp/examples)
[Basic OTLP Example
(0.28)](https://github.com/open-telemetry/opentelemetry-rust/tree/opentelemetry-otlp-0.28.0/opentelemetry-otlp/examples)
This guide covers only the most common breaking changes. If youre using custom
exporters or processors (or authoring one), please consult the changelog for
additional migration details.
## Notes on Breaking Changes and the Path to 1.0
We understand that breaking changes can be challenging, but they are essential
for the growth and stability of the project. With the release of 0.28, the
Metric API (`opentelemetry` crate, "metrics" feature flag) and LogBridge API
(`opentelemetry` crate, "logs" feature flag) are now stable, and we do not
anticipate further breaking changes for these components.
Moreover, the `opentelemetry_sdk` crate for "logs" and "metrics" will have a
very high bar for any future breaking changes. Any changes are expected to
primarily impact those developing custom components, such as custom exporters.
In the upcoming releases, we aim to bring the "traces" feature to the same level
of stability as "logs" and "metrics". Additionally, "opentelemetry-otlp", the
official exporter, will also receive stability guarantees.
We are excited to announce that a 1.0 release, encompassing logs, metrics, and
traces, is planned for June 2025. We appreciate your patience and support as we
work towards this milestone. The 1.0 release will cover the API
(`opentelemetry`), SDK (`opentelemetry_sdk`), OTLP Exporter
(`opentelemetry-otlp`), and Tracing-Bridge (`opentelemetry-appender-tracing`).
We encourage you to share your feedback via GitHub issues or the OTel-Rust Slack
channel [here](https://cloud-native.slack.com/archives/C03GDP0H023).

92
docs/migration_0.29.md Normal file
View File

@ -0,0 +1,92 @@
# Migration Guide from 0.28 to 0.29
OpenTelemetry Rust 0.29 introduces a few breaking changes. This guide aims to
facilitate a smooth migration for common use cases involving the
`opentelemetry`, `opentelemetry_sdk`, `opentelemetry-otlp`, and
`opentelemetry-appender-tracing` crates. For a comprehensive list of changes,
please refer to the detailed changelog for each crate. This document covers only
the most common scenarios. Note that changes that only affect custom
exporter/processor authors are not mentioned in this doc.
OpenTelemetry Metrics API and Log-Bridge API were declared stable in 0.28, and have
no breaking changes.
## Baggage Changes
The Baggage API has been redesigned to align with the OpenTelemetry
specification. While the core API for interacting with Baggage remains the same,
the accepted data types have changed. Baggage Keys now only allow strings (ASCII
printable characters), and Baggage values are restricted to strings.
For detailed changes, see the [changelog](../opentelemetry/CHANGELOG.md). With
version 0.29, the Baggage API has reached "Release Candidate" status, meaning
further breaking changes will be highly restricted.
## Appender-Tracing Changes
The `opentelemetry-appender-tracing` crate, which bridges `tracing` events to
OpenTelemetry logs, has been updated to properly map `tracing` data types to the
OpenTelemetry model. As of version 0.29, this crate is considered "Stable," and
no further breaking changes will be made without a major version bump.
## Configuration via Environment Variables
The 0.29 release aligns OpenTelemetry Rust with the rest of the OpenTelemetry
ecosystem by treating any code-based configuration as final (i.e., it cannot be
overridden by environment variables). This policy was partially true before but
is now applied consistently. If you prefer to configure your application via
environment variables, avoid configuring it programmatically.
## Discontinuing Dedicated Prometheus Exporter
The `opentelemetry-prometheus` crate will be discontinued with the 0.29 release.
Active development on this crate ceased a few months ago. Given that Prometheus
now natively supports OTLP, and considering that the OpenTelemetry Rust project
is still working towards a 1.0 release, we need to focus on essential components
to maintain scope and ensure timely delivery.
Prometheus interoperability remains a key goal for OpenTelemetry. However, the
current `opentelemetry-prometheus` crate requires a major rewrite to eliminate
dependencies on unmaintained crates. We may reintroduce a dedicated Prometheus
exporter in the future once these issues are resolved.
### Migration Guide
For those using Prometheus as a backend, you can integrate with Prometheus using
the following methods:
1. Use the OTLP Exporter to push metrics directly to Prometheus.
2. If you require a pull (scrape) model, push metrics to an OpenTelemetry
Collector using the OTLP Exporter, and configure Prometheus to scrape the
OpenTelemetry Collector.
These alternatives ensure continued Prometheus integration while allowing us to
focus on achieving a stable 1.0 release for OpenTelemetry Rust.
## Next Release
In the [next
release](https://github.com/open-telemetry/opentelemetry-rust/milestone/21), we
expect to stabilize the Metrics SDK and resolve the long-standing question of
`tokio-tracing` vs. `opentelemetry tracing`, which is a prerequisite before
stabilizing Distributed Tracing. Additionally, `Context` is also expected to be
enhanced with the ability to suppress telemetry-induced-telemetry.
## Instrumentation Libraries
Unlike other OpenTelemetry language implementations, OpenTelemetry Rust historically did not
maintain any instrumentations directly. This has recently changed with a
[contribution](https://github.com/open-telemetry/opentelemetry-rust-contrib/pull/202)
from one of the founding members of the OpenTelemetry Rust project to the
contrib repository, providing an instrumentation library for
[`actix-web`](https://github.com/open-telemetry/opentelemetry-rust-contrib/tree/main/opentelemetry-instrumentation-actix-web).
We expect that this instrumentation will serve as a reference implementation demonstrating best practices for
creating OpenTelemetry instrumentations in Rust.
We welcome additional contributions of instrumentation libraries to the contrib repository.
## Thanks
Thank you to everyone who contributed to this milestone. Please share your feedback
through GitHub issues or join the discussion in the OTel-Rust Slack channel
[here](https://cloud-native.slack.com/archives/C03GDP0H023).

68
docs/release_0.30.md Normal file
View File

@ -0,0 +1,68 @@
# Release Notes 0.30
OpenTelemetry Rust 0.30 introduces a few breaking changes to the
`opentelemetry_sdk` crate in the `metrics` feature. These changes were essential
to drive the Metrics SDK towards stability. With this release, the Metrics SDK
is officially declared stable. The Metrics API was declared stable last year,
and previously, the Logs API, SDK, and OTel-Appender-Tracing were also marked
stable. Importantly, no breaking changes have been introduced to components
already marked as stable.
It is worth noting that the `opentelemetry-otlp` crate remains in a
Release-Candidate state and is not yet considered stable. With the API and SDK
for Logs and Metrics now stable, the focus will shift towards further refining
and stabilizing the OTLP Exporters in upcoming releases. Additionally,
Distributed Tracing is expected to progress towards stability, addressing key
interoperability challenges.
For detailed changelogs of individual crates, please refer to their respective
changelog files. This document serves as a summary of the main changes.
## Key Changes
### Metrics SDK Improvements
1. **Stabilized "view" features**: Previously under an experimental feature
flag, views can now be used to modify the name, unit, description, and
cardinality limit of a metric. Advanced view capabilities, such as changing
aggregation or dropping attributes, remain under the experimental feature
flag.
2. **Cardinality capping**: Introduced the ability to cap cardinality and
configure limits using views.
3. **Polished public API**: Refined the public API to hide implementation
details from exporters, enabling future internal optimizations and ensuring
consistency. Some APIs related to authoring custom metric readers have been
moved behind experimental feature flags. These advanced use cases require
more time to finalize the API surface before being included in the stable
release.
### Context-Based Suppression
Added the ability to suppress telemetry based on Context. This feature prevents
telemetry-induced-telemetry scenarios and addresses a long-standing issue. Note
that suppression relies on proper context propagation. Certain libraries used in
OTLP Exporters utilize `tracing` but do not adopt OpenTelemetry's context
propagation. As a result, not all telemetry is automatically suppressed with
this feature. Improvements in this area are expected in future releases.
## Next Release
In the [next
release](https://github.com/open-telemetry/opentelemetry-rust/milestone/22), the
focus will shift to OTLP Exporters and Distributed Tracing, specifically
resolving
[interoperability](https://github.com/open-telemetry/opentelemetry-rust/issues/2420)
issues with `tokio-tracing` and other fixes required to drive Distributed
Tracing towards stability.
## Acknowledgments
Thank you to everyone who contributed to this milestone. We welcome your
feedback through GitHub issues or discussions in the OTel-Rust Slack channel
[here](https://cloud-native.slack.com/archives/C03GDP0H023).
We are also excited to announce that [Anton Grübel](https://github.com/gruebel)
and [Björn Antonsson](https://github.com/bantonsson) have joined the OTel Rust
project as Approvers.

View File

@ -1,41 +1,67 @@
# Examples
This folder contains some examples that should help you get start crates from `opentelemetry-rust`.
This directory contains some examples that should help you get start crates from `opentelemetry-rust`.
## log-basic
**Logs**
This example uses following crates from this repo:
- opentelemetry(log)
- opentelemetry-appender-log
- opentelemetry-appender-tracing
- opentelemetry-stdout
Check this example if you want to understand *how to instrument logs using opentelemetry*.
## metrics-basic
**Metrics**
This example uses following crates from this repo:
- opentelemetry(metrics)
- opentelemetry-stdout
Check this example if you want to understand *how to instrument metrics using opentelemetry*.
## traceresponse
**Tracing**
## metrics-advanced
This example uses following crates from this repo:
- opentelemetry(tracing)
- opentelemetry-http
- opentelemetry-contrib(TraceContextResponsePropagator)
- opentelemetry(metrics)
- opentelemetry-stdout
This builds on top of the metrics-basic,
and shows advanced features in Metrics SDK like using Views.
## tracing-grpc
**Tracing**
This example uses following crates from this repo:
- opentelemetry(tracing)
- opentelemetry-jaeger
- opentelemetry-stdout
The application is built using `tokio`.
Check this example if you want to understand *how to integrate tracing with opentelemetry*.
Check this example if you want to understand *how to create spans and
propagate/restore context in OpenTelemetry* in a gRPC client-server application.
## tracing-http-propagator
This example uses following crates from this repo:
- opentelemetry(tracing)
- opentelemetry-http
- opentelemetry-stdout
Check this example if you want to understand *how to create spans and
propagate/restore context in OpenTelemetry* in an HTTP client-server
application.
## tracing-jaeger
This example uses following crates from this repo:
- opentelemetry(tracing)
- opentelemetry-otlp
The application is built using `tokio`.
Check this example if you want to understand *how to use OTLP Exporter to export traces to Jaeger*.

View File

@ -3,11 +3,18 @@ name = "logs-basic"
version = "0.1.0"
edition = "2021"
license = "Apache-2.0"
rust-version = "1.75.0"
publish = false
autobenches = false
[[bin]]
name = "logs-basic"
path = "src/main.rs"
bench = false
[dependencies]
opentelemetry_api = { path = "../../opentelemetry-api", features = ["logs"] }
opentelemetry_sdk = { path = "../../opentelemetry-sdk", features = ["logs"] }
opentelemetry-stdout = { path = "../../opentelemetry-stdout", features = ["logs"]}
opentelemetry-appender-log = { path = "../../opentelemetry-appender-log"}
log = {version = "0.4.17"}
opentelemetry-stdout = { workspace = true, features = ["logs"] }
opentelemetry-appender-tracing = { workspace = true }
tracing = { workspace = true, features = ["std"]}
tracing-subscriber = { workspace = true, features = ["env-filter","registry", "std", "fmt"] }

View File

@ -1,16 +1,17 @@
# Log Appender for API - Example
# OpenTelemetry Log Appender for tracing - Example
This example shows how to use the opentelemetry-appender-log crate, which is a
[logging appender](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/glossary.md#log-appender--bridge) that bridges logs from the [log crate](https://docs.rs/log/latest/log/) to OpenTelemetry.
The example setups a LoggerProvider with stdout exporter, so logs are emitted to stdout.
This example shows how to use the opentelemetry-appender-tracing crate, which is a
[logging
appender](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/glossary.md#log-appender--bridge)
that bridges logs from the [tracing crate](https://tracing.rs/tracing/#events) to
OpenTelemetry. The example setups a LoggerProvider with stdout exporter, so logs
are emitted to stdout.
## Usage
Run the following, and Logs emitted using [log](https://docs.rs/log/latest/log/) will be written out to stdout.
Run the following, and Logs emitted using [tracing](https://docs.rs/tracing/latest/tracing/)
will be written out to stdout.
```shell
$ cargo run
cargo run
```

View File

@ -1,28 +1,53 @@
use log::{error, Level};
use opentelemetry_api::KeyValue;
use opentelemetry_appender_log::OpenTelemetryLogBridge;
use opentelemetry_sdk::logs::{Config, LoggerProvider};
use opentelemetry_appender_tracing::layer;
use opentelemetry_sdk::logs::SdkLoggerProvider;
use opentelemetry_sdk::Resource;
use tracing::error;
use tracing_subscriber::{prelude::*, EnvFilter};
fn main() {
// Setup LoggerProvider with a stdout exporter
let exporter = opentelemetry_stdout::LogExporter::default();
let logger_provider = LoggerProvider::builder()
.with_config(
Config::default().with_resource(Resource::new(vec![KeyValue::new(
"service.name",
"logs-basic-example",
)])),
let provider: SdkLoggerProvider = SdkLoggerProvider::builder()
.with_resource(
Resource::builder()
.with_service_name("log-appender-tracing-example")
.build(),
)
.with_simple_exporter(exporter)
.build();
// Setup Log Appender for the log crate.
let otel_log_appender = OpenTelemetryLogBridge::new(&logger_provider);
log::set_boxed_logger(Box::new(otel_log_appender)).unwrap();
log::set_max_level(Level::Error.to_level_filter());
// To prevent a telemetry-induced-telemetry loop, OpenTelemetry's own internal
// logging is properly suppressed. However, logs emitted by external components
// (such as reqwest, tonic, etc.) are not suppressed as they do not propagate
// OpenTelemetry context. Until this issue is addressed
// (https://github.com/open-telemetry/opentelemetry-rust/issues/2877),
// filtering like this is the best way to suppress such logs.
//
// The filter levels are set as follows:
// - Allow `info` level and above by default.
// - Completely restrict logs from `hyper`, `tonic`, `h2`, and `reqwest`.
//
// Note: This filtering will also drop logs from these components even when
// they are used outside of the OTLP Exporter.
let filter_otel = EnvFilter::new("info")
.add_directive("hyper=off".parse().unwrap())
.add_directive("tonic=off".parse().unwrap())
.add_directive("h2=off".parse().unwrap())
.add_directive("reqwest=off".parse().unwrap());
let otel_layer = layer::OpenTelemetryTracingBridge::new(&provider).with_filter(filter_otel);
// Emit logs using macros from the log crate.
// These logs gets piped through OpenTelemetry bridge and gets exported to stdout.
error!(target: "my-target", "hello from {}. My price is {}", "apple", 2.99);
// Create a new tracing::Fmt layer to print the logs to stdout. It has a
// default filter of `info` level and above, and `debug` and above for logs
// from OpenTelemetry crates. The filter levels can be customized as needed.
let filter_fmt = EnvFilter::new("info").add_directive("opentelemetry=debug".parse().unwrap());
let fmt_layer = tracing_subscriber::fmt::layer()
.with_thread_names(true)
.with_filter(filter_fmt);
tracing_subscriber::registry()
.with(otel_layer)
.with(fmt_layer)
.init();
error!(name: "my-event-name", target: "my-system", event_id = 20, user_name = "otel", user_email = "otel@opentelemetry.io", message = "This is an example message");
let _ = provider.shutdown();
}

View File

@ -3,10 +3,17 @@ name = "metrics-advanced"
version = "0.1.0"
edition = "2021"
license = "Apache-2.0"
rust-version = "1.75.0"
publish = false
autobenches = false
[[bin]]
name = "metrics-advanced"
path = "src/main.rs"
bench = false
[dependencies]
opentelemetry_api = { path = "../../opentelemetry-api", features = ["metrics"] }
opentelemetry_sdk = { path = "../../opentelemetry-sdk", features = ["metrics", "rt-tokio"] }
opentelemetry-stdout = { path = "../../opentelemetry-stdout", features = ["metrics"]}
tokio = { version = "1.0", features = ["full"] }
opentelemetry = { path = "../../opentelemetry", features = ["metrics"] }
opentelemetry_sdk = { path = "../../opentelemetry-sdk" }
opentelemetry-stdout = { workspace = true, features = ["metrics"] }
tokio = { workspace = true, features = ["full"] }

View File

@ -12,6 +12,3 @@ Run the following, and the Metrics will be written out to stdout.
```shell
$ cargo run
```

View File

@ -1,18 +1,19 @@
use opentelemetry_api::metrics::Unit;
use opentelemetry_api::Key;
use opentelemetry_api::{metrics::MeterProvider as _, KeyValue};
use opentelemetry_sdk::metrics::{Instrument, MeterProvider, PeriodicReader, Stream};
use opentelemetry_sdk::{runtime, Resource};
use opentelemetry::global;
use opentelemetry::KeyValue;
use opentelemetry_sdk::metrics::{Instrument, SdkMeterProvider, Stream, Temporality};
use opentelemetry_sdk::Resource;
use std::error::Error;
fn init_meter_provider() -> MeterProvider {
fn init_meter_provider() -> opentelemetry_sdk::metrics::SdkMeterProvider {
// for example 1
let my_view_rename_and_unit = |i: &Instrument| {
if i.name == "my_histogram" {
if i.name() == "my_histogram" {
Some(
Stream::new()
.name("my_histogram_renamed")
.unit(Unit::new("milliseconds")),
Stream::builder()
.with_name("my_histogram_renamed")
.with_unit("milliseconds")
.build()
.unwrap(),
)
} else {
None
@ -20,31 +21,41 @@ fn init_meter_provider() -> MeterProvider {
};
// for example 2
let my_view_drop_attributes = |i: &Instrument| {
if i.name == "my_counter" {
Some(Stream::new().allowed_attribute_keys(vec![Key::from("mykey1")]))
let my_view_change_cardinality = |i: &Instrument| {
if i.name() == "my_second_histogram" {
// Note: If Stream is invalid, build() will return an error. By
// calling `.ok()`, any such error is ignored and treated as if the
// view does not match the instrument. If this is not the desired
// behavior, consider handling the error explicitly.
Stream::builder().with_cardinality_limit(2).build().ok()
} else {
None
}
};
let exporter = opentelemetry_stdout::MetricsExporter::default();
let reader = PeriodicReader::builder(exporter, runtime::Tokio).build();
MeterProvider::builder()
.with_reader(reader)
.with_resource(Resource::new(vec![KeyValue::new(
"service.name",
"metrics-advanced-example",
)]))
// Build exporter using Delta Temporality.
let exporter = opentelemetry_stdout::MetricExporterBuilder::default()
.with_temporality(Temporality::Delta)
.build();
let resource = Resource::builder()
.with_service_name("metrics-advanced-example")
.build();
let provider = SdkMeterProvider::builder()
.with_periodic_exporter(exporter)
.with_resource(resource)
.with_view(my_view_rename_and_unit)
.with_view(my_view_drop_attributes)
.build()
.with_view(my_view_change_cardinality)
.build();
global::set_meter_provider(provider.clone());
provider
}
#[tokio::main]
async fn main() -> Result<(), Box<dyn Error + Send + Sync + 'static>> {
let meter_provider = init_meter_provider();
let meter = meter_provider.meter("mylibraryname");
let meter = global::meter("mylibraryname");
// Example 1 - Rename metric using View.
// This instrument will be renamed to "my_histogram_renamed",
@ -52,43 +63,58 @@ async fn main() -> Result<(), Box<dyn Error + Send + Sync + 'static>> {
// using view.
let histogram = meter
.f64_histogram("my_histogram")
.with_unit(Unit::new("ms"))
.with_unit("ms")
.with_description("My histogram example description")
.init();
.build();
// Record measurements using the histogram instrument.
histogram.record(
10.5,
[
&[
KeyValue::new("mykey1", "myvalue1"),
KeyValue::new("mykey2", "myvalue2"),
KeyValue::new("mykey3", "myvalue3"),
KeyValue::new("mykey4", "myvalue4"),
]
.as_ref(),
],
);
// Example 2 - Drop unwanted attributes using view.
let counter = meter.u64_counter("my_counter").init();
// Example 2 - Change cardinality using View.
let histogram2 = meter
.f64_histogram("my_second_histogram")
.with_unit("ms")
.with_description("My histogram example description")
.build();
// Record measurements using the Counter instrument.
// Though we are passing 4 attributes here, only 1 will be used
// for aggregation as view is configured to use only "mykey1"
// attribute.
counter.add(
10,
[
KeyValue::new("mykey1", "myvalue1"),
KeyValue::new("mykey2", "myvalue2"),
KeyValue::new("mykey3", "myvalue3"),
KeyValue::new("mykey4", "myvalue4"),
]
.as_ref(),
);
// Record measurements using the histogram instrument. This metric will have
// a cardinality limit of 2, as set in the view. Because of this, only the
// first two distinct attribute combinations will be recorded, and the rest
// will be folded into the overflow attribute. Any number of measurements
// can be recorded as long as they use the same or already-seen attribute
// combinations.
histogram2.record(1.5, &[KeyValue::new("mykey1", "v1")]);
histogram2.record(1.2, &[KeyValue::new("mykey1", "v2")]);
// Metrics are exported by default every 30 seconds when using stdout exporter,
// Repeatedly emitting measurements for "v1" and "v2" will not
// trigger overflow, as they are already seen attribute combinations.
histogram2.record(1.7, &[KeyValue::new("mykey1", "v1")]);
histogram2.record(1.8, &[KeyValue::new("mykey1", "v2")]);
// Emitting measurements for new attribute combinations will trigger
// overflow, as the cardinality limit of 2 has been reached.
// All the below measurements will be folded into the overflow attribute.
histogram2.record(1.23, &[KeyValue::new("mykey1", "v3")]);
histogram2.record(1.4, &[KeyValue::new("mykey1", "v4")]);
histogram2.record(1.6, &[KeyValue::new("mykey1", "v5")]);
histogram2.record(1.7, &[KeyValue::new("mykey1", "v6")]);
histogram2.record(1.8, &[KeyValue::new("mykey1", "v7")]);
// Metrics are exported by default every 60 seconds when using stdout exporter,
// however shutting down the MeterProvider here instantly flushes
// the metrics, instead of waiting for the 30 sec interval.
// the metrics, instead of waiting for the 60 sec interval.
meter_provider.shutdown()?;
Ok(())
}

View File

@ -3,10 +3,18 @@ name = "metrics-basic"
version = "0.1.0"
edition = "2021"
license = "Apache-2.0"
rust-version = "1.75.0"
publish = false
autobenches = false
[[bin]]
name = "metrics-basic"
path = "src/main.rs"
bench = false
[dependencies]
opentelemetry_api = { path = "../../opentelemetry-api", features = ["metrics"] }
opentelemetry_sdk = { path = "../../opentelemetry-sdk", features = ["metrics", "rt-tokio"] }
opentelemetry-stdout = { path = "../../opentelemetry-stdout", features = ["metrics"]}
tokio = { version = "1.0", features = ["full"] }
opentelemetry = { path = "../../opentelemetry", features = ["metrics"] }
opentelemetry_sdk = { path = "../../opentelemetry-sdk", features = ["metrics"] }
opentelemetry-stdout = { workspace = true, features = ["metrics"] }
tokio = { workspace = true, features = ["full"] }

View File

@ -11,6 +11,3 @@ Run the following, and the Metrics will be written out to stdout.
```shell
$ cargo run
```

View File

@ -1,136 +1,176 @@
use opentelemetry_api::metrics::Unit;
use opentelemetry_api::{metrics::MeterProvider as _, KeyValue};
use opentelemetry_sdk::metrics::{MeterProvider, PeriodicReader};
use opentelemetry_sdk::{runtime, Resource};
use opentelemetry::{global, KeyValue};
use opentelemetry_sdk::metrics::SdkMeterProvider;
use opentelemetry_sdk::Resource;
use std::error::Error;
use std::vec;
fn init_meter_provider() -> MeterProvider {
let exporter = opentelemetry_stdout::MetricsExporter::default();
let reader = PeriodicReader::builder(exporter, runtime::Tokio).build();
MeterProvider::builder()
.with_reader(reader)
.with_resource(Resource::new(vec![KeyValue::new(
"service.name",
"metrics-basic-example",
)]))
.build()
fn init_meter_provider() -> opentelemetry_sdk::metrics::SdkMeterProvider {
let exporter = opentelemetry_stdout::MetricExporterBuilder::default()
// Build exporter using Delta Temporality (Defaults to Temporality::Cumulative)
// .with_temporality(opentelemetry_sdk::metrics::Temporality::Delta)
.build();
let provider = SdkMeterProvider::builder()
.with_periodic_exporter(exporter)
.with_resource(
Resource::builder()
.with_service_name("metrics-basic-example")
.build(),
)
.build();
global::set_meter_provider(provider.clone());
provider
}
#[tokio::main]
async fn main() -> Result<(), Box<dyn Error + Send + Sync + 'static>> {
async fn main() -> Result<(), Box<dyn Error>> {
// Initialize the MeterProvider with the stdout Exporter.
let meter_provider = init_meter_provider();
// Create a meter from the above MeterProvider.
let meter = meter_provider.meter("mylibraryname");
let meter = global::meter("mylibraryname");
// Create a Counter Instrument.
let counter = meter.u64_counter("my_counter").init();
let counter = meter.u64_counter("my_counter").build();
// Record measurements using the Counter instrument.
counter.add(
10,
[
&[
KeyValue::new("mykey1", "myvalue1"),
KeyValue::new("mykey2", "myvalue2"),
]
.as_ref(),
],
);
// Create a ObservableCounter instrument and register a callback that reports the measurement.
let observable_counter = meter
let _observable_counter = meter
.u64_observable_counter("my_observable_counter")
.with_description("My observable counter example description")
.with_unit(Unit::new("myunit"))
.init();
meter.register_callback(&[observable_counter.as_any()], move |observer| {
observer.observe_u64(
&observable_counter,
100,
[
KeyValue::new("mykey1", "myvalue1"),
KeyValue::new("mykey2", "myvalue2"),
]
.as_ref(),
)
})?;
.with_unit("myunit")
.with_callback(|observer| {
observer.observe(
100,
&[
KeyValue::new("mykey1", "myvalue1"),
KeyValue::new("mykey2", "myvalue2"),
],
)
})
.build();
// Create a UpCounter Instrument.
let updown_counter = meter.i64_up_down_counter("my_updown_counter").init();
let updown_counter = meter.i64_up_down_counter("my_updown_counter").build();
// Record measurements using the UpCounter instrument.
updown_counter.add(
-10,
[
&[
KeyValue::new("mykey1", "myvalue1"),
KeyValue::new("mykey2", "myvalue2"),
]
.as_ref(),
],
);
// Create a Observable UpDownCounter instrument and register a callback that reports the measurement.
let observable_up_down_counter = meter
let _observable_up_down_counter = meter
.i64_observable_up_down_counter("my_observable_updown_counter")
.with_description("My observable updown counter example description")
.with_unit(Unit::new("myunit"))
.init();
meter.register_callback(&[observable_up_down_counter.as_any()], move |observer| {
observer.observe_i64(
&observable_up_down_counter,
100,
[
KeyValue::new("mykey1", "myvalue1"),
KeyValue::new("mykey2", "myvalue2"),
]
.as_ref(),
)
})?;
.with_unit("myunit")
.with_callback(|observer| {
observer.observe(
100,
&[
KeyValue::new("mykey1", "myvalue1"),
KeyValue::new("mykey2", "myvalue2"),
],
)
})
.build();
// Create a Histogram Instrument.
let histogram = meter
.f64_histogram("my_histogram")
.with_description("My histogram example description")
.init();
// Setting boundaries is optional. By default, the boundaries are set to
// [0.0, 5.0, 10.0, 25.0, 50.0, 75.0, 100.0, 250.0, 500.0, 750.0, 1000.0, 2500.0, 5000.0, 7500.0, 10000.0]
.with_boundaries(vec![0.0, 5.0, 10.0, 15.0, 20.0, 25.0])
.build();
// Record measurements using the histogram instrument.
histogram.record(
10.5,
[
&[
KeyValue::new("mykey1", "myvalue1"),
KeyValue::new("mykey2", "myvalue2"),
]
.as_ref(),
],
);
// Note that there is no ObservableHistogram instrument.
// Create a ObservableGauge instrument and register a callback that reports the measurement.
// Create a Gauge Instrument.
let gauge = meter
.f64_observable_gauge("my_gauge")
.f64_gauge("my_gauge")
.with_description("A gauge set to 1.0")
.with_unit(Unit::new("myunit"))
.init();
.with_unit("myunit")
.build();
// Register a callback that reports the measurement.
meter.register_callback(&[gauge.as_any()], move |observer| {
observer.observe_f64(
&gauge,
1.0,
[
KeyValue::new("mykey1", "myvalue1"),
KeyValue::new("mykey2", "myvalue2"),
]
.as_ref(),
)
})?;
gauge.record(
1.0,
&[
KeyValue::new("mykey1", "myvalue1"),
KeyValue::new("mykey2", "myvalue2"),
],
);
// Note that Gauge only has a Observable version.
// Create a ObservableGauge instrument and register a callback that reports the measurement.
let _observable_gauge = meter
.f64_observable_gauge("my_observable_gauge")
.with_description("An observable gauge set to 1.0")
.with_unit("myunit")
.with_callback(|observer| {
observer.observe(
1.0,
&[
KeyValue::new("mykey1", "myvalue1"),
KeyValue::new("mykey2", "myvalue2"),
],
)
})
.build();
// Metrics are exported by default every 30 seconds when using stdout exporter,
// however shutting down the MeterProvider here instantly flushes
// the metrics, instead of waiting for the 30 sec interval.
// Metrics are exported by default every 60 seconds when using stdout
// exporter, however shutting down the MeterProvider here instantly flushes
// the metrics, instead of waiting for the 60 sec interval. Shutdown returns
// a result, which is bubbled up to the caller The commented code below
// demonstrates handling the shutdown result, instead of bubbling up the
// error.
meter_provider.shutdown()?;
// let shutdown_result = meter_provider.shutdown();
// Handle the shutdown result.
// match shutdown_result {
// Ok(_) => println!("MeterProvider shutdown successfully"),
// Err(e) => {
// match e {
// opentelemetry_sdk::error::ShutdownError::InternalFailure(message) => {
// // This indicates some internal failure during shutdown. The
// // error message is intended for logging purposes only and
// // should not be used to make programmatic decisions.
// println!("MeterProvider shutdown failed: {}", message)
// }
// opentelemetry_sdk::error::ShutdownError::AlreadyShutdown => {
// // This indicates some user code tried to shutdown
// // elsewhere. user need to review their code to ensure
// // shutdown is called only once.
// println!("MeterProvider already shutdown")
// }
// opentelemetry_sdk::error::ShutdownError::Timeout(e) => {
// // This indicates the shutdown timed out, and a good hint to
// // user to increase the timeout. (Shutdown method does not
// // allow custom timeout today, but that is temporary)
// println!("MeterProvider shutdown timed out after {:?}", e)
// }
// }
// }
// }
Ok(())
}

View File

@ -1,24 +0,0 @@
[package]
name = "traceresponse"
version = "0.1.0"
edition = "2021"
license = "Apache-2.0"
publish = false
[[bin]] # Bin to run the http server
name = "http-server"
path = "src/server.rs"
doc = false
[[bin]] # Bin to run the client
name = "http-client"
path = "src/client.rs"
doc = false
[dependencies]
hyper = { version = "0.14", features = ["full"] }
tokio = { version = "1.0", features = ["full"] }
opentelemetry = { path = "../../opentelemetry" }
opentelemetry-http = { path = "../../opentelemetry-http" }
opentelemetry-contrib = { path = "../../opentelemetry-contrib" }
opentelemetry-stdout = { path = "../../opentelemetry-stdout", features = ["trace"] }

View File

@ -1,71 +0,0 @@
use hyper::http::HeaderValue;
use hyper::{body::Body, Client};
use opentelemetry::global;
use opentelemetry::propagation::TextMapPropagator;
use opentelemetry::sdk::propagation::TraceContextPropagator;
use opentelemetry::sdk::trace::TracerProvider;
use opentelemetry::trace::SpanKind;
use opentelemetry::{
trace::{TraceContextExt, Tracer},
Context, KeyValue,
};
use opentelemetry_contrib::trace::propagator::trace_context_response::TraceContextResponsePropagator;
use opentelemetry_http::{HeaderExtractor, HeaderInjector};
use opentelemetry_stdout::SpanExporter;
fn init_tracer() {
global::set_text_map_propagator(TraceContextPropagator::new());
// Install stdout exporter pipeline to be able to retrieve the collected spans.
// For the demonstration, use `Sampler::AlwaysOn` sampler to sample all traces. In a production
// application, use `Sampler::ParentBased` or `Sampler::TraceIdRatioBased` with a desired ratio.
let provider = TracerProvider::builder()
.with_simple_exporter(SpanExporter::default())
.build();
global::set_tracer_provider(provider);
}
#[tokio::main]
async fn main() -> std::result::Result<(), Box<dyn std::error::Error + Send + Sync + 'static>> {
init_tracer();
let client = Client::new();
let tracer = global::tracer("example/client");
let span = tracer
.span_builder("say hello")
.with_kind(SpanKind::Client)
.start(&tracer);
let cx = Context::current_with_span(span);
let mut req = hyper::Request::builder().uri("http://127.0.0.1:3000");
global::get_text_map_propagator(|propagator| {
propagator.inject_context(&cx, &mut HeaderInjector(req.headers_mut().unwrap()))
});
let res = client.request(req.body(Body::from("Hello!"))?).await?;
let response_propagator: &dyn TextMapPropagator = &TraceContextResponsePropagator::new();
let response_cx =
response_propagator.extract_with_context(&cx, &HeaderExtractor(res.headers()));
let response_span = response_cx.span();
cx.span().add_event(
"Got response!".to_string(),
vec![
KeyValue::new("status", res.status().to_string()),
KeyValue::new(
"traceresponse",
res.headers()
.get("traceresponse")
.unwrap_or(&HeaderValue::from_static(""))
.to_str()
.unwrap()
.to_string(),
),
KeyValue::new("child_sampled", response_span.span_context().is_sampled()),
],
);
Ok(())
}

View File

@ -1,63 +0,0 @@
use hyper::service::{make_service_fn, service_fn};
use hyper::{Body, Request, Response, Server};
use opentelemetry::propagation::TextMapPropagator;
use opentelemetry::sdk::trace::TracerProvider;
use opentelemetry::trace::{SpanKind, TraceContextExt};
use opentelemetry::Context;
use opentelemetry::{global, sdk::propagation::TraceContextPropagator, trace::Tracer};
use opentelemetry_contrib::trace::propagator::trace_context_response::TraceContextResponsePropagator;
use opentelemetry_http::{HeaderExtractor, HeaderInjector};
use opentelemetry_stdout::SpanExporter;
use std::{convert::Infallible, net::SocketAddr};
async fn handle(req: Request<Body>) -> Result<Response<Body>, Infallible> {
let parent_cx = global::get_text_map_propagator(|propagator| {
propagator.extract(&HeaderExtractor(req.headers()))
});
let _cx_guard = parent_cx.attach();
let tracer = global::tracer("example/server");
let span = tracer
.span_builder("say hello")
.with_kind(SpanKind::Server)
.start(&tracer);
let cx = Context::current_with_span(span);
cx.span().add_event("handling this...", Vec::new());
let mut res = Response::new("Hello, World!".into());
let response_propagator: &dyn TextMapPropagator = &TraceContextResponsePropagator::new();
response_propagator.inject_context(&cx, &mut HeaderInjector(res.headers_mut()));
Ok(res)
}
fn init_tracer() {
global::set_text_map_propagator(TraceContextPropagator::new());
// Install stdout exporter pipeline to be able to retrieve the collected spans.
// For the demonstration, use `Sampler::AlwaysOn` sampler to sample all traces. In a production
// application, use `Sampler::ParentBased` or `Sampler::TraceIdRatioBased` with a desired ratio.
let provider = TracerProvider::builder()
.with_simple_exporter(SpanExporter::default())
.build();
global::set_tracer_provider(provider);
}
#[tokio::main]
async fn main() {
init_tracer();
let addr = SocketAddr::from(([127, 0, 0, 1], 3000));
let make_svc = make_service_fn(|_conn| async { Ok::<_, Infallible>(service_fn(handle)) });
let server = Server::bind(&addr).serve(make_svc);
println!("Listening on {addr}");
if let Err(e) = server.await {
eprintln!("server error: {e}");
}
}

View File

@ -3,26 +3,32 @@ name = "tracing-grpc"
version = "0.1.0"
edition = "2021"
license = "Apache-2.0"
rust-version = "1.75.0"
publish = false
autobenches = false
[[bin]] # Bin to run the gRPC server
name = "grpc-server"
path = "src/server.rs"
bench = false
[[bin]] # Bin to run the gRPC client
name = "grpc-client"
path = "src/client.rs"
bench = false
[dependencies]
opentelemetry = { version = "0.19", features = ["rt-tokio"] }
opentelemetry-jaeger = { version = "0.18", features = ["rt-tokio"] }
prost = "0.11"
tokio = { version = "1.28", features = ["full"] }
tonic = "0.9.2"
tracing = "0.1"
tracing-futures = "0.2"
tracing-opentelemetry = "0.19"
tracing-subscriber = { version = "0.3", features = ["env-filter"] }
opentelemetry = { path = "../../opentelemetry" }
opentelemetry_sdk = { path = "../../opentelemetry-sdk", features = ["rt-tokio"] }
opentelemetry-stdout = { workspace = true, features = ["trace"] }
prost = { workspace = true }
tokio = { workspace = true, features = ["full"] }
tonic = { workspace = true, features = ["server", "codegen", "channel", "prost", "router"] }
[build-dependencies]
tonic-build = "0.9.2"
tonic-build = { workspace = true }
[package.metadata.cargo-machete]
ignored = [
"prost" # needed for `tonic-build`
]

View File

@ -1,24 +1,25 @@
# GRPC example
Example showing [Tonic] client and server interaction with OpenTelemetry context propagation. [tracing_opentelemetry](https://docs.rs/tracing-opentelemetry/0.4.0/tracing_opentelemetry/) is used to hook into the [tracing](https://github.com/tokio-rs/tracing) ecosystem, which enables drop-in replacements for [log](https://github.com/rust-lang/log) macros and an `#[instrument]` macro that will automatically add spans to your functions.
Example showing [Tonic] client and server interaction with OpenTelemetry context
propagation. Traces are exported to stdout.
[Tonic]: https://github.com/hyperium/tonic
Examples
--------
## Running the example
```shell
# Run jaeger in background
$ docker run -d -p6831:6831/udp -p6832:6832/udp -p16686:16686 jaegertracing/all-in-one:latest
# Run the server
# Run the server first
$ cargo run --bin grpc-server
# Now run the client to make a request to the server
$ cargo run --bin grpc-client
# View spans (see the image below)
$ firefox http://localhost:16686/
```
![Jaeger UI](trace.png)
Observe that the traces are exported to stdout, and that they share the same
TraceId. Also, the server span would be parented to the client span. The example
demonstrates how to propagate and restore OpenTelemetry context when making
out-of-process calls, so as to ensure the same trace is continued in the next
process. The client here initiates the trace by creating the root client span,
and it propagates its context to the server. The server, extracts the context,
and creates its own server span using the extracted context, ensuring both spans
are correlated.

View File

@ -1,14 +1,28 @@
use hello_world::greeter_client::GreeterClient;
use hello_world::HelloRequest;
use opentelemetry::{global, propagation::Injector};
use tracing::*;
use tracing_futures::Instrument;
use tracing_opentelemetry::OpenTelemetrySpanExt;
use tracing_subscriber::prelude::*;
use opentelemetry_sdk::{propagation::TraceContextPropagator, trace as sdktrace};
use opentelemetry_stdout::SpanExporter;
use opentelemetry::{
trace::{SpanKind, TraceContextExt, Tracer},
Context, KeyValue,
};
fn init_tracer() -> sdktrace::SdkTracerProvider {
global::set_text_map_propagator(TraceContextPropagator::new());
// Install stdout exporter pipeline to be able to retrieve the collected spans.
let provider = sdktrace::SdkTracerProvider::builder()
.with_simple_exporter(SpanExporter::default())
.build();
global::set_tracer_provider(provider.clone());
provider
}
struct MetadataMap<'a>(&'a mut tonic::metadata::MetadataMap);
impl<'a> Injector for MetadataMap<'a> {
impl Injector for MetadataMap<'_> {
/// Set a key and value in the MetadataMap. Does nothing if the key or value are not valid inputs
fn set(&mut self, key: &str, value: String) {
if let Ok(key) = tonic::metadata::MetadataKey::from_bytes(key.as_bytes()) {
@ -24,46 +38,57 @@ pub mod hello_world {
tonic::include_proto!("helloworld");
}
#[instrument]
async fn greet() -> Result<(), Box<dyn std::error::Error + Send + Sync + 'static>> {
let mut client = GreeterClient::connect("http://[::1]:50051")
.instrument(info_span!("client connect"))
.await?;
let tracer = global::tracer("example/client");
let span = tracer
.span_builder("Greeter/client")
.with_kind(SpanKind::Client)
.with_attributes([
KeyValue::new("rpc.system", "grpc"),
KeyValue::new("server.port", 50052),
KeyValue::new("rpc.method", "say_hello"),
])
.start(&tracer);
let cx = Context::current_with_span(span);
let mut client = GreeterClient::connect("http://[::1]:50052").await?;
let mut request = tonic::Request::new(HelloRequest {
name: "Tonic".into(),
});
global::get_text_map_propagator(|propagator| {
propagator.inject_context(
&tracing::Span::current().context(),
&mut MetadataMap(request.metadata_mut()),
)
propagator.inject_context(&cx, &mut MetadataMap(request.metadata_mut()))
});
let response = client
.say_hello(request)
.instrument(info_span!("say_hello"))
.await?;
let response = client.say_hello(request).await;
let span = cx.span();
let status = match response {
Ok(_res) => {
span.set_attribute(KeyValue::new("response", "OK"));
"OK".to_string()
}
Err(status) => {
// Access the status code
let status_code = status.code();
span.set_attribute(KeyValue::new(
"response_code_desc",
status_code.description(),
));
status_code.to_string()
}
};
span.add_event("Got response!", vec![KeyValue::new("status", status)]);
info!("Response received: {:?}", response);
Ok(())
}
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error + Send + Sync + 'static>> {
global::set_text_map_propagator(opentelemetry_jaeger::Propagator::new());
let tracer = opentelemetry_jaeger::new_agent_pipeline()
.with_service_name("grpc-client")
.install_simple()?;
tracing_subscriber::registry()
.with(tracing_subscriber::EnvFilter::new("INFO"))
.with(tracing_opentelemetry::layer().with_tracer(tracer))
.try_init()?;
let provider = init_tracer();
greet().await?;
opentelemetry::global::shutdown_tracer_provider();
provider.shutdown()?;
Ok(())
}

View File

@ -1,10 +1,25 @@
use hello_world::greeter_server::{Greeter, GreeterServer};
use hello_world::{HelloReply, HelloRequest};
use opentelemetry::{global, propagation::Extractor};
use opentelemetry::KeyValue;
use opentelemetry::{
global,
propagation::Extractor,
trace::{Span, SpanKind, Tracer},
};
use opentelemetry_sdk::{propagation::TraceContextPropagator, trace::SdkTracerProvider};
use opentelemetry_stdout::SpanExporter;
use tonic::{transport::Server, Request, Response, Status};
use tracing::*;
use tracing_opentelemetry::OpenTelemetrySpanExt;
use tracing_subscriber::prelude::*;
fn init_tracer() -> SdkTracerProvider {
global::set_text_map_propagator(TraceContextPropagator::new());
// Install stdout exporter pipeline to be able to retrieve the collected spans.
let provider = SdkTracerProvider::builder()
.with_simple_exporter(SpanExporter::default())
.build();
global::set_tracer_provider(provider.clone());
provider
}
#[allow(clippy::derive_partial_eq_without_eq)] // tonic don't derive Eq for generated types. We shouldn't manually change it.
pub mod hello_world {
@ -13,7 +28,7 @@ pub mod hello_world {
struct MetadataMap<'a>(&'a tonic::metadata::MetadataMap);
impl<'a> Extractor for MetadataMap<'a> {
impl Extractor for MetadataMap<'_> {
/// Get a value for a key from the MetadataMap. If the value can't be converted to &str, returns None
fn get(&self, key: &str) -> Option<&str> {
self.0.get(key).and_then(|metadata| metadata.to_str().ok())
@ -31,10 +46,9 @@ impl<'a> Extractor for MetadataMap<'a> {
}
}
#[instrument]
fn expensive_fn(to_print: String) {
fn expensive_fn<S: Span>(to_print: String, span: &mut S) {
std::thread::sleep(std::time::Duration::from_millis(20));
info!("{}", to_print);
span.add_event(to_print, vec![]);
}
#[derive(Debug, Default)]
@ -42,17 +56,25 @@ pub struct MyGreeter {}
#[tonic::async_trait]
impl Greeter for MyGreeter {
#[instrument]
async fn say_hello(
&self,
request: Request<HelloRequest>, // Accept request of type HelloRequest
) -> Result<Response<HelloReply>, Status> {
let parent_cx =
global::get_text_map_propagator(|prop| prop.extract(&MetadataMap(request.metadata())));
tracing::Span::current().set_parent(parent_cx);
let tracer = global::tracer("example/server");
let mut span = tracer
.span_builder("Greeter/server")
.with_kind(SpanKind::Server)
.with_attributes([
KeyValue::new("rpc.system", "grpc"),
KeyValue::new("server.port", 50052),
KeyValue::new("rpc.method", "say_hello"),
])
.start_with_context(&tracer, &parent_cx);
let name = request.into_inner().name;
expensive_fn(format!("Got name: {name:?}"));
expensive_fn(format!("Got name: {name:?}"), &mut span);
// Return an instance of type HelloReply
let reply = hello_world::HelloReply {
@ -65,16 +87,9 @@ impl Greeter for MyGreeter {
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error + Send + Sync + 'static>> {
global::set_text_map_propagator(opentelemetry_jaeger::Propagator::new());
let tracer = opentelemetry_jaeger::new_agent_pipeline()
.with_service_name("grpc-server")
.install_batch(opentelemetry::runtime::Tokio)?;
tracing_subscriber::registry()
.with(tracing_subscriber::EnvFilter::new("INFO"))
.with(tracing_opentelemetry::layer().with_tracer(tracer))
.try_init()?;
let provider = init_tracer();
let addr = "[::1]:50051".parse()?;
let addr = "[::1]:50052".parse()?;
let greeter = MyGreeter::default();
Server::builder()
@ -82,7 +97,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error + Send + Sync + 'static>
.serve(addr)
.await?;
opentelemetry::global::shutdown_tracer_provider();
provider.shutdown()?;
Ok(())
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 69 KiB

View File

@ -0,0 +1,34 @@
[package]
name = "tracing-http-propagator"
version = "0.1.0"
edition = "2021"
license = "Apache-2.0"
rust-version = "1.75.0"
publish = false
autobenches = false
[[bin]] # Bin to run the http server
name = "http-server"
path = "src/server.rs"
doc = false
bench = false
[[bin]] # Bin to run the client
name = "http-client"
path = "src/client.rs"
doc = false
bench = false
[dependencies]
http-body-util = { workspace = true }
hyper = { workspace = true, features = ["full"] }
hyper-util = { workspace = true, features = ["full"] }
tokio = { workspace = true, features = ["full"] }
opentelemetry = { path = "../../opentelemetry" }
opentelemetry_sdk = { path = "../../opentelemetry-sdk" }
opentelemetry-http = { path = "../../opentelemetry-http" }
opentelemetry-stdout = { workspace = true, features = ["trace", "logs"] }
opentelemetry-semantic-conventions = { path = "../../opentelemetry-semantic-conventions" }
opentelemetry-appender-tracing = { workspace = true }
tracing = { workspace = true, features = ["std"]}
tracing-subscriber = { workspace = true, features = ["env-filter","registry", "std", "fmt"] }

View File

@ -1,19 +1,18 @@
# HTTP Example
This is a simple example using [hyper] that demonstrates tracing http request
from client to server, and from the server back to the client using the
[W3C Trace Context Response] header. The example shows key aspects of tracing
from client to server. The example shows key aspects of tracing
such as:
- Root Span (on Client)
- Child Span from a Remote Parent (on Server)
- Child Span created on the async function parented by the first level child (on Server)
- SpanContext Propagation (from Client to Server)
- SpanContext Propagation (from Server to Client)
- Span Events
- Span Attributes
- Context propagation across async task boundaries.
[hyper]: https://hyper.rs/
[W3C Trace Context Response]: https://w3c.github.io/trace-context/#traceresponse-header
## Usage

View File

@ -0,0 +1,98 @@
use http_body_util::Full;
use hyper_util::{client::legacy::Client, rt::TokioExecutor};
use opentelemetry::{
global,
trace::{SpanKind, TraceContextExt, Tracer},
Context,
};
use opentelemetry_appender_tracing::layer::OpenTelemetryTracingBridge;
use opentelemetry_http::{Bytes, HeaderInjector};
use opentelemetry_sdk::{
logs::SdkLoggerProvider, propagation::TraceContextPropagator, trace::SdkTracerProvider,
};
use opentelemetry_stdout::{LogExporter, SpanExporter};
use tracing::info;
use tracing_subscriber::{layer::SubscriberExt, util::SubscriberInitExt};
fn init_tracer() -> SdkTracerProvider {
global::set_text_map_propagator(TraceContextPropagator::new());
// Install stdout exporter pipeline to be able to retrieve the collected spans.
// For the demonstration, use `Sampler::AlwaysOn` sampler to sample all traces.
let provider = SdkTracerProvider::builder()
.with_simple_exporter(SpanExporter::default())
.build();
global::set_tracer_provider(provider.clone());
provider
}
fn init_logs() -> SdkLoggerProvider {
// Setup tracerprovider with stdout exporter
// that prints the spans to stdout.
let logger_provider = SdkLoggerProvider::builder()
.with_simple_exporter(LogExporter::default())
.build();
let otel_layer = OpenTelemetryTracingBridge::new(&logger_provider);
tracing_subscriber::registry()
.with(otel_layer)
.with(tracing_subscriber::filter::LevelFilter::INFO)
.init();
logger_provider
}
async fn send_request(
url: &str,
body_content: &str,
span_name: &str,
) -> std::result::Result<(), Box<dyn std::error::Error + Send + Sync + 'static>> {
let client = Client::builder(TokioExecutor::new()).build_http();
let tracer = global::tracer("example/client");
let span = tracer
.span_builder(String::from(span_name))
.with_kind(SpanKind::Client)
.start(&tracer);
let cx = Context::current_with_span(span);
let mut req = hyper::Request::builder().uri(url);
global::get_text_map_propagator(|propagator| {
propagator.inject_context(&cx, &mut HeaderInjector(req.headers_mut().unwrap()))
});
req.headers_mut()
.unwrap()
.insert("baggage", "is_synthetic=true".parse().unwrap());
let res = client
.request(req.body(Full::new(Bytes::from(body_content.to_string())))?)
.await?;
info!(name: "ResponseReceived", status = res.status().to_string(), message = "Response received");
Ok(())
}
#[tokio::main]
async fn main() -> std::result::Result<(), Box<dyn std::error::Error + Send + Sync + 'static>> {
let tracer_provider = init_tracer();
let logger_provider = init_logs();
send_request(
"http://127.0.0.1:3000/health",
"Health Request!",
"server_health_check",
)
.await?;
send_request(
"http://127.0.0.1:3000/echo",
"Echo Request!",
"server_echo_check",
)
.await?;
tracer_provider
.shutdown()
.expect("Shutdown provider failed");
logger_provider
.shutdown()
.expect("Shutdown provider failed");
Ok(())
}

View File

@ -0,0 +1,204 @@
use http_body_util::{combinators::BoxBody, BodyExt, Full};
use hyper::{body::Incoming, service::service_fn, Request, Response, StatusCode};
use hyper_util::rt::{TokioExecutor, TokioIo};
use opentelemetry::{
baggage::BaggageExt,
global::{self, BoxedTracer},
logs::LogRecord,
propagation::TextMapCompositePropagator,
trace::{FutureExt, Span, SpanKind, TraceContextExt, Tracer},
Context, InstrumentationScope, KeyValue,
};
use opentelemetry_appender_tracing::layer::OpenTelemetryTracingBridge;
use opentelemetry_http::{Bytes, HeaderExtractor};
use opentelemetry_sdk::{
error::OTelSdkResult,
logs::{LogProcessor, SdkLogRecord, SdkLoggerProvider},
propagation::{BaggagePropagator, TraceContextPropagator},
trace::{SdkTracerProvider, SpanProcessor},
};
use opentelemetry_semantic_conventions::trace;
use opentelemetry_stdout::{LogExporter, SpanExporter};
use std::time::Duration;
use std::{convert::Infallible, net::SocketAddr, sync::OnceLock};
use tokio::net::TcpListener;
use tracing::info;
use tracing_subscriber::{layer::SubscriberExt, util::SubscriberInitExt};
fn get_tracer() -> &'static BoxedTracer {
static TRACER: OnceLock<BoxedTracer> = OnceLock::new();
TRACER.get_or_init(|| global::tracer("example/server"))
}
// Utility function to extract the context from the incoming request headers
fn extract_context_from_request(req: &Request<Incoming>) -> Context {
global::get_text_map_propagator(|propagator| {
propagator.extract(&HeaderExtractor(req.headers()))
})
}
// Separate async function for the handle endpoint
async fn handle_health_check(
_req: Request<Incoming>,
) -> Result<Response<BoxBody<Bytes, hyper::Error>>, Infallible> {
let tracer = get_tracer();
let _span = tracer
.span_builder("health_check")
.with_kind(SpanKind::Internal)
.start(tracer);
info!(name: "health_check", message = "Health check endpoint hit");
let res = Response::new(
Full::new(Bytes::from_static(b"Server is up and running!"))
.map_err(|err| match err {})
.boxed(),
);
Ok(res)
}
// Separate async function for the echo endpoint
async fn handle_echo(
req: Request<Incoming>,
) -> Result<Response<BoxBody<Bytes, hyper::Error>>, Infallible> {
let tracer = get_tracer();
let _span = tracer
.span_builder("echo")
.with_kind(SpanKind::Internal)
.start(tracer);
info!(name = "echo", message = "Echo endpoint hit");
let res = Response::new(req.into_body().boxed());
Ok(res)
}
async fn router(
req: Request<Incoming>,
) -> Result<Response<BoxBody<Bytes, hyper::Error>>, Infallible> {
// Extract the context from the incoming request headers
let parent_cx = extract_context_from_request(&req);
let response = {
// Create a span parenting the remote client span.
let tracer = get_tracer();
let span = tracer
.span_builder("router")
.with_kind(SpanKind::Server)
.start_with_context(tracer, &parent_cx);
info!(name = "router", message = "Dispatching request");
let cx = parent_cx.with_span(span);
match (req.method(), req.uri().path()) {
(&hyper::Method::GET, "/health") => handle_health_check(req).with_context(cx).await,
(&hyper::Method::GET, "/echo") => handle_echo(req).with_context(cx).await,
_ => {
cx.span()
.set_attribute(KeyValue::new(trace::HTTP_RESPONSE_STATUS_CODE, 404));
let mut not_found = Response::new(BoxBody::default());
*not_found.status_mut() = StatusCode::NOT_FOUND;
Ok(not_found)
}
}
};
response
}
/// A custom log processor that enriches LogRecords with baggage attributes.
/// Baggage information is not added automatically without this processor.
#[derive(Debug)]
struct EnrichWithBaggageLogProcessor;
impl LogProcessor for EnrichWithBaggageLogProcessor {
fn emit(&self, data: &mut SdkLogRecord, _instrumentation: &InstrumentationScope) {
Context::map_current(|cx| {
for (kk, vv) in cx.baggage().iter() {
data.add_attribute(kk.clone(), vv.0.clone());
}
});
}
fn force_flush(&self) -> OTelSdkResult {
Ok(())
}
}
/// A custom span processor that enriches spans with baggage attributes. Baggage
/// information is not added automatically without this processor.
#[derive(Debug)]
struct EnrichWithBaggageSpanProcessor;
impl SpanProcessor for EnrichWithBaggageSpanProcessor {
fn force_flush(&self) -> OTelSdkResult {
Ok(())
}
fn shutdown_with_timeout(&self, _timeout: Duration) -> OTelSdkResult {
Ok(())
}
fn on_start(&self, span: &mut opentelemetry_sdk::trace::Span, cx: &Context) {
for (kk, vv) in cx.baggage().iter() {
span.set_attribute(KeyValue::new(kk.clone(), vv.0.clone()));
}
}
fn on_end(&self, _span: opentelemetry_sdk::trace::SpanData) {}
}
fn init_tracer() -> SdkTracerProvider {
let baggage_propagator = BaggagePropagator::new();
let trace_context_propagator = TraceContextPropagator::new();
let composite_propagator = TextMapCompositePropagator::new(vec![
Box::new(baggage_propagator),
Box::new(trace_context_propagator),
]);
global::set_text_map_propagator(composite_propagator);
// Setup tracerprovider with stdout exporter
// that prints the spans to stdout.
let provider = SdkTracerProvider::builder()
.with_span_processor(EnrichWithBaggageSpanProcessor)
.with_simple_exporter(SpanExporter::default())
.build();
global::set_tracer_provider(provider.clone());
provider
}
fn init_logs() -> SdkLoggerProvider {
// Setup tracerprovider with stdout exporter
// that prints the spans to stdout.
let logger_provider = SdkLoggerProvider::builder()
.with_log_processor(EnrichWithBaggageLogProcessor)
.with_simple_exporter(LogExporter::default())
.build();
let otel_layer = OpenTelemetryTracingBridge::new(&logger_provider);
tracing_subscriber::registry().with(otel_layer).init();
logger_provider
}
#[tokio::main]
async fn main() {
use hyper_util::server::conn::auto::Builder;
let provider = init_tracer();
let logger_provider = init_logs();
let addr = SocketAddr::from(([127, 0, 0, 1], 3000));
let listener = TcpListener::bind(addr).await.unwrap();
while let Ok((stream, _addr)) = listener.accept().await {
if let Err(err) = Builder::new(TokioExecutor::new())
.serve_connection(TokioIo::new(stream), service_fn(router))
.await
{
eprintln!("{err}");
}
}
provider.shutdown().expect("Shutdown provider failed");
logger_provider
.shutdown()
.expect("Shutdown provider failed");
}

View File

@ -1,40 +0,0 @@
# Changelog
## v0.20.0
### Added
- Add `new` method to `BoxedTracer` #1009
- Add js-sys as dependency for api crate when building wasm targets #1078
- Create tracer using a shared instrumentation library #1129
- Add `Context::map_current` #1140
### Changed
- `OtelString::Owned` carries `Box<str>` instead of `String` #1096
### Removed
- Drop include_trace_context parameter from Logs API/SDK. [#1133](https://github.com/open-telemetry/opentelemetry-rust/issues/1133)
- Synchronous instruments no longer accepts `Context` while reporting
measurements. [#1076](https://github.com/open-telemetry/opentelemetry-rust/pull/1076).
### Fixed
- Fix `SpanRef::set_attributes` mutability requirement. [#1038](https://github.com/open-telemetry/opentelemetry-rust/pull/1038)
- Move OrderMap module to root of otel-api crate. [#1061](https://github.com/open-telemetry/opentelemetry-rust/pull/1061)
- Use the browser-only js-sys workaround only when actually targeting a browser #1008
## v0.19.0
### Added
- Add `WithContext` to public api [#893](https://github.com/open-telemetry/opentelemetry-rust/pull/893).
- Add support for instrumentation scope attributes [#1021](https://github.com/open-telemetry/opentelemetry-rust/pull/1021).
### Changed
- Implement `Display` on `Baggage` [#921](https://github.com/open-telemetry/opentelemetry-rust/pull/921).
- Bump MSRV to 1.57 [#953](https://github.com/open-telemetry/opentelemetry-rust/pull/953).
- Update dependencies and bump MSRV to 1.60 [#969](https://github.com/open-telemetry/opentelemetry-rust/pull/969).
## v0.18.0
- API split from `opentelemetry` crate

View File

@ -1,5 +0,0 @@
# Code owners file.
# This file controls who is tagged for review for any given pull request.
# For anything not explicitly taken by someone else:
* @open-telemetry/rust-approvers

View File

@ -1,34 +0,0 @@
[package]
name = "opentelemetry_api"
version = "0.20.0"
description = "OpenTelemetry is a metrics collection and distributed tracing framework"
homepage = "https://github.com/open-telemetry/opentelemetry-rust"
repository = "https://github.com/open-telemetry/opentelemetry-rust"
readme = "README.md"
license = "Apache-2.0"
edition = "2021"
rust-version = "1.60"
[dependencies]
futures-channel = "0.3"
futures-util = { version = "0.3", default-features = false, features = ["std", "sink"] }
indexmap = "1.8"
once_cell = "1.12.0"
pin-project-lite = { version = "0.2", optional = true }
thiserror = "1"
urlencoding = "2.1.2"
[target.'cfg(all(target_arch = "wasm32", not(target_os = "wasi")))'.dependencies]
js-sys = "0.3.63"
[package.metadata.docs.rs]
all-features = true
rustdoc-args = ["--cfg", "docsrs"]
[features]
default = ["trace"]
trace = ["pin-project-lite"]
metrics = []
testing = ["trace"]
logs = []
logs_level_enabled = ["logs"]

View File

@ -1,201 +0,0 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright 2023 The OpenTelemetry Authors
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

View File

@ -1,28 +0,0 @@
![OpenTelemetry — An observability framework for cloud-native software.][splash]
[splash]: https://raw.githubusercontent.com/open-telemetry/opentelemetry-rust/main/assets/logo-text.png
# OpenTelemetry Rust API
The Rust [OpenTelemetry](https://opentelemetry.io/) implementation.
[![Crates.io: opentelemetry-api](https://img.shields.io/crates/v/opentelemetry_api.svg)](https://crates.io/crates/opentelemetry_api)
[![Documentation](https://docs.rs/opentelemetry_api/badge.svg)](https://docs.rs/opentelemetry_api)
[![LICENSE](https://img.shields.io/crates/l/opentelemetry_api)](./LICENSE)
[![GitHub Actions CI](https://github.com/open-telemetry/opentelemetry-rust/workflows/CI/badge.svg)](https://github.com/open-telemetry/opentelemetry-rust/actions?query=workflow%3ACI+branch%3Amain)
[![codecov](https://codecov.io/gh/open-telemetry/opentelemetry-rust/branch/main/graph/badge.svg)](https://codecov.io/gh/open-telemetry/opentelemetry-rust)
[![Slack](https://img.shields.io/badge/slack-@cncf/otel/rust-brightgreen.svg?logo=slack)](https://cloud-native.slack.com/archives/C03GDP0H023)
## Overview
OpenTelemetry is a collection of tools, APIs, and SDKs used to instrument,
generate, collect, and export telemetry data (metrics, logs, and traces) for
analysis in order to understand your software's performance and behavior. You
can export and analyze them using [Prometheus], [Jaeger], and other
observability tools.
*Compiler support: [requires `rustc` 1.60+][msrv]*
[Prometheus]: https://prometheus.io
[Jaeger]: https://www.jaegertracing.io
[msrv]: #supported-rust-versions

View File

@ -1,504 +0,0 @@
use std::borrow::Cow;
use std::sync::Arc;
use std::{fmt, hash};
/// The key part of attribute [KeyValue] pairs.
///
/// See the [attribute naming] spec for guidelines.
///
/// [attribute naming]: https://github.com/open-telemetry/opentelemetry-specification/blob/v1.9.0/specification/common/attribute-naming.md
#[derive(Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
pub struct Key(OtelString);
impl Key {
/// Create a new `Key`.
///
/// # Examples
///
/// ```
/// use opentelemetry_api::Key;
/// use std::sync::Arc;
///
/// let key1 = Key::new("my_static_str");
/// let key2 = Key::new(String::from("my_owned_string"));
/// let key3 = Key::new(Arc::from("my_ref_counted_str"));
/// ```
pub fn new(value: impl Into<Key>) -> Self {
value.into()
}
/// Create a new const `Key`.
pub const fn from_static_str(value: &'static str) -> Self {
Key(OtelString::Static(value))
}
/// Create a `KeyValue` pair for `bool` values.
pub fn bool<T: Into<bool>>(self, value: T) -> KeyValue {
KeyValue {
key: self,
value: Value::Bool(value.into()),
}
}
/// Create a `KeyValue` pair for `i64` values.
pub fn i64(self, value: i64) -> KeyValue {
KeyValue {
key: self,
value: Value::I64(value),
}
}
/// Create a `KeyValue` pair for `f64` values.
pub fn f64(self, value: f64) -> KeyValue {
KeyValue {
key: self,
value: Value::F64(value),
}
}
/// Create a `KeyValue` pair for string-like values.
pub fn string(self, value: impl Into<StringValue>) -> KeyValue {
KeyValue {
key: self,
value: Value::String(value.into()),
}
}
/// Create a `KeyValue` pair for arrays.
pub fn array<T: Into<Array>>(self, value: T) -> KeyValue {
KeyValue {
key: self,
value: Value::Array(value.into()),
}
}
/// Returns a reference to the underlying key name
pub fn as_str(&self) -> &str {
self.0.as_str()
}
}
impl From<&'static str> for Key {
/// Convert a `&str` to a `Key`.
fn from(key_str: &'static str) -> Self {
Key(OtelString::Static(key_str))
}
}
impl From<String> for Key {
/// Convert a `String` to a `Key`.
fn from(string: String) -> Self {
Key(OtelString::Owned(string.into_boxed_str()))
}
}
impl From<Arc<str>> for Key {
/// Convert a `String` to a `Key`.
fn from(string: Arc<str>) -> Self {
Key(OtelString::RefCounted(string))
}
}
impl From<Cow<'static, str>> for Key {
/// Convert a `Cow<'static, str>` to a `Key`
fn from(string: Cow<'static, str>) -> Self {
match string {
Cow::Borrowed(s) => Key(OtelString::Static(s)),
Cow::Owned(s) => Key(OtelString::Owned(s.into_boxed_str())),
}
}
}
impl fmt::Debug for Key {
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
self.0.fmt(fmt)
}
}
impl From<Key> for String {
fn from(key: Key) -> Self {
match key.0 {
OtelString::Owned(s) => s.to_string(),
OtelString::Static(s) => s.to_string(),
OtelString::RefCounted(s) => s.to_string(),
}
}
}
impl fmt::Display for Key {
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
match &self.0 {
OtelString::Owned(s) => s.fmt(fmt),
OtelString::Static(s) => s.fmt(fmt),
OtelString::RefCounted(s) => s.fmt(fmt),
}
}
}
#[derive(Clone, Debug, Eq)]
enum OtelString {
Owned(Box<str>),
Static(&'static str),
RefCounted(Arc<str>),
}
impl OtelString {
fn as_str(&self) -> &str {
match self {
OtelString::Owned(s) => s.as_ref(),
OtelString::Static(s) => s,
OtelString::RefCounted(s) => s.as_ref(),
}
}
}
impl PartialOrd for OtelString {
fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
self.as_str().partial_cmp(other.as_str())
}
}
impl Ord for OtelString {
fn cmp(&self, other: &Self) -> std::cmp::Ordering {
self.as_str().cmp(other.as_str())
}
}
impl PartialEq for OtelString {
fn eq(&self, other: &Self) -> bool {
self.as_str().eq(other.as_str())
}
}
impl hash::Hash for OtelString {
fn hash<H: hash::Hasher>(&self, state: &mut H) {
self.as_str().hash(state)
}
}
/// A [Value::Array] containing homogeneous values.
#[derive(Clone, Debug, PartialEq)]
pub enum Array {
/// Array of bools
Bool(Vec<bool>),
/// Array of integers
I64(Vec<i64>),
/// Array of floats
F64(Vec<f64>),
/// Array of strings
String(Vec<StringValue>),
}
impl fmt::Display for Array {
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Array::Bool(values) => display_array_str(values, fmt),
Array::I64(values) => display_array_str(values, fmt),
Array::F64(values) => display_array_str(values, fmt),
Array::String(values) => {
write!(fmt, "[")?;
for (i, t) in values.iter().enumerate() {
if i > 0 {
write!(fmt, ",")?;
}
write!(fmt, "\"{}\"", t)?;
}
write!(fmt, "]")
}
}
}
}
fn display_array_str<T: fmt::Display>(slice: &[T], fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(fmt, "[")?;
for (i, t) in slice.iter().enumerate() {
if i > 0 {
write!(fmt, ",")?;
}
write!(fmt, "{}", t)?;
}
write!(fmt, "]")
}
macro_rules! into_array {
($(($t:ty, $val:expr),)+) => {
$(
impl From<$t> for Array {
fn from(t: $t) -> Self {
$val(t)
}
}
)+
}
}
into_array!(
(Vec<bool>, Array::Bool),
(Vec<i64>, Array::I64),
(Vec<f64>, Array::F64),
(Vec<StringValue>, Array::String),
);
/// The value part of attribute [KeyValue] pairs.
#[derive(Clone, Debug, PartialEq)]
pub enum Value {
/// bool values
Bool(bool),
/// i64 values
I64(i64),
/// f64 values
F64(f64),
/// String values
String(StringValue),
/// Array of homogeneous values
Array(Array),
}
/// Wrapper for string-like values
#[derive(Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
pub struct StringValue(OtelString);
impl fmt::Debug for StringValue {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
self.0.fmt(f)
}
}
impl fmt::Display for StringValue {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match &self.0 {
OtelString::Owned(s) => s.fmt(f),
OtelString::Static(s) => s.fmt(f),
OtelString::RefCounted(s) => s.fmt(f),
}
}
}
impl AsRef<str> for StringValue {
fn as_ref(&self) -> &str {
self.0.as_str()
}
}
impl StringValue {
/// Returns a string slice to this value
pub fn as_str(&self) -> &str {
self.0.as_str()
}
}
impl From<StringValue> for String {
fn from(s: StringValue) -> Self {
match s.0 {
OtelString::Owned(s) => s.to_string(),
OtelString::Static(s) => s.to_string(),
OtelString::RefCounted(s) => s.to_string(),
}
}
}
impl From<&'static str> for StringValue {
fn from(s: &'static str) -> Self {
StringValue(OtelString::Static(s))
}
}
impl From<String> for StringValue {
fn from(s: String) -> Self {
StringValue(OtelString::Owned(s.into_boxed_str()))
}
}
impl From<Arc<str>> for StringValue {
fn from(s: Arc<str>) -> Self {
StringValue(OtelString::RefCounted(s))
}
}
impl From<Cow<'static, str>> for StringValue {
fn from(s: Cow<'static, str>) -> Self {
match s {
Cow::Owned(s) => StringValue(OtelString::Owned(s.into_boxed_str())),
Cow::Borrowed(s) => StringValue(OtelString::Static(s)),
}
}
}
impl Value {
/// String representation of the `Value`
///
/// This will allocate iff the underlying value is not a `String`.
pub fn as_str(&self) -> Cow<'_, str> {
match self {
Value::Bool(v) => format!("{}", v).into(),
Value::I64(v) => format!("{}", v).into(),
Value::F64(v) => format!("{}", v).into(),
Value::String(v) => Cow::Borrowed(v.as_str()),
Value::Array(v) => format!("{}", v).into(),
}
}
}
macro_rules! from_values {
(
$(
($t:ty, $val:expr);
)+
) => {
$(
impl From<$t> for Value {
fn from(t: $t) -> Self {
$val(t)
}
}
)+
}
}
from_values!(
(bool, Value::Bool);
(i64, Value::I64);
(f64, Value::F64);
(StringValue, Value::String);
);
impl From<&'static str> for Value {
fn from(s: &'static str) -> Self {
Value::String(s.into())
}
}
impl From<String> for Value {
fn from(s: String) -> Self {
Value::String(s.into())
}
}
impl From<Arc<str>> for Value {
fn from(s: Arc<str>) -> Self {
Value::String(s.into())
}
}
impl From<Cow<'static, str>> for Value {
fn from(s: Cow<'static, str>) -> Self {
Value::String(s.into())
}
}
impl fmt::Display for Value {
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Value::Bool(v) => v.fmt(fmt),
Value::I64(v) => v.fmt(fmt),
Value::F64(v) => v.fmt(fmt),
Value::String(v) => fmt.write_str(v.as_str()),
Value::Array(v) => v.fmt(fmt),
}
}
}
/// A key-value pair describing an attribute.
#[derive(Clone, Debug, PartialEq)]
pub struct KeyValue {
/// The attribute name
pub key: Key,
/// The attribute value
pub value: Value,
}
impl KeyValue {
/// Create a new `KeyValue` pair.
pub fn new<K, V>(key: K, value: V) -> Self
where
K: Into<Key>,
V: Into<Value>,
{
KeyValue {
key: key.into(),
value: value.into(),
}
}
}
/// Marker trait for errors returned by exporters
pub trait ExportError: std::error::Error + Send + Sync + 'static {
/// The name of exporter that returned this error
fn exporter_name(&self) -> &'static str;
}
/// Information about a library or crate providing instrumentation.
///
/// An instrumentation library should be named to follow any naming conventions
/// of the instrumented library (e.g. 'middleware' for a web framework).
///
/// See the [instrumentation libraries] spec for more information.
///
/// [instrumentation libraries]: https://github.com/open-telemetry/opentelemetry-specification/blob/v1.9.0/specification/overview.md#instrumentation-libraries
#[derive(Debug, Default, Clone)]
#[non_exhaustive]
pub struct InstrumentationLibrary {
/// The library name.
///
/// This should be the name of the crate providing the instrumentation.
pub name: Cow<'static, str>,
/// The library version.
///
/// # Examples
///
/// ```
/// let library = opentelemetry_api::InstrumentationLibrary::new(
/// "my-crate",
/// Some(env!("CARGO_PKG_VERSION")),
/// Some("https://opentelemetry.io/schemas/1.17.0"),
/// None,
/// );
/// ```
pub version: Option<Cow<'static, str>>,
/// [Schema url] used by this library.
///
/// [Schema url]: https://github.com/open-telemetry/opentelemetry-specification/blob/v1.9.0/specification/schemas/overview.md#schema-url
pub schema_url: Option<Cow<'static, str>>,
/// Specifies the instrumentation scope attributes to associate with emitted telemetry.
pub attributes: Vec<KeyValue>,
}
// Uniqueness for InstrumentationLibrary/InstrumentationScope does not depend on attributes
impl Eq for InstrumentationLibrary {}
impl PartialEq for InstrumentationLibrary {
fn eq(&self, other: &Self) -> bool {
self.name == other.name
&& self.version == other.version
&& self.schema_url == other.schema_url
}
}
impl hash::Hash for InstrumentationLibrary {
fn hash<H: hash::Hasher>(&self, state: &mut H) {
self.name.hash(state);
self.version.hash(state);
self.schema_url.hash(state);
}
}
impl InstrumentationLibrary {
/// Create an new instrumentation library.
pub fn new(
name: impl Into<Cow<'static, str>>,
version: Option<impl Into<Cow<'static, str>>>,
schema_url: Option<impl Into<Cow<'static, str>>>,
attributes: Option<Vec<KeyValue>>,
) -> InstrumentationLibrary {
InstrumentationLibrary {
name: name.into(),
version: version.map(Into::into),
schema_url: schema_url.map(Into::into),
attributes: attributes.unwrap_or_default(),
}
}
}

View File

@ -1,396 +0,0 @@
use std::any::{Any, TypeId};
use std::cell::RefCell;
use std::collections::HashMap;
use std::fmt;
use std::hash::{BuildHasherDefault, Hasher};
use std::marker::PhantomData;
use std::sync::Arc;
thread_local! {
static CURRENT_CONTEXT: RefCell<Context> = RefCell::new(Context::default());
}
/// An execution-scoped collection of values.
///
/// A [`Context`] is a propagation mechanism which carries execution-scoped
/// values across API boundaries and between logically associated execution
/// units. Cross-cutting concerns access their data in-process using the same
/// shared context object.
///
/// [`Context`]s are immutable, and their write operations result in the creation
/// of a new context containing the original values and the new specified values.
///
/// ## Context state
///
/// Concerns can create and retrieve their local state in the current execution
/// state represented by a context through the [`get`] and [`with_value`]
/// methods. It is recommended to use application-specific types when storing new
/// context values to avoid unintentionally overwriting existing state.
///
/// ## Managing the current context
///
/// Contexts can be associated with the caller's current execution unit on a
/// given thread via the [`attach`] method, and previous contexts can be restored
/// by dropping the returned [`ContextGuard`]. Context can be nested, and will
/// restore their parent outer context when detached on drop. To access the
/// values of the context, a snapshot can be created via the [`Context::current`]
/// method.
///
/// [`Context::current`]: Context::current()
/// [`get`]: Context::get()
/// [`with_value`]: Context::with_value()
/// [`attach`]: Context::attach()
///
/// # Examples
///
/// ```
/// use opentelemetry_api::Context;
///
/// // Application-specific `a` and `b` values
/// #[derive(Debug, PartialEq)]
/// struct ValueA(&'static str);
/// #[derive(Debug, PartialEq)]
/// struct ValueB(u64);
///
/// let _outer_guard = Context::new().with_value(ValueA("a")).attach();
///
/// // Only value a has been set
/// let current = Context::current();
/// assert_eq!(current.get::<ValueA>(), Some(&ValueA("a")));
/// assert_eq!(current.get::<ValueB>(), None);
///
/// {
/// let _inner_guard = Context::current_with_value(ValueB(42)).attach();
/// // Both values are set in inner context
/// let current = Context::current();
/// assert_eq!(current.get::<ValueA>(), Some(&ValueA("a")));
/// assert_eq!(current.get::<ValueB>(), Some(&ValueB(42)));
/// }
///
/// // Resets to only the `a` value when inner guard is dropped
/// let current = Context::current();
/// assert_eq!(current.get::<ValueA>(), Some(&ValueA("a")));
/// assert_eq!(current.get::<ValueB>(), None);
/// ```
#[derive(Clone, Default)]
pub struct Context {
entries: HashMap<TypeId, Arc<dyn Any + Sync + Send>, BuildHasherDefault<IdHasher>>,
}
impl Context {
/// Creates an empty `Context`.
///
/// The context is initially created with a capacity of 0, so it will not
/// allocate. Use [`with_value`] to create a new context that has entries.
///
/// [`with_value`]: Context::with_value()
pub fn new() -> Self {
Context::default()
}
/// Returns an immutable snapshot of the current thread's context.
///
/// # Examples
///
/// ```
/// use opentelemetry_api::Context;
///
/// #[derive(Debug, PartialEq)]
/// struct ValueA(&'static str);
///
/// fn do_work() {
/// assert_eq!(Context::current().get(), Some(&ValueA("a")));
/// }
///
/// let _guard = Context::new().with_value(ValueA("a")).attach();
/// do_work()
/// ```
pub fn current() -> Self {
Context::map_current(|cx| cx.clone())
}
/// Applys a function to the current context returning its value.
///
/// This can be used to build higher performing algebraic expressions for
/// optionally creating a new context without the overhead of cloning the
/// current one and dropping it.
///
/// Note: This function will panic if you attempt to attach another context
/// while the current one is still borrowed.
pub fn map_current<T>(f: impl FnOnce(&Context) -> T) -> T {
CURRENT_CONTEXT.with(|cx| f(&cx.borrow()))
}
/// Returns a clone of the current thread's context with the given value.
///
/// This is a more efficient form of `Context::current().with_value(value)`
/// as it avoids the intermediate context clone.
///
/// # Examples
///
/// ```
/// use opentelemetry_api::Context;
///
/// // Given some value types defined in your application
/// #[derive(Debug, PartialEq)]
/// struct ValueA(&'static str);
/// #[derive(Debug, PartialEq)]
/// struct ValueB(u64);
///
/// // You can create and attach context with the first value set to "a"
/// let _guard = Context::new().with_value(ValueA("a")).attach();
///
/// // And create another context based on the fist with a new value
/// let all_current_and_b = Context::current_with_value(ValueB(42));
///
/// // The second context now contains all the current values and the addition
/// assert_eq!(all_current_and_b.get::<ValueA>(), Some(&ValueA("a")));
/// assert_eq!(all_current_and_b.get::<ValueB>(), Some(&ValueB(42)));
/// ```
pub fn current_with_value<T: 'static + Send + Sync>(value: T) -> Self {
let mut new_context = Context::current();
new_context
.entries
.insert(TypeId::of::<T>(), Arc::new(value));
new_context
}
/// Returns a reference to the entry for the corresponding value type.
///
/// # Examples
///
/// ```
/// use opentelemetry_api::Context;
///
/// // Given some value types defined in your application
/// #[derive(Debug, PartialEq)]
/// struct ValueA(&'static str);
/// #[derive(Debug, PartialEq)]
/// struct MyUser();
///
/// let cx = Context::new().with_value(ValueA("a"));
///
/// // Values can be queried by type
/// assert_eq!(cx.get::<ValueA>(), Some(&ValueA("a")));
///
/// // And return none if not yet set
/// assert_eq!(cx.get::<MyUser>(), None);
/// ```
pub fn get<T: 'static>(&self) -> Option<&T> {
self.entries
.get(&TypeId::of::<T>())
.and_then(|rc| rc.downcast_ref())
}
/// Returns a copy of the context with the new value included.
///
/// # Examples
///
/// ```
/// use opentelemetry_api::Context;
///
/// // Given some value types defined in your application
/// #[derive(Debug, PartialEq)]
/// struct ValueA(&'static str);
/// #[derive(Debug, PartialEq)]
/// struct ValueB(u64);
///
/// // You can create a context with the first value set to "a"
/// let cx_with_a = Context::new().with_value(ValueA("a"));
///
/// // And create another context based on the fist with a new value
/// let cx_with_a_and_b = cx_with_a.with_value(ValueB(42));
///
/// // The first context is still available and unmodified
/// assert_eq!(cx_with_a.get::<ValueA>(), Some(&ValueA("a")));
/// assert_eq!(cx_with_a.get::<ValueB>(), None);
///
/// // The second context now contains both values
/// assert_eq!(cx_with_a_and_b.get::<ValueA>(), Some(&ValueA("a")));
/// assert_eq!(cx_with_a_and_b.get::<ValueB>(), Some(&ValueB(42)));
/// ```
pub fn with_value<T: 'static + Send + Sync>(&self, value: T) -> Self {
let mut new_context = self.clone();
new_context
.entries
.insert(TypeId::of::<T>(), Arc::new(value));
new_context
}
/// Replaces the current context on this thread with this context.
///
/// Dropping the returned [`ContextGuard`] will reset the current context to the
/// previous value.
///
///
/// # Examples
///
/// ```
/// use opentelemetry_api::Context;
///
/// #[derive(Debug, PartialEq)]
/// struct ValueA(&'static str);
///
/// let my_cx = Context::new().with_value(ValueA("a"));
///
/// // Set the current thread context
/// let cx_guard = my_cx.attach();
/// assert_eq!(Context::current().get::<ValueA>(), Some(&ValueA("a")));
///
/// // Drop the guard to restore the previous context
/// drop(cx_guard);
/// assert_eq!(Context::current().get::<ValueA>(), None);
/// ```
///
/// Guards do not need to be explicitly dropped:
///
/// ```
/// use opentelemetry_api::Context;
///
/// #[derive(Debug, PartialEq)]
/// struct ValueA(&'static str);
///
/// fn my_function() -> String {
/// // attach a context the duration of this function.
/// let my_cx = Context::new().with_value(ValueA("a"));
/// // NOTE: a variable name after the underscore is **required** or rust
/// // will drop the guard, restoring the previous context _immediately_.
/// let _guard = my_cx.attach();
///
/// // anything happening in functions we call can still access my_cx...
/// my_other_function();
///
/// // returning from the function drops the guard, exiting the span.
/// return "Hello world".to_owned();
/// }
///
/// fn my_other_function() {
/// // ...
/// }
/// ```
/// Sub-scopes may be created to limit the duration for which the span is
/// entered:
///
/// ```
/// use opentelemetry_api::Context;
///
/// #[derive(Debug, PartialEq)]
/// struct ValueA(&'static str);
///
/// let my_cx = Context::new().with_value(ValueA("a"));
///
/// {
/// let _guard = my_cx.attach();
///
/// // the current context can access variables in
/// assert_eq!(Context::current().get::<ValueA>(), Some(&ValueA("a")));
///
/// // exiting the scope drops the guard, detaching the context.
/// }
///
/// // this is back in the default empty context
/// assert_eq!(Context::current().get::<ValueA>(), None);
/// ```
pub fn attach(self) -> ContextGuard {
let previous_cx = CURRENT_CONTEXT
.try_with(|current| current.replace(self))
.ok();
ContextGuard {
previous_cx,
_marker: PhantomData,
}
}
}
impl fmt::Debug for Context {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("Context")
.field("entries", &self.entries.len())
.finish()
}
}
/// A guard that resets the current context to the prior context when dropped.
#[allow(missing_debug_implementations)]
pub struct ContextGuard {
previous_cx: Option<Context>,
// ensure this type is !Send as it relies on thread locals
_marker: PhantomData<*const ()>,
}
impl Drop for ContextGuard {
fn drop(&mut self) {
if let Some(previous_cx) = self.previous_cx.take() {
let _ = CURRENT_CONTEXT.try_with(|current| current.replace(previous_cx));
}
}
}
/// With TypeIds as keys, there's no need to hash them. They are already hashes
/// themselves, coming from the compiler. The IdHasher holds the u64 of
/// the TypeId, and then returns it, instead of doing any bit fiddling.
#[derive(Clone, Default, Debug)]
struct IdHasher(u64);
impl Hasher for IdHasher {
fn write(&mut self, _: &[u8]) {
unreachable!("TypeId calls write_u64");
}
#[inline]
fn write_u64(&mut self, id: u64) {
self.0 = id;
}
#[inline]
fn finish(&self) -> u64 {
self.0
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn nested_contexts() {
#[derive(Debug, PartialEq)]
struct ValueA(&'static str);
#[derive(Debug, PartialEq)]
struct ValueB(u64);
let _outer_guard = Context::new().with_value(ValueA("a")).attach();
// Only value `a` is set
let current = Context::current();
assert_eq!(current.get(), Some(&ValueA("a")));
assert_eq!(current.get::<ValueB>(), None);
{
let _inner_guard = Context::current_with_value(ValueB(42)).attach();
// Both values are set in inner context
let current = Context::current();
assert_eq!(current.get(), Some(&ValueA("a")));
assert_eq!(current.get(), Some(&ValueB(42)));
assert!(Context::map_current(|cx| {
assert_eq!(cx.get(), Some(&ValueA("a")));
assert_eq!(cx.get(), Some(&ValueB(42)));
true
}));
}
// Resets to only value `a` when inner guard is dropped
let current = Context::current();
assert_eq!(current.get(), Some(&ValueA("a")));
assert_eq!(current.get::<ValueB>(), None);
assert!(Context::map_current(|cx| {
assert_eq!(cx.get(), Some(&ValueA("a")));
assert_eq!(cx.get::<ValueB>(), None);
true
}));
}
}

View File

@ -1,78 +0,0 @@
use std::sync::PoisonError;
use std::sync::RwLock;
#[cfg(feature = "logs")]
use crate::logs::LogError;
#[cfg(feature = "metrics")]
use crate::metrics::MetricsError;
#[cfg(feature = "trace")]
use crate::trace::TraceError;
use once_cell::sync::Lazy;
static GLOBAL_ERROR_HANDLER: Lazy<RwLock<Option<ErrorHandler>>> = Lazy::new(|| RwLock::new(None));
/// Wrapper for error from both tracing and metrics part of open telemetry.
#[derive(thiserror::Error, Debug)]
#[non_exhaustive]
pub enum Error {
#[cfg(feature = "trace")]
#[cfg_attr(docsrs, doc(cfg(feature = "trace")))]
#[error(transparent)]
/// Failed to export traces.
Trace(#[from] TraceError),
#[cfg(feature = "metrics")]
#[cfg_attr(docsrs, doc(cfg(feature = "metrics")))]
#[error(transparent)]
/// An issue raised by the metrics module.
Metric(#[from] MetricsError),
#[cfg(feature = "logs")]
#[cfg_attr(docsrs, doc(cfg(feature = "logs")))]
#[error(transparent)]
/// Failed to export logs.
Log(#[from] LogError),
#[error("{0}")]
/// Other types of failures not covered by the variants above.
Other(String),
}
impl<T> From<PoisonError<T>> for Error {
fn from(err: PoisonError<T>) -> Self {
Error::Other(err.to_string())
}
}
struct ErrorHandler(Box<dyn Fn(Error) + Send + Sync>);
/// Handle error using the globally configured error handler.
///
/// Writes to stderr if unset.
pub fn handle_error<T: Into<Error>>(err: T) {
match GLOBAL_ERROR_HANDLER.read() {
Ok(handler) if handler.is_some() => (handler.as_ref().unwrap().0)(err.into()),
_ => match err.into() {
#[cfg(feature = "metrics")]
#[cfg_attr(docsrs, doc(cfg(feature = "metrics")))]
Error::Metric(err) => eprintln!("OpenTelemetry metrics error occurred. {}", err),
#[cfg(feature = "trace")]
#[cfg_attr(docsrs, doc(cfg(feature = "trace")))]
Error::Trace(err) => eprintln!("OpenTelemetry trace error occurred. {}", err),
#[cfg(feature = "logs")]
#[cfg_attr(docsrs, doc(cfg(feature = "logs")))]
Error::Log(err) => eprintln!("OpenTelemetry log error occurred. {}", err),
Error::Other(err_msg) => eprintln!("OpenTelemetry error occurred. {}", err_msg),
},
}
}
/// Set global error handler.
pub fn set_error_handler<F>(f: F) -> std::result::Result<(), Error>
where
F: Fn(Error) + Send + Sync + 'static,
{
GLOBAL_ERROR_HANDLER
.write()
.map(|mut handler| *handler = Some(ErrorHandler(Box::new(f))))
.map_err(Into::into)
}

View File

@ -1,136 +0,0 @@
use std::{
borrow::Cow,
fmt, mem,
sync::{Arc, RwLock},
};
use once_cell::sync::Lazy;
use crate::{
logs::{Logger, LoggerProvider, NoopLoggerProvider},
InstrumentationLibrary,
};
/// Allows a specific [`LoggerProvider`] to be used generically, by mirroring
/// the interface, and boxing the returned types.
///
/// [`LoggerProvider`]: crate::logs::LoggerProvider.
pub trait ObjectSafeLoggerProvider {
/// Creates a versioned named [`Logger`] instance that is a trait object
/// through the underlying [`LoggerProvider`].
///
/// [`Logger`]: crate::logs::Logger
/// [`LoggerProvider`]: crate::logs::LoggerProvider
fn boxed_logger(
&self,
library: Arc<InstrumentationLibrary>,
) -> Box<dyn Logger + Send + Sync + 'static>;
}
impl<L, P> ObjectSafeLoggerProvider for P
where
L: Logger + Send + Sync + 'static,
P: LoggerProvider<Logger = L>,
{
fn boxed_logger(
&self,
library: Arc<InstrumentationLibrary>,
) -> Box<dyn Logger + Send + Sync + 'static> {
Box::new(self.library_logger(library))
}
}
pub struct BoxedLogger(Box<dyn Logger + Send + Sync + 'static>);
impl fmt::Debug for BoxedLogger {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_str("BoxedLogger")
}
}
impl Logger for BoxedLogger {
fn emit(&self, record: crate::logs::LogRecord) {
self.0.emit(record)
}
#[cfg(feature = "logs_level_enabled")]
fn event_enabled(&self, level: crate::logs::Severity, target: &str) -> bool {
self.0.event_enabled(level, target)
}
}
#[derive(Clone)]
/// Represents the globally configured [`LoggerProvider`] instance.
pub struct GlobalLoggerProvider {
provider: Arc<dyn ObjectSafeLoggerProvider + Send + Sync>,
}
impl fmt::Debug for GlobalLoggerProvider {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_str("GlobalLoggerProvider")
}
}
impl GlobalLoggerProvider {
fn new<
L: Logger + Send + Sync + 'static,
P: LoggerProvider<Logger = L> + Send + Sync + 'static,
>(
provider: P,
) -> Self {
GlobalLoggerProvider {
provider: Arc::new(provider),
}
}
}
impl LoggerProvider for GlobalLoggerProvider {
type Logger = BoxedLogger;
fn library_logger(&self, library: Arc<InstrumentationLibrary>) -> Self::Logger {
BoxedLogger(self.provider.boxed_logger(library))
}
}
static GLOBAL_LOGGER_PROVIDER: Lazy<RwLock<GlobalLoggerProvider>> =
Lazy::new(|| RwLock::new(GlobalLoggerProvider::new(NoopLoggerProvider::new())));
/// Returns an instance of the currently configured global [`LoggerProvider`]
/// through [`GlobalLoggerProvider`].
///
/// [`LoggerProvider`]: crate::logs::LoggerProvider
pub fn logger_provider() -> GlobalLoggerProvider {
GLOBAL_LOGGER_PROVIDER
.read()
.expect("GLOBAL_LOGGER_PROVIDER RwLock poisoned")
.clone()
}
/// Creates a named instance of [`Logger`] via the configured
/// [`GlobalLoggerProvider`].
///
/// If `name` is an empty string, the provider will use a default name.
///
/// [`Logger`]: crate::logs::Logger
pub fn logger(name: Cow<'static, str>) -> BoxedLogger {
logger_provider().logger(name)
}
/// Sets the given [`LoggerProvider`] instance as the current global provider,
/// returning the [`LoggerProvider`] instance that was previously set as global
/// provider.
pub fn set_logger_provider<L, P>(new_provider: P) -> GlobalLoggerProvider
where
L: Logger + Send + Sync + 'static,
P: LoggerProvider<Logger = L> + Send + Sync + 'static,
{
let mut provider = GLOBAL_LOGGER_PROVIDER
.write()
.expect("GLOBAL_LOGGER_PROVIDER RwLock poisoned");
mem::replace(&mut *provider, GlobalLoggerProvider::new(new_provider))
}
/// Shut down the current global [`LoggerProvider`].
pub fn shutdown_logger_provider() {
let _ = set_logger_provider(NoopLoggerProvider::new());
}

View File

@ -1,152 +0,0 @@
use crate::metrics::{self, Meter, MeterProvider};
use crate::KeyValue;
use core::fmt;
use once_cell::sync::Lazy;
use std::{
borrow::Cow,
sync::{Arc, RwLock},
};
/// The global `Meter` provider singleton.
static GLOBAL_METER_PROVIDER: Lazy<RwLock<GlobalMeterProvider>> = Lazy::new(|| {
RwLock::new(GlobalMeterProvider::new(
metrics::noop::NoopMeterProvider::new(),
))
});
/// Allows a specific [MeterProvider] to be used generically by the
/// [GlobalMeterProvider] by mirroring the interface and boxing the return types.
pub trait ObjectSafeMeterProvider {
/// Creates a versioned named meter instance that is a trait object through the underlying
/// [MeterProvider].
fn versioned_meter_cow(
&self,
name: Cow<'static, str>,
version: Option<Cow<'static, str>>,
schema_url: Option<Cow<'static, str>>,
attributes: Option<Vec<KeyValue>>,
) -> Meter;
}
impl<P> ObjectSafeMeterProvider for P
where
P: MeterProvider,
{
/// Return a versioned boxed tracer
fn versioned_meter_cow(
&self,
name: Cow<'static, str>,
version: Option<Cow<'static, str>>,
schema_url: Option<Cow<'static, str>>,
attributes: Option<Vec<KeyValue>>,
) -> Meter {
self.versioned_meter(name, version, schema_url, attributes)
}
}
/// Represents the globally configured [`MeterProvider`] instance for this
/// application.
#[derive(Clone)]
pub struct GlobalMeterProvider {
provider: Arc<dyn ObjectSafeMeterProvider + Send + Sync>,
}
impl fmt::Debug for GlobalMeterProvider {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("GlobalMeterProvider").finish()
}
}
impl MeterProvider for GlobalMeterProvider {
fn versioned_meter(
&self,
name: impl Into<Cow<'static, str>>,
version: Option<impl Into<Cow<'static, str>>>,
schema_url: Option<impl Into<Cow<'static, str>>>,
attributes: Option<Vec<KeyValue>>,
) -> Meter {
self.provider.versioned_meter_cow(
name.into(),
version.map(Into::into),
schema_url.map(Into::into),
attributes,
)
}
}
impl GlobalMeterProvider {
/// Create a new global meter provider
pub fn new<P>(provider: P) -> Self
where
P: MeterProvider + Send + Sync + 'static,
{
GlobalMeterProvider {
provider: Arc::new(provider),
}
}
}
/// Sets the given [`MeterProvider`] instance as the current global meter
/// provider.
pub fn set_meter_provider<P>(new_provider: P)
where
P: metrics::MeterProvider + Send + Sync + 'static,
{
let mut global_provider = GLOBAL_METER_PROVIDER
.write()
.expect("GLOBAL_METER_PROVIDER RwLock poisoned");
*global_provider = GlobalMeterProvider::new(new_provider);
}
/// Returns an instance of the currently configured global [`MeterProvider`]
/// through [`GlobalMeterProvider`].
pub fn meter_provider() -> GlobalMeterProvider {
GLOBAL_METER_PROVIDER
.read()
.expect("GLOBAL_METER_PROVIDER RwLock poisoned")
.clone()
}
/// Creates a named [`Meter`] via the configured [`GlobalMeterProvider`].
///
/// If the name is an empty string, the provider will use a default name.
///
/// This is a more convenient way of expressing `global::meter_provider().versioned_meter(name, None, None, None)`.
pub fn meter(name: impl Into<Cow<'static, str>>) -> Meter {
meter_provider().meter(name.into())
}
/// Creates a [`Meter`] with the name, version and schema url.
///
/// - name SHOULD uniquely identify the instrumentation scope, such as the instrumentation library (e.g. io.opentelemetry.contrib.mongodb), package, module or class name.
/// - version specifies the version of the instrumentation scope if the scope has a version
/// - schema url specifies the Schema URL that should be recorded in the emitted telemetry.
///
/// This is a convenient way of `global::meter_provider().versioned_meter(...)`
///
/// # Example
///
/// ```
/// use opentelemetry_api::global::meter_with_version;
/// use opentelemetry_api::KeyValue;
///
/// let meter = meter_with_version(
/// "io.opentelemetry",
/// Some("0.17"),
/// Some("https://opentelemetry.io/schemas/1.2.0"),
/// Some(vec![KeyValue::new("key", "value")]),
/// );
/// ```
pub fn meter_with_version(
name: impl Into<Cow<'static, str>>,
version: Option<impl Into<Cow<'static, str>>>,
schema_url: Option<impl Into<Cow<'static, str>>>,
attributes: Option<Vec<KeyValue>>,
) -> Meter {
meter_provider().versioned_meter(
name.into(),
version.map(Into::into),
schema_url.map(Into::into),
attributes,
)
}

View File

@ -1,30 +0,0 @@
use crate::propagation::TextMapPropagator;
use crate::trace::noop::NoopTextMapPropagator;
use once_cell::sync::Lazy;
use std::sync::RwLock;
/// The current global `TextMapPropagator` propagator.
static GLOBAL_TEXT_MAP_PROPAGATOR: Lazy<RwLock<Box<dyn TextMapPropagator + Send + Sync>>> =
Lazy::new(|| RwLock::new(Box::new(NoopTextMapPropagator::new())));
/// The global default `TextMapPropagator` propagator.
static DEFAULT_TEXT_MAP_PROPAGATOR: Lazy<NoopTextMapPropagator> =
Lazy::new(NoopTextMapPropagator::new);
/// Sets the given [`TextMapPropagator`] propagator as the current global propagator.
pub fn set_text_map_propagator<P: TextMapPropagator + Send + Sync + 'static>(propagator: P) {
let _lock = GLOBAL_TEXT_MAP_PROPAGATOR
.write()
.map(|mut global_propagator| *global_propagator = Box::new(propagator));
}
/// Executes a closure with a reference to the current global [`TextMapPropagator`] propagator.
pub fn get_text_map_propagator<T, F>(mut f: F) -> T
where
F: FnMut(&dyn TextMapPropagator) -> T,
{
GLOBAL_TEXT_MAP_PROPAGATOR
.read()
.map(|propagator| f(&**propagator))
.unwrap_or_else(|_| f(&*DEFAULT_TEXT_MAP_PROPAGATOR as &dyn TextMapPropagator))
}

View File

@ -1,97 +0,0 @@
//! OpenTelemetry provides a single set of APIs, libraries, agents, and collector
//! services to capture distributed traces and metrics from your application. You
//! can analyze them using [Prometheus], [Jaeger], and other observability tools.
//!
//! *Compiler support: [requires `rustc` 1.60+][msrv]*
//!
//! [Prometheus]: https://prometheus.io
//! [Jaeger]: https://www.jaegertracing.io
//! [msrv]: #supported-rust-versions
//!
//! ## Supported Rust Versions
//!
//! OpenTelemetry is built against the latest stable release. The minimum
//! supported version is 1.60. The current OpenTelemetry version is not
//! guaranteed to build on Rust versions earlier than the minimum supported
//! version.
//!
//! The current stable Rust compiler and the three most recent minor versions
//! before it will always be supported. For example, if the current stable
//! compiler version is 1.49, the minimum supported version will not be
//! increased past 1.46, three minor versions prior. Increasing the minimum
//! supported compiler version is not considered a semver breaking change as
//! long as doing so complies with this policy.
#![warn(
future_incompatible,
missing_debug_implementations,
missing_docs,
nonstandard_style,
rust_2018_idioms,
unreachable_pub,
unused
)]
#![allow(clippy::needless_doctest_main)]
#![cfg_attr(
docsrs,
feature(doc_cfg, doc_auto_cfg),
deny(rustdoc::broken_intra_doc_links)
)]
#![doc(
html_logo_url = "https://raw.githubusercontent.com/open-telemetry/opentelemetry-rust/main/assets/logo.svg"
)]
#![cfg_attr(test, deny(warnings))]
pub mod global;
pub mod baggage;
mod context;
pub use context::{Context, ContextGuard};
mod common;
mod order_map;
pub use order_map::OrderMap;
#[cfg(any(feature = "testing", test))]
#[doc(hidden)]
pub mod testing;
pub use common::{Array, ExportError, InstrumentationLibrary, Key, KeyValue, StringValue, Value};
#[cfg(feature = "metrics")]
#[cfg_attr(docsrs, doc(cfg(feature = "metrics")))]
pub mod metrics;
pub mod propagation;
#[cfg(feature = "trace")]
#[cfg_attr(docsrs, doc(cfg(feature = "trace")))]
pub mod trace;
#[cfg(feature = "logs")]
#[cfg_attr(docsrs, doc(cfg(feature = "logs")))]
pub mod logs;
#[doc(hidden)]
#[cfg(any(feature = "metrics", feature = "trace"))]
pub mod time {
use std::time::SystemTime;
#[doc(hidden)]
#[cfg(any(
not(target_arch = "wasm32"),
all(target_arch = "wasm32", target_os = "wasi")
))]
pub fn now() -> SystemTime {
SystemTime::now()
}
#[doc(hidden)]
#[cfg(all(target_arch = "wasm32", not(target_os = "wasi")))]
pub fn now() -> SystemTime {
SystemTime::UNIX_EPOCH + std::time::Duration::from_millis(js_sys::Date::now() as u64)
}
}

View File

@ -1,75 +0,0 @@
use std::{borrow::Cow, sync::Arc};
use crate::{logs::LogRecord, InstrumentationLibrary, KeyValue};
#[cfg(feature = "logs_level_enabled")]
use super::Severity;
/// The interface for emitting [`LogRecord`]s.
pub trait Logger {
/// Emit a [`LogRecord`]. If there is active current thread's [`Context`],
/// the logger will set the record's [`TraceContext`] to the active trace context,
///
/// [`Context`]: crate::Context
/// [`TraceContext`]: crate::logs::TraceContext
fn emit(&self, record: LogRecord);
#[cfg(feature = "logs_level_enabled")]
/// Check if the given log level is enabled.
fn event_enabled(&self, level: Severity, target: &str) -> bool;
}
/// Interfaces that can create [`Logger`] instances.
pub trait LoggerProvider {
/// The [`Logger`] type that this provider will return.
type Logger: Logger;
/// Returns a new versioned logger with a given name.
///
/// The `name` should be the application name or the name of the library
/// providing instrumentation. If the name is empty, then an
/// implementation-defined default name may be used instead.
fn versioned_logger(
&self,
name: impl Into<Cow<'static, str>>,
version: Option<Cow<'static, str>>,
schema_url: Option<Cow<'static, str>>,
attributes: Option<Vec<KeyValue>>,
) -> Self::Logger {
self.library_logger(Arc::new(InstrumentationLibrary::new(
name, version, schema_url, attributes,
)))
}
/// Returns a new versioned logger with the given instrumentation library.
///
/// # Examples
///
/// ```
/// use opentelemetry_api::{global, InstrumentationLibrary, logs::LoggerProvider};
///
/// let provider = global::logger_provider();
///
/// // logger used in applications/binaries
/// let logger = provider.logger("my_app");
/// // logger used in libraries/crates that optionally includes version and schema url
/// let library = std::sync::Arc::new(InstrumentationLibrary::new(
/// env!("CARGO_PKG_NAME"),
/// Some(env!("CARGO_PKG_VERSION")),
/// Some("https://opentelemetry.io/schema/1.0.0"),
/// None,
/// ));
/// let logger = provider.library_logger(library);
/// ```
fn library_logger(&self, library: Arc<InstrumentationLibrary>) -> Self::Logger;
/// Returns a new logger with the given name.
///
/// The `name` should be the application name or the name of the library
/// providing instrumentation. If the name is empty, then an
/// implementation-defined default name may be used instead.
fn logger(&self, name: impl Into<Cow<'static, str>>) -> Self::Logger {
self.versioned_logger(name, None, None, None)
}
}

View File

@ -1,72 +0,0 @@
//! # OpenTelemetry Logs API
use crate::ExportError;
use futures_channel::{mpsc::TrySendError, oneshot::Canceled};
use std::time::Duration;
use thiserror::Error;
mod logger;
mod noop;
mod record;
pub use logger::{Logger, LoggerProvider};
pub use noop::NoopLoggerProvider;
pub use record::{AnyValue, LogRecord, LogRecordBuilder, Severity, TraceContext};
/// Describe the result of operations in log SDK.
pub type LogResult<T> = Result<T, LogError>;
#[derive(Error, Debug)]
#[non_exhaustive]
/// Errors returned by the log SDK.
pub enum LogError {
/// Export failed with the error returned by the exporter.
#[error("Exporter {} encountered the following errors: {0}", .0.exporter_name())]
ExportFailed(Box<dyn ExportError>),
/// Export failed to finish after certain period and processor stopped the export.
#[error("Exporter timed out after {} seconds", .0.as_secs())]
ExportTimedOut(Duration),
/// Other errors propagated from log SDK that weren't covered above.
#[error(transparent)]
Other(#[from] Box<dyn std::error::Error + Send + Sync + 'static>),
}
impl<T> From<T> for LogError
where
T: ExportError,
{
fn from(err: T) -> Self {
LogError::ExportFailed(Box::new(err))
}
}
impl<T> From<TrySendError<T>> for LogError {
fn from(err: TrySendError<T>) -> Self {
LogError::Other(Box::new(err.into_send_error()))
}
}
impl From<Canceled> for LogError {
fn from(err: Canceled) -> Self {
LogError::Other(Box::new(err))
}
}
impl From<String> for LogError {
fn from(err_msg: String) -> Self {
LogError::Other(Box::new(Custom(err_msg)))
}
}
impl From<&'static str> for LogError {
fn from(err_msg: &'static str) -> Self {
LogError::Other(Box::new(Custom(err_msg.into())))
}
}
/// Wrap type for string
#[derive(Error, Debug)]
#[error("{0}")]
struct Custom(String);

View File

@ -1,47 +0,0 @@
use std::{borrow::Cow, sync::Arc};
use crate::{
logs::{LogRecord, Logger, LoggerProvider},
InstrumentationLibrary, KeyValue,
};
/// A no-op implementation of a [`LoggerProvider`].
#[derive(Clone, Debug, Default)]
pub struct NoopLoggerProvider(());
impl NoopLoggerProvider {
/// Create a new no-op logger provider.
pub fn new() -> Self {
NoopLoggerProvider(())
}
}
impl LoggerProvider for NoopLoggerProvider {
type Logger = NoopLogger;
fn library_logger(&self, _library: Arc<InstrumentationLibrary>) -> Self::Logger {
NoopLogger(())
}
fn versioned_logger(
&self,
_name: impl Into<Cow<'static, str>>,
_version: Option<Cow<'static, str>>,
_schema_url: Option<Cow<'static, str>>,
_attributes: Option<Vec<KeyValue>>,
) -> Self::Logger {
NoopLogger(())
}
}
/// A no-op implementation of a [`Logger`]
#[derive(Clone, Debug)]
pub struct NoopLogger(());
impl Logger for NoopLogger {
fn emit(&self, _record: LogRecord) {}
#[cfg(feature = "logs_level_enabled")]
fn event_enabled(&self, _level: super::Severity, _target: &str) -> bool {
true
}
}

View File

@ -1,367 +0,0 @@
use crate::{
trace::{SpanContext, SpanId, TraceContextExt, TraceFlags, TraceId},
Array, Key, OrderMap, StringValue, Value,
};
use std::{borrow::Cow, time::SystemTime};
#[derive(Debug, Clone, Default)]
#[non_exhaustive]
/// LogRecord represents all data carried by a log record, and
/// is provided to `LogExporter`s as input.
pub struct LogRecord {
/// Record timestamp
pub timestamp: Option<SystemTime>,
/// Timestamp for when the record was observed by OpenTelemetry
pub observed_timestamp: Option<SystemTime>,
/// Trace context for logs associated with spans
pub trace_context: Option<TraceContext>,
/// The original severity string from the source
pub severity_text: Option<Cow<'static, str>>,
/// The corresponding severity value, normalized
pub severity_number: Option<Severity>,
/// Record body
pub body: Option<AnyValue>,
/// Additional attributes associated with this record
pub attributes: Option<Vec<(Key, AnyValue)>>,
}
impl LogRecord {
/// Create a [`LogRecordBuilder`] to create a new Log Record
pub fn builder() -> LogRecordBuilder {
LogRecordBuilder::new()
}
}
/// TraceContext stores the trace data for logs that have an associated
/// span.
#[derive(Debug, Clone)]
#[non_exhaustive]
pub struct TraceContext {
/// Trace id
pub trace_id: TraceId,
/// Span Id
pub span_id: SpanId,
/// Trace flags
pub trace_flags: Option<TraceFlags>,
}
impl From<&SpanContext> for TraceContext {
fn from(span_context: &SpanContext) -> Self {
TraceContext {
trace_id: span_context.trace_id(),
span_id: span_context.span_id(),
trace_flags: Some(span_context.trace_flags()),
}
}
}
/// Value types for representing arbitrary values in a log record.
#[derive(Debug, Clone)]
pub enum AnyValue {
/// An integer value
Int(i64),
/// A double value
Double(f64),
/// A string value
String(StringValue),
/// A boolean value
Boolean(bool),
/// A byte array
Bytes(Vec<u8>),
/// An array of `Any` values
ListAny(Vec<AnyValue>),
/// A map of string keys to `Any` values, arbitrarily nested.
Map(OrderMap<Key, AnyValue>),
}
macro_rules! impl_trivial_from {
($t:ty, $variant:path) => {
impl From<$t> for AnyValue {
fn from(val: $t) -> AnyValue {
$variant(val.into())
}
}
};
}
impl_trivial_from!(i8, AnyValue::Int);
impl_trivial_from!(i16, AnyValue::Int);
impl_trivial_from!(i32, AnyValue::Int);
impl_trivial_from!(i64, AnyValue::Int);
impl_trivial_from!(u8, AnyValue::Int);
impl_trivial_from!(u16, AnyValue::Int);
impl_trivial_from!(u32, AnyValue::Int);
impl_trivial_from!(f64, AnyValue::Double);
impl_trivial_from!(f32, AnyValue::Double);
impl_trivial_from!(String, AnyValue::String);
impl_trivial_from!(Cow<'static, str>, AnyValue::String);
impl_trivial_from!(&'static str, AnyValue::String);
impl_trivial_from!(StringValue, AnyValue::String);
impl_trivial_from!(bool, AnyValue::Boolean);
impl<T: Into<AnyValue>> FromIterator<T> for AnyValue {
/// Creates an [`AnyValue::ListAny`] value from a sequence of `Into<AnyValue>` values.
fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self {
AnyValue::ListAny(iter.into_iter().map(Into::into).collect())
}
}
impl<K: Into<Key>, V: Into<AnyValue>> FromIterator<(K, V)> for AnyValue {
/// Creates an [`AnyValue::Map`] value from a sequence of key-value pairs
/// that can be converted into a `Key` and `AnyValue` respectively.
fn from_iter<I: IntoIterator<Item = (K, V)>>(iter: I) -> Self {
AnyValue::Map(OrderMap::from_iter(
iter.into_iter().map(|(k, v)| (k.into(), v.into())),
))
}
}
impl From<Value> for AnyValue {
fn from(value: Value) -> Self {
match value {
Value::Bool(b) => b.into(),
Value::I64(i) => i.into(),
Value::F64(f) => f.into(),
Value::String(s) => s.into(),
Value::Array(a) => match a {
Array::Bool(b) => AnyValue::from_iter(b),
Array::F64(f) => AnyValue::from_iter(f),
Array::I64(i) => AnyValue::from_iter(i),
Array::String(s) => AnyValue::from_iter(s),
},
}
}
}
/// A normalized severity value.
#[derive(Debug, Copy, Clone, PartialEq, Eq, Ord, PartialOrd)]
pub enum Severity {
/// TRACE
Trace = 1,
/// TRACE2
Trace2 = 2,
/// TRACE3
Trace3 = 3,
/// TRACE4
Trace4 = 4,
/// DEBUG
Debug = 5,
/// DEBUG2
Debug2 = 6,
/// DEBUG3
Debug3 = 7,
/// DEBUG4
Debug4 = 8,
/// INFO
Info = 9,
/// INFO2
Info2 = 10,
/// INFO3
Info3 = 11,
/// INFO4
Info4 = 12,
/// WARN
Warn = 13,
/// WARN2
Warn2 = 14,
/// WARN3
Warn3 = 15,
/// WARN4
Warn4 = 16,
/// ERROR
Error = 17,
/// ERROR2
Error2 = 18,
/// ERROR3
Error3 = 19,
/// ERROR4
Error4 = 20,
/// FATAL
Fatal = 21,
/// FATAL2
Fatal2 = 22,
/// FATAL3
Fatal3 = 23,
/// FATAL4
Fatal4 = 24,
}
impl Severity {
/// Return the string representing the short name for the `Severity`
/// value as specified by the OpenTelemetry logs data model.
pub const fn name(&self) -> &'static str {
match &self {
Severity::Trace => "TRACE",
Severity::Trace2 => "TRACE2",
Severity::Trace3 => "TRACE3",
Severity::Trace4 => "TRACE4",
Severity::Debug => "DEBUG",
Severity::Debug2 => "DEBUG2",
Severity::Debug3 => "DEBUG3",
Severity::Debug4 => "DEBUG4",
Severity::Info => "INFO",
Severity::Info2 => "INFO2",
Severity::Info3 => "INFO3",
Severity::Info4 => "INFO4",
Severity::Warn => "WARN",
Severity::Warn2 => "WARN2",
Severity::Warn3 => "WARN3",
Severity::Warn4 => "WARN4",
Severity::Error => "ERROR",
Severity::Error2 => "ERROR2",
Severity::Error3 => "ERROR3",
Severity::Error4 => "ERROR4",
Severity::Fatal => "FATAL",
Severity::Fatal2 => "FATAL2",
Severity::Fatal3 => "FATAL3",
Severity::Fatal4 => "FATAL4",
}
}
}
/// A builder for [`LogRecord`] values.
#[derive(Debug, Clone)]
pub struct LogRecordBuilder {
record: LogRecord,
}
impl LogRecordBuilder {
/// Create a new LogRecordBuilder
pub fn new() -> Self {
Self {
record: Default::default(),
}
}
/// Assign timestamp
pub fn with_timestamp(self, timestamp: SystemTime) -> Self {
Self {
record: LogRecord {
timestamp: Some(timestamp),
..self.record
},
}
}
/// Assign observed timestamp
pub fn with_observed_timestamp(self, timestamp: SystemTime) -> Self {
Self {
record: LogRecord {
observed_timestamp: Some(timestamp),
..self.record
},
}
}
/// Assign the record's [`TraceContext`]
pub fn with_span_context(self, span_context: &SpanContext) -> Self {
Self {
record: LogRecord {
trace_context: Some(TraceContext {
span_id: span_context.span_id(),
trace_id: span_context.trace_id(),
trace_flags: Some(span_context.trace_flags()),
}),
..self.record
},
}
}
/// Assign the record's [`TraceContext`] from a `TraceContextExt` trait
pub fn with_context<T>(self, context: &T) -> Self
where
T: TraceContextExt,
{
if context.has_active_span() {
self.with_span_context(context.span().span_context())
} else {
self
}
}
/// Assign severity text
pub fn with_severity_text<T>(self, severity: T) -> Self
where
T: Into<Cow<'static, str>>,
{
Self {
record: LogRecord {
severity_text: Some(severity.into()),
..self.record
},
}
}
/// Assign severity number
pub fn with_severity_number(self, severity: Severity) -> Self {
Self {
record: LogRecord {
severity_number: Some(severity),
..self.record
},
}
}
/// Assign body
pub fn with_body(self, body: AnyValue) -> Self {
Self {
record: LogRecord {
body: Some(body),
..self.record
},
}
}
/// Assign attributes.
/// The SDK doesn't carry on any deduplication on these attributes.
pub fn with_attributes(self, attributes: Vec<(Key, AnyValue)>) -> Self {
Self {
record: LogRecord {
attributes: Some(attributes),
..self.record
},
}
}
/// Set a single attribute for this record.
/// The SDK doesn't carry on any deduplication on these attributes.
pub fn with_attribute<K, V>(mut self, key: K, value: V) -> Self
where
K: Into<Key>,
V: Into<AnyValue>,
{
if let Some(ref mut vec) = self.record.attributes {
vec.push((key.into(), value.into()));
} else {
let vec = vec![(key.into(), value.into())];
self.record.attributes = Some(vec);
}
self
}
/// Build the record, consuming the Builder
pub fn build(self) -> LogRecord {
self.record
}
}
impl Default for LogRecordBuilder {
fn default() -> Self {
Self::new()
}
}

View File

@ -1,138 +0,0 @@
use crate::{
metrics::{AsyncInstrument, AsyncInstrumentBuilder, InstrumentBuilder, MetricsError},
KeyValue,
};
use core::fmt;
use std::sync::Arc;
use std::{any::Any, convert::TryFrom};
/// An SDK implemented instrument that records increasing values.
pub trait SyncCounter<T> {
/// Records an increment to the counter.
fn add(&self, value: T, attributes: &[KeyValue]);
}
/// An instrument that records increasing values.
#[derive(Clone)]
pub struct Counter<T>(Arc<dyn SyncCounter<T> + Send + Sync>);
impl<T> fmt::Debug for Counter<T>
where
T: fmt::Debug,
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_fmt(format_args!("Counter<{}>", std::any::type_name::<T>()))
}
}
impl<T> Counter<T> {
/// Create a new counter.
pub fn new(inner: Arc<dyn SyncCounter<T> + Send + Sync>) -> Self {
Counter(inner)
}
/// Records an increment to the counter.
pub fn add(&self, value: T, attributes: &[KeyValue]) {
self.0.add(value, attributes)
}
}
impl TryFrom<InstrumentBuilder<'_, Counter<u64>>> for Counter<u64> {
type Error = MetricsError;
fn try_from(builder: InstrumentBuilder<'_, Counter<u64>>) -> Result<Self, Self::Error> {
builder.meter.instrument_provider.u64_counter(
builder.name,
builder.description,
builder.unit,
)
}
}
impl TryFrom<InstrumentBuilder<'_, Counter<f64>>> for Counter<f64> {
type Error = MetricsError;
fn try_from(builder: InstrumentBuilder<'_, Counter<f64>>) -> Result<Self, Self::Error> {
builder.meter.instrument_provider.f64_counter(
builder.name,
builder.description,
builder.unit,
)
}
}
/// An async instrument that records increasing values.
#[derive(Clone)]
pub struct ObservableCounter<T>(Arc<dyn AsyncInstrument<T>>);
impl<T> ObservableCounter<T> {
/// Create a new observable counter.
pub fn new(inner: Arc<dyn AsyncInstrument<T>>) -> Self {
ObservableCounter(inner)
}
}
impl<T> fmt::Debug for ObservableCounter<T> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_fmt(format_args!(
"ObservableCounter<{}>",
std::any::type_name::<T>()
))
}
}
impl<T> ObservableCounter<T> {
/// Records an increment to the counter.
///
/// It is only valid to call this within a callback. If called outside of the
/// registered callback it should have no effect on the instrument, and an
/// error will be reported via the error handler.
pub fn observe(&self, value: T, attributes: &[KeyValue]) {
self.0.observe(value, attributes)
}
/// Used for SDKs to downcast instruments in callbacks.
pub fn as_any(&self) -> Arc<dyn Any> {
self.0.as_any()
}
}
impl<T> AsyncInstrument<T> for ObservableCounter<T> {
fn observe(&self, measurement: T, attributes: &[KeyValue]) {
self.0.observe(measurement, attributes)
}
fn as_any(&self) -> Arc<dyn Any> {
self.0.as_any()
}
}
impl TryFrom<AsyncInstrumentBuilder<'_, ObservableCounter<u64>, u64>> for ObservableCounter<u64> {
type Error = MetricsError;
fn try_from(
builder: AsyncInstrumentBuilder<'_, ObservableCounter<u64>, u64>,
) -> Result<Self, Self::Error> {
builder.meter.instrument_provider.u64_observable_counter(
builder.name,
builder.description,
builder.unit,
builder.callbacks,
)
}
}
impl TryFrom<AsyncInstrumentBuilder<'_, ObservableCounter<f64>, f64>> for ObservableCounter<f64> {
type Error = MetricsError;
fn try_from(
builder: AsyncInstrumentBuilder<'_, ObservableCounter<f64>, f64>,
) -> Result<Self, Self::Error> {
builder.meter.instrument_provider.f64_observable_counter(
builder.name,
builder.description,
builder.unit,
builder.callbacks,
)
}
}

View File

@ -1,101 +0,0 @@
use crate::{
metrics::{AsyncInstrument, AsyncInstrumentBuilder, MetricsError},
KeyValue,
};
use core::fmt;
use std::sync::Arc;
use std::{any::Any, convert::TryFrom};
/// An instrument that records independent readings.
#[derive(Clone)]
pub struct ObservableGauge<T>(Arc<dyn AsyncInstrument<T>>);
impl<T> fmt::Debug for ObservableGauge<T>
where
T: fmt::Debug,
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_fmt(format_args!(
"ObservableGauge<{}>",
std::any::type_name::<T>()
))
}
}
impl<T> ObservableGauge<T> {
/// Records the state of the instrument.
///
/// It is only valid to call this within a callback. If called outside of the
/// registered callback it should have no effect on the instrument, and an
/// error will be reported via the error handler.
pub fn observe(&self, measurement: T, attributes: &[KeyValue]) {
self.0.observe(measurement, attributes)
}
/// Used by SDKs to downcast instruments in callbacks.
pub fn as_any(&self) -> Arc<dyn Any> {
self.0.as_any()
}
}
impl<M> AsyncInstrument<M> for ObservableGauge<M> {
fn observe(&self, measurement: M, attributes: &[KeyValue]) {
self.observe(measurement, attributes)
}
fn as_any(&self) -> Arc<dyn Any> {
self.0.as_any()
}
}
impl<T> ObservableGauge<T> {
/// Create a new gauge
pub fn new(inner: Arc<dyn AsyncInstrument<T>>) -> Self {
ObservableGauge(inner)
}
}
impl TryFrom<AsyncInstrumentBuilder<'_, ObservableGauge<u64>, u64>> for ObservableGauge<u64> {
type Error = MetricsError;
fn try_from(
builder: AsyncInstrumentBuilder<'_, ObservableGauge<u64>, u64>,
) -> Result<Self, Self::Error> {
builder.meter.instrument_provider.u64_observable_gauge(
builder.name,
builder.description,
builder.unit,
builder.callbacks,
)
}
}
impl TryFrom<AsyncInstrumentBuilder<'_, ObservableGauge<f64>, f64>> for ObservableGauge<f64> {
type Error = MetricsError;
fn try_from(
builder: AsyncInstrumentBuilder<'_, ObservableGauge<f64>, f64>,
) -> Result<Self, Self::Error> {
builder.meter.instrument_provider.f64_observable_gauge(
builder.name,
builder.description,
builder.unit,
builder.callbacks,
)
}
}
impl TryFrom<AsyncInstrumentBuilder<'_, ObservableGauge<i64>, i64>> for ObservableGauge<i64> {
type Error = MetricsError;
fn try_from(
builder: AsyncInstrumentBuilder<'_, ObservableGauge<i64>, i64>,
) -> Result<Self, Self::Error> {
builder.meter.instrument_provider.i64_observable_gauge(
builder.name,
builder.description,
builder.unit,
builder.callbacks,
)
}
}

View File

@ -1,74 +0,0 @@
use crate::{
metrics::{InstrumentBuilder, MetricsError},
KeyValue,
};
use core::fmt;
use std::convert::TryFrom;
use std::sync::Arc;
/// An SDK implemented instrument that records a distribution of values.
pub trait SyncHistogram<T> {
/// Adds an additional value to the distribution.
fn record(&self, value: T, attributes: &[KeyValue]);
}
/// An instrument that records a distribution of values.
#[derive(Clone)]
pub struct Histogram<T>(Arc<dyn SyncHistogram<T> + Send + Sync>);
impl<T> fmt::Debug for Histogram<T>
where
T: fmt::Debug,
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_fmt(format_args!("Histogram<{}>", std::any::type_name::<T>()))
}
}
impl<T> Histogram<T> {
/// Create a new histogram.
pub fn new(inner: Arc<dyn SyncHistogram<T> + Send + Sync>) -> Self {
Histogram(inner)
}
/// Adds an additional value to the distribution.
pub fn record(&self, value: T, attributes: &[KeyValue]) {
self.0.record(value, attributes)
}
}
impl TryFrom<InstrumentBuilder<'_, Histogram<f64>>> for Histogram<f64> {
type Error = MetricsError;
fn try_from(builder: InstrumentBuilder<'_, Histogram<f64>>) -> Result<Self, Self::Error> {
builder.meter.instrument_provider.f64_histogram(
builder.name,
builder.description,
builder.unit,
)
}
}
impl TryFrom<InstrumentBuilder<'_, Histogram<u64>>> for Histogram<u64> {
type Error = MetricsError;
fn try_from(builder: InstrumentBuilder<'_, Histogram<u64>>) -> Result<Self, Self::Error> {
builder.meter.instrument_provider.u64_histogram(
builder.name,
builder.description,
builder.unit,
)
}
}
impl TryFrom<InstrumentBuilder<'_, Histogram<i64>>> for Histogram<i64> {
type Error = MetricsError;
fn try_from(builder: InstrumentBuilder<'_, Histogram<i64>>) -> Result<Self, Self::Error> {
builder.meter.instrument_provider.i64_histogram(
builder.name,
builder.description,
builder.unit,
)
}
}

View File

@ -1,342 +0,0 @@
use crate::metrics::{Meter, MetricsError, Result, Unit};
use crate::{global, KeyValue};
use core::fmt;
use std::any::Any;
use std::borrow::Cow;
use std::convert::TryFrom;
use std::marker;
use std::sync::Arc;
pub(super) mod counter;
pub(super) mod gauge;
pub(super) mod histogram;
pub(super) mod up_down_counter;
// instrument validation error strings
const INSTRUMENT_NAME_EMPTY: &str = "instrument name must be non-empty";
const INSTRUMENT_NAME_LENGTH: &str = "instrument name must be less than 64 characters";
const INSTRUMENT_NAME_INVALID_CHAR: &str =
"characters in instrument name must be ASCII and belong to the alphanumeric characters, '_', '.', and '-'";
const INSTRUMENT_NAME_FIRST_ALPHABETIC: &str =
"instrument name must start with an alphabetic character";
const INSTRUMENT_UNIT_LENGTH: &str = "instrument unit must be less than 64 characters";
const INSTRUMENT_UNIT_INVALID_CHAR: &str = "characters in instrument unit must be ASCII";
/// An SDK implemented instrument that records measurements via callback.
pub trait AsyncInstrument<T>: Send + Sync {
/// Observes the state of the instrument.
///
/// It is only valid to call this within a callback.
fn observe(&self, measurement: T, attributes: &[KeyValue]);
/// Used for SDKs to downcast instruments in callbacks.
fn as_any(&self) -> Arc<dyn Any>;
}
/// Configuration for building a sync instrument.
pub struct InstrumentBuilder<'a, T> {
meter: &'a Meter,
name: Cow<'static, str>,
description: Option<Cow<'static, str>>,
unit: Option<Unit>,
_marker: marker::PhantomData<T>,
}
impl<'a, T> InstrumentBuilder<'a, T>
where
T: TryFrom<Self, Error = MetricsError>,
{
/// Create a new instrument builder
pub(crate) fn new(meter: &'a Meter, name: Cow<'static, str>) -> Self {
InstrumentBuilder {
meter,
name,
description: None,
unit: None,
_marker: marker::PhantomData,
}
}
/// Set the description for this instrument
pub fn with_description<S: Into<Cow<'static, str>>>(mut self, description: S) -> Self {
self.description = Some(description.into());
self
}
/// Set the unit for this instrument.
///
/// Unit is case sensitive(`kb` is not the same as `kB`).
///
/// Unit must be:
/// - ASCII string
/// - No longer than 63 characters
pub fn with_unit(mut self, unit: Unit) -> Self {
self.unit = Some(unit);
self
}
/// Validate the instrument configuration and creates a new instrument.
pub fn try_init(self) -> Result<T> {
self.validate_instrument_config()
.map_err(MetricsError::InvalidInstrumentConfiguration)?;
T::try_from(self)
}
/// Creates a new instrument.
///
/// This method reports configuration errors but still returns the instrument.
///
/// # Panics
///
/// Panics if the instrument cannot be created. Use
/// [`try_init`](InstrumentBuilder::try_init) if you want to handle errors.
pub fn init(self) -> T {
if let Err(err) = self.validate_instrument_config() {
global::handle_error(MetricsError::InvalidInstrumentConfiguration(err));
}
T::try_from(self).unwrap()
}
fn validate_instrument_config(&self) -> std::result::Result<(), &'static str> {
// validate instrument name
if self.name.is_empty() {
return Err(INSTRUMENT_NAME_EMPTY);
}
if self.name.len() > 63 {
return Err(INSTRUMENT_NAME_LENGTH);
}
if self.name.starts_with(|c: char| !c.is_ascii_alphabetic()) {
return Err(INSTRUMENT_NAME_FIRST_ALPHABETIC);
}
if self
.name
.contains(|c: char| !c.is_ascii_alphanumeric() && c != '_' && c != '.' && c != '-')
{
return Err(INSTRUMENT_NAME_INVALID_CHAR);
}
// validate instrument unit
if let Some(unit) = &self.unit {
if unit.as_str().len() > 63 {
return Err(INSTRUMENT_UNIT_LENGTH);
}
if unit.as_str().contains(|c: char| !c.is_ascii()) {
return Err(INSTRUMENT_UNIT_INVALID_CHAR);
}
}
Ok(())
}
}
impl<T> fmt::Debug for InstrumentBuilder<'_, T> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("InstrumentBuilder")
.field("name", &self.name)
.field("description", &self.description)
.field("unit", &self.unit)
.field("kind", &std::any::type_name::<T>())
.finish()
}
}
/// A function registered with a [Meter] that makes observations for the
/// instruments it is registered with.
///
/// The async instrument parameter is used to record measurement observations
/// for these instruments.
///
/// The function needs to complete in a finite amount of time.
pub type Callback<T> = Box<dyn Fn(&dyn AsyncInstrument<T>) + Send + Sync>;
/// Configuration for building an async instrument.
pub struct AsyncInstrumentBuilder<'a, I, M>
where
I: AsyncInstrument<M>,
{
meter: &'a Meter,
name: Cow<'static, str>,
description: Option<Cow<'static, str>>,
unit: Option<Unit>,
_inst: marker::PhantomData<I>,
callbacks: Vec<Callback<M>>,
}
impl<'a, I, M> AsyncInstrumentBuilder<'a, I, M>
where
I: TryFrom<Self, Error = MetricsError>,
I: AsyncInstrument<M>,
{
/// Create a new instrument builder
pub(crate) fn new(meter: &'a Meter, name: Cow<'static, str>) -> Self {
AsyncInstrumentBuilder {
meter,
name,
description: None,
unit: None,
_inst: marker::PhantomData,
callbacks: Vec::new(),
}
}
/// Set the description for this instrument
pub fn with_description<S: Into<Cow<'static, str>>>(mut self, description: S) -> Self {
self.description = Some(description.into());
self
}
/// Set the unit for this instrument.
///
/// Unit is case sensitive(`kb` is not the same as `kB`).
///
/// Unit must be:
/// - ASCII string
/// - No longer than 63 characters
pub fn with_unit(mut self, unit: Unit) -> Self {
self.unit = Some(unit);
self
}
/// Set the callback to be called for this instrument.
pub fn with_callback<F>(mut self, callback: F) -> Self
where
F: Fn(&dyn AsyncInstrument<M>) + Send + Sync + 'static,
{
self.callbacks.push(Box::new(callback));
self
}
/// Validate the instrument configuration and creates a new instrument.
pub fn try_init(self) -> Result<I> {
self.validate_instrument_config()
.map_err(MetricsError::InvalidInstrumentConfiguration)?;
I::try_from(self)
}
/// Creates a new instrument.
///
/// This method reports configuration errors but still returns the instrument.
///
/// # Panics
///
/// Panics if the instrument cannot be created. Use
/// [`try_init`](InstrumentBuilder::try_init) if you want to handle errors.
pub fn init(self) -> I {
if let Err(err) = self.validate_instrument_config() {
global::handle_error(MetricsError::InvalidInstrumentConfiguration(err));
}
I::try_from(self).unwrap()
}
fn validate_instrument_config(&self) -> std::result::Result<(), &'static str> {
// validate instrument name
if self.name.is_empty() {
return Err(INSTRUMENT_NAME_EMPTY);
}
if self.name.len() > 63 {
return Err(INSTRUMENT_NAME_LENGTH);
}
if self.name.starts_with(|c: char| !c.is_ascii_alphabetic()) {
return Err(INSTRUMENT_NAME_FIRST_ALPHABETIC);
}
if self
.name
.contains(|c: char| !c.is_ascii_alphanumeric() && c != '_' && c != '.' && c != '-')
{
return Err(INSTRUMENT_NAME_INVALID_CHAR);
}
// validate instrument unit
if let Some(unit) = &self.unit {
if unit.as_str().len() > 63 {
return Err(INSTRUMENT_UNIT_LENGTH);
}
if unit.as_str().contains(|c: char| !c.is_ascii()) {
return Err(INSTRUMENT_UNIT_INVALID_CHAR);
}
}
Ok(())
}
}
impl<I, M> fmt::Debug for AsyncInstrumentBuilder<'_, I, M>
where
I: AsyncInstrument<M>,
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("InstrumentBuilder")
.field("name", &self.name)
.field("description", &self.description)
.field("unit", &self.unit)
.field("kind", &std::any::type_name::<I>())
.field("callbacks_len", &self.callbacks.len())
.finish()
}
}
#[cfg(test)]
mod tests {
use crate::metrics::instruments::{
INSTRUMENT_NAME_FIRST_ALPHABETIC, INSTRUMENT_NAME_INVALID_CHAR, INSTRUMENT_NAME_LENGTH,
INSTRUMENT_UNIT_INVALID_CHAR, INSTRUMENT_UNIT_LENGTH,
};
use crate::metrics::noop::NoopMeterCore;
use crate::metrics::{Counter, InstrumentBuilder, Unit};
use std::sync::Arc;
#[test]
fn test_instrument_config_validation() {
let meter = crate::metrics::Meter::new(Arc::new(NoopMeterCore::new()));
// (name, expected error)
let instrument_name_test_cases = vec![
("validateName", ""),
("_startWithNoneAlphabet", INSTRUMENT_NAME_FIRST_ALPHABETIC),
("utf8char锈", INSTRUMENT_NAME_INVALID_CHAR),
(
"a12345678901234567890123456789012345678901234567890123456789012",
"",
),
(
"a123456789012345678901234567890123456789012345678901234567890123",
INSTRUMENT_NAME_LENGTH,
),
("invalid name", INSTRUMENT_NAME_INVALID_CHAR),
];
for (name, expected_error) in instrument_name_test_cases {
let builder: InstrumentBuilder<'_, Counter<u64>> =
InstrumentBuilder::new(&meter, name.into());
if expected_error.is_empty() {
assert!(builder.validate_instrument_config().is_ok());
} else {
assert_eq!(
builder.validate_instrument_config().unwrap_err(),
expected_error
);
}
}
// (unit, expected error)
let instrument_unit_test_cases = vec![
(
"0123456789012345678901234567890123456789012345678901234567890123",
INSTRUMENT_UNIT_LENGTH,
),
("utf8char锈", INSTRUMENT_UNIT_INVALID_CHAR),
("kb", ""),
];
for (unit, expected_error) in instrument_unit_test_cases {
let builder: InstrumentBuilder<'_, Counter<u64>> =
InstrumentBuilder::new(&meter, "test".into()).with_unit(Unit::new(unit));
if expected_error.is_empty() {
assert!(builder.validate_instrument_config().is_ok());
} else {
assert_eq!(
builder.validate_instrument_config().unwrap_err(),
expected_error
);
}
}
}
}

View File

@ -1,154 +0,0 @@
use crate::{
metrics::{InstrumentBuilder, MetricsError},
KeyValue,
};
use core::fmt;
use std::sync::Arc;
use std::{any::Any, convert::TryFrom};
use super::{AsyncInstrument, AsyncInstrumentBuilder};
/// An SDK implemented instrument that records increasing or decreasing values.
pub trait SyncUpDownCounter<T> {
/// Records an increment or decrement to the counter.
fn add(&self, value: T, attributes: &[KeyValue]);
}
/// An instrument that records increasing or decreasing values.
#[derive(Clone)]
pub struct UpDownCounter<T>(Arc<dyn SyncUpDownCounter<T> + Send + Sync>);
impl<T> fmt::Debug for UpDownCounter<T>
where
T: fmt::Debug,
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_fmt(format_args!(
"UpDownCounter<{}>",
std::any::type_name::<T>()
))
}
}
impl<T> UpDownCounter<T> {
/// Create a new up down counter.
pub fn new(inner: Arc<dyn SyncUpDownCounter<T> + Send + Sync>) -> Self {
UpDownCounter(inner)
}
/// Records an increment or decrement to the counter.
pub fn add(&self, value: T, attributes: &[KeyValue]) {
self.0.add(value, attributes)
}
}
impl TryFrom<InstrumentBuilder<'_, UpDownCounter<i64>>> for UpDownCounter<i64> {
type Error = MetricsError;
fn try_from(builder: InstrumentBuilder<'_, UpDownCounter<i64>>) -> Result<Self, Self::Error> {
builder.meter.instrument_provider.i64_up_down_counter(
builder.name,
builder.description,
builder.unit,
)
}
}
impl TryFrom<InstrumentBuilder<'_, UpDownCounter<f64>>> for UpDownCounter<f64> {
type Error = MetricsError;
fn try_from(builder: InstrumentBuilder<'_, UpDownCounter<f64>>) -> Result<Self, Self::Error> {
builder.meter.instrument_provider.f64_up_down_counter(
builder.name,
builder.description,
builder.unit,
)
}
}
/// An async instrument that records increasing or decreasing values.
#[derive(Clone)]
pub struct ObservableUpDownCounter<T>(Arc<dyn AsyncInstrument<T>>);
impl<T> fmt::Debug for ObservableUpDownCounter<T>
where
T: fmt::Debug,
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_fmt(format_args!(
"ObservableUpDownCounter<{}>",
std::any::type_name::<T>()
))
}
}
impl<T> ObservableUpDownCounter<T> {
/// Create a new observable up down counter.
pub fn new(inner: Arc<dyn AsyncInstrument<T>>) -> Self {
ObservableUpDownCounter(inner)
}
/// Records the increment or decrement to the counter.
///
/// It is only valid to call this within a callback. If called outside of the
/// registered callback it should have no effect on the instrument, and an
/// error will be reported via the error handler.
pub fn observe(&self, value: T, attributes: &[KeyValue]) {
self.0.observe(value, attributes)
}
/// Used for SDKs to downcast instruments in callbacks.
pub fn as_any(&self) -> Arc<dyn Any> {
self.0.as_any()
}
}
impl<T> AsyncInstrument<T> for ObservableUpDownCounter<T> {
fn observe(&self, measurement: T, attributes: &[KeyValue]) {
self.0.observe(measurement, attributes)
}
fn as_any(&self) -> Arc<dyn std::any::Any> {
self.0.as_any()
}
}
impl TryFrom<AsyncInstrumentBuilder<'_, ObservableUpDownCounter<i64>, i64>>
for ObservableUpDownCounter<i64>
{
type Error = MetricsError;
fn try_from(
builder: AsyncInstrumentBuilder<'_, ObservableUpDownCounter<i64>, i64>,
) -> Result<Self, Self::Error> {
builder
.meter
.instrument_provider
.i64_observable_up_down_counter(
builder.name,
builder.description,
builder.unit,
builder.callbacks,
)
}
}
impl TryFrom<AsyncInstrumentBuilder<'_, ObservableUpDownCounter<f64>, f64>>
for ObservableUpDownCounter<f64>
{
type Error = MetricsError;
fn try_from(
builder: AsyncInstrumentBuilder<'_, ObservableUpDownCounter<f64>, f64>,
) -> Result<Self, Self::Error> {
builder
.meter
.instrument_provider
.f64_observable_up_down_counter(
builder.name,
builder.description,
builder.unit,
builder.callbacks,
)
}
}

View File

@ -1,219 +0,0 @@
use core::fmt;
use std::any::Any;
use std::borrow::Cow;
use std::sync::Arc;
use crate::metrics::{
AsyncInstrumentBuilder, Counter, Histogram, InstrumentBuilder, InstrumentProvider,
ObservableCounter, ObservableGauge, ObservableUpDownCounter, Result, UpDownCounter,
};
use crate::KeyValue;
use super::AsyncInstrument;
/// Provides access to named [Meter] instances, for instrumenting an application
/// or crate.
pub trait MeterProvider {
/// Returns a new [Meter] with the provided name and default configuration.
///
/// A [Meter] should be scoped at most to a single application or crate. The
/// name needs to be unique so it does not collide with other names used by
/// an application, nor other applications.
///
/// If the name is empty, then an implementation defined default name will
/// be used instead.
fn meter(&self, name: impl Into<Cow<'static, str>>) -> Meter {
self.versioned_meter(
name,
None::<Cow<'static, str>>,
None::<Cow<'static, str>>,
None,
)
}
/// Creates an implementation of the [`Meter`] interface.
///
/// The instrumentation name must be the name of the library providing instrumentation. This
/// name may be the same as the instrumented code only if that code provides built-in
/// instrumentation. If the instrumentation name is empty, then a implementation defined
/// default name will be used instead.
fn versioned_meter(
&self,
name: impl Into<Cow<'static, str>>,
version: Option<impl Into<Cow<'static, str>>>,
schema_url: Option<impl Into<Cow<'static, str>>>,
attributes: Option<Vec<KeyValue>>,
) -> Meter;
}
/// Provides access to instrument instances for recording metrics.
#[derive(Clone)]
pub struct Meter {
pub(crate) instrument_provider: Arc<dyn InstrumentProvider + Send + Sync>,
}
impl Meter {
/// Create a new named meter from an instrumentation provider
#[doc(hidden)]
pub fn new(instrument_provider: Arc<dyn InstrumentProvider + Send + Sync>) -> Self {
Meter {
instrument_provider,
}
}
/// creates an instrument builder for recording increasing values.
pub fn u64_counter(
&self,
name: impl Into<Cow<'static, str>>,
) -> InstrumentBuilder<'_, Counter<u64>> {
InstrumentBuilder::new(self, name.into())
}
/// creates an instrument builder for recording increasing values.
pub fn f64_counter(
&self,
name: impl Into<Cow<'static, str>>,
) -> InstrumentBuilder<'_, Counter<f64>> {
InstrumentBuilder::new(self, name.into())
}
/// creates an instrument builder for recording increasing values via callback.
pub fn u64_observable_counter(
&self,
name: impl Into<Cow<'static, str>>,
) -> AsyncInstrumentBuilder<'_, ObservableCounter<u64>, u64> {
AsyncInstrumentBuilder::new(self, name.into())
}
/// creates an instrument builder for recording increasing values via callback.
pub fn f64_observable_counter(
&self,
name: impl Into<Cow<'static, str>>,
) -> AsyncInstrumentBuilder<'_, ObservableCounter<f64>, f64> {
AsyncInstrumentBuilder::new(self, name.into())
}
/// creates an instrument builder for recording changes of a value.
pub fn i64_up_down_counter(
&self,
name: impl Into<Cow<'static, str>>,
) -> InstrumentBuilder<'_, UpDownCounter<i64>> {
InstrumentBuilder::new(self, name.into())
}
/// creates an instrument builder for recording changes of a value.
pub fn f64_up_down_counter(
&self,
name: impl Into<Cow<'static, str>>,
) -> InstrumentBuilder<'_, UpDownCounter<f64>> {
InstrumentBuilder::new(self, name.into())
}
/// creates an instrument builder for recording changes of a value via callback.
pub fn i64_observable_up_down_counter(
&self,
name: impl Into<Cow<'static, str>>,
) -> AsyncInstrumentBuilder<'_, ObservableUpDownCounter<i64>, i64> {
AsyncInstrumentBuilder::new(self, name.into())
}
/// creates an instrument builder for recording changes of a value via callback.
pub fn f64_observable_up_down_counter(
&self,
name: impl Into<Cow<'static, str>>,
) -> AsyncInstrumentBuilder<'_, ObservableUpDownCounter<f64>, f64> {
AsyncInstrumentBuilder::new(self, name.into())
}
/// creates an instrument builder for recording the current value via callback.
pub fn u64_observable_gauge(
&self,
name: impl Into<Cow<'static, str>>,
) -> AsyncInstrumentBuilder<'_, ObservableGauge<u64>, u64> {
AsyncInstrumentBuilder::new(self, name.into())
}
/// creates an instrument builder for recording the current value via callback.
pub fn i64_observable_gauge(
&self,
name: impl Into<Cow<'static, str>>,
) -> AsyncInstrumentBuilder<'_, ObservableGauge<i64>, i64> {
AsyncInstrumentBuilder::new(self, name.into())
}
/// creates an instrument builder for recording the current value via callback.
pub fn f64_observable_gauge(
&self,
name: impl Into<Cow<'static, str>>,
) -> AsyncInstrumentBuilder<'_, ObservableGauge<f64>, f64> {
AsyncInstrumentBuilder::new(self, name.into())
}
/// creates an instrument builder for recording a distribution of values.
pub fn f64_histogram(
&self,
name: impl Into<Cow<'static, str>>,
) -> InstrumentBuilder<'_, Histogram<f64>> {
InstrumentBuilder::new(self, name.into())
}
/// creates an instrument builder for recording a distribution of values.
pub fn u64_histogram(
&self,
name: impl Into<Cow<'static, str>>,
) -> InstrumentBuilder<'_, Histogram<u64>> {
InstrumentBuilder::new(self, name.into())
}
/// creates an instrument builder for recording a distribution of values.
pub fn i64_histogram(
&self,
name: impl Into<Cow<'static, str>>,
) -> InstrumentBuilder<'_, Histogram<i64>> {
InstrumentBuilder::new(self, name.into())
}
/// Registers a callback to be called during the collection of a measurement
/// cycle.
///
/// The instruments passed as arguments to be registered are the only
/// instruments that may observe values.
///
/// If no instruments are passed, the callback will not be registered.
pub fn register_callback<F>(
&self,
instruments: &[Arc<dyn Any>],
callback: F,
) -> Result<Box<dyn CallbackRegistration>>
where
F: Fn(&dyn Observer) + Send + Sync + 'static,
{
self.instrument_provider
.register_callback(instruments, Box::new(callback))
}
}
/// A token representing the unique registration of a callback for a set of
/// instruments with a [Meter].
pub trait CallbackRegistration: Send + Sync {
/// Removes the callback registration from its associated [Meter].
fn unregister(&mut self) -> Result<()>;
}
/// Records measurements for multiple instruments in a callback.
pub trait Observer {
/// Records the f64 value with attributes for the observable.
fn observe_f64(&self, inst: &dyn AsyncInstrument<f64>, measurement: f64, attrs: &[KeyValue]);
/// Records the u64 value with attributes for the observable.
fn observe_u64(&self, inst: &dyn AsyncInstrument<u64>, measurement: u64, attrs: &[KeyValue]);
/// Records the i64 value with attributes for the observable.
fn observe_i64(&self, inst: &dyn AsyncInstrument<i64>, measurement: i64, attrs: &[KeyValue]);
}
impl fmt::Debug for Meter {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_str("Meter")
}
}

View File

@ -1,261 +0,0 @@
//! # OpenTelemetry Metrics API
use std::any::Any;
use std::result;
use std::sync::PoisonError;
use std::{borrow::Cow, sync::Arc};
use thiserror::Error;
mod instruments;
mod meter;
pub mod noop;
use crate::ExportError;
pub use instruments::{
counter::{Counter, ObservableCounter, SyncCounter},
gauge::ObservableGauge,
histogram::{Histogram, SyncHistogram},
up_down_counter::{ObservableUpDownCounter, SyncUpDownCounter, UpDownCounter},
AsyncInstrument, AsyncInstrumentBuilder, Callback, InstrumentBuilder,
};
pub use meter::{CallbackRegistration, Meter, MeterProvider, Observer};
/// A specialized `Result` type for metric operations.
pub type Result<T> = result::Result<T, MetricsError>;
/// Errors returned by the metrics API.
#[derive(Error, Debug)]
#[non_exhaustive]
pub enum MetricsError {
/// Other errors not covered by specific cases.
#[error("Metrics error: {0}")]
Other(String),
/// Invalid configuration
#[error("Config error {0}")]
Config(String),
/// Fail to export metrics
#[error("Metrics exporter {} failed with {0}", .0.exporter_name())]
ExportErr(Box<dyn ExportError>),
/// Invalid instrument configuration such invalid instrument name, invalid instrument description, invalid instrument unit, etc.
/// See [spec](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/api.md#general-characteristics)
/// for full list of requirements.
#[error("Invalid instrument configuration: {0}")]
InvalidInstrumentConfiguration(&'static str),
}
impl<T: ExportError> From<T> for MetricsError {
fn from(err: T) -> Self {
MetricsError::ExportErr(Box::new(err))
}
}
impl<T> From<PoisonError<T>> for MetricsError {
fn from(err: PoisonError<T>) -> Self {
MetricsError::Other(err.to_string())
}
}
/// Units denote underlying data units tracked by `Meter`s.
#[derive(Clone, Default, Debug, PartialEq, Eq, Hash)]
pub struct Unit(Cow<'static, str>);
impl Unit {
/// Create a new `Unit` from an `Into<String>`
pub fn new<S>(value: S) -> Self
where
S: Into<Cow<'static, str>>,
{
Unit(value.into())
}
/// View unit as &str
pub fn as_str(&self) -> &str {
self.0.as_ref()
}
}
impl AsRef<str> for Unit {
#[inline]
fn as_ref(&self) -> &str {
self.0.as_ref()
}
}
/// SDK implemented trait for creating instruments
pub trait InstrumentProvider {
/// creates an instrument for recording increasing values.
fn u64_counter(
&self,
_name: Cow<'static, str>,
_description: Option<Cow<'static, str>>,
_unit: Option<Unit>,
) -> Result<Counter<u64>> {
Ok(Counter::new(Arc::new(noop::NoopSyncInstrument::new())))
}
/// creates an instrument for recording increasing values.
fn f64_counter(
&self,
_name: Cow<'static, str>,
_description: Option<Cow<'static, str>>,
_unit: Option<Unit>,
) -> Result<Counter<f64>> {
Ok(Counter::new(Arc::new(noop::NoopSyncInstrument::new())))
}
/// creates an instrument for recording increasing values via callback.
fn u64_observable_counter(
&self,
_name: Cow<'static, str>,
_description: Option<Cow<'static, str>>,
_unit: Option<Unit>,
_callback: Vec<Callback<u64>>,
) -> Result<ObservableCounter<u64>> {
Ok(ObservableCounter::new(Arc::new(
noop::NoopAsyncInstrument::new(),
)))
}
/// creates an instrument for recording increasing values via callback.
fn f64_observable_counter(
&self,
_name: Cow<'static, str>,
_description: Option<Cow<'static, str>>,
_unit: Option<Unit>,
_callback: Vec<Callback<f64>>,
) -> Result<ObservableCounter<f64>> {
Ok(ObservableCounter::new(Arc::new(
noop::NoopAsyncInstrument::new(),
)))
}
/// creates an instrument for recording changes of a value.
fn i64_up_down_counter(
&self,
_name: Cow<'static, str>,
_description: Option<Cow<'static, str>>,
_unit: Option<Unit>,
) -> Result<UpDownCounter<i64>> {
Ok(UpDownCounter::new(
Arc::new(noop::NoopSyncInstrument::new()),
))
}
/// creates an instrument for recording changes of a value.
fn f64_up_down_counter(
&self,
_name: Cow<'static, str>,
_description: Option<Cow<'static, str>>,
_unit: Option<Unit>,
) -> Result<UpDownCounter<f64>> {
Ok(UpDownCounter::new(
Arc::new(noop::NoopSyncInstrument::new()),
))
}
/// creates an instrument for recording changes of a value.
fn i64_observable_up_down_counter(
&self,
_name: Cow<'static, str>,
_description: Option<Cow<'static, str>>,
_unit: Option<Unit>,
_callback: Vec<Callback<i64>>,
) -> Result<ObservableUpDownCounter<i64>> {
Ok(ObservableUpDownCounter::new(Arc::new(
noop::NoopAsyncInstrument::new(),
)))
}
/// creates an instrument for recording changes of a value via callback.
fn f64_observable_up_down_counter(
&self,
_name: Cow<'static, str>,
_description: Option<Cow<'static, str>>,
_unit: Option<Unit>,
_callback: Vec<Callback<f64>>,
) -> Result<ObservableUpDownCounter<f64>> {
Ok(ObservableUpDownCounter::new(Arc::new(
noop::NoopAsyncInstrument::new(),
)))
}
/// creates an instrument for recording the current value via callback.
fn u64_observable_gauge(
&self,
_name: Cow<'static, str>,
_description: Option<Cow<'static, str>>,
_unit: Option<Unit>,
_callback: Vec<Callback<u64>>,
) -> Result<ObservableGauge<u64>> {
Ok(ObservableGauge::new(Arc::new(
noop::NoopAsyncInstrument::new(),
)))
}
/// creates an instrument for recording the current value via callback.
fn i64_observable_gauge(
&self,
_name: Cow<'static, str>,
_description: Option<Cow<'static, str>>,
_unit: Option<Unit>,
_callback: Vec<Callback<i64>>,
) -> Result<ObservableGauge<i64>> {
Ok(ObservableGauge::new(Arc::new(
noop::NoopAsyncInstrument::new(),
)))
}
/// creates an instrument for recording the current value via callback.
fn f64_observable_gauge(
&self,
_name: Cow<'static, str>,
_description: Option<Cow<'static, str>>,
_unit: Option<Unit>,
_callback: Vec<Callback<f64>>,
) -> Result<ObservableGauge<f64>> {
Ok(ObservableGauge::new(Arc::new(
noop::NoopAsyncInstrument::new(),
)))
}
/// creates an instrument for recording a distribution of values.
fn f64_histogram(
&self,
_name: Cow<'static, str>,
_description: Option<Cow<'static, str>>,
_unit: Option<Unit>,
) -> Result<Histogram<f64>> {
Ok(Histogram::new(Arc::new(noop::NoopSyncInstrument::new())))
}
/// creates an instrument for recording a distribution of values.
fn u64_histogram(
&self,
_name: Cow<'static, str>,
_description: Option<Cow<'static, str>>,
_unit: Option<Unit>,
) -> Result<Histogram<u64>> {
Ok(Histogram::new(Arc::new(noop::NoopSyncInstrument::new())))
}
/// creates an instrument for recording a distribution of values.
fn i64_histogram(
&self,
_name: Cow<'static, str>,
_description: Option<Cow<'static, str>>,
_unit: Option<Unit>,
) -> Result<Histogram<i64>> {
Ok(Histogram::new(Arc::new(noop::NoopSyncInstrument::new())))
}
/// Captures the function that will be called during data collection.
///
/// It is only valid to call `observe` within the scope of the passed function.
fn register_callback(
&self,
instruments: &[Arc<dyn Any>],
callbacks: Box<MultiInstrumentCallback>,
) -> Result<Box<dyn CallbackRegistration>>;
}
type MultiInstrumentCallback = dyn Fn(&dyn Observer) + Send + Sync;

View File

@ -1,134 +0,0 @@
//! # No-op OpenTelemetry Metrics Implementation
//!
//! This implementation is returned as the global Meter if no `Meter`
//! has been set. It is also useful for testing purposes as it is intended
//! to have minimal resource utilization and runtime impact.
use crate::{
metrics::{
AsyncInstrument, CallbackRegistration, InstrumentProvider, Meter, MeterProvider, Observer,
Result, SyncCounter, SyncHistogram, SyncUpDownCounter,
},
KeyValue,
};
use std::{any::Any, borrow::Cow, sync::Arc};
/// A no-op instance of a `MetricProvider`
#[derive(Debug, Default)]
pub struct NoopMeterProvider {
_private: (),
}
impl NoopMeterProvider {
/// Create a new no-op meter provider.
pub fn new() -> Self {
NoopMeterProvider { _private: () }
}
}
impl MeterProvider for NoopMeterProvider {
fn versioned_meter(
&self,
_name: impl Into<Cow<'static, str>>,
_version: Option<impl Into<Cow<'static, str>>>,
_schema_url: Option<impl Into<Cow<'static, str>>>,
_attributes: Option<Vec<KeyValue>>,
) -> Meter {
Meter::new(Arc::new(NoopMeterCore::new()))
}
}
/// A no-op instance of a `Meter`
#[derive(Debug, Default)]
pub struct NoopMeterCore {
_private: (),
}
impl NoopMeterCore {
/// Create a new no-op meter core.
pub fn new() -> Self {
NoopMeterCore { _private: () }
}
}
impl InstrumentProvider for NoopMeterCore {
fn register_callback(
&self,
_instruments: &[Arc<dyn Any>],
_callback: Box<dyn Fn(&dyn Observer) + Send + Sync>,
) -> Result<Box<dyn CallbackRegistration>> {
Ok(Box::new(NoopRegistration::new()))
}
}
/// A no-op instance of a callback [CallbackRegistration].
#[derive(Debug, Default)]
pub struct NoopRegistration {
_private: (),
}
impl NoopRegistration {
/// Create a new no-op registration.
pub fn new() -> Self {
NoopRegistration { _private: () }
}
}
impl CallbackRegistration for NoopRegistration {
fn unregister(&mut self) -> Result<()> {
Ok(())
}
}
/// A no-op sync instrument
#[derive(Debug, Default)]
pub struct NoopSyncInstrument {
_private: (),
}
impl NoopSyncInstrument {
/// Create a new no-op sync instrument
pub fn new() -> Self {
NoopSyncInstrument { _private: () }
}
}
impl<T> SyncCounter<T> for NoopSyncInstrument {
fn add(&self, _value: T, _attributes: &[KeyValue]) {
// Ignored
}
}
impl<T> SyncUpDownCounter<T> for NoopSyncInstrument {
fn add(&self, _value: T, _attributes: &[KeyValue]) {
// Ignored
}
}
impl<T> SyncHistogram<T> for NoopSyncInstrument {
fn record(&self, _value: T, _attributes: &[KeyValue]) {
// Ignored
}
}
/// A no-op async instrument.
#[derive(Debug, Default)]
pub struct NoopAsyncInstrument {
_private: (),
}
impl NoopAsyncInstrument {
/// Create a new no-op async instrument
pub fn new() -> Self {
NoopAsyncInstrument { _private: () }
}
}
impl<T> AsyncInstrument<T> for NoopAsyncInstrument {
fn observe(&self, _value: T, _attributes: &[KeyValue]) {
// Ignored
}
fn as_any(&self) -> Arc<dyn Any> {
Arc::new(())
}
}

View File

@ -1,670 +0,0 @@
use crate::{Key, KeyValue, Value};
use indexmap::map::{
Drain, Entry, IntoIter, IntoKeys, IntoValues, Iter, IterMut, Keys, Values, ValuesMut,
};
use indexmap::{Equivalent, IndexMap};
use std::collections::hash_map::RandomState;
use std::hash::{BuildHasher, Hash};
use std::iter::FromIterator;
use std::ops::{Index, IndexMut, RangeBounds};
/// A hash table implementation that preserves insertion order across all operations.
///
/// Entries will be returned according to their insertion order when iterating over the collection.
#[derive(Clone, Debug)]
pub struct OrderMap<K, V, S = RandomState>(IndexMap<K, V, S>);
impl<K, V> OrderMap<K, V> {
/// Create a new map. (Does not allocate)
#[inline]
pub fn new() -> Self {
Self(IndexMap::new())
}
/// Create a new map with capacity for `n` key-value pairs. (Does not
/// allocate if `n` is zero.)
///
/// Computes in **O(n)** time.
#[inline]
pub fn with_capacity(n: usize) -> Self {
Self(IndexMap::with_capacity(n))
}
}
impl<K, V, S> OrderMap<K, V, S> {
/// Create a new map with capacity for `n` key-value pairs. (Does not
/// allocate if `n` is zero.)
///
/// Computes in **O(n)** time.
#[inline]
pub fn with_capacity_and_hasher(n: usize, hash_builder: S) -> Self {
Self(IndexMap::with_capacity_and_hasher(n, hash_builder))
}
/// Create a new map with `hash_builder`.
///
/// This function is `const`, so it
/// can be called in `static` contexts.
pub const fn with_hasher(hash_builder: S) -> Self {
Self(IndexMap::with_hasher(hash_builder))
}
/// Computes in **O(1)** time.
pub fn capacity(&self) -> usize {
self.0.capacity()
}
/// Return a reference to the map's `BuildHasher`.
pub fn hasher(&self) -> &S {
self.0.hasher()
}
/// Return the number of key-value pairs in the map.
///
/// Computes in **O(1)** time.
#[inline]
pub fn len(&self) -> usize {
self.0.len()
}
/// Returns true if the map contains no elements.
///
/// Computes in **O(1)** time.
#[inline]
pub fn is_empty(&self) -> bool {
self.0.is_empty()
}
/// Return an iterator over the key-value pairs of the map, in their order
pub fn iter(&self) -> Iter<'_, K, V> {
self.0.iter()
}
/// Return an iterator over the key-value pairs of the map, in their order
pub fn iter_mut(&mut self) -> IterMut<'_, K, V> {
self.0.iter_mut()
}
/// Return an iterator over the keys of the map, in their order
pub fn keys(&self) -> Keys<'_, K, V> {
self.0.keys()
}
/// Return an owning iterator over the keys of the map, in their order
pub fn into_keys(self) -> IntoKeys<K, V> {
self.0.into_keys()
}
/// Return an iterator over the values of the map, in their order
pub fn values(&self) -> Values<'_, K, V> {
self.0.values()
}
/// Return an iterator over mutable references to the values of the map,
/// in their order
pub fn values_mut(&mut self) -> ValuesMut<'_, K, V> {
self.0.values_mut()
}
/// Return an owning iterator over the values of the map, in their order
pub fn into_values(self) -> IntoValues<K, V> {
self.0.into_values()
}
/// Remove all key-value pairs in the map, while preserving its capacity.
///
/// Computes in **O(n)** time.
pub fn clear(&mut self) {
self.0.clear();
}
/// Shortens the map, keeping the first `len` elements and dropping the rest.
///
/// If `len` is greater than the map's current length, this has no effect.
pub fn truncate(&mut self, len: usize) {
self.0.truncate(len);
}
/// Clears the `IndexMap` in the given index range, returning those
/// key-value pairs as a drain iterator.
///
/// The range may be any type that implements `RangeBounds<usize>`,
/// including all of the `std::ops::Range*` types, or even a tuple pair of
/// `Bound` start and end values. To drain the map entirely, use `RangeFull`
/// like `map.drain(..)`.
///
/// This shifts down all entries following the drained range to fill the
/// gap, and keeps the allocated memory for reuse.
///
/// ***Panics*** if the starting point is greater than the end point or if
/// the end point is greater than the length of the map.
pub fn drain<R>(&mut self, range: R) -> Drain<'_, K, V>
where
R: RangeBounds<usize>,
{
self.0.drain(range)
}
/// Splits the collection into two at the given index.
///
/// Returns a newly allocated map containing the elements in the range
/// `[at, len)`. After the call, the original map will be left containing
/// the elements `[0, at)` with its previous capacity unchanged.
///
/// ***Panics*** if `at > len`.
pub fn split_off(&mut self, at: usize) -> Self
where
S: Clone,
{
Self(self.0.split_off(at))
}
}
impl<K, V, S> OrderMap<K, V, S>
where
K: Hash + Eq,
S: BuildHasher,
{
/// Reserve capacity for `additional` more key-value pairs.
///
/// Computes in **O(n)** time.
pub fn reserve(&mut self, additional: usize) {
self.0.reserve(additional)
}
/// Shrink the capacity of the map as much as possible.
///
/// Computes in **O(n)** time.
pub fn shrink_to_fit(&mut self) {
self.0.shrink_to_fit()
}
/// Insert a key-value pair in the map.
///
/// If an equivalent key already exists in the map: the key remains and
/// retains in its place in the order, its corresponding value is updated
/// with `value` and the older value is returned inside `Some(_)`.
///
/// If no equivalent key existed in the map: the new key-value pair is
/// inserted, last in order, and `None` is returned.
///
/// Computes in **O(1)** time (amortized average).
///
/// See also [`entry`](#method.entry) if you you want to insert *or* modify
/// or if you need to get the index of the corresponding key-value pair.
pub fn insert(&mut self, key: K, value: V) -> Option<V> {
self.0.insert(key, value)
}
/// Insert a key-value pair in the map, and get their index.
///
/// If an equivalent key already exists in the map: the key remains and
/// retains in its place in the order, its corresponding value is updated
/// with `value` and the older value is returned inside `(index, Some(_))`.
///
/// If no equivalent key existed in the map: the new key-value pair is
/// inserted, last in order, and `(index, None)` is returned.
///
/// Computes in **O(1)** time (amortized average).
///
/// See also [`entry`](#method.entry) if you you want to insert *or* modify
/// or if you need to get the index of the corresponding key-value pair.
pub fn insert_full(&mut self, key: K, value: V) -> (usize, Option<V>) {
self.0.insert_full(key, value)
}
/// Get the given keys corresponding entry in the map for insertion and/or
/// in-place manipulation.
///
/// Computes in **O(1)** time (amortized average).
pub fn entry(&mut self, key: K) -> Entry<'_, K, V> {
self.0.entry(key)
}
/// Return `true` if an equivalent to `key` exists in the map.
///
/// Computes in **O(1)** time (average).
pub fn contains_key<Q: ?Sized>(&self, key: &Q) -> bool
where
Q: Hash + Equivalent<K>,
{
self.0.contains_key(key)
}
/// Return a reference to the value stored for `key`, if it is present,
/// else `None`.
///
/// Computes in **O(1)** time (average).
pub fn get<Q: ?Sized>(&self, key: &Q) -> Option<&V>
where
Q: Hash + Equivalent<K>,
{
self.0.get(key)
}
/// Return references to the key-value pair stored for `key`,
/// if it is present, else `None`.
///
/// Computes in **O(1)** time (average).
pub fn get_key_value<Q: ?Sized>(&self, key: &Q) -> Option<(&K, &V)>
where
Q: Hash + Equivalent<K>,
{
self.0.get_key_value(key)
}
/// Return item index, key and value
pub fn get_full<Q: ?Sized>(&self, key: &Q) -> Option<(usize, &K, &V)>
where
Q: Hash + Equivalent<K>,
{
self.0.get_full(key)
}
/// Return item index, if it exists in the map
///
/// Computes in **O(1)** time (average).
pub fn get_index_of<Q: ?Sized>(&self, key: &Q) -> Option<usize>
where
Q: Hash + Equivalent<K>,
{
self.0.get_index_of(key)
}
/// Return a mutable reference to the element pointed at by `key`, if it exists.
pub fn get_mut<Q: ?Sized>(&mut self, key: &Q) -> Option<&mut V>
where
Q: Hash + Equivalent<K>,
{
self.0.get_mut(key)
}
/// Return a mutable reference to the element pointed at by `key`, if it exists.
/// It also returns the element's index and its key.
pub fn get_full_mut<Q: ?Sized>(&mut self, key: &Q) -> Option<(usize, &K, &mut V)>
where
Q: Hash + Equivalent<K>,
{
self.0.get_full_mut(key)
}
/// Remove the key-value pair equivalent to `key` and return
/// its value.
///
/// Like `Vec::remove`, the pair is removed by shifting all of the
/// elements that follow it, preserving their relative order.
/// **This perturbs the index of all of those elements!**
///
/// Return `None` if `key` is not in map.
///
/// Computes in **O(n)** time (average).
pub fn shift_remove<Q: ?Sized>(&mut self, key: &Q) -> Option<V>
where
Q: Hash + Equivalent<K>,
{
self.0.shift_remove(key)
}
/// Remove and return the key-value pair equivalent to `key`.
///
/// Like `Vec::remove`, the pair is removed by shifting all of the
/// elements that follow it, preserving their relative order.
/// **This perturbs the index of all of those elements!**
///
/// Return `None` if `key` is not in map.
///
/// Computes in **O(n)** time (average).
pub fn shift_remove_entry<Q: ?Sized>(&mut self, key: &Q) -> Option<(K, V)>
where
Q: Hash + Equivalent<K>,
{
self.0.shift_remove_entry(key)
}
/// Remove the key-value pair equivalent to `key` and return it and
/// the index it had.
///
/// Like `Vec::remove`, the pair is removed by shifting all of the
/// elements that follow it, preserving their relative order.
/// **This perturbs the index of all of those elements!**
///
/// Return `None` if `key` is not in map.
///
/// Computes in **O(n)** time (average).
pub fn shift_remove_full<Q: ?Sized>(&mut self, key: &Q) -> Option<(usize, K, V)>
where
Q: Hash + Equivalent<K>,
{
self.0.shift_remove_full(key)
}
/// Remove the last key-value pair
///
/// This preserves the order of the remaining elements.
///
/// Computes in **O(1)** time (average).
pub fn pop(&mut self) -> Option<(K, V)> {
self.0.pop()
}
/// Scan through each key-value pair in the map and keep those where the
/// closure `keep` returns `true`.
///
/// The elements are visited in order, and remaining elements keep their
/// order.
///
/// Computes in **O(n)** time (average).
pub fn retain<F>(&mut self, keep: F)
where
F: FnMut(&K, &mut V) -> bool,
{
self.0.retain(keep);
}
}
impl<K, V, S> OrderMap<K, V, S> {
/// Get a key-value pair by index
///
/// Valid indices are *0 <= index < self.len()*
///
/// Computes in **O(1)** time.
pub fn get_index(&self, index: usize) -> Option<(&K, &V)> {
self.0.get_index(index)
}
/// Get a key-value pair by index
///
/// Valid indices are *0 <= index < self.len()*
///
/// Computes in **O(1)** time.
pub fn get_index_mut(&mut self, index: usize) -> Option<(&mut K, &mut V)> {
self.0.get_index_mut(index)
}
/// Get the first key-value pair
///
/// Computes in **O(1)** time.
pub fn first(&self) -> Option<(&K, &V)> {
self.0.first()
}
/// Get the first key-value pair, with mutable access to the value
///
/// Computes in **O(1)** time.
pub fn first_mut(&mut self) -> Option<(&K, &mut V)> {
self.0.first_mut()
}
/// Get the last key-value pair
///
/// Computes in **O(1)** time.
pub fn last(&self) -> Option<(&K, &V)> {
self.0.last()
}
/// Get the last key-value pair, with mutable access to the value
///
/// Computes in **O(1)** time.
pub fn last_mut(&mut self) -> Option<(&K, &mut V)> {
self.0.last_mut()
}
/// Remove the key-value pair by index
///
/// Valid indices are *0 <= index < self.len()*
///
/// Like `Vec::remove`, the pair is removed by shifting all of the
/// elements that follow it, preserving their relative order.
/// **This perturbs the index of all of those elements!**
///
/// Computes in **O(n)** time (average).
pub fn shift_remove_index(&mut self, index: usize) -> Option<(K, V)> {
self.0.shift_remove_index(index)
}
}
impl<'a, K, V, S> IntoIterator for &'a OrderMap<K, V, S> {
type Item = (&'a K, &'a V);
type IntoIter = Iter<'a, K, V>;
fn into_iter(self) -> Self::IntoIter {
self.0.iter()
}
}
impl<'a, K, V, S> IntoIterator for &'a mut OrderMap<K, V, S> {
type Item = (&'a K, &'a mut V);
type IntoIter = IterMut<'a, K, V>;
fn into_iter(self) -> Self::IntoIter {
self.0.iter_mut()
}
}
impl<K, V, S> IntoIterator for OrderMap<K, V, S> {
type Item = (K, V);
type IntoIter = IntoIter<K, V>;
fn into_iter(self) -> Self::IntoIter {
self.0.into_iter()
}
}
/// Access `OrderMap` values corresponding to a key.
///
/// Panics if the value is missing.
impl<K, V, Q: ?Sized, S> Index<&Q> for OrderMap<K, V, S>
where
Q: Hash + Equivalent<K>,
K: Hash + Eq,
S: BuildHasher,
{
type Output = V;
/// Returns a reference to the value corresponding to the supplied `key`.
///
/// ***Panics*** if `key` is not present in the map.
fn index(&self, key: &Q) -> &V {
self.0.index(key)
}
}
/// Access `Ordermap` values corresponding to a key.
///
/// Mutable indexing allows changing / updating values of key-value
/// pairs that are already present.
///
/// You can **not** insert new pairs with index syntax, use `.insert()`.
impl<K, V, Q: ?Sized, S> IndexMut<&Q> for OrderMap<K, V, S>
where
Q: Hash + Equivalent<K>,
K: Hash + Eq,
S: BuildHasher,
{
/// Returns a mutable reference to the value corresponding to the supplied `key`.
///
/// ***Panics*** if `key` is not present in the map.
fn index_mut(&mut self, key: &Q) -> &mut V {
self.0.index_mut(key)
}
}
/// Access `IndexMap` values at indexed positions.
///
/// It panics if the index is out of bounds.
impl<K, V, S> Index<usize> for OrderMap<K, V, S> {
type Output = V;
/// Returns a reference to the value at the supplied `index`.
///
/// ***Panics*** if `index` is out of bounds.
fn index(&self, index: usize) -> &V {
self.0.index(index)
}
}
/// Access `IndexMap` values at indexed positions.
///
/// Mutable indexing allows changing / updating indexed values
/// that are already present.
///
/// You can **not** insert new values with index syntax, use `.insert()`.
///
/// # Examples
///
/// ```
/// use indexmap::IndexMap;
///
/// let mut map = IndexMap::new();
/// for word in "Lorem ipsum dolor sit amet".split_whitespace() {
/// map.insert(word.to_lowercase(), word.to_string());
/// }
/// let lorem = &mut map[0];
/// assert_eq!(lorem, "Lorem");
/// lorem.retain(char::is_lowercase);
/// assert_eq!(map["lorem"], "orem");
/// ```
///
/// ```should_panic
/// use indexmap::IndexMap;
///
/// let mut map = IndexMap::new();
/// map.insert("foo", 1);
/// map[10] = 1; // panics!
/// ```
impl<K, V, S> IndexMut<usize> for OrderMap<K, V, S> {
/// Returns a mutable reference to the value at the supplied `index`.
///
/// ***Panics*** if `index` is out of bounds.
fn index_mut(&mut self, index: usize) -> &mut V {
self.0.index_mut(index)
}
}
impl<K, V, S> FromIterator<(K, V)> for OrderMap<K, V, S>
where
K: Hash + Eq,
S: BuildHasher + Default,
{
/// Create an `OrderMap` from the sequence of key-value pairs in the
/// iterable.
///
/// `from_iter` uses the same logic as `extend`. See
/// [`extend`](#method.extend) for more details.
fn from_iter<I: IntoIterator<Item = (K, V)>>(iterable: I) -> Self {
Self(IndexMap::from_iter(iterable))
}
}
// todo: uncomment when the MSRV bumps
// impl<K, V, const N: usize> From<[(K, V); N]> for OrderMap<K, V, RandomState>
// where
// K: Hash + Eq,
// {
// fn from(arr: [(K, V); N]) -> Self {
// Self(IndexMap::from(arr))
// }
// }
impl<K, V, S> Extend<(K, V)> for OrderMap<K, V, S>
where
K: Hash + Eq,
S: BuildHasher,
{
/// Extend the map with all key-value pairs in the iterable.
///
/// This is equivalent to calling [`insert`](#method.insert) for each of
/// them in order, which means that for keys that already existed
/// in the map, their value is updated but it keeps the existing order.
///
/// New keys are inserted in the order they appear in the sequence. If
/// equivalents of a key occur more than once, the last corresponding value
/// prevails.
fn extend<I: IntoIterator<Item = (K, V)>>(&mut self, iterable: I) {
self.0.extend(iterable)
}
}
impl<'a, K, V, S> Extend<(&'a K, &'a V)> for OrderMap<K, V, S>
where
K: 'a + Hash + Eq + Copy,
V: 'a + Copy,
S: BuildHasher,
{
/// Extend the map with all key-value pairs in the iterable.
///
/// See the first extend method for more details.
fn extend<I: IntoIterator<Item = (&'a K, &'a V)>>(&mut self, iterable: I) {
self.0.extend(iterable)
}
}
impl<K, V, S> Default for OrderMap<K, V, S>
where
S: Default,
{
/// Return an empty `OrderMap`
fn default() -> Self {
Self(IndexMap::default())
}
}
impl<K, V1, S1, V2, S2> PartialEq<OrderMap<K, V2, S2>> for OrderMap<K, V1, S1>
where
K: Hash + Eq,
V1: PartialEq<V2>,
S1: BuildHasher,
S2: BuildHasher,
{
fn eq(&self, other: &OrderMap<K, V2, S2>) -> bool {
self.0.eq(&other.0)
}
}
impl<K, V, S> Eq for OrderMap<K, V, S>
where
K: Eq + Hash,
V: Eq,
S: BuildHasher,
{
}
impl<S> FromIterator<KeyValue> for OrderMap<Key, Value, S>
where
S: BuildHasher + Default,
{
/// Create an `OrderMap` from the sequence of key-value pairs in the
/// iterable.
///
/// `from_iter` uses the same logic as `extend`. See
/// [`extend`](#method.extend) for more details.
fn from_iter<I: IntoIterator<Item = KeyValue>>(iterable: I) -> Self {
Self(IndexMap::from_iter(
iterable.into_iter().map(|kv| (kv.key, kv.value)),
))
}
}
// todo: uncomment below when bumping MSRV
// impl<const N: usize> From<[KeyValue; N]> for OrderMap<Key, Value, RandomState> {
// fn from(arr: [KeyValue; N]) -> Self {
// let arr = arr.map(|kv| (kv.key, kv.value));
// Self(IndexMap::from(arr))
// }
// }
impl<S> Extend<KeyValue> for OrderMap<Key, Value, S>
where
S: BuildHasher,
{
/// Extend the map with all key-value pairs in the iterable.
///
/// This is equivalent to calling [`insert`](#method.insert) for each of
/// them in order, which means that for keys that already existed
/// in the map, their value is updated but it keeps the existing order.
///
/// New keys are inserted in the order they appear in the sequence. If
/// equivalents of a key occur more than once, the last corresponding value
/// prevails.
fn extend<I: IntoIterator<Item = KeyValue>>(&mut self, iterable: I) {
self.0
.extend(iterable.into_iter().map(|kv| (kv.key, kv.value)))
}
}

View File

@ -1,232 +0,0 @@
//! # OpenTelemetry Propagator interface
//!
//! Propagators API consists of two main formats:
//!
//! - `BinaryFormat` is used to serialize and deserialize a value
//! into a binary representation.
//! - `TextMapFormat` is used to inject and extract a value as
//! text into injectors and extractors that travel in-band across process boundaries.
//!
//! Deserializing must set `is_remote` to true on the returned
//! `SpanContext`.
//!
//! ## Binary Format
//!
//! `BinaryFormat` is a formatter to serialize and deserialize a value
//! into a binary format.
//!
//! `BinaryFormat` MUST expose the APIs that serializes values into bytes,
//! and deserializes values from bytes.
//!
//! ### ToBytes
//!
//! Serializes the given value into the on-the-wire representation.
//!
//! Required arguments:
//!
//! - the value to serialize, can be `SpanContext` or `DistributedContext`.
//!
//! Returns the on-the-wire byte representation of the value.
//!
//! ### FromBytes
//!
//! Creates a value from the given on-the-wire encoded representation.
//!
//! If the value could not be parsed, the underlying implementation
//! SHOULD decide to return ether an empty value, an invalid value, or
//! a valid value.
//!
//! Required arguments:
//!
//! - on-the-wire byte representation of the value.
//!
//! Returns a value deserialized from bytes.
//!
//! ## TextMap Format
//!
//! `TextMapFormat` is a formatter that injects and extracts a value
//! as text into injectors and extractors that travel in-band across process boundaries.
//!
//! Encoding is expected to conform to the HTTP Header Field semantics.
//! Values are often encoded as RPC/HTTP request headers.
//!
//! The carrier of propagated data on both the client (injector) and
//! server (extractor) side is usually a http request. Propagation is
//! usually implemented via library-specific request interceptors, where
//! the client-side injects values and the server-side extracts them.
//!
//! `TextMapFormat` MUST expose the APIs that injects values into injectors,
//! and extracts values from extractors.
//!
//! ### Fields
//!
//! The propagation fields defined. If your injector is reused, you should
//! delete the fields here before calling `inject`.
//!
//! For example, if the injector is a single-use or immutable request object,
//! you don't need to clear fields as they couldn't have been set before.
//! If it is a mutable, retryable object, successive calls should clear
//! these fields first.
//!
//! The use cases of this are:
//!
//! - allow pre-allocation of fields, especially in systems like gRPC
//! Metadata
//! - allow a single-pass over an iterator
//!
//! Returns list of fields that will be used by this formatter.
//!
//! ### Inject
//!
//! Injects the value downstream. For example, as http headers.
//!
//! Required arguments:
//!
//! - the `SpanContext` to be injected.
//! - the injector that holds propagation fields. For example, an outgoing
//! message or http request.
//! - the `Setter` invoked for each propagation key to add or remove.
//!
//! #### Setter argument
//!
//! Setter is an argument in `Inject` that puts value into given field.
//!
//! `Setter` allows a `TextMapFormat` to set propagated fields into a
//! injector.
//!
//! `Setter` MUST be stateless and allowed to be saved as a constant to
//! avoid runtime allocations. One of the ways to implement it is `Setter`
//! class with `Put` method as described below.
//!
//! ##### Put
//!
//! Replaces a propagated field with the given value.
//!
//! Required arguments:
//!
//! - the injector holds propagation fields. For example, an outgoing message
//! or http request.
//! - the key of the field.
//! - the value of the field.
//!
//! The implementation SHOULD preserve casing (e.g. it should not transform
//! `Content-Type` to `content-type`) if the used protocol is case insensitive,
//! otherwise it MUST preserve casing.
//!
//! ### Extract
//!
//! Extracts the value from upstream. For example, as http headers.
//!
//! If the value could not be parsed, the underlying implementation will
//! decide to return an object representing either an empty value, an invalid
//! value, or a valid value.
//!
//! Required arguments:
//!
//! - the extractor holds propagation fields. For example, an outgoing message
//! or http request.
//! - the instance of `Getter` invoked for each propagation key to get.
//!
//! Returns the non-null extracted value.
//!
//! #### Getter argument
//!
//! Getter is an argument in `Extract` that get value from given field
//!
//! `Getter` allows a `TextMapFormat` to read propagated fields from a
//! extractor.
//!
//! `Getter` MUST be stateless and allowed to be saved as a constant to avoid
//! runtime allocations. One of the ways to implement it is `Getter` class
//! with `Get` method as described below.
//!
//! ##### Get
//!
//! The Get function MUST return the first value of the given propagation
//! key or return `None` if the key doesn't exist.
//!
//! Required arguments:
//!
//! - the extractor of propagation fields, such as an HTTP request.
//! - the key of the field.
//!
//! The `get` function is responsible for handling case sensitivity. If
//! the getter is intended to work with an HTTP request object, the getter
//! MUST be case insensitive. To improve compatibility with other text-based
//! protocols, text format implementations MUST ensure to always use the
//! canonical casing for their attributes. NOTE: Canonical casing for HTTP
//! headers is usually title case (e.g. `Content-Type` instead of `content-type`).
//!
//! ##### Keys
//!
//! The Keys function returns a vector of the propagation keys.
//!
use std::collections::HashMap;
pub mod text_map_propagator;
pub use text_map_propagator::TextMapPropagator;
/// Injector provides an interface for adding fields from an underlying struct like `HashMap`
pub trait Injector {
/// Add a key and value to the underlying data.
fn set(&mut self, key: &str, value: String);
}
/// Extractor provides an interface for removing fields from an underlying struct like `HashMap`
pub trait Extractor {
/// Get a value from a key from the underlying data.
fn get(&self, key: &str) -> Option<&str>;
/// Collect all the keys from the underlying data.
fn keys(&self) -> Vec<&str>;
}
impl<S: std::hash::BuildHasher> Injector for HashMap<String, String, S> {
/// Set a key and value in the HashMap.
fn set(&mut self, key: &str, value: String) {
self.insert(key.to_lowercase(), value);
}
}
impl<S: std::hash::BuildHasher> Extractor for HashMap<String, String, S> {
/// Get a value for a key from the HashMap.
fn get(&self, key: &str) -> Option<&str> {
self.get(&key.to_lowercase()).map(|v| v.as_str())
}
/// Collect all the keys from the HashMap.
fn keys(&self) -> Vec<&str> {
self.keys().map(|k| k.as_str()).collect::<Vec<_>>()
}
}
#[cfg(test)]
mod tests {
use super::*;
use std::collections::HashMap;
#[test]
fn hash_map_get() {
let mut carrier = HashMap::new();
carrier.set("headerName", "value".to_string());
assert_eq!(
Extractor::get(&carrier, "HEADERNAME"),
Some("value"),
"case insensitive extraction"
);
}
#[test]
fn hash_map_keys() {
let mut carrier = HashMap::new();
carrier.set("headerName1", "value1".to_string());
carrier.set("headerName2", "value2".to_string());
let got = Extractor::keys(&carrier);
assert_eq!(got.len(), 2);
assert!(got.contains(&"headername1"));
assert!(got.contains(&"headername2"));
}
}

View File

@ -1 +0,0 @@
pub mod trace;

View File

@ -1,106 +0,0 @@
use crate::{trace::Tracer, InstrumentationLibrary, KeyValue};
use std::{borrow::Cow, sync::Arc};
/// Types that can create instances of [`Tracer`].
///
/// See the [`global`] module for examples of storing and retrieving tracer
/// provider instances.
///
/// [`global`]: crate::global
pub trait TracerProvider {
/// The [`Tracer`] type that this provider will return.
type Tracer: Tracer;
/// Returns a new tracer with the given name.
///
/// The `name` should be the application name or the name of the library
/// providing instrumentation. If the name is empty, then an
/// implementation-defined default name may be used instead.
///
/// # Examples
///
/// ```
/// use opentelemetry_api::{global, trace::TracerProvider};
/// use opentelemetry_api::KeyValue;
///
/// let provider = global::tracer_provider();
///
/// // tracer used in applications/binaries
/// let tracer = provider.tracer("my_app");
///
/// // tracer used in libraries/crates that optionally includes version and schema url
/// let tracer = provider.versioned_tracer(
/// "my_library",
/// Some(env!("CARGO_PKG_VERSION")),
/// Some("https://opentelemetry.io/schema/1.0.0"),
/// Some(vec![KeyValue::new("key", "value")]),
/// );
/// ```
fn tracer(&self, name: impl Into<Cow<'static, str>>) -> Self::Tracer {
self.versioned_tracer(
name,
None::<Cow<'static, str>>,
None::<Cow<'static, str>>,
None,
)
}
/// Returns a new versioned tracer with a given name.
///
/// The `name` should be the application name or the name of the library
/// providing instrumentation. If the name is empty, then an
/// implementation-defined default name may be used instead.
///
/// # Examples
///
/// ```
/// use opentelemetry_api::{global, trace::TracerProvider};
///
/// let provider = global::tracer_provider();
///
/// // tracer used in applications/binaries
/// let tracer = provider.tracer("my_app");
///
/// // tracer used in libraries/crates that optionally includes version and schema url
/// let tracer = provider.versioned_tracer(
/// "my_library",
/// Some(env!("CARGO_PKG_VERSION")),
/// Some("https://opentelemetry.io/schema/1.0.0"),
/// None,
/// );
/// ```
fn versioned_tracer(
&self,
name: impl Into<Cow<'static, str>>,
version: Option<impl Into<Cow<'static, str>>>,
schema_url: Option<impl Into<Cow<'static, str>>>,
attributes: Option<Vec<KeyValue>>,
) -> Self::Tracer {
self.library_tracer(Arc::new(InstrumentationLibrary::new(
name, version, schema_url, attributes,
)))
}
/// Returns a new versioned tracer with the given instrumentation library.
///
/// # Examples
///
/// ```
/// use opentelemetry_api::{global, InstrumentationLibrary, trace::TracerProvider};
///
/// let provider = global::tracer_provider();
///
/// // tracer used in applications/binaries
/// let tracer = provider.tracer("my_app");
///
/// // tracer used in libraries/crates that optionally includes version and schema url
/// let library = std::sync::Arc::new(InstrumentationLibrary::new(
/// env!("CARGO_PKG_NAME"),
/// Some(env!("CARGO_PKG_VERSION")),
/// Some("https://opentelemetry.io/schema/1.0.0"),
/// None,
/// ));
/// let tracer = provider.library_tracer(library);
/// ```
fn library_tracer(&self, library: Arc<InstrumentationLibrary>) -> Self::Tracer;
}

View File

@ -1,5 +1,75 @@
# Changelog
## vNext
## 0.30.0
Released 2025-May-23
- Updated `opentelemetry` and `opentelemetry-semantic-conventions` dependencies to version 0.30.0.
## 0.29.0
Released 2025-Mar-21
- Similar to the `opentelemetry-appender-tracing` fix [2658](https://github.com/open-telemetry/opentelemetry-rust/issues/2658)
InstrumentationScope(Logger) used by the appender now uses an empty ("") named Logger.
Previously, a Logger with name and version of the crate was used.
Receivers (processors, exporters) are expected to use `LogRecord.target()` as scope name.
This is already done in OTLP Exporters, so this change should be transparent to most users.
- Update `opentelemetry` dependency version to 0.29.
- Update `opentelemetry-semantic-conventions` dependency version to 0.29.
## 0.28.0
Released 2025-Feb-10
- Update `opentelemetry` dependency version to 0.28.
- Update `opentelemetry-semantic-conventions` dependency version to 0.28.
- Bump msrv to 1.75.0.
## 0.27.0
Released 2024-Nov-11
- Update `opentelemetry` dependency version to 0.27
- Bump MSRV to 1.70 [#2179](https://github.com/open-telemetry/opentelemetry-rust/pull/2179)
- [2193](https://github.com/open-telemetry/opentelemetry-rust/pull/2193) `opentelemetry-appender-log`: Output experimental code attributes
- **Breaking** [2291](https://github.com/open-telemetry/opentelemetry-rust/pull/2291) Rename `logs_level_enabled flag` to `spec_unstable_logs_enabled`. Please enable this updated flag if the feature is needed. This flag will be removed once the feature is stabilized in the specifications.
## v0.26.0
Released 2024-Sep-30
- Update `opentelemetry` dependency version to 0.26
## v0.25.0
- Update `opentelemetry` dependency version to 0.25
- Starting with this version, this crate will align with `opentelemetry` crate
on major,minor versions.
## v0.5.0
- [1869](https://github.com/open-telemetry/opentelemetry-rust/pull/1869) Utilize the `LogRecord::set_target()` method to pass the log target to the SDK.
- Update `opentelemetry` dependency version to 0.24
## v0.4.0
- Add log key-values as attributes [#1628](https://github.com/open-telemetry/opentelemetry-rust/pull/1628)
- Update `opentelemetry` dependency version to 0.23
## v0.3.0
## v0.2.0
### Changed
- Bump MSRV to 1.65 [#1318](https://github.com/open-telemetry/opentelemetry-rust/pull/1318)
### Fixed
- Add log appender versions to loggers (#1182).
## v0.1.0
Initial crate release

View File

@ -1,5 +0,0 @@
# Code owners file.
# This file controls who is tagged for review for any given pull request.
# For anything not explicitly taken by someone else:
* @open-telemetry/rust-approvers

View File

@ -1,19 +1,43 @@
[package]
name = "opentelemetry-appender-log"
version = "0.1.0"
version = "0.30.0"
description = "An OpenTelemetry appender for the log crate"
homepage = "https://github.com/open-telemetry/opentelemetry-rust/tree/main/opentelemetry-appender-log"
repository = "https://github.com/open-telemetry/opentelemetry-rust/tree/main/opentelemetry-appender-log"
readme = "README.md"
keywords = ["opentelemetry", "log", "logs"]
license = "Apache-2.0"
rust-version = "1.60"
rust-version = "1.75.0"
edition = "2021"
autobenches = false
[lib]
bench = false
[dependencies]
opentelemetry_api = { version = "0.20", path = "../opentelemetry-api", features = ["logs"]}
log = {version = "0.4.17", features = ["kv_unstable", "std"]}
opentelemetry = { version = "0.30", path = "../opentelemetry", features = [
"logs",
] }
log = { workspace = true, features = ["kv", "std"] }
serde = { workspace = true, optional = true, features = ["std"] }
opentelemetry-semantic-conventions = { version = "0.30", path = "../opentelemetry-semantic-conventions", optional = true, features = [
"semconv_experimental",
] }
[features]
logs_level_enabled = ["opentelemetry_api/logs_level_enabled"]
default = ["logs_level_enabled"]
spec_unstable_logs_enabled = ["opentelemetry/spec_unstable_logs_enabled"]
with-serde = ["log/kv_serde", "serde"]
experimental_metadata_attributes = ["dep:opentelemetry-semantic-conventions"]
[dev-dependencies]
opentelemetry_sdk = { path = "../opentelemetry-sdk", features = [
"testing",
"spec_unstable_logs_enabled",
] }
opentelemetry-stdout = { workspace = true, features = ["logs"] }
log = { workspace = true, features = ["kv_serde"] }
tokio = { workspace = true }
serde = { workspace = true, features = ["std", "derive"] }
[lints]
workspace = true

View File

@ -186,7 +186,7 @@
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright 2023 The OpenTelemetry Authors
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.

View File

@ -1,23 +1,32 @@
# OpenTelemetry Log Appender for `log` crate
![OpenTelemetry — An observability framework for cloud-native software.][splash]
[splash]: https://raw.githubusercontent.com/open-telemetry/opentelemetry-rust/main/assets/logo-text.png
# OpenTelemetry Log Appender
A [Log Appender](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/glossary.md#log-appender--bridge) that bridges logs from the [log crate](https://docs.rs/log/latest/log/) to OpenTelemetry.
This crate contains a [Log Appender](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/glossary.md#log-appender--bridge) that bridges logs from the [log crate](https://docs.rs/log/latest/log/) to OpenTelemetry.
[![Crates.io: opentelemetry-appender-log](https://img.shields.io/crates/v/opentelemetry-appender-log.svg)](https://crates.io/crates/opentelemetry-appender-log)
[![Documentation](https://docs.rs/opentelemetry-appender-log/badge.svg)](https://docs.rs/opentelemetry-appender-log)
[![LICENSE](https://img.shields.io/crates/l/opentelemetry-appender-log)](./LICENSE)
[![LICENSE](https://img.shields.io/crates/l/opentelemetry-appender-log)](https://github.com/open-telemetry/opentelemetry-rust/blob/main/opentelemetry-appender-log/LICENSE)
[![GitHub Actions CI](https://github.com/open-telemetry/opentelemetry-rust/workflows/CI/badge.svg)](https://github.com/open-telemetry/opentelemetry-rust/actions?query=workflow%3ACI+branch%3Amain)
[![Slack](https://img.shields.io/badge/slack-@cncf/otel/rust-brightgreen.svg?logo=slack)](https://cloud-native.slack.com/archives/C03GDP0H023)
## Overview
## OpenTelemetry Overview
[`OpenTelemetry`] is a collection of tools, APIs, and SDKs used to instrument,
generate, collect, and export telemetry data (metrics, logs, and traces) for
analysis in order to understand your software's performance and behavior. This
crate provides additional propagators and exporters for sending telemetry data
to vendors or using experimental propagators like `base64`.
OpenTelemetry is an Observability framework and toolkit designed to create and
manage telemetry data such as traces, metrics, and logs. OpenTelemetry is
vendor- and tool-agnostic, meaning that it can be used with a broad variety of
Observability backends, including open source tools like [Jaeger] and
[Prometheus], as well as commercial offerings.
[`OpenTelemetry`]: https://crates.io/crates/opentelemetry
OpenTelemetry is *not* an observability backend like Jaeger, Prometheus, or other
commercial vendors. OpenTelemetry is focused on the generation, collection,
management, and export of telemetry. A major goal of OpenTelemetry is that you
can easily instrument your applications or systems, no matter their language,
infrastructure, or runtime environment. Crucially, the storage and visualization
of telemetry is intentionally left to other tools.
## Release Notes
You can find the release notes (changelog) [here](https://github.com/open-telemetry/opentelemetry-rust/blob/main/opentelemetry-appender-log/CHANGELOG.md).

View File

@ -0,0 +1,35 @@
//! run with `$ cargo run --example logs-basic`
/// This example shows how to use in_memory_exporter for logs. This uses opentelemetry-appender-log crate, which is a
/// [logging appender](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/glossary.md#log-appender--bridge) that bridges logs from the [log crate](https://docs.rs/log/latest/log/) to OpenTelemetry.
/// The example setups a LoggerProvider with a in-memory exporter, so emitted logs are stored in memory.
///
use log::{error, info, warn, Level};
use opentelemetry_appender_log::OpenTelemetryLogBridge;
use opentelemetry_sdk::logs::{BatchLogProcessor, SdkLoggerProvider};
use opentelemetry_stdout::LogExporter;
#[tokio::main]
async fn main() {
//Create an exporter that writes to stdout
let exporter = LogExporter::default();
//Create a LoggerProvider and register the exporter
let logger_provider = SdkLoggerProvider::builder()
.with_log_processor(BatchLogProcessor::builder(exporter).build())
.build();
// Setup Log Appender for the log crate.
let otel_log_appender = OpenTelemetryLogBridge::new(&logger_provider);
log::set_boxed_logger(Box::new(otel_log_appender)).unwrap();
log::set_max_level(Level::Info.to_level_filter());
// Emit logs using macros from the log crate.
let fruit = "apple";
let price = 2.99;
error!(fruit, price; "hello from {fruit}. My price is {price}");
warn!("warn!");
info!("test log!");
let _ = logger_provider.shutdown();
}

File diff suppressed because it is too large Load Diff

View File

@ -1,5 +1,154 @@
# Changelog
## vNext
## 0.30.1
Released 2025-June-05
- Bump `tracing-opentelemetry` to 0.31
## 0.30.0
Released 2025-May-23
- Updated `opentelemetry` dependency to version 0.30.0.
## 0.29.1
Released 2025-Mar-24
- Bump `tracing-opentelemetry` to 0.30
## 0.29.0
Released 2025-Mar-21
Fixes [1682](https://github.com/open-telemetry/opentelemetry-rust/issues/1682).
"spec_unstable_logs_enabled" feature now do not suppress logs for other layers.
The special treatment of the "message" field has been extended when recording
string values. With this change, when a log is emitted with a field named
"message" (and string value), its value is directly assigned to the LogRecords
body rather than being stored as an attribute named "message". This offers a
slight performance improvement over previous.
For example, the below will now produce LogRecord with the message value
populated as LogRecord's body:
```rust
error!(name: "my-event-name", target: "my-system", event_id = 20, user_name = "otel", user_email = "otel@opentelemetry.io", message = "This is an example message");
```
Previously, Body was only populated when the below style was used.
```rust
error!(name: "my-event-name", target: "my-system", event_id = 20, user_name = "otel", user_email = "otel@opentelemetry.io", "This is an example message");
```
This style, while slightly slower, should still be used when the value is not a
simple string, but require format arguments as in the below example.
```rust
error!(name: "my-event-name", target: "my-system", event_id = 20, user_name = "otel", user_email = "otel@opentelemetry.io", "This is an example message with format arguments {} and {}", "foo", "bar");
```
Fixes [2658](https://github.com/open-telemetry/opentelemetry-rust/issues/2658)
InstrumentationScope(Logger) used by the appender now uses an empty ("") named
Logger. Previously, a Logger with name and version of the crate was used.
Receivers (processors, exporters) are expected to use `LogRecord.target()` as
scope name. This is already done in OTLP Exporters, so this change should be
transparent to most users.
- Passes event name to the `event_enabled` method on the `Logger`. This allows
implementations (SDK, processor, exporters) to leverage this additional
information to determine if an event is enabled.
- `u64`, `i128`, `u128` and `usize` values are stored as `opentelemetry::logs::AnyValue::Int`
when conversion is feasible. Otherwise stored as
`opentelemetry::logs::AnyValue::String`. This avoids unnecessary string
allocation when values can be represented in their original types.
- Byte arrays are stored as `opentelemetry::logs::AnyValue::Bytes` instead
of string.
- `Error` fields are reported using attribute named "exception.message". For
example, the below will now report an attribute named "exception.message",
instead of previously reporting the user provided attribute "error".
`error!(....error = &OTelSdkError::AlreadyShutdown as &dyn std::error::Error...)`
- perf - small perf improvement by avoiding string allocation of `target`
- Update `opentelemetry` dependency version to 0.29.
## 0.28.1
Released 2025-Feb-12
- New *experimental* feature to use trace_id & span_id from spans created through the [tracing](https://crates.io/crates/tracing) crate (experimental_use_tracing_span_context) [#2438](https://github.com/open-telemetry/opentelemetry-rust/pull/2438)
## 0.28.0
Released 2025-Feb-10
- Update `opentelemetry` dependency version to 0.28.
- Bump msrv to 1.75.0.
## 0.27.0
Released 2024-Nov-11
- Update `opentelemetry` dependency version to 0.27
- Bump MSRV to 1.70 [#2179](https://github.com/open-telemetry/opentelemetry-rust/pull/2179)
- **Breaking** [2291](https://github.com/open-telemetry/opentelemetry-rust/pull/2291) Rename `logs_level_enabled flag` to `spec_unstable_logs_enabled`. Please enable this updated flag if the feature is needed. This flag will be removed once the feature is stabilized in the specifications.
## v0.26.0
Released 2024-Sep-30
- Update `opentelemetry` dependency version to 0.26
- [2101](https://github.com/open-telemetry/opentelemetry-rust/pull/2101) The `log` events emitted via the `tracing` pipeline using the `log-tracing` crate no longer include the target metadata as attributes. Exporters or backends that rely on this attribute should now access the target directly from the `LogRecord::target` field.
## v0.25.0
- Update `opentelemetry` dependency version to 0.25
- Starting with this version, this crate will align with `opentelemetry` crate
on major,minor versions.
- Reduce heap allocation by using `&'static str` for `SeverityText`.
## v0.5.0
- [1869](https://github.com/open-telemetry/opentelemetry-rust/pull/1869) Utilize the `LogRecord::set_target()` method to pass the tracing target to the SDK.
Exporters might use the target to override the instrumentation scope, which previously contained "opentelemetry-appender-tracing".
- **Breaking** [1928](https://github.com/open-telemetry/opentelemetry-rust/pull/1928) Insert tracing event name into LogRecord::event_name instead of attributes.
- If using a custom exporter, then they must serialize this field directly from LogRecord::event_name instead of iterating over the attributes. OTLP Exporter is modified to handle this.
- Update `opentelemetry` dependency version to 0.24
## v0.4.0
- Removed unwanted dependency on opentelemetry-sdk.
- Update `opentelemetry` dependency version to 0.23
## v0.3.0
### Added
- New experimental metadata attributes feature (experimental\_metadata\_attributes) [#1380](https://github.com/open-telemetry/opentelemetry-rust/pull/1380)
- Experimental new attributes for tracing metadata
- Fixes the following for events emitted using log crate
- Normalized metadata fields
- Remove redundant metadata
## v0.2.0
### Changed
- Bump MSRV to 1.65 [#1318](https://github.com/open-telemetry/opentelemetry-rust/pull/1318)
### Added
- Add log appender versions to loggers (#1182)
## v0.1.0
Initial crate release

View File

@ -1,5 +0,0 @@
# Code owners file.
# This file controls who is tagged for review for any given pull request.
# For anything not explicitly taken by someone else:
* @open-telemetry/rust-approvers

View File

@ -1,6 +1,6 @@
[package]
name = "opentelemetry-appender-tracing"
version = "0.1.0"
version = "0.30.1"
edition = "2021"
description = "An OpenTelemetry log appender for the tracing crate"
homepage = "https://github.com/open-telemetry/opentelemetry-rust/tree/main/opentelemetry-appender-tracing"
@ -8,19 +8,49 @@ repository = "https://github.com/open-telemetry/opentelemetry-rust/tree/main/ope
readme = "README.md"
keywords = ["opentelemetry", "log", "logs", "tracing"]
license = "Apache-2.0"
rust-version = "1.60"
rust-version = "1.75.0"
autobenches = false
[dependencies]
opentelemetry_api = { version = "0.20", path = "../opentelemetry-api", features = ["logs"] }
opentelemetry_sdk = { version = "0.20", path = "../opentelemetry-sdk", features = ["logs"] }
tracing = {version = "0.1.37", default-features = false, features = ["std"]}
tracing-core = "0.1.31"
tracing-subscriber = { version = "0.3.0", default-features = false, features = ["registry", "std"] }
once_cell = "1.13.0"
log = { workspace = true, optional = true }
opentelemetry = { version = "0.30", path = "../opentelemetry", features = ["logs"] }
tracing = { workspace = true, features = ["std"]}
tracing-core = { workspace = true }
tracing-log = { workspace = true, optional = true }
tracing-subscriber = { workspace = true, features = ["registry", "std"] }
tracing-opentelemetry = { workspace = true, optional = true }
[dev-dependencies]
opentelemetry-stdout = { path = "../opentelemetry-stdout", features = ["logs"] }
log = { workspace = true }
opentelemetry-stdout = { workspace = true, features = ["logs"] }
opentelemetry_sdk = { path = "../opentelemetry-sdk", features = ["logs", "testing"] }
tracing = { workspace = true, features = ["std"]}
tracing-subscriber = { workspace = true, features = ["env-filter","registry", "std", "fmt"] }
tracing-log = { workspace = true }
criterion = { workspace = true }
tokio = { workspace = true, features = ["full"]}
[target.'cfg(not(target_os = "windows"))'.dev-dependencies]
pprof = { version = "0.14", features = ["flamegraph", "criterion"] }
[features]
logs_level_enabled = ["opentelemetry_api/logs_level_enabled", "opentelemetry_sdk/logs_level_enabled"]
default = ["logs_level_enabled"]
default = []
experimental_metadata_attributes = ["dep:tracing-log"]
spec_unstable_logs_enabled = ["opentelemetry/spec_unstable_logs_enabled"]
experimental_use_tracing_span_context = ["tracing-opentelemetry"]
[[bench]]
name = "logs"
harness = false
required-features = ["spec_unstable_logs_enabled"]
[[bench]]
name = "log-attributes"
harness = false
[lib]
bench = false
[lints]
workspace = true

View File

@ -1,30 +1,53 @@
# OpenTelemetry Log Appender for `tracing` crate
![OpenTelemetry — An observability framework for cloud-native software.][splash]
[splash]: https://raw.githubusercontent.com/open-telemetry/opentelemetry-rust/main/assets/logo-text.png
# OpenTelemetry Log Appender for Tracing
A [Log
This crate contains a [Log
Appender](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/glossary.md#log-appender--bridge)
that bridges logs from the [tracing crate](https://tracing.rs/tracing/#events)
to OpenTelemetry logs. Note that this is different from the existing
to OpenTelemetry. Note that this is different from the existing
[tracing-opentelemetry](https://github.com/tokio-rs/tracing-opentelemetry)
project, which supports bridging traces and logs from tracing into OpenTelemetry
traces. This is an experimental component, and could be merged with the
tracing-opentelemetry crate itself.
traces.
[![Crates.io: opentelemetry-appender-tracing](https://img.shields.io/crates/v/opentelemetry-appender-tracing.svg)](https://crates.io/crates/opentelemetry-appender-tracing)
[![Documentation](https://docs.rs/opentelemetry-appender-tracing/badge.svg)](https://docs.rs/opentelemetry-appender-tracing)
[![LICENSE](https://img.shields.io/crates/l/opentelemetry-appender-tracing)](./LICENSE)
[![LICENSE](https://img.shields.io/crates/l/opentelemetry-appender-tracing)](https://github.com/open-telemetry/opentelemetry-rust/blob/main/opentelemetry-appender-tracing/LICENSE)
[![GitHub Actions CI](https://github.com/open-telemetry/opentelemetry-rust/workflows/CI/badge.svg)](https://github.com/open-telemetry/opentelemetry-rust/actions?query=workflow%3ACI+branch%3Amain)
[![Slack](https://img.shields.io/badge/slack-@cncf/otel/rust-brightgreen.svg?logo=slack)](https://cloud-native.slack.com/archives/C03GDP0H023)
## Overview
## OpenTelemetry Overview
[`OpenTelemetry`] is a collection of tools, APIs, and SDKs used to instrument,
generate, collect, and export telemetry data (metrics, logs, and traces) for
analysis in order to understand your software's performance and behavior. This
crate provides additional propagators and exporters for sending telemetry data
to vendors or using experimental propagators like `base64`.
OpenTelemetry is an Observability framework and toolkit designed to create and
manage telemetry data such as traces, metrics, and logs. OpenTelemetry is
vendor- and tool-agnostic, meaning that it can be used with a broad variety of
Observability backends, including open source tools like [Jaeger] and
[Prometheus], as well as commercial offerings.
[`OpenTelemetry`]: https://crates.io/crates/opentelemetry
OpenTelemetry is *not* an observability backend like Jaeger, Prometheus, or other
commercial vendors. OpenTelemetry is focused on the generation, collection,
management, and export of telemetry. A major goal of OpenTelemetry is that you
can easily instrument your applications or systems, no matter their language,
infrastructure, or runtime environment. Crucially, the storage and visualization
of telemetry is intentionally left to other tools.
*[Supported Rust Versions](#supported-rust-versions)*
## Release Notes
You can find the release notes (changelog) [here](https://github.com/open-telemetry/opentelemetry-rust/blob/main/opentelemetry-appender-tracing/CHANGELOG.md).
## Supported Rust Versions
OpenTelemetry is built against the latest stable release. The minimum supported
version is 1.75.0. The current OpenTelemetry version is not guaranteed to build
on Rust versions earlier than the minimum supported version.
The current stable Rust compiler and the three most recent minor versions
before it will always be supported. For example, if the current stable compiler
version is 1.49, the minimum supported version will not be increased past 1.46,
three minor versions prior. Increasing the minimum supported compiler version
is not considered a semver breaking change as long as doing so complies with
this policy.

View File

@ -0,0 +1,273 @@
/*
// Run this benchmark with:
// cargo bench --bench log-attributes
// Adding results in comments for a quick reference.
// Apple M4 Pro
// Total Number of Cores: 14 (10 performance and 4 efficiency)
| Test | Average time | Increment |
|----------------------|--------------|-----------|
| otel_0_attributes | 72 ns | - |
| otel_1_attributes | 117 ns | +45 ns |
| otel_2_attributes | 155 ns | +38 ns |
| otel_3_attributes | 196 ns | +41 ns |
| otel_4_attributes | 240 ns | +44 ns |
| otel_5_attributes | 278 ns | +38 ns |
| otel_6_attributes | 346 ns | +68 ns | // Array is full. 6th attribute causes vec! to be allocated
| otel_7_attributes | 390 ns | +44 ns |
| otel_8_attributes | 431 ns | +41 ns |
| otel_9_attributes | 480 ns | +49 ns |
| otel_10_attributes | 519 ns | +39 ns |
| otel_11_attributes | 625 ns | +106 ns | // vec! initial capacity is 5. 11th attribute causes vec! to be reallocated
| otel_12_attributes | 676 ns | +51 ns |
*/
use criterion::{criterion_group, criterion_main, Criterion};
use opentelemetry::InstrumentationScope;
use opentelemetry_appender_tracing::layer as tracing_layer;
use opentelemetry_sdk::error::OTelSdkResult;
use opentelemetry_sdk::logs::{LogProcessor, SdkLogRecord, SdkLoggerProvider};
use opentelemetry_sdk::Resource;
#[cfg(not(target_os = "windows"))]
use pprof::criterion::{Output, PProfProfiler};
use tracing::error;
use tracing_subscriber::prelude::*;
use tracing_subscriber::Registry;
#[derive(Debug)]
struct NoopProcessor;
impl LogProcessor for NoopProcessor {
fn emit(&self, _: &mut SdkLogRecord, _: &InstrumentationScope) {}
fn force_flush(&self) -> OTelSdkResult {
Ok(())
}
}
/// Creates a single benchmark for a specific number of attributes
fn create_benchmark(c: &mut Criterion, num_attributes: usize) {
let provider = SdkLoggerProvider::builder()
.with_resource(
Resource::builder_empty()
.with_service_name("benchmark")
.build(),
)
.with_log_processor(NoopProcessor)
.build();
let ot_layer = tracing_layer::OpenTelemetryTracingBridge::new(&provider);
let subscriber = Registry::default().with(ot_layer);
tracing::subscriber::with_default(subscriber, || {
c.bench_function(&format!("otel_{num_attributes}_attributes"), |b| {
b.iter(|| {
// Dynamically generate the error! macro call based on the number of attributes
match num_attributes {
0 => {
error!(
name : "CheckoutFailed",
message = "Unable to process checkout."
);
}
1 => {
error!(
name : "CheckoutFailed",
field1 = "field1",
message = "Unable to process checkout."
);
}
2 => {
error!(
name : "CheckoutFailed",
field1 = "field1",
field2 = "field2",
message = "Unable to process checkout."
);
}
3 => {
error!(
name : "CheckoutFailed",
field1 = "field1",
field2 = "field2",
field3 = "field3",
message = "Unable to process checkout."
);
}
4 => {
error!(
name : "CheckoutFailed",
field1 = "field1",
field2 = "field2",
field3 = "field3",
field4 = "field4",
message = "Unable to process checkout."
);
}
5 => {
error!(
name : "CheckoutFailed",
field1 = "field1",
field2 = "field2",
field3 = "field3",
field4 = "field4",
field5 = "field5",
message = "Unable to process checkout."
);
}
6 => {
error!(
name : "CheckoutFailed",
field1 = "field1",
field2 = "field2",
field3 = "field3",
field4 = "field4",
field5 = "field5",
field6 = "field6",
message = "Unable to process checkout."
);
}
7 => {
error!(
name : "CheckoutFailed",
field1 = "field1",
field2 = "field2",
field3 = "field3",
field4 = "field4",
field5 = "field5",
field6 = "field6",
field7 = "field7",
message = "Unable to process checkout."
);
}
8 => {
error!(
name : "CheckoutFailed",
field1 = "field1",
field2 = "field2",
field3 = "field3",
field4 = "field4",
field5 = "field5",
field6 = "field6",
field7 = "field7",
field8 = "field8",
message = "Unable to process checkout."
);
}
9 => {
error!(
name : "CheckoutFailed",
field1 = "field1",
field2 = "field2",
field3 = "field3",
field4 = "field4",
field5 = "field5",
field6 = "field6",
field7 = "field7",
field8 = "field8",
field9 = "field9",
message = "Unable to process checkout."
);
}
10 => {
error!(
name : "CheckoutFailed",
field1 = "field1",
field2 = "field2",
field3 = "field3",
field4 = "field4",
field5 = "field5",
field6 = "field6",
field7 = "field7",
field8 = "field8",
field9 = "field9",
field10 = "field10",
message = "Unable to process checkout."
);
}
11 => {
error!(
name : "CheckoutFailed",
field1 = "field1",
field2 = "field2",
field3 = "field3",
field4 = "field4",
field5 = "field5",
field6 = "field6",
field7 = "field7",
field8 = "field8",
field9 = "field9",
field10 = "field10",
field11 = "field11",
message = "Unable to process checkout."
);
}
12 => {
error!(
name : "CheckoutFailed",
field1 = "field1",
field2 = "field2",
field3 = "field3",
field4 = "field4",
field5 = "field5",
field6 = "field6",
field7 = "field7",
field8 = "field8",
field9 = "field9",
field10 = "field10",
field11 = "field11",
field12 = "field12",
message = "Unable to process checkout."
);
}
_ => {
// Fall back to 10 attributes for any higher number
error!(
name : "CheckoutFailed",
field1 = "field1",
field2 = "field2",
field3 = "field3",
field4 = "field4",
field5 = "field5",
field6 = "field6",
field7 = "field7",
field8 = "field8",
field9 = "field9",
field10 = "field10",
message = "Unable to process checkout."
);
}
}
});
});
});
}
fn criterion_benchmark(c: &mut Criterion) {
create_benchmark(c, 2);
// Run benchmarks for 0 to 12 attributes
// for num_attributes in 0..=12 {
// create_benchmark(c, 2);
// }
}
#[cfg(not(target_os = "windows"))]
criterion_group! {
name = benches;
config = Criterion::default()
.warm_up_time(std::time::Duration::from_secs(1))
.measurement_time(std::time::Duration::from_secs(2))
.with_profiler(PProfProfiler::new(100, Output::Flamegraph(None)));
targets = criterion_benchmark
}
#[cfg(target_os = "windows")]
criterion_group! {
name = benches;
config = Criterion::default()
.warm_up_time(std::time::Duration::from_secs(1))
.measurement_time(std::time::Duration::from_secs(2));
targets = criterion_benchmark
}
criterion_main!(benches);

View File

@ -0,0 +1,181 @@
/*
The benchmark results:
criterion = "0.5.1"
OS: Ubuntu 22.04.3 LTS (5.15.146.1-microsoft-standard-WSL2)
Hardware: AMD EPYC 7763 64-Core Processor - 2.44 GHz, 16vCPUs,
RAM: 64.0 GB
| Test | Average time|
|-----------------------------|-------------|
| log_no_subscriber | 313 ps |
| noop_layer_disabled | 12 ns |
| noop_layer_enabled | 25 ns |
| ot_layer_disabled | 19 ns |
| ot_layer_enabled | 155 ns |
Hardware: Apple M4 Pro
Total Number of Cores: 14 (10 performance and 4 efficiency)
| Test | Average time|
|-----------------------------|-------------|
| log_no_subscriber | 285 ps |
| noop_layer_disabled | 8 ns |
| noop_layer_enabled | 14 ns |
| ot_layer_disabled | 12 ns |
| ot_layer_enabled | 130 ns |
*/
use criterion::{criterion_group, criterion_main, Criterion};
use opentelemetry::InstrumentationScope;
use opentelemetry_appender_tracing::layer as tracing_layer;
use opentelemetry_sdk::error::OTelSdkResult;
use opentelemetry_sdk::logs::{LogProcessor, SdkLogRecord, SdkLoggerProvider};
use opentelemetry_sdk::Resource;
#[cfg(not(target_os = "windows"))]
use pprof::criterion::{Output, PProfProfiler};
use tracing::error;
use tracing_subscriber::prelude::*;
use tracing_subscriber::Layer;
use tracing_subscriber::Registry;
#[derive(Debug)]
struct NoopProcessor {
enabled: bool,
}
impl NoopProcessor {
fn new(enabled: bool) -> Self {
Self { enabled }
}
}
impl LogProcessor for NoopProcessor {
fn emit(&self, _: &mut SdkLogRecord, _: &InstrumentationScope) {}
fn force_flush(&self) -> OTelSdkResult {
Ok(())
}
fn event_enabled(
&self,
_level: opentelemetry::logs::Severity,
_target: &str,
_name: Option<&str>,
) -> bool {
self.enabled
}
}
struct NoOpLogLayer {
enabled: bool,
}
impl<S> Layer<S> for NoOpLogLayer
where
S: tracing::Subscriber,
{
fn on_event(
&self,
event: &tracing::Event<'_>,
_ctx: tracing_subscriber::layer::Context<'_, S>,
) {
let mut visitor = NoopEventVisitor;
event.record(&mut visitor);
}
fn event_enabled(
&self,
_event: &tracing::Event<'_>,
_ctx: tracing_subscriber::layer::Context<'_, S>,
) -> bool {
self.enabled
}
}
struct NoopEventVisitor;
impl tracing::field::Visit for NoopEventVisitor {
fn record_debug(&mut self, _field: &tracing::field::Field, _value: &dyn std::fmt::Debug) {}
}
fn benchmark_no_subscriber(c: &mut Criterion) {
c.bench_function("log_no_subscriber", |b| {
b.iter(|| {
error!(
name : "CheckoutFailed",
book_id = "12345",
book_title = "Rust Programming Adventures",
message = "Unable to process checkout."
);
});
});
}
fn benchmark_with_ot_layer(c: &mut Criterion, enabled: bool, bench_name: &str) {
let processor = NoopProcessor::new(enabled);
let provider = SdkLoggerProvider::builder()
.with_resource(
Resource::builder_empty()
.with_service_name("benchmark")
.build(),
)
.with_log_processor(processor)
.build();
let ot_layer = tracing_layer::OpenTelemetryTracingBridge::new(&provider);
let subscriber = Registry::default().with(ot_layer);
tracing::subscriber::with_default(subscriber, || {
c.bench_function(bench_name, |b| {
b.iter(|| {
error!(
name : "CheckoutFailed",
book_id = "12345",
book_title = "Rust Programming Adventures",
message = "Unable to process checkout."
);
});
});
});
}
fn benchmark_with_noop_layer(c: &mut Criterion, enabled: bool, bench_name: &str) {
let subscriber = Registry::default().with(NoOpLogLayer { enabled });
tracing::subscriber::with_default(subscriber, || {
c.bench_function(bench_name, |b| {
b.iter(|| {
error!(
name : "CheckoutFailed",
book_id = "12345",
book_title = "Rust Programming Adventures",
message = "Unable to process checkout."
);
});
});
});
}
fn criterion_benchmark(c: &mut Criterion) {
benchmark_no_subscriber(c);
benchmark_with_ot_layer(c, true, "ot_layer_enabled");
benchmark_with_ot_layer(c, false, "ot_layer_disabled");
benchmark_with_noop_layer(c, true, "noop_layer_enabled");
benchmark_with_noop_layer(c, false, "noop_layer_disabled");
}
#[cfg(not(target_os = "windows"))]
criterion_group! {
name = benches;
config = Criterion::default()
.warm_up_time(std::time::Duration::from_secs(1))
.measurement_time(std::time::Duration::from_secs(2))
.with_profiler(PProfProfiler::new(100, Output::Flamegraph(None)));
targets = criterion_benchmark
}
#[cfg(target_os = "windows")]
criterion_group! {
name = benches;
config = Criterion::default()
.warm_up_time(std::time::Duration::from_secs(1))
.measurement_time(std::time::Duration::from_secs(2));
targets = criterion_benchmark
}
criterion_main!(benches);

View File

@ -1,28 +1,55 @@
//! run with `$ cargo run --example basic
use opentelemetry_api::KeyValue;
use opentelemetry_appender_tracing::layer;
use opentelemetry_sdk::{
logs::{Config, LoggerProvider},
Resource,
};
use opentelemetry_sdk::{logs::SdkLoggerProvider, Resource};
use tracing::error;
use tracing_subscriber::prelude::*;
use tracing_subscriber::{prelude::*, EnvFilter};
fn main() {
let exporter = opentelemetry_stdout::LogExporter::default();
let provider: LoggerProvider = LoggerProvider::builder()
.with_config(
Config::default().with_resource(Resource::new(vec![KeyValue::new(
"service.name",
"log-appender-tracing-example",
)])),
let provider: SdkLoggerProvider = SdkLoggerProvider::builder()
.with_resource(
Resource::builder()
.with_service_name("log-appender-tracing-example")
.build(),
)
.with_simple_exporter(exporter)
.build();
let layer = layer::OpenTelemetryTracingBridge::new(&provider);
tracing_subscriber::registry().with(layer).init();
error!(target: "my-system", event_id = 20, event_name = "my-event_name", user_name = "otel", user_email = "otel@opentelemetry.io");
drop(provider);
// To prevent a telemetry-induced-telemetry loop, OpenTelemetry's own internal
// logging is properly suppressed. However, logs emitted by external components
// (such as reqwest, tonic, etc.) are not suppressed as they do not propagate
// OpenTelemetry context. Until this issue is addressed
// (https://github.com/open-telemetry/opentelemetry-rust/issues/2877),
// filtering like this is the best way to suppress such logs.
//
// The filter levels are set as follows:
// - Allow `info` level and above by default.
// - Completely restrict logs from `hyper`, `tonic`, `h2`, and `reqwest`.
//
// Note: This filtering will also drop logs from these components even when
// they are used outside of the OTLP Exporter.
let filter_otel = EnvFilter::new("info")
.add_directive("hyper=off".parse().unwrap())
.add_directive("opentelemetry=off".parse().unwrap())
.add_directive("tonic=off".parse().unwrap())
.add_directive("h2=off".parse().unwrap())
.add_directive("reqwest=off".parse().unwrap());
let otel_layer = layer::OpenTelemetryTracingBridge::new(&provider).with_filter(filter_otel);
// Create a new tracing::Fmt layer to print the logs to stdout. It has a
// default filter of `info` level and above, and `debug` and above for logs
// from OpenTelemetry crates. The filter levels can be customized as needed.
let filter_fmt = EnvFilter::new("info").add_directive("opentelemetry=debug".parse().unwrap());
let fmt_layer = tracing_subscriber::fmt::layer()
.with_thread_names(true)
.with_filter(filter_fmt);
tracing_subscriber::registry()
.with(otel_layer)
.with(fmt_layer)
.init();
error!(name: "my-event-name", target: "my-system", event_id = 20, user_name = "otel", user_email = "otel@opentelemetry.io", message = "This is an example message");
let _ = provider.shutdown();
}

File diff suppressed because it is too large Load Diff

View File

@ -1 +1,155 @@
//! # OpenTelemetry-Appender-Tracing
//!
//! This crate provides a bridge between the [`tracing`](https://docs.rs/tracing/latest/tracing/) crate and OpenTelemetry logs.
//! It converts `tracing` events into OpenTelemetry `LogRecords`, allowing applications using `tracing` to seamlessly integrate
//! with OpenTelemetry logging backends.
//!
//! ## Background
//!
//! Unlike traces and metrics, OpenTelemetry does not provide a dedicated logging API for end-users. Instead, it recommends using
//! existing logging libraries and bridging them to OpenTelemetry logs. This crate serves as such a bridge for `tracing` users.
//!
//! ## Features
//!
//! - Converts `tracing` events into OpenTelemetry [`LogRecords`](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/logs/data-model.md#log-and-event-record-definition)
//! - Integrates as a [`Layer`](https://docs.rs/tracing-subscriber/latest/tracing_subscriber/layer/trait.Layer.html)
//! from [`tracing-subscriber`](https://docs.rs/tracing-subscriber/latest/tracing_subscriber/), allowing
//! to be used alongside other `tracing` layers, such as `fmt`
//! - Automatically attaches OpenTelemetry trace context (`TraceId`, `SpanId`, `TraceFlags`) to logs
//! - Automatically associates OpenTelemetry Resource to logs
//! - Supports exporting logs to OpenTelemetry-compatible backends (OTLP, stdout, etc.)
//!
//! ## Getting Started
//!
//! ### 1. Install Dependencies
//!
//! Add the following dependencies to your `Cargo.toml`:
//!
//! ```toml
//! [dependencies]
//! tracing = ">=0.1.40"
//! tracing-core = { version = ">=0.1.33" }
//! tracing-subscriber = { version = "0.3", features = ["registry", "std", "fmt"] }
//! opentelemetry = { version = "0.28", features = ["logs"] }
//! opentelemetry-sdk = { version = "0.28", features = ["logs"] }
//! opentelemetry-appender-tracing = { version = "0.28.1" }
//! ```
//!
//! ### 2. Set Up the OpenTelemetry Logger Provider
//!
//! Before integrating with `tracing`, create an OpenTelemetry [`SdkLoggerProvider`](https://docs.rs/opentelemetry_sdk/latest/opentelemetry_sdk/logs/struct.SdkLoggerProvider.html):
//!
//! ```rust
//! use opentelemetry_sdk::logs::SdkLoggerProvider;
//! use opentelemetry_stdout::LogExporter;
//!
//! let exporter = LogExporter::default();
//! let provider = SdkLoggerProvider::builder()
//! .with_simple_exporter(exporter)
//! .build();
//! ```
//!
//! In this example, `SdkLoggerProvider` is configured to use the `opentelemetry_stdout` crate to export logs to stdout. You can replace it with any other OpenTelemetry-compatible exporter.
//! Any additional OpenTelemetry configuration (e.g., setting up a resource, additional processors etc.) can be done at this stage.
//!
//! ### 3. Create the OpenTelemetry-Tracing Bridge
//!
//! Create `OpenTelemetryTracingBridge` layer using the `SdkLoggerProvider` created in the previous step.
//!
//! ```rust
//! # use opentelemetry_sdk::logs::SdkLoggerProvider;
//! # use opentelemetry_stdout::LogExporter;
//! # use opentelemetry_appender_tracing::layer::OpenTelemetryTracingBridge;
//! # let exporter = LogExporter::default();
//! # let provider = SdkLoggerProvider::builder()
//! # .with_simple_exporter(exporter)
//! # .build();
//! let otel_layer = OpenTelemetryTracingBridge::new(&provider);
//! ```
//!
//! ### 4. Register the `tracing` Subscriber
//!
//! Since this crate provides a `Layer` for `tracing`, you can register it with the `tracing` subscriber as shown below.
//!
//! ```rust
//! # use opentelemetry_sdk::logs::SdkLoggerProvider;
//! # use opentelemetry_stdout::LogExporter;
//! # let exporter = LogExporter::default();
//! # let provider = SdkLoggerProvider::builder().with_simple_exporter(exporter).build();
//! # use opentelemetry_appender_tracing::layer::OpenTelemetryTracingBridge;
//! # let otel_layer = OpenTelemetryTracingBridge::new(&provider);
//! use tracing_subscriber::prelude::*;
//!
//! tracing_subscriber::registry()
//! .with(otel_layer)
//! .with(tracing_subscriber::fmt::layer()) // In this example, `fmt` layer is also added.
//! .init();
//! ```
//!
//! ### 5. Log Events Using `tracing`
//!
//! ```rust
//! use tracing::error;
//! error!(name: "my-event-name1", target: "my-system", event_id = 10, user_name = "otel", user_email = "otel@opentelemetry.io", message = "This is an example message");
//! ```
//!
//!
//! ## Mapping details
//!
//! Since OpenTelemetry and `tracing` have their own data models, this bridge performs the following mappings:
//!
//! | `tracing` | OpenTelemetry | Notes |
//! |-----------------------|-------------------------|-----------------------------------------------------------------------------------------|
//! | name of the event | `EventName` | OpenTelemetry defines logs with name as Events, so every `tracing` Event is actually an OTel Event |
//! | target | `target` | Groups logs from the same module/crate. At recording time, `target` is stored in a top-level field. But exporters treat this information as OpenTelemetry `InstrumentationScope` |
//! | level of the event | `Severity`, `SeverityText` | |
//! | Fields | `Attributes` | Converted into OpenTelemetry log attributes. Field with "message" as key is specially treated and stored as `LogRecord::Body` |
//! | Message | `Body` | The body/message of the log. This is done only if body was not already populated from "message" field above |
//!
//! ### Data Type Mapping
//!
//! The data types supported by `tracing` and OpenTelemetry are different and the following conversions are applied:
//!
//! | `tracing` Type | OpenTelemetry `AnyValue` Type |
//! |----------------|-------------------------------|
//! | `i64` | `Int` |
//! | `f32`, `f64` | `Double` |
//! | `u64`,`u128` ,`i128` | `Int` (if convertible to `i64` without loss) else `String` |
//! | `&str` | `String` |
//! | `bool` | `Bool` |
//! | `&[u8]` | `Bytes` |
//! | `&dyn Debug` | `String` (via `Debug` formatting) |
//! | `&dyn Error` | `String` (via `Debug` formatting). This is stored into an attribute with key "exception.message", following [OTel conventions](https://opentelemetry.io/docs/specs/semconv/attributes-registry/exception/) |
//!
//! In future, additional types may be supported.
//!
//! > **Note:** This crate does not support `tracing` Spans. One may use [`tracing-opentelemetry`](https://docs.rs/tracing-opentelemetry/latest/tracing_opentelemetry/) to
//! > convert `tracing` spans into OpenTelemetry spans. This is a third-party crate
//! > that is not maintained by the OpenTelemetry project.
//! > `tracing-opentelemetry`:
//! > - Converts `tracing` spans into OpenTelemetry spans
//! > - Converts `tracing` events into OpenTelemetry `SpanEvents` rather than logs
//! > Depending on the outcome of the
//! > [discussion](https://github.com/open-telemetry/opentelemetry-rust/issues/1571),
//! > the OpenTelemetry project may provide direct support to map `tracing`
//! > spans to OpenTelemetry in the future.
//!
//! ## Feature Flags
//! `spec_unstable_logs_enabled`: TODO
//!
//! `experimental_metadata_attributes`: TODO
//!
//! `experimental_use_tracing_span_context`: TODO
//!
//! ## Limitations
//! 1. There is no support for `Valuable` crate. [2819](https://github.com/open-telemetry/opentelemetry-rust/issues/2819)
//!
//! ## Stability Guarantees
//! // TODO
//!
//! ## Further Reading
//!
//! - OpenTelemetry Rust: [opentelemetry-rust](https://github.com/open-telemetry/opentelemetry-rust)
//! - Tracing: [tracing](https://docs.rs/tracing/)
//! - OpenTelemetry Logs: [OpenTelemetry Logging Specification](https://opentelemetry.io/docs/specs/otel/logs/)
pub mod layer;

Some files were not shown because too many files have changed in this diff Show More