├── .github
├── CODEOWNERS
├── header-checker-lint.yml
├── trusted-contribution.yml
└── workflows
│ ├── ci.yml
│ └── codeql-analysis.yml
├── .gitignore
├── LICENSE
├── Makefile
├── README.md
├── RELEASING.md
├── SECURITY.md
├── cloudbuild-e2e-cloud-functions-gen2.yaml
├── cloudbuild-e2e-cloud-run.yaml
├── cloudbuild-e2e-gae-standard.yaml
├── cloudbuild-e2e-gae.yaml
├── cloudbuild-e2e-gce.yaml
├── cloudbuild-e2e-gke.yaml
├── cloudbuild-e2e-image.yaml
├── cloudbuild-e2e-local.yaml
├── cloudbuild-integration-tests.yaml
├── detectors
└── gcp
│ ├── README.md
│ ├── app_engine.go
│ ├── app_engine_test.go
│ ├── bms.go
│ ├── bms_test.go
│ ├── detector.go
│ ├── detector_print_test.go
│ ├── detector_test.go
│ ├── faas.go
│ ├── faas_test.go
│ ├── gce.go
│ ├── gce_test.go
│ ├── gke.go
│ ├── gke_test.go
│ ├── go.mod
│ ├── go.sum
│ └── utils_test.go
├── doc.go
├── docs
├── code-of-conduct.md
└── contributing.md
├── e2e-test-server
├── Dockerfile
├── README.md
├── app.go
├── cloud_functions
│ ├── cloud_functions.go
│ ├── go.mod
│ └── go.sum
├── endtoendserver
│ ├── constants.go
│ ├── pull_server.go
│ ├── push_server.go
│ └── server.go
├── go.mod
├── go.sum
├── scenarios
│ ├── constants.go
│ ├── handler.go
│ └── scenarios.go
└── wait-for-image.sh
├── example
├── metric
│ ├── README.md
│ ├── collector
│ │ ├── example.go
│ │ ├── go.mod
│ │ ├── go.sum
│ │ └── sample-collector-config.yaml
│ ├── dashboards
│ │ ├── exponential_histogram_dashboard.json
│ │ └── sdk_dashboard.json
│ ├── exponential_histogram
│ │ ├── README.md
│ │ ├── create_dashboard.sh
│ │ ├── example.go
│ │ ├── go.mod
│ │ └── go.sum
│ ├── images
│ │ ├── exponential_histogram_charts.png
│ │ └── sdk_charts.png
│ ├── otlpgrpc
│ │ ├── README.md
│ │ ├── example.go
│ │ ├── go.mod
│ │ └── go.sum
│ └── sdk
│ │ ├── README.md
│ │ ├── create_dashboard.sh
│ │ ├── example.go
│ │ ├── go.mod
│ │ └── go.sum
└── trace
│ ├── http
│ ├── README.md
│ ├── client
│ │ └── client.go
│ ├── cloudtrace.png
│ ├── go.mod
│ ├── go.sum
│ └── server
│ │ └── server.go
│ ├── otlpgrpc
│ ├── example.go
│ ├── go.mod
│ └── go.sum
│ └── otlphttp
│ ├── example.go
│ ├── go.mod
│ └── go.sum
├── exporter
├── collector
│ ├── README.md
│ ├── benchmark_test.go
│ ├── breaking-changes.md
│ ├── config.go
│ ├── config_test.go
│ ├── go.mod
│ ├── go.sum
│ ├── googlemanagedprometheus
│ │ ├── config.go
│ │ ├── extra_metrics.go
│ │ ├── extra_metrics_test.go
│ │ ├── go.mod
│ │ ├── go.sum
│ │ ├── monitoredresource.go
│ │ ├── monitoredresource_test.go
│ │ ├── naming.go
│ │ └── naming_test.go
│ ├── integrationtest
│ │ ├── cmd
│ │ │ └── recordfixtures
│ │ │ │ └── main.go
│ │ ├── config
│ │ │ └── config_test.go
│ │ ├── diff.go
│ │ ├── factory_test.go
│ │ ├── go.mod
│ │ ├── go.sum
│ │ ├── inmemoryotelexporter.go
│ │ ├── integration_selfobs_test.go
│ │ ├── logs_integration_test.go
│ │ ├── logs_test.go
│ │ ├── metrics_integration_test.go
│ │ ├── metrics_test.go
│ │ ├── protos
│ │ │ ├── fixtures.go
│ │ │ ├── fixtures.pb.go
│ │ │ ├── fixtures.proto
│ │ │ ├── logging_service.proto
│ │ │ ├── metric_service.proto
│ │ │ └── tracing_service.proto
│ │ ├── testcases
│ │ │ ├── conversion.go
│ │ │ ├── exporter_settings.go
│ │ │ ├── testcase.go
│ │ │ ├── testcases_logs.go
│ │ │ ├── testcases_metrics.go
│ │ │ └── testcases_traces.go
│ │ ├── testdata
│ │ │ ├── config.yaml
│ │ │ ├── fixtures
│ │ │ │ ├── logs
│ │ │ │ │ ├── logs_apache_access.json
│ │ │ │ │ ├── logs_apache_access_batches_expected.json
│ │ │ │ │ ├── logs_apache_access_expected.json
│ │ │ │ │ ├── logs_apache_access_resource_attributes.json
│ │ │ │ │ ├── logs_apache_access_resource_attributes_expected.json
│ │ │ │ │ ├── logs_apache_error.json
│ │ │ │ │ ├── logs_apache_error_expected.json
│ │ │ │ │ ├── logs_apache_error_scope.json
│ │ │ │ │ ├── logs_apache_error_scope_expected.json
│ │ │ │ │ ├── logs_apache_json_error_reporting_expected.json
│ │ │ │ │ ├── logs_apache_text_error.json
│ │ │ │ │ ├── logs_apache_text_error_reporting_expected.json
│ │ │ │ │ ├── logs_multi_project.json
│ │ │ │ │ ├── logs_multi_project_destination_quota_expected.json
│ │ │ │ │ ├── logs_multi_project_expected.json
│ │ │ │ │ ├── logs_span_trace_id.json
│ │ │ │ │ ├── logs_span_trace_id_expected.json
│ │ │ │ │ └── logs_user_agent_expected.json
│ │ │ │ ├── metrics
│ │ │ │ │ ├── batching.json
│ │ │ │ │ ├── batching_expect.json
│ │ │ │ │ ├── bms_ops_agent_host_metrics.json
│ │ │ │ │ ├── bms_ops_agent_host_metrics_expect.json
│ │ │ │ │ ├── boolean_gauge.json
│ │ │ │ │ ├── boolean_gauge_expect.json
│ │ │ │ │ ├── counter.json
│ │ │ │ │ ├── counter_compressed_expect.json
│ │ │ │ │ ├── counter_expect.json
│ │ │ │ │ ├── counter_gmp_expect.json
│ │ │ │ │ ├── counter_notfound_expect.json
│ │ │ │ │ ├── counter_unknown_domain_expect.json
│ │ │ │ │ ├── counter_user_agent_expect.json
│ │ │ │ │ ├── counter_wal_deadline_expect.json
│ │ │ │ │ ├── counter_wal_expect.json
│ │ │ │ │ ├── counter_wal_unavailable_expect.json
│ │ │ │ │ ├── counter_workloadgoogleapis_prefix_expect.json
│ │ │ │ │ ├── create_service_timeseries.json
│ │ │ │ │ ├── create_service_timeseries_expect.json
│ │ │ │ │ ├── create_service_timeseries_wal_expect.json
│ │ │ │ │ ├── delta_counter.json
│ │ │ │ │ ├── delta_counter_expect.json
│ │ │ │ │ ├── delta_counter_gmp_expect.json
│ │ │ │ │ ├── exponential_histogram.json
│ │ │ │ │ ├── exponential_histogram_expect.json
│ │ │ │ │ ├── exponential_histogram_gmp_expect.json
│ │ │ │ │ ├── gauge.json
│ │ │ │ │ ├── gauge_expect.json
│ │ │ │ │ ├── gauge_gmp_expect.json
│ │ │ │ │ ├── gke_control_plane.json
│ │ │ │ │ ├── gke_control_plane_expect.json
│ │ │ │ │ ├── gke_metrics_agent.json
│ │ │ │ │ ├── gke_metrics_agent_expect.json
│ │ │ │ │ ├── google_managed_prometheus.json
│ │ │ │ │ ├── google_managed_prometheus_expect.json
│ │ │ │ │ ├── google_managed_prometheus_untyped_name_normalized_expect.json
│ │ │ │ │ ├── histogram.json
│ │ │ │ │ ├── histogram_expect.json
│ │ │ │ │ ├── histogram_gmp_expect.json
│ │ │ │ │ ├── multi_project.json
│ │ │ │ │ ├── multi_project_expected.json
│ │ │ │ │ ├── nonmonotonic_counter.json
│ │ │ │ │ ├── nonmonotonic_counter_expect.json
│ │ │ │ │ ├── nonmonotonic_counter_gmp_expect.json
│ │ │ │ │ ├── ops_agent_host_metrics.json
│ │ │ │ │ ├── ops_agent_host_metrics_expect.json
│ │ │ │ │ ├── ops_agent_self_metrics.json
│ │ │ │ │ ├── ops_agent_self_metrics_expect.json
│ │ │ │ │ ├── prometheus.json
│ │ │ │ │ ├── prometheus_empty_buckets.json
│ │ │ │ │ ├── prometheus_empty_buckets_expected.json
│ │ │ │ │ ├── prometheus_expect.json
│ │ │ │ │ ├── prometheus_stale.json
│ │ │ │ │ ├── prometheus_stale_expect.json
│ │ │ │ │ ├── prometheus_wal_expect.json
│ │ │ │ │ ├── summary.json
│ │ │ │ │ ├── summary_expect.json
│ │ │ │ │ ├── summary_gmp_expect.json
│ │ │ │ │ ├── untyped_gauge.json
│ │ │ │ │ ├── untyped_gauge_expect.json
│ │ │ │ │ ├── untyped_gauge_gmp_expect.json
│ │ │ │ │ ├── with_resource_filter.json
│ │ │ │ │ ├── with_resource_filter_expect.json
│ │ │ │ │ ├── workload_metrics.json
│ │ │ │ │ └── workload_metrics_expect.json
│ │ │ │ └── traces
│ │ │ │ │ ├── traces_basic.json
│ │ │ │ │ ├── traces_basic_expected.json
│ │ │ │ │ └── traces_user_agent_expected.json
│ │ │ └── gmp_config.yaml
│ │ ├── traces_integration_test.go
│ │ └── traces_test.go
│ ├── integrationtests.md
│ ├── internal
│ │ ├── datapointstorage
│ │ │ ├── benchmark_test.go
│ │ │ ├── datapointcache.go
│ │ │ └── datapointcache_test.go
│ │ ├── logsutil
│ │ │ └── logsutil.go
│ │ └── normalization
│ │ │ ├── benchmark_test.go
│ │ │ ├── disabled_normalizer.go
│ │ │ ├── standard_normalizer.go
│ │ │ └── types.go
│ ├── logs.go
│ ├── logs_test.go
│ ├── metrics.go
│ ├── metrics_test.go
│ ├── monitoredresource.go
│ ├── monitoredresource_test.go
│ ├── spandata.go
│ ├── spandata_test.go
│ ├── spansnapshot.go
│ ├── traces.go
│ ├── traces_test.go
│ └── version.go
├── metric
│ ├── README.md
│ ├── cloudmonitoring.go
│ ├── cloudmonitoring_test.go
│ ├── constants.go
│ ├── error.go
│ ├── example_test.go
│ ├── go.mod
│ ├── go.sum
│ ├── metric.go
│ ├── metric_test.go
│ ├── option.go
│ └── version.go
└── trace
│ ├── README.md
│ ├── cloudtrace.go
│ ├── cloudtrace_test.go
│ ├── go.mod
│ ├── go.sum
│ ├── trace.go
│ ├── trace_proto.go
│ ├── trace_proto_test.go
│ └── version.go
├── extension
└── googleclientauthextension
│ ├── README.md
│ ├── config.go
│ ├── config_test.go
│ ├── doc.go
│ ├── factory.go
│ ├── factory_test.go
│ ├── go.mod
│ ├── go.sum
│ ├── grpc.go
│ ├── grpc_test.go
│ ├── http.go
│ ├── http_test.go
│ └── testdata
│ ├── fake_creds.json
│ ├── fake_creds_no_project.json
│ └── fake_isa_creds.json
├── get_main_pkgs.sh
├── go.mod
├── go.sum
├── golangci.yml
├── internal
├── buildscripts
│ └── update-dep
├── cloudmock
│ ├── go.mod
│ ├── go.sum
│ ├── logs.go
│ ├── metrics.go
│ └── traces.go
└── resourcemapping
│ ├── go.mod
│ ├── go.sum
│ └── resourcemapping.go
├── propagator
├── README.md
├── go.mod
├── go.sum
├── propagator.go
└── propagator_test.go
├── renovate.json
├── tools
├── go.mod
├── go.sum
├── release.go
└── tools.go
└── verify_examples.sh
/.github/CODEOWNERS:
--------------------------------------------------------------------------------
1 | # Copyright 2023 Google LLC
2 | #
3 | # Licensed under the Apache License, Version 2.0 (the "License");
4 | # you may not use this file except in compliance with the License.
5 | # You may obtain a copy of the License at
6 | #
7 | # https://www.apache.org/licenses/LICENSE-2.0
8 | #
9 | # Unless required by applicable law or agreed to in writing, software
10 | # distributed under the License is distributed on an "AS IS" BASIS,
11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | # See the License for the specific language governing permissions and
13 | # limitations under the License.
14 |
15 | # Global owners
16 | * @GoogleCloudPlatform/opentelemetry-ops
17 |
--------------------------------------------------------------------------------
/.github/header-checker-lint.yml:
--------------------------------------------------------------------------------
1 | allowedCopyrightHolders:
2 | - Google LLC
3 | - OpenTelemetry Authors
4 | allowedLicenses:
5 | - Apache-2.0
6 | sourceFileExtensions:
7 | - go
8 | - sh
9 |
--------------------------------------------------------------------------------
/.github/trusted-contribution.yml:
--------------------------------------------------------------------------------
1 | # Config reference:
2 | # https://github.com/googleapis/repo-automation-bots/tree/main/packages/trusted-contribution
3 |
4 | trustedContributors:
5 | - renovate-bot
6 | annotations:
7 | # Automatically run Cloud Build tests
8 | - type: comment
9 | text: /gcbrun
10 |
--------------------------------------------------------------------------------
/.github/workflows/codeql-analysis.yml:
--------------------------------------------------------------------------------
1 | name: "CodeQL Analysis"
2 | permissions: read-all
3 | on:
4 | workflow_dispatch:
5 | schedule:
6 | # ┌───────────── minute (0 - 59)
7 | # │ ┌───────────── hour (0 - 23)
8 | # │ │ ┌───────────── day of the month (1 - 31)
9 | # │ │ │ ┌───────────── month (1 - 12 or JAN-DEC)
10 | # │ │ │ │ ┌───────────── day of the week (0 - 6 or SUN-SAT)
11 | # │ │ │ │ │
12 | # │ │ │ │ │
13 | # │ │ │ │ │
14 | # * * * * *
15 | - cron: '30 1 * * *'
16 | push:
17 | branches: [ main ]
18 | pull_request:
19 |
20 | jobs:
21 | CodeQL-Build:
22 | runs-on: ubuntu-latest
23 |
24 | steps:
25 | - name: Checkout repository
26 | uses: actions/checkout@v4
27 |
28 | # Initializes the CodeQL tools for scanning.
29 | - name: Initialize CodeQL
30 | uses: github/codeql-action/init@v3
31 | with:
32 | languages: go
33 |
34 | - name: Autobuild
35 | uses: github/codeql-action/autobuild@v3
36 |
37 | - name: Perform CodeQL Analysis
38 | uses: github/codeql-action/analyze@v3
39 |
40 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | Thumbs.db
3 |
4 | .combined-go.sum
5 | .tools/
6 | .idea/
7 | .vscode/
8 | *.iml
9 | *.so
10 | coverage.*
11 |
12 | /example/metric/collector/metrics
13 | /example/metric/collector/collector
14 | /example/metric/sdk/metrics
15 | /example/metric/sdk/sdk
16 | /example/metric/otlpgrpc/otlpgrpc
17 | /example/trace/otlpgrpc/otlpgrpc
18 | /example/metric/exponential_histogram/exponential_histogram
19 | /example/trace/otlphttp/otlphttp
20 | go.work
21 | go.work.sum
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Open-Telemetry Operations Exporters for Go
2 |
3 | [![Build Status][circleci-image]][circleci-url]
4 |
5 | This repository contains the source code of 2 packages of OpenTelemetry exporters to [Google Cloud Trace](https://cloud.google.com/trace) and [Google Cloud Monitoring](https://cloud.google.com/monitoring).
6 |
7 | To get started with instrumentation in Google Cloud, see [Generate traces and metrics with
8 | Go](https://cloud.google.com/stackdriver/docs/instrumentation/setup/go).
9 |
10 | To learn more about instrumentation and observability, including opinionated recommendations
11 | for Google Cloud Observability, visit [Instrumentation and
12 | observability](https://cloud.google.com/stackdriver/docs/instrumentation/overview).
13 |
14 | ## OpenTelemetry Google Cloud Trace Exporter
15 |
16 | OpenTelemetry Google Cloud Trace Exporter allow the user to send collected traces and spans to Google Cloud.
17 |
18 | See [README.md](https://github.com/GoogleCloudPlatform/opentelemetry-operations-go/blob/main/exporter/trace/README.md) for setup and usage information.
19 |
20 | ## OpenTelemetry Google Cloud Monitoring Exporter
21 |
22 | OpenTelemetry Google Cloud Monitoring Exporter allows the user to send collected metrics to Google Cloud Monitoring.
23 |
24 | See [README.md](https://github.com/GoogleCloudPlatform/opentelemetry-operations-go/blob/main/exporter/metric/README.md) for setup and usage information.
25 |
26 | [circleci-image]: https://circleci.com/gh/GoogleCloudPlatform/opentelemetry-operations-go.svg?style=shield
27 | [circleci-url]: https://circleci.com/gh/GoogleCloudPlatform/opentelemetry-operations-go
28 |
--------------------------------------------------------------------------------
/RELEASING.md:
--------------------------------------------------------------------------------
1 | # Release Process
2 |
3 | ## Pre-Release
4 |
5 | ```
6 | $ git fetch
7 | $ git checkout origin/main -b pre-release
8 | $ # ensure that version numbers in tools/release.go are what you want
9 | $ make prepare-release
10 | $ git commit -a
11 | $ git push -u origin HEAD
12 | $ # create a PR with a link to draft release notes
13 | $ # get the PR reviewed and merged
14 | ```
15 |
16 | ## Release
17 |
18 | ```
19 | $ # Ensure that the `origin` remote points to the main repository and NOT your fork
20 | $ git remote -v
21 | $ # do this after the pre-release PR is merged
22 | $ git fetch
23 | $ git checkout origin/main
24 | $ make release
25 | $ # make sure you don't have any stray tags lying around
26 | $ git push --tags --dry-run
27 | $ # manually inspect the dry run output to ensure correct tags will be pushed
28 | $ git push --tags
29 | ```
30 |
31 | ***IMPORTANT***: It is critical you use the same tag that you used in the Pre-Release step!
32 | Failure to do so will leave things in a broken state.
33 |
34 | ***IMPORTANT***: [There is currently no way to remove an incorrectly tagged version of a Go module](https://github.com/golang/go/issues/34189).
35 | It is critical you make sure the version you push upstream is correct.
36 | [Failure to do so will lead to minor emergencies and tough to work around](https://github.com/open-telemetry/opentelemetry-go/issues/331).
37 |
38 | ## Post-release
39 |
40 | * Verify the examples
41 | ```
42 | ./verify_examples.sh
43 | ```
44 |
45 | The script copies examples into a different directory removes any `replace` declarations in `go.mod` and builds them.
46 | This ensures they build with the published release, not the local copy.
47 |
48 | * Update the examples maintained outside this repo at https://github.com/GoogleCloudPlatform/golang-samples/tree/master/opentelemetry.
49 |
50 | * Update the collector exporter
51 |
--------------------------------------------------------------------------------
/SECURITY.md:
--------------------------------------------------------------------------------
1 | # Security Policy
2 |
3 | ## Supported Versions
4 |
5 | We support only the last minor version of each supported major release: bug fixes are released either as part of the next minor version or as an on-demand patch version. Independent of which version is next, all patch versions are cumulative, meaning that they represent the state of our main branch at the moment of the release. For instance, if the latest version is 0.10.0, bug fixes are released either as part of 0.11.0 or 0.10.1.
6 |
7 | Major releases are supported for 12 months after a new major version is released: https://opensource.google/documentation/policies/library-breaking-change.
8 |
9 | Security fixes are given priority and might be enough to cause a new version to be released.
10 |
11 | ## Reporting a Vulnerability
12 |
13 | In order for the vulnerability reports to reach maintainers as soon as possible, please use the `Report a vulnerability` button on the `Security` tab in the respective GitHub repository. It creates a private communication channel between the reporter and the maintainers.
14 |
15 |
--------------------------------------------------------------------------------
/cloudbuild-e2e-cloud-functions-gen2.yaml:
--------------------------------------------------------------------------------
1 | # Copyright 2023 Google LLC
2 | #
3 | # Licensed under the Apache License, Version 2.0 (the "License");
4 | # you may not use this file except in compliance with the License.
5 | # You may obtain a copy of the License at
6 | #
7 | # http://www.apache.org/licenses/LICENSE-2.0
8 | #
9 | # Unless required by applicable law or agreed to in writing, software
10 | # distributed under the License is distributed on an "AS IS" BASIS,
11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | # See the License for the specific language governing permissions and
13 | # limitations under the License.
14 |
15 | steps:
16 | # Vendor dependencies, and zip the code.
17 | - name: golang:1.23.8
18 | id: zip-code
19 | entrypoint: /bin/bash
20 | args:
21 | - '-c'
22 | - |
23 | apt-get update && \
24 | apt-get install zip --assume-yes && \
25 | cd e2e-test-server/cloud_functions/ && \
26 | go mod vendor && \
27 | zip -r function-source *
28 |
29 | # Run the test
30 | - name: $_TEST_RUNNER_IMAGE
31 | id: run-tests-cloudfunction
32 | dir: /
33 | env: ["PROJECT_ID=$PROJECT_ID"]
34 | args:
35 | - cloud-functions-gen2
36 | - --runtime=go123
37 | - --functionsource=/workspace/e2e-test-server/cloud_functions/function-source.zip
38 | - --entrypoint=HandleCloudFunction
39 |
40 | logsBucket: gs://opentelemetry-ops-e2e-cloud-build-logs
41 | substitutions:
42 | _TEST_RUNNER_IMAGE: us-central1-docker.pkg.dev/${PROJECT_ID}/e2e-testing/opentelemetry-operations-e2e-testing:0.20.1
43 | _TEST_SERVER_IMAGE: us-central1-docker.pkg.dev/${PROJECT_ID}/e2e-testing/opentelemetry-operations-go-e2e-test-server:${SHORT_SHA}
44 |
--------------------------------------------------------------------------------
/cloudbuild-e2e-cloud-run.yaml:
--------------------------------------------------------------------------------
1 | # Copyright 2023 Google LLC
2 | #
3 | # Licensed under the Apache License, Version 2.0 (the "License");
4 | # you may not use this file except in compliance with the License.
5 | # You may obtain a copy of the License at
6 | #
7 | # http://www.apache.org/licenses/LICENSE-2.0
8 | #
9 | # Unless required by applicable law or agreed to in writing, software
10 | # distributed under the License is distributed on an "AS IS" BASIS,
11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | # See the License for the specific language governing permissions and
13 | # limitations under the License.
14 |
15 | steps:
16 | # Wait for the image to exist
17 | - name: "docker"
18 | id: wait-for-image
19 | entrypoint: "sh"
20 | timeout: 3m
21 | env: ["_TEST_SERVER_IMAGE=${_TEST_SERVER_IMAGE}"]
22 | args:
23 | - e2e-test-server/wait-for-image.sh
24 |
25 | # Run the test
26 | - name: $_TEST_RUNNER_IMAGE
27 | id: run-tests-cloudrun
28 | dir: /
29 | timeout: 10m
30 | env: ["PROJECT_ID=$PROJECT_ID"]
31 | args:
32 | - cloud-run
33 | - --image=$_TEST_SERVER_IMAGE
34 |
35 | logsBucket: gs://opentelemetry-ops-e2e-cloud-build-logs
36 | substitutions:
37 | _TEST_RUNNER_IMAGE: us-central1-docker.pkg.dev/${PROJECT_ID}/e2e-testing/opentelemetry-operations-e2e-testing:0.20.1
38 | _TEST_SERVER_IMAGE: us-central1-docker.pkg.dev/${PROJECT_ID}/e2e-testing/opentelemetry-operations-go-e2e-test-server:${SHORT_SHA}
39 |
--------------------------------------------------------------------------------
/cloudbuild-e2e-gae-standard.yaml:
--------------------------------------------------------------------------------
1 | # Copyright 2024 Google LLC
2 | #
3 | # Licensed under the Apache License, Version 2.0 (the "License");
4 | # you may not use this file except in compliance with the License.
5 | # You may obtain a copy of the License at
6 | #
7 | # http://www.apache.org/licenses/LICENSE-2.0
8 | #
9 | # Unless required by applicable law or agreed to in writing, software
10 | # distributed under the License is distributed on an "AS IS" BASIS,
11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | # See the License for the specific language governing permissions and
13 | # limitations under the License.
14 |
15 | steps:
16 | # Vendor dependencies, and zip the code.
17 | - name: golang:1.23.8
18 | id: zip-code
19 | entrypoint: /bin/bash
20 | args:
21 | - '-c'
22 | - |
23 | apt-get update && \
24 | apt-get install zip --assume-yes && \
25 | cd e2e-test-server/ && \
26 | go mod vendor && \
27 | zip -r appsource *
28 |
29 | # Run the test
30 | - name: $_TEST_RUNNER_IMAGE
31 | id: run-tests-gae-standard
32 | dir: /
33 | env: ["PROJECT_ID=$PROJECT_ID"]
34 | args:
35 | - gae-standard
36 | - --runtime=go123
37 | - --appsource=/workspace/e2e-test-server/appsource.zip
38 | logsBucket: gs://opentelemetry-ops-e2e-cloud-build-logs
39 | substitutions:
40 | _TEST_RUNNER_IMAGE: us-central1-docker.pkg.dev/${PROJECT_ID}/e2e-testing/opentelemetry-operations-e2e-testing:0.20.1
41 | _TEST_SERVER_IMAGE: us-central1-docker.pkg.dev/${PROJECT_ID}/e2e-testing/opentelemetry-operations-go-e2e-test-server:${SHORT_SHA}
42 |
--------------------------------------------------------------------------------
/cloudbuild-e2e-gae.yaml:
--------------------------------------------------------------------------------
1 | # Copyright 2023 Google LLC
2 | #
3 | # Licensed under the Apache License, Version 2.0 (the "License");
4 | # you may not use this file except in compliance with the License.
5 | # You may obtain a copy of the License at
6 | #
7 | # http://www.apache.org/licenses/LICENSE-2.0
8 | #
9 | # Unless required by applicable law or agreed to in writing, software
10 | # distributed under the License is distributed on an "AS IS" BASIS,
11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | # See the License for the specific language governing permissions and
13 | # limitations under the License.
14 |
15 | steps:
16 | # Wait for the image to exist
17 | - name: "docker"
18 | id: wait-for-image
19 | entrypoint: "sh"
20 | timeout: 3m
21 | env: ["_TEST_SERVER_IMAGE=${_TEST_SERVER_IMAGE}"]
22 | args:
23 | - e2e-test-server/wait-for-image.sh
24 |
25 | # Run the test
26 | - name: $_TEST_RUNNER_IMAGE
27 | id: run-tests-gae
28 | dir: /
29 | env: ["PROJECT_ID=$PROJECT_ID"]
30 | args:
31 | - gae
32 | - --image=$_TEST_SERVER_IMAGE
33 | - --runtime=go123
34 |
35 | logsBucket: gs://opentelemetry-ops-e2e-cloud-build-logs
36 | substitutions:
37 | _TEST_RUNNER_IMAGE: us-central1-docker.pkg.dev/${PROJECT_ID}/e2e-testing/opentelemetry-operations-e2e-testing:0.20.1
38 | _TEST_SERVER_IMAGE: us-central1-docker.pkg.dev/${PROJECT_ID}/e2e-testing/opentelemetry-operations-go-e2e-test-server:${SHORT_SHA}
39 |
--------------------------------------------------------------------------------
/cloudbuild-e2e-gce.yaml:
--------------------------------------------------------------------------------
1 | # Copyright 2021 Google LLC
2 | #
3 | # Licensed under the Apache License, Version 2.0 (the "License");
4 | # you may not use this file except in compliance with the License.
5 | # You may obtain a copy of the License at
6 | #
7 | # http://www.apache.org/licenses/LICENSE-2.0
8 | #
9 | # Unless required by applicable law or agreed to in writing, software
10 | # distributed under the License is distributed on an "AS IS" BASIS,
11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | # See the License for the specific language governing permissions and
13 | # limitations under the License.
14 |
15 | steps:
16 | # Wait for the image to exist
17 | - name: "docker"
18 | id: wait-for-image
19 | entrypoint: "sh"
20 | timeout: 3m
21 | env: ["_TEST_SERVER_IMAGE=${_TEST_SERVER_IMAGE}"]
22 | args:
23 | - e2e-test-server/wait-for-image.sh
24 |
25 | # Run the test
26 | - name: $_TEST_RUNNER_IMAGE
27 | id: run-tests-gce
28 | dir: /
29 | env: ["PROJECT_ID=$PROJECT_ID"]
30 | args:
31 | - gce
32 | - --image=$_TEST_SERVER_IMAGE
33 |
34 | logsBucket: gs://opentelemetry-ops-e2e-cloud-build-logs
35 | substitutions:
36 | _TEST_RUNNER_IMAGE: us-central1-docker.pkg.dev/${PROJECT_ID}/e2e-testing/opentelemetry-operations-e2e-testing:0.20.1
37 | _TEST_SERVER_IMAGE: us-central1-docker.pkg.dev/${PROJECT_ID}/e2e-testing/opentelemetry-operations-go-e2e-test-server:${SHORT_SHA}
38 |
--------------------------------------------------------------------------------
/cloudbuild-e2e-gke.yaml:
--------------------------------------------------------------------------------
1 | # Copyright 2021 Google LLC
2 | #
3 | # Licensed under the Apache License, Version 2.0 (the "License");
4 | # you may not use this file except in compliance with the License.
5 | # You may obtain a copy of the License at
6 | #
7 | # http://www.apache.org/licenses/LICENSE-2.0 #
8 | # Unless required by applicable law or agreed to in writing, software
9 | # distributed under the License is distributed on an "AS IS" BASIS,
10 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11 | # See the License for the specific language governing permissions and
12 | # limitations under the License.
13 |
14 | steps:
15 | # Wait for the image to exist
16 | - name: "docker"
17 | id: wait-for-image
18 | entrypoint: "sh"
19 | timeout: 3m
20 | env: ["_TEST_SERVER_IMAGE=${_TEST_SERVER_IMAGE}"]
21 | args:
22 | - e2e-test-server/wait-for-image.sh
23 |
24 | # Run the test
25 | - name: $_TEST_RUNNER_IMAGE
26 | id: run-tests-gke
27 | dir: /
28 | env: ["PROJECT_ID=$PROJECT_ID"]
29 | args:
30 | - gke
31 | - --image=$_TEST_SERVER_IMAGE
32 |
33 | logsBucket: gs://opentelemetry-ops-e2e-cloud-build-logs
34 | substitutions:
35 | _TEST_RUNNER_IMAGE: us-central1-docker.pkg.dev/${PROJECT_ID}/e2e-testing/opentelemetry-operations-e2e-testing:0.20.1
36 | _TEST_SERVER_IMAGE: us-central1-docker.pkg.dev/${PROJECT_ID}/e2e-testing/opentelemetry-operations-go-e2e-test-server:${SHORT_SHA}
37 |
--------------------------------------------------------------------------------
/cloudbuild-e2e-image.yaml:
--------------------------------------------------------------------------------
1 | # Copyright 2021 Google LLC
2 | #
3 | # Licensed under the Apache License, Version 2.0 (the "License");
4 | # you may not use this file except in compliance with the License.
5 | # You may obtain a copy of the License at
6 | #
7 | # http://www.apache.org/licenses/LICENSE-2.0
8 | #
9 | # Unless required by applicable law or agreed to in writing, software
10 | # distributed under the License is distributed on an "AS IS" BASIS,
11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | # See the License for the specific language governing permissions and
13 | # limitations under the License.
14 |
15 | steps:
16 | - name: docker
17 | entrypoint: "sh"
18 | args:
19 | - -c
20 | - |
21 | if docker manifest inspect ${_TEST_SERVER_IMAGE} > /dev/null; then
22 | echo "Image already exists, will skip building"
23 | exit
24 | fi
25 | docker build --tag=${_TEST_SERVER_IMAGE} --file=e2e-test-server/Dockerfile .
26 | docker push ${_TEST_SERVER_IMAGE}
27 |
28 | logsBucket: gs://opentelemetry-ops-e2e-cloud-build-logs
29 | substitutions:
30 | _TEST_SERVER_IMAGE: ${_TEST_SERVER_IMAGE_NAME}:${SHORT_SHA}
31 | _TEST_SERVER_IMAGE_NAME: us-central1-docker.pkg.dev/${PROJECT_ID}/e2e-testing/opentelemetry-operations-go-e2e-test-server
32 |
--------------------------------------------------------------------------------
/cloudbuild-e2e-local.yaml:
--------------------------------------------------------------------------------
1 | # Copyright 2021 Google LLC
2 | #
3 | # Licensed under the Apache License, Version 2.0 (the "License");
4 | # you may not use this file except in compliance with the License.
5 | # You may obtain a copy of the License at
6 | #
7 | # http://www.apache.org/licenses/LICENSE-2.0
8 | #
9 | # Unless required by applicable law or agreed to in writing, software
10 | # distributed under the License is distributed on an "AS IS" BASIS,
11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | # See the License for the specific language governing permissions and
13 | # limitations under the License.
14 |
15 | steps:
16 | # Wait for the image to exist
17 | - name: "docker"
18 | id: wait-for-image
19 | entrypoint: "sh"
20 | timeout: 3m
21 | env: ["_TEST_SERVER_IMAGE=${_TEST_SERVER_IMAGE}"]
22 | args:
23 | - e2e-test-server/wait-for-image.sh
24 |
25 | - name: "docker"
26 | id: pull-image
27 | args:
28 | - pull
29 | - $_TEST_SERVER_IMAGE
30 |
31 | # Run the test
32 | - name: $_TEST_RUNNER_IMAGE
33 | id: run-tests-local
34 | dir: /
35 | env: ["PROJECT_ID=$PROJECT_ID"]
36 | args:
37 | - local
38 | - --image=$_TEST_SERVER_IMAGE
39 | - --network=cloudbuild
40 |
41 | logsBucket: gs://opentelemetry-ops-e2e-cloud-build-logs
42 | substitutions:
43 | _TEST_RUNNER_IMAGE: us-central1-docker.pkg.dev/${PROJECT_ID}/e2e-testing/opentelemetry-operations-e2e-testing:0.20.1
44 | _TEST_SERVER_IMAGE: us-central1-docker.pkg.dev/${PROJECT_ID}/e2e-testing/opentelemetry-operations-go-e2e-test-server:${SHORT_SHA}
45 |
--------------------------------------------------------------------------------
/cloudbuild-integration-tests.yaml:
--------------------------------------------------------------------------------
1 | # Copyright 2021 Google LLC
2 | #
3 | # Licensed under the Apache License, Version 2.0 (the "License");
4 | # you may not use this file except in compliance with the License.
5 | # You may obtain a copy of the License at
6 | #
7 | # http://www.apache.org/licenses/LICENSE-2.0
8 | #
9 | # Unless required by applicable law or agreed to in writing, software
10 | # distributed under the License is distributed on an "AS IS" BASIS,
11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | # See the License for the specific language governing permissions and
13 | # limitations under the License.
14 |
15 | steps:
16 | - name: golang:1.23.8
17 | env: ["SECOND_PROJECT_ID=opentelemetry-ops-e2e-2"]
18 | args: ["make", "integrationtest"]
19 | logsBucket: gs://opentelemetry-ops-e2e-cloud-build-logs
20 |
--------------------------------------------------------------------------------
/detectors/gcp/README.md:
--------------------------------------------------------------------------------
1 | # GCP Resource detection library
2 |
3 | This is a library intended to be used by Upstream OpenTelemetry resource detectors. It exists within this repository to allow for integration testing of the detection functions in real GCP environments.
4 |
--------------------------------------------------------------------------------
/detectors/gcp/app_engine.go:
--------------------------------------------------------------------------------
1 | // Copyright 2022 Google LLC
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // https://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | package gcp
16 |
17 | import "context"
18 |
19 | const (
20 | // See https://cloud.google.com/appengine/docs/flexible/python/migrating#modules
21 | // for the environment variables available in GAE environments.
22 | gaeServiceEnv = "GAE_SERVICE"
23 | gaeVersionEnv = "GAE_VERSION"
24 | gaeInstanceEnv = "GAE_INSTANCE"
25 | gaeEnv = "GAE_ENV"
26 | gaeStandard = "standard"
27 | )
28 |
29 | func (d *Detector) onAppEngineStandard() bool {
30 | // See https://cloud.google.com/appengine/docs/standard/go111/runtime#environment_variables.
31 | env, found := d.os.LookupEnv(gaeEnv)
32 | return found && env == gaeStandard
33 | }
34 |
35 | func (d *Detector) onAppEngine() bool {
36 | _, found := d.os.LookupEnv(gaeServiceEnv)
37 | return found
38 | }
39 |
40 | // AppEngineServiceName returns the service name of the app engine service.
41 | func (d *Detector) AppEngineServiceName() (string, error) {
42 | if name, found := d.os.LookupEnv(gaeServiceEnv); found {
43 | return name, nil
44 | }
45 | return "", errEnvVarNotFound
46 | }
47 |
48 | // AppEngineServiceVersion returns the service version of the app engine service.
49 | func (d *Detector) AppEngineServiceVersion() (string, error) {
50 | if version, found := d.os.LookupEnv(gaeVersionEnv); found {
51 | return version, nil
52 | }
53 | return "", errEnvVarNotFound
54 | }
55 |
56 | // AppEngineServiceInstance returns the service instance of the app engine service.
57 | func (d *Detector) AppEngineServiceInstance() (string, error) {
58 | if instanceID, found := d.os.LookupEnv(gaeInstanceEnv); found {
59 | return instanceID, nil
60 | }
61 | return "", errEnvVarNotFound
62 | }
63 |
64 | // AppEngineFlexAvailabilityZoneAndRegion returns the zone and region in which this program is running.
65 | func (d *Detector) AppEngineFlexAvailabilityZoneAndRegion() (string, string, error) {
66 | // The GCE metadata server is available on App Engine Flex.
67 | return d.GCEAvailabilityZoneAndRegion()
68 | }
69 |
70 | // AppEngineStandardAvailabilityZone returns the zone the app engine service is running in.
71 | func (d *Detector) AppEngineStandardAvailabilityZone() (string, error) {
72 | return d.metadata.ZoneWithContext(context.TODO())
73 | }
74 |
75 | // AppEngineStandardCloudRegion returns the region the app engine service is running in.
76 | func (d *Detector) AppEngineStandardCloudRegion() (string, error) {
77 | return d.FaaSCloudRegion()
78 | }
79 |
--------------------------------------------------------------------------------
/detectors/gcp/bms.go:
--------------------------------------------------------------------------------
1 | // Copyright 2024 Google LLC
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // https://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | package gcp
16 |
17 | const (
18 | bmsProjectIDEnv = "BMS_PROJECT_ID"
19 | bmsRegionEnv = "BMS_REGION"
20 | bmsInstanceIDEnv = "BMS_INSTANCE_ID"
21 | )
22 |
23 | // onBareMetalSolution checks if the code is running on a Google Cloud Bare Metal Solution (BMS) by verifying
24 | // the presence and non-empty values of BMS_PROJECT_ID, BMS_REGION, and BMS_INSTANCE_ID environment variables.
25 | // For more information on Google Cloud Bare Metal Solution, see: https://cloud.google.com/bare-metal/docs
26 | func (d *Detector) onBareMetalSolution() bool {
27 | projectID, projectIDExists := d.os.LookupEnv(bmsProjectIDEnv)
28 | region, regionExists := d.os.LookupEnv(bmsRegionEnv)
29 | instanceID, instanceIDExists := d.os.LookupEnv(bmsInstanceIDEnv)
30 | return projectIDExists && regionExists && instanceIDExists && projectID != "" && region != "" && instanceID != ""
31 | }
32 |
33 | // BareMetalSolutionInstanceID returns the instance ID from the BMS_INSTANCE_ID environment variable.
34 | func (d *Detector) BareMetalSolutionInstanceID() (string, error) {
35 | if instanceID, found := d.os.LookupEnv(bmsInstanceIDEnv); found {
36 | return instanceID, nil
37 | }
38 | return "", errEnvVarNotFound
39 | }
40 |
41 | // BareMetalSolutionCloudRegion returns the region from the BMS_REGION environment variable.
42 | func (d *Detector) BareMetalSolutionCloudRegion() (string, error) {
43 | if region, found := d.os.LookupEnv(bmsRegionEnv); found {
44 | return region, nil
45 | }
46 | return "", errEnvVarNotFound
47 | }
48 |
49 | // BareMetalSolutionProjectID returns the project ID from the BMS_PROJECT_ID environment variable.
50 | func (d *Detector) BareMetalSolutionProjectID() (string, error) {
51 | if project, found := d.os.LookupEnv(bmsProjectIDEnv); found {
52 | return project, nil
53 | }
54 | return "", errEnvVarNotFound
55 | }
56 |
--------------------------------------------------------------------------------
/detectors/gcp/bms_test.go:
--------------------------------------------------------------------------------
1 | // Copyright 2024 Google LLC
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // https://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | package gcp
16 |
17 | import (
18 | "testing"
19 |
20 | "github.com/stretchr/testify/assert"
21 | )
22 |
23 | func TestBareMetalSolutionInstanceID(t *testing.T) {
24 | d := NewTestDetector(&FakeMetadataTransport{}, &FakeOSProvider{
25 | Vars: map[string]string{
26 | bmsInstanceIDEnv: "my-host-123",
27 | },
28 | })
29 | instanceID, err := d.BareMetalSolutionInstanceID()
30 | assert.NoError(t, err)
31 | assert.Equal(t, "my-host-123", instanceID)
32 | }
33 |
34 | func TestBareMetalSolutionInstanceIDErr(t *testing.T) {
35 | d := NewTestDetector(&FakeMetadataTransport{}, &FakeOSProvider{
36 | Vars: map[string]string{},
37 | })
38 | instanceID, err := d.BareMetalSolutionInstanceID()
39 | assert.Error(t, err)
40 | assert.Equal(t, "", instanceID)
41 | }
42 |
43 | func TestBareMetalSolutionCloudRegion(t *testing.T) {
44 | d := NewTestDetector(&FakeMetadataTransport{}, &FakeOSProvider{
45 | Vars: map[string]string{
46 | bmsRegionEnv: "us-central1",
47 | },
48 | })
49 | region, err := d.BareMetalSolutionCloudRegion()
50 | assert.NoError(t, err)
51 | assert.Equal(t, "us-central1", region)
52 | }
53 |
54 | func TestBareMetalSolutionCloudRegionErr(t *testing.T) {
55 | d := NewTestDetector(&FakeMetadataTransport{}, &FakeOSProvider{
56 | Vars: map[string]string{},
57 | })
58 | region, err := d.BareMetalSolutionCloudRegion()
59 | assert.Error(t, err)
60 | assert.Equal(t, "", region)
61 | }
62 |
63 | func TestBareMetalSolutionProjectID(t *testing.T) {
64 | d := NewTestDetector(&FakeMetadataTransport{}, &FakeOSProvider{
65 | Vars: map[string]string{
66 | bmsProjectIDEnv: "my-test-project",
67 | },
68 | })
69 | projectID, err := d.BareMetalSolutionProjectID()
70 | assert.NoError(t, err)
71 | assert.Equal(t, "my-test-project", projectID)
72 | }
73 |
74 | func TestBareMetalSolutionProjectIDErr(t *testing.T) {
75 | d := NewTestDetector(&FakeMetadataTransport{}, &FakeOSProvider{
76 | Vars: map[string]string{},
77 | })
78 | projectID, err := d.BareMetalSolutionProjectID()
79 | assert.Error(t, err)
80 | assert.Equal(t, "", projectID)
81 | }
82 |
--------------------------------------------------------------------------------
/detectors/gcp/detector.go:
--------------------------------------------------------------------------------
1 | // Copyright 2022 Google LLC
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // https://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | package gcp
16 |
17 | import (
18 | "context"
19 | "errors"
20 | "os"
21 | "strings"
22 |
23 | "cloud.google.com/go/compute/metadata"
24 | )
25 |
26 | var errEnvVarNotFound = errors.New("environment variable not found")
27 |
28 | // NewDetector returns a *Detector which can get detect the platform,
29 | // and fetch attributes of the platform on which it is running.
30 | func NewDetector() *Detector {
31 | return &Detector{metadata: metadata.NewClient(nil), os: realOSProvider{}}
32 | }
33 |
34 | type Platform int64
35 |
36 | const (
37 | UnknownPlatform Platform = iota
38 | GKE
39 | GCE
40 | CloudRun
41 | CloudRunJob
42 | CloudFunctions
43 | AppEngineStandard
44 | AppEngineFlex
45 | BareMetalSolution
46 | )
47 |
48 | // CloudPlatform returns the platform on which this program is running.
49 | func (d *Detector) CloudPlatform() Platform {
50 | switch {
51 | case d.onBareMetalSolution():
52 | return BareMetalSolution
53 | case d.onGKE():
54 | return GKE
55 | case d.onCloudFunctions():
56 | return CloudFunctions
57 | case d.onCloudRun():
58 | return CloudRun
59 | case d.onCloudRunJob():
60 | return CloudRunJob
61 | case d.onAppEngineStandard():
62 | return AppEngineStandard
63 | case d.onAppEngine():
64 | return AppEngineFlex
65 | case d.onGCE():
66 | return GCE
67 | }
68 | return UnknownPlatform
69 | }
70 |
71 | // ProjectID returns the ID of the project in which this program is running.
72 | func (d *Detector) ProjectID() (string, error) {
73 | // N.B. d.metadata.ProjectIDWithContext(context.TODO()) is cached globally, so if we use it here it's untestable.
74 | s, err := d.metadata.GetWithContext(context.TODO(), "project/project-id")
75 | return strings.TrimSpace(s), err
76 | }
77 |
78 | // instanceID returns the ID of the project in which this program is running.
79 | func (d *Detector) instanceID() (string, error) {
80 | // N.B. d.metadata.InstanceIDWithContext(context.TODO()) is cached globally, so if we use it here it's untestable.
81 | s, err := d.metadata.GetWithContext(context.TODO(), "instance/id")
82 | return strings.TrimSpace(s), err
83 | }
84 |
85 | // Detector collects resource information for all GCP platforms.
86 | type Detector struct {
87 | metadata *metadata.Client
88 | os osProvider
89 | }
90 |
91 | // osProvider contains the subset of the os package functions used by.
92 | type osProvider interface {
93 | LookupEnv(string) (string, bool)
94 | }
95 |
96 | // realOSProvider uses the os package to lookup env vars.
97 | type realOSProvider struct{}
98 |
99 | func (realOSProvider) LookupEnv(env string) (string, bool) {
100 | return os.LookupEnv(env)
101 | }
102 |
--------------------------------------------------------------------------------
/detectors/gcp/gke.go:
--------------------------------------------------------------------------------
1 | // Copyright 2022 Google LLC
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // https://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | package gcp
16 |
17 | import (
18 | "context"
19 | "fmt"
20 | "strings"
21 | )
22 |
23 | const (
24 | // If the kubernetes.default.svc service exists in the cluster,
25 | // then the KUBERNETES_SERVICE_HOST env var will be populated.
26 | // Use this as an indication that we are running on kubernetes.
27 | k8sServiceHostEnv = "KUBERNETES_SERVICE_HOST"
28 | // See the available GKE metadata:
29 | // https://cloud.google.com/kubernetes-engine/docs/concepts/workload-identity#instance_metadata
30 | clusterNameMetadataAttr = "cluster-name"
31 | clusterLocationMetadataAttr = "cluster-location"
32 | )
33 |
34 | func (d *Detector) onGKE() bool {
35 | // Check if we are on k8s first
36 | _, found := d.os.LookupEnv(k8sServiceHostEnv)
37 | if !found {
38 | return false
39 | }
40 | // If we are on k8s, make sure that we are actually on GKE, and not a
41 | // different managed k8s platform.
42 | _, err := d.metadata.InstanceAttributeValueWithContext(context.TODO(), clusterLocationMetadataAttr)
43 | return err == nil
44 | }
45 |
46 | // GKEHostID returns the instance ID of the instance on which this program is running.
47 | func (d *Detector) GKEHostID() (string, error) {
48 | return d.GCEHostID()
49 | }
50 |
51 | // GKEClusterName returns the name if the GKE cluster in which this program is running.
52 | func (d *Detector) GKEClusterName() (string, error) {
53 | return d.metadata.InstanceAttributeValueWithContext(context.TODO(), clusterNameMetadataAttr)
54 | }
55 |
56 | type LocationType int64
57 |
58 | const (
59 | UndefinedLocation LocationType = iota
60 | Zone
61 | Region
62 | )
63 |
64 | // GKEAvailabilityZoneOrRegion returns the location of the cluster and whether the cluster is zonal or regional.
65 | func (d *Detector) GKEAvailabilityZoneOrRegion() (string, LocationType, error) {
66 | clusterLocation, err := d.metadata.InstanceAttributeValueWithContext(context.TODO(), clusterLocationMetadataAttr)
67 | if err != nil {
68 | return "", UndefinedLocation, err
69 | }
70 | switch strings.Count(clusterLocation, "-") {
71 | case 1:
72 | return clusterLocation, Region, nil
73 | case 2:
74 | return clusterLocation, Zone, nil
75 | default:
76 | return "", UndefinedLocation, fmt.Errorf("unrecognized format for cluster location: %v", clusterLocation)
77 | }
78 | }
79 |
--------------------------------------------------------------------------------
/detectors/gcp/go.mod:
--------------------------------------------------------------------------------
1 | module github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp
2 |
3 | go 1.23.0
4 |
5 | require (
6 | cloud.google.com/go/compute/metadata v0.7.0
7 | github.com/stretchr/testify v1.10.0
8 | )
9 |
10 | require (
11 | github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
12 | github.com/kr/pretty v0.3.1 // indirect
13 | github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
14 | github.com/rogpeppe/go-internal v1.13.1 // indirect
15 | golang.org/x/sys v0.33.0 // indirect
16 | gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect
17 | gopkg.in/yaml.v3 v3.0.1 // indirect
18 | )
19 |
--------------------------------------------------------------------------------
/detectors/gcp/go.sum:
--------------------------------------------------------------------------------
1 | cloud.google.com/go/compute/metadata v0.7.0 h1:PBWF+iiAerVNe8UCHxdOt6eHLVc3ydFeOCw78U8ytSU=
2 | cloud.google.com/go/compute/metadata v0.7.0/go.mod h1:j5MvL9PprKL39t166CoB1uVHfQMs4tFQZZcKwksXUjo=
3 | github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
4 | github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM=
5 | github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
6 | github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
7 | github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
8 | github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
9 | github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
10 | github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
11 | github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
12 | github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
13 | github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
14 | github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
15 | github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA=
16 | github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U=
17 | github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
18 | github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs=
19 | github.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII=
20 | github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o=
21 | github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
22 | github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
23 | golang.org/x/sys v0.33.0 h1:q3i8TbbEz+JRD9ywIRlyRAQbM0qF7hu24q3teo2hbuw=
24 | golang.org/x/sys v0.33.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
25 | gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
26 | gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
27 | gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
28 | gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
29 | gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
30 |
--------------------------------------------------------------------------------
/doc.go:
--------------------------------------------------------------------------------
1 | // Copyright 2020 Google LLC
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | package operations
16 |
--------------------------------------------------------------------------------
/docs/code-of-conduct.md:
--------------------------------------------------------------------------------
1 | # Google Open Source Community Guidelines
2 |
3 | At Google, we recognize and celebrate the creativity and collaboration of open
4 | source contributors and the diversity of skills, experiences, cultures, and
5 | opinions they bring to the projects and communities they participate in.
6 |
7 | Every one of Google's open source projects and communities are inclusive
8 | environments, based on treating all individuals respectfully, regardless of
9 | gender identity and expression, sexual orientation, disabilities,
10 | neurodiversity, physical appearance, body size, ethnicity, nationality, race,
11 | age, religion, or similar personal characteristic.
12 |
13 | We value diverse opinions, but we value respectful behavior more.
14 |
15 | Respectful behavior includes:
16 |
17 | * Being considerate, kind, constructive, and helpful.
18 | * Not engaging in demeaning, discriminatory, harassing, hateful, sexualized, or
19 | physically threatening behavior, speech, and imagery.
20 | * Not engaging in unwanted physical contact.
21 |
22 | Some Google open source projects [may adopt][] an explicit project code of
23 | conduct, which may have additional detailed expectations for participants. Most
24 | of those projects will use our [modified Contributor Covenant][].
25 |
26 | [may adopt]: https://opensource.google/docs/releasing/preparing/#conduct
27 | [modified Contributor Covenant]: https://opensource.google/docs/releasing/template/CODE_OF_CONDUCT/
28 |
29 | ## Resolve peacefully
30 |
31 | We do not believe that all conflict is necessarily bad; healthy debate and
32 | disagreement often yields positive results. However, it is never okay to be
33 | disrespectful.
34 |
35 | If you see someone behaving disrespectfully, you are encouraged to address the
36 | behavior directly with those involved. Many issues can be resolved quickly and
37 | easily, and this gives people more control over the outcome of their dispute.
38 | If you are unable to resolve the matter for any reason, or if the behavior is
39 | threatening or harassing, report it. We are dedicated to providing an
40 | environment where participants feel welcome and safe.
41 |
42 | ## Reporting problems
43 |
44 | Some Google open source projects may adopt a project-specific code of conduct.
45 | In those cases, a Google employee will be identified as the Project Steward,
46 | who will receive and handle reports of code of conduct violations. In the event
47 | that a project hasn’t identified a Project Steward, you can report problems by
48 | emailing opensource@google.com.
49 |
50 | We will investigate every complaint, but you may not receive a direct response.
51 | We will use our discretion in determining when and how to follow up on reported
52 | incidents, which may range from not taking action to permanent expulsion from
53 | the project and project-sponsored spaces. We will notify the accused of the
54 | report and provide them an opportunity to discuss it before any action is
55 | taken. The identity of the reporter will be omitted from the details of the
56 | report supplied to the accused. In potentially harmful situations, such as
57 | ongoing harassment or threats to anyone's safety, we may take action without
58 | notice.
59 |
60 | *This document was adapted from the [IndieWeb Code of Conduct][] and can also
61 | be found at .*
62 |
63 | [IndieWeb Code of Conduct]: https://indieweb.org/code-of-conduct
64 |
--------------------------------------------------------------------------------
/docs/contributing.md:
--------------------------------------------------------------------------------
1 | # How to Contribute
2 |
3 | We'd love to accept your patches and contributions to this project. There are
4 | just a few small guidelines you need to follow.
5 |
6 | ## Contributor License Agreement
7 |
8 | Contributions to this project must be accompanied by a Contributor License
9 | Agreement. You (or your employer) retain the copyright to your contribution;
10 | this simply gives us permission to use and redistribute your contributions as
11 | part of the project. Head over to to see
12 | your current agreements on file or to sign a new one.
13 |
14 | You generally only need to submit a CLA once, so if you've already submitted one
15 | (even if it was for a different project), you probably don't need to do it
16 | again.
17 |
18 | ## Code reviews
19 |
20 | All submissions, including submissions by project members, require review. We
21 | use GitHub pull requests for this purpose. Consult
22 | [GitHub Help](https://help.github.com/articles/about-pull-requests/) for more
23 | information on using pull requests.
24 |
25 | ## Community Guidelines
26 |
27 | This project follows [Google's Open Source Community
28 | Guidelines](https://opensource.google/conduct/).
29 |
--------------------------------------------------------------------------------
/e2e-test-server/Dockerfile:
--------------------------------------------------------------------------------
1 | # Copyright 2021 Google LLC
2 | #
3 | # Licensed under the Apache License, Version 2.0 (the "License");
4 | # you may not use this file except in compliance with the License.
5 | # You may obtain a copy of the License at
6 | #
7 | # http://www.apache.org/licenses/LICENSE-2.0
8 | #
9 | # Unless required by applicable law or agreed to in writing, software
10 | # distributed under the License is distributed on an "AS IS" BASIS,
11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | # See the License for the specific language governing permissions and
13 | # limitations under the License.
14 |
15 | FROM golang:1.23.8 as builder
16 |
17 | WORKDIR /workspace/e2e-test-server/
18 |
19 | # In-repo dependencies
20 | COPY exporter/trace/ ../exporter/trace/
21 | COPY internal/resourcemapping/ ../internal/resourcemapping
22 | COPY detectors/gcp/ ../detectors/gcp/
23 |
24 | # cache deps before copying source so that source changes don't invalidate our
25 | # downloaded layer and we don't need to re-download as much.
26 | COPY e2e-test-server/go.mod e2e-test-server/go.sum ./
27 | RUN go mod download
28 |
29 | # Copy the go source
30 | COPY e2e-test-server/app.go ./
31 | COPY e2e-test-server/scenarios/ scenarios/
32 | COPY e2e-test-server/endtoendserver/ endtoendserver/
33 |
34 | # Build
35 | RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -a -o app app.go
36 |
37 | # Use distroless as minimal base image to package the manager binary
38 | # Refer to https://github.com/GoogleContainerTools/distroless for more details
39 | FROM gcr.io/distroless/static
40 | WORKDIR /
41 | COPY --from=builder /workspace/e2e-test-server/app ./
42 |
43 | ENTRYPOINT ["/app"]
44 |
--------------------------------------------------------------------------------
/e2e-test-server/README.md:
--------------------------------------------------------------------------------
1 | # E2E Test Server
2 |
3 | This unpublished package is for e2e testing. Build a docker image from
4 | the repository root:
5 |
6 | ```bash
7 | docker build --tag=ops-go-e2e:local --file=e2e-test-server/Dockerfile .
8 | ```
9 |
10 | and run it with the test server (not yet published).
11 |
--------------------------------------------------------------------------------
/e2e-test-server/app.go:
--------------------------------------------------------------------------------
1 | // Copyright 2021 Google LLC
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | package main
16 |
17 | import (
18 | "context"
19 | "log"
20 | "os"
21 | "os/signal"
22 | "time"
23 |
24 | "github.com/GoogleCloudPlatform/opentelemetry-operations-go/e2e-test-server/endtoendserver"
25 | )
26 |
27 | func main() {
28 | runCtx, cancelRunning := context.WithCancel(context.Background())
29 |
30 | // Gracefully close on SIGINT
31 | interrupted := make(chan os.Signal, 1)
32 | signal.Notify(interrupted, os.Interrupt)
33 | go func() {
34 | <-interrupted
35 | log.Println("Received interrupt signal, shutting down.")
36 | cancelRunning()
37 | }()
38 |
39 | server, err := endtoendserver.New()
40 | if err != nil {
41 | log.Fatalf("Could not initialize server: %v", err)
42 | }
43 |
44 | if err = server.Run(runCtx); err != nil {
45 | log.Printf("Unexpected error occurred: %v", err)
46 | }
47 |
48 | log.Print("Shutting down")
49 | shutdownCtx, cancelShutdown := context.WithTimeout(context.Background(), 10*time.Second)
50 | defer cancelShutdown()
51 | if err = server.Shutdown(shutdownCtx); err != nil {
52 | log.Printf("Unexpected error occurred: %v", err)
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/e2e-test-server/cloud_functions/cloud_functions.go:
--------------------------------------------------------------------------------
1 | // Copyright 2023 Google LLC
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | package cloudfunctions
16 |
17 | import (
18 | "context"
19 | "encoding/json"
20 | "fmt"
21 | "log"
22 | "os"
23 |
24 | "cloud.google.com/go/pubsub"
25 | // funcframework is required to make this build on cloud functions. See
26 | // https://github.com/GoogleCloudPlatform/functions-framework-go/issues/78
27 | _ "github.com/GoogleCloudPlatform/functions-framework-go/funcframework"
28 | "github.com/GoogleCloudPlatform/functions-framework-go/functions"
29 | "github.com/cloudevents/sdk-go/v2/event"
30 |
31 | "github.com/GoogleCloudPlatform/opentelemetry-operations-go/e2e-test-server/scenarios"
32 | )
33 |
34 | var projectID string
35 |
36 | func init() {
37 | // Register a CloudEvent function with the Functions Framework
38 | functions.CloudEvent("HandleCloudFunction", handleCloudFunction)
39 | projectID = os.Getenv("PROJECT_ID")
40 | if projectID == "" {
41 | log.Fatalf("environment variable PROJECT_ID must be set")
42 | }
43 | }
44 |
45 | // PubSubMessage is the payload of a Pub/Sub event.
46 | type PubSubMessage struct {
47 | Message struct {
48 | Attributes map[string]string `json:"attributes,omitempty"`
49 | } `json:"message"`
50 | }
51 |
52 | // handleCloudFunction accepts and handles a CloudEvent object. It decodes the
53 | // pubsub message contained within the event and handles it.
54 | func handleCloudFunction(ctx context.Context, e event.Event) error {
55 | var m PubSubMessage
56 | if err := json.Unmarshal(e.Data(), &m); err != nil {
57 | return fmt.Errorf("json.Unmarshal: %w", err)
58 | }
59 | pubsubClient, err := pubsub.NewClient(context.Background(), projectID)
60 | if err != nil {
61 | return fmt.Errorf("error creating pubsub client: %v", err)
62 | }
63 | defer pubsubClient.Close()
64 | return scenarios.HandleMessage(ctx, pubsubClient, m.Message.Attributes)
65 | }
66 |
--------------------------------------------------------------------------------
/e2e-test-server/endtoendserver/constants.go:
--------------------------------------------------------------------------------
1 | // Copyright 2021 Google LLC
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | package endtoendserver
16 |
17 | import (
18 | "log"
19 | "os"
20 | )
21 |
22 | var (
23 | subscriptionMode string
24 | projectID string
25 | requestSubscriptionName string
26 | port string
27 | )
28 |
29 | func init() {
30 | subscriptionMode = os.Getenv("SUBSCRIPTION_MODE")
31 | if subscriptionMode == "" {
32 | log.Fatalf("environment variable SUBSCRIPTION_MODE must be set")
33 | }
34 | projectID = os.Getenv("PROJECT_ID")
35 | if projectID == "" {
36 | log.Fatalf("environment variable PROJECT_ID must be set")
37 | }
38 | requestSubscriptionName = os.Getenv("REQUEST_SUBSCRIPTION_NAME")
39 | if requestSubscriptionName == "" {
40 | log.Fatalf("environment variable REQUEST_SUBSCRIPTION_NAME must be set")
41 | }
42 | port = os.Getenv("PORT")
43 | if port == "" && subscriptionMode == "push" {
44 | log.Fatalf("environment variable PORT must be set for push subscription")
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/e2e-test-server/endtoendserver/pull_server.go:
--------------------------------------------------------------------------------
1 | // Copyright 2023 Google LLC
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | package endtoendserver
16 |
17 | import (
18 | "context"
19 | "log"
20 |
21 | "cloud.google.com/go/pubsub"
22 |
23 | "github.com/GoogleCloudPlatform/opentelemetry-operations-go/e2e-test-server/scenarios"
24 | )
25 |
26 | // pullServer is an end-to-end test service.
27 | type pullServer struct {
28 | pubsubClient *pubsub.Client
29 | }
30 |
31 | // New instantiates a new end-to-end test service.
32 | func NewPullServer() (Server, error) {
33 | pubsubClient, err := pubsub.NewClient(context.Background(), projectID)
34 | if err != nil {
35 | return nil, err
36 | }
37 |
38 | return &pullServer{
39 | pubsubClient: pubsubClient,
40 | }, nil
41 | }
42 |
43 | // Run the end-to-end test service. This method will block until the context is
44 | // cancel, or an unrecoverable error is encountered.
45 | func (s *pullServer) Run(ctx context.Context) error {
46 | sub := s.pubsubClient.Subscription(requestSubscriptionName)
47 | log.Printf("End-to-end test service listening on %s", sub)
48 | return sub.Receive(ctx, func(ctx context.Context, m *pubsub.Message) { s.onReceive(ctx, m) })
49 | }
50 |
51 | // Shutdown gracefully shuts down the service, flushing and closing resources as
52 | // appropriate.
53 | func (s *pullServer) Shutdown(ctx context.Context) error {
54 | return s.pubsubClient.Close()
55 | }
56 |
57 | // onReceive executes a scenario based on the incoming message from the test runner.
58 | func (s *pullServer) onReceive(ctx context.Context, m *pubsub.Message) {
59 | defer m.Ack()
60 | if err := scenarios.HandleMessage(ctx, s.pubsubClient, m.Attributes); err != nil {
61 | log.Println(err)
62 | }
63 | }
64 |
--------------------------------------------------------------------------------
/e2e-test-server/endtoendserver/server.go:
--------------------------------------------------------------------------------
1 | // Copyright 2021 Google LLC
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | package endtoendserver
16 |
17 | import (
18 | "context"
19 | "fmt"
20 | )
21 |
22 | // Server is an end-to-end test service.
23 | type Server interface {
24 | Run(context.Context) error
25 | Shutdown(ctx context.Context) error
26 | }
27 |
28 | // New instantiates a new end-to-end test service.
29 | func New() (Server, error) {
30 | switch subscriptionMode {
31 | case "pull":
32 | return NewPullServer()
33 | case "push":
34 | return NewPushServer()
35 | default:
36 | return nil, fmt.Errorf("server does not support subscription mode %v", subscriptionMode)
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/e2e-test-server/go.mod:
--------------------------------------------------------------------------------
1 | module github.com/GoogleCloudPlatform/opentelemetry-operations-go/e2e-test-server
2 |
3 | go 1.23.0
4 |
5 | require (
6 | cloud.google.com/go/pubsub v1.49.0
7 | github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/trace v1.28.0
8 | go.opentelemetry.io/contrib/detectors/gcp v1.35.0
9 | go.opentelemetry.io/otel v1.36.0
10 | go.opentelemetry.io/otel/sdk v1.36.0
11 | go.opentelemetry.io/otel/trace v1.36.0
12 | google.golang.org/genproto/googleapis/rpc v0.0.0-20250519155744-55703ea1f237
13 | )
14 |
15 | require (
16 | cloud.google.com/go v0.120.0 // indirect
17 | cloud.google.com/go/auth v0.16.1 // indirect
18 | cloud.google.com/go/auth/oauth2adapt v0.2.8 // indirect
19 | cloud.google.com/go/compute/metadata v0.7.0 // indirect
20 | cloud.google.com/go/iam v1.5.2 // indirect
21 | cloud.google.com/go/trace v1.11.6 // indirect
22 | github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.28.0 // indirect
23 | github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/resourcemapping v0.52.0 // indirect
24 | github.com/felixge/httpsnoop v1.0.4 // indirect
25 | github.com/go-logr/logr v1.4.3 // indirect
26 | github.com/go-logr/stdr v1.2.2 // indirect
27 | github.com/google/s2a-go v0.1.9 // indirect
28 | github.com/google/uuid v1.6.0 // indirect
29 | github.com/googleapis/enterprise-certificate-proxy v0.3.6 // indirect
30 | github.com/googleapis/gax-go/v2 v2.14.2 // indirect
31 | go.opencensus.io v0.24.0 // indirect
32 | go.opentelemetry.io/auto/sdk v1.1.0 // indirect
33 | go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.60.0 // indirect
34 | go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.61.0 // indirect
35 | go.opentelemetry.io/otel/metric v1.36.0 // indirect
36 | golang.org/x/crypto v0.38.0 // indirect
37 | golang.org/x/net v0.40.0 // indirect
38 | golang.org/x/oauth2 v0.30.0 // indirect
39 | golang.org/x/sync v0.14.0 // indirect
40 | golang.org/x/sys v0.33.0 // indirect
41 | golang.org/x/text v0.25.0 // indirect
42 | golang.org/x/time v0.11.0 // indirect
43 | google.golang.org/api v0.234.0 // indirect
44 | google.golang.org/genproto v0.0.0-20250505200425-f936aa4a68b2 // indirect
45 | google.golang.org/genproto/googleapis/api v0.0.0-20250505200425-f936aa4a68b2 // indirect
46 | google.golang.org/grpc v1.72.2 // indirect
47 | google.golang.org/protobuf v1.36.6 // indirect
48 | )
49 |
50 | replace github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/trace => ../exporter/trace
51 |
52 | replace github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/resourcemapping => ../internal/resourcemapping
53 |
54 | replace github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp => ../detectors/gcp
55 |
56 | replace github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/cloudmock => ../internal/cloudmock
57 |
58 | retract v1.0.0-RC1
59 |
--------------------------------------------------------------------------------
/e2e-test-server/scenarios/constants.go:
--------------------------------------------------------------------------------
1 | // Copyright 2023 Google LLC
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | package scenarios
16 |
17 | import (
18 | "log"
19 | "os"
20 | "time"
21 | )
22 |
23 | const (
24 | instrumentingModuleName = "opentelemetry-ops-e2e-test-server"
25 | scenarioKey = "scenario"
26 | testIDKey = "test_id"
27 | statusCodeKey = "status_code"
28 | traceIDKey = "trace_id"
29 |
30 | // This is set small to reduce the latency in sending traces so that the tests finish faster.
31 | traceBatchTimeout = 100 * time.Millisecond
32 | )
33 |
34 | var (
35 | projectID string
36 | responseTopicName string
37 | )
38 |
39 | func init() {
40 | projectID = os.Getenv("PROJECT_ID")
41 | if projectID == "" {
42 | log.Fatalf("environment variable PROJECT_ID must be set")
43 | }
44 | responseTopicName = os.Getenv("RESPONSE_TOPIC_NAME")
45 | if responseTopicName == "" {
46 | log.Fatalf("environment variable RESPONSE_TOPIC_NAME must be set")
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/e2e-test-server/wait-for-image.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | #
3 | # Copyright 2021 Google LLC
4 | #
5 | # Licensed under the Apache License, Version 2.0 (the "License");
6 | # you may not use this file except in compliance with the License.
7 | # You may obtain a copy of the License at
8 | #
9 | # https://www.apache.org/licenses/LICENSE-2.0
10 | #
11 | # Unless required by applicable law or agreed to in writing, software
12 | # distributed under the License is distributed on an "AS IS" BASIS,
13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | # See the License for the specific language governing permissions and
15 | # limitations under the License.
16 |
17 | while true; do
18 | if docker manifest inspect ${_TEST_SERVER_IMAGE} > /dev/null; then
19 | echo "Image is available, continuing onto test"
20 | break
21 | else
22 | echo "Image not available yet, will continue to retry"
23 | fi
24 | sleep 5
25 | done
26 |
--------------------------------------------------------------------------------
/example/metric/README.md:
--------------------------------------------------------------------------------
1 | # Google Cloud Monitoring exporter example
2 |
3 | This example shows how to use [`go.opentelemetry.io/otel`](https://pkg.go.dev/go.opentelemetry.io/otel/) to instrument a simple Go application with metrics and export the metrics to [Google Cloud Monitoring](https://cloud.google.com/monitoring/)
4 |
5 | ## Setup environment
6 |
7 | Before sending metrics to Google Cloud Monitoring, confirm the Cloud Monitoring API is enabled for the project you will use to access the API as described in [this document](https://cloud.google.com/monitoring/api/enable-api).
8 |
9 | You can find your current project ID using the command:
10 |
11 | ```
12 | $ gcloud config get-value project
13 | Your active configuration is: [example]
14 | foo-project-214354
15 | ```
16 |
17 | In this case, the project ID is `foo-project-214354`.
18 |
19 | Next, set this project ID to the environment variable `GOOGLE_PROJECT_ID` using the following command:
20 |
21 | ```
22 | export GOOGLE_PROJECT_ID=$(gcloud config get-value project)
23 | ```
24 |
25 | ### Enable experimental features
26 | The `exponential_histogram` example can optionally export [exemplars](https://opentelemetry.io/docs/specs/otel/metrics/data-model/#exemplars). Enable experimental [exemplar sampling](https://github.com/open-telemetry/opentelemetry-go/blob/main/sdk/metric/internal/x/README.md#exemplars) support with :
27 | ```
28 | export OTEL_GO_X_EXEMPLAR=true
29 | export OTEL_METRICS_EXEMPLAR_FILTER=always_on
30 | ```
31 |
32 | ## Build and run the application
33 |
34 | Once you ensure the API is enabled, then build the example application and run the executable. There are three separate examples showcasing the following -
35 | 1. Exporting metrics via the SDK - [sdk](./sdk/) directory.
36 | 2. Exporting metrics via the OpenTelemetry Collector - [collector](./collector/).
37 | 3. Exporting histogram metrics via the SDK - [exponential_histogram](./exponential_histogram/).
38 |
39 | Change the current directory to the example you wish to run, e.g. `cd sdk` or `cd exponential_histogram`, and then run the example using following commands:
40 |
41 | ```
42 | $ go build -o metrics
43 | $ ./metrics
44 | ...
45 | ```
46 |
47 | To ensure you have enough data to create interesting charts for the exported metrics generated by the example, keep the application running for at least five minutes.
48 |
49 | *Note: For running the collector example, you need to have a locally running OpenTelemetry Collector, configured using the provided [sample config](./collector/sample-collector-config.yaml). Instructions for running OpenTelemetry Collector on your system can be found [here](https://opentelemetry.io/docs/collector/getting-started/#local).*
50 |
51 | ## Visualize exported metrics
52 |
53 | https://console.cloud.google.com/monitoring/dashboards?project=
54 |
55 | Once you think you have sent sufficient data, then create a dashboard. If you are learning how to use Google Cloud Monitoring, you can follow how to use charts step by step on [this document](https://cloud.google.com/monitoring/charts).
56 |
57 | When filling in the **Find resource type and metric box**, use the metric names with the prefix "custom.googleapis.com/opentelemetry/counter-a", "custom.googleapis.com/opentelemetry/observer-a" or with prefix "workload.googleapis.com/latency_" (for example "workload.googleapis.com/latency_a").
58 |
59 | Go to the individual example sub-directories [sdk](./sdk/) or [exponential_histogram](./exponential_histogram/) for further instructions on how to `Create a dashboard` to visualize the exported metrics.
60 |
--------------------------------------------------------------------------------
/example/metric/collector/go.mod:
--------------------------------------------------------------------------------
1 | module github.com/GoogleCloudPlatform/opentelemetry-operations-go/example/metric/collector
2 |
3 | go 1.23.0
4 |
5 | require (
6 | go.opentelemetry.io/otel v1.36.0
7 | go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.34.0
8 | go.opentelemetry.io/otel/metric v1.36.0
9 | go.opentelemetry.io/otel/sdk/metric v1.36.0
10 | )
11 |
12 | require (
13 | github.com/cenkalti/backoff/v4 v4.3.0 // indirect
14 | github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
15 | github.com/go-logr/logr v1.4.3 // indirect
16 | github.com/go-logr/stdr v1.2.2 // indirect
17 | github.com/google/uuid v1.6.0 // indirect
18 | github.com/grpc-ecosystem/grpc-gateway/v2 v2.26.0 // indirect
19 | github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
20 | go.opentelemetry.io/auto/sdk v1.1.0 // indirect
21 | go.opentelemetry.io/otel/sdk v1.36.0 // indirect
22 | go.opentelemetry.io/otel/trace v1.36.0 // indirect
23 | go.opentelemetry.io/proto/otlp v1.5.0 // indirect
24 | golang.org/x/net v0.40.0 // indirect
25 | golang.org/x/sys v0.33.0 // indirect
26 | golang.org/x/text v0.25.0 // indirect
27 | google.golang.org/genproto/googleapis/api v0.0.0-20250505200425-f936aa4a68b2 // indirect
28 | google.golang.org/genproto/googleapis/rpc v0.0.0-20250519155744-55703ea1f237 // indirect
29 | google.golang.org/grpc v1.72.2 // indirect
30 | google.golang.org/protobuf v1.36.6 // indirect
31 | )
32 |
--------------------------------------------------------------------------------
/example/metric/collector/sample-collector-config.yaml:
--------------------------------------------------------------------------------
1 | # This is a sample config file which can be used with an opentelemetry collector
2 | # This sample is configured to recieve OTLP metrics over HTTP on localhost:4318
3 | # and export the recieved metrics to a Google Cloud project.
4 | receivers:
5 | otlp:
6 | protocols:
7 | http:
8 | endpoint: "localhost:4318"
9 |
10 | processors:
11 | memory_limiter:
12 | check_interval: 1s
13 | limit_percentage: 65
14 | spike_limit_percentage: 20
15 | batch:
16 |
17 | exporters:
18 | googlecloud:
19 | retry_on_failure:
20 | enabled: false
21 |
22 | extensions:
23 | health_check:
24 | pprof:
25 | zpages:
26 |
27 | service:
28 | telemetry:
29 | metrics:
30 | address: ":8888"
31 | extensions: [health_check, pprof, zpages]
32 | pipelines:
33 | metrics:
34 | receivers: [otlp]
35 | processors: [memory_limiter, batch]
36 | exporters: [googlecloud]
37 | logs:
38 | receivers: [otlp]
39 | processors: [memory_limiter, batch]
40 | exporters: [googlecloud]
41 |
--------------------------------------------------------------------------------
/example/metric/dashboards/sdk_dashboard.json:
--------------------------------------------------------------------------------
1 | {
2 | "displayName": "OpenTelemetry exporter example/metric",
3 | "gridLayout": {
4 | "columns": "1",
5 | "widgets": [
6 | {
7 | "title": "custom/opentelemetry/counter-a",
8 | "xyChart": {
9 | "chartOptions": {
10 | "mode": "COLOR"
11 | },
12 | "dataSets": [
13 | {
14 | "minAlignmentPeriod": "60s",
15 | "plotType": "LINE",
16 | "timeSeriesQuery": {
17 | "timeSeriesFilter": {
18 | "aggregation": {
19 | "crossSeriesReducer": "REDUCE_SUM",
20 | "perSeriesAligner": "ALIGN_DELTA"
21 | },
22 | "filter": "metric.type=\"workload.googleapis.com/counter-a\"",
23 | "secondaryAggregation": {}
24 | },
25 | "unitOverride": "1"
26 | }
27 | }
28 | ],
29 | "timeshiftDuration": "0s",
30 | "yAxis": {
31 | "label": "total count",
32 | "scale": "LINEAR"
33 | }
34 | }
35 | },
36 | {
37 | "title": "custom/opentelemetry/observer-a",
38 | "xyChart": {
39 | "chartOptions": {
40 | "mode": "COLOR"
41 | },
42 | "dataSets": [
43 | {
44 | "minAlignmentPeriod": "60s",
45 | "plotType": "LINE",
46 | "timeSeriesQuery": {
47 | "timeSeriesFilter": {
48 | "aggregation": {
49 | "perSeriesAligner": "ALIGN_MEAN"
50 | },
51 | "filter": "metric.type=\"workload.googleapis.com/observer-a\"",
52 | "secondaryAggregation": {}
53 | },
54 | "unitOverride": "1"
55 | }
56 | }
57 | ],
58 | "timeshiftDuration": "0s",
59 | "yAxis": {
60 | "label": "guage value",
61 | "scale": "LINEAR"
62 | }
63 | }
64 | }
65 | ]
66 | }
67 | }
68 |
--------------------------------------------------------------------------------
/example/metric/exponential_histogram/README.md:
--------------------------------------------------------------------------------
1 | # Google Cloud Monitoring exponential histogram example
2 |
3 | This example shows how to use [`go.opentelemetry.io/otel`](https://pkg.go.dev/go.opentelemetry.io/otel/) to instrument a simple Go application with metrics and export the metrics to [Google Cloud Monitoring](https://cloud.google.com/monitoring/)
4 |
5 | ## Example details
6 |
7 | This example simulates server latency by sampling a [Log-Normal Distribution](https://en.wikipedia.org/wiki/Log-normal_distribution) with the parameters $\mu = 3.5 , 5.5$ and $\sigma = .5$. We generate the following three example of server latency :
8 |
9 | 1. Latency with Log-Normal Distribution.
10 | 2. Latency with Shifted Mean Distribution.
11 | 3. Latency with Multimodal Distribution (mixture of 1. and 2.).
12 |
13 | We explore the resulting distributions with three types of histograms :
14 |
15 | 1. Opentelemetry Default Linear Buckets Histogram. Buckets are `0, 5, 10, 25, 50, 75, 100, 250, 500, 1000`
16 | 2. Opentelemetry Linear Buckets Histogram. Buckets are `0, 10, 20, 30, ..., 340, 350`.
17 | 3. Opentelemetry Exponential Buckets Histogram with default parameters.
18 |
19 | ## Build and run the application
20 |
21 | Go to the [example/metric/README.md](../README.md) instructions that describe how to build and run all examples.
22 |
23 | ## Sample execution
24 |
25 | ```
26 | $ ./metrics
27 | 2024/03/21 15:38:58 Sent Latency Data (Original Distribution): #points 1000 , mean 36.64255895183214, sdv 19.670797833645373
28 | 2024/03/21 15:38:58 Sent Latency Data (Shifted Distribution): #points 1000 , mean 277.70002931783233, sdv 143.59582355437485
29 | 2024/03/21 15:38:58 Sent Latency Data (Multimodal Distribution): #points 1000 , mean 151.49111863163805, sdv 159.2187295223318
30 | ...
31 | ```
32 |
33 | ## Create dashboard
34 |
35 | When filling in the **Find resource type and metric box**, use the metric names with the prefix "workload.googleapis.com/latency_" to observe histogram metrics (for example "workload.googleapis.com/latency_a").
36 |
37 | If you already know how to use Cloud Monitoring and would just like to confirm the data is properly received, you can run the dashboard creation script bundled in this directory. This command requires at least the [roles/monitoring.dashboardEditor](https://cloud.google.com/monitoring/access-control#dashboard_roles_desc) permissions to create a new dashboard.
38 |
39 | ```
40 | $ ./create_dashboard.sh
41 | ```
42 |
43 | This script creates a dashboard titled "OpenTelemetry - Exponential Histogram example".
44 |
45 | You should be able to view histogram charts like below once you create the dashboard.
46 |
47 |
48 |
--------------------------------------------------------------------------------
/example/metric/exponential_histogram/create_dashboard.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | # Copyright 2024 Google LLC
4 | #
5 | # Licensed under the Apache License, Version 2.0 (the "License");
6 | # you may not use this file except in compliance with the License.
7 | # You may obtain a copy of the License at
8 | #
9 | # http://www.apache.org/licenses/LICENSE-2.0
10 | #
11 | # Unless required by applicable law or agreed to in writing, software
12 | # distributed under the License is distributed on an "AS IS" BASIS,
13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | # See the License for the specific language governing permissions and
15 | # limitations under the License.
16 |
17 | # This dashboard is intended to show the metrics emit from the example
18 | # in the same directory.
19 | # https://cloud.google.com/monitoring/dashboards/api-dashboard
20 | gcloud monitoring dashboards create --config-from-file=--config-from-file=../dashboards/exponential_histogram_dashboard.json
21 |
--------------------------------------------------------------------------------
/example/metric/exponential_histogram/go.mod:
--------------------------------------------------------------------------------
1 | module github.com/GoogleCloudPlatform/opentelemetry-operations-go/example/metric/exponential_histogram
2 |
3 | go 1.23.0
4 |
5 | require (
6 | github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/metric v0.52.0
7 | go.opentelemetry.io/contrib/detectors/gcp v1.35.0
8 | go.opentelemetry.io/otel v1.36.0
9 | go.opentelemetry.io/otel/metric v1.36.0
10 | go.opentelemetry.io/otel/sdk v1.36.0
11 | go.opentelemetry.io/otel/sdk/metric v1.36.0
12 | gonum.org/v1/gonum v0.15.1
13 | )
14 |
15 | require (
16 | cloud.google.com/go/auth v0.16.1 // indirect
17 | cloud.google.com/go/auth/oauth2adapt v0.2.8 // indirect
18 | cloud.google.com/go/compute/metadata v0.7.0 // indirect
19 | cloud.google.com/go/monitoring v1.24.2 // indirect
20 | github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.28.0 // indirect
21 | github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/resourcemapping v0.52.0 // indirect
22 | github.com/go-logr/logr v1.4.3 // indirect
23 | github.com/go-logr/stdr v1.2.2 // indirect
24 | github.com/google/s2a-go v0.1.9 // indirect
25 | github.com/google/uuid v1.6.0 // indirect
26 | github.com/googleapis/enterprise-certificate-proxy v0.3.6 // indirect
27 | github.com/googleapis/gax-go/v2 v2.14.2 // indirect
28 | go.opentelemetry.io/auto/sdk v1.1.0 // indirect
29 | go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.60.0 // indirect
30 | go.opentelemetry.io/otel/trace v1.36.0 // indirect
31 | golang.org/x/crypto v0.38.0 // indirect
32 | golang.org/x/exp v0.0.0-20250106191152-7588d65b2ba8 // indirect
33 | golang.org/x/net v0.40.0 // indirect
34 | golang.org/x/oauth2 v0.30.0 // indirect
35 | golang.org/x/sync v0.14.0 // indirect
36 | golang.org/x/sys v0.33.0 // indirect
37 | golang.org/x/text v0.25.0 // indirect
38 | golang.org/x/time v0.11.0 // indirect
39 | google.golang.org/api v0.234.0 // indirect
40 | google.golang.org/genproto v0.0.0-20250505200425-f936aa4a68b2 // indirect
41 | google.golang.org/genproto/googleapis/api v0.0.0-20250505200425-f936aa4a68b2 // indirect
42 | google.golang.org/genproto/googleapis/rpc v0.0.0-20250519155744-55703ea1f237 // indirect
43 | google.golang.org/grpc v1.72.2 // indirect
44 | google.golang.org/protobuf v1.36.6 // indirect
45 | )
46 |
47 | replace github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/metric => ../../../exporter/metric
48 |
49 | replace github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/cloudmock => ../../../internal/cloudmock
50 |
51 | replace github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/resourcemapping => ../../../internal/resourcemapping
52 |
53 | replace github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp => ../../../detectors/gcp
54 |
--------------------------------------------------------------------------------
/example/metric/images/exponential_histogram_charts.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GoogleCloudPlatform/opentelemetry-operations-go/6658b3aae40518709f8f7763b3e5f0881507ffc1/example/metric/images/exponential_histogram_charts.png
--------------------------------------------------------------------------------
/example/metric/images/sdk_charts.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GoogleCloudPlatform/opentelemetry-operations-go/6658b3aae40518709f8f7763b3e5f0881507ffc1/example/metric/images/sdk_charts.png
--------------------------------------------------------------------------------
/example/metric/otlpgrpc/README.md:
--------------------------------------------------------------------------------
1 | # OTLP Metric with Google Auth Example
2 |
3 | Run this sample to connect to an endpoint that is protected by GCP authentication.
4 |
5 | #### Prerequisites
6 |
7 | Get Google credentials on your machine:
8 |
9 | ```sh
10 | gcloud auth application-default login
11 | ```
12 |
13 | #### Run the Sample
14 |
15 | ```sh
16 | # export necessary OTEL environment variables
17 | export PROJECT_ID=
18 | export OTEL_EXPORTER_OTLP_ENDPOINT=
19 | export OTEL_RESOURCE_ATTRIBUTES="gcp.project_id=$PROJECT_ID,service.name=otlp-sample,service.instance.id=1"
20 | export OTEL_EXPORTER_OTLP_HEADERS=X-Goog-User-Project=$PROJECT_ID
21 |
22 | # from the samples/otlpmetric repository
23 | cd example/metric/otlpgrpc && go run .
24 | ```
25 |
--------------------------------------------------------------------------------
/example/metric/otlpgrpc/example.go:
--------------------------------------------------------------------------------
1 | // Copyright 2024 Google LLC
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | package main
16 |
17 | import (
18 | "context"
19 | "errors"
20 | "log"
21 |
22 | "go.opentelemetry.io/contrib/detectors/gcp"
23 | "go.opentelemetry.io/otel/attribute"
24 | "go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc"
25 | "go.opentelemetry.io/otel/metric"
26 | sdkmetric "go.opentelemetry.io/otel/sdk/metric"
27 | "go.opentelemetry.io/otel/sdk/resource"
28 | semconv "go.opentelemetry.io/otel/semconv/v1.21.0"
29 | "google.golang.org/grpc"
30 | "google.golang.org/grpc/credentials/oauth"
31 | )
32 |
33 | func main() {
34 | ctx := context.Background()
35 |
36 | creds, err := oauth.NewApplicationDefault(ctx)
37 | if err != nil {
38 | panic(err)
39 | }
40 |
41 | res, err := resource.New(
42 | ctx,
43 | // Use the GCP resource detector to detect information about the GCP platform
44 | resource.WithDetectors(gcp.NewDetector()),
45 | // Keep the default detectors
46 | resource.WithTelemetrySDK(),
47 | // Add attributes from environment variables
48 | resource.WithFromEnv(),
49 | // Add your own custom attributes to identify your application
50 | resource.WithAttributes(
51 | semconv.ServiceNameKey.String("example-application"),
52 | ),
53 | )
54 | if errors.Is(err, resource.ErrPartialResource) || errors.Is(err, resource.ErrSchemaURLConflict) {
55 | log.Println(err)
56 | } else if err != nil {
57 | panic(err)
58 | }
59 |
60 | // Set endpoint with OTEL_EXPORTER_OTLP_ENDPOINT or OTEL_EXPORTER_OTLP_METRICS_ENDPOINT
61 | metricExporter, err := otlpmetricgrpc.New(ctx, otlpmetricgrpc.WithDialOption(grpc.WithPerRPCCredentials(creds)))
62 | if err != nil {
63 | panic(err)
64 | }
65 |
66 | meterProvider := sdkmetric.NewMeterProvider(
67 | sdkmetric.WithResource(res),
68 | sdkmetric.WithReader(sdkmetric.NewPeriodicReader(metricExporter)),
69 | )
70 |
71 | defer func() {
72 | if err = meterProvider.Shutdown(ctx); err != nil {
73 | log.Println(err)
74 | }
75 | }()
76 |
77 | meter := meterProvider.Meter("github.com/GoogleCloudPlatform/opentelemetry-operations-go/example/metric/otlpgrpc")
78 |
79 | // Register counter value
80 | counter, err := meter.Int64Counter("counter-a")
81 | if err != nil {
82 | log.Fatalf("Failed to create counter: %v", err)
83 | }
84 | clabels := []attribute.KeyValue{attribute.Key("key").String("value")}
85 | counter.Add(ctx, 100, metric.WithAttributes(clabels...))
86 | }
87 |
--------------------------------------------------------------------------------
/example/metric/otlpgrpc/go.mod:
--------------------------------------------------------------------------------
1 | module github.com/GoogleCloudPlatform/opentelemetry-operations-go/example/metric/otlpgrpc
2 |
3 | go 1.23.0
4 |
5 | require (
6 | go.opentelemetry.io/contrib/detectors/gcp v1.35.0
7 | go.opentelemetry.io/otel v1.36.0
8 | go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.34.0
9 | go.opentelemetry.io/otel/metric v1.36.0
10 | go.opentelemetry.io/otel/sdk v1.36.0
11 | go.opentelemetry.io/otel/sdk/metric v1.36.0
12 | google.golang.org/grpc v1.72.2
13 | )
14 |
15 | require (
16 | cloud.google.com/go/compute/metadata v0.7.0 // indirect
17 | github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.28.0 // indirect
18 | github.com/cenkalti/backoff/v4 v4.3.0 // indirect
19 | github.com/go-logr/logr v1.4.3 // indirect
20 | github.com/go-logr/stdr v1.2.2 // indirect
21 | github.com/google/uuid v1.6.0 // indirect
22 | github.com/grpc-ecosystem/grpc-gateway/v2 v2.26.0 // indirect
23 | go.opentelemetry.io/auto/sdk v1.1.0 // indirect
24 | go.opentelemetry.io/otel/trace v1.36.0 // indirect
25 | go.opentelemetry.io/proto/otlp v1.5.0 // indirect
26 | golang.org/x/net v0.40.0 // indirect
27 | golang.org/x/oauth2 v0.30.0 // indirect
28 | golang.org/x/sys v0.33.0 // indirect
29 | golang.org/x/text v0.25.0 // indirect
30 | google.golang.org/genproto/googleapis/api v0.0.0-20250505200425-f936aa4a68b2 // indirect
31 | google.golang.org/genproto/googleapis/rpc v0.0.0-20250519155744-55703ea1f237 // indirect
32 | google.golang.org/protobuf v1.36.6 // indirect
33 | )
34 |
35 | replace github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/metric => ../../../exporter/metric
36 |
37 | replace github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/cloudmock => ../../../internal/cloudmock
38 |
39 | replace github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/resourcemapping => ../../../internal/resourcemapping
40 |
41 | replace github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp => ../../../detectors/gcp
42 |
--------------------------------------------------------------------------------
/example/metric/sdk/README.md:
--------------------------------------------------------------------------------
1 | # Google Cloud Monitoring exporter example
2 |
3 | This example shows how to use [`go.opentelemetry.io/otel`](https://pkg.go.dev/go.opentelemetry.io/otel/) to instrument a simple Go application with metrics and export the metrics to [Google Cloud Monitoring](https://cloud.google.com/monitoring/)
4 |
5 | ## Build and run the application
6 |
7 | Go to the [example/metric/README.md](../README.md) instructions that describe how to build and run all examples.
8 |
9 | ## Sample execution
10 |
11 | ```
12 | $ ./metrics
13 | 2020/06/11 21:11:15 Most recent data: counter 110, observer 13.45
14 | 2020/06/11 21:11:15 Most recent data: counter 160, observer 16.02
15 | 2020/06/11 21:11:15 Most recent data: counter 134, observer 14.33
16 | 2020/06/11 21:11:15 Most recent data: counter 125, observer 15.12
17 | ...
18 | ```
19 |
20 | ## Create dashboard
21 |
22 | When filling in the **Find resource type and metric box**, use the metric names "custom.googleapis.com/opentelemetry/counter-a" and "custom.googleapis.com/opentelemetry/observer-a".
23 |
24 | If you already know how to use Cloud Monitoring and would just like to confirm the data is properly received, you can run the dashboard creation script bundled in this directory. This command requires at least the [roles/monitoring.dashboardEditor](https://cloud.google.com/monitoring/access-control#dashboard_roles_desc) permissions to create a new dashboard.
25 | ```
26 | $ ./create_dashboard.sh
27 | ```
28 |
29 | This script creates a dashboard titled "OpenTelemetry exporter example/metric".
30 |
31 | You should be able to view line charts like below once you create the dashboard.
32 |
33 | *Note: This script is configured to create dashboard which displays the metrics generated via the `sdk` example.*
34 |
35 |
--------------------------------------------------------------------------------
/example/metric/sdk/create_dashboard.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | # Copyright 2020 Google LLC
4 | #
5 | # Licensed under the Apache License, Version 2.0 (the "License");
6 | # you may not use this file except in compliance with the License.
7 | # You may obtain a copy of the License at
8 | #
9 | # http://www.apache.org/licenses/LICENSE-2.0
10 | #
11 | # Unless required by applicable law or agreed to in writing, software
12 | # distributed under the License is distributed on an "AS IS" BASIS,
13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | # See the License for the specific language governing permissions and
15 | # limitations under the License.
16 |
17 | # This dashboard is intended to show the metrics emit from the example
18 | # in the same directory.
19 | # https://cloud.google.com/monitoring/dashboards/api-dashboard
20 | gcloud monitoring dashboards create --config-from-file=../dashboards/sdk_dashboard.json
21 |
--------------------------------------------------------------------------------
/example/metric/sdk/go.mod:
--------------------------------------------------------------------------------
1 | module github.com/GoogleCloudPlatform/opentelemetry-operations-go/example/metric/sdk
2 |
3 | go 1.23.0
4 |
5 | require (
6 | github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/metric v0.52.0
7 | go.opentelemetry.io/contrib/detectors/gcp v1.35.0
8 | go.opentelemetry.io/otel v1.36.0
9 | go.opentelemetry.io/otel/metric v1.36.0
10 | go.opentelemetry.io/otel/sdk v1.36.0
11 | go.opentelemetry.io/otel/sdk/metric v1.36.0
12 | )
13 |
14 | require (
15 | cloud.google.com/go/auth v0.16.1 // indirect
16 | cloud.google.com/go/auth/oauth2adapt v0.2.8 // indirect
17 | cloud.google.com/go/compute/metadata v0.7.0 // indirect
18 | cloud.google.com/go/monitoring v1.24.2 // indirect
19 | github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.28.0 // indirect
20 | github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/resourcemapping v0.52.0 // indirect
21 | github.com/go-logr/logr v1.4.3 // indirect
22 | github.com/go-logr/stdr v1.2.2 // indirect
23 | github.com/google/s2a-go v0.1.9 // indirect
24 | github.com/google/uuid v1.6.0 // indirect
25 | github.com/googleapis/enterprise-certificate-proxy v0.3.6 // indirect
26 | github.com/googleapis/gax-go/v2 v2.14.2 // indirect
27 | go.opentelemetry.io/auto/sdk v1.1.0 // indirect
28 | go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.60.0 // indirect
29 | go.opentelemetry.io/otel/trace v1.36.0 // indirect
30 | golang.org/x/crypto v0.38.0 // indirect
31 | golang.org/x/net v0.40.0 // indirect
32 | golang.org/x/oauth2 v0.30.0 // indirect
33 | golang.org/x/sync v0.14.0 // indirect
34 | golang.org/x/sys v0.33.0 // indirect
35 | golang.org/x/text v0.25.0 // indirect
36 | golang.org/x/time v0.11.0 // indirect
37 | google.golang.org/api v0.234.0 // indirect
38 | google.golang.org/genproto v0.0.0-20250505200425-f936aa4a68b2 // indirect
39 | google.golang.org/genproto/googleapis/api v0.0.0-20250505200425-f936aa4a68b2 // indirect
40 | google.golang.org/genproto/googleapis/rpc v0.0.0-20250519155744-55703ea1f237 // indirect
41 | google.golang.org/grpc v1.72.2 // indirect
42 | google.golang.org/protobuf v1.36.6 // indirect
43 | )
44 |
45 | replace github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/metric => ../../../exporter/metric
46 |
47 | replace github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/cloudmock => ../../../internal/cloudmock
48 |
49 | replace github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/resourcemapping => ../../../internal/resourcemapping
50 |
51 | replace github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp => ../../../detectors/gcp
52 |
--------------------------------------------------------------------------------
/example/trace/http/README.md:
--------------------------------------------------------------------------------
1 | # HTTP Client-Server example
2 |
3 | An HTTP server and client instrumented to send traces to Google Cloud Trace.
4 |
5 | In order to run this example, you'll need to
6 |
7 | 1. [Create a GCP project](https://cloud.google.com/resource-manager/docs/creating-managing-projects)
8 | 2. [Enable billing](https://cloud.google.com/billing/docs/how-to/manage-billing-account#new-billing)
9 | 3. [Enable the Cloud Trace API](https://console.cloud.google.com/apis/library/cloudtrace.googleapis.com)
10 | 4. Obtain authentication credentials
11 | * If you run the code on GCE/GKE/Cloud Run, it will receive the necessary authentication credentials automatically.
12 | * If you run in Cloud Shell or outside of GCP, you'll need to have it [authenticate as a service account](https://cloud.google.com/docs/authentication/production).
13 | 5. In one terminal, run the server
14 | ```
15 | $ go run ./server
16 | ```
17 | 6. In another terminal on the same host, run the client
18 | ```
19 | $ go run ./client
20 | ```
21 | 7. Open [Google Cloud Trace](https://console.cloud.google.com/traces/list) and examine the trace that was recorded.
22 | 
23 |
--------------------------------------------------------------------------------
/example/trace/http/cloudtrace.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GoogleCloudPlatform/opentelemetry-operations-go/6658b3aae40518709f8f7763b3e5f0881507ffc1/example/trace/http/cloudtrace.png
--------------------------------------------------------------------------------
/example/trace/http/go.mod:
--------------------------------------------------------------------------------
1 | module github.com/GoogleCloudPlatform/opentelemetry-operations-go/example/trace/http
2 |
3 | go 1.23.0
4 |
5 | require (
6 | github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/trace v1.28.0
7 | github.com/GoogleCloudPlatform/opentelemetry-operations-go/propagator v0.52.0
8 | go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.61.0
9 | go.opentelemetry.io/otel v1.36.0
10 | go.opentelemetry.io/otel/sdk v1.36.0
11 | go.opentelemetry.io/otel/trace v1.36.0
12 | )
13 |
14 | require (
15 | cloud.google.com/go/auth v0.16.1 // indirect
16 | cloud.google.com/go/auth/oauth2adapt v0.2.8 // indirect
17 | cloud.google.com/go/compute/metadata v0.7.0 // indirect
18 | cloud.google.com/go/trace v1.11.6 // indirect
19 | github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/resourcemapping v0.52.0 // indirect
20 | github.com/felixge/httpsnoop v1.0.4 // indirect
21 | github.com/go-logr/logr v1.4.3 // indirect
22 | github.com/go-logr/stdr v1.2.2 // indirect
23 | github.com/google/s2a-go v0.1.9 // indirect
24 | github.com/google/uuid v1.6.0 // indirect
25 | github.com/googleapis/enterprise-certificate-proxy v0.3.6 // indirect
26 | github.com/googleapis/gax-go/v2 v2.14.2 // indirect
27 | go.opentelemetry.io/auto/sdk v1.1.0 // indirect
28 | go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.60.0 // indirect
29 | go.opentelemetry.io/otel/metric v1.36.0 // indirect
30 | golang.org/x/crypto v0.38.0 // indirect
31 | golang.org/x/net v0.40.0 // indirect
32 | golang.org/x/oauth2 v0.30.0 // indirect
33 | golang.org/x/sync v0.14.0 // indirect
34 | golang.org/x/sys v0.33.0 // indirect
35 | golang.org/x/text v0.25.0 // indirect
36 | golang.org/x/time v0.11.0 // indirect
37 | google.golang.org/api v0.234.0 // indirect
38 | google.golang.org/genproto/googleapis/api v0.0.0-20250505200425-f936aa4a68b2 // indirect
39 | google.golang.org/genproto/googleapis/rpc v0.0.0-20250519155744-55703ea1f237 // indirect
40 | google.golang.org/grpc v1.72.2 // indirect
41 | google.golang.org/protobuf v1.36.6 // indirect
42 | )
43 |
44 | replace github.com/GoogleCloudPlatform/opentelemetry-operations-go => ../../..
45 |
46 | replace github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/trace => ../../../exporter/trace
47 |
48 | replace github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/resourcemapping => ../../../internal/resourcemapping
49 |
50 | replace github.com/GoogleCloudPlatform/opentelemetry-operations-go/propagator => ../../../propagator
51 |
52 | replace github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/cloudmock => ../../../internal/cloudmock
53 |
54 | retract (
55 | v1.0.0
56 | v1.0.0-RC2
57 | v1.0.0-RC1
58 | )
59 |
--------------------------------------------------------------------------------
/example/trace/http/server/server.go:
--------------------------------------------------------------------------------
1 | // Copyright 2019 OpenTelemetry Authors
2 | // Copyright 2021 Google LLC
3 | //
4 | // Licensed under the Apache License, Version 2.0 (the "License");
5 | // you may not use this file except in compliance with the License.
6 | // You may obtain a copy of the License at
7 | //
8 | // http://www.apache.org/licenses/LICENSE-2.0
9 | //
10 | // Unless required by applicable law or agreed to in writing, software
11 | // distributed under the License is distributed on an "AS IS" BASIS,
12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | // See the License for the specific language governing permissions and
14 | // limitations under the License.
15 |
16 | package main
17 |
18 | import (
19 | "context"
20 | "fmt"
21 | "io"
22 | "log"
23 | "net/http"
24 | "os"
25 |
26 | "go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp"
27 | "go.opentelemetry.io/otel"
28 | "go.opentelemetry.io/otel/attribute"
29 | "go.opentelemetry.io/otel/propagation"
30 | sdktrace "go.opentelemetry.io/otel/sdk/trace"
31 | "go.opentelemetry.io/otel/trace"
32 |
33 | cloudtrace "github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/trace"
34 | gcppropagator "github.com/GoogleCloudPlatform/opentelemetry-operations-go/propagator"
35 | )
36 |
37 | func initTracer() (func(), error) {
38 | projectID := os.Getenv("PROJECT_ID")
39 |
40 | // Create Google Cloud Trace exporter to be able to retrieve
41 | // the collected spans.
42 | exporter, err := cloudtrace.New(cloudtrace.WithProjectID(projectID))
43 | if err != nil {
44 | return nil, err
45 | }
46 | tp := sdktrace.NewTracerProvider(
47 | // For this example code we use sdktrace.AlwaysSample sampler to sample all traces.
48 | // In a production application, use sdktrace.ProbabilitySampler with a desired probability.
49 | sdktrace.WithSampler(sdktrace.AlwaysSample()),
50 | sdktrace.WithBatcher(exporter))
51 |
52 | otel.SetTracerProvider(tp)
53 | return func() {
54 | err := tp.Shutdown(context.Background())
55 | if err != nil {
56 | fmt.Printf("error shutting down trace provider: %+v", err)
57 | }
58 | }, nil
59 | }
60 |
61 | func installPropagators() {
62 | otel.SetTextMapPropagator(
63 | propagation.NewCompositeTextMapPropagator(
64 | // Putting the CloudTraceOneWayPropagator first means the TraceContext propagator
65 | // takes precedence if both the traceparent and the XCTC headers exist.
66 | gcppropagator.CloudTraceOneWayPropagator{},
67 | propagation.TraceContext{},
68 | propagation.Baggage{},
69 | ))
70 | }
71 |
72 | func main() {
73 | installPropagators()
74 | shutdown, err := initTracer()
75 | if err != nil {
76 | log.Fatal(err)
77 | }
78 | defer shutdown()
79 |
80 | helloHandler := func(w http.ResponseWriter, req *http.Request) {
81 | ctx := req.Context()
82 | span := trace.SpanFromContext(ctx)
83 | span.SetAttributes(attribute.String("server", "handling this..."))
84 |
85 | _, _ = io.WriteString(w, "Hello, world!\n")
86 | }
87 | otelHandler := otelhttp.NewHandler(http.HandlerFunc(helloHandler), "Hello")
88 | http.Handle("/hello", otelHandler)
89 | err = http.ListenAndServe(":7777", nil)
90 | if err != nil {
91 | panic(err)
92 | }
93 | }
94 |
--------------------------------------------------------------------------------
/example/trace/otlpgrpc/example.go:
--------------------------------------------------------------------------------
1 | // Copyright 2019 OpenTelemetry Authors
2 | // Copyright 2024 Google LLC
3 | //
4 | // Licensed under the Apache License, Version 2.0 (the "License");
5 | // you may not use this file except in compliance with the License.
6 | // You may obtain a copy of the License at
7 | //
8 | // http://www.apache.org/licenses/LICENSE-2.0
9 | //
10 | // Unless required by applicable law or agreed to in writing, software
11 | // distributed under the License is distributed on an "AS IS" BASIS,
12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | // See the License for the specific language governing permissions and
14 | // limitations under the License.
15 |
16 | package main
17 |
18 | import (
19 | "context"
20 | "flag"
21 | "fmt"
22 | "log"
23 | "time"
24 |
25 | "go.opentelemetry.io/otel"
26 | "go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc"
27 | sdktrace "go.opentelemetry.io/otel/sdk/trace"
28 | semconv "go.opentelemetry.io/otel/semconv/v1.24.0"
29 | "go.opentelemetry.io/otel/trace"
30 |
31 | "google.golang.org/grpc"
32 | "google.golang.org/grpc/credentials/oauth"
33 | )
34 |
35 | var keepRunning = flag.Bool("keepRunning", false, "Set to true for generating spans at a fixed rate indefinitely. Default is false.")
36 |
37 | func initTracer() (func(), error) {
38 | ctx := context.Background()
39 |
40 | creds, err := oauth.NewApplicationDefault(ctx)
41 | if err != nil {
42 | panic(err)
43 | }
44 |
45 | // set OTEL_RESOURCE_ATTRIBUTES="gcp.project_id="
46 | // set endpoint with OTEL_EXPORTER_OTLP_ENDPOINT=https://
47 | // set OTEL_EXPORTER_OTLP_HEADERS="x-goog-user-project="
48 | exporter, err := otlptracegrpc.New(ctx, otlptracegrpc.WithDialOption(grpc.WithPerRPCCredentials(creds)))
49 | if err != nil {
50 | panic(err)
51 | }
52 |
53 | tp := sdktrace.NewTracerProvider(
54 | // For this example code we use sdktrace.AlwaysSample sampler to sample all traces.
55 | // In a production application, use sdktrace.TraceIDRatioBased with a desired probability.
56 | sdktrace.WithSampler(sdktrace.AlwaysSample()),
57 | sdktrace.WithBatcher(exporter))
58 |
59 | otel.SetTracerProvider(tp)
60 | return func() {
61 | err := tp.Shutdown(context.Background())
62 | if err != nil {
63 | fmt.Printf("error shutting down trace provider: %+v", err)
64 | }
65 | }, nil
66 | }
67 |
68 | func generateTestSpan(ctx context.Context, tr trace.Tracer, description string) {
69 | fmt.Println("starting span...")
70 | _, span := tr.Start(ctx, description, trace.WithAttributes(semconv.PeerServiceKey.String("ExampleService")))
71 | defer span.End()
72 | defer fmt.Println("ending span.")
73 |
74 | time.Sleep(3 * time.Second)
75 | }
76 |
77 | func generateSpansAtFixedRate(ctx context.Context, tr trace.Tracer) {
78 | fmt.Println("Generating 1 test span every 10 seconds indefinitely")
79 | ticker := time.NewTicker(10 * time.Second)
80 | defer ticker.Stop()
81 |
82 | for tick := range ticker.C {
83 | go generateTestSpan(ctx, tr, fmt.Sprintf("span-%s", tick))
84 | }
85 | fmt.Println("Span generation complete.")
86 | }
87 |
88 | func main() {
89 | flag.Parse()
90 | shutdown, err := initTracer()
91 | if err != nil {
92 | log.Fatal(err)
93 | }
94 | defer shutdown()
95 | tr := otel.Tracer("cloudtrace/example/client")
96 |
97 | ctx := context.Background()
98 | if *keepRunning {
99 | generateSpansAtFixedRate(ctx, tr)
100 | } else {
101 | generateTestSpan(ctx, tr, "test span")
102 | }
103 | }
104 |
--------------------------------------------------------------------------------
/example/trace/otlpgrpc/go.mod:
--------------------------------------------------------------------------------
1 | module github.com/GoogleCloudPlatform/opentelemetry-operations-go/example/trace/otlpgrpc
2 |
3 | go 1.23.0
4 |
5 | require (
6 | go.opentelemetry.io/otel v1.36.0
7 | go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.34.0
8 | go.opentelemetry.io/otel/sdk v1.36.0
9 | go.opentelemetry.io/otel/trace v1.36.0
10 | google.golang.org/grpc v1.72.2
11 | )
12 |
13 | require (
14 | cloud.google.com/go/compute/metadata v0.7.0 // indirect
15 | github.com/cenkalti/backoff/v4 v4.3.0 // indirect
16 | github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
17 | github.com/go-logr/logr v1.4.3 // indirect
18 | github.com/go-logr/stdr v1.2.2 // indirect
19 | github.com/google/uuid v1.6.0 // indirect
20 | github.com/grpc-ecosystem/grpc-gateway/v2 v2.26.0 // indirect
21 | github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
22 | go.opentelemetry.io/auto/sdk v1.1.0 // indirect
23 | go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.34.0 // indirect
24 | go.opentelemetry.io/otel/metric v1.36.0 // indirect
25 | go.opentelemetry.io/otel/sdk/metric v1.36.0 // indirect
26 | go.opentelemetry.io/proto/otlp v1.5.0 // indirect
27 | golang.org/x/net v0.40.0 // indirect
28 | golang.org/x/oauth2 v0.30.0 // indirect
29 | golang.org/x/sys v0.33.0 // indirect
30 | golang.org/x/text v0.25.0 // indirect
31 | google.golang.org/genproto/googleapis/api v0.0.0-20250505200425-f936aa4a68b2 // indirect
32 | google.golang.org/genproto/googleapis/rpc v0.0.0-20250519155744-55703ea1f237 // indirect
33 | google.golang.org/protobuf v1.36.6 // indirect
34 | )
35 |
--------------------------------------------------------------------------------
/example/trace/otlphttp/example.go:
--------------------------------------------------------------------------------
1 | // Copyright 2019 OpenTelemetry Authors
2 | // Copyright 2024 Google LLC
3 | //
4 | // Licensed under the Apache License, Version 2.0 (the "License");
5 | // you may not use this file except in compliance with the License.
6 | // You may obtain a copy of the License at
7 | //
8 | // http://www.apache.org/licenses/LICENSE-2.0
9 | //
10 | // Unless required by applicable law or agreed to in writing, software
11 | // distributed under the License is distributed on an "AS IS" BASIS,
12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | // See the License for the specific language governing permissions and
14 | // limitations under the License.
15 |
16 | package main
17 |
18 | import (
19 | "context"
20 | "fmt"
21 | "log"
22 | "os"
23 | "time"
24 |
25 | "go.opentelemetry.io/otel"
26 | "go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp"
27 | sdktrace "go.opentelemetry.io/otel/sdk/trace"
28 | semconv "go.opentelemetry.io/otel/semconv/v1.24.0"
29 | "go.opentelemetry.io/otel/trace"
30 |
31 | "golang.org/x/oauth2/google"
32 | )
33 |
34 | func initTracer(projectID string) (func(), error) {
35 | ctx := context.Background()
36 |
37 | creds, err := google.FindDefaultCredentials(ctx)
38 | if err != nil {
39 | panic(err)
40 | }
41 | token, err := creds.TokenSource.Token()
42 | if err != nil {
43 | panic(err)
44 | }
45 |
46 | // set OTEL_RESOURCE_ATTRIBUTES="gcp.project_id="
47 | // set endpoint with OTEL_EXPORTER_OTLP_ENDPOINT=https://
48 | exporter, err := otlptracehttp.New(ctx, otlptracehttp.WithHeaders(map[string]string{
49 | "Authorization": fmt.Sprintf("Bearer %s", token.AccessToken),
50 | "x-goog-user-project": projectID,
51 | }))
52 | if err != nil {
53 | panic(err)
54 | }
55 |
56 | tp := sdktrace.NewTracerProvider(
57 | // For this example code we use sdktrace.AlwaysSample sampler to sample all traces.
58 | // In a production application, use sdktrace.ProbabilitySampler with a desired probability.
59 | sdktrace.WithSampler(sdktrace.AlwaysSample()),
60 | sdktrace.WithBatcher(exporter))
61 |
62 | otel.SetTracerProvider(tp)
63 | return func() {
64 | err := tp.Shutdown(context.Background())
65 | if err != nil {
66 | fmt.Printf("error shutting down trace provider: %+v", err)
67 | }
68 | }, nil
69 | }
70 |
71 | func main() {
72 | projectID := os.Getenv("GCLOUD_PROJECT")
73 | shutdown, err := initTracer(projectID)
74 | if err != nil {
75 | log.Fatal(err)
76 | }
77 | defer shutdown()
78 | tr := otel.Tracer("cloudtrace/example/client")
79 |
80 | ctx := context.Background()
81 | fmt.Println("starting span...")
82 | _, span := tr.Start(ctx, "test span", trace.WithAttributes(semconv.PeerServiceKey.String("ExampleService")))
83 | defer span.End()
84 | defer fmt.Println("ending span.")
85 |
86 | time.Sleep(3 * time.Second)
87 | }
88 |
--------------------------------------------------------------------------------
/example/trace/otlphttp/go.mod:
--------------------------------------------------------------------------------
1 | module github.com/GoogleCloudPlatform/opentelemetry-operations-go/example/trace/otlphttp
2 |
3 | go 1.23.0
4 |
5 | require (
6 | go.opentelemetry.io/otel v1.36.0
7 | go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.34.0
8 | go.opentelemetry.io/otel/sdk v1.36.0
9 | go.opentelemetry.io/otel/trace v1.36.0
10 | golang.org/x/oauth2 v0.30.0
11 | )
12 |
13 | require (
14 | cloud.google.com/go/compute/metadata v0.7.0 // indirect
15 | github.com/cenkalti/backoff/v4 v4.3.0 // indirect
16 | github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
17 | github.com/go-logr/logr v1.4.3 // indirect
18 | github.com/go-logr/stdr v1.2.2 // indirect
19 | github.com/google/uuid v1.6.0 // indirect
20 | github.com/grpc-ecosystem/grpc-gateway/v2 v2.26.0 // indirect
21 | github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
22 | go.opentelemetry.io/auto/sdk v1.1.0 // indirect
23 | go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.34.0 // indirect
24 | go.opentelemetry.io/otel/metric v1.36.0 // indirect
25 | go.opentelemetry.io/otel/sdk/metric v1.36.0 // indirect
26 | go.opentelemetry.io/proto/otlp v1.5.0 // indirect
27 | golang.org/x/net v0.40.0 // indirect
28 | golang.org/x/sys v0.33.0 // indirect
29 | golang.org/x/text v0.25.0 // indirect
30 | google.golang.org/genproto/googleapis/api v0.0.0-20250505200425-f936aa4a68b2 // indirect
31 | google.golang.org/genproto/googleapis/rpc v0.0.0-20250519155744-55703ea1f237 // indirect
32 | google.golang.org/grpc v1.72.2 // indirect
33 | google.golang.org/protobuf v1.36.6 // indirect
34 | )
35 |
--------------------------------------------------------------------------------
/exporter/collector/benchmark_test.go:
--------------------------------------------------------------------------------
1 | // Copyright 2024 Google LLC
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // https://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | package collector
16 |
17 | import (
18 | "testing"
19 |
20 | "github.com/stretchr/testify/assert"
21 | "go.opentelemetry.io/collector/pdata/pcommon"
22 | )
23 |
24 | func BenchmarkAttributesToLabels(b *testing.B) {
25 | attr := pcommon.NewMap()
26 | assert.NoError(b, attr.FromRaw(map[string]interface{}{
27 | "a": true,
28 | "b": false,
29 | "c": int64(12),
30 | "d": 12.3,
31 | "e": nil,
32 | "f": []byte{0xde, 0xad, 0xbe, 0xef},
33 | "g": []interface{}{"x", nil, "y"},
34 | "h": map[string]interface{}{"a": "b"},
35 | }))
36 | b.ResetTimer()
37 |
38 | for i := 0; i < b.N; i++ {
39 | assert.Len(b, attributesToLabels(attr), 8)
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/exporter/collector/googlemanagedprometheus/config.go:
--------------------------------------------------------------------------------
1 | // Copyright 2023 Google LLC
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // https://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | package googlemanagedprometheus
16 |
17 | // Config provides configuration options specific to the GMP translation.
18 | // It is meant to be embedded in the googlemanagedprometheus configuration.
19 | type Config struct {
20 | // AddMetricSuffixes controls whether suffixes are added to metric names. Defaults to true.
21 | AddMetricSuffixes bool `mapstructure:"add_metric_suffixes"`
22 | // ExtraMetricsConfig configures the target_info and otel_scope_info metrics.
23 | ExtraMetricsConfig ExtraMetricsConfig `mapstructure:"extra_metrics_config"`
24 | }
25 |
26 | // ExtraMetricsConfig controls the inclusion of additional metrics.
27 | type ExtraMetricsConfig struct {
28 | // Add `target_info` metric based on the resource. On by default.
29 | EnableTargetInfo bool `mapstructure:"enable_target_info"`
30 | // Add `otel_scope_info` metric and `scope_name`/`scope_version` attributes to all other metrics. On by default.
31 | EnableScopeInfo bool `mapstructure:"enable_scope_info"`
32 | }
33 |
34 | func DefaultConfig() Config {
35 | return Config{
36 | AddMetricSuffixes: true,
37 | ExtraMetricsConfig: ExtraMetricsConfig{
38 | EnableTargetInfo: true,
39 | EnableScopeInfo: true,
40 | },
41 | }
42 | }
43 |
44 | // Validate checks if the exporter configuration is valid.
45 | func (cfg *Config) Validate() error {
46 | return nil
47 | }
48 |
--------------------------------------------------------------------------------
/exporter/collector/googlemanagedprometheus/go.mod:
--------------------------------------------------------------------------------
1 | module github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/collector/googlemanagedprometheus
2 |
3 | go 1.23.0
4 |
5 | require (
6 | github.com/prometheus/common v0.62.0
7 | github.com/stretchr/testify v1.10.0
8 | go.opentelemetry.io/collector/featuregate v1.26.0
9 | go.opentelemetry.io/collector/pdata v1.33.0
10 | go.opentelemetry.io/collector/semconv v0.120.0
11 | google.golang.org/genproto/googleapis/api v0.0.0-20250505200425-f936aa4a68b2
12 | )
13 |
14 | require (
15 | github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
16 | github.com/go-logr/logr v1.4.3 // indirect
17 | github.com/gogo/protobuf v1.3.2 // indirect
18 | github.com/google/go-cmp v0.7.0 // indirect
19 | github.com/hashicorp/go-version v1.7.0 // indirect
20 | github.com/json-iterator/go v1.1.12 // indirect
21 | github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
22 | github.com/modern-go/reflect2 v1.0.2 // indirect
23 | github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
24 | github.com/prometheus/client_model v0.6.1 // indirect
25 | github.com/rogpeppe/go-internal v1.13.1 // indirect
26 | go.opentelemetry.io/otel v1.36.0 // indirect
27 | go.opentelemetry.io/otel/sdk/metric v1.36.0 // indirect
28 | go.uber.org/multierr v1.11.0 // indirect
29 | golang.org/x/net v0.40.0 // indirect
30 | golang.org/x/sys v0.33.0 // indirect
31 | golang.org/x/text v0.25.0 // indirect
32 | google.golang.org/genproto/googleapis/rpc v0.0.0-20250519155744-55703ea1f237 // indirect
33 | google.golang.org/grpc v1.72.2 // indirect
34 | google.golang.org/protobuf v1.36.6 // indirect
35 | gopkg.in/yaml.v3 v3.0.1 // indirect
36 | )
37 |
38 | replace (
39 | github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/collector => ../../collector
40 | github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/trace => ../../trace
41 | github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/resourcemapping => ../../../internal/resourcemapping
42 | )
43 |
--------------------------------------------------------------------------------
/exporter/collector/integrationtest/diff.go:
--------------------------------------------------------------------------------
1 | // Copyright 2021 Google LLC
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // https://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | package integrationtest
16 |
17 | import (
18 | "testing"
19 |
20 | "github.com/google/go-cmp/cmp"
21 | "github.com/google/go-cmp/cmp/cmpopts"
22 | "google.golang.org/protobuf/proto"
23 | "google.golang.org/protobuf/testing/protocmp"
24 |
25 | "github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/collector/integrationtest/protos"
26 | "github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/collector/integrationtest/testcases"
27 | )
28 |
29 | var (
30 | cmpOptions = []cmp.Option{
31 | protocmp.Transform(),
32 | cmpopts.EquateEmpty(),
33 | }
34 | )
35 |
36 | // Diff uses cmp.Diff(), protocmp, and some custom options to compare two protobuf messages.
37 | func DiffMetricProtos(t testing.TB, x, y *protos.MetricExpectFixture) string {
38 | x = proto.Clone(x).(*protos.MetricExpectFixture)
39 | y = proto.Clone(y).(*protos.MetricExpectFixture)
40 | testcases.NormalizeMetricFixture(t, x)
41 | testcases.NormalizeMetricFixture(t, y)
42 |
43 | return cmp.Diff(x, y, cmpOptions...)
44 | }
45 |
46 | // Diff uses cmp.Diff(), protocmp, and some custom options to compare two protobuf messages.
47 | func DiffLogProtos(t testing.TB, x, y *protos.LogExpectFixture) string {
48 | x = proto.Clone(x).(*protos.LogExpectFixture)
49 | y = proto.Clone(y).(*protos.LogExpectFixture)
50 | testcases.NormalizeLogFixture(t, x)
51 | testcases.NormalizeLogFixture(t, y)
52 |
53 | return cmp.Diff(x, y, cmpOptions...)
54 | }
55 |
56 | // Diff uses cmp.Diff(), protocmp, and some custom options to compare two protobuf messages.
57 | func DiffTraceProtos(t testing.TB, x, y *protos.TraceExpectFixture) string {
58 | x = proto.Clone(x).(*protos.TraceExpectFixture)
59 | y = proto.Clone(y).(*protos.TraceExpectFixture)
60 | testcases.NormalizeTraceFixture(t, x)
61 | testcases.NormalizeTraceFixture(t, y)
62 |
63 | return cmp.Diff(x, y, cmpOptions...)
64 | }
65 |
--------------------------------------------------------------------------------
/exporter/collector/integrationtest/factory_test.go:
--------------------------------------------------------------------------------
1 | // Copyright 2022 Google LLC
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // https://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | package integrationtest
16 |
17 | import (
18 | "testing"
19 |
20 | "github.com/stretchr/testify/assert"
21 | "go.opentelemetry.io/collector/component/componenttest"
22 |
23 | "github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/collector"
24 | )
25 |
26 | func TestCreateDefaultConfig(t *testing.T) {
27 | cfg := collector.DefaultConfig()
28 | assert.NotNil(t, cfg, "failed to create default config")
29 | assert.NoError(t, componenttest.CheckConfigStruct(cfg))
30 | }
31 |
--------------------------------------------------------------------------------
/exporter/collector/integrationtest/integration_selfobs_test.go:
--------------------------------------------------------------------------------
1 | // Copyright 2024 Google LLC
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // https://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | //go:build integrationtest
16 | // +build integrationtest
17 |
18 | package integrationtest
19 |
20 | import (
21 | "context"
22 | "log"
23 | "os"
24 | "testing"
25 |
26 | "github.com/google/uuid"
27 | "go.opentelemetry.io/otel"
28 | sdkmetric "go.opentelemetry.io/otel/sdk/metric"
29 | "go.opentelemetry.io/otel/sdk/resource"
30 | semconv "go.opentelemetry.io/otel/semconv/v1.24.0"
31 |
32 | mexporter "github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/metric"
33 | )
34 |
35 | func TestMain(m *testing.M) {
36 | ctx := context.Background()
37 | exporter, err := mexporter.New(mexporter.WithProjectID(os.Getenv("PROJECT_ID")))
38 | if err != nil {
39 | log.Fatalf("Failed to create self-obs exporter: %v", err)
40 | }
41 | version4Uuid, err := uuid.NewRandom()
42 | if err != nil {
43 | log.Fatalf("Failed to create uuid for resource: %v", err)
44 | }
45 | res, err := resource.New(
46 | ctx,
47 | resource.WithTelemetrySDK(),
48 | resource.WithFromEnv(),
49 | resource.WithAttributes(
50 | semconv.ServiceNameKey.String("integrationtest"),
51 | semconv.ServiceInstanceIDKey.String(version4Uuid.String()),
52 | ),
53 | )
54 | if err != nil {
55 | log.Fatalf("Failed to create self-obs resource: %v", err)
56 | }
57 | mp := sdkmetric.NewMeterProvider(
58 | sdkmetric.WithResource(res),
59 | sdkmetric.WithReader(sdkmetric.NewPeriodicReader(exporter)),
60 | )
61 | defer mp.Shutdown(ctx)
62 | otel.SetMeterProvider(mp)
63 | m.Run()
64 | }
65 |
--------------------------------------------------------------------------------
/exporter/collector/integrationtest/protos/fixtures.go:
--------------------------------------------------------------------------------
1 | // Copyright 2021 Google LLC
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // https://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | //go:build generate
16 | // +build generate
17 |
18 | //go:generate protoc -I=. --go_opt=paths=source_relative --go_out=. fixtures.proto
19 |
20 | package protos
21 |
--------------------------------------------------------------------------------
/exporter/collector/integrationtest/protos/fixtures.proto:
--------------------------------------------------------------------------------
1 | // Copyright 2021 Google LLC
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // https://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | syntax = "proto3";
16 | package fixtures;
17 | option go_package = "github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/collector/integrationtest/protos";
18 |
19 | import "metric_service.proto";
20 | import "logging_service.proto";
21 | import "tracing_service.proto";
22 |
23 | message MetricExpectFixture {
24 | repeated google.monitoring.v3.CreateTimeSeriesRequest create_time_series_requests = 1;
25 | repeated google.monitoring.v3.CreateMetricDescriptorRequest create_metric_descriptor_requests = 2;
26 | repeated google.monitoring.v3.CreateTimeSeriesRequest create_service_time_series_requests = 3;
27 | SelfObservabilityMetric self_observability_metrics = 4;
28 | string user_agent = 5;
29 | }
30 |
31 | message SelfObservabilityMetric {
32 | repeated google.monitoring.v3.CreateTimeSeriesRequest create_time_series_requests = 1;
33 | repeated google.monitoring.v3.CreateMetricDescriptorRequest create_metric_descriptor_requests = 2;
34 | }
35 |
36 | message LogExpectFixture {
37 | repeated google.logging.v2.WriteLogEntriesRequest write_log_entries_requests = 1;
38 | string user_agent = 2;
39 | SelfObservabilityMetric self_observability_metrics = 3;
40 | }
41 |
42 | message TraceExpectFixture {
43 | repeated google.tracing.v2.BatchWriteSpansRequest batch_write_spans_request = 1;
44 | string user_agent = 2;
45 | SelfObservabilityMetric self_observability_metrics = 3;
46 | }
47 |
--------------------------------------------------------------------------------
/exporter/collector/integrationtest/protos/logging_service.proto:
--------------------------------------------------------------------------------
1 | // Copyright 2022 Google LLC
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // https://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | // This is a stub of
16 | // https://github.com/googleapis/googleapis/blob/master/google/logging/v2/logging.proto
17 | // to avoid taking full dependency on googleapis repo
18 |
19 | syntax = "proto3";
20 | package google.logging.v2;
21 | option go_package = "cloud.google.com/go/logging/apiv2/loggingpb;logging";
22 |
23 | message WriteLogEntriesRequest{}
24 |
--------------------------------------------------------------------------------
/exporter/collector/integrationtest/protos/metric_service.proto:
--------------------------------------------------------------------------------
1 | // Copyright 2021 Google LLC
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // https://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | // This is a stub of
16 | // https://github.com/googleapis/googleapis/blob/master/google/monitoring/v3/metric_service.proto
17 | // to avoid taking full dependency on googleapis repo
18 |
19 | syntax = "proto3";
20 | package google.monitoring.v3;
21 | option go_package = "cloud.google.com/go/monitoring/apiv3/v2/monitoringpb;monitoring";
22 |
23 | message CreateTimeSeriesRequest {}
24 | message CreateMetricDescriptorRequest {}
25 |
--------------------------------------------------------------------------------
/exporter/collector/integrationtest/protos/tracing_service.proto:
--------------------------------------------------------------------------------
1 | // Copyright 2022 Google LLC
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // https://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | // This is a stub of
16 | // https://github.com/googleapis/googleapis/blob/master/google/devtools/cloudtrace/v2/tracing.proto
17 | // to avoid taking full dependency on googleapis repo
18 |
19 | syntax = "proto3";
20 | package google.tracing.v2;
21 | option go_package = "cloud.google.com/go/trace/apiv2/tracepb;tracing";
22 |
23 | message BatchWriteSpansRequest {}
--------------------------------------------------------------------------------
/exporter/collector/integrationtest/testcases/exporter_settings.go:
--------------------------------------------------------------------------------
1 | // Copyright 2025 Google LLC
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // https://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | package testcases
16 |
17 | import (
18 | "fmt"
19 | "runtime"
20 | "strings"
21 |
22 | "go.opentelemetry.io/collector/component"
23 | "go.opentelemetry.io/collector/exporter"
24 | "go.opentelemetry.io/otel/metric"
25 | "go.uber.org/zap"
26 |
27 | "github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/collector"
28 | )
29 |
30 | func NewTestExporterSettings(logger *zap.Logger, meterProvider metric.MeterProvider) exporter.Settings {
31 | return exporter.Settings{
32 | TelemetrySettings: component.TelemetrySettings{
33 | Logger: logger,
34 | MeterProvider: meterProvider,
35 | },
36 | BuildInfo: component.BuildInfo{
37 | Description: "GoogleCloudExporter Integration Test",
38 | Version: collector.Version(),
39 | },
40 | }
41 | }
42 |
43 | func SetTestUserAgent(cfg *collector.Config, buildInfo component.BuildInfo) {
44 | collector.SetUserAgent(cfg, buildInfo)
45 | cfg.UserAgent = UserAgentRemoveRuntimeInfo(cfg.UserAgent)
46 | }
47 |
48 | func UserAgentRemoveRuntimeInfo(userAgent string) string {
49 | runtimeInfo := fmt.Sprintf(" (%s/%s)", runtime.GOOS, runtime.GOARCH)
50 | return strings.ReplaceAll(userAgent, runtimeInfo, "")
51 | }
52 |
--------------------------------------------------------------------------------
/exporter/collector/integrationtest/testcases/testcases_traces.go:
--------------------------------------------------------------------------------
1 | // Copyright 2022 Google LLC
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // https://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | package testcases
16 |
17 | import "github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/collector"
18 |
19 | var TracesTestCases = []TestCase{
20 | {
21 | Name: "Basic traces",
22 | OTLPInputFixturePath: "testdata/fixtures/traces/traces_basic.json",
23 | ExpectFixturePath: "testdata/fixtures/traces/traces_basic_expected.json",
24 | },
25 | {
26 | Name: "Custom User Agent",
27 | OTLPInputFixturePath: "testdata/fixtures/traces/traces_basic.json",
28 | ExpectFixturePath: "testdata/fixtures/traces/traces_user_agent_expected.json",
29 | ConfigureCollector: func(cfg *collector.Config) {
30 | cfg.UserAgent = "custom-user-agent {{version}}"
31 | },
32 | },
33 | }
34 |
--------------------------------------------------------------------------------
/exporter/collector/integrationtest/testdata/config.yaml:
--------------------------------------------------------------------------------
1 | receivers:
2 | nop:
3 |
4 | processors:
5 | nop:
6 |
7 | exporters:
8 | googlecloud:
9 | googlecloud/customname:
10 | project: my-project
11 | user_agent: opentelemetry-collector-contrib {{version}}
12 | trace:
13 | endpoint: test-trace-endpoint
14 | use_insecure: true
15 | grpc_pool_size: 1
16 | metric:
17 | endpoint: test-metric-endpoint
18 | use_insecure: true
19 | prefix: prefix
20 | skip_create_descriptor: true
21 | grpc_pool_size: 1
22 | log:
23 | default_log_name: foo-log
24 | grpc_pool_size: 1
25 |
26 | service:
27 | pipelines:
28 | traces:
29 | receivers: [nop]
30 | processors: [nop]
31 | exporters: [googlecloud]
32 | metrics:
33 | receivers: [nop]
34 | processors: [nop]
35 | exporters: [googlecloud]
36 |
37 |
--------------------------------------------------------------------------------
/exporter/collector/integrationtest/testdata/fixtures/logs/logs_apache_error_scope.json:
--------------------------------------------------------------------------------
1 | {
2 | "resourceLogs": [
3 | {
4 | "resource": {
5 | "attributes": [
6 | {
7 | "key": "cloud.platform",
8 | "value": {
9 | "stringValue": "gcp_compute_engine"
10 | }
11 | }
12 | ]
13 | },
14 | "scopeLogs": [
15 | {
16 | "scope": {
17 | "name": "scopeNameFoo",
18 | "version": "9000"
19 | },
20 | "logRecords": [
21 | {
22 | "timeUnixNano": "1651013315606298000",
23 | "body": {
24 | "kvlistValue": {
25 | "values": [
26 | {
27 | "key": "time",
28 | "value": {
29 | "stringValue": "Tue Apr 26 22:48:35.606298 2022"
30 | }
31 | },
32 | {
33 | "key": "severity",
34 | "value": {
35 | "stringValue": "notice"
36 | }
37 | },
38 | {
39 | "key": "message",
40 | "value": {
41 | "stringValue": "[pid 769:tid 140159306111872] AH00094: Command line: '/usr/local/apache/bin/httpd'"
42 | }
43 | }
44 | ]
45 | }
46 | },
47 | "attributes": [
48 | {
49 | "key": "log.file.name",
50 | "value": {
51 | "stringValue": "test.log"
52 | }
53 | },
54 | {
55 | "key": "gcp.log_name",
56 | "value": {
57 | "stringValue": "apache-error-fixture"
58 | }
59 | }
60 | ],
61 | "traceId": "",
62 | "spanId": ""
63 | }
64 | ]
65 | }
66 | ]
67 | }
68 | ]
69 | }
70 |
--------------------------------------------------------------------------------
/exporter/collector/integrationtest/testdata/fixtures/logs/logs_apache_text_error.json:
--------------------------------------------------------------------------------
1 | {
2 | "resourceLogs": [
3 | {
4 | "resource": {
5 | "attributes": [
6 | {
7 | "key": "cloud.platform",
8 | "value": {
9 | "stringValue": "gcp_compute_engine"
10 | }
11 | },
12 | {
13 | "key": "service.name",
14 | "value": {
15 | "stringValue": "apache_service"
16 | }
17 | },
18 | {
19 | "key": "service.namespace",
20 | "value": {
21 | "stringValue": ""
22 | }
23 | }
24 | ]
25 | },
26 | "scopeLogs": [
27 | {
28 | "scope": {},
29 | "logRecords": [
30 | {
31 | "observedTimeUnixNano": "1650984816000000000",
32 | "body": {
33 | "stringValue": "127.0.0.1 - - [26/Apr/2022:22:53:36 +0800] \"GET / HTTP/1.1\" 200 1247"
34 | },
35 | "severity_number": 17,
36 | "attributes": [
37 | {
38 | "key": "gcp.log_name",
39 | "value": {
40 | "stringValue": "my-log-name-foo"
41 | }
42 | }
43 | ],
44 | "traceId": "",
45 | "spanId": ""
46 | },
47 | {
48 | "observedTimeUnixNano": "1650984816000000000",
49 | "body": {
50 | "stringValue": "127.0.0.1 - - [26/Apr/2022:22:53:36 +0800] \"GET / HTTP/1.1\" 200 1247"
51 | },
52 | "severity_text": "ERROR",
53 | "attributes": [
54 | {
55 | "key": "gcp.log_name",
56 | "value": {
57 | "stringValue": "my-log-name-foo"
58 | }
59 | }
60 | ],
61 | "traceId": "",
62 | "spanId": ""
63 | }
64 | ]
65 | }
66 | ]
67 | }
68 | ]
69 | }
70 |
--------------------------------------------------------------------------------
/exporter/collector/integrationtest/testdata/fixtures/metrics/boolean_gauge.json:
--------------------------------------------------------------------------------
1 | {
2 | "resourceMetrics": [
3 | {
4 | "resource": {
5 | "attributes": [
6 | {
7 | "key": "cloud.availability_zone",
8 | "value": {
9 | "stringValue": "us-central1-c"
10 | }
11 | },
12 | {
13 | "key": "service.name",
14 | "value": {
15 | "stringValue": "demo"
16 | }
17 | },
18 | {
19 | "key": "service.instance.id",
20 | "value": {
21 | "stringValue": "10.92.5.2:15692"
22 | }
23 | }
24 | ]
25 | },
26 | "scopeMetrics": [
27 | {
28 | "scope": {},
29 | "metrics": [
30 | {
31 | "name": "observer.boolean.collector",
32 | "unit": "{gcp.BOOL}",
33 | "gauge": {
34 | "dataPoints": [
35 | {
36 | "attributes": [
37 | {
38 | "key": "key",
39 | "value": {
40 | "stringValue": "value-1"
41 | }
42 | }
43 | ],
44 | "startTimeUnixNano": "11651379494838206464",
45 | "timeUnixNano": "1687377293673694987",
46 | "asInt": "0"
47 | },
48 | {
49 | "attributes": [
50 | {
51 | "key": "key",
52 | "value": {
53 | "stringValue": "value-2"
54 | }
55 | }
56 | ],
57 | "startTimeUnixNano": "1688083417576000000",
58 | "timeUnixNano": "1688083820000000000",
59 | "asInt": "393"
60 | },
61 | {
62 | "attributes": [
63 | {
64 | "key": "key",
65 | "value": {
66 | "stringValue": "value-3"
67 | }
68 | }
69 | ],
70 | "startTimeUnixNano": "1688083940000000000",
71 | "timeUnixNano": "1688084000000000000",
72 | "asInt": "-272"
73 | }
74 | ]
75 | }
76 | }
77 | ]
78 | }
79 | ]
80 | }
81 | ]
82 | }
--------------------------------------------------------------------------------
/exporter/collector/integrationtest/testdata/fixtures/metrics/counter.json:
--------------------------------------------------------------------------------
1 | {
2 | "resourceMetrics": [
3 | {
4 | "resource": {
5 | "attributes": [
6 | {
7 | "key": "cloud.availability_zone",
8 | "value": {
9 | "stringValue": "us-central1-c"
10 | }
11 | },
12 | {
13 | "key": "service.name",
14 | "value": {
15 | "stringValue": "demo"
16 | }
17 | },
18 | {
19 | "key": "service.instance.id",
20 | "value": {
21 | "stringValue": "10.92.5.2:15692"
22 | }
23 | }
24 | ]
25 | },
26 | "scopeMetrics": [
27 | {
28 | "scope": {},
29 | "metrics": [
30 | {
31 | "name": "test.counter",
32 | "description": "This is a test counter",
33 | "unit": "s",
34 | "sum": {
35 | "dataPoints": [
36 | {
37 | "attributes": [
38 | {
39 | "key": "foo.bar",
40 | "value": {
41 | "stringValue": "baz"
42 | }
43 | }
44 | ],
45 | "startTimeUnixNano": "1634322229906722370",
46 | "timeUnixNano": "1634322234906722370",
47 | "asInt": "253"
48 | }
49 | ],
50 | "aggregationTemporality": "AGGREGATION_TEMPORALITY_CUMULATIVE",
51 | "isMonotonic": true
52 | }
53 | }
54 | ]
55 | }
56 | ]
57 | }
58 | ]
59 | }
60 |
--------------------------------------------------------------------------------
/exporter/collector/integrationtest/testdata/fixtures/metrics/create_service_timeseries.json:
--------------------------------------------------------------------------------
1 | {
2 | "resourceMetrics": [
3 | {
4 | "resource": {
5 | "attributes": [
6 | {
7 | "key": "cloud.platform",
8 | "value": {
9 | "stringValue": "gcp_kubernetes_engine"
10 | }
11 | },
12 | {
13 | "key": "k8s.node.name",
14 | "value": {
15 | "stringValue": "gke-rabbitmq-test-dev-default-pool-4ffbde79-k6w0"
16 | }
17 | },
18 | {
19 | "key": "cloud.availability_zone",
20 | "value": {
21 | "stringValue": "us-central1-c"
22 | }
23 | },
24 | {
25 | "key": "k8s.cluster.name",
26 | "value": {
27 | "stringValue": "rabbitmq-test-dev"
28 | }
29 | }
30 | ]
31 | },
32 | "scopeMetrics": [
33 | {
34 | "scope": {
35 | "name": "foo",
36 | "version": "1.2.3"
37 | },
38 | "metrics": [
39 | {
40 | "name":"kubernetes.io/internal/nodes/clustermetrics/node_network_availability_transition_time",
41 | "description":"Node network unavailable condition last transition time (seconds since epoch)",
42 | "gauge":{
43 | "dataPoints":[
44 | {
45 | "attributes":[
46 | {
47 | "key":"network_unavailable",
48 | "value":{
49 | "stringValue":"False"
50 | }
51 | }
52 | ],
53 | "timeUnixNano":"1639162382976000000",
54 | "asInt":"1639069893"
55 | }
56 | ]
57 | }
58 | }
59 | ]
60 | }
61 | ]
62 | }
63 | ]
64 | }
65 |
--------------------------------------------------------------------------------
/exporter/collector/integrationtest/testdata/fixtures/metrics/delta_counter.json:
--------------------------------------------------------------------------------
1 | {
2 | "resourceMetrics": [
3 | {
4 | "resource": {
5 | "attributes": [
6 | {
7 | "key": "cloud.availability_zone",
8 | "value": {
9 | "stringValue": "us-central1-c"
10 | }
11 | },
12 | {
13 | "key": "service.name",
14 | "value": {
15 | "stringValue": "demo"
16 | }
17 | },
18 | {
19 | "key": "service.instance.id",
20 | "value": {
21 | "stringValue": "10.92.5.2:15692"
22 | }
23 | }
24 | ]
25 | },
26 | "scopeMetrics": [
27 | {
28 | "scope": {},
29 | "metrics": [
30 | {
31 | "name": "delta.counter",
32 | "description": "This is a test counter with delta temporality",
33 | "unit": "s",
34 | "sum": {
35 | "dataPoints": [
36 | {
37 | "attributes": [
38 | {
39 | "key": "foo.bar",
40 | "value": {
41 | "stringValue": "baz"
42 | }
43 | }
44 | ],
45 | "startTimeUnixNano": "1634322229906722370",
46 | "timeUnixNano": "1634322234906722370",
47 | "asInt": "253"
48 | }
49 | ],
50 | "aggregationTemporality": "AGGREGATION_TEMPORALITY_DELTA",
51 | "isMonotonic": true
52 | }
53 | }
54 | ]
55 | }
56 | ]
57 | }
58 | ]
59 | }
60 |
--------------------------------------------------------------------------------
/exporter/collector/integrationtest/testdata/fixtures/metrics/gauge.json:
--------------------------------------------------------------------------------
1 | {
2 | "resourceMetrics": [
3 | {
4 | "resource": {
5 | "attributes": [
6 | {
7 | "key": "cloud.availability_zone",
8 | "value": {
9 | "stringValue": "us-central1-c"
10 | }
11 | },
12 | {
13 | "key": "service.name",
14 | "value": {
15 | "stringValue": "demo"
16 | }
17 | },
18 | {
19 | "key": "service.instance.id",
20 | "value": {
21 | "stringValue": "10.92.5.2:15692"
22 | }
23 | }
24 | ]
25 | },
26 | "scopeMetrics": [
27 | {
28 | "scope": {},
29 | "metrics": [
30 | {
31 | "name": "simple.gauge",
32 | "unit": "s",
33 | "gauge": {
34 | "dataPoints": [
35 | {
36 | "attributes": [
37 | {
38 | "key": "some.lemons",
39 | "value": {
40 | "stringValue": "13"
41 | }
42 | }
43 | ],
44 | "timeUnixNano": "1649443516286000000",
45 | "asDouble": 1
46 | },
47 | {
48 | "attributes": [
49 | {
50 | "key": "some.lemons",
51 | "value": {
52 | "stringValue": "1"
53 | }
54 | }
55 | ],
56 | "timeUnixNano": "1649443516286000000",
57 | "asDouble": 13
58 | }
59 | ]
60 | }
61 | }
62 | ]
63 | }
64 | ]
65 | }
66 | ]
67 | }
--------------------------------------------------------------------------------
/exporter/collector/integrationtest/testdata/fixtures/metrics/nonmonotonic_counter.json:
--------------------------------------------------------------------------------
1 | {
2 | "resourceMetrics": [
3 | {
4 | "resource": {
5 | "attributes": [
6 | {
7 | "key": "cloud.availability_zone",
8 | "value": {
9 | "stringValue": "us-central1-c"
10 | }
11 | },
12 | {
13 | "key": "service.name",
14 | "value": {
15 | "stringValue": "demo"
16 | }
17 | },
18 | {
19 | "key": "service.instance.id",
20 | "value": {
21 | "stringValue": "10.92.5.2:15692"
22 | }
23 | }
24 | ]
25 | },
26 | "scopeMetrics": [
27 | {
28 | "scope": {},
29 | "metrics": [
30 | {
31 | "name": "system.memory.usage",
32 | "description": "Bytes of memory in use.",
33 | "unit": "By",
34 | "sum": {
35 | "dataPoints": [
36 | {
37 | "attributes": [
38 | {
39 | "key": "state",
40 | "value": {
41 | "stringValue": "used"
42 | }
43 | }
44 | ],
45 | "timeUnixNano": "1634877479074335121",
46 | "asInt": "6641752448"
47 | }
48 | ],
49 | "aggregationTemporality": "AGGREGATION_TEMPORALITY_CUMULATIVE"
50 | }
51 | }
52 | ]
53 | }
54 | ]
55 | }
56 | ]
57 | }
58 |
--------------------------------------------------------------------------------
/exporter/collector/integrationtest/testdata/fixtures/metrics/summary.json:
--------------------------------------------------------------------------------
1 | {
2 | "resourceMetrics": [
3 | {
4 | "resource": {
5 | "attributes": [
6 | {
7 | "key": "cloud.availability_zone",
8 | "value": {
9 | "stringValue": "us-central1-c"
10 | }
11 | },
12 | {
13 | "key": "service.name",
14 | "value": {
15 | "stringValue": "demo"
16 | }
17 | },
18 | {
19 | "key": "service.instance.id",
20 | "value": {
21 | "stringValue": "10.92.5.2:15692"
22 | }
23 | }
24 | ]
25 | },
26 | "scopeMetrics": [
27 | {
28 | "scope": {},
29 | "metrics": [
30 | {
31 | "name": "test.summary",
32 | "description": "This is a test summary",
33 | "unit": "s",
34 | "summary": {
35 | "dataPoints": [
36 | {
37 | "attributes": [
38 | {
39 | "key": "foo.bar",
40 | "value": {
41 | "stringValue": "baz"
42 | }
43 | }
44 | ],
45 | "startTimeUnixNano": "1634322229906722370",
46 | "timeUnixNano": "1634322234906722370",
47 | "count": "10",
48 | "sum": 123.4,
49 | "quantile_values": [
50 | {
51 | "quantile": 0.5,
52 | "value": 10.2
53 | },
54 | {
55 | "quantile": 0.75,
56 | "value": 25.5
57 | },
58 | {
59 | "quantile": 0.9,
60 | "value": 100.2
61 | }
62 | ]
63 | }
64 | ]
65 | }
66 | }
67 | ]
68 | }
69 | ]
70 | }
71 | ]
72 | }
--------------------------------------------------------------------------------
/exporter/collector/integrationtest/testdata/fixtures/metrics/untyped_gauge.json:
--------------------------------------------------------------------------------
1 | {
2 | "resourceMetrics": [
3 | {
4 | "resource": {
5 | "attributes": [
6 | {
7 | "key": "cloud.availability_zone",
8 | "value": {
9 | "stringValue": "us-central1-c"
10 | }
11 | },
12 | {
13 | "key": "service.name",
14 | "value": {
15 | "stringValue": "demo"
16 | }
17 | },
18 | {
19 | "key": "service.instance.id",
20 | "value": {
21 | "stringValue": "10.92.5.2:15692"
22 | }
23 | }
24 | ]
25 | },
26 | "scopeMetrics": [
27 | {
28 | "scope": {},
29 | "metrics": [
30 | {
31 | "name": "fake_untyped_metric",
32 | "gauge": {
33 | "dataPoints": [
34 | {
35 | "attributes": [
36 | {
37 | "key": "ex_com_lemons_untyped",
38 | "value": {
39 | "stringValue": "13"
40 | }
41 | }
42 | ],
43 | "startTimeUnixNano": "1649443416286000000",
44 | "timeUnixNano": "1649443516286000000",
45 | "asDouble": 3
46 | }
47 | ]
48 | },
49 | "metadata": [
50 | {
51 | "key": "prometheus.type",
52 | "value": {
53 | "stringValue": "unknown"
54 | }
55 | }
56 | ]
57 | }
58 | ]
59 | }
60 | ]
61 | }
62 | ]
63 | }
--------------------------------------------------------------------------------
/exporter/collector/integrationtest/testdata/fixtures/metrics/with_resource_filter.json:
--------------------------------------------------------------------------------
1 | {
2 | "resourceMetrics": [
3 | {
4 | "resource": {
5 | "attributes": [
6 | {
7 | "key": "service.name",
8 | "value": {
9 | "stringValue": "foo-service"
10 | }
11 | },
12 | {
13 | "key": "service.namespace",
14 | "value": {
15 | "stringValue": "foo"
16 | }
17 | },
18 | {
19 | "key": "service.instance.id",
20 | "value": {
21 | "stringValue": "abc123"
22 | }
23 | },
24 | {
25 | "key": "telemetry.sdk.language",
26 | "value": {
27 | "stringValue": "java"
28 | }
29 | },
30 | {
31 | "key": "telemetry.sdk.version",
32 | "value": {
33 | "stringValue": "1.1.1"
34 | }
35 | },
36 | {
37 | "key": "something.uninteresting",
38 | "value": {
39 | "stringValue": "baz"
40 | }
41 | }
42 | ]
43 | },
44 | "scopeMetrics": [
45 | {
46 | "scope": {},
47 | "metrics": [
48 | {
49 | "name": "testresourcefilter",
50 | "description": "This is a test counter",
51 | "unit": "1",
52 | "sum": {
53 | "dataPoints": [
54 | {
55 | "attributes": [
56 | {
57 | "key": "foo",
58 | "value": {
59 | "stringValue": "bar"
60 | }
61 | }
62 | ],
63 | "startTimeUnixNano": "1634322229906722370",
64 | "timeUnixNano": "1634322234906722370",
65 | "asInt": "253"
66 | }
67 | ],
68 | "aggregationTemporality": "AGGREGATION_TEMPORALITY_CUMULATIVE",
69 | "isMonotonic": true
70 | }
71 | }
72 | ]
73 | }
74 | ]
75 | }
76 | ]
77 | }
78 |
--------------------------------------------------------------------------------
/exporter/collector/integrationtest/testdata/gmp_config.yaml:
--------------------------------------------------------------------------------
1 | receivers:
2 | nop:
3 |
4 | processors:
5 | nop:
6 |
7 | exporters:
8 | googlemanagedprometheus:
9 | googlemanagedprometheus/customname:
10 | project: my-project
11 | user_agent: opentelemetry-collector-contrib {{version}}
12 | endpoint: test-metric-endpoint
13 | use_insecure: true
14 |
15 | service:
16 | pipelines:
17 | metrics:
18 | receivers: [nop]
19 | processors: [nop]
20 | exporters: [googlemanagedprometheus]
21 |
--------------------------------------------------------------------------------
/exporter/collector/integrationtest/traces_integration_test.go:
--------------------------------------------------------------------------------
1 | // Copyright 2022 Google LLC
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // https://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | //go:build integrationtest
16 | // +build integrationtest
17 |
18 | package integrationtest
19 |
20 | import (
21 | "context"
22 | "os"
23 | "testing"
24 | "time"
25 |
26 | "github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/collector"
27 | "github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/collector/integrationtest/testcases"
28 | "github.com/stretchr/testify/require"
29 | "go.opentelemetry.io/collector/component/componenttest"
30 | "go.opentelemetry.io/otel/metric/noop"
31 | "go.uber.org/zap"
32 | )
33 |
34 | func createTracesExporter(
35 | ctx context.Context,
36 | t *testing.T,
37 | test *testcases.TestCase,
38 | ) *collector.TraceExporter {
39 | cfg := test.CreateTraceConfig()
40 | logger, _ := zap.NewProduction()
41 | cfg.ProjectID = os.Getenv("PROJECT_ID")
42 |
43 | set := testcases.NewTestExporterSettings(logger, noop.NewMeterProvider())
44 | testcases.SetTestUserAgent(&cfg, set.BuildInfo)
45 | exporter, err := collector.NewGoogleCloudTracesExporter(
46 | ctx,
47 | cfg,
48 | set,
49 | collector.DefaultTimeout,
50 | )
51 | require.NoError(t, err)
52 | err = exporter.Start(ctx, componenttest.NewNopHost())
53 | require.NoError(t, err)
54 | t.Log("Collector traces exporter started")
55 | return exporter
56 | }
57 |
58 | func TestIntegrationTraces(t *testing.T) {
59 | ctx := context.Background()
60 | endTime := time.Now()
61 | startTime := endTime.Add(-time.Second)
62 |
63 | for _, test := range testcases.TracesTestCases {
64 | test := test
65 |
66 | t.Run(test.Name, func(t *testing.T) {
67 | test.SkipIfNeeded(t)
68 | traces := test.LoadOTLPTracesInput(t, startTime, endTime)
69 | exporter := createTracesExporter(ctx, t, &test)
70 | defer func() { require.NoError(t, exporter.Shutdown(ctx)) }()
71 |
72 | require.NoError(
73 | t,
74 | exporter.PushTraces(ctx, traces),
75 | "Failed to export metrics",
76 | )
77 | })
78 | }
79 | }
80 |
--------------------------------------------------------------------------------
/exporter/collector/integrationtest/traces_test.go:
--------------------------------------------------------------------------------
1 | // Copyright 2022 Google LLC
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // https://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | package integrationtest
16 |
17 | import (
18 | "context"
19 | "testing"
20 | "time"
21 |
22 | "github.com/stretchr/testify/require"
23 |
24 | "github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/collector/integrationtest/protos"
25 | "github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/collector/integrationtest/testcases"
26 | "github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/cloudmock"
27 | )
28 |
29 | func TestTraces(t *testing.T) {
30 | ctx := context.Background()
31 | endTime := time.Now()
32 | startTime := endTime.Add(-time.Second)
33 |
34 | for _, test := range testcases.TracesTestCases {
35 | t.Run(test.Name, func(t *testing.T) {
36 | test.SkipIfNeeded(t)
37 |
38 | traces := test.LoadOTLPTracesInput(t, startTime, endTime)
39 | testServer, err := cloudmock.NewTracesTestServer()
40 | require.NoError(t, err)
41 | go testServer.Serve()
42 | defer testServer.Shutdown()
43 |
44 | inMemoryOTelExporter, err := NewInMemoryOTelExporter()
45 | require.NoError(t, err)
46 | //nolint:errcheck
47 | defer inMemoryOTelExporter.Shutdown(ctx)
48 | testServerExporter := NewTraceTestExporter(ctx, t, testServer, test.CreateTraceConfig(), inMemoryOTelExporter.MeterProvider)
49 |
50 | err = testServerExporter.PushTraces(ctx, traces)
51 | if !test.ExpectErr {
52 | require.NoError(t, err, "Failed to export traces to local test server")
53 | } else {
54 | require.Error(t, err, "Did not see expected error")
55 | }
56 | require.NoError(t, testServerExporter.Shutdown(ctx))
57 |
58 | expectFixture := test.LoadTraceExpectFixture(
59 | t,
60 | startTime,
61 | endTime,
62 | )
63 |
64 | selfObsMetrics, err := inMemoryOTelExporter.Proto(ctx)
65 | require.NoError(t, err)
66 | fixture := &protos.TraceExpectFixture{
67 | BatchWriteSpansRequest: testServer.CreateBatchWriteSpansRequests(),
68 | UserAgent: testServer.UserAgent(),
69 | SelfObservabilityMetrics: selfObsMetrics,
70 | }
71 |
72 | diff := DiffTraceProtos(
73 | t,
74 | fixture,
75 | expectFixture,
76 | )
77 | if diff != "" {
78 | require.Fail(
79 | t,
80 | "Expected requests fixture and actual GCM requests differ",
81 | diff,
82 | )
83 | }
84 | })
85 | }
86 | }
87 |
--------------------------------------------------------------------------------
/exporter/collector/internal/datapointstorage/benchmark_test.go:
--------------------------------------------------------------------------------
1 | // Copyright 2024 Google LLC
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // https://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | package datapointstorage
16 |
17 | import (
18 | "testing"
19 |
20 | "go.opentelemetry.io/collector/pdata/pcommon"
21 | "go.opentelemetry.io/collector/pdata/pmetric"
22 | monitoredrespb "google.golang.org/genproto/googleapis/api/monitoredres"
23 | )
24 |
25 | func BenchmarkIdentifier(b *testing.B) {
26 | metric := pmetric.NewMetric()
27 | metric.SetName("custom.googleapis.com/test.metric")
28 | attrs := pcommon.NewMap()
29 | attrs.PutStr("string", "strval")
30 | attrs.PutBool("bool", true)
31 | attrs.PutInt("int", 123)
32 | attrs.PutInt("int1", 123)
33 | attrs.PutInt("int2", 123)
34 | attrs.PutInt("int3", 123)
35 | attrs.PutInt("int4", 123)
36 | attrs.PutInt("int5", 123)
37 | monitoredResource := &monitoredrespb.MonitoredResource{
38 | Type: "k8s_container",
39 | Labels: map[string]string{
40 | "location": "us-central1-b",
41 | "project": "project-foo",
42 | "cluster": "cluster-foo",
43 | "pod": "pod-foo",
44 | "namespace": "namespace-foo",
45 | "container": "container-foo",
46 | },
47 | }
48 | extraLabels := map[string]string{
49 | "foo": "bar",
50 | "hello": "world",
51 | "ding": "dong",
52 | }
53 |
54 | b.ResetTimer()
55 | for i := 0; i < b.N; i++ {
56 | Identifier(monitoredResource, extraLabels, metric, attrs)
57 | }
58 | }
59 |
--------------------------------------------------------------------------------
/exporter/collector/internal/logsutil/logsutil.go:
--------------------------------------------------------------------------------
1 | // Copyright 2023 Google LLC
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | package logsutil
16 |
17 | // ExporterConfig configures the Logs exporter with various settings post-initializition.
18 | // It is meant to be used by integration tests.
19 | type ExporterConfig struct {
20 | // MaxEntrySize is the maximum size of an individual LogEntry in bytes. Entries
21 | // larger than this size will be split into multiple entries.
22 | MaxEntrySize int
23 | // MaxRequestSize is the maximum size of a batch WriteLogEntries request in bytes.
24 | // Request larger than this size will be split into multiple requests.
25 | MaxRequestSize int
26 | }
27 |
--------------------------------------------------------------------------------
/exporter/collector/internal/normalization/types.go:
--------------------------------------------------------------------------------
1 | // Copyright 2022 Google LLC
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // https://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | package normalization
16 |
17 | import (
18 | "go.opentelemetry.io/collector/pdata/pmetric"
19 | )
20 |
21 | // Normalizer can normalize data points to handle cases in which the start time is unknown.
22 | type Normalizer interface {
23 | // NormalizeExponentialHistogramDataPoint normalizes an exponential histogram.
24 | // It returns the normalized point, and true if the point should be kept.
25 | NormalizeExponentialHistogramDataPoint(point pmetric.ExponentialHistogramDataPoint, identifier uint64) bool
26 | // NormalizeHistogramDataPoint normalizes a cumulative histogram.
27 | // It returns the normalized point, and true if the point should be kept.
28 | NormalizeHistogramDataPoint(point pmetric.HistogramDataPoint, identifier uint64) bool
29 | // NormalizeNumberDataPoint normalizes a cumulative, monotonic sum.
30 | // It returns the normalized point, and true if the point should be kept.
31 | NormalizeNumberDataPoint(point pmetric.NumberDataPoint, identifier uint64) bool
32 | // NormalizeSummaryDataPoint normalizes a summary.
33 | // It returns the normalized point, and true if the point should be kept.
34 | NormalizeSummaryDataPoint(point pmetric.SummaryDataPoint, identifier uint64) bool
35 | }
36 |
--------------------------------------------------------------------------------
/exporter/collector/monitoredresource.go:
--------------------------------------------------------------------------------
1 | // Copyright 2022 Google LLC
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // https://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | package collector
16 |
17 | import (
18 | "regexp"
19 | "strings"
20 |
21 | "go.opentelemetry.io/collector/pdata/pcommon"
22 | semconv "go.opentelemetry.io/collector/semconv/v1.22.0"
23 | monitoredrespb "google.golang.org/genproto/googleapis/api/monitoredres"
24 |
25 | "github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/resourcemapping"
26 | )
27 |
28 | type attributes struct {
29 | Attrs pcommon.Map
30 | }
31 |
32 | func (attrs *attributes) GetString(key string) (string, bool) {
33 | value, ok := attrs.Attrs.Get(key)
34 | if ok {
35 | return value.AsString(), ok
36 | }
37 | return "", false
38 | }
39 |
40 | // defaultResourceToMonitoredResource pdata Resource to a GCM Monitored Resource.
41 | func defaultResourceToMonitoringMonitoredResource(resource pcommon.Resource) *monitoredrespb.MonitoredResource {
42 | return resourcemapping.ResourceAttributesToMonitoringMonitoredResource(&attributes{
43 | Attrs: resource.Attributes(),
44 | })
45 | }
46 |
47 | // defaultResourceToMonitoredResource pdata Resource to a GCM Monitored Resource.
48 | func defaultResourceToLoggingMonitoredResource(resource pcommon.Resource) *monitoredrespb.MonitoredResource {
49 | return resourcemapping.ResourceAttributesToLoggingMonitoredResource(&attributes{
50 | Attrs: resource.Attributes(),
51 | })
52 | }
53 |
54 | // resourceToLabels converts the Resource attributes into labels.
55 | // TODO(@damemi): Refactor to pass control-coupling lint check.
56 | //
57 | //nolint:revive
58 | func filterAttributes(
59 | attributes pcommon.Map,
60 | serviceResourceLabels bool,
61 | resourceFilters []ResourceFilter,
62 | ) pcommon.Map {
63 | attrs := pcommon.NewMap()
64 | attributes.Range(func(k string, v pcommon.Value) bool {
65 | // Is a service attribute and should be included
66 | if serviceResourceLabels &&
67 | (k == semconv.AttributeServiceName ||
68 | k == semconv.AttributeServiceNamespace ||
69 | k == semconv.AttributeServiceInstanceID) {
70 | if len(v.AsString()) > 0 {
71 | v.CopyTo(attrs.PutEmpty(k))
72 | }
73 | return true
74 | }
75 | // Matches one of the resource filters
76 | for _, resourceFilter := range resourceFilters {
77 | if match, _ := regexp.Match(resourceFilter.Regex, []byte(k)); strings.HasPrefix(k, resourceFilter.Prefix) && match {
78 | v.CopyTo(attrs.PutEmpty(k))
79 | return true
80 | }
81 | }
82 | return true
83 | })
84 | return attrs
85 | }
86 |
--------------------------------------------------------------------------------
/exporter/collector/spansnapshot.go:
--------------------------------------------------------------------------------
1 | // Copyright 2021 OpenTelemetry Authors
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | package collector
16 |
17 | import (
18 | "time"
19 |
20 | "go.opentelemetry.io/otel/attribute"
21 | "go.opentelemetry.io/otel/sdk/instrumentation"
22 | sdkresource "go.opentelemetry.io/otel/sdk/resource"
23 | sdktrace "go.opentelemetry.io/otel/sdk/trace"
24 | apitrace "go.opentelemetry.io/otel/trace"
25 | )
26 |
27 | // spanSnapshot serves the same purpose as
28 | // https://github.com/open-telemetry/opentelemetry-go/blob/main/sdk/trace/snapshot.go#L28
29 | // It allows instantiating ReadOnlySpans.
30 | type spanSnapshot struct {
31 | endTime time.Time
32 | startTime time.Time
33 | // ReadOnlySpan is needed so we can inherit the "private" func
34 | sdktrace.ReadOnlySpan
35 | resource *sdkresource.Resource
36 | instrumentationScope instrumentation.Scope
37 | status sdktrace.Status
38 | name string
39 | attributes []attribute.KeyValue
40 | events []sdktrace.Event
41 | links []sdktrace.Link
42 | parent apitrace.SpanContext
43 | spanContext apitrace.SpanContext
44 | droppedMessageEvents int
45 | droppedLinks int
46 | childSpanCount int
47 | spanKind apitrace.SpanKind
48 | droppedAttributes int
49 | }
50 |
51 | func (s spanSnapshot) Name() string { return s.name }
52 | func (s spanSnapshot) SpanContext() apitrace.SpanContext { return s.spanContext }
53 | func (s spanSnapshot) Parent() apitrace.SpanContext { return s.parent }
54 | func (s spanSnapshot) SpanKind() apitrace.SpanKind { return s.spanKind }
55 | func (s spanSnapshot) StartTime() time.Time { return s.startTime }
56 | func (s spanSnapshot) EndTime() time.Time { return s.endTime }
57 | func (s spanSnapshot) Attributes() []attribute.KeyValue { return s.attributes }
58 | func (s spanSnapshot) Links() []sdktrace.Link { return s.links }
59 | func (s spanSnapshot) Events() []sdktrace.Event { return s.events }
60 | func (s spanSnapshot) Status() sdktrace.Status { return s.status }
61 | func (s spanSnapshot) Resource() *sdkresource.Resource { return s.resource }
62 | func (s spanSnapshot) DroppedAttributes() int { return s.droppedAttributes }
63 | func (s spanSnapshot) DroppedLinks() int { return s.droppedLinks }
64 | func (s spanSnapshot) DroppedEvents() int { return s.droppedLinks }
65 | func (s spanSnapshot) ChildSpanCount() int { return s.childSpanCount }
66 | func (s spanSnapshot) InstrumentationScope() instrumentation.Scope {
67 | return s.instrumentationScope
68 | }
69 |
--------------------------------------------------------------------------------
/exporter/collector/version.go:
--------------------------------------------------------------------------------
1 | // Copyright 2024 Google LLC
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | package collector
16 |
17 | // Version is the current release version of the OpenTelemetry
18 | // Operations Collector Exporter in use.
19 | func Version() string {
20 | return "0.52.0"
21 | }
22 |
--------------------------------------------------------------------------------
/exporter/metric/README.md:
--------------------------------------------------------------------------------
1 | # OpenTelemetry Google Cloud Monitoring Exporter
2 |
3 | [](https://pkg.go.dev/github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/metric)
4 | [![Apache License][license-image]][license-url]
5 |
6 | OpenTelemetry Google Cloud Monitoring Exporter allows the user to send collected metrics to Google Cloud.
7 |
8 | To get started with instrumentation in Google Cloud, see [Generate traces and metrics with
9 | Go](https://cloud.google.com/stackdriver/docs/instrumentation/setup/go).
10 |
11 | To learn more about instrumentation and observability, including opinionated recommendations
12 | for Google Cloud Observability, visit [Instrumentation and
13 | observability](https://cloud.google.com/stackdriver/docs/instrumentation/overview).
14 |
15 | [Google Cloud Monitoring](https://cloud.google.com/monitoring) provides visibility into the performance, uptime, and overall health of cloud-powered applications. It collects metrics, events, and metadata from Google Cloud, Amazon Web Services, hosted uptime probes, application instrumentation, and a variety of common application components including Cassandra, Nginx, Apache Web Server, Elasticsearch, and many others. Operations ingests that data and generates insights via dashboards, charts, and alerts. Cloud Monitoring alerting helps you collaborate by integrating with Slack, PagerDuty, and more.
16 |
17 | ## Setup
18 |
19 | Google Cloud Monitoring is a managed service provided by Google Cloud Platform. Google Cloud Monitoring requires to set up "Workspace" in advance. The guide to create a new Workspace is available on [the official document](https://cloud.google.com/monitoring/workspaces/create).
20 |
21 | ## Authentication
22 |
23 | The Google Cloud Monitoring exporter depends upon [`google.FindDefaultCredentials`](https://pkg.go.dev/golang.org/x/oauth2/google?tab=doc#FindDefaultCredentials), so the service account is automatically detected by default, but also the custom credential file (so called `service_account_key.json`) can be detected with specific conditions. Quoting from the document of `google.FindDefaultCredentials`:
24 |
25 | * A JSON file whose path is specified by the `GOOGLE_APPLICATION_CREDENTIALS` environment variable.
26 | * A JSON file in a location known to the gcloud command-line tool. On Windows, this is `%APPDATA%/gcloud/application_default_credentials.json`. On other systems, `$HOME/.config/gcloud/application_default_credentials.json`.
27 |
28 | When running code locally, you may need to specify a Google Project ID in addition to `GOOGLE_APPLICATION_CREDENTIALS`. This is best done using an environment variable (e.g. `GOOGLE_CLOUD_PROJECT`) and the `metric.WithProjectID` method, e.g.:
29 |
30 | ```golang
31 | projectID := os.Getenv("GOOGLE_CLOUD_PROJECT")
32 | opts := []mexporter.Option{
33 | mexporter.WithProjectID(projectID),
34 | }
35 | ```
36 |
37 | ## Useful links
38 |
39 | * For more information on OpenTelemetry, visit: https://opentelemetry.io/
40 | * For more about OpenTelemetry Go, visit: https://github.com/open-telemetry/opentelemetry-go
41 | * Learn more about Google Cloud Monitoring at https://cloud.google.com/monitoring
42 |
43 | [license-url]: https://github.com/GoogleCloudPlatform/opentelemetry-operations-go/blob/main/LICENSE
44 | [license-image]: https://img.shields.io/badge/license-Apache_2.0-green.svg?style=flat
45 |
--------------------------------------------------------------------------------
/exporter/metric/cloudmonitoring.go:
--------------------------------------------------------------------------------
1 | // Copyright 2020 Google LLC
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | package metric
16 |
17 | import (
18 | "context"
19 | "errors"
20 | "fmt"
21 |
22 | sdkmetric "go.opentelemetry.io/otel/sdk/metric"
23 |
24 | monitoring "cloud.google.com/go/monitoring/apiv3/v2"
25 | "golang.org/x/oauth2/google"
26 | )
27 |
28 | // New creates a new Exporter thats implements metric.Exporter.
29 | func New(opts ...Option) (sdkmetric.Exporter, error) {
30 | o := options{
31 | context: context.Background(),
32 | resourceAttributeFilter: DefaultResourceAttributesFilter,
33 | }
34 | for _, opt := range opts {
35 | opt(&o)
36 | }
37 |
38 | if o.projectID == "" {
39 | creds, err := google.FindDefaultCredentials(o.context, monitoring.DefaultAuthScopes()...)
40 | if err != nil {
41 | return nil, fmt.Errorf("failed to find Google Cloud credentials: %v", err)
42 | }
43 | if creds.ProjectID == "" {
44 | return nil, errors.New("google cloud monitoring: no project found with application default credentials")
45 | }
46 | o.projectID = creds.ProjectID
47 | }
48 | return newMetricExporter(&o)
49 | }
50 |
--------------------------------------------------------------------------------
/exporter/metric/cloudmonitoring_test.go:
--------------------------------------------------------------------------------
1 | // Copyright 2025 Google LLC
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | package metric
16 |
17 | import (
18 | "fmt"
19 | "testing"
20 |
21 | monitoring "cloud.google.com/go/monitoring/apiv3/v2"
22 | )
23 |
24 | func TestNew(t *testing.T) {
25 | cl := &monitoring.MetricClient{}
26 | tcs := []struct {
27 | desc string
28 | opts []Option
29 | verifyExporterFunc func(*metricExporter) error
30 | }{
31 | {
32 | desc: "WithMetricClient sets the client",
33 | opts: []Option{WithMonitoringClient(cl)},
34 | verifyExporterFunc: func(e *metricExporter) error {
35 | if e.client != cl {
36 | return fmt.Errorf("client mismatch, got = %p, want = %p", e.client, cl)
37 | }
38 | return nil
39 | },
40 | },
41 | {
42 | desc: "WithMetricClient overrides WithMetricClientOptions",
43 | opts: []Option{WithMonitoringClient(cl), WithMonitoringClientOptions()},
44 | verifyExporterFunc: func(e *metricExporter) error {
45 | if e.client != cl {
46 | return fmt.Errorf("client mismatch, got = %p, want = %p", e.client, cl)
47 | }
48 | return nil
49 | },
50 | },
51 | }
52 |
53 | for _, tc := range tcs {
54 | t.Run(tc.desc, func(t *testing.T) {
55 | opts := append(tc.opts, WithProjectID("some-project-id"))
56 | e, err := New(opts...)
57 | if err != nil {
58 | t.Fatalf("New(): %v", err)
59 | }
60 | exp, ok := e.(*metricExporter)
61 | if !ok {
62 | t.Fatal("unexpected type mismatch")
63 | }
64 | if err := tc.verifyExporterFunc(exp); err != nil {
65 | t.Fatalf("failed to verify exporter: %v", err)
66 | }
67 | })
68 | }
69 | }
70 |
--------------------------------------------------------------------------------
/exporter/metric/error.go:
--------------------------------------------------------------------------------
1 | // Copyright 2020 Google LLC
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | package metric
16 |
17 | import (
18 | "errors"
19 | "fmt"
20 | )
21 |
22 | var (
23 | errBlankProjectID = errors.New("expecting a non-blank ProjectID")
24 | )
25 |
26 | type errUnexpectedAggregationKind struct {
27 | kind string
28 | }
29 |
30 | func (e errUnexpectedAggregationKind) Error() string {
31 | return fmt.Sprintf("the metric kind is unexpected: %v", e.kind)
32 | }
33 |
--------------------------------------------------------------------------------
/exporter/metric/example_test.go:
--------------------------------------------------------------------------------
1 | // Copyright 2023 Google LLC
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | package metric_test
16 |
17 | import (
18 | "context"
19 | "log"
20 |
21 | "go.opentelemetry.io/otel/attribute"
22 | "go.opentelemetry.io/otel/metric"
23 | sdkmetric "go.opentelemetry.io/otel/sdk/metric"
24 |
25 | mexporter "github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/metric"
26 | )
27 |
28 | func ExampleNew() {
29 | exporter, err := mexporter.New()
30 | if err != nil {
31 | log.Printf("Failed to create exporter: %v", err)
32 | return
33 | }
34 | // initialize a MeterProvider with that periodically exports to the GCP exporter.
35 | provider := sdkmetric.NewMeterProvider(
36 | sdkmetric.WithReader(sdkmetric.NewPeriodicReader(exporter)),
37 | )
38 | ctx := context.Background()
39 | defer func() {
40 | if err = provider.Shutdown(ctx); err != nil {
41 | log.Printf("Failed to shut down meter provider: %v", err)
42 | }
43 | }()
44 |
45 | // Start meter
46 | meter := provider.Meter("github.com/GoogleCloudPlatform/opentelemetry-operations-go/example/metric")
47 |
48 | counter, err := meter.Int64Counter("counter-foo")
49 | if err != nil {
50 | log.Printf("Failed to create counter: %v", err)
51 | return
52 | }
53 | attrs := []attribute.KeyValue{
54 | attribute.Key("key").String("value"),
55 | }
56 | counter.Add(ctx, 123, metric.WithAttributes(attrs...))
57 | }
58 |
--------------------------------------------------------------------------------
/exporter/metric/go.mod:
--------------------------------------------------------------------------------
1 | module github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/metric
2 |
3 | go 1.23.0
4 |
5 | require (
6 | cloud.google.com/go/monitoring v1.24.2
7 | github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/resourcemapping v0.52.0
8 | github.com/googleapis/gax-go/v2 v2.14.2
9 | github.com/stretchr/testify v1.10.0
10 | go.opentelemetry.io/otel v1.36.0
11 | go.opentelemetry.io/otel/metric v1.36.0
12 | go.opentelemetry.io/otel/sdk v1.36.0
13 | go.opentelemetry.io/otel/sdk/metric v1.36.0
14 | golang.org/x/net v0.40.0 // indirect
15 | golang.org/x/oauth2 v0.30.0
16 | golang.org/x/sys v0.33.0 // indirect
17 | google.golang.org/api v0.234.0
18 | google.golang.org/genproto v0.0.0-20250505200425-f936aa4a68b2 // indirect
19 | google.golang.org/grpc v1.72.2
20 | google.golang.org/protobuf v1.36.6
21 | )
22 |
23 | require (
24 | github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/cloudmock v0.52.0
25 | go.opentelemetry.io/otel/trace v1.36.0
26 | google.golang.org/genproto/googleapis/api v0.0.0-20250505200425-f936aa4a68b2
27 | )
28 |
29 | require (
30 | cloud.google.com/go/auth v0.16.1 // indirect
31 | cloud.google.com/go/auth/oauth2adapt v0.2.8 // indirect
32 | cloud.google.com/go/compute/metadata v0.7.0 // indirect
33 | cloud.google.com/go/logging v1.13.0 // indirect
34 | cloud.google.com/go/longrunning v0.6.7 // indirect
35 | cloud.google.com/go/trace v1.11.6 // indirect
36 | github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
37 | github.com/go-logr/logr v1.4.3 // indirect
38 | github.com/go-logr/stdr v1.2.2 // indirect
39 | github.com/google/s2a-go v0.1.9 // indirect
40 | github.com/google/uuid v1.6.0 // indirect
41 | github.com/googleapis/enterprise-certificate-proxy v0.3.6 // indirect
42 | github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
43 | go.opentelemetry.io/auto/sdk v1.1.0 // indirect
44 | go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.60.0 // indirect
45 | go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.61.0 // indirect
46 | golang.org/x/crypto v0.38.0 // indirect
47 | golang.org/x/sync v0.14.0 // indirect
48 | golang.org/x/text v0.25.0 // indirect
49 | golang.org/x/time v0.11.0 // indirect
50 | google.golang.org/genproto/googleapis/rpc v0.0.0-20250519155744-55703ea1f237 // indirect
51 | gopkg.in/yaml.v3 v3.0.1 // indirect
52 | )
53 |
54 | replace github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/cloudmock => ../../internal/cloudmock
55 |
56 | replace github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/resourcemapping => ../../internal/resourcemapping
57 |
58 | retract v1.0.0-RC1
59 |
--------------------------------------------------------------------------------
/exporter/metric/version.go:
--------------------------------------------------------------------------------
1 | // Copyright 2020 Google LLC
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | package metric
16 |
17 | // Version is the current release version of the OpenTelemetry
18 | // Operations Metric Exporter in use.
19 | func Version() string {
20 | return "0.52.0"
21 | }
22 |
--------------------------------------------------------------------------------
/exporter/trace/go.mod:
--------------------------------------------------------------------------------
1 | module github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/trace
2 |
3 | go 1.23.0
4 |
5 | require (
6 | cloud.google.com/go/trace v1.11.6
7 | github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/cloudmock v0.52.0
8 | github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/resourcemapping v0.52.0
9 | github.com/stretchr/testify v1.10.0
10 | go.opentelemetry.io/otel v1.36.0
11 | go.opentelemetry.io/otel/sdk v1.36.0
12 | go.opentelemetry.io/otel/trace v1.36.0
13 | golang.org/x/oauth2 v0.30.0
14 | google.golang.org/api v0.234.0
15 | google.golang.org/genproto/googleapis/rpc v0.0.0-20250519155744-55703ea1f237
16 | google.golang.org/grpc v1.72.2
17 | google.golang.org/protobuf v1.36.6
18 | )
19 |
20 | require (
21 | cloud.google.com/go/auth v0.16.1 // indirect
22 | cloud.google.com/go/auth/oauth2adapt v0.2.8 // indirect
23 | cloud.google.com/go/compute/metadata v0.7.0 // indirect
24 | cloud.google.com/go/logging v1.13.0 // indirect
25 | cloud.google.com/go/longrunning v0.6.7 // indirect
26 | cloud.google.com/go/monitoring v1.24.2 // indirect
27 | github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
28 | github.com/felixge/httpsnoop v1.0.4 // indirect
29 | github.com/go-logr/logr v1.4.3 // indirect
30 | github.com/go-logr/stdr v1.2.2 // indirect
31 | github.com/google/s2a-go v0.1.9 // indirect
32 | github.com/google/uuid v1.6.0 // indirect
33 | github.com/googleapis/enterprise-certificate-proxy v0.3.6 // indirect
34 | github.com/googleapis/gax-go/v2 v2.14.2 // indirect
35 | github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
36 | go.opentelemetry.io/auto/sdk v1.1.0 // indirect
37 | go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.60.0 // indirect
38 | go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.61.0 // indirect
39 | go.opentelemetry.io/otel/metric v1.36.0 // indirect
40 | golang.org/x/crypto v0.38.0 // indirect
41 | golang.org/x/net v0.40.0 // indirect
42 | golang.org/x/sync v0.14.0 // indirect
43 | golang.org/x/sys v0.33.0 // indirect
44 | golang.org/x/text v0.25.0 // indirect
45 | golang.org/x/time v0.11.0 // indirect
46 | google.golang.org/genproto v0.0.0-20250505200425-f936aa4a68b2 // indirect
47 | google.golang.org/genproto/googleapis/api v0.0.0-20250505200425-f936aa4a68b2 // indirect
48 | gopkg.in/yaml.v3 v3.0.1 // indirect
49 | )
50 |
51 | replace github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/resourcemapping => ../../internal/resourcemapping
52 |
53 | replace github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/cloudmock => ../../internal/cloudmock
54 |
--------------------------------------------------------------------------------
/exporter/trace/version.go:
--------------------------------------------------------------------------------
1 | // Copyright 2020 Google LLC
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | package trace
16 |
17 | // Version is the current release version of the OpenTelemetry
18 | // Operations Trace Exporter in use.
19 | func Version() string {
20 | return "1.28.0"
21 | }
22 |
--------------------------------------------------------------------------------
/extension/googleclientauthextension/README.md:
--------------------------------------------------------------------------------
1 | # Authenticator - Google Client Credentials
2 |
3 | | Status | |
4 | | ------------- |-----------|
5 | | Stability | [alpha] |
6 |
7 | [alpha]: https://github.com/open-telemetry/opentelemetry-collector#alpha
8 |
9 | This extension provides Google OAuth2 Client Credentials and Metadata for gRPC and http based exporters.
10 |
11 | The authenticator type has to be set to `googleclientauth`.
12 |
13 | ## Configuration
14 |
15 | ```yaml
16 | extensions:
17 | googleclientauth:
18 |
19 | receivers:
20 | otlp:
21 | protocols:
22 | grpc:
23 |
24 | exporters:
25 | otlp/withauth:
26 | endpoint: 0.0.0.0:5000
27 | ca_file: /tmp/certs/ca.pem
28 | auth:
29 | authenticator: googleclientauth
30 |
31 | service:
32 | extensions: [googleclientauth]
33 | pipelines:
34 | metrics:
35 | receivers: [otlp]
36 | processors: []
37 | exporters: [otlp/withauth]
38 | ```
39 |
40 | Following are the configuration fields:
41 | - **project** - The Google Cloud Project telemetry is sent to if the gcp.project.id resource attribute is not set. If unspecified, this is determined using application default credentials.
42 | - [**scopes**](https://datatracker.ietf.org/doc/html/rfc6749#section-3.3) - The oauth 2.0 scopes requested by the extension.
43 | - [**quota_project**](https://cloud.google.com/apis/docs/system-parameters) - The project for quota and billing purposes. The caller must have serviceusage.services.use permission on the project.
44 | - **token_type** - The type of generated token. Default: `access_token`
45 | - `access_token`: [OAuth 2.0 access token](https://cloud.google.com/docs/authentication/token-types#access) will be generated.
46 | - `id_token`: Google-signed [ID token](https://cloud.google.com/docs/authentication/token-types#id) will be generated.
47 | - **audience** - The audience claim used for generating ID token
48 |
--------------------------------------------------------------------------------
/extension/googleclientauthextension/config.go:
--------------------------------------------------------------------------------
1 | // Copyright 2023 Google LLC
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | package googleclientauthextension // import "github.com/GoogleCloudPlatform/opentelemetry-operations-go/extension/googleclientauthextension"
16 |
17 | import (
18 | "errors"
19 |
20 | "go.opentelemetry.io/collector/component"
21 | )
22 |
23 | const (
24 | // accessToken indicates OAuth 2.0 access token (https://cloud.google.com/docs/authentication/token-types#access)
25 | accessToken = "access_token"
26 |
27 | // idToken indicates Google-signed ID-token (https://cloud.google.com/docs/authentication/token-types#id)
28 | idToken = "id_token"
29 | )
30 |
31 | var tokenTypes = map[string]struct{}{
32 | accessToken: {},
33 | idToken: {},
34 | }
35 |
36 | // Config stores the configuration for GCP Client Credentials.
37 | type Config struct {
38 | // Project is the project telemetry is sent to if the gcp.project.id
39 | // resource attribute is not set. If unspecified, this is determined using
40 | // application default credentials.
41 | Project string `mapstructure:"project"`
42 |
43 | // QuotaProject specifies a project for quota and billing purposes. The
44 | // caller must have serviceusage.services.use permission on the project.
45 | //
46 | // For more information please read:
47 | // https://cloud.google.com/apis/docs/system-parameters
48 | QuotaProject string `mapstructure:"quota_project"`
49 |
50 | // TokenType specifies which type of token will be generated.
51 | // default: access_token
52 | TokenType string `mapstructure:"token_type,omitempty"`
53 |
54 | // Audience specifies the audience claim used for generating ID token.
55 | Audience string `mapstructure:"audience,omitempty"`
56 |
57 | // Scope specifies optional requested permissions.
58 | // See https://datatracker.ietf.org/doc/html/rfc6749#section-3.3
59 | Scopes []string `mapstructure:"scopes,omitempty"`
60 |
61 | // TODO: Support impersonation, similar to what exists in the googlecloud collector exporter.
62 | }
63 |
64 | var _ component.Config = (*Config)(nil)
65 |
66 | // Validate checks if the extension configuration is valid.
67 | func (cfg *Config) Validate() error {
68 | if _, ok := tokenTypes[cfg.TokenType]; !ok {
69 | return errors.New("invalid token_type")
70 | }
71 |
72 | if cfg.TokenType == idToken && cfg.Audience == "" {
73 | return errors.New("audience must be specified when using the id_token token_type")
74 | }
75 |
76 | return nil
77 | }
78 |
79 | // defaultScopes are the scopes required for writing logs, metrics, and traces.
80 | var defaultScopes = []string{
81 | "https://www.googleapis.com/auth/cloud-platform",
82 | "https://www.googleapis.com/auth/logging.write",
83 | "https://www.googleapis.com/auth/monitoring.write",
84 | "https://www.googleapis.com/auth/trace.append",
85 | }
86 |
87 | func CreateDefaultConfig() component.Config {
88 | return &Config{
89 | Scopes: defaultScopes,
90 | TokenType: accessToken,
91 | }
92 | }
93 |
--------------------------------------------------------------------------------
/extension/googleclientauthextension/config_test.go:
--------------------------------------------------------------------------------
1 | // Copyright 2024 Google LLC
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | package googleclientauthextension // import "github.com/GoogleCloudPlatform/opentelemetry-operations-go/extension/googleclientauthextension"
16 |
17 | import (
18 | "testing"
19 |
20 | "github.com/stretchr/testify/assert"
21 | )
22 |
23 | func TestConfig_Validate_ValidAccessToken(t *testing.T) {
24 | cfg := &Config{
25 | TokenType: accessToken,
26 | }
27 |
28 | err := cfg.Validate()
29 | assert.NoError(t, err)
30 | }
31 |
32 | func TestConfig_Validate_ValidIDToken(t *testing.T) {
33 | cfg := &Config{
34 | TokenType: idToken,
35 | Audience: "audience",
36 | }
37 |
38 | err := cfg.Validate()
39 | assert.NoError(t, err)
40 | }
41 |
42 | func TestConfig_Validate_MissingAudience(t *testing.T) {
43 | cfg := &Config{
44 | TokenType: idToken,
45 | }
46 |
47 | err := cfg.Validate()
48 | assert.Error(t, err)
49 | }
50 |
51 | func TestConfig_Validate_Invalid(t *testing.T) {
52 | cfg := &Config{
53 | TokenType: "invalid",
54 | }
55 |
56 | err := cfg.Validate()
57 | assert.Error(t, err)
58 | }
59 |
--------------------------------------------------------------------------------
/extension/googleclientauthextension/doc.go:
--------------------------------------------------------------------------------
1 | // Copyright 2023 Google LLC
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | // Package googleclientauthextension provides gRPC and HTTP credentials and metadata
16 | // using Application Default Credentials: https://cloud.google.com/docs/authentication#adc
17 | package googleclientauthextension // import "github.com/GoogleCloudPlatform/opentelemetry-operations-go/extension/googleclientauthextension"
18 |
--------------------------------------------------------------------------------
/extension/googleclientauthextension/go.mod:
--------------------------------------------------------------------------------
1 | module github.com/GoogleCloudPlatform/opentelemetry-operations-go/extension/googleclientauthextension
2 |
3 | go 1.23.0
4 |
5 | require (
6 | github.com/stretchr/testify v1.10.0
7 | go.opentelemetry.io/collector/component v0.120.0
8 | go.opentelemetry.io/collector/component/componenttest v0.120.0
9 | go.opentelemetry.io/collector/extension v0.120.0
10 | golang.org/x/oauth2 v0.30.0
11 | google.golang.org/api v0.234.0
12 | google.golang.org/grpc v1.72.2
13 | )
14 |
15 | require (
16 | cloud.google.com/go/auth v0.16.1 // indirect
17 | cloud.google.com/go/auth/oauth2adapt v0.2.8 // indirect
18 | cloud.google.com/go/compute/metadata v0.7.0 // indirect
19 | github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
20 | github.com/felixge/httpsnoop v1.0.4 // indirect
21 | github.com/go-logr/logr v1.4.3 // indirect
22 | github.com/go-logr/stdr v1.2.2 // indirect
23 | github.com/gogo/protobuf v1.3.2 // indirect
24 | github.com/google/s2a-go v0.1.9 // indirect
25 | github.com/google/uuid v1.6.0 // indirect
26 | github.com/googleapis/enterprise-certificate-proxy v0.3.6 // indirect
27 | github.com/googleapis/gax-go/v2 v2.14.2 // indirect
28 | github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
29 | go.opentelemetry.io/auto/sdk v1.1.0 // indirect
30 | go.opentelemetry.io/collector/pdata v1.33.0 // indirect
31 | go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.61.0 // indirect
32 | go.opentelemetry.io/otel v1.36.0 // indirect
33 | go.opentelemetry.io/otel/metric v1.36.0 // indirect
34 | go.opentelemetry.io/otel/sdk v1.36.0 // indirect
35 | go.opentelemetry.io/otel/sdk/metric v1.36.0 // indirect
36 | go.opentelemetry.io/otel/trace v1.36.0 // indirect
37 | go.uber.org/multierr v1.11.0 // indirect
38 | go.uber.org/zap v1.27.0 // indirect
39 | golang.org/x/crypto v0.38.0 // indirect
40 | golang.org/x/net v0.40.0 // indirect
41 | golang.org/x/sys v0.33.0 // indirect
42 | golang.org/x/text v0.25.0 // indirect
43 | google.golang.org/genproto/googleapis/rpc v0.0.0-20250519155744-55703ea1f237 // indirect
44 | google.golang.org/protobuf v1.36.6 // indirect
45 | gopkg.in/yaml.v3 v3.0.1 // indirect
46 | )
47 |
48 | retract (
49 | v0.76.2
50 | v0.76.1
51 | v0.65.0
52 | )
53 |
--------------------------------------------------------------------------------
/extension/googleclientauthextension/grpc.go:
--------------------------------------------------------------------------------
1 | // Copyright 2023 Google LLC
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | package googleclientauthextension // import "github.com/GoogleCloudPlatform/opentelemetry-operations-go/extension/googleclientauthextension"
16 |
17 | import (
18 | "context"
19 | "errors"
20 |
21 | "google.golang.org/grpc/credentials"
22 | )
23 |
24 | // perRPCCredentials returns gRPC credentials using the OAuth TokenSource, and adds
25 | // google metadata.
26 | func (ca clientAuthenticator) PerRPCCredentials() (credentials.PerRPCCredentials, error) {
27 | if ca.TokenSource == nil {
28 | return nil, errors.New("not started")
29 | }
30 | return ca, nil
31 | }
32 |
33 | // GetRequestMetadata gets the request metadata as a map from a clientAuthenticator.
34 | // Based on metadata added by the google go client:
35 | // https://github.com/googleapis/google-api-go-client/blob/113082d14d54f188d1b6c34c652e416592fc51b5/transport/grpc/dial.go#L224
36 | func (ca clientAuthenticator) GetRequestMetadata(ctx context.Context, uri ...string) (map[string]string, error) {
37 | if ca.TokenSource == nil {
38 | return nil, errors.New("not started")
39 | }
40 |
41 | metadata, err := ca.TokenSource.GetRequestMetadata(ctx, uri...)
42 | if err != nil {
43 | return nil, err
44 | }
45 |
46 | // Attach system parameters
47 | if ca.config.QuotaProject != "" {
48 | metadata["X-goog-user-project"] = ca.config.QuotaProject
49 | }
50 | if ca.config.Project != "" {
51 | metadata["X-goog-project-id"] = ca.config.Project
52 | }
53 | return metadata, nil
54 | }
55 |
--------------------------------------------------------------------------------
/extension/googleclientauthextension/grpc_test.go:
--------------------------------------------------------------------------------
1 | // Copyright 2024 Google LLC
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | package googleclientauthextension // import "github.com/GoogleCloudPlatform/opentelemetry-operations-go/extension/googleclientauthextension"
16 |
17 | import (
18 | "context"
19 | "testing"
20 |
21 | "github.com/stretchr/testify/assert"
22 | "google.golang.org/api/idtoken"
23 | )
24 |
25 | func TestPerRPCCredentials(t *testing.T) {
26 | t.Setenv("GOOGLE_APPLICATION_CREDENTIALS", "testdata/fake_creds.json")
27 | ca := clientAuthenticator{config: &Config{
28 | Project: "my-project",
29 | QuotaProject: "other-project",
30 | TokenType: accessToken,
31 | }}
32 | err := ca.Start(context.Background(), nil)
33 | assert.NoError(t, err)
34 |
35 | perrpc, err := ca.PerRPCCredentials()
36 | assert.NotNil(t, perrpc)
37 | assert.NoError(t, err)
38 | }
39 |
40 | func TestPerRPCCredentialsWithIDToken(t *testing.T) {
41 | t.Setenv("GOOGLE_APPLICATION_CREDENTIALS", "testdata/fake_isa_creds.json")
42 | ca := clientAuthenticator{
43 | config: &Config{
44 | Project: "my-project",
45 | TokenType: idToken,
46 | Audience: "http://example.com",
47 | },
48 | newIDTokenSource: idtoken.NewTokenSource,
49 | }
50 | err := ca.Start(context.Background(), nil)
51 | assert.NoError(t, err)
52 |
53 | perrpc, err := ca.PerRPCCredentials()
54 | assert.NotNil(t, perrpc)
55 | assert.NoError(t, err)
56 | }
57 |
58 | func TestPerRPCCredentialsNotStarted(t *testing.T) {
59 | ca := clientAuthenticator{config: &Config{
60 | Project: "my-project",
61 | QuotaProject: "other-project",
62 | TokenType: accessToken,
63 | }}
64 | perrpc, err := ca.PerRPCCredentials()
65 | assert.Nil(t, perrpc)
66 | assert.Error(t, err)
67 | }
68 |
--------------------------------------------------------------------------------
/extension/googleclientauthextension/http.go:
--------------------------------------------------------------------------------
1 | // Copyright 2023 Google LLC
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | package googleclientauthextension // import "github.com/GoogleCloudPlatform/opentelemetry-operations-go/extension/googleclientauthextension"
16 |
17 | import (
18 | "errors"
19 | "net/http"
20 |
21 | "golang.org/x/oauth2"
22 | )
23 |
24 | // roundTripper provides an HTTP RoundTripper which adds gcp credentials and
25 | // headers.
26 | func (ca *clientAuthenticator) RoundTripper(base http.RoundTripper) (http.RoundTripper, error) {
27 | if ca.TokenSource == nil {
28 | return nil, errors.New("not started")
29 | }
30 | return &oauth2.Transport{
31 | Source: ca,
32 | Base: ¶meterTransport{
33 | base: base,
34 | config: ca.config,
35 | },
36 | }, nil
37 | }
38 |
39 | type parameterTransport struct {
40 | base http.RoundTripper
41 | config *Config
42 | }
43 |
44 | // RoundTrip adds headers related to
45 | // Based on headers added by the google go client:
46 | // https://github.com/googleapis/google-api-go-client/blob/113082d14d54f188d1b6c34c652e416592fc51b5/transport/http/dial.go#L122
47 | func (t *parameterTransport) RoundTrip(req *http.Request) (*http.Response, error) {
48 | if t.base == nil {
49 | return nil, errors.New("transport: no Transport specified")
50 | }
51 | newReq := *req
52 | newReq.Header = make(http.Header)
53 | for k, vv := range req.Header {
54 | newReq.Header[k] = vv
55 | }
56 |
57 | // Attach system parameters into the header
58 | if t.config.QuotaProject != "" {
59 | newReq.Header.Set("X-Goog-User-Project", t.config.QuotaProject)
60 | }
61 | if t.config.Project != "" {
62 | newReq.Header.Set("X-Goog-Project-ID", t.config.Project)
63 | }
64 |
65 | return t.base.RoundTrip(&newReq)
66 | }
67 |
--------------------------------------------------------------------------------
/extension/googleclientauthextension/testdata/fake_creds.json:
--------------------------------------------------------------------------------
1 | {
2 | "client_id": "notreal-notreal.apps.googleusercontent.com",
3 | "client_secret": "d-notreal",
4 | "project_id": "my-project",
5 | "refresh_token": "notreal-notreal-notreal-notreal-notreal",
6 | "type": "authorized_user"
7 | }
--------------------------------------------------------------------------------
/extension/googleclientauthextension/testdata/fake_creds_no_project.json:
--------------------------------------------------------------------------------
1 | {
2 | "client_id": "notreal-notreal.apps.googleusercontent.com",
3 | "client_secret": "d-notreal",
4 | "project_id": "",
5 | "refresh_token": "notreal-notreal-notreal-notreal-notreal",
6 | "type": "authorized_user"
7 | }
8 |
--------------------------------------------------------------------------------
/extension/googleclientauthextension/testdata/fake_isa_creds.json:
--------------------------------------------------------------------------------
1 | {
2 | "type": "impersonated_service_account",
3 | "service_account_impersonation_url": "http://example.com",
4 | "source_credentials": {
5 | "client_id": "notreal-notreal.apps.googleusercontent.com",
6 | "client_secret": "d-notreal",
7 | "refresh_token": "notreal-notreal-notreal-notreal-notreal",
8 | "type": "authorized_user"
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/get_main_pkgs.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | # Copyright 2020 Google LLC
4 | #
5 | # Licensed under the Apache License, Version 2.0 (the "License");
6 | # you may not use this file except in compliance with the License.
7 | # You may obtain a copy of the License at
8 | #
9 | # http://www.apache.org/licenses/LICENSE-2.0
10 | #
11 | # Unless required by applicable law or agreed to in writing, software
12 | # distributed under the License is distributed on an "AS IS" BASIS,
13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | # See the License for the specific language governing permissions and
15 | # limitations under the License.
16 |
17 | set -euo pipefail
18 |
19 | top_dir='.'
20 | if [[ $# -gt 0 ]]; then
21 | top_dir="${1}"
22 | fi
23 |
24 | p=$(pwd)
25 | mod_dirs=()
26 | mapfile -t mod_dirs < <(find "${top_dir}" -type f -name 'go.mod' -exec dirname {} \; | sort)
27 |
28 | for mod_dir in "${mod_dirs[@]}"; do
29 | cd "${mod_dir}"
30 | main_dirs=()
31 | mapfile -t main_dirs < <(go list --find -f '{{.Name}}|{{.Dir}}' ./... | grep '^main|' | cut -f 2- -d '|')
32 | for main_dir in "${main_dirs[@]}"; do
33 | echo ".${main_dir#${p}}"
34 | done
35 | cd "${p}"
36 | done
37 |
--------------------------------------------------------------------------------
/go.mod:
--------------------------------------------------------------------------------
1 | module github.com/GoogleCloudPlatform/opentelemetry-operations-go
2 |
3 | go 1.23
4 |
5 | retract (
6 | v1.8.0
7 | v1.5.2
8 | v1.5.1
9 | v1.5.0
10 | v1.4.0
11 | v1.3.0
12 | v1.0.0
13 | v1.0.0-RC2
14 | v1.0.0-RC1
15 | )
16 |
--------------------------------------------------------------------------------
/go.sum:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GoogleCloudPlatform/opentelemetry-operations-go/6658b3aae40518709f8f7763b3e5f0881507ffc1/go.sum
--------------------------------------------------------------------------------
/internal/buildscripts/update-dep:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | # Updates MODULE inside go.mod if it is already present to version VERSION.
4 |
5 | set -e
6 |
7 | if grep -q "$MODULE " go.mod; then
8 | go get $MODULE@$VERSION
9 | fi
10 |
11 |
--------------------------------------------------------------------------------
/internal/cloudmock/go.mod:
--------------------------------------------------------------------------------
1 | module github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/cloudmock
2 |
3 | go 1.23.0
4 |
5 | require (
6 | cloud.google.com/go/logging v1.13.0
7 | cloud.google.com/go/monitoring v1.24.2
8 | cloud.google.com/go/trace v1.11.6
9 | google.golang.org/genproto/googleapis/api v0.0.0-20250505200425-f936aa4a68b2
10 | google.golang.org/grpc v1.72.2
11 | google.golang.org/protobuf v1.36.6
12 | )
13 |
14 | require (
15 | cloud.google.com/go/longrunning v0.6.7 // indirect
16 | github.com/go-logr/logr v1.4.3 // indirect
17 | github.com/google/go-cmp v0.7.0 // indirect
18 | go.opentelemetry.io/otel v1.36.0 // indirect
19 | go.opentelemetry.io/otel/sdk/metric v1.36.0 // indirect
20 | golang.org/x/net v0.40.0 // indirect
21 | golang.org/x/sys v0.33.0 // indirect
22 | golang.org/x/text v0.25.0 // indirect
23 | google.golang.org/genproto v0.0.0-20250505200425-f936aa4a68b2 // indirect
24 | google.golang.org/genproto/googleapis/rpc v0.0.0-20250519155744-55703ea1f237 // indirect
25 | )
26 |
--------------------------------------------------------------------------------
/internal/cloudmock/logs.go:
--------------------------------------------------------------------------------
1 | // Copyright 2022 Google LLC
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // https://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | package cloudmock
16 |
17 | import (
18 | "context"
19 | "net"
20 | "strings"
21 | "sync"
22 |
23 | logpb "cloud.google.com/go/logging/apiv2/loggingpb"
24 | "google.golang.org/grpc"
25 | "google.golang.org/grpc/metadata"
26 | )
27 |
28 | type LogsTestServer struct {
29 | lis net.Listener
30 | srv *grpc.Server
31 | // Endpoint where the gRPC server is listening
32 | Endpoint string
33 | userAgent string
34 | writeLogEntriesRequests []*logpb.WriteLogEntriesRequest
35 | mu sync.Mutex
36 | }
37 |
38 | func (l *LogsTestServer) Shutdown() {
39 | l.srv.GracefulStop()
40 | }
41 |
42 | func (l *LogsTestServer) Serve() {
43 | //nolint:errcheck
44 | l.srv.Serve(l.lis)
45 | }
46 |
47 | func (l *LogsTestServer) CreateWriteLogEntriesRequests() []*logpb.WriteLogEntriesRequest {
48 | l.mu.Lock()
49 | defer l.mu.Unlock()
50 | reqs := l.writeLogEntriesRequests
51 | l.writeLogEntriesRequests = nil
52 | return reqs
53 | }
54 |
55 | // Pops out the UserAgent from the most recent CreateWriteLogEntries.
56 | func (l *LogsTestServer) UserAgent() string {
57 | l.mu.Lock()
58 | defer l.mu.Unlock()
59 | ua := l.userAgent
60 | l.userAgent = ""
61 | return ua
62 | }
63 |
64 | func (l *LogsTestServer) appendWriteLogEntriesRequest(ctx context.Context, req *logpb.WriteLogEntriesRequest) {
65 | l.mu.Lock()
66 | defer l.mu.Unlock()
67 | l.writeLogEntriesRequests = append(l.writeLogEntriesRequests, req)
68 | if md, ok := metadata.FromIncomingContext(ctx); ok {
69 | l.userAgent = strings.Join(md.Get("User-Agent"), ";")
70 | }
71 | }
72 |
73 | type fakeLoggingServiceServer struct {
74 | logpb.UnimplementedLoggingServiceV2Server
75 | logsTestServer *LogsTestServer
76 | }
77 |
78 | func (f *fakeLoggingServiceServer) WriteLogEntries(
79 | ctx context.Context,
80 | request *logpb.WriteLogEntriesRequest,
81 | ) (*logpb.WriteLogEntriesResponse, error) {
82 | f.logsTestServer.appendWriteLogEntriesRequest(ctx, request)
83 | return &logpb.WriteLogEntriesResponse{}, nil
84 | }
85 |
86 | func NewLoggingTestServer() (*LogsTestServer, error) {
87 | srv := grpc.NewServer()
88 | lis, err := net.Listen("tcp", "localhost:0")
89 | if err != nil {
90 | return nil, err
91 | }
92 | testServer := &LogsTestServer{
93 | Endpoint: lis.Addr().String(),
94 | lis: lis,
95 | srv: srv,
96 | }
97 | logpb.RegisterLoggingServiceV2Server(
98 | srv,
99 | &fakeLoggingServiceServer{logsTestServer: testServer},
100 | )
101 |
102 | return testServer, nil
103 | }
104 |
--------------------------------------------------------------------------------
/internal/resourcemapping/go.mod:
--------------------------------------------------------------------------------
1 | module github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/resourcemapping
2 |
3 | go 1.23.0
4 |
5 | require (
6 | go.opentelemetry.io/otel v1.36.0
7 | google.golang.org/genproto/googleapis/api v0.0.0-20250505200425-f936aa4a68b2
8 | )
9 |
10 | require (
11 | github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
12 | github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
13 | google.golang.org/protobuf v1.36.6 // indirect
14 | )
15 |
--------------------------------------------------------------------------------
/internal/resourcemapping/go.sum:
--------------------------------------------------------------------------------
1 | github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM=
2 | github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
3 | github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
4 | github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
5 | github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U=
6 | github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
7 | github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
8 | github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
9 | go.opentelemetry.io/otel v1.36.0 h1:UumtzIklRBY6cI/lllNZlALOF5nNIzJVb16APdvgTXg=
10 | go.opentelemetry.io/otel v1.36.0/go.mod h1:/TcFMXYjyRNh8khOAO9ybYkqaDBb/70aVwkNML4pP8E=
11 | google.golang.org/genproto/googleapis/api v0.0.0-20250505200425-f936aa4a68b2 h1:vPV0tzlsK6EzEDHNNH5sa7Hs9bd7iXR7B1tSiPepkV0=
12 | google.golang.org/genproto/googleapis/api v0.0.0-20250505200425-f936aa4a68b2/go.mod h1:pKLAc5OolXC3ViWGI62vvC0n10CpwAtRcTNCFwTKBEw=
13 | google.golang.org/protobuf v1.36.6 h1:z1NpPI8ku2WgiWnf+t9wTPsn6eP1L7ksHUlkfLvd9xY=
14 | google.golang.org/protobuf v1.36.6/go.mod h1:jduwjTPXsFjZGTmRluh+L6NjiWu7pchiJ2/5YcXBHnY=
15 | gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
16 | gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
17 |
--------------------------------------------------------------------------------
/propagator/go.mod:
--------------------------------------------------------------------------------
1 | module github.com/GoogleCloudPlatform/opentelemetry-operations-go/propagator
2 |
3 | go 1.23.0
4 |
5 | require (
6 | github.com/google/go-cmp v0.7.0
7 | go.opentelemetry.io/otel v1.36.0
8 | go.opentelemetry.io/otel/trace v1.36.0
9 | )
10 |
11 | require (
12 | github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
13 | github.com/go-logr/logr v1.4.3 // indirect
14 | github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
15 | )
16 |
--------------------------------------------------------------------------------
/propagator/go.sum:
--------------------------------------------------------------------------------
1 | github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM=
2 | github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
3 | github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI=
4 | github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
5 | github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
6 | github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
7 | github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
8 | github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
9 | github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U=
10 | github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
11 | github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
12 | github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
13 | go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA=
14 | go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A=
15 | go.opentelemetry.io/otel v1.36.0 h1:UumtzIklRBY6cI/lllNZlALOF5nNIzJVb16APdvgTXg=
16 | go.opentelemetry.io/otel v1.36.0/go.mod h1:/TcFMXYjyRNh8khOAO9ybYkqaDBb/70aVwkNML4pP8E=
17 | go.opentelemetry.io/otel/metric v1.36.0 h1:MoWPKVhQvJ+eeXWHFBOPoBOi20jh6Iq2CcCREuTYufE=
18 | go.opentelemetry.io/otel/metric v1.36.0/go.mod h1:zC7Ks+yeyJt4xig9DEw9kuUFe5C3zLbVjV2PzT6qzbs=
19 | go.opentelemetry.io/otel/trace v1.36.0 h1:ahxWNuqZjpdiFAyrIoQ4GIiAIhxAunQR6MUoKrsNd4w=
20 | go.opentelemetry.io/otel/trace v1.36.0/go.mod h1:gQ+OnDZzrybY4k4seLzPAWNwVBBVlF2szhehOBB/tGA=
21 | gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
22 | gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
23 |
--------------------------------------------------------------------------------
/renovate.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "https://docs.renovatebot.com/renovate-schema.json",
3 | "extends": [
4 | "config:recommended"
5 | ],
6 | "ignorePaths": [],
7 | "labels": ["Skip Changelog", "dependencies"],
8 | "postUpdateOptions" : [
9 | "gomodTidy"
10 | ],
11 | "packageRules": [
12 | {
13 | "matchManagers": ["gomod"],
14 | "matchDepTypes": ["indirect"],
15 | "enabled": true
16 | },
17 | {
18 | "matchFileNames": ["tools/**"],
19 | "matchManagers": ["gomod"],
20 | "matchDepTypes": ["indirect"],
21 | "enabled": false
22 | },
23 | {
24 | "matchPackageNames": ["google.golang.org/**"],
25 | "groupName": "google.golang.org"
26 | },
27 | {
28 | "matchPackageNames": ["golang.org/x/**"],
29 | "groupName": "golang.org/x"
30 | },
31 | {
32 | "matchPackageNames": ["cloud.google.com/**"],
33 | "groupName": "cloud.google.com"
34 | },
35 | {
36 | "matchManagers": ["gomod"],
37 | "matchPackageNames": ["go.opentelemetry.io/collector/**", "github.com/open-telemetry/opentelemetry-collector-contrib/**"],
38 | "groupName": "go.opentelemetry.io/collector"
39 | },
40 | {
41 | "matchManagers": ["gomod"],
42 | "matchPackageNames": ["go.opentelemetry.io/otel", "go.opentelemetry.io/otel/**", "go.opentelemetry.io/contrib/**"],
43 | "groupName": "go.opentelemetry.io/otel"
44 | }
45 | ]
46 | }
47 |
--------------------------------------------------------------------------------
/tools/tools.go:
--------------------------------------------------------------------------------
1 | // Copyright 2020 Google LLC
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | //go:build tools
16 |
17 | package tools
18 |
19 | import (
20 | _ "github.com/client9/misspell/cmd/misspell"
21 | _ "github.com/golangci/golangci-lint/cmd/golangci-lint"
22 | _ "github.com/itchyny/gojq/cmd/gojq"
23 | _ "github.com/wadey/gocovmerge"
24 | _ "golang.org/x/tools/cmd/stringer"
25 | _ "golang.org/x/tools/go/analysis/passes/fieldalignment/cmd/fieldalignment"
26 | _ "golang.org/x/vuln/cmd/govulncheck"
27 | _ "google.golang.org/protobuf/cmd/protoc-gen-go"
28 | )
29 |
--------------------------------------------------------------------------------
/verify_examples.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | # Copyright 2020 Google LLC
4 | #
5 | # Licensed under the Apache License, Version 2.0 (the "License");
6 | # you may not use this file except in compliance with the License.
7 | # You may obtain a copy of the License at
8 | #
9 | # http://www.apache.org/licenses/LICENSE-2.0
10 | #
11 | # Unless required by applicable law or agreed to in writing, software
12 | # distributed under the License is distributed on an "AS IS" BASIS,
13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | # See the License for the specific language governing permissions and
15 | # limitations under the License.
16 |
17 | set -euo pipefail
18 |
19 | cd $(dirname $0)
20 | TOOLS_DIR=$(pwd)/.tools
21 |
22 | # Pre-requisites
23 | if ! git diff --quiet; then \
24 | git status
25 | printf "\n\nError: working tree is not clean\n"
26 | exit -1
27 | fi
28 |
29 | if [ "$(git tag --contains $(git log -1 --pretty=format:"%H"))" = "" ] ; then
30 | printf "$(git log -1)"
31 | printf "\n\nError: HEAD is not pointing to a tagged version"
32 | fi
33 |
34 | make ${TOOLS_DIR}/gojq
35 |
36 | DIR_TMP="$(mktemp -d -t otelops-XXXX)"
37 |
38 | printf "Copy examples to ${DIR_TMP}\n"
39 | cp -a ./example ${DIR_TMP}
40 |
41 | # Update go.mod files
42 | printf "Update go.mod: rename module and remove replace\n"
43 |
44 | PACKAGE_DIRS=$(find . -mindepth 2 -type f -name 'go.mod' -exec dirname {} \; | grep -E 'example' | sed 's/^\.\///' | sort)
45 |
46 | for dir in $PACKAGE_DIRS; do
47 | printf " Update go.mod for $dir\n"
48 | (cd "${DIR_TMP}/${dir}" && \
49 | # replaces is ("mod1" "mod2" …)
50 | replaces=($(go mod edit -json | ${TOOLS_DIR}/gojq '.Replace[].Old.Path')) && \
51 | # strip double quotes
52 | replaces=("${replaces[@]%\"}") && \
53 | replaces=("${replaces[@]#\"}") && \
54 | # make an array (-dropreplace=mod1 -dropreplace=mod2 …)
55 | dropreplaces=("${replaces[@]/#/-dropreplace=}") && \
56 | go mod edit -module "oteltmp/${dir}" "${dropreplaces[@]}" && \
57 | go mod tidy)
58 | done
59 | printf "Update done:\n\n"
60 |
61 | # Build directories that contain main package. These directories are different than
62 | # directories that contain go.mod files.
63 | printf "Build examples:\n"
64 | EXAMPLES=$(./get_main_pkgs.sh ./example)
65 | for ex in $EXAMPLES; do
66 | printf " Build $ex in ${DIR_TMP}/${ex}\n"
67 | (cd "${DIR_TMP}/${ex}" && \
68 | go build .)
69 | done
70 |
71 | # Cleanup
72 | printf "Remove copied files.\n"
73 | rm -rf $DIR_TMP
74 |
--------------------------------------------------------------------------------