diff --git a/.chloggen/config.yaml b/.chloggen/config.yaml index 621f29580564..d9fcc941ac2b 100644 --- a/.chloggen/config.yaml +++ b/.chloggen/config.yaml @@ -12,45 +12,80 @@ components: - cmd/mdatagen - connector/forward - connector/sample + - consumer/consumererror/xconsumererror - consumer/xconsumer - docs/rfcs - exporter/debug - exporter/nop - - exporter/otlp - - exporter/otlphttp + - exporter/otlp_grpc + - exporter/otlp_http - extension/memory_limiter - - extension/xextension - - extension/xextension - extension/zpages - pdata/pprofile - - pdata/xpdata + - pkg/client + - pkg/component + - pkg/component/componentstatus + - pkg/component/componenttest - pkg/config/configauth - pkg/config/configcompression - pkg/config/configgrpc - - pkg/config/confighttp + - pkg/config/confighttp/xconfighttp - pkg/config/configmiddleware - pkg/config/confignet - pkg/config/configopaque - - pkg/config/configoptional - pkg/config/configretry - pkg/config/configtelemetry - pkg/config/configtls + - pkg/confighttp + - pkg/configoptional - pkg/confmap + - pkg/connector + - pkg/connector/connectortest + - pkg/consumer + - pkg/consumer/consumererror + - pkg/consumer/consumertest + - pkg/exporter + - pkg/exporter/exportertest - pkg/exporterhelper + - pkg/extension + - pkg/extension/extensiontest + - pkg/extensionauth + - pkg/extensionauth/extensionauthtest + - pkg/extensioncapabilities + - pkg/extensionmiddleware + - pkg/extensionmiddleware/extensionmiddlewaretest + - pkg/featuregate + - pkg/filter - pkg/otelcol + - pkg/otelcol/otelcoltest - pkg/pdata + - pkg/pipeline + - pkg/processor + - pkg/processor/processortest - pkg/processorhelper - pkg/queuebatch + - pkg/receiver + - pkg/receiver/receivertest - pkg/receiverhelper - pkg/scraper + - pkg/scraper/scrapertest - pkg/scraperhelper - pkg/service + - pkg/service/hostcapabilities + - pkg/service/telemetry/telemetrytest + - pkg/xconfmap - pkg/xconnector - pkg/xexporter - pkg/xexporterhelper + - pkg/xextension + - pkg/xextension/storage + - pkg/xpdata + - pkg/xpipeline - pkg/xprocessor + - pkg/xprocessorhelper - pkg/xreceiver - pkg/xscraper + - pkg/xscraperhelper - processor/batch - processor/memory_limiter - processor/sample @@ -63,5 +98,6 @@ components: - receiver/otlp - receiver/sample - receiver/sample + - receiver/sampleentity - scraper/sample - service/graph diff --git a/.chloggen/confighttp-allow-unset-compression.yaml b/.chloggen/confighttp-allow-unset-compression.yaml deleted file mode 100644 index 5351e671066d..000000000000 --- a/.chloggen/confighttp-allow-unset-compression.yaml +++ /dev/null @@ -1,18 +0,0 @@ -change_type: enhancement -component: pkg/config/confighttp -note: Setting `compression_algorithms` to an empty list now disables automatic decompression, ignoring Content-Encoding - -# One or more tracking issues or pull requests related to the change -issues: [14131] - -# (Optional) One or more lines of additional information to render under the primary note. -# These lines will be padded with 2 spaces and then inserted directly into the document. -# Use pipe (|) for multiline entries. -subtext: - -# Optional: The change log or logs in which this entry should be included. -# e.g. '[user]' or '[user, api]' -# Include 'user' if the change is relevant to end users. -# Include 'api' if there is a change to a library API. -# Default: '[user]' -change_logs: [user] diff --git a/.chloggen/mx-psi_cookies-config-use-configoptional.yaml b/.chloggen/mx-psi_cookies-config-use-configoptional.yaml deleted file mode 100644 index a4523df95c53..000000000000 --- a/.chloggen/mx-psi_cookies-config-use-configoptional.yaml +++ /dev/null @@ -1,25 +0,0 @@ -# Use this changelog template to create an entry for release notes. - -# One of 'breaking', 'deprecation', 'new_component', 'enhancement', 'bug_fix' -change_type: breaking - -# The name of the component, or a single word describing the area of concern, (e.g. otlpreceiver) -component: pkg/config/confighttp - -# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`). -note: Use configoptional.Optional for confighttp.ClientConfig.Cookies field - -# One or more tracking issues or pull requests related to the change -issues: [14021] - -# (Optional) One or more lines of additional information to render under the primary note. -# These lines will be padded with 2 spaces and then inserted directly into the document. -# Use pipe (|) for multiline entries. -subtext: - -# Optional: The change log or logs in which this entry should be included. -# e.g. '[user]' or '[user, api]' -# Include 'user' if the change is relevant to end users. -# Include 'api' if there is a change to a library API. -# Default: '[user]' -change_logs: [] diff --git a/.chloggen/mx-psi_scrub-zero-value-contents.yaml b/.chloggen/mx-psi_scrub-zero-value-contents.yaml deleted file mode 100644 index dc58de2b9276..000000000000 --- a/.chloggen/mx-psi_scrub-zero-value-contents.yaml +++ /dev/null @@ -1,25 +0,0 @@ -# Use this changelog template to create an entry for release notes. - -# One of 'breaking', 'deprecation', 'new_component', 'enhancement', 'bug_fix' -change_type: bug_fix - -# The name of the component, or a single word describing the area of concern, (e.g. receiver/otlp) -component: pkg/config/configoptional - -# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`). -note: Ensure that configoptional.None values resulting from unmarshaling are equivalent to configoptional.Optional zero value. - -# One or more tracking issues or pull requests related to the change -issues: [14218] - -# (Optional) One or more lines of additional information to render under the primary note. -# These lines will be padded with 2 spaces and then inserted directly into the document. -# Use pipe (|) for multiline entries. -subtext: - -# Optional: The change log or logs in which this entry should be included. -# e.g. '[user]' or '[user, api]' -# Include 'user' if the change is relevant to end users. -# Include 'api' if there is a change to a library API. -# Default: '[user]' -change_logs: [] diff --git a/.chloggen/no-host-in-configgrpc.yaml b/.chloggen/no-host-in-configgrpc.yaml deleted file mode 100644 index e47512f19ae9..000000000000 --- a/.chloggen/no-host-in-configgrpc.yaml +++ /dev/null @@ -1,29 +0,0 @@ -# Use this changelog template to create an entry for release notes. - -# One of 'breaking', 'deprecation', 'new_component', 'enhancement', 'bug_fix' -change_type: breaking - -# The name of the component, or a single word describing the area of concern, (e.g. otlpreceiver) -component: pkg/config/configgrpc - -# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`). -note: Replace `component.Host` parameter of ToServer/ToClientConn by map of extensions - -# One or more tracking issues or pull requests related to the change -issues: [13640] - -# (Optional) One or more lines of additional information to render under the primary note. -# These lines will be padded with 2 spaces and then inserted directly into the document. -# Use pipe (|) for multiline entries. -subtext: | - Components must now pass the map obtained from the host's `GetExtensions` method - instead of the host itself. - - Nil may be used in tests where no middleware or authentication extensions are used. - -# Optional: The change log or logs in which this entry should be included. -# e.g. '[user]' or '[user, api]' -# Include 'user' if the change is relevant to end users. -# Include 'api' if there is a change to a library API. -# Default: '[user]' -change_logs: [api] diff --git a/.chloggen/no-host-in-confighttp.yaml b/.chloggen/no-host-in-confighttp.yaml deleted file mode 100644 index f62e893cf4e4..000000000000 --- a/.chloggen/no-host-in-confighttp.yaml +++ /dev/null @@ -1,29 +0,0 @@ -# Use this changelog template to create an entry for release notes. - -# One of 'breaking', 'deprecation', 'new_component', 'enhancement', 'bug_fix' -change_type: breaking - -# The name of the component, or a single word describing the area of concern, (e.g. otlpreceiver) -component: pkg/config/confighttp - -# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`). -note: Replace `component.Host` parameter of ToServer/ToClient by map of extensions - -# One or more tracking issues or pull requests related to the change -issues: [13640] - -# (Optional) One or more lines of additional information to render under the primary note. -# These lines will be padded with 2 spaces and then inserted directly into the document. -# Use pipe (|) for multiline entries. -subtext: | - Components must now pass the map obtained from the host's `GetExtensions` method - instead of the host itself. - - Nil may be used in tests where no middleware or authentication extensions are used. - -# Optional: The change log or logs in which this entry should be included. -# e.g. '[user]' or '[user, api]' -# Include 'user' if the change is relevant to end users. -# Include 'api' if there is a change to a library API. -# Default: '[user]' -change_logs: [api] diff --git a/.chloggen/profile-duration-enhancement.yaml b/.chloggen/profile-duration-enhancement.yaml deleted file mode 100644 index 58b27cc0ad24..000000000000 --- a/.chloggen/profile-duration-enhancement.yaml +++ /dev/null @@ -1,25 +0,0 @@ -# Use this changelog template to create an entry for release notes. - -# One of 'breaking', 'deprecation', 'new_component', 'enhancement', 'bug_fix' -change_type: enhancement - -# The name of the component, or a single word describing the area of concern, (e.g. receiver/otlp) -component: pkg/pdata - -# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`). -note: Add profile.DurationNano() and profile.SetDurationNano() - -# One or more tracking issues or pull requests related to the change -issues: [14188] - -# (Optional) One or more lines of additional information to render under the primary note. -# These lines will be padded with 2 spaces and then inserted directly into the document. -# Use pipe (|) for multiline entries. -subtext: - -# Optional: The change log or logs in which this entry should be included. -# e.g. '[user]' or '[user, api]' -# Include 'user' if the change is relevant to end users. -# Include 'api' if there is a change to a library API. -# Default: '[user]' -change_logs: [api] diff --git a/.chloggen/profile-duration.yaml b/.chloggen/profile-duration.yaml deleted file mode 100644 index 20e0d9886f9e..000000000000 --- a/.chloggen/profile-duration.yaml +++ /dev/null @@ -1,25 +0,0 @@ -# Use this changelog template to create an entry for release notes. - -# One of 'breaking', 'deprecation', 'new_component', 'enhancement', 'bug_fix' -change_type: deprecation - -# The name of the component, or a single word describing the area of concern, (e.g. receiver/otlp) -component: pkg/pdata - -# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`). -note: Deprecate profile.Duration() and profile.SetDuration() - -# One or more tracking issues or pull requests related to the change -issues: [14188] - -# (Optional) One or more lines of additional information to render under the primary note. -# These lines will be padded with 2 spaces and then inserted directly into the document. -# Use pipe (|) for multiline entries. -subtext: - -# Optional: The change log or logs in which this entry should be included. -# e.g. '[user]' or '[user, api]' -# Include 'user' if the change is relevant to end users. -# Include 'api' if there is a change to a library API. -# Default: '[user]' -change_logs: [api] diff --git a/.chloggen/scraper-profiles.yaml b/.chloggen/scraper-profiles.yaml deleted file mode 100644 index 587bee22e730..000000000000 --- a/.chloggen/scraper-profiles.yaml +++ /dev/null @@ -1,25 +0,0 @@ -# Use this changelog template to create an entry for release notes. - -# One of 'breaking', 'deprecation', 'new_component', 'enhancement', 'bug_fix' -change_type: 'enhancement' - -# The name of the component, or a single word describing the area of concern, (e.g. otlpreceiver) -component: pkg/xscraper - -# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`). -note: Implement xscraper for Profiles. - -# One or more tracking issues or pull requests related to the change -issues: [13915] - -# (Optional) One or more lines of additional information to render under the primary note. -# These lines will be padded with 2 spaces and then inserted directly into the document. -# Use pipe (|) for multiline entries. -subtext: - -# Optional: The change log or logs in which this entry should be included. -# e.g. '[user]' or '[user, api]' -# Include 'user' if the change is relevant to end users. -# Include 'api' if there is a change to a library API. -# Default: '[user]' -change_logs: [user] diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 8c5b4f8b1a0d..fc8d597defbd 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -18,13 +18,25 @@ # Start components list -cmd/builder/ @open-telemetry/collector-approvers +cmd/builder/ @open-telemetry/collector-approvers @ArthurSens @dmathieu cmd/mdatagen/ @open-telemetry/collector-approvers @dmitryax cmd/mdatagen/internal/sampleconnector/ @open-telemetry/collector-approvers +cmd/mdatagen/internal/sampleentityreceiver/ @open-telemetry/collector-approvers @dmitryax cmd/mdatagen/internal/samplefactoryreceiver/ @open-telemetry/collector-approvers @dmitryax cmd/mdatagen/internal/sampleprocessor/ @open-telemetry/collector-approvers cmd/mdatagen/internal/samplereceiver/ @open-telemetry/collector-approvers @dmitryax cmd/mdatagen/internal/samplescraper/ @open-telemetry/collector-approvers @dmitryax +config/configauth/ @open-telemetry/collector-approvers +config/configcompression/ @open-telemetry/collector-approvers +config/configgrpc/ @open-telemetry/collector-approvers +config/confighttp/ @open-telemetry/collector-approvers +config/configmiddleware/ @open-telemetry/collector-approvers +config/confignet/ @open-telemetry/collector-approvers +config/configopaque/ @open-telemetry/collector-approvers +config/configoptional/ @open-telemetry/collector-approvers +config/configretry/ @open-telemetry/collector-approvers +config/configtelemetry/ @open-telemetry/collector-approvers +config/configtls/ @open-telemetry/collector-approvers confmap/ @open-telemetry/collector-approvers @mx-psi @evan-bradley confmap/provider/envprovider/ @open-telemetry/collector-approvers confmap/provider/fileprovider/ @open-telemetry/collector-approvers @@ -33,6 +45,7 @@ confmap/provider/httpsprovider/ @open-telemetry/collector-approvers confmap/provider/yamlprovider/ @open-telemetry/collector-approvers connector/forwardconnector/ @open-telemetry/collector-approvers connector/xconnector/ @open-telemetry/collector-approvers @mx-psi @dmathieu +consumer/consumererror/xconsumererror/ @open-telemetry/collector-approvers consumer/xconsumer/ @open-telemetry/collector-approvers @mx-psi @dmathieu docs/rfcs/ @open-telemetry/collector-approvers @codeboten @bogdandrutu @dmitryax @mx-psi exporter/debugexporter/ @open-telemetry/collector-approvers @andrzej-stencel @@ -62,6 +75,7 @@ receiver/xreceiver/ @open-telemetry/collector-approvers scraper/ @open-telemetry/collector-approvers scraper/xscraper @open-telemetry/collector-approvers scraper/scraperhelper/ @open-telemetry/collector-approvers +scraper/scraperhelper/xscraperhelper @open-telemetry/collector-approvers service/ @open-telemetry/collector-approvers service/internal/graph/ @open-telemetry/collector-approvers diff --git a/.github/ISSUE_TEMPLATE/bug_report.yaml b/.github/ISSUE_TEMPLATE/bug_report.yaml index bba1d2ed8767..9cc195c2eeb7 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yaml +++ b/.github/ISSUE_TEMPLATE/bug_report.yaml @@ -25,6 +25,17 @@ body: - cmd/mdatagen/internal/sampleprocessor - cmd/mdatagen/internal/samplereceiver - cmd/mdatagen/internal/samplescraper + - config/configauth + - config/configcompression + - config/configgrpc + - config/confighttp + - config/configmiddleware + - config/confignet + - config/configopaque + - config/configoptional + - config/configretry + - config/configtelemetry + - config/configtls - confmap - confmap/provider/envprovider - confmap/provider/fileprovider @@ -33,6 +44,7 @@ body: - confmap/provider/yamlprovider - connector/forward - connector/x + - consumer/consumererror/xconsumererror - consumer/xconsumer - docs/rfcs - exporter/debug @@ -41,7 +53,7 @@ body: - exporter/exporterhelper/xexporterhelper - exporter/nop - exporter/otlp - - exporter/otlphttp + - exporter/otlp_http - exporter/x - extension/memorylimiter - extension/x @@ -61,6 +73,8 @@ body: - receiver/x - scraper - scraper/scraperhelper + - scraper/scraperhelper/xscraperhelper + - scraper/xscraper - service - service/internal/graph # End components list diff --git a/.github/ISSUE_TEMPLATE/feature_request.yaml b/.github/ISSUE_TEMPLATE/feature_request.yaml index 2b10eda576f4..edcdab0fa06b 100644 --- a/.github/ISSUE_TEMPLATE/feature_request.yaml +++ b/.github/ISSUE_TEMPLATE/feature_request.yaml @@ -19,6 +19,17 @@ body: - cmd/mdatagen/internal/sampleprocessor - cmd/mdatagen/internal/samplereceiver - cmd/mdatagen/internal/samplescraper + - config/configauth + - config/configcompression + - config/configgrpc + - config/confighttp + - config/configmiddleware + - config/confignet + - config/configopaque + - config/configoptional + - config/configretry + - config/configtelemetry + - config/configtls - confmap - confmap/provider/envprovider - confmap/provider/fileprovider @@ -27,6 +38,7 @@ body: - confmap/provider/yamlprovider - connector/forward - connector/x + - consumer/consumererror/xconsumererror - consumer/xconsumer - docs/rfcs - exporter/debug @@ -34,8 +46,8 @@ body: - exporter/exporterhelper/internal/queuebatch - exporter/exporterhelper/xexporterhelper - exporter/nop - - exporter/otlp - - exporter/otlphttp + - exporter/otlp_grpc + - exporter/otlp_http - exporter/x - extension/memorylimiter - extension/x @@ -55,6 +67,8 @@ body: - receiver/x - scraper - scraper/scraperhelper + - scraper/scraperhelper/xscraperhelper + - scraper/xscraper - service - service/internal/graph # End components list diff --git a/.github/ISSUE_TEMPLATE/other.yaml b/.github/ISSUE_TEMPLATE/other.yaml index 8ec6a71b6e75..8792b1f0a3e5 100644 --- a/.github/ISSUE_TEMPLATE/other.yaml +++ b/.github/ISSUE_TEMPLATE/other.yaml @@ -18,6 +18,17 @@ body: - cmd/mdatagen/internal/sampleprocessor - cmd/mdatagen/internal/samplereceiver - cmd/mdatagen/internal/samplescraper + - config/configauth + - config/configcompression + - config/configgrpc + - config/confighttp + - config/configmiddleware + - config/confignet + - config/configopaque + - config/configoptional + - config/configretry + - config/configtelemetry + - config/configtls - confmap - confmap/provider/envprovider - confmap/provider/fileprovider @@ -26,6 +37,7 @@ body: - confmap/provider/yamlprovider - connector/forward - connector/x + - consumer/consumererror/xconsumererror - consumer/xconsumer - docs/rfcs - exporter/debug @@ -33,8 +45,8 @@ body: - exporter/exporterhelper/internal/queuebatch - exporter/exporterhelper/xexporterhelper - exporter/nop - - exporter/otlp - - exporter/otlphttp + - exporter/otlp_grpc + - exporter/otlp_http - exporter/x - extension/memorylimiter - extension/x @@ -54,6 +66,8 @@ body: - receiver/x - scraper - scraper/scraperhelper + - scraper/scraperhelper/xscraperhelper + - scraper/xscraper - service - service/internal/graph # End components list diff --git a/.github/lychee.toml b/.github/lychee.toml index a228cd084361..8fd0202285cd 100644 --- a/.github/lychee.toml +++ b/.github/lychee.toml @@ -1,11 +1,12 @@ -include-fragments = true +include_fragments = true accept = ["200..=299", "429"] exclude = [ "^http(s)?://localhost", - "^http(s)?://example.com" + "^http(s)?://example.com", + "^https://opentelemetry.io/img/logos/opentelemetry-logo-nav\\.png$", + "^https://opentelemetry.io/docs/collector/trace-receiver/?$", + "^https://www\\.gnu\\.org/software/make/$", + "^https://kubernetes\\.io/docs/reference/command-line-tools-reference/feature-gates/#feature-stages$" ] - -# better to be safe and avoid failures -max-retries = 6 diff --git a/.github/workflows/add-labels-and-owners.yml b/.github/workflows/add-labels-and-owners.yml index 5a10c038db53..91e9d4f673de 100644 --- a/.github/workflows/add-labels-and-owners.yml +++ b/.github/workflows/add-labels-and-owners.yml @@ -15,7 +15,7 @@ jobs: runs-on: ubuntu-24.04 if: ${{ github.actor != 'dependabot[bot]' && github.actor != 'renovate[bot]' && github.repository_owner == 'open-telemetry' && github.event.pull_request.draft == false }} steps: - - uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - name: Run add-codeowners-to-pr.sh run: ./.github/workflows/scripts/add-labels-and-owners.sh diff --git a/.github/workflows/add-labels-command.yml b/.github/workflows/add-labels-command.yml index 1be4eb15b5bd..0a31f302680a 100644 --- a/.github/workflows/add-labels-command.yml +++ b/.github/workflows/add-labels-command.yml @@ -13,7 +13,7 @@ jobs: runs-on: ubuntu-24.04 steps: - - uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - name: Run add-labels-command.sh run: ./.github/workflows/scripts/add-labels-command.sh diff --git a/.github/workflows/api-compatibility.yml b/.github/workflows/api-compatibility.yml index 4963e5de4231..d382f6305ef6 100644 --- a/.github/workflows/api-compatibility.yml +++ b/.github/workflows/api-compatibility.yml @@ -20,25 +20,25 @@ jobs: HEAD_REF: ${{ github.head_ref }} steps: - name: Checkout-Main - uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: ref: ${{ github.base_ref }} path: ${{ github.base_ref }} - name: Checkout-HEAD - uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: path: ${{ github.head_ref }} - name: Setup Go - uses: actions/setup-go@4dc6199c7b1a012772edbd06daecab0f50c9053c # v6.1.0 + uses: actions/setup-go@4b73464bb391d4059bd26b0524d20df3927bd417 # v6.3.0 with: go-version: oldstable cache: false - name: Cache Go id: go-cache - uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0 + uses: actions/cache@cdf6c1fa76f9f475f3d7449005a359c84ca0f306 # v5.0.3 with: path: | ~/go/bin diff --git a/.github/workflows/build-and-test-arm.yml b/.github/workflows/build-and-test-arm.yml index d204f6dd032d..6905ee7e3d5c 100644 --- a/.github/workflows/build-and-test-arm.yml +++ b/.github/workflows/build-and-test-arm.yml @@ -28,15 +28,15 @@ jobs: if: ${{ github.actor != 'dependabot[bot]' && (contains(github.event.pull_request.labels.*.name, 'Run ARM') || github.event_name == 'push' || github.event_name == 'merge_group') }} runs-on: ${{ matrix.os }} steps: - - uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0 - - uses: actions/setup-go@4dc6199c7b1a012772edbd06daecab0f50c9053c # v6.1.0 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + - uses: actions/setup-go@4b73464bb391d4059bd26b0524d20df3927bd417 # v6.3.0 with: go-version: oldstable cache: false - name: Cache Go id: go-cache timeout-minutes: 5 - uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0 + uses: actions/cache@cdf6c1fa76f9f475f3d7449005a359c84ca0f306 # v5.0.3 with: path: | ~/go/bin diff --git a/.github/workflows/build-and-test-windows.yaml b/.github/workflows/build-and-test-windows.yaml index 2836b1dad043..1d81d44013c8 100644 --- a/.github/workflows/build-and-test-windows.yaml +++ b/.github/workflows/build-and-test-windows.yaml @@ -23,14 +23,14 @@ jobs: runs-on: ${{ matrix.os }} steps: - name: Checkout Repo - uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - name: Setup Go - uses: actions/setup-go@4dc6199c7b1a012772edbd06daecab0f50c9053c # v6.1.0 + uses: actions/setup-go@4b73464bb391d4059bd26b0524d20df3927bd417 # v6.3.0 with: go-version: oldstable cache: false - name: Cache Go - uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0 + uses: actions/cache@cdf6c1fa76f9f475f3d7449005a359c84ca0f306 # v5.0.3 env: cache-name: cache-go-modules with: @@ -52,14 +52,14 @@ jobs: runs-on: ${{ matrix.os }} steps: - name: Checkout Repo - uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - name: Setup Go - uses: actions/setup-go@4dc6199c7b1a012772edbd06daecab0f50c9053c # v6.1.0 + uses: actions/setup-go@4b73464bb391d4059bd26b0524d20df3927bd417 # v6.3.0 with: go-version: oldstable cache: false - name: Cache Go - uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0 + uses: actions/cache@cdf6c1fa76f9f475f3d7449005a359c84ca0f306 # v5.0.3 env: cache-name: cache-go-modules with: diff --git a/.github/workflows/build-and-test.yml b/.github/workflows/build-and-test.yml index 9dbad3d326b3..9180358ab687 100644 --- a/.github/workflows/build-and-test.yml +++ b/.github/workflows/build-and-test.yml @@ -19,15 +19,15 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout Repo - uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - name: Setup Go - uses: actions/setup-go@4dc6199c7b1a012772edbd06daecab0f50c9053c # v6.1.0 + uses: actions/setup-go@4b73464bb391d4059bd26b0524d20df3927bd417 # v6.3.0 with: go-version: oldstable cache: false - name: Cache Go id: go-cache - uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0 + uses: actions/cache@cdf6c1fa76f9f475f3d7449005a359c84ca0f306 # v5.0.3 with: path: | ~/go/bin @@ -42,15 +42,15 @@ jobs: needs: [setup-environment] steps: - name: Checkout Repo - uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - name: Setup Go - uses: actions/setup-go@4dc6199c7b1a012772edbd06daecab0f50c9053c # v6.1.0 + uses: actions/setup-go@4b73464bb391d4059bd26b0524d20df3927bd417 # v6.3.0 with: go-version: oldstable cache: false - name: Cache Go id: go-cache - uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0 + uses: actions/cache@cdf6c1fa76f9f475f3d7449005a359c84ca0f306 # v5.0.3 with: path: | ~/go/bin @@ -67,15 +67,15 @@ jobs: needs: [setup-environment] steps: - name: Checkout Repo - uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - name: Setup Go - uses: actions/setup-go@4dc6199c7b1a012772edbd06daecab0f50c9053c # v6.1.0 + uses: actions/setup-go@4b73464bb391d4059bd26b0524d20df3927bd417 # v6.3.0 with: go-version: oldstable cache: false - name: Cache Go id: go-cache - uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0 + uses: actions/cache@cdf6c1fa76f9f475f3d7449005a359c84ca0f306 # v5.0.3 with: path: | ~/go/bin @@ -89,26 +89,32 @@ jobs: needs: [setup-environment] steps: - name: Checkout Repo - uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - name: Setup Go - uses: actions/setup-go@4dc6199c7b1a012772edbd06daecab0f50c9053c # v6.1.0 + uses: actions/setup-go@4b73464bb391d4059bd26b0524d20df3927bd417 # v6.3.0 with: go-version: stable cache: false - name: Cache Go id: go-cache - uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0 + uses: actions/cache@cdf6c1fa76f9f475f3d7449005a359c84ca0f306 # v5.0.3 with: path: | ~/go/bin ~/go/pkg/mod key: go-cache-${{ runner.os }}-${{ runner.arch }}-${{ hashFiles('**/go.sum') }} + - name: Setup Node + uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0 + with: + node-version: "24" - name: checklicense run: make checklicense - name: misspell run: make misspell - name: checkdoc run: make checkdoc + - name: markdownlint + run: make markdownlint - name: checkapi run: make checkapi - name: Check for go mod dependency changes @@ -141,6 +147,10 @@ jobs: run: | make crosslink git diff -s --exit-code || (echo 'Replace statements are out of date, please run "make crosslink" and commit the changes in this PR.' && exit 1) + - name: generate-chloggen-components + run: | + make generate-chloggen-components + git diff --exit-code || (echo '.chloggen/config.yaml is out of date, please run "make generate-chloggen-components" and commit the changes.' && exit 1) unittest-matrix: strategy: @@ -151,29 +161,29 @@ jobs: needs: [setup-environment] steps: - name: Checkout Repo - uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - name: Setup Go - uses: actions/setup-go@4dc6199c7b1a012772edbd06daecab0f50c9053c # v6.1.0 + uses: actions/setup-go@4b73464bb391d4059bd26b0524d20df3927bd417 # v6.3.0 with: go-version: ${{ matrix.go-version }} cache: false - name: Cache Go id: go-cache - uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0 + uses: actions/cache@cdf6c1fa76f9f475f3d7449005a359c84ca0f306 # v5.0.3 with: path: | ~/go/bin ~/go/pkg/mod key: go-cache-${{ runner.os }}-${{ runner.arch }}-${{ hashFiles('**/go.sum') }} - name: Cache Build - uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0 + uses: actions/cache@cdf6c1fa76f9f475f3d7449005a359c84ca0f306 # v5.0.3 with: path: ~/.cache/go-build key: unittest-${{ runner.os }}-${{ matrix.runner }}-go-build-${{ matrix.go-version }}-${{ hashFiles('**/go.sum') }} - name: Run Unit Tests run: | make -j4 gotest-with-junit - - uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0 + - uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 with: name: test-results-${{ runner.os }}-${{ matrix.runner }}-${{ matrix.go-version }} path: internal/tools/testresults/ @@ -200,29 +210,29 @@ jobs: needs: [setup-environment] steps: - name: Checkout Repo - uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - name: Setup Go - uses: actions/setup-go@4dc6199c7b1a012772edbd06daecab0f50c9053c # v6.1.0 + uses: actions/setup-go@4b73464bb391d4059bd26b0524d20df3927bd417 # v6.3.0 with: go-version: oldstable cache: false - name: Cache Go id: go-cache - uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0 + uses: actions/cache@cdf6c1fa76f9f475f3d7449005a359c84ca0f306 # v5.0.3 with: path: | ~/go/bin ~/go/pkg/mod key: go-cache-${{ runner.os }}-${{ runner.arch }}-${{ hashFiles('**/go.sum') }} - name: Cache Build - uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0 + uses: actions/cache@cdf6c1fa76f9f475f3d7449005a359c84ca0f306 # v5.0.3 with: path: ~/.cache/go-build key: coverage-${{ runner.os }}-go-build-${{ hashFiles('**/go.sum') }} - name: Run Unit Tests With Coverage run: make gotest-with-cover - name: Upload coverage report - uses: codecov/codecov-action@5a1091511ad55cbe89839c7260b706298ca349f7 # 5.5.1 + uses: codecov/codecov-action@671740ac38dd9b0130fbe1cec585b89eea48d3de # 5.5.2 env: CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} @@ -244,6 +254,8 @@ jobs: goarch: amd64 - goos: darwin goarch: arm64 + - goos: js + goarch: wasm - goos: linux goarch: 386 - goos: linux @@ -268,15 +280,15 @@ jobs: steps: - name: Checkout Repo - uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - name: Setup Go - uses: actions/setup-go@4dc6199c7b1a012772edbd06daecab0f50c9053c # v6.1.0 + uses: actions/setup-go@4b73464bb391d4059bd26b0524d20df3927bd417 # v6.3.0 with: go-version: oldstable cache: false - name: Cache Go id: go-cache - uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0 + uses: actions/cache@cdf6c1fa76f9f475f3d7449005a359c84ca0f306 # v5.0.3 with: path: | ~/go/bin diff --git a/.github/workflows/builder-integration-test.yaml b/.github/workflows/builder-integration-test.yaml index df9c8bfccd45..4dd0970f49c4 100644 --- a/.github/workflows/builder-integration-test.yaml +++ b/.github/workflows/builder-integration-test.yaml @@ -31,16 +31,16 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout Repo - uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - name: Setup Go - uses: actions/setup-go@4dc6199c7b1a012772edbd06daecab0f50c9053c # v6.1.0 + uses: actions/setup-go@4b73464bb391d4059bd26b0524d20df3927bd417 # v6.3.0 with: go-version: oldstable cache: false - name: Cache Go id: go-cache - uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0 + uses: actions/cache@cdf6c1fa76f9f475f3d7449005a359c84ca0f306 # v5.0.3 with: path: | ~/go/bin diff --git a/.github/workflows/builder-snapshot.yaml b/.github/workflows/builder-snapshot.yaml index 10b53d12c816..37fca2ec2ec1 100644 --- a/.github/workflows/builder-snapshot.yaml +++ b/.github/workflows/builder-snapshot.yaml @@ -19,14 +19,14 @@ env: jobs: snapshot: runs-on: ubuntu-24.04 - if: ${{ github.repository_owner == 'open-telemetry' }} + if: ${{ github.repository_owner == 'Sawmills' }} steps: - - uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: path: .core - name: Pull the latest releases repo - uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: path: opentelemetry-collector-releases repository: open-telemetry/opentelemetry-collector-releases @@ -34,25 +34,25 @@ jobs: - name: Copy release files run: cp -R ./opentelemetry-collector-releases/cmd/builder/. ./.core/cmd/builder/ - - uses: sigstore/cosign-installer@faadad0cce49287aee09b3a48701e75088a2c6ad # v4.0.0 + - uses: sigstore/cosign-installer@ba7bc0a3fef59531c69a25acd34668d6d3fe6f22 # v4.1.0 - - uses: anchore/sbom-action/download-syft@fbfd9c6c189226748411491745178e0c2017392d # v0.20.10 + - uses: anchore/sbom-action/download-syft@57aae528053a48a3f6235f2d9461b05fbcb7366d # v0.23.1 - - uses: docker/setup-qemu-action@c7c53464625b32c7a7e944ae62b3e17d2b600130 # v3.7.0 + - uses: docker/setup-qemu-action@ce360397dd3f832beb865e1373c09c0e9f86d70a # v4.0.0 with: - platforms: amd64, arm64,ppc64le + platforms: amd64,arm64,ppc64le,s390x,riscv64 - - uses: docker/setup-buildx-action@e468171a9de216ec08956ac3ada2f0791b6bd435 # v3.11.1 + - uses: docker/setup-buildx-action@4d04d5d9486b7bd6fa91e7baf45bbb4f8b9deedd # v4.0.0 - name: Setup Go - uses: actions/setup-go@4dc6199c7b1a012772edbd06daecab0f50c9053c # v6.1.0 + uses: actions/setup-go@4b73464bb391d4059bd26b0524d20df3927bd417 # v6.3.0 with: go-version: stable cache: false - name: Cache Go id: go-cache - uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0 + uses: actions/cache@cdf6c1fa76f9f475f3d7449005a359c84ca0f306 # v5.0.3 with: path: | ~/go/bin @@ -60,7 +60,7 @@ jobs: key: go-cache-${{ runner.os }}-${{ runner.arch }}-${{ hashFiles('**/go.sum') }} - name: Check GoReleaser - uses: goreleaser/goreleaser-action@e435ccd777264be153ace6237001ef4d979d3a7a # v6.4.0 + uses: goreleaser/goreleaser-action@ec59f474b9834571250b370d4735c50f8e2d1e29 # v7.0.0 with: distribution: goreleaser-pro version: ${{ env.GORELEASER_PRO_VERSION }} @@ -70,7 +70,7 @@ jobs: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - name: Run GoReleaser - uses: goreleaser/goreleaser-action@e435ccd777264be153ace6237001ef4d979d3a7a # v6.4.0 + uses: goreleaser/goreleaser-action@ec59f474b9834571250b370d4735c50f8e2d1e29 # v7.0.0 with: distribution: goreleaser-pro version: ${{ env.GORELEASER_PRO_VERSION }} diff --git a/.github/workflows/changelog.yml b/.github/workflows/changelog.yml index 4db9f3886a90..3c6353abc37f 100644 --- a/.github/workflows/changelog.yml +++ b/.github/workflows/changelog.yml @@ -27,18 +27,18 @@ jobs: PR_HEAD: ${{ github.event.pull_request.head.sha }} steps: - name: Checkout Repo - uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: fetch-depth: 0 - name: Setup Go - uses: actions/setup-go@4dc6199c7b1a012772edbd06daecab0f50c9053c # v6.1.0 + uses: actions/setup-go@4b73464bb391d4059bd26b0524d20df3927bd417 # v6.3.0 with: go-version: oldstable cache: false - name: Cache Go id: go-cache - uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0 + uses: actions/cache@cdf6c1fa76f9f475f3d7449005a359c84ca0f306 # v5.0.3 with: path: | ~/go/bin @@ -58,17 +58,6 @@ jobs: echo "CHANGELOG.md and CHANGELOG-API.md were not modified." fi - - name: Ensure changelog config.yaml is up to date - run: | - make generate-chloggen-components - if [[ $(git diff --name-only) ]]; then - echo ".chloggen/config.yaml is out of date. Please run 'make generate-chloggen-components' and commit the changes." - false - else - echo ".chloggen/config.yaml is up to date." - fi - git checkout $PR_HEAD -- ./.chloggen/config.yaml - - name: Ensure ./.chloggen/*.yaml addition(s) run: | if [[ 1 -gt $(git diff --diff-filter=A --name-only $(git merge-base origin/main $PR_HEAD) $PR_HEAD ./.chloggen | grep -c \\.yaml) ]] @@ -92,7 +81,7 @@ jobs: run: make chlog-preview > changelog_preview.md - name: Link Checker id: lychee - uses: lycheeverse/lychee-action@a8c4c7cb88f0c7386610c35eb25108e448569cb0 # v2.7.0 + uses: lycheeverse/lychee-action@8646ba30535128ac92d33dfc9133794bfdd9b411 # v2.8.0 with: args: "--verbose --no-progress ./changelog_preview.md --config .github/lychee.toml" failIfEmpty: false diff --git a/.github/workflows/check-codeowners.yaml b/.github/workflows/check-codeowners.yaml index 8dc66723e6ba..527ff1e321d7 100644 --- a/.github/workflows/check-codeowners.yaml +++ b/.github/workflows/check-codeowners.yaml @@ -34,21 +34,21 @@ jobs: runs-on: ubuntu-24.04 if: ${{ github.actor != 'dependabot[bot]' && github.repository == 'open-telemetry/opentelemetry-collector' }} steps: - - uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 - - uses: actions/setup-go@4dc6199c7b1a012772edbd06daecab0f50c9053c # v6 + - uses: actions/setup-go@4b73464bb391d4059bd26b0524d20df3927bd417 # v6 id: go-setup with: go-version: oldstable cache-dependency-path: "**/*.sum" - - uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 with: ref: ${{github.event.pull_request.head.ref}} repository: ${{github.event.pull_request.head.repo.full_name}} path: pr - - uses: actions/create-github-app-token@7e473efe3cb98aa54f8d4bac15400b15fad77d94 # v2.2.0 + - uses: actions/create-github-app-token@29824e69f54612133e76f7eaac726eef6c875baf # v2.2.1 id: otelbot-token with: app-id: ${{ vars.OTELBOT_APP_ID }} diff --git a/.github/workflows/check-links.yaml b/.github/workflows/check-links.yaml index 27ee66173be0..33d2c787d2ba 100644 --- a/.github/workflows/check-links.yaml +++ b/.github/workflows/check-links.yaml @@ -22,7 +22,7 @@ jobs: files: ${{ steps.changes.outputs.files }} steps: - name: Checkout Repo - uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: fetch-depth: 0 - name: Get changed files @@ -41,13 +41,13 @@ jobs: if: ${{needs.changedfiles.outputs.files}} steps: - name: Checkout Repo - uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: fetch-depth: 0 - name: Link Checker id: lychee - uses: lycheeverse/lychee-action@a8c4c7cb88f0c7386610c35eb25108e448569cb0 # v2.7.0 + uses: lycheeverse/lychee-action@8646ba30535128ac92d33dfc9133794bfdd9b411 # v2.8.0 with: args: "--verbose --no-progress ${{needs.changedfiles.outputs.files}} --config .github/lychee.toml" failIfEmpty: false diff --git a/.github/workflows/check-merge-freeze.yml b/.github/workflows/check-merge-freeze.yml index bd0cb5b1f821..1a7fc1aef292 100644 --- a/.github/workflows/check-merge-freeze.yml +++ b/.github/workflows/check-merge-freeze.yml @@ -27,7 +27,7 @@ jobs: ((github.event.pull_request.user.login || github.event.merge_group.head_commit.author.name) != 'otelbot[bot]') runs-on: ubuntu-latest steps: - - uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: sparse-checkout: .github/workflows/scripts - run: ./.github/workflows/scripts/check-merge-freeze.sh diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index 3cb8bbc73d1a..e598e0924bf5 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -20,17 +20,17 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - name: Setup Go - uses: actions/setup-go@4dc6199c7b1a012772edbd06daecab0f50c9053c # v6.1.0 + uses: actions/setup-go@4b73464bb391d4059bd26b0524d20df3927bd417 # v6.3.0 with: go-version: oldstable cache: false - name: Cache Go id: go-cache - uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0 + uses: actions/cache@cdf6c1fa76f9f475f3d7449005a359c84ca0f306 # v5.0.3 with: path: | ~/go/bin @@ -39,12 +39,12 @@ jobs: # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL - uses: github/codeql-action/init@fdbfb4d2750291e159f0156def62b853c2798ca2 # v4.31.5 + uses: github/codeql-action/init@0d579ffd059c29b07949a3cce3983f0780820c98 # v4.32.6 with: languages: go - name: Autobuild - uses: github/codeql-action/autobuild@fdbfb4d2750291e159f0156def62b853c2798ca2 # v4.31.5 + uses: github/codeql-action/autobuild@0d579ffd059c29b07949a3cce3983f0780820c98 # v4.32.6 - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@fdbfb4d2750291e159f0156def62b853c2798ca2 # v4.31.5 + uses: github/codeql-action/analyze@0d579ffd059c29b07949a3cce3983f0780820c98 # v4.32.6 diff --git a/.github/workflows/contrib-tests.yml b/.github/workflows/contrib-tests.yml index 533de78c40c0..8be1c7ab445e 100644 --- a/.github/workflows/contrib-tests.yml +++ b/.github/workflows/contrib-tests.yml @@ -62,21 +62,21 @@ jobs: - other steps: - name: Checkout Repo - uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - name: Download contrib - uses: actions/download-artifact@018cc2cf5baa6db3ef3c5f8a56943fffe632ef53 # v6.0.0 + uses: actions/download-artifact@70fc10c6e5e1ce46ad2ea6f2b72d43f7d47b13c3 # v8.0.0 with: name: contrib path: /tmp/contrib - name: Setup Go - uses: actions/setup-go@4dc6199c7b1a012772edbd06daecab0f50c9053c # v6.1.0 + uses: actions/setup-go@4b73464bb391d4059bd26b0524d20df3927bd417 # v6.3.0 with: go-version: oldstable cache: false - name: Cache Go id: go-cache - uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0 + uses: actions/cache@cdf6c1fa76f9f475f3d7449005a359c84ca0f306 # v5.0.3 with: path: | ~/go/bin @@ -85,7 +85,6 @@ jobs: - name: Run tests run: | - chmod +x /tmp/contrib/.tools/* make CONTRIB_PATH=/tmp/contrib SKIP_RESTORE_CONTRIB=true GROUP=${{ matrix.group }} check-contrib contrib_tests: diff --git a/.github/workflows/fossa.yml b/.github/workflows/fossa.yml index d0af31d300a3..21d6b7ce19de 100644 --- a/.github/workflows/fossa.yml +++ b/.github/workflows/fossa.yml @@ -12,9 +12,9 @@ jobs: fossa: runs-on: ubuntu-latest steps: - - uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - - uses: fossas/fossa-action@3ebcea1862c6ffbd5cf1b4d0bd6b3fe7bd6f2cac # v1.7.0 + - uses: fossas/fossa-action@c414b9ad82eaad041e47a7cf62a4f02411f427a0 # v1.8.0 with: api-key: ${{secrets.FOSSA_API_KEY}} team: OpenTelemetry diff --git a/.github/workflows/go-benchmarks.yml b/.github/workflows/go-benchmarks.yml index 3a1c393043e0..50e3d1d28227 100644 --- a/.github/workflows/go-benchmarks.yml +++ b/.github/workflows/go-benchmarks.yml @@ -14,10 +14,10 @@ jobs: env: HAS_CODSPEED_TOKEN: ${{ secrets.CODSPEED_TOKEN != '' }} steps: - - uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - run: ./.github/workflows/scripts/free-disk-space.sh - name: Setup Go - uses: actions/setup-go@4dc6199c7b1a012772edbd06daecab0f50c9053c # v6.1.0 + uses: actions/setup-go@4b73464bb391d4059bd26b0524d20df3927bd417 # v6.3.0 with: go-version: stable cache: false diff --git a/.github/workflows/lint-workflow-files.yml b/.github/workflows/lint-workflow-files.yml index 77efa2d0cd83..ec51ae69443b 100644 --- a/.github/workflows/lint-workflow-files.yml +++ b/.github/workflows/lint-workflow-files.yml @@ -19,17 +19,17 @@ jobs: steps: - name: Checkout code - uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - name: Set up Go - uses: actions/setup-go@4dc6199c7b1a012772edbd06daecab0f50c9053c # v6 + uses: actions/setup-go@4b73464bb391d4059bd26b0524d20df3927bd417 # v6 with: go-version: stable cache: false - name: Cache Go id: go-cache - uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0 + uses: actions/cache@cdf6c1fa76f9f475f3d7449005a359c84ca0f306 # v5.0.3 with: path: | ~/go/bin diff --git a/.github/workflows/perf.yml b/.github/workflows/perf.yml index d32407f76463..de79c462b949 100644 --- a/.github/workflows/perf.yml +++ b/.github/workflows/perf.yml @@ -10,17 +10,17 @@ jobs: runperf: runs-on: ubuntu-latest steps: - - uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - name: Setup Go - uses: actions/setup-go@4dc6199c7b1a012772edbd06daecab0f50c9053c # v6.1.0 + uses: actions/setup-go@4b73464bb391d4059bd26b0524d20df3927bd417 # v6.3.0 with: go-version: oldstable cache: false - name: Cache Go id: go-cache - uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0 + uses: actions/cache@cdf6c1fa76f9f475f3d7449005a359c84ca0f306 # v5.0.3 with: path: | ~/go/bin diff --git a/.github/workflows/ping-codeowners-issues.yml b/.github/workflows/ping-codeowners-issues.yml index 57debb5fd1a7..2cac27803e4b 100644 --- a/.github/workflows/ping-codeowners-issues.yml +++ b/.github/workflows/ping-codeowners-issues.yml @@ -10,9 +10,9 @@ jobs: permissions: issues: write runs-on: ubuntu-24.04 - if: ${{ github.repository_owner == 'open-telemetry' }} + if: ${{ github.repository_owner == 'Sawmills' }} steps: - - uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - name: Run ping-codeowners-issues.sh run: ./.github/workflows/scripts/ping-codeowners-issues.sh diff --git a/.github/workflows/ping-codeowners-on-new-issue.yml b/.github/workflows/ping-codeowners-on-new-issue.yml index 1aa42ed5882c..7f72759bad8e 100644 --- a/.github/workflows/ping-codeowners-on-new-issue.yml +++ b/.github/workflows/ping-codeowners-on-new-issue.yml @@ -12,7 +12,7 @@ jobs: runs-on: ubuntu-24.04 if: ${{ github.repository_owner == 'open-telemetry' }} steps: - - uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - name: Run ping-codeowners-on-new-issue.sh run: ./.github/workflows/scripts/ping-codeowners-on-new-issue.sh diff --git a/.github/workflows/ping-codeowners-prs.yml b/.github/workflows/ping-codeowners-prs.yml index d1e9c581f395..57bfc34f2a93 100644 --- a/.github/workflows/ping-codeowners-prs.yml +++ b/.github/workflows/ping-codeowners-prs.yml @@ -14,7 +14,7 @@ jobs: runs-on: ubuntu-24.04 if: ${{ github.actor != 'dependabot[bot]' && github.actor != 'renovate[bot]' && github.repository_owner == 'open-telemetry' && github.event.pull_request.draft == false }} steps: - - uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - name: Run ping-codeowners-prs.sh run: ./.github/workflows/scripts/ping-codeowners-prs.sh diff --git a/.github/workflows/prepare-release.yml b/.github/workflows/prepare-release.yml index ffabf61f1bbb..dd6918a59974 100644 --- a/.github/workflows/prepare-release.yml +++ b/.github/workflows/prepare-release.yml @@ -65,7 +65,7 @@ jobs: - validate-versions-format runs-on: ubuntu-latest steps: - - uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: fetch-depth: 0 # Make sure that there are no open issues with release:blocker label in Core. The release has to be delayed until they are resolved. @@ -100,7 +100,7 @@ jobs: permissions: issues: write steps: - - uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: fetch-depth: 0 # To keep track of the progress, it might be helpful to create a tracking issue similar to #6067. You are responsible @@ -124,25 +124,25 @@ jobs: permissions: contents: write steps: - - uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: fetch-depth: 0 - name: Setup Go - uses: actions/setup-go@4dc6199c7b1a012772edbd06daecab0f50c9053c # v6.1.0 + uses: actions/setup-go@4b73464bb391d4059bd26b0524d20df3927bd417 # v6.3.0 with: go-version: stable cache: false - name: Cache Go id: go-cache - uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0 + uses: actions/cache@cdf6c1fa76f9f475f3d7449005a359c84ca0f306 # v5.0.3 with: path: | ~/go/bin ~/go/pkg/mod key: go-cache-${{ runner.os }}-${{ runner.arch }}-${{ hashFiles('**/go.sum') }} - - uses: actions/create-github-app-token@7e473efe3cb98aa54f8d4bac15400b15fad77d94 # v2.2.0 + - uses: actions/create-github-app-token@29824e69f54612133e76f7eaac726eef6c875baf # v2.2.1 id: otelbot-token with: app-id: ${{ vars.OTELBOT_APP_ID }} diff --git a/.github/workflows/release-branch.yml b/.github/workflows/release-branch.yml index 8c6c581bb727..f4eceb8c8f9e 100644 --- a/.github/workflows/release-branch.yml +++ b/.github/workflows/release-branch.yml @@ -18,19 +18,19 @@ jobs: contents: write steps: - name: Checkout repository - uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: fetch-depth: 0 - name: Setup Go - uses: actions/setup-go@4dc6199c7b1a012772edbd06daecab0f50c9053c # v6.1.0 + uses: actions/setup-go@4b73464bb391d4059bd26b0524d20df3927bd417 # v6.3.0 with: go-version: oldstable cache: false - name: Cache Go id: go-cache - uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0 + uses: actions/cache@cdf6c1fa76f9f475f3d7449005a359c84ca0f306 # v5.0.3 with: path: | ~/go/bin diff --git a/.github/workflows/rerun-workflows.yml b/.github/workflows/rerun-workflows.yml new file mode 100644 index 000000000000..c5a7ca2fd83d --- /dev/null +++ b/.github/workflows/rerun-workflows.yml @@ -0,0 +1,24 @@ +name: "Rerun Failed Workflows" +on: + issue_comment: + types: + - created + +permissions: read-all + +jobs: + rerun-failed: + if: ${{ github.event.issue.pull_request && startsWith(github.event.comment.body, '/rerun') && github.repository_owner == 'open-telemetry' }} + permissions: + actions: write + checks: read + runs-on: ubuntu-24.04 + steps: + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 + - name: Run rerun-failed-workflows.sh + run: ./.github/workflows/scripts/rerun-failed-workflows.sh + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + PR_NUMBER: ${{ github.event.issue.number }} + COMMENT: ${{ github.event.comment.body }} + SENDER: ${{ github.event.comment.user.login }} diff --git a/.github/workflows/scorecard.yml b/.github/workflows/scorecard.yml index 67f8e827ee9e..3128978798a4 100644 --- a/.github/workflows/scorecard.yml +++ b/.github/workflows/scorecard.yml @@ -29,7 +29,7 @@ jobs: steps: - name: "Checkout code" - uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: persist-credentials: false @@ -56,7 +56,7 @@ jobs: # Upload the results as artifacts (optional). Commenting out will disable uploads of run results in SARIF # format to the repository Actions tab. - name: "Upload artifact" - uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0 + uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 with: name: SARIF file path: results.sarif @@ -64,6 +64,6 @@ jobs: # Upload the results to GitHub's code scanning dashboard. - name: "Upload to code-scanning" - uses: github/codeql-action/upload-sarif@fdbfb4d2750291e159f0156def62b853c2798ca2 # v4.31.5 + uses: github/codeql-action/upload-sarif@0d579ffd059c29b07949a3cce3983f0780820c98 # v4.32.6 with: sarif_file: results.sarif diff --git a/.github/workflows/scripts/release-create-tracking-issue.sh b/.github/workflows/scripts/release-create-tracking-issue.sh index f85db07ce7dd..585acbfcf02b 100755 --- a/.github/workflows/scripts/release-create-tracking-issue.sh +++ b/.github/workflows/scripts/release-create-tracking-issue.sh @@ -18,15 +18,21 @@ if [ "${EXISTING_ISSUE}" != "" ]; then exit 0 fi -gh issue create -a "${GITHUB_ACTOR}" --repo "${REPO}" --label release --title "Release ${RELEASE_VERSION}" --body "Like #4522, but for ${RELEASE_VERSION} +gh issue create -a "${GITHUB_ACTOR}" --repo "${REPO}" --label release --title "Release ${RELEASE_VERSION}" --body "Like #14236, but for ${RELEASE_VERSION} **Performed by collector release manager** - [ ] Prepare core release ${RELEASE_VERSION} - [ ] Tag and release core ${RELEASE_VERSION} + +**Performed by collector contrib release manager** + - [ ] Prepare contrib release v${CANDIDATE_BETA} - [ ] Tag and release contrib v${CANDIDATE_BETA} -- [ ] Prepare otelcol-releases v${CANDIDATE_BETA} -- [ ] Release binaries and container images v${CANDIDATE_BETA} + +**Performed by collector releases release manager** + +- [ ] Prepare otelcol containers images release v${CANDIDATE_BETA} +- [ ] Tag and otelcol containers images release v${CANDIDATE_BETA} **Performed by operator maintainers** diff --git a/.github/workflows/scripts/rerun-failed-workflows.sh b/.github/workflows/scripts/rerun-failed-workflows.sh new file mode 100755 index 000000000000..308c4b8bd1a0 --- /dev/null +++ b/.github/workflows/scripts/rerun-failed-workflows.sh @@ -0,0 +1,44 @@ +#!/usr/bin/env bash +# +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 +# + +set -euo pipefail + +if [[ -z "${PR_NUMBER:-}" || -z "${COMMENT:-}" || -z "${SENDER:-}" ]]; then + echo "PR_NUMBER, COMMENT, or SENDER not set" + exit 0 +fi + +if [[ ${COMMENT:0:6} != "/rerun" ]]; then + echo "Not a rerun command" + exit 0 +fi + +PR_DATA=$(gh pr view "${PR_NUMBER}" --json headRefOid,author) +HEAD_SHA=$(echo "${PR_DATA}" | jq -r '.headRefOid') +PR_AUTHOR=$(echo "${PR_DATA}" | jq -r '.author.login') + +if [[ "${SENDER}" != "${PR_AUTHOR}" ]]; then + echo "Only PR author can rerun workflows" + exit 0 +fi + +echo "Finding failed workflows for commit: ${HEAD_SHA}" + +FAILED_RUNS=$(gh run list \ + --commit "${HEAD_SHA}" \ + --status failure \ + --json databaseId \ + --jq '.[].databaseId') + +if [[ -z "${FAILED_RUNS}" ]]; then + echo "No failed workflows found" + exit 0 +else + for RUN_ID in ${FAILED_RUNS}; do + echo "Rerunning workflow: ${RUN_ID}" + gh run rerun "${RUN_ID}" --failed + done +fi diff --git a/.github/workflows/shellcheck.yml b/.github/workflows/shellcheck.yml index 6321a54d3e6b..133ecf9ece0e 100644 --- a/.github/workflows/shellcheck.yml +++ b/.github/workflows/shellcheck.yml @@ -14,6 +14,6 @@ jobs: name: Shellcheck runs-on: ubuntu-latest steps: - - uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - name: Run ShellCheck uses: ludeeus/action-shellcheck@00cae500b08a931fb5698e11e79bfbd38e612a38 # 2.0.0 diff --git a/.github/workflows/sourcecode-release.yaml b/.github/workflows/sourcecode-release.yaml index 604d16eefa65..dc783c707962 100644 --- a/.github/workflows/sourcecode-release.yaml +++ b/.github/workflows/sourcecode-release.yaml @@ -16,7 +16,7 @@ jobs: issues: write # Grant write permissions to PR milestones steps: - name: Checkout Repo - uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: fetch-depth: 0 diff --git a/.github/workflows/spell-check.yaml b/.github/workflows/spell-check.yaml index 27d89ea32312..a33654e030fb 100644 --- a/.github/workflows/spell-check.yaml +++ b/.github/workflows/spell-check.yaml @@ -13,10 +13,10 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - name: Run cSpell - uses: streetsidesoftware/cspell-action@3294df585d3d639e30f3bc019cb11940b9866e95 # v8.0.0 + uses: streetsidesoftware/cspell-action@9cd41bb518a24fefdafd9880cbab8f0ceba04d28 # v8.3.0 with: incremental_files_only: false use_cspell_files: true diff --git a/.github/workflows/stale-pr.yaml b/.github/workflows/stale-pr.yaml index 9f5d1083b9c7..b6b2a8fbfd36 100644 --- a/.github/workflows/stale-pr.yaml +++ b/.github/workflows/stale-pr.yaml @@ -12,7 +12,7 @@ jobs: pull-requests: write # for actions/stale to close stale PRs runs-on: ubuntu-latest steps: - - uses: actions/stale@5f858e3efba33a5ca4407a664cc011ad407f2008 # v10.1.0 + - uses: actions/stale@b5d41d4e1d5dceea10e7104786b73624c18a190f # v10.2.0 with: repo-token: ${{ secrets.GITHUB_TOKEN }} stale-pr-message: "This PR was marked stale due to lack of activity. It will be closed in 14 days." diff --git a/.github/workflows/survey-on-merged-pr.yml b/.github/workflows/survey-on-merged-pr.yml index bb5861d3c59a..b7424e410aa4 100644 --- a/.github/workflows/survey-on-merged-pr.yml +++ b/.github/workflows/survey-on-merged-pr.yml @@ -17,7 +17,7 @@ jobs: runs-on: ubuntu-latest if: github.event.pull_request.merged == true steps: - - uses: actions/create-github-app-token@7e473efe3cb98aa54f8d4bac15400b15fad77d94 # v2.2.0 + - uses: actions/create-github-app-token@29824e69f54612133e76f7eaac726eef6c875baf # v2.2.1 id: otelbot-token with: app-id: ${{ vars.OTELBOT_APP_ID }} diff --git a/.github/workflows/tidy-dependencies.yml b/.github/workflows/tidy-dependencies.yml index c7330604ca7f..a7e5294cce92 100644 --- a/.github/workflows/tidy-dependencies.yml +++ b/.github/workflows/tidy-dependencies.yml @@ -13,18 +13,18 @@ jobs: contents: write # for Git to git push timeout-minutes: 30 runs-on: ubuntu-latest - if: ${{ !contains(github.event.pull_request.labels.*.name, 'dependency-major-update') && (github.actor == 'renovate[bot]' || contains(github.event.pull_request.labels.*.name, 'renovatebot')) }} + if: ${{ !contains(github.event.pull_request.labels.*.name, 'dependency-major-update') && (github.actor == 'renovate[bot]' || contains(github.event.pull_request.labels.*.name, 'renovatebot')) && github.event.pull_request.head.repo.fork == false }} steps: - - uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: ref: ${{ github.head_ref }} - - uses: actions/setup-go@4dc6199c7b1a012772edbd06daecab0f50c9053c # v6.1.0 + - uses: actions/setup-go@4b73464bb391d4059bd26b0524d20df3927bd417 # v6.3.0 with: go-version: oldstable cache: false - name: Cache Go id: go-cache - uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0 + uses: actions/cache@cdf6c1fa76f9f475f3d7449005a359c84ca0f306 # v5.0.3 with: path: | ~/go/bin diff --git a/.github/workflows/utils/cspell.json b/.github/workflows/utils/cspell.json index dcec12199e69..1b4939dcabfa 100644 --- a/.github/workflows/utils/cspell.json +++ b/.github/workflows/utils/cspell.json @@ -2,6 +2,7 @@ "version": "0.2", "language": "en", "words": [ + "aggregatable", "Alolita", "Andrzej", "Anoshin", @@ -22,6 +23,7 @@ "Distro", "Dmitrii", "Dockerhub", + "Dont", "Drutu", "Dynatrace", "Excalidraw", @@ -85,6 +87,7 @@ "Unmarshalable", "Unmarshaller", "Unmarshallers", + "unmarshalled", "Vihas", "Weng", "Zipkin", @@ -125,6 +128,7 @@ "cmux", "codeboten", "codeowners", + "componentalias", "componenterror", "componenthelper", "componentprofiles", @@ -147,6 +151,7 @@ "configparser", "configretry", "configrpc", + "configschema", "configsource", "configtelemetry", "configtest", @@ -313,6 +318,7 @@ "multiclient", "multimod", "mycert", + "mycomponent", "myconnector", "myexporter", "myextension", @@ -321,6 +327,7 @@ "myreceiver", "myrepo", "mysite", + "nodisplayname", "nonclobbering", "nopexporter", "nopreceiver", @@ -351,6 +358,7 @@ "otelzap", "otlpexporter", "otlpgrpc", + "otlp_http", "otlphttp", "otlphttpexporter", "otlphttpexporter's", @@ -399,9 +407,11 @@ "protos", "ptraceotlp", "queuebatch", + "reaggregate", "receiverhelper", "receiverprofiles", "receivertest", + "replicaset", "renovatebot", "resourcedetection", "resourcedetectionprocessor", @@ -413,6 +423,8 @@ "rrschulze", "runperf", "safelist", + "sampleentity", + "sampleentityreceiver", "samplefactoryreceiver", "samplereceiver", "samplingdecision", @@ -420,6 +432,7 @@ "sarama", "sattributes", "sattributesprocessor", + "schemagen", "scrapererror", "scraperhelper", "scrapertest", @@ -457,6 +470,7 @@ "testcomponents", "testconverter", "testdata", + "testdesc", "testfunc", "testonly", "testprocessor", @@ -505,6 +519,7 @@ "xprocessorhelper", "xreceiver", "xscraper", + "xscraperhelper", "yamlmapprovider", "yamlprovider", "yamls", diff --git a/.gitignore b/.gitignore index e70fa857c72f..bf1e36a663eb 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,7 @@ bin/ dist/ /local +.schemas # GoLand IDEA /.idea/ @@ -10,6 +11,9 @@ dist/ .vscode/ .devcontainer/ +# Cursor +.cursor + # Emacs *~ \#*\# diff --git a/.golangci.yml b/.golangci.yml index 7baced4afa0f..d93f37c388b6 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -75,6 +75,8 @@ linters: deny: - pkg: "go.uber.org/atomic" desc: "Use 'sync/atomic' instead of go.uber.org/atomic" + - pkg: "gopkg.in/yaml.v3" + desc: "Use 'go.yaml.in/yaml/v3' instead of gopkg.in/yaml.v3" - pkg: "github.com/pkg/errors" desc: "Use 'errors' or 'fmt' instead of github.com/pkg/errors" - pkg: "github.com/hashicorp/go-multierror" @@ -83,6 +85,15 @@ linters: desc: "Use the newer 'math/rand/v2' instead of math/rand" - pkg: "sigs.k8s.io/yaml" desc: "Use 'go.yaml.in/yaml' instead of sigs.k8s.io/yaml" + semconv: + list-mode: lax + files: + - "!cmd/mdatagen/**" # Exclude mdatagen + deny: + - pkg: go.opentelemetry.io/otel/semconv + desc: Use go.opentelemetry.io/otel/semconv/v1.38.0 instead. If a newer semconv version has been released, update the depguard rule. + allow: + - go.opentelemetry.io/otel/semconv/v1.38.0 # Add a different guard rule so that we can ignore tests. ignore-in-test: # Allow in tests for testing pdata or other receivers/exporters that expect OTLP. diff --git a/.markdownlint.yaml b/.markdownlint.yaml new file mode 100644 index 000000000000..7c7ed47bda37 --- /dev/null +++ b/.markdownlint.yaml @@ -0,0 +1,39 @@ +# markdownlint configuration for OpenTelemetry Collector +# https://github.com/DavidAnson/markdownlint/blob/main/doc/Rules.md +# +# Start permissive to establish a baseline; tighten rules over time. +default: true + +# Disabled rules (existing codebase has many violations) +MD001: false # heading increment +MD004: false # unordered list style +MD007: false # unordered list indentation +MD009: false # trailing spaces +MD010: false # hard tabs +MD012: false # multiple consecutive blank lines +MD013: false # line length +MD014: false # dollar signs in commands +MD022: false # blanks around headings +MD024: false # duplicate headings +MD025: false # multiple top-level headings +MD026: false # trailing punctuation in heading +MD029: false # ordered list prefix +MD030: false # spaces after list markers +MD031: false # blanks around fences +MD032: false # blanks around lists +MD033: false # inline HTML +MD034: false # bare URLs +MD036: false # emphasis as heading +MD038: false # spaces in code spans +MD040: false # fenced code language +MD041: false # first line heading +MD047: false # single trailing newline +MD049: false # emphasis style +MD051: false # link fragments +MD053: false # unused link definitions +MD058: false # blanks around tables +MD059: false # descriptive link text +MD060: false # table column style +MD018: false # no space after hash in heading +MD028: false # blank line inside blockquote +MD037: false # spaces inside emphasis diff --git a/.markdownlintignore b/.markdownlintignore new file mode 100644 index 000000000000..88ea04aff409 --- /dev/null +++ b/.markdownlintignore @@ -0,0 +1,6 @@ +# Changelogs (autogenerated, chloggen manages structure) +CHANGELOG.md +CHANGELOG-API.md + +# GitHub templates (intentional structure/HTML) +.github/ diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 000000000000..25ab4de17a17 --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,36 @@ +# AGENTS.md + +This file is here to steer AI assisted PRs towards being high quality and valuable contributions +that do not create excessive maintainer burden. It is inspired by the Open Policy Agent and Fedora +projects policies. + +## General Rules and Guidelines + +The most important rule is not to post comments on issues or PRs that are AI-generated. Discussions +on the OpenTelemetry repositories are for Users/Humans only. + +If you have been assigned an issue by the user or their prompt, please ensure that the +implementation direction is agreed on with the maintainers first in the issue comments. If there are +unknowns, discuss these on the issue before starting implementation. Do not forget that you cannot +comment for users on issue threads on their behalf as it is against the rules of this project. + +## Developer environment + +Make sure to follow docs/coding-guidelines.md on any contributions. + +Non-exhaustively, the important points are: + +* Whenever applicable, all code changes should have tests that actually validate the changes. + +## Commit formatting + +We appreciate it if users disclose the use of AI tools when the significant part of a commit is +taken from a tool without changes. When making a commit this should be disclosed through an +Assisted-by: commit message trailer. + +Examples: + +``` +Assisted-by: ChatGPT 5.2 +Assisted-by: Claude Opus 4.5 +``` diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 000000000000..43c994c2d361 --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1 @@ +@AGENTS.md diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 53d7a63ab027..7344c65723e5 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -59,7 +59,7 @@ Components refer to connectors, exporters, extensions, processors, and receivers * Provide a configuration structure which defines the configuration of the component * Provide the implementation that performs the component operation -For more details on components, see the [Adding New Components](https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/main/CONTRIBUTING.md#adding-new-components) document and the tutorial [Building a Trace Receiver](https://opentelemetry.io/docs/collector/trace-receiver/) which provides a detailed example of building a component. +For more details on components, see the [Adding New Components](https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/main/CONTRIBUTING.md) document and the tutorial [Building a Trace Receiver](https://opentelemetry.io/docs/collector/trace-receiver/) which provides a detailed example of building a component. When adding a new component to the OpenTelemetry Collector, ensure that any configuration structs used by the component include fields with the `configopaque.String` type for sensitive data. This ensures that the data is masked when serialized to prevent accidental exposure. @@ -127,6 +127,16 @@ Example label comment: /label help-wanted -arm64 ``` +### Rerunning Failed Workflows + +PR authors can rerun failed GitHub Actions workflows by commenting `/rerun` on the pull request. This will automatically rerun all failed workflow runs for the PR's latest commit. + +Example rerun comment: + +``` +/rerun +``` + ## How to contribute ### Before you start @@ -144,7 +154,7 @@ Comment on the issue that you want to work on so we can assign it to you and clarify anything related to it. If you would like to work on something that is not listed as an issue -(e.g. a new feature or enhancement) please first read our [vision](docs/vision.md) +(e.g. a new feature or enhancement) please first read our [vision](docs/vision.md) to make sure your proposal aligns with the goals of the Collector, then create an issue and describe your proposal. It is best to do this in advance so that maintainers can decide if the proposal is a good fit for @@ -192,7 +202,7 @@ section of the general project contributing guide. Working with the project sources requires the following tools: 1. [git](https://git-scm.com/) -2. [go](https://golang.org/) (version 1.24 and up) +2. [go](https://golang.org/) (version 1.25 and up) 3. [make](https://www.gnu.org/software/make/) 4. [docker](https://www.docker.com/) @@ -217,6 +227,8 @@ Run tests, fmt, and lint: $ make ``` +You can run `make markdownlint` to check Markdown formatting. + ## Creating a PR Checkout a new branch, make modifications, build locally, and push the branch to your fork @@ -249,7 +261,7 @@ before merging (but see the above paragraph about writing good commit messages i ## General Notes -This project uses Go 1.24.* and [Github Actions.](https://github.com/features/actions) +This project uses Go 1.25.* and [Github Actions.](https://github.com/features/actions) It is recommended to run `make gofmt all` before submitting your PR. @@ -320,7 +332,7 @@ locally. Ensure that you execute these commands from the root of the repository: The actual name of the binary will depend on your platform, adjust accordingly (e.g., `./bin/otelcorecol_darwin_arm64`). - + Replace `otel-config.yaml` with the appropriate configuration file as needed. 3. Verify that your changes are reflected in the Collector's behavior by testing @@ -415,10 +427,10 @@ running the default common target for each module as well as additional repo-lev When a new OTLP version is published, the following steps are required to update this code base: 1. Edit the top-level Makefile's `OPENTELEMETRY_PROTO_VERSION` variable -2. Run `make genproto` +2. Run `make genproto` 3. Inspect modifications to the generated code in `pdata/internal/data/protogen` 4. When new fields are added in the protocol, make corresponding changes in `pdata/internal/cmd/pdatagen/internal` -5. Run `make genpdata` +5. Run `make genpdata` 6. Inspect modifications to the generated code in `pdata/*` 7. Run `make genproto-cleanup`, to remove temporary files 8. Update the supported OTLP version in [README.md](./README.md). diff --git a/Makefile b/Makefile index 180ea642ae38..4fd66d73270a 100644 --- a/Makefile +++ b/Makefile @@ -12,11 +12,15 @@ ALL_SRC := $(shell find . -name '*.go' \ ALL_DOC := $(shell find . \( -name "*.md" -o -name "*.yaml" \) \ -type f | sort) +# All Markdown files. Used in markdownlint. +ALL_MD := $(shell find . -name "*.md" -type f | sort) + # ALL_MODULES includes ./* dirs (excludes . dir) ALL_MODULES := $(shell find . -mindepth 2 \ -type f \ -name "go.mod" \ -not -path "./internal/tools/*" \ + -not -path "./cmd/builder/internal/tmp/init/*" \ -exec dirname {} \; | sort ) CMD?= @@ -37,7 +41,7 @@ endef .DEFAULT_GOAL := all .PHONY: all -all: checklicense checkdoc misspell goimpi goporto multimod-verify golint gotest +all: checklicense checkdoc misspell markdownlint goimpi goporto multimod-verify golint gotest all-modules: @echo $(ALL_MODULES) | tr ' ' '\n' | sort @@ -82,6 +86,10 @@ for-all: golint: @$(MAKE) for-all-target TARGET="lint" +.PHONY: gomodernize +gomodernize: + @$(MAKE) for-all-target TARGET="modernize" + .PHONY: goimpi goimpi: @$(MAKE) for-all-target TARGET="impi" @@ -130,6 +138,10 @@ checklicense: misspell: $(GO_TOOL) misspell -error $(ALL_DOC) +.PHONY: markdownlint +markdownlint: + npx -y markdownlint-cli@0.48.0 -c .markdownlint.yaml --ignore-path .markdownlintignore -- $(ALL_MD) + .PHONY: misspell-correction misspell-correction: $(GO_TOOL) misspell -w $(ALL_DOC) @@ -180,6 +192,7 @@ ocb: genpdata: cd internal/cmd/pdatagen && $(GOCMD) run main.go -C $(SRC_ROOT) $(MAKE) -C pdata fmt + cd pdata && $(GO_TOOL) betteralign --generated_files --apply ./... || true DOCKERCMD ?= docker DOCKER_PROTOBUF ?= otel/build-protobuf:0.23.0 @@ -224,7 +237,6 @@ check-contrib: .PHONY: generate-contrib generate-contrib: @echo -e "\nGenerating files in contrib" - $(MAKE) -C $(CONTRIB_PATH) -B install-tools $(MAKE) -C $(CONTRIB_PATH) generate GROUP=all # Restores contrib to its original state after running check-contrib. diff --git a/Makefile.Common b/Makefile.Common index 9860da5f1b4b..2f1a1c167ff1 100644 --- a/Makefile.Common +++ b/Makefile.Common @@ -25,6 +25,10 @@ JUNIT_OUT_DIR ?= $(TOOLS_MOD_DIR)/testresults .PHONY: test test: + # GODEBUG=fips140=only is used to surface any FIPS-140-3 non-compliant cryptographic + # calls into the Go standard library. See: https://go.dev/doc/security/fips140#fips-140-3-mode + # disabling fips only to unblock CI. See https://github.com/open-telemetry/opentelemetry-collector/issues/13925 + # GODEBUG=fips140=only $(GO_TOOL) gotestsum --packages="./..." -- $(GOTEST_OPT) $(GO_TOOL) gotestsum --packages="./..." -- $(GOTEST_OPT) .PHONY: test-with-cover @@ -50,21 +54,17 @@ benchmark: .PHONY: fmt fmt: common/gofmt common/goimports common/gofumpt -# `modernize' cannot be installed as a Go tool via `go get -tool'. -# -# See [1] for more details. -# -# [1]: https://github.com/golang/go/issues/73279 .PHONY: modernize modernize: - $(GOCMD) run \ - golang.org/x/tools/gopls/internal/analysis/modernize/cmd/modernize@latest \ - -fix -test -v ./... + $(GO_TOOL) modernize \ + -fix -test -v -any -fmtappendf -forvar -mapsloop -minmax -newexpr -omitzero -plusbuild \ + -rangeint -reflecttypefor -slicescontains -slicessort -stditerators -stringscut \ + -stringscutprefix -stringsseq -stringsbuilder -testingcontext -unsafefuncs -waitgroup ./... .PHONY: tidy tidy: rm -fr go.sum - $(GOCMD) mod tidy -compat=1.24.0 + $(GOCMD) mod tidy -compat=1.25.0 .PHONY: lint lint: diff --git a/README.md b/README.md index 2b84d80af249..0252a59d8e64 100644 --- a/README.md +++ b/README.md @@ -184,11 +184,12 @@ For more information about the maintainer role, see the [community repository](h For more information about the approver role, see the [community repository](https://github.com/open-telemetry/community/blob/main/guides/contributor/membership.md#approver). In addition to what is described at the organization-level, the SIG Collector requires all core approvers to take part in rotating -the role of the [release manager](./docs/release.md#release-manager). +the role of the [release manager](./docs/release.md#release-managers). ### Triagers - [Andrzej Stencel](https://github.com/andrzej-stencel), Elastic +- [Arthur Silva Sens](https://github.com/ArthurSens), Grafana Labs - [Chao Weng](https://github.com/sincejune), AppDynamics - [Vihas Makwana](https://github.com/VihasMakwana), Elastic - Actively seeking contributors to triage issues diff --git a/client/go.mod b/client/go.mod index d2512bb7dfe9..d24794c7e633 100644 --- a/client/go.mod +++ b/client/go.mod @@ -1,22 +1,22 @@ module go.opentelemetry.io/collector/client -go 1.24.0 +go 1.25.0 require ( github.com/stretchr/testify v1.11.1 - go.opentelemetry.io/collector/consumer v1.46.0 - go.opentelemetry.io/collector/pdata v1.46.0 + go.opentelemetry.io/collector/consumer v1.54.0 + go.opentelemetry.io/collector/pdata v1.54.0 go.uber.org/goleak v1.3.0 ) require ( github.com/davecgh/go-spew v1.1.1 // indirect - github.com/hashicorp/go-version v1.7.0 // indirect + github.com/hashicorp/go-version v1.8.0 // indirect github.com/json-iterator/go v1.1.12 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee // indirect github.com/pmezard/go-difflib v1.0.0 // indirect - go.opentelemetry.io/collector/featuregate v1.46.0 // indirect + go.opentelemetry.io/collector/featuregate v1.54.0 // indirect go.uber.org/multierr v1.11.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/client/go.sum b/client/go.sum index 903bf673575c..002e4ea530db 100644 --- a/client/go.sum +++ b/client/go.sum @@ -2,8 +2,8 @@ github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= -github.com/hashicorp/go-version v1.7.0 h1:5tqGy27NaOTB8yJKUZELlFAS/LTKJkrmONwQKeRZfjY= -github.com/hashicorp/go-version v1.7.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= +github.com/hashicorp/go-version v1.8.0 h1:KAkNb1HAiZd1ukkxDFGmokVZe1Xy9HG6NUp+bPle2i4= +github.com/hashicorp/go-version v1.8.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= @@ -24,18 +24,18 @@ github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+ github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U= github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= -go.opentelemetry.io/proto/slim/otlp v1.9.0 h1:fPVMv8tP3TrsqlkH1HWYUpbCY9cAIemx184VGkS6vlE= -go.opentelemetry.io/proto/slim/otlp v1.9.0/go.mod h1:xXdeJJ90Gqyll+orzUkY4bOd2HECo5JofeoLpymVqdI= -go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.2.0 h1:o13nadWDNkH/quoDomDUClnQBpdQQ2Qqv0lQBjIXjE8= -go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.2.0/go.mod h1:Gyb6Xe7FTi/6xBHwMmngGoHqL0w29Y4eW8TGFzpefGA= -go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.2.0 h1:EiUYvtwu6PMrMHVjcPfnsG3v+ajPkbUeH+IL93+QYyk= -go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.2.0/go.mod h1:mUUHKFiN2SST3AhJ8XhJxEoeVW12oqfXog0Bo8W3Ec4= +go.opentelemetry.io/proto/slim/otlp v1.10.0 h1:iR97Vs/ZDR+y9TfuP9b1XBtdPWeC+OMslIBmhcLU7jM= +go.opentelemetry.io/proto/slim/otlp v1.10.0/go.mod h1:lV9250stpjYLPNA5viFabIgP2QlUGRT1GdTgAf8SIUk= +go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.3.0 h1:RUF5rO0hAlgiJt1fzQVzcVs3vZVNHIcMLgOgG4rWNcQ= +go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.3.0/go.mod h1:I89cynRj8y+383o7tEQVg2SVA6SRgDVIouWPUVXjx0U= +go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.3.0 h1:CQvJSldHRUN6Z8jsUeYv8J0lXRvygALXIzsmAeCcZE0= +go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.3.0/go.mod h1:xSQ+mEfJe/GjK1LXEyVOoSI1N9JV9ZI923X5kup43W4= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= -google.golang.org/protobuf v1.36.10 h1:AYd7cD/uASjIL6Q9LiTjz8JLcrh/88q5UObnmY3aOOE= -google.golang.org/protobuf v1.36.10/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= +google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE= +google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= diff --git a/client/metadata.yaml b/client/metadata.yaml new file mode 100644 index 000000000000..1d24c67352fb --- /dev/null +++ b/client/metadata.yaml @@ -0,0 +1,6 @@ +type: client +github_project: open-telemetry/opentelemetry-collector + +status: + disable_codecov_badge: true + class: pkg diff --git a/cmd/builder/README.md b/cmd/builder/README.md index f91e2d546423..55279bf5e03f 100644 --- a/cmd/builder/README.md +++ b/cmd/builder/README.md @@ -141,7 +141,9 @@ The configuration file is composed of two main parts: `dist` and module types. A ocb --config=config.yaml ``` -The module types are specified at the top-level, and might be: `extensions`, `exporters`, `receivers` and `processors`. They all accept a list of components, and each component is required to have at least the `gomod` entry. When not specified, the `import` value is inferred from the `gomod`. When not specified, the `name` is inferred from the `import`. +The module types are specified at the top-level. Available options are `extensions`, `exporters`, `receivers`, `processors`, `providers`, and `converters`. They all accept a list of components, and each component is required to have at least the `gomod` entry. The telemetry provider for the Collector binary can also be specified through the `telemetry` key, which can be set to a single module, also requiring a `gomod` entry at a minimum. + +When not specified, the `import` value is inferred from the `gomod`. When not specified, the `name` is inferred from the `import`. The `import` might specify a more specific path than what is specified in the `gomod`. For instance, your Go module might be `gitlab.com/myorg/myrepo` and the `import` might be `gitlab.com/myorg/myrepo/myexporter`. @@ -159,10 +161,13 @@ dist: go: "/usr/bin/go" # which Go binary to use to compile the generated sources. Optional. debug_compilation: false # enabling this causes the builder to keep the debug symbols in the resulting binary. Optional. exporters: - - gomod: "github.com/open-telemetry/opentelemetry-collector-contrib/exporter/alibabacloudlogserviceexporter v0.129.0" # the Go module for the component. Required. + - gomod: "github.com/open-telemetry/opentelemetry-collector-contrib/exporter/alibabacloudlogserviceexporter v0.146.0" # the Go module for the component. Required. import: "github.com/open-telemetry/opentelemetry-collector-contrib/exporter/alibabacloudlogserviceexporter" # the import path for the component. Optional. name: "alibabacloudlogserviceexporter" # package name to use in the generated sources. Optional. path: "./alibabacloudlogserviceexporter" # in case a local version should be used for the module, the path relative to the current dir, or a full path can be specified. Optional. +telemetry: + gomod: go.opentelemetry.io/collector/service v0.146.0 + import: go.opentelemetry.io/collector/service/telemetry/otelconftelemetry replaces: # a list of "replaces" directives that will be part of the resulting go.mod - github.com/open-telemetry/opentelemetry-collector-contrib/internal/common => github.com/open-telemetry/opentelemetry-collector-contrib/internal/common v0.128.0 diff --git a/cmd/builder/go.mod b/cmd/builder/go.mod index 2a78ecff2715..65f4b1ce2198 100644 --- a/cmd/builder/go.mod +++ b/cmd/builder/go.mod @@ -3,21 +3,21 @@ module go.opentelemetry.io/collector/cmd/builder -go 1.24.0 +go 1.25.0 require ( github.com/knadh/koanf/parsers/yaml v1.1.0 github.com/knadh/koanf/providers/env/v2 v2.0.0 - github.com/knadh/koanf/providers/file v1.2.0 + github.com/knadh/koanf/providers/file v1.2.1 github.com/knadh/koanf/providers/fs v1.0.0 - github.com/knadh/koanf/v2 v2.3.0 - github.com/spf13/cobra v1.10.1 + github.com/knadh/koanf/v2 v2.3.3 + github.com/spf13/cobra v1.10.2 github.com/spf13/pflag v1.0.10 github.com/stretchr/testify v1.11.1 go.uber.org/goleak v1.3.0 go.uber.org/multierr v1.11.0 go.uber.org/zap v1.27.1 - golang.org/x/mod v0.28.0 + golang.org/x/mod v0.33.0 ) require ( @@ -32,7 +32,7 @@ require ( github.com/pmezard/go-difflib v1.0.0 // indirect github.com/rogpeppe/go-internal v1.10.0 // indirect go.yaml.in/yaml/v3 v3.0.4 // indirect - golang.org/x/sys v0.36.0 // indirect + golang.org/x/sys v0.41.0 // indirect gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/cmd/builder/go.sum b/cmd/builder/go.sum index dd836363f69c..01e7c10c0725 100644 --- a/cmd/builder/go.sum +++ b/cmd/builder/go.sum @@ -14,12 +14,12 @@ github.com/knadh/koanf/parsers/yaml v1.1.0 h1:3ltfm9ljprAHt4jxgeYLlFPmUaunuCgu1y github.com/knadh/koanf/parsers/yaml v1.1.0/go.mod h1:HHmcHXUrp9cOPcuC+2wrr44GTUB0EC+PyfN3HZD9tFg= github.com/knadh/koanf/providers/env/v2 v2.0.0 h1:Ad5H3eun722u+FvchiIcEIJZsZ2M6oxCkgZfWN5B5KY= github.com/knadh/koanf/providers/env/v2 v2.0.0/go.mod h1:1g01PE+Ve1gBfWNNw2wmULRP0tc8RJrjn5p2N/jNCIc= -github.com/knadh/koanf/providers/file v1.2.0 h1:hrUJ6Y9YOA49aNu/RSYzOTFlqzXSCpmYIDXI7OJU6+U= -github.com/knadh/koanf/providers/file v1.2.0/go.mod h1:bp1PM5f83Q+TOUu10J/0ApLBd9uIzg+n9UgthfY+nRA= +github.com/knadh/koanf/providers/file v1.2.1 h1:bEWbtQwYrA+W2DtdBrQWyXqJaJSG3KrP3AESOJYp9wM= +github.com/knadh/koanf/providers/file v1.2.1/go.mod h1:bp1PM5f83Q+TOUu10J/0ApLBd9uIzg+n9UgthfY+nRA= github.com/knadh/koanf/providers/fs v1.0.0 h1:tvn4MrduLgdOSUqqEHULUuIcELXf6xDOpH8GUErpYaY= github.com/knadh/koanf/providers/fs v1.0.0/go.mod h1:FksHET+xXFNDozvj8ZCdom54OnZ6eGKJtC5FhZJKx/8= -github.com/knadh/koanf/v2 v2.3.0 h1:Qg076dDRFHvqnKG97ZEsi9TAg2/nFTa9hCdcSa1lvlM= -github.com/knadh/koanf/v2 v2.3.0/go.mod h1:gRb40VRAbd4iJMYYD5IxZ6hfuopFcXBpc9bbQpZwo28= +github.com/knadh/koanf/v2 v2.3.3 h1:jLJC8XCRfLC7n4F+ZKKdBsbq1bfXTpuFhf4L7t94D94= +github.com/knadh/koanf/v2 v2.3.3/go.mod h1:gRb40VRAbd4iJMYYD5IxZ6hfuopFcXBpc9bbQpZwo28= github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= @@ -38,8 +38,8 @@ github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/f github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ= github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= -github.com/spf13/cobra v1.10.1 h1:lJeBwCfmrnXthfAupyUTzJ/J4Nc1RsHC/mSRU2dll/s= -github.com/spf13/cobra v1.10.1/go.mod h1:7SmJGaTHFVBY0jW4NXGluQoLvhqFQM+6XSKD+P4XaB0= +github.com/spf13/cobra v1.10.2 h1:DMTTonx5m65Ic0GOoRY2c16WCbHxOOw6xxezuLaBpcU= +github.com/spf13/cobra v1.10.2/go.mod h1:7C1pvHqHw5A4vrJfjNwvOdzYu0Gml16OCs2GRiTUUS4= github.com/spf13/pflag v1.0.9/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/spf13/pflag v1.0.10 h1:4EBh2KAYBwaONj6b2Ye1GiHfwjqyROoF4RwYO+vPwFk= github.com/spf13/pflag v1.0.10/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= @@ -53,10 +53,10 @@ go.uber.org/zap v1.27.1 h1:08RqriUEv8+ArZRYSTXy1LeBScaMpVSTBhCeaZYfMYc= go.uber.org/zap v1.27.1/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc= go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg= -golang.org/x/mod v0.28.0 h1:gQBtGhjxykdjY9YhZpSlZIsbnaE2+PgjfLWUQTnoZ1U= -golang.org/x/mod v0.28.0/go.mod h1:yfB/L0NOf/kmEbXjzCPOx1iK1fRutOydrCMsqRhEBxI= -golang.org/x/sys v0.36.0 h1:KVRy2GtZBrk1cBYA7MKu5bEZFxQk4NIDV6RLVcC8o0k= -golang.org/x/sys v0.36.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= +golang.org/x/mod v0.33.0 h1:tHFzIWbBifEmbwtGz65eaWyGiGZatSrT9prnU8DbVL8= +golang.org/x/mod v0.33.0/go.mod h1:swjeQEj+6r7fODbD2cqrnje9PnziFuw4bmLbBZFrQ5w= +golang.org/x/sys v0.41.0 h1:Ivj+2Cp/ylzLiEU89QhWblYnOE9zerudt9Ftecq2C6k= +golang.org/x/sys v0.41.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= diff --git a/cmd/builder/internal/.gitignore b/cmd/builder/internal/.gitignore new file mode 100644 index 000000000000..3a04a58b4dfb --- /dev/null +++ b/cmd/builder/internal/.gitignore @@ -0,0 +1,2 @@ +# tmp folder used by tests +tmp/ diff --git a/cmd/builder/internal/builder/config.go b/cmd/builder/internal/builder/config.go index 6fe8201f0bd0..e8bf79a95437 100644 --- a/cmd/builder/internal/builder/config.go +++ b/cmd/builder/internal/builder/config.go @@ -18,8 +18,8 @@ import ( ) const ( - defaultBetaOtelColVersion = "v0.140.0" - defaultStableOtelColVersion = "v1.46.0" + DefaultBetaOtelColVersion = "v0.148.0" + DefaultStableOtelColVersion = "v1.54.0" ) // errMissingGoMod indicates an empty gomod field @@ -46,6 +46,7 @@ type Config struct { Receivers []Module `mapstructure:"receivers"` Processors []Module `mapstructure:"processors"` Connectors []Module `mapstructure:"connectors"` + Telemetry Module `mapstructure:"telemetry"` ConfmapProviders []Module `mapstructure:"providers"` ConfmapConverters []Module `mapstructure:"converters"` Replaces []string `mapstructure:"replaces"` @@ -102,7 +103,7 @@ func NewDefaultConfig() (*Config, error) { } return &Config{ - OtelColVersion: defaultBetaOtelColVersion, + OtelColVersion: DefaultBetaOtelColVersion, Logger: log, Distribution: Distribution{ OutputPath: outputDir, @@ -116,19 +117,19 @@ func NewDefaultConfig() (*Config, error) { }, ConfmapProviders: []Module{ { - GoMod: "go.opentelemetry.io/collector/confmap/provider/envprovider " + defaultStableOtelColVersion, + GoMod: "go.opentelemetry.io/collector/confmap/provider/envprovider " + DefaultStableOtelColVersion, }, { - GoMod: "go.opentelemetry.io/collector/confmap/provider/fileprovider " + defaultStableOtelColVersion, + GoMod: "go.opentelemetry.io/collector/confmap/provider/fileprovider " + DefaultStableOtelColVersion, }, { - GoMod: "go.opentelemetry.io/collector/confmap/provider/httpprovider " + defaultStableOtelColVersion, + GoMod: "go.opentelemetry.io/collector/confmap/provider/httpprovider " + DefaultStableOtelColVersion, }, { - GoMod: "go.opentelemetry.io/collector/confmap/provider/httpsprovider " + defaultStableOtelColVersion, + GoMod: "go.opentelemetry.io/collector/confmap/provider/httpsprovider " + DefaultStableOtelColVersion, }, { - GoMod: "go.opentelemetry.io/collector/confmap/provider/yamlprovider " + defaultStableOtelColVersion, + GoMod: "go.opentelemetry.io/collector/confmap/provider/yamlprovider " + DefaultStableOtelColVersion, }, }, }, nil @@ -144,6 +145,7 @@ func (c *Config) Validate() error { validateModules("connector", c.Connectors), validateModules("provider", c.ConfmapProviders), validateModules("converter", c.ConfmapConverters), + validateTelemetry(c), ) } @@ -193,6 +195,12 @@ func (c *Config) ParseModules() error { return err } + telemetry, err := parseModules([]Module{c.Telemetry}, usedNames) + if err != nil { + return err + } + c.Telemetry = telemetry[0] + c.ConfmapProviders, err = parseModules(c.ConfmapProviders, usedNames) if err != nil { return err @@ -205,7 +213,7 @@ func (c *Config) ParseModules() error { } func (c *Config) allComponents() []Module { - return slices.Concat[[]Module](c.Exporters, c.Receivers, c.Processors, c.Extensions, c.Connectors, c.ConfmapProviders, c.ConfmapConverters) + return slices.Concat(c.Exporters, c.Receivers, c.Processors, c.Extensions, c.Connectors, []Module{c.Telemetry}, c.ConfmapProviders, c.ConfmapConverters) } func validateModules(name string, mods []Module) error { @@ -217,6 +225,25 @@ func validateModules(name string, mods []Module) error { return nil } +// validateTelemetry ensures there is a valid telemetry module specified. +// If the field is not set, it is defaulted to otelconftelemetry. +func validateTelemetry(c *Config) error { + // We cannot set this in createDefaultConfig, since koanf merges maps and we + // would get a blend of this value and user-provided values. Once + // otelconftelemetry is its own module (that is, the `Import` field is not + // set), we can likely move the default to createDefaultConfig. + if c.Telemetry.Name == "" && c.Telemetry.Import == "" && c.Telemetry.GoMod == "" && c.Telemetry.Path == "" { + c.Telemetry = Module{ + GoMod: "go.opentelemetry.io/collector/service " + DefaultBetaOtelColVersion, + Import: "go.opentelemetry.io/collector/service/telemetry/otelconftelemetry", + } + } else if c.Telemetry.GoMod == "" { + return fmt.Errorf("telemetry module: %w", errMissingGoMod) + } + + return nil +} + func parseModules(mods []Module, usedNames map[string]int) ([]Module, error) { var parsedModules []Module for _, mod := range mods { diff --git a/cmd/builder/internal/builder/config_test.go b/cmd/builder/internal/builder/config_test.go index 14ca9bbe5527..116ae9f102d7 100644 --- a/cmd/builder/internal/builder/config_test.go +++ b/cmd/builder/internal/builder/config_test.go @@ -70,6 +70,9 @@ func TestAliases(t *testing.T) { GoMod: "github.com/another3/module v0.1.2", }, }, + Telemetry: Module{ + GoMod: "github.com/another3/module v0.1.2", + }, } // test @@ -128,6 +131,10 @@ func TestAliases(t *testing.T) { assert.Equal(t, "github.com/another3/module v0.1.2", cfg.Connectors[2].GoMod) assert.Equal(t, "github.com/another3/module", cfg.Connectors[2].Import) assert.Equal(t, "module5", cfg.Connectors[2].Name) + + assert.Equal(t, "github.com/another3/module v0.1.2", cfg.Telemetry.GoMod) + assert.Equal(t, "github.com/another3/module", cfg.Telemetry.Import) + assert.Equal(t, "module6", cfg.Telemetry.Name) } func TestParseModules(t *testing.T) { @@ -275,6 +282,15 @@ func TestMissingModule(t *testing.T) { }, err: errMissingGoMod, }, + { + cfg: Config{ + Logger: zap.NewNop(), + Telemetry: Module{ + Import: "go.opentelemetry.io/collector/service/telemetry/otelconftelemetry", + }, + }, + err: errMissingGoMod, + }, } for _, test := range configurations { @@ -285,10 +301,11 @@ func TestMissingModule(t *testing.T) { func TestNewDefaultConfig(t *testing.T) { cfg, err := NewDefaultConfig() require.NoError(t, err) - require.NoError(t, cfg.ParseModules()) - assert.NoError(t, cfg.Validate()) - assert.NoError(t, cfg.SetGoPath()) + assert.Empty(t, cfg.Telemetry.GoMod) require.NoError(t, cfg.Validate()) + require.NoError(t, cfg.SetGoPath()) + require.NoError(t, cfg.ParseModules()) + assert.NotEmpty(t, cfg.Telemetry.GoMod) assert.False(t, cfg.Distribution.DebugCompilation) assert.Empty(t, cfg.Distribution.BuildTags) assert.False(t, cfg.LDSet) @@ -305,9 +322,9 @@ func TestNewBuiltinConfig(t *testing.T) { cfg := Config{Logger: zaptest.NewLogger(t)} require.NoError(t, k.UnmarshalWithConf("", &cfg, koanf.UnmarshalConf{Tag: "mapstructure"})) - assert.NoError(t, cfg.ParseModules()) - assert.NoError(t, cfg.Validate()) - assert.NoError(t, cfg.SetGoPath()) + require.NoError(t, cfg.Validate()) + require.NoError(t, cfg.SetGoPath()) + require.NoError(t, cfg.ParseModules()) // Unlike the config initialized in NewDefaultConfig(), we expect // the builtin default to be practically useful, so there must be diff --git a/cmd/builder/internal/builder/main.go b/cmd/builder/internal/builder/main.go index 3601deba02cc..47f180c815b1 100644 --- a/cmd/builder/internal/builder/main.go +++ b/cmd/builder/internal/builder/main.go @@ -10,6 +10,7 @@ import ( "os" "os/exec" "path/filepath" + "runtime" "strings" "text/template" "time" @@ -115,11 +116,11 @@ func Compile(cfg *Config) error { } cfg.Logger.Info("Compiling") - ldflags := "-s -w" // we strip the symbols by default for smaller binaries gcflags := "" + binaryName := outputBinaryName(cfg.Distribution.Name) - args := []string{"build", "-trimpath", "-o", cfg.Distribution.Name} + args := []string{"build", "-trimpath", "-o", binaryName} if cfg.Distribution.DebugCompilation { cfg.Logger.Info("Debug compilation is enabled, the debug symbols will be left on the resulting binary") ldflags = cfg.LDFlags @@ -146,11 +147,26 @@ func Compile(cfg *Config) error { if _, err := runGoCommand(cfg, args...); err != nil { return fmt.Errorf("%w: %s", errCompileFailed, err.Error()) } - cfg.Logger.Info("Compiled", zap.String("binary", fmt.Sprintf("%s/%s", cfg.Distribution.OutputPath, cfg.Distribution.Name))) + cfg.Logger.Info("Compiled", zap.String("binary", fmt.Sprintf("%s/%s", cfg.Distribution.OutputPath, binaryName))) return nil } +func outputBinaryName(name string) string { + goos, ok := os.LookupEnv("GOOS") + if !ok || goos == "" { + goos = runtime.GOOS + } + + if !strings.EqualFold(goos, "windows") { + return name + } + if strings.EqualFold(filepath.Ext(name), ".exe") { + return name + } + return name + ".exe" +} + // GetModules retrieves the go modules, updating go.mod and go.sum in the process func GetModules(cfg *Config) error { if cfg.SkipGetModules { @@ -158,7 +174,7 @@ func GetModules(cfg *Config) error { return nil } - if _, err := runGoCommand(cfg, "mod", "tidy", "-compat=1.24"); err != nil { + if _, err := runGoCommand(cfg, "mod", "tidy", "-compat=1.25"); err != nil { return fmt.Errorf("failed to update go.mod: %w", err) } @@ -174,7 +190,7 @@ func GetModules(cfg *Config) error { } coreDepVersion, ok := dependencyVersions[otelcolPath] - betaVersion := semver.MajorMinor(defaultBetaOtelColVersion) + betaVersion := semver.MajorMinor(DefaultBetaOtelColVersion) if !ok { return fmt.Errorf("core collector %w: '%s'. %s", ErrDepNotFound, otelcolPath, skipStrictMsg) } diff --git a/cmd/builder/internal/builder/main_test.go b/cmd/builder/internal/builder/main_test.go index f6660b4795e4..25ec82c22d03 100644 --- a/cmd/builder/internal/builder/main_test.go +++ b/cmd/builder/internal/builder/main_test.go @@ -88,6 +88,7 @@ var replaceModules = []string{ "/extension/zpagesextension", "/extension/xextension", "/featuregate", + "/internal/componentalias", "/internal/memorylimiter", "/internal/fanoutconsumer", "/internal/sharedcomponent", @@ -147,6 +148,31 @@ func TestGenerateInvalidOutputPath(t *testing.T) { require.ErrorContains(t, err, "failed to create output path") } +func TestOutputBinaryName(t *testing.T) { + for _, tt := range []struct { + name string + goos string + want string + }{ + { + name: "on windows", + goos: "windows", + want: "otelcorecol.exe", + }, + { + name: "on other OSes", + goos: "linux", + want: "otelcorecol", + }, + } { + t.Run(tt.name, func(t *testing.T) { + t.Setenv("GOOS", tt.goos) + assert.Equal(t, tt.want, outputBinaryName("otelcorecol")) + assert.Equal(t, "otelcorecol.exe", outputBinaryName("otelcorecol.exe")) + }) + } +} + func TestVersioning(t *testing.T) { replaces := generateReplaces() tests := []struct { @@ -446,8 +472,7 @@ func TestReplaceStatementsAreComplete(t *testing.T) { func verifyGoMod(t *testing.T, dir string, replaceMods map[string]bool) { gomodpath := path.Join(dir, "go.mod") - //nolint:gosec // #nosec G304 We control this path and generate the file inside, so we can assume it is safe. - gomod, err := os.ReadFile(gomodpath) + gomod, err := os.ReadFile(filepath.Clean(gomodpath)) require.NoError(t, err) mod, err := modfile.Parse(gomodpath, gomod, nil) diff --git a/cmd/builder/internal/builder/templates/components.go.tmpl b/cmd/builder/internal/builder/templates/components.go.tmpl index d9722a9cb5d6..0348d8e5e297 100644 --- a/cmd/builder/internal/builder/templates/components.go.tmpl +++ b/cmd/builder/internal/builder/templates/components.go.tmpl @@ -10,7 +10,7 @@ import ( "go.opentelemetry.io/collector/otelcol" "go.opentelemetry.io/collector/processor" "go.opentelemetry.io/collector/receiver" - "go.opentelemetry.io/collector/service/telemetry/otelconftelemetry" + {{.Telemetry.Name}} "{{.Telemetry.Import}}" {{- range .Connectors}} {{.Name}} "{{.Import}}" {{- end}} @@ -28,10 +28,24 @@ import ( {{- end}} ) +type aliasProvider interface{ DeprecatedAlias() component.Type } + +func makeModulesMap[T component.Factory](factories map[component.Type]T, modules map[component.Type]string) map[component.Type]string { + for compType, factory := range factories { + if ap, ok := any(factory).(aliasProvider); ok { + alias := ap.DeprecatedAlias() + if alias.String() != "" { + modules[alias] = modules[compType] + } + } + } + return modules +} + func components() (otelcol.Factories, error) { var err error factories := otelcol.Factories{ - Telemetry: otelconftelemetry.NewFactory(), + Telemetry: {{.Telemetry.Name}}.NewFactory(), } factories.Extensions, err = otelcol.MakeFactoryMap[extension.Factory]( @@ -42,10 +56,11 @@ func components() (otelcol.Factories, error) { if err != nil { return otelcol.Factories{}, err } - factories.ExtensionModules = make(map[component.Type]string, len(factories.Extensions)) - {{- range .Extensions}} - factories.ExtensionModules[{{.Name}}.NewFactory().Type()] = "{{.GoMod}}" - {{- end}} + factories.ExtensionModules = makeModulesMap(factories.Extensions, map[component.Type]string{ + {{- range .Extensions}} + {{.Name}}.NewFactory().Type(): "{{.GoMod}}", + {{- end}} + }) factories.Receivers, err = otelcol.MakeFactoryMap[receiver.Factory]( {{- range .Receivers}} @@ -55,10 +70,11 @@ func components() (otelcol.Factories, error) { if err != nil { return otelcol.Factories{}, err } - factories.ReceiverModules = make(map[component.Type]string, len(factories.Receivers)) - {{- range .Receivers}} - factories.ReceiverModules[{{.Name}}.NewFactory().Type()] = "{{.GoMod}}" - {{- end}} + factories.ReceiverModules = makeModulesMap(factories.Receivers, map[component.Type]string{ + {{- range .Receivers}} + {{.Name}}.NewFactory().Type(): "{{.GoMod}}", + {{- end}} + }) factories.Exporters, err = otelcol.MakeFactoryMap[exporter.Factory]( {{- range .Exporters}} @@ -68,10 +84,11 @@ func components() (otelcol.Factories, error) { if err != nil { return otelcol.Factories{}, err } - factories.ExporterModules = make(map[component.Type]string, len(factories.Exporters)) - {{- range .Exporters}} - factories.ExporterModules[{{.Name}}.NewFactory().Type()] = "{{.GoMod}}" - {{- end}} + factories.ExporterModules = makeModulesMap(factories.Exporters, map[component.Type]string{ + {{- range .Exporters}} + {{.Name}}.NewFactory().Type(): "{{.GoMod}}", + {{- end}} + }) factories.Processors, err = otelcol.MakeFactoryMap[processor.Factory]( {{- range .Processors}} @@ -81,10 +98,11 @@ func components() (otelcol.Factories, error) { if err != nil { return otelcol.Factories{}, err } - factories.ProcessorModules = make(map[component.Type]string, len(factories.Processors)) - {{- range .Processors}} - factories.ProcessorModules[{{.Name}}.NewFactory().Type()] = "{{.GoMod}}" - {{- end}} + factories.ProcessorModules = makeModulesMap(factories.Processors, map[component.Type]string{ + {{- range .Processors}} + {{.Name}}.NewFactory().Type(): "{{.GoMod}}", + {{- end}} + }) factories.Connectors, err = otelcol.MakeFactoryMap[connector.Factory]( {{- range .Connectors}} @@ -94,10 +112,11 @@ func components() (otelcol.Factories, error) { if err != nil { return otelcol.Factories{}, err } - factories.ConnectorModules = make(map[component.Type]string, len(factories.Connectors)) - {{- range .Connectors}} - factories.ConnectorModules[{{.Name}}.NewFactory().Type()] = "{{.GoMod}}" - {{- end}} + factories.ConnectorModules = makeModulesMap(factories.Connectors, map[component.Type]string{ + {{- range .Connectors}} + {{.Name}}.NewFactory().Type(): "{{.GoMod}}", + {{- end}} + }) return factories, nil } diff --git a/cmd/builder/internal/builder/templates/go.mod.tmpl b/cmd/builder/internal/builder/templates/go.mod.tmpl index 13ce9852a9a7..78894af80198 100644 --- a/cmd/builder/internal/builder/templates/go.mod.tmpl +++ b/cmd/builder/internal/builder/templates/go.mod.tmpl @@ -2,7 +2,7 @@ module {{.Distribution.Module}} -go 1.24 +go 1.25 require ( {{- range .ConfmapConverters}} @@ -26,6 +26,7 @@ require ( {{- range .Processors}} {{if .GoMod}}{{.GoMod}}{{end}} {{- end}} + {{if .Telemetry.GoMod}}{{.Telemetry.GoMod}}{{end}} go.opentelemetry.io/collector/otelcol {{.OtelColVersion}} ) @@ -55,6 +56,7 @@ require ( {{- range .Processors}} {{if ne .Path ""}}replace {{.GoMod}} => {{.Path}}{{end}} {{- end}} +{{if ne .Telemetry.Path ""}}replace {{.Telemetry.GoMod}} => {{.Telemetry.Path}}{{end}} {{- range .Replaces}} replace {{.}} {{- end}} diff --git a/cmd/builder/internal/builder/templates/main.go.tmpl b/cmd/builder/internal/builder/templates/main.go.tmpl index e3b1e8499f6f..37a0696cda1a 100644 --- a/cmd/builder/internal/builder/templates/main.go.tmpl +++ b/cmd/builder/internal/builder/templates/main.go.tmpl @@ -4,13 +4,14 @@ package main import ( - "log" + "fmt" + "os" "go.opentelemetry.io/collector/component" "go.opentelemetry.io/collector/confmap" {{- range .ConfmapConverters}} {{.Name}} "{{.Import}}" - {{- end}} + {{- end}} {{- range .ConfmapProviders}} {{.Name}} "{{.Import}}" {{- end}} @@ -50,7 +51,7 @@ func main() { {{- range .ConfmapProviders}} {{.Name}}.NewFactory().Create(confmap.ProviderSettings{}).Scheme(): "{{.GoMod}}", {{- end}} - }, + }, ConverterModules: []string{ {{- range .ConfmapConverters}} "{{.GoMod}}", @@ -59,14 +60,15 @@ func main() { } if err := run(set); err != nil { - log.Fatal(err) + _, _ = fmt.Fprintln(os.Stderr, err) + os.Exit(1) } } func runInteractive(params otelcol.CollectorSettings) error { cmd := otelcol.NewCommand(params) if err := cmd.Execute(); err != nil { - log.Fatalf("collector server run finished with error: %v", err) + return err } return nil diff --git a/cmd/builder/internal/command.go b/cmd/builder/internal/command.go index 520921229fb4..624a658192b9 100644 --- a/cmd/builder/internal/command.go +++ b/cmd/builder/internal/command.go @@ -34,9 +34,8 @@ const ( // Command is the main entrypoint for this application func Command() (*cobra.Command, error) { cmd := &cobra.Command{ - SilenceUsage: true, // Don't print usage on Run error. - SilenceErrors: true, // Don't print errors; main does it. - Use: "ocb", + SilenceUsage: true, // Don't print usage on Run error. + Use: "ocb", Long: fmt.Sprintf("OpenTelemetry Collector Builder (%s)", version) + ` ocb generates a custom OpenTelemetry Collector binary using the @@ -69,7 +68,7 @@ configuration is provided, ocb will generate a default Collector. return nil, err } - // version of this binary + cmd.AddCommand(initCommand()) cmd.AddCommand(versionCommand()) return cmd, nil diff --git a/cmd/builder/internal/command_init.go b/cmd/builder/internal/command_init.go new file mode 100644 index 000000000000..53471c94ad51 --- /dev/null +++ b/cmd/builder/internal/command_init.go @@ -0,0 +1,144 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +package internal // import "go.opentelemetry.io/collector/cmd/builder/internal" + +import ( + "bytes" + "embed" + "errors" + "fmt" + "os" + "os/exec" + "path" + "path/filepath" + "text/template" + + "github.com/spf13/cobra" + + "go.opentelemetry.io/collector/cmd/builder/internal/builder" +) + +const defaultDescription = "Custom OpenTelemetry Collector" + +//go:embed init/templates/*.tmpl +var templatesFS embed.FS + +type metadata struct { + Name string + Description string + StableVersion string + BetaVersion string +} + +func initCommand() *cobra.Command { + var outputPath string + + cmd := &cobra.Command{ + Use: "init", + Short: "[EXPERIMENTAL] Initializes a new custom collector repository in the provided folder", + Long: `ocb init initializes a new repository in the provided folder with a manifest to start building a custom Collector. This command is experimental and very likely to change.`, + Args: cobra.NoArgs, + RunE: func(_ *cobra.Command, _ []string) error { + return run(outputPath) + }, + } + + cmd.Flags().StringVar(&outputPath, "path", ".", "Output path where the collector repository will be initialized") + + return cmd +} + +func run(path string) error { + if path == "" { + return errors.New("argument must be a folder") + } + path, err := filepath.Abs(path) + if err != nil { + return fmt.Errorf("failed to get absolute path for %v: %w", path, err) + } + err = os.MkdirAll(path, 0o750) + if err != nil { + return fmt.Errorf("failed creating folder %v: %w", path, err) + } + + meta := metadata{ + Name: filepath.Base(path), + Description: defaultDescription, + StableVersion: builder.DefaultStableOtelColVersion, + BetaVersion: builder.DefaultBetaOtelColVersion, + } + + err = writeTemplate(path, "manifest.yaml", meta) + if err != nil { + return fmt.Errorf("failed writing manifest: %w", err) + } + + err = writeTemplate(path, ".gitignore", meta) + if err != nil { + return fmt.Errorf("failed writing gitignore: %w", err) + } + + err = writeTemplate(path, "README.md", meta) + if err != nil { + return fmt.Errorf("failed writing README: %w", err) + } + + err = writeTemplate(path, "go.mod", meta) + if err != nil { + return fmt.Errorf("failed writing go.mod: %w", err) + } + + err = writeTemplate(path, "Makefile", meta) + if err != nil { + return fmt.Errorf("failed writing Makefile: %w", err) + } + + err = writeTemplate(path, "config.yaml", meta) + if err != nil { + return fmt.Errorf("failed writing config.yaml: %w", err) + } + + err = os.MkdirAll(filepath.Join(path, "build"), 0o750) + if err != nil { + return fmt.Errorf("failed creating build folder: %w", err) + } + + err = runTidy(path) + if err != nil { + return fmt.Errorf("failed running go mod tidy: %w", err) + } + + return nil +} + +func writeTemplate(path, fn string, m metadata) error { + outputFile := filepath.Join(path, fn) + + content, err := executeTemplate(fn+".tmpl", m) + if err != nil { + return err + } + return os.WriteFile(outputFile, content, 0o600) +} + +func executeTemplate(tmplFile string, m metadata) ([]byte, error) { + tmplPath := path.Join("init/templates", tmplFile) + tmpl := template.Must(template.New(tmplFile).ParseFS(templatesFS, tmplPath)) + buf := bytes.Buffer{} + + if err := tmpl.Execute(&buf, m); err != nil { + return []byte{}, fmt.Errorf("failed executing template: %w", err) + } + return buf.Bytes(), nil +} + +func runTidy(path string) error { + cmd := exec.Command("go", "mod", "tidy") + cmd.Dir = path + output, err := cmd.CombinedOutput() + if err != nil { + return fmt.Errorf("%w (%s)", err, string(output)) + } + return nil +} diff --git a/cmd/builder/internal/command_init_test.go b/cmd/builder/internal/command_init_test.go new file mode 100644 index 000000000000..7c83210e9d09 --- /dev/null +++ b/cmd/builder/internal/command_init_test.go @@ -0,0 +1,87 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +package internal // import "go.opentelemetry.io/collector/cmd/builder/internal" + +import ( + "path/filepath" + "testing" + + "github.com/knadh/koanf/parsers/yaml" + "github.com/knadh/koanf/providers/file" + "github.com/knadh/koanf/v2" + "github.com/spf13/cobra" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + + "go.opentelemetry.io/collector/cmd/builder/internal/builder" +) + +func TestInitCommand(t *testing.T) { + cmd := initCommand() + + assert.NotNil(t, cmd) + assert.IsType(t, &cobra.Command{}, cmd) + assert.Equal(t, "init", cmd.Use) +} + +func TestRunInit(t *testing.T) { + for _, tt := range []struct { + name string + buildPath func(string) string + + wantErr string + }{ + { + name: "without a path", + buildPath: func(string) string { return "" }, + wantErr: "argument must be a folder", + }, + { + name: "with a relative path", + buildPath: func(string) string { return "./tmp/init" }, + wantErr: "", + }, + { + name: "with an absolute path", + buildPath: func(dir string) string { return dir }, + wantErr: "", + }, + } { + t.Run(tt.name, func(t *testing.T) { + tmpdir := filepath.Join(t.TempDir(), "init") + path := tt.buildPath(tmpdir) + err := run(path) + + if tt.wantErr == "" { + require.NoError(t, err) + validateCollector(t, path) + } else { + require.ErrorContains(t, err, tt.wantErr) + } + }) + } +} + +func validateCollector(t *testing.T, path string) { + require.FileExists(t, filepath.Join(path, ".gitignore")) + require.FileExists(t, filepath.Join(path, "README.md")) + require.FileExists(t, filepath.Join(path, "manifest.yaml")) + require.FileExists(t, filepath.Join(path, "go.mod")) + require.FileExists(t, filepath.Join(path, "go.sum")) + require.FileExists(t, filepath.Join(path, "Makefile")) + require.FileExists(t, filepath.Join(path, "config.yaml")) + + k := koanf.New(".") + err := k.Load(file.Provider(filepath.Join(path, "manifest.yaml")), yaml.Parser()) + require.NoError(t, err) + + cfg := builder.Config{} + err = k.UnmarshalWithConf("", &cfg, koanf.UnmarshalConf{ + Tag: "mapstructure", + }) + require.NoError(t, err) + + assert.Equal(t, "init", cfg.Distribution.Name) + assert.Equal(t, defaultDescription, cfg.Distribution.Description) +} diff --git a/cmd/builder/internal/command_test.go b/cmd/builder/internal/command_test.go index ecc468c2c7d0..328f76d55424 100644 --- a/cmd/builder/internal/command_test.go +++ b/cmd/builder/internal/command_test.go @@ -4,6 +4,7 @@ package internal import ( + "bytes" "strings" "testing" @@ -24,11 +25,10 @@ func TestCommand(t *testing.T) { { name: "command created", want: &cobra.Command{ - SilenceUsage: true, // Don't print usage on Run error. - SilenceErrors: true, // Don't print errors; main does it. - Use: "ocb", - Long: "OpenTelemetry Collector Builder", - Args: cobra.NoArgs, + SilenceUsage: true, // Don't print usage on Run error. + Use: "ocb", + Long: "OpenTelemetry Collector Builder", + Args: cobra.NoArgs, }, wantErr: false, }, @@ -55,6 +55,23 @@ func TestCommand(t *testing.T) { } } +func TestCommandErrorOutputOnce(t *testing.T) { + cmd, err := Command() + require.NoError(t, err) + + var stderr bytes.Buffer + cmd.SetErr(&stderr) + cmd.SetArgs([]string{"/nonexistent/path/metadata.yaml"}) + + err = cmd.Execute() + require.Error(t, err) + out := stderr.String() + require.NotEmpty(t, out) + + msg := err.Error() + assert.Equal(t, 1, strings.Count(out, msg), out) +} + func TestApplyFlags(t *testing.T) { tests := []struct { name string diff --git a/cmd/builder/internal/config/default.yaml b/cmd/builder/internal/config/default.yaml index 039d19bca16c..60bc50b7467a 100644 --- a/cmd/builder/internal/config/default.yaml +++ b/cmd/builder/internal/config/default.yaml @@ -10,29 +10,33 @@ dist: module: go.opentelemetry.io/collector/cmd/otelcorecol name: otelcorecol description: Local OpenTelemetry Collector binary, testing only. - version: 0.140.0-dev + version: 0.148.0-dev receivers: - - gomod: go.opentelemetry.io/collector/receiver/nopreceiver v0.140.0 - - gomod: go.opentelemetry.io/collector/receiver/otlpreceiver v0.140.0 + - gomod: go.opentelemetry.io/collector/receiver/nopreceiver v0.148.0 + - gomod: go.opentelemetry.io/collector/receiver/otlpreceiver v0.148.0 exporters: - - gomod: go.opentelemetry.io/collector/exporter/debugexporter v0.140.0 - - gomod: go.opentelemetry.io/collector/exporter/nopexporter v0.140.0 - - gomod: go.opentelemetry.io/collector/exporter/otlpexporter v0.140.0 - - gomod: go.opentelemetry.io/collector/exporter/otlphttpexporter v0.140.0 + - gomod: go.opentelemetry.io/collector/exporter/debugexporter v0.148.0 + - gomod: go.opentelemetry.io/collector/exporter/nopexporter v0.148.0 + - gomod: go.opentelemetry.io/collector/exporter/otlpexporter v0.148.0 + - gomod: go.opentelemetry.io/collector/exporter/otlphttpexporter v0.148.0 extensions: - - gomod: go.opentelemetry.io/collector/extension/memorylimiterextension v0.140.0 - - gomod: go.opentelemetry.io/collector/extension/zpagesextension v0.140.0 + - gomod: go.opentelemetry.io/collector/extension/memorylimiterextension v0.148.0 + - gomod: go.opentelemetry.io/collector/extension/zpagesextension v0.148.0 processors: - - gomod: go.opentelemetry.io/collector/processor/batchprocessor v0.140.0 - - gomod: go.opentelemetry.io/collector/processor/memorylimiterprocessor v0.140.0 + - gomod: go.opentelemetry.io/collector/processor/batchprocessor v0.148.0 + - gomod: go.opentelemetry.io/collector/processor/memorylimiterprocessor v0.148.0 connectors: - - gomod: go.opentelemetry.io/collector/connector/forwardconnector v0.140.0 + - gomod: go.opentelemetry.io/collector/connector/forwardconnector v0.148.0 providers: - - gomod: go.opentelemetry.io/collector/confmap/provider/envprovider v1.46.0 - - gomod: go.opentelemetry.io/collector/confmap/provider/fileprovider v1.46.0 - - gomod: go.opentelemetry.io/collector/confmap/provider/httpprovider v1.46.0 - - gomod: go.opentelemetry.io/collector/confmap/provider/httpsprovider v1.46.0 - - gomod: go.opentelemetry.io/collector/confmap/provider/yamlprovider v1.46.0 + - gomod: go.opentelemetry.io/collector/confmap/provider/envprovider v1.54.0 + - gomod: go.opentelemetry.io/collector/confmap/provider/fileprovider v1.54.0 + - gomod: go.opentelemetry.io/collector/confmap/provider/httpprovider v1.54.0 + - gomod: go.opentelemetry.io/collector/confmap/provider/httpsprovider v1.54.0 + - gomod: go.opentelemetry.io/collector/confmap/provider/yamlprovider v1.54.0 + +telemetry: + gomod: go.opentelemetry.io/collector/service v0.148.0 + import: go.opentelemetry.io/collector/service/telemetry/otelconftelemetry diff --git a/cmd/builder/internal/init/templates/.gitignore.tmpl b/cmd/builder/internal/init/templates/.gitignore.tmpl new file mode 100644 index 000000000000..567609b1234a --- /dev/null +++ b/cmd/builder/internal/init/templates/.gitignore.tmpl @@ -0,0 +1 @@ +build/ diff --git a/cmd/builder/internal/init/templates/Makefile.tmpl b/cmd/builder/internal/init/templates/Makefile.tmpl new file mode 100644 index 000000000000..cd31039c5df4 --- /dev/null +++ b/cmd/builder/internal/init/templates/Makefile.tmpl @@ -0,0 +1,17 @@ +.PHONY: generate +generate: + go tool go.opentelemetry.io/collector/cmd/builder --verbose --config manifest.yaml + cd build/collector && go mod tidy + +.PHONY: tidy +tidy: + @if [ -d build/collector ]; then \ + cd build/collector && go mod tidy; \ + else \ + go mod tidy; \ + fi + +.PHONY: run +run: generate + @cd build/collector && \ + ./{{.Name}} --config ../../config.yaml diff --git a/cmd/builder/internal/init/templates/README.md.tmpl b/cmd/builder/internal/init/templates/README.md.tmpl new file mode 100644 index 000000000000..0f390b804fc5 --- /dev/null +++ b/cmd/builder/internal/init/templates/README.md.tmpl @@ -0,0 +1,44 @@ +# {{.Name}} Collector + +Welcome to your new custom OpenTelemetry Collector! +This Collector allows you to configure the components you wish to use, and only those. + +Components can come from the ones provided by the OpenTelemetry organization in +the +[opentelemetry-collector-contrib](https://github.com/open-telemetry/opentelemetry-collector-contrib) +repository, or from any other source, including your [custom, possibly private +code](https://opentelemetry.io/docs/collector/extend/custom-component/). The +only requirement is that they match the Go interface for that component, so the +Collector can run them. + +## Important files + +Edit these two files to customize your Collector: + +* `manifest.yaml` - The manifest file configures the OpenTelemetry Collector Builder and tells it what modules it needs to enable within your custom collector. + See [Configure the OpenTelemetry Collector Builder](https://opentelemetry.io/docs/collector/extend/ocb/#configure-the-opentelemetry-collector-builder) for more information. +* `config.yaml` - The Collector configuration allows you to configure your components and their pipelines. This is where you tell your Collector where it needs to export data. + See [Collector Configuration](https://opentelemetry.io/docs/collector/configuration/) for more information. + +## Running your custom Collector + +You can already run your custom Collector, though it only includes the OTLP +receiver and exporter. + +Use the following make command: + +``` +make run +``` + +This will build your collector inside the `build/collector` folder, and then +run the compiled binary. + +With the `make generate` command, you can also build the collector but not run it. + +## Next + +To learn more, read the [Extend the +Collector](https://opentelemetry.io/docs/collector/extend/) documentation, +which will give you pointers to configure your new custom Collector, and to +build custom components. diff --git a/cmd/builder/internal/init/templates/config.yaml.tmpl b/cmd/builder/internal/init/templates/config.yaml.tmpl new file mode 100644 index 000000000000..c81bc2f4467f --- /dev/null +++ b/cmd/builder/internal/init/templates/config.yaml.tmpl @@ -0,0 +1,23 @@ +receivers: + otlp: + protocols: + grpc: + endpoint: 0.0.0.0:4317 + http: + endpoint: 0.0.0.0:4318 + +exporters: + otlp: + endpoint: https://localhost:4318 + +service: + pipelines: + traces: + receivers: [otlp] + exporters: [otlp] + metrics: + receivers: [otlp] + exporters: [otlp] + logs: + receivers: [otlp] + exporters: [otlp] diff --git a/cmd/builder/internal/init/templates/go.mod.tmpl b/cmd/builder/internal/init/templates/go.mod.tmpl new file mode 100644 index 000000000000..fadab362d312 --- /dev/null +++ b/cmd/builder/internal/init/templates/go.mod.tmpl @@ -0,0 +1,5 @@ +module {{.Name}} + +go 1.25 + +tool go.opentelemetry.io/collector/cmd/builder diff --git a/cmd/builder/internal/init/templates/manifest.yaml.tmpl b/cmd/builder/internal/init/templates/manifest.yaml.tmpl new file mode 100644 index 000000000000..7e1164344cf4 --- /dev/null +++ b/cmd/builder/internal/init/templates/manifest.yaml.tmpl @@ -0,0 +1,10 @@ +dist: + name: {{.Name}} + description: {{.Description}} + output_path: ./build/collector + +exporters: + - gomod: go.opentelemetry.io/collector/exporter/otlpexporter {{.BetaVersion}} + +receivers: + - gomod: go.opentelemetry.io/collector/receiver/otlpreceiver {{.BetaVersion}} diff --git a/cmd/builder/main.go b/cmd/builder/main.go index c1a27854c6db..89c24a08bbf5 100644 --- a/cmd/builder/main.go +++ b/cmd/builder/main.go @@ -4,6 +4,8 @@ package main import ( + "os" + "github.com/spf13/cobra" "go.opentelemetry.io/collector/cmd/builder/internal" @@ -12,5 +14,8 @@ import ( func main() { cmd, err := internal.Command() cobra.CheckErr(err) - cobra.CheckErr(cmd.Execute()) + + if err := cmd.Execute(); err != nil { + os.Exit(1) + } } diff --git a/cmd/builder/metadata.yaml b/cmd/builder/metadata.yaml index 6cf04f23bb96..10dec9dc09a6 100644 --- a/cmd/builder/metadata.yaml +++ b/cmd/builder/metadata.yaml @@ -7,4 +7,4 @@ status: stability: alpha: [metrics] codeowners: - active: [] + active: [ArthurSens, dmathieu] diff --git a/cmd/builder/test/core.builder.yaml b/cmd/builder/test/core.builder.yaml index 5c9eb6fa231b..db63cb1a5984 100644 --- a/cmd/builder/test/core.builder.yaml +++ b/cmd/builder/test/core.builder.yaml @@ -4,10 +4,10 @@ dist: go: ${GOBIN} extensions: - - gomod: go.opentelemetry.io/collector/extension/zpagesextension v0.140.0 + - gomod: go.opentelemetry.io/collector/extension/zpagesextension v0.148.0 receivers: - - gomod: go.opentelemetry.io/collector/receiver/otlpreceiver v0.140.0 + - gomod: go.opentelemetry.io/collector/receiver/otlpreceiver v0.148.0 exporters: - - gomod: go.opentelemetry.io/collector/exporter/debugexporter v0.140.0 + - gomod: go.opentelemetry.io/collector/exporter/debugexporter v0.148.0 diff --git a/cmd/builder/test/test.sh b/cmd/builder/test/test.sh index bd0591afd04c..9fecc2d3c451 100755 --- a/cmd/builder/test/test.sh +++ b/cmd/builder/test/test.sh @@ -59,6 +59,8 @@ test_build_config() { "${out}/${test}" --config "./test/${test}.otel.yaml" > "${out}/otelcol.log" 2>&1 & pid=$! + # each attempt pauses for 100ms before retrying + max_retries=50 retries=0 while true do @@ -106,8 +108,73 @@ test_build_config() { } -# each attempt pauses for 100ms before retrying -max_retries=50 +test_init() { + out="${base}/init" + if ! mkdir -p "${out}"; then + echo "❌ FAIL ${test}. Failed to create test directory for the test. Aborting tests." + exit 2 + fi + + echo "Starting init test at $(date)" >> "${out}/test.log" + + if ! go run . init --path "${out}" > "${out}/builder.log" 2>&1; then + echo "❌ FAIL ${test}. Failed to compile the test. Build logs:" + cat "${out}/builder.log" + failed=true + return + fi + + go tool -modfile "${WORKSPACE_DIR}/internal/tools/go.mod" envsubst \ + -o "${out}/manifest.yaml" -i <(cat "${out}/manifest.yaml" "$replaces") + + cd "${out}" || exit 1 + make run > "${out}/otelcol.log" 2>&1 & + pid=$! + + # each attempt pauses for 100ms before retrying + max_retries=15000 + retries=0 + while true + do + if ! kill -0 "${pid}" >/dev/null 2>&1; then + echo "❌ FAIL ${test}. The OpenTelemetry Collector isn't running. Startup log:" + cat "${out}/otelcol.log" + failed=true + break + fi + + if cat "${out}/otelcol.log" | grep "Everything is ready."; then + echo "✅ PASS init" + + kill "${pid}" + ret=$? + if [ $ret -ne 0 ]; then + echo "Failed to stop the running instance for test ${test}. Return code: ${ret} . Skipping tests." + exit 4 + fi + break + fi + + echo "Server still unavailable for test '${test}'" >> "${out}/test.log" + + ((retries++)) + if [ "$retries" -gt "$max_retries" ]; then + echo "❌ FAIL ${test}. Server wasn't up after about 5m." + failed=true + + kill "${pid}" + ret=$? + if [ $ret -ne 0 ]; then + echo "Failed to stop the running instance for test ${test}. Return code: ${ret} . Skipping tests." + exit 8 + fi + break + fi + sleep 0.1s + done + + echo "Stopping server for '${test}' (pid: ${pid})" >> "${out}/test.log" +} tests="core" @@ -131,6 +198,8 @@ do test_build_config "$test" "./test/${test}.builder.yaml" done +test_init + if [[ "$failed" == "true" ]]; then exit 1 fi diff --git a/cmd/mdatagen/README.md b/cmd/mdatagen/README.md index 99469c03d013..ce3cfa0a6316 100644 --- a/cmd/mdatagen/README.md +++ b/cmd/mdatagen/README.md @@ -14,10 +14,10 @@ Every component's documentation should include a brief description of the compon There is also some information about the component (or metadata) that should be included to help end-users understand the current state of the component and whether it is right for their use case. Examples of this metadata about a component are: -* its stability level -* the distributions containing it -* the types of pipelines it supports -* metrics emitted in the case of a scraping receiver, a scraper, or a connector +- its stability level +- the distributions containing it +- the types of pipelines it supports +- metrics emitted in the case of a scraping receiver, a scraper, or a connector The metadata generator defines a schema for specifying this information to ensure it is complete and well-formed. The metadata generator is then able to ingest the metadata, validate it against the schema and produce documentation in a standardized format. @@ -26,10 +26,12 @@ An example of how this generated documentation looks can be found in [documentat ## Using the Metadata Generator In order for a component to benefit from the metadata generator (`mdatagen`) these requirements need to be met: + 1. A yaml file containing the metadata that needs to be included in the component 2. The component should declare a `go:generate mdatagen` directive which tells `mdatagen` what to generate As an example, here is a minimal `metadata.yaml` for the [OTLP receiver](https://github.com/open-telemetry/opentelemetry-collector/tree/main/receiver/otlpreceiver): + ```yaml type: otlp status: @@ -42,6 +44,7 @@ status: Detailed information about the schema of `metadata.yaml` can be found in [metadata-schema.yaml](./metadata-schema.yaml). The `go:generate mdatagen` directive is usually defined in a `doc.go` file in the same package as the component, for example: + ```go //go:generate mdatagen metadata.yaml @@ -50,11 +53,88 @@ package main Below are some more examples that can be used for reference: -* The ElasticSearch receiver has an extensive [metadata.yaml](https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/main/receiver/elasticsearchreceiver/metadata.yaml) -* The host metrics receiver has internal subcomponents, each with their own `metadata.yaml` and `doc.go`. See [cpuscraper](https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/main/receiver/hostmetricsreceiver/internal/scraper/cpuscraper) for example. +- The ElasticSearch receiver has an extensive [metadata.yaml](https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/main/receiver/elasticsearchreceiver/metadata.yaml) +- The host metrics receiver has internal subcomponents, each with their own `metadata.yaml` and `doc.go`. See [cpuscraper](https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/main/receiver/hostmetricsreceiver/internal/scraper/cpuscraper) for example. You can run `cd cmd/mdatagen && $(GOCMD) install .` to install the `mdatagen` tool in `GOBIN` and then run `mdatagen metadata.yaml` to generate documentation for a specific component or you can run `make generate` to generate documentation for all components. +### Component Config Documentation + +The metadata generator supports automatic generation of configuration schemas for components. +This generates JSON Schema files that enable IDE autocompletion, validation, and documentation for component configuration. +In the future it will also generate Go config structs and human-readable documentation for configuration options + +To define a configuration schema, add a `config` section to your `metadata.yaml`: + +```yaml +type: myreceiver +status: + class: receiver + stability: + beta: [metrics, traces] + +config: + type: object + properties: + endpoint: + type: string + description: The endpoint to listen on + default: "localhost:4317" + timeout: + type: string + format: duration + description: Request timeout duration + default: "30s" + tls: + $ref: go.opentelemetry.io/collector/config/configtls.server_config + required: [endpoint] +``` + +The `config` section is based on [JSON Schema standard](https://json-schema.org/) (draft 2020-12) and supports: + +- **Standard JSON Schema types**: string, number, integer, boolean, object, array, null +- **Validation constraints**: minLength, maxLength, pattern, minimum, maximum, enum, etc. +- **References**: Internal (`$ref: definition_name`), external (`$ref: package.path.type`), or relative (`$ref: ./internal/config.type`) +- **Reusable definitions**: Define common schemas in `$defs` and reference them with `$ref` +- **Schema composition**: Use `allOf` for complex configurations + +### Feature Gates Documentation + +The metadata generator supports automatic documentation generation for feature gates used by components. Feature gates are documented by adding a `feature_gates` section to your `metadata.yaml`: + +```yaml +type: mycomponent +status: + class: receiver + stability: + beta: [metrics, traces] + +feature_gates: + - id: mycomponent.newFeature + description: 'Enables new feature functionality that improves performance' + stage: alpha + from_version: 'v0.100.0' + reference_url: 'https://github.com/open-telemetry/opentelemetry-collector/issues/12345' + + - id: mycomponent.stableFeature + description: 'A feature that has reached stability' + stage: stable + from_version: 'v0.90.0' + to_version: 'v0.95.0' + reference_url: 'https://github.com/open-telemetry/opentelemetry-collector/issues/11111' +``` + +This will generate a "Feature Gates" section in the component's `documentation.md` file with a table containing: + +- **Feature Gate**: The gate identifier +- **Stage**: The lifecycle stage (alpha, beta, stable, deprecated) +- **Description**: Brief description of what the gate controls +- **From Version**: Version when the gate was introduced +- **To Version**: Version when stable/deprecated gates will be removed (if applicable) +- **Reference**: Link to additional contextual information + +The feature gate definitions should correspond to actual gates registered in your component code using the [Feature Gates API](../../featuregate/README.md). + ### Generate multiple metadata packages By default, `mdatagen` will generate a package called `metadata` in the `internal` directory. If you want to generate a package with a different name, you can use the `generated_package_name` configuration field to provide an alternate name. diff --git a/cmd/mdatagen/go.mod b/cmd/mdatagen/go.mod index 1ce3a78a0038..f617fe41a190 100644 --- a/cmd/mdatagen/go.mod +++ b/cmd/mdatagen/go.mod @@ -1,80 +1,110 @@ module go.opentelemetry.io/collector/cmd/mdatagen -go 1.24.0 +go 1.25.0 require ( github.com/google/go-cmp v0.7.0 - github.com/spf13/cobra v1.10.1 + github.com/spf13/cobra v1.10.2 github.com/stretchr/testify v1.11.1 - go.opentelemetry.io/collector/component v1.46.0 - go.opentelemetry.io/collector/component/componenttest v0.140.0 - go.opentelemetry.io/collector/confmap v1.46.0 + go.opentelemetry.io/collector/component v1.54.0 + go.opentelemetry.io/collector/component/componenttest v0.148.0 + go.opentelemetry.io/collector/config/confighttp v0.140.0 + go.opentelemetry.io/collector/config/configoptional v1.54.0 + go.opentelemetry.io/collector/confmap v1.54.0 go.opentelemetry.io/collector/confmap/provider/fileprovider v1.46.0 - go.opentelemetry.io/collector/connector v0.140.0 - go.opentelemetry.io/collector/connector/connectortest v0.140.0 - go.opentelemetry.io/collector/consumer v1.46.0 - go.opentelemetry.io/collector/consumer/consumertest v0.140.0 + go.opentelemetry.io/collector/connector v0.148.0 + go.opentelemetry.io/collector/connector/connectortest v0.148.0 + go.opentelemetry.io/collector/connector/xconnector v0.148.0 + go.opentelemetry.io/collector/consumer v1.54.0 + go.opentelemetry.io/collector/consumer/consumertest v0.148.0 + go.opentelemetry.io/collector/consumer/xconsumer v0.148.0 + go.opentelemetry.io/collector/featuregate v1.54.0 go.opentelemetry.io/collector/filter v0.140.0 - go.opentelemetry.io/collector/pdata v1.46.0 + go.opentelemetry.io/collector/pdata v1.54.0 + go.opentelemetry.io/collector/pdata/pprofile v0.148.0 go.opentelemetry.io/collector/pdata/xpdata v0.140.0 - go.opentelemetry.io/collector/pipeline v1.46.0 - go.opentelemetry.io/collector/processor v1.46.0 - go.opentelemetry.io/collector/processor/processortest v0.140.0 - go.opentelemetry.io/collector/receiver v1.46.0 - go.opentelemetry.io/collector/receiver/receivertest v0.140.0 - go.opentelemetry.io/collector/scraper v0.140.0 + go.opentelemetry.io/collector/pipeline v1.54.0 + go.opentelemetry.io/collector/pipeline/xpipeline v0.148.0 + go.opentelemetry.io/collector/processor v1.54.0 + go.opentelemetry.io/collector/processor/processortest v0.148.0 + go.opentelemetry.io/collector/processor/xprocessor v0.148.0 + go.opentelemetry.io/collector/receiver v1.54.0 + go.opentelemetry.io/collector/receiver/receivertest v0.148.0 + go.opentelemetry.io/collector/receiver/xreceiver v0.148.0 + go.opentelemetry.io/collector/scraper v0.148.0 + go.opentelemetry.io/collector/scraper/scraperhelper v0.0.0-00010101000000-000000000000 go.opentelemetry.io/collector/scraper/scrapertest v0.140.0 + go.opentelemetry.io/collector/scraper/xscraper v0.0.0-00010101000000-000000000000 go.opentelemetry.io/collector/service/hostcapabilities v0.140.0 - go.opentelemetry.io/otel v1.40.0 - go.opentelemetry.io/otel/metric v1.40.0 - go.opentelemetry.io/otel/sdk/metric v1.40.0 - go.opentelemetry.io/otel/trace v1.40.0 + go.opentelemetry.io/otel v1.42.0 + go.opentelemetry.io/otel/metric v1.42.0 + go.opentelemetry.io/otel/sdk/metric v1.42.0 + go.opentelemetry.io/otel/trace v1.42.0 go.uber.org/goleak v1.3.0 go.uber.org/zap v1.27.1 - golang.org/x/text v0.31.0 - gopkg.in/yaml.v3 v3.0.1 + go.yaml.in/yaml/v3 v3.0.4 + golang.org/x/text v0.34.0 + golang.org/x/tools v0.42.0 ) require ( github.com/cespare/xxhash/v2 v2.3.0 // indirect - github.com/davecgh/go-spew v1.1.1 // indirect + github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect + github.com/felixge/httpsnoop v1.0.4 // indirect + github.com/foxboron/go-tpm-keyfiles v0.0.0-20251226215517-609e4778396f // indirect + github.com/fsnotify/fsnotify v1.9.0 // indirect github.com/go-logr/logr v1.4.3 // indirect github.com/go-logr/stdr v1.2.2 // indirect - github.com/go-viper/mapstructure/v2 v2.4.0 // indirect + github.com/go-viper/mapstructure/v2 v2.5.0 // indirect github.com/gobwas/glob v0.2.3 // indirect + github.com/golang/snappy v1.0.0 // indirect + github.com/google/go-tpm v0.9.8 // indirect github.com/google/uuid v1.6.0 // indirect - github.com/hashicorp/go-version v1.7.0 // indirect + github.com/hashicorp/go-version v1.8.0 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/json-iterator/go v1.1.12 // indirect + github.com/klauspost/compress v1.18.4 // indirect github.com/knadh/koanf/maps v0.1.2 // indirect github.com/knadh/koanf/providers/confmap v1.0.0 // indirect - github.com/knadh/koanf/v2 v2.3.0 // indirect + github.com/knadh/koanf/v2 v2.3.3 // indirect github.com/mitchellh/copystructure v1.2.0 // indirect github.com/mitchellh/reflectwalk v1.0.2 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee // indirect - github.com/pmezard/go-difflib v1.0.0 // indirect - github.com/spf13/pflag v1.0.9 // indirect + github.com/pierrec/lz4/v4 v4.1.26 // indirect + github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect + github.com/rs/cors v1.11.1 // indirect + github.com/spf13/pflag v1.0.10 // indirect go.opentelemetry.io/auto/sdk v1.2.1 // indirect - go.opentelemetry.io/collector/component/componentstatus v0.140.0 // indirect - go.opentelemetry.io/collector/connector/xconnector v0.140.0 // indirect - go.opentelemetry.io/collector/consumer/consumererror v0.140.0 // indirect - go.opentelemetry.io/collector/consumer/xconsumer v0.140.0 // indirect - go.opentelemetry.io/collector/featuregate v1.46.0 // indirect - go.opentelemetry.io/collector/internal/fanoutconsumer v0.140.0 // indirect - go.opentelemetry.io/collector/pdata/pprofile v0.140.0 // indirect - go.opentelemetry.io/collector/pdata/testdata v0.140.0 // indirect - go.opentelemetry.io/collector/pipeline/xpipeline v0.140.0 // indirect - go.opentelemetry.io/collector/processor/xprocessor v0.140.0 // indirect - go.opentelemetry.io/collector/receiver/xreceiver v0.140.0 // indirect - go.opentelemetry.io/collector/service v0.140.0 // indirect - go.opentelemetry.io/otel/sdk v1.40.0 // indirect + go.opentelemetry.io/collector/client v1.54.0 // indirect + go.opentelemetry.io/collector/component/componentstatus v0.148.0 // indirect + go.opentelemetry.io/collector/config/configauth v1.54.0 // indirect + go.opentelemetry.io/collector/config/configcompression v1.54.0 // indirect + go.opentelemetry.io/collector/config/configmiddleware v1.54.0 // indirect + go.opentelemetry.io/collector/config/confignet v0.0.0-00010101000000-000000000000 // indirect + go.opentelemetry.io/collector/config/configopaque v1.54.0 // indirect + go.opentelemetry.io/collector/config/configtls v1.54.0 // indirect + go.opentelemetry.io/collector/confmap/xconfmap v0.148.0 // indirect + go.opentelemetry.io/collector/consumer/consumererror v0.148.0 // indirect + go.opentelemetry.io/collector/extension/extensionauth v1.54.0 // indirect + go.opentelemetry.io/collector/extension/extensionmiddleware v0.148.0 // indirect + go.opentelemetry.io/collector/internal/componentalias v0.148.0 // indirect + go.opentelemetry.io/collector/internal/fanoutconsumer v0.148.0 // indirect + go.opentelemetry.io/collector/pdata/testdata v0.148.0 // indirect + go.opentelemetry.io/collector/receiver/receiverhelper v0.140.0 // indirect + go.opentelemetry.io/collector/service v0.148.0 // indirect + go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.67.0 // indirect + go.opentelemetry.io/otel/sdk v1.42.0 // indirect go.uber.org/multierr v1.11.0 // indirect - go.yaml.in/yaml/v3 v3.0.4 // indirect - golang.org/x/sys v0.40.0 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20251022142026-3a174f9686a8 // indirect - google.golang.org/grpc v1.77.0 // indirect - google.golang.org/protobuf v1.36.10 // indirect + golang.org/x/crypto v0.48.0 // indirect + golang.org/x/mod v0.33.0 // indirect + golang.org/x/net v0.51.0 // indirect + golang.org/x/sync v0.19.0 // indirect + golang.org/x/sys v0.41.0 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20260226221140-a57be14db171 // indirect + google.golang.org/grpc v1.79.3 // indirect + google.golang.org/protobuf v1.36.11 // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect ) replace go.opentelemetry.io/collector/component => ../../component @@ -200,3 +230,13 @@ replace go.opentelemetry.io/collector/exporter/exporterhelper => ../../exporter/ replace go.opentelemetry.io/collector/service/telemetry/telemetrytest => ../../service/telemetry/telemetrytest replace go.opentelemetry.io/collector/internal/testutil => ../../internal/testutil + +replace go.opentelemetry.io/collector/internal/componentalias => ../../internal/componentalias + +replace go.opentelemetry.io/collector/config/confignet => ../../config/confignet + +replace go.opentelemetry.io/collector/receiver/receiverhelper => ../../receiver/receiverhelper + +replace go.opentelemetry.io/collector/scraper/scraperhelper => ../../scraper/scraperhelper + +replace go.opentelemetry.io/collector/scraper/xscraper => ../../scraper/xscraper diff --git a/cmd/mdatagen/go.sum b/cmd/mdatagen/go.sum index 417a6687489e..aa1275164334 100644 --- a/cmd/mdatagen/go.sum +++ b/cmd/mdatagen/go.sum @@ -2,36 +2,51 @@ github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UF github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= +github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg= +github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= +github.com/foxboron/go-tpm-keyfiles v0.0.0-20251226215517-609e4778396f h1:RJ+BDPLSHQO7cSjKBqjPJSbi1qfk9WcsjQDtZiw3dZw= +github.com/foxboron/go-tpm-keyfiles v0.0.0-20251226215517-609e4778396f/go.mod h1:VHbbch/X4roIY22jL1s3qRbZhCiRIgUAF/PdSUcx2io= +github.com/fsnotify/fsnotify v1.9.0 h1:2Ml+OJNzbYCTzsxtv8vKSFD9PbJjmhYF14k/jKC7S9k= +github.com/fsnotify/fsnotify v1.9.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI= github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= -github.com/go-viper/mapstructure/v2 v2.4.0 h1:EBsztssimR/CONLSZZ04E8qAkxNYq4Qp9LvH92wZUgs= -github.com/go-viper/mapstructure/v2 v2.4.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM= +github.com/go-viper/mapstructure/v2 v2.5.0 h1:vM5IJoUAy3d7zRSVtIwQgBj7BiWtMPfmPEgAXnvj1Ro= +github.com/go-viper/mapstructure/v2 v2.5.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM= github.com/gobwas/glob v0.2.3 h1:A4xDbljILXROh+kObIiy5kIaPYD8e96x1tgBhUI5J+Y= github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8= github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= +github.com/golang/snappy v1.0.0 h1:Oy607GVXHs7RtbggtPBnr2RmDArIsAefDwvrdWvRhGs= +github.com/golang/snappy v1.0.0/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= +github.com/google/go-tpm v0.9.8 h1:slArAR9Ft+1ybZu0lBwpSmpwhRXaa85hWtMinMyRAWo= +github.com/google/go-tpm v0.9.8/go.mod h1:h9jEsEECg7gtLis0upRBQU+GhYVH6jMjrFxI8u6bVUY= +github.com/google/go-tpm-tools v0.4.7 h1:J3ycC8umYxM9A4eF73EofRZu4BxY0jjQnUnkhIBbvws= +github.com/google/go-tpm-tools v0.4.7/go.mod h1:gSyXTZHe3fgbzb6WEGd90QucmsnT1SRdlye82gH8QjQ= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/hashicorp/go-version v1.7.0 h1:5tqGy27NaOTB8yJKUZELlFAS/LTKJkrmONwQKeRZfjY= -github.com/hashicorp/go-version v1.7.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= +github.com/hashicorp/go-version v1.8.0 h1:KAkNb1HAiZd1ukkxDFGmokVZe1Xy9HG6NUp+bPle2i4= +github.com/hashicorp/go-version v1.8.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= +github.com/klauspost/compress v1.18.4 h1:RPhnKRAQ4Fh8zU2FY/6ZFDwTVTxgJ/EMydqSTzE9a2c= +github.com/klauspost/compress v1.18.4/go.mod h1:R0h/fSBs8DE4ENlcrlib3PsXS61voFxhIs2DeRhCvJ4= github.com/knadh/koanf/maps v0.1.2 h1:RBfmAW5CnZT+PJ1CVc1QSJKf4Xu9kxfQgYVQSu8hpbo= github.com/knadh/koanf/maps v0.1.2/go.mod h1:npD/QZY3V6ghQDdcQzl1W4ICNVTkohC8E73eI2xW4yI= github.com/knadh/koanf/providers/confmap v1.0.0 h1:mHKLJTE7iXEys6deO5p6olAiZdG5zwp8Aebir+/EaRE= github.com/knadh/koanf/providers/confmap v1.0.0/go.mod h1:txHYHiI2hAtF0/0sCmcuol4IDcuQbKTybiB1nOcUo1A= -github.com/knadh/koanf/v2 v2.3.0 h1:Qg076dDRFHvqnKG97ZEsi9TAg2/nFTa9hCdcSa1lvlM= -github.com/knadh/koanf/v2 v2.3.0/go.mod h1:gRb40VRAbd4iJMYYD5IxZ6hfuopFcXBpc9bbQpZwo28= +github.com/knadh/koanf/v2 v2.3.3 h1:jLJC8XCRfLC7n4F+ZKKdBsbq1bfXTpuFhf4L7t94D94= +github.com/knadh/koanf/v2 v2.3.3/go.mod h1:gRb40VRAbd4iJMYYD5IxZ6hfuopFcXBpc9bbQpZwo28= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= @@ -46,37 +61,45 @@ github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJ github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee h1:W5t00kpgFdJifH4BDsTlE89Zl93FEloxaWZfGcifgq8= github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= -github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pierrec/lz4/v4 v4.1.26 h1:GrpZw1gZttORinvzBdXPUXATeqlJjqUG/D87TKMnhjY= +github.com/pierrec/lz4/v4 v4.1.26/go.mod h1:EoQMVJgeeEOMsCqCzqFm2O0cJvljX2nGZjcRIPL34O4= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= +github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ= github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc= +github.com/rs/cors v1.11.1 h1:eU3gRzXLRK57F5rKMGMZURNdIG4EoAmX8k94r9wXWHA= +github.com/rs/cors v1.11.1/go.mod h1:XyqrcTp5zjWr1wsJ8PIRZssZ8b/WMcMf71DJnit4EMU= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= -github.com/spf13/cobra v1.10.1 h1:lJeBwCfmrnXthfAupyUTzJ/J4Nc1RsHC/mSRU2dll/s= -github.com/spf13/cobra v1.10.1/go.mod h1:7SmJGaTHFVBY0jW4NXGluQoLvhqFQM+6XSKD+P4XaB0= -github.com/spf13/pflag v1.0.9 h1:9exaQaMOCwffKiiiYk6/BndUBv+iRViNW+4lEMi0PvY= +github.com/spf13/cobra v1.10.2 h1:DMTTonx5m65Ic0GOoRY2c16WCbHxOOw6xxezuLaBpcU= +github.com/spf13/cobra v1.10.2/go.mod h1:7C1pvHqHw5A4vrJfjNwvOdzYu0Gml16OCs2GRiTUUS4= github.com/spf13/pflag v1.0.9/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= +github.com/spf13/pflag v1.0.10 h1:4EBh2KAYBwaONj6b2Ye1GiHfwjqyROoF4RwYO+vPwFk= +github.com/spf13/pflag v1.0.10/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U= github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64= go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y= -go.opentelemetry.io/otel v1.40.0 h1:oA5YeOcpRTXq6NN7frwmwFR0Cn3RhTVZvXsP4duvCms= -go.opentelemetry.io/otel v1.40.0/go.mod h1:IMb+uXZUKkMXdPddhwAHm6UfOwJyh4ct1ybIlV14J0g= -go.opentelemetry.io/otel/metric v1.40.0 h1:rcZe317KPftE2rstWIBitCdVp89A2HqjkxR3c11+p9g= -go.opentelemetry.io/otel/metric v1.40.0/go.mod h1:ib/crwQH7N3r5kfiBZQbwrTge743UDc7DTFVZrrXnqc= -go.opentelemetry.io/otel/sdk v1.40.0 h1:KHW/jUzgo6wsPh9At46+h4upjtccTmuZCFAc9OJ71f8= -go.opentelemetry.io/otel/sdk v1.40.0/go.mod h1:Ph7EFdYvxq72Y8Li9q8KebuYUr2KoeyHx0DRMKrYBUE= -go.opentelemetry.io/otel/sdk/metric v1.40.0 h1:mtmdVqgQkeRxHgRv4qhyJduP3fYJRMX4AtAlbuWdCYw= -go.opentelemetry.io/otel/sdk/metric v1.40.0/go.mod h1:4Z2bGMf0KSK3uRjlczMOeMhKU2rhUqdWNoKcYrtcBPg= -go.opentelemetry.io/otel/trace v1.40.0 h1:WA4etStDttCSYuhwvEa8OP8I5EWu24lkOzp+ZYblVjw= -go.opentelemetry.io/otel/trace v1.40.0/go.mod h1:zeAhriXecNGP/s2SEG3+Y8X9ujcJOTqQ5RgdEJcawiA= -go.opentelemetry.io/proto/slim/otlp v1.9.0 h1:fPVMv8tP3TrsqlkH1HWYUpbCY9cAIemx184VGkS6vlE= -go.opentelemetry.io/proto/slim/otlp v1.9.0/go.mod h1:xXdeJJ90Gqyll+orzUkY4bOd2HECo5JofeoLpymVqdI= -go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.2.0 h1:o13nadWDNkH/quoDomDUClnQBpdQQ2Qqv0lQBjIXjE8= -go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.2.0/go.mod h1:Gyb6Xe7FTi/6xBHwMmngGoHqL0w29Y4eW8TGFzpefGA= -go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.2.0 h1:EiUYvtwu6PMrMHVjcPfnsG3v+ajPkbUeH+IL93+QYyk= -go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.2.0/go.mod h1:mUUHKFiN2SST3AhJ8XhJxEoeVW12oqfXog0Bo8W3Ec4= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.67.0 h1:OyrsyzuttWTSur2qN/Lm0m2a8yqyIjUVBZcxFPuXq2o= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.67.0/go.mod h1:C2NGBr+kAB4bk3xtMXfZ94gqFDtg/GkI7e9zqGh5Beg= +go.opentelemetry.io/otel v1.42.0 h1:lSQGzTgVR3+sgJDAU/7/ZMjN9Z+vUip7leaqBKy4sho= +go.opentelemetry.io/otel v1.42.0/go.mod h1:lJNsdRMxCUIWuMlVJWzecSMuNjE7dOYyWlqOXWkdqCc= +go.opentelemetry.io/otel/metric v1.42.0 h1:2jXG+3oZLNXEPfNmnpxKDeZsFI5o4J+nz6xUlaFdF/4= +go.opentelemetry.io/otel/metric v1.42.0/go.mod h1:RlUN/7vTU7Ao/diDkEpQpnz3/92J9ko05BIwxYa2SSI= +go.opentelemetry.io/otel/sdk v1.42.0 h1:LyC8+jqk6UJwdrI/8VydAq/hvkFKNHZVIWuslJXYsDo= +go.opentelemetry.io/otel/sdk v1.42.0/go.mod h1:rGHCAxd9DAph0joO4W6OPwxjNTYWghRWmkHuGbayMts= +go.opentelemetry.io/otel/sdk/metric v1.42.0 h1:D/1QR46Clz6ajyZ3G8SgNlTJKBdGp84q9RKCAZ3YGuA= +go.opentelemetry.io/otel/sdk/metric v1.42.0/go.mod h1:Ua6AAlDKdZ7tdvaQKfSmnFTdHx37+J4ba8MwVCYM5hc= +go.opentelemetry.io/otel/trace v1.42.0 h1:OUCgIPt+mzOnaUTpOQcBiM/PLQ/Op7oq6g4LenLmOYY= +go.opentelemetry.io/otel/trace v1.42.0/go.mod h1:f3K9S+IFqnumBkKhRJMeaZeNk9epyhnCmQh/EysQCdc= +go.opentelemetry.io/proto/slim/otlp v1.10.0 h1:iR97Vs/ZDR+y9TfuP9b1XBtdPWeC+OMslIBmhcLU7jM= +go.opentelemetry.io/proto/slim/otlp v1.10.0/go.mod h1:lV9250stpjYLPNA5viFabIgP2QlUGRT1GdTgAf8SIUk= +go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.3.0 h1:RUF5rO0hAlgiJt1fzQVzcVs3vZVNHIcMLgOgG4rWNcQ= +go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.3.0/go.mod h1:I89cynRj8y+383o7tEQVg2SVA6SRgDVIouWPUVXjx0U= +go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.3.0 h1:CQvJSldHRUN6Z8jsUeYv8J0lXRvygALXIzsmAeCcZE0= +go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.3.0/go.mod h1:xSQ+mEfJe/GjK1LXEyVOoSI1N9JV9ZI923X5kup43W4= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= @@ -85,18 +108,28 @@ go.uber.org/zap v1.27.1 h1:08RqriUEv8+ArZRYSTXy1LeBScaMpVSTBhCeaZYfMYc= go.uber.org/zap v1.27.1/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc= go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg= -golang.org/x/net v0.47.0 h1:Mx+4dIFzqraBXUugkia1OOvlD6LemFo1ALMHjrXDOhY= -golang.org/x/net v0.47.0/go.mod h1:/jNxtkgq5yWUGYkaZGqo27cfGZ1c5Nen03aYrrKpVRU= -golang.org/x/sys v0.40.0 h1:DBZZqJ2Rkml6QMQsZywtnjnnGvHza6BTfYFWY9kjEWQ= -golang.org/x/sys v0.40.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= -golang.org/x/text v0.31.0 h1:aC8ghyu4JhP8VojJ2lEHBnochRno1sgL6nEi9WGFGMM= -golang.org/x/text v0.31.0/go.mod h1:tKRAlv61yKIjGGHX/4tP1LTbc13YSec1pxVEWXzfoeM= -google.golang.org/genproto/googleapis/rpc v0.0.0-20251022142026-3a174f9686a8 h1:M1rk8KBnUsBDg1oPGHNCxG4vc1f49epmTO7xscSajMk= -google.golang.org/genproto/googleapis/rpc v0.0.0-20251022142026-3a174f9686a8/go.mod h1:7i2o+ce6H/6BluujYR+kqX3GKH+dChPTQU19wjRPiGk= -google.golang.org/grpc v1.77.0 h1:wVVY6/8cGA6vvffn+wWK5ToddbgdU3d8MNENr4evgXM= -google.golang.org/grpc v1.77.0/go.mod h1:z0BY1iVj0q8E1uSQCjL9cppRj+gnZjzDnzV0dHhrNig= -google.golang.org/protobuf v1.36.10 h1:AYd7cD/uASjIL6Q9LiTjz8JLcrh/88q5UObnmY3aOOE= -google.golang.org/protobuf v1.36.10/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= +golang.org/x/crypto v0.48.0 h1:/VRzVqiRSggnhY7gNRxPauEQ5Drw9haKdM0jqfcCFts= +golang.org/x/crypto v0.48.0/go.mod h1:r0kV5h3qnFPlQnBSrULhlsRfryS2pmewsg+XfMgkVos= +golang.org/x/mod v0.33.0 h1:tHFzIWbBifEmbwtGz65eaWyGiGZatSrT9prnU8DbVL8= +golang.org/x/mod v0.33.0/go.mod h1:swjeQEj+6r7fODbD2cqrnje9PnziFuw4bmLbBZFrQ5w= +golang.org/x/net v0.51.0 h1:94R/GTO7mt3/4wIKpcR5gkGmRLOuE/2hNGeWq/GBIFo= +golang.org/x/net v0.51.0/go.mod h1:aamm+2QF5ogm02fjy5Bb7CQ0WMt1/WVM7FtyaTLlA9Y= +golang.org/x/sync v0.19.0 h1:vV+1eWNmZ5geRlYjzm2adRgW2/mcpevXNg50YZtPCE4= +golang.org/x/sync v0.19.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI= +golang.org/x/sys v0.41.0 h1:Ivj+2Cp/ylzLiEU89QhWblYnOE9zerudt9Ftecq2C6k= +golang.org/x/sys v0.41.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= +golang.org/x/text v0.34.0 h1:oL/Qq0Kdaqxa1KbNeMKwQq0reLCCaFtqu2eNuSeNHbk= +golang.org/x/text v0.34.0/go.mod h1:homfLqTYRFyVYemLBFl5GgL/DWEiH5wcsQ5gSh1yziA= +golang.org/x/tools v0.42.0 h1:uNgphsn75Tdz5Ji2q36v/nsFSfR/9BRFvqhGBaJGd5k= +golang.org/x/tools v0.42.0/go.mod h1:Ma6lCIwGZvHK6XtgbswSoWroEkhugApmsXyrUmBhfr0= +gonum.org/v1/gonum v0.17.0 h1:VbpOemQlsSMrYmn7T2OUvQ4dqxQXU+ouZFQsZOx50z4= +gonum.org/v1/gonum v0.17.0/go.mod h1:El3tOrEuMpv2UdMrbNlKEh9vd86bmQ6vqIcDwxEOc1E= +google.golang.org/genproto/googleapis/rpc v0.0.0-20260226221140-a57be14db171 h1:ggcbiqK8WWh6l1dnltU4BgWGIGo+EVYxCaAPih/zQXQ= +google.golang.org/genproto/googleapis/rpc v0.0.0-20260226221140-a57be14db171/go.mod h1:4Hqkh8ycfw05ld/3BWL7rJOSfebL2Q+DVDeRgYgxUU8= +google.golang.org/grpc v1.79.3 h1:sybAEdRIEtvcD68Gx7dmnwjZKlyfuc61Dyo9pGXXkKE= +google.golang.org/grpc v1.79.3/go.mod h1:KmT0Kjez+0dde/v2j9vzwoAScgEPx/Bw1CYChhHLrHQ= +google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE= +google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= diff --git a/cmd/mdatagen/internal/cfggen/generation.go b/cmd/mdatagen/internal/cfggen/generation.go new file mode 100644 index 000000000000..a916e12b30f4 --- /dev/null +++ b/cmd/mdatagen/internal/cfggen/generation.go @@ -0,0 +1,282 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +package cfggen // import "go.opentelemetry.io/collector/cmd/mdatagen/internal/cfggen" +import ( + "errors" + "fmt" + "maps" + "slices" + + "go.opentelemetry.io/collector/cmd/mdatagen/internal/helpers" +) + +// NewCfgFns returns template functions for config generation with rootPackage and componentPackage +// baked into closures. This way the template itself never needs to pass these context values around. +func NewCfgFns(rootPackage, componentPackage string) map[string]any { + return map[string]any{ + "extractImports": func(cfg *ConfigMetadata) []string { + if cfg == nil { + return nil + } + imports, err := ExtractImports(cfg, rootPackage, componentPackage) + if err != nil { + return []string{} + } + return imports + }, + "extractDefs": func(cfg *ConfigMetadata) map[string]*ConfigMetadata { + if cfg == nil { + return nil + } + return ExtractDefs(cfg) + }, + "mapGoType": func(cfg *ConfigMetadata, propName string) string { + if cfg == nil { + return "any" + } + goType, err := MapGoType(cfg, propName, rootPackage, componentPackage) + if err != nil { + panic(err) + } + return goType + }, + "publicType": func(ref string) string { + typeName, err := FormatTypeName(ref, rootPackage, componentPackage) + if err != nil { + panic(err) + } + return typeName + }, + } +} + +// WithCfgFns merges config generation template functions into the given function map. +// The rootPackage and componentPackage are captured in closures so the template doesn't need to thread them through. +func WithCfgFns(fns map[string]any, rootPackage, componentPackage string) map[string]any { + cfgFns := NewCfgFns(rootPackage, componentPackage) + maps.Copy(fns, cfgFns) + return fns +} + +var goBasicTypes = []string{ + "rune", "byte", + "uint", "int8", "uint8", "int16", "uint16", "int32", "uint32", "int64", "uint64", + "float32", "float64", +} + +// MapGoType maps a ConfigMetadata to its corresponding Go type as a string. +func MapGoType(md *ConfigMetadata, propName, rootPackage, componentPackage string) (string, error) { + if md == nil { + return "", errors.New("nil ConfigMetadata") + } + goType, err := resolveGoType(md, propName, rootPackage, componentPackage) + if err != nil { + return "", fmt.Errorf("failed to resolve Go type for property %q: %w", propName, err) + } + if md.IsPointer { + goType = "*" + goType + } + if md.IsOptional { + return "configoptional.Optional[" + goType + "]", nil + } + return goType, nil +} + +func resolveGoType(md *ConfigMetadata, propName, rootPackage, componentPackage string) (string, error) { + if md.GoType != "" { + if slices.Contains(goBasicTypes, md.GoType) { + return md.GoType, nil + } + typeName, err := FormatTypeName(md.GoType, rootPackage, componentPackage) + if err != nil { + return "", fmt.Errorf("failed to format custom type %q: %w", md.GoType, err) + } + return typeName, nil + } + if md.Ref != "" { + typeName, err := FormatTypeName(md.Ref, rootPackage, componentPackage) + if err != nil { + return "", fmt.Errorf("failed to format reference type %q: %w", md.Ref, err) + } + return typeName, nil + } + + switch md.Type { + case "string": + switch md.Format { + case "date-time": + return "time.Time", nil + case "duration": + return "time.Duration", nil + default: + return "string", nil + } + case "integer": + return "int", nil + case "number": + return "float64", nil + case "boolean": + return "bool", nil + case "array": + if md.Items == nil { + return "[]any", nil + } + itemType, err := MapGoType(md.Items, propName+"_item", rootPackage, componentPackage) + if err != nil { + return "", fmt.Errorf("failed to map array item type: %w", err) + } + return "[]" + itemType, nil + case "object": + if md.AdditionalProperties != nil { + valueType, err := MapGoType(md.AdditionalProperties, propName, rootPackage, componentPackage) + if err != nil { + return "", fmt.Errorf("failed to map additionalProperties type: %w", err) + } + return "map[string]" + valueType, nil + } + if md.Properties != nil { + formatted, err := helpers.FormatIdentifier(propName, true) + if err != nil { + return "", fmt.Errorf("failed to format embedded object type name %q: %w", propName, err) + } + return formatted, nil + } + return "map[string]any", nil + case "": + return "any", nil + default: + return "", fmt.Errorf("unsupported type: %q", md.Type) + } +} + +// ExtractImports recursively scans the ConfigMetadata and collects all unique import paths needed for the generated Go code. +func ExtractImports(md *ConfigMetadata, rootPackage, componentPackage string) ([]string, error) { + if md == nil { + return nil, nil + } + + imports := make(map[string]bool) + if err := collectImports(md, imports, rootPackage, componentPackage); err != nil { + return nil, err + } + + return slices.Collect(maps.Keys(imports)), nil +} + +func collectImports(md *ConfigMetadata, imports map[string]bool, rootPackage, componentPackage string) error { + if md == nil { + return nil + } + + if md.GoType != "" { + ref, err := ResolveGoTypeRef(md.GoType, rootPackage, componentPackage) + if err == nil && ref.ImportPath != "" { + imports[ref.ImportPath] = true + } + } + + if md.Ref != "" { + ref, err := ResolveGoTypeRef(md.Ref, rootPackage, componentPackage) + if err == nil && ref.ImportPath != "" { + imports[ref.ImportPath] = true + } + } + + if md.Type == "string" && (md.Format == "date-time" || md.Format == "duration") { + imports["time"] = true + } + + if md.IsOptional { + imports["go.opentelemetry.io/collector/config/configoptional"] = true + } + + for _, prop := range md.Properties { + if err := collectImports(prop, imports, rootPackage, componentPackage); err != nil { + return err + } + } + + if md.Items != nil { + if err := collectImports(md.Items, imports, rootPackage, componentPackage); err != nil { + return err + } + } + + for _, schema := range md.AllOf { + if err := collectImports(schema, imports, rootPackage, componentPackage); err != nil { + return err + } + } + + for _, def := range md.Defs { + if err := collectImports(def, imports, rootPackage, componentPackage); err != nil { + return err + } + } + + if err := collectImports(md.AdditionalProperties, imports, rootPackage, componentPackage); err != nil { + return err + } + + if md.ContentSchema != nil { + if err := collectImports(md.ContentSchema, imports, rootPackage, componentPackage); err != nil { + return err + } + } + + return nil +} + +// FormatTypeName resolves a reference string to a Go type expression using GoTypeRef. +func FormatTypeName(ref, rootPackage, componentPackage string) (string, error) { + tr, err := ResolveGoTypeRef(ref, rootPackage, componentPackage) + if err != nil { + return "", err + } + return tr.String(), nil +} + +// ExtractDefs recursively collects all definitions from the ConfigMetadata, including nested ones, +// and returns a flat map of definition names to their corresponding ConfigMetadata. +func ExtractDefs(md *ConfigMetadata) map[string]*ConfigMetadata { + defs := make(map[string]*ConfigMetadata) + collectDefs(md, defs) + return defs +} + +func collectDefs(md *ConfigMetadata, defs map[string]*ConfigMetadata) { + if md == nil { + return + } + + for name, def := range md.Defs { + defs[name] = def + collectDefs(def, defs) + } + + for propName, prop := range md.Properties { + // if is embedded object + if prop.Type == "object" { + if len(prop.Properties) > 0 { + defs[propName] = prop + collectDefs(prop, defs) + } + ap := prop.AdditionalProperties + if ap == nil { + ap = md.AdditionalProperties + } + if ap != nil && ap.Type == "object" && len(ap.Properties) > 0 { + defs[propName] = ap + collectDefs(ap, defs) + } + } + if prop.Type == "array" { + if prop.Items != nil && prop.Items.Type == "object" && len(prop.Items.Properties) > 0 { + defName := propName + "_item" + defs[defName] = prop.Items + collectDefs(prop.Items, defs) + } + } + } +} diff --git a/cmd/mdatagen/internal/cfggen/generation_test.go b/cmd/mdatagen/internal/cfggen/generation_test.go new file mode 100644 index 000000000000..45ff5db01ca5 --- /dev/null +++ b/cmd/mdatagen/internal/cfggen/generation_test.go @@ -0,0 +1,984 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +package cfggen + +import ( + "testing" + + "github.com/stretchr/testify/require" +) + +func TestMapGoType_BasicTypes(t *testing.T) { + tests := []struct { + name string + metadata *ConfigMetadata + propName string + expected string + }{ + { + name: "string type", + metadata: &ConfigMetadata{Type: "string"}, + propName: "field", + expected: "string", + }, + { + name: "integer type", + metadata: &ConfigMetadata{Type: "integer"}, + propName: "field", + expected: "int", + }, + { + name: "number type", + metadata: &ConfigMetadata{Type: "number"}, + propName: "field", + expected: "float64", + }, + { + name: "boolean type", + metadata: &ConfigMetadata{Type: "boolean"}, + propName: "field", + expected: "bool", + }, + { + name: "empty type defaults to any", + metadata: &ConfigMetadata{Type: ""}, + propName: "field", + expected: "any", + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + result, err := MapGoType(tt.metadata, tt.propName, "", "") + require.NoError(t, err) + require.Equal(t, tt.expected, result) + }) + } +} + +func TestMapGoType_FormattedStrings(t *testing.T) { + tests := []struct { + name string + format string + expected string + }{ + { + name: "date-time format", + format: "date-time", + expected: "time.Time", + }, + { + name: "duration format", + format: "duration", + expected: "time.Duration", + }, + { + name: "no format", + format: "", + expected: "string", + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + md := &ConfigMetadata{ + Type: "string", + Format: tt.format, + } + result, err := MapGoType(md, "field", "", "") + require.NoError(t, err) + require.Equal(t, tt.expected, result) + }) + } +} + +func TestMapGoType_Arrays(t *testing.T) { + compPkg := "go.opentelemetry.io/collector/cmd/mdatagen/internal/samplescraper" + + tests := []struct { + name string + metadata *ConfigMetadata + expected string + }{ + { + name: "array with string items", + metadata: &ConfigMetadata{ + Type: "array", + Items: &ConfigMetadata{Type: "string"}, + }, + expected: "[]string", + }, + { + name: "array with int items", + metadata: &ConfigMetadata{ + Type: "array", + Items: &ConfigMetadata{Type: "integer"}, + }, + expected: "[]int", + }, + { + name: "array with ref items", + metadata: &ConfigMetadata{ + Type: "array", + Items: &ConfigMetadata{Ref: "./internal/metadata.custom_type"}, + }, + expected: "[]metadata.CustomType", + }, + { + name: "array with nested object items ", + metadata: &ConfigMetadata{ + Type: "array", + Items: &ConfigMetadata{ + Type: "object", + Properties: map[string]*ConfigMetadata{ + "name": {Type: "string"}, + }, + }, + }, + expected: "[]FieldItem", + }, + { + name: "array without items defaults to any", + metadata: &ConfigMetadata{ + Type: "array", + Items: nil, + }, + expected: "[]any", + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + result, err := MapGoType(tt.metadata, "field", "", compPkg) + require.NoError(t, err) + require.Equal(t, tt.expected, result) + }) + } +} + +func TestMapGoType_Objects(t *testing.T) { + compPkg := "go.opentelemetry.io/collector/cmd/mdatagen/internal/samplescraper" + + tests := []struct { + name string + metadata *ConfigMetadata + propName string + expected string + }{ + { + name: "object with additionalProperties string", + metadata: &ConfigMetadata{ + Type: "object", + AdditionalProperties: &ConfigMetadata{Type: "string"}, + }, + propName: "field", + expected: "map[string]string", + }, + { + name: "object with additionalProperties int", + metadata: &ConfigMetadata{ + Type: "object", + AdditionalProperties: &ConfigMetadata{Type: "integer"}, + }, + propName: "field", + expected: "map[string]int", + }, + { + name: "object with additionalProperties ref", + metadata: &ConfigMetadata{ + Type: "object", + AdditionalProperties: &ConfigMetadata{Ref: "./internal/metadata.custom_type"}, + }, + propName: "field", + expected: "map[string]metadata.CustomType", + }, + { + name: "object without additionalProperties or properties", + metadata: &ConfigMetadata{ + Type: "object", + }, + propName: "field", + expected: "map[string]any", + }, + { + name: "object with properties", + metadata: &ConfigMetadata{ + Type: "object", + Properties: map[string]*ConfigMetadata{ + "name": {Type: "string"}, + }, + }, + propName: "my_config", + expected: "MyConfig", + }, + { + name: "map of arrays of objects", + metadata: &ConfigMetadata{ + Type: "object", + AdditionalProperties: &ConfigMetadata{ + Type: "array", + Items: &ConfigMetadata{ + Type: "object", + Properties: map[string]*ConfigMetadata{ + "id": {Type: "integer"}, + }, + }, + }, + }, + propName: "field", + expected: "map[string][]FieldItem", + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + result, err := MapGoType(tt.metadata, tt.propName, "", compPkg) + require.NoError(t, err) + require.Equal(t, tt.expected, result) + }) + } +} + +func TestMapGoType_CustomTypes(t *testing.T) { + tests := []struct { + name string + metadata *ConfigMetadata + expected string + }{ + { + name: "custom type with basic type", + metadata: &ConfigMetadata{ + Type: "string", + GoType: "rune", + }, + expected: "rune", + }, + { + name: "custom type with external package", + metadata: &ConfigMetadata{ + Type: "object", + GoType: "github.com/example/pkg.CustomType", + }, + expected: "pkg.CustomType", + }, + { + name: "custom type without package", + metadata: &ConfigMetadata{ + Type: "object", + GoType: "my_custom_type", + }, + expected: "MyCustomType", + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + result, err := MapGoType(tt.metadata, "field", "", "") + require.NoError(t, err) + require.Equal(t, tt.expected, result) + }) + } +} + +func TestMapGoType_References(t *testing.T) { + tests := []struct { + name string + ref string + expected string + }{ + { + name: "internal reference", + ref: "my_type", + expected: "MyType", + }, + { + name: "external reference", + ref: "go.opentelemetry.io/collector/component.Config", + expected: "component.Config", + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + md := &ConfigMetadata{ + Ref: tt.ref, + } + result, err := MapGoType(md, "field", "", "") + require.NoError(t, err) + require.Equal(t, tt.expected, result) + }) + } +} + +func TestMapGoType_Modifiers(t *testing.T) { + tests := []struct { + name string + metadata *ConfigMetadata + expected string + }{ + { + name: "optional type", + metadata: &ConfigMetadata{ + Type: "string", + IsOptional: true, + }, + expected: "configoptional.Optional[string]", + }, + { + name: "pointer type", + metadata: &ConfigMetadata{ + Type: "string", + IsPointer: true, + }, + expected: "*string", + }, + { + name: "optional pointer", + metadata: &ConfigMetadata{ + Type: "string", + IsOptional: true, + IsPointer: true, + }, + expected: "configoptional.Optional[*string]", + }, + { + name: "array of pointers", + metadata: &ConfigMetadata{ + Type: "array", + Items: &ConfigMetadata{ + Type: "string", + IsPointer: true, + }, + }, + expected: "[]*string", + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + result, err := MapGoType(tt.metadata, "field", "", "") + require.NoError(t, err) + require.Equal(t, tt.expected, result) + }) + } +} + +func TestMapGoType_NilInput(t *testing.T) { + _, err := MapGoType(nil, "field", "", "") + require.Error(t, err) + require.Contains(t, err.Error(), "nil ConfigMetadata") +} + +func TestMapGoType_UnsupportedType(t *testing.T) { + md := &ConfigMetadata{ + Type: "unsupported_type", + } + _, err := MapGoType(md, "field", "", "") + require.Error(t, err) + require.Contains(t, err.Error(), "unsupported type") +} + +func TestExtractImports_BasicTypes(t *testing.T) { + tests := []struct { + name string + metadata *ConfigMetadata + expected []string + }{ + { + name: "no imports for basic types", + metadata: &ConfigMetadata{Type: "string"}, + expected: []string{}, + }, + { + name: "time import for date-time format", + metadata: &ConfigMetadata{ + Type: "string", + Format: "date-time", + }, + expected: []string{"time"}, + }, + { + name: "time import for duration format", + metadata: &ConfigMetadata{ + Type: "string", + Format: "duration", + }, + expected: []string{"time"}, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + result, err := ExtractImports(tt.metadata, "", "") + require.NoError(t, err) + require.ElementsMatch(t, tt.expected, result) + }) + } +} + +func TestExtractImports_CustomTypes(t *testing.T) { + tests := []struct { + name string + metadata *ConfigMetadata + expected []string + }{ + { + name: "external custom type", + metadata: &ConfigMetadata{ + Type: "object", + GoType: "github.com/example/pkg.CustomType", + }, + expected: []string{"github.com/example/pkg"}, + }, + { + name: "external reference", + metadata: &ConfigMetadata{ + Ref: "go.opentelemetry.io/collector/component.Config", + }, + expected: []string{"go.opentelemetry.io/collector/component"}, + }, + { + name: "no import for internal reference", + metadata: &ConfigMetadata{ + Ref: "my_type", + }, + expected: []string{}, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + result, err := ExtractImports(tt.metadata, "", "") + require.NoError(t, err) + require.ElementsMatch(t, tt.expected, result) + }) + } +} + +func TestExtractImports_LocalRef(t *testing.T) { + rootPkg := "go.opentelemetry.io/collector" + compPkg := "go.opentelemetry.io/collector/scraper/scraperhelper" + + tests := []struct { + name string + metadata *ConfigMetadata + expected []string + }{ + { + name: "local absolute reference", + metadata: &ConfigMetadata{ + Ref: "/config/confighttp.client_config", + }, + expected: []string{"go.opentelemetry.io/collector/config/confighttp"}, + }, + { + name: "local relative reference", + metadata: &ConfigMetadata{ + Ref: "./internal/metadata.custom_type", + }, + expected: []string{"go.opentelemetry.io/collector/scraper/scraperhelper/internal/metadata"}, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + result, err := ExtractImports(tt.metadata, rootPkg, compPkg) + require.NoError(t, err) + require.ElementsMatch(t, tt.expected, result) + }) + } +} + +func TestExtractImports_Optional(t *testing.T) { + md := &ConfigMetadata{ + Type: "string", + IsOptional: true, + } + result, err := ExtractImports(md, "", "") + require.NoError(t, err) + require.Contains(t, result, "go.opentelemetry.io/collector/config/configoptional") +} + +func TestExtractImports_Nested(t *testing.T) { + md := &ConfigMetadata{ + Type: "object", + Properties: map[string]*ConfigMetadata{ + "timeout": { + Type: "string", + Format: "duration", + }, + "nested": { + Type: "object", + Properties: map[string]*ConfigMetadata{ + "timestamp": { + Type: "string", + Format: "date-time", + }, + }, + }, + }, + } + result, err := ExtractImports(md, "", "") + require.NoError(t, err) + require.Contains(t, result, "time") +} + +func TestExtractImports_AllOf(t *testing.T) { + md := &ConfigMetadata{ + Type: "object", + AllOf: []*ConfigMetadata{ + { + Type: "string", + Format: "duration", + }, + }, + } + result, err := ExtractImports(md, "", "") + require.NoError(t, err) + require.Contains(t, result, "time") +} + +func TestExtractImports_ArrayItems(t *testing.T) { + md := &ConfigMetadata{ + Type: "array", + Items: &ConfigMetadata{ + Type: "string", + Format: "date-time", + }, + } + result, err := ExtractImports(md, "", "") + require.NoError(t, err) + require.Contains(t, result, "time") +} + +func TestExtractImports_AdditionalProperties(t *testing.T) { + md := &ConfigMetadata{ + Type: "object", + AdditionalProperties: &ConfigMetadata{ + Type: "string", + Format: "duration", + }, + } + result, err := ExtractImports(md, "", "") + require.NoError(t, err) + require.Contains(t, result, "time") +} + +func TestExtractImports_Defs(t *testing.T) { + md := &ConfigMetadata{ + Type: "object", + Defs: map[string]*ConfigMetadata{ + "CustomType": { + Type: "string", + Format: "date-time", + }, + }, + } + result, err := ExtractImports(md, "", "") + require.NoError(t, err) + require.Contains(t, result, "time") +} + +func TestExtractImports_NilInput(t *testing.T) { + result, err := ExtractImports(nil, "", "") + require.NoError(t, err) + require.Nil(t, result) +} + +func TestFormatTypeName_InternalReferences(t *testing.T) { + tests := []struct { + name string + ref string + expected string + }{ + { + name: "simple name", + ref: "my_type", + expected: "MyType", + }, + { + name: "snake case", + ref: "my_custom_type", + expected: "MyCustomType", + }, + { + name: "already formatted", + ref: "MyType", + expected: "MyType", + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + result, err := FormatTypeName(tt.ref, "", "") + require.NoError(t, err) + require.Equal(t, tt.expected, result) + }) + } +} + +func TestFormatTypeName_ExternalReferences(t *testing.T) { + tests := []struct { + name string + ref string + expected string + }{ + { + name: "full package path", + ref: "go.opentelemetry.io/collector/component.Config", + expected: "component.Config", + }, + { + name: "nested package", + ref: "github.com/example/pkg/subpkg.Type", + expected: "subpkg.Type", + }, + { + name: "type name needs formatting", + ref: "github.com/example/pkg.my_type", + expected: "pkg.MyType", + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + result, err := FormatTypeName(tt.ref, "", "") + require.NoError(t, err) + require.Equal(t, tt.expected, result) + }) + } +} + +func TestFormatTypeName_LocalReferences(t *testing.T) { + rootPkg := "go.opentelemetry.io/collector" + compPkg := "go.opentelemetry.io/collector/scraper/scraperhelper" + + tests := []struct { + name string + ref string + expected string + }{ + { + name: "local absolute", + ref: "/config/confighttp.client_config", + expected: "confighttp.ClientConfig", + }, + { + name: "local relative", + ref: "./internal/metadata.metrics_builder", + expected: "metadata.MetricsBuilder", + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + result, err := FormatTypeName(tt.ref, rootPkg, compPkg) + require.NoError(t, err) + require.Equal(t, tt.expected, result) + }) + } +} + +func TestFormatTypeName_InvalidInput(t *testing.T) { + tests := []struct { + name string + ref string + }{ + { + name: "empty type name after dot", + ref: "github.com/example/pkg.", + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + _, err := FormatTypeName(tt.ref, "", "") + require.Error(t, err) + }) + } +} + +func TestExtractDefs_Basic(t *testing.T) { + md := &ConfigMetadata{ + Type: "object", + Defs: map[string]*ConfigMetadata{ + "CustomType": { + Type: "string", + }, + "AnotherType": { + Type: "integer", + }, + }, + } + + result := ExtractDefs(md) + require.Len(t, result, 2) + require.Contains(t, result, "CustomType") + require.Contains(t, result, "AnotherType") +} + +func TestExtractDefs_NestedDefs(t *testing.T) { + md := &ConfigMetadata{ + Type: "object", + Defs: map[string]*ConfigMetadata{ + "OuterType": { + Type: "object", + Defs: map[string]*ConfigMetadata{ + "InnerType": { + Type: "string", + }, + }, + }, + }, + } + + result := ExtractDefs(md) + require.Len(t, result, 2) + require.Contains(t, result, "OuterType") + require.Contains(t, result, "InnerType") +} + +func TestExtractDefs_EmbeddedObjects(t *testing.T) { + md := &ConfigMetadata{ + Type: "object", + Properties: map[string]*ConfigMetadata{ + "config": { + Type: "object", + Properties: map[string]*ConfigMetadata{ + "name": {Type: "string"}, + }, + }, + }, + } + + result := ExtractDefs(md) + require.Len(t, result, 1) + require.Contains(t, result, "config") + require.Equal(t, "object", result["config"].Type) +} + +func TestExtractDefs_ArrayItems(t *testing.T) { + md := &ConfigMetadata{ + Type: "object", + Properties: map[string]*ConfigMetadata{ + "servers": { + Type: "array", + Items: &ConfigMetadata{ + Type: "object", + Properties: map[string]*ConfigMetadata{ + "host": {Type: "string"}, + }, + }, + }, + }, + } + + result := ExtractDefs(md) + require.Len(t, result, 1) + require.Contains(t, result, "servers_item") + require.Equal(t, "object", result["servers_item"].Type) +} + +func TestExtractDefs_NilInput(t *testing.T) { + result := ExtractDefs(nil) + require.Empty(t, result) +} + +func TestExtractDefs_EmptyInput(t *testing.T) { + md := &ConfigMetadata{ + Type: "object", + } + result := ExtractDefs(md) + require.Empty(t, result) +} + +func TestExtractDefs_AdditionalPropertiesObject(t *testing.T) { + md := &ConfigMetadata{ + Type: "object", + Properties: map[string]*ConfigMetadata{ + // A property of type "object" with no sub-properties triggers the ap check + "extra": {Type: "object"}, + }, + AdditionalProperties: &ConfigMetadata{ + Type: "object", + Properties: map[string]*ConfigMetadata{ + "value": {Type: "integer"}, + }, + }, + } + result := ExtractDefs(md) + require.Contains(t, result, "extra") +} + +func TestNewCfgFns_ExtractImports(t *testing.T) { + fns := NewCfgFns("go.opentelemetry.io/collector", "go.opentelemetry.io/collector/comp") + + extractImports := fns["extractImports"].(func(*ConfigMetadata) []string) + + // nil input returns nil + require.Nil(t, extractImports(nil)) + + // valid input returns imports + md := &ConfigMetadata{Type: "string", Format: "duration"} + result := extractImports(md) + require.Contains(t, result, "time") + + // input with unresolvable GoType: collectImports swallows the error, returns empty slice + errMd := &ConfigMetadata{GoType: "github.com/pkg."} + result = extractImports(errMd) + require.Empty(t, result) +} + +func TestNewCfgFns_ExtractDefs(t *testing.T) { + fns := NewCfgFns("", "") + + extractDefs := fns["extractDefs"].(func(*ConfigMetadata) map[string]*ConfigMetadata) + + // nil input returns nil + require.Nil(t, extractDefs(nil)) + + // valid input + md := &ConfigMetadata{ + Type: "object", + Defs: map[string]*ConfigMetadata{"MyType": {Type: "string"}}, + } + result := extractDefs(md) + require.Contains(t, result, "MyType") +} + +func TestNewCfgFns_MapGoType(t *testing.T) { + fns := NewCfgFns("", "") + + mapGoType := fns["mapGoType"].(func(*ConfigMetadata, string) string) + + // nil input returns "any" + require.Equal(t, "any", mapGoType(nil, "field")) + + // valid input + require.Equal(t, "string", mapGoType(&ConfigMetadata{Type: "string"}, "field")) +} + +func TestNewCfgFns_PublicType(t *testing.T) { + fns := NewCfgFns("", "") + + publicType := fns["publicType"].(func(string) string) + + require.Equal(t, "MyType", publicType("my_type")) + require.Equal(t, "component.Config", publicType("go.opentelemetry.io/collector/component.Config")) +} + +func TestWithCfgFns(t *testing.T) { + base := map[string]any{"existing": "value"} + result := WithCfgFns(base, "", "") + + require.Equal(t, "value", result["existing"]) + require.Contains(t, result, "mapGoType") + require.Contains(t, result, "extractImports") + require.Contains(t, result, "extractDefs") + require.Contains(t, result, "publicType") +} + +func TestResolveGoType_CustomTypeFormatError(t *testing.T) { + // GoType with invalid empty type name after dot triggers FormatTypeName error + md := &ConfigMetadata{GoType: "github.com/pkg."} + _, err := MapGoType(md, "field", "", "") + require.Error(t, err) + require.Contains(t, err.Error(), "failed to format custom type") +} + +func TestResolveGoType_RefFormatError(t *testing.T) { + // Ref with invalid empty type name after dot triggers FormatTypeName error + md := &ConfigMetadata{Ref: "github.com/pkg."} + _, err := MapGoType(md, "field", "", "") + require.Error(t, err) + require.Contains(t, err.Error(), "failed to format reference type") +} + +func TestResolveGoType_ArrayItemError(t *testing.T) { + // Array whose item type fails to resolve + md := &ConfigMetadata{ + Type: "array", + Items: &ConfigMetadata{Type: "unsupported_array_item"}, + } + _, err := MapGoType(md, "field", "", "") + require.Error(t, err) + require.Contains(t, err.Error(), "failed to map array item type") +} + +func TestResolveGoType_AdditionalPropertiesError(t *testing.T) { + // Object with additionalProperties whose type fails to resolve + md := &ConfigMetadata{ + Type: "object", + AdditionalProperties: &ConfigMetadata{Type: "unsupported_value"}, + } + _, err := MapGoType(md, "field", "", "") + require.Error(t, err) + require.Contains(t, err.Error(), "failed to map additionalProperties type") +} + +func TestResolveGoType_EmbeddedObjectNameError(t *testing.T) { + // Object with properties but propName that cannot be formatted as an identifier + md := &ConfigMetadata{ + Type: "object", + Properties: map[string]*ConfigMetadata{ + "x": {Type: "string"}, + }, + } + _, err := MapGoType(md, "", "", "") + require.Error(t, err) + require.Contains(t, err.Error(), "failed to format embedded object type name") +} + +func TestExtractImports_PropError(t *testing.T) { + // A property with an invalid GoType propagates the error through collectImports + md := &ConfigMetadata{ + Type: "object", + Properties: map[string]*ConfigMetadata{ + "bad": {GoType: "github.com/pkg.", Type: "object"}, + }, + } + // collectImports swallows ResolveGoTypeRef errors (err == nil check), so no error expected; + // this exercises the properties loop path + _, err := ExtractImports(md, "", "") + require.NoError(t, err) +} + +func TestExtractImports_ItemsPath(t *testing.T) { + md := &ConfigMetadata{ + Type: "array", + Items: &ConfigMetadata{ + Type: "string", + IsOptional: true, + }, + } + result, err := ExtractImports(md, "", "") + require.NoError(t, err) + require.Contains(t, result, "go.opentelemetry.io/collector/config/configoptional") +} + +func TestExtractImports_DefsPath(t *testing.T) { + md := &ConfigMetadata{ + Defs: map[string]*ConfigMetadata{ + "T": { + Type: "string", + IsOptional: true, + }, + }, + } + result, err := ExtractImports(md, "", "") + require.NoError(t, err) + require.Contains(t, result, "go.opentelemetry.io/collector/config/configoptional") +} + +func TestExtractImports_ContentSchema(t *testing.T) { + md := &ConfigMetadata{ + ContentSchema: &ConfigMetadata{ + Type: "string", + Format: "duration", + }, + } + result, err := ExtractImports(md, "", "") + require.NoError(t, err) + require.Contains(t, result, "time") +} diff --git a/cmd/mdatagen/internal/cfggen/loader.go b/cmd/mdatagen/internal/cfggen/loader.go new file mode 100644 index 000000000000..e9020e2d0c84 --- /dev/null +++ b/cmd/mdatagen/internal/cfggen/loader.go @@ -0,0 +1,227 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +package cfggen // import "go.opentelemetry.io/collector/cmd/mdatagen/internal/cfggen" + +import ( + "errors" + "fmt" + "io" + "log" + "net/http" + "os" + "os/exec" + "path/filepath" + "strings" + "time" + + "go.yaml.in/yaml/v3" + "golang.org/x/tools/go/packages" +) + +const ( + schemaFileName = "config.schema.yaml" +) + +// ErrNotFound indicates a schema was not found by any source. +var ErrNotFound = errors.New("schema not found") + +// Loader loads configuration metadata from various sources (file, HTTP). +type Loader interface { + Load(ref Ref) (*ConfigMetadata, error) +} + +type schemaLoader struct { + cache map[string]*ConfigMetadata + cd string + rootDir string + httpClient *http.Client +} + +// NewLoader creates a fully configured loader. Takes current component's directory to determine where to look for local schema files. +func NewLoader(cwd string) Loader { + return &schemaLoader{ + cache: make(map[string]*ConfigMetadata), + cd: cwd, + httpClient: &http.Client{Timeout: 30 * time.Second}, + } +} + +func (sl *schemaLoader) Load(ref Ref) (*ConfigMetadata, error) { + if cached, ok := sl.cache[ref.CacheKey()]; ok { + return cached, nil + } + + metadata, err := sl.load(ref) + if err != nil { + return nil, err + } + + sl.cache[ref.CacheKey()] = metadata + return metadata, nil +} + +func (sl *schemaLoader) load(ref Ref) (*ConfigMetadata, error) { + repoRoot, err := sl.repoRoot(sl.cd) + if err != nil { + return nil, fmt.Errorf("failed to determine repo root: %w", err) + } + + if ref.isLocal() { + var filePath string + if strings.HasPrefix(ref.schemaID, "/") { + filePath = filepath.Join(repoRoot, ref.SchemaID(), schemaFileName) + } else { + filePath = filepath.Join(sl.cd, ref.SchemaID(), schemaFileName) + } + return sl.loadFromFile(filePath) + } + + return sl.loadFromHTTP(ref, filepath.Join(repoRoot, ".schemas")) +} + +func (sl *schemaLoader) loadFromFile(filePath string) (*ConfigMetadata, error) { + body, err := os.ReadFile(filePath) // #nosec G304 + if err != nil { + if os.IsNotExist(err) { + return nil, ErrNotFound + } + return nil, fmt.Errorf("failed to read schema from %s: %w", filePath, err) + } + + var metadata ConfigMetadata + if err := yaml.Unmarshal(body, &metadata); err != nil { + return nil, fmt.Errorf("failed to parse schema from %s: %w", filePath, err) + } + + return &metadata, nil +} + +func (sl *schemaLoader) loadFromHTTP(ref Ref, fileCacheDir string) (*ConfigMetadata, error) { + version, err := sl.refVersion(&ref) + if err != nil { + return nil, err + } + filePath := filepath.Join(fileCacheDir, version, filepath.FromSlash(ref.SchemaID()), schemaFileName) + // check fs cache first + metadata, err := sl.loadFromFile(filePath) + if err == nil { + return metadata, nil + } + if !errors.Is(err, ErrNotFound) { + log.Printf("warning: failed to load schema from file cache at %s: %v", filePath, err) + } + metadata, err = sl.tryLoad(ref, version) + if err != nil { + return nil, err + } + if err := sl.persistToFile(filePath, metadata); err != nil { + log.Printf("warning: failed to persist schema to file cache at %s: %v", filePath, err) + } + return metadata, nil +} + +func (sl *schemaLoader) tryLoad(ref Ref, version string) (*ConfigMetadata, error) { + url, err := ref.URL(version) + if err != nil { + return nil, fmt.Errorf("failed to construct URL for %s: %w", ref.CacheKey(), err) + } + + resp, err := sl.httpClient.Get(url) + if err != nil { + return nil, fmt.Errorf("failed to fetch schema from %s: %w", url, err) + } + defer resp.Body.Close() + + if resp.StatusCode == http.StatusNotFound { + return nil, ErrNotFound + } + if resp.StatusCode != http.StatusOK { + return nil, fmt.Errorf("failed to fetch schema from %s: HTTP %d", url, resp.StatusCode) + } + + body, err := io.ReadAll(resp.Body) + if err != nil { + return nil, fmt.Errorf("failed to read response body from %s: %w", url, err) + } + + var metadata ConfigMetadata + if err := yaml.Unmarshal(body, &metadata); err != nil { + return nil, fmt.Errorf("failed to parse schema from %s: %w", url, err) + } + + return &metadata, nil +} + +func (sl *schemaLoader) persistToFile(filePath string, md *ConfigMetadata) error { + if err := os.MkdirAll(filepath.Dir(filePath), 0o750); err != nil { + return fmt.Errorf("failed to create directory: %w", err) + } + + data, err := yaml.Marshal(md) + if err != nil { + return fmt.Errorf("failed to marshal metadata: %w", err) + } + + if err := os.WriteFile(filePath, data, 0o600); err != nil { + return fmt.Errorf("failed to write file: %w", err) + } + + return nil +} + +func (sl *schemaLoader) refVersion(ref *Ref) (string, error) { + // Try to resolve version via packages.Load (respects replace directives) + modulePath := ref.Module() + if modulePath != "" { + if version := sl.resolveModuleVersion(modulePath); version != "" { + return version, nil + } + // attempt to "go get" the module to resolve version if not found locally + cmd := exec.Command("go", "get", modulePath) // #nosec G204 + cmd.Dir = sl.cd + + if err := cmd.Run(); err != nil { + return "", fmt.Errorf("failed to run `go get` for module %s: %w", modulePath, err) + } + if version := sl.resolveModuleVersion(modulePath); version != "" { + return version, nil + } + return "", fmt.Errorf("unable to resolve version for module %s after `go get`: %w", modulePath, ErrNotFound) + } + return "", fmt.Errorf("unknown module path for `%s` ref", ref) +} + +func (sl *schemaLoader) resolveModuleVersion(importPath string) string { + cfg := &packages.Config{ + Mode: packages.NeedModule, + Dir: sl.cd, + } + pkgs, err := packages.Load(cfg, importPath) + if err != nil || len(pkgs) == 0 { + return "" + } + + pkg := pkgs[0] + if pkg.Module == nil { + return "" + } + + return pkg.Module.Version +} + +func (sl *schemaLoader) repoRoot(componentDir string) (string, error) { + if sl.rootDir != "" { + return sl.rootDir, nil + } + + cmd := exec.Command("git", "rev-parse", "--show-toplevel") + cmd.Dir = componentDir + output, err := cmd.Output() + if err != nil { + return "", fmt.Errorf("failed to determine repo root: %w", err) + } + sl.rootDir = strings.TrimSpace(string(output)) + + return sl.rootDir, nil +} diff --git a/cmd/mdatagen/internal/cfggen/loader_test.go b/cmd/mdatagen/internal/cfggen/loader_test.go new file mode 100644 index 000000000000..d1231bd78cdc --- /dev/null +++ b/cmd/mdatagen/internal/cfggen/loader_test.go @@ -0,0 +1,556 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +package cfggen + +import ( + "net/http" + "net/http/httptest" + "os" + "path/filepath" + "runtime" + "strings" + "testing" + "time" + + "github.com/stretchr/testify/require" +) + +func TestLoader_LoadFromFile_Success(t *testing.T) { + tempDir := t.TempDir() + + // Create schema file - for a local ref + schemaPath := filepath.Join(tempDir, "internal/metadata") + require.NoError(t, os.MkdirAll(schemaPath, 0o750)) + schemaFile := filepath.Join(schemaPath, schemaFileName) + schemaContent := `title: "Test Schema" +description: "A test schema" +type: object +` + require.NoError(t, os.WriteFile(schemaFile, []byte(schemaContent), 0o600)) + + loader := NewLoader(tempDir).(*schemaLoader) + + // For local refs, the loadFromFile method takes a file path + result, err := loader.loadFromFile(schemaFile) + require.NoError(t, err) + require.Equal(t, "Test Schema", result.Title) + require.Equal(t, "A test schema", result.Description) + require.Equal(t, "object", result.Type) +} + +func TestLoader_LoadFromFile_NotFound(t *testing.T) { + tempDir := t.TempDir() + loader := NewLoader(tempDir).(*schemaLoader) + + // Try to load from non-existent file + result, err := loader.loadFromFile(filepath.Join(tempDir, "nonexistent", schemaFileName)) + require.ErrorIs(t, err, ErrNotFound) + require.Nil(t, result) +} + +func TestLoader_LoadFromFile_ParseError(t *testing.T) { + tempDir := t.TempDir() + + // Create invalid YAML file + schemaPath := filepath.Join(tempDir, "test/path") + require.NoError(t, os.MkdirAll(schemaPath, 0o750)) + schemaFile := filepath.Join(schemaPath, schemaFileName) + invalidYAML := `title: "Test" + invalid: yaml: content: +` + require.NoError(t, os.WriteFile(schemaFile, []byte(invalidYAML), 0o600)) + + loader := NewLoader(tempDir).(*schemaLoader) + + result, err := loader.loadFromFile(schemaFile) + require.Error(t, err) + require.Contains(t, err.Error(), "failed to parse schema") + require.Nil(t, result) +} + +func TestLoader_LoadFromHTTP_Success(t *testing.T) { + // Create test HTTP server + server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) { + w.WriteHeader(http.StatusOK) + _, _ = w.Write([]byte(`title: "HTTP Schema" +type: string +`)) + })) + defer server.Close() + + // Override namespaceToURL for testing + originalURL := namespaceToURL["go.opentelemetry.io/collector"] + namespaceToURL["go.opentelemetry.io/collector"] = server.URL + defer func() { namespaceToURL["go.opentelemetry.io/collector"] = originalURL }() + + tempDir := t.TempDir() + // Use mdatagenDir so resolveModuleVersion can find the module in go.mod + loader := NewLoader(mdatagenDir(t)).(*schemaLoader) + ref := *NewRef("go.opentelemetry.io/collector/scraper/scraperhelper.controller_config") + + result, err := loader.loadFromHTTP(ref, filepath.Join(tempDir, ".schemas")) + require.NoError(t, err) + require.Equal(t, "HTTP Schema", result.Title) + require.Equal(t, "string", result.Type) +} + +func TestLoader_LoadFromHTTP_NotFound(t *testing.T) { + server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) { + w.WriteHeader(http.StatusNotFound) + })) + defer server.Close() + + originalURL := namespaceToURL["go.opentelemetry.io/collector"] + namespaceToURL["go.opentelemetry.io/collector"] = server.URL + defer func() { namespaceToURL["go.opentelemetry.io/collector"] = originalURL }() + + tempDir := t.TempDir() + loader := NewLoader(mdatagenDir(t)).(*schemaLoader) + ref := *NewRef("go.opentelemetry.io/collector/scraper/scraperhelper.controller_config") + + result, err := loader.loadFromHTTP(ref, filepath.Join(tempDir, ".schemas")) + require.ErrorIs(t, err, ErrNotFound) + require.Nil(t, result) +} + +func TestLoader_LoadFromHTTP_ServerError(t *testing.T) { + server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) { + w.WriteHeader(http.StatusInternalServerError) + })) + defer server.Close() + + originalURL := namespaceToURL["go.opentelemetry.io/collector"] + namespaceToURL["go.opentelemetry.io/collector"] = server.URL + defer func() { namespaceToURL["go.opentelemetry.io/collector"] = originalURL }() + + tempDir := t.TempDir() + loader := NewLoader(mdatagenDir(t)).(*schemaLoader) + ref := *NewRef("go.opentelemetry.io/collector/scraper/scraperhelper.controller_config") + + result, err := loader.loadFromHTTP(ref, filepath.Join(tempDir, ".schemas")) + require.Error(t, err) + require.Contains(t, err.Error(), "HTTP 500") + require.Nil(t, result) +} + +func TestLoader_TryLoad_WithVersion(t *testing.T) { + // Create test HTTP server that returns different content for different versions + server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + w.WriteHeader(http.StatusOK) + if strings.Contains(r.URL.Path, "v1.0.0") { + _, _ = w.Write([]byte(`title: "Versioned Schema"`)) + } else { + _, _ = w.Write([]byte(`title: "Main Version Schema"`)) + } + })) + defer server.Close() + + originalURL := namespaceToURL["go.opentelemetry.io/collector"] + namespaceToURL["go.opentelemetry.io/collector"] = server.URL + defer func() { namespaceToURL["go.opentelemetry.io/collector"] = originalURL }() + + tempDir := t.TempDir() + loader := NewLoader(tempDir).(*schemaLoader) + ref := *NewRef("go.opentelemetry.io/collector/test/path.config") + + // Try to load with version + result, err := loader.tryLoad(ref, "v1.0.0") + require.NoError(t, err) + require.Equal(t, "Versioned Schema", result.Title) +} + +func TestLoader_PersistToFile_Success(t *testing.T) { + tempDir := t.TempDir() + loader := NewLoader(tempDir).(*schemaLoader) + + metadata := &ConfigMetadata{ + Title: "Persisted Schema", + Description: "Test persistence", + } + + filePath := filepath.Join(tempDir, "test", "persisted.yaml") + err := loader.persistToFile(filePath, metadata) + require.NoError(t, err) + + // Verify file was created + require.FileExists(t, filePath) + + content, err := os.ReadFile(filePath) // #nosec G304 + require.NoError(t, err) + require.Contains(t, string(content), "Persisted Schema") + require.Contains(t, string(content), "Test persistence") +} + +func TestLoader_Load_CacheInteraction(t *testing.T) { + tempDir := t.TempDir() + + loader := NewLoader(tempDir).(*schemaLoader) + ref := *NewRef("go.opentelemetry.io/collector/test/path.config") + + expected := &ConfigMetadata{Title: "Pre-cached Schema"} + loader.cache[ref.CacheKey()] = expected + + result, err := loader.Load(ref) + require.NoError(t, err) + require.Equal(t, expected, result) + require.Same(t, expected, result) +} + +func TestLoader_Integration_MemoryCachePeristence(t *testing.T) { + tempDir := t.TempDir() + + loader := &schemaLoader{ + cache: make(map[string]*ConfigMetadata), + cd: tempDir, + httpClient: &http.Client{Timeout: 30 * time.Second}, + } + + ref := *NewRef("go.opentelemetry.io/collector/test/path.config") + expected := &ConfigMetadata{Title: "Integration Test"} + + loader.cache[ref.CacheKey()] = expected + + result1, err := loader.Load(ref) + require.NoError(t, err) + require.Equal(t, "Integration Test", result1.Title) + + result2, err := loader.Load(ref) + require.NoError(t, err) + require.Equal(t, "Integration Test", result2.Title) + + require.Same(t, result1, result2) +} + +func TestLoader_Load_CachesOnFirstLoad(t *testing.T) { + tempDir := t.TempDir() + + schemaPath := filepath.Join(tempDir, "subdir") + require.NoError(t, os.MkdirAll(schemaPath, 0o750)) + schemaFile := filepath.Join(schemaPath, schemaFileName) + require.NoError(t, os.WriteFile(schemaFile, []byte("title: Cached\ntype: object\n"), 0o600)) + + loader := NewLoader(tempDir).(*schemaLoader) + loader.rootDir = tempDir // bypass git + + ref := Ref{schemaID: "subdir", kind: Local} + + result1, err := loader.Load(ref) + require.NoError(t, err) + require.Equal(t, "Cached", result1.Title) + + result2, err := loader.Load(ref) + require.NoError(t, err) + require.Same(t, result1, result2) +} + +func TestLoader_Load_RepoRootError(t *testing.T) { + tempDir := t.TempDir() + loader := NewLoader(tempDir).(*schemaLoader) + + ref := Ref{schemaID: "subdir", kind: Local} + _, err := loader.load(ref) + require.Error(t, err) + require.Contains(t, err.Error(), "failed to determine repo root") +} + +func TestLoader_Load_LocalAbsolutePath(t *testing.T) { + tempDir := t.TempDir() + + // Create schema at /somepackage/config.schema.yaml + schemaDir := filepath.Join(tempDir, "somepackage") + require.NoError(t, os.MkdirAll(schemaDir, 0o750)) + require.NoError(t, os.WriteFile(filepath.Join(schemaDir, schemaFileName), []byte("title: AbsoluteLocal\ntype: object\n"), 0o600)) + + loader := NewLoader(tempDir).(*schemaLoader) + loader.rootDir = tempDir // bypass git + + // absolute local ref (starts with /) + ref := Ref{schemaID: "/somepackage", kind: Local} + result, err := loader.load(ref) + require.NoError(t, err) + require.Equal(t, "AbsoluteLocal", result.Title) +} + +func TestLoader_Load_LocalRelativePath(t *testing.T) { + tempDir := t.TempDir() + subDir := filepath.Join(tempDir, "subdir") + require.NoError(t, os.MkdirAll(subDir, 0o750)) + require.NoError(t, os.WriteFile(filepath.Join(subDir, schemaFileName), []byte("title: RelativeLocal\ntype: object\n"), 0o600)) + + loader := NewLoader(tempDir).(*schemaLoader) + loader.rootDir = tempDir // bypass git + + // relative local ref (does not start with /) + ref := Ref{schemaID: "subdir", kind: Local} + result, err := loader.load(ref) + require.NoError(t, err) + require.Equal(t, "RelativeLocal", result.Title) +} + +func TestLoader_LoadFromFile_ReadError(t *testing.T) { + // Create a directory where the file is expected — os.ReadFile on a directory fails + tempDir := t.TempDir() + dirPath := filepath.Join(tempDir, schemaFileName) + require.NoError(t, os.MkdirAll(dirPath, 0o750)) + + loader := NewLoader(tempDir).(*schemaLoader) + result, err := loader.loadFromFile(dirPath) + require.Error(t, err) + require.Nil(t, result) + require.NotErrorIs(t, err, ErrNotFound) + require.Contains(t, err.Error(), "failed to read schema") +} + +func TestLoader_LoadFromHTTP_FileCacheHit(t *testing.T) { + // Test that loadFromHTTP returns from the file cache when a schema is already persisted, + // without making any HTTP requests. + ref := *NewRef("go.opentelemetry.io/collector/scraper/scraperhelper.controller_config") + + // Resolve the real module version so we can place the file at the right path. + mdDir := mdatagenDir(t) + helper := NewLoader(mdDir).(*schemaLoader) + version := helper.resolveModuleVersion(ref.Module()) + if version == "" { + t.Skip("could not resolve module version, skipping file cache hit test") + } + + tempDir := t.TempDir() + fileCacheDir := filepath.Join(tempDir, ".schemas") + filePath := filepath.Join(fileCacheDir, version, ref.SchemaID(), schemaFileName) + require.NoError(t, os.MkdirAll(filepath.Dir(filePath), 0o750)) + require.NoError(t, os.WriteFile(filePath, []byte("title: FileCached\ntype: object\n"), 0o600)) + + // Use an httpClient that always panics to confirm no HTTP call is made. + loader := &schemaLoader{ + cache: make(map[string]*ConfigMetadata), + cd: mdDir, + httpClient: &http.Client{}, + } + + result, err := loader.loadFromHTTP(ref, fileCacheDir) + require.NoError(t, err) + require.Equal(t, "FileCached", result.Title) +} + +func TestLoader_LoadFromHTTP_PersistWarning(t *testing.T) { + // Test the warning path when persistToFile fails (non-writable dir). + // We create a read-only file cache dir so persistToFile fails. + if runtime.GOOS == "windows" { + t.Skip("file permission test not reliable on Windows") + } + + server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) { + w.WriteHeader(http.StatusOK) + _, _ = w.Write([]byte("title: PersistFail\ntype: object\n")) + })) + defer server.Close() + + originalURL := namespaceToURL["go.opentelemetry.io/collector"] + namespaceToURL["go.opentelemetry.io/collector"] = server.URL + defer func() { namespaceToURL["go.opentelemetry.io/collector"] = originalURL }() + + tempDir := t.TempDir() + + // Make the file cache directory read-only so persistToFile fails + cacheDir := filepath.Join(tempDir, ".schemas") + require.NoError(t, os.MkdirAll(cacheDir, 0o750)) + + loader := NewLoader(mdatagenDir(t)).(*schemaLoader) + ref := *NewRef("go.opentelemetry.io/collector/scraper/scraperhelper.controller_config") + + // Should still return the result even though persist fails (warning only) + result, err := loader.loadFromHTTP(ref, cacheDir) + require.NoError(t, err) + require.Equal(t, "PersistFail", result.Title) +} + +func TestLoader_LoadFromHTTP_NonNotFoundFileError(t *testing.T) { + // Test the log.Printf warning path in loadFromHTTP when loadFromFile on the cached path + // fails with a non-ErrNotFound error (directory placed where file is expected). + server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) { + w.WriteHeader(http.StatusOK) + _, _ = w.Write([]byte("title: AfterWarning\ntype: object\n")) + })) + defer server.Close() + + originalURL := namespaceToURL["go.opentelemetry.io/collector"] + namespaceToURL["go.opentelemetry.io/collector"] = server.URL + defer func() { namespaceToURL["go.opentelemetry.io/collector"] = originalURL }() + + mdDir := mdatagenDir(t) + ref := *NewRef("go.opentelemetry.io/collector/scraper/scraperhelper.controller_config") + + // Resolve the real version so we can poison the file cache at the correct path + helper := NewLoader(mdDir).(*schemaLoader) + version := helper.resolveModuleVersion(ref.Module()) + if version == "" { + t.Skip("could not resolve module version, skipping non-ErrNotFound warning test") + } + + tempDir := t.TempDir() + cacheDir := filepath.Join(tempDir, ".schemas") + filePath := filepath.Join(cacheDir, version, ref.SchemaID(), schemaFileName) + // Place a directory at the expected file path → loadFromFile returns a non-ErrNotFound error + require.NoError(t, os.MkdirAll(filePath, 0o750)) + + loader := &schemaLoader{ + cache: make(map[string]*ConfigMetadata), + cd: mdDir, + httpClient: &http.Client{}, + } + + result, err := loader.loadFromHTTP(ref, cacheDir) + require.NoError(t, err) + require.Equal(t, "AfterWarning", result.Title) +} + +func TestLoader_TryLoad_URLError(t *testing.T) { + // Ref with unsupported namespace → URL() returns an error + loader := NewLoader("").(*schemaLoader) + ref := *NewRef("unknownns/path.type") + // namespace is set so Module() returns non-empty, but Namespace() returns false + // Actually NewRef sets it as external; let's manually set up a ref with no URL support + ref2 := Ref{namespace: "unsupported.example.com", schemaID: "pkg", defName: "t", kind: External} + _, err := loader.tryLoad(ref2, "v1.0.0") + require.Error(t, err) + require.Contains(t, err.Error(), "failed to construct URL") + _ = ref +} + +func TestLoader_TryLoad_HTTPError(t *testing.T) { + // Use a server that closes connections immediately to simulate a network error + // The simplest approach: use an invalid URL + loader := NewLoader("").(*schemaLoader) + + ref := *NewRef("go.opentelemetry.io/collector/test/path.config") + + // Override the URL to point to an invalid host + originalURL := namespaceToURL["go.opentelemetry.io/collector"] + namespaceToURL["go.opentelemetry.io/collector"] = "http://127.0.0.1:0" // port 0 → connection refused + defer func() { namespaceToURL["go.opentelemetry.io/collector"] = originalURL }() + + _, err := loader.tryLoad(ref, "v1.0.0") + require.Error(t, err) + require.Contains(t, err.Error(), "failed to fetch schema") +} + +func TestLoader_TryLoad_ParseError(t *testing.T) { + server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) { + w.WriteHeader(http.StatusOK) + _, _ = w.Write([]byte("title: bad\n invalid: yaml: :\n")) + })) + defer server.Close() + + originalURL := namespaceToURL["go.opentelemetry.io/collector"] + namespaceToURL["go.opentelemetry.io/collector"] = server.URL + defer func() { namespaceToURL["go.opentelemetry.io/collector"] = originalURL }() + + loader := NewLoader("").(*schemaLoader) + ref := *NewRef("go.opentelemetry.io/collector/test/path.config") + _, err := loader.tryLoad(ref, "v1.0.0") + require.Error(t, err) + require.Contains(t, err.Error(), "failed to parse schema") +} + +func TestLoader_RefVersion_UnknownModulePath(t *testing.T) { + tempDir := t.TempDir() + loader := NewLoader(tempDir).(*schemaLoader) + + ref := Ref{namespace: "", schemaID: "pkg", defName: "t", kind: Internal} + _, err := loader.refVersion(&ref) + require.Error(t, err) + require.Contains(t, err.Error(), "unknown module path") +} + +func TestLoader_ResolveModuleVersion_NilModule(t *testing.T) { + loader := NewLoader(mdatagenDir(t)).(*schemaLoader) + + version := loader.resolveModuleVersion("fmt") + require.Empty(t, version) +} + +func TestLoader_ResolveModuleVersion_LoadError(t *testing.T) { + loader := NewLoader("/nonexistent/path/xyz").(*schemaLoader) + + version := loader.resolveModuleVersion("somemodule/that/doesnt/exist") + require.Empty(t, version) +} + +func TestLoader_RepoRoot_CachedValue(t *testing.T) { + loader := NewLoader("").(*schemaLoader) + loader.rootDir = "/cached/root" + + root, err := loader.repoRoot("/any/dir") + require.NoError(t, err) + require.Equal(t, "/cached/root", root) +} + +func TestLoader_RepoRoot_GitError(t *testing.T) { + tempDir := t.TempDir() + loader := NewLoader(tempDir).(*schemaLoader) + + _, err := loader.repoRoot(tempDir) + require.Error(t, err) + require.Contains(t, err.Error(), "failed to determine repo root") +} + +func TestLoader_PersistToFile_MkdirAllError(t *testing.T) { + if runtime.GOOS == "windows" { + t.Skip("file permission test not reliable on Windows") + } + tempDir := t.TempDir() + t.Cleanup(func() { + _ = os.Chmod(tempDir, 0o700) // #nosec G302 -- restore so t.TempDir cleanup can remove it + }) + + require.NoError(t, os.Chmod(tempDir, 0o500)) // #nosec G302 + + loader := NewLoader(tempDir).(*schemaLoader) + err := loader.persistToFile(filepath.Join(tempDir, "newdir", "schema.yaml"), &ConfigMetadata{Title: "X"}) + require.Error(t, err) + require.Contains(t, err.Error(), "failed to create directory") +} + +func TestLoader_PersistToFile_WriteFileError(t *testing.T) { + tempDir := t.TempDir() + + filePath := filepath.Join(tempDir, "schema.yaml") + require.NoError(t, os.MkdirAll(filePath, 0o750)) + + loader := NewLoader(tempDir).(*schemaLoader) + err := loader.persistToFile(filePath, &ConfigMetadata{Title: "X"}) + require.Error(t, err) + require.Contains(t, err.Error(), "failed to write file") +} + +func TestLoader_TryLoad_ReadBodyError(t *testing.T) { + server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) { + w.Header().Set("Content-Length", "1000") + w.WriteHeader(http.StatusOK) + hj, ok := w.(http.Hijacker) + if !ok { + return + } + conn, _, _ := hj.Hijack() + _ = conn.Close() + })) + defer server.Close() + + originalURL := namespaceToURL["go.opentelemetry.io/collector"] + namespaceToURL["go.opentelemetry.io/collector"] = server.URL + defer func() { namespaceToURL["go.opentelemetry.io/collector"] = originalURL }() + + loader := NewLoader("").(*schemaLoader) + ref := *NewRef("go.opentelemetry.io/collector/test/path.config") + _, err := loader.tryLoad(ref, "v1.0.0") + require.Error(t, err) + require.Contains(t, err.Error(), "failed to read response body") +} + +func mdatagenDir(t *testing.T) string { + t.Helper() + _, file, _, ok := runtime.Caller(0) + require.True(t, ok, "could not determine caller file") + return filepath.Join(filepath.Dir(file), "../..") +} diff --git a/cmd/mdatagen/internal/cfggen/model.go b/cmd/mdatagen/internal/cfggen/model.go new file mode 100644 index 000000000000..eaed6211bde4 --- /dev/null +++ b/cmd/mdatagen/internal/cfggen/model.go @@ -0,0 +1,68 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +package cfggen // import "go.opentelemetry.io/collector/cmd/mdatagen/internal/cfggen" + +import ( + "encoding/json" + "errors" + "fmt" +) + +// ConfigMetadata represents a JSON schema object, draft 2020-12 (limited), with additional custom fields. +type ConfigMetadata struct { + Schema string `mapstructure:"$schema,omitempty" json:"$schema,omitempty" yaml:"$schema,omitempty"` + ID string `mapstructure:"$id,omitempty" json:"$id,omitempty" yaml:"$id,omitempty"` + Title string `mapstructure:"title,omitempty" json:"title,omitempty" yaml:"title,omitempty"` + Description string `mapstructure:"description,omitempty" json:"description,omitempty" yaml:"description,omitempty"` + Comment string `mapstructure:"$comment,omitempty" json:"$comment,omitempty" yaml:"$comment,omitempty"` + Type any `mapstructure:"type,omitempty" json:"type,omitempty" yaml:"type,omitempty"` + Ref string `mapstructure:"$ref,omitempty" json:"-" yaml:"$ref,omitempty"` + Default any `mapstructure:"default,omitempty" json:"default,omitempty" yaml:"default,omitempty"` + Examples []any `mapstructure:"examples,omitempty" json:"examples,omitempty" yaml:"examples,omitempty"` + Deprecated bool `mapstructure:"deprecated,omitempty" json:"deprecated,omitempty" yaml:"deprecated,omitempty"` + Enum []any `mapstructure:"enum,omitempty" json:"enum,omitempty" yaml:"enum,omitempty"` + Const any `mapstructure:"const,omitempty" json:"const,omitempty" yaml:"const,omitempty"` + AllOf []*ConfigMetadata `mapstructure:"allOf,omitempty" json:"allOf,omitempty" yaml:"allOf,omitempty"` + Properties map[string]*ConfigMetadata `mapstructure:"properties,omitempty" json:"properties,omitempty" yaml:"properties,omitempty"` + AdditionalProperties *ConfigMetadata `mapstructure:"additionalProperties,omitempty" json:"additionalProperties,omitempty" yaml:"additionalProperties,omitempty"` + Required []string `mapstructure:"required,omitempty" json:"required,omitempty" yaml:"required,omitempty"` + MinProperties *int `mapstructure:"minProperties,omitempty" json:"minProperties,omitempty" yaml:"minProperties,omitempty"` + MaxProperties *int `mapstructure:"maxProperties,omitempty" json:"maxProperties,omitempty" yaml:"maxProperties,omitempty"` + Items *ConfigMetadata `mapstructure:"items,omitempty" json:"items,omitempty" yaml:"items,omitempty"` + MinItems *int `mapstructure:"minItems,omitempty" json:"minItems,omitempty" yaml:"minItems,omitempty"` + MaxItems *int `mapstructure:"maxItems,omitempty" json:"maxItems,omitempty" yaml:"maxItems,omitempty"` + UniqueItems bool `mapstructure:"uniqueItems,omitempty" json:"uniqueItems,omitempty" yaml:"uniqueItems,omitempty"` + MaxLength *int `mapstructure:"maxLength,omitempty" json:"maxLength,omitempty" yaml:"maxLength,omitempty"` + MinLength *int `mapstructure:"minLength,omitempty" json:"minLength,omitempty" yaml:"minLength,omitempty"` + Pattern string `mapstructure:"pattern,omitempty" json:"pattern,omitempty" yaml:"pattern,omitempty"` + Format string `mapstructure:"format,omitempty" json:"format,omitempty" yaml:"format,omitempty"` + ContentMediaType string `mapstructure:"contentMediaType,omitempty" json:"contentMediaType,omitempty" yaml:"contentMediaType,omitempty"` + ContentEncoding string `mapstructure:"contentEncoding,omitempty" json:"contentEncoding,omitempty" yaml:"contentEncoding,omitempty"` + ContentSchema *ConfigMetadata `mapstructure:"contentSchema,omitempty" json:"contentSchema,omitempty" yaml:"contentSchema,omitempty"` + MultipleOf *float64 `mapstructure:"multipleOf,omitempty" json:"multipleOf,omitempty" yaml:"multipleOf,omitempty"` + Maximum *float64 `mapstructure:"maximum,omitempty" json:"maximum,omitempty" yaml:"maximum,omitempty"` + ExclusiveMaximum *float64 `mapstructure:"exclusiveMaximum,omitempty" json:"exclusiveMaximum,omitempty" yaml:"exclusiveMaximum,omitempty"` + Minimum *float64 `mapstructure:"minimum,omitempty" json:"minimum,omitempty" yaml:"minimum,omitempty"` + ExclusiveMinimum *float64 `mapstructure:"exclusiveMinimum,omitempty" json:"exclusiveMinimum,omitempty" yaml:"exclusiveMinimum,omitempty"` + Defs map[string]*ConfigMetadata `mapstructure:"$defs,omitempty" json:"-" yaml:"$defs,omitempty"` + // Additional custom fields + GoType string `mapstructure:"x-customType,omitempty" json:"-" yaml:"x-customType,omitempty"` + IsPointer bool `mapstructure:"x-pointer,omitempty" json:"-" yaml:"x-pointer,omitempty"` + IsOptional bool `mapstructure:"x-optional,omitempty" json:"-" yaml:"x-optional,omitempty"` +} + +func (md *ConfigMetadata) ToJSON() ([]byte, error) { + return json.MarshalIndent(md, "", " ") +} + +func (md *ConfigMetadata) Validate() error { + var errs error + if md.Type != "object" { + errs = errors.Join(errs, fmt.Errorf("config type must be \"object\", got %q", md.Type)) + } + if len(md.Properties) == 0 && len(md.AllOf) == 0 { + errs = errors.Join(errs, errors.New("config must not be empty")) + } + return errs +} diff --git a/cmd/mdatagen/internal/cfggen/model_test.go b/cmd/mdatagen/internal/cfggen/model_test.go new file mode 100644 index 000000000000..e0bb01e6d67c --- /dev/null +++ b/cmd/mdatagen/internal/cfggen/model_test.go @@ -0,0 +1,327 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +package cfggen + +import ( + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func TestConfigMetadata_ToJSON(t *testing.T) { + md := &ConfigMetadata{ + Schema: schemaVersion, + Type: "object", + Properties: map[string]*ConfigMetadata{ + "endpoint": {Type: "string", Description: "The endpoint"}, + }, + } + + data, err := md.ToJSON() + require.NoError(t, err) + assert.Contains(t, string(data), `"$schema"`) + assert.Contains(t, string(data), `"endpoint"`) + assert.Contains(t, string(data), `"The endpoint"`) +} + +func TestConfigMetadata_Validate_Valid(t *testing.T) { + tests := []struct { + name string + md *ConfigMetadata + }{ + { + name: "valid with properties", + md: &ConfigMetadata{ + Type: "object", + Properties: map[string]*ConfigMetadata{ + "endpoint": {Type: "string"}, + }, + }, + }, + { + name: "valid with allOf", + md: &ConfigMetadata{ + Type: "object", + AllOf: []*ConfigMetadata{ + {Ref: "some_ref"}, + }, + }, + }, + { + name: "valid with both properties and allOf", + md: &ConfigMetadata{ + Type: "object", + Properties: map[string]*ConfigMetadata{ + "endpoint": {Type: "string"}, + }, + AllOf: []*ConfigMetadata{ + {Ref: "some_ref"}, + }, + }, + }, + { + name: "valid with multiple properties", + md: &ConfigMetadata{ + Type: "object", + Properties: map[string]*ConfigMetadata{ + "endpoint": {Type: "string"}, + "timeout": {Type: "string", GoType: "time.Duration"}, + "port": {Type: "integer"}, + }, + }, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + err := tt.md.Validate() + assert.NoError(t, err) + }) + } +} + +func TestConfigMetadata_Validate_InvalidType(t *testing.T) { + tests := []struct { + name string + md *ConfigMetadata + wantErr string + }{ + { + name: "type is string instead of object", + md: &ConfigMetadata{ + Type: "string", + Properties: map[string]*ConfigMetadata{ + "endpoint": {Type: "string"}, + }, + }, + wantErr: `config type must be "object", got "string"`, + }, + { + name: "type is empty string", + md: &ConfigMetadata{ + Type: "", + Properties: map[string]*ConfigMetadata{ + "endpoint": {Type: "string"}, + }, + }, + wantErr: `config type must be "object", got ""`, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + err := tt.md.Validate() + require.Error(t, err) + assert.Contains(t, err.Error(), tt.wantErr) + }) + } +} + +func TestConfigMetadata_Validate_EmptyConfig(t *testing.T) { + tests := []struct { + name string + md *ConfigMetadata + wantErr string + }{ + { + name: "no properties and no allOf", + md: &ConfigMetadata{ + Type: "object", + }, + wantErr: "config must not be empty", + }, + { + name: "empty properties map and no allOf", + md: &ConfigMetadata{ + Type: "object", + Properties: map[string]*ConfigMetadata{}, + }, + wantErr: "config must not be empty", + }, + { + name: "empty allOf slice and no properties", + md: &ConfigMetadata{ + Type: "object", + AllOf: []*ConfigMetadata{}, + }, + wantErr: "config must not be empty", + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + err := tt.md.Validate() + require.Error(t, err) + assert.Contains(t, err.Error(), tt.wantErr) + }) + } +} + +func TestConfigMetadata_Validate_MultipleErrors(t *testing.T) { + tests := []struct { + name string + md *ConfigMetadata + wantErrCount int + wantErrContains []string + }{ + { + name: "invalid type and empty config", + md: &ConfigMetadata{ + Type: "string", + }, + wantErrCount: 2, + wantErrContains: []string{ + `config type must be "object", got "string"`, + "config must not be empty", + }, + }, + { + name: "invalid type with empty properties and empty allOf", + md: &ConfigMetadata{ + Type: "array", + Properties: map[string]*ConfigMetadata{}, + AllOf: []*ConfigMetadata{}, + }, + wantErrCount: 2, + wantErrContains: []string{ + `config type must be "object", got "array"`, + "config must not be empty", + }, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + err := tt.md.Validate() + require.Error(t, err) + + // Check that error contains all expected substrings + for _, expectedErr := range tt.wantErrContains { + assert.Contains(t, err.Error(), expectedErr) + } + }) + } +} + +func TestConfigMetadata_Validate_NilMetadata(t *testing.T) { + var md *ConfigMetadata + // The current implementation panics on nil receiver + // This test documents that behavior + assert.Panics(t, func() { + _ = md.Validate() + }, "Validate() should panic when called on nil ConfigMetadata") +} + +func TestConfigMetadata_Validate_TypeAsInterface(t *testing.T) { + // Test when Type field is set as interface{} instead of string + // This tests the real-world scenario where YAML/JSON unmarshaling + // might produce different types + tests := []struct { + name string + typeVal any + wantErr bool + }{ + { + name: "type as string 'object'", + typeVal: "object", + wantErr: false, + }, + { + name: "type as string 'string'", + typeVal: "string", + wantErr: true, + }, + { + name: "type as array of strings (union type) - not supported", + typeVal: []any{"object", "null"}, + wantErr: true, // Current implementation doesn't handle union types, treats as invalid + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + md := &ConfigMetadata{ + Type: tt.typeVal, + Properties: map[string]*ConfigMetadata{ + "field": {Type: "string"}, + }, + } + + err := md.Validate() + if tt.wantErr { + assert.Error(t, err) + } else { + assert.NoError(t, err) + } + }) + } +} + +func TestConfigMetadata_Validate_EdgeCases(t *testing.T) { + tests := []struct { + name string + md *ConfigMetadata + wantErr bool + }{ + { + name: "single property is sufficient", + md: &ConfigMetadata{ + Type: "object", + Properties: map[string]*ConfigMetadata{ + "only_field": {Type: "string"}, + }, + }, + wantErr: false, + }, + { + name: "single allOf entry is sufficient", + md: &ConfigMetadata{ + Type: "object", + AllOf: []*ConfigMetadata{ + {Ref: "base_config"}, + }, + }, + wantErr: false, + }, + { + name: "properties with nested objects", + md: &ConfigMetadata{ + Type: "object", + Properties: map[string]*ConfigMetadata{ + "server": { + Type: "object", + Properties: map[string]*ConfigMetadata{ + "host": {Type: "string"}, + "port": {Type: "integer"}, + }, + }, + }, + }, + wantErr: false, + }, + { + name: "allOf with nil entries", + md: &ConfigMetadata{ + Type: "object", + AllOf: []*ConfigMetadata{ + nil, + {Ref: "base_config"}, + }, + }, + wantErr: false, // At least one non-nil entry exists + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + err := tt.md.Validate() + if tt.wantErr { + assert.Error(t, err) + } else { + assert.NoError(t, err) + } + }) + } +} diff --git a/cmd/mdatagen/internal/cfggen/namespace.go b/cmd/mdatagen/internal/cfggen/namespace.go new file mode 100644 index 000000000000..a49ba8b0fa61 --- /dev/null +++ b/cmd/mdatagen/internal/cfggen/namespace.go @@ -0,0 +1,197 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +package cfggen // import "go.opentelemetry.io/collector/cmd/mdatagen/internal/cfggen" + +import ( + "errors" + "fmt" + "maps" + "path" + "regexp" + "slices" + "strings" +) + +var namespaceToURL = map[string]string{ + "go.opentelemetry.io/collector": "https://raw.githubusercontent.com/open-telemetry/opentelemetry-collector", + "github.com/open-telemetry/opentelemetry-collector-contrib": "https://raw.githubusercontent.com/open-telemetry/opentelemetry-collector-contrib", +} + +var supportedNamespaces = slices.Collect(maps.Keys(namespaceToURL)) + +type RefKind int + +const ( + External RefKind = iota + Internal + Local +) + +type Ref struct { + namespace string + schemaID string + defName string + kind RefKind +} + +var localRefPattern = regexp.MustCompile(`^((?:/|\.\.?/).*?)(?:\.([^./]+))?$`) + +func NewRef(refPath string) *Ref { + var namespace, schemaID, defName string + var kind RefKind + + switch { + case localRefPattern.MatchString(refPath): + matches := localRefPattern.FindStringSubmatch(refPath) + schemaID = matches[1] + defName = matches[2] + kind = Local + case !strings.ContainsRune(refPath, '/'): + defName = refPath + kind = Internal + default: + namespace = namespaceOf(refPath) + rest, _ := strings.CutPrefix(refPath, namespace) + schemaID, defName, _ = strings.Cut(rest, ".") + schemaID = strings.Trim(schemaID, "/") + kind = External + } + + return &Ref{ + namespace, + schemaID, + defName, + kind, + } +} + +func WithOrigin(refPath string, origin *Ref) *Ref { + ref := NewRef(refPath) + if origin != nil { + if origin.isExternal() { + ref.namespace = origin.namespace + ref.kind = External + if !strings.HasPrefix(ref.schemaID, "/") { + ref.schemaID = path.Join(origin.schemaID, ref.schemaID) + } else { + ref.schemaID = strings.Trim(ref.schemaID, "/") + } + } + } + return ref +} + +func namespaceOf(path string) string { + if ns, ok := matchSupportedNamespace(path); ok { + return ns + } + if idx := strings.LastIndex(path, "/"); idx != -1 { + return path[:idx] + } + return "" +} + +func matchSupportedNamespace(path string) (string, bool) { + for _, ns := range supportedNamespaces { + if strings.HasPrefix(path, ns) { + return ns, true + } + } + return "", false +} + +func (r *Ref) Namespace() (string, bool) { + _, ok := matchSupportedNamespace(r.namespace) + return r.namespace, ok +} + +func (r *Ref) Module() string { + if r.namespace != "" { + return r.namespace + "/" + r.schemaID + } + return "" +} + +func (r *Ref) SchemaID() string { + return r.schemaID +} + +func (r *Ref) DefName() string { + return r.defName +} + +func (r *Ref) URL(version string) (string, error) { + ns, ok := r.Namespace() + if !ok { + return "", errors.New("unsupported namespace") + } + baseURL := namespaceToURL[ns] + return fmt.Sprintf("%s/%s/%s/%s", + baseURL, + version, + r.SchemaID(), + schemaFileName), + nil +} + +func (r *Ref) isInternal() bool { + return r.kind == Internal +} + +func (r *Ref) isLocal() bool { + return r.kind == Local +} + +func (r *Ref) isExternal() bool { + return r.kind == External +} + +func (r *Ref) Validate() error { + if r.String() == "" { + return errors.New("empty path") + } + + if r.defName == "" { + return errors.New("missing definition name") + } + if r.isInternal() || r.isLocal() { + if r.isLocal() && r.schemaID == "" { + return errors.New("missing schema ID in local reference") + } + } + + return nil +} + +func (r *Ref) String() string { + var sb strings.Builder + if r.namespace != "" { + sb.WriteString(r.namespace) + } + if r.schemaID != "" { + if sb.Len() > 0 { + sb.WriteRune('/') + } + sb.WriteString(r.schemaID) + } + if r.defName != "" { + if sb.Len() > 0 { + sb.WriteRune('.') + } + sb.WriteString(r.defName) + } + + return sb.String() +} + +func (r *Ref) CacheKey() string { + return r.String() +} + +func LocalizeRef(refPath, importRootPath string) string { + if importRootPath == "" || !strings.HasPrefix(refPath, importRootPath+"/") { + return refPath + } + return strings.TrimPrefix(refPath, importRootPath) +} diff --git a/cmd/mdatagen/internal/cfggen/namespace_test.go b/cmd/mdatagen/internal/cfggen/namespace_test.go new file mode 100644 index 000000000000..21f0df73d19f --- /dev/null +++ b/cmd/mdatagen/internal/cfggen/namespace_test.go @@ -0,0 +1,369 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +package cfggen + +import ( + "testing" + + "github.com/stretchr/testify/require" +) + +func TestNewRef(t *testing.T) { + tests := []struct { + name string + refPath string + expected *Ref + }{ + { + name: "empty ref", + refPath: "", + expected: &Ref{ + namespace: "", + schemaID: "", + defName: "", + kind: Internal, + }, + }, + { + name: "internal ref", + refPath: "target_type", + expected: &Ref{ + namespace: "", + schemaID: "", + defName: "target_type", + kind: Internal, + }, + }, + { + name: "local ref with absolute path", + refPath: "/config/configauth.config", + expected: &Ref{ + namespace: "", + schemaID: "/config/configauth", + defName: "config", + kind: Local, + }, + }, + { + name: "local ref with relative path (./)", + refPath: "./internal/metadata.config", + expected: &Ref{ + namespace: "", + schemaID: "./internal/metadata", + defName: "config", + kind: Local, + }, + }, + { + name: "local ref with relative path (../)", + refPath: "../other.config", + expected: &Ref{ + namespace: "", + schemaID: "../other", + defName: "config", + kind: Local, + }, + }, + { + name: "local ref without def name", + refPath: "/config/configauth", + expected: &Ref{ + namespace: "", + schemaID: "/config/configauth", + defName: "", + kind: Local, + }, + }, + { + name: "local ref empty", + refPath: "../", + expected: &Ref{ + namespace: "", + schemaID: "../", + defName: "", + kind: Local, + }, + }, + { + name: "local ref empty short schemaId", + refPath: "../.test", + expected: &Ref{ + namespace: "", + schemaID: "../", + defName: "test", + kind: Local, + }, + }, + { + name: "external ref without version", + refPath: "go.opentelemetry.io/collector/config/confighttp.client_config", + expected: &Ref{ + namespace: "go.opentelemetry.io/collector", + schemaID: "config/confighttp", + defName: "client_config", + kind: External, + }, + }, + { + name: "external ref without def name", + refPath: "go.opentelemetry.io/collector/config/confighttp", + expected: &Ref{ + namespace: "go.opentelemetry.io/collector", + schemaID: "config/confighttp", + defName: "", + kind: External, + }, + }, + { + name: "external ref without schema ID", + refPath: "go.opentelemetry.io/collector", + expected: &Ref{ + namespace: "go.opentelemetry.io/collector", + schemaID: "", + defName: "", + kind: External, + }, + }, + { + name: "unknown namespace", + refPath: "com.github.example/custom.xyz", + expected: &Ref{ + namespace: "com.github.example", + schemaID: "custom", + defName: "xyz", + kind: External, + }, + }, + { + name: "ref with wrong format", + refPath: "some/path.with.dots", + expected: &Ref{ + namespace: "some", + schemaID: "path", + defName: "with.dots", + kind: External, + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + result := NewRef(tt.refPath) + require.Equal(t, tt.expected, result) + }) + } +} + +func TestWithOrigin(t *testing.T) { + tests := []struct { + name string + refPath string + origin string + expected string + }{ + { + name: "absolute ref resolves against namespace", + refPath: "/config/configauth.config", + origin: "go.opentelemetry.io/collector/config/confighttp", + expected: "go.opentelemetry.io/collector/config/configauth.config", + }, + { + name: "absolute ref with empty origin unchanged", + refPath: "/config/configauth.config", + origin: "", + expected: "/config/configauth.config", + }, + { + name: "relative ref resolves against module path", + refPath: "./internal/metadata.config", + origin: "go.opentelemetry.io/collector/config/confighttp", + expected: "go.opentelemetry.io/collector/config/confighttp/internal/metadata.config", + }, + { + name: "parent relative ref resolves against parent module", + refPath: "../configtls.tls_config", + origin: "go.opentelemetry.io/collector/config/confighttp", + expected: "go.opentelemetry.io/collector/config/configtls.tls_config", + }, + { + name: "external ref with same-namespace origin joins schema IDs", + refPath: "go.opentelemetry.io/collector/config/confighttp.client_config", + origin: "go.opentelemetry.io/collector/config/confighttp", + expected: "go.opentelemetry.io/collector/config/confighttp/config/confighttp.client_config", + }, + { + name: "internal ref with origin unchanged", + refPath: "target_type", + origin: "go.opentelemetry.io/collector/config/confighttp", + expected: "go.opentelemetry.io/collector/config/confighttp.target_type", + }, + { + name: "no version propagated when origin has no version", + refPath: "/config/configauth.config", + origin: "go.opentelemetry.io/collector/config/confighttp", + expected: "go.opentelemetry.io/collector/config/configauth.config", + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + ref := WithOrigin(tt.refPath, NewRef(tt.origin)) + require.Equal(t, tt.expected, ref.CacheKey()) + }) + } +} + +func TestRef_Validate(t *testing.T) { + tests := []struct { + name string + refPath string + wantErr bool + }{ + { + name: "valid collector reference", + refPath: "go.opentelemetry.io/collector/scraper/scraperhelper.controller_config", + wantErr: false, + }, + { + name: "valid contrib reference", + refPath: "github.com/open-telemetry/opentelemetry-collector-contrib/receiver/mysqlreceiver.config", + wantErr: false, + }, + { + name: "valid internal reference", + refPath: "target_type", + wantErr: false, + }, + { + name: "valid local absolute reference", + refPath: "/config/configauth.config", + wantErr: false, + }, + { + name: "empty path", + refPath: "", + wantErr: true, + }, + { + name: "missing def name", + refPath: "/config/configauth", + wantErr: true, + }, + { + name: "missing schema ID with external ref", + refPath: "go.opentelemetry.io/collector", + wantErr: true, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + ref := NewRef(tt.refPath) + err := ref.Validate() + if tt.wantErr { + require.Error(t, err) + } else { + require.NoError(t, err) + } + }) + } +} + +func TestRef_URL(t *testing.T) { + tests := []struct { + name string + refPath string + version string + expected string + }{ + { + name: "collector reference", + refPath: "go.opentelemetry.io/collector/scraper/scraperhelper.controller_config", + version: "v1.0.0", + expected: "https://raw.githubusercontent.com/open-telemetry/opentelemetry-collector/v1.0.0/scraper/scraperhelper/config.schema.yaml", + }, + { + name: "contrib reference", + refPath: "github.com/open-telemetry/opentelemetry-collector-contrib/receiver/mysqlreceiver.config", + version: "v0.95.0", + expected: "https://raw.githubusercontent.com/open-telemetry/opentelemetry-collector-contrib/v0.95.0/receiver/mysqlreceiver/config.schema.yaml", + }, + { + name: "main version", + refPath: "go.opentelemetry.io/collector/processor/batchprocessor.config", + version: "main", + expected: "https://raw.githubusercontent.com/open-telemetry/opentelemetry-collector/main/processor/batchprocessor/config.schema.yaml", + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + ref := NewRef(tt.refPath) + result, err := ref.URL(tt.version) + require.NoError(t, err) + require.Equal(t, tt.expected, result) + }) + } +} + +func TestRef_String(t *testing.T) { + ref := NewRef("go.opentelemetry.io/collector/config/confighttp.client_config") + require.Equal(t, "go.opentelemetry.io/collector/config/confighttp.client_config", ref.String()) +} + +func TestRef_Module_EmptyNamespace(t *testing.T) { + ref := NewRef("target_type") + require.Empty(t, ref.Module()) +} + +func TestRef_URL_UnsupportedNamespace(t *testing.T) { + ref := NewRef("unsupported.example.com/pkg/sub.config") + _, err := ref.URL("v1.0.0") + require.Error(t, err) + require.Contains(t, err.Error(), "unsupported namespace") +} + +func TestRef_Validate_LocalRefMissingSchemaID(t *testing.T) { + ref := &Ref{schemaID: "", defName: "config", kind: Local} + err := ref.Validate() + require.Error(t, err) + require.Contains(t, err.Error(), "missing schema ID in local reference") +} + +func TestNamespaceOf_FallbackLastSlash(t *testing.T) { + result := namespaceOf("com.example/some/path.type") + require.Equal(t, "com.example/some", result) +} + +func TestNamespaceOf_NoSlash(t *testing.T) { + result := namespaceOf("noslash") + require.Empty(t, result) +} + +func TestLocalizeRef(t *testing.T) { + tests := []struct { + name string + refPath string + importRootPath string + expected string + }{ + { + name: "same root collector ref becomes local absolute", + refPath: "go.opentelemetry.io/collector/filter.config", + importRootPath: "go.opentelemetry.io/collector", + expected: "/filter.config", + }, + { + name: "different root ref stays external", + refPath: "go.opentelemetry.io/collector/filter.config", + importRootPath: "github.com/open-telemetry/opentelemetry-collector-contrib", + expected: "go.opentelemetry.io/collector/filter.config", + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + require.Equal(t, tt.expected, LocalizeRef(tt.refPath, tt.importRootPath)) + }) + } +} diff --git a/cmd/mdatagen/internal/cfggen/resolver.go b/cmd/mdatagen/internal/cfggen/resolver.go new file mode 100644 index 000000000000..142d91f0f3d5 --- /dev/null +++ b/cmd/mdatagen/internal/cfggen/resolver.go @@ -0,0 +1,231 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +package cfggen // import "go.opentelemetry.io/collector/cmd/mdatagen/internal/cfggen" + +import ( + "fmt" + "reflect" + "strings" +) + +const ( + schemaVersion = "https://json-schema.org/draft/2020-12/schema" + // goDurationPattern matches Go duration strings (e.g., "30s", "1h30m", "500ms") + goDurationPattern = `^([0-9]+(\.[0-9]+)?(ns|us|µs|ms|s|m|h))+$` +) + +type Resolver struct { + pkgID string + class string + name string + loader Loader +} + +func NewResolver(pkgID, class, name, dir string) *Resolver { + loader := NewLoader(dir) + + return &Resolver{ + loader: loader, + pkgID: pkgID, + class: class, + name: name, + } +} + +// ResolveSchema takes a source configuration metadata schema and resolves all references ($ref) +// to produce a fully resolved schema. It handles both internal references (within the same schema) and external references +// (pointing to other schemas, either locally or remotely). The resolver uses registered loaders to fetch external schemas as needed. +// +// Returns a new ConfigMetadata with all references resolved, or an error if resolution fails. +func (r *Resolver) ResolveSchema(src *ConfigMetadata) (*ConfigMetadata, error) { + target := &ConfigMetadata{} + err := r.resolveSchema(src, src, target, nil) + if err != nil { + return nil, err + } + + target.Schema = schemaVersion + target.ID = r.pkgID + target.Title = fmt.Sprintf("%s/%s", r.class, r.name) + + return target, nil +} + +// transformDurationFormat converts JSON Schema format: duration to Go duration pattern. +// JSON Schema duration format expects ISO 8601 (e.g., "PT30S"), but Go uses a different +// format (e.g., "30s", "1h30m"). This function replaces the format with a pattern that +// validates Go duration strings. +func transformDurationFormat(md *ConfigMetadata) { + if md.Type == "string" && md.Format == "duration" { + md.Format = "" + md.Pattern = goDurationPattern + if md.Description != "" && !strings.Contains(md.Description, "duration") { + md.Description += " (duration format, e.g., \"30s\", \"1h30m\")" + } + } +} + +func (r *Resolver) resolveSchema(root, current, target *ConfigMetadata, origin *Ref) error { + if current.Ref != "" { + resolved, err := r.resolveRef(root, current, origin) + if err != nil { + return fmt.Errorf("failed to resolve $ref %q: %w", current.Ref, err) + } + + // Preserve custom extensions defined on the reference node + customGoType := current.GoType + customIsPointer := current.IsPointer + customIsOptional := current.IsOptional + customDescription := current.Description + customDefault := current.Default + customEnum := current.Enum + + // Copy the resolved node + newCurrent := *resolved + + // Restore custom extensions if they were explicitly set on the reference + if customGoType != "" { + newCurrent.GoType = customGoType + } + if customIsPointer { + newCurrent.IsPointer = customIsPointer + } + if customIsOptional { + newCurrent.IsOptional = customIsOptional + } + if customDescription != "" { + newCurrent.Description = customDescription + } + if customDefault != nil { + newCurrent.Default = customDefault + } + if len(customEnum) > 0 { + newCurrent.Enum = customEnum + } + + current = &newCurrent + } + + currRef := reflect.ValueOf(current).Elem() + targetRef := reflect.ValueOf(target).Elem() + + for i := 0; i < currRef.NumField(); i++ { + field := currRef.Field(i) + targetField := targetRef.Field(i) + + if !targetField.CanSet() { + continue + } + + switch field.Kind() { + case reflect.Ptr: + if !field.IsNil() && field.Elem().Kind() == reflect.Struct { + if field.Type() == reflect.TypeFor[*ConfigMetadata]() { + newMeta := &ConfigMetadata{} + if err := r.resolveSchema(root, field.Interface().(*ConfigMetadata), newMeta, origin); err != nil { + return err + } + targetField.Set(reflect.ValueOf(newMeta)) + } + } + case reflect.Map: + if field.Type().Elem() == reflect.TypeFor[*ConfigMetadata]() { + newMap := reflect.MakeMap(field.Type()) + iter := field.MapRange() + for iter.Next() { + key := iter.Key() + value := iter.Value() + if !value.IsNil() { + newMeta := &ConfigMetadata{} + if err := r.resolveSchema(root, value.Interface().(*ConfigMetadata), newMeta, origin); err != nil { + return err + } + newMap.SetMapIndex(key, reflect.ValueOf(newMeta)) + } + } + targetField.Set(newMap) + } else { + targetField.Set(field) + } + case reflect.Slice: + if field.Type().Elem() == reflect.TypeFor[*ConfigMetadata]() { + newSlice := reflect.MakeSlice(field.Type(), field.Len(), field.Len()) + for j := 0; j < field.Len(); j++ { + elem := field.Index(j) + if !elem.IsNil() { + newMeta := &ConfigMetadata{} + if err := r.resolveSchema(root, elem.Interface().(*ConfigMetadata), newMeta, origin); err != nil { + return err + } + newSlice.Index(j).Set(reflect.ValueOf(newMeta)) + } + } + targetField.Set(newSlice) + } else { + targetField.Set(field) + } + default: + targetField.Set(field) + } + } + transformDurationFormat(target) + target.Defs = nil // Clear defs after resolution to avoid confusion + return nil +} + +// resolveRef resolves a JSON Schema $ref, handling both internal and external references. +// The origin parameter tracks which namespace the current schema was loaded from, +// enabling local refs in remotely-fetched schemas to be converted to external refs. +func (r *Resolver) resolveRef(root, current *ConfigMetadata, origin *Ref) (*ConfigMetadata, error) { + ref := WithOrigin(current.Ref, origin) + + if err := ref.Validate(); err != nil { + return nil, fmt.Errorf("invalid reference format %q: %w", current.Ref, err) + } + + if ref.isInternal() { + if root.Defs != nil { + if val, ok := root.Defs[ref.DefName()]; ok { + return val, nil + } + } + } + + if ref.isLocal() { + return r.loadExternalRef(ref) + } + + // check if it's in known namespace + if _, ok := ref.Namespace(); ok { + return r.loadExternalRef(ref) + } + + // fallback to type "any" + current.GoType = current.Ref + current.Comment = "Uses `any` type." + return current, nil +} + +// loadExternalRef uses SchemaLoader to load external references +func (r *Resolver) loadExternalRef(ref *Ref) (*ConfigMetadata, error) { + md, err := r.loader.Load(*ref) + if err != nil { + return nil, err + } + if md == nil { + return nil, fmt.Errorf("no loader could resolve external reference: %s", ref) + } + + if md.Defs != nil { + if def, ok := md.Defs[ref.DefName()]; ok { + resolved := &ConfigMetadata{} + if err := r.resolveSchema(md, def, resolved, ref); err != nil { + return nil, fmt.Errorf("failed to resolve internal references in external schema %s: %w", ref, err) + } + return resolved, nil + } + } + + return nil, fmt.Errorf("type %q not found in loaded schema for reference %s", ref.DefName(), ref) +} diff --git a/cmd/mdatagen/internal/cfggen/resolver_test.go b/cmd/mdatagen/internal/cfggen/resolver_test.go new file mode 100644 index 000000000000..c130a83e0d3c --- /dev/null +++ b/cmd/mdatagen/internal/cfggen/resolver_test.go @@ -0,0 +1,1155 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +package cfggen + +import ( + "fmt" + "testing" + + "github.com/stretchr/testify/require" +) + +func TestResolver_ResolveSchema_BasicMetadata(t *testing.T) { + resolver := &Resolver{ + pkgID: "go.opentelemetry.io/collector/receiver/otlpreceiver", + class: "receiver", + name: "otlp", + loader: NewLoader(""), + } + + src := &ConfigMetadata{ + Description: "OTLP receiver configuration", + Type: "object", + } + + result, err := resolver.ResolveSchema(src) + require.NoError(t, err) + require.Equal(t, schemaVersion, result.Schema) + require.Equal(t, "go.opentelemetry.io/collector/receiver/otlpreceiver", result.ID) + require.Equal(t, "receiver/otlp", result.Title) + require.Equal(t, "OTLP receiver configuration", result.Description) + require.Equal(t, "object", result.Type) +} + +func TestResolver_ResolveSchema_InternalReference(t *testing.T) { + resolver := &Resolver{ + pkgID: "go.opentelemetry.io/collector/test/component", + class: "receiver", + name: "test", + loader: NewLoader(""), + } + + src := &ConfigMetadata{ + Type: "object", + Properties: map[string]*ConfigMetadata{ + "config": { + Ref: "target_type", + }, + }, + Defs: map[string]*ConfigMetadata{ + "target_type": { + Type: "string", + Description: "Target type description", + }, + }, + } + + result, err := resolver.ResolveSchema(src) + require.NoError(t, err) + require.Equal(t, "object", result.Type) + require.NotNil(t, result.Properties["config"]) + require.Equal(t, "string", result.Properties["config"].Type) + require.Equal(t, "Target type description", result.Properties["config"].Description) +} + +func TestResolver_ResolveSchema_UnknownInternalReference(t *testing.T) { + resolver := &Resolver{ + pkgID: "go.opentelemetry.io/collector/test/component", + class: "receiver", + name: "test", + loader: NewLoader(""), + } + + src := &ConfigMetadata{ + Type: "object", + Properties: map[string]*ConfigMetadata{ + "config": { + Ref: "unknown_type", + }, + }, + } + + // Should use "any" type because the internal reference doesn't exist + result, err := resolver.ResolveSchema(src) + require.NoError(t, err) + require.Nil(t, result.Properties["config"].Type) +} + +func TestResolver_ResolveSchema_NestedStructures(t *testing.T) { + resolver := &Resolver{ + pkgID: "go.opentelemetry.io/collector/test/component", + class: "receiver", + name: "test", + loader: NewLoader(""), + } + + src := &ConfigMetadata{ + Type: "object", + Properties: map[string]*ConfigMetadata{ + "nested": { + Type: "object", + Properties: map[string]*ConfigMetadata{ + "field1": { + Type: "string", + }, + "field2": { + Type: "integer", + }, + }, + }, + }, + } + + result, err := resolver.ResolveSchema(src) + require.NoError(t, err) + require.Equal(t, "object", result.Type) + require.NotNil(t, result.Properties["nested"]) + require.Equal(t, "object", result.Properties["nested"].Type) + require.NotNil(t, result.Properties["nested"].Properties["field1"]) + require.Equal(t, "string", result.Properties["nested"].Properties["field1"].Type) + require.NotNil(t, result.Properties["nested"].Properties["field2"]) + require.Equal(t, "integer", result.Properties["nested"].Properties["field2"].Type) +} + +func TestResolver_ResolveSchema_AllOf(t *testing.T) { + resolver := &Resolver{ + pkgID: "go.opentelemetry.io/collector/test/component", + class: "receiver", + name: "test", + loader: NewLoader(""), + } + + src := &ConfigMetadata{ + Type: "object", + AllOf: []*ConfigMetadata{ + { + Type: "object", + Properties: map[string]*ConfigMetadata{ + "field1": {Type: "string"}, + }, + }, + { + Type: "object", + Properties: map[string]*ConfigMetadata{ + "field2": {Type: "integer"}, + }, + }, + }, + } + + result, err := resolver.ResolveSchema(src) + require.NoError(t, err) + require.Len(t, result.AllOf, 2) + require.NotNil(t, result.AllOf[0].Properties["field1"]) + require.NotNil(t, result.AllOf[1].Properties["field2"]) +} + +func TestResolver_ResolveSchema_ArrayItems(t *testing.T) { + resolver := &Resolver{ + pkgID: "go.opentelemetry.io/collector/test/component", + class: "receiver", + name: "test", + loader: NewLoader(""), + } + + src := &ConfigMetadata{ + Type: "array", + Items: &ConfigMetadata{ + Type: "object", + Properties: map[string]*ConfigMetadata{ + "name": {Type: "string"}, + }, + }, + } + + result, err := resolver.ResolveSchema(src) + require.NoError(t, err) + require.Equal(t, "array", result.Type) + require.NotNil(t, result.Items) + require.Equal(t, "object", result.Items.Type) + require.NotNil(t, result.Items.Properties["name"]) +} + +func TestResolver_LoadExternalRef_Success(t *testing.T) { + ml := &mockLoader{ + schemas: map[string]*ConfigMetadata{ + "go.opentelemetry.io/collector/scraper/scraperhelper.controller_config": { + Type: "object", + Defs: map[string]*ConfigMetadata{ + "controller_config": { + Type: "object", + Properties: map[string]*ConfigMetadata{ + "timeout": { + Type: "string", + }, + }, + }, + }, + }, + }, + } + + resolver := &Resolver{ + pkgID: "go.opentelemetry.io/collector/test/component", + class: "receiver", + name: "test", + loader: ml, + } + + ref := NewRef("go.opentelemetry.io/collector/scraper/scraperhelper.controller_config") + result, err := resolver.loadExternalRef(ref) + require.NoError(t, err) + require.Equal(t, "object", result.Type) + require.NotNil(t, result.Properties["timeout"]) + require.Equal(t, "string", result.Properties["timeout"].Type) +} + +func TestResolver_LoadExternalRef_InvalidPath(t *testing.T) { + resolver := &Resolver{ + pkgID: "go.opentelemetry.io/collector/test/component", + class: "receiver", + name: "test", + loader: NewLoader(""), + } + + ref := NewRef("invalid/path/without/namespace") + result, err := resolver.loadExternalRef(ref) + require.Error(t, err) + require.Nil(t, result) +} + +func TestResolver_LoadExternalRef_TypeNotFound(t *testing.T) { + ml := &mockLoader{ + schemas: map[string]*ConfigMetadata{ + "go.opentelemetry.io/collector/scraper/scraperhelper.controller_config": { + Type: "object", + Defs: map[string]*ConfigMetadata{ + "other_type": { + Type: "string", + }, + }, + }, + }, + } + + resolver := &Resolver{ + pkgID: "go.opentelemetry.io/collector/test/component", + class: "receiver", + name: "test", + loader: ml, + } + + ref := NewRef("go.opentelemetry.io/collector/scraper/scraperhelper.controller_config") + result, err := resolver.loadExternalRef(ref) + require.Error(t, err) + require.Contains(t, err.Error(), "type \"controller_config\" not found") + require.Nil(t, result) +} + +func TestResolver_IsExternalRef(t *testing.T) { + tests := []struct { + name string + ref string + expected bool + }{ + { + name: "collector external ref - known namespace", + ref: "go.opentelemetry.io/collector/scraper/scraperhelper.controller_config", + expected: true, + }, + { + name: "contrib external ref - known namespace", + ref: "github.com/open-telemetry/opentelemetry-collector-contrib/receiver/mysqlreceiver.config", + expected: true, + }, + { + name: "relative path - local not external", + ref: "./internal/metadata.metrics_builder_config", + expected: false, + }, + { + name: "internal ref - simple name", + ref: "target_type", + expected: false, + }, + { + name: "unsupported namespace - still external (not internal/local)", + ref: "github.com/example/custom.config", + expected: true, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + r := NewRef(tt.ref) + result := r.isExternal() + require.Equal(t, tt.expected, result) + }) + } +} + +func TestResolver_ResolveSchema_ExternalReference_Integration(t *testing.T) { + // Use mockLoader instead of real file loading to avoid repo root dependency + confighttpSchema := &ConfigMetadata{ + Type: "object", + Defs: map[string]*ConfigMetadata{ + "client_config": { + Type: "object", + Properties: map[string]*ConfigMetadata{ + "endpoint": { + Type: "string", + Description: "HTTP endpoint", + }, + "timeout": { + Type: "string", + Description: "Request timeout", + }, + }, + }, + }, + } + + ml := &mockLoader{ + schemas: map[string]*ConfigMetadata{ + "go.opentelemetry.io/collector/config/confighttp.client_config": confighttpSchema, + }, + } + + resolver := &Resolver{ + pkgID: "go.opentelemetry.io/collector/receiver/otlpreceiver", + class: "receiver", + name: "otlp", + loader: ml, + } + + src := &ConfigMetadata{ + Type: "object", + Properties: map[string]*ConfigMetadata{ + "http": { + Ref: "go.opentelemetry.io/collector/config/confighttp.client_config", + }, + }, + } + + result, err := resolver.ResolveSchema(src) + require.NoError(t, err) + require.Equal(t, "object", result.Type) + require.NotNil(t, result.Properties["http"]) + require.Equal(t, "object", result.Properties["http"].Type) + require.NotNil(t, result.Properties["http"].Properties["endpoint"]) + require.Equal(t, "HTTP endpoint", result.Properties["http"].Properties["endpoint"].Description) + require.NotNil(t, result.Properties["http"].Properties["timeout"]) + require.Equal(t, "Request timeout", result.Properties["http"].Properties["timeout"].Description) +} + +func TestResolver_ResolveSchema_DurationFormat(t *testing.T) { + resolver := &Resolver{ + pkgID: "go.opentelemetry.io/collector/test/component", + class: "receiver", + name: "test", + loader: NewLoader(""), + } + + src := &ConfigMetadata{ + Type: "object", + Properties: map[string]*ConfigMetadata{ + "timeout": { + Type: "string", + Format: "duration", + Description: "Request timeout", + }, + "interval": { + Type: "string", + Format: "duration", + }, + }, + } + + result, err := resolver.ResolveSchema(src) + require.NoError(t, err) + + // Check timeout field - should have pattern instead of format + require.NotNil(t, result.Properties["timeout"]) + require.Equal(t, "string", result.Properties["timeout"].Type) + require.Empty(t, result.Properties["timeout"].Format, "format should be cleared") + require.Equal(t, `^([0-9]+(\.[0-9]+)?(ns|us|µs|ms|s|m|h))+$`, result.Properties["timeout"].Pattern) + require.Contains(t, result.Properties["timeout"].Description, "duration format") + require.Contains(t, result.Properties["timeout"].Description, "Request timeout") + + // Check interval field - should have pattern and auto-generated description hint + require.NotNil(t, result.Properties["interval"]) + require.Equal(t, "string", result.Properties["interval"].Type) + require.Empty(t, result.Properties["interval"].Format) + require.Equal(t, `^([0-9]+(\.[0-9]+)?(ns|us|µs|ms|s|m|h))+$`, result.Properties["interval"].Pattern) +} + +// mockLoader is a test helper that returns pre-configured schemas keyed by cache key. +type mockLoader struct { + schemas map[string]*ConfigMetadata +} + +func (m *mockLoader) Load(ref Ref) (*ConfigMetadata, error) { + cacheKey := ref.CacheKey() + if md, ok := m.schemas[cacheKey]; ok { + return md, nil + } + return nil, fmt.Errorf("schema not found for ref: %s", cacheKey) +} + +func TestResolver_ResolveSchema_OriginConvertsLocalRefToExternal(t *testing.T) { + // confighttp schema contains a local absolute ref to /config/configauth.config + // When loaded as an external ref from the collector namespace, the local ref + // should be converted to go.opentelemetry.io/collector/config/configauth.config + configauthSchema := &ConfigMetadata{ + Type: "object", + Defs: map[string]*ConfigMetadata{ + "config": { + Type: "object", + Description: "Auth configuration", + Properties: map[string]*ConfigMetadata{ + "token": {Type: "string"}, + }, + }, + }, + } + + confighttpSchema := &ConfigMetadata{ + Type: "object", + Defs: map[string]*ConfigMetadata{ + "client_config": { + Type: "object", + Properties: map[string]*ConfigMetadata{ + "endpoint": {Type: "string"}, + "auth": { + // This is the key: a local absolute ref inside an externally-loaded schema + Ref: "/config/configauth.config", + }, + }, + }, + }, + } + + ml := &mockLoader{ + schemas: map[string]*ConfigMetadata{ + // When loading the reference to confighttp.client_config, we get the whole schema with all defs + "go.opentelemetry.io/collector/config/confighttp.client_config": confighttpSchema, + // When resolving the local ref /config/configauth.config -> go.opentelemetry.io/collector/config/configauth.config + "go.opentelemetry.io/collector/config/configauth.config": configauthSchema, + }, + } + + resolver := &Resolver{ + pkgID: "go.opentelemetry.io/collector/receiver/otlpreceiver", + class: "receiver", + name: "otlp", + loader: ml, + } + + src := &ConfigMetadata{ + Type: "object", + Properties: map[string]*ConfigMetadata{ + "http": { + Ref: "go.opentelemetry.io/collector/config/confighttp.client_config", + }, + }, + } + + result, err := resolver.ResolveSchema(src) + require.NoError(t, err) + require.NotNil(t, result.Properties["http"]) + require.Equal(t, "object", result.Properties["http"].Type) + require.NotNil(t, result.Properties["http"].Properties["endpoint"]) + require.Equal(t, "string", result.Properties["http"].Properties["endpoint"].Type) + // The auth property should have been resolved through origin-aware conversion + require.NotNil(t, result.Properties["http"].Properties["auth"]) + require.Equal(t, "object", result.Properties["http"].Properties["auth"].Type) + require.Equal(t, "Auth configuration", result.Properties["http"].Properties["auth"].Description) + require.NotNil(t, result.Properties["http"].Properties["auth"].Properties["token"]) +} + +func TestResolver_ResolveSchema_LocalRefWithOriginConversion(t *testing.T) { + // When a local ref is encountered in an externally-loaded schema, it should be converted + // using the origin namespace + configauthSchema := &ConfigMetadata{ + Type: "object", + Defs: map[string]*ConfigMetadata{ + "config": { + Type: "object", + Description: "Auth config", + }, + }, + } + + confighttpSchema := &ConfigMetadata{ + Type: "object", + Defs: map[string]*ConfigMetadata{ + "client_config": { + Type: "object", + Properties: map[string]*ConfigMetadata{ + "auth": { + // This is a local absolute ref inside an externally-loaded schema + Ref: "/config/configauth.config", + }, + }, + }, + }, + } + + ml := &mockLoader{ + schemas: map[string]*ConfigMetadata{ + "go.opentelemetry.io/collector/config/confighttp.client_config": confighttpSchema, + // After origin conversion, /config/configauth.config becomes: + "go.opentelemetry.io/collector/config/configauth.config": configauthSchema, + }, + } + + resolver := &Resolver{ + pkgID: "go.opentelemetry.io/collector/receiver/otlpreceiver", + class: "receiver", + name: "otlp", + loader: ml, + } + + src := &ConfigMetadata{ + Type: "object", + Properties: map[string]*ConfigMetadata{ + "http": { + Ref: "go.opentelemetry.io/collector/config/confighttp.client_config", + }, + }, + } + + result, err := resolver.ResolveSchema(src) + require.NoError(t, err) + require.NotNil(t, result.Properties["http"]) + require.Equal(t, "object", result.Properties["http"].Type) + // auth should be resolved through origin-aware conversion + require.NotNil(t, result.Properties["http"].Properties["auth"]) + require.Equal(t, "object", result.Properties["http"].Properties["auth"].Type) + require.Equal(t, "Auth config", result.Properties["http"].Properties["auth"].Description) +} + +func TestResolver_ResolveSchema_NestedOriginPropagation(t *testing.T) { + // Schema A (remote) → local ref → Schema B (also remote) → local ref → Schema C + // Verify the origin propagates through all levels. + + schemaC := &ConfigMetadata{ + Type: "object", + Defs: map[string]*ConfigMetadata{ + "tls_config": { + Type: "object", + Description: "TLS configuration", + }, + }, + } + + schemaB := &ConfigMetadata{ + Type: "object", + Defs: map[string]*ConfigMetadata{ + "auth_config": { + Type: "object", + Properties: map[string]*ConfigMetadata{ + "tls": { + // Nested local ref — should also be converted using origin + Ref: "/config/configtls.tls_config", + }, + }, + }, + }, + } + + schemaA := &ConfigMetadata{ + Type: "object", + Defs: map[string]*ConfigMetadata{ + "client_config": { + Type: "object", + Properties: map[string]*ConfigMetadata{ + "auth": { + Ref: "/config/configauth.auth_config", + }, + }, + }, + }, + } + + ml := &mockLoader{ + schemas: map[string]*ConfigMetadata{ + "go.opentelemetry.io/collector/config/confighttp.client_config": schemaA, + "go.opentelemetry.io/collector/config/configauth.auth_config": schemaB, + "go.opentelemetry.io/collector/config/configtls.tls_config": schemaC, + }, + } + + resolver := &Resolver{ + pkgID: "go.opentelemetry.io/collector/receiver/otlpreceiver", + class: "receiver", + name: "otlp", + loader: ml, + } + + src := &ConfigMetadata{ + Type: "object", + Properties: map[string]*ConfigMetadata{ + "http": { + Ref: "go.opentelemetry.io/collector/config/confighttp.client_config", + }, + }, + } + + result, err := resolver.ResolveSchema(src) + require.NoError(t, err) + require.NotNil(t, result.Properties["http"]) + // auth should be resolved through origin-aware conversion + auth := result.Properties["http"].Properties["auth"] + require.NotNil(t, auth) + require.Equal(t, "object", auth.Type) + // tls inside auth should also be resolved through origin propagation + tls := auth.Properties["tls"] + require.NotNil(t, tls) + require.Equal(t, "object", tls.Type) + require.Equal(t, "TLS configuration", tls.Description) +} + +func TestResolver_ResolveSchema_RelativeRefWithOrigin(t *testing.T) { + metadataSchema := &ConfigMetadata{ + Type: "object", + Defs: map[string]*ConfigMetadata{ + "metrics_config": { + Type: "object", + Description: "Metrics configuration", + }, + }, + } + + confighttpSchema := &ConfigMetadata{ + Type: "object", + Defs: map[string]*ConfigMetadata{ + "client_config": { + Type: "object", + Properties: map[string]*ConfigMetadata{ + "metrics": { + Ref: "./internal/metadata.metrics_config", + }, + }, + }, + }, + } + + ml := &mockLoader{ + schemas: map[string]*ConfigMetadata{ + "go.opentelemetry.io/collector/config/confighttp.client_config": confighttpSchema, + "go.opentelemetry.io/collector/config/confighttp/internal/metadata.metrics_config": metadataSchema, + }, + } + + resolver := &Resolver{ + pkgID: "go.opentelemetry.io/collector/receiver/otlpreceiver", + class: "receiver", + name: "otlp", + loader: ml, + } + + src := &ConfigMetadata{ + Type: "object", + Properties: map[string]*ConfigMetadata{ + "http": { + Ref: "go.opentelemetry.io/collector/config/confighttp.client_config", + }, + }, + } + + result, err := resolver.ResolveSchema(src) + require.NoError(t, err) + require.NotNil(t, result.Properties["http"]) + metrics := result.Properties["http"].Properties["metrics"] + require.NotNil(t, metrics) + require.Equal(t, "object", metrics.Type) + require.Equal(t, "Metrics configuration", metrics.Description) +} + +func TestResolver_ResolveSchema_ParentRelativeRefWithOrigin(t *testing.T) { + configtlsSchema := &ConfigMetadata{ + Type: "object", + Defs: map[string]*ConfigMetadata{ + "tls_config": { + Type: "object", + Description: "TLS settings", + }, + }, + } + + confighttpSchema := &ConfigMetadata{ + Type: "object", + Defs: map[string]*ConfigMetadata{ + "client_config": { + Type: "object", + Properties: map[string]*ConfigMetadata{ + "tls": { + Ref: "../configtls.tls_config", + }, + }, + }, + }, + } + + ml := &mockLoader{ + schemas: map[string]*ConfigMetadata{ + "go.opentelemetry.io/collector/config/confighttp.client_config": confighttpSchema, + "go.opentelemetry.io/collector/config/configtls.tls_config": configtlsSchema, + }, + } + + resolver := &Resolver{ + pkgID: "go.opentelemetry.io/collector/receiver/otlpreceiver", + class: "receiver", + name: "otlp", + loader: ml, + } + + src := &ConfigMetadata{ + Type: "object", + Properties: map[string]*ConfigMetadata{ + "http": { + Ref: "go.opentelemetry.io/collector/config/confighttp.client_config", + }, + }, + } + + result, err := resolver.ResolveSchema(src) + require.NoError(t, err) + require.NotNil(t, result.Properties["http"]) + tls := result.Properties["http"].Properties["tls"] + require.NotNil(t, tls) + require.Equal(t, "object", tls.Type) + require.Equal(t, "TLS settings", tls.Description) +} + +func TestNewResolver(t *testing.T) { + dir := t.TempDir() + r := NewResolver("go.opentelemetry.io/collector/receiver/otlp", "receiver", "otlp", dir) + require.NotNil(t, r) + require.Equal(t, "go.opentelemetry.io/collector/receiver/otlp", r.pkgID) + require.Equal(t, "receiver", r.class) + require.Equal(t, "otlp", r.name) + require.NotNil(t, r.loader) +} + +func TestResolver_ResolveSchema_UnknownNamespaceFallback(t *testing.T) { + // An external ref with an unsupported namespace should fall back to "any" type + resolver := &Resolver{ + pkgID: "go.opentelemetry.io/collector/test/component", + class: "receiver", + name: "test", + loader: NewLoader(""), + } + + src := &ConfigMetadata{ + Type: "object", + Properties: map[string]*ConfigMetadata{ + "custom": { + Ref: "github.com/example/custom.config", + }, + }, + } + + result, err := resolver.ResolveSchema(src) + require.NoError(t, err) + require.NotNil(t, result.Properties["custom"]) + require.Equal(t, "github.com/example/custom.config", result.Properties["custom"].GoType) + require.Contains(t, result.Properties["custom"].Comment, "any") +} + +func TestResolver_ResolveSchema_LoaderError(t *testing.T) { + ml := &mockLoader{schemas: map[string]*ConfigMetadata{}} + + resolver := &Resolver{ + pkgID: "go.opentelemetry.io/collector/test/component", + class: "receiver", + name: "test", + loader: ml, + } + + src := &ConfigMetadata{ + Type: "object", + Properties: map[string]*ConfigMetadata{ + "http": { + Ref: "go.opentelemetry.io/collector/config/confighttp.client_config", + }, + }, + } + + result, err := resolver.ResolveSchema(src) + require.Error(t, err) + require.Nil(t, result) +} + +func TestResolver_ResolveRef_InvalidRefFormat(t *testing.T) { + resolver := &Resolver{ + pkgID: "go.opentelemetry.io/collector/test/component", + class: "receiver", + name: "test", + loader: NewLoader(""), + } + + src := &ConfigMetadata{ + Type: "object", + Properties: map[string]*ConfigMetadata{ + "bad": { + Ref: "/", + }, + }, + } + _, err := resolver.ResolveSchema(src) + require.Error(t, err) + require.Contains(t, err.Error(), "invalid reference format") +} + +func TestResolver_LoadExternalRef_NilResult(t *testing.T) { + ml := &nilResultLoader{} + resolver := &Resolver{ + pkgID: "go.opentelemetry.io/collector/test/component", + class: "receiver", + name: "test", + loader: ml, + } + + ref := NewRef("go.opentelemetry.io/collector/config/confighttp.client_config") + result, err := resolver.loadExternalRef(ref) + require.Error(t, err) + require.Contains(t, err.Error(), "no loader could resolve external reference") + require.Nil(t, result) +} + +// nilResultLoader returns (nil, nil) for any ref. +type nilResultLoader struct{} + +func (n *nilResultLoader) Load(_ Ref) (*ConfigMetadata, error) { return nil, nil } + +func TestResolver_LoadExternalRef_InternalResolutionError(t *testing.T) { + brokenSchema := &ConfigMetadata{ + Type: "object", + Defs: map[string]*ConfigMetadata{ + "config": { + Type: "object", + Properties: map[string]*ConfigMetadata{ + "field": { + Ref: "/", + }, + }, + }, + }, + } + + ml := &mockLoader{ + schemas: map[string]*ConfigMetadata{ + "go.opentelemetry.io/collector/config/confighttp.config": brokenSchema, + }, + } + + resolver := &Resolver{ + pkgID: "go.opentelemetry.io/collector/test/component", + class: "receiver", + name: "test", + loader: ml, + } + + ref := NewRef("go.opentelemetry.io/collector/config/confighttp.config") + result, err := resolver.loadExternalRef(ref) + require.Error(t, err) + require.Contains(t, err.Error(), "failed to resolve internal references in external schema") + require.Nil(t, result) +} + +func TestResolver_ResolveSchema_LocalRef(t *testing.T) { + localSchema := &ConfigMetadata{ + Type: "object", + Defs: map[string]*ConfigMetadata{ + "target": { + Type: "object", + Description: "Local target", + }, + }, + } + + ml := &mockLoader{ + schemas: map[string]*ConfigMetadata{ + "/config/localtype.target": localSchema, + }, + } + + resolver := &Resolver{ + pkgID: "go.opentelemetry.io/collector/test/component", + class: "receiver", + name: "test", + loader: ml, + } + + src := &ConfigMetadata{ + Type: "object", + Properties: map[string]*ConfigMetadata{ + "local": { + Ref: "/config/localtype.target", + }, + }, + } + + result, err := resolver.ResolveSchema(src) + require.NoError(t, err) + require.NotNil(t, result.Properties["local"]) + require.Equal(t, "object", result.Properties["local"].Type) + require.Equal(t, "Local target", result.Properties["local"].Description) +} + +func TestResolver_ResolveSchema_MapValueError(t *testing.T) { + resolver := &Resolver{ + pkgID: "go.opentelemetry.io/collector/test/component", + class: "receiver", + name: "test", + loader: &mockLoader{schemas: map[string]*ConfigMetadata{}}, + } + + src := &ConfigMetadata{ + Type: "object", + Properties: map[string]*ConfigMetadata{ + "field": { + // Ref to an unknown external schema → loader returns error + Ref: "go.opentelemetry.io/collector/missing/pkg.config", + }, + }, + } + + _, err := resolver.ResolveSchema(src) + require.Error(t, err) +} + +func TestResolver_ResolveSchema_AllOfError(t *testing.T) { + resolver := &Resolver{ + pkgID: "go.opentelemetry.io/collector/test/component", + class: "receiver", + name: "test", + loader: &mockLoader{schemas: map[string]*ConfigMetadata{}}, + } + + src := &ConfigMetadata{ + Type: "object", + AllOf: []*ConfigMetadata{ + { + Ref: "go.opentelemetry.io/collector/missing/pkg.config", + }, + }, + } + + _, err := resolver.ResolveSchema(src) + require.Error(t, err) +} + +func TestResolver_ResolveSchema_PtrFieldError(t *testing.T) { + resolver := &Resolver{ + pkgID: "go.opentelemetry.io/collector/test/component", + class: "receiver", + name: "test", + loader: &mockLoader{schemas: map[string]*ConfigMetadata{}}, + } + + src := &ConfigMetadata{ + Type: "object", + Properties: map[string]*ConfigMetadata{ + "body": { + Type: "string", + ContentSchema: &ConfigMetadata{ + Ref: "/", + }, + }, + }, + } + + _, err := resolver.ResolveSchema(src) + require.Error(t, err) +} + +func TestResolver_ResolveSchema_PointerFields(t *testing.T) { + resolver := &Resolver{ + pkgID: "go.opentelemetry.io/collector/test/component", + class: "receiver", + name: "test", + loader: NewLoader(""), + } + + minItems := 1 + maxItems := 10 + src := &ConfigMetadata{ + Type: "object", + Properties: map[string]*ConfigMetadata{ + "tags": { + Type: "array", + Items: &ConfigMetadata{Type: "string"}, + MinItems: &minItems, + MaxItems: &maxItems, + }, + }, + } + + result, err := resolver.ResolveSchema(src) + require.NoError(t, err) + require.NotNil(t, result.Properties["tags"]) + require.Equal(t, "array", result.Properties["tags"].Type) + require.NotNil(t, result.Properties["tags"].Items) + require.Equal(t, "string", result.Properties["tags"].Items.Type) +} + +func TestResolver_ResolveSchema_ContentSchema(t *testing.T) { + resolver := &Resolver{ + pkgID: "go.opentelemetry.io/collector/test/component", + class: "receiver", + name: "test", + loader: NewLoader(""), + } + + src := &ConfigMetadata{ + Type: "object", + Properties: map[string]*ConfigMetadata{ + "body": { + Type: "string", + ContentMediaType: "application/json", + ContentSchema: &ConfigMetadata{ + Type: "object", + Properties: map[string]*ConfigMetadata{ + "name": {Type: "string"}, + }, + }, + }, + }, + } + + result, err := resolver.ResolveSchema(src) + require.NoError(t, err) + require.NotNil(t, result.Properties["body"]) + require.NotNil(t, result.Properties["body"].ContentSchema) + require.Equal(t, "object", result.Properties["body"].ContentSchema.Type) +} + +func TestResolver_ResolveSchema_PreservesCustomExtensions(t *testing.T) { + // When a node has both a $ref and custom extensions (GoType, IsPointer, + // IsOptional, Description, Default, Enum), the custom extensions should + // be preserved after resolution instead of being overwritten by the + // resolved schema's values. + + targetSchema := &ConfigMetadata{ + Type: "object", + Defs: map[string]*ConfigMetadata{ + "duration_type": { + Type: "string", + Description: "A generic duration type", + }, + }, + } + + ml := &mockLoader{ + schemas: map[string]*ConfigMetadata{ + "go.opentelemetry.io/collector/config/configbase.duration_type": targetSchema, + }, + } + + resolver := &Resolver{ + pkgID: "go.opentelemetry.io/collector/test/component", + class: "receiver", + name: "test", + loader: ml, + } + + src := &ConfigMetadata{ + Type: "object", + Properties: map[string]*ConfigMetadata{ + "timeout": { + Ref: "go.opentelemetry.io/collector/config/configbase.duration_type", + GoType: "time.Duration", + IsPointer: true, + IsOptional: true, + Description: "Request timeout for the endpoint", + Default: "30s", + Enum: []any{"10s", "30s", "60s"}, + }, + }, + } + + result, err := resolver.ResolveSchema(src) + require.NoError(t, err) + require.NotNil(t, result.Properties["timeout"]) + + timeout := result.Properties["timeout"] + // GoType should be preserved from the referencing node + require.Equal(t, "time.Duration", timeout.GoType) + // IsPointer should be preserved + require.True(t, timeout.IsPointer) + // IsOptional should be preserved + require.True(t, timeout.IsOptional) + // Description should come from the referencing node, not the target + require.Equal(t, "Request timeout for the endpoint", timeout.Description) + // Default should be preserved + require.NotNil(t, timeout.Default) + require.Equal(t, "30s", timeout.Default) + // Enum should be preserved + require.Equal(t, []any{"10s", "30s", "60s"}, timeout.Enum) + // Type should come from the resolved schema + require.Equal(t, "string", timeout.Type) +} + +func TestResolver_ResolveSchema_RefWithoutCustomExtensions(t *testing.T) { + // When a node has a $ref but NO custom extensions, the resolved schema's + // values should be used as-is (no overriding). + + targetSchema := &ConfigMetadata{ + Type: "object", + Defs: map[string]*ConfigMetadata{ + "base_config": { + Type: "object", + Description: "Base configuration from the target schema", + GoType: "BaseConfig", + }, + }, + } + + ml := &mockLoader{ + schemas: map[string]*ConfigMetadata{ + "go.opentelemetry.io/collector/config/configbase.base_config": targetSchema, + }, + } + + resolver := &Resolver{ + pkgID: "go.opentelemetry.io/collector/test/component", + class: "receiver", + name: "test", + loader: ml, + } + + src := &ConfigMetadata{ + Type: "object", + Properties: map[string]*ConfigMetadata{ + "base": { + Ref: "go.opentelemetry.io/collector/config/configbase.base_config", + // No custom extensions set + }, + }, + } + + result, err := resolver.ResolveSchema(src) + require.NoError(t, err) + require.NotNil(t, result.Properties["base"]) + + base := result.Properties["base"] + // Values should come from the resolved target + require.Equal(t, "object", base.Type) + require.Equal(t, "Base configuration from the target schema", base.Description) + require.Equal(t, "BaseConfig", base.GoType) +} diff --git a/cmd/mdatagen/internal/cfggen/type_ref.go b/cmd/mdatagen/internal/cfggen/type_ref.go new file mode 100644 index 000000000000..21560d82db88 --- /dev/null +++ b/cmd/mdatagen/internal/cfggen/type_ref.go @@ -0,0 +1,122 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +package cfggen // import "go.opentelemetry.io/collector/cmd/mdatagen/internal/cfggen" + +import ( + "errors" + "fmt" + "path" + "strings" + + "go.opentelemetry.io/collector/cmd/mdatagen/internal/helpers" +) + +// GoTypeRef represents a fully resolved Go type reference for code generation. +// It holds the import path and exported type name needed to render a type in generated Go source code. +type GoTypeRef struct { + // ImportPath is the full Go import path + // Empty for internal (local $defs) references that need no import. + ImportPath string + // TypeName is the exported Go type name + TypeName string +} + +// Qualifier returns the short package name used as a qualifier in Go source. +// Returns "" for internal references (no import needed). +func (r GoTypeRef) Qualifier() string { + if r.ImportPath == "" { + return "" + } + return path.Base(r.ImportPath) +} + +// String returns the Go type expression as it would appear in source code, +func (r GoTypeRef) String() string { + if q := r.Qualifier(); q != "" { + return q + "." + r.TypeName + } + return r.TypeName +} + +// ResolveGoTypeRef converts a raw metadata reference string into a GoTypeRef. +// +// Parameters: +// - ref: raw reference string from metadata +// - rootPackage: module path from the repo-root go.mod +// - componentPackage: full Go import path of the component +func ResolveGoTypeRef(ref, rootPackage, componentPackage string) (GoTypeRef, error) { + if ref == "" { + return GoTypeRef{}, errors.New("empty reference string") + } + + cleanRef, _, _ := strings.Cut(ref, "@") + + switch { + case strings.HasPrefix(cleanRef, "/"): + return resolveLocalAbsolute(cleanRef, rootPackage) + case strings.HasPrefix(cleanRef, "./") || strings.HasPrefix(cleanRef, "../"): + return resolveLocalRelative(cleanRef, componentPackage) + case strings.Contains(cleanRef, "/"): + return resolveExternal(cleanRef) + default: + return resolveInternal(cleanRef) + } +} + +func resolveInternal(ref string) (GoTypeRef, error) { + typeName, err := helpers.FormatIdentifier(ref, true) + if err != nil { + return GoTypeRef{}, fmt.Errorf("failed to format internal type %q: %w", ref, err) + } + return GoTypeRef{ImportPath: "", TypeName: typeName}, nil +} + +func resolveExternal(ref string) (GoTypeRef, error) { + sepIndex := strings.LastIndex(ref, ".") + if sepIndex == -1 || sepIndex == len(ref)-1 { + return GoTypeRef{}, fmt.Errorf("invalid external reference %q: missing type name after last dot", ref) + } + pkgPath := ref[:sepIndex] + rawType := ref[sepIndex+1:] + + typeName, err := helpers.FormatIdentifier(rawType, true) + if err != nil { + return GoTypeRef{}, fmt.Errorf("failed to format external type %q: %w", rawType, err) + } + return GoTypeRef{ImportPath: pkgPath, TypeName: typeName}, nil +} + +func resolveLocalAbsolute(ref, rootPackage string) (GoTypeRef, error) { + sepIndex := strings.LastIndex(ref, ".") + if sepIndex == -1 || sepIndex == len(ref)-1 { + return GoTypeRef{}, fmt.Errorf("invalid local absolute reference %q: missing type name after last dot", ref) + } + localPath := ref[:sepIndex] + rawType := ref[sepIndex+1:] + + typeName, err := helpers.FormatIdentifier(rawType, true) + if err != nil { + return GoTypeRef{}, fmt.Errorf("failed to format local type %q: %w", rawType, err) + } + + importPath := rootPackage + localPath + return GoTypeRef{ImportPath: importPath, TypeName: typeName}, nil +} + +func resolveLocalRelative(ref, componentPackage string) (GoTypeRef, error) { + sepIndex := strings.LastIndex(ref, ".") + if sepIndex == -1 || sepIndex == len(ref)-1 { + return GoTypeRef{}, fmt.Errorf("invalid local relative reference %q: missing type name after last dot", ref) + } + relPath := ref[:sepIndex] + rawType := ref[sepIndex+1:] + + typeName, err := helpers.FormatIdentifier(rawType, true) + if err != nil { + return GoTypeRef{}, fmt.Errorf("failed to format local type %q: %w", rawType, err) + } + + importPath := path.Join(componentPackage, relPath) + return GoTypeRef{ImportPath: importPath, TypeName: typeName}, nil +} diff --git a/cmd/mdatagen/internal/cfggen/type_ref_test.go b/cmd/mdatagen/internal/cfggen/type_ref_test.go new file mode 100644 index 000000000000..c56c725efb82 --- /dev/null +++ b/cmd/mdatagen/internal/cfggen/type_ref_test.go @@ -0,0 +1,272 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +package cfggen + +import ( + "testing" + + "github.com/stretchr/testify/require" +) + +func TestGoTypeRef_String(t *testing.T) { + tests := []struct { + name string + ref GoTypeRef + expected string + }{ + { + name: "internal type (no import)", + ref: GoTypeRef{ImportPath: "", TypeName: "Target"}, + expected: "Target", + }, + { + name: "external type with package qualifier", + ref: GoTypeRef{ImportPath: "go.opentelemetry.io/collector/config/confighttp", TypeName: "ClientConfig"}, + expected: "confighttp.ClientConfig", + }, + { + name: "standard library type", + ref: GoTypeRef{ImportPath: "time", TypeName: "Duration"}, + expected: "time.Duration", + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + require.Equal(t, tt.expected, tt.ref.String()) + }) + } +} + +func TestGoTypeRef_Qualifier(t *testing.T) { + tests := []struct { + name string + ref GoTypeRef + expected string + }{ + { + name: "no import path", + ref: GoTypeRef{ImportPath: ""}, + expected: "", + }, + { + name: "nested package", + ref: GoTypeRef{ImportPath: "go.opentelemetry.io/collector/config/confighttp"}, + expected: "confighttp", + }, + { + name: "single segment", + ref: GoTypeRef{ImportPath: "time"}, + expected: "time", + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + require.Equal(t, tt.expected, tt.ref.Qualifier()) + }) + } +} + +func TestResolveGoTypeRef_Internal(t *testing.T) { + tests := []struct { + name string + ref string + expected GoTypeRef + }{ + { + name: "simple snake_case name", + ref: "target", + expected: GoTypeRef{ImportPath: "", TypeName: "Target"}, + }, + { + name: "multi-word snake_case", + ref: "my_custom_type", + expected: GoTypeRef{ImportPath: "", TypeName: "MyCustomType"}, + }, + { + name: "already formatted", + ref: "MyType", + expected: GoTypeRef{ImportPath: "", TypeName: "MyType"}, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + result, err := ResolveGoTypeRef(tt.ref, "", "") + require.NoError(t, err) + require.Equal(t, tt.expected, result) + }) + } +} + +func TestResolveGoTypeRef_External(t *testing.T) { + tests := []struct { + name string + ref string + expected GoTypeRef + }{ + { + name: "full module path", + ref: "go.opentelemetry.io/collector/config/confighttp.client_config", + expected: GoTypeRef{ + ImportPath: "go.opentelemetry.io/collector/config/confighttp", + TypeName: "ClientConfig", + }, + }, + { + name: "with version suffix", + ref: "go.opentelemetry.io/collector/scraper/scraperhelper.controller_config@v0.146.0", + expected: GoTypeRef{ + ImportPath: "go.opentelemetry.io/collector/scraper/scraperhelper", + TypeName: "ControllerConfig", + }, + }, + { + name: "github package", + ref: "github.com/example/pkg/subpkg.MyType", + expected: GoTypeRef{ + ImportPath: "github.com/example/pkg/subpkg", + TypeName: "MyType", + }, + }, + { + name: "type name needs formatting", + ref: "github.com/example/pkg.my_type", + expected: GoTypeRef{ + ImportPath: "github.com/example/pkg", + TypeName: "MyType", + }, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + result, err := ResolveGoTypeRef(tt.ref, "", "") + require.NoError(t, err) + require.Equal(t, tt.expected, result) + }) + } +} + +func TestResolveGoTypeRef_LocalAbsolute(t *testing.T) { + rootPkg := "go.opentelemetry.io/collector" + + tests := []struct { + name string + ref string + expected GoTypeRef + }{ + { + name: "repo-relative path", + ref: "/config/confighttp.client_config", + expected: GoTypeRef{ + ImportPath: "go.opentelemetry.io/collector/config/confighttp", + TypeName: "ClientConfig", + }, + }, + { + name: "nested path", + ref: "/scraper/scraperhelper.controller_config", + expected: GoTypeRef{ + ImportPath: "go.opentelemetry.io/collector/scraper/scraperhelper", + TypeName: "ControllerConfig", + }, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + result, err := ResolveGoTypeRef(tt.ref, rootPkg, "") + require.NoError(t, err) + require.Equal(t, tt.expected, result) + }) + } +} + +func TestResolveGoTypeRef_LocalAbsolute_DifferentRoot(t *testing.T) { + rootPkg := "github.com/open-telemetry/opentelemetry-collector-contrib" + + ref := "/receiver/hostmetricsreceiver/internal.scraper_config" + result, err := ResolveGoTypeRef(ref, rootPkg, "") + require.NoError(t, err) + require.Equal(t, GoTypeRef{ + ImportPath: "github.com/open-telemetry/opentelemetry-collector-contrib/receiver/hostmetricsreceiver/internal", + TypeName: "ScraperConfig", + }, result) +} + +func TestResolveGoTypeRef_LocalRelative(t *testing.T) { + compPkg := "go.opentelemetry.io/collector/scraper/scraperhelper" + + tests := []struct { + name string + ref string + expected GoTypeRef + }{ + { + name: "relative to component", + ref: "./internal/metadata.metrics_builder", + expected: GoTypeRef{ + ImportPath: "go.opentelemetry.io/collector/scraper/scraperhelper/internal/metadata", + TypeName: "MetricsBuilder", + }, + }, + { + name: "parent directory reference", + ref: "../otherpackage.some_type", + expected: GoTypeRef{ + ImportPath: "go.opentelemetry.io/collector/scraper/otherpackage", + TypeName: "SomeType", + }, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + result, err := ResolveGoTypeRef(tt.ref, "", compPkg) + require.NoError(t, err) + require.Equal(t, tt.expected, result) + }) + } +} + +func TestResolveGoTypeRef_Errors(t *testing.T) { + tests := []struct { + name string + ref string + }{ + { + name: "empty reference", + ref: "", + }, + { + name: "external missing type after dot", + ref: "github.com/example/pkg.", + }, + { + name: "local absolute missing type after dot", + ref: "/config/confighttp.", + }, + { + name: "local relative missing type after dot", + ref: "./internal/metadata.", + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + _, err := ResolveGoTypeRef(tt.ref, "root", "comp") + require.Error(t, err) + }) + } +} + +func TestResolveGoTypeRef_VersionStripped(t *testing.T) { + ref := "go.opentelemetry.io/collector/config/confighttp.client_config@v0.146.0" + result, err := ResolveGoTypeRef(ref, "", "") + require.NoError(t, err) + require.Equal(t, "go.opentelemetry.io/collector/config/confighttp", result.ImportPath) + require.Equal(t, "ClientConfig", result.TypeName) +} diff --git a/cmd/mdatagen/internal/cfggen/writer.go b/cmd/mdatagen/internal/cfggen/writer.go new file mode 100644 index 000000000000..774bc350a58a --- /dev/null +++ b/cmd/mdatagen/internal/cfggen/writer.go @@ -0,0 +1,23 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +package cfggen // import "go.opentelemetry.io/collector/cmd/mdatagen/internal/cfggen" + +import ( + "os" + "path/filepath" +) + +const fileName = "config.schema.json" + +// WriteJSONSchema writes the given ConfigMetadata as a JSON Schema file +// named "config.schema.json" in the specified directory. +func WriteJSONSchema(dir string, md *ConfigMetadata) error { + filePath := filepath.Join(dir, fileName) + data, err := md.ToJSON() + if err != nil { + return err + } + + return os.WriteFile(filePath, data, 0o600) +} diff --git a/cmd/mdatagen/internal/cfggen/writer_test.go b/cmd/mdatagen/internal/cfggen/writer_test.go new file mode 100644 index 000000000000..eb950080e1a0 --- /dev/null +++ b/cmd/mdatagen/internal/cfggen/writer_test.go @@ -0,0 +1,37 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +package cfggen + +import ( + "os" + "path/filepath" + "testing" + + "github.com/stretchr/testify/require" +) + +func TestWriteJSONSchema(t *testing.T) { + dir := t.TempDir() + md := &ConfigMetadata{ + Schema: schemaVersion, + Type: "object", + Properties: map[string]*ConfigMetadata{ + "endpoint": {Type: "string"}, + }, + } + + err := WriteJSONSchema(dir, md) + require.NoError(t, err) + + content, err := os.ReadFile(filepath.Join(dir, fileName)) // #nosec G304 + require.NoError(t, err) + require.Contains(t, string(content), `"$schema"`) + require.Contains(t, string(content), `"endpoint"`) +} + +func TestWriteJSONSchema_InvalidDir(t *testing.T) { + md := &ConfigMetadata{Type: "object"} + err := WriteJSONSchema("/nonexistent/path/that/does/not/exist", md) + require.Error(t, err) +} diff --git a/cmd/mdatagen/internal/command.go b/cmd/mdatagen/internal/command.go index 3e41a5e77f8c..68bfdbf04063 100644 --- a/cmd/mdatagen/internal/command.go +++ b/cmd/mdatagen/internal/command.go @@ -19,9 +19,12 @@ import ( "text/template" "github.com/spf13/cobra" + "go.yaml.in/yaml/v3" "golang.org/x/text/cases" "golang.org/x/text/language" - "gopkg.in/yaml.v3" + + "go.opentelemetry.io/collector/cmd/mdatagen/internal/cfggen" + "go.opentelemetry.io/collector/cmd/mdatagen/internal/helpers" ) const ( @@ -59,6 +62,7 @@ func NewCommand() (*cobra.Command, error) { Use: "mdatagen", Version: ver, SilenceUsage: true, + Args: cobra.ExactArgs(1), RunE: func(_ *cobra.Command, args []string) error { return run(args[0]) }, @@ -77,8 +81,12 @@ func run(ymlPath string) error { ymlDir := filepath.Dir(ymlPath) packageName := filepath.Base(ymlDir) + importRootPath, err := helpers.RootPackage(ymlDir) + if err != nil { + return fmt.Errorf("unable to determine import root path: %w", err) + } - raw, readErr := os.ReadFile(ymlPath) //nolint:gosec // G304: abs path is cleaned/validated above; safe to read + raw, readErr := os.ReadFile(filepath.Clean(ymlPath)) if readErr != nil { return fmt.Errorf("failed reading %v: %w", ymlPath, readErr) } @@ -100,7 +108,7 @@ func run(ymlPath string) error { if !slices.Contains(nonComponents, md.Status.Class) { toGenerate[filepath.Join(tmplDir, "status.go.tmpl")] = filepath.Join(codeDir, "generated_status.go") err = generateFile(filepath.Join(tmplDir, "component_test.go.tmpl"), - filepath.Join(ymlDir, "generated_component_test.go"), md, packageName) + filepath.Join(ymlDir, "generated_component_test.go"), md, packageName, importRootPath) if err != nil { return err } @@ -120,7 +128,7 @@ func run(ymlPath string) error { } err = generateFile(filepath.Join(tmplDir, "package_test.go.tmpl"), - filepath.Join(ymlDir, "generated_package_test.go"), md, packageName) + filepath.Join(ymlDir, "generated_package_test.go"), md, packageName, importRootPath) if err != nil { return err } @@ -129,7 +137,7 @@ func run(ymlPath string) error { err = inlineReplace( filepath.Join(tmplDir, "readme.md.tmpl"), filepath.Join(ymlDir, "README.md"), - md, statusStart, statusEnd, md.GeneratedPackageName) + md, statusStart, statusEnd, md.GeneratedPackageName, importRootPath) if err != nil { return err } @@ -172,7 +180,7 @@ func run(ymlPath string) error { } } - if len(md.Metrics) != 0 || len(md.Telemetry.Metrics) != 0 || len(md.ResourceAttributes) != 0 || len(md.Events) != 0 { // if there's metrics or internal metrics or events, generate documentation for them + if len(md.Metrics) != 0 || len(md.Telemetry.Metrics) != 0 || len(md.ResourceAttributes) != 0 || len(md.Events) != 0 || len(md.FeatureGates) != 0 { // if there's metrics or internal metrics or events or feature gates, generate documentation for them toGenerate[filepath.Join(tmplDir, "documentation.md.tmpl")] = filepath.Join(ymlDir, "documentation.md") } @@ -185,6 +193,7 @@ func run(ymlPath string) error { toGenerate[filepath.Join(tmplDir, "testdata", "config.yaml.tmpl")] = filepath.Join(testdataDir, "config.yaml") toGenerate[filepath.Join(tmplDir, "config.go.tmpl")] = filepath.Join(codeDir, "generated_config.go") toGenerate[filepath.Join(tmplDir, "config_test.go.tmpl")] = filepath.Join(codeDir, "generated_config_test.go") + toGenerate[filepath.Join(tmplDir, "config.schema.yaml.tmpl")] = filepath.Join(codeDir, "config.schema.yaml") } if len(md.ResourceAttributes) > 0 { // only generate resource files if resource attributes are configured @@ -203,6 +212,15 @@ func run(ymlPath string) error { toGenerate[filepath.Join(tmplDir, "logs_test.go.tmpl")] = filepath.Join(codeDir, "generated_logs_test.go") } + if len(md.FeatureGates) > 0 { // only generate feature gates if feature gates are present + toGenerate[filepath.Join(tmplDir, "feature_gates.go.tmpl")] = filepath.Join(codeDir, "generated_feature_gates.go") + } + + if len(md.Entities) > 0 && len(md.Metrics) > 0 { // only generate entity metrics if entities are defined + toGenerate[filepath.Join(tmplDir, "entity_metrics.go.tmpl")] = filepath.Join(codeDir, "generated_entity_metrics.go") + toGenerate[filepath.Join(tmplDir, "entity_metrics_test.go.tmpl")] = filepath.Join(codeDir, "generated_entity_metrics_test.go") + } + // If at least one file to generate, will need the codeDir if len(toGenerate) > 0 { if err = os.MkdirAll(codeDir, 0o700); err != nil { @@ -211,160 +229,208 @@ func run(ymlPath string) error { } for tmpl, dst := range toGenerate { - if err := generateFile(tmpl, dst, md, md.GeneratedPackageName); err != nil { + if err := generateFile(tmpl, dst, md, md.GeneratedPackageName, importRootPath); err != nil { return err } } + if err := generateConfigFiles(md, ymlDir, importRootPath); err != nil { + return fmt.Errorf("failed to generate config files: %w", err) + } + return nil } -func templatize(tmplFile string, md Metadata) *template.Template { +func getTemplateFuncMap(md Metadata, importRootPath string) template.FuncMap { + return template.FuncMap{ + "publicVar": func(s string) (string, error) { + return helpers.FormatIdentifier(s, true) + }, + "attributeInfo": func(an AttributeName) Attribute { + return md.Attributes[an] + }, + "defaultAttributes": func(ans []AttributeName) []string { + var atts []string + for _, an := range ans { + if md.Attributes[an].IsNotOptIn() { + atts = append(atts, string(md.Attributes[an].Name())) + } + } + return atts + }, + "requiredAttributes": func(ans []AttributeName) []string { + var atts []string + for _, an := range ans { + if md.Attributes[an].IsRequired() { + atts = append(atts, string(md.Attributes[an].Name())) + } + } + return atts + }, + "hasAggregatableAttributes": func(ans []AttributeName) bool { + for _, an := range ans { + if md.Attributes[an].RequirementLevel == AttributeRequirementLevelRecommended || + md.Attributes[an].RequirementLevel == AttributeRequirementLevelOptIn { + return true + } + } + return false + }, + "getEventConditionalAttributes": func(attrs map[AttributeName]Attribute) []AttributeName { + seen := make(map[AttributeName]bool) + used := make([]AttributeName, 0) + + for _, event := range md.Events { + for _, attribute := range event.Attributes { + v, exists := attrs[attribute] + if exists && v.IsConditional() && !seen[attribute] { + used = append(used, attribute) + seen[attribute] = true + } + } + } + sort.Slice(used, func(i, j int) bool { return string(used[i]) < string(used[j]) }) + + return used + }, + "getMetricConditionalAttributes": func(attrs map[AttributeName]Attribute) []AttributeName { + seen := make(map[AttributeName]bool) + used := make([]AttributeName, 0) + + for _, event := range md.Metrics { + for _, attribute := range event.Attributes { + v, exists := attrs[attribute] + if exists && v.IsConditional() && !seen[attribute] { + used = append(used, attribute) + seen[attribute] = true + } + } + } + sort.Slice(used, func(i, j int) bool { return string(used[i]) < string(used[j]) }) + + return used + }, + "metricInfo": func(mn MetricName) Metric { + return md.Metrics[mn] + }, + "eventInfo": func(en EventName) Event { + return md.Events[en] + }, + "telemetryInfo": func(mn MetricName) Metric { + return md.Telemetry.Metrics[mn] + }, + "parseImportsRequired": func(metrics map[MetricName]Metric) bool { + for _, m := range metrics { + if m.Data().HasMetricInputType() { + return true + } + } + return false + }, + "stringsJoin": strings.Join, + "stringsSplit": strings.Split, + "userLinks": func(elems []string) []string { + result := make([]string, len(elems)) + for i, elem := range elems { + if elem == "open-telemetry/collector-approvers" { + result[i] = "[@open-telemetry/collector-approvers](https://github.com/orgs/open-telemetry/teams/collector-approvers)" + } else { + result[i] = fmt.Sprintf("[@%s](https://www.github.com/%s)", elem, elem) + } + } + return result + }, + "casesTitle": cases.Title(language.English).String, + "toLowerCase": strings.ToLower, + "toCamelCase": func(s string) string { + return joinCamelCase(strings.Split(s, "_"), true) + }, + "toLowerCamelCase": func(s string) string { + return joinCamelCase(strings.Split(s, "_"), false) + }, + "schemaRef": func(ref string) string { + return cfggen.LocalizeRef(ref, importRootPath) + }, + "inc": func(i int) int { return i + 1 }, + "distroURL": distroURL, + "isExporter": func() bool { + return md.Status.Class == "exporter" + }, + "isProcessor": func() bool { + return md.Status.Class == "processor" + }, + "isReceiver": func() bool { + return md.Status.Class == "receiver" + }, + "isExtension": func() bool { + return md.Status.Class == "extension" + }, + "isConnector": func() bool { + return md.Status.Class == "connector" + }, + "isScraper": func() bool { + return md.Status.Class == "scraper" + }, + "isCommand": func() bool { + return md.Status.Class == "cmd" + }, + "supportsLogs": func() bool { return md.supportsSignal("logs") }, + "supportsMetrics": func() bool { return md.supportsSignal("metrics") }, + "supportsTraces": func() bool { return md.supportsSignal("traces") }, + "supportsProfiles": func() bool { return md.supportsSignal("profiles") }, + "supportsLogsToLogs": func() bool { return md.supportsSignal("logs_to_logs") }, + "supportsLogsToMetrics": func() bool { return md.supportsSignal("logs_to_metrics") }, + "supportsLogsToTraces": func() bool { return md.supportsSignal("logs_to_traces") }, + "supportsLogsToProfiles": func() bool { return md.supportsSignal("logs_to_profiles") }, + "supportsMetricsToLogs": func() bool { return md.supportsSignal("metrics_to_logs") }, + "supportsMetricsToMetrics": func() bool { return md.supportsSignal("metrics_to_metrics") }, + "supportsMetricsToTraces": func() bool { return md.supportsSignal("metrics_to_traces") }, + "supportsMetricsToProfiles": func() bool { return md.supportsSignal("metrics_to_profiles") }, + "supportsTracesToLogs": func() bool { return md.supportsSignal("traces_to_logs") }, + "supportsTracesToMetrics": func() bool { return md.supportsSignal("traces_to_metrics") }, + "supportsTracesToTraces": func() bool { return md.supportsSignal("traces_to_traces") }, + "supportsTracesToProfiles": func() bool { return md.supportsSignal("traces_to_profiles") }, + "supportsProfilesToLogs": func() bool { return md.supportsSignal("profiles_to_logs") }, + "supportsProfilesToMetrics": func() bool { return md.supportsSignal("profiles_to_metrics") }, + "supportsProfilesToTraces": func() bool { return md.supportsSignal("profiles_to_traces") }, + "supportsProfilesToProfiles": func() bool { return md.supportsSignal("profiles_to_profiles") }, + "expectConsumerError": func() bool { + return md.Tests.ExpectConsumerError + }, + // ParseFS delegates the parsing of the files to `Glob` + // which uses the `\` as a special character. + // Meaning on windows based machines, the `\` needs to be replaced + // with a `/` for it to find the file. + } +} + +func templatize(tmplFile string, funcMap template.FuncMap) *template.Template { return template.Must( template. New(filepath.Base(tmplFile)). Option("missingkey=error"). - Funcs(map[string]any{ - "publicVar": func(s string) (string, error) { - return FormatIdentifier(s, true) - }, - "attributeInfo": func(an AttributeName) Attribute { - return md.Attributes[an] - }, - "getEventConditionalAttributes": func(attrs map[AttributeName]Attribute) []AttributeName { - seen := make(map[AttributeName]bool) - used := make([]AttributeName, 0) - - for _, event := range md.Events { - for _, attribute := range event.Attributes { - v, exists := attrs[attribute] - if exists && v.IsConditional() && !seen[attribute] { - used = append(used, attribute) - seen[attribute] = true - } - } - } - sort.Slice(used, func(i, j int) bool { return string(used[i]) < string(used[j]) }) - - return used - }, - "getMetricConditionalAttributes": func(attrs map[AttributeName]Attribute) []AttributeName { - seen := make(map[AttributeName]bool) - used := make([]AttributeName, 0) - - for _, event := range md.Metrics { - for _, attribute := range event.Attributes { - v, exists := attrs[attribute] - if exists && v.IsConditional() && !seen[attribute] { - used = append(used, attribute) - seen[attribute] = true - } - } - } - sort.Slice(used, func(i, j int) bool { return string(used[i]) < string(used[j]) }) - - return used - }, - "metricInfo": func(mn MetricName) Metric { - return md.Metrics[mn] - }, - "eventInfo": func(en EventName) Event { - return md.Events[en] - }, - "telemetryInfo": func(mn MetricName) Metric { - return md.Telemetry.Metrics[mn] - }, - "parseImportsRequired": func(metrics map[MetricName]Metric) bool { - for _, m := range metrics { - if m.Data().HasMetricInputType() { - return true - } - } - return false - }, - "stringsJoin": strings.Join, - "stringsSplit": strings.Split, - "userLinks": func(elems []string) []string { - result := make([]string, len(elems)) - for i, elem := range elems { - if elem == "open-telemetry/collector-approvers" { - result[i] = "[@open-telemetry/collector-approvers](https://github.com/orgs/open-telemetry/teams/collector-approvers)" - } else { - result[i] = fmt.Sprintf("[@%s](https://www.github.com/%s)", elem, elem) - } - } - return result - }, - "casesTitle": cases.Title(language.English).String, - "toLowerCase": strings.ToLower, - "toCamelCase": func(s string) string { - caser := cases.Title(language.English).String - parts := strings.Split(s, "_") - var result strings.Builder - for _, part := range parts { - fmt.Fprintf(&result, "%s", caser(part)) - } - return result.String() - }, - "inc": func(i int) int { return i + 1 }, - "distroURL": distroURL, - "isExporter": func() bool { - return md.Status.Class == "exporter" - }, - "isProcessor": func() bool { - return md.Status.Class == "processor" - }, - "isReceiver": func() bool { - return md.Status.Class == "receiver" - }, - "isExtension": func() bool { - return md.Status.Class == "extension" - }, - "isConnector": func() bool { - return md.Status.Class == "connector" - }, - "isScraper": func() bool { - return md.Status.Class == "scraper" - }, - "isCommand": func() bool { - return md.Status.Class == "cmd" - }, - "supportsLogs": func() bool { return md.supportsSignal("logs") }, - "supportsMetrics": func() bool { return md.supportsSignal("metrics") }, - "supportsTraces": func() bool { return md.supportsSignal("traces") }, - "supportsLogsToLogs": func() bool { return md.supportsSignal("logs_to_logs") }, - "supportsLogsToMetrics": func() bool { return md.supportsSignal("logs_to_metrics") }, - "supportsLogsToTraces": func() bool { return md.supportsSignal("logs_to_traces") }, - "supportsMetricsToLogs": func() bool { return md.supportsSignal("metrics_to_logs") }, - "supportsMetricsToMetrics": func() bool { return md.supportsSignal("metrics_to_metrics") }, - "supportsMetricsToTraces": func() bool { return md.supportsSignal("metrics_to_traces") }, - "supportsTracesToLogs": func() bool { return md.supportsSignal("traces_to_logs") }, - "supportsTracesToMetrics": func() bool { return md.supportsSignal("traces_to_metrics") }, - "supportsTracesToTraces": func() bool { return md.supportsSignal("traces_to_traces") }, - "expectConsumerError": func() bool { - return md.Tests.ExpectConsumerError - }, - // ParseFS delegates the parsing of the files to `Glob` - // which uses the `\` as a special character. - // Meaning on windows based machines, the `\` needs to be replaced - // with a `/` for it to find the file. - }).ParseFS(TemplateFS, "templates/helper.tmpl", strings.ReplaceAll(tmplFile, "\\", "/"))) + Funcs(funcMap). + ParseFS(TemplateFS, "templates/helper.tmpl", strings.ReplaceAll(tmplFile, "\\", "/"))) } -func executeTemplate(tmplFile string, md Metadata, goPackage string) ([]byte, error) { - tmpl := templatize(tmplFile, md) +func executeTemplate(tmplFile string, md Metadata, goPackage, importRootPath string, fns template.FuncMap) ([]byte, error) { + tmpl := templatize(tmplFile, fns) buf := bytes.Buffer{} - if err := tmpl.Execute(&buf, TemplateContext{Metadata: md, Package: goPackage}); err != nil { + if err := tmpl.Execute(&buf, TemplateContext{Metadata: md, Package: goPackage, ImportRootPath: importRootPath}); err != nil { return []byte{}, fmt.Errorf("failed executing template: %w", err) } return buf.Bytes(), nil } -func inlineReplace(tmplFile, outputFile string, md Metadata, start, end, goPackage string) error { +func generateFile(tmplFile, outputFile string, md Metadata, goPackage, importRootPath string) error { + return generateFileWithFns(tmplFile, outputFile, md, goPackage, importRootPath, getTemplateFuncMap(md, importRootPath)) +} + +func inlineReplace(tmplFile, outputFile string, md Metadata, start, end, goPackage, importRootPath string) error { var readmeContents []byte var err error - if readmeContents, err = os.ReadFile(outputFile); err != nil { //nolint:gosec + if readmeContents, err = os.ReadFile(filepath.Clean(outputFile)); err != nil { return err } @@ -377,7 +443,7 @@ func inlineReplace(tmplFile, outputFile string, md Metadata, start, end, goPacka md.GithubProject = "open-telemetry/opentelemetry-collector-contrib" } - buf, err := executeTemplate(tmplFile, md, goPackage) + buf, err := executeTemplate(tmplFile, md, goPackage, importRootPath, getTemplateFuncMap(md, importRootPath)) if err != nil { return err } @@ -390,12 +456,12 @@ func inlineReplace(tmplFile, outputFile string, md Metadata, start, end, goPacka return nil } -func generateFile(tmplFile, outputFile string, md Metadata, goPackage string) error { +func generateFileWithFns(tmplFile, outputFile string, md Metadata, goPackage, importRootPath string, fns template.FuncMap) error { if err := os.Remove(outputFile); err != nil && !errors.Is(err, fs.ErrNotExist) { return fmt.Errorf("unable to remove generated file %q: %w", outputFile, err) } - result, err := executeTemplate(tmplFile, md, goPackage) + result, err := executeTemplate(tmplFile, md, goPackage, importRootPath, fns) if err != nil { return err } @@ -474,3 +540,50 @@ func validateYAMLKeyOrder(raw []byte) error { } return nil } + +func generateConfigFiles(md Metadata, mdDir, _ string) error { + if md.Config != nil { + resolver := cfggen.NewResolver(md.PackageName, md.Status.Class, md.Type, mdDir) + resolvedSchema, err := resolver.ResolveSchema(md.Config) + if err != nil { + return fmt.Errorf("failed to resolve config schema: %w", err) + } + + err = cfggen.WriteJSONSchema(mdDir, resolvedSchema) + if err != nil { + return fmt.Errorf("failed to write config schema: %w", err) + } + + if err := generateConfigGoStruct(md, mdDir); err != nil { + return fmt.Errorf("failed to generate config Go struct: %w", err) + } + } + return nil +} + +func generateConfigGoStruct(md Metadata, outputDir string) error { + rootPkg, err := helpers.RootPackage(outputDir) + if err != nil { + return fmt.Errorf("unable to determine root package: %w", err) + } + + packageName := filepath.Base(outputDir) + tmplFile := filepath.Join("templates", "config_from_cfggen.go.tmpl") + dstFile := filepath.Join(outputDir, "generated_config.go") + + fns := cfggen.WithCfgFns(getTemplateFuncMap(md, rootPkg), rootPkg, md.PackageName) + return generateFileWithFns(tmplFile, dstFile, md, packageName, rootPkg, fns) +} + +func joinCamelCase(parts []string, exported bool) string { + caser := cases.Title(language.English).String + var result strings.Builder + for i, part := range parts { + if i == 0 && !exported { + fmt.Fprintf(&result, "%s", strings.ToLower(part)) + } else { + fmt.Fprintf(&result, "%s", caser(part)) + } + } + return result.String() +} diff --git a/cmd/mdatagen/internal/command_test.go b/cmd/mdatagen/internal/command_test.go index 2a70c4ef693c..11ff9f5bd12c 100644 --- a/cmd/mdatagen/internal/command_test.go +++ b/cmd/mdatagen/internal/command_test.go @@ -9,13 +9,16 @@ import ( "go/parser" "go/token" "os" + "os/exec" "path/filepath" + "strings" "testing" "github.com/spf13/cobra" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + "go.opentelemetry.io/collector/cmd/mdatagen/internal/cfggen" "go.opentelemetry.io/collector/component" ) @@ -29,6 +32,33 @@ func TestNewCommand(t *testing.T) { assert.True(t, cmd.SilenceUsage) } +func TestCommandNoArgs(t *testing.T) { + cmd, err := NewCommand() + require.NoError(t, err) + + cmd.SetArgs([]string{}) + err = cmd.Execute() + + require.Error(t, err) +} + +func TestCommandErrorOutputOnce(t *testing.T) { + cmd, err := NewCommand() + require.NoError(t, err) + + var stderr bytes.Buffer + cmd.SetErr(&stderr) + cmd.SetArgs([]string{"/nonexistent/path/metadata.yaml"}) + + err = cmd.Execute() + require.Error(t, err) + out := stderr.String() + require.NotEmpty(t, out) + + msg := err.Error() + assert.Equal(t, 1, strings.Count(out, msg), out) +} + func TestRunContents(t *testing.T) { tests := []struct { yml string @@ -47,8 +77,12 @@ func TestRunContents(t *testing.T) { wantGoleakSkip bool wantGoleakSetup bool wantGoleakTeardown bool + wantFeatureGatesGenerated bool + wantConfigSchemaGenerated bool + wantMetricsSchemaYamlGenerated bool wantErr bool wantOrderErr bool + wantRunErr bool wantAttributes []string }{ { @@ -81,12 +115,13 @@ func TestRunContents(t *testing.T) { wantReadmeGenerated: true, }, { - yml: "metrics_and_type.yaml", - wantMetricsGenerated: true, - wantConfigGenerated: true, - wantStatusGenerated: true, - wantReadmeGenerated: true, - wantComponentTestGenerated: true, + yml: "metrics_and_type.yaml", + wantMetricsGenerated: true, + wantConfigGenerated: true, + wantStatusGenerated: true, + wantReadmeGenerated: true, + wantComponentTestGenerated: true, + wantMetricsSchemaYamlGenerated: true, }, { yml: "resource_attributes_only.yaml", @@ -96,6 +131,7 @@ func TestRunContents(t *testing.T) { wantReadmeGenerated: true, wantComponentTestGenerated: true, wantLogsGenerated: true, + wantMetricsSchemaYamlGenerated: true, }, { yml: "status_only.yaml", @@ -134,6 +170,12 @@ func TestRunContents(t *testing.T) { wantReadmeGenerated: true, wantComponentTestGenerated: true, }, + { + yml: "with_tests_profiles_connector.yaml", + wantStatusGenerated: true, + wantReadmeGenerated: true, + wantComponentTestGenerated: true, + }, { yml: "with_goleak_ignores.yaml", wantStatusGenerated: true, @@ -178,12 +220,13 @@ func TestRunContents(t *testing.T) { wantComponentTestGenerated: true, }, { - yml: "async_metric.yaml", - wantMetricsGenerated: true, - wantConfigGenerated: true, - wantStatusGenerated: true, - wantReadmeGenerated: true, - wantComponentTestGenerated: true, + yml: "async_metric.yaml", + wantMetricsGenerated: true, + wantConfigGenerated: true, + wantStatusGenerated: true, + wantReadmeGenerated: true, + wantComponentTestGenerated: true, + wantMetricsSchemaYamlGenerated: true, }, { yml: "custom_generated_package_name.yaml", @@ -193,22 +236,43 @@ func TestRunContents(t *testing.T) { wantLogsGenerated: true, }, { - yml: "with_conditional_attribute.yaml", + yml: "feature_gates.yaml", wantStatusGenerated: true, wantReadmeGenerated: true, - wantMetricsGenerated: true, - wantLogsGenerated: true, - wantConfigGenerated: true, wantComponentTestGenerated: true, + wantFeatureGatesGenerated: true, + }, + { + yml: "with_conditional_attribute.yaml", + wantStatusGenerated: true, + wantReadmeGenerated: true, + wantMetricsGenerated: true, + wantLogsGenerated: true, + wantConfigGenerated: true, + wantComponentTestGenerated: true, + wantMetricsSchemaYamlGenerated: true, }, { - yml: "events/basic_event.yaml", + yml: "events/basic_event.yaml", + wantStatusGenerated: true, + wantReadmeGenerated: true, + wantComponentTestGenerated: true, + wantConfigGenerated: true, + wantEventsGenerated: true, + wantLogsGenerated: true, + wantMetricsSchemaYamlGenerated: true, + }, + { + yml: "with_config.yaml", wantStatusGenerated: true, wantReadmeGenerated: true, - wantComponentTestGenerated: true, - wantConfigGenerated: true, - wantEventsGenerated: true, wantLogsGenerated: true, + wantComponentTestGenerated: true, + wantConfigSchemaGenerated: true, + }, + { + yml: "with_invalid_config_ref.yaml", + wantRunErr: true, }, } for _, tt := range tests { @@ -216,6 +280,9 @@ func TestRunContents(t *testing.T) { tmpdir := filepath.Join(t.TempDir(), "shortname") err := os.MkdirAll(tmpdir, 0o750) require.NoError(t, err) + // Init a git repo so helpers.RootPackage can resolve the repo root + // when generateConfigGoStruct is called for components with config. + gitInit(t, tmpdir) ymlContent, err := os.ReadFile(filepath.Join("testdata", tt.yml)) require.NoError(t, err) metadataFile := filepath.Join(tmpdir, "metadata.yaml") @@ -244,21 +311,29 @@ foo require.Contains(t, err.Error(), "metadata.yaml ordering check failed") return } + if tt.wantRunErr { + require.Error(t, err) + require.Contains(t, err.Error(), "failed to generate config files") + return + } require.NoError(t, err) + // Documentation is generated when any of these features are present + wantDocumentationGenerated := tt.wantFeatureGatesGenerated || tt.wantMetricsGenerated || tt.wantTelemetryGenerated || tt.wantResourceAttributesGenerated || tt.wantEventsGenerated + var contents []byte if tt.wantMetricsGenerated { require.FileExists(t, filepath.Join(tmpdir, generatedPackageDir, "generated_metrics.go")) require.FileExists(t, filepath.Join(tmpdir, generatedPackageDir, "generated_metrics_test.go")) require.FileExists(t, filepath.Join(tmpdir, "documentation.md")) if len(tt.wantAttributes) > 0 { - contents, err = os.ReadFile(filepath.Join(tmpdir, "documentation.md")) //nolint:gosec + contents, err = os.ReadFile(filepath.Clean(filepath.Join(tmpdir, "documentation.md"))) require.NoError(t, err) for _, attr := range tt.wantAttributes { require.Contains(t, string(contents), attr) } } - contents, err = os.ReadFile(filepath.Join(tmpdir, generatedPackageDir, "generated_metrics.go")) //nolint:gosec + contents, err = os.ReadFile(filepath.Clean(filepath.Join(tmpdir, generatedPackageDir, "generated_metrics.go"))) require.NoError(t, err) if tt.wantMetricsContext { require.Contains(t, string(contents), "\"context\"") @@ -290,7 +365,7 @@ foo require.FileExists(t, filepath.Join(tmpdir, generatedPackageDir, "generated_telemetry.go")) require.FileExists(t, filepath.Join(tmpdir, generatedPackageDir, "generated_telemetry_test.go")) require.FileExists(t, filepath.Join(tmpdir, "documentation.md")) - contents, err = os.ReadFile(filepath.Join(tmpdir, generatedPackageDir, "generated_telemetry.go")) //nolint:gosec + contents, err = os.ReadFile(filepath.Clean(filepath.Join(tmpdir, generatedPackageDir, "generated_telemetry.go"))) require.NoError(t, err) if tt.wantMetricsContext { require.Contains(t, string(contents), "\"context\"") @@ -301,7 +376,9 @@ foo require.NoFileExists(t, filepath.Join(tmpdir, generatedPackageDir, "generated_telemetry.go")) } - if !tt.wantMetricsGenerated && !tt.wantTelemetryGenerated && !tt.wantResourceAttributesGenerated && !tt.wantEventsGenerated { + if wantDocumentationGenerated { + require.FileExists(t, filepath.Join(tmpdir, "documentation.md")) + } else { require.NoFileExists(t, filepath.Join(tmpdir, "documentation.md")) } @@ -311,7 +388,7 @@ foo require.NoFileExists(t, filepath.Join(tmpdir, generatedPackageDir, "generated_status.go")) } - contents, err = os.ReadFile(filepath.Join(tmpdir, "README.md")) //nolint:gosec + contents, err = os.ReadFile(filepath.Clean(filepath.Join(tmpdir, "README.md"))) require.NoError(t, err) if tt.wantReadmeGenerated { require.NotContains(t, string(contents), "foo") @@ -321,7 +398,7 @@ foo if tt.wantComponentTestGenerated { require.FileExists(t, filepath.Join(tmpdir, "generated_component_test.go")) - contents, err = os.ReadFile(filepath.Join(tmpdir, "generated_component_test.go")) //nolint:gosec + contents, err = os.ReadFile(filepath.Clean(filepath.Join(tmpdir, "generated_component_test.go"))) require.NoError(t, err) require.Contains(t, string(contents), "func Test") _, err = parser.ParseFile(token.NewFileSet(), "", contents, parser.DeclarationErrors) @@ -331,7 +408,7 @@ foo } require.FileExists(t, filepath.Join(tmpdir, "generated_package_test.go")) - contents, err = os.ReadFile(filepath.Join(tmpdir, "generated_package_test.go")) //nolint:gosec + contents, err = os.ReadFile(filepath.Clean(filepath.Join(tmpdir, "generated_package_test.go"))) require.NoError(t, err) require.Contains(t, string(contents), "func TestMain") _, err = parser.ParseFile(token.NewFileSet(), "", contents, parser.DeclarationErrors) @@ -362,10 +439,152 @@ foo } else { require.NotContains(t, string(contents), "teardownFunc") } + + if tt.wantConfigSchemaGenerated { + require.FileExists(t, filepath.Join(tmpdir, "config.schema.json")) + } else { + require.NoFileExists(t, filepath.Join(tmpdir, "config.schema.json")) + } + + schemaYamlPath := filepath.Join(tmpdir, generatedPackageDir, "config.schema.yaml") + if tt.wantMetricsSchemaYamlGenerated { + require.FileExists(t, schemaYamlPath) + contents, err = os.ReadFile(filepath.Clean(schemaYamlPath)) + require.NoError(t, err) + require.Contains(t, string(contents), "# Code generated by mdatagen. DO NOT EDIT.") + require.Contains(t, string(contents), "$defs:") + if tt.wantMetricsGenerated { + require.Contains(t, string(contents), "metrics_config:") + require.Contains(t, string(contents), "metrics_builder_config:") + } + if tt.wantEventsGenerated { + require.Contains(t, string(contents), "events_config:") + require.Contains(t, string(contents), "logs_builder_config:") + } + if tt.wantResourceAttributesGenerated { + require.Contains(t, string(contents), "resource_attributes_config:") + } + } else { + require.NoFileExists(t, schemaYamlPath) + } }) } } +func TestGenerateConfigFiles(t *testing.T) { + tests := []struct { + name string + md Metadata + wantErr bool + wantGen bool + }{ + { + name: "nil config skips generation", + md: Metadata{ + Type: "test", + Status: &Status{ + Class: "receiver", + }, + Config: nil, + }, + wantGen: false, + }, + { + name: "valid config generates schema file", + md: Metadata{ + Type: "test", + PackageName: "shortname", + Status: &Status{ + Class: "receiver", + }, + Config: &cfggen.ConfigMetadata{ + Type: "object", + }, + }, + wantGen: true, + }, + { + name: "invalid ref in config causes resolve error", + md: Metadata{ + Type: "test", + PackageName: "shortname", + Status: &Status{ + Class: "receiver", + }, + // A local ref without a definition name fails Validate() inside ResolveSchema + Config: &cfggen.ConfigMetadata{ + Ref: "/config/configauth", + }, + }, + wantErr: true, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + root := t.TempDir() + + tmpdir := filepath.Join(root, "shortname") + require.NoError(t, os.MkdirAll(tmpdir, 0o700)) + + gitInit(t, root) + require.NoError(t, os.WriteFile(filepath.Join(root, "go.mod"), []byte("module testmodule\n"), 0o600)) + err := generateConfigFiles(tt.md, tmpdir, "testmodule") + if tt.wantErr { + require.Error(t, err) + return + } + require.NoError(t, err) + if tt.wantGen { + require.FileExists(t, filepath.Join(tmpdir, "config.schema.json")) + } else { + require.NoFileExists(t, filepath.Join(tmpdir, "config.schema.json")) + } + }) + } +} + +func TestGenerateConfigGoStruct_RootPackageError(t *testing.T) { + // tmpdir is not inside any git repo, so helpers.RootPackage fails + md := Metadata{ + Type: "test", + PackageName: "shortname", + Status: &Status{Class: "receiver"}, + Config: &cfggen.ConfigMetadata{Type: "object"}, + } + err := generateConfigGoStruct(md, t.TempDir()) + require.Error(t, err) + require.Contains(t, err.Error(), "unable to determine root package") +} + +func TestGenerateConfigFiles_GoStructError(t *testing.T) { + // generateConfigGoStruct fails because tmpdir is not inside a git repo + md := Metadata{ + Type: "test", + PackageName: "shortname", + Status: &Status{Class: "receiver"}, + Config: &cfggen.ConfigMetadata{Type: "object"}, + } + err := generateConfigFiles(md, t.TempDir(), "testmodule") + require.Error(t, err) + require.Contains(t, err.Error(), "failed to generate config Go struct") +} + +func TestGenerateConfigFiles_WriteError(t *testing.T) { + md := Metadata{ + Type: "test", + PackageName: "shortname", + Status: &Status{ + Class: "receiver", + }, + Config: &cfggen.ConfigMetadata{ + Type: "object", + }, + } + err := generateConfigFiles(md, "/nonexistent/path/that/does/not/exist", "testmodule") + require.Error(t, err) + require.Contains(t, err.Error(), "failed to write config schema") +} + func TestRun(t *testing.T) { type args struct { ymlPath string @@ -636,11 +855,11 @@ Some info about a component readmeFile := filepath.Join(tmpdir, "README.md") require.NoError(t, os.WriteFile(readmeFile, []byte(tt.markdown), 0o600)) - err := inlineReplace("templates/readme.md.tmpl", readmeFile, md, statusStart, statusEnd, "metadata") + err := inlineReplace("templates/readme.md.tmpl", readmeFile, md, statusStart, statusEnd, "metadata", "go.opentelemetry.io/collector") require.NoError(t, err) require.FileExists(t, filepath.Join(tmpdir, "README.md")) - got, err := os.ReadFile(filepath.Join(tmpdir, "README.md")) //nolint:gosec + got, err := os.ReadFile(filepath.Clean(filepath.Join(tmpdir, "README.md"))) require.NoError(t, err) got = bytes.ReplaceAll(got, []byte("\r\n"), []byte("\n")) expected, err := os.ReadFile(filepath.Join("testdata", tt.outputFile)) @@ -718,6 +937,38 @@ var ( const ( MetricsStability = component.StabilityLevelAlpha ) +`, + }, + { + name: "foo component with deprecated type", + md: Metadata{ + Type: "foo", + DeprecatedType: "old_foo", + Status: &Status{ + Stability: map[component.StabilityLevel][]string{ + component.StabilityLevelBeta: {"metrics"}, + }, + Distributions: []string{"contrib"}, + Class: "receiver", + }, + }, + expected: `// Code generated by mdatagen. DO NOT EDIT. + +package metadata + +import ( + "go.opentelemetry.io/collector/component" +) + +var ( + Type = component.MustNewType("foo") + DeprecatedType = component.MustNewType("old_foo") + ScopeName = "" +) + +const ( + MetricsStability = component.StabilityLevelBeta +) `, }, } @@ -726,9 +977,9 @@ const ( t.Run(tt.name, func(t *testing.T) { tmpdir := t.TempDir() err := generateFile("templates/status.go.tmpl", - filepath.Join(tmpdir, "generated_status.go"), tt.md, "metadata") + filepath.Join(tmpdir, "generated_status.go"), tt.md, "metadata", "go.opentelemetry.io/collector") require.NoError(t, err) - actual, err := os.ReadFile(filepath.Join(tmpdir, "generated_status.go")) //nolint:gosec + actual, err := os.ReadFile(filepath.Clean(filepath.Join(tmpdir, "generated_status.go"))) require.NoError(t, err) require.Equal(t, tt.expected, string(actual)) }) @@ -812,11 +1063,51 @@ func Tracer(settings component.TelemetrySettings) trace.Tracer { t.Run(tt.name, func(t *testing.T) { tmpdir := t.TempDir() err := generateFile("templates/telemetry.go.tmpl", - filepath.Join(tmpdir, "generated_telemetry.go"), tt.md, "metadata") + filepath.Join(tmpdir, "generated_telemetry.go"), tt.md, "metadata", "go.opentelemetry.io/collector") require.NoError(t, err) - actual, err := os.ReadFile(filepath.Join(tmpdir, "generated_telemetry.go")) //nolint:gosec + actual, err := os.ReadFile(filepath.Clean(filepath.Join(tmpdir, "generated_telemetry.go"))) require.NoError(t, err) require.Equal(t, tt.expected, string(actual)) }) } } + +func TestGenerateConfigSchema_LocalizesSameRootRefs(t *testing.T) { + enabled := true + md := Metadata{ + Type: "foo", + ResourceAttributes: map[AttributeName]Attribute{ + "resource.attr": { + Description: "resource attr", + EnabledPtr: &enabled, + FullName: "resource.attr", + }, + }, + Events: map[EventName]Event{ + "default.event": { + Signal: Signal{ + Enabled: true, + Description: "event description", + }, + }, + }, + } + + tmpdir := t.TempDir() + outputFile := filepath.Join(tmpdir, "config.schema.yaml") + err := generateFile("templates/config.schema.yaml.tmpl", outputFile, md, "metadata", "go.opentelemetry.io/collector") + require.NoError(t, err) + + actual, err := os.ReadFile(filepath.Clean(outputFile)) + require.NoError(t, err) + require.Contains(t, string(actual), "$ref: /filter.config") + require.NotContains(t, string(actual), "$ref: go.opentelemetry.io/collector/filter.config") +} + +func gitInit(t *testing.T, dir string) { + t.Helper() + cmd := exec.Command("git", "init") + cmd.Dir = dir + out, err := cmd.CombinedOutput() + require.NoError(t, err, "git init failed: %s", out) +} diff --git a/cmd/mdatagen/internal/embedded_templates_test.go b/cmd/mdatagen/internal/embedded_templates_test.go index c3f7c0bcf3cc..0e6858d35a05 100644 --- a/cmd/mdatagen/internal/embedded_templates_test.go +++ b/cmd/mdatagen/internal/embedded_templates_test.go @@ -31,6 +31,7 @@ func TestEnsureTemplatesLoaded(t *testing.T) { path.Join(rootDir, "resource_test.go.tmpl"): {}, path.Join(rootDir, "config.go.tmpl"): {}, path.Join(rootDir, "config_test.go.tmpl"): {}, + path.Join(rootDir, "config.schema.yaml.tmpl"): {}, path.Join(rootDir, "package_test.go.tmpl"): {}, path.Join(rootDir, "readme.md.tmpl"): {}, path.Join(rootDir, "status.go.tmpl"): {}, @@ -40,6 +41,11 @@ func TestEnsureTemplatesLoaded(t *testing.T) { path.Join(rootDir, "telemetrytest.go.tmpl"): {}, path.Join(rootDir, "telemetrytest_test.go.tmpl"): {}, path.Join(rootDir, "helper.tmpl"): {}, + path.Join(rootDir, "feature_gates.md.tmpl"): {}, + path.Join(rootDir, "feature_gates.go.tmpl"): {}, + path.Join(rootDir, "config_from_cfggen.go.tmpl"): {}, + path.Join(rootDir, "entity_metrics.go.tmpl"): {}, + path.Join(rootDir, "entity_metrics_test.go.tmpl"): {}, } count = 0 ) diff --git a/cmd/mdatagen/internal/event.go b/cmd/mdatagen/internal/event.go index 9f89d973d320..328243879dde 100644 --- a/cmd/mdatagen/internal/event.go +++ b/cmd/mdatagen/internal/event.go @@ -6,6 +6,7 @@ package internal // import "go.opentelemetry.io/collector/cmd/mdatagen/internal" import ( "errors" + "go.opentelemetry.io/collector/cmd/mdatagen/internal/helpers" "go.opentelemetry.io/collector/confmap" ) @@ -14,11 +15,11 @@ type ( ) func (ln EventName) Render() (string, error) { - return FormatIdentifier(string(ln), true) + return helpers.FormatIdentifier(string(ln), true) } func (ln EventName) RenderUnexported() (string, error) { - return FormatIdentifier(string(ln), false) + return helpers.FormatIdentifier(string(ln), false) } type Event struct { diff --git a/cmd/mdatagen/internal/lint.go b/cmd/mdatagen/internal/helpers/lint.go similarity index 94% rename from cmd/mdatagen/internal/lint.go rename to cmd/mdatagen/internal/helpers/lint.go index b4b2f2f3c03c..55e1602aee1e 100644 --- a/cmd/mdatagen/internal/lint.go +++ b/cmd/mdatagen/internal/helpers/lint.go @@ -1,7 +1,7 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -package internal // import "go.opentelemetry.io/collector/cmd/mdatagen/internal" +package helpers // import "go.opentelemetry.io/collector/cmd/mdatagen/internal/helpers" import ( "errors" diff --git a/cmd/mdatagen/internal/lint_test.go b/cmd/mdatagen/internal/helpers/lint_test.go similarity index 98% rename from cmd/mdatagen/internal/lint_test.go rename to cmd/mdatagen/internal/helpers/lint_test.go index feca8fac27bb..19f97537864d 100644 --- a/cmd/mdatagen/internal/lint_test.go +++ b/cmd/mdatagen/internal/helpers/lint_test.go @@ -1,7 +1,7 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -package internal +package helpers import ( "testing" diff --git a/cmd/mdatagen/internal/helpers/packages.go b/cmd/mdatagen/internal/helpers/packages.go new file mode 100644 index 000000000000..712a864e30e1 --- /dev/null +++ b/cmd/mdatagen/internal/helpers/packages.go @@ -0,0 +1,45 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +package helpers // import "go.opentelemetry.io/collector/cmd/mdatagen/internal/helpers" + +import ( + "errors" + "fmt" + "os" + "os/exec" + "path/filepath" + "strings" +) + +// RootPackage determines the root Go module path by reading the module directive +// from the go.mod at the repository root. This is used to resolve local absolute +// references (e.g., "/config/confighttp.client_config") into full Go import paths. +func RootPackage(componentDir string) (string, error) { + repoRoot, err := repoRoot(componentDir) + if err != nil { + return "", err + } + + goModData, err := os.ReadFile(filepath.Clean(filepath.Join(repoRoot, "go.mod"))) + if err != nil { + return "", fmt.Errorf("failed to read root go.mod: %w", err) + } + + for line := range strings.SplitSeq(string(goModData), "\n") { + if after, ok := strings.CutPrefix(strings.TrimSpace(line), "module "); ok { + return strings.TrimSpace(after), nil + } + } + return "", errors.New("module directive not found in root go.mod") +} + +func repoRoot(dir string) (string, error) { + cmd := exec.Command("git", "rev-parse", "--show-toplevel") + cmd.Dir = dir + output, err := cmd.Output() + if err != nil { + return "", fmt.Errorf("failed to find repo root: %w", err) + } + return strings.TrimSpace(string(output)), nil +} diff --git a/cmd/mdatagen/internal/helpers/packages_test.go b/cmd/mdatagen/internal/helpers/packages_test.go new file mode 100644 index 000000000000..c9bf1b9f9fb9 --- /dev/null +++ b/cmd/mdatagen/internal/helpers/packages_test.go @@ -0,0 +1,107 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +package helpers + +import ( + "os" + "os/exec" + "path/filepath" + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func TestRepoRoot(t *testing.T) { + t.Run("returns_repo_root_from_subdirectory", func(t *testing.T) { + wd, err := os.Getwd() + require.NoError(t, err) + + root, err := repoRoot(wd) + require.NoError(t, err) + assert.DirExists(t, root) + assert.FileExists(t, filepath.Join(root, "go.mod")) + }) + + t.Run("error_for_nonexistent_directory", func(t *testing.T) { + _, err := repoRoot("/nonexistent/path/that/does/not/exist") + require.Error(t, err) + }) + + t.Run("error_outside_git_repo", func(t *testing.T) { + tmp := t.TempDir() + _, err := repoRoot(tmp) + require.Error(t, err) + }) +} + +func TestRootPackage(t *testing.T) { + t.Run("returns_correct_module_path", func(t *testing.T) { + wd, err := os.Getwd() + require.NoError(t, err) + + pkg, err := RootPackage(wd) + require.NoError(t, err) + assert.Equal(t, "go.opentelemetry.io/collector", pkg) + }) + + t.Run("error_for_nonexistent_directory", func(t *testing.T) { + _, err := RootPackage("/nonexistent/path/that/does/not/exist") + require.Error(t, err) + }) + + t.Run("error_when_go_mod_missing", func(t *testing.T) { + tmp := t.TempDir() + subDir := filepath.Join(tmp, "sub") + require.NoError(t, os.MkdirAll(subDir, 0o700)) + + gitInit(t, tmp) + + _, err := RootPackage(subDir) + require.Error(t, err) + assert.Contains(t, err.Error(), "go.mod") + }) + + t.Run("error_when_go_mod_has_no_module_directive", func(t *testing.T) { + tmp := t.TempDir() + subDir := filepath.Join(tmp, "sub") + require.NoError(t, os.MkdirAll(subDir, 0o700)) + + gitInit(t, tmp) + require.NoError(t, os.WriteFile( + filepath.Join(tmp, "go.mod"), + []byte("go 1.21\n"), + 0o600, + )) + + _, err := RootPackage(subDir) + require.Error(t, err) + assert.Contains(t, err.Error(), "module directive not found") + }) + + t.Run("parses_module_from_synthetic_go_mod", func(t *testing.T) { + tmp := t.TempDir() + subDir := filepath.Join(tmp, "pkg", "foo") + require.NoError(t, os.MkdirAll(subDir, 0o700)) + + gitInit(t, tmp) + require.NoError(t, os.WriteFile( + filepath.Join(tmp, "go.mod"), + []byte("module example.com/my-project\n\ngo 1.21\n"), + 0o600, + )) + + pkg, err := RootPackage(subDir) + require.NoError(t, err) + assert.Equal(t, "example.com/my-project", pkg) + }) +} + +func gitInit(t *testing.T, dir string) { + t.Helper() + cmd := exec.Command("git", "init") + cmd.Dir = dir + out, err := cmd.CombinedOutput() + require.NoError(t, err, "git init failed: %s", out) +} diff --git a/cmd/mdatagen/internal/loader.go b/cmd/mdatagen/internal/loader.go index 159c1daada8e..df5cc1ce5106 100644 --- a/cmd/mdatagen/internal/loader.go +++ b/cmd/mdatagen/internal/loader.go @@ -29,6 +29,8 @@ type TemplateContext struct { Metadata // Package name for generated code. Package string + // ImportRootPath is the repo-local import prefix used to localize same-tree schema references. + ImportRootPath string } func LoadMetadata(filePath string) (Metadata, error) { diff --git a/cmd/mdatagen/internal/loader_test.go b/cmd/mdatagen/internal/loader_test.go index e5b8afbd7417..27c24655f818 100644 --- a/cmd/mdatagen/internal/loader_test.go +++ b/cmd/mdatagen/internal/loader_test.go @@ -10,6 +10,7 @@ import ( "github.com/stretchr/testify/require" + "go.opentelemetry.io/collector/cmd/mdatagen/internal/cfggen" "go.opentelemetry.io/collector/component" "go.opentelemetry.io/collector/pdata/pcommon" "go.opentelemetry.io/collector/pdata/pmetric" @@ -47,8 +48,11 @@ func TestLoadMetadata(t *testing.T) { GithubProject: "open-telemetry/opentelemetry-collector", GeneratedPackageName: "metadata", Type: "sample", - SemConvVersion: "1.37.0", + DisplayName: "Sample Receiver", + Description: "This receiver is used for testing purposes to check the output of mdatagen.", + SemConvVersion: "1.38.0", PackageName: "go.opentelemetry.io/collector/cmd/mdatagen/internal/samplereceiver", + ReaggregationEnabled: true, Status: &Status{ DisableCodeCov: true, Class: "receiver", @@ -71,6 +75,28 @@ func TestLoadMetadata(t *testing.T) { Warnings: []string{"Any additional information that should be brought to the consumer's attention"}, UnsupportedPlatforms: []string{"freebsd", "illumos"}, }, + Config: &cfggen.ConfigMetadata{ + Type: "object", + AllOf: []*cfggen.ConfigMetadata{ + { + Ref: "./internal/metadata.metrics_builder_config", + }, + }, + Properties: map[string]*cfggen.ConfigMetadata{ + "endpoint": { + Description: "The endpoint to scrape metrics from.", + Type: "string", + Default: "localhost:12345", + }, + "timeout": { + Description: "Timeout for scraping metrics.", + Type: "string", + Format: "duration", + Default: "10s", + }, + }, + Required: []string{"endpoint"}, + }, ResourceAttributes: map[AttributeName]Attribute{ "string.resource.attr": { Description: "Resource attribute with any string value.", @@ -241,6 +267,14 @@ func TestLoadMetadata(t *testing.T) { FullName: "opt_in_bool_attr", RequirementLevel: AttributeRequirementLevelOptIn, }, + "required_string_attr": { + Description: "A required attribute with a string value", + Type: ValueType{ + ValueType: pcommon.ValueTypeStr, + }, + FullName: "required_string_attr", + RequirementLevel: AttributeRequirementLevelRequired, + }, }, Metrics: map[MetricName]Metric{ "default.metric": { @@ -248,7 +282,7 @@ func TestLoadMetadata(t *testing.T) { Enabled: true, Description: "Monotonic cumulative sum int metric enabled by default.", ExtendedDocumentation: "The metric will be become optional soon.", - Stability: Stability{Level: component.StabilityLevelDevelopment}, + Stability: component.StabilityLevelDeprecated, Warnings: Warnings{ IfEnabledNotSet: "This metric will be disabled by default soon.", }, @@ -260,12 +294,40 @@ func TestLoadMetadata(t *testing.T) { AggregationTemporality: AggregationTemporality{Aggregation: pmetric.AggregationTemporalityCumulative}, Mono: Mono{Monotonic: true}, }, + Deprecated: &Deprecated{ + Since: "1.0.0", + Note: "This metric will be removed", + }, + }, + "reaggregate.metric": { + Signal: Signal{ + Enabled: true, + Description: "Metric for testing spatial reaggregation", + Stability: component.StabilityLevelBeta, + Attributes: []AttributeName{"string_attr", "boolean_attr"}, + }, + Unit: strPtr("1"), + Gauge: &Gauge{ + MetricValueType: MetricValueType{pmetric.NumberDataPointValueTypeDouble}, + }, + }, + "reaggregate.metric.with_required": { + Signal: Signal{ + Enabled: true, + Description: "Metric for testing spatial reaggregation with required attributes", + Stability: component.StabilityLevelBeta, + Attributes: []AttributeName{"required_string_attr", "string_attr", "boolean_attr"}, + }, + Unit: strPtr("1"), + Gauge: &Gauge{ + MetricValueType: MetricValueType{pmetric.NumberDataPointValueTypeDouble}, + }, }, "system.cpu.time": { Signal: Signal{ Enabled: true, - Stability: Stability{Level: component.StabilityLevelBeta}, - SemanticConvention: &SemanticConvention{SemanticConventionRef: "https://github.com/open-telemetry/semantic-conventions/blob/v1.37.0/docs/system/system-metrics.md#metric-systemcputime"}, + Stability: component.StabilityLevelBeta, + SemanticConvention: &SemanticConvention{SemanticConventionRef: "https://github.com/open-telemetry/semantic-conventions/blob/v1.38.0/docs/system/system-metrics.md#metric-systemcputime"}, Description: "Monotonic cumulative sum int metric enabled by default.", ExtendedDocumentation: "The metric will be become optional soon.", }, @@ -280,12 +342,16 @@ func TestLoadMetadata(t *testing.T) { Signal: Signal{ Enabled: false, Description: "[DEPRECATED] Gauge double metric disabled by default.", - Stability: Stability{Level: component.StabilityLevelDeprecated}, + Stability: component.StabilityLevelDeprecated, Warnings: Warnings{ IfConfigured: "This metric is deprecated and will be removed soon.", }, Attributes: []AttributeName{"string_attr", "boolean_attr", "boolean_attr2", "conditional_string_attr"}, }, + Deprecated: &Deprecated{ + Since: "1.0.0", + Note: "This metric will be removed", + }, Unit: strPtr("1"), Gauge: &Gauge{ MetricValueType: MetricValueType{pmetric.NumberDataPointValueTypeDouble}, @@ -295,12 +361,16 @@ func TestLoadMetadata(t *testing.T) { Signal: Signal{ Enabled: false, Description: "[DEPRECATED] Gauge double metric disabled by default.", - Stability: Stability{Level: component.StabilityLevelDeprecated}, + Stability: component.StabilityLevelDeprecated, Warnings: Warnings{ IfConfigured: "This metric is deprecated and will be removed soon.", }, Attributes: []AttributeName{"string_attr", "boolean_attr"}, }, + Deprecated: &Deprecated{ + Since: "1.0.0", + Note: "This metric will be removed", + }, Unit: strPtr(""), Gauge: &Gauge{ MetricValueType: MetricValueType{pmetric.NumberDataPointValueTypeDouble}, @@ -312,11 +382,15 @@ func TestLoadMetadata(t *testing.T) { Enabled: true, Description: "[DEPRECATED] Non-monotonic delta sum double metric enabled by default.", ExtendedDocumentation: "The metric will be removed soon.", - Stability: Stability{Level: component.StabilityLevelDeprecated}, + Stability: component.StabilityLevelDeprecated, Warnings: Warnings{ IfEnabled: "This metric is deprecated and will be removed soon.", }, }, + Deprecated: &Deprecated{ + Since: "1.0.0", + Note: "This metric will be removed", + }, Unit: strPtr("s"), Sum: &Sum{ MetricValueType: MetricValueType{pmetric.NumberDataPointValueTypeDouble}, @@ -328,7 +402,7 @@ func TestLoadMetadata(t *testing.T) { Signal: Signal{ Enabled: true, Description: "Monotonic cumulative sum int metric with string input_type enabled by default.", - Stability: Stability{Level: component.StabilityLevelDevelopment}, + Stability: component.StabilityLevelDevelopment, Attributes: []AttributeName{"string_attr", "overridden_int_attr", "enum_attr", "slice_attr", "map_attr"}, }, Unit: strPtr("s"), @@ -379,10 +453,14 @@ func TestLoadMetadata(t *testing.T) { "batch_size_trigger_send": { Signal: Signal{ Enabled: true, - Stability: Stability{Level: component.StabilityLevelDeprecated, From: "v0.110.0"}, + Stability: component.StabilityLevelDeprecated, Description: "Number of times the batch was sent due to a size trigger", }, - Unit: strPtr("{times}"), + Deprecated: &Deprecated{ + Since: "1.5.0", + Note: "This metric will be removed in favor of batch_send_trigger_size", + }, + Unit: strPtr("{time}"), Sum: &Sum{ MetricValueType: MetricValueType{pmetric.NumberDataPointValueTypeInt}, Mono: Mono{Monotonic: true}, @@ -391,7 +469,7 @@ func TestLoadMetadata(t *testing.T) { "request_duration": { Signal: Signal{ Enabled: true, - Stability: Stability{Level: component.StabilityLevelAlpha}, + Stability: component.StabilityLevelAlpha, Description: "Duration of request", }, Unit: strPtr("s"), @@ -403,7 +481,7 @@ func TestLoadMetadata(t *testing.T) { "process_runtime_total_alloc_bytes": { Signal: Signal{ Enabled: true, - Stability: Stability{Level: component.StabilityLevelStable}, + Stability: component.StabilityLevelStable, Description: "Cumulative bytes allocated for heap objects (see 'go doc runtime.MemStats.TotalAlloc')", }, Unit: strPtr("By"), @@ -418,11 +496,11 @@ func TestLoadMetadata(t *testing.T) { "queue_length": { Signal: Signal{ Enabled: true, - Stability: Stability{Level: component.StabilityLevelAlpha}, + Stability: component.StabilityLevelAlpha, Description: "This metric is optional and therefore not initialized in NewTelemetryBuilder.", ExtendedDocumentation: "For example this metric only exists if feature A is enabled.", }, - Unit: strPtr("{items}"), + Unit: strPtr("{item}"), Optional: true, Gauge: &Gauge{ MetricValueType: MetricValueType{ @@ -435,9 +513,9 @@ func TestLoadMetadata(t *testing.T) { Signal: Signal{ Enabled: true, Description: "Queue capacity - sync gauge example.", - Stability: Stability{Level: component.StabilityLevelDevelopment}, + Stability: component.StabilityLevelDevelopment, }, - Unit: strPtr("{items}"), + Unit: strPtr("{item}"), Gauge: &Gauge{ MetricValueType: MetricValueType{ ValueType: pmetric.NumberDataPointValueTypeInt, @@ -449,6 +527,15 @@ func TestLoadMetadata(t *testing.T) { ScopeName: "go.opentelemetry.io/collector/internal/receiver/samplereceiver", ShortFolderName: "sample", Tests: Tests{Host: "newMdatagenNopHost()"}, + FeatureGates: []FeatureGate{ + { + ID: "receiver.sample.featuregate.example", + Description: "This is an example feature gate for testing mdatagen code generation.", + Stage: "alpha", + FromVersion: "v0.100.0", + ReferenceURL: "https://github.com/open-telemetry/opentelemetry-collector/issues/12345", + }, + }, }, }, { @@ -537,7 +624,7 @@ func TestLoadMetadata(t *testing.T) { { name: "testdata/invalid_metric_stability.yaml", want: Metadata{}, - wantErr: "decoding failed due to the following error(s):\n\n'metrics[default.metric]' decoding failed due to the following error(s):\n\n'stability' decoding failed due to the following error(s):\n\n'level' unsupported stability level: \"development42\"", + wantErr: "decoding failed due to the following error(s):\n\n'metrics[default.metric]' decoding failed due to the following error(s):\n\n'stability' unsupported stability level: \"development42\"", }, { name: "testdata/invalid_metric_semconvref.yaml", @@ -547,12 +634,117 @@ func TestLoadMetadata(t *testing.T) { { name: "testdata/no_metric_stability.yaml", want: Metadata{}, - wantErr: "decoding failed due to the following error(s):\n\n'metrics[default.metric]' decoding failed due to the following error(s):\n\n'stability' missing required field: `stability.level`", + wantErr: "metric \"default.metric\": missing required field: `stability.level`", + }, + { + name: "testdata/undeprecated_with_deprecation.yaml", + want: Metadata{}, + wantErr: "`stability` must be `deprecated` when specifying a `deprecated` field", + }, + { + name: "testdata/invalid_config.yaml", + want: Metadata{}, + wantErr: "config type must be \"object\", got \"string\"", }, { name: "testdata/~~this file doesn't exist~~.yaml", wantErr: "unable to read the file file:testdata/~~this file doesn't exist~~.yaml", }, + { + name: "testdata/display_name.yaml", + want: Metadata{ + Type: "test", + DisplayName: "Test Receiver", + GeneratedPackageName: "metadata", + ScopeName: "go.opentelemetry.io/collector/cmd/mdatagen/internal/testdata", + PackageName: "go.opentelemetry.io/collector/cmd/mdatagen/internal/testdata", + ShortFolderName: "testdata", + Tests: Tests{Host: "newMdatagenNopHost()"}, + Status: &Status{ + Class: "receiver", + Stability: map[component.StabilityLevel][]string{ + component.StabilityLevelBeta: {"logs"}, + }, + }, + }, + }, + { + name: "testdata/no_display_name.yaml", + want: Metadata{ + Type: "nodisplayname", + DisplayName: "", + GeneratedPackageName: "metadata", + ScopeName: "go.opentelemetry.io/collector/cmd/mdatagen/internal/testdata", + PackageName: "go.opentelemetry.io/collector/cmd/mdatagen/internal/testdata", + ShortFolderName: "testdata", + Tests: Tests{Host: "newMdatagenNopHost()"}, + Status: &Status{ + Class: "receiver", + Stability: map[component.StabilityLevel][]string{ + component.StabilityLevelBeta: {"logs"}, + }, + }, + }, + }, + { + name: "testdata/with_description.yaml", + want: Metadata{ + Type: "testdesc", + DisplayName: "Test Component", + Description: "This is a test component with a description.", + GeneratedPackageName: "metadata", + ScopeName: "go.opentelemetry.io/collector/cmd/mdatagen/internal/testdata", + PackageName: "go.opentelemetry.io/collector/cmd/mdatagen/internal/testdata", + ShortFolderName: "testdata", + Tests: Tests{Host: "newMdatagenNopHost()"}, + Status: &Status{ + Class: "receiver", + Stability: map[component.StabilityLevel][]string{ + component.StabilityLevelBeta: {"logs"}, + }, + }, + }, + }, + { + name: "testdata/with_underscore_in_semconv_ref_anchor_tag.yaml", + want: Metadata{ + Type: "metricreceiver", + GeneratedPackageName: "metadata", + SemConvVersion: "1.38.0", + ScopeName: "go.opentelemetry.io/collector/cmd/mdatagen/internal/testdata", + PackageName: "go.opentelemetry.io/collector/cmd/mdatagen/internal/testdata", + ShortFolderName: "testdata", + Tests: Tests{Host: "newMdatagenNopHost()"}, + Status: &Status{ + Class: "receiver", + Stability: map[component.StabilityLevel][]string{ + component.StabilityLevelDevelopment: {"logs"}, + component.StabilityLevelBeta: {"traces"}, + component.StabilityLevelStable: {"metrics"}, + }, + Distributions: []string{"contrib"}, + Warnings: []string{"Any additional information that should be brought to the consumer's attention"}, + }, + Metrics: map[MetricName]Metric{ + "system.disk.io_time": { + Signal: Signal{ + Enabled: true, + Description: "Time disk spent activated..", + Stability: component.StabilityLevelDevelopment, + SemanticConvention: &SemanticConvention{ + SemanticConventionRef: "https://github.com/open-telemetry/semantic-conventions/blob/v1.38.0/docs/system/system-metrics.md#metric-systemdiskio_time", + }, + }, + Unit: strPtr("s"), + Sum: &Sum{ + AggregationTemporality: AggregationTemporality{Aggregation: pmetric.AggregationTemporalityCumulative}, + Mono: Mono{Monotonic: true}, + MetricValueType: MetricValueType{ValueType: pmetric.NumberDataPointValueTypeDouble}, + }, + }, + }, + }, + }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { diff --git a/cmd/mdatagen/internal/metadata.go b/cmd/mdatagen/internal/metadata.go index d5355273e725..9c552f0319a8 100644 --- a/cmd/mdatagen/internal/metadata.go +++ b/cmd/mdatagen/internal/metadata.go @@ -11,6 +11,9 @@ import ( "strconv" "strings" + "go.opentelemetry.io/collector/cmd/mdatagen/internal/cfggen" + "go.opentelemetry.io/collector/cmd/mdatagen/internal/helpers" + "go.opentelemetry.io/collector/component" "go.opentelemetry.io/collector/filter" "go.opentelemetry.io/collector/pdata/pcommon" ) @@ -18,10 +21,18 @@ import ( type Metadata struct { // Type of the component. Type string `mapstructure:"type"` + // DeprecatedType of the component. + DeprecatedType string `mapstructure:"deprecated_type"` + // DisplayName is a human-readable display name for the component. + DisplayName string `mapstructure:"display_name"` + // Description is a brief description of the component. + Description string `mapstructure:"description"` // Type of the parent component (applicable to subcomponents). Parent string `mapstructure:"parent"` // Status information for the component. Status *Status `mapstructure:"status"` + // Spatial Re-aggregation featuregate. + ReaggregationEnabled bool `mapstructure:"reaggregation_enabled"` // The name of the package that will be generated. GeneratedPackageName string `mapstructure:"generated_package_name"` // Telemetry information for the component. @@ -48,6 +59,28 @@ type Metadata struct { Tests Tests `mapstructure:"tests"` // PackageName is the name of the package where the component is defined. PackageName string `mapstructure:"package_name"` + // FeatureGates that are managed by the component. + FeatureGates []FeatureGate `mapstructure:"feature_gates"` + // Config is the configuration schema for the component. + Config *cfggen.ConfigMetadata `mapstructure:"config"` +} + +type Deprecated struct { + Since string `mapstructure:"since"` + Note string `mapstructure:"note"` +} + +func (d *Deprecated) validate() error { + if strings.TrimSpace(d.Since) == "" { + return errors.New("deprecated.since must be set") + } + + // NOTE: note is optional, but if present, it must not be empty + if d.Note != "" && strings.TrimSpace(d.Note) == "" { + return errors.New("deprecated.note must not be empty") + } + + return nil } func (md Metadata) GetCodeCovComponentID() string { @@ -55,7 +88,7 @@ func (md Metadata) GetCodeCovComponentID() string { return md.Status.CodeCovComponentID } - return strings.ReplaceAll(md.Status.Class+"_"+md.Type, "/", "_") + return strings.ReplaceAll(md.Status.Class+"_"+strings.ReplaceAll(md.Type, "_", ""), "/", "_") } func (md Metadata) HasEntities() bool { @@ -89,6 +122,14 @@ func (md *Metadata) Validate() error { errs = errors.Join(errs, err) } + if err := md.validateFeatureGates(); err != nil { + errs = errors.Join(errs, err) + } + + if err := md.validateConfig(); err != nil { + errs = errors.Join(errs, err) + } + return errs } @@ -137,6 +178,7 @@ func (md *Metadata) validateEntities() error { usedAttrs := make(map[AttributeName]string) seenTypes := make(map[string]bool) + // First pass: collect entity types and validate basic entity properties for _, entity := range md.Entities { if entity.Type == "" { errs = errors.Join(errs, errors.New("entity type cannot be empty")) @@ -173,6 +215,36 @@ func (md *Metadata) validateEntities() error { usedAttrs[ref.Ref] = entity.Type } } + for _, ref := range entity.ExtraAttributes { + if _, ok := md.ResourceAttributes[ref.Ref]; !ok { + errs = errors.Join(errs, fmt.Errorf(`entity "%v": extra_attributes refers to undefined resource attribute: %v`, entity.Type, ref.Ref)) + } + } + } + + // Second pass: validate relationships + seenRelationships := make(map[string]string) + for _, entity := range md.Entities { + for _, rel := range entity.Relationships { + if rel.Type == "" { + errs = errors.Join(errs, fmt.Errorf(`entity "%v": relationship type cannot be empty`, entity.Type)) + continue + } + if rel.Target == "" { + errs = errors.Join(errs, fmt.Errorf(`entity "%v": relationship target cannot be empty`, entity.Type)) + continue + } + if !seenTypes[rel.Target] { + errs = errors.Join(errs, fmt.Errorf(`entity "%v": relationship target "%v" does not exist`, entity.Type, rel.Target)) + continue + } + if seenRelationships[rel.Target] == entity.Type || seenRelationships[entity.Type] == rel.Target { + errs = errors.Join(errs, fmt.Errorf(`entity "%v": duplicate relationship to target "%v" (only one relationship allowed between two entities)`, entity.Type, rel.Target)) + continue + } + seenRelationships[rel.Target] = entity.Type + seenRelationships[entity.Type] = rel.Target + } } return errs } @@ -184,7 +256,8 @@ func (md *Metadata) validateMetricsAndEvents() error { validateMetrics(md.Metrics, md.Attributes, usedAttrs, md.SemConvVersion), validateMetrics(md.Telemetry.Metrics, md.Attributes, usedAttrs, md.SemConvVersion), validateEvents(md.Events, md.Attributes, usedAttrs), - md.validateAttributes(usedAttrs)) + md.validateAttributes(usedAttrs), + md.validateEntityAssociations()) return errs } @@ -212,6 +285,36 @@ func (md *Metadata) validateAttributes(usedAttrs map[AttributeName]bool) error { return errs } +// validateEntityAssociations checks that if entities are defined, then each metric and event must be associated with an entity. +func (md *Metadata) validateEntityAssociations() error { + var errs error + requireEntityAssociation := len(md.Entities) > 0 + entityTypes := make(map[string]bool) + for _, entity := range md.Entities { + entityTypes[entity.Type] = true + } + + for metricName, metric := range md.Metrics { + if requireEntityAssociation && metric.Entity == "" { + errs = errors.Join(errs, fmt.Errorf(`metric "%v": entity is required when entities are defined`, metricName)) + } + if metric.Entity != "" && !entityTypes[metric.Entity] { + errs = errors.Join(errs, fmt.Errorf(`metric "%v": entity refers to undefined entity type: %v`, metricName, metric.Entity)) + } + } + + for eventName, event := range md.Events { + if requireEntityAssociation && event.Entity == "" { + errs = errors.Join(errs, fmt.Errorf(`event "%v": entity is required when entities are defined`, eventName)) + } + if event.Entity != "" && !entityTypes[event.Entity] { + errs = errors.Join(errs, fmt.Errorf(`event "%v": entity refers to undefined entity type: %v`, eventName, event.Entity)) + } + } + + return errs +} + func (md *Metadata) supportsSignal(signal string) bool { if md.Status == nil { return false @@ -270,6 +373,83 @@ func validateEvents(events map[EventName]Event, attributes map[AttributeName]Att return errs } +func (md *Metadata) validateFeatureGates() error { + var errs error + seen := make(map[FeatureGateID]bool) + idRegexp := regexp.MustCompile(`^[0-9a-zA-Z.]*$`) + + // Validate that feature gates are sorted by ID + if !slices.IsSortedFunc(md.FeatureGates, func(a, b FeatureGate) int { + return strings.Compare(string(a.ID), string(b.ID)) + }) { + errs = errors.Join(errs, errors.New("feature gates must be sorted by ID")) + } + + for i, gate := range md.FeatureGates { + // Validate gate ID is not empty + if string(gate.ID) == "" { + errs = errors.Join(errs, fmt.Errorf("feature gate at index %d: ID cannot be empty", i)) + continue + } + + // Validate ID follows the allowed character pattern + if !idRegexp.MatchString(string(gate.ID)) { + errs = errors.Join(errs, fmt.Errorf(`feature gate "%v": ID contains invalid characters, must match ^[0-9a-zA-Z.]*$`, gate.ID)) + } + + // Check for duplicate IDs + if seen[gate.ID] { + errs = errors.Join(errs, fmt.Errorf(`feature gate "%v": duplicate ID`, gate.ID)) + continue + } + seen[gate.ID] = true + + // Validate gate has required fields + if gate.Description == "" { + errs = errors.Join(errs, fmt.Errorf(`feature gate "%v": description is required`, gate.ID)) + } + + // Validate that each feature gate has a reference link + if gate.ReferenceURL == "" { + errs = errors.Join(errs, fmt.Errorf(`feature gate "%v": reference_url is required`, gate.ID)) + } + + // Validate stage is one of the allowed values + validStages := map[FeatureGateStage]bool{ + FeatureGateStageAlpha: true, + FeatureGateStageBeta: true, + FeatureGateStageStable: true, + FeatureGateStageDeprecated: true, + } + if !validStages[gate.Stage] { + errs = errors.Join(errs, fmt.Errorf(`feature gate "%v": invalid stage "%v", must be one of: alpha, beta, stable, deprecated`, gate.ID, gate.Stage)) + } + + // Validate from_version is required + if gate.FromVersion == "" { + errs = errors.Join(errs, fmt.Errorf(`feature gate "%v": from_version is required`, gate.ID)) + } else if !strings.HasPrefix(gate.FromVersion, "v") { + errs = errors.Join(errs, fmt.Errorf(`feature gate "%v": from_version "%v" must start with 'v'`, gate.ID, gate.FromVersion)) + } + if gate.ToVersion != "" && !strings.HasPrefix(gate.ToVersion, "v") { + errs = errors.Join(errs, fmt.Errorf(`feature gate "%v": to_version "%v" must start with 'v'`, gate.ID, gate.ToVersion)) + } + + // Validate that stable/deprecated gates should have to_version + if (gate.Stage == FeatureGateStageStable || gate.Stage == FeatureGateStageDeprecated) && gate.ToVersion == "" { + errs = errors.Join(errs, fmt.Errorf(`feature gate "%v": to_version is required for %v stage gates`, gate.ID, gate.Stage)) + } + } + return errs +} + +func (md *Metadata) validateConfig() error { + if md.Config != nil { + return md.Config.Validate() + } + return nil +} + type AttributeName string // AttributeRequirementLevel defines the requirement level of an attribute. @@ -302,11 +482,11 @@ func (rl AttributeRequirementLevel) String() string { } func (mn AttributeName) Render() (string, error) { - return FormatIdentifier(string(mn), true) + return helpers.FormatIdentifier(string(mn), true) } func (mn AttributeName) RenderUnexported() (string, error) { - return FormatIdentifier(string(mn), false) + return helpers.FormatIdentifier(string(mn), false) } // ValueType defines an attribute value type. @@ -408,6 +588,17 @@ func (a Attribute) IsConditional() bool { return a.RequirementLevel == AttributeRequirementLevelConditionallyRequired } +// IsRequired returns true if the attribute is required. +func (a Attribute) IsRequired() bool { + return a.RequirementLevel == AttributeRequirementLevelRequired +} + +// IsNotOptIn returns true if the attribute is any requirement_level above +// opt_in +func (a Attribute) IsNotOptIn() bool { + return a.RequirementLevel != AttributeRequirementLevelOptIn +} + // UnmarshalText implements the encoding.TextUnmarshaler interface. func (rl *AttributeRequirementLevel) UnmarshalText(text []byte) error { switch string(text) { @@ -472,6 +663,31 @@ func (a Attribute) TestValue() string { return "" } +func (a Attribute) TestValueTwo() string { + if a.Enum != nil { + return fmt.Sprintf(`%q`, a.Enum[1]) + } + switch a.Type.ValueType { + case pcommon.ValueTypeEmpty: + return "" + case pcommon.ValueTypeStr: + return fmt.Sprintf(`"%s-val-2"`, a.FullName) + case pcommon.ValueTypeInt: + return strconv.Itoa(len(a.FullName) + 1) + case pcommon.ValueTypeDouble: + return fmt.Sprintf("%f", 1.1+float64(len(a.FullName))) + case pcommon.ValueTypeBool: + return strconv.FormatBool(len(a.FullName)%2 == 1) + case pcommon.ValueTypeMap: + return fmt.Sprintf(`map[string]any{"key3": "%s-val3", "key4": "%s-val4"}`, a.FullName, a.FullName) + case pcommon.ValueTypeSlice: + return fmt.Sprintf(`[]any{"%s-item3", "%s-item4"}`, a.FullName, a.FullName) + case pcommon.ValueTypeBytes: + return fmt.Sprintf(`[]byte("%s-val-2")`, a.FullName) + } + return "" +} + type Signal struct { // Enabled defines whether the signal is enabled by default. Enabled bool `mapstructure:"enabled"` @@ -486,13 +702,17 @@ type Signal struct { SemanticConvention *SemanticConvention `mapstructure:"semantic_convention"` // The stability level of the signal. - Stability Stability `mapstructure:"stability"` + Stability component.StabilityLevel `mapstructure:"stability"` // Extended documentation of the signal. If specified, this will be appended to the description used in generated documentation. ExtendedDocumentation string `mapstructure:"extended_documentation"` // Attributes is the list of attributes that the signal emits. Attributes []AttributeName `mapstructure:"attributes"` + + // Entity is the type of entity this signal is associated with. + // Required when entities are defined. + Entity string `mapstructure:"entity"` } func (s Signal) HasConditionalAttributes(attrs map[AttributeName]Attribute) bool { @@ -510,14 +730,58 @@ type Entity struct { // Brief is a brief description of the entity. Brief string `mapstructure:"brief"` // Stability is the stability level of the entity. - Stability string `mapstructure:"stability"` + Stability component.StabilityLevel `mapstructure:"stability"` // Identity contains references to resource attributes that uniquely identify the entity. Identity []EntityAttributeRef `mapstructure:"identity"` // Description contains references to resource attributes that describe the entity. Description []EntityAttributeRef `mapstructure:"description"` + // ExtraAttributes contains references to resource attributes that are contextually + // relevant to the entity but are not part of its identity or description + // (e.g. k8s.namespace.name on a pod entity). + ExtraAttributes []EntityAttributeRef `mapstructure:"extra_attributes"` + // Relationships defines how this entity relates to other entities (optional). + // Relationships should be defined only on one end. It is recommended to define + // relationships on entities with lower lifespan (higher churn). + Relationships []EntityRelationship `mapstructure:"relationships"` } type EntityAttributeRef struct { // Ref is the reference to a resource attribute. Ref AttributeName `mapstructure:"ref"` } + +type EntityRelationship struct { + // Type is the relationship type (e.g., "parent", "child", "peer"). + Type string `mapstructure:"type"` + // Target is the entity type this entity relates to. + Target string `mapstructure:"target"` +} + +// FeatureGateID represents the identifier for a feature gate. +type FeatureGateID string + +// FeatureGateStage represents the lifecycle stage of a feature gate. +type FeatureGateStage string + +const ( + FeatureGateStageAlpha FeatureGateStage = "alpha" + FeatureGateStageBeta FeatureGateStage = "beta" + FeatureGateStageStable FeatureGateStage = "stable" + FeatureGateStageDeprecated FeatureGateStage = "deprecated" +) + +// FeatureGate represents a feature gate definition in metadata. +type FeatureGate struct { + // ID is the unique identifier for the feature gate. + ID FeatureGateID `mapstructure:"id"` + // Description of the feature gate. + Description string `mapstructure:"description"` + // Stage is the lifecycle stage of the feature gate. + Stage FeatureGateStage `mapstructure:"stage"` + // FromVersion is the version when the feature gate was introduced. + FromVersion string `mapstructure:"from_version"` + // ToVersion is the version when the feature gate reached stable stage. + ToVersion string `mapstructure:"to_version"` + // ReferenceURL is the URL with contextual information about the feature gate. + ReferenceURL string `mapstructure:"reference_url"` +} diff --git a/cmd/mdatagen/internal/metadata_test.go b/cmd/mdatagen/internal/metadata_test.go index fd811c60acb4..a567bad73cca 100644 --- a/cmd/mdatagen/internal/metadata_test.go +++ b/cmd/mdatagen/internal/metadata_test.go @@ -4,13 +4,12 @@ package internal import ( - "io/fs" - "path/filepath" - "slices" "testing" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + + "go.opentelemetry.io/collector/cmd/mdatagen/internal/cfggen" ) func TestValidate(t *testing.T) { @@ -140,50 +139,57 @@ func TestValidate(t *testing.T) { name: "testdata/entity_duplicate_types.yaml", wantErr: `duplicate entity type: host`, }, + { + name: "testdata/invalid_entity_stability.yaml", + wantErr: `unsupported stability level: "stable42"`, + }, + { + name: "testdata/entity_relationships_bidirectional.yaml", + wantErr: `duplicate relationship to target "k8s.replicaset" (only one relationship allowed between two entities)`, + }, + { + name: "testdata/entity_relationships_empty_type.yaml", + wantErr: `entity "k8s.pod": relationship type cannot be empty`, + }, + { + name: "testdata/entity_relationships_empty_target.yaml", + wantErr: `entity "k8s.pod": relationship target cannot be empty`, + }, + { + name: "testdata/entity_relationships_undefined_target.yaml", + wantErr: `entity "k8s.pod": relationship target "k8s.replicaset" does not exist`, + }, + { + name: "testdata/entity_metric_missing_association.yaml", + wantErr: `metric "host.cpu.time": entity is required when entities are defined`, + }, + { + name: "testdata/entity_event_missing_association.yaml", + wantErr: `event "host.restart": entity is required when entities are defined`, + }, + { + name: "testdata/entity_undefined_reference.yaml", + wantErr: `metric "host.cpu.time": entity refers to undefined entity type: undefined_entity`, + }, + { + name: "testdata/entity_single_metric_missing_association.yaml", + wantErr: `metric "host.cpu.time": entity is required when entities are defined`, + }, + { + name: "testdata/entity_metrics_events_valid.yaml", + wantErr: "", + }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { _, err := LoadMetadata(tt.name) - require.Error(t, err) - require.ErrorContains(t, err, tt.wantErr) - }) - } -} - -func TestValidateMetricDuplicates(t *testing.T) { - allowedMetrics := map[string][]string{ - "container.cpu.utilization": {"docker_stats", "kubeletstats"}, - "container.memory.rss": {"docker_stats", "kubeletstats"}, - "container.uptime": {"docker_stats", "kubeletstats"}, - } - allMetrics := map[string][]string{} - err := filepath.Walk("../../../receiver", func(path string, info fs.FileInfo, _ error) error { - if info.Name() == "metadata.yaml" { - md, err := LoadMetadata(path) - require.NoError(t, err) - if len(md.Metrics) > 0 { - for metricName := range md.Metrics { - allMetrics[md.Type] = append(allMetrics[md.Type], string(metricName)) - } + if tt.wantErr != "" { + require.Error(t, err) + require.ErrorContains(t, err, tt.wantErr) + } else { + require.NoError(t, err) } - } - return nil - }) - require.NoError(t, err) - - seen := make(map[string]string) - for receiver, metrics := range allMetrics { - for _, metricName := range metrics { - if val, exists := seen[metricName]; exists { - receivers, allowed := allowedMetrics[metricName] - assert.Truef( - t, - allowed && slices.Contains(receivers, receiver) && slices.Contains(receivers, val), - "Duplicate metric %v in receivers %v and %v. Please validate that this is intentional by adding the metric name and receiver types in the allowedMetrics map in this test\n", metricName, receiver, val, - ) - } - seen[metricName] = receiver - } + }) } } @@ -225,6 +231,15 @@ func TestCodeCovID(t *testing.T) { }, want: "exporter_file", }, + { + md: Metadata{ + Type: "file_log_thing", + Status: &Status{ + Class: "exporter", + }, + }, + want: "exporter_filelogthing", + }, } for _, tt := range tests { @@ -323,3 +338,240 @@ func TestAttributeRequirementLevelUnmarshalText(t *testing.T) { }) } } + +func TestValidateFeatureGates(t *testing.T) { + tests := []struct { + name string + featureGate FeatureGate + wantErr string + }{ + { + name: "valid alpha gate", + featureGate: FeatureGate{ + ID: "component.feature", + Description: "Test feature gate", + Stage: FeatureGateStageAlpha, + FromVersion: "v0.100.0", + ReferenceURL: "https://example.com", + }, + }, + { + name: "valid stable gate with to_version", + featureGate: FeatureGate{ + ID: "component.stable", + Description: "Stable feature gate", + Stage: FeatureGateStageStable, + FromVersion: "v0.90.0", + ToVersion: "v0.95.0", + ReferenceURL: "https://example.com", + }, + }, + { + name: "empty description", + featureGate: FeatureGate{ + ID: "component.feature", + Stage: FeatureGateStageAlpha, + FromVersion: "v0.100.0", + }, + wantErr: `description is required`, + }, + { + name: "invalid stage", + featureGate: FeatureGate{ + ID: "component.feature", + Description: "Test feature", + Stage: "invalid", + FromVersion: "v0.100.0", + }, + wantErr: `invalid stage "invalid"`, + }, + { + name: "missing from_version", + featureGate: FeatureGate{ + ID: "component.feature", + Description: "Test feature", + Stage: FeatureGateStageAlpha, + }, + wantErr: `from_version is required`, + }, + { + name: "from_version without v prefix", + featureGate: FeatureGate{ + ID: "component.feature", + Description: "Test feature", + Stage: FeatureGateStageAlpha, + FromVersion: "0.100.0", + }, + wantErr: `from_version "0.100.0" must start with 'v'`, + }, + { + name: "to_version without v prefix", + featureGate: FeatureGate{ + ID: "component.feature", + Description: "Test feature", + Stage: FeatureGateStageStable, + FromVersion: "v0.90.0", + ToVersion: "0.95.0", + }, + wantErr: `to_version "0.95.0" must start with 'v'`, + }, + { + name: "stable gate missing to_version", + featureGate: FeatureGate{ + ID: "component.feature", + Description: "Test feature", + Stage: FeatureGateStageStable, + FromVersion: "v0.90.0", + }, + wantErr: `to_version is required for stable stage gates`, + }, + { + name: "deprecated gate missing to_version", + featureGate: FeatureGate{ + ID: "component.feature", + Description: "Test feature", + Stage: FeatureGateStageDeprecated, + FromVersion: "v0.90.0", + }, + wantErr: `to_version is required for deprecated stage gates`, + }, + { + name: "missing reference_url", + featureGate: FeatureGate{ + ID: "component.feature", + Description: "Test feature", + Stage: FeatureGateStageAlpha, + FromVersion: "v0.100.0", + }, + wantErr: `reference_url is required`, + }, + { + name: "invalid characters in ID", + featureGate: FeatureGate{ + ID: "component.feature@invalid", + Description: "Test feature", + Stage: FeatureGateStageAlpha, + FromVersion: "v0.100.0", + ReferenceURL: "https://example.com", + }, + wantErr: `ID contains invalid characters`, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + md := &Metadata{ + FeatureGates: []FeatureGate{tt.featureGate}, + } + err := md.validateFeatureGates() + if tt.wantErr != "" { + require.Error(t, err) + assert.ErrorContains(t, err, tt.wantErr) + } else { + require.NoError(t, err) + } + }) + } +} + +func TestValidateFeatureGatesEmptyID(t *testing.T) { + md := &Metadata{ + FeatureGates: []FeatureGate{ + { + Description: "Test", + Stage: FeatureGateStageAlpha, + }, + }, + } + err := md.validateFeatureGates() + require.Error(t, err) + assert.ErrorContains(t, err, "ID cannot be empty") +} + +func TestValidateFeatureGatesDuplicateID(t *testing.T) { + md := &Metadata{ + FeatureGates: []FeatureGate{ + { + ID: "component.feature", + Description: "Test feature", + Stage: FeatureGateStageAlpha, + }, + { + ID: "component.feature", + Description: "Duplicate feature", + Stage: FeatureGateStageAlpha, + }, + }, + } + err := md.validateFeatureGates() + require.Error(t, err) + assert.ErrorContains(t, err, "duplicate ID") +} + +func TestValidateFeatureGatesNotSorted(t *testing.T) { + md := &Metadata{ + FeatureGates: []FeatureGate{ + { + ID: "component.zebra", + Description: "Test feature", + Stage: FeatureGateStageAlpha, + ReferenceURL: "https://example.com", + }, + { + ID: "component.alpha", + Description: "Another feature", + Stage: FeatureGateStageAlpha, + ReferenceURL: "https://example.com", + }, + }, + } + err := md.validateFeatureGates() + require.Error(t, err) + assert.ErrorContains(t, err, "feature gates must be sorted by ID") +} + +func TestValidateConfig(t *testing.T) { + tests := []struct { + name string + config *cfggen.ConfigMetadata + wantErr bool + }{ + { + name: "valid config", + config: &cfggen.ConfigMetadata{ + Type: "object", + AllOf: []*cfggen.ConfigMetadata{ + { + Ref: "component.config", + }, + }, + }, + wantErr: false, + }, + { + name: "no config defined", + config: nil, + wantErr: false, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + md := &Metadata{ + Type: "test", + Status: &Status{ + Class: "exporter", + Stability: StabilityMap{ + 6: {"traces"}, + }, + }, + Config: tt.config, + } + err := md.Validate() + if tt.wantErr { + require.Error(t, err) + } else { + require.NoError(t, err) + } + }) + } +} diff --git a/cmd/mdatagen/internal/metric.go b/cmd/mdatagen/internal/metric.go index cdba7d6d2e54..0b9a26bf2553 100644 --- a/cmd/mdatagen/internal/metric.go +++ b/cmd/mdatagen/internal/metric.go @@ -12,21 +12,22 @@ import ( "golang.org/x/text/cases" "golang.org/x/text/language" + "go.opentelemetry.io/collector/cmd/mdatagen/internal/helpers" "go.opentelemetry.io/collector/component" "go.opentelemetry.io/collector/confmap" "go.opentelemetry.io/collector/pdata/pmetric" ) -var reNonAlnum = regexp.MustCompile(`[^a-z0-9]+`) +var reNonAlnum = regexp.MustCompile(`[^a-z0-9_]+`) type MetricName string func (mn MetricName) Render() (string, error) { - return FormatIdentifier(string(mn), true) + return helpers.FormatIdentifier(string(mn), true) } func (mn MetricName) RenderUnexported() (string, error) { - return FormatIdentifier(string(mn), false) + return helpers.FormatIdentifier(string(mn), false) } type Metric struct { @@ -48,33 +49,24 @@ type Metric struct { // Override the default prefix for the metric name. Prefix string `mapstructure:"prefix"` -} -type Stability struct { - Level component.StabilityLevel `mapstructure:"level"` - From string `mapstructure:"from"` + // Deprecation metadata for deprecated metrics + Deprecated *Deprecated `mapstructure:"deprecated,omitempty"` } -func (s Stability) String() string { - if s.Level == component.StabilityLevelUndefined || - s.Level == component.StabilityLevelStable { - return "" - } - if s.From != "" { - return fmt.Sprintf(" [%s since %s]", s.Level.String(), s.From) - } - return fmt.Sprintf(" [%s]", s.Level.String()) -} +func (m *Metric) validate(metricName MetricName, semConvVersion string) error { + var errs error -func (s *Stability) Unmarshal(parser *confmap.Conf) error { - if !parser.IsSet("level") { - return errors.New("missing required field: `stability.level`") + if m.Deprecated != nil { + if m.Stability != component.StabilityLevelDeprecated { + errs = errors.Join(errs, errors.New("`stability` must be `deprecated` when specifying a `deprecated` field")) + } + + if err := m.Deprecated.validate(); err != nil { + errs = errors.Join(errs, err) + } } - return parser.Unmarshal(s) -} -func (m *Metric) validate(metricName MetricName, semConvVersion string) error { - var errs error if m.Sum == nil && m.Gauge == nil && m.Histogram == nil { errs = errors.Join(errs, errors.New("missing metric type key, "+ "one of the following has to be specified: sum, gauge, histogram")) @@ -83,6 +75,9 @@ func (m *Metric) validate(metricName MetricName, semConvVersion string) error { errs = errors.Join(errs, errors.New("more than one metric type keys, "+ "only one of the following has to be specified: sum, gauge, histogram")) } + if m.Stability == component.StabilityLevelUndefined { + errs = errors.Join(errs, errors.New("missing required field: `stability.level`")) + } if m.Description == "" { errs = errors.Join(errs, errors.New(`missing metric description`)) } diff --git a/cmd/mdatagen/internal/sampleconnector/documentation.md b/cmd/mdatagen/internal/sampleconnector/documentation.md index 940695a81583..3708e08948e3 100644 --- a/cmd/mdatagen/internal/sampleconnector/documentation.md +++ b/cmd/mdatagen/internal/sampleconnector/documentation.md @@ -40,7 +40,9 @@ The metric will be removed soon. | Unit | Metric Type | Value Type | Aggregation Temporality | Monotonic | Stability | | ---- | ----------- | ---------- | ----------------------- | --------- | --------- | -| s | Sum | Double | Delta | false | Deprecated | +| s | Sum | Double | Delta | false | Deprecated since 1.0.0 | + +**Deprecation note**: This metric will be removed ### metric.input_type @@ -60,6 +62,21 @@ Monotonic cumulative sum int metric with string input_type enabled by default. | slice_attr | Attribute with a slice value. | Any Slice | Recommended | | map_attr | Attribute with a map value. | Any Map | Recommended | +### reaggregate.metric + +Metric for testing spatial reaggregation + +| Unit | Metric Type | Value Type | Stability | +| ---- | ----------- | ---------- | --------- | +| 1 | Gauge | Double | Beta | + +#### Attributes + +| Name | Description | Values | Requirement Level | +| ---- | ----------- | ------ | -------- | +| string_attr | Attribute with any string value. | Any Str | Recommended | +| boolean_attr | Attribute with a boolean value. | Any Bool | Recommended | + ## Optional Metrics The following metrics are not emitted by default. Each of them can be enabled by applying the following configuration: @@ -76,7 +93,9 @@ metrics: | Unit | Metric Type | Value Type | Stability | | ---- | ----------- | ---------- | --------- | -| 1 | Gauge | Double | Deprecated | +| 1 | Gauge | Double | Deprecated since 1.0.0 | + +**Deprecation note**: This metric will be removed #### Attributes @@ -92,7 +111,9 @@ metrics: | Unit | Metric Type | Value Type | Stability | | ---- | ----------- | ---------- | --------- | -| | Gauge | Double | Deprecated | +| | Gauge | Double | Deprecated since 1.0.0 | + +**Deprecation note**: This metric will be removed #### Attributes @@ -122,10 +143,10 @@ The following entities are defined for this component: A test entity. -**Stability:** stable +**Stability:** Stable -**Identity Attributes:** +**Identifying Attributes:** - `string.resource.attr` -**Description Attributes:** +**Descriptive Attributes:** - `map.resource.attr` diff --git a/cmd/mdatagen/internal/sampleconnector/factory.go b/cmd/mdatagen/internal/sampleconnector/factory.go index bc63848bfd45..6e18860541ac 100644 --- a/cmd/mdatagen/internal/sampleconnector/factory.go +++ b/cmd/mdatagen/internal/sampleconnector/factory.go @@ -9,22 +9,31 @@ import ( "go.opentelemetry.io/collector/cmd/mdatagen/internal/sampleconnector/internal/metadata" "go.opentelemetry.io/collector/component" "go.opentelemetry.io/collector/connector" + "go.opentelemetry.io/collector/connector/xconnector" "go.opentelemetry.io/collector/consumer" + "go.opentelemetry.io/collector/consumer/xconsumer" "go.opentelemetry.io/collector/pdata/pmetric" + "go.opentelemetry.io/collector/pdata/pprofile" ) // NewFactory returns a connector.Factory for sample connector. func NewFactory() connector.Factory { - return connector.NewFactory( + return xconnector.NewFactory( metadata.Type, func() component.Config { return &struct{}{} }, - connector.WithMetricsToMetrics(createMetricsToMetricsConnector, metadata.MetricsToMetricsStability)) + xconnector.WithMetricsToMetrics(createMetricsToMetricsConnector, metadata.MetricsToMetricsStability), + xconnector.WithProfilesToProfiles(createProfilesToProfilesConnector, metadata.ProfilesToProfilesStability), + ) } func createMetricsToMetricsConnector(context.Context, connector.Settings, component.Config, consumer.Metrics) (connector.Metrics, error) { return nopInstance, nil } +func createProfilesToProfilesConnector(context.Context, connector.Settings, component.Config, xconsumer.Profiles) (xconnector.Profiles, error) { + return nopInstance, nil +} + var nopInstance = &nopConnector{} type nopConnector struct { @@ -39,3 +48,7 @@ func (n nopConnector) Capabilities() consumer.Capabilities { func (n nopConnector) ConsumeMetrics(context.Context, pmetric.Metrics) error { return nil } + +func (n nopConnector) ConsumeProfiles(context.Context, pprofile.Profiles) error { + return nil +} diff --git a/cmd/mdatagen/internal/sampleconnector/generated_component_test.go b/cmd/mdatagen/internal/sampleconnector/generated_component_test.go index 08dde142959e..cec5f6c9f4f0 100644 --- a/cmd/mdatagen/internal/sampleconnector/generated_component_test.go +++ b/cmd/mdatagen/internal/sampleconnector/generated_component_test.go @@ -14,9 +14,12 @@ import ( "go.opentelemetry.io/collector/confmap/confmaptest" "go.opentelemetry.io/collector/connector" "go.opentelemetry.io/collector/connector/connectortest" + "go.opentelemetry.io/collector/connector/xconnector" "go.opentelemetry.io/collector/consumer" "go.opentelemetry.io/collector/consumer/consumertest" + "go.opentelemetry.io/collector/consumer/xconsumer" "go.opentelemetry.io/collector/pipeline" + "go.opentelemetry.io/collector/pipeline/xpipeline" ) var typ = component.MustNewType("sample") @@ -44,6 +47,14 @@ func TestComponentLifecycle(t *testing.T) { return factory.CreateMetricsToMetrics(ctx, set, cfg, router) }, }, + + { + name: "profiles_to_profiles", + createFn: func(ctx context.Context, set connector.Settings, cfg component.Config) (component.Component, error) { + router := xconnector.NewProfilesRouter(map[pipeline.ID]xconsumer.Profiles{pipeline.NewID(xpipeline.SignalProfiles): consumertest.NewNop()}) + return factory.(xconnector.Factory).CreateProfilesToProfiles(ctx, set, cfg, router) + }, + }, } cm, err := confmaptest.LoadConf("metadata.yaml") diff --git a/cmd/mdatagen/internal/sampleconnector/internal/metadata/config.schema.yaml b/cmd/mdatagen/internal/sampleconnector/internal/metadata/config.schema.yaml new file mode 100644 index 000000000000..66025499b20b --- /dev/null +++ b/cmd/mdatagen/internal/sampleconnector/internal/metadata/config.schema.yaml @@ -0,0 +1,300 @@ +# Code generated by mdatagen. DO NOT EDIT. +$defs: + metrics_config: + description: MetricsConfig provides config for sample metrics. + type: object + properties: + default.metric: + description: "DefaultMetricMetricConfig provides config for the default.metric metric." + type: object + properties: + enabled: + type: boolean + default: true + aggregation_strategy: + type: string + enum: + - "sum" + - "avg" + - "min" + - "max" + default: "sum" + attributes: + type: array + items: + type: string + enum: + - "string_attr" + - "state" + - "enum_attr" + - "slice_attr" + - "map_attr" + default: + - "string_attr" + - "state" + - "enum_attr" + - "slice_attr" + - "map_attr" + default.metric.to_be_removed: + description: "DefaultMetricToBeRemovedMetricConfig provides config for the default.metric.to_be_removed metric." + type: object + properties: + enabled: + type: boolean + default: true + metric.input_type: + description: "MetricInputTypeMetricConfig provides config for the metric.input_type metric." + type: object + properties: + enabled: + type: boolean + default: true + aggregation_strategy: + type: string + enum: + - "sum" + - "avg" + - "min" + - "max" + default: "sum" + attributes: + type: array + items: + type: string + enum: + - "string_attr" + - "state" + - "enum_attr" + - "slice_attr" + - "map_attr" + default: + - "string_attr" + - "state" + - "enum_attr" + - "slice_attr" + - "map_attr" + optional.metric: + description: "OptionalMetricMetricConfig provides config for the optional.metric metric." + type: object + properties: + enabled: + type: boolean + default: false + aggregation_strategy: + type: string + enum: + - "sum" + - "avg" + - "min" + - "max" + default: "avg" + attributes: + type: array + items: + type: string + enum: + - "string_attr" + - "boolean_attr" + - "boolean_attr2" + default: + - "string_attr" + - "boolean_attr" + - "boolean_attr2" + optional.metric.empty_unit: + description: "OptionalMetricEmptyUnitMetricConfig provides config for the optional.metric.empty_unit metric." + type: object + properties: + enabled: + type: boolean + default: false + aggregation_strategy: + type: string + enum: + - "sum" + - "avg" + - "min" + - "max" + default: "avg" + attributes: + type: array + items: + type: string + enum: + - "string_attr" + - "boolean_attr" + default: + - "string_attr" + - "boolean_attr" + reaggregate.metric: + description: "ReaggregateMetricMetricConfig provides config for the reaggregate.metric metric." + type: object + properties: + enabled: + type: boolean + default: true + aggregation_strategy: + type: string + enum: + - "sum" + - "avg" + - "min" + - "max" + default: "avg" + attributes: + type: array + items: + type: string + enum: + - "string_attr" + - "boolean_attr" + default: + - "string_attr" + - "boolean_attr" + resource_attributes_config: + description: ResourceAttributesConfig provides config for sample resource attributes. + type: object + properties: + map.resource.attr: + description: ResourceAttributeConfig provides common config for a map.resource.attr resource attribute. + type: object + properties: + enabled: + type: boolean + default: true + metrics_include: + description: "Experimental: MetricsInclude defines a list of filters for attribute values. If the list is not empty, only metrics with matching resource attribute values will be emitted." + type: array + items: + $ref: /filter.config + metrics_exclude: + description: "Experimental: MetricsExclude defines a list of filters for attribute values. If the list is not empty, metrics with matching resource attribute values will not be emitted. MetricsInclude has higher priority than MetricsExclude." + type: array + items: + $ref: /filter.config + optional.resource.attr: + description: ResourceAttributeConfig provides common config for a optional.resource.attr resource attribute. + type: object + properties: + enabled: + type: boolean + default: false + metrics_include: + description: "Experimental: MetricsInclude defines a list of filters for attribute values. If the list is not empty, only metrics with matching resource attribute values will be emitted." + type: array + items: + $ref: /filter.config + metrics_exclude: + description: "Experimental: MetricsExclude defines a list of filters for attribute values. If the list is not empty, metrics with matching resource attribute values will not be emitted. MetricsInclude has higher priority than MetricsExclude." + type: array + items: + $ref: /filter.config + slice.resource.attr: + description: ResourceAttributeConfig provides common config for a slice.resource.attr resource attribute. + type: object + properties: + enabled: + type: boolean + default: true + metrics_include: + description: "Experimental: MetricsInclude defines a list of filters for attribute values. If the list is not empty, only metrics with matching resource attribute values will be emitted." + type: array + items: + $ref: /filter.config + metrics_exclude: + description: "Experimental: MetricsExclude defines a list of filters for attribute values. If the list is not empty, metrics with matching resource attribute values will not be emitted. MetricsInclude has higher priority than MetricsExclude." + type: array + items: + $ref: /filter.config + string.enum.resource.attr: + description: ResourceAttributeConfig provides common config for a string.enum.resource.attr resource attribute. + type: object + properties: + enabled: + type: boolean + default: true + metrics_include: + description: "Experimental: MetricsInclude defines a list of filters for attribute values. If the list is not empty, only metrics with matching resource attribute values will be emitted." + type: array + items: + $ref: /filter.config + metrics_exclude: + description: "Experimental: MetricsExclude defines a list of filters for attribute values. If the list is not empty, metrics with matching resource attribute values will not be emitted. MetricsInclude has higher priority than MetricsExclude." + type: array + items: + $ref: /filter.config + string.resource.attr: + description: ResourceAttributeConfig provides common config for a string.resource.attr resource attribute. + type: object + properties: + enabled: + type: boolean + default: true + metrics_include: + description: "Experimental: MetricsInclude defines a list of filters for attribute values. If the list is not empty, only metrics with matching resource attribute values will be emitted." + type: array + items: + $ref: /filter.config + metrics_exclude: + description: "Experimental: MetricsExclude defines a list of filters for attribute values. If the list is not empty, metrics with matching resource attribute values will not be emitted. MetricsInclude has higher priority than MetricsExclude." + type: array + items: + $ref: /filter.config + string.resource.attr_disable_warning: + description: ResourceAttributeConfig provides common config for a string.resource.attr_disable_warning resource attribute. + type: object + properties: + enabled: + type: boolean + default: true + metrics_include: + description: "Experimental: MetricsInclude defines a list of filters for attribute values. If the list is not empty, only metrics with matching resource attribute values will be emitted." + type: array + items: + $ref: /filter.config + metrics_exclude: + description: "Experimental: MetricsExclude defines a list of filters for attribute values. If the list is not empty, metrics with matching resource attribute values will not be emitted. MetricsInclude has higher priority than MetricsExclude." + type: array + items: + $ref: /filter.config + string.resource.attr_remove_warning: + description: ResourceAttributeConfig provides common config for a string.resource.attr_remove_warning resource attribute. + type: object + properties: + enabled: + type: boolean + default: false + metrics_include: + description: "Experimental: MetricsInclude defines a list of filters for attribute values. If the list is not empty, only metrics with matching resource attribute values will be emitted." + type: array + items: + $ref: /filter.config + metrics_exclude: + description: "Experimental: MetricsExclude defines a list of filters for attribute values. If the list is not empty, metrics with matching resource attribute values will not be emitted. MetricsInclude has higher priority than MetricsExclude." + type: array + items: + $ref: /filter.config + string.resource.attr_to_be_removed: + description: ResourceAttributeConfig provides common config for a string.resource.attr_to_be_removed resource attribute. + type: object + properties: + enabled: + type: boolean + default: true + metrics_include: + description: "Experimental: MetricsInclude defines a list of filters for attribute values. If the list is not empty, only metrics with matching resource attribute values will be emitted." + type: array + items: + $ref: /filter.config + metrics_exclude: + description: "Experimental: MetricsExclude defines a list of filters for attribute values. If the list is not empty, metrics with matching resource attribute values will not be emitted. MetricsInclude has higher priority than MetricsExclude." + type: array + items: + $ref: /filter.config + metrics_builder_config: + description: MetricsBuilderConfig is a configuration for sample metrics builder. + type: object + properties: + metrics: + $ref: metrics_config + resource_attributes: + $ref: resource_attributes_config diff --git a/cmd/mdatagen/internal/sampleconnector/internal/metadata/generated_config.go b/cmd/mdatagen/internal/sampleconnector/internal/metadata/generated_config.go index 05ddc47ac404..26f90f0caab7 100644 --- a/cmd/mdatagen/internal/sampleconnector/internal/metadata/generated_config.go +++ b/cmd/mdatagen/internal/sampleconnector/internal/metadata/generated_config.go @@ -3,54 +3,323 @@ package metadata import ( + "fmt" + "go.opentelemetry.io/collector/confmap" "go.opentelemetry.io/collector/filter" ) -// MetricConfig provides common config for a particular metric. -type MetricConfig struct { - Enabled bool `mapstructure:"enabled"` +// DefaultMetricMetricAttributeKey specifies the key of an attribute for the default.metric metric. +type DefaultMetricMetricAttributeKey string + +const ( + DefaultMetricMetricAttributeKeyStringAttr DefaultMetricMetricAttributeKey = "string_attr" + DefaultMetricMetricAttributeKeyOverriddenIntAttr DefaultMetricMetricAttributeKey = "state" + DefaultMetricMetricAttributeKeyEnumAttr DefaultMetricMetricAttributeKey = "enum_attr" + DefaultMetricMetricAttributeKeySliceAttr DefaultMetricMetricAttributeKey = "slice_attr" + DefaultMetricMetricAttributeKeyMapAttr DefaultMetricMetricAttributeKey = "map_attr" +) + +// DefaultMetricMetricConfig provides config for the default.metric metric. +type DefaultMetricMetricConfig struct { + Enabled bool `mapstructure:"enabled"` + enabledSetByUser bool + + AggregationStrategy string `mapstructure:"aggregation_strategy"` + EnabledAttributes []DefaultMetricMetricAttributeKey `mapstructure:"attributes"` +} + +func (ms *DefaultMetricMetricConfig) Unmarshal(parser *confmap.Conf) error { + if parser == nil { + return nil + } + + err := parser.Unmarshal(ms) + if err != nil { + return err + } + + ms.enabledSetByUser = parser.IsSet("enabled") + return nil +} + +func (ms *DefaultMetricMetricConfig) Validate() error { + for _, val := range ms.EnabledAttributes { + switch val { + case DefaultMetricMetricAttributeKeyStringAttr, DefaultMetricMetricAttributeKeyOverriddenIntAttr, DefaultMetricMetricAttributeKeyEnumAttr, DefaultMetricMetricAttributeKeySliceAttr, DefaultMetricMetricAttributeKeyMapAttr: + default: + return fmt.Errorf("metric default.metric doesn't have an attribute %v, valid attributes: [string_attr, state, enum_attr, slice_attr, map_attr]", val) + } + } + + switch ms.AggregationStrategy { + case AggregationStrategySum, AggregationStrategyAvg, AggregationStrategyMin, AggregationStrategyMax: + default: + return fmt.Errorf("invalid aggregation strategy %q, valid strategies: [%s, %s, %s, %s]", ms.AggregationStrategy, AggregationStrategySum, AggregationStrategyAvg, AggregationStrategyMin, AggregationStrategyMax) + } + + return nil +} + +// DefaultMetricToBeRemovedMetricConfig provides config for the default.metric.to_be_removed metric. +type DefaultMetricToBeRemovedMetricConfig struct { + Enabled bool `mapstructure:"enabled"` + enabledSetByUser bool +} + +func (ms *DefaultMetricToBeRemovedMetricConfig) Unmarshal(parser *confmap.Conf) error { + if parser == nil { + return nil + } + + err := parser.Unmarshal(ms) + if err != nil { + return err + } + + ms.enabledSetByUser = parser.IsSet("enabled") + return nil +} + +// MetricInputTypeMetricAttributeKey specifies the key of an attribute for the metric.input_type metric. +type MetricInputTypeMetricAttributeKey string +const ( + MetricInputTypeMetricAttributeKeyStringAttr MetricInputTypeMetricAttributeKey = "string_attr" + MetricInputTypeMetricAttributeKeyOverriddenIntAttr MetricInputTypeMetricAttributeKey = "state" + MetricInputTypeMetricAttributeKeyEnumAttr MetricInputTypeMetricAttributeKey = "enum_attr" + MetricInputTypeMetricAttributeKeySliceAttr MetricInputTypeMetricAttributeKey = "slice_attr" + MetricInputTypeMetricAttributeKeyMapAttr MetricInputTypeMetricAttributeKey = "map_attr" +) + +// MetricInputTypeMetricConfig provides config for the metric.input_type metric. +type MetricInputTypeMetricConfig struct { + Enabled bool `mapstructure:"enabled"` enabledSetByUser bool + + AggregationStrategy string `mapstructure:"aggregation_strategy"` + EnabledAttributes []MetricInputTypeMetricAttributeKey `mapstructure:"attributes"` } -func (ms *MetricConfig) Unmarshal(parser *confmap.Conf) error { +func (ms *MetricInputTypeMetricConfig) Unmarshal(parser *confmap.Conf) error { if parser == nil { return nil } + err := parser.Unmarshal(ms) if err != nil { return err } + ms.enabledSetByUser = parser.IsSet("enabled") return nil } +func (ms *MetricInputTypeMetricConfig) Validate() error { + for _, val := range ms.EnabledAttributes { + switch val { + case MetricInputTypeMetricAttributeKeyStringAttr, MetricInputTypeMetricAttributeKeyOverriddenIntAttr, MetricInputTypeMetricAttributeKeyEnumAttr, MetricInputTypeMetricAttributeKeySliceAttr, MetricInputTypeMetricAttributeKeyMapAttr: + default: + return fmt.Errorf("metric metric.input_type doesn't have an attribute %v, valid attributes: [string_attr, state, enum_attr, slice_attr, map_attr]", val) + } + } + + switch ms.AggregationStrategy { + case AggregationStrategySum, AggregationStrategyAvg, AggregationStrategyMin, AggregationStrategyMax: + default: + return fmt.Errorf("invalid aggregation strategy %q, valid strategies: [%s, %s, %s, %s]", ms.AggregationStrategy, AggregationStrategySum, AggregationStrategyAvg, AggregationStrategyMin, AggregationStrategyMax) + } + + return nil +} + +// OptionalMetricMetricAttributeKey specifies the key of an attribute for the optional.metric metric. +type OptionalMetricMetricAttributeKey string + +const ( + OptionalMetricMetricAttributeKeyStringAttr OptionalMetricMetricAttributeKey = "string_attr" + OptionalMetricMetricAttributeKeyBooleanAttr OptionalMetricMetricAttributeKey = "boolean_attr" + OptionalMetricMetricAttributeKeyBooleanAttr2 OptionalMetricMetricAttributeKey = "boolean_attr2" +) + +// OptionalMetricMetricConfig provides config for the optional.metric metric. +type OptionalMetricMetricConfig struct { + Enabled bool `mapstructure:"enabled"` + enabledSetByUser bool + + AggregationStrategy string `mapstructure:"aggregation_strategy"` + EnabledAttributes []OptionalMetricMetricAttributeKey `mapstructure:"attributes"` +} + +func (ms *OptionalMetricMetricConfig) Unmarshal(parser *confmap.Conf) error { + if parser == nil { + return nil + } + + err := parser.Unmarshal(ms) + if err != nil { + return err + } + + ms.enabledSetByUser = parser.IsSet("enabled") + return nil +} + +func (ms *OptionalMetricMetricConfig) Validate() error { + for _, val := range ms.EnabledAttributes { + switch val { + case OptionalMetricMetricAttributeKeyStringAttr, OptionalMetricMetricAttributeKeyBooleanAttr, OptionalMetricMetricAttributeKeyBooleanAttr2: + default: + return fmt.Errorf("metric optional.metric doesn't have an attribute %v, valid attributes: [string_attr, boolean_attr, boolean_attr2]", val) + } + } + + switch ms.AggregationStrategy { + case AggregationStrategySum, AggregationStrategyAvg, AggregationStrategyMin, AggregationStrategyMax: + default: + return fmt.Errorf("invalid aggregation strategy %q, valid strategies: [%s, %s, %s, %s]", ms.AggregationStrategy, AggregationStrategySum, AggregationStrategyAvg, AggregationStrategyMin, AggregationStrategyMax) + } + + return nil +} + +// OptionalMetricEmptyUnitMetricAttributeKey specifies the key of an attribute for the optional.metric.empty_unit metric. +type OptionalMetricEmptyUnitMetricAttributeKey string + +const ( + OptionalMetricEmptyUnitMetricAttributeKeyStringAttr OptionalMetricEmptyUnitMetricAttributeKey = "string_attr" + OptionalMetricEmptyUnitMetricAttributeKeyBooleanAttr OptionalMetricEmptyUnitMetricAttributeKey = "boolean_attr" +) + +// OptionalMetricEmptyUnitMetricConfig provides config for the optional.metric.empty_unit metric. +type OptionalMetricEmptyUnitMetricConfig struct { + Enabled bool `mapstructure:"enabled"` + enabledSetByUser bool + + AggregationStrategy string `mapstructure:"aggregation_strategy"` + EnabledAttributes []OptionalMetricEmptyUnitMetricAttributeKey `mapstructure:"attributes"` +} + +func (ms *OptionalMetricEmptyUnitMetricConfig) Unmarshal(parser *confmap.Conf) error { + if parser == nil { + return nil + } + + err := parser.Unmarshal(ms) + if err != nil { + return err + } + + ms.enabledSetByUser = parser.IsSet("enabled") + return nil +} + +func (ms *OptionalMetricEmptyUnitMetricConfig) Validate() error { + for _, val := range ms.EnabledAttributes { + switch val { + case OptionalMetricEmptyUnitMetricAttributeKeyStringAttr, OptionalMetricEmptyUnitMetricAttributeKeyBooleanAttr: + default: + return fmt.Errorf("metric optional.metric.empty_unit doesn't have an attribute %v, valid attributes: [string_attr, boolean_attr]", val) + } + } + + switch ms.AggregationStrategy { + case AggregationStrategySum, AggregationStrategyAvg, AggregationStrategyMin, AggregationStrategyMax: + default: + return fmt.Errorf("invalid aggregation strategy %q, valid strategies: [%s, %s, %s, %s]", ms.AggregationStrategy, AggregationStrategySum, AggregationStrategyAvg, AggregationStrategyMin, AggregationStrategyMax) + } + + return nil +} + +// ReaggregateMetricMetricAttributeKey specifies the key of an attribute for the reaggregate.metric metric. +type ReaggregateMetricMetricAttributeKey string + +const ( + ReaggregateMetricMetricAttributeKeyStringAttr ReaggregateMetricMetricAttributeKey = "string_attr" + ReaggregateMetricMetricAttributeKeyBooleanAttr ReaggregateMetricMetricAttributeKey = "boolean_attr" +) + +// ReaggregateMetricMetricConfig provides config for the reaggregate.metric metric. +type ReaggregateMetricMetricConfig struct { + Enabled bool `mapstructure:"enabled"` + enabledSetByUser bool + + AggregationStrategy string `mapstructure:"aggregation_strategy"` + EnabledAttributes []ReaggregateMetricMetricAttributeKey `mapstructure:"attributes"` +} + +func (ms *ReaggregateMetricMetricConfig) Unmarshal(parser *confmap.Conf) error { + if parser == nil { + return nil + } + + err := parser.Unmarshal(ms) + if err != nil { + return err + } + + ms.enabledSetByUser = parser.IsSet("enabled") + return nil +} + +func (ms *ReaggregateMetricMetricConfig) Validate() error { + for _, val := range ms.EnabledAttributes { + switch val { + case ReaggregateMetricMetricAttributeKeyStringAttr, ReaggregateMetricMetricAttributeKeyBooleanAttr: + default: + return fmt.Errorf("metric reaggregate.metric doesn't have an attribute %v, valid attributes: [string_attr, boolean_attr]", val) + } + } + + switch ms.AggregationStrategy { + case AggregationStrategySum, AggregationStrategyAvg, AggregationStrategyMin, AggregationStrategyMax: + default: + return fmt.Errorf("invalid aggregation strategy %q, valid strategies: [%s, %s, %s, %s]", ms.AggregationStrategy, AggregationStrategySum, AggregationStrategyAvg, AggregationStrategyMin, AggregationStrategyMax) + } + + return nil +} + // MetricsConfig provides config for sample metrics. type MetricsConfig struct { - DefaultMetric MetricConfig `mapstructure:"default.metric"` - DefaultMetricToBeRemoved MetricConfig `mapstructure:"default.metric.to_be_removed"` - MetricInputType MetricConfig `mapstructure:"metric.input_type"` - OptionalMetric MetricConfig `mapstructure:"optional.metric"` - OptionalMetricEmptyUnit MetricConfig `mapstructure:"optional.metric.empty_unit"` + DefaultMetric DefaultMetricMetricConfig `mapstructure:"default.metric"` + DefaultMetricToBeRemoved DefaultMetricToBeRemovedMetricConfig `mapstructure:"default.metric.to_be_removed"` + MetricInputType MetricInputTypeMetricConfig `mapstructure:"metric.input_type"` + OptionalMetric OptionalMetricMetricConfig `mapstructure:"optional.metric"` + OptionalMetricEmptyUnit OptionalMetricEmptyUnitMetricConfig `mapstructure:"optional.metric.empty_unit"` + ReaggregateMetric ReaggregateMetricMetricConfig `mapstructure:"reaggregate.metric"` } func DefaultMetricsConfig() MetricsConfig { return MetricsConfig{ - DefaultMetric: MetricConfig{ - Enabled: true, + DefaultMetric: DefaultMetricMetricConfig{ + Enabled: true, + AggregationStrategy: AggregationStrategySum, + EnabledAttributes: []DefaultMetricMetricAttributeKey{DefaultMetricMetricAttributeKeyStringAttr, DefaultMetricMetricAttributeKeyOverriddenIntAttr, DefaultMetricMetricAttributeKeyEnumAttr, DefaultMetricMetricAttributeKeySliceAttr, DefaultMetricMetricAttributeKeyMapAttr}, }, - DefaultMetricToBeRemoved: MetricConfig{ + DefaultMetricToBeRemoved: DefaultMetricToBeRemovedMetricConfig{ Enabled: true, }, - MetricInputType: MetricConfig{ - Enabled: true, + MetricInputType: MetricInputTypeMetricConfig{ + Enabled: true, + AggregationStrategy: AggregationStrategySum, + EnabledAttributes: []MetricInputTypeMetricAttributeKey{MetricInputTypeMetricAttributeKeyStringAttr, MetricInputTypeMetricAttributeKeyOverriddenIntAttr, MetricInputTypeMetricAttributeKeyEnumAttr, MetricInputTypeMetricAttributeKeySliceAttr, MetricInputTypeMetricAttributeKeyMapAttr}, }, - OptionalMetric: MetricConfig{ - Enabled: false, + OptionalMetric: OptionalMetricMetricConfig{ + Enabled: false, + AggregationStrategy: AggregationStrategyAvg, + EnabledAttributes: []OptionalMetricMetricAttributeKey{OptionalMetricMetricAttributeKeyStringAttr, OptionalMetricMetricAttributeKeyBooleanAttr, OptionalMetricMetricAttributeKeyBooleanAttr2}, }, - OptionalMetricEmptyUnit: MetricConfig{ - Enabled: false, + OptionalMetricEmptyUnit: OptionalMetricEmptyUnitMetricConfig{ + Enabled: false, + AggregationStrategy: AggregationStrategyAvg, + EnabledAttributes: []OptionalMetricEmptyUnitMetricAttributeKey{OptionalMetricEmptyUnitMetricAttributeKeyStringAttr, OptionalMetricEmptyUnitMetricAttributeKeyBooleanAttr}, + }, + ReaggregateMetric: ReaggregateMetricMetricConfig{ + Enabled: true, + AggregationStrategy: AggregationStrategyAvg, + EnabledAttributes: []ReaggregateMetricMetricAttributeKey{ReaggregateMetricMetricAttributeKeyStringAttr, ReaggregateMetricMetricAttributeKeyBooleanAttr}, }, } } diff --git a/cmd/mdatagen/internal/sampleconnector/internal/metadata/generated_config_test.go b/cmd/mdatagen/internal/sampleconnector/internal/metadata/generated_config_test.go index cc1a2cd0525d..3cc435e22044 100644 --- a/cmd/mdatagen/internal/sampleconnector/internal/metadata/generated_config_test.go +++ b/cmd/mdatagen/internal/sampleconnector/internal/metadata/generated_config_test.go @@ -27,11 +27,34 @@ func TestMetricsBuilderConfig(t *testing.T) { name: "all_set", want: MetricsBuilderConfig{ Metrics: MetricsConfig{ - DefaultMetric: MetricConfig{Enabled: true}, - DefaultMetricToBeRemoved: MetricConfig{Enabled: true}, - MetricInputType: MetricConfig{Enabled: true}, - OptionalMetric: MetricConfig{Enabled: true}, - OptionalMetricEmptyUnit: MetricConfig{Enabled: true}, + DefaultMetric: DefaultMetricMetricConfig{ + Enabled: true, + AggregationStrategy: AggregationStrategySum, + EnabledAttributes: []DefaultMetricMetricAttributeKey{DefaultMetricMetricAttributeKeyStringAttr, DefaultMetricMetricAttributeKeyOverriddenIntAttr, DefaultMetricMetricAttributeKeyEnumAttr, DefaultMetricMetricAttributeKeySliceAttr, DefaultMetricMetricAttributeKeyMapAttr}, + }, + DefaultMetricToBeRemoved: DefaultMetricToBeRemovedMetricConfig{ + Enabled: true, + }, + MetricInputType: MetricInputTypeMetricConfig{ + Enabled: true, + AggregationStrategy: AggregationStrategySum, + EnabledAttributes: []MetricInputTypeMetricAttributeKey{MetricInputTypeMetricAttributeKeyStringAttr, MetricInputTypeMetricAttributeKeyOverriddenIntAttr, MetricInputTypeMetricAttributeKeyEnumAttr, MetricInputTypeMetricAttributeKeySliceAttr, MetricInputTypeMetricAttributeKeyMapAttr}, + }, + OptionalMetric: OptionalMetricMetricConfig{ + Enabled: true, + AggregationStrategy: AggregationStrategyAvg, + EnabledAttributes: []OptionalMetricMetricAttributeKey{OptionalMetricMetricAttributeKeyStringAttr, OptionalMetricMetricAttributeKeyBooleanAttr, OptionalMetricMetricAttributeKeyBooleanAttr2}, + }, + OptionalMetricEmptyUnit: OptionalMetricEmptyUnitMetricConfig{ + Enabled: true, + AggregationStrategy: AggregationStrategyAvg, + EnabledAttributes: []OptionalMetricEmptyUnitMetricAttributeKey{OptionalMetricEmptyUnitMetricAttributeKeyStringAttr, OptionalMetricEmptyUnitMetricAttributeKeyBooleanAttr}, + }, + ReaggregateMetric: ReaggregateMetricMetricConfig{ + Enabled: true, + AggregationStrategy: AggregationStrategyAvg, + EnabledAttributes: []ReaggregateMetricMetricAttributeKey{ReaggregateMetricMetricAttributeKeyStringAttr, ReaggregateMetricMetricAttributeKeyBooleanAttr}, + }, }, ResourceAttributes: ResourceAttributesConfig{ MapResourceAttr: ResourceAttributeConfig{Enabled: true}, @@ -49,11 +72,34 @@ func TestMetricsBuilderConfig(t *testing.T) { name: "none_set", want: MetricsBuilderConfig{ Metrics: MetricsConfig{ - DefaultMetric: MetricConfig{Enabled: false}, - DefaultMetricToBeRemoved: MetricConfig{Enabled: false}, - MetricInputType: MetricConfig{Enabled: false}, - OptionalMetric: MetricConfig{Enabled: false}, - OptionalMetricEmptyUnit: MetricConfig{Enabled: false}, + DefaultMetric: DefaultMetricMetricConfig{ + Enabled: false, + AggregationStrategy: AggregationStrategySum, + EnabledAttributes: []DefaultMetricMetricAttributeKey{DefaultMetricMetricAttributeKeyStringAttr, DefaultMetricMetricAttributeKeyOverriddenIntAttr, DefaultMetricMetricAttributeKeyEnumAttr, DefaultMetricMetricAttributeKeySliceAttr, DefaultMetricMetricAttributeKeyMapAttr}, + }, + DefaultMetricToBeRemoved: DefaultMetricToBeRemovedMetricConfig{ + Enabled: false, + }, + MetricInputType: MetricInputTypeMetricConfig{ + Enabled: false, + AggregationStrategy: AggregationStrategySum, + EnabledAttributes: []MetricInputTypeMetricAttributeKey{MetricInputTypeMetricAttributeKeyStringAttr, MetricInputTypeMetricAttributeKeyOverriddenIntAttr, MetricInputTypeMetricAttributeKeyEnumAttr, MetricInputTypeMetricAttributeKeySliceAttr, MetricInputTypeMetricAttributeKeyMapAttr}, + }, + OptionalMetric: OptionalMetricMetricConfig{ + Enabled: false, + AggregationStrategy: AggregationStrategyAvg, + EnabledAttributes: []OptionalMetricMetricAttributeKey{OptionalMetricMetricAttributeKeyStringAttr, OptionalMetricMetricAttributeKeyBooleanAttr, OptionalMetricMetricAttributeKeyBooleanAttr2}, + }, + OptionalMetricEmptyUnit: OptionalMetricEmptyUnitMetricConfig{ + Enabled: false, + AggregationStrategy: AggregationStrategyAvg, + EnabledAttributes: []OptionalMetricEmptyUnitMetricAttributeKey{OptionalMetricEmptyUnitMetricAttributeKeyStringAttr, OptionalMetricEmptyUnitMetricAttributeKeyBooleanAttr}, + }, + ReaggregateMetric: ReaggregateMetricMetricConfig{ + Enabled: false, + AggregationStrategy: AggregationStrategyAvg, + EnabledAttributes: []ReaggregateMetricMetricAttributeKey{ReaggregateMetricMetricAttributeKeyStringAttr, ReaggregateMetricMetricAttributeKeyBooleanAttr}, + }, }, ResourceAttributes: ResourceAttributesConfig{ MapResourceAttr: ResourceAttributeConfig{Enabled: false}, @@ -71,7 +117,7 @@ func TestMetricsBuilderConfig(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { cfg := loadMetricsBuilderConfig(t, tt.name) - diff := cmp.Diff(tt.want, cfg, cmpopts.IgnoreUnexported(MetricConfig{}, ResourceAttributeConfig{})) + diff := cmp.Diff(tt.want, cfg, cmpopts.IgnoreUnexported(DefaultMetricMetricConfig{}, DefaultMetricToBeRemovedMetricConfig{}, MetricInputTypeMetricConfig{}, OptionalMetricMetricConfig{}, OptionalMetricEmptyUnitMetricConfig{}, ReaggregateMetricMetricConfig{}, ResourceAttributeConfig{})) require.Emptyf(t, diff, "Config mismatch (-expected +actual):\n%s", diff) }) } diff --git a/cmd/mdatagen/internal/sampleconnector/internal/metadata/generated_entity_metrics.go b/cmd/mdatagen/internal/sampleconnector/internal/metadata/generated_entity_metrics.go new file mode 100644 index 000000000000..379d7c7b2249 --- /dev/null +++ b/cmd/mdatagen/internal/sampleconnector/internal/metadata/generated_entity_metrics.go @@ -0,0 +1,105 @@ +// Code generated by mdatagen. DO NOT EDIT. + +package metadata + +import ( + "fmt" + "strconv" + + "go.opentelemetry.io/collector/pdata/pcommon" + "go.opentelemetry.io/collector/pdata/xpdata/entity" +) + +// TestEntityEntity represents a test.entity entity. +// Create one with NewTestEntityEntity and pass it to EmitForEntity. +type TestEntityEntity struct { + stringResourceAttr string + mapResourceAttr map[string]any +} + +// NewTestEntityEntity creates a new TestEntityEntity. +// Identity attributes are required and must be provided at construction time. +func NewTestEntityEntity(stringResourceAttr string) *TestEntityEntity { + return &TestEntityEntity{ + stringResourceAttr: stringResourceAttr, + } +} + +// Description attribute setters for test.entity. + +// SetMapResourceAttr sets the map.resource.attr description attribute. +func (e *TestEntityEntity) SetMapResourceAttr(val map[string]any) { + e.mapResourceAttr = val +} + +// copyToResource populates res with the entity's attributes according to cfg. +// If all identity attributes are enabled, an entity ref is produced; otherwise +// the enabled attributes are written directly as plain resource attributes. +func (e *TestEntityEntity) copyToResource(cfg ResourceAttributesConfig, res pcommon.Resource) { + if cfg.StringResourceAttr.Enabled { + ent := entity.ResourceEntities(res).PutEmpty("test.entity") + ent.IdentifyingAttributes().PutStr("string.resource.attr", e.stringResourceAttr) + if cfg.MapResourceAttr.Enabled { + ent.DescriptiveAttributes().PutEmpty("map.resource.attr").SetEmptyMap().FromRaw(e.mapResourceAttr) + } + } else { + if cfg.StringResourceAttr.Enabled { + res.Attributes().PutStr("string.resource.attr", e.stringResourceAttr) + } + if cfg.MapResourceAttr.Enabled { + res.Attributes().PutEmptyMap("map.resource.attr").FromRaw(e.mapResourceAttr) + } + } +} + +// TestEntityMetricsBuilder records metrics for the test.entity entity. +// Obtain one via MetricsBuilder.ForTestEntity(). +type TestEntityMetricsBuilder struct { + mb *MetricsBuilder + entity *TestEntityEntity +} + +// RecordDefaultMetricDataPoint records a data point for the default.metric metric. +func (eb *TestEntityMetricsBuilder) RecordDefaultMetricDataPoint(ts pcommon.Timestamp, val int64, stringAttrAttributeValue string, overriddenIntAttrAttributeValue int64, enumAttrAttributeValue AttributeEnumAttr, sliceAttrAttributeValue []any, mapAttrAttributeValue map[string]any) { + eb.mb.metricDefaultMetric.recordDataPoint(eb.mb.startTime, ts, val, stringAttrAttributeValue, overriddenIntAttrAttributeValue, enumAttrAttributeValue.String(), sliceAttrAttributeValue, mapAttrAttributeValue) +} + +// RecordDefaultMetricToBeRemovedDataPoint records a data point for the default.metric.to_be_removed metric. +func (eb *TestEntityMetricsBuilder) RecordDefaultMetricToBeRemovedDataPoint(ts pcommon.Timestamp, val float64) { + eb.mb.metricDefaultMetricToBeRemoved.recordDataPoint(eb.mb.startTime, ts, val) +} + +// RecordMetricInputTypeDataPoint records a data point for the metric.input_type metric. +func (eb *TestEntityMetricsBuilder) RecordMetricInputTypeDataPoint(ts pcommon.Timestamp, inputVal string, stringAttrAttributeValue string, overriddenIntAttrAttributeValue int64, enumAttrAttributeValue AttributeEnumAttr, sliceAttrAttributeValue []any, mapAttrAttributeValue map[string]any) error { + val, err := strconv.ParseInt(inputVal, 10, 64) + if err != nil { + return fmt.Errorf("failed to parse int64 for MetricInputType, value was %s: %w", inputVal, err) + } + eb.mb.metricMetricInputType.recordDataPoint(eb.mb.startTime, ts, val, stringAttrAttributeValue, overriddenIntAttrAttributeValue, enumAttrAttributeValue.String(), sliceAttrAttributeValue, mapAttrAttributeValue) + return nil +} + +// RecordOptionalMetricDataPoint records a data point for the optional.metric metric. +func (eb *TestEntityMetricsBuilder) RecordOptionalMetricDataPoint(ts pcommon.Timestamp, val float64, stringAttrAttributeValue string, booleanAttrAttributeValue bool, booleanAttr2AttributeValue bool) { + eb.mb.metricOptionalMetric.recordDataPoint(eb.mb.startTime, ts, val, stringAttrAttributeValue, booleanAttrAttributeValue, booleanAttr2AttributeValue) +} + +// RecordOptionalMetricEmptyUnitDataPoint records a data point for the optional.metric.empty_unit metric. +func (eb *TestEntityMetricsBuilder) RecordOptionalMetricEmptyUnitDataPoint(ts pcommon.Timestamp, val float64, stringAttrAttributeValue string, booleanAttrAttributeValue bool) { + eb.mb.metricOptionalMetricEmptyUnit.recordDataPoint(eb.mb.startTime, ts, val, stringAttrAttributeValue, booleanAttrAttributeValue) +} + +// RecordReaggregateMetricDataPoint records a data point for the reaggregate.metric metric. +func (eb *TestEntityMetricsBuilder) RecordReaggregateMetricDataPoint(ts pcommon.Timestamp, val float64, stringAttrAttributeValue string, booleanAttrAttributeValue bool) { + eb.mb.metricReaggregateMetric.recordDataPoint(eb.mb.startTime, ts, val, stringAttrAttributeValue, booleanAttrAttributeValue) +} + +// Emit emits all pending metrics for the entity. Resource attributes are filtered by config: +// disabled identity attributes suppress the entity (other enabled attributes are added directly +// to the resource); disabled descriptive/extra attributes are omitted entirely. +func (eb *TestEntityMetricsBuilder) Emit() { + res := pcommon.NewResource() + cfg := eb.mb.config.ResourceAttributes + eb.entity.copyToResource(cfg, res) + eb.mb.EmitForResource(withResourceMoved(res)) +} diff --git a/cmd/mdatagen/internal/sampleconnector/internal/metadata/generated_entity_metrics_test.go b/cmd/mdatagen/internal/sampleconnector/internal/metadata/generated_entity_metrics_test.go new file mode 100644 index 000000000000..d33f6c898e72 --- /dev/null +++ b/cmd/mdatagen/internal/sampleconnector/internal/metadata/generated_entity_metrics_test.go @@ -0,0 +1,110 @@ +// Code generated by mdatagen. DO NOT EDIT. + +package metadata + +import ( + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + + "go.opentelemetry.io/collector/connector/connectortest" + "go.opentelemetry.io/collector/pdata/pcommon" + "go.opentelemetry.io/collector/pdata/xpdata/entity" +) + +func TestEntityBuilders(t *testing.T) { + start := pcommon.Timestamp(1_000_000_000) + ts := pcommon.Timestamp(1_000_001_000) + settings := connectortest.NewNopSettings(connectortest.NopType) + mb := NewMetricsBuilder(DefaultMetricsBuilderConfig(), settings, WithStartTime(start)) + + t.Run("test.entity", func(t *testing.T) { + e := NewTestEntityEntity("string.resource.attr-val") + require.NotNil(t, e) + e.SetMapResourceAttr(map[string]any{"key1": "map.resource.attr-val1", "key2": "map.resource.attr-val2"}) + + eb := mb.ForTestEntity(e) + eb.RecordDefaultMetricDataPoint(ts, 1, "string_attr-val", 19, AttributeEnumAttrRed, []any{"slice_attr-item1", "slice_attr-item2"}, map[string]any{"key1": "map_attr-val1", "key2": "map_attr-val2"}) + eb.RecordDefaultMetricToBeRemovedDataPoint(ts, 1) + eb.RecordMetricInputTypeDataPoint(ts, "1", "string_attr-val", 19, AttributeEnumAttrRed, []any{"slice_attr-item1", "slice_attr-item2"}, map[string]any{"key1": "map_attr-val1", "key2": "map_attr-val2"}) + eb.RecordOptionalMetricDataPoint(ts, 1, "string_attr-val", true, false) + eb.RecordOptionalMetricEmptyUnitDataPoint(ts, 1, "string_attr-val", true) + eb.RecordReaggregateMetricDataPoint(ts, 1, "string_attr-val", true) + eb.Emit() + metrics := mb.Emit() + + require.Equal(t, 1, metrics.ResourceMetrics().Len()) + rm := metrics.ResourceMetrics().At(0) + entityVal, ok := entity.ResourceEntities(rm.Resource()).Get("test.entity") + require.True(t, ok) + attrVal, ok := entityVal.IdentifyingAttributes().Get("string.resource.attr") + require.True(t, ok) + assert.Equal(t, "string.resource.attr-val", attrVal.Str()) + + require.Equal(t, 1, rm.ScopeMetrics().Len()) + ms := rm.ScopeMetrics().At(0).Metrics() + assert.Equal(t, 4, ms.Len()) + }) + t.Run("test.entity/disabled_identity_attr", func(t *testing.T) { + // When an identity attribute is disabled, the entity is not produced but + // other enabled attributes are still added to the resource directly. + cfg := DefaultMetricsBuilderConfig() + cfg.ResourceAttributes.StringResourceAttr.Enabled = false + mb := NewMetricsBuilder(cfg, settings, WithStartTime(start)) + + e := NewTestEntityEntity("string.resource.attr-val") + e.SetMapResourceAttr(map[string]any{"key1": "map.resource.attr-val1", "key2": "map.resource.attr-val2"}) + + eb := mb.ForTestEntity(e) + eb.RecordDefaultMetricDataPoint(ts, 1, "string_attr-val", 19, AttributeEnumAttrRed, []any{"slice_attr-item1", "slice_attr-item2"}, map[string]any{"key1": "map_attr-val1", "key2": "map_attr-val2"}) + eb.RecordDefaultMetricToBeRemovedDataPoint(ts, 1) + eb.RecordMetricInputTypeDataPoint(ts, "1", "string_attr-val", 19, AttributeEnumAttrRed, []any{"slice_attr-item1", "slice_attr-item2"}, map[string]any{"key1": "map_attr-val1", "key2": "map_attr-val2"}) + eb.RecordOptionalMetricDataPoint(ts, 1, "string_attr-val", true, false) + eb.RecordOptionalMetricEmptyUnitDataPoint(ts, 1, "string_attr-val", true) + eb.RecordReaggregateMetricDataPoint(ts, 1, "string_attr-val", true) + eb.Emit() + metrics := mb.Emit() + + require.Equal(t, 1, metrics.ResourceMetrics().Len()) + rm := metrics.ResourceMetrics().At(0) + // Entity must not be present since its identity attribute is disabled. + _, ok := entity.ResourceEntities(rm.Resource()).Get("test.entity") + assert.False(t, ok) + // Enabled descriptive attributes should still be on the resource directly. + _, ok = rm.Resource().Attributes().Get("map.resource.attr") + assert.True(t, ok) + }) + t.Run("test.entity/disabled_descriptive_attr", func(t *testing.T) { + // When a descriptive attribute is disabled, the entity is still produced + // with its identity but the disabled attribute is not added. + cfg := DefaultMetricsBuilderConfig() + cfg.ResourceAttributes.MapResourceAttr.Enabled = false + mb := NewMetricsBuilder(cfg, settings, WithStartTime(start)) + + e := NewTestEntityEntity("string.resource.attr-val") + e.SetMapResourceAttr(map[string]any{"key1": "map.resource.attr-val1", "key2": "map.resource.attr-val2"}) + + eb := mb.ForTestEntity(e) + eb.RecordDefaultMetricDataPoint(ts, 1, "string_attr-val", 19, AttributeEnumAttrRed, []any{"slice_attr-item1", "slice_attr-item2"}, map[string]any{"key1": "map_attr-val1", "key2": "map_attr-val2"}) + eb.RecordDefaultMetricToBeRemovedDataPoint(ts, 1) + eb.RecordMetricInputTypeDataPoint(ts, "1", "string_attr-val", 19, AttributeEnumAttrRed, []any{"slice_attr-item1", "slice_attr-item2"}, map[string]any{"key1": "map_attr-val1", "key2": "map_attr-val2"}) + eb.RecordOptionalMetricDataPoint(ts, 1, "string_attr-val", true, false) + eb.RecordOptionalMetricEmptyUnitDataPoint(ts, 1, "string_attr-val", true) + eb.RecordReaggregateMetricDataPoint(ts, 1, "string_attr-val", true) + eb.Emit() + metrics := mb.Emit() + + require.Equal(t, 1, metrics.ResourceMetrics().Len()) + rm := metrics.ResourceMetrics().At(0) + // Entity must still be produced since identity attributes are enabled. + entityVal, ok := entity.ResourceEntities(rm.Resource()).Get("test.entity") + require.True(t, ok) + attrVal, ok := entityVal.IdentifyingAttributes().Get("string.resource.attr") + require.True(t, ok) + assert.Equal(t, "string.resource.attr-val", attrVal.Str()) + // Disabled descriptive/extra attributes must not be present. + _, ok = entityVal.DescriptiveAttributes().Get("map.resource.attr") + assert.False(t, ok) + }) +} diff --git a/cmd/mdatagen/internal/sampleconnector/internal/metadata/generated_metrics.go b/cmd/mdatagen/internal/sampleconnector/internal/metadata/generated_metrics.go index 475e719db5ca..a12e6bdd3867 100644 --- a/cmd/mdatagen/internal/sampleconnector/internal/metadata/generated_metrics.go +++ b/cmd/mdatagen/internal/sampleconnector/internal/metadata/generated_metrics.go @@ -4,6 +4,7 @@ package metadata import ( "fmt" + "slices" "strconv" "time" @@ -16,6 +17,13 @@ import ( "go.opentelemetry.io/collector/pdata/pmetric" ) +const ( + AggregationStrategySum = "sum" + AggregationStrategyAvg = "avg" + AggregationStrategyMin = "min" + AggregationStrategyMax = "max" +) + // AttributeEnumAttr specifies the value enum_attr attribute. type AttributeEnumAttr int @@ -62,6 +70,9 @@ var MetricsInfo = metricsInfo{ OptionalMetricEmptyUnit: metricInfo{ Name: "optional.metric.empty_unit", }, + ReaggregateMetric: metricInfo{ + Name: "reaggregate.metric", + }, } type metricsInfo struct { @@ -70,6 +81,7 @@ type metricsInfo struct { MetricInputType metricInfo OptionalMetric metricInfo OptionalMetricEmptyUnit metricInfo + ReaggregateMetric metricInfo } type metricInfo struct { @@ -77,9 +89,10 @@ type metricInfo struct { } type metricDefaultMetric struct { - data pmetric.Metric // data buffer for generated metric. - config MetricConfig // metric config provided by user. - capacity int // max observed number of data points added to the metric. + data pmetric.Metric // data buffer for generated metric. + config DefaultMetricMetricConfig // metric config provided by user. + capacity int // max observed number of data points added to the metric. + aggDataPoints []int64 // slice containing number of aggregated datapoints at each index } // init fills default.metric metric with initial data. @@ -91,21 +104,60 @@ func (m *metricDefaultMetric) init() { m.data.Sum().SetIsMonotonic(true) m.data.Sum().SetAggregationTemporality(pmetric.AggregationTemporalityCumulative) m.data.Sum().DataPoints().EnsureCapacity(m.capacity) + m.aggDataPoints = m.aggDataPoints[:0] } func (m *metricDefaultMetric) recordDataPoint(start pcommon.Timestamp, ts pcommon.Timestamp, val int64, stringAttrAttributeValue string, overriddenIntAttrAttributeValue int64, enumAttrAttributeValue string, sliceAttrAttributeValue []any, mapAttrAttributeValue map[string]any) { if !m.config.Enabled { return } - dp := m.data.Sum().DataPoints().AppendEmpty() + + dp := pmetric.NewNumberDataPoint() dp.SetStartTimestamp(start) dp.SetTimestamp(ts) + if slices.Contains(m.config.EnabledAttributes, DefaultMetricMetricAttributeKeyStringAttr) { + dp.Attributes().PutStr("string_attr", stringAttrAttributeValue) + } + if slices.Contains(m.config.EnabledAttributes, DefaultMetricMetricAttributeKeyOverriddenIntAttr) { + dp.Attributes().PutInt("state", overriddenIntAttrAttributeValue) + } + if slices.Contains(m.config.EnabledAttributes, DefaultMetricMetricAttributeKeyEnumAttr) { + dp.Attributes().PutStr("enum_attr", enumAttrAttributeValue) + } + if slices.Contains(m.config.EnabledAttributes, DefaultMetricMetricAttributeKeySliceAttr) { + dp.Attributes().PutEmptySlice("slice_attr").FromRaw(sliceAttrAttributeValue) + } + if slices.Contains(m.config.EnabledAttributes, DefaultMetricMetricAttributeKeyMapAttr) { + dp.Attributes().PutEmptyMap("map_attr").FromRaw(mapAttrAttributeValue) + } + + var s string + dps := m.data.Sum().DataPoints() + for i := 0; i < dps.Len(); i++ { + dpi := dps.At(i) + if dp.Attributes().Equal(dpi.Attributes()) && dp.StartTimestamp() == dpi.StartTimestamp() && dp.Timestamp() == dpi.Timestamp() { + switch s = m.config.AggregationStrategy; s { + case AggregationStrategySum, AggregationStrategyAvg: + dpi.SetIntValue(dpi.IntValue() + val) + m.aggDataPoints[i] += 1 + return + case AggregationStrategyMin: + if dpi.IntValue() > val { + dpi.SetIntValue(val) + } + return + case AggregationStrategyMax: + if dpi.IntValue() < val { + dpi.SetIntValue(val) + } + return + } + } + } + dp.SetIntValue(val) - dp.Attributes().PutStr("string_attr", stringAttrAttributeValue) - dp.Attributes().PutInt("state", overriddenIntAttrAttributeValue) - dp.Attributes().PutStr("enum_attr", enumAttrAttributeValue) - dp.Attributes().PutEmptySlice("slice_attr").FromRaw(sliceAttrAttributeValue) - dp.Attributes().PutEmptyMap("map_attr").FromRaw(mapAttrAttributeValue) + m.aggDataPoints = append(m.aggDataPoints, 1) + dp.MoveTo(dps.AppendEmpty()) } // updateCapacity saves max length of data point slices that will be used for the slice capacity. @@ -118,14 +170,20 @@ func (m *metricDefaultMetric) updateCapacity() { // emit appends recorded metric data to a metrics slice and prepares it for recording another set of data points. func (m *metricDefaultMetric) emit(metrics pmetric.MetricSlice) { if m.config.Enabled && m.data.Sum().DataPoints().Len() > 0 { + if m.config.AggregationStrategy == AggregationStrategyAvg { + for i, aggCount := range m.aggDataPoints { + m.data.Sum().DataPoints().At(i).SetIntValue(m.data.Sum().DataPoints().At(i).IntValue() / aggCount) + } + } m.updateCapacity() m.data.MoveTo(metrics.AppendEmpty()) m.init() } } -func newMetricDefaultMetric(cfg MetricConfig) metricDefaultMetric { +func newMetricDefaultMetric(cfg DefaultMetricMetricConfig) metricDefaultMetric { m := metricDefaultMetric{config: cfg} + if cfg.Enabled { m.data = pmetric.NewMetric() m.init() @@ -134,9 +192,9 @@ func newMetricDefaultMetric(cfg MetricConfig) metricDefaultMetric { } type metricDefaultMetricToBeRemoved struct { - data pmetric.Metric // data buffer for generated metric. - config MetricConfig // metric config provided by user. - capacity int // max observed number of data points added to the metric. + data pmetric.Metric // data buffer for generated metric. + config DefaultMetricToBeRemovedMetricConfig // metric config provided by user. + capacity int // max observed number of data points added to the metric. } // init fills default.metric.to_be_removed metric with initial data. @@ -175,8 +233,9 @@ func (m *metricDefaultMetricToBeRemoved) emit(metrics pmetric.MetricSlice) { } } -func newMetricDefaultMetricToBeRemoved(cfg MetricConfig) metricDefaultMetricToBeRemoved { +func newMetricDefaultMetricToBeRemoved(cfg DefaultMetricToBeRemovedMetricConfig) metricDefaultMetricToBeRemoved { m := metricDefaultMetricToBeRemoved{config: cfg} + if cfg.Enabled { m.data = pmetric.NewMetric() m.init() @@ -185,9 +244,10 @@ func newMetricDefaultMetricToBeRemoved(cfg MetricConfig) metricDefaultMetricToBe } type metricMetricInputType struct { - data pmetric.Metric // data buffer for generated metric. - config MetricConfig // metric config provided by user. - capacity int // max observed number of data points added to the metric. + data pmetric.Metric // data buffer for generated metric. + config MetricInputTypeMetricConfig // metric config provided by user. + capacity int // max observed number of data points added to the metric. + aggDataPoints []int64 // slice containing number of aggregated datapoints at each index } // init fills metric.input_type metric with initial data. @@ -199,21 +259,60 @@ func (m *metricMetricInputType) init() { m.data.Sum().SetIsMonotonic(true) m.data.Sum().SetAggregationTemporality(pmetric.AggregationTemporalityCumulative) m.data.Sum().DataPoints().EnsureCapacity(m.capacity) + m.aggDataPoints = m.aggDataPoints[:0] } func (m *metricMetricInputType) recordDataPoint(start pcommon.Timestamp, ts pcommon.Timestamp, val int64, stringAttrAttributeValue string, overriddenIntAttrAttributeValue int64, enumAttrAttributeValue string, sliceAttrAttributeValue []any, mapAttrAttributeValue map[string]any) { if !m.config.Enabled { return } - dp := m.data.Sum().DataPoints().AppendEmpty() + + dp := pmetric.NewNumberDataPoint() dp.SetStartTimestamp(start) dp.SetTimestamp(ts) + if slices.Contains(m.config.EnabledAttributes, MetricInputTypeMetricAttributeKeyStringAttr) { + dp.Attributes().PutStr("string_attr", stringAttrAttributeValue) + } + if slices.Contains(m.config.EnabledAttributes, MetricInputTypeMetricAttributeKeyOverriddenIntAttr) { + dp.Attributes().PutInt("state", overriddenIntAttrAttributeValue) + } + if slices.Contains(m.config.EnabledAttributes, MetricInputTypeMetricAttributeKeyEnumAttr) { + dp.Attributes().PutStr("enum_attr", enumAttrAttributeValue) + } + if slices.Contains(m.config.EnabledAttributes, MetricInputTypeMetricAttributeKeySliceAttr) { + dp.Attributes().PutEmptySlice("slice_attr").FromRaw(sliceAttrAttributeValue) + } + if slices.Contains(m.config.EnabledAttributes, MetricInputTypeMetricAttributeKeyMapAttr) { + dp.Attributes().PutEmptyMap("map_attr").FromRaw(mapAttrAttributeValue) + } + + var s string + dps := m.data.Sum().DataPoints() + for i := 0; i < dps.Len(); i++ { + dpi := dps.At(i) + if dp.Attributes().Equal(dpi.Attributes()) && dp.StartTimestamp() == dpi.StartTimestamp() && dp.Timestamp() == dpi.Timestamp() { + switch s = m.config.AggregationStrategy; s { + case AggregationStrategySum, AggregationStrategyAvg: + dpi.SetIntValue(dpi.IntValue() + val) + m.aggDataPoints[i] += 1 + return + case AggregationStrategyMin: + if dpi.IntValue() > val { + dpi.SetIntValue(val) + } + return + case AggregationStrategyMax: + if dpi.IntValue() < val { + dpi.SetIntValue(val) + } + return + } + } + } + dp.SetIntValue(val) - dp.Attributes().PutStr("string_attr", stringAttrAttributeValue) - dp.Attributes().PutInt("state", overriddenIntAttrAttributeValue) - dp.Attributes().PutStr("enum_attr", enumAttrAttributeValue) - dp.Attributes().PutEmptySlice("slice_attr").FromRaw(sliceAttrAttributeValue) - dp.Attributes().PutEmptyMap("map_attr").FromRaw(mapAttrAttributeValue) + m.aggDataPoints = append(m.aggDataPoints, 1) + dp.MoveTo(dps.AppendEmpty()) } // updateCapacity saves max length of data point slices that will be used for the slice capacity. @@ -226,14 +325,20 @@ func (m *metricMetricInputType) updateCapacity() { // emit appends recorded metric data to a metrics slice and prepares it for recording another set of data points. func (m *metricMetricInputType) emit(metrics pmetric.MetricSlice) { if m.config.Enabled && m.data.Sum().DataPoints().Len() > 0 { + if m.config.AggregationStrategy == AggregationStrategyAvg { + for i, aggCount := range m.aggDataPoints { + m.data.Sum().DataPoints().At(i).SetIntValue(m.data.Sum().DataPoints().At(i).IntValue() / aggCount) + } + } m.updateCapacity() m.data.MoveTo(metrics.AppendEmpty()) m.init() } } -func newMetricMetricInputType(cfg MetricConfig) metricMetricInputType { +func newMetricMetricInputType(cfg MetricInputTypeMetricConfig) metricMetricInputType { m := metricMetricInputType{config: cfg} + if cfg.Enabled { m.data = pmetric.NewMetric() m.init() @@ -242,9 +347,10 @@ func newMetricMetricInputType(cfg MetricConfig) metricMetricInputType { } type metricOptionalMetric struct { - data pmetric.Metric // data buffer for generated metric. - config MetricConfig // metric config provided by user. - capacity int // max observed number of data points added to the metric. + data pmetric.Metric // data buffer for generated metric. + config OptionalMetricMetricConfig // metric config provided by user. + capacity int // max observed number of data points added to the metric. + aggDataPoints []float64 // slice containing number of aggregated datapoints at each index } // init fills optional.metric metric with initial data. @@ -254,19 +360,54 @@ func (m *metricOptionalMetric) init() { m.data.SetUnit("1") m.data.SetEmptyGauge() m.data.Gauge().DataPoints().EnsureCapacity(m.capacity) + m.aggDataPoints = m.aggDataPoints[:0] } func (m *metricOptionalMetric) recordDataPoint(start pcommon.Timestamp, ts pcommon.Timestamp, val float64, stringAttrAttributeValue string, booleanAttrAttributeValue bool, booleanAttr2AttributeValue bool) { if !m.config.Enabled { return } - dp := m.data.Gauge().DataPoints().AppendEmpty() + + dp := pmetric.NewNumberDataPoint() dp.SetStartTimestamp(start) dp.SetTimestamp(ts) + if slices.Contains(m.config.EnabledAttributes, OptionalMetricMetricAttributeKeyStringAttr) { + dp.Attributes().PutStr("string_attr", stringAttrAttributeValue) + } + if slices.Contains(m.config.EnabledAttributes, OptionalMetricMetricAttributeKeyBooleanAttr) { + dp.Attributes().PutBool("boolean_attr", booleanAttrAttributeValue) + } + if slices.Contains(m.config.EnabledAttributes, OptionalMetricMetricAttributeKeyBooleanAttr2) { + dp.Attributes().PutBool("boolean_attr2", booleanAttr2AttributeValue) + } + + var s string + dps := m.data.Gauge().DataPoints() + for i := 0; i < dps.Len(); i++ { + dpi := dps.At(i) + if dp.Attributes().Equal(dpi.Attributes()) && dp.StartTimestamp() == dpi.StartTimestamp() && dp.Timestamp() == dpi.Timestamp() { + switch s = m.config.AggregationStrategy; s { + case AggregationStrategySum, AggregationStrategyAvg: + dpi.SetDoubleValue(dpi.DoubleValue() + val) + m.aggDataPoints[i] += 1 + return + case AggregationStrategyMin: + if dpi.DoubleValue() > val { + dpi.SetDoubleValue(val) + } + return + case AggregationStrategyMax: + if dpi.DoubleValue() < val { + dpi.SetDoubleValue(val) + } + return + } + } + } + dp.SetDoubleValue(val) - dp.Attributes().PutStr("string_attr", stringAttrAttributeValue) - dp.Attributes().PutBool("boolean_attr", booleanAttrAttributeValue) - dp.Attributes().PutBool("boolean_attr2", booleanAttr2AttributeValue) + m.aggDataPoints = append(m.aggDataPoints, 1) + dp.MoveTo(dps.AppendEmpty()) } // updateCapacity saves max length of data point slices that will be used for the slice capacity. @@ -279,14 +420,20 @@ func (m *metricOptionalMetric) updateCapacity() { // emit appends recorded metric data to a metrics slice and prepares it for recording another set of data points. func (m *metricOptionalMetric) emit(metrics pmetric.MetricSlice) { if m.config.Enabled && m.data.Gauge().DataPoints().Len() > 0 { + if m.config.AggregationStrategy == AggregationStrategyAvg { + for i, aggCount := range m.aggDataPoints { + m.data.Gauge().DataPoints().At(i).SetDoubleValue(m.data.Gauge().DataPoints().At(i).DoubleValue() / aggCount) + } + } m.updateCapacity() m.data.MoveTo(metrics.AppendEmpty()) m.init() } } -func newMetricOptionalMetric(cfg MetricConfig) metricOptionalMetric { +func newMetricOptionalMetric(cfg OptionalMetricMetricConfig) metricOptionalMetric { m := metricOptionalMetric{config: cfg} + if cfg.Enabled { m.data = pmetric.NewMetric() m.init() @@ -295,9 +442,10 @@ func newMetricOptionalMetric(cfg MetricConfig) metricOptionalMetric { } type metricOptionalMetricEmptyUnit struct { - data pmetric.Metric // data buffer for generated metric. - config MetricConfig // metric config provided by user. - capacity int // max observed number of data points added to the metric. + data pmetric.Metric // data buffer for generated metric. + config OptionalMetricEmptyUnitMetricConfig // metric config provided by user. + capacity int // max observed number of data points added to the metric. + aggDataPoints []float64 // slice containing number of aggregated datapoints at each index } // init fills optional.metric.empty_unit metric with initial data. @@ -307,18 +455,51 @@ func (m *metricOptionalMetricEmptyUnit) init() { m.data.SetUnit("") m.data.SetEmptyGauge() m.data.Gauge().DataPoints().EnsureCapacity(m.capacity) + m.aggDataPoints = m.aggDataPoints[:0] } func (m *metricOptionalMetricEmptyUnit) recordDataPoint(start pcommon.Timestamp, ts pcommon.Timestamp, val float64, stringAttrAttributeValue string, booleanAttrAttributeValue bool) { if !m.config.Enabled { return } - dp := m.data.Gauge().DataPoints().AppendEmpty() + + dp := pmetric.NewNumberDataPoint() dp.SetStartTimestamp(start) dp.SetTimestamp(ts) + if slices.Contains(m.config.EnabledAttributes, OptionalMetricEmptyUnitMetricAttributeKeyStringAttr) { + dp.Attributes().PutStr("string_attr", stringAttrAttributeValue) + } + if slices.Contains(m.config.EnabledAttributes, OptionalMetricEmptyUnitMetricAttributeKeyBooleanAttr) { + dp.Attributes().PutBool("boolean_attr", booleanAttrAttributeValue) + } + + var s string + dps := m.data.Gauge().DataPoints() + for i := 0; i < dps.Len(); i++ { + dpi := dps.At(i) + if dp.Attributes().Equal(dpi.Attributes()) && dp.StartTimestamp() == dpi.StartTimestamp() && dp.Timestamp() == dpi.Timestamp() { + switch s = m.config.AggregationStrategy; s { + case AggregationStrategySum, AggregationStrategyAvg: + dpi.SetDoubleValue(dpi.DoubleValue() + val) + m.aggDataPoints[i] += 1 + return + case AggregationStrategyMin: + if dpi.DoubleValue() > val { + dpi.SetDoubleValue(val) + } + return + case AggregationStrategyMax: + if dpi.DoubleValue() < val { + dpi.SetDoubleValue(val) + } + return + } + } + } + dp.SetDoubleValue(val) - dp.Attributes().PutStr("string_attr", stringAttrAttributeValue) - dp.Attributes().PutBool("boolean_attr", booleanAttrAttributeValue) + m.aggDataPoints = append(m.aggDataPoints, 1) + dp.MoveTo(dps.AppendEmpty()) } // updateCapacity saves max length of data point slices that will be used for the slice capacity. @@ -331,14 +512,112 @@ func (m *metricOptionalMetricEmptyUnit) updateCapacity() { // emit appends recorded metric data to a metrics slice and prepares it for recording another set of data points. func (m *metricOptionalMetricEmptyUnit) emit(metrics pmetric.MetricSlice) { if m.config.Enabled && m.data.Gauge().DataPoints().Len() > 0 { + if m.config.AggregationStrategy == AggregationStrategyAvg { + for i, aggCount := range m.aggDataPoints { + m.data.Gauge().DataPoints().At(i).SetDoubleValue(m.data.Gauge().DataPoints().At(i).DoubleValue() / aggCount) + } + } m.updateCapacity() m.data.MoveTo(metrics.AppendEmpty()) m.init() } } -func newMetricOptionalMetricEmptyUnit(cfg MetricConfig) metricOptionalMetricEmptyUnit { +func newMetricOptionalMetricEmptyUnit(cfg OptionalMetricEmptyUnitMetricConfig) metricOptionalMetricEmptyUnit { m := metricOptionalMetricEmptyUnit{config: cfg} + + if cfg.Enabled { + m.data = pmetric.NewMetric() + m.init() + } + return m +} + +type metricReaggregateMetric struct { + data pmetric.Metric // data buffer for generated metric. + config ReaggregateMetricMetricConfig // metric config provided by user. + capacity int // max observed number of data points added to the metric. + aggDataPoints []float64 // slice containing number of aggregated datapoints at each index +} + +// init fills reaggregate.metric metric with initial data. +func (m *metricReaggregateMetric) init() { + m.data.SetName("reaggregate.metric") + m.data.SetDescription("Metric for testing spatial reaggregation") + m.data.SetUnit("1") + m.data.SetEmptyGauge() + m.data.Gauge().DataPoints().EnsureCapacity(m.capacity) + m.aggDataPoints = m.aggDataPoints[:0] +} + +func (m *metricReaggregateMetric) recordDataPoint(start pcommon.Timestamp, ts pcommon.Timestamp, val float64, stringAttrAttributeValue string, booleanAttrAttributeValue bool) { + if !m.config.Enabled { + return + } + + dp := pmetric.NewNumberDataPoint() + dp.SetStartTimestamp(start) + dp.SetTimestamp(ts) + if slices.Contains(m.config.EnabledAttributes, ReaggregateMetricMetricAttributeKeyStringAttr) { + dp.Attributes().PutStr("string_attr", stringAttrAttributeValue) + } + if slices.Contains(m.config.EnabledAttributes, ReaggregateMetricMetricAttributeKeyBooleanAttr) { + dp.Attributes().PutBool("boolean_attr", booleanAttrAttributeValue) + } + + var s string + dps := m.data.Gauge().DataPoints() + for i := 0; i < dps.Len(); i++ { + dpi := dps.At(i) + if dp.Attributes().Equal(dpi.Attributes()) && dp.StartTimestamp() == dpi.StartTimestamp() && dp.Timestamp() == dpi.Timestamp() { + switch s = m.config.AggregationStrategy; s { + case AggregationStrategySum, AggregationStrategyAvg: + dpi.SetDoubleValue(dpi.DoubleValue() + val) + m.aggDataPoints[i] += 1 + return + case AggregationStrategyMin: + if dpi.DoubleValue() > val { + dpi.SetDoubleValue(val) + } + return + case AggregationStrategyMax: + if dpi.DoubleValue() < val { + dpi.SetDoubleValue(val) + } + return + } + } + } + + dp.SetDoubleValue(val) + m.aggDataPoints = append(m.aggDataPoints, 1) + dp.MoveTo(dps.AppendEmpty()) +} + +// updateCapacity saves max length of data point slices that will be used for the slice capacity. +func (m *metricReaggregateMetric) updateCapacity() { + if m.data.Gauge().DataPoints().Len() > m.capacity { + m.capacity = m.data.Gauge().DataPoints().Len() + } +} + +// emit appends recorded metric data to a metrics slice and prepares it for recording another set of data points. +func (m *metricReaggregateMetric) emit(metrics pmetric.MetricSlice) { + if m.config.Enabled && m.data.Gauge().DataPoints().Len() > 0 { + if m.config.AggregationStrategy == AggregationStrategyAvg { + for i, aggCount := range m.aggDataPoints { + m.data.Gauge().DataPoints().At(i).SetDoubleValue(m.data.Gauge().DataPoints().At(i).DoubleValue() / aggCount) + } + } + m.updateCapacity() + m.data.MoveTo(metrics.AppendEmpty()) + m.init() + } +} + +func newMetricReaggregateMetric(cfg ReaggregateMetricMetricConfig) metricReaggregateMetric { + m := metricReaggregateMetric{config: cfg} + if cfg.Enabled { m.data = pmetric.NewMetric() m.init() @@ -361,6 +640,7 @@ type MetricsBuilder struct { metricMetricInputType metricMetricInputType metricOptionalMetric metricOptionalMetric metricOptionalMetricEmptyUnit metricOptionalMetricEmptyUnit + metricReaggregateMetric metricReaggregateMetric } // MetricBuilderOption applies changes to default metrics builder. @@ -412,6 +692,7 @@ func NewMetricsBuilder(mbc MetricsBuilderConfig, settings connector.Settings, op metricMetricInputType: newMetricMetricInputType(mbc.Metrics.MetricInputType), metricOptionalMetric: newMetricOptionalMetric(mbc.Metrics.OptionalMetric), metricOptionalMetricEmptyUnit: newMetricOptionalMetricEmptyUnit(mbc.Metrics.OptionalMetricEmptyUnit), + metricReaggregateMetric: newMetricReaggregateMetric(mbc.Metrics.ReaggregateMetric), resourceAttributeIncludeFilter: make(map[string]filter.Filter), resourceAttributeExcludeFilter: make(map[string]filter.Filter), } @@ -501,6 +782,12 @@ func WithResource(res pcommon.Resource) ResourceMetricsOption { }) } +func withResourceMoved(res pcommon.Resource) ResourceMetricsOption { + return resourceMetricsOptionFunc(func(rm pmetric.ResourceMetrics) { + res.MoveTo(rm.Resource()) + }) +} + // WithStartTimeOverride overrides start time for all the resource metrics data points. // This option should be only used if different start time has to be set on metrics coming from different resources. func WithStartTimeOverride(start pcommon.Timestamp) ResourceMetricsOption { @@ -521,11 +808,19 @@ func WithStartTimeOverride(start pcommon.Timestamp) ResourceMetricsOption { }) } +// ForTestEntity returns a TestEntityMetricsBuilder that restricts metric recording +// to metrics belonging to the test.entity entity. +func (mb *MetricsBuilder) ForTestEntity(e *TestEntityEntity) *TestEntityMetricsBuilder { + return &TestEntityMetricsBuilder{mb: mb, entity: e} +} + // EmitForResource saves all the generated metrics under a new resource and updates the internal state to be ready for // recording another set of data points as part of another resource. This function can be helpful when one scraper // needs to emit metrics from several resources. Otherwise calling this function is not required, // just `Emit` function can be called instead. // Resource attributes should be provided as ResourceMetricsOption arguments. +// +// Deprecated: Use the For methods to get entity-scoped builders and call Emit() on them instead. func (mb *MetricsBuilder) EmitForResource(options ...ResourceMetricsOption) { rm := pmetric.NewResourceMetrics() rm.SetSchemaUrl(conventions.SchemaURL) @@ -538,6 +833,7 @@ func (mb *MetricsBuilder) EmitForResource(options ...ResourceMetricsOption) { mb.metricMetricInputType.emit(ils.Metrics()) mb.metricOptionalMetric.emit(ils.Metrics()) mb.metricOptionalMetricEmptyUnit.emit(ils.Metrics()) + mb.metricReaggregateMetric.emit(ils.Metrics()) for _, op := range options { op.apply(rm) @@ -570,16 +866,22 @@ func (mb *MetricsBuilder) Emit(options ...ResourceMetricsOption) pmetric.Metrics } // RecordDefaultMetricDataPoint adds a data point to default.metric metric. +// +// Deprecated: Use mb.ForTestEntity(entity).RecordDefaultMetricDataPoint(...) instead. func (mb *MetricsBuilder) RecordDefaultMetricDataPoint(ts pcommon.Timestamp, val int64, stringAttrAttributeValue string, overriddenIntAttrAttributeValue int64, enumAttrAttributeValue AttributeEnumAttr, sliceAttrAttributeValue []any, mapAttrAttributeValue map[string]any) { mb.metricDefaultMetric.recordDataPoint(mb.startTime, ts, val, stringAttrAttributeValue, overriddenIntAttrAttributeValue, enumAttrAttributeValue.String(), sliceAttrAttributeValue, mapAttrAttributeValue) } // RecordDefaultMetricToBeRemovedDataPoint adds a data point to default.metric.to_be_removed metric. +// +// Deprecated: Use mb.ForTestEntity(entity).RecordDefaultMetricToBeRemovedDataPoint(...) instead. func (mb *MetricsBuilder) RecordDefaultMetricToBeRemovedDataPoint(ts pcommon.Timestamp, val float64) { mb.metricDefaultMetricToBeRemoved.recordDataPoint(mb.startTime, ts, val) } // RecordMetricInputTypeDataPoint adds a data point to metric.input_type metric. +// +// Deprecated: Use mb.ForTestEntity(entity).RecordMetricInputTypeDataPoint(...) instead. func (mb *MetricsBuilder) RecordMetricInputTypeDataPoint(ts pcommon.Timestamp, inputVal string, stringAttrAttributeValue string, overriddenIntAttrAttributeValue int64, enumAttrAttributeValue AttributeEnumAttr, sliceAttrAttributeValue []any, mapAttrAttributeValue map[string]any) error { val, err := strconv.ParseInt(inputVal, 10, 64) if err != nil { @@ -590,15 +892,26 @@ func (mb *MetricsBuilder) RecordMetricInputTypeDataPoint(ts pcommon.Timestamp, i } // RecordOptionalMetricDataPoint adds a data point to optional.metric metric. +// +// Deprecated: Use mb.ForTestEntity(entity).RecordOptionalMetricDataPoint(...) instead. func (mb *MetricsBuilder) RecordOptionalMetricDataPoint(ts pcommon.Timestamp, val float64, stringAttrAttributeValue string, booleanAttrAttributeValue bool, booleanAttr2AttributeValue bool) { mb.metricOptionalMetric.recordDataPoint(mb.startTime, ts, val, stringAttrAttributeValue, booleanAttrAttributeValue, booleanAttr2AttributeValue) } // RecordOptionalMetricEmptyUnitDataPoint adds a data point to optional.metric.empty_unit metric. +// +// Deprecated: Use mb.ForTestEntity(entity).RecordOptionalMetricEmptyUnitDataPoint(...) instead. func (mb *MetricsBuilder) RecordOptionalMetricEmptyUnitDataPoint(ts pcommon.Timestamp, val float64, stringAttrAttributeValue string, booleanAttrAttributeValue bool) { mb.metricOptionalMetricEmptyUnit.recordDataPoint(mb.startTime, ts, val, stringAttrAttributeValue, booleanAttrAttributeValue) } +// RecordReaggregateMetricDataPoint adds a data point to reaggregate.metric metric. +// +// Deprecated: Use mb.ForTestEntity(entity).RecordReaggregateMetricDataPoint(...) instead. +func (mb *MetricsBuilder) RecordReaggregateMetricDataPoint(ts pcommon.Timestamp, val float64, stringAttrAttributeValue string, booleanAttrAttributeValue bool) { + mb.metricReaggregateMetric.recordDataPoint(mb.startTime, ts, val, stringAttrAttributeValue, booleanAttrAttributeValue) +} + // Reset resets metrics builder to its initial state. It should be used when external metrics source is restarted, // and metrics builder should update its startTime and reset it's internal state accordingly. func (mb *MetricsBuilder) Reset(options ...MetricBuilderOption) { diff --git a/cmd/mdatagen/internal/sampleconnector/internal/metadata/generated_metrics_test.go b/cmd/mdatagen/internal/sampleconnector/internal/metadata/generated_metrics_test.go index 32e55353c2c1..ee250e95c811 100644 --- a/cmd/mdatagen/internal/sampleconnector/internal/metadata/generated_metrics_test.go +++ b/cmd/mdatagen/internal/sampleconnector/internal/metadata/generated_metrics_test.go @@ -20,6 +20,7 @@ const ( testDataSetDefault testDataSet = iota testDataSetAll testDataSetNone + testDataSetReag ) func TestMetricsBuilder(t *testing.T) { @@ -37,6 +38,11 @@ func TestMetricsBuilder(t *testing.T) { metricsSet: testDataSetAll, resAttrsSet: testDataSetAll, }, + { + name: "reaggregate_set", + metricsSet: testDataSetReag, + resAttrsSet: testDataSetReag, + }, { name: "none_set", metricsSet: testDataSetNone, @@ -61,6 +67,12 @@ func TestMetricsBuilder(t *testing.T) { settings := connectortest.NewNopSettings(connectortest.NopType) settings.Logger = zap.New(observedZapCore) mb := NewMetricsBuilder(loadMetricsBuilderConfig(t, tt.name), settings, WithStartTime(start)) + aggMap := make(map[string]string) // contains the aggregation strategies for each metric name + aggMap["DefaultMetric"] = mb.metricDefaultMetric.config.AggregationStrategy + aggMap["MetricInputType"] = mb.metricMetricInputType.config.AggregationStrategy + aggMap["OptionalMetric"] = mb.metricOptionalMetric.config.AggregationStrategy + aggMap["OptionalMetricEmptyUnit"] = mb.metricOptionalMetricEmptyUnit.config.AggregationStrategy + aggMap["ReaggregateMetric"] = mb.metricReaggregateMetric.config.AggregationStrategy expectedWarnings := 0 if tt.metricsSet == testDataSetDefault { @@ -91,29 +103,51 @@ func TestMetricsBuilder(t *testing.T) { assert.Equal(t, "[WARNING] `string.resource.attr_to_be_removed` should not be enabled: This resource_attribute is deprecated and will be removed soon.", observedLogs.All()[expectedWarnings].Message) expectedWarnings++ } - - assert.Equal(t, expectedWarnings, observedLogs.Len()) + if tt.metricsSet != testDataSetReag { + assert.Equal(t, expectedWarnings, observedLogs.Len()) + } defaultMetricsCount := 0 allMetricsCount := 0 + ebTestEntity := mb.ForTestEntity(NewTestEntityEntity("string.resource.attr-val")) defaultMetricsCount++ allMetricsCount++ - mb.RecordDefaultMetricDataPoint(ts, 1, "string_attr-val", 19, AttributeEnumAttrRed, []any{"slice_attr-item1", "slice_attr-item2"}, map[string]any{"key1": "map_attr-val1", "key2": "map_attr-val2"}) + ebTestEntity.RecordDefaultMetricDataPoint(ts, 1, "string_attr-val", 19, AttributeEnumAttrRed, []any{"slice_attr-item1", "slice_attr-item2"}, map[string]any{"key1": "map_attr-val1", "key2": "map_attr-val2"}) + if tt.name == "reaggregate_set" { + ebTestEntity.RecordDefaultMetricDataPoint(ts, 3, "string_attr-val-2", 20, AttributeEnumAttrGreen, []any{"slice_attr-item3", "slice_attr-item4"}, map[string]any{"key3": "map_attr-val3", "key4": "map_attr-val4"}) + } defaultMetricsCount++ allMetricsCount++ - mb.RecordDefaultMetricToBeRemovedDataPoint(ts, 1) + ebTestEntity.RecordDefaultMetricToBeRemovedDataPoint(ts, 1) defaultMetricsCount++ allMetricsCount++ - mb.RecordMetricInputTypeDataPoint(ts, "1", "string_attr-val", 19, AttributeEnumAttrRed, []any{"slice_attr-item1", "slice_attr-item2"}, map[string]any{"key1": "map_attr-val1", "key2": "map_attr-val2"}) + ebTestEntity.RecordMetricInputTypeDataPoint(ts, "1", "string_attr-val", 19, AttributeEnumAttrRed, []any{"slice_attr-item1", "slice_attr-item2"}, map[string]any{"key1": "map_attr-val1", "key2": "map_attr-val2"}) + if tt.name == "reaggregate_set" { + ebTestEntity.RecordMetricInputTypeDataPoint(ts, "3", "string_attr-val-2", 20, AttributeEnumAttrGreen, []any{"slice_attr-item3", "slice_attr-item4"}, map[string]any{"key3": "map_attr-val3", "key4": "map_attr-val4"}) + } + + allMetricsCount++ + ebTestEntity.RecordOptionalMetricDataPoint(ts, 1, "string_attr-val", true, false) + if tt.name == "reaggregate_set" { + ebTestEntity.RecordOptionalMetricDataPoint(ts, 3, "string_attr-val-2", false, true) + } allMetricsCount++ - mb.RecordOptionalMetricDataPoint(ts, 1, "string_attr-val", true, false) + ebTestEntity.RecordOptionalMetricEmptyUnitDataPoint(ts, 1, "string_attr-val", true) + if tt.name == "reaggregate_set" { + ebTestEntity.RecordOptionalMetricEmptyUnitDataPoint(ts, 3, "string_attr-val-2", false) + } + defaultMetricsCount++ allMetricsCount++ - mb.RecordOptionalMetricEmptyUnitDataPoint(ts, 1, "string_attr-val", true) + ebTestEntity.RecordReaggregateMetricDataPoint(ts, 1, "string_attr-val", true) + if tt.name == "reaggregate_set" { + ebTestEntity.RecordReaggregateMetricDataPoint(ts, 3, "string_attr-val-2", false) + } + ebTestEntity.Emit() rb := mb.NewResourceBuilder() rb.SetMapResourceAttr(map[string]any{"key1": "map.resource.attr-val1", "key2": "map.resource.attr-val2"}) @@ -126,137 +160,321 @@ func TestMetricsBuilder(t *testing.T) { rb.SetStringResourceAttrToBeRemoved("string.resource.attr_to_be_removed-val") res := rb.Emit() metrics := mb.Emit(WithResource(res)) + if tt.name == "reaggregate_set" { + assert.Empty(t, mb.metricDefaultMetric.aggDataPoints) + assert.Empty(t, mb.metricMetricInputType.aggDataPoints) + assert.Empty(t, mb.metricOptionalMetric.aggDataPoints) + assert.Empty(t, mb.metricOptionalMetricEmptyUnit.aggDataPoints) + assert.Empty(t, mb.metricReaggregateMetric.aggDataPoints) + } if tt.expectEmpty { assert.Equal(t, 0, metrics.ResourceMetrics().Len()) return } - assert.Equal(t, 1, metrics.ResourceMetrics().Len()) - rm := metrics.ResourceMetrics().At(0) - assert.Equal(t, res, rm.Resource()) - assert.Equal(t, 1, rm.ScopeMetrics().Len()) - ms := rm.ScopeMetrics().At(0).Metrics() + var allMetricsList []pmetric.Metric + totalMetricsCount := 0 + for ri := 0; ri < metrics.ResourceMetrics().Len(); ri++ { + rm := metrics.ResourceMetrics().At(ri) + assert.Equal(t, 1, rm.ScopeMetrics().Len()) + ms := rm.ScopeMetrics().At(0).Metrics() + totalMetricsCount += ms.Len() + for mi := 0; mi < ms.Len(); mi++ { + allMetricsList = append(allMetricsList, ms.At(mi)) + } + } if tt.metricsSet == testDataSetDefault { - assert.Equal(t, defaultMetricsCount, ms.Len()) + assert.Equal(t, defaultMetricsCount, totalMetricsCount) } if tt.metricsSet == testDataSetAll { - assert.Equal(t, allMetricsCount, ms.Len()) + assert.Equal(t, allMetricsCount, totalMetricsCount) } validatedMetrics := make(map[string]bool) - for i := 0; i < ms.Len(); i++ { - switch ms.At(i).Name() { + for _, mi := range allMetricsList { + switch mi.Name() { case "default.metric": - assert.False(t, validatedMetrics["default.metric"], "Found a duplicate in the metrics slice: default.metric") - validatedMetrics["default.metric"] = true - assert.Equal(t, pmetric.MetricTypeSum, ms.At(i).Type()) - assert.Equal(t, 1, ms.At(i).Sum().DataPoints().Len()) - assert.Equal(t, "Monotonic cumulative sum int metric enabled by default.", ms.At(i).Description()) - assert.Equal(t, "s", ms.At(i).Unit()) - assert.True(t, ms.At(i).Sum().IsMonotonic()) - assert.Equal(t, pmetric.AggregationTemporalityCumulative, ms.At(i).Sum().AggregationTemporality()) - dp := ms.At(i).Sum().DataPoints().At(0) - assert.Equal(t, start, dp.StartTimestamp()) - assert.Equal(t, ts, dp.Timestamp()) - assert.Equal(t, pmetric.NumberDataPointValueTypeInt, dp.ValueType()) - assert.Equal(t, int64(1), dp.IntValue()) - attrVal, ok := dp.Attributes().Get("string_attr") - assert.True(t, ok) - assert.Equal(t, "string_attr-val", attrVal.Str()) - attrVal, ok = dp.Attributes().Get("state") - assert.True(t, ok) - assert.EqualValues(t, 19, attrVal.Int()) - attrVal, ok = dp.Attributes().Get("enum_attr") - assert.True(t, ok) - assert.Equal(t, "red", attrVal.Str()) - attrVal, ok = dp.Attributes().Get("slice_attr") - assert.True(t, ok) - assert.Equal(t, []any{"slice_attr-item1", "slice_attr-item2"}, attrVal.Slice().AsRaw()) - attrVal, ok = dp.Attributes().Get("map_attr") - assert.True(t, ok) - assert.Equal(t, map[string]any{"key1": "map_attr-val1", "key2": "map_attr-val2"}, attrVal.Map().AsRaw()) + if tt.name != "reaggregate_set" { + assert.False(t, validatedMetrics["default.metric"], "Found a duplicate in the metrics slice: default.metric") + validatedMetrics["default.metric"] = true + assert.Equal(t, pmetric.MetricTypeSum, mi.Type()) + assert.Equal(t, 1, mi.Sum().DataPoints().Len()) + assert.Equal(t, "Monotonic cumulative sum int metric enabled by default.", mi.Description()) + assert.Equal(t, "s", mi.Unit()) + assert.True(t, mi.Sum().IsMonotonic()) + assert.Equal(t, pmetric.AggregationTemporalityCumulative, mi.Sum().AggregationTemporality()) + dp := mi.Sum().DataPoints().At(0) + assert.Equal(t, start, dp.StartTimestamp()) + assert.Equal(t, ts, dp.Timestamp()) + assert.Equal(t, pmetric.NumberDataPointValueTypeInt, dp.ValueType()) + assert.Equal(t, int64(1), dp.IntValue()) + attrVal, ok := dp.Attributes().Get("string_attr") + assert.True(t, ok) + assert.Equal(t, "string_attr-val", attrVal.Str()) + attrVal, ok = dp.Attributes().Get("state") + assert.True(t, ok) + assert.EqualValues(t, 19, attrVal.Int()) + attrVal, ok = dp.Attributes().Get("enum_attr") + assert.True(t, ok) + assert.Equal(t, "red", attrVal.Str()) + attrVal, ok = dp.Attributes().Get("slice_attr") + assert.True(t, ok) + assert.Equal(t, []any{"slice_attr-item1", "slice_attr-item2"}, attrVal.Slice().AsRaw()) + attrVal, ok = dp.Attributes().Get("map_attr") + assert.True(t, ok) + assert.Equal(t, map[string]any{"key1": "map_attr-val1", "key2": "map_attr-val2"}, attrVal.Map().AsRaw()) + } else { + assert.False(t, validatedMetrics["default.metric"], "Found a duplicate in the metrics slice: default.metric") + validatedMetrics["default.metric"] = true + assert.Equal(t, pmetric.MetricTypeSum, mi.Type()) + assert.Equal(t, 1, mi.Sum().DataPoints().Len()) + assert.Equal(t, "Monotonic cumulative sum int metric enabled by default.", mi.Description()) + assert.Equal(t, "s", mi.Unit()) + assert.True(t, mi.Sum().IsMonotonic()) + assert.Equal(t, pmetric.AggregationTemporalityCumulative, mi.Sum().AggregationTemporality()) + dp := mi.Sum().DataPoints().At(0) + assert.Equal(t, start, dp.StartTimestamp()) + assert.Equal(t, ts, dp.Timestamp()) + assert.Equal(t, pmetric.NumberDataPointValueTypeInt, dp.ValueType()) + switch aggMap["default.metric"] { + case "sum": + assert.Equal(t, int64(4), dp.IntValue()) + case "avg": + assert.Equal(t, int64(2), dp.IntValue()) + case "min": + assert.Equal(t, int64(1), dp.IntValue()) + case "max": + assert.Equal(t, int64(3), dp.IntValue()) + } + _, ok := dp.Attributes().Get("string_attr") + assert.False(t, ok) + _, ok = dp.Attributes().Get("state") + assert.False(t, ok) + _, ok = dp.Attributes().Get("enum_attr") + assert.False(t, ok) + _, ok = dp.Attributes().Get("slice_attr") + assert.False(t, ok) + _, ok = dp.Attributes().Get("map_attr") + assert.False(t, ok) + } case "default.metric.to_be_removed": assert.False(t, validatedMetrics["default.metric.to_be_removed"], "Found a duplicate in the metrics slice: default.metric.to_be_removed") validatedMetrics["default.metric.to_be_removed"] = true - assert.Equal(t, pmetric.MetricTypeSum, ms.At(i).Type()) - assert.Equal(t, 1, ms.At(i).Sum().DataPoints().Len()) - assert.Equal(t, "[DEPRECATED] Non-monotonic delta sum double metric enabled by default.", ms.At(i).Description()) - assert.Equal(t, "s", ms.At(i).Unit()) - assert.False(t, ms.At(i).Sum().IsMonotonic()) - assert.Equal(t, pmetric.AggregationTemporalityDelta, ms.At(i).Sum().AggregationTemporality()) - dp := ms.At(i).Sum().DataPoints().At(0) + assert.Equal(t, pmetric.MetricTypeSum, mi.Type()) + assert.Equal(t, 1, mi.Sum().DataPoints().Len()) + assert.Equal(t, "[DEPRECATED] Non-monotonic delta sum double metric enabled by default.", mi.Description()) + assert.Equal(t, "s", mi.Unit()) + assert.False(t, mi.Sum().IsMonotonic()) + assert.Equal(t, pmetric.AggregationTemporalityDelta, mi.Sum().AggregationTemporality()) + dp := mi.Sum().DataPoints().At(0) assert.Equal(t, start, dp.StartTimestamp()) assert.Equal(t, ts, dp.Timestamp()) assert.Equal(t, pmetric.NumberDataPointValueTypeDouble, dp.ValueType()) assert.InDelta(t, float64(1), dp.DoubleValue(), 0.01) case "metric.input_type": - assert.False(t, validatedMetrics["metric.input_type"], "Found a duplicate in the metrics slice: metric.input_type") - validatedMetrics["metric.input_type"] = true - assert.Equal(t, pmetric.MetricTypeSum, ms.At(i).Type()) - assert.Equal(t, 1, ms.At(i).Sum().DataPoints().Len()) - assert.Equal(t, "Monotonic cumulative sum int metric with string input_type enabled by default.", ms.At(i).Description()) - assert.Equal(t, "s", ms.At(i).Unit()) - assert.True(t, ms.At(i).Sum().IsMonotonic()) - assert.Equal(t, pmetric.AggregationTemporalityCumulative, ms.At(i).Sum().AggregationTemporality()) - dp := ms.At(i).Sum().DataPoints().At(0) - assert.Equal(t, start, dp.StartTimestamp()) - assert.Equal(t, ts, dp.Timestamp()) - assert.Equal(t, pmetric.NumberDataPointValueTypeInt, dp.ValueType()) - assert.Equal(t, int64(1), dp.IntValue()) - attrVal, ok := dp.Attributes().Get("string_attr") - assert.True(t, ok) - assert.Equal(t, "string_attr-val", attrVal.Str()) - attrVal, ok = dp.Attributes().Get("state") - assert.True(t, ok) - assert.EqualValues(t, 19, attrVal.Int()) - attrVal, ok = dp.Attributes().Get("enum_attr") - assert.True(t, ok) - assert.Equal(t, "red", attrVal.Str()) - attrVal, ok = dp.Attributes().Get("slice_attr") - assert.True(t, ok) - assert.Equal(t, []any{"slice_attr-item1", "slice_attr-item2"}, attrVal.Slice().AsRaw()) - attrVal, ok = dp.Attributes().Get("map_attr") - assert.True(t, ok) - assert.Equal(t, map[string]any{"key1": "map_attr-val1", "key2": "map_attr-val2"}, attrVal.Map().AsRaw()) + if tt.name != "reaggregate_set" { + assert.False(t, validatedMetrics["metric.input_type"], "Found a duplicate in the metrics slice: metric.input_type") + validatedMetrics["metric.input_type"] = true + assert.Equal(t, pmetric.MetricTypeSum, mi.Type()) + assert.Equal(t, 1, mi.Sum().DataPoints().Len()) + assert.Equal(t, "Monotonic cumulative sum int metric with string input_type enabled by default.", mi.Description()) + assert.Equal(t, "s", mi.Unit()) + assert.True(t, mi.Sum().IsMonotonic()) + assert.Equal(t, pmetric.AggregationTemporalityCumulative, mi.Sum().AggregationTemporality()) + dp := mi.Sum().DataPoints().At(0) + assert.Equal(t, start, dp.StartTimestamp()) + assert.Equal(t, ts, dp.Timestamp()) + assert.Equal(t, pmetric.NumberDataPointValueTypeInt, dp.ValueType()) + assert.Equal(t, int64(1), dp.IntValue()) + attrVal, ok := dp.Attributes().Get("string_attr") + assert.True(t, ok) + assert.Equal(t, "string_attr-val", attrVal.Str()) + attrVal, ok = dp.Attributes().Get("state") + assert.True(t, ok) + assert.EqualValues(t, 19, attrVal.Int()) + attrVal, ok = dp.Attributes().Get("enum_attr") + assert.True(t, ok) + assert.Equal(t, "red", attrVal.Str()) + attrVal, ok = dp.Attributes().Get("slice_attr") + assert.True(t, ok) + assert.Equal(t, []any{"slice_attr-item1", "slice_attr-item2"}, attrVal.Slice().AsRaw()) + attrVal, ok = dp.Attributes().Get("map_attr") + assert.True(t, ok) + assert.Equal(t, map[string]any{"key1": "map_attr-val1", "key2": "map_attr-val2"}, attrVal.Map().AsRaw()) + } else { + assert.False(t, validatedMetrics["metric.input_type"], "Found a duplicate in the metrics slice: metric.input_type") + validatedMetrics["metric.input_type"] = true + assert.Equal(t, pmetric.MetricTypeSum, mi.Type()) + assert.Equal(t, 1, mi.Sum().DataPoints().Len()) + assert.Equal(t, "Monotonic cumulative sum int metric with string input_type enabled by default.", mi.Description()) + assert.Equal(t, "s", mi.Unit()) + assert.True(t, mi.Sum().IsMonotonic()) + assert.Equal(t, pmetric.AggregationTemporalityCumulative, mi.Sum().AggregationTemporality()) + dp := mi.Sum().DataPoints().At(0) + assert.Equal(t, start, dp.StartTimestamp()) + assert.Equal(t, ts, dp.Timestamp()) + assert.Equal(t, pmetric.NumberDataPointValueTypeInt, dp.ValueType()) + switch aggMap["metric.input_type"] { + case "sum": + assert.Equal(t, int64(4), dp.IntValue()) + case "avg": + assert.Equal(t, int64(2), dp.IntValue()) + case "min": + assert.Equal(t, int64(1), dp.IntValue()) + case "max": + assert.Equal(t, int64(3), dp.IntValue()) + } + _, ok := dp.Attributes().Get("string_attr") + assert.False(t, ok) + _, ok = dp.Attributes().Get("state") + assert.False(t, ok) + _, ok = dp.Attributes().Get("enum_attr") + assert.False(t, ok) + _, ok = dp.Attributes().Get("slice_attr") + assert.False(t, ok) + _, ok = dp.Attributes().Get("map_attr") + assert.False(t, ok) + } case "optional.metric": - assert.False(t, validatedMetrics["optional.metric"], "Found a duplicate in the metrics slice: optional.metric") - validatedMetrics["optional.metric"] = true - assert.Equal(t, pmetric.MetricTypeGauge, ms.At(i).Type()) - assert.Equal(t, 1, ms.At(i).Gauge().DataPoints().Len()) - assert.Equal(t, "[DEPRECATED] Gauge double metric disabled by default.", ms.At(i).Description()) - assert.Equal(t, "1", ms.At(i).Unit()) - dp := ms.At(i).Gauge().DataPoints().At(0) - assert.Equal(t, start, dp.StartTimestamp()) - assert.Equal(t, ts, dp.Timestamp()) - assert.Equal(t, pmetric.NumberDataPointValueTypeDouble, dp.ValueType()) - assert.InDelta(t, float64(1), dp.DoubleValue(), 0.01) - attrVal, ok := dp.Attributes().Get("string_attr") - assert.True(t, ok) - assert.Equal(t, "string_attr-val", attrVal.Str()) - attrVal, ok = dp.Attributes().Get("boolean_attr") - assert.True(t, ok) - assert.True(t, attrVal.Bool()) - attrVal, ok = dp.Attributes().Get("boolean_attr2") - assert.True(t, ok) - assert.False(t, attrVal.Bool()) + if tt.name != "reaggregate_set" { + assert.False(t, validatedMetrics["optional.metric"], "Found a duplicate in the metrics slice: optional.metric") + validatedMetrics["optional.metric"] = true + assert.Equal(t, pmetric.MetricTypeGauge, mi.Type()) + assert.Equal(t, 1, mi.Gauge().DataPoints().Len()) + assert.Equal(t, "[DEPRECATED] Gauge double metric disabled by default.", mi.Description()) + assert.Equal(t, "1", mi.Unit()) + dp := mi.Gauge().DataPoints().At(0) + assert.Equal(t, start, dp.StartTimestamp()) + assert.Equal(t, ts, dp.Timestamp()) + assert.Equal(t, pmetric.NumberDataPointValueTypeDouble, dp.ValueType()) + assert.InDelta(t, float64(1), dp.DoubleValue(), 0.01) + attrVal, ok := dp.Attributes().Get("string_attr") + assert.True(t, ok) + assert.Equal(t, "string_attr-val", attrVal.Str()) + attrVal, ok = dp.Attributes().Get("boolean_attr") + assert.True(t, ok) + assert.True(t, attrVal.Bool()) + attrVal, ok = dp.Attributes().Get("boolean_attr2") + assert.True(t, ok) + assert.False(t, attrVal.Bool()) + } else { + assert.False(t, validatedMetrics["optional.metric"], "Found a duplicate in the metrics slice: optional.metric") + validatedMetrics["optional.metric"] = true + assert.Equal(t, pmetric.MetricTypeGauge, mi.Type()) + assert.Equal(t, 1, mi.Gauge().DataPoints().Len()) + assert.Equal(t, "[DEPRECATED] Gauge double metric disabled by default.", mi.Description()) + assert.Equal(t, "1", mi.Unit()) + dp := mi.Gauge().DataPoints().At(0) + assert.Equal(t, start, dp.StartTimestamp()) + assert.Equal(t, ts, dp.Timestamp()) + assert.Equal(t, pmetric.NumberDataPointValueTypeDouble, dp.ValueType()) + switch aggMap["optional.metric"] { + case "sum": + assert.InDelta(t, float64(4), dp.DoubleValue(), 0.01) + case "avg": + assert.InDelta(t, float64(2), dp.DoubleValue(), 0.01) + case "min": + assert.InDelta(t, float64(1), dp.DoubleValue(), 0.01) + case "max": + assert.InDelta(t, float64(3), dp.DoubleValue(), 0.01) + } + _, ok := dp.Attributes().Get("string_attr") + assert.False(t, ok) + _, ok = dp.Attributes().Get("boolean_attr") + assert.False(t, ok) + _, ok = dp.Attributes().Get("boolean_attr2") + assert.False(t, ok) + } case "optional.metric.empty_unit": - assert.False(t, validatedMetrics["optional.metric.empty_unit"], "Found a duplicate in the metrics slice: optional.metric.empty_unit") - validatedMetrics["optional.metric.empty_unit"] = true - assert.Equal(t, pmetric.MetricTypeGauge, ms.At(i).Type()) - assert.Equal(t, 1, ms.At(i).Gauge().DataPoints().Len()) - assert.Equal(t, "[DEPRECATED] Gauge double metric disabled by default.", ms.At(i).Description()) - assert.Empty(t, ms.At(i).Unit()) - dp := ms.At(i).Gauge().DataPoints().At(0) - assert.Equal(t, start, dp.StartTimestamp()) - assert.Equal(t, ts, dp.Timestamp()) - assert.Equal(t, pmetric.NumberDataPointValueTypeDouble, dp.ValueType()) - assert.InDelta(t, float64(1), dp.DoubleValue(), 0.01) - attrVal, ok := dp.Attributes().Get("string_attr") - assert.True(t, ok) - assert.Equal(t, "string_attr-val", attrVal.Str()) - attrVal, ok = dp.Attributes().Get("boolean_attr") - assert.True(t, ok) - assert.True(t, attrVal.Bool()) + if tt.name != "reaggregate_set" { + assert.False(t, validatedMetrics["optional.metric.empty_unit"], "Found a duplicate in the metrics slice: optional.metric.empty_unit") + validatedMetrics["optional.metric.empty_unit"] = true + assert.Equal(t, pmetric.MetricTypeGauge, mi.Type()) + assert.Equal(t, 1, mi.Gauge().DataPoints().Len()) + assert.Equal(t, "[DEPRECATED] Gauge double metric disabled by default.", mi.Description()) + assert.Empty(t, mi.Unit()) + dp := mi.Gauge().DataPoints().At(0) + assert.Equal(t, start, dp.StartTimestamp()) + assert.Equal(t, ts, dp.Timestamp()) + assert.Equal(t, pmetric.NumberDataPointValueTypeDouble, dp.ValueType()) + assert.InDelta(t, float64(1), dp.DoubleValue(), 0.01) + attrVal, ok := dp.Attributes().Get("string_attr") + assert.True(t, ok) + assert.Equal(t, "string_attr-val", attrVal.Str()) + attrVal, ok = dp.Attributes().Get("boolean_attr") + assert.True(t, ok) + assert.True(t, attrVal.Bool()) + } else { + assert.False(t, validatedMetrics["optional.metric.empty_unit"], "Found a duplicate in the metrics slice: optional.metric.empty_unit") + validatedMetrics["optional.metric.empty_unit"] = true + assert.Equal(t, pmetric.MetricTypeGauge, mi.Type()) + assert.Equal(t, 1, mi.Gauge().DataPoints().Len()) + assert.Equal(t, "[DEPRECATED] Gauge double metric disabled by default.", mi.Description()) + assert.Empty(t, mi.Unit()) + dp := mi.Gauge().DataPoints().At(0) + assert.Equal(t, start, dp.StartTimestamp()) + assert.Equal(t, ts, dp.Timestamp()) + assert.Equal(t, pmetric.NumberDataPointValueTypeDouble, dp.ValueType()) + switch aggMap["optional.metric.empty_unit"] { + case "sum": + assert.InDelta(t, float64(4), dp.DoubleValue(), 0.01) + case "avg": + assert.InDelta(t, float64(2), dp.DoubleValue(), 0.01) + case "min": + assert.InDelta(t, float64(1), dp.DoubleValue(), 0.01) + case "max": + assert.InDelta(t, float64(3), dp.DoubleValue(), 0.01) + } + _, ok := dp.Attributes().Get("string_attr") + assert.False(t, ok) + _, ok = dp.Attributes().Get("boolean_attr") + assert.False(t, ok) + } + case "reaggregate.metric": + if tt.name != "reaggregate_set" { + assert.False(t, validatedMetrics["reaggregate.metric"], "Found a duplicate in the metrics slice: reaggregate.metric") + validatedMetrics["reaggregate.metric"] = true + assert.Equal(t, pmetric.MetricTypeGauge, mi.Type()) + assert.Equal(t, 1, mi.Gauge().DataPoints().Len()) + assert.Equal(t, "Metric for testing spatial reaggregation", mi.Description()) + assert.Equal(t, "1", mi.Unit()) + dp := mi.Gauge().DataPoints().At(0) + assert.Equal(t, start, dp.StartTimestamp()) + assert.Equal(t, ts, dp.Timestamp()) + assert.Equal(t, pmetric.NumberDataPointValueTypeDouble, dp.ValueType()) + assert.InDelta(t, float64(1), dp.DoubleValue(), 0.01) + attrVal, ok := dp.Attributes().Get("string_attr") + assert.True(t, ok) + assert.Equal(t, "string_attr-val", attrVal.Str()) + attrVal, ok = dp.Attributes().Get("boolean_attr") + assert.True(t, ok) + assert.True(t, attrVal.Bool()) + } else { + assert.False(t, validatedMetrics["reaggregate.metric"], "Found a duplicate in the metrics slice: reaggregate.metric") + validatedMetrics["reaggregate.metric"] = true + assert.Equal(t, pmetric.MetricTypeGauge, mi.Type()) + assert.Equal(t, 1, mi.Gauge().DataPoints().Len()) + assert.Equal(t, "Metric for testing spatial reaggregation", mi.Description()) + assert.Equal(t, "1", mi.Unit()) + dp := mi.Gauge().DataPoints().At(0) + assert.Equal(t, start, dp.StartTimestamp()) + assert.Equal(t, ts, dp.Timestamp()) + assert.Equal(t, pmetric.NumberDataPointValueTypeDouble, dp.ValueType()) + switch aggMap["reaggregate.metric"] { + case "sum": + assert.InDelta(t, float64(4), dp.DoubleValue(), 0.01) + case "avg": + assert.InDelta(t, float64(2), dp.DoubleValue(), 0.01) + case "min": + assert.InDelta(t, float64(1), dp.DoubleValue(), 0.01) + case "max": + assert.InDelta(t, float64(3), dp.DoubleValue(), 0.01) + } + _, ok := dp.Attributes().Get("string_attr") + assert.False(t, ok) + _, ok = dp.Attributes().Get("boolean_attr") + assert.False(t, ok) + } } } }) diff --git a/cmd/mdatagen/internal/sampleconnector/internal/metadata/generated_resource.go b/cmd/mdatagen/internal/sampleconnector/internal/metadata/generated_resource.go index bc21975f07f7..da69b3c08411 100644 --- a/cmd/mdatagen/internal/sampleconnector/internal/metadata/generated_resource.go +++ b/cmd/mdatagen/internal/sampleconnector/internal/metadata/generated_resource.go @@ -4,7 +4,6 @@ package metadata import ( "go.opentelemetry.io/collector/pdata/pcommon" - "go.opentelemetry.io/collector/pdata/xpdata/entity" ) // ResourceBuilder is a helper struct to build resources predefined in metadata.yaml. @@ -85,18 +84,6 @@ func (rb *ResourceBuilder) SetStringResourceAttrToBeRemoved(val string) { } } -// AssociateWithTestEntity associates the resource with entity type "test.entity". -// This method is experimental and will be replaced with an entity builder pattern in the future. -// However, for now, it allows associating resources with entities and producing correct entity references. -func (rb *ResourceBuilder) AssociateWithTestEntity() { - entityRef := entity.ResourceEntityRefs(rb.res).AppendEmpty() - entityRef.SetType("test.entity") - idKeys := entityRef.IdKeys() - idKeys.Append("string.resource.attr") - descKeys := entityRef.DescriptionKeys() - descKeys.Append("map.resource.attr") -} - // Emit returns the built resource and resets the internal builder state. func (rb *ResourceBuilder) Emit() pcommon.Resource { r := rb.res diff --git a/cmd/mdatagen/internal/sampleconnector/internal/metadata/generated_status.go b/cmd/mdatagen/internal/sampleconnector/internal/metadata/generated_status.go index 0f4ac454c407..29450fb75d29 100644 --- a/cmd/mdatagen/internal/sampleconnector/internal/metadata/generated_status.go +++ b/cmd/mdatagen/internal/sampleconnector/internal/metadata/generated_status.go @@ -12,5 +12,6 @@ var ( ) const ( - MetricsToMetricsStability = component.StabilityLevelDevelopment + MetricsToMetricsStability = component.StabilityLevelDevelopment + ProfilesToProfilesStability = component.StabilityLevelDevelopment ) diff --git a/cmd/mdatagen/internal/sampleconnector/internal/metadata/testdata/config.yaml b/cmd/mdatagen/internal/sampleconnector/internal/metadata/testdata/config.yaml index c4b7edd65683..d918fb1c4c1e 100644 --- a/cmd/mdatagen/internal/sampleconnector/internal/metadata/testdata/config.yaml +++ b/cmd/mdatagen/internal/sampleconnector/internal/metadata/testdata/config.yaml @@ -3,14 +3,57 @@ all_set: metrics: default.metric: enabled: true + attributes: ["string_attr","state","enum_attr","slice_attr","map_attr"] default.metric.to_be_removed: enabled: true metric.input_type: enabled: true + attributes: ["string_attr","state","enum_attr","slice_attr","map_attr"] optional.metric: enabled: true + attributes: ["string_attr","boolean_attr","boolean_attr2"] optional.metric.empty_unit: enabled: true + attributes: ["string_attr","boolean_attr"] + reaggregate.metric: + enabled: true + attributes: ["string_attr","boolean_attr"] + resource_attributes: + map.resource.attr: + enabled: true + optional.resource.attr: + enabled: true + slice.resource.attr: + enabled: true + string.enum.resource.attr: + enabled: true + string.resource.attr: + enabled: true + string.resource.attr_disable_warning: + enabled: true + string.resource.attr_remove_warning: + enabled: true + string.resource.attr_to_be_removed: + enabled: true +reaggregate_set: + metrics: + default.metric: + enabled: true + attributes: [] + default.metric.to_be_removed: + enabled: true + metric.input_type: + enabled: true + attributes: [] + optional.metric: + enabled: true + attributes: [] + optional.metric.empty_unit: + enabled: true + attributes: [] + reaggregate.metric: + enabled: true + attributes: [] resource_attributes: map.resource.attr: enabled: true @@ -32,14 +75,21 @@ none_set: metrics: default.metric: enabled: false + attributes: ["string_attr","state","enum_attr","slice_attr","map_attr"] default.metric.to_be_removed: enabled: false metric.input_type: enabled: false + attributes: ["string_attr","state","enum_attr","slice_attr","map_attr"] optional.metric: enabled: false + attributes: ["string_attr","boolean_attr","boolean_attr2"] optional.metric.empty_unit: enabled: false + attributes: ["string_attr","boolean_attr"] + reaggregate.metric: + enabled: false + attributes: ["string_attr","boolean_attr"] resource_attributes: map.resource.attr: enabled: false diff --git a/cmd/mdatagen/internal/sampleconnector/metadata.yaml b/cmd/mdatagen/internal/sampleconnector/metadata.yaml index 99c25baa499b..f82539fc9c8e 100644 --- a/cmd/mdatagen/internal/sampleconnector/metadata.yaml +++ b/cmd/mdatagen/internal/sampleconnector/metadata.yaml @@ -1,7 +1,10 @@ # Sample metadata file with all available configurations for a connector. type: sample +display_name: Sample Connector +description: This connector is used for testing purposes to check the output of mdatagen. github_project: open-telemetry/opentelemetry-collector +reaggregation_enabled: true sem_conv_version: 1.9.0 @@ -9,7 +12,7 @@ status: disable_codecov_badge: true class: connector stability: - development: [metrics_to_metrics] + development: [metrics_to_metrics, profiles_to_profiles] distributions: [] unsupported_platforms: [freebsd, illumos] codeowners: @@ -112,8 +115,7 @@ metrics: enabled: true description: Monotonic cumulative sum int metric enabled by default. extended_documentation: The metric will be become optional soon. - stability: - level: development + stability: development unit: s sum: value_type: int @@ -121,6 +123,7 @@ metrics: aggregation_temporality: cumulative attributes: [string_attr, overridden_int_attr, enum_attr, slice_attr, map_attr] + entity: test.entity warnings: if_enabled_not_set: This metric will be disabled by default soon. @@ -128,21 +131,23 @@ metrics: enabled: true description: "[DEPRECATED] Non-monotonic delta sum double metric enabled by default." extended_documentation: The metric will be removed soon. - stability: - level: deprecated + stability: deprecated + deprecated: + since: "1.0.0" + note: "This metric will be removed" unit: s sum: value_type: double monotonic: false aggregation_temporality: delta + entity: test.entity warnings: if_enabled: This metric is deprecated and will be removed soon. metric.input_type: enabled: true description: Monotonic cumulative sum int metric with string input_type enabled by default. - stability: - level: development + stability: development unit: s sum: value_type: int @@ -151,27 +156,44 @@ metrics: aggregation_temporality: cumulative attributes: [string_attr, overridden_int_attr, enum_attr, slice_attr, map_attr] + entity: test.entity optional.metric: enabled: false description: "[DEPRECATED] Gauge double metric disabled by default." - stability: - level: deprecated + stability: deprecated + deprecated: + since: "1.0.0" + note: "This metric will be removed" unit: "1" gauge: value_type: double attributes: [string_attr, boolean_attr, boolean_attr2] + entity: test.entity warnings: if_configured: This metric is deprecated and will be removed soon. optional.metric.empty_unit: enabled: false description: "[DEPRECATED] Gauge double metric disabled by default." - stability: - level: deprecated + stability: deprecated + deprecated: + since: "1.0.0" + note: "This metric will be removed" unit: "" gauge: value_type: double attributes: [string_attr, boolean_attr] + entity: test.entity warnings: if_configured: This metric is deprecated and will be removed soon. + + reaggregate.metric: + enabled: true + description: Metric for testing spatial reaggregation + unit: "1" + stability: beta + gauge: + value_type: double + attributes: [string_attr, boolean_attr] + entity: test.entity diff --git a/cmd/mdatagen/internal/sampleentityreceiver/doc.go b/cmd/mdatagen/internal/sampleentityreceiver/doc.go new file mode 100644 index 000000000000..62bab6860180 --- /dev/null +++ b/cmd/mdatagen/internal/sampleentityreceiver/doc.go @@ -0,0 +1,7 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +// Generate a sample entity-based metrics builder +//go:generate mdatagen metadata.yaml + +package sampleentityreceiver // import "go.opentelemetry.io/collector/cmd/mdatagen/internal/sampleentityreceiver" diff --git a/cmd/mdatagen/internal/sampleentityreceiver/documentation.md b/cmd/mdatagen/internal/sampleentityreceiver/documentation.md new file mode 100644 index 000000000000..5530a6cf657f --- /dev/null +++ b/cmd/mdatagen/internal/sampleentityreceiver/documentation.md @@ -0,0 +1,81 @@ +[comment]: <> (Code generated by mdatagen. DO NOT EDIT.) + +# sampleentity + +## Default Metrics + +The following metrics are emitted by default. Each of them can be disabled by applying the following configuration: + +```yaml +metrics: + : + enabled: false +``` + +### k8s.pod.cpu_time + +CPU time consumed by the pod + +| Unit | Metric Type | Value Type | Aggregation Temporality | Monotonic | Stability | +| ---- | ----------- | ---------- | ----------------------- | --------- | --------- | +| s | Sum | Double | Cumulative | true | Development | + +### k8s.pod.phase + +Current phase of the pod + +| Unit | Metric Type | Value Type | Stability | +| ---- | ----------- | ---------- | --------- | +| 1 | Gauge | Int | Development | + +#### Attributes + +| Name | Description | Values | Requirement Level | +| ---- | ----------- | ------ | -------- | +| phase | The phase of the pod (Pending, Running, Succeeded, Failed, Unknown) | Str: ``Pending``, ``Running``, ``Succeeded``, ``Failed``, ``Unknown`` | Recommended | + +### k8s.replicaset.desired + +Number of desired replicas + +| Unit | Metric Type | Value Type | Stability | +| ---- | ----------- | ---------- | --------- | +| {replicas} | Gauge | Int | Development | + +## Resource Attributes + +| Name | Description | Values | Enabled | +| ---- | ----------- | ------ | ------- | +| k8s.namespace.name | The name of the Kubernetes Namespace | Any Str | true | +| k8s.pod.name | The name of the Kubernetes Pod | Any Str | true | +| k8s.pod.uid | The UID of the Kubernetes Pod | Any Str | true | +| k8s.replicaset.name | The name of the Kubernetes ReplicaSet | Any Str | true | +| k8s.replicaset.uid | The UID of the Kubernetes ReplicaSet | Any Str | true | + +## Entities + +The following entities are defined for this component: + +### k8s.replicaset + +A Kubernetes ReplicaSet + +**Stability:** Development + +**Identifying Attributes:** +- `k8s.replicaset.uid` + +**Descriptive Attributes:** +- `k8s.replicaset.name` + +### k8s.pod + +A Kubernetes Pod + +**Stability:** Development + +**Identifying Attributes:** +- `k8s.pod.uid` + +**Descriptive Attributes:** +- `k8s.pod.name` diff --git a/cmd/mdatagen/internal/sampleentityreceiver/factory.go b/cmd/mdatagen/internal/sampleentityreceiver/factory.go new file mode 100644 index 000000000000..96b2705d5483 --- /dev/null +++ b/cmd/mdatagen/internal/sampleentityreceiver/factory.go @@ -0,0 +1,37 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +package sampleentityreceiver // import "go.opentelemetry.io/collector/cmd/mdatagen/internal/sampleentityreceiver" + +import ( + "context" + + "go.opentelemetry.io/collector/cmd/mdatagen/internal/sampleentityreceiver/internal/metadata" + "go.opentelemetry.io/collector/component" + "go.opentelemetry.io/collector/consumer" + "go.opentelemetry.io/collector/receiver" + "go.opentelemetry.io/collector/receiver/xreceiver" +) + +// NewFactory returns a receiver.Factory for sample entity receiver. +func NewFactory() xreceiver.Factory { + return xreceiver.NewFactory( + metadata.Type, + func() component.Config { return &struct{}{} }, + xreceiver.WithMetrics(createMetrics, metadata.MetricsStability), + ) +} + +func createMetrics(context.Context, receiver.Settings, component.Config, consumer.Metrics) (receiver.Metrics, error) { + return nopInstance, nil +} + +var nopInstance = &nopReceiver{} + +type nopReceiver struct { + component.StartFunc +} + +func (nopReceiver) Shutdown(context.Context) error { + return nil +} diff --git a/cmd/mdatagen/internal/sampleentityreceiver/generated_component_test.go b/cmd/mdatagen/internal/sampleentityreceiver/generated_component_test.go new file mode 100644 index 000000000000..8451baf0360f --- /dev/null +++ b/cmd/mdatagen/internal/sampleentityreceiver/generated_component_test.go @@ -0,0 +1,88 @@ +// Code generated by mdatagen. DO NOT EDIT. + +package sampleentityreceiver + +import ( + "context" + "testing" + + "github.com/stretchr/testify/require" + + "go.opentelemetry.io/collector/component" + "go.opentelemetry.io/collector/component/componenttest" + "go.opentelemetry.io/collector/confmap/confmaptest" + "go.opentelemetry.io/collector/consumer/consumertest" + "go.opentelemetry.io/collector/receiver" + "go.opentelemetry.io/collector/receiver/receivertest" +) + +var typ = component.MustNewType("sampleentity") + +func TestComponentFactoryType(t *testing.T) { + require.Equal(t, typ, NewFactory().Type()) +} + +func TestComponentConfigStruct(t *testing.T) { + require.NoError(t, componenttest.CheckConfigStruct(NewFactory().CreateDefaultConfig())) +} + +func TestComponentLifecycle(t *testing.T) { + factory := NewFactory() + + tests := []struct { + createFn func(ctx context.Context, set receiver.Settings, cfg component.Config) (component.Component, error) + name string + }{ + + { + name: "metrics", + createFn: func(ctx context.Context, set receiver.Settings, cfg component.Config) (component.Component, error) { + return factory.CreateMetrics(ctx, set, cfg, consumertest.NewNop()) + }, + }, + } + + cm, err := confmaptest.LoadConf("metadata.yaml") + require.NoError(t, err) + cfg := factory.CreateDefaultConfig() + sub, err := cm.Sub("tests::config") + require.NoError(t, err) + require.NoError(t, sub.Unmarshal(&cfg)) + + for _, tt := range tests { + t.Run(tt.name+"-shutdown", func(t *testing.T) { + c, err := tt.createFn(context.Background(), receivertest.NewNopSettings(typ), cfg) + require.NoError(t, err) + err = c.Shutdown(context.Background()) + require.NoError(t, err) + }) + t.Run(tt.name+"-lifecycle", func(t *testing.T) { + firstRcvr, err := tt.createFn(context.Background(), receivertest.NewNopSettings(typ), cfg) + require.NoError(t, err) + host := newMdatagenNopHost() + require.NoError(t, err) + require.NoError(t, firstRcvr.Start(context.Background(), host)) + require.NoError(t, firstRcvr.Shutdown(context.Background())) + secondRcvr, err := tt.createFn(context.Background(), receivertest.NewNopSettings(typ), cfg) + require.NoError(t, err) + require.NoError(t, secondRcvr.Start(context.Background(), host)) + require.NoError(t, secondRcvr.Shutdown(context.Background())) + }) + } +} + +var _ component.Host = (*mdatagenNopHost)(nil) + +type mdatagenNopHost struct{} + +func newMdatagenNopHost() component.Host { + return &mdatagenNopHost{} +} + +func (mnh *mdatagenNopHost) GetExtensions() map[component.ID]component.Component { + return nil +} + +func (mnh *mdatagenNopHost) GetFactory(_ component.Kind, _ component.Type) component.Factory { + return nil +} diff --git a/cmd/mdatagen/internal/sampleentityreceiver/generated_package_test.go b/cmd/mdatagen/internal/sampleentityreceiver/generated_package_test.go new file mode 100644 index 000000000000..4dd76d5fbac2 --- /dev/null +++ b/cmd/mdatagen/internal/sampleentityreceiver/generated_package_test.go @@ -0,0 +1,13 @@ +// Code generated by mdatagen. DO NOT EDIT. + +package sampleentityreceiver + +import ( + "testing" + + "go.uber.org/goleak" +) + +func TestMain(m *testing.M) { + goleak.VerifyTestMain(m) +} diff --git a/cmd/mdatagen/internal/sampleentityreceiver/internal/metadata/config.schema.yaml b/cmd/mdatagen/internal/sampleentityreceiver/internal/metadata/config.schema.yaml new file mode 100644 index 000000000000..0c912f6f8687 --- /dev/null +++ b/cmd/mdatagen/internal/sampleentityreceiver/internal/metadata/config.schema.yaml @@ -0,0 +1,124 @@ +# Code generated by mdatagen. DO NOT EDIT. +$defs: + metrics_config: + description: MetricsConfig provides config for sampleentity metrics. + type: object + properties: + k8s.pod.cpu_time: + description: "K8sPodCPUTimeMetricConfig provides config for the k8s.pod.cpu_time metric." + type: object + properties: + enabled: + type: boolean + default: true + k8s.pod.phase: + description: "K8sPodPhaseMetricConfig provides config for the k8s.pod.phase metric." + type: object + properties: + enabled: + type: boolean + default: true + k8s.replicaset.desired: + description: "K8sReplicasetDesiredMetricConfig provides config for the k8s.replicaset.desired metric." + type: object + properties: + enabled: + type: boolean + default: true + resource_attributes_config: + description: ResourceAttributesConfig provides config for sampleentity resource attributes. + type: object + properties: + k8s.namespace.name: + description: ResourceAttributeConfig provides common config for a k8s.namespace.name resource attribute. + type: object + properties: + enabled: + type: boolean + default: true + metrics_include: + description: "Experimental: MetricsInclude defines a list of filters for attribute values. If the list is not empty, only metrics with matching resource attribute values will be emitted." + type: array + items: + $ref: /filter.config + metrics_exclude: + description: "Experimental: MetricsExclude defines a list of filters for attribute values. If the list is not empty, metrics with matching resource attribute values will not be emitted. MetricsInclude has higher priority than MetricsExclude." + type: array + items: + $ref: /filter.config + k8s.pod.name: + description: ResourceAttributeConfig provides common config for a k8s.pod.name resource attribute. + type: object + properties: + enabled: + type: boolean + default: true + metrics_include: + description: "Experimental: MetricsInclude defines a list of filters for attribute values. If the list is not empty, only metrics with matching resource attribute values will be emitted." + type: array + items: + $ref: /filter.config + metrics_exclude: + description: "Experimental: MetricsExclude defines a list of filters for attribute values. If the list is not empty, metrics with matching resource attribute values will not be emitted. MetricsInclude has higher priority than MetricsExclude." + type: array + items: + $ref: /filter.config + k8s.pod.uid: + description: ResourceAttributeConfig provides common config for a k8s.pod.uid resource attribute. + type: object + properties: + enabled: + type: boolean + default: true + metrics_include: + description: "Experimental: MetricsInclude defines a list of filters for attribute values. If the list is not empty, only metrics with matching resource attribute values will be emitted." + type: array + items: + $ref: /filter.config + metrics_exclude: + description: "Experimental: MetricsExclude defines a list of filters for attribute values. If the list is not empty, metrics with matching resource attribute values will not be emitted. MetricsInclude has higher priority than MetricsExclude." + type: array + items: + $ref: /filter.config + k8s.replicaset.name: + description: ResourceAttributeConfig provides common config for a k8s.replicaset.name resource attribute. + type: object + properties: + enabled: + type: boolean + default: true + metrics_include: + description: "Experimental: MetricsInclude defines a list of filters for attribute values. If the list is not empty, only metrics with matching resource attribute values will be emitted." + type: array + items: + $ref: /filter.config + metrics_exclude: + description: "Experimental: MetricsExclude defines a list of filters for attribute values. If the list is not empty, metrics with matching resource attribute values will not be emitted. MetricsInclude has higher priority than MetricsExclude." + type: array + items: + $ref: /filter.config + k8s.replicaset.uid: + description: ResourceAttributeConfig provides common config for a k8s.replicaset.uid resource attribute. + type: object + properties: + enabled: + type: boolean + default: true + metrics_include: + description: "Experimental: MetricsInclude defines a list of filters for attribute values. If the list is not empty, only metrics with matching resource attribute values will be emitted." + type: array + items: + $ref: /filter.config + metrics_exclude: + description: "Experimental: MetricsExclude defines a list of filters for attribute values. If the list is not empty, metrics with matching resource attribute values will not be emitted. MetricsInclude has higher priority than MetricsExclude." + type: array + items: + $ref: /filter.config + metrics_builder_config: + description: MetricsBuilderConfig is a configuration for sampleentity metrics builder. + type: object + properties: + metrics: + $ref: metrics_config + resource_attributes: + $ref: resource_attributes_config diff --git a/cmd/mdatagen/internal/sampleentityreceiver/internal/metadata/generated_config.go b/cmd/mdatagen/internal/sampleentityreceiver/internal/metadata/generated_config.go new file mode 100644 index 000000000000..5909a73e02f1 --- /dev/null +++ b/cmd/mdatagen/internal/sampleentityreceiver/internal/metadata/generated_config.go @@ -0,0 +1,117 @@ +// Code generated by mdatagen. DO NOT EDIT. + +package metadata + +import ( + "go.opentelemetry.io/collector/confmap" + "go.opentelemetry.io/collector/filter" +) + +// MetricConfig provides common config for a particular metric. +type MetricConfig struct { + Enabled bool `mapstructure:"enabled"` + enabledSetByUser bool +} + +func (ms *MetricConfig) Unmarshal(parser *confmap.Conf) error { + if parser == nil { + return nil + } + + err := parser.Unmarshal(ms) + if err != nil { + return err + } + + ms.enabledSetByUser = parser.IsSet("enabled") + return nil +} + +// MetricsConfig provides config for sampleentity metrics. +type MetricsConfig struct { + K8sPodCPUTime MetricConfig `mapstructure:"k8s.pod.cpu_time"` + K8sPodPhase MetricConfig `mapstructure:"k8s.pod.phase"` + K8sReplicasetDesired MetricConfig `mapstructure:"k8s.replicaset.desired"` +} + +func DefaultMetricsConfig() MetricsConfig { + return MetricsConfig{ + K8sPodCPUTime: MetricConfig{ + Enabled: true, + }, + K8sPodPhase: MetricConfig{ + Enabled: true, + }, + K8sReplicasetDesired: MetricConfig{ + Enabled: true, + }, + } +} + +// ResourceAttributeConfig provides common config for a particular resource attribute. +type ResourceAttributeConfig struct { + Enabled bool `mapstructure:"enabled"` + // Experimental: MetricsInclude defines a list of filters for attribute values. + // If the list is not empty, only metrics with matching resource attribute values will be emitted. + MetricsInclude []filter.Config `mapstructure:"metrics_include"` + // Experimental: MetricsExclude defines a list of filters for attribute values. + // If the list is not empty, metrics with matching resource attribute values will not be emitted. + // MetricsInclude has higher priority than MetricsExclude. + MetricsExclude []filter.Config `mapstructure:"metrics_exclude"` + + enabledSetByUser bool +} + +func (rac *ResourceAttributeConfig) Unmarshal(parser *confmap.Conf) error { + if parser == nil { + return nil + } + err := parser.Unmarshal(rac) + if err != nil { + return err + } + rac.enabledSetByUser = parser.IsSet("enabled") + return nil +} + +// ResourceAttributesConfig provides config for sampleentity resource attributes. +type ResourceAttributesConfig struct { + K8sNamespaceName ResourceAttributeConfig `mapstructure:"k8s.namespace.name"` + K8sPodName ResourceAttributeConfig `mapstructure:"k8s.pod.name"` + K8sPodUID ResourceAttributeConfig `mapstructure:"k8s.pod.uid"` + K8sReplicasetName ResourceAttributeConfig `mapstructure:"k8s.replicaset.name"` + K8sReplicasetUID ResourceAttributeConfig `mapstructure:"k8s.replicaset.uid"` +} + +func DefaultResourceAttributesConfig() ResourceAttributesConfig { + return ResourceAttributesConfig{ + K8sNamespaceName: ResourceAttributeConfig{ + Enabled: true, + }, + K8sPodName: ResourceAttributeConfig{ + Enabled: true, + }, + K8sPodUID: ResourceAttributeConfig{ + Enabled: true, + }, + K8sReplicasetName: ResourceAttributeConfig{ + Enabled: true, + }, + K8sReplicasetUID: ResourceAttributeConfig{ + Enabled: true, + }, + } +} + +// MetricsBuilderConfig is a configuration for sampleentity metrics builder. +type MetricsBuilderConfig struct { + Metrics MetricsConfig `mapstructure:"metrics"` + ResourceAttributes ResourceAttributesConfig `mapstructure:"resource_attributes"` +} + +func DefaultMetricsBuilderConfig() MetricsBuilderConfig { + return MetricsBuilderConfig{ + Metrics: DefaultMetricsConfig(), + ResourceAttributes: DefaultResourceAttributesConfig(), + } +} diff --git a/cmd/mdatagen/internal/sampleentityreceiver/internal/metadata/generated_config_test.go b/cmd/mdatagen/internal/sampleentityreceiver/internal/metadata/generated_config_test.go new file mode 100644 index 000000000000..f67a44af0775 --- /dev/null +++ b/cmd/mdatagen/internal/sampleentityreceiver/internal/metadata/generated_config_test.go @@ -0,0 +1,141 @@ +// Code generated by mdatagen. DO NOT EDIT. + +package metadata + +import ( + "path/filepath" + "testing" + + "github.com/google/go-cmp/cmp" + "github.com/google/go-cmp/cmp/cmpopts" + "github.com/stretchr/testify/require" + + "go.opentelemetry.io/collector/confmap" + "go.opentelemetry.io/collector/confmap/confmaptest" +) + +func TestMetricsBuilderConfig(t *testing.T) { + tests := []struct { + name string + want MetricsBuilderConfig + }{ + { + name: "default", + want: DefaultMetricsBuilderConfig(), + }, + { + name: "all_set", + want: MetricsBuilderConfig{ + Metrics: MetricsConfig{ + K8sPodCPUTime: MetricConfig{ + Enabled: true, + }, + K8sPodPhase: MetricConfig{ + Enabled: true, + }, + K8sReplicasetDesired: MetricConfig{ + Enabled: true, + }, + }, + ResourceAttributes: ResourceAttributesConfig{ + K8sNamespaceName: ResourceAttributeConfig{Enabled: true}, + K8sPodName: ResourceAttributeConfig{Enabled: true}, + K8sPodUID: ResourceAttributeConfig{Enabled: true}, + K8sReplicasetName: ResourceAttributeConfig{Enabled: true}, + K8sReplicasetUID: ResourceAttributeConfig{Enabled: true}, + }, + }, + }, + { + name: "none_set", + want: MetricsBuilderConfig{ + Metrics: MetricsConfig{ + K8sPodCPUTime: MetricConfig{ + Enabled: false, + }, + K8sPodPhase: MetricConfig{ + Enabled: false, + }, + K8sReplicasetDesired: MetricConfig{ + Enabled: false, + }, + }, + ResourceAttributes: ResourceAttributesConfig{ + K8sNamespaceName: ResourceAttributeConfig{Enabled: false}, + K8sPodName: ResourceAttributeConfig{Enabled: false}, + K8sPodUID: ResourceAttributeConfig{Enabled: false}, + K8sReplicasetName: ResourceAttributeConfig{Enabled: false}, + K8sReplicasetUID: ResourceAttributeConfig{Enabled: false}, + }, + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + cfg := loadMetricsBuilderConfig(t, tt.name) + diff := cmp.Diff(tt.want, cfg, cmpopts.IgnoreUnexported(MetricConfig{}, ResourceAttributeConfig{})) + require.Emptyf(t, diff, "Config mismatch (-expected +actual):\n%s", diff) + }) + } +} + +func loadMetricsBuilderConfig(t *testing.T, name string) MetricsBuilderConfig { + cm, err := confmaptest.LoadConf(filepath.Join("testdata", "config.yaml")) + require.NoError(t, err) + sub, err := cm.Sub(name) + require.NoError(t, err) + cfg := DefaultMetricsBuilderConfig() + require.NoError(t, sub.Unmarshal(&cfg, confmap.WithIgnoreUnused())) + return cfg +} + +func TestResourceAttributesConfig(t *testing.T) { + tests := []struct { + name string + want ResourceAttributesConfig + }{ + { + name: "default", + want: DefaultResourceAttributesConfig(), + }, + { + name: "all_set", + want: ResourceAttributesConfig{ + K8sNamespaceName: ResourceAttributeConfig{Enabled: true}, + K8sPodName: ResourceAttributeConfig{Enabled: true}, + K8sPodUID: ResourceAttributeConfig{Enabled: true}, + K8sReplicasetName: ResourceAttributeConfig{Enabled: true}, + K8sReplicasetUID: ResourceAttributeConfig{Enabled: true}, + }, + }, + { + name: "none_set", + want: ResourceAttributesConfig{ + K8sNamespaceName: ResourceAttributeConfig{Enabled: false}, + K8sPodName: ResourceAttributeConfig{Enabled: false}, + K8sPodUID: ResourceAttributeConfig{Enabled: false}, + K8sReplicasetName: ResourceAttributeConfig{Enabled: false}, + K8sReplicasetUID: ResourceAttributeConfig{Enabled: false}, + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + cfg := loadResourceAttributesConfig(t, tt.name) + diff := cmp.Diff(tt.want, cfg, cmpopts.IgnoreUnexported(ResourceAttributeConfig{})) + require.Emptyf(t, diff, "Config mismatch (-expected +actual):\n%s", diff) + }) + } +} + +func loadResourceAttributesConfig(t *testing.T, name string) ResourceAttributesConfig { + cm, err := confmaptest.LoadConf(filepath.Join("testdata", "config.yaml")) + require.NoError(t, err) + sub, err := cm.Sub(name) + require.NoError(t, err) + sub, err = sub.Sub("resource_attributes") + require.NoError(t, err) + cfg := DefaultResourceAttributesConfig() + require.NoError(t, sub.Unmarshal(&cfg)) + return cfg +} diff --git a/cmd/mdatagen/internal/sampleentityreceiver/internal/metadata/generated_entity_metrics.go b/cmd/mdatagen/internal/sampleentityreceiver/internal/metadata/generated_entity_metrics.go new file mode 100644 index 000000000000..797ab46d812f --- /dev/null +++ b/cmd/mdatagen/internal/sampleentityreceiver/internal/metadata/generated_entity_metrics.go @@ -0,0 +1,168 @@ +// Code generated by mdatagen. DO NOT EDIT. + +package metadata + +import ( + "go.opentelemetry.io/collector/pdata/pcommon" + "go.opentelemetry.io/collector/pdata/xpdata/entity" +) + +// K8sReplicasetEntity represents a k8s.replicaset entity. +// Create one with NewK8sReplicasetEntity and pass it to EmitForEntity. +type K8sReplicasetEntity struct { + k8sReplicasetUID string + k8sReplicasetName string +} + +// NewK8sReplicasetEntity creates a new K8sReplicasetEntity. +// Identity attributes are required and must be provided at construction time. +func NewK8sReplicasetEntity(k8sReplicasetUID string) *K8sReplicasetEntity { + return &K8sReplicasetEntity{ + k8sReplicasetUID: k8sReplicasetUID, + } +} + +// Description attribute setters for k8s.replicaset. + +// SetK8sReplicasetName sets the k8s.replicaset.name description attribute. +func (e *K8sReplicasetEntity) SetK8sReplicasetName(val string) { + e.k8sReplicasetName = val +} + +// copyToResource populates res with the entity's attributes according to cfg. +// If all identity attributes are enabled, an entity ref is produced; otherwise +// the enabled attributes are written directly as plain resource attributes. +func (e *K8sReplicasetEntity) copyToResource(cfg ResourceAttributesConfig, res pcommon.Resource) { + if cfg.K8sReplicasetUID.Enabled { + ent := entity.ResourceEntities(res).PutEmpty("k8s.replicaset") + ent.IdentifyingAttributes().PutStr("k8s.replicaset.uid", e.k8sReplicasetUID) + if cfg.K8sReplicasetName.Enabled { + ent.DescriptiveAttributes().PutStr("k8s.replicaset.name", e.k8sReplicasetName) + } + } else { + if cfg.K8sReplicasetUID.Enabled { + res.Attributes().PutStr("k8s.replicaset.uid", e.k8sReplicasetUID) + } + if cfg.K8sReplicasetName.Enabled { + res.Attributes().PutStr("k8s.replicaset.name", e.k8sReplicasetName) + } + } +} + +// K8sPodEntity represents a k8s.pod entity. +// Create one with NewK8sPodEntity and pass it to EmitForEntity. +type K8sPodEntity struct { + k8sPodUID string + k8sPodName string + k8sNamespaceName string + controlledByK8sReplicaset *K8sReplicasetEntity +} + +// NewK8sPodEntity creates a new K8sPodEntity. +// Identity attributes are required and must be provided at construction time. +func NewK8sPodEntity(k8sPodUID string) *K8sPodEntity { + return &K8sPodEntity{ + k8sPodUID: k8sPodUID, + } +} + +// Description attribute setters for k8s.pod. + +// SetK8sPodName sets the k8s.pod.name description attribute. +func (e *K8sPodEntity) SetK8sPodName(val string) { + e.k8sPodName = val +} + +// Extra attribute setters for k8s.pod. +// These attributes are contextually relevant but are not part of the entity's identity or description. + +// SetK8sNamespaceName sets the k8s.namespace.name extra attribute on the resource. +func (e *K8sPodEntity) SetK8sNamespaceName(val string) { + e.k8sNamespaceName = val +} + +// Relationship setters for k8s.pod. + +// SetControlledByK8sReplicaset sets the controlled_by relationship to a k8s.replicaset entity. +// The related entity will be emitted alongside this entity's metrics. +func (e *K8sPodEntity) SetControlledByK8sReplicaset(target *K8sReplicasetEntity) { + e.controlledByK8sReplicaset = target +} + +// copyToResource populates res with the entity's attributes according to cfg. +// If all identity attributes are enabled, an entity ref is produced; otherwise +// the enabled attributes are written directly as plain resource attributes. +func (e *K8sPodEntity) copyToResource(cfg ResourceAttributesConfig, res pcommon.Resource) { + if cfg.K8sPodUID.Enabled { + ent := entity.ResourceEntities(res).PutEmpty("k8s.pod") + ent.IdentifyingAttributes().PutStr("k8s.pod.uid", e.k8sPodUID) + if cfg.K8sPodName.Enabled { + ent.DescriptiveAttributes().PutStr("k8s.pod.name", e.k8sPodName) + } + if cfg.K8sNamespaceName.Enabled { + ent.DescriptiveAttributes().PutStr("k8s.namespace.name", e.k8sNamespaceName) + } + } else { + if cfg.K8sPodUID.Enabled { + res.Attributes().PutStr("k8s.pod.uid", e.k8sPodUID) + } + if cfg.K8sPodName.Enabled { + res.Attributes().PutStr("k8s.pod.name", e.k8sPodName) + } + if cfg.K8sNamespaceName.Enabled { + res.Attributes().PutStr("k8s.namespace.name", e.k8sNamespaceName) + } + } +} + +// K8sReplicasetMetricsBuilder records metrics for the k8s.replicaset entity. +// Obtain one via MetricsBuilder.ForK8sReplicaset(). +type K8sReplicasetMetricsBuilder struct { + mb *MetricsBuilder + entity *K8sReplicasetEntity +} + +// RecordK8sReplicasetDesiredDataPoint records a data point for the k8s.replicaset.desired metric. +func (eb *K8sReplicasetMetricsBuilder) RecordK8sReplicasetDesiredDataPoint(ts pcommon.Timestamp, val int64) { + eb.mb.metricK8sReplicasetDesired.recordDataPoint(eb.mb.startTime, ts, val) +} + +// Emit emits all pending metrics for the entity. Resource attributes are filtered by config: +// disabled identity attributes suppress the entity (other enabled attributes are added directly +// to the resource); disabled descriptive/extra attributes are omitted entirely. +func (eb *K8sReplicasetMetricsBuilder) Emit() { + res := pcommon.NewResource() + cfg := eb.mb.config.ResourceAttributes + eb.entity.copyToResource(cfg, res) + eb.mb.EmitForResource(withResourceMoved(res)) +} + +// K8sPodMetricsBuilder records metrics for the k8s.pod entity. +// Obtain one via MetricsBuilder.ForK8sPod(). +type K8sPodMetricsBuilder struct { + mb *MetricsBuilder + entity *K8sPodEntity +} + +// RecordK8sPodCPUTimeDataPoint records a data point for the k8s.pod.cpu_time metric. +func (eb *K8sPodMetricsBuilder) RecordK8sPodCPUTimeDataPoint(ts pcommon.Timestamp, val float64) { + eb.mb.metricK8sPodCPUTime.recordDataPoint(eb.mb.startTime, ts, val) +} + +// RecordK8sPodPhaseDataPoint records a data point for the k8s.pod.phase metric. +func (eb *K8sPodMetricsBuilder) RecordK8sPodPhaseDataPoint(ts pcommon.Timestamp, val int64, phaseAttributeValue AttributePhase) { + eb.mb.metricK8sPodPhase.recordDataPoint(eb.mb.startTime, ts, val, phaseAttributeValue.String()) +} + +// Emit emits all pending metrics for the entity. Resource attributes are filtered by config: +// disabled identity attributes suppress the entity (other enabled attributes are added directly +// to the resource); disabled descriptive/extra attributes are omitted entirely. +func (eb *K8sPodMetricsBuilder) Emit() { + res := pcommon.NewResource() + cfg := eb.mb.config.ResourceAttributes + eb.entity.copyToResource(cfg, res) + if eb.entity.controlledByK8sReplicaset != nil { + eb.entity.controlledByK8sReplicaset.copyToResource(cfg, res) + } + eb.mb.EmitForResource(withResourceMoved(res)) +} diff --git a/cmd/mdatagen/internal/sampleentityreceiver/internal/metadata/generated_entity_metrics_test.go b/cmd/mdatagen/internal/sampleentityreceiver/internal/metadata/generated_entity_metrics_test.go new file mode 100644 index 000000000000..1094d17b0a20 --- /dev/null +++ b/cmd/mdatagen/internal/sampleentityreceiver/internal/metadata/generated_entity_metrics_test.go @@ -0,0 +1,179 @@ +// Code generated by mdatagen. DO NOT EDIT. + +package metadata + +import ( + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + + "go.opentelemetry.io/collector/pdata/pcommon" + "go.opentelemetry.io/collector/pdata/xpdata/entity" + "go.opentelemetry.io/collector/receiver/receivertest" +) + +func TestEntityBuilders(t *testing.T) { + start := pcommon.Timestamp(1_000_000_000) + ts := pcommon.Timestamp(1_000_001_000) + settings := receivertest.NewNopSettings(receivertest.NopType) + mb := NewMetricsBuilder(DefaultMetricsBuilderConfig(), settings, WithStartTime(start)) + + t.Run("k8s.replicaset", func(t *testing.T) { + e := NewK8sReplicasetEntity("k8s.replicaset.uid-val") + require.NotNil(t, e) + e.SetK8sReplicasetName("k8s.replicaset.name-val") + + eb := mb.ForK8sReplicaset(e) + eb.RecordK8sReplicasetDesiredDataPoint(ts, 1) + eb.Emit() + metrics := mb.Emit() + + require.Equal(t, 1, metrics.ResourceMetrics().Len()) + rm := metrics.ResourceMetrics().At(0) + entityVal, ok := entity.ResourceEntities(rm.Resource()).Get("k8s.replicaset") + require.True(t, ok) + attrVal, ok := entityVal.IdentifyingAttributes().Get("k8s.replicaset.uid") + require.True(t, ok) + assert.Equal(t, "k8s.replicaset.uid-val", attrVal.Str()) + + require.Equal(t, 1, rm.ScopeMetrics().Len()) + ms := rm.ScopeMetrics().At(0).Metrics() + assert.Equal(t, 1, ms.Len()) + }) + t.Run("k8s.replicaset/disabled_identity_attr", func(t *testing.T) { + // When an identity attribute is disabled, the entity is not produced but + // other enabled attributes are still added to the resource directly. + cfg := DefaultMetricsBuilderConfig() + cfg.ResourceAttributes.K8sReplicasetUID.Enabled = false + mb := NewMetricsBuilder(cfg, settings, WithStartTime(start)) + + e := NewK8sReplicasetEntity("k8s.replicaset.uid-val") + e.SetK8sReplicasetName("k8s.replicaset.name-val") + + eb := mb.ForK8sReplicaset(e) + eb.RecordK8sReplicasetDesiredDataPoint(ts, 1) + eb.Emit() + metrics := mb.Emit() + + require.Equal(t, 1, metrics.ResourceMetrics().Len()) + rm := metrics.ResourceMetrics().At(0) + // Entity must not be present since its identity attribute is disabled. + _, ok := entity.ResourceEntities(rm.Resource()).Get("k8s.replicaset") + assert.False(t, ok) + // Enabled descriptive attributes should still be on the resource directly. + _, ok = rm.Resource().Attributes().Get("k8s.replicaset.name") + assert.True(t, ok) + }) + t.Run("k8s.replicaset/disabled_descriptive_attr", func(t *testing.T) { + // When a descriptive attribute is disabled, the entity is still produced + // with its identity but the disabled attribute is not added. + cfg := DefaultMetricsBuilderConfig() + cfg.ResourceAttributes.K8sReplicasetName.Enabled = false + mb := NewMetricsBuilder(cfg, settings, WithStartTime(start)) + + e := NewK8sReplicasetEntity("k8s.replicaset.uid-val") + e.SetK8sReplicasetName("k8s.replicaset.name-val") + + eb := mb.ForK8sReplicaset(e) + eb.RecordK8sReplicasetDesiredDataPoint(ts, 1) + eb.Emit() + metrics := mb.Emit() + + require.Equal(t, 1, metrics.ResourceMetrics().Len()) + rm := metrics.ResourceMetrics().At(0) + // Entity must still be produced since identity attributes are enabled. + entityVal, ok := entity.ResourceEntities(rm.Resource()).Get("k8s.replicaset") + require.True(t, ok) + attrVal, ok := entityVal.IdentifyingAttributes().Get("k8s.replicaset.uid") + require.True(t, ok) + assert.Equal(t, "k8s.replicaset.uid-val", attrVal.Str()) + // Disabled descriptive/extra attributes must not be present. + _, ok = entityVal.DescriptiveAttributes().Get("k8s.replicaset.name") + assert.False(t, ok) + }) + + t.Run("k8s.pod", func(t *testing.T) { + e := NewK8sPodEntity("k8s.pod.uid-val") + require.NotNil(t, e) + e.SetK8sPodName("k8s.pod.name-val") + e.SetK8sNamespaceName("k8s.namespace.name-val") + relatedK8sReplicaset := NewK8sReplicasetEntity("k8s.replicaset.uid-val") + e.SetControlledByK8sReplicaset(relatedK8sReplicaset) + + eb := mb.ForK8sPod(e) + eb.RecordK8sPodCPUTimeDataPoint(ts, 1) + eb.RecordK8sPodPhaseDataPoint(ts, 1, AttributePhasePending) + eb.Emit() + metrics := mb.Emit() + + require.Equal(t, 1, metrics.ResourceMetrics().Len()) + rm := metrics.ResourceMetrics().At(0) + entityVal, ok := entity.ResourceEntities(rm.Resource()).Get("k8s.pod") + require.True(t, ok) + attrVal, ok := entityVal.IdentifyingAttributes().Get("k8s.pod.uid") + require.True(t, ok) + assert.Equal(t, "k8s.pod.uid-val", attrVal.Str()) + + require.Equal(t, 1, rm.ScopeMetrics().Len()) + ms := rm.ScopeMetrics().At(0).Metrics() + assert.Equal(t, 2, ms.Len()) + }) + t.Run("k8s.pod/disabled_identity_attr", func(t *testing.T) { + // When an identity attribute is disabled, the entity is not produced but + // other enabled attributes are still added to the resource directly. + cfg := DefaultMetricsBuilderConfig() + cfg.ResourceAttributes.K8sPodUID.Enabled = false + mb := NewMetricsBuilder(cfg, settings, WithStartTime(start)) + + e := NewK8sPodEntity("k8s.pod.uid-val") + e.SetK8sPodName("k8s.pod.name-val") + + eb := mb.ForK8sPod(e) + eb.RecordK8sPodCPUTimeDataPoint(ts, 1) + eb.RecordK8sPodPhaseDataPoint(ts, 1, AttributePhasePending) + eb.Emit() + metrics := mb.Emit() + + require.Equal(t, 1, metrics.ResourceMetrics().Len()) + rm := metrics.ResourceMetrics().At(0) + // Entity must not be present since its identity attribute is disabled. + _, ok := entity.ResourceEntities(rm.Resource()).Get("k8s.pod") + assert.False(t, ok) + // Enabled descriptive attributes should still be on the resource directly. + _, ok = rm.Resource().Attributes().Get("k8s.pod.name") + assert.True(t, ok) + }) + t.Run("k8s.pod/disabled_descriptive_attr", func(t *testing.T) { + // When a descriptive attribute is disabled, the entity is still produced + // with its identity but the disabled attribute is not added. + cfg := DefaultMetricsBuilderConfig() + cfg.ResourceAttributes.K8sPodName.Enabled = false + cfg.ResourceAttributes.K8sNamespaceName.Enabled = false + mb := NewMetricsBuilder(cfg, settings, WithStartTime(start)) + + e := NewK8sPodEntity("k8s.pod.uid-val") + e.SetK8sPodName("k8s.pod.name-val") + e.SetK8sNamespaceName("k8s.namespace.name-val") + + eb := mb.ForK8sPod(e) + eb.RecordK8sPodCPUTimeDataPoint(ts, 1) + eb.RecordK8sPodPhaseDataPoint(ts, 1, AttributePhasePending) + eb.Emit() + metrics := mb.Emit() + + require.Equal(t, 1, metrics.ResourceMetrics().Len()) + rm := metrics.ResourceMetrics().At(0) + // Entity must still be produced since identity attributes are enabled. + entityVal, ok := entity.ResourceEntities(rm.Resource()).Get("k8s.pod") + require.True(t, ok) + attrVal, ok := entityVal.IdentifyingAttributes().Get("k8s.pod.uid") + require.True(t, ok) + assert.Equal(t, "k8s.pod.uid-val", attrVal.Str()) + // Disabled descriptive/extra attributes must not be present. + _, ok = entityVal.DescriptiveAttributes().Get("k8s.pod.name") + assert.False(t, ok) + _, ok = entityVal.DescriptiveAttributes().Get("k8s.namespace.name") + assert.False(t, ok) + }) +} diff --git a/cmd/mdatagen/internal/sampleentityreceiver/internal/metadata/generated_metrics.go b/cmd/mdatagen/internal/sampleentityreceiver/internal/metadata/generated_metrics.go new file mode 100644 index 000000000000..f3af73a00bde --- /dev/null +++ b/cmd/mdatagen/internal/sampleentityreceiver/internal/metadata/generated_metrics.go @@ -0,0 +1,457 @@ +// Code generated by mdatagen. DO NOT EDIT. + +package metadata + +import ( + "time" + + conventions "go.opentelemetry.io/otel/semconv/v1.38.0" + + "go.opentelemetry.io/collector/component" + "go.opentelemetry.io/collector/filter" + "go.opentelemetry.io/collector/pdata/pcommon" + "go.opentelemetry.io/collector/pdata/pmetric" + "go.opentelemetry.io/collector/receiver" +) + +// AttributePhase specifies the value phase attribute. +type AttributePhase int + +const ( + _ AttributePhase = iota + AttributePhasePending + AttributePhaseRunning + AttributePhaseSucceeded + AttributePhaseFailed + AttributePhaseUnknown +) + +// String returns the string representation of the AttributePhase. +func (av AttributePhase) String() string { + switch av { + case AttributePhasePending: + return "Pending" + case AttributePhaseRunning: + return "Running" + case AttributePhaseSucceeded: + return "Succeeded" + case AttributePhaseFailed: + return "Failed" + case AttributePhaseUnknown: + return "Unknown" + } + return "" +} + +// MapAttributePhase is a helper map of string to AttributePhase attribute value. +var MapAttributePhase = map[string]AttributePhase{ + "Pending": AttributePhasePending, + "Running": AttributePhaseRunning, + "Succeeded": AttributePhaseSucceeded, + "Failed": AttributePhaseFailed, + "Unknown": AttributePhaseUnknown, +} + +var MetricsInfo = metricsInfo{ + K8sPodCPUTime: metricInfo{ + Name: "k8s.pod.cpu_time", + }, + K8sPodPhase: metricInfo{ + Name: "k8s.pod.phase", + }, + K8sReplicasetDesired: metricInfo{ + Name: "k8s.replicaset.desired", + }, +} + +type metricsInfo struct { + K8sPodCPUTime metricInfo + K8sPodPhase metricInfo + K8sReplicasetDesired metricInfo +} + +type metricInfo struct { + Name string +} + +type metricK8sPodCPUTime struct { + data pmetric.Metric // data buffer for generated metric. + config MetricConfig // metric config provided by user. + capacity int // max observed number of data points added to the metric. +} + +// init fills k8s.pod.cpu_time metric with initial data. +func (m *metricK8sPodCPUTime) init() { + m.data.SetName("k8s.pod.cpu_time") + m.data.SetDescription("CPU time consumed by the pod") + m.data.SetUnit("s") + m.data.SetEmptySum() + m.data.Sum().SetIsMonotonic(true) + m.data.Sum().SetAggregationTemporality(pmetric.AggregationTemporalityCumulative) +} + +func (m *metricK8sPodCPUTime) recordDataPoint(start pcommon.Timestamp, ts pcommon.Timestamp, val float64) { + if !m.config.Enabled { + return + } + dp := m.data.Sum().DataPoints().AppendEmpty() + dp.SetStartTimestamp(start) + dp.SetTimestamp(ts) + dp.SetDoubleValue(val) +} + +// updateCapacity saves max length of data point slices that will be used for the slice capacity. +func (m *metricK8sPodCPUTime) updateCapacity() { + if m.data.Sum().DataPoints().Len() > m.capacity { + m.capacity = m.data.Sum().DataPoints().Len() + } +} + +// emit appends recorded metric data to a metrics slice and prepares it for recording another set of data points. +func (m *metricK8sPodCPUTime) emit(metrics pmetric.MetricSlice) { + if m.config.Enabled && m.data.Sum().DataPoints().Len() > 0 { + m.updateCapacity() + m.data.MoveTo(metrics.AppendEmpty()) + m.init() + } +} + +func newMetricK8sPodCPUTime(cfg MetricConfig) metricK8sPodCPUTime { + m := metricK8sPodCPUTime{config: cfg} + + if cfg.Enabled { + m.data = pmetric.NewMetric() + m.init() + } + return m +} + +type metricK8sPodPhase struct { + data pmetric.Metric // data buffer for generated metric. + config MetricConfig // metric config provided by user. + capacity int // max observed number of data points added to the metric. +} + +// init fills k8s.pod.phase metric with initial data. +func (m *metricK8sPodPhase) init() { + m.data.SetName("k8s.pod.phase") + m.data.SetDescription("Current phase of the pod") + m.data.SetUnit("1") + m.data.SetEmptyGauge() + m.data.Gauge().DataPoints().EnsureCapacity(m.capacity) +} + +func (m *metricK8sPodPhase) recordDataPoint(start pcommon.Timestamp, ts pcommon.Timestamp, val int64, phaseAttributeValue string) { + if !m.config.Enabled { + return + } + dp := m.data.Gauge().DataPoints().AppendEmpty() + dp.SetStartTimestamp(start) + dp.SetTimestamp(ts) + dp.SetIntValue(val) + dp.Attributes().PutStr("phase", phaseAttributeValue) +} + +// updateCapacity saves max length of data point slices that will be used for the slice capacity. +func (m *metricK8sPodPhase) updateCapacity() { + if m.data.Gauge().DataPoints().Len() > m.capacity { + m.capacity = m.data.Gauge().DataPoints().Len() + } +} + +// emit appends recorded metric data to a metrics slice and prepares it for recording another set of data points. +func (m *metricK8sPodPhase) emit(metrics pmetric.MetricSlice) { + if m.config.Enabled && m.data.Gauge().DataPoints().Len() > 0 { + m.updateCapacity() + m.data.MoveTo(metrics.AppendEmpty()) + m.init() + } +} + +func newMetricK8sPodPhase(cfg MetricConfig) metricK8sPodPhase { + m := metricK8sPodPhase{config: cfg} + + if cfg.Enabled { + m.data = pmetric.NewMetric() + m.init() + } + return m +} + +type metricK8sReplicasetDesired struct { + data pmetric.Metric // data buffer for generated metric. + config MetricConfig // metric config provided by user. + capacity int // max observed number of data points added to the metric. +} + +// init fills k8s.replicaset.desired metric with initial data. +func (m *metricK8sReplicasetDesired) init() { + m.data.SetName("k8s.replicaset.desired") + m.data.SetDescription("Number of desired replicas") + m.data.SetUnit("{replicas}") + m.data.SetEmptyGauge() +} + +func (m *metricK8sReplicasetDesired) recordDataPoint(start pcommon.Timestamp, ts pcommon.Timestamp, val int64) { + if !m.config.Enabled { + return + } + dp := m.data.Gauge().DataPoints().AppendEmpty() + dp.SetStartTimestamp(start) + dp.SetTimestamp(ts) + dp.SetIntValue(val) +} + +// updateCapacity saves max length of data point slices that will be used for the slice capacity. +func (m *metricK8sReplicasetDesired) updateCapacity() { + if m.data.Gauge().DataPoints().Len() > m.capacity { + m.capacity = m.data.Gauge().DataPoints().Len() + } +} + +// emit appends recorded metric data to a metrics slice and prepares it for recording another set of data points. +func (m *metricK8sReplicasetDesired) emit(metrics pmetric.MetricSlice) { + if m.config.Enabled && m.data.Gauge().DataPoints().Len() > 0 { + m.updateCapacity() + m.data.MoveTo(metrics.AppendEmpty()) + m.init() + } +} + +func newMetricK8sReplicasetDesired(cfg MetricConfig) metricK8sReplicasetDesired { + m := metricK8sReplicasetDesired{config: cfg} + + if cfg.Enabled { + m.data = pmetric.NewMetric() + m.init() + } + return m +} + +// MetricsBuilder provides an interface for scrapers to report metrics while taking care of all the transformations +// required to produce metric representation defined in metadata and user config. +type MetricsBuilder struct { + config MetricsBuilderConfig // config of the metrics builder. + startTime pcommon.Timestamp // start time that will be applied to all recorded data points. + metricsCapacity int // maximum observed number of metrics per resource. + metricsBuffer pmetric.Metrics // accumulates metrics data before emitting. + buildInfo component.BuildInfo // contains version information. + resourceAttributeIncludeFilter map[string]filter.Filter + resourceAttributeExcludeFilter map[string]filter.Filter + metricK8sPodCPUTime metricK8sPodCPUTime + metricK8sPodPhase metricK8sPodPhase + metricK8sReplicasetDesired metricK8sReplicasetDesired +} + +// MetricBuilderOption applies changes to default metrics builder. +type MetricBuilderOption interface { + apply(*MetricsBuilder) +} + +type metricBuilderOptionFunc func(mb *MetricsBuilder) + +func (mbof metricBuilderOptionFunc) apply(mb *MetricsBuilder) { + mbof(mb) +} + +// WithStartTime sets startTime on the metrics builder. +func WithStartTime(startTime pcommon.Timestamp) MetricBuilderOption { + return metricBuilderOptionFunc(func(mb *MetricsBuilder) { + mb.startTime = startTime + }) +} +func NewMetricsBuilder(mbc MetricsBuilderConfig, settings receiver.Settings, options ...MetricBuilderOption) *MetricsBuilder { + mb := &MetricsBuilder{ + config: mbc, + startTime: pcommon.NewTimestampFromTime(time.Now()), + metricsBuffer: pmetric.NewMetrics(), + buildInfo: settings.BuildInfo, + metricK8sPodCPUTime: newMetricK8sPodCPUTime(mbc.Metrics.K8sPodCPUTime), + metricK8sPodPhase: newMetricK8sPodPhase(mbc.Metrics.K8sPodPhase), + metricK8sReplicasetDesired: newMetricK8sReplicasetDesired(mbc.Metrics.K8sReplicasetDesired), + resourceAttributeIncludeFilter: make(map[string]filter.Filter), + resourceAttributeExcludeFilter: make(map[string]filter.Filter), + } + if mbc.ResourceAttributes.K8sNamespaceName.MetricsInclude != nil { + mb.resourceAttributeIncludeFilter["k8s.namespace.name"] = filter.CreateFilter(mbc.ResourceAttributes.K8sNamespaceName.MetricsInclude) + } + if mbc.ResourceAttributes.K8sNamespaceName.MetricsExclude != nil { + mb.resourceAttributeExcludeFilter["k8s.namespace.name"] = filter.CreateFilter(mbc.ResourceAttributes.K8sNamespaceName.MetricsExclude) + } + if mbc.ResourceAttributes.K8sPodName.MetricsInclude != nil { + mb.resourceAttributeIncludeFilter["k8s.pod.name"] = filter.CreateFilter(mbc.ResourceAttributes.K8sPodName.MetricsInclude) + } + if mbc.ResourceAttributes.K8sPodName.MetricsExclude != nil { + mb.resourceAttributeExcludeFilter["k8s.pod.name"] = filter.CreateFilter(mbc.ResourceAttributes.K8sPodName.MetricsExclude) + } + if mbc.ResourceAttributes.K8sPodUID.MetricsInclude != nil { + mb.resourceAttributeIncludeFilter["k8s.pod.uid"] = filter.CreateFilter(mbc.ResourceAttributes.K8sPodUID.MetricsInclude) + } + if mbc.ResourceAttributes.K8sPodUID.MetricsExclude != nil { + mb.resourceAttributeExcludeFilter["k8s.pod.uid"] = filter.CreateFilter(mbc.ResourceAttributes.K8sPodUID.MetricsExclude) + } + if mbc.ResourceAttributes.K8sReplicasetName.MetricsInclude != nil { + mb.resourceAttributeIncludeFilter["k8s.replicaset.name"] = filter.CreateFilter(mbc.ResourceAttributes.K8sReplicasetName.MetricsInclude) + } + if mbc.ResourceAttributes.K8sReplicasetName.MetricsExclude != nil { + mb.resourceAttributeExcludeFilter["k8s.replicaset.name"] = filter.CreateFilter(mbc.ResourceAttributes.K8sReplicasetName.MetricsExclude) + } + if mbc.ResourceAttributes.K8sReplicasetUID.MetricsInclude != nil { + mb.resourceAttributeIncludeFilter["k8s.replicaset.uid"] = filter.CreateFilter(mbc.ResourceAttributes.K8sReplicasetUID.MetricsInclude) + } + if mbc.ResourceAttributes.K8sReplicasetUID.MetricsExclude != nil { + mb.resourceAttributeExcludeFilter["k8s.replicaset.uid"] = filter.CreateFilter(mbc.ResourceAttributes.K8sReplicasetUID.MetricsExclude) + } + + for _, op := range options { + op.apply(mb) + } + return mb +} + +// NewResourceBuilder returns a new resource builder that should be used to build a resource associated with for the emitted metrics. +func (mb *MetricsBuilder) NewResourceBuilder() *ResourceBuilder { + return NewResourceBuilder(mb.config.ResourceAttributes) +} + +// updateCapacity updates max length of metrics and resource attributes that will be used for the slice capacity. +func (mb *MetricsBuilder) updateCapacity(rm pmetric.ResourceMetrics) { + if mb.metricsCapacity < rm.ScopeMetrics().At(0).Metrics().Len() { + mb.metricsCapacity = rm.ScopeMetrics().At(0).Metrics().Len() + } +} + +// ResourceMetricsOption applies changes to provided resource metrics. +type ResourceMetricsOption interface { + apply(pmetric.ResourceMetrics) +} + +type resourceMetricsOptionFunc func(pmetric.ResourceMetrics) + +func (rmof resourceMetricsOptionFunc) apply(rm pmetric.ResourceMetrics) { + rmof(rm) +} + +// WithResource sets the provided resource on the emitted ResourceMetrics. +// It's recommended to use ResourceBuilder to create the resource. +func WithResource(res pcommon.Resource) ResourceMetricsOption { + return resourceMetricsOptionFunc(func(rm pmetric.ResourceMetrics) { + res.CopyTo(rm.Resource()) + }) +} + +func withResourceMoved(res pcommon.Resource) ResourceMetricsOption { + return resourceMetricsOptionFunc(func(rm pmetric.ResourceMetrics) { + res.MoveTo(rm.Resource()) + }) +} + +// WithStartTimeOverride overrides start time for all the resource metrics data points. +// This option should be only used if different start time has to be set on metrics coming from different resources. +func WithStartTimeOverride(start pcommon.Timestamp) ResourceMetricsOption { + return resourceMetricsOptionFunc(func(rm pmetric.ResourceMetrics) { + var dps pmetric.NumberDataPointSlice + metrics := rm.ScopeMetrics().At(0).Metrics() + for i := 0; i < metrics.Len(); i++ { + switch metrics.At(i).Type() { + case pmetric.MetricTypeGauge: + dps = metrics.At(i).Gauge().DataPoints() + case pmetric.MetricTypeSum: + dps = metrics.At(i).Sum().DataPoints() + } + for j := 0; j < dps.Len(); j++ { + dps.At(j).SetStartTimestamp(start) + } + } + }) +} + +// ForK8sReplicaset returns a K8sReplicasetMetricsBuilder that restricts metric recording +// to metrics belonging to the k8s.replicaset entity. +func (mb *MetricsBuilder) ForK8sReplicaset(e *K8sReplicasetEntity) *K8sReplicasetMetricsBuilder { + return &K8sReplicasetMetricsBuilder{mb: mb, entity: e} +} + +// ForK8sPod returns a K8sPodMetricsBuilder that restricts metric recording +// to metrics belonging to the k8s.pod entity. +func (mb *MetricsBuilder) ForK8sPod(e *K8sPodEntity) *K8sPodMetricsBuilder { + return &K8sPodMetricsBuilder{mb: mb, entity: e} +} + +// EmitForResource saves all the generated metrics under a new resource and updates the internal state to be ready for +// recording another set of data points as part of another resource. This function can be helpful when one scraper +// needs to emit metrics from several resources. Otherwise calling this function is not required, +// just `Emit` function can be called instead. +// Resource attributes should be provided as ResourceMetricsOption arguments. +// +// Deprecated: Use the For methods to get entity-scoped builders and call Emit() on them instead. +func (mb *MetricsBuilder) EmitForResource(options ...ResourceMetricsOption) { + rm := pmetric.NewResourceMetrics() + rm.SetSchemaUrl(conventions.SchemaURL) + ils := rm.ScopeMetrics().AppendEmpty() + ils.Scope().SetName(ScopeName) + ils.Scope().SetVersion(mb.buildInfo.Version) + ils.Metrics().EnsureCapacity(mb.metricsCapacity) + mb.metricK8sPodCPUTime.emit(ils.Metrics()) + mb.metricK8sPodPhase.emit(ils.Metrics()) + mb.metricK8sReplicasetDesired.emit(ils.Metrics()) + + for _, op := range options { + op.apply(rm) + } + for attr, filter := range mb.resourceAttributeIncludeFilter { + if val, ok := rm.Resource().Attributes().Get(attr); ok && !filter.Matches(val.AsString()) { + return + } + } + for attr, filter := range mb.resourceAttributeExcludeFilter { + if val, ok := rm.Resource().Attributes().Get(attr); ok && filter.Matches(val.AsString()) { + return + } + } + + if ils.Metrics().Len() > 0 { + mb.updateCapacity(rm) + rm.MoveTo(mb.metricsBuffer.ResourceMetrics().AppendEmpty()) + } +} + +// Emit returns all the metrics accumulated by the metrics builder and updates the internal state to be ready for +// recording another set of metrics. This function will be responsible for applying all the transformations required to +// produce metric representation defined in metadata and user config, e.g. delta or cumulative. +func (mb *MetricsBuilder) Emit(options ...ResourceMetricsOption) pmetric.Metrics { + mb.EmitForResource(options...) + metrics := mb.metricsBuffer + mb.metricsBuffer = pmetric.NewMetrics() + return metrics +} + +// RecordK8sPodCPUTimeDataPoint adds a data point to k8s.pod.cpu_time metric. +// +// Deprecated: Use mb.ForK8sPod(entity).RecordK8sPodCPUTimeDataPoint(...) instead. +func (mb *MetricsBuilder) RecordK8sPodCPUTimeDataPoint(ts pcommon.Timestamp, val float64) { + mb.metricK8sPodCPUTime.recordDataPoint(mb.startTime, ts, val) +} + +// RecordK8sPodPhaseDataPoint adds a data point to k8s.pod.phase metric. +// +// Deprecated: Use mb.ForK8sPod(entity).RecordK8sPodPhaseDataPoint(...) instead. +func (mb *MetricsBuilder) RecordK8sPodPhaseDataPoint(ts pcommon.Timestamp, val int64, phaseAttributeValue AttributePhase) { + mb.metricK8sPodPhase.recordDataPoint(mb.startTime, ts, val, phaseAttributeValue.String()) +} + +// RecordK8sReplicasetDesiredDataPoint adds a data point to k8s.replicaset.desired metric. +// +// Deprecated: Use mb.ForK8sReplicaset(entity).RecordK8sReplicasetDesiredDataPoint(...) instead. +func (mb *MetricsBuilder) RecordK8sReplicasetDesiredDataPoint(ts pcommon.Timestamp, val int64) { + mb.metricK8sReplicasetDesired.recordDataPoint(mb.startTime, ts, val) +} + +// Reset resets metrics builder to its initial state. It should be used when external metrics source is restarted, +// and metrics builder should update its startTime and reset it's internal state accordingly. +func (mb *MetricsBuilder) Reset(options ...MetricBuilderOption) { + mb.startTime = pcommon.NewTimestampFromTime(time.Now()) + for _, op := range options { + op.apply(mb) + } +} diff --git a/cmd/mdatagen/internal/sampleentityreceiver/internal/metadata/generated_metrics_test.go b/cmd/mdatagen/internal/sampleentityreceiver/internal/metadata/generated_metrics_test.go new file mode 100644 index 000000000000..fcb9f070164e --- /dev/null +++ b/cmd/mdatagen/internal/sampleentityreceiver/internal/metadata/generated_metrics_test.go @@ -0,0 +1,166 @@ +// Code generated by mdatagen. DO NOT EDIT. + +package metadata + +import ( + "testing" + + "github.com/stretchr/testify/assert" + "go.uber.org/zap" + "go.uber.org/zap/zaptest/observer" + + "go.opentelemetry.io/collector/pdata/pcommon" + "go.opentelemetry.io/collector/pdata/pmetric" + "go.opentelemetry.io/collector/receiver/receivertest" +) + +type testDataSet int + +const ( + testDataSetDefault testDataSet = iota + testDataSetAll + testDataSetNone +) + +func TestMetricsBuilder(t *testing.T) { + tests := []struct { + name string + metricsSet testDataSet + resAttrsSet testDataSet + expectEmpty bool + }{ + { + name: "default", + }, + { + name: "all_set", + metricsSet: testDataSetAll, + resAttrsSet: testDataSetAll, + }, + { + name: "none_set", + metricsSet: testDataSetNone, + resAttrsSet: testDataSetNone, + expectEmpty: true, + }, + { + name: "filter_set_include", + resAttrsSet: testDataSetAll, + }, + { + name: "filter_set_exclude", + resAttrsSet: testDataSetAll, + expectEmpty: true, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + start := pcommon.Timestamp(1_000_000_000) + ts := pcommon.Timestamp(1_000_001_000) + observedZapCore, observedLogs := observer.New(zap.WarnLevel) + settings := receivertest.NewNopSettings(receivertest.NopType) + settings.Logger = zap.New(observedZapCore) + mb := NewMetricsBuilder(loadMetricsBuilderConfig(t, tt.name), settings, WithStartTime(start)) + + expectedWarnings := 0 + assert.Equal(t, expectedWarnings, observedLogs.Len()) + + defaultMetricsCount := 0 + allMetricsCount := 0 + ebK8sReplicaset := mb.ForK8sReplicaset(NewK8sReplicasetEntity("k8s.replicaset.uid-val")) + ebK8sPod := mb.ForK8sPod(NewK8sPodEntity("k8s.pod.uid-val")) + + defaultMetricsCount++ + allMetricsCount++ + ebK8sPod.RecordK8sPodCPUTimeDataPoint(ts, 1) + + defaultMetricsCount++ + allMetricsCount++ + ebK8sPod.RecordK8sPodPhaseDataPoint(ts, 1, AttributePhasePending) + + defaultMetricsCount++ + allMetricsCount++ + ebK8sReplicaset.RecordK8sReplicasetDesiredDataPoint(ts, 1) + ebK8sReplicaset.Emit() + ebK8sPod.Emit() + + rb := mb.NewResourceBuilder() + rb.SetK8sNamespaceName("k8s.namespace.name-val") + rb.SetK8sPodName("k8s.pod.name-val") + rb.SetK8sPodUID("k8s.pod.uid-val") + rb.SetK8sReplicasetName("k8s.replicaset.name-val") + rb.SetK8sReplicasetUID("k8s.replicaset.uid-val") + res := rb.Emit() + metrics := mb.Emit(WithResource(res)) + + if tt.expectEmpty { + assert.Equal(t, 0, metrics.ResourceMetrics().Len()) + return + } + + var allMetricsList []pmetric.Metric + totalMetricsCount := 0 + for ri := 0; ri < metrics.ResourceMetrics().Len(); ri++ { + rm := metrics.ResourceMetrics().At(ri) + assert.Equal(t, 1, rm.ScopeMetrics().Len()) + ms := rm.ScopeMetrics().At(0).Metrics() + totalMetricsCount += ms.Len() + for mi := 0; mi < ms.Len(); mi++ { + allMetricsList = append(allMetricsList, ms.At(mi)) + } + } + if tt.metricsSet == testDataSetDefault { + assert.Equal(t, defaultMetricsCount, totalMetricsCount) + } + if tt.metricsSet == testDataSetAll { + assert.Equal(t, allMetricsCount, totalMetricsCount) + } + validatedMetrics := make(map[string]bool) + for _, mi := range allMetricsList { + switch mi.Name() { + case "k8s.pod.cpu_time": + assert.False(t, validatedMetrics["k8s.pod.cpu_time"], "Found a duplicate in the metrics slice: k8s.pod.cpu_time") + validatedMetrics["k8s.pod.cpu_time"] = true + assert.Equal(t, pmetric.MetricTypeSum, mi.Type()) + assert.Equal(t, 1, mi.Sum().DataPoints().Len()) + assert.Equal(t, "CPU time consumed by the pod", mi.Description()) + assert.Equal(t, "s", mi.Unit()) + assert.True(t, mi.Sum().IsMonotonic()) + assert.Equal(t, pmetric.AggregationTemporalityCumulative, mi.Sum().AggregationTemporality()) + dp := mi.Sum().DataPoints().At(0) + assert.Equal(t, start, dp.StartTimestamp()) + assert.Equal(t, ts, dp.Timestamp()) + assert.Equal(t, pmetric.NumberDataPointValueTypeDouble, dp.ValueType()) + assert.InDelta(t, float64(1), dp.DoubleValue(), 0.01) + case "k8s.pod.phase": + assert.False(t, validatedMetrics["k8s.pod.phase"], "Found a duplicate in the metrics slice: k8s.pod.phase") + validatedMetrics["k8s.pod.phase"] = true + assert.Equal(t, pmetric.MetricTypeGauge, mi.Type()) + assert.Equal(t, 1, mi.Gauge().DataPoints().Len()) + assert.Equal(t, "Current phase of the pod", mi.Description()) + assert.Equal(t, "1", mi.Unit()) + dp := mi.Gauge().DataPoints().At(0) + assert.Equal(t, start, dp.StartTimestamp()) + assert.Equal(t, ts, dp.Timestamp()) + assert.Equal(t, pmetric.NumberDataPointValueTypeInt, dp.ValueType()) + assert.Equal(t, int64(1), dp.IntValue()) + attrVal, ok := dp.Attributes().Get("phase") + assert.True(t, ok) + assert.Equal(t, "Pending", attrVal.Str()) + case "k8s.replicaset.desired": + assert.False(t, validatedMetrics["k8s.replicaset.desired"], "Found a duplicate in the metrics slice: k8s.replicaset.desired") + validatedMetrics["k8s.replicaset.desired"] = true + assert.Equal(t, pmetric.MetricTypeGauge, mi.Type()) + assert.Equal(t, 1, mi.Gauge().DataPoints().Len()) + assert.Equal(t, "Number of desired replicas", mi.Description()) + assert.Equal(t, "{replicas}", mi.Unit()) + dp := mi.Gauge().DataPoints().At(0) + assert.Equal(t, start, dp.StartTimestamp()) + assert.Equal(t, ts, dp.Timestamp()) + assert.Equal(t, pmetric.NumberDataPointValueTypeInt, dp.ValueType()) + assert.Equal(t, int64(1), dp.IntValue()) + } + } + }) + } +} diff --git a/cmd/mdatagen/internal/sampleentityreceiver/internal/metadata/generated_resource.go b/cmd/mdatagen/internal/sampleentityreceiver/internal/metadata/generated_resource.go new file mode 100644 index 000000000000..3ef542df678e --- /dev/null +++ b/cmd/mdatagen/internal/sampleentityreceiver/internal/metadata/generated_resource.go @@ -0,0 +1,64 @@ +// Code generated by mdatagen. DO NOT EDIT. + +package metadata + +import ( + "go.opentelemetry.io/collector/pdata/pcommon" +) + +// ResourceBuilder is a helper struct to build resources predefined in metadata.yaml. +// The ResourceBuilder is not thread-safe and must not to be used in multiple goroutines. +type ResourceBuilder struct { + config ResourceAttributesConfig + res pcommon.Resource +} + +// NewResourceBuilder creates a new ResourceBuilder. This method should be called on the start of the application. +func NewResourceBuilder(rac ResourceAttributesConfig) *ResourceBuilder { + return &ResourceBuilder{ + config: rac, + res: pcommon.NewResource(), + } +} + +// SetK8sNamespaceName sets provided value as "k8s.namespace.name" attribute. +func (rb *ResourceBuilder) SetK8sNamespaceName(val string) { + if rb.config.K8sNamespaceName.Enabled { + rb.res.Attributes().PutStr("k8s.namespace.name", val) + } +} + +// SetK8sPodName sets provided value as "k8s.pod.name" attribute. +func (rb *ResourceBuilder) SetK8sPodName(val string) { + if rb.config.K8sPodName.Enabled { + rb.res.Attributes().PutStr("k8s.pod.name", val) + } +} + +// SetK8sPodUID sets provided value as "k8s.pod.uid" attribute. +func (rb *ResourceBuilder) SetK8sPodUID(val string) { + if rb.config.K8sPodUID.Enabled { + rb.res.Attributes().PutStr("k8s.pod.uid", val) + } +} + +// SetK8sReplicasetName sets provided value as "k8s.replicaset.name" attribute. +func (rb *ResourceBuilder) SetK8sReplicasetName(val string) { + if rb.config.K8sReplicasetName.Enabled { + rb.res.Attributes().PutStr("k8s.replicaset.name", val) + } +} + +// SetK8sReplicasetUID sets provided value as "k8s.replicaset.uid" attribute. +func (rb *ResourceBuilder) SetK8sReplicasetUID(val string) { + if rb.config.K8sReplicasetUID.Enabled { + rb.res.Attributes().PutStr("k8s.replicaset.uid", val) + } +} + +// Emit returns the built resource and resets the internal builder state. +func (rb *ResourceBuilder) Emit() pcommon.Resource { + r := rb.res + rb.res = pcommon.NewResource() + return r +} diff --git a/cmd/mdatagen/internal/sampleentityreceiver/internal/metadata/generated_resource_test.go b/cmd/mdatagen/internal/sampleentityreceiver/internal/metadata/generated_resource_test.go new file mode 100644 index 000000000000..a4ebd740f7b1 --- /dev/null +++ b/cmd/mdatagen/internal/sampleentityreceiver/internal/metadata/generated_resource_test.go @@ -0,0 +1,64 @@ +// Code generated by mdatagen. DO NOT EDIT. + +package metadata + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestResourceBuilder(t *testing.T) { + for _, tt := range []string{"default", "all_set", "none_set"} { + t.Run(tt, func(t *testing.T) { + cfg := loadResourceAttributesConfig(t, tt) + rb := NewResourceBuilder(cfg) + rb.SetK8sNamespaceName("k8s.namespace.name-val") + rb.SetK8sPodName("k8s.pod.name-val") + rb.SetK8sPodUID("k8s.pod.uid-val") + rb.SetK8sReplicasetName("k8s.replicaset.name-val") + rb.SetK8sReplicasetUID("k8s.replicaset.uid-val") + + res := rb.Emit() + assert.Equal(t, 0, rb.Emit().Attributes().Len()) // Second call should return empty Resource + + switch tt { + case "default": + assert.Equal(t, 5, res.Attributes().Len()) + case "all_set": + assert.Equal(t, 5, res.Attributes().Len()) + case "none_set": + assert.Equal(t, 0, res.Attributes().Len()) + return + default: + assert.Failf(t, "unexpected test case: %s", tt) + } + + val, ok := res.Attributes().Get("k8s.namespace.name") + assert.True(t, ok) + if ok { + assert.Equal(t, "k8s.namespace.name-val", val.Str()) + } + val, ok = res.Attributes().Get("k8s.pod.name") + assert.True(t, ok) + if ok { + assert.Equal(t, "k8s.pod.name-val", val.Str()) + } + val, ok = res.Attributes().Get("k8s.pod.uid") + assert.True(t, ok) + if ok { + assert.Equal(t, "k8s.pod.uid-val", val.Str()) + } + val, ok = res.Attributes().Get("k8s.replicaset.name") + assert.True(t, ok) + if ok { + assert.Equal(t, "k8s.replicaset.name-val", val.Str()) + } + val, ok = res.Attributes().Get("k8s.replicaset.uid") + assert.True(t, ok) + if ok { + assert.Equal(t, "k8s.replicaset.uid-val", val.Str()) + } + }) + } +} diff --git a/cmd/mdatagen/internal/sampleentityreceiver/internal/metadata/generated_status.go b/cmd/mdatagen/internal/sampleentityreceiver/internal/metadata/generated_status.go new file mode 100644 index 000000000000..8e37382858c4 --- /dev/null +++ b/cmd/mdatagen/internal/sampleentityreceiver/internal/metadata/generated_status.go @@ -0,0 +1,16 @@ +// Code generated by mdatagen. DO NOT EDIT. + +package metadata + +import ( + "go.opentelemetry.io/collector/component" +) + +var ( + Type = component.MustNewType("sampleentity") + ScopeName = "go.opentelemetry.io/collector/internal/receiver/sampleentityreceiver" +) + +const ( + MetricsStability = component.StabilityLevelDevelopment +) diff --git a/cmd/mdatagen/internal/sampleentityreceiver/internal/metadata/testdata/config.yaml b/cmd/mdatagen/internal/sampleentityreceiver/internal/metadata/testdata/config.yaml new file mode 100644 index 000000000000..1d944f190ede --- /dev/null +++ b/cmd/mdatagen/internal/sampleentityreceiver/internal/metadata/testdata/config.yaml @@ -0,0 +1,83 @@ +default: +all_set: + metrics: + k8s.pod.cpu_time: + enabled: true + k8s.pod.phase: + enabled: true + k8s.replicaset.desired: + enabled: true + resource_attributes: + k8s.namespace.name: + enabled: true + k8s.pod.name: + enabled: true + k8s.pod.uid: + enabled: true + k8s.replicaset.name: + enabled: true + k8s.replicaset.uid: + enabled: true +none_set: + metrics: + k8s.pod.cpu_time: + enabled: false + k8s.pod.phase: + enabled: false + k8s.replicaset.desired: + enabled: false + resource_attributes: + k8s.namespace.name: + enabled: false + k8s.pod.name: + enabled: false + k8s.pod.uid: + enabled: false + k8s.replicaset.name: + enabled: false + k8s.replicaset.uid: + enabled: false +filter_set_include: + resource_attributes: + k8s.namespace.name: + enabled: true + metrics_include: + - regexp: ".*" + k8s.pod.name: + enabled: true + metrics_include: + - regexp: ".*" + k8s.pod.uid: + enabled: true + metrics_include: + - regexp: ".*" + k8s.replicaset.name: + enabled: true + metrics_include: + - regexp: ".*" + k8s.replicaset.uid: + enabled: true + metrics_include: + - regexp: ".*" +filter_set_exclude: + resource_attributes: + k8s.namespace.name: + enabled: true + metrics_exclude: + - strict: "k8s.namespace.name-val" + k8s.pod.name: + enabled: true + metrics_exclude: + - strict: "k8s.pod.name-val" + k8s.pod.uid: + enabled: true + metrics_exclude: + - strict: "k8s.pod.uid-val" + k8s.replicaset.name: + enabled: true + metrics_exclude: + - strict: "k8s.replicaset.name-val" + k8s.replicaset.uid: + enabled: true + metrics_exclude: + - strict: "k8s.replicaset.uid-val" diff --git a/cmd/mdatagen/internal/sampleentityreceiver/metadata.yaml b/cmd/mdatagen/internal/sampleentityreceiver/metadata.yaml new file mode 100644 index 000000000000..ce3610f81f36 --- /dev/null +++ b/cmd/mdatagen/internal/sampleentityreceiver/metadata.yaml @@ -0,0 +1,101 @@ +# Sample metadata file with entities for testing entity-based builder API + +type: sampleentity +display_name: Sample Entity Receiver +description: This receiver demonstrates entity-based metrics builder API. +scope_name: go.opentelemetry.io/collector/internal/receiver/sampleentityreceiver +sem_conv_version: 1.38.0 + +status: + class: receiver + stability: + development: [metrics] + codeowners: + active: [dmitryax] + +resource_attributes: + k8s.namespace.name: + description: The name of the Kubernetes Namespace + type: string + enabled: true + + k8s.pod.name: + description: The name of the Kubernetes Pod + type: string + enabled: true + + k8s.pod.uid: + description: The UID of the Kubernetes Pod + type: string + enabled: true + + k8s.replicaset.name: + description: The name of the Kubernetes ReplicaSet + type: string + enabled: true + + k8s.replicaset.uid: + description: The UID of the Kubernetes ReplicaSet + type: string + enabled: true + +entities: + - type: k8s.replicaset + brief: A Kubernetes ReplicaSet + stability: development + identity: + - ref: k8s.replicaset.uid + description: + - ref: k8s.replicaset.name + + - type: k8s.pod + brief: A Kubernetes Pod + stability: development + identity: + - ref: k8s.pod.uid + description: + - ref: k8s.pod.name + extra_attributes: + - ref: k8s.namespace.name + relationships: + - type: controlled_by + target: k8s.replicaset + +attributes: + phase: + description: The phase of the pod (Pending, Running, Succeeded, Failed, Unknown) + type: string + enum: [Pending, Running, Succeeded, Failed, Unknown] + +metrics: + k8s.pod.cpu_time: + enabled: true + description: CPU time consumed by the pod + unit: s + sum: + value_type: double + monotonic: true + aggregation_temporality: cumulative + attributes: [] + entity: k8s.pod + stability: development + + k8s.pod.phase: + enabled: true + description: Current phase of the pod + unit: "1" + gauge: + value_type: int + attributes: [phase] + entity: k8s.pod + stability: development + + k8s.replicaset.desired: + enabled: true + description: Number of desired replicas + unit: "{replicas}" + gauge: + value_type: int + attributes: [] + entity: k8s.replicaset + stability: development diff --git a/cmd/mdatagen/internal/samplefactoryreceiver/README.md b/cmd/mdatagen/internal/samplefactoryreceiver/README.md index 6a12429d7cff..349ad9f4449b 100644 --- a/cmd/mdatagen/internal/samplefactoryreceiver/README.md +++ b/cmd/mdatagen/internal/samplefactoryreceiver/README.md @@ -1,6 +1,8 @@ -# Sample Receiver -This receiver is used for testing purposes to check the output of mdatagen. +# Sample Factory Receiver + +This receiver is used for testing purposes to check the output of mdatagen. + | Status | | | ------------- |-----------| | Stability | [deprecated]: profiles | diff --git a/cmd/mdatagen/internal/samplefactoryreceiver/factory.go b/cmd/mdatagen/internal/samplefactoryreceiver/factory.go index a3cba05934d2..739b2fae6f27 100644 --- a/cmd/mdatagen/internal/samplefactoryreceiver/factory.go +++ b/cmd/mdatagen/internal/samplefactoryreceiver/factory.go @@ -12,18 +12,22 @@ import ( "go.opentelemetry.io/collector/cmd/mdatagen/internal/samplefactoryreceiver/internal/metadata" "go.opentelemetry.io/collector/component" "go.opentelemetry.io/collector/consumer" + "go.opentelemetry.io/collector/consumer/xconsumer" "go.opentelemetry.io/collector/receiver" + "go.opentelemetry.io/collector/receiver/xreceiver" "go.opentelemetry.io/collector/service/hostcapabilities" ) // NewFactory returns a receiver.Factory for sample receiver. -func NewFactory() receiver.Factory { - return receiver.NewFactory( +func NewFactory() xreceiver.Factory { + return xreceiver.NewFactory( metadata.Type, func() component.Config { return &struct{}{} }, - receiver.WithTraces(createTraces, metadata.TracesStability), - receiver.WithMetrics(createMetrics, metadata.MetricsStability), - receiver.WithLogs(createLogs, metadata.LogsStability)) + xreceiver.WithTraces(createTraces, metadata.TracesStability), + xreceiver.WithMetrics(createMetrics, metadata.MetricsStability), + xreceiver.WithLogs(createLogs, metadata.LogsStability), + xreceiver.WithProfiles(createProfiles, metadata.ProfilesStability), + ) } func createTraces(context.Context, receiver.Settings, component.Config, consumer.Traces) (receiver.Traces, error) { @@ -51,6 +55,10 @@ func createLogs(context.Context, receiver.Settings, component.Config, consumer.L return nopInstance, nil } +func createProfiles(context.Context, receiver.Settings, component.Config, xconsumer.Profiles) (xreceiver.Profiles, error) { + return nopInstance, nil +} + var nopInstance = &nopReceiver{} type nopReceiver struct { diff --git a/cmd/mdatagen/internal/samplefactoryreceiver/generated_component_test.go b/cmd/mdatagen/internal/samplefactoryreceiver/generated_component_test.go index 38cf1def51ea..7c4738b79f12 100644 --- a/cmd/mdatagen/internal/samplefactoryreceiver/generated_component_test.go +++ b/cmd/mdatagen/internal/samplefactoryreceiver/generated_component_test.go @@ -15,6 +15,7 @@ import ( "go.opentelemetry.io/collector/consumer/consumertest" "go.opentelemetry.io/collector/receiver" "go.opentelemetry.io/collector/receiver/receivertest" + "go.opentelemetry.io/collector/receiver/xreceiver" ) var typ = component.MustNewType("sample") @@ -55,6 +56,13 @@ func TestComponentLifecycle(t *testing.T) { return factory.CreateTraces(ctx, set, cfg, consumertest.NewNop()) }, }, + + { + name: "profiles", + createFn: func(ctx context.Context, set receiver.Settings, cfg component.Config) (component.Component, error) { + return factory.(xreceiver.Factory).CreateProfiles(ctx, set, cfg, consumertest.NewNop()) + }, + }, } cm, err := confmaptest.LoadConf("metadata.yaml") diff --git a/cmd/mdatagen/internal/samplefactoryreceiver/metadata.yaml b/cmd/mdatagen/internal/samplefactoryreceiver/metadata.yaml index a64cd97fd72f..7c8679e679bb 100644 --- a/cmd/mdatagen/internal/samplefactoryreceiver/metadata.yaml +++ b/cmd/mdatagen/internal/samplefactoryreceiver/metadata.yaml @@ -1,6 +1,8 @@ # Sample metadata file with all available configurations for a receiver. type: sample +display_name: Sample Factory Receiver +description: This receiver is used for testing purposes to check the output of mdatagen. scope_name: go.opentelemetry.io/collector/internal/receiver/samplefactoryreceiver github_project: open-telemetry/opentelemetry-collector diff --git a/cmd/mdatagen/internal/sampleprocessor/README.md b/cmd/mdatagen/internal/sampleprocessor/README.md index 48c23b1e51b2..bd8916b8faf9 100644 --- a/cmd/mdatagen/internal/sampleprocessor/README.md +++ b/cmd/mdatagen/internal/sampleprocessor/README.md @@ -1,9 +1,11 @@ + # Sample Processor + This processor is used for testing purposes to check the output of mdatagen. - + | Status | | | ------------- |-----------| -| Stability | [development]: logs | +| Stability | [development]: logs, profiles | | | [beta]: traces | | | [stable]: metrics | | Unsupported Platforms | freebsd, illumos | diff --git a/cmd/mdatagen/internal/sampleprocessor/factory.go b/cmd/mdatagen/internal/sampleprocessor/factory.go index a6f2814b3dd0..998c24a7eb64 100644 --- a/cmd/mdatagen/internal/sampleprocessor/factory.go +++ b/cmd/mdatagen/internal/sampleprocessor/factory.go @@ -9,20 +9,25 @@ import ( "go.opentelemetry.io/collector/cmd/mdatagen/internal/sampleprocessor/internal/metadata" "go.opentelemetry.io/collector/component" "go.opentelemetry.io/collector/consumer" + "go.opentelemetry.io/collector/consumer/xconsumer" "go.opentelemetry.io/collector/pdata/plog" "go.opentelemetry.io/collector/pdata/pmetric" + "go.opentelemetry.io/collector/pdata/pprofile" "go.opentelemetry.io/collector/pdata/ptrace" "go.opentelemetry.io/collector/processor" + "go.opentelemetry.io/collector/processor/xprocessor" ) // NewFactory returns a receiver.Factory for sample receiver. func NewFactory() processor.Factory { - return processor.NewFactory( + return xprocessor.NewFactory( metadata.Type, func() component.Config { return &struct{}{} }, - processor.WithTraces(createTracesProcessor, metadata.TracesStability), - processor.WithMetrics(createMetricsProcessor, metadata.MetricsStability), - processor.WithLogs(createLogsProcessor, metadata.LogsStability)) + xprocessor.WithTraces(createTracesProcessor, metadata.TracesStability), + xprocessor.WithMetrics(createMetricsProcessor, metadata.MetricsStability), + xprocessor.WithLogs(createLogsProcessor, metadata.LogsStability), + xprocessor.WithProfiles(createProfilesProcessor, metadata.ProfilesStability), + ) } func createTracesProcessor(context.Context, processor.Settings, component.Config, consumer.Traces) (processor.Traces, error) { @@ -37,6 +42,10 @@ func createLogsProcessor(context.Context, processor.Settings, component.Config, return nopInstance, nil } +func createProfilesProcessor(context.Context, processor.Settings, component.Config, xconsumer.Profiles) (xprocessor.Profiles, error) { + return nopInstance, nil +} + var nopInstance = &nopProcessor{} type nopProcessor struct { @@ -59,3 +68,7 @@ func (n nopProcessor) Capabilities() consumer.Capabilities { func (n nopProcessor) ConsumeMetrics(context.Context, pmetric.Metrics) error { return nil } + +func (n nopProcessor) ConsumeProfiles(context.Context, pprofile.Profiles) error { + return nil +} diff --git a/cmd/mdatagen/internal/sampleprocessor/generated_component_test.go b/cmd/mdatagen/internal/sampleprocessor/generated_component_test.go index 26bf0ad844a8..56889a5bef99 100644 --- a/cmd/mdatagen/internal/sampleprocessor/generated_component_test.go +++ b/cmd/mdatagen/internal/sampleprocessor/generated_component_test.go @@ -20,6 +20,7 @@ import ( "go.opentelemetry.io/collector/pdata/ptrace" "go.opentelemetry.io/collector/processor" "go.opentelemetry.io/collector/processor/processortest" + "go.opentelemetry.io/collector/processor/xprocessor" ) var typ = component.MustNewType("sample") @@ -60,6 +61,13 @@ func TestComponentLifecycle(t *testing.T) { return factory.CreateTraces(ctx, set, cfg, consumertest.NewNop()) }, }, + + { + name: "profiles", + createFn: func(ctx context.Context, set processor.Settings, cfg component.Config) (component.Component, error) { + return factory.(xprocessor.Factory).CreateProfiles(ctx, set, cfg, consumertest.NewNop()) + }, + }, } cm, err := confmaptest.LoadConf("metadata.yaml") diff --git a/cmd/mdatagen/internal/sampleprocessor/internal/metadata/config.schema.yaml b/cmd/mdatagen/internal/sampleprocessor/internal/metadata/config.schema.yaml new file mode 100644 index 000000000000..33ddf9990d3f --- /dev/null +++ b/cmd/mdatagen/internal/sampleprocessor/internal/metadata/config.schema.yaml @@ -0,0 +1,62 @@ +# Code generated by mdatagen. DO NOT EDIT. +$defs: + resource_attributes_config: + description: ResourceAttributesConfig provides config for sample resource attributes. + type: object + properties: + map.resource.attr: + description: ResourceAttributeConfig provides common config for a map.resource.attr resource attribute. + type: object + properties: + enabled: + type: boolean + default: true + optional.resource.attr: + description: ResourceAttributeConfig provides common config for a optional.resource.attr resource attribute. + type: object + properties: + enabled: + type: boolean + default: false + slice.resource.attr: + description: ResourceAttributeConfig provides common config for a slice.resource.attr resource attribute. + type: object + properties: + enabled: + type: boolean + default: true + string.enum.resource.attr: + description: ResourceAttributeConfig provides common config for a string.enum.resource.attr resource attribute. + type: object + properties: + enabled: + type: boolean + default: true + string.resource.attr: + description: ResourceAttributeConfig provides common config for a string.resource.attr resource attribute. + type: object + properties: + enabled: + type: boolean + default: true + string.resource.attr_disable_warning: + description: ResourceAttributeConfig provides common config for a string.resource.attr_disable_warning resource attribute. + type: object + properties: + enabled: + type: boolean + default: true + string.resource.attr_remove_warning: + description: ResourceAttributeConfig provides common config for a string.resource.attr_remove_warning resource attribute. + type: object + properties: + enabled: + type: boolean + default: false + string.resource.attr_to_be_removed: + description: ResourceAttributeConfig provides common config for a string.resource.attr_to_be_removed resource attribute. + type: object + properties: + enabled: + type: boolean + default: true diff --git a/cmd/mdatagen/internal/sampleprocessor/internal/metadata/generated_status.go b/cmd/mdatagen/internal/sampleprocessor/internal/metadata/generated_status.go index 7f86f1d8fc13..b1546b29c05f 100644 --- a/cmd/mdatagen/internal/sampleprocessor/internal/metadata/generated_status.go +++ b/cmd/mdatagen/internal/sampleprocessor/internal/metadata/generated_status.go @@ -12,7 +12,8 @@ var ( ) const ( - LogsStability = component.StabilityLevelDevelopment - TracesStability = component.StabilityLevelBeta - MetricsStability = component.StabilityLevelStable + LogsStability = component.StabilityLevelDevelopment + ProfilesStability = component.StabilityLevelDevelopment + TracesStability = component.StabilityLevelBeta + MetricsStability = component.StabilityLevelStable ) diff --git a/cmd/mdatagen/internal/sampleprocessor/internal/metadata/testdata/config.yaml b/cmd/mdatagen/internal/sampleprocessor/internal/metadata/testdata/config.yaml index bcc1a519f602..8ae9f4dcd166 100644 --- a/cmd/mdatagen/internal/sampleprocessor/internal/metadata/testdata/config.yaml +++ b/cmd/mdatagen/internal/sampleprocessor/internal/metadata/testdata/config.yaml @@ -17,6 +17,24 @@ all_set: enabled: true string.resource.attr_to_be_removed: enabled: true +reaggregate_set: + resource_attributes: + map.resource.attr: + enabled: true + optional.resource.attr: + enabled: true + slice.resource.attr: + enabled: true + string.enum.resource.attr: + enabled: true + string.resource.attr: + enabled: true + string.resource.attr_disable_warning: + enabled: true + string.resource.attr_remove_warning: + enabled: true + string.resource.attr_to_be_removed: + enabled: true none_set: resource_attributes: map.resource.attr: diff --git a/cmd/mdatagen/internal/sampleprocessor/metadata.yaml b/cmd/mdatagen/internal/sampleprocessor/metadata.yaml index ce7f738c0f6f..c4b7e3a24d29 100644 --- a/cmd/mdatagen/internal/sampleprocessor/metadata.yaml +++ b/cmd/mdatagen/internal/sampleprocessor/metadata.yaml @@ -1,6 +1,9 @@ -# Sample metadata file with all available configurations for a receiver. +# Sample metadata file with all available configurations for a processor. type: sample +display_name: Sample Processor +description: This processor is used for testing purposes to check the output of mdatagen. +reaggregation_enabled: true scope_name: go.opentelemetry.io/collector/internal/receiver/samplereceiver github_project: open-telemetry/opentelemetry-collector @@ -10,7 +13,7 @@ status: disable_codecov_badge: true class: processor stability: - development: [logs] + development: [logs, profiles] beta: [traces] stable: [metrics] distributions: [] diff --git a/cmd/mdatagen/internal/samplereceiver/README.md b/cmd/mdatagen/internal/samplereceiver/README.md index 70549c2036d3..fc299a43fb7c 100644 --- a/cmd/mdatagen/internal/samplereceiver/README.md +++ b/cmd/mdatagen/internal/samplereceiver/README.md @@ -1,6 +1,8 @@ + # Sample Receiver + This receiver is used for testing purposes to check the output of mdatagen. - + | Status | | | ------------- |-----------| | Stability | [deprecated]: profiles | diff --git a/cmd/mdatagen/internal/samplereceiver/config.schema.json b/cmd/mdatagen/internal/samplereceiver/config.schema.json new file mode 100644 index 000000000000..7a75f8e81e38 --- /dev/null +++ b/cmd/mdatagen/internal/samplereceiver/config.schema.json @@ -0,0 +1,881 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "go.opentelemetry.io/collector/cmd/mdatagen/internal/samplereceiver", + "title": "receiver/sample", + "type": "object", + "allOf": [ + { + "description": "MetricsBuilderConfig is a configuration for sample metrics builder.", + "type": "object", + "properties": { + "metrics": { + "description": "MetricsConfig provides config for sample metrics.", + "type": "object", + "properties": { + "default.metric": { + "description": "DefaultMetricMetricConfig provides config for the default.metric metric.", + "type": "object", + "properties": { + "aggregation_strategy": { + "type": "string", + "default": "sum", + "enum": [ + "sum", + "avg", + "min", + "max" + ] + }, + "attributes": { + "type": "array", + "default": [ + "string_attr", + "state", + "enum_attr", + "slice_attr", + "map_attr", + "conditional_int_attr", + "conditional_string_attr" + ], + "items": { + "type": "string", + "enum": [ + "string_attr", + "state", + "enum_attr", + "slice_attr", + "map_attr", + "conditional_int_attr", + "conditional_string_attr", + "opt_in_bool_attr" + ] + } + }, + "enabled": { + "type": "boolean", + "default": true + } + } + }, + "default.metric.to_be_removed": { + "description": "DefaultMetricToBeRemovedMetricConfig provides config for the default.metric.to_be_removed metric.", + "type": "object", + "properties": { + "enabled": { + "type": "boolean", + "default": true + } + } + }, + "metric.input_type": { + "description": "MetricInputTypeMetricConfig provides config for the metric.input_type metric.", + "type": "object", + "properties": { + "aggregation_strategy": { + "type": "string", + "default": "sum", + "enum": [ + "sum", + "avg", + "min", + "max" + ] + }, + "attributes": { + "type": "array", + "default": [ + "string_attr", + "state", + "enum_attr", + "slice_attr", + "map_attr" + ], + "items": { + "type": "string", + "enum": [ + "string_attr", + "state", + "enum_attr", + "slice_attr", + "map_attr" + ] + } + }, + "enabled": { + "type": "boolean", + "default": true + } + } + }, + "optional.metric": { + "description": "OptionalMetricMetricConfig provides config for the optional.metric metric.", + "type": "object", + "properties": { + "aggregation_strategy": { + "type": "string", + "default": "avg", + "enum": [ + "sum", + "avg", + "min", + "max" + ] + }, + "attributes": { + "type": "array", + "default": [ + "string_attr", + "boolean_attr", + "boolean_attr2", + "conditional_string_attr" + ], + "items": { + "type": "string", + "enum": [ + "string_attr", + "boolean_attr", + "boolean_attr2", + "conditional_string_attr" + ] + } + }, + "enabled": { + "type": "boolean", + "default": false + } + } + }, + "optional.metric.empty_unit": { + "description": "OptionalMetricEmptyUnitMetricConfig provides config for the optional.metric.empty_unit metric.", + "type": "object", + "properties": { + "aggregation_strategy": { + "type": "string", + "default": "avg", + "enum": [ + "sum", + "avg", + "min", + "max" + ] + }, + "attributes": { + "type": "array", + "default": [ + "string_attr", + "boolean_attr" + ], + "items": { + "type": "string", + "enum": [ + "string_attr", + "boolean_attr" + ] + } + }, + "enabled": { + "type": "boolean", + "default": false + } + } + }, + "reaggregate.metric": { + "description": "ReaggregateMetricMetricConfig provides config for the reaggregate.metric metric.", + "type": "object", + "properties": { + "aggregation_strategy": { + "type": "string", + "default": "avg", + "enum": [ + "sum", + "avg", + "min", + "max" + ] + }, + "attributes": { + "type": "array", + "default": [ + "string_attr", + "boolean_attr" + ], + "items": { + "type": "string", + "enum": [ + "string_attr", + "boolean_attr" + ] + } + }, + "enabled": { + "type": "boolean", + "default": true + } + } + }, + "reaggregate.metric.with_required": { + "description": "ReaggregateMetricWithRequiredMetricConfig provides config for the reaggregate.metric.with_required metric.", + "type": "object", + "properties": { + "aggregation_strategy": { + "type": "string", + "default": "avg", + "enum": [ + "sum", + "avg", + "min", + "max" + ] + }, + "attributes": { + "type": "array", + "default": [ + "required_string_attr", + "string_attr", + "boolean_attr" + ], + "items": { + "type": "string", + "enum": [ + "required_string_attr", + "string_attr", + "boolean_attr" + ] + } + }, + "enabled": { + "type": "boolean", + "default": true + } + } + }, + "system.cpu.time": { + "description": "SystemCPUTimeMetricConfig provides config for the system.cpu.time metric.", + "type": "object", + "properties": { + "enabled": { + "type": "boolean", + "default": true + } + } + } + } + }, + "resource_attributes": { + "description": "ResourceAttributesConfig provides config for sample resource attributes.", + "type": "object", + "properties": { + "map.resource.attr": { + "description": "ResourceAttributeConfig provides common config for a map.resource.attr resource attribute.", + "type": "object", + "properties": { + "enabled": { + "type": "boolean", + "default": true + }, + "events_exclude": { + "description": "Experimental: EventsExclude defines a list of filters for attribute values. If the list is not empty, events with matching resource attribute values will not be emitted. EventsInclude has higher priority than EventsExclude.", + "type": "array", + "items": { + "description": "Config configures the matching behavior of a Filter.", + "type": "object", + "properties": { + "regexp": { + "type": "string" + }, + "strict": { + "type": "string" + } + } + } + }, + "events_include": { + "description": "Experimental: EventsInclude defines a list of filters for attribute values. If the list is not empty, only events with matching resource attribute values will be emitted.", + "type": "array", + "items": { + "description": "Config configures the matching behavior of a Filter.", + "type": "object", + "properties": { + "regexp": { + "type": "string" + }, + "strict": { + "type": "string" + } + } + } + }, + "metrics_exclude": { + "description": "Experimental: MetricsExclude defines a list of filters for attribute values. If the list is not empty, metrics with matching resource attribute values will not be emitted. MetricsInclude has higher priority than MetricsExclude.", + "type": "array", + "items": { + "description": "Config configures the matching behavior of a Filter.", + "type": "object", + "properties": { + "regexp": { + "type": "string" + }, + "strict": { + "type": "string" + } + } + } + }, + "metrics_include": { + "description": "Experimental: MetricsInclude defines a list of filters for attribute values. If the list is not empty, only metrics with matching resource attribute values will be emitted.", + "type": "array", + "items": { + "description": "Config configures the matching behavior of a Filter.", + "type": "object", + "properties": { + "regexp": { + "type": "string" + }, + "strict": { + "type": "string" + } + } + } + } + } + }, + "optional.resource.attr": { + "description": "ResourceAttributeConfig provides common config for a optional.resource.attr resource attribute.", + "type": "object", + "properties": { + "enabled": { + "type": "boolean", + "default": false + }, + "events_exclude": { + "description": "Experimental: EventsExclude defines a list of filters for attribute values. If the list is not empty, events with matching resource attribute values will not be emitted. EventsInclude has higher priority than EventsExclude.", + "type": "array", + "items": { + "description": "Config configures the matching behavior of a Filter.", + "type": "object", + "properties": { + "regexp": { + "type": "string" + }, + "strict": { + "type": "string" + } + } + } + }, + "events_include": { + "description": "Experimental: EventsInclude defines a list of filters for attribute values. If the list is not empty, only events with matching resource attribute values will be emitted.", + "type": "array", + "items": { + "description": "Config configures the matching behavior of a Filter.", + "type": "object", + "properties": { + "regexp": { + "type": "string" + }, + "strict": { + "type": "string" + } + } + } + }, + "metrics_exclude": { + "description": "Experimental: MetricsExclude defines a list of filters for attribute values. If the list is not empty, metrics with matching resource attribute values will not be emitted. MetricsInclude has higher priority than MetricsExclude.", + "type": "array", + "items": { + "description": "Config configures the matching behavior of a Filter.", + "type": "object", + "properties": { + "regexp": { + "type": "string" + }, + "strict": { + "type": "string" + } + } + } + }, + "metrics_include": { + "description": "Experimental: MetricsInclude defines a list of filters for attribute values. If the list is not empty, only metrics with matching resource attribute values will be emitted.", + "type": "array", + "items": { + "description": "Config configures the matching behavior of a Filter.", + "type": "object", + "properties": { + "regexp": { + "type": "string" + }, + "strict": { + "type": "string" + } + } + } + } + } + }, + "slice.resource.attr": { + "description": "ResourceAttributeConfig provides common config for a slice.resource.attr resource attribute.", + "type": "object", + "properties": { + "enabled": { + "type": "boolean", + "default": true + }, + "events_exclude": { + "description": "Experimental: EventsExclude defines a list of filters for attribute values. If the list is not empty, events with matching resource attribute values will not be emitted. EventsInclude has higher priority than EventsExclude.", + "type": "array", + "items": { + "description": "Config configures the matching behavior of a Filter.", + "type": "object", + "properties": { + "regexp": { + "type": "string" + }, + "strict": { + "type": "string" + } + } + } + }, + "events_include": { + "description": "Experimental: EventsInclude defines a list of filters for attribute values. If the list is not empty, only events with matching resource attribute values will be emitted.", + "type": "array", + "items": { + "description": "Config configures the matching behavior of a Filter.", + "type": "object", + "properties": { + "regexp": { + "type": "string" + }, + "strict": { + "type": "string" + } + } + } + }, + "metrics_exclude": { + "description": "Experimental: MetricsExclude defines a list of filters for attribute values. If the list is not empty, metrics with matching resource attribute values will not be emitted. MetricsInclude has higher priority than MetricsExclude.", + "type": "array", + "items": { + "description": "Config configures the matching behavior of a Filter.", + "type": "object", + "properties": { + "regexp": { + "type": "string" + }, + "strict": { + "type": "string" + } + } + } + }, + "metrics_include": { + "description": "Experimental: MetricsInclude defines a list of filters for attribute values. If the list is not empty, only metrics with matching resource attribute values will be emitted.", + "type": "array", + "items": { + "description": "Config configures the matching behavior of a Filter.", + "type": "object", + "properties": { + "regexp": { + "type": "string" + }, + "strict": { + "type": "string" + } + } + } + } + } + }, + "string.enum.resource.attr": { + "description": "ResourceAttributeConfig provides common config for a string.enum.resource.attr resource attribute.", + "type": "object", + "properties": { + "enabled": { + "type": "boolean", + "default": true + }, + "events_exclude": { + "description": "Experimental: EventsExclude defines a list of filters for attribute values. If the list is not empty, events with matching resource attribute values will not be emitted. EventsInclude has higher priority than EventsExclude.", + "type": "array", + "items": { + "description": "Config configures the matching behavior of a Filter.", + "type": "object", + "properties": { + "regexp": { + "type": "string" + }, + "strict": { + "type": "string" + } + } + } + }, + "events_include": { + "description": "Experimental: EventsInclude defines a list of filters for attribute values. If the list is not empty, only events with matching resource attribute values will be emitted.", + "type": "array", + "items": { + "description": "Config configures the matching behavior of a Filter.", + "type": "object", + "properties": { + "regexp": { + "type": "string" + }, + "strict": { + "type": "string" + } + } + } + }, + "metrics_exclude": { + "description": "Experimental: MetricsExclude defines a list of filters for attribute values. If the list is not empty, metrics with matching resource attribute values will not be emitted. MetricsInclude has higher priority than MetricsExclude.", + "type": "array", + "items": { + "description": "Config configures the matching behavior of a Filter.", + "type": "object", + "properties": { + "regexp": { + "type": "string" + }, + "strict": { + "type": "string" + } + } + } + }, + "metrics_include": { + "description": "Experimental: MetricsInclude defines a list of filters for attribute values. If the list is not empty, only metrics with matching resource attribute values will be emitted.", + "type": "array", + "items": { + "description": "Config configures the matching behavior of a Filter.", + "type": "object", + "properties": { + "regexp": { + "type": "string" + }, + "strict": { + "type": "string" + } + } + } + } + } + }, + "string.resource.attr": { + "description": "ResourceAttributeConfig provides common config for a string.resource.attr resource attribute.", + "type": "object", + "properties": { + "enabled": { + "type": "boolean", + "default": true + }, + "events_exclude": { + "description": "Experimental: EventsExclude defines a list of filters for attribute values. If the list is not empty, events with matching resource attribute values will not be emitted. EventsInclude has higher priority than EventsExclude.", + "type": "array", + "items": { + "description": "Config configures the matching behavior of a Filter.", + "type": "object", + "properties": { + "regexp": { + "type": "string" + }, + "strict": { + "type": "string" + } + } + } + }, + "events_include": { + "description": "Experimental: EventsInclude defines a list of filters for attribute values. If the list is not empty, only events with matching resource attribute values will be emitted.", + "type": "array", + "items": { + "description": "Config configures the matching behavior of a Filter.", + "type": "object", + "properties": { + "regexp": { + "type": "string" + }, + "strict": { + "type": "string" + } + } + } + }, + "metrics_exclude": { + "description": "Experimental: MetricsExclude defines a list of filters for attribute values. If the list is not empty, metrics with matching resource attribute values will not be emitted. MetricsInclude has higher priority than MetricsExclude.", + "type": "array", + "items": { + "description": "Config configures the matching behavior of a Filter.", + "type": "object", + "properties": { + "regexp": { + "type": "string" + }, + "strict": { + "type": "string" + } + } + } + }, + "metrics_include": { + "description": "Experimental: MetricsInclude defines a list of filters for attribute values. If the list is not empty, only metrics with matching resource attribute values will be emitted.", + "type": "array", + "items": { + "description": "Config configures the matching behavior of a Filter.", + "type": "object", + "properties": { + "regexp": { + "type": "string" + }, + "strict": { + "type": "string" + } + } + } + } + } + }, + "string.resource.attr_disable_warning": { + "description": "ResourceAttributeConfig provides common config for a string.resource.attr_disable_warning resource attribute.", + "type": "object", + "properties": { + "enabled": { + "type": "boolean", + "default": true + }, + "events_exclude": { + "description": "Experimental: EventsExclude defines a list of filters for attribute values. If the list is not empty, events with matching resource attribute values will not be emitted. EventsInclude has higher priority than EventsExclude.", + "type": "array", + "items": { + "description": "Config configures the matching behavior of a Filter.", + "type": "object", + "properties": { + "regexp": { + "type": "string" + }, + "strict": { + "type": "string" + } + } + } + }, + "events_include": { + "description": "Experimental: EventsInclude defines a list of filters for attribute values. If the list is not empty, only events with matching resource attribute values will be emitted.", + "type": "array", + "items": { + "description": "Config configures the matching behavior of a Filter.", + "type": "object", + "properties": { + "regexp": { + "type": "string" + }, + "strict": { + "type": "string" + } + } + } + }, + "metrics_exclude": { + "description": "Experimental: MetricsExclude defines a list of filters for attribute values. If the list is not empty, metrics with matching resource attribute values will not be emitted. MetricsInclude has higher priority than MetricsExclude.", + "type": "array", + "items": { + "description": "Config configures the matching behavior of a Filter.", + "type": "object", + "properties": { + "regexp": { + "type": "string" + }, + "strict": { + "type": "string" + } + } + } + }, + "metrics_include": { + "description": "Experimental: MetricsInclude defines a list of filters for attribute values. If the list is not empty, only metrics with matching resource attribute values will be emitted.", + "type": "array", + "items": { + "description": "Config configures the matching behavior of a Filter.", + "type": "object", + "properties": { + "regexp": { + "type": "string" + }, + "strict": { + "type": "string" + } + } + } + } + } + }, + "string.resource.attr_remove_warning": { + "description": "ResourceAttributeConfig provides common config for a string.resource.attr_remove_warning resource attribute.", + "type": "object", + "properties": { + "enabled": { + "type": "boolean", + "default": false + }, + "events_exclude": { + "description": "Experimental: EventsExclude defines a list of filters for attribute values. If the list is not empty, events with matching resource attribute values will not be emitted. EventsInclude has higher priority than EventsExclude.", + "type": "array", + "items": { + "description": "Config configures the matching behavior of a Filter.", + "type": "object", + "properties": { + "regexp": { + "type": "string" + }, + "strict": { + "type": "string" + } + } + } + }, + "events_include": { + "description": "Experimental: EventsInclude defines a list of filters for attribute values. If the list is not empty, only events with matching resource attribute values will be emitted.", + "type": "array", + "items": { + "description": "Config configures the matching behavior of a Filter.", + "type": "object", + "properties": { + "regexp": { + "type": "string" + }, + "strict": { + "type": "string" + } + } + } + }, + "metrics_exclude": { + "description": "Experimental: MetricsExclude defines a list of filters for attribute values. If the list is not empty, metrics with matching resource attribute values will not be emitted. MetricsInclude has higher priority than MetricsExclude.", + "type": "array", + "items": { + "description": "Config configures the matching behavior of a Filter.", + "type": "object", + "properties": { + "regexp": { + "type": "string" + }, + "strict": { + "type": "string" + } + } + } + }, + "metrics_include": { + "description": "Experimental: MetricsInclude defines a list of filters for attribute values. If the list is not empty, only metrics with matching resource attribute values will be emitted.", + "type": "array", + "items": { + "description": "Config configures the matching behavior of a Filter.", + "type": "object", + "properties": { + "regexp": { + "type": "string" + }, + "strict": { + "type": "string" + } + } + } + } + } + }, + "string.resource.attr_to_be_removed": { + "description": "ResourceAttributeConfig provides common config for a string.resource.attr_to_be_removed resource attribute.", + "type": "object", + "properties": { + "enabled": { + "type": "boolean", + "default": true + }, + "events_exclude": { + "description": "Experimental: EventsExclude defines a list of filters for attribute values. If the list is not empty, events with matching resource attribute values will not be emitted. EventsInclude has higher priority than EventsExclude.", + "type": "array", + "items": { + "description": "Config configures the matching behavior of a Filter.", + "type": "object", + "properties": { + "regexp": { + "type": "string" + }, + "strict": { + "type": "string" + } + } + } + }, + "events_include": { + "description": "Experimental: EventsInclude defines a list of filters for attribute values. If the list is not empty, only events with matching resource attribute values will be emitted.", + "type": "array", + "items": { + "description": "Config configures the matching behavior of a Filter.", + "type": "object", + "properties": { + "regexp": { + "type": "string" + }, + "strict": { + "type": "string" + } + } + } + }, + "metrics_exclude": { + "description": "Experimental: MetricsExclude defines a list of filters for attribute values. If the list is not empty, metrics with matching resource attribute values will not be emitted. MetricsInclude has higher priority than MetricsExclude.", + "type": "array", + "items": { + "description": "Config configures the matching behavior of a Filter.", + "type": "object", + "properties": { + "regexp": { + "type": "string" + }, + "strict": { + "type": "string" + } + } + } + }, + "metrics_include": { + "description": "Experimental: MetricsInclude defines a list of filters for attribute values. If the list is not empty, only metrics with matching resource attribute values will be emitted.", + "type": "array", + "items": { + "description": "Config configures the matching behavior of a Filter.", + "type": "object", + "properties": { + "regexp": { + "type": "string" + }, + "strict": { + "type": "string" + } + } + } + } + } + } + } + } + } + } + ], + "properties": { + "endpoint": { + "description": "The endpoint to scrape metrics from.", + "type": "string", + "default": "localhost:12345" + }, + "timeout": { + "description": "Timeout for scraping metrics. (duration format, e.g., \"30s\", \"1h30m\")", + "type": "string", + "default": "10s", + "pattern": "^([0-9]+(\\.[0-9]+)?(ns|us|µs|ms|s|m|h))+$" + } + }, + "required": [ + "endpoint" + ] +} \ No newline at end of file diff --git a/cmd/mdatagen/internal/samplereceiver/documentation.md b/cmd/mdatagen/internal/samplereceiver/documentation.md index 25fa9c66b74e..972446f81542 100644 --- a/cmd/mdatagen/internal/samplereceiver/documentation.md +++ b/cmd/mdatagen/internal/samplereceiver/documentation.md @@ -20,7 +20,9 @@ The metric will be become optional soon. | Unit | Metric Type | Value Type | Aggregation Temporality | Monotonic | Stability | | ---- | ----------- | ---------- | ----------------------- | --------- | --------- | -| s | Sum | Int | Cumulative | true | Development | +| s | Sum | Int | Cumulative | true | Deprecated since 1.0.0 | + +**Deprecation note**: This metric will be removed #### Attributes @@ -43,7 +45,9 @@ The metric will be removed soon. | Unit | Metric Type | Value Type | Aggregation Temporality | Monotonic | Stability | | ---- | ----------- | ---------- | ----------------------- | --------- | --------- | -| s | Sum | Double | Delta | false | Deprecated | +| s | Sum | Double | Delta | false | Deprecated since 1.0.0 | + +**Deprecation note**: This metric will be removed ### metric.input_type @@ -63,6 +67,37 @@ Monotonic cumulative sum int metric with string input_type enabled by default. | slice_attr | Attribute with a slice value. | Any Slice | Recommended | | map_attr | Attribute with a map value. | Any Map | Recommended | +### reaggregate.metric + +Metric for testing spatial reaggregation + +| Unit | Metric Type | Value Type | Stability | +| ---- | ----------- | ---------- | --------- | +| 1 | Gauge | Double | Beta | + +#### Attributes + +| Name | Description | Values | Requirement Level | +| ---- | ----------- | ------ | -------- | +| string_attr | Attribute with any string value. | Any Str | Recommended | +| boolean_attr | Attribute with a boolean value. | Any Bool | Recommended | + +### reaggregate.metric.with_required + +Metric for testing spatial reaggregation with required attributes + +| Unit | Metric Type | Value Type | Stability | +| ---- | ----------- | ---------- | --------- | +| 1 | Gauge | Double | Beta | + +#### Attributes + +| Name | Description | Values | Requirement Level | +| ---- | ----------- | ------ | -------- | +| required_string_attr | A required attribute with a string value | Any Str | Required | +| string_attr | Attribute with any string value. | Any Str | Recommended | +| boolean_attr | Attribute with a boolean value. | Any Bool | Recommended | + ### system.cpu.time Monotonic cumulative sum int metric enabled by default. @@ -71,7 +106,7 @@ The metric will be become optional soon. | Unit | Metric Type | Value Type | Aggregation Temporality | Monotonic | Stability | Semantic Convention | | ---- | ----------- | ---------- | ----------------------- | --------- | --------- | ------------------- | -| s | Sum | Int | Cumulative | true | Beta | [system.cpu.time](https://github.com/open-telemetry/semantic-conventions/blob/v1.37.0/docs/system/system-metrics.md#metric-systemcputime) | +| s | Sum | Int | Cumulative | true | Beta | [system.cpu.time](https://github.com/open-telemetry/semantic-conventions/blob/v1.38.0/docs/system/system-metrics.md#metric-systemcputime) | ## Optional Metrics @@ -89,7 +124,9 @@ metrics: | Unit | Metric Type | Value Type | Stability | | ---- | ----------- | ---------- | --------- | -| 1 | Gauge | Double | Deprecated | +| 1 | Gauge | Double | Deprecated since 1.0.0 | + +**Deprecation note**: This metric will be removed #### Attributes @@ -106,7 +143,9 @@ metrics: | Unit | Metric Type | Value Type | Stability | | ---- | ----------- | ---------- | --------- | -| | Gauge | Double | Deprecated | +| | Gauge | Double | Deprecated since 1.0.0 | + +**Deprecation note**: This metric will be removed #### Attributes @@ -202,11 +241,16 @@ The following telemetry is emitted by this component. ### otelcol_batch_size_trigger_send -Number of times the batch was sent due to a size trigger [Deprecated since v0.110.0] +Number of times the batch was sent due to a size trigger + +> **Deprecated since 1.5.0** +> This metric will be removed in favor of batch_send_trigger_size | Unit | Metric Type | Value Type | Monotonic | Stability | | ---- | ----------- | ---------- | --------- | --------- | -| {times} | Sum | Int | true | Deprecated | +| {time} | Sum | Int | true | Deprecated since 1.5.0 | + +**Deprecation note**: This metric will be removed in favor of batch_send_trigger_size ### otelcol_process_runtime_total_alloc_bytes @@ -218,26 +262,36 @@ Cumulative bytes allocated for heap objects (see 'go doc runtime.MemStats.TotalA ### otelcol_queue_capacity -Queue capacity - sync gauge example. [Development] +Queue capacity - sync gauge example. | Unit | Metric Type | Value Type | Stability | | ---- | ----------- | ---------- | --------- | -| {items} | Gauge | Int | Development | +| {item} | Gauge | Int | Development | ### otelcol_queue_length -This metric is optional and therefore not initialized in NewTelemetryBuilder. [Alpha] +This metric is optional and therefore not initialized in NewTelemetryBuilder. For example this metric only exists if feature A is enabled. | Unit | Metric Type | Value Type | Stability | | ---- | ----------- | ---------- | --------- | -| {items} | Gauge | Int | Alpha | +| {item} | Gauge | Int | Alpha | ### otelcol_request_duration -Duration of request [Alpha] +Duration of request | Unit | Metric Type | Value Type | Stability | | ---- | ----------- | ---------- | --------- | | s | Histogram | Double | Alpha | + +## Feature Gates + +This component has the following feature gates: + +| Feature Gate | Stage | Description | From Version | To Version | Reference | +| ------------ | ----- | ----------- | ------------ | ---------- | --------- | +| `receiver.sample.featuregate.example` | alpha | This is an example feature gate for testing mdatagen code generation. | v0.100.0 | N/A | [Link](https://github.com/open-telemetry/opentelemetry-collector/issues/12345) | + +For more information about feature gates, see the [Feature Gates](https://github.com/open-telemetry/opentelemetry-collector/blob/main/featuregate/README.md) documentation. diff --git a/cmd/mdatagen/internal/samplereceiver/factory.go b/cmd/mdatagen/internal/samplereceiver/factory.go index df625767eff0..453adfd46579 100644 --- a/cmd/mdatagen/internal/samplereceiver/factory.go +++ b/cmd/mdatagen/internal/samplereceiver/factory.go @@ -11,17 +11,21 @@ import ( "go.opentelemetry.io/collector/cmd/mdatagen/internal/samplereceiver/internal/metadata" "go.opentelemetry.io/collector/component" "go.opentelemetry.io/collector/consumer" + "go.opentelemetry.io/collector/consumer/xconsumer" "go.opentelemetry.io/collector/receiver" + "go.opentelemetry.io/collector/receiver/xreceiver" ) // NewFactory returns a receiver.Factory for sample receiver. -func NewFactory() receiver.Factory { - return receiver.NewFactory( +func NewFactory() xreceiver.Factory { + return xreceiver.NewFactory( metadata.Type, func() component.Config { return &struct{}{} }, - receiver.WithTraces(createTraces, metadata.TracesStability), - receiver.WithMetrics(createMetrics, metadata.MetricsStability), - receiver.WithLogs(createLogs, metadata.LogsStability)) + xreceiver.WithTraces(createTraces, metadata.TracesStability), + xreceiver.WithMetrics(createMetrics, metadata.MetricsStability), + xreceiver.WithLogs(createLogs, metadata.LogsStability), + xreceiver.WithProfiles(createProfiles, metadata.ProfilesStability), + ) } func createTraces(context.Context, receiver.Settings, component.Config, consumer.Traces) (receiver.Traces, error) { @@ -49,6 +53,10 @@ func createLogs(context.Context, receiver.Settings, component.Config, consumer.L return nopInstance, nil } +func createProfiles(context.Context, receiver.Settings, component.Config, xconsumer.Profiles) (xreceiver.Profiles, error) { + return nopInstance, nil +} + var nopInstance = &nopReceiver{} type nopReceiver struct { diff --git a/cmd/mdatagen/internal/samplereceiver/generated_component_test.go b/cmd/mdatagen/internal/samplereceiver/generated_component_test.go index 99fa261656c0..b27c553c8503 100644 --- a/cmd/mdatagen/internal/samplereceiver/generated_component_test.go +++ b/cmd/mdatagen/internal/samplereceiver/generated_component_test.go @@ -15,6 +15,7 @@ import ( "go.opentelemetry.io/collector/consumer/consumertest" "go.opentelemetry.io/collector/receiver" "go.opentelemetry.io/collector/receiver/receivertest" + "go.opentelemetry.io/collector/receiver/xreceiver" ) var typ = component.MustNewType("sample") @@ -55,6 +56,13 @@ func TestComponentLifecycle(t *testing.T) { return factory.CreateTraces(ctx, set, cfg, consumertest.NewNop()) }, }, + + { + name: "profiles", + createFn: func(ctx context.Context, set receiver.Settings, cfg component.Config) (component.Component, error) { + return factory.(xreceiver.Factory).CreateProfiles(ctx, set, cfg, consumertest.NewNop()) + }, + }, } cm, err := confmaptest.LoadConf("metadata.yaml") diff --git a/cmd/mdatagen/internal/samplereceiver/generated_config.go b/cmd/mdatagen/internal/samplereceiver/generated_config.go new file mode 100644 index 000000000000..98773ef45cac --- /dev/null +++ b/cmd/mdatagen/internal/samplereceiver/generated_config.go @@ -0,0 +1,18 @@ +// Code generated by mdatagen. DO NOT EDIT. + +package samplereceiver + +import ( + "time" + + "go.opentelemetry.io/collector/cmd/mdatagen/internal/samplereceiver/internal/metadata" +) + +// Config defines the configuration for Sample Receiver component. +type Config struct { + metadata.MetricsBuilderConfig `mapstructure:",squash"` + // The endpoint to scrape metrics from. + Endpoint string `mapstructure:"endpoint"` + // Timeout for scraping metrics. + Timeout time.Duration `mapstructure:"timeout"` +} diff --git a/cmd/mdatagen/internal/samplereceiver/internal/metadata/config.schema.yaml b/cmd/mdatagen/internal/samplereceiver/internal/metadata/config.schema.yaml new file mode 100644 index 000000000000..2fc71dc2e4e6 --- /dev/null +++ b/cmd/mdatagen/internal/samplereceiver/internal/metadata/config.schema.yaml @@ -0,0 +1,454 @@ +# Code generated by mdatagen. DO NOT EDIT. +$defs: + metrics_config: + description: MetricsConfig provides config for sample metrics. + type: object + properties: + default.metric: + description: "DefaultMetricMetricConfig provides config for the default.metric metric." + type: object + properties: + enabled: + type: boolean + default: true + aggregation_strategy: + type: string + enum: + - "sum" + - "avg" + - "min" + - "max" + default: "sum" + attributes: + type: array + items: + type: string + enum: + - "string_attr" + - "state" + - "enum_attr" + - "slice_attr" + - "map_attr" + - "conditional_int_attr" + - "conditional_string_attr" + - "opt_in_bool_attr" + default: + - "string_attr" + - "state" + - "enum_attr" + - "slice_attr" + - "map_attr" + - "conditional_int_attr" + - "conditional_string_attr" + default.metric.to_be_removed: + description: "DefaultMetricToBeRemovedMetricConfig provides config for the default.metric.to_be_removed metric." + type: object + properties: + enabled: + type: boolean + default: true + metric.input_type: + description: "MetricInputTypeMetricConfig provides config for the metric.input_type metric." + type: object + properties: + enabled: + type: boolean + default: true + aggregation_strategy: + type: string + enum: + - "sum" + - "avg" + - "min" + - "max" + default: "sum" + attributes: + type: array + items: + type: string + enum: + - "string_attr" + - "state" + - "enum_attr" + - "slice_attr" + - "map_attr" + default: + - "string_attr" + - "state" + - "enum_attr" + - "slice_attr" + - "map_attr" + optional.metric: + description: "OptionalMetricMetricConfig provides config for the optional.metric metric." + type: object + properties: + enabled: + type: boolean + default: false + aggregation_strategy: + type: string + enum: + - "sum" + - "avg" + - "min" + - "max" + default: "avg" + attributes: + type: array + items: + type: string + enum: + - "string_attr" + - "boolean_attr" + - "boolean_attr2" + - "conditional_string_attr" + default: + - "string_attr" + - "boolean_attr" + - "boolean_attr2" + - "conditional_string_attr" + optional.metric.empty_unit: + description: "OptionalMetricEmptyUnitMetricConfig provides config for the optional.metric.empty_unit metric." + type: object + properties: + enabled: + type: boolean + default: false + aggregation_strategy: + type: string + enum: + - "sum" + - "avg" + - "min" + - "max" + default: "avg" + attributes: + type: array + items: + type: string + enum: + - "string_attr" + - "boolean_attr" + default: + - "string_attr" + - "boolean_attr" + reaggregate.metric: + description: "ReaggregateMetricMetricConfig provides config for the reaggregate.metric metric." + type: object + properties: + enabled: + type: boolean + default: true + aggregation_strategy: + type: string + enum: + - "sum" + - "avg" + - "min" + - "max" + default: "avg" + attributes: + type: array + items: + type: string + enum: + - "string_attr" + - "boolean_attr" + default: + - "string_attr" + - "boolean_attr" + reaggregate.metric.with_required: + description: "ReaggregateMetricWithRequiredMetricConfig provides config for the reaggregate.metric.with_required metric." + type: object + properties: + enabled: + type: boolean + default: true + aggregation_strategy: + type: string + enum: + - "sum" + - "avg" + - "min" + - "max" + default: "avg" + attributes: + type: array + items: + type: string + enum: + - "required_string_attr" + - "string_attr" + - "boolean_attr" + default: + - "required_string_attr" + - "string_attr" + - "boolean_attr" + system.cpu.time: + description: "SystemCPUTimeMetricConfig provides config for the system.cpu.time metric." + type: object + properties: + enabled: + type: boolean + default: true + events_config: + description: EventsConfig provides config for sample events. + type: object + properties: + default.event: + description: EventConfig provides common config for a default.event event. + type: object + properties: + enabled: + type: boolean + default: true + default.event.to_be_removed: + description: EventConfig provides common config for a default.event.to_be_removed event. + type: object + properties: + enabled: + type: boolean + default: true + default.event.to_be_renamed: + description: EventConfig provides common config for a default.event.to_be_renamed event. + type: object + properties: + enabled: + type: boolean + default: false + resource_attributes_config: + description: ResourceAttributesConfig provides config for sample resource attributes. + type: object + properties: + map.resource.attr: + description: ResourceAttributeConfig provides common config for a map.resource.attr resource attribute. + type: object + properties: + enabled: + type: boolean + default: true + metrics_include: + description: "Experimental: MetricsInclude defines a list of filters for attribute values. If the list is not empty, only metrics with matching resource attribute values will be emitted." + type: array + items: + $ref: /filter.config + metrics_exclude: + description: "Experimental: MetricsExclude defines a list of filters for attribute values. If the list is not empty, metrics with matching resource attribute values will not be emitted. MetricsInclude has higher priority than MetricsExclude." + type: array + items: + $ref: /filter.config + events_include: + description: "Experimental: EventsInclude defines a list of filters for attribute values. If the list is not empty, only events with matching resource attribute values will be emitted." + type: array + items: + $ref: /filter.config + events_exclude: + description: "Experimental: EventsExclude defines a list of filters for attribute values. If the list is not empty, events with matching resource attribute values will not be emitted. EventsInclude has higher priority than EventsExclude." + type: array + items: + $ref: /filter.config + optional.resource.attr: + description: ResourceAttributeConfig provides common config for a optional.resource.attr resource attribute. + type: object + properties: + enabled: + type: boolean + default: false + metrics_include: + description: "Experimental: MetricsInclude defines a list of filters for attribute values. If the list is not empty, only metrics with matching resource attribute values will be emitted." + type: array + items: + $ref: /filter.config + metrics_exclude: + description: "Experimental: MetricsExclude defines a list of filters for attribute values. If the list is not empty, metrics with matching resource attribute values will not be emitted. MetricsInclude has higher priority than MetricsExclude." + type: array + items: + $ref: /filter.config + events_include: + description: "Experimental: EventsInclude defines a list of filters for attribute values. If the list is not empty, only events with matching resource attribute values will be emitted." + type: array + items: + $ref: /filter.config + events_exclude: + description: "Experimental: EventsExclude defines a list of filters for attribute values. If the list is not empty, events with matching resource attribute values will not be emitted. EventsInclude has higher priority than EventsExclude." + type: array + items: + $ref: /filter.config + slice.resource.attr: + description: ResourceAttributeConfig provides common config for a slice.resource.attr resource attribute. + type: object + properties: + enabled: + type: boolean + default: true + metrics_include: + description: "Experimental: MetricsInclude defines a list of filters for attribute values. If the list is not empty, only metrics with matching resource attribute values will be emitted." + type: array + items: + $ref: /filter.config + metrics_exclude: + description: "Experimental: MetricsExclude defines a list of filters for attribute values. If the list is not empty, metrics with matching resource attribute values will not be emitted. MetricsInclude has higher priority than MetricsExclude." + type: array + items: + $ref: /filter.config + events_include: + description: "Experimental: EventsInclude defines a list of filters for attribute values. If the list is not empty, only events with matching resource attribute values will be emitted." + type: array + items: + $ref: /filter.config + events_exclude: + description: "Experimental: EventsExclude defines a list of filters for attribute values. If the list is not empty, events with matching resource attribute values will not be emitted. EventsInclude has higher priority than EventsExclude." + type: array + items: + $ref: /filter.config + string.enum.resource.attr: + description: ResourceAttributeConfig provides common config for a string.enum.resource.attr resource attribute. + type: object + properties: + enabled: + type: boolean + default: true + metrics_include: + description: "Experimental: MetricsInclude defines a list of filters for attribute values. If the list is not empty, only metrics with matching resource attribute values will be emitted." + type: array + items: + $ref: /filter.config + metrics_exclude: + description: "Experimental: MetricsExclude defines a list of filters for attribute values. If the list is not empty, metrics with matching resource attribute values will not be emitted. MetricsInclude has higher priority than MetricsExclude." + type: array + items: + $ref: /filter.config + events_include: + description: "Experimental: EventsInclude defines a list of filters for attribute values. If the list is not empty, only events with matching resource attribute values will be emitted." + type: array + items: + $ref: /filter.config + events_exclude: + description: "Experimental: EventsExclude defines a list of filters for attribute values. If the list is not empty, events with matching resource attribute values will not be emitted. EventsInclude has higher priority than EventsExclude." + type: array + items: + $ref: /filter.config + string.resource.attr: + description: ResourceAttributeConfig provides common config for a string.resource.attr resource attribute. + type: object + properties: + enabled: + type: boolean + default: true + metrics_include: + description: "Experimental: MetricsInclude defines a list of filters for attribute values. If the list is not empty, only metrics with matching resource attribute values will be emitted." + type: array + items: + $ref: /filter.config + metrics_exclude: + description: "Experimental: MetricsExclude defines a list of filters for attribute values. If the list is not empty, metrics with matching resource attribute values will not be emitted. MetricsInclude has higher priority than MetricsExclude." + type: array + items: + $ref: /filter.config + events_include: + description: "Experimental: EventsInclude defines a list of filters for attribute values. If the list is not empty, only events with matching resource attribute values will be emitted." + type: array + items: + $ref: /filter.config + events_exclude: + description: "Experimental: EventsExclude defines a list of filters for attribute values. If the list is not empty, events with matching resource attribute values will not be emitted. EventsInclude has higher priority than EventsExclude." + type: array + items: + $ref: /filter.config + string.resource.attr_disable_warning: + description: ResourceAttributeConfig provides common config for a string.resource.attr_disable_warning resource attribute. + type: object + properties: + enabled: + type: boolean + default: true + metrics_include: + description: "Experimental: MetricsInclude defines a list of filters for attribute values. If the list is not empty, only metrics with matching resource attribute values will be emitted." + type: array + items: + $ref: /filter.config + metrics_exclude: + description: "Experimental: MetricsExclude defines a list of filters for attribute values. If the list is not empty, metrics with matching resource attribute values will not be emitted. MetricsInclude has higher priority than MetricsExclude." + type: array + items: + $ref: /filter.config + events_include: + description: "Experimental: EventsInclude defines a list of filters for attribute values. If the list is not empty, only events with matching resource attribute values will be emitted." + type: array + items: + $ref: /filter.config + events_exclude: + description: "Experimental: EventsExclude defines a list of filters for attribute values. If the list is not empty, events with matching resource attribute values will not be emitted. EventsInclude has higher priority than EventsExclude." + type: array + items: + $ref: /filter.config + string.resource.attr_remove_warning: + description: ResourceAttributeConfig provides common config for a string.resource.attr_remove_warning resource attribute. + type: object + properties: + enabled: + type: boolean + default: false + metrics_include: + description: "Experimental: MetricsInclude defines a list of filters for attribute values. If the list is not empty, only metrics with matching resource attribute values will be emitted." + type: array + items: + $ref: /filter.config + metrics_exclude: + description: "Experimental: MetricsExclude defines a list of filters for attribute values. If the list is not empty, metrics with matching resource attribute values will not be emitted. MetricsInclude has higher priority than MetricsExclude." + type: array + items: + $ref: /filter.config + events_include: + description: "Experimental: EventsInclude defines a list of filters for attribute values. If the list is not empty, only events with matching resource attribute values will be emitted." + type: array + items: + $ref: /filter.config + events_exclude: + description: "Experimental: EventsExclude defines a list of filters for attribute values. If the list is not empty, events with matching resource attribute values will not be emitted. EventsInclude has higher priority than EventsExclude." + type: array + items: + $ref: /filter.config + string.resource.attr_to_be_removed: + description: ResourceAttributeConfig provides common config for a string.resource.attr_to_be_removed resource attribute. + type: object + properties: + enabled: + type: boolean + default: true + metrics_include: + description: "Experimental: MetricsInclude defines a list of filters for attribute values. If the list is not empty, only metrics with matching resource attribute values will be emitted." + type: array + items: + $ref: /filter.config + metrics_exclude: + description: "Experimental: MetricsExclude defines a list of filters for attribute values. If the list is not empty, metrics with matching resource attribute values will not be emitted. MetricsInclude has higher priority than MetricsExclude." + type: array + items: + $ref: /filter.config + events_include: + description: "Experimental: EventsInclude defines a list of filters for attribute values. If the list is not empty, only events with matching resource attribute values will be emitted." + type: array + items: + $ref: /filter.config + events_exclude: + description: "Experimental: EventsExclude defines a list of filters for attribute values. If the list is not empty, events with matching resource attribute values will not be emitted. EventsInclude has higher priority than EventsExclude." + type: array + items: + $ref: /filter.config + metrics_builder_config: + description: MetricsBuilderConfig is a configuration for sample metrics builder. + type: object + properties: + metrics: + $ref: metrics_config + resource_attributes: + $ref: resource_attributes_config + logs_builder_config: + description: LogsBuilderConfig is a configuration for sample logs builder. + type: object + properties: + events: + $ref: events_config + resource_attributes: + $ref: resource_attributes_config diff --git a/cmd/mdatagen/internal/samplereceiver/internal/metadata/generated_config.go b/cmd/mdatagen/internal/samplereceiver/internal/metadata/generated_config.go index 8fede9dd04df..cd7fc3bbacd0 100644 --- a/cmd/mdatagen/internal/samplereceiver/internal/metadata/generated_config.go +++ b/cmd/mdatagen/internal/samplereceiver/internal/metadata/generated_config.go @@ -3,57 +3,410 @@ package metadata import ( + "fmt" + "slices" + "go.opentelemetry.io/collector/confmap" "go.opentelemetry.io/collector/filter" ) -// MetricConfig provides common config for a particular metric. -type MetricConfig struct { - Enabled bool `mapstructure:"enabled"` +// DefaultMetricMetricAttributeKey specifies the key of an attribute for the default.metric metric. +type DefaultMetricMetricAttributeKey string + +const ( + DefaultMetricMetricAttributeKeyStringAttr DefaultMetricMetricAttributeKey = "string_attr" + DefaultMetricMetricAttributeKeyOverriddenIntAttr DefaultMetricMetricAttributeKey = "state" + DefaultMetricMetricAttributeKeyEnumAttr DefaultMetricMetricAttributeKey = "enum_attr" + DefaultMetricMetricAttributeKeySliceAttr DefaultMetricMetricAttributeKey = "slice_attr" + DefaultMetricMetricAttributeKeyMapAttr DefaultMetricMetricAttributeKey = "map_attr" + DefaultMetricMetricAttributeKeyConditionalIntAttr DefaultMetricMetricAttributeKey = "conditional_int_attr" + DefaultMetricMetricAttributeKeyConditionalStringAttr DefaultMetricMetricAttributeKey = "conditional_string_attr" + DefaultMetricMetricAttributeKeyOptInBoolAttr DefaultMetricMetricAttributeKey = "opt_in_bool_attr" +) + +// DefaultMetricMetricConfig provides config for the default.metric metric. +type DefaultMetricMetricConfig struct { + Enabled bool `mapstructure:"enabled"` + enabledSetByUser bool + + AggregationStrategy string `mapstructure:"aggregation_strategy"` + EnabledAttributes []DefaultMetricMetricAttributeKey `mapstructure:"attributes"` +} + +func (ms *DefaultMetricMetricConfig) Unmarshal(parser *confmap.Conf) error { + if parser == nil { + return nil + } + + err := parser.Unmarshal(ms) + if err != nil { + return err + } + + ms.enabledSetByUser = parser.IsSet("enabled") + return nil +} + +func (ms *DefaultMetricMetricConfig) Validate() error { + for _, val := range ms.EnabledAttributes { + switch val { + case DefaultMetricMetricAttributeKeyStringAttr, DefaultMetricMetricAttributeKeyOverriddenIntAttr, DefaultMetricMetricAttributeKeyEnumAttr, DefaultMetricMetricAttributeKeySliceAttr, DefaultMetricMetricAttributeKeyMapAttr, DefaultMetricMetricAttributeKeyConditionalIntAttr, DefaultMetricMetricAttributeKeyConditionalStringAttr, DefaultMetricMetricAttributeKeyOptInBoolAttr: + default: + return fmt.Errorf("metric default.metric doesn't have an attribute %v, valid attributes: [string_attr, state, enum_attr, slice_attr, map_attr, conditional_int_attr, conditional_string_attr, opt_in_bool_attr]", val) + } + } + + switch ms.AggregationStrategy { + case AggregationStrategySum, AggregationStrategyAvg, AggregationStrategyMin, AggregationStrategyMax: + default: + return fmt.Errorf("invalid aggregation strategy %q, valid strategies: [%s, %s, %s, %s]", ms.AggregationStrategy, AggregationStrategySum, AggregationStrategyAvg, AggregationStrategyMin, AggregationStrategyMax) + } + + return nil +} + +// DefaultMetricToBeRemovedMetricConfig provides config for the default.metric.to_be_removed metric. +type DefaultMetricToBeRemovedMetricConfig struct { + Enabled bool `mapstructure:"enabled"` + enabledSetByUser bool +} + +func (ms *DefaultMetricToBeRemovedMetricConfig) Unmarshal(parser *confmap.Conf) error { + if parser == nil { + return nil + } + + err := parser.Unmarshal(ms) + if err != nil { + return err + } + + ms.enabledSetByUser = parser.IsSet("enabled") + return nil +} + +// MetricInputTypeMetricAttributeKey specifies the key of an attribute for the metric.input_type metric. +type MetricInputTypeMetricAttributeKey string + +const ( + MetricInputTypeMetricAttributeKeyStringAttr MetricInputTypeMetricAttributeKey = "string_attr" + MetricInputTypeMetricAttributeKeyOverriddenIntAttr MetricInputTypeMetricAttributeKey = "state" + MetricInputTypeMetricAttributeKeyEnumAttr MetricInputTypeMetricAttributeKey = "enum_attr" + MetricInputTypeMetricAttributeKeySliceAttr MetricInputTypeMetricAttributeKey = "slice_attr" + MetricInputTypeMetricAttributeKeyMapAttr MetricInputTypeMetricAttributeKey = "map_attr" +) + +// MetricInputTypeMetricConfig provides config for the metric.input_type metric. +type MetricInputTypeMetricConfig struct { + Enabled bool `mapstructure:"enabled"` + enabledSetByUser bool + + AggregationStrategy string `mapstructure:"aggregation_strategy"` + EnabledAttributes []MetricInputTypeMetricAttributeKey `mapstructure:"attributes"` +} + +func (ms *MetricInputTypeMetricConfig) Unmarshal(parser *confmap.Conf) error { + if parser == nil { + return nil + } + + err := parser.Unmarshal(ms) + if err != nil { + return err + } + + ms.enabledSetByUser = parser.IsSet("enabled") + return nil +} + +func (ms *MetricInputTypeMetricConfig) Validate() error { + for _, val := range ms.EnabledAttributes { + switch val { + case MetricInputTypeMetricAttributeKeyStringAttr, MetricInputTypeMetricAttributeKeyOverriddenIntAttr, MetricInputTypeMetricAttributeKeyEnumAttr, MetricInputTypeMetricAttributeKeySliceAttr, MetricInputTypeMetricAttributeKeyMapAttr: + default: + return fmt.Errorf("metric metric.input_type doesn't have an attribute %v, valid attributes: [string_attr, state, enum_attr, slice_attr, map_attr]", val) + } + } + + switch ms.AggregationStrategy { + case AggregationStrategySum, AggregationStrategyAvg, AggregationStrategyMin, AggregationStrategyMax: + default: + return fmt.Errorf("invalid aggregation strategy %q, valid strategies: [%s, %s, %s, %s]", ms.AggregationStrategy, AggregationStrategySum, AggregationStrategyAvg, AggregationStrategyMin, AggregationStrategyMax) + } + + return nil +} + +// OptionalMetricMetricAttributeKey specifies the key of an attribute for the optional.metric metric. +type OptionalMetricMetricAttributeKey string + +const ( + OptionalMetricMetricAttributeKeyStringAttr OptionalMetricMetricAttributeKey = "string_attr" + OptionalMetricMetricAttributeKeyBooleanAttr OptionalMetricMetricAttributeKey = "boolean_attr" + OptionalMetricMetricAttributeKeyBooleanAttr2 OptionalMetricMetricAttributeKey = "boolean_attr2" + OptionalMetricMetricAttributeKeyConditionalStringAttr OptionalMetricMetricAttributeKey = "conditional_string_attr" +) + +// OptionalMetricMetricConfig provides config for the optional.metric metric. +type OptionalMetricMetricConfig struct { + Enabled bool `mapstructure:"enabled"` + enabledSetByUser bool + + AggregationStrategy string `mapstructure:"aggregation_strategy"` + EnabledAttributes []OptionalMetricMetricAttributeKey `mapstructure:"attributes"` +} + +func (ms *OptionalMetricMetricConfig) Unmarshal(parser *confmap.Conf) error { + if parser == nil { + return nil + } + + err := parser.Unmarshal(ms) + if err != nil { + return err + } + + ms.enabledSetByUser = parser.IsSet("enabled") + return nil +} + +func (ms *OptionalMetricMetricConfig) Validate() error { + for _, val := range ms.EnabledAttributes { + switch val { + case OptionalMetricMetricAttributeKeyStringAttr, OptionalMetricMetricAttributeKeyBooleanAttr, OptionalMetricMetricAttributeKeyBooleanAttr2, OptionalMetricMetricAttributeKeyConditionalStringAttr: + default: + return fmt.Errorf("metric optional.metric doesn't have an attribute %v, valid attributes: [string_attr, boolean_attr, boolean_attr2, conditional_string_attr]", val) + } + } + + switch ms.AggregationStrategy { + case AggregationStrategySum, AggregationStrategyAvg, AggregationStrategyMin, AggregationStrategyMax: + default: + return fmt.Errorf("invalid aggregation strategy %q, valid strategies: [%s, %s, %s, %s]", ms.AggregationStrategy, AggregationStrategySum, AggregationStrategyAvg, AggregationStrategyMin, AggregationStrategyMax) + } + + return nil +} + +// OptionalMetricEmptyUnitMetricAttributeKey specifies the key of an attribute for the optional.metric.empty_unit metric. +type OptionalMetricEmptyUnitMetricAttributeKey string + +const ( + OptionalMetricEmptyUnitMetricAttributeKeyStringAttr OptionalMetricEmptyUnitMetricAttributeKey = "string_attr" + OptionalMetricEmptyUnitMetricAttributeKeyBooleanAttr OptionalMetricEmptyUnitMetricAttributeKey = "boolean_attr" +) + +// OptionalMetricEmptyUnitMetricConfig provides config for the optional.metric.empty_unit metric. +type OptionalMetricEmptyUnitMetricConfig struct { + Enabled bool `mapstructure:"enabled"` + enabledSetByUser bool + + AggregationStrategy string `mapstructure:"aggregation_strategy"` + EnabledAttributes []OptionalMetricEmptyUnitMetricAttributeKey `mapstructure:"attributes"` +} + +func (ms *OptionalMetricEmptyUnitMetricConfig) Unmarshal(parser *confmap.Conf) error { + if parser == nil { + return nil + } + + err := parser.Unmarshal(ms) + if err != nil { + return err + } + + ms.enabledSetByUser = parser.IsSet("enabled") + return nil +} + +func (ms *OptionalMetricEmptyUnitMetricConfig) Validate() error { + for _, val := range ms.EnabledAttributes { + switch val { + case OptionalMetricEmptyUnitMetricAttributeKeyStringAttr, OptionalMetricEmptyUnitMetricAttributeKeyBooleanAttr: + default: + return fmt.Errorf("metric optional.metric.empty_unit doesn't have an attribute %v, valid attributes: [string_attr, boolean_attr]", val) + } + } + + switch ms.AggregationStrategy { + case AggregationStrategySum, AggregationStrategyAvg, AggregationStrategyMin, AggregationStrategyMax: + default: + return fmt.Errorf("invalid aggregation strategy %q, valid strategies: [%s, %s, %s, %s]", ms.AggregationStrategy, AggregationStrategySum, AggregationStrategyAvg, AggregationStrategyMin, AggregationStrategyMax) + } + + return nil +} + +// ReaggregateMetricMetricAttributeKey specifies the key of an attribute for the reaggregate.metric metric. +type ReaggregateMetricMetricAttributeKey string + +const ( + ReaggregateMetricMetricAttributeKeyStringAttr ReaggregateMetricMetricAttributeKey = "string_attr" + ReaggregateMetricMetricAttributeKeyBooleanAttr ReaggregateMetricMetricAttributeKey = "boolean_attr" +) + +// ReaggregateMetricMetricConfig provides config for the reaggregate.metric metric. +type ReaggregateMetricMetricConfig struct { + Enabled bool `mapstructure:"enabled"` + enabledSetByUser bool + + AggregationStrategy string `mapstructure:"aggregation_strategy"` + EnabledAttributes []ReaggregateMetricMetricAttributeKey `mapstructure:"attributes"` +} + +func (ms *ReaggregateMetricMetricConfig) Unmarshal(parser *confmap.Conf) error { + if parser == nil { + return nil + } + + err := parser.Unmarshal(ms) + if err != nil { + return err + } + ms.enabledSetByUser = parser.IsSet("enabled") + return nil +} + +func (ms *ReaggregateMetricMetricConfig) Validate() error { + for _, val := range ms.EnabledAttributes { + switch val { + case ReaggregateMetricMetricAttributeKeyStringAttr, ReaggregateMetricMetricAttributeKeyBooleanAttr: + default: + return fmt.Errorf("metric reaggregate.metric doesn't have an attribute %v, valid attributes: [string_attr, boolean_attr]", val) + } + } + + switch ms.AggregationStrategy { + case AggregationStrategySum, AggregationStrategyAvg, AggregationStrategyMin, AggregationStrategyMax: + default: + return fmt.Errorf("invalid aggregation strategy %q, valid strategies: [%s, %s, %s, %s]", ms.AggregationStrategy, AggregationStrategySum, AggregationStrategyAvg, AggregationStrategyMin, AggregationStrategyMax) + } + + return nil +} + +// ReaggregateMetricWithRequiredMetricAttributeKey specifies the key of an attribute for the reaggregate.metric.with_required metric. +type ReaggregateMetricWithRequiredMetricAttributeKey string + +const ( + ReaggregateMetricWithRequiredMetricAttributeKeyRequiredStringAttr ReaggregateMetricWithRequiredMetricAttributeKey = "required_string_attr" + ReaggregateMetricWithRequiredMetricAttributeKeyStringAttr ReaggregateMetricWithRequiredMetricAttributeKey = "string_attr" + ReaggregateMetricWithRequiredMetricAttributeKeyBooleanAttr ReaggregateMetricWithRequiredMetricAttributeKey = "boolean_attr" +) + +// ReaggregateMetricWithRequiredMetricConfig provides config for the reaggregate.metric.with_required metric. +type ReaggregateMetricWithRequiredMetricConfig struct { + Enabled bool `mapstructure:"enabled"` enabledSetByUser bool + + AggregationStrategy string `mapstructure:"aggregation_strategy"` + EnabledAttributes []ReaggregateMetricWithRequiredMetricAttributeKey `mapstructure:"attributes"` } -func (ms *MetricConfig) Unmarshal(parser *confmap.Conf) error { +func (ms *ReaggregateMetricWithRequiredMetricConfig) Unmarshal(parser *confmap.Conf) error { if parser == nil { return nil } + err := parser.Unmarshal(ms) if err != nil { return err } + + ms.enabledSetByUser = parser.IsSet("enabled") + return nil +} + +func (ms *ReaggregateMetricWithRequiredMetricConfig) Validate() error { + for _, val := range ms.EnabledAttributes { + switch val { + case ReaggregateMetricWithRequiredMetricAttributeKeyRequiredStringAttr, ReaggregateMetricWithRequiredMetricAttributeKeyStringAttr, ReaggregateMetricWithRequiredMetricAttributeKeyBooleanAttr: + default: + return fmt.Errorf("metric reaggregate.metric.with_required doesn't have an attribute %v, valid attributes: [required_string_attr, string_attr, boolean_attr]", val) + } + } + if !slices.Contains(ms.EnabledAttributes, ReaggregateMetricWithRequiredMetricAttributeKeyRequiredStringAttr) { + return fmt.Errorf("required_string_attr is a required attribute for reaggregate.metric.with_required metric and must be included") + } + + switch ms.AggregationStrategy { + case AggregationStrategySum, AggregationStrategyAvg, AggregationStrategyMin, AggregationStrategyMax: + default: + return fmt.Errorf("invalid aggregation strategy %q, valid strategies: [%s, %s, %s, %s]", ms.AggregationStrategy, AggregationStrategySum, AggregationStrategyAvg, AggregationStrategyMin, AggregationStrategyMax) + } + + return nil +} + +// SystemCPUTimeMetricConfig provides config for the system.cpu.time metric. +type SystemCPUTimeMetricConfig struct { + Enabled bool `mapstructure:"enabled"` + enabledSetByUser bool +} + +func (ms *SystemCPUTimeMetricConfig) Unmarshal(parser *confmap.Conf) error { + if parser == nil { + return nil + } + + err := parser.Unmarshal(ms) + if err != nil { + return err + } + ms.enabledSetByUser = parser.IsSet("enabled") return nil } // MetricsConfig provides config for sample metrics. type MetricsConfig struct { - DefaultMetric MetricConfig `mapstructure:"default.metric"` - DefaultMetricToBeRemoved MetricConfig `mapstructure:"default.metric.to_be_removed"` - MetricInputType MetricConfig `mapstructure:"metric.input_type"` - OptionalMetric MetricConfig `mapstructure:"optional.metric"` - OptionalMetricEmptyUnit MetricConfig `mapstructure:"optional.metric.empty_unit"` - SystemCPUTime MetricConfig `mapstructure:"system.cpu.time"` + DefaultMetric DefaultMetricMetricConfig `mapstructure:"default.metric"` + DefaultMetricToBeRemoved DefaultMetricToBeRemovedMetricConfig `mapstructure:"default.metric.to_be_removed"` + MetricInputType MetricInputTypeMetricConfig `mapstructure:"metric.input_type"` + OptionalMetric OptionalMetricMetricConfig `mapstructure:"optional.metric"` + OptionalMetricEmptyUnit OptionalMetricEmptyUnitMetricConfig `mapstructure:"optional.metric.empty_unit"` + ReaggregateMetric ReaggregateMetricMetricConfig `mapstructure:"reaggregate.metric"` + ReaggregateMetricWithRequired ReaggregateMetricWithRequiredMetricConfig `mapstructure:"reaggregate.metric.with_required"` + SystemCPUTime SystemCPUTimeMetricConfig `mapstructure:"system.cpu.time"` } func DefaultMetricsConfig() MetricsConfig { return MetricsConfig{ - DefaultMetric: MetricConfig{ - Enabled: true, + DefaultMetric: DefaultMetricMetricConfig{ + Enabled: true, + AggregationStrategy: AggregationStrategySum, + EnabledAttributes: []DefaultMetricMetricAttributeKey{DefaultMetricMetricAttributeKeyStringAttr, DefaultMetricMetricAttributeKeyOverriddenIntAttr, DefaultMetricMetricAttributeKeyEnumAttr, DefaultMetricMetricAttributeKeySliceAttr, DefaultMetricMetricAttributeKeyMapAttr, DefaultMetricMetricAttributeKeyConditionalIntAttr, DefaultMetricMetricAttributeKeyConditionalStringAttr}, }, - DefaultMetricToBeRemoved: MetricConfig{ + DefaultMetricToBeRemoved: DefaultMetricToBeRemovedMetricConfig{ Enabled: true, }, - MetricInputType: MetricConfig{ - Enabled: true, + MetricInputType: MetricInputTypeMetricConfig{ + Enabled: true, + AggregationStrategy: AggregationStrategySum, + EnabledAttributes: []MetricInputTypeMetricAttributeKey{MetricInputTypeMetricAttributeKeyStringAttr, MetricInputTypeMetricAttributeKeyOverriddenIntAttr, MetricInputTypeMetricAttributeKeyEnumAttr, MetricInputTypeMetricAttributeKeySliceAttr, MetricInputTypeMetricAttributeKeyMapAttr}, }, - OptionalMetric: MetricConfig{ - Enabled: false, + OptionalMetric: OptionalMetricMetricConfig{ + Enabled: false, + AggregationStrategy: AggregationStrategyAvg, + EnabledAttributes: []OptionalMetricMetricAttributeKey{OptionalMetricMetricAttributeKeyStringAttr, OptionalMetricMetricAttributeKeyBooleanAttr, OptionalMetricMetricAttributeKeyBooleanAttr2, OptionalMetricMetricAttributeKeyConditionalStringAttr}, }, - OptionalMetricEmptyUnit: MetricConfig{ - Enabled: false, + OptionalMetricEmptyUnit: OptionalMetricEmptyUnitMetricConfig{ + Enabled: false, + AggregationStrategy: AggregationStrategyAvg, + EnabledAttributes: []OptionalMetricEmptyUnitMetricAttributeKey{OptionalMetricEmptyUnitMetricAttributeKeyStringAttr, OptionalMetricEmptyUnitMetricAttributeKeyBooleanAttr}, + }, + ReaggregateMetric: ReaggregateMetricMetricConfig{ + Enabled: true, + AggregationStrategy: AggregationStrategyAvg, + EnabledAttributes: []ReaggregateMetricMetricAttributeKey{ReaggregateMetricMetricAttributeKeyStringAttr, ReaggregateMetricMetricAttributeKeyBooleanAttr}, + }, + ReaggregateMetricWithRequired: ReaggregateMetricWithRequiredMetricConfig{ + Enabled: true, + AggregationStrategy: AggregationStrategyAvg, + EnabledAttributes: []ReaggregateMetricWithRequiredMetricAttributeKey{ReaggregateMetricWithRequiredMetricAttributeKeyRequiredStringAttr, ReaggregateMetricWithRequiredMetricAttributeKeyStringAttr, ReaggregateMetricWithRequiredMetricAttributeKeyBooleanAttr}, }, - SystemCPUTime: MetricConfig{ + SystemCPUTime: SystemCPUTimeMetricConfig{ Enabled: true, }, } diff --git a/cmd/mdatagen/internal/samplereceiver/internal/metadata/generated_config_test.go b/cmd/mdatagen/internal/samplereceiver/internal/metadata/generated_config_test.go index abe03b709a52..d7e413f3b349 100644 --- a/cmd/mdatagen/internal/samplereceiver/internal/metadata/generated_config_test.go +++ b/cmd/mdatagen/internal/samplereceiver/internal/metadata/generated_config_test.go @@ -27,12 +27,42 @@ func TestMetricsBuilderConfig(t *testing.T) { name: "all_set", want: MetricsBuilderConfig{ Metrics: MetricsConfig{ - DefaultMetric: MetricConfig{Enabled: true}, - DefaultMetricToBeRemoved: MetricConfig{Enabled: true}, - MetricInputType: MetricConfig{Enabled: true}, - OptionalMetric: MetricConfig{Enabled: true}, - OptionalMetricEmptyUnit: MetricConfig{Enabled: true}, - SystemCPUTime: MetricConfig{Enabled: true}, + DefaultMetric: DefaultMetricMetricConfig{ + Enabled: true, + AggregationStrategy: AggregationStrategySum, + EnabledAttributes: []DefaultMetricMetricAttributeKey{DefaultMetricMetricAttributeKeyStringAttr, DefaultMetricMetricAttributeKeyOverriddenIntAttr, DefaultMetricMetricAttributeKeyEnumAttr, DefaultMetricMetricAttributeKeySliceAttr, DefaultMetricMetricAttributeKeyMapAttr, DefaultMetricMetricAttributeKeyConditionalIntAttr, DefaultMetricMetricAttributeKeyConditionalStringAttr, DefaultMetricMetricAttributeKeyOptInBoolAttr}, + }, + DefaultMetricToBeRemoved: DefaultMetricToBeRemovedMetricConfig{ + Enabled: true, + }, + MetricInputType: MetricInputTypeMetricConfig{ + Enabled: true, + AggregationStrategy: AggregationStrategySum, + EnabledAttributes: []MetricInputTypeMetricAttributeKey{MetricInputTypeMetricAttributeKeyStringAttr, MetricInputTypeMetricAttributeKeyOverriddenIntAttr, MetricInputTypeMetricAttributeKeyEnumAttr, MetricInputTypeMetricAttributeKeySliceAttr, MetricInputTypeMetricAttributeKeyMapAttr}, + }, + OptionalMetric: OptionalMetricMetricConfig{ + Enabled: true, + AggregationStrategy: AggregationStrategyAvg, + EnabledAttributes: []OptionalMetricMetricAttributeKey{OptionalMetricMetricAttributeKeyStringAttr, OptionalMetricMetricAttributeKeyBooleanAttr, OptionalMetricMetricAttributeKeyBooleanAttr2, OptionalMetricMetricAttributeKeyConditionalStringAttr}, + }, + OptionalMetricEmptyUnit: OptionalMetricEmptyUnitMetricConfig{ + Enabled: true, + AggregationStrategy: AggregationStrategyAvg, + EnabledAttributes: []OptionalMetricEmptyUnitMetricAttributeKey{OptionalMetricEmptyUnitMetricAttributeKeyStringAttr, OptionalMetricEmptyUnitMetricAttributeKeyBooleanAttr}, + }, + ReaggregateMetric: ReaggregateMetricMetricConfig{ + Enabled: true, + AggregationStrategy: AggregationStrategyAvg, + EnabledAttributes: []ReaggregateMetricMetricAttributeKey{ReaggregateMetricMetricAttributeKeyStringAttr, ReaggregateMetricMetricAttributeKeyBooleanAttr}, + }, + ReaggregateMetricWithRequired: ReaggregateMetricWithRequiredMetricConfig{ + Enabled: true, + AggregationStrategy: AggregationStrategyAvg, + EnabledAttributes: []ReaggregateMetricWithRequiredMetricAttributeKey{ReaggregateMetricWithRequiredMetricAttributeKeyRequiredStringAttr, ReaggregateMetricWithRequiredMetricAttributeKeyStringAttr, ReaggregateMetricWithRequiredMetricAttributeKeyBooleanAttr}, + }, + SystemCPUTime: SystemCPUTimeMetricConfig{ + Enabled: true, + }, }, ResourceAttributes: ResourceAttributesConfig{ MapResourceAttr: ResourceAttributeConfig{Enabled: true}, @@ -50,12 +80,42 @@ func TestMetricsBuilderConfig(t *testing.T) { name: "none_set", want: MetricsBuilderConfig{ Metrics: MetricsConfig{ - DefaultMetric: MetricConfig{Enabled: false}, - DefaultMetricToBeRemoved: MetricConfig{Enabled: false}, - MetricInputType: MetricConfig{Enabled: false}, - OptionalMetric: MetricConfig{Enabled: false}, - OptionalMetricEmptyUnit: MetricConfig{Enabled: false}, - SystemCPUTime: MetricConfig{Enabled: false}, + DefaultMetric: DefaultMetricMetricConfig{ + Enabled: false, + AggregationStrategy: AggregationStrategySum, + EnabledAttributes: []DefaultMetricMetricAttributeKey{DefaultMetricMetricAttributeKeyStringAttr, DefaultMetricMetricAttributeKeyOverriddenIntAttr, DefaultMetricMetricAttributeKeyEnumAttr, DefaultMetricMetricAttributeKeySliceAttr, DefaultMetricMetricAttributeKeyMapAttr, DefaultMetricMetricAttributeKeyConditionalIntAttr, DefaultMetricMetricAttributeKeyConditionalStringAttr, DefaultMetricMetricAttributeKeyOptInBoolAttr}, + }, + DefaultMetricToBeRemoved: DefaultMetricToBeRemovedMetricConfig{ + Enabled: false, + }, + MetricInputType: MetricInputTypeMetricConfig{ + Enabled: false, + AggregationStrategy: AggregationStrategySum, + EnabledAttributes: []MetricInputTypeMetricAttributeKey{MetricInputTypeMetricAttributeKeyStringAttr, MetricInputTypeMetricAttributeKeyOverriddenIntAttr, MetricInputTypeMetricAttributeKeyEnumAttr, MetricInputTypeMetricAttributeKeySliceAttr, MetricInputTypeMetricAttributeKeyMapAttr}, + }, + OptionalMetric: OptionalMetricMetricConfig{ + Enabled: false, + AggregationStrategy: AggregationStrategyAvg, + EnabledAttributes: []OptionalMetricMetricAttributeKey{OptionalMetricMetricAttributeKeyStringAttr, OptionalMetricMetricAttributeKeyBooleanAttr, OptionalMetricMetricAttributeKeyBooleanAttr2, OptionalMetricMetricAttributeKeyConditionalStringAttr}, + }, + OptionalMetricEmptyUnit: OptionalMetricEmptyUnitMetricConfig{ + Enabled: false, + AggregationStrategy: AggregationStrategyAvg, + EnabledAttributes: []OptionalMetricEmptyUnitMetricAttributeKey{OptionalMetricEmptyUnitMetricAttributeKeyStringAttr, OptionalMetricEmptyUnitMetricAttributeKeyBooleanAttr}, + }, + ReaggregateMetric: ReaggregateMetricMetricConfig{ + Enabled: false, + AggregationStrategy: AggregationStrategyAvg, + EnabledAttributes: []ReaggregateMetricMetricAttributeKey{ReaggregateMetricMetricAttributeKeyStringAttr, ReaggregateMetricMetricAttributeKeyBooleanAttr}, + }, + ReaggregateMetricWithRequired: ReaggregateMetricWithRequiredMetricConfig{ + Enabled: false, + AggregationStrategy: AggregationStrategyAvg, + EnabledAttributes: []ReaggregateMetricWithRequiredMetricAttributeKey{ReaggregateMetricWithRequiredMetricAttributeKeyRequiredStringAttr, ReaggregateMetricWithRequiredMetricAttributeKeyStringAttr, ReaggregateMetricWithRequiredMetricAttributeKeyBooleanAttr}, + }, + SystemCPUTime: SystemCPUTimeMetricConfig{ + Enabled: false, + }, }, ResourceAttributes: ResourceAttributesConfig{ MapResourceAttr: ResourceAttributeConfig{Enabled: false}, @@ -73,7 +133,7 @@ func TestMetricsBuilderConfig(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { cfg := loadMetricsBuilderConfig(t, tt.name) - diff := cmp.Diff(tt.want, cfg, cmpopts.IgnoreUnexported(MetricConfig{}, ResourceAttributeConfig{})) + diff := cmp.Diff(tt.want, cfg, cmpopts.IgnoreUnexported(DefaultMetricMetricConfig{}, DefaultMetricToBeRemovedMetricConfig{}, MetricInputTypeMetricConfig{}, OptionalMetricMetricConfig{}, OptionalMetricEmptyUnitMetricConfig{}, ReaggregateMetricMetricConfig{}, ReaggregateMetricWithRequiredMetricConfig{}, SystemCPUTimeMetricConfig{}, ResourceAttributeConfig{})) require.Emptyf(t, diff, "Config mismatch (-expected +actual):\n%s", diff) }) } diff --git a/cmd/mdatagen/internal/samplereceiver/internal/metadata/generated_feature_gates.go b/cmd/mdatagen/internal/samplereceiver/internal/metadata/generated_feature_gates.go new file mode 100644 index 000000000000..6537d6b20c3c --- /dev/null +++ b/cmd/mdatagen/internal/samplereceiver/internal/metadata/generated_feature_gates.go @@ -0,0 +1,15 @@ +// Code generated by mdatagen. DO NOT EDIT. + +package metadata + +import ( + "go.opentelemetry.io/collector/featuregate" +) + +var ReceiverSampleFeaturegateExampleFeatureGate = featuregate.GlobalRegistry().MustRegister( + "receiver.sample.featuregate.example", + featuregate.StageAlpha, + featuregate.WithRegisterDescription("This is an example feature gate for testing mdatagen code generation."), + featuregate.WithRegisterReferenceURL("https://github.com/open-telemetry/opentelemetry-collector/issues/12345"), + featuregate.WithRegisterFromVersion("v0.100.0"), +) diff --git a/cmd/mdatagen/internal/samplereceiver/internal/metadata/generated_logs.go b/cmd/mdatagen/internal/samplereceiver/internal/metadata/generated_logs.go index 965481b46ef1..8530872a0550 100644 --- a/cmd/mdatagen/internal/samplereceiver/internal/metadata/generated_logs.go +++ b/cmd/mdatagen/internal/samplereceiver/internal/metadata/generated_logs.go @@ -5,7 +5,7 @@ package metadata import ( "context" - conventions "go.opentelemetry.io/otel/semconv/v1.37.0" + conventions "go.opentelemetry.io/otel/semconv/v1.38.0" "go.opentelemetry.io/otel/trace" "go.opentelemetry.io/collector/component" diff --git a/cmd/mdatagen/internal/samplereceiver/internal/metadata/generated_metrics.go b/cmd/mdatagen/internal/samplereceiver/internal/metadata/generated_metrics.go index a8fb3a631a4b..e047d97c69a7 100644 --- a/cmd/mdatagen/internal/samplereceiver/internal/metadata/generated_metrics.go +++ b/cmd/mdatagen/internal/samplereceiver/internal/metadata/generated_metrics.go @@ -4,10 +4,11 @@ package metadata import ( "fmt" + "slices" "strconv" "time" - conventions "go.opentelemetry.io/otel/semconv/v1.37.0" + conventions "go.opentelemetry.io/otel/semconv/v1.38.0" "go.opentelemetry.io/collector/component" "go.opentelemetry.io/collector/filter" @@ -16,6 +17,13 @@ import ( "go.opentelemetry.io/collector/receiver" ) +const ( + AggregationStrategySum = "sum" + AggregationStrategyAvg = "avg" + AggregationStrategyMin = "min" + AggregationStrategyMax = "max" +) + // AttributeEnumAttr specifies the value enum_attr attribute. type AttributeEnumAttr int @@ -62,18 +70,26 @@ var MetricsInfo = metricsInfo{ OptionalMetricEmptyUnit: metricInfo{ Name: "optional.metric.empty_unit", }, + ReaggregateMetric: metricInfo{ + Name: "reaggregate.metric", + }, + ReaggregateMetricWithRequired: metricInfo{ + Name: "reaggregate.metric.with_required", + }, SystemCPUTime: metricInfo{ Name: "system.cpu.time", }, } type metricsInfo struct { - DefaultMetric metricInfo - DefaultMetricToBeRemoved metricInfo - MetricInputType metricInfo - OptionalMetric metricInfo - OptionalMetricEmptyUnit metricInfo - SystemCPUTime metricInfo + DefaultMetric metricInfo + DefaultMetricToBeRemoved metricInfo + MetricInputType metricInfo + OptionalMetric metricInfo + OptionalMetricEmptyUnit metricInfo + ReaggregateMetric metricInfo + ReaggregateMetricWithRequired metricInfo + SystemCPUTime metricInfo } type metricInfo struct { @@ -103,9 +119,10 @@ func WithConditionalStringAttrMetricAttribute(conditionalStringAttrAttributeValu } type metricDefaultMetric struct { - data pmetric.Metric // data buffer for generated metric. - config MetricConfig // metric config provided by user. - capacity int // max observed number of data points added to the metric. + data pmetric.Metric // data buffer for generated metric. + config DefaultMetricMetricConfig // metric config provided by user. + capacity int // max observed number of data points added to the metric. + aggDataPoints []int64 // slice containing number of aggregated datapoints at each index } // init fills default.metric metric with initial data. @@ -117,25 +134,66 @@ func (m *metricDefaultMetric) init() { m.data.Sum().SetIsMonotonic(true) m.data.Sum().SetAggregationTemporality(pmetric.AggregationTemporalityCumulative) m.data.Sum().DataPoints().EnsureCapacity(m.capacity) + m.aggDataPoints = m.aggDataPoints[:0] } func (m *metricDefaultMetric) recordDataPoint(start pcommon.Timestamp, ts pcommon.Timestamp, val int64, stringAttrAttributeValue string, overriddenIntAttrAttributeValue int64, enumAttrAttributeValue string, sliceAttrAttributeValue []any, mapAttrAttributeValue map[string]any, optInBoolAttrAttributeValue bool, options ...MetricAttributeOption) { if !m.config.Enabled { return } - dp := m.data.Sum().DataPoints().AppendEmpty() + + dp := pmetric.NewNumberDataPoint() dp.SetStartTimestamp(start) dp.SetTimestamp(ts) - dp.SetIntValue(val) - dp.Attributes().PutStr("string_attr", stringAttrAttributeValue) - dp.Attributes().PutInt("state", overriddenIntAttrAttributeValue) - dp.Attributes().PutStr("enum_attr", enumAttrAttributeValue) - dp.Attributes().PutEmptySlice("slice_attr").FromRaw(sliceAttrAttributeValue) - dp.Attributes().PutEmptyMap("map_attr").FromRaw(mapAttrAttributeValue) - dp.Attributes().PutBool("opt_in_bool_attr", optInBoolAttrAttributeValue) + if slices.Contains(m.config.EnabledAttributes, DefaultMetricMetricAttributeKeyStringAttr) { + dp.Attributes().PutStr("string_attr", stringAttrAttributeValue) + } + if slices.Contains(m.config.EnabledAttributes, DefaultMetricMetricAttributeKeyOverriddenIntAttr) { + dp.Attributes().PutInt("state", overriddenIntAttrAttributeValue) + } + if slices.Contains(m.config.EnabledAttributes, DefaultMetricMetricAttributeKeyEnumAttr) { + dp.Attributes().PutStr("enum_attr", enumAttrAttributeValue) + } + if slices.Contains(m.config.EnabledAttributes, DefaultMetricMetricAttributeKeySliceAttr) { + dp.Attributes().PutEmptySlice("slice_attr").FromRaw(sliceAttrAttributeValue) + } + if slices.Contains(m.config.EnabledAttributes, DefaultMetricMetricAttributeKeyMapAttr) { + dp.Attributes().PutEmptyMap("map_attr").FromRaw(mapAttrAttributeValue) + } + if slices.Contains(m.config.EnabledAttributes, DefaultMetricMetricAttributeKeyOptInBoolAttr) { + dp.Attributes().PutBool("opt_in_bool_attr", optInBoolAttrAttributeValue) + } for _, op := range options { op.apply(dp) } + + var s string + dps := m.data.Sum().DataPoints() + for i := 0; i < dps.Len(); i++ { + dpi := dps.At(i) + if dp.Attributes().Equal(dpi.Attributes()) && dp.StartTimestamp() == dpi.StartTimestamp() && dp.Timestamp() == dpi.Timestamp() { + switch s = m.config.AggregationStrategy; s { + case AggregationStrategySum, AggregationStrategyAvg: + dpi.SetIntValue(dpi.IntValue() + val) + m.aggDataPoints[i] += 1 + return + case AggregationStrategyMin: + if dpi.IntValue() > val { + dpi.SetIntValue(val) + } + return + case AggregationStrategyMax: + if dpi.IntValue() < val { + dpi.SetIntValue(val) + } + return + } + } + } + + dp.SetIntValue(val) + m.aggDataPoints = append(m.aggDataPoints, 1) + dp.MoveTo(dps.AppendEmpty()) } // updateCapacity saves max length of data point slices that will be used for the slice capacity. @@ -148,14 +206,20 @@ func (m *metricDefaultMetric) updateCapacity() { // emit appends recorded metric data to a metrics slice and prepares it for recording another set of data points. func (m *metricDefaultMetric) emit(metrics pmetric.MetricSlice) { if m.config.Enabled && m.data.Sum().DataPoints().Len() > 0 { + if m.config.AggregationStrategy == AggregationStrategyAvg { + for i, aggCount := range m.aggDataPoints { + m.data.Sum().DataPoints().At(i).SetIntValue(m.data.Sum().DataPoints().At(i).IntValue() / aggCount) + } + } m.updateCapacity() m.data.MoveTo(metrics.AppendEmpty()) m.init() } } -func newMetricDefaultMetric(cfg MetricConfig) metricDefaultMetric { +func newMetricDefaultMetric(cfg DefaultMetricMetricConfig) metricDefaultMetric { m := metricDefaultMetric{config: cfg} + if cfg.Enabled { m.data = pmetric.NewMetric() m.init() @@ -164,9 +228,9 @@ func newMetricDefaultMetric(cfg MetricConfig) metricDefaultMetric { } type metricDefaultMetricToBeRemoved struct { - data pmetric.Metric // data buffer for generated metric. - config MetricConfig // metric config provided by user. - capacity int // max observed number of data points added to the metric. + data pmetric.Metric // data buffer for generated metric. + config DefaultMetricToBeRemovedMetricConfig // metric config provided by user. + capacity int // max observed number of data points added to the metric. } // init fills default.metric.to_be_removed metric with initial data. @@ -205,8 +269,9 @@ func (m *metricDefaultMetricToBeRemoved) emit(metrics pmetric.MetricSlice) { } } -func newMetricDefaultMetricToBeRemoved(cfg MetricConfig) metricDefaultMetricToBeRemoved { +func newMetricDefaultMetricToBeRemoved(cfg DefaultMetricToBeRemovedMetricConfig) metricDefaultMetricToBeRemoved { m := metricDefaultMetricToBeRemoved{config: cfg} + if cfg.Enabled { m.data = pmetric.NewMetric() m.init() @@ -215,9 +280,10 @@ func newMetricDefaultMetricToBeRemoved(cfg MetricConfig) metricDefaultMetricToBe } type metricMetricInputType struct { - data pmetric.Metric // data buffer for generated metric. - config MetricConfig // metric config provided by user. - capacity int // max observed number of data points added to the metric. + data pmetric.Metric // data buffer for generated metric. + config MetricInputTypeMetricConfig // metric config provided by user. + capacity int // max observed number of data points added to the metric. + aggDataPoints []int64 // slice containing number of aggregated datapoints at each index } // init fills metric.input_type metric with initial data. @@ -229,21 +295,60 @@ func (m *metricMetricInputType) init() { m.data.Sum().SetIsMonotonic(true) m.data.Sum().SetAggregationTemporality(pmetric.AggregationTemporalityCumulative) m.data.Sum().DataPoints().EnsureCapacity(m.capacity) + m.aggDataPoints = m.aggDataPoints[:0] } func (m *metricMetricInputType) recordDataPoint(start pcommon.Timestamp, ts pcommon.Timestamp, val int64, stringAttrAttributeValue string, overriddenIntAttrAttributeValue int64, enumAttrAttributeValue string, sliceAttrAttributeValue []any, mapAttrAttributeValue map[string]any) { if !m.config.Enabled { return } - dp := m.data.Sum().DataPoints().AppendEmpty() + + dp := pmetric.NewNumberDataPoint() dp.SetStartTimestamp(start) dp.SetTimestamp(ts) + if slices.Contains(m.config.EnabledAttributes, MetricInputTypeMetricAttributeKeyStringAttr) { + dp.Attributes().PutStr("string_attr", stringAttrAttributeValue) + } + if slices.Contains(m.config.EnabledAttributes, MetricInputTypeMetricAttributeKeyOverriddenIntAttr) { + dp.Attributes().PutInt("state", overriddenIntAttrAttributeValue) + } + if slices.Contains(m.config.EnabledAttributes, MetricInputTypeMetricAttributeKeyEnumAttr) { + dp.Attributes().PutStr("enum_attr", enumAttrAttributeValue) + } + if slices.Contains(m.config.EnabledAttributes, MetricInputTypeMetricAttributeKeySliceAttr) { + dp.Attributes().PutEmptySlice("slice_attr").FromRaw(sliceAttrAttributeValue) + } + if slices.Contains(m.config.EnabledAttributes, MetricInputTypeMetricAttributeKeyMapAttr) { + dp.Attributes().PutEmptyMap("map_attr").FromRaw(mapAttrAttributeValue) + } + + var s string + dps := m.data.Sum().DataPoints() + for i := 0; i < dps.Len(); i++ { + dpi := dps.At(i) + if dp.Attributes().Equal(dpi.Attributes()) && dp.StartTimestamp() == dpi.StartTimestamp() && dp.Timestamp() == dpi.Timestamp() { + switch s = m.config.AggregationStrategy; s { + case AggregationStrategySum, AggregationStrategyAvg: + dpi.SetIntValue(dpi.IntValue() + val) + m.aggDataPoints[i] += 1 + return + case AggregationStrategyMin: + if dpi.IntValue() > val { + dpi.SetIntValue(val) + } + return + case AggregationStrategyMax: + if dpi.IntValue() < val { + dpi.SetIntValue(val) + } + return + } + } + } + dp.SetIntValue(val) - dp.Attributes().PutStr("string_attr", stringAttrAttributeValue) - dp.Attributes().PutInt("state", overriddenIntAttrAttributeValue) - dp.Attributes().PutStr("enum_attr", enumAttrAttributeValue) - dp.Attributes().PutEmptySlice("slice_attr").FromRaw(sliceAttrAttributeValue) - dp.Attributes().PutEmptyMap("map_attr").FromRaw(mapAttrAttributeValue) + m.aggDataPoints = append(m.aggDataPoints, 1) + dp.MoveTo(dps.AppendEmpty()) } // updateCapacity saves max length of data point slices that will be used for the slice capacity. @@ -256,14 +361,20 @@ func (m *metricMetricInputType) updateCapacity() { // emit appends recorded metric data to a metrics slice and prepares it for recording another set of data points. func (m *metricMetricInputType) emit(metrics pmetric.MetricSlice) { if m.config.Enabled && m.data.Sum().DataPoints().Len() > 0 { + if m.config.AggregationStrategy == AggregationStrategyAvg { + for i, aggCount := range m.aggDataPoints { + m.data.Sum().DataPoints().At(i).SetIntValue(m.data.Sum().DataPoints().At(i).IntValue() / aggCount) + } + } m.updateCapacity() m.data.MoveTo(metrics.AppendEmpty()) m.init() } } -func newMetricMetricInputType(cfg MetricConfig) metricMetricInputType { +func newMetricMetricInputType(cfg MetricInputTypeMetricConfig) metricMetricInputType { m := metricMetricInputType{config: cfg} + if cfg.Enabled { m.data = pmetric.NewMetric() m.init() @@ -272,9 +383,10 @@ func newMetricMetricInputType(cfg MetricConfig) metricMetricInputType { } type metricOptionalMetric struct { - data pmetric.Metric // data buffer for generated metric. - config MetricConfig // metric config provided by user. - capacity int // max observed number of data points added to the metric. + data pmetric.Metric // data buffer for generated metric. + config OptionalMetricMetricConfig // metric config provided by user. + capacity int // max observed number of data points added to the metric. + aggDataPoints []float64 // slice containing number of aggregated datapoints at each index } // init fills optional.metric metric with initial data. @@ -284,22 +396,57 @@ func (m *metricOptionalMetric) init() { m.data.SetUnit("1") m.data.SetEmptyGauge() m.data.Gauge().DataPoints().EnsureCapacity(m.capacity) + m.aggDataPoints = m.aggDataPoints[:0] } func (m *metricOptionalMetric) recordDataPoint(start pcommon.Timestamp, ts pcommon.Timestamp, val float64, stringAttrAttributeValue string, booleanAttrAttributeValue bool, booleanAttr2AttributeValue bool, options ...MetricAttributeOption) { if !m.config.Enabled { return } - dp := m.data.Gauge().DataPoints().AppendEmpty() + + dp := pmetric.NewNumberDataPoint() dp.SetStartTimestamp(start) dp.SetTimestamp(ts) - dp.SetDoubleValue(val) - dp.Attributes().PutStr("string_attr", stringAttrAttributeValue) - dp.Attributes().PutBool("boolean_attr", booleanAttrAttributeValue) - dp.Attributes().PutBool("boolean_attr2", booleanAttr2AttributeValue) + if slices.Contains(m.config.EnabledAttributes, OptionalMetricMetricAttributeKeyStringAttr) { + dp.Attributes().PutStr("string_attr", stringAttrAttributeValue) + } + if slices.Contains(m.config.EnabledAttributes, OptionalMetricMetricAttributeKeyBooleanAttr) { + dp.Attributes().PutBool("boolean_attr", booleanAttrAttributeValue) + } + if slices.Contains(m.config.EnabledAttributes, OptionalMetricMetricAttributeKeyBooleanAttr2) { + dp.Attributes().PutBool("boolean_attr2", booleanAttr2AttributeValue) + } for _, op := range options { op.apply(dp) } + + var s string + dps := m.data.Gauge().DataPoints() + for i := 0; i < dps.Len(); i++ { + dpi := dps.At(i) + if dp.Attributes().Equal(dpi.Attributes()) && dp.StartTimestamp() == dpi.StartTimestamp() && dp.Timestamp() == dpi.Timestamp() { + switch s = m.config.AggregationStrategy; s { + case AggregationStrategySum, AggregationStrategyAvg: + dpi.SetDoubleValue(dpi.DoubleValue() + val) + m.aggDataPoints[i] += 1 + return + case AggregationStrategyMin: + if dpi.DoubleValue() > val { + dpi.SetDoubleValue(val) + } + return + case AggregationStrategyMax: + if dpi.DoubleValue() < val { + dpi.SetDoubleValue(val) + } + return + } + } + } + + dp.SetDoubleValue(val) + m.aggDataPoints = append(m.aggDataPoints, 1) + dp.MoveTo(dps.AppendEmpty()) } // updateCapacity saves max length of data point slices that will be used for the slice capacity. @@ -312,14 +459,20 @@ func (m *metricOptionalMetric) updateCapacity() { // emit appends recorded metric data to a metrics slice and prepares it for recording another set of data points. func (m *metricOptionalMetric) emit(metrics pmetric.MetricSlice) { if m.config.Enabled && m.data.Gauge().DataPoints().Len() > 0 { + if m.config.AggregationStrategy == AggregationStrategyAvg { + for i, aggCount := range m.aggDataPoints { + m.data.Gauge().DataPoints().At(i).SetDoubleValue(m.data.Gauge().DataPoints().At(i).DoubleValue() / aggCount) + } + } m.updateCapacity() m.data.MoveTo(metrics.AppendEmpty()) m.init() } } -func newMetricOptionalMetric(cfg MetricConfig) metricOptionalMetric { +func newMetricOptionalMetric(cfg OptionalMetricMetricConfig) metricOptionalMetric { m := metricOptionalMetric{config: cfg} + if cfg.Enabled { m.data = pmetric.NewMetric() m.init() @@ -328,9 +481,10 @@ func newMetricOptionalMetric(cfg MetricConfig) metricOptionalMetric { } type metricOptionalMetricEmptyUnit struct { - data pmetric.Metric // data buffer for generated metric. - config MetricConfig // metric config provided by user. - capacity int // max observed number of data points added to the metric. + data pmetric.Metric // data buffer for generated metric. + config OptionalMetricEmptyUnitMetricConfig // metric config provided by user. + capacity int // max observed number of data points added to the metric. + aggDataPoints []float64 // slice containing number of aggregated datapoints at each index } // init fills optional.metric.empty_unit metric with initial data. @@ -340,18 +494,51 @@ func (m *metricOptionalMetricEmptyUnit) init() { m.data.SetUnit("") m.data.SetEmptyGauge() m.data.Gauge().DataPoints().EnsureCapacity(m.capacity) + m.aggDataPoints = m.aggDataPoints[:0] } func (m *metricOptionalMetricEmptyUnit) recordDataPoint(start pcommon.Timestamp, ts pcommon.Timestamp, val float64, stringAttrAttributeValue string, booleanAttrAttributeValue bool) { if !m.config.Enabled { return } - dp := m.data.Gauge().DataPoints().AppendEmpty() + + dp := pmetric.NewNumberDataPoint() dp.SetStartTimestamp(start) dp.SetTimestamp(ts) + if slices.Contains(m.config.EnabledAttributes, OptionalMetricEmptyUnitMetricAttributeKeyStringAttr) { + dp.Attributes().PutStr("string_attr", stringAttrAttributeValue) + } + if slices.Contains(m.config.EnabledAttributes, OptionalMetricEmptyUnitMetricAttributeKeyBooleanAttr) { + dp.Attributes().PutBool("boolean_attr", booleanAttrAttributeValue) + } + + var s string + dps := m.data.Gauge().DataPoints() + for i := 0; i < dps.Len(); i++ { + dpi := dps.At(i) + if dp.Attributes().Equal(dpi.Attributes()) && dp.StartTimestamp() == dpi.StartTimestamp() && dp.Timestamp() == dpi.Timestamp() { + switch s = m.config.AggregationStrategy; s { + case AggregationStrategySum, AggregationStrategyAvg: + dpi.SetDoubleValue(dpi.DoubleValue() + val) + m.aggDataPoints[i] += 1 + return + case AggregationStrategyMin: + if dpi.DoubleValue() > val { + dpi.SetDoubleValue(val) + } + return + case AggregationStrategyMax: + if dpi.DoubleValue() < val { + dpi.SetDoubleValue(val) + } + return + } + } + } + dp.SetDoubleValue(val) - dp.Attributes().PutStr("string_attr", stringAttrAttributeValue) - dp.Attributes().PutBool("boolean_attr", booleanAttrAttributeValue) + m.aggDataPoints = append(m.aggDataPoints, 1) + dp.MoveTo(dps.AppendEmpty()) } // updateCapacity saves max length of data point slices that will be used for the slice capacity. @@ -364,14 +551,207 @@ func (m *metricOptionalMetricEmptyUnit) updateCapacity() { // emit appends recorded metric data to a metrics slice and prepares it for recording another set of data points. func (m *metricOptionalMetricEmptyUnit) emit(metrics pmetric.MetricSlice) { if m.config.Enabled && m.data.Gauge().DataPoints().Len() > 0 { + if m.config.AggregationStrategy == AggregationStrategyAvg { + for i, aggCount := range m.aggDataPoints { + m.data.Gauge().DataPoints().At(i).SetDoubleValue(m.data.Gauge().DataPoints().At(i).DoubleValue() / aggCount) + } + } m.updateCapacity() m.data.MoveTo(metrics.AppendEmpty()) m.init() } } -func newMetricOptionalMetricEmptyUnit(cfg MetricConfig) metricOptionalMetricEmptyUnit { +func newMetricOptionalMetricEmptyUnit(cfg OptionalMetricEmptyUnitMetricConfig) metricOptionalMetricEmptyUnit { m := metricOptionalMetricEmptyUnit{config: cfg} + + if cfg.Enabled { + m.data = pmetric.NewMetric() + m.init() + } + return m +} + +type metricReaggregateMetric struct { + data pmetric.Metric // data buffer for generated metric. + config ReaggregateMetricMetricConfig // metric config provided by user. + capacity int // max observed number of data points added to the metric. + aggDataPoints []float64 // slice containing number of aggregated datapoints at each index +} + +// init fills reaggregate.metric metric with initial data. +func (m *metricReaggregateMetric) init() { + m.data.SetName("reaggregate.metric") + m.data.SetDescription("Metric for testing spatial reaggregation") + m.data.SetUnit("1") + m.data.SetEmptyGauge() + m.data.Gauge().DataPoints().EnsureCapacity(m.capacity) + m.aggDataPoints = m.aggDataPoints[:0] +} + +func (m *metricReaggregateMetric) recordDataPoint(start pcommon.Timestamp, ts pcommon.Timestamp, val float64, stringAttrAttributeValue string, booleanAttrAttributeValue bool) { + if !m.config.Enabled { + return + } + + dp := pmetric.NewNumberDataPoint() + dp.SetStartTimestamp(start) + dp.SetTimestamp(ts) + if slices.Contains(m.config.EnabledAttributes, ReaggregateMetricMetricAttributeKeyStringAttr) { + dp.Attributes().PutStr("string_attr", stringAttrAttributeValue) + } + if slices.Contains(m.config.EnabledAttributes, ReaggregateMetricMetricAttributeKeyBooleanAttr) { + dp.Attributes().PutBool("boolean_attr", booleanAttrAttributeValue) + } + + var s string + dps := m.data.Gauge().DataPoints() + for i := 0; i < dps.Len(); i++ { + dpi := dps.At(i) + if dp.Attributes().Equal(dpi.Attributes()) && dp.StartTimestamp() == dpi.StartTimestamp() && dp.Timestamp() == dpi.Timestamp() { + switch s = m.config.AggregationStrategy; s { + case AggregationStrategySum, AggregationStrategyAvg: + dpi.SetDoubleValue(dpi.DoubleValue() + val) + m.aggDataPoints[i] += 1 + return + case AggregationStrategyMin: + if dpi.DoubleValue() > val { + dpi.SetDoubleValue(val) + } + return + case AggregationStrategyMax: + if dpi.DoubleValue() < val { + dpi.SetDoubleValue(val) + } + return + } + } + } + + dp.SetDoubleValue(val) + m.aggDataPoints = append(m.aggDataPoints, 1) + dp.MoveTo(dps.AppendEmpty()) +} + +// updateCapacity saves max length of data point slices that will be used for the slice capacity. +func (m *metricReaggregateMetric) updateCapacity() { + if m.data.Gauge().DataPoints().Len() > m.capacity { + m.capacity = m.data.Gauge().DataPoints().Len() + } +} + +// emit appends recorded metric data to a metrics slice and prepares it for recording another set of data points. +func (m *metricReaggregateMetric) emit(metrics pmetric.MetricSlice) { + if m.config.Enabled && m.data.Gauge().DataPoints().Len() > 0 { + if m.config.AggregationStrategy == AggregationStrategyAvg { + for i, aggCount := range m.aggDataPoints { + m.data.Gauge().DataPoints().At(i).SetDoubleValue(m.data.Gauge().DataPoints().At(i).DoubleValue() / aggCount) + } + } + m.updateCapacity() + m.data.MoveTo(metrics.AppendEmpty()) + m.init() + } +} + +func newMetricReaggregateMetric(cfg ReaggregateMetricMetricConfig) metricReaggregateMetric { + m := metricReaggregateMetric{config: cfg} + + if cfg.Enabled { + m.data = pmetric.NewMetric() + m.init() + } + return m +} + +type metricReaggregateMetricWithRequired struct { + data pmetric.Metric // data buffer for generated metric. + config ReaggregateMetricWithRequiredMetricConfig // metric config provided by user. + capacity int // max observed number of data points added to the metric. + aggDataPoints []float64 // slice containing number of aggregated datapoints at each index +} + +// init fills reaggregate.metric.with_required metric with initial data. +func (m *metricReaggregateMetricWithRequired) init() { + m.data.SetName("reaggregate.metric.with_required") + m.data.SetDescription("Metric for testing spatial reaggregation with required attributes") + m.data.SetUnit("1") + m.data.SetEmptyGauge() + m.data.Gauge().DataPoints().EnsureCapacity(m.capacity) + m.aggDataPoints = m.aggDataPoints[:0] +} + +func (m *metricReaggregateMetricWithRequired) recordDataPoint(start pcommon.Timestamp, ts pcommon.Timestamp, val float64, requiredStringAttrAttributeValue string, stringAttrAttributeValue string, booleanAttrAttributeValue bool) { + if !m.config.Enabled { + return + } + + dp := pmetric.NewNumberDataPoint() + dp.SetStartTimestamp(start) + dp.SetTimestamp(ts) + if slices.Contains(m.config.EnabledAttributes, ReaggregateMetricWithRequiredMetricAttributeKeyRequiredStringAttr) { + dp.Attributes().PutStr("required_string_attr", requiredStringAttrAttributeValue) + } + if slices.Contains(m.config.EnabledAttributes, ReaggregateMetricWithRequiredMetricAttributeKeyStringAttr) { + dp.Attributes().PutStr("string_attr", stringAttrAttributeValue) + } + if slices.Contains(m.config.EnabledAttributes, ReaggregateMetricWithRequiredMetricAttributeKeyBooleanAttr) { + dp.Attributes().PutBool("boolean_attr", booleanAttrAttributeValue) + } + + var s string + dps := m.data.Gauge().DataPoints() + for i := 0; i < dps.Len(); i++ { + dpi := dps.At(i) + if dp.Attributes().Equal(dpi.Attributes()) && dp.StartTimestamp() == dpi.StartTimestamp() && dp.Timestamp() == dpi.Timestamp() { + switch s = m.config.AggregationStrategy; s { + case AggregationStrategySum, AggregationStrategyAvg: + dpi.SetDoubleValue(dpi.DoubleValue() + val) + m.aggDataPoints[i] += 1 + return + case AggregationStrategyMin: + if dpi.DoubleValue() > val { + dpi.SetDoubleValue(val) + } + return + case AggregationStrategyMax: + if dpi.DoubleValue() < val { + dpi.SetDoubleValue(val) + } + return + } + } + } + + dp.SetDoubleValue(val) + m.aggDataPoints = append(m.aggDataPoints, 1) + dp.MoveTo(dps.AppendEmpty()) +} + +// updateCapacity saves max length of data point slices that will be used for the slice capacity. +func (m *metricReaggregateMetricWithRequired) updateCapacity() { + if m.data.Gauge().DataPoints().Len() > m.capacity { + m.capacity = m.data.Gauge().DataPoints().Len() + } +} + +// emit appends recorded metric data to a metrics slice and prepares it for recording another set of data points. +func (m *metricReaggregateMetricWithRequired) emit(metrics pmetric.MetricSlice) { + if m.config.Enabled && m.data.Gauge().DataPoints().Len() > 0 { + if m.config.AggregationStrategy == AggregationStrategyAvg { + for i, aggCount := range m.aggDataPoints { + m.data.Gauge().DataPoints().At(i).SetDoubleValue(m.data.Gauge().DataPoints().At(i).DoubleValue() / aggCount) + } + } + m.updateCapacity() + m.data.MoveTo(metrics.AppendEmpty()) + m.init() + } +} + +func newMetricReaggregateMetricWithRequired(cfg ReaggregateMetricWithRequiredMetricConfig) metricReaggregateMetricWithRequired { + m := metricReaggregateMetricWithRequired{config: cfg} + if cfg.Enabled { m.data = pmetric.NewMetric() m.init() @@ -380,9 +760,9 @@ func newMetricOptionalMetricEmptyUnit(cfg MetricConfig) metricOptionalMetricEmpt } type metricSystemCPUTime struct { - data pmetric.Metric // data buffer for generated metric. - config MetricConfig // metric config provided by user. - capacity int // max observed number of data points added to the metric. + data pmetric.Metric // data buffer for generated metric. + config SystemCPUTimeMetricConfig // metric config provided by user. + capacity int // max observed number of data points added to the metric. } // init fills system.cpu.time metric with initial data. @@ -421,8 +801,9 @@ func (m *metricSystemCPUTime) emit(metrics pmetric.MetricSlice) { } } -func newMetricSystemCPUTime(cfg MetricConfig) metricSystemCPUTime { +func newMetricSystemCPUTime(cfg SystemCPUTimeMetricConfig) metricSystemCPUTime { m := metricSystemCPUTime{config: cfg} + if cfg.Enabled { m.data = pmetric.NewMetric() m.init() @@ -433,19 +814,21 @@ func newMetricSystemCPUTime(cfg MetricConfig) metricSystemCPUTime { // MetricsBuilder provides an interface for scrapers to report metrics while taking care of all the transformations // required to produce metric representation defined in metadata and user config. type MetricsBuilder struct { - config MetricsBuilderConfig // config of the metrics builder. - startTime pcommon.Timestamp // start time that will be applied to all recorded data points. - metricsCapacity int // maximum observed number of metrics per resource. - metricsBuffer pmetric.Metrics // accumulates metrics data before emitting. - buildInfo component.BuildInfo // contains version information. - resourceAttributeIncludeFilter map[string]filter.Filter - resourceAttributeExcludeFilter map[string]filter.Filter - metricDefaultMetric metricDefaultMetric - metricDefaultMetricToBeRemoved metricDefaultMetricToBeRemoved - metricMetricInputType metricMetricInputType - metricOptionalMetric metricOptionalMetric - metricOptionalMetricEmptyUnit metricOptionalMetricEmptyUnit - metricSystemCPUTime metricSystemCPUTime + config MetricsBuilderConfig // config of the metrics builder. + startTime pcommon.Timestamp // start time that will be applied to all recorded data points. + metricsCapacity int // maximum observed number of metrics per resource. + metricsBuffer pmetric.Metrics // accumulates metrics data before emitting. + buildInfo component.BuildInfo // contains version information. + resourceAttributeIncludeFilter map[string]filter.Filter + resourceAttributeExcludeFilter map[string]filter.Filter + metricDefaultMetric metricDefaultMetric + metricDefaultMetricToBeRemoved metricDefaultMetricToBeRemoved + metricMetricInputType metricMetricInputType + metricOptionalMetric metricOptionalMetric + metricOptionalMetricEmptyUnit metricOptionalMetricEmptyUnit + metricReaggregateMetric metricReaggregateMetric + metricReaggregateMetricWithRequired metricReaggregateMetricWithRequired + metricSystemCPUTime metricSystemCPUTime } // MetricBuilderOption applies changes to default metrics builder. @@ -488,18 +871,20 @@ func NewMetricsBuilder(mbc MetricsBuilderConfig, settings receiver.Settings, opt settings.Logger.Warn("[WARNING] `string.resource.attr_to_be_removed` should not be enabled: This resource_attribute is deprecated and will be removed soon.") } mb := &MetricsBuilder{ - config: mbc, - startTime: pcommon.NewTimestampFromTime(time.Now()), - metricsBuffer: pmetric.NewMetrics(), - buildInfo: settings.BuildInfo, - metricDefaultMetric: newMetricDefaultMetric(mbc.Metrics.DefaultMetric), - metricDefaultMetricToBeRemoved: newMetricDefaultMetricToBeRemoved(mbc.Metrics.DefaultMetricToBeRemoved), - metricMetricInputType: newMetricMetricInputType(mbc.Metrics.MetricInputType), - metricOptionalMetric: newMetricOptionalMetric(mbc.Metrics.OptionalMetric), - metricOptionalMetricEmptyUnit: newMetricOptionalMetricEmptyUnit(mbc.Metrics.OptionalMetricEmptyUnit), - metricSystemCPUTime: newMetricSystemCPUTime(mbc.Metrics.SystemCPUTime), - resourceAttributeIncludeFilter: make(map[string]filter.Filter), - resourceAttributeExcludeFilter: make(map[string]filter.Filter), + config: mbc, + startTime: pcommon.NewTimestampFromTime(time.Now()), + metricsBuffer: pmetric.NewMetrics(), + buildInfo: settings.BuildInfo, + metricDefaultMetric: newMetricDefaultMetric(mbc.Metrics.DefaultMetric), + metricDefaultMetricToBeRemoved: newMetricDefaultMetricToBeRemoved(mbc.Metrics.DefaultMetricToBeRemoved), + metricMetricInputType: newMetricMetricInputType(mbc.Metrics.MetricInputType), + metricOptionalMetric: newMetricOptionalMetric(mbc.Metrics.OptionalMetric), + metricOptionalMetricEmptyUnit: newMetricOptionalMetricEmptyUnit(mbc.Metrics.OptionalMetricEmptyUnit), + metricReaggregateMetric: newMetricReaggregateMetric(mbc.Metrics.ReaggregateMetric), + metricReaggregateMetricWithRequired: newMetricReaggregateMetricWithRequired(mbc.Metrics.ReaggregateMetricWithRequired), + metricSystemCPUTime: newMetricSystemCPUTime(mbc.Metrics.SystemCPUTime), + resourceAttributeIncludeFilter: make(map[string]filter.Filter), + resourceAttributeExcludeFilter: make(map[string]filter.Filter), } if mbc.ResourceAttributes.MapResourceAttr.MetricsInclude != nil { mb.resourceAttributeIncludeFilter["map.resource.attr"] = filter.CreateFilter(mbc.ResourceAttributes.MapResourceAttr.MetricsInclude) @@ -624,6 +1009,8 @@ func (mb *MetricsBuilder) EmitForResource(options ...ResourceMetricsOption) { mb.metricMetricInputType.emit(ils.Metrics()) mb.metricOptionalMetric.emit(ils.Metrics()) mb.metricOptionalMetricEmptyUnit.emit(ils.Metrics()) + mb.metricReaggregateMetric.emit(ils.Metrics()) + mb.metricReaggregateMetricWithRequired.emit(ils.Metrics()) mb.metricSystemCPUTime.emit(ils.Metrics()) for _, op := range options { @@ -686,6 +1073,16 @@ func (mb *MetricsBuilder) RecordOptionalMetricEmptyUnitDataPoint(ts pcommon.Time mb.metricOptionalMetricEmptyUnit.recordDataPoint(mb.startTime, ts, val, stringAttrAttributeValue, booleanAttrAttributeValue) } +// RecordReaggregateMetricDataPoint adds a data point to reaggregate.metric metric. +func (mb *MetricsBuilder) RecordReaggregateMetricDataPoint(ts pcommon.Timestamp, val float64, stringAttrAttributeValue string, booleanAttrAttributeValue bool) { + mb.metricReaggregateMetric.recordDataPoint(mb.startTime, ts, val, stringAttrAttributeValue, booleanAttrAttributeValue) +} + +// RecordReaggregateMetricWithRequiredDataPoint adds a data point to reaggregate.metric.with_required metric. +func (mb *MetricsBuilder) RecordReaggregateMetricWithRequiredDataPoint(ts pcommon.Timestamp, val float64, requiredStringAttrAttributeValue string, stringAttrAttributeValue string, booleanAttrAttributeValue bool) { + mb.metricReaggregateMetricWithRequired.recordDataPoint(mb.startTime, ts, val, requiredStringAttrAttributeValue, stringAttrAttributeValue, booleanAttrAttributeValue) +} + // RecordSystemCPUTimeDataPoint adds a data point to system.cpu.time metric. func (mb *MetricsBuilder) RecordSystemCPUTimeDataPoint(ts pcommon.Timestamp, val int64) { mb.metricSystemCPUTime.recordDataPoint(mb.startTime, ts, val) diff --git a/cmd/mdatagen/internal/samplereceiver/internal/metadata/generated_metrics_test.go b/cmd/mdatagen/internal/samplereceiver/internal/metadata/generated_metrics_test.go index b0dc2ce98b10..fa7064e63fbc 100644 --- a/cmd/mdatagen/internal/samplereceiver/internal/metadata/generated_metrics_test.go +++ b/cmd/mdatagen/internal/samplereceiver/internal/metadata/generated_metrics_test.go @@ -20,6 +20,7 @@ const ( testDataSetDefault testDataSet = iota testDataSetAll testDataSetNone + testDataSetReag ) func TestMetricsBuilder(t *testing.T) { @@ -37,6 +38,11 @@ func TestMetricsBuilder(t *testing.T) { metricsSet: testDataSetAll, resAttrsSet: testDataSetAll, }, + { + name: "reaggregate_set", + metricsSet: testDataSetReag, + resAttrsSet: testDataSetReag, + }, { name: "none_set", metricsSet: testDataSetNone, @@ -61,6 +67,13 @@ func TestMetricsBuilder(t *testing.T) { settings := receivertest.NewNopSettings(receivertest.NopType) settings.Logger = zap.New(observedZapCore) mb := NewMetricsBuilder(loadMetricsBuilderConfig(t, tt.name), settings, WithStartTime(start)) + aggMap := make(map[string]string) // contains the aggregation strategies for each metric name + aggMap["DefaultMetric"] = mb.metricDefaultMetric.config.AggregationStrategy + aggMap["MetricInputType"] = mb.metricMetricInputType.config.AggregationStrategy + aggMap["OptionalMetric"] = mb.metricOptionalMetric.config.AggregationStrategy + aggMap["OptionalMetricEmptyUnit"] = mb.metricOptionalMetricEmptyUnit.config.AggregationStrategy + aggMap["ReaggregateMetric"] = mb.metricReaggregateMetric.config.AggregationStrategy + aggMap["ReaggregateMetricWithRequired"] = mb.metricReaggregateMetricWithRequired.config.AggregationStrategy expectedWarnings := 0 if tt.metricsSet == testDataSetDefault { @@ -91,8 +104,9 @@ func TestMetricsBuilder(t *testing.T) { assert.Equal(t, "[WARNING] `string.resource.attr_to_be_removed` should not be enabled: This resource_attribute is deprecated and will be removed soon.", observedLogs.All()[expectedWarnings].Message) expectedWarnings++ } - - assert.Equal(t, expectedWarnings, observedLogs.Len()) + if tt.metricsSet != testDataSetReag { + assert.Equal(t, expectedWarnings, observedLogs.Len()) + } defaultMetricsCount := 0 allMetricsCount := 0 @@ -100,6 +114,9 @@ func TestMetricsBuilder(t *testing.T) { defaultMetricsCount++ allMetricsCount++ mb.RecordDefaultMetricDataPoint(ts, 1, "string_attr-val", 19, AttributeEnumAttrRed, []any{"slice_attr-item1", "slice_attr-item2"}, map[string]any{"key1": "map_attr-val1", "key2": "map_attr-val2"}, true, WithConditionalIntAttrMetricAttribute(20), WithConditionalStringAttrMetricAttribute("conditional_string_attr-val")) + if tt.name == "reaggregate_set" { + mb.RecordDefaultMetricDataPoint(ts, 3, "string_attr-val-2", 20, AttributeEnumAttrGreen, []any{"slice_attr-item3", "slice_attr-item4"}, map[string]any{"key3": "map_attr-val3", "key4": "map_attr-val4"}, false, WithConditionalIntAttrMetricAttribute(20), WithConditionalStringAttrMetricAttribute("conditional_string_attr-val")) + } defaultMetricsCount++ allMetricsCount++ @@ -108,12 +125,35 @@ func TestMetricsBuilder(t *testing.T) { defaultMetricsCount++ allMetricsCount++ mb.RecordMetricInputTypeDataPoint(ts, "1", "string_attr-val", 19, AttributeEnumAttrRed, []any{"slice_attr-item1", "slice_attr-item2"}, map[string]any{"key1": "map_attr-val1", "key2": "map_attr-val2"}) + if tt.name == "reaggregate_set" { + mb.RecordMetricInputTypeDataPoint(ts, "3", "string_attr-val-2", 20, AttributeEnumAttrGreen, []any{"slice_attr-item3", "slice_attr-item4"}, map[string]any{"key3": "map_attr-val3", "key4": "map_attr-val4"}) + } allMetricsCount++ mb.RecordOptionalMetricDataPoint(ts, 1, "string_attr-val", true, false, WithConditionalStringAttrMetricAttribute("conditional_string_attr-val")) + if tt.name == "reaggregate_set" { + mb.RecordOptionalMetricDataPoint(ts, 3, "string_attr-val-2", false, true, WithConditionalStringAttrMetricAttribute("conditional_string_attr-val")) + } allMetricsCount++ mb.RecordOptionalMetricEmptyUnitDataPoint(ts, 1, "string_attr-val", true) + if tt.name == "reaggregate_set" { + mb.RecordOptionalMetricEmptyUnitDataPoint(ts, 3, "string_attr-val-2", false) + } + + defaultMetricsCount++ + allMetricsCount++ + mb.RecordReaggregateMetricDataPoint(ts, 1, "string_attr-val", true) + if tt.name == "reaggregate_set" { + mb.RecordReaggregateMetricDataPoint(ts, 3, "string_attr-val-2", false) + } + + defaultMetricsCount++ + allMetricsCount++ + mb.RecordReaggregateMetricWithRequiredDataPoint(ts, 1, "required_string_attr-val", "string_attr-val", true) + if tt.name == "reaggregate_set" { + mb.RecordReaggregateMetricWithRequiredDataPoint(ts, 3, "required_string_attr-val", "string_attr-val-2", false) + } defaultMetricsCount++ allMetricsCount++ @@ -130,159 +170,393 @@ func TestMetricsBuilder(t *testing.T) { rb.SetStringResourceAttrToBeRemoved("string.resource.attr_to_be_removed-val") res := rb.Emit() metrics := mb.Emit(WithResource(res)) + if tt.name == "reaggregate_set" { + assert.Empty(t, mb.metricDefaultMetric.aggDataPoints) + assert.Empty(t, mb.metricMetricInputType.aggDataPoints) + assert.Empty(t, mb.metricOptionalMetric.aggDataPoints) + assert.Empty(t, mb.metricOptionalMetricEmptyUnit.aggDataPoints) + assert.Empty(t, mb.metricReaggregateMetric.aggDataPoints) + assert.Empty(t, mb.metricReaggregateMetricWithRequired.aggDataPoints) + } if tt.expectEmpty { assert.Equal(t, 0, metrics.ResourceMetrics().Len()) return } - assert.Equal(t, 1, metrics.ResourceMetrics().Len()) - rm := metrics.ResourceMetrics().At(0) - assert.Equal(t, res, rm.Resource()) - assert.Equal(t, 1, rm.ScopeMetrics().Len()) - ms := rm.ScopeMetrics().At(0).Metrics() + var allMetricsList []pmetric.Metric + totalMetricsCount := 0 + for ri := 0; ri < metrics.ResourceMetrics().Len(); ri++ { + rm := metrics.ResourceMetrics().At(ri) + assert.Equal(t, 1, rm.ScopeMetrics().Len()) + ms := rm.ScopeMetrics().At(0).Metrics() + totalMetricsCount += ms.Len() + for mi := 0; mi < ms.Len(); mi++ { + allMetricsList = append(allMetricsList, ms.At(mi)) + } + } if tt.metricsSet == testDataSetDefault { - assert.Equal(t, defaultMetricsCount, ms.Len()) + assert.Equal(t, defaultMetricsCount, totalMetricsCount) } if tt.metricsSet == testDataSetAll { - assert.Equal(t, allMetricsCount, ms.Len()) + assert.Equal(t, allMetricsCount, totalMetricsCount) } validatedMetrics := make(map[string]bool) - for i := 0; i < ms.Len(); i++ { - switch ms.At(i).Name() { + for _, mi := range allMetricsList { + switch mi.Name() { case "default.metric": - assert.False(t, validatedMetrics["default.metric"], "Found a duplicate in the metrics slice: default.metric") - validatedMetrics["default.metric"] = true - assert.Equal(t, pmetric.MetricTypeSum, ms.At(i).Type()) - assert.Equal(t, 1, ms.At(i).Sum().DataPoints().Len()) - assert.Equal(t, "Monotonic cumulative sum int metric enabled by default.", ms.At(i).Description()) - assert.Equal(t, "s", ms.At(i).Unit()) - assert.True(t, ms.At(i).Sum().IsMonotonic()) - assert.Equal(t, pmetric.AggregationTemporalityCumulative, ms.At(i).Sum().AggregationTemporality()) - dp := ms.At(i).Sum().DataPoints().At(0) - assert.Equal(t, start, dp.StartTimestamp()) - assert.Equal(t, ts, dp.Timestamp()) - assert.Equal(t, pmetric.NumberDataPointValueTypeInt, dp.ValueType()) - assert.Equal(t, int64(1), dp.IntValue()) - attrVal, ok := dp.Attributes().Get("string_attr") - assert.True(t, ok) - assert.Equal(t, "string_attr-val", attrVal.Str()) - attrVal, ok = dp.Attributes().Get("state") - assert.True(t, ok) - assert.EqualValues(t, 19, attrVal.Int()) - attrVal, ok = dp.Attributes().Get("enum_attr") - assert.True(t, ok) - assert.Equal(t, "red", attrVal.Str()) - attrVal, ok = dp.Attributes().Get("slice_attr") - assert.True(t, ok) - assert.Equal(t, []any{"slice_attr-item1", "slice_attr-item2"}, attrVal.Slice().AsRaw()) - attrVal, ok = dp.Attributes().Get("map_attr") - assert.True(t, ok) - assert.Equal(t, map[string]any{"key1": "map_attr-val1", "key2": "map_attr-val2"}, attrVal.Map().AsRaw()) - attrVal, ok = dp.Attributes().Get("conditional_int_attr") - assert.True(t, ok) - assert.EqualValues(t, 20, attrVal.Int()) - attrVal, ok = dp.Attributes().Get("conditional_string_attr") - assert.True(t, ok) - assert.Equal(t, "conditional_string_attr-val", attrVal.Str()) - attrVal, ok = dp.Attributes().Get("opt_in_bool_attr") - assert.True(t, ok) - assert.True(t, attrVal.Bool()) + if tt.name != "reaggregate_set" { + assert.False(t, validatedMetrics["default.metric"], "Found a duplicate in the metrics slice: default.metric") + validatedMetrics["default.metric"] = true + assert.Equal(t, pmetric.MetricTypeSum, mi.Type()) + assert.Equal(t, 1, mi.Sum().DataPoints().Len()) + assert.Equal(t, "Monotonic cumulative sum int metric enabled by default.", mi.Description()) + assert.Equal(t, "s", mi.Unit()) + assert.True(t, mi.Sum().IsMonotonic()) + assert.Equal(t, pmetric.AggregationTemporalityCumulative, mi.Sum().AggregationTemporality()) + dp := mi.Sum().DataPoints().At(0) + assert.Equal(t, start, dp.StartTimestamp()) + assert.Equal(t, ts, dp.Timestamp()) + assert.Equal(t, pmetric.NumberDataPointValueTypeInt, dp.ValueType()) + assert.Equal(t, int64(1), dp.IntValue()) + attrVal, ok := dp.Attributes().Get("string_attr") + assert.True(t, ok) + assert.Equal(t, "string_attr-val", attrVal.Str()) + attrVal, ok = dp.Attributes().Get("state") + assert.True(t, ok) + assert.EqualValues(t, 19, attrVal.Int()) + attrVal, ok = dp.Attributes().Get("enum_attr") + assert.True(t, ok) + assert.Equal(t, "red", attrVal.Str()) + attrVal, ok = dp.Attributes().Get("slice_attr") + assert.True(t, ok) + assert.Equal(t, []any{"slice_attr-item1", "slice_attr-item2"}, attrVal.Slice().AsRaw()) + attrVal, ok = dp.Attributes().Get("map_attr") + assert.True(t, ok) + assert.Equal(t, map[string]any{"key1": "map_attr-val1", "key2": "map_attr-val2"}, attrVal.Map().AsRaw()) + attrVal, ok = dp.Attributes().Get("conditional_int_attr") + assert.True(t, ok) + assert.EqualValues(t, 20, attrVal.Int()) + attrVal, ok = dp.Attributes().Get("conditional_string_attr") + assert.True(t, ok) + assert.Equal(t, "conditional_string_attr-val", attrVal.Str()) + } else { + assert.False(t, validatedMetrics["default.metric"], "Found a duplicate in the metrics slice: default.metric") + validatedMetrics["default.metric"] = true + assert.Equal(t, pmetric.MetricTypeSum, mi.Type()) + assert.Equal(t, 1, mi.Sum().DataPoints().Len()) + assert.Equal(t, "Monotonic cumulative sum int metric enabled by default.", mi.Description()) + assert.Equal(t, "s", mi.Unit()) + assert.True(t, mi.Sum().IsMonotonic()) + assert.Equal(t, pmetric.AggregationTemporalityCumulative, mi.Sum().AggregationTemporality()) + dp := mi.Sum().DataPoints().At(0) + assert.Equal(t, start, dp.StartTimestamp()) + assert.Equal(t, ts, dp.Timestamp()) + assert.Equal(t, pmetric.NumberDataPointValueTypeInt, dp.ValueType()) + switch aggMap["default.metric"] { + case "sum": + assert.Equal(t, int64(4), dp.IntValue()) + case "avg": + assert.Equal(t, int64(2), dp.IntValue()) + case "min": + assert.Equal(t, int64(1), dp.IntValue()) + case "max": + assert.Equal(t, int64(3), dp.IntValue()) + } + _, ok := dp.Attributes().Get("string_attr") + assert.False(t, ok) + _, ok = dp.Attributes().Get("state") + assert.False(t, ok) + _, ok = dp.Attributes().Get("enum_attr") + assert.False(t, ok) + _, ok = dp.Attributes().Get("slice_attr") + assert.False(t, ok) + _, ok = dp.Attributes().Get("map_attr") + assert.False(t, ok) + _, ok = dp.Attributes().Get("opt_in_bool_attr") + assert.False(t, ok) + } case "default.metric.to_be_removed": assert.False(t, validatedMetrics["default.metric.to_be_removed"], "Found a duplicate in the metrics slice: default.metric.to_be_removed") validatedMetrics["default.metric.to_be_removed"] = true - assert.Equal(t, pmetric.MetricTypeSum, ms.At(i).Type()) - assert.Equal(t, 1, ms.At(i).Sum().DataPoints().Len()) - assert.Equal(t, "[DEPRECATED] Non-monotonic delta sum double metric enabled by default.", ms.At(i).Description()) - assert.Equal(t, "s", ms.At(i).Unit()) - assert.False(t, ms.At(i).Sum().IsMonotonic()) - assert.Equal(t, pmetric.AggregationTemporalityDelta, ms.At(i).Sum().AggregationTemporality()) - dp := ms.At(i).Sum().DataPoints().At(0) + assert.Equal(t, pmetric.MetricTypeSum, mi.Type()) + assert.Equal(t, 1, mi.Sum().DataPoints().Len()) + assert.Equal(t, "[DEPRECATED] Non-monotonic delta sum double metric enabled by default.", mi.Description()) + assert.Equal(t, "s", mi.Unit()) + assert.False(t, mi.Sum().IsMonotonic()) + assert.Equal(t, pmetric.AggregationTemporalityDelta, mi.Sum().AggregationTemporality()) + dp := mi.Sum().DataPoints().At(0) assert.Equal(t, start, dp.StartTimestamp()) assert.Equal(t, ts, dp.Timestamp()) assert.Equal(t, pmetric.NumberDataPointValueTypeDouble, dp.ValueType()) assert.InDelta(t, float64(1), dp.DoubleValue(), 0.01) case "metric.input_type": - assert.False(t, validatedMetrics["metric.input_type"], "Found a duplicate in the metrics slice: metric.input_type") - validatedMetrics["metric.input_type"] = true - assert.Equal(t, pmetric.MetricTypeSum, ms.At(i).Type()) - assert.Equal(t, 1, ms.At(i).Sum().DataPoints().Len()) - assert.Equal(t, "Monotonic cumulative sum int metric with string input_type enabled by default.", ms.At(i).Description()) - assert.Equal(t, "s", ms.At(i).Unit()) - assert.True(t, ms.At(i).Sum().IsMonotonic()) - assert.Equal(t, pmetric.AggregationTemporalityCumulative, ms.At(i).Sum().AggregationTemporality()) - dp := ms.At(i).Sum().DataPoints().At(0) - assert.Equal(t, start, dp.StartTimestamp()) - assert.Equal(t, ts, dp.Timestamp()) - assert.Equal(t, pmetric.NumberDataPointValueTypeInt, dp.ValueType()) - assert.Equal(t, int64(1), dp.IntValue()) - attrVal, ok := dp.Attributes().Get("string_attr") - assert.True(t, ok) - assert.Equal(t, "string_attr-val", attrVal.Str()) - attrVal, ok = dp.Attributes().Get("state") - assert.True(t, ok) - assert.EqualValues(t, 19, attrVal.Int()) - attrVal, ok = dp.Attributes().Get("enum_attr") - assert.True(t, ok) - assert.Equal(t, "red", attrVal.Str()) - attrVal, ok = dp.Attributes().Get("slice_attr") - assert.True(t, ok) - assert.Equal(t, []any{"slice_attr-item1", "slice_attr-item2"}, attrVal.Slice().AsRaw()) - attrVal, ok = dp.Attributes().Get("map_attr") - assert.True(t, ok) - assert.Equal(t, map[string]any{"key1": "map_attr-val1", "key2": "map_attr-val2"}, attrVal.Map().AsRaw()) + if tt.name != "reaggregate_set" { + assert.False(t, validatedMetrics["metric.input_type"], "Found a duplicate in the metrics slice: metric.input_type") + validatedMetrics["metric.input_type"] = true + assert.Equal(t, pmetric.MetricTypeSum, mi.Type()) + assert.Equal(t, 1, mi.Sum().DataPoints().Len()) + assert.Equal(t, "Monotonic cumulative sum int metric with string input_type enabled by default.", mi.Description()) + assert.Equal(t, "s", mi.Unit()) + assert.True(t, mi.Sum().IsMonotonic()) + assert.Equal(t, pmetric.AggregationTemporalityCumulative, mi.Sum().AggregationTemporality()) + dp := mi.Sum().DataPoints().At(0) + assert.Equal(t, start, dp.StartTimestamp()) + assert.Equal(t, ts, dp.Timestamp()) + assert.Equal(t, pmetric.NumberDataPointValueTypeInt, dp.ValueType()) + assert.Equal(t, int64(1), dp.IntValue()) + attrVal, ok := dp.Attributes().Get("string_attr") + assert.True(t, ok) + assert.Equal(t, "string_attr-val", attrVal.Str()) + attrVal, ok = dp.Attributes().Get("state") + assert.True(t, ok) + assert.EqualValues(t, 19, attrVal.Int()) + attrVal, ok = dp.Attributes().Get("enum_attr") + assert.True(t, ok) + assert.Equal(t, "red", attrVal.Str()) + attrVal, ok = dp.Attributes().Get("slice_attr") + assert.True(t, ok) + assert.Equal(t, []any{"slice_attr-item1", "slice_attr-item2"}, attrVal.Slice().AsRaw()) + attrVal, ok = dp.Attributes().Get("map_attr") + assert.True(t, ok) + assert.Equal(t, map[string]any{"key1": "map_attr-val1", "key2": "map_attr-val2"}, attrVal.Map().AsRaw()) + } else { + assert.False(t, validatedMetrics["metric.input_type"], "Found a duplicate in the metrics slice: metric.input_type") + validatedMetrics["metric.input_type"] = true + assert.Equal(t, pmetric.MetricTypeSum, mi.Type()) + assert.Equal(t, 1, mi.Sum().DataPoints().Len()) + assert.Equal(t, "Monotonic cumulative sum int metric with string input_type enabled by default.", mi.Description()) + assert.Equal(t, "s", mi.Unit()) + assert.True(t, mi.Sum().IsMonotonic()) + assert.Equal(t, pmetric.AggregationTemporalityCumulative, mi.Sum().AggregationTemporality()) + dp := mi.Sum().DataPoints().At(0) + assert.Equal(t, start, dp.StartTimestamp()) + assert.Equal(t, ts, dp.Timestamp()) + assert.Equal(t, pmetric.NumberDataPointValueTypeInt, dp.ValueType()) + switch aggMap["metric.input_type"] { + case "sum": + assert.Equal(t, int64(4), dp.IntValue()) + case "avg": + assert.Equal(t, int64(2), dp.IntValue()) + case "min": + assert.Equal(t, int64(1), dp.IntValue()) + case "max": + assert.Equal(t, int64(3), dp.IntValue()) + } + _, ok := dp.Attributes().Get("string_attr") + assert.False(t, ok) + _, ok = dp.Attributes().Get("state") + assert.False(t, ok) + _, ok = dp.Attributes().Get("enum_attr") + assert.False(t, ok) + _, ok = dp.Attributes().Get("slice_attr") + assert.False(t, ok) + _, ok = dp.Attributes().Get("map_attr") + assert.False(t, ok) + } case "optional.metric": - assert.False(t, validatedMetrics["optional.metric"], "Found a duplicate in the metrics slice: optional.metric") - validatedMetrics["optional.metric"] = true - assert.Equal(t, pmetric.MetricTypeGauge, ms.At(i).Type()) - assert.Equal(t, 1, ms.At(i).Gauge().DataPoints().Len()) - assert.Equal(t, "[DEPRECATED] Gauge double metric disabled by default.", ms.At(i).Description()) - assert.Equal(t, "1", ms.At(i).Unit()) - dp := ms.At(i).Gauge().DataPoints().At(0) - assert.Equal(t, start, dp.StartTimestamp()) - assert.Equal(t, ts, dp.Timestamp()) - assert.Equal(t, pmetric.NumberDataPointValueTypeDouble, dp.ValueType()) - assert.InDelta(t, float64(1), dp.DoubleValue(), 0.01) - attrVal, ok := dp.Attributes().Get("string_attr") - assert.True(t, ok) - assert.Equal(t, "string_attr-val", attrVal.Str()) - attrVal, ok = dp.Attributes().Get("boolean_attr") - assert.True(t, ok) - assert.True(t, attrVal.Bool()) - attrVal, ok = dp.Attributes().Get("boolean_attr2") - assert.True(t, ok) - assert.False(t, attrVal.Bool()) - attrVal, ok = dp.Attributes().Get("conditional_string_attr") - assert.True(t, ok) - assert.Equal(t, "conditional_string_attr-val", attrVal.Str()) + if tt.name != "reaggregate_set" { + assert.False(t, validatedMetrics["optional.metric"], "Found a duplicate in the metrics slice: optional.metric") + validatedMetrics["optional.metric"] = true + assert.Equal(t, pmetric.MetricTypeGauge, mi.Type()) + assert.Equal(t, 1, mi.Gauge().DataPoints().Len()) + assert.Equal(t, "[DEPRECATED] Gauge double metric disabled by default.", mi.Description()) + assert.Equal(t, "1", mi.Unit()) + dp := mi.Gauge().DataPoints().At(0) + assert.Equal(t, start, dp.StartTimestamp()) + assert.Equal(t, ts, dp.Timestamp()) + assert.Equal(t, pmetric.NumberDataPointValueTypeDouble, dp.ValueType()) + assert.InDelta(t, float64(1), dp.DoubleValue(), 0.01) + attrVal, ok := dp.Attributes().Get("string_attr") + assert.True(t, ok) + assert.Equal(t, "string_attr-val", attrVal.Str()) + attrVal, ok = dp.Attributes().Get("boolean_attr") + assert.True(t, ok) + assert.True(t, attrVal.Bool()) + attrVal, ok = dp.Attributes().Get("boolean_attr2") + assert.True(t, ok) + assert.False(t, attrVal.Bool()) + attrVal, ok = dp.Attributes().Get("conditional_string_attr") + assert.True(t, ok) + assert.Equal(t, "conditional_string_attr-val", attrVal.Str()) + } else { + assert.False(t, validatedMetrics["optional.metric"], "Found a duplicate in the metrics slice: optional.metric") + validatedMetrics["optional.metric"] = true + assert.Equal(t, pmetric.MetricTypeGauge, mi.Type()) + assert.Equal(t, 1, mi.Gauge().DataPoints().Len()) + assert.Equal(t, "[DEPRECATED] Gauge double metric disabled by default.", mi.Description()) + assert.Equal(t, "1", mi.Unit()) + dp := mi.Gauge().DataPoints().At(0) + assert.Equal(t, start, dp.StartTimestamp()) + assert.Equal(t, ts, dp.Timestamp()) + assert.Equal(t, pmetric.NumberDataPointValueTypeDouble, dp.ValueType()) + switch aggMap["optional.metric"] { + case "sum": + assert.InDelta(t, float64(4), dp.DoubleValue(), 0.01) + case "avg": + assert.InDelta(t, float64(2), dp.DoubleValue(), 0.01) + case "min": + assert.InDelta(t, float64(1), dp.DoubleValue(), 0.01) + case "max": + assert.InDelta(t, float64(3), dp.DoubleValue(), 0.01) + } + _, ok := dp.Attributes().Get("string_attr") + assert.False(t, ok) + _, ok = dp.Attributes().Get("boolean_attr") + assert.False(t, ok) + _, ok = dp.Attributes().Get("boolean_attr2") + assert.False(t, ok) + } case "optional.metric.empty_unit": - assert.False(t, validatedMetrics["optional.metric.empty_unit"], "Found a duplicate in the metrics slice: optional.metric.empty_unit") - validatedMetrics["optional.metric.empty_unit"] = true - assert.Equal(t, pmetric.MetricTypeGauge, ms.At(i).Type()) - assert.Equal(t, 1, ms.At(i).Gauge().DataPoints().Len()) - assert.Equal(t, "[DEPRECATED] Gauge double metric disabled by default.", ms.At(i).Description()) - assert.Empty(t, ms.At(i).Unit()) - dp := ms.At(i).Gauge().DataPoints().At(0) - assert.Equal(t, start, dp.StartTimestamp()) - assert.Equal(t, ts, dp.Timestamp()) - assert.Equal(t, pmetric.NumberDataPointValueTypeDouble, dp.ValueType()) - assert.InDelta(t, float64(1), dp.DoubleValue(), 0.01) - attrVal, ok := dp.Attributes().Get("string_attr") - assert.True(t, ok) - assert.Equal(t, "string_attr-val", attrVal.Str()) - attrVal, ok = dp.Attributes().Get("boolean_attr") - assert.True(t, ok) - assert.True(t, attrVal.Bool()) + if tt.name != "reaggregate_set" { + assert.False(t, validatedMetrics["optional.metric.empty_unit"], "Found a duplicate in the metrics slice: optional.metric.empty_unit") + validatedMetrics["optional.metric.empty_unit"] = true + assert.Equal(t, pmetric.MetricTypeGauge, mi.Type()) + assert.Equal(t, 1, mi.Gauge().DataPoints().Len()) + assert.Equal(t, "[DEPRECATED] Gauge double metric disabled by default.", mi.Description()) + assert.Empty(t, mi.Unit()) + dp := mi.Gauge().DataPoints().At(0) + assert.Equal(t, start, dp.StartTimestamp()) + assert.Equal(t, ts, dp.Timestamp()) + assert.Equal(t, pmetric.NumberDataPointValueTypeDouble, dp.ValueType()) + assert.InDelta(t, float64(1), dp.DoubleValue(), 0.01) + attrVal, ok := dp.Attributes().Get("string_attr") + assert.True(t, ok) + assert.Equal(t, "string_attr-val", attrVal.Str()) + attrVal, ok = dp.Attributes().Get("boolean_attr") + assert.True(t, ok) + assert.True(t, attrVal.Bool()) + } else { + assert.False(t, validatedMetrics["optional.metric.empty_unit"], "Found a duplicate in the metrics slice: optional.metric.empty_unit") + validatedMetrics["optional.metric.empty_unit"] = true + assert.Equal(t, pmetric.MetricTypeGauge, mi.Type()) + assert.Equal(t, 1, mi.Gauge().DataPoints().Len()) + assert.Equal(t, "[DEPRECATED] Gauge double metric disabled by default.", mi.Description()) + assert.Empty(t, mi.Unit()) + dp := mi.Gauge().DataPoints().At(0) + assert.Equal(t, start, dp.StartTimestamp()) + assert.Equal(t, ts, dp.Timestamp()) + assert.Equal(t, pmetric.NumberDataPointValueTypeDouble, dp.ValueType()) + switch aggMap["optional.metric.empty_unit"] { + case "sum": + assert.InDelta(t, float64(4), dp.DoubleValue(), 0.01) + case "avg": + assert.InDelta(t, float64(2), dp.DoubleValue(), 0.01) + case "min": + assert.InDelta(t, float64(1), dp.DoubleValue(), 0.01) + case "max": + assert.InDelta(t, float64(3), dp.DoubleValue(), 0.01) + } + _, ok := dp.Attributes().Get("string_attr") + assert.False(t, ok) + _, ok = dp.Attributes().Get("boolean_attr") + assert.False(t, ok) + } + case "reaggregate.metric": + if tt.name != "reaggregate_set" { + assert.False(t, validatedMetrics["reaggregate.metric"], "Found a duplicate in the metrics slice: reaggregate.metric") + validatedMetrics["reaggregate.metric"] = true + assert.Equal(t, pmetric.MetricTypeGauge, mi.Type()) + assert.Equal(t, 1, mi.Gauge().DataPoints().Len()) + assert.Equal(t, "Metric for testing spatial reaggregation", mi.Description()) + assert.Equal(t, "1", mi.Unit()) + dp := mi.Gauge().DataPoints().At(0) + assert.Equal(t, start, dp.StartTimestamp()) + assert.Equal(t, ts, dp.Timestamp()) + assert.Equal(t, pmetric.NumberDataPointValueTypeDouble, dp.ValueType()) + assert.InDelta(t, float64(1), dp.DoubleValue(), 0.01) + attrVal, ok := dp.Attributes().Get("string_attr") + assert.True(t, ok) + assert.Equal(t, "string_attr-val", attrVal.Str()) + attrVal, ok = dp.Attributes().Get("boolean_attr") + assert.True(t, ok) + assert.True(t, attrVal.Bool()) + } else { + assert.False(t, validatedMetrics["reaggregate.metric"], "Found a duplicate in the metrics slice: reaggregate.metric") + validatedMetrics["reaggregate.metric"] = true + assert.Equal(t, pmetric.MetricTypeGauge, mi.Type()) + assert.Equal(t, 1, mi.Gauge().DataPoints().Len()) + assert.Equal(t, "Metric for testing spatial reaggregation", mi.Description()) + assert.Equal(t, "1", mi.Unit()) + dp := mi.Gauge().DataPoints().At(0) + assert.Equal(t, start, dp.StartTimestamp()) + assert.Equal(t, ts, dp.Timestamp()) + assert.Equal(t, pmetric.NumberDataPointValueTypeDouble, dp.ValueType()) + switch aggMap["reaggregate.metric"] { + case "sum": + assert.InDelta(t, float64(4), dp.DoubleValue(), 0.01) + case "avg": + assert.InDelta(t, float64(2), dp.DoubleValue(), 0.01) + case "min": + assert.InDelta(t, float64(1), dp.DoubleValue(), 0.01) + case "max": + assert.InDelta(t, float64(3), dp.DoubleValue(), 0.01) + } + _, ok := dp.Attributes().Get("string_attr") + assert.False(t, ok) + _, ok = dp.Attributes().Get("boolean_attr") + assert.False(t, ok) + } + case "reaggregate.metric.with_required": + if tt.name != "reaggregate_set" { + assert.False(t, validatedMetrics["reaggregate.metric.with_required"], "Found a duplicate in the metrics slice: reaggregate.metric.with_required") + validatedMetrics["reaggregate.metric.with_required"] = true + assert.Equal(t, pmetric.MetricTypeGauge, mi.Type()) + assert.Equal(t, 1, mi.Gauge().DataPoints().Len()) + assert.Equal(t, "Metric for testing spatial reaggregation with required attributes", mi.Description()) + assert.Equal(t, "1", mi.Unit()) + dp := mi.Gauge().DataPoints().At(0) + assert.Equal(t, start, dp.StartTimestamp()) + assert.Equal(t, ts, dp.Timestamp()) + assert.Equal(t, pmetric.NumberDataPointValueTypeDouble, dp.ValueType()) + assert.InDelta(t, float64(1), dp.DoubleValue(), 0.01) + attrVal, ok := dp.Attributes().Get("required_string_attr") + assert.True(t, ok) + assert.Equal(t, "required_string_attr-val", attrVal.Str()) + attrVal, ok = dp.Attributes().Get("string_attr") + assert.True(t, ok) + assert.Equal(t, "string_attr-val", attrVal.Str()) + attrVal, ok = dp.Attributes().Get("boolean_attr") + assert.True(t, ok) + assert.True(t, attrVal.Bool()) + } else { + assert.False(t, validatedMetrics["reaggregate.metric.with_required"], "Found a duplicate in the metrics slice: reaggregate.metric.with_required") + validatedMetrics["reaggregate.metric.with_required"] = true + assert.Equal(t, pmetric.MetricTypeGauge, mi.Type()) + assert.Equal(t, 1, mi.Gauge().DataPoints().Len()) + assert.Equal(t, "Metric for testing spatial reaggregation with required attributes", mi.Description()) + assert.Equal(t, "1", mi.Unit()) + dp := mi.Gauge().DataPoints().At(0) + assert.Equal(t, start, dp.StartTimestamp()) + assert.Equal(t, ts, dp.Timestamp()) + assert.Equal(t, pmetric.NumberDataPointValueTypeDouble, dp.ValueType()) + switch aggMap["reaggregate.metric.with_required"] { + case "sum": + assert.InDelta(t, float64(4), dp.DoubleValue(), 0.01) + case "avg": + assert.InDelta(t, float64(2), dp.DoubleValue(), 0.01) + case "min": + assert.InDelta(t, float64(1), dp.DoubleValue(), 0.01) + case "max": + assert.InDelta(t, float64(3), dp.DoubleValue(), 0.01) + } + _, ok := dp.Attributes().Get("required_string_attr") + assert.True(t, ok) + _, ok = dp.Attributes().Get("string_attr") + assert.False(t, ok) + _, ok = dp.Attributes().Get("boolean_attr") + assert.False(t, ok) + } case "system.cpu.time": assert.False(t, validatedMetrics["system.cpu.time"], "Found a duplicate in the metrics slice: system.cpu.time") validatedMetrics["system.cpu.time"] = true - assert.Equal(t, pmetric.MetricTypeSum, ms.At(i).Type()) - assert.Equal(t, 1, ms.At(i).Sum().DataPoints().Len()) - assert.Equal(t, "Monotonic cumulative sum int metric enabled by default.", ms.At(i).Description()) - assert.Equal(t, "s", ms.At(i).Unit()) - assert.True(t, ms.At(i).Sum().IsMonotonic()) - assert.Equal(t, pmetric.AggregationTemporalityCumulative, ms.At(i).Sum().AggregationTemporality()) - dp := ms.At(i).Sum().DataPoints().At(0) + assert.Equal(t, pmetric.MetricTypeSum, mi.Type()) + assert.Equal(t, 1, mi.Sum().DataPoints().Len()) + assert.Equal(t, "Monotonic cumulative sum int metric enabled by default.", mi.Description()) + assert.Equal(t, "s", mi.Unit()) + assert.True(t, mi.Sum().IsMonotonic()) + assert.Equal(t, pmetric.AggregationTemporalityCumulative, mi.Sum().AggregationTemporality()) + dp := mi.Sum().DataPoints().At(0) assert.Equal(t, start, dp.StartTimestamp()) assert.Equal(t, ts, dp.Timestamp()) assert.Equal(t, pmetric.NumberDataPointValueTypeInt, dp.ValueType()) diff --git a/cmd/mdatagen/internal/samplereceiver/internal/metadata/generated_telemetry.go b/cmd/mdatagen/internal/samplereceiver/internal/metadata/generated_telemetry.go index a210d8dbfd1f..6e1e8d406821 100644 --- a/cmd/mdatagen/internal/samplereceiver/internal/metadata/generated_telemetry.go +++ b/cmd/mdatagen/internal/samplereceiver/internal/metadata/generated_telemetry.go @@ -106,26 +106,26 @@ func NewTelemetryBuilder(settings component.TelemetrySettings, options ...Teleme var err, errs error builder.BatchSizeTriggerSend, err = builder.meter.Int64Counter( "otelcol_batch_size_trigger_send", - metric.WithDescription("Number of times the batch was sent due to a size trigger [Deprecated since v0.110.0]"), - metric.WithUnit("{times}"), + metric.WithDescription("Number of times the batch was sent due to a size trigger [Deprecated]"), + metric.WithUnit("{time}"), ) errs = errors.Join(errs, err) builder.ProcessRuntimeTotalAllocBytes, err = builder.meter.Int64ObservableCounter( "otelcol_process_runtime_total_alloc_bytes", - metric.WithDescription("Cumulative bytes allocated for heap objects (see 'go doc runtime.MemStats.TotalAlloc')"), + metric.WithDescription("Cumulative bytes allocated for heap objects (see 'go doc runtime.MemStats.TotalAlloc') [Stable]"), metric.WithUnit("By"), ) errs = errors.Join(errs, err) builder.QueueCapacity, err = builder.meter.Int64Gauge( "otelcol_queue_capacity", metric.WithDescription("Queue capacity - sync gauge example. [Development]"), - metric.WithUnit("{items}"), + metric.WithUnit("{item}"), ) errs = errors.Join(errs, err) builder.QueueLength, err = builder.meter.Int64ObservableGauge( "otelcol_queue_length", metric.WithDescription("This metric is optional and therefore not initialized in NewTelemetryBuilder. [Alpha]"), - metric.WithUnit("{items}"), + metric.WithUnit("{item}"), ) errs = errors.Join(errs, err) builder.RequestDuration, err = builder.meter.Float64Histogram( diff --git a/cmd/mdatagen/internal/samplereceiver/internal/metadata/testdata/config.yaml b/cmd/mdatagen/internal/samplereceiver/internal/metadata/testdata/config.yaml index 6e461af19fe8..023835c76d01 100644 --- a/cmd/mdatagen/internal/samplereceiver/internal/metadata/testdata/config.yaml +++ b/cmd/mdatagen/internal/samplereceiver/internal/metadata/testdata/config.yaml @@ -3,14 +3,72 @@ all_set: metrics: default.metric: enabled: true + attributes: ["string_attr","state","enum_attr","slice_attr","map_attr","conditional_int_attr","conditional_string_attr","opt_in_bool_attr"] default.metric.to_be_removed: enabled: true metric.input_type: enabled: true + attributes: ["string_attr","state","enum_attr","slice_attr","map_attr"] optional.metric: enabled: true + attributes: ["string_attr","boolean_attr","boolean_attr2","conditional_string_attr"] optional.metric.empty_unit: enabled: true + attributes: ["string_attr","boolean_attr"] + reaggregate.metric: + enabled: true + attributes: ["string_attr","boolean_attr"] + reaggregate.metric.with_required: + enabled: true + attributes: ["required_string_attr","string_attr","boolean_attr"] + system.cpu.time: + enabled: true + events: + default.event: + enabled: true + default.event.to_be_removed: + enabled: true + default.event.to_be_renamed: + enabled: true + resource_attributes: + map.resource.attr: + enabled: true + optional.resource.attr: + enabled: true + slice.resource.attr: + enabled: true + string.enum.resource.attr: + enabled: true + string.resource.attr: + enabled: true + string.resource.attr_disable_warning: + enabled: true + string.resource.attr_remove_warning: + enabled: true + string.resource.attr_to_be_removed: + enabled: true +reaggregate_set: + metrics: + default.metric: + enabled: true + attributes: [] + default.metric.to_be_removed: + enabled: true + metric.input_type: + enabled: true + attributes: [] + optional.metric: + enabled: true + attributes: [] + optional.metric.empty_unit: + enabled: true + attributes: [] + reaggregate.metric: + enabled: true + attributes: [] + reaggregate.metric.with_required: + enabled: true + attributes: ["required_string_attr"] system.cpu.time: enabled: true events: @@ -41,14 +99,24 @@ none_set: metrics: default.metric: enabled: false + attributes: ["string_attr","state","enum_attr","slice_attr","map_attr","conditional_int_attr","conditional_string_attr","opt_in_bool_attr"] default.metric.to_be_removed: enabled: false metric.input_type: enabled: false + attributes: ["string_attr","state","enum_attr","slice_attr","map_attr"] optional.metric: enabled: false + attributes: ["string_attr","boolean_attr","boolean_attr2","conditional_string_attr"] optional.metric.empty_unit: enabled: false + attributes: ["string_attr","boolean_attr"] + reaggregate.metric: + enabled: false + attributes: ["string_attr","boolean_attr"] + reaggregate.metric.with_required: + enabled: false + attributes: ["required_string_attr","string_attr","boolean_attr"] system.cpu.time: enabled: false events: diff --git a/cmd/mdatagen/internal/samplereceiver/internal/metadatatest/generated_telemetrytest.go b/cmd/mdatagen/internal/samplereceiver/internal/metadatatest/generated_telemetrytest.go index 361a36432034..12c6c4cebb0e 100644 --- a/cmd/mdatagen/internal/samplereceiver/internal/metadatatest/generated_telemetrytest.go +++ b/cmd/mdatagen/internal/samplereceiver/internal/metadatatest/generated_telemetrytest.go @@ -25,8 +25,8 @@ func NewSettings(tt *componenttest.Telemetry) receiver.Settings { func AssertEqualBatchSizeTriggerSend(t *testing.T, tt *componenttest.Telemetry, dps []metricdata.DataPoint[int64], opts ...metricdatatest.Option) { want := metricdata.Metrics{ Name: "otelcol_batch_size_trigger_send", - Description: "Number of times the batch was sent due to a size trigger [Deprecated since v0.110.0]", - Unit: "{times}", + Description: "Number of times the batch was sent due to a size trigger [Deprecated]", + Unit: "{time}", Data: metricdata.Sum[int64]{ Temporality: metricdata.CumulativeTemporality, IsMonotonic: true, @@ -41,7 +41,7 @@ func AssertEqualBatchSizeTriggerSend(t *testing.T, tt *componenttest.Telemetry, func AssertEqualProcessRuntimeTotalAllocBytes(t *testing.T, tt *componenttest.Telemetry, dps []metricdata.DataPoint[int64], opts ...metricdatatest.Option) { want := metricdata.Metrics{ Name: "otelcol_process_runtime_total_alloc_bytes", - Description: "Cumulative bytes allocated for heap objects (see 'go doc runtime.MemStats.TotalAlloc')", + Description: "Cumulative bytes allocated for heap objects (see 'go doc runtime.MemStats.TotalAlloc') [Stable]", Unit: "By", Data: metricdata.Sum[int64]{ Temporality: metricdata.CumulativeTemporality, @@ -58,7 +58,7 @@ func AssertEqualQueueCapacity(t *testing.T, tt *componenttest.Telemetry, dps []m want := metricdata.Metrics{ Name: "otelcol_queue_capacity", Description: "Queue capacity - sync gauge example. [Development]", - Unit: "{items}", + Unit: "{item}", Data: metricdata.Gauge[int64]{ DataPoints: dps, }, @@ -72,7 +72,7 @@ func AssertEqualQueueLength(t *testing.T, tt *componenttest.Telemetry, dps []met want := metricdata.Metrics{ Name: "otelcol_queue_length", Description: "This metric is optional and therefore not initialized in NewTelemetryBuilder. [Alpha]", - Unit: "{items}", + Unit: "{item}", Data: metricdata.Gauge[int64]{ DataPoints: dps, }, diff --git a/cmd/mdatagen/internal/samplereceiver/metadata.yaml b/cmd/mdatagen/internal/samplereceiver/metadata.yaml index c1ede02b02f4..c036705d2bca 100644 --- a/cmd/mdatagen/internal/samplereceiver/metadata.yaml +++ b/cmd/mdatagen/internal/samplereceiver/metadata.yaml @@ -1,10 +1,20 @@ # Sample metadata file with all available configurations for a receiver. type: sample +display_name: Sample Receiver +description: This receiver is used for testing purposes to check the output of mdatagen. +reaggregation_enabled: true scope_name: go.opentelemetry.io/collector/internal/receiver/samplereceiver github_project: open-telemetry/opentelemetry-collector -sem_conv_version: 1.37.0 +sem_conv_version: 1.38.0 + +feature_gates: + - id: receiver.sample.featuregate.example + description: This is an example feature gate for testing mdatagen code generation. + stage: alpha + from_version: v0.100.0 + reference_url: https://github.com/open-telemetry/opentelemetry-collector/issues/12345 status: disable_codecov_badge: true @@ -25,6 +35,22 @@ status: warnings: - Any additional information that should be brought to the consumer's attention +config: + type: object + allOf: + - $ref: ./internal/metadata.metrics_builder_config + properties: + endpoint: + description: The endpoint to scrape metrics from. + type: string + default: "localhost:12345" + timeout: + description: Timeout for scraping metrics. + type: string + format: duration + default: 10s + required: [endpoint] + resource_attributes: map.resource.attr: description: Resource attribute with a map value. @@ -113,6 +139,11 @@ attributes: description: Integer attribute with overridden name. type: int + required_string_attr: + description: A required attribute with a string value + type: string + requirement_level: required + slice_attr: description: Attribute with a slice value. type: slice @@ -161,8 +192,10 @@ metrics: enabled: true description: Monotonic cumulative sum int metric enabled by default. extended_documentation: The metric will be become optional soon. - stability: - level: development + stability: deprecated + deprecated: + since: "1.0.0" + note: "This metric will be removed" unit: s sum: value_type: int @@ -186,8 +219,10 @@ metrics: enabled: true description: "[DEPRECATED] Non-monotonic delta sum double metric enabled by default." extended_documentation: The metric will be removed soon. - stability: - level: deprecated + stability: deprecated + deprecated: + since: "1.0.0" + note: "This metric will be removed" unit: s sum: value_type: double @@ -199,8 +234,7 @@ metrics: metric.input_type: enabled: true description: Monotonic cumulative sum int metric with string input_type enabled by default. - stability: - level: development + stability: development unit: s sum: value_type: int @@ -213,8 +247,10 @@ metrics: optional.metric: enabled: false description: "[DEPRECATED] Gauge double metric disabled by default." - stability: - level: deprecated + stability: deprecated + deprecated: + since: "1.0.0" + note: "This metric will be removed" unit: "1" gauge: value_type: double @@ -225,8 +261,10 @@ metrics: optional.metric.empty_unit: enabled: false description: "[DEPRECATED] Gauge double metric disabled by default." - stability: - level: deprecated + stability: deprecated + deprecated: + since: "1.0.0" + note: "This metric will be removed" unit: "" gauge: value_type: double @@ -234,10 +272,27 @@ metrics: warnings: if_configured: This metric is deprecated and will be removed soon. + reaggregate.metric: + enabled: true + description: Metric for testing spatial reaggregation + unit: "1" + stability: beta + gauge: + value_type: double + attributes: [string_attr, boolean_attr] + + reaggregate.metric.with_required: + enabled: true + description: Metric for testing spatial reaggregation with required attributes + unit: "1" + stability: beta + gauge: + value_type: double + attributes: [required_string_attr, string_attr, boolean_attr] + system.cpu.time: enabled: true - stability: - level: beta + stability: beta description: Monotonic cumulative sum int metric enabled by default. extended_documentation: The metric will be become optional soon. unit: s @@ -246,24 +301,24 @@ metrics: monotonic: true aggregation_temporality: cumulative semantic_convention: - ref: https://github.com/open-telemetry/semantic-conventions/blob/v1.37.0/docs/system/system-metrics.md#metric-systemcputime + ref: https://github.com/open-telemetry/semantic-conventions/blob/v1.38.0/docs/system/system-metrics.md#metric-systemcputime telemetry: metrics: batch_size_trigger_send: enabled: true - stability: - level: deprecated - from: v0.110.0 + stability: deprecated + deprecated: + since: "1.5.0" + note: "This metric will be removed in favor of batch_send_trigger_size" description: Number of times the batch was sent due to a size trigger - unit: "{times}" + unit: "{time}" sum: value_type: int monotonic: true process_runtime_total_alloc_bytes: enabled: true - stability: - level: stable + stability: stable description: Cumulative bytes allocated for heap objects (see 'go doc runtime.MemStats.TotalAlloc') unit: By sum: @@ -273,26 +328,23 @@ telemetry: queue_capacity: enabled: true description: Queue capacity - sync gauge example. - stability: - level: development - unit: "{items}" + stability: development + unit: "{item}" gauge: value_type: int queue_length: enabled: true - stability: - level: alpha + stability: alpha description: This metric is optional and therefore not initialized in NewTelemetryBuilder. extended_documentation: For example this metric only exists if feature A is enabled. - unit: "{items}" + unit: "{item}" optional: true gauge: async: true value_type: int request_duration: enabled: true - stability: - level: alpha + stability: alpha description: Duration of request unit: s histogram: diff --git a/cmd/mdatagen/internal/samplescraper/README.md b/cmd/mdatagen/internal/samplescraper/README.md index 5654b3aeb540..120460364ff3 100644 --- a/cmd/mdatagen/internal/samplescraper/README.md +++ b/cmd/mdatagen/internal/samplescraper/README.md @@ -1,9 +1,11 @@ + # Sample Scraper + This scraper is used for testing purposes to check the output of mdatagen. - + | Status | | | ------------- |-----------| -| Stability | [development]: logs | +| Stability | [development]: logs, profiles | | | [stable]: metrics | | Unsupported Platforms | freebsd, illumos | | Distributions | [] | diff --git a/cmd/mdatagen/internal/samplescraper/config.schema.json b/cmd/mdatagen/internal/samplescraper/config.schema.json new file mode 100644 index 000000000000..fc9a7cda4138 --- /dev/null +++ b/cmd/mdatagen/internal/samplescraper/config.schema.json @@ -0,0 +1,264 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "go.opentelemetry.io/collector/cmd/mdatagen/internal/samplescraper", + "title": "scraper/sample", + "description": "Configuration for the Sample Scraper.", + "type": "object", + "allOf": [ + { + "description": "ControllerConfig defines common settings for a scraper controller configuration. Scraper controller receivers can embed this struct, instead of receiver.Settings, and extend it with more fields if needed.", + "type": "object", + "properties": { + "collection_interval": { + "description": "CollectionInterval sets how frequently the scraper should be called and used as the context timeout to ensure that scrapers don't exceed the interval. (duration format, e.g., \"30s\", \"1h30m\")", + "type": "string", + "pattern": "^([0-9]+(\\.[0-9]+)?(ns|us|µs|ms|s|m|h))+$" + }, + "initial_delay": { + "description": "InitialDelay sets the initial start delay for the scraper, any non positive value is assumed to be immediately. (duration format, e.g., \"30s\", \"1h30m\")", + "type": "string", + "pattern": "^([0-9]+(\\.[0-9]+)?(ns|us|µs|ms|s|m|h))+$" + }, + "timeout": { + "description": "Timeout is an optional value used to set scraper's context deadline. (duration format, e.g., \"30s\", \"1h30m\")", + "type": "string", + "pattern": "^([0-9]+(\\.[0-9]+)?(ns|us|µs|ms|s|m|h))+$" + } + } + } + ], + "properties": { + "targets": { + "description": "Targets configuration for the scraper.", + "type": "array", + "items": { + "type": "object", + "properties": { + "http_client": { + "description": "ClientConfig defines settings for creating an HTTP client.", + "type": "object", + "properties": { + "auth": { + "description": "Auth configuration for outgoing HTTP calls.", + "type": "object", + "properties": { + "authenticator": { + "description": "AuthenticatorID specifies the name of the extension to use in order to authenticate the incoming data point.", + "type": "string" + } + } + }, + "compression": { + "description": "The compression key for supported compression types within collector.", + "type": "string" + }, + "compression_params": { + "description": "Advanced configuration options for the Compression", + "type": "object", + "properties": { + "level": { + "type": "integer" + } + } + }, + "cookies": { + "description": "Cookies configures the cookie management of the HTTP client." + }, + "disable_keep_alives": { + "description": "DisableKeepAlives, if true, disables HTTP keep-alives and will only use the connection to the server for a single HTTP request. WARNING: enabling this option can result in significant overhead establishing a new HTTP(S) connection for every request. Before enabling this option please consider whether changes to idle connection settings can achieve your goal.", + "type": "boolean" + }, + "endpoint": { + "description": "The target URL to send data to (e.g.: http://some.url:9411/v1/traces).", + "type": "string" + }, + "force_attempt_http2": { + "description": "Enabling ForceAttemptHTTP2 forces the HTTP transport to use the HTTP/2 protocol. By default, this is set to true. NOTE: HTTP/2 does not support settings such as MaxConnsPerHost, MaxIdleConnsPerHost and MaxIdleConns.", + "type": "boolean" + }, + "headers": { + "description": "Additional headers attached to each HTTP request sent by the client. Existing header values are overwritten if collision happens. Header values are opaque since they may be sensitive.", + "type": "array", + "items": { + "description": "Pair is an element of a MapList, and consists of a name and an opaque value.", + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "value": { + "description": "String alias that is marshaled and printed in an opaque way. To recover the original value, cast it to a string.", + "type": "string" + } + } + } + }, + "http2_ping_timeout": { + "description": "HTTP2PingTimeout if there's no response to the ping within the configured value, the connection will be closed. If not set or set to 0, it defaults to 15s. (duration format, e.g., \"30s\", \"1h30m\")", + "type": "string", + "pattern": "^([0-9]+(\\.[0-9]+)?(ns|us|µs|ms|s|m|h))+$" + }, + "http2_read_idle_timeout": { + "description": "This is needed in case you run into https://github.com/golang/go/issues/59690 https://github.com/golang/go/issues/36026 HTTP2ReadIdleTimeout if the connection has been idle for the configured value send a ping frame for health check 0s means no health check will be performed. (duration format, e.g., \"30s\", \"1h30m\")", + "type": "string", + "pattern": "^([0-9]+(\\.[0-9]+)?(ns|us|µs|ms|s|m|h))+$" + }, + "idle_conn_timeout": { + "description": "IdleConnTimeout is the maximum amount of time a connection will remain open before closing itself. By default, it is set to 90 seconds. (duration format, e.g., \"30s\", \"1h30m\")", + "type": "string", + "pattern": "^([0-9]+(\\.[0-9]+)?(ns|us|µs|ms|s|m|h))+$" + }, + "max_conns_per_host": { + "description": "MaxConnsPerHost limits the total number of connections per host, including connections in the dialing, active, and idle states. Default is 0 (unlimited).", + "type": "integer" + }, + "max_idle_conns": { + "description": "MaxIdleConns is used to set a limit to the maximum idle HTTP connections the client can keep open. By default, it is set to 100. Zero means no limit.", + "type": "integer" + }, + "max_idle_conns_per_host": { + "description": "MaxIdleConnsPerHost is used to set a limit to the maximum idle HTTP connections the host can keep open. If zero, [net/http.DefaultMaxIdleConnsPerHost] is used.", + "type": "integer" + }, + "middlewares": { + "description": "Middlewares are used to add custom functionality to the HTTP client. Middleware handlers are called in the order they appear in this list, with the first middleware becoming the outermost handler.", + "type": "array", + "items": { + "description": "Middleware defines the extension ID for a middleware component.", + "type": "object", + "properties": { + "id": { + "description": "ID specifies the name of the extension to use.", + "type": "string" + } + } + } + }, + "proxy_url": { + "description": "ProxyURL setting for the collector", + "type": "string" + }, + "read_buffer_size": { + "description": "ReadBufferSize for HTTP client. See http.Transport.ReadBufferSize. Default is 0.", + "type": "integer" + }, + "timeout": { + "description": "Timeout parameter configures `http.Client.Timeout`. Default is 0 (unlimited). (duration format, e.g., \"30s\", \"1h30m\")", + "type": "string", + "pattern": "^([0-9]+(\\.[0-9]+)?(ns|us|µs|ms|s|m|h))+$" + }, + "tls": { + "description": "TLS struct exposes TLS client configuration.", + "type": "object", + "allOf": [ + { + "description": "Config exposes the common client and server TLS configurations. Note: Since there isn't anything specific to a server connection. Components with server connections should use Config.", + "type": "object", + "properties": { + "ca_file": { + "description": "Path to the CA cert. For a client this verifies the server certificate. For a server this verifies client certificates. If empty uses system root CA. (optional)", + "type": "string" + }, + "ca_pem": { + "description": "In memory PEM encoded cert. (optional)", + "type": "string" + }, + "cert_file": { + "description": "Path to the TLS cert to use for TLS required connections. (optional)", + "type": "string" + }, + "cert_pem": { + "description": "In memory PEM encoded TLS cert to use for TLS required connections. (optional)", + "type": "string" + }, + "cipher_suites": { + "description": "CipherSuites is a list of TLS cipher suites that the TLS transport can use. If left blank, a safe default list is used. See https://go.dev/src/crypto/tls/cipher_suites.go for a list of supported cipher suites.", + "type": "array", + "items": { + "type": "string" + } + }, + "curve_preferences": { + "description": "contains the elliptic curves that will be used in an ECDHE handshake, in preference order Defaults to empty list and \"crypto/tls\" defaults are used, internally.", + "type": "array", + "items": { + "type": "string" + } + }, + "include_system_ca_certs_pool": { + "description": "If true, load system CA certificates pool in addition to the certificates configured in this struct.", + "type": "boolean" + }, + "key_file": { + "description": "Path to the TLS key to use for TLS required connections. (optional)", + "type": "string" + }, + "key_pem": { + "description": "In memory PEM encoded TLS key to use for TLS required connections. (optional)", + "type": "string" + }, + "max_version": { + "description": "MaxVersion sets the maximum TLS version that is acceptable. If not set, refer to crypto/tls for defaults. (optional)", + "type": "string" + }, + "min_version": { + "description": "MinVersion sets the minimum TLS version that is acceptable. If not set, TLS 1.2 will be used. (optional)", + "type": "string" + }, + "reload_interval": { + "description": "ReloadInterval specifies the duration after which the certificate will be reloaded If not set, it will never be reloaded (optional)", + "type": "string", + "pattern": "^([0-9]+(\\.[0-9]+)?(ns|us|µs|ms|s|m|h))+$" + }, + "tpm": { + "description": "Trusted platform module configuration", + "type": "object", + "properties": { + "auth": { + "type": "string" + }, + "enabled": { + "type": "boolean" + }, + "owner_auth": { + "type": "string" + }, + "path": { + "description": "The path to the TPM device or Unix domain socket. For instance /dev/tpm0 or /dev/tpmrm0.", + "type": "string" + } + } + } + } + } + ], + "properties": { + "insecure": { + "description": "In gRPC and HTTP when set to true, this is used to disable the client transport security. See https://godoc.org/google.golang.org/grpc#WithInsecure for gRPC. Please refer to https://godoc.org/crypto/tls#Config for more information. (optional, default false)", + "type": "boolean" + }, + "insecure_skip_verify": { + "description": "InsecureSkipVerify will enable TLS but not verify the certificate.", + "type": "boolean" + }, + "server_name_override": { + "description": "ServerName requested by client for virtual hosting. This sets the ServerName in the TLSConfig. Please refer to https://godoc.org/crypto/tls#Config for more information. (optional)", + "type": "string" + } + } + }, + "write_buffer_size": { + "description": "WriteBufferSize for HTTP client. See http.Transport.WriteBufferSize. Default is 0.", + "type": "integer" + } + } + }, + "interval": { + "type": "string", + "pattern": "^([0-9]+(\\.[0-9]+)?(ns|us|µs|ms|s|m|h))+$" + } + } + } + } + } +} \ No newline at end of file diff --git a/cmd/mdatagen/internal/samplescraper/documentation.md b/cmd/mdatagen/internal/samplescraper/documentation.md index ee027ef51386..dc0ab8c93aa6 100644 --- a/cmd/mdatagen/internal/samplescraper/documentation.md +++ b/cmd/mdatagen/internal/samplescraper/documentation.md @@ -40,7 +40,9 @@ The metric will be removed soon. | Unit | Metric Type | Value Type | Aggregation Temporality | Monotonic | Stability | | ---- | ----------- | ---------- | ----------------------- | --------- | --------- | -| s | Sum | Double | Delta | false | Deprecated | +| s | Sum | Double | Delta | false | Deprecated since 1.0.0 | + +**Deprecation note**: This metric will be removed ### metric.input_type @@ -60,6 +62,21 @@ Monotonic cumulative sum int metric with string input_type enabled by default. | slice_attr | Attribute with a slice value. | Any Slice | Recommended | | map_attr | Attribute with a map value. | Any Map | Recommended | +### reaggregate.metric + +Metric for testing spatial reaggregation + +| Unit | Metric Type | Value Type | Stability | +| ---- | ----------- | ---------- | --------- | +| 1 | Gauge | Double | Beta | + +#### Attributes + +| Name | Description | Values | Requirement Level | +| ---- | ----------- | ------ | -------- | +| string_attr | Attribute with any string value. | Any Str | Recommended | +| boolean_attr | Attribute with a boolean value. | Any Bool | Recommended | + ### system.cpu.time Monotonic cumulative sum int metric enabled by default. @@ -68,7 +85,7 @@ The metric will be become optional soon. | Unit | Metric Type | Value Type | Aggregation Temporality | Monotonic | Stability | Semantic Convention | | ---- | ----------- | ---------- | ----------------------- | --------- | --------- | ------------------- | -| s | Sum | Int | Cumulative | true | Beta | [system.cpu.time](https://github.com/open-telemetry/semantic-conventions/blob/v1.37.0/docs/system/system-metrics.md#metric-systemcputime) | +| s | Sum | Int | Cumulative | true | Beta | [system.cpu.time](https://github.com/open-telemetry/semantic-conventions/blob/v1.38.0/docs/system/system-metrics.md#metric-systemcputime) | ## Optional Metrics @@ -86,7 +103,9 @@ metrics: | Unit | Metric Type | Value Type | Stability | | ---- | ----------- | ---------- | --------- | -| 1 | Gauge | Double | Deprecated | +| 1 | Gauge | Double | Deprecated since 1.0.0 | + +**Deprecation note**: This metric will be removed #### Attributes @@ -102,7 +121,9 @@ metrics: | Unit | Metric Type | Value Type | Stability | | ---- | ----------- | ---------- | --------- | -| | Gauge | Double | Deprecated | +| | Gauge | Double | Deprecated since 1.0.0 | + +**Deprecation note**: This metric will be removed #### Attributes diff --git a/cmd/mdatagen/internal/samplescraper/factory.go b/cmd/mdatagen/internal/samplescraper/factory.go index b27b912ef5dc..898e4124b07c 100644 --- a/cmd/mdatagen/internal/samplescraper/factory.go +++ b/cmd/mdatagen/internal/samplescraper/factory.go @@ -10,16 +10,20 @@ import ( "go.opentelemetry.io/collector/component" "go.opentelemetry.io/collector/pdata/plog" "go.opentelemetry.io/collector/pdata/pmetric" + "go.opentelemetry.io/collector/pdata/pprofile" "go.opentelemetry.io/collector/scraper" + "go.opentelemetry.io/collector/scraper/xscraper" ) // NewFactory returns a receiver.Factory for sample receiver. func NewFactory() scraper.Factory { - return scraper.NewFactory( + return xscraper.NewFactory( metadata.Type, func() component.Config { return &struct{}{} }, - scraper.WithMetrics(createMetrics, metadata.MetricsStability), - scraper.WithLogs(createLogs, metadata.LogsStability)) + xscraper.WithMetrics(createMetrics, metadata.MetricsStability), + xscraper.WithLogs(createLogs, metadata.LogsStability), + xscraper.WithProfiles(createProfiles, metadata.ProfilesStability), + ) } func createMetrics(context.Context, scraper.Settings, component.Config) (scraper.Metrics, error) { @@ -31,3 +35,7 @@ func createMetrics(context.Context, scraper.Settings, component.Config) (scraper func createLogs(context.Context, scraper.Settings, component.Config) (scraper.Logs, error) { return scraper.NewLogs(func(context.Context) (plog.Logs, error) { return plog.Logs{}, nil }) } + +func createProfiles(context.Context, scraper.Settings, component.Config) (xscraper.Profiles, error) { + return xscraper.NewProfiles(func(context.Context) (pprofile.Profiles, error) { return pprofile.Profiles{}, nil }) +} diff --git a/cmd/mdatagen/internal/samplescraper/generated_component_test.go b/cmd/mdatagen/internal/samplescraper/generated_component_test.go index bfa30b0c4cc9..ec27478462ae 100644 --- a/cmd/mdatagen/internal/samplescraper/generated_component_test.go +++ b/cmd/mdatagen/internal/samplescraper/generated_component_test.go @@ -14,6 +14,7 @@ import ( "go.opentelemetry.io/collector/confmap/confmaptest" "go.opentelemetry.io/collector/scraper" "go.opentelemetry.io/collector/scraper/scrapertest" + "go.opentelemetry.io/collector/scraper/xscraper" ) var typ = component.MustNewType("sample") @@ -47,6 +48,13 @@ func TestComponentLifecycle(t *testing.T) { return factory.CreateMetrics(ctx, set, cfg) }, }, + + { + name: "profiles", + createFn: func(ctx context.Context, set scraper.Settings, cfg component.Config) (component.Component, error) { + return factory.(xscraper.Factory).CreateProfiles(ctx, set, cfg) + }, + }, } cm, err := confmaptest.LoadConf("metadata.yaml") diff --git a/cmd/mdatagen/internal/samplescraper/generated_config.go b/cmd/mdatagen/internal/samplescraper/generated_config.go new file mode 100644 index 000000000000..e44b865219a7 --- /dev/null +++ b/cmd/mdatagen/internal/samplescraper/generated_config.go @@ -0,0 +1,23 @@ +// Code generated by mdatagen. DO NOT EDIT. + +package samplescraper + +import ( + "time" + + "go.opentelemetry.io/collector/config/confighttp" + "go.opentelemetry.io/collector/config/configoptional" + "go.opentelemetry.io/collector/scraper/scraperhelper" +) + +type TargetsItem struct { + HTTPClient confighttp.ClientConfig `mapstructure:"http_client"` + Interval configoptional.Optional[time.Duration] `mapstructure:"interval"` +} + +// Configuration for the Sample Scraper. +type Config struct { + scraperhelper.ControllerConfig `mapstructure:",squash"` + // Targets configuration for the scraper. + Targets *[]TargetsItem `mapstructure:"targets"` +} diff --git a/cmd/mdatagen/internal/samplescraper/internal/metadata/config.schema.yaml b/cmd/mdatagen/internal/samplescraper/internal/metadata/config.schema.yaml new file mode 100644 index 000000000000..e5c92ab01f90 --- /dev/null +++ b/cmd/mdatagen/internal/samplescraper/internal/metadata/config.schema.yaml @@ -0,0 +1,307 @@ +# Code generated by mdatagen. DO NOT EDIT. +$defs: + metrics_config: + description: MetricsConfig provides config for sample metrics. + type: object + properties: + default.metric: + description: "DefaultMetricMetricConfig provides config for the default.metric metric." + type: object + properties: + enabled: + type: boolean + default: true + aggregation_strategy: + type: string + enum: + - "sum" + - "avg" + - "min" + - "max" + default: "sum" + attributes: + type: array + items: + type: string + enum: + - "string_attr" + - "state" + - "enum_attr" + - "slice_attr" + - "map_attr" + default: + - "string_attr" + - "state" + - "enum_attr" + - "slice_attr" + - "map_attr" + default.metric.to_be_removed: + description: "DefaultMetricToBeRemovedMetricConfig provides config for the default.metric.to_be_removed metric." + type: object + properties: + enabled: + type: boolean + default: true + metric.input_type: + description: "MetricInputTypeMetricConfig provides config for the metric.input_type metric." + type: object + properties: + enabled: + type: boolean + default: true + aggregation_strategy: + type: string + enum: + - "sum" + - "avg" + - "min" + - "max" + default: "sum" + attributes: + type: array + items: + type: string + enum: + - "string_attr" + - "state" + - "enum_attr" + - "slice_attr" + - "map_attr" + default: + - "string_attr" + - "state" + - "enum_attr" + - "slice_attr" + - "map_attr" + optional.metric: + description: "OptionalMetricMetricConfig provides config for the optional.metric metric." + type: object + properties: + enabled: + type: boolean + default: false + aggregation_strategy: + type: string + enum: + - "sum" + - "avg" + - "min" + - "max" + default: "avg" + attributes: + type: array + items: + type: string + enum: + - "string_attr" + - "boolean_attr" + - "boolean_attr2" + default: + - "string_attr" + - "boolean_attr" + - "boolean_attr2" + optional.metric.empty_unit: + description: "OptionalMetricEmptyUnitMetricConfig provides config for the optional.metric.empty_unit metric." + type: object + properties: + enabled: + type: boolean + default: false + aggregation_strategy: + type: string + enum: + - "sum" + - "avg" + - "min" + - "max" + default: "avg" + attributes: + type: array + items: + type: string + enum: + - "string_attr" + - "boolean_attr" + default: + - "string_attr" + - "boolean_attr" + reaggregate.metric: + description: "ReaggregateMetricMetricConfig provides config for the reaggregate.metric metric." + type: object + properties: + enabled: + type: boolean + default: true + aggregation_strategy: + type: string + enum: + - "sum" + - "avg" + - "min" + - "max" + default: "avg" + attributes: + type: array + items: + type: string + enum: + - "string_attr" + - "boolean_attr" + default: + - "string_attr" + - "boolean_attr" + system.cpu.time: + description: "SystemCPUTimeMetricConfig provides config for the system.cpu.time metric." + type: object + properties: + enabled: + type: boolean + default: true + resource_attributes_config: + description: ResourceAttributesConfig provides config for sample resource attributes. + type: object + properties: + map.resource.attr: + description: ResourceAttributeConfig provides common config for a map.resource.attr resource attribute. + type: object + properties: + enabled: + type: boolean + default: true + metrics_include: + description: "Experimental: MetricsInclude defines a list of filters for attribute values. If the list is not empty, only metrics with matching resource attribute values will be emitted." + type: array + items: + $ref: /filter.config + metrics_exclude: + description: "Experimental: MetricsExclude defines a list of filters for attribute values. If the list is not empty, metrics with matching resource attribute values will not be emitted. MetricsInclude has higher priority than MetricsExclude." + type: array + items: + $ref: /filter.config + optional.resource.attr: + description: ResourceAttributeConfig provides common config for a optional.resource.attr resource attribute. + type: object + properties: + enabled: + type: boolean + default: false + metrics_include: + description: "Experimental: MetricsInclude defines a list of filters for attribute values. If the list is not empty, only metrics with matching resource attribute values will be emitted." + type: array + items: + $ref: /filter.config + metrics_exclude: + description: "Experimental: MetricsExclude defines a list of filters for attribute values. If the list is not empty, metrics with matching resource attribute values will not be emitted. MetricsInclude has higher priority than MetricsExclude." + type: array + items: + $ref: /filter.config + slice.resource.attr: + description: ResourceAttributeConfig provides common config for a slice.resource.attr resource attribute. + type: object + properties: + enabled: + type: boolean + default: true + metrics_include: + description: "Experimental: MetricsInclude defines a list of filters for attribute values. If the list is not empty, only metrics with matching resource attribute values will be emitted." + type: array + items: + $ref: /filter.config + metrics_exclude: + description: "Experimental: MetricsExclude defines a list of filters for attribute values. If the list is not empty, metrics with matching resource attribute values will not be emitted. MetricsInclude has higher priority than MetricsExclude." + type: array + items: + $ref: /filter.config + string.enum.resource.attr: + description: ResourceAttributeConfig provides common config for a string.enum.resource.attr resource attribute. + type: object + properties: + enabled: + type: boolean + default: true + metrics_include: + description: "Experimental: MetricsInclude defines a list of filters for attribute values. If the list is not empty, only metrics with matching resource attribute values will be emitted." + type: array + items: + $ref: /filter.config + metrics_exclude: + description: "Experimental: MetricsExclude defines a list of filters for attribute values. If the list is not empty, metrics with matching resource attribute values will not be emitted. MetricsInclude has higher priority than MetricsExclude." + type: array + items: + $ref: /filter.config + string.resource.attr: + description: ResourceAttributeConfig provides common config for a string.resource.attr resource attribute. + type: object + properties: + enabled: + type: boolean + default: true + metrics_include: + description: "Experimental: MetricsInclude defines a list of filters for attribute values. If the list is not empty, only metrics with matching resource attribute values will be emitted." + type: array + items: + $ref: /filter.config + metrics_exclude: + description: "Experimental: MetricsExclude defines a list of filters for attribute values. If the list is not empty, metrics with matching resource attribute values will not be emitted. MetricsInclude has higher priority than MetricsExclude." + type: array + items: + $ref: /filter.config + string.resource.attr_disable_warning: + description: ResourceAttributeConfig provides common config for a string.resource.attr_disable_warning resource attribute. + type: object + properties: + enabled: + type: boolean + default: true + metrics_include: + description: "Experimental: MetricsInclude defines a list of filters for attribute values. If the list is not empty, only metrics with matching resource attribute values will be emitted." + type: array + items: + $ref: /filter.config + metrics_exclude: + description: "Experimental: MetricsExclude defines a list of filters for attribute values. If the list is not empty, metrics with matching resource attribute values will not be emitted. MetricsInclude has higher priority than MetricsExclude." + type: array + items: + $ref: /filter.config + string.resource.attr_remove_warning: + description: ResourceAttributeConfig provides common config for a string.resource.attr_remove_warning resource attribute. + type: object + properties: + enabled: + type: boolean + default: false + metrics_include: + description: "Experimental: MetricsInclude defines a list of filters for attribute values. If the list is not empty, only metrics with matching resource attribute values will be emitted." + type: array + items: + $ref: /filter.config + metrics_exclude: + description: "Experimental: MetricsExclude defines a list of filters for attribute values. If the list is not empty, metrics with matching resource attribute values will not be emitted. MetricsInclude has higher priority than MetricsExclude." + type: array + items: + $ref: /filter.config + string.resource.attr_to_be_removed: + description: ResourceAttributeConfig provides common config for a string.resource.attr_to_be_removed resource attribute. + type: object + properties: + enabled: + type: boolean + default: true + metrics_include: + description: "Experimental: MetricsInclude defines a list of filters for attribute values. If the list is not empty, only metrics with matching resource attribute values will be emitted." + type: array + items: + $ref: /filter.config + metrics_exclude: + description: "Experimental: MetricsExclude defines a list of filters for attribute values. If the list is not empty, metrics with matching resource attribute values will not be emitted. MetricsInclude has higher priority than MetricsExclude." + type: array + items: + $ref: /filter.config + metrics_builder_config: + description: MetricsBuilderConfig is a configuration for sample metrics builder. + type: object + properties: + metrics: + $ref: metrics_config + resource_attributes: + $ref: resource_attributes_config diff --git a/cmd/mdatagen/internal/samplescraper/internal/metadata/generated_config.go b/cmd/mdatagen/internal/samplescraper/internal/metadata/generated_config.go index 8a790277c383..1b11d7611414 100644 --- a/cmd/mdatagen/internal/samplescraper/internal/metadata/generated_config.go +++ b/cmd/mdatagen/internal/samplescraper/internal/metadata/generated_config.go @@ -3,57 +3,346 @@ package metadata import ( + "fmt" + "go.opentelemetry.io/collector/confmap" "go.opentelemetry.io/collector/filter" ) -// MetricConfig provides common config for a particular metric. -type MetricConfig struct { - Enabled bool `mapstructure:"enabled"` +// DefaultMetricMetricAttributeKey specifies the key of an attribute for the default.metric metric. +type DefaultMetricMetricAttributeKey string + +const ( + DefaultMetricMetricAttributeKeyStringAttr DefaultMetricMetricAttributeKey = "string_attr" + DefaultMetricMetricAttributeKeyOverriddenIntAttr DefaultMetricMetricAttributeKey = "state" + DefaultMetricMetricAttributeKeyEnumAttr DefaultMetricMetricAttributeKey = "enum_attr" + DefaultMetricMetricAttributeKeySliceAttr DefaultMetricMetricAttributeKey = "slice_attr" + DefaultMetricMetricAttributeKeyMapAttr DefaultMetricMetricAttributeKey = "map_attr" +) + +// DefaultMetricMetricConfig provides config for the default.metric metric. +type DefaultMetricMetricConfig struct { + Enabled bool `mapstructure:"enabled"` + enabledSetByUser bool + + AggregationStrategy string `mapstructure:"aggregation_strategy"` + EnabledAttributes []DefaultMetricMetricAttributeKey `mapstructure:"attributes"` +} + +func (ms *DefaultMetricMetricConfig) Unmarshal(parser *confmap.Conf) error { + if parser == nil { + return nil + } + + err := parser.Unmarshal(ms) + if err != nil { + return err + } + + ms.enabledSetByUser = parser.IsSet("enabled") + return nil +} + +func (ms *DefaultMetricMetricConfig) Validate() error { + for _, val := range ms.EnabledAttributes { + switch val { + case DefaultMetricMetricAttributeKeyStringAttr, DefaultMetricMetricAttributeKeyOverriddenIntAttr, DefaultMetricMetricAttributeKeyEnumAttr, DefaultMetricMetricAttributeKeySliceAttr, DefaultMetricMetricAttributeKeyMapAttr: + default: + return fmt.Errorf("metric default.metric doesn't have an attribute %v, valid attributes: [string_attr, state, enum_attr, slice_attr, map_attr]", val) + } + } + + switch ms.AggregationStrategy { + case AggregationStrategySum, AggregationStrategyAvg, AggregationStrategyMin, AggregationStrategyMax: + default: + return fmt.Errorf("invalid aggregation strategy %q, valid strategies: [%s, %s, %s, %s]", ms.AggregationStrategy, AggregationStrategySum, AggregationStrategyAvg, AggregationStrategyMin, AggregationStrategyMax) + } + + return nil +} + +// DefaultMetricToBeRemovedMetricConfig provides config for the default.metric.to_be_removed metric. +type DefaultMetricToBeRemovedMetricConfig struct { + Enabled bool `mapstructure:"enabled"` + enabledSetByUser bool +} + +func (ms *DefaultMetricToBeRemovedMetricConfig) Unmarshal(parser *confmap.Conf) error { + if parser == nil { + return nil + } + + err := parser.Unmarshal(ms) + if err != nil { + return err + } + ms.enabledSetByUser = parser.IsSet("enabled") + return nil +} + +// MetricInputTypeMetricAttributeKey specifies the key of an attribute for the metric.input_type metric. +type MetricInputTypeMetricAttributeKey string + +const ( + MetricInputTypeMetricAttributeKeyStringAttr MetricInputTypeMetricAttributeKey = "string_attr" + MetricInputTypeMetricAttributeKeyOverriddenIntAttr MetricInputTypeMetricAttributeKey = "state" + MetricInputTypeMetricAttributeKeyEnumAttr MetricInputTypeMetricAttributeKey = "enum_attr" + MetricInputTypeMetricAttributeKeySliceAttr MetricInputTypeMetricAttributeKey = "slice_attr" + MetricInputTypeMetricAttributeKeyMapAttr MetricInputTypeMetricAttributeKey = "map_attr" +) + +// MetricInputTypeMetricConfig provides config for the metric.input_type metric. +type MetricInputTypeMetricConfig struct { + Enabled bool `mapstructure:"enabled"` + enabledSetByUser bool + + AggregationStrategy string `mapstructure:"aggregation_strategy"` + EnabledAttributes []MetricInputTypeMetricAttributeKey `mapstructure:"attributes"` +} + +func (ms *MetricInputTypeMetricConfig) Unmarshal(parser *confmap.Conf) error { + if parser == nil { + return nil + } + + err := parser.Unmarshal(ms) + if err != nil { + return err + } + + ms.enabledSetByUser = parser.IsSet("enabled") + return nil +} + +func (ms *MetricInputTypeMetricConfig) Validate() error { + for _, val := range ms.EnabledAttributes { + switch val { + case MetricInputTypeMetricAttributeKeyStringAttr, MetricInputTypeMetricAttributeKeyOverriddenIntAttr, MetricInputTypeMetricAttributeKeyEnumAttr, MetricInputTypeMetricAttributeKeySliceAttr, MetricInputTypeMetricAttributeKeyMapAttr: + default: + return fmt.Errorf("metric metric.input_type doesn't have an attribute %v, valid attributes: [string_attr, state, enum_attr, slice_attr, map_attr]", val) + } + } + + switch ms.AggregationStrategy { + case AggregationStrategySum, AggregationStrategyAvg, AggregationStrategyMin, AggregationStrategyMax: + default: + return fmt.Errorf("invalid aggregation strategy %q, valid strategies: [%s, %s, %s, %s]", ms.AggregationStrategy, AggregationStrategySum, AggregationStrategyAvg, AggregationStrategyMin, AggregationStrategyMax) + } + + return nil +} + +// OptionalMetricMetricAttributeKey specifies the key of an attribute for the optional.metric metric. +type OptionalMetricMetricAttributeKey string + +const ( + OptionalMetricMetricAttributeKeyStringAttr OptionalMetricMetricAttributeKey = "string_attr" + OptionalMetricMetricAttributeKeyBooleanAttr OptionalMetricMetricAttributeKey = "boolean_attr" + OptionalMetricMetricAttributeKeyBooleanAttr2 OptionalMetricMetricAttributeKey = "boolean_attr2" +) + +// OptionalMetricMetricConfig provides config for the optional.metric metric. +type OptionalMetricMetricConfig struct { + Enabled bool `mapstructure:"enabled"` enabledSetByUser bool + + AggregationStrategy string `mapstructure:"aggregation_strategy"` + EnabledAttributes []OptionalMetricMetricAttributeKey `mapstructure:"attributes"` } -func (ms *MetricConfig) Unmarshal(parser *confmap.Conf) error { +func (ms *OptionalMetricMetricConfig) Unmarshal(parser *confmap.Conf) error { if parser == nil { return nil } + err := parser.Unmarshal(ms) if err != nil { return err } + + ms.enabledSetByUser = parser.IsSet("enabled") + return nil +} + +func (ms *OptionalMetricMetricConfig) Validate() error { + for _, val := range ms.EnabledAttributes { + switch val { + case OptionalMetricMetricAttributeKeyStringAttr, OptionalMetricMetricAttributeKeyBooleanAttr, OptionalMetricMetricAttributeKeyBooleanAttr2: + default: + return fmt.Errorf("metric optional.metric doesn't have an attribute %v, valid attributes: [string_attr, boolean_attr, boolean_attr2]", val) + } + } + + switch ms.AggregationStrategy { + case AggregationStrategySum, AggregationStrategyAvg, AggregationStrategyMin, AggregationStrategyMax: + default: + return fmt.Errorf("invalid aggregation strategy %q, valid strategies: [%s, %s, %s, %s]", ms.AggregationStrategy, AggregationStrategySum, AggregationStrategyAvg, AggregationStrategyMin, AggregationStrategyMax) + } + + return nil +} + +// OptionalMetricEmptyUnitMetricAttributeKey specifies the key of an attribute for the optional.metric.empty_unit metric. +type OptionalMetricEmptyUnitMetricAttributeKey string + +const ( + OptionalMetricEmptyUnitMetricAttributeKeyStringAttr OptionalMetricEmptyUnitMetricAttributeKey = "string_attr" + OptionalMetricEmptyUnitMetricAttributeKeyBooleanAttr OptionalMetricEmptyUnitMetricAttributeKey = "boolean_attr" +) + +// OptionalMetricEmptyUnitMetricConfig provides config for the optional.metric.empty_unit metric. +type OptionalMetricEmptyUnitMetricConfig struct { + Enabled bool `mapstructure:"enabled"` + enabledSetByUser bool + + AggregationStrategy string `mapstructure:"aggregation_strategy"` + EnabledAttributes []OptionalMetricEmptyUnitMetricAttributeKey `mapstructure:"attributes"` +} + +func (ms *OptionalMetricEmptyUnitMetricConfig) Unmarshal(parser *confmap.Conf) error { + if parser == nil { + return nil + } + + err := parser.Unmarshal(ms) + if err != nil { + return err + } + + ms.enabledSetByUser = parser.IsSet("enabled") + return nil +} + +func (ms *OptionalMetricEmptyUnitMetricConfig) Validate() error { + for _, val := range ms.EnabledAttributes { + switch val { + case OptionalMetricEmptyUnitMetricAttributeKeyStringAttr, OptionalMetricEmptyUnitMetricAttributeKeyBooleanAttr: + default: + return fmt.Errorf("metric optional.metric.empty_unit doesn't have an attribute %v, valid attributes: [string_attr, boolean_attr]", val) + } + } + + switch ms.AggregationStrategy { + case AggregationStrategySum, AggregationStrategyAvg, AggregationStrategyMin, AggregationStrategyMax: + default: + return fmt.Errorf("invalid aggregation strategy %q, valid strategies: [%s, %s, %s, %s]", ms.AggregationStrategy, AggregationStrategySum, AggregationStrategyAvg, AggregationStrategyMin, AggregationStrategyMax) + } + + return nil +} + +// ReaggregateMetricMetricAttributeKey specifies the key of an attribute for the reaggregate.metric metric. +type ReaggregateMetricMetricAttributeKey string + +const ( + ReaggregateMetricMetricAttributeKeyStringAttr ReaggregateMetricMetricAttributeKey = "string_attr" + ReaggregateMetricMetricAttributeKeyBooleanAttr ReaggregateMetricMetricAttributeKey = "boolean_attr" +) + +// ReaggregateMetricMetricConfig provides config for the reaggregate.metric metric. +type ReaggregateMetricMetricConfig struct { + Enabled bool `mapstructure:"enabled"` + enabledSetByUser bool + + AggregationStrategy string `mapstructure:"aggregation_strategy"` + EnabledAttributes []ReaggregateMetricMetricAttributeKey `mapstructure:"attributes"` +} + +func (ms *ReaggregateMetricMetricConfig) Unmarshal(parser *confmap.Conf) error { + if parser == nil { + return nil + } + + err := parser.Unmarshal(ms) + if err != nil { + return err + } + + ms.enabledSetByUser = parser.IsSet("enabled") + return nil +} + +func (ms *ReaggregateMetricMetricConfig) Validate() error { + for _, val := range ms.EnabledAttributes { + switch val { + case ReaggregateMetricMetricAttributeKeyStringAttr, ReaggregateMetricMetricAttributeKeyBooleanAttr: + default: + return fmt.Errorf("metric reaggregate.metric doesn't have an attribute %v, valid attributes: [string_attr, boolean_attr]", val) + } + } + + switch ms.AggregationStrategy { + case AggregationStrategySum, AggregationStrategyAvg, AggregationStrategyMin, AggregationStrategyMax: + default: + return fmt.Errorf("invalid aggregation strategy %q, valid strategies: [%s, %s, %s, %s]", ms.AggregationStrategy, AggregationStrategySum, AggregationStrategyAvg, AggregationStrategyMin, AggregationStrategyMax) + } + + return nil +} + +// SystemCPUTimeMetricConfig provides config for the system.cpu.time metric. +type SystemCPUTimeMetricConfig struct { + Enabled bool `mapstructure:"enabled"` + enabledSetByUser bool +} + +func (ms *SystemCPUTimeMetricConfig) Unmarshal(parser *confmap.Conf) error { + if parser == nil { + return nil + } + + err := parser.Unmarshal(ms) + if err != nil { + return err + } + ms.enabledSetByUser = parser.IsSet("enabled") return nil } // MetricsConfig provides config for sample metrics. type MetricsConfig struct { - DefaultMetric MetricConfig `mapstructure:"default.metric"` - DefaultMetricToBeRemoved MetricConfig `mapstructure:"default.metric.to_be_removed"` - MetricInputType MetricConfig `mapstructure:"metric.input_type"` - OptionalMetric MetricConfig `mapstructure:"optional.metric"` - OptionalMetricEmptyUnit MetricConfig `mapstructure:"optional.metric.empty_unit"` - SystemCPUTime MetricConfig `mapstructure:"system.cpu.time"` + DefaultMetric DefaultMetricMetricConfig `mapstructure:"default.metric"` + DefaultMetricToBeRemoved DefaultMetricToBeRemovedMetricConfig `mapstructure:"default.metric.to_be_removed"` + MetricInputType MetricInputTypeMetricConfig `mapstructure:"metric.input_type"` + OptionalMetric OptionalMetricMetricConfig `mapstructure:"optional.metric"` + OptionalMetricEmptyUnit OptionalMetricEmptyUnitMetricConfig `mapstructure:"optional.metric.empty_unit"` + ReaggregateMetric ReaggregateMetricMetricConfig `mapstructure:"reaggregate.metric"` + SystemCPUTime SystemCPUTimeMetricConfig `mapstructure:"system.cpu.time"` } func DefaultMetricsConfig() MetricsConfig { return MetricsConfig{ - DefaultMetric: MetricConfig{ - Enabled: true, + DefaultMetric: DefaultMetricMetricConfig{ + Enabled: true, + AggregationStrategy: AggregationStrategySum, + EnabledAttributes: []DefaultMetricMetricAttributeKey{DefaultMetricMetricAttributeKeyStringAttr, DefaultMetricMetricAttributeKeyOverriddenIntAttr, DefaultMetricMetricAttributeKeyEnumAttr, DefaultMetricMetricAttributeKeySliceAttr, DefaultMetricMetricAttributeKeyMapAttr}, }, - DefaultMetricToBeRemoved: MetricConfig{ + DefaultMetricToBeRemoved: DefaultMetricToBeRemovedMetricConfig{ Enabled: true, }, - MetricInputType: MetricConfig{ - Enabled: true, + MetricInputType: MetricInputTypeMetricConfig{ + Enabled: true, + AggregationStrategy: AggregationStrategySum, + EnabledAttributes: []MetricInputTypeMetricAttributeKey{MetricInputTypeMetricAttributeKeyStringAttr, MetricInputTypeMetricAttributeKeyOverriddenIntAttr, MetricInputTypeMetricAttributeKeyEnumAttr, MetricInputTypeMetricAttributeKeySliceAttr, MetricInputTypeMetricAttributeKeyMapAttr}, }, - OptionalMetric: MetricConfig{ - Enabled: false, + OptionalMetric: OptionalMetricMetricConfig{ + Enabled: false, + AggregationStrategy: AggregationStrategyAvg, + EnabledAttributes: []OptionalMetricMetricAttributeKey{OptionalMetricMetricAttributeKeyStringAttr, OptionalMetricMetricAttributeKeyBooleanAttr, OptionalMetricMetricAttributeKeyBooleanAttr2}, }, - OptionalMetricEmptyUnit: MetricConfig{ - Enabled: false, + OptionalMetricEmptyUnit: OptionalMetricEmptyUnitMetricConfig{ + Enabled: false, + AggregationStrategy: AggregationStrategyAvg, + EnabledAttributes: []OptionalMetricEmptyUnitMetricAttributeKey{OptionalMetricEmptyUnitMetricAttributeKeyStringAttr, OptionalMetricEmptyUnitMetricAttributeKeyBooleanAttr}, + }, + ReaggregateMetric: ReaggregateMetricMetricConfig{ + Enabled: true, + AggregationStrategy: AggregationStrategyAvg, + EnabledAttributes: []ReaggregateMetricMetricAttributeKey{ReaggregateMetricMetricAttributeKeyStringAttr, ReaggregateMetricMetricAttributeKeyBooleanAttr}, }, - SystemCPUTime: MetricConfig{ + SystemCPUTime: SystemCPUTimeMetricConfig{ Enabled: true, }, } diff --git a/cmd/mdatagen/internal/samplescraper/internal/metadata/generated_config_test.go b/cmd/mdatagen/internal/samplescraper/internal/metadata/generated_config_test.go index d68dcc807a0b..8ce5e887b582 100644 --- a/cmd/mdatagen/internal/samplescraper/internal/metadata/generated_config_test.go +++ b/cmd/mdatagen/internal/samplescraper/internal/metadata/generated_config_test.go @@ -27,12 +27,37 @@ func TestMetricsBuilderConfig(t *testing.T) { name: "all_set", want: MetricsBuilderConfig{ Metrics: MetricsConfig{ - DefaultMetric: MetricConfig{Enabled: true}, - DefaultMetricToBeRemoved: MetricConfig{Enabled: true}, - MetricInputType: MetricConfig{Enabled: true}, - OptionalMetric: MetricConfig{Enabled: true}, - OptionalMetricEmptyUnit: MetricConfig{Enabled: true}, - SystemCPUTime: MetricConfig{Enabled: true}, + DefaultMetric: DefaultMetricMetricConfig{ + Enabled: true, + AggregationStrategy: AggregationStrategySum, + EnabledAttributes: []DefaultMetricMetricAttributeKey{DefaultMetricMetricAttributeKeyStringAttr, DefaultMetricMetricAttributeKeyOverriddenIntAttr, DefaultMetricMetricAttributeKeyEnumAttr, DefaultMetricMetricAttributeKeySliceAttr, DefaultMetricMetricAttributeKeyMapAttr}, + }, + DefaultMetricToBeRemoved: DefaultMetricToBeRemovedMetricConfig{ + Enabled: true, + }, + MetricInputType: MetricInputTypeMetricConfig{ + Enabled: true, + AggregationStrategy: AggregationStrategySum, + EnabledAttributes: []MetricInputTypeMetricAttributeKey{MetricInputTypeMetricAttributeKeyStringAttr, MetricInputTypeMetricAttributeKeyOverriddenIntAttr, MetricInputTypeMetricAttributeKeyEnumAttr, MetricInputTypeMetricAttributeKeySliceAttr, MetricInputTypeMetricAttributeKeyMapAttr}, + }, + OptionalMetric: OptionalMetricMetricConfig{ + Enabled: true, + AggregationStrategy: AggregationStrategyAvg, + EnabledAttributes: []OptionalMetricMetricAttributeKey{OptionalMetricMetricAttributeKeyStringAttr, OptionalMetricMetricAttributeKeyBooleanAttr, OptionalMetricMetricAttributeKeyBooleanAttr2}, + }, + OptionalMetricEmptyUnit: OptionalMetricEmptyUnitMetricConfig{ + Enabled: true, + AggregationStrategy: AggregationStrategyAvg, + EnabledAttributes: []OptionalMetricEmptyUnitMetricAttributeKey{OptionalMetricEmptyUnitMetricAttributeKeyStringAttr, OptionalMetricEmptyUnitMetricAttributeKeyBooleanAttr}, + }, + ReaggregateMetric: ReaggregateMetricMetricConfig{ + Enabled: true, + AggregationStrategy: AggregationStrategyAvg, + EnabledAttributes: []ReaggregateMetricMetricAttributeKey{ReaggregateMetricMetricAttributeKeyStringAttr, ReaggregateMetricMetricAttributeKeyBooleanAttr}, + }, + SystemCPUTime: SystemCPUTimeMetricConfig{ + Enabled: true, + }, }, ResourceAttributes: ResourceAttributesConfig{ MapResourceAttr: ResourceAttributeConfig{Enabled: true}, @@ -50,12 +75,37 @@ func TestMetricsBuilderConfig(t *testing.T) { name: "none_set", want: MetricsBuilderConfig{ Metrics: MetricsConfig{ - DefaultMetric: MetricConfig{Enabled: false}, - DefaultMetricToBeRemoved: MetricConfig{Enabled: false}, - MetricInputType: MetricConfig{Enabled: false}, - OptionalMetric: MetricConfig{Enabled: false}, - OptionalMetricEmptyUnit: MetricConfig{Enabled: false}, - SystemCPUTime: MetricConfig{Enabled: false}, + DefaultMetric: DefaultMetricMetricConfig{ + Enabled: false, + AggregationStrategy: AggregationStrategySum, + EnabledAttributes: []DefaultMetricMetricAttributeKey{DefaultMetricMetricAttributeKeyStringAttr, DefaultMetricMetricAttributeKeyOverriddenIntAttr, DefaultMetricMetricAttributeKeyEnumAttr, DefaultMetricMetricAttributeKeySliceAttr, DefaultMetricMetricAttributeKeyMapAttr}, + }, + DefaultMetricToBeRemoved: DefaultMetricToBeRemovedMetricConfig{ + Enabled: false, + }, + MetricInputType: MetricInputTypeMetricConfig{ + Enabled: false, + AggregationStrategy: AggregationStrategySum, + EnabledAttributes: []MetricInputTypeMetricAttributeKey{MetricInputTypeMetricAttributeKeyStringAttr, MetricInputTypeMetricAttributeKeyOverriddenIntAttr, MetricInputTypeMetricAttributeKeyEnumAttr, MetricInputTypeMetricAttributeKeySliceAttr, MetricInputTypeMetricAttributeKeyMapAttr}, + }, + OptionalMetric: OptionalMetricMetricConfig{ + Enabled: false, + AggregationStrategy: AggregationStrategyAvg, + EnabledAttributes: []OptionalMetricMetricAttributeKey{OptionalMetricMetricAttributeKeyStringAttr, OptionalMetricMetricAttributeKeyBooleanAttr, OptionalMetricMetricAttributeKeyBooleanAttr2}, + }, + OptionalMetricEmptyUnit: OptionalMetricEmptyUnitMetricConfig{ + Enabled: false, + AggregationStrategy: AggregationStrategyAvg, + EnabledAttributes: []OptionalMetricEmptyUnitMetricAttributeKey{OptionalMetricEmptyUnitMetricAttributeKeyStringAttr, OptionalMetricEmptyUnitMetricAttributeKeyBooleanAttr}, + }, + ReaggregateMetric: ReaggregateMetricMetricConfig{ + Enabled: false, + AggregationStrategy: AggregationStrategyAvg, + EnabledAttributes: []ReaggregateMetricMetricAttributeKey{ReaggregateMetricMetricAttributeKeyStringAttr, ReaggregateMetricMetricAttributeKeyBooleanAttr}, + }, + SystemCPUTime: SystemCPUTimeMetricConfig{ + Enabled: false, + }, }, ResourceAttributes: ResourceAttributesConfig{ MapResourceAttr: ResourceAttributeConfig{Enabled: false}, @@ -73,7 +123,7 @@ func TestMetricsBuilderConfig(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { cfg := loadMetricsBuilderConfig(t, tt.name) - diff := cmp.Diff(tt.want, cfg, cmpopts.IgnoreUnexported(MetricConfig{}, ResourceAttributeConfig{})) + diff := cmp.Diff(tt.want, cfg, cmpopts.IgnoreUnexported(DefaultMetricMetricConfig{}, DefaultMetricToBeRemovedMetricConfig{}, MetricInputTypeMetricConfig{}, OptionalMetricMetricConfig{}, OptionalMetricEmptyUnitMetricConfig{}, ReaggregateMetricMetricConfig{}, SystemCPUTimeMetricConfig{}, ResourceAttributeConfig{})) require.Emptyf(t, diff, "Config mismatch (-expected +actual):\n%s", diff) }) } diff --git a/cmd/mdatagen/internal/samplescraper/internal/metadata/generated_logs.go b/cmd/mdatagen/internal/samplescraper/internal/metadata/generated_logs.go index 187b564f16a5..ff23893fc9fc 100644 --- a/cmd/mdatagen/internal/samplescraper/internal/metadata/generated_logs.go +++ b/cmd/mdatagen/internal/samplescraper/internal/metadata/generated_logs.go @@ -3,7 +3,7 @@ package metadata import ( - conventions "go.opentelemetry.io/otel/semconv/v1.37.0" + conventions "go.opentelemetry.io/otel/semconv/v1.38.0" "go.opentelemetry.io/collector/component" "go.opentelemetry.io/collector/pdata/pcommon" diff --git a/cmd/mdatagen/internal/samplescraper/internal/metadata/generated_metrics.go b/cmd/mdatagen/internal/samplescraper/internal/metadata/generated_metrics.go index 296bacb75932..27ee2837773f 100644 --- a/cmd/mdatagen/internal/samplescraper/internal/metadata/generated_metrics.go +++ b/cmd/mdatagen/internal/samplescraper/internal/metadata/generated_metrics.go @@ -4,10 +4,11 @@ package metadata import ( "fmt" + "slices" "strconv" "time" - conventions "go.opentelemetry.io/otel/semconv/v1.37.0" + conventions "go.opentelemetry.io/otel/semconv/v1.38.0" "go.opentelemetry.io/collector/component" "go.opentelemetry.io/collector/filter" @@ -16,6 +17,13 @@ import ( "go.opentelemetry.io/collector/scraper" ) +const ( + AggregationStrategySum = "sum" + AggregationStrategyAvg = "avg" + AggregationStrategyMin = "min" + AggregationStrategyMax = "max" +) + // AttributeEnumAttr specifies the value enum_attr attribute. type AttributeEnumAttr int @@ -62,6 +70,9 @@ var MetricsInfo = metricsInfo{ OptionalMetricEmptyUnit: metricInfo{ Name: "optional.metric.empty_unit", }, + ReaggregateMetric: metricInfo{ + Name: "reaggregate.metric", + }, SystemCPUTime: metricInfo{ Name: "system.cpu.time", }, @@ -73,6 +84,7 @@ type metricsInfo struct { MetricInputType metricInfo OptionalMetric metricInfo OptionalMetricEmptyUnit metricInfo + ReaggregateMetric metricInfo SystemCPUTime metricInfo } @@ -81,9 +93,10 @@ type metricInfo struct { } type metricDefaultMetric struct { - data pmetric.Metric // data buffer for generated metric. - config MetricConfig // metric config provided by user. - capacity int // max observed number of data points added to the metric. + data pmetric.Metric // data buffer for generated metric. + config DefaultMetricMetricConfig // metric config provided by user. + capacity int // max observed number of data points added to the metric. + aggDataPoints []int64 // slice containing number of aggregated datapoints at each index } // init fills default.metric metric with initial data. @@ -95,21 +108,60 @@ func (m *metricDefaultMetric) init() { m.data.Sum().SetIsMonotonic(true) m.data.Sum().SetAggregationTemporality(pmetric.AggregationTemporalityCumulative) m.data.Sum().DataPoints().EnsureCapacity(m.capacity) + m.aggDataPoints = m.aggDataPoints[:0] } func (m *metricDefaultMetric) recordDataPoint(start pcommon.Timestamp, ts pcommon.Timestamp, val int64, stringAttrAttributeValue string, overriddenIntAttrAttributeValue int64, enumAttrAttributeValue string, sliceAttrAttributeValue []any, mapAttrAttributeValue map[string]any) { if !m.config.Enabled { return } - dp := m.data.Sum().DataPoints().AppendEmpty() + + dp := pmetric.NewNumberDataPoint() dp.SetStartTimestamp(start) dp.SetTimestamp(ts) + if slices.Contains(m.config.EnabledAttributes, DefaultMetricMetricAttributeKeyStringAttr) { + dp.Attributes().PutStr("string_attr", stringAttrAttributeValue) + } + if slices.Contains(m.config.EnabledAttributes, DefaultMetricMetricAttributeKeyOverriddenIntAttr) { + dp.Attributes().PutInt("state", overriddenIntAttrAttributeValue) + } + if slices.Contains(m.config.EnabledAttributes, DefaultMetricMetricAttributeKeyEnumAttr) { + dp.Attributes().PutStr("enum_attr", enumAttrAttributeValue) + } + if slices.Contains(m.config.EnabledAttributes, DefaultMetricMetricAttributeKeySliceAttr) { + dp.Attributes().PutEmptySlice("slice_attr").FromRaw(sliceAttrAttributeValue) + } + if slices.Contains(m.config.EnabledAttributes, DefaultMetricMetricAttributeKeyMapAttr) { + dp.Attributes().PutEmptyMap("map_attr").FromRaw(mapAttrAttributeValue) + } + + var s string + dps := m.data.Sum().DataPoints() + for i := 0; i < dps.Len(); i++ { + dpi := dps.At(i) + if dp.Attributes().Equal(dpi.Attributes()) && dp.StartTimestamp() == dpi.StartTimestamp() && dp.Timestamp() == dpi.Timestamp() { + switch s = m.config.AggregationStrategy; s { + case AggregationStrategySum, AggregationStrategyAvg: + dpi.SetIntValue(dpi.IntValue() + val) + m.aggDataPoints[i] += 1 + return + case AggregationStrategyMin: + if dpi.IntValue() > val { + dpi.SetIntValue(val) + } + return + case AggregationStrategyMax: + if dpi.IntValue() < val { + dpi.SetIntValue(val) + } + return + } + } + } + dp.SetIntValue(val) - dp.Attributes().PutStr("string_attr", stringAttrAttributeValue) - dp.Attributes().PutInt("state", overriddenIntAttrAttributeValue) - dp.Attributes().PutStr("enum_attr", enumAttrAttributeValue) - dp.Attributes().PutEmptySlice("slice_attr").FromRaw(sliceAttrAttributeValue) - dp.Attributes().PutEmptyMap("map_attr").FromRaw(mapAttrAttributeValue) + m.aggDataPoints = append(m.aggDataPoints, 1) + dp.MoveTo(dps.AppendEmpty()) } // updateCapacity saves max length of data point slices that will be used for the slice capacity. @@ -122,14 +174,20 @@ func (m *metricDefaultMetric) updateCapacity() { // emit appends recorded metric data to a metrics slice and prepares it for recording another set of data points. func (m *metricDefaultMetric) emit(metrics pmetric.MetricSlice) { if m.config.Enabled && m.data.Sum().DataPoints().Len() > 0 { + if m.config.AggregationStrategy == AggregationStrategyAvg { + for i, aggCount := range m.aggDataPoints { + m.data.Sum().DataPoints().At(i).SetIntValue(m.data.Sum().DataPoints().At(i).IntValue() / aggCount) + } + } m.updateCapacity() m.data.MoveTo(metrics.AppendEmpty()) m.init() } } -func newMetricDefaultMetric(cfg MetricConfig) metricDefaultMetric { +func newMetricDefaultMetric(cfg DefaultMetricMetricConfig) metricDefaultMetric { m := metricDefaultMetric{config: cfg} + if cfg.Enabled { m.data = pmetric.NewMetric() m.init() @@ -138,9 +196,9 @@ func newMetricDefaultMetric(cfg MetricConfig) metricDefaultMetric { } type metricDefaultMetricToBeRemoved struct { - data pmetric.Metric // data buffer for generated metric. - config MetricConfig // metric config provided by user. - capacity int // max observed number of data points added to the metric. + data pmetric.Metric // data buffer for generated metric. + config DefaultMetricToBeRemovedMetricConfig // metric config provided by user. + capacity int // max observed number of data points added to the metric. } // init fills default.metric.to_be_removed metric with initial data. @@ -179,8 +237,9 @@ func (m *metricDefaultMetricToBeRemoved) emit(metrics pmetric.MetricSlice) { } } -func newMetricDefaultMetricToBeRemoved(cfg MetricConfig) metricDefaultMetricToBeRemoved { +func newMetricDefaultMetricToBeRemoved(cfg DefaultMetricToBeRemovedMetricConfig) metricDefaultMetricToBeRemoved { m := metricDefaultMetricToBeRemoved{config: cfg} + if cfg.Enabled { m.data = pmetric.NewMetric() m.init() @@ -189,9 +248,10 @@ func newMetricDefaultMetricToBeRemoved(cfg MetricConfig) metricDefaultMetricToBe } type metricMetricInputType struct { - data pmetric.Metric // data buffer for generated metric. - config MetricConfig // metric config provided by user. - capacity int // max observed number of data points added to the metric. + data pmetric.Metric // data buffer for generated metric. + config MetricInputTypeMetricConfig // metric config provided by user. + capacity int // max observed number of data points added to the metric. + aggDataPoints []int64 // slice containing number of aggregated datapoints at each index } // init fills metric.input_type metric with initial data. @@ -203,21 +263,60 @@ func (m *metricMetricInputType) init() { m.data.Sum().SetIsMonotonic(true) m.data.Sum().SetAggregationTemporality(pmetric.AggregationTemporalityCumulative) m.data.Sum().DataPoints().EnsureCapacity(m.capacity) + m.aggDataPoints = m.aggDataPoints[:0] } func (m *metricMetricInputType) recordDataPoint(start pcommon.Timestamp, ts pcommon.Timestamp, val int64, stringAttrAttributeValue string, overriddenIntAttrAttributeValue int64, enumAttrAttributeValue string, sliceAttrAttributeValue []any, mapAttrAttributeValue map[string]any) { if !m.config.Enabled { return } - dp := m.data.Sum().DataPoints().AppendEmpty() + + dp := pmetric.NewNumberDataPoint() dp.SetStartTimestamp(start) dp.SetTimestamp(ts) + if slices.Contains(m.config.EnabledAttributes, MetricInputTypeMetricAttributeKeyStringAttr) { + dp.Attributes().PutStr("string_attr", stringAttrAttributeValue) + } + if slices.Contains(m.config.EnabledAttributes, MetricInputTypeMetricAttributeKeyOverriddenIntAttr) { + dp.Attributes().PutInt("state", overriddenIntAttrAttributeValue) + } + if slices.Contains(m.config.EnabledAttributes, MetricInputTypeMetricAttributeKeyEnumAttr) { + dp.Attributes().PutStr("enum_attr", enumAttrAttributeValue) + } + if slices.Contains(m.config.EnabledAttributes, MetricInputTypeMetricAttributeKeySliceAttr) { + dp.Attributes().PutEmptySlice("slice_attr").FromRaw(sliceAttrAttributeValue) + } + if slices.Contains(m.config.EnabledAttributes, MetricInputTypeMetricAttributeKeyMapAttr) { + dp.Attributes().PutEmptyMap("map_attr").FromRaw(mapAttrAttributeValue) + } + + var s string + dps := m.data.Sum().DataPoints() + for i := 0; i < dps.Len(); i++ { + dpi := dps.At(i) + if dp.Attributes().Equal(dpi.Attributes()) && dp.StartTimestamp() == dpi.StartTimestamp() && dp.Timestamp() == dpi.Timestamp() { + switch s = m.config.AggregationStrategy; s { + case AggregationStrategySum, AggregationStrategyAvg: + dpi.SetIntValue(dpi.IntValue() + val) + m.aggDataPoints[i] += 1 + return + case AggregationStrategyMin: + if dpi.IntValue() > val { + dpi.SetIntValue(val) + } + return + case AggregationStrategyMax: + if dpi.IntValue() < val { + dpi.SetIntValue(val) + } + return + } + } + } + dp.SetIntValue(val) - dp.Attributes().PutStr("string_attr", stringAttrAttributeValue) - dp.Attributes().PutInt("state", overriddenIntAttrAttributeValue) - dp.Attributes().PutStr("enum_attr", enumAttrAttributeValue) - dp.Attributes().PutEmptySlice("slice_attr").FromRaw(sliceAttrAttributeValue) - dp.Attributes().PutEmptyMap("map_attr").FromRaw(mapAttrAttributeValue) + m.aggDataPoints = append(m.aggDataPoints, 1) + dp.MoveTo(dps.AppendEmpty()) } // updateCapacity saves max length of data point slices that will be used for the slice capacity. @@ -230,14 +329,20 @@ func (m *metricMetricInputType) updateCapacity() { // emit appends recorded metric data to a metrics slice and prepares it for recording another set of data points. func (m *metricMetricInputType) emit(metrics pmetric.MetricSlice) { if m.config.Enabled && m.data.Sum().DataPoints().Len() > 0 { + if m.config.AggregationStrategy == AggregationStrategyAvg { + for i, aggCount := range m.aggDataPoints { + m.data.Sum().DataPoints().At(i).SetIntValue(m.data.Sum().DataPoints().At(i).IntValue() / aggCount) + } + } m.updateCapacity() m.data.MoveTo(metrics.AppendEmpty()) m.init() } } -func newMetricMetricInputType(cfg MetricConfig) metricMetricInputType { +func newMetricMetricInputType(cfg MetricInputTypeMetricConfig) metricMetricInputType { m := metricMetricInputType{config: cfg} + if cfg.Enabled { m.data = pmetric.NewMetric() m.init() @@ -246,9 +351,10 @@ func newMetricMetricInputType(cfg MetricConfig) metricMetricInputType { } type metricOptionalMetric struct { - data pmetric.Metric // data buffer for generated metric. - config MetricConfig // metric config provided by user. - capacity int // max observed number of data points added to the metric. + data pmetric.Metric // data buffer for generated metric. + config OptionalMetricMetricConfig // metric config provided by user. + capacity int // max observed number of data points added to the metric. + aggDataPoints []float64 // slice containing number of aggregated datapoints at each index } // init fills optional.metric metric with initial data. @@ -258,19 +364,54 @@ func (m *metricOptionalMetric) init() { m.data.SetUnit("1") m.data.SetEmptyGauge() m.data.Gauge().DataPoints().EnsureCapacity(m.capacity) + m.aggDataPoints = m.aggDataPoints[:0] } func (m *metricOptionalMetric) recordDataPoint(start pcommon.Timestamp, ts pcommon.Timestamp, val float64, stringAttrAttributeValue string, booleanAttrAttributeValue bool, booleanAttr2AttributeValue bool) { if !m.config.Enabled { return } - dp := m.data.Gauge().DataPoints().AppendEmpty() + + dp := pmetric.NewNumberDataPoint() dp.SetStartTimestamp(start) dp.SetTimestamp(ts) + if slices.Contains(m.config.EnabledAttributes, OptionalMetricMetricAttributeKeyStringAttr) { + dp.Attributes().PutStr("string_attr", stringAttrAttributeValue) + } + if slices.Contains(m.config.EnabledAttributes, OptionalMetricMetricAttributeKeyBooleanAttr) { + dp.Attributes().PutBool("boolean_attr", booleanAttrAttributeValue) + } + if slices.Contains(m.config.EnabledAttributes, OptionalMetricMetricAttributeKeyBooleanAttr2) { + dp.Attributes().PutBool("boolean_attr2", booleanAttr2AttributeValue) + } + + var s string + dps := m.data.Gauge().DataPoints() + for i := 0; i < dps.Len(); i++ { + dpi := dps.At(i) + if dp.Attributes().Equal(dpi.Attributes()) && dp.StartTimestamp() == dpi.StartTimestamp() && dp.Timestamp() == dpi.Timestamp() { + switch s = m.config.AggregationStrategy; s { + case AggregationStrategySum, AggregationStrategyAvg: + dpi.SetDoubleValue(dpi.DoubleValue() + val) + m.aggDataPoints[i] += 1 + return + case AggregationStrategyMin: + if dpi.DoubleValue() > val { + dpi.SetDoubleValue(val) + } + return + case AggregationStrategyMax: + if dpi.DoubleValue() < val { + dpi.SetDoubleValue(val) + } + return + } + } + } + dp.SetDoubleValue(val) - dp.Attributes().PutStr("string_attr", stringAttrAttributeValue) - dp.Attributes().PutBool("boolean_attr", booleanAttrAttributeValue) - dp.Attributes().PutBool("boolean_attr2", booleanAttr2AttributeValue) + m.aggDataPoints = append(m.aggDataPoints, 1) + dp.MoveTo(dps.AppendEmpty()) } // updateCapacity saves max length of data point slices that will be used for the slice capacity. @@ -283,14 +424,20 @@ func (m *metricOptionalMetric) updateCapacity() { // emit appends recorded metric data to a metrics slice and prepares it for recording another set of data points. func (m *metricOptionalMetric) emit(metrics pmetric.MetricSlice) { if m.config.Enabled && m.data.Gauge().DataPoints().Len() > 0 { + if m.config.AggregationStrategy == AggregationStrategyAvg { + for i, aggCount := range m.aggDataPoints { + m.data.Gauge().DataPoints().At(i).SetDoubleValue(m.data.Gauge().DataPoints().At(i).DoubleValue() / aggCount) + } + } m.updateCapacity() m.data.MoveTo(metrics.AppendEmpty()) m.init() } } -func newMetricOptionalMetric(cfg MetricConfig) metricOptionalMetric { +func newMetricOptionalMetric(cfg OptionalMetricMetricConfig) metricOptionalMetric { m := metricOptionalMetric{config: cfg} + if cfg.Enabled { m.data = pmetric.NewMetric() m.init() @@ -299,9 +446,10 @@ func newMetricOptionalMetric(cfg MetricConfig) metricOptionalMetric { } type metricOptionalMetricEmptyUnit struct { - data pmetric.Metric // data buffer for generated metric. - config MetricConfig // metric config provided by user. - capacity int // max observed number of data points added to the metric. + data pmetric.Metric // data buffer for generated metric. + config OptionalMetricEmptyUnitMetricConfig // metric config provided by user. + capacity int // max observed number of data points added to the metric. + aggDataPoints []float64 // slice containing number of aggregated datapoints at each index } // init fills optional.metric.empty_unit metric with initial data. @@ -311,18 +459,51 @@ func (m *metricOptionalMetricEmptyUnit) init() { m.data.SetUnit("") m.data.SetEmptyGauge() m.data.Gauge().DataPoints().EnsureCapacity(m.capacity) + m.aggDataPoints = m.aggDataPoints[:0] } func (m *metricOptionalMetricEmptyUnit) recordDataPoint(start pcommon.Timestamp, ts pcommon.Timestamp, val float64, stringAttrAttributeValue string, booleanAttrAttributeValue bool) { if !m.config.Enabled { return } - dp := m.data.Gauge().DataPoints().AppendEmpty() + + dp := pmetric.NewNumberDataPoint() dp.SetStartTimestamp(start) dp.SetTimestamp(ts) + if slices.Contains(m.config.EnabledAttributes, OptionalMetricEmptyUnitMetricAttributeKeyStringAttr) { + dp.Attributes().PutStr("string_attr", stringAttrAttributeValue) + } + if slices.Contains(m.config.EnabledAttributes, OptionalMetricEmptyUnitMetricAttributeKeyBooleanAttr) { + dp.Attributes().PutBool("boolean_attr", booleanAttrAttributeValue) + } + + var s string + dps := m.data.Gauge().DataPoints() + for i := 0; i < dps.Len(); i++ { + dpi := dps.At(i) + if dp.Attributes().Equal(dpi.Attributes()) && dp.StartTimestamp() == dpi.StartTimestamp() && dp.Timestamp() == dpi.Timestamp() { + switch s = m.config.AggregationStrategy; s { + case AggregationStrategySum, AggregationStrategyAvg: + dpi.SetDoubleValue(dpi.DoubleValue() + val) + m.aggDataPoints[i] += 1 + return + case AggregationStrategyMin: + if dpi.DoubleValue() > val { + dpi.SetDoubleValue(val) + } + return + case AggregationStrategyMax: + if dpi.DoubleValue() < val { + dpi.SetDoubleValue(val) + } + return + } + } + } + dp.SetDoubleValue(val) - dp.Attributes().PutStr("string_attr", stringAttrAttributeValue) - dp.Attributes().PutBool("boolean_attr", booleanAttrAttributeValue) + m.aggDataPoints = append(m.aggDataPoints, 1) + dp.MoveTo(dps.AppendEmpty()) } // updateCapacity saves max length of data point slices that will be used for the slice capacity. @@ -335,14 +516,112 @@ func (m *metricOptionalMetricEmptyUnit) updateCapacity() { // emit appends recorded metric data to a metrics slice and prepares it for recording another set of data points. func (m *metricOptionalMetricEmptyUnit) emit(metrics pmetric.MetricSlice) { if m.config.Enabled && m.data.Gauge().DataPoints().Len() > 0 { + if m.config.AggregationStrategy == AggregationStrategyAvg { + for i, aggCount := range m.aggDataPoints { + m.data.Gauge().DataPoints().At(i).SetDoubleValue(m.data.Gauge().DataPoints().At(i).DoubleValue() / aggCount) + } + } m.updateCapacity() m.data.MoveTo(metrics.AppendEmpty()) m.init() } } -func newMetricOptionalMetricEmptyUnit(cfg MetricConfig) metricOptionalMetricEmptyUnit { +func newMetricOptionalMetricEmptyUnit(cfg OptionalMetricEmptyUnitMetricConfig) metricOptionalMetricEmptyUnit { m := metricOptionalMetricEmptyUnit{config: cfg} + + if cfg.Enabled { + m.data = pmetric.NewMetric() + m.init() + } + return m +} + +type metricReaggregateMetric struct { + data pmetric.Metric // data buffer for generated metric. + config ReaggregateMetricMetricConfig // metric config provided by user. + capacity int // max observed number of data points added to the metric. + aggDataPoints []float64 // slice containing number of aggregated datapoints at each index +} + +// init fills reaggregate.metric metric with initial data. +func (m *metricReaggregateMetric) init() { + m.data.SetName("reaggregate.metric") + m.data.SetDescription("Metric for testing spatial reaggregation") + m.data.SetUnit("1") + m.data.SetEmptyGauge() + m.data.Gauge().DataPoints().EnsureCapacity(m.capacity) + m.aggDataPoints = m.aggDataPoints[:0] +} + +func (m *metricReaggregateMetric) recordDataPoint(start pcommon.Timestamp, ts pcommon.Timestamp, val float64, stringAttrAttributeValue string, booleanAttrAttributeValue bool) { + if !m.config.Enabled { + return + } + + dp := pmetric.NewNumberDataPoint() + dp.SetStartTimestamp(start) + dp.SetTimestamp(ts) + if slices.Contains(m.config.EnabledAttributes, ReaggregateMetricMetricAttributeKeyStringAttr) { + dp.Attributes().PutStr("string_attr", stringAttrAttributeValue) + } + if slices.Contains(m.config.EnabledAttributes, ReaggregateMetricMetricAttributeKeyBooleanAttr) { + dp.Attributes().PutBool("boolean_attr", booleanAttrAttributeValue) + } + + var s string + dps := m.data.Gauge().DataPoints() + for i := 0; i < dps.Len(); i++ { + dpi := dps.At(i) + if dp.Attributes().Equal(dpi.Attributes()) && dp.StartTimestamp() == dpi.StartTimestamp() && dp.Timestamp() == dpi.Timestamp() { + switch s = m.config.AggregationStrategy; s { + case AggregationStrategySum, AggregationStrategyAvg: + dpi.SetDoubleValue(dpi.DoubleValue() + val) + m.aggDataPoints[i] += 1 + return + case AggregationStrategyMin: + if dpi.DoubleValue() > val { + dpi.SetDoubleValue(val) + } + return + case AggregationStrategyMax: + if dpi.DoubleValue() < val { + dpi.SetDoubleValue(val) + } + return + } + } + } + + dp.SetDoubleValue(val) + m.aggDataPoints = append(m.aggDataPoints, 1) + dp.MoveTo(dps.AppendEmpty()) +} + +// updateCapacity saves max length of data point slices that will be used for the slice capacity. +func (m *metricReaggregateMetric) updateCapacity() { + if m.data.Gauge().DataPoints().Len() > m.capacity { + m.capacity = m.data.Gauge().DataPoints().Len() + } +} + +// emit appends recorded metric data to a metrics slice and prepares it for recording another set of data points. +func (m *metricReaggregateMetric) emit(metrics pmetric.MetricSlice) { + if m.config.Enabled && m.data.Gauge().DataPoints().Len() > 0 { + if m.config.AggregationStrategy == AggregationStrategyAvg { + for i, aggCount := range m.aggDataPoints { + m.data.Gauge().DataPoints().At(i).SetDoubleValue(m.data.Gauge().DataPoints().At(i).DoubleValue() / aggCount) + } + } + m.updateCapacity() + m.data.MoveTo(metrics.AppendEmpty()) + m.init() + } +} + +func newMetricReaggregateMetric(cfg ReaggregateMetricMetricConfig) metricReaggregateMetric { + m := metricReaggregateMetric{config: cfg} + if cfg.Enabled { m.data = pmetric.NewMetric() m.init() @@ -351,9 +630,9 @@ func newMetricOptionalMetricEmptyUnit(cfg MetricConfig) metricOptionalMetricEmpt } type metricSystemCPUTime struct { - data pmetric.Metric // data buffer for generated metric. - config MetricConfig // metric config provided by user. - capacity int // max observed number of data points added to the metric. + data pmetric.Metric // data buffer for generated metric. + config SystemCPUTimeMetricConfig // metric config provided by user. + capacity int // max observed number of data points added to the metric. } // init fills system.cpu.time metric with initial data. @@ -392,8 +671,9 @@ func (m *metricSystemCPUTime) emit(metrics pmetric.MetricSlice) { } } -func newMetricSystemCPUTime(cfg MetricConfig) metricSystemCPUTime { +func newMetricSystemCPUTime(cfg SystemCPUTimeMetricConfig) metricSystemCPUTime { m := metricSystemCPUTime{config: cfg} + if cfg.Enabled { m.data = pmetric.NewMetric() m.init() @@ -416,6 +696,7 @@ type MetricsBuilder struct { metricMetricInputType metricMetricInputType metricOptionalMetric metricOptionalMetric metricOptionalMetricEmptyUnit metricOptionalMetricEmptyUnit + metricReaggregateMetric metricReaggregateMetric metricSystemCPUTime metricSystemCPUTime } @@ -468,6 +749,7 @@ func NewMetricsBuilder(mbc MetricsBuilderConfig, settings scraper.Settings, opti metricMetricInputType: newMetricMetricInputType(mbc.Metrics.MetricInputType), metricOptionalMetric: newMetricOptionalMetric(mbc.Metrics.OptionalMetric), metricOptionalMetricEmptyUnit: newMetricOptionalMetricEmptyUnit(mbc.Metrics.OptionalMetricEmptyUnit), + metricReaggregateMetric: newMetricReaggregateMetric(mbc.Metrics.ReaggregateMetric), metricSystemCPUTime: newMetricSystemCPUTime(mbc.Metrics.SystemCPUTime), resourceAttributeIncludeFilter: make(map[string]filter.Filter), resourceAttributeExcludeFilter: make(map[string]filter.Filter), @@ -595,6 +877,7 @@ func (mb *MetricsBuilder) EmitForResource(options ...ResourceMetricsOption) { mb.metricMetricInputType.emit(ils.Metrics()) mb.metricOptionalMetric.emit(ils.Metrics()) mb.metricOptionalMetricEmptyUnit.emit(ils.Metrics()) + mb.metricReaggregateMetric.emit(ils.Metrics()) mb.metricSystemCPUTime.emit(ils.Metrics()) for _, op := range options { @@ -657,6 +940,11 @@ func (mb *MetricsBuilder) RecordOptionalMetricEmptyUnitDataPoint(ts pcommon.Time mb.metricOptionalMetricEmptyUnit.recordDataPoint(mb.startTime, ts, val, stringAttrAttributeValue, booleanAttrAttributeValue) } +// RecordReaggregateMetricDataPoint adds a data point to reaggregate.metric metric. +func (mb *MetricsBuilder) RecordReaggregateMetricDataPoint(ts pcommon.Timestamp, val float64, stringAttrAttributeValue string, booleanAttrAttributeValue bool) { + mb.metricReaggregateMetric.recordDataPoint(mb.startTime, ts, val, stringAttrAttributeValue, booleanAttrAttributeValue) +} + // RecordSystemCPUTimeDataPoint adds a data point to system.cpu.time metric. func (mb *MetricsBuilder) RecordSystemCPUTimeDataPoint(ts pcommon.Timestamp, val int64) { mb.metricSystemCPUTime.recordDataPoint(mb.startTime, ts, val) diff --git a/cmd/mdatagen/internal/samplescraper/internal/metadata/generated_metrics_test.go b/cmd/mdatagen/internal/samplescraper/internal/metadata/generated_metrics_test.go index a2e2b5e55c02..2912301f5051 100644 --- a/cmd/mdatagen/internal/samplescraper/internal/metadata/generated_metrics_test.go +++ b/cmd/mdatagen/internal/samplescraper/internal/metadata/generated_metrics_test.go @@ -20,6 +20,7 @@ const ( testDataSetDefault testDataSet = iota testDataSetAll testDataSetNone + testDataSetReag ) func TestMetricsBuilder(t *testing.T) { @@ -37,6 +38,11 @@ func TestMetricsBuilder(t *testing.T) { metricsSet: testDataSetAll, resAttrsSet: testDataSetAll, }, + { + name: "reaggregate_set", + metricsSet: testDataSetReag, + resAttrsSet: testDataSetReag, + }, { name: "none_set", metricsSet: testDataSetNone, @@ -61,6 +67,12 @@ func TestMetricsBuilder(t *testing.T) { settings := scrapertest.NewNopSettings(scrapertest.NopType) settings.Logger = zap.New(observedZapCore) mb := NewMetricsBuilder(loadMetricsBuilderConfig(t, tt.name), settings, WithStartTime(start)) + aggMap := make(map[string]string) // contains the aggregation strategies for each metric name + aggMap["DefaultMetric"] = mb.metricDefaultMetric.config.AggregationStrategy + aggMap["MetricInputType"] = mb.metricMetricInputType.config.AggregationStrategy + aggMap["OptionalMetric"] = mb.metricOptionalMetric.config.AggregationStrategy + aggMap["OptionalMetricEmptyUnit"] = mb.metricOptionalMetricEmptyUnit.config.AggregationStrategy + aggMap["ReaggregateMetric"] = mb.metricReaggregateMetric.config.AggregationStrategy expectedWarnings := 0 if tt.metricsSet == testDataSetDefault { @@ -91,8 +103,9 @@ func TestMetricsBuilder(t *testing.T) { assert.Equal(t, "[WARNING] `string.resource.attr_to_be_removed` should not be enabled: This resource_attribute is deprecated and will be removed soon.", observedLogs.All()[expectedWarnings].Message) expectedWarnings++ } - - assert.Equal(t, expectedWarnings, observedLogs.Len()) + if tt.metricsSet != testDataSetReag { + assert.Equal(t, expectedWarnings, observedLogs.Len()) + } defaultMetricsCount := 0 allMetricsCount := 0 @@ -100,6 +113,9 @@ func TestMetricsBuilder(t *testing.T) { defaultMetricsCount++ allMetricsCount++ mb.RecordDefaultMetricDataPoint(ts, 1, "string_attr-val", 19, AttributeEnumAttrRed, []any{"slice_attr-item1", "slice_attr-item2"}, map[string]any{"key1": "map_attr-val1", "key2": "map_attr-val2"}) + if tt.name == "reaggregate_set" { + mb.RecordDefaultMetricDataPoint(ts, 3, "string_attr-val-2", 20, AttributeEnumAttrGreen, []any{"slice_attr-item3", "slice_attr-item4"}, map[string]any{"key3": "map_attr-val3", "key4": "map_attr-val4"}) + } defaultMetricsCount++ allMetricsCount++ @@ -108,12 +124,28 @@ func TestMetricsBuilder(t *testing.T) { defaultMetricsCount++ allMetricsCount++ mb.RecordMetricInputTypeDataPoint(ts, "1", "string_attr-val", 19, AttributeEnumAttrRed, []any{"slice_attr-item1", "slice_attr-item2"}, map[string]any{"key1": "map_attr-val1", "key2": "map_attr-val2"}) + if tt.name == "reaggregate_set" { + mb.RecordMetricInputTypeDataPoint(ts, "3", "string_attr-val-2", 20, AttributeEnumAttrGreen, []any{"slice_attr-item3", "slice_attr-item4"}, map[string]any{"key3": "map_attr-val3", "key4": "map_attr-val4"}) + } allMetricsCount++ mb.RecordOptionalMetricDataPoint(ts, 1, "string_attr-val", true, false) + if tt.name == "reaggregate_set" { + mb.RecordOptionalMetricDataPoint(ts, 3, "string_attr-val-2", false, true) + } allMetricsCount++ mb.RecordOptionalMetricEmptyUnitDataPoint(ts, 1, "string_attr-val", true) + if tt.name == "reaggregate_set" { + mb.RecordOptionalMetricEmptyUnitDataPoint(ts, 3, "string_attr-val-2", false) + } + + defaultMetricsCount++ + allMetricsCount++ + mb.RecordReaggregateMetricDataPoint(ts, 1, "string_attr-val", true) + if tt.name == "reaggregate_set" { + mb.RecordReaggregateMetricDataPoint(ts, 3, "string_attr-val-2", false) + } defaultMetricsCount++ allMetricsCount++ @@ -130,147 +162,331 @@ func TestMetricsBuilder(t *testing.T) { rb.SetStringResourceAttrToBeRemoved("string.resource.attr_to_be_removed-val") res := rb.Emit() metrics := mb.Emit(WithResource(res)) + if tt.name == "reaggregate_set" { + assert.Empty(t, mb.metricDefaultMetric.aggDataPoints) + assert.Empty(t, mb.metricMetricInputType.aggDataPoints) + assert.Empty(t, mb.metricOptionalMetric.aggDataPoints) + assert.Empty(t, mb.metricOptionalMetricEmptyUnit.aggDataPoints) + assert.Empty(t, mb.metricReaggregateMetric.aggDataPoints) + } if tt.expectEmpty { assert.Equal(t, 0, metrics.ResourceMetrics().Len()) return } - assert.Equal(t, 1, metrics.ResourceMetrics().Len()) - rm := metrics.ResourceMetrics().At(0) - assert.Equal(t, res, rm.Resource()) - assert.Equal(t, 1, rm.ScopeMetrics().Len()) - ms := rm.ScopeMetrics().At(0).Metrics() + var allMetricsList []pmetric.Metric + totalMetricsCount := 0 + for ri := 0; ri < metrics.ResourceMetrics().Len(); ri++ { + rm := metrics.ResourceMetrics().At(ri) + assert.Equal(t, 1, rm.ScopeMetrics().Len()) + ms := rm.ScopeMetrics().At(0).Metrics() + totalMetricsCount += ms.Len() + for mi := 0; mi < ms.Len(); mi++ { + allMetricsList = append(allMetricsList, ms.At(mi)) + } + } if tt.metricsSet == testDataSetDefault { - assert.Equal(t, defaultMetricsCount, ms.Len()) + assert.Equal(t, defaultMetricsCount, totalMetricsCount) } if tt.metricsSet == testDataSetAll { - assert.Equal(t, allMetricsCount, ms.Len()) + assert.Equal(t, allMetricsCount, totalMetricsCount) } validatedMetrics := make(map[string]bool) - for i := 0; i < ms.Len(); i++ { - switch ms.At(i).Name() { + for _, mi := range allMetricsList { + switch mi.Name() { case "default.metric": - assert.False(t, validatedMetrics["default.metric"], "Found a duplicate in the metrics slice: default.metric") - validatedMetrics["default.metric"] = true - assert.Equal(t, pmetric.MetricTypeSum, ms.At(i).Type()) - assert.Equal(t, 1, ms.At(i).Sum().DataPoints().Len()) - assert.Equal(t, "Monotonic cumulative sum int metric enabled by default.", ms.At(i).Description()) - assert.Equal(t, "s", ms.At(i).Unit()) - assert.True(t, ms.At(i).Sum().IsMonotonic()) - assert.Equal(t, pmetric.AggregationTemporalityCumulative, ms.At(i).Sum().AggregationTemporality()) - dp := ms.At(i).Sum().DataPoints().At(0) - assert.Equal(t, start, dp.StartTimestamp()) - assert.Equal(t, ts, dp.Timestamp()) - assert.Equal(t, pmetric.NumberDataPointValueTypeInt, dp.ValueType()) - assert.Equal(t, int64(1), dp.IntValue()) - attrVal, ok := dp.Attributes().Get("string_attr") - assert.True(t, ok) - assert.Equal(t, "string_attr-val", attrVal.Str()) - attrVal, ok = dp.Attributes().Get("state") - assert.True(t, ok) - assert.EqualValues(t, 19, attrVal.Int()) - attrVal, ok = dp.Attributes().Get("enum_attr") - assert.True(t, ok) - assert.Equal(t, "red", attrVal.Str()) - attrVal, ok = dp.Attributes().Get("slice_attr") - assert.True(t, ok) - assert.Equal(t, []any{"slice_attr-item1", "slice_attr-item2"}, attrVal.Slice().AsRaw()) - attrVal, ok = dp.Attributes().Get("map_attr") - assert.True(t, ok) - assert.Equal(t, map[string]any{"key1": "map_attr-val1", "key2": "map_attr-val2"}, attrVal.Map().AsRaw()) + if tt.name != "reaggregate_set" { + assert.False(t, validatedMetrics["default.metric"], "Found a duplicate in the metrics slice: default.metric") + validatedMetrics["default.metric"] = true + assert.Equal(t, pmetric.MetricTypeSum, mi.Type()) + assert.Equal(t, 1, mi.Sum().DataPoints().Len()) + assert.Equal(t, "Monotonic cumulative sum int metric enabled by default.", mi.Description()) + assert.Equal(t, "s", mi.Unit()) + assert.True(t, mi.Sum().IsMonotonic()) + assert.Equal(t, pmetric.AggregationTemporalityCumulative, mi.Sum().AggregationTemporality()) + dp := mi.Sum().DataPoints().At(0) + assert.Equal(t, start, dp.StartTimestamp()) + assert.Equal(t, ts, dp.Timestamp()) + assert.Equal(t, pmetric.NumberDataPointValueTypeInt, dp.ValueType()) + assert.Equal(t, int64(1), dp.IntValue()) + attrVal, ok := dp.Attributes().Get("string_attr") + assert.True(t, ok) + assert.Equal(t, "string_attr-val", attrVal.Str()) + attrVal, ok = dp.Attributes().Get("state") + assert.True(t, ok) + assert.EqualValues(t, 19, attrVal.Int()) + attrVal, ok = dp.Attributes().Get("enum_attr") + assert.True(t, ok) + assert.Equal(t, "red", attrVal.Str()) + attrVal, ok = dp.Attributes().Get("slice_attr") + assert.True(t, ok) + assert.Equal(t, []any{"slice_attr-item1", "slice_attr-item2"}, attrVal.Slice().AsRaw()) + attrVal, ok = dp.Attributes().Get("map_attr") + assert.True(t, ok) + assert.Equal(t, map[string]any{"key1": "map_attr-val1", "key2": "map_attr-val2"}, attrVal.Map().AsRaw()) + } else { + assert.False(t, validatedMetrics["default.metric"], "Found a duplicate in the metrics slice: default.metric") + validatedMetrics["default.metric"] = true + assert.Equal(t, pmetric.MetricTypeSum, mi.Type()) + assert.Equal(t, 1, mi.Sum().DataPoints().Len()) + assert.Equal(t, "Monotonic cumulative sum int metric enabled by default.", mi.Description()) + assert.Equal(t, "s", mi.Unit()) + assert.True(t, mi.Sum().IsMonotonic()) + assert.Equal(t, pmetric.AggregationTemporalityCumulative, mi.Sum().AggregationTemporality()) + dp := mi.Sum().DataPoints().At(0) + assert.Equal(t, start, dp.StartTimestamp()) + assert.Equal(t, ts, dp.Timestamp()) + assert.Equal(t, pmetric.NumberDataPointValueTypeInt, dp.ValueType()) + switch aggMap["default.metric"] { + case "sum": + assert.Equal(t, int64(4), dp.IntValue()) + case "avg": + assert.Equal(t, int64(2), dp.IntValue()) + case "min": + assert.Equal(t, int64(1), dp.IntValue()) + case "max": + assert.Equal(t, int64(3), dp.IntValue()) + } + _, ok := dp.Attributes().Get("string_attr") + assert.False(t, ok) + _, ok = dp.Attributes().Get("state") + assert.False(t, ok) + _, ok = dp.Attributes().Get("enum_attr") + assert.False(t, ok) + _, ok = dp.Attributes().Get("slice_attr") + assert.False(t, ok) + _, ok = dp.Attributes().Get("map_attr") + assert.False(t, ok) + } case "default.metric.to_be_removed": assert.False(t, validatedMetrics["default.metric.to_be_removed"], "Found a duplicate in the metrics slice: default.metric.to_be_removed") validatedMetrics["default.metric.to_be_removed"] = true - assert.Equal(t, pmetric.MetricTypeSum, ms.At(i).Type()) - assert.Equal(t, 1, ms.At(i).Sum().DataPoints().Len()) - assert.Equal(t, "[DEPRECATED] Non-monotonic delta sum double metric enabled by default.", ms.At(i).Description()) - assert.Equal(t, "s", ms.At(i).Unit()) - assert.False(t, ms.At(i).Sum().IsMonotonic()) - assert.Equal(t, pmetric.AggregationTemporalityDelta, ms.At(i).Sum().AggregationTemporality()) - dp := ms.At(i).Sum().DataPoints().At(0) + assert.Equal(t, pmetric.MetricTypeSum, mi.Type()) + assert.Equal(t, 1, mi.Sum().DataPoints().Len()) + assert.Equal(t, "[DEPRECATED] Non-monotonic delta sum double metric enabled by default.", mi.Description()) + assert.Equal(t, "s", mi.Unit()) + assert.False(t, mi.Sum().IsMonotonic()) + assert.Equal(t, pmetric.AggregationTemporalityDelta, mi.Sum().AggregationTemporality()) + dp := mi.Sum().DataPoints().At(0) assert.Equal(t, start, dp.StartTimestamp()) assert.Equal(t, ts, dp.Timestamp()) assert.Equal(t, pmetric.NumberDataPointValueTypeDouble, dp.ValueType()) assert.InDelta(t, float64(1), dp.DoubleValue(), 0.01) case "metric.input_type": - assert.False(t, validatedMetrics["metric.input_type"], "Found a duplicate in the metrics slice: metric.input_type") - validatedMetrics["metric.input_type"] = true - assert.Equal(t, pmetric.MetricTypeSum, ms.At(i).Type()) - assert.Equal(t, 1, ms.At(i).Sum().DataPoints().Len()) - assert.Equal(t, "Monotonic cumulative sum int metric with string input_type enabled by default.", ms.At(i).Description()) - assert.Equal(t, "s", ms.At(i).Unit()) - assert.True(t, ms.At(i).Sum().IsMonotonic()) - assert.Equal(t, pmetric.AggregationTemporalityCumulative, ms.At(i).Sum().AggregationTemporality()) - dp := ms.At(i).Sum().DataPoints().At(0) - assert.Equal(t, start, dp.StartTimestamp()) - assert.Equal(t, ts, dp.Timestamp()) - assert.Equal(t, pmetric.NumberDataPointValueTypeInt, dp.ValueType()) - assert.Equal(t, int64(1), dp.IntValue()) - attrVal, ok := dp.Attributes().Get("string_attr") - assert.True(t, ok) - assert.Equal(t, "string_attr-val", attrVal.Str()) - attrVal, ok = dp.Attributes().Get("state") - assert.True(t, ok) - assert.EqualValues(t, 19, attrVal.Int()) - attrVal, ok = dp.Attributes().Get("enum_attr") - assert.True(t, ok) - assert.Equal(t, "red", attrVal.Str()) - attrVal, ok = dp.Attributes().Get("slice_attr") - assert.True(t, ok) - assert.Equal(t, []any{"slice_attr-item1", "slice_attr-item2"}, attrVal.Slice().AsRaw()) - attrVal, ok = dp.Attributes().Get("map_attr") - assert.True(t, ok) - assert.Equal(t, map[string]any{"key1": "map_attr-val1", "key2": "map_attr-val2"}, attrVal.Map().AsRaw()) + if tt.name != "reaggregate_set" { + assert.False(t, validatedMetrics["metric.input_type"], "Found a duplicate in the metrics slice: metric.input_type") + validatedMetrics["metric.input_type"] = true + assert.Equal(t, pmetric.MetricTypeSum, mi.Type()) + assert.Equal(t, 1, mi.Sum().DataPoints().Len()) + assert.Equal(t, "Monotonic cumulative sum int metric with string input_type enabled by default.", mi.Description()) + assert.Equal(t, "s", mi.Unit()) + assert.True(t, mi.Sum().IsMonotonic()) + assert.Equal(t, pmetric.AggregationTemporalityCumulative, mi.Sum().AggregationTemporality()) + dp := mi.Sum().DataPoints().At(0) + assert.Equal(t, start, dp.StartTimestamp()) + assert.Equal(t, ts, dp.Timestamp()) + assert.Equal(t, pmetric.NumberDataPointValueTypeInt, dp.ValueType()) + assert.Equal(t, int64(1), dp.IntValue()) + attrVal, ok := dp.Attributes().Get("string_attr") + assert.True(t, ok) + assert.Equal(t, "string_attr-val", attrVal.Str()) + attrVal, ok = dp.Attributes().Get("state") + assert.True(t, ok) + assert.EqualValues(t, 19, attrVal.Int()) + attrVal, ok = dp.Attributes().Get("enum_attr") + assert.True(t, ok) + assert.Equal(t, "red", attrVal.Str()) + attrVal, ok = dp.Attributes().Get("slice_attr") + assert.True(t, ok) + assert.Equal(t, []any{"slice_attr-item1", "slice_attr-item2"}, attrVal.Slice().AsRaw()) + attrVal, ok = dp.Attributes().Get("map_attr") + assert.True(t, ok) + assert.Equal(t, map[string]any{"key1": "map_attr-val1", "key2": "map_attr-val2"}, attrVal.Map().AsRaw()) + } else { + assert.False(t, validatedMetrics["metric.input_type"], "Found a duplicate in the metrics slice: metric.input_type") + validatedMetrics["metric.input_type"] = true + assert.Equal(t, pmetric.MetricTypeSum, mi.Type()) + assert.Equal(t, 1, mi.Sum().DataPoints().Len()) + assert.Equal(t, "Monotonic cumulative sum int metric with string input_type enabled by default.", mi.Description()) + assert.Equal(t, "s", mi.Unit()) + assert.True(t, mi.Sum().IsMonotonic()) + assert.Equal(t, pmetric.AggregationTemporalityCumulative, mi.Sum().AggregationTemporality()) + dp := mi.Sum().DataPoints().At(0) + assert.Equal(t, start, dp.StartTimestamp()) + assert.Equal(t, ts, dp.Timestamp()) + assert.Equal(t, pmetric.NumberDataPointValueTypeInt, dp.ValueType()) + switch aggMap["metric.input_type"] { + case "sum": + assert.Equal(t, int64(4), dp.IntValue()) + case "avg": + assert.Equal(t, int64(2), dp.IntValue()) + case "min": + assert.Equal(t, int64(1), dp.IntValue()) + case "max": + assert.Equal(t, int64(3), dp.IntValue()) + } + _, ok := dp.Attributes().Get("string_attr") + assert.False(t, ok) + _, ok = dp.Attributes().Get("state") + assert.False(t, ok) + _, ok = dp.Attributes().Get("enum_attr") + assert.False(t, ok) + _, ok = dp.Attributes().Get("slice_attr") + assert.False(t, ok) + _, ok = dp.Attributes().Get("map_attr") + assert.False(t, ok) + } case "optional.metric": - assert.False(t, validatedMetrics["optional.metric"], "Found a duplicate in the metrics slice: optional.metric") - validatedMetrics["optional.metric"] = true - assert.Equal(t, pmetric.MetricTypeGauge, ms.At(i).Type()) - assert.Equal(t, 1, ms.At(i).Gauge().DataPoints().Len()) - assert.Equal(t, "[DEPRECATED] Gauge double metric disabled by default.", ms.At(i).Description()) - assert.Equal(t, "1", ms.At(i).Unit()) - dp := ms.At(i).Gauge().DataPoints().At(0) - assert.Equal(t, start, dp.StartTimestamp()) - assert.Equal(t, ts, dp.Timestamp()) - assert.Equal(t, pmetric.NumberDataPointValueTypeDouble, dp.ValueType()) - assert.InDelta(t, float64(1), dp.DoubleValue(), 0.01) - attrVal, ok := dp.Attributes().Get("string_attr") - assert.True(t, ok) - assert.Equal(t, "string_attr-val", attrVal.Str()) - attrVal, ok = dp.Attributes().Get("boolean_attr") - assert.True(t, ok) - assert.True(t, attrVal.Bool()) - attrVal, ok = dp.Attributes().Get("boolean_attr2") - assert.True(t, ok) - assert.False(t, attrVal.Bool()) + if tt.name != "reaggregate_set" { + assert.False(t, validatedMetrics["optional.metric"], "Found a duplicate in the metrics slice: optional.metric") + validatedMetrics["optional.metric"] = true + assert.Equal(t, pmetric.MetricTypeGauge, mi.Type()) + assert.Equal(t, 1, mi.Gauge().DataPoints().Len()) + assert.Equal(t, "[DEPRECATED] Gauge double metric disabled by default.", mi.Description()) + assert.Equal(t, "1", mi.Unit()) + dp := mi.Gauge().DataPoints().At(0) + assert.Equal(t, start, dp.StartTimestamp()) + assert.Equal(t, ts, dp.Timestamp()) + assert.Equal(t, pmetric.NumberDataPointValueTypeDouble, dp.ValueType()) + assert.InDelta(t, float64(1), dp.DoubleValue(), 0.01) + attrVal, ok := dp.Attributes().Get("string_attr") + assert.True(t, ok) + assert.Equal(t, "string_attr-val", attrVal.Str()) + attrVal, ok = dp.Attributes().Get("boolean_attr") + assert.True(t, ok) + assert.True(t, attrVal.Bool()) + attrVal, ok = dp.Attributes().Get("boolean_attr2") + assert.True(t, ok) + assert.False(t, attrVal.Bool()) + } else { + assert.False(t, validatedMetrics["optional.metric"], "Found a duplicate in the metrics slice: optional.metric") + validatedMetrics["optional.metric"] = true + assert.Equal(t, pmetric.MetricTypeGauge, mi.Type()) + assert.Equal(t, 1, mi.Gauge().DataPoints().Len()) + assert.Equal(t, "[DEPRECATED] Gauge double metric disabled by default.", mi.Description()) + assert.Equal(t, "1", mi.Unit()) + dp := mi.Gauge().DataPoints().At(0) + assert.Equal(t, start, dp.StartTimestamp()) + assert.Equal(t, ts, dp.Timestamp()) + assert.Equal(t, pmetric.NumberDataPointValueTypeDouble, dp.ValueType()) + switch aggMap["optional.metric"] { + case "sum": + assert.InDelta(t, float64(4), dp.DoubleValue(), 0.01) + case "avg": + assert.InDelta(t, float64(2), dp.DoubleValue(), 0.01) + case "min": + assert.InDelta(t, float64(1), dp.DoubleValue(), 0.01) + case "max": + assert.InDelta(t, float64(3), dp.DoubleValue(), 0.01) + } + _, ok := dp.Attributes().Get("string_attr") + assert.False(t, ok) + _, ok = dp.Attributes().Get("boolean_attr") + assert.False(t, ok) + _, ok = dp.Attributes().Get("boolean_attr2") + assert.False(t, ok) + } case "optional.metric.empty_unit": - assert.False(t, validatedMetrics["optional.metric.empty_unit"], "Found a duplicate in the metrics slice: optional.metric.empty_unit") - validatedMetrics["optional.metric.empty_unit"] = true - assert.Equal(t, pmetric.MetricTypeGauge, ms.At(i).Type()) - assert.Equal(t, 1, ms.At(i).Gauge().DataPoints().Len()) - assert.Equal(t, "[DEPRECATED] Gauge double metric disabled by default.", ms.At(i).Description()) - assert.Empty(t, ms.At(i).Unit()) - dp := ms.At(i).Gauge().DataPoints().At(0) - assert.Equal(t, start, dp.StartTimestamp()) - assert.Equal(t, ts, dp.Timestamp()) - assert.Equal(t, pmetric.NumberDataPointValueTypeDouble, dp.ValueType()) - assert.InDelta(t, float64(1), dp.DoubleValue(), 0.01) - attrVal, ok := dp.Attributes().Get("string_attr") - assert.True(t, ok) - assert.Equal(t, "string_attr-val", attrVal.Str()) - attrVal, ok = dp.Attributes().Get("boolean_attr") - assert.True(t, ok) - assert.True(t, attrVal.Bool()) + if tt.name != "reaggregate_set" { + assert.False(t, validatedMetrics["optional.metric.empty_unit"], "Found a duplicate in the metrics slice: optional.metric.empty_unit") + validatedMetrics["optional.metric.empty_unit"] = true + assert.Equal(t, pmetric.MetricTypeGauge, mi.Type()) + assert.Equal(t, 1, mi.Gauge().DataPoints().Len()) + assert.Equal(t, "[DEPRECATED] Gauge double metric disabled by default.", mi.Description()) + assert.Empty(t, mi.Unit()) + dp := mi.Gauge().DataPoints().At(0) + assert.Equal(t, start, dp.StartTimestamp()) + assert.Equal(t, ts, dp.Timestamp()) + assert.Equal(t, pmetric.NumberDataPointValueTypeDouble, dp.ValueType()) + assert.InDelta(t, float64(1), dp.DoubleValue(), 0.01) + attrVal, ok := dp.Attributes().Get("string_attr") + assert.True(t, ok) + assert.Equal(t, "string_attr-val", attrVal.Str()) + attrVal, ok = dp.Attributes().Get("boolean_attr") + assert.True(t, ok) + assert.True(t, attrVal.Bool()) + } else { + assert.False(t, validatedMetrics["optional.metric.empty_unit"], "Found a duplicate in the metrics slice: optional.metric.empty_unit") + validatedMetrics["optional.metric.empty_unit"] = true + assert.Equal(t, pmetric.MetricTypeGauge, mi.Type()) + assert.Equal(t, 1, mi.Gauge().DataPoints().Len()) + assert.Equal(t, "[DEPRECATED] Gauge double metric disabled by default.", mi.Description()) + assert.Empty(t, mi.Unit()) + dp := mi.Gauge().DataPoints().At(0) + assert.Equal(t, start, dp.StartTimestamp()) + assert.Equal(t, ts, dp.Timestamp()) + assert.Equal(t, pmetric.NumberDataPointValueTypeDouble, dp.ValueType()) + switch aggMap["optional.metric.empty_unit"] { + case "sum": + assert.InDelta(t, float64(4), dp.DoubleValue(), 0.01) + case "avg": + assert.InDelta(t, float64(2), dp.DoubleValue(), 0.01) + case "min": + assert.InDelta(t, float64(1), dp.DoubleValue(), 0.01) + case "max": + assert.InDelta(t, float64(3), dp.DoubleValue(), 0.01) + } + _, ok := dp.Attributes().Get("string_attr") + assert.False(t, ok) + _, ok = dp.Attributes().Get("boolean_attr") + assert.False(t, ok) + } + case "reaggregate.metric": + if tt.name != "reaggregate_set" { + assert.False(t, validatedMetrics["reaggregate.metric"], "Found a duplicate in the metrics slice: reaggregate.metric") + validatedMetrics["reaggregate.metric"] = true + assert.Equal(t, pmetric.MetricTypeGauge, mi.Type()) + assert.Equal(t, 1, mi.Gauge().DataPoints().Len()) + assert.Equal(t, "Metric for testing spatial reaggregation", mi.Description()) + assert.Equal(t, "1", mi.Unit()) + dp := mi.Gauge().DataPoints().At(0) + assert.Equal(t, start, dp.StartTimestamp()) + assert.Equal(t, ts, dp.Timestamp()) + assert.Equal(t, pmetric.NumberDataPointValueTypeDouble, dp.ValueType()) + assert.InDelta(t, float64(1), dp.DoubleValue(), 0.01) + attrVal, ok := dp.Attributes().Get("string_attr") + assert.True(t, ok) + assert.Equal(t, "string_attr-val", attrVal.Str()) + attrVal, ok = dp.Attributes().Get("boolean_attr") + assert.True(t, ok) + assert.True(t, attrVal.Bool()) + } else { + assert.False(t, validatedMetrics["reaggregate.metric"], "Found a duplicate in the metrics slice: reaggregate.metric") + validatedMetrics["reaggregate.metric"] = true + assert.Equal(t, pmetric.MetricTypeGauge, mi.Type()) + assert.Equal(t, 1, mi.Gauge().DataPoints().Len()) + assert.Equal(t, "Metric for testing spatial reaggregation", mi.Description()) + assert.Equal(t, "1", mi.Unit()) + dp := mi.Gauge().DataPoints().At(0) + assert.Equal(t, start, dp.StartTimestamp()) + assert.Equal(t, ts, dp.Timestamp()) + assert.Equal(t, pmetric.NumberDataPointValueTypeDouble, dp.ValueType()) + switch aggMap["reaggregate.metric"] { + case "sum": + assert.InDelta(t, float64(4), dp.DoubleValue(), 0.01) + case "avg": + assert.InDelta(t, float64(2), dp.DoubleValue(), 0.01) + case "min": + assert.InDelta(t, float64(1), dp.DoubleValue(), 0.01) + case "max": + assert.InDelta(t, float64(3), dp.DoubleValue(), 0.01) + } + _, ok := dp.Attributes().Get("string_attr") + assert.False(t, ok) + _, ok = dp.Attributes().Get("boolean_attr") + assert.False(t, ok) + } case "system.cpu.time": assert.False(t, validatedMetrics["system.cpu.time"], "Found a duplicate in the metrics slice: system.cpu.time") validatedMetrics["system.cpu.time"] = true - assert.Equal(t, pmetric.MetricTypeSum, ms.At(i).Type()) - assert.Equal(t, 1, ms.At(i).Sum().DataPoints().Len()) - assert.Equal(t, "Monotonic cumulative sum int metric enabled by default.", ms.At(i).Description()) - assert.Equal(t, "s", ms.At(i).Unit()) - assert.True(t, ms.At(i).Sum().IsMonotonic()) - assert.Equal(t, pmetric.AggregationTemporalityCumulative, ms.At(i).Sum().AggregationTemporality()) - dp := ms.At(i).Sum().DataPoints().At(0) + assert.Equal(t, pmetric.MetricTypeSum, mi.Type()) + assert.Equal(t, 1, mi.Sum().DataPoints().Len()) + assert.Equal(t, "Monotonic cumulative sum int metric enabled by default.", mi.Description()) + assert.Equal(t, "s", mi.Unit()) + assert.True(t, mi.Sum().IsMonotonic()) + assert.Equal(t, pmetric.AggregationTemporalityCumulative, mi.Sum().AggregationTemporality()) + dp := mi.Sum().DataPoints().At(0) assert.Equal(t, start, dp.StartTimestamp()) assert.Equal(t, ts, dp.Timestamp()) assert.Equal(t, pmetric.NumberDataPointValueTypeInt, dp.ValueType()) diff --git a/cmd/mdatagen/internal/samplescraper/internal/metadata/generated_status.go b/cmd/mdatagen/internal/samplescraper/internal/metadata/generated_status.go index 943074109b8e..b5d6acbb5a6c 100644 --- a/cmd/mdatagen/internal/samplescraper/internal/metadata/generated_status.go +++ b/cmd/mdatagen/internal/samplescraper/internal/metadata/generated_status.go @@ -12,6 +12,7 @@ var ( ) const ( - LogsStability = component.StabilityLevelDevelopment - MetricsStability = component.StabilityLevelStable + LogsStability = component.StabilityLevelDevelopment + ProfilesStability = component.StabilityLevelDevelopment + MetricsStability = component.StabilityLevelStable ) diff --git a/cmd/mdatagen/internal/samplescraper/internal/metadata/testdata/config.yaml b/cmd/mdatagen/internal/samplescraper/internal/metadata/testdata/config.yaml index d936342fd3fd..3940dff513fd 100644 --- a/cmd/mdatagen/internal/samplescraper/internal/metadata/testdata/config.yaml +++ b/cmd/mdatagen/internal/samplescraper/internal/metadata/testdata/config.yaml @@ -3,14 +3,59 @@ all_set: metrics: default.metric: enabled: true + attributes: ["string_attr","state","enum_attr","slice_attr","map_attr"] default.metric.to_be_removed: enabled: true metric.input_type: enabled: true + attributes: ["string_attr","state","enum_attr","slice_attr","map_attr"] optional.metric: enabled: true + attributes: ["string_attr","boolean_attr","boolean_attr2"] optional.metric.empty_unit: enabled: true + attributes: ["string_attr","boolean_attr"] + reaggregate.metric: + enabled: true + attributes: ["string_attr","boolean_attr"] + system.cpu.time: + enabled: true + resource_attributes: + map.resource.attr: + enabled: true + optional.resource.attr: + enabled: true + slice.resource.attr: + enabled: true + string.enum.resource.attr: + enabled: true + string.resource.attr: + enabled: true + string.resource.attr_disable_warning: + enabled: true + string.resource.attr_remove_warning: + enabled: true + string.resource.attr_to_be_removed: + enabled: true +reaggregate_set: + metrics: + default.metric: + enabled: true + attributes: [] + default.metric.to_be_removed: + enabled: true + metric.input_type: + enabled: true + attributes: [] + optional.metric: + enabled: true + attributes: [] + optional.metric.empty_unit: + enabled: true + attributes: [] + reaggregate.metric: + enabled: true + attributes: [] system.cpu.time: enabled: true resource_attributes: @@ -34,14 +79,21 @@ none_set: metrics: default.metric: enabled: false + attributes: ["string_attr","state","enum_attr","slice_attr","map_attr"] default.metric.to_be_removed: enabled: false metric.input_type: enabled: false + attributes: ["string_attr","state","enum_attr","slice_attr","map_attr"] optional.metric: enabled: false + attributes: ["string_attr","boolean_attr","boolean_attr2"] optional.metric.empty_unit: enabled: false + attributes: ["string_attr","boolean_attr"] + reaggregate.metric: + enabled: false + attributes: ["string_attr","boolean_attr"] system.cpu.time: enabled: false resource_attributes: diff --git a/cmd/mdatagen/internal/samplescraper/metadata.yaml b/cmd/mdatagen/internal/samplescraper/metadata.yaml index 27b7cb91b66a..f88c07cb3b31 100644 --- a/cmd/mdatagen/internal/samplescraper/metadata.yaml +++ b/cmd/mdatagen/internal/samplescraper/metadata.yaml @@ -1,16 +1,19 @@ # Sample metadata file with all available configurations for a scraper. type: sample +display_name: Sample Scraper +description: This scraper is used for testing purposes to check the output of mdatagen. +reaggregation_enabled: true github_project: open-telemetry/opentelemetry-collector -sem_conv_version: 1.37.0 +sem_conv_version: 1.38.0 status: disable_codecov_badge: true class: scraper stability: stable: [metrics] - development: [logs] + development: [logs, profiles] distributions: [] unsupported_platforms: [freebsd, illumos] codeowners: @@ -18,6 +21,27 @@ status: warnings: - Any additional information that should be brought to the consumer's attention +config: + type: object + description: Configuration for the Sample Scraper. + allOf: + - $ref: /scraper/scraperhelper.controller_config + $defs: + properties: + targets: + description: Targets configuration for the scraper. + x-pointer: true + type: array + items: + type: object + properties: + http_client: + $ref: /config/confighttp.client_config + interval: + type: string + format: duration + x-optional: true + resource_attributes: map.resource.attr: description: Resource attribute with a map value. @@ -104,8 +128,7 @@ metrics: enabled: true description: Monotonic cumulative sum int metric enabled by default. extended_documentation: The metric will be become optional soon. - stability: - level: development + stability: development unit: s sum: value_type: int @@ -120,8 +143,10 @@ metrics: enabled: true description: "[DEPRECATED] Non-monotonic delta sum double metric enabled by default." extended_documentation: The metric will be removed soon. - stability: - level: deprecated + stability: deprecated + deprecated: + since: "1.0.0" + note: "This metric will be removed" unit: s sum: value_type: double @@ -132,8 +157,7 @@ metrics: metric.input_type: enabled: true - stability: - level: development + stability: development description: Monotonic cumulative sum int metric with string input_type enabled by default. unit: s sum: @@ -147,8 +171,10 @@ metrics: optional.metric: enabled: false description: "[DEPRECATED] Gauge double metric disabled by default." - stability: - level: deprecated + stability: deprecated + deprecated: + since: "1.0.0" + note: "This metric will be removed" unit: "1" gauge: value_type: double @@ -159,8 +185,10 @@ metrics: optional.metric.empty_unit: enabled: false description: "[DEPRECATED] Gauge double metric disabled by default." - stability: - level: deprecated + stability: deprecated + deprecated: + since: "1.0.0" + note: "This metric will be removed" unit: "" gauge: value_type: double @@ -168,10 +196,18 @@ metrics: warnings: if_configured: This metric is deprecated and will be removed soon. + reaggregate.metric: + enabled: true + description: Metric for testing spatial reaggregation + unit: "1" + stability: beta + gauge: + value_type: double + attributes: [string_attr, boolean_attr] + system.cpu.time: enabled: true - stability: - level: beta + stability: beta description: Monotonic cumulative sum int metric enabled by default. extended_documentation: The metric will be become optional soon. unit: s @@ -180,4 +216,4 @@ metrics: monotonic: true aggregation_temporality: cumulative semantic_convention: - ref: https://github.com/open-telemetry/semantic-conventions/blob/v1.37.0/docs/system/system-metrics.md#metric-systemcputime + ref: https://github.com/open-telemetry/semantic-conventions/blob/v1.38.0/docs/system/system-metrics.md#metric-systemcputime diff --git a/cmd/mdatagen/internal/templates/component_test.go.tmpl b/cmd/mdatagen/internal/templates/component_test.go.tmpl index 1437e6637c55..becfcd8012de 100644 --- a/cmd/mdatagen/internal/templates/component_test.go.tmpl +++ b/cmd/mdatagen/internal/templates/component_test.go.tmpl @@ -23,20 +23,32 @@ import ( {{- if isExporter }} "go.opentelemetry.io/collector/exporter" "go.opentelemetry.io/collector/exporter/exportertest" + {{- if supportsProfiles }} + "go.opentelemetry.io/collector/exporter/xexporter" + {{- end }} {{- end }} {{- if isProcessor }} "go.opentelemetry.io/collector/consumer/consumertest" "go.opentelemetry.io/collector/processor" "go.opentelemetry.io/collector/processor/processortest" + {{- if supportsProfiles }} + "go.opentelemetry.io/collector/processor/xprocessor" + {{- end }} {{- end }} {{- if isReceiver }} "go.opentelemetry.io/collector/consumer/consumertest" "go.opentelemetry.io/collector/receiver" "go.opentelemetry.io/collector/receiver/receivertest" + {{- if supportsProfiles }} + "go.opentelemetry.io/collector/receiver/xreceiver" + {{- end }} {{- end }} {{- if isScraper }} "go.opentelemetry.io/collector/scraper" "go.opentelemetry.io/collector/scraper/scrapertest" + {{- if supportsProfiles }} + "go.opentelemetry.io/collector/scraper/xscraper" + {{- end }} {{- end }} {{- if isExtension }} "go.opentelemetry.io/collector/extension/extensiontest" @@ -44,9 +56,15 @@ import ( {{- if isConnector }} "go.opentelemetry.io/collector/connector" "go.opentelemetry.io/collector/connector/connectortest" + {{- if supportsProfiles }} + "go.opentelemetry.io/collector/connector/xconnector" + {{- end }} "go.opentelemetry.io/collector/consumer" "go.opentelemetry.io/collector/consumer/consumertest" "go.opentelemetry.io/collector/pipeline" + {{- if supportsProfiles }} + "go.opentelemetry.io/collector/pipeline/xpipeline" + {{- end }} {{- end }} {{- if or isExporter isProcessor }} "go.opentelemetry.io/collector/pdata/pcommon" @@ -196,6 +214,14 @@ func TestComponentLifecycle(t *testing.T) { return factory.CreateTraces(ctx, set, cfg, consumertest.NewNop()) }, }, +{{ end }} +{{ if supportsProfiles }} + { + name: "profiles", + createFn: func(ctx context.Context, set processor.Settings, cfg component.Config) (component.Component, error) { + return factory.(xprocessor.Factory).CreateProfiles(ctx, set, cfg, consumertest.NewNop()) + }, + }, {{ end }} } @@ -291,6 +317,14 @@ func TestComponentLifecycle(t *testing.T) { return factory.CreateTraces(ctx, set, cfg, consumertest.NewNop()) }, }, +{{ end }} +{{ if supportsProfiles }} + { + name: "profiles", + createFn: func(ctx context.Context, set receiver.Settings, cfg component.Config) (component.Component, error) { + return factory.(xreceiver.Factory).CreateProfiles(ctx, set, cfg, consumertest.NewNop()) + }, + }, {{ end }} } @@ -360,6 +394,14 @@ func TestComponentLifecycle(t *testing.T) { return factory.CreateTraces(ctx, set, cfg) }, }, +{{ end }} +{{ if supportsProfiles }} + { + name: "profiles", + createFn: func(ctx context.Context, set scraper.Settings, cfg component.Config) (component.Component, error) { + return factory.(xscraper.Factory).CreateProfiles(ctx, set, cfg) + }, + }, {{ end }} } @@ -469,6 +511,15 @@ func TestComponentLifecycle(t *testing.T) { }, }, {{ end }} +{{ if supportsLogsToProfiles }} + { + name: "logs_to_profiles", + createFn: func(ctx context.Context, set connector.Settings, cfg component.Config) (component.Component, error) { + router := connector.NewTracesRouter(map[pipeline.ID]xconsumer.Profiles{pipeline.NewID(xpipeline.SignalProfiles): consumertest.NewNop()}) + return factory.(xconnector.Factory).CreateLogsToProfiles(ctx, set, cfg, router) + }, + }, +{{ end }} {{ if supportsMetricsToLogs }} { name: "metrics_to_logs", @@ -496,6 +547,15 @@ func TestComponentLifecycle(t *testing.T) { }, }, {{ end }} +{{ if supportsMetricsToProfiles }} + { + name: "metrics_to_profiles", + createFn: func(ctx context.Context, set connector.Settings, cfg component.Config) (component.Component, error) { + router := connector.NewTracesRouter(map[pipeline.ID]xconsumer.Profiles{pipeline.NewID(xpipeline.SignalProfiles): consumertest.NewNop()}) + return factory.(xconnector.Factory).CreateMetricsToTraces(ctx, set, cfg, router) + }, + }, +{{ end }} {{ if supportsTracesToLogs }} { name: "traces_to_logs", @@ -522,6 +582,51 @@ func TestComponentLifecycle(t *testing.T) { return factory.CreateTracesToTraces(ctx, set, cfg, router) }, }, +{{ end }} +{{ if supportsTracesToProfiles }} + { + name: "traces_to_profiles", + createFn: func(ctx context.Context, set connector.Settings, cfg component.Config) (component.Component, error) { + router := connector.NewTracesRouter(map[pipeline.ID]xconsumer.Profiles{pipeline.NewID(xpipeline.SignalProfiles): consumertest.NewNop()}) + return factory.(xconnector.Factory).CreateTracesToProfiles(ctx, set, cfg, router) + }, + }, +{{ end }} +{{ if supportsProfilesToLogs }} + { + name: "profiles_to_logs", + createFn: func(ctx context.Context, set connector.Settings, cfg component.Config) (component.Component, error) { + router := connector.NewLogsRouter(map[pipeline.ID]consumer.Logs{pipeline.NewID(pipeline.SignalLogs): consumertest.NewNop()}) + return factory.(xconnector.Factory).CreateProfilesToLogs(ctx, set, cfg, router) + }, + }, +{{ end }} +{{ if supportsProfilesToMetrics }} + { + name: "profiles_to_metrics", + createFn: func(ctx context.Context, set connector.Settings, cfg component.Config) (component.Component, error) { + router := connector.NewMetricsRouter(map[pipeline.ID]consumer.Metrics{pipeline.NewID(pipeline.SignalMetrics): consumertest.NewNop()}) + return factory.(xconnector.Factory).CreateProfilesToMetrics(ctx, set, cfg, router) + }, + }, +{{ end }} +{{ if supportsProfilesToTraces }} + { + name: "profiles_to_traces", + createFn: func(ctx context.Context, set connector.Settings, cfg component.Config) (component.Component, error) { + router := connector.NewTracesRouter(map[pipeline.ID]consumer.Traces{pipeline.NewID(pipeline.SignalTraces): consumertest.NewNop()}) + return factory.(xconnector.Factory).CreateProfilesToTraces(ctx, set, cfg, router) + }, + }, +{{ end }} +{{ if supportsProfilesToProfiles }} + { + name: "profiles_to_profiles", + createFn: func(ctx context.Context, set connector.Settings, cfg component.Config) (component.Component, error) { + router := xconnector.NewProfilesRouter(map[pipeline.ID]xconsumer.Profiles{pipeline.NewID(xpipeline.SignalProfiles): consumertest.NewNop()}) + return factory.(xconnector.Factory).CreateProfilesToProfiles(ctx, set, cfg, router) + }, + }, {{ end }} } diff --git a/cmd/mdatagen/internal/templates/config.go.tmpl b/cmd/mdatagen/internal/templates/config.go.tmpl index 58f7b2229cca..a3f5bc4d6239 100644 --- a/cmd/mdatagen/internal/templates/config.go.tmpl +++ b/cmd/mdatagen/internal/templates/config.go.tmpl @@ -2,45 +2,109 @@ package {{ .Package }} +{{ $reag := .ReaggregationEnabled }} +{{- $hasReagMetrics := false }} +{{- range $name, $metric := .Metrics }}{{- if and $reag (hasAggregatableAttributes $metric.Attributes) }}{{- $hasReagMetrics = true }}{{- end }}{{- end }} + import ( - "go.opentelemetry.io/collector/confmap" - {{ if and .Metrics .ResourceAttributes -}} - "go.opentelemetry.io/collector/filter" - {{- end }} + {{- if $hasReagMetrics }} + "fmt" + "slices" + {{- end }} + + "go.opentelemetry.io/collector/confmap" + {{ if and .Metrics .ResourceAttributes -}} + "go.opentelemetry.io/collector/filter" + {{- end }} ) {{ if .Metrics -}} +{{- if not $reag }} // MetricConfig provides common config for a particular metric. type MetricConfig struct { - Enabled bool `mapstructure:"enabled"` - + Enabled bool `mapstructure:"enabled"` enabledSetByUser bool } func (ms *MetricConfig) Unmarshal(parser *confmap.Conf) error { - if parser == nil { - return nil + {{- template "metricUnmarshal" "ms" }} +} +{{- else }} + +{{- range $name, $metric := .Metrics }} +{{- if hasAggregatableAttributes $metric.Attributes }} +// {{ $name.Render }}MetricAttributeKey specifies the key of an attribute for the {{ $name }} metric. +type {{ $name.Render }}MetricAttributeKey string + +const ( + {{- range $metric.Attributes }} + {{ $name.Render }}MetricAttributeKey{{ .Render }} {{ $name.Render }}MetricAttributeKey = "{{ (attributeInfo .).Name }}" + {{- end }} +) +{{- end }} + +// {{ $name.Render }}MetricConfig provides config for the {{ $name }} metric. +type {{ $name.Render }}MetricConfig struct { + Enabled bool `mapstructure:"enabled"` + enabledSetByUser bool + {{- if hasAggregatableAttributes $metric.Attributes }} + + AggregationStrategy string `mapstructure:"aggregation_strategy"` + EnabledAttributes []{{ $name.Render }}MetricAttributeKey `mapstructure:"attributes"` + {{- end }} +} + +func (ms *{{ $name.Render }}MetricConfig) Unmarshal(parser *confmap.Conf) error { + {{- template "metricUnmarshal" "ms" }} +} + +{{ if hasAggregatableAttributes $metric.Attributes -}} +func (ms *{{ $name.Render }}MetricConfig) Validate() error { + for _, val := range ms.EnabledAttributes { + switch val { + case {{ range $index, $element := $metric.Attributes -}}{{ if $index }}, {{ end }}{{ $name.Render }}MetricAttributeKey{{ $element.Render }}{{ end }}: + default: + return fmt.Errorf("metric {{ $name }} doesn't have an attribute %v, valid attributes: [{{ range $index, $element := $metric.Attributes -}}{{ if $index }}, {{ end }}{{ (attributeInfo $element).Name }}{{ end }}]", val) + } } - err := parser.Unmarshal(ms) - if err != nil { - return err + + {{- range $element := $metric.Attributes }} + {{- if (attributeInfo $element).IsRequired }} + if !slices.Contains(ms.EnabledAttributes, {{ $name.Render }}MetricAttributeKey{{ $element.Render }}) { + return fmt.Errorf("{{ (attributeInfo $element).Name }} is a required attribute for {{ $name }} metric and must be included") } - ms.enabledSetByUser = parser.IsSet("enabled") + {{- end }} + {{- end }} + + switch ms.AggregationStrategy { + case AggregationStrategySum, AggregationStrategyAvg, AggregationStrategyMin, AggregationStrategyMax: + default: + return fmt.Errorf("invalid aggregation strategy %q, valid strategies: [%s, %s, %s, %s]", ms.AggregationStrategy, AggregationStrategySum, AggregationStrategyAvg, AggregationStrategyMin, AggregationStrategyMax) + } + return nil } +{{- end }} +{{- end }} +{{- end }} // MetricsConfig provides config for {{ .Type }} metrics. type MetricsConfig struct { {{- range $name, $metric := .Metrics }} - {{ $name.Render }} MetricConfig `mapstructure:"{{ $name }}"` + {{ $name.Render }} {{ if $reag }}{{ $name.Render }}{{ end }}MetricConfig `mapstructure:"{{ $name }}"` {{- end }} } func DefaultMetricsConfig() MetricsConfig { return MetricsConfig{ {{- range $name, $metric := .Metrics }} - {{ $name.Render }}: MetricConfig{ + {{- $metricReag := and $reag (hasAggregatableAttributes $metric.Attributes) }} + {{ $name.Render }}: {{ if $reag }}{{ $name.Render }}{{ end }}MetricConfig{ Enabled: {{ $metric.Enabled }}, + {{- if $metricReag }} + AggregationStrategy: AggregationStrategy{{ if eq $metric.Data.Type "Sum" }}Sum{{ else }}Avg{{ end }}, + EnabledAttributes: []{{ $name.Render }}MetricAttributeKey{ {{- range $element := $metric.Attributes -}}{{- if (attributeInfo $element).IsNotOptIn }}{{ $name.Render }}MetricAttributeKey{{ $element.Render }}, {{ end }}{{- end -}} }, + {{- end }} }, {{- end }} } diff --git a/cmd/mdatagen/internal/templates/config.schema.yaml.tmpl b/cmd/mdatagen/internal/templates/config.schema.yaml.tmpl new file mode 100644 index 000000000000..91d6cc0b58ea --- /dev/null +++ b/cmd/mdatagen/internal/templates/config.schema.yaml.tmpl @@ -0,0 +1,125 @@ +# Code generated by mdatagen. DO NOT EDIT. +{{- $reag := .ReaggregationEnabled }} +$defs: +{{- if .Metrics }} + metrics_config: + description: MetricsConfig provides config for {{ .Type }} metrics. + type: object + properties: + {{- range $name, $metric := .Metrics }} + {{- $metricReag := and $reag (hasAggregatableAttributes $metric.Attributes) }} + {{ $name }}: + description: "{{ $name.Render }}MetricConfig provides config for the {{ $name }} metric." + type: object + properties: + enabled: + type: boolean + default: {{ $metric.Enabled }} + {{- if $metricReag }} + aggregation_strategy: + type: string + enum: + - "sum" + - "avg" + - "min" + - "max" + {{- if eq $metric.Data.Type "Sum" }} + default: "sum" + {{- else }} + default: "avg" + {{- end }} + attributes: + type: array + items: + type: string + enum: + {{- range $metric.Attributes }} + - "{{ (attributeInfo .).Name }}" + {{- end }} + default: + {{- range $metric.Attributes }} + {{- if (attributeInfo .).IsNotOptIn }} + - "{{ (attributeInfo .).Name }}" + {{- end }} + {{- end }} + {{- end }} + {{- end }} +{{- end }} +{{- if .Events }} + events_config: + description: EventsConfig provides config for {{ .Type }} events. + type: object + properties: + {{- range $name, $event := .Events }} + {{ $name }}: + description: EventConfig provides common config for a {{ $name }} event. + type: object + properties: + enabled: + type: boolean + default: {{ $event.Enabled }} + {{- end }} +{{- end }} +{{- if .ResourceAttributes }} + resource_attributes_config: + description: ResourceAttributesConfig provides config for {{ .Type }} resource attributes. + type: object + properties: + {{- range $name, $attr := .ResourceAttributes }} + {{ $name }}: + description: ResourceAttributeConfig provides common config for a {{ $name }} resource attribute. + type: object + properties: + enabled: + type: boolean + default: {{ $attr.Enabled }} + {{- if $.Metrics }} + metrics_include: + description: "Experimental: MetricsInclude defines a list of filters for attribute values. If the list is not empty, only metrics with matching resource attribute values will be emitted." + type: array + items: + $ref: {{ schemaRef "go.opentelemetry.io/collector/filter.config" }} + metrics_exclude: + description: "Experimental: MetricsExclude defines a list of filters for attribute values. If the list is not empty, metrics with matching resource attribute values will not be emitted. MetricsInclude has higher priority than MetricsExclude." + type: array + items: + $ref: {{ schemaRef "go.opentelemetry.io/collector/filter.config" }} + {{- end }} + {{- if $.Events }} + events_include: + description: "Experimental: EventsInclude defines a list of filters for attribute values. If the list is not empty, only events with matching resource attribute values will be emitted." + type: array + items: + $ref: {{ schemaRef "go.opentelemetry.io/collector/filter.config" }} + events_exclude: + description: "Experimental: EventsExclude defines a list of filters for attribute values. If the list is not empty, events with matching resource attribute values will not be emitted. EventsInclude has higher priority than EventsExclude." + type: array + items: + $ref: {{ schemaRef "go.opentelemetry.io/collector/filter.config" }} + {{- end }} + {{- end }} +{{- end }} +{{- if .Metrics }} + metrics_builder_config: + description: MetricsBuilderConfig is a configuration for {{ .Type }} metrics builder. + type: object + properties: + metrics: + $ref: metrics_config + {{- if .ResourceAttributes }} + resource_attributes: + $ref: resource_attributes_config + {{- end }} +{{- end }} +{{- if .Events }} + logs_builder_config: + description: LogsBuilderConfig is a configuration for {{ .Type }} logs builder. + type: object + properties: + events: + $ref: events_config + {{- if .ResourceAttributes }} + resource_attributes: + $ref: resource_attributes_config + {{- end }} +{{- end }} diff --git a/cmd/mdatagen/internal/templates/config_from_cfggen.go.tmpl b/cmd/mdatagen/internal/templates/config_from_cfggen.go.tmpl new file mode 100644 index 000000000000..ea1500ee43e3 --- /dev/null +++ b/cmd/mdatagen/internal/templates/config_from_cfggen.go.tmpl @@ -0,0 +1,48 @@ +// Code generated by mdatagen. DO NOT EDIT. + +package {{ .Package }} + +{{ $imports := extractImports .Metadata.Config }} +{{- if $imports }} +import ( +{{- range $imports }} + "{{ . }}" +{{- end }} +) +{{- end }} + +{{ define "struct" }} + {{- if .AllOf }} + {{- range .AllOf }} + {{- if .Description }} + // {{ .Description }} + {{- end }} + {{ .Ref | publicType }} `mapstructure:",squash"` + {{- end }} + {{- end }} + {{- range $propName, $prop := .Properties }} + {{- if $prop.Description }} + // {{ $prop.Description }} + {{- end }} + {{ $propName | publicVar }} {{ mapGoType $prop $propName }} `mapstructure:"{{ $propName }}"` + {{- end }} +{{ end }} + +{{- $defs := extractDefs .Metadata.Config }} +{{ range $defName, $def := $defs }} + {{- if $def.Description }} +// {{ $defName | publicVar }} {{ $def.Description }} + {{- end }} +type {{ $defName | publicVar }} struct { +{{ template "struct" $def }} +} +{{ end }} + +{{- if .Metadata.Config.Description }} +// {{ .Metadata.Config.Description }} +{{- else }} +// Config defines the configuration for {{ .Metadata.DisplayName }} component. +{{- end }} +type Config struct { +{{ template "struct" .Metadata.Config }} +} diff --git a/cmd/mdatagen/internal/templates/config_test.go.tmpl b/cmd/mdatagen/internal/templates/config_test.go.tmpl index 781a115c4a04..eeef58fb1687 100644 --- a/cmd/mdatagen/internal/templates/config_test.go.tmpl +++ b/cmd/mdatagen/internal/templates/config_test.go.tmpl @@ -14,6 +14,8 @@ import ( "go.opentelemetry.io/collector/confmap/confmaptest" ) +{{ $reag := .ReaggregationEnabled }} + {{ if .Metrics }} func TestMetricsBuilderConfig(t *testing.T) { tests := []struct { @@ -28,8 +30,15 @@ func TestMetricsBuilderConfig(t *testing.T) { name: "all_set", want: MetricsBuilderConfig{ Metrics: MetricsConfig{ - {{- range $name, $_ := .Metrics }} - {{ $name.Render }}: MetricConfig{Enabled: true}, + {{- range $name, $metric := .Metrics }} + {{- $metricReag := and $reag (hasAggregatableAttributes $metric.Attributes) }} + {{ $name.Render }}: {{ if $reag }}{{ $name.Render }}{{ end }}MetricConfig{ + Enabled: true, + {{- if $metricReag }} + AggregationStrategy: AggregationStrategy{{ if eq $metric.Data.Type "Sum" }}Sum{{ else }}Avg{{ end }}, + EnabledAttributes: []{{ $name.Render }}MetricAttributeKey{ {{- range $index, $element := $metric.Attributes -}}{{ if $index }}, {{ end }}{{ $name.Render }}MetricAttributeKey{{ $element.Render }}{{ end -}} }, + {{- end }} + }, {{- end }} }, {{- if .ResourceAttributes }} @@ -45,8 +54,15 @@ func TestMetricsBuilderConfig(t *testing.T) { name: "none_set", want: MetricsBuilderConfig{ Metrics: MetricsConfig{ - {{- range $name, $_ := .Metrics }} - {{ $name.Render }}: MetricConfig{Enabled: false}, + {{- range $name, $metric := .Metrics }} + {{- $metricReag := and $reag (hasAggregatableAttributes $metric.Attributes) }} + {{ $name.Render }}: {{ if $reag }}{{ $name.Render }}{{ end }}MetricConfig{ + Enabled: false, + {{- if $metricReag }} + AggregationStrategy: AggregationStrategy{{ if eq $metric.Data.Type "Sum" }}Sum{{ else }}Avg{{ end }}, + EnabledAttributes: []{{ $name.Render }}MetricAttributeKey{ {{- range $index, $element := $metric.Attributes -}}{{ if $index }}, {{ end }}{{ $name.Render }}MetricAttributeKey{{ $element.Render }}{{ end -}} }, + {{- end }} + }, {{- end }} }, {{- if .ResourceAttributes }} @@ -62,8 +78,12 @@ func TestMetricsBuilderConfig(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { cfg := loadMetricsBuilderConfig(t, tt.name) - diff := cmp.Diff(tt.want, cfg, cmpopts.IgnoreUnexported(MetricConfig{} - {{- if .ResourceAttributes }}, ResourceAttributeConfig{}{{ end }})) + diff := cmp.Diff(tt.want, cfg, cmpopts.IgnoreUnexported( + {{- if $reag }} + {{- range $name, $metric := .Metrics }}{{ $name.Render }}MetricConfig{}, {{ end }} + {{- else }}MetricConfig{},{{ end }} + {{- if .ResourceAttributes }}ResourceAttributeConfig{},{{ end }} + )) require.Emptyf(t, diff, "Config mismatch (-expected +actual):\n%s", diff) }) } diff --git a/cmd/mdatagen/internal/templates/documentation.md.tmpl b/cmd/mdatagen/internal/templates/documentation.md.tmpl index d8b882544045..73cadff8c208 100644 --- a/cmd/mdatagen/internal/templates/documentation.md.tmpl +++ b/cmd/mdatagen/internal/templates/documentation.md.tmpl @@ -12,13 +12,17 @@ {{- end }} -| Unit | Metric Type | Value Type |{{ if $metric.Data.HasAggregated }} Aggregation Temporality |{{ end }}{{ if $metric.Data.HasMonotonic }} Monotonic |{{ end }}{{ if $metric.Stability.Level }} Stability |{{ end }}{{ if $metric.SemanticConvention }} Semantic Convention |{{ end }} -| ---- | ----------- | ---------- |{{ if $metric.Data.HasAggregated }} ----------------------- |{{ end }}{{ if $metric.Data.HasMonotonic }} --------- |{{ end }}{{ if $metric.Stability.Level }} --------- |{{ end }}{{ if $metric.SemanticConvention }} ------------------- |{{ end }} +| Unit | Metric Type | Value Type |{{ if $metric.Data.HasAggregated }} Aggregation Temporality |{{ end }}{{ if $metric.Data.HasMonotonic }} Monotonic |{{ end }}{{ if $metric.Stability }} Stability |{{ end }}{{ if $metric.SemanticConvention }} Semantic Convention |{{ end }} +| ---- | ----------- | ---------- |{{ if $metric.Data.HasAggregated }} ----------------------- |{{ end }}{{ if $metric.Data.HasMonotonic }} --------- |{{ end }}{{ if $metric.Stability }} --------- |{{ end }}{{ if $metric.SemanticConvention }} ------------------- |{{ end }} | {{ $metric.Unit }} | {{ $metric.Data.Type }} | {{ $metric.Data.MetricValueType }} | {{- if $metric.Data.HasAggregated }} {{ $metric.Data.AggregationTemporality }} |{{ end }} {{- if $metric.Data.HasMonotonic }} {{ $metric.Data.Monotonic }} |{{ end }} -{{- if $metric.Stability.Level }} {{ $metric.Stability.Level }} |{{ end }} +{{- if $metric.Stability }} {{ $metric.Stability }}{{ if $metric.Deprecated }} since {{ $metric.Deprecated.Since }}{{ end }} |{{ end }} {{- if $metric.SemanticConvention }} [{{ $metricName }}]({{ $metric.SemanticConvention.SemanticConventionRef }}) |{{ end }} +{{- if $metric.Deprecated }}{{ if $metric.Deprecated.Note }} + +**Deprecation note**: {{ $metric.Deprecated.Note }} +{{- end }}{{ end }} {{- if $metric.Attributes }} @@ -72,7 +76,14 @@ ### {{ if $metric.Prefix -}}{{ $metric.Prefix }}{{- else -}}otelcol_{{- end -}}{{ $metricName }} -{{ $metric.Description }}{{ $metric.Stability }} +{{ $metric.Description }} +{{- if $metric.Deprecated }} + +> **Deprecated since {{ $metric.Deprecated.Since}}** +{{- if $metric.Deprecated.Note }} +> {{ $metric.Deprecated.Note }} +{{- end }} +{{- end }} {{- if $metric.ExtendedDocumentation }} @@ -80,12 +91,16 @@ {{- end }} -| Unit | Metric Type | Value Type |{{ if $metric.Data.HasMonotonic }} Monotonic |{{ end }}{{ if $metric.Stability.Level }} Stability |{{ end }}{{ if $metric.SemanticConvention }} Semantic Convention |{{ end }} -| ---- | ----------- | ---------- |{{ if $metric.Data.HasMonotonic }} --------- |{{ end }}{{ if $metric.Stability.Level }} --------- |{{ end }}{{ if $metric.SemanticConvention }} ------------------- |{{ end }} +| Unit | Metric Type | Value Type |{{ if $metric.Data.HasMonotonic }} Monotonic |{{ end }}{{ if $metric.Stability }} Stability |{{ end }}{{ if $metric.SemanticConvention }} Semantic Convention |{{ end }} +| ---- | ----------- | ---------- |{{ if $metric.Data.HasMonotonic }} --------- |{{ end }}{{ if $metric.Stability }} --------- |{{ end }}{{ if $metric.SemanticConvention }} ------------------- |{{ end }} | {{ $metric.Unit }} | {{ $metric.Data.Type }} | {{ $metric.Data.MetricValueType }} | {{- if $metric.Data.HasMonotonic }} {{ $metric.Data.Monotonic }} |{{ end }} -{{- if $metric.Stability.Level }} {{ $metric.Stability.Level }} |{{ end }} +{{- if $metric.Stability }} {{ $metric.Stability }}{{ if $metric.Deprecated }} since {{ $metric.Deprecated.Since }}{{ end }} |{{ end }} {{- if $metric.SemanticConvention }} [{{ $metricName }}]({{ $metric.SemanticConvention.SemanticConventionRef }}) |{{ end }} +{{- if $metric.Deprecated }}{{ if $metric.Deprecated.Note }} + +**Deprecation note**: {{ $metric.Deprecated.Note }} +{{- end }}{{ end }} {{- if $metric.Attributes }} @@ -233,7 +248,7 @@ The following entities are defined for this component: {{- if $entity.Identity }} -**Identity Attributes:** +**Identifying Attributes:** {{- range $entity.Identity }} - `{{ .Ref }}` {{- end }} @@ -241,7 +256,7 @@ The following entities are defined for this component: {{- if $entity.Description }} -**Description Attributes:** +**Descriptive Attributes:** {{- range $entity.Description }} - `{{ .Ref }}` {{- end }} @@ -266,3 +281,19 @@ The following telemetry is emitted by this component. {{- end }} {{- end }} + +{{- if .FeatureGates }} + +## Feature Gates + +This component has the following feature gates: + +| Feature Gate | Stage | Description | From Version | To Version | Reference | +| ------------ | ----- | ----------- | ------------ | ---------- | --------- | +{{- range .FeatureGates }} +| `{{ .ID }}` | {{ .Stage }} | {{ .Description }} | {{ if .FromVersion }}{{ .FromVersion }}{{ else }}N/A{{ end }} | {{ if .ToVersion }}{{ .ToVersion }}{{ else }}N/A{{ end }} | {{ if .ReferenceURL }}[Link]({{ .ReferenceURL }}){{ else }}N/A{{ end }} | +{{- end }} + +For more information about feature gates, see the [Feature Gates](https://github.com/open-telemetry/opentelemetry-collector/blob/main/featuregate/README.md) documentation. + +{{- end }} diff --git a/cmd/mdatagen/internal/templates/entity_metrics.go.tmpl b/cmd/mdatagen/internal/templates/entity_metrics.go.tmpl new file mode 100644 index 000000000000..45c1a83e0e62 --- /dev/null +++ b/cmd/mdatagen/internal/templates/entity_metrics.go.tmpl @@ -0,0 +1,248 @@ +// Code generated by mdatagen. DO NOT EDIT. + +package {{ .Package }} + +import ( + {{- if .Metrics | parseImportsRequired }} + "fmt" + "strconv" + {{- end }} + + "go.opentelemetry.io/collector/pdata/pcommon" + "go.opentelemetry.io/collector/pdata/xpdata/entity" +) + +{{ $resourceAttributes := .ResourceAttributes }} +{{ $metrics := .Metrics }} + +{{ range $ent := .Entities }} +{{ $entityType := $ent.Type }} +{{ $entityStructType := printf "%sEntity" (publicVar $entityType) }} + +// {{ $entityStructType }} represents a {{ $entityType }} entity. +// Create one with New{{ $entityStructType }} and pass it to EmitForEntity. +type {{ $entityStructType }} struct { + {{- range $idAttr := $ent.Identity }} + {{- $attr := index $resourceAttributes $idAttr.Ref }} + {{ $idAttr.Ref.RenderUnexported }} {{ $attr.Type.Primitive }} + {{- end }} + {{- range $descAttr := $ent.Description }} + {{- $attr := index $resourceAttributes $descAttr.Ref }} + {{ $descAttr.Ref.RenderUnexported }} {{ $attr.Type.Primitive }} + {{- end }} + {{- range $extraAttr := $ent.ExtraAttributes }} + {{- $attr := index $resourceAttributes $extraAttr.Ref }} + {{ $extraAttr.Ref.RenderUnexported }} {{ $attr.Type.Primitive }} + {{- end }} + {{- range $rel := $ent.Relationships }} + {{ toLowerCamelCase $rel.Type }}{{ publicVar $rel.Target }} *{{ publicVar $rel.Target }}Entity + {{- end }} +} + +// New{{ $entityStructType }} creates a new {{ $entityStructType }}. +// Identity attributes are required and must be provided at construction time. +func New{{ $entityStructType }}( + {{- range $i, $idAttr := $ent.Identity -}} + {{- if $i }}, {{ end -}} + {{- $attr := index $resourceAttributes $idAttr.Ref -}} + {{ $idAttr.Ref.RenderUnexported }} {{ $attr.Type.Primitive }} + {{- end -}} +) *{{ $entityStructType }} { + return &{{ $entityStructType }}{ + {{- range $idAttr := $ent.Identity }} + {{ $idAttr.Ref.RenderUnexported }}: {{ $idAttr.Ref.RenderUnexported }}, + {{- end }} + } +} + +{{- if $ent.Description }} + +// Description attribute setters for {{ $entityType }}. +{{- range $descAttr := $ent.Description }} +{{- $attr := index $resourceAttributes $descAttr.Ref }} + +// Set{{ publicVar $descAttr.Ref.Render }} sets the {{ $descAttr.Ref }} description attribute. +func (e *{{ $entityStructType }}) Set{{ publicVar $descAttr.Ref.Render }}(val {{ $attr.Type.Primitive }}) { + e.{{ $descAttr.Ref.RenderUnexported }} = val +} +{{- end }} +{{- end }} + +{{- if $ent.ExtraAttributes }} + +// Extra attribute setters for {{ $entityType }}. +// These attributes are contextually relevant but are not part of the entity's identity or description. +{{- range $extraAttr := $ent.ExtraAttributes }} +{{- $attr := index $resourceAttributes $extraAttr.Ref }} + +// Set{{ publicVar $extraAttr.Ref.Render }} sets the {{ $extraAttr.Ref }} extra attribute on the resource. +func (e *{{ $entityStructType }}) Set{{ publicVar $extraAttr.Ref.Render }}(val {{ $attr.Type.Primitive }}) { + e.{{ $extraAttr.Ref.RenderUnexported }} = val +} +{{- end }} +{{- end }} + +{{- if $ent.Relationships }} + +// Relationship setters for {{ $entityType }}. +{{- range $rel := $ent.Relationships }} +{{ $relMethod := printf "Set%s%s" (publicVar $rel.Type) (publicVar $rel.Target) }} + +// {{ $relMethod }} sets the {{ $rel.Type }} relationship to a {{ $rel.Target }} entity. +// The related entity will be emitted alongside this entity's metrics. +func (e *{{ $entityStructType }}) {{ $relMethod }}(target *{{ publicVar $rel.Target }}Entity) { + e.{{ toLowerCamelCase $rel.Type }}{{ publicVar $rel.Target }} = target +} +{{- end }} +{{- end }} + +// copyToResource populates res with the entity's attributes according to cfg. +// If all identity attributes are enabled, an entity ref is produced; otherwise +// the enabled attributes are written directly as plain resource attributes. +func (e *{{ $entityStructType }}) copyToResource(cfg ResourceAttributesConfig, res pcommon.Resource) { + if {{ range $i, $idAttr := $ent.Identity }}{{ if $i }} && {{ end }}cfg.{{ publicVar $idAttr.Ref.Render }}.Enabled{{ end }} { + ent := entity.ResourceEntities(res).PutEmpty("{{ $entityType }}") + {{- range $idAttr := $ent.Identity }} + {{- $attr := index $resourceAttributes $idAttr.Ref }} + {{- if eq $attr.Type.ValueType.String "Str" }} + ent.IdentifyingAttributes().PutStr("{{ $idAttr.Ref }}", e.{{ $idAttr.Ref.RenderUnexported }}) + {{- else if or (eq $attr.Type.ValueType.String "Map") (eq $attr.Type.ValueType.String "Slice") (eq $attr.Type.ValueType.String "Bytes") }} + ent.IdentifyingAttributes().PutEmpty("{{ $idAttr.Ref }}").SetEmpty{{ $attr.Type.ValueType }}().FromRaw(e.{{ $idAttr.Ref.RenderUnexported }}) + {{- else }} + ent.IdentifyingAttributes().PutEmpty("{{ $idAttr.Ref }}").Set{{ $attr.Type.ValueType }}(e.{{ $idAttr.Ref.RenderUnexported }}) + {{- end }} + {{- end }} + {{- range $descAttr := $ent.Description }} + {{- $attr := index $resourceAttributes $descAttr.Ref }} + if cfg.{{ publicVar $descAttr.Ref.Render }}.Enabled { + {{- if eq $attr.Type.ValueType.String "Str" }} + ent.DescriptiveAttributes().PutStr("{{ $descAttr.Ref }}", e.{{ $descAttr.Ref.RenderUnexported }}) + {{- else if or (eq $attr.Type.ValueType.String "Map") (eq $attr.Type.ValueType.String "Slice") (eq $attr.Type.ValueType.String "Bytes") }} + ent.DescriptiveAttributes().PutEmpty("{{ $descAttr.Ref }}").SetEmpty{{ $attr.Type.ValueType }}().FromRaw(e.{{ $descAttr.Ref.RenderUnexported }}) + {{- else }} + ent.DescriptiveAttributes().PutEmpty("{{ $descAttr.Ref }}").Set{{ $attr.Type.ValueType }}(e.{{ $descAttr.Ref.RenderUnexported }}) + {{- end }} + } + {{- end }} + {{- range $extraAttr := $ent.ExtraAttributes }} + {{- $attr := index $resourceAttributes $extraAttr.Ref }} + if cfg.{{ publicVar $extraAttr.Ref.Render }}.Enabled { + {{- if eq $attr.Type.ValueType.String "Str" }} + ent.DescriptiveAttributes().PutStr("{{ $extraAttr.Ref }}", e.{{ $extraAttr.Ref.RenderUnexported }}) + {{- else if or (eq $attr.Type.ValueType.String "Map") (eq $attr.Type.ValueType.String "Slice") (eq $attr.Type.ValueType.String "Bytes") }} + ent.DescriptiveAttributes().PutEmpty("{{ $extraAttr.Ref }}").SetEmpty{{ $attr.Type.ValueType }}().FromRaw(e.{{ $extraAttr.Ref.RenderUnexported }}) + {{- else }} + ent.DescriptiveAttributes().PutEmpty("{{ $extraAttr.Ref }}").Set{{ $attr.Type.ValueType }}(e.{{ $extraAttr.Ref.RenderUnexported }}) + {{- end }} + } + {{- end }} + } else { + {{- range $idAttr := $ent.Identity }} + {{- $attr := index $resourceAttributes $idAttr.Ref }} + if cfg.{{ publicVar $idAttr.Ref.Render }}.Enabled { + {{- if or (eq $attr.Type.String "Bytes") (eq $attr.Type.String "Slice") (eq $attr.Type.String "Map") }} + res.Attributes().PutEmpty{{ $attr.Type }}("{{ $idAttr.Ref }}").FromRaw(e.{{ $idAttr.Ref.RenderUnexported }}) + {{- else }} + res.Attributes().Put{{ $attr.Type }}("{{ $idAttr.Ref }}", e.{{ $idAttr.Ref.RenderUnexported }}) + {{- end }} + } + {{- end }} + {{- range $descAttr := $ent.Description }} + {{- $attr := index $resourceAttributes $descAttr.Ref }} + if cfg.{{ publicVar $descAttr.Ref.Render }}.Enabled { + {{- if or (eq $attr.Type.String "Bytes") (eq $attr.Type.String "Slice") (eq $attr.Type.String "Map") }} + res.Attributes().PutEmpty{{ $attr.Type }}("{{ $descAttr.Ref }}").FromRaw(e.{{ $descAttr.Ref.RenderUnexported }}) + {{- else }} + res.Attributes().Put{{ $attr.Type }}("{{ $descAttr.Ref }}", e.{{ $descAttr.Ref.RenderUnexported }}) + {{- end }} + } + {{- end }} + {{- range $extraAttr := $ent.ExtraAttributes }} + {{- $attr := index $resourceAttributes $extraAttr.Ref }} + if cfg.{{ publicVar $extraAttr.Ref.Render }}.Enabled { + {{- if or (eq $attr.Type.String "Bytes") (eq $attr.Type.String "Slice") (eq $attr.Type.String "Map") }} + res.Attributes().PutEmpty{{ $attr.Type }}("{{ $extraAttr.Ref }}").FromRaw(e.{{ $extraAttr.Ref.RenderUnexported }}) + {{- else }} + res.Attributes().Put{{ $attr.Type }}("{{ $extraAttr.Ref }}", e.{{ $extraAttr.Ref.RenderUnexported }}) + {{- end }} + } + {{- end }} + } +} + +{{ end }} + +{{ range $ent := .Entities }} +{{ $entityType := $ent.Type }} +{{ $entityStructType := printf "%sEntity" (publicVar $entityType) }} +{{ $builderType := printf "%sMetricsBuilder" (publicVar $entityType) }} + +// {{ $builderType }} records metrics for the {{ $entityType }} entity. +// Obtain one via MetricsBuilder.For{{ publicVar $entityType }}(). +type {{ $builderType }} struct { + mb *MetricsBuilder + entity *{{ $entityStructType }} +} + +{{- range $name, $metric := $metrics }} +{{- if eq $metric.Entity $entityType }} + +{{/* TODO: Consolidate with the root-level Record*DataPoint methods in metrics.go.tmpl. */}} +// Record{{ $name.Render }}DataPoint records a data point for the {{ $name }} metric. +func (eb *{{ $builderType }}) Record{{ $name.Render }}DataPoint(ts pcommon.Timestamp + {{- if $metric.Data.HasMetricInputType }}, inputVal {{ $metric.Data.MetricInputType.String }} + {{- else }}, val {{ $metric.Data.MetricValueType.BasicType }} + {{- end }} + {{- range $metric.Attributes -}} + {{- if not (attributeInfo .).IsConditional -}} + , {{ .RenderUnexported }}AttributeValue {{ if (attributeInfo .).Enum }}Attribute{{ .Render }}{{ else }}{{ (attributeInfo .).Type.Primitive }}{{ end }} + {{- end -}} + {{- end -}} + {{- if $metric.HasConditionalAttributes $.Attributes -}} + , options ...MetricAttributeOption + {{- end -}} + ) + {{- if $metric.Data.HasMetricInputType }} error{{ end }} { + {{- if $metric.Data.HasMetricInputType }} + {{- if eq $metric.Data.MetricValueType.BasicType "float64" }} + val, err := strconv.ParseFloat(inputVal, 64) + {{- else if eq $metric.Data.MetricValueType.BasicType "int64" }} + val, err := strconv.ParseInt(inputVal, 10, 64) + {{- end }} + if err != nil { + return fmt.Errorf("failed to parse {{ $metric.Data.MetricValueType.BasicType }} for {{ $name.Render }}, value was %s: %w", inputVal, err) + } + {{- end }} + eb.mb.metric{{ $name.Render }}.recordDataPoint(eb.mb.startTime, ts, val + {{- range $metric.Attributes -}} + {{- if not (attributeInfo .).IsConditional -}} + , {{ .RenderUnexported }}AttributeValue{{ if (attributeInfo .).Enum }}.String(){{ end }} + {{- end -}} + {{- end -}} + {{- if $metric.HasConditionalAttributes $.Attributes -}} + , options... + {{- end -}} + ) + {{- if $metric.Data.HasMetricInputType }} + return nil + {{- end }} +} +{{- end }} +{{- end }} + +// Emit emits all pending metrics for the entity. Resource attributes are filtered by config: +// disabled identity attributes suppress the entity (other enabled attributes are added directly +// to the resource); disabled descriptive/extra attributes are omitted entirely. +func (eb *{{ $builderType }}) Emit() { + res := pcommon.NewResource() + cfg := eb.mb.config.ResourceAttributes + eb.entity.copyToResource(cfg, res) + {{- range $rel := $ent.Relationships }} + if eb.entity.{{ toLowerCamelCase $rel.Type }}{{ publicVar $rel.Target }} != nil { + eb.entity.{{ toLowerCamelCase $rel.Type }}{{ publicVar $rel.Target }}.copyToResource(cfg, res) + } + {{- end }} + eb.mb.EmitForResource(withResourceMoved(res)) +} + +{{- end }} diff --git a/cmd/mdatagen/internal/templates/entity_metrics_test.go.tmpl b/cmd/mdatagen/internal/templates/entity_metrics_test.go.tmpl new file mode 100644 index 000000000000..5fe19b3c523b --- /dev/null +++ b/cmd/mdatagen/internal/templates/entity_metrics_test.go.tmpl @@ -0,0 +1,234 @@ +// Code generated by mdatagen. DO NOT EDIT. + +package {{ .Package }} + +import ( + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "go.opentelemetry.io/collector/pdata/pcommon" + "go.opentelemetry.io/collector/pdata/xpdata/entity" + "go.opentelemetry.io/collector/{{ .Status.Class }}/{{ .Status.Class }}test" +) + +{{ $resourceAttributes := .ResourceAttributes }} + +func TestEntityBuilders(t *testing.T) { + start := pcommon.Timestamp(1_000_000_000) + ts := pcommon.Timestamp(1_000_001_000) + settings := {{ .Status.Class }}test.NewNopSettings({{ .Status.Class }}test.NopType) + mb := NewMetricsBuilder(DefaultMetricsBuilderConfig(), settings, WithStartTime(start)) + + {{- range $ent := .Entities }} + {{ $entityType := $ent.Type }} + {{ $entityStructType := printf "%sEntity" (publicVar $entityType) }} + + t.Run("{{ $entityType }}", func(t *testing.T) { + e := New{{ $entityStructType }}( + {{- range $i, $idAttr := $ent.Identity -}} + {{- $attr := index $resourceAttributes $idAttr.Ref -}} + {{- if $i }}, {{ end -}}{{ $attr.TestValue }} + {{- end -}} + ) + require.NotNil(t, e) + + {{- if $ent.Description }} + {{- range $descAttr := $ent.Description }} + {{- $attr := index $resourceAttributes $descAttr.Ref }} + e.Set{{ publicVar $descAttr.Ref.Render }}({{ $attr.TestValue }}) + {{- end }} + {{- end }} + + {{- if $ent.ExtraAttributes }} + {{- range $extraAttr := $ent.ExtraAttributes }} + {{- $attr := index $resourceAttributes $extraAttr.Ref }} + e.Set{{ publicVar $extraAttr.Ref.Render }}({{ $attr.TestValue }}) + {{- end }} + {{- end }} + + {{- if $ent.Relationships }} + {{- range $rel := $ent.Relationships }} + {{- range $other := $.Entities }} + {{- if eq $other.Type $rel.Target }} + related{{ publicVar $rel.Target }} := New{{ publicVar $rel.Target }}Entity( + {{- range $i, $idAttr := $other.Identity -}} + {{- $attr := index $resourceAttributes $idAttr.Ref -}} + {{- if $i }}, {{ end -}}{{ $attr.TestValue }} + {{- end -}} + ) + e.Set{{ publicVar $rel.Type }}{{ publicVar $rel.Target }}(related{{ publicVar $rel.Target }}) + {{- end }} + {{- end }} + {{- end }} + {{- end }} + + eb := mb.For{{ publicVar $entityType }}(e) + {{- range $name, $metric := $.Metrics }} + {{- if eq $metric.Entity $entityType }} + eb.Record{{ $name.Render }}DataPoint(ts, {{ if $metric.Data.HasMetricInputType }}"1"{{ else }}1{{ end }} + {{- range $metric.Attributes -}} + {{- if not (attributeInfo .).IsConditional -}} + , {{- template "getAttributeValue" . -}} + {{- end -}} + {{- end -}} + ) + {{- end }} + {{- end }} + eb.Emit() + metrics := mb.Emit() + + {{- $count := 0 }} + {{- range $name, $metric := $.Metrics }} + {{- if and (eq $metric.Entity $entityType) $metric.Enabled }} + {{- $count = inc $count }} + {{- end }} + {{- end }} + {{- if gt $count 0 }} + + require.Equal(t, 1, metrics.ResourceMetrics().Len()) + rm := metrics.ResourceMetrics().At(0) + + {{- range $idAttr := $ent.Identity }} + {{- $attr := index $resourceAttributes $idAttr.Ref }} + entityVal, ok := entity.ResourceEntities(rm.Resource()).Get("{{ $entityType }}") + require.True(t, ok) + attrVal, ok := entityVal.IdentifyingAttributes().Get("{{ $idAttr.Ref }}") + require.True(t, ok) + assert.Equal(t, {{ $attr.TestValue }}, attrVal.Str()) + {{- end }} + + require.Equal(t, 1, rm.ScopeMetrics().Len()) + ms := rm.ScopeMetrics().At(0).Metrics() + assert.Equal(t, {{ $count }}, ms.Len()) + {{- else }} + // All metrics for this entity are disabled by default. + assert.Equal(t, 0, metrics.ResourceMetrics().Len()) + {{- end }} + }) + + {{- if gt $count 0 }} + t.Run("{{ $entityType }}/disabled_identity_attr", func(t *testing.T) { + // When an identity attribute is disabled, the entity is not produced but + // other enabled attributes are still added to the resource directly. + cfg := DefaultMetricsBuilderConfig() + {{- range $idAttr := $ent.Identity }} + cfg.ResourceAttributes.{{ publicVar $idAttr.Ref.Render }}.Enabled = false + {{- end }} + mb := NewMetricsBuilder(cfg, settings, WithStartTime(start)) + + e := New{{ $entityStructType }}( + {{- range $i, $idAttr := $ent.Identity -}} + {{- $attr := index $resourceAttributes $idAttr.Ref -}} + {{- if $i }}, {{ end -}}{{ $attr.TestValue }} + {{- end -}} + ) + {{- if $ent.Description }} + {{- range $descAttr := $ent.Description }} + {{- $attr := index $resourceAttributes $descAttr.Ref }} + e.Set{{ publicVar $descAttr.Ref.Render }}({{ $attr.TestValue }}) + {{- end }} + {{- end }} + + eb := mb.For{{ publicVar $entityType }}(e) + {{- range $name, $metric := $.Metrics }} + {{- if eq $metric.Entity $entityType }} + eb.Record{{ $name.Render }}DataPoint(ts, {{ if $metric.Data.HasMetricInputType }}"1"{{ else }}1{{ end }} + {{- range $metric.Attributes -}} + {{- if not (attributeInfo .).IsConditional -}} + , {{- template "getAttributeValue" . -}} + {{- end -}} + {{- end -}} + ) + {{- end }} + {{- end }} + eb.Emit() + metrics := mb.Emit() + + require.Equal(t, 1, metrics.ResourceMetrics().Len()) + rm := metrics.ResourceMetrics().At(0) + // Entity must not be present since its identity attribute is disabled. + _, ok := entity.ResourceEntities(rm.Resource()).Get("{{ $entityType }}") + assert.False(t, ok) + // Enabled descriptive attributes should still be on the resource directly. + {{- range $descAttr := $ent.Description }} + {{- $attr := index $resourceAttributes $descAttr.Ref }} + {{- if $attr.Enabled }} + _, ok = rm.Resource().Attributes().Get("{{ $descAttr.Ref }}") + assert.True(t, ok) + {{- end }} + {{- end }} + }) + + {{- if or $ent.Description $ent.ExtraAttributes }} + t.Run("{{ $entityType }}/disabled_descriptive_attr", func(t *testing.T) { + // When a descriptive attribute is disabled, the entity is still produced + // with its identity but the disabled attribute is not added. + cfg := DefaultMetricsBuilderConfig() + {{- range $descAttr := $ent.Description }} + cfg.ResourceAttributes.{{ publicVar $descAttr.Ref.Render }}.Enabled = false + {{- end }} + {{- range $extraAttr := $ent.ExtraAttributes }} + cfg.ResourceAttributes.{{ publicVar $extraAttr.Ref.Render }}.Enabled = false + {{- end }} + mb := NewMetricsBuilder(cfg, settings, WithStartTime(start)) + + e := New{{ $entityStructType }}( + {{- range $i, $idAttr := $ent.Identity -}} + {{- $attr := index $resourceAttributes $idAttr.Ref -}} + {{- if $i }}, {{ end -}}{{ $attr.TestValue }} + {{- end -}} + ) + {{- if $ent.Description }} + {{- range $descAttr := $ent.Description }} + {{- $attr := index $resourceAttributes $descAttr.Ref }} + e.Set{{ publicVar $descAttr.Ref.Render }}({{ $attr.TestValue }}) + {{- end }} + {{- end }} + {{- if $ent.ExtraAttributes }} + {{- range $extraAttr := $ent.ExtraAttributes }} + {{- $attr := index $resourceAttributes $extraAttr.Ref }} + e.Set{{ publicVar $extraAttr.Ref.Render }}({{ $attr.TestValue }}) + {{- end }} + {{- end }} + + eb := mb.For{{ publicVar $entityType }}(e) + {{- range $name, $metric := $.Metrics }} + {{- if eq $metric.Entity $entityType }} + eb.Record{{ $name.Render }}DataPoint(ts, {{ if $metric.Data.HasMetricInputType }}"1"{{ else }}1{{ end }} + {{- range $metric.Attributes -}} + {{- if not (attributeInfo .).IsConditional -}} + , {{- template "getAttributeValue" . -}} + {{- end -}} + {{- end -}} + ) + {{- end }} + {{- end }} + eb.Emit() + metrics := mb.Emit() + + require.Equal(t, 1, metrics.ResourceMetrics().Len()) + rm := metrics.ResourceMetrics().At(0) + // Entity must still be produced since identity attributes are enabled. + entityVal, ok := entity.ResourceEntities(rm.Resource()).Get("{{ $entityType }}") + require.True(t, ok) + {{- range $idAttr := $ent.Identity }} + {{- $attr := index $resourceAttributes $idAttr.Ref }} + attrVal, ok := entityVal.IdentifyingAttributes().Get("{{ $idAttr.Ref }}") + require.True(t, ok) + assert.Equal(t, {{ $attr.TestValue }}, attrVal.Str()) + {{- end }} + // Disabled descriptive/extra attributes must not be present. + {{- range $descAttr := $ent.Description }} + _, ok = entityVal.DescriptiveAttributes().Get("{{ $descAttr.Ref }}") + assert.False(t, ok) + {{- end }} + {{- range $extraAttr := $ent.ExtraAttributes }} + _, ok = entityVal.DescriptiveAttributes().Get("{{ $extraAttr.Ref }}") + assert.False(t, ok) + {{- end }} + }) + {{- end }} + {{- end }} + {{- end }} +} diff --git a/cmd/mdatagen/internal/templates/feature_gates.go.tmpl b/cmd/mdatagen/internal/templates/feature_gates.go.tmpl new file mode 100644 index 000000000000..5410857b1896 --- /dev/null +++ b/cmd/mdatagen/internal/templates/feature_gates.go.tmpl @@ -0,0 +1,21 @@ +// Code generated by mdatagen. DO NOT EDIT. + +package {{ .Package }} + +import ( + "go.opentelemetry.io/collector/featuregate" +) + +{{- range $idx, $gate := .FeatureGates }} + +var {{ printf "%s" $gate.ID | publicVar }}FeatureGate = featuregate.GlobalRegistry().MustRegister( + "{{ $gate.ID }}", + featuregate.Stage{{ printf "%s" $gate.Stage | casesTitle }}, + featuregate.WithRegisterDescription("{{ $gate.Description }}"), + featuregate.WithRegisterReferenceURL("{{ $gate.ReferenceURL }}"), + featuregate.WithRegisterFromVersion("{{ $gate.FromVersion }}"), + {{- if $gate.ToVersion }} + featuregate.WithRegisterToVersion("{{ $gate.ToVersion }}"), + {{- end }} +) +{{- end }} diff --git a/cmd/mdatagen/internal/templates/feature_gates.md.tmpl b/cmd/mdatagen/internal/templates/feature_gates.md.tmpl new file mode 100644 index 000000000000..47ab76a90512 --- /dev/null +++ b/cmd/mdatagen/internal/templates/feature_gates.md.tmpl @@ -0,0 +1,15 @@ +{{- if len .FeatureGates }} + +## Feature Gates + +This component has the following feature gates: + +| Feature Gate | Stage | Description | From Version | To Version | Reference | +| ------------ | ----- | ----------- | ------------ | ---------- | --------- | +{{- range .FeatureGates }} +| `{{ .ID }}` | {{ .Stage }} | {{ .Description }} | {{ if .FromVersion }}{{ .FromVersion }}{{ else }}N/A{{ end }} | {{ if .ToVersion }}{{ .ToVersion }}{{ else }}N/A{{ end }} | {{ if .ReferenceURL }}[Link]({{ .ReferenceURL }}){{ else }}N/A{{ end }} | +{{- end }} + +For more information about feature gates, see the [Feature Gates](https://github.com/open-telemetry/opentelemetry-collector/blob/main/featuregate/README.md) documentation. + +{{- end }} diff --git a/cmd/mdatagen/internal/templates/helper.tmpl b/cmd/mdatagen/internal/templates/helper.tmpl index 2fdca5ec42ce..9875707e4cac 100644 --- a/cmd/mdatagen/internal/templates/helper.tmpl +++ b/cmd/mdatagen/internal/templates/helper.tmpl @@ -10,6 +10,38 @@ {{- end }} {{- end -}} +{{- define "putMetricAttribute" -}} + if slices.Contains(m.config.EnabledAttributes, "{{ (attributeInfo .).Name }}") { + {{- if eq (attributeInfo .).Type.Primitive "[]byte" }} + dp.Attributes().PutEmptyBytes("{{ (attributeInfo .).Name }}").FromRaw({{ .RenderUnexported }}AttributeValue) + {{- else if eq (attributeInfo .).Type.Primitive "[]any" }} + dp.Attributes().PutEmptySlice("{{ (attributeInfo .).Name }}").FromRaw({{ .RenderUnexported }}AttributeValue) + {{- else if eq (attributeInfo .).Type.Primitive "map[string]any" }} + dp.Attributes().PutEmptyMap("{{ (attributeInfo .).Name }}").FromRaw({{ .RenderUnexported }}AttributeValue) + {{- else }} + dp.Attributes().Put{{ (attributeInfo .).Type }}("{{ (attributeInfo .).Name }}", {{ .RenderUnexported }}AttributeValue) + {{- end }} + } +{{- end -}} + {{- define "getAttributeValue" -}} {{ if (attributeInfo .).Enum }}Attribute{{ .Render }}{{ (index (attributeInfo .).Enum 0) | publicVar }}{{ else }}{{ (attributeInfo .).TestValue }}{{ end }} {{- end -}} + +{{- define "getAttributeValueTwo" -}} +{{ if (attributeInfo .).Enum }}Attribute{{ .Render }}{{ if gt (len (attributeInfo .).Enum) 1}}{{ (index (attributeInfo .).Enum 1) | publicVar}}{{ else }}{{ (index (attributeInfo .).Enum 0) | publicVar}}{{ end }}{{ else }}{{ (attributeInfo .).TestValueTwo }}{{ end }} +{{- end -}} + +{{- define "metricUnmarshal" }} + if parser == nil { + return nil + } + + err := parser.Unmarshal({{ . }}) + if err != nil { + return err + } + + {{ . }}.enabledSetByUser = parser.IsSet("enabled") + return nil +{{- end }} diff --git a/cmd/mdatagen/internal/templates/logs.go.tmpl b/cmd/mdatagen/internal/templates/logs.go.tmpl index 9908069b8168..30125e133238 100644 --- a/cmd/mdatagen/internal/templates/logs.go.tmpl +++ b/cmd/mdatagen/internal/templates/logs.go.tmpl @@ -66,7 +66,7 @@ func (e *event{{ $name.Render }}) recordEvent(ctx context.Context, timestamp pco {{- end }} {{- end }} - {{ if $event.HasConditionalAttributes $.Attributes }} + {{ if $event.HasConditionalAttributes $.Attributes }} for _, op := range options { op.apply(dp) } @@ -75,7 +75,7 @@ func (e *event{{ $name.Render }}) recordEvent(ctx context.Context, timestamp pco // emit appends recorded event data to a events slice and prepares it for recording another set of log records. func (e *event{{ $name.Render }}) emit(lrs plog.LogRecordSlice) { - if e.config.Enabled && e.data.Len() > 0 { + if e.config.Enabled && e.data.Len() > 0 { e.data.MoveAndAppendTo(lrs) } } @@ -93,7 +93,7 @@ func newEvent{{ $name.Render }}(cfg EventConfig) event{{ $name.Render }} { // LogsBuilder provides an interface for scrapers to report logs while taking care of all the transformations // required to produce log representation defined in metadata and user config. type LogsBuilder struct { - {{- if .Events }} + {{- if .Events }} config LogsBuilderConfig // config of the logs builder. {{- end }} logsBuffer plog.Logs @@ -110,7 +110,7 @@ type LogsBuilder struct { // LogBuilderOption applies changes to default logs builder. type LogBuilderOption interface { - apply(*LogsBuilder) + apply(*LogsBuilder) } {{- if or isReceiver isScraper }} @@ -190,13 +190,13 @@ func (lb *LogsBuilder) NewResourceBuilder() *ResourceBuilder { // ResourceLogsOption applies changes to provided resource logs. type ResourceLogsOption interface { - apply(plog.ResourceLogs) + apply(plog.ResourceLogs) } type resourceLogsOptionFunc func(plog.ResourceLogs) func (rlof resourceLogsOptionFunc) apply(rl plog.ResourceLogs) { - rlof(rl) + rlof(rl) } // WithLogsResource sets the provided resource on the emitted ResourceLogs. @@ -226,7 +226,7 @@ func (lb *LogsBuilder) EmitForResource(options ...ResourceLogsOption) { ils.Scope().SetName(ScopeName) ils.Scope().SetVersion(lb.buildInfo.Version) - {{- range $name, $event := .Events }} + {{- range $name, $event := .Events }} lb.event{{- $name.Render }}.emit(ils.LogRecords()) {{- end }} @@ -234,12 +234,12 @@ func (lb *LogsBuilder) EmitForResource(options ...ResourceLogsOption) { op.apply(rl) } - if lb.logRecordsBuffer.Len() > 0 { - lb.logRecordsBuffer.MoveAndAppendTo(ils.LogRecords()) - lb.logRecordsBuffer = plog.NewLogRecordSlice() - } + if lb.logRecordsBuffer.Len() > 0 { + lb.logRecordsBuffer.MoveAndAppendTo(ils.LogRecords()) + lb.logRecordsBuffer = plog.NewLogRecordSlice() + } - {{ if and .Events .ResourceAttributes -}} + {{ if and .Events .ResourceAttributes -}} for attr, filter := range lb.resourceAttributeIncludeFilter { if val, ok := rl.Resource().Attributes().Get(attr); ok && !filter.Matches(val.AsString()) { return @@ -262,8 +262,8 @@ func (lb *LogsBuilder) EmitForResource(options ...ResourceLogsOption) { // produce logs representation defined in metadata and user config. func (lb *LogsBuilder) Emit(options ...ResourceLogsOption) plog.Logs { lb.EmitForResource(options...) - logs := lb.logsBuffer - lb.logsBuffer = plog.NewLogs() + logs := lb.logsBuffer + lb.logsBuffer = plog.NewLogs() return logs } diff --git a/cmd/mdatagen/internal/templates/logs_test.go.tmpl b/cmd/mdatagen/internal/templates/logs_test.go.tmpl index d2c602e51767..c172baea347e 100644 --- a/cmd/mdatagen/internal/templates/logs_test.go.tmpl +++ b/cmd/mdatagen/internal/templates/logs_test.go.tmpl @@ -30,26 +30,26 @@ const ( {{- end }} func TestLogsBuilderAppendLogRecord(t *testing.T) { - observedZapCore, _ := observer.New(zap.WarnLevel) - {{- if or isReceiver isScraper }} - settings := {{ .Status.Class }}test.NewNopSettings({{ .Status.Class }}test.NopType) - {{- end }} - settings.Logger = zap.New(observedZapCore) - lb := NewLogsBuilder({{ if .Events }}loadLogsBuilderConfig(t, "all_set"), {{ end }}settings) + observedZapCore, _ := observer.New(zap.WarnLevel) + {{- if or isReceiver isScraper }} + settings := {{ .Status.Class }}test.NewNopSettings({{ .Status.Class }}test.NopType) + {{- end }} + settings.Logger = zap.New(observedZapCore) + lb := NewLogsBuilder({{ if .Events }}loadLogsBuilderConfig(t, "all_set"), {{ end }}settings) - {{ if .ResourceAttributes }} - rb := lb.NewResourceBuilder() - {{- range $name, $attr := .ResourceAttributes }} - {{- if $attr.Enum }} - rb.Set{{ $attr.Name.Render }}{{ index $attr.Enum 0 | publicVar }}() - {{- else }} - rb.Set{{ $attr.Name.Render }}({{ $attr.TestValue }}) - {{- end }} - {{- end }} - res := rb.Emit() - {{- else }} - res := pcommon.NewResource() - {{- end }} + {{ if .ResourceAttributes }} + rb := lb.NewResourceBuilder() + {{- range $name, $attr := .ResourceAttributes }} + {{- if $attr.Enum }} + rb.Set{{ $attr.Name.Render }}{{ index $attr.Enum 0 | publicVar }}() + {{- else }} + rb.Set{{ $attr.Name.Render }}({{ $attr.TestValue }}) + {{- end }} + {{- end }} + res := rb.Emit() + {{- else }} + res := pcommon.NewResource() + {{- end }} // append the first log record lr := plog.NewLogRecord() @@ -136,15 +136,15 @@ func TestLogsBuilder(t *testing.T) { TraceID: trace.TraceID(traceID), SpanID: trace.SpanID(spanID), TraceFlags: trace.FlagsSampled, - })) + })) observedZapCore, observedLogs := observer.New(zap.WarnLevel) - {{- if or isReceiver isScraper }} - settings := {{ .Status.Class }}test.NewNopSettings({{ .Status.Class }}test.NopType) - {{- end }} + {{- if or isReceiver isScraper }} + settings := {{ .Status.Class }}test.NewNopSettings({{ .Status.Class }}test.NopType) + {{- end }} settings.Logger = zap.New(observedZapCore) lb := NewLogsBuilder(loadLogsBuilderConfig(t, tt.name), settings) - expectedWarnings := 0 + expectedWarnings := 0 {{- range $name, $event := .Events }} {{- if and $event.Enabled $event.Warnings.IfEnabled }} if tt.eventsSet == eventTestDataSetDefault || tt.eventsSet == eventTestDataSetAll { @@ -201,11 +201,11 @@ func TestLogsBuilder(t *testing.T) { {{- end -}} {{- end -}} {{- range $event.Attributes -}} - {{- if (attributeInfo .).IsConditional -}} - , With{{ .Render }}EventAttribute({{- template "getAttributeValue" . -}}) - {{- end -}} - {{- end -}} - ) + {{- if (attributeInfo .).IsConditional -}} + , With{{ .Render }}EventAttribute({{- template "getAttributeValue" . -}}) + {{- end -}} + {{- end -}} + ) {{- end }} {{ if .ResourceAttributes }} diff --git a/cmd/mdatagen/internal/templates/metrics.go.tmpl b/cmd/mdatagen/internal/templates/metrics.go.tmpl index faeb3aa1f889..2a95877fc1d7 100644 --- a/cmd/mdatagen/internal/templates/metrics.go.tmpl +++ b/cmd/mdatagen/internal/templates/metrics.go.tmpl @@ -2,12 +2,19 @@ package {{ .Package }} +{{ $reag := .ReaggregationEnabled }} +{{- $hasReagMetrics := false }} +{{- range $name, $metric := .Metrics }}{{- if and $reag (hasAggregatableAttributes $metric.Attributes) }}{{- $hasReagMetrics = true }}{{- end }}{{- end }} + import ( {{- if .Metrics | parseImportsRequired }} "strconv" "fmt" {{- end }} "time" + {{- if $hasReagMetrics }} + "slices" + {{- end }} "go.opentelemetry.io/collector/component" "go.opentelemetry.io/collector/pdata/pcommon" @@ -23,8 +30,17 @@ import ( {{- end }} ) +{{- if $reag }} +const ( + AggregationStrategySum = "sum" + AggregationStrategyAvg = "avg" + AggregationStrategyMin = "min" + AggregationStrategyMax = "max" +) +{{- end }} + {{ range $name, $info := .Attributes }} -{{- if $info.Enum -}} +{{- if $info.Enum }} // Attribute{{ $name.Render }} specifies the value {{ $name }} attribute. type Attribute{{ $name.Render }} int @@ -52,16 +68,15 @@ var MapAttribute{{ $name.Render }} = map[string]Attribute{{ $name.Render }}{ "{{ . }}": Attribute{{ $name.Render }}{{ . | publicVar }}, {{- end }} } - -{{ end }} +{{- end }} {{- end }} var MetricsInfo = metricsInfo{ - {{- range $name, $metric := .Metrics }} - {{ $name.Render }}: metricInfo{ - Name: "{{ $name }}", - }, - {{- end }} + {{- range $name, $metric := .Metrics }} + {{ $name.Render }}: metricInfo{ + Name: "{{ $name }}", + }, + {{- end }} } type metricsInfo struct { @@ -71,7 +86,7 @@ type metricsInfo struct { } type metricInfo struct { - Name string + Name string } {{ if getMetricConditionalAttributes .Attributes }} @@ -94,11 +109,15 @@ func With{{ .Render }}MetricAttribute({{ .RenderUnexported }}AttributeValue {{ ( {{ end }} {{ end }} -{{ range $name, $metric := .Metrics -}} +{{ range $name, $metric := .Metrics }} +{{- $metricReag := and $reag (hasAggregatableAttributes $metric.Attributes) -}} type metric{{ $name.Render }} struct { - data pmetric.Metric // data buffer for generated metric. - config MetricConfig // metric config provided by user. - capacity int // max observed number of data points added to the metric. + data pmetric.Metric // data buffer for generated metric. + config {{ if $reag }}{{ $name.Render }}{{ end }}MetricConfig // metric config provided by user. + capacity int // max observed number of data points added to the metric. + {{- if $metricReag }} + aggDataPoints []{{ $metric.Data.MetricValueType.BasicType }} // slice containing number of aggregated datapoints at each index + {{- end }} } // init fills {{ $name }} metric with initial data. @@ -116,8 +135,65 @@ func (m *metric{{ $name.Render }}) init() { {{- if $metric.Attributes }} m.data.{{ $metric.Data.Type }}().DataPoints().EnsureCapacity(m.capacity) {{- end }} + {{- if $metricReag }} + m.aggDataPoints = m.aggDataPoints[:0] + {{- end }} } +{{/* This function changed in a major way, so instead of gating individual lines of code the original is being included */}} +{{- if $metricReag }} +func (m *metric{{ $name.Render }}) recordDataPoint(start pcommon.Timestamp, ts pcommon.Timestamp, val {{ $metric.Data.MetricValueType.BasicType }} +{{- range $metric.Attributes -}}{{- if not (attributeInfo .).IsConditional -}}, {{ .RenderUnexported }}AttributeValue {{ (attributeInfo .).Type.Primitive }}{{ end }}{{ end }}{{- if $metric.HasConditionalAttributes $.Attributes -}}, options ...MetricAttributeOption{{- end -}}) { + if !m.config.Enabled { + return + } + + dp := pmetric.NewNumberDataPoint() + dp.SetStartTimestamp(start) + dp.SetTimestamp(ts) + {{- range $metric.Attributes }} + {{- if not (attributeInfo .).IsConditional }} + if slices.Contains(m.config.EnabledAttributes, {{ $name.Render }}MetricAttributeKey{{ .Render }}) { + {{- template "putAttribute" . }} + } + {{- end }} + {{- end }} + + {{- if $metric.HasConditionalAttributes $.Attributes }} + for _, op := range options { + op.apply(dp) + } + {{- end }} + + var s string + dps := m.data.{{ $metric.Data.Type }}().DataPoints() + for i := 0; i < dps.Len(); i++ { + dpi := dps.At(i) + if dp.Attributes().Equal(dpi.Attributes()) && dp.StartTimestamp() == dpi.StartTimestamp() && dp.Timestamp() == dpi.Timestamp() { + switch s = m.config.AggregationStrategy; s { + case AggregationStrategySum, AggregationStrategyAvg: + dpi.Set{{ $metric.Data.MetricValueType }}Value(dpi.{{ $metric.Data.MetricValueType }}Value() + val) + m.aggDataPoints[i] += 1 + return + case AggregationStrategyMin: + if dpi.{{ $metric.Data.MetricValueType }}Value() > val { + dpi.Set{{ $metric.Data.MetricValueType }}Value(val) + } + return + case AggregationStrategyMax: + if dpi.{{ $metric.Data.MetricValueType }}Value() < val { + dpi.Set{{ $metric.Data.MetricValueType }}Value(val) + } + return + } + } + } + + dp.Set{{ $metric.Data.MetricValueType }}Value(val) + m.aggDataPoints = append(m.aggDataPoints, 1) + dp.MoveTo(dps.AppendEmpty()) +} +{{- else }} func (m *metric{{ $name.Render }}) recordDataPoint(start pcommon.Timestamp, ts pcommon.Timestamp, val {{ $metric.Data.MetricValueType.BasicType }} {{- range $metric.Attributes -}}{{- if not (attributeInfo .).IsConditional -}}, {{ .RenderUnexported }}AttributeValue {{ (attributeInfo .).Type.Primitive }}{{ end }}{{ end }}{{- if $metric.HasConditionalAttributes $.Attributes -}}, options ...MetricAttributeOption{{- end -}}) { if !m.config.Enabled { @@ -128,17 +204,18 @@ func (m *metric{{ $name.Render }}) recordDataPoint(start pcommon.Timestamp, ts p dp.SetTimestamp(ts) dp.Set{{ $metric.Data.MetricValueType }}Value(val) {{- range $metric.Attributes }} - {{- if not (attributeInfo .).IsConditional -}} + {{- if not (attributeInfo .).IsConditional -}} {{- template "putAttribute" . -}} {{- end }} {{- end }} {{- if $metric.HasConditionalAttributes $.Attributes }} - for _, op := range options { - op.apply(dp) - } - {{- end }} + for _, op := range options { + op.apply(dp) + } + {{- end }} } +{{- end }} // updateCapacity saves max length of data point slices that will be used for the slice capacity. func (m *metric{{ $name.Render }}) updateCapacity() { @@ -149,15 +226,25 @@ func (m *metric{{ $name.Render }}) updateCapacity() { // emit appends recorded metric data to a metrics slice and prepares it for recording another set of data points. func (m *metric{{ $name.Render }}) emit(metrics pmetric.MetricSlice) { + {{- if $metricReag }} + if m.config.Enabled && m.data.{{ $metric.Data.Type }}().DataPoints().Len() > 0 { + if m.config.AggregationStrategy == AggregationStrategyAvg { + for i, aggCount := range m.aggDataPoints { + m.data.{{ $metric.Data.Type }}().DataPoints().At(i).Set{{ $metric.Data.MetricValueType }}Value(m.data.{{ $metric.Data.Type }}().DataPoints().At(i).{{ $metric.Data.MetricValueType }}Value() / aggCount) + } + } + {{- else }} if m.config.Enabled && m.data.{{ $metric.Data.Type }}().DataPoints().Len() > 0 { + {{- end }} m.updateCapacity() m.data.MoveTo(metrics.AppendEmpty()) m.init() } } -func newMetric{{ $name.Render }}(cfg MetricConfig) metric{{ $name.Render }} { +func newMetric{{ $name.Render }}(cfg {{ if $reag }}{{ $name.Render }}{{ end }}MetricConfig) metric{{ $name.Render }} { m := metric{{ $name.Render }}{config: cfg} + if cfg.Enabled { m.data = pmetric.NewMetric() m.init() @@ -186,13 +273,13 @@ type MetricsBuilder struct { // MetricBuilderOption applies changes to default metrics builder. type MetricBuilderOption interface { - apply(*MetricsBuilder) + apply(*MetricsBuilder) } type metricBuilderOptionFunc func(mb *MetricsBuilder) func (mbof metricBuilderOptionFunc) apply(mb *MetricsBuilder) { - mbof(mb) + mbof(mb) } // WithStartTime sets startTime on the metrics builder. @@ -283,13 +370,13 @@ func (mb *MetricsBuilder) updateCapacity(rm pmetric.ResourceMetrics) { // ResourceMetricsOption applies changes to provided resource metrics. type ResourceMetricsOption interface { - apply(pmetric.ResourceMetrics) + apply(pmetric.ResourceMetrics) } type resourceMetricsOptionFunc func(pmetric.ResourceMetrics) func (rmof resourceMetricsOptionFunc) apply(rm pmetric.ResourceMetrics) { - rmof(rm) + rmof(rm) } // WithResource sets the provided resource on the emitted ResourceMetrics. @@ -300,6 +387,14 @@ func WithResource(res pcommon.Resource) ResourceMetricsOption { }) } +{{ if .HasEntities -}} +func withResourceMoved(res pcommon.Resource) ResourceMetricsOption { + return resourceMetricsOptionFunc(func(rm pmetric.ResourceMetrics) { + res.MoveTo(rm.Resource()) + }) +} +{{- end }} + // WithStartTimeOverride overrides start time for all the resource metrics data points. // This option should be only used if different start time has to be set on metrics coming from different resources. func WithStartTimeOverride(start pcommon.Timestamp) ResourceMetricsOption { @@ -320,11 +415,27 @@ func WithStartTimeOverride(start pcommon.Timestamp) ResourceMetricsOption { }) } +{{ range $ent := .Entities }} +{{ $entityType := $ent.Type }} +{{ $entityStructType := printf "%sEntity" (publicVar $entityType) }} +{{ $builderType := printf "%sMetricsBuilder" (publicVar $entityType) }} + +// For{{ publicVar $entityType }} returns a {{ $builderType }} that restricts metric recording +// to metrics belonging to the {{ $entityType }} entity. +func (mb *MetricsBuilder) For{{ publicVar $entityType }}(e *{{ $entityStructType }}) *{{ $builderType }} { + return &{{ $builderType }}{mb: mb, entity: e} +} +{{ end }} + // EmitForResource saves all the generated metrics under a new resource and updates the internal state to be ready for // recording another set of data points as part of another resource. This function can be helpful when one scraper // needs to emit metrics from several resources. Otherwise calling this function is not required, // just `Emit` function can be called instead. // Resource attributes should be provided as ResourceMetricsOption arguments. +{{- if .HasEntities }} +// +// Deprecated: Use the For methods to get entity-scoped builders and call Emit() on them instead. +{{- end }} func (mb *MetricsBuilder) EmitForResource(options ...ResourceMetricsOption) { rm := pmetric.NewResourceMetrics() {{- if .SemConvVersion }} @@ -372,6 +483,10 @@ func (mb *MetricsBuilder) Emit(options ...ResourceMetricsOption) pmetric.Metrics {{ range $name, $metric := .Metrics -}} // Record{{ $name.Render }}DataPoint adds a data point to {{ $name }} metric. +{{- if $metric.Entity }} +// +// Deprecated: Use mb.For{{ publicVar $metric.Entity }}(entity).Record{{ $name.Render }}DataPoint(...) instead. +{{- end }} func (mb *MetricsBuilder) Record{{ $name.Render }}DataPoint(ts pcommon.Timestamp {{- if $metric.Data.HasMetricInputType }}, inputVal {{ $metric.Data.MetricInputType.String }} {{- else }}, val {{ $metric.Data.MetricValueType.BasicType }} @@ -403,9 +518,9 @@ func (mb *MetricsBuilder) Record{{ $name.Render }}DataPoint(ts pcommon.Timestamp {{- end -}} {{- end -}} {{- if $metric.HasConditionalAttributes $.Attributes -}} - , options... - {{- end -}} - ) + , options... + {{- end -}} + ) {{- if $metric.Data.HasMetricInputType }} return nil {{- end }} diff --git a/cmd/mdatagen/internal/templates/metrics_test.go.tmpl b/cmd/mdatagen/internal/templates/metrics_test.go.tmpl index 633219209793..c8bedebd1afe 100644 --- a/cmd/mdatagen/internal/templates/metrics_test.go.tmpl +++ b/cmd/mdatagen/internal/templates/metrics_test.go.tmpl @@ -2,6 +2,10 @@ package {{ .Package }} +{{ $reag := .ReaggregationEnabled }} +{{- $hasReagMetrics := false }} +{{- range $name, $metric := .Metrics }}{{- if and $reag (hasAggregatableAttributes $metric.Attributes) }}{{- $hasReagMetrics = true }}{{- end }}{{- end }} + import ( "testing" @@ -15,13 +19,15 @@ import ( "go.uber.org/zap/zaptest/observer" ) - type testDataSet int const ( testDataSetDefault testDataSet = iota testDataSetAll testDataSetNone + {{- if $reag }} + testDataSetReag + {{- end }} ) func TestMetricsBuilder(t *testing.T) { @@ -39,6 +45,13 @@ func TestMetricsBuilder(t *testing.T) { metricsSet: testDataSetAll, resAttrsSet: testDataSetAll, }, + {{- if $reag }} + { + name: "reaggregate_set", + metricsSet: testDataSetReag, + resAttrsSet: testDataSetReag, + }, + {{- end }} { name: "none_set", metricsSet: testDataSetNone, @@ -62,12 +75,21 @@ func TestMetricsBuilder(t *testing.T) { start := pcommon.Timestamp(1_000_000_000) ts := pcommon.Timestamp(1_000_001_000) observedZapCore, observedLogs := observer.New(zap.WarnLevel) - {{- if or isReceiver isScraper isConnector }} - settings := {{ .Status.Class }}test.NewNopSettings({{ .Status.Class }}test.NopType) - {{- end }} + {{- if or isReceiver isScraper isConnector }} + settings := {{ .Status.Class }}test.NewNopSettings({{ .Status.Class }}test.NopType) + {{- end }} settings.Logger = zap.New(observedZapCore) mb := NewMetricsBuilder(loadMetricsBuilderConfig(t, tt.name), settings, WithStartTime(start)) + {{- if $hasReagMetrics }} + aggMap := make(map[string]string) // contains the aggregation strategies for each metric name + {{- range $name, $metric := .Metrics }} + {{- if hasAggregatableAttributes $metric.Attributes }} + aggMap["{{ $name.Render }}"] = mb.metric{{ $name.Render }}.config.AggregationStrategy + {{- end }} + {{- end }} + {{- end }} + expectedWarnings := 0 {{- range $name, $metric := .Metrics }} {{- if and $metric.Enabled $metric.Warnings.IfEnabled }} @@ -110,27 +132,66 @@ func TestMetricsBuilder(t *testing.T) { {{- end }} {{- end }} - + {{- if $reag }} + if tt.metricsSet != testDataSetReag { + assert.Equal(t, expectedWarnings, observedLogs.Len()) + } + {{- else }} assert.Equal(t, expectedWarnings, observedLogs.Len()) + {{- end }} defaultMetricsCount := 0 allMetricsCount := 0 + + {{- range $ent := .Entities }} + eb{{ publicVar $ent.Type }} := mb.For{{ publicVar $ent.Type }}(New{{ publicVar $ent.Type }}Entity( + {{- range $i, $idAttr := $ent.Identity -}} + {{- $attr := index $.ResourceAttributes $idAttr.Ref -}} + {{- if $i }}, {{ end -}}{{ $attr.TestValue }} + {{- end -}} + )) + {{- end }} + {{- range $name, $metric := .Metrics }} - {{ if $metric.Enabled }}defaultMetricsCount++{{ end }} - allMetricsCount++ - mb.Record{{ $name.Render }}DataPoint(ts, {{ if $metric.Data.HasMetricInputType }}"1"{{ else }}1{{ end }} + {{ if $metric.Enabled }}defaultMetricsCount++{{ end }} + allMetricsCount++ + {{ if $metric.Entity }}eb{{ publicVar $metric.Entity }}{{ else }}mb{{ end }}.Record{{ $name.Render }}DataPoint(ts, {{ if $metric.Data.HasMetricInputType }}"1"{{ else }}1{{ end }} + {{- range $metric.Attributes -}} + {{- if not (attributeInfo .).IsConditional -}} + , {{- template "getAttributeValue" . -}} + {{- end -}} + {{- end -}} + {{- range $metric.Attributes -}} + {{- if (attributeInfo .).IsConditional -}} + , With{{ .Render }}MetricAttribute({{- template "getAttributeValue" . -}}) + {{- end -}} + {{- end -}} + ) + {{- if and $reag (hasAggregatableAttributes $metric.Attributes) }} + if tt.name == "reaggregate_set" { + {{ if $metric.Entity }}eb{{ publicVar $metric.Entity }}{{ else }}mb{{ end }}.Record{{ $name.Render }}DataPoint(ts, {{ if $metric.Data.HasMetricInputType }}"3"{{ else }}3{{ end }} {{- range $metric.Attributes -}} {{- if not (attributeInfo .).IsConditional -}} + {{- if (attributeInfo .).IsRequired -}} , {{- template "getAttributeValue" . -}} + {{- else -}} + , {{- template "getAttributeValueTwo" . -}} + {{- end -}} {{- end -}} {{- end -}} {{- range $metric.Attributes -}} - {{- if (attributeInfo .).IsConditional -}} - , With{{ .Render }}MetricAttribute({{- template "getAttributeValue" . -}}) - {{- end -}} - {{- end -}} - ) + {{- if (attributeInfo .).IsConditional -}} + , With{{ .Render }}MetricAttribute({{- template "getAttributeValue" . -}}) + {{- end -}} + {{- end -}} + ) + } + {{- end }} + {{- end }} + + {{- range $ent := .Entities }} + eb{{ publicVar $ent.Type }}.Emit() {{- end }} {{ if .ResourceAttributes }} @@ -147,45 +208,160 @@ func TestMetricsBuilder(t *testing.T) { res := pcommon.NewResource() {{- end }} metrics := mb.Emit(WithResource(res)) + {{- if $reag }} + if tt.name == "reaggregate_set" { + {{- range $name, $metric := .Metrics }} + {{- if hasAggregatableAttributes $metric.Attributes }} + assert.Empty(t, mb.metric{{ $name.Render }}.aggDataPoints) + {{- end }} + {{- end }} + } + {{- end }} if tt.expectEmpty { assert.Equal(t, 0, metrics.ResourceMetrics().Len()) return } - assert.Equal(t, 1, metrics.ResourceMetrics().Len()) - rm := metrics.ResourceMetrics().At(0) - assert.Equal(t, res, rm.Resource()) - assert.Equal(t, 1, rm.ScopeMetrics().Len()) - ms := rm.ScopeMetrics().At(0).Metrics() + var allMetricsList []pmetric.Metric + totalMetricsCount := 0 + for ri := 0; ri < metrics.ResourceMetrics().Len(); ri++ { + rm := metrics.ResourceMetrics().At(ri) + assert.Equal(t, 1, rm.ScopeMetrics().Len()) + ms := rm.ScopeMetrics().At(0).Metrics() + totalMetricsCount += ms.Len() + for mi := 0; mi < ms.Len(); mi++ { + allMetricsList = append(allMetricsList, ms.At(mi)) + } + } if tt.metricsSet == testDataSetDefault { - assert.Equal(t, defaultMetricsCount, ms.Len()) + assert.Equal(t, defaultMetricsCount, totalMetricsCount) } if tt.metricsSet == testDataSetAll { - assert.Equal(t, allMetricsCount, ms.Len()) + assert.Equal(t, allMetricsCount, totalMetricsCount) } validatedMetrics := make(map[string]bool) - for i := 0; i < ms.Len(); i++ { - switch ms.At(i).Name() { + for _, mi := range allMetricsList { + switch mi.Name() { {{- range $name, $metric := .Metrics }} case "{{ $name }}": + {{- if and $reag (hasAggregatableAttributes $metric.Attributes) }} + if tt.name != "reaggregate_set" { + assert.False(t, validatedMetrics["{{ $name }}"], "Found a duplicate in the metrics slice: {{ $name }}") + validatedMetrics["{{ $name }}"] = true + assert.Equal(t, pmetric.MetricType{{ $metric.Data.Type }}, mi.Type()) + assert.Equal(t, 1, mi.{{ $metric.Data.Type }}().DataPoints().Len()) + assert.Equal(t, "{{ $metric.Description }}", mi.Description()) + {{- if len $metric.Unit}} + assert.Equal(t, "{{ $metric.Unit }}", mi.Unit()) + {{- else }} + assert.Empty(t, mi.Unit()) + {{- end }} + {{- if $metric.Data.HasMonotonic }} + assert.{{- if $metric.Data.Monotonic }}True{{ else }}False{{ end }}(t, mi.{{ $metric.Data.Type }}().IsMonotonic()) + {{- end }} + {{- if $metric.Data.HasAggregated }} + assert.Equal(t, pmetric.AggregationTemporality{{ $metric.Data.AggregationTemporality }}, mi.{{ $metric.Data.Type }}().AggregationTemporality()) + {{- end }} + dp := mi.{{ $metric.Data.Type }}().DataPoints().At(0) + assert.Equal(t, start, dp.StartTimestamp()) + assert.Equal(t, ts, dp.Timestamp()) + assert.Equal(t, pmetric.NumberDataPointValueType{{ $metric.Data.MetricValueType }}, dp.ValueType()) + {{- if eq $metric.Data.MetricValueType.BasicType "float64" }} + assert.InDelta(t, {{ $metric.Data.MetricValueType.BasicType }}(1), dp.{{ $metric.Data.MetricValueType }}Value(), 0.01) + {{- else }} + assert.Equal(t, {{ $metric.Data.MetricValueType.BasicType }}(1), dp.{{ $metric.Data.MetricValueType }}Value()) + {{- end }} + {{- range $i, $attr := $metric.Attributes }} + {{- if ne (attributeInfo $attr).RequirementLevel.String "Opt-In" }} + attrVal, ok {{ if eq $i 0 }}:{{ end }}= dp.Attributes().Get("{{ (attributeInfo $attr).Name }}") + assert.True(t, ok) + {{- if eq (attributeInfo $attr).Type.String "Bool"}} + assert.{{- if eq (attributeInfo $attr).TestValue "true" }}True{{ else }}False{{- end }}(t, attrVal.{{ (attributeInfo $attr).Type }}() + {{- else if eq (attributeInfo $attr).Type.String "Int"}} + assert.EqualValues(t, {{ (attributeInfo $attr).TestValue }}, attrVal.{{ (attributeInfo $attr).Type }}() + {{- else }} + assert.Equal(t, {{ (attributeInfo $attr).TestValue }}, attrVal.{{ (attributeInfo $attr).Type }}() + {{- end }} + {{- if or (eq (attributeInfo $attr).Type.String "Slice") (eq (attributeInfo $attr).Type.String "Map")}}.AsRaw(){{ end }}) + {{- end }} + {{- end }} + } else { + assert.False(t, validatedMetrics["{{ $name }}"], "Found a duplicate in the metrics slice: {{ $name }}") + validatedMetrics["{{ $name }}"] = true + assert.Equal(t, pmetric.MetricType{{ $metric.Data.Type }}, mi.Type()) + assert.Equal(t, 1, mi.{{ $metric.Data.Type }}().DataPoints().Len()) + assert.Equal(t, "{{ $metric.Description }}", mi.Description()) + {{- if len $metric.Unit}} + assert.Equal(t, "{{ $metric.Unit }}", mi.Unit()) + {{- else }} + assert.Empty(t, mi.Unit()) + {{- end }} + {{- if $metric.Data.HasMonotonic }} + assert.{{- if $metric.Data.Monotonic }}True{{ else }}False{{ end }}(t, mi.{{ $metric.Data.Type }}().IsMonotonic()) + {{- end }} + {{- if $metric.Data.HasAggregated }} + assert.Equal(t, pmetric.AggregationTemporality{{ $metric.Data.AggregationTemporality }}, mi.{{ $metric.Data.Type }}().AggregationTemporality()) + {{- end }} + dp := mi.{{ $metric.Data.Type }}().DataPoints().At(0) + assert.Equal(t, start, dp.StartTimestamp()) + assert.Equal(t, ts, dp.Timestamp()) + assert.Equal(t, pmetric.NumberDataPointValueType{{ $metric.Data.MetricValueType }}, dp.ValueType()) + switch aggMap["{{ $name }}"] { + case "sum": + {{- if eq $metric.Data.MetricValueType.BasicType "float64" }} + assert.InDelta(t, {{ $metric.Data.MetricValueType.BasicType }}(4), dp.{{ $metric.Data.MetricValueType }}Value(), 0.01) + {{- else }} + assert.Equal(t, {{ $metric.Data.MetricValueType.BasicType }}(4), dp.{{ $metric.Data.MetricValueType }}Value()) + {{- end }} + case "avg": + {{- if eq $metric.Data.MetricValueType.BasicType "float64" }} + assert.InDelta(t, {{ $metric.Data.MetricValueType.BasicType }}(2), dp.{{ $metric.Data.MetricValueType }}Value(), 0.01) + {{- else }} + assert.Equal(t, {{ $metric.Data.MetricValueType.BasicType }}(2), dp.{{ $metric.Data.MetricValueType }}Value()) + {{- end }} + case "min": + {{- if eq $metric.Data.MetricValueType.BasicType "float64" }} + assert.InDelta(t, {{ $metric.Data.MetricValueType.BasicType }}(1), dp.{{ $metric.Data.MetricValueType }}Value(), 0.01) + {{- else }} + assert.Equal(t, {{ $metric.Data.MetricValueType.BasicType }}(1), dp.{{ $metric.Data.MetricValueType }}Value()) + {{- end }} + case "max": + {{- if eq $metric.Data.MetricValueType.BasicType "float64" }} + assert.InDelta(t, {{ $metric.Data.MetricValueType.BasicType }}(3), dp.{{ $metric.Data.MetricValueType }}Value(), 0.01) + {{- else }} + assert.Equal(t, {{ $metric.Data.MetricValueType.BasicType }}(3), dp.{{ $metric.Data.MetricValueType }}Value()) + {{- end }} + } + {{- range $i, $attr := $metric.Attributes }} + {{- if eq (attributeInfo $attr).RequirementLevel.String "Required" }} + _, ok {{ if eq $i 0 }}:{{ end }}= dp.Attributes().Get("{{ (attributeInfo $attr).Name }}") + assert.True(t, ok) + {{- else if eq (attributeInfo $attr).RequirementLevel.String "Conditionally Required" }} + {{- else }} + _, ok {{ if eq $i 0 }}:{{ end }}= dp.Attributes().Get("{{ (attributeInfo $attr).Name }}") + assert.False(t, ok) + {{- end }} + {{- end }} + } + {{- else }} assert.False(t, validatedMetrics["{{ $name }}"], "Found a duplicate in the metrics slice: {{ $name }}") validatedMetrics["{{ $name }}"] = true - assert.Equal(t, pmetric.MetricType{{ $metric.Data.Type }}, ms.At(i).Type()) - assert.Equal(t, 1, ms.At(i).{{ $metric.Data.Type }}().DataPoints().Len()) - assert.Equal(t, "{{ $metric.Description }}", ms.At(i).Description()) + assert.Equal(t, pmetric.MetricType{{ $metric.Data.Type }}, mi.Type()) + assert.Equal(t, 1, mi.{{ $metric.Data.Type }}().DataPoints().Len()) + assert.Equal(t, "{{ $metric.Description }}", mi.Description()) {{- if len $metric.Unit}} - assert.Equal(t, "{{ $metric.Unit }}", ms.At(i).Unit()) + assert.Equal(t, "{{ $metric.Unit }}", mi.Unit()) {{- else }} - assert.Empty(t, ms.At(i).Unit()) + assert.Empty(t, mi.Unit()) {{- end }} {{- if $metric.Data.HasMonotonic }} - assert.{{- if $metric.Data.Monotonic }}True{{ else }}False{{ end }}(t, ms.At(i).{{ $metric.Data.Type }}().IsMonotonic()) + assert.{{- if $metric.Data.Monotonic }}True{{ else }}False{{ end }}(t, mi.{{ $metric.Data.Type }}().IsMonotonic()) {{- end }} {{- if $metric.Data.HasAggregated }} - assert.Equal(t, pmetric.AggregationTemporality{{ $metric.Data.AggregationTemporality }}, ms.At(i).{{ $metric.Data.Type }}().AggregationTemporality()) + assert.Equal(t, pmetric.AggregationTemporality{{ $metric.Data.AggregationTemporality }}, mi.{{ $metric.Data.Type }}().AggregationTemporality()) {{- end }} - dp := ms.At(i).{{ $metric.Data.Type }}().DataPoints().At(0) + dp := mi.{{ $metric.Data.Type }}().DataPoints().At(0) assert.Equal(t, start, dp.StartTimestamp()) assert.Equal(t, ts, dp.Timestamp()) assert.Equal(t, pmetric.NumberDataPointValueType{{ $metric.Data.MetricValueType }}, dp.ValueType()) @@ -207,7 +383,8 @@ func TestMetricsBuilder(t *testing.T) { {{- end }} {{- if or (eq (attributeInfo $attr).Type.String "Slice") (eq (attributeInfo $attr).Type.String "Map")}}.AsRaw(){{ end }}) {{- end }} - {{- end }} + {{- end }} + {{- end }} } } }) diff --git a/cmd/mdatagen/internal/templates/package_test.go.tmpl b/cmd/mdatagen/internal/templates/package_test.go.tmpl index 892248f63dff..71dc86cbc5d4 100644 --- a/cmd/mdatagen/internal/templates/package_test.go.tmpl +++ b/cmd/mdatagen/internal/templates/package_test.go.tmpl @@ -3,27 +3,27 @@ package {{ if isCommand -}}main{{ else }}{{ .Package }}{{- end }} import ( - {{- if .Tests.GoLeak.Skip }} - "os" - {{- end }} + {{- if .Tests.GoLeak.Skip }} + "os" + {{- end }} "testing" - {{- if not .Tests.GoLeak.Skip }} - "go.uber.org/goleak" - {{- end }} + {{- if not .Tests.GoLeak.Skip }} + "go.uber.org/goleak" + {{- end }} ) func TestMain(m *testing.M) { - {{- if .Tests.GoLeak.Setup }} - {{.Tests.GoLeak.Setup}} - {{- end }} - {{- if .Tests.GoLeak.Skip }} - // skipping goleak test as per metadata.yml configuration - os.Exit(m.Run()) - {{- else }} + {{- if .Tests.GoLeak.Setup }} + {{.Tests.GoLeak.Setup}} + {{- end }} + {{- if .Tests.GoLeak.Skip }} + // skipping goleak test as per metadata.yml configuration + os.Exit(m.Run()) + {{- else }} goleak.VerifyTestMain(m {{- range $val := .Tests.GoLeak.Ignore.Top}}, goleak.IgnoreTopFunction("{{$val}}"){{end}}{{- range $val := .Tests.GoLeak.Ignore.Any}}, goleak.IgnoreAnyFunction("{{$val}}"){{end}} ) - {{- end }} - {{- if .Tests.GoLeak.Teardown }} - {{.Tests.GoLeak.Teardown}} - {{- end }} + {{- end }} + {{- if .Tests.GoLeak.Teardown }} + {{.Tests.GoLeak.Teardown}} + {{- end }} } diff --git a/cmd/mdatagen/internal/templates/readme.md.tmpl b/cmd/mdatagen/internal/templates/readme.md.tmpl index 74ff711b8d11..bd707b641bc4 100644 --- a/cmd/mdatagen/internal/templates/readme.md.tmpl +++ b/cmd/mdatagen/internal/templates/readme.md.tmpl @@ -1,4 +1,11 @@ +{{- if .DisplayName }} +# {{ .DisplayName }} +{{- end }} +{{- if .Description }} + +{{ .Description }} +{{ end -}} {{- if len .Status.Stability }} | Status | | | ------------- |-----------| diff --git a/cmd/mdatagen/internal/templates/resource.go.tmpl b/cmd/mdatagen/internal/templates/resource.go.tmpl index ef84f1cf12d7..068fe11dcdf6 100644 --- a/cmd/mdatagen/internal/templates/resource.go.tmpl +++ b/cmd/mdatagen/internal/templates/resource.go.tmpl @@ -4,9 +4,6 @@ package {{ .Package }} import ( "go.opentelemetry.io/collector/pdata/pcommon" -{{- if .HasEntities }} - "go.opentelemetry.io/collector/pdata/xpdata/entity" -{{- end }} ) // ResourceBuilder is a helper struct to build resources predefined in metadata.yaml. @@ -46,30 +43,6 @@ func (rb *ResourceBuilder) Set{{ $name.Render }}(val {{ $attr.Type.Primitive }}) {{- end }} {{ end }} -{{- if .HasEntities }} - -{{ range $entity := .Entities }} -// AssociateWith{{ $entity.Type | publicVar }} associates the resource with entity type "{{ $entity.Type }}". -// This method is experimental and will be replaced with an entity builder pattern in the future. -// However, for now, it allows associating resources with entities and producing correct entity references. -func (rb *ResourceBuilder) AssociateWith{{ $entity.Type | publicVar }}() { - entityRef := entity.ResourceEntityRefs(rb.res).AppendEmpty() - entityRef.SetType("{{ $entity.Type }}") - {{- if $entity.Identity }} - idKeys := entityRef.IdKeys() - {{- range $entity.Identity }} - idKeys.Append("{{ .Ref }}") - {{- end }} - {{- end }} - {{- if $entity.Description }} - descKeys := entityRef.DescriptionKeys() - {{- range $entity.Description }} - descKeys.Append("{{ .Ref }}") - {{- end }} - {{- end }} -} -{{ end }} -{{- end }} // Emit returns the built resource and resets the internal builder state. func (rb *ResourceBuilder) Emit() pcommon.Resource { diff --git a/cmd/mdatagen/internal/templates/status.go.tmpl b/cmd/mdatagen/internal/templates/status.go.tmpl index 789605ee01fb..9f7206a68e4c 100644 --- a/cmd/mdatagen/internal/templates/status.go.tmpl +++ b/cmd/mdatagen/internal/templates/status.go.tmpl @@ -7,8 +7,11 @@ import ( ) var ( - Type = component.MustNewType("{{ .Type }}") - ScopeName = "{{ .ScopeName }}" + Type = component.MustNewType("{{ .Type }}") +{{- if .DeprecatedType }} + DeprecatedType = component.MustNewType("{{ .DeprecatedType }}") +{{- end }} + ScopeName = "{{ .ScopeName }}" ) const ( diff --git a/cmd/mdatagen/internal/templates/telemetry.go.tmpl b/cmd/mdatagen/internal/templates/telemetry.go.tmpl index da4dc276973e..560e58049688 100644 --- a/cmd/mdatagen/internal/templates/telemetry.go.tmpl +++ b/cmd/mdatagen/internal/templates/telemetry.go.tmpl @@ -3,29 +3,29 @@ package {{ .Package }} import ( - {{- if .Telemetry.Metrics }} - {{- range $_, $metric := .Telemetry.Metrics }} - {{- if $metric.Data.Async }} - "context" - {{- break}} - {{- end }} - {{- end }} - "errors" - "sync" - {{- end }} - - "go.opentelemetry.io/otel/metric" - {{- if .Telemetry.Metrics }} - {{- range $_, $metric := .Telemetry.Metrics }} - {{- if $metric.Data.Async }} - "go.opentelemetry.io/otel/metric/embedded" - {{- break}} - {{- end }} - {{- end }} - {{- end }} - "go.opentelemetry.io/otel/trace" - - "go.opentelemetry.io/collector/component" + {{- if .Telemetry.Metrics }} + {{- range $_, $metric := .Telemetry.Metrics }} + {{- if $metric.Data.Async }} + "context" + {{- break}} + {{- end }} + {{- end }} + "errors" + "sync" + {{- end }} + + "go.opentelemetry.io/otel/metric" + {{- if .Telemetry.Metrics }} + {{- range $_, $metric := .Telemetry.Metrics }} + {{- if $metric.Data.Async }} + "go.opentelemetry.io/otel/metric/embedded" + {{- break}} + {{- end }} + {{- end }} + {{- end }} + "go.opentelemetry.io/otel/trace" + + "go.opentelemetry.io/collector/component" ) func Meter(settings component.TelemetrySettings) metric.Meter { @@ -40,61 +40,61 @@ func Tracer(settings component.TelemetrySettings) trace.Tracer { // TelemetryBuilder provides an interface for components to report telemetry // as defined in metadata and user config. type TelemetryBuilder struct { - meter metric.Meter + meter metric.Meter mu sync.Mutex - registrations []metric.Registration + registrations []metric.Registration {{- range $name, $metric := .Telemetry.Metrics }} {{ $name.Render }} metric.{{ $metric.Data.Instrument }} - {{- if and ($metric.Data.Async) (not $metric.Optional) }} - {{- end }} + {{- if and ($metric.Data.Async) (not $metric.Optional) }} + {{- end }} {{- end }} } // TelemetryBuilderOption applies changes to default builder. type TelemetryBuilderOption interface { - apply(*TelemetryBuilder) + apply(*TelemetryBuilder) } type telemetryBuilderOptionFunc func(mb *TelemetryBuilder) func (tbof telemetryBuilderOptionFunc) apply(mb *TelemetryBuilder) { - tbof(mb) + tbof(mb) } {{- range $name, $metric := .Telemetry.Metrics }} - {{ if $metric.Data.Async -}} + {{ if $metric.Data.Async -}} // Register{{ $name.Render }}Callback sets callback for observable {{ $name.Render }} metric. func (builder *TelemetryBuilder) Register{{ $name.Render }}Callback(cb metric.{{ casesTitle $metric.Data.BasicType }}Callback) error { - reg, err := builder.meter.RegisterCallback(func(ctx context.Context, o metric.Observer) error { - cb(ctx, &observer{{ casesTitle $metric.Data.BasicType }}{inst : builder.{{ $name.Render }}, obs: o}) - return nil - }, builder.{{ $name.Render }}) + reg, err := builder.meter.RegisterCallback(func(ctx context.Context, o metric.Observer) error { + cb(ctx, &observer{{ casesTitle $metric.Data.BasicType }}{inst : builder.{{ $name.Render }}, obs: o}) + return nil + }, builder.{{ $name.Render }}) if err != nil { return err - } - builder.mu.Lock() - defer builder.mu.Unlock() - builder.registrations = append(builder.registrations, reg) - return nil + } + builder.mu.Lock() + defer builder.mu.Unlock() + builder.registrations = append(builder.registrations, reg) + return nil } - {{- end }} + {{- end }} {{- end }} {{- range $name, $metric := .Telemetry.Metrics }} {{- if $metric.Data.Async }} - {{ if eq $metric.Data.BasicType "int64" -}} + {{ if eq $metric.Data.BasicType "int64" -}} type observerInt64 struct { embedded.Int64Observer - inst metric.Int64Observable - obs metric.Observer + inst metric.Int64Observable + obs metric.Observer } func (oi *observerInt64) Observe(value int64, opts ...metric.ObserveOption) { - oi.obs.ObserveInt64(oi.inst, value, opts...) + oi.obs.ObserveInt64(oi.inst, value, opts...) } - {{ break }} - {{- end }} + {{ break }} + {{- end }} {{- end }} {{- end }} @@ -102,13 +102,13 @@ func (oi *observerInt64) Observe(value int64, opts ...metric.ObserveOption) { {{- if $metric.Data.Async }} {{ if eq $metric.Data.BasicType "float64" -}} type observerFloat64 struct { - embedded.Float64Observer - inst metric.Float64Observable - obs metric.Observer + embedded.Float64Observer + inst metric.Float64Observable + obs metric.Observer } func (oi *observerFloat64) Observe(value float64, opts ...metric.ObserveOption) { - oi.obs.ObserveFloat64(oi.inst, value, opts...) + oi.obs.ObserveFloat64(oi.inst, value, opts...) } {{ break }} {{- end }} @@ -117,39 +117,39 @@ func (oi *observerFloat64) Observe(value float64, opts ...metric.ObserveOption) // Shutdown unregister all registered callbacks for async instruments. func (builder *TelemetryBuilder) Shutdown() { - builder.mu.Lock() + builder.mu.Lock() defer builder.mu.Unlock() for _, reg := range builder.registrations { - reg.Unregister() - } + reg.Unregister() + } } // NewTelemetryBuilder provides a struct with methods to update all internal telemetry // for a component func NewTelemetryBuilder(settings component.TelemetrySettings, options ...TelemetryBuilderOption) (*TelemetryBuilder, error) { - builder := TelemetryBuilder{} + builder := TelemetryBuilder{} for _, op := range options { op.apply(&builder) } - builder.meter = Meter(settings) - var err, errs error - - {{- range $name, $metric := .Telemetry.Metrics }} - builder.{{ $name.Render }}, err = builder.meter.{{ $metric.Data.Instrument }}( - {{ if $metric.Prefix -}} - "{{ $metric.Prefix }}{{ $name }}", - {{ else -}} - "otelcol_{{ $name }}", - {{ end -}} - metric.WithDescription("{{ $metric.Description }}{{ $metric.Stability }}"), - metric.WithUnit("{{ $metric.Unit }}"), - {{ if eq $metric.Data.Type "Histogram" -}} - {{- if $metric.Data.Boundaries -}}metric.WithExplicitBucketBoundaries([]float64{ {{- range $metric.Data.Boundaries }} {{.}}, {{- end }} }...),{{- end }} - {{- end }} - ) - errs = errors.Join(errs, err) - {{- end }} - return &builder, errs + builder.meter = Meter(settings) + var err, errs error + + {{- range $name, $metric := .Telemetry.Metrics }} + builder.{{ $name.Render }}, err = builder.meter.{{ $metric.Data.Instrument }}( + {{ if $metric.Prefix -}} + "{{ $metric.Prefix }}{{ $name }}", + {{ else -}} + "otelcol_{{ $name }}", + {{ end -}} + metric.WithDescription("{{ $metric.Description }} [{{ $metric.Stability }}]"), + metric.WithUnit("{{ $metric.Unit }}"), + {{ if eq $metric.Data.Type "Histogram" -}} + {{- if $metric.Data.Boundaries -}}metric.WithExplicitBucketBoundaries([]float64{ {{- range $metric.Data.Boundaries }} {{.}}, {{- end }} }...),{{- end }} + {{- end }} + ) + errs = errors.Join(errs, err) + {{- end }} + return &builder, errs } {{- end }} diff --git a/cmd/mdatagen/internal/templates/telemetrytest.go.tmpl b/cmd/mdatagen/internal/templates/telemetrytest.go.tmpl index 62a371545b26..b75e3cd19ebb 100644 --- a/cmd/mdatagen/internal/templates/telemetrytest.go.tmpl +++ b/cmd/mdatagen/internal/templates/telemetrytest.go.tmpl @@ -3,20 +3,20 @@ package {{ .Package }}test import ( - "testing" - - "github.com/stretchr/testify/require" - "go.opentelemetry.io/otel/sdk/metric/metricdata" - "go.opentelemetry.io/otel/sdk/metric/metricdata/metricdatatest" - - {{- if or isConnector isExporter isExtension isProcessor isReceiver isScraper }} - "go.opentelemetry.io/collector/component" - {{- end }} - "go.opentelemetry.io/collector/component/componenttest" - {{- if or isConnector isExporter isExtension isProcessor isReceiver isScraper }} - "go.opentelemetry.io/collector/{{ .Status.Class }}" - "go.opentelemetry.io/collector/{{ .Status.Class }}/{{ .Status.Class }}test" - {{- end }} + "testing" + + "github.com/stretchr/testify/require" + "go.opentelemetry.io/otel/sdk/metric/metricdata" + "go.opentelemetry.io/otel/sdk/metric/metricdata/metricdatatest" + + {{- if or isConnector isExporter isExtension isProcessor isReceiver isScraper }} + "go.opentelemetry.io/collector/component" + {{- end }} + "go.opentelemetry.io/collector/component/componenttest" + {{- if or isConnector isExporter isExtension isProcessor isReceiver isScraper }} + "go.opentelemetry.io/collector/{{ .Status.Class }}" + "go.opentelemetry.io/collector/{{ .Status.Class }}/{{ .Status.Class }}test" + {{- end }} ) {{ if or isConnector isExporter isExtension isProcessor isReceiver isScraper }} @@ -37,7 +37,7 @@ func AssertEqual{{ $name.Render }}(t *testing.T, tt *componenttest.Telemetry, dp {{ else -}} Name: "otelcol_{{ $name }}", {{ end -}} - Description: "{{ $metric.Description }}{{ $metric.Stability }}", + Description: "{{ $metric.Description }} [{{ $metric.Stability }}]", Unit: "{{ $metric.Unit }}", Data: metricdata.{{ $metric.Data.Type }}[{{ $metric.Data.BasicType }}]{ {{- if $metric.Data.HasAggregated }} diff --git a/cmd/mdatagen/internal/templates/telemetrytest_test.go.tmpl b/cmd/mdatagen/internal/templates/telemetrytest_test.go.tmpl index d4680f089617..871a33e092c3 100644 --- a/cmd/mdatagen/internal/templates/telemetrytest_test.go.tmpl +++ b/cmd/mdatagen/internal/templates/telemetrytest_test.go.tmpl @@ -3,61 +3,61 @@ package {{ .Package }}test import ( - "context" - "testing" + "context" + "testing" "github.com/stretchr/testify/require" - {{- if .Telemetry.Metrics }} - {{- range $_, $metric := .Telemetry.Metrics }} - {{- if $metric.Data.Async }} - "go.opentelemetry.io/otel/metric" - {{- break}} - {{- end }} - {{- end }} - {{- end }} - "go.opentelemetry.io/otel/sdk/metric/metricdata" - "go.opentelemetry.io/otel/sdk/metric/metricdata/metricdatatest" - - "go.opentelemetry.io/collector/component/componenttest" - "{{ .PackageName }}/internal/{{ .GeneratedPackageName }}" + {{- if .Telemetry.Metrics }} + {{- range $_, $metric := .Telemetry.Metrics }} + {{- if $metric.Data.Async }} + "go.opentelemetry.io/otel/metric" + {{- break}} + {{- end }} + {{- end }} + {{- end }} + "go.opentelemetry.io/otel/sdk/metric/metricdata" + "go.opentelemetry.io/otel/sdk/metric/metricdata/metricdatatest" + + "go.opentelemetry.io/collector/component/componenttest" + "{{ .PackageName }}/internal/{{ .GeneratedPackageName }}" ) func TestSetupTelemetry(t *testing.T) { testTel := componenttest.NewTelemetry() tb, err := {{ .Package }}.NewTelemetryBuilder(testTel.NewTelemetrySettings()) - require.NoError(t, err) + require.NoError(t, err) defer tb.Shutdown() - {{- range $name, $metric := .Telemetry.Metrics }} - {{- if $metric.Data.Async }} - require.NoError(t, tb.Register{{ $name.Render }}Callback(func(_ context.Context, observer metric.{{ casesTitle $metric.Data.BasicType }}Observer) error { - observer.Observe(1) - return nil - })) - {{- end }} - {{- end }} - - {{- range $name, $metric := .Telemetry.Metrics }} - {{- if not $metric.Data.Async }} - {{- if eq $metric.Data.Type "Sum" }} - tb.{{ $name.Render }}.Add(context.Background(), 1) - {{- else }} - tb.{{ $name.Render }}.Record(context.Background(), 1) - {{- end }} - {{- end }} - {{- end }} - - {{- range $name, $metric := .Telemetry.Metrics }} - AssertEqual{{ $name.Render }}(t, testTel, - {{ if eq $metric.Data.Type "Gauge" -}} - []metricdata.DataPoint[{{ $metric.Gauge.MetricValueType.BasicType }}]{{"{{Value: 1}}"}}, - {{- else if eq $metric.Data.Type "Sum" -}} - []metricdata.DataPoint[{{ $metric.Sum.MetricValueType.BasicType }}]{{"{{Value: 1}}"}}, - {{- else if eq $metric.Data.Type "Histogram" -}} - []metricdata.HistogramDataPoint[{{ $metric.Histogram.MetricValueType.BasicType }}]{{"{{}}"}}, metricdatatest.IgnoreValue(), - {{- end }} - metricdatatest.IgnoreTimestamp()) - {{- end }} + {{- range $name, $metric := .Telemetry.Metrics }} + {{- if $metric.Data.Async }} + require.NoError(t, tb.Register{{ $name.Render }}Callback(func(_ context.Context, observer metric.{{ casesTitle $metric.Data.BasicType }}Observer) error { + observer.Observe(1) + return nil + })) + {{- end }} + {{- end }} + + {{- range $name, $metric := .Telemetry.Metrics }} + {{- if not $metric.Data.Async }} + {{- if eq $metric.Data.Type "Sum" }} + tb.{{ $name.Render }}.Add(context.Background(), 1) + {{- else }} + tb.{{ $name.Render }}.Record(context.Background(), 1) + {{- end }} + {{- end }} + {{- end }} + + {{- range $name, $metric := .Telemetry.Metrics }} + AssertEqual{{ $name.Render }}(t, testTel, + {{ if eq $metric.Data.Type "Gauge" -}} + []metricdata.DataPoint[{{ $metric.Gauge.MetricValueType.BasicType }}]{{"{{Value: 1}}"}}, + {{- else if eq $metric.Data.Type "Sum" -}} + []metricdata.DataPoint[{{ $metric.Sum.MetricValueType.BasicType }}]{{"{{Value: 1}}"}}, + {{- else if eq $metric.Data.Type "Histogram" -}} + []metricdata.HistogramDataPoint[{{ $metric.Histogram.MetricValueType.BasicType }}]{{"{{}}"}}, metricdatatest.IgnoreValue(), + {{- end }} + metricdatatest.IgnoreTimestamp()) + {{- end }} require.NoError(t, testTel.Shutdown(context.Background())) } diff --git a/cmd/mdatagen/internal/templates/testdata/config.yaml.tmpl b/cmd/mdatagen/internal/templates/testdata/config.yaml.tmpl index 1edabcba2c42..cd0693e31f18 100644 --- a/cmd/mdatagen/internal/templates/testdata/config.yaml.tmpl +++ b/cmd/mdatagen/internal/templates/testdata/config.yaml.tmpl @@ -1,10 +1,43 @@ +{{- $reag := .ReaggregationEnabled -}} default: all_set: +{{- if $reag }} {{- if .Metrics }} metrics: - {{- range $name, $_ := .Metrics }} + {{- range $name, $metric := .Metrics }} + {{- $metricReag := and $reag (hasAggregatableAttributes $metric.Attributes) }} {{ $name }}: enabled: true + {{- if $metricReag }} + attributes: [{{- range $index, $element := $metric.Attributes -}}{{ if $index }},{{ end }}"{{ (attributeInfo $element).Name }}"{{ end -}}] + {{- end }} + {{- end }} + {{- end }} + {{- if .Events }} + events: + {{- range $name, $_ := .Events }} + {{ $name }}: + enabled: true + {{- end }} + {{- end }} + {{- if .ResourceAttributes }} + resource_attributes: + {{- range $name, $_ := .ResourceAttributes }} + {{ $name }}: + enabled: true + {{- end }} + {{- end }} +reaggregate_set: +{{- end }} + {{- if .Metrics }} + metrics: + {{- range $name, $metric := .Metrics }} + {{- $metricReag := and $reag (hasAggregatableAttributes $metric.Attributes) }} + {{ $name }}: + enabled: true + {{- if $metricReag }} + attributes: [{{- range $index, $attr := requiredAttributes $metric.Attributes -}}{{ if $index }},{{ end }}"{{ $attr }}"{{- end -}}] + {{- end }} {{- end }} {{- end }} {{- if .Events }} @@ -24,9 +57,13 @@ all_set: none_set: {{- if .Metrics }} metrics: - {{- range $name, $_ := .Metrics }} + {{- range $name, $metric := .Metrics }} + {{- $metricReag := and $reag (hasAggregatableAttributes $metric.Attributes) }} {{ $name }}: enabled: false + {{- if $metricReag }} + attributes: [{{- range $index, $element := $metric.Attributes -}}{{ if $index }},{{ end }}"{{ (attributeInfo $element).Name }}"{{ end -}}] + {{- end }} {{- end }} {{- end }} {{- if .Events }} diff --git a/cmd/mdatagen/internal/testdata/async_metric.yaml b/cmd/mdatagen/internal/testdata/async_metric.yaml index 0ab626840902..48bba1e958cf 100644 --- a/cmd/mdatagen/internal/testdata/async_metric.yaml +++ b/cmd/mdatagen/internal/testdata/async_metric.yaml @@ -13,8 +13,7 @@ metrics: metric: enabled: true description: Description. - stability: - level: development + stability: development unit: s gauge: value_type: double diff --git a/cmd/mdatagen/internal/testdata/display_name.yaml b/cmd/mdatagen/internal/testdata/display_name.yaml new file mode 100644 index 000000000000..ea5f9088ecf6 --- /dev/null +++ b/cmd/mdatagen/internal/testdata/display_name.yaml @@ -0,0 +1,7 @@ +type: test +display_name: Test Receiver + +status: + class: receiver + stability: + beta: [logs] diff --git a/cmd/mdatagen/internal/testdata/entity_event_missing_association.yaml b/cmd/mdatagen/internal/testdata/entity_event_missing_association.yaml new file mode 100644 index 000000000000..dfc987a9eef4 --- /dev/null +++ b/cmd/mdatagen/internal/testdata/entity_event_missing_association.yaml @@ -0,0 +1,38 @@ +type: sample +status: + class: receiver + stability: + stable: [metrics] + +resource_attributes: + host.id: + description: The unique host identifier + type: string + enabled: true + process.pid: + description: The process identifier + type: int + enabled: true + +entities: + - type: host + brief: A host instance. + stability: stable + identity: + - ref: host.id + - type: process + brief: A process instance. + stability: stable + identity: + - ref: process.pid + +attributes: + test.attr: + description: Test attribute + type: string + +events: + host.restart: + enabled: true + description: Host restart event + attributes: [test.attr] diff --git a/cmd/mdatagen/internal/testdata/entity_metric_missing_association.yaml b/cmd/mdatagen/internal/testdata/entity_metric_missing_association.yaml new file mode 100644 index 000000000000..639c51db549a --- /dev/null +++ b/cmd/mdatagen/internal/testdata/entity_metric_missing_association.yaml @@ -0,0 +1,44 @@ +type: sample +status: + class: receiver + stability: + stable: [metrics] + +resource_attributes: + host.id: + description: The unique host identifier + type: string + enabled: true + process.pid: + description: The process identifier + type: int + enabled: true + +entities: + - type: host + brief: A host instance. + stability: stable + identity: + - ref: host.id + - type: process + brief: A process instance. + stability: stable + identity: + - ref: process.pid + +attributes: + test.attr: + description: Test attribute + type: string + +metrics: + host.cpu.time: + enabled: true + description: Host CPU time + unit: s + sum: + value_type: int + monotonic: true + aggregation_temporality: cumulative + stability: stable + attributes: [test.attr] diff --git a/cmd/mdatagen/internal/testdata/entity_metrics_events_valid.yaml b/cmd/mdatagen/internal/testdata/entity_metrics_events_valid.yaml new file mode 100644 index 000000000000..441bd3f86bb6 --- /dev/null +++ b/cmd/mdatagen/internal/testdata/entity_metrics_events_valid.yaml @@ -0,0 +1,76 @@ +type: sample +status: + class: receiver + stability: + stable: [metrics] + +resource_attributes: + host.id: + description: The unique host identifier + type: string + enabled: true + host.name: + description: The hostname + type: string + enabled: true + process.pid: + description: The process identifier + type: int + enabled: true + +entities: + - type: host + brief: A host instance. + stability: stable + identity: + - ref: host.id + description: + - ref: host.name + - type: process + brief: A process instance. + stability: stable + identity: + - ref: process.pid + +attributes: + test.attr: + description: Test attribute + type: string + +metrics: + host.cpu.time: + enabled: true + description: Host CPU time + unit: s + sum: + value_type: int + monotonic: true + aggregation_temporality: cumulative + stability: stable + entity: host + attributes: [test.attr] + + process.cpu.time: + enabled: true + description: Process CPU time + unit: s + sum: + value_type: int + monotonic: true + aggregation_temporality: cumulative + stability: stable + entity: process + attributes: [test.attr] + +events: + host.restart: + enabled: true + description: Host restart event + entity: host + attributes: [test.attr] + + process.start: + enabled: true + description: Process start event + entity: process + attributes: [test.attr] diff --git a/cmd/mdatagen/internal/testdata/entity_relationships_bidirectional.yaml b/cmd/mdatagen/internal/testdata/entity_relationships_bidirectional.yaml new file mode 100644 index 000000000000..0d722bc9a66d --- /dev/null +++ b/cmd/mdatagen/internal/testdata/entity_relationships_bidirectional.yaml @@ -0,0 +1,33 @@ +type: sample +status: + class: receiver + stability: + stable: [metrics] + +resource_attributes: + k8s.replicaset.uid: + description: The unique identifier of the Kubernetes ReplicaSet + type: string + enabled: true + k8s.pod.uid: + description: The unique identifier of the Kubernetes pod + type: string + enabled: true + +entities: + - type: k8s.replicaset + brief: A Kubernetes ReplicaSet + stability: stable + identity: + - ref: k8s.replicaset.uid + relationships: + - type: controls + target: k8s.pod + - type: k8s.pod + brief: A Kubernetes pod + stability: stable + identity: + - ref: k8s.pod.uid + relationships: + - type: controlled_by + target: k8s.replicaset diff --git a/cmd/mdatagen/internal/testdata/entity_relationships_empty_target.yaml b/cmd/mdatagen/internal/testdata/entity_relationships_empty_target.yaml new file mode 100644 index 000000000000..1ccb213e1699 --- /dev/null +++ b/cmd/mdatagen/internal/testdata/entity_relationships_empty_target.yaml @@ -0,0 +1,29 @@ +type: sample +status: + class: receiver + stability: + stable: [metrics] + +resource_attributes: + k8s.replicaset.uid: + description: The unique identifier of the Kubernetes ReplicaSet + type: string + enabled: true + k8s.pod.uid: + description: The unique identifier of the Kubernetes pod + type: string + enabled: true + +entities: + - type: k8s.replicaset + brief: A Kubernetes ReplicaSet + stability: stable + identity: + - ref: k8s.replicaset.uid + - type: k8s.pod + brief: A Kubernetes pod + stability: stable + identity: + - ref: k8s.pod.uid + relationships: + - type: controlled_by diff --git a/cmd/mdatagen/internal/testdata/entity_relationships_empty_type.yaml b/cmd/mdatagen/internal/testdata/entity_relationships_empty_type.yaml new file mode 100644 index 000000000000..665152dd69f5 --- /dev/null +++ b/cmd/mdatagen/internal/testdata/entity_relationships_empty_type.yaml @@ -0,0 +1,29 @@ +type: sample +status: + class: receiver + stability: + stable: [metrics] + +resource_attributes: + k8s.replicaset.uid: + description: The unique identifier of the Kubernetes ReplicaSet + type: string + enabled: true + k8s.pod.uid: + description: The unique identifier of the Kubernetes pod + type: string + enabled: true + +entities: + - type: k8s.replicaset + brief: A Kubernetes ReplicaSet + stability: stable + identity: + - ref: k8s.replicaset.uid + - type: k8s.pod + brief: A Kubernetes pod + stability: stable + identity: + - ref: k8s.pod.uid + relationships: + - target: k8s.replicaset diff --git a/cmd/mdatagen/internal/testdata/entity_relationships_undefined_target.yaml b/cmd/mdatagen/internal/testdata/entity_relationships_undefined_target.yaml new file mode 100644 index 000000000000..c97f39526310 --- /dev/null +++ b/cmd/mdatagen/internal/testdata/entity_relationships_undefined_target.yaml @@ -0,0 +1,21 @@ +type: sample +status: + class: receiver + stability: + stable: [metrics] + +resource_attributes: + k8s.pod.uid: + description: The unique identifier of the Kubernetes pod + type: string + enabled: true + +entities: + - type: k8s.pod + brief: A Kubernetes pod + stability: stable + identity: + - ref: k8s.pod.uid + relationships: + - type: controlled_by + target: k8s.replicaset diff --git a/cmd/mdatagen/internal/testdata/entity_relationships_valid.yaml b/cmd/mdatagen/internal/testdata/entity_relationships_valid.yaml new file mode 100644 index 000000000000..4f01a680dc3f --- /dev/null +++ b/cmd/mdatagen/internal/testdata/entity_relationships_valid.yaml @@ -0,0 +1,42 @@ +type: sample +status: + class: receiver + stability: + stable: [metrics] + +resource_attributes: + k8s.replicaset.uid: + description: The unique identifier of the Kubernetes ReplicaSet + type: string + enabled: true + k8s.replicaset.name: + description: The name of the Kubernetes ReplicaSet + type: string + enabled: true + k8s.pod.uid: + description: The unique identifier of the Kubernetes pod + type: string + enabled: true + k8s.pod.name: + description: The name of the Kubernetes pod + type: string + enabled: true + +entities: + - type: k8s.replicaset + brief: A Kubernetes ReplicaSet + stability: stable + identity: + - ref: k8s.replicaset.uid + description: + - ref: k8s.replicaset.name + - type: k8s.pod + brief: A Kubernetes pod + stability: stable + identity: + - ref: k8s.pod.uid + description: + - ref: k8s.pod.name + relationships: + - type: controlled_by + target: k8s.replicaset diff --git a/cmd/mdatagen/internal/testdata/entity_single_metric_missing_association.yaml b/cmd/mdatagen/internal/testdata/entity_single_metric_missing_association.yaml new file mode 100644 index 000000000000..1d00a4f34f72 --- /dev/null +++ b/cmd/mdatagen/internal/testdata/entity_single_metric_missing_association.yaml @@ -0,0 +1,35 @@ +type: sample +status: + class: receiver + stability: + stable: [metrics] + +resource_attributes: + host.id: + description: The unique host identifier + type: string + enabled: true + +entities: + - type: host + brief: A host instance. + stability: stable + identity: + - ref: host.id + +attributes: + test.attr: + description: Test attribute + type: string + +metrics: + host.cpu.time: + enabled: true + description: Host CPU time + unit: s + sum: + value_type: int + monotonic: true + aggregation_temporality: cumulative + stability: stable + attributes: [test.attr] diff --git a/cmd/mdatagen/internal/testdata/entity_undefined_reference.yaml b/cmd/mdatagen/internal/testdata/entity_undefined_reference.yaml new file mode 100644 index 000000000000..36ce63198532 --- /dev/null +++ b/cmd/mdatagen/internal/testdata/entity_undefined_reference.yaml @@ -0,0 +1,36 @@ +type: sample +status: + class: receiver + stability: + stable: [metrics] + +resource_attributes: + host.id: + description: The unique host identifier + type: string + enabled: true + +entities: + - type: host + brief: A host instance. + stability: stable + identity: + - ref: host.id + +attributes: + test.attr: + description: Test attribute + type: string + +metrics: + host.cpu.time: + enabled: true + description: Host CPU time + unit: s + sum: + value_type: int + monotonic: true + aggregation_temporality: cumulative + stability: stable + entity: undefined_entity + attributes: [test.attr] diff --git a/cmd/mdatagen/internal/testdata/feature_gates.yaml b/cmd/mdatagen/internal/testdata/feature_gates.yaml new file mode 100644 index 000000000000..11b6b0894395 --- /dev/null +++ b/cmd/mdatagen/internal/testdata/feature_gates.yaml @@ -0,0 +1,19 @@ +type: sample +status: + class: receiver + stability: + beta: [metrics] + +feature_gates: + - id: sample.feature.gate + description: 'This is a sample feature gate for testing purposes' + stage: alpha + from_version: 'v0.100.0' + reference_url: 'https://github.com/open-telemetry/opentelemetry-collector/issues/12345' + + - id: stable.feature.gate + description: 'This is a stable feature gate' + stage: stable + from_version: 'v0.90.0' + to_version: 'v0.95.0' + reference_url: 'https://github.com/open-telemetry/opentelemetry-collector/issues/11111' diff --git a/cmd/mdatagen/internal/testdata/internal/metadata/generated_status.go b/cmd/mdatagen/internal/testdata/internal/metadata/generated_status.go new file mode 100644 index 000000000000..66b7b2c30cfc --- /dev/null +++ b/cmd/mdatagen/internal/testdata/internal/metadata/generated_status.go @@ -0,0 +1,16 @@ +// Code generated by mdatagen. DO NOT EDIT. + +package metadata + +import ( + "go.opentelemetry.io/collector/component" +) + +var ( + Type = component.MustNewType("sample") + ScopeName = "go.opentelemetry.io/collector/cmd/mdatagen/internal/testdata" +) + +const ( + MetricsStability = component.StabilityLevelBeta +) diff --git a/cmd/mdatagen/internal/testdata/invalid_aggregation.yaml b/cmd/mdatagen/internal/testdata/invalid_aggregation.yaml index c86c2d626625..7c798965c6d7 100644 --- a/cmd/mdatagen/internal/testdata/invalid_aggregation.yaml +++ b/cmd/mdatagen/internal/testdata/invalid_aggregation.yaml @@ -15,8 +15,7 @@ metrics: enabled: true description: Monotonic cumulative sum int metric enabled by default. extended_documentation: The metric will be become optional soon. - stability: - level: development + stability: development unit: s sum: value_type: int diff --git a/cmd/mdatagen/internal/testdata/invalid_config.yaml b/cmd/mdatagen/internal/testdata/invalid_config.yaml new file mode 100644 index 000000000000..53e2030db4ef --- /dev/null +++ b/cmd/mdatagen/internal/testdata/invalid_config.yaml @@ -0,0 +1,13 @@ +type: receiver + +status: + class: receiver + stability: + beta: [logs] + distributions: [contrib] + +config: + type: string + properties: + endpoint: + type: string diff --git a/cmd/mdatagen/internal/testdata/invalid_entity_stability.yaml b/cmd/mdatagen/internal/testdata/invalid_entity_stability.yaml new file mode 100644 index 000000000000..722ac9558310 --- /dev/null +++ b/cmd/mdatagen/internal/testdata/invalid_entity_stability.yaml @@ -0,0 +1,28 @@ +type: sample +status: + class: receiver + stability: + stable: [metrics] + +resource_attributes: + host.id: + description: The unique host identifier + type: string + enabled: true + host.name: + description: The hostname + type: string + enabled: true + process.pid: + description: The process identifier + type: int + enabled: true + +entities: + - type: host + brief: A host instance. + stability: stable42 + identity: + - ref: host.id + description: + - ref: host.name diff --git a/cmd/mdatagen/internal/testdata/invalid_input_type.yaml b/cmd/mdatagen/internal/testdata/invalid_input_type.yaml index 5651abe9b4f3..3ecbe5cfa64c 100644 --- a/cmd/mdatagen/internal/testdata/invalid_input_type.yaml +++ b/cmd/mdatagen/internal/testdata/invalid_input_type.yaml @@ -11,8 +11,7 @@ metrics: system.cpu.time: enabled: true description: Total CPU seconds broken down by different states. - stability: - level: development + stability: development unit: s sum: value_type: double diff --git a/cmd/mdatagen/internal/testdata/invalid_metric_semconvref.yaml b/cmd/mdatagen/internal/testdata/invalid_metric_semconvref.yaml index cccf15e55245..0f431e8deae9 100644 --- a/cmd/mdatagen/internal/testdata/invalid_metric_semconvref.yaml +++ b/cmd/mdatagen/internal/testdata/invalid_metric_semconvref.yaml @@ -17,8 +17,7 @@ metrics: enabled: true description: Monotonic cumulative sum int metric enabled by default. extended_documentation: The metric will be become optional soon. - stability: - level: development + stability: development semantic_convention: ref: https://github.com/open-telemetry/semantic-conventions/blob/v1.38.0/docs/system/system-metrics.md#metric-systemcputime unit: s diff --git a/cmd/mdatagen/internal/testdata/invalid_metric_stability.yaml b/cmd/mdatagen/internal/testdata/invalid_metric_stability.yaml index 0906a5720b44..44d900a78202 100644 --- a/cmd/mdatagen/internal/testdata/invalid_metric_stability.yaml +++ b/cmd/mdatagen/internal/testdata/invalid_metric_stability.yaml @@ -15,8 +15,7 @@ metrics: enabled: true description: Monotonic cumulative sum int metric enabled by default. extended_documentation: The metric will be become optional soon. - stability: - level: development42 + stability: development42 unit: s sum: value_type: int diff --git a/cmd/mdatagen/internal/testdata/metrics_and_type.yaml b/cmd/mdatagen/internal/testdata/metrics_and_type.yaml index e2591e04f6ed..537a56335ee9 100644 --- a/cmd/mdatagen/internal/testdata/metrics_and_type.yaml +++ b/cmd/mdatagen/internal/testdata/metrics_and_type.yaml @@ -13,8 +13,7 @@ metrics: metric: enabled: true description: Description. - stability: - level: development + stability: development unit: s gauge: value_type: double diff --git a/cmd/mdatagen/internal/testdata/no_aggregation.yaml b/cmd/mdatagen/internal/testdata/no_aggregation.yaml index f9425fa6df78..fb19f85ed166 100644 --- a/cmd/mdatagen/internal/testdata/no_aggregation.yaml +++ b/cmd/mdatagen/internal/testdata/no_aggregation.yaml @@ -16,9 +16,8 @@ metrics: enabled: true description: Monotonic cumulative sum int metric enabled by default. extended_documentation: The metric will be become optional soon. - stability: - level: development + stability: development unit: s sum: value_type: int - monotonic: false \ No newline at end of file + monotonic: false diff --git a/cmd/mdatagen/internal/testdata/no_description_attr.yaml b/cmd/mdatagen/internal/testdata/no_description_attr.yaml index 6d4744ca86ea..63d60cc3c491 100644 --- a/cmd/mdatagen/internal/testdata/no_description_attr.yaml +++ b/cmd/mdatagen/internal/testdata/no_description_attr.yaml @@ -23,8 +23,7 @@ metrics: enabled: true description: Monotonic cumulative sum int metric enabled by default. extended_documentation: The metric will be become optional soon. - stability: - level: development + stability: development unit: s sum: value_type: int diff --git a/cmd/mdatagen/internal/testdata/no_display_name.yaml b/cmd/mdatagen/internal/testdata/no_display_name.yaml new file mode 100644 index 000000000000..0e7f304c2fc2 --- /dev/null +++ b/cmd/mdatagen/internal/testdata/no_display_name.yaml @@ -0,0 +1,6 @@ +type: nodisplayname + +status: + class: receiver + stability: + beta: [logs] diff --git a/cmd/mdatagen/internal/testdata/no_enabled.yaml b/cmd/mdatagen/internal/testdata/no_enabled.yaml index c993152f3f95..2b4a278091d2 100644 --- a/cmd/mdatagen/internal/testdata/no_enabled.yaml +++ b/cmd/mdatagen/internal/testdata/no_enabled.yaml @@ -6,12 +6,11 @@ status: development: [logs] beta: [traces] stable: [metrics] - + metrics: system.cpu.time: description: Total CPU seconds broken down by different states. - stability: - level: development + stability: development unit: s sum: value_type: double diff --git a/cmd/mdatagen/internal/testdata/no_metric_description.yaml b/cmd/mdatagen/internal/testdata/no_metric_description.yaml index 0ef5dc10d9f6..aa14a70c28f1 100644 --- a/cmd/mdatagen/internal/testdata/no_metric_description.yaml +++ b/cmd/mdatagen/internal/testdata/no_metric_description.yaml @@ -15,8 +15,7 @@ metrics: default.metric: enabled: true extended_documentation: The metric will be become optional soon. - stability: - level: development + stability: development unit: s sum: value_type: int diff --git a/cmd/mdatagen/internal/testdata/no_metric_type.yaml b/cmd/mdatagen/internal/testdata/no_metric_type.yaml index 792e88ecefc6..bb6b0c26fdd3 100644 --- a/cmd/mdatagen/internal/testdata/no_metric_type.yaml +++ b/cmd/mdatagen/internal/testdata/no_metric_type.yaml @@ -9,7 +9,6 @@ metrics: system.cpu.time: enabled: true description: Total CPU seconds broken down by different states. - stability: - level: development + stability: development unit: s attributes: diff --git a/cmd/mdatagen/internal/testdata/no_metric_unit.yaml b/cmd/mdatagen/internal/testdata/no_metric_unit.yaml index 9f55e10cf13a..394d3e677b65 100644 --- a/cmd/mdatagen/internal/testdata/no_metric_unit.yaml +++ b/cmd/mdatagen/internal/testdata/no_metric_unit.yaml @@ -16,8 +16,7 @@ metrics: enabled: true description: Monotonic cumulative sum int metric enabled by default. extended_documentation: The metric will be become optional soon. - stability: - level: development + stability: development sum: value_type: int monotonic: true diff --git a/cmd/mdatagen/internal/testdata/no_monotonic.yaml b/cmd/mdatagen/internal/testdata/no_monotonic.yaml index 9d2cf74de9a8..cda807c497be 100644 --- a/cmd/mdatagen/internal/testdata/no_monotonic.yaml +++ b/cmd/mdatagen/internal/testdata/no_monotonic.yaml @@ -16,8 +16,7 @@ metrics: enabled: true description: Monotonic cumulative sum int metric enabled by default. extended_documentation: The metric will be become optional soon. - stability: - level: development + stability: development unit: s sum: value_type: int diff --git a/cmd/mdatagen/internal/testdata/no_type_attr.yaml b/cmd/mdatagen/internal/testdata/no_type_attr.yaml index 0cc5f8e56f52..9bf9f672ce40 100644 --- a/cmd/mdatagen/internal/testdata/no_type_attr.yaml +++ b/cmd/mdatagen/internal/testdata/no_type_attr.yaml @@ -17,8 +17,7 @@ metrics: metric: enabled: true description: Metric. - stability: - level: development + stability: development unit: "1" gauge: value_type: double diff --git a/cmd/mdatagen/internal/testdata/no_value_type.yaml b/cmd/mdatagen/internal/testdata/no_value_type.yaml index cdc2412d47d3..eaab6d45086c 100644 --- a/cmd/mdatagen/internal/testdata/no_value_type.yaml +++ b/cmd/mdatagen/internal/testdata/no_value_type.yaml @@ -15,8 +15,7 @@ metrics: system.cpu.time: enabled: true description: Total CPU seconds broken down by different states. - stability: - level: development + stability: development unit: s sum: monotonic: true diff --git a/cmd/mdatagen/internal/testdata/two_metric_types.yaml b/cmd/mdatagen/internal/testdata/two_metric_types.yaml index b6b48fd2aae1..2476aff426e1 100644 --- a/cmd/mdatagen/internal/testdata/two_metric_types.yaml +++ b/cmd/mdatagen/internal/testdata/two_metric_types.yaml @@ -11,8 +11,7 @@ metrics: system.cpu.time: enabled: true description: Total CPU seconds broken down by different states. - stability: - level: development + stability: development unit: s gauge: value_type: double diff --git a/cmd/mdatagen/internal/testdata/undeprecated_with_deprecation.yaml b/cmd/mdatagen/internal/testdata/undeprecated_with_deprecation.yaml new file mode 100644 index 000000000000..6d563178a065 --- /dev/null +++ b/cmd/mdatagen/internal/testdata/undeprecated_with_deprecation.yaml @@ -0,0 +1,25 @@ +type: metricreceiver + +status: + class: receiver + stability: + development: [logs] + beta: [traces] + stable: [metrics] + distributions: [contrib] + warnings: + - Any additional information that should be brought to the consumer's attention + +metrics: + default.metric: + enabled: true + description: Monotonic cumulative sum int metric enabled by default. + extended_documentation: The metric will be become optional soon. + stability: development + deprecated: + note: this should not happen + unit: s + sum: + value_type: int + monotonic: true + aggregation_temporality: cumulative diff --git a/cmd/mdatagen/internal/testdata/unknown_metric_attribute.yaml b/cmd/mdatagen/internal/testdata/unknown_metric_attribute.yaml index 6e4bad5e281c..8f27faab13b2 100644 --- a/cmd/mdatagen/internal/testdata/unknown_metric_attribute.yaml +++ b/cmd/mdatagen/internal/testdata/unknown_metric_attribute.yaml @@ -6,13 +6,12 @@ status: development: [logs] beta: [traces] stable: [metrics] - + metrics: system.cpu.time: enabled: true description: Total CPU seconds broken down by different states. - stability: - level: development + stability: development unit: s sum: value_type: double diff --git a/cmd/mdatagen/internal/testdata/unknown_value_type.yaml b/cmd/mdatagen/internal/testdata/unknown_value_type.yaml index 1231e7282ac5..eab669a95b0a 100644 --- a/cmd/mdatagen/internal/testdata/unknown_value_type.yaml +++ b/cmd/mdatagen/internal/testdata/unknown_value_type.yaml @@ -11,8 +11,7 @@ metrics: system.cpu.time: enabled: true description: Total CPU seconds broken down by different states. - stability: - level: development + stability: development unit: s sum: value_type: unknown diff --git a/cmd/mdatagen/internal/testdata/unused_attribute.yaml b/cmd/mdatagen/internal/testdata/unused_attribute.yaml index 4d07147fa10d..a7daa3dd2c3c 100644 --- a/cmd/mdatagen/internal/testdata/unused_attribute.yaml +++ b/cmd/mdatagen/internal/testdata/unused_attribute.yaml @@ -26,8 +26,7 @@ metrics: metric: enabled: true description: Metric. - stability: - level: development + stability: development unit: "1" gauge: value_type: double @@ -38,9 +37,8 @@ telemetry: metric: enabled: true description: Metric. - stability: - level: development + stability: development unit: "1" gauge: value_type: double - attributes: [used_attr_in_telemetry_section] \ No newline at end of file + attributes: [used_attr_in_telemetry_section] diff --git a/cmd/mdatagen/internal/testdata/with_conditional_attribute.yaml b/cmd/mdatagen/internal/testdata/with_conditional_attribute.yaml index d3f4af8e07d3..0246020710d9 100644 --- a/cmd/mdatagen/internal/testdata/with_conditional_attribute.yaml +++ b/cmd/mdatagen/internal/testdata/with_conditional_attribute.yaml @@ -12,7 +12,7 @@ attributes: description: Conditional int attr. type: string requirement_level: conditionally_required - + opt_in_string_attr: description: Opt-in string attr. type: string @@ -22,8 +22,7 @@ metrics: metric: enabled: true description: Metric. - stability: - level: development + stability: development unit: "1" gauge: value_type: double diff --git a/cmd/mdatagen/internal/testdata/with_config.yaml b/cmd/mdatagen/internal/testdata/with_config.yaml new file mode 100644 index 000000000000..176fd3c8165e --- /dev/null +++ b/cmd/mdatagen/internal/testdata/with_config.yaml @@ -0,0 +1,25 @@ +type: receiver + +status: + class: receiver + stability: + beta: [logs] + distributions: [contrib] + +config: + type: object + properties: + endpoint: + description: The endpoint to connect to. + type: string + default: "localhost:4317" + timeout: + description: Timeout for requests. + type: string + format: duration + default: 10s + required: [endpoint] + +tests: + skip_lifecycle: true + skip_shutdown: true diff --git a/cmd/mdatagen/internal/testdata/with_description.yaml b/cmd/mdatagen/internal/testdata/with_description.yaml new file mode 100644 index 000000000000..7182bc4e9fa6 --- /dev/null +++ b/cmd/mdatagen/internal/testdata/with_description.yaml @@ -0,0 +1,8 @@ +type: testdesc +display_name: Test Component +description: This is a test component with a description. + +status: + class: receiver + stability: + beta: [logs] diff --git a/cmd/mdatagen/internal/testdata/with_invalid_config_ref.yaml b/cmd/mdatagen/internal/testdata/with_invalid_config_ref.yaml new file mode 100644 index 000000000000..71959786e185 --- /dev/null +++ b/cmd/mdatagen/internal/testdata/with_invalid_config_ref.yaml @@ -0,0 +1,19 @@ +type: receiver + +status: + class: receiver + stability: + beta: [logs] + distributions: [contrib] + +# config has a local $ref without a definition name, which passes LoadMetadata +# validation but causes generateConfigFiles to return an error during schema resolution. +config: + type: object + properties: + sub: + $ref: "/config/configauth" + +tests: + skip_lifecycle: true + skip_shutdown: true diff --git a/cmd/mdatagen/internal/testdata/with_stability_from.yaml b/cmd/mdatagen/internal/testdata/with_stability_from.yaml new file mode 100644 index 000000000000..fff097644ae8 --- /dev/null +++ b/cmd/mdatagen/internal/testdata/with_stability_from.yaml @@ -0,0 +1,18 @@ +type: test +status: + class: receiver + stability: + Beta: [metrics] +metrics: + test.metric: + enabled: true + description: Test metric with stability from field + unit: "1" + stability: + level: beta + from: "1.0.0" + sum: + value_type: int + aggregation_temporality: cumulative + monotonic: true + diff --git a/cmd/mdatagen/internal/testdata/with_telemetry.yaml b/cmd/mdatagen/internal/testdata/with_telemetry.yaml index 6d203ac98751..212511683d91 100644 --- a/cmd/mdatagen/internal/testdata/with_telemetry.yaml +++ b/cmd/mdatagen/internal/testdata/with_telemetry.yaml @@ -14,8 +14,7 @@ telemetry: description: Latency (in microseconds) of a given sampling policy unit: µs enabled: true - stability: - level: alpha + stability: alpha histogram: value_type: int attributes: [name] diff --git a/cmd/mdatagen/internal/testdata/with_tests_profiles_connector.yaml b/cmd/mdatagen/internal/testdata/with_tests_profiles_connector.yaml new file mode 100644 index 000000000000..45e281acba7b --- /dev/null +++ b/cmd/mdatagen/internal/testdata/with_tests_profiles_connector.yaml @@ -0,0 +1,7 @@ +type: foobar + +status: + disable_codecov_badge: true + class: connector + stability: + beta: [traces_to_profiles, metrics_to_profiles, logs_to_profiles, profiles_to_traces, profiles_to_metrics, profiles_to_logs, profiles_to_profiles] diff --git a/cmd/mdatagen/internal/testdata/with_underscore_in_semconv_ref_anchor_tag.yaml b/cmd/mdatagen/internal/testdata/with_underscore_in_semconv_ref_anchor_tag.yaml new file mode 100644 index 000000000000..df19b0a5e127 --- /dev/null +++ b/cmd/mdatagen/internal/testdata/with_underscore_in_semconv_ref_anchor_tag.yaml @@ -0,0 +1,27 @@ +type: metricreceiver + +status: + class: receiver + stability: + development: [logs] + beta: [traces] + stable: [metrics] + distributions: [contrib] + warnings: + - Any additional information that should be brought to the consumer's attention + +sem_conv_version: 1.38.0 + +metrics: + system.disk.io_time: + enabled: true + description: Time disk spent activated.. + stability: development + semantic_convention: + ref: https://github.com/open-telemetry/semantic-conventions/blob/v1.38.0/docs/system/system-metrics.md#metric-systemdiskio_time + unit: s + sum: + value_type: double + monotonic: true + aggregation_temporality: cumulative + diff --git a/cmd/mdatagen/main.go b/cmd/mdatagen/main.go index 32bab21949d3..e3eb75b32991 100644 --- a/cmd/mdatagen/main.go +++ b/cmd/mdatagen/main.go @@ -6,6 +6,8 @@ package main //go:generate mdatagen metadata.yaml import ( + "os" + "github.com/spf13/cobra" "go.opentelemetry.io/collector/cmd/mdatagen/internal" @@ -14,5 +16,8 @@ import ( func main() { cmd, err := internal.NewCommand() cobra.CheckErr(err) - cobra.CheckErr(cmd.Execute()) + + if err := cmd.Execute(); err != nil { + os.Exit(1) + } } diff --git a/cmd/mdatagen/metadata-schema.yaml b/cmd/mdatagen/metadata-schema.yaml index e11880d26b35..6c1d0340f385 100644 --- a/cmd/mdatagen/metadata-schema.yaml +++ b/cmd/mdatagen/metadata-schema.yaml @@ -1,6 +1,15 @@ # Required: The type of the component - Usually the name. The type and class combined uniquely identify the component (eg. receiver/otlp) or subcomponent (eg. receiver/hostmetricsreceiver/cpu) type: +# Optional: A deprecated type that is still available as an alias. +deprecated_type: string + +# Optional: Human-readable display name for the component. Used as the title in generated README files. +display_name: string + +# Optional: Brief description of the component that will be included in the generated README. +description: string + # Required for subcomponents: The type of the parent component. parent: string @@ -41,6 +50,100 @@ status: # This attribute should be set for metrics compliant with OTel Semantic Conventions. sem_conv_version: 1.9.0 +# Optional: JSON Schema based definition for the component's configuration structure. +# This section defines the schema that could be used to generate: +# - JSON Schema files that can be used for validation and documentation. (current) +# - Go structs representing the configuration with appropriate types and validation tags. (future) +# - Configuration reference documentation in the generated README files. (future) +config: + # Optional: Description of the configuration schema. + description: string + # Optional: Additional comments for developers (not included in JSON output). + $comment: string + # Required: The type of the configuration object. Typically "object" for component configs. + type: + # Optional: Map of configuration properties that define the component's configuration fields. + properties: + : + # Optional: Description of this configuration property. + description: string + # Optional: The JSON Schema type of this property. + type: + # Optional: Reference to another schema definition. Can be: + # - Internal reference: name of a type in $defs (e.g., "endpoint_config") + # - External reference: full package path with type (e.g., "go.opentelemetry.io/collector/config/confighttp.client_config") + # - Relative reference: local path (e.g., "./internal/metadata.config") + $ref: string + # Optional: Default value for this property if not specified. + default: any + # Optional: Example values for this property. + examples: [any] + # Optional: Indicates if this property is deprecated. + deprecated: bool + # Optional: For string types - allowed values. + enum: [string] + # Optional: Constant value - property must have exactly this value. + const: any + # Optional: For string types - regular expression pattern that the value must match. + pattern: string + # Optional: For string types - format specification (e.g., "uri", "email", "date-time", "duration"). + format: string + # Optional: For string types - minimum length. + minLength: int + # Optional: For string types - maximum length. + maxLength: int + # Optional: For number/integer types - minimum value (inclusive). + minimum: number + # Optional: For number/integer types - maximum value (inclusive). + maximum: number + # Optional: For number/integer types - exclusive minimum value. + exclusiveMinimum: number + # Optional: For number/integer types - exclusive maximum value. + exclusiveMaximum: number + # Optional: For number types - value must be a multiple of this number. + multipleOf: number + # Optional: For object types - properties of the nested object. + properties: {} # Recursively follows same structure + # Optional: For object types - whether additional properties beyond those defined are allowed. + # Can be true, false, or an object schema defining the type of additional properties. + additionalProperties: + # Optional: For object types - minimum number of properties required. + minProperties: int + # Optional: For object types - maximum number of properties allowed. + maxProperties: int + # Optional: For array types - schema for array items. + items: + # Same structure as property definition + type: string + # ... other item properties + # Optional: For array types - minimum number of items. + minItems: int + # Optional: For array types - maximum number of items. + maxItems: int + # Optional: For array types - whether all items must be unique. + uniqueItems: bool + # Optional: All of these schemas must be satisfied (schema composition). + allOf: + - type: object + properties: {} + # Custom extension fields (not part of JSON Schema standard, used by mdatagen): + # Optional: Custom Go type name to use instead of generated type. + x-customType: string + # Optional: Whether this field should be a pointer in Go code. + x-pointer: bool + # Optional: Whether this field is optional in Go code (will use pointer or optional type). + x-optional: bool + # Optional: List of required property names. Properties in this list must be present in the config. + required: [string] + # Optional: Map of reusable schema definitions that can be referenced via $ref. + # These definitions are not directly part of the config but can be reused multiple times. + $defs: + : + # Same structure as property definition + type: object + properties: {} + # ... other schema properties + # Optional: map of resource attribute definitions with the key being the attribute name. resource_attributes: : @@ -81,6 +184,16 @@ entities: # All referenced attributes must be defined in the resource_attributes section. description: - ref: string + # Optional: array of relationships to other entities. Relationships should be defined on only + # one end to avoid bidirectional definitions. It is recommended to define relationships on + # entities with lower lifespan (higher churn). For example, a pod should define its relationship + # to a replicaset, rather than the replicaset defining its relationship to pods. + relationships: + - # Required: the type of the relationship (e.g., "controlled_by", "parent", "peer"). + type: string + # Required: the target entity type this entity relates to. Must reference an entity + # defined in the same metadata.yaml file. + target: string # Optional: map of attribute definitions with the key being the attribute name and value # being described below. @@ -139,12 +252,18 @@ metrics: input_type: string # Optional: array of attributes that were defined in the attributes section that are emitted by this metric. attributes: [string] + # Optional: the entity type this metric is associated with. + # Required when entities are defined in the entities section. + # Must reference an entity type defined in the entities section. + entity: string # Required: the metric stability - stability: - # Required: the level of stability - level: - # Optional: the version current stability was introduced - from: + stability: + # Deprecation information for the metric. Required when stability is `deprecated`. + deprecated: + # Required: version when the metric was deprecated + since: + # Required: migration note + note: # Optional: the reference to a semantic convention semantic_convention: ref: @@ -170,6 +289,10 @@ events: if_configured: # Optional: array of attributes that were defined in the attributes section that are emitted by this event. attributes: [string] + # Optional: the entity type this event is associated with. + # Required when entities are defined in the entities section. + # Must reference an entity type defined in the entities section. + entity: string # Lifecycle tests generated for this component. tests: @@ -198,8 +321,18 @@ telemetry: enabled: bool # Required: metric description. description: - # Optional: the stability level of the metric. Set to alpha by default. - stability: [alpha|stable|deprecated] + # Optional: the stability of the metric. Set to alpha by default. + stability: + # Optional: the stability level of the metric. Set to alpha by default. + level: [alpha|stable|deprecated] + # Optional: the version current stability was introduced + from: + # Deprecation information for the metric. Required when stability is `deprecated`. + deprecated: + # Required: version when the metric was deprecated + since: + # Required: migration note + note: # Optional: extended documentation of the metric. extended_documentation: # Optional: whether or not this metric is optional. Optional metrics may only be initialized @@ -232,3 +365,18 @@ telemetry: # Optional: array of attributes that were defined in the attributes section that are emitted by this metric. # Note: Only the following attribute types are supported: attributes: [string] + +# Optional: list of feature gate definitions. +feature_gates: + - # Required: unique identifier for the feature gate. + id: + # Required: description of the feature gate. + description: string + # Required: lifecycle stage of the feature gate. + stage: + # Required: version when the feature gate was introduced. + from_version: string + # Required for stable/deprecated gates: version when the feature gate reached stable stage. + to_version: string + # Required: URL with contextual information about the feature gate. + reference_url: string diff --git a/cmd/otelcorecol/builder-config.yaml b/cmd/otelcorecol/builder-config.yaml index ce7c26a41cc9..8b54dc8404fa 100644 --- a/cmd/otelcorecol/builder-config.yaml +++ b/cmd/otelcorecol/builder-config.yaml @@ -10,31 +10,35 @@ dist: module: go.opentelemetry.io/collector/cmd/otelcorecol name: otelcorecol description: Local OpenTelemetry Collector binary, testing only. - version: 0.140.0-dev + version: 0.148.0-dev receivers: - - gomod: go.opentelemetry.io/collector/receiver/nopreceiver v0.140.0 - - gomod: go.opentelemetry.io/collector/receiver/otlpreceiver v0.140.0 + - gomod: go.opentelemetry.io/collector/receiver/nopreceiver v0.148.0 + - gomod: go.opentelemetry.io/collector/receiver/otlpreceiver v0.148.0 exporters: - - gomod: go.opentelemetry.io/collector/exporter/debugexporter v0.140.0 - - gomod: go.opentelemetry.io/collector/exporter/nopexporter v0.140.0 - - gomod: go.opentelemetry.io/collector/exporter/otlpexporter v0.140.0 - - gomod: go.opentelemetry.io/collector/exporter/otlphttpexporter v0.140.0 + - gomod: go.opentelemetry.io/collector/exporter/debugexporter v0.148.0 + - gomod: go.opentelemetry.io/collector/exporter/nopexporter v0.148.0 + - gomod: go.opentelemetry.io/collector/exporter/otlpexporter v0.148.0 + - gomod: go.opentelemetry.io/collector/exporter/otlphttpexporter v0.148.0 extensions: - - gomod: go.opentelemetry.io/collector/extension/memorylimiterextension v0.140.0 - - gomod: go.opentelemetry.io/collector/extension/zpagesextension v0.140.0 + - gomod: go.opentelemetry.io/collector/extension/memorylimiterextension v0.148.0 + - gomod: go.opentelemetry.io/collector/extension/zpagesextension v0.148.0 processors: - - gomod: go.opentelemetry.io/collector/processor/batchprocessor v0.140.0 - - gomod: go.opentelemetry.io/collector/processor/memorylimiterprocessor v0.140.0 + - gomod: go.opentelemetry.io/collector/processor/batchprocessor v0.148.0 + - gomod: go.opentelemetry.io/collector/processor/memorylimiterprocessor v0.148.0 connectors: - - gomod: go.opentelemetry.io/collector/connector/forwardconnector v0.140.0 + - gomod: go.opentelemetry.io/collector/connector/forwardconnector v0.148.0 providers: - - gomod: go.opentelemetry.io/collector/confmap/provider/envprovider v1.46.0 - - gomod: go.opentelemetry.io/collector/confmap/provider/fileprovider v1.46.0 - - gomod: go.opentelemetry.io/collector/confmap/provider/httpprovider v1.46.0 - - gomod: go.opentelemetry.io/collector/confmap/provider/httpsprovider v1.46.0 - - gomod: go.opentelemetry.io/collector/confmap/provider/yamlprovider v1.46.0 + - gomod: go.opentelemetry.io/collector/confmap/provider/envprovider v1.54.0 + - gomod: go.opentelemetry.io/collector/confmap/provider/fileprovider v1.54.0 + - gomod: go.opentelemetry.io/collector/confmap/provider/httpprovider v1.54.0 + - gomod: go.opentelemetry.io/collector/confmap/provider/httpsprovider v1.54.0 + - gomod: go.opentelemetry.io/collector/confmap/provider/yamlprovider v1.54.0 + +telemetry: + gomod: go.opentelemetry.io/collector/service v0.148.0 + import: go.opentelemetry.io/collector/service/telemetry/otelconftelemetry replaces: - go.opentelemetry.io/collector => ../../ @@ -89,6 +93,7 @@ replaces: - go.opentelemetry.io/collector/extension/xextension => ../../extension/xextension - go.opentelemetry.io/collector/extension/zpagesextension => ../../extension/zpagesextension - go.opentelemetry.io/collector/featuregate => ../../featuregate + - go.opentelemetry.io/collector/internal/componentalias => ../../internal/componentalias - go.opentelemetry.io/collector/internal/memorylimiter => ../../internal/memorylimiter - go.opentelemetry.io/collector/internal/fanoutconsumer => ../../internal/fanoutconsumer - go.opentelemetry.io/collector/internal/telemetry => ../../internal/telemetry diff --git a/cmd/otelcorecol/components.go b/cmd/otelcorecol/components.go index 0e1698461442..4ffd939b8f11 100644 --- a/cmd/otelcorecol/components.go +++ b/cmd/otelcorecol/components.go @@ -21,9 +21,23 @@ import ( "go.opentelemetry.io/collector/receiver" nopreceiver "go.opentelemetry.io/collector/receiver/nopreceiver" otlpreceiver "go.opentelemetry.io/collector/receiver/otlpreceiver" - "go.opentelemetry.io/collector/service/telemetry/otelconftelemetry" + otelconftelemetry "go.opentelemetry.io/collector/service/telemetry/otelconftelemetry" ) +type aliasProvider interface{ DeprecatedAlias() component.Type } + +func makeModulesMap[T component.Factory](factories map[component.Type]T, modules map[component.Type]string) map[component.Type]string { + for compType, factory := range factories { + if ap, ok := any(factory).(aliasProvider); ok { + alias := ap.DeprecatedAlias() + if alias.String() != "" { + modules[alias] = modules[compType] + } + } + } + return modules +} + func components() (otelcol.Factories, error) { var err error factories := otelcol.Factories{ @@ -37,9 +51,10 @@ func components() (otelcol.Factories, error) { if err != nil { return otelcol.Factories{}, err } - factories.ExtensionModules = make(map[component.Type]string, len(factories.Extensions)) - factories.ExtensionModules[memorylimiterextension.NewFactory().Type()] = "go.opentelemetry.io/collector/extension/memorylimiterextension v0.140.0" - factories.ExtensionModules[zpagesextension.NewFactory().Type()] = "go.opentelemetry.io/collector/extension/zpagesextension v0.140.0" + factories.ExtensionModules = makeModulesMap(factories.Extensions, map[component.Type]string{ + memorylimiterextension.NewFactory().Type(): "go.opentelemetry.io/collector/extension/memorylimiterextension v0.148.0", + zpagesextension.NewFactory().Type(): "go.opentelemetry.io/collector/extension/zpagesextension v0.148.0", + }) factories.Receivers, err = otelcol.MakeFactoryMap[receiver.Factory]( nopreceiver.NewFactory(), @@ -48,9 +63,10 @@ func components() (otelcol.Factories, error) { if err != nil { return otelcol.Factories{}, err } - factories.ReceiverModules = make(map[component.Type]string, len(factories.Receivers)) - factories.ReceiverModules[nopreceiver.NewFactory().Type()] = "go.opentelemetry.io/collector/receiver/nopreceiver v0.140.0" - factories.ReceiverModules[otlpreceiver.NewFactory().Type()] = "go.opentelemetry.io/collector/receiver/otlpreceiver v0.140.0" + factories.ReceiverModules = makeModulesMap(factories.Receivers, map[component.Type]string{ + nopreceiver.NewFactory().Type(): "go.opentelemetry.io/collector/receiver/nopreceiver v0.148.0", + otlpreceiver.NewFactory().Type(): "go.opentelemetry.io/collector/receiver/otlpreceiver v0.148.0", + }) factories.Exporters, err = otelcol.MakeFactoryMap[exporter.Factory]( debugexporter.NewFactory(), @@ -61,11 +77,12 @@ func components() (otelcol.Factories, error) { if err != nil { return otelcol.Factories{}, err } - factories.ExporterModules = make(map[component.Type]string, len(factories.Exporters)) - factories.ExporterModules[debugexporter.NewFactory().Type()] = "go.opentelemetry.io/collector/exporter/debugexporter v0.140.0" - factories.ExporterModules[nopexporter.NewFactory().Type()] = "go.opentelemetry.io/collector/exporter/nopexporter v0.140.0" - factories.ExporterModules[otlpexporter.NewFactory().Type()] = "go.opentelemetry.io/collector/exporter/otlpexporter v0.140.0" - factories.ExporterModules[otlphttpexporter.NewFactory().Type()] = "go.opentelemetry.io/collector/exporter/otlphttpexporter v0.140.0" + factories.ExporterModules = makeModulesMap(factories.Exporters, map[component.Type]string{ + debugexporter.NewFactory().Type(): "go.opentelemetry.io/collector/exporter/debugexporter v0.148.0", + nopexporter.NewFactory().Type(): "go.opentelemetry.io/collector/exporter/nopexporter v0.148.0", + otlpexporter.NewFactory().Type(): "go.opentelemetry.io/collector/exporter/otlpexporter v0.148.0", + otlphttpexporter.NewFactory().Type(): "go.opentelemetry.io/collector/exporter/otlphttpexporter v0.148.0", + }) factories.Processors, err = otelcol.MakeFactoryMap[processor.Factory]( batchprocessor.NewFactory(), @@ -74,9 +91,10 @@ func components() (otelcol.Factories, error) { if err != nil { return otelcol.Factories{}, err } - factories.ProcessorModules = make(map[component.Type]string, len(factories.Processors)) - factories.ProcessorModules[batchprocessor.NewFactory().Type()] = "go.opentelemetry.io/collector/processor/batchprocessor v0.140.0" - factories.ProcessorModules[memorylimiterprocessor.NewFactory().Type()] = "go.opentelemetry.io/collector/processor/memorylimiterprocessor v0.140.0" + factories.ProcessorModules = makeModulesMap(factories.Processors, map[component.Type]string{ + batchprocessor.NewFactory().Type(): "go.opentelemetry.io/collector/processor/batchprocessor v0.148.0", + memorylimiterprocessor.NewFactory().Type(): "go.opentelemetry.io/collector/processor/memorylimiterprocessor v0.148.0", + }) factories.Connectors, err = otelcol.MakeFactoryMap[connector.Factory]( forwardconnector.NewFactory(), @@ -84,8 +102,9 @@ func components() (otelcol.Factories, error) { if err != nil { return otelcol.Factories{}, err } - factories.ConnectorModules = make(map[component.Type]string, len(factories.Connectors)) - factories.ConnectorModules[forwardconnector.NewFactory().Type()] = "go.opentelemetry.io/collector/connector/forwardconnector v0.140.0" + factories.ConnectorModules = makeModulesMap(factories.Connectors, map[component.Type]string{ + forwardconnector.NewFactory().Type(): "go.opentelemetry.io/collector/connector/forwardconnector v0.148.0", + }) return factories, nil } diff --git a/cmd/otelcorecol/go.mod b/cmd/otelcorecol/go.mod index 32f2dab9dfdc..5a7a756e0be0 100644 --- a/cmd/otelcorecol/go.mod +++ b/cmd/otelcorecol/go.mod @@ -2,176 +2,177 @@ module go.opentelemetry.io/collector/cmd/otelcorecol -go 1.24.0 +go 1.25.0 require ( - go.opentelemetry.io/collector/component v1.46.0 - go.opentelemetry.io/collector/confmap v1.46.0 - go.opentelemetry.io/collector/confmap/provider/envprovider v1.46.0 - go.opentelemetry.io/collector/confmap/provider/fileprovider v1.46.0 - go.opentelemetry.io/collector/confmap/provider/httpprovider v1.46.0 - go.opentelemetry.io/collector/confmap/provider/httpsprovider v1.46.0 - go.opentelemetry.io/collector/confmap/provider/yamlprovider v1.46.0 - go.opentelemetry.io/collector/connector v0.140.0 - go.opentelemetry.io/collector/connector/forwardconnector v0.140.0 - go.opentelemetry.io/collector/exporter v1.46.0 - go.opentelemetry.io/collector/exporter/debugexporter v0.140.0 - go.opentelemetry.io/collector/exporter/nopexporter v0.140.0 - go.opentelemetry.io/collector/exporter/otlpexporter v0.140.0 - go.opentelemetry.io/collector/exporter/otlphttpexporter v0.140.0 - go.opentelemetry.io/collector/extension v1.46.0 - go.opentelemetry.io/collector/extension/memorylimiterextension v0.140.0 - go.opentelemetry.io/collector/extension/zpagesextension v0.140.0 - go.opentelemetry.io/collector/otelcol v0.140.0 - go.opentelemetry.io/collector/processor v1.46.0 - go.opentelemetry.io/collector/processor/batchprocessor v0.140.0 - go.opentelemetry.io/collector/processor/memorylimiterprocessor v0.140.0 - go.opentelemetry.io/collector/receiver v1.46.0 - go.opentelemetry.io/collector/receiver/nopreceiver v0.140.0 - go.opentelemetry.io/collector/receiver/otlpreceiver v0.140.0 - go.opentelemetry.io/collector/service v0.140.0 - golang.org/x/sys v0.40.0 + go.opentelemetry.io/collector/component v1.54.0 + go.opentelemetry.io/collector/confmap v1.54.0 + go.opentelemetry.io/collector/confmap/provider/envprovider v1.54.0 + go.opentelemetry.io/collector/confmap/provider/fileprovider v1.54.0 + go.opentelemetry.io/collector/confmap/provider/httpprovider v1.54.0 + go.opentelemetry.io/collector/confmap/provider/httpsprovider v1.54.0 + go.opentelemetry.io/collector/confmap/provider/yamlprovider v1.54.0 + go.opentelemetry.io/collector/connector v0.148.0 + go.opentelemetry.io/collector/connector/forwardconnector v0.148.0 + go.opentelemetry.io/collector/exporter v1.54.0 + go.opentelemetry.io/collector/exporter/debugexporter v0.148.0 + go.opentelemetry.io/collector/exporter/nopexporter v0.148.0 + go.opentelemetry.io/collector/exporter/otlpexporter v0.148.0 + go.opentelemetry.io/collector/exporter/otlphttpexporter v0.148.0 + go.opentelemetry.io/collector/extension v1.54.0 + go.opentelemetry.io/collector/extension/memorylimiterextension v0.148.0 + go.opentelemetry.io/collector/extension/zpagesextension v0.148.0 + go.opentelemetry.io/collector/otelcol v0.148.0 + go.opentelemetry.io/collector/processor v1.54.0 + go.opentelemetry.io/collector/processor/batchprocessor v0.148.0 + go.opentelemetry.io/collector/processor/memorylimiterprocessor v0.148.0 + go.opentelemetry.io/collector/receiver v1.54.0 + go.opentelemetry.io/collector/receiver/nopreceiver v0.148.0 + go.opentelemetry.io/collector/receiver/otlpreceiver v0.148.0 + go.opentelemetry.io/collector/service v0.148.0 + golang.org/x/sys v0.41.0 ) require ( github.com/beorn7/perks v1.0.1 // indirect github.com/cenkalti/backoff/v5 v5.0.3 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect - github.com/davecgh/go-spew v1.1.1 // indirect - github.com/ebitengine/purego v0.9.0 // indirect + github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect + github.com/ebitengine/purego v0.10.0 // indirect github.com/felixge/httpsnoop v1.0.4 // indirect - github.com/foxboron/go-tpm-keyfiles v0.0.0-20250903184740-5d135037bd4d // indirect + github.com/foxboron/go-tpm-keyfiles v0.0.0-20251226215517-609e4778396f // indirect github.com/fsnotify/fsnotify v1.9.0 // indirect github.com/go-logr/logr v1.4.3 // indirect github.com/go-logr/stdr v1.2.2 // indirect github.com/go-ole/go-ole v1.2.6 // indirect - github.com/go-viper/mapstructure/v2 v2.4.0 // indirect + github.com/go-viper/mapstructure/v2 v2.5.0 // indirect github.com/gobwas/glob v0.2.3 // indirect github.com/golang/snappy v1.0.0 // indirect - github.com/google/go-tpm v0.9.7 // indirect + github.com/google/go-tpm v0.9.8 // indirect github.com/google/uuid v1.6.0 // indirect - github.com/grafana/regexp v0.0.0-20240518133315-a468a5bfb3bc // indirect - github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.2 // indirect - github.com/hashicorp/go-version v1.7.0 // indirect + github.com/grpc-ecosystem/grpc-gateway/v2 v2.28.0 // indirect + github.com/hashicorp/go-version v1.8.0 // indirect + github.com/hashicorp/golang-lru/v2 v2.0.7 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/json-iterator/go v1.1.12 // indirect - github.com/klauspost/compress v1.18.1 // indirect + github.com/klauspost/compress v1.18.4 // indirect github.com/knadh/koanf/maps v0.1.2 // indirect github.com/knadh/koanf/providers/confmap v1.0.0 // indirect - github.com/knadh/koanf/v2 v2.3.0 // indirect - github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 // indirect + github.com/knadh/koanf/v2 v2.3.3 // indirect + github.com/lufia/plan9stats v0.0.0-20251013123823-9fd1530e3ec3 // indirect github.com/mitchellh/copystructure v1.2.0 // indirect github.com/mitchellh/reflectwalk v1.0.2 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee // indirect github.com/mostynb/go-grpc-compression v1.2.3 // indirect github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect - github.com/pierrec/lz4/v4 v4.1.22 // indirect - github.com/pmezard/go-difflib v1.0.0 // indirect + github.com/pierrec/lz4/v4 v4.1.26 // indirect + github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect github.com/power-devops/perfstat v0.0.0-20240221224432-82ca36839d55 // indirect github.com/prometheus/client_golang v1.23.2 // indirect github.com/prometheus/client_model v0.6.2 // indirect - github.com/prometheus/common v0.67.1 // indirect - github.com/prometheus/otlptranslator v0.0.2 // indirect - github.com/prometheus/procfs v0.17.0 // indirect + github.com/prometheus/common v0.67.5 // indirect + github.com/prometheus/otlptranslator v1.0.0 // indirect + github.com/prometheus/procfs v0.20.1 // indirect github.com/rs/cors v1.11.1 // indirect - github.com/shirou/gopsutil/v4 v4.25.10 // indirect - github.com/spf13/cobra v1.10.1 // indirect - github.com/spf13/pflag v1.0.9 // indirect + github.com/shirou/gopsutil/v4 v4.26.2 // indirect + github.com/spf13/cobra v1.10.2 // indirect + github.com/spf13/pflag v1.0.10 // indirect github.com/stretchr/testify v1.11.1 // indirect - github.com/tklauser/go-sysconf v0.3.15 // indirect - github.com/tklauser/numcpus v0.10.0 // indirect + github.com/tklauser/go-sysconf v0.3.16 // indirect + github.com/tklauser/numcpus v0.11.0 // indirect github.com/yusufpapurcu/wmi v1.2.4 // indirect go.opentelemetry.io/auto/sdk v1.2.1 // indirect - go.opentelemetry.io/collector v0.140.0 // indirect - go.opentelemetry.io/collector/client v1.46.0 // indirect - go.opentelemetry.io/collector/component/componentstatus v0.140.0 // indirect - go.opentelemetry.io/collector/component/componenttest v0.140.0 // indirect - go.opentelemetry.io/collector/config/configauth v1.46.0 // indirect - go.opentelemetry.io/collector/config/configcompression v1.46.0 // indirect - go.opentelemetry.io/collector/config/configgrpc v0.140.0 // indirect - go.opentelemetry.io/collector/config/confighttp v0.140.0 // indirect - go.opentelemetry.io/collector/config/configmiddleware v1.46.0 // indirect + go.opentelemetry.io/collector v0.148.0 // indirect + go.opentelemetry.io/collector/client v1.54.0 // indirect + go.opentelemetry.io/collector/component/componentstatus v0.148.0 // indirect + go.opentelemetry.io/collector/component/componenttest v0.148.0 // indirect + go.opentelemetry.io/collector/config/configauth v1.54.0 // indirect + go.opentelemetry.io/collector/config/configcompression v1.54.0 // indirect + go.opentelemetry.io/collector/config/configgrpc v0.148.0 // indirect + go.opentelemetry.io/collector/config/confighttp v0.148.0 // indirect + go.opentelemetry.io/collector/config/configmiddleware v1.54.0 // indirect go.opentelemetry.io/collector/config/confignet v1.46.0 // indirect - go.opentelemetry.io/collector/config/configopaque v1.46.0 // indirect - go.opentelemetry.io/collector/config/configoptional v1.46.0 // indirect - go.opentelemetry.io/collector/config/configretry v1.46.0 // indirect - go.opentelemetry.io/collector/config/configtelemetry v0.140.0 // indirect - go.opentelemetry.io/collector/config/configtls v1.46.0 // indirect - go.opentelemetry.io/collector/confmap/xconfmap v0.140.0 // indirect - go.opentelemetry.io/collector/connector/connectortest v0.140.0 // indirect - go.opentelemetry.io/collector/connector/xconnector v0.140.0 // indirect - go.opentelemetry.io/collector/consumer v1.46.0 // indirect - go.opentelemetry.io/collector/consumer/consumererror v0.140.0 // indirect + go.opentelemetry.io/collector/config/configopaque v1.54.0 // indirect + go.opentelemetry.io/collector/config/configoptional v1.54.0 // indirect + go.opentelemetry.io/collector/config/configretry v1.54.0 // indirect + go.opentelemetry.io/collector/config/configtelemetry v0.148.0 // indirect + go.opentelemetry.io/collector/config/configtls v1.54.0 // indirect + go.opentelemetry.io/collector/confmap/xconfmap v0.148.0 // indirect + go.opentelemetry.io/collector/connector/connectortest v0.148.0 // indirect + go.opentelemetry.io/collector/connector/xconnector v0.148.0 // indirect + go.opentelemetry.io/collector/consumer v1.54.0 // indirect + go.opentelemetry.io/collector/consumer/consumererror v0.148.0 // indirect go.opentelemetry.io/collector/consumer/consumererror/xconsumererror v0.140.0 // indirect - go.opentelemetry.io/collector/consumer/consumertest v0.140.0 // indirect - go.opentelemetry.io/collector/consumer/xconsumer v0.140.0 // indirect - go.opentelemetry.io/collector/exporter/exporterhelper v0.140.0 // indirect - go.opentelemetry.io/collector/exporter/exporterhelper/xexporterhelper v0.140.0 // indirect - go.opentelemetry.io/collector/exporter/exportertest v0.140.0 // indirect - go.opentelemetry.io/collector/exporter/xexporter v0.140.0 // indirect - go.opentelemetry.io/collector/extension/extensionauth v1.46.0 // indirect + go.opentelemetry.io/collector/consumer/consumertest v0.148.0 // indirect + go.opentelemetry.io/collector/consumer/xconsumer v0.148.0 // indirect + go.opentelemetry.io/collector/exporter/exporterhelper v0.148.0 // indirect + go.opentelemetry.io/collector/exporter/exporterhelper/xexporterhelper v0.148.0 // indirect + go.opentelemetry.io/collector/exporter/exportertest v0.148.0 // indirect + go.opentelemetry.io/collector/exporter/xexporter v0.148.0 // indirect + go.opentelemetry.io/collector/extension/extensionauth v1.54.0 // indirect go.opentelemetry.io/collector/extension/extensioncapabilities v0.140.0 // indirect - go.opentelemetry.io/collector/extension/extensionmiddleware v0.140.0 // indirect - go.opentelemetry.io/collector/extension/extensiontest v0.140.0 // indirect + go.opentelemetry.io/collector/extension/extensionmiddleware v0.148.0 // indirect + go.opentelemetry.io/collector/extension/extensiontest v0.148.0 // indirect go.opentelemetry.io/collector/extension/xextension v0.140.0 // indirect - go.opentelemetry.io/collector/featuregate v1.46.0 // indirect - go.opentelemetry.io/collector/internal/fanoutconsumer v0.140.0 // indirect - go.opentelemetry.io/collector/internal/memorylimiter v0.140.0 // indirect + go.opentelemetry.io/collector/featuregate v1.54.0 // indirect + go.opentelemetry.io/collector/internal/componentalias v0.148.0 // indirect + go.opentelemetry.io/collector/internal/fanoutconsumer v0.148.0 // indirect + go.opentelemetry.io/collector/internal/memorylimiter v0.148.0 // indirect go.opentelemetry.io/collector/internal/sharedcomponent v0.140.0 // indirect go.opentelemetry.io/collector/internal/telemetry v0.140.0 // indirect - go.opentelemetry.io/collector/pdata v1.46.0 // indirect - go.opentelemetry.io/collector/pdata/pprofile v0.140.0 // indirect - go.opentelemetry.io/collector/pdata/testdata v0.140.0 // indirect - go.opentelemetry.io/collector/pdata/xpdata v0.140.0 // indirect - go.opentelemetry.io/collector/pipeline v1.46.0 // indirect - go.opentelemetry.io/collector/pipeline/xpipeline v0.140.0 // indirect - go.opentelemetry.io/collector/processor/processorhelper v0.140.0 // indirect + go.opentelemetry.io/collector/pdata v1.54.0 // indirect + go.opentelemetry.io/collector/pdata/pprofile v0.148.0 // indirect + go.opentelemetry.io/collector/pdata/testdata v0.148.0 // indirect + go.opentelemetry.io/collector/pdata/xpdata v0.148.0 // indirect + go.opentelemetry.io/collector/pipeline v1.54.0 // indirect + go.opentelemetry.io/collector/pipeline/xpipeline v0.148.0 // indirect + go.opentelemetry.io/collector/processor/processorhelper v0.148.0 // indirect go.opentelemetry.io/collector/processor/processorhelper/xprocessorhelper v0.140.0 // indirect - go.opentelemetry.io/collector/processor/processortest v0.140.0 // indirect - go.opentelemetry.io/collector/processor/xprocessor v0.140.0 // indirect + go.opentelemetry.io/collector/processor/processortest v0.148.0 // indirect + go.opentelemetry.io/collector/processor/xprocessor v0.148.0 // indirect go.opentelemetry.io/collector/receiver/receiverhelper v0.140.0 // indirect - go.opentelemetry.io/collector/receiver/receivertest v0.140.0 // indirect - go.opentelemetry.io/collector/receiver/xreceiver v0.140.0 // indirect + go.opentelemetry.io/collector/receiver/receivertest v0.148.0 // indirect + go.opentelemetry.io/collector/receiver/xreceiver v0.148.0 // indirect go.opentelemetry.io/collector/service/hostcapabilities v0.140.0 // indirect go.opentelemetry.io/contrib/bridges/otelzap v0.13.0 // indirect go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.63.0 // indirect - go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.63.0 // indirect + go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.67.0 // indirect go.opentelemetry.io/contrib/otelconf v0.18.0 // indirect go.opentelemetry.io/contrib/propagators/b3 v1.38.0 // indirect - go.opentelemetry.io/contrib/zpages v0.63.0 // indirect - go.opentelemetry.io/otel v1.40.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.14.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.14.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.38.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.38.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.38.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.38.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.38.0 // indirect - go.opentelemetry.io/otel/exporters/prometheus v0.60.0 // indirect - go.opentelemetry.io/otel/exporters/stdout/stdoutlog v0.14.0 // indirect - go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.38.0 // indirect - go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.38.0 // indirect - go.opentelemetry.io/otel/log v0.14.0 // indirect - go.opentelemetry.io/otel/metric v1.40.0 // indirect - go.opentelemetry.io/otel/sdk v1.40.0 // indirect - go.opentelemetry.io/otel/sdk/log v0.14.0 // indirect - go.opentelemetry.io/otel/sdk/metric v1.40.0 // indirect - go.opentelemetry.io/otel/trace v1.40.0 // indirect - go.opentelemetry.io/proto/otlp v1.7.1 // indirect + go.opentelemetry.io/contrib/zpages v0.67.0 // indirect + go.opentelemetry.io/otel v1.42.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.18.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.18.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.42.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.42.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.42.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.42.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.42.0 // indirect + go.opentelemetry.io/otel/exporters/prometheus v0.64.0 // indirect + go.opentelemetry.io/otel/exporters/stdout/stdoutlog v0.18.0 // indirect + go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.42.0 // indirect + go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.42.0 // indirect + go.opentelemetry.io/otel/log v0.18.0 // indirect + go.opentelemetry.io/otel/metric v1.42.0 // indirect + go.opentelemetry.io/otel/sdk v1.42.0 // indirect + go.opentelemetry.io/otel/sdk/log v0.18.0 // indirect + go.opentelemetry.io/otel/sdk/metric v1.42.0 // indirect + go.opentelemetry.io/otel/trace v1.42.0 // indirect + go.opentelemetry.io/proto/otlp v1.10.0 // indirect go.uber.org/multierr v1.11.0 // indirect go.uber.org/zap v1.27.1 // indirect go.yaml.in/yaml/v2 v2.4.3 // indirect go.yaml.in/yaml/v3 v3.0.4 // indirect - golang.org/x/crypto v0.45.0 // indirect + golang.org/x/crypto v0.48.0 // indirect golang.org/x/exp v0.0.0-20240506185415-9bf2ced13842 // indirect - golang.org/x/net v0.47.0 // indirect - golang.org/x/text v0.31.0 // indirect - gonum.org/v1/gonum v0.16.0 // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20251022142026-3a174f9686a8 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20251022142026-3a174f9686a8 // indirect - google.golang.org/grpc v1.77.0 // indirect - google.golang.org/protobuf v1.36.10 // indirect + golang.org/x/net v0.51.0 // indirect + golang.org/x/text v0.34.0 // indirect + gonum.org/v1/gonum v0.17.0 // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20260226221140-a57be14db171 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20260226221140-a57be14db171 // indirect + google.golang.org/grpc v1.79.3 // indirect + google.golang.org/protobuf v1.36.11 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) @@ -279,6 +280,8 @@ replace go.opentelemetry.io/collector/extension/zpagesextension => ../../extensi replace go.opentelemetry.io/collector/featuregate => ../../featuregate +replace go.opentelemetry.io/collector/internal/componentalias => ../../internal/componentalias + replace go.opentelemetry.io/collector/internal/memorylimiter => ../../internal/memorylimiter replace go.opentelemetry.io/collector/internal/fanoutconsumer => ../../internal/fanoutconsumer diff --git a/cmd/otelcorecol/go.sum b/cmd/otelcorecol/go.sum index 2b59e7837dd4..dc518c02cac8 100644 --- a/cmd/otelcorecol/go.sum +++ b/cmd/otelcorecol/go.sum @@ -6,16 +6,15 @@ github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UF github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/ebitengine/purego v0.9.0 h1:mh0zpKBIXDceC63hpvPuGLiJ8ZAa3DfrFTudmfi8A4k= -github.com/ebitengine/purego v0.9.0/go.mod h1:iIjxzd6CiRiOG0UyXP+V1+jWqUXVjPKLAI0mRfJZTmQ= +github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= +github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/ebitengine/purego v0.10.0 h1:QIw4xfpWT6GWTzaW5XEKy3HXoqrJGx1ijYHzTF0/ISU= +github.com/ebitengine/purego v0.10.0/go.mod h1:iIjxzd6CiRiOG0UyXP+V1+jWqUXVjPKLAI0mRfJZTmQ= github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg= github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= -github.com/foxboron/go-tpm-keyfiles v0.0.0-20250903184740-5d135037bd4d h1:EdO/NMMuCZfxhdzTZLuKAciQSnI2DV+Ppg8+vAYrnqA= -github.com/foxboron/go-tpm-keyfiles v0.0.0-20250903184740-5d135037bd4d/go.mod h1:uAyTlAUxchYuiFjTHmuIEJ4nGSm7iOPaGcAyA81fJ80= -github.com/foxboron/swtpm_test v0.0.0-20230726224112-46aaafdf7006 h1:50sW4r0PcvlpG4PV8tYh2RVCapszJgaOLRCS2subvV4= -github.com/foxboron/swtpm_test v0.0.0-20230726224112-46aaafdf7006/go.mod h1:eIXCMsMYCaqq9m1KSSxXwQG11krpuNPGP3k0uaWrbas= +github.com/foxboron/go-tpm-keyfiles v0.0.0-20251226215517-609e4778396f h1:RJ+BDPLSHQO7cSjKBqjPJSbi1qfk9WcsjQDtZiw3dZw= +github.com/foxboron/go-tpm-keyfiles v0.0.0-20251226215517-609e4778396f/go.mod h1:VHbbch/X4roIY22jL1s3qRbZhCiRIgUAF/PdSUcx2io= github.com/fsnotify/fsnotify v1.9.0 h1:2Ml+OJNzbYCTzsxtv8vKSFD9PbJjmhYF14k/jKC7S9k= github.com/fsnotify/fsnotify v1.9.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= @@ -25,50 +24,49 @@ github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY= github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0= -github.com/go-viper/mapstructure/v2 v2.4.0 h1:EBsztssimR/CONLSZZ04E8qAkxNYq4Qp9LvH92wZUgs= -github.com/go-viper/mapstructure/v2 v2.4.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM= +github.com/go-viper/mapstructure/v2 v2.5.0 h1:vM5IJoUAy3d7zRSVtIwQgBj7BiWtMPfmPEgAXnvj1Ro= +github.com/go-viper/mapstructure/v2 v2.5.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM= github.com/gobwas/glob v0.2.3 h1:A4xDbljILXROh+kObIiy5kIaPYD8e96x1tgBhUI5J+Y= github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8= github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= github.com/golang/snappy v1.0.0 h1:Oy607GVXHs7RtbggtPBnr2RmDArIsAefDwvrdWvRhGs= github.com/golang/snappy v1.0.0/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= -github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= -github.com/google/go-tpm v0.9.7 h1:u89J4tUUeDTlH8xxC3CTW7OHZjbjKoHdQ9W7gCUhtxA= -github.com/google/go-tpm v0.9.7/go.mod h1:h9jEsEECg7gtLis0upRBQU+GhYVH6jMjrFxI8u6bVUY= -github.com/google/go-tpm-tools v0.4.4 h1:oiQfAIkc6xTy9Fl5NKTeTJkBTlXdHsxAofmQyxBKY98= -github.com/google/go-tpm-tools v0.4.4/go.mod h1:T8jXkp2s+eltnCDIsXR84/MTcVU9Ja7bh3Mit0pa4AY= +github.com/google/go-tpm v0.9.8 h1:slArAR9Ft+1ybZu0lBwpSmpwhRXaa85hWtMinMyRAWo= +github.com/google/go-tpm v0.9.8/go.mod h1:h9jEsEECg7gtLis0upRBQU+GhYVH6jMjrFxI8u6bVUY= +github.com/google/go-tpm-tools v0.4.7 h1:J3ycC8umYxM9A4eF73EofRZu4BxY0jjQnUnkhIBbvws= +github.com/google/go-tpm-tools v0.4.7/go.mod h1:gSyXTZHe3fgbzb6WEGd90QucmsnT1SRdlye82gH8QjQ= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/grafana/regexp v0.0.0-20240518133315-a468a5bfb3bc h1:GN2Lv3MGO7AS6PrRoT6yV5+wkrOpcszoIsO4+4ds248= -github.com/grafana/regexp v0.0.0-20240518133315-a468a5bfb3bc/go.mod h1:+JKpmjMGhpgPL+rXZ5nsZieVzvarn86asRlBg4uNGnk= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.2 h1:8Tjv8EJ+pM1xP8mK6egEbD1OgnVTyacbefKhmbLhIhU= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.2/go.mod h1:pkJQ2tZHJ0aFOVEEot6oZmaVEZcRme73eIFmhiVuRWs= -github.com/hashicorp/go-version v1.7.0 h1:5tqGy27NaOTB8yJKUZELlFAS/LTKJkrmONwQKeRZfjY= -github.com/hashicorp/go-version v1.7.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.28.0 h1:HWRh5R2+9EifMyIHV7ZV+MIZqgz+PMpZ14Jynv3O2Zs= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.28.0/go.mod h1:JfhWUomR1baixubs02l85lZYYOm7LV6om4ceouMv45c= +github.com/hashicorp/go-version v1.8.0 h1:KAkNb1HAiZd1ukkxDFGmokVZe1Xy9HG6NUp+bPle2i4= +github.com/hashicorp/go-version v1.8.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= +github.com/hashicorp/golang-lru/v2 v2.0.7 h1:a+bsQ5rvGLjzHuww6tVxozPZFVghXaHOwFs4luLUK2k= +github.com/hashicorp/golang-lru/v2 v2.0.7/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyfM2/ZepoAG6RGpeM= github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= -github.com/klauspost/compress v1.18.1 h1:bcSGx7UbpBqMChDtsF28Lw6v/G94LPrrbMbdC3JH2co= -github.com/klauspost/compress v1.18.1/go.mod h1:ZQFFVG+MdnR0P+l6wpXgIL4NTtwiKIdBnrBd8Nrxr+0= +github.com/klauspost/compress v1.18.4 h1:RPhnKRAQ4Fh8zU2FY/6ZFDwTVTxgJ/EMydqSTzE9a2c= +github.com/klauspost/compress v1.18.4/go.mod h1:R0h/fSBs8DE4ENlcrlib3PsXS61voFxhIs2DeRhCvJ4= github.com/knadh/koanf/maps v0.1.2 h1:RBfmAW5CnZT+PJ1CVc1QSJKf4Xu9kxfQgYVQSu8hpbo= github.com/knadh/koanf/maps v0.1.2/go.mod h1:npD/QZY3V6ghQDdcQzl1W4ICNVTkohC8E73eI2xW4yI= github.com/knadh/koanf/providers/confmap v1.0.0 h1:mHKLJTE7iXEys6deO5p6olAiZdG5zwp8Aebir+/EaRE= github.com/knadh/koanf/providers/confmap v1.0.0/go.mod h1:txHYHiI2hAtF0/0sCmcuol4IDcuQbKTybiB1nOcUo1A= -github.com/knadh/koanf/v2 v2.3.0 h1:Qg076dDRFHvqnKG97ZEsi9TAg2/nFTa9hCdcSa1lvlM= -github.com/knadh/koanf/v2 v2.3.0/go.mod h1:gRb40VRAbd4iJMYYD5IxZ6hfuopFcXBpc9bbQpZwo28= +github.com/knadh/koanf/v2 v2.3.3 h1:jLJC8XCRfLC7n4F+ZKKdBsbq1bfXTpuFhf4L7t94D94= +github.com/knadh/koanf/v2 v2.3.3/go.mod h1:gRb40VRAbd4iJMYYD5IxZ6hfuopFcXBpc9bbQpZwo28= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc= github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= -github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 h1:6E+4a0GO5zZEnZ81pIr0yLvtUWk2if982qA3F3QD6H4= -github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0/go.mod h1:zJYVVT2jmtg6P3p1VtQj7WsuWi/y4VnjVBn7F8KPB3I= +github.com/lufia/plan9stats v0.0.0-20251013123823-9fd1530e3ec3 h1:PwQumkgq4/acIiZhtifTV5OUqqiP82UAl0h87xj/l9k= +github.com/lufia/plan9stats v0.0.0-20251013123823-9fd1530e3ec3/go.mod h1:autxFIvghDt3jPTLoqZ9OZ7s9qTGNAWmYCjVFWPX/zg= github.com/mitchellh/copystructure v1.2.0 h1:vpKXTN4ewci03Vljg/q9QvCGUDttBOGBIa15WveJJGw= github.com/mitchellh/copystructure v1.2.0/go.mod h1:qLl+cE2AmVv+CoeAwDPye/v+N2HKCj9FbZEVFJRxO9s= github.com/mitchellh/reflectwalk v1.0.2 h1:G2LzWKi524PWgd3mLHV8Y5k7s6XUvT0Gef6zxSIeXaQ= @@ -83,41 +81,43 @@ github.com/mostynb/go-grpc-compression v1.2.3 h1:42/BKWMy0KEJGSdWvzqIyOZ95YcR9mL github.com/mostynb/go-grpc-compression v1.2.3/go.mod h1:AghIxF3P57umzqM9yz795+y1Vjs47Km/Y2FE6ouQ7Lg= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= -github.com/pierrec/lz4/v4 v4.1.22 h1:cKFw6uJDK+/gfw5BcDL0JL5aBsAFdsIT18eRtLj7VIU= -github.com/pierrec/lz4/v4 v4.1.22/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4= -github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pierrec/lz4/v4 v4.1.26 h1:GrpZw1gZttORinvzBdXPUXATeqlJjqUG/D87TKMnhjY= +github.com/pierrec/lz4/v4 v4.1.26/go.mod h1:EoQMVJgeeEOMsCqCzqFm2O0cJvljX2nGZjcRIPL34O4= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= +github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/power-devops/perfstat v0.0.0-20240221224432-82ca36839d55 h1:o4JXh1EVt9k/+g42oCprj/FisM4qX9L3sZB3upGN2ZU= github.com/power-devops/perfstat v0.0.0-20240221224432-82ca36839d55/go.mod h1:OmDBASR4679mdNQnz2pUhc2G8CO2JrUAVFDRBDP/hJE= github.com/prometheus/client_golang v1.23.2 h1:Je96obch5RDVy3FDMndoUsjAhG5Edi49h0RJWRi/o0o= github.com/prometheus/client_golang v1.23.2/go.mod h1:Tb1a6LWHB3/SPIzCoaDXI4I8UHKeFTEQ1YCr+0Gyqmg= github.com/prometheus/client_model v0.6.2 h1:oBsgwpGs7iVziMvrGhE53c/GrLUsZdHnqNwqPLxwZyk= github.com/prometheus/client_model v0.6.2/go.mod h1:y3m2F6Gdpfy6Ut/GBsUqTWZqCUvMVzSfMLjcu6wAwpE= -github.com/prometheus/common v0.67.1 h1:OTSON1P4DNxzTg4hmKCc37o4ZAZDv0cfXLkOt0oEowI= -github.com/prometheus/common v0.67.1/go.mod h1:RpmT9v35q2Y+lsieQsdOh5sXZ6ajUGC8NjZAmr8vb0Q= -github.com/prometheus/otlptranslator v0.0.2 h1:+1CdeLVrRQ6Psmhnobldo0kTp96Rj80DRXRd5OSnMEQ= -github.com/prometheus/otlptranslator v0.0.2/go.mod h1:P8AwMgdD7XEr6QRUJ2QWLpiAZTgTE2UYgjlu3svompI= -github.com/prometheus/procfs v0.17.0 h1:FuLQ+05u4ZI+SS/w9+BWEM2TXiHKsUQ9TADiRH7DuK0= -github.com/prometheus/procfs v0.17.0/go.mod h1:oPQLaDAMRbA+u8H5Pbfq+dl3VDAvHxMUOVhe0wYB2zw= +github.com/prometheus/common v0.67.5 h1:pIgK94WWlQt1WLwAC5j2ynLaBRDiinoAb86HZHTUGI4= +github.com/prometheus/common v0.67.5/go.mod h1:SjE/0MzDEEAyrdr5Gqc6G+sXI67maCxzaT3A2+HqjUw= +github.com/prometheus/otlptranslator v1.0.0 h1:s0LJW/iN9dkIH+EnhiD3BlkkP5QVIUVEoIwkU+A6qos= +github.com/prometheus/otlptranslator v1.0.0/go.mod h1:vRYWnXvI6aWGpsdY/mOT/cbeVRBlPWtBNDb7kGR3uKM= +github.com/prometheus/procfs v0.20.1 h1:XwbrGOIplXW/AU3YhIhLODXMJYyC1isLFfYCsTEycfc= +github.com/prometheus/procfs v0.20.1/go.mod h1:o9EMBZGRyvDrSPH1RqdxhojkuXstoe4UlK79eF5TGGo= github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ= github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc= github.com/rs/cors v1.11.1 h1:eU3gRzXLRK57F5rKMGMZURNdIG4EoAmX8k94r9wXWHA= github.com/rs/cors v1.11.1/go.mod h1:XyqrcTp5zjWr1wsJ8PIRZssZ8b/WMcMf71DJnit4EMU= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= -github.com/shirou/gopsutil/v4 v4.25.10 h1:at8lk/5T1OgtuCp+AwrDofFRjnvosn0nkN2OLQ6g8tA= -github.com/shirou/gopsutil/v4 v4.25.10/go.mod h1:+kSwyC8DRUD9XXEHCAFjK+0nuArFJM0lva+StQAcskM= -github.com/spf13/cobra v1.10.1 h1:lJeBwCfmrnXthfAupyUTzJ/J4Nc1RsHC/mSRU2dll/s= -github.com/spf13/cobra v1.10.1/go.mod h1:7SmJGaTHFVBY0jW4NXGluQoLvhqFQM+6XSKD+P4XaB0= -github.com/spf13/pflag v1.0.9 h1:9exaQaMOCwffKiiiYk6/BndUBv+iRViNW+4lEMi0PvY= +github.com/shirou/gopsutil/v4 v4.26.2 h1:X8i6sicvUFih4BmYIGT1m2wwgw2VG9YgrDTi7cIRGUI= +github.com/shirou/gopsutil/v4 v4.26.2/go.mod h1:LZ6ewCSkBqUpvSOf+LsTGnRinC6iaNUNMGBtDkJBaLQ= +github.com/spf13/cobra v1.10.2 h1:DMTTonx5m65Ic0GOoRY2c16WCbHxOOw6xxezuLaBpcU= +github.com/spf13/cobra v1.10.2/go.mod h1:7C1pvHqHw5A4vrJfjNwvOdzYu0Gml16OCs2GRiTUUS4= github.com/spf13/pflag v1.0.9/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= +github.com/spf13/pflag v1.0.10 h1:4EBh2KAYBwaONj6b2Ye1GiHfwjqyROoF4RwYO+vPwFk= +github.com/spf13/pflag v1.0.10/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U= github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= -github.com/tklauser/go-sysconf v0.3.15 h1:VE89k0criAymJ/Os65CSn1IXaol+1wrsFHEB8Ol49K4= -github.com/tklauser/go-sysconf v0.3.15/go.mod h1:Dmjwr6tYFIseJw7a3dRLJfsHAMXZ3nEnL/aZY+0IuI4= -github.com/tklauser/numcpus v0.10.0 h1:18njr6LDBk1zuna922MgdjQuJFjrdppsZG60sHGfjso= -github.com/tklauser/numcpus v0.10.0/go.mod h1:BiTKazU708GQTYF4mB+cmlpT2Is1gLk7XVuEeem8LsQ= +github.com/tklauser/go-sysconf v0.3.16 h1:frioLaCQSsF5Cy1jgRBrzr6t502KIIwQ0MArYICU0nA= +github.com/tklauser/go-sysconf v0.3.16/go.mod h1:/qNL9xxDhc7tx3HSRsLWNnuzbVfh3e7gh/BmM179nYI= +github.com/tklauser/numcpus v0.11.0 h1:nSTwhKH5e1dMNsCdVBukSZrURJRoHbSEQjdEbY+9RXw= +github.com/tklauser/numcpus v0.11.0/go.mod h1:z+LwcLq54uWZTX0u/bGobaV34u6V7KNlTZejzM6/3MQ= github.com/yusufpapurcu/wmi v1.2.4 h1:zFUKzehAFReQwLys1b/iSMl+JQGSCSjtVqQn9bBrPo0= github.com/yusufpapurcu/wmi v1.2.4/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0= go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64= @@ -126,62 +126,62 @@ go.opentelemetry.io/contrib/bridges/otelzap v0.13.0 h1:aBKdhLVieqvwWe9A79UHI/0vg go.opentelemetry.io/contrib/bridges/otelzap v0.13.0/go.mod h1:SYqtxLQE7iINgh6WFuVi2AI70148B8EI35DSk0Wr8m4= go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.63.0 h1:YH4g8lQroajqUwWbq/tr2QX1JFmEXaDLgG+ew9bLMWo= go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.63.0/go.mod h1:fvPi2qXDqFs8M4B4fmJhE92TyQs9Ydjlg3RvfUp+NbQ= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.63.0 h1:RbKq8BG0FI8OiXhBfcRtqqHcZcka+gU3cskNuf05R18= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.63.0/go.mod h1:h06DGIukJOevXaj/xrNjhi/2098RZzcLTbc0jDAUbsg= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.67.0 h1:OyrsyzuttWTSur2qN/Lm0m2a8yqyIjUVBZcxFPuXq2o= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.67.0/go.mod h1:C2NGBr+kAB4bk3xtMXfZ94gqFDtg/GkI7e9zqGh5Beg= go.opentelemetry.io/contrib/otelconf v0.18.0 h1:ciF2Gf00BWs0DnexKFZXcxg9kJ8r3SUW1LOzW3CsKA8= go.opentelemetry.io/contrib/otelconf v0.18.0/go.mod h1:FcP7k+JLwBLdOxS6qY6VQ/4b5VBntI6L6o80IMwhAeI= go.opentelemetry.io/contrib/propagators/b3 v1.38.0 h1:uHsCCOSKl0kLrV2dLkFK+8Ywk9iKa/fptkytc6aFFEo= go.opentelemetry.io/contrib/propagators/b3 v1.38.0/go.mod h1:wMRSZJZcY8ya9mApLLhwIMjqmApy2o/Ml+62lhvxyHU= -go.opentelemetry.io/contrib/zpages v0.63.0 h1:TppOKuZGbqXMgsfjqq3i09N5Vbo1JLtLImUqiTPGnX4= -go.opentelemetry.io/contrib/zpages v0.63.0/go.mod h1:5F8uugz75ay/MMhRRhxAXY33FuaI8dl7jTxefrIy5qk= -go.opentelemetry.io/otel v1.40.0 h1:oA5YeOcpRTXq6NN7frwmwFR0Cn3RhTVZvXsP4duvCms= -go.opentelemetry.io/otel v1.40.0/go.mod h1:IMb+uXZUKkMXdPddhwAHm6UfOwJyh4ct1ybIlV14J0g= -go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.14.0 h1:OMqPldHt79PqWKOMYIAQs3CxAi7RLgPxwfFSwr4ZxtM= -go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.14.0/go.mod h1:1biG4qiqTxKiUCtoWDPpL3fB3KxVwCiGw81j3nKMuHE= -go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.14.0 h1:QQqYw3lkrzwVsoEX0w//EhH/TCnpRdEenKBOOEIMjWc= -go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.14.0/go.mod h1:gSVQcr17jk2ig4jqJ2DX30IdWH251JcNAecvrqTxH1s= -go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.38.0 h1:vl9obrcoWVKp/lwl8tRE33853I8Xru9HFbw/skNeLs8= -go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.38.0/go.mod h1:GAXRxmLJcVM3u22IjTg74zWBrRCKq8BnOqUVLodpcpw= -go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.38.0 h1:Oe2z/BCg5q7k4iXC3cqJxKYg0ieRiOqF0cecFYdPTwk= -go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.38.0/go.mod h1:ZQM5lAJpOsKnYagGg/zV2krVqTtaVdYdDkhMoX6Oalg= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.38.0 h1:GqRJVj7UmLjCVyVJ3ZFLdPRmhDUp2zFmQe3RHIOsw24= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.38.0/go.mod h1:ri3aaHSmCTVYu2AWv44YMauwAQc0aqI9gHKIcSbI1pU= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.38.0 h1:lwI4Dc5leUqENgGuQImwLo4WnuXFPetmPpkLi2IrX54= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.38.0/go.mod h1:Kz/oCE7z5wuyhPxsXDuaPteSWqjSBD5YaSdbxZYGbGk= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.38.0 h1:aTL7F04bJHUlztTsNGJ2l+6he8c+y/b//eR0jjjemT4= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.38.0/go.mod h1:kldtb7jDTeol0l3ewcmd8SDvx3EmIE7lyvqbasU3QC4= -go.opentelemetry.io/otel/exporters/prometheus v0.60.0 h1:cGtQxGvZbnrWdC2GyjZi0PDKVSLWP/Jocix3QWfXtbo= -go.opentelemetry.io/otel/exporters/prometheus v0.60.0/go.mod h1:hkd1EekxNo69PTV4OWFGZcKQiIqg0RfuWExcPKFvepk= -go.opentelemetry.io/otel/exporters/stdout/stdoutlog v0.14.0 h1:B/g+qde6Mkzxbry5ZZag0l7QrQBCtVm7lVjaLgmpje8= -go.opentelemetry.io/otel/exporters/stdout/stdoutlog v0.14.0/go.mod h1:mOJK8eMmgW6ocDJn6Bn11CcZ05gi3P8GylBXEkZtbgA= -go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.38.0 h1:wm/Q0GAAykXv83wzcKzGGqAnnfLFyFe7RslekZuv+VI= -go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.38.0/go.mod h1:ra3Pa40+oKjvYh+ZD3EdxFZZB0xdMfuileHAm4nNN7w= -go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.38.0 h1:kJxSDN4SgWWTjG/hPp3O7LCGLcHXFlvS2/FFOrwL+SE= -go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.38.0/go.mod h1:mgIOzS7iZeKJdeB8/NYHrJ48fdGc71Llo5bJ1J4DWUE= -go.opentelemetry.io/otel/log v0.14.0 h1:2rzJ+pOAZ8qmZ3DDHg73NEKzSZkhkGIua9gXtxNGgrM= -go.opentelemetry.io/otel/log v0.14.0/go.mod h1:5jRG92fEAgx0SU/vFPxmJvhIuDU9E1SUnEQrMlJpOno= +go.opentelemetry.io/contrib/zpages v0.67.0 h1:cIUwWSVDovuLEbDIKreptjdxMuIhGiqwq0uL8YNaq1c= +go.opentelemetry.io/contrib/zpages v0.67.0/go.mod h1:vK8fsYHgPYg4Z/XDbFSEvItSGZDbjWTvjBOu8+AiDhc= +go.opentelemetry.io/otel v1.42.0 h1:lSQGzTgVR3+sgJDAU/7/ZMjN9Z+vUip7leaqBKy4sho= +go.opentelemetry.io/otel v1.42.0/go.mod h1:lJNsdRMxCUIWuMlVJWzecSMuNjE7dOYyWlqOXWkdqCc= +go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.18.0 h1:deI9UQMoGFgrg5iLPgzueqFPHevDl+28YKfSpPTI6rY= +go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.18.0/go.mod h1:PFx9NgpNUKXdf7J4Q3agRxMs3Y07QhTCVipKmLsMKnU= +go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.18.0 h1:icqq3Z34UrEFk2u+HMhTtRsvo7Ues+eiJVjaJt62njs= +go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.18.0/go.mod h1:W2m8P+d5Wn5kipj4/xmbt9uMqezEKfBjzVJadfABSBE= +go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.42.0 h1:MdKucPl/HbzckWWEisiNqMPhRrAOQX8r4jTuGr636gk= +go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.42.0/go.mod h1:RolT8tWtfHcjajEH5wFIZ4Dgh5jpPdFXYV9pTAk/qjc= +go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.42.0 h1:H7O6RlGOMTizyl3R08Kn5pdM06bnH8oscSj7o11tmLA= +go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.42.0/go.mod h1:mBFWu/WOVDkWWsR7Tx7h6EpQB8wsv7P0Yrh0Pb7othc= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.42.0 h1:THuZiwpQZuHPul65w4WcwEnkX2QIuMT+UFoOrygtoJw= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.42.0/go.mod h1:J2pvYM5NGHofZ2/Ru6zw/TNWnEQp5crgyDeSrYpXkAw= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.42.0 h1:zWWrB1U6nqhS/k6zYB74CjRpuiitRtLLi68VcgmOEto= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.42.0/go.mod h1:2qXPNBX1OVRC0IwOnfo1ljoid+RD0QK3443EaqVlsOU= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.42.0 h1:uLXP+3mghfMf7XmV4PkGfFhFKuNWoCvvx5wP/wOXo0o= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.42.0/go.mod h1:v0Tj04armyT59mnURNUJf7RCKcKzq+lgJs6QSjHjaTc= +go.opentelemetry.io/otel/exporters/prometheus v0.64.0 h1:g0LRDXMX/G1SEZtK8zl8Chm4K6GBwRkjPKE36LxiTYs= +go.opentelemetry.io/otel/exporters/prometheus v0.64.0/go.mod h1:UrgcjnarfdlBDP3GjDIJWe6HTprwSazNjwsI+Ru6hro= +go.opentelemetry.io/otel/exporters/stdout/stdoutlog v0.18.0 h1:KJVjPD3rcPb98rIs3HznyJlrfx9ge5oJvxxlGR+P/7s= +go.opentelemetry.io/otel/exporters/stdout/stdoutlog v0.18.0/go.mod h1:K3kRa2ckmHWQaTWQdPRHc7qGXASuVuoEQXzrvlA98Ws= +go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.42.0 h1:lSZHgNHfbmQTPfuTmWVkEu8J8qXaQwuV30pjCcAUvP8= +go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.42.0/go.mod h1:so9ounLcuoRDu033MW/E0AD4hhUjVqswrMF5FoZlBcw= +go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.42.0 h1:s/1iRkCKDfhlh1JF26knRneorus8aOwVIDhvYx9WoDw= +go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.42.0/go.mod h1:UI3wi0FXg1Pofb8ZBiBLhtMzgoTm1TYkMvn71fAqDzs= +go.opentelemetry.io/otel/log v0.18.0 h1:XgeQIIBjZZrliksMEbcwMZefoOSMI1hdjiLEiiB0bAg= +go.opentelemetry.io/otel/log v0.18.0/go.mod h1:KEV1kad0NofR3ycsiDH4Yjcoj0+8206I6Ox2QYFSNgI= go.opentelemetry.io/otel/log/logtest v0.14.0 h1:BGTqNeluJDK2uIHAY8lRqxjVAYfqgcaTbVk1n3MWe5A= go.opentelemetry.io/otel/log/logtest v0.14.0/go.mod h1:IuguGt8XVP4XA4d2oEEDMVDBBCesMg8/tSGWDjuKfoA= -go.opentelemetry.io/otel/metric v1.40.0 h1:rcZe317KPftE2rstWIBitCdVp89A2HqjkxR3c11+p9g= -go.opentelemetry.io/otel/metric v1.40.0/go.mod h1:ib/crwQH7N3r5kfiBZQbwrTge743UDc7DTFVZrrXnqc= -go.opentelemetry.io/otel/sdk v1.40.0 h1:KHW/jUzgo6wsPh9At46+h4upjtccTmuZCFAc9OJ71f8= -go.opentelemetry.io/otel/sdk v1.40.0/go.mod h1:Ph7EFdYvxq72Y8Li9q8KebuYUr2KoeyHx0DRMKrYBUE= -go.opentelemetry.io/otel/sdk/log v0.14.0 h1:JU/U3O7N6fsAXj0+CXz21Czg532dW2V4gG1HE/e8Zrg= -go.opentelemetry.io/otel/sdk/log v0.14.0/go.mod h1:imQvII+0ZylXfKU7/wtOND8Hn4OpT3YUoIgqJVksUkM= -go.opentelemetry.io/otel/sdk/log/logtest v0.14.0 h1:Ijbtz+JKXl8T2MngiwqBlPaHqc4YCaP/i13Qrow6gAM= -go.opentelemetry.io/otel/sdk/log/logtest v0.14.0/go.mod h1:dCU8aEL6q+L9cYTqcVOk8rM9Tp8WdnHOPLiBgp0SGOA= -go.opentelemetry.io/otel/sdk/metric v1.40.0 h1:mtmdVqgQkeRxHgRv4qhyJduP3fYJRMX4AtAlbuWdCYw= -go.opentelemetry.io/otel/sdk/metric v1.40.0/go.mod h1:4Z2bGMf0KSK3uRjlczMOeMhKU2rhUqdWNoKcYrtcBPg= -go.opentelemetry.io/otel/trace v1.40.0 h1:WA4etStDttCSYuhwvEa8OP8I5EWu24lkOzp+ZYblVjw= -go.opentelemetry.io/otel/trace v1.40.0/go.mod h1:zeAhriXecNGP/s2SEG3+Y8X9ujcJOTqQ5RgdEJcawiA= -go.opentelemetry.io/proto/otlp v1.7.1 h1:gTOMpGDb0WTBOP8JaO72iL3auEZhVmAQg4ipjOVAtj4= -go.opentelemetry.io/proto/otlp v1.7.1/go.mod h1:b2rVh6rfI/s2pHWNlB7ILJcRALpcNDzKhACevjI+ZnE= -go.opentelemetry.io/proto/slim/otlp v1.9.0 h1:fPVMv8tP3TrsqlkH1HWYUpbCY9cAIemx184VGkS6vlE= -go.opentelemetry.io/proto/slim/otlp v1.9.0/go.mod h1:xXdeJJ90Gqyll+orzUkY4bOd2HECo5JofeoLpymVqdI= -go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.2.0 h1:o13nadWDNkH/quoDomDUClnQBpdQQ2Qqv0lQBjIXjE8= -go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.2.0/go.mod h1:Gyb6Xe7FTi/6xBHwMmngGoHqL0w29Y4eW8TGFzpefGA= -go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.2.0 h1:EiUYvtwu6PMrMHVjcPfnsG3v+ajPkbUeH+IL93+QYyk= -go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.2.0/go.mod h1:mUUHKFiN2SST3AhJ8XhJxEoeVW12oqfXog0Bo8W3Ec4= +go.opentelemetry.io/otel/metric v1.42.0 h1:2jXG+3oZLNXEPfNmnpxKDeZsFI5o4J+nz6xUlaFdF/4= +go.opentelemetry.io/otel/metric v1.42.0/go.mod h1:RlUN/7vTU7Ao/diDkEpQpnz3/92J9ko05BIwxYa2SSI= +go.opentelemetry.io/otel/sdk v1.42.0 h1:LyC8+jqk6UJwdrI/8VydAq/hvkFKNHZVIWuslJXYsDo= +go.opentelemetry.io/otel/sdk v1.42.0/go.mod h1:rGHCAxd9DAph0joO4W6OPwxjNTYWghRWmkHuGbayMts= +go.opentelemetry.io/otel/sdk/log v0.18.0 h1:n8OyZr7t7otkeTnPTbDNom6rW16TBYGtvyy2Gk6buQw= +go.opentelemetry.io/otel/sdk/log v0.18.0/go.mod h1:C0+wxkTwKpOCZLrlJ3pewPiiQwpzycPI/u6W0Z9fuYk= +go.opentelemetry.io/otel/sdk/log/logtest v0.18.0 h1:l3mYuPsuBx6UKE47BVcPrZoZ0q/KER57vbj2qkgDLXA= +go.opentelemetry.io/otel/sdk/log/logtest v0.18.0/go.mod h1:7cHtiVJpZebB3wybTa4NG+FUo5NPe3PROz1FqB0+qdw= +go.opentelemetry.io/otel/sdk/metric v1.42.0 h1:D/1QR46Clz6ajyZ3G8SgNlTJKBdGp84q9RKCAZ3YGuA= +go.opentelemetry.io/otel/sdk/metric v1.42.0/go.mod h1:Ua6AAlDKdZ7tdvaQKfSmnFTdHx37+J4ba8MwVCYM5hc= +go.opentelemetry.io/otel/trace v1.42.0 h1:OUCgIPt+mzOnaUTpOQcBiM/PLQ/Op7oq6g4LenLmOYY= +go.opentelemetry.io/otel/trace v1.42.0/go.mod h1:f3K9S+IFqnumBkKhRJMeaZeNk9epyhnCmQh/EysQCdc= +go.opentelemetry.io/proto/otlp v1.10.0 h1:IQRWgT5srOCYfiWnpqUYz9CVmbO8bFmKcwYxpuCSL2g= +go.opentelemetry.io/proto/otlp v1.10.0/go.mod h1:/CV4QoCR/S9yaPj8utp3lvQPoqMtxXdzn7ozvvozVqk= +go.opentelemetry.io/proto/slim/otlp v1.10.0 h1:iR97Vs/ZDR+y9TfuP9b1XBtdPWeC+OMslIBmhcLU7jM= +go.opentelemetry.io/proto/slim/otlp v1.10.0/go.mod h1:lV9250stpjYLPNA5viFabIgP2QlUGRT1GdTgAf8SIUk= +go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.3.0 h1:RUF5rO0hAlgiJt1fzQVzcVs3vZVNHIcMLgOgG4rWNcQ= +go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.3.0/go.mod h1:I89cynRj8y+383o7tEQVg2SVA6SRgDVIouWPUVXjx0U= +go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.3.0 h1:CQvJSldHRUN6Z8jsUeYv8J0lXRvygALXIzsmAeCcZE0= +go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.3.0/go.mod h1:xSQ+mEfJe/GjK1LXEyVOoSI1N9JV9ZI923X5kup43W4= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= @@ -192,29 +192,28 @@ go.yaml.in/yaml/v2 v2.4.3 h1:6gvOSjQoTB3vt1l+CU+tSyi/HOjfOjRLJ4YwYZGwRO0= go.yaml.in/yaml/v2 v2.4.3/go.mod h1:zSxWcmIDjOzPXpjlTTbAsKokqkDNAVtZO0WOMiT90s8= go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc= go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg= -golang.org/x/crypto v0.45.0 h1:jMBrvKuj23MTlT0bQEOBcAE0mjg8mK9RXFhRH6nyF3Q= -golang.org/x/crypto v0.45.0/go.mod h1:XTGrrkGJve7CYK7J8PEww4aY7gM3qMCElcJQ8n8JdX4= +golang.org/x/crypto v0.48.0 h1:/VRzVqiRSggnhY7gNRxPauEQ5Drw9haKdM0jqfcCFts= +golang.org/x/crypto v0.48.0/go.mod h1:r0kV5h3qnFPlQnBSrULhlsRfryS2pmewsg+XfMgkVos= golang.org/x/exp v0.0.0-20240506185415-9bf2ced13842 h1:vr/HnozRka3pE4EsMEg1lgkXJkTFJCVUX+S/ZT6wYzM= golang.org/x/exp v0.0.0-20240506185415-9bf2ced13842/go.mod h1:XtvwrStGgqGPLc4cjQfWqZHG1YFdYs6swckp8vpsjnc= -golang.org/x/net v0.47.0 h1:Mx+4dIFzqraBXUugkia1OOvlD6LemFo1ALMHjrXDOhY= -golang.org/x/net v0.47.0/go.mod h1:/jNxtkgq5yWUGYkaZGqo27cfGZ1c5Nen03aYrrKpVRU= +golang.org/x/net v0.51.0 h1:94R/GTO7mt3/4wIKpcR5gkGmRLOuE/2hNGeWq/GBIFo= +golang.org/x/net v0.51.0/go.mod h1:aamm+2QF5ogm02fjy5Bb7CQ0WMt1/WVM7FtyaTLlA9Y= golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201204225414-ed752295db88/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.40.0 h1:DBZZqJ2Rkml6QMQsZywtnjnnGvHza6BTfYFWY9kjEWQ= -golang.org/x/sys v0.40.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= -golang.org/x/text v0.31.0 h1:aC8ghyu4JhP8VojJ2lEHBnochRno1sgL6nEi9WGFGMM= -golang.org/x/text v0.31.0/go.mod h1:tKRAlv61yKIjGGHX/4tP1LTbc13YSec1pxVEWXzfoeM= -golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -gonum.org/v1/gonum v0.16.0 h1:5+ul4Swaf3ESvrOnidPp4GZbzf0mxVQpDCYUQE7OJfk= -gonum.org/v1/gonum v0.16.0/go.mod h1:fef3am4MQ93R2HHpKnLk4/Tbh/s0+wqD5nfa6Pnwy4E= -google.golang.org/genproto/googleapis/api v0.0.0-20251022142026-3a174f9686a8 h1:mepRgnBZa07I4TRuomDE4sTIYieg/osKmzIf4USdWS4= -google.golang.org/genproto/googleapis/api v0.0.0-20251022142026-3a174f9686a8/go.mod h1:fDMmzKV90WSg1NbozdqrE64fkuTv6mlq2zxo9ad+3yo= -google.golang.org/genproto/googleapis/rpc v0.0.0-20251022142026-3a174f9686a8 h1:M1rk8KBnUsBDg1oPGHNCxG4vc1f49epmTO7xscSajMk= -google.golang.org/genproto/googleapis/rpc v0.0.0-20251022142026-3a174f9686a8/go.mod h1:7i2o+ce6H/6BluujYR+kqX3GKH+dChPTQU19wjRPiGk= -google.golang.org/grpc v1.77.0 h1:wVVY6/8cGA6vvffn+wWK5ToddbgdU3d8MNENr4evgXM= -google.golang.org/grpc v1.77.0/go.mod h1:z0BY1iVj0q8E1uSQCjL9cppRj+gnZjzDnzV0dHhrNig= -google.golang.org/protobuf v1.36.10 h1:AYd7cD/uASjIL6Q9LiTjz8JLcrh/88q5UObnmY3aOOE= -google.golang.org/protobuf v1.36.10/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= +golang.org/x/sys v0.41.0 h1:Ivj+2Cp/ylzLiEU89QhWblYnOE9zerudt9Ftecq2C6k= +golang.org/x/sys v0.41.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= +golang.org/x/text v0.34.0 h1:oL/Qq0Kdaqxa1KbNeMKwQq0reLCCaFtqu2eNuSeNHbk= +golang.org/x/text v0.34.0/go.mod h1:homfLqTYRFyVYemLBFl5GgL/DWEiH5wcsQ5gSh1yziA= +gonum.org/v1/gonum v0.17.0 h1:VbpOemQlsSMrYmn7T2OUvQ4dqxQXU+ouZFQsZOx50z4= +gonum.org/v1/gonum v0.17.0/go.mod h1:El3tOrEuMpv2UdMrbNlKEh9vd86bmQ6vqIcDwxEOc1E= +google.golang.org/genproto/googleapis/api v0.0.0-20260226221140-a57be14db171 h1:tu/dtnW1o3wfaxCOjSLn5IRX4YDcJrtlpzYkhHhGaC4= +google.golang.org/genproto/googleapis/api v0.0.0-20260226221140-a57be14db171/go.mod h1:M5krXqk4GhBKvB596udGL3UyjL4I1+cTbK0orROM9ng= +google.golang.org/genproto/googleapis/rpc v0.0.0-20260226221140-a57be14db171 h1:ggcbiqK8WWh6l1dnltU4BgWGIGo+EVYxCaAPih/zQXQ= +google.golang.org/genproto/googleapis/rpc v0.0.0-20260226221140-a57be14db171/go.mod h1:4Hqkh8ycfw05ld/3BWL7rJOSfebL2Q+DVDeRgYgxUU8= +google.golang.org/grpc v1.79.3 h1:sybAEdRIEtvcD68Gx7dmnwjZKlyfuc61Dyo9pGXXkKE= +google.golang.org/grpc v1.79.3/go.mod h1:KmT0Kjez+0dde/v2j9vzwoAScgEPx/Bw1CYChhHLrHQ= +google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE= +google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= diff --git a/cmd/otelcorecol/main.go b/cmd/otelcorecol/main.go index 401bed4c47fe..920173381078 100644 --- a/cmd/otelcorecol/main.go +++ b/cmd/otelcorecol/main.go @@ -4,7 +4,8 @@ package main import ( - "log" + "fmt" + "os" "go.opentelemetry.io/collector/component" "go.opentelemetry.io/collector/confmap" @@ -20,7 +21,7 @@ func main() { info := component.BuildInfo{ Command: "otelcorecol", Description: "Local OpenTelemetry Collector binary, testing only.", - Version: "0.140.0-dev", + Version: "0.148.0-dev", } set := otelcol.CollectorSettings{ @@ -38,24 +39,25 @@ func main() { }, }, ProviderModules: map[string]string{ - envprovider.NewFactory().Create(confmap.ProviderSettings{}).Scheme(): "go.opentelemetry.io/collector/confmap/provider/envprovider v1.46.0", - fileprovider.NewFactory().Create(confmap.ProviderSettings{}).Scheme(): "go.opentelemetry.io/collector/confmap/provider/fileprovider v1.46.0", - httpprovider.NewFactory().Create(confmap.ProviderSettings{}).Scheme(): "go.opentelemetry.io/collector/confmap/provider/httpprovider v1.46.0", - httpsprovider.NewFactory().Create(confmap.ProviderSettings{}).Scheme(): "go.opentelemetry.io/collector/confmap/provider/httpsprovider v1.46.0", - yamlprovider.NewFactory().Create(confmap.ProviderSettings{}).Scheme(): "go.opentelemetry.io/collector/confmap/provider/yamlprovider v1.46.0", + envprovider.NewFactory().Create(confmap.ProviderSettings{}).Scheme(): "go.opentelemetry.io/collector/confmap/provider/envprovider v1.54.0", + fileprovider.NewFactory().Create(confmap.ProviderSettings{}).Scheme(): "go.opentelemetry.io/collector/confmap/provider/fileprovider v1.54.0", + httpprovider.NewFactory().Create(confmap.ProviderSettings{}).Scheme(): "go.opentelemetry.io/collector/confmap/provider/httpprovider v1.54.0", + httpsprovider.NewFactory().Create(confmap.ProviderSettings{}).Scheme(): "go.opentelemetry.io/collector/confmap/provider/httpsprovider v1.54.0", + yamlprovider.NewFactory().Create(confmap.ProviderSettings{}).Scheme(): "go.opentelemetry.io/collector/confmap/provider/yamlprovider v1.54.0", }, ConverterModules: []string{}, } if err := run(set); err != nil { - log.Fatal(err) + _, _ = fmt.Fprintln(os.Stderr, err) + os.Exit(1) } } func runInteractive(params otelcol.CollectorSettings) error { cmd := otelcol.NewCommand(params) if err := cmd.Execute(); err != nil { - log.Fatalf("collector server run finished with error: %v", err) + return err } return nil diff --git a/component/component.go b/component/component.go index 5a32c5041d7c..c816f9909066 100644 --- a/component/component.go +++ b/component/component.go @@ -29,11 +29,17 @@ type Component interface { // If this is an exporter component it may prepare for exporting // by connecting to the endpoint. // - // If the component needs to perform a long-running starting operation then it is recommended - // that Start() returns quickly and the long-running operation is performed in background. - // In that case make sure that the long-running operation does not use the context passed - // to Start() function since that context will be cancelled soon and can abort the long-running - // operation. Create a new context from the context.Background() for long-running operations. + // If the component needs to perform a long-running starting operation, then + // it is recommended that Start() returns quickly and the long-running + // operation is performed in the background. Background operations should + // create their own context using context.WithCancel(context.Background()) + // rather than using the passed context, which is intended only for the + // startup operation itself. The component should cancel this context in its + // Shutdown() method. + // + // Note: as of today, the context passed to Start() lives for the entire + // lifetime of the collector, but this may change in the future to include a + // startup timeout. Start(ctx context.Context, host Host) error // Shutdown is invoked during service shutdown. After Shutdown() is called, if the component @@ -46,7 +52,7 @@ type Component interface { // If there are any background operations running by the component they must be aborted before // this function returns. Remember that if you started any long-running background operations from // the Start() method, those operations must be also cancelled. If there are any buffers in the - // component, they should be cleared and the data sent immediately to the next component. + // component, they should be flushed with the data being sent immediately to the next component. // // The component's lifecycle is completed once the Shutdown() method returns. No other // methods of the component are called after that. If necessary a new component with diff --git a/component/componentstatus/go.mod b/component/componentstatus/go.mod index b1da12ca0f5e..f00e79c8acc0 100644 --- a/component/componentstatus/go.mod +++ b/component/componentstatus/go.mod @@ -1,23 +1,23 @@ module go.opentelemetry.io/collector/component/componentstatus -go 1.24.0 +go 1.25.0 require ( github.com/stretchr/testify v1.11.1 - go.opentelemetry.io/collector/component v1.46.0 - go.opentelemetry.io/collector/pdata v1.46.0 - go.opentelemetry.io/collector/pipeline v1.46.0 + go.opentelemetry.io/collector/component v1.54.0 + go.opentelemetry.io/collector/pdata v1.54.0 + go.opentelemetry.io/collector/pipeline v1.54.0 ) require ( github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/davecgh/go-spew v1.1.1 // indirect - github.com/hashicorp/go-version v1.7.0 // indirect + github.com/hashicorp/go-version v1.8.0 // indirect github.com/json-iterator/go v1.1.12 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee // indirect github.com/pmezard/go-difflib v1.0.0 // indirect - go.opentelemetry.io/collector/featuregate v1.46.0 // indirect + go.opentelemetry.io/collector/featuregate v1.54.0 // indirect go.opentelemetry.io/otel v1.40.0 // indirect go.opentelemetry.io/otel/metric v1.40.0 // indirect go.opentelemetry.io/otel/trace v1.40.0 // indirect diff --git a/component/componentstatus/go.sum b/component/componentstatus/go.sum index 37d6edbc3764..46cd6ed8c011 100644 --- a/component/componentstatus/go.sum +++ b/component/componentstatus/go.sum @@ -10,8 +10,8 @@ github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= -github.com/hashicorp/go-version v1.7.0 h1:5tqGy27NaOTB8yJKUZELlFAS/LTKJkrmONwQKeRZfjY= -github.com/hashicorp/go-version v1.7.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= +github.com/hashicorp/go-version v1.8.0 h1:KAkNb1HAiZd1ukkxDFGmokVZe1Xy9HG6NUp+bPle2i4= +github.com/hashicorp/go-version v1.8.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= @@ -40,20 +40,20 @@ go.opentelemetry.io/otel/metric v1.40.0 h1:rcZe317KPftE2rstWIBitCdVp89A2HqjkxR3c go.opentelemetry.io/otel/metric v1.40.0/go.mod h1:ib/crwQH7N3r5kfiBZQbwrTge743UDc7DTFVZrrXnqc= go.opentelemetry.io/otel/trace v1.40.0 h1:WA4etStDttCSYuhwvEa8OP8I5EWu24lkOzp+ZYblVjw= go.opentelemetry.io/otel/trace v1.40.0/go.mod h1:zeAhriXecNGP/s2SEG3+Y8X9ujcJOTqQ5RgdEJcawiA= -go.opentelemetry.io/proto/slim/otlp v1.9.0 h1:fPVMv8tP3TrsqlkH1HWYUpbCY9cAIemx184VGkS6vlE= -go.opentelemetry.io/proto/slim/otlp v1.9.0/go.mod h1:xXdeJJ90Gqyll+orzUkY4bOd2HECo5JofeoLpymVqdI= -go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.2.0 h1:o13nadWDNkH/quoDomDUClnQBpdQQ2Qqv0lQBjIXjE8= -go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.2.0/go.mod h1:Gyb6Xe7FTi/6xBHwMmngGoHqL0w29Y4eW8TGFzpefGA= -go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.2.0 h1:EiUYvtwu6PMrMHVjcPfnsG3v+ajPkbUeH+IL93+QYyk= -go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.2.0/go.mod h1:mUUHKFiN2SST3AhJ8XhJxEoeVW12oqfXog0Bo8W3Ec4= +go.opentelemetry.io/proto/slim/otlp v1.10.0 h1:iR97Vs/ZDR+y9TfuP9b1XBtdPWeC+OMslIBmhcLU7jM= +go.opentelemetry.io/proto/slim/otlp v1.10.0/go.mod h1:lV9250stpjYLPNA5viFabIgP2QlUGRT1GdTgAf8SIUk= +go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.3.0 h1:RUF5rO0hAlgiJt1fzQVzcVs3vZVNHIcMLgOgG4rWNcQ= +go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.3.0/go.mod h1:I89cynRj8y+383o7tEQVg2SVA6SRgDVIouWPUVXjx0U= +go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.3.0 h1:CQvJSldHRUN6Z8jsUeYv8J0lXRvygALXIzsmAeCcZE0= +go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.3.0/go.mod h1:xSQ+mEfJe/GjK1LXEyVOoSI1N9JV9ZI923X5kup43W4= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= go.uber.org/zap v1.27.1 h1:08RqriUEv8+ArZRYSTXy1LeBScaMpVSTBhCeaZYfMYc= go.uber.org/zap v1.27.1/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= -google.golang.org/protobuf v1.36.10 h1:AYd7cD/uASjIL6Q9LiTjz8JLcrh/88q5UObnmY3aOOE= -google.golang.org/protobuf v1.36.10/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= +google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE= +google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= diff --git a/component/componentstatus/metadata.yaml b/component/componentstatus/metadata.yaml new file mode 100644 index 000000000000..f5902034e3c2 --- /dev/null +++ b/component/componentstatus/metadata.yaml @@ -0,0 +1,6 @@ +type: component/componentstatus +github_project: open-telemetry/opentelemetry-collector + +status: + disable_codecov_badge: true + class: pkg diff --git a/component/componenttest/go.mod b/component/componenttest/go.mod index c8ceedbc39b1..c401d872af4a 100644 --- a/component/componenttest/go.mod +++ b/component/componenttest/go.mod @@ -1,6 +1,6 @@ module go.opentelemetry.io/collector/component/componenttest -go 1.24.0 +go 1.25.0 require ( github.com/stretchr/testify v1.11.1 @@ -21,15 +21,15 @@ require ( github.com/go-logr/logr v1.4.3 // indirect github.com/go-logr/stdr v1.2.2 // indirect github.com/google/uuid v1.6.0 // indirect - github.com/hashicorp/go-version v1.7.0 // indirect + github.com/hashicorp/go-version v1.8.0 // indirect github.com/json-iterator/go v1.1.12 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee // indirect github.com/pmezard/go-difflib v1.0.0 // indirect go.opentelemetry.io/auto/sdk v1.2.1 // indirect - go.opentelemetry.io/collector/featuregate v1.46.0 // indirect + go.opentelemetry.io/collector/featuregate v1.54.0 // indirect go.opentelemetry.io/otel v1.40.0 // indirect - golang.org/x/sys v0.40.0 // indirect + golang.org/x/sys v0.41.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/component/componenttest/go.sum b/component/componenttest/go.sum index c102571e7869..1e6789104ba9 100644 --- a/component/componenttest/go.sum +++ b/component/componenttest/go.sum @@ -13,8 +13,8 @@ github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/hashicorp/go-version v1.7.0 h1:5tqGy27NaOTB8yJKUZELlFAS/LTKJkrmONwQKeRZfjY= -github.com/hashicorp/go-version v1.7.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= +github.com/hashicorp/go-version v1.8.0 h1:KAkNb1HAiZd1ukkxDFGmokVZe1Xy9HG6NUp+bPle2i4= +github.com/hashicorp/go-version v1.8.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= @@ -47,22 +47,22 @@ go.opentelemetry.io/otel/sdk/metric v1.40.0 h1:mtmdVqgQkeRxHgRv4qhyJduP3fYJRMX4A go.opentelemetry.io/otel/sdk/metric v1.40.0/go.mod h1:4Z2bGMf0KSK3uRjlczMOeMhKU2rhUqdWNoKcYrtcBPg= go.opentelemetry.io/otel/trace v1.40.0 h1:WA4etStDttCSYuhwvEa8OP8I5EWu24lkOzp+ZYblVjw= go.opentelemetry.io/otel/trace v1.40.0/go.mod h1:zeAhriXecNGP/s2SEG3+Y8X9ujcJOTqQ5RgdEJcawiA= -go.opentelemetry.io/proto/slim/otlp v1.9.0 h1:fPVMv8tP3TrsqlkH1HWYUpbCY9cAIemx184VGkS6vlE= -go.opentelemetry.io/proto/slim/otlp v1.9.0/go.mod h1:xXdeJJ90Gqyll+orzUkY4bOd2HECo5JofeoLpymVqdI= -go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.2.0 h1:o13nadWDNkH/quoDomDUClnQBpdQQ2Qqv0lQBjIXjE8= -go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.2.0/go.mod h1:Gyb6Xe7FTi/6xBHwMmngGoHqL0w29Y4eW8TGFzpefGA= -go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.2.0 h1:EiUYvtwu6PMrMHVjcPfnsG3v+ajPkbUeH+IL93+QYyk= -go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.2.0/go.mod h1:mUUHKFiN2SST3AhJ8XhJxEoeVW12oqfXog0Bo8W3Ec4= +go.opentelemetry.io/proto/slim/otlp v1.10.0 h1:iR97Vs/ZDR+y9TfuP9b1XBtdPWeC+OMslIBmhcLU7jM= +go.opentelemetry.io/proto/slim/otlp v1.10.0/go.mod h1:lV9250stpjYLPNA5viFabIgP2QlUGRT1GdTgAf8SIUk= +go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.3.0 h1:RUF5rO0hAlgiJt1fzQVzcVs3vZVNHIcMLgOgG4rWNcQ= +go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.3.0/go.mod h1:I89cynRj8y+383o7tEQVg2SVA6SRgDVIouWPUVXjx0U= +go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.3.0 h1:CQvJSldHRUN6Z8jsUeYv8J0lXRvygALXIzsmAeCcZE0= +go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.3.0/go.mod h1:xSQ+mEfJe/GjK1LXEyVOoSI1N9JV9ZI923X5kup43W4= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= go.uber.org/zap v1.27.1 h1:08RqriUEv8+ArZRYSTXy1LeBScaMpVSTBhCeaZYfMYc= go.uber.org/zap v1.27.1/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= -golang.org/x/sys v0.40.0 h1:DBZZqJ2Rkml6QMQsZywtnjnnGvHza6BTfYFWY9kjEWQ= -golang.org/x/sys v0.40.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= -google.golang.org/protobuf v1.36.10 h1:AYd7cD/uASjIL6Q9LiTjz8JLcrh/88q5UObnmY3aOOE= -google.golang.org/protobuf v1.36.10/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= +golang.org/x/sys v0.41.0 h1:Ivj+2Cp/ylzLiEU89QhWblYnOE9zerudt9Ftecq2C6k= +golang.org/x/sys v0.41.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= +google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE= +google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= diff --git a/component/componenttest/metadata.yaml b/component/componenttest/metadata.yaml new file mode 100644 index 000000000000..9ea065522370 --- /dev/null +++ b/component/componenttest/metadata.yaml @@ -0,0 +1,6 @@ +type: component/componenttest +github_project: open-telemetry/opentelemetry-collector + +status: + disable_codecov_badge: true + class: pkg diff --git a/component/go.mod b/component/go.mod index 372f32ad2212..118f17850c95 100644 --- a/component/go.mod +++ b/component/go.mod @@ -1,6 +1,6 @@ module go.opentelemetry.io/collector/component -go 1.24.0 +go 1.25.0 require ( github.com/stretchr/testify v1.11.1 @@ -14,13 +14,13 @@ require ( require ( github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/davecgh/go-spew v1.1.1 // indirect - github.com/hashicorp/go-version v1.7.0 // indirect + github.com/hashicorp/go-version v1.8.0 // indirect github.com/json-iterator/go v1.1.12 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee // indirect github.com/pmezard/go-difflib v1.0.0 // indirect github.com/rogpeppe/go-internal v1.14.1 // indirect - go.opentelemetry.io/collector/featuregate v1.46.0 // indirect + go.opentelemetry.io/collector/featuregate v1.54.0 // indirect go.opentelemetry.io/otel v1.40.0 // indirect go.uber.org/multierr v1.11.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect diff --git a/component/go.sum b/component/go.sum index 37d6edbc3764..46cd6ed8c011 100644 --- a/component/go.sum +++ b/component/go.sum @@ -10,8 +10,8 @@ github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= -github.com/hashicorp/go-version v1.7.0 h1:5tqGy27NaOTB8yJKUZELlFAS/LTKJkrmONwQKeRZfjY= -github.com/hashicorp/go-version v1.7.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= +github.com/hashicorp/go-version v1.8.0 h1:KAkNb1HAiZd1ukkxDFGmokVZe1Xy9HG6NUp+bPle2i4= +github.com/hashicorp/go-version v1.8.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= @@ -40,20 +40,20 @@ go.opentelemetry.io/otel/metric v1.40.0 h1:rcZe317KPftE2rstWIBitCdVp89A2HqjkxR3c go.opentelemetry.io/otel/metric v1.40.0/go.mod h1:ib/crwQH7N3r5kfiBZQbwrTge743UDc7DTFVZrrXnqc= go.opentelemetry.io/otel/trace v1.40.0 h1:WA4etStDttCSYuhwvEa8OP8I5EWu24lkOzp+ZYblVjw= go.opentelemetry.io/otel/trace v1.40.0/go.mod h1:zeAhriXecNGP/s2SEG3+Y8X9ujcJOTqQ5RgdEJcawiA= -go.opentelemetry.io/proto/slim/otlp v1.9.0 h1:fPVMv8tP3TrsqlkH1HWYUpbCY9cAIemx184VGkS6vlE= -go.opentelemetry.io/proto/slim/otlp v1.9.0/go.mod h1:xXdeJJ90Gqyll+orzUkY4bOd2HECo5JofeoLpymVqdI= -go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.2.0 h1:o13nadWDNkH/quoDomDUClnQBpdQQ2Qqv0lQBjIXjE8= -go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.2.0/go.mod h1:Gyb6Xe7FTi/6xBHwMmngGoHqL0w29Y4eW8TGFzpefGA= -go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.2.0 h1:EiUYvtwu6PMrMHVjcPfnsG3v+ajPkbUeH+IL93+QYyk= -go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.2.0/go.mod h1:mUUHKFiN2SST3AhJ8XhJxEoeVW12oqfXog0Bo8W3Ec4= +go.opentelemetry.io/proto/slim/otlp v1.10.0 h1:iR97Vs/ZDR+y9TfuP9b1XBtdPWeC+OMslIBmhcLU7jM= +go.opentelemetry.io/proto/slim/otlp v1.10.0/go.mod h1:lV9250stpjYLPNA5viFabIgP2QlUGRT1GdTgAf8SIUk= +go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.3.0 h1:RUF5rO0hAlgiJt1fzQVzcVs3vZVNHIcMLgOgG4rWNcQ= +go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.3.0/go.mod h1:I89cynRj8y+383o7tEQVg2SVA6SRgDVIouWPUVXjx0U= +go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.3.0 h1:CQvJSldHRUN6Z8jsUeYv8J0lXRvygALXIzsmAeCcZE0= +go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.3.0/go.mod h1:xSQ+mEfJe/GjK1LXEyVOoSI1N9JV9ZI923X5kup43W4= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= go.uber.org/zap v1.27.1 h1:08RqriUEv8+ArZRYSTXy1LeBScaMpVSTBhCeaZYfMYc= go.uber.org/zap v1.27.1/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= -google.golang.org/protobuf v1.36.10 h1:AYd7cD/uASjIL6Q9LiTjz8JLcrh/88q5UObnmY3aOOE= -google.golang.org/protobuf v1.36.10/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= +google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE= +google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= diff --git a/component/identifiable_test.go b/component/identifiable_test.go index ace96386bb8b..075769440570 100644 --- a/component/identifiable_test.go +++ b/component/identifiable_test.go @@ -236,6 +236,7 @@ func TestNewType(t *testing.T) { {name: "oteltestbedcol"}, {name: "otlp"}, {name: "otlp_encoding"}, + {name: "otlp_http"}, {name: "otlphttp"}, {name: "otlpjsonfile"}, {name: "ottl"}, diff --git a/component/metadata.yaml b/component/metadata.yaml new file mode 100644 index 000000000000..90860123b3b9 --- /dev/null +++ b/component/metadata.yaml @@ -0,0 +1,6 @@ +type: component +github_project: open-telemetry/opentelemetry-collector + +status: + disable_codecov_badge: true + class: pkg diff --git a/config/configauth/README.md b/config/configauth/README.md index 25ed0be9c87f..b50ebcbaa8dc 100644 --- a/config/configauth/README.md +++ b/config/configauth/README.md @@ -59,7 +59,7 @@ receivers: ## oidc is the extension name to use as the authenticator for this receiver authenticator: oidc - otlphttp/withauth: + otlp_http/withauth: endpoint: http://localhost:9000 auth: authenticator: oauth2client diff --git a/config/configauth/config.schema.yaml b/config/configauth/config.schema.yaml new file mode 100644 index 000000000000..a3649bbe6f80 --- /dev/null +++ b/config/configauth/config.schema.yaml @@ -0,0 +1,9 @@ +$defs: + config: + description: Config defines the auth settings for the receiver. + type: object + properties: + authenticator: + description: AuthenticatorID specifies the name of the extension to use in order to authenticate the incoming data point. + type: string + x-customType: go.opentelemetry.io/collector/component.ID diff --git a/config/configauth/go.mod b/config/configauth/go.mod index aedf9527b416..bb0fecab217f 100644 --- a/config/configauth/go.mod +++ b/config/configauth/go.mod @@ -1,33 +1,34 @@ module go.opentelemetry.io/collector/config/configauth -go 1.24.0 +go 1.25.0 require ( github.com/stretchr/testify v1.11.1 - go.opentelemetry.io/collector/component v1.46.0 - go.opentelemetry.io/collector/extension v1.46.0 - go.opentelemetry.io/collector/extension/extensionauth v1.46.0 - go.opentelemetry.io/collector/extension/extensionauth/extensionauthtest v0.140.0 + go.opentelemetry.io/collector/component v1.54.0 + go.opentelemetry.io/collector/extension v1.54.0 + go.opentelemetry.io/collector/extension/extensionauth v1.54.0 + go.opentelemetry.io/collector/extension/extensionauth/extensionauthtest v0.148.0 go.uber.org/goleak v1.3.0 ) require ( github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/davecgh/go-spew v1.1.1 // indirect - github.com/hashicorp/go-version v1.7.0 // indirect + github.com/hashicorp/go-version v1.8.0 // indirect github.com/json-iterator/go v1.1.12 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee // indirect github.com/pmezard/go-difflib v1.0.0 // indirect - go.opentelemetry.io/collector/featuregate v1.46.0 // indirect - go.opentelemetry.io/collector/pdata v1.46.0 // indirect - go.opentelemetry.io/otel v1.40.0 // indirect - go.opentelemetry.io/otel/metric v1.40.0 // indirect - go.opentelemetry.io/otel/trace v1.40.0 // indirect + go.opentelemetry.io/collector/featuregate v1.54.0 // indirect + go.opentelemetry.io/collector/internal/componentalias v0.148.0 // indirect + go.opentelemetry.io/collector/pdata v1.54.0 // indirect + go.opentelemetry.io/otel v1.42.0 // indirect + go.opentelemetry.io/otel/metric v1.42.0 // indirect + go.opentelemetry.io/otel/trace v1.42.0 // indirect go.uber.org/multierr v1.11.0 // indirect go.uber.org/zap v1.27.1 // indirect - google.golang.org/grpc v1.77.0 // indirect - google.golang.org/protobuf v1.36.10 // indirect + google.golang.org/grpc v1.79.3 // indirect + google.golang.org/protobuf v1.36.11 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) @@ -44,3 +45,5 @@ replace go.opentelemetry.io/collector/extension/extensionauth/extensionauthtest replace go.opentelemetry.io/collector/featuregate => ../../featuregate replace go.opentelemetry.io/collector/internal/testutil => ../../internal/testutil + +replace go.opentelemetry.io/collector/internal/componentalias => ../../internal/componentalias diff --git a/config/configauth/go.sum b/config/configauth/go.sum index 7754787e8588..41c81c103c95 100644 --- a/config/configauth/go.sum +++ b/config/configauth/go.sum @@ -10,8 +10,8 @@ github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= -github.com/hashicorp/go-version v1.7.0 h1:5tqGy27NaOTB8yJKUZELlFAS/LTKJkrmONwQKeRZfjY= -github.com/hashicorp/go-version v1.7.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= +github.com/hashicorp/go-version v1.8.0 h1:KAkNb1HAiZd1ukkxDFGmokVZe1Xy9HG6NUp+bPle2i4= +github.com/hashicorp/go-version v1.8.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= @@ -34,36 +34,36 @@ github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64= go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y= -go.opentelemetry.io/otel v1.40.0 h1:oA5YeOcpRTXq6NN7frwmwFR0Cn3RhTVZvXsP4duvCms= -go.opentelemetry.io/otel v1.40.0/go.mod h1:IMb+uXZUKkMXdPddhwAHm6UfOwJyh4ct1ybIlV14J0g= -go.opentelemetry.io/otel/metric v1.40.0 h1:rcZe317KPftE2rstWIBitCdVp89A2HqjkxR3c11+p9g= -go.opentelemetry.io/otel/metric v1.40.0/go.mod h1:ib/crwQH7N3r5kfiBZQbwrTge743UDc7DTFVZrrXnqc= -go.opentelemetry.io/otel/trace v1.40.0 h1:WA4etStDttCSYuhwvEa8OP8I5EWu24lkOzp+ZYblVjw= -go.opentelemetry.io/otel/trace v1.40.0/go.mod h1:zeAhriXecNGP/s2SEG3+Y8X9ujcJOTqQ5RgdEJcawiA= -go.opentelemetry.io/proto/slim/otlp v1.9.0 h1:fPVMv8tP3TrsqlkH1HWYUpbCY9cAIemx184VGkS6vlE= -go.opentelemetry.io/proto/slim/otlp v1.9.0/go.mod h1:xXdeJJ90Gqyll+orzUkY4bOd2HECo5JofeoLpymVqdI= -go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.2.0 h1:o13nadWDNkH/quoDomDUClnQBpdQQ2Qqv0lQBjIXjE8= -go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.2.0/go.mod h1:Gyb6Xe7FTi/6xBHwMmngGoHqL0w29Y4eW8TGFzpefGA= -go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.2.0 h1:EiUYvtwu6PMrMHVjcPfnsG3v+ajPkbUeH+IL93+QYyk= -go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.2.0/go.mod h1:mUUHKFiN2SST3AhJ8XhJxEoeVW12oqfXog0Bo8W3Ec4= +go.opentelemetry.io/otel v1.42.0 h1:lSQGzTgVR3+sgJDAU/7/ZMjN9Z+vUip7leaqBKy4sho= +go.opentelemetry.io/otel v1.42.0/go.mod h1:lJNsdRMxCUIWuMlVJWzecSMuNjE7dOYyWlqOXWkdqCc= +go.opentelemetry.io/otel/metric v1.42.0 h1:2jXG+3oZLNXEPfNmnpxKDeZsFI5o4J+nz6xUlaFdF/4= +go.opentelemetry.io/otel/metric v1.42.0/go.mod h1:RlUN/7vTU7Ao/diDkEpQpnz3/92J9ko05BIwxYa2SSI= +go.opentelemetry.io/otel/trace v1.42.0 h1:OUCgIPt+mzOnaUTpOQcBiM/PLQ/Op7oq6g4LenLmOYY= +go.opentelemetry.io/otel/trace v1.42.0/go.mod h1:f3K9S+IFqnumBkKhRJMeaZeNk9epyhnCmQh/EysQCdc= +go.opentelemetry.io/proto/slim/otlp v1.10.0 h1:iR97Vs/ZDR+y9TfuP9b1XBtdPWeC+OMslIBmhcLU7jM= +go.opentelemetry.io/proto/slim/otlp v1.10.0/go.mod h1:lV9250stpjYLPNA5viFabIgP2QlUGRT1GdTgAf8SIUk= +go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.3.0 h1:RUF5rO0hAlgiJt1fzQVzcVs3vZVNHIcMLgOgG4rWNcQ= +go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.3.0/go.mod h1:I89cynRj8y+383o7tEQVg2SVA6SRgDVIouWPUVXjx0U= +go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.3.0 h1:CQvJSldHRUN6Z8jsUeYv8J0lXRvygALXIzsmAeCcZE0= +go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.3.0/go.mod h1:xSQ+mEfJe/GjK1LXEyVOoSI1N9JV9ZI923X5kup43W4= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= go.uber.org/zap v1.27.1 h1:08RqriUEv8+ArZRYSTXy1LeBScaMpVSTBhCeaZYfMYc= go.uber.org/zap v1.27.1/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= -golang.org/x/net v0.46.1-0.20251013234738-63d1a5100f82 h1:6/3JGEh1C88g7m+qzzTbl3A0FtsLguXieqofVLU/JAo= -golang.org/x/net v0.46.1-0.20251013234738-63d1a5100f82/go.mod h1:Q9BGdFy1y4nkUwiLvT5qtyhAnEHgnQ/zd8PfU6nc210= -golang.org/x/sys v0.40.0 h1:DBZZqJ2Rkml6QMQsZywtnjnnGvHza6BTfYFWY9kjEWQ= -golang.org/x/sys v0.40.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= -golang.org/x/text v0.30.0 h1:yznKA/E9zq54KzlzBEAWn1NXSQ8DIp/NYMy88xJjl4k= -golang.org/x/text v0.30.0/go.mod h1:yDdHFIX9t+tORqspjENWgzaCVXgk0yYnYuSZ8UzzBVM= -google.golang.org/genproto/googleapis/rpc v0.0.0-20251022142026-3a174f9686a8 h1:M1rk8KBnUsBDg1oPGHNCxG4vc1f49epmTO7xscSajMk= -google.golang.org/genproto/googleapis/rpc v0.0.0-20251022142026-3a174f9686a8/go.mod h1:7i2o+ce6H/6BluujYR+kqX3GKH+dChPTQU19wjRPiGk= -google.golang.org/grpc v1.77.0 h1:wVVY6/8cGA6vvffn+wWK5ToddbgdU3d8MNENr4evgXM= -google.golang.org/grpc v1.77.0/go.mod h1:z0BY1iVj0q8E1uSQCjL9cppRj+gnZjzDnzV0dHhrNig= -google.golang.org/protobuf v1.36.10 h1:AYd7cD/uASjIL6Q9LiTjz8JLcrh/88q5UObnmY3aOOE= -google.golang.org/protobuf v1.36.10/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= +golang.org/x/net v0.51.0 h1:94R/GTO7mt3/4wIKpcR5gkGmRLOuE/2hNGeWq/GBIFo= +golang.org/x/net v0.51.0/go.mod h1:aamm+2QF5ogm02fjy5Bb7CQ0WMt1/WVM7FtyaTLlA9Y= +golang.org/x/sys v0.41.0 h1:Ivj+2Cp/ylzLiEU89QhWblYnOE9zerudt9Ftecq2C6k= +golang.org/x/sys v0.41.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= +golang.org/x/text v0.34.0 h1:oL/Qq0Kdaqxa1KbNeMKwQq0reLCCaFtqu2eNuSeNHbk= +golang.org/x/text v0.34.0/go.mod h1:homfLqTYRFyVYemLBFl5GgL/DWEiH5wcsQ5gSh1yziA= +google.golang.org/genproto/googleapis/rpc v0.0.0-20251222181119-0a764e51fe1b h1:Mv8VFug0MP9e5vUxfBcE3vUkV6CImK3cMNMIDFjmzxU= +google.golang.org/genproto/googleapis/rpc v0.0.0-20251222181119-0a764e51fe1b/go.mod h1:j9x/tPzZkyxcgEFkiKEEGxfvyumM01BEtsW8xzOahRQ= +google.golang.org/grpc v1.79.3 h1:sybAEdRIEtvcD68Gx7dmnwjZKlyfuc61Dyo9pGXXkKE= +google.golang.org/grpc v1.79.3/go.mod h1:KmT0Kjez+0dde/v2j9vzwoAScgEPx/Bw1CYChhHLrHQ= +google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE= +google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= diff --git a/config/configcompression/config.schema.yaml b/config/configcompression/config.schema.yaml new file mode 100644 index 000000000000..0c089957fd84 --- /dev/null +++ b/config/configcompression/config.schema.yaml @@ -0,0 +1,11 @@ +$defs: + compression_params: + type: object + properties: + level: + $ref: level + level: + type: integer + type: + description: Type represents a compression method + type: string diff --git a/config/configcompression/go.mod b/config/configcompression/go.mod index 73791528737d..bc56bf0cdb9a 100644 --- a/config/configcompression/go.mod +++ b/config/configcompression/go.mod @@ -1,6 +1,6 @@ module go.opentelemetry.io/collector/config/configcompression -go 1.24.0 +go 1.25.0 require ( github.com/stretchr/testify v1.11.1 diff --git a/config/configgrpc/README.md b/config/configgrpc/README.md index e1e652591f6a..a30dda37999b 100644 --- a/config/configgrpc/README.md +++ b/config/configgrpc/README.md @@ -35,7 +35,7 @@ Example: ```yaml exporters: - otlp: + otlp_grpc: endpoint: otelcol2:55690 auth: authenticator: some-authenticator-extension @@ -86,7 +86,7 @@ The following table summarizes the results, including some additional columns co Compression ratios will vary in practice as they are highly dependent on the data's information entropy. Compression rates are dependent on the speed of the CPU, and the size of payloads being compressed: smaller payloads compress at slower rates relative to larger payloads, which are able to amortize fixed computation costs over more bytes. -`gzip` is the only required compression algorithm required for [OTLP servers](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/protocol/otlp.md#protocol-details), and is a natural first choice. It is not as fast as `snappy`, but achieves better compression ratios and has reasonable performance. If your collector is CPU bound and your OTLP server supports it, you may benefit from using `snappy` compression. If your collector is CPU bound and has a very fast network link, you may benefit from disabling compression, which is the default. +`gzip` is the only required compression algorithm required for [OTLP servers](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/protocol/otlp.md), and is a natural first choice. It is not as fast as `snappy`, but achieves better compression ratios and has reasonable performance. If your collector is CPU bound and your OTLP server supports it, you may benefit from using `snappy` compression. If your collector is CPU bound and has a very fast network link, you may benefit from disabling compression, which is the default. ## Server Configuration diff --git a/config/configgrpc/client_middleware_test.go b/config/configgrpc/client_middleware_test.go index 7ddb99ba164f..58fedd609003 100644 --- a/config/configgrpc/client_middleware_test.go +++ b/config/configgrpc/client_middleware_test.go @@ -40,7 +40,7 @@ func newTestMiddlewareConfig(name string) configmiddleware.Config { func newTestClientMiddleware(name string) extension.Extension { return &testClientMiddleware{ Extension: extensionmiddlewaretest.NewNop(), - GetGRPCClientOptionsFunc: func() ([]grpc.DialOption, error) { + GetGRPCClientOptionsFunc: func(_ context.Context) ([]grpc.DialOption, error) { return []grpc.DialOption{ grpc.WithChainUnaryInterceptor( func( diff --git a/config/configgrpc/config.schema.yaml b/config/configgrpc/config.schema.yaml new file mode 100644 index 000000000000..0419d72486f1 --- /dev/null +++ b/config/configgrpc/config.schema.yaml @@ -0,0 +1,142 @@ +$defs: + client_config: + description: ClientConfig defines common settings for a gRPC client configuration. + type: object + properties: + auth: + description: Auth configuration for outgoing RPCs. + x-optional: true + $ref: go.opentelemetry.io/collector/config/configauth.config + authority: + description: WithAuthority parameter configures client to rewrite ":authority" header (godoc.org/google.golang.org/grpc#WithAuthority) + type: string + balancer_name: + description: Sets the balancer in grpclb_policy to discover the servers. Default is pick_first. https://github.com/grpc/grpc-go/blob/master/examples/features/load_balancing/README.md + type: string + compression: + description: The compression key for supported compression types within collector. + $ref: go.opentelemetry.io/collector/config/configcompression.type + endpoint: + description: The target to which the exporter is going to send traces or metrics, using the gRPC protocol. The valid syntax is described at https://github.com/grpc/grpc/blob/master/doc/naming.md. + type: string + headers: + description: The headers associated with gRPC requests. + $ref: go.opentelemetry.io/collector/config/configopaque.map_list + keepalive: + description: The keepalive parameters for gRPC client. See grpc.WithKeepaliveParams. (https://godoc.org/google.golang.org/grpc#WithKeepaliveParams). + x-optional: true + $ref: keepalive_client_config + middlewares: + description: Middlewares for the gRPC client. + type: array + items: + $ref: go.opentelemetry.io/collector/config/configmiddleware.config + read_buffer_size: + description: ReadBufferSize for gRPC client. See grpc.WithReadBufferSize. (https://godoc.org/google.golang.org/grpc#WithReadBufferSize). + type: integer + tls: + description: TLS struct exposes TLS client configuration. + $ref: go.opentelemetry.io/collector/config/configtls.client_config + wait_for_ready: + description: WaitForReady parameter configures client to wait for ready state before sending data. (https://github.com/grpc/grpc/blob/master/doc/wait-for-ready.md) + type: boolean + write_buffer_size: + description: WriteBufferSize for gRPC gRPC. See grpc.WithWriteBufferSize. (https://godoc.org/google.golang.org/grpc#WithWriteBufferSize). + type: integer + keepalive_client_config: + description: 'KeepaliveClientConfig exposes the keepalive.ClientParameters to be used by the exporter. Refer to the original data-structure for the meaning of each parameter: https://godoc.org/google.golang.org/grpc/keepalive#ClientParameters' + type: object + properties: + permit_without_stream: + type: boolean + time: + type: string + x-customType: time.Duration + format: duration + timeout: + type: string + x-customType: time.Duration + format: duration + keepalive_enforcement_policy: + description: KeepaliveEnforcementPolicy allow configuration of the keepalive.EnforcementPolicy. The same default values as keepalive.EnforcementPolicy are applicable and get applied by the server. See https://godoc.org/google.golang.org/grpc/keepalive#EnforcementPolicy for details. + type: object + properties: + min_time: + type: string + x-customType: time.Duration + format: duration + permit_without_stream: + type: boolean + keepalive_server_config: + description: KeepaliveServerConfig is the configuration for keepalive. + type: object + properties: + enforcement_policy: + x-optional: true + $ref: keepalive_enforcement_policy + server_parameters: + x-optional: true + $ref: keepalive_server_parameters + keepalive_server_parameters: + description: KeepaliveServerParameters allow configuration of the keepalive.ServerParameters. The same default values as keepalive.ServerParameters are applicable and get applied by the server. See https://godoc.org/google.golang.org/grpc/keepalive#ServerParameters for details. + type: object + properties: + max_connection_age: + type: string + x-customType: time.Duration + format: duration + max_connection_age_grace: + type: string + x-customType: time.Duration + format: duration + max_connection_idle: + type: string + x-customType: time.Duration + format: duration + time: + type: string + x-customType: time.Duration + format: duration + timeout: + type: string + x-customType: time.Duration + format: duration + server_config: + description: ServerConfig defines common settings for a gRPC server configuration. + type: object + properties: + auth: + description: Auth for this receiver + x-optional: true + $ref: go.opentelemetry.io/collector/config/configauth.config + include_metadata: + description: Include propagates the incoming connection's metadata to downstream consumers. + type: boolean + keepalive: + description: Keepalive anchor for all the settings related to keepalive. + x-optional: true + $ref: keepalive_server_config + max_concurrent_streams: + description: MaxConcurrentStreams sets the limit on the number of concurrent streams to each ServerTransport. It has effect only for streaming RPCs. + type: integer + x-customType: uint32 + max_recv_msg_size_mib: + description: MaxRecvMsgSizeMiB sets the maximum size (in MiB) of messages accepted by the server. + type: integer + middlewares: + description: Middlewares for the gRPC server. + type: array + items: + $ref: go.opentelemetry.io/collector/config/configmiddleware.config + read_buffer_size: + description: ReadBufferSize for gRPC server. See grpc.ReadBufferSize. (https://godoc.org/google.golang.org/grpc#ReadBufferSize). + type: integer + tls: + description: Configures the protocol to use TLS. The default value is nil, which will cause the protocol to not use TLS. + x-optional: true + $ref: go.opentelemetry.io/collector/config/configtls.server_config + write_buffer_size: + description: WriteBufferSize for gRPC server. See grpc.WriteBufferSize. (https://godoc.org/google.golang.org/grpc#WriteBufferSize). + type: integer + allOf: + - $ref: go.opentelemetry.io/collector/config/confignet.addr_config diff --git a/config/configgrpc/configgrpc.go b/config/configgrpc/configgrpc.go index 1d7284831884..092317952096 100644 --- a/config/configgrpc/configgrpc.go +++ b/config/configgrpc/configgrpc.go @@ -9,6 +9,9 @@ import ( "errors" "fmt" "math" + "net" + "regexp" + "strconv" "strings" "time" @@ -224,6 +227,24 @@ func NewDefaultServerConfig() ServerConfig { } func (cc *ClientConfig) Validate() error { + if after, ok := strings.CutPrefix(cc.Endpoint, "unix://"); ok { + if after == "" { + return errors.New("unix socket path cannot be empty") + } + return nil + } + + if endpoint := cc.sanitizedEndpoint(); endpoint != "" { + // Validate that the port is in the address + _, port, err := net.SplitHostPort(endpoint) + if err != nil { + return err + } + if _, err := strconv.Atoi(port); err != nil { + return fmt.Errorf(`invalid port "%v"`, port) + } + } + if cc.BalancerName != "" { if balancer.Get(cc.BalancerName) == nil { return fmt.Errorf("invalid balancer_name: %s", cc.BalancerName) @@ -240,6 +261,9 @@ func (cc *ClientConfig) sanitizedEndpoint() string { return strings.TrimPrefix(cc.Endpoint, "http://") case cc.isSchemeHTTPS(): return strings.TrimPrefix(cc.Endpoint, "https://") + case strings.HasPrefix(cc.Endpoint, "dns://"): + r := regexp.MustCompile(`^dns:///?`) + return r.ReplaceAllString(cc.Endpoint, "") default: return cc.Endpoint } @@ -286,8 +310,16 @@ func (cc *ClientConfig) ToClientConn( if err != nil { return nil, err } - //nolint:staticcheck // SA1019 see https://github.com/open-telemetry/opentelemetry-collector/pull/11575 - return grpc.DialContext(ctx, cc.sanitizedEndpoint(), grpcOpts...) + conn, err := grpc.NewClient(cc.sanitizedEndpoint(), grpcOpts...) + if err != nil { + return nil, err + } + + // Initiate connection to match the previous behavior of DialContext + // This ensures the connection is established eagerly rather than lazily + conn.Connect() + + return conn, nil } func (cc *ClientConfig) addHeadersIfAbsent(ctx context.Context) context.Context { @@ -525,6 +557,10 @@ func (sc *ServerConfig) getGrpcServerOptions( var uInterceptors []grpc.UnaryServerInterceptor var sInterceptors []grpc.StreamServerInterceptor + // Add client info first, before auth. + uInterceptors = append(uInterceptors, enhanceWithClientInformation(sc.IncludeMetadata)) + sInterceptors = append(sInterceptors, enhanceStreamWithClientInformation(sc.IncludeMetadata)) //nolint:contextcheck // context already handled + if sc.Auth.HasValue() { authenticator, err := sc.Auth.Get().GetServerAuthenticator(ctx, extensions) if err != nil { @@ -542,10 +578,6 @@ func (sc *ServerConfig) getGrpcServerOptions( } // Enable OpenTelemetry observability plugin. - - uInterceptors = append(uInterceptors, enhanceWithClientInformation(sc.IncludeMetadata)) - sInterceptors = append(sInterceptors, enhanceStreamWithClientInformation(sc.IncludeMetadata)) //nolint:contextcheck // context already handled - opts = append(opts, grpc.StatsHandler(otelgrpc.NewServerHandler(otelOpts...)), grpc.ChainUnaryInterceptor(uInterceptors...), grpc.ChainStreamInterceptor(sInterceptors...)) // Apply middleware options. Note: OpenTelemetry could be registered as an extension. diff --git a/config/configgrpc/configgrpc_test.go b/config/configgrpc/configgrpc_test.go index bbcc3581ca1e..08d075a62a4a 100644 --- a/config/configgrpc/configgrpc_test.go +++ b/config/configgrpc/configgrpc_test.go @@ -263,6 +263,24 @@ func TestAllGrpcClientSettings(t *testing.T) { } } +func TestSanitizeEndpoint(t *testing.T) { + cfg := NewDefaultClientConfig() + cfg.Endpoint = "dns://authority/backend.example.com:4317" + assert.Equal(t, "authority/backend.example.com:4317", cfg.sanitizedEndpoint()) + cfg.Endpoint = "dns:///backend.example.com:4317" + assert.Equal(t, "backend.example.com:4317", cfg.sanitizedEndpoint()) + cfg.Endpoint = "dns:////backend.example.com:4317" + assert.Equal(t, "/backend.example.com:4317", cfg.sanitizedEndpoint()) +} + +func TestValidateEndpoint(t *testing.T) { + cfg := NewDefaultClientConfig() + cfg.Endpoint = "dns://authority/backend.example.com:4317" + assert.NoError(t, cfg.Validate()) + cfg.Endpoint = "unix:///my/unix/socket.sock" + assert.NoError(t, cfg.Validate()) +} + func TestHeaders(t *testing.T) { traceServer := &grpcTraceServer{} server, addr := traceServer.startTestServer(t, configoptional.Some(ServerConfig{ @@ -457,7 +475,7 @@ func TestGRPCClientSettingsError(t *testing.T) { err: "failed to load TLS config: failed to load CA CertPool File: failed to load cert /doesnt/exist:", settings: ClientConfig{ Headers: nil, - Endpoint: "", + Endpoint: "localhost:1234", Compression: "", TLS: configtls.ClientConfig{ Config: configtls.Config{ @@ -472,7 +490,7 @@ func TestGRPCClientSettingsError(t *testing.T) { err: "failed to load TLS config: failed to load TLS cert and key: for auth via TLS, provide both certificate and key, or neither", settings: ClientConfig{ Headers: nil, - Endpoint: "", + Endpoint: "localhost:1234", Compression: "", TLS: configtls.ClientConfig{ Config: configtls.Config{ @@ -616,7 +634,7 @@ func TestGRPCServerSettings_ToListener_Error(t *testing.T) { assert.Error(t, err) } -func TestHttpReception(t *testing.T) { +func TestHTTPReception(t *testing.T) { tests := []struct { name string tlsServerCreds configoptional.Optional[configtls.ServerConfig] @@ -963,22 +981,74 @@ func TestClientInfoInterceptors(t *testing.T) { } } +func TestClientInfoInterceptorBeforeAuth(t *testing.T) { + mock := &grpcTraceServer{} + var addr string + var authCalled bool + + type serverAuthExtension struct { + component.StartFunc + component.ShutdownFunc + extensionauth.Server + } + + // prepare the server + { + var srv *grpc.Server + srv, addr = mock.startTestServerWithExtensions(t, configoptional.Some(ServerConfig{ + NetAddr: confignet.AddrConfig{ + Endpoint: "localhost:0", + Transport: confignet.TransportTypeTCP, + }, + Auth: configoptional.Some(configauth.Config{ + AuthenticatorID: mockID, + }), + }), map[component.ID]component.Component{ + mockID: serverAuthExtension{ + Server: newMockAuthServer( + func(ctx context.Context, _ map[string][]string) (context.Context, error) { + // verify that client info is populated before auth + authCalled = true + cl := client.FromContext(ctx) + assert.NotNil(t, cl.Addr) + return ctx, nil + }, + ), + }, + }) + defer srv.Stop() + } + + // prepare the client and execute a RPC + { + _, errResp := sendTestRequest(t, ClientConfig{ + Endpoint: addr, + TLS: configtls.ClientConfig{ + Insecure: true, + }, + }) + require.NoError(t, errResp) + } + + assert.True(t, authCalled) +} + func TestDefaultUnaryInterceptorAuthSucceeded(t *testing.T) { // prepare handlerCalled := false authCalled := false - authFunc := func(context.Context, map[string][]string) (context.Context, error) { + expectedAuthData := new(struct{ client.AuthData }) + authFunc := func(ctx context.Context, _ map[string][]string) (context.Context, error) { authCalled = true - ctx := client.NewContext(context.Background(), client.Info{ - Addr: &net.IPAddr{IP: net.IPv4(1, 2, 3, 4)}, - }) - + cl := client.FromContext(ctx) + cl.Auth = expectedAuthData + ctx = client.NewContext(ctx, cl) return ctx, nil } handler := func(ctx context.Context, _ any) (any, error) { handlerCalled = true cl := client.FromContext(ctx) - assert.Equal(t, "1.2.3.4", cl.Addr.String()) + assert.Equal(t, expectedAuthData, cl.Auth) return nil, nil } ctx := metadata.NewIncomingContext(context.Background(), metadata.Pairs("authorization", "some-auth-data")) @@ -1068,17 +1138,18 @@ func TestDefaultStreamInterceptorAuthSucceeded(t *testing.T) { // prepare handlerCalled := false authCalled := false - authFunc := func(context.Context, map[string][]string) (context.Context, error) { + expectedAuthData := new(struct{ client.AuthData }) + authFunc := func(ctx context.Context, _ map[string][]string) (context.Context, error) { authCalled = true - ctx := client.NewContext(context.Background(), client.Info{ - Addr: &net.IPAddr{IP: net.IPv4(1, 2, 3, 4)}, - }) + cl := client.FromContext(ctx) + cl.Auth = expectedAuthData + ctx = client.NewContext(ctx, cl) return ctx, nil } handler := func(_ any, stream grpc.ServerStream) error { // ensure that the client information is propagated down to the underlying stream cl := client.FromContext(stream.Context()) - assert.Equal(t, "1.2.3.4", cl.Addr.String()) + assert.Equal(t, expectedAuthData, cl.Auth) handlerCalled = true return nil } diff --git a/config/configgrpc/go.mod b/config/configgrpc/go.mod index f2c9bf8e5005..a458d6b387a6 100644 --- a/config/configgrpc/go.mod +++ b/config/configgrpc/go.mod @@ -1,74 +1,75 @@ module go.opentelemetry.io/collector/config/configgrpc -go 1.24.0 +go 1.25.0 require ( github.com/mostynb/go-grpc-compression v1.2.3 github.com/stretchr/testify v1.11.1 go.opentelemetry.io/collector/client v1.46.0 - go.opentelemetry.io/collector/component v1.46.0 + go.opentelemetry.io/collector/component v1.54.0 go.opentelemetry.io/collector/component/componenttest v0.140.0 go.opentelemetry.io/collector/config/configauth v1.46.0 go.opentelemetry.io/collector/config/configcompression v1.46.0 go.opentelemetry.io/collector/config/configmiddleware v1.46.0 go.opentelemetry.io/collector/config/confignet v1.46.0 - go.opentelemetry.io/collector/config/configopaque v1.46.0 + go.opentelemetry.io/collector/config/configopaque v1.54.0 go.opentelemetry.io/collector/config/configoptional v1.46.0 go.opentelemetry.io/collector/config/configtls v1.46.0 - go.opentelemetry.io/collector/extension v1.46.0 - go.opentelemetry.io/collector/extension/extensionauth v1.46.0 - go.opentelemetry.io/collector/extension/extensionauth/extensionauthtest v0.140.0 - go.opentelemetry.io/collector/extension/extensionmiddleware v0.140.0 - go.opentelemetry.io/collector/extension/extensionmiddleware/extensionmiddlewaretest v0.140.0 - go.opentelemetry.io/collector/pdata v1.46.0 + go.opentelemetry.io/collector/extension v1.54.0 + go.opentelemetry.io/collector/extension/extensionauth v1.54.0 + go.opentelemetry.io/collector/extension/extensionauth/extensionauthtest v0.148.0 + go.opentelemetry.io/collector/extension/extensionmiddleware v0.148.0 + go.opentelemetry.io/collector/extension/extensionmiddleware/extensionmiddlewaretest v0.148.0 + go.opentelemetry.io/collector/pdata v1.54.0 go.opentelemetry.io/collector/pdata/testdata v0.140.0 go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.63.0 - go.opentelemetry.io/otel v1.40.0 + go.opentelemetry.io/otel v1.42.0 go.uber.org/goleak v1.3.0 - google.golang.org/grpc v1.77.0 + google.golang.org/grpc v1.79.3 ) require ( github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/davecgh/go-spew v1.1.1 // indirect - github.com/foxboron/go-tpm-keyfiles v0.0.0-20250903184740-5d135037bd4d // indirect + github.com/foxboron/go-tpm-keyfiles v0.0.0-20251226215517-609e4778396f // indirect github.com/fsnotify/fsnotify v1.9.0 // indirect github.com/go-logr/logr v1.4.3 // indirect github.com/go-logr/stdr v1.2.2 // indirect - github.com/go-viper/mapstructure/v2 v2.4.0 // indirect + github.com/go-viper/mapstructure/v2 v2.5.0 // indirect github.com/gobwas/glob v0.2.3 // indirect github.com/golang/snappy v0.0.4 // indirect - github.com/google/go-tpm v0.9.7 // indirect + github.com/google/go-tpm v0.9.8 // indirect github.com/google/uuid v1.6.0 // indirect - github.com/hashicorp/go-version v1.7.0 // indirect + github.com/hashicorp/go-version v1.8.0 // indirect github.com/json-iterator/go v1.1.12 // indirect github.com/klauspost/compress v1.17.9 // indirect github.com/knadh/koanf/maps v0.1.2 // indirect github.com/knadh/koanf/providers/confmap v1.0.0 // indirect - github.com/knadh/koanf/v2 v2.3.0 // indirect + github.com/knadh/koanf/v2 v2.3.3 // indirect github.com/mitchellh/copystructure v1.2.0 // indirect github.com/mitchellh/reflectwalk v1.0.2 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee // indirect github.com/pmezard/go-difflib v1.0.0 // indirect go.opentelemetry.io/auto/sdk v1.2.1 // indirect - go.opentelemetry.io/collector/confmap v1.46.0 // indirect - go.opentelemetry.io/collector/confmap/xconfmap v0.140.0 // indirect - go.opentelemetry.io/collector/featuregate v1.46.0 // indirect - go.opentelemetry.io/collector/pdata/pprofile v0.140.0 // indirect - go.opentelemetry.io/otel/metric v1.40.0 // indirect + go.opentelemetry.io/collector/confmap v1.54.0 // indirect + go.opentelemetry.io/collector/confmap/xconfmap v0.148.0 // indirect + go.opentelemetry.io/collector/featuregate v1.54.0 // indirect + go.opentelemetry.io/collector/internal/componentalias v0.148.0 // indirect + go.opentelemetry.io/collector/pdata/pprofile v0.148.0 // indirect + go.opentelemetry.io/otel/metric v1.42.0 // indirect go.opentelemetry.io/otel/sdk v1.40.0 // indirect go.opentelemetry.io/otel/sdk/metric v1.40.0 // indirect - go.opentelemetry.io/otel/trace v1.40.0 // indirect + go.opentelemetry.io/otel/trace v1.42.0 // indirect go.uber.org/multierr v1.11.0 // indirect go.uber.org/zap v1.27.1 // indirect go.yaml.in/yaml/v3 v3.0.4 // indirect - golang.org/x/crypto v0.45.0 // indirect - golang.org/x/net v0.47.0 // indirect - golang.org/x/sys v0.40.0 // indirect - golang.org/x/text v0.31.0 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20251022142026-3a174f9686a8 // indirect - google.golang.org/protobuf v1.36.10 // indirect + golang.org/x/crypto v0.48.0 // indirect + golang.org/x/net v0.51.0 // indirect + golang.org/x/sys v0.41.0 // indirect + golang.org/x/text v0.34.0 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20251222181119-0a764e51fe1b // indirect + google.golang.org/protobuf v1.36.11 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) @@ -117,3 +118,5 @@ replace go.opentelemetry.io/collector/confmap => ../../confmap replace go.opentelemetry.io/collector/confmap/xconfmap => ../../confmap/xconfmap replace go.opentelemetry.io/collector/internal/testutil => ../../internal/testutil + +replace go.opentelemetry.io/collector/internal/componentalias => ../../internal/componentalias diff --git a/config/configgrpc/go.sum b/config/configgrpc/go.sum index 59e76e05b1de..b193eede3b37 100644 --- a/config/configgrpc/go.sum +++ b/config/configgrpc/go.sum @@ -3,10 +3,8 @@ github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XL github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/foxboron/go-tpm-keyfiles v0.0.0-20250903184740-5d135037bd4d h1:EdO/NMMuCZfxhdzTZLuKAciQSnI2DV+Ppg8+vAYrnqA= -github.com/foxboron/go-tpm-keyfiles v0.0.0-20250903184740-5d135037bd4d/go.mod h1:uAyTlAUxchYuiFjTHmuIEJ4nGSm7iOPaGcAyA81fJ80= -github.com/foxboron/swtpm_test v0.0.0-20230726224112-46aaafdf7006 h1:50sW4r0PcvlpG4PV8tYh2RVCapszJgaOLRCS2subvV4= -github.com/foxboron/swtpm_test v0.0.0-20230726224112-46aaafdf7006/go.mod h1:eIXCMsMYCaqq9m1KSSxXwQG11krpuNPGP3k0uaWrbas= +github.com/foxboron/go-tpm-keyfiles v0.0.0-20251226215517-609e4778396f h1:RJ+BDPLSHQO7cSjKBqjPJSbi1qfk9WcsjQDtZiw3dZw= +github.com/foxboron/go-tpm-keyfiles v0.0.0-20251226215517-609e4778396f/go.mod h1:VHbbch/X4roIY22jL1s3qRbZhCiRIgUAF/PdSUcx2io= github.com/fsnotify/fsnotify v1.9.0 h1:2Ml+OJNzbYCTzsxtv8vKSFD9PbJjmhYF14k/jKC7S9k= github.com/fsnotify/fsnotify v1.9.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= @@ -14,8 +12,8 @@ github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI= github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= -github.com/go-viper/mapstructure/v2 v2.4.0 h1:EBsztssimR/CONLSZZ04E8qAkxNYq4Qp9LvH92wZUgs= -github.com/go-viper/mapstructure/v2 v2.4.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM= +github.com/go-viper/mapstructure/v2 v2.5.0 h1:vM5IJoUAy3d7zRSVtIwQgBj7BiWtMPfmPEgAXnvj1Ro= +github.com/go-viper/mapstructure/v2 v2.5.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM= github.com/gobwas/glob v0.2.3 h1:A4xDbljILXROh+kObIiy5kIaPYD8e96x1tgBhUI5J+Y= github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8= github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= @@ -24,15 +22,15 @@ github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM= github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= -github.com/google/go-tpm v0.9.7 h1:u89J4tUUeDTlH8xxC3CTW7OHZjbjKoHdQ9W7gCUhtxA= -github.com/google/go-tpm v0.9.7/go.mod h1:h9jEsEECg7gtLis0upRBQU+GhYVH6jMjrFxI8u6bVUY= -github.com/google/go-tpm-tools v0.4.4 h1:oiQfAIkc6xTy9Fl5NKTeTJkBTlXdHsxAofmQyxBKY98= -github.com/google/go-tpm-tools v0.4.4/go.mod h1:T8jXkp2s+eltnCDIsXR84/MTcVU9Ja7bh3Mit0pa4AY= +github.com/google/go-tpm v0.9.8 h1:slArAR9Ft+1ybZu0lBwpSmpwhRXaa85hWtMinMyRAWo= +github.com/google/go-tpm v0.9.8/go.mod h1:h9jEsEECg7gtLis0upRBQU+GhYVH6jMjrFxI8u6bVUY= +github.com/google/go-tpm-tools v0.4.7 h1:J3ycC8umYxM9A4eF73EofRZu4BxY0jjQnUnkhIBbvws= +github.com/google/go-tpm-tools v0.4.7/go.mod h1:gSyXTZHe3fgbzb6WEGd90QucmsnT1SRdlye82gH8QjQ= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/hashicorp/go-version v1.7.0 h1:5tqGy27NaOTB8yJKUZELlFAS/LTKJkrmONwQKeRZfjY= -github.com/hashicorp/go-version v1.7.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= +github.com/hashicorp/go-version v1.8.0 h1:KAkNb1HAiZd1ukkxDFGmokVZe1Xy9HG6NUp+bPle2i4= +github.com/hashicorp/go-version v1.8.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= github.com/klauspost/compress v1.17.9 h1:6KIumPrER1LHsvBVuDa0r5xaG0Es51mhhB9BQB2qeMA= @@ -41,8 +39,8 @@ github.com/knadh/koanf/maps v0.1.2 h1:RBfmAW5CnZT+PJ1CVc1QSJKf4Xu9kxfQgYVQSu8hpb github.com/knadh/koanf/maps v0.1.2/go.mod h1:npD/QZY3V6ghQDdcQzl1W4ICNVTkohC8E73eI2xW4yI= github.com/knadh/koanf/providers/confmap v1.0.0 h1:mHKLJTE7iXEys6deO5p6olAiZdG5zwp8Aebir+/EaRE= github.com/knadh/koanf/providers/confmap v1.0.0/go.mod h1:txHYHiI2hAtF0/0sCmcuol4IDcuQbKTybiB1nOcUo1A= -github.com/knadh/koanf/v2 v2.3.0 h1:Qg076dDRFHvqnKG97ZEsi9TAg2/nFTa9hCdcSa1lvlM= -github.com/knadh/koanf/v2 v2.3.0/go.mod h1:gRb40VRAbd4iJMYYD5IxZ6hfuopFcXBpc9bbQpZwo28= +github.com/knadh/koanf/v2 v2.3.3 h1:jLJC8XCRfLC7n4F+ZKKdBsbq1bfXTpuFhf4L7t94D94= +github.com/knadh/koanf/v2 v2.3.3/go.mod h1:gRb40VRAbd4iJMYYD5IxZ6hfuopFcXBpc9bbQpZwo28= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= @@ -71,22 +69,22 @@ go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y= go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.63.0 h1:YH4g8lQroajqUwWbq/tr2QX1JFmEXaDLgG+ew9bLMWo= go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.63.0/go.mod h1:fvPi2qXDqFs8M4B4fmJhE92TyQs9Ydjlg3RvfUp+NbQ= -go.opentelemetry.io/otel v1.40.0 h1:oA5YeOcpRTXq6NN7frwmwFR0Cn3RhTVZvXsP4duvCms= -go.opentelemetry.io/otel v1.40.0/go.mod h1:IMb+uXZUKkMXdPddhwAHm6UfOwJyh4ct1ybIlV14J0g= -go.opentelemetry.io/otel/metric v1.40.0 h1:rcZe317KPftE2rstWIBitCdVp89A2HqjkxR3c11+p9g= -go.opentelemetry.io/otel/metric v1.40.0/go.mod h1:ib/crwQH7N3r5kfiBZQbwrTge743UDc7DTFVZrrXnqc= +go.opentelemetry.io/otel v1.42.0 h1:lSQGzTgVR3+sgJDAU/7/ZMjN9Z+vUip7leaqBKy4sho= +go.opentelemetry.io/otel v1.42.0/go.mod h1:lJNsdRMxCUIWuMlVJWzecSMuNjE7dOYyWlqOXWkdqCc= +go.opentelemetry.io/otel/metric v1.42.0 h1:2jXG+3oZLNXEPfNmnpxKDeZsFI5o4J+nz6xUlaFdF/4= +go.opentelemetry.io/otel/metric v1.42.0/go.mod h1:RlUN/7vTU7Ao/diDkEpQpnz3/92J9ko05BIwxYa2SSI= go.opentelemetry.io/otel/sdk v1.40.0 h1:KHW/jUzgo6wsPh9At46+h4upjtccTmuZCFAc9OJ71f8= go.opentelemetry.io/otel/sdk v1.40.0/go.mod h1:Ph7EFdYvxq72Y8Li9q8KebuYUr2KoeyHx0DRMKrYBUE= go.opentelemetry.io/otel/sdk/metric v1.40.0 h1:mtmdVqgQkeRxHgRv4qhyJduP3fYJRMX4AtAlbuWdCYw= go.opentelemetry.io/otel/sdk/metric v1.40.0/go.mod h1:4Z2bGMf0KSK3uRjlczMOeMhKU2rhUqdWNoKcYrtcBPg= -go.opentelemetry.io/otel/trace v1.40.0 h1:WA4etStDttCSYuhwvEa8OP8I5EWu24lkOzp+ZYblVjw= -go.opentelemetry.io/otel/trace v1.40.0/go.mod h1:zeAhriXecNGP/s2SEG3+Y8X9ujcJOTqQ5RgdEJcawiA= -go.opentelemetry.io/proto/slim/otlp v1.9.0 h1:fPVMv8tP3TrsqlkH1HWYUpbCY9cAIemx184VGkS6vlE= -go.opentelemetry.io/proto/slim/otlp v1.9.0/go.mod h1:xXdeJJ90Gqyll+orzUkY4bOd2HECo5JofeoLpymVqdI= -go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.2.0 h1:o13nadWDNkH/quoDomDUClnQBpdQQ2Qqv0lQBjIXjE8= -go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.2.0/go.mod h1:Gyb6Xe7FTi/6xBHwMmngGoHqL0w29Y4eW8TGFzpefGA= -go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.2.0 h1:EiUYvtwu6PMrMHVjcPfnsG3v+ajPkbUeH+IL93+QYyk= -go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.2.0/go.mod h1:mUUHKFiN2SST3AhJ8XhJxEoeVW12oqfXog0Bo8W3Ec4= +go.opentelemetry.io/otel/trace v1.42.0 h1:OUCgIPt+mzOnaUTpOQcBiM/PLQ/Op7oq6g4LenLmOYY= +go.opentelemetry.io/otel/trace v1.42.0/go.mod h1:f3K9S+IFqnumBkKhRJMeaZeNk9epyhnCmQh/EysQCdc= +go.opentelemetry.io/proto/slim/otlp v1.10.0 h1:iR97Vs/ZDR+y9TfuP9b1XBtdPWeC+OMslIBmhcLU7jM= +go.opentelemetry.io/proto/slim/otlp v1.10.0/go.mod h1:lV9250stpjYLPNA5viFabIgP2QlUGRT1GdTgAf8SIUk= +go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.3.0 h1:RUF5rO0hAlgiJt1fzQVzcVs3vZVNHIcMLgOgG4rWNcQ= +go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.3.0/go.mod h1:I89cynRj8y+383o7tEQVg2SVA6SRgDVIouWPUVXjx0U= +go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.3.0 h1:CQvJSldHRUN6Z8jsUeYv8J0lXRvygALXIzsmAeCcZE0= +go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.3.0/go.mod h1:xSQ+mEfJe/GjK1LXEyVOoSI1N9JV9ZI923X5kup43W4= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= @@ -95,22 +93,22 @@ go.uber.org/zap v1.27.1 h1:08RqriUEv8+ArZRYSTXy1LeBScaMpVSTBhCeaZYfMYc= go.uber.org/zap v1.27.1/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc= go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg= -golang.org/x/crypto v0.45.0 h1:jMBrvKuj23MTlT0bQEOBcAE0mjg8mK9RXFhRH6nyF3Q= -golang.org/x/crypto v0.45.0/go.mod h1:XTGrrkGJve7CYK7J8PEww4aY7gM3qMCElcJQ8n8JdX4= -golang.org/x/net v0.47.0 h1:Mx+4dIFzqraBXUugkia1OOvlD6LemFo1ALMHjrXDOhY= -golang.org/x/net v0.47.0/go.mod h1:/jNxtkgq5yWUGYkaZGqo27cfGZ1c5Nen03aYrrKpVRU= -golang.org/x/sys v0.40.0 h1:DBZZqJ2Rkml6QMQsZywtnjnnGvHza6BTfYFWY9kjEWQ= -golang.org/x/sys v0.40.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= -golang.org/x/text v0.31.0 h1:aC8ghyu4JhP8VojJ2lEHBnochRno1sgL6nEi9WGFGMM= -golang.org/x/text v0.31.0/go.mod h1:tKRAlv61yKIjGGHX/4tP1LTbc13YSec1pxVEWXzfoeM= +golang.org/x/crypto v0.48.0 h1:/VRzVqiRSggnhY7gNRxPauEQ5Drw9haKdM0jqfcCFts= +golang.org/x/crypto v0.48.0/go.mod h1:r0kV5h3qnFPlQnBSrULhlsRfryS2pmewsg+XfMgkVos= +golang.org/x/net v0.51.0 h1:94R/GTO7mt3/4wIKpcR5gkGmRLOuE/2hNGeWq/GBIFo= +golang.org/x/net v0.51.0/go.mod h1:aamm+2QF5ogm02fjy5Bb7CQ0WMt1/WVM7FtyaTLlA9Y= +golang.org/x/sys v0.41.0 h1:Ivj+2Cp/ylzLiEU89QhWblYnOE9zerudt9Ftecq2C6k= +golang.org/x/sys v0.41.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= +golang.org/x/text v0.34.0 h1:oL/Qq0Kdaqxa1KbNeMKwQq0reLCCaFtqu2eNuSeNHbk= +golang.org/x/text v0.34.0/go.mod h1:homfLqTYRFyVYemLBFl5GgL/DWEiH5wcsQ5gSh1yziA= gonum.org/v1/gonum v0.16.0 h1:5+ul4Swaf3ESvrOnidPp4GZbzf0mxVQpDCYUQE7OJfk= gonum.org/v1/gonum v0.16.0/go.mod h1:fef3am4MQ93R2HHpKnLk4/Tbh/s0+wqD5nfa6Pnwy4E= -google.golang.org/genproto/googleapis/rpc v0.0.0-20251022142026-3a174f9686a8 h1:M1rk8KBnUsBDg1oPGHNCxG4vc1f49epmTO7xscSajMk= -google.golang.org/genproto/googleapis/rpc v0.0.0-20251022142026-3a174f9686a8/go.mod h1:7i2o+ce6H/6BluujYR+kqX3GKH+dChPTQU19wjRPiGk= -google.golang.org/grpc v1.77.0 h1:wVVY6/8cGA6vvffn+wWK5ToddbgdU3d8MNENr4evgXM= -google.golang.org/grpc v1.77.0/go.mod h1:z0BY1iVj0q8E1uSQCjL9cppRj+gnZjzDnzV0dHhrNig= -google.golang.org/protobuf v1.36.10 h1:AYd7cD/uASjIL6Q9LiTjz8JLcrh/88q5UObnmY3aOOE= -google.golang.org/protobuf v1.36.10/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= +google.golang.org/genproto/googleapis/rpc v0.0.0-20251222181119-0a764e51fe1b h1:Mv8VFug0MP9e5vUxfBcE3vUkV6CImK3cMNMIDFjmzxU= +google.golang.org/genproto/googleapis/rpc v0.0.0-20251222181119-0a764e51fe1b/go.mod h1:j9x/tPzZkyxcgEFkiKEEGxfvyumM01BEtsW8xzOahRQ= +google.golang.org/grpc v1.79.3 h1:sybAEdRIEtvcD68Gx7dmnwjZKlyfuc61Dyo9pGXXkKE= +google.golang.org/grpc v1.79.3/go.mod h1:KmT0Kjez+0dde/v2j9vzwoAScgEPx/Bw1CYChhHLrHQ= +google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE= +google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= diff --git a/config/configgrpc/server_middleware_test.go b/config/configgrpc/server_middleware_test.go index c62748c78be0..3512445fa490 100644 --- a/config/configgrpc/server_middleware_test.go +++ b/config/configgrpc/server_middleware_test.go @@ -46,7 +46,7 @@ type testServerMiddleware struct { func newTestServerMiddleware(name string) extension.Extension { return &testServerMiddleware{ Extension: extensionmiddlewaretest.NewNop(), - GetGRPCServerOptionsFunc: func() ([]grpc.ServerOption, error) { + GetGRPCServerOptionsFunc: func(_ context.Context) ([]grpc.ServerOption, error) { return []grpc.ServerOption{grpc.ChainUnaryInterceptor( func( ctx context.Context, diff --git a/config/confighttp/README.md b/config/confighttp/README.md index 08987e611615..ba13f30fcfa8 100644 --- a/config/confighttp/README.md +++ b/config/confighttp/README.md @@ -15,6 +15,7 @@ configuration. For more information, see [configtls README](../configtls/README.md). - `endpoint`: address:port +- `proxy_url`: Proxy URL to use for HTTP requests - [`tls`](../configtls/README.md) - [`headers`](https://pkg.go.dev/net/http#Request): name/value pairs added to the HTTP request headers - certain headers such as Content-Length and Connection are automatically written when needed and values in Header may be ignored. @@ -67,7 +68,7 @@ Example: ```yaml exporter: - otlphttp: + otlp_http: endpoint: otelcol2:55690 auth: authenticator: some-authenticator-extension @@ -106,9 +107,17 @@ will not be enabled. header, allowing clients to cache the response to CORS preflight requests. If not set, browsers use a default of 5 seconds. - `endpoint`: Valid value syntax available [here](https://github.com/grpc/grpc/blob/master/doc/naming.md) +- `transport`: The transport protocol to use. Defaults to `tcp`. See the [confignet README](../confignet/README.md) for more information. - `max_request_body_size`: configures the maximum allowed body size in bytes for a single request. Default: `20971520` (20MiB) +- `include_metadata`: propagates the client metadata from the incoming requests to the downstream consumers. Default: `false` +- `response_headers`: Additional headers attached to each HTTP response sent to the client. Header values are opaque since they may be sensitive - `compression_algorithms`: configures the list of compression algorithms the server can accept. Default: ["", "gzip", "zstd", "zlib", "snappy", "deflate", "lz4"] - `x-snappy-framed` can be used if feature gate `confighttp.snappyFramed` is enabled. +- `read_timeout`: maximum duration for reading the entire request, including the body. A zero or negative value means there will be no timeout. Default: `0` (no timeout) +- `read_header_timeout`: amount of time allowed to read request headers. If zero, the value of `read_timeout` is used. If both are zero, there is no timeout. Default: `1m` +- `write_timeout`: maximum duration before timing out writes of the response. A zero or negative value means there will be no timeout. Default: `30s` +- `idle_timeout`: maximum amount of time to wait for the next request when keep-alives are enabled. If zero, the value of `read_timeout` is used. If both are zero, there is no timeout. Default: `1m` +- `keep_alives_enabled`: controls whether HTTP keep-alives are enabled. Default: `true` - [`tls`](../configtls/README.md) - [`auth`](../configauth/README.md) - `request_params`: a list of query parameter names to add to the auth context, along with the HTTP headers diff --git a/config/confighttp/client.go b/config/confighttp/client.go index ec16cc293d5e..3c826b9fc31a 100644 --- a/config/confighttp/client.go +++ b/config/confighttp/client.go @@ -205,16 +205,15 @@ func (cc *ClientConfig) ToClient(ctx context.Context, extensions map[component.I return nil, errors.New("middlewares were configured but this component or its host does not support extensions") } for i := len(cc.Middlewares) - 1; i >= 0; i-- { - var wrapper func(http.RoundTripper) (http.RoundTripper, error) - wrapper, err = cc.Middlewares[i].GetHTTPClientRoundTripper(ctx, extensions) + getClient, rerr := cc.Middlewares[i].GetHTTPClientRoundTripper(ctx, extensions) // If we failed to get the middleware - if err != nil { - return nil, err + if rerr != nil { + return nil, rerr } - clientTransport, err = wrapper(clientTransport) + clientTransport, rerr = getClient(ctx, clientTransport) // If we failed to construct a wrapper - if err != nil { - return nil, err + if rerr != nil { + return nil, rerr } } diff --git a/config/confighttp/client_middleware_test.go b/config/confighttp/client_middleware_test.go index 90bbf12108cb..58465e9524cd 100644 --- a/config/confighttp/client_middleware_test.go +++ b/config/confighttp/client_middleware_test.go @@ -32,30 +32,32 @@ type testClientMiddleware struct { func newTestClientMiddleware(name string) component.Component { return &testClientMiddleware{ Extension: extensionmiddlewaretest.NewNop(), - GetHTTPRoundTripperFunc: func(transport http.RoundTripper) (http.RoundTripper, error) { - return extensionmiddlewaretest.RoundTripperFunc( - func(req *http.Request) (*http.Response, error) { - resp, err := transport.RoundTrip(req) - if err != nil { - return resp, err - } - - // Read the original body - body, err := io.ReadAll(resp.Body) - if err != nil { - return resp, err - } - _ = resp.Body.Close() - - // Create a new body with the appended text - newBody := string(body) + "\r\noutput by " + name - - // Replace the response body - resp.Body = io.NopCloser(strings.NewReader(newBody)) - resp.ContentLength = int64(len(newBody)) - - return resp, nil - }), nil + GetHTTPRoundTripperFunc: func(_ context.Context) (extensionmiddleware.WrapHTTPRoundTripperFunc, error) { + return func(_ context.Context, transport http.RoundTripper) (http.RoundTripper, error) { + return extensionmiddlewaretest.RoundTripperFunc( + func(req *http.Request) (*http.Response, error) { + resp, err := transport.RoundTrip(req) + if err != nil { + return resp, err + } + + // Read the original body + body, err := io.ReadAll(resp.Body) + if err != nil { + return resp, err + } + _ = resp.Body.Close() + + // Create a new body with the appended text + newBody := string(body) + "\r\noutput by " + name + + // Replace the response body + resp.Body = io.NopCloser(strings.NewReader(newBody)) + resp.ContentLength = int64(len(newBody)) + + return resp, nil + }), nil + }, nil }, } } diff --git a/config/confighttp/client_test.go b/config/confighttp/client_test.go index 65423c76bb2f..69326d79cfcf 100644 --- a/config/confighttp/client_test.go +++ b/config/confighttp/client_test.go @@ -485,7 +485,7 @@ func TestHTTPClientSettingWithAuthConfig(t *testing.T) { } } -func TestHttpClientHeaders(t *testing.T) { +func TestHTTPClientHeaders(t *testing.T) { tests := []struct { name string headers configopaque.MapList @@ -524,7 +524,7 @@ func TestHttpClientHeaders(t *testing.T) { } } -func TestHttpClientHostHeader(t *testing.T) { +func TestHTTPClientHostHeader(t *testing.T) { hostHeader := "th" tt := struct { name string @@ -559,7 +559,7 @@ func TestHttpClientHostHeader(t *testing.T) { }) } -func TestHttpTransportOptions(t *testing.T) { +func TestHTTPTransportOptions(t *testing.T) { settings := componenttest.NewNopTelemetrySettings() // Disable OTel instrumentation so the *http.Transport object is directly accessible settings.MeterProvider = nil diff --git a/config/confighttp/compression.go b/config/confighttp/compression.go index 62f1ff6d7d27..3e357ad166be 100644 --- a/config/confighttp/compression.go +++ b/config/confighttp/compression.go @@ -22,19 +22,11 @@ import ( "github.com/pierrec/lz4/v4" "go.opentelemetry.io/collector/config/configcompression" - "go.opentelemetry.io/collector/featuregate" -) - -var enableFramedSnappy = featuregate.GlobalRegistry().MustRegister( - "confighttp.framedSnappy", - featuregate.StageBeta, - featuregate.WithRegisterFromVersion("v0.125.0"), - featuregate.WithRegisterDescription("Content encoding 'snappy' will compress/decompress block snappy format while 'x-snappy-framed' will compress/decompress framed snappy format."), - featuregate.WithRegisterReferenceURL("https://github.com/open-telemetry/opentelemetry-collector/issues/10584"), + "go.opentelemetry.io/collector/config/confighttp/internal/metadata" ) func defaultCompressionAlgorithms() []string { - if enableFramedSnappy.IsEnabled() { + if metadata.ConfighttpFramedSnappyFeatureGate.IsEnabled() { return []string{"", "gzip", "zstd", "zlib", "snappy", "deflate", "lz4", "x-snappy-framed"} } return []string{"", "gzip", "zstd", "zlib", "snappy", "deflate", "lz4"} @@ -236,7 +228,7 @@ func httpContentDecompressor(h http.Handler, maxRequestBodySize int64, eh func(w enabled := map[string]func(body io.ReadCloser) (io.ReadCloser, error){} for _, dec := range enableDecoders { - if dec == "x-frame-snappy" && !enableFramedSnappy.IsEnabled() { + if dec == "x-frame-snappy" && !metadata.ConfighttpFramedSnappyFeatureGate.IsEnabled() { continue } enabled[dec] = availableDecoders[dec] diff --git a/config/confighttp/compression_test.go b/config/confighttp/compression_test.go index e9cff5c573b0..068fd8c22ee7 100644 --- a/config/confighttp/compression_test.go +++ b/config/confighttp/compression_test.go @@ -25,6 +25,8 @@ import ( "go.opentelemetry.io/collector/component/componenttest" "go.opentelemetry.io/collector/config/configcompression" + "go.opentelemetry.io/collector/config/confighttp/internal/metadata" + "go.opentelemetry.io/collector/config/confignet" "go.opentelemetry.io/collector/featuregate" ) @@ -152,7 +154,7 @@ func TestHTTPClientCompression(t *testing.T) { } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - require.NoError(t, featuregate.GlobalRegistry().Set(enableFramedSnappy.ID(), tt.framedSnappyEnabled)) + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.ConfighttpFramedSnappyFeatureGate.ID(), tt.framedSnappyEnabled)) srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { body, err := io.ReadAll(r.Body) @@ -352,7 +354,7 @@ func TestHTTPContentDecompressionHandler(t *testing.T) { } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - require.NoError(t, featuregate.GlobalRegistry().Set(enableFramedSnappy.ID(), tt.framedSnappyEnabled)) + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.ConfighttpFramedSnappyFeatureGate.ID(), tt.framedSnappyEnabled)) srv := httptest.NewServer(httpContentDecompressor(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { body, err := io.ReadAll(r.Body) @@ -472,7 +474,10 @@ func TestEmptyCompressionAlgorithmsAllowsUncompressed(t *testing.T) { // Create ServerConfig with the specified CompressionAlgorithms serverConfig := &ServerConfig{ - Endpoint: "localhost:0", + NetAddr: confignet.AddrConfig{ + Endpoint: "localhost:0", + Transport: confignet.TransportTypeTCP, + }, CompressionAlgorithms: tt.compressionAlgorithms, } @@ -673,7 +678,7 @@ func TestDecompressorAvoidDecompressionBomb(t *testing.T) { } { t.Run(tc.name, func(t *testing.T) { // t.Parallel() // TODO: Re-enable parallel tests once feature gate is removed. We can't parallelize since registry is shared. - require.NoError(t, featuregate.GlobalRegistry().Set(enableFramedSnappy.ID(), tc.framedSnappyEnabled)) + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.ConfighttpFramedSnappyFeatureGate.ID(), tc.framedSnappyEnabled)) h := httpContentDecompressor( http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { diff --git a/config/confighttp/compressor.go b/config/confighttp/compressor.go index 70ad7227a1a7..a3843ab94539 100644 --- a/config/confighttp/compressor.go +++ b/config/confighttp/compressor.go @@ -16,6 +16,7 @@ import ( "github.com/pierrec/lz4/v4" "go.opentelemetry.io/collector/config/configcompression" + "go.opentelemetry.io/collector/config/confighttp/internal/metadata" ) type writeCloserReset interface { @@ -67,14 +68,14 @@ func newWriteCloserResetFunc(compressionType configcompression.Type, compression return w }, nil case configcompression.TypeSnappyFramed: - if !enableFramedSnappy.IsEnabled() { + if !metadata.ConfighttpFramedSnappyFeatureGate.IsEnabled() { return nil, errors.New("x-snappy-framed is not enabled") } return func() writeCloserReset { return snappy.NewBufferedWriter(nil) }, nil case configcompression.TypeSnappy: - if !enableFramedSnappy.IsEnabled() { + if !metadata.ConfighttpFramedSnappyFeatureGate.IsEnabled() { // If framed snappy feature gate is not enabled, we keep the current behavior // where the 'Content-Encoding: snappy' is compressed as the framed snappy format. return func() writeCloserReset { diff --git a/config/confighttp/compressor_test.go b/config/confighttp/compressor_test.go index 1278e1923740..08a198aaddca 100644 --- a/config/confighttp/compressor_test.go +++ b/config/confighttp/compressor_test.go @@ -16,9 +16,11 @@ import ( "github.com/stretchr/testify/require" "go.opentelemetry.io/collector/config/configcompression" + "go.opentelemetry.io/collector/internal/testutil" ) func BenchmarkCompression(b *testing.B) { + testutil.SkipGCHeavyBench(b) benchmarks := []struct { codec configcompression.Type name string @@ -35,7 +37,7 @@ func BenchmarkCompression(b *testing.B) { function: benchmarkCompressionNoConcurrency, }, } - payload := make([]byte, 10<<20) + payload := make([]byte, 10<<22) buffer := bytes.Buffer{} buffer.Grow(len(payload)) @@ -55,38 +57,31 @@ func BenchmarkCompression(b *testing.B) { func benchmarkCompression(b *testing.B, _ configcompression.Type, buf *bytes.Buffer, payload []byte) { // Concurrency Enabled - - b.Run("compress", func(b *testing.B) { - stringReader := strings.NewReader(string(payload)) - stringReadCloser := io.NopCloser(stringReader) - var enc io.Writer - b.ResetTimer() - b.ReportAllocs() - b.SetBytes(int64(len(payload))) - for b.Loop() { - enc, _ = zstd.NewWriter(nil, zstd.WithEncoderConcurrency(5)) - enc.(writeCloserReset).Reset(buf) - _, copyErr := io.Copy(enc, stringReadCloser) - require.NoError(b, copyErr) - } - }) + stringReader := strings.NewReader(string(payload)) + stringReadCloser := io.NopCloser(stringReader) + var enc io.Writer + b.ResetTimer() + b.ReportAllocs() + b.SetBytes(int64(len(payload))) + for b.Loop() { + enc, _ = zstd.NewWriter(nil, zstd.WithEncoderConcurrency(5)) + enc.(writeCloserReset).Reset(buf) + _, copyErr := io.Copy(enc, stringReadCloser) + require.NoError(b, copyErr) + } } func benchmarkCompressionNoConcurrency(b *testing.B, _ configcompression.Type, buf *bytes.Buffer, payload []byte) { - // Concurrency Disabled - - b.Run("compress", func(b *testing.B) { - stringReader := strings.NewReader(string(payload)) - stringReadCloser := io.NopCloser(stringReader) - var enc io.Writer - b.ResetTimer() - b.ReportAllocs() - b.SetBytes(int64(len(payload))) - for b.Loop() { - enc, _ = zstd.NewWriter(nil, zstd.WithEncoderConcurrency(1)) - enc.(writeCloserReset).Reset(buf) - _, copyErr := io.Copy(enc, stringReadCloser) - require.NoError(b, copyErr) - } - }) + stringReader := strings.NewReader(string(payload)) + stringReadCloser := io.NopCloser(stringReader) + var enc io.Writer + b.ResetTimer() + b.ReportAllocs() + b.SetBytes(int64(len(payload))) + for b.Loop() { + enc, _ = zstd.NewWriter(nil, zstd.WithEncoderConcurrency(1)) + enc.(writeCloserReset).Reset(buf) + _, copyErr := io.Copy(enc, stringReadCloser) + require.NoError(b, copyErr) + } } diff --git a/config/confighttp/config.schema.yaml b/config/confighttp/config.schema.yaml new file mode 100644 index 000000000000..52ed2849aa6f --- /dev/null +++ b/config/confighttp/config.schema.yaml @@ -0,0 +1,168 @@ +$defs: + auth_config: + type: object + properties: + request_params: + description: RequestParameters is a list of parameters that should be extracted from the request and added to the context. When a parameter is found in both the query string and the header, the value from the query string will be used. + type: array + items: + type: string + allOf: + - $ref: /config/configauth.config + cookies_config: + description: CookiesConfig defines the configuration of the HTTP client regarding cookies served by the server. + client_config: + description: ClientConfig defines settings for creating an HTTP client. + type: object + properties: + auth: + description: Auth configuration for outgoing HTTP calls. + x-optional: true + $ref: /config/configauth.config + compression: + description: The compression key for supported compression types within collector. + $ref: /config/configcompression.type + compression_params: + description: Advanced configuration options for the Compression + $ref: /config/configcompression.compression_params + cookies: + description: Cookies configures the cookie management of the HTTP client. + x-optional: true + $ref: cookies_config + disable_keep_alives: + description: 'DisableKeepAlives, if true, disables HTTP keep-alives and will only use the connection to the server for a single HTTP request. WARNING: enabling this option can result in significant overhead establishing a new HTTP(S) connection for every request. Before enabling this option please consider whether changes to idle connection settings can achieve your goal.' + type: boolean + endpoint: + description: 'The target URL to send data to (e.g.: http://some.url:9411/v1/traces).' + type: string + force_attempt_http2: + description: 'Enabling ForceAttemptHTTP2 forces the HTTP transport to use the HTTP/2 protocol. By default, this is set to true. NOTE: HTTP/2 does not support settings such as MaxConnsPerHost, MaxIdleConnsPerHost and MaxIdleConns.' + type: boolean + headers: + description: Additional headers attached to each HTTP request sent by the client. Existing header values are overwritten if collision happens. Header values are opaque since they may be sensitive. + $ref: /config/configopaque.map_list + http2_ping_timeout: + description: HTTP2PingTimeout if there's no response to the ping within the configured value, the connection will be closed. If not set or set to 0, it defaults to 15s. + type: string + x-customType: time.Duration + format: duration + http2_read_idle_timeout: + description: This is needed in case you run into https://github.com/golang/go/issues/59690 https://github.com/golang/go/issues/36026 HTTP2ReadIdleTimeout if the connection has been idle for the configured value send a ping frame for health check 0s means no health check will be performed. + type: string + x-customType: time.Duration + format: duration + idle_conn_timeout: + description: IdleConnTimeout is the maximum amount of time a connection will remain open before closing itself. By default, it is set to 90 seconds. + type: string + x-customType: time.Duration + format: duration + max_conns_per_host: + description: MaxConnsPerHost limits the total number of connections per host, including connections in the dialing, active, and idle states. Default is 0 (unlimited). + type: integer + max_idle_conns: + description: MaxIdleConns is used to set a limit to the maximum idle HTTP connections the client can keep open. By default, it is set to 100. Zero means no limit. + type: integer + max_idle_conns_per_host: + description: MaxIdleConnsPerHost is used to set a limit to the maximum idle HTTP connections the host can keep open. If zero, [net/http.DefaultMaxIdleConnsPerHost] is used. + type: integer + middlewares: + description: Middlewares are used to add custom functionality to the HTTP client. Middleware handlers are called in the order they appear in this list, with the first middleware becoming the outermost handler. + type: array + items: + $ref: /config/configmiddleware.config + proxy_url: + description: ProxyURL setting for the collector + type: string + read_buffer_size: + description: ReadBufferSize for HTTP client. See http.Transport.ReadBufferSize. Default is 0. + type: integer + timeout: + description: Timeout parameter configures `http.Client.Timeout`. Default is 0 (unlimited). + type: string + x-customType: time.Duration + format: duration + tls: + description: TLS struct exposes TLS client configuration. + $ref: /config/configtls.client_config + write_buffer_size: + description: WriteBufferSize for HTTP client. See http.Transport.WriteBufferSize. Default is 0. + type: integer + cors_config: + description: CORSConfig configures a receiver for HTTP cross-origin resource sharing (CORS). See the underlying https://github.com/rs/cors package for details. + type: object + properties: + allowed_headers: + description: AllowedHeaders sets what headers will be allowed in CORS requests. The Accept, Accept-Language, Content-Type, and Content-Language headers are implicitly allowed. If no headers are listed, X-Requested-With will also be accepted by default. Include "*" to allow any request header. + type: array + items: + type: string + allowed_origins: + description: AllowedOrigins sets the allowed values of the Origin header for HTTP/JSON requests to an OTLP receiver. An origin may contain a wildcard (*) to replace 0 or more characters (e.g., "http://*.domain.com", or "*" to allow any origin). + type: array + items: + type: string + max_age: + description: MaxAge sets the value of the Access-Control-Max-Age response header. Set it to the number of seconds that browsers should cache a CORS preflight response for. + type: integer + server_config: + description: ServerConfig defines settings for creating an HTTP server. + type: object + properties: + auth: + description: Auth for this receiver + x-optional: true + $ref: auth_config + compression_algorithms: + description: 'CompressionAlgorithms configures the list of compression algorithms the server can accept. Default: ["", "gzip", "zstd", "zlib", "snappy", "deflate"]' + type: array + items: + type: string + cors: + description: CORS configures the server for HTTP cross-origin resource sharing (CORS). + x-optional: true + $ref: cors_config + endpoint: + description: Endpoint configures the listening address for the server. + type: string + idle_timeout: + description: IdleTimeout is the maximum amount of time to wait for the next request when keep-alives are enabled. If IdleTimeout is zero, the value of ReadTimeout is used. If both are zero, there is no timeout. + type: string + x-customType: time.Duration + format: duration + include_metadata: + description: IncludeMetadata propagates the client metadata from the incoming requests to the downstream consumers + type: boolean + keep_alives_enabled: + description: KeepAlivesEnabled controls whether HTTP keep-alives are enabled. By default, keep-alives are always enabled. Only very resource-constrained environments should disable them. + type: boolean + max_request_body_size: + description: 'MaxRequestBodySize sets the maximum request body size in bytes. Default: 20MiB.' + type: integer + x-customType: int64 + middlewares: + description: Middlewares are used to add custom functionality to the HTTP server. Middleware handlers are called in the order they appear in this list, with the first middleware becoming the outermost handler. + type: array + items: + $ref: /config/configmiddleware.config + read_header_timeout: + description: ReadHeaderTimeout is the amount of time allowed to read request headers. The connection's read deadline is reset after reading the headers and the Handler can decide what is considered too slow for the body. If ReadHeaderTimeout is zero, the value of ReadTimeout is used. If both are zero, there is no timeout. + type: string + x-customType: time.Duration + format: duration + read_timeout: + description: ReadTimeout is the maximum duration for reading the entire request, including the body. A zero or negative value means there will be no timeout. Because ReadTimeout does not let Handlers make per-request decisions on each request body's acceptable deadline or upload rate, most users will prefer to use ReadHeaderTimeout. It is valid to use them both. + type: string + x-customType: time.Duration + format: duration + response_headers: + description: Additional headers attached to each HTTP response sent to the client. Header values are opaque since they may be sensitive. + $ref: /config/configopaque.map_list + tls: + description: TLS struct exposes TLS client configuration. + x-optional: true + $ref: /config/configtls.server_config + write_timeout: + description: WriteTimeout is the maximum duration before timing out writes of the response. It is reset whenever a new request's header is read. Like ReadTimeout, it does not let Handlers make decisions on a per-request basis. A zero or negative value means there will be no timeout. + type: string + x-customType: time.Duration + format: duration diff --git a/config/confighttp/confighttp_example_test.go b/config/confighttp/confighttp_example_test.go index dc711d70dc57..a34bec10fe03 100644 --- a/config/confighttp/confighttp_example_test.go +++ b/config/confighttp/confighttp_example_test.go @@ -12,7 +12,7 @@ import ( func ExampleServerConfig() { settings := NewDefaultServerConfig() - settings.Endpoint = "localhost:443" + settings.NetAddr.Endpoint = "localhost:443" // Typically obtained as an argument of Component.Start() host := componenttest.NewNopHost() diff --git a/config/confighttp/doc.go b/config/confighttp/doc.go index 70809993da8b..ea30cfb96e8f 100644 --- a/config/confighttp/doc.go +++ b/config/confighttp/doc.go @@ -7,3 +7,5 @@ // The configuration structs in this package may be shared across signals, but // assume each struct is used for a single protocol and component. package confighttp // import "go.opentelemetry.io/collector/config/confighttp" + +//go:generate mdatagen metadata.yaml diff --git a/config/confighttp/documentation.md b/config/confighttp/documentation.md new file mode 100644 index 000000000000..0acc2deddf22 --- /dev/null +++ b/config/confighttp/documentation.md @@ -0,0 +1,13 @@ +[comment]: <> (Code generated by mdatagen. DO NOT EDIT.) + +# confighttp + +## Feature Gates + +This component has the following feature gates: + +| Feature Gate | Stage | Description | From Version | To Version | Reference | +| ------------ | ----- | ----------- | ------------ | ---------- | --------- | +| `confighttp.framedSnappy` | beta | Content encoding 'snappy' will compress/decompress block snappy format while 'x-snappy-framed' will compress/decompress framed snappy format. | v0.125.0 | N/A | [Link](https://github.com/open-telemetry/opentelemetry-collector/issues/10584) | + +For more information about feature gates, see the [Feature Gates](https://github.com/open-telemetry/opentelemetry-collector/blob/main/featuregate/README.md) documentation. diff --git a/config/confighttp/package_test.go b/config/confighttp/generated_package_test.go similarity index 61% rename from config/confighttp/package_test.go rename to config/confighttp/generated_package_test.go index 30797439baf3..7bcd969a5905 100644 --- a/config/confighttp/package_test.go +++ b/config/confighttp/generated_package_test.go @@ -1,5 +1,4 @@ -// Copyright The OpenTelemetry Authors -// SPDX-License-Identifier: Apache-2.0 +// Code generated by mdatagen. DO NOT EDIT. package confighttp diff --git a/config/confighttp/go.mod b/config/confighttp/go.mod index a9bd90f54036..83cf4e5dea8e 100644 --- a/config/confighttp/go.mod +++ b/config/confighttp/go.mod @@ -1,74 +1,79 @@ module go.opentelemetry.io/collector/config/confighttp -go 1.24.0 +go 1.25.0 require ( github.com/golang/snappy v1.0.0 - github.com/klauspost/compress v1.18.1 - github.com/pierrec/lz4/v4 v4.1.22 + github.com/klauspost/compress v1.18.4 + github.com/pierrec/lz4/v4 v4.1.26 github.com/rs/cors v1.11.1 github.com/stretchr/testify v1.11.1 go.opentelemetry.io/collector/client v1.46.0 - go.opentelemetry.io/collector/component v1.46.0 + go.opentelemetry.io/collector/component v1.54.0 go.opentelemetry.io/collector/component/componenttest v0.140.0 go.opentelemetry.io/collector/config/configauth v1.46.0 go.opentelemetry.io/collector/config/configcompression v1.46.0 go.opentelemetry.io/collector/config/configmiddleware v1.46.0 - go.opentelemetry.io/collector/config/configopaque v1.46.0 + go.opentelemetry.io/collector/config/confignet v0.0.0-00010101000000-000000000000 + go.opentelemetry.io/collector/config/configopaque v1.54.0 go.opentelemetry.io/collector/config/configoptional v1.46.0 go.opentelemetry.io/collector/config/configtls v1.46.0 - go.opentelemetry.io/collector/extension v1.46.0 - go.opentelemetry.io/collector/extension/extensionauth v1.46.0 - go.opentelemetry.io/collector/extension/extensionauth/extensionauthtest v0.140.0 - go.opentelemetry.io/collector/extension/extensionmiddleware v0.140.0 - go.opentelemetry.io/collector/extension/extensionmiddleware/extensionmiddlewaretest v0.140.0 - go.opentelemetry.io/collector/featuregate v1.46.0 + go.opentelemetry.io/collector/extension v1.54.0 + go.opentelemetry.io/collector/extension/extensionauth v1.54.0 + go.opentelemetry.io/collector/extension/extensionauth/extensionauthtest v0.148.0 + go.opentelemetry.io/collector/extension/extensionmiddleware v0.148.0 + go.opentelemetry.io/collector/extension/extensionmiddleware/extensionmiddlewaretest v0.148.0 + go.opentelemetry.io/collector/featuregate v1.54.0 + go.opentelemetry.io/collector/internal/testutil v0.148.0 go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.63.0 - go.opentelemetry.io/otel v1.40.0 + go.opentelemetry.io/otel v1.42.0 go.uber.org/goleak v1.3.0 go.uber.org/zap v1.27.1 - golang.org/x/net v0.47.0 + golang.org/x/net v0.51.0 ) -require github.com/cespare/xxhash/v2 v2.3.0 // indirect +require ( + github.com/cespare/xxhash/v2 v2.3.0 // indirect + go.opentelemetry.io/collector/internal/componentalias v0.148.0 // indirect +) require ( github.com/davecgh/go-spew v1.1.1 // indirect github.com/felixge/httpsnoop v1.0.4 // indirect - github.com/foxboron/go-tpm-keyfiles v0.0.0-20250903184740-5d135037bd4d // indirect + github.com/foxboron/go-tpm-keyfiles v0.0.0-20251226215517-609e4778396f // indirect github.com/fsnotify/fsnotify v1.9.0 // indirect github.com/go-logr/logr v1.4.3 // indirect github.com/go-logr/stdr v1.2.2 // indirect - github.com/go-viper/mapstructure/v2 v2.4.0 // indirect + github.com/go-viper/mapstructure/v2 v2.5.0 // indirect github.com/gobwas/glob v0.2.3 // indirect - github.com/google/go-tpm v0.9.7 // indirect + github.com/google/go-tpm v0.9.8 // indirect github.com/google/uuid v1.6.0 // indirect - github.com/hashicorp/go-version v1.7.0 // indirect + github.com/hashicorp/go-version v1.8.0 // indirect github.com/json-iterator/go v1.1.12 // indirect github.com/knadh/koanf/maps v0.1.2 // indirect github.com/knadh/koanf/providers/confmap v1.0.0 // indirect - github.com/knadh/koanf/v2 v2.3.0 // indirect + github.com/knadh/koanf/v2 v2.3.3 // indirect github.com/mitchellh/copystructure v1.2.0 // indirect github.com/mitchellh/reflectwalk v1.0.2 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee // indirect github.com/pmezard/go-difflib v1.0.0 // indirect go.opentelemetry.io/auto/sdk v1.2.1 // indirect - go.opentelemetry.io/collector/confmap v1.46.0 - go.opentelemetry.io/collector/confmap/xconfmap v0.140.0 - go.opentelemetry.io/collector/pdata v1.46.0 // indirect - go.opentelemetry.io/otel/metric v1.40.0 // indirect + go.opentelemetry.io/collector/confmap v1.54.0 + go.opentelemetry.io/collector/confmap/xconfmap v0.148.0 + go.opentelemetry.io/collector/pdata v1.54.0 // indirect + go.opentelemetry.io/otel/metric v1.42.0 // indirect go.opentelemetry.io/otel/sdk v1.40.0 // indirect go.opentelemetry.io/otel/sdk/metric v1.40.0 // indirect - go.opentelemetry.io/otel/trace v1.40.0 // indirect + go.opentelemetry.io/otel/trace v1.42.0 // indirect go.uber.org/multierr v1.11.0 // indirect go.yaml.in/yaml/v3 v3.0.4 // indirect - golang.org/x/crypto v0.45.0 // indirect - golang.org/x/sys v0.40.0 // indirect - golang.org/x/text v0.31.0 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20251022142026-3a174f9686a8 // indirect - google.golang.org/grpc v1.77.0 // indirect - google.golang.org/protobuf v1.36.10 // indirect + golang.org/x/crypto v0.48.0 // indirect + golang.org/x/sys v0.41.0 // indirect + golang.org/x/text v0.34.0 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20251222181119-0a764e51fe1b // indirect + google.golang.org/grpc v1.79.3 // indirect + google.golang.org/protobuf v1.36.11 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) @@ -78,6 +83,8 @@ replace go.opentelemetry.io/collector/config/configcompression => ../configcompr replace go.opentelemetry.io/collector/config/configmiddleware => ../configmiddleware +replace go.opentelemetry.io/collector/config/confignet => ../confignet + replace go.opentelemetry.io/collector/config/configopaque => ../configopaque replace go.opentelemetry.io/collector/config/configoptional => ../configoptional @@ -111,3 +118,5 @@ replace go.opentelemetry.io/collector/confmap => ../../confmap replace go.opentelemetry.io/collector/confmap/xconfmap => ../../confmap/xconfmap replace go.opentelemetry.io/collector/internal/testutil => ../../internal/testutil + +replace go.opentelemetry.io/collector/internal/componentalias => ../../internal/componentalias diff --git a/config/confighttp/go.sum b/config/confighttp/go.sum index f9df5f2d7a82..402ae45b7926 100644 --- a/config/confighttp/go.sum +++ b/config/confighttp/go.sum @@ -5,10 +5,8 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg= github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= -github.com/foxboron/go-tpm-keyfiles v0.0.0-20250903184740-5d135037bd4d h1:EdO/NMMuCZfxhdzTZLuKAciQSnI2DV+Ppg8+vAYrnqA= -github.com/foxboron/go-tpm-keyfiles v0.0.0-20250903184740-5d135037bd4d/go.mod h1:uAyTlAUxchYuiFjTHmuIEJ4nGSm7iOPaGcAyA81fJ80= -github.com/foxboron/swtpm_test v0.0.0-20230726224112-46aaafdf7006 h1:50sW4r0PcvlpG4PV8tYh2RVCapszJgaOLRCS2subvV4= -github.com/foxboron/swtpm_test v0.0.0-20230726224112-46aaafdf7006/go.mod h1:eIXCMsMYCaqq9m1KSSxXwQG11krpuNPGP3k0uaWrbas= +github.com/foxboron/go-tpm-keyfiles v0.0.0-20251226215517-609e4778396f h1:RJ+BDPLSHQO7cSjKBqjPJSbi1qfk9WcsjQDtZiw3dZw= +github.com/foxboron/go-tpm-keyfiles v0.0.0-20251226215517-609e4778396f/go.mod h1:VHbbch/X4roIY22jL1s3qRbZhCiRIgUAF/PdSUcx2io= github.com/fsnotify/fsnotify v1.9.0 h1:2Ml+OJNzbYCTzsxtv8vKSFD9PbJjmhYF14k/jKC7S9k= github.com/fsnotify/fsnotify v1.9.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= @@ -16,8 +14,8 @@ github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI= github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= -github.com/go-viper/mapstructure/v2 v2.4.0 h1:EBsztssimR/CONLSZZ04E8qAkxNYq4Qp9LvH92wZUgs= -github.com/go-viper/mapstructure/v2 v2.4.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM= +github.com/go-viper/mapstructure/v2 v2.5.0 h1:vM5IJoUAy3d7zRSVtIwQgBj7BiWtMPfmPEgAXnvj1Ro= +github.com/go-viper/mapstructure/v2 v2.5.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM= github.com/gobwas/glob v0.2.3 h1:A4xDbljILXROh+kObIiy5kIaPYD8e96x1tgBhUI5J+Y= github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8= github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= @@ -26,25 +24,25 @@ github.com/golang/snappy v1.0.0 h1:Oy607GVXHs7RtbggtPBnr2RmDArIsAefDwvrdWvRhGs= github.com/golang/snappy v1.0.0/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= -github.com/google/go-tpm v0.9.7 h1:u89J4tUUeDTlH8xxC3CTW7OHZjbjKoHdQ9W7gCUhtxA= -github.com/google/go-tpm v0.9.7/go.mod h1:h9jEsEECg7gtLis0upRBQU+GhYVH6jMjrFxI8u6bVUY= -github.com/google/go-tpm-tools v0.4.4 h1:oiQfAIkc6xTy9Fl5NKTeTJkBTlXdHsxAofmQyxBKY98= -github.com/google/go-tpm-tools v0.4.4/go.mod h1:T8jXkp2s+eltnCDIsXR84/MTcVU9Ja7bh3Mit0pa4AY= +github.com/google/go-tpm v0.9.8 h1:slArAR9Ft+1ybZu0lBwpSmpwhRXaa85hWtMinMyRAWo= +github.com/google/go-tpm v0.9.8/go.mod h1:h9jEsEECg7gtLis0upRBQU+GhYVH6jMjrFxI8u6bVUY= +github.com/google/go-tpm-tools v0.4.7 h1:J3ycC8umYxM9A4eF73EofRZu4BxY0jjQnUnkhIBbvws= +github.com/google/go-tpm-tools v0.4.7/go.mod h1:gSyXTZHe3fgbzb6WEGd90QucmsnT1SRdlye82gH8QjQ= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/hashicorp/go-version v1.7.0 h1:5tqGy27NaOTB8yJKUZELlFAS/LTKJkrmONwQKeRZfjY= -github.com/hashicorp/go-version v1.7.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= +github.com/hashicorp/go-version v1.8.0 h1:KAkNb1HAiZd1ukkxDFGmokVZe1Xy9HG6NUp+bPle2i4= +github.com/hashicorp/go-version v1.8.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= -github.com/klauspost/compress v1.18.1 h1:bcSGx7UbpBqMChDtsF28Lw6v/G94LPrrbMbdC3JH2co= -github.com/klauspost/compress v1.18.1/go.mod h1:ZQFFVG+MdnR0P+l6wpXgIL4NTtwiKIdBnrBd8Nrxr+0= +github.com/klauspost/compress v1.18.4 h1:RPhnKRAQ4Fh8zU2FY/6ZFDwTVTxgJ/EMydqSTzE9a2c= +github.com/klauspost/compress v1.18.4/go.mod h1:R0h/fSBs8DE4ENlcrlib3PsXS61voFxhIs2DeRhCvJ4= github.com/knadh/koanf/maps v0.1.2 h1:RBfmAW5CnZT+PJ1CVc1QSJKf4Xu9kxfQgYVQSu8hpbo= github.com/knadh/koanf/maps v0.1.2/go.mod h1:npD/QZY3V6ghQDdcQzl1W4ICNVTkohC8E73eI2xW4yI= github.com/knadh/koanf/providers/confmap v1.0.0 h1:mHKLJTE7iXEys6deO5p6olAiZdG5zwp8Aebir+/EaRE= github.com/knadh/koanf/providers/confmap v1.0.0/go.mod h1:txHYHiI2hAtF0/0sCmcuol4IDcuQbKTybiB1nOcUo1A= -github.com/knadh/koanf/v2 v2.3.0 h1:Qg076dDRFHvqnKG97ZEsi9TAg2/nFTa9hCdcSa1lvlM= -github.com/knadh/koanf/v2 v2.3.0/go.mod h1:gRb40VRAbd4iJMYYD5IxZ6hfuopFcXBpc9bbQpZwo28= +github.com/knadh/koanf/v2 v2.3.3 h1:jLJC8XCRfLC7n4F+ZKKdBsbq1bfXTpuFhf4L7t94D94= +github.com/knadh/koanf/v2 v2.3.3/go.mod h1:gRb40VRAbd4iJMYYD5IxZ6hfuopFcXBpc9bbQpZwo28= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= @@ -59,8 +57,8 @@ github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJ github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee h1:W5t00kpgFdJifH4BDsTlE89Zl93FEloxaWZfGcifgq8= github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= -github.com/pierrec/lz4/v4 v4.1.22 h1:cKFw6uJDK+/gfw5BcDL0JL5aBsAFdsIT18eRtLj7VIU= -github.com/pierrec/lz4/v4 v4.1.22/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4= +github.com/pierrec/lz4/v4 v4.1.26 h1:GrpZw1gZttORinvzBdXPUXATeqlJjqUG/D87TKMnhjY= +github.com/pierrec/lz4/v4 v4.1.26/go.mod h1:EoQMVJgeeEOMsCqCzqFm2O0cJvljX2nGZjcRIPL34O4= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ= @@ -75,22 +73,22 @@ go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.63.0 h1:RbKq8BG0FI8OiXhBfcRtqqHcZcka+gU3cskNuf05R18= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.63.0/go.mod h1:h06DGIukJOevXaj/xrNjhi/2098RZzcLTbc0jDAUbsg= -go.opentelemetry.io/otel v1.40.0 h1:oA5YeOcpRTXq6NN7frwmwFR0Cn3RhTVZvXsP4duvCms= -go.opentelemetry.io/otel v1.40.0/go.mod h1:IMb+uXZUKkMXdPddhwAHm6UfOwJyh4ct1ybIlV14J0g= -go.opentelemetry.io/otel/metric v1.40.0 h1:rcZe317KPftE2rstWIBitCdVp89A2HqjkxR3c11+p9g= -go.opentelemetry.io/otel/metric v1.40.0/go.mod h1:ib/crwQH7N3r5kfiBZQbwrTge743UDc7DTFVZrrXnqc= +go.opentelemetry.io/otel v1.42.0 h1:lSQGzTgVR3+sgJDAU/7/ZMjN9Z+vUip7leaqBKy4sho= +go.opentelemetry.io/otel v1.42.0/go.mod h1:lJNsdRMxCUIWuMlVJWzecSMuNjE7dOYyWlqOXWkdqCc= +go.opentelemetry.io/otel/metric v1.42.0 h1:2jXG+3oZLNXEPfNmnpxKDeZsFI5o4J+nz6xUlaFdF/4= +go.opentelemetry.io/otel/metric v1.42.0/go.mod h1:RlUN/7vTU7Ao/diDkEpQpnz3/92J9ko05BIwxYa2SSI= go.opentelemetry.io/otel/sdk v1.40.0 h1:KHW/jUzgo6wsPh9At46+h4upjtccTmuZCFAc9OJ71f8= go.opentelemetry.io/otel/sdk v1.40.0/go.mod h1:Ph7EFdYvxq72Y8Li9q8KebuYUr2KoeyHx0DRMKrYBUE= go.opentelemetry.io/otel/sdk/metric v1.40.0 h1:mtmdVqgQkeRxHgRv4qhyJduP3fYJRMX4AtAlbuWdCYw= go.opentelemetry.io/otel/sdk/metric v1.40.0/go.mod h1:4Z2bGMf0KSK3uRjlczMOeMhKU2rhUqdWNoKcYrtcBPg= -go.opentelemetry.io/otel/trace v1.40.0 h1:WA4etStDttCSYuhwvEa8OP8I5EWu24lkOzp+ZYblVjw= -go.opentelemetry.io/otel/trace v1.40.0/go.mod h1:zeAhriXecNGP/s2SEG3+Y8X9ujcJOTqQ5RgdEJcawiA= -go.opentelemetry.io/proto/slim/otlp v1.9.0 h1:fPVMv8tP3TrsqlkH1HWYUpbCY9cAIemx184VGkS6vlE= -go.opentelemetry.io/proto/slim/otlp v1.9.0/go.mod h1:xXdeJJ90Gqyll+orzUkY4bOd2HECo5JofeoLpymVqdI= -go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.2.0 h1:o13nadWDNkH/quoDomDUClnQBpdQQ2Qqv0lQBjIXjE8= -go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.2.0/go.mod h1:Gyb6Xe7FTi/6xBHwMmngGoHqL0w29Y4eW8TGFzpefGA= -go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.2.0 h1:EiUYvtwu6PMrMHVjcPfnsG3v+ajPkbUeH+IL93+QYyk= -go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.2.0/go.mod h1:mUUHKFiN2SST3AhJ8XhJxEoeVW12oqfXog0Bo8W3Ec4= +go.opentelemetry.io/otel/trace v1.42.0 h1:OUCgIPt+mzOnaUTpOQcBiM/PLQ/Op7oq6g4LenLmOYY= +go.opentelemetry.io/otel/trace v1.42.0/go.mod h1:f3K9S+IFqnumBkKhRJMeaZeNk9epyhnCmQh/EysQCdc= +go.opentelemetry.io/proto/slim/otlp v1.10.0 h1:iR97Vs/ZDR+y9TfuP9b1XBtdPWeC+OMslIBmhcLU7jM= +go.opentelemetry.io/proto/slim/otlp v1.10.0/go.mod h1:lV9250stpjYLPNA5viFabIgP2QlUGRT1GdTgAf8SIUk= +go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.3.0 h1:RUF5rO0hAlgiJt1fzQVzcVs3vZVNHIcMLgOgG4rWNcQ= +go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.3.0/go.mod h1:I89cynRj8y+383o7tEQVg2SVA6SRgDVIouWPUVXjx0U= +go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.3.0 h1:CQvJSldHRUN6Z8jsUeYv8J0lXRvygALXIzsmAeCcZE0= +go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.3.0/go.mod h1:xSQ+mEfJe/GjK1LXEyVOoSI1N9JV9ZI923X5kup43W4= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= @@ -99,22 +97,22 @@ go.uber.org/zap v1.27.1 h1:08RqriUEv8+ArZRYSTXy1LeBScaMpVSTBhCeaZYfMYc= go.uber.org/zap v1.27.1/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc= go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg= -golang.org/x/crypto v0.45.0 h1:jMBrvKuj23MTlT0bQEOBcAE0mjg8mK9RXFhRH6nyF3Q= -golang.org/x/crypto v0.45.0/go.mod h1:XTGrrkGJve7CYK7J8PEww4aY7gM3qMCElcJQ8n8JdX4= -golang.org/x/net v0.47.0 h1:Mx+4dIFzqraBXUugkia1OOvlD6LemFo1ALMHjrXDOhY= -golang.org/x/net v0.47.0/go.mod h1:/jNxtkgq5yWUGYkaZGqo27cfGZ1c5Nen03aYrrKpVRU= -golang.org/x/sys v0.40.0 h1:DBZZqJ2Rkml6QMQsZywtnjnnGvHza6BTfYFWY9kjEWQ= -golang.org/x/sys v0.40.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= -golang.org/x/text v0.31.0 h1:aC8ghyu4JhP8VojJ2lEHBnochRno1sgL6nEi9WGFGMM= -golang.org/x/text v0.31.0/go.mod h1:tKRAlv61yKIjGGHX/4tP1LTbc13YSec1pxVEWXzfoeM= +golang.org/x/crypto v0.48.0 h1:/VRzVqiRSggnhY7gNRxPauEQ5Drw9haKdM0jqfcCFts= +golang.org/x/crypto v0.48.0/go.mod h1:r0kV5h3qnFPlQnBSrULhlsRfryS2pmewsg+XfMgkVos= +golang.org/x/net v0.51.0 h1:94R/GTO7mt3/4wIKpcR5gkGmRLOuE/2hNGeWq/GBIFo= +golang.org/x/net v0.51.0/go.mod h1:aamm+2QF5ogm02fjy5Bb7CQ0WMt1/WVM7FtyaTLlA9Y= +golang.org/x/sys v0.41.0 h1:Ivj+2Cp/ylzLiEU89QhWblYnOE9zerudt9Ftecq2C6k= +golang.org/x/sys v0.41.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= +golang.org/x/text v0.34.0 h1:oL/Qq0Kdaqxa1KbNeMKwQq0reLCCaFtqu2eNuSeNHbk= +golang.org/x/text v0.34.0/go.mod h1:homfLqTYRFyVYemLBFl5GgL/DWEiH5wcsQ5gSh1yziA= gonum.org/v1/gonum v0.16.0 h1:5+ul4Swaf3ESvrOnidPp4GZbzf0mxVQpDCYUQE7OJfk= gonum.org/v1/gonum v0.16.0/go.mod h1:fef3am4MQ93R2HHpKnLk4/Tbh/s0+wqD5nfa6Pnwy4E= -google.golang.org/genproto/googleapis/rpc v0.0.0-20251022142026-3a174f9686a8 h1:M1rk8KBnUsBDg1oPGHNCxG4vc1f49epmTO7xscSajMk= -google.golang.org/genproto/googleapis/rpc v0.0.0-20251022142026-3a174f9686a8/go.mod h1:7i2o+ce6H/6BluujYR+kqX3GKH+dChPTQU19wjRPiGk= -google.golang.org/grpc v1.77.0 h1:wVVY6/8cGA6vvffn+wWK5ToddbgdU3d8MNENr4evgXM= -google.golang.org/grpc v1.77.0/go.mod h1:z0BY1iVj0q8E1uSQCjL9cppRj+gnZjzDnzV0dHhrNig= -google.golang.org/protobuf v1.36.10 h1:AYd7cD/uASjIL6Q9LiTjz8JLcrh/88q5UObnmY3aOOE= -google.golang.org/protobuf v1.36.10/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= +google.golang.org/genproto/googleapis/rpc v0.0.0-20251222181119-0a764e51fe1b h1:Mv8VFug0MP9e5vUxfBcE3vUkV6CImK3cMNMIDFjmzxU= +google.golang.org/genproto/googleapis/rpc v0.0.0-20251222181119-0a764e51fe1b/go.mod h1:j9x/tPzZkyxcgEFkiKEEGxfvyumM01BEtsW8xzOahRQ= +google.golang.org/grpc v1.79.3 h1:sybAEdRIEtvcD68Gx7dmnwjZKlyfuc61Dyo9pGXXkKE= +google.golang.org/grpc v1.79.3/go.mod h1:KmT0Kjez+0dde/v2j9vzwoAScgEPx/Bw1CYChhHLrHQ= +google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE= +google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= diff --git a/config/confighttp/internal/metadata/generated_feature_gates.go b/config/confighttp/internal/metadata/generated_feature_gates.go new file mode 100644 index 000000000000..11139342aab2 --- /dev/null +++ b/config/confighttp/internal/metadata/generated_feature_gates.go @@ -0,0 +1,15 @@ +// Code generated by mdatagen. DO NOT EDIT. + +package metadata + +import ( + "go.opentelemetry.io/collector/featuregate" +) + +var ConfighttpFramedSnappyFeatureGate = featuregate.GlobalRegistry().MustRegister( + "confighttp.framedSnappy", + featuregate.StageBeta, + featuregate.WithRegisterDescription("Content encoding 'snappy' will compress/decompress block snappy format while 'x-snappy-framed' will compress/decompress framed snappy format."), + featuregate.WithRegisterReferenceURL("https://github.com/open-telemetry/opentelemetry-collector/issues/10584"), + featuregate.WithRegisterFromVersion("v0.125.0"), +) diff --git a/config/confighttp/metadata.yaml b/config/confighttp/metadata.yaml index 91031dc4e4bd..729744e18607 100644 --- a/config/confighttp/metadata.yaml +++ b/config/confighttp/metadata.yaml @@ -1,6 +1,16 @@ -type: config/confighttp +type: confighttp github_project: open-telemetry/opentelemetry-collector status: disable_codecov_badge: true class: pkg + stability: + beta: [metrics, traces, logs] + development: [profiles] + +feature_gates: + - id: confighttp.framedSnappy + description: "Content encoding 'snappy' will compress/decompress block snappy format while 'x-snappy-framed' will compress/decompress framed snappy format." + stage: beta + from_version: 'v0.125.0' + reference_url: 'https://github.com/open-telemetry/opentelemetry-collector/issues/10584' diff --git a/config/confighttp/server.go b/config/confighttp/server.go index 57a7feebdf74..733e069b3263 100644 --- a/config/confighttp/server.go +++ b/config/confighttp/server.go @@ -10,6 +10,7 @@ import ( "io" "net" "net/http" + "strings" "time" "github.com/rs/cors" @@ -23,6 +24,7 @@ import ( "go.opentelemetry.io/collector/config/configauth" "go.opentelemetry.io/collector/config/confighttp/internal" "go.opentelemetry.io/collector/config/configmiddleware" + "go.opentelemetry.io/collector/config/confignet" "go.opentelemetry.io/collector/config/configopaque" "go.opentelemetry.io/collector/config/configoptional" "go.opentelemetry.io/collector/config/configtls" @@ -33,10 +35,13 @@ const defaultMaxRequestBodySize = 20 * 1024 * 1024 // 20MiB // ServerConfig defines settings for creating an HTTP server. type ServerConfig struct { - // Endpoint configures the listening address for the server. - Endpoint string `mapstructure:"endpoint,omitempty"` + // NetAddr holds configuration for the network listener. + // + // Transport defaults to "tcp" if unspecified, and only + // "tcp", "tcp4", "tcp6", and "unix" are valid options. + NetAddr confignet.AddrConfig `mapstructure:",squash"` - // TLS struct exposes TLS client configuration. + // TLS struct exposes TLS server configuration. TLS configoptional.Optional[configtls.ServerConfig] `mapstructure:"tls"` // CORS configures the server for HTTP cross-origin resource sharing (CORS). @@ -102,7 +107,12 @@ type ServerConfig struct { // NewDefaultServerConfig returns ServerConfig type object with default values. // We encourage to use this function to create an object of ServerConfig. func NewDefaultServerConfig() ServerConfig { + netAddr := confignet.NewDefaultAddrConfig() + // We typically want to create a TCP server and listen over a network. + netAddr.Transport = confignet.TransportTypeTCP + return ServerConfig{ + NetAddr: netAddr, WriteTimeout: 30 * time.Second, ReadHeaderTimeout: 1 * time.Minute, IdleTimeout: 1 * time.Minute, @@ -123,7 +133,7 @@ type AuthConfig struct { // ToListener creates a net.Listener. func (sc *ServerConfig) ToListener(ctx context.Context) (net.Listener, error) { - listener, err := net.Listen("tcp", sc.Endpoint) + listener, err := sc.NetAddr.Listen(ctx) if err != nil { return nil, err } @@ -197,7 +207,7 @@ func (sc *ServerConfig) ToServer(ctx context.Context, extensions map[component.I if err != nil { return nil, err } - handler, err = wrapper(handler) + handler, err = wrapper(ctx, handler) // If we failed to construct a wrapper if err != nil { return nil, err @@ -257,13 +267,18 @@ func (sc *ServerConfig) ToServer(ctx context.Context, extensions map[component.I // // "HTTP span names SHOULD be {method} {target} if there is a (low-cardinality) target available. // If there is no (low-cardinality) {target} available, HTTP span names SHOULD be {method}. - // ... + // + // The {method} MUST be {http.request.method} if the method represents the original method known + // to the instrumentation. In other cases (when {http.request.method} is set to _OTHER), + // {method} MUST be HTTP. + // // Instrumentation MUST NOT default to using URI path as a {target}." // + method := standardizeHTTPMethod(r.Method, "HTTP") if r.Pattern != "" { - return r.Method + " " + r.Pattern + return method + " " + r.Pattern } - return r.Method + return method }), otelhttp.WithMeterProvider(settings.MeterProvider), }, @@ -369,3 +384,14 @@ func maxRequestBodySizeInterceptor(next http.Handler, maxRecvSize int64) http.Ha next.ServeHTTP(w, r) }) } + +// standardizeHTTPMethod returns an upper case HTTP method if well-known, otherwise unknown. +// Based on https://github.com/open-telemetry/opentelemetry-go-contrib/blob/1530d71edc6d40d0659187d069081b639ef1b394/instrumentation/github.com/emicklei/go-restful/otelrestful/internal/semconv/util.go#L119 +func standardizeHTTPMethod(method, unknown string) string { + method = strings.ToUpper(method) + switch method { + case http.MethodConnect, http.MethodDelete, http.MethodGet, http.MethodHead, http.MethodOptions, http.MethodPatch, http.MethodPost, http.MethodPut, http.MethodTrace: + return method + } + return unknown +} diff --git a/config/confighttp/server_middleware_test.go b/config/confighttp/server_middleware_test.go index f48fae08bd1c..f94146b94c14 100644 --- a/config/confighttp/server_middleware_test.go +++ b/config/confighttp/server_middleware_test.go @@ -17,6 +17,7 @@ import ( "go.opentelemetry.io/collector/component" "go.opentelemetry.io/collector/component/componenttest" "go.opentelemetry.io/collector/config/configmiddleware" + "go.opentelemetry.io/collector/config/confignet" "go.opentelemetry.io/collector/extension" "go.opentelemetry.io/collector/extension/extensionmiddleware" "go.opentelemetry.io/collector/extension/extensionmiddleware/extensionmiddlewaretest" @@ -31,17 +32,19 @@ type testServerMiddleware struct { func newTestServerMiddleware(name string) component.Component { return &testServerMiddleware{ Extension: extensionmiddlewaretest.NewNop(), - GetHTTPHandlerFunc: func(handler http.Handler) (http.Handler, error) { - return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - // Append middleware name to the URL path - r.URL.Path += name + "/" + GetHTTPHandlerFunc: func(_ context.Context) (extensionmiddleware.WrapHTTPHandlerFunc, error) { + return func(_ context.Context, handler http.Handler) (http.Handler, error) { + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + // Append middleware name to the URL path + r.URL.Path += name + "/" - // Call the next handler in the chain - handler.ServeHTTP(w, r) + // Call the next handler in the chain + handler.ServeHTTP(w, r) - // Add middleware name to the response - _, _ = w.Write([]byte("\r\nserved by " + name)) - }), nil + // Add middleware name to the response + _, _ = w.Write([]byte("\r\nserved by " + name)) + }), nil + }, nil }, } } @@ -91,7 +94,10 @@ func TestServerMiddleware(t *testing.T) { t.Run(tc.name, func(t *testing.T) { // Create server config with the test middlewares cfg := ServerConfig{ - Endpoint: "localhost:0", + NetAddr: confignet.AddrConfig{ + Endpoint: "localhost:0", + Transport: confignet.TransportTypeTCP, + }, Middlewares: tc.middlewares, } @@ -148,7 +154,10 @@ func TestServerMiddlewareErrors(t *testing.T) { name: "extension_not_found", extensions: map[component.ID]component.Component{}, config: ServerConfig{ - Endpoint: "localhost:0", + NetAddr: confignet.AddrConfig{ + Endpoint: "localhost:0", + Transport: confignet.TransportTypeTCP, + }, Middlewares: []configmiddleware.Config{ { ID: component.MustNewID("nonexistent"), @@ -163,7 +172,10 @@ func TestServerMiddlewareErrors(t *testing.T) { component.MustNewID("errormw"): extensionmiddlewaretest.NewErr(errors.New("http middleware error")), }, config: ServerConfig{ - Endpoint: "localhost:0", + NetAddr: confignet.AddrConfig{ + Endpoint: "localhost:0", + Transport: confignet.TransportTypeTCP, + }, Middlewares: []configmiddleware.Config{ { ID: component.MustNewID("errormw"), @@ -199,7 +211,10 @@ func TestServerMiddlewareErrors(t *testing.T) { name: "grpc_extension_not_found", extensions: map[component.ID]component.Component{}, config: ServerConfig{ - Endpoint: "localhost:0", + NetAddr: confignet.AddrConfig{ + Endpoint: "localhost:0", + Transport: confignet.TransportTypeTCP, + }, Middlewares: []configmiddleware.Config{ { ID: component.MustNewID("nonexistent"), @@ -214,7 +229,10 @@ func TestServerMiddlewareErrors(t *testing.T) { component.MustNewID("errormw"): extensionmiddlewaretest.NewErr(errors.New("grpc middleware error")), }, config: ServerConfig{ - Endpoint: "localhost:0", + NetAddr: confignet.AddrConfig{ + Endpoint: "localhost:0", + Transport: confignet.TransportTypeTCP, + }, Middlewares: []configmiddleware.Config{ { ID: component.MustNewID("errormw"), diff --git a/config/confighttp/server_test.go b/config/confighttp/server_test.go index 5db0af79a811..75520a13fa68 100644 --- a/config/confighttp/server_test.go +++ b/config/confighttp/server_test.go @@ -9,9 +9,11 @@ import ( "errors" "fmt" "io" + "net" "net/http" "net/http/httptest" "path/filepath" + "runtime" "strconv" "strings" "testing" @@ -23,7 +25,7 @@ import ( "go.opentelemetry.io/collector/component" "go.opentelemetry.io/collector/component/componenttest" "go.opentelemetry.io/collector/config/configauth" - "go.opentelemetry.io/collector/config/configmiddleware" + "go.opentelemetry.io/collector/config/confignet" "go.opentelemetry.io/collector/config/configopaque" "go.opentelemetry.io/collector/config/configoptional" "go.opentelemetry.io/collector/config/configtls" @@ -56,7 +58,10 @@ func TestHTTPServerSettingsError(t *testing.T) { { err: "^failed to load TLS config: failed to load CA CertPool File: failed to load cert /doesnt/exist:", settings: ServerConfig{ - Endpoint: "localhost:0", + NetAddr: confignet.AddrConfig{ + Endpoint: "localhost:0", + Transport: confignet.TransportTypeTCP, + }, TLS: configoptional.Some(configtls.ServerConfig{ Config: configtls.Config{ CAFile: "/doesnt/exist", @@ -67,7 +72,10 @@ func TestHTTPServerSettingsError(t *testing.T) { { err: "^failed to load TLS config: failed to load TLS cert and key: for auth via TLS, provide both certificate and key, or neither", settings: ServerConfig{ - Endpoint: "localhost:0", + NetAddr: confignet.AddrConfig{ + Endpoint: "localhost:0", + Transport: confignet.TransportTypeTCP, + }, TLS: configoptional.Some(configtls.ServerConfig{ Config: configtls.Config{ CertFile: "/doesnt/exist", @@ -78,7 +86,10 @@ func TestHTTPServerSettingsError(t *testing.T) { { err: "failed to load client CA CertPool: failed to load CA /doesnt/exist:", settings: ServerConfig{ - Endpoint: "localhost:0", + NetAddr: confignet.AddrConfig{ + Endpoint: "localhost:0", + Transport: confignet.TransportTypeTCP, + }, TLS: configoptional.Some(configtls.ServerConfig{ ClientCAFile: "/doesnt/exist", }), @@ -93,7 +104,7 @@ func TestHTTPServerSettingsError(t *testing.T) { } } -func TestHttpReception(t *testing.T) { +func TestHTTPServerTLS(t *testing.T) { tests := []struct { name string tlsServerCreds configoptional.Optional[configtls.ServerConfig] @@ -219,25 +230,19 @@ func TestHttpReception(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { sc := &ServerConfig{ - Endpoint: "localhost:0", - TLS: tt.tlsServerCreds, + NetAddr: confignet.AddrConfig{ + Endpoint: "localhost:0", + Transport: confignet.TransportTypeTCP, + }, + TLS: tt.tlsServerCreds, } ln, err := sc.ToListener(context.Background()) require.NoError(t, err) - s, err := sc.ToServer( - context.Background(), - nil, - componenttest.NewNopTelemetrySettings(), - http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) { - _, errWrite := fmt.Fprint(w, "tt") - assert.NoError(t, errWrite) - })) - require.NoError(t, err) - - go func() { - _ = s.Serve(ln) - }() + startServer(t, sc, ln, http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) { + _, errWrite := fmt.Fprint(w, "tt") + assert.NoError(t, errWrite) + })) prefix := "https://" expectedProto := "HTTP/2.0" @@ -270,12 +275,41 @@ func TestHttpReception(t *testing.T) { assert.Equal(t, "tt", string(body)) assert.Equal(t, expectedProto, resp.Proto) } - require.NoError(t, s.Close()) }) } } -func TestHttpCors(t *testing.T) { +func TestHTTPServerTransport(t *testing.T) { + if runtime.GOOS == "linux" { + t.Run("unix", func(t *testing.T) { + addr := "@" + t.Name() // abstract unix socket + sc := &ServerConfig{ + NetAddr: confignet.AddrConfig{ + Endpoint: addr, + Transport: confignet.TransportTypeUnix, + }, + } + ln, err := sc.ToListener(context.Background()) + require.NoError(t, err) + startServer(t, sc, ln, http.HandlerFunc(func(http.ResponseWriter, *http.Request) {})) + + client := http.Client{ + Transport: &http.Transport{ + DialContext: func(_ context.Context, _, _ string) (net.Conn, error) { + return net.Dial("unix", addr) + }, + }, + Timeout: 5 * time.Second, // Set a client-level timeout + } + resp, err := client.Get("http://whatever/foo") + require.NoError(t, err) + defer resp.Body.Close() + assert.Equal(t, http.StatusOK, resp.StatusCode) + }) + } +} + +func TestHTTPCors(t *testing.T) { tests := []struct { name string @@ -332,25 +366,19 @@ func TestHttpCors(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { sc := &ServerConfig{ - Endpoint: "localhost:0", - CORS: tt.CORSConfig, + NetAddr: confignet.AddrConfig{ + Endpoint: "localhost:0", + Transport: confignet.TransportTypeTCP, + }, + CORS: tt.CORSConfig, } ln, err := sc.ToListener(context.Background()) require.NoError(t, err) - s, err := sc.ToServer( - context.Background(), - nil, - componenttest.NewNopTelemetrySettings(), - http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) { - w.WriteHeader(http.StatusOK) - })) - require.NoError(t, err) - - go func() { - _ = s.Serve(ln) - }() + startServer(t, sc, ln, http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) { + w.WriteHeader(http.StatusOK) + })) url := "http://" + ln.Addr().String() @@ -367,16 +395,17 @@ func TestHttpCors(t *testing.T) { // Verify disallowed domain gets responses that disallow CORS. verifyCorsResp(t, url, "disallowed-origin.com", tt.CORSConfig, false, expectedStatus, tt.disallowedWorks) - - require.NoError(t, s.Close()) }) } } -func TestHttpCorsInvalidSettings(t *testing.T) { +func TestHTTPCorsInvalidSettings(t *testing.T) { sc := &ServerConfig{ - Endpoint: "localhost:0", - CORS: configoptional.Some(CORSConfig{AllowedHeaders: []string{"some-header"}}), + NetAddr: confignet.AddrConfig{ + Endpoint: "localhost:0", + Transport: confignet.TransportTypeTCP, + }, + CORS: configoptional.Some(CORSConfig{AllowedHeaders: []string{"some-header"}}), } // This effectively does not enable CORS but should also not cause an error @@ -390,9 +419,12 @@ func TestHttpCorsInvalidSettings(t *testing.T) { require.NoError(t, s.Close()) } -func TestHttpCorsWithSettings(t *testing.T) { +func TestHTTPCorsWithSettings(t *testing.T) { sc := &ServerConfig{ - Endpoint: "localhost:0", + NetAddr: confignet.AddrConfig{ + Endpoint: "localhost:0", + Transport: confignet.TransportTypeTCP, + }, CORS: configoptional.Some(CORSConfig{ AllowedOrigins: []string{"*"}, }), @@ -423,7 +455,7 @@ func TestHttpCorsWithSettings(t *testing.T) { assert.Equal(t, "*", rec.Header().Get("Access-Control-Allow-Origin")) } -func TestHttpServerHeaders(t *testing.T) { +func TestHTTPServerHeaders(t *testing.T) { tests := []struct { name string headers configopaque.MapList @@ -444,32 +476,24 @@ func TestHttpServerHeaders(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { sc := &ServerConfig{ - Endpoint: "localhost:0", + NetAddr: confignet.AddrConfig{ + Endpoint: "localhost:0", + Transport: confignet.TransportTypeTCP, + }, ResponseHeaders: tt.headers, } ln, err := sc.ToListener(context.Background()) require.NoError(t, err) - s, err := sc.ToServer( - context.Background(), - nil, - componenttest.NewNopTelemetrySettings(), - http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) { - w.WriteHeader(http.StatusOK) - })) - require.NoError(t, err) - - go func() { - _ = s.Serve(ln) - }() + startServer(t, sc, ln, http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) { + w.WriteHeader(http.StatusOK) + })) url := "http://" + ln.Addr().String() // Verify allowed domain gets responses that allow CORS. verifyHeadersResp(t, url, tt.headers) - - require.NoError(t, s.Close()) }) } } @@ -529,7 +553,10 @@ func TestServerAuth(t *testing.T) { // prepare authCalled := false sc := ServerConfig{ - Endpoint: "localhost:0", + NetAddr: confignet.AddrConfig{ + Endpoint: "localhost:0", + Transport: confignet.TransportTypeTCP, + }, Auth: configoptional.Some(AuthConfig{ Config: configauth.Config{ AuthenticatorID: mockID, @@ -577,7 +604,10 @@ func TestInvalidServerAuth(t *testing.T) { func TestFailedServerAuth(t *testing.T) { // prepare sc := ServerConfig{ - Endpoint: "localhost:0", + NetAddr: confignet.AddrConfig{ + Endpoint: "localhost:0", + Transport: confignet.TransportTypeTCP, + }, Auth: configoptional.Some(AuthConfig{ Config: configauth.Config{ AuthenticatorID: mockID, @@ -605,7 +635,10 @@ func TestFailedServerAuth(t *testing.T) { func TestFailedServerAuthWithErrorHandler(t *testing.T) { // prepare sc := ServerConfig{ - Endpoint: "localhost:0", + NetAddr: confignet.AddrConfig{ + Endpoint: "localhost:0", + Transport: confignet.TransportTypeTCP, + }, Auth: configoptional.Some(AuthConfig{ Config: configauth.Config{ AuthenticatorID: mockID, @@ -641,7 +674,10 @@ func TestFailedServerAuthWithErrorHandler(t *testing.T) { func TestServerWithErrorHandler(t *testing.T) { // prepare sc := ServerConfig{ - Endpoint: "localhost:0", + NetAddr: confignet.AddrConfig{ + Endpoint: "localhost:0", + Transport: confignet.TransportTypeTCP, + }, } eh := func(w http.ResponseWriter, _ *http.Request, _ string, statusCode int) { assert.Equal(t, http.StatusBadRequest, statusCode) @@ -672,7 +708,7 @@ func TestServerWithErrorHandler(t *testing.T) { func TestServerWithDecoder(t *testing.T) { // prepare sc := NewDefaultServerConfig() - sc.Endpoint = "localhost:0" + sc.NetAddr.Endpoint = "localhost:0" decoder := func(body io.ReadCloser) (io.ReadCloser, error) { return body, nil } @@ -788,7 +824,10 @@ func TestAuthWithQueryParams(t *testing.T) { // prepare authCalled := false sc := ServerConfig{ - Endpoint: "localhost:0", + NetAddr: confignet.AddrConfig{ + Endpoint: "localhost:0", + Transport: confignet.TransportTypeTCP, + }, Auth: configoptional.Some(AuthConfig{ RequestParameters: []string{"auth"}, Config: configauth.Config{ @@ -822,7 +861,7 @@ func TestAuthWithQueryParams(t *testing.T) { assert.True(t, authCalled) } -func BenchmarkHttpRequest(b *testing.B) { +func BenchmarkHTTPRequest(b *testing.B) { tests := []struct { name string forceHTTP1 bool @@ -865,28 +904,20 @@ func BenchmarkHttpRequest(b *testing.B) { } sc := &ServerConfig{ - Endpoint: "localhost:0", - TLS: tlsServerCreds, + NetAddr: confignet.AddrConfig{ + Endpoint: "localhost:0", + Transport: confignet.TransportTypeTCP, + }, + TLS: tlsServerCreds, } - s, err := sc.ToServer( - context.Background(), - nil, - componenttest.NewNopTelemetrySettings(), - http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) { - _, errWrite := fmt.Fprint(w, "tt") - assert.NoError(b, errWrite) - })) - require.NoError(b, err) ln, err := sc.ToListener(context.Background()) require.NoError(b, err) - go func() { - _ = s.Serve(ln) - }() - defer func() { - _ = s.Close() - }() + startServer(b, sc, ln, http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) { + _, errWrite := fmt.Fprint(w, "tt") + assert.NoError(b, errWrite) + })) for _, bb := range tests { cc := &ClientConfig{ @@ -957,35 +988,24 @@ func TestHTTPServerKeepAlives(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { sc := &ServerConfig{ - Endpoint: "localhost:0", + NetAddr: confignet.AddrConfig{ + Endpoint: "localhost:0", + Transport: confignet.TransportTypeTCP, + }, KeepAlivesEnabled: tt.keepAlivesEnabled, } - server, err := sc.ToServer( - context.Background(), - nil, - componenttest.NewNopTelemetrySettings(), - http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) { - w.WriteHeader(http.StatusOK) - })) - + ln, err := sc.ToListener(context.Background()) require.NoError(t, err) - require.NotNil(t, server) + + startServer(t, sc, ln, http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) { + w.WriteHeader(http.StatusOK) + })) // Since http.Server.disableKeepAlives is a private field and difficult to test directly, // we'll verify the configuration was set by testing the server behavior. // The main verification is that ToServer() succeeds without error when DisableKeepAlives is set. - ln, err := sc.ToListener(context.Background()) - require.NoError(t, err) - - go func() { - _ = server.Serve(ln) - }() - defer func() { - _ = server.Close() - }() - resp, err := http.Get("http://" + ln.Addr().String()) require.NoError(t, err) require.NotNil(t, resp) @@ -1005,28 +1025,41 @@ func TestHTTPServerTelemetry_Tracing(t *testing.T) { type testcase struct { handler http.Handler + httpMethod string expectedSpanName string } - for name, testcase := range map[string]testcase{ + for name, tc := range map[string]testcase{ "pattern": { handler: mux, + httpMethod: "GET", expectedSpanName: "GET /b/{bucket}/o/{objectname...}", }, "no_pattern": { handler: http.HandlerFunc(func(http.ResponseWriter, *http.Request) {}), + httpMethod: "GET", expectedSpanName: "GET", }, + "unknown_method": { + handler: mux, + httpMethod: "FOOBAR", + expectedSpanName: "HTTP /b/{bucket}/o/{objectname...}", + }, + "lowercase_method": { + handler: mux, + httpMethod: "get", + expectedSpanName: "GET /b/{bucket}/o/{objectname...}", + }, } { t.Run(name, func(t *testing.T) { telemetry := componenttest.NewTelemetry() config := NewDefaultServerConfig() - config.Endpoint = "localhost:0" + config.NetAddr.Endpoint = "localhost:0" srv, err := config.ToServer( context.Background(), nil, telemetry.NewTelemetrySettings(), - testcase.handler, + tc.handler, ) require.NoError(t, err) @@ -1042,14 +1075,16 @@ func TestHTTPServerTelemetry_Tracing(t *testing.T) { <-done }() - resp, err := http.Get(fmt.Sprintf("http://%s/b/bucket123/o/object456/segment", lis.Addr())) + req, err := http.NewRequest(tc.httpMethod, fmt.Sprintf("http://%s/b/bucket123/o/object456/segment", lis.Addr()), http.NoBody) + require.NoError(t, err) + resp, err := http.DefaultClient.Do(req) require.NoError(t, err) require.Equal(t, http.StatusOK, resp.StatusCode) resp.Body.Close() spans := telemetry.SpanRecorder.Ended() require.Len(t, spans, 1) - assert.Equal(t, testcase.expectedSpanName, spans[0].Name()) + assert.Equal(t, tc.expectedSpanName, spans[0].Name()) }) } } @@ -1069,7 +1104,7 @@ func TestServerUnmarshalYAMLWithMiddlewares(t *testing.T) { // Validate the server configuration using reflection-based validation require.NoError(t, xconfmap.Validate(&serverConfig), "Server configuration should be valid") - assert.Equal(t, "0.0.0.0:4318", serverConfig.Endpoint) + assert.Equal(t, "0.0.0.0:4318", serverConfig.NetAddr.Endpoint) require.Len(t, serverConfig.Middlewares, 2) assert.Equal(t, component.MustNewID("careful_middleware"), serverConfig.Middlewares[0].ID) assert.Equal(t, component.MustNewID("support_middleware"), serverConfig.Middlewares[1].ID) @@ -1091,7 +1126,7 @@ func TestServerUnmarshalYAMLComprehensiveConfig(t *testing.T) { require.NoError(t, xconfmap.Validate(&serverConfig), "Server configuration should be valid") // Verify basic fields - assert.Equal(t, "0.0.0.0:4318", serverConfig.Endpoint) + assert.Equal(t, "0.0.0.0:4318", serverConfig.NetAddr.Endpoint) assert.Equal(t, 30*time.Second, serverConfig.ReadTimeout) assert.Equal(t, 10*time.Second, serverConfig.ReadHeaderTimeout) assert.Equal(t, 30*time.Second, serverConfig.WriteTimeout) @@ -1131,17 +1166,11 @@ func TestServerUnmarshalYAMLComprehensiveConfig(t *testing.T) { assert.Equal(t, component.MustNewID("server_middleware3"), serverConfig.Middlewares[2].ID) } -// TestMiddlewaresFieldCompatibility tests that the new "middlewares" field name -// is used instead of the old "middleware" name, ensuring the bug is fixed -func TestServerMiddlewaresFieldCompatibility(t *testing.T) { - // Test that we can create a config with middlewares using the new field name - serverConfig := ServerConfig{ - Endpoint: "0.0.0.0:4318", - Middlewares: []configmiddleware.Config{ - {ID: component.MustNewID("server_middleware")}, - }, - } - assert.Equal(t, "0.0.0.0:4318", serverConfig.Endpoint) - assert.Len(t, serverConfig.Middlewares, 1) - assert.Equal(t, component.MustNewID("server_middleware"), serverConfig.Middlewares[0].ID) +func startServer(tb testing.TB, sc *ServerConfig, ln net.Listener, h http.Handler) { + s, err := sc.ToServer(tb.Context(), nil, componenttest.NewNopTelemetrySettings(), h) + require.NoError(tb, err) + tb.Cleanup(func() { + require.NoError(tb, s.Close()) + }) + go func() { _ = s.Serve(ln) }() } diff --git a/config/confighttp/testdata/config.yaml b/config/confighttp/testdata/config.yaml index 0b241df6fb9c..3aae5f75b63b 100644 --- a/config/confighttp/testdata/config.yaml +++ b/config/confighttp/testdata/config.yaml @@ -61,6 +61,7 @@ client: server: # Network endpoint configuration endpoint: "0.0.0.0:4318" + transport: tcp # TLS configuration tls: diff --git a/config/confighttp/testdata/middlewares.yaml b/config/confighttp/testdata/middlewares.yaml index fb705743e54a..569f17b6c5c0 100644 --- a/config/confighttp/testdata/middlewares.yaml +++ b/config/confighttp/testdata/middlewares.yaml @@ -8,6 +8,7 @@ client: server: endpoint: "0.0.0.0:4318" + transport: tcp middlewares: - id: "careful_middleware" - id: "support_middleware" diff --git a/config/confighttp/xconfighttp/go.mod b/config/confighttp/xconfighttp/go.mod index 9dfce7d442d6..7553af25020a 100644 --- a/config/confighttp/xconfighttp/go.mod +++ b/config/confighttp/xconfighttp/go.mod @@ -1,70 +1,71 @@ module go.opentelemetry.io/collector/config/confighttp/xconfighttp -go 1.24.0 +go 1.25.0 require ( github.com/stretchr/testify v1.11.1 go.opentelemetry.io/collector/component/componenttest v0.140.0 go.opentelemetry.io/collector/config/confighttp v0.140.0 + go.opentelemetry.io/collector/config/confignet v0.0.0-00010101000000-000000000000 go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.63.0 go.opentelemetry.io/otel/sdk v1.40.0 - go.opentelemetry.io/otel/trace v1.40.0 + go.opentelemetry.io/otel/trace v1.42.0 ) require ( github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/davecgh/go-spew v1.1.1 // indirect github.com/felixge/httpsnoop v1.0.4 // indirect - github.com/foxboron/go-tpm-keyfiles v0.0.0-20250903184740-5d135037bd4d // indirect + github.com/foxboron/go-tpm-keyfiles v0.0.0-20251226215517-609e4778396f // indirect github.com/fsnotify/fsnotify v1.9.0 // indirect github.com/go-logr/logr v1.4.3 // indirect github.com/go-logr/stdr v1.2.2 // indirect - github.com/go-viper/mapstructure/v2 v2.4.0 // indirect + github.com/go-viper/mapstructure/v2 v2.5.0 // indirect github.com/gobwas/glob v0.2.3 // indirect github.com/golang/snappy v1.0.0 // indirect - github.com/google/go-tpm v0.9.7 // indirect + github.com/google/go-tpm v0.9.8 // indirect github.com/google/uuid v1.6.0 // indirect - github.com/hashicorp/go-version v1.7.0 // indirect + github.com/hashicorp/go-version v1.8.0 // indirect github.com/json-iterator/go v1.1.12 // indirect - github.com/klauspost/compress v1.18.1 // indirect + github.com/klauspost/compress v1.18.4 // indirect github.com/knadh/koanf/maps v0.1.2 // indirect github.com/knadh/koanf/providers/confmap v1.0.0 // indirect - github.com/knadh/koanf/v2 v2.3.0 // indirect + github.com/knadh/koanf/v2 v2.3.3 // indirect github.com/mitchellh/copystructure v1.2.0 // indirect github.com/mitchellh/reflectwalk v1.0.2 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee // indirect - github.com/pierrec/lz4/v4 v4.1.22 // indirect + github.com/pierrec/lz4/v4 v4.1.26 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect github.com/rs/cors v1.11.1 // indirect go.opentelemetry.io/auto/sdk v1.2.1 // indirect go.opentelemetry.io/collector/client v1.46.0 // indirect - go.opentelemetry.io/collector/component v1.46.0 // indirect + go.opentelemetry.io/collector/component v1.54.0 // indirect go.opentelemetry.io/collector/config/configauth v1.46.0 // indirect go.opentelemetry.io/collector/config/configcompression v1.46.0 // indirect go.opentelemetry.io/collector/config/configmiddleware v1.46.0 // indirect - go.opentelemetry.io/collector/config/configopaque v1.46.0 // indirect + go.opentelemetry.io/collector/config/configopaque v1.54.0 // indirect go.opentelemetry.io/collector/config/configoptional v1.46.0 // indirect go.opentelemetry.io/collector/config/configtls v1.46.0 // indirect - go.opentelemetry.io/collector/confmap v1.46.0 // indirect - go.opentelemetry.io/collector/confmap/xconfmap v0.140.0 // indirect - go.opentelemetry.io/collector/extension/extensionauth v1.46.0 // indirect - go.opentelemetry.io/collector/extension/extensionmiddleware v0.140.0 // indirect - go.opentelemetry.io/collector/featuregate v1.46.0 // indirect - go.opentelemetry.io/collector/pdata v1.46.0 // indirect - go.opentelemetry.io/otel v1.40.0 // indirect - go.opentelemetry.io/otel/metric v1.40.0 // indirect + go.opentelemetry.io/collector/confmap v1.54.0 // indirect + go.opentelemetry.io/collector/confmap/xconfmap v0.148.0 // indirect + go.opentelemetry.io/collector/extension/extensionauth v1.54.0 // indirect + go.opentelemetry.io/collector/extension/extensionmiddleware v0.148.0 // indirect + go.opentelemetry.io/collector/featuregate v1.54.0 // indirect + go.opentelemetry.io/collector/pdata v1.54.0 // indirect + go.opentelemetry.io/otel v1.42.0 // indirect + go.opentelemetry.io/otel/metric v1.42.0 // indirect go.opentelemetry.io/otel/sdk/metric v1.40.0 // indirect go.uber.org/multierr v1.11.0 // indirect go.uber.org/zap v1.27.1 // indirect go.yaml.in/yaml/v3 v3.0.4 // indirect - golang.org/x/crypto v0.45.0 // indirect - golang.org/x/net v0.47.0 // indirect - golang.org/x/sys v0.40.0 // indirect - golang.org/x/text v0.31.0 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20251022142026-3a174f9686a8 // indirect - google.golang.org/grpc v1.77.0 // indirect - google.golang.org/protobuf v1.36.10 // indirect + golang.org/x/crypto v0.48.0 // indirect + golang.org/x/net v0.51.0 // indirect + golang.org/x/sys v0.41.0 // indirect + golang.org/x/text v0.34.0 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20251222181119-0a764e51fe1b // indirect + google.golang.org/grpc v1.79.3 // indirect + google.golang.org/protobuf v1.36.11 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) @@ -102,6 +103,8 @@ replace go.opentelemetry.io/collector/extension/extensionmiddleware => ../../../ replace go.opentelemetry.io/collector/config/configmiddleware => ../../configmiddleware +replace go.opentelemetry.io/collector/config/confignet => ../../confignet + replace go.opentelemetry.io/collector/extension/extensionmiddleware/extensionmiddlewaretest => ../../../extension/extensionmiddleware/extensionmiddlewaretest replace go.opentelemetry.io/collector/confmap => ../../../confmap @@ -109,3 +112,5 @@ replace go.opentelemetry.io/collector/confmap => ../../../confmap replace go.opentelemetry.io/collector/confmap/xconfmap => ../../../confmap/xconfmap replace go.opentelemetry.io/collector/internal/testutil => ../../../internal/testutil + +replace go.opentelemetry.io/collector/internal/componentalias => ../../../internal/componentalias diff --git a/config/confighttp/xconfighttp/go.sum b/config/confighttp/xconfighttp/go.sum index f9df5f2d7a82..402ae45b7926 100644 --- a/config/confighttp/xconfighttp/go.sum +++ b/config/confighttp/xconfighttp/go.sum @@ -5,10 +5,8 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg= github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= -github.com/foxboron/go-tpm-keyfiles v0.0.0-20250903184740-5d135037bd4d h1:EdO/NMMuCZfxhdzTZLuKAciQSnI2DV+Ppg8+vAYrnqA= -github.com/foxboron/go-tpm-keyfiles v0.0.0-20250903184740-5d135037bd4d/go.mod h1:uAyTlAUxchYuiFjTHmuIEJ4nGSm7iOPaGcAyA81fJ80= -github.com/foxboron/swtpm_test v0.0.0-20230726224112-46aaafdf7006 h1:50sW4r0PcvlpG4PV8tYh2RVCapszJgaOLRCS2subvV4= -github.com/foxboron/swtpm_test v0.0.0-20230726224112-46aaafdf7006/go.mod h1:eIXCMsMYCaqq9m1KSSxXwQG11krpuNPGP3k0uaWrbas= +github.com/foxboron/go-tpm-keyfiles v0.0.0-20251226215517-609e4778396f h1:RJ+BDPLSHQO7cSjKBqjPJSbi1qfk9WcsjQDtZiw3dZw= +github.com/foxboron/go-tpm-keyfiles v0.0.0-20251226215517-609e4778396f/go.mod h1:VHbbch/X4roIY22jL1s3qRbZhCiRIgUAF/PdSUcx2io= github.com/fsnotify/fsnotify v1.9.0 h1:2Ml+OJNzbYCTzsxtv8vKSFD9PbJjmhYF14k/jKC7S9k= github.com/fsnotify/fsnotify v1.9.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= @@ -16,8 +14,8 @@ github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI= github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= -github.com/go-viper/mapstructure/v2 v2.4.0 h1:EBsztssimR/CONLSZZ04E8qAkxNYq4Qp9LvH92wZUgs= -github.com/go-viper/mapstructure/v2 v2.4.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM= +github.com/go-viper/mapstructure/v2 v2.5.0 h1:vM5IJoUAy3d7zRSVtIwQgBj7BiWtMPfmPEgAXnvj1Ro= +github.com/go-viper/mapstructure/v2 v2.5.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM= github.com/gobwas/glob v0.2.3 h1:A4xDbljILXROh+kObIiy5kIaPYD8e96x1tgBhUI5J+Y= github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8= github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= @@ -26,25 +24,25 @@ github.com/golang/snappy v1.0.0 h1:Oy607GVXHs7RtbggtPBnr2RmDArIsAefDwvrdWvRhGs= github.com/golang/snappy v1.0.0/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= -github.com/google/go-tpm v0.9.7 h1:u89J4tUUeDTlH8xxC3CTW7OHZjbjKoHdQ9W7gCUhtxA= -github.com/google/go-tpm v0.9.7/go.mod h1:h9jEsEECg7gtLis0upRBQU+GhYVH6jMjrFxI8u6bVUY= -github.com/google/go-tpm-tools v0.4.4 h1:oiQfAIkc6xTy9Fl5NKTeTJkBTlXdHsxAofmQyxBKY98= -github.com/google/go-tpm-tools v0.4.4/go.mod h1:T8jXkp2s+eltnCDIsXR84/MTcVU9Ja7bh3Mit0pa4AY= +github.com/google/go-tpm v0.9.8 h1:slArAR9Ft+1ybZu0lBwpSmpwhRXaa85hWtMinMyRAWo= +github.com/google/go-tpm v0.9.8/go.mod h1:h9jEsEECg7gtLis0upRBQU+GhYVH6jMjrFxI8u6bVUY= +github.com/google/go-tpm-tools v0.4.7 h1:J3ycC8umYxM9A4eF73EofRZu4BxY0jjQnUnkhIBbvws= +github.com/google/go-tpm-tools v0.4.7/go.mod h1:gSyXTZHe3fgbzb6WEGd90QucmsnT1SRdlye82gH8QjQ= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/hashicorp/go-version v1.7.0 h1:5tqGy27NaOTB8yJKUZELlFAS/LTKJkrmONwQKeRZfjY= -github.com/hashicorp/go-version v1.7.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= +github.com/hashicorp/go-version v1.8.0 h1:KAkNb1HAiZd1ukkxDFGmokVZe1Xy9HG6NUp+bPle2i4= +github.com/hashicorp/go-version v1.8.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= -github.com/klauspost/compress v1.18.1 h1:bcSGx7UbpBqMChDtsF28Lw6v/G94LPrrbMbdC3JH2co= -github.com/klauspost/compress v1.18.1/go.mod h1:ZQFFVG+MdnR0P+l6wpXgIL4NTtwiKIdBnrBd8Nrxr+0= +github.com/klauspost/compress v1.18.4 h1:RPhnKRAQ4Fh8zU2FY/6ZFDwTVTxgJ/EMydqSTzE9a2c= +github.com/klauspost/compress v1.18.4/go.mod h1:R0h/fSBs8DE4ENlcrlib3PsXS61voFxhIs2DeRhCvJ4= github.com/knadh/koanf/maps v0.1.2 h1:RBfmAW5CnZT+PJ1CVc1QSJKf4Xu9kxfQgYVQSu8hpbo= github.com/knadh/koanf/maps v0.1.2/go.mod h1:npD/QZY3V6ghQDdcQzl1W4ICNVTkohC8E73eI2xW4yI= github.com/knadh/koanf/providers/confmap v1.0.0 h1:mHKLJTE7iXEys6deO5p6olAiZdG5zwp8Aebir+/EaRE= github.com/knadh/koanf/providers/confmap v1.0.0/go.mod h1:txHYHiI2hAtF0/0sCmcuol4IDcuQbKTybiB1nOcUo1A= -github.com/knadh/koanf/v2 v2.3.0 h1:Qg076dDRFHvqnKG97ZEsi9TAg2/nFTa9hCdcSa1lvlM= -github.com/knadh/koanf/v2 v2.3.0/go.mod h1:gRb40VRAbd4iJMYYD5IxZ6hfuopFcXBpc9bbQpZwo28= +github.com/knadh/koanf/v2 v2.3.3 h1:jLJC8XCRfLC7n4F+ZKKdBsbq1bfXTpuFhf4L7t94D94= +github.com/knadh/koanf/v2 v2.3.3/go.mod h1:gRb40VRAbd4iJMYYD5IxZ6hfuopFcXBpc9bbQpZwo28= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= @@ -59,8 +57,8 @@ github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJ github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee h1:W5t00kpgFdJifH4BDsTlE89Zl93FEloxaWZfGcifgq8= github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= -github.com/pierrec/lz4/v4 v4.1.22 h1:cKFw6uJDK+/gfw5BcDL0JL5aBsAFdsIT18eRtLj7VIU= -github.com/pierrec/lz4/v4 v4.1.22/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4= +github.com/pierrec/lz4/v4 v4.1.26 h1:GrpZw1gZttORinvzBdXPUXATeqlJjqUG/D87TKMnhjY= +github.com/pierrec/lz4/v4 v4.1.26/go.mod h1:EoQMVJgeeEOMsCqCzqFm2O0cJvljX2nGZjcRIPL34O4= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ= @@ -75,22 +73,22 @@ go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.63.0 h1:RbKq8BG0FI8OiXhBfcRtqqHcZcka+gU3cskNuf05R18= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.63.0/go.mod h1:h06DGIukJOevXaj/xrNjhi/2098RZzcLTbc0jDAUbsg= -go.opentelemetry.io/otel v1.40.0 h1:oA5YeOcpRTXq6NN7frwmwFR0Cn3RhTVZvXsP4duvCms= -go.opentelemetry.io/otel v1.40.0/go.mod h1:IMb+uXZUKkMXdPddhwAHm6UfOwJyh4ct1ybIlV14J0g= -go.opentelemetry.io/otel/metric v1.40.0 h1:rcZe317KPftE2rstWIBitCdVp89A2HqjkxR3c11+p9g= -go.opentelemetry.io/otel/metric v1.40.0/go.mod h1:ib/crwQH7N3r5kfiBZQbwrTge743UDc7DTFVZrrXnqc= +go.opentelemetry.io/otel v1.42.0 h1:lSQGzTgVR3+sgJDAU/7/ZMjN9Z+vUip7leaqBKy4sho= +go.opentelemetry.io/otel v1.42.0/go.mod h1:lJNsdRMxCUIWuMlVJWzecSMuNjE7dOYyWlqOXWkdqCc= +go.opentelemetry.io/otel/metric v1.42.0 h1:2jXG+3oZLNXEPfNmnpxKDeZsFI5o4J+nz6xUlaFdF/4= +go.opentelemetry.io/otel/metric v1.42.0/go.mod h1:RlUN/7vTU7Ao/diDkEpQpnz3/92J9ko05BIwxYa2SSI= go.opentelemetry.io/otel/sdk v1.40.0 h1:KHW/jUzgo6wsPh9At46+h4upjtccTmuZCFAc9OJ71f8= go.opentelemetry.io/otel/sdk v1.40.0/go.mod h1:Ph7EFdYvxq72Y8Li9q8KebuYUr2KoeyHx0DRMKrYBUE= go.opentelemetry.io/otel/sdk/metric v1.40.0 h1:mtmdVqgQkeRxHgRv4qhyJduP3fYJRMX4AtAlbuWdCYw= go.opentelemetry.io/otel/sdk/metric v1.40.0/go.mod h1:4Z2bGMf0KSK3uRjlczMOeMhKU2rhUqdWNoKcYrtcBPg= -go.opentelemetry.io/otel/trace v1.40.0 h1:WA4etStDttCSYuhwvEa8OP8I5EWu24lkOzp+ZYblVjw= -go.opentelemetry.io/otel/trace v1.40.0/go.mod h1:zeAhriXecNGP/s2SEG3+Y8X9ujcJOTqQ5RgdEJcawiA= -go.opentelemetry.io/proto/slim/otlp v1.9.0 h1:fPVMv8tP3TrsqlkH1HWYUpbCY9cAIemx184VGkS6vlE= -go.opentelemetry.io/proto/slim/otlp v1.9.0/go.mod h1:xXdeJJ90Gqyll+orzUkY4bOd2HECo5JofeoLpymVqdI= -go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.2.0 h1:o13nadWDNkH/quoDomDUClnQBpdQQ2Qqv0lQBjIXjE8= -go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.2.0/go.mod h1:Gyb6Xe7FTi/6xBHwMmngGoHqL0w29Y4eW8TGFzpefGA= -go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.2.0 h1:EiUYvtwu6PMrMHVjcPfnsG3v+ajPkbUeH+IL93+QYyk= -go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.2.0/go.mod h1:mUUHKFiN2SST3AhJ8XhJxEoeVW12oqfXog0Bo8W3Ec4= +go.opentelemetry.io/otel/trace v1.42.0 h1:OUCgIPt+mzOnaUTpOQcBiM/PLQ/Op7oq6g4LenLmOYY= +go.opentelemetry.io/otel/trace v1.42.0/go.mod h1:f3K9S+IFqnumBkKhRJMeaZeNk9epyhnCmQh/EysQCdc= +go.opentelemetry.io/proto/slim/otlp v1.10.0 h1:iR97Vs/ZDR+y9TfuP9b1XBtdPWeC+OMslIBmhcLU7jM= +go.opentelemetry.io/proto/slim/otlp v1.10.0/go.mod h1:lV9250stpjYLPNA5viFabIgP2QlUGRT1GdTgAf8SIUk= +go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.3.0 h1:RUF5rO0hAlgiJt1fzQVzcVs3vZVNHIcMLgOgG4rWNcQ= +go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.3.0/go.mod h1:I89cynRj8y+383o7tEQVg2SVA6SRgDVIouWPUVXjx0U= +go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.3.0 h1:CQvJSldHRUN6Z8jsUeYv8J0lXRvygALXIzsmAeCcZE0= +go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.3.0/go.mod h1:xSQ+mEfJe/GjK1LXEyVOoSI1N9JV9ZI923X5kup43W4= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= @@ -99,22 +97,22 @@ go.uber.org/zap v1.27.1 h1:08RqriUEv8+ArZRYSTXy1LeBScaMpVSTBhCeaZYfMYc= go.uber.org/zap v1.27.1/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc= go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg= -golang.org/x/crypto v0.45.0 h1:jMBrvKuj23MTlT0bQEOBcAE0mjg8mK9RXFhRH6nyF3Q= -golang.org/x/crypto v0.45.0/go.mod h1:XTGrrkGJve7CYK7J8PEww4aY7gM3qMCElcJQ8n8JdX4= -golang.org/x/net v0.47.0 h1:Mx+4dIFzqraBXUugkia1OOvlD6LemFo1ALMHjrXDOhY= -golang.org/x/net v0.47.0/go.mod h1:/jNxtkgq5yWUGYkaZGqo27cfGZ1c5Nen03aYrrKpVRU= -golang.org/x/sys v0.40.0 h1:DBZZqJ2Rkml6QMQsZywtnjnnGvHza6BTfYFWY9kjEWQ= -golang.org/x/sys v0.40.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= -golang.org/x/text v0.31.0 h1:aC8ghyu4JhP8VojJ2lEHBnochRno1sgL6nEi9WGFGMM= -golang.org/x/text v0.31.0/go.mod h1:tKRAlv61yKIjGGHX/4tP1LTbc13YSec1pxVEWXzfoeM= +golang.org/x/crypto v0.48.0 h1:/VRzVqiRSggnhY7gNRxPauEQ5Drw9haKdM0jqfcCFts= +golang.org/x/crypto v0.48.0/go.mod h1:r0kV5h3qnFPlQnBSrULhlsRfryS2pmewsg+XfMgkVos= +golang.org/x/net v0.51.0 h1:94R/GTO7mt3/4wIKpcR5gkGmRLOuE/2hNGeWq/GBIFo= +golang.org/x/net v0.51.0/go.mod h1:aamm+2QF5ogm02fjy5Bb7CQ0WMt1/WVM7FtyaTLlA9Y= +golang.org/x/sys v0.41.0 h1:Ivj+2Cp/ylzLiEU89QhWblYnOE9zerudt9Ftecq2C6k= +golang.org/x/sys v0.41.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= +golang.org/x/text v0.34.0 h1:oL/Qq0Kdaqxa1KbNeMKwQq0reLCCaFtqu2eNuSeNHbk= +golang.org/x/text v0.34.0/go.mod h1:homfLqTYRFyVYemLBFl5GgL/DWEiH5wcsQ5gSh1yziA= gonum.org/v1/gonum v0.16.0 h1:5+ul4Swaf3ESvrOnidPp4GZbzf0mxVQpDCYUQE7OJfk= gonum.org/v1/gonum v0.16.0/go.mod h1:fef3am4MQ93R2HHpKnLk4/Tbh/s0+wqD5nfa6Pnwy4E= -google.golang.org/genproto/googleapis/rpc v0.0.0-20251022142026-3a174f9686a8 h1:M1rk8KBnUsBDg1oPGHNCxG4vc1f49epmTO7xscSajMk= -google.golang.org/genproto/googleapis/rpc v0.0.0-20251022142026-3a174f9686a8/go.mod h1:7i2o+ce6H/6BluujYR+kqX3GKH+dChPTQU19wjRPiGk= -google.golang.org/grpc v1.77.0 h1:wVVY6/8cGA6vvffn+wWK5ToddbgdU3d8MNENr4evgXM= -google.golang.org/grpc v1.77.0/go.mod h1:z0BY1iVj0q8E1uSQCjL9cppRj+gnZjzDnzV0dHhrNig= -google.golang.org/protobuf v1.36.10 h1:AYd7cD/uASjIL6Q9LiTjz8JLcrh/88q5UObnmY3aOOE= -google.golang.org/protobuf v1.36.10/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= +google.golang.org/genproto/googleapis/rpc v0.0.0-20251222181119-0a764e51fe1b h1:Mv8VFug0MP9e5vUxfBcE3vUkV6CImK3cMNMIDFjmzxU= +google.golang.org/genproto/googleapis/rpc v0.0.0-20251222181119-0a764e51fe1b/go.mod h1:j9x/tPzZkyxcgEFkiKEEGxfvyumM01BEtsW8xzOahRQ= +google.golang.org/grpc v1.79.3 h1:sybAEdRIEtvcD68Gx7dmnwjZKlyfuc61Dyo9pGXXkKE= +google.golang.org/grpc v1.79.3/go.mod h1:KmT0Kjez+0dde/v2j9vzwoAScgEPx/Bw1CYChhHLrHQ= +google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE= +google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= diff --git a/config/confighttp/xconfighttp/metadata.yaml b/config/confighttp/xconfighttp/metadata.yaml new file mode 100644 index 000000000000..8166a4353f32 --- /dev/null +++ b/config/confighttp/xconfighttp/metadata.yaml @@ -0,0 +1,6 @@ +type: config/confighttp/xconfighttp +github_project: open-telemetry/opentelemetry-collector + +status: + disable_codecov_badge: true + class: pkg diff --git a/config/confighttp/xconfighttp/options_test.go b/config/confighttp/xconfighttp/options_test.go index e9b0c46db75d..1828c582baf0 100644 --- a/config/confighttp/xconfighttp/options_test.go +++ b/config/confighttp/xconfighttp/options_test.go @@ -18,12 +18,16 @@ import ( "go.opentelemetry.io/collector/component/componenttest" "go.opentelemetry.io/collector/config/confighttp" + "go.opentelemetry.io/collector/config/confignet" ) func TestServerWithOtelHTTPOptions(t *testing.T) { // prepare sc := confighttp.ServerConfig{ - Endpoint: "localhost:0", + NetAddr: confignet.AddrConfig{ + Endpoint: "localhost:0", + Transport: confignet.TransportTypeTCP, + }, } telemetry := componenttest.NewNopTelemetrySettings() diff --git a/config/configmiddleware/config.schema.yaml b/config/configmiddleware/config.schema.yaml new file mode 100644 index 000000000000..13dba6c7ec9a --- /dev/null +++ b/config/configmiddleware/config.schema.yaml @@ -0,0 +1,9 @@ +$defs: + config: + description: Middleware defines the extension ID for a middleware component. + type: object + properties: + id: + description: ID specifies the name of the extension to use. + type: string + x-customType: go.opentelemetry.io/collector/component.ID diff --git a/config/configmiddleware/configmiddleware.go b/config/configmiddleware/configmiddleware.go index 831ba7766fec..88fa509dc38c 100644 --- a/config/configmiddleware/configmiddleware.go +++ b/config/configmiddleware/configmiddleware.go @@ -9,7 +9,6 @@ import ( "context" "errors" "fmt" - "net/http" "google.golang.org/grpc" @@ -38,10 +37,10 @@ type Config struct { // returns the HTTP client wrapper function. If a middleware is not // found, an error is returned. This should only be used by HTTP // clients. -func (m Config) GetHTTPClientRoundTripper(_ context.Context, extensions map[component.ID]component.Component) (func(http.RoundTripper) (http.RoundTripper, error), error) { +func (m Config) GetHTTPClientRoundTripper(ctx context.Context, extensions map[component.ID]component.Component) (extensionmiddleware.WrapHTTPRoundTripperFunc, error) { if ext, found := extensions[m.ID]; found { if client, ok := ext.(extensionmiddleware.HTTPClient); ok { - return client.GetHTTPRoundTripper, nil + return client.GetHTTPRoundTripper(ctx) } return nil, errNotHTTPClient } @@ -53,10 +52,10 @@ func (m Config) GetHTTPClientRoundTripper(_ context.Context, extensions map[comp // returns the http.Handler wrapper function. If a middleware is not // found, an error is returned. This should only be used by HTTP // servers. -func (m Config) GetHTTPServerHandler(_ context.Context, extensions map[component.ID]component.Component) (func(http.Handler) (http.Handler, error), error) { +func (m Config) GetHTTPServerHandler(ctx context.Context, extensions map[component.ID]component.Component) (extensionmiddleware.WrapHTTPHandlerFunc, error) { if ext, found := extensions[m.ID]; found { if server, ok := ext.(extensionmiddleware.HTTPServer); ok { - return server.GetHTTPHandler, nil + return server.GetHTTPHandler(ctx) } return nil, errNotHTTPServer } @@ -68,10 +67,10 @@ func (m Config) GetHTTPServerHandler(_ context.Context, extensions map[component // extensionmiddleware.GRPCClient from the map of extensions, and // returns the gRPC dial options. If a middleware is not found, an // error is returned. This should only be used by gRPC clients. -func (m Config) GetGRPCClientOptions(_ context.Context, extensions map[component.ID]component.Component) ([]grpc.DialOption, error) { +func (m Config) GetGRPCClientOptions(ctx context.Context, extensions map[component.ID]component.Component) ([]grpc.DialOption, error) { if ext, found := extensions[m.ID]; found { if client, ok := ext.(extensionmiddleware.GRPCClient); ok { - return client.GetGRPCClientOptions() + return client.GetGRPCClientOptions(ctx) } return nil, errNotGRPCClient } @@ -82,10 +81,10 @@ func (m Config) GetGRPCClientOptions(_ context.Context, extensions map[component // extensionmiddleware.GRPCServer from the map of extensions, and // returns the gRPC server options. If a middleware is not found, an // error is returned. This should only be used by gRPC servers. -func (m Config) GetGRPCServerOptions(_ context.Context, extensions map[component.ID]component.Component) ([]grpc.ServerOption, error) { +func (m Config) GetGRPCServerOptions(ctx context.Context, extensions map[component.ID]component.Component) ([]grpc.ServerOption, error) { if ext, found := extensions[m.ID]; found { if server, ok := ext.(extensionmiddleware.GRPCServer); ok { - return server.GetGRPCServerOptions() + return server.GetGRPCServerOptions(ctx) } return nil, errNotGRPCServer } diff --git a/config/configmiddleware/configmiddleware_test.go b/config/configmiddleware/configmiddleware_test.go index 5cdb2628fbaf..7551f5346ecf 100644 --- a/config/configmiddleware/configmiddleware_test.go +++ b/config/configmiddleware/configmiddleware_test.go @@ -149,7 +149,7 @@ func TestConfig_GetGRPCServerOptions(t *testing.T) { extensionmiddleware.GetGRPCServerOptionsFunc }{ Extension: extensionmiddlewaretest.NewNop(), - GetGRPCServerOptionsFunc: func() ([]grpc.ServerOption, error) { + GetGRPCServerOptionsFunc: func(context.Context) ([]grpc.ServerOption, error) { return []grpc.ServerOption{ grpc.EmptyServerOption{}, }, nil @@ -212,7 +212,7 @@ func TestConfig_GetGRPCClientOptions(t *testing.T) { extensionmiddleware.GetGRPCClientOptionsFunc }{ Extension: extensionmiddlewaretest.NewNop(), - GetGRPCClientOptionsFunc: func() ([]grpc.DialOption, error) { + GetGRPCClientOptionsFunc: func(_ context.Context) ([]grpc.DialOption, error) { return []grpc.DialOption{ grpc.EmptyDialOption{}, }, nil diff --git a/config/configmiddleware/go.mod b/config/configmiddleware/go.mod index 437d16a037ca..a9548a5be09c 100644 --- a/config/configmiddleware/go.mod +++ b/config/configmiddleware/go.mod @@ -1,37 +1,38 @@ module go.opentelemetry.io/collector/config/configmiddleware -go 1.24.0 +go 1.25.0 require ( github.com/stretchr/testify v1.11.1 - go.opentelemetry.io/collector/component v1.46.0 - go.opentelemetry.io/collector/extension v1.46.0 - go.opentelemetry.io/collector/extension/extensionmiddleware v0.140.0 - go.opentelemetry.io/collector/extension/extensionmiddleware/extensionmiddlewaretest v0.140.0 - google.golang.org/grpc v1.77.0 + go.opentelemetry.io/collector/component v1.54.0 + go.opentelemetry.io/collector/extension v1.54.0 + go.opentelemetry.io/collector/extension/extensionmiddleware v0.148.0 + go.opentelemetry.io/collector/extension/extensionmiddleware/extensionmiddlewaretest v0.148.0 + google.golang.org/grpc v1.79.3 ) require ( github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/davecgh/go-spew v1.1.1 // indirect - github.com/hashicorp/go-version v1.7.0 // indirect + github.com/hashicorp/go-version v1.8.0 // indirect github.com/json-iterator/go v1.1.12 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee // indirect github.com/pmezard/go-difflib v1.0.0 // indirect - go.opentelemetry.io/collector/featuregate v1.46.0 // indirect - go.opentelemetry.io/collector/pdata v1.46.0 // indirect - go.opentelemetry.io/otel v1.40.0 // indirect - go.opentelemetry.io/otel/metric v1.40.0 // indirect + go.opentelemetry.io/collector/featuregate v1.54.0 // indirect + go.opentelemetry.io/collector/internal/componentalias v0.148.0 // indirect + go.opentelemetry.io/collector/pdata v1.54.0 // indirect + go.opentelemetry.io/otel v1.42.0 // indirect + go.opentelemetry.io/otel/metric v1.42.0 // indirect go.opentelemetry.io/otel/sdk v1.40.0 // indirect - go.opentelemetry.io/otel/trace v1.40.0 // indirect + go.opentelemetry.io/otel/trace v1.42.0 // indirect go.uber.org/multierr v1.11.0 // indirect go.uber.org/zap v1.27.1 // indirect - golang.org/x/net v0.46.1-0.20251013234738-63d1a5100f82 // indirect - golang.org/x/sys v0.40.0 // indirect - golang.org/x/text v0.30.0 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20251022142026-3a174f9686a8 // indirect - google.golang.org/protobuf v1.36.10 // indirect + golang.org/x/net v0.51.0 // indirect + golang.org/x/sys v0.41.0 // indirect + golang.org/x/text v0.34.0 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20251222181119-0a764e51fe1b // indirect + google.golang.org/protobuf v1.36.11 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) @@ -48,3 +49,5 @@ replace go.opentelemetry.io/collector/featuregate => ../../featuregate replace go.opentelemetry.io/collector/extension => ../../extension replace go.opentelemetry.io/collector/internal/testutil => ../../internal/testutil + +replace go.opentelemetry.io/collector/internal/componentalias => ../../internal/componentalias diff --git a/config/configmiddleware/go.sum b/config/configmiddleware/go.sum index cd4bad993d65..7e33dd95f22e 100644 --- a/config/configmiddleware/go.sum +++ b/config/configmiddleware/go.sum @@ -14,8 +14,8 @@ github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/hashicorp/go-version v1.7.0 h1:5tqGy27NaOTB8yJKUZELlFAS/LTKJkrmONwQKeRZfjY= -github.com/hashicorp/go-version v1.7.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= +github.com/hashicorp/go-version v1.8.0 h1:KAkNb1HAiZd1ukkxDFGmokVZe1Xy9HG6NUp+bPle2i4= +github.com/hashicorp/go-version v1.8.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= @@ -38,42 +38,42 @@ github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64= go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y= -go.opentelemetry.io/otel v1.40.0 h1:oA5YeOcpRTXq6NN7frwmwFR0Cn3RhTVZvXsP4duvCms= -go.opentelemetry.io/otel v1.40.0/go.mod h1:IMb+uXZUKkMXdPddhwAHm6UfOwJyh4ct1ybIlV14J0g= -go.opentelemetry.io/otel/metric v1.40.0 h1:rcZe317KPftE2rstWIBitCdVp89A2HqjkxR3c11+p9g= -go.opentelemetry.io/otel/metric v1.40.0/go.mod h1:ib/crwQH7N3r5kfiBZQbwrTge743UDc7DTFVZrrXnqc= +go.opentelemetry.io/otel v1.42.0 h1:lSQGzTgVR3+sgJDAU/7/ZMjN9Z+vUip7leaqBKy4sho= +go.opentelemetry.io/otel v1.42.0/go.mod h1:lJNsdRMxCUIWuMlVJWzecSMuNjE7dOYyWlqOXWkdqCc= +go.opentelemetry.io/otel/metric v1.42.0 h1:2jXG+3oZLNXEPfNmnpxKDeZsFI5o4J+nz6xUlaFdF/4= +go.opentelemetry.io/otel/metric v1.42.0/go.mod h1:RlUN/7vTU7Ao/diDkEpQpnz3/92J9ko05BIwxYa2SSI= go.opentelemetry.io/otel/sdk v1.40.0 h1:KHW/jUzgo6wsPh9At46+h4upjtccTmuZCFAc9OJ71f8= go.opentelemetry.io/otel/sdk v1.40.0/go.mod h1:Ph7EFdYvxq72Y8Li9q8KebuYUr2KoeyHx0DRMKrYBUE= go.opentelemetry.io/otel/sdk/metric v1.40.0 h1:mtmdVqgQkeRxHgRv4qhyJduP3fYJRMX4AtAlbuWdCYw= go.opentelemetry.io/otel/sdk/metric v1.40.0/go.mod h1:4Z2bGMf0KSK3uRjlczMOeMhKU2rhUqdWNoKcYrtcBPg= -go.opentelemetry.io/otel/trace v1.40.0 h1:WA4etStDttCSYuhwvEa8OP8I5EWu24lkOzp+ZYblVjw= -go.opentelemetry.io/otel/trace v1.40.0/go.mod h1:zeAhriXecNGP/s2SEG3+Y8X9ujcJOTqQ5RgdEJcawiA= -go.opentelemetry.io/proto/slim/otlp v1.9.0 h1:fPVMv8tP3TrsqlkH1HWYUpbCY9cAIemx184VGkS6vlE= -go.opentelemetry.io/proto/slim/otlp v1.9.0/go.mod h1:xXdeJJ90Gqyll+orzUkY4bOd2HECo5JofeoLpymVqdI= -go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.2.0 h1:o13nadWDNkH/quoDomDUClnQBpdQQ2Qqv0lQBjIXjE8= -go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.2.0/go.mod h1:Gyb6Xe7FTi/6xBHwMmngGoHqL0w29Y4eW8TGFzpefGA= -go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.2.0 h1:EiUYvtwu6PMrMHVjcPfnsG3v+ajPkbUeH+IL93+QYyk= -go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.2.0/go.mod h1:mUUHKFiN2SST3AhJ8XhJxEoeVW12oqfXog0Bo8W3Ec4= +go.opentelemetry.io/otel/trace v1.42.0 h1:OUCgIPt+mzOnaUTpOQcBiM/PLQ/Op7oq6g4LenLmOYY= +go.opentelemetry.io/otel/trace v1.42.0/go.mod h1:f3K9S+IFqnumBkKhRJMeaZeNk9epyhnCmQh/EysQCdc= +go.opentelemetry.io/proto/slim/otlp v1.10.0 h1:iR97Vs/ZDR+y9TfuP9b1XBtdPWeC+OMslIBmhcLU7jM= +go.opentelemetry.io/proto/slim/otlp v1.10.0/go.mod h1:lV9250stpjYLPNA5viFabIgP2QlUGRT1GdTgAf8SIUk= +go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.3.0 h1:RUF5rO0hAlgiJt1fzQVzcVs3vZVNHIcMLgOgG4rWNcQ= +go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.3.0/go.mod h1:I89cynRj8y+383o7tEQVg2SVA6SRgDVIouWPUVXjx0U= +go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.3.0 h1:CQvJSldHRUN6Z8jsUeYv8J0lXRvygALXIzsmAeCcZE0= +go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.3.0/go.mod h1:xSQ+mEfJe/GjK1LXEyVOoSI1N9JV9ZI923X5kup43W4= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= go.uber.org/zap v1.27.1 h1:08RqriUEv8+ArZRYSTXy1LeBScaMpVSTBhCeaZYfMYc= go.uber.org/zap v1.27.1/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= -golang.org/x/net v0.46.1-0.20251013234738-63d1a5100f82 h1:6/3JGEh1C88g7m+qzzTbl3A0FtsLguXieqofVLU/JAo= -golang.org/x/net v0.46.1-0.20251013234738-63d1a5100f82/go.mod h1:Q9BGdFy1y4nkUwiLvT5qtyhAnEHgnQ/zd8PfU6nc210= -golang.org/x/sys v0.40.0 h1:DBZZqJ2Rkml6QMQsZywtnjnnGvHza6BTfYFWY9kjEWQ= -golang.org/x/sys v0.40.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= -golang.org/x/text v0.30.0 h1:yznKA/E9zq54KzlzBEAWn1NXSQ8DIp/NYMy88xJjl4k= -golang.org/x/text v0.30.0/go.mod h1:yDdHFIX9t+tORqspjENWgzaCVXgk0yYnYuSZ8UzzBVM= +golang.org/x/net v0.51.0 h1:94R/GTO7mt3/4wIKpcR5gkGmRLOuE/2hNGeWq/GBIFo= +golang.org/x/net v0.51.0/go.mod h1:aamm+2QF5ogm02fjy5Bb7CQ0WMt1/WVM7FtyaTLlA9Y= +golang.org/x/sys v0.41.0 h1:Ivj+2Cp/ylzLiEU89QhWblYnOE9zerudt9Ftecq2C6k= +golang.org/x/sys v0.41.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= +golang.org/x/text v0.34.0 h1:oL/Qq0Kdaqxa1KbNeMKwQq0reLCCaFtqu2eNuSeNHbk= +golang.org/x/text v0.34.0/go.mod h1:homfLqTYRFyVYemLBFl5GgL/DWEiH5wcsQ5gSh1yziA= gonum.org/v1/gonum v0.16.0 h1:5+ul4Swaf3ESvrOnidPp4GZbzf0mxVQpDCYUQE7OJfk= gonum.org/v1/gonum v0.16.0/go.mod h1:fef3am4MQ93R2HHpKnLk4/Tbh/s0+wqD5nfa6Pnwy4E= -google.golang.org/genproto/googleapis/rpc v0.0.0-20251022142026-3a174f9686a8 h1:M1rk8KBnUsBDg1oPGHNCxG4vc1f49epmTO7xscSajMk= -google.golang.org/genproto/googleapis/rpc v0.0.0-20251022142026-3a174f9686a8/go.mod h1:7i2o+ce6H/6BluujYR+kqX3GKH+dChPTQU19wjRPiGk= -google.golang.org/grpc v1.77.0 h1:wVVY6/8cGA6vvffn+wWK5ToddbgdU3d8MNENr4evgXM= -google.golang.org/grpc v1.77.0/go.mod h1:z0BY1iVj0q8E1uSQCjL9cppRj+gnZjzDnzV0dHhrNig= -google.golang.org/protobuf v1.36.10 h1:AYd7cD/uASjIL6Q9LiTjz8JLcrh/88q5UObnmY3aOOE= -google.golang.org/protobuf v1.36.10/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= +google.golang.org/genproto/googleapis/rpc v0.0.0-20251222181119-0a764e51fe1b h1:Mv8VFug0MP9e5vUxfBcE3vUkV6CImK3cMNMIDFjmzxU= +google.golang.org/genproto/googleapis/rpc v0.0.0-20251222181119-0a764e51fe1b/go.mod h1:j9x/tPzZkyxcgEFkiKEEGxfvyumM01BEtsW8xzOahRQ= +google.golang.org/grpc v1.79.3 h1:sybAEdRIEtvcD68Gx7dmnwjZKlyfuc61Dyo9pGXXkKE= +google.golang.org/grpc v1.79.3/go.mod h1:KmT0Kjez+0dde/v2j9vzwoAScgEPx/Bw1CYChhHLrHQ= +google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE= +google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= diff --git a/config/confignet/config.schema.yaml b/config/confignet/config.schema.yaml new file mode 100644 index 000000000000..369d409d9b1c --- /dev/null +++ b/config/confignet/config.schema.yaml @@ -0,0 +1,36 @@ +$defs: + addr_config: + description: AddrConfig represents a network endpoint address. + type: object + properties: + dialer: + description: DialerConfig contains options for connecting to an address. + $ref: dialer_config + endpoint: + description: Endpoint configures the address for this network connection. For TCP and UDP networks, the address has the form "host:port". The host must be a literal IP address, or a host name that can be resolved to IP addresses. The port must be a literal port number or a service name. If the host is a literal IPv6 address it must be enclosed in square brackets, as in "[2001:db8::1]:80" or "[fe80::1%zone]:80". The zone specifies the scope of the literal IPv6 address as defined in RFC 4007. + type: string + transport: + description: Transport to use. Allowed protocols are "tcp", "tcp4" (IPv4-only), "tcp6" (IPv6-only), "udp", "udp4" (IPv4-only), "udp6" (IPv6-only), "ip", "ip4" (IPv4-only), "ip6" (IPv6-only), "unix", "unixgram" and "unixpacket". + $ref: transport_type + dialer_config: + description: DialerConfig contains options for connecting to an address. + type: object + properties: + timeout: + description: Timeout is the maximum amount of time a dial will wait for a connect to complete. The default is no timeout. + type: string + x-customType: time.Duration + format: duration + tcp_addr_config: + description: TCPAddrConfig represents a TCP endpoint address. + type: object + properties: + dialer: + description: DialerConfig contains options for connecting to an address. + $ref: dialer_config + endpoint: + description: Endpoint configures the address for this network connection. The address has the form "host:port". The host must be a literal IP address, or a host name that can be resolved to IP addresses. The port must be a literal port number or a service name. If the host is a literal IPv6 address it must be enclosed in square brackets, as in "[2001:db8::1]:80" or "[fe80::1%zone]:80". The zone specifies the scope of the literal IPv6 address as defined in RFC 4007. + type: string + transport_type: + description: TransportType represents a type of network transport protocol + type: string diff --git a/config/confignet/go.mod b/config/confignet/go.mod index 9fd5f557643f..42c371d55079 100644 --- a/config/confignet/go.mod +++ b/config/confignet/go.mod @@ -1,6 +1,6 @@ module go.opentelemetry.io/collector/config/confignet -go 1.24.0 +go 1.25.0 require ( github.com/stretchr/testify v1.11.1 diff --git a/config/configopaque/config.schema.yaml b/config/configopaque/config.schema.yaml new file mode 100644 index 000000000000..6c226d023cd2 --- /dev/null +++ b/config/configopaque/config.schema.yaml @@ -0,0 +1,17 @@ +$defs: + map_list: + description: MapList is a replacement for map[string]configopaque.String with a similar API, which can also be unmarshalled from (and is stored as) a list of name/value pairs. Pairs are assumed to have distinct names. This is checked during config validation. + type: array + items: + $ref: pair + pair: + description: Pair is an element of a MapList, and consists of a name and an opaque value. + type: object + properties: + name: + type: string + value: + $ref: string + string: + description: String alias that is marshaled and printed in an opaque way. To recover the original value, cast it to a string. + type: string diff --git a/config/configopaque/doc_test.go b/config/configopaque/doc_test.go index 774c02dde0d2..d0df515ebf02 100644 --- a/config/configopaque/doc_test.go +++ b/config/configopaque/doc_test.go @@ -7,7 +7,7 @@ import ( "encoding/json" "fmt" - yaml "go.yaml.in/yaml/v3" + "go.yaml.in/yaml/v3" "go.opentelemetry.io/collector/config/configopaque" ) diff --git a/config/configopaque/go.mod b/config/configopaque/go.mod index 8a58233950f5..ed00ad199764 100644 --- a/config/configopaque/go.mod +++ b/config/configopaque/go.mod @@ -1,27 +1,27 @@ module go.opentelemetry.io/collector/config/configopaque -go 1.24.0 +go 1.25.0 require ( github.com/stretchr/testify v1.11.1 - go.opentelemetry.io/collector/confmap v1.46.0 - go.opentelemetry.io/collector/confmap/xconfmap v0.140.0 + go.opentelemetry.io/collector/confmap v1.54.0 + go.opentelemetry.io/collector/confmap/xconfmap v0.148.0 go.uber.org/goleak v1.3.0 go.yaml.in/yaml/v3 v3.0.4 ) require ( github.com/davecgh/go-spew v1.1.1 // indirect - github.com/go-viper/mapstructure/v2 v2.4.0 // indirect + github.com/go-viper/mapstructure/v2 v2.5.0 // indirect github.com/gobwas/glob v0.2.3 // indirect - github.com/hashicorp/go-version v1.7.0 // indirect + github.com/hashicorp/go-version v1.8.0 // indirect github.com/knadh/koanf/maps v0.1.2 // indirect github.com/knadh/koanf/providers/confmap v1.0.0 // indirect - github.com/knadh/koanf/v2 v2.3.0 // indirect + github.com/knadh/koanf/v2 v2.3.3 // indirect github.com/mitchellh/copystructure v1.2.0 // indirect github.com/mitchellh/reflectwalk v1.0.2 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect - go.opentelemetry.io/collector/featuregate v1.46.0 // indirect + go.opentelemetry.io/collector/featuregate v1.54.0 // indirect go.uber.org/multierr v1.11.0 // indirect go.uber.org/zap v1.27.1 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect diff --git a/config/configopaque/go.sum b/config/configopaque/go.sum index 6020e16119b7..d19c16bb075a 100644 --- a/config/configopaque/go.sum +++ b/config/configopaque/go.sum @@ -1,17 +1,17 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/go-viper/mapstructure/v2 v2.4.0 h1:EBsztssimR/CONLSZZ04E8qAkxNYq4Qp9LvH92wZUgs= -github.com/go-viper/mapstructure/v2 v2.4.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM= +github.com/go-viper/mapstructure/v2 v2.5.0 h1:vM5IJoUAy3d7zRSVtIwQgBj7BiWtMPfmPEgAXnvj1Ro= +github.com/go-viper/mapstructure/v2 v2.5.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM= github.com/gobwas/glob v0.2.3 h1:A4xDbljILXROh+kObIiy5kIaPYD8e96x1tgBhUI5J+Y= github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8= -github.com/hashicorp/go-version v1.7.0 h1:5tqGy27NaOTB8yJKUZELlFAS/LTKJkrmONwQKeRZfjY= -github.com/hashicorp/go-version v1.7.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= +github.com/hashicorp/go-version v1.8.0 h1:KAkNb1HAiZd1ukkxDFGmokVZe1Xy9HG6NUp+bPle2i4= +github.com/hashicorp/go-version v1.8.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/knadh/koanf/maps v0.1.2 h1:RBfmAW5CnZT+PJ1CVc1QSJKf4Xu9kxfQgYVQSu8hpbo= github.com/knadh/koanf/maps v0.1.2/go.mod h1:npD/QZY3V6ghQDdcQzl1W4ICNVTkohC8E73eI2xW4yI= github.com/knadh/koanf/providers/confmap v1.0.0 h1:mHKLJTE7iXEys6deO5p6olAiZdG5zwp8Aebir+/EaRE= github.com/knadh/koanf/providers/confmap v1.0.0/go.mod h1:txHYHiI2hAtF0/0sCmcuol4IDcuQbKTybiB1nOcUo1A= -github.com/knadh/koanf/v2 v2.3.0 h1:Qg076dDRFHvqnKG97ZEsi9TAg2/nFTa9hCdcSa1lvlM= -github.com/knadh/koanf/v2 v2.3.0/go.mod h1:gRb40VRAbd4iJMYYD5IxZ6hfuopFcXBpc9bbQpZwo28= +github.com/knadh/koanf/v2 v2.3.3 h1:jLJC8XCRfLC7n4F+ZKKdBsbq1bfXTpuFhf4L7t94D94= +github.com/knadh/koanf/v2 v2.3.3/go.mod h1:gRb40VRAbd4iJMYYD5IxZ6hfuopFcXBpc9bbQpZwo28= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= diff --git a/config/configoptional/documentation.md b/config/configoptional/documentation.md new file mode 100644 index 000000000000..103e65cfa624 --- /dev/null +++ b/config/configoptional/documentation.md @@ -0,0 +1,13 @@ +[comment]: <> (Code generated by mdatagen. DO NOT EDIT.) + +# configoptional + +## Feature Gates + +This component has the following feature gates: + +| Feature Gate | Stage | Description | From Version | To Version | Reference | +| ------------ | ----- | ----------- | ------------ | ---------- | --------- | +| `configoptional.AddEnabledField` | beta | Allows optional fields to be toggled via an 'enabled' field. | v0.138.0 | N/A | [Link](https://github.com/open-telemetry/opentelemetry-collector/issues/14021) | + +For more information about feature gates, see the [Feature Gates](https://github.com/open-telemetry/opentelemetry-collector/blob/main/featuregate/README.md) documentation. diff --git a/config/configoptional/package_test.go b/config/configoptional/generated_package_test.go similarity index 62% rename from config/configoptional/package_test.go rename to config/configoptional/generated_package_test.go index c64bec583325..3d4bb88ee12b 100644 --- a/config/configoptional/package_test.go +++ b/config/configoptional/generated_package_test.go @@ -1,5 +1,4 @@ -// Copyright The OpenTelemetry Authors -// SPDX-License-Identifier: Apache-2.0 +// Code generated by mdatagen. DO NOT EDIT. package configoptional diff --git a/config/configoptional/go.mod b/config/configoptional/go.mod index f3a7e80d218f..cbf1f28d5a7e 100644 --- a/config/configoptional/go.mod +++ b/config/configoptional/go.mod @@ -1,23 +1,23 @@ module go.opentelemetry.io/collector/config/configoptional -go 1.24.0 +go 1.25.0 require ( github.com/stretchr/testify v1.11.1 - go.opentelemetry.io/collector/confmap v1.46.0 - go.opentelemetry.io/collector/confmap/xconfmap v0.140.0 - go.opentelemetry.io/collector/featuregate v1.46.0 + go.opentelemetry.io/collector/confmap v1.54.0 + go.opentelemetry.io/collector/confmap/xconfmap v0.148.0 + go.opentelemetry.io/collector/featuregate v1.54.0 go.uber.org/goleak v1.3.0 ) require ( github.com/davecgh/go-spew v1.1.1 // indirect - github.com/go-viper/mapstructure/v2 v2.4.0 // indirect + github.com/go-viper/mapstructure/v2 v2.5.0 // indirect github.com/gobwas/glob v0.2.3 // indirect - github.com/hashicorp/go-version v1.7.0 // indirect + github.com/hashicorp/go-version v1.8.0 // indirect github.com/knadh/koanf/maps v0.1.2 // indirect github.com/knadh/koanf/providers/confmap v1.0.0 // indirect - github.com/knadh/koanf/v2 v2.3.0 // indirect + github.com/knadh/koanf/v2 v2.3.3 // indirect github.com/mitchellh/copystructure v1.2.0 // indirect github.com/mitchellh/reflectwalk v1.0.2 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect diff --git a/config/configoptional/go.sum b/config/configoptional/go.sum index 6020e16119b7..d19c16bb075a 100644 --- a/config/configoptional/go.sum +++ b/config/configoptional/go.sum @@ -1,17 +1,17 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/go-viper/mapstructure/v2 v2.4.0 h1:EBsztssimR/CONLSZZ04E8qAkxNYq4Qp9LvH92wZUgs= -github.com/go-viper/mapstructure/v2 v2.4.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM= +github.com/go-viper/mapstructure/v2 v2.5.0 h1:vM5IJoUAy3d7zRSVtIwQgBj7BiWtMPfmPEgAXnvj1Ro= +github.com/go-viper/mapstructure/v2 v2.5.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM= github.com/gobwas/glob v0.2.3 h1:A4xDbljILXROh+kObIiy5kIaPYD8e96x1tgBhUI5J+Y= github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8= -github.com/hashicorp/go-version v1.7.0 h1:5tqGy27NaOTB8yJKUZELlFAS/LTKJkrmONwQKeRZfjY= -github.com/hashicorp/go-version v1.7.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= +github.com/hashicorp/go-version v1.8.0 h1:KAkNb1HAiZd1ukkxDFGmokVZe1Xy9HG6NUp+bPle2i4= +github.com/hashicorp/go-version v1.8.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/knadh/koanf/maps v0.1.2 h1:RBfmAW5CnZT+PJ1CVc1QSJKf4Xu9kxfQgYVQSu8hpbo= github.com/knadh/koanf/maps v0.1.2/go.mod h1:npD/QZY3V6ghQDdcQzl1W4ICNVTkohC8E73eI2xW4yI= github.com/knadh/koanf/providers/confmap v1.0.0 h1:mHKLJTE7iXEys6deO5p6olAiZdG5zwp8Aebir+/EaRE= github.com/knadh/koanf/providers/confmap v1.0.0/go.mod h1:txHYHiI2hAtF0/0sCmcuol4IDcuQbKTybiB1nOcUo1A= -github.com/knadh/koanf/v2 v2.3.0 h1:Qg076dDRFHvqnKG97ZEsi9TAg2/nFTa9hCdcSa1lvlM= -github.com/knadh/koanf/v2 v2.3.0/go.mod h1:gRb40VRAbd4iJMYYD5IxZ6hfuopFcXBpc9bbQpZwo28= +github.com/knadh/koanf/v2 v2.3.3 h1:jLJC8XCRfLC7n4F+ZKKdBsbq1bfXTpuFhf4L7t94D94= +github.com/knadh/koanf/v2 v2.3.3/go.mod h1:gRb40VRAbd4iJMYYD5IxZ6hfuopFcXBpc9bbQpZwo28= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= diff --git a/config/configoptional/internal/metadata/generated_feature_gates.go b/config/configoptional/internal/metadata/generated_feature_gates.go new file mode 100644 index 000000000000..8818547d7eb7 --- /dev/null +++ b/config/configoptional/internal/metadata/generated_feature_gates.go @@ -0,0 +1,15 @@ +// Code generated by mdatagen. DO NOT EDIT. + +package metadata + +import ( + "go.opentelemetry.io/collector/featuregate" +) + +var ConfigoptionalAddEnabledFieldFeatureGate = featuregate.GlobalRegistry().MustRegister( + "configoptional.AddEnabledField", + featuregate.StageBeta, + featuregate.WithRegisterDescription("Allows optional fields to be toggled via an 'enabled' field."), + featuregate.WithRegisterReferenceURL("https://github.com/open-telemetry/opentelemetry-collector/issues/14021"), + featuregate.WithRegisterFromVersion("v0.138.0"), +) diff --git a/config/configoptional/metadata.yaml b/config/configoptional/metadata.yaml index 50724cfa91ea..cddc29450c7c 100644 --- a/config/configoptional/metadata.yaml +++ b/config/configoptional/metadata.yaml @@ -1,6 +1,16 @@ -type: config/configoptional +type: configoptional github_project: open-telemetry/opentelemetry-collector status: disable_codecov_badge: true class: pkg + stability: + beta: [metrics, traces, logs] + development: [profiles] + +feature_gates: + - id: configoptional.AddEnabledField + description: "Allows optional fields to be toggled via an 'enabled' field." + stage: beta + from_version: 'v0.138.0' + reference_url: 'https://github.com/open-telemetry/opentelemetry-collector/issues/14021' diff --git a/config/configoptional/optional.go b/config/configoptional/optional.go index 640b5d6a98f5..fad786616dd9 100644 --- a/config/configoptional/optional.go +++ b/config/configoptional/optional.go @@ -3,15 +3,17 @@ package configoptional // import "go.opentelemetry.io/collector/config/configoptional" +//go:generate mdatagen metadata.yaml + import ( "errors" "fmt" "reflect" "strings" + "go.opentelemetry.io/collector/config/configoptional/internal/metadata" "go.opentelemetry.io/collector/confmap" "go.opentelemetry.io/collector/confmap/xconfmap" - "go.opentelemetry.io/collector/featuregate" ) type flavor int @@ -167,17 +169,6 @@ func (o *Optional[T]) GetOrInsertDefault() *T { var _ confmap.Unmarshaler = (*Optional[any])(nil) -var ( - addEnabledFieldFeatureGateID = "configoptional.AddEnabledField" - addEnabledFieldFeatureGate = featuregate.GlobalRegistry().MustRegister( - addEnabledFieldFeatureGateID, - featuregate.StageBeta, - featuregate.WithRegisterFromVersion("v0.138.0"), - featuregate.WithRegisterDescription("Allows optional fields to be toggled via an 'enabled' field."), - featuregate.WithRegisterReferenceURL("https://github.com/open-telemetry/opentelemetry-collector/issues/14021"), - ) -) - // Unmarshal the configuration into the Optional value. // // The behavior of this method depends on the state of the Optional: @@ -205,7 +196,7 @@ func (o *Optional[T]) Unmarshal(conf *confmap.Conf) error { } isEnabled := true - if addEnabledFieldFeatureGate.IsEnabled() && conf.IsSet("enabled") { + if metadata.ConfigoptionalAddEnabledFieldFeatureGate.IsEnabled() && conf.IsSet("enabled") { enabled := conf.Get("enabled") conf.Delete("enabled") var ok bool @@ -214,7 +205,7 @@ func (o *Optional[T]) Unmarshal(conf *confmap.Conf) error { } } - if err := conf.Unmarshal(&o.value); err != nil { + if err := conf.Unmarshal(&o.value, xconfmap.WithForceUnmarshaler()); err != nil { return err } diff --git a/config/configoptional/optional_test.go b/config/configoptional/optional_test.go index 03414f215175..e97ba452ee09 100644 --- a/config/configoptional/optional_test.go +++ b/config/configoptional/optional_test.go @@ -11,6 +11,7 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + "go.opentelemetry.io/collector/config/configoptional/internal/metadata" "go.opentelemetry.io/collector/confmap" "go.opentelemetry.io/collector/confmap/confmaptest" "go.opentelemetry.io/collector/confmap/xconfmap" @@ -511,9 +512,11 @@ func TestAddFieldEnabledFeatureGate(t *testing.T) { }, } - oldVal := addEnabledFieldFeatureGate.IsEnabled() - require.NoError(t, featuregate.GlobalRegistry().Set(addEnabledFieldFeatureGateID, true)) - defer func() { require.NoError(t, featuregate.GlobalRegistry().Set(addEnabledFieldFeatureGateID, oldVal)) }() + oldVal := metadata.ConfigoptionalAddEnabledFieldFeatureGate.IsEnabled() + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.ConfigoptionalAddEnabledFieldFeatureGate.ID(), true)) + defer func() { + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.ConfigoptionalAddEnabledFieldFeatureGate.ID(), oldVal)) + }() for _, test := range tests { t.Run(test.name, func(t *testing.T) { @@ -529,9 +532,11 @@ func TestAddFieldEnabledFeatureGate(t *testing.T) { } func TestEnabledFalseResetsValue(t *testing.T) { - oldVal := addEnabledFieldFeatureGate.IsEnabled() - require.NoError(t, featuregate.GlobalRegistry().Set(addEnabledFieldFeatureGateID, true)) - defer func() { require.NoError(t, featuregate.GlobalRegistry().Set(addEnabledFieldFeatureGateID, oldVal)) }() + oldVal := metadata.ConfigoptionalAddEnabledFieldFeatureGate.IsEnabled() + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.ConfigoptionalAddEnabledFieldFeatureGate.ID(), true)) + defer func() { + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.ConfigoptionalAddEnabledFieldFeatureGate.ID(), oldVal)) + }() cfg := Config[Sub]{Sub1: Some(Sub{Foo: "initial"})} require.True(t, cfg.Sub1.HasValue()) @@ -544,9 +549,11 @@ func TestEnabledFalseResetsValue(t *testing.T) { } func TestUnmarshalErrorEnabledInvalidType(t *testing.T) { - oldVal := addEnabledFieldFeatureGate.IsEnabled() - require.NoError(t, featuregate.GlobalRegistry().Set(addEnabledFieldFeatureGateID, true)) - defer func() { require.NoError(t, featuregate.GlobalRegistry().Set(addEnabledFieldFeatureGateID, oldVal)) }() + oldVal := metadata.ConfigoptionalAddEnabledFieldFeatureGate.IsEnabled() + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.ConfigoptionalAddEnabledFieldFeatureGate.ID(), true)) + defer func() { + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.ConfigoptionalAddEnabledFieldFeatureGate.ID(), oldVal)) + }() cm := confmap.NewFromStringMap(map[string]any{ "sub": map[string]any{ diff --git a/config/configretry/config.schema.yaml b/config/configretry/config.schema.yaml new file mode 100644 index 000000000000..f8a4bab979ab --- /dev/null +++ b/config/configretry/config.schema.yaml @@ -0,0 +1,31 @@ +$defs: + back_off_config: + description: BackOffConfig defines configuration for retrying batches in case of export failure. The current supported strategy is exponential backoff. + type: object + properties: + enabled: + description: Enabled indicates whether to not retry sending batches in case of export failure. + type: boolean + initial_interval: + description: InitialInterval the time to wait after the first failure before retrying. + type: string + x-customType: time.Duration + format: duration + max_elapsed_time: + description: MaxElapsedTime is the maximum amount of time (including retries) spent trying to send a request/batch. Once this value is reached, the data is discarded. If set to 0, the retries are never stopped. + type: string + x-customType: time.Duration + format: duration + max_interval: + description: MaxInterval is the upper bound on backoff interval. Once this value is reached the delay between consecutive retries will always be `MaxInterval`. + type: string + x-customType: time.Duration + format: duration + multiplier: + description: Multiplier is the value multiplied by the backoff interval bounds + type: number + x-customType: float64 + randomization_factor: + description: RandomizationFactor is a random factor used to calculate next backoffs Randomized interval = RetryInterval * (1 ± RandomizationFactor) + type: number + x-customType: float64 diff --git a/config/configretry/go.mod b/config/configretry/go.mod index 215a66c17a22..900d0bf06c8b 100644 --- a/config/configretry/go.mod +++ b/config/configretry/go.mod @@ -1,6 +1,6 @@ module go.opentelemetry.io/collector/config/configretry -go 1.24.0 +go 1.25.0 require ( github.com/cenkalti/backoff/v5 v5.0.3 diff --git a/config/configtelemetry/config.schema.yaml b/config/configtelemetry/config.schema.yaml new file mode 100644 index 000000000000..674f389267ec --- /dev/null +++ b/config/configtelemetry/config.schema.yaml @@ -0,0 +1,5 @@ +$defs: + level: + description: Level is the level of internal telemetry (metrics, logs, traces about the component itself) that every component should generate. + type: integer + x-customType: int32 diff --git a/config/configtelemetry/go.mod b/config/configtelemetry/go.mod index d7cf1c4f0d8e..c5c3750fea5a 100644 --- a/config/configtelemetry/go.mod +++ b/config/configtelemetry/go.mod @@ -1,6 +1,6 @@ module go.opentelemetry.io/collector/config/configtelemetry -go 1.24.0 +go 1.25.0 require ( github.com/stretchr/testify v1.11.1 diff --git a/config/configtls/README.md b/config/configtls/README.md index 792312233564..3db0c8b93986 100644 --- a/config/configtls/README.md +++ b/config/configtls/README.md @@ -57,7 +57,7 @@ __IMPORTANT__: TLS 1.0 and 1.1 are deprecated due to known vulnerabilities and s - `min_version` (default = "1.2"): Minimum acceptable TLS version. - options: ["1.0", "1.1", "1.2", "1.3"] -- `max_version` (default = "" handled by [crypto/tls](https://github.com/golang/go/blob/ed9db1d36ad6ef61095d5941ad9ee6da7ab6d05a/src/crypto/tls/common.go#L700) - currently TLS 1.3): Maximum acceptable TLS version. +- `max_version` (default = "" handled by [crypto/tls](https://github.com/golang/go/blob/ed9db1d36ad6ef61095d5941ad9ee6da7ab6d05a/src/crypto/tls/common.go) - currently TLS 1.3): Maximum acceptable TLS version. - options: ["1.0", "1.1", "1.2", "1.3"] Explicit cipher suites can be set. If left blank, a safe default list is used. See https://go.dev/src/crypto/tls/cipher_suites.go for a list of supported cipher suites. @@ -99,7 +99,7 @@ Example: ```yaml exporters: - otlp: + otlp_grpc: endpoint: myserver.local:55690 tls: insecure: false @@ -174,7 +174,7 @@ Example: ```yaml exporters: - otlp: + otlp_grpc: endpoint: myserver.local:55690 tls: ca_file: ca.crt @@ -185,4 +185,4 @@ exporters: path: /dev/tpmrm0 ``` -The `client-tss2.key` private key with TSS2 format will be loaded from the TPM device `/dev/tpmrm0`. \ No newline at end of file +The `client-tss2.key` private key with TSS2 format will be loaded from the TPM device `/dev/tpmrm0`. diff --git a/config/configtls/config.schema.yaml b/config/configtls/config.schema.yaml new file mode 100644 index 000000000000..11f094120924 --- /dev/null +++ b/config/configtls/config.schema.yaml @@ -0,0 +1,90 @@ +$defs: + client_config: + description: ClientConfig contains TLS configurations that are specific to client connections in addition to the common configurations. This should be used by components configuring TLS client connections. + type: object + properties: + insecure: + description: In gRPC and HTTP when set to true, this is used to disable the client transport security. See https://godoc.org/google.golang.org/grpc#WithInsecure for gRPC. Please refer to https://godoc.org/crypto/tls#Config for more information. (optional, default false) + type: boolean + insecure_skip_verify: + description: InsecureSkipVerify will enable TLS but not verify the certificate. + type: boolean + server_name_override: + description: ServerName requested by client for virtual hosting. This sets the ServerName in the TLSConfig. Please refer to https://godoc.org/crypto/tls#Config for more information. (optional) + type: string + allOf: + - $ref: config + config: + description: 'Config exposes the common client and server TLS configurations. Note: Since there isn''t anything specific to a server connection. Components with server connections should use Config.' + type: object + properties: + ca_file: + description: Path to the CA cert. For a client this verifies the server certificate. For a server this verifies client certificates. If empty uses system root CA. (optional) + type: string + ca_pem: + description: In memory PEM encoded cert. (optional) + $ref: /config/configopaque.string + cert_file: + description: Path to the TLS cert to use for TLS required connections. (optional) + type: string + cert_pem: + description: In memory PEM encoded TLS cert to use for TLS required connections. (optional) + $ref: /config/configopaque.string + cipher_suites: + description: CipherSuites is a list of TLS cipher suites that the TLS transport can use. If left blank, a safe default list is used. See https://go.dev/src/crypto/tls/cipher_suites.go for a list of supported cipher suites. + type: array + items: + type: string + curve_preferences: + description: contains the elliptic curves that will be used in an ECDHE handshake, in preference order Defaults to empty list and "crypto/tls" defaults are used, internally. + type: array + items: + type: string + include_system_ca_certs_pool: + description: If true, load system CA certificates pool in addition to the certificates configured in this struct. + type: boolean + key_file: + description: Path to the TLS key to use for TLS required connections. (optional) + type: string + key_pem: + description: In memory PEM encoded TLS key to use for TLS required connections. (optional) + $ref: /config/configopaque.string + max_version: + description: MaxVersion sets the maximum TLS version that is acceptable. If not set, refer to crypto/tls for defaults. (optional) + type: string + min_version: + description: MinVersion sets the minimum TLS version that is acceptable. If not set, TLS 1.2 will be used. (optional) + type: string + reload_interval: + description: ReloadInterval specifies the duration after which the certificate will be reloaded If not set, it will never be reloaded (optional) + type: string + x-customType: time.Duration + format: duration + tpm: + description: Trusted platform module configuration + $ref: tpm_config + server_config: + description: ServerConfig contains TLS configurations that are specific to server connections in addition to the common configurations. This should be used by components configuring TLS server connections. + type: object + properties: + client_ca_file: + description: Path to the TLS cert to use by the server to verify a client certificate. (optional) This sets the ClientCAs and ClientAuth to RequireAndVerifyClientCert in the TLSConfig. Please refer to https://godoc.org/crypto/tls#Config for more information. (optional) + type: string + client_ca_file_reload: + description: Reload the ClientCAs file when it is modified (optional, default false) + type: boolean + allOf: + - $ref: config + tpm_config: + description: TPMConfig defines trusted platform module configuration for storing TLS keys. + type: object + properties: + auth: + type: string + enabled: + type: boolean + owner_auth: + type: string + path: + description: The path to the TPM device or Unix domain socket. For instance /dev/tpm0 or /dev/tpmrm0. + type: string diff --git a/config/configtls/go.mod b/config/configtls/go.mod index 632fa127952e..d43a851b83d1 100644 --- a/config/configtls/go.mod +++ b/config/configtls/go.mod @@ -1,35 +1,36 @@ module go.opentelemetry.io/collector/config/configtls -go 1.24.0 +go 1.25.0 require ( github.com/foxboron/go-tpm-keyfiles v0.0.0-20250903184740-5d135037bd4d github.com/fsnotify/fsnotify v1.9.0 - github.com/google/go-tpm v0.9.7 + github.com/google/go-tpm v0.9.8 github.com/stretchr/testify v1.11.1 - go.opentelemetry.io/collector/config/configopaque v1.46.0 - go.opentelemetry.io/collector/confmap/xconfmap v0.140.0 + go.opentelemetry.io/collector/config/configopaque v1.54.0 + go.opentelemetry.io/collector/confmap/xconfmap v0.148.0 + go.opentelemetry.io/collector/internal/testutil v0.148.0 ) require ( github.com/davecgh/go-spew v1.1.1 // indirect - github.com/go-viper/mapstructure/v2 v2.4.0 // indirect + github.com/go-viper/mapstructure/v2 v2.5.0 // indirect github.com/gobwas/glob v0.2.3 // indirect - github.com/google/go-tpm-tools v0.4.4 // indirect - github.com/hashicorp/go-version v1.7.0 // indirect + github.com/google/go-tpm-tools v0.4.7 // indirect + github.com/hashicorp/go-version v1.8.0 // indirect github.com/knadh/koanf/maps v0.1.2 // indirect github.com/knadh/koanf/providers/confmap v1.0.0 // indirect - github.com/knadh/koanf/v2 v2.3.0 // indirect + github.com/knadh/koanf/v2 v2.3.3 // indirect github.com/mitchellh/copystructure v1.2.0 // indirect github.com/mitchellh/reflectwalk v1.0.2 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect - go.opentelemetry.io/collector/confmap v1.46.0 // indirect - go.opentelemetry.io/collector/featuregate v1.46.0 // indirect + go.opentelemetry.io/collector/confmap v1.54.0 // indirect + go.opentelemetry.io/collector/featuregate v1.54.0 // indirect go.uber.org/multierr v1.11.0 // indirect go.uber.org/zap v1.27.1 // indirect go.yaml.in/yaml/v3 v3.0.4 // indirect - golang.org/x/crypto v0.45.0 // indirect - golang.org/x/sys v0.38.0 // indirect + golang.org/x/crypto v0.48.0 // indirect + golang.org/x/sys v0.41.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/config/configtls/go.sum b/config/configtls/go.sum index ece2db9de204..53e37775a866 100644 --- a/config/configtls/go.sum +++ b/config/configtls/go.sum @@ -6,34 +6,32 @@ github.com/foxboron/swtpm_test v0.0.0-20230726224112-46aaafdf7006 h1:50sW4r0Pcvl github.com/foxboron/swtpm_test v0.0.0-20230726224112-46aaafdf7006/go.mod h1:eIXCMsMYCaqq9m1KSSxXwQG11krpuNPGP3k0uaWrbas= github.com/fsnotify/fsnotify v1.9.0 h1:2Ml+OJNzbYCTzsxtv8vKSFD9PbJjmhYF14k/jKC7S9k= github.com/fsnotify/fsnotify v1.9.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0= -github.com/go-viper/mapstructure/v2 v2.4.0 h1:EBsztssimR/CONLSZZ04E8qAkxNYq4Qp9LvH92wZUgs= -github.com/go-viper/mapstructure/v2 v2.4.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM= +github.com/go-viper/mapstructure/v2 v2.5.0 h1:vM5IJoUAy3d7zRSVtIwQgBj7BiWtMPfmPEgAXnvj1Ro= +github.com/go-viper/mapstructure/v2 v2.5.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM= github.com/gobwas/glob v0.2.3 h1:A4xDbljILXROh+kObIiy5kIaPYD8e96x1tgBhUI5J+Y= github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8= -github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= -github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= -github.com/google/go-configfs-tsm v0.2.2 h1:YnJ9rXIOj5BYD7/0DNnzs8AOp7UcvjfTvt215EWcs98= -github.com/google/go-configfs-tsm v0.2.2/go.mod h1:EL1GTDFMb5PZQWDviGfZV9n87WeGTR/JUg13RfwkgRo= -github.com/google/go-sev-guest v0.9.3 h1:GOJ+EipURdeWFl/YYdgcCxyPeMgQUWlI056iFkBD8UU= -github.com/google/go-sev-guest v0.9.3/go.mod h1:hc1R4R6f8+NcJwITs0L90fYWTsBpd1Ix+Gur15sqHDs= -github.com/google/go-tdx-guest v0.3.1 h1:gl0KvjdsD4RrJzyLefDOvFOUH3NAJri/3qvaL5m83Iw= -github.com/google/go-tdx-guest v0.3.1/go.mod h1:/rc3d7rnPykOPuY8U9saMyEps0PZDThLk/RygXm04nE= -github.com/google/go-tpm v0.9.7 h1:u89J4tUUeDTlH8xxC3CTW7OHZjbjKoHdQ9W7gCUhtxA= -github.com/google/go-tpm v0.9.7/go.mod h1:h9jEsEECg7gtLis0upRBQU+GhYVH6jMjrFxI8u6bVUY= -github.com/google/go-tpm-tools v0.4.4 h1:oiQfAIkc6xTy9Fl5NKTeTJkBTlXdHsxAofmQyxBKY98= -github.com/google/go-tpm-tools v0.4.4/go.mod h1:T8jXkp2s+eltnCDIsXR84/MTcVU9Ja7bh3Mit0pa4AY= +github.com/google/go-configfs-tsm v0.3.3-0.20240919001351-b4b5b84fdcbc h1:SG12DWUUM5igxm+//YX5Yq4vhdoRnOG9HkCodkOn+YU= +github.com/google/go-configfs-tsm v0.3.3-0.20240919001351-b4b5b84fdcbc/go.mod h1:EL1GTDFMb5PZQWDviGfZV9n87WeGTR/JUg13RfwkgRo= +github.com/google/go-sev-guest v0.14.0 h1:dCb4F3YrHTtrDX3cYIPTifEDz7XagZmXQioxRBW4wOo= +github.com/google/go-sev-guest v0.14.0/go.mod h1:SK9vW+uyfuzYdVN0m8BShL3OQCtXZe/JPF7ZkpD3760= +github.com/google/go-tdx-guest v0.3.2-0.20241009005452-097ee70d0843 h1:+MoPobRN9HrDhGyn6HnF5NYo4uMBKaiFqAtf/D/OB4A= +github.com/google/go-tdx-guest v0.3.2-0.20241009005452-097ee70d0843/go.mod h1:g/n8sKITIT9xRivBUbizo34DTsUm2nN2uU3A662h09g= +github.com/google/go-tpm v0.9.8 h1:slArAR9Ft+1ybZu0lBwpSmpwhRXaa85hWtMinMyRAWo= +github.com/google/go-tpm v0.9.8/go.mod h1:h9jEsEECg7gtLis0upRBQU+GhYVH6jMjrFxI8u6bVUY= +github.com/google/go-tpm-tools v0.4.7 h1:J3ycC8umYxM9A4eF73EofRZu4BxY0jjQnUnkhIBbvws= +github.com/google/go-tpm-tools v0.4.7/go.mod h1:gSyXTZHe3fgbzb6WEGd90QucmsnT1SRdlye82gH8QjQ= github.com/google/logger v1.1.1 h1:+6Z2geNxc9G+4D4oDO9njjjn2d0wN5d7uOo0vOIW1NQ= github.com/google/logger v1.1.1/go.mod h1:BkeJZ+1FhQ+/d087r4dzojEg1u2ZX+ZqG1jTUrLM+zQ= -github.com/google/uuid v1.3.1 h1:KjJaJ9iWZ3jOFZIf1Lqf4laDRCasjl0BCmnEGxkdLb4= -github.com/google/uuid v1.3.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/hashicorp/go-version v1.7.0 h1:5tqGy27NaOTB8yJKUZELlFAS/LTKJkrmONwQKeRZfjY= -github.com/hashicorp/go-version v1.7.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= +github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= +github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/hashicorp/go-version v1.8.0 h1:KAkNb1HAiZd1ukkxDFGmokVZe1Xy9HG6NUp+bPle2i4= +github.com/hashicorp/go-version v1.8.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/knadh/koanf/maps v0.1.2 h1:RBfmAW5CnZT+PJ1CVc1QSJKf4Xu9kxfQgYVQSu8hpbo= github.com/knadh/koanf/maps v0.1.2/go.mod h1:npD/QZY3V6ghQDdcQzl1W4ICNVTkohC8E73eI2xW4yI= github.com/knadh/koanf/providers/confmap v1.0.0 h1:mHKLJTE7iXEys6deO5p6olAiZdG5zwp8Aebir+/EaRE= github.com/knadh/koanf/providers/confmap v1.0.0/go.mod h1:txHYHiI2hAtF0/0sCmcuol4IDcuQbKTybiB1nOcUo1A= -github.com/knadh/koanf/v2 v2.3.0 h1:Qg076dDRFHvqnKG97ZEsi9TAg2/nFTa9hCdcSa1lvlM= -github.com/knadh/koanf/v2 v2.3.0/go.mod h1:gRb40VRAbd4iJMYYD5IxZ6hfuopFcXBpc9bbQpZwo28= +github.com/knadh/koanf/v2 v2.3.3 h1:jLJC8XCRfLC7n4F+ZKKdBsbq1bfXTpuFhf4L7t94D94= +github.com/knadh/koanf/v2 v2.3.3/go.mod h1:gRb40VRAbd4iJMYYD5IxZ6hfuopFcXBpc9bbQpZwo28= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= @@ -42,10 +40,6 @@ github.com/mitchellh/copystructure v1.2.0 h1:vpKXTN4ewci03Vljg/q9QvCGUDttBOGBIa1 github.com/mitchellh/copystructure v1.2.0/go.mod h1:qLl+cE2AmVv+CoeAwDPye/v+N2HKCj9FbZEVFJRxO9s= github.com/mitchellh/reflectwalk v1.0.2 h1:G2LzWKi524PWgd3mLHV8Y5k7s6XUvT0Gef6zxSIeXaQ= github.com/mitchellh/reflectwalk v1.0.2/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= -github.com/pborman/uuid v1.2.1 h1:+ZZIw58t/ozdjRaXh/3awHfmWRbzYxJoAdNJxe/3pvw= -github.com/pborman/uuid v1.2.1/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k= -github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= -github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ= @@ -60,12 +54,12 @@ go.uber.org/zap v1.27.1 h1:08RqriUEv8+ArZRYSTXy1LeBScaMpVSTBhCeaZYfMYc= go.uber.org/zap v1.27.1/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc= go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg= -golang.org/x/crypto v0.45.0 h1:jMBrvKuj23MTlT0bQEOBcAE0mjg8mK9RXFhRH6nyF3Q= -golang.org/x/crypto v0.45.0/go.mod h1:XTGrrkGJve7CYK7J8PEww4aY7gM3qMCElcJQ8n8JdX4= -golang.org/x/sys v0.38.0 h1:3yZWxaJjBmCWXqhN1qh02AkOnCQ1poK6oF+a7xWL6Gc= -golang.org/x/sys v0.38.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= -google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8= -google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +golang.org/x/crypto v0.48.0 h1:/VRzVqiRSggnhY7gNRxPauEQ5Drw9haKdM0jqfcCFts= +golang.org/x/crypto v0.48.0/go.mod h1:r0kV5h3qnFPlQnBSrULhlsRfryS2pmewsg+XfMgkVos= +golang.org/x/sys v0.41.0 h1:Ivj+2Cp/ylzLiEU89QhWblYnOE9zerudt9Ftecq2C6k= +golang.org/x/sys v0.41.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= +google.golang.org/protobuf v1.35.1 h1:m3LfL6/Ca+fqnjnlqQXNpFPABW1UD7mjh8KO2mKFytA= +google.golang.org/protobuf v1.35.1/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= diff --git a/config/configtls/tpm_test.go b/config/configtls/tpm_test.go index c9dd8d63fece..d6ce70701107 100644 --- a/config/configtls/tpm_test.go +++ b/config/configtls/tpm_test.go @@ -28,9 +28,12 @@ import ( "github.com/google/go-tpm/tpm2/transport/simulator" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + + "go.opentelemetry.io/collector/internal/testutil" ) func TestTPM_loadCertificate(t *testing.T) { + testutil.SkipIfFIPSOnly(t, "use of CFB is not allowed in FIPS 140-only mode") tpm, err := simulator.OpenSimulator() require.NoError(t, err) defer tpm.Close() @@ -98,6 +101,7 @@ func TestTPM_loadCertificate_error(t *testing.T) { } func TestTPM_tpmCertificate_errors(t *testing.T) { + testutil.SkipIfFIPSOnly(t, "use of CFB is not allowed in FIPS 140-only mode") tpm, err := simulator.OpenSimulator() require.NoError(t, err) defer tpm.Close() diff --git a/confmap/confmaptest/configtest.go b/confmap/confmaptest/configtest.go index 7c68f889a7d4..712ef038a0f7 100644 --- a/confmap/confmaptest/configtest.go +++ b/confmap/confmaptest/configtest.go @@ -9,7 +9,7 @@ import ( "path/filepath" "regexp" - yaml "go.yaml.in/yaml/v3" + "go.yaml.in/yaml/v3" "go.opentelemetry.io/collector/confmap" ) diff --git a/confmap/documentation.md b/confmap/documentation.md new file mode 100644 index 000000000000..a42acecbbcb6 --- /dev/null +++ b/confmap/documentation.md @@ -0,0 +1,14 @@ +[comment]: <> (Code generated by mdatagen. DO NOT EDIT.) + +# confmap + +## Feature Gates + +This component has the following feature gates: + +| Feature Gate | Stage | Description | From Version | To Version | Reference | +| ------------ | ----- | ----------- | ------------ | ---------- | --------- | +| `confmap.enableMergeAppendOption` | alpha | Combines lists when resolving configs from different sources. This feature gate will not be stabilized 'as is'; the current behavior will remain the default. | v0.120.0 | N/A | [Link](https://github.com/open-telemetry/opentelemetry-collector/issues/8754) | +| `confmap.newExpandedValueSanitizer` | beta | Fixes some types of decoding errors where environment variables are parsed as non-string types but assigned to string fields. | v0.144.0 | N/A | [Link](https://github.com/open-telemetry/opentelemetry-collector/pull/14413) | + +For more information about feature gates, see the [Feature Gates](https://github.com/open-telemetry/opentelemetry-collector/blob/main/featuregate/README.md) documentation. diff --git a/confmap/go.mod b/confmap/go.mod index 30ceaeb354b7..cfdf56b33bc5 100644 --- a/confmap/go.mod +++ b/confmap/go.mod @@ -1,16 +1,16 @@ module go.opentelemetry.io/collector/confmap -go 1.24.0 +go 1.25.0 require ( - github.com/go-viper/mapstructure/v2 v2.4.0 + github.com/go-viper/mapstructure/v2 v2.5.0 github.com/gobwas/glob v0.2.3 github.com/knadh/koanf/maps v0.1.2 github.com/knadh/koanf/providers/confmap v1.0.0 - github.com/knadh/koanf/v2 v2.3.0 + github.com/knadh/koanf/v2 v2.3.3 github.com/stretchr/testify v1.11.1 - go.opentelemetry.io/collector/featuregate v1.46.0 - go.opentelemetry.io/collector/internal/testutil v0.140.0 + go.opentelemetry.io/collector/featuregate v1.54.0 + go.opentelemetry.io/collector/internal/testutil v0.148.0 go.uber.org/goleak v1.3.0 go.uber.org/multierr v1.11.0 go.uber.org/zap v1.27.1 @@ -19,7 +19,7 @@ require ( require ( github.com/davecgh/go-spew v1.1.1 // indirect - github.com/hashicorp/go-version v1.7.0 // indirect + github.com/hashicorp/go-version v1.8.0 // indirect github.com/mitchellh/copystructure v1.2.0 // indirect github.com/mitchellh/reflectwalk v1.0.2 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect diff --git a/confmap/go.sum b/confmap/go.sum index 6020e16119b7..d19c16bb075a 100644 --- a/confmap/go.sum +++ b/confmap/go.sum @@ -1,17 +1,17 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/go-viper/mapstructure/v2 v2.4.0 h1:EBsztssimR/CONLSZZ04E8qAkxNYq4Qp9LvH92wZUgs= -github.com/go-viper/mapstructure/v2 v2.4.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM= +github.com/go-viper/mapstructure/v2 v2.5.0 h1:vM5IJoUAy3d7zRSVtIwQgBj7BiWtMPfmPEgAXnvj1Ro= +github.com/go-viper/mapstructure/v2 v2.5.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM= github.com/gobwas/glob v0.2.3 h1:A4xDbljILXROh+kObIiy5kIaPYD8e96x1tgBhUI5J+Y= github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8= -github.com/hashicorp/go-version v1.7.0 h1:5tqGy27NaOTB8yJKUZELlFAS/LTKJkrmONwQKeRZfjY= -github.com/hashicorp/go-version v1.7.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= +github.com/hashicorp/go-version v1.8.0 h1:KAkNb1HAiZd1ukkxDFGmokVZe1Xy9HG6NUp+bPle2i4= +github.com/hashicorp/go-version v1.8.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/knadh/koanf/maps v0.1.2 h1:RBfmAW5CnZT+PJ1CVc1QSJKf4Xu9kxfQgYVQSu8hpbo= github.com/knadh/koanf/maps v0.1.2/go.mod h1:npD/QZY3V6ghQDdcQzl1W4ICNVTkohC8E73eI2xW4yI= github.com/knadh/koanf/providers/confmap v1.0.0 h1:mHKLJTE7iXEys6deO5p6olAiZdG5zwp8Aebir+/EaRE= github.com/knadh/koanf/providers/confmap v1.0.0/go.mod h1:txHYHiI2hAtF0/0sCmcuol4IDcuQbKTybiB1nOcUo1A= -github.com/knadh/koanf/v2 v2.3.0 h1:Qg076dDRFHvqnKG97ZEsi9TAg2/nFTa9hCdcSa1lvlM= -github.com/knadh/koanf/v2 v2.3.0/go.mod h1:gRb40VRAbd4iJMYYD5IxZ6hfuopFcXBpc9bbQpZwo28= +github.com/knadh/koanf/v2 v2.3.3 h1:jLJC8XCRfLC7n4F+ZKKdBsbq1bfXTpuFhf4L7t94D94= +github.com/knadh/koanf/v2 v2.3.3/go.mod h1:gRb40VRAbd4iJMYYD5IxZ6hfuopFcXBpc9bbQpZwo28= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= diff --git a/confmap/internal/conf.go b/confmap/internal/conf.go index 1760cdd425cb..139ef3f1b134 100644 --- a/confmap/internal/conf.go +++ b/confmap/internal/conf.go @@ -13,6 +13,7 @@ import ( "github.com/knadh/koanf/v2" encoder "go.opentelemetry.io/collector/confmap/internal/mapstructure" + "go.opentelemetry.io/collector/confmap/internal/metadata" ) const ( @@ -99,8 +100,7 @@ func (l *Conf) IsSet(key string) bool { // Merge merges the input given configuration into the existing config. // Note that the given map may be modified. func (l *Conf) Merge(in *Conf) error { - if EnableMergeAppendOption.IsEnabled() { - // only use MergeAppend when EnableMergeAppendOption featuregate is enabled. + if metadata.ConfmapEnableMergeAppendOptionFeatureGate.IsEnabled() { return l.mergeAppend(in) } l.isNil = l.isNil && in.isNil @@ -182,6 +182,10 @@ func (l *Conf) ToStringMap() map[string]any { return sanitize(l.toStringMapWithExpand()).(map[string]any) } +func ToStringMapRaw(conf *Conf) map[string]any { + return conf.toStringMapWithExpand() +} + func (l *Conf) unsanitizedGet(key string) any { return l.k.Get(key) } diff --git a/confmap/internal/confmap_test.go b/confmap/internal/confmap_test.go index 6e458b0cbd6a..fe9d968e4856 100644 --- a/confmap/internal/confmap_test.go +++ b/confmap/internal/confmap_test.go @@ -4,6 +4,7 @@ package internal import ( + "encoding" "errors" "math" "os" @@ -14,7 +15,10 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - yaml "go.yaml.in/yaml/v3" + "go.yaml.in/yaml/v3" + + "go.opentelemetry.io/collector/confmap/internal/metadata" + "go.opentelemetry.io/collector/featuregate" ) func TestToStringMapFlatten(t *testing.T) { @@ -559,6 +563,53 @@ func TestEmbeddedMarshalerError(t *testing.T) { assert.EqualError(t, cfgMap.Unmarshal(tc), "error running encode hook: marshaling error") } +// stringOpaque is similar to configopaque.String, in that +// marshaling then unmarshaling it changes its value. +type stringOpaque string + +var _ encoding.TextMarshaler = stringOpaque("") + +func (s stringOpaque) MarshalText() (text []byte, err error) { + return []byte("opaque"), nil +} + +type squashedConfigOpaque struct { + Value stringOpaque `mapstructure:"value"` + secret bool +} + +var _ Unmarshaler = (*squashedConfigOpaque)(nil) + +func (ecwrt *squashedConfigOpaque) Unmarshal(conf *Conf) error { + if err := conf.Unmarshal(ecwrt); err != nil { + return err + } + ecwrt.secret = true + return nil +} + +type testConfigOpaque struct { + // Don't embed, otherwise testConfigOpaque will implement Unmarshaler, + // and unmarshalerHookFunc will be called instead of unmarshalerEmbeddedStructsHookFunc. + Squashed squashedConfigOpaque `mapstructure:",squash"` +} + +// Regression test: the hook processing embedded marshalers previously made the assumption that +// marshaling a struct then unmarshaling the resulting map back into the struct +// is a no-op, which is not true for configopaque.String. +func TestEmbeddedMarshalerWithoutRoundtrip(t *testing.T) { + cfgMap := NewFromStringMap(map[string]any{ + "value": "hello", + }) + + tc := &testConfigOpaque{} + require.NoError(t, cfgMap.Unmarshal(tc)) + // Check that "hello" hasn't been replaced by "opaque" + assert.Equal(t, "hello", string(tc.Squashed.Value)) + // Check that the inner Unmarshal was called + assert.True(t, tc.Squashed.secret) +} + type B struct { String string `mapstructure:"string"` } @@ -965,7 +1016,10 @@ func TestRecursiveUnmarshaling(t *testing.T) { require.Equal(t, "something", r.Foo) } -func TestExpandedValue(t *testing.T) { +func testExpandedValue(t *testing.T, newSanitizer bool) { + err := featuregate.GlobalRegistry().Set(metadata.ConfmapNewExpandedValueSanitizerFeatureGate.ID(), newSanitizer) + require.NoError(t, err) + cm := NewFromStringMap(map[string]any{ "key": ExpandedValue{ Value: 0xdeadbeef, @@ -983,6 +1037,30 @@ func TestExpandedValue(t *testing.T) { require.NoError(t, cm.Unmarshal(&cfgStr)) assert.Equal(t, "original", cfgStr.Key) + type ConfigStrPtr struct { + Key *string `mapstructure:"key"` + } + + cfgStrPtr := ConfigStrPtr{} + if newSanitizer { + require.NoError(t, cm.Unmarshal(&cfgStrPtr)) + if assert.NotNil(t, cfgStrPtr.Key) { + assert.Equal(t, "original", *cfgStrPtr.Key) + } + } else { + require.Error(t, cm.Unmarshal(&cfgStrPtr)) + } + + cfgMapStrPtr := map[string]*string{} + if newSanitizer { + require.NoError(t, cm.Unmarshal(&cfgMapStrPtr)) + if assert.NotNil(t, cfgMapStrPtr["key"]) { + assert.Equal(t, "original", *cfgMapStrPtr["key"]) + } + } else { + require.Error(t, cm.Unmarshal(&cfgMapStrPtr)) + } + type ConfigInt struct { Key int `mapstructure:"key"` } @@ -997,6 +1075,39 @@ func TestExpandedValue(t *testing.T) { assert.Error(t, cm.Unmarshal(&cfgBool)) } +func TestExpandedValue(t *testing.T) { + before := metadata.ConfmapNewExpandedValueSanitizerFeatureGate.IsEnabled() + t.Run("old sanitizer", func(t *testing.T) { + testExpandedValue(t, false) + }) + t.Run("new sanitizer", func(t *testing.T) { + testExpandedValue(t, true) + }) + err := featuregate.GlobalRegistry().Set(metadata.ConfmapNewExpandedValueSanitizerFeatureGate.ID(), before) + require.NoError(t, err) +} + +func TestExpandedValueNil(t *testing.T) { + cm := NewFromStringMap(map[string]any{ + "key": ExpandedValue{ + Value: nil, + Original: "NULL", + }, + }) + + type ConfigStrPtr struct { + Key *string `mapstructure:"key"` + } + + cfgStrPtr := ConfigStrPtr{} + require.NoError(t, cm.Unmarshal(&cfgStrPtr)) + assert.Nil(t, cfgStrPtr.Key) + + cfgMapStrPtr := map[string]*string{} + require.NoError(t, cm.Unmarshal(&cfgMapStrPtr)) + assert.Nil(t, cfgMapStrPtr["key"]) +} + func TestSubExpandedValue(t *testing.T) { cm := NewFromStringMap(map[string]any{ "key": map[string]any{ @@ -1326,3 +1437,35 @@ func TestConfmapNilMerge(t *testing.T) { }) } } + +type simpleUnmarshaler struct { + unmarshaled bool + Value string `mapstructure:"value"` +} + +var _ Unmarshaler = (*simpleUnmarshaler)(nil) + +func (s *simpleUnmarshaler) Unmarshal(c *Conf) error { + s.unmarshaled = true + return c.Unmarshal(s) // Does not call simpleUnmarshaler.Unmarshal +} + +type wrapperUnmarshaler[T any] struct { + inner T +} + +var _ Unmarshaler = (*wrapperUnmarshaler[simpleUnmarshaler])(nil) + +func (w *wrapperUnmarshaler[T]) Unmarshal(c *Conf) error { + return c.Unmarshal(&w.inner, WithForceUnmarshaler()) // Calls T.Unmarshal +} + +func TestUnmarshalWithForceUnmarshaler(t *testing.T) { + conf := NewFromStringMap(map[string]any{ + "value": "test_value", + }) + var out wrapperUnmarshaler[simpleUnmarshaler] + require.NoError(t, conf.Unmarshal(&out)) + assert.Equal(t, "test_value", out.inner.Value) + assert.True(t, out.inner.unmarshaled) +} diff --git a/confmap/internal/decoder.go b/confmap/internal/decoder.go index d3f8af79718b..e06eeaec7247 100644 --- a/confmap/internal/decoder.go +++ b/confmap/internal/decoder.go @@ -7,13 +7,13 @@ import ( "encoding" "errors" "fmt" - "maps" "reflect" "slices" "strings" "github.com/go-viper/mapstructure/v2" + "go.opentelemetry.io/collector/confmap/internal/metadata" "go.opentelemetry.io/collector/confmap/internal/third_party/composehook" ) @@ -32,6 +32,18 @@ func WithIgnoreUnused() UnmarshalOption { }) } +// WithForceUnmarshaler sets an option to run a top-level Unmarshal method, +// even if the Conf being unmarshaled is already a parameter from an Unmarshal method. +// To avoid infinite recursion, this should only be used when unmarshaling into +// a different type from the current Unmarshaler. +// For instance, this should be used in wrapper types such as configoptional.Optional +// to ensure the inner type's Unmarshal method is called. +func WithForceUnmarshaler() UnmarshalOption { + return UnmarshalOptionFunc(func(uo *UnmarshalOptions) { + uo.ForceUnmarshaler = true + }) +} + // Decode decodes the contents of the Conf into the result argument, using a // mapstructure decoder with the following notable behaviors. Ensures that maps whose // values are nil pointer structs resolved to the zero value of the target struct (see @@ -54,10 +66,10 @@ func Decode(input, result any, settings UnmarshalOptions, skipTopLevelUnmarshale mapKeyStringToMapKeyTextUnmarshalerHookFunc(), mapstructure.StringToTimeDurationHookFunc(), mapstructure.TextUnmarshallerHookFunc(), - unmarshalerHookFunc(result, skipTopLevelUnmarshaler), + unmarshalerHookFunc(result, skipTopLevelUnmarshaler && !settings.ForceUnmarshaler), // after the main unmarshaler hook is called, // we unmarshal the embedded structs if present to merge with the result: - unmarshalerEmbeddedStructsHookFunc(), + unmarshalerEmbeddedStructsHookFunc(settings), zeroSliceAndMapHookFunc(), ), } @@ -76,7 +88,10 @@ func Decode(input, result any, settings UnmarshalOptions, skipTopLevelUnmarshale // When a value has been loaded from an external source via a provider, we keep both the // parsed value and the original string value. This allows us to expand the value to its -// original string representation when decoding into a string field, and use the original otherwise. +// original string representation when decoding into a string field, and use the parsed value otherwise. +// +// Fields containing a pointer to a string will also be set to the original string representation, +// except when the parsed value is nil (i.e. parsed from YAML `null`, `NULL`, `~`, the empty string, etc.) func useExpandValue() mapstructure.DecodeHookFuncType { return func( _ reflect.Type, @@ -84,7 +99,26 @@ func useExpandValue() mapstructure.DecodeHookFuncType { data any, ) (any, error) { if exp, ok := data.(ExpandedValue); ok { - v := castTo(exp, to.Kind() == reflect.String) + var useOriginal bool + if metadata.ConfmapNewExpandedValueSanitizerFeatureGate.IsEnabled() { + // Check if the target field is string, *string, **string, etc. + baseType := to + pointed := false + for baseType.Kind() == reflect.Pointer { + baseType = baseType.Elem() + pointed = true + } + useOriginal = baseType.Kind() == reflect.String + + // If the parsed value is nil and the target is a pointer, use the parsed value. + if pointed && exp.Value == nil { + useOriginal = false + } + } else { + useOriginal = to.Kind() == reflect.String + } + + v := castTo(exp, useOriginal) // See https://github.com/open-telemetry/opentelemetry-collector/issues/10949 // If the `to.Kind` is not a string, then expandValue's original value is useless and // the casted-to value will be nil. In that scenario, we need to use the default value of `to`'s kind. @@ -94,14 +128,17 @@ func useExpandValue() mapstructure.DecodeHookFuncType { return v, nil } - switch to.Kind() { - case reflect.Array, reflect.Slice, reflect.Map: - if isStringyStructure(to) { - // If the target field is a stringy structure, sanitize to use the original string value everywhere. - return sanitizeToStr(data), nil + if !metadata.ConfmapNewExpandedValueSanitizerFeatureGate.IsEnabled() { + switch to.Kind() { + case reflect.Array, reflect.Slice, reflect.Map: + if isStringyStructure(to) { + // If the target field is a stringy structure, sanitize to use the original string value everywhere. + return sanitizeToStr(data), nil + } + + // Otherwise, sanitize to use the parsed value everywhere. + return sanitize(data), nil } - // Otherwise, sanitize to use the parsed value everywhere. - return sanitize(data), nil } return data, nil } @@ -189,7 +226,7 @@ func mapKeyStringToMapKeyTextUnmarshalerHookFunc() mapstructure.DecodeHookFuncTy // unmarshalerEmbeddedStructsHookFunc provides a mechanism for embedded structs to define their own unmarshal logic, // by implementing the Unmarshaler interface. -func unmarshalerEmbeddedStructsHookFunc() mapstructure.DecodeHookFuncValue { +func unmarshalerEmbeddedStructsHookFunc(settings UnmarshalOptions) mapstructure.DecodeHookFuncValue { return safeWrapDecodeHookFunc(func(from, to reflect.Value) (any, error) { if to.Type().Kind() != reflect.Struct { return from.Interface(), nil @@ -198,32 +235,72 @@ func unmarshalerEmbeddedStructsHookFunc() mapstructure.DecodeHookFuncValue { if !ok { return from.Interface(), nil } + + // First call Unmarshaler on squashed embedded fields, if necessary. + var squashedUnmarshalers []int for i := 0; i < to.Type().NumField(); i++ { - // embedded structs passed in via `squash` cannot be pointers. We just check if they are structs: f := to.Type().Field(i) - if f.IsExported() && slices.Contains(strings.Split(f.Tag.Get(MapstructureTag), ","), "squash") { - if unmarshaler, ok := to.Field(i).Addr().Interface().(Unmarshaler); ok { - c := NewFromStringMap(fromAsMap) - c.skipTopLevelUnmarshaler = true - if err := unmarshaler.Unmarshal(c); err != nil { - return nil, err - } - // the struct we receive from this unmarshaling only contains fields related to the embedded struct. - // we merge this partially unmarshaled struct with the rest of the result. - // note we already unmarshaled the main struct earlier, and therefore merge with it. - conf := New() - if err := conf.Marshal(unmarshaler); err != nil { - return nil, err - } - resultMap := conf.ToStringMap() - if fromAsMap == nil && len(resultMap) > 0 { - fromAsMap = make(map[string]any, len(resultMap)) - } - maps.Copy(fromAsMap, resultMap) - } + if !f.IsExported() { + continue + } + tagParts := strings.Split(f.Tag.Get(MapstructureTag), ",") + if !slices.Contains(tagParts[1:], "squash") { + continue + } + unmarshaler, ok := to.Field(i).Addr().Interface().(Unmarshaler) + if !ok { + continue } + c := NewFromStringMap(fromAsMap) + c.skipTopLevelUnmarshaler = true + if err := unmarshaler.Unmarshal(c); err != nil { + return nil, err + } + squashedUnmarshalers = append(squashedUnmarshalers, i) + } + + // No squashed unmarshalers, we can let mapstructure do its job. + if len(squashedUnmarshalers) == 0 { + return fromAsMap, nil + } + + // We need to unmarshal into all other fields without overwriting the output of the Unmarshal calls. + // To do that, create a custom "partial" struct containing only the non-squashed fields. + var fields []reflect.StructField + var fieldValues []reflect.Value + for i := 0; i < to.Type().NumField(); i++ { + f := to.Type().Field(i) + if !f.IsExported() { + continue + } + if slices.Contains(squashedUnmarshalers, i) { + continue + } + fields = append(fields, f) + fieldValues = append(fieldValues, to.Field(i)) + } + restType := reflect.StructOf(fields) + restValue := reflect.New(restType) + + // Copy initial values into partial struct. + for i, fieldValue := range fieldValues { + restValue.Elem().Field(i).Set(fieldValue) } - return fromAsMap, nil + + // Decode into the partial struct. + // This performs a recursive call into this hook, which will be handled by the "no squashed unmarshalers" case above. + // We need to set `IgnoreUnused` to avoid errors from the map containing fields only present in the full struct. + settings.IgnoreUnused = true + if err := Decode(fromAsMap, restValue.Interface(), settings, true); err != nil { + return nil, err + } + + // Copy decoding results back to the original struct. + for i, fieldValue := range fieldValues { + fieldValue.Set(restValue.Elem().Field(i)) + } + + return to, nil }) } diff --git a/confmap/internal/e2e/Makefile b/confmap/internal/e2e/Makefile index bdd863a203be..011fca9e195f 100644 --- a/confmap/internal/e2e/Makefile +++ b/confmap/internal/e2e/Makefile @@ -1 +1,4 @@ include ../../../Makefile.Common + +# Override COVER_PKGS to include the parent package that this e2e module tests +COVER_PKGS := go.opentelemetry.io/collector/confmap/internal,$(COVER_PKGS) diff --git a/confmap/internal/e2e/expand_test.go b/confmap/internal/e2e/expand_test.go index 3e1cbf86feac..4424271304c6 100644 --- a/confmap/internal/e2e/expand_test.go +++ b/confmap/internal/e2e/expand_test.go @@ -12,8 +12,10 @@ import ( "github.com/stretchr/testify/require" "go.opentelemetry.io/collector/confmap" + "go.opentelemetry.io/collector/confmap/internal" "go.opentelemetry.io/collector/confmap/provider/envprovider" "go.opentelemetry.io/collector/confmap/provider/fileprovider" + "go.opentelemetry.io/collector/confmap/xconfmap" ) func Test_EscapedEnvVars_NoDefaultScheme(t *testing.T) { @@ -47,6 +49,8 @@ func Test_EscapedEnvVars_NoDefaultScheme(t *testing.T) { "key18": "here is 1 $", "key19": "here are 2 $$", "key20": "some expanded value came from nested expansion", + "key21": "default_value", + "key22": "${env:UNDEFINED_KEY:-${env:UNDEFINED_KEY}}", }, } @@ -95,6 +99,8 @@ func Test_EscapedEnvVars_DefaultScheme(t *testing.T) { "key18": "here is 1 $", "key19": "here are 2 $$", "key20": "some expanded value came from nested expansion", + "key21": "default_value", + "key22": "${env:UNDEFINED_KEY:-${env:UNDEFINED_KEY}}", }, } @@ -111,3 +117,17 @@ func Test_EscapedEnvVars_DefaultScheme(t *testing.T) { m := cfgMap.ToStringMap() assert.Equal(t, expectedMap, m) } + +func Test_RawConfMap(t *testing.T) { + data := map[string]any{ + "value": internal.ExpandedValue{ + Value: 8080, + Original: "8080", + }, + } + conf := confmap.NewFromStringMap(data) + + rawData := xconfmap.ToStringMapRaw(conf) + _, isPresentAndExpandedValue := rawData["value"].(internal.ExpandedValue) + require.True(t, isPresentAndExpandedValue) +} diff --git a/confmap/internal/e2e/go.mod b/confmap/internal/e2e/go.mod index cb0ad6cdef1d..58809965153d 100644 --- a/confmap/internal/e2e/go.mod +++ b/confmap/internal/e2e/go.mod @@ -1,28 +1,28 @@ module go.opentelemetry.io/collector/confmap/internal/e2e -go 1.24.0 +go 1.25.0 require ( github.com/stretchr/testify v1.11.1 - go.opentelemetry.io/collector/config/configopaque v1.46.0 - go.opentelemetry.io/collector/confmap v1.46.0 - go.opentelemetry.io/collector/confmap/provider/envprovider v1.46.0 - go.opentelemetry.io/collector/confmap/provider/fileprovider v1.46.0 + go.opentelemetry.io/collector/config/configopaque v1.54.0 + go.opentelemetry.io/collector/confmap v1.54.0 + go.opentelemetry.io/collector/confmap/provider/envprovider v1.54.0 + go.opentelemetry.io/collector/confmap/provider/fileprovider v1.54.0 + go.opentelemetry.io/collector/confmap/xconfmap v0.148.0 + go.opentelemetry.io/collector/featuregate v1.54.0 ) require ( github.com/davecgh/go-spew v1.1.1 // indirect - github.com/go-viper/mapstructure/v2 v2.4.0 // indirect + github.com/go-viper/mapstructure/v2 v2.5.0 // indirect github.com/gobwas/glob v0.2.3 // indirect - github.com/hashicorp/go-version v1.7.0 // indirect + github.com/hashicorp/go-version v1.8.0 // indirect github.com/knadh/koanf/maps v0.1.2 // indirect github.com/knadh/koanf/providers/confmap v1.0.0 // indirect - github.com/knadh/koanf/v2 v2.3.0 // indirect + github.com/knadh/koanf/v2 v2.3.3 // indirect github.com/mitchellh/copystructure v1.2.0 // indirect github.com/mitchellh/reflectwalk v1.0.2 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect - go.opentelemetry.io/collector/confmap/xconfmap v0.140.0 // indirect - go.opentelemetry.io/collector/featuregate v1.46.0 // indirect go.uber.org/multierr v1.11.0 // indirect go.uber.org/zap v1.27.1 // indirect go.yaml.in/yaml/v3 v3.0.4 // indirect diff --git a/confmap/internal/e2e/go.sum b/confmap/internal/e2e/go.sum index 6020e16119b7..d19c16bb075a 100644 --- a/confmap/internal/e2e/go.sum +++ b/confmap/internal/e2e/go.sum @@ -1,17 +1,17 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/go-viper/mapstructure/v2 v2.4.0 h1:EBsztssimR/CONLSZZ04E8qAkxNYq4Qp9LvH92wZUgs= -github.com/go-viper/mapstructure/v2 v2.4.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM= +github.com/go-viper/mapstructure/v2 v2.5.0 h1:vM5IJoUAy3d7zRSVtIwQgBj7BiWtMPfmPEgAXnvj1Ro= +github.com/go-viper/mapstructure/v2 v2.5.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM= github.com/gobwas/glob v0.2.3 h1:A4xDbljILXROh+kObIiy5kIaPYD8e96x1tgBhUI5J+Y= github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8= -github.com/hashicorp/go-version v1.7.0 h1:5tqGy27NaOTB8yJKUZELlFAS/LTKJkrmONwQKeRZfjY= -github.com/hashicorp/go-version v1.7.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= +github.com/hashicorp/go-version v1.8.0 h1:KAkNb1HAiZd1ukkxDFGmokVZe1Xy9HG6NUp+bPle2i4= +github.com/hashicorp/go-version v1.8.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/knadh/koanf/maps v0.1.2 h1:RBfmAW5CnZT+PJ1CVc1QSJKf4Xu9kxfQgYVQSu8hpbo= github.com/knadh/koanf/maps v0.1.2/go.mod h1:npD/QZY3V6ghQDdcQzl1W4ICNVTkohC8E73eI2xW4yI= github.com/knadh/koanf/providers/confmap v1.0.0 h1:mHKLJTE7iXEys6deO5p6olAiZdG5zwp8Aebir+/EaRE= github.com/knadh/koanf/providers/confmap v1.0.0/go.mod h1:txHYHiI2hAtF0/0sCmcuol4IDcuQbKTybiB1nOcUo1A= -github.com/knadh/koanf/v2 v2.3.0 h1:Qg076dDRFHvqnKG97ZEsi9TAg2/nFTa9hCdcSa1lvlM= -github.com/knadh/koanf/v2 v2.3.0/go.mod h1:gRb40VRAbd4iJMYYD5IxZ6hfuopFcXBpc9bbQpZwo28= +github.com/knadh/koanf/v2 v2.3.3 h1:jLJC8XCRfLC7n4F+ZKKdBsbq1bfXTpuFhf4L7t94D94= +github.com/knadh/koanf/v2 v2.3.3/go.mod h1:gRb40VRAbd4iJMYYD5IxZ6hfuopFcXBpc9bbQpZwo28= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= diff --git a/confmap/internal/e2e/maplist_expanded_test.go b/confmap/internal/e2e/maplist_expanded_test.go new file mode 100644 index 000000000000..40f6ef1d60dd --- /dev/null +++ b/confmap/internal/e2e/maplist_expanded_test.go @@ -0,0 +1,138 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +package e2etest + +import ( + "testing" + + "github.com/stretchr/testify/require" + + "go.opentelemetry.io/collector/config/configopaque" + "go.opentelemetry.io/collector/confmap" + "go.opentelemetry.io/collector/confmap/internal" + "go.opentelemetry.io/collector/confmap/internal/metadata" + "go.opentelemetry.io/collector/featuregate" +) + +type testHeadersConfig struct { + Headers configopaque.MapList `mapstructure:"headers"` +} + +// TestMapListWithExpandedValue tests that MapList can handle ExpandedValue +// from environment variable expansion +func TestMapListWithExpandedValue(t *testing.T) { + // Simulate what happens when ${env:TOKEN} is expanded + // The confmap will contain an ExpandedValue instead of a plain string + data := map[string]any{ + "headers": []any{ + map[string]any{ + "name": "Authorization", + "value": internal.ExpandedValue{ + Value: "Bearer secret-token", + Original: "Bearer secret-token", + }, + }, + }, + } + + conf := confmap.NewFromStringMap(data) + var tc testHeadersConfig + err := conf.Unmarshal(&tc) + require.NoError(t, err) + + val, ok := tc.Headers.Get("Authorization") + require.True(t, ok) + require.Equal(t, configopaque.String("Bearer secret-token"), val) +} + +// TestMapListWithExpandedValueIntValue tests an ExpandedValue with an integer Value +func TestMapListWithExpandedValueIntValue(t *testing.T) { + // Simulate what happens when expanding a value that parses as an int + data := map[string]any{ + "headers": []any{ + map[string]any{ + "name": "X-Port", + "value": internal.ExpandedValue{ + Value: 8080, // Value is parsed as int + Original: "8080", // Original is string + }, + }, + }, + } + + originalState := metadata.ConfmapNewExpandedValueSanitizerFeatureGate.IsEnabled() + defer func() { + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.ConfmapNewExpandedValueSanitizerFeatureGate.ID(), originalState)) + }() + + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.ConfmapNewExpandedValueSanitizerFeatureGate.ID(), true)) + + conf := confmap.NewFromStringMap(data) + var tc testHeadersConfig + err := conf.Unmarshal(&tc) + require.NoError(t, err) + + val, ok := tc.Headers.Get("X-Port") + require.True(t, ok) + require.Equal(t, configopaque.String("8080"), val) + + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.ConfmapNewExpandedValueSanitizerFeatureGate.ID(), false)) + + // This will fail because when reverting to old behavior, ExpandedValues get decoded at collection time and doesn't + // take struct collections into account. + err = conf.Unmarshal(&tc) + require.Error(t, err) +} + +// TestDirectConfigopaqueStringWithExpandedValueIntValue tests that direct unmarshaling works +func TestDirectConfigopaqueStringWithExpandedValueIntValue(t *testing.T) { + type testConfig struct { + Value configopaque.String `mapstructure:"value"` + } + + // Direct configopaque.String field (not in a map/slice structure) + data := map[string]any{ + "value": internal.ExpandedValue{ + Value: 8080, + Original: "8080", + }, + } + + conf := confmap.NewFromStringMap(data) + var tc testConfig + err := conf.Unmarshal(&tc) + // This should work because useExpandValue detects the target is a string + require.NoError(t, err) + require.Equal(t, configopaque.String("8080"), tc.Value) +} + +// TestStringyStructureWithExpandedValue tests the isStringyStructure path in useExpandValue +func TestStringyStructureWithExpandedValue(t *testing.T) { + type testConfig struct { + Tags []string `mapstructure:"tags"` + } + + data := map[string]any{ + "tags": []any{ + internal.ExpandedValue{ + Value: 8080, + Original: "8080", + }, + }, + } + + originalState := metadata.ConfmapNewExpandedValueSanitizerFeatureGate.IsEnabled() + defer func() { + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.ConfmapNewExpandedValueSanitizerFeatureGate.ID(), originalState)) + }() + + // With feature gate disabled, useExpandValue should detect []string as stringy + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.ConfmapNewExpandedValueSanitizerFeatureGate.ID(), false)) + + conf := confmap.NewFromStringMap(data) + var tc testConfig + err := conf.Unmarshal(&tc) + require.NoError(t, err) + require.Equal(t, []string{"8080"}, tc.Tags) +} diff --git a/confmap/internal/e2e/testdata/expand-escaped-env.yaml b/confmap/internal/e2e/testdata/expand-escaped-env.yaml index c355d447e82b..5847451cbf15 100644 --- a/confmap/internal/e2e/testdata/expand-escaped-env.yaml +++ b/confmap/internal/e2e/testdata/expand-escaped-env.yaml @@ -39,3 +39,7 @@ test_map: key19: "${env:ENV_NESTED_DOLLARSIGN_ESCAPED}" # nested env var syntax is expanded key20: "${env:ENV_EXPAND_NESTED}" + # default value + key21: "${env:UNDEFINED_KEY:-default_value}" + # escaped default value + key22: "${env:UNDEFINED_KEY:-$${env:UNDEFINED_KEY}}" diff --git a/confmap/internal/e2e/testdata/indirect-slice-env-var-main.yaml b/confmap/internal/e2e/testdata/indirect-slice-env-var-main.yaml index 8ba70ed338dc..be451ca154ce 100644 --- a/confmap/internal/e2e/testdata/indirect-slice-env-var-main.yaml +++ b/confmap/internal/e2e/testdata/indirect-slice-env-var-main.yaml @@ -6,7 +6,7 @@ receivers: exporters: nop: - otlp: + otlp_grpc: endpoint: localhost:4317 service: diff --git a/confmap/internal/e2e/types_test.go b/confmap/internal/e2e/types_test.go index dd706463ed02..311a05bd101d 100644 --- a/confmap/internal/e2e/types_test.go +++ b/confmap/internal/e2e/types_test.go @@ -568,7 +568,7 @@ func TestIndirectSliceEnvVar(t *testing.T) { Exporters struct { OTLP struct { Endpoint string `mapstructure:"endpoint"` - } `mapstructure:"otlp"` + } `mapstructure:"otlp_grpc"` Nop struct{} `mapstructure:"nop"` } `mapstructure:"exporters"` Receivers struct { diff --git a/confmap/internal/featuregates.go b/confmap/internal/featuregates.go deleted file mode 100644 index 47f9348dc424..000000000000 --- a/confmap/internal/featuregates.go +++ /dev/null @@ -1,14 +0,0 @@ -// Copyright The OpenTelemetry Authors -// SPDX-License-Identifier: Apache-2.0 - -package internal // import "go.opentelemetry.io/collector/confmap/internal" - -import "go.opentelemetry.io/collector/featuregate" - -var EnableMergeAppendOption = featuregate.GlobalRegistry().MustRegister( - "confmap.enableMergeAppendOption", - featuregate.StageAlpha, - featuregate.WithRegisterFromVersion("v0.120.0"), - featuregate.WithRegisterDescription("Combines lists when resolving configs from different sources. This feature gate will not be stabilized 'as is'; the current behavior will remain the default."), - featuregate.WithRegisterReferenceURL("https://github.com/open-telemetry/opentelemetry-collector/issues/8754"), -) diff --git a/confmap/internal/mapstructure/encoder.go b/confmap/internal/mapstructure/encoder.go index d8208747d375..0a10560ffa65 100644 --- a/confmap/internal/mapstructure/encoder.go +++ b/confmap/internal/mapstructure/encoder.go @@ -12,7 +12,7 @@ import ( "strings" "github.com/go-viper/mapstructure/v2" - yaml "go.yaml.in/yaml/v3" + "go.yaml.in/yaml/v3" ) const ( diff --git a/confmap/internal/metadata/generated_feature_gates.go b/confmap/internal/metadata/generated_feature_gates.go new file mode 100644 index 000000000000..d277f5542645 --- /dev/null +++ b/confmap/internal/metadata/generated_feature_gates.go @@ -0,0 +1,23 @@ +// Code generated by mdatagen. DO NOT EDIT. + +package metadata + +import ( + "go.opentelemetry.io/collector/featuregate" +) + +var ConfmapEnableMergeAppendOptionFeatureGate = featuregate.GlobalRegistry().MustRegister( + "confmap.enableMergeAppendOption", + featuregate.StageAlpha, + featuregate.WithRegisterDescription("Combines lists when resolving configs from different sources. This feature gate will not be stabilized 'as is'; the current behavior will remain the default."), + featuregate.WithRegisterReferenceURL("https://github.com/open-telemetry/opentelemetry-collector/issues/8754"), + featuregate.WithRegisterFromVersion("v0.120.0"), +) + +var ConfmapNewExpandedValueSanitizerFeatureGate = featuregate.GlobalRegistry().MustRegister( + "confmap.newExpandedValueSanitizer", + featuregate.StageBeta, + featuregate.WithRegisterDescription("Fixes some types of decoding errors where environment variables are parsed as non-string types but assigned to string fields."), + featuregate.WithRegisterReferenceURL("https://github.com/open-telemetry/opentelemetry-collector/pull/14413"), + featuregate.WithRegisterFromVersion("v0.144.0"), +) diff --git a/confmap/internal/unmarshaloption.go b/confmap/internal/unmarshaloption.go index e82ce6fd0cc3..77e38417ea82 100644 --- a/confmap/internal/unmarshaloption.go +++ b/confmap/internal/unmarshaloption.go @@ -10,7 +10,8 @@ type UnmarshalOption interface { // UnmarshalOptions is used by (*Conf).Unmarshal to toggle unmarshaling settings. // It is in the `internal` package so experimental options can be added in xconfmap. type UnmarshalOptions struct { - IgnoreUnused bool + IgnoreUnused bool + ForceUnmarshaler bool } type UnmarshalOptionFunc func(*UnmarshalOptions) diff --git a/confmap/metadata.yaml b/confmap/metadata.yaml index d6194801c04f..99b0141ee76f 100644 --- a/confmap/metadata.yaml +++ b/confmap/metadata.yaml @@ -10,3 +10,15 @@ status: class: pkg stability: stable: [logs, metrics, traces] + +feature_gates: + - id: confmap.enableMergeAppendOption + description: "Combines lists when resolving configs from different sources. This feature gate will not be stabilized 'as is'; the current behavior will remain the default." + stage: alpha + from_version: 'v0.120.0' + reference_url: 'https://github.com/open-telemetry/opentelemetry-collector/issues/8754' + - id: confmap.newExpandedValueSanitizer + description: 'Fixes some types of decoding errors where environment variables are parsed as non-string types but assigned to string fields.' + stage: beta + from_version: 'v0.144.0' + reference_url: 'https://github.com/open-telemetry/opentelemetry-collector/pull/14413' diff --git a/confmap/provider.go b/confmap/provider.go index ab3e9a18a5ba..cf22f53a3163 100644 --- a/confmap/provider.go +++ b/confmap/provider.go @@ -9,7 +9,7 @@ import ( "time" "go.uber.org/zap" - yaml "go.yaml.in/yaml/v3" + "go.yaml.in/yaml/v3" ) // ProviderSettings are the settings to initialize a Provider. diff --git a/confmap/provider/envprovider/go.mod b/confmap/provider/envprovider/go.mod index df99009da52b..06646e032162 100644 --- a/confmap/provider/envprovider/go.mod +++ b/confmap/provider/envprovider/go.mod @@ -1,26 +1,26 @@ module go.opentelemetry.io/collector/confmap/provider/envprovider -go 1.24.0 +go 1.25.0 require ( github.com/stretchr/testify v1.11.1 - go.opentelemetry.io/collector/confmap v1.46.0 + go.opentelemetry.io/collector/confmap v1.54.0 go.uber.org/goleak v1.3.0 go.uber.org/zap v1.27.1 ) require ( github.com/davecgh/go-spew v1.1.1 // indirect - github.com/go-viper/mapstructure/v2 v2.4.0 // indirect + github.com/go-viper/mapstructure/v2 v2.5.0 // indirect github.com/gobwas/glob v0.2.3 // indirect - github.com/hashicorp/go-version v1.7.0 // indirect + github.com/hashicorp/go-version v1.8.0 // indirect github.com/knadh/koanf/maps v0.1.2 // indirect github.com/knadh/koanf/providers/confmap v1.0.0 // indirect - github.com/knadh/koanf/v2 v2.3.0 // indirect + github.com/knadh/koanf/v2 v2.3.3 // indirect github.com/mitchellh/copystructure v1.2.0 // indirect github.com/mitchellh/reflectwalk v1.0.2 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect - go.opentelemetry.io/collector/featuregate v1.46.0 // indirect + go.opentelemetry.io/collector/featuregate v1.54.0 // indirect go.uber.org/multierr v1.11.0 // indirect go.yaml.in/yaml/v3 v3.0.4 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect diff --git a/confmap/provider/envprovider/go.sum b/confmap/provider/envprovider/go.sum index 6020e16119b7..d19c16bb075a 100644 --- a/confmap/provider/envprovider/go.sum +++ b/confmap/provider/envprovider/go.sum @@ -1,17 +1,17 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/go-viper/mapstructure/v2 v2.4.0 h1:EBsztssimR/CONLSZZ04E8qAkxNYq4Qp9LvH92wZUgs= -github.com/go-viper/mapstructure/v2 v2.4.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM= +github.com/go-viper/mapstructure/v2 v2.5.0 h1:vM5IJoUAy3d7zRSVtIwQgBj7BiWtMPfmPEgAXnvj1Ro= +github.com/go-viper/mapstructure/v2 v2.5.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM= github.com/gobwas/glob v0.2.3 h1:A4xDbljILXROh+kObIiy5kIaPYD8e96x1tgBhUI5J+Y= github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8= -github.com/hashicorp/go-version v1.7.0 h1:5tqGy27NaOTB8yJKUZELlFAS/LTKJkrmONwQKeRZfjY= -github.com/hashicorp/go-version v1.7.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= +github.com/hashicorp/go-version v1.8.0 h1:KAkNb1HAiZd1ukkxDFGmokVZe1Xy9HG6NUp+bPle2i4= +github.com/hashicorp/go-version v1.8.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/knadh/koanf/maps v0.1.2 h1:RBfmAW5CnZT+PJ1CVc1QSJKf4Xu9kxfQgYVQSu8hpbo= github.com/knadh/koanf/maps v0.1.2/go.mod h1:npD/QZY3V6ghQDdcQzl1W4ICNVTkohC8E73eI2xW4yI= github.com/knadh/koanf/providers/confmap v1.0.0 h1:mHKLJTE7iXEys6deO5p6olAiZdG5zwp8Aebir+/EaRE= github.com/knadh/koanf/providers/confmap v1.0.0/go.mod h1:txHYHiI2hAtF0/0sCmcuol4IDcuQbKTybiB1nOcUo1A= -github.com/knadh/koanf/v2 v2.3.0 h1:Qg076dDRFHvqnKG97ZEsi9TAg2/nFTa9hCdcSa1lvlM= -github.com/knadh/koanf/v2 v2.3.0/go.mod h1:gRb40VRAbd4iJMYYD5IxZ6hfuopFcXBpc9bbQpZwo28= +github.com/knadh/koanf/v2 v2.3.3 h1:jLJC8XCRfLC7n4F+ZKKdBsbq1bfXTpuFhf4L7t94D94= +github.com/knadh/koanf/v2 v2.3.3/go.mod h1:gRb40VRAbd4iJMYYD5IxZ6hfuopFcXBpc9bbQpZwo28= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= diff --git a/confmap/provider/envprovider/provider_test.go b/confmap/provider/envprovider/provider_test.go index cc5edcc45850..50559f91f009 100644 --- a/confmap/provider/envprovider/provider_test.go +++ b/confmap/provider/envprovider/provider_test.go @@ -24,7 +24,7 @@ const validYAML = ` processors: testprocessor: exporters: - otlp: + otlp_grpc: endpoint: "localhost:4317" ` @@ -68,8 +68,8 @@ func TestEnv(t *testing.T) { retMap, err := ret.AsConf() require.NoError(t, err) expectedMap := confmap.NewFromStringMap(map[string]any{ - "processors::testprocessor": nil, - "exporters::otlp::endpoint": "localhost:4317", + "processors::testprocessor": nil, + "exporters::otlp_grpc::endpoint": "localhost:4317", }) assert.Equal(t, expectedMap.ToStringMap(), retMap.ToStringMap()) @@ -88,8 +88,8 @@ func TestEnvWithLogger(t *testing.T) { retMap, err := ret.AsConf() require.NoError(t, err) expectedMap := confmap.NewFromStringMap(map[string]any{ - "processors::testprocessor": nil, - "exporters::otlp::endpoint": "localhost:4317", + "processors::testprocessor": nil, + "exporters::otlp_grpc::endpoint": "localhost:4317", }) assert.Equal(t, expectedMap.ToStringMap(), retMap.ToStringMap()) diff --git a/confmap/provider/fileprovider/go.mod b/confmap/provider/fileprovider/go.mod index 1a37f9e6ffe2..642810c6dd54 100644 --- a/confmap/provider/fileprovider/go.mod +++ b/confmap/provider/fileprovider/go.mod @@ -1,25 +1,25 @@ module go.opentelemetry.io/collector/confmap/provider/fileprovider -go 1.24.0 +go 1.25.0 require ( github.com/stretchr/testify v1.11.1 - go.opentelemetry.io/collector/confmap v1.46.0 + go.opentelemetry.io/collector/confmap v1.54.0 go.uber.org/goleak v1.3.0 ) require ( github.com/davecgh/go-spew v1.1.1 // indirect - github.com/go-viper/mapstructure/v2 v2.4.0 // indirect + github.com/go-viper/mapstructure/v2 v2.5.0 // indirect github.com/gobwas/glob v0.2.3 // indirect - github.com/hashicorp/go-version v1.7.0 // indirect + github.com/hashicorp/go-version v1.8.0 // indirect github.com/knadh/koanf/maps v0.1.2 // indirect github.com/knadh/koanf/providers/confmap v1.0.0 // indirect - github.com/knadh/koanf/v2 v2.3.0 // indirect + github.com/knadh/koanf/v2 v2.3.3 // indirect github.com/mitchellh/copystructure v1.2.0 // indirect github.com/mitchellh/reflectwalk v1.0.2 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect - go.opentelemetry.io/collector/featuregate v1.46.0 // indirect + go.opentelemetry.io/collector/featuregate v1.54.0 // indirect go.uber.org/multierr v1.11.0 // indirect go.uber.org/zap v1.27.1 // indirect go.yaml.in/yaml/v3 v3.0.4 // indirect diff --git a/confmap/provider/fileprovider/go.sum b/confmap/provider/fileprovider/go.sum index 6020e16119b7..d19c16bb075a 100644 --- a/confmap/provider/fileprovider/go.sum +++ b/confmap/provider/fileprovider/go.sum @@ -1,17 +1,17 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/go-viper/mapstructure/v2 v2.4.0 h1:EBsztssimR/CONLSZZ04E8qAkxNYq4Qp9LvH92wZUgs= -github.com/go-viper/mapstructure/v2 v2.4.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM= +github.com/go-viper/mapstructure/v2 v2.5.0 h1:vM5IJoUAy3d7zRSVtIwQgBj7BiWtMPfmPEgAXnvj1Ro= +github.com/go-viper/mapstructure/v2 v2.5.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM= github.com/gobwas/glob v0.2.3 h1:A4xDbljILXROh+kObIiy5kIaPYD8e96x1tgBhUI5J+Y= github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8= -github.com/hashicorp/go-version v1.7.0 h1:5tqGy27NaOTB8yJKUZELlFAS/LTKJkrmONwQKeRZfjY= -github.com/hashicorp/go-version v1.7.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= +github.com/hashicorp/go-version v1.8.0 h1:KAkNb1HAiZd1ukkxDFGmokVZe1Xy9HG6NUp+bPle2i4= +github.com/hashicorp/go-version v1.8.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/knadh/koanf/maps v0.1.2 h1:RBfmAW5CnZT+PJ1CVc1QSJKf4Xu9kxfQgYVQSu8hpbo= github.com/knadh/koanf/maps v0.1.2/go.mod h1:npD/QZY3V6ghQDdcQzl1W4ICNVTkohC8E73eI2xW4yI= github.com/knadh/koanf/providers/confmap v1.0.0 h1:mHKLJTE7iXEys6deO5p6olAiZdG5zwp8Aebir+/EaRE= github.com/knadh/koanf/providers/confmap v1.0.0/go.mod h1:txHYHiI2hAtF0/0sCmcuol4IDcuQbKTybiB1nOcUo1A= -github.com/knadh/koanf/v2 v2.3.0 h1:Qg076dDRFHvqnKG97ZEsi9TAg2/nFTa9hCdcSa1lvlM= -github.com/knadh/koanf/v2 v2.3.0/go.mod h1:gRb40VRAbd4iJMYYD5IxZ6hfuopFcXBpc9bbQpZwo28= +github.com/knadh/koanf/v2 v2.3.3 h1:jLJC8XCRfLC7n4F+ZKKdBsbq1bfXTpuFhf4L7t94D94= +github.com/knadh/koanf/v2 v2.3.3/go.mod h1:gRb40VRAbd4iJMYYD5IxZ6hfuopFcXBpc9bbQpZwo28= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= diff --git a/confmap/provider/fileprovider/provider_test.go b/confmap/provider/fileprovider/provider_test.go index 1487a515c077..c2a6005640dc 100644 --- a/confmap/provider/fileprovider/provider_test.go +++ b/confmap/provider/fileprovider/provider_test.go @@ -69,8 +69,8 @@ func TestRelativePath(t *testing.T) { retMap, err := ret.AsConf() require.NoError(t, err) expectedMap := confmap.NewFromStringMap(map[string]any{ - "processors::testprocessor": nil, - "exporters::otlp::endpoint": "localhost:4317", + "processors::testprocessor": nil, + "exporters::otlp_grpc::endpoint": "localhost:4317", }) assert.Equal(t, expectedMap, retMap) assert.NoError(t, fp.Shutdown(context.Background())) @@ -83,8 +83,8 @@ func TestAbsolutePath(t *testing.T) { retMap, err := ret.AsConf() require.NoError(t, err) expectedMap := confmap.NewFromStringMap(map[string]any{ - "processors::testprocessor": nil, - "exporters::otlp::endpoint": "localhost:4317", + "processors::testprocessor": nil, + "exporters::otlp_grpc::endpoint": "localhost:4317", }) assert.Equal(t, expectedMap, retMap) assert.NoError(t, fp.Shutdown(context.Background())) diff --git a/confmap/provider/fileprovider/testdata/default-config.yaml b/confmap/provider/fileprovider/testdata/default-config.yaml index 78b6afd11a46..cc4c0e8a3585 100644 --- a/confmap/provider/fileprovider/testdata/default-config.yaml +++ b/confmap/provider/fileprovider/testdata/default-config.yaml @@ -1,5 +1,5 @@ processors: testprocessor: exporters: - otlp: + otlp_grpc: endpoint: "localhost:4317" diff --git a/confmap/provider/httpprovider/go.mod b/confmap/provider/httpprovider/go.mod index e9f539fcb7fb..9ecfca7b2039 100644 --- a/confmap/provider/httpprovider/go.mod +++ b/confmap/provider/httpprovider/go.mod @@ -1,25 +1,25 @@ module go.opentelemetry.io/collector/confmap/provider/httpprovider -go 1.24.0 +go 1.25.0 require ( github.com/stretchr/testify v1.11.1 - go.opentelemetry.io/collector/confmap v1.46.0 + go.opentelemetry.io/collector/confmap v1.54.0 go.uber.org/goleak v1.3.0 ) require ( github.com/davecgh/go-spew v1.1.1 // indirect - github.com/go-viper/mapstructure/v2 v2.4.0 // indirect + github.com/go-viper/mapstructure/v2 v2.5.0 // indirect github.com/gobwas/glob v0.2.3 // indirect - github.com/hashicorp/go-version v1.7.0 // indirect + github.com/hashicorp/go-version v1.8.0 // indirect github.com/knadh/koanf/maps v0.1.2 // indirect github.com/knadh/koanf/providers/confmap v1.0.0 // indirect - github.com/knadh/koanf/v2 v2.3.0 // indirect + github.com/knadh/koanf/v2 v2.3.3 // indirect github.com/mitchellh/copystructure v1.2.0 // indirect github.com/mitchellh/reflectwalk v1.0.2 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect - go.opentelemetry.io/collector/featuregate v1.46.0 // indirect + go.opentelemetry.io/collector/featuregate v1.54.0 // indirect go.uber.org/multierr v1.11.0 // indirect go.uber.org/zap v1.27.1 // indirect go.yaml.in/yaml/v3 v3.0.4 // indirect diff --git a/confmap/provider/httpprovider/go.sum b/confmap/provider/httpprovider/go.sum index 6020e16119b7..d19c16bb075a 100644 --- a/confmap/provider/httpprovider/go.sum +++ b/confmap/provider/httpprovider/go.sum @@ -1,17 +1,17 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/go-viper/mapstructure/v2 v2.4.0 h1:EBsztssimR/CONLSZZ04E8qAkxNYq4Qp9LvH92wZUgs= -github.com/go-viper/mapstructure/v2 v2.4.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM= +github.com/go-viper/mapstructure/v2 v2.5.0 h1:vM5IJoUAy3d7zRSVtIwQgBj7BiWtMPfmPEgAXnvj1Ro= +github.com/go-viper/mapstructure/v2 v2.5.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM= github.com/gobwas/glob v0.2.3 h1:A4xDbljILXROh+kObIiy5kIaPYD8e96x1tgBhUI5J+Y= github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8= -github.com/hashicorp/go-version v1.7.0 h1:5tqGy27NaOTB8yJKUZELlFAS/LTKJkrmONwQKeRZfjY= -github.com/hashicorp/go-version v1.7.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= +github.com/hashicorp/go-version v1.8.0 h1:KAkNb1HAiZd1ukkxDFGmokVZe1Xy9HG6NUp+bPle2i4= +github.com/hashicorp/go-version v1.8.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/knadh/koanf/maps v0.1.2 h1:RBfmAW5CnZT+PJ1CVc1QSJKf4Xu9kxfQgYVQSu8hpbo= github.com/knadh/koanf/maps v0.1.2/go.mod h1:npD/QZY3V6ghQDdcQzl1W4ICNVTkohC8E73eI2xW4yI= github.com/knadh/koanf/providers/confmap v1.0.0 h1:mHKLJTE7iXEys6deO5p6olAiZdG5zwp8Aebir+/EaRE= github.com/knadh/koanf/providers/confmap v1.0.0/go.mod h1:txHYHiI2hAtF0/0sCmcuol4IDcuQbKTybiB1nOcUo1A= -github.com/knadh/koanf/v2 v2.3.0 h1:Qg076dDRFHvqnKG97ZEsi9TAg2/nFTa9hCdcSa1lvlM= -github.com/knadh/koanf/v2 v2.3.0/go.mod h1:gRb40VRAbd4iJMYYD5IxZ6hfuopFcXBpc9bbQpZwo28= +github.com/knadh/koanf/v2 v2.3.3 h1:jLJC8XCRfLC7n4F+ZKKdBsbq1bfXTpuFhf4L7t94D94= +github.com/knadh/koanf/v2 v2.3.3/go.mod h1:gRb40VRAbd4iJMYYD5IxZ6hfuopFcXBpc9bbQpZwo28= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= diff --git a/confmap/provider/httpsprovider/go.mod b/confmap/provider/httpsprovider/go.mod index dad75aae1110..0f6c6df7b243 100644 --- a/confmap/provider/httpsprovider/go.mod +++ b/confmap/provider/httpsprovider/go.mod @@ -1,25 +1,25 @@ module go.opentelemetry.io/collector/confmap/provider/httpsprovider -go 1.24.0 +go 1.25.0 require ( github.com/stretchr/testify v1.11.1 - go.opentelemetry.io/collector/confmap v1.46.0 + go.opentelemetry.io/collector/confmap v1.54.0 go.uber.org/goleak v1.3.0 ) require ( github.com/davecgh/go-spew v1.1.1 // indirect - github.com/go-viper/mapstructure/v2 v2.4.0 // indirect + github.com/go-viper/mapstructure/v2 v2.5.0 // indirect github.com/gobwas/glob v0.2.3 // indirect - github.com/hashicorp/go-version v1.7.0 // indirect + github.com/hashicorp/go-version v1.8.0 // indirect github.com/knadh/koanf/maps v0.1.2 // indirect github.com/knadh/koanf/providers/confmap v1.0.0 // indirect - github.com/knadh/koanf/v2 v2.3.0 // indirect + github.com/knadh/koanf/v2 v2.3.3 // indirect github.com/mitchellh/copystructure v1.2.0 // indirect github.com/mitchellh/reflectwalk v1.0.2 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect - go.opentelemetry.io/collector/featuregate v1.46.0 // indirect + go.opentelemetry.io/collector/featuregate v1.54.0 // indirect go.uber.org/multierr v1.11.0 // indirect go.uber.org/zap v1.27.1 // indirect go.yaml.in/yaml/v3 v3.0.4 // indirect diff --git a/confmap/provider/httpsprovider/go.sum b/confmap/provider/httpsprovider/go.sum index 6020e16119b7..d19c16bb075a 100644 --- a/confmap/provider/httpsprovider/go.sum +++ b/confmap/provider/httpsprovider/go.sum @@ -1,17 +1,17 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/go-viper/mapstructure/v2 v2.4.0 h1:EBsztssimR/CONLSZZ04E8qAkxNYq4Qp9LvH92wZUgs= -github.com/go-viper/mapstructure/v2 v2.4.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM= +github.com/go-viper/mapstructure/v2 v2.5.0 h1:vM5IJoUAy3d7zRSVtIwQgBj7BiWtMPfmPEgAXnvj1Ro= +github.com/go-viper/mapstructure/v2 v2.5.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM= github.com/gobwas/glob v0.2.3 h1:A4xDbljILXROh+kObIiy5kIaPYD8e96x1tgBhUI5J+Y= github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8= -github.com/hashicorp/go-version v1.7.0 h1:5tqGy27NaOTB8yJKUZELlFAS/LTKJkrmONwQKeRZfjY= -github.com/hashicorp/go-version v1.7.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= +github.com/hashicorp/go-version v1.8.0 h1:KAkNb1HAiZd1ukkxDFGmokVZe1Xy9HG6NUp+bPle2i4= +github.com/hashicorp/go-version v1.8.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/knadh/koanf/maps v0.1.2 h1:RBfmAW5CnZT+PJ1CVc1QSJKf4Xu9kxfQgYVQSu8hpbo= github.com/knadh/koanf/maps v0.1.2/go.mod h1:npD/QZY3V6ghQDdcQzl1W4ICNVTkohC8E73eI2xW4yI= github.com/knadh/koanf/providers/confmap v1.0.0 h1:mHKLJTE7iXEys6deO5p6olAiZdG5zwp8Aebir+/EaRE= github.com/knadh/koanf/providers/confmap v1.0.0/go.mod h1:txHYHiI2hAtF0/0sCmcuol4IDcuQbKTybiB1nOcUo1A= -github.com/knadh/koanf/v2 v2.3.0 h1:Qg076dDRFHvqnKG97ZEsi9TAg2/nFTa9hCdcSa1lvlM= -github.com/knadh/koanf/v2 v2.3.0/go.mod h1:gRb40VRAbd4iJMYYD5IxZ6hfuopFcXBpc9bbQpZwo28= +github.com/knadh/koanf/v2 v2.3.3 h1:jLJC8XCRfLC7n4F+ZKKdBsbq1bfXTpuFhf4L7t94D94= +github.com/knadh/koanf/v2 v2.3.3/go.mod h1:gRb40VRAbd4iJMYYD5IxZ6hfuopFcXBpc9bbQpZwo28= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= diff --git a/confmap/provider/yamlprovider/README.md b/confmap/provider/yamlprovider/README.md index abf74e585bc2..16f96ee1177e 100644 --- a/confmap/provider/yamlprovider/README.md +++ b/confmap/provider/yamlprovider/README.md @@ -22,5 +22,5 @@ The YAML Provider takes a literal YAML string as Collector configuration. The scheme for this provider is `yaml`. Usage looks like the following passed to the Collector's command line invocation: ```text ---config="yaml:exporters::otlphttp::sending_queue::batch::flush_timeout: 2s" +--config="yaml:exporters::otlp_http::sending_queue::batch::flush_timeout: 2s" ``` diff --git a/confmap/provider/yamlprovider/go.mod b/confmap/provider/yamlprovider/go.mod index 51252113402c..a43d906fd38a 100644 --- a/confmap/provider/yamlprovider/go.mod +++ b/confmap/provider/yamlprovider/go.mod @@ -1,25 +1,25 @@ module go.opentelemetry.io/collector/confmap/provider/yamlprovider -go 1.24.0 +go 1.25.0 require ( github.com/stretchr/testify v1.11.1 - go.opentelemetry.io/collector/confmap v1.46.0 + go.opentelemetry.io/collector/confmap v1.54.0 go.uber.org/goleak v1.3.0 ) require ( github.com/davecgh/go-spew v1.1.1 // indirect - github.com/go-viper/mapstructure/v2 v2.4.0 // indirect + github.com/go-viper/mapstructure/v2 v2.5.0 // indirect github.com/gobwas/glob v0.2.3 // indirect - github.com/hashicorp/go-version v1.7.0 // indirect + github.com/hashicorp/go-version v1.8.0 // indirect github.com/knadh/koanf/maps v0.1.2 // indirect github.com/knadh/koanf/providers/confmap v1.0.0 // indirect - github.com/knadh/koanf/v2 v2.3.0 // indirect + github.com/knadh/koanf/v2 v2.3.3 // indirect github.com/mitchellh/copystructure v1.2.0 // indirect github.com/mitchellh/reflectwalk v1.0.2 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect - go.opentelemetry.io/collector/featuregate v1.46.0 // indirect + go.opentelemetry.io/collector/featuregate v1.54.0 // indirect go.uber.org/multierr v1.11.0 // indirect go.uber.org/zap v1.27.1 // indirect go.yaml.in/yaml/v3 v3.0.4 // indirect diff --git a/confmap/provider/yamlprovider/go.sum b/confmap/provider/yamlprovider/go.sum index 6020e16119b7..d19c16bb075a 100644 --- a/confmap/provider/yamlprovider/go.sum +++ b/confmap/provider/yamlprovider/go.sum @@ -1,17 +1,17 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/go-viper/mapstructure/v2 v2.4.0 h1:EBsztssimR/CONLSZZ04E8qAkxNYq4Qp9LvH92wZUgs= -github.com/go-viper/mapstructure/v2 v2.4.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM= +github.com/go-viper/mapstructure/v2 v2.5.0 h1:vM5IJoUAy3d7zRSVtIwQgBj7BiWtMPfmPEgAXnvj1Ro= +github.com/go-viper/mapstructure/v2 v2.5.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM= github.com/gobwas/glob v0.2.3 h1:A4xDbljILXROh+kObIiy5kIaPYD8e96x1tgBhUI5J+Y= github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8= -github.com/hashicorp/go-version v1.7.0 h1:5tqGy27NaOTB8yJKUZELlFAS/LTKJkrmONwQKeRZfjY= -github.com/hashicorp/go-version v1.7.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= +github.com/hashicorp/go-version v1.8.0 h1:KAkNb1HAiZd1ukkxDFGmokVZe1Xy9HG6NUp+bPle2i4= +github.com/hashicorp/go-version v1.8.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/knadh/koanf/maps v0.1.2 h1:RBfmAW5CnZT+PJ1CVc1QSJKf4Xu9kxfQgYVQSu8hpbo= github.com/knadh/koanf/maps v0.1.2/go.mod h1:npD/QZY3V6ghQDdcQzl1W4ICNVTkohC8E73eI2xW4yI= github.com/knadh/koanf/providers/confmap v1.0.0 h1:mHKLJTE7iXEys6deO5p6olAiZdG5zwp8Aebir+/EaRE= github.com/knadh/koanf/providers/confmap v1.0.0/go.mod h1:txHYHiI2hAtF0/0sCmcuol4IDcuQbKTybiB1nOcUo1A= -github.com/knadh/koanf/v2 v2.3.0 h1:Qg076dDRFHvqnKG97ZEsi9TAg2/nFTa9hCdcSa1lvlM= -github.com/knadh/koanf/v2 v2.3.0/go.mod h1:gRb40VRAbd4iJMYYD5IxZ6hfuopFcXBpc9bbQpZwo28= +github.com/knadh/koanf/v2 v2.3.3 h1:jLJC8XCRfLC7n4F+ZKKdBsbq1bfXTpuFhf4L7t94D94= +github.com/knadh/koanf/v2 v2.3.3/go.mod h1:gRb40VRAbd4iJMYYD5IxZ6hfuopFcXBpc9bbQpZwo28= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= diff --git a/confmap/provider/yamlprovider/provider.go b/confmap/provider/yamlprovider/provider.go index 8385823abc13..c0e3296a39cb 100644 --- a/confmap/provider/yamlprovider/provider.go +++ b/confmap/provider/yamlprovider/provider.go @@ -24,8 +24,8 @@ type provider struct{} // bytes-uri = "yaml:" yaml-bytes // // Examples: -// `yaml:exporters::otlphttp::sending_queue::batch::flush_timeout: 2s` -// `yaml:exporters::otlphttp/foo::sending_queue::batch::flush_timeout: 2s` +// `yaml:exporters::otlp_http::sending_queue::batch::flush_timeout: 2s` +// `yaml:exporters::otlp_http/foo::sending_queue::batch::flush_timeout: 2s` func NewFactory() confmap.ProviderFactory { return confmap.NewProviderFactory(newProvider) } diff --git a/confmap/resolver_test.go b/confmap/resolver_test.go index 51e9795f1b47..9d157c28603d 100644 --- a/confmap/resolver_test.go +++ b/confmap/resolver_test.go @@ -17,9 +17,9 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "go.uber.org/zap" - yaml "go.yaml.in/yaml/v3" + "go.yaml.in/yaml/v3" - "go.opentelemetry.io/collector/confmap/internal" + "go.opentelemetry.io/collector/confmap/internal/metadata" "go.opentelemetry.io/collector/featuregate" ) @@ -398,14 +398,12 @@ func TestResolverShutdownClosesWatch(t *testing.T) { require.NoError(t, errN) var watcherWG sync.WaitGroup - watcherWG.Add(1) - go func() { + watcherWG.Go(func() { errW, ok := <-resolver.Watch() // Channel is closed, no exception - assert.NoError(t, errW) + require.NoError(t, errW) assert.False(t, ok) - watcherWG.Done() - }() + }) require.NoError(t, resolver.Shutdown(context.Background())) watcherWG.Wait() @@ -467,10 +465,10 @@ func TestMergeFunctionality(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { if tt.flagEnabled { - require.NoError(t, featuregate.GlobalRegistry().Set(internal.EnableMergeAppendOption.ID(), true)) + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.ConfmapEnableMergeAppendOptionFeatureGate.ID(), true)) defer func() { // Restore previous value. - require.NoError(t, featuregate.GlobalRegistry().Set(internal.EnableMergeAppendOption.ID(), false)) + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.ConfmapEnableMergeAppendOptionFeatureGate.ID(), false)) }() } runScenario(t, tt.scenarioFile) @@ -536,12 +534,10 @@ func newRaceDetectorProvider() ProviderFactory { } func (p *provider) Retrieve(_ context.Context, _ string, watcher WatcherFunc) (*Retrieved, error) { - p.wg.Add(1) - go func() { + p.wg.Go(func() { // mock a config change event and wait for goroutine to return. - defer p.wg.Done() watcher(&ChangeEvent{}) - }() + }) return NewRetrieved(map[string]any{}) } diff --git a/confmap/xconfmap/config.go b/confmap/xconfmap/config.go index 113d0a3fce1e..28b40cf8b1fb 100644 --- a/confmap/xconfmap/config.go +++ b/confmap/xconfmap/config.go @@ -11,6 +11,7 @@ import ( "strings" "go.opentelemetry.io/collector/confmap" + "go.opentelemetry.io/collector/confmap/internal" ) // As interface types are only used for static typing, a common idiom to find the reflection Type @@ -194,3 +195,13 @@ func stringifyMapKey(val reflect.Value) string { } } } + +// WithForceUnmarshaler sets an option to run a top-level Unmarshal method, +// even if the Conf being unmarshaled is already a parameter from an Unmarshal method. +// To avoid infinite recursion, this should only be used when unmarshaling into +// a different type from the current Unmarshaler. +// For instance, this should be used in wrapper types such as configoptional.Optional +// to ensure the inner type's Unmarshal method is called. +func WithForceUnmarshaler() confmap.UnmarshalOption { + return internal.WithForceUnmarshaler() +} diff --git a/confmap/xconfmap/confmap.go b/confmap/xconfmap/confmap.go new file mode 100644 index 000000000000..ab061c8d7fd8 --- /dev/null +++ b/confmap/xconfmap/confmap.go @@ -0,0 +1,27 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +package xconfmap // import "go.opentelemetry.io/collector/confmap/xconfmap" + +import ( + "go.opentelemetry.io/collector/confmap" + "go.opentelemetry.io/collector/confmap/internal" +) + +// ExpandedValue represents a configuration value that has been expanded from a template +// (e.g., environment variable substitution). It contains both the parsed value and the +// original string representation. +// +// This type is exposed to allow working with configuration values returned by ToStringMapRaw. +type ExpandedValue = internal.ExpandedValue + +// ToStringMapRaw returns the raw configuration map without sanitization. +// This is an experimental API and may change or be removed in future versions. +// The returned map may change at any time without prior notice. +// +// Unlike confmap.Conf.ToStringMap(), this function does not sanitize the map +// by removing expandedValue references. This allows for configmap manipulation +// without destroying internal types. +func ToStringMapRaw(conf *confmap.Conf) map[string]any { + return internal.ToStringMapRaw(conf) +} diff --git a/confmap/xconfmap/go.mod b/confmap/xconfmap/go.mod index a5d1de3d0b50..31f8daa1d250 100644 --- a/confmap/xconfmap/go.mod +++ b/confmap/xconfmap/go.mod @@ -1,24 +1,24 @@ module go.opentelemetry.io/collector/confmap/xconfmap -go 1.24.0 +go 1.25.0 require ( github.com/stretchr/testify v1.11.1 - go.opentelemetry.io/collector/confmap v1.46.0 + go.opentelemetry.io/collector/confmap v1.54.0 ) require ( github.com/davecgh/go-spew v1.1.1 // indirect - github.com/go-viper/mapstructure/v2 v2.4.0 // indirect + github.com/go-viper/mapstructure/v2 v2.5.0 // indirect github.com/gobwas/glob v0.2.3 // indirect - github.com/hashicorp/go-version v1.7.0 // indirect + github.com/hashicorp/go-version v1.8.0 // indirect github.com/knadh/koanf/maps v0.1.2 // indirect github.com/knadh/koanf/providers/confmap v1.0.0 // indirect - github.com/knadh/koanf/v2 v2.3.0 // indirect + github.com/knadh/koanf/v2 v2.3.3 // indirect github.com/mitchellh/copystructure v1.2.0 // indirect github.com/mitchellh/reflectwalk v1.0.2 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect - go.opentelemetry.io/collector/featuregate v1.46.0 // indirect + go.opentelemetry.io/collector/featuregate v1.54.0 // indirect go.uber.org/multierr v1.11.0 // indirect go.uber.org/zap v1.27.1 // indirect go.yaml.in/yaml/v3 v3.0.4 // indirect diff --git a/confmap/xconfmap/go.sum b/confmap/xconfmap/go.sum index 6020e16119b7..d19c16bb075a 100644 --- a/confmap/xconfmap/go.sum +++ b/confmap/xconfmap/go.sum @@ -1,17 +1,17 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/go-viper/mapstructure/v2 v2.4.0 h1:EBsztssimR/CONLSZZ04E8qAkxNYq4Qp9LvH92wZUgs= -github.com/go-viper/mapstructure/v2 v2.4.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM= +github.com/go-viper/mapstructure/v2 v2.5.0 h1:vM5IJoUAy3d7zRSVtIwQgBj7BiWtMPfmPEgAXnvj1Ro= +github.com/go-viper/mapstructure/v2 v2.5.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM= github.com/gobwas/glob v0.2.3 h1:A4xDbljILXROh+kObIiy5kIaPYD8e96x1tgBhUI5J+Y= github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8= -github.com/hashicorp/go-version v1.7.0 h1:5tqGy27NaOTB8yJKUZELlFAS/LTKJkrmONwQKeRZfjY= -github.com/hashicorp/go-version v1.7.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= +github.com/hashicorp/go-version v1.8.0 h1:KAkNb1HAiZd1ukkxDFGmokVZe1Xy9HG6NUp+bPle2i4= +github.com/hashicorp/go-version v1.8.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/knadh/koanf/maps v0.1.2 h1:RBfmAW5CnZT+PJ1CVc1QSJKf4Xu9kxfQgYVQSu8hpbo= github.com/knadh/koanf/maps v0.1.2/go.mod h1:npD/QZY3V6ghQDdcQzl1W4ICNVTkohC8E73eI2xW4yI= github.com/knadh/koanf/providers/confmap v1.0.0 h1:mHKLJTE7iXEys6deO5p6olAiZdG5zwp8Aebir+/EaRE= github.com/knadh/koanf/providers/confmap v1.0.0/go.mod h1:txHYHiI2hAtF0/0sCmcuol4IDcuQbKTybiB1nOcUo1A= -github.com/knadh/koanf/v2 v2.3.0 h1:Qg076dDRFHvqnKG97ZEsi9TAg2/nFTa9hCdcSa1lvlM= -github.com/knadh/koanf/v2 v2.3.0/go.mod h1:gRb40VRAbd4iJMYYD5IxZ6hfuopFcXBpc9bbQpZwo28= +github.com/knadh/koanf/v2 v2.3.3 h1:jLJC8XCRfLC7n4F+ZKKdBsbq1bfXTpuFhf4L7t94D94= +github.com/knadh/koanf/v2 v2.3.3/go.mod h1:gRb40VRAbd4iJMYYD5IxZ6hfuopFcXBpc9bbQpZwo28= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= diff --git a/confmap/xconfmap/metadata.yaml b/confmap/xconfmap/metadata.yaml new file mode 100644 index 000000000000..1224882e674d --- /dev/null +++ b/confmap/xconfmap/metadata.yaml @@ -0,0 +1,6 @@ +type: xconfmap +github_project: open-telemetry/opentelemetry-collector + +status: + disable_codecov_badge: true + class: pkg diff --git a/connector/connector.go b/connector/connector.go index e7c11d95bd51..4689519644f7 100644 --- a/connector/connector.go +++ b/connector/connector.go @@ -9,6 +9,7 @@ import ( "go.opentelemetry.io/collector/component" "go.opentelemetry.io/collector/connector/internal" "go.opentelemetry.io/collector/consumer" + "go.opentelemetry.io/collector/internal/componentalias" "go.opentelemetry.io/collector/pipeline" ) @@ -234,6 +235,7 @@ func WithLogsToLogs(createLogsToLogs CreateLogsToLogsFunc, sl component.Stabilit type factory struct { cfgType component.Type component.CreateDefaultConfigFunc + componentalias.TypeAliasHolder createTracesToTracesFunc CreateTracesToTracesFunc createTracesToMetricsFunc CreateTracesToMetricsFunc @@ -308,8 +310,8 @@ func (f *factory) CreateTracesToTraces(ctx context.Context, set Settings, cfg co return nil, internal.ErrDataTypes(set.ID, pipeline.SignalTraces, pipeline.SignalTraces) } - if set.ID.Type() != f.Type() { - return nil, internal.ErrIDMismatch(set.ID, f.Type()) + if err := componentalias.ValidateComponentType(f, set.ID); err != nil { + return nil, err } return f.createTracesToTracesFunc(ctx, set, cfg, next) @@ -320,8 +322,8 @@ func (f *factory) CreateTracesToMetrics(ctx context.Context, set Settings, cfg c return nil, internal.ErrDataTypes(set.ID, pipeline.SignalTraces, pipeline.SignalMetrics) } - if set.ID.Type() != f.Type() { - return nil, internal.ErrIDMismatch(set.ID, f.Type()) + if err := componentalias.ValidateComponentType(f, set.ID); err != nil { + return nil, err } return f.createTracesToMetricsFunc(ctx, set, cfg, next) @@ -332,8 +334,8 @@ func (f *factory) CreateTracesToLogs(ctx context.Context, set Settings, cfg comp return nil, internal.ErrDataTypes(set.ID, pipeline.SignalTraces, pipeline.SignalLogs) } - if set.ID.Type() != f.Type() { - return nil, internal.ErrIDMismatch(set.ID, f.Type()) + if err := componentalias.ValidateComponentType(f, set.ID); err != nil { + return nil, err } return f.createTracesToLogsFunc(ctx, set, cfg, next) @@ -344,8 +346,8 @@ func (f *factory) CreateMetricsToTraces(ctx context.Context, set Settings, cfg c return nil, internal.ErrDataTypes(set.ID, pipeline.SignalMetrics, pipeline.SignalTraces) } - if set.ID.Type() != f.Type() { - return nil, internal.ErrIDMismatch(set.ID, f.Type()) + if err := componentalias.ValidateComponentType(f, set.ID); err != nil { + return nil, err } return f.createMetricsToTracesFunc(ctx, set, cfg, next) @@ -356,8 +358,8 @@ func (f *factory) CreateMetricsToMetrics(ctx context.Context, set Settings, cfg return nil, internal.ErrDataTypes(set.ID, pipeline.SignalMetrics, pipeline.SignalMetrics) } - if set.ID.Type() != f.Type() { - return nil, internal.ErrIDMismatch(set.ID, f.Type()) + if err := componentalias.ValidateComponentType(f, set.ID); err != nil { + return nil, err } return f.createMetricsToMetricsFunc(ctx, set, cfg, next) @@ -368,8 +370,8 @@ func (f *factory) CreateMetricsToLogs(ctx context.Context, set Settings, cfg com return nil, internal.ErrDataTypes(set.ID, pipeline.SignalMetrics, pipeline.SignalLogs) } - if set.ID.Type() != f.Type() { - return nil, internal.ErrIDMismatch(set.ID, f.Type()) + if err := componentalias.ValidateComponentType(f, set.ID); err != nil { + return nil, err } return f.createMetricsToLogsFunc(ctx, set, cfg, next) @@ -380,8 +382,8 @@ func (f *factory) CreateLogsToTraces(ctx context.Context, set Settings, cfg comp return nil, internal.ErrDataTypes(set.ID, pipeline.SignalLogs, pipeline.SignalTraces) } - if set.ID.Type() != f.Type() { - return nil, internal.ErrIDMismatch(set.ID, f.Type()) + if err := componentalias.ValidateComponentType(f, set.ID); err != nil { + return nil, err } return f.createLogsToTracesFunc(ctx, set, cfg, next) @@ -392,8 +394,8 @@ func (f *factory) CreateLogsToMetrics(ctx context.Context, set Settings, cfg com return nil, internal.ErrDataTypes(set.ID, pipeline.SignalLogs, pipeline.SignalMetrics) } - if set.ID.Type() != f.Type() { - return nil, internal.ErrIDMismatch(set.ID, f.Type()) + if err := componentalias.ValidateComponentType(f, set.ID); err != nil { + return nil, err } return f.createLogsToMetricsFunc(ctx, set, cfg, next) @@ -404,8 +406,8 @@ func (f *factory) CreateLogsToLogs(ctx context.Context, set Settings, cfg compon return nil, internal.ErrDataTypes(set.ID, pipeline.SignalLogs, pipeline.SignalLogs) } - if set.ID.Type() != f.Type() { - return nil, internal.ErrIDMismatch(set.ID, f.Type()) + if err := componentalias.ValidateComponentType(f, set.ID); err != nil { + return nil, err } return f.createLogsToLogsFunc(ctx, set, cfg, next) @@ -416,6 +418,7 @@ func NewFactory(cfgType component.Type, createDefaultConfig component.CreateDefa f := &factory{ cfgType: cfgType, CreateDefaultConfigFunc: createDefaultConfig, + TypeAliasHolder: componentalias.NewTypeAliasHolder(), } for _, opt := range options { opt.apply(f) diff --git a/connector/connectortest/go.mod b/connector/connectortest/go.mod index e01fbffe5d8b..a6a62317e4ef 100644 --- a/connector/connectortest/go.mod +++ b/connector/connectortest/go.mod @@ -1,19 +1,19 @@ module go.opentelemetry.io/collector/connector/connectortest -go 1.24.0 +go 1.25.0 require ( github.com/google/uuid v1.6.0 github.com/stretchr/testify v1.11.1 - go.opentelemetry.io/collector/component v1.46.0 - go.opentelemetry.io/collector/component/componenttest v0.140.0 - go.opentelemetry.io/collector/connector v0.140.0 - go.opentelemetry.io/collector/connector/xconnector v0.140.0 - go.opentelemetry.io/collector/consumer v1.46.0 - go.opentelemetry.io/collector/consumer/consumertest v0.140.0 - go.opentelemetry.io/collector/consumer/xconsumer v0.140.0 - go.opentelemetry.io/collector/pdata v1.46.0 - go.opentelemetry.io/collector/pdata/pprofile v0.140.0 + go.opentelemetry.io/collector/component v1.54.0 + go.opentelemetry.io/collector/component/componenttest v0.148.0 + go.opentelemetry.io/collector/connector v0.148.0 + go.opentelemetry.io/collector/connector/xconnector v0.148.0 + go.opentelemetry.io/collector/consumer v1.54.0 + go.opentelemetry.io/collector/consumer/consumertest v0.148.0 + go.opentelemetry.io/collector/consumer/xconsumer v0.148.0 + go.opentelemetry.io/collector/pdata v1.54.0 + go.opentelemetry.io/collector/pdata/pprofile v0.148.0 go.uber.org/goleak v1.3.0 ) @@ -22,24 +22,25 @@ require ( github.com/davecgh/go-spew v1.1.1 // indirect github.com/go-logr/logr v1.4.3 // indirect github.com/go-logr/stdr v1.2.2 // indirect - github.com/hashicorp/go-version v1.7.0 // indirect + github.com/hashicorp/go-version v1.8.0 // indirect github.com/json-iterator/go v1.1.12 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee // indirect github.com/pmezard/go-difflib v1.0.0 // indirect go.opentelemetry.io/auto/sdk v1.2.1 // indirect - go.opentelemetry.io/collector/featuregate v1.46.0 // indirect - go.opentelemetry.io/collector/internal/fanoutconsumer v0.140.0 // indirect - go.opentelemetry.io/collector/pipeline v1.46.0 // indirect - go.opentelemetry.io/collector/pipeline/xpipeline v0.140.0 // indirect - go.opentelemetry.io/otel v1.40.0 // indirect - go.opentelemetry.io/otel/metric v1.40.0 // indirect + go.opentelemetry.io/collector/featuregate v1.54.0 // indirect + go.opentelemetry.io/collector/internal/componentalias v0.148.0 // indirect + go.opentelemetry.io/collector/internal/fanoutconsumer v0.148.0 // indirect + go.opentelemetry.io/collector/pipeline v1.54.0 // indirect + go.opentelemetry.io/collector/pipeline/xpipeline v0.148.0 // indirect + go.opentelemetry.io/otel v1.42.0 // indirect + go.opentelemetry.io/otel/metric v1.42.0 // indirect go.opentelemetry.io/otel/sdk v1.40.0 // indirect go.opentelemetry.io/otel/sdk/metric v1.40.0 // indirect - go.opentelemetry.io/otel/trace v1.40.0 // indirect + go.opentelemetry.io/otel/trace v1.42.0 // indirect go.uber.org/multierr v1.11.0 // indirect go.uber.org/zap v1.27.1 // indirect - golang.org/x/sys v0.40.0 // indirect + golang.org/x/sys v0.41.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) @@ -72,3 +73,5 @@ replace go.opentelemetry.io/collector/internal/fanoutconsumer => ../../internal/ replace go.opentelemetry.io/collector/featuregate => ../../featuregate replace go.opentelemetry.io/collector/internal/testutil => ../../internal/testutil + +replace go.opentelemetry.io/collector/internal/componentalias => ../../internal/componentalias diff --git a/connector/connectortest/go.sum b/connector/connectortest/go.sum index c102571e7869..43bdbeb8d219 100644 --- a/connector/connectortest/go.sum +++ b/connector/connectortest/go.sum @@ -13,8 +13,8 @@ github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/hashicorp/go-version v1.7.0 h1:5tqGy27NaOTB8yJKUZELlFAS/LTKJkrmONwQKeRZfjY= -github.com/hashicorp/go-version v1.7.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= +github.com/hashicorp/go-version v1.8.0 h1:KAkNb1HAiZd1ukkxDFGmokVZe1Xy9HG6NUp+bPle2i4= +github.com/hashicorp/go-version v1.8.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= @@ -37,32 +37,32 @@ github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64= go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y= -go.opentelemetry.io/otel v1.40.0 h1:oA5YeOcpRTXq6NN7frwmwFR0Cn3RhTVZvXsP4duvCms= -go.opentelemetry.io/otel v1.40.0/go.mod h1:IMb+uXZUKkMXdPddhwAHm6UfOwJyh4ct1ybIlV14J0g= -go.opentelemetry.io/otel/metric v1.40.0 h1:rcZe317KPftE2rstWIBitCdVp89A2HqjkxR3c11+p9g= -go.opentelemetry.io/otel/metric v1.40.0/go.mod h1:ib/crwQH7N3r5kfiBZQbwrTge743UDc7DTFVZrrXnqc= +go.opentelemetry.io/otel v1.42.0 h1:lSQGzTgVR3+sgJDAU/7/ZMjN9Z+vUip7leaqBKy4sho= +go.opentelemetry.io/otel v1.42.0/go.mod h1:lJNsdRMxCUIWuMlVJWzecSMuNjE7dOYyWlqOXWkdqCc= +go.opentelemetry.io/otel/metric v1.42.0 h1:2jXG+3oZLNXEPfNmnpxKDeZsFI5o4J+nz6xUlaFdF/4= +go.opentelemetry.io/otel/metric v1.42.0/go.mod h1:RlUN/7vTU7Ao/diDkEpQpnz3/92J9ko05BIwxYa2SSI= go.opentelemetry.io/otel/sdk v1.40.0 h1:KHW/jUzgo6wsPh9At46+h4upjtccTmuZCFAc9OJ71f8= go.opentelemetry.io/otel/sdk v1.40.0/go.mod h1:Ph7EFdYvxq72Y8Li9q8KebuYUr2KoeyHx0DRMKrYBUE= go.opentelemetry.io/otel/sdk/metric v1.40.0 h1:mtmdVqgQkeRxHgRv4qhyJduP3fYJRMX4AtAlbuWdCYw= go.opentelemetry.io/otel/sdk/metric v1.40.0/go.mod h1:4Z2bGMf0KSK3uRjlczMOeMhKU2rhUqdWNoKcYrtcBPg= -go.opentelemetry.io/otel/trace v1.40.0 h1:WA4etStDttCSYuhwvEa8OP8I5EWu24lkOzp+ZYblVjw= -go.opentelemetry.io/otel/trace v1.40.0/go.mod h1:zeAhriXecNGP/s2SEG3+Y8X9ujcJOTqQ5RgdEJcawiA= -go.opentelemetry.io/proto/slim/otlp v1.9.0 h1:fPVMv8tP3TrsqlkH1HWYUpbCY9cAIemx184VGkS6vlE= -go.opentelemetry.io/proto/slim/otlp v1.9.0/go.mod h1:xXdeJJ90Gqyll+orzUkY4bOd2HECo5JofeoLpymVqdI= -go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.2.0 h1:o13nadWDNkH/quoDomDUClnQBpdQQ2Qqv0lQBjIXjE8= -go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.2.0/go.mod h1:Gyb6Xe7FTi/6xBHwMmngGoHqL0w29Y4eW8TGFzpefGA= -go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.2.0 h1:EiUYvtwu6PMrMHVjcPfnsG3v+ajPkbUeH+IL93+QYyk= -go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.2.0/go.mod h1:mUUHKFiN2SST3AhJ8XhJxEoeVW12oqfXog0Bo8W3Ec4= +go.opentelemetry.io/otel/trace v1.42.0 h1:OUCgIPt+mzOnaUTpOQcBiM/PLQ/Op7oq6g4LenLmOYY= +go.opentelemetry.io/otel/trace v1.42.0/go.mod h1:f3K9S+IFqnumBkKhRJMeaZeNk9epyhnCmQh/EysQCdc= +go.opentelemetry.io/proto/slim/otlp v1.10.0 h1:iR97Vs/ZDR+y9TfuP9b1XBtdPWeC+OMslIBmhcLU7jM= +go.opentelemetry.io/proto/slim/otlp v1.10.0/go.mod h1:lV9250stpjYLPNA5viFabIgP2QlUGRT1GdTgAf8SIUk= +go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.3.0 h1:RUF5rO0hAlgiJt1fzQVzcVs3vZVNHIcMLgOgG4rWNcQ= +go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.3.0/go.mod h1:I89cynRj8y+383o7tEQVg2SVA6SRgDVIouWPUVXjx0U= +go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.3.0 h1:CQvJSldHRUN6Z8jsUeYv8J0lXRvygALXIzsmAeCcZE0= +go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.3.0/go.mod h1:xSQ+mEfJe/GjK1LXEyVOoSI1N9JV9ZI923X5kup43W4= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= go.uber.org/zap v1.27.1 h1:08RqriUEv8+ArZRYSTXy1LeBScaMpVSTBhCeaZYfMYc= go.uber.org/zap v1.27.1/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= -golang.org/x/sys v0.40.0 h1:DBZZqJ2Rkml6QMQsZywtnjnnGvHza6BTfYFWY9kjEWQ= -golang.org/x/sys v0.40.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= -google.golang.org/protobuf v1.36.10 h1:AYd7cD/uASjIL6Q9LiTjz8JLcrh/88q5UObnmY3aOOE= -google.golang.org/protobuf v1.36.10/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= +golang.org/x/sys v0.41.0 h1:Ivj+2Cp/ylzLiEU89QhWblYnOE9zerudt9Ftecq2C6k= +golang.org/x/sys v0.41.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= +google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE= +google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= diff --git a/connector/connectortest/metadata.yaml b/connector/connectortest/metadata.yaml new file mode 100644 index 000000000000..7e01bf7beb60 --- /dev/null +++ b/connector/connectortest/metadata.yaml @@ -0,0 +1,6 @@ +type: connector/connectortest +github_project: open-telemetry/opentelemetry-collector + +status: + disable_codecov_badge: true + class: pkg diff --git a/connector/forwardconnector/README.md b/connector/forwardconnector/README.md index fe8b93e41b96..c43c662becb6 100644 --- a/connector/forwardconnector/README.md +++ b/connector/forwardconnector/README.md @@ -1,6 +1,5 @@ -# Forward Connector - +# Forward Connector | Status | | | ------------- |-----------| | Distributions | [core], [contrib], [k8s] | diff --git a/connector/forwardconnector/generated_component_test.go b/connector/forwardconnector/generated_component_test.go index c60eef921283..00270ba58fe1 100644 --- a/connector/forwardconnector/generated_component_test.go +++ b/connector/forwardconnector/generated_component_test.go @@ -13,9 +13,12 @@ import ( "go.opentelemetry.io/collector/confmap/confmaptest" "go.opentelemetry.io/collector/connector" "go.opentelemetry.io/collector/connector/connectortest" + "go.opentelemetry.io/collector/connector/xconnector" "go.opentelemetry.io/collector/consumer" "go.opentelemetry.io/collector/consumer/consumertest" + "go.opentelemetry.io/collector/consumer/xconsumer" "go.opentelemetry.io/collector/pipeline" + "go.opentelemetry.io/collector/pipeline/xpipeline" ) var typ = component.MustNewType("forward") @@ -59,6 +62,14 @@ func TestComponentLifecycle(t *testing.T) { return factory.CreateTracesToTraces(ctx, set, cfg, router) }, }, + + { + name: "profiles_to_profiles", + createFn: func(ctx context.Context, set connector.Settings, cfg component.Config) (component.Component, error) { + router := xconnector.NewProfilesRouter(map[pipeline.ID]xconsumer.Profiles{pipeline.NewID(xpipeline.SignalProfiles): consumertest.NewNop()}) + return factory.(xconnector.Factory).CreateProfilesToProfiles(ctx, set, cfg, router) + }, + }, } cm, err := confmaptest.LoadConf("metadata.yaml") diff --git a/connector/forwardconnector/go.mod b/connector/forwardconnector/go.mod index 207358aab8ab..c7518eb2982a 100644 --- a/connector/forwardconnector/go.mod +++ b/connector/forwardconnector/go.mod @@ -1,21 +1,22 @@ module go.opentelemetry.io/collector/connector/forwardconnector -go 1.24.0 +go 1.25.0 require ( github.com/stretchr/testify v1.11.1 - go.opentelemetry.io/collector/component v1.46.0 - go.opentelemetry.io/collector/component/componenttest v0.140.0 - go.opentelemetry.io/collector/confmap v1.46.0 - go.opentelemetry.io/collector/connector v0.140.0 - go.opentelemetry.io/collector/connector/connectortest v0.140.0 - go.opentelemetry.io/collector/connector/xconnector v0.140.0 - go.opentelemetry.io/collector/consumer v1.46.0 - go.opentelemetry.io/collector/consumer/consumertest v0.140.0 - go.opentelemetry.io/collector/consumer/xconsumer v0.140.0 - go.opentelemetry.io/collector/pdata v1.46.0 - go.opentelemetry.io/collector/pdata/pprofile v0.140.0 - go.opentelemetry.io/collector/pipeline v1.46.0 + go.opentelemetry.io/collector/component v1.54.0 + go.opentelemetry.io/collector/component/componenttest v0.148.0 + go.opentelemetry.io/collector/confmap v1.54.0 + go.opentelemetry.io/collector/connector v0.148.0 + go.opentelemetry.io/collector/connector/connectortest v0.148.0 + go.opentelemetry.io/collector/connector/xconnector v0.148.0 + go.opentelemetry.io/collector/consumer v1.54.0 + go.opentelemetry.io/collector/consumer/consumertest v0.148.0 + go.opentelemetry.io/collector/consumer/xconsumer v0.148.0 + go.opentelemetry.io/collector/pdata v1.54.0 + go.opentelemetry.io/collector/pdata/pprofile v0.148.0 + go.opentelemetry.io/collector/pipeline v1.54.0 + go.opentelemetry.io/collector/pipeline/xpipeline v0.148.0 go.uber.org/goleak v1.3.0 ) @@ -24,32 +25,32 @@ require ( github.com/davecgh/go-spew v1.1.1 // indirect github.com/go-logr/logr v1.4.3 // indirect github.com/go-logr/stdr v1.2.2 // indirect - github.com/go-viper/mapstructure/v2 v2.4.0 // indirect + github.com/go-viper/mapstructure/v2 v2.5.0 // indirect github.com/gobwas/glob v0.2.3 // indirect github.com/google/uuid v1.6.0 // indirect - github.com/hashicorp/go-version v1.7.0 // indirect + github.com/hashicorp/go-version v1.8.0 // indirect github.com/json-iterator/go v1.1.12 // indirect github.com/knadh/koanf/maps v0.1.2 // indirect github.com/knadh/koanf/providers/confmap v1.0.0 // indirect - github.com/knadh/koanf/v2 v2.3.0 // indirect + github.com/knadh/koanf/v2 v2.3.3 // indirect github.com/mitchellh/copystructure v1.2.0 // indirect github.com/mitchellh/reflectwalk v1.0.2 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee // indirect github.com/pmezard/go-difflib v1.0.0 // indirect go.opentelemetry.io/auto/sdk v1.2.1 // indirect - go.opentelemetry.io/collector/featuregate v1.46.0 // indirect - go.opentelemetry.io/collector/internal/fanoutconsumer v0.140.0 // indirect - go.opentelemetry.io/collector/pipeline/xpipeline v0.140.0 // indirect - go.opentelemetry.io/otel v1.40.0 // indirect - go.opentelemetry.io/otel/metric v1.40.0 // indirect + go.opentelemetry.io/collector/featuregate v1.54.0 // indirect + go.opentelemetry.io/collector/internal/componentalias v0.148.0 // indirect + go.opentelemetry.io/collector/internal/fanoutconsumer v0.148.0 // indirect + go.opentelemetry.io/otel v1.42.0 // indirect + go.opentelemetry.io/otel/metric v1.42.0 // indirect go.opentelemetry.io/otel/sdk v1.40.0 // indirect go.opentelemetry.io/otel/sdk/metric v1.40.0 // indirect - go.opentelemetry.io/otel/trace v1.40.0 // indirect + go.opentelemetry.io/otel/trace v1.42.0 // indirect go.uber.org/multierr v1.11.0 // indirect go.uber.org/zap v1.27.1 // indirect go.yaml.in/yaml/v3 v3.0.4 // indirect - golang.org/x/sys v0.40.0 // indirect + golang.org/x/sys v0.41.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) @@ -91,3 +92,5 @@ replace go.opentelemetry.io/collector/internal/fanoutconsumer => ../../internal/ replace go.opentelemetry.io/collector/featuregate => ../../featuregate replace go.opentelemetry.io/collector/internal/testutil => ../../internal/testutil + +replace go.opentelemetry.io/collector/internal/componentalias => ../../internal/componentalias diff --git a/connector/forwardconnector/go.sum b/connector/forwardconnector/go.sum index 6f8a31ea9ede..b796e7242c7e 100644 --- a/connector/forwardconnector/go.sum +++ b/connector/forwardconnector/go.sum @@ -8,8 +8,8 @@ github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI= github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= -github.com/go-viper/mapstructure/v2 v2.4.0 h1:EBsztssimR/CONLSZZ04E8qAkxNYq4Qp9LvH92wZUgs= -github.com/go-viper/mapstructure/v2 v2.4.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM= +github.com/go-viper/mapstructure/v2 v2.5.0 h1:vM5IJoUAy3d7zRSVtIwQgBj7BiWtMPfmPEgAXnvj1Ro= +github.com/go-viper/mapstructure/v2 v2.5.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM= github.com/gobwas/glob v0.2.3 h1:A4xDbljILXROh+kObIiy5kIaPYD8e96x1tgBhUI5J+Y= github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8= github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= @@ -17,16 +17,16 @@ github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/hashicorp/go-version v1.7.0 h1:5tqGy27NaOTB8yJKUZELlFAS/LTKJkrmONwQKeRZfjY= -github.com/hashicorp/go-version v1.7.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= +github.com/hashicorp/go-version v1.8.0 h1:KAkNb1HAiZd1ukkxDFGmokVZe1Xy9HG6NUp+bPle2i4= +github.com/hashicorp/go-version v1.8.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= github.com/knadh/koanf/maps v0.1.2 h1:RBfmAW5CnZT+PJ1CVc1QSJKf4Xu9kxfQgYVQSu8hpbo= github.com/knadh/koanf/maps v0.1.2/go.mod h1:npD/QZY3V6ghQDdcQzl1W4ICNVTkohC8E73eI2xW4yI= github.com/knadh/koanf/providers/confmap v1.0.0 h1:mHKLJTE7iXEys6deO5p6olAiZdG5zwp8Aebir+/EaRE= github.com/knadh/koanf/providers/confmap v1.0.0/go.mod h1:txHYHiI2hAtF0/0sCmcuol4IDcuQbKTybiB1nOcUo1A= -github.com/knadh/koanf/v2 v2.3.0 h1:Qg076dDRFHvqnKG97ZEsi9TAg2/nFTa9hCdcSa1lvlM= -github.com/knadh/koanf/v2 v2.3.0/go.mod h1:gRb40VRAbd4iJMYYD5IxZ6hfuopFcXBpc9bbQpZwo28= +github.com/knadh/koanf/v2 v2.3.3 h1:jLJC8XCRfLC7n4F+ZKKdBsbq1bfXTpuFhf4L7t94D94= +github.com/knadh/koanf/v2 v2.3.3/go.mod h1:gRb40VRAbd4iJMYYD5IxZ6hfuopFcXBpc9bbQpZwo28= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= @@ -51,22 +51,22 @@ github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64= go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y= -go.opentelemetry.io/otel v1.40.0 h1:oA5YeOcpRTXq6NN7frwmwFR0Cn3RhTVZvXsP4duvCms= -go.opentelemetry.io/otel v1.40.0/go.mod h1:IMb+uXZUKkMXdPddhwAHm6UfOwJyh4ct1ybIlV14J0g= -go.opentelemetry.io/otel/metric v1.40.0 h1:rcZe317KPftE2rstWIBitCdVp89A2HqjkxR3c11+p9g= -go.opentelemetry.io/otel/metric v1.40.0/go.mod h1:ib/crwQH7N3r5kfiBZQbwrTge743UDc7DTFVZrrXnqc= +go.opentelemetry.io/otel v1.42.0 h1:lSQGzTgVR3+sgJDAU/7/ZMjN9Z+vUip7leaqBKy4sho= +go.opentelemetry.io/otel v1.42.0/go.mod h1:lJNsdRMxCUIWuMlVJWzecSMuNjE7dOYyWlqOXWkdqCc= +go.opentelemetry.io/otel/metric v1.42.0 h1:2jXG+3oZLNXEPfNmnpxKDeZsFI5o4J+nz6xUlaFdF/4= +go.opentelemetry.io/otel/metric v1.42.0/go.mod h1:RlUN/7vTU7Ao/diDkEpQpnz3/92J9ko05BIwxYa2SSI= go.opentelemetry.io/otel/sdk v1.40.0 h1:KHW/jUzgo6wsPh9At46+h4upjtccTmuZCFAc9OJ71f8= go.opentelemetry.io/otel/sdk v1.40.0/go.mod h1:Ph7EFdYvxq72Y8Li9q8KebuYUr2KoeyHx0DRMKrYBUE= go.opentelemetry.io/otel/sdk/metric v1.40.0 h1:mtmdVqgQkeRxHgRv4qhyJduP3fYJRMX4AtAlbuWdCYw= go.opentelemetry.io/otel/sdk/metric v1.40.0/go.mod h1:4Z2bGMf0KSK3uRjlczMOeMhKU2rhUqdWNoKcYrtcBPg= -go.opentelemetry.io/otel/trace v1.40.0 h1:WA4etStDttCSYuhwvEa8OP8I5EWu24lkOzp+ZYblVjw= -go.opentelemetry.io/otel/trace v1.40.0/go.mod h1:zeAhriXecNGP/s2SEG3+Y8X9ujcJOTqQ5RgdEJcawiA= -go.opentelemetry.io/proto/slim/otlp v1.9.0 h1:fPVMv8tP3TrsqlkH1HWYUpbCY9cAIemx184VGkS6vlE= -go.opentelemetry.io/proto/slim/otlp v1.9.0/go.mod h1:xXdeJJ90Gqyll+orzUkY4bOd2HECo5JofeoLpymVqdI= -go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.2.0 h1:o13nadWDNkH/quoDomDUClnQBpdQQ2Qqv0lQBjIXjE8= -go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.2.0/go.mod h1:Gyb6Xe7FTi/6xBHwMmngGoHqL0w29Y4eW8TGFzpefGA= -go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.2.0 h1:EiUYvtwu6PMrMHVjcPfnsG3v+ajPkbUeH+IL93+QYyk= -go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.2.0/go.mod h1:mUUHKFiN2SST3AhJ8XhJxEoeVW12oqfXog0Bo8W3Ec4= +go.opentelemetry.io/otel/trace v1.42.0 h1:OUCgIPt+mzOnaUTpOQcBiM/PLQ/Op7oq6g4LenLmOYY= +go.opentelemetry.io/otel/trace v1.42.0/go.mod h1:f3K9S+IFqnumBkKhRJMeaZeNk9epyhnCmQh/EysQCdc= +go.opentelemetry.io/proto/slim/otlp v1.10.0 h1:iR97Vs/ZDR+y9TfuP9b1XBtdPWeC+OMslIBmhcLU7jM= +go.opentelemetry.io/proto/slim/otlp v1.10.0/go.mod h1:lV9250stpjYLPNA5viFabIgP2QlUGRT1GdTgAf8SIUk= +go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.3.0 h1:RUF5rO0hAlgiJt1fzQVzcVs3vZVNHIcMLgOgG4rWNcQ= +go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.3.0/go.mod h1:I89cynRj8y+383o7tEQVg2SVA6SRgDVIouWPUVXjx0U= +go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.3.0 h1:CQvJSldHRUN6Z8jsUeYv8J0lXRvygALXIzsmAeCcZE0= +go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.3.0/go.mod h1:xSQ+mEfJe/GjK1LXEyVOoSI1N9JV9ZI923X5kup43W4= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= @@ -75,10 +75,10 @@ go.uber.org/zap v1.27.1 h1:08RqriUEv8+ArZRYSTXy1LeBScaMpVSTBhCeaZYfMYc= go.uber.org/zap v1.27.1/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc= go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg= -golang.org/x/sys v0.40.0 h1:DBZZqJ2Rkml6QMQsZywtnjnnGvHza6BTfYFWY9kjEWQ= -golang.org/x/sys v0.40.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= -google.golang.org/protobuf v1.36.10 h1:AYd7cD/uASjIL6Q9LiTjz8JLcrh/88q5UObnmY3aOOE= -google.golang.org/protobuf v1.36.10/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= +golang.org/x/sys v0.41.0 h1:Ivj+2Cp/ylzLiEU89QhWblYnOE9zerudt9Ftecq2C6k= +golang.org/x/sys v0.41.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= +google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE= +google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= diff --git a/connector/forwardconnector/metadata.yaml b/connector/forwardconnector/metadata.yaml index 1b1aaa79bc6b..2ec4b4ccb18a 100644 --- a/connector/forwardconnector/metadata.yaml +++ b/connector/forwardconnector/metadata.yaml @@ -1,3 +1,4 @@ +display_name: Forward Connector type: forward github_project: open-telemetry/opentelemetry-collector diff --git a/connector/go.mod b/connector/go.mod index f7e2397deff3..b5e034304a10 100644 --- a/connector/go.mod +++ b/connector/go.mod @@ -1,16 +1,17 @@ module go.opentelemetry.io/collector/connector -go 1.24.0 +go 1.25.0 require ( github.com/stretchr/testify v1.11.1 - go.opentelemetry.io/collector/component v1.46.0 - go.opentelemetry.io/collector/consumer v1.46.0 - go.opentelemetry.io/collector/consumer/consumertest v0.140.0 - go.opentelemetry.io/collector/internal/fanoutconsumer v0.140.0 - go.opentelemetry.io/collector/pdata v1.46.0 - go.opentelemetry.io/collector/pdata/testdata v0.140.0 - go.opentelemetry.io/collector/pipeline v1.46.0 + go.opentelemetry.io/collector/component v1.54.0 + go.opentelemetry.io/collector/consumer v1.54.0 + go.opentelemetry.io/collector/consumer/consumertest v0.148.0 + go.opentelemetry.io/collector/internal/componentalias v0.148.0 + go.opentelemetry.io/collector/internal/fanoutconsumer v0.148.0 + go.opentelemetry.io/collector/pdata v1.54.0 + go.opentelemetry.io/collector/pdata/testdata v0.148.0 + go.opentelemetry.io/collector/pipeline v1.54.0 go.uber.org/goleak v1.3.0 go.uber.org/multierr v1.11.0 ) @@ -18,17 +19,17 @@ require ( require ( github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/davecgh/go-spew v1.1.1 // indirect - github.com/hashicorp/go-version v1.7.0 // indirect + github.com/hashicorp/go-version v1.8.0 // indirect github.com/json-iterator/go v1.1.12 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee // indirect github.com/pmezard/go-difflib v1.0.0 // indirect - go.opentelemetry.io/collector/consumer/xconsumer v0.140.0 // indirect - go.opentelemetry.io/collector/featuregate v1.46.0 // indirect - go.opentelemetry.io/collector/pdata/pprofile v0.140.0 // indirect - go.opentelemetry.io/otel v1.40.0 // indirect - go.opentelemetry.io/otel/metric v1.40.0 // indirect - go.opentelemetry.io/otel/trace v1.40.0 // indirect + go.opentelemetry.io/collector/consumer/xconsumer v0.148.0 // indirect + go.opentelemetry.io/collector/featuregate v1.54.0 // indirect + go.opentelemetry.io/collector/pdata/pprofile v0.148.0 // indirect + go.opentelemetry.io/otel v1.42.0 // indirect + go.opentelemetry.io/otel/metric v1.42.0 // indirect + go.opentelemetry.io/otel/trace v1.42.0 // indirect go.uber.org/zap v1.27.1 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) @@ -49,6 +50,8 @@ replace go.opentelemetry.io/collector/consumer/consumertest => ../consumer/consu replace go.opentelemetry.io/collector/pipeline => ../pipeline +replace go.opentelemetry.io/collector/internal/componentalias => ../internal/componentalias + replace go.opentelemetry.io/collector/internal/fanoutconsumer => ../internal/fanoutconsumer replace go.opentelemetry.io/collector/featuregate => ../featuregate diff --git a/connector/go.sum b/connector/go.sum index 37d6edbc3764..1abfd0c69894 100644 --- a/connector/go.sum +++ b/connector/go.sum @@ -10,8 +10,8 @@ github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= -github.com/hashicorp/go-version v1.7.0 h1:5tqGy27NaOTB8yJKUZELlFAS/LTKJkrmONwQKeRZfjY= -github.com/hashicorp/go-version v1.7.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= +github.com/hashicorp/go-version v1.8.0 h1:KAkNb1HAiZd1ukkxDFGmokVZe1Xy9HG6NUp+bPle2i4= +github.com/hashicorp/go-version v1.8.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= @@ -34,26 +34,26 @@ github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64= go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y= -go.opentelemetry.io/otel v1.40.0 h1:oA5YeOcpRTXq6NN7frwmwFR0Cn3RhTVZvXsP4duvCms= -go.opentelemetry.io/otel v1.40.0/go.mod h1:IMb+uXZUKkMXdPddhwAHm6UfOwJyh4ct1ybIlV14J0g= -go.opentelemetry.io/otel/metric v1.40.0 h1:rcZe317KPftE2rstWIBitCdVp89A2HqjkxR3c11+p9g= -go.opentelemetry.io/otel/metric v1.40.0/go.mod h1:ib/crwQH7N3r5kfiBZQbwrTge743UDc7DTFVZrrXnqc= -go.opentelemetry.io/otel/trace v1.40.0 h1:WA4etStDttCSYuhwvEa8OP8I5EWu24lkOzp+ZYblVjw= -go.opentelemetry.io/otel/trace v1.40.0/go.mod h1:zeAhriXecNGP/s2SEG3+Y8X9ujcJOTqQ5RgdEJcawiA= -go.opentelemetry.io/proto/slim/otlp v1.9.0 h1:fPVMv8tP3TrsqlkH1HWYUpbCY9cAIemx184VGkS6vlE= -go.opentelemetry.io/proto/slim/otlp v1.9.0/go.mod h1:xXdeJJ90Gqyll+orzUkY4bOd2HECo5JofeoLpymVqdI= -go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.2.0 h1:o13nadWDNkH/quoDomDUClnQBpdQQ2Qqv0lQBjIXjE8= -go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.2.0/go.mod h1:Gyb6Xe7FTi/6xBHwMmngGoHqL0w29Y4eW8TGFzpefGA= -go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.2.0 h1:EiUYvtwu6PMrMHVjcPfnsG3v+ajPkbUeH+IL93+QYyk= -go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.2.0/go.mod h1:mUUHKFiN2SST3AhJ8XhJxEoeVW12oqfXog0Bo8W3Ec4= +go.opentelemetry.io/otel v1.42.0 h1:lSQGzTgVR3+sgJDAU/7/ZMjN9Z+vUip7leaqBKy4sho= +go.opentelemetry.io/otel v1.42.0/go.mod h1:lJNsdRMxCUIWuMlVJWzecSMuNjE7dOYyWlqOXWkdqCc= +go.opentelemetry.io/otel/metric v1.42.0 h1:2jXG+3oZLNXEPfNmnpxKDeZsFI5o4J+nz6xUlaFdF/4= +go.opentelemetry.io/otel/metric v1.42.0/go.mod h1:RlUN/7vTU7Ao/diDkEpQpnz3/92J9ko05BIwxYa2SSI= +go.opentelemetry.io/otel/trace v1.42.0 h1:OUCgIPt+mzOnaUTpOQcBiM/PLQ/Op7oq6g4LenLmOYY= +go.opentelemetry.io/otel/trace v1.42.0/go.mod h1:f3K9S+IFqnumBkKhRJMeaZeNk9epyhnCmQh/EysQCdc= +go.opentelemetry.io/proto/slim/otlp v1.10.0 h1:iR97Vs/ZDR+y9TfuP9b1XBtdPWeC+OMslIBmhcLU7jM= +go.opentelemetry.io/proto/slim/otlp v1.10.0/go.mod h1:lV9250stpjYLPNA5viFabIgP2QlUGRT1GdTgAf8SIUk= +go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.3.0 h1:RUF5rO0hAlgiJt1fzQVzcVs3vZVNHIcMLgOgG4rWNcQ= +go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.3.0/go.mod h1:I89cynRj8y+383o7tEQVg2SVA6SRgDVIouWPUVXjx0U= +go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.3.0 h1:CQvJSldHRUN6Z8jsUeYv8J0lXRvygALXIzsmAeCcZE0= +go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.3.0/go.mod h1:xSQ+mEfJe/GjK1LXEyVOoSI1N9JV9ZI923X5kup43W4= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= go.uber.org/zap v1.27.1 h1:08RqriUEv8+ArZRYSTXy1LeBScaMpVSTBhCeaZYfMYc= go.uber.org/zap v1.27.1/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= -google.golang.org/protobuf v1.36.10 h1:AYd7cD/uASjIL6Q9LiTjz8JLcrh/88q5UObnmY3aOOE= -google.golang.org/protobuf v1.36.10/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= +google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE= +google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= diff --git a/connector/metadata.yaml b/connector/metadata.yaml new file mode 100644 index 000000000000..9cb77b44bc68 --- /dev/null +++ b/connector/metadata.yaml @@ -0,0 +1,6 @@ +type: connector +github_project: open-telemetry/opentelemetry-collector + +status: + disable_codecov_badge: true + class: pkg diff --git a/connector/xconnector/connector.go b/connector/xconnector/connector.go index 3a516ad918dd..3f874d0838ac 100644 --- a/connector/xconnector/connector.go +++ b/connector/xconnector/connector.go @@ -11,6 +11,7 @@ import ( "go.opentelemetry.io/collector/connector/internal" "go.opentelemetry.io/collector/consumer" "go.opentelemetry.io/collector/consumer/xconsumer" + "go.opentelemetry.io/collector/internal/componentalias" "go.opentelemetry.io/collector/pipeline" "go.opentelemetry.io/collector/pipeline/xpipeline" ) @@ -78,88 +79,82 @@ type CreateProfilesToLogsFunc func(context.Context, connector.Settings, componen // FactoryOption apply changes to ReceiverOptions. type FactoryOption interface { // applyOption applies the option. - applyOption(o *factoryOpts) + applyOption(o *factory) } // factoryOptionFunc is an ReceiverFactoryOption created through a function. -type factoryOptionFunc func(*factoryOpts) +type factoryOptionFunc func(*factory) -func (f factoryOptionFunc) applyOption(o *factoryOpts) { +func (f factoryOptionFunc) applyOption(o *factory) { f(o) } -type factoryOpts struct { - opts []connector.FactoryOption - - *factory -} - // WithTracesToTraces overrides the default "error not supported" implementation for WithTracesToTraces and the default "undefined" stability level. func WithTracesToTraces(createTracesToTraces connector.CreateTracesToTracesFunc, sl component.StabilityLevel) FactoryOption { - return factoryOptionFunc(func(o *factoryOpts) { + return factoryOptionFunc(func(o *factory) { o.opts = append(o.opts, connector.WithTracesToTraces(createTracesToTraces, sl)) }) } // WithTracesToMetrics overrides the default "error not supported" implementation for WithTracesToMetrics and the default "undefined" stability level. func WithTracesToMetrics(createTracesToMetrics connector.CreateTracesToMetricsFunc, sl component.StabilityLevel) FactoryOption { - return factoryOptionFunc(func(o *factoryOpts) { + return factoryOptionFunc(func(o *factory) { o.opts = append(o.opts, connector.WithTracesToMetrics(createTracesToMetrics, sl)) }) } // WithTracesToLogs overrides the default "error not supported" implementation for WithTracesToLogs and the default "undefined" stability level. func WithTracesToLogs(createTracesToLogs connector.CreateTracesToLogsFunc, sl component.StabilityLevel) FactoryOption { - return factoryOptionFunc(func(o *factoryOpts) { + return factoryOptionFunc(func(o *factory) { o.opts = append(o.opts, connector.WithTracesToLogs(createTracesToLogs, sl)) }) } // WithMetricsToTraces overrides the default "error not supported" implementation for WithMetricsToTraces and the default "undefined" stability level. func WithMetricsToTraces(createMetricsToTraces connector.CreateMetricsToTracesFunc, sl component.StabilityLevel) FactoryOption { - return factoryOptionFunc(func(o *factoryOpts) { + return factoryOptionFunc(func(o *factory) { o.opts = append(o.opts, connector.WithMetricsToTraces(createMetricsToTraces, sl)) }) } // WithMetricsToMetrics overrides the default "error not supported" implementation for WithMetricsToMetrics and the default "undefined" stability level. func WithMetricsToMetrics(createMetricsToMetrics connector.CreateMetricsToMetricsFunc, sl component.StabilityLevel) FactoryOption { - return factoryOptionFunc(func(o *factoryOpts) { + return factoryOptionFunc(func(o *factory) { o.opts = append(o.opts, connector.WithMetricsToMetrics(createMetricsToMetrics, sl)) }) } // WithMetricsToLogs overrides the default "error not supported" implementation for WithMetricsToLogs and the default "undefined" stability level. func WithMetricsToLogs(createMetricsToLogs connector.CreateMetricsToLogsFunc, sl component.StabilityLevel) FactoryOption { - return factoryOptionFunc(func(o *factoryOpts) { + return factoryOptionFunc(func(o *factory) { o.opts = append(o.opts, connector.WithMetricsToLogs(createMetricsToLogs, sl)) }) } // WithLogsToTraces overrides the default "error not supported" implementation for WithLogsToTraces and the default "undefined" stability level. func WithLogsToTraces(createLogsToTraces connector.CreateLogsToTracesFunc, sl component.StabilityLevel) FactoryOption { - return factoryOptionFunc(func(o *factoryOpts) { + return factoryOptionFunc(func(o *factory) { o.opts = append(o.opts, connector.WithLogsToTraces(createLogsToTraces, sl)) }) } // WithLogsToMetrics overrides the default "error not supported" implementation for WithLogsToMetrics and the default "undefined" stability level. func WithLogsToMetrics(createLogsToMetrics connector.CreateLogsToMetricsFunc, sl component.StabilityLevel) FactoryOption { - return factoryOptionFunc(func(o *factoryOpts) { + return factoryOptionFunc(func(o *factory) { o.opts = append(o.opts, connector.WithLogsToMetrics(createLogsToMetrics, sl)) }) } // WithLogsToLogs overrides the default "error not supported" implementation for WithLogsToLogs and the default "undefined" stability level. func WithLogsToLogs(createLogsToLogs connector.CreateLogsToLogsFunc, sl component.StabilityLevel) FactoryOption { - return factoryOptionFunc(func(o *factoryOpts) { + return factoryOptionFunc(func(o *factory) { o.opts = append(o.opts, connector.WithLogsToLogs(createLogsToLogs, sl)) }) } // WithTracesToProfiles overrides the default "error not supported" implementation for WithTracesToProfiles and the default "undefined" stability level. func WithTracesToProfiles(createTracesToProfiles CreateTracesToProfilesFunc, sl component.StabilityLevel) FactoryOption { - return factoryOptionFunc(func(o *factoryOpts) { + return factoryOptionFunc(func(o *factory) { o.tracesToProfilesStabilityLevel = sl o.createTracesToProfilesFunc = createTracesToProfiles }) @@ -167,7 +162,7 @@ func WithTracesToProfiles(createTracesToProfiles CreateTracesToProfilesFunc, sl // WithMetricsToProfiles overrides the default "error not supported" implementation for WithMetricsToProfiles and the default "undefined" stability level. func WithMetricsToProfiles(createMetricsToProfiles CreateMetricsToProfilesFunc, sl component.StabilityLevel) FactoryOption { - return factoryOptionFunc(func(o *factoryOpts) { + return factoryOptionFunc(func(o *factory) { o.metricsToProfilesStabilityLevel = sl o.createMetricsToProfilesFunc = createMetricsToProfiles }) @@ -175,7 +170,7 @@ func WithMetricsToProfiles(createMetricsToProfiles CreateMetricsToProfilesFunc, // WithLogsToProfiles overrides the default "error not supported" implementation for WithLogsToProfiles and the default "undefined" stability level. func WithLogsToProfiles(createLogsToProfiles CreateLogsToProfilesFunc, sl component.StabilityLevel) FactoryOption { - return factoryOptionFunc(func(o *factoryOpts) { + return factoryOptionFunc(func(o *factory) { o.logsToProfilesStabilityLevel = sl o.createLogsToProfilesFunc = createLogsToProfiles }) @@ -183,7 +178,7 @@ func WithLogsToProfiles(createLogsToProfiles CreateLogsToProfilesFunc, sl compon // WithProfilesToProfiles overrides the default "error not supported" implementation for WithProfilesToProfiles and the default "undefined" stability level. func WithProfilesToProfiles(createProfilesToProfiles CreateProfilesToProfilesFunc, sl component.StabilityLevel) FactoryOption { - return factoryOptionFunc(func(o *factoryOpts) { + return factoryOptionFunc(func(o *factory) { o.profilesToProfilesStabilityLevel = sl o.createProfilesToProfilesFunc = createProfilesToProfiles }) @@ -191,7 +186,7 @@ func WithProfilesToProfiles(createProfilesToProfiles CreateProfilesToProfilesFun // WithProfilesToTraces overrides the default "error not supported" implementation for WithProfilesToTraces and the default "undefined" stability level. func WithProfilesToTraces(createProfilesToTraces CreateProfilesToTracesFunc, sl component.StabilityLevel) FactoryOption { - return factoryOptionFunc(func(o *factoryOpts) { + return factoryOptionFunc(func(o *factory) { o.profilesToTracesStabilityLevel = sl o.createProfilesToTracesFunc = createProfilesToTraces }) @@ -199,7 +194,7 @@ func WithProfilesToTraces(createProfilesToTraces CreateProfilesToTracesFunc, sl // WithProfilesToMetrics overrides the default "error not supported" implementation for WithProfilesToMetrics and the default "undefined" stability level. func WithProfilesToMetrics(createProfilesToMetrics CreateProfilesToMetricsFunc, sl component.StabilityLevel) FactoryOption { - return factoryOptionFunc(func(o *factoryOpts) { + return factoryOptionFunc(func(o *factory) { o.profilesToMetricsStabilityLevel = sl o.createProfilesToMetricsFunc = createProfilesToMetrics }) @@ -207,15 +202,25 @@ func WithProfilesToMetrics(createProfilesToMetrics CreateProfilesToMetricsFunc, // WithProfilesToLogs overrides the default "error not supported" implementation for WithProfilesToLogs and the default "undefined" stability level. func WithProfilesToLogs(createProfilesToLogs CreateProfilesToLogsFunc, sl component.StabilityLevel) FactoryOption { - return factoryOptionFunc(func(o *factoryOpts) { + return factoryOptionFunc(func(o *factory) { o.profilesToLogsStabilityLevel = sl o.createProfilesToLogsFunc = createProfilesToLogs }) } +// WithDeprecatedTypeAlias configures a deprecated type alias for the connector. Only one alias is supported per connector. +// When the alias is used in configuration, a deprecation warning is automatically logged. +func WithDeprecatedTypeAlias(alias component.Type) FactoryOption { + return factoryOptionFunc(func(o *factory) { + o.SetDeprecatedAlias(alias) + }) +} + // factory implements the Factory interface. type factory struct { connector.Factory + componentalias.TypeAliasHolder + opts []connector.FactoryOption createTracesToProfilesFunc CreateTracesToProfilesFunc createMetricsToProfilesFunc CreateMetricsToProfilesFunc @@ -268,6 +273,9 @@ func (f *factory) CreateTracesToProfiles(ctx context.Context, set connector.Sett if f.createTracesToProfilesFunc == nil { return nil, internal.ErrDataTypes(set.ID, pipeline.SignalTraces, xpipeline.SignalProfiles) } + if err := componentalias.ValidateComponentType(f.Factory, set.ID); err != nil { + return nil, err + } return f.createTracesToProfilesFunc(ctx, set, cfg, next) } @@ -275,6 +283,9 @@ func (f *factory) CreateMetricsToProfiles(ctx context.Context, set connector.Set if f.createMetricsToProfilesFunc == nil { return nil, internal.ErrDataTypes(set.ID, pipeline.SignalMetrics, xpipeline.SignalProfiles) } + if err := componentalias.ValidateComponentType(f.Factory, set.ID); err != nil { + return nil, err + } return f.createMetricsToProfilesFunc(ctx, set, cfg, next) } @@ -282,6 +293,9 @@ func (f *factory) CreateLogsToProfiles(ctx context.Context, set connector.Settin if f.createLogsToProfilesFunc == nil { return nil, internal.ErrDataTypes(set.ID, pipeline.SignalLogs, xpipeline.SignalProfiles) } + if err := componentalias.ValidateComponentType(f.Factory, set.ID); err != nil { + return nil, err + } return f.createLogsToProfilesFunc(ctx, set, cfg, next) } @@ -289,6 +303,9 @@ func (f *factory) CreateProfilesToProfiles(ctx context.Context, set connector.Se if f.createProfilesToProfilesFunc == nil { return nil, internal.ErrDataTypes(set.ID, xpipeline.SignalProfiles, xpipeline.SignalProfiles) } + if err := componentalias.ValidateComponentType(f.Factory, set.ID); err != nil { + return nil, err + } return f.createProfilesToProfilesFunc(ctx, set, cfg, next) } @@ -296,6 +313,9 @@ func (f *factory) CreateProfilesToTraces(ctx context.Context, set connector.Sett if f.createProfilesToTracesFunc == nil { return nil, internal.ErrDataTypes(set.ID, xpipeline.SignalProfiles, pipeline.SignalTraces) } + if err := componentalias.ValidateComponentType(f.Factory, set.ID); err != nil { + return nil, err + } return f.createProfilesToTracesFunc(ctx, set, cfg, next) } @@ -303,6 +323,9 @@ func (f *factory) CreateProfilesToMetrics(ctx context.Context, set connector.Set if f.createProfilesToMetricsFunc == nil { return nil, internal.ErrDataTypes(set.ID, xpipeline.SignalProfiles, pipeline.SignalMetrics) } + if err := componentalias.ValidateComponentType(f.Factory, set.ID); err != nil { + return nil, err + } return f.createProfilesToMetricsFunc(ctx, set, cfg, next) } @@ -310,15 +333,19 @@ func (f *factory) CreateProfilesToLogs(ctx context.Context, set connector.Settin if f.createProfilesToLogsFunc == nil { return nil, internal.ErrDataTypes(set.ID, xpipeline.SignalProfiles, pipeline.SignalLogs) } + if err := componentalias.ValidateComponentType(f.Factory, set.ID); err != nil { + return nil, err + } return f.createProfilesToLogsFunc(ctx, set, cfg, next) } -// NewFactory returns a Factory. +// NewFactory creates a wrapped connector.Factory with experimental capabilities func NewFactory(cfgType component.Type, createDefaultConfig component.CreateDefaultConfigFunc, options ...FactoryOption) Factory { - opts := factoryOpts{factory: &factory{}} + f := &factory{TypeAliasHolder: componentalias.NewTypeAliasHolder()} for _, opt := range options { - opt.applyOption(&opts) + opt.applyOption(f) } - opts.Factory = connector.NewFactory(cfgType, createDefaultConfig, opts.opts...) - return opts.factory + f.Factory = connector.NewFactory(cfgType, createDefaultConfig, f.opts...) + f.Factory.(componentalias.TypeAliasHolder).SetDeprecatedAlias(f.DeprecatedAlias()) + return f } diff --git a/connector/xconnector/connector_test.go b/connector/xconnector/connector_test.go index 8363a18a36b1..32de0b5c6a5f 100644 --- a/connector/xconnector/connector_test.go +++ b/connector/xconnector/connector_test.go @@ -16,13 +16,14 @@ import ( "go.opentelemetry.io/collector/consumer" "go.opentelemetry.io/collector/consumer/consumertest" "go.opentelemetry.io/collector/consumer/xconsumer" + "go.opentelemetry.io/collector/internal/componentalias" "go.opentelemetry.io/collector/pipeline" "go.opentelemetry.io/collector/pipeline/xpipeline" ) var ( testType = component.MustNewType("test") - testID = component.MustNewIDWithName("type", "name") + testID = component.MustNewIDWithName(testType.String(), "name") ) func TestNewFactoryNoOptions(t *testing.T) { @@ -53,10 +54,14 @@ func TestNewFactoryWithSameTypes(t *testing.T) { ) assert.Equal(t, testType, factory.Type()) assert.EqualValues(t, &defaultCfg, factory.CreateDefaultConfig()) + wrongID := component.MustNewID("wrong") + wrongIDErrStr := internal.ErrIDMismatch(wrongID, testType).Error() assert.Equal(t, component.StabilityLevelAlpha, factory.ProfilesToProfilesStability()) _, err := factory.CreateProfilesToProfiles(context.Background(), connector.Settings{ID: testID}, &defaultCfg, consumertest.NewNop()) require.NoError(t, err) + _, err = factory.CreateProfilesToProfiles(context.Background(), connector.Settings{ID: wrongID}, &defaultCfg, consumertest.NewNop()) + require.ErrorContains(t, err, wrongIDErrStr) _, err = factory.CreateProfilesToTraces(context.Background(), connector.Settings{ID: testID}, &defaultCfg, consumertest.NewNop()) assert.Equal(t, err, internal.ErrDataTypes(testID, xpipeline.SignalProfiles, pipeline.SignalTraces)) @@ -79,6 +84,8 @@ func TestNewFactoryWithTranslateTypes(t *testing.T) { ) assert.Equal(t, testType, factory.Type()) assert.EqualValues(t, &defaultCfg, factory.CreateDefaultConfig()) + wrongID := component.MustNewID("wrong") + wrongIDErrStr := internal.ErrIDMismatch(wrongID, testType).Error() _, err := factory.CreateProfilesToProfiles(context.Background(), connector.Settings{ID: testID}, &defaultCfg, consumertest.NewNop()) assert.Equal(t, err, internal.ErrDataTypes(testID, xpipeline.SignalProfiles, xpipeline.SignalProfiles)) @@ -86,26 +93,38 @@ func TestNewFactoryWithTranslateTypes(t *testing.T) { assert.Equal(t, component.StabilityLevelBeta, factory.TracesToProfilesStability()) _, err = factory.CreateTracesToProfiles(context.Background(), connector.Settings{ID: testID}, &defaultCfg, consumertest.NewNop()) require.NoError(t, err) + _, err = factory.CreateTracesToProfiles(context.Background(), connector.Settings{ID: wrongID}, &defaultCfg, consumertest.NewNop()) + require.ErrorContains(t, err, wrongIDErrStr) assert.Equal(t, component.StabilityLevelDevelopment, factory.MetricsToProfilesStability()) _, err = factory.CreateMetricsToProfiles(context.Background(), connector.Settings{ID: testID}, &defaultCfg, consumertest.NewNop()) require.NoError(t, err) + _, err = factory.CreateMetricsToProfiles(context.Background(), connector.Settings{ID: wrongID}, &defaultCfg, consumertest.NewNop()) + require.ErrorContains(t, err, wrongIDErrStr) assert.Equal(t, component.StabilityLevelAlpha, factory.LogsToProfilesStability()) _, err = factory.CreateLogsToProfiles(context.Background(), connector.Settings{ID: testID}, &defaultCfg, consumertest.NewNop()) require.NoError(t, err) + _, err = factory.CreateLogsToProfiles(context.Background(), connector.Settings{ID: wrongID}, &defaultCfg, consumertest.NewNop()) + require.ErrorContains(t, err, wrongIDErrStr) assert.Equal(t, component.StabilityLevelBeta, factory.ProfilesToTracesStability()) _, err = factory.CreateProfilesToTraces(context.Background(), connector.Settings{ID: testID}, &defaultCfg, consumertest.NewNop()) require.NoError(t, err) + _, err = factory.CreateProfilesToTraces(context.Background(), connector.Settings{ID: wrongID}, &defaultCfg, consumertest.NewNop()) + require.ErrorContains(t, err, wrongIDErrStr) assert.Equal(t, component.StabilityLevelDevelopment, factory.ProfilesToMetricsStability()) _, err = factory.CreateProfilesToMetrics(context.Background(), connector.Settings{ID: testID}, &defaultCfg, consumertest.NewNop()) require.NoError(t, err) + _, err = factory.CreateProfilesToMetrics(context.Background(), connector.Settings{ID: wrongID}, &defaultCfg, consumertest.NewNop()) + require.ErrorContains(t, err, wrongIDErrStr) assert.Equal(t, component.StabilityLevelAlpha, factory.ProfilesToLogsStability()) _, err = factory.CreateProfilesToLogs(context.Background(), connector.Settings{ID: testID}, &defaultCfg, consumertest.NewNop()) - assert.NoError(t, err) + require.NoError(t, err) + _, err = factory.CreateProfilesToLogs(context.Background(), connector.Settings{ID: wrongID}, &defaultCfg, consumertest.NewNop()) + require.ErrorContains(t, err, wrongIDErrStr) } var nopInstance = &nopConnector{ @@ -146,3 +165,27 @@ func createProfilesToMetrics(context.Context, connector.Settings, component.Conf func createProfilesToLogs(context.Context, connector.Settings, component.Config, consumer.Logs) (Profiles, error) { return nopInstance, nil } + +func TestNewFactoryWithDeprecatedAlias(t *testing.T) { + testType := component.MustNewType("newname") + aliasType := component.MustNewType("oldname") + defaultCfg := struct{}{} + + f := NewFactory( + testType, + func() component.Config { return &defaultCfg }, + WithProfilesToProfiles(createProfilesToProfiles, component.StabilityLevelAlpha), + WithDeprecatedTypeAlias(aliasType), + ) + + assert.Equal(t, testType, f.Type()) + assert.Equal(t, aliasType, f.(*factory).Factory.(componentalias.TypeAliasHolder).DeprecatedAlias()) + assert.EqualValues(t, &defaultCfg, f.CreateDefaultConfig()) + + _, err := f.CreateProfilesToProfiles(context.Background(), connector.Settings{ID: component.MustNewID("newname")}, &defaultCfg, consumertest.NewNop()) + require.NoError(t, err) + _, err = f.CreateProfilesToProfiles(context.Background(), connector.Settings{ID: component.MustNewID("oldname")}, &defaultCfg, consumertest.NewNop()) + require.NoError(t, err) + _, err = f.CreateProfilesToProfiles(context.Background(), connector.Settings{ID: component.MustNewID("wrongname")}, &defaultCfg, consumertest.NewNop()) + require.Error(t, err) +} diff --git a/connector/xconnector/go.mod b/connector/xconnector/go.mod index 5a16510f5bed..d29e623ea6e3 100644 --- a/connector/xconnector/go.mod +++ b/connector/xconnector/go.mod @@ -1,34 +1,35 @@ module go.opentelemetry.io/collector/connector/xconnector -go 1.24.0 +go 1.25.0 require ( github.com/stretchr/testify v1.11.1 - go.opentelemetry.io/collector/component v1.46.0 - go.opentelemetry.io/collector/connector v0.140.0 - go.opentelemetry.io/collector/consumer v1.46.0 - go.opentelemetry.io/collector/consumer/consumertest v0.140.0 - go.opentelemetry.io/collector/consumer/xconsumer v0.140.0 - go.opentelemetry.io/collector/internal/fanoutconsumer v0.140.0 - go.opentelemetry.io/collector/pdata/pprofile v0.140.0 - go.opentelemetry.io/collector/pdata/testdata v0.140.0 - go.opentelemetry.io/collector/pipeline v1.46.0 - go.opentelemetry.io/collector/pipeline/xpipeline v0.140.0 + go.opentelemetry.io/collector/component v1.54.0 + go.opentelemetry.io/collector/connector v0.148.0 + go.opentelemetry.io/collector/consumer v1.54.0 + go.opentelemetry.io/collector/consumer/consumertest v0.148.0 + go.opentelemetry.io/collector/consumer/xconsumer v0.148.0 + go.opentelemetry.io/collector/internal/componentalias v0.148.0 + go.opentelemetry.io/collector/internal/fanoutconsumer v0.148.0 + go.opentelemetry.io/collector/pdata/pprofile v0.148.0 + go.opentelemetry.io/collector/pdata/testdata v0.148.0 + go.opentelemetry.io/collector/pipeline v1.54.0 + go.opentelemetry.io/collector/pipeline/xpipeline v0.148.0 ) require ( github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/davecgh/go-spew v1.1.1 // indirect - github.com/hashicorp/go-version v1.7.0 // indirect + github.com/hashicorp/go-version v1.8.0 // indirect github.com/json-iterator/go v1.1.12 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee // indirect github.com/pmezard/go-difflib v1.0.0 // indirect - go.opentelemetry.io/collector/featuregate v1.46.0 // indirect - go.opentelemetry.io/collector/pdata v1.46.0 // indirect - go.opentelemetry.io/otel v1.40.0 // indirect - go.opentelemetry.io/otel/metric v1.40.0 // indirect - go.opentelemetry.io/otel/trace v1.40.0 // indirect + go.opentelemetry.io/collector/featuregate v1.54.0 // indirect + go.opentelemetry.io/collector/pdata v1.54.0 // indirect + go.opentelemetry.io/otel v1.42.0 // indirect + go.opentelemetry.io/otel/metric v1.42.0 // indirect + go.opentelemetry.io/otel/trace v1.42.0 // indirect go.uber.org/multierr v1.11.0 // indirect go.uber.org/zap v1.27.1 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect @@ -59,3 +60,5 @@ replace go.opentelemetry.io/collector/internal/fanoutconsumer => ../../internal/ replace go.opentelemetry.io/collector/featuregate => ../../featuregate replace go.opentelemetry.io/collector/internal/testutil => ../../internal/testutil + +replace go.opentelemetry.io/collector/internal/componentalias => ../../internal/componentalias diff --git a/connector/xconnector/go.sum b/connector/xconnector/go.sum index 37d6edbc3764..1abfd0c69894 100644 --- a/connector/xconnector/go.sum +++ b/connector/xconnector/go.sum @@ -10,8 +10,8 @@ github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= -github.com/hashicorp/go-version v1.7.0 h1:5tqGy27NaOTB8yJKUZELlFAS/LTKJkrmONwQKeRZfjY= -github.com/hashicorp/go-version v1.7.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= +github.com/hashicorp/go-version v1.8.0 h1:KAkNb1HAiZd1ukkxDFGmokVZe1Xy9HG6NUp+bPle2i4= +github.com/hashicorp/go-version v1.8.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= @@ -34,26 +34,26 @@ github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64= go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y= -go.opentelemetry.io/otel v1.40.0 h1:oA5YeOcpRTXq6NN7frwmwFR0Cn3RhTVZvXsP4duvCms= -go.opentelemetry.io/otel v1.40.0/go.mod h1:IMb+uXZUKkMXdPddhwAHm6UfOwJyh4ct1ybIlV14J0g= -go.opentelemetry.io/otel/metric v1.40.0 h1:rcZe317KPftE2rstWIBitCdVp89A2HqjkxR3c11+p9g= -go.opentelemetry.io/otel/metric v1.40.0/go.mod h1:ib/crwQH7N3r5kfiBZQbwrTge743UDc7DTFVZrrXnqc= -go.opentelemetry.io/otel/trace v1.40.0 h1:WA4etStDttCSYuhwvEa8OP8I5EWu24lkOzp+ZYblVjw= -go.opentelemetry.io/otel/trace v1.40.0/go.mod h1:zeAhriXecNGP/s2SEG3+Y8X9ujcJOTqQ5RgdEJcawiA= -go.opentelemetry.io/proto/slim/otlp v1.9.0 h1:fPVMv8tP3TrsqlkH1HWYUpbCY9cAIemx184VGkS6vlE= -go.opentelemetry.io/proto/slim/otlp v1.9.0/go.mod h1:xXdeJJ90Gqyll+orzUkY4bOd2HECo5JofeoLpymVqdI= -go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.2.0 h1:o13nadWDNkH/quoDomDUClnQBpdQQ2Qqv0lQBjIXjE8= -go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.2.0/go.mod h1:Gyb6Xe7FTi/6xBHwMmngGoHqL0w29Y4eW8TGFzpefGA= -go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.2.0 h1:EiUYvtwu6PMrMHVjcPfnsG3v+ajPkbUeH+IL93+QYyk= -go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.2.0/go.mod h1:mUUHKFiN2SST3AhJ8XhJxEoeVW12oqfXog0Bo8W3Ec4= +go.opentelemetry.io/otel v1.42.0 h1:lSQGzTgVR3+sgJDAU/7/ZMjN9Z+vUip7leaqBKy4sho= +go.opentelemetry.io/otel v1.42.0/go.mod h1:lJNsdRMxCUIWuMlVJWzecSMuNjE7dOYyWlqOXWkdqCc= +go.opentelemetry.io/otel/metric v1.42.0 h1:2jXG+3oZLNXEPfNmnpxKDeZsFI5o4J+nz6xUlaFdF/4= +go.opentelemetry.io/otel/metric v1.42.0/go.mod h1:RlUN/7vTU7Ao/diDkEpQpnz3/92J9ko05BIwxYa2SSI= +go.opentelemetry.io/otel/trace v1.42.0 h1:OUCgIPt+mzOnaUTpOQcBiM/PLQ/Op7oq6g4LenLmOYY= +go.opentelemetry.io/otel/trace v1.42.0/go.mod h1:f3K9S+IFqnumBkKhRJMeaZeNk9epyhnCmQh/EysQCdc= +go.opentelemetry.io/proto/slim/otlp v1.10.0 h1:iR97Vs/ZDR+y9TfuP9b1XBtdPWeC+OMslIBmhcLU7jM= +go.opentelemetry.io/proto/slim/otlp v1.10.0/go.mod h1:lV9250stpjYLPNA5viFabIgP2QlUGRT1GdTgAf8SIUk= +go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.3.0 h1:RUF5rO0hAlgiJt1fzQVzcVs3vZVNHIcMLgOgG4rWNcQ= +go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.3.0/go.mod h1:I89cynRj8y+383o7tEQVg2SVA6SRgDVIouWPUVXjx0U= +go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.3.0 h1:CQvJSldHRUN6Z8jsUeYv8J0lXRvygALXIzsmAeCcZE0= +go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.3.0/go.mod h1:xSQ+mEfJe/GjK1LXEyVOoSI1N9JV9ZI923X5kup43W4= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= go.uber.org/zap v1.27.1 h1:08RqriUEv8+ArZRYSTXy1LeBScaMpVSTBhCeaZYfMYc= go.uber.org/zap v1.27.1/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= -google.golang.org/protobuf v1.36.10 h1:AYd7cD/uASjIL6Q9LiTjz8JLcrh/88q5UObnmY3aOOE= -google.golang.org/protobuf v1.36.10/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= +google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE= +google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= diff --git a/consumer/consumererror/go.mod b/consumer/consumererror/go.mod index 94bb848012e4..860b259c0801 100644 --- a/consumer/consumererror/go.mod +++ b/consumer/consumererror/go.mod @@ -1,29 +1,29 @@ module go.opentelemetry.io/collector/consumer/consumererror -go 1.24.0 +go 1.25.0 require ( github.com/stretchr/testify v1.11.1 - go.opentelemetry.io/collector/pdata v1.46.0 - go.opentelemetry.io/collector/pdata/pprofile v0.140.0 - go.opentelemetry.io/collector/pdata/testdata v0.140.0 + go.opentelemetry.io/collector/pdata v1.54.0 + go.opentelemetry.io/collector/pdata/pprofile v0.148.0 + go.opentelemetry.io/collector/pdata/testdata v0.148.0 go.uber.org/goleak v1.3.0 - google.golang.org/grpc v1.77.0 + google.golang.org/grpc v1.79.3 ) require ( github.com/davecgh/go-spew v1.1.1 // indirect - github.com/hashicorp/go-version v1.7.0 // indirect + github.com/hashicorp/go-version v1.8.0 // indirect github.com/json-iterator/go v1.1.12 // indirect github.com/kr/text v0.2.0 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee // indirect github.com/pmezard/go-difflib v1.0.0 // indirect - go.opentelemetry.io/collector/featuregate v1.46.0 // indirect + go.opentelemetry.io/collector/featuregate v1.54.0 // indirect go.uber.org/multierr v1.11.0 // indirect - golang.org/x/sys v0.37.0 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20251022142026-3a174f9686a8 // indirect - google.golang.org/protobuf v1.36.10 // indirect + golang.org/x/sys v0.41.0 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20251222181119-0a764e51fe1b // indirect + google.golang.org/protobuf v1.36.11 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/consumer/consumererror/go.sum b/consumer/consumererror/go.sum index fc129b09419e..a3b545cb1583 100644 --- a/consumer/consumererror/go.sum +++ b/consumer/consumererror/go.sum @@ -1,3 +1,5 @@ +github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= +github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= @@ -7,8 +9,8 @@ github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6 github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= -github.com/hashicorp/go-version v1.7.0 h1:5tqGy27NaOTB8yJKUZELlFAS/LTKJkrmONwQKeRZfjY= -github.com/hashicorp/go-version v1.7.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= +github.com/hashicorp/go-version v1.8.0 h1:KAkNb1HAiZd1ukkxDFGmokVZe1Xy9HG6NUp+bPle2i4= +github.com/hashicorp/go-version v1.8.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= @@ -29,28 +31,30 @@ github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+ github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U= github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= -go.opentelemetry.io/proto/slim/otlp v1.9.0 h1:fPVMv8tP3TrsqlkH1HWYUpbCY9cAIemx184VGkS6vlE= -go.opentelemetry.io/proto/slim/otlp v1.9.0/go.mod h1:xXdeJJ90Gqyll+orzUkY4bOd2HECo5JofeoLpymVqdI= -go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.2.0 h1:o13nadWDNkH/quoDomDUClnQBpdQQ2Qqv0lQBjIXjE8= -go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.2.0/go.mod h1:Gyb6Xe7FTi/6xBHwMmngGoHqL0w29Y4eW8TGFzpefGA= -go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.2.0 h1:EiUYvtwu6PMrMHVjcPfnsG3v+ajPkbUeH+IL93+QYyk= -go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.2.0/go.mod h1:mUUHKFiN2SST3AhJ8XhJxEoeVW12oqfXog0Bo8W3Ec4= +go.opentelemetry.io/otel v1.40.0 h1:oA5YeOcpRTXq6NN7frwmwFR0Cn3RhTVZvXsP4duvCms= +go.opentelemetry.io/otel v1.40.0/go.mod h1:IMb+uXZUKkMXdPddhwAHm6UfOwJyh4ct1ybIlV14J0g= +go.opentelemetry.io/proto/slim/otlp v1.10.0 h1:iR97Vs/ZDR+y9TfuP9b1XBtdPWeC+OMslIBmhcLU7jM= +go.opentelemetry.io/proto/slim/otlp v1.10.0/go.mod h1:lV9250stpjYLPNA5viFabIgP2QlUGRT1GdTgAf8SIUk= +go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.3.0 h1:RUF5rO0hAlgiJt1fzQVzcVs3vZVNHIcMLgOgG4rWNcQ= +go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.3.0/go.mod h1:I89cynRj8y+383o7tEQVg2SVA6SRgDVIouWPUVXjx0U= +go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.3.0 h1:CQvJSldHRUN6Z8jsUeYv8J0lXRvygALXIzsmAeCcZE0= +go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.3.0/go.mod h1:xSQ+mEfJe/GjK1LXEyVOoSI1N9JV9ZI923X5kup43W4= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= -golang.org/x/net v0.46.1-0.20251013234738-63d1a5100f82 h1:6/3JGEh1C88g7m+qzzTbl3A0FtsLguXieqofVLU/JAo= -golang.org/x/net v0.46.1-0.20251013234738-63d1a5100f82/go.mod h1:Q9BGdFy1y4nkUwiLvT5qtyhAnEHgnQ/zd8PfU6nc210= -golang.org/x/sys v0.37.0 h1:fdNQudmxPjkdUTPnLn5mdQv7Zwvbvpaxqs831goi9kQ= -golang.org/x/sys v0.37.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= -golang.org/x/text v0.30.0 h1:yznKA/E9zq54KzlzBEAWn1NXSQ8DIp/NYMy88xJjl4k= -golang.org/x/text v0.30.0/go.mod h1:yDdHFIX9t+tORqspjENWgzaCVXgk0yYnYuSZ8UzzBVM= -google.golang.org/genproto/googleapis/rpc v0.0.0-20251022142026-3a174f9686a8 h1:M1rk8KBnUsBDg1oPGHNCxG4vc1f49epmTO7xscSajMk= -google.golang.org/genproto/googleapis/rpc v0.0.0-20251022142026-3a174f9686a8/go.mod h1:7i2o+ce6H/6BluujYR+kqX3GKH+dChPTQU19wjRPiGk= -google.golang.org/grpc v1.77.0 h1:wVVY6/8cGA6vvffn+wWK5ToddbgdU3d8MNENr4evgXM= -google.golang.org/grpc v1.77.0/go.mod h1:z0BY1iVj0q8E1uSQCjL9cppRj+gnZjzDnzV0dHhrNig= -google.golang.org/protobuf v1.36.10 h1:AYd7cD/uASjIL6Q9LiTjz8JLcrh/88q5UObnmY3aOOE= -google.golang.org/protobuf v1.36.10/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= +golang.org/x/net v0.51.0 h1:94R/GTO7mt3/4wIKpcR5gkGmRLOuE/2hNGeWq/GBIFo= +golang.org/x/net v0.51.0/go.mod h1:aamm+2QF5ogm02fjy5Bb7CQ0WMt1/WVM7FtyaTLlA9Y= +golang.org/x/sys v0.41.0 h1:Ivj+2Cp/ylzLiEU89QhWblYnOE9zerudt9Ftecq2C6k= +golang.org/x/sys v0.41.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= +golang.org/x/text v0.34.0 h1:oL/Qq0Kdaqxa1KbNeMKwQq0reLCCaFtqu2eNuSeNHbk= +golang.org/x/text v0.34.0/go.mod h1:homfLqTYRFyVYemLBFl5GgL/DWEiH5wcsQ5gSh1yziA= +google.golang.org/genproto/googleapis/rpc v0.0.0-20251222181119-0a764e51fe1b h1:Mv8VFug0MP9e5vUxfBcE3vUkV6CImK3cMNMIDFjmzxU= +google.golang.org/genproto/googleapis/rpc v0.0.0-20251222181119-0a764e51fe1b/go.mod h1:j9x/tPzZkyxcgEFkiKEEGxfvyumM01BEtsW8xzOahRQ= +google.golang.org/grpc v1.79.3 h1:sybAEdRIEtvcD68Gx7dmnwjZKlyfuc61Dyo9pGXXkKE= +google.golang.org/grpc v1.79.3/go.mod h1:KmT0Kjez+0dde/v2j9vzwoAScgEPx/Bw1CYChhHLrHQ= +google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE= +google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= diff --git a/consumer/consumererror/metadata.yaml b/consumer/consumererror/metadata.yaml new file mode 100644 index 000000000000..892da5f29b65 --- /dev/null +++ b/consumer/consumererror/metadata.yaml @@ -0,0 +1,6 @@ +type: consumer/consumererror +github_project: open-telemetry/opentelemetry-collector + +status: + disable_codecov_badge: true + class: pkg diff --git a/consumer/consumererror/xconsumererror/go.mod b/consumer/consumererror/xconsumererror/go.mod index e464a4ee553e..b5174c55af44 100644 --- a/consumer/consumererror/xconsumererror/go.mod +++ b/consumer/consumererror/xconsumererror/go.mod @@ -1,23 +1,23 @@ module go.opentelemetry.io/collector/consumer/consumererror/xconsumererror -go 1.24.0 +go 1.25.0 require ( github.com/stretchr/testify v1.11.1 - go.opentelemetry.io/collector/consumer/consumererror v0.140.0 - go.opentelemetry.io/collector/pdata/pprofile v0.140.0 - go.opentelemetry.io/collector/pdata/testdata v0.140.0 + go.opentelemetry.io/collector/consumer/consumererror v0.148.0 + go.opentelemetry.io/collector/pdata/pprofile v0.148.0 + go.opentelemetry.io/collector/pdata/testdata v0.148.0 ) require ( github.com/davecgh/go-spew v1.1.1 // indirect - github.com/hashicorp/go-version v1.7.0 // indirect + github.com/hashicorp/go-version v1.8.0 // indirect github.com/json-iterator/go v1.1.12 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee // indirect github.com/pmezard/go-difflib v1.0.0 // indirect - go.opentelemetry.io/collector/featuregate v1.46.0 // indirect - go.opentelemetry.io/collector/pdata v1.46.0 // indirect + go.opentelemetry.io/collector/featuregate v1.54.0 // indirect + go.opentelemetry.io/collector/pdata v1.54.0 // indirect go.uber.org/multierr v1.11.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/consumer/consumererror/xconsumererror/go.sum b/consumer/consumererror/xconsumererror/go.sum index 903bf673575c..a38defe5d44d 100644 --- a/consumer/consumererror/xconsumererror/go.sum +++ b/consumer/consumererror/xconsumererror/go.sum @@ -1,9 +1,11 @@ +github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= +github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= -github.com/hashicorp/go-version v1.7.0 h1:5tqGy27NaOTB8yJKUZELlFAS/LTKJkrmONwQKeRZfjY= -github.com/hashicorp/go-version v1.7.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= +github.com/hashicorp/go-version v1.8.0 h1:KAkNb1HAiZd1ukkxDFGmokVZe1Xy9HG6NUp+bPle2i4= +github.com/hashicorp/go-version v1.8.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= @@ -24,18 +26,20 @@ github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+ github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U= github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= -go.opentelemetry.io/proto/slim/otlp v1.9.0 h1:fPVMv8tP3TrsqlkH1HWYUpbCY9cAIemx184VGkS6vlE= -go.opentelemetry.io/proto/slim/otlp v1.9.0/go.mod h1:xXdeJJ90Gqyll+orzUkY4bOd2HECo5JofeoLpymVqdI= -go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.2.0 h1:o13nadWDNkH/quoDomDUClnQBpdQQ2Qqv0lQBjIXjE8= -go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.2.0/go.mod h1:Gyb6Xe7FTi/6xBHwMmngGoHqL0w29Y4eW8TGFzpefGA= -go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.2.0 h1:EiUYvtwu6PMrMHVjcPfnsG3v+ajPkbUeH+IL93+QYyk= -go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.2.0/go.mod h1:mUUHKFiN2SST3AhJ8XhJxEoeVW12oqfXog0Bo8W3Ec4= +go.opentelemetry.io/otel v1.40.0 h1:oA5YeOcpRTXq6NN7frwmwFR0Cn3RhTVZvXsP4duvCms= +go.opentelemetry.io/otel v1.40.0/go.mod h1:IMb+uXZUKkMXdPddhwAHm6UfOwJyh4ct1ybIlV14J0g= +go.opentelemetry.io/proto/slim/otlp v1.10.0 h1:iR97Vs/ZDR+y9TfuP9b1XBtdPWeC+OMslIBmhcLU7jM= +go.opentelemetry.io/proto/slim/otlp v1.10.0/go.mod h1:lV9250stpjYLPNA5viFabIgP2QlUGRT1GdTgAf8SIUk= +go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.3.0 h1:RUF5rO0hAlgiJt1fzQVzcVs3vZVNHIcMLgOgG4rWNcQ= +go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.3.0/go.mod h1:I89cynRj8y+383o7tEQVg2SVA6SRgDVIouWPUVXjx0U= +go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.3.0 h1:CQvJSldHRUN6Z8jsUeYv8J0lXRvygALXIzsmAeCcZE0= +go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.3.0/go.mod h1:xSQ+mEfJe/GjK1LXEyVOoSI1N9JV9ZI923X5kup43W4= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= -google.golang.org/protobuf v1.36.10 h1:AYd7cD/uASjIL6Q9LiTjz8JLcrh/88q5UObnmY3aOOE= -google.golang.org/protobuf v1.36.10/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= +google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE= +google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= diff --git a/consumer/consumererror/xconsumererror/metadata.yaml b/consumer/consumererror/xconsumererror/metadata.yaml new file mode 100644 index 000000000000..cd0eba7e1071 --- /dev/null +++ b/consumer/consumererror/xconsumererror/metadata.yaml @@ -0,0 +1,8 @@ +type: consumererror/xconsumererror +github_project: open-telemetry/opentelemetry-collector + +status: + disable_codecov_badge: true + class: consumer + stability: + development: [profiles] diff --git a/consumer/consumertest/go.mod b/consumer/consumertest/go.mod index d321ae6d8f6f..2c5986c35a3d 100644 --- a/consumer/consumertest/go.mod +++ b/consumer/consumertest/go.mod @@ -1,27 +1,27 @@ module go.opentelemetry.io/collector/consumer/consumertest -go 1.24.0 +go 1.25.0 replace go.opentelemetry.io/collector/consumer => ../ require ( github.com/stretchr/testify v1.11.1 - go.opentelemetry.io/collector/consumer v1.46.0 - go.opentelemetry.io/collector/consumer/xconsumer v0.140.0 - go.opentelemetry.io/collector/pdata v1.46.0 - go.opentelemetry.io/collector/pdata/pprofile v0.140.0 - go.opentelemetry.io/collector/pdata/testdata v0.140.0 + go.opentelemetry.io/collector/consumer v1.54.0 + go.opentelemetry.io/collector/consumer/xconsumer v0.148.0 + go.opentelemetry.io/collector/pdata v1.54.0 + go.opentelemetry.io/collector/pdata/pprofile v0.148.0 + go.opentelemetry.io/collector/pdata/testdata v0.148.0 go.uber.org/goleak v1.3.0 ) require ( github.com/davecgh/go-spew v1.1.1 // indirect - github.com/hashicorp/go-version v1.7.0 // indirect + github.com/hashicorp/go-version v1.8.0 // indirect github.com/json-iterator/go v1.1.12 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee // indirect github.com/pmezard/go-difflib v1.0.0 // indirect - go.opentelemetry.io/collector/featuregate v1.46.0 // indirect + go.opentelemetry.io/collector/featuregate v1.54.0 // indirect go.uber.org/multierr v1.11.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/consumer/consumertest/go.sum b/consumer/consumertest/go.sum index 903bf673575c..a38defe5d44d 100644 --- a/consumer/consumertest/go.sum +++ b/consumer/consumertest/go.sum @@ -1,9 +1,11 @@ +github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= +github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= -github.com/hashicorp/go-version v1.7.0 h1:5tqGy27NaOTB8yJKUZELlFAS/LTKJkrmONwQKeRZfjY= -github.com/hashicorp/go-version v1.7.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= +github.com/hashicorp/go-version v1.8.0 h1:KAkNb1HAiZd1ukkxDFGmokVZe1Xy9HG6NUp+bPle2i4= +github.com/hashicorp/go-version v1.8.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= @@ -24,18 +26,20 @@ github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+ github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U= github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= -go.opentelemetry.io/proto/slim/otlp v1.9.0 h1:fPVMv8tP3TrsqlkH1HWYUpbCY9cAIemx184VGkS6vlE= -go.opentelemetry.io/proto/slim/otlp v1.9.0/go.mod h1:xXdeJJ90Gqyll+orzUkY4bOd2HECo5JofeoLpymVqdI= -go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.2.0 h1:o13nadWDNkH/quoDomDUClnQBpdQQ2Qqv0lQBjIXjE8= -go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.2.0/go.mod h1:Gyb6Xe7FTi/6xBHwMmngGoHqL0w29Y4eW8TGFzpefGA= -go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.2.0 h1:EiUYvtwu6PMrMHVjcPfnsG3v+ajPkbUeH+IL93+QYyk= -go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.2.0/go.mod h1:mUUHKFiN2SST3AhJ8XhJxEoeVW12oqfXog0Bo8W3Ec4= +go.opentelemetry.io/otel v1.40.0 h1:oA5YeOcpRTXq6NN7frwmwFR0Cn3RhTVZvXsP4duvCms= +go.opentelemetry.io/otel v1.40.0/go.mod h1:IMb+uXZUKkMXdPddhwAHm6UfOwJyh4ct1ybIlV14J0g= +go.opentelemetry.io/proto/slim/otlp v1.10.0 h1:iR97Vs/ZDR+y9TfuP9b1XBtdPWeC+OMslIBmhcLU7jM= +go.opentelemetry.io/proto/slim/otlp v1.10.0/go.mod h1:lV9250stpjYLPNA5viFabIgP2QlUGRT1GdTgAf8SIUk= +go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.3.0 h1:RUF5rO0hAlgiJt1fzQVzcVs3vZVNHIcMLgOgG4rWNcQ= +go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.3.0/go.mod h1:I89cynRj8y+383o7tEQVg2SVA6SRgDVIouWPUVXjx0U= +go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.3.0 h1:CQvJSldHRUN6Z8jsUeYv8J0lXRvygALXIzsmAeCcZE0= +go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.3.0/go.mod h1:xSQ+mEfJe/GjK1LXEyVOoSI1N9JV9ZI923X5kup43W4= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= -google.golang.org/protobuf v1.36.10 h1:AYd7cD/uASjIL6Q9LiTjz8JLcrh/88q5UObnmY3aOOE= -google.golang.org/protobuf v1.36.10/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= +google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE= +google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= diff --git a/consumer/consumertest/metadata.yaml b/consumer/consumertest/metadata.yaml new file mode 100644 index 000000000000..944bc160ffac --- /dev/null +++ b/consumer/consumertest/metadata.yaml @@ -0,0 +1,6 @@ +type: consumer/consumertest +github_project: open-telemetry/opentelemetry-collector + +status: + disable_codecov_badge: true + class: pkg diff --git a/consumer/consumertest/sink.go b/consumer/consumertest/sink.go index ec5cca1efb5c..3c83ee016144 100644 --- a/consumer/consumertest/sink.go +++ b/consumer/consumertest/sink.go @@ -201,10 +201,11 @@ func (sle *LogsSink) Contexts() []context.Context { // stores all profiles and allows querying them for testing. type ProfilesSink struct { nonMutatingConsumer - mu sync.Mutex - profiles []pprofile.Profiles - contexts []context.Context - sampleCount int + mu sync.Mutex + profiles []pprofile.Profiles + contexts []context.Context + sampleCount int + profileCount int } var _ xconsumer.Profiles = (*ProfilesSink)(nil) @@ -217,6 +218,7 @@ func (ste *ProfilesSink) ConsumeProfiles(ctx context.Context, td pprofile.Profil ste.profiles = append(ste.profiles, td) ste.contexts = append(ste.contexts, ctx) ste.sampleCount += td.SampleCount() + ste.profileCount += td.ProfileCount() return nil } @@ -231,13 +233,20 @@ func (ste *ProfilesSink) AllProfiles() []pprofile.Profiles { return copyProfiles } -// SampleCount returns the number of profiles stored by this sink since last Reset. +// SampleCount returns the number of samples stored by this sink since last Reset. func (ste *ProfilesSink) SampleCount() int { ste.mu.Lock() defer ste.mu.Unlock() return ste.sampleCount } +// ProfileCount returns the number of profiles stored by this sink since last Reset. +func (ste *ProfilesSink) ProfileCount() int { + ste.mu.Lock() + defer ste.mu.Unlock() + return ste.profileCount +} + // Reset deletes any stored data. func (ste *ProfilesSink) Reset() { ste.mu.Lock() @@ -246,6 +255,7 @@ func (ste *ProfilesSink) Reset() { ste.profiles = nil ste.contexts = nil ste.sampleCount = 0 + ste.profileCount = 0 } // Contexts returns the contexts stored by this sink since last Reset. diff --git a/consumer/consumertest/sink_test.go b/consumer/consumertest/sink_test.go index 035d917b1532..7df47c215999 100644 --- a/consumer/consumertest/sink_test.go +++ b/consumer/consumertest/sink_test.go @@ -78,10 +78,14 @@ func TestProfilesSink(t *testing.T) { want = append(want, td) } assert.Equal(t, want, sink.AllProfiles()) + // Each Profile in Profiles holds a single sample. + // So SampleCount() equals ProfileCount() in this case. assert.Equal(t, len(want), sink.SampleCount()) + assert.Equal(t, len(want), sink.ProfileCount()) sink.Reset() assert.Empty(t, sink.AllProfiles()) - assert.Empty(t, sink.SampleCount()) + assert.Equal(t, 0, sink.SampleCount()) + assert.Equal(t, 0, sink.ProfileCount()) } func TestTracesSinkWithContext(t *testing.T) { diff --git a/consumer/go.mod b/consumer/go.mod index ff41c3e29134..304b3decd5d4 100644 --- a/consumer/go.mod +++ b/consumer/go.mod @@ -1,22 +1,22 @@ module go.opentelemetry.io/collector/consumer -go 1.24.0 +go 1.25.0 require ( github.com/stretchr/testify v1.11.1 - go.opentelemetry.io/collector/pdata v1.46.0 + go.opentelemetry.io/collector/pdata v1.54.0 go.uber.org/goleak v1.3.0 ) require ( github.com/davecgh/go-spew v1.1.1 // indirect - github.com/hashicorp/go-version v1.7.0 // indirect + github.com/hashicorp/go-version v1.8.0 // indirect github.com/json-iterator/go v1.1.12 // indirect github.com/kr/text v0.2.0 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee // indirect github.com/pmezard/go-difflib v1.0.0 // indirect - go.opentelemetry.io/collector/featuregate v1.46.0 // indirect + go.opentelemetry.io/collector/featuregate v1.54.0 // indirect go.uber.org/multierr v1.11.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/consumer/go.sum b/consumer/go.sum index 773c58016f4e..bad900103d1c 100644 --- a/consumer/go.sum +++ b/consumer/go.sum @@ -3,8 +3,8 @@ github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= -github.com/hashicorp/go-version v1.7.0 h1:5tqGy27NaOTB8yJKUZELlFAS/LTKJkrmONwQKeRZfjY= -github.com/hashicorp/go-version v1.7.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= +github.com/hashicorp/go-version v1.8.0 h1:KAkNb1HAiZd1ukkxDFGmokVZe1Xy9HG6NUp+bPle2i4= +github.com/hashicorp/go-version v1.8.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= @@ -25,18 +25,18 @@ github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+ github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U= github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= -go.opentelemetry.io/proto/slim/otlp v1.9.0 h1:fPVMv8tP3TrsqlkH1HWYUpbCY9cAIemx184VGkS6vlE= -go.opentelemetry.io/proto/slim/otlp v1.9.0/go.mod h1:xXdeJJ90Gqyll+orzUkY4bOd2HECo5JofeoLpymVqdI= -go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.2.0 h1:o13nadWDNkH/quoDomDUClnQBpdQQ2Qqv0lQBjIXjE8= -go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.2.0/go.mod h1:Gyb6Xe7FTi/6xBHwMmngGoHqL0w29Y4eW8TGFzpefGA= -go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.2.0 h1:EiUYvtwu6PMrMHVjcPfnsG3v+ajPkbUeH+IL93+QYyk= -go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.2.0/go.mod h1:mUUHKFiN2SST3AhJ8XhJxEoeVW12oqfXog0Bo8W3Ec4= +go.opentelemetry.io/proto/slim/otlp v1.10.0 h1:iR97Vs/ZDR+y9TfuP9b1XBtdPWeC+OMslIBmhcLU7jM= +go.opentelemetry.io/proto/slim/otlp v1.10.0/go.mod h1:lV9250stpjYLPNA5viFabIgP2QlUGRT1GdTgAf8SIUk= +go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.3.0 h1:RUF5rO0hAlgiJt1fzQVzcVs3vZVNHIcMLgOgG4rWNcQ= +go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.3.0/go.mod h1:I89cynRj8y+383o7tEQVg2SVA6SRgDVIouWPUVXjx0U= +go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.3.0 h1:CQvJSldHRUN6Z8jsUeYv8J0lXRvygALXIzsmAeCcZE0= +go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.3.0/go.mod h1:xSQ+mEfJe/GjK1LXEyVOoSI1N9JV9ZI923X5kup43W4= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= -google.golang.org/protobuf v1.36.10 h1:AYd7cD/uASjIL6Q9LiTjz8JLcrh/88q5UObnmY3aOOE= -google.golang.org/protobuf v1.36.10/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= +google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE= +google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= diff --git a/consumer/metadata.yaml b/consumer/metadata.yaml new file mode 100644 index 000000000000..5fae4126d5d5 --- /dev/null +++ b/consumer/metadata.yaml @@ -0,0 +1,6 @@ +type: consumer +github_project: open-telemetry/opentelemetry-collector + +status: + disable_codecov_badge: true + class: pkg diff --git a/consumer/xconsumer/go.mod b/consumer/xconsumer/go.mod index b56288c964a4..ae6269af233f 100644 --- a/consumer/xconsumer/go.mod +++ b/consumer/xconsumer/go.mod @@ -1,22 +1,22 @@ module go.opentelemetry.io/collector/consumer/xconsumer -go 1.24.0 +go 1.25.0 require ( github.com/stretchr/testify v1.11.1 - go.opentelemetry.io/collector/consumer v1.46.0 - go.opentelemetry.io/collector/pdata/pprofile v0.140.0 + go.opentelemetry.io/collector/consumer v1.54.0 + go.opentelemetry.io/collector/pdata/pprofile v0.148.0 ) require ( github.com/davecgh/go-spew v1.1.1 // indirect - github.com/hashicorp/go-version v1.7.0 // indirect + github.com/hashicorp/go-version v1.8.0 // indirect github.com/json-iterator/go v1.1.12 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee // indirect github.com/pmezard/go-difflib v1.0.0 // indirect - go.opentelemetry.io/collector/featuregate v1.46.0 // indirect - go.opentelemetry.io/collector/pdata v1.46.0 // indirect + go.opentelemetry.io/collector/featuregate v1.54.0 // indirect + go.opentelemetry.io/collector/pdata v1.54.0 // indirect go.uber.org/multierr v1.11.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/consumer/xconsumer/go.sum b/consumer/xconsumer/go.sum index 903bf673575c..a38defe5d44d 100644 --- a/consumer/xconsumer/go.sum +++ b/consumer/xconsumer/go.sum @@ -1,9 +1,11 @@ +github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= +github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= -github.com/hashicorp/go-version v1.7.0 h1:5tqGy27NaOTB8yJKUZELlFAS/LTKJkrmONwQKeRZfjY= -github.com/hashicorp/go-version v1.7.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= +github.com/hashicorp/go-version v1.8.0 h1:KAkNb1HAiZd1ukkxDFGmokVZe1Xy9HG6NUp+bPle2i4= +github.com/hashicorp/go-version v1.8.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= @@ -24,18 +26,20 @@ github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+ github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U= github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= -go.opentelemetry.io/proto/slim/otlp v1.9.0 h1:fPVMv8tP3TrsqlkH1HWYUpbCY9cAIemx184VGkS6vlE= -go.opentelemetry.io/proto/slim/otlp v1.9.0/go.mod h1:xXdeJJ90Gqyll+orzUkY4bOd2HECo5JofeoLpymVqdI= -go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.2.0 h1:o13nadWDNkH/quoDomDUClnQBpdQQ2Qqv0lQBjIXjE8= -go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.2.0/go.mod h1:Gyb6Xe7FTi/6xBHwMmngGoHqL0w29Y4eW8TGFzpefGA= -go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.2.0 h1:EiUYvtwu6PMrMHVjcPfnsG3v+ajPkbUeH+IL93+QYyk= -go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.2.0/go.mod h1:mUUHKFiN2SST3AhJ8XhJxEoeVW12oqfXog0Bo8W3Ec4= +go.opentelemetry.io/otel v1.40.0 h1:oA5YeOcpRTXq6NN7frwmwFR0Cn3RhTVZvXsP4duvCms= +go.opentelemetry.io/otel v1.40.0/go.mod h1:IMb+uXZUKkMXdPddhwAHm6UfOwJyh4ct1ybIlV14J0g= +go.opentelemetry.io/proto/slim/otlp v1.10.0 h1:iR97Vs/ZDR+y9TfuP9b1XBtdPWeC+OMslIBmhcLU7jM= +go.opentelemetry.io/proto/slim/otlp v1.10.0/go.mod h1:lV9250stpjYLPNA5viFabIgP2QlUGRT1GdTgAf8SIUk= +go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.3.0 h1:RUF5rO0hAlgiJt1fzQVzcVs3vZVNHIcMLgOgG4rWNcQ= +go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.3.0/go.mod h1:I89cynRj8y+383o7tEQVg2SVA6SRgDVIouWPUVXjx0U= +go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.3.0 h1:CQvJSldHRUN6Z8jsUeYv8J0lXRvygALXIzsmAeCcZE0= +go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.3.0/go.mod h1:xSQ+mEfJe/GjK1LXEyVOoSI1N9JV9ZI923X5kup43W4= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= -google.golang.org/protobuf v1.36.10 h1:AYd7cD/uASjIL6Q9LiTjz8JLcrh/88q5UObnmY3aOOE= -google.golang.org/protobuf v1.36.10/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= +google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE= +google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= diff --git a/docs/coding-guidelines.md b/docs/coding-guidelines.md index 7252f15ae6f4..aab9eadc1952 100644 --- a/docs/coding-guidelines.md +++ b/docs/coding-guidelines.md @@ -9,6 +9,29 @@ interaction with a human (such as this Collector). ## Naming convention +### Component naming + +Components (receivers, processors, exporters, extensions, and connectors) MUST use `lower_snake_case` naming convention. This ensures consistency and enhances readability for end users. + +This naming convention applies to the component identifier used in configuration files and component registration, not to Go package names which follow standard Go naming conventions (lowercase, no underscores). + +Examples of correct component names: +- `memory_limiter` (not `memorylimiter`) +- `otlp_http` (not `otlphttp`) + +For example, a component with identifier `memory_limiter` would typically have a Go package name like `memorylimiterprocessor`. + +#### Migration for existing components + +Components that currently use a different naming convention: +- SHOULD add the `lower_snake_case` name as the primary identifier +- MAY support the old name as a deprecated alias for backwards compatibility +- MUST document the migration path in their README + +Only components following the `lower_snake_case` naming convention should be marked as stable. + +### Go API naming conventions + To keep naming patterns consistent across the project, naming patterns are enforced to make intent clear by: - Methods that return a variable that uses the zero value or values provided via the method MUST have the prefix `New`. For example: @@ -38,7 +61,7 @@ To keep naming patterns consistent across the project, naming patterns are enfor - `func CreateTracesExport(...) {...}` - `func CreateTracesToTracesFunc(...) {...}` -### Configuration structs +#### Configuration structs When naming configuration structs, use the following guidelines: @@ -47,6 +70,51 @@ When naming configuration structs, use the following guidelines: - Use the `Settings` suffix for configuration structs that are set by developers in the code. For example, `component.TelemetrySettings` ends in `Settings` since it is set by developers in the code. - Avoid redundant prefixes that are already implied by the package name. For example, use`configgrpc.ClientConfig` instead of `configgrpc.GRPCClientConfig`. +#### Avoid Embedded Structs + +When defining configuration structs, avoid using embedded (anonymous) struct fields. Instead, use explicitly named fields. + +**Rationale:** + +1. **Unmarshal Compatibility**: Embedded structs can break custom `Unmarshal` implementations. If an embedded struct requires special unmarshaling logic, it may not function correctly when embedded. + +2. **Naming Conflicts**: Embedded structs can cause field name collisions. Even if the YAML configuration nests them properly (e.g., under `sending_queue`), having identical field names in embedded structs creates ambiguity in the Go code. + +3. **Clarity**: Named fields make the configuration structure more explicit and easier to understand. + +**Example:** + +```go +// ❌ BAD: Using embedded structs +type ExporterConfig struct { + exporterhelper.TimeoutConfig // embedded + exporterhelper.QueueConfig // embedded + exporterhelper.RetryConfig // embedded +} + +// ✅ GOOD: Using named fields +type ExporterConfig struct { + Timeout exporterhelper.TimeoutConfig `mapstructure:"timeout"` + Queue exporterhelper.QueueConfig `mapstructure:"sending_queue"` + Retry exporterhelper.RetryConfig `mapstructure:"retry_on_failure"` +} +``` + +This practice ensures better maintainability and prevents subtle bugs related to struct composition and configuration unmarshaling. + +**Preserving Flat YAML Structure with the `squash` Tag:** + +In some cases, you may need to maintain backward compatibility with an existing flat YAML configuration structure while still using named fields in Go. The `mapstructure:",squash"` tag achieves this by flattening the nested struct's fields into the parent configuration: + +```go +// Using named fields with squash tag for flat YAML structure +type Config struct { + ClientConfig confighttp.ClientConfig `mapstructure:",squash"` +} +``` + +This allows the YAML configuration to remain flat (fields at the top level) while the Go code uses a named field. However, prefer explicitly nested configurations (without `squash`) for new components, as the nested structure is clearer and avoids the issues mentioned above. + ## Module organization As usual in Go projects, organize your code into packages grouping related functionality. To ensure @@ -353,6 +421,40 @@ SemConv approvers. At their discretion, the code owners may choose to block the component’s implementation PR until the related Semantic Conventions changes are completed. +## Telemetry Stability Levels + +### Metrics + +Metrics emitted by Collector scrapers/receivers (e.g. `system.cpu.time`) follow the same stability levels +as the Collector's internal metrics (e.g. `otelcol_process_cpu_seconds`), as documented in +[Internal Telemetry Stability](https://opentelemetry.io/docs/collector/internal-telemetry/#metrics). + +In particular, for beta and stable levels the following guidelines apply: + +#### Beta stability level + +It is highly encouraged that metrics in beta stage +are also defined as Semantic Conventions based on the [Semantic Conventions compatibility](#semantic-conventions-compatibility), +ensuring cross-project consistency. + +#### Stable stability level + +Before promoting a metric to stable, it should be discussed whether it needs to +be defined as a Semantic Convention, following the [Semantic Conventions compatibility](#semantic-conventions-compatibility). +Promoting a metric to stable without it being a Semantic Convention involves +the risk of potential divergence within OpenTelemetry's projects. +For example, a stable metric in the Collector might be introduced in a slightly +different way in another OpenTelemetry project in the future, or it might be proposed +as a Semantic Convention in the future. +In case of such divergence, a stable Collector metric won't be allowed to +change, and if wider alignment is needed, the metric should be deprecated and +removed in order to come into alignment with the Semantic Conventions. +Consequently, the Collector's maintainers and components' code owners should +acknowledge that risk before marking a metric as stable without it being a +stable Semantic Convention and should provide justification for the decision. In +any case, [Semantic Conventions' guidelines](https://opentelemetry.io/docs/specs/semconv/how-to-write-conventions/) +should be advised when metrics are defined within the Collector directly. + ### Testing Library Recommendations To keep testing practices consistent across the project, it is advised to use these libraries under @@ -412,6 +514,10 @@ package test func DoFoo() {} ``` +If applicable, add the [`//go:fix inline` +directive](https://pkg.go.dev/golang.org/x/tools/go/analysis/passes/inline#hdr-Analyzer_inline) on +the deprecated function to help with the migration. + #### Example #1 - Renaming a function 1. Current version `v0.N` has `func GetFoo() Bar` diff --git a/docs/platform-support.md b/docs/platform-support.md index d9e690bc1abb..66b978cd6df0 100644 --- a/docs/platform-support.md +++ b/docs/platform-support.md @@ -8,16 +8,16 @@ For platforms not listed as supported by any of the tiers, support cannot be ass ## Current Test Strategy -The current verification process of the OpenTelemetry Collector includes unit and performance tests for core and additional end-to-end and integration tests for contrib. In the end-to-end tests, receivers, processors, and exporters etc. are tested in a testbed, while the integration tests rely on actual instances and available container images. Additional stability tests are in preparation for the future as well. All verification tests are run on the linux/amd64 as the primary platform today. In addition, unit tests are run for the _contrib_ collector on windows/amd64. The tests use as execution environments the latest Ubuntu and Windows Server versions [supported as Github runners](https://docs.github.com/en/actions/using-github-hosted-runners/about-github-hosted-runners#supported-runners-and-hardware-resources). +The current verification process of the OpenTelemetry Collector includes unit and performance tests for core and additional end-to-end and integration tests for contrib. In the end-to-end tests, receivers, processors, and exporters etc. are tested in a testbed, while the integration tests rely on actual instances and available container images. Additional stability tests are in preparation for the future as well. All verification tests are run on the linux/amd64 as the primary platform today. In addition, unit tests are run for the _contrib_ collector on windows/amd64. The tests use as execution environments the latest Ubuntu and Windows Server versions [supported as Github runners](https://docs.github.com/en/actions/using-github-hosted-runners/about-github-hosted-runners). The cross compile supports the following targets: - darwin/amd64 and darwin/arm64 - linux/amd64, linux/arm64, linux/386, linux/arm and linux/ppc64le -- windows/amd64, windows/386. +- windows/amd64, windows/arm64 and windows/386. Except of the mentioned tests for linux/amd64 and windows/amd64, no other platforms are tested by the CI/CD tooling. -Container images of the _core_ and _contrib_ collector are built and published to Docker Hub and ghcr.io for the platforms specified in the [goreleaser configuration](https://github.com/open-telemetry/opentelemetry-collector-releases/blob/bf8002ec6d2109cdb4184fc6eb6f8bda59ea96a2/.goreleaser.yaml#L137). End-to-end tests of the _contrib_ container images are run on the latest Ubuntu Linux supported by GitHub runners and for the four most recent Kubernetes versions. +Container images of the _core_ and _contrib_ collector are built and published to Docker Hub and ghcr.io for the platforms specified in the [goreleaser configuration](https://github.com/open-telemetry/opentelemetry-collector-releases/blob/bf8002ec6d2109cdb4184fc6eb6f8bda59ea96a2/.goreleaser.yaml). End-to-end tests of the _contrib_ container images are run on the latest Ubuntu Linux supported by GitHub runners and for the four most recent Kubernetes versions. ## Tiered platform support model @@ -61,11 +61,13 @@ Tier 3 platforms are currently: | Platform | Owner(s) | |---------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------| | darwin/amd64 | [@h0cheung](https://github.com/h0cheung) | +| js/wasm | [@evan-bradley](https://github.com/evan-bradley), [@mx-psi](https://github.com/mx-psi) | | linux/386 | [@andrzej-stencel](https://github.com/andrzej-stencel) | | linux/arm | [@Wal8800](https://github.com/Wal8800), [@atoulme](https://github.com/atoulme) | | linux/ppc64le | [@IBM-Currency-Helper](https://github.com/IBM-Currency-Helper), [@adilhusain-s](https://github.com/adilhusain-s), [@seth-priya](https://github.com/seth-priya) | | linux/riscv64 | [@shanduur](https://github.com/shanduur) | | linux/s390x | [@bwalk-at-ibm](https://github.com/bwalk-at-ibm), [@rrschulze](https://github.com/rrschulze) | | windows/386 | [@pjanotti](https://github.com/pjanotti) | +| windows/arm64 | [@pjanotti](https://github.com/pjanotti) | The proposed additional platform aix/ppc64 ([#19195](https://github.com/open-telemetry/opentelemetry-collector-contrib/issues/19195)) will be included into Tier 3 once it's added to the OpenTelemetry Collector as platform. diff --git a/docs/release.md b/docs/release.md index 3fd52168b025..465398a0cbdd 100644 --- a/docs/release.md +++ b/docs/release.md @@ -4,9 +4,9 @@ Collector build and testing is currently fully automated. However there are stil We release both core and contrib collectors with the same versions where the contrib release uses the core release as a dependency. We’ve divided this process into three sections. Each section is assigned to an approver or maintainer of the corresponding repository. The sections are: -1. The [Core](#releasing-opentelemetry-collector) collector, including the collector builder CLI tool. -2. The [Contrib](#releasing-opentelemetry-collector-contrib) collector repository, containing Collector components. -3. The [artifacts](#producing-the-artifacts) +1. The [Core](#releasing-opentelemetry-collector-core-release-manager) collector, including the collector builder CLI tool. +2. The [Contrib](#releasing-opentelemetry-collector-contrib-contrib-release-manager) collector repository, containing Collector components. +3. The [artifacts](#producing-the-artifacts-releases-release-manager) **Important Note:** You’ll need to be able to sign git commits/tags in order to be able to release a collector version. Follow [this guide](https://docs.github.com/en/authentication/managing-commit-signature-verification/signing-commits) to set it up. @@ -30,17 +30,9 @@ Before the release, make sure there are no open release blockers in [core](https - 🛑 **Do not move forward until this PR is merged.** 2. Determine the version number that will be assigned to the release. Usually, we increment the minor version number and set the patch number to 0. In this document, we are using `v0.85.0` as the version to be released, following `v0.84.0`. - Check if stable modules have any changes since the last release by running the following: - - `make check-changes PREVIOUS_VERSION=v1.x.x MODSET=stable`. - - If there are no changes, there is no need to release new version for stable - modules. If there are changes found but .chloggen directory doesn't have any - corresponding entries, add missing changelog entries. If the changes are - insignificant, consider not releasing a new version for stable modules. 3. Manually run the action [Automation - Prepare Release](https://github.com/open-telemetry/opentelemetry-collector/actions/workflows/prepare-release.yml). This action will create an issue to track the progress of the release and a pull request to update the changelog and version numbers in the repo. - When prompted, enter the version numbers determined in Step 2, but do not include a leading `v`. - - If not intending to release stable modules, do not specify a version for `Release candidate version stable`. - While this PR is open all merging in Core is automatically halted via the `Merge freeze / Check` CI check. - If the PR needs updated in any way you can make the changes in a fork and PR those changes into the `prepare-release-prs/x` branch. You do not need to wait for the CI to pass in this prep-to-prep PR. - 🛑 **Do not move forward until this PR is merged.** 🛑 @@ -50,17 +42,17 @@ Before the release, make sure there are no open release blockers in [core](https ⚠️ If you set your remote using `https` you need to include `REMOTE=https://github.com/open-telemetry/opentelemetry-collector.git` in each command. ⚠️ - `make push-tags MODSET=beta` for the beta modules group, - - `make push-tags MODSET=stable` for the stable modules group, only if there were changes since the last release. - + - `make push-tags MODSET=stable` for the stable modules group. + **Note**: Pushing the **beta** tags will automatically trigger the [Automation - Release Branch](https://github.com/open-telemetry/opentelemetry-collector/actions/workflows/release-branch.yml) GitHub Action, which will create the release branch (e.g. `release/v0.127.x`) from the commit that prepared the release. Pushing stable tags, if required, will not trigger creation of an additional release branch. 5. Wait for the "Automation - Release Branch" workflow to complete successfully. This workflow will automatically: - Detect the version from the pushed beta tags - Use the commit on which the tags were pushed as the "prepare release" commit - Create a new release branch (e.g. `release/v0.127.x`) from that commit - + If the workflow fails, you can check the [Actions tab](https://github.com/open-telemetry/opentelemetry-collector/actions) for details. The underlying script (./.github/workflows/scripts/release-branch.sh) can also be tested and run locally if needed by setting the GITHUB_REF environment variable (e.g., `GITHUB_REF=refs/tags/v0.85.0 ./.github/workflows/scripts/release-branch.sh`). - + 6. Wait for the tag-triggered build workflows to pass successfully. 7. A new `v0.85.0` source code release should be automatically created on Github by now. Its description should already contain the corresponding CHANGELOG.md and CHANGELOG-API.md contents. @@ -121,7 +113,7 @@ releases and add new schedules to the bottom of the list. To update the release to fix the workflow, a maintainer can update the release tag to the commit with the fix and re-run the release. (Note: This cannot be done by approvers.) - + It is safe to re-run the workflows that already succeeded. Publishing container images can be done multiple times, and publishing artifacts or pushing OCB/Supervisor tags to GitHub will fail without any adverse effects. @@ -181,18 +173,18 @@ Once a module is ready to be released under the `1.x` version scheme, file a PR | Date | Version | Core Release manager | Contrib release manager | 'Releases' release manager | |------------|----------|-----------------------|-------------------------|----------------------------| -| 2025-12-01 | v0.141.0 | [@dmathieu][12] | [@braydonk][13] | [@MovieStoreGuy][17] | -| 2025-12-15 | v0.142.0 | [@atoulme][5] | [@atoulme][5] | [@atoulme][5] | -| 2026-01-05 | v0.143.0 | [@jmacd][1] | [@ArthurSens][11] | [@mowies][15] | -| 2026-01-19 | v0.144.0 | [@mx-psi][14] | [@mx-psi][14] | [@mx-psi][14] | -| 2026-02-02 | v0.145.0 | [@TylerHelmuth][3] | [@TylerHelmuth][3] | [@TylerHelmuth][3] | -| 2026-02-16 | v0.146.0 | [@evan-bradley][2] | [@evan-bradley][2] | [@evan-bradley][2] | -| 2026-03-02 | v0.147.0 | [@songy23][6] | [@songy23][6] | [@songy23][6] | | 2026-03-16 | v0.148.0 | [@dmitryax][7] | [@dmitryax][7] | [@dmitryax][7] | | 2026-03-30 | v0.149.0 | [@codeboten][8] | [@codeboten][8] | [@codeboten][8] | -| 2026-04-13 | v0.150.0 | [@axw][18] | [@ChrsMark][19] | [@crobert-1][20] | +| 2026-04-13 | v0.150.0 | [@dmathieu][12] | [@andrzej-stencel][4] | [@crobert-1][20] | | 2026-04-27 | v0.151.0 | [@bogdandrutu][9] | [@bogdandrutu][9] | [@bogdandrutu][9] | -| 2025-05-11 | v0.152.0 | [@jade-guiton-dd][10] | [@andrzej-stencel][4] | [@dehaansa][16] | +| 2026-05-11 | v0.152.0 | [@jade-guiton-dd][10] | [@ChrsMark][19] | [@dehaansa][16] | +| 2026-05-25 | v0.153.0 | [@axw][18] | [@braydonk][13] | [@MovieStoreGuy][17] | +| 2025-06-08 | v0.154.0 | [@atoulme][5] | [@atoulme][5] | [@atoulme][5] | +| 2026-06-22 | v0.155.0 | [@jmacd][1] | [@ArthurSens][11] | [@TylerHelmuth][3] | +| 2026-07-06 | v0.156.0 | [@mx-psi][14] | [@mx-psi][14] | [@mx-psi][14] | +| 2026-07-20 | v0.157.0 | [@TylerHelmuth][3] | [@TylerHelmuth][3] | [@mowies][15] | +| 2026-08-03 | v0.158.0 | [@evan-bradley][2] | [@evan-bradley][2] | [@evan-bradley][2] | +| 2026-08-17 | v0.159.0 | [@songy23][6] | [@songy23][6] | [@songy23][6] | [1]: https://github.com/jmacd [2]: https://github.com/evan-bradley diff --git a/docs/rfcs/component-configuration-schema-roadmap.md b/docs/rfcs/component-configuration-schema-roadmap.md new file mode 100644 index 000000000000..d844297c9e71 --- /dev/null +++ b/docs/rfcs/component-configuration-schema-roadmap.md @@ -0,0 +1,134 @@ +# Component Configuration Management Roadmap + +## Motivation + +The OpenTelemetry Collector ecosystem lacks a unified approach to configuration management, leading to several problems: + +1. **Documentation Drift**: Go configuration structs and documentation exist independently and frequently diverge over time +2. **Inconsistent Developer Experience**: No standardized patterns for defining component configurations +3. **No config validation capabilities**: Lack of JSON schemas prevents autocompletion and validation in configuration editors + +## Current state + +- Go configuration structs in each component with validation implemented via custom code and defaults set in `setDefaultConfig` functions +- Manual documentation that often becomes outdated +- No standardized JSON schemas for configuration validation + +## Desired state + +**Goal**: Establish a single source of truth for component configuration that generates: +1. **Go configuration structs** with proper mapstructure tags, validation, and default values. +2. **JSON schemas** for configuration validation and editor autocompletion +3. **Documentation** that stays automatically synchronized with implementation + +## Previous and current approaches + +### Past attempts + +- [Previously available contrib configschema tool](https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/v0.102.0/cmd/configschema): Retired due to incompleteness, complexity and maintenance burden. It required dynamic analysis of Go code and pulling all dependencies. + +- [PR #27003](https://github.com/open-telemetry/opentelemetry-collector-contrib/pull/27003): Failed due to trying to cover all corner-cases in the design phase instead of quickly iterating from a simpler approach. + +- [PR #10694](https://github.com/open-telemetry/opentelemetry-collector/pull/10694): An attempt to generate config structs from the schema defined in metadata.yaml using github.com/atombender/go-jsonschema. It faced some limitations of the library. However, it was abandoned mostly due to a lack of involvement from the reviewers. + +### Current initiatives + +- [opentelemetry-collector-contrib/cmd/schemagen/](https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/main/cmd/schemagen): Generates JSON schemas from Go structs with limited support for validation and default values. It uses AST parsing with module-aware loading of dependencies to handle shared libraries. + +- [PR #14288](https://github.com/open-telemetry/opentelemetry-collector/pull/14288): Also uses AST parsing to generate JSON schemas from Go structs for the component configurations without using shared config support. Written as part of mdatagen tool. + +Parsing Go code to generate schemas is inherently limited. Community consensus recommends reversing the process: generate Go code from schemas instead. There is already widely established practice in other ecosystems to generate go code and documentation for other parts of the OTel Collector. + +## Suggested approach + +### Overview + +This RFC proposes an approach that transitions from the current Go-struct-first model to a schema-first configuration generation system: + +1. **Bootstrap Phase**: Use existing `schemagen` tool to generate initial schema specifications +2. **Tool Development Phase**: Create new tooling that generates Go structs, JSON schemas, and documentation from YAML schema specifications +3. **Migration Phase**: Migrate all components to the new schema-first approach + +Use of the `schemagen` tool is dictated by the modularity of the Collector components. It allows generating schemas for shared libraries (e.g., scraperhelper) that can be referenced by individual components. + +### Reasoning behind this approach + +- **Explicit validation**: Schema specifications can explicitly capture validation rules and default config values that cannot be extracted from Go code +- **Rich documentation**: Schemas can include descriptions, examples, and constraints that enhance generated documentation +- **Simplified tooling**: Template-based code generation is more predictable than AST parsing + +**Why YAML schema format for the source of truth?** +- **Human-readable**: Easier for component developers to author and maintain than JSON +- **Integration with existing infrastructure**: Natural extension of `metadata.yaml` approach used by `mdatagen` given that it already uses YAML to generate metrics builder configs +- **Extensibility**: YAML allows for custom fields to capture domain-specific configuration and provide escape-hatches to generate config fields that still require custom implementation, validation or default value setters. + +### Example schema format + +```yaml +config: + allOf: + - $ref: "go.opentelemetry.io/collector/scraper/scraperhelper#/$defs/ControllerConfig" + - $ref: "#/$defs/MetricsBuilderConfig" + properties: + targets: + type: array + items: + type: object + properties: + host: + type: string + description: "Target hostname or IP address" + ping_count: + type: integer + description: "Number of pings to send" + default: 3 + ping_interval: + type: string + format: duration + x-customType: "time.Duration" + description: "Interval between pings" + default: "1s" + required: ["host"] +``` + +`#/$defs/MetricsBuilderConfig` would be automatically generated by mdatagen with the same process used to generate the go structs and documentation today. + +`go.opentelemetry.io/collector/scraper/scraperhelper#/$defs/ControllerConfig` would be generated by the new tool from the schema definition in the scraperhelper component. + +#### Extensibility + +The YAML schema specification can be extended with custom fields (e.g., `x-customType`) to capture domain-specific types and validation rules that are not natively supported in JSON schema. Additionally, we may introduce custom fields that generate fields that will produce references to structs or validation functions that require more complex logic and manual implementation. + +### Roadmap + +#### Phase 1: Bootstrap initial schemas + +**Objective**: Use `schemagen` tool to generate initial schema specifications for all components + +**Success Criteria:** +- YAML schemas generated for all components in core and contrib repositories +- Setup CI check to ensure schemas remain up-to-date with Go structs + +#### Phase 2: Implement new generation tool + +**Objective**: Implement a new tool that takes YAML schema from the user and generates Go structs, combined JSON schema, and documentation per component. + +**Success Criteria:** +- New tool generates Go structs that are API-compatible with existing implementations with the following features: + - Parses YAML schema specifications + - Generates Go configuration structs with proper validation + - Produces JSON schemas for config validation + - Creates synchronized documentation +- Generated JSON schemas pass validation tests with real collector configurations +- Generated documentation accurately reflects all configuration options +- Pilot components successfully replace hand-written implementations + +If existing config structs don't follow the established naming patterns produced by the generated code, the implementation may allow breaking the Go API compatibility in favor of consistent Go API naming standards and long-term maintainability. However, the configuration file format MUST remain compatible for end users. + +#### Phase 3: Migrate all components + +**Objective**: Migrate all components to the new tool introduced in Phase 2 + +**Success Criteria:** +- All core and contrib components migrated to schema-first approach +- All new components use schema-first tooling by default diff --git a/docs/rfcs/processing.md b/docs/rfcs/processing.md index 3678922d8ef4..7901acd2b1b1 100644 --- a/docs/rfcs/processing.md +++ b/docs/rfcs/processing.md @@ -248,7 +248,7 @@ receivers: otlp: exporters: - otlp: + otlp_grpc: processors: transform: diff --git a/docs/rfcs/semconv-feature-gates.md b/docs/rfcs/semconv-feature-gates.md new file mode 100644 index 000000000000..227b588fff53 --- /dev/null +++ b/docs/rfcs/semconv-feature-gates.md @@ -0,0 +1,248 @@ +# Semantic conventions migrations in the Collector + +## Overview + +The OpenTelemetry Collector components emit telemetry that often conforms to semantic conventions. +Semantic conventions have [varying levels of stability][1] and often have an SDK-focused migration +guide. + +This RFC defines how migration should be handled in Collector components that have +semantic conventions that migrate to a stable version, in a Collector-native way. + +## Scope and goals + +This RFC provides general guidelines for semantic convention-mandated migrations of telemetry created by Collector components (usually receivers) and output into the Collector's pipeline. It explicitly does not attempt to cover: +- telemetry created by an application and forwarded by a Collector receiver; +- internal telemetry of Collector components; +- guidelines for the migration of specific semantic conventions. + +The migration mechanism should have the following characteristics: + +1. **Collector native**: the mechanism should work in a similar way to other Collector migrations + and should feel natural and intuitive to users. +2. **Simple**: a user should have to make a small number of changes to their Collector deployment to + migrate to a new set of conventions. +3. **Easy to understand**: It should be easy to understand how to migrate a particular set of + conventions. +5. **Flexible (double publish)**: The mechanism should allow you to 'double publish' v0 and v1 + conventions +6. **Flexible (other conventions)**: The mechanism should still allow for evolution of other + semantic conventions that are not being migrated. + +## Background + +### Setup + +We want to write guidance for when we have a component that emits telemetry from a common +`area` that is undergoing a migration mandated by the Semantic Conventions SIG. In the rest of this +document we refer to the **v0** conventions and the **v1** conventions, which are the conventions +in this area before and after the migration. + +When the semantic conventions are specific to a component we use +- `kind` to refer to the component kind (receiver, exporter...) +- `id` for the component id (e.g. `hostmetrics`) + +### What does the semconv spec say? + +The semantic conventions specification defines an environment variable named +`OTEL_SEMCONV_STABILITY_OPT_IN` that, for each area, takes two possible values: +1. One value representing the new semantic conventions (e.g. `http`, `gen_ai_latest_experimental`) +2. Once mature enough, a second value ending in `/dup` that emits both the old conventions and the + new ones. + +This is not specified in a generic way, but it is a consistent pattern across all semantic +conventions areas that are being actively worked on: + +
+ + Example 1: HTTP compatibility warning + +Taken from [semconv v1.38.0][2]: + +> **Warning** +> Existing HTTP instrumentations that are using +> [v1.20.0 of this document](https://github.com/open-telemetry/opentelemetry-specification/blob/v1.20.0/specification/trace/semantic_conventions/http.md) +> (or prior): +> +> * SHOULD NOT change the version of the HTTP or networking conventions that they emit +> until the HTTP semantic conventions are marked stable (HTTP stabilization will +> include stabilization of a core set of networking conventions which are also used +> in HTTP instrumentations). Conventions include, but are not limited to, attributes, +> metric and span names, and unit of measure. +> * SHOULD introduce an environment variable `OTEL_SEMCONV_STABILITY_OPT_IN` +> in the existing major version which is a comma-separated list of values. +> The only values defined so far are: +> * `http` - emit the new, stable HTTP and networking conventions, +> and stop emitting the old experimental HTTP and networking conventions +> that the instrumentation emitted previously. +> * `http/dup` - emit both the old and the stable HTTP and networking conventions, +> allowing for a seamless transition. +> * The default behavior (in the absence of one of these values) is to continue +> emitting whatever version of the old experimental HTTP and networking conventions +> the instrumentation was emitting previously. +> * Note: `http/dup` has higher precedence than `http` in case both values are present +> * SHOULD maintain (security patching at a minimum) the existing major version +> for at least six months after it starts emitting both sets of conventions. +> * SHOULD drop the environment variable in the next major version (stable +> next major version SHOULD NOT be released prior to October 1, 2023). + +
+ +
+ + Example 2: GenAI compatibility warning + +From [semconv v1.38.0][3]: + +> [!Warning] +> +> Existing GenAI instrumentations that are using +> [v1.36.0 of this document](https://github.com/open-telemetry/semantic-conventions/blob/v1.36.0/docs/gen-ai/README.md) +> (or prior): +> +> * SHOULD NOT change the version of the GenAI conventions that they emit by default. +> Conventions include, but are not limited to, attributes, metric, span and event names, +> span kind and unit of measure. +> * SHOULD introduce an environment variable `OTEL_SEMCONV_STABILITY_OPT_IN` +> as a comma-separated list of category-specific values. The list of values +> includes: +> * `gen_ai_latest_experimental` - emit the latest experimental version of +> GenAI conventions (supported by the instrumentation) and do not emit the +> old one (v1.36.0 or prior). +> * The default behavior is to continue emitting whatever version of the GenAI +> conventions the instrumentation was emitting (1.36.0 or prior). +> +> This transition plan will be updated to include stable version before the +> GenAI conventions are marked as stable. + +
+ +
+ + Example 3: K8s compatibility warning + +> From [semconv v1.38.0][3]: + +> When existing K8s instrumentations published by OpenTelemetry are +> updated to the stable K8s semantic conventions, they: +> +> - SHOULD introduce an environment variable `OTEL_SEMCONV_STABILITY_OPT_IN` in +> their existing major version, which accepts: +> - `k8s` - emit the stable k8s conventions, and stop emitting +> the old k8s conventions that the instrumentation emitted previously. +> - `k8s/dup` - emit both the old and the stable k8s conventions, +> allowing for a phased rollout of the stable semantic conventions. +> - The default behavior (in the absence of one of these values) is to continue +> emitting whatever version of the old k8s conventions the +> instrumentation was emitting previously. +> - Need to maintain (security patching at a minimum) their existing major version +> for at least six months after it starts emitting both sets of conventions. +> - May drop the environment variable in their next major version and emit only +> the stable k8s conventions. + +> Specifically for the Opentelemetry Collector: + +> The transition will happen through two different feature gates. +> One for enabling the new schema called `semconv.k8s.enableStable`, +> and one for disabling the old schema called `semconv.k8s.disableLegacy`. Then: + +> - On alpha the old schema is enabled by default (`semconv.k8s.disableLegacy` defaults to false), +> while the new schema is disabled by default (`semconv.k8s.enableStable` defaults to false). +> - On beta/stable the old schema is disabled by default (`semconv.k8s.disableLegacy` defaults to true), +> while the new is enabled by default (`semconv.k8s.enableStable` defaults to true). +> - It is an error to disable both schemas +> - Both schemas can be enabled with `--feature-gates=-semconv.k8s.disableLegacy,+semconv.k8s.enableStable`. + +
+ +## Proposed mechanism + +Suppose the `` (e.g. `hostmetrics`) `kind` (e.g. `receiver`) component is migrating from v0 to +v1 semantic conventions on the area `area` (e.g. `process`). The semantic conventions specification +defines the set of conventions that are in scope for a particular migration. + +To support this migration, the component defines two feature gates: `..EmitV1Conventions` (e.g. +`receiver.hostmetrics.EmitV1ProcessConventions`) and `..DontEmitV0Conventions` +(e.g. `receiver.hostmetrics.DontEmitV0ProcessConventions`). These feature gates work as follows: + +| `..EmitV1Conventions` status | `..DontEmitV0Conventions` status | Resulting behavior | +|-----------------------------------------------|-------------------------------------------------------|-----------------------------------------------------------| +| Disabled | Disabled | Emit telemetry under the 'v0' conventions | +| Disabled | Enabled | Error at startup since this would not emit any telemetry | +| Enabled | Disabled | Emit telemetry under both the v0 and the v1 conventions | +| Enabled | Enabled | Emit telemetry under the v1 conventions | + +Both feature gates evolve at the same pace through the feature gate stages, so that the progression +is as follows: +1. Initially both are at **alpha** stage (disabled by default). This means that the default behavior + is to emit only the 'v0' conventions. Users can opt-in to emit the v1 conventions alongside the + v0 conventions or to emit only the v1 conventions. A warning message must be logged by the component at startup indicating the upcoming change. +2. Whenever there is a semantic conventions release that marks these as stable, the feature gates are promoted to the + **beta** stage on the same Collector release. The new default behavior is therefore to emit only the + 'v1' conventions. Users can opt-out to emit the v1 conventions alongside the v0 conventions or + to emit only the v0 conventions. +3. After 4 minor releases, the feature gates are promoted to the **stable** stage. At this point users + can only use the v1 conventions. +4. After additional 4 minor releases, the feature gates are removed. + +This mechanism does not cover any sort of transition for experimental semantic conventions. These +presumably would be covered by separate feature gates or some other mechanism. + +## Handling conflicts during double-publishing + +During the double-publishing phase (when both `..EmitV1Conventions` is enabled and `..DontEmitV0Conventions` is disabled), components typically emit both v0 and v1 telemetry. For metrics, this usually means emitting two separate metrics with different names (e.g., `http.server.duration` for v0 and `http.server.request.duration` for v1). + +However, in some cases v0 and v1 conventions may use the same metric name but with different characteristics (e.g., different attributes or metric types). Two metrics with identical names must not be emitted, as this would produce an invalid OpenTelemetry dataset and cause issues on backends. Below are examples illustrating how such conflicts can be resolved: + +**Different attributes:** If a metric name stays the same but an attribute is renamed, emit a single metric with both the v0 and v1 attributes present. For instance, if `process.cpu.time` uses `process.owner` in v0 and `process.owner.name` in v1, emit one metric with both attributes. + +**Different metric type:** If a metric name stays the same but the type changes (e.g., Gauge to UpDownCounter), emit a single metric with the v1 type, effectively prioritizing the new convention. For instance, if `system.memory.usage` changes from Gauge to UpDownCounter, emit it as an UpDownCounter. + +## Alternative mechanisms + +There are some other possibilities: + +### Environment variable + +We could just use the `OTEL_SEMCONV_STABILITY_OPT_IN` mechanism. However, this does not feel +"Collector native": Collector users expect experimental features to be controlled via feature gates +and as such this could be a surprising mechanism. In particular, users would expect that they are +able to 'roll back' to the previous behavior even after a Collector upgrade, something that the +environment variable mechanism explicitly does not support. + +### More granular feature gate pairs + +The granularity of the feature gates described could be changed: we could have a pair per convention +or even a pair for the whole Collector. I argue 'per component' strikes the right balance between +simplicity and flexibility: +- per convention would lead to dozens of feature gates on some of the areas we want to stabilize. It + would also be unclear how these interact on edge cases (semantic conventions may only make sense + holistically) +- a single pair of feature gates would effectively be forever unstable and would not be flexible + enough to allow people to migrate on a per dashboard basis + +### Meta feature gate + +We could have both a feature gate pair per component and a meta target feature gate pair that allows +you to enable/disable all v1 conventions at the same time. This is effectively a superset of the +proposed mechanism, so I argue we can postpone this for later: if users ask for it, we can always +add it in the future. + +## Open questions and future possibilities + +This document does not cover how to deal with experimental semantic conventions after the 'big' +migration has been completed in one particular area. What to do here in part depends on the +[stabilization changes][4]. Quoting the blogpost: +> Instrumentation stability should be decoupled from semantic convention stability. We have a lot of +> stable instrumentation that is safe to run in production, but has data that may change in the +> future. Users have told us that conflating these two levels of stability is confusing and limits +> their options. + +How to deal with these remains an open question that should be tackled in OTEPs first. + +As mentioned above, the 'Meta feature gate' remains a possibility even when adopting this mechanism. + +[1]: https://opentelemetry.io/docs/specs/semconv/general/semantic-convention-groups/#group-stability +[2]: https://github.com/open-telemetry/semantic-conventions/blob/v1.38.0/docs/http/README.md +[3]: https://github.com/open-telemetry/semantic-conventions/blob/v1.38.0/docs/gen-ai/README.md +[4]: https://opentelemetry.io/blog/2025/stability-proposal-announcement/ diff --git a/docs/scraping-receivers.md b/docs/scraping-receivers.md index 35dee48cdf25..b25c78d37c5f 100644 --- a/docs/scraping-receivers.md +++ b/docs/scraping-receivers.md @@ -79,6 +79,10 @@ Nevertheless, metrics that are emitted by default MUST be always kept up-to-date monitored system. Given that, occasional breaking changes in the emitted metrics are expected even in the stable receivers. Any breaking change MUST be applied following [the deprecation process](#changing-the-emitted-metrics). +## Stability levels for metrics and attributes + +See [Collector's Telemetry Stability levels](./coding-guidelines.md#telemetry-stability-levels) + ## Changing the emitted metrics Some changes are not considered breaking and can be applied to metrics emitted by scraping receivers of any diff --git a/examples/k8s/otel-config.yaml b/examples/k8s/otel-config.yaml index d7d2a155654f..0db90d2de2f7 100644 --- a/examples/k8s/otel-config.yaml +++ b/examples/k8s/otel-config.yaml @@ -16,7 +16,7 @@ data: http: endpoint: ${env:MY_POD_IP}:4318 exporters: - otlp: + otlp_grpc: endpoint: "otel-collector.default:4317" tls: insecure: true @@ -122,7 +122,7 @@ data: extensions: zpages: {} exporters: - otlp: + otlp_grpc: endpoint: "http://someotlp.target.com:4317" # Replace with a real endpoint. tls: insecure: true diff --git a/exporter/debugexporter/README.md b/exporter/debugexporter/README.md index 9b6297c2341d..cc994b620b5b 100644 --- a/exporter/debugexporter/README.md +++ b/exporter/debugexporter/README.md @@ -1,6 +1,5 @@ -# Debug Exporter - +# Debug Exporter | Status | | | ------------- |-----------| | Stability | [development]: profiles | @@ -38,6 +37,7 @@ The following settings are optional: Refer to [Zap docs](https://godoc.org/go.uber.org/zap/zapcore#NewSampler) for more details on how sampling parameters impact number of messages. - `use_internal_logger` (default = `true`): uses the collector's internal logger for output. See [below](#using-the-collectors-internal-logger) for description. +- `output_paths` (default = `["stdout"]`): a list of file paths to write output to. This option can only be used when `use_internal_logger` is `false`. Special strings "stdout" and "stderr" are interpreted as [standard output](https://en.wikipedia.org/wiki/Standard_streams#Standard_output_(stdout)) and [standard error](https://en.wikipedia.org/wiki/Standard_streams#Standard_error_(stderr)) respectively. All other values are treated as file paths. Setting `output_paths` when `use_internal_logger` is `true` results in a configuration error. - `sending_queue` (disabled by default): see [Sending Queue](../exporterhelper/README.md#sending-queue) for the full set of available options. Example configuration: @@ -50,6 +50,16 @@ exporters: sampling_thereafter: 200 ``` +Example configuration with custom output path: + +```yaml +exporters: + debug: + use_internal_logger: false + output_paths: + - stderr +``` + ## Verbosity levels The following subsections describe the output from the exporter depending on the configured verbosity level - `basic`, `normal` and `detailed`. @@ -138,7 +148,8 @@ This comes with the following consequences: When `use_internal_logger` is set to `false`, the exporter does not use the collector's internal logger. Changing the values in `service::telemetry::logs` has no effect on the exporter's output. -The exporter's output is sent to `stdout`. +The exporter's output is sent to the paths specified in `output_paths` (default: `["stdout"]`). +You can configure `output_paths` to send output to `stderr`, a file, or multiple destinations. [internal_telemetry]: https://opentelemetry.io/docs/collector/internal-telemetry/ [internal_logs_config]: https://opentelemetry.io/docs/collector/internal-telemetry/#configure-internal-logs diff --git a/exporter/debugexporter/config.go b/exporter/debugexporter/config.go index fbf962d7c89b..57ee242ced92 100644 --- a/exporter/debugexporter/config.go +++ b/exporter/debugexporter/config.go @@ -4,9 +4,11 @@ package debugexporter // import "go.opentelemetry.io/collector/exporter/debugexporter" import ( + "errors" "fmt" "go.opentelemetry.io/collector/component" + "go.opentelemetry.io/collector/config/configoptional" "go.opentelemetry.io/collector/config/configtelemetry" "go.opentelemetry.io/collector/exporter/exporterhelper" ) @@ -33,7 +35,14 @@ type Config struct { // UseInternalLogger defines whether the exporter sends the output to the collector's internal logger. UseInternalLogger bool `mapstructure:"use_internal_logger"` - QueueConfig exporterhelper.QueueBatchConfig `mapstructure:"sending_queue"` + // OutputPaths is a list of file paths to write logging output to. + // This option can only be used when use_internal_logger is false. + // Special strings "stdout" and "stderr" are interpreted as os.Stdout and os.Stderr respectively. + // All other values are treated as file paths. + // If not set, defaults to ["stdout"]. + OutputPaths []string `mapstructure:"output_paths"` + + QueueConfig configoptional.Optional[exporterhelper.QueueBatchConfig] `mapstructure:"sending_queue"` // prevent unkeyed literal initialization _ struct{} @@ -47,5 +56,17 @@ func (cfg *Config) Validate() error { return fmt.Errorf("verbosity level %q is not supported", cfg.Verbosity) } + // output_paths is only used when use_internal_logger is false + // If set when use_internal_logger is true, it would be ignored, which is confusing + if cfg.UseInternalLogger && cfg.OutputPaths != nil { + return errors.New("output_paths is not supported when use_internal_logger is true") + } + + // If use_internal_logger is false and output_paths is explicitly set to empty, error + // (nil output_paths will default to ["stdout"] in createCustomLogger) + if !cfg.UseInternalLogger && cfg.OutputPaths != nil && len(cfg.OutputPaths) == 0 { + return errors.New("output_paths must not be empty when use_internal_logger is false") + } + return nil } diff --git a/exporter/debugexporter/config_test.go b/exporter/debugexporter/config_test.go index 51b4c875e798..634b94148087 100644 --- a/exporter/debugexporter/config_test.go +++ b/exporter/debugexporter/config_test.go @@ -10,6 +10,7 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + "go.opentelemetry.io/collector/config/configoptional" "go.opentelemetry.io/collector/config/configtelemetry" "go.opentelemetry.io/collector/confmap" "go.opentelemetry.io/collector/confmap/confmaptest" @@ -24,12 +25,11 @@ func TestUnmarshalDefaultConfig(t *testing.T) { } func TestUnmarshalConfig(t *testing.T) { - queueCfg := exporterhelper.NewDefaultQueueConfig() - queueCfg.Enabled = false tests := []struct { - filename string - cfg *Config - expectedErr string + filename string + cfg *Config + expectedUnmarshalErr string + expectedValidateErr string }{ { filename: "config_verbosity.yaml", @@ -37,12 +37,29 @@ func TestUnmarshalConfig(t *testing.T) { Verbosity: configtelemetry.LevelDetailed, SamplingInitial: 10, SamplingThereafter: 50, - QueueConfig: queueCfg, + UseInternalLogger: false, + OutputPaths: []string{"stdout"}, + QueueConfig: configoptional.Default(exporterhelper.NewDefaultQueueConfig()), + }, + }, + { + filename: "config_output_paths.yaml", + cfg: &Config{ + Verbosity: configtelemetry.LevelBasic, + SamplingInitial: 2, + SamplingThereafter: 1, + UseInternalLogger: false, + OutputPaths: []string{"stderr"}, + QueueConfig: configoptional.Default(exporterhelper.NewDefaultQueueConfig()), }, }, { - filename: "config_verbosity_typo.yaml", - expectedErr: "'' has invalid keys: verBosity", + filename: "config_output_paths_empty.yaml", + expectedValidateErr: "output_paths must not be empty when use_internal_logger is false", + }, + { + filename: "config_verbosity_typo.yaml", + expectedUnmarshalErr: "has invalid keys: verBosity", }, } @@ -53,12 +70,20 @@ func TestUnmarshalConfig(t *testing.T) { factory := NewFactory() cfg := factory.CreateDefaultConfig() err = cm.Unmarshal(&cfg) - if tt.expectedErr != "" { - assert.ErrorContains(t, err, tt.expectedErr) - } else { - require.NoError(t, err) - assert.Equal(t, tt.cfg, cfg) + if tt.expectedUnmarshalErr != "" { + require.ErrorContains(t, err, tt.expectedUnmarshalErr) + return + } + require.NoError(t, err) + + cfgCasted := cfg.(*Config) + err = cfgCasted.Validate() + if tt.expectedValidateErr != "" { + require.ErrorContains(t, err, tt.expectedValidateErr) + return } + require.NoError(t, err) + assert.Equal(t, tt.cfg, cfg) }) } } @@ -122,7 +147,45 @@ func TestValidate(t *testing.T) { { name: "verbosity detailed", cfg: &Config{ - Verbosity: configtelemetry.LevelDetailed, + Verbosity: configtelemetry.LevelDetailed, + UseInternalLogger: true, // Default behavior + }, + }, + { + name: "empty output_paths when use_internal_logger is false", + cfg: &Config{ + UseInternalLogger: false, + OutputPaths: []string{}, + }, + expectedErr: "output_paths must not be empty when use_internal_logger is false", + }, + { + name: "valid output_paths when use_internal_logger is false", + cfg: &Config{ + UseInternalLogger: false, + OutputPaths: []string{"stdout"}, + }, + }, + { + name: "nil output_paths when use_internal_logger is false (defaults to stdout)", + cfg: &Config{ + UseInternalLogger: false, + OutputPaths: nil, + }, + }, + { + name: "output_paths set when use_internal_logger is true (not allowed)", + cfg: &Config{ + UseInternalLogger: true, + OutputPaths: []string{"stderr"}, + }, + expectedErr: "output_paths is not supported when use_internal_logger is true", + }, + { + name: "nil output_paths when use_internal_logger is true (allowed)", + cfg: &Config{ + UseInternalLogger: true, + OutputPaths: nil, }, }, } @@ -131,7 +194,7 @@ func TestValidate(t *testing.T) { t.Run(tt.name, func(t *testing.T) { err := tt.cfg.Validate() if tt.expectedErr != "" { - assert.EqualError(t, err, tt.expectedErr) + assert.ErrorContains(t, err, tt.expectedErr) } else { assert.NoError(t, err) } diff --git a/exporter/debugexporter/exporter_test.go b/exporter/debugexporter/exporter_test.go index 367f5f10eeee..fcebf9b9ff2d 100644 --- a/exporter/debugexporter/exporter_test.go +++ b/exporter/debugexporter/exporter_test.go @@ -12,8 +12,10 @@ import ( "github.com/stretchr/testify/require" "go.uber.org/zap/zaptest" + "go.opentelemetry.io/collector/config/configoptional" "go.opentelemetry.io/collector/config/configtelemetry" "go.opentelemetry.io/collector/exporter/debugexporter/internal/metadata" + "go.opentelemetry.io/collector/exporter/exporterhelper" "go.opentelemetry.io/collector/exporter/exportertest" "go.opentelemetry.io/collector/pdata/plog" "go.opentelemetry.io/collector/pdata/pmetric" @@ -111,7 +113,8 @@ func createTestCases() []testCase { name: "default config", config: func() *Config { c := createDefaultConfig().(*Config) - c.QueueConfig.QueueSize = 10 + c.QueueConfig = configoptional.Some(exporterhelper.NewDefaultQueueConfig()) + c.QueueConfig.Get().QueueSize = 10 return c }(), }, @@ -119,11 +122,24 @@ func createTestCases() []testCase { name: "don't use internal logger", config: func() *Config { cfg := createDefaultConfig().(*Config) - cfg.QueueConfig.QueueSize = 10 + cfg.QueueConfig = configoptional.Some(exporterhelper.NewDefaultQueueConfig()) + cfg.QueueConfig.Get().QueueSize = 10 cfg.UseInternalLogger = false return cfg }(), }, + { + name: "custom output paths", + config: func() *Config { + cfg := createDefaultConfig().(*Config) + queueCfg := exporterhelper.NewDefaultQueueConfig() + queueCfg.QueueSize = 10 + cfg.QueueConfig = configoptional.Some(queueCfg) + cfg.UseInternalLogger = false + cfg.OutputPaths = []string{"stderr"} + return cfg + }(), + }, } } diff --git a/exporter/debugexporter/factory.go b/exporter/debugexporter/factory.go index e950d51ba7eb..e181e320f4be 100644 --- a/exporter/debugexporter/factory.go +++ b/exporter/debugexporter/factory.go @@ -11,6 +11,7 @@ import ( "go.uber.org/zap/zapcore" "go.opentelemetry.io/collector/component" + "go.opentelemetry.io/collector/config/configoptional" "go.opentelemetry.io/collector/config/configtelemetry" "go.opentelemetry.io/collector/consumer" "go.opentelemetry.io/collector/exporter" @@ -42,15 +43,12 @@ func NewFactory() exporter.Factory { } func createDefaultConfig() component.Config { - queueCfg := exporterhelper.NewDefaultQueueConfig() - queueCfg.Enabled = false - return &Config{ Verbosity: configtelemetry.LevelBasic, SamplingInitial: defaultSamplingInitial, SamplingThereafter: defaultSamplingThereafter, UseInternalLogger: true, - QueueConfig: queueCfg, + QueueConfig: configoptional.Default(exporterhelper.NewDefaultQueueConfig()), } } @@ -128,6 +126,10 @@ func createCustomLogger(exporterConfig *Config) *zap.Logger { encoderConfig.LevelKey = "" // Do not prefix the output with current timestamp. encoderConfig.TimeKey = "" + outputPaths := exporterConfig.OutputPaths + if outputPaths == nil { + outputPaths = []string{"stdout"} + } zapConfig := zap.Config{ Level: zap.NewAtomicLevelAt(zap.InfoLevel), DisableCaller: true, @@ -137,8 +139,7 @@ func createCustomLogger(exporterConfig *Config) *zap.Logger { }, Encoding: "console", EncoderConfig: encoderConfig, - // Send exporter's output to stdout. This should be made configurable. - OutputPaths: []string{"stdout"}, + OutputPaths: outputPaths, } return zap.Must(zapConfig.Build()) } diff --git a/exporter/debugexporter/factory_test.go b/exporter/debugexporter/factory_test.go index 509228cfb97f..6835d4203ab8 100644 --- a/exporter/debugexporter/factory_test.go +++ b/exporter/debugexporter/factory_test.go @@ -5,12 +5,17 @@ package debugexporter import ( "context" + "os" + "path/filepath" + "runtime" "testing" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + "go.uber.org/zap" "go.opentelemetry.io/collector/component/componenttest" + "go.opentelemetry.io/collector/config/configtelemetry" "go.opentelemetry.io/collector/exporter/exportertest" "go.opentelemetry.io/collector/exporter/xexporter" ) @@ -19,7 +24,13 @@ func TestCreateDefaultConfig(t *testing.T) { factory := NewFactory() cfg := factory.CreateDefaultConfig() assert.NotNil(t, cfg, "failed to create default config") - assert.NoError(t, componenttest.CheckConfigStruct(cfg)) + require.NoError(t, componenttest.CheckConfigStruct(cfg)) + + config := cfg.(*Config) + assert.True(t, config.UseInternalLogger) + // OutputPaths is nil by default (only used when UseInternalLogger is false, + // where it defaults to ["stdout"] in createCustomLogger if not set) + assert.Nil(t, config.OutputPaths) } func TestCreateMetrics(t *testing.T) { @@ -57,3 +68,128 @@ func TestCreateFactoryProfiles(t *testing.T) { require.NoError(t, err) assert.NotNil(t, te) } + +func TestCreateCustomLogger(t *testing.T) { + tests := []struct { + name string + outputPaths []string + }{ + { + name: "stdout", + outputPaths: []string{"stdout"}, + }, + { + name: "stderr", + outputPaths: []string{"stderr"}, + }, + { + name: "multiple paths", + outputPaths: []string{"stdout", "stderr"}, + }, + { + name: "nil defaults to stdout", + outputPaths: nil, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + config := &Config{ + OutputPaths: tt.outputPaths, + SamplingInitial: 2, + SamplingThereafter: 1, + } + logger := createCustomLogger(config) + require.NotNil(t, logger) + logger.Info("test message") + // Sync may return an error for stdout/stderr in test environments + _ = logger.Sync() + }) + } +} + +func TestCreateCustomLoggerWithFileOutput(t *testing.T) { + if runtime.GOOS == "windows" { + t.Skip("Skipping on Windows due to file locking issues with t.TempDir() cleanup") + } + + tmpDir := t.TempDir() + filePath := filepath.Clean(filepath.Join(tmpDir, "debug.log")) + + config := &Config{ + OutputPaths: []string{filePath}, + SamplingInitial: 2, + SamplingThereafter: 1, + } + + logger := createCustomLogger(config) + require.NotNil(t, logger) + + logger.Info("test message to file") + require.NoError(t, logger.Sync()) + + // Verify file was created and contains content + content, err := os.ReadFile(filePath) + require.NoError(t, err) + assert.Contains(t, string(content), "test message to file") +} + +func TestCreateLogger(t *testing.T) { + tests := []struct { + name string + config *Config + }{ + { + name: "use internal logger", + config: &Config{ + UseInternalLogger: true, + SamplingInitial: 2, + SamplingThereafter: 1, + }, + }, + { + name: "use custom logger with stdout", + config: &Config{ + UseInternalLogger: false, + OutputPaths: []string{"stdout"}, + SamplingInitial: 2, + SamplingThereafter: 1, + }, + }, + { + name: "use custom logger with nil output paths defaults to stdout", + config: &Config{ + UseInternalLogger: false, + OutputPaths: nil, + SamplingInitial: 2, + SamplingThereafter: 1, + }, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + baseLogger := zap.NewNop() + logger := createLogger(tt.config, baseLogger) + require.NotNil(t, logger) + logger.Info("test message") + _ = logger.Sync() + }) + } +} + +func TestCreateLoggerWithInternalLogger(t *testing.T) { + config := &Config{ + UseInternalLogger: true, + SamplingInitial: 10, + SamplingThereafter: 50, + Verbosity: configtelemetry.LevelDetailed, + } + + baseLogger := zap.NewNop() + logger := createLogger(config, baseLogger) + require.NotNil(t, logger) + + logger.Info("test message") + _ = logger.Sync() +} diff --git a/exporter/debugexporter/go.mod b/exporter/debugexporter/go.mod index 68ae12f819d3..bbea0bf59c61 100644 --- a/exporter/debugexporter/go.mod +++ b/exporter/debugexporter/go.mod @@ -1,26 +1,27 @@ module go.opentelemetry.io/collector/exporter/debugexporter -go 1.24.0 +go 1.25.0 require ( github.com/stretchr/testify v1.11.1 - go.opentelemetry.io/collector/component v1.46.0 - go.opentelemetry.io/collector/component/componenttest v0.140.0 - go.opentelemetry.io/collector/config/configtelemetry v0.140.0 - go.opentelemetry.io/collector/confmap v1.46.0 - go.opentelemetry.io/collector/consumer v1.46.0 - go.opentelemetry.io/collector/exporter v1.46.0 - go.opentelemetry.io/collector/exporter/exporterhelper v0.140.0 - go.opentelemetry.io/collector/exporter/exporterhelper/xexporterhelper v0.140.0 - go.opentelemetry.io/collector/exporter/exportertest v0.140.0 - go.opentelemetry.io/collector/exporter/xexporter v0.140.0 - go.opentelemetry.io/collector/pdata v1.46.0 - go.opentelemetry.io/collector/pdata/pprofile v0.140.0 - go.opentelemetry.io/collector/pdata/testdata v0.140.0 - go.opentelemetry.io/collector/pdata/xpdata v0.140.0 + go.opentelemetry.io/collector/component v1.54.0 + go.opentelemetry.io/collector/component/componenttest v0.148.0 + go.opentelemetry.io/collector/config/configoptional v1.54.0 + go.opentelemetry.io/collector/config/configtelemetry v0.148.0 + go.opentelemetry.io/collector/confmap v1.54.0 + go.opentelemetry.io/collector/consumer v1.54.0 + go.opentelemetry.io/collector/exporter v1.54.0 + go.opentelemetry.io/collector/exporter/exporterhelper v0.148.0 + go.opentelemetry.io/collector/exporter/exporterhelper/xexporterhelper v0.148.0 + go.opentelemetry.io/collector/exporter/exportertest v0.148.0 + go.opentelemetry.io/collector/exporter/xexporter v0.148.0 + go.opentelemetry.io/collector/pdata v1.54.0 + go.opentelemetry.io/collector/pdata/pprofile v0.148.0 + go.opentelemetry.io/collector/pdata/testdata v0.148.0 + go.opentelemetry.io/collector/pdata/xpdata v0.148.0 go.uber.org/goleak v1.3.0 go.uber.org/zap v1.27.1 - golang.org/x/sys v0.40.0 + golang.org/x/sys v0.41.0 ) require ( @@ -29,14 +30,15 @@ require ( github.com/davecgh/go-spew v1.1.1 // indirect github.com/go-logr/logr v1.4.3 // indirect github.com/go-logr/stdr v1.2.2 // indirect - github.com/go-viper/mapstructure/v2 v2.4.0 // indirect + github.com/go-viper/mapstructure/v2 v2.5.0 // indirect github.com/gobwas/glob v0.2.3 // indirect github.com/google/uuid v1.6.0 // indirect - github.com/hashicorp/go-version v1.7.0 // indirect + github.com/hashicorp/go-version v1.8.0 // indirect + github.com/hashicorp/golang-lru/v2 v2.0.7 // indirect github.com/json-iterator/go v1.1.12 // indirect github.com/knadh/koanf/maps v0.1.2 // indirect github.com/knadh/koanf/providers/confmap v1.0.0 // indirect - github.com/knadh/koanf/v2 v2.3.0 // indirect + github.com/knadh/koanf/v2 v2.3.3 // indirect github.com/mitchellh/copystructure v1.2.0 // indirect github.com/mitchellh/reflectwalk v1.0.2 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect @@ -44,31 +46,31 @@ require ( github.com/pmezard/go-difflib v1.0.0 // indirect go.opentelemetry.io/auto/sdk v1.2.1 // indirect go.opentelemetry.io/collector/client v1.46.0 // indirect - go.opentelemetry.io/collector/config/configoptional v1.46.0 // indirect - go.opentelemetry.io/collector/config/configretry v1.46.0 // indirect - go.opentelemetry.io/collector/confmap/xconfmap v0.140.0 // indirect - go.opentelemetry.io/collector/consumer/consumererror v0.140.0 // indirect + go.opentelemetry.io/collector/config/configretry v1.54.0 // indirect + go.opentelemetry.io/collector/confmap/xconfmap v0.148.0 // indirect + go.opentelemetry.io/collector/consumer/consumererror v0.148.0 // indirect go.opentelemetry.io/collector/consumer/consumererror/xconsumererror v0.140.0 // indirect - go.opentelemetry.io/collector/consumer/consumertest v0.140.0 // indirect - go.opentelemetry.io/collector/consumer/xconsumer v0.140.0 // indirect - go.opentelemetry.io/collector/extension v1.46.0 // indirect + go.opentelemetry.io/collector/consumer/consumertest v0.148.0 // indirect + go.opentelemetry.io/collector/consumer/xconsumer v0.148.0 // indirect + go.opentelemetry.io/collector/extension v1.54.0 // indirect go.opentelemetry.io/collector/extension/xextension v0.140.0 // indirect - go.opentelemetry.io/collector/featuregate v1.46.0 // indirect - go.opentelemetry.io/collector/pipeline v1.46.0 // indirect + go.opentelemetry.io/collector/featuregate v1.54.0 // indirect + go.opentelemetry.io/collector/internal/componentalias v0.148.0 // indirect + go.opentelemetry.io/collector/pipeline v1.54.0 // indirect go.opentelemetry.io/collector/pipeline/xpipeline v0.140.0 // indirect - go.opentelemetry.io/collector/receiver v1.46.0 // indirect - go.opentelemetry.io/collector/receiver/receivertest v0.140.0 // indirect - go.opentelemetry.io/collector/receiver/xreceiver v0.140.0 // indirect - go.opentelemetry.io/otel v1.40.0 // indirect - go.opentelemetry.io/otel/metric v1.40.0 // indirect + go.opentelemetry.io/collector/receiver v1.54.0 // indirect + go.opentelemetry.io/collector/receiver/receivertest v0.148.0 // indirect + go.opentelemetry.io/collector/receiver/xreceiver v0.148.0 // indirect + go.opentelemetry.io/otel v1.42.0 // indirect + go.opentelemetry.io/otel/metric v1.42.0 // indirect go.opentelemetry.io/otel/sdk v1.40.0 // indirect go.opentelemetry.io/otel/sdk/metric v1.40.0 // indirect - go.opentelemetry.io/otel/trace v1.40.0 // indirect + go.opentelemetry.io/otel/trace v1.42.0 // indirect go.uber.org/multierr v1.11.0 // indirect go.yaml.in/yaml/v3 v3.0.4 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20251022142026-3a174f9686a8 // indirect - google.golang.org/grpc v1.77.0 // indirect - google.golang.org/protobuf v1.36.10 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20251222181119-0a764e51fe1b // indirect + google.golang.org/grpc v1.79.3 // indirect + google.golang.org/protobuf v1.36.11 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) @@ -135,3 +137,5 @@ replace go.opentelemetry.io/collector/confmap/xconfmap => ../../confmap/xconfmap replace go.opentelemetry.io/collector/exporter/exporterhelper => ../exporterhelper replace go.opentelemetry.io/collector/internal/testutil => ../../internal/testutil + +replace go.opentelemetry.io/collector/internal/componentalias => ../../internal/componentalias diff --git a/exporter/debugexporter/go.sum b/exporter/debugexporter/go.sum index d3c35ba1cbd6..d6e38a64eac0 100644 --- a/exporter/debugexporter/go.sum +++ b/exporter/debugexporter/go.sum @@ -10,8 +10,8 @@ github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI= github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= -github.com/go-viper/mapstructure/v2 v2.4.0 h1:EBsztssimR/CONLSZZ04E8qAkxNYq4Qp9LvH92wZUgs= -github.com/go-viper/mapstructure/v2 v2.4.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM= +github.com/go-viper/mapstructure/v2 v2.5.0 h1:vM5IJoUAy3d7zRSVtIwQgBj7BiWtMPfmPEgAXnvj1Ro= +github.com/go-viper/mapstructure/v2 v2.5.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM= github.com/gobwas/glob v0.2.3 h1:A4xDbljILXROh+kObIiy5kIaPYD8e96x1tgBhUI5J+Y= github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8= github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= @@ -21,16 +21,18 @@ github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/hashicorp/go-version v1.7.0 h1:5tqGy27NaOTB8yJKUZELlFAS/LTKJkrmONwQKeRZfjY= -github.com/hashicorp/go-version v1.7.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= +github.com/hashicorp/go-version v1.8.0 h1:KAkNb1HAiZd1ukkxDFGmokVZe1Xy9HG6NUp+bPle2i4= +github.com/hashicorp/go-version v1.8.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= +github.com/hashicorp/golang-lru/v2 v2.0.7 h1:a+bsQ5rvGLjzHuww6tVxozPZFVghXaHOwFs4luLUK2k= +github.com/hashicorp/golang-lru/v2 v2.0.7/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyfM2/ZepoAG6RGpeM= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= github.com/knadh/koanf/maps v0.1.2 h1:RBfmAW5CnZT+PJ1CVc1QSJKf4Xu9kxfQgYVQSu8hpbo= github.com/knadh/koanf/maps v0.1.2/go.mod h1:npD/QZY3V6ghQDdcQzl1W4ICNVTkohC8E73eI2xW4yI= github.com/knadh/koanf/providers/confmap v1.0.0 h1:mHKLJTE7iXEys6deO5p6olAiZdG5zwp8Aebir+/EaRE= github.com/knadh/koanf/providers/confmap v1.0.0/go.mod h1:txHYHiI2hAtF0/0sCmcuol4IDcuQbKTybiB1nOcUo1A= -github.com/knadh/koanf/v2 v2.3.0 h1:Qg076dDRFHvqnKG97ZEsi9TAg2/nFTa9hCdcSa1lvlM= -github.com/knadh/koanf/v2 v2.3.0/go.mod h1:gRb40VRAbd4iJMYYD5IxZ6hfuopFcXBpc9bbQpZwo28= +github.com/knadh/koanf/v2 v2.3.3 h1:jLJC8XCRfLC7n4F+ZKKdBsbq1bfXTpuFhf4L7t94D94= +github.com/knadh/koanf/v2 v2.3.3/go.mod h1:gRb40VRAbd4iJMYYD5IxZ6hfuopFcXBpc9bbQpZwo28= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= @@ -55,22 +57,22 @@ github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64= go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y= -go.opentelemetry.io/otel v1.40.0 h1:oA5YeOcpRTXq6NN7frwmwFR0Cn3RhTVZvXsP4duvCms= -go.opentelemetry.io/otel v1.40.0/go.mod h1:IMb+uXZUKkMXdPddhwAHm6UfOwJyh4ct1ybIlV14J0g= -go.opentelemetry.io/otel/metric v1.40.0 h1:rcZe317KPftE2rstWIBitCdVp89A2HqjkxR3c11+p9g= -go.opentelemetry.io/otel/metric v1.40.0/go.mod h1:ib/crwQH7N3r5kfiBZQbwrTge743UDc7DTFVZrrXnqc= +go.opentelemetry.io/otel v1.42.0 h1:lSQGzTgVR3+sgJDAU/7/ZMjN9Z+vUip7leaqBKy4sho= +go.opentelemetry.io/otel v1.42.0/go.mod h1:lJNsdRMxCUIWuMlVJWzecSMuNjE7dOYyWlqOXWkdqCc= +go.opentelemetry.io/otel/metric v1.42.0 h1:2jXG+3oZLNXEPfNmnpxKDeZsFI5o4J+nz6xUlaFdF/4= +go.opentelemetry.io/otel/metric v1.42.0/go.mod h1:RlUN/7vTU7Ao/diDkEpQpnz3/92J9ko05BIwxYa2SSI= go.opentelemetry.io/otel/sdk v1.40.0 h1:KHW/jUzgo6wsPh9At46+h4upjtccTmuZCFAc9OJ71f8= go.opentelemetry.io/otel/sdk v1.40.0/go.mod h1:Ph7EFdYvxq72Y8Li9q8KebuYUr2KoeyHx0DRMKrYBUE= go.opentelemetry.io/otel/sdk/metric v1.40.0 h1:mtmdVqgQkeRxHgRv4qhyJduP3fYJRMX4AtAlbuWdCYw= go.opentelemetry.io/otel/sdk/metric v1.40.0/go.mod h1:4Z2bGMf0KSK3uRjlczMOeMhKU2rhUqdWNoKcYrtcBPg= -go.opentelemetry.io/otel/trace v1.40.0 h1:WA4etStDttCSYuhwvEa8OP8I5EWu24lkOzp+ZYblVjw= -go.opentelemetry.io/otel/trace v1.40.0/go.mod h1:zeAhriXecNGP/s2SEG3+Y8X9ujcJOTqQ5RgdEJcawiA= -go.opentelemetry.io/proto/slim/otlp v1.9.0 h1:fPVMv8tP3TrsqlkH1HWYUpbCY9cAIemx184VGkS6vlE= -go.opentelemetry.io/proto/slim/otlp v1.9.0/go.mod h1:xXdeJJ90Gqyll+orzUkY4bOd2HECo5JofeoLpymVqdI= -go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.2.0 h1:o13nadWDNkH/quoDomDUClnQBpdQQ2Qqv0lQBjIXjE8= -go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.2.0/go.mod h1:Gyb6Xe7FTi/6xBHwMmngGoHqL0w29Y4eW8TGFzpefGA= -go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.2.0 h1:EiUYvtwu6PMrMHVjcPfnsG3v+ajPkbUeH+IL93+QYyk= -go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.2.0/go.mod h1:mUUHKFiN2SST3AhJ8XhJxEoeVW12oqfXog0Bo8W3Ec4= +go.opentelemetry.io/otel/trace v1.42.0 h1:OUCgIPt+mzOnaUTpOQcBiM/PLQ/Op7oq6g4LenLmOYY= +go.opentelemetry.io/otel/trace v1.42.0/go.mod h1:f3K9S+IFqnumBkKhRJMeaZeNk9epyhnCmQh/EysQCdc= +go.opentelemetry.io/proto/slim/otlp v1.10.0 h1:iR97Vs/ZDR+y9TfuP9b1XBtdPWeC+OMslIBmhcLU7jM= +go.opentelemetry.io/proto/slim/otlp v1.10.0/go.mod h1:lV9250stpjYLPNA5viFabIgP2QlUGRT1GdTgAf8SIUk= +go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.3.0 h1:RUF5rO0hAlgiJt1fzQVzcVs3vZVNHIcMLgOgG4rWNcQ= +go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.3.0/go.mod h1:I89cynRj8y+383o7tEQVg2SVA6SRgDVIouWPUVXjx0U= +go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.3.0 h1:CQvJSldHRUN6Z8jsUeYv8J0lXRvygALXIzsmAeCcZE0= +go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.3.0/go.mod h1:xSQ+mEfJe/GjK1LXEyVOoSI1N9JV9ZI923X5kup43W4= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= @@ -79,18 +81,18 @@ go.uber.org/zap v1.27.1 h1:08RqriUEv8+ArZRYSTXy1LeBScaMpVSTBhCeaZYfMYc= go.uber.org/zap v1.27.1/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc= go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg= -golang.org/x/net v0.46.1-0.20251013234738-63d1a5100f82 h1:6/3JGEh1C88g7m+qzzTbl3A0FtsLguXieqofVLU/JAo= -golang.org/x/net v0.46.1-0.20251013234738-63d1a5100f82/go.mod h1:Q9BGdFy1y4nkUwiLvT5qtyhAnEHgnQ/zd8PfU6nc210= -golang.org/x/sys v0.40.0 h1:DBZZqJ2Rkml6QMQsZywtnjnnGvHza6BTfYFWY9kjEWQ= -golang.org/x/sys v0.40.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= -golang.org/x/text v0.30.0 h1:yznKA/E9zq54KzlzBEAWn1NXSQ8DIp/NYMy88xJjl4k= -golang.org/x/text v0.30.0/go.mod h1:yDdHFIX9t+tORqspjENWgzaCVXgk0yYnYuSZ8UzzBVM= -google.golang.org/genproto/googleapis/rpc v0.0.0-20251022142026-3a174f9686a8 h1:M1rk8KBnUsBDg1oPGHNCxG4vc1f49epmTO7xscSajMk= -google.golang.org/genproto/googleapis/rpc v0.0.0-20251022142026-3a174f9686a8/go.mod h1:7i2o+ce6H/6BluujYR+kqX3GKH+dChPTQU19wjRPiGk= -google.golang.org/grpc v1.77.0 h1:wVVY6/8cGA6vvffn+wWK5ToddbgdU3d8MNENr4evgXM= -google.golang.org/grpc v1.77.0/go.mod h1:z0BY1iVj0q8E1uSQCjL9cppRj+gnZjzDnzV0dHhrNig= -google.golang.org/protobuf v1.36.10 h1:AYd7cD/uASjIL6Q9LiTjz8JLcrh/88q5UObnmY3aOOE= -google.golang.org/protobuf v1.36.10/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= +golang.org/x/net v0.51.0 h1:94R/GTO7mt3/4wIKpcR5gkGmRLOuE/2hNGeWq/GBIFo= +golang.org/x/net v0.51.0/go.mod h1:aamm+2QF5ogm02fjy5Bb7CQ0WMt1/WVM7FtyaTLlA9Y= +golang.org/x/sys v0.41.0 h1:Ivj+2Cp/ylzLiEU89QhWblYnOE9zerudt9Ftecq2C6k= +golang.org/x/sys v0.41.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= +golang.org/x/text v0.34.0 h1:oL/Qq0Kdaqxa1KbNeMKwQq0reLCCaFtqu2eNuSeNHbk= +golang.org/x/text v0.34.0/go.mod h1:homfLqTYRFyVYemLBFl5GgL/DWEiH5wcsQ5gSh1yziA= +google.golang.org/genproto/googleapis/rpc v0.0.0-20251222181119-0a764e51fe1b h1:Mv8VFug0MP9e5vUxfBcE3vUkV6CImK3cMNMIDFjmzxU= +google.golang.org/genproto/googleapis/rpc v0.0.0-20251222181119-0a764e51fe1b/go.mod h1:j9x/tPzZkyxcgEFkiKEEGxfvyumM01BEtsW8xzOahRQ= +google.golang.org/grpc v1.79.3 h1:sybAEdRIEtvcD68Gx7dmnwjZKlyfuc61Dyo9pGXXkKE= +google.golang.org/grpc v1.79.3/go.mod h1:KmT0Kjez+0dde/v2j9vzwoAScgEPx/Bw1CYChhHLrHQ= +google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE= +google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= diff --git a/exporter/debugexporter/internal/normal/metrics.go b/exporter/debugexporter/internal/normal/metrics.go index 01bdc8405b87..86d2a9cc6dab 100644 --- a/exporter/debugexporter/internal/normal/metrics.go +++ b/exporter/debugexporter/internal/normal/metrics.go @@ -6,6 +6,7 @@ package normal // import "go.opentelemetry.io/collector/exporter/debugexporter/i import ( "bytes" "fmt" + "math" "strconv" "strings" @@ -115,21 +116,39 @@ func writeExponentialHistogramDataPoints(metric pmetric.Metric) (lines []string) dataPoint := metric.ExponentialHistogram().DataPoints().At(i) dataPointAttributes := writeAttributes(dataPoint.Attributes()) - var value string - value = fmt.Sprintf("count=%d", dataPoint.Count()) + var value strings.Builder + fmt.Fprintf(&value, "count=%d", dataPoint.Count()) if dataPoint.HasSum() { - value += fmt.Sprintf(" sum=%v", dataPoint.Sum()) + fmt.Fprintf(&value, " sum=%v", dataPoint.Sum()) } if dataPoint.HasMin() { - value += fmt.Sprintf(" min=%v", dataPoint.Min()) + fmt.Fprintf(&value, " min=%v", dataPoint.Min()) } if dataPoint.HasMax() { - value += fmt.Sprintf(" max=%v", dataPoint.Max()) + fmt.Fprintf(&value, " max=%v", dataPoint.Max()) } - // TODO display buckets + factor := math.Ldexp(math.Ln2, -int(dataPoint.Scale())) - dataPointLine := fmt.Sprintf("%s{%s} %s\n", metric.Name(), strings.Join(dataPointAttributes, ","), value) + negB := dataPoint.Negative() + for j := negB.BucketCounts().Len() - 1; j >= 0; j-- { + index := float64(negB.Offset()) + float64(j) + upperBound := -math.Exp(index * factor) + fmt.Fprintf(&value, " le%v=%d", upperBound, negB.BucketCounts().At(j)) + } + + if dataPoint.ZeroCount() != 0 { + fmt.Fprintf(&value, " zero=%d", dataPoint.ZeroCount()) + } + + posB := dataPoint.Positive() + for j := 0; j < posB.BucketCounts().Len(); j++ { + index := float64(posB.Offset()) + float64(j) + upperBound := math.Exp((index + 1) * factor) + fmt.Fprintf(&value, " le%v=%d", upperBound, posB.BucketCounts().At(j)) + } + + dataPointLine := fmt.Sprintf("%s{%s} %s\n", metric.Name(), strings.Join(dataPointAttributes, ","), value.String()) lines = append(lines, dataPointLine) } return lines diff --git a/exporter/debugexporter/internal/normal/metrics_test.go b/exporter/debugexporter/internal/normal/metrics_test.go index c82c3a390538..9901bc175d0b 100644 --- a/exporter/debugexporter/internal/normal/metrics_test.go +++ b/exporter/debugexporter/internal/normal/metrics_test.go @@ -4,6 +4,8 @@ package normal import ( + "fmt" + "math" "testing" "github.com/stretchr/testify/assert" @@ -107,7 +109,7 @@ http.server.request.duration{http.response.status_code=200,http.request.method=G `, }, { - name: "exponential histogram", + name: "exponential histogram without buckets", input: func() pmetric.Metrics { metrics := pmetric.NewMetrics() metric := metrics.ResourceMetrics().AppendEmpty().ScopeMetrics().AppendEmpty().Metrics().AppendEmpty() @@ -126,6 +128,57 @@ ScopeMetrics #0 http.server.request.duration{http.response.status_code=200,http.request.method=GET} count=1340 sum=99.573 min=0.017 max=8.13 `, }, + { + name: "exponential histogram with buckets", + input: func() pmetric.Metrics { + metrics := pmetric.NewMetrics() + metric := metrics.ResourceMetrics().AppendEmpty().ScopeMetrics().AppendEmpty().Metrics().AppendEmpty() + metric.SetName("http.server.request.duration") + dataPoint := metric.SetEmptyExponentialHistogram().DataPoints().AppendEmpty() + dataPoint.Attributes().PutInt("http.response.status_code", 200) + dataPoint.Attributes().PutStr("http.request.method", "GET") + dataPoint.SetCount(1340) + dataPoint.SetSum(99.573) + dataPoint.SetMin(0.017) + dataPoint.SetMax(8.13) + dataPoint.SetScale(3) + dataPoint.SetZeroCount(3) + dataPoint.Negative().SetOffset(-2) + dataPoint.Negative().BucketCounts().FromRaw([]uint64{10, 20}) + dataPoint.Positive().SetOffset(1) + dataPoint.Positive().BucketCounts().FromRaw([]uint64{40, 50, 60}) + return metrics + }(), + expected: func() string { + f := math.Ldexp(math.Ln2, -3) + return fmt.Sprintf("ResourceMetrics #0\nScopeMetrics #0\n"+ + "http.server.request.duration{http.response.status_code=200,http.request.method=GET}"+ + " count=1340 sum=99.573 min=0.017 max=8.13"+ + " le%v=20 le%v=10 zero=3 le%v=40 le%v=50 le%v=60\n", + -math.Exp(-1*f), -math.Exp(-2*f), + math.Exp(2*f), math.Exp(3*f), math.Exp(4*f)) + }(), + }, + { + name: "exponential histogram with positive buckets only", + input: func() pmetric.Metrics { + metrics := pmetric.NewMetrics() + metric := metrics.ResourceMetrics().AppendEmpty().ScopeMetrics().AppendEmpty().Metrics().AppendEmpty() + metric.SetName("latency") + dataPoint := metric.SetEmptyExponentialHistogram().DataPoints().AppendEmpty() + dataPoint.SetCount(2) + dataPoint.SetScale(1) + dataPoint.Positive().SetOffset(1) + dataPoint.Positive().BucketCounts().FromRaw([]uint64{1, 1}) + return metrics + }(), + expected: func() string { + f := math.Ldexp(math.Ln2, -1) + return fmt.Sprintf("ResourceMetrics #0\nScopeMetrics #0\n"+ + "latency{} count=2 le%v=1 le%v=1\n", + math.Exp(2*f), math.Exp(3*f)) + }(), + }, { name: "summary", input: func() pmetric.Metrics { diff --git a/exporter/debugexporter/internal/otlptext/databuffer.go b/exporter/debugexporter/internal/otlptext/databuffer.go index 67b92b103b79..81ed35b41f57 100644 --- a/exporter/debugexporter/internal/otlptext/databuffer.go +++ b/exporter/debugexporter/internal/otlptext/databuffer.go @@ -116,6 +116,7 @@ func (b *dataBuffer) logMetricDescriptor(md pmetric.Metric) { b.logEntry(" -> Description: %s", md.Description()) b.logEntry(" -> Unit: %s", md.Unit()) b.logEntry(" -> DataType: %s", md.Type().String()) + b.logAttributes(" -> Metadata", md.Metadata()) } func (b *dataBuffer) logMetricDataPoints(m pmetric.Metric) { diff --git a/exporter/debugexporter/internal/otlptext/metrics_test.go b/exporter/debugexporter/internal/otlptext/metrics_test.go index 1d2b26c3ffdc..7048e2d0d8cc 100644 --- a/exporter/debugexporter/internal/otlptext/metrics_test.go +++ b/exporter/debugexporter/internal/otlptext/metrics_test.go @@ -47,6 +47,11 @@ func TestMetricsText(t *testing.T) { in: generateMetricsWithEntityRefs(), out: "metrics_with_entity_refs.out", }, + { + name: "metrics_with_metadata", + in: generateMetricsWithMetadata(), + out: "metrics_with_metadata.out", + }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { @@ -80,3 +85,26 @@ func generateMetricsWithEntityRefs() pmetric.Metrics { return md } + +func generateMetricsWithMetadata() pmetric.Metrics { + md := pmetric.NewMetrics() + rm := md.ResourceMetrics().AppendEmpty() + rm.Resource().Attributes().PutStr("service.name", "test-service") + + sm := rm.ScopeMetrics().AppendEmpty() + sm.Scope().SetName("test-scope") + + metric := sm.Metrics().AppendEmpty() + metric.SetName("test-metric-metadata") + metric.SetDescription("A test metric with metadata") + metric.SetUnit("1") + + metric.Metadata().PutStr("meta.key", "meta-value") + metric.Metadata().PutInt("meta.id", 101) + + gauge := metric.SetEmptyGauge() + dp := gauge.DataPoints().AppendEmpty() + dp.SetIntValue(1) + + return md +} diff --git a/exporter/debugexporter/internal/otlptext/testdata/metrics/metrics_with_metadata.out b/exporter/debugexporter/internal/otlptext/testdata/metrics/metrics_with_metadata.out new file mode 100644 index 000000000000..4e2430fd0eaa --- /dev/null +++ b/exporter/debugexporter/internal/otlptext/testdata/metrics/metrics_with_metadata.out @@ -0,0 +1,20 @@ +ResourceMetrics #0 +Resource SchemaURL: +Resource attributes: + -> service.name: Str(test-service) +ScopeMetrics #0 +ScopeMetrics SchemaURL: +InstrumentationScope test-scope +Metric #0 +Descriptor: + -> Name: test-metric-metadata + -> Description: A test metric with metadata + -> Unit: 1 + -> DataType: Gauge + -> Metadata: + -> meta.key: Str(meta-value) + -> meta.id: Int(101) +NumberDataPoints #0 +StartTimestamp: 1970-01-01 00:00:00 +0000 UTC +Timestamp: 1970-01-01 00:00:00 +0000 UTC +Value: 1 diff --git a/exporter/debugexporter/internal/otlptext/testdata/profiles/two_profiles.out b/exporter/debugexporter/internal/otlptext/testdata/profiles/two_profiles.out index e3493a3a3738..c9d138a0a693 100644 --- a/exporter/debugexporter/internal/otlptext/testdata/profiles/two_profiles.out +++ b/exporter/debugexporter/internal/otlptext/testdata/profiles/two_profiles.out @@ -52,7 +52,7 @@ Profile #0 Sample #0 Values: [4] Attributes: - -> key: value + -> key: value-1 Profile #1 Profile ID : 0202030405060708090a0b0c0d0e0f10 Start time : 2020-02-11 20:26:12.000000321 +0000 UTC @@ -61,4 +61,4 @@ Profile #1 Sample #0 Values: [9] Attributes: - -> key: value + -> key: value-2 diff --git a/exporter/debugexporter/internal/otlptext/testdata/traces/traces_with_entity_refs.out b/exporter/debugexporter/internal/otlptext/testdata/traces/traces_with_entity_refs.out index 88b5e40568a1..bf3053307de0 100644 --- a/exporter/debugexporter/internal/otlptext/testdata/traces/traces_with_entity_refs.out +++ b/exporter/debugexporter/internal/otlptext/testdata/traces/traces_with_entity_refs.out @@ -29,3 +29,6 @@ Span #0 End time : 1970-01-01 00:00:00 +0000 UTC Status code : Unset Status message : + DroppedAttributesCount: 0 + DroppedEventsCount: 0 + DroppedLinksCount: 0 diff --git a/exporter/debugexporter/internal/otlptext/testdata/traces/two_spans.out b/exporter/debugexporter/internal/otlptext/testdata/traces/two_spans.out index 9cb3ac750387..e4f3bfd203ee 100644 --- a/exporter/debugexporter/internal/otlptext/testdata/traces/two_spans.out +++ b/exporter/debugexporter/internal/otlptext/testdata/traces/two_spans.out @@ -16,6 +16,9 @@ Span #0 End time : 2020-02-11 20:26:13.000000789 +0000 UTC Status code : Error Status message : status-cancelled + DroppedAttributesCount: 1 + DroppedEventsCount: 1 + DroppedLinksCount: 0 Events: SpanEvent #0 -> Name: event-with-attr @@ -37,6 +40,9 @@ Span #1 End time : 2020-02-11 20:26:13.000000789 +0000 UTC Status code : Unset Status message : + DroppedAttributesCount: 0 + DroppedEventsCount: 0 + DroppedLinksCount: 3 Links: SpanLink #0 -> Trace ID: diff --git a/exporter/debugexporter/internal/otlptext/traces.go b/exporter/debugexporter/internal/otlptext/traces.go index 190bab5dcd1c..4058493842e7 100644 --- a/exporter/debugexporter/internal/otlptext/traces.go +++ b/exporter/debugexporter/internal/otlptext/traces.go @@ -4,6 +4,8 @@ package otlptext // import "go.opentelemetry.io/collector/exporter/debugexporter/internal/otlptext" import ( + "strconv" + "go.opentelemetry.io/collector/pdata/ptrace" ) @@ -49,6 +51,10 @@ func (textTracesMarshaler) MarshalTraces(td ptrace.Traces) ([]byte, error) { buf.logAttr("Status code", span.Status().Code().String()) buf.logAttr("Status message", span.Status().Message()) + buf.logAttr("DroppedAttributesCount", strconv.FormatUint(uint64(span.DroppedAttributesCount()), 10)) + buf.logAttr("DroppedEventsCount", strconv.FormatUint(uint64(span.DroppedEventsCount()), 10)) + buf.logAttr("DroppedLinksCount", strconv.FormatUint(uint64(span.DroppedLinksCount()), 10)) + buf.logAttributes("Attributes", span.Attributes()) buf.logEvents("Events", span.Events()) buf.logLinks("Links", span.Links()) diff --git a/exporter/debugexporter/metadata.yaml b/exporter/debugexporter/metadata.yaml index 73d94988532f..8c7f219c470f 100644 --- a/exporter/debugexporter/metadata.yaml +++ b/exporter/debugexporter/metadata.yaml @@ -1,3 +1,4 @@ +display_name: Debug Exporter type: debug github_project: open-telemetry/opentelemetry-collector diff --git a/exporter/debugexporter/testdata/config_output_paths.yaml b/exporter/debugexporter/testdata/config_output_paths.yaml new file mode 100644 index 000000000000..d47368b79ea5 --- /dev/null +++ b/exporter/debugexporter/testdata/config_output_paths.yaml @@ -0,0 +1,4 @@ +use_internal_logger: false +output_paths: + - stderr + diff --git a/exporter/debugexporter/testdata/config_output_paths_empty.yaml b/exporter/debugexporter/testdata/config_output_paths_empty.yaml new file mode 100644 index 000000000000..af6c8bfa7015 --- /dev/null +++ b/exporter/debugexporter/testdata/config_output_paths_empty.yaml @@ -0,0 +1,3 @@ +use_internal_logger: false +output_paths: [] + diff --git a/exporter/debugexporter/testdata/config_verbosity.yaml b/exporter/debugexporter/testdata/config_verbosity.yaml index 682c45f73d4b..25508073793c 100644 --- a/exporter/debugexporter/testdata/config_verbosity.yaml +++ b/exporter/debugexporter/testdata/config_verbosity.yaml @@ -2,3 +2,5 @@ verbosity: detailed sampling_initial: 10 sampling_thereafter: 50 use_internal_logger: false +output_paths: + - stdout diff --git a/exporter/example_test.go b/exporter/example_test.go index 9a21c4056097..a605423cd1b9 100644 --- a/exporter/example_test.go +++ b/exporter/example_test.go @@ -10,6 +10,7 @@ import ( "go.uber.org/zap" "go.opentelemetry.io/collector/component" + "go.opentelemetry.io/collector/config/configoptional" "go.opentelemetry.io/collector/config/configretry" "go.opentelemetry.io/collector/consumer" "go.opentelemetry.io/collector/exporter" @@ -22,7 +23,7 @@ var typeStr = component.MustNewType("example") // exampleConfig holds configuration settings for the exporter. type exampleConfig struct { - QueueSettings exporterhelper.QueueBatchConfig + QueueSettings configoptional.Optional[exporterhelper.QueueBatchConfig] BackOffConfig configretry.BackOffConfig } diff --git a/exporter/exporter.go b/exporter/exporter.go index 2df5ab6853bc..7bb908c8200d 100644 --- a/exporter/exporter.go +++ b/exporter/exporter.go @@ -8,7 +8,7 @@ import ( "go.opentelemetry.io/collector/component" "go.opentelemetry.io/collector/consumer" - "go.opentelemetry.io/collector/exporter/internal/experr" + "go.opentelemetry.io/collector/internal/componentalias" "go.opentelemetry.io/collector/pipeline" ) @@ -105,6 +105,7 @@ type CreateLogsFunc func(context.Context, Settings, component.Config) (Logs, err type factory struct { cfgType component.Type component.CreateDefaultConfigFunc + componentalias.TypeAliasHolder createTracesFunc CreateTracesFunc tracesStabilityLevel component.StabilityLevel createMetricsFunc CreateMetricsFunc @@ -136,8 +137,8 @@ func (f *factory) CreateTraces(ctx context.Context, set Settings, cfg component. return nil, pipeline.ErrSignalNotSupported } - if set.ID.Type() != f.Type() { - return nil, experr.ErrIDMismatch(set.ID, f.Type()) + if err := componentalias.ValidateComponentType(f, set.ID); err != nil { + return nil, err } return f.createTracesFunc(ctx, set, cfg) @@ -148,8 +149,8 @@ func (f *factory) CreateMetrics(ctx context.Context, set Settings, cfg component return nil, pipeline.ErrSignalNotSupported } - if set.ID.Type() != f.Type() { - return nil, experr.ErrIDMismatch(set.ID, f.Type()) + if err := componentalias.ValidateComponentType(f, set.ID); err != nil { + return nil, err } return f.createMetricsFunc(ctx, set, cfg) @@ -160,8 +161,8 @@ func (f *factory) CreateLogs(ctx context.Context, set Settings, cfg component.Co return nil, pipeline.ErrSignalNotSupported } - if set.ID.Type() != f.Type() { - return nil, experr.ErrIDMismatch(set.ID, f.Type()) + if err := componentalias.ValidateComponentType(f, set.ID); err != nil { + return nil, err } return f.createLogsFunc(ctx, set, cfg) @@ -196,6 +197,7 @@ func NewFactory(cfgType component.Type, createDefaultConfig component.CreateDefa f := &factory{ cfgType: cfgType, CreateDefaultConfigFunc: createDefaultConfig, + TypeAliasHolder: componentalias.NewTypeAliasHolder(), } for _, opt := range options { opt.applyOption(f) diff --git a/exporter/exporterhelper/README.md b/exporter/exporterhelper/README.md index 4652383c6a25..02ed231f9864 100644 --- a/exporter/exporterhelper/README.md +++ b/exporter/exporterhelper/README.md @@ -30,6 +30,12 @@ The following configuration options can be modified: - `queue_size` (default = 1000): Maximum size the queue can accept. Measured in units defined by `sizer` - `batch`: see below. +**Failure behavior**: If data cannot be added to the sending queue, it is typically dropped. This occurs when the queue has reached its configured capacity or, for persistent queues, when the underlying storage cannot accept additional data (for example, due to insufficient disk space or I/O errors). + +When `block_on_overflow` is enabled, the caller may instead wait until space becomes available, and the request may still be enqueued if capacity frees up before the timeout. + +If data is rejected before entering the queue, it does not reach the exporter retry logic. Such enqueue failures are reported by the `otelcol_exporter_enqueue_failed_*` metrics. + #### Sending queue batch settings Batch settings are available in the sending queue. Batching is disabled, by default. To enable default @@ -39,6 +45,7 @@ batch settings, use `batch: {}`. When `batch` is defined, the settings are: - `min_size` (default = 8192): the minimum size of a batch; should be less than or equal to the `sending_queue::queue_size` if `sending_queue::batch::sizer` matches `sending_queue::sizer`. - `max_size` (default = 0): the maximum size of a batch, enables batch splitting. The maximum size of a batch should be greater than or equal to the minimum size of a batch. If set to zero, there is no maximum size; - `sizer`: see below. +- `partition`: see below. The `batch::sizer` field is given special treatment because the queue itself also defines a `sizer`. This field supports using different size limits for the queue and batch-related logic. @@ -50,6 +57,16 @@ Available `batch::sizer` options: - `items`: number of the smallest parts of each signal (spans, metric data points, log records); - `bytes`: the size of serialized data in bytes (the least performant option). + +The `batch::partition` configuration defines the partitioning of the batches. + +Available `batch::partition` options: + +- `metadata_keys`: a list of `client.Metadata` keys used to partition data into + separate batches. When empty, a single batcher instance is used. When set, one batcher will be used + per distinct combination of values for the listed metadata keys. Empty value and unset metadata are + treated as distinct cases. Entries are case-insensitive. Duplicated entries will trigger a validation error. Default is empty. + ### Timeout - `timeout` (default = 5s): Time to wait per individual attempt to send data to a backend @@ -116,7 +133,7 @@ receivers: protocols: grpc: exporters: - otlp: + otlp_grpc: endpoint: sending_queue: storage: file_storage/otc diff --git a/exporter/exporterhelper/config.schema.yaml b/exporter/exporterhelper/config.schema.yaml new file mode 100644 index 000000000000..e3f50a147b86 --- /dev/null +++ b/exporter/exporterhelper/config.schema.yaml @@ -0,0 +1,14 @@ +$defs: + batch_config: + description: BatchConfig defines a configuration for batching requests based on a timeout and a minimum number of items. + $ref: ./internal/queuebatch.batch_config + option: + description: Option apply changes to BaseExporter. + $ref: ./internal.option + queue_batch_config: + description: QueueBatchConfig defines configuration for queueing and batching for the exporter. + $ref: ./internal/queuebatch.config + request_sizer_type: + $ref: ./internal/request.sizer_type + timeout_config: + $ref: ./internal.timeout_config diff --git a/exporter/exporterhelper/documentation.md b/exporter/exporterhelper/documentation.md index 095309bed21f..dc2dd66bc317 100644 --- a/exporter/exporterhelper/documentation.md +++ b/exporter/exporterhelper/documentation.md @@ -8,39 +8,47 @@ The following telemetry is emitted by this component. ### otelcol_exporter_enqueue_failed_log_records -Number of log records failed to be added to the sending queue. [Alpha] +Number of log records failed to be added to the sending queue. | Unit | Metric Type | Value Type | Monotonic | Stability | | ---- | ----------- | ---------- | --------- | --------- | -| {records} | Sum | Int | true | Alpha | +| {record} | Sum | Int | true | Alpha | ### otelcol_exporter_enqueue_failed_metric_points -Number of metric points failed to be added to the sending queue. [Alpha] +Number of metric points failed to be added to the sending queue. | Unit | Metric Type | Value Type | Monotonic | Stability | | ---- | ----------- | ---------- | --------- | --------- | -| {datapoints} | Sum | Int | true | Alpha | +| {datapoint} | Sum | Int | true | Alpha | + +### otelcol_exporter_enqueue_failed_profile_samples + +Number of profile samples failed to be added to the sending queue. + +| Unit | Metric Type | Value Type | Monotonic | Stability | +| ---- | ----------- | ---------- | --------- | --------- | +| {sample} | Sum | Int | true | Development | ### otelcol_exporter_enqueue_failed_spans -Number of spans failed to be added to the sending queue. [Alpha] +Number of spans failed to be added to the sending queue. | Unit | Metric Type | Value Type | Monotonic | Stability | | ---- | ----------- | ---------- | --------- | --------- | -| {spans} | Sum | Int | true | Alpha | +| {span} | Sum | Int | true | Alpha | ### otelcol_exporter_queue_batch_send_size -Number of units in the batch [Development] +Number of units in the batch | Unit | Metric Type | Value Type | Stability | | ---- | ----------- | ---------- | --------- | -| {units} | Histogram | Int | Development | +| {unit} | Histogram | Int | Development | ### otelcol_exporter_queue_batch_send_size_bytes -Number of bytes in batch that was sent. Only available on detailed level. [Development] +Number of bytes in batch that was sent. Only available on detailed level. | Unit | Metric Type | Value Type | Stability | | ---- | ----------- | ---------- | --------- | @@ -48,64 +56,90 @@ Number of bytes in batch that was sent. Only available on detailed level. [Devel ### otelcol_exporter_queue_capacity -Fixed capacity of the retry queue (in batches). [Alpha] +Fixed capacity of the retry queue (in batches). | Unit | Metric Type | Value Type | Stability | | ---- | ----------- | ---------- | --------- | -| {batches} | Gauge | Int | Alpha | +| {batch} | Gauge | Int | Alpha | ### otelcol_exporter_queue_size -Current size of the retry queue (in batches). [Alpha] +Current size of the retry queue (in batches). | Unit | Metric Type | Value Type | Stability | | ---- | ----------- | ---------- | --------- | -| {batches} | Gauge | Int | Alpha | +| {batch} | Gauge | Int | Alpha | ### otelcol_exporter_send_failed_log_records -Number of log records in failed attempts to send to destination. [Alpha] +Number of log records in failed attempts to send to destination. At detailed telemetry level, includes attributes: error.type (semantic convention), error.permanent. | Unit | Metric Type | Value Type | Monotonic | Stability | | ---- | ----------- | ---------- | --------- | --------- | -| {records} | Sum | Int | true | Alpha | +| {record} | Sum | Int | true | Alpha | ### otelcol_exporter_send_failed_metric_points -Number of metric points in failed attempts to send to destination. [Alpha] +Number of metric points in failed attempts to send to destination. At detailed telemetry level, includes attributes: error.type (semantic convention), error.permanent. + +| Unit | Metric Type | Value Type | Monotonic | Stability | +| ---- | ----------- | ---------- | --------- | --------- | +| {datapoint} | Sum | Int | true | Alpha | + +### otelcol_exporter_send_failed_profile_samples + +Number of profile samples in failed attempts to send to destination. At detailed telemetry level, includes attributes: error.type (semantic convention), error.permanent. | Unit | Metric Type | Value Type | Monotonic | Stability | | ---- | ----------- | ---------- | --------- | --------- | -| {datapoints} | Sum | Int | true | Alpha | +| {sample} | Sum | Int | true | Development | ### otelcol_exporter_send_failed_spans -Number of spans in failed attempts to send to destination. [Alpha] +Number of spans in failed attempts to send to destination. At detailed telemetry level, includes attributes: error.type (semantic convention), error.permanent. | Unit | Metric Type | Value Type | Monotonic | Stability | | ---- | ----------- | ---------- | --------- | --------- | -| {spans} | Sum | Int | true | Alpha | +| {span} | Sum | Int | true | Alpha | ### otelcol_exporter_sent_log_records -Number of log record successfully sent to destination. [Alpha] +Number of log record successfully sent to destination. | Unit | Metric Type | Value Type | Monotonic | Stability | | ---- | ----------- | ---------- | --------- | --------- | -| {records} | Sum | Int | true | Alpha | +| {record} | Sum | Int | true | Alpha | ### otelcol_exporter_sent_metric_points -Number of metric points successfully sent to destination. [Alpha] +Number of metric points successfully sent to destination. | Unit | Metric Type | Value Type | Monotonic | Stability | | ---- | ----------- | ---------- | --------- | --------- | -| {datapoints} | Sum | Int | true | Alpha | +| {datapoint} | Sum | Int | true | Alpha | + +### otelcol_exporter_sent_profile_samples + +Number of profile samples successfully sent to destination. + +| Unit | Metric Type | Value Type | Monotonic | Stability | +| ---- | ----------- | ---------- | --------- | --------- | +| {sample} | Sum | Int | true | Development | ### otelcol_exporter_sent_spans -Number of spans successfully sent to destination. [Alpha] +Number of spans successfully sent to destination. | Unit | Metric Type | Value Type | Monotonic | Stability | | ---- | ----------- | ---------- | --------- | --------- | -| {spans} | Sum | Int | true | Alpha | +| {span} | Sum | Int | true | Alpha | + +## Feature Gates + +This component has the following feature gates: + +| Feature Gate | Stage | Description | From Version | To Version | Reference | +| ------------ | ----- | ----------- | ------------ | ---------- | --------- | +| `exporter.PersistRequestContext` | beta | controls whether context should be stored alongside requests in the persistent queue | v0.128.0 | N/A | [Link](https://github.com/open-telemetry/opentelemetry-collector/pull/13188) | + +For more information about feature gates, see the [Feature Gates](https://github.com/open-telemetry/opentelemetry-collector/blob/main/featuregate/README.md) documentation. diff --git a/exporter/exporterhelper/go.mod b/exporter/exporterhelper/go.mod index 83afc594237f..64729ba510d9 100644 --- a/exporter/exporterhelper/go.mod +++ b/exporter/exporterhelper/go.mod @@ -1,39 +1,43 @@ module go.opentelemetry.io/collector/exporter/exporterhelper -go 1.24.0 +go 1.25.0 require ( github.com/cenkalti/backoff/v5 v5.0.3 + github.com/hashicorp/golang-lru/v2 v2.0.7 github.com/stretchr/testify v1.11.1 go.opentelemetry.io/collector/client v1.46.0 - go.opentelemetry.io/collector/component v1.46.0 - go.opentelemetry.io/collector/component/componenttest v0.140.0 - go.opentelemetry.io/collector/config/configoptional v1.46.0 - go.opentelemetry.io/collector/config/configretry v1.46.0 - go.opentelemetry.io/collector/confmap v1.46.0 - go.opentelemetry.io/collector/confmap/xconfmap v0.140.0 - go.opentelemetry.io/collector/consumer v1.46.0 - go.opentelemetry.io/collector/consumer/consumererror v0.140.0 - go.opentelemetry.io/collector/consumer/consumertest v0.140.0 - go.opentelemetry.io/collector/exporter v1.46.0 + go.opentelemetry.io/collector/component v1.54.0 + go.opentelemetry.io/collector/component/componenttest v0.148.0 + go.opentelemetry.io/collector/config/configoptional v1.54.0 + go.opentelemetry.io/collector/config/configretry v1.54.0 + go.opentelemetry.io/collector/confmap v1.54.0 + go.opentelemetry.io/collector/confmap/xconfmap v0.148.0 + go.opentelemetry.io/collector/consumer v1.54.0 + go.opentelemetry.io/collector/consumer/consumererror v0.148.0 + go.opentelemetry.io/collector/consumer/consumertest v0.148.0 + go.opentelemetry.io/collector/exporter v1.54.0 go.opentelemetry.io/collector/exporter/exportertest v0.140.0 go.opentelemetry.io/collector/extension/extensiontest v0.140.0 go.opentelemetry.io/collector/extension/xextension v0.140.0 - go.opentelemetry.io/collector/featuregate v1.46.0 - go.opentelemetry.io/collector/pdata v1.46.0 - go.opentelemetry.io/collector/pdata/pprofile v0.140.0 - go.opentelemetry.io/collector/pdata/testdata v0.140.0 + go.opentelemetry.io/collector/featuregate v1.54.0 + go.opentelemetry.io/collector/internal/testutil v0.148.0 + go.opentelemetry.io/collector/pdata v1.54.0 + go.opentelemetry.io/collector/pdata/pprofile v0.148.0 + go.opentelemetry.io/collector/pdata/testdata v0.148.0 go.opentelemetry.io/collector/pdata/xpdata v0.140.0 - go.opentelemetry.io/collector/pipeline v1.46.0 - go.opentelemetry.io/otel v1.40.0 - go.opentelemetry.io/otel/metric v1.40.0 + go.opentelemetry.io/collector/pipeline v1.54.0 + go.opentelemetry.io/collector/pipeline/xpipeline v0.0.0-00010101000000-000000000000 + go.opentelemetry.io/otel v1.42.0 + go.opentelemetry.io/otel/metric v1.42.0 go.opentelemetry.io/otel/sdk v1.40.0 go.opentelemetry.io/otel/sdk/metric v1.40.0 - go.opentelemetry.io/otel/trace v1.40.0 + go.opentelemetry.io/otel/trace v1.42.0 go.uber.org/goleak v1.3.0 go.uber.org/multierr v1.11.0 go.uber.org/zap v1.27.1 - google.golang.org/protobuf v1.36.10 + google.golang.org/grpc v1.79.3 + google.golang.org/protobuf v1.36.11 ) require ( @@ -41,30 +45,30 @@ require ( github.com/davecgh/go-spew v1.1.1 // indirect github.com/go-logr/logr v1.4.3 // indirect github.com/go-logr/stdr v1.2.2 // indirect - github.com/go-viper/mapstructure/v2 v2.4.0 // indirect + github.com/go-viper/mapstructure/v2 v2.5.0 // indirect github.com/gobwas/glob v0.2.3 // indirect github.com/google/uuid v1.6.0 // indirect - github.com/hashicorp/go-version v1.7.0 // indirect + github.com/hashicorp/go-version v1.8.0 // indirect github.com/json-iterator/go v1.1.12 // indirect github.com/knadh/koanf/maps v0.1.2 // indirect github.com/knadh/koanf/providers/confmap v1.0.0 // indirect - github.com/knadh/koanf/v2 v2.3.0 // indirect + github.com/knadh/koanf/v2 v2.3.3 // indirect github.com/mitchellh/copystructure v1.2.0 // indirect github.com/mitchellh/reflectwalk v1.0.2 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee // indirect github.com/pmezard/go-difflib v1.0.0 // indirect go.opentelemetry.io/auto/sdk v1.2.1 // indirect - go.opentelemetry.io/collector/consumer/xconsumer v0.140.0 // indirect - go.opentelemetry.io/collector/exporter/xexporter v0.140.0 // indirect - go.opentelemetry.io/collector/extension v1.46.0 // indirect - go.opentelemetry.io/collector/receiver v1.46.0 // indirect - go.opentelemetry.io/collector/receiver/receivertest v0.140.0 // indirect - go.opentelemetry.io/collector/receiver/xreceiver v0.140.0 // indirect + go.opentelemetry.io/collector/consumer/xconsumer v0.148.0 // indirect + go.opentelemetry.io/collector/exporter/xexporter v0.148.0 // indirect + go.opentelemetry.io/collector/extension v1.54.0 // indirect + go.opentelemetry.io/collector/internal/componentalias v0.148.0 // indirect + go.opentelemetry.io/collector/receiver v1.54.0 // indirect + go.opentelemetry.io/collector/receiver/receivertest v0.148.0 // indirect + go.opentelemetry.io/collector/receiver/xreceiver v0.148.0 // indirect go.yaml.in/yaml/v3 v3.0.4 // indirect - golang.org/x/sys v0.40.0 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20251022142026-3a174f9686a8 // indirect - google.golang.org/grpc v1.77.0 // indirect + golang.org/x/sys v0.41.0 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20251222181119-0a764e51fe1b // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) @@ -121,3 +125,7 @@ replace go.opentelemetry.io/collector/config/configoptional => ../../config/conf replace go.opentelemetry.io/collector/confmap/xconfmap => ../../confmap/xconfmap replace go.opentelemetry.io/collector/internal/testutil => ../../internal/testutil + +replace go.opentelemetry.io/collector/internal/componentalias => ../../internal/componentalias + +replace go.opentelemetry.io/collector/pipeline/xpipeline => ../../pipeline/xpipeline diff --git a/exporter/exporterhelper/go.sum b/exporter/exporterhelper/go.sum index d3c35ba1cbd6..d6e38a64eac0 100644 --- a/exporter/exporterhelper/go.sum +++ b/exporter/exporterhelper/go.sum @@ -10,8 +10,8 @@ github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI= github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= -github.com/go-viper/mapstructure/v2 v2.4.0 h1:EBsztssimR/CONLSZZ04E8qAkxNYq4Qp9LvH92wZUgs= -github.com/go-viper/mapstructure/v2 v2.4.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM= +github.com/go-viper/mapstructure/v2 v2.5.0 h1:vM5IJoUAy3d7zRSVtIwQgBj7BiWtMPfmPEgAXnvj1Ro= +github.com/go-viper/mapstructure/v2 v2.5.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM= github.com/gobwas/glob v0.2.3 h1:A4xDbljILXROh+kObIiy5kIaPYD8e96x1tgBhUI5J+Y= github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8= github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= @@ -21,16 +21,18 @@ github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/hashicorp/go-version v1.7.0 h1:5tqGy27NaOTB8yJKUZELlFAS/LTKJkrmONwQKeRZfjY= -github.com/hashicorp/go-version v1.7.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= +github.com/hashicorp/go-version v1.8.0 h1:KAkNb1HAiZd1ukkxDFGmokVZe1Xy9HG6NUp+bPle2i4= +github.com/hashicorp/go-version v1.8.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= +github.com/hashicorp/golang-lru/v2 v2.0.7 h1:a+bsQ5rvGLjzHuww6tVxozPZFVghXaHOwFs4luLUK2k= +github.com/hashicorp/golang-lru/v2 v2.0.7/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyfM2/ZepoAG6RGpeM= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= github.com/knadh/koanf/maps v0.1.2 h1:RBfmAW5CnZT+PJ1CVc1QSJKf4Xu9kxfQgYVQSu8hpbo= github.com/knadh/koanf/maps v0.1.2/go.mod h1:npD/QZY3V6ghQDdcQzl1W4ICNVTkohC8E73eI2xW4yI= github.com/knadh/koanf/providers/confmap v1.0.0 h1:mHKLJTE7iXEys6deO5p6olAiZdG5zwp8Aebir+/EaRE= github.com/knadh/koanf/providers/confmap v1.0.0/go.mod h1:txHYHiI2hAtF0/0sCmcuol4IDcuQbKTybiB1nOcUo1A= -github.com/knadh/koanf/v2 v2.3.0 h1:Qg076dDRFHvqnKG97ZEsi9TAg2/nFTa9hCdcSa1lvlM= -github.com/knadh/koanf/v2 v2.3.0/go.mod h1:gRb40VRAbd4iJMYYD5IxZ6hfuopFcXBpc9bbQpZwo28= +github.com/knadh/koanf/v2 v2.3.3 h1:jLJC8XCRfLC7n4F+ZKKdBsbq1bfXTpuFhf4L7t94D94= +github.com/knadh/koanf/v2 v2.3.3/go.mod h1:gRb40VRAbd4iJMYYD5IxZ6hfuopFcXBpc9bbQpZwo28= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= @@ -55,22 +57,22 @@ github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64= go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y= -go.opentelemetry.io/otel v1.40.0 h1:oA5YeOcpRTXq6NN7frwmwFR0Cn3RhTVZvXsP4duvCms= -go.opentelemetry.io/otel v1.40.0/go.mod h1:IMb+uXZUKkMXdPddhwAHm6UfOwJyh4ct1ybIlV14J0g= -go.opentelemetry.io/otel/metric v1.40.0 h1:rcZe317KPftE2rstWIBitCdVp89A2HqjkxR3c11+p9g= -go.opentelemetry.io/otel/metric v1.40.0/go.mod h1:ib/crwQH7N3r5kfiBZQbwrTge743UDc7DTFVZrrXnqc= +go.opentelemetry.io/otel v1.42.0 h1:lSQGzTgVR3+sgJDAU/7/ZMjN9Z+vUip7leaqBKy4sho= +go.opentelemetry.io/otel v1.42.0/go.mod h1:lJNsdRMxCUIWuMlVJWzecSMuNjE7dOYyWlqOXWkdqCc= +go.opentelemetry.io/otel/metric v1.42.0 h1:2jXG+3oZLNXEPfNmnpxKDeZsFI5o4J+nz6xUlaFdF/4= +go.opentelemetry.io/otel/metric v1.42.0/go.mod h1:RlUN/7vTU7Ao/diDkEpQpnz3/92J9ko05BIwxYa2SSI= go.opentelemetry.io/otel/sdk v1.40.0 h1:KHW/jUzgo6wsPh9At46+h4upjtccTmuZCFAc9OJ71f8= go.opentelemetry.io/otel/sdk v1.40.0/go.mod h1:Ph7EFdYvxq72Y8Li9q8KebuYUr2KoeyHx0DRMKrYBUE= go.opentelemetry.io/otel/sdk/metric v1.40.0 h1:mtmdVqgQkeRxHgRv4qhyJduP3fYJRMX4AtAlbuWdCYw= go.opentelemetry.io/otel/sdk/metric v1.40.0/go.mod h1:4Z2bGMf0KSK3uRjlczMOeMhKU2rhUqdWNoKcYrtcBPg= -go.opentelemetry.io/otel/trace v1.40.0 h1:WA4etStDttCSYuhwvEa8OP8I5EWu24lkOzp+ZYblVjw= -go.opentelemetry.io/otel/trace v1.40.0/go.mod h1:zeAhriXecNGP/s2SEG3+Y8X9ujcJOTqQ5RgdEJcawiA= -go.opentelemetry.io/proto/slim/otlp v1.9.0 h1:fPVMv8tP3TrsqlkH1HWYUpbCY9cAIemx184VGkS6vlE= -go.opentelemetry.io/proto/slim/otlp v1.9.0/go.mod h1:xXdeJJ90Gqyll+orzUkY4bOd2HECo5JofeoLpymVqdI= -go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.2.0 h1:o13nadWDNkH/quoDomDUClnQBpdQQ2Qqv0lQBjIXjE8= -go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.2.0/go.mod h1:Gyb6Xe7FTi/6xBHwMmngGoHqL0w29Y4eW8TGFzpefGA= -go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.2.0 h1:EiUYvtwu6PMrMHVjcPfnsG3v+ajPkbUeH+IL93+QYyk= -go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.2.0/go.mod h1:mUUHKFiN2SST3AhJ8XhJxEoeVW12oqfXog0Bo8W3Ec4= +go.opentelemetry.io/otel/trace v1.42.0 h1:OUCgIPt+mzOnaUTpOQcBiM/PLQ/Op7oq6g4LenLmOYY= +go.opentelemetry.io/otel/trace v1.42.0/go.mod h1:f3K9S+IFqnumBkKhRJMeaZeNk9epyhnCmQh/EysQCdc= +go.opentelemetry.io/proto/slim/otlp v1.10.0 h1:iR97Vs/ZDR+y9TfuP9b1XBtdPWeC+OMslIBmhcLU7jM= +go.opentelemetry.io/proto/slim/otlp v1.10.0/go.mod h1:lV9250stpjYLPNA5viFabIgP2QlUGRT1GdTgAf8SIUk= +go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.3.0 h1:RUF5rO0hAlgiJt1fzQVzcVs3vZVNHIcMLgOgG4rWNcQ= +go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.3.0/go.mod h1:I89cynRj8y+383o7tEQVg2SVA6SRgDVIouWPUVXjx0U= +go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.3.0 h1:CQvJSldHRUN6Z8jsUeYv8J0lXRvygALXIzsmAeCcZE0= +go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.3.0/go.mod h1:xSQ+mEfJe/GjK1LXEyVOoSI1N9JV9ZI923X5kup43W4= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= @@ -79,18 +81,18 @@ go.uber.org/zap v1.27.1 h1:08RqriUEv8+ArZRYSTXy1LeBScaMpVSTBhCeaZYfMYc= go.uber.org/zap v1.27.1/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc= go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg= -golang.org/x/net v0.46.1-0.20251013234738-63d1a5100f82 h1:6/3JGEh1C88g7m+qzzTbl3A0FtsLguXieqofVLU/JAo= -golang.org/x/net v0.46.1-0.20251013234738-63d1a5100f82/go.mod h1:Q9BGdFy1y4nkUwiLvT5qtyhAnEHgnQ/zd8PfU6nc210= -golang.org/x/sys v0.40.0 h1:DBZZqJ2Rkml6QMQsZywtnjnnGvHza6BTfYFWY9kjEWQ= -golang.org/x/sys v0.40.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= -golang.org/x/text v0.30.0 h1:yznKA/E9zq54KzlzBEAWn1NXSQ8DIp/NYMy88xJjl4k= -golang.org/x/text v0.30.0/go.mod h1:yDdHFIX9t+tORqspjENWgzaCVXgk0yYnYuSZ8UzzBVM= -google.golang.org/genproto/googleapis/rpc v0.0.0-20251022142026-3a174f9686a8 h1:M1rk8KBnUsBDg1oPGHNCxG4vc1f49epmTO7xscSajMk= -google.golang.org/genproto/googleapis/rpc v0.0.0-20251022142026-3a174f9686a8/go.mod h1:7i2o+ce6H/6BluujYR+kqX3GKH+dChPTQU19wjRPiGk= -google.golang.org/grpc v1.77.0 h1:wVVY6/8cGA6vvffn+wWK5ToddbgdU3d8MNENr4evgXM= -google.golang.org/grpc v1.77.0/go.mod h1:z0BY1iVj0q8E1uSQCjL9cppRj+gnZjzDnzV0dHhrNig= -google.golang.org/protobuf v1.36.10 h1:AYd7cD/uASjIL6Q9LiTjz8JLcrh/88q5UObnmY3aOOE= -google.golang.org/protobuf v1.36.10/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= +golang.org/x/net v0.51.0 h1:94R/GTO7mt3/4wIKpcR5gkGmRLOuE/2hNGeWq/GBIFo= +golang.org/x/net v0.51.0/go.mod h1:aamm+2QF5ogm02fjy5Bb7CQ0WMt1/WVM7FtyaTLlA9Y= +golang.org/x/sys v0.41.0 h1:Ivj+2Cp/ylzLiEU89QhWblYnOE9zerudt9Ftecq2C6k= +golang.org/x/sys v0.41.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= +golang.org/x/text v0.34.0 h1:oL/Qq0Kdaqxa1KbNeMKwQq0reLCCaFtqu2eNuSeNHbk= +golang.org/x/text v0.34.0/go.mod h1:homfLqTYRFyVYemLBFl5GgL/DWEiH5wcsQ5gSh1yziA= +google.golang.org/genproto/googleapis/rpc v0.0.0-20251222181119-0a764e51fe1b h1:Mv8VFug0MP9e5vUxfBcE3vUkV6CImK3cMNMIDFjmzxU= +google.golang.org/genproto/googleapis/rpc v0.0.0-20251222181119-0a764e51fe1b/go.mod h1:j9x/tPzZkyxcgEFkiKEEGxfvyumM01BEtsW8xzOahRQ= +google.golang.org/grpc v1.79.3 h1:sybAEdRIEtvcD68Gx7dmnwjZKlyfuc61Dyo9pGXXkKE= +google.golang.org/grpc v1.79.3/go.mod h1:KmT0Kjez+0dde/v2j9vzwoAScgEPx/Bw1CYChhHLrHQ= +google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE= +google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= diff --git a/exporter/exporterhelper/internal/base_exporter.go b/exporter/exporterhelper/internal/base_exporter.go index 457a7f04b044..64cd4f733339 100644 --- a/exporter/exporterhelper/internal/base_exporter.go +++ b/exporter/exporterhelper/internal/base_exporter.go @@ -11,6 +11,7 @@ import ( "go.uber.org/zap" "go.opentelemetry.io/collector/component" + "go.opentelemetry.io/collector/config/configoptional" "go.opentelemetry.io/collector/config/configretry" "go.opentelemetry.io/collector/consumer" "go.opentelemetry.io/collector/exporter" @@ -48,7 +49,7 @@ type BaseExporter struct { retryCfg configretry.BackOffConfig queueBatchSettings queuebatch.Settings[request.Request] - queueCfg queuebatch.Config + queueCfg configoptional.Optional[queuebatch.Config] queuePayloadCodec queuePayloadCodec queueUseEncodingForInMemory bool } @@ -93,19 +94,19 @@ func NewBaseExporter(set exporter.Settings, signal pipeline.Signal, pusher sende return nil, err } - if be.queueCfg.Batch.HasValue() { + if be.queueCfg.HasValue() && be.queueCfg.Get().Batch.HasValue() { // Batcher mutates the data. be.ConsumerOptions = append(be.ConsumerOptions, consumer.WithCapabilities(consumer.Capabilities{MutatesData: true})) } - if be.queueCfg.Enabled { + if be.queueCfg.HasValue() { qSet := queuebatch.AllSettings[request.Request]{ Settings: be.queueBatchSettings, Signal: signal, ID: set.ID, Telemetry: set.TelemetrySettings, } - be.QueueSender, err = NewQueueSender(qSet, be.queueCfg, be.ExportFailureMessage, be.firstSender) + be.QueueSender, err = NewQueueSender(qSet, *be.queueCfg.Get(), be.ExportFailureMessage, be.firstSender) if err != nil { return nil, err } @@ -202,7 +203,7 @@ func WithRetry(config configretry.BackOffConfig) Option { // WithQueue overrides the default queuebatch.Config for an exporter. // The default queuebatch.Config is to disable queueing. // This option cannot be used with the new exporter helpers New[Traces|Metrics|Logs]RequestExporter. -func WithQueue(cfg queuebatch.Config) Option { +func WithQueue(cfg configoptional.Optional[queuebatch.Config]) Option { return func(o *BaseExporter) error { if o.queueBatchSettings.Encoding == nil { return errors.New("WithQueue option is not available for the new request exporters, use WithQueueBatch instead") @@ -213,17 +214,30 @@ func WithQueue(cfg queuebatch.Config) Option { // WithQueueBatch enables queueing for an exporter. // This option should be used with the new exporter helpers New[Traces|Metrics|Logs]RequestExporter. +// If batch.partition.MetadataKeys is set, it will automatically configure the partitioner and merge function +// to partition batches based on the specified metadata keys. // Experimental: This API is at the early stage of development and may change without backward compatibility // until https://github.com/open-telemetry/opentelemetry-collector/issues/8122 is resolved. -func WithQueueBatch(cfg queuebatch.Config, set queuebatch.Settings[request.Request]) Option { +func WithQueueBatch(cfg configoptional.Optional[queuebatch.Config], set queuebatch.Settings[request.Request]) Option { return func(o *BaseExporter) error { - if !cfg.Enabled { + if !cfg.HasValue() { o.ExportFailureMessage += " Try enabling sending_queue to survive temporary failures." return nil } - if cfg.StorageID != nil && set.Encoding == nil { + if cfg.Get().StorageID != nil && set.Encoding == nil { return errors.New("`Settings.Encoding` must not be nil when persistent queue is enabled") } + // Automatically configure partitioner if MetadataKeys is set + if cfg.Get().Batch.HasValue() && len(cfg.Get().Batch.Get().Partition.MetadataKeys) > 0 { + if set.Partitioner != nil { + return errors.New("cannot use metadata_keys when a custom partitioner is already configured") + } + if set.MergeCtx != nil { + return errors.New("cannot use metadata_keys when a custom merge function is already configured") + } + set.Partitioner = queuebatch.NewMetadataKeysPartitioner(cfg.Get().Batch.Get().Partition.MetadataKeys) + set.MergeCtx = queuebatch.NewMetadataKeysMergeCtx(cfg.Get().Batch.Get().Partition.MetadataKeys) + } o.queueBatchSettings = set o.queueCfg = cfg return nil diff --git a/exporter/exporterhelper/internal/base_exporter_test.go b/exporter/exporterhelper/internal/base_exporter_test.go index 0d1ac853921e..5e5228851925 100644 --- a/exporter/exporterhelper/internal/base_exporter_test.go +++ b/exporter/exporterhelper/internal/base_exporter_test.go @@ -15,6 +15,7 @@ import ( "go.opentelemetry.io/collector/component" "go.opentelemetry.io/collector/component/componenttest" + "go.opentelemetry.io/collector/config/configoptional" "go.opentelemetry.io/collector/config/configretry" "go.opentelemetry.io/collector/exporter/exporterhelper/internal/queuebatch" "go.opentelemetry.io/collector/exporter/exporterhelper/internal/request" @@ -49,7 +50,7 @@ func TestQueueOptionsWithRequestExporter(t *testing.T) { require.NoError(t, err) require.Nil(t, bs.queueBatchSettings.Encoding) _, err = NewBaseExporter(exportertest.NewNopSettings(exportertest.NopType), pipeline.SignalMetrics, noopExport, - WithRetry(configretry.NewDefaultBackOffConfig()), WithQueue(NewDefaultQueueConfig())) + WithRetry(configretry.NewDefaultBackOffConfig()), WithQueue(configoptional.Some(NewDefaultQueueConfig()))) require.Error(t, err) qCfg := NewDefaultQueueConfig() @@ -58,12 +59,12 @@ func TestQueueOptionsWithRequestExporter(t *testing.T) { _, err = NewBaseExporter(exportertest.NewNopSettings(exportertest.NopType), pipeline.SignalMetrics, noopExport, WithQueueBatchSettings(newFakeQueueBatch()), WithRetry(configretry.NewDefaultBackOffConfig()), - WithQueueBatch(qCfg, queuebatch.Settings[request.Request]{})) + WithQueueBatch(configoptional.Some(qCfg), queuebatch.Settings[request.Request]{})) require.Error(t, err) _, err = NewBaseExporter(exportertest.NewNopSettings(exportertest.NopType), pipeline.SignalMetrics, noopExport, WithQueueBatchInMemoryEncoding(true), - WithQueueBatch(NewDefaultQueueConfig(), queuebatch.Settings[request.Request]{})) + WithQueueBatch(configoptional.Some(NewDefaultQueueConfig()), queuebatch.Settings[request.Request]{})) require.ErrorContains(t, err, "`Settings.Encoding` must not be nil when in-memory encoding is enabled") } @@ -77,7 +78,7 @@ func TestBaseExporterLogging(t *testing.T) { qCfg.WaitForResult = true bs, err := NewBaseExporter(set, pipeline.SignalMetrics, errExport, WithQueueBatchSettings(newFakeQueueBatch()), - WithQueue(qCfg), + WithQueue(configoptional.Some(qCfg)), WithRetry(rCfg)) require.NoError(t, err) require.NoError(t, bs.Start(context.Background(), componenttest.NewNopHost())) @@ -93,6 +94,103 @@ func TestBaseExporterLogging(t *testing.T) { require.NoError(t, bs.Shutdown(context.Background())) } +func TestWithQueue_MetadataKeys(t *testing.T) { + t.Run("with MetadataKeys - configures partitioner and merge function", func(t *testing.T) { + qCfg := NewDefaultQueueConfig() + qCfg.Batch.GetOrInsertDefault().Partition.MetadataKeys = []string{"key1", "key2"} + + be, err := NewBaseExporter( + exportertest.NewNopSettings(exportertest.NopType), + pipeline.SignalMetrics, + noopExport, + WithQueueBatchSettings(newFakeQueueBatch()), + WithQueue(configoptional.Some(qCfg)), + ) + require.NoError(t, err) + assert.NotNil(t, be) + + // Verify partitioner and merge function are configured + assert.NotNil(t, be.queueBatchSettings.Partitioner, "Partitioner should be set when MetadataKeys is provided") + assert.NotNil(t, be.queueBatchSettings.MergeCtx, "MergeCtx should be set when MetadataKeys is provided") + }) + + t.Run("without MetadataKeys - does not configure partitioner", func(t *testing.T) { + tests := []struct { + name string + metadataKeys []string + }{ + {"empty slice", []string{}}, + {"nil", nil}, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + qCfg := NewDefaultQueueConfig() + qCfg.Batch.GetOrInsertDefault().Partition.MetadataKeys = tt.metadataKeys + + be, err := NewBaseExporter( + exportertest.NewNopSettings(exportertest.NopType), + pipeline.SignalMetrics, + noopExport, + WithQueueBatchSettings(newFakeQueueBatch()), + WithQueue(configoptional.Some(qCfg)), + ) + require.NoError(t, err) + assert.NotNil(t, be) + + // Verify partitioner and merge function are NOT configured + assert.Nil(t, be.queueBatchSettings.Partitioner, "Partitioner should not be set when MetadataKeys is %s", tt.name) + assert.Nil(t, be.queueBatchSettings.MergeCtx, "MergeCtx should not be set when MetadataKeys is %s", tt.name) + }) + } + }) + + t.Run("error when custom partitioner already set and metadata_keys used", func(t *testing.T) { + qCfg := NewDefaultQueueConfig() + qCfg.Batch.GetOrInsertDefault().Partition.MetadataKeys = []string{"key1", "key2"} + + // Set up queue batch settings with a custom partitioner already configured + customSettings := newFakeQueueBatch() + customPartitioner := queuebatch.NewPartitioner( + func(context.Context, request.Request) string { + return "custom" + }, + ) + customSettings.Partitioner = customPartitioner + + _, err := NewBaseExporter( + exportertest.NewNopSettings(exportertest.NopType), + pipeline.SignalMetrics, + noopExport, + WithQueueBatchSettings(customSettings), + WithQueue(configoptional.Some(qCfg)), + ) + require.Error(t, err) + assert.Contains(t, err.Error(), "cannot use metadata_keys when a custom partitioner is already configured") + }) + + t.Run("error when custom merge function already set and metadata_keys used", func(t *testing.T) { + qCfg := NewDefaultQueueConfig() + qCfg.Batch.GetOrInsertDefault().Partition.MetadataKeys = []string{"key1", "key2"} + + // Set up queue batch settings with a custom merge function already configured + customSettings := newFakeQueueBatch() + customSettings.MergeCtx = func(context.Context, context.Context) context.Context { + return context.Background() + } + + _, err := NewBaseExporter( + exportertest.NewNopSettings(exportertest.NopType), + pipeline.SignalMetrics, + noopExport, + WithQueueBatchSettings(customSettings), + WithQueue(configoptional.Some(qCfg)), + ) + require.Error(t, err) + assert.Contains(t, err.Error(), "cannot use metadata_keys when a custom merge function is already configured") + }) +} + func TestQueueRetryWithDisabledQueue(t *testing.T) { tests := []struct { name string @@ -103,9 +201,7 @@ func TestQueueRetryWithDisabledQueue(t *testing.T) { queueOptions: []Option{ WithQueueBatchSettings(newFakeQueueBatch()), func() Option { - qs := NewDefaultQueueConfig() - qs.Enabled = false - return WithQueue(qs) + return WithQueue(configoptional.None[queuebatch.Config]()) }(), }, }, @@ -113,9 +209,7 @@ func TestQueueRetryWithDisabledQueue(t *testing.T) { name: "WithRequestQueue", queueOptions: []Option{ func() Option { - qs := NewDefaultQueueConfig() - qs.Enabled = false - return WithQueueBatch(qs, newFakeQueueBatch()) + return WithQueueBatch(configoptional.None[queuebatch.Config](), newFakeQueueBatch()) }(), }, }, @@ -148,7 +242,7 @@ func TestWithQueueBatchPayloadCodec(t *testing.T) { pipeline.SignalLogs, noopExport, WithQueueBatchPayloadCodec(codec), - WithQueueBatch(qCfg, newFakeQueueBatch()), + WithQueueBatch(configoptional.Some(qCfg), newFakeQueueBatch()), ) require.NoError(t, err) @@ -169,7 +263,7 @@ func TestWithQueueBatchPayloadCodec(t *testing.T) { exportertest.NewNopSettings(exportertest.NopType), pipeline.SignalLogs, noopExport, - WithQueueBatch(qCfg, newFakeQueueBatch()), + WithQueueBatch(configoptional.Some(qCfg), newFakeQueueBatch()), WithQueueBatchPayloadCodec(codec), ) require.NoError(t, err) @@ -191,13 +285,13 @@ func TestWithQueueBatchInMemoryEncoding(t *testing.T) { name: "option before queue", options: []Option{ WithQueueBatchInMemoryEncoding(true), - WithQueueBatch(qCfg, newFakeQueueBatch()), + WithQueueBatch(configoptional.Some(qCfg), newFakeQueueBatch()), }, }, { name: "option after queue", options: []Option{ - WithQueueBatch(qCfg, newFakeQueueBatch()), + WithQueueBatch(configoptional.Some(qCfg), newFakeQueueBatch()), WithQueueBatchInMemoryEncoding(true), }, }, diff --git a/exporter/exporterhelper/internal/config.schema.yaml b/exporter/exporterhelper/internal/config.schema.yaml new file mode 100644 index 000000000000..91712d54f977 --- /dev/null +++ b/exporter/exporterhelper/internal/config.schema.yaml @@ -0,0 +1,10 @@ +$defs: + timeout_config: + description: TimeoutConfig for timeout. The timeout applies to individual attempts to send data to the backend. + type: object + properties: + timeout: + description: Timeout is the timeout for every attempt to send data to the backend. A zero timeout means no timeout. + type: string + x-customType: time.Duration + format: duration diff --git a/exporter/exporterhelper/internal/metadata/generated_feature_gates.go b/exporter/exporterhelper/internal/metadata/generated_feature_gates.go new file mode 100644 index 000000000000..194bc07ed829 --- /dev/null +++ b/exporter/exporterhelper/internal/metadata/generated_feature_gates.go @@ -0,0 +1,15 @@ +// Code generated by mdatagen. DO NOT EDIT. + +package metadata + +import ( + "go.opentelemetry.io/collector/featuregate" +) + +var ExporterPersistRequestContextFeatureGate = featuregate.GlobalRegistry().MustRegister( + "exporter.PersistRequestContext", + featuregate.StageBeta, + featuregate.WithRegisterDescription("controls whether context should be stored alongside requests in the persistent queue"), + featuregate.WithRegisterReferenceURL("https://github.com/open-telemetry/opentelemetry-collector/pull/13188"), + featuregate.WithRegisterFromVersion("v0.128.0"), +) diff --git a/exporter/exporterhelper/internal/metadata/generated_telemetry.go b/exporter/exporterhelper/internal/metadata/generated_telemetry.go index 510cb29002d8..778cf718b550 100644 --- a/exporter/exporterhelper/internal/metadata/generated_telemetry.go +++ b/exporter/exporterhelper/internal/metadata/generated_telemetry.go @@ -25,22 +25,25 @@ func Tracer(settings component.TelemetrySettings) trace.Tracer { // TelemetryBuilder provides an interface for components to report telemetry // as defined in metadata and user config. type TelemetryBuilder struct { - meter metric.Meter - mu sync.Mutex - registrations []metric.Registration - ExporterEnqueueFailedLogRecords metric.Int64Counter - ExporterEnqueueFailedMetricPoints metric.Int64Counter - ExporterEnqueueFailedSpans metric.Int64Counter - ExporterQueueBatchSendSize metric.Int64Histogram - ExporterQueueBatchSendSizeBytes metric.Int64Histogram - ExporterQueueCapacity metric.Int64ObservableGauge - ExporterQueueSize metric.Int64ObservableGauge - ExporterSendFailedLogRecords metric.Int64Counter - ExporterSendFailedMetricPoints metric.Int64Counter - ExporterSendFailedSpans metric.Int64Counter - ExporterSentLogRecords metric.Int64Counter - ExporterSentMetricPoints metric.Int64Counter - ExporterSentSpans metric.Int64Counter + meter metric.Meter + mu sync.Mutex + registrations []metric.Registration + ExporterEnqueueFailedLogRecords metric.Int64Counter + ExporterEnqueueFailedMetricPoints metric.Int64Counter + ExporterEnqueueFailedProfileSamples metric.Int64Counter + ExporterEnqueueFailedSpans metric.Int64Counter + ExporterQueueBatchSendSize metric.Int64Histogram + ExporterQueueBatchSendSizeBytes metric.Int64Histogram + ExporterQueueCapacity metric.Int64ObservableGauge + ExporterQueueSize metric.Int64ObservableGauge + ExporterSendFailedLogRecords metric.Int64Counter + ExporterSendFailedMetricPoints metric.Int64Counter + ExporterSendFailedProfileSamples metric.Int64Counter + ExporterSendFailedSpans metric.Int64Counter + ExporterSentLogRecords metric.Int64Counter + ExporterSentMetricPoints metric.Int64Counter + ExporterSentProfileSamples metric.Int64Counter + ExporterSentSpans metric.Int64Counter } // TelemetryBuilderOption applies changes to default builder. @@ -115,25 +118,31 @@ func NewTelemetryBuilder(settings component.TelemetrySettings, options ...Teleme builder.ExporterEnqueueFailedLogRecords, err = builder.meter.Int64Counter( "otelcol_exporter_enqueue_failed_log_records", metric.WithDescription("Number of log records failed to be added to the sending queue. [Alpha]"), - metric.WithUnit("{records}"), + metric.WithUnit("{record}"), ) errs = errors.Join(errs, err) builder.ExporterEnqueueFailedMetricPoints, err = builder.meter.Int64Counter( "otelcol_exporter_enqueue_failed_metric_points", metric.WithDescription("Number of metric points failed to be added to the sending queue. [Alpha]"), - metric.WithUnit("{datapoints}"), + metric.WithUnit("{datapoint}"), + ) + errs = errors.Join(errs, err) + builder.ExporterEnqueueFailedProfileSamples, err = builder.meter.Int64Counter( + "otelcol_exporter_enqueue_failed_profile_samples", + metric.WithDescription("Number of profile samples failed to be added to the sending queue. [Development]"), + metric.WithUnit("{sample}"), ) errs = errors.Join(errs, err) builder.ExporterEnqueueFailedSpans, err = builder.meter.Int64Counter( "otelcol_exporter_enqueue_failed_spans", metric.WithDescription("Number of spans failed to be added to the sending queue. [Alpha]"), - metric.WithUnit("{spans}"), + metric.WithUnit("{span}"), ) errs = errors.Join(errs, err) builder.ExporterQueueBatchSendSize, err = builder.meter.Int64Histogram( "otelcol_exporter_queue_batch_send_size", metric.WithDescription("Number of units in the batch [Development]"), - metric.WithUnit("{units}"), + metric.WithUnit("{unit}"), metric.WithExplicitBucketBoundaries([]float64{10, 25, 50, 75, 100, 250, 500, 750, 1000, 2000, 3000, 4000, 5000, 6000, 7000, 8000, 9000, 10000, 20000, 30000, 50000, 100000}...), ) errs = errors.Join(errs, err) @@ -147,49 +156,61 @@ func NewTelemetryBuilder(settings component.TelemetrySettings, options ...Teleme builder.ExporterQueueCapacity, err = builder.meter.Int64ObservableGauge( "otelcol_exporter_queue_capacity", metric.WithDescription("Fixed capacity of the retry queue (in batches). [Alpha]"), - metric.WithUnit("{batches}"), + metric.WithUnit("{batch}"), ) errs = errors.Join(errs, err) builder.ExporterQueueSize, err = builder.meter.Int64ObservableGauge( "otelcol_exporter_queue_size", metric.WithDescription("Current size of the retry queue (in batches). [Alpha]"), - metric.WithUnit("{batches}"), + metric.WithUnit("{batch}"), ) errs = errors.Join(errs, err) builder.ExporterSendFailedLogRecords, err = builder.meter.Int64Counter( "otelcol_exporter_send_failed_log_records", - metric.WithDescription("Number of log records in failed attempts to send to destination. [Alpha]"), - metric.WithUnit("{records}"), + metric.WithDescription("Number of log records in failed attempts to send to destination. At detailed telemetry level, includes attributes: error.type (semantic convention), error.permanent. [Alpha]"), + metric.WithUnit("{record}"), ) errs = errors.Join(errs, err) builder.ExporterSendFailedMetricPoints, err = builder.meter.Int64Counter( "otelcol_exporter_send_failed_metric_points", - metric.WithDescription("Number of metric points in failed attempts to send to destination. [Alpha]"), - metric.WithUnit("{datapoints}"), + metric.WithDescription("Number of metric points in failed attempts to send to destination. At detailed telemetry level, includes attributes: error.type (semantic convention), error.permanent. [Alpha]"), + metric.WithUnit("{datapoint}"), + ) + errs = errors.Join(errs, err) + builder.ExporterSendFailedProfileSamples, err = builder.meter.Int64Counter( + "otelcol_exporter_send_failed_profile_samples", + metric.WithDescription("Number of profile samples in failed attempts to send to destination. At detailed telemetry level, includes attributes: error.type (semantic convention), error.permanent. [Development]"), + metric.WithUnit("{sample}"), ) errs = errors.Join(errs, err) builder.ExporterSendFailedSpans, err = builder.meter.Int64Counter( "otelcol_exporter_send_failed_spans", - metric.WithDescription("Number of spans in failed attempts to send to destination. [Alpha]"), - metric.WithUnit("{spans}"), + metric.WithDescription("Number of spans in failed attempts to send to destination. At detailed telemetry level, includes attributes: error.type (semantic convention), error.permanent. [Alpha]"), + metric.WithUnit("{span}"), ) errs = errors.Join(errs, err) builder.ExporterSentLogRecords, err = builder.meter.Int64Counter( "otelcol_exporter_sent_log_records", metric.WithDescription("Number of log record successfully sent to destination. [Alpha]"), - metric.WithUnit("{records}"), + metric.WithUnit("{record}"), ) errs = errors.Join(errs, err) builder.ExporterSentMetricPoints, err = builder.meter.Int64Counter( "otelcol_exporter_sent_metric_points", metric.WithDescription("Number of metric points successfully sent to destination. [Alpha]"), - metric.WithUnit("{datapoints}"), + metric.WithUnit("{datapoint}"), + ) + errs = errors.Join(errs, err) + builder.ExporterSentProfileSamples, err = builder.meter.Int64Counter( + "otelcol_exporter_sent_profile_samples", + metric.WithDescription("Number of profile samples successfully sent to destination. [Development]"), + metric.WithUnit("{sample}"), ) errs = errors.Join(errs, err) builder.ExporterSentSpans, err = builder.meter.Int64Counter( "otelcol_exporter_sent_spans", metric.WithDescription("Number of spans successfully sent to destination. [Alpha]"), - metric.WithUnit("{spans}"), + metric.WithUnit("{span}"), ) errs = errors.Join(errs, err) return &builder, errs diff --git a/exporter/exporterhelper/internal/metadatatest/generated_telemetrytest.go b/exporter/exporterhelper/internal/metadatatest/generated_telemetrytest.go index 7096bc471f75..2c501440d376 100644 --- a/exporter/exporterhelper/internal/metadatatest/generated_telemetrytest.go +++ b/exporter/exporterhelper/internal/metadatatest/generated_telemetrytest.go @@ -16,7 +16,7 @@ func AssertEqualExporterEnqueueFailedLogRecords(t *testing.T, tt *componenttest. want := metricdata.Metrics{ Name: "otelcol_exporter_enqueue_failed_log_records", Description: "Number of log records failed to be added to the sending queue. [Alpha]", - Unit: "{records}", + Unit: "{record}", Data: metricdata.Sum[int64]{ Temporality: metricdata.CumulativeTemporality, IsMonotonic: true, @@ -32,7 +32,7 @@ func AssertEqualExporterEnqueueFailedMetricPoints(t *testing.T, tt *componenttes want := metricdata.Metrics{ Name: "otelcol_exporter_enqueue_failed_metric_points", Description: "Number of metric points failed to be added to the sending queue. [Alpha]", - Unit: "{datapoints}", + Unit: "{datapoint}", Data: metricdata.Sum[int64]{ Temporality: metricdata.CumulativeTemporality, IsMonotonic: true, @@ -44,11 +44,27 @@ func AssertEqualExporterEnqueueFailedMetricPoints(t *testing.T, tt *componenttes metricdatatest.AssertEqual(t, want, got, opts...) } +func AssertEqualExporterEnqueueFailedProfileSamples(t *testing.T, tt *componenttest.Telemetry, dps []metricdata.DataPoint[int64], opts ...metricdatatest.Option) { + want := metricdata.Metrics{ + Name: "otelcol_exporter_enqueue_failed_profile_samples", + Description: "Number of profile samples failed to be added to the sending queue. [Development]", + Unit: "{sample}", + Data: metricdata.Sum[int64]{ + Temporality: metricdata.CumulativeTemporality, + IsMonotonic: true, + DataPoints: dps, + }, + } + got, err := tt.GetMetric("otelcol_exporter_enqueue_failed_profile_samples") + require.NoError(t, err) + metricdatatest.AssertEqual(t, want, got, opts...) +} + func AssertEqualExporterEnqueueFailedSpans(t *testing.T, tt *componenttest.Telemetry, dps []metricdata.DataPoint[int64], opts ...metricdatatest.Option) { want := metricdata.Metrics{ Name: "otelcol_exporter_enqueue_failed_spans", Description: "Number of spans failed to be added to the sending queue. [Alpha]", - Unit: "{spans}", + Unit: "{span}", Data: metricdata.Sum[int64]{ Temporality: metricdata.CumulativeTemporality, IsMonotonic: true, @@ -64,7 +80,7 @@ func AssertEqualExporterQueueBatchSendSize(t *testing.T, tt *componenttest.Telem want := metricdata.Metrics{ Name: "otelcol_exporter_queue_batch_send_size", Description: "Number of units in the batch [Development]", - Unit: "{units}", + Unit: "{unit}", Data: metricdata.Histogram[int64]{ Temporality: metricdata.CumulativeTemporality, DataPoints: dps, @@ -94,7 +110,7 @@ func AssertEqualExporterQueueCapacity(t *testing.T, tt *componenttest.Telemetry, want := metricdata.Metrics{ Name: "otelcol_exporter_queue_capacity", Description: "Fixed capacity of the retry queue (in batches). [Alpha]", - Unit: "{batches}", + Unit: "{batch}", Data: metricdata.Gauge[int64]{ DataPoints: dps, }, @@ -108,7 +124,7 @@ func AssertEqualExporterQueueSize(t *testing.T, tt *componenttest.Telemetry, dps want := metricdata.Metrics{ Name: "otelcol_exporter_queue_size", Description: "Current size of the retry queue (in batches). [Alpha]", - Unit: "{batches}", + Unit: "{batch}", Data: metricdata.Gauge[int64]{ DataPoints: dps, }, @@ -121,8 +137,8 @@ func AssertEqualExporterQueueSize(t *testing.T, tt *componenttest.Telemetry, dps func AssertEqualExporterSendFailedLogRecords(t *testing.T, tt *componenttest.Telemetry, dps []metricdata.DataPoint[int64], opts ...metricdatatest.Option) { want := metricdata.Metrics{ Name: "otelcol_exporter_send_failed_log_records", - Description: "Number of log records in failed attempts to send to destination. [Alpha]", - Unit: "{records}", + Description: "Number of log records in failed attempts to send to destination. At detailed telemetry level, includes attributes: error.type (semantic convention), error.permanent. [Alpha]", + Unit: "{record}", Data: metricdata.Sum[int64]{ Temporality: metricdata.CumulativeTemporality, IsMonotonic: true, @@ -137,8 +153,8 @@ func AssertEqualExporterSendFailedLogRecords(t *testing.T, tt *componenttest.Tel func AssertEqualExporterSendFailedMetricPoints(t *testing.T, tt *componenttest.Telemetry, dps []metricdata.DataPoint[int64], opts ...metricdatatest.Option) { want := metricdata.Metrics{ Name: "otelcol_exporter_send_failed_metric_points", - Description: "Number of metric points in failed attempts to send to destination. [Alpha]", - Unit: "{datapoints}", + Description: "Number of metric points in failed attempts to send to destination. At detailed telemetry level, includes attributes: error.type (semantic convention), error.permanent. [Alpha]", + Unit: "{datapoint}", Data: metricdata.Sum[int64]{ Temporality: metricdata.CumulativeTemporality, IsMonotonic: true, @@ -150,11 +166,27 @@ func AssertEqualExporterSendFailedMetricPoints(t *testing.T, tt *componenttest.T metricdatatest.AssertEqual(t, want, got, opts...) } +func AssertEqualExporterSendFailedProfileSamples(t *testing.T, tt *componenttest.Telemetry, dps []metricdata.DataPoint[int64], opts ...metricdatatest.Option) { + want := metricdata.Metrics{ + Name: "otelcol_exporter_send_failed_profile_samples", + Description: "Number of profile samples in failed attempts to send to destination. At detailed telemetry level, includes attributes: error.type (semantic convention), error.permanent. [Development]", + Unit: "{sample}", + Data: metricdata.Sum[int64]{ + Temporality: metricdata.CumulativeTemporality, + IsMonotonic: true, + DataPoints: dps, + }, + } + got, err := tt.GetMetric("otelcol_exporter_send_failed_profile_samples") + require.NoError(t, err) + metricdatatest.AssertEqual(t, want, got, opts...) +} + func AssertEqualExporterSendFailedSpans(t *testing.T, tt *componenttest.Telemetry, dps []metricdata.DataPoint[int64], opts ...metricdatatest.Option) { want := metricdata.Metrics{ Name: "otelcol_exporter_send_failed_spans", - Description: "Number of spans in failed attempts to send to destination. [Alpha]", - Unit: "{spans}", + Description: "Number of spans in failed attempts to send to destination. At detailed telemetry level, includes attributes: error.type (semantic convention), error.permanent. [Alpha]", + Unit: "{span}", Data: metricdata.Sum[int64]{ Temporality: metricdata.CumulativeTemporality, IsMonotonic: true, @@ -170,7 +202,7 @@ func AssertEqualExporterSentLogRecords(t *testing.T, tt *componenttest.Telemetry want := metricdata.Metrics{ Name: "otelcol_exporter_sent_log_records", Description: "Number of log record successfully sent to destination. [Alpha]", - Unit: "{records}", + Unit: "{record}", Data: metricdata.Sum[int64]{ Temporality: metricdata.CumulativeTemporality, IsMonotonic: true, @@ -186,7 +218,7 @@ func AssertEqualExporterSentMetricPoints(t *testing.T, tt *componenttest.Telemet want := metricdata.Metrics{ Name: "otelcol_exporter_sent_metric_points", Description: "Number of metric points successfully sent to destination. [Alpha]", - Unit: "{datapoints}", + Unit: "{datapoint}", Data: metricdata.Sum[int64]{ Temporality: metricdata.CumulativeTemporality, IsMonotonic: true, @@ -198,11 +230,27 @@ func AssertEqualExporterSentMetricPoints(t *testing.T, tt *componenttest.Telemet metricdatatest.AssertEqual(t, want, got, opts...) } +func AssertEqualExporterSentProfileSamples(t *testing.T, tt *componenttest.Telemetry, dps []metricdata.DataPoint[int64], opts ...metricdatatest.Option) { + want := metricdata.Metrics{ + Name: "otelcol_exporter_sent_profile_samples", + Description: "Number of profile samples successfully sent to destination. [Development]", + Unit: "{sample}", + Data: metricdata.Sum[int64]{ + Temporality: metricdata.CumulativeTemporality, + IsMonotonic: true, + DataPoints: dps, + }, + } + got, err := tt.GetMetric("otelcol_exporter_sent_profile_samples") + require.NoError(t, err) + metricdatatest.AssertEqual(t, want, got, opts...) +} + func AssertEqualExporterSentSpans(t *testing.T, tt *componenttest.Telemetry, dps []metricdata.DataPoint[int64], opts ...metricdatatest.Option) { want := metricdata.Metrics{ Name: "otelcol_exporter_sent_spans", Description: "Number of spans successfully sent to destination. [Alpha]", - Unit: "{spans}", + Unit: "{span}", Data: metricdata.Sum[int64]{ Temporality: metricdata.CumulativeTemporality, IsMonotonic: true, diff --git a/exporter/exporterhelper/internal/metadatatest/generated_telemetrytest_test.go b/exporter/exporterhelper/internal/metadatatest/generated_telemetrytest_test.go index 838a03f504ac..39ec6b670d57 100644 --- a/exporter/exporterhelper/internal/metadatatest/generated_telemetrytest_test.go +++ b/exporter/exporterhelper/internal/metadatatest/generated_telemetrytest_test.go @@ -30,14 +30,17 @@ func TestSetupTelemetry(t *testing.T) { })) tb.ExporterEnqueueFailedLogRecords.Add(context.Background(), 1) tb.ExporterEnqueueFailedMetricPoints.Add(context.Background(), 1) + tb.ExporterEnqueueFailedProfileSamples.Add(context.Background(), 1) tb.ExporterEnqueueFailedSpans.Add(context.Background(), 1) tb.ExporterQueueBatchSendSize.Record(context.Background(), 1) tb.ExporterQueueBatchSendSizeBytes.Record(context.Background(), 1) tb.ExporterSendFailedLogRecords.Add(context.Background(), 1) tb.ExporterSendFailedMetricPoints.Add(context.Background(), 1) + tb.ExporterSendFailedProfileSamples.Add(context.Background(), 1) tb.ExporterSendFailedSpans.Add(context.Background(), 1) tb.ExporterSentLogRecords.Add(context.Background(), 1) tb.ExporterSentMetricPoints.Add(context.Background(), 1) + tb.ExporterSentProfileSamples.Add(context.Background(), 1) tb.ExporterSentSpans.Add(context.Background(), 1) AssertEqualExporterEnqueueFailedLogRecords(t, testTel, []metricdata.DataPoint[int64]{{Value: 1}}, @@ -45,6 +48,9 @@ func TestSetupTelemetry(t *testing.T) { AssertEqualExporterEnqueueFailedMetricPoints(t, testTel, []metricdata.DataPoint[int64]{{Value: 1}}, metricdatatest.IgnoreTimestamp()) + AssertEqualExporterEnqueueFailedProfileSamples(t, testTel, + []metricdata.DataPoint[int64]{{Value: 1}}, + metricdatatest.IgnoreTimestamp()) AssertEqualExporterEnqueueFailedSpans(t, testTel, []metricdata.DataPoint[int64]{{Value: 1}}, metricdatatest.IgnoreTimestamp()) @@ -66,6 +72,9 @@ func TestSetupTelemetry(t *testing.T) { AssertEqualExporterSendFailedMetricPoints(t, testTel, []metricdata.DataPoint[int64]{{Value: 1}}, metricdatatest.IgnoreTimestamp()) + AssertEqualExporterSendFailedProfileSamples(t, testTel, + []metricdata.DataPoint[int64]{{Value: 1}}, + metricdatatest.IgnoreTimestamp()) AssertEqualExporterSendFailedSpans(t, testTel, []metricdata.DataPoint[int64]{{Value: 1}}, metricdatatest.IgnoreTimestamp()) @@ -75,6 +84,9 @@ func TestSetupTelemetry(t *testing.T) { AssertEqualExporterSentMetricPoints(t, testTel, []metricdata.DataPoint[int64]{{Value: 1}}, metricdatatest.IgnoreTimestamp()) + AssertEqualExporterSentProfileSamples(t, testTel, + []metricdata.DataPoint[int64]{{Value: 1}}, + metricdatatest.IgnoreTimestamp()) AssertEqualExporterSentSpans(t, testTel, []metricdata.DataPoint[int64]{{Value: 1}}, metricdatatest.IgnoreTimestamp()) diff --git a/exporter/exporterhelper/internal/obs_report_sender.go b/exporter/exporterhelper/internal/obs_report_sender.go index 3438863ff510..db0538c8e87f 100644 --- a/exporter/exporterhelper/internal/obs_report_sender.go +++ b/exporter/exporterhelper/internal/obs_report_sender.go @@ -5,19 +5,26 @@ package internal // import "go.opentelemetry.io/collector/exporter/exporterhelpe import ( "context" + "errors" "go.opentelemetry.io/otel/attribute" - "go.opentelemetry.io/otel/codes" + otelcodes "go.opentelemetry.io/otel/codes" "go.opentelemetry.io/otel/metric" + semconv "go.opentelemetry.io/otel/semconv/v1.38.0" "go.opentelemetry.io/otel/trace" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" "go.opentelemetry.io/collector/component" + "go.opentelemetry.io/collector/consumer/consumererror" "go.opentelemetry.io/collector/exporter" + "go.opentelemetry.io/collector/exporter/exporterhelper/internal/experr" "go.opentelemetry.io/collector/exporter/exporterhelper/internal/metadata" "go.opentelemetry.io/collector/exporter/exporterhelper/internal/queuebatch" "go.opentelemetry.io/collector/exporter/exporterhelper/internal/request" "go.opentelemetry.io/collector/exporter/exporterhelper/internal/sender" "go.opentelemetry.io/collector/pipeline" + "go.opentelemetry.io/collector/pipeline/xpipeline" ) const ( @@ -34,6 +41,9 @@ const ( ItemsSent = "items.sent" // ItemsFailed used to track number of items that failed to be sent by exporters. ItemsFailed = "items.failed" + + // ErrorPermanentKey indicates whether the error is permanent (non-retryable). + ErrorPermanentKey = "error.permanent" ) type obsReportSender[K request.Request] struct { @@ -78,6 +88,9 @@ func newObsReportSender[K request.Request](set exporter.Settings, signal pipelin case pipeline.SignalLogs: or.itemsSentInst = telemetryBuilder.ExporterSentLogRecords or.itemsFailedInst = telemetryBuilder.ExporterSendFailedLogRecords + case xpipeline.SignalProfiles: + or.itemsSentInst = telemetryBuilder.ExporterSentProfileSamples + or.itemsFailedInst = telemetryBuilder.ExporterSendFailedProfileSamples } return or, nil @@ -105,16 +118,16 @@ func (ors *obsReportSender[K]) startOp(ctx context.Context) context.Context { } // EndOp completes the export operation that was started with StartOp. -func (ors *obsReportSender[K]) endOp(ctx context.Context, numLogRecords int, err error) { - numSent, numFailedToSend := toNumItems(numLogRecords, err) +func (ors *obsReportSender[K]) endOp(ctx context.Context, numRecords int, err error) { + numSent, numFailedToSend := toNumItems(numRecords, err) - // No metrics recorded for profiles. if ors.itemsSentInst != nil { ors.itemsSentInst.Add(ctx, numSent, ors.metricAttr) } - // No metrics recorded for profiles. - if ors.itemsFailedInst != nil { - ors.itemsFailedInst.Add(ctx, numFailedToSend, ors.metricAttr) + + if ors.itemsFailedInst != nil && numFailedToSend > 0 { + withFailedAttrs := metric.WithAttributeSet(extractFailureAttributes(err)) + ors.itemsFailedInst.Add(ctx, numFailedToSend, ors.metricAttr, withFailedAttrs) } span := trace.SpanFromContext(ctx) @@ -126,7 +139,7 @@ func (ors *obsReportSender[K]) endOp(ctx context.Context, numLogRecords int, err attribute.Int64(ItemsFailed, numFailedToSend), ) if err != nil { - span.SetStatus(codes.Error, err.Error()) + span.SetStatus(otelcodes.Error, err.Error()) } } } @@ -137,3 +150,38 @@ func toNumItems(numExportedItems int, err error) (int64, int64) { } return int64(numExportedItems), 0 } + +func extractFailureAttributes(err error) attribute.Set { + if err == nil { + return attribute.NewSet() + } + + attrs := []attribute.KeyValue{} + + errorType := determineErrorType(err) + attrs = append(attrs, attribute.String(string(semconv.ErrorTypeKey), errorType)) + + isPermanent := consumererror.IsPermanent(err) + attrs = append(attrs, attribute.Bool(ErrorPermanentKey, isPermanent)) + + return attribute.NewSet(attrs...) +} + +func determineErrorType(err error) string { + if experr.IsShutdownErr(err) { + return "Shutdown" + } + + if errors.Is(err, context.Canceled) { + return "Canceled" + } + if errors.Is(err, context.DeadlineExceeded) { + return "Deadline_Exceeded" + } + + if st, ok := status.FromError(err); ok && st.Code() != codes.OK { + return st.Code().String() + } + + return "_OTHER" +} diff --git a/exporter/exporterhelper/internal/obs_report_sender_test.go b/exporter/exporterhelper/internal/obs_report_sender_test.go index 0f54aef78532..f9a0209f60f2 100644 --- a/exporter/exporterhelper/internal/obs_report_sender_test.go +++ b/exporter/exporterhelper/internal/obs_report_sender_test.go @@ -6,6 +6,7 @@ package internal import ( "context" "errors" + "fmt" "testing" "github.com/stretchr/testify/assert" @@ -14,15 +15,21 @@ import ( "go.opentelemetry.io/otel/codes" "go.opentelemetry.io/otel/sdk/metric/metricdata" "go.opentelemetry.io/otel/sdk/metric/metricdata/metricdatatest" + semconv "go.opentelemetry.io/otel/semconv/v1.38.0" + grpccodes "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" "go.opentelemetry.io/collector/component" "go.opentelemetry.io/collector/component/componenttest" + "go.opentelemetry.io/collector/consumer/consumererror" "go.opentelemetry.io/collector/exporter" + "go.opentelemetry.io/collector/exporter/exporterhelper/internal/experr" "go.opentelemetry.io/collector/exporter/exporterhelper/internal/metadatatest" "go.opentelemetry.io/collector/exporter/exporterhelper/internal/request" "go.opentelemetry.io/collector/exporter/exporterhelper/internal/requesttest" "go.opentelemetry.io/collector/exporter/exporterhelper/internal/sender" "go.opentelemetry.io/collector/pipeline" + "go.opentelemetry.io/collector/pipeline/xpipeline" ) var ( @@ -31,6 +38,168 @@ var ( errFake = errors.New("errFake") ) +func TestExportTraceFailureAttributes(t *testing.T) { + tests := []struct { + name string + err error + numItems int + expectedType string + expectedPerm bool + useCustomCtx bool + ctxSetup func() context.Context + }{ + { + name: "PermanentError", + err: consumererror.NewPermanent(errors.New("bad data")), + numItems: 5, + expectedType: "_OTHER", + expectedPerm: true, + }, + { + name: "ShutdownError", + err: experr.NewShutdownErr(errors.New("shutting down")), + numItems: 3, + expectedType: "Shutdown", + expectedPerm: false, + }, + { + name: "ContextCanceled", + err: context.Canceled, + numItems: 2, + expectedType: "Canceled", + expectedPerm: false, + useCustomCtx: true, + ctxSetup: func() context.Context { + ctx, cancel := context.WithCancel(context.Background()) + cancel() + return ctx + }, + }, + { + name: "ContextDeadlineExceeded", + err: context.DeadlineExceeded, + numItems: 4, + expectedType: "Deadline_Exceeded", + expectedPerm: false, + }, + { + name: "UnknownError", + err: errFake, + numItems: 8, + expectedType: "_OTHER", + expectedPerm: false, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + telemetry := componenttest.NewTelemetry() + t.Cleanup(func() { require.NoError(t, telemetry.Shutdown(context.Background())) }) + + obsrep, err := newObsReportSender( + exporter.Settings{ID: exporterID, TelemetrySettings: telemetry.NewTelemetrySettings(), BuildInfo: component.NewDefaultBuildInfo()}, + pipeline.SignalTraces, + sender.NewSender(func(context.Context, request.Request) error { + return tt.err + }), + ) + require.NoError(t, err) + + ctx := context.Background() + if tt.useCustomCtx && tt.ctxSetup != nil { + ctx = tt.ctxSetup() + } + + req := &requesttest.FakeRequest{Items: tt.numItems} + sendErr := obsrep.Send(ctx, req) + require.Error(t, sendErr) + + wantAttrs := attribute.NewSet( + attribute.String("exporter", exporterID.String()), + attribute.String(string(semconv.ErrorTypeKey), tt.expectedType), + attribute.Bool(ErrorPermanentKey, tt.expectedPerm), + ) + + metadatatest.AssertEqualExporterSendFailedSpans(t, telemetry, + []metricdata.DataPoint[int64]{ + { + Attributes: wantAttrs, + Value: int64(req.Items), + }, + }, metricdatatest.IgnoreTimestamp(), metricdatatest.IgnoreExemplars()) + }) + } +} + +func TestExportTraceFailureAttributesGRPCError(t *testing.T) { + tests := []struct { + name string + grpcCode grpccodes.Code + expectedType string + isPermanent bool + }{ + { + name: "Unavailable", + grpcCode: grpccodes.Unavailable, + expectedType: "Unavailable", + isPermanent: false, + }, + { + name: "ResourceExhausted", + grpcCode: grpccodes.ResourceExhausted, + expectedType: "ResourceExhausted", + isPermanent: false, + }, + { + name: "DataLoss", + grpcCode: grpccodes.DataLoss, + expectedType: "DataLoss", + isPermanent: false, + }, + { + name: "InvalidArgument", + grpcCode: grpccodes.InvalidArgument, + expectedType: "InvalidArgument", + isPermanent: false, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + telemetry := componenttest.NewTelemetry() + t.Cleanup(func() { require.NoError(t, telemetry.Shutdown(context.Background())) }) + + grpcErr := status.Error(tt.grpcCode, "test error") + obsrep, err := newObsReportSender( + exporter.Settings{ID: exporterID, TelemetrySettings: telemetry.NewTelemetrySettings(), BuildInfo: component.NewDefaultBuildInfo()}, + pipeline.SignalTraces, + sender.NewSender(func(context.Context, request.Request) error { + return grpcErr + }), + ) + require.NoError(t, err) + + req := &requesttest.FakeRequest{Items: 10} + sendErr := obsrep.Send(context.Background(), req) + require.Error(t, sendErr) + + wantAttrs := attribute.NewSet( + attribute.String("exporter", exporterID.String()), + attribute.String(string(semconv.ErrorTypeKey), tt.expectedType), + attribute.Bool(ErrorPermanentKey, tt.isPermanent), + ) + + metadatatest.AssertEqualExporterSendFailedSpans(t, telemetry, + []metricdata.DataPoint[int64]{ + { + Attributes: wantAttrs, + Value: int64(req.Items), + }, + }, metricdatatest.IgnoreTimestamp(), metricdatatest.IgnoreExemplars()) + }) + } +} + func TestExportTraceDataOp(t *testing.T) { tt := componenttest.NewTelemetry() t.Cleanup(func() { require.NoError(t, tt.Shutdown(context.Background())) }) @@ -87,16 +256,22 @@ func TestExportTraceDataOp(t *testing.T) { }, }, metricdatatest.IgnoreTimestamp(), metricdatatest.IgnoreExemplars()) + var expectedDataPoints []metricdata.DataPoint[int64] if failedToSendSpans > 0 { - metadatatest.AssertEqualExporterSendFailedSpans(t, tt, - []metricdata.DataPoint[int64]{ - { - Attributes: attribute.NewSet( - attribute.String("exporter", exporterID.String())), - Value: int64(failedToSendSpans), - }, - }, metricdatatest.IgnoreTimestamp(), metricdatatest.IgnoreExemplars()) + wantAttrs := attribute.NewSet( + attribute.String("exporter", exporterID.String()), + attribute.String(string(semconv.ErrorTypeKey), "_OTHER"), + attribute.Bool(ErrorPermanentKey, false), + ) + expectedDataPoints = []metricdata.DataPoint[int64]{ + { + Attributes: wantAttrs, + Value: int64(failedToSendSpans), + }, + } } + metadatatest.AssertEqualExporterSendFailedSpans(t, tt, expectedDataPoints, + metricdatatest.IgnoreTimestamp(), metricdatatest.IgnoreExemplars()) } func TestExportMetricsOp(t *testing.T) { @@ -155,16 +330,22 @@ func TestExportMetricsOp(t *testing.T) { }, }, metricdatatest.IgnoreTimestamp(), metricdatatest.IgnoreExemplars()) + var expectedDataPoints []metricdata.DataPoint[int64] if failedToSendMetricPoints > 0 { - metadatatest.AssertEqualExporterSendFailedMetricPoints(t, tt, - []metricdata.DataPoint[int64]{ - { - Attributes: attribute.NewSet( - attribute.String("exporter", exporterID.String())), - Value: int64(failedToSendMetricPoints), - }, - }, metricdatatest.IgnoreTimestamp(), metricdatatest.IgnoreExemplars()) + wantAttrs := attribute.NewSet( + attribute.String("exporter", exporterID.String()), + attribute.String(string(semconv.ErrorTypeKey), "_OTHER"), + attribute.Bool(ErrorPermanentKey, false), + ) + expectedDataPoints = []metricdata.DataPoint[int64]{ + { + Attributes: wantAttrs, + Value: int64(failedToSendMetricPoints), + }, + } } + metadatatest.AssertEqualExporterSendFailedMetricPoints(t, tt, expectedDataPoints, + metricdatatest.IgnoreTimestamp(), metricdatatest.IgnoreExemplars()) } func TestExportLogsOp(t *testing.T) { @@ -223,16 +404,218 @@ func TestExportLogsOp(t *testing.T) { }, }, metricdatatest.IgnoreTimestamp(), metricdatatest.IgnoreExemplars()) + var expectedDataPoints []metricdata.DataPoint[int64] if failedToSendLogRecords > 0 { - metadatatest.AssertEqualExporterSendFailedLogRecords(t, tt, - []metricdata.DataPoint[int64]{ - { - Attributes: attribute.NewSet( - attribute.String("exporter", exporterID.String())), - Value: int64(failedToSendLogRecords), - }, - }, metricdatatest.IgnoreTimestamp(), metricdatatest.IgnoreExemplars()) + wantAttrs := attribute.NewSet( + attribute.String("exporter", exporterID.String()), + attribute.String(string(semconv.ErrorTypeKey), "_OTHER"), + attribute.Bool(ErrorPermanentKey, false), + ) + expectedDataPoints = []metricdata.DataPoint[int64]{ + { + Attributes: wantAttrs, + Value: int64(failedToSendLogRecords), + }, + } + } + metadatatest.AssertEqualExporterSendFailedLogRecords(t, tt, expectedDataPoints, + metricdatatest.IgnoreTimestamp(), metricdatatest.IgnoreExemplars()) +} + +// TestDetermineErrorType tests the determineErrorType function directly +func TestDetermineErrorType(t *testing.T) { + tests := []struct { + name string + err error + expectedErrorType string + }{ + { + name: "shutdown error", + err: experr.NewShutdownErr(errors.New("shutting down")), + expectedErrorType: "Shutdown", + }, + { + name: "context canceled", + err: context.Canceled, + expectedErrorType: "Canceled", + }, + { + name: "context deadline exceeded", + err: context.DeadlineExceeded, + expectedErrorType: "Deadline_Exceeded", + }, + { + name: "unknown error", + err: errors.New("some error"), + expectedErrorType: "_OTHER", + }, + { + name: "wrapped context canceled", + err: fmt.Errorf("failed: %w", context.Canceled), + expectedErrorType: "Canceled", + }, + { + name: "wrapped context deadline exceeded", + err: fmt.Errorf("timeout: %w", context.DeadlineExceeded), + expectedErrorType: "Deadline_Exceeded", + }, + { + name: "gRPC Unavailable", + err: status.Error(grpccodes.Unavailable, "service unavailable"), + expectedErrorType: "Unavailable", + }, + { + name: "gRPC ResourceExhausted", + err: status.Error(grpccodes.ResourceExhausted, "quota exceeded"), + expectedErrorType: "ResourceExhausted", + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + errorType := determineErrorType(tt.err) + assert.Equal(t, tt.expectedErrorType, errorType, "error.type mismatch") + }) + } +} + +// TestExtractFailureAttributes tests the extractFailureAttributes function directly +func TestExtractFailureAttributes(t *testing.T) { + tests := []struct { + name string + err error + expected attribute.Set + }{ + { + name: "permanent error", + err: consumererror.NewPermanent(errors.New("bad data")), + expected: attribute.NewSet( + attribute.String(string(semconv.ErrorTypeKey), "_OTHER"), + attribute.Bool(ErrorPermanentKey, true), + ), + }, + { + name: "non-permanent error", + err: errors.New("transient error"), + expected: attribute.NewSet( + attribute.String(string(semconv.ErrorTypeKey), "_OTHER"), + attribute.Bool(ErrorPermanentKey, false), + ), + }, + { + name: "shutdown error", + err: experr.NewShutdownErr(errors.New("shutdown")), + expected: attribute.NewSet( + attribute.String(string(semconv.ErrorTypeKey), "Shutdown"), + attribute.Bool(ErrorPermanentKey, false), + ), + }, + { + name: "context canceled", + err: context.Canceled, + expected: attribute.NewSet( + attribute.String(string(semconv.ErrorTypeKey), "Canceled"), + attribute.Bool(ErrorPermanentKey, false), + ), + }, + { + name: "context deadline exceeded", + err: context.DeadlineExceeded, + expected: attribute.NewSet( + attribute.String(string(semconv.ErrorTypeKey), "Deadline_Exceeded"), + attribute.Bool(ErrorPermanentKey, false), + ), + }, + { + name: "gRPC Unavailable", + err: status.Error(grpccodes.Unavailable, "service unavailable"), + expected: attribute.NewSet( + attribute.String(string(semconv.ErrorTypeKey), "Unavailable"), + attribute.Bool(ErrorPermanentKey, false), + ), + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + result := extractFailureAttributes(tt.err) + assert.Equal(t, tt.expected, result) + }) + } +} + +func TestExportProfilesOp(t *testing.T) { + tt := componenttest.NewTelemetry() + t.Cleanup(func() { require.NoError(t, tt.Shutdown(context.Background())) }) + + parentCtx, parentSpan := tt.NewTelemetrySettings().TracerProvider.Tracer("test").Start(context.Background(), t.Name()) + defer parentSpan.End() + + var exporterErr error + obsrep, err := newObsReportSender( + exporter.Settings{ID: exporterID, TelemetrySettings: tt.NewTelemetrySettings(), BuildInfo: component.NewDefaultBuildInfo()}, + xpipeline.SignalProfiles, + sender.NewSender(func(context.Context, request.Request) error { return exporterErr }), + ) + require.NoError(t, err) + + params := []testParams{ + {items: 17, err: nil}, + {items: 23, err: errFake}, + } + for i := range params { + exporterErr = params[i].err + require.ErrorIs(t, obsrep.Send(parentCtx, &requesttest.FakeRequest{Items: params[i].items}), params[i].err) + } + + spans := tt.SpanRecorder.Ended() + require.Len(t, spans, len(params)) + + var sentProfileRecords, failedToSendProfileRecords int + for i, span := range spans { + assert.Equal(t, "exporter/"+exporterID.String()+"/profiles", span.Name()) + switch { + case params[i].err == nil: + sentProfileRecords += params[i].items + require.Contains(t, span.Attributes(), attribute.KeyValue{Key: ItemsSent, Value: attribute.Int64Value(int64(params[i].items))}) + require.Contains(t, span.Attributes(), attribute.KeyValue{Key: ItemsFailed, Value: attribute.Int64Value(0)}) + assert.Equal(t, codes.Unset, span.Status().Code) + case errors.Is(params[i].err, errFake): + failedToSendProfileRecords += params[i].items + require.Contains(t, span.Attributes(), attribute.KeyValue{Key: ItemsSent, Value: attribute.Int64Value(0)}) + require.Contains(t, span.Attributes(), attribute.KeyValue{Key: ItemsFailed, Value: attribute.Int64Value(int64(params[i].items))}) + assert.Equal(t, codes.Error, span.Status().Code) + assert.Equal(t, params[i].err.Error(), span.Status().Description) + default: + t.Fatalf("unexpected error: %v", params[i].err) + } + } + + metadatatest.AssertEqualExporterSentProfileSamples(t, tt, + []metricdata.DataPoint[int64]{ + { + Attributes: attribute.NewSet( + attribute.String("exporter", exporterID.String())), + Value: int64(sentProfileRecords), + }, + }, metricdatatest.IgnoreTimestamp(), metricdatatest.IgnoreExemplars()) + + var expectedDataPoints []metricdata.DataPoint[int64] + if failedToSendProfileRecords > 0 { + wantAttrs := attribute.NewSet( + attribute.String("exporter", exporterID.String()), + attribute.String(string(semconv.ErrorTypeKey), "_OTHER"), + attribute.Bool(ErrorPermanentKey, false), + ) + expectedDataPoints = []metricdata.DataPoint[int64]{ + { + Attributes: wantAttrs, + Value: int64(failedToSendProfileRecords), + }, + } } + metadatatest.AssertEqualExporterSendFailedProfileSamples(t, tt, expectedDataPoints, + metricdatatest.IgnoreTimestamp(), metricdatatest.IgnoreExemplars()) } type testParams struct { diff --git a/exporter/exporterhelper/internal/queue/async_queue.go b/exporter/exporterhelper/internal/queue/async_queue.go index 99304dd37741..d5e8a1618e20 100644 --- a/exporter/exporterhelper/internal/queue/async_queue.go +++ b/exporter/exporterhelper/internal/queue/async_queue.go @@ -36,11 +36,9 @@ func (qc *asyncQueue[T]) Start(ctx context.Context, host component.Host) error { } var startWG sync.WaitGroup for i := 0; i < qc.numConsumers; i++ { - qc.stopWG.Add(1) startWG.Add(1) - go func() { //nolint:contextcheck + qc.stopWG.Go(func() { //nolint:contextcheck startWG.Done() - defer qc.stopWG.Done() for { ctx, req, done, ok := qc.Read(context.Background()) if !ok { @@ -51,7 +49,7 @@ func (qc *asyncQueue[T]) Start(ctx context.Context, host component.Host) error { qc.refCounter.Unref(req) } } - }() + }) } startWG.Wait() diff --git a/exporter/exporterhelper/internal/queue/async_queue_test.go b/exporter/exporterhelper/internal/queue/async_queue_test.go index 17d12b3db184..3d92da5ce691 100644 --- a/exporter/exporterhelper/internal/queue/async_queue_test.go +++ b/exporter/exporterhelper/internal/queue/async_queue_test.go @@ -46,13 +46,11 @@ func TestAsyncMemoryQueueBlocking(t *testing.T) { require.NoError(t, ac.Start(context.Background(), componenttest.NewNopHost())) wg := &sync.WaitGroup{} for range 10 { - wg.Add(1) - go func() { - defer wg.Done() + wg.Go(func() { for range 100_000 { assert.NoError(t, ac.Offer(context.Background(), 10)) } - }() + }) } wg.Wait() require.NoError(t, ac.Shutdown(context.Background())) @@ -72,13 +70,11 @@ func TestAsyncMemoryWaitForResultQueueBlocking(t *testing.T) { require.NoError(t, ac.Start(context.Background(), componenttest.NewNopHost())) wg := &sync.WaitGroup{} for range 10 { - wg.Add(1) - go func() { - defer wg.Done() + wg.Go(func() { for range 100_000 { assert.NoError(t, ac.Offer(context.Background(), 10)) } - }() + }) } wg.Wait() require.NoError(t, ac.Shutdown(context.Background())) @@ -98,14 +94,12 @@ func TestAsyncMemoryQueueBlockingCancelled(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) wg := sync.WaitGroup{} - wg.Add(1) - go func() { - defer wg.Done() + wg.Go(func() { for range 10 { - assert.NoError(t, ac.Offer(ctx, 1)) + require.NoError(t, ac.Offer(ctx, 1)) } assert.ErrorIs(t, ac.Offer(ctx, 3), context.Canceled) - }() + }) // Sleep some time so that the go-routine blocks, it doesn't have to but even if it // does things will work. <-time.After(1 * time.Second) diff --git a/exporter/exporterhelper/internal/queue/fg.go b/exporter/exporterhelper/internal/queue/fg.go index 31e7d13fc77c..27969fe31575 100644 --- a/exporter/exporterhelper/internal/queue/fg.go +++ b/exporter/exporterhelper/internal/queue/fg.go @@ -3,19 +3,11 @@ package queue // import "go.opentelemetry.io/collector/exporter/exporterhelper/internal/queue" -import "go.opentelemetry.io/collector/featuregate" - -// PersistRequestContextFeatureGate controls whether request context should be preserved in the persistent queue. -var PersistRequestContextFeatureGate = featuregate.GlobalRegistry().MustRegister( - "exporter.PersistRequestContext", - featuregate.StageBeta, - featuregate.WithRegisterFromVersion("v0.128.0"), - featuregate.WithRegisterDescription("controls whether context should be stored alongside requests in the persistent queue"), -) +import "go.opentelemetry.io/collector/exporter/exporterhelper/internal/metadata" // assign the feature gate to separate functions to make it possible to override the behavior in tests // on write and read paths separately. var ( - PersistRequestContextOnRead = PersistRequestContextFeatureGate.IsEnabled - PersistRequestContextOnWrite = PersistRequestContextFeatureGate.IsEnabled + PersistRequestContextOnRead = metadata.ExporterPersistRequestContextFeatureGate.IsEnabled + PersistRequestContextOnWrite = metadata.ExporterPersistRequestContextFeatureGate.IsEnabled ) diff --git a/exporter/exporterhelper/internal/queue/memory_queue_test.go b/exporter/exporterhelper/internal/queue/memory_queue_test.go index d792a09273de..90f72b6d8b09 100644 --- a/exporter/exporterhelper/internal/queue/memory_queue_test.go +++ b/exporter/exporterhelper/internal/queue/memory_queue_test.go @@ -60,11 +60,9 @@ func TestMemoryQueueBlockingCancelled(t *testing.T) { require.NoError(t, q.Offer(context.Background(), 3)) ctx, cancel := context.WithCancel(context.Background()) wg := sync.WaitGroup{} - wg.Add(1) - go func() { - defer wg.Done() + wg.Go(func() { assert.ErrorIs(t, q.Offer(ctx, 3), context.Canceled) - }() + }) cancel() wg.Wait() assert.EqualValues(t, 3, q.Size()) @@ -141,14 +139,12 @@ func TestMemoryQueueWaitForResultPassErrorBack(t *testing.T) { set.WaitForResult = true q := newMemoryQueue[intRequest](set) require.NoError(t, q.Start(context.Background(), componenttest.NewNopHost())) - wg.Add(1) - go func() { - defer wg.Done() + wg.Go(func() { _, req, done, ok := q.Read(context.Background()) assert.True(t, ok) assert.EqualValues(t, 1, req) done.OnDone(myErr) - }() + }) require.ErrorIs(t, q.Offer(context.Background(), intRequest(1)), myErr) require.NoError(t, q.Shutdown(context.Background())) wg.Wait() @@ -163,22 +159,18 @@ func TestMemoryQueueWaitForResultCancelIncomingRequest(t *testing.T) { require.NoError(t, q.Start(context.Background(), componenttest.NewNopHost())) // Consume async new data. - wg.Add(1) - go func() { - defer wg.Done() + wg.Go(func() { _, _, done, ok := q.Read(context.Background()) assert.True(t, ok) <-stop done.OnDone(nil) - }() + }) ctx, cancel := context.WithCancel(context.Background()) - wg.Add(1) - go func() { - defer wg.Done() + wg.Go(func() { <-time.After(time.Second) cancel() - }() + }) require.ErrorIs(t, q.Offer(ctx, intRequest(1)), context.Canceled) close(stop) require.NoError(t, q.Shutdown(context.Background())) @@ -194,22 +186,18 @@ func TestMemoryQueueWaitForResultSizeAndCapacity(t *testing.T) { require.NoError(t, q.Start(context.Background(), componenttest.NewNopHost())) // Consume async new data. - wg.Add(1) - go func() { - defer wg.Done() + wg.Go(func() { _, _, done, ok := q.Read(context.Background()) assert.True(t, ok) <-stop done.OnDone(nil) - }() + }) assert.EqualValues(t, 0, q.Size()) assert.EqualValues(t, 100, q.Capacity()) - wg.Add(1) - go func() { - defer wg.Done() + wg.Go(func() { assert.NoError(t, q.Offer(context.Background(), intRequest(1))) - }() + }) assert.Eventually(t, func() bool { return q.Size() == 1 }, 1*time.Second, 10*time.Millisecond) assert.EqualValues(t, 100, q.Capacity()) close(stop) @@ -226,9 +214,7 @@ func BenchmarkMemoryQueueWaitForResult(b *testing.B) { require.NoError(b, q.Start(context.Background(), componenttest.NewNopHost())) // Consume async new data. - wg.Add(1) - go func() { - defer wg.Done() + wg.Go(func() { for { _, req, done, ok := q.Read(context.Background()) if !ok { @@ -237,7 +223,7 @@ func BenchmarkMemoryQueueWaitForResult(b *testing.B) { consumed.Add(int64(req)) done.OnDone(nil) } - }() + }) b.ReportAllocs() for b.Loop() { diff --git a/exporter/exporterhelper/internal/queue/obs_queue.go b/exporter/exporterhelper/internal/queue/obs_queue.go index 8cad69620676..8900d83d7090 100644 --- a/exporter/exporterhelper/internal/queue/obs_queue.go +++ b/exporter/exporterhelper/internal/queue/obs_queue.go @@ -13,6 +13,7 @@ import ( "go.opentelemetry.io/collector/exporter/exporterhelper/internal/metadata" "go.opentelemetry.io/collector/exporter/exporterhelper/internal/request" "go.opentelemetry.io/collector/pipeline" + "go.opentelemetry.io/collector/pipeline/xpipeline" ) const ( @@ -74,6 +75,8 @@ func newObsQueue[T request.Request](set Settings[T], delegate Queue[T]) (Queue[T or.enqueueFailedInst = tb.ExporterEnqueueFailedMetricPoints case pipeline.SignalLogs: or.enqueueFailedInst = tb.ExporterEnqueueFailedLogRecords + case xpipeline.SignalProfiles: + or.enqueueFailedInst = tb.ExporterEnqueueFailedProfileSamples } or.queueBatchSizeInst = tb.ExporterQueueBatchSendSize diff --git a/exporter/exporterhelper/internal/queue/obs_queue_test.go b/exporter/exporterhelper/internal/queue/obs_queue_test.go index f797b26a823a..184b4bed06ea 100644 --- a/exporter/exporterhelper/internal/queue/obs_queue_test.go +++ b/exporter/exporterhelper/internal/queue/obs_queue_test.go @@ -20,6 +20,7 @@ import ( "go.opentelemetry.io/collector/exporter/exporterhelper/internal/requesttest" "go.opentelemetry.io/collector/exporter/exportertest" "go.opentelemetry.io/collector/pipeline" + "go.opentelemetry.io/collector/pipeline/xpipeline" ) var exporterID = component.NewID(exportertest.NopType) @@ -203,6 +204,58 @@ func TestObsQueueMetricsFailure(t *testing.T) { }, metricdatatest.IgnoreTimestamp(), metricdatatest.IgnoreExemplars()) } +func TestObsQueueProfiles(t *testing.T) { + tt := componenttest.NewTelemetry() + t.Cleanup(func() { require.NoError(t, tt.Shutdown(context.Background())) }) + + te, err := newObsQueue[request.Request](Settings[request.Request]{ + Signal: xpipeline.SignalProfiles, + ID: exporterID, + Telemetry: tt.NewTelemetrySettings(), + }, newFakeQueue[request.Request](nil, 27, 29)) + require.NoError(t, err) + require.NoError(t, te.Offer(context.Background(), &requesttest.FakeRequest{Items: 22})) + metadatatest.AssertEqualExporterQueueSize(t, tt, + []metricdata.DataPoint[int64]{ + { + Attributes: attribute.NewSet( + attribute.String(exporterKey, exporterID.String()), + attribute.String(dataTypeKey, xpipeline.SignalProfiles.String())), + Value: int64(27), + }, + }, metricdatatest.IgnoreTimestamp()) + metadatatest.AssertEqualExporterQueueCapacity(t, tt, + []metricdata.DataPoint[int64]{ + { + Attributes: attribute.NewSet( + attribute.String(exporterKey, exporterID.String()), + attribute.String(dataTypeKey, xpipeline.SignalProfiles.String())), + Value: int64(29), + }, + }, metricdatatest.IgnoreTimestamp()) +} + +func TestObsQueueProfilesFailure(t *testing.T) { + tt := componenttest.NewTelemetry() + t.Cleanup(func() { require.NoError(t, tt.Shutdown(context.Background())) }) + + te, err := newObsQueue[request.Request](Settings[request.Request]{ + Signal: xpipeline.SignalProfiles, + ID: exporterID, + Telemetry: tt.NewTelemetrySettings(), + }, newFakeQueue[request.Request](errors.New("my error"), 0, 0)) + require.NoError(t, err) + require.Error(t, te.Offer(context.Background(), &requesttest.FakeRequest{Items: 22})) + metadatatest.AssertEqualExporterEnqueueFailedProfileSamples(t, tt, + []metricdata.DataPoint[int64]{ + { + Attributes: attribute.NewSet( + attribute.String(exporterKey, exporterID.String())), + Value: int64(22), + }, + }, metricdatatest.IgnoreTimestamp(), metricdatatest.IgnoreExemplars()) +} + func TestObsQueueLogsBatchSize(t *testing.T) { tt := componenttest.NewTelemetry() t.Cleanup(func() { require.NoError(t, tt.Shutdown(context.Background())) }) @@ -280,3 +333,29 @@ func TestObsQueueMetricsBatchSize(t *testing.T) { }, }, metricdatatest.IgnoreTimestamp()) } + +func TestObsQueueProfilesBatchSize(t *testing.T) { + tt := componenttest.NewTelemetry() + t.Cleanup(func() { require.NoError(t, tt.Shutdown(context.Background())) }) + + te, err := newObsQueue[request.Request](Settings[request.Request]{ + Signal: xpipeline.SignalProfiles, + ID: exporterID, + Telemetry: tt.NewTelemetrySettings(), + }, newFakeQueue[request.Request](nil, 27, 29)) + require.NoError(t, err) + require.NoError(t, te.Offer(context.Background(), &requesttest.FakeRequest{Items: 22, Bytes: 300})) + metadatatest.AssertEqualExporterQueueBatchSendSize(t, tt, + []metricdata.HistogramDataPoint[int64]{ + { + Attributes: attribute.NewSet( + attribute.String(exporterKey, exporterID.String())), + Count: 1, + Bounds: []float64{10, 25, 50, 75, 100, 250, 500, 750, 1000, 2000, 3000, 4000, 5000, 6000, 7000, 8000, 9000, 10000, 20000, 30000, 50000, 100000}, + BucketCounts: []uint64{0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + Min: metricdata.NewExtrema[int64](22), + Max: metricdata.NewExtrema[int64](22), + Sum: 22, + }, + }, metricdatatest.IgnoreTimestamp()) +} diff --git a/exporter/exporterhelper/internal/queue/persistent_queue.go b/exporter/exporterhelper/internal/queue/persistent_queue.go index a4ddf2e330b5..4fcb074b6ac1 100644 --- a/exporter/exporterhelper/internal/queue/persistent_queue.go +++ b/exporter/exporterhelper/internal/queue/persistent_queue.go @@ -141,7 +141,6 @@ func (pq *persistentQueue[T]) internalSize() int64 { } func (pq *persistentQueue[T]) requestSize() int64 { - //nolint:gosec return int64(pq.metadata.WriteIndex-pq.metadata.ReadIndex) + int64(len(pq.metadata.CurrentlyDispatchedItems)) } diff --git a/exporter/exporterhelper/internal/queue/persistent_queue_test.go b/exporter/exporterhelper/internal/queue/persistent_queue_test.go index 6633a90f7686..546f8724032a 100644 --- a/exporter/exporterhelper/internal/queue/persistent_queue_test.go +++ b/exporter/exporterhelper/internal/queue/persistent_queue_test.go @@ -432,13 +432,11 @@ func TestPersistentBlockingQueue(t *testing.T) { td := intRequest(10) wg := &sync.WaitGroup{} for range 10 { - wg.Add(1) - go func() { - defer wg.Done() + wg.Go(func() { for range 100_000 { assert.NoError(t, pq.Offer(context.Background(), td)) } - }() + }) } wg.Wait() // Because the persistent queue is not draining after Shutdown, need to wait here for the drain. @@ -710,9 +708,7 @@ func TestPersistentQueueStartWithNonDispatchedConcurrent(t *testing.T) { proWg := sync.WaitGroup{} // Sending small amount of data as windows test can't handle the test fast enough for range 5 { - proWg.Add(1) - go func() { - defer proWg.Done() + proWg.Go(func() { // Put in items up to capacity for range 10 { for { @@ -723,18 +719,16 @@ func TestPersistentQueueStartWithNonDispatchedConcurrent(t *testing.T) { time.Sleep(50 * time.Nanosecond) } } - }() + }) } conWg := sync.WaitGroup{} for range 5 { - conWg.Add(1) - go func() { - defer conWg.Done() + conWg.Go(func() { for range 10 { assert.True(t, consume(pq, func(context.Context, intRequest) error { return nil })) } - }() + }) } conDone := make(chan struct{}) @@ -1185,7 +1179,6 @@ func requireCurrentlyDispatchedItemsEqual(t *testing.T, pq *persistentQueue[intR func itemIndexArrayToBytes(arr []uint64) []byte { size := len(arr) buf := make([]byte, 0, 4+size*8) - //nolint:gosec buf = binary.LittleEndian.AppendUint32(buf, uint32(size)) for _, item := range arr { buf = binary.LittleEndian.AppendUint64(buf, item) diff --git a/exporter/exporterhelper/internal/queue_sender.go b/exporter/exporterhelper/internal/queue_sender.go index c49c7265647e..804f34a7233f 100644 --- a/exporter/exporterhelper/internal/queue_sender.go +++ b/exporter/exporterhelper/internal/queue_sender.go @@ -16,15 +16,16 @@ import ( ) // NewDefaultQueueConfig returns the default config for queuebatch.Config. -// By default, the queue stores 1000 requests of telemetry and is non-blocking when full. +// By default: +// +// - the queue stores 1000 requests of telemetry +// - is non-blocking when full +// - concurrent exports limited to 10 +// - emits batches of 8192 items, timeout 200ms func NewDefaultQueueConfig() queuebatch.Config { return queuebatch.Config{ - Enabled: true, - Sizer: request.SizerTypeRequests, - NumConsumers: 10, - // By default, batches are 8192 spans, for a total of up to 8 million spans in the queue - // This can be estimated at 1-4 GB worth of maximum memory usage - // This default is probably still too high, and may be adjusted further down in a future release + Sizer: request.SizerTypeRequests, + NumConsumers: 10, QueueSize: 1_000, BlockOnOverflow: false, Batch: configoptional.Default(queuebatch.BatchConfig{ diff --git a/exporter/exporterhelper/internal/queue_sender_test.go b/exporter/exporterhelper/internal/queue_sender_test.go index ad6020b5a1f5..94546f7a47ad 100644 --- a/exporter/exporterhelper/internal/queue_sender_test.go +++ b/exporter/exporterhelper/internal/queue_sender_test.go @@ -15,6 +15,7 @@ import ( "go.opentelemetry.io/collector/component" "go.opentelemetry.io/collector/component/componenttest" + "go.opentelemetry.io/collector/config/configoptional" "go.opentelemetry.io/collector/exporter/exporterhelper/internal/queuebatch" "go.opentelemetry.io/collector/exporter/exporterhelper/internal/request" "go.opentelemetry.io/collector/exporter/exporterhelper/internal/requesttest" @@ -31,8 +32,9 @@ func TestNewQueueSenderFailedRequestDropped(t *testing.T) { } logger, observed := observer.New(zap.ErrorLevel) qSet.Telemetry.Logger = zap.New(logger) + qCfg := NewDefaultQueueConfig() be, err := NewQueueSender( - qSet, NewDefaultQueueConfig(), "", sender.NewSender(func(context.Context, request.Request) error { return errors.New("some error") })) + qSet, qCfg, "", sender.NewSender(func(context.Context, request.Request) error { return errors.New("some error") })) require.NoError(t, err) require.NoError(t, be.Start(context.Background(), componenttest.NewNopHost())) @@ -54,6 +56,6 @@ func TestQueueConfig_Validate(t *testing.T) { require.EqualError(t, qCfg.Validate(), "`queue_size` must be positive") // Confirm Validate doesn't return error with invalid config when feature is disabled - qCfg.Enabled = false - assert.NoError(t, qCfg.Validate()) + noCfg := configoptional.None[queuebatch.Config]() + assert.NoError(t, noCfg.Validate()) } diff --git a/exporter/exporterhelper/internal/queuebatch/batcher.go b/exporter/exporterhelper/internal/queuebatch/batcher.go index 6d4fcfb7e116..3b393be8855f 100644 --- a/exporter/exporterhelper/internal/queuebatch/batcher.go +++ b/exporter/exporterhelper/internal/queuebatch/batcher.go @@ -41,8 +41,12 @@ func NewBatcher(cfg configoptional.Optional[BatchConfig], set batcherSettings[re } if set.partitioner == nil { - return newPartitionBatcher(*cfg.Get(), sizer, set.mergeCtx, newWorkerPool(set.maxWorkers), set.next, set.logger), nil + return newPartitionBatcher(*cfg.Get(), sizer, set.mergeCtx, newWorkerPool(set.maxWorkers), set.next, set.logger, nil), nil } - return newMultiBatcher(*cfg.Get(), sizer, newWorkerPool(set.maxWorkers), set.partitioner, set.mergeCtx, set.next, set.logger), nil + mb, err := newMultiBatcher(*cfg.Get(), sizer, newWorkerPool(set.maxWorkers), set.partitioner, set.mergeCtx, set.next, set.logger) + if err != nil { + return nil, fmt.Errorf("error during creating multi batcher: %w", err) + } + return mb, nil } diff --git a/exporter/exporterhelper/internal/queuebatch/config.go b/exporter/exporterhelper/internal/queuebatch/config.go index c7b4e97658dc..d58cb9835ad5 100644 --- a/exporter/exporterhelper/internal/queuebatch/config.go +++ b/exporter/exporterhelper/internal/queuebatch/config.go @@ -6,6 +6,7 @@ package queuebatch // import "go.opentelemetry.io/collector/exporter/exporterhel import ( "errors" "fmt" + "strings" "time" "go.opentelemetry.io/collector/component" @@ -16,9 +17,6 @@ import ( // Config defines configuration for queueing and batching incoming requests. type Config struct { - // Enabled indicates whether to not enqueue and batch before exporting. - Enabled bool `mapstructure:"enabled"` - // WaitForResult determines if incoming requests are blocked until the request is processed or not. // Currently, this option is not available when persistent queue is configured using the storage configuration. WaitForResult bool `mapstructure:"wait_for_result"` @@ -66,10 +64,6 @@ func (cfg *Config) Unmarshal(conf *confmap.Conf) error { // Validate checks if the Config is valid func (cfg *Config) Validate() error { - if !cfg.Enabled { - return nil - } - if cfg.NumConsumers <= 0 { return errors.New("`num_consumers` must be positive") } @@ -108,6 +102,22 @@ type BatchConfig struct { // MaxSize defines the configuration for the maximum size of a batch. MaxSize int64 `mapstructure:"max_size"` + + // Partition defines the partitioning of the batches configuration. + Partition PartitionConfig `mapstructure:"partition"` +} + +// PartitionConfig defines a configuration for partitioning requests based on metadata keys. +type PartitionConfig struct { + // MetadataKeys is a list of client.Metadata keys that will be used to partition + // the data into batches. If this setting is empty, a single batcher instance + // will be used. When this setting is not empty, one batcher will be used per + // distinct combination of values for the listed metadata keys. + // + // Empty value and unset metadata are treated as distinct cases. + // + // Entries are case-insensitive. Duplicated entries will trigger a validation error. + MetadataKeys []string `mapstructure:"metadata_keys"` } func (cfg *BatchConfig) Validate() error { @@ -138,3 +148,21 @@ func (cfg *BatchConfig) Validate() error { return nil } + +func (cfg *PartitionConfig) Validate() error { + if cfg == nil { + return nil + } + + // Validate metadata_keys for duplicates (case-insensitive) + uniq := map[string]bool{} + for _, k := range cfg.MetadataKeys { + l := strings.ToLower(k) + if _, has := uniq[l]; has { + return fmt.Errorf("duplicate entry in metadata_keys: %q (case-insensitive)", l) + } + uniq[l] = true + } + + return nil +} diff --git a/exporter/exporterhelper/internal/queuebatch/config.schema.yaml b/exporter/exporterhelper/internal/queuebatch/config.schema.yaml new file mode 100644 index 000000000000..4e034ecaefc1 --- /dev/null +++ b/exporter/exporterhelper/internal/queuebatch/config.schema.yaml @@ -0,0 +1,67 @@ +$defs: + batch_config: + description: BatchConfig defines a configuration for batching requests based on a timeout and a minimum number of items. + type: object + properties: + flush_timeout: + description: FlushTimeout sets the time after which a batch will be sent regardless of its size. + type: string + x-customType: time.Duration + format: duration + max_size: + description: MaxSize defines the configuration for the maximum size of a batch. + type: integer + x-customType: int64 + min_size: + description: MinSize defines the configuration for the minimum size of a batch. + type: integer + x-customType: int64 + partition: + description: Partition defines the partitioning of the batches configuration. + $ref: partition_config + sizer: + description: Sizer determines the type of size measurement used by the batch. If not configured, use the same configuration as the queue. It accepts "requests", "items", or "bytes". + type: string + x-customType: go.opentelemetry.io/collector/exporter/exporterhelper/internal/request.SizerType + partition_config: + description: PartitionConfig defines a configuration for partitioning requests based on metadata keys. + type: object + properties: + metadata_keys: + description: MetadataKeys is a list of client.Metadata keys that will be used to partition the data into batches. If this setting is empty, a single batcher instance will be used. When this setting is not empty, one batcher will be used per distinct combination of values for the listed metadata keys. Empty value and unset metadata are treated as distinct cases. Entries are case-insensitive. Duplicated entries will trigger a validation error. + type: array + items: + type: string + config: + description: Config defines configuration for queueing and batching incoming requests. + type: object + properties: + batch: + description: BatchConfig it configures how the requests are consumed from the queue and batch together during consumption. + x-optional: true + $ref: batch_config + block_on_overflow: + description: BlockOnOverflow determines the behavior when the component's TotalSize limit is reached. If true, the component will wait for space; otherwise, operations will immediately return a retryable error. + type: boolean + enabled: + description: Enabled indicates whether to not enqueue and batch before exporting. + type: boolean + num_consumers: + description: NumConsumers is the maximum number of concurrent consumers from the queue. This applies across all different optional configurations from above (e.g. wait_for_result, block_on_overflow, storage, etc.). + type: integer + queue_size: + description: QueueSize represents the maximum data size allowed for concurrent storage and processing. + type: integer + x-customType: int64 + sizer: + description: Sizer determines the type of size measurement used by this component. It accepts "requests", "items", or "bytes". + type: string + x-customType: go.opentelemetry.io/collector/exporter/exporterhelper/internal/request.SizerType + storage: + description: 'StorageID if not empty, enables the persistent storage and uses the component specified as a storage extension for the persistent queue. TODO: This will be changed to Optional when available. See https://github.com/open-telemetry/opentelemetry-collector/issues/13822' + x-pointer: true + type: string + x-customType: go.opentelemetry.io/collector/component.ID + wait_for_result: + description: WaitForResult determines if incoming requests are blocked until the request is processed or not. Currently, this option is not available when persistent queue is configured using the storage configuration. + type: boolean diff --git a/exporter/exporterhelper/internal/queuebatch/config_test.go b/exporter/exporterhelper/internal/queuebatch/config_test.go index f9d7a33b111b..484a0db18eb1 100644 --- a/exporter/exporterhelper/internal/queuebatch/config_test.go +++ b/exporter/exporterhelper/internal/queuebatch/config_test.go @@ -51,10 +51,45 @@ func TestConfig_Validate(t *testing.T) { cfg = newTestConfig() cfg.Sizer = request.SizerTypeBytes require.NoError(t, xconfmap.Validate(cfg)) +} + +func TestBatchConfig_Validate_MetadataKeys(t *testing.T) { + t.Run("no duplicates - valid", func(t *testing.T) { + cfg := newTestBatchConfig() + cfg.Partition.MetadataKeys = []string{"key1", "key2", "key3"} + require.NoError(t, xconfmap.Validate(cfg)) + }) - // Confirm Validate doesn't return error with invalid config when feature is disabled - cfg.Enabled = false - assert.NoError(t, xconfmap.Validate(cfg)) + t.Run("duplicate keys mixed case - invalid", func(t *testing.T) { + cfg := newTestBatchConfig() + cfg.Partition.MetadataKeys = []string{"Key1", "kEy1", "key2"} + err := xconfmap.Validate(cfg) + require.Error(t, err) + assert.Contains(t, err.Error(), "duplicate entry in metadata_keys") + assert.Contains(t, err.Error(), "key1") + assert.Contains(t, err.Error(), "case-insensitive") + }) + + t.Run("empty metadata_keys - valid", func(t *testing.T) { + cfg := newTestBatchConfig() + cfg.Partition.MetadataKeys = []string{} + require.NoError(t, xconfmap.Validate(cfg)) + }) + + t.Run("nil metadata_keys - valid", func(t *testing.T) { + cfg := newTestBatchConfig() + cfg.Partition.MetadataKeys = nil + require.NoError(t, xconfmap.Validate(cfg)) + }) + + t.Run("multiple duplicates - reports first duplicate", func(t *testing.T) { + cfg := newTestBatchConfig() + cfg.Partition.MetadataKeys = []string{"key1", "key2", "key1", "key2"} + err := xconfmap.Validate(cfg) + require.Error(t, err) + assert.Contains(t, err.Error(), "duplicate entry in metadata_keys") + assert.Contains(t, err.Error(), "key1") + }) } func TestBatchConfig_Validate(t *testing.T) { @@ -97,9 +132,8 @@ func newTestBatchConfig() BatchConfig { } func TestUnmarshal(t *testing.T) { - newBaseCfg := func() Config { - return Config{ - Enabled: true, + newBaseCfg := func() configoptional.Optional[Config] { + return configoptional.Some(Config{ Sizer: request.SizerTypeRequests, NumConsumers: 10, QueueSize: 1_000, @@ -108,38 +142,38 @@ func TestUnmarshal(t *testing.T) { Sizer: request.SizerTypeItems, MinSize: 8192, }), - } + }) } tests := []struct { path string expectedErr string - expectedCfg func() Config + expectedCfg func() configoptional.Optional[Config] }{ { path: "batch_set_empty_explicit_sizer.yaml", - expectedCfg: func() Config { + expectedCfg: func() configoptional.Optional[Config] { cfg := newBaseCfg() - cfg.Sizer = request.SizerTypeBytes + cfg.Get().Sizer = request.SizerTypeBytes // Batch is set, sizer is not overridden - cfg.Batch.GetOrInsertDefault() + cfg.Get().Batch.GetOrInsertDefault() return cfg }, }, { path: "batch_set_empty_no_explicit_sizer.yaml", - expectedCfg: func() Config { + expectedCfg: func() configoptional.Optional[Config] { cfg := newBaseCfg() - cfg.Batch.GetOrInsertDefault() + cfg.Get().Batch.GetOrInsertDefault() return cfg }, }, { path: "batch_set_nonempty_explicit_sizer.yaml", - expectedCfg: func() Config { + expectedCfg: func() configoptional.Optional[Config] { cfg := newBaseCfg() - cfg.Sizer = request.SizerTypeBytes - cfg.QueueSize = 2000 - cfg.Batch = configoptional.Some(BatchConfig{ + cfg.Get().Sizer = request.SizerTypeBytes + cfg.Get().QueueSize = 2000 + cfg.Get().Batch = configoptional.Some(BatchConfig{ FlushTimeout: 200 * time.Millisecond, // Sizer has been overridden by parent sizer Sizer: request.SizerTypeBytes, @@ -150,10 +184,10 @@ func TestUnmarshal(t *testing.T) { }, { path: "batch_set_nonempty_no_explicit_sizer.yaml", - expectedCfg: func() Config { + expectedCfg: func() configoptional.Optional[Config] { cfg := newBaseCfg() - cfg.QueueSize = 2000 - cfg.Batch = configoptional.Some(BatchConfig{ + cfg.Get().QueueSize = 2000 + cfg.Get().Batch = configoptional.Some(BatchConfig{ FlushTimeout: 200 * time.Millisecond, // Sizer has NOT been overridden by parent sizer Sizer: request.SizerTypeItems, @@ -175,7 +209,7 @@ func TestUnmarshal(t *testing.T) { require.NoError(t, err) cfg := newBaseCfg() - err = cfg.Unmarshal(cm) + err = cm.Unmarshal(&cfg) if tt.expectedErr != "" { assert.ErrorContains(t, err, tt.expectedErr) return diff --git a/exporter/exporterhelper/internal/queuebatch/logs_batch_test.go b/exporter/exporterhelper/internal/queuebatch/logs_batch_test.go index df4a721e360d..913198aaccb2 100644 --- a/exporter/exporterhelper/internal/queuebatch/logs_batch_test.go +++ b/exporter/exporterhelper/internal/queuebatch/logs_batch_test.go @@ -12,6 +12,7 @@ import ( "go.opentelemetry.io/collector/exporter/exporterhelper/internal/request" "go.opentelemetry.io/collector/exporter/exporterhelper/internal/sizer" + "go.opentelemetry.io/collector/internal/testutil" "go.opentelemetry.io/collector/pdata/plog" "go.opentelemetry.io/collector/pdata/testdata" ) @@ -325,6 +326,7 @@ func TestLogsMergeSplitUnknownSizerType(t *testing.T) { } func BenchmarkSplittingBasedOnItemCountManySmallLogs(b *testing.B) { + testutil.SkipGCHeavyBench(b) // All requests merge into a single batch. b.ReportAllocs() for b.Loop() { @@ -339,6 +341,7 @@ func BenchmarkSplittingBasedOnItemCountManySmallLogs(b *testing.B) { } func BenchmarkSplittingBasedOnByteSizeManySmallLogs(b *testing.B) { + testutil.SkipGCHeavyBench(b) // All requests merge into a single batch. b.ReportAllocs() for b.Loop() { @@ -353,6 +356,7 @@ func BenchmarkSplittingBasedOnByteSizeManySmallLogs(b *testing.B) { } func BenchmarkSplittingBasedOnItemCountManyLogsSlightlyAboveLimit(b *testing.B) { + testutil.SkipGCHeavyBench(b) // Every incoming request results in a split. b.ReportAllocs() for b.Loop() { @@ -367,6 +371,7 @@ func BenchmarkSplittingBasedOnItemCountManyLogsSlightlyAboveLimit(b *testing.B) } func BenchmarkSplittingBasedOnByteSizeManyLogsSlightlyAboveLimit(b *testing.B) { + testutil.SkipGCHeavyBench(b) // Every incoming request results in a split. b.ReportAllocs() for b.Loop() { @@ -382,6 +387,7 @@ func BenchmarkSplittingBasedOnByteSizeManyLogsSlightlyAboveLimit(b *testing.B) { } func BenchmarkSplittingBasedOnItemCountHugeLogs(b *testing.B) { + testutil.SkipGCHeavyBench(b) // One request splits into many batches. b.ReportAllocs() for b.Loop() { @@ -394,6 +400,7 @@ func BenchmarkSplittingBasedOnItemCountHugeLogs(b *testing.B) { } func BenchmarkSplittingBasedOnByteSizeHugeLogs(b *testing.B) { + testutil.SkipGCHeavyBench(b) // One request splits into many batches. b.ReportAllocs() for b.Loop() { diff --git a/exporter/exporterhelper/internal/queuebatch/metadata_partitioner.go b/exporter/exporterhelper/internal/queuebatch/metadata_partitioner.go new file mode 100644 index 000000000000..8ea3baa60365 --- /dev/null +++ b/exporter/exporterhelper/internal/queuebatch/metadata_partitioner.go @@ -0,0 +1,74 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +package queuebatch // import "go.opentelemetry.io/collector/exporter/exporterhelper/internal/queuebatch" + +import ( + "bytes" + "context" + + "go.opentelemetry.io/collector/client" + "go.opentelemetry.io/collector/exporter/exporterhelper/internal/request" +) + +// metadataKeysPartitioner partitions requests based on client metadata keys. +type metadataKeysPartitioner struct { + keys []string +} + +// NewMetadataKeysPartitioner creates a new partitioner that partitions requests +// based on the specified metadata keys. If keys is empty, returns nil. +func NewMetadataKeysPartitioner(keys []string) Partitioner[request.Request] { + if len(keys) == 0 { + return nil + } + return &metadataKeysPartitioner{keys: keys} +} + +// GetKey returns a partition key based on the metadata keys configured. +func (p *metadataKeysPartitioner) GetKey( + ctx context.Context, + _ request.Request, +) string { + var kb bytes.Buffer + meta := client.FromContext(ctx).Metadata + + var afterFirst bool + for _, k := range p.keys { + if values := meta.Get(k); len(values) != 0 { + if afterFirst { + kb.WriteByte(0) + } + kb.WriteString(k) + afterFirst = true + for _, val := range values { + kb.WriteByte(0) + kb.WriteString(val) + } + } + } + return kb.String() +} + +// NewMetadataKeysMergeCtx creates a merge function for contexts that merges +// metadata based on the specified keys. If keys is empty, returns nil. +func NewMetadataKeysMergeCtx(keys []string) func(context.Context, context.Context) context.Context { + if len(keys) == 0 { + return nil + } + return func(ctx1, _ context.Context) context.Context { + m1 := client.FromContext(ctx1).Metadata + + m := make(map[string][]string, len(keys)) + for _, key := range keys { + v1 := m1.Get(key) + if len(v1) > 0 { + m[key] = v1 + } + } + return client.NewContext( + context.Background(), + client.Info{Metadata: client.NewMetadata(m)}, + ) + } +} diff --git a/exporter/exporterhelper/internal/queuebatch/metadata_partitioner_test.go b/exporter/exporterhelper/internal/queuebatch/metadata_partitioner_test.go new file mode 100644 index 000000000000..a6f1c9327102 --- /dev/null +++ b/exporter/exporterhelper/internal/queuebatch/metadata_partitioner_test.go @@ -0,0 +1,420 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +package queuebatch // import "go.opentelemetry.io/collector/exporter/exporterhelper/internal/queuebatch" + +import ( + "context" + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + + "go.opentelemetry.io/collector/client" + "go.opentelemetry.io/collector/exporter/exporterhelper/internal/requesttest" +) + +func TestMetadataKeysPartitioner_MergeCtx(t *testing.T) { + t.Run("merge contexts with same metadata key values", func(t *testing.T) { + mergeCtx := NewMetadataKeysMergeCtx([]string{"key1", "key2"}) + + ctx1 := client.NewContext( + context.Background(), + client.Info{ + Metadata: client.NewMetadata(map[string][]string{ + "key1": {"value1"}, + "key2": {"value2"}, + }), + }, + ) + + ctx2 := client.NewContext( + context.Background(), + client.Info{ + Metadata: client.NewMetadata(map[string][]string{ + "key1": {"value1"}, + "key2": {"value2"}, + }), + }, + ) + + mergedCtx := mergeCtx(ctx1, ctx2) + require.NotNil(t, mergedCtx) + + mergedMeta := client.FromContext(mergedCtx).Metadata + assert.Equal(t, []string{"value1"}, mergedMeta.Get("key1")) + assert.Equal(t, []string{"value2"}, mergedMeta.Get("key2")) + }) + + t.Run("merge contexts with same metadata key values and additional keys", func(t *testing.T) { + mergeCtx := NewMetadataKeysMergeCtx([]string{"key1"}) + + ctx1 := client.NewContext( + context.Background(), + client.Info{ + Metadata: client.NewMetadata(map[string][]string{ + "key1": {"value1"}, + "other": {"other1"}, + }), + }, + ) + + ctx2 := client.NewContext( + context.Background(), + client.Info{ + Metadata: client.NewMetadata(map[string][]string{ + "key1": {"value1"}, + "other": {"other2"}, + }), + }, + ) + + mergedCtx := mergeCtx(ctx1, ctx2) + require.NotNil(t, mergedCtx) + + mergedMeta := client.FromContext(mergedCtx).Metadata + assert.Equal(t, []string{"value1"}, mergedMeta.Get("key1")) + // Other keys should not be in merged metadata since they're not in partitioner keys + assert.Empty(t, mergedMeta.Get("other")) + }) + + t.Run("merge contexts with empty metadata", func(t *testing.T) { + mergeCtx := NewMetadataKeysMergeCtx([]string{"key1"}) + + ctx1 := client.NewContext( + context.Background(), + client.Info{ + Metadata: client.NewMetadata(map[string][]string{}), + }, + ) + + ctx2 := client.NewContext( + context.Background(), + client.Info{ + Metadata: client.NewMetadata(map[string][]string{}), + }, + ) + + mergedCtx := mergeCtx(ctx1, ctx2) + require.NotNil(t, mergedCtx) + + mergedMeta := client.FromContext(mergedCtx).Metadata + assert.Empty(t, mergedMeta.Get("key1")) + }) + + t.Run("merge when one context has metadata and other is empty", func(t *testing.T) { + mergeCtx := NewMetadataKeysMergeCtx([]string{"key1"}) + + ctx1 := client.NewContext( + context.Background(), + client.Info{ + Metadata: client.NewMetadata(map[string][]string{ + "key1": {"value1"}, + }), + }, + ) + + ctx2 := client.NewContext( + context.Background(), + client.Info{ + Metadata: client.NewMetadata(map[string][]string{}), + }, + ) + + mergedCtx := mergeCtx(ctx1, ctx2) + require.NotNil(t, mergedCtx) + mergedMeta := client.FromContext(mergedCtx).Metadata + assert.Equal(t, []string{"value1"}, mergedMeta.Get("key1")) + }) + + t.Run("merge when contexts have different metadata key values", func(t *testing.T) { + mergeCtx := NewMetadataKeysMergeCtx([]string{"key1"}) + + ctx1 := client.NewContext( + context.Background(), + client.Info{ + Metadata: client.NewMetadata(map[string][]string{ + "key1": {"value1"}, + }), + }, + ) + + ctx2 := client.NewContext( + context.Background(), + client.Info{ + Metadata: client.NewMetadata(map[string][]string{ + "key1": {"value2"}, + }), + }, + ) + + mergedCtx := mergeCtx(ctx1, ctx2) + require.NotNil(t, mergedCtx) + mergedMeta := client.FromContext(mergedCtx).Metadata + assert.Equal(t, []string{"value1"}, mergedMeta.Get("key1")) + }) + + t.Run("merge when contexts have different metadata key values for multiple keys", func(t *testing.T) { + mergeCtx := NewMetadataKeysMergeCtx([]string{"key1", "key2"}) + + ctx1 := client.NewContext( + context.Background(), + client.Info{ + Metadata: client.NewMetadata(map[string][]string{ + "key1": {"value1"}, + "key2": {"value2"}, + }), + }, + ) + + ctx2 := client.NewContext( + context.Background(), + client.Info{ + Metadata: client.NewMetadata(map[string][]string{ + "key1": {"value1"}, + "key2": {"different"}, + }), + }, + ) + + mergedCtx := mergeCtx(ctx1, ctx2) + require.NotNil(t, mergedCtx) + mergedMeta := client.FromContext(mergedCtx).Metadata + assert.Equal(t, []string{"value1"}, mergedMeta.Get("key1")) + assert.Equal(t, []string{"value2"}, mergedMeta.Get("key2")) + }) + + t.Run("merge contexts with multiple values for same key", func(t *testing.T) { + mergeCtx := NewMetadataKeysMergeCtx([]string{"key1"}) + + ctx1 := client.NewContext( + context.Background(), + client.Info{ + Metadata: client.NewMetadata(map[string][]string{ + "key1": {"value1", "value2"}, + }), + }, + ) + + ctx2 := client.NewContext( + context.Background(), + client.Info{ + Metadata: client.NewMetadata(map[string][]string{ + "key1": {"value1", "value2"}, + }), + }, + ) + + mergedCtx := mergeCtx(ctx1, ctx2) + require.NotNil(t, mergedCtx) + + mergedMeta := client.FromContext(mergedCtx).Metadata + assert.Equal(t, []string{"value1", "value2"}, mergedMeta.Get("key1")) + }) + + t.Run("merge when contexts have different multiple values for same key", func(t *testing.T) { + mergeCtx := NewMetadataKeysMergeCtx([]string{"key1"}) + + ctx1 := client.NewContext( + context.Background(), + client.Info{ + Metadata: client.NewMetadata(map[string][]string{ + "key1": {"value1", "value2"}, + }), + }, + ) + + ctx2 := client.NewContext( + context.Background(), + client.Info{ + Metadata: client.NewMetadata(map[string][]string{ + "key1": {"value1", "value3"}, + }), + }, + ) + + mergedCtx := mergeCtx(ctx1, ctx2) + require.NotNil(t, mergedCtx) + mergedMeta := client.FromContext(mergedCtx).Metadata + assert.Equal(t, []string{"value1", "value2"}, mergedMeta.Get("key1")) + }) +} + +func TestMetadataKeysPartitioner_GetKey(t *testing.T) { + t.Run("single key with single value", func(t *testing.T) { + partitioner := NewMetadataKeysPartitioner([]string{"key1"}) + + ctx := client.NewContext( + context.Background(), + client.Info{ + Metadata: client.NewMetadata(map[string][]string{ + "key1": {"value1"}, + }), + }, + ) + + key := partitioner.GetKey(ctx, &requesttest.FakeRequest{}) + expected := "key1\x00value1" + assert.Equal(t, expected, key) + }) + + t.Run("single key with multiple values", func(t *testing.T) { + partitioner := NewMetadataKeysPartitioner([]string{"key1"}) + + ctx := client.NewContext( + context.Background(), + client.Info{ + Metadata: client.NewMetadata(map[string][]string{ + "key1": {"value1", "value2", "value3"}, + }), + }, + ) + + key := partitioner.GetKey(ctx, &requesttest.FakeRequest{}) + // Format: key1\0value1\0value2\0value3 + expected := "key1\x00value1\x00value2\x00value3" + assert.Equal(t, expected, key) + }) + + t.Run("multiple keys with values", func(t *testing.T) { + partitioner := NewMetadataKeysPartitioner([]string{"key1", "key2"}) + + ctx := client.NewContext( + context.Background(), + client.Info{ + Metadata: client.NewMetadata(map[string][]string{ + "key1": {"value1"}, + "key2": {"value2"}, + }), + }, + ) + + key := partitioner.GetKey(ctx, &requesttest.FakeRequest{}) + // Format: key1\0value1\0key2\0value2 (separator between keys) + expected := "key1\x00value1\x00key2\x00value2" + assert.Equal(t, expected, key) + }) + + t.Run("multiple keys with multiple values", func(t *testing.T) { + partitioner := NewMetadataKeysPartitioner([]string{"key1", "key2"}) + + ctx := client.NewContext( + context.Background(), + client.Info{ + Metadata: client.NewMetadata(map[string][]string{ + "key1": {"value1", "value1b"}, + "key2": {"value2", "value2b"}, + }), + }, + ) + + key := partitioner.GetKey(ctx, &requesttest.FakeRequest{}) + // Format: key1\0value1\0value1b\0key2\0value2\0value2b + expected := "key1\x00value1\x00value1b\x00key2\x00value2\x00value2b" + assert.Equal(t, expected, key) + }) + + t.Run("keys that don't exist in metadata are skipped", func(t *testing.T) { + partitioner := NewMetadataKeysPartitioner([]string{"key1", "key2", "key3"}) + + ctx := client.NewContext( + context.Background(), + client.Info{ + Metadata: client.NewMetadata(map[string][]string{ + "key1": {"value1"}, + // key2 is missing + "key3": {"value3"}, + }), + }, + ) + + key := partitioner.GetKey(ctx, &requesttest.FakeRequest{}) + // Format: key1\0value1\0key3\0value3 (key2 is skipped) + expected := "key1\x00value1\x00key3\x00value3" + assert.Equal(t, expected, key) + }) + + t.Run("empty metadata returns empty string", func(t *testing.T) { + partitioner := NewMetadataKeysPartitioner([]string{"key1", "key2"}) + + ctx := client.NewContext( + context.Background(), + client.Info{ + Metadata: client.NewMetadata(map[string][]string{}), + }, + ) + + key := partitioner.GetKey(ctx, &requesttest.FakeRequest{}) + assert.Empty(t, key) + }) + + t.Run("keys with empty values are skipped", func(t *testing.T) { + partitioner := NewMetadataKeysPartitioner([]string{"key1", "key2", "key3"}) + + ctx := client.NewContext( + context.Background(), + client.Info{ + Metadata: client.NewMetadata(map[string][]string{ + "key1": {"value1"}, + "key2": {}, // empty slice + "key3": {"value3"}, + }), + }, + ) + + key := partitioner.GetKey(ctx, &requesttest.FakeRequest{}) + // Format: key1\0value1\0key3\0value3 (key2 is skipped) + expected := "key1\x00value1\x00key3\x00value3" + assert.Equal(t, expected, key) + }) + + t.Run("keys in order respect partitioner key order", func(t *testing.T) { + partitioner := NewMetadataKeysPartitioner([]string{"key3", "key1", "key2"}) + + ctx := client.NewContext( + context.Background(), + client.Info{ + Metadata: client.NewMetadata(map[string][]string{ + "key1": {"value1"}, + "key2": {"value2"}, + "key3": {"value3"}, + }), + }, + ) + + key := partitioner.GetKey(ctx, &requesttest.FakeRequest{}) + // Format should follow partitioner order: key3\0value3\0key1\0value1\0key2\0value2 + expected := "key3\x00value3\x00key1\x00value1\x00key2\x00value2" + assert.Equal(t, expected, key) + }) + + t.Run("additional metadata keys not in partitioner are ignored", func(t *testing.T) { + partitioner := NewMetadataKeysPartitioner([]string{"key1"}) + + ctx := client.NewContext( + context.Background(), + client.Info{ + Metadata: client.NewMetadata(map[string][]string{ + "key1": {"value1"}, + "other": {"other1"}, + "extra": {"extra1"}, + }), + }, + ) + + key := partitioner.GetKey(ctx, &requesttest.FakeRequest{}) + // Format: key1\0value1 (other keys are ignored) + expected := "key1\x00value1" + assert.Equal(t, expected, key) + }) + + t.Run("returns nil partitioner when keys are empty", func(t *testing.T) { + partitioner := NewMetadataKeysPartitioner([]string{}) + assert.Nil(t, partitioner) + }) + + t.Run("returns nil merge function when keys are empty", func(t *testing.T) { + mergeCtx := NewMetadataKeysMergeCtx([]string{}) + assert.Nil(t, mergeCtx) + }) +} diff --git a/exporter/exporterhelper/internal/queuebatch/metrics_batch_test.go b/exporter/exporterhelper/internal/queuebatch/metrics_batch_test.go index 1a1e1d26363f..5696b8265f53 100644 --- a/exporter/exporterhelper/internal/queuebatch/metrics_batch_test.go +++ b/exporter/exporterhelper/internal/queuebatch/metrics_batch_test.go @@ -12,6 +12,7 @@ import ( "go.opentelemetry.io/collector/exporter/exporterhelper/internal/request" "go.opentelemetry.io/collector/exporter/exporterhelper/internal/sizer" + "go.opentelemetry.io/collector/internal/testutil" "go.opentelemetry.io/collector/pdata/pmetric" "go.opentelemetry.io/collector/pdata/testdata" ) @@ -264,6 +265,7 @@ func TestMergeSplitManySmallMetrics(t *testing.T) { } func BenchmarkSplittingBasedOnItemCountManySmallMetrics(b *testing.B) { + testutil.SkipGCHeavyBench(b) // All requests merge into a single batch. b.ReportAllocs() for b.Loop() { @@ -278,6 +280,7 @@ func BenchmarkSplittingBasedOnItemCountManySmallMetrics(b *testing.B) { } func BenchmarkSplittingBasedOnItemCountManyMetricsSlightlyAboveLimit(b *testing.B) { + testutil.SkipGCHeavyBench(b) // Every incoming request results in a split. b.ReportAllocs() for b.Loop() { @@ -292,6 +295,7 @@ func BenchmarkSplittingBasedOnItemCountManyMetricsSlightlyAboveLimit(b *testing. } func BenchmarkSplittingBasedOnItemCountHugeMetrics(b *testing.B) { + testutil.SkipGCHeavyBench(b) // One request splits into many batches. b.ReportAllocs() for b.Loop() { @@ -604,7 +608,7 @@ func TestExtractHistogramDataPoints(t *testing.T) { for i := 0; i < tt.numDataPoints; i++ { dp := histogram.DataPoints().AppendEmpty() - dp.SetCount(uint64(i)) //nolint:gosec // disable G115 + dp.SetCount(uint64(i)) } sz := &mockMetricsSizer{dpSize: 1} @@ -653,7 +657,7 @@ func TestExtractExponentialHistogramDataPoints(t *testing.T) { expHistogram := srcMetric.SetEmptyExponentialHistogram() for i := 0; i < tt.numDataPoints; i++ { dp := expHistogram.DataPoints().AppendEmpty() - dp.SetCount(uint64(i)) //nolint:gosec // disable G115 + dp.SetCount(uint64(i)) } sz := &mockMetricsSizer{dpSize: 1} @@ -702,7 +706,7 @@ func TestExtractSummaryDataPoints(t *testing.T) { summary := srcMetric.SetEmptySummary() for i := 0; i < tt.numDataPoints; i++ { dp := summary.DataPoints().AppendEmpty() - dp.SetCount(uint64(i)) //nolint:gosec // disable G115 + dp.SetCount(uint64(i)) } sz := &mockMetricsSizer{dpSize: 1} diff --git a/exporter/exporterhelper/internal/queuebatch/multi_batcher.go b/exporter/exporterhelper/internal/queuebatch/multi_batcher.go index 6fb9eeb79e9d..bbf513fe9569 100644 --- a/exporter/exporterhelper/internal/queuebatch/multi_batcher.go +++ b/exporter/exporterhelper/internal/queuebatch/multi_batcher.go @@ -6,6 +6,7 @@ import ( "context" "sync" + lru "github.com/hashicorp/golang-lru/v2/simplelru" "go.uber.org/zap" "go.opentelemetry.io/collector/component" @@ -21,8 +22,9 @@ type multiBatcher struct { partitioner Partitioner[request.Request] mergeCtx func(context.Context, context.Context) context.Context consumeFunc sender.SendFunc[request.Request] - shards sync.Map + partitions *lru.LRU[string, *partitionBatcher] logger *zap.Logger + lock sync.Mutex } func newMultiBatcher( @@ -33,8 +35,8 @@ func newMultiBatcher( mergeCtx func(context.Context, context.Context) context.Context, next sender.SendFunc[request.Request], logger *zap.Logger, -) *multiBatcher { - return &multiBatcher{ +) (*multiBatcher, error) { + mb := &multiBatcher{ cfg: bCfg, wp: wp, sizer: sizer, @@ -43,24 +45,41 @@ func newMultiBatcher( consumeFunc: next, logger: logger, } + + // Create LRU cache with eviction callback + // TODO: make maxActivePartitionsCount configurable + cache, err := lru.NewLRU[string, *partitionBatcher](10000, func(_ string, pb *partitionBatcher) { + // Flush the partition when evicted + mb.wp.execute(pb.shutdownInternal) + }) + if err != nil { + return nil, err + } + + mb.partitions = cache + return mb, nil } func (mb *multiBatcher) getPartition(ctx context.Context, req request.Request) *partitionBatcher { key := mb.partitioner.GetKey(ctx, req) - s, found := mb.shards.Load(key) - // Fast path, shard already created. - if found { - return s.(*partitionBatcher) - } - newS := newPartitionBatcher(mb.cfg, mb.sizer, mb.mergeCtx, mb.wp, mb.consumeFunc, mb.logger) - _ = newS.Start(ctx, nil) - s, loaded := mb.shards.LoadOrStore(key, newS) - // If not loaded, there was a race condition in adding the new shard. Shutdown the newly created shard. - if loaded { - _ = newS.Shutdown(ctx) + mb.lock.Lock() + defer mb.lock.Unlock() + + // Fast path: partition already exists + if pb, ok := mb.partitions.Get(key); ok { + return pb } - return s.(*partitionBatcher) + + // Create new partition with onEmpty callback to remove from LRU after idle timeout + newPB := newPartitionBatcher(mb.cfg, mb.sizer, mb.mergeCtx, mb.wp, mb.consumeFunc, mb.logger, func() { + mb.lock.Lock() + defer mb.lock.Unlock() + mb.partitions.Remove(key) + }) + _ = mb.partitions.Add(key, newPB) + _ = newPB.Start(ctx, nil) + return newPB } func (mb *multiBatcher) Start(context.Context, component.Host) error { @@ -72,16 +91,25 @@ func (mb *multiBatcher) Consume(ctx context.Context, req request.Request, done q shard.Consume(ctx, req, done) } +// getActivePartitionsCount is test only method +func (mb *multiBatcher) getActivePartitionsCount() int64 { + mb.lock.Lock() + defer mb.lock.Unlock() + return int64(mb.partitions.Len()) +} + func (mb *multiBatcher) Shutdown(ctx context.Context) error { var wg sync.WaitGroup - mb.shards.Range(func(_, shard any) bool { - wg.Add(1) - go func() { - defer wg.Done() - _ = shard.(*partitionBatcher).Shutdown(ctx) - }() - return true - }) + mb.lock.Lock() + defer mb.lock.Unlock() + for _, key := range mb.partitions.Keys() { + if pb, ok := mb.partitions.Peek(key); ok { + wg.Go(func() { + _ = pb.Shutdown(ctx) + }) + } + } wg.Wait() + mb.partitions.Purge() return nil } diff --git a/exporter/exporterhelper/internal/queuebatch/multi_batcher_test.go b/exporter/exporterhelper/internal/queuebatch/multi_batcher_test.go index 58cce15ce28c..6ba491b32c6e 100644 --- a/exporter/exporterhelper/internal/queuebatch/multi_batcher_test.go +++ b/exporter/exporterhelper/internal/queuebatch/multi_batcher_test.go @@ -27,7 +27,7 @@ func TestMultiBatcher_NoTimeout(t *testing.T) { type partitionKey struct{} - ba := newMultiBatcher(cfg, + ba, err := newMultiBatcher(cfg, request.NewItemsSizer(), newWorkerPool(1), NewPartitioner(func(ctx context.Context, _ request.Request) string { @@ -38,14 +38,18 @@ func TestMultiBatcher_NoTimeout(t *testing.T) { zap.NewNop(), ) + require.NoError(t, err) require.NoError(t, ba.Start(context.Background(), componenttest.NewNopHost())) t.Cleanup(func() { require.NoError(t, ba.Shutdown(context.Background())) }) done := newFakeDone() + assert.Equal(t, int64(0), ba.getActivePartitionsCount()) ba.Consume(context.WithValue(context.Background(), partitionKey{}, "p1"), &requesttest.FakeRequest{Items: 8}, done) + assert.Equal(t, int64(1), ba.getActivePartitionsCount()) ba.Consume(context.WithValue(context.Background(), partitionKey{}, "p2"), &requesttest.FakeRequest{Items: 6}, done) + assert.Equal(t, int64(2), ba.getActivePartitionsCount()) // Neither batch should be flushed since they haven't reached min threshold. assert.Equal(t, 0, sink.RequestsCount()) @@ -80,7 +84,7 @@ func TestMultiBatcher_Timeout(t *testing.T) { type partitionKey struct{} - ba := newMultiBatcher(cfg, + ba, err := newMultiBatcher(cfg, request.NewItemsSizer(), newWorkerPool(1), NewPartitioner(func(ctx context.Context, _ request.Request) string { @@ -91,6 +95,7 @@ func TestMultiBatcher_Timeout(t *testing.T) { zap.NewNop(), ) + require.NoError(t, err) require.NoError(t, ba.Start(context.Background(), componenttest.NewNopHost())) t.Cleanup(func() { require.NoError(t, ba.Shutdown(context.Background())) @@ -116,3 +121,49 @@ func TestMultiBatcher_Timeout(t *testing.T) { require.NoError(t, ba.Start(context.Background(), componenttest.NewNopHost())) } + +func TestMultiBatcher_PartitionRemovedAfterIdleTimeout(t *testing.T) { + // Use a short FlushTimeout so the idle threshold (partitionIdleCycles*FlushTimeout) is reached quickly. + cfg := BatchConfig{ + FlushTimeout: 10 * time.Millisecond, + Sizer: request.SizerTypeItems, + MinSize: 100, // High min size to prevent immediate flush + } + sink := requesttest.NewSink() + + type partitionKey struct{} + + ba, err := newMultiBatcher(cfg, + request.NewItemsSizer(), + newWorkerPool(1), + NewPartitioner(func(ctx context.Context, _ request.Request) string { + return ctx.Value(partitionKey{}).(string) + }), + nil, + sink.Export, + zap.NewNop(), + ) + + require.NoError(t, err) + require.NoError(t, ba.Start(context.Background(), componenttest.NewNopHost())) + t.Cleanup(func() { + require.NoError(t, ba.Shutdown(context.Background())) + }) + + done := newFakeDone() + + // Create a partition + ba.Consume(context.WithValue(context.Background(), partitionKey{}, "p1"), &requesttest.FakeRequest{Items: 5}, done) + assert.Equal(t, int64(1), ba.getActivePartitionsCount()) + + // Wait for the batch to flush via timeout + assert.Eventually(t, func() bool { + return sink.RequestsCount() == 1 + }, 500*time.Millisecond, 10*time.Millisecond) + + // Wait for idle timeout (partitionIdleCycles * FlushTimeout = 10 * 10ms = 100ms) + // After this, the partition should be removed from the LRU cache. + assert.Eventually(t, func() bool { + return ba.getActivePartitionsCount() == 0 + }, 500*time.Millisecond, 10*time.Millisecond) +} diff --git a/exporter/exporterhelper/internal/queuebatch/partition_batcher.go b/exporter/exporterhelper/internal/queuebatch/partition_batcher.go index 323ea27f1223..8a8c6e8951bf 100644 --- a/exporter/exporterhelper/internal/queuebatch/partition_batcher.go +++ b/exporter/exporterhelper/internal/queuebatch/partition_batcher.go @@ -17,6 +17,10 @@ import ( "go.opentelemetry.io/collector/exporter/exporterhelper/internal/sender" ) +// partitionIdleCycles*FlushTimeout is the duration after which an empty partition is removed. +// TODO make this configurable. +const partitionIdleCycles = 10 + var _ Batcher[request.Request] = (*partitionBatcher)(nil) type batch struct { @@ -38,6 +42,9 @@ type partitionBatcher struct { timer *time.Timer shutdownCh chan struct{} logger *zap.Logger + onEmpty func() // callback triggered when partition is idle for given time period. + lastDataTime time.Time // tracks when data was last present + active bool // indicates if partition is still active i.e timer is running and shutdown is not called yet. If Consume is called on inactive partition then data is flushed sync because timer is not running. } func newPartitionBatcher( @@ -47,15 +54,19 @@ func newPartitionBatcher( wp *workerPool, next sender.SendFunc[request.Request], logger *zap.Logger, + onEmpty func(), ) *partitionBatcher { return &partitionBatcher{ - cfg: cfg, - wp: wp, - sizer: sizer, - mergeCtx: mergeCtx, - consumeFunc: next, - shutdownCh: make(chan struct{}, 1), - logger: logger, + cfg: cfg, + wp: wp, + sizer: sizer, + mergeCtx: mergeCtx, + consumeFunc: next, + shutdownCh: make(chan struct{}, 1), + logger: logger, + onEmpty: onEmpty, + lastDataTime: time.Now(), + active: true, } } @@ -65,9 +76,10 @@ func (qb *partitionBatcher) resetTimer() { } } -func (qb *partitionBatcher) Consume(ctx context.Context, req request.Request, done queue.Done) { +func (qb *partitionBatcher) consumeInternal(ctx context.Context, req request.Request, done queue.Done) bool { qb.currentBatchMu.Lock() - + isActive := qb.active + qb.lastDataTime = time.Now() if qb.currentBatch == nil { reqList, mergeSplitErr := req.MergeSplit(ctx, int(qb.cfg.MaxSize), qb.cfg.Sizer, nil) if mergeSplitErr != nil { @@ -78,7 +90,7 @@ func (qb *partitionBatcher) Consume(ctx context.Context, req request.Request, do if len(reqList) == 0 { done.OnDone(mergeSplitErr) qb.currentBatchMu.Unlock() - return + return isActive } // If more than one flush is required for this request, call done only when all flushes are done. @@ -113,7 +125,7 @@ func (qb *partitionBatcher) Consume(ctx context.Context, req request.Request, do qb.flush(ctx, reqList[i], done) } - return + return isActive } reqList, mergeSplitErr := qb.currentBatch.req.MergeSplit(ctx, int(qb.cfg.MaxSize), qb.cfg.Sizer, req) @@ -126,7 +138,7 @@ func (qb *partitionBatcher) Consume(ctx context.Context, req request.Request, do if len(reqList) == 0 { done.OnDone(mergeSplitErr) qb.currentBatchMu.Unlock() - return + return isActive } // If more than one flush is required for this request, call done only when all flushes are done. @@ -136,7 +148,7 @@ func (qb *partitionBatcher) Consume(ctx context.Context, req request.Request, do numRefs++ } if numRefs > 1 { - done = newRefCountDone(done, int64(len(reqList))) + done = newRefCountDone(done, int64(numRefs)) if mergeSplitErr != nil { done.OnDone(mergeSplitErr) } @@ -190,6 +202,14 @@ func (qb *partitionBatcher) Consume(ctx context.Context, req request.Request, do for i := 0; i < len(reqList); i++ { qb.flush(ctx, reqList[i], done) } + return isActive +} + +func (qb *partitionBatcher) Consume(ctx context.Context, req request.Request, done queue.Done) { + if !qb.consumeInternal(ctx, req, done) { + // Not active partition then flush else let the timer/Shutdown do it's work. + qb.flushCurrentBatchOrRemovePartition() + } } // Start starts the goroutine that reads from the queue and flushes asynchronously. @@ -198,44 +218,72 @@ func (qb *partitionBatcher) Start(context.Context, component.Host) error { return nil } qb.timer = time.NewTimer(qb.cfg.FlushTimeout) - qb.stopWG.Add(1) - go func() { - defer qb.stopWG.Done() + qb.stopWG.Go(func() { for { select { case <-qb.shutdownCh: return case <-qb.timer.C: - qb.flushCurrentBatchIfNecessary() + qb.flushCurrentBatchOrRemovePartition() } } - }() + }) return nil } -// Shutdown ensures that queue and all Batcher are stopped. -func (qb *partitionBatcher) Shutdown(context.Context) error { +// shutdownInternal ensures that queue and all Batcher are stopped. +func (qb *partitionBatcher) shutdownInternal() { + qb.currentBatchMu.Lock() + if !qb.active { + qb.currentBatchMu.Unlock() + return + } + qb.active = false + // don't need to trigger onEmpty during shutdown as partitionBatcher will be purged anyway. + qb.onEmpty = nil + qb.currentBatchMu.Unlock() close(qb.shutdownCh) // Make sure execute one last flush if necessary. - qb.flushCurrentBatchIfNecessary() + qb.flushCurrentBatchOrRemovePartition() qb.stopWG.Wait() +} + +// Shutdown ensures that queue and all Batcher are stopped. +func (qb *partitionBatcher) Shutdown(context.Context) error { + qb.shutdownInternal() return nil } -// flushCurrentBatchIfNecessary sends out the current request batch if it is not nil -func (qb *partitionBatcher) flushCurrentBatchIfNecessary() { +// flushCurrentBatchOrRemovePartition flushes the current batch if not empty, +// or removes the partition from the parent if it's been idle for too long. +func (qb *partitionBatcher) flushCurrentBatchOrRemovePartition() { qb.currentBatchMu.Lock() if qb.currentBatch == nil { + // No data to flush - check if idle for too long AND no one holding a reference + idleDuration := time.Since(qb.lastDataTime) + + if idleDuration >= (partitionIdleCycles*qb.cfg.FlushTimeout) && qb.onEmpty != nil { + qb.currentBatchMu.Unlock() + qb.onEmpty() + return + } + if qb.timer != nil { + qb.resetTimer() + } qb.currentBatchMu.Unlock() return } + + // Has data to flush - update lastDataTime + qb.lastDataTime = time.Now() batchToFlush := qb.currentBatch qb.currentBatch = nil + // Reset timer while holding the lock to prevent data race with Consume() which + // also calls resetTimer() under the same lock. + qb.resetTimer() qb.currentBatchMu.Unlock() - // flush() blocks until successfully started a goroutine for flushing. qb.flush(batchToFlush.ctx, batchToFlush.req, batchToFlush.done) - qb.resetTimer() } // flush starts a goroutine that calls consumeFunc. It blocks until a worker is available if necessary. diff --git a/exporter/exporterhelper/internal/queuebatch/partition_batcher_test.go b/exporter/exporterhelper/internal/queuebatch/partition_batcher_test.go index fe2951c83b08..09b7ab0ea6e8 100644 --- a/exporter/exporterhelper/internal/queuebatch/partition_batcher_test.go +++ b/exporter/exporterhelper/internal/queuebatch/partition_batcher_test.go @@ -66,7 +66,7 @@ func TestPartitionBatcher_NoSplit_MinThresholdZero_TimeoutDisabled(t *testing.T) } sink := requesttest.NewSink() - ba := newPartitionBatcher(cfg, tt.sizer, nil, newWorkerPool(tt.maxWorkers), sink.Export, zap.NewNop()) + ba := newPartitionBatcher(cfg, tt.sizer, nil, newWorkerPool(tt.maxWorkers), sink.Export, zap.NewNop(), nil) require.NoError(t, ba.Start(context.Background(), componenttest.NewNopHost())) t.Cleanup(func() { require.NoError(t, ba.Shutdown(context.Background())) @@ -132,7 +132,7 @@ func TestPartitionBatcher_NoSplit_TimeoutDisabled(t *testing.T) { } sink := requesttest.NewSink() - ba := newPartitionBatcher(cfg, tt.sizer, nil, newWorkerPool(tt.maxWorkers), sink.Export, zap.NewNop()) + ba := newPartitionBatcher(cfg, tt.sizer, nil, newWorkerPool(tt.maxWorkers), sink.Export, zap.NewNop(), nil) require.NoError(t, ba.Start(context.Background(), componenttest.NewNopHost())) done := newFakeDone() @@ -213,7 +213,7 @@ func TestPartitionBatcher_NoSplit_WithTimeout(t *testing.T) { } sink := requesttest.NewSink() - ba := newPartitionBatcher(cfg, tt.sizer, nil, newWorkerPool(tt.maxWorkers), sink.Export, zap.NewNop()) + ba := newPartitionBatcher(cfg, tt.sizer, nil, newWorkerPool(tt.maxWorkers), sink.Export, zap.NewNop(), nil) require.NoError(t, ba.Start(context.Background(), componenttest.NewNopHost())) t.Cleanup(func() { require.NoError(t, ba.Shutdown(context.Background())) @@ -285,7 +285,7 @@ func TestPartitionBatcher_Split_TimeoutDisabled(t *testing.T) { } sink := requesttest.NewSink() - ba := newPartitionBatcher(cfg, tt.sizer, nil, newWorkerPool(tt.maxWorkers), sink.Export, zap.NewNop()) + ba := newPartitionBatcher(cfg, tt.sizer, nil, newWorkerPool(tt.maxWorkers), sink.Export, zap.NewNop(), nil) require.NoError(t, ba.Start(context.Background(), componenttest.NewNopHost())) done := newFakeDone() @@ -333,7 +333,7 @@ func TestPartitionBatcher_Shutdown(t *testing.T) { } sink := requesttest.NewSink() - ba := newPartitionBatcher(cfg, request.NewItemsSizer(), nil, newWorkerPool(2), sink.Export, zap.NewNop()) + ba := newPartitionBatcher(cfg, request.NewItemsSizer(), nil, newWorkerPool(2), sink.Export, zap.NewNop(), nil) require.NoError(t, ba.Start(context.Background(), componenttest.NewNopHost())) done := newFakeDone() @@ -362,7 +362,7 @@ func TestPartitionBatcher_MergeError(t *testing.T) { } sink := requesttest.NewSink() - ba := newPartitionBatcher(cfg, request.NewItemsSizer(), nil, newWorkerPool(2), sink.Export, zap.NewNop()) + ba := newPartitionBatcher(cfg, request.NewItemsSizer(), nil, newWorkerPool(2), sink.Export, zap.NewNop(), nil) require.NoError(t, ba.Start(context.Background(), componenttest.NewNopHost())) t.Cleanup(func() { require.NoError(t, ba.Shutdown(context.Background())) @@ -396,7 +396,7 @@ func TestPartitionBatcher_PartialSuccessError(t *testing.T) { core, observed := observer.New(zap.WarnLevel) logger := zap.New(core) sink := requesttest.NewSink() - ba := newPartitionBatcher(cfg, request.NewItemsSizer(), nil, newWorkerPool(1), sink.Export, logger) + ba := newPartitionBatcher(cfg, request.NewItemsSizer(), nil, newWorkerPool(1), sink.Export, logger, nil) require.NoError(t, ba.Start(context.Background(), componenttest.NewNopHost())) done := newFakeDone() @@ -438,7 +438,7 @@ func TestSPartitionBatcher_PartialSuccessError_AfterOkRequest(t *testing.T) { core, observed := observer.New(zap.WarnLevel) logger := zap.New(core) sink := requesttest.NewSink() - ba := newPartitionBatcher(cfg, request.NewItemsSizer(), nil, newWorkerPool(1), sink.Export, logger) + ba := newPartitionBatcher(cfg, request.NewItemsSizer(), nil, newWorkerPool(1), sink.Export, logger, nil) require.NoError(t, ba.Start(context.Background(), componenttest.NewNopHost())) done := newFakeDone() @@ -498,7 +498,7 @@ func TestShardBatcher_EmptyRequestList(t *testing.T) { } sink := requesttest.NewSink() - ba := newPartitionBatcher(cfg, request.NewItemsSizer(), nil, newWorkerPool(1), sink.Export, zap.NewNop()) + ba := newPartitionBatcher(cfg, request.NewItemsSizer(), nil, newWorkerPool(1), sink.Export, zap.NewNop(), nil) require.NoError(t, ba.Start(context.Background(), componenttest.NewNopHost())) t.Cleanup(func() { require.NoError(t, ba.Shutdown(context.Background())) @@ -548,7 +548,7 @@ func TestPartitionBatcher_ContextMerging(t *testing.T) { MinSize: 10, } sink := requesttest.NewSink() - ba := newPartitionBatcher(cfg, request.NewItemsSizer(), tt.mergeCtxFunc, newWorkerPool(1), sink.Export, zap.NewNop()) + ba := newPartitionBatcher(cfg, request.NewItemsSizer(), tt.mergeCtxFunc, newWorkerPool(1), sink.Export, zap.NewNop(), nil) require.NoError(t, ba.Start(context.Background(), componenttest.NewNopHost())) done := newFakeDone() @@ -560,3 +560,72 @@ func TestPartitionBatcher_ContextMerging(t *testing.T) { }) } } + +func TestPartitionBatcher_OnEmptyCallbackTriggered(t *testing.T) { + // Use a very short FlushTimeout so the idle threshold (partitionIdleCycles*FlushTimeout) is reached quickly. + cfg := BatchConfig{ + FlushTimeout: 10 * time.Millisecond, + Sizer: request.SizerTypeItems, + MinSize: 100, // High min size to ensure data doesn't flush immediately + } + + sink := requesttest.NewSink() + onEmptyCalled := &atomic.Int64{} + onEmpty := func() { + onEmptyCalled.Add(1) + } + + ba := newPartitionBatcher(cfg, request.NewItemsSizer(), nil, newWorkerPool(1), sink.Export, zap.NewNop(), onEmpty) + require.NoError(t, ba.Start(context.Background(), componenttest.NewNopHost())) + t.Cleanup(func() { + require.NoError(t, ba.Shutdown(context.Background())) + }) + + // Consume some data below min threshold so it stays in currentBatch + done := newFakeDone() + ba.Consume(context.Background(), &requesttest.FakeRequest{Items: 5}, done) + + // Wait for the batch to be flushed by timeout + assert.Eventually(t, func() bool { + return sink.RequestsCount() == 1 + }, 500*time.Millisecond, 10*time.Millisecond) + + // Now wait for idle timeout (partitionIdleCycles * FlushTimeout = 10 * 10ms = 100ms) + // The onEmpty callback should be called after the partition is idle for this duration. + assert.Eventually(t, func() bool { + return onEmptyCalled.Load() >= 1 + }, 500*time.Millisecond, 10*time.Millisecond) +} + +func TestPartitionBatcher_OnEmptyNotCalledWithActiveData(t *testing.T) { + // Test that onEmpty is NOT called when data keeps flowing + cfg := BatchConfig{ + FlushTimeout: 20 * time.Millisecond, + Sizer: request.SizerTypeItems, + MinSize: 5, + } + + sink := requesttest.NewSink() + onEmptyCalled := &atomic.Int64{} + onEmpty := func() { + onEmptyCalled.Add(1) + } + + ba := newPartitionBatcher(cfg, request.NewItemsSizer(), nil, newWorkerPool(1), sink.Export, zap.NewNop(), onEmpty) + require.NoError(t, ba.Start(context.Background(), componenttest.NewNopHost())) + t.Cleanup(func() { + require.NoError(t, ba.Shutdown(context.Background())) + }) + + done := newFakeDone() + // Keep sending data to prevent idle timeout + for range 5 { + ba.Consume(context.Background(), &requesttest.FakeRequest{Items: 5}, done) + time.Sleep(15 * time.Millisecond) + } + + // Data was flowing, onEmpty should not have been called + assert.Equal(t, int64(0), onEmptyCalled.Load()) + // But data should have been flushed + assert.GreaterOrEqual(t, sink.RequestsCount(), 1) +} diff --git a/exporter/exporterhelper/internal/queuebatch/queue_batch_test.go b/exporter/exporterhelper/internal/queuebatch/queue_batch_test.go index 0fcaf70ec1f5..46a344d7155d 100644 --- a/exporter/exporterhelper/internal/queuebatch/queue_batch_test.go +++ b/exporter/exporterhelper/internal/queuebatch/queue_batch_test.go @@ -124,7 +124,6 @@ func TestQueueBatchDifferentSizers(t *testing.T) { // because the bytes size is used for the queue, // but split because the items size is used for batch. cfg := Config{ - Enabled: true, WaitForResult: false, Sizer: request.SizerTypeBytes, QueueSize: 100, @@ -487,11 +486,9 @@ func TestQueueBatch_BatchBlocking(t *testing.T) { // send 6 blockOnOverflow requests wg := sync.WaitGroup{} for range 6 { - wg.Add(1) - go func() { - defer wg.Done() + wg.Go(func() { assert.NoError(t, qb.Send(context.Background(), &requesttest.FakeRequest{Items: 1, Delay: 10 * time.Millisecond})) - }() + }) } wg.Wait() @@ -604,7 +601,6 @@ func TestQueueBatchTimerFlush(t *testing.T) { func newTestConfig() Config { return Config{ - Enabled: true, WaitForResult: false, Sizer: request.SizerTypeItems, NumConsumers: runtime.NumCPU(), diff --git a/exporter/exporterhelper/internal/queuebatch/traces_batch_test.go b/exporter/exporterhelper/internal/queuebatch/traces_batch_test.go index 2dccdd9ab69a..4dae82dffbee 100644 --- a/exporter/exporterhelper/internal/queuebatch/traces_batch_test.go +++ b/exporter/exporterhelper/internal/queuebatch/traces_batch_test.go @@ -12,6 +12,7 @@ import ( "go.opentelemetry.io/collector/exporter/exporterhelper/internal/request" "go.opentelemetry.io/collector/exporter/exporterhelper/internal/sizer" + "go.opentelemetry.io/collector/internal/testutil" "go.opentelemetry.io/collector/pdata/ptrace" "go.opentelemetry.io/collector/pdata/testdata" ) @@ -338,6 +339,7 @@ func TestTracesMergeSplitUnknownSizerType(t *testing.T) { } func BenchmarkSplittingBasedOnItemCountManySmallTraces(b *testing.B) { + testutil.SkipGCHeavyBench(b) // All requests merge into a single batch. b.ReportAllocs() for b.Loop() { @@ -352,6 +354,7 @@ func BenchmarkSplittingBasedOnItemCountManySmallTraces(b *testing.B) { } func BenchmarkSplittingBasedOnItemCountManyTracesSlightlyAboveLimit(b *testing.B) { + testutil.SkipGCHeavyBench(b) // Every incoming request results in a split. b.ReportAllocs() for b.Loop() { @@ -366,6 +369,7 @@ func BenchmarkSplittingBasedOnItemCountManyTracesSlightlyAboveLimit(b *testing.B } func BenchmarkSplittingBasedOnItemCountHugeTraces(b *testing.B) { + testutil.SkipGCHeavyBench(b) // One request splits into many batches. b.ReportAllocs() for b.Loop() { diff --git a/exporter/exporterhelper/internal/sizer/proto_delta_sizer.go b/exporter/exporterhelper/internal/sizer/proto_delta_sizer.go index 1ed9c5a89673..5e8aa9408945 100644 --- a/exporter/exporterhelper/internal/sizer/proto_delta_sizer.go +++ b/exporter/exporterhelper/internal/sizer/proto_delta_sizer.go @@ -26,7 +26,7 @@ type protoDeltaSizer struct{} // - opentelemetry-collector/pdata/internal/data/protogen/profiles/v1development/profiles.pb.go // which is generated with gogo/protobuf. func (s *protoDeltaSizer) DeltaSize(newItemSize int) int { - return 1 + newItemSize + sov(uint64(newItemSize)) //nolint:gosec // disable G115 + return 1 + newItemSize + sov(uint64(newItemSize)) } func sov(x uint64) int { diff --git a/exporter/exporterhelper/logs_test.go b/exporter/exporterhelper/logs_test.go index 132712b567f7..79312364429e 100644 --- a/exporter/exporterhelper/logs_test.go +++ b/exporter/exporterhelper/logs_test.go @@ -17,11 +17,13 @@ import ( "go.opentelemetry.io/otel/sdk/metric/metricdata/metricdatatest" sdktrace "go.opentelemetry.io/otel/sdk/trace" "go.opentelemetry.io/otel/sdk/trace/tracetest" + semconv "go.opentelemetry.io/otel/semconv/v1.38.0" "go.opentelemetry.io/otel/trace" nooptrace "go.opentelemetry.io/otel/trace/noop" "go.opentelemetry.io/collector/component" "go.opentelemetry.io/collector/component/componenttest" + "go.opentelemetry.io/collector/config/configoptional" "go.opentelemetry.io/collector/consumer" "go.opentelemetry.io/collector/consumer/consumertest" "go.opentelemetry.io/collector/exporter" @@ -99,9 +101,9 @@ func TestLogs_Default_ReturnError(t *testing.T) { func TestLogs_WithPersistentQueue(t *testing.T) { fgOrigReadState := queue.PersistRequestContextOnRead fgOrigWriteState := queue.PersistRequestContextOnWrite - qCfg := NewDefaultQueueConfig() + qCfg := configoptional.Some(NewDefaultQueueConfig()) storageID := component.MustNewIDWithName("file_storage", "storage") - qCfg.StorageID = &storageID + qCfg.Get().StorageID = &storageID set := exportertest.NewNopSettings(exportertest.NopType) set.ID = component.MustNewIDWithName("test_logs", "with_persistent_queue") host := hosttest.NewHost(map[component.ID]component.Component{ @@ -344,7 +346,9 @@ func checkRecordedMetricsForLogs(t *testing.T, tt *componenttest.Telemetry, id c []metricdata.DataPoint[int64]{ { Attributes: attribute.NewSet( - attribute.String("exporter", id.String())), + attribute.String("exporter", id.String()), + attribute.String(string(semconv.ErrorTypeKey), "_OTHER"), + attribute.Bool(internal.ErrorPermanentKey, false)), Value: int64(numBatches * ld.LogRecordCount()), }, }, metricdatatest.IgnoreTimestamp(), metricdatatest.IgnoreExemplars()) diff --git a/exporter/exporterhelper/metadata.yaml b/exporter/exporterhelper/metadata.yaml index baa606a08fc8..1763c937f0c9 100644 --- a/exporter/exporterhelper/metadata.yaml +++ b/exporter/exporterhelper/metadata.yaml @@ -15,30 +15,36 @@ telemetry: metrics: exporter_enqueue_failed_log_records: enabled: true - stability: - level: alpha + stability: alpha description: Number of log records failed to be added to the sending queue. - unit: "{records}" + unit: "{record}" sum: value_type: int monotonic: true exporter_enqueue_failed_metric_points: enabled: true - stability: - level: alpha + stability: alpha description: Number of metric points failed to be added to the sending queue. - unit: "{datapoints}" + unit: "{datapoint}" + sum: + value_type: int + monotonic: true + + exporter_enqueue_failed_profile_samples: + enabled: true + stability: development + description: Number of profile samples failed to be added to the sending queue. + unit: "{sample}" sum: value_type: int monotonic: true exporter_enqueue_failed_spans: enabled: true - stability: - level: alpha + stability: alpha description: Number of spans failed to be added to the sending queue. - unit: "{spans}" + unit: "{span}" sum: value_type: int monotonic: true @@ -46,9 +52,8 @@ telemetry: exporter_queue_batch_send_size: enabled: true description: Number of units in the batch - stability: - level: development - unit: "{units}" + stability: development + unit: "{unit}" histogram: value_type: int bucket_boundaries: @@ -80,8 +85,7 @@ telemetry: exporter_queue_batch_send_size_bytes: enabled: true description: Number of bytes in batch that was sent. Only available on detailed level. - stability: - level: development + stability: development unit: By histogram: value_type: int @@ -105,80 +109,97 @@ telemetry: exporter_queue_capacity: enabled: true - stability: - level: alpha + stability: alpha description: Fixed capacity of the retry queue (in batches). - unit: "{batches}" + unit: "{batch}" gauge: value_type: int async: true exporter_queue_size: enabled: true - stability: - level: alpha + stability: alpha description: Current size of the retry queue (in batches). - unit: "{batches}" + unit: "{batch}" gauge: value_type: int async: true exporter_send_failed_log_records: enabled: true - stability: - level: alpha - description: Number of log records in failed attempts to send to destination. - unit: "{records}" + stability: alpha + description: "Number of log records in failed attempts to send to destination. At detailed telemetry level, includes attributes: error.type (semantic convention), error.permanent." + unit: "{record}" sum: value_type: int monotonic: true exporter_send_failed_metric_points: enabled: true - stability: - level: alpha - description: Number of metric points in failed attempts to send to destination. - unit: "{datapoints}" + stability: alpha + description: "Number of metric points in failed attempts to send to destination. At detailed telemetry level, includes attributes: error.type (semantic convention), error.permanent." + unit: "{datapoint}" + sum: + value_type: int + monotonic: true + + exporter_send_failed_profile_samples: + enabled: true + stability: development + description: "Number of profile samples in failed attempts to send to destination. At detailed telemetry level, includes attributes: error.type (semantic convention), error.permanent." + unit: "{sample}" sum: value_type: int monotonic: true exporter_send_failed_spans: enabled: true - stability: - level: alpha - description: Number of spans in failed attempts to send to destination. - unit: "{spans}" + stability: alpha + description: "Number of spans in failed attempts to send to destination. At detailed telemetry level, includes attributes: error.type (semantic convention), error.permanent." + unit: "{span}" sum: value_type: int monotonic: true exporter_sent_log_records: enabled: true - stability: - level: alpha + stability: alpha description: Number of log record successfully sent to destination. - unit: "{records}" + unit: "{record}" sum: value_type: int monotonic: true exporter_sent_metric_points: enabled: true - stability: - level: alpha + stability: alpha description: Number of metric points successfully sent to destination. - unit: "{datapoints}" + unit: "{datapoint}" + sum: + value_type: int + monotonic: true + + exporter_sent_profile_samples: + enabled: true + stability: development + description: Number of profile samples successfully sent to destination. + unit: "{sample}" sum: value_type: int monotonic: true exporter_sent_spans: enabled: true - stability: - level: alpha + stability: alpha description: Number of spans successfully sent to destination. - unit: "{spans}" + unit: "{span}" sum: value_type: int monotonic: true + +feature_gates: + - id: exporter.PersistRequestContext + description: 'controls whether context should be stored alongside requests in the persistent queue' + stage: beta + from_version: 'v0.128.0' + reference_url: 'https://github.com/open-telemetry/opentelemetry-collector/pull/13188' diff --git a/exporter/exporterhelper/metrics_test.go b/exporter/exporterhelper/metrics_test.go index dc559d9f9f31..11ec249d1c9f 100644 --- a/exporter/exporterhelper/metrics_test.go +++ b/exporter/exporterhelper/metrics_test.go @@ -17,11 +17,13 @@ import ( "go.opentelemetry.io/otel/sdk/metric/metricdata/metricdatatest" sdktrace "go.opentelemetry.io/otel/sdk/trace" "go.opentelemetry.io/otel/sdk/trace/tracetest" + semconv "go.opentelemetry.io/otel/semconv/v1.38.0" "go.opentelemetry.io/otel/trace" nooptrace "go.opentelemetry.io/otel/trace/noop" "go.opentelemetry.io/collector/component" "go.opentelemetry.io/collector/component/componenttest" + "go.opentelemetry.io/collector/config/configoptional" "go.opentelemetry.io/collector/consumer" "go.opentelemetry.io/collector/consumer/consumertest" "go.opentelemetry.io/collector/exporter" @@ -148,7 +150,7 @@ func TestMetrics_WithPersistentQueue(t *testing.T) { }) ms := consumertest.MetricsSink{} - te, err := NewMetrics(context.Background(), set, &fakeMetricsConfig, ms.ConsumeMetrics, WithQueue(qCfg)) + te, err := NewMetrics(context.Background(), set, &fakeMetricsConfig, ms.ConsumeMetrics, WithQueue(configoptional.Some(qCfg))) require.NoError(t, err) require.NoError(t, te.Start(context.Background(), host)) t.Cleanup(func() { require.NoError(t, te.Shutdown(context.Background())) }) @@ -348,7 +350,9 @@ func checkRecordedMetricsForMetrics(t *testing.T, tt *componenttest.Telemetry, i []metricdata.DataPoint[int64]{ { Attributes: attribute.NewSet( - attribute.String(internal.ExporterKey, id.String())), + attribute.String(internal.ExporterKey, id.String()), + attribute.String(string(semconv.ErrorTypeKey), "_OTHER"), + attribute.Bool(internal.ErrorPermanentKey, false)), Value: numPoints, }, }, metricdatatest.IgnoreTimestamp(), metricdatatest.IgnoreExemplars()) diff --git a/exporter/exporterhelper/queue_batch.go b/exporter/exporterhelper/queue_batch.go index 7d7808e82172..07128c0913d4 100644 --- a/exporter/exporterhelper/queue_batch.go +++ b/exporter/exporterhelper/queue_batch.go @@ -6,6 +6,7 @@ package exporterhelper // import "go.opentelemetry.io/collector/exporter/exporte import ( "context" + "go.opentelemetry.io/collector/config/configoptional" "go.opentelemetry.io/collector/exporter/exporterhelper/internal" "go.opentelemetry.io/collector/exporter/exporterhelper/internal/queue" "go.opentelemetry.io/collector/exporter/exporterhelper/internal/queuebatch" @@ -14,7 +15,7 @@ import ( // WithQueue overrides the default QueueBatchConfig for an exporter. // The default QueueBatchConfig is to disable queueing. // This option cannot be used with the new exporter helpers New[Traces|Metrics|Logs]RequestExporter. -func WithQueue(config QueueBatchConfig) Option { +func WithQueue(config configoptional.Optional[QueueBatchConfig]) Option { return internal.WithQueue(config) } diff --git a/exporter/exporterhelper/traces_test.go b/exporter/exporterhelper/traces_test.go index d4cb14c3b2f7..077565792228 100644 --- a/exporter/exporterhelper/traces_test.go +++ b/exporter/exporterhelper/traces_test.go @@ -17,11 +17,13 @@ import ( "go.opentelemetry.io/otel/sdk/metric/metricdata/metricdatatest" sdktrace "go.opentelemetry.io/otel/sdk/trace" "go.opentelemetry.io/otel/sdk/trace/tracetest" + semconv "go.opentelemetry.io/otel/semconv/v1.38.0" "go.opentelemetry.io/otel/trace" nooptrace "go.opentelemetry.io/otel/trace/noop" "go.opentelemetry.io/collector/component" "go.opentelemetry.io/collector/component/componenttest" + "go.opentelemetry.io/collector/config/configoptional" "go.opentelemetry.io/collector/consumer" "go.opentelemetry.io/collector/consumer/consumertest" "go.opentelemetry.io/collector/exporter" @@ -150,7 +152,7 @@ func TestTraces_WithPersistentQueue(t *testing.T) { }) ts := consumertest.TracesSink{} - te, err := NewTraces(context.Background(), set, &fakeTracesConfig, ts.ConsumeTraces, WithQueue(qCfg)) + te, err := NewTraces(context.Background(), set, &fakeTracesConfig, ts.ConsumeTraces, WithQueue(configoptional.Some(qCfg))) require.NoError(t, err) require.NoError(t, te.Start(context.Background(), host)) t.Cleanup(func() { require.NoError(t, te.Shutdown(context.Background())) }) @@ -353,7 +355,9 @@ func checkRecordedMetricsForTraces(t *testing.T, tt *componenttest.Telemetry, id []metricdata.DataPoint[int64]{ { Attributes: attribute.NewSet( - attribute.String(internal.ExporterKey, id.String())), + attribute.String(internal.ExporterKey, id.String()), + attribute.String(string(semconv.ErrorTypeKey), "_OTHER"), + attribute.Bool(internal.ErrorPermanentKey, false)), Value: int64(numBatches * td.SpanCount()), }, }, metricdatatest.IgnoreTimestamp(), metricdatatest.IgnoreExemplars()) diff --git a/exporter/exporterhelper/xexporterhelper/go.mod b/exporter/exporterhelper/xexporterhelper/go.mod index 6f9a14757dfe..47819e176466 100644 --- a/exporter/exporterhelper/xexporterhelper/go.mod +++ b/exporter/exporterhelper/xexporterhelper/go.mod @@ -1,28 +1,29 @@ module go.opentelemetry.io/collector/exporter/exporterhelper/xexporterhelper -go 1.24.0 +go 1.25.0 require ( github.com/stretchr/testify v1.11.1 - go.opentelemetry.io/collector/component v1.46.0 - go.opentelemetry.io/collector/component/componenttest v0.140.0 - go.opentelemetry.io/collector/consumer v1.46.0 - go.opentelemetry.io/collector/consumer/consumererror v0.140.0 + go.opentelemetry.io/collector/component v1.54.0 + go.opentelemetry.io/collector/component/componenttest v0.148.0 + go.opentelemetry.io/collector/config/configoptional v1.54.0 + go.opentelemetry.io/collector/consumer v1.54.0 + go.opentelemetry.io/collector/consumer/consumererror v0.148.0 go.opentelemetry.io/collector/consumer/consumererror/xconsumererror v0.140.0 - go.opentelemetry.io/collector/consumer/consumertest v0.140.0 - go.opentelemetry.io/collector/consumer/xconsumer v0.140.0 - go.opentelemetry.io/collector/exporter v1.46.0 - go.opentelemetry.io/collector/exporter/exporterhelper v0.140.0 + go.opentelemetry.io/collector/consumer/consumertest v0.148.0 + go.opentelemetry.io/collector/consumer/xconsumer v0.148.0 + go.opentelemetry.io/collector/exporter v1.54.0 + go.opentelemetry.io/collector/exporter/exporterhelper v0.148.0 go.opentelemetry.io/collector/exporter/exportertest v0.140.0 - go.opentelemetry.io/collector/exporter/xexporter v0.140.0 - go.opentelemetry.io/collector/pdata v1.46.0 - go.opentelemetry.io/collector/pdata/pprofile v0.140.0 - go.opentelemetry.io/collector/pdata/testdata v0.140.0 + go.opentelemetry.io/collector/exporter/xexporter v0.148.0 + go.opentelemetry.io/collector/pdata v1.54.0 + go.opentelemetry.io/collector/pdata/pprofile v0.148.0 + go.opentelemetry.io/collector/pdata/testdata v0.148.0 go.opentelemetry.io/collector/pdata/xpdata v0.140.0 go.opentelemetry.io/collector/pipeline/xpipeline v0.140.0 - go.opentelemetry.io/otel v1.40.0 + go.opentelemetry.io/otel v1.42.0 go.opentelemetry.io/otel/sdk v1.40.0 - go.opentelemetry.io/otel/trace v1.40.0 + go.opentelemetry.io/otel/trace v1.42.0 go.uber.org/zap v1.27.1 ) @@ -32,14 +33,15 @@ require ( github.com/davecgh/go-spew v1.1.1 // indirect github.com/go-logr/logr v1.4.3 // indirect github.com/go-logr/stdr v1.2.2 // indirect - github.com/go-viper/mapstructure/v2 v2.4.0 // indirect + github.com/go-viper/mapstructure/v2 v2.5.0 // indirect github.com/gobwas/glob v0.2.3 // indirect github.com/google/uuid v1.6.0 // indirect - github.com/hashicorp/go-version v1.7.0 // indirect + github.com/hashicorp/go-version v1.8.0 // indirect + github.com/hashicorp/golang-lru/v2 v2.0.7 // indirect github.com/json-iterator/go v1.1.12 // indirect github.com/knadh/koanf/maps v0.1.2 // indirect github.com/knadh/koanf/providers/confmap v1.0.0 // indirect - github.com/knadh/koanf/v2 v2.3.0 // indirect + github.com/knadh/koanf/v2 v2.3.3 // indirect github.com/mitchellh/copystructure v1.2.0 // indirect github.com/mitchellh/reflectwalk v1.0.2 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect @@ -47,25 +49,25 @@ require ( github.com/pmezard/go-difflib v1.0.0 // indirect go.opentelemetry.io/auto/sdk v1.2.1 // indirect go.opentelemetry.io/collector/client v1.46.0 // indirect - go.opentelemetry.io/collector/config/configoptional v1.46.0 // indirect - go.opentelemetry.io/collector/config/configretry v1.46.0 // indirect - go.opentelemetry.io/collector/confmap v1.46.0 // indirect - go.opentelemetry.io/collector/confmap/xconfmap v0.140.0 // indirect - go.opentelemetry.io/collector/extension v1.46.0 // indirect + go.opentelemetry.io/collector/config/configretry v1.54.0 // indirect + go.opentelemetry.io/collector/confmap v1.54.0 // indirect + go.opentelemetry.io/collector/confmap/xconfmap v0.148.0 // indirect + go.opentelemetry.io/collector/extension v1.54.0 // indirect go.opentelemetry.io/collector/extension/xextension v0.140.0 // indirect - go.opentelemetry.io/collector/featuregate v1.46.0 // indirect - go.opentelemetry.io/collector/pipeline v1.46.0 // indirect - go.opentelemetry.io/collector/receiver v1.46.0 // indirect - go.opentelemetry.io/collector/receiver/receivertest v0.140.0 // indirect - go.opentelemetry.io/collector/receiver/xreceiver v0.140.0 // indirect - go.opentelemetry.io/otel/metric v1.40.0 // indirect + go.opentelemetry.io/collector/featuregate v1.54.0 // indirect + go.opentelemetry.io/collector/internal/componentalias v0.148.0 // indirect + go.opentelemetry.io/collector/pipeline v1.54.0 // indirect + go.opentelemetry.io/collector/receiver v1.54.0 // indirect + go.opentelemetry.io/collector/receiver/receivertest v0.148.0 // indirect + go.opentelemetry.io/collector/receiver/xreceiver v0.148.0 // indirect + go.opentelemetry.io/otel/metric v1.42.0 // indirect go.opentelemetry.io/otel/sdk/metric v1.40.0 // indirect go.uber.org/multierr v1.11.0 // indirect go.yaml.in/yaml/v3 v3.0.4 // indirect - golang.org/x/sys v0.40.0 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20251022142026-3a174f9686a8 // indirect - google.golang.org/grpc v1.77.0 // indirect - google.golang.org/protobuf v1.36.10 // indirect + golang.org/x/sys v0.41.0 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20251222181119-0a764e51fe1b // indirect + google.golang.org/grpc v1.79.3 // indirect + google.golang.org/protobuf v1.36.11 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) @@ -128,3 +130,5 @@ replace go.opentelemetry.io/collector/confmap/xconfmap => ../../../confmap/xconf replace go.opentelemetry.io/collector/exporter/exporterhelper => ../ replace go.opentelemetry.io/collector/internal/testutil => ../../../internal/testutil + +replace go.opentelemetry.io/collector/internal/componentalias => ../../../internal/componentalias diff --git a/exporter/exporterhelper/xexporterhelper/go.sum b/exporter/exporterhelper/xexporterhelper/go.sum index d3c35ba1cbd6..d6e38a64eac0 100644 --- a/exporter/exporterhelper/xexporterhelper/go.sum +++ b/exporter/exporterhelper/xexporterhelper/go.sum @@ -10,8 +10,8 @@ github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI= github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= -github.com/go-viper/mapstructure/v2 v2.4.0 h1:EBsztssimR/CONLSZZ04E8qAkxNYq4Qp9LvH92wZUgs= -github.com/go-viper/mapstructure/v2 v2.4.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM= +github.com/go-viper/mapstructure/v2 v2.5.0 h1:vM5IJoUAy3d7zRSVtIwQgBj7BiWtMPfmPEgAXnvj1Ro= +github.com/go-viper/mapstructure/v2 v2.5.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM= github.com/gobwas/glob v0.2.3 h1:A4xDbljILXROh+kObIiy5kIaPYD8e96x1tgBhUI5J+Y= github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8= github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= @@ -21,16 +21,18 @@ github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/hashicorp/go-version v1.7.0 h1:5tqGy27NaOTB8yJKUZELlFAS/LTKJkrmONwQKeRZfjY= -github.com/hashicorp/go-version v1.7.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= +github.com/hashicorp/go-version v1.8.0 h1:KAkNb1HAiZd1ukkxDFGmokVZe1Xy9HG6NUp+bPle2i4= +github.com/hashicorp/go-version v1.8.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= +github.com/hashicorp/golang-lru/v2 v2.0.7 h1:a+bsQ5rvGLjzHuww6tVxozPZFVghXaHOwFs4luLUK2k= +github.com/hashicorp/golang-lru/v2 v2.0.7/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyfM2/ZepoAG6RGpeM= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= github.com/knadh/koanf/maps v0.1.2 h1:RBfmAW5CnZT+PJ1CVc1QSJKf4Xu9kxfQgYVQSu8hpbo= github.com/knadh/koanf/maps v0.1.2/go.mod h1:npD/QZY3V6ghQDdcQzl1W4ICNVTkohC8E73eI2xW4yI= github.com/knadh/koanf/providers/confmap v1.0.0 h1:mHKLJTE7iXEys6deO5p6olAiZdG5zwp8Aebir+/EaRE= github.com/knadh/koanf/providers/confmap v1.0.0/go.mod h1:txHYHiI2hAtF0/0sCmcuol4IDcuQbKTybiB1nOcUo1A= -github.com/knadh/koanf/v2 v2.3.0 h1:Qg076dDRFHvqnKG97ZEsi9TAg2/nFTa9hCdcSa1lvlM= -github.com/knadh/koanf/v2 v2.3.0/go.mod h1:gRb40VRAbd4iJMYYD5IxZ6hfuopFcXBpc9bbQpZwo28= +github.com/knadh/koanf/v2 v2.3.3 h1:jLJC8XCRfLC7n4F+ZKKdBsbq1bfXTpuFhf4L7t94D94= +github.com/knadh/koanf/v2 v2.3.3/go.mod h1:gRb40VRAbd4iJMYYD5IxZ6hfuopFcXBpc9bbQpZwo28= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= @@ -55,22 +57,22 @@ github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64= go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y= -go.opentelemetry.io/otel v1.40.0 h1:oA5YeOcpRTXq6NN7frwmwFR0Cn3RhTVZvXsP4duvCms= -go.opentelemetry.io/otel v1.40.0/go.mod h1:IMb+uXZUKkMXdPddhwAHm6UfOwJyh4ct1ybIlV14J0g= -go.opentelemetry.io/otel/metric v1.40.0 h1:rcZe317KPftE2rstWIBitCdVp89A2HqjkxR3c11+p9g= -go.opentelemetry.io/otel/metric v1.40.0/go.mod h1:ib/crwQH7N3r5kfiBZQbwrTge743UDc7DTFVZrrXnqc= +go.opentelemetry.io/otel v1.42.0 h1:lSQGzTgVR3+sgJDAU/7/ZMjN9Z+vUip7leaqBKy4sho= +go.opentelemetry.io/otel v1.42.0/go.mod h1:lJNsdRMxCUIWuMlVJWzecSMuNjE7dOYyWlqOXWkdqCc= +go.opentelemetry.io/otel/metric v1.42.0 h1:2jXG+3oZLNXEPfNmnpxKDeZsFI5o4J+nz6xUlaFdF/4= +go.opentelemetry.io/otel/metric v1.42.0/go.mod h1:RlUN/7vTU7Ao/diDkEpQpnz3/92J9ko05BIwxYa2SSI= go.opentelemetry.io/otel/sdk v1.40.0 h1:KHW/jUzgo6wsPh9At46+h4upjtccTmuZCFAc9OJ71f8= go.opentelemetry.io/otel/sdk v1.40.0/go.mod h1:Ph7EFdYvxq72Y8Li9q8KebuYUr2KoeyHx0DRMKrYBUE= go.opentelemetry.io/otel/sdk/metric v1.40.0 h1:mtmdVqgQkeRxHgRv4qhyJduP3fYJRMX4AtAlbuWdCYw= go.opentelemetry.io/otel/sdk/metric v1.40.0/go.mod h1:4Z2bGMf0KSK3uRjlczMOeMhKU2rhUqdWNoKcYrtcBPg= -go.opentelemetry.io/otel/trace v1.40.0 h1:WA4etStDttCSYuhwvEa8OP8I5EWu24lkOzp+ZYblVjw= -go.opentelemetry.io/otel/trace v1.40.0/go.mod h1:zeAhriXecNGP/s2SEG3+Y8X9ujcJOTqQ5RgdEJcawiA= -go.opentelemetry.io/proto/slim/otlp v1.9.0 h1:fPVMv8tP3TrsqlkH1HWYUpbCY9cAIemx184VGkS6vlE= -go.opentelemetry.io/proto/slim/otlp v1.9.0/go.mod h1:xXdeJJ90Gqyll+orzUkY4bOd2HECo5JofeoLpymVqdI= -go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.2.0 h1:o13nadWDNkH/quoDomDUClnQBpdQQ2Qqv0lQBjIXjE8= -go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.2.0/go.mod h1:Gyb6Xe7FTi/6xBHwMmngGoHqL0w29Y4eW8TGFzpefGA= -go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.2.0 h1:EiUYvtwu6PMrMHVjcPfnsG3v+ajPkbUeH+IL93+QYyk= -go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.2.0/go.mod h1:mUUHKFiN2SST3AhJ8XhJxEoeVW12oqfXog0Bo8W3Ec4= +go.opentelemetry.io/otel/trace v1.42.0 h1:OUCgIPt+mzOnaUTpOQcBiM/PLQ/Op7oq6g4LenLmOYY= +go.opentelemetry.io/otel/trace v1.42.0/go.mod h1:f3K9S+IFqnumBkKhRJMeaZeNk9epyhnCmQh/EysQCdc= +go.opentelemetry.io/proto/slim/otlp v1.10.0 h1:iR97Vs/ZDR+y9TfuP9b1XBtdPWeC+OMslIBmhcLU7jM= +go.opentelemetry.io/proto/slim/otlp v1.10.0/go.mod h1:lV9250stpjYLPNA5viFabIgP2QlUGRT1GdTgAf8SIUk= +go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.3.0 h1:RUF5rO0hAlgiJt1fzQVzcVs3vZVNHIcMLgOgG4rWNcQ= +go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.3.0/go.mod h1:I89cynRj8y+383o7tEQVg2SVA6SRgDVIouWPUVXjx0U= +go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.3.0 h1:CQvJSldHRUN6Z8jsUeYv8J0lXRvygALXIzsmAeCcZE0= +go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.3.0/go.mod h1:xSQ+mEfJe/GjK1LXEyVOoSI1N9JV9ZI923X5kup43W4= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= @@ -79,18 +81,18 @@ go.uber.org/zap v1.27.1 h1:08RqriUEv8+ArZRYSTXy1LeBScaMpVSTBhCeaZYfMYc= go.uber.org/zap v1.27.1/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc= go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg= -golang.org/x/net v0.46.1-0.20251013234738-63d1a5100f82 h1:6/3JGEh1C88g7m+qzzTbl3A0FtsLguXieqofVLU/JAo= -golang.org/x/net v0.46.1-0.20251013234738-63d1a5100f82/go.mod h1:Q9BGdFy1y4nkUwiLvT5qtyhAnEHgnQ/zd8PfU6nc210= -golang.org/x/sys v0.40.0 h1:DBZZqJ2Rkml6QMQsZywtnjnnGvHza6BTfYFWY9kjEWQ= -golang.org/x/sys v0.40.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= -golang.org/x/text v0.30.0 h1:yznKA/E9zq54KzlzBEAWn1NXSQ8DIp/NYMy88xJjl4k= -golang.org/x/text v0.30.0/go.mod h1:yDdHFIX9t+tORqspjENWgzaCVXgk0yYnYuSZ8UzzBVM= -google.golang.org/genproto/googleapis/rpc v0.0.0-20251022142026-3a174f9686a8 h1:M1rk8KBnUsBDg1oPGHNCxG4vc1f49epmTO7xscSajMk= -google.golang.org/genproto/googleapis/rpc v0.0.0-20251022142026-3a174f9686a8/go.mod h1:7i2o+ce6H/6BluujYR+kqX3GKH+dChPTQU19wjRPiGk= -google.golang.org/grpc v1.77.0 h1:wVVY6/8cGA6vvffn+wWK5ToddbgdU3d8MNENr4evgXM= -google.golang.org/grpc v1.77.0/go.mod h1:z0BY1iVj0q8E1uSQCjL9cppRj+gnZjzDnzV0dHhrNig= -google.golang.org/protobuf v1.36.10 h1:AYd7cD/uASjIL6Q9LiTjz8JLcrh/88q5UObnmY3aOOE= -google.golang.org/protobuf v1.36.10/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= +golang.org/x/net v0.51.0 h1:94R/GTO7mt3/4wIKpcR5gkGmRLOuE/2hNGeWq/GBIFo= +golang.org/x/net v0.51.0/go.mod h1:aamm+2QF5ogm02fjy5Bb7CQ0WMt1/WVM7FtyaTLlA9Y= +golang.org/x/sys v0.41.0 h1:Ivj+2Cp/ylzLiEU89QhWblYnOE9zerudt9Ftecq2C6k= +golang.org/x/sys v0.41.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= +golang.org/x/text v0.34.0 h1:oL/Qq0Kdaqxa1KbNeMKwQq0reLCCaFtqu2eNuSeNHbk= +golang.org/x/text v0.34.0/go.mod h1:homfLqTYRFyVYemLBFl5GgL/DWEiH5wcsQ5gSh1yziA= +google.golang.org/genproto/googleapis/rpc v0.0.0-20251222181119-0a764e51fe1b h1:Mv8VFug0MP9e5vUxfBcE3vUkV6CImK3cMNMIDFjmzxU= +google.golang.org/genproto/googleapis/rpc v0.0.0-20251222181119-0a764e51fe1b/go.mod h1:j9x/tPzZkyxcgEFkiKEEGxfvyumM01BEtsW8xzOahRQ= +google.golang.org/grpc v1.79.3 h1:sybAEdRIEtvcD68Gx7dmnwjZKlyfuc61Dyo9pGXXkKE= +google.golang.org/grpc v1.79.3/go.mod h1:KmT0Kjez+0dde/v2j9vzwoAScgEPx/Bw1CYChhHLrHQ= +google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE= +google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= diff --git a/exporter/exporterhelper/xexporterhelper/new_request.go b/exporter/exporterhelper/xexporterhelper/new_request.go index 7fe7472eeb51..12679e10a4f4 100644 --- a/exporter/exporterhelper/xexporterhelper/new_request.go +++ b/exporter/exporterhelper/xexporterhelper/new_request.go @@ -6,6 +6,7 @@ package xexporterhelper // import "go.opentelemetry.io/collector/exporter/export import ( "context" + "go.opentelemetry.io/collector/config/configoptional" "go.opentelemetry.io/collector/exporter" "go.opentelemetry.io/collector/exporter/exporterhelper" "go.opentelemetry.io/collector/exporter/exporterhelper/internal" @@ -81,8 +82,10 @@ func NewTracesQueueBatchSettings() QueueBatchSettings { // WithQueueBatch enables queueing and batching for an exporter. // This option should be used with the new exporter helpers New[Traces|Metrics|Logs]RequestExporter. +// If batch.partition.MetadataKeys is set, it will automatically configure the partitioner and merge function +// to partition batches based on the specified metadata keys. // Experimental: This API is at the early stage of development and may change without backward compatibility // until https://github.com/open-telemetry/opentelemetry-collector/issues/8122 is resolved. -func WithQueueBatch(cfg exporterhelper.QueueBatchConfig, set QueueBatchSettings) exporterhelper.Option { +func WithQueueBatch(cfg configoptional.Optional[exporterhelper.QueueBatchConfig], set QueueBatchSettings) exporterhelper.Option { return internal.WithQueueBatch(cfg, set) } diff --git a/exporter/exporterhelper/xexporterhelper/profiles_batch.go b/exporter/exporterhelper/xexporterhelper/profiles_batch.go index 3ee8d7a5c90a..2a837a745eb3 100644 --- a/exporter/exporterhelper/xexporterhelper/profiles_batch.go +++ b/exporter/exporterhelper/xexporterhelper/profiles_batch.go @@ -33,18 +33,10 @@ func (req *profilesRequest) MergeSplit(_ context.Context, maxSize int, szt expor if !ok { return nil, errors.New("invalid input type") } - // TODO(13106): handle merging of profiles (and change the indice tables with their new indices) - // req2.mergeTo(req, sz) - - // If no limit we can simply merge the new request into the current and return. - if maxSize == 0 { - return []Request{req, req2}, nil + err := req2.mergeTo(req, sz) + if err != nil { + return nil, fmt.Errorf("failed merging profiles; %w", err) } - - sp1, err1 := req.split(maxSize, sz) - sp2, err2 := req2.split(maxSize, sz) - - return append(sp1, sp2...), errors.Join(err1, err2) } // If no limit we can simply merge the new request into the current and return. @@ -54,14 +46,13 @@ func (req *profilesRequest) MergeSplit(_ context.Context, maxSize int, szt expor return req.split(maxSize, sz) } -// TODO(13106): handle merging of profiles (and change the indice tables with their new indices) -/*func (req *profilesRequest) mergeTo(dst *profilesRequest, sz sizer.ProfilesSizer) { +func (req *profilesRequest) mergeTo(dst *profilesRequest, sz sizer.ProfilesSizer) error { if sz != nil { dst.setCachedSize(dst.size(sz) + req.size(sz)) req.setCachedSize(0) } - req.pd.ResourceProfiles().MoveAndAppendTo(dst.pd.ResourceProfiles()) -}*/ + return req.pd.MergeTo(dst.pd) +} func (req *profilesRequest) split(maxSize int, sz sizer.ProfilesSizer) ([]Request, error) { var res []Request @@ -83,6 +74,8 @@ func extractProfiles(srcProfiles pprofile.Profiles, capacity int, sz sizer.Profi destProfiles := pprofile.NewProfiles() capacityLeft := capacity - sz.ProfilesSize(destProfiles) removedSize := 0 + + srcProfiles.Dictionary().CopyTo(destProfiles.Dictionary()) srcProfiles.ResourceProfiles().RemoveIf(func(srcRP pprofile.ResourceProfiles) bool { // If the no more capacity left just return. if capacityLeft == 0 { diff --git a/exporter/exporterhelper/xexporterhelper/profiles_batch_test.go b/exporter/exporterhelper/xexporterhelper/profiles_batch_test.go index 218f22fb1972..d53b35a2024c 100644 --- a/exporter/exporterhelper/xexporterhelper/profiles_batch_test.go +++ b/exporter/exporterhelper/xexporterhelper/profiles_batch_test.go @@ -22,9 +22,8 @@ func TestMergeProfiles(t *testing.T) { pr2 := newProfilesRequest(testdata.GenerateProfiles(3)) res, err := pr1.MergeSplit(context.Background(), 0, exporterhelper.RequestSizerTypeItems, pr2) require.NoError(t, err) - assert.Len(t, res, 2) - assert.Equal(t, 2, res[0].ItemsCount()) - assert.Equal(t, 3, res[1].ItemsCount()) + assert.Len(t, res, 1) + assert.Equal(t, 5, res[0].ItemsCount()) } func TestMergeProfilesInvalidInput(t *testing.T) { @@ -34,8 +33,6 @@ func TestMergeProfilesInvalidInput(t *testing.T) { } func TestMergeSplitProfiles(t *testing.T) { - t.Skip("merging of profiles has been temporarily disabled (https://github.com/open-telemetry/opentelemetry-collector/issues/13106)") - tests := []struct { name string szt exporterhelper.RequestSizerType @@ -53,12 +50,16 @@ func TestMergeSplitProfiles(t *testing.T) { expected: []Request{newProfilesRequest(pprofile.NewProfiles())}, }, { - name: "first_request_empty", - szt: exporterhelper.RequestSizerTypeItems, - maxSize: 10, - pr1: newProfilesRequest(pprofile.NewProfiles()), - pr2: newProfilesRequest(testdata.GenerateProfiles(5)), - expected: []Request{newProfilesRequest(testdata.GenerateProfiles(5))}, + name: "first_request_empty", + szt: exporterhelper.RequestSizerTypeItems, + maxSize: 10, + pr1: newProfilesRequest(testdata.GenerateProfiles(0)), + pr2: newProfilesRequest(testdata.GenerateProfiles(5)), + expected: []Request{newProfilesRequest(func() pprofile.Profiles { + profiles := testdata.GenerateProfiles(0) + _ = testdata.GenerateProfiles(5).MergeTo(profiles) + return profiles + }())}, }, { name: "first_empty_second_nil", @@ -137,8 +138,6 @@ func TestMergeSplitProfiles(t *testing.T) { } func TestMergeSplitProfilesBasedOnByteSize(t *testing.T) { - t.Skip("merging of profiles has been temporarily disabled (https://github.com/open-telemetry/opentelemetry-collector/issues/13106)") - tests := []struct { name string szt exporterhelper.RequestSizerType @@ -253,7 +252,7 @@ func TestMergeSplitProfilesBasedOnByteSize(t *testing.T) { { name: "merge_only", szt: exporterhelper.RequestSizerTypeBytes, - maxSize: profilesMarshaler.ProfilesSize(testdata.GenerateProfiles(11)), + maxSize: profilesMarshaler.ProfilesSize(testdata.GenerateProfiles(13)), pr1: newProfilesRequest(testdata.GenerateProfiles(4)), pr2: newProfilesRequest(testdata.GenerateProfiles(6)), expected: []Request{newProfilesRequest(func() pprofile.Profiles { @@ -266,12 +265,12 @@ func TestMergeSplitProfilesBasedOnByteSize(t *testing.T) { name: "split_only", szt: exporterhelper.RequestSizerTypeBytes, maxSize: profilesMarshaler.ProfilesSize(testdata.GenerateProfiles(4)), - pr1: newProfilesRequest(pprofile.NewProfiles()), + pr1: newProfilesRequest(testdata.GenerateProfiles(0)), pr2: newProfilesRequest(testdata.GenerateProfiles(10)), expected: []Request{ newProfilesRequest(testdata.GenerateProfiles(4)), - newProfilesRequest(testdata.GenerateProfiles(4)), - newProfilesRequest(testdata.GenerateProfiles(2)), + newProfilesRequest(testdata.GenerateProfiles(5)), + newProfilesRequest(testdata.GenerateProfiles(1)), }, }, { @@ -283,11 +282,11 @@ func TestMergeSplitProfilesBasedOnByteSize(t *testing.T) { expected: []Request{ newProfilesRequest(func() pprofile.Profiles { profiles := testdata.GenerateProfiles(7) - testdata.GenerateProfiles(2).ResourceProfiles().MoveAndAppendTo(profiles.ResourceProfiles()) + testdata.GenerateProfiles(3).ResourceProfiles().MoveAndAppendTo(profiles.ResourceProfiles()) return profiles }()), - newProfilesRequest(testdata.GenerateProfiles(10)), - newProfilesRequest(testdata.GenerateProfiles(9)), + newProfilesRequest(testdata.GenerateProfiles(11)), + newProfilesRequest(testdata.GenerateProfiles(7)), }, }, } @@ -312,22 +311,18 @@ func TestExtractProfiles(t *testing.T) { } } -func TestMergeSplitManySmallLogs(t *testing.T) { - t.Skip("merging of profiles has been temporarily disabled (https://github.com/open-telemetry/opentelemetry-collector/issues/13106)") - +func TestMergeSplitManySmallProfiles(t *testing.T) { // All requests merge into a single batch. merged := []Request{newProfilesRequest(testdata.GenerateProfiles(1))} for range 1000 { - lr2 := newProfilesRequest(testdata.GenerateProfiles(10)) - res, _ := merged[len(merged)-1].MergeSplit(context.Background(), 10000, exporterhelper.RequestSizerTypeItems, lr2) + pr2 := newProfilesRequest(testdata.GenerateProfiles(10)) + res, _ := merged[len(merged)-1].MergeSplit(context.Background(), 10000, exporterhelper.RequestSizerTypeItems, pr2) merged = append(merged[0:len(merged)-1], res...) } assert.Len(t, merged, 2) } func BenchmarkSplittingBasedOnByteSizeManySmallProfiles(b *testing.B) { - b.Skip("merging of profiles has been temporarily disabled (https://github.com/open-telemetry/opentelemetry-collector/issues/13106)") - // All requests merge into a single batch. b.ReportAllocs() for b.Loop() { @@ -342,13 +337,11 @@ func BenchmarkSplittingBasedOnByteSizeManySmallProfiles(b *testing.B) { ) merged = append(merged[0:len(merged)-1], res...) } - assert.Len(b, merged, 1) + assert.Len(b, merged, 2) } } func BenchmarkSplittingBasedOnByteSizeManyProfilesSlightlyAboveLimit(b *testing.B) { - b.Skip("merging of profiles has been temporarily disabled (https://github.com/open-telemetry/opentelemetry-collector/issues/13106)") - // Every incoming request results in a split. b.ReportAllocs() for b.Loop() { @@ -369,8 +362,6 @@ func BenchmarkSplittingBasedOnByteSizeManyProfilesSlightlyAboveLimit(b *testing. } func BenchmarkSplittingBasedOnByteSizeHugeProfiles(b *testing.B) { - b.Skip("merging of profiles has been temporarily disabled (https://github.com/open-telemetry/opentelemetry-collector/issues/13106)") - // One request splits into many batches. b.ReportAllocs() for b.Loop() { diff --git a/exporter/exporterhelper/xexporterhelper/profiles_test.go b/exporter/exporterhelper/xexporterhelper/profiles_test.go index a48d5a760758..c296a5c82e94 100644 --- a/exporter/exporterhelper/xexporterhelper/profiles_test.go +++ b/exporter/exporterhelper/xexporterhelper/profiles_test.go @@ -20,6 +20,7 @@ import ( "go.opentelemetry.io/collector/component" "go.opentelemetry.io/collector/component/componenttest" + "go.opentelemetry.io/collector/config/configoptional" "go.opentelemetry.io/collector/consumer" "go.opentelemetry.io/collector/consumer/consumererror" "go.opentelemetry.io/collector/consumer/consumererror/xconsumererror" @@ -218,7 +219,7 @@ func TestProfiles_WithPersistentQueue(t *testing.T) { }) ts := consumertest.ProfilesSink{} - te, err := NewProfiles(context.Background(), set, &fakeProfilesExporterConfig, ts.ConsumeProfiles, exporterhelper.WithQueue(qCfg)) + te, err := NewProfiles(context.Background(), set, &fakeProfilesExporterConfig, ts.ConsumeProfiles, exporterhelper.WithQueue(configoptional.Some(qCfg))) require.NoError(t, err) require.NoError(t, te.Start(context.Background(), host)) t.Cleanup(func() { require.NoError(t, te.Shutdown(context.Background())) }) diff --git a/exporter/exportertest/go.mod b/exporter/exportertest/go.mod index 1cc644c3a998..8021c56e0335 100644 --- a/exporter/exportertest/go.mod +++ b/exporter/exportertest/go.mod @@ -1,25 +1,25 @@ module go.opentelemetry.io/collector/exporter/exportertest -go 1.24.0 +go 1.25.0 require ( github.com/google/uuid v1.6.0 github.com/stretchr/testify v1.11.1 - go.opentelemetry.io/collector/component v1.46.0 - go.opentelemetry.io/collector/component/componenttest v0.140.0 - go.opentelemetry.io/collector/config/configretry v1.46.0 - go.opentelemetry.io/collector/consumer v1.46.0 - go.opentelemetry.io/collector/consumer/consumererror v0.140.0 - go.opentelemetry.io/collector/consumer/consumertest v0.140.0 - go.opentelemetry.io/collector/exporter v1.46.0 - go.opentelemetry.io/collector/exporter/exporterhelper v0.140.0 - go.opentelemetry.io/collector/exporter/xexporter v0.140.0 - go.opentelemetry.io/collector/pdata v1.46.0 - go.opentelemetry.io/collector/pdata/pprofile v0.140.0 - go.opentelemetry.io/collector/pipeline v1.46.0 - go.opentelemetry.io/collector/receiver v1.46.0 - go.opentelemetry.io/collector/receiver/receivertest v0.140.0 - google.golang.org/grpc v1.77.0 + go.opentelemetry.io/collector/component v1.54.0 + go.opentelemetry.io/collector/component/componenttest v0.148.0 + go.opentelemetry.io/collector/config/configretry v1.54.0 + go.opentelemetry.io/collector/consumer v1.54.0 + go.opentelemetry.io/collector/consumer/consumererror v0.148.0 + go.opentelemetry.io/collector/consumer/consumertest v0.148.0 + go.opentelemetry.io/collector/exporter v1.54.0 + go.opentelemetry.io/collector/exporter/exporterhelper v0.148.0 + go.opentelemetry.io/collector/exporter/xexporter v0.148.0 + go.opentelemetry.io/collector/pdata v1.54.0 + go.opentelemetry.io/collector/pdata/pprofile v0.148.0 + go.opentelemetry.io/collector/pipeline v1.54.0 + go.opentelemetry.io/collector/receiver v1.54.0 + go.opentelemetry.io/collector/receiver/receivertest v0.148.0 + google.golang.org/grpc v1.79.3 ) require ( @@ -28,13 +28,14 @@ require ( github.com/davecgh/go-spew v1.1.1 // indirect github.com/go-logr/logr v1.4.3 // indirect github.com/go-logr/stdr v1.2.2 // indirect - github.com/go-viper/mapstructure/v2 v2.4.0 // indirect + github.com/go-viper/mapstructure/v2 v2.5.0 // indirect github.com/gobwas/glob v0.2.3 // indirect - github.com/hashicorp/go-version v1.7.0 // indirect + github.com/hashicorp/go-version v1.8.0 // indirect + github.com/hashicorp/golang-lru/v2 v2.0.7 // indirect github.com/json-iterator/go v1.1.12 // indirect github.com/knadh/koanf/maps v0.1.2 // indirect github.com/knadh/koanf/providers/confmap v1.0.0 // indirect - github.com/knadh/koanf/v2 v2.3.0 // indirect + github.com/knadh/koanf/v2 v2.3.3 // indirect github.com/mitchellh/copystructure v1.2.0 // indirect github.com/mitchellh/reflectwalk v1.0.2 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect @@ -42,26 +43,28 @@ require ( github.com/pmezard/go-difflib v1.0.0 // indirect go.opentelemetry.io/auto/sdk v1.2.1 // indirect go.opentelemetry.io/collector/client v1.46.0 // indirect - go.opentelemetry.io/collector/config/configoptional v1.46.0 // indirect - go.opentelemetry.io/collector/confmap v1.46.0 // indirect - go.opentelemetry.io/collector/confmap/xconfmap v0.140.0 // indirect - go.opentelemetry.io/collector/consumer/xconsumer v0.140.0 // indirect - go.opentelemetry.io/collector/extension v1.46.0 // indirect + go.opentelemetry.io/collector/config/configoptional v1.54.0 // indirect + go.opentelemetry.io/collector/confmap v1.54.0 // indirect + go.opentelemetry.io/collector/confmap/xconfmap v0.148.0 // indirect + go.opentelemetry.io/collector/consumer/xconsumer v0.148.0 // indirect + go.opentelemetry.io/collector/extension v1.54.0 // indirect go.opentelemetry.io/collector/extension/xextension v0.140.0 // indirect - go.opentelemetry.io/collector/featuregate v1.46.0 // indirect + go.opentelemetry.io/collector/featuregate v1.54.0 // indirect + go.opentelemetry.io/collector/internal/componentalias v0.148.0 // indirect go.opentelemetry.io/collector/pdata/xpdata v0.140.0 // indirect - go.opentelemetry.io/collector/receiver/xreceiver v0.140.0 // indirect - go.opentelemetry.io/otel v1.40.0 // indirect - go.opentelemetry.io/otel/metric v1.40.0 // indirect + go.opentelemetry.io/collector/pipeline/xpipeline v0.0.0-00010101000000-000000000000 // indirect + go.opentelemetry.io/collector/receiver/xreceiver v0.148.0 // indirect + go.opentelemetry.io/otel v1.42.0 // indirect + go.opentelemetry.io/otel/metric v1.42.0 // indirect go.opentelemetry.io/otel/sdk v1.40.0 // indirect go.opentelemetry.io/otel/sdk/metric v1.40.0 // indirect - go.opentelemetry.io/otel/trace v1.40.0 // indirect + go.opentelemetry.io/otel/trace v1.42.0 // indirect go.uber.org/multierr v1.11.0 // indirect go.uber.org/zap v1.27.1 // indirect go.yaml.in/yaml/v3 v3.0.4 // indirect - golang.org/x/sys v0.40.0 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20251022142026-3a174f9686a8 // indirect - google.golang.org/protobuf v1.36.10 // indirect + golang.org/x/sys v0.41.0 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20251222181119-0a764e51fe1b // indirect + google.golang.org/protobuf v1.36.11 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) @@ -118,3 +121,7 @@ replace go.opentelemetry.io/collector/confmap/xconfmap => ../../confmap/xconfmap replace go.opentelemetry.io/collector/exporter/exporterhelper => ../exporterhelper replace go.opentelemetry.io/collector/internal/testutil => ../../internal/testutil + +replace go.opentelemetry.io/collector/internal/componentalias => ../../internal/componentalias + +replace go.opentelemetry.io/collector/pipeline/xpipeline => ../../pipeline/xpipeline diff --git a/exporter/exportertest/go.sum b/exporter/exportertest/go.sum index d3c35ba1cbd6..d6e38a64eac0 100644 --- a/exporter/exportertest/go.sum +++ b/exporter/exportertest/go.sum @@ -10,8 +10,8 @@ github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI= github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= -github.com/go-viper/mapstructure/v2 v2.4.0 h1:EBsztssimR/CONLSZZ04E8qAkxNYq4Qp9LvH92wZUgs= -github.com/go-viper/mapstructure/v2 v2.4.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM= +github.com/go-viper/mapstructure/v2 v2.5.0 h1:vM5IJoUAy3d7zRSVtIwQgBj7BiWtMPfmPEgAXnvj1Ro= +github.com/go-viper/mapstructure/v2 v2.5.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM= github.com/gobwas/glob v0.2.3 h1:A4xDbljILXROh+kObIiy5kIaPYD8e96x1tgBhUI5J+Y= github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8= github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= @@ -21,16 +21,18 @@ github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/hashicorp/go-version v1.7.0 h1:5tqGy27NaOTB8yJKUZELlFAS/LTKJkrmONwQKeRZfjY= -github.com/hashicorp/go-version v1.7.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= +github.com/hashicorp/go-version v1.8.0 h1:KAkNb1HAiZd1ukkxDFGmokVZe1Xy9HG6NUp+bPle2i4= +github.com/hashicorp/go-version v1.8.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= +github.com/hashicorp/golang-lru/v2 v2.0.7 h1:a+bsQ5rvGLjzHuww6tVxozPZFVghXaHOwFs4luLUK2k= +github.com/hashicorp/golang-lru/v2 v2.0.7/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyfM2/ZepoAG6RGpeM= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= github.com/knadh/koanf/maps v0.1.2 h1:RBfmAW5CnZT+PJ1CVc1QSJKf4Xu9kxfQgYVQSu8hpbo= github.com/knadh/koanf/maps v0.1.2/go.mod h1:npD/QZY3V6ghQDdcQzl1W4ICNVTkohC8E73eI2xW4yI= github.com/knadh/koanf/providers/confmap v1.0.0 h1:mHKLJTE7iXEys6deO5p6olAiZdG5zwp8Aebir+/EaRE= github.com/knadh/koanf/providers/confmap v1.0.0/go.mod h1:txHYHiI2hAtF0/0sCmcuol4IDcuQbKTybiB1nOcUo1A= -github.com/knadh/koanf/v2 v2.3.0 h1:Qg076dDRFHvqnKG97ZEsi9TAg2/nFTa9hCdcSa1lvlM= -github.com/knadh/koanf/v2 v2.3.0/go.mod h1:gRb40VRAbd4iJMYYD5IxZ6hfuopFcXBpc9bbQpZwo28= +github.com/knadh/koanf/v2 v2.3.3 h1:jLJC8XCRfLC7n4F+ZKKdBsbq1bfXTpuFhf4L7t94D94= +github.com/knadh/koanf/v2 v2.3.3/go.mod h1:gRb40VRAbd4iJMYYD5IxZ6hfuopFcXBpc9bbQpZwo28= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= @@ -55,22 +57,22 @@ github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64= go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y= -go.opentelemetry.io/otel v1.40.0 h1:oA5YeOcpRTXq6NN7frwmwFR0Cn3RhTVZvXsP4duvCms= -go.opentelemetry.io/otel v1.40.0/go.mod h1:IMb+uXZUKkMXdPddhwAHm6UfOwJyh4ct1ybIlV14J0g= -go.opentelemetry.io/otel/metric v1.40.0 h1:rcZe317KPftE2rstWIBitCdVp89A2HqjkxR3c11+p9g= -go.opentelemetry.io/otel/metric v1.40.0/go.mod h1:ib/crwQH7N3r5kfiBZQbwrTge743UDc7DTFVZrrXnqc= +go.opentelemetry.io/otel v1.42.0 h1:lSQGzTgVR3+sgJDAU/7/ZMjN9Z+vUip7leaqBKy4sho= +go.opentelemetry.io/otel v1.42.0/go.mod h1:lJNsdRMxCUIWuMlVJWzecSMuNjE7dOYyWlqOXWkdqCc= +go.opentelemetry.io/otel/metric v1.42.0 h1:2jXG+3oZLNXEPfNmnpxKDeZsFI5o4J+nz6xUlaFdF/4= +go.opentelemetry.io/otel/metric v1.42.0/go.mod h1:RlUN/7vTU7Ao/diDkEpQpnz3/92J9ko05BIwxYa2SSI= go.opentelemetry.io/otel/sdk v1.40.0 h1:KHW/jUzgo6wsPh9At46+h4upjtccTmuZCFAc9OJ71f8= go.opentelemetry.io/otel/sdk v1.40.0/go.mod h1:Ph7EFdYvxq72Y8Li9q8KebuYUr2KoeyHx0DRMKrYBUE= go.opentelemetry.io/otel/sdk/metric v1.40.0 h1:mtmdVqgQkeRxHgRv4qhyJduP3fYJRMX4AtAlbuWdCYw= go.opentelemetry.io/otel/sdk/metric v1.40.0/go.mod h1:4Z2bGMf0KSK3uRjlczMOeMhKU2rhUqdWNoKcYrtcBPg= -go.opentelemetry.io/otel/trace v1.40.0 h1:WA4etStDttCSYuhwvEa8OP8I5EWu24lkOzp+ZYblVjw= -go.opentelemetry.io/otel/trace v1.40.0/go.mod h1:zeAhriXecNGP/s2SEG3+Y8X9ujcJOTqQ5RgdEJcawiA= -go.opentelemetry.io/proto/slim/otlp v1.9.0 h1:fPVMv8tP3TrsqlkH1HWYUpbCY9cAIemx184VGkS6vlE= -go.opentelemetry.io/proto/slim/otlp v1.9.0/go.mod h1:xXdeJJ90Gqyll+orzUkY4bOd2HECo5JofeoLpymVqdI= -go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.2.0 h1:o13nadWDNkH/quoDomDUClnQBpdQQ2Qqv0lQBjIXjE8= -go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.2.0/go.mod h1:Gyb6Xe7FTi/6xBHwMmngGoHqL0w29Y4eW8TGFzpefGA= -go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.2.0 h1:EiUYvtwu6PMrMHVjcPfnsG3v+ajPkbUeH+IL93+QYyk= -go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.2.0/go.mod h1:mUUHKFiN2SST3AhJ8XhJxEoeVW12oqfXog0Bo8W3Ec4= +go.opentelemetry.io/otel/trace v1.42.0 h1:OUCgIPt+mzOnaUTpOQcBiM/PLQ/Op7oq6g4LenLmOYY= +go.opentelemetry.io/otel/trace v1.42.0/go.mod h1:f3K9S+IFqnumBkKhRJMeaZeNk9epyhnCmQh/EysQCdc= +go.opentelemetry.io/proto/slim/otlp v1.10.0 h1:iR97Vs/ZDR+y9TfuP9b1XBtdPWeC+OMslIBmhcLU7jM= +go.opentelemetry.io/proto/slim/otlp v1.10.0/go.mod h1:lV9250stpjYLPNA5viFabIgP2QlUGRT1GdTgAf8SIUk= +go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.3.0 h1:RUF5rO0hAlgiJt1fzQVzcVs3vZVNHIcMLgOgG4rWNcQ= +go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.3.0/go.mod h1:I89cynRj8y+383o7tEQVg2SVA6SRgDVIouWPUVXjx0U= +go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.3.0 h1:CQvJSldHRUN6Z8jsUeYv8J0lXRvygALXIzsmAeCcZE0= +go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.3.0/go.mod h1:xSQ+mEfJe/GjK1LXEyVOoSI1N9JV9ZI923X5kup43W4= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= @@ -79,18 +81,18 @@ go.uber.org/zap v1.27.1 h1:08RqriUEv8+ArZRYSTXy1LeBScaMpVSTBhCeaZYfMYc= go.uber.org/zap v1.27.1/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc= go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg= -golang.org/x/net v0.46.1-0.20251013234738-63d1a5100f82 h1:6/3JGEh1C88g7m+qzzTbl3A0FtsLguXieqofVLU/JAo= -golang.org/x/net v0.46.1-0.20251013234738-63d1a5100f82/go.mod h1:Q9BGdFy1y4nkUwiLvT5qtyhAnEHgnQ/zd8PfU6nc210= -golang.org/x/sys v0.40.0 h1:DBZZqJ2Rkml6QMQsZywtnjnnGvHza6BTfYFWY9kjEWQ= -golang.org/x/sys v0.40.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= -golang.org/x/text v0.30.0 h1:yznKA/E9zq54KzlzBEAWn1NXSQ8DIp/NYMy88xJjl4k= -golang.org/x/text v0.30.0/go.mod h1:yDdHFIX9t+tORqspjENWgzaCVXgk0yYnYuSZ8UzzBVM= -google.golang.org/genproto/googleapis/rpc v0.0.0-20251022142026-3a174f9686a8 h1:M1rk8KBnUsBDg1oPGHNCxG4vc1f49epmTO7xscSajMk= -google.golang.org/genproto/googleapis/rpc v0.0.0-20251022142026-3a174f9686a8/go.mod h1:7i2o+ce6H/6BluujYR+kqX3GKH+dChPTQU19wjRPiGk= -google.golang.org/grpc v1.77.0 h1:wVVY6/8cGA6vvffn+wWK5ToddbgdU3d8MNENr4evgXM= -google.golang.org/grpc v1.77.0/go.mod h1:z0BY1iVj0q8E1uSQCjL9cppRj+gnZjzDnzV0dHhrNig= -google.golang.org/protobuf v1.36.10 h1:AYd7cD/uASjIL6Q9LiTjz8JLcrh/88q5UObnmY3aOOE= -google.golang.org/protobuf v1.36.10/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= +golang.org/x/net v0.51.0 h1:94R/GTO7mt3/4wIKpcR5gkGmRLOuE/2hNGeWq/GBIFo= +golang.org/x/net v0.51.0/go.mod h1:aamm+2QF5ogm02fjy5Bb7CQ0WMt1/WVM7FtyaTLlA9Y= +golang.org/x/sys v0.41.0 h1:Ivj+2Cp/ylzLiEU89QhWblYnOE9zerudt9Ftecq2C6k= +golang.org/x/sys v0.41.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= +golang.org/x/text v0.34.0 h1:oL/Qq0Kdaqxa1KbNeMKwQq0reLCCaFtqu2eNuSeNHbk= +golang.org/x/text v0.34.0/go.mod h1:homfLqTYRFyVYemLBFl5GgL/DWEiH5wcsQ5gSh1yziA= +google.golang.org/genproto/googleapis/rpc v0.0.0-20251222181119-0a764e51fe1b h1:Mv8VFug0MP9e5vUxfBcE3vUkV6CImK3cMNMIDFjmzxU= +google.golang.org/genproto/googleapis/rpc v0.0.0-20251222181119-0a764e51fe1b/go.mod h1:j9x/tPzZkyxcgEFkiKEEGxfvyumM01BEtsW8xzOahRQ= +google.golang.org/grpc v1.79.3 h1:sybAEdRIEtvcD68Gx7dmnwjZKlyfuc61Dyo9pGXXkKE= +google.golang.org/grpc v1.79.3/go.mod h1:KmT0Kjez+0dde/v2j9vzwoAScgEPx/Bw1CYChhHLrHQ= +google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE= +google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= diff --git a/exporter/exportertest/metadata.yaml b/exporter/exportertest/metadata.yaml new file mode 100644 index 000000000000..284be79ad19d --- /dev/null +++ b/exporter/exportertest/metadata.yaml @@ -0,0 +1,6 @@ +type: exporter/exportertest +github_project: open-telemetry/opentelemetry-collector + +status: + disable_codecov_badge: true + class: pkg diff --git a/exporter/go.mod b/exporter/go.mod index edad1a789e93..e8dfd15d6e16 100644 --- a/exporter/go.mod +++ b/exporter/go.mod @@ -1,16 +1,18 @@ module go.opentelemetry.io/collector/exporter -go 1.24.0 +go 1.25.0 require ( github.com/stretchr/testify v1.11.1 - go.opentelemetry.io/collector/component v1.46.0 - go.opentelemetry.io/collector/config/configretry v1.46.0 - go.opentelemetry.io/collector/consumer v1.46.0 - go.opentelemetry.io/collector/consumer/consumertest v0.140.0 - go.opentelemetry.io/collector/exporter/exporterhelper v0.140.0 - go.opentelemetry.io/collector/pdata v1.46.0 - go.opentelemetry.io/collector/pipeline v1.46.0 + go.opentelemetry.io/collector/component v1.54.0 + go.opentelemetry.io/collector/config/configoptional v1.54.0 + go.opentelemetry.io/collector/config/configretry v1.54.0 + go.opentelemetry.io/collector/consumer v1.54.0 + go.opentelemetry.io/collector/consumer/consumertest v0.148.0 + go.opentelemetry.io/collector/exporter/exporterhelper v0.148.0 + go.opentelemetry.io/collector/internal/componentalias v0.148.0 + go.opentelemetry.io/collector/pdata v1.54.0 + go.opentelemetry.io/collector/pipeline v1.54.0 go.uber.org/goleak v1.3.0 go.uber.org/zap v1.27.1 ) @@ -19,38 +21,39 @@ require ( github.com/cenkalti/backoff/v5 v5.0.3 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/davecgh/go-spew v1.1.1 // indirect - github.com/go-viper/mapstructure/v2 v2.4.0 // indirect + github.com/go-viper/mapstructure/v2 v2.5.0 // indirect github.com/gobwas/glob v0.2.3 // indirect - github.com/hashicorp/go-version v1.7.0 // indirect + github.com/hashicorp/go-version v1.8.0 // indirect + github.com/hashicorp/golang-lru/v2 v2.0.7 // indirect github.com/json-iterator/go v1.1.12 // indirect github.com/knadh/koanf/maps v0.1.2 // indirect github.com/knadh/koanf/providers/confmap v1.0.0 // indirect - github.com/knadh/koanf/v2 v2.3.0 // indirect + github.com/knadh/koanf/v2 v2.3.3 // indirect github.com/mitchellh/copystructure v1.2.0 // indirect github.com/mitchellh/reflectwalk v1.0.2 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee // indirect github.com/pmezard/go-difflib v1.0.0 // indirect go.opentelemetry.io/collector/client v1.46.0 // indirect - go.opentelemetry.io/collector/config/configoptional v1.46.0 // indirect - go.opentelemetry.io/collector/confmap v1.46.0 // indirect - go.opentelemetry.io/collector/confmap/xconfmap v0.140.0 // indirect - go.opentelemetry.io/collector/consumer/consumererror v0.140.0 // indirect - go.opentelemetry.io/collector/consumer/xconsumer v0.140.0 // indirect - go.opentelemetry.io/collector/extension v1.46.0 // indirect + go.opentelemetry.io/collector/confmap v1.54.0 // indirect + go.opentelemetry.io/collector/confmap/xconfmap v0.148.0 // indirect + go.opentelemetry.io/collector/consumer/consumererror v0.148.0 // indirect + go.opentelemetry.io/collector/consumer/xconsumer v0.148.0 // indirect + go.opentelemetry.io/collector/extension v1.54.0 // indirect go.opentelemetry.io/collector/extension/xextension v0.140.0 // indirect - go.opentelemetry.io/collector/featuregate v1.46.0 // indirect - go.opentelemetry.io/collector/pdata/pprofile v0.140.0 // indirect + go.opentelemetry.io/collector/featuregate v1.54.0 // indirect + go.opentelemetry.io/collector/pdata/pprofile v0.148.0 // indirect go.opentelemetry.io/collector/pdata/xpdata v0.140.0 // indirect - go.opentelemetry.io/otel v1.40.0 // indirect - go.opentelemetry.io/otel/metric v1.40.0 // indirect - go.opentelemetry.io/otel/trace v1.40.0 // indirect + go.opentelemetry.io/collector/pipeline/xpipeline v0.0.0-00010101000000-000000000000 // indirect + go.opentelemetry.io/otel v1.42.0 // indirect + go.opentelemetry.io/otel/metric v1.42.0 // indirect + go.opentelemetry.io/otel/trace v1.42.0 // indirect go.uber.org/multierr v1.11.0 // indirect go.yaml.in/yaml/v3 v3.0.4 // indirect - golang.org/x/sys v0.40.0 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20251022142026-3a174f9686a8 // indirect - google.golang.org/grpc v1.77.0 // indirect - google.golang.org/protobuf v1.36.10 // indirect + golang.org/x/sys v0.41.0 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20251222181119-0a764e51fe1b // indirect + google.golang.org/grpc v1.79.3 // indirect + google.golang.org/protobuf v1.36.11 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) @@ -109,3 +112,7 @@ replace go.opentelemetry.io/collector/confmap/xconfmap => ../confmap/xconfmap replace go.opentelemetry.io/collector/exporter/exporterhelper => ./exporterhelper replace go.opentelemetry.io/collector/internal/testutil => ../internal/testutil + +replace go.opentelemetry.io/collector/internal/componentalias => ../internal/componentalias + +replace go.opentelemetry.io/collector/pipeline/xpipeline => ../pipeline/xpipeline diff --git a/exporter/go.sum b/exporter/go.sum index b88ccb71a844..3b9cc545f3b4 100644 --- a/exporter/go.sum +++ b/exporter/go.sum @@ -9,8 +9,8 @@ github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI= github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= -github.com/go-viper/mapstructure/v2 v2.4.0 h1:EBsztssimR/CONLSZZ04E8qAkxNYq4Qp9LvH92wZUgs= -github.com/go-viper/mapstructure/v2 v2.4.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM= +github.com/go-viper/mapstructure/v2 v2.5.0 h1:vM5IJoUAy3d7zRSVtIwQgBj7BiWtMPfmPEgAXnvj1Ro= +github.com/go-viper/mapstructure/v2 v2.5.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM= github.com/gobwas/glob v0.2.3 h1:A4xDbljILXROh+kObIiy5kIaPYD8e96x1tgBhUI5J+Y= github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8= github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= @@ -20,16 +20,18 @@ github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/hashicorp/go-version v1.7.0 h1:5tqGy27NaOTB8yJKUZELlFAS/LTKJkrmONwQKeRZfjY= -github.com/hashicorp/go-version v1.7.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= +github.com/hashicorp/go-version v1.8.0 h1:KAkNb1HAiZd1ukkxDFGmokVZe1Xy9HG6NUp+bPle2i4= +github.com/hashicorp/go-version v1.8.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= +github.com/hashicorp/golang-lru/v2 v2.0.7 h1:a+bsQ5rvGLjzHuww6tVxozPZFVghXaHOwFs4luLUK2k= +github.com/hashicorp/golang-lru/v2 v2.0.7/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyfM2/ZepoAG6RGpeM= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= github.com/knadh/koanf/maps v0.1.2 h1:RBfmAW5CnZT+PJ1CVc1QSJKf4Xu9kxfQgYVQSu8hpbo= github.com/knadh/koanf/maps v0.1.2/go.mod h1:npD/QZY3V6ghQDdcQzl1W4ICNVTkohC8E73eI2xW4yI= github.com/knadh/koanf/providers/confmap v1.0.0 h1:mHKLJTE7iXEys6deO5p6olAiZdG5zwp8Aebir+/EaRE= github.com/knadh/koanf/providers/confmap v1.0.0/go.mod h1:txHYHiI2hAtF0/0sCmcuol4IDcuQbKTybiB1nOcUo1A= -github.com/knadh/koanf/v2 v2.3.0 h1:Qg076dDRFHvqnKG97ZEsi9TAg2/nFTa9hCdcSa1lvlM= -github.com/knadh/koanf/v2 v2.3.0/go.mod h1:gRb40VRAbd4iJMYYD5IxZ6hfuopFcXBpc9bbQpZwo28= +github.com/knadh/koanf/v2 v2.3.3 h1:jLJC8XCRfLC7n4F+ZKKdBsbq1bfXTpuFhf4L7t94D94= +github.com/knadh/koanf/v2 v2.3.3/go.mod h1:gRb40VRAbd4iJMYYD5IxZ6hfuopFcXBpc9bbQpZwo28= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= @@ -54,22 +56,22 @@ github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64= go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y= -go.opentelemetry.io/otel v1.40.0 h1:oA5YeOcpRTXq6NN7frwmwFR0Cn3RhTVZvXsP4duvCms= -go.opentelemetry.io/otel v1.40.0/go.mod h1:IMb+uXZUKkMXdPddhwAHm6UfOwJyh4ct1ybIlV14J0g= -go.opentelemetry.io/otel/metric v1.40.0 h1:rcZe317KPftE2rstWIBitCdVp89A2HqjkxR3c11+p9g= -go.opentelemetry.io/otel/metric v1.40.0/go.mod h1:ib/crwQH7N3r5kfiBZQbwrTge743UDc7DTFVZrrXnqc= +go.opentelemetry.io/otel v1.42.0 h1:lSQGzTgVR3+sgJDAU/7/ZMjN9Z+vUip7leaqBKy4sho= +go.opentelemetry.io/otel v1.42.0/go.mod h1:lJNsdRMxCUIWuMlVJWzecSMuNjE7dOYyWlqOXWkdqCc= +go.opentelemetry.io/otel/metric v1.42.0 h1:2jXG+3oZLNXEPfNmnpxKDeZsFI5o4J+nz6xUlaFdF/4= +go.opentelemetry.io/otel/metric v1.42.0/go.mod h1:RlUN/7vTU7Ao/diDkEpQpnz3/92J9ko05BIwxYa2SSI= go.opentelemetry.io/otel/sdk v1.40.0 h1:KHW/jUzgo6wsPh9At46+h4upjtccTmuZCFAc9OJ71f8= go.opentelemetry.io/otel/sdk v1.40.0/go.mod h1:Ph7EFdYvxq72Y8Li9q8KebuYUr2KoeyHx0DRMKrYBUE= go.opentelemetry.io/otel/sdk/metric v1.40.0 h1:mtmdVqgQkeRxHgRv4qhyJduP3fYJRMX4AtAlbuWdCYw= go.opentelemetry.io/otel/sdk/metric v1.40.0/go.mod h1:4Z2bGMf0KSK3uRjlczMOeMhKU2rhUqdWNoKcYrtcBPg= -go.opentelemetry.io/otel/trace v1.40.0 h1:WA4etStDttCSYuhwvEa8OP8I5EWu24lkOzp+ZYblVjw= -go.opentelemetry.io/otel/trace v1.40.0/go.mod h1:zeAhriXecNGP/s2SEG3+Y8X9ujcJOTqQ5RgdEJcawiA= -go.opentelemetry.io/proto/slim/otlp v1.9.0 h1:fPVMv8tP3TrsqlkH1HWYUpbCY9cAIemx184VGkS6vlE= -go.opentelemetry.io/proto/slim/otlp v1.9.0/go.mod h1:xXdeJJ90Gqyll+orzUkY4bOd2HECo5JofeoLpymVqdI= -go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.2.0 h1:o13nadWDNkH/quoDomDUClnQBpdQQ2Qqv0lQBjIXjE8= -go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.2.0/go.mod h1:Gyb6Xe7FTi/6xBHwMmngGoHqL0w29Y4eW8TGFzpefGA= -go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.2.0 h1:EiUYvtwu6PMrMHVjcPfnsG3v+ajPkbUeH+IL93+QYyk= -go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.2.0/go.mod h1:mUUHKFiN2SST3AhJ8XhJxEoeVW12oqfXog0Bo8W3Ec4= +go.opentelemetry.io/otel/trace v1.42.0 h1:OUCgIPt+mzOnaUTpOQcBiM/PLQ/Op7oq6g4LenLmOYY= +go.opentelemetry.io/otel/trace v1.42.0/go.mod h1:f3K9S+IFqnumBkKhRJMeaZeNk9epyhnCmQh/EysQCdc= +go.opentelemetry.io/proto/slim/otlp v1.10.0 h1:iR97Vs/ZDR+y9TfuP9b1XBtdPWeC+OMslIBmhcLU7jM= +go.opentelemetry.io/proto/slim/otlp v1.10.0/go.mod h1:lV9250stpjYLPNA5viFabIgP2QlUGRT1GdTgAf8SIUk= +go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.3.0 h1:RUF5rO0hAlgiJt1fzQVzcVs3vZVNHIcMLgOgG4rWNcQ= +go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.3.0/go.mod h1:I89cynRj8y+383o7tEQVg2SVA6SRgDVIouWPUVXjx0U= +go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.3.0 h1:CQvJSldHRUN6Z8jsUeYv8J0lXRvygALXIzsmAeCcZE0= +go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.3.0/go.mod h1:xSQ+mEfJe/GjK1LXEyVOoSI1N9JV9ZI923X5kup43W4= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= @@ -78,18 +80,18 @@ go.uber.org/zap v1.27.1 h1:08RqriUEv8+ArZRYSTXy1LeBScaMpVSTBhCeaZYfMYc= go.uber.org/zap v1.27.1/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc= go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg= -golang.org/x/net v0.46.1-0.20251013234738-63d1a5100f82 h1:6/3JGEh1C88g7m+qzzTbl3A0FtsLguXieqofVLU/JAo= -golang.org/x/net v0.46.1-0.20251013234738-63d1a5100f82/go.mod h1:Q9BGdFy1y4nkUwiLvT5qtyhAnEHgnQ/zd8PfU6nc210= -golang.org/x/sys v0.40.0 h1:DBZZqJ2Rkml6QMQsZywtnjnnGvHza6BTfYFWY9kjEWQ= -golang.org/x/sys v0.40.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= -golang.org/x/text v0.30.0 h1:yznKA/E9zq54KzlzBEAWn1NXSQ8DIp/NYMy88xJjl4k= -golang.org/x/text v0.30.0/go.mod h1:yDdHFIX9t+tORqspjENWgzaCVXgk0yYnYuSZ8UzzBVM= -google.golang.org/genproto/googleapis/rpc v0.0.0-20251022142026-3a174f9686a8 h1:M1rk8KBnUsBDg1oPGHNCxG4vc1f49epmTO7xscSajMk= -google.golang.org/genproto/googleapis/rpc v0.0.0-20251022142026-3a174f9686a8/go.mod h1:7i2o+ce6H/6BluujYR+kqX3GKH+dChPTQU19wjRPiGk= -google.golang.org/grpc v1.77.0 h1:wVVY6/8cGA6vvffn+wWK5ToddbgdU3d8MNENr4evgXM= -google.golang.org/grpc v1.77.0/go.mod h1:z0BY1iVj0q8E1uSQCjL9cppRj+gnZjzDnzV0dHhrNig= -google.golang.org/protobuf v1.36.10 h1:AYd7cD/uASjIL6Q9LiTjz8JLcrh/88q5UObnmY3aOOE= -google.golang.org/protobuf v1.36.10/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= +golang.org/x/net v0.51.0 h1:94R/GTO7mt3/4wIKpcR5gkGmRLOuE/2hNGeWq/GBIFo= +golang.org/x/net v0.51.0/go.mod h1:aamm+2QF5ogm02fjy5Bb7CQ0WMt1/WVM7FtyaTLlA9Y= +golang.org/x/sys v0.41.0 h1:Ivj+2Cp/ylzLiEU89QhWblYnOE9zerudt9Ftecq2C6k= +golang.org/x/sys v0.41.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= +golang.org/x/text v0.34.0 h1:oL/Qq0Kdaqxa1KbNeMKwQq0reLCCaFtqu2eNuSeNHbk= +golang.org/x/text v0.34.0/go.mod h1:homfLqTYRFyVYemLBFl5GgL/DWEiH5wcsQ5gSh1yziA= +google.golang.org/genproto/googleapis/rpc v0.0.0-20251222181119-0a764e51fe1b h1:Mv8VFug0MP9e5vUxfBcE3vUkV6CImK3cMNMIDFjmzxU= +google.golang.org/genproto/googleapis/rpc v0.0.0-20251222181119-0a764e51fe1b/go.mod h1:j9x/tPzZkyxcgEFkiKEEGxfvyumM01BEtsW8xzOahRQ= +google.golang.org/grpc v1.79.3 h1:sybAEdRIEtvcD68Gx7dmnwjZKlyfuc61Dyo9pGXXkKE= +google.golang.org/grpc v1.79.3/go.mod h1:KmT0Kjez+0dde/v2j9vzwoAScgEPx/Bw1CYChhHLrHQ= +google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE= +google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= diff --git a/exporter/metadata.yaml b/exporter/metadata.yaml new file mode 100644 index 000000000000..9e7a22f48cea --- /dev/null +++ b/exporter/metadata.yaml @@ -0,0 +1,6 @@ +type: exporter +github_project: open-telemetry/opentelemetry-collector + +status: + disable_codecov_badge: true + class: pkg diff --git a/exporter/nopexporter/README.md b/exporter/nopexporter/README.md index c2159a297cda..f4c5f3ef3f39 100644 --- a/exporter/nopexporter/README.md +++ b/exporter/nopexporter/README.md @@ -1,13 +1,14 @@ -# No-op Exporter - +# No-op Exporter | Status | | | ------------- |-----------| -| Stability | [beta]: traces, metrics, logs | +| Stability | [development]: profiles | +| | [beta]: traces, metrics, logs | | Distributions | [core], [contrib], [k8s] | | Issues | [![Open issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector?query=is%3Aissue%20is%3Aopen%20label%3Aexporter%2Fnop%20&label=open&color=orange&logo=opentelemetry)](https://github.com/open-telemetry/opentelemetry-collector/issues?q=is%3Aopen+is%3Aissue+label%3Aexporter%2Fnop) [![Closed issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector?query=is%3Aissue%20is%3Aclosed%20label%3Aexporter%2Fnop%20&label=closed&color=blue&logo=opentelemetry)](https://github.com/open-telemetry/opentelemetry-collector/issues?q=is%3Aclosed+is%3Aissue+label%3Aexporter%2Fnop) | | [Code Owners](https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/main/CONTRIBUTING.md#becoming-a-code-owner) | [@evan-bradley](https://www.github.com/evan-bradley) | +[development]: https://github.com/open-telemetry/opentelemetry-collector/blob/main/docs/component-stability.md#development [beta]: https://github.com/open-telemetry/opentelemetry-collector/blob/main/docs/component-stability.md#beta [core]: https://github.com/open-telemetry/opentelemetry-collector-releases/tree/main/distributions/otelcol [contrib]: https://github.com/open-telemetry/opentelemetry-collector-releases/tree/main/distributions/otelcol-contrib @@ -25,5 +26,5 @@ exporter definitions. It takes no configuration. ```yaml exporters: - nop: + nop: {} # Explicitly set in case the config is re-serialized (e.g. with the Operator) ``` diff --git a/exporter/nopexporter/go.mod b/exporter/nopexporter/go.mod index 2be542e82f7a..5090660ba9d4 100644 --- a/exporter/nopexporter/go.mod +++ b/exporter/nopexporter/go.mod @@ -1,16 +1,18 @@ module go.opentelemetry.io/collector/exporter/nopexporter -go 1.24.0 +go 1.25.0 require ( github.com/stretchr/testify v1.11.1 - go.opentelemetry.io/collector/component v1.46.0 - go.opentelemetry.io/collector/component/componenttest v0.140.0 - go.opentelemetry.io/collector/confmap v1.46.0 - go.opentelemetry.io/collector/consumer/consumertest v0.140.0 - go.opentelemetry.io/collector/exporter v1.46.0 - go.opentelemetry.io/collector/exporter/exportertest v0.140.0 - go.opentelemetry.io/collector/pdata v1.46.0 + go.opentelemetry.io/collector/component v1.54.0 + go.opentelemetry.io/collector/component/componenttest v0.148.0 + go.opentelemetry.io/collector/confmap v1.54.0 + go.opentelemetry.io/collector/consumer/consumertest v0.148.0 + go.opentelemetry.io/collector/exporter v1.54.0 + go.opentelemetry.io/collector/exporter/exportertest v0.148.0 + go.opentelemetry.io/collector/exporter/xexporter v0.148.0 + go.opentelemetry.io/collector/pdata v1.54.0 + go.opentelemetry.io/collector/pdata/pprofile v0.148.0 go.uber.org/goleak v1.3.0 ) @@ -19,42 +21,41 @@ require ( github.com/davecgh/go-spew v1.1.1 // indirect github.com/go-logr/logr v1.4.3 // indirect github.com/go-logr/stdr v1.2.2 // indirect - github.com/go-viper/mapstructure/v2 v2.4.0 // indirect + github.com/go-viper/mapstructure/v2 v2.5.0 // indirect github.com/gobwas/glob v0.2.3 // indirect github.com/google/uuid v1.6.0 // indirect - github.com/hashicorp/go-version v1.7.0 // indirect + github.com/hashicorp/go-version v1.8.0 // indirect github.com/json-iterator/go v1.1.12 // indirect github.com/knadh/koanf/maps v0.1.2 // indirect github.com/knadh/koanf/providers/confmap v1.0.0 // indirect - github.com/knadh/koanf/v2 v2.3.0 // indirect + github.com/knadh/koanf/v2 v2.3.3 // indirect github.com/mitchellh/copystructure v1.2.0 // indirect github.com/mitchellh/reflectwalk v1.0.2 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee // indirect github.com/pmezard/go-difflib v1.0.0 // indirect go.opentelemetry.io/auto/sdk v1.2.1 // indirect - go.opentelemetry.io/collector/consumer v1.46.0 // indirect - go.opentelemetry.io/collector/consumer/consumererror v0.140.0 // indirect - go.opentelemetry.io/collector/consumer/xconsumer v0.140.0 // indirect - go.opentelemetry.io/collector/exporter/xexporter v0.140.0 // indirect - go.opentelemetry.io/collector/featuregate v1.46.0 // indirect - go.opentelemetry.io/collector/pdata/pprofile v0.140.0 // indirect - go.opentelemetry.io/collector/pipeline v1.46.0 // indirect - go.opentelemetry.io/collector/receiver v1.46.0 // indirect - go.opentelemetry.io/collector/receiver/receivertest v0.140.0 // indirect - go.opentelemetry.io/collector/receiver/xreceiver v0.140.0 // indirect - go.opentelemetry.io/otel v1.40.0 // indirect - go.opentelemetry.io/otel/metric v1.40.0 // indirect + go.opentelemetry.io/collector/consumer v1.54.0 // indirect + go.opentelemetry.io/collector/consumer/consumererror v0.148.0 // indirect + go.opentelemetry.io/collector/consumer/xconsumer v0.148.0 // indirect + go.opentelemetry.io/collector/featuregate v1.54.0 // indirect + go.opentelemetry.io/collector/internal/componentalias v0.148.0 // indirect + go.opentelemetry.io/collector/pipeline v1.54.0 // indirect + go.opentelemetry.io/collector/receiver v1.54.0 // indirect + go.opentelemetry.io/collector/receiver/receivertest v0.148.0 // indirect + go.opentelemetry.io/collector/receiver/xreceiver v0.148.0 // indirect + go.opentelemetry.io/otel v1.42.0 // indirect + go.opentelemetry.io/otel/metric v1.42.0 // indirect go.opentelemetry.io/otel/sdk v1.40.0 // indirect go.opentelemetry.io/otel/sdk/metric v1.40.0 // indirect - go.opentelemetry.io/otel/trace v1.40.0 // indirect + go.opentelemetry.io/otel/trace v1.42.0 // indirect go.uber.org/multierr v1.11.0 // indirect go.uber.org/zap v1.27.1 // indirect go.yaml.in/yaml/v3 v3.0.4 // indirect - golang.org/x/sys v0.40.0 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20251022142026-3a174f9686a8 // indirect - google.golang.org/grpc v1.77.0 // indirect - google.golang.org/protobuf v1.36.10 // indirect + golang.org/x/sys v0.41.0 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20251222181119-0a764e51fe1b // indirect + google.golang.org/grpc v1.79.3 // indirect + google.golang.org/protobuf v1.36.11 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) @@ -113,3 +114,7 @@ replace go.opentelemetry.io/collector/confmap/xconfmap => ../../confmap/xconfmap replace go.opentelemetry.io/collector/exporter/exporterhelper => ../exporterhelper replace go.opentelemetry.io/collector/internal/testutil => ../../internal/testutil + +replace go.opentelemetry.io/collector/internal/componentalias => ../../internal/componentalias + +replace go.opentelemetry.io/collector/pipeline/xpipeline => ../../pipeline/xpipeline diff --git a/exporter/nopexporter/go.sum b/exporter/nopexporter/go.sum index d3c35ba1cbd6..d6e38a64eac0 100644 --- a/exporter/nopexporter/go.sum +++ b/exporter/nopexporter/go.sum @@ -10,8 +10,8 @@ github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI= github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= -github.com/go-viper/mapstructure/v2 v2.4.0 h1:EBsztssimR/CONLSZZ04E8qAkxNYq4Qp9LvH92wZUgs= -github.com/go-viper/mapstructure/v2 v2.4.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM= +github.com/go-viper/mapstructure/v2 v2.5.0 h1:vM5IJoUAy3d7zRSVtIwQgBj7BiWtMPfmPEgAXnvj1Ro= +github.com/go-viper/mapstructure/v2 v2.5.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM= github.com/gobwas/glob v0.2.3 h1:A4xDbljILXROh+kObIiy5kIaPYD8e96x1tgBhUI5J+Y= github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8= github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= @@ -21,16 +21,18 @@ github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/hashicorp/go-version v1.7.0 h1:5tqGy27NaOTB8yJKUZELlFAS/LTKJkrmONwQKeRZfjY= -github.com/hashicorp/go-version v1.7.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= +github.com/hashicorp/go-version v1.8.0 h1:KAkNb1HAiZd1ukkxDFGmokVZe1Xy9HG6NUp+bPle2i4= +github.com/hashicorp/go-version v1.8.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= +github.com/hashicorp/golang-lru/v2 v2.0.7 h1:a+bsQ5rvGLjzHuww6tVxozPZFVghXaHOwFs4luLUK2k= +github.com/hashicorp/golang-lru/v2 v2.0.7/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyfM2/ZepoAG6RGpeM= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= github.com/knadh/koanf/maps v0.1.2 h1:RBfmAW5CnZT+PJ1CVc1QSJKf4Xu9kxfQgYVQSu8hpbo= github.com/knadh/koanf/maps v0.1.2/go.mod h1:npD/QZY3V6ghQDdcQzl1W4ICNVTkohC8E73eI2xW4yI= github.com/knadh/koanf/providers/confmap v1.0.0 h1:mHKLJTE7iXEys6deO5p6olAiZdG5zwp8Aebir+/EaRE= github.com/knadh/koanf/providers/confmap v1.0.0/go.mod h1:txHYHiI2hAtF0/0sCmcuol4IDcuQbKTybiB1nOcUo1A= -github.com/knadh/koanf/v2 v2.3.0 h1:Qg076dDRFHvqnKG97ZEsi9TAg2/nFTa9hCdcSa1lvlM= -github.com/knadh/koanf/v2 v2.3.0/go.mod h1:gRb40VRAbd4iJMYYD5IxZ6hfuopFcXBpc9bbQpZwo28= +github.com/knadh/koanf/v2 v2.3.3 h1:jLJC8XCRfLC7n4F+ZKKdBsbq1bfXTpuFhf4L7t94D94= +github.com/knadh/koanf/v2 v2.3.3/go.mod h1:gRb40VRAbd4iJMYYD5IxZ6hfuopFcXBpc9bbQpZwo28= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= @@ -55,22 +57,22 @@ github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64= go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y= -go.opentelemetry.io/otel v1.40.0 h1:oA5YeOcpRTXq6NN7frwmwFR0Cn3RhTVZvXsP4duvCms= -go.opentelemetry.io/otel v1.40.0/go.mod h1:IMb+uXZUKkMXdPddhwAHm6UfOwJyh4ct1ybIlV14J0g= -go.opentelemetry.io/otel/metric v1.40.0 h1:rcZe317KPftE2rstWIBitCdVp89A2HqjkxR3c11+p9g= -go.opentelemetry.io/otel/metric v1.40.0/go.mod h1:ib/crwQH7N3r5kfiBZQbwrTge743UDc7DTFVZrrXnqc= +go.opentelemetry.io/otel v1.42.0 h1:lSQGzTgVR3+sgJDAU/7/ZMjN9Z+vUip7leaqBKy4sho= +go.opentelemetry.io/otel v1.42.0/go.mod h1:lJNsdRMxCUIWuMlVJWzecSMuNjE7dOYyWlqOXWkdqCc= +go.opentelemetry.io/otel/metric v1.42.0 h1:2jXG+3oZLNXEPfNmnpxKDeZsFI5o4J+nz6xUlaFdF/4= +go.opentelemetry.io/otel/metric v1.42.0/go.mod h1:RlUN/7vTU7Ao/diDkEpQpnz3/92J9ko05BIwxYa2SSI= go.opentelemetry.io/otel/sdk v1.40.0 h1:KHW/jUzgo6wsPh9At46+h4upjtccTmuZCFAc9OJ71f8= go.opentelemetry.io/otel/sdk v1.40.0/go.mod h1:Ph7EFdYvxq72Y8Li9q8KebuYUr2KoeyHx0DRMKrYBUE= go.opentelemetry.io/otel/sdk/metric v1.40.0 h1:mtmdVqgQkeRxHgRv4qhyJduP3fYJRMX4AtAlbuWdCYw= go.opentelemetry.io/otel/sdk/metric v1.40.0/go.mod h1:4Z2bGMf0KSK3uRjlczMOeMhKU2rhUqdWNoKcYrtcBPg= -go.opentelemetry.io/otel/trace v1.40.0 h1:WA4etStDttCSYuhwvEa8OP8I5EWu24lkOzp+ZYblVjw= -go.opentelemetry.io/otel/trace v1.40.0/go.mod h1:zeAhriXecNGP/s2SEG3+Y8X9ujcJOTqQ5RgdEJcawiA= -go.opentelemetry.io/proto/slim/otlp v1.9.0 h1:fPVMv8tP3TrsqlkH1HWYUpbCY9cAIemx184VGkS6vlE= -go.opentelemetry.io/proto/slim/otlp v1.9.0/go.mod h1:xXdeJJ90Gqyll+orzUkY4bOd2HECo5JofeoLpymVqdI= -go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.2.0 h1:o13nadWDNkH/quoDomDUClnQBpdQQ2Qqv0lQBjIXjE8= -go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.2.0/go.mod h1:Gyb6Xe7FTi/6xBHwMmngGoHqL0w29Y4eW8TGFzpefGA= -go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.2.0 h1:EiUYvtwu6PMrMHVjcPfnsG3v+ajPkbUeH+IL93+QYyk= -go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.2.0/go.mod h1:mUUHKFiN2SST3AhJ8XhJxEoeVW12oqfXog0Bo8W3Ec4= +go.opentelemetry.io/otel/trace v1.42.0 h1:OUCgIPt+mzOnaUTpOQcBiM/PLQ/Op7oq6g4LenLmOYY= +go.opentelemetry.io/otel/trace v1.42.0/go.mod h1:f3K9S+IFqnumBkKhRJMeaZeNk9epyhnCmQh/EysQCdc= +go.opentelemetry.io/proto/slim/otlp v1.10.0 h1:iR97Vs/ZDR+y9TfuP9b1XBtdPWeC+OMslIBmhcLU7jM= +go.opentelemetry.io/proto/slim/otlp v1.10.0/go.mod h1:lV9250stpjYLPNA5viFabIgP2QlUGRT1GdTgAf8SIUk= +go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.3.0 h1:RUF5rO0hAlgiJt1fzQVzcVs3vZVNHIcMLgOgG4rWNcQ= +go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.3.0/go.mod h1:I89cynRj8y+383o7tEQVg2SVA6SRgDVIouWPUVXjx0U= +go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.3.0 h1:CQvJSldHRUN6Z8jsUeYv8J0lXRvygALXIzsmAeCcZE0= +go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.3.0/go.mod h1:xSQ+mEfJe/GjK1LXEyVOoSI1N9JV9ZI923X5kup43W4= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= @@ -79,18 +81,18 @@ go.uber.org/zap v1.27.1 h1:08RqriUEv8+ArZRYSTXy1LeBScaMpVSTBhCeaZYfMYc= go.uber.org/zap v1.27.1/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc= go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg= -golang.org/x/net v0.46.1-0.20251013234738-63d1a5100f82 h1:6/3JGEh1C88g7m+qzzTbl3A0FtsLguXieqofVLU/JAo= -golang.org/x/net v0.46.1-0.20251013234738-63d1a5100f82/go.mod h1:Q9BGdFy1y4nkUwiLvT5qtyhAnEHgnQ/zd8PfU6nc210= -golang.org/x/sys v0.40.0 h1:DBZZqJ2Rkml6QMQsZywtnjnnGvHza6BTfYFWY9kjEWQ= -golang.org/x/sys v0.40.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= -golang.org/x/text v0.30.0 h1:yznKA/E9zq54KzlzBEAWn1NXSQ8DIp/NYMy88xJjl4k= -golang.org/x/text v0.30.0/go.mod h1:yDdHFIX9t+tORqspjENWgzaCVXgk0yYnYuSZ8UzzBVM= -google.golang.org/genproto/googleapis/rpc v0.0.0-20251022142026-3a174f9686a8 h1:M1rk8KBnUsBDg1oPGHNCxG4vc1f49epmTO7xscSajMk= -google.golang.org/genproto/googleapis/rpc v0.0.0-20251022142026-3a174f9686a8/go.mod h1:7i2o+ce6H/6BluujYR+kqX3GKH+dChPTQU19wjRPiGk= -google.golang.org/grpc v1.77.0 h1:wVVY6/8cGA6vvffn+wWK5ToddbgdU3d8MNENr4evgXM= -google.golang.org/grpc v1.77.0/go.mod h1:z0BY1iVj0q8E1uSQCjL9cppRj+gnZjzDnzV0dHhrNig= -google.golang.org/protobuf v1.36.10 h1:AYd7cD/uASjIL6Q9LiTjz8JLcrh/88q5UObnmY3aOOE= -google.golang.org/protobuf v1.36.10/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= +golang.org/x/net v0.51.0 h1:94R/GTO7mt3/4wIKpcR5gkGmRLOuE/2hNGeWq/GBIFo= +golang.org/x/net v0.51.0/go.mod h1:aamm+2QF5ogm02fjy5Bb7CQ0WMt1/WVM7FtyaTLlA9Y= +golang.org/x/sys v0.41.0 h1:Ivj+2Cp/ylzLiEU89QhWblYnOE9zerudt9Ftecq2C6k= +golang.org/x/sys v0.41.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= +golang.org/x/text v0.34.0 h1:oL/Qq0Kdaqxa1KbNeMKwQq0reLCCaFtqu2eNuSeNHbk= +golang.org/x/text v0.34.0/go.mod h1:homfLqTYRFyVYemLBFl5GgL/DWEiH5wcsQ5gSh1yziA= +google.golang.org/genproto/googleapis/rpc v0.0.0-20251222181119-0a764e51fe1b h1:Mv8VFug0MP9e5vUxfBcE3vUkV6CImK3cMNMIDFjmzxU= +google.golang.org/genproto/googleapis/rpc v0.0.0-20251222181119-0a764e51fe1b/go.mod h1:j9x/tPzZkyxcgEFkiKEEGxfvyumM01BEtsW8xzOahRQ= +google.golang.org/grpc v1.79.3 h1:sybAEdRIEtvcD68Gx7dmnwjZKlyfuc61Dyo9pGXXkKE= +google.golang.org/grpc v1.79.3/go.mod h1:KmT0Kjez+0dde/v2j9vzwoAScgEPx/Bw1CYChhHLrHQ= +google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE= +google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= diff --git a/exporter/nopexporter/internal/metadata/generated_status.go b/exporter/nopexporter/internal/metadata/generated_status.go index d7336115c61d..9d6e4c91af7b 100644 --- a/exporter/nopexporter/internal/metadata/generated_status.go +++ b/exporter/nopexporter/internal/metadata/generated_status.go @@ -12,7 +12,8 @@ var ( ) const ( - TracesStability = component.StabilityLevelBeta - MetricsStability = component.StabilityLevelBeta - LogsStability = component.StabilityLevelBeta + ProfilesStability = component.StabilityLevelDevelopment + TracesStability = component.StabilityLevelBeta + MetricsStability = component.StabilityLevelBeta + LogsStability = component.StabilityLevelBeta ) diff --git a/exporter/nopexporter/metadata.yaml b/exporter/nopexporter/metadata.yaml index 8194c2ad2e4c..be35a7d4a08a 100644 --- a/exporter/nopexporter/metadata.yaml +++ b/exporter/nopexporter/metadata.yaml @@ -1,3 +1,4 @@ +display_name: No-op Exporter type: nop github_project: open-telemetry/opentelemetry-collector @@ -9,4 +10,5 @@ status: class: exporter stability: beta: [traces, metrics, logs] + development: [profiles] distributions: [core, contrib, k8s] diff --git a/exporter/nopexporter/nop_exporter.go b/exporter/nopexporter/nop_exporter.go index 423dedb0c5da..93b620638a4c 100644 --- a/exporter/nopexporter/nop_exporter.go +++ b/exporter/nopexporter/nop_exporter.go @@ -10,16 +10,18 @@ import ( "go.opentelemetry.io/collector/consumer/consumertest" "go.opentelemetry.io/collector/exporter" "go.opentelemetry.io/collector/exporter/nopexporter/internal/metadata" + "go.opentelemetry.io/collector/exporter/xexporter" ) // NewFactory returns an exporter.Factory that constructs nop exporters. func NewFactory() exporter.Factory { - return exporter.NewFactory( + return xexporter.NewFactory( metadata.Type, func() component.Config { return &struct{}{} }, - exporter.WithTraces(createTraces, metadata.TracesStability), - exporter.WithMetrics(createMetrics, metadata.MetricsStability), - exporter.WithLogs(createLogs, metadata.LogsStability), + xexporter.WithTraces(createTraces, metadata.TracesStability), + xexporter.WithMetrics(createMetrics, metadata.MetricsStability), + xexporter.WithLogs(createLogs, metadata.LogsStability), + xexporter.WithProfiles(createProfiles, metadata.ProfilesStability), ) } @@ -35,6 +37,10 @@ func createLogs(context.Context, exporter.Settings, component.Config) (exporter. return nopInstance, nil } +func createProfiles(context.Context, exporter.Settings, component.Config) (xexporter.Profiles, error) { + return nopInstance, nil +} + var nopInstance = &nop{ Consumer: consumertest.NewNop(), } diff --git a/exporter/nopexporter/nop_exporter_test.go b/exporter/nopexporter/nop_exporter_test.go index 22e1c7ce59ec..1eee6baaf6cc 100644 --- a/exporter/nopexporter/nop_exporter_test.go +++ b/exporter/nopexporter/nop_exporter_test.go @@ -13,8 +13,10 @@ import ( "go.opentelemetry.io/collector/component" "go.opentelemetry.io/collector/component/componenttest" "go.opentelemetry.io/collector/exporter/exportertest" + "go.opentelemetry.io/collector/exporter/xexporter" "go.opentelemetry.io/collector/pdata/plog" "go.opentelemetry.io/collector/pdata/pmetric" + "go.opentelemetry.io/collector/pdata/pprofile" "go.opentelemetry.io/collector/pdata/ptrace" ) @@ -42,4 +44,10 @@ func TestNewNopFactory(t *testing.T) { assert.NoError(t, logs.Start(context.Background(), componenttest.NewNopHost())) assert.NoError(t, logs.ConsumeLogs(context.Background(), plog.NewLogs())) assert.NoError(t, logs.Shutdown(context.Background())) + + profiles, err := factory.(xexporter.Factory).CreateProfiles(context.Background(), exportertest.NewNopSettings(factory.Type()), cfg) + require.NoError(t, err) + assert.NoError(t, profiles.Start(context.Background(), componenttest.NewNopHost())) + assert.NoError(t, profiles.ConsumeProfiles(context.Background(), pprofile.NewProfiles())) + assert.NoError(t, profiles.Shutdown(context.Background())) } diff --git a/exporter/otlpexporter/README.md b/exporter/otlpexporter/README.md index 8c4f09a247ec..8b75b98eedf1 100644 --- a/exporter/otlpexporter/README.md +++ b/exporter/otlpexporter/README.md @@ -1,6 +1,5 @@ -# OTLP gRPC Exporter - +# OTLP gRPC Exporter | Status | | | ------------- |-----------| | Stability | [development]: profiles | @@ -37,7 +36,7 @@ Example: ```yaml exporters: - otlp: + otlp_grpc: endpoint: otelcol2:4317 tls: cert_file: file.cert @@ -52,7 +51,7 @@ By default, `gzip` compression is enabled. See [compression comparison](../../co ```yaml exporters: - otlp: + otlp_grpc: ... compression: none ``` diff --git a/exporter/otlpexporter/config.go b/exporter/otlpexporter/config.go index 7bcd17c0235c..d2c3b610f7c5 100644 --- a/exporter/otlpexporter/config.go +++ b/exporter/otlpexporter/config.go @@ -5,51 +5,37 @@ package otlpexporter // import "go.opentelemetry.io/collector/exporter/otlpexpor import ( "errors" - "fmt" - "net" "regexp" - "strconv" "strings" "go.opentelemetry.io/collector/component" "go.opentelemetry.io/collector/config/configgrpc" + "go.opentelemetry.io/collector/config/configoptional" "go.opentelemetry.io/collector/config/configretry" + "go.opentelemetry.io/collector/confmap/xconfmap" "go.opentelemetry.io/collector/exporter/exporterhelper" ) // Config defines configuration for OTLP exporter. type Config struct { - TimeoutConfig exporterhelper.TimeoutConfig `mapstructure:",squash"` // squash ensures fields are correctly decoded in embedded struct. - QueueConfig exporterhelper.QueueBatchConfig `mapstructure:"sending_queue"` - RetryConfig configretry.BackOffConfig `mapstructure:"retry_on_failure"` - ClientConfig configgrpc.ClientConfig `mapstructure:",squash"` // squash ensures fields are correctly decoded in embedded struct. + TimeoutConfig exporterhelper.TimeoutConfig `mapstructure:",squash"` // squash ensures fields are correctly decoded in embedded struct. + QueueConfig configoptional.Optional[exporterhelper.QueueBatchConfig] `mapstructure:"sending_queue"` + RetryConfig configretry.BackOffConfig `mapstructure:"retry_on_failure"` + ClientConfig configgrpc.ClientConfig `mapstructure:",squash"` // squash ensures fields are correctly decoded in embedded struct. // prevent unkeyed literal initialization _ struct{} } -func (c *Config) Validate() error { - if after, ok := strings.CutPrefix(c.ClientConfig.Endpoint, "unix://"); ok { - if after == "" { - return errors.New("unix socket path cannot be empty") - } - return nil - } +var ( + _ component.Config = (*Config)(nil) + _ xconfmap.Validator = (*Config)(nil) +) - endpoint := c.sanitizedEndpoint() - if endpoint == "" { +func (c *Config) Validate() error { + if endpoint := c.sanitizedEndpoint(); endpoint == "" { return errors.New(`requires a non-empty "endpoint"`) } - - // Validate that the port is in the address - _, port, err := net.SplitHostPort(endpoint) - if err != nil { - return err - } - if _, err := strconv.Atoi(port); err != nil { - return fmt.Errorf(`invalid port "%s"`, port) - } - return nil } @@ -66,5 +52,3 @@ func (c *Config) sanitizedEndpoint() string { return c.ClientConfig.Endpoint } } - -var _ component.Config = (*Config)(nil) diff --git a/exporter/otlpexporter/config.yaml b/exporter/otlpexporter/config.yaml new file mode 100644 index 000000000000..4009acb16550 --- /dev/null +++ b/exporter/otlpexporter/config.yaml @@ -0,0 +1,11 @@ +description: Config defines configuration for OTLP exporter. +type: object +properties: + retry_on_failure: + $ref: go.opentelemetry.io/collector/config/configretry.back_off_config + sending_queue: + x-optional: true + $ref: go.opentelemetry.io/collector/exporter/exporterhelper.queue_batch_config +allOf: + - $ref: go.opentelemetry.io/collector/exporter/exporterhelper.timeout_config + - $ref: go.opentelemetry.io/collector/config/configgrpc.client_config diff --git a/exporter/otlpexporter/config_test.go b/exporter/otlpexporter/config_test.go index c87e0d9de37c..6561ab280466 100644 --- a/exporter/otlpexporter/config_test.go +++ b/exporter/otlpexporter/config_test.go @@ -51,8 +51,7 @@ func TestUnmarshalConfig(t *testing.T) { MaxInterval: 1 * time.Minute, MaxElapsedTime: 10 * time.Minute, }, - QueueConfig: exporterhelper.QueueBatchConfig{ - Enabled: true, + QueueConfig: configoptional.Some(exporterhelper.QueueBatchConfig{ Sizer: exporterhelper.RequestSizerTypeItems, NumConsumers: 2, QueueSize: 100000, @@ -62,7 +61,7 @@ func TestUnmarshalConfig(t *testing.T) { MinSize: 1000, MaxSize: 10000, }), - }, + }), ClientConfig: configgrpc.ClientConfig{ Headers: configopaque.MapList{ {Name: "another", Value: "somevalue"}, @@ -102,8 +101,7 @@ func TestUnmarshalDefaultBatchConfig(t *testing.T) { Timeout: 10 * time.Second, }, RetryConfig: configretry.NewDefaultBackOffConfig(), - QueueConfig: exporterhelper.QueueBatchConfig{ - Enabled: true, + QueueConfig: configoptional.Some(exporterhelper.QueueBatchConfig{ Sizer: exporterhelper.RequestSizerTypeRequests, QueueSize: 1000, NumConsumers: 10, @@ -112,9 +110,10 @@ func TestUnmarshalDefaultBatchConfig(t *testing.T) { Sizer: exporterhelper.RequestSizerTypeItems, MinSize: 8192, }), - }, + }), ClientConfig: configgrpc.ClientConfig{ Endpoint: "1.2.3.4:1234", + BalancerName: "round_robin", Compression: "gzip", WriteBufferSize: 512 * 1024, }, @@ -180,23 +179,12 @@ func TestValidDNSEndpoint(t *testing.T) { factory := NewFactory() cfg := factory.CreateDefaultConfig().(*Config) cfg.ClientConfig.Endpoint = "dns://authority/backend.example.com:4317" - assert.NoError(t, cfg.Validate()) + assert.NoError(t, xconfmap.Validate(cfg)) } func TestValidUnixSocketEndpoint(t *testing.T) { factory := NewFactory() cfg := factory.CreateDefaultConfig().(*Config) cfg.ClientConfig.Endpoint = "unix:///my/unix/socket.sock" - assert.NoError(t, cfg.Validate()) -} - -func TestSanitizeEndpoint(t *testing.T) { - factory := NewFactory() - cfg := factory.CreateDefaultConfig().(*Config) - cfg.ClientConfig.Endpoint = "dns://authority/backend.example.com:4317" - assert.Equal(t, "authority/backend.example.com:4317", cfg.sanitizedEndpoint()) - cfg.ClientConfig.Endpoint = "dns:///backend.example.com:4317" - assert.Equal(t, "backend.example.com:4317", cfg.sanitizedEndpoint()) - cfg.ClientConfig.Endpoint = "dns:////backend.example.com:4317" - assert.Equal(t, "/backend.example.com:4317", cfg.sanitizedEndpoint()) + assert.NoError(t, xconfmap.Validate(cfg)) } diff --git a/exporter/otlpexporter/factory.go b/exporter/otlpexporter/factory.go index 3d5cc8512144..2f3f9c45ad57 100644 --- a/exporter/otlpexporter/factory.go +++ b/exporter/otlpexporter/factory.go @@ -24,6 +24,7 @@ func NewFactory() exporter.Factory { return xexporter.NewFactory( metadata.Type, createDefaultConfig, + xexporter.WithDeprecatedTypeAlias(metadata.DeprecatedType), xexporter.WithTraces(createTraces, metadata.TracesStability), xexporter.WithMetrics(createMetrics, metadata.MetricsStability), xexporter.WithLogs(createLogs, metadata.LogsStability), @@ -39,12 +40,11 @@ func createDefaultConfig() component.Config { clientCfg.WriteBufferSize = 512 * 1024 // For backward compatibility: clientCfg.Keepalive = configoptional.None[configgrpc.KeepaliveClientConfig]() - clientCfg.BalancerName = "" return &Config{ TimeoutConfig: exporterhelper.NewDefaultTimeoutConfig(), RetryConfig: configretry.NewDefaultBackOffConfig(), - QueueConfig: exporterhelper.NewDefaultQueueConfig(), + QueueConfig: configoptional.Some(exporterhelper.NewDefaultQueueConfig()), ClientConfig: clientCfg, } } diff --git a/exporter/otlpexporter/factory_test.go b/exporter/otlpexporter/factory_test.go index 0a8e82d22fd9..1fcc61a14412 100644 --- a/exporter/otlpexporter/factory_test.go +++ b/exporter/otlpexporter/factory_test.go @@ -33,9 +33,10 @@ func TestCreateDefaultConfig(t *testing.T) { ocfg, ok := factory.CreateDefaultConfig().(*Config) assert.True(t, ok) assert.Equal(t, configretry.NewDefaultBackOffConfig(), ocfg.RetryConfig) - assert.Equal(t, exporterhelper.NewDefaultQueueConfig(), ocfg.QueueConfig) + assert.Equal(t, configoptional.Some(exporterhelper.NewDefaultQueueConfig()), ocfg.QueueConfig) assert.Equal(t, exporterhelper.NewDefaultTimeoutConfig(), ocfg.TimeoutConfig) assert.Equal(t, configcompression.TypeGzip, ocfg.ClientConfig.Compression) + assert.Equal(t, configgrpc.BalancerName(), ocfg.ClientConfig.BalancerName) } func TestCreateMetrics(t *testing.T) { diff --git a/exporter/otlpexporter/generated_component_test.go b/exporter/otlpexporter/generated_component_test.go index 56db8c1503ae..af130da013c0 100644 --- a/exporter/otlpexporter/generated_component_test.go +++ b/exporter/otlpexporter/generated_component_test.go @@ -20,7 +20,7 @@ import ( "go.opentelemetry.io/collector/pdata/ptrace" ) -var typ = component.MustNewType("otlp") +var typ = component.MustNewType("otlp_grpc") func TestComponentFactoryType(t *testing.T) { require.Equal(t, typ, NewFactory().Type()) diff --git a/exporter/otlpexporter/go.mod b/exporter/otlpexporter/go.mod index 77d601865973..c418f994aa19 100644 --- a/exporter/otlpexporter/go.mod +++ b/exporter/otlpexporter/go.mod @@ -1,58 +1,59 @@ module go.opentelemetry.io/collector/exporter/otlpexporter -go 1.24.0 +go 1.25.0 require ( github.com/stretchr/testify v1.11.1 - go.opentelemetry.io/collector v0.140.0 - go.opentelemetry.io/collector/component v1.46.0 - go.opentelemetry.io/collector/component/componenttest v0.140.0 - go.opentelemetry.io/collector/config/configauth v1.46.0 - go.opentelemetry.io/collector/config/configcompression v1.46.0 - go.opentelemetry.io/collector/config/configgrpc v0.140.0 - go.opentelemetry.io/collector/config/configopaque v1.46.0 - go.opentelemetry.io/collector/config/configoptional v1.46.0 - go.opentelemetry.io/collector/config/configretry v1.46.0 - go.opentelemetry.io/collector/config/configtls v1.46.0 - go.opentelemetry.io/collector/confmap v1.46.0 - go.opentelemetry.io/collector/confmap/xconfmap v0.140.0 - go.opentelemetry.io/collector/consumer v1.46.0 - go.opentelemetry.io/collector/consumer/consumererror v0.140.0 - go.opentelemetry.io/collector/exporter v1.46.0 - go.opentelemetry.io/collector/exporter/exporterhelper v0.140.0 - go.opentelemetry.io/collector/exporter/exporterhelper/xexporterhelper v0.140.0 - go.opentelemetry.io/collector/exporter/exportertest v0.140.0 - go.opentelemetry.io/collector/exporter/xexporter v0.140.0 - go.opentelemetry.io/collector/internal/testutil v0.140.0 - go.opentelemetry.io/collector/pdata v1.46.0 - go.opentelemetry.io/collector/pdata/pprofile v0.140.0 - go.opentelemetry.io/collector/pdata/testdata v0.140.0 + go.opentelemetry.io/collector v0.148.0 + go.opentelemetry.io/collector/component v1.54.0 + go.opentelemetry.io/collector/component/componenttest v0.148.0 + go.opentelemetry.io/collector/config/configauth v1.54.0 + go.opentelemetry.io/collector/config/configcompression v1.54.0 + go.opentelemetry.io/collector/config/configgrpc v0.148.0 + go.opentelemetry.io/collector/config/configopaque v1.54.0 + go.opentelemetry.io/collector/config/configoptional v1.54.0 + go.opentelemetry.io/collector/config/configretry v1.54.0 + go.opentelemetry.io/collector/config/configtls v1.54.0 + go.opentelemetry.io/collector/confmap v1.54.0 + go.opentelemetry.io/collector/confmap/xconfmap v0.148.0 + go.opentelemetry.io/collector/consumer v1.54.0 + go.opentelemetry.io/collector/consumer/consumererror v0.148.0 + go.opentelemetry.io/collector/exporter v1.54.0 + go.opentelemetry.io/collector/exporter/exporterhelper v0.148.0 + go.opentelemetry.io/collector/exporter/exporterhelper/xexporterhelper v0.148.0 + go.opentelemetry.io/collector/exporter/exportertest v0.148.0 + go.opentelemetry.io/collector/exporter/xexporter v0.148.0 + go.opentelemetry.io/collector/internal/testutil v0.148.0 + go.opentelemetry.io/collector/pdata v1.54.0 + go.opentelemetry.io/collector/pdata/pprofile v0.148.0 + go.opentelemetry.io/collector/pdata/testdata v0.148.0 go.uber.org/goleak v1.3.0 go.uber.org/zap v1.27.1 - google.golang.org/genproto/googleapis/rpc v0.0.0-20251022142026-3a174f9686a8 - google.golang.org/grpc v1.77.0 - google.golang.org/protobuf v1.36.10 + google.golang.org/genproto/googleapis/rpc v0.0.0-20260226221140-a57be14db171 + google.golang.org/grpc v1.79.3 + google.golang.org/protobuf v1.36.11 ) require ( github.com/cenkalti/backoff/v5 v5.0.3 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/davecgh/go-spew v1.1.1 // indirect - github.com/foxboron/go-tpm-keyfiles v0.0.0-20250903184740-5d135037bd4d // indirect + github.com/foxboron/go-tpm-keyfiles v0.0.0-20251226215517-609e4778396f // indirect github.com/fsnotify/fsnotify v1.9.0 // indirect github.com/go-logr/logr v1.4.3 // indirect github.com/go-logr/stdr v1.2.2 // indirect - github.com/go-viper/mapstructure/v2 v2.4.0 // indirect + github.com/go-viper/mapstructure/v2 v2.5.0 // indirect github.com/gobwas/glob v0.2.3 // indirect github.com/golang/snappy v0.0.4 // indirect - github.com/google/go-tpm v0.9.7 // indirect + github.com/google/go-tpm v0.9.8 // indirect github.com/google/uuid v1.6.0 // indirect - github.com/hashicorp/go-version v1.7.0 // indirect + github.com/hashicorp/go-version v1.8.0 // indirect + github.com/hashicorp/golang-lru/v2 v2.0.7 // indirect github.com/json-iterator/go v1.1.12 // indirect github.com/klauspost/compress v1.17.11 // indirect github.com/knadh/koanf/maps v0.1.2 // indirect github.com/knadh/koanf/providers/confmap v1.0.0 // indirect - github.com/knadh/koanf/v2 v2.3.0 // indirect + github.com/knadh/koanf/v2 v2.3.3 // indirect github.com/mitchellh/copystructure v1.2.0 // indirect github.com/mitchellh/reflectwalk v1.0.2 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect @@ -64,31 +65,32 @@ require ( go.opentelemetry.io/collector/config/configmiddleware v1.46.0 // indirect go.opentelemetry.io/collector/config/confignet v1.46.0 // indirect go.opentelemetry.io/collector/consumer/consumererror/xconsumererror v0.140.0 // indirect - go.opentelemetry.io/collector/consumer/consumertest v0.140.0 // indirect - go.opentelemetry.io/collector/consumer/xconsumer v0.140.0 // indirect - go.opentelemetry.io/collector/extension v1.46.0 // indirect - go.opentelemetry.io/collector/extension/extensionauth v1.46.0 // indirect - go.opentelemetry.io/collector/extension/extensionmiddleware v0.140.0 // indirect + go.opentelemetry.io/collector/consumer/consumertest v0.148.0 // indirect + go.opentelemetry.io/collector/consumer/xconsumer v0.148.0 // indirect + go.opentelemetry.io/collector/extension v1.54.0 // indirect + go.opentelemetry.io/collector/extension/extensionauth v1.54.0 // indirect + go.opentelemetry.io/collector/extension/extensionmiddleware v0.148.0 // indirect go.opentelemetry.io/collector/extension/xextension v0.140.0 // indirect - go.opentelemetry.io/collector/featuregate v1.46.0 // indirect + go.opentelemetry.io/collector/featuregate v1.54.0 // indirect + go.opentelemetry.io/collector/internal/componentalias v0.148.0 // indirect go.opentelemetry.io/collector/pdata/xpdata v0.140.0 // indirect - go.opentelemetry.io/collector/pipeline v1.46.0 // indirect + go.opentelemetry.io/collector/pipeline v1.54.0 // indirect go.opentelemetry.io/collector/pipeline/xpipeline v0.140.0 // indirect - go.opentelemetry.io/collector/receiver v1.46.0 // indirect - go.opentelemetry.io/collector/receiver/receivertest v0.140.0 // indirect - go.opentelemetry.io/collector/receiver/xreceiver v0.140.0 // indirect + go.opentelemetry.io/collector/receiver v1.54.0 // indirect + go.opentelemetry.io/collector/receiver/receivertest v0.148.0 // indirect + go.opentelemetry.io/collector/receiver/xreceiver v0.148.0 // indirect go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.63.0 // indirect - go.opentelemetry.io/otel v1.40.0 // indirect - go.opentelemetry.io/otel/metric v1.40.0 // indirect + go.opentelemetry.io/otel v1.42.0 // indirect + go.opentelemetry.io/otel/metric v1.42.0 // indirect go.opentelemetry.io/otel/sdk v1.40.0 // indirect go.opentelemetry.io/otel/sdk/metric v1.40.0 // indirect - go.opentelemetry.io/otel/trace v1.40.0 // indirect + go.opentelemetry.io/otel/trace v1.42.0 // indirect go.uber.org/multierr v1.11.0 // indirect go.yaml.in/yaml/v3 v3.0.4 // indirect - golang.org/x/crypto v0.45.0 // indirect - golang.org/x/net v0.47.0 // indirect - golang.org/x/sys v0.40.0 // indirect - golang.org/x/text v0.31.0 // indirect + golang.org/x/crypto v0.48.0 // indirect + golang.org/x/net v0.51.0 // indirect + golang.org/x/sys v0.41.0 // indirect + golang.org/x/text v0.34.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) @@ -182,3 +184,5 @@ replace go.opentelemetry.io/collector/config/configoptional => ../../config/conf replace go.opentelemetry.io/collector/exporter/exporterhelper => ../exporterhelper replace go.opentelemetry.io/collector/internal/testutil => ../../internal/testutil + +replace go.opentelemetry.io/collector/internal/componentalias => ../../internal/componentalias diff --git a/exporter/otlpexporter/go.sum b/exporter/otlpexporter/go.sum index 78a776a2e20d..42df3e2fe6cf 100644 --- a/exporter/otlpexporter/go.sum +++ b/exporter/otlpexporter/go.sum @@ -5,10 +5,8 @@ github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XL github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/foxboron/go-tpm-keyfiles v0.0.0-20250903184740-5d135037bd4d h1:EdO/NMMuCZfxhdzTZLuKAciQSnI2DV+Ppg8+vAYrnqA= -github.com/foxboron/go-tpm-keyfiles v0.0.0-20250903184740-5d135037bd4d/go.mod h1:uAyTlAUxchYuiFjTHmuIEJ4nGSm7iOPaGcAyA81fJ80= -github.com/foxboron/swtpm_test v0.0.0-20230726224112-46aaafdf7006 h1:50sW4r0PcvlpG4PV8tYh2RVCapszJgaOLRCS2subvV4= -github.com/foxboron/swtpm_test v0.0.0-20230726224112-46aaafdf7006/go.mod h1:eIXCMsMYCaqq9m1KSSxXwQG11krpuNPGP3k0uaWrbas= +github.com/foxboron/go-tpm-keyfiles v0.0.0-20251226215517-609e4778396f h1:RJ+BDPLSHQO7cSjKBqjPJSbi1qfk9WcsjQDtZiw3dZw= +github.com/foxboron/go-tpm-keyfiles v0.0.0-20251226215517-609e4778396f/go.mod h1:VHbbch/X4roIY22jL1s3qRbZhCiRIgUAF/PdSUcx2io= github.com/fsnotify/fsnotify v1.9.0 h1:2Ml+OJNzbYCTzsxtv8vKSFD9PbJjmhYF14k/jKC7S9k= github.com/fsnotify/fsnotify v1.9.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= @@ -16,8 +14,8 @@ github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI= github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= -github.com/go-viper/mapstructure/v2 v2.4.0 h1:EBsztssimR/CONLSZZ04E8qAkxNYq4Qp9LvH92wZUgs= -github.com/go-viper/mapstructure/v2 v2.4.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM= +github.com/go-viper/mapstructure/v2 v2.5.0 h1:vM5IJoUAy3d7zRSVtIwQgBj7BiWtMPfmPEgAXnvj1Ro= +github.com/go-viper/mapstructure/v2 v2.5.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM= github.com/gobwas/glob v0.2.3 h1:A4xDbljILXROh+kObIiy5kIaPYD8e96x1tgBhUI5J+Y= github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8= github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= @@ -26,15 +24,17 @@ github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM= github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= -github.com/google/go-tpm v0.9.7 h1:u89J4tUUeDTlH8xxC3CTW7OHZjbjKoHdQ9W7gCUhtxA= -github.com/google/go-tpm v0.9.7/go.mod h1:h9jEsEECg7gtLis0upRBQU+GhYVH6jMjrFxI8u6bVUY= -github.com/google/go-tpm-tools v0.4.4 h1:oiQfAIkc6xTy9Fl5NKTeTJkBTlXdHsxAofmQyxBKY98= -github.com/google/go-tpm-tools v0.4.4/go.mod h1:T8jXkp2s+eltnCDIsXR84/MTcVU9Ja7bh3Mit0pa4AY= +github.com/google/go-tpm v0.9.8 h1:slArAR9Ft+1ybZu0lBwpSmpwhRXaa85hWtMinMyRAWo= +github.com/google/go-tpm v0.9.8/go.mod h1:h9jEsEECg7gtLis0upRBQU+GhYVH6jMjrFxI8u6bVUY= +github.com/google/go-tpm-tools v0.4.7 h1:J3ycC8umYxM9A4eF73EofRZu4BxY0jjQnUnkhIBbvws= +github.com/google/go-tpm-tools v0.4.7/go.mod h1:gSyXTZHe3fgbzb6WEGd90QucmsnT1SRdlye82gH8QjQ= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/hashicorp/go-version v1.7.0 h1:5tqGy27NaOTB8yJKUZELlFAS/LTKJkrmONwQKeRZfjY= -github.com/hashicorp/go-version v1.7.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= +github.com/hashicorp/go-version v1.8.0 h1:KAkNb1HAiZd1ukkxDFGmokVZe1Xy9HG6NUp+bPle2i4= +github.com/hashicorp/go-version v1.8.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= +github.com/hashicorp/golang-lru/v2 v2.0.7 h1:a+bsQ5rvGLjzHuww6tVxozPZFVghXaHOwFs4luLUK2k= +github.com/hashicorp/golang-lru/v2 v2.0.7/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyfM2/ZepoAG6RGpeM= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= github.com/klauspost/compress v1.17.11 h1:In6xLpyWOi1+C7tXUUWv2ot1QvBjxevKAaI6IXrJmUc= @@ -43,8 +43,8 @@ github.com/knadh/koanf/maps v0.1.2 h1:RBfmAW5CnZT+PJ1CVc1QSJKf4Xu9kxfQgYVQSu8hpb github.com/knadh/koanf/maps v0.1.2/go.mod h1:npD/QZY3V6ghQDdcQzl1W4ICNVTkohC8E73eI2xW4yI= github.com/knadh/koanf/providers/confmap v1.0.0 h1:mHKLJTE7iXEys6deO5p6olAiZdG5zwp8Aebir+/EaRE= github.com/knadh/koanf/providers/confmap v1.0.0/go.mod h1:txHYHiI2hAtF0/0sCmcuol4IDcuQbKTybiB1nOcUo1A= -github.com/knadh/koanf/v2 v2.3.0 h1:Qg076dDRFHvqnKG97ZEsi9TAg2/nFTa9hCdcSa1lvlM= -github.com/knadh/koanf/v2 v2.3.0/go.mod h1:gRb40VRAbd4iJMYYD5IxZ6hfuopFcXBpc9bbQpZwo28= +github.com/knadh/koanf/v2 v2.3.3 h1:jLJC8XCRfLC7n4F+ZKKdBsbq1bfXTpuFhf4L7t94D94= +github.com/knadh/koanf/v2 v2.3.3/go.mod h1:gRb40VRAbd4iJMYYD5IxZ6hfuopFcXBpc9bbQpZwo28= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= @@ -73,22 +73,22 @@ go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y= go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.63.0 h1:YH4g8lQroajqUwWbq/tr2QX1JFmEXaDLgG+ew9bLMWo= go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.63.0/go.mod h1:fvPi2qXDqFs8M4B4fmJhE92TyQs9Ydjlg3RvfUp+NbQ= -go.opentelemetry.io/otel v1.40.0 h1:oA5YeOcpRTXq6NN7frwmwFR0Cn3RhTVZvXsP4duvCms= -go.opentelemetry.io/otel v1.40.0/go.mod h1:IMb+uXZUKkMXdPddhwAHm6UfOwJyh4ct1ybIlV14J0g= -go.opentelemetry.io/otel/metric v1.40.0 h1:rcZe317KPftE2rstWIBitCdVp89A2HqjkxR3c11+p9g= -go.opentelemetry.io/otel/metric v1.40.0/go.mod h1:ib/crwQH7N3r5kfiBZQbwrTge743UDc7DTFVZrrXnqc= +go.opentelemetry.io/otel v1.42.0 h1:lSQGzTgVR3+sgJDAU/7/ZMjN9Z+vUip7leaqBKy4sho= +go.opentelemetry.io/otel v1.42.0/go.mod h1:lJNsdRMxCUIWuMlVJWzecSMuNjE7dOYyWlqOXWkdqCc= +go.opentelemetry.io/otel/metric v1.42.0 h1:2jXG+3oZLNXEPfNmnpxKDeZsFI5o4J+nz6xUlaFdF/4= +go.opentelemetry.io/otel/metric v1.42.0/go.mod h1:RlUN/7vTU7Ao/diDkEpQpnz3/92J9ko05BIwxYa2SSI= go.opentelemetry.io/otel/sdk v1.40.0 h1:KHW/jUzgo6wsPh9At46+h4upjtccTmuZCFAc9OJ71f8= go.opentelemetry.io/otel/sdk v1.40.0/go.mod h1:Ph7EFdYvxq72Y8Li9q8KebuYUr2KoeyHx0DRMKrYBUE= go.opentelemetry.io/otel/sdk/metric v1.40.0 h1:mtmdVqgQkeRxHgRv4qhyJduP3fYJRMX4AtAlbuWdCYw= go.opentelemetry.io/otel/sdk/metric v1.40.0/go.mod h1:4Z2bGMf0KSK3uRjlczMOeMhKU2rhUqdWNoKcYrtcBPg= -go.opentelemetry.io/otel/trace v1.40.0 h1:WA4etStDttCSYuhwvEa8OP8I5EWu24lkOzp+ZYblVjw= -go.opentelemetry.io/otel/trace v1.40.0/go.mod h1:zeAhriXecNGP/s2SEG3+Y8X9ujcJOTqQ5RgdEJcawiA= -go.opentelemetry.io/proto/slim/otlp v1.9.0 h1:fPVMv8tP3TrsqlkH1HWYUpbCY9cAIemx184VGkS6vlE= -go.opentelemetry.io/proto/slim/otlp v1.9.0/go.mod h1:xXdeJJ90Gqyll+orzUkY4bOd2HECo5JofeoLpymVqdI= -go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.2.0 h1:o13nadWDNkH/quoDomDUClnQBpdQQ2Qqv0lQBjIXjE8= -go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.2.0/go.mod h1:Gyb6Xe7FTi/6xBHwMmngGoHqL0w29Y4eW8TGFzpefGA= -go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.2.0 h1:EiUYvtwu6PMrMHVjcPfnsG3v+ajPkbUeH+IL93+QYyk= -go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.2.0/go.mod h1:mUUHKFiN2SST3AhJ8XhJxEoeVW12oqfXog0Bo8W3Ec4= +go.opentelemetry.io/otel/trace v1.42.0 h1:OUCgIPt+mzOnaUTpOQcBiM/PLQ/Op7oq6g4LenLmOYY= +go.opentelemetry.io/otel/trace v1.42.0/go.mod h1:f3K9S+IFqnumBkKhRJMeaZeNk9epyhnCmQh/EysQCdc= +go.opentelemetry.io/proto/slim/otlp v1.10.0 h1:iR97Vs/ZDR+y9TfuP9b1XBtdPWeC+OMslIBmhcLU7jM= +go.opentelemetry.io/proto/slim/otlp v1.10.0/go.mod h1:lV9250stpjYLPNA5viFabIgP2QlUGRT1GdTgAf8SIUk= +go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.3.0 h1:RUF5rO0hAlgiJt1fzQVzcVs3vZVNHIcMLgOgG4rWNcQ= +go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.3.0/go.mod h1:I89cynRj8y+383o7tEQVg2SVA6SRgDVIouWPUVXjx0U= +go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.3.0 h1:CQvJSldHRUN6Z8jsUeYv8J0lXRvygALXIzsmAeCcZE0= +go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.3.0/go.mod h1:xSQ+mEfJe/GjK1LXEyVOoSI1N9JV9ZI923X5kup43W4= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= @@ -97,22 +97,22 @@ go.uber.org/zap v1.27.1 h1:08RqriUEv8+ArZRYSTXy1LeBScaMpVSTBhCeaZYfMYc= go.uber.org/zap v1.27.1/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc= go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg= -golang.org/x/crypto v0.45.0 h1:jMBrvKuj23MTlT0bQEOBcAE0mjg8mK9RXFhRH6nyF3Q= -golang.org/x/crypto v0.45.0/go.mod h1:XTGrrkGJve7CYK7J8PEww4aY7gM3qMCElcJQ8n8JdX4= -golang.org/x/net v0.47.0 h1:Mx+4dIFzqraBXUugkia1OOvlD6LemFo1ALMHjrXDOhY= -golang.org/x/net v0.47.0/go.mod h1:/jNxtkgq5yWUGYkaZGqo27cfGZ1c5Nen03aYrrKpVRU= -golang.org/x/sys v0.40.0 h1:DBZZqJ2Rkml6QMQsZywtnjnnGvHza6BTfYFWY9kjEWQ= -golang.org/x/sys v0.40.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= -golang.org/x/text v0.31.0 h1:aC8ghyu4JhP8VojJ2lEHBnochRno1sgL6nEi9WGFGMM= -golang.org/x/text v0.31.0/go.mod h1:tKRAlv61yKIjGGHX/4tP1LTbc13YSec1pxVEWXzfoeM= +golang.org/x/crypto v0.48.0 h1:/VRzVqiRSggnhY7gNRxPauEQ5Drw9haKdM0jqfcCFts= +golang.org/x/crypto v0.48.0/go.mod h1:r0kV5h3qnFPlQnBSrULhlsRfryS2pmewsg+XfMgkVos= +golang.org/x/net v0.51.0 h1:94R/GTO7mt3/4wIKpcR5gkGmRLOuE/2hNGeWq/GBIFo= +golang.org/x/net v0.51.0/go.mod h1:aamm+2QF5ogm02fjy5Bb7CQ0WMt1/WVM7FtyaTLlA9Y= +golang.org/x/sys v0.41.0 h1:Ivj+2Cp/ylzLiEU89QhWblYnOE9zerudt9Ftecq2C6k= +golang.org/x/sys v0.41.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= +golang.org/x/text v0.34.0 h1:oL/Qq0Kdaqxa1KbNeMKwQq0reLCCaFtqu2eNuSeNHbk= +golang.org/x/text v0.34.0/go.mod h1:homfLqTYRFyVYemLBFl5GgL/DWEiH5wcsQ5gSh1yziA= gonum.org/v1/gonum v0.16.0 h1:5+ul4Swaf3ESvrOnidPp4GZbzf0mxVQpDCYUQE7OJfk= gonum.org/v1/gonum v0.16.0/go.mod h1:fef3am4MQ93R2HHpKnLk4/Tbh/s0+wqD5nfa6Pnwy4E= -google.golang.org/genproto/googleapis/rpc v0.0.0-20251022142026-3a174f9686a8 h1:M1rk8KBnUsBDg1oPGHNCxG4vc1f49epmTO7xscSajMk= -google.golang.org/genproto/googleapis/rpc v0.0.0-20251022142026-3a174f9686a8/go.mod h1:7i2o+ce6H/6BluujYR+kqX3GKH+dChPTQU19wjRPiGk= -google.golang.org/grpc v1.77.0 h1:wVVY6/8cGA6vvffn+wWK5ToddbgdU3d8MNENr4evgXM= -google.golang.org/grpc v1.77.0/go.mod h1:z0BY1iVj0q8E1uSQCjL9cppRj+gnZjzDnzV0dHhrNig= -google.golang.org/protobuf v1.36.10 h1:AYd7cD/uASjIL6Q9LiTjz8JLcrh/88q5UObnmY3aOOE= -google.golang.org/protobuf v1.36.10/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= +google.golang.org/genproto/googleapis/rpc v0.0.0-20260226221140-a57be14db171 h1:ggcbiqK8WWh6l1dnltU4BgWGIGo+EVYxCaAPih/zQXQ= +google.golang.org/genproto/googleapis/rpc v0.0.0-20260226221140-a57be14db171/go.mod h1:4Hqkh8ycfw05ld/3BWL7rJOSfebL2Q+DVDeRgYgxUU8= +google.golang.org/grpc v1.79.3 h1:sybAEdRIEtvcD68Gx7dmnwjZKlyfuc61Dyo9pGXXkKE= +google.golang.org/grpc v1.79.3/go.mod h1:KmT0Kjez+0dde/v2j9vzwoAScgEPx/Bw1CYChhHLrHQ= +google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE= +google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= diff --git a/exporter/otlpexporter/internal/metadata/generated_status.go b/exporter/otlpexporter/internal/metadata/generated_status.go index 02066a673f01..e6c97f9df18d 100644 --- a/exporter/otlpexporter/internal/metadata/generated_status.go +++ b/exporter/otlpexporter/internal/metadata/generated_status.go @@ -7,8 +7,9 @@ import ( ) var ( - Type = component.MustNewType("otlp") - ScopeName = "go.opentelemetry.io/collector/exporter/otlpexporter" + Type = component.MustNewType("otlp_grpc") + DeprecatedType = component.MustNewType("otlp") + ScopeName = "go.opentelemetry.io/collector/exporter/otlpexporter" ) const ( diff --git a/exporter/otlpexporter/metadata.yaml b/exporter/otlpexporter/metadata.yaml index ec58c59c24d2..eee68cb128ae 100644 --- a/exporter/otlpexporter/metadata.yaml +++ b/exporter/otlpexporter/metadata.yaml @@ -1,4 +1,6 @@ -type: otlp +display_name: OTLP gRPC Exporter +type: otlp_grpc +deprecated_type: otlp github_project: open-telemetry/opentelemetry-collector status: diff --git a/exporter/otlpexporter/otlp.go b/exporter/otlpexporter/otlp.go index 2b0e95fa86b7..5a8e0c799200 100644 --- a/exporter/otlpexporter/otlp.go +++ b/exporter/otlpexporter/otlp.go @@ -5,6 +5,7 @@ package otlpexporter // import "go.opentelemetry.io/collector/exporter/otlpexpor import ( "context" + "errors" "fmt" "runtime" @@ -90,6 +91,10 @@ func (e *baseExporter) shutdown(context.Context) error { } func (e *baseExporter) pushTraces(ctx context.Context, td ptrace.Traces) error { + if e.traceExporter == nil { + return errors.New("otlp exporter not started") + } + req := ptraceotlp.NewExportRequestFromTraces(td) resp, respErr := e.traceExporter.Export(ctx, req, e.callOptions...) if err := processError(respErr); err != nil { @@ -106,6 +111,10 @@ func (e *baseExporter) pushTraces(ctx context.Context, td ptrace.Traces) error { } func (e *baseExporter) pushMetrics(ctx context.Context, md pmetric.Metrics) error { + if e.metricExporter == nil { + return errors.New("otlp exporter not started") + } + req := pmetricotlp.NewExportRequestFromMetrics(md) resp, respErr := e.metricExporter.Export(ctx, req, e.callOptions...) if err := processError(respErr); err != nil { @@ -122,6 +131,10 @@ func (e *baseExporter) pushMetrics(ctx context.Context, md pmetric.Metrics) erro } func (e *baseExporter) pushLogs(ctx context.Context, ld plog.Logs) error { + if e.logExporter == nil { + return errors.New("otlp exporter not started") + } + req := plogotlp.NewExportRequestFromLogs(ld) resp, respErr := e.logExporter.Export(ctx, req, e.callOptions...) if err := processError(respErr); err != nil { @@ -138,6 +151,10 @@ func (e *baseExporter) pushLogs(ctx context.Context, ld plog.Logs) error { } func (e *baseExporter) pushProfiles(ctx context.Context, td pprofile.Profiles) error { + if e.profileExporter == nil { + return errors.New("otlp exporter not started") + } + req := pprofileotlp.NewExportRequestFromProfiles(td) resp, respErr := e.profileExporter.Export(ctx, req, e.callOptions...) if err := processError(respErr); err != nil { diff --git a/exporter/otlpexporter/otlp_test.go b/exporter/otlpexporter/otlp_test.go index 30c5b7184113..8a4155a1ed80 100644 --- a/exporter/otlpexporter/otlp_test.go +++ b/exporter/otlpexporter/otlp_test.go @@ -28,8 +28,10 @@ import ( "go.opentelemetry.io/collector/component/componenttest" "go.opentelemetry.io/collector/config/configgrpc" "go.opentelemetry.io/collector/config/configopaque" + "go.opentelemetry.io/collector/config/configoptional" "go.opentelemetry.io/collector/config/configtls" "go.opentelemetry.io/collector/exporter" + "go.opentelemetry.io/collector/exporter/exporterhelper" "go.opentelemetry.io/collector/exporter/exportertest" "go.opentelemetry.io/collector/exporter/xexporter" "go.opentelemetry.io/collector/pdata/plog" @@ -309,7 +311,7 @@ func TestSendTraces(t *testing.T) { cfg := factory.CreateDefaultConfig().(*Config) // Disable queuing to ensure that we execute the request when calling ConsumeTraces // otherwise we will not see any errors. - cfg.QueueConfig.Enabled = false + cfg.QueueConfig = configoptional.None[exporterhelper.QueueBatchConfig]() cfg.ClientConfig = configgrpc.ClientConfig{ Endpoint: ln.Addr().String(), TLS: configtls.ClientConfig{ @@ -395,7 +397,7 @@ func TestSendTraces(t *testing.T) { assert.Contains(t, observed.FilterLevelExact(zap.WarnLevel).All()[0].Message, "Partial success") } -func TestSendTracesWhenEndpointHasHttpScheme(t *testing.T) { +func TestSendTracesWhenEndpointHasHTTPScheme(t *testing.T) { tests := []struct { name string useTLS bool @@ -481,7 +483,7 @@ func TestSendMetrics(t *testing.T) { cfg := factory.CreateDefaultConfig().(*Config) // Disable queuing to ensure that we execute the request when calling ConsumeMetrics // otherwise we will not see any errors. - cfg.QueueConfig.Enabled = false + cfg.QueueConfig = configoptional.None[exporterhelper.QueueBatchConfig]() cfg.ClientConfig = configgrpc.ClientConfig{ Endpoint: ln.Addr().String(), TLS: configtls.ClientConfig{ @@ -586,7 +588,7 @@ func TestSendTraceDataServerDownAndUp(t *testing.T) { cfg := factory.CreateDefaultConfig().(*Config) // Disable queuing to ensure that we execute the request when calling ConsumeTraces // otherwise we will not see the error. - cfg.QueueConfig.Enabled = false + cfg.QueueConfig = configoptional.None[exporterhelper.QueueBatchConfig]() cfg.ClientConfig = configgrpc.ClientConfig{ Endpoint: ln.Addr().String(), TLS: configtls.ClientConfig{ @@ -778,7 +780,7 @@ func TestSendLogData(t *testing.T) { cfg := factory.CreateDefaultConfig().(*Config) // Disable queuing to ensure that we execute the request when calling ConsumeLogs // otherwise we will not see any errors. - cfg.QueueConfig.Enabled = false + cfg.QueueConfig = configoptional.None[exporterhelper.QueueBatchConfig]() cfg.ClientConfig = configgrpc.ClientConfig{ Endpoint: ln.Addr().String(), TLS: configtls.ClientConfig{ @@ -882,7 +884,7 @@ func TestSendProfiles(t *testing.T) { cfg := factory.CreateDefaultConfig().(*Config) // Disable queuing to ensure that we execute the request when calling ConsumeProfiles // otherwise we will not see any errors. - cfg.QueueConfig.Enabled = false + cfg.QueueConfig = configoptional.None[exporterhelper.QueueBatchConfig]() cfg.ClientConfig = configgrpc.ClientConfig{ Endpoint: ln.Addr().String(), TLS: configtls.ClientConfig{ @@ -968,7 +970,47 @@ func TestSendProfiles(t *testing.T) { assert.Contains(t, observed.FilterLevelExact(zap.WarnLevel).All()[0].Message, "Partial success") } -func TestSendProfilesWhenEndpointHasHttpScheme(t *testing.T) { +func TestPushTracesBeforeStart(t *testing.T) { + factory := NewFactory() + cfg := factory.CreateDefaultConfig() + set := exportertest.NewNopSettings(factory.Type()) + exp := newExporter(cfg, set) + err := exp.pushTraces(context.Background(), ptrace.NewTraces()) + require.Error(t, err) + assert.Contains(t, err.Error(), "not started") +} + +func TestPushMetricsBeforeStart(t *testing.T) { + factory := NewFactory() + cfg := factory.CreateDefaultConfig() + set := exportertest.NewNopSettings(factory.Type()) + exp := newExporter(cfg, set) + err := exp.pushMetrics(context.Background(), pmetric.NewMetrics()) + require.Error(t, err) + assert.Contains(t, err.Error(), "not started") +} + +func TestPushLogsBeforeStart(t *testing.T) { + factory := NewFactory() + cfg := factory.CreateDefaultConfig() + set := exportertest.NewNopSettings(factory.Type()) + exp := newExporter(cfg, set) + err := exp.pushLogs(context.Background(), plog.NewLogs()) + require.Error(t, err) + assert.Contains(t, err.Error(), "not started") +} + +func TestPushProfilesBeforeStart(t *testing.T) { + factory := NewFactory() + cfg := factory.CreateDefaultConfig() + set := exportertest.NewNopSettings(factory.Type()) + exp := newExporter(cfg, set) + err := exp.pushProfiles(context.Background(), pprofile.NewProfiles()) + require.Error(t, err) + assert.Contains(t, err.Error(), "not started") +} + +func TestSendProfilesWhenEndpointHasHTTPScheme(t *testing.T) { tests := []struct { name string useTLS bool diff --git a/exporter/otlphttpexporter/README.md b/exporter/otlphttpexporter/README.md index c4e1f92200d4..8cb96381d748 100644 --- a/exporter/otlphttpexporter/README.md +++ b/exporter/otlphttpexporter/README.md @@ -1,6 +1,5 @@ -# OTLP/HTTP Exporter - +# OTLP HTTP Exporter | Status | | | ------------- |-----------| | Stability | [development]: profiles | @@ -16,10 +15,13 @@ [otlp]: https://github.com/open-telemetry/opentelemetry-collector-releases/tree/main/distributions/otelcol-otlp -Export traces and/or metrics via HTTP using [OTLP]( +The `otlp_http` exporter sends logs, metrics, profiles and traces via HTTP using [OTLP]( https://github.com/open-telemetry/opentelemetry-proto/blob/main/docs/specification.md) format. +The `otlphttp` deprecated alias exists for the component name. It will be removed in a future version. +If you use the deprecated alias `otlphttp` in your configuration, change it to `otlp_http`. + The following settings are required: - `endpoint` (no default): The target base URL to send data to (e.g.: https://example.com:4318). @@ -48,7 +50,7 @@ Example: ```yaml exporters: - otlphttp: + otlp_http: endpoint: https://example.com:4318 ``` @@ -56,7 +58,7 @@ By default `gzip` compression is enabled. See [compression comparison](../../con ```yaml exporters: - otlphttp: + otlp_http: ... compression: none ``` @@ -65,7 +67,7 @@ By default `proto` encoding is used, to change the content encoding of the messa ```yaml exporters: - otlphttp: + otlp_http: ... encoding: json ``` diff --git a/exporter/otlphttpexporter/config.go b/exporter/otlphttpexporter/config.go index 0417fe1dd75a..8ce72fa28b42 100644 --- a/exporter/otlphttpexporter/config.go +++ b/exporter/otlphttpexporter/config.go @@ -10,6 +10,7 @@ import ( "go.opentelemetry.io/collector/component" "go.opentelemetry.io/collector/config/confighttp" + "go.opentelemetry.io/collector/config/configoptional" "go.opentelemetry.io/collector/config/configretry" "go.opentelemetry.io/collector/exporter/exporterhelper" ) @@ -45,9 +46,9 @@ func (e *EncodingType) UnmarshalText(text []byte) error { // Config defines configuration for OTLP/HTTP exporter. type Config struct { - ClientConfig confighttp.ClientConfig `mapstructure:",squash"` // squash ensures fields are correctly decoded in embedded struct. - QueueConfig exporterhelper.QueueBatchConfig `mapstructure:"sending_queue"` - RetryConfig configretry.BackOffConfig `mapstructure:"retry_on_failure"` + ClientConfig confighttp.ClientConfig `mapstructure:",squash"` // squash ensures fields are correctly decoded in embedded struct. + QueueConfig configoptional.Optional[exporterhelper.QueueBatchConfig] `mapstructure:"sending_queue"` + RetryConfig configretry.BackOffConfig `mapstructure:"retry_on_failure"` // The URL to send traces to. If omitted the Endpoint + "/v1/traces" will be used. TracesEndpoint string `mapstructure:"traces_endpoint"` diff --git a/exporter/otlphttpexporter/config_test.go b/exporter/otlphttpexporter/config_test.go index 1957053163a2..81fb4252e79d 100644 --- a/exporter/otlphttpexporter/config_test.go +++ b/exporter/otlphttpexporter/config_test.go @@ -53,8 +53,7 @@ func TestUnmarshalConfig(t *testing.T) { MaxInterval: 1 * time.Minute, MaxElapsedTime: 10 * time.Minute, }, - QueueConfig: exporterhelper.QueueBatchConfig{ - Enabled: true, + QueueConfig: configoptional.Some(exporterhelper.QueueBatchConfig{ Sizer: exporterhelper.RequestSizerTypeRequests, NumConsumers: 2, QueueSize: 10, @@ -63,7 +62,7 @@ func TestUnmarshalConfig(t *testing.T) { FlushTimeout: 200 * time.Millisecond, MinSize: 8192, }), - }, + }), Encoding: EncodingProto, ClientConfig: confighttp.ClientConfig{ Headers: configopaque.MapList{ diff --git a/exporter/otlphttpexporter/factory.go b/exporter/otlphttpexporter/factory.go index 3db1c4d0f561..7693247b7cf6 100644 --- a/exporter/otlphttpexporter/factory.go +++ b/exporter/otlphttpexporter/factory.go @@ -13,6 +13,7 @@ import ( "go.opentelemetry.io/collector/component" "go.opentelemetry.io/collector/config/configcompression" "go.opentelemetry.io/collector/config/confighttp" + "go.opentelemetry.io/collector/config/configoptional" "go.opentelemetry.io/collector/config/configretry" "go.opentelemetry.io/collector/consumer" "go.opentelemetry.io/collector/exporter" @@ -27,6 +28,7 @@ func NewFactory() exporter.Factory { return xexporter.NewFactory( metadata.Type, createDefaultConfig, + xexporter.WithDeprecatedTypeAlias(metadata.DeprecatedType), xexporter.WithTraces(createTraces, metadata.TracesStability), xexporter.WithMetrics(createMetrics, metadata.MetricsStability), xexporter.WithLogs(createLogs, metadata.LogsStability), @@ -44,7 +46,7 @@ func createDefaultConfig() component.Config { return &Config{ RetryConfig: configretry.NewDefaultBackOffConfig(), - QueueConfig: exporterhelper.NewDefaultQueueConfig(), + QueueConfig: configoptional.Some(exporterhelper.NewDefaultQueueConfig()), Encoding: EncodingProto, ClientConfig: clientConfig, } diff --git a/exporter/otlphttpexporter/factory_test.go b/exporter/otlphttpexporter/factory_test.go index 3e4b1e690b66..90364a050bb3 100644 --- a/exporter/otlphttpexporter/factory_test.go +++ b/exporter/otlphttpexporter/factory_test.go @@ -35,7 +35,7 @@ func TestCreateDefaultConfig(t *testing.T) { assert.Equal(t, 300*time.Second, ocfg.RetryConfig.MaxElapsedTime, "default retry MaxElapsedTime") assert.Equal(t, 5*time.Second, ocfg.RetryConfig.InitialInterval, "default retry InitialInterval") assert.Equal(t, 30*time.Second, ocfg.RetryConfig.MaxInterval, "default retry MaxInterval") - assert.True(t, ocfg.QueueConfig.Enabled, "default sending queue is enabled") + assert.True(t, ocfg.QueueConfig.HasValue(), "default sending queue is enabled") assert.Equal(t, EncodingProto, ocfg.Encoding) assert.Equal(t, configcompression.TypeGzip, ocfg.ClientConfig.Compression) } diff --git a/exporter/otlphttpexporter/generated_component_test.go b/exporter/otlphttpexporter/generated_component_test.go index ef3b0f47f29d..7ee862097dd4 100644 --- a/exporter/otlphttpexporter/generated_component_test.go +++ b/exporter/otlphttpexporter/generated_component_test.go @@ -20,7 +20,7 @@ import ( "go.opentelemetry.io/collector/pdata/ptrace" ) -var typ = component.MustNewType("otlphttp") +var typ = component.MustNewType("otlp_http") func TestComponentFactoryType(t *testing.T) { require.Equal(t, typ, NewFactory().Type()) diff --git a/exporter/otlphttpexporter/go.mod b/exporter/otlphttpexporter/go.mod index 967dd1d36c48..12fc5eed865b 100644 --- a/exporter/otlphttpexporter/go.mod +++ b/exporter/otlphttpexporter/go.mod @@ -1,35 +1,35 @@ module go.opentelemetry.io/collector/exporter/otlphttpexporter -go 1.24.0 +go 1.25.0 require ( github.com/stretchr/testify v1.11.1 - go.opentelemetry.io/collector v0.140.0 - go.opentelemetry.io/collector/component v1.46.0 - go.opentelemetry.io/collector/component/componenttest v0.140.0 - go.opentelemetry.io/collector/config/configcompression v1.46.0 - go.opentelemetry.io/collector/config/confighttp v0.140.0 - go.opentelemetry.io/collector/config/configopaque v1.46.0 - go.opentelemetry.io/collector/config/configoptional v1.46.0 - go.opentelemetry.io/collector/config/configretry v1.46.0 - go.opentelemetry.io/collector/config/configtls v1.46.0 - go.opentelemetry.io/collector/confmap v1.46.0 - go.opentelemetry.io/collector/confmap/xconfmap v0.140.0 - go.opentelemetry.io/collector/consumer v1.46.0 - go.opentelemetry.io/collector/consumer/consumererror v0.140.0 - go.opentelemetry.io/collector/exporter v1.46.0 - go.opentelemetry.io/collector/exporter/exporterhelper v0.140.0 - go.opentelemetry.io/collector/exporter/exporterhelper/xexporterhelper v0.140.0 - go.opentelemetry.io/collector/exporter/exportertest v0.140.0 - go.opentelemetry.io/collector/exporter/xexporter v0.140.0 - go.opentelemetry.io/collector/internal/testutil v0.140.0 - go.opentelemetry.io/collector/pdata v1.46.0 - go.opentelemetry.io/collector/pdata/pprofile v0.140.0 + go.opentelemetry.io/collector v0.148.0 + go.opentelemetry.io/collector/component v1.54.0 + go.opentelemetry.io/collector/component/componenttest v0.148.0 + go.opentelemetry.io/collector/config/configcompression v1.54.0 + go.opentelemetry.io/collector/config/confighttp v0.148.0 + go.opentelemetry.io/collector/config/configopaque v1.54.0 + go.opentelemetry.io/collector/config/configoptional v1.54.0 + go.opentelemetry.io/collector/config/configretry v1.54.0 + go.opentelemetry.io/collector/config/configtls v1.54.0 + go.opentelemetry.io/collector/confmap v1.54.0 + go.opentelemetry.io/collector/confmap/xconfmap v0.148.0 + go.opentelemetry.io/collector/consumer v1.54.0 + go.opentelemetry.io/collector/consumer/consumererror v0.148.0 + go.opentelemetry.io/collector/exporter v1.54.0 + go.opentelemetry.io/collector/exporter/exporterhelper v0.148.0 + go.opentelemetry.io/collector/exporter/exporterhelper/xexporterhelper v0.148.0 + go.opentelemetry.io/collector/exporter/exportertest v0.148.0 + go.opentelemetry.io/collector/exporter/xexporter v0.148.0 + go.opentelemetry.io/collector/internal/testutil v0.148.0 + go.opentelemetry.io/collector/pdata v1.54.0 + go.opentelemetry.io/collector/pdata/pprofile v0.148.0 go.uber.org/goleak v1.3.0 go.uber.org/zap v1.27.1 - google.golang.org/genproto/googleapis/rpc v0.0.0-20251022142026-3a174f9686a8 - google.golang.org/grpc v1.77.0 - google.golang.org/protobuf v1.36.10 + google.golang.org/genproto/googleapis/rpc v0.0.0-20251222181119-0a764e51fe1b + google.golang.org/grpc v1.79.3 + google.golang.org/protobuf v1.36.11 ) require ( @@ -37,58 +37,61 @@ require ( github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/davecgh/go-spew v1.1.1 // indirect github.com/felixge/httpsnoop v1.0.4 // indirect - github.com/foxboron/go-tpm-keyfiles v0.0.0-20250903184740-5d135037bd4d // indirect + github.com/foxboron/go-tpm-keyfiles v0.0.0-20251226215517-609e4778396f // indirect github.com/fsnotify/fsnotify v1.9.0 // indirect github.com/go-logr/logr v1.4.3 // indirect github.com/go-logr/stdr v1.2.2 // indirect - github.com/go-viper/mapstructure/v2 v2.4.0 // indirect + github.com/go-viper/mapstructure/v2 v2.5.0 // indirect github.com/gobwas/glob v0.2.3 // indirect github.com/golang/snappy v1.0.0 // indirect - github.com/google/go-tpm v0.9.7 // indirect + github.com/google/go-tpm v0.9.8 // indirect github.com/google/uuid v1.6.0 // indirect - github.com/hashicorp/go-version v1.7.0 // indirect + github.com/hashicorp/go-version v1.8.0 // indirect + github.com/hashicorp/golang-lru/v2 v2.0.7 // indirect github.com/json-iterator/go v1.1.12 // indirect - github.com/klauspost/compress v1.18.1 // indirect + github.com/klauspost/compress v1.18.4 // indirect github.com/knadh/koanf/maps v0.1.2 // indirect github.com/knadh/koanf/providers/confmap v1.0.0 // indirect - github.com/knadh/koanf/v2 v2.3.0 // indirect + github.com/knadh/koanf/v2 v2.3.3 // indirect github.com/mitchellh/copystructure v1.2.0 // indirect github.com/mitchellh/reflectwalk v1.0.2 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee // indirect - github.com/pierrec/lz4/v4 v4.1.22 // indirect + github.com/pierrec/lz4/v4 v4.1.26 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect github.com/rs/cors v1.11.1 // indirect go.opentelemetry.io/auto/sdk v1.2.1 // indirect go.opentelemetry.io/collector/client v1.46.0 // indirect go.opentelemetry.io/collector/config/configauth v1.46.0 // indirect go.opentelemetry.io/collector/config/configmiddleware v1.46.0 // indirect + go.opentelemetry.io/collector/config/confignet v0.0.0-00010101000000-000000000000 // indirect go.opentelemetry.io/collector/consumer/consumererror/xconsumererror v0.140.0 // indirect - go.opentelemetry.io/collector/consumer/consumertest v0.140.0 // indirect - go.opentelemetry.io/collector/consumer/xconsumer v0.140.0 // indirect - go.opentelemetry.io/collector/extension v1.46.0 // indirect - go.opentelemetry.io/collector/extension/extensionauth v1.46.0 // indirect - go.opentelemetry.io/collector/extension/extensionmiddleware v0.140.0 // indirect + go.opentelemetry.io/collector/consumer/consumertest v0.148.0 // indirect + go.opentelemetry.io/collector/consumer/xconsumer v0.148.0 // indirect + go.opentelemetry.io/collector/extension v1.54.0 // indirect + go.opentelemetry.io/collector/extension/extensionauth v1.54.0 // indirect + go.opentelemetry.io/collector/extension/extensionmiddleware v0.148.0 // indirect go.opentelemetry.io/collector/extension/xextension v0.140.0 // indirect - go.opentelemetry.io/collector/featuregate v1.46.0 // indirect + go.opentelemetry.io/collector/featuregate v1.54.0 // indirect + go.opentelemetry.io/collector/internal/componentalias v0.148.0 // indirect go.opentelemetry.io/collector/pdata/xpdata v0.140.0 // indirect - go.opentelemetry.io/collector/pipeline v1.46.0 // indirect + go.opentelemetry.io/collector/pipeline v1.54.0 // indirect go.opentelemetry.io/collector/pipeline/xpipeline v0.140.0 // indirect - go.opentelemetry.io/collector/receiver v1.46.0 // indirect - go.opentelemetry.io/collector/receiver/receivertest v0.140.0 // indirect - go.opentelemetry.io/collector/receiver/xreceiver v0.140.0 // indirect + go.opentelemetry.io/collector/receiver v1.54.0 // indirect + go.opentelemetry.io/collector/receiver/receivertest v0.148.0 // indirect + go.opentelemetry.io/collector/receiver/xreceiver v0.148.0 // indirect go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.63.0 // indirect - go.opentelemetry.io/otel v1.40.0 // indirect - go.opentelemetry.io/otel/metric v1.40.0 // indirect + go.opentelemetry.io/otel v1.42.0 // indirect + go.opentelemetry.io/otel/metric v1.42.0 // indirect go.opentelemetry.io/otel/sdk v1.40.0 // indirect go.opentelemetry.io/otel/sdk/metric v1.40.0 // indirect - go.opentelemetry.io/otel/trace v1.40.0 // indirect + go.opentelemetry.io/otel/trace v1.42.0 // indirect go.uber.org/multierr v1.11.0 // indirect go.yaml.in/yaml/v3 v3.0.4 // indirect - golang.org/x/crypto v0.45.0 // indirect - golang.org/x/net v0.47.0 // indirect - golang.org/x/sys v0.40.0 // indirect - golang.org/x/text v0.31.0 // indirect + golang.org/x/crypto v0.48.0 // indirect + golang.org/x/net v0.51.0 // indirect + golang.org/x/sys v0.41.0 // indirect + golang.org/x/text v0.34.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) @@ -180,3 +183,7 @@ replace go.opentelemetry.io/collector/pdata/xpdata => ../../pdata/xpdata replace go.opentelemetry.io/collector/exporter/exporterhelper => ../exporterhelper replace go.opentelemetry.io/collector/internal/testutil => ../../internal/testutil + +replace go.opentelemetry.io/collector/internal/componentalias => ../../internal/componentalias + +replace go.opentelemetry.io/collector/config/confignet => ../../config/confignet diff --git a/exporter/otlphttpexporter/go.sum b/exporter/otlphttpexporter/go.sum index ca0648ad8688..4b924c547d3a 100644 --- a/exporter/otlphttpexporter/go.sum +++ b/exporter/otlphttpexporter/go.sum @@ -7,10 +7,8 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg= github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= -github.com/foxboron/go-tpm-keyfiles v0.0.0-20250903184740-5d135037bd4d h1:EdO/NMMuCZfxhdzTZLuKAciQSnI2DV+Ppg8+vAYrnqA= -github.com/foxboron/go-tpm-keyfiles v0.0.0-20250903184740-5d135037bd4d/go.mod h1:uAyTlAUxchYuiFjTHmuIEJ4nGSm7iOPaGcAyA81fJ80= -github.com/foxboron/swtpm_test v0.0.0-20230726224112-46aaafdf7006 h1:50sW4r0PcvlpG4PV8tYh2RVCapszJgaOLRCS2subvV4= -github.com/foxboron/swtpm_test v0.0.0-20230726224112-46aaafdf7006/go.mod h1:eIXCMsMYCaqq9m1KSSxXwQG11krpuNPGP3k0uaWrbas= +github.com/foxboron/go-tpm-keyfiles v0.0.0-20251226215517-609e4778396f h1:RJ+BDPLSHQO7cSjKBqjPJSbi1qfk9WcsjQDtZiw3dZw= +github.com/foxboron/go-tpm-keyfiles v0.0.0-20251226215517-609e4778396f/go.mod h1:VHbbch/X4roIY22jL1s3qRbZhCiRIgUAF/PdSUcx2io= github.com/fsnotify/fsnotify v1.9.0 h1:2Ml+OJNzbYCTzsxtv8vKSFD9PbJjmhYF14k/jKC7S9k= github.com/fsnotify/fsnotify v1.9.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= @@ -18,8 +16,8 @@ github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI= github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= -github.com/go-viper/mapstructure/v2 v2.4.0 h1:EBsztssimR/CONLSZZ04E8qAkxNYq4Qp9LvH92wZUgs= -github.com/go-viper/mapstructure/v2 v2.4.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM= +github.com/go-viper/mapstructure/v2 v2.5.0 h1:vM5IJoUAy3d7zRSVtIwQgBj7BiWtMPfmPEgAXnvj1Ro= +github.com/go-viper/mapstructure/v2 v2.5.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM= github.com/gobwas/glob v0.2.3 h1:A4xDbljILXROh+kObIiy5kIaPYD8e96x1tgBhUI5J+Y= github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8= github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= @@ -28,25 +26,27 @@ github.com/golang/snappy v1.0.0 h1:Oy607GVXHs7RtbggtPBnr2RmDArIsAefDwvrdWvRhGs= github.com/golang/snappy v1.0.0/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= -github.com/google/go-tpm v0.9.7 h1:u89J4tUUeDTlH8xxC3CTW7OHZjbjKoHdQ9W7gCUhtxA= -github.com/google/go-tpm v0.9.7/go.mod h1:h9jEsEECg7gtLis0upRBQU+GhYVH6jMjrFxI8u6bVUY= -github.com/google/go-tpm-tools v0.4.4 h1:oiQfAIkc6xTy9Fl5NKTeTJkBTlXdHsxAofmQyxBKY98= -github.com/google/go-tpm-tools v0.4.4/go.mod h1:T8jXkp2s+eltnCDIsXR84/MTcVU9Ja7bh3Mit0pa4AY= +github.com/google/go-tpm v0.9.8 h1:slArAR9Ft+1ybZu0lBwpSmpwhRXaa85hWtMinMyRAWo= +github.com/google/go-tpm v0.9.8/go.mod h1:h9jEsEECg7gtLis0upRBQU+GhYVH6jMjrFxI8u6bVUY= +github.com/google/go-tpm-tools v0.4.7 h1:J3ycC8umYxM9A4eF73EofRZu4BxY0jjQnUnkhIBbvws= +github.com/google/go-tpm-tools v0.4.7/go.mod h1:gSyXTZHe3fgbzb6WEGd90QucmsnT1SRdlye82gH8QjQ= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/hashicorp/go-version v1.7.0 h1:5tqGy27NaOTB8yJKUZELlFAS/LTKJkrmONwQKeRZfjY= -github.com/hashicorp/go-version v1.7.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= +github.com/hashicorp/go-version v1.8.0 h1:KAkNb1HAiZd1ukkxDFGmokVZe1Xy9HG6NUp+bPle2i4= +github.com/hashicorp/go-version v1.8.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= +github.com/hashicorp/golang-lru/v2 v2.0.7 h1:a+bsQ5rvGLjzHuww6tVxozPZFVghXaHOwFs4luLUK2k= +github.com/hashicorp/golang-lru/v2 v2.0.7/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyfM2/ZepoAG6RGpeM= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= -github.com/klauspost/compress v1.18.1 h1:bcSGx7UbpBqMChDtsF28Lw6v/G94LPrrbMbdC3JH2co= -github.com/klauspost/compress v1.18.1/go.mod h1:ZQFFVG+MdnR0P+l6wpXgIL4NTtwiKIdBnrBd8Nrxr+0= +github.com/klauspost/compress v1.18.4 h1:RPhnKRAQ4Fh8zU2FY/6ZFDwTVTxgJ/EMydqSTzE9a2c= +github.com/klauspost/compress v1.18.4/go.mod h1:R0h/fSBs8DE4ENlcrlib3PsXS61voFxhIs2DeRhCvJ4= github.com/knadh/koanf/maps v0.1.2 h1:RBfmAW5CnZT+PJ1CVc1QSJKf4Xu9kxfQgYVQSu8hpbo= github.com/knadh/koanf/maps v0.1.2/go.mod h1:npD/QZY3V6ghQDdcQzl1W4ICNVTkohC8E73eI2xW4yI= github.com/knadh/koanf/providers/confmap v1.0.0 h1:mHKLJTE7iXEys6deO5p6olAiZdG5zwp8Aebir+/EaRE= github.com/knadh/koanf/providers/confmap v1.0.0/go.mod h1:txHYHiI2hAtF0/0sCmcuol4IDcuQbKTybiB1nOcUo1A= -github.com/knadh/koanf/v2 v2.3.0 h1:Qg076dDRFHvqnKG97ZEsi9TAg2/nFTa9hCdcSa1lvlM= -github.com/knadh/koanf/v2 v2.3.0/go.mod h1:gRb40VRAbd4iJMYYD5IxZ6hfuopFcXBpc9bbQpZwo28= +github.com/knadh/koanf/v2 v2.3.3 h1:jLJC8XCRfLC7n4F+ZKKdBsbq1bfXTpuFhf4L7t94D94= +github.com/knadh/koanf/v2 v2.3.3/go.mod h1:gRb40VRAbd4iJMYYD5IxZ6hfuopFcXBpc9bbQpZwo28= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= @@ -61,8 +61,8 @@ github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJ github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee h1:W5t00kpgFdJifH4BDsTlE89Zl93FEloxaWZfGcifgq8= github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= -github.com/pierrec/lz4/v4 v4.1.22 h1:cKFw6uJDK+/gfw5BcDL0JL5aBsAFdsIT18eRtLj7VIU= -github.com/pierrec/lz4/v4 v4.1.22/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4= +github.com/pierrec/lz4/v4 v4.1.26 h1:GrpZw1gZttORinvzBdXPUXATeqlJjqUG/D87TKMnhjY= +github.com/pierrec/lz4/v4 v4.1.26/go.mod h1:EoQMVJgeeEOMsCqCzqFm2O0cJvljX2nGZjcRIPL34O4= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ= @@ -77,22 +77,22 @@ go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.63.0 h1:RbKq8BG0FI8OiXhBfcRtqqHcZcka+gU3cskNuf05R18= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.63.0/go.mod h1:h06DGIukJOevXaj/xrNjhi/2098RZzcLTbc0jDAUbsg= -go.opentelemetry.io/otel v1.40.0 h1:oA5YeOcpRTXq6NN7frwmwFR0Cn3RhTVZvXsP4duvCms= -go.opentelemetry.io/otel v1.40.0/go.mod h1:IMb+uXZUKkMXdPddhwAHm6UfOwJyh4ct1ybIlV14J0g= -go.opentelemetry.io/otel/metric v1.40.0 h1:rcZe317KPftE2rstWIBitCdVp89A2HqjkxR3c11+p9g= -go.opentelemetry.io/otel/metric v1.40.0/go.mod h1:ib/crwQH7N3r5kfiBZQbwrTge743UDc7DTFVZrrXnqc= +go.opentelemetry.io/otel v1.42.0 h1:lSQGzTgVR3+sgJDAU/7/ZMjN9Z+vUip7leaqBKy4sho= +go.opentelemetry.io/otel v1.42.0/go.mod h1:lJNsdRMxCUIWuMlVJWzecSMuNjE7dOYyWlqOXWkdqCc= +go.opentelemetry.io/otel/metric v1.42.0 h1:2jXG+3oZLNXEPfNmnpxKDeZsFI5o4J+nz6xUlaFdF/4= +go.opentelemetry.io/otel/metric v1.42.0/go.mod h1:RlUN/7vTU7Ao/diDkEpQpnz3/92J9ko05BIwxYa2SSI= go.opentelemetry.io/otel/sdk v1.40.0 h1:KHW/jUzgo6wsPh9At46+h4upjtccTmuZCFAc9OJ71f8= go.opentelemetry.io/otel/sdk v1.40.0/go.mod h1:Ph7EFdYvxq72Y8Li9q8KebuYUr2KoeyHx0DRMKrYBUE= go.opentelemetry.io/otel/sdk/metric v1.40.0 h1:mtmdVqgQkeRxHgRv4qhyJduP3fYJRMX4AtAlbuWdCYw= go.opentelemetry.io/otel/sdk/metric v1.40.0/go.mod h1:4Z2bGMf0KSK3uRjlczMOeMhKU2rhUqdWNoKcYrtcBPg= -go.opentelemetry.io/otel/trace v1.40.0 h1:WA4etStDttCSYuhwvEa8OP8I5EWu24lkOzp+ZYblVjw= -go.opentelemetry.io/otel/trace v1.40.0/go.mod h1:zeAhriXecNGP/s2SEG3+Y8X9ujcJOTqQ5RgdEJcawiA= -go.opentelemetry.io/proto/slim/otlp v1.9.0 h1:fPVMv8tP3TrsqlkH1HWYUpbCY9cAIemx184VGkS6vlE= -go.opentelemetry.io/proto/slim/otlp v1.9.0/go.mod h1:xXdeJJ90Gqyll+orzUkY4bOd2HECo5JofeoLpymVqdI= -go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.2.0 h1:o13nadWDNkH/quoDomDUClnQBpdQQ2Qqv0lQBjIXjE8= -go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.2.0/go.mod h1:Gyb6Xe7FTi/6xBHwMmngGoHqL0w29Y4eW8TGFzpefGA= -go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.2.0 h1:EiUYvtwu6PMrMHVjcPfnsG3v+ajPkbUeH+IL93+QYyk= -go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.2.0/go.mod h1:mUUHKFiN2SST3AhJ8XhJxEoeVW12oqfXog0Bo8W3Ec4= +go.opentelemetry.io/otel/trace v1.42.0 h1:OUCgIPt+mzOnaUTpOQcBiM/PLQ/Op7oq6g4LenLmOYY= +go.opentelemetry.io/otel/trace v1.42.0/go.mod h1:f3K9S+IFqnumBkKhRJMeaZeNk9epyhnCmQh/EysQCdc= +go.opentelemetry.io/proto/slim/otlp v1.10.0 h1:iR97Vs/ZDR+y9TfuP9b1XBtdPWeC+OMslIBmhcLU7jM= +go.opentelemetry.io/proto/slim/otlp v1.10.0/go.mod h1:lV9250stpjYLPNA5viFabIgP2QlUGRT1GdTgAf8SIUk= +go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.3.0 h1:RUF5rO0hAlgiJt1fzQVzcVs3vZVNHIcMLgOgG4rWNcQ= +go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.3.0/go.mod h1:I89cynRj8y+383o7tEQVg2SVA6SRgDVIouWPUVXjx0U= +go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.3.0 h1:CQvJSldHRUN6Z8jsUeYv8J0lXRvygALXIzsmAeCcZE0= +go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.3.0/go.mod h1:xSQ+mEfJe/GjK1LXEyVOoSI1N9JV9ZI923X5kup43W4= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= @@ -101,22 +101,22 @@ go.uber.org/zap v1.27.1 h1:08RqriUEv8+ArZRYSTXy1LeBScaMpVSTBhCeaZYfMYc= go.uber.org/zap v1.27.1/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc= go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg= -golang.org/x/crypto v0.45.0 h1:jMBrvKuj23MTlT0bQEOBcAE0mjg8mK9RXFhRH6nyF3Q= -golang.org/x/crypto v0.45.0/go.mod h1:XTGrrkGJve7CYK7J8PEww4aY7gM3qMCElcJQ8n8JdX4= -golang.org/x/net v0.47.0 h1:Mx+4dIFzqraBXUugkia1OOvlD6LemFo1ALMHjrXDOhY= -golang.org/x/net v0.47.0/go.mod h1:/jNxtkgq5yWUGYkaZGqo27cfGZ1c5Nen03aYrrKpVRU= -golang.org/x/sys v0.40.0 h1:DBZZqJ2Rkml6QMQsZywtnjnnGvHza6BTfYFWY9kjEWQ= -golang.org/x/sys v0.40.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= -golang.org/x/text v0.31.0 h1:aC8ghyu4JhP8VojJ2lEHBnochRno1sgL6nEi9WGFGMM= -golang.org/x/text v0.31.0/go.mod h1:tKRAlv61yKIjGGHX/4tP1LTbc13YSec1pxVEWXzfoeM= +golang.org/x/crypto v0.48.0 h1:/VRzVqiRSggnhY7gNRxPauEQ5Drw9haKdM0jqfcCFts= +golang.org/x/crypto v0.48.0/go.mod h1:r0kV5h3qnFPlQnBSrULhlsRfryS2pmewsg+XfMgkVos= +golang.org/x/net v0.51.0 h1:94R/GTO7mt3/4wIKpcR5gkGmRLOuE/2hNGeWq/GBIFo= +golang.org/x/net v0.51.0/go.mod h1:aamm+2QF5ogm02fjy5Bb7CQ0WMt1/WVM7FtyaTLlA9Y= +golang.org/x/sys v0.41.0 h1:Ivj+2Cp/ylzLiEU89QhWblYnOE9zerudt9Ftecq2C6k= +golang.org/x/sys v0.41.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= +golang.org/x/text v0.34.0 h1:oL/Qq0Kdaqxa1KbNeMKwQq0reLCCaFtqu2eNuSeNHbk= +golang.org/x/text v0.34.0/go.mod h1:homfLqTYRFyVYemLBFl5GgL/DWEiH5wcsQ5gSh1yziA= gonum.org/v1/gonum v0.16.0 h1:5+ul4Swaf3ESvrOnidPp4GZbzf0mxVQpDCYUQE7OJfk= gonum.org/v1/gonum v0.16.0/go.mod h1:fef3am4MQ93R2HHpKnLk4/Tbh/s0+wqD5nfa6Pnwy4E= -google.golang.org/genproto/googleapis/rpc v0.0.0-20251022142026-3a174f9686a8 h1:M1rk8KBnUsBDg1oPGHNCxG4vc1f49epmTO7xscSajMk= -google.golang.org/genproto/googleapis/rpc v0.0.0-20251022142026-3a174f9686a8/go.mod h1:7i2o+ce6H/6BluujYR+kqX3GKH+dChPTQU19wjRPiGk= -google.golang.org/grpc v1.77.0 h1:wVVY6/8cGA6vvffn+wWK5ToddbgdU3d8MNENr4evgXM= -google.golang.org/grpc v1.77.0/go.mod h1:z0BY1iVj0q8E1uSQCjL9cppRj+gnZjzDnzV0dHhrNig= -google.golang.org/protobuf v1.36.10 h1:AYd7cD/uASjIL6Q9LiTjz8JLcrh/88q5UObnmY3aOOE= -google.golang.org/protobuf v1.36.10/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= +google.golang.org/genproto/googleapis/rpc v0.0.0-20251222181119-0a764e51fe1b h1:Mv8VFug0MP9e5vUxfBcE3vUkV6CImK3cMNMIDFjmzxU= +google.golang.org/genproto/googleapis/rpc v0.0.0-20251222181119-0a764e51fe1b/go.mod h1:j9x/tPzZkyxcgEFkiKEEGxfvyumM01BEtsW8xzOahRQ= +google.golang.org/grpc v1.79.3 h1:sybAEdRIEtvcD68Gx7dmnwjZKlyfuc61Dyo9pGXXkKE= +google.golang.org/grpc v1.79.3/go.mod h1:KmT0Kjez+0dde/v2j9vzwoAScgEPx/Bw1CYChhHLrHQ= +google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE= +google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= diff --git a/exporter/otlphttpexporter/internal/metadata/generated_status.go b/exporter/otlphttpexporter/internal/metadata/generated_status.go index f16f032244b1..b74a3b10cfc9 100644 --- a/exporter/otlphttpexporter/internal/metadata/generated_status.go +++ b/exporter/otlphttpexporter/internal/metadata/generated_status.go @@ -7,8 +7,9 @@ import ( ) var ( - Type = component.MustNewType("otlphttp") - ScopeName = "go.opentelemetry.io/collector/exporter/otlphttpexporter" + Type = component.MustNewType("otlp_http") + DeprecatedType = component.MustNewType("otlphttp") + ScopeName = "go.opentelemetry.io/collector/exporter/otlphttpexporter" ) const ( diff --git a/exporter/otlphttpexporter/metadata.yaml b/exporter/otlphttpexporter/metadata.yaml index 7fdb6b268812..d0f46fb06d28 100644 --- a/exporter/otlphttpexporter/metadata.yaml +++ b/exporter/otlphttpexporter/metadata.yaml @@ -1,4 +1,6 @@ -type: otlphttp +display_name: OTLP HTTP Exporter +type: otlp_http +deprecated_type: otlphttp github_project: open-telemetry/opentelemetry-collector status: @@ -11,5 +13,7 @@ status: tests: config: - endpoint: "https://1.2.3.4:1234" + # use an endpoint that does not resolve, to ensure + # connection attempts fail quickly in tests + endpoint: "https://testing.invalid:1234" diff --git a/exporter/otlphttpexporter/otlp.go b/exporter/otlphttpexporter/otlp.go index 6cb68a026859..1993dd19b74d 100644 --- a/exporter/otlphttpexporter/otlp.go +++ b/exporter/otlphttpexporter/otlp.go @@ -173,9 +173,9 @@ func (e *baseExporter) pushProfiles(ctx context.Context, td pprofile.Profiles) e return e.export(ctx, e.profilesURL, request, e.profilesPartialSuccessHandler) } -func (e *baseExporter) export(ctx context.Context, url string, request []byte, partialSuccessHandler partialSuccessHandler) error { - e.logger.Debug("Preparing to make HTTP request", zap.String("url", url)) - req, err := http.NewRequestWithContext(ctx, http.MethodPost, url, bytes.NewReader(request)) +func (e *baseExporter) export(ctx context.Context, requestURL string, request []byte, partialSuccessHandler partialSuccessHandler) error { + e.logger.Debug("Preparing to make HTTP request", zap.String("url", requestURL)) + req, err := http.NewRequestWithContext(ctx, http.MethodPost, requestURL, bytes.NewReader(request)) if err != nil { return consumererror.NewPermanent(err) } @@ -193,6 +193,10 @@ func (e *baseExporter) export(ctx context.Context, url string, request []byte, p resp, err := e.client.Do(req) if err != nil { + var urlErr *url.Error + if errors.As(err, &urlErr) { + urlErr.URL = req.URL.String() + } return fmt.Errorf("failed to make an HTTP request: %w", err) } @@ -214,11 +218,11 @@ func (e *baseExporter) export(ctx context.Context, url string, request []byte, p if respStatus != nil { errString = fmt.Sprintf( "error exporting items, request to %s responded with HTTP Status Code %d, Message=%s, Details=%v", - url, resp.StatusCode, respStatus.Message, respStatus.Details) + requestURL, resp.StatusCode, respStatus.Message, respStatus.Details) } else { errString = fmt.Sprintf( "error exporting items, request to %s responded with HTTP Status Code %d", - url, resp.StatusCode) + requestURL, resp.StatusCode) } formattedErr = statusutil.NewStatusFromMsgAndHTTPCode(errString, resp.StatusCode).Err() diff --git a/exporter/otlphttpexporter/otlp_test.go b/exporter/otlphttpexporter/otlp_test.go index 91f7bed8a6c0..25e85d6c265e 100644 --- a/exporter/otlphttpexporter/otlp_test.go +++ b/exporter/otlphttpexporter/otlp_test.go @@ -11,6 +11,7 @@ import ( "io" "net/http" "net/http/httptest" + "net/url" "strings" "testing" "time" @@ -1174,3 +1175,43 @@ type badReader struct{} func (b badReader) Read([]byte) (int, error) { return 0, errors.New("Bad read") } + +type mockTransport struct { + roundTripFunc func(req *http.Request) (*http.Response, error) +} + +func (t *mockTransport) RoundTrip(req *http.Request) (*http.Response, error) { + return t.roundTripFunc(req) +} + +func TestExport_ErrorShowsModifiedURL(t *testing.T) { + originalURL := "http://localhost:4318/v1/logs" + modifiedURL := "https://actual-destination.example.com/v1/logs" + + transport := &mockTransport{ + roundTripFunc: func(req *http.Request) (*http.Response, error) { + parsedModified, err := url.Parse(modifiedURL) + require.NoError(t, err) + req.URL = parsedModified + + return nil, errors.New("we need an error logged") + }, + } + + client := &http.Client{Transport: transport} + + logger, _ := observer.New(zap.DebugLevel) + exp := &baseExporter{ + client: client, + logger: zap.New(logger), + config: &Config{ + Encoding: EncodingProto, + }, + } + + err := exp.export(context.Background(), originalURL, []byte("test data"), nil) + + require.Error(t, err) + assert.Contains(t, err.Error(), modifiedURL, "Error message should contain the modified destination URL") + assert.NotContains(t, err.Error(), originalURL, "Error message should NOT contain the original placeholder URL") +} diff --git a/exporter/otlphttpexporter/testdata/bad_empty_config.yaml b/exporter/otlphttpexporter/testdata/bad_empty_config.yaml index c52b900bbe9d..f77e33a72f00 100644 --- a/exporter/otlphttpexporter/testdata/bad_empty_config.yaml +++ b/exporter/otlphttpexporter/testdata/bad_empty_config.yaml @@ -5,11 +5,11 @@ processors: nop: exporters: - otlphttp: + otlp_http: service: pipelines: traces: receivers: [nop] processors: [nop] - exporters: [otlphttp] + exporters: [otlp_http] diff --git a/exporter/xexporter/exporter.go b/exporter/xexporter/exporter.go index dea6ed6084ea..3a5fb4e5dbf8 100644 --- a/exporter/xexporter/exporter.go +++ b/exporter/xexporter/exporter.go @@ -9,7 +9,7 @@ import ( "go.opentelemetry.io/collector/component" "go.opentelemetry.io/collector/consumer/xconsumer" "go.opentelemetry.io/collector/exporter" - "go.opentelemetry.io/collector/exporter/internal/experr" + "go.opentelemetry.io/collector/internal/componentalias" "go.opentelemetry.io/collector/pipeline" ) @@ -34,55 +34,60 @@ type Factory interface { // FactoryOption apply changes to ReceiverOptions. type FactoryOption interface { // applyOption applies the option. - applyOption(o *factoryOpts) + applyOption(o *factory) } // factoryOptionFunc is an ReceiverFactoryOption created through a function. -type factoryOptionFunc func(*factoryOpts) +type factoryOptionFunc func(*factory) -func (f factoryOptionFunc) applyOption(o *factoryOpts) { +func (f factoryOptionFunc) applyOption(o *factory) { f(o) } -type factoryOpts struct { - opts []exporter.FactoryOption - *factory -} - // CreateProfilesFunc is the equivalent of Factory.CreateProfiles. type CreateProfilesFunc func(context.Context, exporter.Settings, component.Config) (Profiles, error) // WithTraces overrides the default "error not supported" implementation for CreateTraces and the default "undefined" stability level. func WithTraces(createTraces exporter.CreateTracesFunc, sl component.StabilityLevel) FactoryOption { - return factoryOptionFunc(func(o *factoryOpts) { + return factoryOptionFunc(func(o *factory) { o.opts = append(o.opts, exporter.WithTraces(createTraces, sl)) }) } // WithMetrics overrides the default "error not supported" implementation for CreateMetrics and the default "undefined" stability level. func WithMetrics(createMetrics exporter.CreateMetricsFunc, sl component.StabilityLevel) FactoryOption { - return factoryOptionFunc(func(o *factoryOpts) { + return factoryOptionFunc(func(o *factory) { o.opts = append(o.opts, exporter.WithMetrics(createMetrics, sl)) }) } // WithLogs overrides the default "error not supported" implementation for CreateLogs and the default "undefined" stability level. func WithLogs(createLogs exporter.CreateLogsFunc, sl component.StabilityLevel) FactoryOption { - return factoryOptionFunc(func(o *factoryOpts) { + return factoryOptionFunc(func(o *factory) { o.opts = append(o.opts, exporter.WithLogs(createLogs, sl)) }) } // WithProfiles overrides the default "error not supported" implementation for CreateProfilesExporter and the default "undefined" stability level. func WithProfiles(createProfiles CreateProfilesFunc, sl component.StabilityLevel) FactoryOption { - return factoryOptionFunc(func(o *factoryOpts) { + return factoryOptionFunc(func(o *factory) { o.profilesStabilityLevel = sl o.createProfilesFunc = createProfiles }) } +// WithDeprecatedTypeAlias configures a deprecated type alias for the exporter. Only one alias is supported per exporter. +// When the alias is used in configuration, a deprecation warning is automatically logged. +func WithDeprecatedTypeAlias(alias component.Type) FactoryOption { + return factoryOptionFunc(func(o *factory) { + o.SetDeprecatedAlias(alias) + }) +} + type factory struct { exporter.Factory + componentalias.TypeAliasHolder + opts []exporter.FactoryOption createProfilesFunc CreateProfilesFunc profilesStabilityLevel component.StabilityLevel } @@ -95,19 +100,19 @@ func (f *factory) CreateProfiles(ctx context.Context, set exporter.Settings, cfg if f.createProfilesFunc == nil { return nil, pipeline.ErrSignalNotSupported } - - if set.ID.Type() != f.Type() { - return nil, experr.ErrIDMismatch(set.ID, f.Type()) + if err := componentalias.ValidateComponentType(f.Factory, set.ID); err != nil { + return nil, err } return f.createProfilesFunc(ctx, set, cfg) } -// NewFactory returns a Factory. +// NewFactory creates a wrapped exporter.Factory with experimental capabilities. func NewFactory(cfgType component.Type, createDefaultConfig component.CreateDefaultConfigFunc, options ...FactoryOption) Factory { - opts := factoryOpts{factory: &factory{}} + f := &factory{TypeAliasHolder: componentalias.NewTypeAliasHolder()} for _, opt := range options { - opt.applyOption(&opts) + opt.applyOption(f) } - opts.Factory = exporter.NewFactory(cfgType, createDefaultConfig, opts.opts...) - return opts.factory + f.Factory = exporter.NewFactory(cfgType, createDefaultConfig, f.opts...) + f.Factory.(componentalias.TypeAliasHolder).SetDeprecatedAlias(f.DeprecatedAlias()) + return f } diff --git a/exporter/xexporter/exporter_test.go b/exporter/xexporter/exporter_test.go index 3951bb75cb29..0d9b926d9e33 100644 --- a/exporter/xexporter/exporter_test.go +++ b/exporter/xexporter/exporter_test.go @@ -14,6 +14,7 @@ import ( "go.opentelemetry.io/collector/consumer/consumertest" "go.opentelemetry.io/collector/exporter" "go.opentelemetry.io/collector/exporter/internal/experr" + "go.opentelemetry.io/collector/internal/componentalias" ) var testID = component.MustNewID("test") @@ -53,3 +54,27 @@ type nop struct { func createProfiles(context.Context, exporter.Settings, component.Config) (Profiles, error) { return nopInstance, nil } + +func TestNewFactoryWithDeprecatedAlias(t *testing.T) { + testType := component.MustNewType("newname") + aliasType := component.MustNewType("oldname") + defaultCfg := struct{}{} + + f := NewFactory( + testType, + func() component.Config { return &defaultCfg }, + WithProfiles(createProfiles, component.StabilityLevelAlpha), + WithDeprecatedTypeAlias(aliasType), + ) + + assert.Equal(t, testType, f.Type()) + assert.Equal(t, aliasType, f.(*factory).Factory.(componentalias.TypeAliasHolder).DeprecatedAlias()) + assert.EqualValues(t, &defaultCfg, f.CreateDefaultConfig()) + + _, err := f.CreateProfiles(context.Background(), exporter.Settings{ID: component.MustNewID("newname")}, &defaultCfg) + require.NoError(t, err) + _, err = f.CreateProfiles(context.Background(), exporter.Settings{ID: component.MustNewID("oldname")}, &defaultCfg) + require.NoError(t, err) + _, err = f.CreateProfiles(context.Background(), exporter.Settings{ID: component.MustNewID("wrongname")}, &defaultCfg) + require.Error(t, err) +} diff --git a/exporter/xexporter/go.mod b/exporter/xexporter/go.mod index e0d25947878a..09fc8a59ddb5 100644 --- a/exporter/xexporter/go.mod +++ b/exporter/xexporter/go.mod @@ -1,31 +1,32 @@ module go.opentelemetry.io/collector/exporter/xexporter -go 1.24.0 +go 1.25.0 require ( github.com/stretchr/testify v1.11.1 - go.opentelemetry.io/collector/component v1.46.0 - go.opentelemetry.io/collector/consumer/consumertest v0.140.0 - go.opentelemetry.io/collector/consumer/xconsumer v0.140.0 - go.opentelemetry.io/collector/exporter v1.46.0 - go.opentelemetry.io/collector/pipeline v1.46.0 + go.opentelemetry.io/collector/component v1.54.0 + go.opentelemetry.io/collector/consumer/consumertest v0.148.0 + go.opentelemetry.io/collector/consumer/xconsumer v0.148.0 + go.opentelemetry.io/collector/exporter v1.54.0 + go.opentelemetry.io/collector/internal/componentalias v0.148.0 + go.opentelemetry.io/collector/pipeline v1.54.0 ) require ( github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/davecgh/go-spew v1.1.1 // indirect - github.com/hashicorp/go-version v1.7.0 // indirect + github.com/hashicorp/go-version v1.8.0 // indirect github.com/json-iterator/go v1.1.12 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee // indirect github.com/pmezard/go-difflib v1.0.0 // indirect - go.opentelemetry.io/collector/consumer v1.46.0 // indirect - go.opentelemetry.io/collector/featuregate v1.46.0 // indirect - go.opentelemetry.io/collector/pdata v1.46.0 // indirect - go.opentelemetry.io/collector/pdata/pprofile v0.140.0 // indirect - go.opentelemetry.io/otel v1.40.0 // indirect - go.opentelemetry.io/otel/metric v1.40.0 // indirect - go.opentelemetry.io/otel/trace v1.40.0 // indirect + go.opentelemetry.io/collector/consumer v1.54.0 // indirect + go.opentelemetry.io/collector/featuregate v1.54.0 // indirect + go.opentelemetry.io/collector/pdata v1.54.0 // indirect + go.opentelemetry.io/collector/pdata/pprofile v0.148.0 // indirect + go.opentelemetry.io/otel v1.42.0 // indirect + go.opentelemetry.io/otel/metric v1.42.0 // indirect + go.opentelemetry.io/otel/trace v1.42.0 // indirect go.uber.org/multierr v1.11.0 // indirect go.uber.org/zap v1.27.1 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect @@ -84,3 +85,7 @@ replace go.opentelemetry.io/collector/confmap/xconfmap => ../../confmap/xconfmap replace go.opentelemetry.io/collector/exporter/exporterhelper => ../exporterhelper replace go.opentelemetry.io/collector/internal/testutil => ../../internal/testutil + +replace go.opentelemetry.io/collector/internal/componentalias => ../../internal/componentalias + +replace go.opentelemetry.io/collector/pipeline/xpipeline => ../../pipeline/xpipeline diff --git a/exporter/xexporter/go.sum b/exporter/xexporter/go.sum index 155fb762a40a..f3253e1adf4e 100644 --- a/exporter/xexporter/go.sum +++ b/exporter/xexporter/go.sum @@ -9,23 +9,25 @@ github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI= github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= -github.com/go-viper/mapstructure/v2 v2.4.0 h1:EBsztssimR/CONLSZZ04E8qAkxNYq4Qp9LvH92wZUgs= -github.com/go-viper/mapstructure/v2 v2.4.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM= +github.com/go-viper/mapstructure/v2 v2.5.0 h1:vM5IJoUAy3d7zRSVtIwQgBj7BiWtMPfmPEgAXnvj1Ro= +github.com/go-viper/mapstructure/v2 v2.5.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM= github.com/gobwas/glob v0.2.3 h1:A4xDbljILXROh+kObIiy5kIaPYD8e96x1tgBhUI5J+Y= github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8= github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= -github.com/hashicorp/go-version v1.7.0 h1:5tqGy27NaOTB8yJKUZELlFAS/LTKJkrmONwQKeRZfjY= -github.com/hashicorp/go-version v1.7.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= +github.com/hashicorp/go-version v1.8.0 h1:KAkNb1HAiZd1ukkxDFGmokVZe1Xy9HG6NUp+bPle2i4= +github.com/hashicorp/go-version v1.8.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= +github.com/hashicorp/golang-lru/v2 v2.0.7 h1:a+bsQ5rvGLjzHuww6tVxozPZFVghXaHOwFs4luLUK2k= +github.com/hashicorp/golang-lru/v2 v2.0.7/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyfM2/ZepoAG6RGpeM= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= github.com/knadh/koanf/maps v0.1.2 h1:RBfmAW5CnZT+PJ1CVc1QSJKf4Xu9kxfQgYVQSu8hpbo= github.com/knadh/koanf/maps v0.1.2/go.mod h1:npD/QZY3V6ghQDdcQzl1W4ICNVTkohC8E73eI2xW4yI= github.com/knadh/koanf/providers/confmap v1.0.0 h1:mHKLJTE7iXEys6deO5p6olAiZdG5zwp8Aebir+/EaRE= github.com/knadh/koanf/providers/confmap v1.0.0/go.mod h1:txHYHiI2hAtF0/0sCmcuol4IDcuQbKTybiB1nOcUo1A= -github.com/knadh/koanf/v2 v2.3.0 h1:Qg076dDRFHvqnKG97ZEsi9TAg2/nFTa9hCdcSa1lvlM= -github.com/knadh/koanf/v2 v2.3.0/go.mod h1:gRb40VRAbd4iJMYYD5IxZ6hfuopFcXBpc9bbQpZwo28= +github.com/knadh/koanf/v2 v2.3.3 h1:jLJC8XCRfLC7n4F+ZKKdBsbq1bfXTpuFhf4L7t94D94= +github.com/knadh/koanf/v2 v2.3.3/go.mod h1:gRb40VRAbd4iJMYYD5IxZ6hfuopFcXBpc9bbQpZwo28= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= @@ -50,18 +52,18 @@ github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64= go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y= -go.opentelemetry.io/otel v1.40.0 h1:oA5YeOcpRTXq6NN7frwmwFR0Cn3RhTVZvXsP4duvCms= -go.opentelemetry.io/otel v1.40.0/go.mod h1:IMb+uXZUKkMXdPddhwAHm6UfOwJyh4ct1ybIlV14J0g= -go.opentelemetry.io/otel/metric v1.40.0 h1:rcZe317KPftE2rstWIBitCdVp89A2HqjkxR3c11+p9g= -go.opentelemetry.io/otel/metric v1.40.0/go.mod h1:ib/crwQH7N3r5kfiBZQbwrTge743UDc7DTFVZrrXnqc= -go.opentelemetry.io/otel/trace v1.40.0 h1:WA4etStDttCSYuhwvEa8OP8I5EWu24lkOzp+ZYblVjw= -go.opentelemetry.io/otel/trace v1.40.0/go.mod h1:zeAhriXecNGP/s2SEG3+Y8X9ujcJOTqQ5RgdEJcawiA= -go.opentelemetry.io/proto/slim/otlp v1.9.0 h1:fPVMv8tP3TrsqlkH1HWYUpbCY9cAIemx184VGkS6vlE= -go.opentelemetry.io/proto/slim/otlp v1.9.0/go.mod h1:xXdeJJ90Gqyll+orzUkY4bOd2HECo5JofeoLpymVqdI= -go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.2.0 h1:o13nadWDNkH/quoDomDUClnQBpdQQ2Qqv0lQBjIXjE8= -go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.2.0/go.mod h1:Gyb6Xe7FTi/6xBHwMmngGoHqL0w29Y4eW8TGFzpefGA= -go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.2.0 h1:EiUYvtwu6PMrMHVjcPfnsG3v+ajPkbUeH+IL93+QYyk= -go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.2.0/go.mod h1:mUUHKFiN2SST3AhJ8XhJxEoeVW12oqfXog0Bo8W3Ec4= +go.opentelemetry.io/otel v1.42.0 h1:lSQGzTgVR3+sgJDAU/7/ZMjN9Z+vUip7leaqBKy4sho= +go.opentelemetry.io/otel v1.42.0/go.mod h1:lJNsdRMxCUIWuMlVJWzecSMuNjE7dOYyWlqOXWkdqCc= +go.opentelemetry.io/otel/metric v1.42.0 h1:2jXG+3oZLNXEPfNmnpxKDeZsFI5o4J+nz6xUlaFdF/4= +go.opentelemetry.io/otel/metric v1.42.0/go.mod h1:RlUN/7vTU7Ao/diDkEpQpnz3/92J9ko05BIwxYa2SSI= +go.opentelemetry.io/otel/trace v1.42.0 h1:OUCgIPt+mzOnaUTpOQcBiM/PLQ/Op7oq6g4LenLmOYY= +go.opentelemetry.io/otel/trace v1.42.0/go.mod h1:f3K9S+IFqnumBkKhRJMeaZeNk9epyhnCmQh/EysQCdc= +go.opentelemetry.io/proto/slim/otlp v1.10.0 h1:iR97Vs/ZDR+y9TfuP9b1XBtdPWeC+OMslIBmhcLU7jM= +go.opentelemetry.io/proto/slim/otlp v1.10.0/go.mod h1:lV9250stpjYLPNA5viFabIgP2QlUGRT1GdTgAf8SIUk= +go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.3.0 h1:RUF5rO0hAlgiJt1fzQVzcVs3vZVNHIcMLgOgG4rWNcQ= +go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.3.0/go.mod h1:I89cynRj8y+383o7tEQVg2SVA6SRgDVIouWPUVXjx0U= +go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.3.0 h1:CQvJSldHRUN6Z8jsUeYv8J0lXRvygALXIzsmAeCcZE0= +go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.3.0/go.mod h1:xSQ+mEfJe/GjK1LXEyVOoSI1N9JV9ZI923X5kup43W4= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= @@ -70,14 +72,14 @@ go.uber.org/zap v1.27.1 h1:08RqriUEv8+ArZRYSTXy1LeBScaMpVSTBhCeaZYfMYc= go.uber.org/zap v1.27.1/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc= go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg= -golang.org/x/sys v0.40.0 h1:DBZZqJ2Rkml6QMQsZywtnjnnGvHza6BTfYFWY9kjEWQ= -golang.org/x/sys v0.40.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= -google.golang.org/genproto/googleapis/rpc v0.0.0-20251022142026-3a174f9686a8 h1:M1rk8KBnUsBDg1oPGHNCxG4vc1f49epmTO7xscSajMk= -google.golang.org/genproto/googleapis/rpc v0.0.0-20251022142026-3a174f9686a8/go.mod h1:7i2o+ce6H/6BluujYR+kqX3GKH+dChPTQU19wjRPiGk= -google.golang.org/grpc v1.77.0 h1:wVVY6/8cGA6vvffn+wWK5ToddbgdU3d8MNENr4evgXM= -google.golang.org/grpc v1.77.0/go.mod h1:z0BY1iVj0q8E1uSQCjL9cppRj+gnZjzDnzV0dHhrNig= -google.golang.org/protobuf v1.36.10 h1:AYd7cD/uASjIL6Q9LiTjz8JLcrh/88q5UObnmY3aOOE= -google.golang.org/protobuf v1.36.10/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= +golang.org/x/sys v0.41.0 h1:Ivj+2Cp/ylzLiEU89QhWblYnOE9zerudt9Ftecq2C6k= +golang.org/x/sys v0.41.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= +google.golang.org/genproto/googleapis/rpc v0.0.0-20251222181119-0a764e51fe1b h1:Mv8VFug0MP9e5vUxfBcE3vUkV6CImK3cMNMIDFjmzxU= +google.golang.org/genproto/googleapis/rpc v0.0.0-20251222181119-0a764e51fe1b/go.mod h1:j9x/tPzZkyxcgEFkiKEEGxfvyumM01BEtsW8xzOahRQ= +google.golang.org/grpc v1.79.3 h1:sybAEdRIEtvcD68Gx7dmnwjZKlyfuc61Dyo9pGXXkKE= +google.golang.org/grpc v1.79.3/go.mod h1:KmT0Kjez+0dde/v2j9vzwoAScgEPx/Bw1CYChhHLrHQ= +google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE= +google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= diff --git a/extension/extension.go b/extension/extension.go index b127432bcf9a..d90571344e61 100644 --- a/extension/extension.go +++ b/extension/extension.go @@ -5,9 +5,9 @@ package extension // import "go.opentelemetry.io/collector/extension" import ( "context" - "fmt" "go.opentelemetry.io/collector/component" + "go.opentelemetry.io/collector/internal/componentalias" ) // Extension is the interface for objects hosted by the OpenTelemetry Collector that @@ -49,6 +49,7 @@ type Factory interface { type factory struct { cfgType component.Type component.CreateDefaultConfigFunc + componentalias.TypeAliasHolder createFunc CreateFunc extensionStability component.StabilityLevel } @@ -64,8 +65,8 @@ func (f *factory) Stability() component.StabilityLevel { } func (f *factory) Create(ctx context.Context, set Settings, cfg component.Config) (Extension, error) { - if set.ID.Type() != f.cfgType { - return nil, fmt.Errorf("component type mismatch: component ID %q does not have type %q", set.ID, f.cfgType) + if err := componentalias.ValidateComponentType(f, set.ID); err != nil { + return nil, err } return f.createFunc(ctx, set, cfg) @@ -81,6 +82,7 @@ func NewFactory( return &factory{ cfgType: cfgType, CreateDefaultConfigFunc: createDefaultConfig, + TypeAliasHolder: componentalias.NewTypeAliasHolder(), createFunc: createServiceExtension, extensionStability: sl, } diff --git a/extension/extensionauth/extensionauthtest/go.mod b/extension/extensionauth/extensionauthtest/go.mod index b953d670e2a3..4dc8778f7f4e 100644 --- a/extension/extensionauth/extensionauthtest/go.mod +++ b/extension/extensionauth/extensionauthtest/go.mod @@ -1,33 +1,33 @@ module go.opentelemetry.io/collector/extension/extensionauth/extensionauthtest -go 1.24.0 +go 1.25.0 require ( github.com/stretchr/testify v1.11.1 - go.opentelemetry.io/collector/component v1.46.0 - go.opentelemetry.io/collector/extension v1.46.0 - go.opentelemetry.io/collector/extension/extensionauth v1.46.0 + go.opentelemetry.io/collector/component v1.54.0 + go.opentelemetry.io/collector/extension v1.54.0 + go.opentelemetry.io/collector/extension/extensionauth v1.54.0 go.uber.org/goleak v1.3.0 - google.golang.org/grpc v1.77.0 + google.golang.org/grpc v1.79.3 ) require ( github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/davecgh/go-spew v1.1.1 // indirect - github.com/hashicorp/go-version v1.7.0 // indirect + github.com/hashicorp/go-version v1.8.0 // indirect github.com/json-iterator/go v1.1.12 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee // indirect github.com/pmezard/go-difflib v1.0.0 // indirect - go.opentelemetry.io/collector/featuregate v1.46.0 // indirect - go.opentelemetry.io/collector/pdata v1.46.0 // indirect - go.opentelemetry.io/otel v1.40.0 // indirect - go.opentelemetry.io/otel/metric v1.40.0 // indirect - go.opentelemetry.io/otel/trace v1.40.0 // indirect + go.opentelemetry.io/collector/featuregate v1.54.0 // indirect + go.opentelemetry.io/collector/internal/componentalias v0.148.0 // indirect + go.opentelemetry.io/collector/pdata v1.54.0 // indirect + go.opentelemetry.io/otel v1.42.0 // indirect + go.opentelemetry.io/otel/metric v1.42.0 // indirect + go.opentelemetry.io/otel/trace v1.42.0 // indirect go.uber.org/multierr v1.11.0 // indirect go.uber.org/zap v1.27.1 // indirect - golang.org/x/sys v0.40.0 // indirect - google.golang.org/protobuf v1.36.10 // indirect + google.golang.org/protobuf v1.36.11 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) @@ -42,3 +42,5 @@ replace go.opentelemetry.io/collector/extension => ../.. replace go.opentelemetry.io/collector/featuregate => ../../../featuregate replace go.opentelemetry.io/collector/internal/testutil => ../../../internal/testutil + +replace go.opentelemetry.io/collector/internal/componentalias => ../../../internal/componentalias diff --git a/extension/extensionauth/extensionauthtest/go.sum b/extension/extensionauth/extensionauthtest/go.sum index 7754787e8588..41c81c103c95 100644 --- a/extension/extensionauth/extensionauthtest/go.sum +++ b/extension/extensionauth/extensionauthtest/go.sum @@ -10,8 +10,8 @@ github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= -github.com/hashicorp/go-version v1.7.0 h1:5tqGy27NaOTB8yJKUZELlFAS/LTKJkrmONwQKeRZfjY= -github.com/hashicorp/go-version v1.7.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= +github.com/hashicorp/go-version v1.8.0 h1:KAkNb1HAiZd1ukkxDFGmokVZe1Xy9HG6NUp+bPle2i4= +github.com/hashicorp/go-version v1.8.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= @@ -34,36 +34,36 @@ github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64= go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y= -go.opentelemetry.io/otel v1.40.0 h1:oA5YeOcpRTXq6NN7frwmwFR0Cn3RhTVZvXsP4duvCms= -go.opentelemetry.io/otel v1.40.0/go.mod h1:IMb+uXZUKkMXdPddhwAHm6UfOwJyh4ct1ybIlV14J0g= -go.opentelemetry.io/otel/metric v1.40.0 h1:rcZe317KPftE2rstWIBitCdVp89A2HqjkxR3c11+p9g= -go.opentelemetry.io/otel/metric v1.40.0/go.mod h1:ib/crwQH7N3r5kfiBZQbwrTge743UDc7DTFVZrrXnqc= -go.opentelemetry.io/otel/trace v1.40.0 h1:WA4etStDttCSYuhwvEa8OP8I5EWu24lkOzp+ZYblVjw= -go.opentelemetry.io/otel/trace v1.40.0/go.mod h1:zeAhriXecNGP/s2SEG3+Y8X9ujcJOTqQ5RgdEJcawiA= -go.opentelemetry.io/proto/slim/otlp v1.9.0 h1:fPVMv8tP3TrsqlkH1HWYUpbCY9cAIemx184VGkS6vlE= -go.opentelemetry.io/proto/slim/otlp v1.9.0/go.mod h1:xXdeJJ90Gqyll+orzUkY4bOd2HECo5JofeoLpymVqdI= -go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.2.0 h1:o13nadWDNkH/quoDomDUClnQBpdQQ2Qqv0lQBjIXjE8= -go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.2.0/go.mod h1:Gyb6Xe7FTi/6xBHwMmngGoHqL0w29Y4eW8TGFzpefGA= -go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.2.0 h1:EiUYvtwu6PMrMHVjcPfnsG3v+ajPkbUeH+IL93+QYyk= -go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.2.0/go.mod h1:mUUHKFiN2SST3AhJ8XhJxEoeVW12oqfXog0Bo8W3Ec4= +go.opentelemetry.io/otel v1.42.0 h1:lSQGzTgVR3+sgJDAU/7/ZMjN9Z+vUip7leaqBKy4sho= +go.opentelemetry.io/otel v1.42.0/go.mod h1:lJNsdRMxCUIWuMlVJWzecSMuNjE7dOYyWlqOXWkdqCc= +go.opentelemetry.io/otel/metric v1.42.0 h1:2jXG+3oZLNXEPfNmnpxKDeZsFI5o4J+nz6xUlaFdF/4= +go.opentelemetry.io/otel/metric v1.42.0/go.mod h1:RlUN/7vTU7Ao/diDkEpQpnz3/92J9ko05BIwxYa2SSI= +go.opentelemetry.io/otel/trace v1.42.0 h1:OUCgIPt+mzOnaUTpOQcBiM/PLQ/Op7oq6g4LenLmOYY= +go.opentelemetry.io/otel/trace v1.42.0/go.mod h1:f3K9S+IFqnumBkKhRJMeaZeNk9epyhnCmQh/EysQCdc= +go.opentelemetry.io/proto/slim/otlp v1.10.0 h1:iR97Vs/ZDR+y9TfuP9b1XBtdPWeC+OMslIBmhcLU7jM= +go.opentelemetry.io/proto/slim/otlp v1.10.0/go.mod h1:lV9250stpjYLPNA5viFabIgP2QlUGRT1GdTgAf8SIUk= +go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.3.0 h1:RUF5rO0hAlgiJt1fzQVzcVs3vZVNHIcMLgOgG4rWNcQ= +go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.3.0/go.mod h1:I89cynRj8y+383o7tEQVg2SVA6SRgDVIouWPUVXjx0U= +go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.3.0 h1:CQvJSldHRUN6Z8jsUeYv8J0lXRvygALXIzsmAeCcZE0= +go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.3.0/go.mod h1:xSQ+mEfJe/GjK1LXEyVOoSI1N9JV9ZI923X5kup43W4= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= go.uber.org/zap v1.27.1 h1:08RqriUEv8+ArZRYSTXy1LeBScaMpVSTBhCeaZYfMYc= go.uber.org/zap v1.27.1/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= -golang.org/x/net v0.46.1-0.20251013234738-63d1a5100f82 h1:6/3JGEh1C88g7m+qzzTbl3A0FtsLguXieqofVLU/JAo= -golang.org/x/net v0.46.1-0.20251013234738-63d1a5100f82/go.mod h1:Q9BGdFy1y4nkUwiLvT5qtyhAnEHgnQ/zd8PfU6nc210= -golang.org/x/sys v0.40.0 h1:DBZZqJ2Rkml6QMQsZywtnjnnGvHza6BTfYFWY9kjEWQ= -golang.org/x/sys v0.40.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= -golang.org/x/text v0.30.0 h1:yznKA/E9zq54KzlzBEAWn1NXSQ8DIp/NYMy88xJjl4k= -golang.org/x/text v0.30.0/go.mod h1:yDdHFIX9t+tORqspjENWgzaCVXgk0yYnYuSZ8UzzBVM= -google.golang.org/genproto/googleapis/rpc v0.0.0-20251022142026-3a174f9686a8 h1:M1rk8KBnUsBDg1oPGHNCxG4vc1f49epmTO7xscSajMk= -google.golang.org/genproto/googleapis/rpc v0.0.0-20251022142026-3a174f9686a8/go.mod h1:7i2o+ce6H/6BluujYR+kqX3GKH+dChPTQU19wjRPiGk= -google.golang.org/grpc v1.77.0 h1:wVVY6/8cGA6vvffn+wWK5ToddbgdU3d8MNENr4evgXM= -google.golang.org/grpc v1.77.0/go.mod h1:z0BY1iVj0q8E1uSQCjL9cppRj+gnZjzDnzV0dHhrNig= -google.golang.org/protobuf v1.36.10 h1:AYd7cD/uASjIL6Q9LiTjz8JLcrh/88q5UObnmY3aOOE= -google.golang.org/protobuf v1.36.10/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= +golang.org/x/net v0.51.0 h1:94R/GTO7mt3/4wIKpcR5gkGmRLOuE/2hNGeWq/GBIFo= +golang.org/x/net v0.51.0/go.mod h1:aamm+2QF5ogm02fjy5Bb7CQ0WMt1/WVM7FtyaTLlA9Y= +golang.org/x/sys v0.41.0 h1:Ivj+2Cp/ylzLiEU89QhWblYnOE9zerudt9Ftecq2C6k= +golang.org/x/sys v0.41.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= +golang.org/x/text v0.34.0 h1:oL/Qq0Kdaqxa1KbNeMKwQq0reLCCaFtqu2eNuSeNHbk= +golang.org/x/text v0.34.0/go.mod h1:homfLqTYRFyVYemLBFl5GgL/DWEiH5wcsQ5gSh1yziA= +google.golang.org/genproto/googleapis/rpc v0.0.0-20251222181119-0a764e51fe1b h1:Mv8VFug0MP9e5vUxfBcE3vUkV6CImK3cMNMIDFjmzxU= +google.golang.org/genproto/googleapis/rpc v0.0.0-20251222181119-0a764e51fe1b/go.mod h1:j9x/tPzZkyxcgEFkiKEEGxfvyumM01BEtsW8xzOahRQ= +google.golang.org/grpc v1.79.3 h1:sybAEdRIEtvcD68Gx7dmnwjZKlyfuc61Dyo9pGXXkKE= +google.golang.org/grpc v1.79.3/go.mod h1:KmT0Kjez+0dde/v2j9vzwoAScgEPx/Bw1CYChhHLrHQ= +google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE= +google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= diff --git a/extension/extensionauth/extensionauthtest/metadata.yaml b/extension/extensionauth/extensionauthtest/metadata.yaml new file mode 100644 index 000000000000..63750abc6272 --- /dev/null +++ b/extension/extensionauth/extensionauthtest/metadata.yaml @@ -0,0 +1,6 @@ +type: extensionauth/extensionauthtest +github_project: open-telemetry/opentelemetry-collector + +status: + disable_codecov_badge: true + class: pkg diff --git a/extension/extensionauth/go.mod b/extension/extensionauth/go.mod index 6bf9f2bc9bb3..7a7d54688155 100644 --- a/extension/extensionauth/go.mod +++ b/extension/extensionauth/go.mod @@ -1,11 +1,11 @@ module go.opentelemetry.io/collector/extension/extensionauth -go 1.24.0 +go 1.25.0 require ( github.com/stretchr/testify v1.11.1 go.uber.org/goleak v1.3.0 - google.golang.org/grpc v1.77.0 + google.golang.org/grpc v1.79.3 ) require ( @@ -13,7 +13,8 @@ require ( github.com/kr/pretty v0.3.1 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect github.com/rogpeppe/go-internal v1.13.1 // indirect - google.golang.org/protobuf v1.36.10 // indirect + golang.org/x/net v0.51.0 // indirect + google.golang.org/protobuf v1.36.11 // indirect gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/extension/extensionauth/go.sum b/extension/extensionauth/go.sum index daba815e2cc1..aa25e212ada2 100644 --- a/extension/extensionauth/go.sum +++ b/extension/extensionauth/go.sum @@ -20,18 +20,18 @@ github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= -golang.org/x/net v0.46.1-0.20251013234738-63d1a5100f82 h1:6/3JGEh1C88g7m+qzzTbl3A0FtsLguXieqofVLU/JAo= -golang.org/x/net v0.46.1-0.20251013234738-63d1a5100f82/go.mod h1:Q9BGdFy1y4nkUwiLvT5qtyhAnEHgnQ/zd8PfU6nc210= -golang.org/x/sys v0.37.0 h1:fdNQudmxPjkdUTPnLn5mdQv7Zwvbvpaxqs831goi9kQ= -golang.org/x/sys v0.37.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= -golang.org/x/text v0.30.0 h1:yznKA/E9zq54KzlzBEAWn1NXSQ8DIp/NYMy88xJjl4k= -golang.org/x/text v0.30.0/go.mod h1:yDdHFIX9t+tORqspjENWgzaCVXgk0yYnYuSZ8UzzBVM= -google.golang.org/genproto/googleapis/rpc v0.0.0-20251022142026-3a174f9686a8 h1:M1rk8KBnUsBDg1oPGHNCxG4vc1f49epmTO7xscSajMk= -google.golang.org/genproto/googleapis/rpc v0.0.0-20251022142026-3a174f9686a8/go.mod h1:7i2o+ce6H/6BluujYR+kqX3GKH+dChPTQU19wjRPiGk= -google.golang.org/grpc v1.77.0 h1:wVVY6/8cGA6vvffn+wWK5ToddbgdU3d8MNENr4evgXM= -google.golang.org/grpc v1.77.0/go.mod h1:z0BY1iVj0q8E1uSQCjL9cppRj+gnZjzDnzV0dHhrNig= -google.golang.org/protobuf v1.36.10 h1:AYd7cD/uASjIL6Q9LiTjz8JLcrh/88q5UObnmY3aOOE= -google.golang.org/protobuf v1.36.10/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= +golang.org/x/net v0.51.0 h1:94R/GTO7mt3/4wIKpcR5gkGmRLOuE/2hNGeWq/GBIFo= +golang.org/x/net v0.51.0/go.mod h1:aamm+2QF5ogm02fjy5Bb7CQ0WMt1/WVM7FtyaTLlA9Y= +golang.org/x/sys v0.41.0 h1:Ivj+2Cp/ylzLiEU89QhWblYnOE9zerudt9Ftecq2C6k= +golang.org/x/sys v0.41.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= +golang.org/x/text v0.34.0 h1:oL/Qq0Kdaqxa1KbNeMKwQq0reLCCaFtqu2eNuSeNHbk= +golang.org/x/text v0.34.0/go.mod h1:homfLqTYRFyVYemLBFl5GgL/DWEiH5wcsQ5gSh1yziA= +google.golang.org/genproto/googleapis/rpc v0.0.0-20251202230838-ff82c1b0f217 h1:gRkg/vSppuSQoDjxyiGfN4Upv/h/DQmIR10ZU8dh4Ww= +google.golang.org/genproto/googleapis/rpc v0.0.0-20251202230838-ff82c1b0f217/go.mod h1:7i2o+ce6H/6BluujYR+kqX3GKH+dChPTQU19wjRPiGk= +google.golang.org/grpc v1.79.3 h1:sybAEdRIEtvcD68Gx7dmnwjZKlyfuc61Dyo9pGXXkKE= +google.golang.org/grpc v1.79.3/go.mod h1:KmT0Kjez+0dde/v2j9vzwoAScgEPx/Bw1CYChhHLrHQ= +google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE= +google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= diff --git a/extension/extensionauth/metadata.yaml b/extension/extensionauth/metadata.yaml new file mode 100644 index 000000000000..5eb10cb58937 --- /dev/null +++ b/extension/extensionauth/metadata.yaml @@ -0,0 +1,6 @@ +type: extensionauth +github_project: open-telemetry/opentelemetry-collector + +status: + disable_codecov_badge: true + class: pkg diff --git a/extension/extensioncapabilities/go.mod b/extension/extensioncapabilities/go.mod index 809bdedef2ab..db2e757e4f98 100644 --- a/extension/extensioncapabilities/go.mod +++ b/extension/extensioncapabilities/go.mod @@ -1,31 +1,32 @@ module go.opentelemetry.io/collector/extension/extensioncapabilities -go 1.24.0 +go 1.25.0 require ( - go.opentelemetry.io/collector/component v1.46.0 - go.opentelemetry.io/collector/confmap v1.46.0 - go.opentelemetry.io/collector/extension v1.46.0 + go.opentelemetry.io/collector/component v1.54.0 + go.opentelemetry.io/collector/confmap v1.54.0 + go.opentelemetry.io/collector/extension v1.54.0 ) require ( github.com/cespare/xxhash/v2 v2.3.0 // indirect - github.com/go-viper/mapstructure/v2 v2.4.0 // indirect + github.com/go-viper/mapstructure/v2 v2.5.0 // indirect github.com/gobwas/glob v0.2.3 // indirect - github.com/hashicorp/go-version v1.7.0 // indirect + github.com/hashicorp/go-version v1.8.0 // indirect github.com/json-iterator/go v1.1.12 // indirect github.com/knadh/koanf/maps v0.1.2 // indirect github.com/knadh/koanf/providers/confmap v1.0.0 // indirect - github.com/knadh/koanf/v2 v2.3.0 // indirect + github.com/knadh/koanf/v2 v2.3.3 // indirect github.com/mitchellh/copystructure v1.2.0 // indirect github.com/mitchellh/reflectwalk v1.0.2 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee // indirect - go.opentelemetry.io/collector/featuregate v1.46.0 // indirect - go.opentelemetry.io/collector/pdata v1.46.0 // indirect - go.opentelemetry.io/otel v1.40.0 // indirect - go.opentelemetry.io/otel/metric v1.40.0 // indirect - go.opentelemetry.io/otel/trace v1.40.0 // indirect + go.opentelemetry.io/collector/featuregate v1.54.0 // indirect + go.opentelemetry.io/collector/internal/componentalias v0.148.0 // indirect + go.opentelemetry.io/collector/pdata v1.54.0 // indirect + go.opentelemetry.io/otel v1.42.0 // indirect + go.opentelemetry.io/otel/metric v1.42.0 // indirect + go.opentelemetry.io/otel/trace v1.42.0 // indirect go.uber.org/multierr v1.11.0 // indirect go.uber.org/zap v1.27.1 // indirect go.yaml.in/yaml/v3 v3.0.4 // indirect @@ -42,3 +43,5 @@ replace go.opentelemetry.io/collector/component => ../../component replace go.opentelemetry.io/collector/featuregate => ../../featuregate replace go.opentelemetry.io/collector/internal/testutil => ../../internal/testutil + +replace go.opentelemetry.io/collector/internal/componentalias => ../../internal/componentalias diff --git a/extension/extensioncapabilities/go.sum b/extension/extensioncapabilities/go.sum index 1acda282130c..1b316d94add2 100644 --- a/extension/extensioncapabilities/go.sum +++ b/extension/extensioncapabilities/go.sum @@ -7,23 +7,23 @@ github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI= github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= -github.com/go-viper/mapstructure/v2 v2.4.0 h1:EBsztssimR/CONLSZZ04E8qAkxNYq4Qp9LvH92wZUgs= -github.com/go-viper/mapstructure/v2 v2.4.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM= +github.com/go-viper/mapstructure/v2 v2.5.0 h1:vM5IJoUAy3d7zRSVtIwQgBj7BiWtMPfmPEgAXnvj1Ro= +github.com/go-viper/mapstructure/v2 v2.5.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM= github.com/gobwas/glob v0.2.3 h1:A4xDbljILXROh+kObIiy5kIaPYD8e96x1tgBhUI5J+Y= github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8= github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= -github.com/hashicorp/go-version v1.7.0 h1:5tqGy27NaOTB8yJKUZELlFAS/LTKJkrmONwQKeRZfjY= -github.com/hashicorp/go-version v1.7.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= +github.com/hashicorp/go-version v1.8.0 h1:KAkNb1HAiZd1ukkxDFGmokVZe1Xy9HG6NUp+bPle2i4= +github.com/hashicorp/go-version v1.8.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= github.com/knadh/koanf/maps v0.1.2 h1:RBfmAW5CnZT+PJ1CVc1QSJKf4Xu9kxfQgYVQSu8hpbo= github.com/knadh/koanf/maps v0.1.2/go.mod h1:npD/QZY3V6ghQDdcQzl1W4ICNVTkohC8E73eI2xW4yI= github.com/knadh/koanf/providers/confmap v1.0.0 h1:mHKLJTE7iXEys6deO5p6olAiZdG5zwp8Aebir+/EaRE= github.com/knadh/koanf/providers/confmap v1.0.0/go.mod h1:txHYHiI2hAtF0/0sCmcuol4IDcuQbKTybiB1nOcUo1A= -github.com/knadh/koanf/v2 v2.3.0 h1:Qg076dDRFHvqnKG97ZEsi9TAg2/nFTa9hCdcSa1lvlM= -github.com/knadh/koanf/v2 v2.3.0/go.mod h1:gRb40VRAbd4iJMYYD5IxZ6hfuopFcXBpc9bbQpZwo28= +github.com/knadh/koanf/v2 v2.3.3 h1:jLJC8XCRfLC7n4F+ZKKdBsbq1bfXTpuFhf4L7t94D94= +github.com/knadh/koanf/v2 v2.3.3/go.mod h1:gRb40VRAbd4iJMYYD5IxZ6hfuopFcXBpc9bbQpZwo28= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= @@ -48,18 +48,18 @@ github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64= go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y= -go.opentelemetry.io/otel v1.40.0 h1:oA5YeOcpRTXq6NN7frwmwFR0Cn3RhTVZvXsP4duvCms= -go.opentelemetry.io/otel v1.40.0/go.mod h1:IMb+uXZUKkMXdPddhwAHm6UfOwJyh4ct1ybIlV14J0g= -go.opentelemetry.io/otel/metric v1.40.0 h1:rcZe317KPftE2rstWIBitCdVp89A2HqjkxR3c11+p9g= -go.opentelemetry.io/otel/metric v1.40.0/go.mod h1:ib/crwQH7N3r5kfiBZQbwrTge743UDc7DTFVZrrXnqc= -go.opentelemetry.io/otel/trace v1.40.0 h1:WA4etStDttCSYuhwvEa8OP8I5EWu24lkOzp+ZYblVjw= -go.opentelemetry.io/otel/trace v1.40.0/go.mod h1:zeAhriXecNGP/s2SEG3+Y8X9ujcJOTqQ5RgdEJcawiA= -go.opentelemetry.io/proto/slim/otlp v1.9.0 h1:fPVMv8tP3TrsqlkH1HWYUpbCY9cAIemx184VGkS6vlE= -go.opentelemetry.io/proto/slim/otlp v1.9.0/go.mod h1:xXdeJJ90Gqyll+orzUkY4bOd2HECo5JofeoLpymVqdI= -go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.2.0 h1:o13nadWDNkH/quoDomDUClnQBpdQQ2Qqv0lQBjIXjE8= -go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.2.0/go.mod h1:Gyb6Xe7FTi/6xBHwMmngGoHqL0w29Y4eW8TGFzpefGA= -go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.2.0 h1:EiUYvtwu6PMrMHVjcPfnsG3v+ajPkbUeH+IL93+QYyk= -go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.2.0/go.mod h1:mUUHKFiN2SST3AhJ8XhJxEoeVW12oqfXog0Bo8W3Ec4= +go.opentelemetry.io/otel v1.42.0 h1:lSQGzTgVR3+sgJDAU/7/ZMjN9Z+vUip7leaqBKy4sho= +go.opentelemetry.io/otel v1.42.0/go.mod h1:lJNsdRMxCUIWuMlVJWzecSMuNjE7dOYyWlqOXWkdqCc= +go.opentelemetry.io/otel/metric v1.42.0 h1:2jXG+3oZLNXEPfNmnpxKDeZsFI5o4J+nz6xUlaFdF/4= +go.opentelemetry.io/otel/metric v1.42.0/go.mod h1:RlUN/7vTU7Ao/diDkEpQpnz3/92J9ko05BIwxYa2SSI= +go.opentelemetry.io/otel/trace v1.42.0 h1:OUCgIPt+mzOnaUTpOQcBiM/PLQ/Op7oq6g4LenLmOYY= +go.opentelemetry.io/otel/trace v1.42.0/go.mod h1:f3K9S+IFqnumBkKhRJMeaZeNk9epyhnCmQh/EysQCdc= +go.opentelemetry.io/proto/slim/otlp v1.10.0 h1:iR97Vs/ZDR+y9TfuP9b1XBtdPWeC+OMslIBmhcLU7jM= +go.opentelemetry.io/proto/slim/otlp v1.10.0/go.mod h1:lV9250stpjYLPNA5viFabIgP2QlUGRT1GdTgAf8SIUk= +go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.3.0 h1:RUF5rO0hAlgiJt1fzQVzcVs3vZVNHIcMLgOgG4rWNcQ= +go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.3.0/go.mod h1:I89cynRj8y+383o7tEQVg2SVA6SRgDVIouWPUVXjx0U= +go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.3.0 h1:CQvJSldHRUN6Z8jsUeYv8J0lXRvygALXIzsmAeCcZE0= +go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.3.0/go.mod h1:xSQ+mEfJe/GjK1LXEyVOoSI1N9JV9ZI923X5kup43W4= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= @@ -68,8 +68,8 @@ go.uber.org/zap v1.27.1 h1:08RqriUEv8+ArZRYSTXy1LeBScaMpVSTBhCeaZYfMYc= go.uber.org/zap v1.27.1/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc= go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg= -google.golang.org/protobuf v1.36.10 h1:AYd7cD/uASjIL6Q9LiTjz8JLcrh/88q5UObnmY3aOOE= -google.golang.org/protobuf v1.36.10/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= +google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE= +google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= diff --git a/extension/extensioncapabilities/metadata.yaml b/extension/extensioncapabilities/metadata.yaml new file mode 100644 index 000000000000..eb37be1bd04b --- /dev/null +++ b/extension/extensioncapabilities/metadata.yaml @@ -0,0 +1,6 @@ +type: extensioncapabilities +github_project: open-telemetry/opentelemetry-collector + +status: + disable_codecov_badge: true + class: pkg diff --git a/extension/extensionmiddleware/client.go b/extension/extensionmiddleware/client.go index fb24a18339ef..41788b5aa574 100644 --- a/extension/extensionmiddleware/client.go +++ b/extension/extensionmiddleware/client.go @@ -4,6 +4,7 @@ package extensionmiddleware // import "go.opentelemetry.io/collector/extension/extensionmiddleware" import ( + "context" "net/http" "google.golang.org/grpc" @@ -11,36 +12,44 @@ import ( // HTTPClient is an interface for HTTP client middleware extensions. type HTTPClient interface { - // GetHTTPRoundTripper wraps the provided client RoundTripper. - GetHTTPRoundTripper(http.RoundTripper) (http.RoundTripper, error) + // GetHTTPRoundTripper initializes a client HTTP RoundTripper + // wrapper, this typically called when the Collector + // starts. If there is an error this returns a nil + // function. If the error is nil, the WrapHTTPRoundTripperFunc + // will never be nil. + GetHTTPRoundTripper(context.Context) (WrapHTTPRoundTripperFunc, error) } // GRPCClient is an interface for gRPC client middleware extensions. type GRPCClient interface { // GetGRPCClientOptions returns the gRPC dial options to use for client connections. - GetGRPCClientOptions() ([]grpc.DialOption, error) + GetGRPCClientOptions(context.Context) ([]grpc.DialOption, error) } var _ HTTPClient = (*GetHTTPRoundTripperFunc)(nil) // GetHTTPRoundTripperFunc is a function that implements HTTPClient. -type GetHTTPRoundTripperFunc func(base http.RoundTripper) (http.RoundTripper, error) +type GetHTTPRoundTripperFunc func(context.Context) (WrapHTTPRoundTripperFunc, error) -func (f GetHTTPRoundTripperFunc) GetHTTPRoundTripper(base http.RoundTripper) (http.RoundTripper, error) { +func (f GetHTTPRoundTripperFunc) GetHTTPRoundTripper(ctx context.Context) (WrapHTTPRoundTripperFunc, error) { if f == nil { - return base, nil + return func(_ context.Context, rt http.RoundTripper) (http.RoundTripper, error) { return rt, nil }, nil } - return f(base) + return f(ctx) } var _ GRPCClient = (*GetGRPCClientOptionsFunc)(nil) // GetGRPCClientOptionsFunc is a function that implements GRPCClient. -type GetGRPCClientOptionsFunc func() ([]grpc.DialOption, error) +type GetGRPCClientOptionsFunc func(context.Context) ([]grpc.DialOption, error) -func (f GetGRPCClientOptionsFunc) GetGRPCClientOptions() ([]grpc.DialOption, error) { +func (f GetGRPCClientOptionsFunc) GetGRPCClientOptions(ctx context.Context) ([]grpc.DialOption, error) { if f == nil { return nil, nil } - return f() + return f(ctx) } + +// WrapHTTPRoundTripperFunc is called to initialize a new instance of +// HTTP client middleware. +type WrapHTTPRoundTripperFunc = func(context.Context, http.RoundTripper) (http.RoundTripper, error) diff --git a/extension/extensionmiddleware/client_test.go b/extension/extensionmiddleware/client_test.go index 8d4eadcade20..a2ffb76393ea 100644 --- a/extension/extensionmiddleware/client_test.go +++ b/extension/extensionmiddleware/client_test.go @@ -4,6 +4,7 @@ package extensionmiddleware import ( + "context" "errors" "net/http" "testing" @@ -15,75 +16,76 @@ import ( func TestGetHTTPRoundTripperFunc(t *testing.T) { // Create a base round tripper for testing baseRT := http.DefaultTransport + testctx := context.Background() t.Run("nil function", func(t *testing.T) { var nilFunc GetHTTPRoundTripperFunc - rt, err := nilFunc.GetHTTPRoundTripper(baseRT) + rtfunc, err := nilFunc.GetHTTPRoundTripper(testctx) + require.NoError(t, err) + + rt, err := rtfunc(testctx, baseRT) require.NoError(t, err) require.Equal(t, baseRT, rt) }) t.Run("identity function", func(t *testing.T) { - identityFunc := GetHTTPRoundTripperFunc(func(base http.RoundTripper) (http.RoundTripper, error) { - return base, nil - }) - rt, err := identityFunc.GetHTTPRoundTripper(baseRT) + identityFunc := GetHTTPRoundTripperFunc(nil) + rtfunc, err := identityFunc.GetHTTPRoundTripper(testctx) + require.NoError(t, err) + rt, err := rtfunc(testctx, baseRT) require.NoError(t, err) require.Equal(t, baseRT, rt) }) t.Run("error function", func(t *testing.T) { expectedErr := errors.New("round tripper error") - errorFunc := GetHTTPRoundTripperFunc(func(_ http.RoundTripper) (http.RoundTripper, error) { + errorFunc := GetHTTPRoundTripperFunc(func(_ context.Context) (WrapHTTPRoundTripperFunc, error) { return nil, expectedErr }) - - rt, err := errorFunc.GetHTTPRoundTripper(baseRT) + rtfunc, err := errorFunc.GetHTTPRoundTripper(testctx) require.Error(t, err) require.Equal(t, expectedErr, err) - require.Nil(t, rt) + require.Nil(t, rtfunc) }) } func TestGetGRPCClientOptionsFunc(t *testing.T) { + type testCtx struct{} + var ( + key = testCtx{} + value = "testval" + ) + testctx := context.WithValue(context.Background(), key, value) + t.Run("nil function", func(t *testing.T) { var nilFunc GetGRPCClientOptionsFunc - options, err := nilFunc.GetGRPCClientOptions() + options, err := nilFunc.GetGRPCClientOptions(testctx) require.NoError(t, err) require.Nil(t, options) }) - t.Run("empty options function", func(t *testing.T) { - emptyFunc := GetGRPCClientOptionsFunc(func() ([]grpc.DialOption, error) { - return []grpc.DialOption{}, nil - }) - - options, err := emptyFunc.GetGRPCClientOptions() - require.NoError(t, err) - require.Empty(t, options) - }) - t.Run("options function", func(t *testing.T) { - // Create some test dial options dialOpt1 := grpc.WithAuthority("test-authority") dialOpt2 := grpc.WithDisableRetry() - optionsFunc := GetGRPCClientOptionsFunc(func() ([]grpc.DialOption, error) { + optionsFunc := GetGRPCClientOptionsFunc(func(ctx context.Context) ([]grpc.DialOption, error) { + require.Equal(t, ctx.Value(key), value) return []grpc.DialOption{dialOpt1, dialOpt2}, nil }) - options, err := optionsFunc.GetGRPCClientOptions() + options, err := optionsFunc.GetGRPCClientOptions(testctx) require.NoError(t, err) require.Len(t, options, 2) }) t.Run("error function", func(t *testing.T) { expectedErr := errors.New("grpc options error") - errorFunc := GetGRPCClientOptionsFunc(func() ([]grpc.DialOption, error) { + errorFunc := GetGRPCClientOptionsFunc(func(ctx context.Context) ([]grpc.DialOption, error) { + require.Equal(t, ctx.Value(key), value) return nil, expectedErr }) - options, err := errorFunc.GetGRPCClientOptions() + options, err := errorFunc.GetGRPCClientOptions(testctx) require.Error(t, err) require.Equal(t, expectedErr, err) require.Nil(t, options) diff --git a/extension/extensionmiddleware/extensionmiddlewaretest/err.go b/extension/extensionmiddleware/extensionmiddlewaretest/err.go index b881dae2c519..69ba8db718f8 100644 --- a/extension/extensionmiddleware/extensionmiddlewaretest/err.go +++ b/extension/extensionmiddleware/extensionmiddlewaretest/err.go @@ -4,7 +4,7 @@ package extensionmiddlewaretest // import "go.opentelemetry.io/collector/extension/extensionmiddleware/extensionmiddlewaretest" import ( - "net/http" + "context" "google.golang.org/grpc" @@ -34,16 +34,16 @@ type baseExtension struct { // extensionmiddleware interface and always returns an error. func NewErr(err error) extension.Extension { return &baseExtension{ - GetHTTPRoundTripperFunc: func(http.RoundTripper) (http.RoundTripper, error) { + GetHTTPRoundTripperFunc: func(context.Context) (extensionmiddleware.WrapHTTPRoundTripperFunc, error) { return nil, err }, - GetGRPCClientOptionsFunc: func() ([]grpc.DialOption, error) { + GetGRPCClientOptionsFunc: func(context.Context) ([]grpc.DialOption, error) { return nil, err }, - GetHTTPHandlerFunc: func(http.Handler) (http.Handler, error) { + GetHTTPHandlerFunc: func(context.Context) (extensionmiddleware.WrapHTTPHandlerFunc, error) { return nil, err }, - GetGRPCServerOptionsFunc: func() ([]grpc.ServerOption, error) { + GetGRPCServerOptionsFunc: func(context.Context) ([]grpc.ServerOption, error) { return nil, err }, } diff --git a/extension/extensionmiddleware/extensionmiddlewaretest/err_test.go b/extension/extensionmiddleware/extensionmiddlewaretest/err_test.go index 14bcf291b5b0..a84897a1aafa 100644 --- a/extension/extensionmiddleware/extensionmiddlewaretest/err_test.go +++ b/extension/extensionmiddleware/extensionmiddlewaretest/err_test.go @@ -4,6 +4,7 @@ package extensionmiddlewaretest import ( + "context" "errors" "testing" @@ -17,25 +18,26 @@ func TestErrClient(t *testing.T) { httpClient, ok := client.(extensionmiddleware.HTTPClient) require.True(t, ok) - _, err := httpClient.GetHTTPRoundTripper(nil) + _, err := httpClient.GetHTTPRoundTripper(context.Background()) require.Error(t, err) grpcClient, ok := client.(extensionmiddleware.GRPCClient) require.True(t, ok) - _, err = grpcClient.GetGRPCClientOptions() + _, err = grpcClient.GetGRPCClientOptions(context.Background()) require.Error(t, err) } func TestErrServer(t *testing.T) { server := NewErr(errors.New("error")) + testctx := context.Background() httpServer, ok := server.(extensionmiddleware.HTTPServer) require.True(t, ok) - _, err := httpServer.GetHTTPHandler(nil) + _, err := httpServer.GetHTTPHandler(testctx) require.Error(t, err) grpcServer, ok := server.(extensionmiddleware.GRPCServer) require.True(t, ok) - _, err = grpcServer.GetGRPCServerOptions() + _, err = grpcServer.GetGRPCServerOptions(context.Background()) require.Error(t, err) } diff --git a/extension/extensionmiddleware/extensionmiddlewaretest/go.mod b/extension/extensionmiddleware/extensionmiddlewaretest/go.mod index 41d60ad9623d..db59ee296760 100644 --- a/extension/extensionmiddleware/extensionmiddlewaretest/go.mod +++ b/extension/extensionmiddleware/extensionmiddlewaretest/go.mod @@ -1,36 +1,37 @@ module go.opentelemetry.io/collector/extension/extensionmiddleware/extensionmiddlewaretest -go 1.24.0 +go 1.25.0 require ( github.com/stretchr/testify v1.11.1 - go.opentelemetry.io/collector/component v1.46.0 - go.opentelemetry.io/collector/extension v1.46.0 - go.opentelemetry.io/collector/extension/extensionmiddleware v0.140.0 - google.golang.org/grpc v1.77.0 + go.opentelemetry.io/collector/component v1.54.0 + go.opentelemetry.io/collector/extension v1.54.0 + go.opentelemetry.io/collector/extension/extensionmiddleware v0.148.0 + google.golang.org/grpc v1.79.3 ) require ( github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/davecgh/go-spew v1.1.1 // indirect - github.com/hashicorp/go-version v1.7.0 // indirect + github.com/hashicorp/go-version v1.8.0 // indirect github.com/json-iterator/go v1.1.12 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee // indirect github.com/pmezard/go-difflib v1.0.0 // indirect - go.opentelemetry.io/collector/featuregate v1.46.0 // indirect - go.opentelemetry.io/collector/pdata v1.46.0 // indirect - go.opentelemetry.io/otel v1.40.0 // indirect - go.opentelemetry.io/otel/metric v1.40.0 // indirect + go.opentelemetry.io/collector/featuregate v1.54.0 // indirect + go.opentelemetry.io/collector/internal/componentalias v0.148.0 // indirect + go.opentelemetry.io/collector/pdata v1.54.0 // indirect + go.opentelemetry.io/otel v1.42.0 // indirect + go.opentelemetry.io/otel/metric v1.42.0 // indirect go.opentelemetry.io/otel/sdk/metric v1.40.0 // indirect - go.opentelemetry.io/otel/trace v1.40.0 // indirect + go.opentelemetry.io/otel/trace v1.42.0 // indirect go.uber.org/multierr v1.11.0 // indirect go.uber.org/zap v1.27.1 // indirect - golang.org/x/net v0.46.1-0.20251013234738-63d1a5100f82 // indirect - golang.org/x/sys v0.40.0 // indirect - golang.org/x/text v0.30.0 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20251022142026-3a174f9686a8 // indirect - google.golang.org/protobuf v1.36.10 // indirect + golang.org/x/net v0.51.0 // indirect + golang.org/x/sys v0.41.0 // indirect + golang.org/x/text v0.34.0 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20251222181119-0a764e51fe1b // indirect + google.golang.org/protobuf v1.36.11 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) @@ -45,3 +46,5 @@ replace go.opentelemetry.io/collector/extension => ../.. replace go.opentelemetry.io/collector/featuregate => ../../../featuregate replace go.opentelemetry.io/collector/internal/testutil => ../../../internal/testutil + +replace go.opentelemetry.io/collector/internal/componentalias => ../../../internal/componentalias diff --git a/extension/extensionmiddleware/extensionmiddlewaretest/go.sum b/extension/extensionmiddleware/extensionmiddlewaretest/go.sum index cd4bad993d65..7e33dd95f22e 100644 --- a/extension/extensionmiddleware/extensionmiddlewaretest/go.sum +++ b/extension/extensionmiddleware/extensionmiddlewaretest/go.sum @@ -14,8 +14,8 @@ github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/hashicorp/go-version v1.7.0 h1:5tqGy27NaOTB8yJKUZELlFAS/LTKJkrmONwQKeRZfjY= -github.com/hashicorp/go-version v1.7.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= +github.com/hashicorp/go-version v1.8.0 h1:KAkNb1HAiZd1ukkxDFGmokVZe1Xy9HG6NUp+bPle2i4= +github.com/hashicorp/go-version v1.8.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= @@ -38,42 +38,42 @@ github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64= go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y= -go.opentelemetry.io/otel v1.40.0 h1:oA5YeOcpRTXq6NN7frwmwFR0Cn3RhTVZvXsP4duvCms= -go.opentelemetry.io/otel v1.40.0/go.mod h1:IMb+uXZUKkMXdPddhwAHm6UfOwJyh4ct1ybIlV14J0g= -go.opentelemetry.io/otel/metric v1.40.0 h1:rcZe317KPftE2rstWIBitCdVp89A2HqjkxR3c11+p9g= -go.opentelemetry.io/otel/metric v1.40.0/go.mod h1:ib/crwQH7N3r5kfiBZQbwrTge743UDc7DTFVZrrXnqc= +go.opentelemetry.io/otel v1.42.0 h1:lSQGzTgVR3+sgJDAU/7/ZMjN9Z+vUip7leaqBKy4sho= +go.opentelemetry.io/otel v1.42.0/go.mod h1:lJNsdRMxCUIWuMlVJWzecSMuNjE7dOYyWlqOXWkdqCc= +go.opentelemetry.io/otel/metric v1.42.0 h1:2jXG+3oZLNXEPfNmnpxKDeZsFI5o4J+nz6xUlaFdF/4= +go.opentelemetry.io/otel/metric v1.42.0/go.mod h1:RlUN/7vTU7Ao/diDkEpQpnz3/92J9ko05BIwxYa2SSI= go.opentelemetry.io/otel/sdk v1.40.0 h1:KHW/jUzgo6wsPh9At46+h4upjtccTmuZCFAc9OJ71f8= go.opentelemetry.io/otel/sdk v1.40.0/go.mod h1:Ph7EFdYvxq72Y8Li9q8KebuYUr2KoeyHx0DRMKrYBUE= go.opentelemetry.io/otel/sdk/metric v1.40.0 h1:mtmdVqgQkeRxHgRv4qhyJduP3fYJRMX4AtAlbuWdCYw= go.opentelemetry.io/otel/sdk/metric v1.40.0/go.mod h1:4Z2bGMf0KSK3uRjlczMOeMhKU2rhUqdWNoKcYrtcBPg= -go.opentelemetry.io/otel/trace v1.40.0 h1:WA4etStDttCSYuhwvEa8OP8I5EWu24lkOzp+ZYblVjw= -go.opentelemetry.io/otel/trace v1.40.0/go.mod h1:zeAhriXecNGP/s2SEG3+Y8X9ujcJOTqQ5RgdEJcawiA= -go.opentelemetry.io/proto/slim/otlp v1.9.0 h1:fPVMv8tP3TrsqlkH1HWYUpbCY9cAIemx184VGkS6vlE= -go.opentelemetry.io/proto/slim/otlp v1.9.0/go.mod h1:xXdeJJ90Gqyll+orzUkY4bOd2HECo5JofeoLpymVqdI= -go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.2.0 h1:o13nadWDNkH/quoDomDUClnQBpdQQ2Qqv0lQBjIXjE8= -go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.2.0/go.mod h1:Gyb6Xe7FTi/6xBHwMmngGoHqL0w29Y4eW8TGFzpefGA= -go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.2.0 h1:EiUYvtwu6PMrMHVjcPfnsG3v+ajPkbUeH+IL93+QYyk= -go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.2.0/go.mod h1:mUUHKFiN2SST3AhJ8XhJxEoeVW12oqfXog0Bo8W3Ec4= +go.opentelemetry.io/otel/trace v1.42.0 h1:OUCgIPt+mzOnaUTpOQcBiM/PLQ/Op7oq6g4LenLmOYY= +go.opentelemetry.io/otel/trace v1.42.0/go.mod h1:f3K9S+IFqnumBkKhRJMeaZeNk9epyhnCmQh/EysQCdc= +go.opentelemetry.io/proto/slim/otlp v1.10.0 h1:iR97Vs/ZDR+y9TfuP9b1XBtdPWeC+OMslIBmhcLU7jM= +go.opentelemetry.io/proto/slim/otlp v1.10.0/go.mod h1:lV9250stpjYLPNA5viFabIgP2QlUGRT1GdTgAf8SIUk= +go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.3.0 h1:RUF5rO0hAlgiJt1fzQVzcVs3vZVNHIcMLgOgG4rWNcQ= +go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.3.0/go.mod h1:I89cynRj8y+383o7tEQVg2SVA6SRgDVIouWPUVXjx0U= +go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.3.0 h1:CQvJSldHRUN6Z8jsUeYv8J0lXRvygALXIzsmAeCcZE0= +go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.3.0/go.mod h1:xSQ+mEfJe/GjK1LXEyVOoSI1N9JV9ZI923X5kup43W4= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= go.uber.org/zap v1.27.1 h1:08RqriUEv8+ArZRYSTXy1LeBScaMpVSTBhCeaZYfMYc= go.uber.org/zap v1.27.1/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= -golang.org/x/net v0.46.1-0.20251013234738-63d1a5100f82 h1:6/3JGEh1C88g7m+qzzTbl3A0FtsLguXieqofVLU/JAo= -golang.org/x/net v0.46.1-0.20251013234738-63d1a5100f82/go.mod h1:Q9BGdFy1y4nkUwiLvT5qtyhAnEHgnQ/zd8PfU6nc210= -golang.org/x/sys v0.40.0 h1:DBZZqJ2Rkml6QMQsZywtnjnnGvHza6BTfYFWY9kjEWQ= -golang.org/x/sys v0.40.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= -golang.org/x/text v0.30.0 h1:yznKA/E9zq54KzlzBEAWn1NXSQ8DIp/NYMy88xJjl4k= -golang.org/x/text v0.30.0/go.mod h1:yDdHFIX9t+tORqspjENWgzaCVXgk0yYnYuSZ8UzzBVM= +golang.org/x/net v0.51.0 h1:94R/GTO7mt3/4wIKpcR5gkGmRLOuE/2hNGeWq/GBIFo= +golang.org/x/net v0.51.0/go.mod h1:aamm+2QF5ogm02fjy5Bb7CQ0WMt1/WVM7FtyaTLlA9Y= +golang.org/x/sys v0.41.0 h1:Ivj+2Cp/ylzLiEU89QhWblYnOE9zerudt9Ftecq2C6k= +golang.org/x/sys v0.41.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= +golang.org/x/text v0.34.0 h1:oL/Qq0Kdaqxa1KbNeMKwQq0reLCCaFtqu2eNuSeNHbk= +golang.org/x/text v0.34.0/go.mod h1:homfLqTYRFyVYemLBFl5GgL/DWEiH5wcsQ5gSh1yziA= gonum.org/v1/gonum v0.16.0 h1:5+ul4Swaf3ESvrOnidPp4GZbzf0mxVQpDCYUQE7OJfk= gonum.org/v1/gonum v0.16.0/go.mod h1:fef3am4MQ93R2HHpKnLk4/Tbh/s0+wqD5nfa6Pnwy4E= -google.golang.org/genproto/googleapis/rpc v0.0.0-20251022142026-3a174f9686a8 h1:M1rk8KBnUsBDg1oPGHNCxG4vc1f49epmTO7xscSajMk= -google.golang.org/genproto/googleapis/rpc v0.0.0-20251022142026-3a174f9686a8/go.mod h1:7i2o+ce6H/6BluujYR+kqX3GKH+dChPTQU19wjRPiGk= -google.golang.org/grpc v1.77.0 h1:wVVY6/8cGA6vvffn+wWK5ToddbgdU3d8MNENr4evgXM= -google.golang.org/grpc v1.77.0/go.mod h1:z0BY1iVj0q8E1uSQCjL9cppRj+gnZjzDnzV0dHhrNig= -google.golang.org/protobuf v1.36.10 h1:AYd7cD/uASjIL6Q9LiTjz8JLcrh/88q5UObnmY3aOOE= -google.golang.org/protobuf v1.36.10/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= +google.golang.org/genproto/googleapis/rpc v0.0.0-20251222181119-0a764e51fe1b h1:Mv8VFug0MP9e5vUxfBcE3vUkV6CImK3cMNMIDFjmzxU= +google.golang.org/genproto/googleapis/rpc v0.0.0-20251222181119-0a764e51fe1b/go.mod h1:j9x/tPzZkyxcgEFkiKEEGxfvyumM01BEtsW8xzOahRQ= +google.golang.org/grpc v1.79.3 h1:sybAEdRIEtvcD68Gx7dmnwjZKlyfuc61Dyo9pGXXkKE= +google.golang.org/grpc v1.79.3/go.mod h1:KmT0Kjez+0dde/v2j9vzwoAScgEPx/Bw1CYChhHLrHQ= +google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE= +google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= diff --git a/extension/extensionmiddleware/extensionmiddlewaretest/metadata.yaml b/extension/extensionmiddleware/extensionmiddlewaretest/metadata.yaml new file mode 100644 index 000000000000..aa4c0839797a --- /dev/null +++ b/extension/extensionmiddleware/extensionmiddlewaretest/metadata.yaml @@ -0,0 +1,6 @@ +type: extensionmiddleware/extensionmiddlewaretest +github_project: open-telemetry/opentelemetry-collector + +status: + disable_codecov_badge: true + class: pkg diff --git a/extension/extensionmiddleware/extensionmiddlewaretest/nop_test.go b/extension/extensionmiddleware/extensionmiddlewaretest/nop_test.go index d1190fbff983..9eeaec1c2ce9 100644 --- a/extension/extensionmiddleware/extensionmiddlewaretest/nop_test.go +++ b/extension/extensionmiddleware/extensionmiddlewaretest/nop_test.go @@ -4,6 +4,7 @@ package extensionmiddlewaretest import ( + "context" "net/http" "testing" @@ -13,33 +14,41 @@ import ( ) func TestNopClient(t *testing.T) { + testctx := context.Background() client := NewNop() httpClient, ok := client.(extensionmiddleware.HTTPClient) require.True(t, ok) - rt, err := httpClient.GetHTTPRoundTripper(nil) + rtfunc, err := httpClient.GetHTTPRoundTripper(context.Background()) + require.NoError(t, err) + + rt, err := rtfunc(testctx, nil) require.NoError(t, err) require.Nil(t, rt) grpcClient, ok := client.(extensionmiddleware.GRPCClient) require.True(t, ok) - grpcOpts, err := grpcClient.GetGRPCClientOptions() + grpcOpts, err := grpcClient.GetGRPCClientOptions(context.Background()) require.NoError(t, err) require.Nil(t, grpcOpts) } func TestNopServer(t *testing.T) { client := NewNop() + testctx := context.Background() httpServer, ok := client.(extensionmiddleware.HTTPServer) require.True(t, ok) - rt, err := httpServer.GetHTTPHandler(nil) + hfunc, err := httpServer.GetHTTPHandler(testctx) require.NoError(t, err) - require.Nil(t, rt) + + handler, err := hfunc(testctx, nil) + require.NoError(t, err) + require.Nil(t, handler) grpcServer, ok := client.(extensionmiddleware.GRPCServer) require.True(t, ok) - grpcOpts, err := grpcServer.GetGRPCServerOptions() + grpcOpts, err := grpcServer.GetGRPCServerOptions(context.Background()) require.NoError(t, err) require.Nil(t, grpcOpts) } diff --git a/extension/extensionmiddleware/go.mod b/extension/extensionmiddleware/go.mod index abba8d510eee..c39897ee1d2b 100644 --- a/extension/extensionmiddleware/go.mod +++ b/extension/extensionmiddleware/go.mod @@ -1,19 +1,19 @@ module go.opentelemetry.io/collector/extension/extensionmiddleware -go 1.24.0 +go 1.25.0 require ( github.com/stretchr/testify v1.11.1 - google.golang.org/grpc v1.77.0 + google.golang.org/grpc v1.79.3 ) require ( github.com/davecgh/go-spew v1.1.1 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect - golang.org/x/net v0.46.1-0.20251013234738-63d1a5100f82 // indirect - golang.org/x/sys v0.37.0 // indirect - golang.org/x/text v0.30.0 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20251022142026-3a174f9686a8 // indirect - google.golang.org/protobuf v1.36.10 // indirect + golang.org/x/net v0.51.0 // indirect + golang.org/x/sys v0.41.0 // indirect + golang.org/x/text v0.34.0 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20251222181119-0a764e51fe1b // indirect + google.golang.org/protobuf v1.36.11 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/extension/extensionmiddleware/go.sum b/extension/extensionmiddleware/go.sum index 2b01f03c477e..9f836feb9190 100644 --- a/extension/extensionmiddleware/go.sum +++ b/extension/extensionmiddleware/go.sum @@ -1,3 +1,5 @@ +github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= +github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI= @@ -16,30 +18,30 @@ github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64= go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y= -go.opentelemetry.io/otel v1.38.0 h1:RkfdswUDRimDg0m2Az18RKOsnI8UDzppJAtj01/Ymk8= -go.opentelemetry.io/otel v1.38.0/go.mod h1:zcmtmQ1+YmQM9wrNsTGV/q/uyusom3P8RxwExxkZhjM= -go.opentelemetry.io/otel/metric v1.38.0 h1:Kl6lzIYGAh5M159u9NgiRkmoMKjvbsKtYRwgfrA6WpA= -go.opentelemetry.io/otel/metric v1.38.0/go.mod h1:kB5n/QoRM8YwmUahxvI3bO34eVtQf2i4utNVLr9gEmI= -go.opentelemetry.io/otel/sdk v1.38.0 h1:l48sr5YbNf2hpCUj/FoGhW9yDkl+Ma+LrVl8qaM5b+E= -go.opentelemetry.io/otel/sdk v1.38.0/go.mod h1:ghmNdGlVemJI3+ZB5iDEuk4bWA3GkTpW+DOoZMYBVVg= -go.opentelemetry.io/otel/sdk/metric v1.38.0 h1:aSH66iL0aZqo//xXzQLYozmWrXxyFkBJ6qT5wthqPoM= -go.opentelemetry.io/otel/sdk/metric v1.38.0/go.mod h1:dg9PBnW9XdQ1Hd6ZnRz689CbtrUp0wMMs9iPcgT9EZA= -go.opentelemetry.io/otel/trace v1.38.0 h1:Fxk5bKrDZJUH+AMyyIXGcFAPah0oRcT+LuNtJrmcNLE= -go.opentelemetry.io/otel/trace v1.38.0/go.mod h1:j1P9ivuFsTceSWe1oY+EeW3sc+Pp42sO++GHkg4wwhs= -golang.org/x/net v0.46.1-0.20251013234738-63d1a5100f82 h1:6/3JGEh1C88g7m+qzzTbl3A0FtsLguXieqofVLU/JAo= -golang.org/x/net v0.46.1-0.20251013234738-63d1a5100f82/go.mod h1:Q9BGdFy1y4nkUwiLvT5qtyhAnEHgnQ/zd8PfU6nc210= -golang.org/x/sys v0.37.0 h1:fdNQudmxPjkdUTPnLn5mdQv7Zwvbvpaxqs831goi9kQ= -golang.org/x/sys v0.37.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= -golang.org/x/text v0.30.0 h1:yznKA/E9zq54KzlzBEAWn1NXSQ8DIp/NYMy88xJjl4k= -golang.org/x/text v0.30.0/go.mod h1:yDdHFIX9t+tORqspjENWgzaCVXgk0yYnYuSZ8UzzBVM= +go.opentelemetry.io/otel v1.39.0 h1:8yPrr/S0ND9QEfTfdP9V+SiwT4E0G7Y5MO7p85nis48= +go.opentelemetry.io/otel v1.39.0/go.mod h1:kLlFTywNWrFyEdH0oj2xK0bFYZtHRYUdv1NklR/tgc8= +go.opentelemetry.io/otel/metric v1.39.0 h1:d1UzonvEZriVfpNKEVmHXbdf909uGTOQjA0HF0Ls5Q0= +go.opentelemetry.io/otel/metric v1.39.0/go.mod h1:jrZSWL33sD7bBxg1xjrqyDjnuzTUB0x1nBERXd7Ftcs= +go.opentelemetry.io/otel/sdk v1.39.0 h1:nMLYcjVsvdui1B/4FRkwjzoRVsMK8uL/cj0OyhKzt18= +go.opentelemetry.io/otel/sdk v1.39.0/go.mod h1:vDojkC4/jsTJsE+kh+LXYQlbL8CgrEcwmt1ENZszdJE= +go.opentelemetry.io/otel/sdk/metric v1.39.0 h1:cXMVVFVgsIf2YL6QkRF4Urbr/aMInf+2WKg+sEJTtB8= +go.opentelemetry.io/otel/sdk/metric v1.39.0/go.mod h1:xq9HEVH7qeX69/JnwEfp6fVq5wosJsY1mt4lLfYdVew= +go.opentelemetry.io/otel/trace v1.39.0 h1:2d2vfpEDmCJ5zVYz7ijaJdOF59xLomrvj7bjt6/qCJI= +go.opentelemetry.io/otel/trace v1.39.0/go.mod h1:88w4/PnZSazkGzz/w84VHpQafiU4EtqqlVdxWy+rNOA= +golang.org/x/net v0.51.0 h1:94R/GTO7mt3/4wIKpcR5gkGmRLOuE/2hNGeWq/GBIFo= +golang.org/x/net v0.51.0/go.mod h1:aamm+2QF5ogm02fjy5Bb7CQ0WMt1/WVM7FtyaTLlA9Y= +golang.org/x/sys v0.41.0 h1:Ivj+2Cp/ylzLiEU89QhWblYnOE9zerudt9Ftecq2C6k= +golang.org/x/sys v0.41.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= +golang.org/x/text v0.34.0 h1:oL/Qq0Kdaqxa1KbNeMKwQq0reLCCaFtqu2eNuSeNHbk= +golang.org/x/text v0.34.0/go.mod h1:homfLqTYRFyVYemLBFl5GgL/DWEiH5wcsQ5gSh1yziA= gonum.org/v1/gonum v0.16.0 h1:5+ul4Swaf3ESvrOnidPp4GZbzf0mxVQpDCYUQE7OJfk= gonum.org/v1/gonum v0.16.0/go.mod h1:fef3am4MQ93R2HHpKnLk4/Tbh/s0+wqD5nfa6Pnwy4E= -google.golang.org/genproto/googleapis/rpc v0.0.0-20251022142026-3a174f9686a8 h1:M1rk8KBnUsBDg1oPGHNCxG4vc1f49epmTO7xscSajMk= -google.golang.org/genproto/googleapis/rpc v0.0.0-20251022142026-3a174f9686a8/go.mod h1:7i2o+ce6H/6BluujYR+kqX3GKH+dChPTQU19wjRPiGk= -google.golang.org/grpc v1.77.0 h1:wVVY6/8cGA6vvffn+wWK5ToddbgdU3d8MNENr4evgXM= -google.golang.org/grpc v1.77.0/go.mod h1:z0BY1iVj0q8E1uSQCjL9cppRj+gnZjzDnzV0dHhrNig= -google.golang.org/protobuf v1.36.10 h1:AYd7cD/uASjIL6Q9LiTjz8JLcrh/88q5UObnmY3aOOE= -google.golang.org/protobuf v1.36.10/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= +google.golang.org/genproto/googleapis/rpc v0.0.0-20251222181119-0a764e51fe1b h1:Mv8VFug0MP9e5vUxfBcE3vUkV6CImK3cMNMIDFjmzxU= +google.golang.org/genproto/googleapis/rpc v0.0.0-20251222181119-0a764e51fe1b/go.mod h1:j9x/tPzZkyxcgEFkiKEEGxfvyumM01BEtsW8xzOahRQ= +google.golang.org/grpc v1.79.3 h1:sybAEdRIEtvcD68Gx7dmnwjZKlyfuc61Dyo9pGXXkKE= +google.golang.org/grpc v1.79.3/go.mod h1:KmT0Kjez+0dde/v2j9vzwoAScgEPx/Bw1CYChhHLrHQ= +google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE= +google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= diff --git a/extension/extensionmiddleware/metadata.yaml b/extension/extensionmiddleware/metadata.yaml new file mode 100644 index 000000000000..864b10774c0a --- /dev/null +++ b/extension/extensionmiddleware/metadata.yaml @@ -0,0 +1,6 @@ +type: extensionmiddleware +github_project: open-telemetry/opentelemetry-collector + +status: + disable_codecov_badge: true + class: pkg diff --git a/extension/extensionmiddleware/server.go b/extension/extensionmiddleware/server.go index 6fa9ca1ae609..03e5a0f4e540 100644 --- a/extension/extensionmiddleware/server.go +++ b/extension/extensionmiddleware/server.go @@ -4,6 +4,7 @@ package extensionmiddleware // import "go.opentelemetry.io/collector/extension/extensionmiddleware" import ( + "context" "net/http" "google.golang.org/grpc" @@ -12,35 +13,41 @@ import ( // HTTPServer defines the interface for HTTP server middleware extensions. type HTTPServer interface { // GetHTTPHandler wraps the provided base http.Handler. - GetHTTPHandler(base http.Handler) (http.Handler, error) + GetHTTPHandler(_ context.Context) (WrapHTTPHandlerFunc, error) } // GRPCServer defines the interface for gRPC server middleware extensions. type GRPCServer interface { // GetGRPCServerOptions returns options for a gRPC server. - GetGRPCServerOptions() ([]grpc.ServerOption, error) + GetGRPCServerOptions(context.Context) ([]grpc.ServerOption, error) } var _ HTTPServer = (*GetHTTPHandlerFunc)(nil) // GetHTTPHandlerFunc is a function that implements HTTPServer. -type GetHTTPHandlerFunc func(base http.Handler) (http.Handler, error) +type GetHTTPHandlerFunc func(_ context.Context) (WrapHTTPHandlerFunc, error) -func (f GetHTTPHandlerFunc) GetHTTPHandler(base http.Handler) (http.Handler, error) { +func (f GetHTTPHandlerFunc) GetHTTPHandler(ctx context.Context) (WrapHTTPHandlerFunc, error) { if f == nil { - return base, nil + return func(_ context.Context, h http.Handler) (http.Handler, error) { + return h, nil + }, nil } - return f(base) + return f(ctx) } var _ GRPCServer = (*GetGRPCServerOptionsFunc)(nil) // GetGRPCServerOptionsFunc is a function that implements GRPCServer. -type GetGRPCServerOptionsFunc func() ([]grpc.ServerOption, error) +type GetGRPCServerOptionsFunc func(context.Context) ([]grpc.ServerOption, error) -func (f GetGRPCServerOptionsFunc) GetGRPCServerOptions() ([]grpc.ServerOption, error) { +func (f GetGRPCServerOptionsFunc) GetGRPCServerOptions(ctx context.Context) ([]grpc.ServerOption, error) { if f == nil { return nil, nil } - return f() + return f(ctx) } + +// WrapHTTPHandlerFunc is called to initialize a new instance of +// HTTP server middleware at runtime. +type WrapHTTPHandlerFunc = func(context.Context, http.Handler) (http.Handler, error) diff --git a/extension/extensionmiddleware/server_test.go b/extension/extensionmiddleware/server_test.go index eee61f5410e7..b1e26ad611d7 100644 --- a/extension/extensionmiddleware/server_test.go +++ b/extension/extensionmiddleware/server_test.go @@ -15,13 +15,18 @@ import ( ) func TestGetHTTPHandlerFunc(t *testing.T) { + testctx := context.Background() + t.Run("nil_function", func(t *testing.T) { var f GetHTTPHandlerFunc baseHandler := http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) { w.WriteHeader(http.StatusNoContent) }) - handler, err := f.GetHTTPHandler(baseHandler) + hfunc, err := f.GetHTTPHandler(testctx) + require.NoError(t, err) + + handler, err := hfunc(testctx, baseHandler) require.NoError(t, err) rr := httptest.NewRecorder() @@ -35,16 +40,21 @@ func TestGetHTTPHandlerFunc(t *testing.T) { w.WriteHeader(http.StatusOK) }) - f := GetHTTPHandlerFunc(func(base http.Handler) (http.Handler, error) { - return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - called = true - base.ServeHTTP(w, r) - }), nil + f := GetHTTPHandlerFunc(func(_ context.Context) (WrapHTTPHandlerFunc, error) { + return func(_ context.Context, base http.Handler) (http.Handler, error) { + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + called = true + base.ServeHTTP(w, r) + }), nil + }, nil }) - handler, err := f.GetHTTPHandler(baseHandler) + hfunc, err := f.GetHTTPHandler(testctx) + require.NoError(t, err) + require.NotNil(t, hfunc) + + handler, err := hfunc(testctx, baseHandler) require.NoError(t, err) - require.NotNil(t, handler) rr := httptest.NewRecorder() handler.ServeHTTP(rr, httptest.NewRequest(http.MethodGet, "/", http.NoBody)) @@ -54,21 +64,27 @@ func TestGetHTTPHandlerFunc(t *testing.T) { t.Run("returns_error", func(t *testing.T) { expectedErr := errors.New("test error") - f := GetHTTPHandlerFunc(func(http.Handler) (http.Handler, error) { + f := GetHTTPHandlerFunc(func(context.Context) (WrapHTTPHandlerFunc, error) { return nil, expectedErr }) - baseHandler := http.HandlerFunc(func(http.ResponseWriter, *http.Request) {}) - handler, err := f.GetHTTPHandler(baseHandler) + hfunc, err := f.GetHTTPHandler(testctx) require.Equal(t, expectedErr, err) - require.Nil(t, handler) + require.Nil(t, hfunc) }) } func TestGetGRPCServerOptionsFunc(t *testing.T) { + type testCtx struct{} + var ( + key = testCtx{} + value = "testval" + ) + testctx := context.WithValue(context.Background(), key, value) + t.Run("nil_function", func(t *testing.T) { var f GetGRPCServerOptionsFunc - opts, err := f.GetGRPCServerOptions() + opts, err := f.GetGRPCServerOptions(testctx) require.NoError(t, err) require.Nil(t, opts) }) @@ -84,22 +100,24 @@ func TestGetGRPCServerOptionsFunc(t *testing.T) { } expectedOpts := []grpc.ServerOption{grpc.UnaryInterceptor(interceptor)} - f := GetGRPCServerOptionsFunc(func() ([]grpc.ServerOption, error) { + f := GetGRPCServerOptionsFunc(func(ctx context.Context) ([]grpc.ServerOption, error) { + require.Equal(t, ctx.Value(key), value) return expectedOpts, nil }) - opts, err := f.GetGRPCServerOptions() + opts, err := f.GetGRPCServerOptions(testctx) require.NoError(t, err) require.Equal(t, expectedOpts, opts) }) t.Run("returns_error", func(t *testing.T) { expectedErr := errors.New("test error") - f := GetGRPCServerOptionsFunc(func() ([]grpc.ServerOption, error) { + f := GetGRPCServerOptionsFunc(func(ctx context.Context) ([]grpc.ServerOption, error) { + require.Equal(t, ctx.Value(key), value) return nil, expectedErr }) - opts, err := f.GetGRPCServerOptions() + opts, err := f.GetGRPCServerOptions(testctx) require.Equal(t, expectedErr, err) require.Nil(t, opts) }) diff --git a/extension/extensiontest/go.mod b/extension/extensiontest/go.mod index 31985c2632cd..f65216eff598 100644 --- a/extension/extensiontest/go.mod +++ b/extension/extensiontest/go.mod @@ -1,15 +1,15 @@ module go.opentelemetry.io/collector/extension/extensiontest -go 1.24.0 +go 1.25.0 replace go.opentelemetry.io/collector/extension => .. require ( github.com/google/uuid v1.6.0 github.com/stretchr/testify v1.11.1 - go.opentelemetry.io/collector/component v1.46.0 - go.opentelemetry.io/collector/component/componenttest v0.140.0 - go.opentelemetry.io/collector/extension v1.46.0 + go.opentelemetry.io/collector/component v1.54.0 + go.opentelemetry.io/collector/component/componenttest v0.148.0 + go.opentelemetry.io/collector/extension v1.54.0 ) require ( @@ -17,22 +17,23 @@ require ( github.com/davecgh/go-spew v1.1.1 // indirect github.com/go-logr/logr v1.4.3 // indirect github.com/go-logr/stdr v1.2.2 // indirect - github.com/hashicorp/go-version v1.7.0 // indirect + github.com/hashicorp/go-version v1.8.0 // indirect github.com/json-iterator/go v1.1.12 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee // indirect github.com/pmezard/go-difflib v1.0.0 // indirect go.opentelemetry.io/auto/sdk v1.2.1 // indirect - go.opentelemetry.io/collector/featuregate v1.46.0 // indirect - go.opentelemetry.io/collector/pdata v1.46.0 // indirect - go.opentelemetry.io/otel v1.40.0 // indirect - go.opentelemetry.io/otel/metric v1.40.0 // indirect + go.opentelemetry.io/collector/featuregate v1.54.0 // indirect + go.opentelemetry.io/collector/internal/componentalias v0.148.0 // indirect + go.opentelemetry.io/collector/pdata v1.54.0 // indirect + go.opentelemetry.io/otel v1.42.0 // indirect + go.opentelemetry.io/otel/metric v1.42.0 // indirect go.opentelemetry.io/otel/sdk v1.40.0 // indirect go.opentelemetry.io/otel/sdk/metric v1.40.0 // indirect - go.opentelemetry.io/otel/trace v1.40.0 // indirect + go.opentelemetry.io/otel/trace v1.42.0 // indirect go.uber.org/multierr v1.11.0 // indirect go.uber.org/zap v1.27.1 // indirect - golang.org/x/sys v0.40.0 // indirect + golang.org/x/sys v0.41.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) @@ -45,3 +46,5 @@ replace go.opentelemetry.io/collector/component/componenttest => ../../component replace go.opentelemetry.io/collector/featuregate => ../../featuregate replace go.opentelemetry.io/collector/internal/testutil => ../../internal/testutil + +replace go.opentelemetry.io/collector/internal/componentalias => ../../internal/componentalias diff --git a/extension/extensiontest/go.sum b/extension/extensiontest/go.sum index c102571e7869..43bdbeb8d219 100644 --- a/extension/extensiontest/go.sum +++ b/extension/extensiontest/go.sum @@ -13,8 +13,8 @@ github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/hashicorp/go-version v1.7.0 h1:5tqGy27NaOTB8yJKUZELlFAS/LTKJkrmONwQKeRZfjY= -github.com/hashicorp/go-version v1.7.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= +github.com/hashicorp/go-version v1.8.0 h1:KAkNb1HAiZd1ukkxDFGmokVZe1Xy9HG6NUp+bPle2i4= +github.com/hashicorp/go-version v1.8.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= @@ -37,32 +37,32 @@ github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64= go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y= -go.opentelemetry.io/otel v1.40.0 h1:oA5YeOcpRTXq6NN7frwmwFR0Cn3RhTVZvXsP4duvCms= -go.opentelemetry.io/otel v1.40.0/go.mod h1:IMb+uXZUKkMXdPddhwAHm6UfOwJyh4ct1ybIlV14J0g= -go.opentelemetry.io/otel/metric v1.40.0 h1:rcZe317KPftE2rstWIBitCdVp89A2HqjkxR3c11+p9g= -go.opentelemetry.io/otel/metric v1.40.0/go.mod h1:ib/crwQH7N3r5kfiBZQbwrTge743UDc7DTFVZrrXnqc= +go.opentelemetry.io/otel v1.42.0 h1:lSQGzTgVR3+sgJDAU/7/ZMjN9Z+vUip7leaqBKy4sho= +go.opentelemetry.io/otel v1.42.0/go.mod h1:lJNsdRMxCUIWuMlVJWzecSMuNjE7dOYyWlqOXWkdqCc= +go.opentelemetry.io/otel/metric v1.42.0 h1:2jXG+3oZLNXEPfNmnpxKDeZsFI5o4J+nz6xUlaFdF/4= +go.opentelemetry.io/otel/metric v1.42.0/go.mod h1:RlUN/7vTU7Ao/diDkEpQpnz3/92J9ko05BIwxYa2SSI= go.opentelemetry.io/otel/sdk v1.40.0 h1:KHW/jUzgo6wsPh9At46+h4upjtccTmuZCFAc9OJ71f8= go.opentelemetry.io/otel/sdk v1.40.0/go.mod h1:Ph7EFdYvxq72Y8Li9q8KebuYUr2KoeyHx0DRMKrYBUE= go.opentelemetry.io/otel/sdk/metric v1.40.0 h1:mtmdVqgQkeRxHgRv4qhyJduP3fYJRMX4AtAlbuWdCYw= go.opentelemetry.io/otel/sdk/metric v1.40.0/go.mod h1:4Z2bGMf0KSK3uRjlczMOeMhKU2rhUqdWNoKcYrtcBPg= -go.opentelemetry.io/otel/trace v1.40.0 h1:WA4etStDttCSYuhwvEa8OP8I5EWu24lkOzp+ZYblVjw= -go.opentelemetry.io/otel/trace v1.40.0/go.mod h1:zeAhriXecNGP/s2SEG3+Y8X9ujcJOTqQ5RgdEJcawiA= -go.opentelemetry.io/proto/slim/otlp v1.9.0 h1:fPVMv8tP3TrsqlkH1HWYUpbCY9cAIemx184VGkS6vlE= -go.opentelemetry.io/proto/slim/otlp v1.9.0/go.mod h1:xXdeJJ90Gqyll+orzUkY4bOd2HECo5JofeoLpymVqdI= -go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.2.0 h1:o13nadWDNkH/quoDomDUClnQBpdQQ2Qqv0lQBjIXjE8= -go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.2.0/go.mod h1:Gyb6Xe7FTi/6xBHwMmngGoHqL0w29Y4eW8TGFzpefGA= -go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.2.0 h1:EiUYvtwu6PMrMHVjcPfnsG3v+ajPkbUeH+IL93+QYyk= -go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.2.0/go.mod h1:mUUHKFiN2SST3AhJ8XhJxEoeVW12oqfXog0Bo8W3Ec4= +go.opentelemetry.io/otel/trace v1.42.0 h1:OUCgIPt+mzOnaUTpOQcBiM/PLQ/Op7oq6g4LenLmOYY= +go.opentelemetry.io/otel/trace v1.42.0/go.mod h1:f3K9S+IFqnumBkKhRJMeaZeNk9epyhnCmQh/EysQCdc= +go.opentelemetry.io/proto/slim/otlp v1.10.0 h1:iR97Vs/ZDR+y9TfuP9b1XBtdPWeC+OMslIBmhcLU7jM= +go.opentelemetry.io/proto/slim/otlp v1.10.0/go.mod h1:lV9250stpjYLPNA5viFabIgP2QlUGRT1GdTgAf8SIUk= +go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.3.0 h1:RUF5rO0hAlgiJt1fzQVzcVs3vZVNHIcMLgOgG4rWNcQ= +go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.3.0/go.mod h1:I89cynRj8y+383o7tEQVg2SVA6SRgDVIouWPUVXjx0U= +go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.3.0 h1:CQvJSldHRUN6Z8jsUeYv8J0lXRvygALXIzsmAeCcZE0= +go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.3.0/go.mod h1:xSQ+mEfJe/GjK1LXEyVOoSI1N9JV9ZI923X5kup43W4= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= go.uber.org/zap v1.27.1 h1:08RqriUEv8+ArZRYSTXy1LeBScaMpVSTBhCeaZYfMYc= go.uber.org/zap v1.27.1/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= -golang.org/x/sys v0.40.0 h1:DBZZqJ2Rkml6QMQsZywtnjnnGvHza6BTfYFWY9kjEWQ= -golang.org/x/sys v0.40.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= -google.golang.org/protobuf v1.36.10 h1:AYd7cD/uASjIL6Q9LiTjz8JLcrh/88q5UObnmY3aOOE= -google.golang.org/protobuf v1.36.10/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= +golang.org/x/sys v0.41.0 h1:Ivj+2Cp/ylzLiEU89QhWblYnOE9zerudt9Ftecq2C6k= +golang.org/x/sys v0.41.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= +google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE= +google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= diff --git a/extension/extensiontest/metadata.yaml b/extension/extensiontest/metadata.yaml new file mode 100644 index 000000000000..ab266caeb1a2 --- /dev/null +++ b/extension/extensiontest/metadata.yaml @@ -0,0 +1,6 @@ +type: extension/extensiontest +github_project: open-telemetry/opentelemetry-collector + +status: + disable_codecov_badge: true + class: pkg diff --git a/extension/go.mod b/extension/go.mod index dbe136552f03..1bd18c050563 100644 --- a/extension/go.mod +++ b/extension/go.mod @@ -1,26 +1,27 @@ module go.opentelemetry.io/collector/extension -go 1.24.0 +go 1.25.0 require ( github.com/stretchr/testify v1.11.1 - go.opentelemetry.io/collector/component v1.46.0 + go.opentelemetry.io/collector/component v1.54.0 + go.opentelemetry.io/collector/internal/componentalias v0.148.0 go.uber.org/goleak v1.3.0 ) require ( github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/davecgh/go-spew v1.1.1 // indirect - github.com/hashicorp/go-version v1.7.0 // indirect + github.com/hashicorp/go-version v1.8.0 // indirect github.com/json-iterator/go v1.1.12 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee // indirect github.com/pmezard/go-difflib v1.0.0 // indirect - go.opentelemetry.io/collector/featuregate v1.46.0 // indirect - go.opentelemetry.io/collector/pdata v1.46.0 // indirect - go.opentelemetry.io/otel v1.40.0 // indirect - go.opentelemetry.io/otel/metric v1.40.0 // indirect - go.opentelemetry.io/otel/trace v1.40.0 // indirect + go.opentelemetry.io/collector/featuregate v1.54.0 // indirect + go.opentelemetry.io/collector/pdata v1.54.0 // indirect + go.opentelemetry.io/otel v1.42.0 // indirect + go.opentelemetry.io/otel/metric v1.42.0 // indirect + go.opentelemetry.io/otel/trace v1.42.0 // indirect go.uber.org/multierr v1.11.0 // indirect go.uber.org/zap v1.27.1 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect @@ -32,4 +33,6 @@ replace go.opentelemetry.io/collector/pdata => ../pdata replace go.opentelemetry.io/collector/featuregate => ../featuregate +replace go.opentelemetry.io/collector/internal/componentalias => ../internal/componentalias + replace go.opentelemetry.io/collector/internal/testutil => ../internal/testutil diff --git a/extension/go.sum b/extension/go.sum index 37d6edbc3764..1abfd0c69894 100644 --- a/extension/go.sum +++ b/extension/go.sum @@ -10,8 +10,8 @@ github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= -github.com/hashicorp/go-version v1.7.0 h1:5tqGy27NaOTB8yJKUZELlFAS/LTKJkrmONwQKeRZfjY= -github.com/hashicorp/go-version v1.7.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= +github.com/hashicorp/go-version v1.8.0 h1:KAkNb1HAiZd1ukkxDFGmokVZe1Xy9HG6NUp+bPle2i4= +github.com/hashicorp/go-version v1.8.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= @@ -34,26 +34,26 @@ github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64= go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y= -go.opentelemetry.io/otel v1.40.0 h1:oA5YeOcpRTXq6NN7frwmwFR0Cn3RhTVZvXsP4duvCms= -go.opentelemetry.io/otel v1.40.0/go.mod h1:IMb+uXZUKkMXdPddhwAHm6UfOwJyh4ct1ybIlV14J0g= -go.opentelemetry.io/otel/metric v1.40.0 h1:rcZe317KPftE2rstWIBitCdVp89A2HqjkxR3c11+p9g= -go.opentelemetry.io/otel/metric v1.40.0/go.mod h1:ib/crwQH7N3r5kfiBZQbwrTge743UDc7DTFVZrrXnqc= -go.opentelemetry.io/otel/trace v1.40.0 h1:WA4etStDttCSYuhwvEa8OP8I5EWu24lkOzp+ZYblVjw= -go.opentelemetry.io/otel/trace v1.40.0/go.mod h1:zeAhriXecNGP/s2SEG3+Y8X9ujcJOTqQ5RgdEJcawiA= -go.opentelemetry.io/proto/slim/otlp v1.9.0 h1:fPVMv8tP3TrsqlkH1HWYUpbCY9cAIemx184VGkS6vlE= -go.opentelemetry.io/proto/slim/otlp v1.9.0/go.mod h1:xXdeJJ90Gqyll+orzUkY4bOd2HECo5JofeoLpymVqdI= -go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.2.0 h1:o13nadWDNkH/quoDomDUClnQBpdQQ2Qqv0lQBjIXjE8= -go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.2.0/go.mod h1:Gyb6Xe7FTi/6xBHwMmngGoHqL0w29Y4eW8TGFzpefGA= -go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.2.0 h1:EiUYvtwu6PMrMHVjcPfnsG3v+ajPkbUeH+IL93+QYyk= -go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.2.0/go.mod h1:mUUHKFiN2SST3AhJ8XhJxEoeVW12oqfXog0Bo8W3Ec4= +go.opentelemetry.io/otel v1.42.0 h1:lSQGzTgVR3+sgJDAU/7/ZMjN9Z+vUip7leaqBKy4sho= +go.opentelemetry.io/otel v1.42.0/go.mod h1:lJNsdRMxCUIWuMlVJWzecSMuNjE7dOYyWlqOXWkdqCc= +go.opentelemetry.io/otel/metric v1.42.0 h1:2jXG+3oZLNXEPfNmnpxKDeZsFI5o4J+nz6xUlaFdF/4= +go.opentelemetry.io/otel/metric v1.42.0/go.mod h1:RlUN/7vTU7Ao/diDkEpQpnz3/92J9ko05BIwxYa2SSI= +go.opentelemetry.io/otel/trace v1.42.0 h1:OUCgIPt+mzOnaUTpOQcBiM/PLQ/Op7oq6g4LenLmOYY= +go.opentelemetry.io/otel/trace v1.42.0/go.mod h1:f3K9S+IFqnumBkKhRJMeaZeNk9epyhnCmQh/EysQCdc= +go.opentelemetry.io/proto/slim/otlp v1.10.0 h1:iR97Vs/ZDR+y9TfuP9b1XBtdPWeC+OMslIBmhcLU7jM= +go.opentelemetry.io/proto/slim/otlp v1.10.0/go.mod h1:lV9250stpjYLPNA5viFabIgP2QlUGRT1GdTgAf8SIUk= +go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.3.0 h1:RUF5rO0hAlgiJt1fzQVzcVs3vZVNHIcMLgOgG4rWNcQ= +go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.3.0/go.mod h1:I89cynRj8y+383o7tEQVg2SVA6SRgDVIouWPUVXjx0U= +go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.3.0 h1:CQvJSldHRUN6Z8jsUeYv8J0lXRvygALXIzsmAeCcZE0= +go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.3.0/go.mod h1:xSQ+mEfJe/GjK1LXEyVOoSI1N9JV9ZI923X5kup43W4= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= go.uber.org/zap v1.27.1 h1:08RqriUEv8+ArZRYSTXy1LeBScaMpVSTBhCeaZYfMYc= go.uber.org/zap v1.27.1/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= -google.golang.org/protobuf v1.36.10 h1:AYd7cD/uASjIL6Q9LiTjz8JLcrh/88q5UObnmY3aOOE= -google.golang.org/protobuf v1.36.10/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= +google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE= +google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= diff --git a/extension/memorylimiterextension/README.md b/extension/memorylimiterextension/README.md index a54f0fea3db3..e6f2f1daa0d1 100644 --- a/extension/memorylimiterextension/README.md +++ b/extension/memorylimiterextension/README.md @@ -1,6 +1,5 @@ -# Memory Limiter Extension - +# Memory Limiter Extension | Status | | | ------------- |-----------| | Stability | [development] | @@ -14,6 +13,29 @@ The memory limiter extension is used to prevent out of memory situations on the collector. The extension will potentially replace the Memory Limiter Processor. It provides better guarantees from running out of memory as it will be used by the receivers to reject requests before converting them into OTLP. All the configurations -are the same as Memory Limiter Processor. The extension is under development and does nothing. +are the same as Memory Limiter Processor. + + +This extension can be used as an extension for all HTTP and gRPC receivers that +are configured through the standard `confighttp` and `configgrpc` libraries. For +example, to configure this extension in the OTLP receiver: + +``` +receivers: + otlp: + protocols: + grpc: + middlewares: + - id: memory_limiter + http: + middlewares: + - id: memory_limiter + +extensions: + memory_limiter: + check_interval: 1s + limit_percentage: 1 + spike_limit_percentage: 0.05 +``` see [memorylimiterprocessor](../../processor/memorylimiterprocessor/README.md) for additional details diff --git a/extension/memorylimiterextension/go.mod b/extension/memorylimiterextension/go.mod index afb62f7e60dc..6a5bfc47b1c8 100644 --- a/extension/memorylimiterextension/go.mod +++ b/extension/memorylimiterextension/go.mod @@ -1,56 +1,63 @@ module go.opentelemetry.io/collector/extension/memorylimiterextension -go 1.24.0 +go 1.25.0 require ( github.com/stretchr/testify v1.11.1 - go.opentelemetry.io/collector/component v1.46.0 - go.opentelemetry.io/collector/component/componenttest v0.140.0 - go.opentelemetry.io/collector/confmap v1.46.0 - go.opentelemetry.io/collector/extension v1.46.0 - go.opentelemetry.io/collector/extension/extensiontest v0.140.0 - go.opentelemetry.io/collector/internal/memorylimiter v0.140.0 + go.opentelemetry.io/collector/component v1.54.0 + go.opentelemetry.io/collector/component/componenttest v0.148.0 + go.opentelemetry.io/collector/confmap v1.54.0 + go.opentelemetry.io/collector/extension v1.54.0 + go.opentelemetry.io/collector/extension/extensionmiddleware v0.148.0 + go.opentelemetry.io/collector/extension/extensiontest v0.148.0 + go.opentelemetry.io/collector/internal/memorylimiter v0.148.0 go.uber.org/goleak v1.3.0 go.uber.org/zap v1.27.1 + google.golang.org/grpc v1.79.3 ) require ( github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/davecgh/go-spew v1.1.1 // indirect - github.com/ebitengine/purego v0.9.0 // indirect + github.com/ebitengine/purego v0.10.0 // indirect github.com/go-logr/logr v1.4.3 // indirect github.com/go-logr/stdr v1.2.2 // indirect github.com/go-ole/go-ole v1.2.6 // indirect - github.com/go-viper/mapstructure/v2 v2.4.0 // indirect + github.com/go-viper/mapstructure/v2 v2.5.0 // indirect github.com/gobwas/glob v0.2.3 // indirect github.com/google/uuid v1.6.0 // indirect - github.com/hashicorp/go-version v1.7.0 // indirect + github.com/hashicorp/go-version v1.8.0 // indirect github.com/json-iterator/go v1.1.12 // indirect github.com/knadh/koanf/maps v0.1.2 // indirect github.com/knadh/koanf/providers/confmap v1.0.0 // indirect - github.com/knadh/koanf/v2 v2.3.0 // indirect - github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 // indirect + github.com/knadh/koanf/v2 v2.3.3 // indirect + github.com/lufia/plan9stats v0.0.0-20251013123823-9fd1530e3ec3 // indirect github.com/mitchellh/copystructure v1.2.0 // indirect github.com/mitchellh/reflectwalk v1.0.2 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee // indirect github.com/pmezard/go-difflib v1.0.0 // indirect github.com/power-devops/perfstat v0.0.0-20240221224432-82ca36839d55 // indirect - github.com/shirou/gopsutil/v4 v4.25.10 // indirect - github.com/tklauser/go-sysconf v0.3.15 // indirect - github.com/tklauser/numcpus v0.10.0 // indirect + github.com/shirou/gopsutil/v4 v4.26.2 // indirect + github.com/tklauser/go-sysconf v0.3.16 // indirect + github.com/tklauser/numcpus v0.11.0 // indirect github.com/yusufpapurcu/wmi v1.2.4 // indirect go.opentelemetry.io/auto/sdk v1.2.1 // indirect - go.opentelemetry.io/collector/featuregate v1.46.0 // indirect - go.opentelemetry.io/collector/pdata v1.46.0 // indirect - go.opentelemetry.io/otel v1.40.0 // indirect - go.opentelemetry.io/otel/metric v1.40.0 // indirect + go.opentelemetry.io/collector/featuregate v1.54.0 // indirect + go.opentelemetry.io/collector/internal/componentalias v0.148.0 // indirect + go.opentelemetry.io/collector/pdata v1.54.0 // indirect + go.opentelemetry.io/otel v1.42.0 // indirect + go.opentelemetry.io/otel/metric v1.42.0 // indirect go.opentelemetry.io/otel/sdk v1.40.0 // indirect go.opentelemetry.io/otel/sdk/metric v1.40.0 // indirect - go.opentelemetry.io/otel/trace v1.40.0 // indirect + go.opentelemetry.io/otel/trace v1.42.0 // indirect go.uber.org/multierr v1.11.0 // indirect go.yaml.in/yaml/v3 v3.0.4 // indirect - golang.org/x/sys v0.40.0 // indirect + golang.org/x/net v0.51.0 // indirect + golang.org/x/sys v0.41.0 // indirect + golang.org/x/text v0.34.0 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20251222181119-0a764e51fe1b // indirect + google.golang.org/protobuf v1.36.11 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) @@ -71,3 +78,7 @@ replace go.opentelemetry.io/collector/extension/extensiontest => ../../extension replace go.opentelemetry.io/collector/featuregate => ../../featuregate replace go.opentelemetry.io/collector/internal/testutil => ../../internal/testutil + +replace go.opentelemetry.io/collector/extension/extensionmiddleware => ../../extension/extensionmiddleware + +replace go.opentelemetry.io/collector/internal/componentalias => ../../internal/componentalias diff --git a/extension/memorylimiterextension/go.sum b/extension/memorylimiterextension/go.sum index d725bedbee13..046ea8a2c234 100644 --- a/extension/memorylimiterextension/go.sum +++ b/extension/memorylimiterextension/go.sum @@ -3,8 +3,8 @@ github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XL github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/ebitengine/purego v0.9.0 h1:mh0zpKBIXDceC63hpvPuGLiJ8ZAa3DfrFTudmfi8A4k= -github.com/ebitengine/purego v0.9.0/go.mod h1:iIjxzd6CiRiOG0UyXP+V1+jWqUXVjPKLAI0mRfJZTmQ= +github.com/ebitengine/purego v0.10.0 h1:QIw4xfpWT6GWTzaW5XEKy3HXoqrJGx1ijYHzTF0/ISU= +github.com/ebitengine/purego v0.10.0/go.mod h1:iIjxzd6CiRiOG0UyXP+V1+jWqUXVjPKLAI0mRfJZTmQ= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI= github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= @@ -12,32 +12,33 @@ github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY= github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0= -github.com/go-viper/mapstructure/v2 v2.4.0 h1:EBsztssimR/CONLSZZ04E8qAkxNYq4Qp9LvH92wZUgs= -github.com/go-viper/mapstructure/v2 v2.4.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM= +github.com/go-viper/mapstructure/v2 v2.5.0 h1:vM5IJoUAy3d7zRSVtIwQgBj7BiWtMPfmPEgAXnvj1Ro= +github.com/go-viper/mapstructure/v2 v2.5.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM= github.com/gobwas/glob v0.2.3 h1:A4xDbljILXROh+kObIiy5kIaPYD8e96x1tgBhUI5J+Y= github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8= -github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= +github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/hashicorp/go-version v1.7.0 h1:5tqGy27NaOTB8yJKUZELlFAS/LTKJkrmONwQKeRZfjY= -github.com/hashicorp/go-version v1.7.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= +github.com/hashicorp/go-version v1.8.0 h1:KAkNb1HAiZd1ukkxDFGmokVZe1Xy9HG6NUp+bPle2i4= +github.com/hashicorp/go-version v1.8.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= github.com/knadh/koanf/maps v0.1.2 h1:RBfmAW5CnZT+PJ1CVc1QSJKf4Xu9kxfQgYVQSu8hpbo= github.com/knadh/koanf/maps v0.1.2/go.mod h1:npD/QZY3V6ghQDdcQzl1W4ICNVTkohC8E73eI2xW4yI= github.com/knadh/koanf/providers/confmap v1.0.0 h1:mHKLJTE7iXEys6deO5p6olAiZdG5zwp8Aebir+/EaRE= github.com/knadh/koanf/providers/confmap v1.0.0/go.mod h1:txHYHiI2hAtF0/0sCmcuol4IDcuQbKTybiB1nOcUo1A= -github.com/knadh/koanf/v2 v2.3.0 h1:Qg076dDRFHvqnKG97ZEsi9TAg2/nFTa9hCdcSa1lvlM= -github.com/knadh/koanf/v2 v2.3.0/go.mod h1:gRb40VRAbd4iJMYYD5IxZ6hfuopFcXBpc9bbQpZwo28= +github.com/knadh/koanf/v2 v2.3.3 h1:jLJC8XCRfLC7n4F+ZKKdBsbq1bfXTpuFhf4L7t94D94= +github.com/knadh/koanf/v2 v2.3.3/go.mod h1:gRb40VRAbd4iJMYYD5IxZ6hfuopFcXBpc9bbQpZwo28= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= -github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 h1:6E+4a0GO5zZEnZ81pIr0yLvtUWk2if982qA3F3QD6H4= -github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0/go.mod h1:zJYVVT2jmtg6P3p1VtQj7WsuWi/y4VnjVBn7F8KPB3I= +github.com/lufia/plan9stats v0.0.0-20251013123823-9fd1530e3ec3 h1:PwQumkgq4/acIiZhtifTV5OUqqiP82UAl0h87xj/l9k= +github.com/lufia/plan9stats v0.0.0-20251013123823-9fd1530e3ec3/go.mod h1:autxFIvghDt3jPTLoqZ9OZ7s9qTGNAWmYCjVFWPX/zg= github.com/mitchellh/copystructure v1.2.0 h1:vpKXTN4ewci03Vljg/q9QvCGUDttBOGBIa15WveJJGw= github.com/mitchellh/copystructure v1.2.0/go.mod h1:qLl+cE2AmVv+CoeAwDPye/v+N2HKCj9FbZEVFJRxO9s= github.com/mitchellh/reflectwalk v1.0.2 h1:G2LzWKi524PWgd3mLHV8Y5k7s6XUvT0Gef6zxSIeXaQ= @@ -54,36 +55,36 @@ github.com/power-devops/perfstat v0.0.0-20240221224432-82ca36839d55 h1:o4JXh1EVt github.com/power-devops/perfstat v0.0.0-20240221224432-82ca36839d55/go.mod h1:OmDBASR4679mdNQnz2pUhc2G8CO2JrUAVFDRBDP/hJE= github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ= github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc= -github.com/shirou/gopsutil/v4 v4.25.10 h1:at8lk/5T1OgtuCp+AwrDofFRjnvosn0nkN2OLQ6g8tA= -github.com/shirou/gopsutil/v4 v4.25.10/go.mod h1:+kSwyC8DRUD9XXEHCAFjK+0nuArFJM0lva+StQAcskM= +github.com/shirou/gopsutil/v4 v4.26.2 h1:X8i6sicvUFih4BmYIGT1m2wwgw2VG9YgrDTi7cIRGUI= +github.com/shirou/gopsutil/v4 v4.26.2/go.mod h1:LZ6ewCSkBqUpvSOf+LsTGnRinC6iaNUNMGBtDkJBaLQ= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U= github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= -github.com/tklauser/go-sysconf v0.3.15 h1:VE89k0criAymJ/Os65CSn1IXaol+1wrsFHEB8Ol49K4= -github.com/tklauser/go-sysconf v0.3.15/go.mod h1:Dmjwr6tYFIseJw7a3dRLJfsHAMXZ3nEnL/aZY+0IuI4= -github.com/tklauser/numcpus v0.10.0 h1:18njr6LDBk1zuna922MgdjQuJFjrdppsZG60sHGfjso= -github.com/tklauser/numcpus v0.10.0/go.mod h1:BiTKazU708GQTYF4mB+cmlpT2Is1gLk7XVuEeem8LsQ= +github.com/tklauser/go-sysconf v0.3.16 h1:frioLaCQSsF5Cy1jgRBrzr6t502KIIwQ0MArYICU0nA= +github.com/tklauser/go-sysconf v0.3.16/go.mod h1:/qNL9xxDhc7tx3HSRsLWNnuzbVfh3e7gh/BmM179nYI= +github.com/tklauser/numcpus v0.11.0 h1:nSTwhKH5e1dMNsCdVBukSZrURJRoHbSEQjdEbY+9RXw= +github.com/tklauser/numcpus v0.11.0/go.mod h1:z+LwcLq54uWZTX0u/bGobaV34u6V7KNlTZejzM6/3MQ= github.com/yusufpapurcu/wmi v1.2.4 h1:zFUKzehAFReQwLys1b/iSMl+JQGSCSjtVqQn9bBrPo0= github.com/yusufpapurcu/wmi v1.2.4/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0= go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64= go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y= -go.opentelemetry.io/otel v1.40.0 h1:oA5YeOcpRTXq6NN7frwmwFR0Cn3RhTVZvXsP4duvCms= -go.opentelemetry.io/otel v1.40.0/go.mod h1:IMb+uXZUKkMXdPddhwAHm6UfOwJyh4ct1ybIlV14J0g= -go.opentelemetry.io/otel/metric v1.40.0 h1:rcZe317KPftE2rstWIBitCdVp89A2HqjkxR3c11+p9g= -go.opentelemetry.io/otel/metric v1.40.0/go.mod h1:ib/crwQH7N3r5kfiBZQbwrTge743UDc7DTFVZrrXnqc= +go.opentelemetry.io/otel v1.42.0 h1:lSQGzTgVR3+sgJDAU/7/ZMjN9Z+vUip7leaqBKy4sho= +go.opentelemetry.io/otel v1.42.0/go.mod h1:lJNsdRMxCUIWuMlVJWzecSMuNjE7dOYyWlqOXWkdqCc= +go.opentelemetry.io/otel/metric v1.42.0 h1:2jXG+3oZLNXEPfNmnpxKDeZsFI5o4J+nz6xUlaFdF/4= +go.opentelemetry.io/otel/metric v1.42.0/go.mod h1:RlUN/7vTU7Ao/diDkEpQpnz3/92J9ko05BIwxYa2SSI= go.opentelemetry.io/otel/sdk v1.40.0 h1:KHW/jUzgo6wsPh9At46+h4upjtccTmuZCFAc9OJ71f8= go.opentelemetry.io/otel/sdk v1.40.0/go.mod h1:Ph7EFdYvxq72Y8Li9q8KebuYUr2KoeyHx0DRMKrYBUE= go.opentelemetry.io/otel/sdk/metric v1.40.0 h1:mtmdVqgQkeRxHgRv4qhyJduP3fYJRMX4AtAlbuWdCYw= go.opentelemetry.io/otel/sdk/metric v1.40.0/go.mod h1:4Z2bGMf0KSK3uRjlczMOeMhKU2rhUqdWNoKcYrtcBPg= -go.opentelemetry.io/otel/trace v1.40.0 h1:WA4etStDttCSYuhwvEa8OP8I5EWu24lkOzp+ZYblVjw= -go.opentelemetry.io/otel/trace v1.40.0/go.mod h1:zeAhriXecNGP/s2SEG3+Y8X9ujcJOTqQ5RgdEJcawiA= -go.opentelemetry.io/proto/slim/otlp v1.9.0 h1:fPVMv8tP3TrsqlkH1HWYUpbCY9cAIemx184VGkS6vlE= -go.opentelemetry.io/proto/slim/otlp v1.9.0/go.mod h1:xXdeJJ90Gqyll+orzUkY4bOd2HECo5JofeoLpymVqdI= -go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.2.0 h1:o13nadWDNkH/quoDomDUClnQBpdQQ2Qqv0lQBjIXjE8= -go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.2.0/go.mod h1:Gyb6Xe7FTi/6xBHwMmngGoHqL0w29Y4eW8TGFzpefGA= -go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.2.0 h1:EiUYvtwu6PMrMHVjcPfnsG3v+ajPkbUeH+IL93+QYyk= -go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.2.0/go.mod h1:mUUHKFiN2SST3AhJ8XhJxEoeVW12oqfXog0Bo8W3Ec4= +go.opentelemetry.io/otel/trace v1.42.0 h1:OUCgIPt+mzOnaUTpOQcBiM/PLQ/Op7oq6g4LenLmOYY= +go.opentelemetry.io/otel/trace v1.42.0/go.mod h1:f3K9S+IFqnumBkKhRJMeaZeNk9epyhnCmQh/EysQCdc= +go.opentelemetry.io/proto/slim/otlp v1.10.0 h1:iR97Vs/ZDR+y9TfuP9b1XBtdPWeC+OMslIBmhcLU7jM= +go.opentelemetry.io/proto/slim/otlp v1.10.0/go.mod h1:lV9250stpjYLPNA5viFabIgP2QlUGRT1GdTgAf8SIUk= +go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.3.0 h1:RUF5rO0hAlgiJt1fzQVzcVs3vZVNHIcMLgOgG4rWNcQ= +go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.3.0/go.mod h1:I89cynRj8y+383o7tEQVg2SVA6SRgDVIouWPUVXjx0U= +go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.3.0 h1:CQvJSldHRUN6Z8jsUeYv8J0lXRvygALXIzsmAeCcZE0= +go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.3.0/go.mod h1:xSQ+mEfJe/GjK1LXEyVOoSI1N9JV9ZI923X5kup43W4= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= @@ -92,13 +93,22 @@ go.uber.org/zap v1.27.1 h1:08RqriUEv8+ArZRYSTXy1LeBScaMpVSTBhCeaZYfMYc= go.uber.org/zap v1.27.1/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc= go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg= +golang.org/x/net v0.51.0 h1:94R/GTO7mt3/4wIKpcR5gkGmRLOuE/2hNGeWq/GBIFo= +golang.org/x/net v0.51.0/go.mod h1:aamm+2QF5ogm02fjy5Bb7CQ0WMt1/WVM7FtyaTLlA9Y= golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201204225414-ed752295db88/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.40.0 h1:DBZZqJ2Rkml6QMQsZywtnjnnGvHza6BTfYFWY9kjEWQ= -golang.org/x/sys v0.40.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= -golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -google.golang.org/protobuf v1.36.10 h1:AYd7cD/uASjIL6Q9LiTjz8JLcrh/88q5UObnmY3aOOE= -google.golang.org/protobuf v1.36.10/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= +golang.org/x/sys v0.41.0 h1:Ivj+2Cp/ylzLiEU89QhWblYnOE9zerudt9Ftecq2C6k= +golang.org/x/sys v0.41.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= +golang.org/x/text v0.34.0 h1:oL/Qq0Kdaqxa1KbNeMKwQq0reLCCaFtqu2eNuSeNHbk= +golang.org/x/text v0.34.0/go.mod h1:homfLqTYRFyVYemLBFl5GgL/DWEiH5wcsQ5gSh1yziA= +gonum.org/v1/gonum v0.16.0 h1:5+ul4Swaf3ESvrOnidPp4GZbzf0mxVQpDCYUQE7OJfk= +gonum.org/v1/gonum v0.16.0/go.mod h1:fef3am4MQ93R2HHpKnLk4/Tbh/s0+wqD5nfa6Pnwy4E= +google.golang.org/genproto/googleapis/rpc v0.0.0-20251222181119-0a764e51fe1b h1:Mv8VFug0MP9e5vUxfBcE3vUkV6CImK3cMNMIDFjmzxU= +google.golang.org/genproto/googleapis/rpc v0.0.0-20251222181119-0a764e51fe1b/go.mod h1:j9x/tPzZkyxcgEFkiKEEGxfvyumM01BEtsW8xzOahRQ= +google.golang.org/grpc v1.79.3 h1:sybAEdRIEtvcD68Gx7dmnwjZKlyfuc61Dyo9pGXXkKE= +google.golang.org/grpc v1.79.3/go.mod h1:KmT0Kjez+0dde/v2j9vzwoAScgEPx/Bw1CYChhHLrHQ= +google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE= +google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= diff --git a/extension/memorylimiterextension/memorylimiter.go b/extension/memorylimiterextension/memorylimiter.go index 4986243ce10b..3a5c26300798 100644 --- a/extension/memorylimiterextension/memorylimiter.go +++ b/extension/memorylimiterextension/memorylimiter.go @@ -5,13 +5,23 @@ package memorylimiterextension // import "go.opentelemetry.io/collector/extensio import ( "context" + "net/http" "go.uber.org/zap" + "google.golang.org/grpc" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" "go.opentelemetry.io/collector/component" + "go.opentelemetry.io/collector/extension/extensionmiddleware" "go.opentelemetry.io/collector/internal/memorylimiter" ) +var ( + _ extensionmiddleware.GRPCServer = (*memoryLimiterExtension)(nil) + _ extensionmiddleware.HTTPServer = (*memoryLimiterExtension)(nil) +) + type memoryLimiterExtension struct { memLimiter *memorylimiter.MemoryLimiter } @@ -38,3 +48,37 @@ func (ml *memoryLimiterExtension) Shutdown(ctx context.Context) error { func (ml *memoryLimiterExtension) MustRefuse() bool { return ml.memLimiter.MustRefuse() } + +// GetHTTPHandler implements extensionmiddleware.HTTPServer +func (ml *memoryLimiterExtension) GetHTTPHandler(_ context.Context) (extensionmiddleware.WrapHTTPHandlerFunc, error) { + return ml.wrapHTTPHandler, nil +} + +func (ml *memoryLimiterExtension) wrapHTTPHandler(_ context.Context, base http.Handler) (http.Handler, error) { + return http.HandlerFunc(func(resp http.ResponseWriter, req *http.Request) { + if ml.MustRefuse() { + http.Error(resp, http.StatusText(http.StatusTooManyRequests), http.StatusTooManyRequests) + return + } + base.ServeHTTP(resp, req) + }), nil +} + +func (ml *memoryLimiterExtension) GetGRPCServerOptions(_ context.Context) ([]grpc.ServerOption, error) { + return []grpc.ServerOption{ + grpc.ChainUnaryInterceptor( + func(ctx context.Context, req any, _ *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (resp any, err error) { + if ml.MustRefuse() { + return nil, status.Errorf(codes.ResourceExhausted, "RESOURCE_EXHAUSTED") + } + return handler(ctx, req) + }), + grpc.ChainStreamInterceptor( + func(srv any, ss grpc.ServerStream, _ *grpc.StreamServerInfo, handler grpc.StreamHandler) error { + if ml.MustRefuse() { + return status.Errorf(codes.ResourceExhausted, "RESOURCE_EXHAUSTED") + } + return handler(srv, ss) + }), + }, nil +} diff --git a/extension/memorylimiterextension/metadata.yaml b/extension/memorylimiterextension/metadata.yaml index d22c83dcb937..e63d18b64ac0 100644 --- a/extension/memorylimiterextension/metadata.yaml +++ b/extension/memorylimiterextension/metadata.yaml @@ -1,3 +1,4 @@ +display_name: Memory Limiter Extension type: memory_limiter github_project: open-telemetry/opentelemetry-collector diff --git a/extension/metadata.yaml b/extension/metadata.yaml new file mode 100644 index 000000000000..8113f669af6b --- /dev/null +++ b/extension/metadata.yaml @@ -0,0 +1,6 @@ +type: extension +github_project: open-telemetry/opentelemetry-collector + +status: + disable_codecov_badge: true + class: pkg diff --git a/extension/xextension/extension.go b/extension/xextension/extension.go new file mode 100644 index 000000000000..1b9c7849ad16 --- /dev/null +++ b/extension/xextension/extension.go @@ -0,0 +1,51 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +package xextension // import "go.opentelemetry.io/collector/extension/xextension" + +import ( + "go.opentelemetry.io/collector/component" + "go.opentelemetry.io/collector/extension" + "go.opentelemetry.io/collector/internal/componentalias" +) + +type Factory interface { + extension.Factory +} + +type FactoryOption interface { + applyOption(o *factory) +} + +type factoryOptionFunc func(*factory) + +func (f factoryOptionFunc) applyOption(o *factory) { + f(o) +} + +type factory struct { + extension.Factory + componentalias.TypeAliasHolder +} + +func WithDeprecatedTypeAlias(alias component.Type) FactoryOption { + return factoryOptionFunc(func(o *factory) { + o.SetDeprecatedAlias(alias) + }) +} + +func NewFactory( + cfgType component.Type, + createDefaultConfig component.CreateDefaultConfigFunc, + createServiceExtension extension.CreateFunc, + sl component.StabilityLevel, + options ...FactoryOption, +) Factory { + f := &factory{TypeAliasHolder: componentalias.NewTypeAliasHolder()} + for _, opt := range options { + opt.applyOption(f) + } + f.Factory = extension.NewFactory(cfgType, createDefaultConfig, createServiceExtension, sl) + f.Factory.(componentalias.TypeAliasHolder).SetDeprecatedAlias(f.DeprecatedAlias()) + return f +} diff --git a/extension/xextension/extension_test.go b/extension/xextension/extension_test.go new file mode 100644 index 000000000000..a006582e1d68 --- /dev/null +++ b/extension/xextension/extension_test.go @@ -0,0 +1,60 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +package xextension + +import ( + "context" + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + + "go.opentelemetry.io/collector/component" + "go.opentelemetry.io/collector/component/componenttest" + "go.opentelemetry.io/collector/extension" +) + +type nopExtension struct { + component.StartFunc + component.ShutdownFunc +} + +func TestWithDeprecatedTypeAlias(t *testing.T) { + originalType := component.MustNewType("original") + aliasType := component.MustNewType("alias") + nopExtensionInstance := new(nopExtension) + + factory := NewFactory( + originalType, + func() component.Config { return &struct{}{} }, + func(context.Context, extension.Settings, component.Config) (extension.Extension, error) { + return nopExtensionInstance, nil + }, + component.StabilityLevelAlpha, + WithDeprecatedTypeAlias(aliasType), + ) + + assert.Equal(t, originalType, factory.Type()) + + ext, err := factory.Create(context.Background(), extension.Settings{ + ID: component.NewID(originalType), + TelemetrySettings: componenttest.NewNopTelemetrySettings(), + }, factory.CreateDefaultConfig()) + require.NoError(t, err) + require.NotNil(t, ext) + + ext, err = factory.Create(context.Background(), extension.Settings{ + ID: component.NewID(aliasType), + TelemetrySettings: componenttest.NewNopTelemetrySettings(), + }, factory.CreateDefaultConfig()) + require.NoError(t, err) + require.NotNil(t, ext) + + ext, err = factory.Create(context.Background(), extension.Settings{ + ID: component.NewID(component.MustNewType("wrong")), + TelemetrySettings: componenttest.NewNopTelemetrySettings(), + }, factory.CreateDefaultConfig()) + require.Error(t, err) + require.Nil(t, ext) +} diff --git a/extension/xextension/go.mod b/extension/xextension/go.mod index e8a7ab58acb3..845e30d02c80 100644 --- a/extension/xextension/go.mod +++ b/extension/xextension/go.mod @@ -1,25 +1,38 @@ module go.opentelemetry.io/collector/extension/xextension -go 1.24.0 +go 1.25.0 require ( - go.opentelemetry.io/collector/component v1.46.0 - go.opentelemetry.io/collector/extension v1.46.0 + github.com/stretchr/testify v1.11.1 + go.opentelemetry.io/collector/component v1.54.0 + go.opentelemetry.io/collector/component/componenttest v0.148.0 + go.opentelemetry.io/collector/extension v1.54.0 + go.opentelemetry.io/collector/internal/componentalias v0.148.0 ) require ( github.com/cespare/xxhash/v2 v2.3.0 // indirect - github.com/hashicorp/go-version v1.7.0 // indirect + github.com/davecgh/go-spew v1.1.1 // indirect + github.com/go-logr/logr v1.4.3 // indirect + github.com/go-logr/stdr v1.2.2 // indirect + github.com/google/uuid v1.6.0 // indirect + github.com/hashicorp/go-version v1.8.0 // indirect github.com/json-iterator/go v1.1.12 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee // indirect - go.opentelemetry.io/collector/featuregate v1.46.0 // indirect - go.opentelemetry.io/collector/pdata v1.46.0 // indirect - go.opentelemetry.io/otel v1.40.0 // indirect - go.opentelemetry.io/otel/metric v1.40.0 // indirect - go.opentelemetry.io/otel/trace v1.40.0 // indirect + github.com/pmezard/go-difflib v1.0.0 // indirect + go.opentelemetry.io/auto/sdk v1.2.1 // indirect + go.opentelemetry.io/collector/featuregate v1.54.0 // indirect + go.opentelemetry.io/collector/pdata v1.54.0 // indirect + go.opentelemetry.io/otel v1.42.0 // indirect + go.opentelemetry.io/otel/metric v1.42.0 // indirect + go.opentelemetry.io/otel/sdk v1.40.0 // indirect + go.opentelemetry.io/otel/sdk/metric v1.40.0 // indirect + go.opentelemetry.io/otel/trace v1.42.0 // indirect go.uber.org/multierr v1.11.0 // indirect go.uber.org/zap v1.27.1 // indirect + golang.org/x/sys v0.41.0 // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect ) replace go.opentelemetry.io/collector/extension => ../ @@ -31,3 +44,7 @@ replace go.opentelemetry.io/collector/pdata => ../../pdata replace go.opentelemetry.io/collector/featuregate => ../../featuregate replace go.opentelemetry.io/collector/internal/testutil => ../../internal/testutil + +replace go.opentelemetry.io/collector/internal/componentalias => ../../internal/componentalias + +replace go.opentelemetry.io/collector/component/componenttest => ../../component/componenttest diff --git a/extension/xextension/go.sum b/extension/xextension/go.sum index 55f5e17e95dd..43bdbeb8d219 100644 --- a/extension/xextension/go.sum +++ b/extension/xextension/go.sum @@ -3,6 +3,7 @@ github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XL github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI= github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= @@ -10,10 +11,16 @@ github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= -github.com/hashicorp/go-version v1.7.0 h1:5tqGy27NaOTB8yJKUZELlFAS/LTKJkrmONwQKeRZfjY= -github.com/hashicorp/go-version v1.7.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= +github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= +github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/hashicorp/go-version v1.8.0 h1:KAkNb1HAiZd1ukkxDFGmokVZe1Xy9HG6NUp+bPle2i4= +github.com/hashicorp/go-version v1.8.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= +github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= +github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= +github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= +github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= @@ -22,31 +29,42 @@ github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee h1:W5t00kpgFd github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ= +github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U= github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64= go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y= -go.opentelemetry.io/otel v1.40.0 h1:oA5YeOcpRTXq6NN7frwmwFR0Cn3RhTVZvXsP4duvCms= -go.opentelemetry.io/otel v1.40.0/go.mod h1:IMb+uXZUKkMXdPddhwAHm6UfOwJyh4ct1ybIlV14J0g= -go.opentelemetry.io/otel/metric v1.40.0 h1:rcZe317KPftE2rstWIBitCdVp89A2HqjkxR3c11+p9g= -go.opentelemetry.io/otel/metric v1.40.0/go.mod h1:ib/crwQH7N3r5kfiBZQbwrTge743UDc7DTFVZrrXnqc= -go.opentelemetry.io/otel/trace v1.40.0 h1:WA4etStDttCSYuhwvEa8OP8I5EWu24lkOzp+ZYblVjw= -go.opentelemetry.io/otel/trace v1.40.0/go.mod h1:zeAhriXecNGP/s2SEG3+Y8X9ujcJOTqQ5RgdEJcawiA= -go.opentelemetry.io/proto/slim/otlp v1.9.0 h1:fPVMv8tP3TrsqlkH1HWYUpbCY9cAIemx184VGkS6vlE= -go.opentelemetry.io/proto/slim/otlp v1.9.0/go.mod h1:xXdeJJ90Gqyll+orzUkY4bOd2HECo5JofeoLpymVqdI= -go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.2.0 h1:o13nadWDNkH/quoDomDUClnQBpdQQ2Qqv0lQBjIXjE8= -go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.2.0/go.mod h1:Gyb6Xe7FTi/6xBHwMmngGoHqL0w29Y4eW8TGFzpefGA= -go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.2.0 h1:EiUYvtwu6PMrMHVjcPfnsG3v+ajPkbUeH+IL93+QYyk= -go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.2.0/go.mod h1:mUUHKFiN2SST3AhJ8XhJxEoeVW12oqfXog0Bo8W3Ec4= +go.opentelemetry.io/otel v1.42.0 h1:lSQGzTgVR3+sgJDAU/7/ZMjN9Z+vUip7leaqBKy4sho= +go.opentelemetry.io/otel v1.42.0/go.mod h1:lJNsdRMxCUIWuMlVJWzecSMuNjE7dOYyWlqOXWkdqCc= +go.opentelemetry.io/otel/metric v1.42.0 h1:2jXG+3oZLNXEPfNmnpxKDeZsFI5o4J+nz6xUlaFdF/4= +go.opentelemetry.io/otel/metric v1.42.0/go.mod h1:RlUN/7vTU7Ao/diDkEpQpnz3/92J9ko05BIwxYa2SSI= +go.opentelemetry.io/otel/sdk v1.40.0 h1:KHW/jUzgo6wsPh9At46+h4upjtccTmuZCFAc9OJ71f8= +go.opentelemetry.io/otel/sdk v1.40.0/go.mod h1:Ph7EFdYvxq72Y8Li9q8KebuYUr2KoeyHx0DRMKrYBUE= +go.opentelemetry.io/otel/sdk/metric v1.40.0 h1:mtmdVqgQkeRxHgRv4qhyJduP3fYJRMX4AtAlbuWdCYw= +go.opentelemetry.io/otel/sdk/metric v1.40.0/go.mod h1:4Z2bGMf0KSK3uRjlczMOeMhKU2rhUqdWNoKcYrtcBPg= +go.opentelemetry.io/otel/trace v1.42.0 h1:OUCgIPt+mzOnaUTpOQcBiM/PLQ/Op7oq6g4LenLmOYY= +go.opentelemetry.io/otel/trace v1.42.0/go.mod h1:f3K9S+IFqnumBkKhRJMeaZeNk9epyhnCmQh/EysQCdc= +go.opentelemetry.io/proto/slim/otlp v1.10.0 h1:iR97Vs/ZDR+y9TfuP9b1XBtdPWeC+OMslIBmhcLU7jM= +go.opentelemetry.io/proto/slim/otlp v1.10.0/go.mod h1:lV9250stpjYLPNA5viFabIgP2QlUGRT1GdTgAf8SIUk= +go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.3.0 h1:RUF5rO0hAlgiJt1fzQVzcVs3vZVNHIcMLgOgG4rWNcQ= +go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.3.0/go.mod h1:I89cynRj8y+383o7tEQVg2SVA6SRgDVIouWPUVXjx0U= +go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.3.0 h1:CQvJSldHRUN6Z8jsUeYv8J0lXRvygALXIzsmAeCcZE0= +go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.3.0/go.mod h1:xSQ+mEfJe/GjK1LXEyVOoSI1N9JV9ZI923X5kup43W4= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= go.uber.org/zap v1.27.1 h1:08RqriUEv8+ArZRYSTXy1LeBScaMpVSTBhCeaZYfMYc= go.uber.org/zap v1.27.1/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= -google.golang.org/protobuf v1.36.10 h1:AYd7cD/uASjIL6Q9LiTjz8JLcrh/88q5UObnmY3aOOE= -google.golang.org/protobuf v1.36.10/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= +golang.org/x/sys v0.41.0 h1:Ivj+2Cp/ylzLiEU89QhWblYnOE9zerudt9Ftecq2C6k= +golang.org/x/sys v0.41.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= +google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE= +google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/extension/xextension/metadata.yaml b/extension/xextension/metadata.yaml index 674d6357c802..e73142dbb09b 100644 --- a/extension/xextension/metadata.yaml +++ b/extension/xextension/metadata.yaml @@ -3,7 +3,7 @@ github_project: open-telemetry/opentelemetry-collector status: disable_codecov_badge: true - class: extension + class: pkg codeowners: stability: development: [profiles] diff --git a/extension/xextension/storage/metadata.yaml b/extension/xextension/storage/metadata.yaml index bc95f3e4629a..001e1ca1a6f0 100644 --- a/extension/xextension/storage/metadata.yaml +++ b/extension/xextension/storage/metadata.yaml @@ -1,9 +1,9 @@ -type: xextension +type: xextension/storage github_project: open-telemetry/opentelemetry-collector status: disable_codecov_badge: true - class: extension + class: pkg codeowners: active: - swiatekm diff --git a/extension/zpagesextension/README.md b/extension/zpagesextension/README.md index 1aff49e57ae9..c9c5e9332f04 100644 --- a/extension/zpagesextension/README.md +++ b/extension/zpagesextension/README.md @@ -1,6 +1,5 @@ -# zPages - +# zPages Extension | Status | | | ------------- |-----------| | Stability | [beta] | diff --git a/extension/zpagesextension/config.go b/extension/zpagesextension/config.go index cda4717c0868..e5f06d269a6a 100644 --- a/extension/zpagesextension/config.go +++ b/extension/zpagesextension/config.go @@ -32,7 +32,7 @@ var _ component.Config = (*Config)(nil) // Validate checks if the extension configuration is valid func (cfg *Config) Validate() error { - if cfg.Endpoint == "" { + if cfg.NetAddr.Endpoint == "" { return errors.New("\"endpoint\" is required when using the \"zpages\" extension") } return nil diff --git a/extension/zpagesextension/config_test.go b/extension/zpagesextension/config_test.go index cbbd324f0081..d6aac5442cfe 100644 --- a/extension/zpagesextension/config_test.go +++ b/extension/zpagesextension/config_test.go @@ -32,10 +32,9 @@ func TestUnmarshalConfig(t *testing.T) { factory := NewFactory() cfg := factory.CreateDefaultConfig() require.NoError(t, cm.Unmarshal(&cfg)) - assert.Equal(t, - &Config{ - ServerConfig: confighttp.ServerConfig{ - Endpoint: "localhost:56888", - }, - }, cfg) + + expectedServerConfig := confighttp.NewDefaultServerConfig() + expectedServerConfig.NetAddr.Endpoint = "localhost:56888" + + assert.Equal(t, &Config{ServerConfig: expectedServerConfig}, cfg) } diff --git a/extension/zpagesextension/factory.go b/extension/zpagesextension/factory.go index 08e79541da1b..f1529a9981ba 100644 --- a/extension/zpagesextension/factory.go +++ b/extension/zpagesextension/factory.go @@ -22,10 +22,10 @@ func NewFactory() extension.Factory { } func createDefaultConfig() component.Config { + serverConfig := confighttp.NewDefaultServerConfig() + serverConfig.NetAddr.Endpoint = defaultEndpoint return &Config{ - ServerConfig: confighttp.ServerConfig{ - Endpoint: defaultEndpoint, - }, + ServerConfig: serverConfig, } } diff --git a/extension/zpagesextension/factory_test.go b/extension/zpagesextension/factory_test.go index b45f7f582213..b07998379bab 100644 --- a/extension/zpagesextension/factory_test.go +++ b/extension/zpagesextension/factory_test.go @@ -19,13 +19,11 @@ import ( ) func TestFactory_CreateDefaultConfig(t *testing.T) { + expectedServerConfig := confighttp.NewDefaultServerConfig() + expectedServerConfig.NetAddr.Endpoint = "localhost:55679" + cfg := createDefaultConfig() - assert.Equal(t, &Config{ - ServerConfig: confighttp.ServerConfig{ - Endpoint: "localhost:55679", - }, - }, - cfg) + assert.Equal(t, &Config{ServerConfig: expectedServerConfig}, cfg) require.NoError(t, componenttest.CheckConfigStruct(cfg)) ext, err := create(context.Background(), extensiontest.NewNopSettings(metadata.Type), cfg) @@ -35,7 +33,7 @@ func TestFactory_CreateDefaultConfig(t *testing.T) { func TestFactoryCreate(t *testing.T) { cfg := createDefaultConfig().(*Config) - cfg.Endpoint = testutil.GetAvailableLocalAddress(t) + cfg.NetAddr.Endpoint = testutil.GetAvailableLocalAddress(t) set := extensiontest.NewNopSettings(extensiontest.NopType) set.ID = component.NewID(NewFactory().Type()) diff --git a/extension/zpagesextension/go.mod b/extension/zpagesextension/go.mod index 6cc21caa1891..464f6000cc81 100644 --- a/extension/zpagesextension/go.mod +++ b/extension/zpagesextension/go.mod @@ -1,22 +1,23 @@ module go.opentelemetry.io/collector/extension/zpagesextension -go 1.24.0 +go 1.25.0 require ( github.com/stretchr/testify v1.11.1 - go.opentelemetry.io/collector/component v1.46.0 + go.opentelemetry.io/collector/component v1.54.0 go.opentelemetry.io/collector/component/componentstatus v0.140.0 - go.opentelemetry.io/collector/component/componenttest v0.140.0 + go.opentelemetry.io/collector/component/componenttest v0.148.0 go.opentelemetry.io/collector/config/configauth v1.46.0 go.opentelemetry.io/collector/config/confighttp v0.140.0 + go.opentelemetry.io/collector/config/confignet v0.0.0-00010101000000-000000000000 go.opentelemetry.io/collector/config/configoptional v1.46.0 - go.opentelemetry.io/collector/confmap v1.46.0 - go.opentelemetry.io/collector/extension v1.46.0 + go.opentelemetry.io/collector/confmap v1.54.0 + go.opentelemetry.io/collector/extension v1.54.0 go.opentelemetry.io/collector/extension/extensiontest v0.140.0 - go.opentelemetry.io/collector/internal/testutil v0.140.0 + go.opentelemetry.io/collector/internal/testutil v0.148.0 go.opentelemetry.io/contrib/zpages v0.63.0 go.opentelemetry.io/otel/sdk v1.40.0 - go.opentelemetry.io/otel/trace v1.40.0 + go.opentelemetry.io/otel/trace v1.42.0 go.uber.org/goleak v1.3.0 go.uber.org/zap v1.27.1 ) @@ -25,53 +26,54 @@ require ( github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/davecgh/go-spew v1.1.1 // indirect github.com/felixge/httpsnoop v1.0.4 // indirect - github.com/foxboron/go-tpm-keyfiles v0.0.0-20250903184740-5d135037bd4d // indirect + github.com/foxboron/go-tpm-keyfiles v0.0.0-20251226215517-609e4778396f // indirect github.com/fsnotify/fsnotify v1.9.0 // indirect github.com/go-logr/logr v1.4.3 // indirect github.com/go-logr/stdr v1.2.2 // indirect - github.com/go-viper/mapstructure/v2 v2.4.0 // indirect + github.com/go-viper/mapstructure/v2 v2.5.0 // indirect github.com/gobwas/glob v0.2.3 // indirect github.com/golang/snappy v1.0.0 // indirect - github.com/google/go-tpm v0.9.7 // indirect + github.com/google/go-tpm v0.9.8 // indirect github.com/google/uuid v1.6.0 // indirect - github.com/hashicorp/go-version v1.7.0 // indirect + github.com/hashicorp/go-version v1.8.0 // indirect github.com/json-iterator/go v1.1.12 // indirect - github.com/klauspost/compress v1.18.1 // indirect + github.com/klauspost/compress v1.18.4 // indirect github.com/knadh/koanf/maps v0.1.2 // indirect github.com/knadh/koanf/providers/confmap v1.0.0 // indirect - github.com/knadh/koanf/v2 v2.3.0 // indirect + github.com/knadh/koanf/v2 v2.3.3 // indirect github.com/mitchellh/copystructure v1.2.0 // indirect github.com/mitchellh/reflectwalk v1.0.2 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee // indirect - github.com/pierrec/lz4/v4 v4.1.22 // indirect + github.com/pierrec/lz4/v4 v4.1.26 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect github.com/rs/cors v1.11.1 // indirect go.opentelemetry.io/auto/sdk v1.2.1 // indirect go.opentelemetry.io/collector/client v1.46.0 // indirect go.opentelemetry.io/collector/config/configcompression v1.46.0 // indirect go.opentelemetry.io/collector/config/configmiddleware v1.46.0 // indirect - go.opentelemetry.io/collector/config/configopaque v1.46.0 // indirect + go.opentelemetry.io/collector/config/configopaque v1.54.0 // indirect go.opentelemetry.io/collector/config/configtls v1.46.0 // indirect - go.opentelemetry.io/collector/confmap/xconfmap v0.140.0 // indirect - go.opentelemetry.io/collector/extension/extensionauth v1.46.0 // indirect - go.opentelemetry.io/collector/extension/extensionmiddleware v0.140.0 // indirect - go.opentelemetry.io/collector/featuregate v1.46.0 // indirect - go.opentelemetry.io/collector/pdata v1.46.0 // indirect - go.opentelemetry.io/collector/pipeline v1.46.0 // indirect + go.opentelemetry.io/collector/confmap/xconfmap v0.148.0 // indirect + go.opentelemetry.io/collector/extension/extensionauth v1.54.0 // indirect + go.opentelemetry.io/collector/extension/extensionmiddleware v0.148.0 // indirect + go.opentelemetry.io/collector/featuregate v1.54.0 // indirect + go.opentelemetry.io/collector/internal/componentalias v0.148.0 // indirect + go.opentelemetry.io/collector/pdata v1.54.0 // indirect + go.opentelemetry.io/collector/pipeline v1.54.0 // indirect go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.63.0 // indirect - go.opentelemetry.io/otel v1.40.0 // indirect - go.opentelemetry.io/otel/metric v1.40.0 // indirect + go.opentelemetry.io/otel v1.42.0 // indirect + go.opentelemetry.io/otel/metric v1.42.0 // indirect go.opentelemetry.io/otel/sdk/metric v1.40.0 // indirect go.uber.org/multierr v1.11.0 // indirect go.yaml.in/yaml/v3 v3.0.4 // indirect - golang.org/x/crypto v0.45.0 // indirect - golang.org/x/net v0.47.0 // indirect - golang.org/x/sys v0.40.0 // indirect - golang.org/x/text v0.31.0 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20251022142026-3a174f9686a8 // indirect - google.golang.org/grpc v1.77.0 // indirect - google.golang.org/protobuf v1.36.10 // indirect + golang.org/x/crypto v0.48.0 // indirect + golang.org/x/net v0.51.0 // indirect + golang.org/x/sys v0.41.0 // indirect + golang.org/x/text v0.34.0 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20251222181119-0a764e51fe1b // indirect + google.golang.org/grpc v1.79.3 // indirect + google.golang.org/protobuf v1.36.11 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) @@ -103,6 +105,8 @@ replace go.opentelemetry.io/collector/extension/extensionauth => ../extensionaut replace go.opentelemetry.io/collector/config/confighttp => ../../config/confighttp +replace go.opentelemetry.io/collector/config/confignet => ../../config/confignet + replace go.opentelemetry.io/collector/client => ../../client replace go.opentelemetry.io/collector/component/componentstatus => ../../component/componentstatus @@ -127,3 +131,5 @@ replace go.opentelemetry.io/collector/extension/extensionmiddleware/extensionmid replace go.opentelemetry.io/collector/confmap/xconfmap => ../../confmap/xconfmap replace go.opentelemetry.io/collector/internal/testutil => ../../internal/testutil + +replace go.opentelemetry.io/collector/internal/componentalias => ../../internal/componentalias diff --git a/extension/zpagesextension/go.sum b/extension/zpagesextension/go.sum index ab2c32ce2ac8..1c4a9b9594a9 100644 --- a/extension/zpagesextension/go.sum +++ b/extension/zpagesextension/go.sum @@ -5,10 +5,8 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg= github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= -github.com/foxboron/go-tpm-keyfiles v0.0.0-20250903184740-5d135037bd4d h1:EdO/NMMuCZfxhdzTZLuKAciQSnI2DV+Ppg8+vAYrnqA= -github.com/foxboron/go-tpm-keyfiles v0.0.0-20250903184740-5d135037bd4d/go.mod h1:uAyTlAUxchYuiFjTHmuIEJ4nGSm7iOPaGcAyA81fJ80= -github.com/foxboron/swtpm_test v0.0.0-20230726224112-46aaafdf7006 h1:50sW4r0PcvlpG4PV8tYh2RVCapszJgaOLRCS2subvV4= -github.com/foxboron/swtpm_test v0.0.0-20230726224112-46aaafdf7006/go.mod h1:eIXCMsMYCaqq9m1KSSxXwQG11krpuNPGP3k0uaWrbas= +github.com/foxboron/go-tpm-keyfiles v0.0.0-20251226215517-609e4778396f h1:RJ+BDPLSHQO7cSjKBqjPJSbi1qfk9WcsjQDtZiw3dZw= +github.com/foxboron/go-tpm-keyfiles v0.0.0-20251226215517-609e4778396f/go.mod h1:VHbbch/X4roIY22jL1s3qRbZhCiRIgUAF/PdSUcx2io= github.com/fsnotify/fsnotify v1.9.0 h1:2Ml+OJNzbYCTzsxtv8vKSFD9PbJjmhYF14k/jKC7S9k= github.com/fsnotify/fsnotify v1.9.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= @@ -16,8 +14,8 @@ github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI= github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= -github.com/go-viper/mapstructure/v2 v2.4.0 h1:EBsztssimR/CONLSZZ04E8qAkxNYq4Qp9LvH92wZUgs= -github.com/go-viper/mapstructure/v2 v2.4.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM= +github.com/go-viper/mapstructure/v2 v2.5.0 h1:vM5IJoUAy3d7zRSVtIwQgBj7BiWtMPfmPEgAXnvj1Ro= +github.com/go-viper/mapstructure/v2 v2.5.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM= github.com/gobwas/glob v0.2.3 h1:A4xDbljILXROh+kObIiy5kIaPYD8e96x1tgBhUI5J+Y= github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8= github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= @@ -26,25 +24,25 @@ github.com/golang/snappy v1.0.0 h1:Oy607GVXHs7RtbggtPBnr2RmDArIsAefDwvrdWvRhGs= github.com/golang/snappy v1.0.0/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= -github.com/google/go-tpm v0.9.7 h1:u89J4tUUeDTlH8xxC3CTW7OHZjbjKoHdQ9W7gCUhtxA= -github.com/google/go-tpm v0.9.7/go.mod h1:h9jEsEECg7gtLis0upRBQU+GhYVH6jMjrFxI8u6bVUY= -github.com/google/go-tpm-tools v0.4.4 h1:oiQfAIkc6xTy9Fl5NKTeTJkBTlXdHsxAofmQyxBKY98= -github.com/google/go-tpm-tools v0.4.4/go.mod h1:T8jXkp2s+eltnCDIsXR84/MTcVU9Ja7bh3Mit0pa4AY= +github.com/google/go-tpm v0.9.8 h1:slArAR9Ft+1ybZu0lBwpSmpwhRXaa85hWtMinMyRAWo= +github.com/google/go-tpm v0.9.8/go.mod h1:h9jEsEECg7gtLis0upRBQU+GhYVH6jMjrFxI8u6bVUY= +github.com/google/go-tpm-tools v0.4.7 h1:J3ycC8umYxM9A4eF73EofRZu4BxY0jjQnUnkhIBbvws= +github.com/google/go-tpm-tools v0.4.7/go.mod h1:gSyXTZHe3fgbzb6WEGd90QucmsnT1SRdlye82gH8QjQ= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/hashicorp/go-version v1.7.0 h1:5tqGy27NaOTB8yJKUZELlFAS/LTKJkrmONwQKeRZfjY= -github.com/hashicorp/go-version v1.7.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= +github.com/hashicorp/go-version v1.8.0 h1:KAkNb1HAiZd1ukkxDFGmokVZe1Xy9HG6NUp+bPle2i4= +github.com/hashicorp/go-version v1.8.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= -github.com/klauspost/compress v1.18.1 h1:bcSGx7UbpBqMChDtsF28Lw6v/G94LPrrbMbdC3JH2co= -github.com/klauspost/compress v1.18.1/go.mod h1:ZQFFVG+MdnR0P+l6wpXgIL4NTtwiKIdBnrBd8Nrxr+0= +github.com/klauspost/compress v1.18.4 h1:RPhnKRAQ4Fh8zU2FY/6ZFDwTVTxgJ/EMydqSTzE9a2c= +github.com/klauspost/compress v1.18.4/go.mod h1:R0h/fSBs8DE4ENlcrlib3PsXS61voFxhIs2DeRhCvJ4= github.com/knadh/koanf/maps v0.1.2 h1:RBfmAW5CnZT+PJ1CVc1QSJKf4Xu9kxfQgYVQSu8hpbo= github.com/knadh/koanf/maps v0.1.2/go.mod h1:npD/QZY3V6ghQDdcQzl1W4ICNVTkohC8E73eI2xW4yI= github.com/knadh/koanf/providers/confmap v1.0.0 h1:mHKLJTE7iXEys6deO5p6olAiZdG5zwp8Aebir+/EaRE= github.com/knadh/koanf/providers/confmap v1.0.0/go.mod h1:txHYHiI2hAtF0/0sCmcuol4IDcuQbKTybiB1nOcUo1A= -github.com/knadh/koanf/v2 v2.3.0 h1:Qg076dDRFHvqnKG97ZEsi9TAg2/nFTa9hCdcSa1lvlM= -github.com/knadh/koanf/v2 v2.3.0/go.mod h1:gRb40VRAbd4iJMYYD5IxZ6hfuopFcXBpc9bbQpZwo28= +github.com/knadh/koanf/v2 v2.3.3 h1:jLJC8XCRfLC7n4F+ZKKdBsbq1bfXTpuFhf4L7t94D94= +github.com/knadh/koanf/v2 v2.3.3/go.mod h1:gRb40VRAbd4iJMYYD5IxZ6hfuopFcXBpc9bbQpZwo28= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= @@ -59,8 +57,8 @@ github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJ github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee h1:W5t00kpgFdJifH4BDsTlE89Zl93FEloxaWZfGcifgq8= github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= -github.com/pierrec/lz4/v4 v4.1.22 h1:cKFw6uJDK+/gfw5BcDL0JL5aBsAFdsIT18eRtLj7VIU= -github.com/pierrec/lz4/v4 v4.1.22/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4= +github.com/pierrec/lz4/v4 v4.1.26 h1:GrpZw1gZttORinvzBdXPUXATeqlJjqUG/D87TKMnhjY= +github.com/pierrec/lz4/v4 v4.1.26/go.mod h1:EoQMVJgeeEOMsCqCzqFm2O0cJvljX2nGZjcRIPL34O4= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ= @@ -77,22 +75,22 @@ go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.63.0 h1:RbKq8BG go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.63.0/go.mod h1:h06DGIukJOevXaj/xrNjhi/2098RZzcLTbc0jDAUbsg= go.opentelemetry.io/contrib/zpages v0.63.0 h1:TppOKuZGbqXMgsfjqq3i09N5Vbo1JLtLImUqiTPGnX4= go.opentelemetry.io/contrib/zpages v0.63.0/go.mod h1:5F8uugz75ay/MMhRRhxAXY33FuaI8dl7jTxefrIy5qk= -go.opentelemetry.io/otel v1.40.0 h1:oA5YeOcpRTXq6NN7frwmwFR0Cn3RhTVZvXsP4duvCms= -go.opentelemetry.io/otel v1.40.0/go.mod h1:IMb+uXZUKkMXdPddhwAHm6UfOwJyh4ct1ybIlV14J0g= -go.opentelemetry.io/otel/metric v1.40.0 h1:rcZe317KPftE2rstWIBitCdVp89A2HqjkxR3c11+p9g= -go.opentelemetry.io/otel/metric v1.40.0/go.mod h1:ib/crwQH7N3r5kfiBZQbwrTge743UDc7DTFVZrrXnqc= +go.opentelemetry.io/otel v1.42.0 h1:lSQGzTgVR3+sgJDAU/7/ZMjN9Z+vUip7leaqBKy4sho= +go.opentelemetry.io/otel v1.42.0/go.mod h1:lJNsdRMxCUIWuMlVJWzecSMuNjE7dOYyWlqOXWkdqCc= +go.opentelemetry.io/otel/metric v1.42.0 h1:2jXG+3oZLNXEPfNmnpxKDeZsFI5o4J+nz6xUlaFdF/4= +go.opentelemetry.io/otel/metric v1.42.0/go.mod h1:RlUN/7vTU7Ao/diDkEpQpnz3/92J9ko05BIwxYa2SSI= go.opentelemetry.io/otel/sdk v1.40.0 h1:KHW/jUzgo6wsPh9At46+h4upjtccTmuZCFAc9OJ71f8= go.opentelemetry.io/otel/sdk v1.40.0/go.mod h1:Ph7EFdYvxq72Y8Li9q8KebuYUr2KoeyHx0DRMKrYBUE= go.opentelemetry.io/otel/sdk/metric v1.40.0 h1:mtmdVqgQkeRxHgRv4qhyJduP3fYJRMX4AtAlbuWdCYw= go.opentelemetry.io/otel/sdk/metric v1.40.0/go.mod h1:4Z2bGMf0KSK3uRjlczMOeMhKU2rhUqdWNoKcYrtcBPg= -go.opentelemetry.io/otel/trace v1.40.0 h1:WA4etStDttCSYuhwvEa8OP8I5EWu24lkOzp+ZYblVjw= -go.opentelemetry.io/otel/trace v1.40.0/go.mod h1:zeAhriXecNGP/s2SEG3+Y8X9ujcJOTqQ5RgdEJcawiA= -go.opentelemetry.io/proto/slim/otlp v1.9.0 h1:fPVMv8tP3TrsqlkH1HWYUpbCY9cAIemx184VGkS6vlE= -go.opentelemetry.io/proto/slim/otlp v1.9.0/go.mod h1:xXdeJJ90Gqyll+orzUkY4bOd2HECo5JofeoLpymVqdI= -go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.2.0 h1:o13nadWDNkH/quoDomDUClnQBpdQQ2Qqv0lQBjIXjE8= -go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.2.0/go.mod h1:Gyb6Xe7FTi/6xBHwMmngGoHqL0w29Y4eW8TGFzpefGA= -go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.2.0 h1:EiUYvtwu6PMrMHVjcPfnsG3v+ajPkbUeH+IL93+QYyk= -go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.2.0/go.mod h1:mUUHKFiN2SST3AhJ8XhJxEoeVW12oqfXog0Bo8W3Ec4= +go.opentelemetry.io/otel/trace v1.42.0 h1:OUCgIPt+mzOnaUTpOQcBiM/PLQ/Op7oq6g4LenLmOYY= +go.opentelemetry.io/otel/trace v1.42.0/go.mod h1:f3K9S+IFqnumBkKhRJMeaZeNk9epyhnCmQh/EysQCdc= +go.opentelemetry.io/proto/slim/otlp v1.10.0 h1:iR97Vs/ZDR+y9TfuP9b1XBtdPWeC+OMslIBmhcLU7jM= +go.opentelemetry.io/proto/slim/otlp v1.10.0/go.mod h1:lV9250stpjYLPNA5viFabIgP2QlUGRT1GdTgAf8SIUk= +go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.3.0 h1:RUF5rO0hAlgiJt1fzQVzcVs3vZVNHIcMLgOgG4rWNcQ= +go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.3.0/go.mod h1:I89cynRj8y+383o7tEQVg2SVA6SRgDVIouWPUVXjx0U= +go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.3.0 h1:CQvJSldHRUN6Z8jsUeYv8J0lXRvygALXIzsmAeCcZE0= +go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.3.0/go.mod h1:xSQ+mEfJe/GjK1LXEyVOoSI1N9JV9ZI923X5kup43W4= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= @@ -101,22 +99,22 @@ go.uber.org/zap v1.27.1 h1:08RqriUEv8+ArZRYSTXy1LeBScaMpVSTBhCeaZYfMYc= go.uber.org/zap v1.27.1/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc= go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg= -golang.org/x/crypto v0.45.0 h1:jMBrvKuj23MTlT0bQEOBcAE0mjg8mK9RXFhRH6nyF3Q= -golang.org/x/crypto v0.45.0/go.mod h1:XTGrrkGJve7CYK7J8PEww4aY7gM3qMCElcJQ8n8JdX4= -golang.org/x/net v0.47.0 h1:Mx+4dIFzqraBXUugkia1OOvlD6LemFo1ALMHjrXDOhY= -golang.org/x/net v0.47.0/go.mod h1:/jNxtkgq5yWUGYkaZGqo27cfGZ1c5Nen03aYrrKpVRU= -golang.org/x/sys v0.40.0 h1:DBZZqJ2Rkml6QMQsZywtnjnnGvHza6BTfYFWY9kjEWQ= -golang.org/x/sys v0.40.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= -golang.org/x/text v0.31.0 h1:aC8ghyu4JhP8VojJ2lEHBnochRno1sgL6nEi9WGFGMM= -golang.org/x/text v0.31.0/go.mod h1:tKRAlv61yKIjGGHX/4tP1LTbc13YSec1pxVEWXzfoeM= +golang.org/x/crypto v0.48.0 h1:/VRzVqiRSggnhY7gNRxPauEQ5Drw9haKdM0jqfcCFts= +golang.org/x/crypto v0.48.0/go.mod h1:r0kV5h3qnFPlQnBSrULhlsRfryS2pmewsg+XfMgkVos= +golang.org/x/net v0.51.0 h1:94R/GTO7mt3/4wIKpcR5gkGmRLOuE/2hNGeWq/GBIFo= +golang.org/x/net v0.51.0/go.mod h1:aamm+2QF5ogm02fjy5Bb7CQ0WMt1/WVM7FtyaTLlA9Y= +golang.org/x/sys v0.41.0 h1:Ivj+2Cp/ylzLiEU89QhWblYnOE9zerudt9Ftecq2C6k= +golang.org/x/sys v0.41.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= +golang.org/x/text v0.34.0 h1:oL/Qq0Kdaqxa1KbNeMKwQq0reLCCaFtqu2eNuSeNHbk= +golang.org/x/text v0.34.0/go.mod h1:homfLqTYRFyVYemLBFl5GgL/DWEiH5wcsQ5gSh1yziA= gonum.org/v1/gonum v0.16.0 h1:5+ul4Swaf3ESvrOnidPp4GZbzf0mxVQpDCYUQE7OJfk= gonum.org/v1/gonum v0.16.0/go.mod h1:fef3am4MQ93R2HHpKnLk4/Tbh/s0+wqD5nfa6Pnwy4E= -google.golang.org/genproto/googleapis/rpc v0.0.0-20251022142026-3a174f9686a8 h1:M1rk8KBnUsBDg1oPGHNCxG4vc1f49epmTO7xscSajMk= -google.golang.org/genproto/googleapis/rpc v0.0.0-20251022142026-3a174f9686a8/go.mod h1:7i2o+ce6H/6BluujYR+kqX3GKH+dChPTQU19wjRPiGk= -google.golang.org/grpc v1.77.0 h1:wVVY6/8cGA6vvffn+wWK5ToddbgdU3d8MNENr4evgXM= -google.golang.org/grpc v1.77.0/go.mod h1:z0BY1iVj0q8E1uSQCjL9cppRj+gnZjzDnzV0dHhrNig= -google.golang.org/protobuf v1.36.10 h1:AYd7cD/uASjIL6Q9LiTjz8JLcrh/88q5UObnmY3aOOE= -google.golang.org/protobuf v1.36.10/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= +google.golang.org/genproto/googleapis/rpc v0.0.0-20251222181119-0a764e51fe1b h1:Mv8VFug0MP9e5vUxfBcE3vUkV6CImK3cMNMIDFjmzxU= +google.golang.org/genproto/googleapis/rpc v0.0.0-20251222181119-0a764e51fe1b/go.mod h1:j9x/tPzZkyxcgEFkiKEEGxfvyumM01BEtsW8xzOahRQ= +google.golang.org/grpc v1.79.3 h1:sybAEdRIEtvcD68Gx7dmnwjZKlyfuc61Dyo9pGXXkKE= +google.golang.org/grpc v1.79.3/go.mod h1:KmT0Kjez+0dde/v2j9vzwoAScgEPx/Bw1CYChhHLrHQ= +google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE= +google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= diff --git a/extension/zpagesextension/metadata.yaml b/extension/zpagesextension/metadata.yaml index 849ef46c208e..7ebc5f5b0a2f 100644 --- a/extension/zpagesextension/metadata.yaml +++ b/extension/zpagesextension/metadata.yaml @@ -1,3 +1,4 @@ +display_name: zPages Extension type: zpages github_project: open-telemetry/opentelemetry-collector diff --git a/extension/zpagesextension/testdata/config.yaml b/extension/zpagesextension/testdata/config.yaml index e80ed6bacdbe..f3a6dcf7f800 100644 --- a/extension/zpagesextension/testdata/config.yaml +++ b/extension/zpagesextension/testdata/config.yaml @@ -1 +1,2 @@ endpoint: "localhost:56888" +transport: tcp diff --git a/extension/zpagesextension/zpagesextension_test.go b/extension/zpagesextension/zpagesextension_test.go index 75da997e678b..e588a8ba1105 100644 --- a/extension/zpagesextension/zpagesextension_test.go +++ b/extension/zpagesextension/zpagesextension_test.go @@ -18,6 +18,7 @@ import ( "go.opentelemetry.io/collector/component/componenttest" "go.opentelemetry.io/collector/config/configauth" "go.opentelemetry.io/collector/config/confighttp" + "go.opentelemetry.io/collector/config/confignet" "go.opentelemetry.io/collector/config/configoptional" "go.opentelemetry.io/collector/internal/testutil" ) @@ -51,9 +52,13 @@ func newZpagesTelemetrySettings() component.TelemetrySettings { } func TestZPagesExtensionUsage(t *testing.T) { + addr := testutil.GetAvailableLocalAddress(t) cfg := &Config{ ServerConfig: confighttp.ServerConfig{ - Endpoint: testutil.GetAvailableLocalAddress(t), + NetAddr: confignet.AddrConfig{ + Endpoint: addr, + Transport: confignet.TransportTypeTCP, + }, }, } @@ -66,11 +71,8 @@ func TestZPagesExtensionUsage(t *testing.T) { // Give a chance for the server goroutine to run. runtime.Gosched() - _, zpagesPort, err := net.SplitHostPort(cfg.Endpoint) - require.NoError(t, err) - client := &http.Client{} - resp, err := client.Get("http://localhost:" + zpagesPort + "/debug/tracez") + resp, err := client.Get("http://" + addr + "/debug/tracez") require.NoError(t, err) defer resp.Body.Close() @@ -80,7 +82,10 @@ func TestZPagesExtensionUsage(t *testing.T) { func TestZPagesExtensionBadAuthExtension(t *testing.T) { cfg := &Config{ ServerConfig: confighttp.ServerConfig{ - Endpoint: "localhost:0", + NetAddr: confignet.AddrConfig{ + Endpoint: "localhost:0", + Transport: confignet.TransportTypeTCP, + }, Auth: configoptional.Some(confighttp.AuthConfig{ Config: configauth.Config{ AuthenticatorID: component.MustNewIDWithName("foo", "bar"), @@ -100,7 +105,10 @@ func TestZPagesExtensionPortAlreadyInUse(t *testing.T) { cfg := &Config{ ServerConfig: confighttp.ServerConfig{ - Endpoint: endpoint, + NetAddr: confignet.AddrConfig{ + Endpoint: endpoint, + Transport: confignet.TransportTypeTCP, + }, }, } zpagesExt := newServer(cfg, newZpagesTelemetrySettings()) @@ -112,7 +120,10 @@ func TestZPagesExtensionPortAlreadyInUse(t *testing.T) { func TestZPagesMultipleStarts(t *testing.T) { cfg := &Config{ ServerConfig: confighttp.ServerConfig{ - Endpoint: testutil.GetAvailableLocalAddress(t), + NetAddr: confignet.AddrConfig{ + Endpoint: testutil.GetAvailableLocalAddress(t), + Transport: confignet.TransportTypeTCP, + }, }, } @@ -129,7 +140,10 @@ func TestZPagesMultipleStarts(t *testing.T) { func TestZPagesMultipleShutdowns(t *testing.T) { cfg := &Config{ ServerConfig: confighttp.ServerConfig{ - Endpoint: testutil.GetAvailableLocalAddress(t), + NetAddr: confignet.AddrConfig{ + Endpoint: testutil.GetAvailableLocalAddress(t), + Transport: confignet.TransportTypeTCP, + }, }, } @@ -144,7 +158,10 @@ func TestZPagesMultipleShutdowns(t *testing.T) { func TestZPagesShutdownWithoutStart(t *testing.T) { cfg := &Config{ ServerConfig: confighttp.ServerConfig{ - Endpoint: testutil.GetAvailableLocalAddress(t), + NetAddr: confignet.AddrConfig{ + Endpoint: testutil.GetAvailableLocalAddress(t), + Transport: confignet.TransportTypeTCP, + }, }, } @@ -155,9 +172,13 @@ func TestZPagesShutdownWithoutStart(t *testing.T) { } func TestZPagesEnableExpvar(t *testing.T) { + addr := testutil.GetAvailableLocalAddress(t) cfg := &Config{ ServerConfig: confighttp.ServerConfig{ - Endpoint: testutil.GetAvailableLocalAddress(t), + NetAddr: confignet.AddrConfig{ + Endpoint: addr, + Transport: confignet.TransportTypeTCP, + }, }, Expvar: ExpvarConfig{ Enabled: true, @@ -173,11 +194,8 @@ func TestZPagesEnableExpvar(t *testing.T) { // Give a chance for the server goroutine to run. runtime.Gosched() - _, zpagesPort, err := net.SplitHostPort(cfg.Endpoint) - require.NoError(t, err) - client := &http.Client{} - resp, err := client.Get("http://localhost:" + zpagesPort + "/debug/expvarz") + resp, err := client.Get("http://" + addr + "/debug/expvarz") require.NoError(t, err) defer resp.Body.Close() diff --git a/featuregate/README.md b/featuregate/README.md index d3e3c802d63b..12f8ebf85217 100644 --- a/featuregate/README.md +++ b/featuregate/README.md @@ -8,9 +8,36 @@ based on flags at the component level. ## Usage -Feature gates must be defined and registered with the global registry in -an `init()` function. This makes the `Gate` available to be configured and -queried with the defined [`Stage`](#feature-lifecycle) default value. +### With mdatagen + +In components that use mdatagen, feature gates should be defined in the +component's `metadata.yml`. + +```yaml +feature_gates: + - id: namespaced.uniqueIdentifier + description: A brief description of what the gate controls + stage: stable + from_version: 'v0.65.0' + reference_url: 'https://github.com/open-telemetry/opentelemetry-collector/issues/6167' +``` + +Running the mdatagen code generator with this configuration will initialize the +feature flag in the `internal/metadata` submodule. +The status of the gate can later be checked by calling that submodule: + +```go +if metadata.NamespacedUniqueIdentifierFeatureGate.IsEnabled() { + setupNewFeature() +} +``` + +### In code + +In components that don't use mdatagen, feature gates can be defined and +registered with the global registry in an `init()` function. This makes the +`Gate` available to be configured and queried with the defined +[`Stage`](#feature-lifecycle) default value. A `Gate` can have a list of associated issues that allow users to refer to the issue and report any additional problems or understand the context of the `Gate`. Once a `Gate` has been marked as `Stable`, it must have a `RemovalVersion` set. @@ -25,7 +52,7 @@ var myFeatureGate = featuregate.GlobalRegistry().MustRegister( featuregate.WithRegisterToVersion("v0.70.0")) ``` -The status of the gate may later be checked by interrogating the global +The status of the gate may later be checked by interrogating the global feature gate registry: ```go @@ -34,14 +61,14 @@ if myFeatureGate.IsEnabled() { } ``` -Note that querying the registry takes a read lock and accesses a map, so it -should be done once and the result cached for local use if repeated checks +Note that querying the registry takes a read lock and accesses a map, so it +should be done once and the result cached for local use if repeated checks are required. Avoid querying the registry in a loop. ## Controlling Gates -Feature gates can be enabled or disabled via the CLI, with the -`--feature-gates` flag. When using the CLI flag, gate +Feature gates can be enabled or disabled via the CLI, with the +`--feature-gates` flag. When using the CLI flag, gate identifiers must be presented as a comma-delimited list. Gate identifiers prefixed with `-` will disable the gate and prefixing with `+` or with no prefix will enable the gate. @@ -54,19 +81,19 @@ This will enable `gate1` and `gate3` and disable `gate2`. ## Feature Lifecycle -Features controlled by a `Gate` should follow a three-stage lifecycle, +Features controlled by a `Gate` should follow a three-stage lifecycle, modeled after the [system used by Kubernetes](https://kubernetes.io/docs/reference/command-line-tools-reference/feature-gates/#feature-stages): -1. An `alpha` stage where the feature is disabled by default and must be enabled +1. An `alpha` stage where the feature is disabled by default and must be enabled through a `Gate`. -2. A `beta` stage where the feature has been well tested and is enabled by +2. A `beta` stage where the feature has been well tested and is enabled by default but can be disabled through a `Gate`. 3. A generally available or `stable` stage where the feature is permanently enabled. At this stage the gate should no longer be explicitly used. Disabling the gate will produce an error and explicitly enabling will produce a warning log. 4. A `stable` feature gate will be removed in the version specified by its `ToVersion` value. -Features that prove unworkable in the `alpha` stage may be discontinued +Features that prove unworkable in the `alpha` stage may be discontinued without proceeding to the `beta` stage. Instead, they will proceed to the `deprecated` stage, which will feature is permanently disabled. A feature gate will be removed once it has been `deprecated` for at least 2 releases of the collector. diff --git a/featuregate/examples_test.go b/featuregate/examples_test.go new file mode 100644 index 000000000000..6fe6ac188ab9 --- /dev/null +++ b/featuregate/examples_test.go @@ -0,0 +1,54 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +package featuregate_test + +import ( + "flag" + "fmt" + + "go.opentelemetry.io/collector/featuregate" +) + +func ExampleRegistry_Register() { + reg := featuregate.NewRegistry() + gate := reg.MustRegister( + "featuregate.example.gate", + featuregate.StageAlpha, + featuregate.WithRegisterDescription("Example gate"), + ) + + // By default an alpha feature gate is disabled. + fmt.Println(gate.IsEnabled()) + if err := reg.Set(gate.ID(), true); err != nil { + fmt.Println("error:", err) + return + } + // Alpha feature gates can be modified so the gate is now enabled. + fmt.Println(gate.IsEnabled()) + + // Output: + // false + // true +} + +func ExampleRegistry_RegisterFlags() { + reg := featuregate.NewRegistry() + alphaGate := reg.MustRegister("featuregate.example.alpha", featuregate.StageAlpha) + betaGate := reg.MustRegister("featuregate.example.beta", featuregate.StageBeta) + + fs := flag.NewFlagSet("example", flag.ContinueOnError) + // RegisterFlags registers the `--feature-gates` flag on the FlagSet. + reg.RegisterFlags(fs) + if err := fs.Parse([]string{"--feature-gates=featuregate.example.alpha,-featuregate.example.beta"}); err != nil { + fmt.Println("error:", err) + return + } + + fmt.Printf("featuregate.example.alpha=%v\n", alphaGate.IsEnabled()) + fmt.Printf("featuregate.example.beta=%v\n", betaGate.IsEnabled()) + + // Output: + // featuregate.example.alpha=true + // featuregate.example.beta=false +} diff --git a/featuregate/go.mod b/featuregate/go.mod index 9740380d3fba..81e493bd33c2 100644 --- a/featuregate/go.mod +++ b/featuregate/go.mod @@ -1,9 +1,9 @@ module go.opentelemetry.io/collector/featuregate -go 1.24.0 +go 1.25.0 require ( - github.com/hashicorp/go-version v1.7.0 + github.com/hashicorp/go-version v1.8.0 github.com/stretchr/testify v1.11.1 go.uber.org/goleak v1.3.0 go.uber.org/multierr v1.11.0 diff --git a/featuregate/go.sum b/featuregate/go.sum index eb911e928417..fd40271978da 100644 --- a/featuregate/go.sum +++ b/featuregate/go.sum @@ -1,8 +1,8 @@ github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/hashicorp/go-version v1.7.0 h1:5tqGy27NaOTB8yJKUZELlFAS/LTKJkrmONwQKeRZfjY= -github.com/hashicorp/go-version v1.7.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= +github.com/hashicorp/go-version v1.8.0 h1:KAkNb1HAiZd1ukkxDFGmokVZe1Xy9HG6NUp+bPle2i4= +github.com/hashicorp/go-version v1.8.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= diff --git a/featuregate/metadata.yaml b/featuregate/metadata.yaml new file mode 100644 index 000000000000..f830a48aba08 --- /dev/null +++ b/featuregate/metadata.yaml @@ -0,0 +1,6 @@ +type: featuregate +github_project: open-telemetry/opentelemetry-collector + +status: + disable_codecov_badge: true + class: pkg diff --git a/filter/config.schema.yaml b/filter/config.schema.yaml new file mode 100644 index 000000000000..02fe9b5d17f2 --- /dev/null +++ b/filter/config.schema.yaml @@ -0,0 +1,9 @@ +$defs: + config: + description: Config configures the matching behavior of a Filter. + type: object + properties: + regexp: + type: string + strict: + type: string diff --git a/filter/go.mod b/filter/go.mod index be2c54890e5c..d46090ba9d69 100644 --- a/filter/go.mod +++ b/filter/go.mod @@ -1,24 +1,24 @@ module go.opentelemetry.io/collector/filter -go 1.24.0 +go 1.25.0 require ( github.com/stretchr/testify v1.11.1 - go.opentelemetry.io/collector/confmap v1.46.0 + go.opentelemetry.io/collector/confmap v1.54.0 ) require ( github.com/davecgh/go-spew v1.1.1 // indirect - github.com/go-viper/mapstructure/v2 v2.4.0 // indirect + github.com/go-viper/mapstructure/v2 v2.5.0 // indirect github.com/gobwas/glob v0.2.3 // indirect - github.com/hashicorp/go-version v1.7.0 // indirect + github.com/hashicorp/go-version v1.8.0 // indirect github.com/knadh/koanf/maps v0.1.2 // indirect github.com/knadh/koanf/providers/confmap v1.0.0 // indirect - github.com/knadh/koanf/v2 v2.3.0 // indirect + github.com/knadh/koanf/v2 v2.3.3 // indirect github.com/mitchellh/copystructure v1.2.0 // indirect github.com/mitchellh/reflectwalk v1.0.2 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect - go.opentelemetry.io/collector/featuregate v1.46.0 // indirect + go.opentelemetry.io/collector/featuregate v1.54.0 // indirect go.uber.org/multierr v1.11.0 // indirect go.uber.org/zap v1.27.1 // indirect go.yaml.in/yaml/v3 v3.0.4 // indirect diff --git a/filter/go.sum b/filter/go.sum index 6020e16119b7..d19c16bb075a 100644 --- a/filter/go.sum +++ b/filter/go.sum @@ -1,17 +1,17 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/go-viper/mapstructure/v2 v2.4.0 h1:EBsztssimR/CONLSZZ04E8qAkxNYq4Qp9LvH92wZUgs= -github.com/go-viper/mapstructure/v2 v2.4.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM= +github.com/go-viper/mapstructure/v2 v2.5.0 h1:vM5IJoUAy3d7zRSVtIwQgBj7BiWtMPfmPEgAXnvj1Ro= +github.com/go-viper/mapstructure/v2 v2.5.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM= github.com/gobwas/glob v0.2.3 h1:A4xDbljILXROh+kObIiy5kIaPYD8e96x1tgBhUI5J+Y= github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8= -github.com/hashicorp/go-version v1.7.0 h1:5tqGy27NaOTB8yJKUZELlFAS/LTKJkrmONwQKeRZfjY= -github.com/hashicorp/go-version v1.7.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= +github.com/hashicorp/go-version v1.8.0 h1:KAkNb1HAiZd1ukkxDFGmokVZe1Xy9HG6NUp+bPle2i4= +github.com/hashicorp/go-version v1.8.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/knadh/koanf/maps v0.1.2 h1:RBfmAW5CnZT+PJ1CVc1QSJKf4Xu9kxfQgYVQSu8hpbo= github.com/knadh/koanf/maps v0.1.2/go.mod h1:npD/QZY3V6ghQDdcQzl1W4ICNVTkohC8E73eI2xW4yI= github.com/knadh/koanf/providers/confmap v1.0.0 h1:mHKLJTE7iXEys6deO5p6olAiZdG5zwp8Aebir+/EaRE= github.com/knadh/koanf/providers/confmap v1.0.0/go.mod h1:txHYHiI2hAtF0/0sCmcuol4IDcuQbKTybiB1nOcUo1A= -github.com/knadh/koanf/v2 v2.3.0 h1:Qg076dDRFHvqnKG97ZEsi9TAg2/nFTa9hCdcSa1lvlM= -github.com/knadh/koanf/v2 v2.3.0/go.mod h1:gRb40VRAbd4iJMYYD5IxZ6hfuopFcXBpc9bbQpZwo28= +github.com/knadh/koanf/v2 v2.3.3 h1:jLJC8XCRfLC7n4F+ZKKdBsbq1bfXTpuFhf4L7t94D94= +github.com/knadh/koanf/v2 v2.3.3/go.mod h1:gRb40VRAbd4iJMYYD5IxZ6hfuopFcXBpc9bbQpZwo28= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= diff --git a/filter/metadata.yaml b/filter/metadata.yaml new file mode 100644 index 000000000000..c86332b2ce8f --- /dev/null +++ b/filter/metadata.yaml @@ -0,0 +1,6 @@ +type: filter +github_project: open-telemetry/opentelemetry-collector + +status: + disable_codecov_badge: true + class: pkg diff --git a/go.mod b/go.mod index d1551674e6d9..5a686c418d73 100644 --- a/go.mod +++ b/go.mod @@ -8,13 +8,13 @@ module go.opentelemetry.io/collector // For the OpenTelemetry Collector Core distribution specifically, see // https://github.com/open-telemetry/opentelemetry-collector-releases/tree/main/distributions/otelcol -go 1.24.0 +go 1.25.0 require ( github.com/stretchr/testify v1.11.1 - google.golang.org/genproto/googleapis/rpc v0.0.0-20251022142026-3a174f9686a8 - google.golang.org/grpc v1.77.0 - google.golang.org/protobuf v1.36.10 + google.golang.org/genproto/googleapis/rpc v0.0.0-20251202230838-ff82c1b0f217 + google.golang.org/grpc v1.79.3 + google.golang.org/protobuf v1.36.11 ) require ( @@ -22,7 +22,8 @@ require ( github.com/kr/pretty v0.3.1 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect github.com/rogpeppe/go-internal v1.13.1 // indirect - golang.org/x/sys v0.37.0 // indirect + golang.org/x/net v0.51.0 // indirect + golang.org/x/sys v0.41.0 // indirect gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/go.sum b/go.sum index 2e2cb01585e9..50bfc5449014 100644 --- a/go.sum +++ b/go.sum @@ -20,18 +20,18 @@ github.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o= github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U= github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= -golang.org/x/net v0.46.1-0.20251013234738-63d1a5100f82 h1:6/3JGEh1C88g7m+qzzTbl3A0FtsLguXieqofVLU/JAo= -golang.org/x/net v0.46.1-0.20251013234738-63d1a5100f82/go.mod h1:Q9BGdFy1y4nkUwiLvT5qtyhAnEHgnQ/zd8PfU6nc210= -golang.org/x/sys v0.37.0 h1:fdNQudmxPjkdUTPnLn5mdQv7Zwvbvpaxqs831goi9kQ= -golang.org/x/sys v0.37.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= -golang.org/x/text v0.30.0 h1:yznKA/E9zq54KzlzBEAWn1NXSQ8DIp/NYMy88xJjl4k= -golang.org/x/text v0.30.0/go.mod h1:yDdHFIX9t+tORqspjENWgzaCVXgk0yYnYuSZ8UzzBVM= -google.golang.org/genproto/googleapis/rpc v0.0.0-20251022142026-3a174f9686a8 h1:M1rk8KBnUsBDg1oPGHNCxG4vc1f49epmTO7xscSajMk= -google.golang.org/genproto/googleapis/rpc v0.0.0-20251022142026-3a174f9686a8/go.mod h1:7i2o+ce6H/6BluujYR+kqX3GKH+dChPTQU19wjRPiGk= -google.golang.org/grpc v1.77.0 h1:wVVY6/8cGA6vvffn+wWK5ToddbgdU3d8MNENr4evgXM= -google.golang.org/grpc v1.77.0/go.mod h1:z0BY1iVj0q8E1uSQCjL9cppRj+gnZjzDnzV0dHhrNig= -google.golang.org/protobuf v1.36.10 h1:AYd7cD/uASjIL6Q9LiTjz8JLcrh/88q5UObnmY3aOOE= -google.golang.org/protobuf v1.36.10/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= +golang.org/x/net v0.51.0 h1:94R/GTO7mt3/4wIKpcR5gkGmRLOuE/2hNGeWq/GBIFo= +golang.org/x/net v0.51.0/go.mod h1:aamm+2QF5ogm02fjy5Bb7CQ0WMt1/WVM7FtyaTLlA9Y= +golang.org/x/sys v0.41.0 h1:Ivj+2Cp/ylzLiEU89QhWblYnOE9zerudt9Ftecq2C6k= +golang.org/x/sys v0.41.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= +golang.org/x/text v0.34.0 h1:oL/Qq0Kdaqxa1KbNeMKwQq0reLCCaFtqu2eNuSeNHbk= +golang.org/x/text v0.34.0/go.mod h1:homfLqTYRFyVYemLBFl5GgL/DWEiH5wcsQ5gSh1yziA= +google.golang.org/genproto/googleapis/rpc v0.0.0-20251202230838-ff82c1b0f217 h1:gRkg/vSppuSQoDjxyiGfN4Upv/h/DQmIR10ZU8dh4Ww= +google.golang.org/genproto/googleapis/rpc v0.0.0-20251202230838-ff82c1b0f217/go.mod h1:7i2o+ce6H/6BluujYR+kqX3GKH+dChPTQU19wjRPiGk= +google.golang.org/grpc v1.79.3 h1:sybAEdRIEtvcD68Gx7dmnwjZKlyfuc61Dyo9pGXXkKE= +google.golang.org/grpc v1.79.3/go.mod h1:KmT0Kjez+0dde/v2j9vzwoAScgEPx/Bw1CYChhHLrHQ= +google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE= +google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= diff --git a/internal/cmd/pdatagen/go.mod b/internal/cmd/pdatagen/go.mod index 8b36d25892be..a38649124244 100644 --- a/internal/cmd/pdatagen/go.mod +++ b/internal/cmd/pdatagen/go.mod @@ -1,5 +1,5 @@ module go.opentelemetry.io/collector/internal/cmd/pdatagen -go 1.24.0 +go 1.25.0 require github.com/ettle/strcase v0.2.0 diff --git a/internal/cmd/pdatagen/internal/pdata/base_slices.go b/internal/cmd/pdatagen/internal/pdata/base_slices.go index 08f9dee84476..7b1bd9035d0c 100644 --- a/internal/cmd/pdatagen/internal/pdata/base_slices.go +++ b/internal/cmd/pdatagen/internal/pdata/base_slices.go @@ -5,7 +5,7 @@ package pdata // import "go.opentelemetry.io/collector/internal/cmd/pdatagen/int import ( "go.opentelemetry.io/collector/internal/cmd/pdatagen/internal/proto" - "go.opentelemetry.io/collector/internal/cmd/pdatagen/internal/template" + "go.opentelemetry.io/collector/internal/cmd/pdatagen/internal/tmplutil" ) type baseSlice interface { @@ -38,15 +38,15 @@ func (ss *messageSlice) getPackageName() string { } func (ss *messageSlice) generate(packageInfo *PackageInfo) []byte { - return []byte(template.Execute(sliceTemplate, ss.templateFields(packageInfo))) + return []byte(tmplutil.Execute(sliceTemplate, ss.templateFields(packageInfo))) } func (ss *messageSlice) generateTests(packageInfo *PackageInfo) []byte { - return []byte(template.Execute(sliceTestTemplate, ss.templateFields(packageInfo))) + return []byte(tmplutil.Execute(sliceTestTemplate, ss.templateFields(packageInfo))) } func (ss *messageSlice) generateInternal(packageInfo *PackageInfo) []byte { - return []byte(template.Execute(sliceInternalTemplate, ss.templateFields(packageInfo))) + return []byte(tmplutil.Execute(sliceInternalTemplate, ss.templateFields(packageInfo))) } func (ss *messageSlice) templateFields(packageInfo *PackageInfo) map[string]any { diff --git a/internal/cmd/pdatagen/internal/pdata/base_struct.go b/internal/cmd/pdatagen/internal/pdata/base_struct.go index c57eb2e596f1..5cb87f1c02fc 100644 --- a/internal/cmd/pdatagen/internal/pdata/base_struct.go +++ b/internal/cmd/pdatagen/internal/pdata/base_struct.go @@ -5,7 +5,7 @@ package pdata // import "go.opentelemetry.io/collector/internal/cmd/pdatagen/int import ( "go.opentelemetry.io/collector/internal/cmd/pdatagen/internal/proto" - "go.opentelemetry.io/collector/internal/cmd/pdatagen/internal/template" + "go.opentelemetry.io/collector/internal/cmd/pdatagen/internal/tmplutil" ) type baseStruct interface { @@ -39,15 +39,15 @@ func (ms *messageStruct) getName() string { } func (ms *messageStruct) generate(packageInfo *PackageInfo) []byte { - return []byte(template.Execute(messageTemplate, ms.templateFields(packageInfo))) + return []byte(tmplutil.Execute(messageTemplate, ms.templateFields(packageInfo))) } func (ms *messageStruct) generateTests(packageInfo *PackageInfo) []byte { - return []byte(template.Execute(messageTestTemplate, ms.templateFields(packageInfo))) + return []byte(tmplutil.Execute(messageTestTemplate, ms.templateFields(packageInfo))) } func (ms *messageStruct) generateInternal(packageInfo *PackageInfo) []byte { - return []byte(template.Execute(messageInternalTemplate, ms.templateFields(packageInfo))) + return []byte(tmplutil.Execute(messageInternalTemplate, ms.templateFields(packageInfo))) } func (ms *messageStruct) getProtoMessage() *proto.Message { diff --git a/internal/cmd/pdatagen/internal/pdata/message_field.go b/internal/cmd/pdatagen/internal/pdata/message_field.go index 624c22d7cfdf..522ab06f7636 100644 --- a/internal/cmd/pdatagen/internal/pdata/message_field.go +++ b/internal/cmd/pdatagen/internal/pdata/message_field.go @@ -7,7 +7,7 @@ import ( "strings" "go.opentelemetry.io/collector/internal/cmd/pdatagen/internal/proto" - "go.opentelemetry.io/collector/internal/cmd/pdatagen/internal/template" + "go.opentelemetry.io/collector/internal/cmd/pdatagen/internal/tmplutil" ) const messageAccessorsTemplate = `// {{ .fieldName }} returns the {{ .lowerFieldName }} associated with this {{ .structName }}. @@ -40,18 +40,18 @@ type MessageField struct { } func (mf *MessageField) GenerateAccessors(ms *messageStruct) string { - t := template.Parse("messageAccessorsTemplate", []byte(messageAccessorsTemplate)) - return template.Execute(t, mf.templateFields(ms)) + t := tmplutil.Parse("messageAccessorsTemplate", []byte(messageAccessorsTemplate)) + return tmplutil.Execute(t, mf.templateFields(ms)) } func (mf *MessageField) GenerateAccessorsTest(ms *messageStruct) string { - t := template.Parse("messageAccessorsTestTemplate", []byte(messageAccessorsTestTemplate)) - return template.Execute(t, mf.templateFields(ms)) + t := tmplutil.Parse("messageAccessorsTestTemplate", []byte(messageAccessorsTestTemplate)) + return tmplutil.Execute(t, mf.templateFields(ms)) } func (mf *MessageField) GenerateTestValue(ms *messageStruct) string { - t := template.Parse("messageSetTestTemplate", []byte(messageSetTestTemplate)) - return template.Execute(t, mf.templateFields(ms)) + t := tmplutil.Parse("messageSetTestTemplate", []byte(messageSetTestTemplate)) + return tmplutil.Execute(t, mf.templateFields(ms)) } func (mf *MessageField) toProtoField(ms *messageStruct) proto.FieldInterface { diff --git a/internal/cmd/pdatagen/internal/pdata/one_of_field.go b/internal/cmd/pdatagen/internal/pdata/one_of_field.go index d0610bd3a5b4..313e851906a1 100644 --- a/internal/cmd/pdatagen/internal/pdata/one_of_field.go +++ b/internal/cmd/pdatagen/internal/pdata/one_of_field.go @@ -7,7 +7,7 @@ import ( "strings" "go.opentelemetry.io/collector/internal/cmd/pdatagen/internal/proto" - "go.opentelemetry.io/collector/internal/cmd/pdatagen/internal/template" + "go.opentelemetry.io/collector/internal/cmd/pdatagen/internal/tmplutil" ) const oneOfAccessorTemplate = `// {{ .typeFuncName }} returns the type of the {{ .lowerOriginFieldName }} for this {{ .structName }}. @@ -21,9 +21,9 @@ func (ms {{ .structName }}) {{ .typeFuncName }}() {{ .typeName }} { return {{ .typeName }}Empty } -{{ range .values }} +{{ range .values -}} {{ .GenerateAccessors $.baseStruct $.OneOfField }} -{{ end }}` +{{- end }}` const oneOfAccessorTestTemplate = `func Test{{ .structName }}_{{ .typeFuncName }}(t *testing.T) { tv := New{{ .structName }}() @@ -32,21 +32,21 @@ const oneOfAccessorTestTemplate = `func Test{{ .structName }}_{{ .typeFuncName } {{ range .values -}} {{ .GenerateTests $.baseStruct $.OneOfField }} -{{ end }} +{{- end }} ` const oneOfTestFailingUnmarshalProtoValuesTemplate = ` - {{- range .fields }} + {{ range .fields -}} {{ .GenTestFailingUnmarshalProtoValues }} {{- end }}` const oneOfTestValuesTemplate = ` - {{- range .fields }} + {{ range .fields -}} {{ .GenTestEncodingValues }} {{- end }}` const oneOfPoolOrigTemplate = ` - {{- range .fields }} + {{ range .fields -}} {{ .GenPool }} {{- end }}` @@ -58,36 +58,36 @@ func (m *{{ .protoName }}) Get{{ .originFieldName }}() any { return nil } -{{- range .fields }} +{{ range .fields -}} {{ .GenOneOfMessages }} {{- end }}` const oneOfDeleteOrigTemplate = `switch ov := orig.{{ .originFieldName }}.(type) { {{ range .fields -}} case *{{ $.protoName }}_{{ .GetName }}: - {{ .GenDelete }}{{- end }} - } -` + {{ .GenDelete }} + {{ end -}} +}` const oneOfCopyOrigTemplate = `switch t := src.{{ .originFieldName }}.(type) { -{{- range .fields }} + {{ range .fields -}} case *{{ $.protoName }}_{{ .GetName }}: {{ .GenCopy }} -{{- end }} + {{ end -}} default: dest.{{ .originFieldName }} = nil }` const oneOfMarshalJSONTemplate = `switch orig := orig.{{ .originFieldName }}.(type) { - {{- range .fields }} + {{ range .fields -}} case *{{ $.protoName }}_{{ .GetName }}: {{ .GenMarshalJSON }} - {{- end }} + {{ end -}} }` const oneOfUnmarshalJSONTemplate = ` - {{- range .fields }} - {{ .GenUnmarshalJSON }} + {{ range .fields -}} + {{ .GenUnmarshalJSON }} {{- end }}` const oneOfSizeProtoTemplate = `switch orig := orig.{{ .originFieldName }}.(type) { @@ -101,16 +101,16 @@ const oneOfSizeProtoTemplate = `switch orig := orig.{{ .originFieldName }}.(type }` const oneOfMarshalProtoTemplate = `switch orig := orig.{{ .originFieldName }}.(type) { - {{- range .fields }} + {{ range .fields -}} case *{{ $.protoName }}_{{ .GetName }}: {{ .GenMarshalProto }} - {{- end }} + {{ end -}} }` const oneOfUnmarshalProtoTemplate = ` {{- range .fields }} {{ .GenUnmarshalProto }} - {{- end }}` + {{ end }}` type OneOfField struct { originFieldName string @@ -121,7 +121,7 @@ type OneOfField struct { } func (of *OneOfField) GenerateAccessors(ms *messageStruct) string { - return template.Execute(template.Parse("oneOfAccessorTemplate", []byte(oneOfAccessorTemplate)), of.templateFields(ms)) + return tmplutil.Execute(tmplutil.Parse("oneOfAccessorTemplate", []byte(oneOfAccessorTemplate)), of.templateFields(ms)) } func (of *OneOfField) typeFuncName() string { @@ -133,7 +133,7 @@ func (of *OneOfField) typeFuncName() string { } func (of *OneOfField) GenerateAccessorsTest(ms *messageStruct) string { - return template.Execute(template.Parse("oneOfAccessorTestTemplate", []byte(oneOfAccessorTestTemplate)), of.templateFields(ms)) + return tmplutil.Execute(tmplutil.Parse("oneOfAccessorTestTemplate", []byte(oneOfAccessorTestTemplate)), of.templateFields(ms)) } func (of *OneOfField) GenerateTestValue(ms *messageStruct) string { @@ -163,7 +163,7 @@ func (of *oneOfProtoField) GenMessageField() string { } func (of *oneOfProtoField) GenOneOfMessages() string { - return template.Execute(template.Parse("oneOfMessageOrigTemplate", []byte(oneOfMessageOrigTemplate)), of.templateFields()) + return tmplutil.Execute(tmplutil.Parse("oneOfMessageOrigTemplate", []byte(oneOfMessageOrigTemplate)), of.templateFields()) } func (of *oneOfProtoField) GetName() string { @@ -178,51 +178,55 @@ func (of *oneOfProtoField) DefaultValue() string { panic("implement me") } +func (of *oneOfProtoField) GenTest() string { + return "orig." + of.GetName() + " = " + of.TestValue() +} + func (of *oneOfProtoField) TestValue() string { return "&" + of.protoName + "_" + of.fields[0].GetName() + "{" + of.fields[0].GetName() + ": " + of.fields[0].TestValue() + "}" } func (of *oneOfProtoField) GenTestFailingUnmarshalProtoValues() string { - return template.Execute(template.Parse("oneOfTestFailingUnmarshalProtoValuesTemplate", []byte(oneOfTestFailingUnmarshalProtoValuesTemplate)), of.templateFields()) + return tmplutil.Execute(tmplutil.Parse("oneOfTestFailingUnmarshalProtoValuesTemplate", []byte(oneOfTestFailingUnmarshalProtoValuesTemplate)), of.templateFields()) } func (of *oneOfProtoField) GenTestEncodingValues() string { - return template.Execute(template.Parse("oneOfTestValuesTemplate", []byte(oneOfTestValuesTemplate)), of.templateFields()) + return tmplutil.Execute(tmplutil.Parse("oneOfTestValuesTemplate", []byte(oneOfTestValuesTemplate)), of.templateFields()) } func (of *oneOfProtoField) GenPool() string { - return template.Execute(template.Parse("oneOfPoolOrigTemplate", []byte(oneOfPoolOrigTemplate)), of.templateFields()) + return tmplutil.Execute(tmplutil.Parse("oneOfPoolOrigTemplate", []byte(oneOfPoolOrigTemplate)), of.templateFields()) } func (of *oneOfProtoField) GenDelete() string { - return template.Execute(template.Parse("oneOfDeleteOrigTemplate", []byte(oneOfDeleteOrigTemplate)), of.templateFields()) + return tmplutil.Execute(tmplutil.Parse("oneOfDeleteOrigTemplate", []byte(oneOfDeleteOrigTemplate)), of.templateFields()) } func (of *oneOfProtoField) GenCopy() string { - return template.Execute(template.Parse("oneOfCopyOrigTemplate", []byte(oneOfCopyOrigTemplate)), of.templateFields()) + return tmplutil.Execute(tmplutil.Parse("oneOfCopyOrigTemplate", []byte(oneOfCopyOrigTemplate)), of.templateFields()) } func (of *oneOfProtoField) GenMarshalJSON() string { - return template.Execute(template.Parse("oneOfMarshalJSONTemplate", []byte(oneOfMarshalJSONTemplate)), of.templateFields()) + return tmplutil.Execute(tmplutil.Parse("oneOfMarshalJSONTemplate", []byte(oneOfMarshalJSONTemplate)), of.templateFields()) } func (of *oneOfProtoField) GenUnmarshalJSON() string { - return template.Execute(template.Parse("oneOfUnmarshalJSONTemplate", []byte(oneOfUnmarshalJSONTemplate)), of.templateFields()) + return tmplutil.Execute(tmplutil.Parse("oneOfUnmarshalJSONTemplate", []byte(oneOfUnmarshalJSONTemplate)), of.templateFields()) } func (of *oneOfProtoField) GenSizeProto() string { - t := template.Parse("oneOfSizeProtoTemplate", []byte(oneOfSizeProtoTemplate)) - return template.Execute(t, of.templateFields()) + t := tmplutil.Parse("oneOfSizeProtoTemplate", []byte(oneOfSizeProtoTemplate)) + return tmplutil.Execute(t, of.templateFields()) } func (of *oneOfProtoField) GenMarshalProto() string { - t := template.Parse("oneOfMarshalProtoTemplate", []byte(oneOfMarshalProtoTemplate)) - return template.Execute(t, of.templateFields()) + t := tmplutil.Parse("oneOfMarshalProtoTemplate", []byte(oneOfMarshalProtoTemplate)) + return tmplutil.Execute(t, of.templateFields()) } func (of *oneOfProtoField) GenUnmarshalProto() string { - t := template.Parse("oneOfUnmarshalProtoTemplate", []byte(oneOfUnmarshalProtoTemplate)) - return template.Execute(t, of.templateFields()) + t := tmplutil.Parse("oneOfUnmarshalProtoTemplate", []byte(oneOfUnmarshalProtoTemplate)) + return tmplutil.Execute(t, of.templateFields()) } func (of *oneOfProtoField) templateFields() map[string]any { diff --git a/internal/cmd/pdatagen/internal/pdata/one_of_message_value.go b/internal/cmd/pdatagen/internal/pdata/one_of_message_value.go index d015703c05b9..2689a4c522b9 100644 --- a/internal/cmd/pdatagen/internal/pdata/one_of_message_value.go +++ b/internal/cmd/pdatagen/internal/pdata/one_of_message_value.go @@ -7,7 +7,7 @@ import ( "strings" "go.opentelemetry.io/collector/internal/cmd/pdatagen/internal/proto" - "go.opentelemetry.io/collector/internal/cmd/pdatagen/internal/template" + "go.opentelemetry.io/collector/internal/cmd/pdatagen/internal/tmplutil" ) const oneOfMessageAccessorsTemplate = `// {{ .fieldName }} returns the {{ .lowerFieldName }} associated with this {{ .structName }}. @@ -32,7 +32,7 @@ func (ms {{ .structName }}) {{ .fieldName }}() {{ .returnType }} { func (ms {{ .structName }}) SetEmpty{{ .fieldName }}() {{ .returnType }} { ms.state.AssertMutable() var ov *internal.{{ .originStructType }} - if !internal.UseProtoPooling.IsEnabled() { + if !metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() { ov = &internal.{{ .originStructType }}{} } else { ov = internal.ProtoPool{{ .oneOfName }}.Get().(*internal.{{ .originStructType }}) @@ -72,23 +72,23 @@ func (omv *OneOfMessageValue) GetOriginFieldName() string { } func (omv *OneOfMessageValue) GenerateAccessors(ms *messageStruct, of *OneOfField) string { - t := template.Parse("oneOfMessageAccessorsTemplate", []byte(oneOfMessageAccessorsTemplate)) - return template.Execute(t, omv.templateFields(ms, of)) + t := tmplutil.Parse("oneOfMessageAccessorsTemplate", []byte(oneOfMessageAccessorsTemplate)) + return tmplutil.Execute(t, omv.templateFields(ms, of)) } func (omv *OneOfMessageValue) GenerateTests(ms *messageStruct, of *OneOfField) string { - t := template.Parse("oneOfMessageAccessorsTestTemplate", []byte(oneOfMessageAccessorsTestTemplate)) - return template.Execute(t, omv.templateFields(ms, of)) + t := tmplutil.Parse("oneOfMessageAccessorsTestTemplate", []byte(oneOfMessageAccessorsTestTemplate)) + return tmplutil.Execute(t, omv.templateFields(ms, of)) } func (omv *OneOfMessageValue) GenerateTestValue(ms *messageStruct, of *OneOfField) string { - t := template.Parse("oneOfMessageSetTestTemplate", []byte(oneOfMessageSetTestTemplate)) - return template.Execute(t, omv.templateFields(ms, of)) + t := tmplutil.Parse("oneOfMessageSetTestTemplate", []byte(oneOfMessageSetTestTemplate)) + return tmplutil.Execute(t, omv.templateFields(ms, of)) } func (omv *OneOfMessageValue) GenerateType(ms *messageStruct, of *OneOfField) string { - t := template.Parse("oneOfMessageTypeTemplate", []byte(oneOfMessageTypeTemplate)) - return template.Execute(t, omv.templateFields(ms, of)) + t := tmplutil.Parse("oneOfMessageTypeTemplate", []byte(oneOfMessageTypeTemplate)) + return tmplutil.Execute(t, omv.templateFields(ms, of)) } func (omv *OneOfMessageValue) toProtoField(ms *messageStruct, of *OneOfField) proto.FieldInterface { diff --git a/internal/cmd/pdatagen/internal/pdata/one_of_primitive_value.go b/internal/cmd/pdatagen/internal/pdata/one_of_primitive_value.go index ea140f808f90..c250326a6948 100644 --- a/internal/cmd/pdatagen/internal/pdata/one_of_primitive_value.go +++ b/internal/cmd/pdatagen/internal/pdata/one_of_primitive_value.go @@ -7,7 +7,7 @@ import ( "strings" "go.opentelemetry.io/collector/internal/cmd/pdatagen/internal/proto" - "go.opentelemetry.io/collector/internal/cmd/pdatagen/internal/template" + "go.opentelemetry.io/collector/internal/cmd/pdatagen/internal/tmplutil" ) const oneOfPrimitiveAccessorsTemplate = `// {{ .accessorFieldName }} returns the {{ .lowerFieldName }} associated with this {{ .structName }}. @@ -19,7 +19,7 @@ func (ms {{ .structName }}) {{ .accessorFieldName }}() {{ .returnType }} { func (ms {{ .structName }}) Set{{ .accessorFieldName }}(v {{ .returnType }}) { ms.state.AssertMutable() var ov *internal.{{ .originStructType }} - if !internal.UseProtoPooling.IsEnabled() { + if !metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() { ov = &internal.{{ .originStructType }}{} } else { ov = internal.ProtoPool{{ .oneOfName }}.Get().(*internal.{{ .originStructType }}) @@ -70,23 +70,23 @@ func (opv *OneOfPrimitiveValue) GetOriginFieldName() string { } func (opv *OneOfPrimitiveValue) GenerateAccessors(ms *messageStruct, of *OneOfField) string { - t := template.Parse("oneOfPrimitiveAccessorsTemplate", []byte(oneOfPrimitiveAccessorsTemplate)) - return template.Execute(t, opv.templateFields(ms, of)) + t := tmplutil.Parse("oneOfPrimitiveAccessorsTemplate", []byte(oneOfPrimitiveAccessorsTemplate)) + return tmplutil.Execute(t, opv.templateFields(ms, of)) } func (opv *OneOfPrimitiveValue) GenerateTests(ms *messageStruct, of *OneOfField) string { - t := template.Parse("oneOfPrimitiveAccessorTestTemplate", []byte(oneOfPrimitiveAccessorTestTemplate)) - return template.Execute(t, opv.templateFields(ms, of)) + t := tmplutil.Parse("oneOfPrimitiveAccessorTestTemplate", []byte(oneOfPrimitiveAccessorTestTemplate)) + return tmplutil.Execute(t, opv.templateFields(ms, of)) } func (opv *OneOfPrimitiveValue) GenerateTestValue(ms *messageStruct, of *OneOfField) string { - t := template.Parse("oneOfPrimitiveSetTestTemplate", []byte(oneOfPrimitiveSetTestTemplate)) - return template.Execute(t, opv.templateFields(ms, of)) + t := tmplutil.Parse("oneOfPrimitiveSetTestTemplate", []byte(oneOfPrimitiveSetTestTemplate)) + return tmplutil.Execute(t, opv.templateFields(ms, of)) } func (opv *OneOfPrimitiveValue) GenerateType(ms *messageStruct, of *OneOfField) string { - t := template.Parse("oneOfPrimitiveCopyOrigTemplate", []byte(oneOfPrimitiveTypeTemplate)) - return template.Execute(t, opv.templateFields(ms, of)) + t := tmplutil.Parse("oneOfPrimitiveCopyOrigTemplate", []byte(oneOfPrimitiveTypeTemplate)) + return tmplutil.Execute(t, opv.templateFields(ms, of)) } func (opv *OneOfPrimitiveValue) toProtoField(ms *messageStruct, of *OneOfField) proto.FieldInterface { diff --git a/internal/cmd/pdatagen/internal/pdata/optional_primitive_field.go b/internal/cmd/pdatagen/internal/pdata/optional_primitive_field.go index b917664d88cf..423c5c4464d5 100644 --- a/internal/cmd/pdatagen/internal/pdata/optional_primitive_field.go +++ b/internal/cmd/pdatagen/internal/pdata/optional_primitive_field.go @@ -6,30 +6,30 @@ import ( "strings" "go.opentelemetry.io/collector/internal/cmd/pdatagen/internal/proto" - "go.opentelemetry.io/collector/internal/cmd/pdatagen/internal/template" + "go.opentelemetry.io/collector/internal/cmd/pdatagen/internal/tmplutil" ) const optionalPrimitiveAccessorsTemplate = `// {{ .fieldName }} returns the {{ .lowerFieldName }} associated with this {{ .structName }}. func (ms {{ .structName }}) {{ .fieldName }}() {{ .returnType }} { - return ms.orig.Get{{ .fieldName }}() + return ms.orig.{{ .fieldName }} } // Has{{ .fieldName }} returns true if the {{ .structName }} contains a // {{ .fieldName }} value otherwise. func (ms {{ .structName }}) Has{{ .fieldName }}() bool { - return ms.orig.{{ .fieldName }}_ != nil + return ms.orig.Has{{ .fieldName }}() } // Set{{ .fieldName }} replaces the {{ .lowerFieldName }} associated with this {{ .structName }}. func (ms {{ .structName }}) Set{{ .fieldName }}(v {{ .returnType }}) { ms.state.AssertMutable() - ms.orig.{{ .fieldName }}_ = &internal.{{ .originStructType }}{{ "{" }}{{ .fieldName }}: v} + ms.orig.Set{{ .fieldName }}(v) } // Remove{{ .fieldName }} removes the {{ .lowerFieldName }} associated with this {{ .structName }}. func (ms {{ .structName }}) Remove{{ .fieldName }}() { ms.state.AssertMutable() - ms.orig.{{ .fieldName }}_ = nil + ms.orig.Remove{{ .fieldName }}() }` const optionalPrimitiveAccessorsTestTemplate = `func Test{{ .structName }}_{{ .fieldName }}(t *testing.T) { @@ -57,16 +57,6 @@ const optionalPrimitiveAccessorsTestTemplate = `func Test{{ .structName }}_{{ .f const optionalPrimitiveSetTestTemplate = `orig.{{ .fieldName }}_ = &internal.{{ .originStructType }}{ {{- .fieldName }}: {{ .testValue }}}` -const optionalOneOfMessageOrigTemplate = ` -func (m *{{ .ParentMessageName }}) Get{{ .OneOfGroup }}() any { - if m != nil { - return m.{{ .Name }}_ - } - return nil -} - -` - type OptionalPrimitiveField struct { fieldName string protoID uint32 @@ -74,77 +64,35 @@ type OptionalPrimitiveField struct { } func (opv *OptionalPrimitiveField) GenerateAccessors(ms *messageStruct) string { - return template.Execute(template.Parse("optionalPrimitiveAccessorsTemplate", []byte(optionalPrimitiveAccessorsTemplate)), opv.templateFields(ms)) + return tmplutil.Execute(tmplutil.Parse("optionalPrimitiveAccessorsTemplate", []byte(optionalPrimitiveAccessorsTemplate)), opv.templateFields(ms)) } func (opv *OptionalPrimitiveField) GenerateAccessorsTest(ms *messageStruct) string { - return template.Execute(template.Parse("optionalPrimitiveAccessorsTestTemplate", []byte(optionalPrimitiveAccessorsTestTemplate)), opv.templateFields(ms)) + return tmplutil.Execute(tmplutil.Parse("optionalPrimitiveAccessorsTestTemplate", []byte(optionalPrimitiveAccessorsTestTemplate)), opv.templateFields(ms)) } func (opv *OptionalPrimitiveField) GenerateTestValue(ms *messageStruct) string { - return template.Execute(template.Parse("optionalPrimitiveSetTestTemplate", []byte(optionalPrimitiveSetTestTemplate)), opv.templateFields(ms)) -} - -type optionalPrimitiveProtoField struct { - *proto.Field -} - -func (opv optionalPrimitiveProtoField) GetName() string { - return opv.Name + "_" -} - -func (opv optionalPrimitiveProtoField) TestValue() string { - return "&" + opv.OneOfMessageName + "{" + opv.Name + ": " + opv.Field.TestValue() + "}" -} - -func (opv optionalPrimitiveProtoField) GenMessageField() string { - return opv.Name + "_ any" -} - -func (opv optionalPrimitiveProtoField) GenOneOfMessages() string { - return template.Execute(template.Parse("optionalOneOfMessageOrigTemplate", []byte(optionalOneOfMessageOrigTemplate)), opv.Field) + opv.Field.GenOneOfMessages() -} - -func (opv optionalPrimitiveProtoField) GenCopy() string { - return "switch t := src." + opv.Name + "_.(type) {\n\tcase *" + opv.OneOfMessageName + ":\n\t" + opv.Field.GenCopy() + "\ndefault: dest." + opv.Name + "_ = nil\n}\n" -} - -func (opv optionalPrimitiveProtoField) GenDelete() string { - return "switch ov := orig." + opv.Name + "_.(type) {\n\tcase *" + opv.OneOfMessageName + ":\n\t" + opv.Field.GenDelete() + "\n}\n" -} - -func (opv optionalPrimitiveProtoField) GenMarshalJSON() string { - return "if orig, ok := orig." + opv.Name + "_.(*" + opv.OneOfMessageName + "); ok {\n\t" + opv.Field.GenMarshalJSON() + "}" -} - -func (opv optionalPrimitiveProtoField) GenSizeProto() string { - return "if orig, ok := orig." + opv.Name + "_.(*" + opv.OneOfMessageName + "); ok {\n\t_ = orig\n\t" + opv.Field.GenSizeProto() + "}" -} - -func (opv optionalPrimitiveProtoField) GenMarshalProto() string { - return "if orig, ok := orig." + opv.Name + "_.(*" + opv.OneOfMessageName + "); ok {\n\t" + opv.Field.GenMarshalProto() + "}" + return tmplutil.Execute(tmplutil.Parse("optionalPrimitiveSetTestTemplate", []byte(optionalPrimitiveSetTestTemplate)), opv.templateFields(ms)) } func (opv *OptionalPrimitiveField) toProtoField(ms *messageStruct) proto.FieldInterface { - return optionalPrimitiveProtoField{&proto.Field{ + return &proto.Field{ Type: opv.protoType, ID: opv.protoID, - OneOfGroup: opv.fieldName + "_", Name: opv.fieldName, - OneOfMessageName: ms.protoName + "_" + opv.fieldName, ParentMessageName: ms.protoName, Nullable: true, - }} + } } func (opv *OptionalPrimitiveField) templateFields(ms *messageStruct) map[string]any { - pf := opv.toProtoField(ms).(optionalPrimitiveProtoField) + pf := opv.toProtoField(ms).(*proto.Field) return map[string]any{ "structName": ms.getName(), "defaultVal": pf.DefaultValue(), "fieldName": opv.fieldName, "lowerFieldName": strings.ToLower(opv.fieldName), - "testValue": pf.Field.TestValue(), + "testValue": pf.TestValue(), "returnType": pf.GoType(), "originName": ms.getOriginName(), "originStructName": ms.getOriginFullName(), diff --git a/internal/cmd/pdatagen/internal/pdata/pcommon_package.go b/internal/cmd/pdatagen/internal/pdata/pcommon_package.go index 0ef2c470c191..4d3ed758beb8 100644 --- a/internal/cmd/pdatagen/internal/pdata/pcommon_package.go +++ b/internal/cmd/pdatagen/internal/pdata/pcommon_package.go @@ -109,6 +109,11 @@ var keyValueStruct = &messageStruct{ protoID: 2, returnMessage: anyValueClone, }, + &PrimitiveField{ + fieldName: "KeyStrindex", + protoID: 3, + protoType: proto.TypeInt32, + }, }, hasOnlyInternal: true, } @@ -171,6 +176,12 @@ var anyValueStruct = &messageStruct{ originFieldName: "BytesValue", protoType: proto.TypeBytes, }, + &OneOfPrimitiveValue{ + fieldName: "StringValueStrindex", + protoID: 8, + originFieldName: "StringValueStrindex", + protoType: proto.TypeInt32, + }, }, }, }, diff --git a/internal/cmd/pdatagen/internal/pdata/pprofile_package.go b/internal/cmd/pdatagen/internal/pdata/pprofile_package.go index 68fb8189f2b1..b80e7f20598c 100644 --- a/internal/cmd/pdatagen/internal/pdata/pprofile_package.go +++ b/internal/cmd/pdatagen/internal/pdata/pprofile_package.go @@ -408,23 +408,23 @@ var sample = &messageStruct{ protoID: 1, protoType: proto.TypeInt32, }, - &SliceField{ - fieldName: "Values", - protoID: 2, - protoType: proto.TypeInt64, - returnSlice: int64Slice, - }, &SliceField{ fieldName: "AttributeIndices", - protoID: 3, + protoID: 2, protoType: proto.TypeInt32, returnSlice: int32Slice, }, &PrimitiveField{ fieldName: "LinkIndex", - protoID: 4, + protoID: 3, protoType: proto.TypeInt32, }, + &SliceField{ + fieldName: "Values", + protoID: 4, + protoType: proto.TypeInt64, + returnSlice: int64Slice, + }, &SliceField{ fieldName: "TimestampsUnixNano", protoID: 5, diff --git a/internal/cmd/pdatagen/internal/pdata/primitive_field.go b/internal/cmd/pdatagen/internal/pdata/primitive_field.go index 43a50198730f..3c9b462bd8f2 100644 --- a/internal/cmd/pdatagen/internal/pdata/primitive_field.go +++ b/internal/cmd/pdatagen/internal/pdata/primitive_field.go @@ -7,7 +7,7 @@ import ( "strings" "go.opentelemetry.io/collector/internal/cmd/pdatagen/internal/proto" - "go.opentelemetry.io/collector/internal/cmd/pdatagen/internal/template" + "go.opentelemetry.io/collector/internal/cmd/pdatagen/internal/tmplutil" ) const primitiveAccessorsTemplate = `// {{ .fieldName }} returns the {{ .lowerFieldName }} associated with this {{ .structName }}. @@ -56,18 +56,18 @@ type PrimitiveField struct { } func (pf *PrimitiveField) GenerateAccessors(ms *messageStruct) string { - t := template.Parse("primitiveAccessorsTemplate", []byte(primitiveAccessorsTemplate)) - return template.Execute(t, pf.templateFields(ms)) + t := tmplutil.Parse("primitiveAccessorsTemplate", []byte(primitiveAccessorsTemplate)) + return tmplutil.Execute(t, pf.templateFields(ms)) } func (pf *PrimitiveField) GenerateAccessorsTest(ms *messageStruct) string { - t := template.Parse("primitiveAccessorsTestTemplate", []byte(primitiveAccessorsTestTemplate)) - return template.Execute(t, pf.templateFields(ms)) + t := tmplutil.Parse("primitiveAccessorsTestTemplate", []byte(primitiveAccessorsTestTemplate)) + return tmplutil.Execute(t, pf.templateFields(ms)) } func (pf *PrimitiveField) GenerateTestValue(ms *messageStruct) string { - t := template.Parse("primitiveSetTestTemplate", []byte(primitiveSetTestTemplate)) - return template.Execute(t, pf.templateFields(ms)) + t := tmplutil.Parse("primitiveSetTestTemplate", []byte(primitiveSetTestTemplate)) + return tmplutil.Execute(t, pf.templateFields(ms)) } func (pf *PrimitiveField) toProtoField(*messageStruct) proto.FieldInterface { diff --git a/internal/cmd/pdatagen/internal/pdata/primitive_slice_structs.go b/internal/cmd/pdatagen/internal/pdata/primitive_slice_structs.go index b9d054f4f808..1322c59d4ff0 100644 --- a/internal/cmd/pdatagen/internal/pdata/primitive_slice_structs.go +++ b/internal/cmd/pdatagen/internal/pdata/primitive_slice_structs.go @@ -7,7 +7,7 @@ import ( "strings" "go.opentelemetry.io/collector/internal/cmd/pdatagen/internal/proto" - "go.opentelemetry.io/collector/internal/cmd/pdatagen/internal/template" + "go.opentelemetry.io/collector/internal/cmd/pdatagen/internal/tmplutil" ) // primitiveSliceStruct generates a struct for a slice of primitive value elements. The structs are always generated @@ -32,15 +32,15 @@ func (iss *primitiveSliceStruct) getPackageName() string { } func (iss *primitiveSliceStruct) generate(packageInfo *PackageInfo) []byte { - return []byte(template.Execute(primitiveSliceTemplate, iss.templateFields(packageInfo))) + return []byte(tmplutil.Execute(primitiveSliceTemplate, iss.templateFields(packageInfo))) } func (iss *primitiveSliceStruct) generateTests(packageInfo *PackageInfo) []byte { - return []byte(template.Execute(primitiveSliceTestTemplate, iss.templateFields(packageInfo))) + return []byte(tmplutil.Execute(primitiveSliceTestTemplate, iss.templateFields(packageInfo))) } func (iss *primitiveSliceStruct) generateInternal(packageInfo *PackageInfo) []byte { - return []byte(template.Execute(primitiveSliceInternalTemplate, iss.templateFields(packageInfo))) + return []byte(tmplutil.Execute(primitiveSliceInternalTemplate, iss.templateFields(packageInfo))) } func (iss *primitiveSliceStruct) getOriginName() string { diff --git a/internal/cmd/pdatagen/internal/pdata/slice_field.go b/internal/cmd/pdatagen/internal/pdata/slice_field.go index d9f355b5bb76..5a7743219712 100644 --- a/internal/cmd/pdatagen/internal/pdata/slice_field.go +++ b/internal/cmd/pdatagen/internal/pdata/slice_field.go @@ -5,7 +5,7 @@ package pdata // import "go.opentelemetry.io/collector/internal/cmd/pdatagen/int import ( "go.opentelemetry.io/collector/internal/cmd/pdatagen/internal/proto" - "go.opentelemetry.io/collector/internal/cmd/pdatagen/internal/template" + "go.opentelemetry.io/collector/internal/cmd/pdatagen/internal/tmplutil" ) const sliceAccessorTemplate = `// {{ .fieldName }} returns the {{ .fieldName }} associated with this {{ .structName }}. @@ -42,21 +42,21 @@ func (sf *SliceField) GenerateAccessors(ms *messageStruct) string { if sf.hideAccessors { return "" } - t := template.Parse("sliceAccessorTemplate", []byte(sliceAccessorTemplate)) - return template.Execute(t, sf.templateFields(ms)) + t := tmplutil.Parse("sliceAccessorTemplate", []byte(sliceAccessorTemplate)) + return tmplutil.Execute(t, sf.templateFields(ms)) } func (sf *SliceField) GenerateAccessorsTest(ms *messageStruct) string { if sf.hideAccessors { return "" } - t := template.Parse("sliceAccessorsTestTemplate", []byte(sliceAccessorsTestTemplate)) - return template.Execute(t, sf.templateFields(ms)) + t := tmplutil.Parse("sliceAccessorsTestTemplate", []byte(sliceAccessorsTestTemplate)) + return tmplutil.Execute(t, sf.templateFields(ms)) } func (sf *SliceField) GenerateTestValue(ms *messageStruct) string { - t := template.Parse("sliceSetTestTemplate", []byte(sliceSetTestTemplate)) - return template.Execute(t, sf.templateFields(ms)) + t := tmplutil.Parse("sliceSetTestTemplate", []byte(sliceSetTestTemplate)) + return tmplutil.Execute(t, sf.templateFields(ms)) } func (sf *SliceField) toProtoField(ms *messageStruct) proto.FieldInterface { diff --git a/internal/cmd/pdatagen/internal/pdata/templates.go b/internal/cmd/pdatagen/internal/pdata/templates.go index 4c90a05be890..b530dce5d75c 100644 --- a/internal/cmd/pdatagen/internal/pdata/templates.go +++ b/internal/cmd/pdatagen/internal/pdata/templates.go @@ -6,43 +6,43 @@ package pdata // import "go.opentelemetry.io/collector/internal/cmd/pdatagen/int import ( _ "embed" // Blank import required for go:embed to work. - "go.opentelemetry.io/collector/internal/cmd/pdatagen/internal/template" + "go.opentelemetry.io/collector/internal/cmd/pdatagen/internal/tmplutil" ) var ( //go:embed templates/message.go.tmpl messageTemplateBytes []byte - messageTemplate = template.Parse("message.go", messageTemplateBytes) + messageTemplate = tmplutil.Parse("message.go", messageTemplateBytes) //go:embed templates/message_internal.go.tmpl messageInternalTemplateBytes []byte - messageInternalTemplate = template.Parse("message_internal.go", messageInternalTemplateBytes) + messageInternalTemplate = tmplutil.Parse("message_internal.go", messageInternalTemplateBytes) //go:embed templates/message_test.go.tmpl messageTestTemplateBytes []byte - messageTestTemplate = template.Parse("message_test.go", messageTestTemplateBytes) + messageTestTemplate = tmplutil.Parse("message_test.go", messageTestTemplateBytes) //go:embed templates/primitive_slice.go.tmpl primitiveSliceTemplateBytes []byte - primitiveSliceTemplate = template.Parse("primitive_slice.go", primitiveSliceTemplateBytes) + primitiveSliceTemplate = tmplutil.Parse("primitive_slice.go", primitiveSliceTemplateBytes) //go:embed templates/primitive_slice_internal.go.tmpl primitiveSliceInternalTemplateBytes []byte - primitiveSliceInternalTemplate = template.Parse("primitive_slice_internal.go", primitiveSliceInternalTemplateBytes) + primitiveSliceInternalTemplate = tmplutil.Parse("primitive_slice_internal.go", primitiveSliceInternalTemplateBytes) //go:embed templates/primitive_slice_test.go.tmpl primitiveSliceTestTemplateBytes []byte - primitiveSliceTestTemplate = template.Parse("primitive_slice_test.go", primitiveSliceTestTemplateBytes) + primitiveSliceTestTemplate = tmplutil.Parse("primitive_slice_test.go", primitiveSliceTestTemplateBytes) //go:embed templates/slice.go.tmpl sliceTemplateBytes []byte - sliceTemplate = template.Parse("slice.go", sliceTemplateBytes) + sliceTemplate = tmplutil.Parse("slice.go", sliceTemplateBytes) //go:embed templates/slice_internal.go.tmpl sliceInternalTemplateBytes []byte - sliceInternalTemplate = template.Parse("slice_internal.go", sliceInternalTemplateBytes) + sliceInternalTemplate = tmplutil.Parse("slice_internal.go", sliceInternalTemplateBytes) //go:embed templates/slice_test.go.tmpl sliceTestTemplateBytes []byte - sliceTestTemplate = template.Parse("slice_test.go", sliceTestTemplateBytes) + sliceTestTemplate = tmplutil.Parse("slice_test.go", sliceTestTemplateBytes) ) diff --git a/internal/cmd/pdatagen/internal/pdata/typed_field.go b/internal/cmd/pdatagen/internal/pdata/typed_field.go index 1445066f4416..294f29beb3c2 100644 --- a/internal/cmd/pdatagen/internal/pdata/typed_field.go +++ b/internal/cmd/pdatagen/internal/pdata/typed_field.go @@ -7,7 +7,7 @@ import ( "strings" "go.opentelemetry.io/collector/internal/cmd/pdatagen/internal/proto" - "go.opentelemetry.io/collector/internal/cmd/pdatagen/internal/template" + "go.opentelemetry.io/collector/internal/cmd/pdatagen/internal/tmplutil" ) const typedAccessorsTemplate = `// {{ .fieldName }} returns the {{ .lowerFieldName }} associated with this {{ .structName }}. @@ -51,18 +51,18 @@ type TypedType struct { } func (ptf *TypedField) GenerateAccessors(ms *messageStruct) string { - t := template.Parse("typedAccessorsTemplate", []byte(typedAccessorsTemplate)) - return template.Execute(t, ptf.templateFields(ms)) + t := tmplutil.Parse("typedAccessorsTemplate", []byte(typedAccessorsTemplate)) + return tmplutil.Execute(t, ptf.templateFields(ms)) } func (ptf *TypedField) GenerateAccessorsTest(ms *messageStruct) string { - t := template.Parse("typedAccessorsTestTemplate", []byte(typedAccessorsTestTemplate)) - return template.Execute(t, ptf.templateFields(ms)) + t := tmplutil.Parse("typedAccessorsTestTemplate", []byte(typedAccessorsTestTemplate)) + return tmplutil.Execute(t, ptf.templateFields(ms)) } func (ptf *TypedField) GenerateTestValue(ms *messageStruct) string { - t := template.Parse("typedSetTestTemplate", []byte(typedSetTestTemplate)) - return template.Execute(t, ptf.templateFields(ms)) + t := tmplutil.Parse("typedSetTestTemplate", []byte(typedSetTestTemplate)) + return tmplutil.Execute(t, ptf.templateFields(ms)) } type ProtoTypedField struct { diff --git a/internal/cmd/pdatagen/internal/proto/copy.go b/internal/cmd/pdatagen/internal/proto/copy.go index 5afcb141702f..5d2fd7d35ed9 100644 --- a/internal/cmd/pdatagen/internal/proto/copy.go +++ b/internal/cmd/pdatagen/internal/proto/copy.go @@ -4,29 +4,35 @@ package proto // import "go.opentelemetry.io/collector/internal/cmd/pdatagen/internal/proto" import ( - "go.opentelemetry.io/collector/internal/cmd/pdatagen/internal/template" + "go.opentelemetry.io/collector/internal/cmd/pdatagen/internal/tmplutil" ) const copyOther = `{{ if .repeated -}} dest.{{ .fieldName }} = append(dest.{{ .fieldName }}[:0], src.{{ .fieldName }}...) -{{- else if not .nullable -}} - dest.{{ .fieldName }} = src.{{ .fieldName }} -{{ else -}} +{{ else if ne .oneOfGroup "" -}} var ov *{{ .oneOfMessageName }} - if !UseProtoPooling.IsEnabled() { + if !metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() { ov = &{{ .oneOfMessageName }}{} } else { ov = ProtoPool{{ .oneOfMessageName }}.Get().(*{{ .oneOfMessageName }}) } ov.{{ .fieldName }} = t.{{ .fieldName }} dest.{{ .oneOfGroup }} = ov +{{ else if .nullable -}} + if src.Has{{ .fieldName }}() { + dest.Set{{ .fieldName }}(src.{{ .fieldName }}) + } else { + dest.Remove{{ .fieldName }}() + } +{{ else -}} + dest.{{ .fieldName }} = src.{{ .fieldName }} {{- end }}` const copyMessage = `{{ if .repeated -}} dest.{{ .fieldName }} = Copy{{ .messageName }}{{ if .nullable }}Ptr{{ end }}Slice(dest.{{ .fieldName }}, src.{{ .fieldName }}) {{- else if ne .oneOfGroup "" -}} var ov *{{ .oneOfMessageName }} - if !UseProtoPooling.IsEnabled() { + if !metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() { ov = &{{ .oneOfMessageName }}{} } else { ov = ProtoPool{{ .oneOfMessageName }}.Get().(*{{ .oneOfMessageName }}) @@ -44,7 +50,7 @@ const copyMessage = `{{ if .repeated -}} func (pf *Field) GenCopy() string { tf := pf.getTemplateFields() if pf.Type == TypeMessage { - return template.Execute(template.Parse("copyMessage", []byte(copyMessage)), tf) + return tmplutil.Execute(tmplutil.Parse("copyMessage", []byte(copyMessage)), tf) } - return template.Execute(template.Parse("copyOther", []byte(copyOther)), tf) + return tmplutil.Execute(tmplutil.Parse("copyOther", []byte(copyOther)), tf) } diff --git a/internal/cmd/pdatagen/internal/proto/delete.go b/internal/cmd/pdatagen/internal/proto/delete.go index 9ddc23d2c418..bbcd5a539cf7 100644 --- a/internal/cmd/pdatagen/internal/proto/delete.go +++ b/internal/cmd/pdatagen/internal/proto/delete.go @@ -4,23 +4,23 @@ package proto // import "go.opentelemetry.io/collector/internal/cmd/pdatagen/internal/proto" import ( - "go.opentelemetry.io/collector/internal/cmd/pdatagen/internal/template" + "go.opentelemetry.io/collector/internal/cmd/pdatagen/internal/tmplutil" ) const deleteOther = `{{ if ne .oneOfGroup "" -}} - if UseProtoPooling.IsEnabled() { + if metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() { ov.{{ .fieldName }} = {{ .defaultValue }} ProtoPool{{ .oneOfMessageName }}.Put(ov) } -{{ end }}` +{{- end -}}` const deleteMessage = `{{ if .repeated -}} for i := range orig.{{ .fieldName }} { {{ if .nullable -}} Delete{{ .messageName }}(orig.{{ .fieldName }}[i], true) - {{- else -}} + {{ else -}} Delete{{ .messageName }}(&orig.{{ .fieldName }}[i], false) - {{- end }} + {{- end -}} } {{- else if ne .oneOfGroup "" -}} Delete{{ .messageName }}(ov.{{ .fieldName }}, true) @@ -30,16 +30,16 @@ const deleteMessage = `{{ if .repeated -}} Delete{{ .messageName }}(orig.{{ .fieldName }}, true) {{- else -}} Delete{{ .messageName }}(&orig.{{ .fieldName }}, false) -{{- end }} +{{- end -}} ` func (pf *Field) GenDelete() string { tf := pf.getTemplateFields() if pf.Type == TypeMessage { - return template.Execute(template.Parse("deleteMessage", []byte(deleteMessage)), tf) + return tmplutil.Execute(tmplutil.Parse("deleteMessage", []byte(deleteMessage)), tf) } if pf.OneOfGroup != "" { - return template.Execute(template.Parse("deleteOther", []byte(deleteOther)), tf) + return tmplutil.Execute(tmplutil.Parse("deleteOther", []byte(deleteOther)), tf) } return "" } diff --git a/internal/cmd/pdatagen/internal/proto/enum.go b/internal/cmd/pdatagen/internal/proto/enum.go index f347c11cf903..0aff51a9dc65 100644 --- a/internal/cmd/pdatagen/internal/proto/enum.go +++ b/internal/cmd/pdatagen/internal/proto/enum.go @@ -4,7 +4,7 @@ package proto // import "go.opentelemetry.io/collector/internal/cmd/pdatagen/internal/proto" import ( - "go.opentelemetry.io/collector/internal/cmd/pdatagen/internal/template" + "go.opentelemetry.io/collector/internal/cmd/pdatagen/internal/tmplutil" ) const enumMessageTemplate = ` @@ -51,15 +51,5 @@ type EnumField struct { } func (ms *Enum) GenerateEnum() []byte { - return []byte(template.Execute(template.Parse("enumMessageTemplate", []byte(enumMessageTemplate)), ms)) -} - -func (ms *Enum) templateFields(imports, testImports []string) map[string]any { - return map[string]any{ - "fields": ms.Fields, - "messageName": ms.Name, - "description": ms.Description, - "imports": imports, - "testImports": testImports, - } + return []byte(tmplutil.Execute(tmplutil.Parse("enumMessageTemplate", []byte(enumMessageTemplate)), ms)) } diff --git a/internal/cmd/pdatagen/internal/proto/field.go b/internal/cmd/pdatagen/internal/proto/field.go index 1fe80faba409..fda58db9ab26 100644 --- a/internal/cmd/pdatagen/internal/proto/field.go +++ b/internal/cmd/pdatagen/internal/proto/field.go @@ -35,6 +35,8 @@ type FieldInterface interface { GenOneOfMessages() string + GenTest() string + GoType() string DefaultValue() string @@ -105,6 +107,17 @@ func (pf *Field) DefaultValue() string { } } +func (pf *Field) GenTest() string { + if pf.Repeated { + return "orig." + pf.GetName() + " = " + pf.TestValue() + } + + if pf.Type != TypeMessage && pf.Nullable { + return "orig.Set" + pf.GetName() + "(" + pf.TestValue() + ")" + } + return "orig." + pf.GetName() + " = " + pf.TestValue() +} + func (pf *Field) TestValue() string { if pf.Repeated { return pf.MemberGoType() + "{" + pf.DefaultValue() + ", " + pf.rawTestValue() + "}" @@ -171,7 +184,10 @@ func (pf *Field) MemberGoType() string { if pf.Repeated { return "[]" + ptrGoType() } - return ptrGoType() + if pf.Type == TypeMessage { + return ptrGoType() + } + return pf.GoType() } func (pf *Field) GenMessageField() string { @@ -218,7 +234,6 @@ func genProtoTag(fieldNumber uint32, wt WireType) []string { i := 0 keybuf := make([]byte, 0) for i = 0; x > 127; i++ { - //nolint:gosec keybuf = append(keybuf, 0x80|uint8(x&0x7F)) x >>= 7 } diff --git a/internal/cmd/pdatagen/internal/proto/json_marshal.go b/internal/cmd/pdatagen/internal/proto/json_marshal.go index d2ef34b0ff88..812bb27d1270 100644 --- a/internal/cmd/pdatagen/internal/proto/json_marshal.go +++ b/internal/cmd/pdatagen/internal/proto/json_marshal.go @@ -6,7 +6,7 @@ package proto // import "go.opentelemetry.io/collector/internal/cmd/pdatagen/int import ( "fmt" - "go.opentelemetry.io/collector/internal/cmd/pdatagen/internal/template" + "go.opentelemetry.io/collector/internal/cmd/pdatagen/internal/tmplutil" ) const marshalJSONPrimitive = `{{ if .repeated -}} @@ -20,15 +20,19 @@ const marshalJSONPrimitive = `{{ if .repeated -}} } dest.WriteArrayEnd() } +{{ else if ne .oneOfGroup "" -}} + dest.WriteObjectField("{{ .jsonTag }}") + dest.Write{{ upperFirst .goType }}(orig.{{ .fieldName }}) {{- else }} {{- if not .nullable -}} if orig.{{ .fieldName }} != {{ .defaultValue }} { +{{- else -}} + if orig.Has{{ .fieldName }} () { {{ end -}} dest.WriteObjectField("{{ .jsonTag }}") dest.Write{{ upperFirst .goType }}(orig.{{ .fieldName }}) -{{- if not .nullable -}} } -{{- end }}{{- end }}` +{{- end }}` const marshalJSONEnum = `{{ if .repeated -}} if len(orig.{{ .fieldName }}) > 0 { @@ -93,17 +97,17 @@ func (pf *Field) GenMarshalJSON() string { tf := pf.getTemplateFields() switch pf.Type { case TypeBytes: - return template.Execute(template.Parse("marshalJSONBytes", []byte(marshalJSONBytes)), tf) + return tmplutil.Execute(tmplutil.Parse("marshalJSONBytes", []byte(marshalJSONBytes)), tf) case TypeMessage: - return template.Execute(template.Parse("marshalJSONMessage", []byte(marshalJSONMessage)), tf) + return tmplutil.Execute(tmplutil.Parse("marshalJSONMessage", []byte(marshalJSONMessage)), tf) case TypeEnum: - return template.Execute(template.Parse("marshalJSONEnum", []byte(marshalJSONEnum)), tf) + return tmplutil.Execute(tmplutil.Parse("marshalJSONEnum", []byte(marshalJSONEnum)), tf) case TypeDouble, TypeFloat, TypeFixed64, TypeSFixed64, TypeFixed32, TypeSFixed32, TypeInt32, TypeInt64, TypeUint32, TypeUint64, TypeSInt32, TypeSInt64, TypeBool, TypeString: - return template.Execute(template.Parse("marshalJSONPrimitive", []byte(marshalJSONPrimitive)), tf) + return tmplutil.Execute(tmplutil.Parse("marshalJSONPrimitive", []byte(marshalJSONPrimitive)), tf) } panic(fmt.Sprintf("unhandled case %T", pf.Type)) } diff --git a/internal/cmd/pdatagen/internal/proto/json_unmarshal.go b/internal/cmd/pdatagen/internal/proto/json_unmarshal.go index bdb288640f67..f721b3ddeed6 100644 --- a/internal/cmd/pdatagen/internal/proto/json_unmarshal.go +++ b/internal/cmd/pdatagen/internal/proto/json_unmarshal.go @@ -9,7 +9,7 @@ import ( "github.com/ettle/strcase" - "go.opentelemetry.io/collector/internal/cmd/pdatagen/internal/template" + "go.opentelemetry.io/collector/internal/cmd/pdatagen/internal/tmplutil" ) const unmarshalJSONPrimitive = ` case {{ .allJSONTags }}: @@ -17,10 +17,10 @@ const unmarshalJSONPrimitive = ` case {{ .allJSONTags }}: for iter.ReadArray() { orig.{{ .fieldName }} = append(orig.{{ .fieldName }}, iter.Read{{ upperFirst .goType }}()) } -{{ else if .nullable -}} +{{ else if ne .oneOfGroup "" -}} { var ov *{{ .oneOfMessageName }} - if !UseProtoPooling.IsEnabled() { + if !metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() { ov = &{{ .oneOfMessageName }}{} } else { ov = ProtoPool{{ .oneOfMessageName }}.Get().(*{{ .oneOfMessageName }}) @@ -28,6 +28,8 @@ const unmarshalJSONPrimitive = ` case {{ .allJSONTags }}: ov.{{ .fieldName }} = iter.Read{{ upperFirst .goType }}() orig.{{ .oneOfGroup }} = ov } +{{ else if .nullable -}} + orig.Set{{ .fieldName }}(iter.Read{{ upperFirst .goType }}()) {{ else -}} orig.{{ .fieldName }} = iter.Read{{ upperFirst .goType }}() {{- end }}` @@ -50,7 +52,7 @@ const unmarshalJSONMessage = ` case {{ .allJSONTags }}: {{ else if ne .oneOfGroup "" -}} { var ov *{{ .oneOfMessageName }} - if !UseProtoPooling.IsEnabled() { + if !metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() { ov = &{{ .oneOfMessageName }}{} } else { ov = ProtoPool{{ .oneOfMessageName }}.Get().(*{{ .oneOfMessageName }}) @@ -72,7 +74,7 @@ const unmarshalJSONBytes = ` case {{ .allJSONTags }}: {{ else if ne .oneOfGroup "" -}} { var ov *{{ .oneOfMessageName }} - if !UseProtoPooling.IsEnabled() { + if !metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() { ov = &{{ .oneOfMessageName }}{} } else { ov = ProtoPool{{ .oneOfMessageName }}.Get().(*{{ .oneOfMessageName }}) @@ -89,17 +91,17 @@ func (pf *Field) GenUnmarshalJSON() string { tf["allJSONTags"] = allJSONTags(pf.Name) switch pf.Type { case TypeBytes: - return template.Execute(template.Parse("unmarshalJSONBytes", []byte(unmarshalJSONBytes)), tf) + return tmplutil.Execute(tmplutil.Parse("unmarshalJSONBytes", []byte(unmarshalJSONBytes)), tf) case TypeMessage: - return template.Execute(template.Parse("unmarshalJSONMessage", []byte(unmarshalJSONMessage)), tf) + return tmplutil.Execute(tmplutil.Parse("unmarshalJSONMessage", []byte(unmarshalJSONMessage)), tf) case TypeEnum: - return template.Execute(template.Parse("unmarshalJSONEnum", []byte(unmarshalJSONEnum)), tf) + return tmplutil.Execute(tmplutil.Parse("unmarshalJSONEnum", []byte(unmarshalJSONEnum)), tf) case TypeDouble, TypeFloat, TypeFixed64, TypeSFixed64, TypeFixed32, TypeSFixed32, TypeInt32, TypeInt64, TypeUint32, TypeUint64, TypeSInt32, TypeSInt64, TypeBool, TypeString: - return template.Execute(template.Parse("unmarshalJSONPrimitive", []byte(unmarshalJSONPrimitive)), tf) + return tmplutil.Execute(tmplutil.Parse("unmarshalJSONPrimitive", []byte(unmarshalJSONPrimitive)), tf) } panic(fmt.Sprintf("unhandled case %T", pf.Type)) } diff --git a/internal/cmd/pdatagen/internal/proto/message.go b/internal/cmd/pdatagen/internal/proto/message.go index f7f060f69555..0e34670f320e 100644 --- a/internal/cmd/pdatagen/internal/proto/message.go +++ b/internal/cmd/pdatagen/internal/proto/message.go @@ -6,17 +6,17 @@ package proto // import "go.opentelemetry.io/collector/internal/cmd/pdatagen/int import ( _ "embed" - "go.opentelemetry.io/collector/internal/cmd/pdatagen/internal/template" + "go.opentelemetry.io/collector/internal/cmd/pdatagen/internal/tmplutil" ) var ( //go:embed templates/message.go.tmpl messageTemplateBytes []byte - messageTemplate = template.Parse("message_internal_test.go", messageTemplateBytes) + messageTemplate = tmplutil.Parse("message_internal_test.go", messageTemplateBytes) //go:embed templates/message_test.go.tmpl messageTestTemplateBytes []byte - messageTestTemplate = template.Parse("message_internal_test.go", messageTestTemplateBytes) + messageTestTemplate = tmplutil.Parse("message_internal_test.go", messageTestTemplateBytes) ) type Message struct { @@ -25,14 +25,20 @@ type Message struct { OriginFullName string UpstreamMessage string Fields []FieldInterface + metadata *Metadata } func (ms *Message) GenerateMessage(imports, testImports []string) []byte { - return []byte(template.Execute(messageTemplate, ms.templateFields(imports, testImports))) + ms.metadata = newMetadata(ms) + return []byte(tmplutil.Execute(messageTemplate, ms.templateFields(imports, testImports))) } func (ms *Message) GenerateMessageTests(imports, testImports []string) []byte { - return []byte(template.Execute(messageTestTemplate, ms.templateFields(imports, testImports))) + return []byte(tmplutil.Execute(messageTestTemplate, ms.templateFields(imports, testImports))) +} + +func (ms *Message) GenerateMetadata() string { + return string(ms.metadata.Generate()) } func (ms *Message) templateFields(imports, testImports []string) map[string]any { @@ -43,5 +49,20 @@ func (ms *Message) templateFields(imports, testImports []string) map[string]any "description": ms.Description, "imports": imports, "testImports": testImports, + // 0 size means no metadata is needed + "metadataSize": ms.metadataSize(), + "GenerateMetadata": ms.GenerateMetadata, + } +} + +func (ms *Message) metadataSize() int { + if ms.metadata == nil { + return 0 + } + + if len(ms.metadata.OptionalFields) == 0 { + return 0 } + + return ms.metadata.OptionalFields[len(ms.metadata.OptionalFields)-1].Value/64 + 1 } diff --git a/internal/cmd/pdatagen/internal/proto/metadata.go b/internal/cmd/pdatagen/internal/proto/metadata.go new file mode 100644 index 000000000000..a06050e66211 --- /dev/null +++ b/internal/cmd/pdatagen/internal/proto/metadata.go @@ -0,0 +1,77 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +package proto // import "go.opentelemetry.io/collector/internal/cmd/pdatagen/internal/proto" + +import ( + "go.opentelemetry.io/collector/internal/cmd/pdatagen/internal/tmplutil" +) + +const metadataMessageTemplate = ` +{{- range .OptionalFields }} +const fieldBlock{{ $.Name }}{{ .Name }} = uint64({{ .Value }} >> 6) +const fieldBit{{ $.Name }}{{ .Name }} = uint64(1 << {{ .Value }} & 0x3F) + +func (m *{{ $.Name }}) Set{{ .Name }}(value {{ .GoType }}) { + m.{{ .Name }} = value + m.metadata[fieldBlock{{ $.Name }}{{ .Name }}] |= fieldBit{{ $.Name }}{{ .Name }} +} + +func (m *{{ $.Name }}) Remove{{ .Name }}() { + m.{{ .Name }} = {{ .DefaultValue }} + m.metadata[fieldBlock{{ $.Name }}{{ .Name }}] &^= fieldBit{{ $.Name }}{{ .Name }} +} + +func (m *{{ $.Name }}) Has{{ .Name }}() bool { + return m.metadata[fieldBlock{{ $.Name }}{{ .Name }}] & fieldBit{{ $.Name }}{{ .Name }} != 0 +} +{{- end }} + +` + +type Metadata struct { + Name string + OptionalFields []*MetadataOptionalField +} + +type MetadataOptionalField struct { + *Field + Value int +} + +func newMetadata(ms *Message) *Metadata { + meta := &Metadata{ + Name: ms.Name, + } + value := 0 + for _, fieldI := range ms.Fields { + field, ok := fieldI.(*Field) + if !ok { + continue + } + if field.Repeated { + continue + } + switch field.Type { + case TypeDouble, TypeFloat, TypeInt32, TypeInt64, TypeUint32, TypeUint64, TypeSInt32, TypeSInt64, TypeFixed32, TypeFixed64, TypeSFixed32, TypeSFixed64, TypeBool: + if !field.Nullable { + continue + } + default: + continue + } + meta.OptionalFields = append(meta.OptionalFields, &MetadataOptionalField{ + Field: field, + Value: value, + }) + value++ + } + if len(meta.OptionalFields) == 0 { + return nil + } + return meta +} + +func (meta *Metadata) Generate() []byte { + return []byte(tmplutil.Execute(tmplutil.Parse("metadataMessageTemplate", []byte(metadataMessageTemplate)), meta)) +} diff --git a/internal/cmd/pdatagen/internal/proto/oneof_message.go b/internal/cmd/pdatagen/internal/proto/oneof_message.go index 0b5213ed87d4..abd2e56a5983 100644 --- a/internal/cmd/pdatagen/internal/proto/oneof_message.go +++ b/internal/cmd/pdatagen/internal/proto/oneof_message.go @@ -4,7 +4,7 @@ package proto // import "go.opentelemetry.io/collector/internal/cmd/pdatagen/internal/proto" import ( - "go.opentelemetry.io/collector/internal/cmd/pdatagen/internal/template" + "go.opentelemetry.io/collector/internal/cmd/pdatagen/internal/tmplutil" ) const oneOfMessageOrigOtherTemplate = ` @@ -37,9 +37,9 @@ func (pf *Field) GenOneOfMessages() string { tf := pf.getTemplateFields() if pf.OneOfGroup != "" { if pf.Type == TypeMessage { - return template.Execute(template.Parse("oneOfMessageOrigMessageTemplate", []byte(oneOfMessageOrigMessageTemplate)), tf) + return tmplutil.Execute(tmplutil.Parse("oneOfMessageOrigMessageTemplate", []byte(oneOfMessageOrigMessageTemplate)), tf) } - return template.Execute(template.Parse("oneOfMessageOrigOtherTemplate", []byte(oneOfMessageOrigOtherTemplate)), tf) + return tmplutil.Execute(tmplutil.Parse("oneOfMessageOrigOtherTemplate", []byte(oneOfMessageOrigOtherTemplate)), tf) } return "" } diff --git a/internal/cmd/pdatagen/internal/proto/pools.go b/internal/cmd/pdatagen/internal/proto/pools.go index f028aa9d7fbc..617ee749110e 100644 --- a/internal/cmd/pdatagen/internal/proto/pools.go +++ b/internal/cmd/pdatagen/internal/proto/pools.go @@ -4,7 +4,7 @@ package proto // import "go.opentelemetry.io/collector/internal/cmd/pdatagen/internal/proto" import ( - "go.opentelemetry.io/collector/internal/cmd/pdatagen/internal/template" + "go.opentelemetry.io/collector/internal/cmd/pdatagen/internal/tmplutil" ) const poolVarOrigTemplate = ` @@ -18,7 +18,7 @@ const poolVarOrigTemplate = ` func (pf *Field) GenPool() string { tf := pf.getTemplateFields() if pf.OneOfGroup != "" { - return template.Execute(template.Parse("poolVarOrigTemplate", []byte(poolVarOrigTemplate)), tf) + return tmplutil.Execute(tmplutil.Parse("poolVarOrigTemplate", []byte(poolVarOrigTemplate)), tf) } return "" } diff --git a/internal/cmd/pdatagen/internal/proto/proto_marshal.go b/internal/cmd/pdatagen/internal/proto/proto_marshal.go index 62713bfc8749..81bc7ebb085f 100644 --- a/internal/cmd/pdatagen/internal/proto/proto_marshal.go +++ b/internal/cmd/pdatagen/internal/proto/proto_marshal.go @@ -6,7 +6,7 @@ package proto // import "go.opentelemetry.io/collector/internal/cmd/pdatagen/int import ( "fmt" - "go.opentelemetry.io/collector/internal/cmd/pdatagen/internal/template" + "go.opentelemetry.io/collector/internal/cmd/pdatagen/internal/tmplutil" ) const marshalProtoFloat = `{{ if .repeated -}} @@ -22,19 +22,27 @@ const marshalProtoFloat = `{{ if .repeated -}} buf[pos] = {{ . }} {{ end -}} } +{{- else if ne .oneOfGroup "" -}} + pos -= {{ div .bitSize 8 }} + binary.LittleEndian.PutUint{{ .bitSize }}(buf[pos:], math.Float{{ .bitSize }}bits(orig.{{ .fieldName }})) + {{ range .protoTag -}} + pos-- + buf[pos] = {{ . }} + {{ end -}} {{- else }} -{{- if not .nullable -}} - if orig.{{ .fieldName }} != 0 { -{{ end -}} + {{- if not .nullable -}} + if orig.{{ .fieldName }} != {{ .defaultValue }} { + {{- else -}} + if orig.Has{{ .fieldName }}() { + {{- end }} pos -= {{ div .bitSize 8 }} binary.LittleEndian.PutUint{{ .bitSize }}(buf[pos:], math.Float{{ .bitSize }}bits(orig.{{ .fieldName }})) {{ range .protoTag -}} pos-- buf[pos] = {{ . }} {{ end -}} -{{- if not .nullable -}} } -{{- end }}{{- end }}` +{{- end }}` const marshalProtoFixed = `{{ if .repeated -}} l = len(orig.{{ .fieldName }}) @@ -49,19 +57,27 @@ const marshalProtoFixed = `{{ if .repeated -}} buf[pos] = {{ . }} {{ end -}} } +{{- else if ne .oneOfGroup "" -}} + pos -= {{ div .bitSize 8 }} + binary.LittleEndian.PutUint{{ .bitSize }}(buf[pos:], uint{{ .bitSize }}(orig.{{ .fieldName }})) + {{ range .protoTag -}} + pos-- + buf[pos] = {{ . }} + {{ end -}} {{- else }} -{{- if not .nullable -}} - if orig.{{ .fieldName }} != 0 { -{{ end -}} + {{- if not .nullable -}} + if orig.{{ .fieldName }} != {{ .defaultValue }} { + {{- else -}} + if orig.Has{{ .fieldName }}() { + {{- end }} pos -= {{ div .bitSize 8 }} binary.LittleEndian.PutUint{{ .bitSize }}(buf[pos:], uint{{ .bitSize }}(orig.{{ .fieldName }})) {{ range .protoTag -}} pos-- buf[pos] = {{ . }} {{ end -}} -{{- if not .nullable -}} } -{{- end }}{{- end }}` +{{- end }}` const marshalProtoBool = `{{ if .repeated -}} l = len(orig.{{ .fieldName }}) @@ -80,10 +96,23 @@ const marshalProtoBool = `{{ if .repeated -}} buf[pos] = {{ . }} {{ end -}} } +{{- else if ne .oneOfGroup "" -}} + pos-- + if orig.{{ .fieldName }} { + buf[pos] = 1 + } else { + buf[pos] = 0 + } + {{ range .protoTag -}} + pos-- + buf[pos] = {{ . }} + {{ end -}} {{- else }} -{{- if not .nullable -}} - if orig.{{ .fieldName }} { -{{ end -}} + {{- if not .nullable -}} + if orig.{{ .fieldName }} != {{ .defaultValue }} { + {{- else -}} + if orig.Has{{ .fieldName }}() { + {{- end }} pos-- if orig.{{ .fieldName }} { buf[pos] = 1 @@ -94,9 +123,8 @@ const marshalProtoBool = `{{ if .repeated -}} pos-- buf[pos] = {{ . }} {{ end -}} -{{- if not .nullable -}} } -{{- end }}{{- end }}` +{{- end }}` const marshalProtoVarint = `{{ if .repeated -}} l = len(orig.{{ .fieldName }}) @@ -111,18 +139,25 @@ const marshalProtoVarint = `{{ if .repeated -}} buf[pos] = {{ . }} {{ end -}} } +{{- else if ne .oneOfGroup "" -}} + pos = proto.EncodeVarint(buf, pos, uint64(orig.{{ .fieldName }})) + {{ range .protoTag -}} + pos-- + buf[pos] = {{ . }} + {{ end -}} {{- else }} -{{- if not .nullable -}} - if orig.{{ .fieldName }} != 0 { -{{ end -}} + {{- if not .nullable -}} + if orig.{{ .fieldName }} != {{ .defaultValue }} { + {{- else -}} + if orig.Has{{ .fieldName }}() { + {{- end }} pos = proto.EncodeVarint(buf, pos, uint64(orig.{{ .fieldName }})) {{ range .protoTag -}} pos-- buf[pos] = {{ . }} {{ end -}} -{{- if not .nullable -}} } -{{- end }}{{- end }}` +{{- end }}` const marshalProtoBytesString = `{{ if .repeated -}} for i := len(orig.{{ .fieldName }}) - 1; i >= 0; i-- { @@ -194,36 +229,43 @@ const marshalProtoSignedVarint = `{{ if .repeated -}} buf[pos] = {{ . }} {{ end -}} } +{{- else if ne .oneOfGroup "" -}} + pos = proto.EncodeVarint(buf, pos, uint64((uint{{ .bitSize }}(orig.{{ .fieldName }})<<1)^uint{{ .bitSize }}(orig.{{ .fieldName }}>>{{ sub .bitSize 1}}))) + {{ range .protoTag -}} + pos-- + buf[pos] = {{ . }} + {{ end -}} {{- else }} -{{- if not .nullable -}} - if orig.{{ .fieldName }} != 0 { -{{ end -}} + {{- if not .nullable -}} + if orig.{{ .fieldName }} != {{ .defaultValue }} { + {{- else -}} + if orig.Has{{ .fieldName }}() { + {{- end }} pos = proto.EncodeVarint(buf, pos, uint64((uint{{ .bitSize }}(orig.{{ .fieldName }})<<1)^uint{{ .bitSize }}(orig.{{ .fieldName }}>>{{ sub .bitSize 1}}))) {{ range .protoTag -}} pos-- buf[pos] = {{ . }} {{ end -}} -{{- if not .nullable -}} } -{{- end }}{{- end }}` +{{- end }}` func (pf *Field) GenMarshalProto() string { tf := pf.getTemplateFields() switch pf.Type { case TypeDouble, TypeFloat: - return template.Execute(template.Parse("marshalProtoFloat", []byte(marshalProtoFloat)), tf) + return tmplutil.Execute(tmplutil.Parse("marshalProtoFloat", []byte(marshalProtoFloat)), tf) case TypeFixed64, TypeSFixed64, TypeFixed32, TypeSFixed32: - return template.Execute(template.Parse("marshalProtoFixed", []byte(marshalProtoFixed)), tf) + return tmplutil.Execute(tmplutil.Parse("marshalProtoFixed", []byte(marshalProtoFixed)), tf) case TypeInt32, TypeInt64, TypeUint32, TypeUint64, TypeEnum: - return template.Execute(template.Parse("marshalProtoVarint", []byte(marshalProtoVarint)), tf) + return tmplutil.Execute(tmplutil.Parse("marshalProtoVarint", []byte(marshalProtoVarint)), tf) case TypeBool: - return template.Execute(template.Parse("marshalProtoBool", []byte(marshalProtoBool)), tf) + return tmplutil.Execute(tmplutil.Parse("marshalProtoBool", []byte(marshalProtoBool)), tf) case TypeBytes, TypeString: - return template.Execute(template.Parse("marshalProtoBytesString", []byte(marshalProtoBytesString)), tf) + return tmplutil.Execute(tmplutil.Parse("marshalProtoBytesString", []byte(marshalProtoBytesString)), tf) case TypeMessage: - return template.Execute(template.Parse("marshalProtoMessage", []byte(marshalProtoMessage)), tf) + return tmplutil.Execute(tmplutil.Parse("marshalProtoMessage", []byte(marshalProtoMessage)), tf) case TypeSInt32, TypeSInt64: - return template.Execute(template.Parse("marshalProtoSignedVarint", []byte(marshalProtoSignedVarint)), tf) + return tmplutil.Execute(tmplutil.Parse("marshalProtoSignedVarint", []byte(marshalProtoSignedVarint)), tf) } panic(fmt.Sprintf("unhandled case %T", pf.Type)) } diff --git a/internal/cmd/pdatagen/internal/proto/proto_size.go b/internal/cmd/pdatagen/internal/proto/proto_size.go index 26cbb50ec3b6..87ce618a2088 100644 --- a/internal/cmd/pdatagen/internal/proto/proto_size.go +++ b/internal/cmd/pdatagen/internal/proto/proto_size.go @@ -6,7 +6,7 @@ package proto // import "go.opentelemetry.io/collector/internal/cmd/pdatagen/int import ( "fmt" - "go.opentelemetry.io/collector/internal/cmd/pdatagen/internal/template" + "go.opentelemetry.io/collector/internal/cmd/pdatagen/internal/tmplutil" ) const sizeProtoI8 = `{{ if .repeated -}} @@ -15,12 +15,16 @@ const sizeProtoI8 = `{{ if .repeated -}} l *= 8 n+= {{ .protoTagSize }} + proto.Sov(uint64(l)) + l } -{{- else if not .nullable -}} - if orig.{{ .fieldName }} != 0 { +{{- else if ne .oneOfGroup "" }} + n+= {{ add .protoTagSize 8 }} +{{- else }} + {{- if not .nullable -}} + if orig.{{ .fieldName }} != {{ .defaultValue }} { + {{- else -}} + if orig.Has{{ .fieldName }}() { + {{- end }} n+= {{ add .protoTagSize 8 }} } -{{- else -}} - n+= {{ add .protoTagSize 8 }} {{- end }}` const sizeProtoI4 = `{{ if .repeated -}} @@ -29,12 +33,16 @@ const sizeProtoI4 = `{{ if .repeated -}} l *= 4 n+= + {{ .protoTagSize }} + proto.Sov(uint64(l)) + l } -{{- else if not .nullable -}} - if orig.{{ .fieldName }} != 0 { +{{- else if ne .oneOfGroup "" }} + n+= {{ add .protoTagSize 4 }} +{{- else }} + {{- if not .nullable -}} + if orig.{{ .fieldName }} != {{ .defaultValue }} { + {{- else -}} + if orig.Has{{ .fieldName }}() { + {{- end }} n+= {{ add .protoTagSize 4 }} } -{{- else -}} - n+= {{ add .protoTagSize 4 }} {{- end }}` const sizeProtoBool = `{{ if .repeated -}} @@ -42,15 +50,19 @@ const sizeProtoBool = `{{ if .repeated -}} if l > 0 { n+= + {{ .protoTagSize }} + proto.Sov(uint64(l)) + l } -{{- else if not .nullable -}} - if orig.{{ .fieldName }} { +{{- else if ne .oneOfGroup "" }} n+= {{ add .protoTagSize 1 }} - } {{- else -}} - n+= {{ add .protoTagSize 1 }} + {{- if not .nullable -}} + if orig.{{ .fieldName }} != {{ .defaultValue }} { + {{- else -}} + if orig.Has{{ .fieldName }}() { + {{- end }} + n+= {{ add .protoTagSize 1 }} + } {{- end }}` -const sizeProtoVarint = `{{ if .repeated -}} +const sizeProtoVarint = `{{ if .repeated }} if len(orig.{{ .fieldName }}) > 0 { l = 0 for _, e := range orig.{{ .fieldName }} { @@ -58,12 +70,16 @@ const sizeProtoVarint = `{{ if .repeated -}} } n+= {{ .protoTagSize }} + proto.Sov(uint64(l)) + l } -{{- else if not .nullable -}} - if orig.{{ .fieldName }} != 0 { +{{- else if ne .oneOfGroup "" }} + n+= {{ .protoTagSize }} + proto.Sov(uint64(orig.{{ .fieldName }})) +{{- else }} + {{- if not .nullable -}} + if orig.{{ .fieldName }} != {{ .defaultValue }} { + {{- else -}} + if orig.Has{{ .fieldName }}() { + {{- end }} n+= {{ .protoTagSize }} + proto.Sov(uint64(orig.{{ .fieldName }})) } -{{- else -}} - n+= {{ .protoTagSize }} + proto.Sov(uint64(orig.{{ .fieldName }})) {{- end }}` const sizeProtoBytesString = `{{ if .repeated -}} @@ -71,14 +87,14 @@ const sizeProtoBytesString = `{{ if .repeated -}} l = len(s) n+= {{ .protoTagSize }} + proto.Sov(uint64(l)) + l } -{{- else if not .nullable -}} +{{- else if ne .oneOfGroup "" -}} + l = len(orig.{{ .fieldName }}) + n+= {{ .protoTagSize }} + proto.Sov(uint64(l)) + l +{{- else }} l = len(orig.{{ .fieldName }}) if l > 0 { n+= {{ .protoTagSize }} + proto.Sov(uint64(l)) + l } -{{- else -}} - l = len(orig.{{ .fieldName }}) - n+= {{ .protoTagSize }} + proto.Sov(uint64(l)) + l {{- end }}` const sizeProtoMessage = `{{ if .repeated -}} @@ -104,31 +120,35 @@ const sizeProtoSignedVarint = `{{ if .repeated -}} } n+= {{ .protoTagSize }} + proto.Sov(uint64(l)) + l } -{{- else if not .nullable -}} - if orig.{{ .fieldName }} != 0 { +{{- else if ne .oneOfGroup "" -}} + n+= {{ .protoTagSize }} + proto.Soz(uint64(orig.{{ .fieldName }})) +{{- else -}} + {{- if not .nullable -}} + if orig.{{ .fieldName }} != {{ .defaultValue }} { + {{- else -}} + if orig.Has{{ .fieldName }}() { + {{- end }} n+= {{ .protoTagSize }} + proto.Soz(uint64(orig.{{ .fieldName }})) } -{{- else -}} - n+= {{ .protoTagSize }} + proto.Soz(uint64(orig.{{ .fieldName }})) {{- end }}` func (pf *Field) GenSizeProto() string { tf := pf.getTemplateFields() switch pf.Type { case TypeFixed64, TypeSFixed64, TypeDouble: - return template.Execute(template.Parse("sizeProtoI8", []byte(sizeProtoI8)), tf) + return tmplutil.Execute(tmplutil.Parse("sizeProtoI8", []byte(sizeProtoI8)), tf) case TypeFixed32, TypeSFixed32, TypeFloat: - return template.Execute(template.Parse("sizeProtoI4", []byte(sizeProtoI4)), tf) + return tmplutil.Execute(tmplutil.Parse("sizeProtoI4", []byte(sizeProtoI4)), tf) case TypeInt32, TypeInt64, TypeUint32, TypeUint64, TypeEnum: - return template.Execute(template.Parse("sizeProtoVarint", []byte(sizeProtoVarint)), tf) + return tmplutil.Execute(tmplutil.Parse("sizeProtoVarint", []byte(sizeProtoVarint)), tf) case TypeBool: - return template.Execute(template.Parse("sizeProtoBool", []byte(sizeProtoBool)), tf) + return tmplutil.Execute(tmplutil.Parse("sizeProtoBool", []byte(sizeProtoBool)), tf) case TypeBytes, TypeString: - return template.Execute(template.Parse("sizeProtoBytesString", []byte(sizeProtoBytesString)), tf) + return tmplutil.Execute(tmplutil.Parse("sizeProtoBytesString", []byte(sizeProtoBytesString)), tf) case TypeMessage: - return template.Execute(template.Parse("sizeProtoMessage", []byte(sizeProtoMessage)), tf) + return tmplutil.Execute(tmplutil.Parse("sizeProtoMessage", []byte(sizeProtoMessage)), tf) case TypeSInt32, TypeSInt64: - return template.Execute(template.Parse("sizeProtoSignedVarint", []byte(sizeProtoSignedVarint)), tf) + return tmplutil.Execute(tmplutil.Parse("sizeProtoSignedVarint", []byte(sizeProtoSignedVarint)), tf) } panic(fmt.Sprintf("unhandled case %T", pf.Type)) } diff --git a/internal/cmd/pdatagen/internal/proto/proto_unmarshal.go b/internal/cmd/pdatagen/internal/proto/proto_unmarshal.go index 9d9f68ed421c..40203cb69b8d 100644 --- a/internal/cmd/pdatagen/internal/proto/proto_unmarshal.go +++ b/internal/cmd/pdatagen/internal/proto/proto_unmarshal.go @@ -6,7 +6,7 @@ package proto // import "go.opentelemetry.io/collector/internal/cmd/pdatagen/int import ( "fmt" - "go.opentelemetry.io/collector/internal/cmd/pdatagen/internal/template" + "go.opentelemetry.io/collector/internal/cmd/pdatagen/internal/tmplutil" ) const unmarshalProtoFloat = `{{ if .repeated -}} @@ -54,14 +54,16 @@ const unmarshalProtoFloat = `{{ if .repeated -}} } {{ if ne .oneOfGroup "" -}} var ov *{{ .oneOfMessageName }} - if !UseProtoPooling.IsEnabled() { + if !metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() { ov = &{{ .oneOfMessageName }}{} } else { ov = ProtoPool{{ .oneOfMessageName }}.Get().(*{{ .oneOfMessageName }}) } ov.{{ .fieldName }} = math.Float{{ .bitSize }}frombits(num) orig.{{ .oneOfGroup }} = ov -{{- else }} +{{- else if .nullable -}} + orig.Set{{ .fieldName }}(math.Float{{ .bitSize }}frombits(num)) +{{- else -}} orig.{{ .fieldName }} = math.Float{{ .bitSize }}frombits(num) {{- end }}{{- end }}` @@ -110,7 +112,7 @@ const unmarshalProtoFixed = `{{ if .repeated -}} } {{ if ne .oneOfGroup "" -}} var ov *{{ .oneOfMessageName }} - if !UseProtoPooling.IsEnabled() { + if !metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() { ov = &{{ .oneOfMessageName }}{} } else { ov = ProtoPool{{ .oneOfMessageName }}.Get().(*{{ .oneOfMessageName }}) @@ -166,14 +168,16 @@ const unmarshalProtoBool = `{{ if .repeated -}} } {{ if ne .oneOfGroup "" -}} var ov *{{ .oneOfMessageName }} - if !UseProtoPooling.IsEnabled() { + if !metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() { ov = &{{ .oneOfMessageName }}{} } else { ov = ProtoPool{{ .oneOfMessageName }}.Get().(*{{ .oneOfMessageName }}) } ov.{{ .fieldName }} = num != 0 orig.{{ .oneOfGroup }} = ov -{{- else }} +{{- else if .nullable -}} + orig.Set{{ .fieldName }}(num != 0) +{{- else -}} orig.{{ .fieldName }} = num != 0 {{- end }}{{- end }}` @@ -220,14 +224,16 @@ const unmarshalProtoVarint = `{{ if .repeated -}} } {{ if ne .oneOfGroup "" -}} var ov *{{ .oneOfMessageName }} - if !UseProtoPooling.IsEnabled() { + if !metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() { ov = &{{ .oneOfMessageName }}{} } else { ov = ProtoPool{{ .oneOfMessageName }}.Get().(*{{ .oneOfMessageName }}) } ov.{{ .fieldName }} = {{ .goType }}(num) orig.{{ .oneOfGroup }} = ov -{{- else }} +{{- else if .nullable -}} + orig.Set{{ .fieldName }}({{ .goType }}(num)) +{{- else -}} orig.{{ .fieldName }} = {{ .goType }}(num) {{- end }}{{- end }}` @@ -244,7 +250,7 @@ const unmarshalProtoString = ` startPos := pos - length {{ if ne .oneOfGroup "" -}} var ov *{{ .oneOfMessageName }} - if !UseProtoPooling.IsEnabled() { + if !metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() { ov = &{{ .oneOfMessageName }}{} } else { ov = ProtoPool{{ .oneOfMessageName }}.Get().(*{{ .oneOfMessageName }}) @@ -270,7 +276,7 @@ const unmarshalProtoBytes = ` startPos := pos - length {{ if ne .oneOfGroup "" -}} var ov *{{ .oneOfMessageName }} - if !UseProtoPooling.IsEnabled() { + if !metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() { ov = &{{ .oneOfMessageName }}{} } else { ov = ProtoPool{{ .oneOfMessageName }}.Get().(*{{ .oneOfMessageName }}) @@ -307,7 +313,7 @@ const unmarshalProtoMessage = ` startPos := pos - length {{ if ne .oneOfGroup "" -}} var ov *{{ .oneOfMessageName }} - if !UseProtoPooling.IsEnabled() { + if !metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() { ov = &{{ .oneOfMessageName }}{} } else { ov = ProtoPool{{ .oneOfMessageName }}.Get().(*{{ .oneOfMessageName }}) @@ -378,14 +384,16 @@ const unmarshalProtoSignedVarint = `{{ if .repeated -}} } {{ if ne .oneOfGroup "" -}} var ov *{{ .oneOfMessageName }} - if !UseProtoPooling.IsEnabled() { + if !metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() { ov = &{{ .oneOfMessageName }}{} } else { ov = ProtoPool{{ .oneOfMessageName }}.Get().(*{{ .oneOfMessageName }}) } ov.{{ .fieldName }} = int{{ .bitSize }}(uint{{ .bitSize }}(num >> 1) ^ uint{{ .bitSize }}(int{{ .bitSize }}((num&1)<<{{ sub .bitSize 1 }})>>{{ sub .bitSize 1 }})) orig.{{ .oneOfGroup }} = ov -{{- else }} +{{- else if .nullable -}} + orig.Set{{ .fieldName }}(int{{ .bitSize }}(uint{{ .bitSize }}(num >> 1) ^ uint{{ .bitSize }}(int{{ .bitSize }}((num&1)<<{{ sub .bitSize 1 }})>>{{ sub .bitSize 1 }}))) +{{- else -}} orig.{{ .fieldName }} = int{{ .bitSize }}(uint{{ .bitSize }}(num >> 1) ^ uint{{ .bitSize }}(int{{ .bitSize }}((num&1)<<{{ sub .bitSize 1 }})>>{{ sub .bitSize 1 }})) {{- end }}{{- end }}` @@ -393,21 +401,21 @@ func (pf *Field) GenUnmarshalProto() string { tf := pf.getTemplateFields() switch pf.Type { case TypeDouble, TypeFloat: - return template.Execute(template.Parse("unmarshalProtoFloat", []byte(unmarshalProtoFloat)), tf) + return tmplutil.Execute(tmplutil.Parse("unmarshalProtoFloat", []byte(unmarshalProtoFloat)), tf) case TypeFixed64, TypeSFixed64, TypeFixed32, TypeSFixed32: - return template.Execute(template.Parse("unmarshalProtoFixed", []byte(unmarshalProtoFixed)), tf) + return tmplutil.Execute(tmplutil.Parse("unmarshalProtoFixed", []byte(unmarshalProtoFixed)), tf) case TypeInt32, TypeInt64, TypeUint32, TypeUint64, TypeEnum: - return template.Execute(template.Parse("unmarshalProtoVarint", []byte(unmarshalProtoVarint)), tf) + return tmplutil.Execute(tmplutil.Parse("unmarshalProtoVarint", []byte(unmarshalProtoVarint)), tf) case TypeBool: - return template.Execute(template.Parse("unmarshalProtoBool", []byte(unmarshalProtoBool)), tf) + return tmplutil.Execute(tmplutil.Parse("unmarshalProtoBool", []byte(unmarshalProtoBool)), tf) case TypeString: - return template.Execute(template.Parse("unmarshalProtoString", []byte(unmarshalProtoString)), tf) + return tmplutil.Execute(tmplutil.Parse("unmarshalProtoString", []byte(unmarshalProtoString)), tf) case TypeBytes: - return template.Execute(template.Parse("unmarshalProtoBytes", []byte(unmarshalProtoBytes)), tf) + return tmplutil.Execute(tmplutil.Parse("unmarshalProtoBytes", []byte(unmarshalProtoBytes)), tf) case TypeMessage: - return template.Execute(template.Parse("unmarshalProtoMessage", []byte(unmarshalProtoMessage)), tf) + return tmplutil.Execute(tmplutil.Parse("unmarshalProtoMessage", []byte(unmarshalProtoMessage)), tf) case TypeSInt32, TypeSInt64: - return template.Execute(template.Parse("unmarshalProtoSignedVarint", []byte(unmarshalProtoSignedVarint)), tf) + return tmplutil.Execute(tmplutil.Parse("unmarshalProtoSignedVarint", []byte(unmarshalProtoSignedVarint)), tf) } panic(fmt.Sprintf("unhandled case %T", pf.Type)) } diff --git a/internal/cmd/pdatagen/internal/proto/templates/message.go.tmpl b/internal/cmd/pdatagen/internal/proto/templates/message.go.tmpl index d6aefa3106b1..3e7ae87f547d 100644 --- a/internal/cmd/pdatagen/internal/proto/templates/message.go.tmpl +++ b/internal/cmd/pdatagen/internal/proto/templates/message.go.tmpl @@ -20,7 +20,11 @@ import ( type {{ .messageName }} struct { {{- range .fields }} {{ .GenMessageField }} -{{- end }}} +{{- end }} +{{ if gt .metadataSize 0 -}} + metadata [{{ .metadataSize }}]uint64 +{{ end -}} +} var ( protoPool{{ .messageName }} = sync.Pool{ @@ -33,7 +37,7 @@ var ( func New{{ .messageName }}() *{{ .messageName }} { - if !UseProtoPooling.IsEnabled() { + if !metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() { return &{{ .messageName }}{} } return protoPool{{ .messageName }}.Get().(*{{ .messageName }}) @@ -44,12 +48,14 @@ func Delete{{ .messageName }}(orig *{{ .messageName }}, nullable bool) { return } - if !UseProtoPooling.IsEnabled() { + if !metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() { orig.Reset() return } - {{ range .fields }}{{ .GenDelete }}{{ end }} + {{- range .fields }} + {{ .GenDelete }} + {{- end }} orig.Reset() if nullable { protoPool{{ .messageName }}.Put(orig) @@ -199,10 +205,14 @@ func (orig *{{ .messageName }}) UnmarshalProto(buf []byte) error { return nil } +{{ if gt .metadataSize 0 -}} +{{ call .GenerateMetadata }} +{{ end -}} + func GenTest{{ .messageName }}() *{{ .messageName }} { orig := New{{ .messageName }}() {{- range .fields }} - orig.{{ .GetName }} = {{ .TestValue }} + {{ .GenTest }} {{- end }} return orig } diff --git a/internal/cmd/pdatagen/internal/proto/templates/message_test.go.tmpl b/internal/cmd/pdatagen/internal/proto/templates/message_test.go.tmpl index 36ae9ae3a375..c408852979aa 100644 --- a/internal/cmd/pdatagen/internal/proto/templates/message_test.go.tmpl +++ b/internal/cmd/pdatagen/internal/proto/templates/message_test.go.tmpl @@ -16,10 +16,10 @@ func TestCopy{{ .messageName }}(t *testing.T) { for name, src := range genTestEncodingValues{{ .messageName }}() { for _, pooling := range []bool{true, false} { t.Run(name+"/Pooling="+strconv.FormatBool(pooling), func(t *testing.T) { - prevPooling := UseProtoPooling.IsEnabled() - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), pooling)) + prevPooling := metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), pooling)) defer func() { - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), prevPooling)) + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), prevPooling)) }() dest := New{{ .messageName }}() @@ -95,10 +95,10 @@ func TestMarshalAndUnmarshalJSON{{ .messageName }}(t *testing.T) { for name, src := range genTestEncodingValues{{ .messageName }}() { for _, pooling := range []bool{true, false} { t.Run(name+"/Pooling="+strconv.FormatBool(pooling), func(t *testing.T) { - prevPooling := UseProtoPooling.IsEnabled() - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), pooling)) + prevPooling := metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), pooling)) defer func() { - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), prevPooling)) + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), prevPooling)) }() stream := json.BorrowStream(nil) @@ -139,10 +139,10 @@ func TestMarshalAndUnmarshalProto{{ .messageName }}(t *testing.T) { for name, src := range genTestEncodingValues{{ .messageName }}(){ for _, pooling := range []bool{true, false} { t.Run(name+"/Pooling="+strconv.FormatBool(pooling), func(t *testing.T) { - prevPooling := UseProtoPooling.IsEnabled() - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), pooling)) + prevPooling := metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), pooling)) defer func() { - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), prevPooling)) + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), prevPooling)) }() buf := make([]byte, src.SizeProto()) diff --git a/internal/cmd/pdatagen/internal/proto/test_encoding_values.go b/internal/cmd/pdatagen/internal/proto/test_encoding_values.go index 40071693160b..9b47bc6a5962 100644 --- a/internal/cmd/pdatagen/internal/proto/test_encoding_values.go +++ b/internal/cmd/pdatagen/internal/proto/test_encoding_values.go @@ -7,12 +7,18 @@ import ( "slices" "strings" - "go.opentelemetry.io/collector/internal/cmd/pdatagen/internal/template" + "go.opentelemetry.io/collector/internal/cmd/pdatagen/internal/tmplutil" ) const encodingTestValuesScalar = `{{ if ne .oneOfGroup "" -}} "{{ .fieldName }}/default": { {{ .oneOfGroup }}: &{{ .oneOfMessageName }}{{ "{" }}{{ .fieldName }}: {{ .defaultValue }}} }, "{{ .fieldName }}/test": { {{ .oneOfGroup }}: &{{ .oneOfMessageName }}{{ "{" }}{{ .fieldName }}: {{ .testValue }}} }, +{{- else if .nullable }} +"{{ .fieldName }}/test": func () *{{ .parentMessageName }} { + ms := New{{ .parentMessageName }}() + ms.Set{{ .fieldName }}({{ .testValue }}) + return ms +}(), {{- else }} "{{ .fieldName }}/test": { {{ .fieldName }}: {{ .testValue }} }, {{- end }}` @@ -28,14 +34,14 @@ func (pf *Field) GenTestEncodingValues() string { tf := pf.getTemplateFields() switch pf.Type { case TypeMessage: - return template.Execute(template.Parse("encodingTestValuesMessage", []byte(encodingTestValuesMessage)), tf) + return tmplutil.Execute(tmplutil.Parse("encodingTestValuesMessage", []byte(encodingTestValuesMessage)), tf) case TypeDouble, TypeFloat, TypeFixed64, TypeSFixed64, TypeFixed32, TypeSFixed32, TypeInt32, TypeInt64, TypeUint32, TypeUint64, TypeSInt32, TypeSInt64, TypeBool, TypeString, TypeBytes, TypeEnum: - return template.Execute(template.Parse("encodingTestValuesScalar", []byte(encodingTestValuesScalar)), tf) + return tmplutil.Execute(tmplutil.Parse("encodingTestValuesScalar", []byte(encodingTestValuesScalar)), tf) } return "" } @@ -55,7 +61,7 @@ func (pf *Field) GenTestFailingUnmarshalProtoValues() string { TypeInt32, TypeInt64, TypeUint32, TypeUint64, TypeSInt32, TypeSInt64, TypeBool, TypeString, TypeBytes, TypeEnum: - return template.Execute(template.Parse("failingUnmarshalProtoValuesScalar", []byte(failingUnmarshalProtoValuesScalar)), tf) + return tmplutil.Execute(tmplutil.Parse("failingUnmarshalProtoValuesScalar", []byte(failingUnmarshalProtoValuesScalar)), tf) } return "" } diff --git a/internal/cmd/pdatagen/internal/template/template.go b/internal/cmd/pdatagen/internal/tmplutil/template.go similarity index 91% rename from internal/cmd/pdatagen/internal/template/template.go rename to internal/cmd/pdatagen/internal/tmplutil/template.go index 38967d7af997..fe2f813bbd2f 100644 --- a/internal/cmd/pdatagen/internal/template/template.go +++ b/internal/cmd/pdatagen/internal/tmplutil/template.go @@ -1,7 +1,7 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -package template // import "go.opentelemetry.io/collector/internal/cmd/pdatagen/internal/template" +package tmplutil // import "go.opentelemetry.io/collector/internal/cmd/pdatagen/internal/tmplutil" import ( "strings" diff --git a/internal/componentalias/Makefile b/internal/componentalias/Makefile new file mode 100644 index 000000000000..ded7a36092dc --- /dev/null +++ b/internal/componentalias/Makefile @@ -0,0 +1 @@ +include ../../Makefile.Common diff --git a/internal/componentalias/alias.go b/internal/componentalias/alias.go new file mode 100644 index 000000000000..7008a269cb64 --- /dev/null +++ b/internal/componentalias/alias.go @@ -0,0 +1,50 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +package componentalias // import "go.opentelemetry.io/collector/internal/componentalias" + +import ( + "errors" + "fmt" + + "go.opentelemetry.io/collector/component" +) + +type TypeAliasHolder interface { + DeprecatedAlias() component.Type + SetDeprecatedAlias(component.Type) +} + +func NewTypeAliasHolder() TypeAliasHolder { + ta := typeAlias(component.Type{}) + return &ta +} + +type typeAlias component.Type + +// DeprecatedAlias returns the deprecated type typeAlias for this component, if any. +// Returns an empty component.Type if no typeAlias is configured. +func (ta *typeAlias) DeprecatedAlias() component.Type { + return component.Type(*ta) +} + +// SetDeprecatedAlias sets the deprecated type typeAlias. +func (ta *typeAlias) SetDeprecatedAlias(newAlias component.Type) { + *ta = typeAlias(newAlias) +} + +// ValidateComponentType returns an error if the provided factory does not match the provided component ID. +// It checks both the current type and any deprecated alias type. +func ValidateComponentType(f component.Factory, id component.ID) error { + if id.Type() == f.Type() { + return nil + } + errMsg := fmt.Sprintf("component type mismatch: component ID %q does not have type %q", id, f.Type()) + if aliasHolder, ok := f.(TypeAliasHolder); ok && aliasHolder.DeprecatedAlias().String() != "" { + if id.Type() == aliasHolder.DeprecatedAlias() { + return nil + } + errMsg += fmt.Sprintf(" or deprecated alias type %q", aliasHolder.DeprecatedAlias()) + } + return errors.New(errMsg) +} diff --git a/internal/componentalias/alias_test.go b/internal/componentalias/alias_test.go new file mode 100644 index 000000000000..c8ea7e8bd333 --- /dev/null +++ b/internal/componentalias/alias_test.go @@ -0,0 +1,157 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +package componentalias + +import ( + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + + "go.opentelemetry.io/collector/component" +) + +func TestNewTypeAliasHolder(t *testing.T) { + holder := NewTypeAliasHolder() + require.NotNil(t, holder) + + alias := holder.DeprecatedAlias() + assert.Equal(t, component.Type{}, alias) + assert.Empty(t, alias.String()) + + testType := component.MustNewType("test_alias") + holder.SetDeprecatedAlias(testType) + retrievedAlias := holder.DeprecatedAlias() + assert.Equal(t, testType, retrievedAlias) + assert.Equal(t, "test_alias", retrievedAlias.String()) +} + +type mockFactory struct { + factoryType component.Type + TypeAliasHolder +} + +func (f *mockFactory) Type() component.Type { + return f.factoryType +} + +func (f *mockFactory) CreateDefaultConfig() component.Config { + return nil +} + +func TestValidateComponentType_ExactMatch(t *testing.T) { + testType := component.MustNewType("test") + factory := &mockFactory{ + factoryType: testType, + TypeAliasHolder: NewTypeAliasHolder(), + } + + testID := component.MustNewID(testType.String()) + err := ValidateComponentType(factory, testID) + require.NoError(t, err) +} + +func TestValidateComponentType_AliasMatch(t *testing.T) { + factoryType := component.MustNewType("new_name") + aliasType := component.MustNewType("old_name") + + factory := &mockFactory{ + factoryType: factoryType, + TypeAliasHolder: NewTypeAliasHolder(), + } + factory.SetDeprecatedAlias(aliasType) + + // Test with alias type + aliasID := component.MustNewID(aliasType.String()) + err := ValidateComponentType(factory, aliasID) + require.NoError(t, err) + + // Test with factory type still works + factoryID := component.MustNewID(factoryType.String()) + err = ValidateComponentType(factory, factoryID) + require.NoError(t, err) +} + +func TestValidateComponentType_NoMatch(t *testing.T) { + factoryType := component.MustNewType("factory_type") + wrongType := component.MustNewType("wrong_type") + + factory := &mockFactory{ + factoryType: factoryType, + TypeAliasHolder: NewTypeAliasHolder(), + } + + wrongID := component.MustNewID(wrongType.String()) + err := ValidateComponentType(factory, wrongID) + require.Error(t, err) + assert.Contains(t, err.Error(), "component type mismatch") + assert.Contains(t, err.Error(), wrongType.String()) + assert.Contains(t, err.Error(), factoryType.String()) +} + +func TestValidateComponentType_NoMatchWithAlias(t *testing.T) { + factoryType := component.MustNewType("factory_type") + aliasType := component.MustNewType("alias_type") + wrongType := component.MustNewType("wrong_type") + + factory := &mockFactory{ + factoryType: factoryType, + TypeAliasHolder: NewTypeAliasHolder(), + } + factory.SetDeprecatedAlias(aliasType) + + wrongID := component.MustNewID(wrongType.String()) + err := ValidateComponentType(factory, wrongID) + require.Error(t, err) + assert.Contains(t, err.Error(), "component type mismatch") + assert.Contains(t, err.Error(), wrongType.String()) + assert.Contains(t, err.Error(), factoryType.String()) + assert.Contains(t, err.Error(), "deprecated alias type") + assert.Contains(t, err.Error(), aliasType.String()) +} + +func TestValidateComponentType_EmptyAlias(t *testing.T) { + factoryType := component.MustNewType("factory_type") + wrongType := component.MustNewType("wrong_type") + + factory := &mockFactory{ + factoryType: factoryType, + TypeAliasHolder: NewTypeAliasHolder(), + } + // Don't set any alias (empty by default) + + wrongID := component.MustNewID(wrongType.String()) + err := ValidateComponentType(factory, wrongID) + require.Error(t, err) + assert.Contains(t, err.Error(), "component type mismatch") + assert.NotContains(t, err.Error(), "deprecated alias type") +} + +type mockFactoryWithoutAlias struct { + factoryType component.Type +} + +func (f *mockFactoryWithoutAlias) Type() component.Type { + return f.factoryType +} + +func (f *mockFactoryWithoutAlias) CreateDefaultConfig() component.Config { + return nil +} + +func TestValidateComponentType_FactoryWithoutAliasSupport(t *testing.T) { + factoryType := component.MustNewType("factory_type") + factory := &mockFactoryWithoutAlias{factoryType: factoryType} + + factoryID := component.MustNewID(factoryType.String()) + err := ValidateComponentType(factory, factoryID) + require.NoError(t, err) + + wrongType := component.MustNewType("wrong_type") + wrongID := component.MustNewID(wrongType.String()) + err = ValidateComponentType(factory, wrongID) + require.Error(t, err) + assert.Contains(t, err.Error(), "component type mismatch") + assert.NotContains(t, err.Error(), "deprecated alias type") +} diff --git a/internal/componentalias/go.mod b/internal/componentalias/go.mod new file mode 100644 index 000000000000..4c31826b2036 --- /dev/null +++ b/internal/componentalias/go.mod @@ -0,0 +1,34 @@ +module go.opentelemetry.io/collector/internal/componentalias + +go 1.25.0 + +require ( + github.com/stretchr/testify v1.11.1 + go.opentelemetry.io/collector/component v1.54.0 +) + +require ( + github.com/cespare/xxhash/v2 v2.3.0 // indirect + github.com/davecgh/go-spew v1.1.1 // indirect + github.com/hashicorp/go-version v1.8.0 // indirect + github.com/json-iterator/go v1.1.12 // indirect + github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect + github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee // indirect + github.com/pmezard/go-difflib v1.0.0 // indirect + go.opentelemetry.io/collector/featuregate v1.54.0 // indirect + go.opentelemetry.io/collector/pdata v1.54.0 // indirect + go.opentelemetry.io/otel v1.42.0 // indirect + go.opentelemetry.io/otel/metric v1.42.0 // indirect + go.opentelemetry.io/otel/trace v1.42.0 // indirect + go.uber.org/multierr v1.11.0 // indirect + go.uber.org/zap v1.27.1 // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect +) + +replace go.opentelemetry.io/collector/component => ../../component + +replace go.opentelemetry.io/collector/pdata => ../../pdata + +replace go.opentelemetry.io/collector/featuregate => ../../featuregate + +replace go.opentelemetry.io/collector/internal/testutil => ../testutil diff --git a/internal/componentalias/go.sum b/internal/componentalias/go.sum new file mode 100644 index 000000000000..1abfd0c69894 --- /dev/null +++ b/internal/componentalias/go.sum @@ -0,0 +1,61 @@ +github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= +github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI= +github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= +github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= +github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= +github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= +github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= +github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/hashicorp/go-version v1.8.0 h1:KAkNb1HAiZd1ukkxDFGmokVZe1Xy9HG6NUp+bPle2i4= +github.com/hashicorp/go-version v1.8.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= +github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= +github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= +github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= +github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= +github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= +github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= +github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee h1:W5t00kpgFdJifH4BDsTlE89Zl93FEloxaWZfGcifgq8= +github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ= +github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U= +github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= +go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64= +go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y= +go.opentelemetry.io/otel v1.42.0 h1:lSQGzTgVR3+sgJDAU/7/ZMjN9Z+vUip7leaqBKy4sho= +go.opentelemetry.io/otel v1.42.0/go.mod h1:lJNsdRMxCUIWuMlVJWzecSMuNjE7dOYyWlqOXWkdqCc= +go.opentelemetry.io/otel/metric v1.42.0 h1:2jXG+3oZLNXEPfNmnpxKDeZsFI5o4J+nz6xUlaFdF/4= +go.opentelemetry.io/otel/metric v1.42.0/go.mod h1:RlUN/7vTU7Ao/diDkEpQpnz3/92J9ko05BIwxYa2SSI= +go.opentelemetry.io/otel/trace v1.42.0 h1:OUCgIPt+mzOnaUTpOQcBiM/PLQ/Op7oq6g4LenLmOYY= +go.opentelemetry.io/otel/trace v1.42.0/go.mod h1:f3K9S+IFqnumBkKhRJMeaZeNk9epyhnCmQh/EysQCdc= +go.opentelemetry.io/proto/slim/otlp v1.10.0 h1:iR97Vs/ZDR+y9TfuP9b1XBtdPWeC+OMslIBmhcLU7jM= +go.opentelemetry.io/proto/slim/otlp v1.10.0/go.mod h1:lV9250stpjYLPNA5viFabIgP2QlUGRT1GdTgAf8SIUk= +go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.3.0 h1:RUF5rO0hAlgiJt1fzQVzcVs3vZVNHIcMLgOgG4rWNcQ= +go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.3.0/go.mod h1:I89cynRj8y+383o7tEQVg2SVA6SRgDVIouWPUVXjx0U= +go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.3.0 h1:CQvJSldHRUN6Z8jsUeYv8J0lXRvygALXIzsmAeCcZE0= +go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.3.0/go.mod h1:xSQ+mEfJe/GjK1LXEyVOoSI1N9JV9ZI923X5kup43W4= +go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= +go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= +go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= +go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= +go.uber.org/zap v1.27.1 h1:08RqriUEv8+ArZRYSTXy1LeBScaMpVSTBhCeaZYfMYc= +go.uber.org/zap v1.27.1/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= +google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE= +google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/internal/e2e/confighttp_test.go b/internal/e2e/confighttp_test.go index b59ea6f326b0..e745f7280d1f 100644 --- a/internal/e2e/confighttp_test.go +++ b/internal/e2e/confighttp_test.go @@ -11,6 +11,7 @@ import ( "github.com/stretchr/testify/require" "go.opentelemetry.io/collector/config/confighttp" + "go.opentelemetry.io/collector/config/confignet" "go.opentelemetry.io/collector/confmap" ) @@ -35,6 +36,7 @@ func TestConfmapMarshalConfigHTTP(t *testing.T) { "keep_alives_enabled": true, "read_header_timeout": 60 * time.Second, "tls": nil, + "transport": confignet.TransportTypeTCP, "write_timeout": 30 * time.Second, }, conf.ToStringMap()) diff --git a/internal/e2e/consume_contract_test.go b/internal/e2e/consume_contract_test.go index 5194b9e772bd..c02ea5b5f69a 100644 --- a/internal/e2e/consume_contract_test.go +++ b/internal/e2e/consume_contract_test.go @@ -9,6 +9,7 @@ import ( "go.opentelemetry.io/collector/component" "go.opentelemetry.io/collector/config/configgrpc" + "go.opentelemetry.io/collector/config/configoptional" "go.opentelemetry.io/collector/config/configretry" "go.opentelemetry.io/collector/config/configtls" "go.opentelemetry.io/collector/exporter/exporterhelper" @@ -23,7 +24,7 @@ func testExporterConfig(endpoint string) component.Config { retryConfig := configretry.NewDefaultBackOffConfig() retryConfig.InitialInterval = time.Millisecond // interval is short for the test purposes return &otlpexporter.Config{ - QueueConfig: exporterhelper.QueueBatchConfig{Enabled: false}, + QueueConfig: configoptional.None[exporterhelper.QueueBatchConfig](), RetryConfig: retryConfig, ClientConfig: configgrpc.ClientConfig{ Endpoint: endpoint, diff --git a/internal/e2e/error_propagation_test.go b/internal/e2e/error_propagation_test.go index bb2180416d26..06ac87a86980 100644 --- a/internal/e2e/error_propagation_test.go +++ b/internal/e2e/error_propagation_test.go @@ -28,6 +28,7 @@ import ( "go.opentelemetry.io/collector/config/configoptional" "go.opentelemetry.io/collector/config/configtls" "go.opentelemetry.io/collector/consumer" + "go.opentelemetry.io/collector/exporter/exporterhelper" "go.opentelemetry.io/collector/exporter/exportertest" "go.opentelemetry.io/collector/exporter/otlpexporter" "go.opentelemetry.io/collector/exporter/otlphttpexporter" @@ -169,7 +170,7 @@ func createGRPCExporter(t *testing.T, s *status.Status) consumer.Logs { f := otlpexporter.NewFactory() cfg := f.CreateDefaultConfig().(*otlpexporter.Config) - cfg.QueueConfig.Enabled = false + cfg.QueueConfig = configoptional.None[exporterhelper.QueueBatchConfig]() cfg.RetryConfig.Enabled = false cfg.ClientConfig = configgrpc.ClientConfig{ Endpoint: ln.Addr().String(), @@ -203,11 +204,11 @@ func createHTTPExporter(t *testing.T, code int) consumer.Logs { f := otlphttpexporter.NewFactory() cfg := f.CreateDefaultConfig().(*otlphttpexporter.Config) - cfg.QueueConfig.Enabled = false + cfg.QueueConfig = configoptional.None[exporterhelper.QueueBatchConfig]() cfg.RetryConfig.Enabled = false cfg.Encoding = otlphttpexporter.EncodingProto cfg.LogsEndpoint = srv.URL + "/v1/logs" - e, err := f.CreateLogs(context.Background(), exportertest.NewNopSettings(component.MustNewType("otlphttp")), cfg) + e, err := f.CreateLogs(context.Background(), exportertest.NewNopSettings(component.MustNewType("otlp_http")), cfg) require.NoError(t, err) err = e.Start(context.Background(), componenttest.NewNopHost()) require.NoError(t, err) @@ -271,12 +272,16 @@ func assertOnHTTPCode(t *testing.T, l consumer.Logs, code int) { logProto, err := protoMarshaler.MarshalLogs(ld) require.NoError(t, err) + addr := testutil.GetAvailableLocalAddress(t) rf := otlpreceiver.NewFactory() rcfg := rf.CreateDefaultConfig().(*otlpreceiver.Config) rcfg.HTTP = configoptional.Some( otlpreceiver.HTTPConfig{ ServerConfig: confighttp.ServerConfig{ - Endpoint: testutil.GetAvailableLocalAddress(t), + NetAddr: confignet.AddrConfig{ + Endpoint: addr, + Transport: confignet.TransportTypeTCP, + }, }, LogsURLPath: "/v1/logs", }, @@ -292,7 +297,7 @@ func assertOnHTTPCode(t *testing.T, l consumer.Logs, code int) { require.NoError(t, r.Shutdown(context.Background())) }) - doHTTPRequest(t, rcfg.HTTP.Get().ServerConfig.Endpoint+"/v1/logs", logProto, code) + doHTTPRequest(t, addr+"/v1/logs", logProto, code) } func doHTTPRequest( diff --git a/internal/e2e/exporter_failure_attributes_test.go b/internal/e2e/exporter_failure_attributes_test.go new file mode 100644 index 000000000000..1bbdbeaff9b4 --- /dev/null +++ b/internal/e2e/exporter_failure_attributes_test.go @@ -0,0 +1,221 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +package e2e + +import ( + "context" + "fmt" + "net/http" + "net/http/httptest" + "path/filepath" + "sync/atomic" + "testing" + "time" + + dto "github.com/prometheus/client_model/go" + "github.com/prometheus/common/expfmt" + "github.com/prometheus/common/model" + "github.com/stretchr/testify/require" + + "go.opentelemetry.io/collector/component" + "go.opentelemetry.io/collector/confmap" + "go.opentelemetry.io/collector/confmap/provider/envprovider" + "go.opentelemetry.io/collector/confmap/provider/fileprovider" + "go.opentelemetry.io/collector/confmap/provider/yamlprovider" + "go.opentelemetry.io/collector/exporter" + "go.opentelemetry.io/collector/exporter/otlphttpexporter" + "go.opentelemetry.io/collector/otelcol" + "go.opentelemetry.io/collector/receiver" + "go.opentelemetry.io/collector/receiver/otlpreceiver" + "go.opentelemetry.io/collector/service/telemetry/otelconftelemetry" +) + +func TestExporterFailureAttributesDetailed(t *testing.T) { + t.Run("permanent error sets error.permanent", func(t *testing.T) { + server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + if r.URL.Path != "/v1/metrics" { + w.WriteHeader(http.StatusNotFound) + return + } + http.Error(w, "bad request", http.StatusBadRequest) + })) + defer server.Close() + + otelPort, metricsPort := startFailureAttributeCollector(t, server.URL) + + require.NoError(t, sendTestMetrics(otelPort)) + + require.Eventually(t, func() bool { + metric := scrapeFailureMetric(t, metricsPort, "otlp_http/test") + if metric == nil { + return false + } + failurePermanent, ok := labelValue(metric, "error_permanent") + return ok && failurePermanent == "true" + }, 5*time.Second, 200*time.Millisecond, "expected permanent failure metric") + }) + + t.Run("transient error that recovers has no failure metric", func(t *testing.T) { + var attempts atomic.Int32 + server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + if r.URL.Path != "/v1/metrics" { + w.WriteHeader(http.StatusNotFound) + return + } + if attempts.Add(1) == 1 { + http.Error(w, "try again", http.StatusServiceUnavailable) + return + } + w.WriteHeader(http.StatusOK) + })) + defer server.Close() + + otelPort, metricsPort := startFailureAttributeCollector(t, server.URL) + + require.NoError(t, sendTestMetrics(otelPort)) + assertNoFailureMetric(t, metricsPort, "otlp_http/test") + }) + + t.Run("retryable error exhausts retries", func(t *testing.T) { + server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + if r.URL.Path != "/v1/metrics" { + w.WriteHeader(http.StatusNotFound) + return + } + http.Error(w, "temporarily unavailable", http.StatusServiceUnavailable) + })) + defer server.Close() + + otelPort, metricsPort := startFailureAttributeCollector(t, server.URL) + + require.NoError(t, sendTestMetrics(otelPort)) + + require.Eventually(t, func() bool { + metric := scrapeFailureMetric(t, metricsPort, "otlp_http/test") + if metric == nil { + return false + } + failurePermanent, ok := labelValue(metric, "error_permanent") + return ok && failurePermanent == "false" + }, 5*time.Second, 200*time.Millisecond, "expected retry exhaustion metric") + }) +} + +func startFailureAttributeCollector(t *testing.T, exporterEndpoint string) (string, string) { + t.Helper() + otelPort := getFreePort(t) + metricsPort := getFreePort(t) + + t.Setenv("METRICS_PORT", metricsPort) + t.Setenv("OTEL_PORT", otelPort) + t.Setenv("EXPORTER_ENDPOINT", exporterEndpoint) + + collector, err := otelcol.NewCollector(otelcol.CollectorSettings{ + BuildInfo: component.NewDefaultBuildInfo(), + Factories: func() (otelcol.Factories, error) { + return otelcol.Factories{ + Receivers: map[component.Type]receiver.Factory{otlpreceiver.NewFactory().Type(): otlpreceiver.NewFactory()}, + Exporters: map[component.Type]exporter.Factory{ + otlphttpexporter.NewFactory().Type(): otlphttpexporter.NewFactory(), + }, + Telemetry: otelconftelemetry.NewFactory(), + }, nil + }, + ConfigProviderSettings: otelcol.ConfigProviderSettings{ + ResolverSettings: confmap.ResolverSettings{ + URIs: []string{filepath.Join("testdata", "exporter_failure_attributes_test.yaml")}, + ProviderFactories: []confmap.ProviderFactory{ + fileprovider.NewFactory(), + yamlprovider.NewFactory(), + envprovider.NewFactory(), + }, + }, + }, + }) + require.NoError(t, err) + + ctx, cancel := context.WithCancel(context.Background()) + t.Cleanup(cancel) + + go func() { + if err := collector.Run(ctx); err != nil { + t.Logf("Collector stopped with error: %v", err) + } + }() + + require.Eventually(t, func() bool { + resp, err := http.Get(fmt.Sprintf("http://localhost:%s/metrics", metricsPort)) + if err != nil { + return false + } + resp.Body.Close() + return resp.StatusCode == http.StatusOK + }, 5*time.Second, 100*time.Millisecond, "collector failed to start") + + return otelPort, metricsPort +} + +func scrapeFailureMetric(t *testing.T, metricsPort, exporterName string) *dto.Metric { + t.Helper() + resp, err := http.Get(fmt.Sprintf("http://localhost:%s/metrics", metricsPort)) + if err != nil { + return nil + } + defer resp.Body.Close() + if resp.StatusCode != http.StatusOK { + return nil + } + + parser := expfmt.NewTextParser(model.UTF8Validation) + parsed, err := parser.TextToMetricFamilies(resp.Body) + if err != nil { + return nil + } + + metricFamily, ok := parsed["otelcol_exporter_send_failed_metric_points"] + if !ok { + metricFamily, ok = parsed["otelcol_exporter_send_failed_metric_points_total"] + } + if !ok { + return nil + } + + for _, metric := range metricFamily.Metric { + if hasLabel(metric, "exporter", exporterName) { + return metric + } + } + + return nil +} + +func hasLabel(metric *dto.Metric, name, expected string) bool { + for _, label := range metric.Label { + if label.GetName() == name && label.GetValue() == expected { + return true + } + } + return false +} + +func labelValue(metric *dto.Metric, labelName string) (string, bool) { + for _, label := range metric.Label { + if label.GetName() == labelName { + return label.GetValue(), true + } + } + return "", false +} + +func assertNoFailureMetric(t *testing.T, metricsPort, exporterName string) { + t.Helper() + deadline := time.Now().Add(2 * time.Second) + for time.Now().Before(deadline) { + if metric := scrapeFailureMetric(t, metricsPort, exporterName); metric != nil { + failurePermanent, _ := labelValue(metric, "error_permanent") + t.Fatalf("unexpected failure metric recorded, error_permanent=%s", failurePermanent) + } + time.Sleep(100 * time.Millisecond) + } +} diff --git a/internal/e2e/go.mod b/internal/e2e/go.mod index c4bc2701e339..a50e8a05b599 100644 --- a/internal/e2e/go.mod +++ b/internal/e2e/go.mod @@ -1,166 +1,167 @@ module go.opentelemetry.io/collector/internal/e2e -go 1.24.0 +go 1.25.0 require ( github.com/google/go-cmp v0.7.0 - github.com/prometheus/common v0.67.1 + github.com/google/uuid v1.6.0 + github.com/prometheus/client_model v0.6.2 + github.com/prometheus/common v0.67.5 github.com/stretchr/testify v1.11.1 - go.opentelemetry.io/collector/component v1.46.0 - go.opentelemetry.io/collector/component/componentstatus v0.140.0 - go.opentelemetry.io/collector/component/componenttest v0.140.0 - go.opentelemetry.io/collector/config/configauth v1.46.0 - go.opentelemetry.io/collector/config/configgrpc v0.140.0 - go.opentelemetry.io/collector/config/confighttp v0.140.0 - go.opentelemetry.io/collector/config/confignet v1.46.0 - go.opentelemetry.io/collector/config/configopaque v1.46.0 - go.opentelemetry.io/collector/config/configoptional v1.46.0 - go.opentelemetry.io/collector/config/configretry v1.46.0 - go.opentelemetry.io/collector/config/configtelemetry v0.140.0 - go.opentelemetry.io/collector/config/configtls v1.46.0 - go.opentelemetry.io/collector/confmap v1.46.0 - go.opentelemetry.io/collector/confmap/provider/envprovider v1.46.0 - go.opentelemetry.io/collector/confmap/provider/fileprovider v1.46.0 - go.opentelemetry.io/collector/confmap/provider/yamlprovider v1.46.0 - go.opentelemetry.io/collector/connector v0.140.0 - go.opentelemetry.io/collector/connector/connectortest v0.140.0 - go.opentelemetry.io/collector/consumer v1.46.0 - go.opentelemetry.io/collector/consumer/consumertest v0.140.0 - go.opentelemetry.io/collector/exporter v1.46.0 - go.opentelemetry.io/collector/exporter/debugexporter v0.140.0 - go.opentelemetry.io/collector/exporter/exporterhelper v0.140.0 - go.opentelemetry.io/collector/exporter/exportertest v0.140.0 - go.opentelemetry.io/collector/exporter/otlpexporter v0.140.0 - go.opentelemetry.io/collector/exporter/otlphttpexporter v0.140.0 - go.opentelemetry.io/collector/extension v1.46.0 - go.opentelemetry.io/collector/internal/sharedcomponent v0.140.0 - go.opentelemetry.io/collector/internal/testutil v0.140.0 - go.opentelemetry.io/collector/otelcol v0.140.0 - go.opentelemetry.io/collector/pdata v1.46.0 - go.opentelemetry.io/collector/pdata/testdata v0.140.0 - go.opentelemetry.io/collector/pipeline v1.46.0 - go.opentelemetry.io/collector/processor v1.46.0 - go.opentelemetry.io/collector/processor/batchprocessor v0.140.0 - go.opentelemetry.io/collector/receiver v1.46.0 - go.opentelemetry.io/collector/receiver/otlpreceiver v0.140.0 - go.opentelemetry.io/collector/receiver/receivertest v0.140.0 - go.opentelemetry.io/collector/service v0.140.0 - go.opentelemetry.io/proto/otlp v1.9.0 + go.opentelemetry.io/collector/component v1.54.0 + go.opentelemetry.io/collector/component/componentstatus v0.148.0 + go.opentelemetry.io/collector/component/componenttest v0.148.0 + go.opentelemetry.io/collector/config/configauth v1.54.0 + go.opentelemetry.io/collector/config/configgrpc v0.148.0 + go.opentelemetry.io/collector/config/confighttp v0.148.0 + go.opentelemetry.io/collector/config/confignet v1.54.0 + go.opentelemetry.io/collector/config/configopaque v1.54.0 + go.opentelemetry.io/collector/config/configoptional v1.54.0 + go.opentelemetry.io/collector/config/configretry v1.54.0 + go.opentelemetry.io/collector/config/configtelemetry v0.148.0 + go.opentelemetry.io/collector/config/configtls v1.54.0 + go.opentelemetry.io/collector/confmap v1.54.0 + go.opentelemetry.io/collector/confmap/provider/envprovider v1.54.0 + go.opentelemetry.io/collector/confmap/provider/fileprovider v1.54.0 + go.opentelemetry.io/collector/confmap/provider/yamlprovider v1.54.0 + go.opentelemetry.io/collector/connector v0.148.0 + go.opentelemetry.io/collector/connector/connectortest v0.148.0 + go.opentelemetry.io/collector/consumer v1.54.0 + go.opentelemetry.io/collector/consumer/consumertest v0.148.0 + go.opentelemetry.io/collector/exporter v1.54.0 + go.opentelemetry.io/collector/exporter/debugexporter v0.148.0 + go.opentelemetry.io/collector/exporter/exporterhelper v0.148.0 + go.opentelemetry.io/collector/exporter/exportertest v0.148.0 + go.opentelemetry.io/collector/exporter/otlpexporter v0.148.0 + go.opentelemetry.io/collector/exporter/otlphttpexporter v0.148.0 + go.opentelemetry.io/collector/extension v1.54.0 + go.opentelemetry.io/collector/internal/sharedcomponent v0.148.0 + go.opentelemetry.io/collector/internal/testutil v0.148.0 + go.opentelemetry.io/collector/otelcol v0.148.0 + go.opentelemetry.io/collector/pdata v1.54.0 + go.opentelemetry.io/collector/pdata/testdata v0.148.0 + go.opentelemetry.io/collector/pipeline v1.54.0 + go.opentelemetry.io/collector/processor v1.54.0 + go.opentelemetry.io/collector/processor/batchprocessor v0.148.0 + go.opentelemetry.io/collector/receiver v1.54.0 + go.opentelemetry.io/collector/receiver/otlpreceiver v0.148.0 + go.opentelemetry.io/collector/receiver/receivertest v0.148.0 + go.opentelemetry.io/collector/service v0.148.0 + go.opentelemetry.io/proto/otlp v1.10.0 go.uber.org/goleak v1.3.0 go.uber.org/zap v1.27.1 - google.golang.org/grpc v1.77.0 - google.golang.org/protobuf v1.36.10 + google.golang.org/grpc v1.79.3 + google.golang.org/protobuf v1.36.11 ) require ( github.com/beorn7/perks v1.0.1 // indirect github.com/cenkalti/backoff/v5 v5.0.3 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect - github.com/davecgh/go-spew v1.1.1 // indirect - github.com/ebitengine/purego v0.9.0 // indirect + github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect + github.com/ebitengine/purego v0.10.0 // indirect github.com/felixge/httpsnoop v1.0.4 // indirect - github.com/foxboron/go-tpm-keyfiles v0.0.0-20250903184740-5d135037bd4d // indirect + github.com/foxboron/go-tpm-keyfiles v0.0.0-20251226215517-609e4778396f // indirect github.com/fsnotify/fsnotify v1.9.0 // indirect github.com/go-logr/logr v1.4.3 // indirect github.com/go-logr/stdr v1.2.2 // indirect github.com/go-ole/go-ole v1.2.6 // indirect - github.com/go-viper/mapstructure/v2 v2.4.0 // indirect + github.com/go-viper/mapstructure/v2 v2.5.0 // indirect github.com/gobwas/glob v0.2.3 // indirect github.com/golang/snappy v1.0.0 // indirect - github.com/google/go-tpm v0.9.7 // indirect - github.com/google/uuid v1.6.0 // indirect - github.com/grafana/regexp v0.0.0-20240518133315-a468a5bfb3bc // indirect - github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.2 // indirect - github.com/hashicorp/go-version v1.7.0 // indirect + github.com/google/go-tpm v0.9.8 // indirect + github.com/grpc-ecosystem/grpc-gateway/v2 v2.28.0 // indirect + github.com/hashicorp/go-version v1.8.0 // indirect + github.com/hashicorp/golang-lru/v2 v2.0.7 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/json-iterator/go v1.1.12 // indirect - github.com/klauspost/compress v1.18.1 // indirect + github.com/klauspost/compress v1.18.4 // indirect github.com/knadh/koanf/maps v0.1.2 // indirect github.com/knadh/koanf/providers/confmap v1.0.0 // indirect - github.com/knadh/koanf/v2 v2.3.0 // indirect - github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 // indirect + github.com/knadh/koanf/v2 v2.3.3 // indirect + github.com/lufia/plan9stats v0.0.0-20251013123823-9fd1530e3ec3 // indirect github.com/mitchellh/copystructure v1.2.0 // indirect github.com/mitchellh/reflectwalk v1.0.2 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee // indirect github.com/mostynb/go-grpc-compression v1.2.3 // indirect github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect - github.com/pierrec/lz4/v4 v4.1.22 // indirect - github.com/pmezard/go-difflib v1.0.0 // indirect + github.com/pierrec/lz4/v4 v4.1.26 // indirect + github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect github.com/power-devops/perfstat v0.0.0-20240221224432-82ca36839d55 // indirect github.com/prometheus/client_golang v1.23.2 // indirect - github.com/prometheus/client_model v0.6.2 // indirect - github.com/prometheus/otlptranslator v0.0.2 // indirect - github.com/prometheus/procfs v0.17.0 // indirect + github.com/prometheus/otlptranslator v1.0.0 // indirect + github.com/prometheus/procfs v0.20.1 // indirect github.com/rs/cors v1.11.1 // indirect - github.com/shirou/gopsutil/v4 v4.25.10 // indirect - github.com/spf13/cobra v1.10.1 // indirect - github.com/spf13/pflag v1.0.9 // indirect - github.com/tklauser/go-sysconf v0.3.15 // indirect - github.com/tklauser/numcpus v0.10.0 // indirect + github.com/shirou/gopsutil/v4 v4.26.2 // indirect + github.com/spf13/cobra v1.10.2 // indirect + github.com/spf13/pflag v1.0.10 // indirect + github.com/tklauser/go-sysconf v0.3.16 // indirect + github.com/tklauser/numcpus v0.11.0 // indirect github.com/yusufpapurcu/wmi v1.2.4 // indirect go.opentelemetry.io/auto/sdk v1.2.1 // indirect - go.opentelemetry.io/collector v0.140.0 // indirect - go.opentelemetry.io/collector/client v1.46.0 // indirect - go.opentelemetry.io/collector/config/configcompression v1.46.0 // indirect - go.opentelemetry.io/collector/config/configmiddleware v1.46.0 // indirect - go.opentelemetry.io/collector/confmap/xconfmap v0.140.0 // indirect - go.opentelemetry.io/collector/connector/xconnector v0.140.0 // indirect - go.opentelemetry.io/collector/consumer/consumererror v0.140.0 // indirect + go.opentelemetry.io/collector v0.148.0 // indirect + go.opentelemetry.io/collector/client v1.54.0 // indirect + go.opentelemetry.io/collector/config/configcompression v1.54.0 // indirect + go.opentelemetry.io/collector/config/configmiddleware v1.54.0 // indirect + go.opentelemetry.io/collector/confmap/xconfmap v0.148.0 // indirect + go.opentelemetry.io/collector/connector/xconnector v0.148.0 // indirect + go.opentelemetry.io/collector/consumer/consumererror v0.148.0 // indirect go.opentelemetry.io/collector/consumer/consumererror/xconsumererror v0.140.0 // indirect - go.opentelemetry.io/collector/consumer/xconsumer v0.140.0 // indirect - go.opentelemetry.io/collector/exporter/exporterhelper/xexporterhelper v0.140.0 // indirect - go.opentelemetry.io/collector/exporter/xexporter v0.140.0 // indirect - go.opentelemetry.io/collector/extension/extensionauth v1.46.0 // indirect + go.opentelemetry.io/collector/consumer/xconsumer v0.148.0 // indirect + go.opentelemetry.io/collector/exporter/exporterhelper/xexporterhelper v0.148.0 // indirect + go.opentelemetry.io/collector/exporter/xexporter v0.148.0 // indirect + go.opentelemetry.io/collector/extension/extensionauth v1.54.0 // indirect go.opentelemetry.io/collector/extension/extensioncapabilities v0.140.0 // indirect - go.opentelemetry.io/collector/extension/extensionmiddleware v0.140.0 // indirect - go.opentelemetry.io/collector/extension/extensiontest v0.140.0 // indirect + go.opentelemetry.io/collector/extension/extensionmiddleware v0.148.0 // indirect + go.opentelemetry.io/collector/extension/extensiontest v0.148.0 // indirect go.opentelemetry.io/collector/extension/xextension v0.140.0 // indirect - go.opentelemetry.io/collector/featuregate v1.46.0 // indirect - go.opentelemetry.io/collector/internal/fanoutconsumer v0.140.0 // indirect + go.opentelemetry.io/collector/featuregate v1.54.0 // indirect + go.opentelemetry.io/collector/internal/componentalias v0.148.0 // indirect + go.opentelemetry.io/collector/internal/fanoutconsumer v0.148.0 // indirect go.opentelemetry.io/collector/internal/telemetry v0.140.0 // indirect - go.opentelemetry.io/collector/pdata/pprofile v0.140.0 // indirect - go.opentelemetry.io/collector/pdata/xpdata v0.140.0 // indirect - go.opentelemetry.io/collector/pipeline/xpipeline v0.140.0 // indirect - go.opentelemetry.io/collector/processor/processortest v0.140.0 // indirect - go.opentelemetry.io/collector/processor/xprocessor v0.140.0 // indirect + go.opentelemetry.io/collector/pdata/pprofile v0.148.0 // indirect + go.opentelemetry.io/collector/pdata/xpdata v0.148.0 // indirect + go.opentelemetry.io/collector/pipeline/xpipeline v0.148.0 // indirect + go.opentelemetry.io/collector/processor/processortest v0.148.0 // indirect + go.opentelemetry.io/collector/processor/xprocessor v0.148.0 // indirect go.opentelemetry.io/collector/receiver/receiverhelper v0.140.0 // indirect - go.opentelemetry.io/collector/receiver/xreceiver v0.140.0 // indirect + go.opentelemetry.io/collector/receiver/xreceiver v0.148.0 // indirect go.opentelemetry.io/collector/service/hostcapabilities v0.140.0 // indirect go.opentelemetry.io/contrib/bridges/otelzap v0.13.0 // indirect go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.63.0 // indirect - go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.63.0 // indirect + go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.67.0 // indirect go.opentelemetry.io/contrib/otelconf v0.18.0 // indirect go.opentelemetry.io/contrib/propagators/b3 v1.38.0 // indirect - go.opentelemetry.io/otel v1.40.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.14.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.14.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.38.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.38.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.38.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.38.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.38.0 // indirect - go.opentelemetry.io/otel/exporters/prometheus v0.60.0 // indirect - go.opentelemetry.io/otel/exporters/stdout/stdoutlog v0.14.0 // indirect - go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.38.0 // indirect - go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.38.0 // indirect - go.opentelemetry.io/otel/log v0.14.0 // indirect - go.opentelemetry.io/otel/metric v1.40.0 // indirect - go.opentelemetry.io/otel/sdk v1.40.0 // indirect - go.opentelemetry.io/otel/sdk/log v0.14.0 // indirect - go.opentelemetry.io/otel/sdk/metric v1.40.0 // indirect - go.opentelemetry.io/otel/trace v1.40.0 // indirect + go.opentelemetry.io/otel v1.42.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.18.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.18.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.42.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.42.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.42.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.42.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.42.0 // indirect + go.opentelemetry.io/otel/exporters/prometheus v0.64.0 // indirect + go.opentelemetry.io/otel/exporters/stdout/stdoutlog v0.18.0 // indirect + go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.42.0 // indirect + go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.42.0 // indirect + go.opentelemetry.io/otel/log v0.18.0 // indirect + go.opentelemetry.io/otel/metric v1.42.0 // indirect + go.opentelemetry.io/otel/sdk v1.42.0 // indirect + go.opentelemetry.io/otel/sdk/log v0.18.0 // indirect + go.opentelemetry.io/otel/sdk/metric v1.42.0 // indirect + go.opentelemetry.io/otel/trace v1.42.0 // indirect go.uber.org/multierr v1.11.0 // indirect go.yaml.in/yaml/v2 v2.4.3 // indirect go.yaml.in/yaml/v3 v3.0.4 // indirect - golang.org/x/crypto v0.45.0 // indirect + golang.org/x/crypto v0.48.0 // indirect golang.org/x/exp v0.0.0-20240506185415-9bf2ced13842 // indirect - golang.org/x/net v0.47.0 // indirect - golang.org/x/sys v0.40.0 // indirect - golang.org/x/text v0.31.0 // indirect - gonum.org/v1/gonum v0.16.0 // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20251022142026-3a174f9686a8 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20251022142026-3a174f9686a8 // indirect + golang.org/x/net v0.51.0 // indirect + golang.org/x/sys v0.41.0 // indirect + golang.org/x/text v0.34.0 // indirect + gonum.org/v1/gonum v0.17.0 // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20260226221140-a57be14db171 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20260226221140-a57be14db171 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) @@ -303,3 +304,5 @@ replace go.opentelemetry.io/collector/confmap/provider/envprovider => ../../conf replace go.opentelemetry.io/collector/exporter/exporterhelper => ../../exporter/exporterhelper replace go.opentelemetry.io/collector/internal/testutil => ../../internal/testutil + +replace go.opentelemetry.io/collector/internal/componentalias => ../componentalias diff --git a/internal/e2e/go.sum b/internal/e2e/go.sum index b6e0a1565c39..dc518c02cac8 100644 --- a/internal/e2e/go.sum +++ b/internal/e2e/go.sum @@ -6,16 +6,15 @@ github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UF github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/ebitengine/purego v0.9.0 h1:mh0zpKBIXDceC63hpvPuGLiJ8ZAa3DfrFTudmfi8A4k= -github.com/ebitengine/purego v0.9.0/go.mod h1:iIjxzd6CiRiOG0UyXP+V1+jWqUXVjPKLAI0mRfJZTmQ= +github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= +github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/ebitengine/purego v0.10.0 h1:QIw4xfpWT6GWTzaW5XEKy3HXoqrJGx1ijYHzTF0/ISU= +github.com/ebitengine/purego v0.10.0/go.mod h1:iIjxzd6CiRiOG0UyXP+V1+jWqUXVjPKLAI0mRfJZTmQ= github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg= github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= -github.com/foxboron/go-tpm-keyfiles v0.0.0-20250903184740-5d135037bd4d h1:EdO/NMMuCZfxhdzTZLuKAciQSnI2DV+Ppg8+vAYrnqA= -github.com/foxboron/go-tpm-keyfiles v0.0.0-20250903184740-5d135037bd4d/go.mod h1:uAyTlAUxchYuiFjTHmuIEJ4nGSm7iOPaGcAyA81fJ80= -github.com/foxboron/swtpm_test v0.0.0-20230726224112-46aaafdf7006 h1:50sW4r0PcvlpG4PV8tYh2RVCapszJgaOLRCS2subvV4= -github.com/foxboron/swtpm_test v0.0.0-20230726224112-46aaafdf7006/go.mod h1:eIXCMsMYCaqq9m1KSSxXwQG11krpuNPGP3k0uaWrbas= +github.com/foxboron/go-tpm-keyfiles v0.0.0-20251226215517-609e4778396f h1:RJ+BDPLSHQO7cSjKBqjPJSbi1qfk9WcsjQDtZiw3dZw= +github.com/foxboron/go-tpm-keyfiles v0.0.0-20251226215517-609e4778396f/go.mod h1:VHbbch/X4roIY22jL1s3qRbZhCiRIgUAF/PdSUcx2io= github.com/fsnotify/fsnotify v1.9.0 h1:2Ml+OJNzbYCTzsxtv8vKSFD9PbJjmhYF14k/jKC7S9k= github.com/fsnotify/fsnotify v1.9.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= @@ -25,50 +24,49 @@ github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY= github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0= -github.com/go-viper/mapstructure/v2 v2.4.0 h1:EBsztssimR/CONLSZZ04E8qAkxNYq4Qp9LvH92wZUgs= -github.com/go-viper/mapstructure/v2 v2.4.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM= +github.com/go-viper/mapstructure/v2 v2.5.0 h1:vM5IJoUAy3d7zRSVtIwQgBj7BiWtMPfmPEgAXnvj1Ro= +github.com/go-viper/mapstructure/v2 v2.5.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM= github.com/gobwas/glob v0.2.3 h1:A4xDbljILXROh+kObIiy5kIaPYD8e96x1tgBhUI5J+Y= github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8= github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= github.com/golang/snappy v1.0.0 h1:Oy607GVXHs7RtbggtPBnr2RmDArIsAefDwvrdWvRhGs= github.com/golang/snappy v1.0.0/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= -github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= -github.com/google/go-tpm v0.9.7 h1:u89J4tUUeDTlH8xxC3CTW7OHZjbjKoHdQ9W7gCUhtxA= -github.com/google/go-tpm v0.9.7/go.mod h1:h9jEsEECg7gtLis0upRBQU+GhYVH6jMjrFxI8u6bVUY= -github.com/google/go-tpm-tools v0.4.4 h1:oiQfAIkc6xTy9Fl5NKTeTJkBTlXdHsxAofmQyxBKY98= -github.com/google/go-tpm-tools v0.4.4/go.mod h1:T8jXkp2s+eltnCDIsXR84/MTcVU9Ja7bh3Mit0pa4AY= +github.com/google/go-tpm v0.9.8 h1:slArAR9Ft+1ybZu0lBwpSmpwhRXaa85hWtMinMyRAWo= +github.com/google/go-tpm v0.9.8/go.mod h1:h9jEsEECg7gtLis0upRBQU+GhYVH6jMjrFxI8u6bVUY= +github.com/google/go-tpm-tools v0.4.7 h1:J3ycC8umYxM9A4eF73EofRZu4BxY0jjQnUnkhIBbvws= +github.com/google/go-tpm-tools v0.4.7/go.mod h1:gSyXTZHe3fgbzb6WEGd90QucmsnT1SRdlye82gH8QjQ= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/grafana/regexp v0.0.0-20240518133315-a468a5bfb3bc h1:GN2Lv3MGO7AS6PrRoT6yV5+wkrOpcszoIsO4+4ds248= -github.com/grafana/regexp v0.0.0-20240518133315-a468a5bfb3bc/go.mod h1:+JKpmjMGhpgPL+rXZ5nsZieVzvarn86asRlBg4uNGnk= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.2 h1:8Tjv8EJ+pM1xP8mK6egEbD1OgnVTyacbefKhmbLhIhU= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.2/go.mod h1:pkJQ2tZHJ0aFOVEEot6oZmaVEZcRme73eIFmhiVuRWs= -github.com/hashicorp/go-version v1.7.0 h1:5tqGy27NaOTB8yJKUZELlFAS/LTKJkrmONwQKeRZfjY= -github.com/hashicorp/go-version v1.7.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.28.0 h1:HWRh5R2+9EifMyIHV7ZV+MIZqgz+PMpZ14Jynv3O2Zs= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.28.0/go.mod h1:JfhWUomR1baixubs02l85lZYYOm7LV6om4ceouMv45c= +github.com/hashicorp/go-version v1.8.0 h1:KAkNb1HAiZd1ukkxDFGmokVZe1Xy9HG6NUp+bPle2i4= +github.com/hashicorp/go-version v1.8.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= +github.com/hashicorp/golang-lru/v2 v2.0.7 h1:a+bsQ5rvGLjzHuww6tVxozPZFVghXaHOwFs4luLUK2k= +github.com/hashicorp/golang-lru/v2 v2.0.7/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyfM2/ZepoAG6RGpeM= github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= -github.com/klauspost/compress v1.18.1 h1:bcSGx7UbpBqMChDtsF28Lw6v/G94LPrrbMbdC3JH2co= -github.com/klauspost/compress v1.18.1/go.mod h1:ZQFFVG+MdnR0P+l6wpXgIL4NTtwiKIdBnrBd8Nrxr+0= +github.com/klauspost/compress v1.18.4 h1:RPhnKRAQ4Fh8zU2FY/6ZFDwTVTxgJ/EMydqSTzE9a2c= +github.com/klauspost/compress v1.18.4/go.mod h1:R0h/fSBs8DE4ENlcrlib3PsXS61voFxhIs2DeRhCvJ4= github.com/knadh/koanf/maps v0.1.2 h1:RBfmAW5CnZT+PJ1CVc1QSJKf4Xu9kxfQgYVQSu8hpbo= github.com/knadh/koanf/maps v0.1.2/go.mod h1:npD/QZY3V6ghQDdcQzl1W4ICNVTkohC8E73eI2xW4yI= github.com/knadh/koanf/providers/confmap v1.0.0 h1:mHKLJTE7iXEys6deO5p6olAiZdG5zwp8Aebir+/EaRE= github.com/knadh/koanf/providers/confmap v1.0.0/go.mod h1:txHYHiI2hAtF0/0sCmcuol4IDcuQbKTybiB1nOcUo1A= -github.com/knadh/koanf/v2 v2.3.0 h1:Qg076dDRFHvqnKG97ZEsi9TAg2/nFTa9hCdcSa1lvlM= -github.com/knadh/koanf/v2 v2.3.0/go.mod h1:gRb40VRAbd4iJMYYD5IxZ6hfuopFcXBpc9bbQpZwo28= +github.com/knadh/koanf/v2 v2.3.3 h1:jLJC8XCRfLC7n4F+ZKKdBsbq1bfXTpuFhf4L7t94D94= +github.com/knadh/koanf/v2 v2.3.3/go.mod h1:gRb40VRAbd4iJMYYD5IxZ6hfuopFcXBpc9bbQpZwo28= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc= github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= -github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 h1:6E+4a0GO5zZEnZ81pIr0yLvtUWk2if982qA3F3QD6H4= -github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0/go.mod h1:zJYVVT2jmtg6P3p1VtQj7WsuWi/y4VnjVBn7F8KPB3I= +github.com/lufia/plan9stats v0.0.0-20251013123823-9fd1530e3ec3 h1:PwQumkgq4/acIiZhtifTV5OUqqiP82UAl0h87xj/l9k= +github.com/lufia/plan9stats v0.0.0-20251013123823-9fd1530e3ec3/go.mod h1:autxFIvghDt3jPTLoqZ9OZ7s9qTGNAWmYCjVFWPX/zg= github.com/mitchellh/copystructure v1.2.0 h1:vpKXTN4ewci03Vljg/q9QvCGUDttBOGBIa15WveJJGw= github.com/mitchellh/copystructure v1.2.0/go.mod h1:qLl+cE2AmVv+CoeAwDPye/v+N2HKCj9FbZEVFJRxO9s= github.com/mitchellh/reflectwalk v1.0.2 h1:G2LzWKi524PWgd3mLHV8Y5k7s6XUvT0Gef6zxSIeXaQ= @@ -83,41 +81,43 @@ github.com/mostynb/go-grpc-compression v1.2.3 h1:42/BKWMy0KEJGSdWvzqIyOZ95YcR9mL github.com/mostynb/go-grpc-compression v1.2.3/go.mod h1:AghIxF3P57umzqM9yz795+y1Vjs47Km/Y2FE6ouQ7Lg= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= -github.com/pierrec/lz4/v4 v4.1.22 h1:cKFw6uJDK+/gfw5BcDL0JL5aBsAFdsIT18eRtLj7VIU= -github.com/pierrec/lz4/v4 v4.1.22/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4= -github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pierrec/lz4/v4 v4.1.26 h1:GrpZw1gZttORinvzBdXPUXATeqlJjqUG/D87TKMnhjY= +github.com/pierrec/lz4/v4 v4.1.26/go.mod h1:EoQMVJgeeEOMsCqCzqFm2O0cJvljX2nGZjcRIPL34O4= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= +github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/power-devops/perfstat v0.0.0-20240221224432-82ca36839d55 h1:o4JXh1EVt9k/+g42oCprj/FisM4qX9L3sZB3upGN2ZU= github.com/power-devops/perfstat v0.0.0-20240221224432-82ca36839d55/go.mod h1:OmDBASR4679mdNQnz2pUhc2G8CO2JrUAVFDRBDP/hJE= github.com/prometheus/client_golang v1.23.2 h1:Je96obch5RDVy3FDMndoUsjAhG5Edi49h0RJWRi/o0o= github.com/prometheus/client_golang v1.23.2/go.mod h1:Tb1a6LWHB3/SPIzCoaDXI4I8UHKeFTEQ1YCr+0Gyqmg= github.com/prometheus/client_model v0.6.2 h1:oBsgwpGs7iVziMvrGhE53c/GrLUsZdHnqNwqPLxwZyk= github.com/prometheus/client_model v0.6.2/go.mod h1:y3m2F6Gdpfy6Ut/GBsUqTWZqCUvMVzSfMLjcu6wAwpE= -github.com/prometheus/common v0.67.1 h1:OTSON1P4DNxzTg4hmKCc37o4ZAZDv0cfXLkOt0oEowI= -github.com/prometheus/common v0.67.1/go.mod h1:RpmT9v35q2Y+lsieQsdOh5sXZ6ajUGC8NjZAmr8vb0Q= -github.com/prometheus/otlptranslator v0.0.2 h1:+1CdeLVrRQ6Psmhnobldo0kTp96Rj80DRXRd5OSnMEQ= -github.com/prometheus/otlptranslator v0.0.2/go.mod h1:P8AwMgdD7XEr6QRUJ2QWLpiAZTgTE2UYgjlu3svompI= -github.com/prometheus/procfs v0.17.0 h1:FuLQ+05u4ZI+SS/w9+BWEM2TXiHKsUQ9TADiRH7DuK0= -github.com/prometheus/procfs v0.17.0/go.mod h1:oPQLaDAMRbA+u8H5Pbfq+dl3VDAvHxMUOVhe0wYB2zw= +github.com/prometheus/common v0.67.5 h1:pIgK94WWlQt1WLwAC5j2ynLaBRDiinoAb86HZHTUGI4= +github.com/prometheus/common v0.67.5/go.mod h1:SjE/0MzDEEAyrdr5Gqc6G+sXI67maCxzaT3A2+HqjUw= +github.com/prometheus/otlptranslator v1.0.0 h1:s0LJW/iN9dkIH+EnhiD3BlkkP5QVIUVEoIwkU+A6qos= +github.com/prometheus/otlptranslator v1.0.0/go.mod h1:vRYWnXvI6aWGpsdY/mOT/cbeVRBlPWtBNDb7kGR3uKM= +github.com/prometheus/procfs v0.20.1 h1:XwbrGOIplXW/AU3YhIhLODXMJYyC1isLFfYCsTEycfc= +github.com/prometheus/procfs v0.20.1/go.mod h1:o9EMBZGRyvDrSPH1RqdxhojkuXstoe4UlK79eF5TGGo= github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ= github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc= github.com/rs/cors v1.11.1 h1:eU3gRzXLRK57F5rKMGMZURNdIG4EoAmX8k94r9wXWHA= github.com/rs/cors v1.11.1/go.mod h1:XyqrcTp5zjWr1wsJ8PIRZssZ8b/WMcMf71DJnit4EMU= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= -github.com/shirou/gopsutil/v4 v4.25.10 h1:at8lk/5T1OgtuCp+AwrDofFRjnvosn0nkN2OLQ6g8tA= -github.com/shirou/gopsutil/v4 v4.25.10/go.mod h1:+kSwyC8DRUD9XXEHCAFjK+0nuArFJM0lva+StQAcskM= -github.com/spf13/cobra v1.10.1 h1:lJeBwCfmrnXthfAupyUTzJ/J4Nc1RsHC/mSRU2dll/s= -github.com/spf13/cobra v1.10.1/go.mod h1:7SmJGaTHFVBY0jW4NXGluQoLvhqFQM+6XSKD+P4XaB0= -github.com/spf13/pflag v1.0.9 h1:9exaQaMOCwffKiiiYk6/BndUBv+iRViNW+4lEMi0PvY= +github.com/shirou/gopsutil/v4 v4.26.2 h1:X8i6sicvUFih4BmYIGT1m2wwgw2VG9YgrDTi7cIRGUI= +github.com/shirou/gopsutil/v4 v4.26.2/go.mod h1:LZ6ewCSkBqUpvSOf+LsTGnRinC6iaNUNMGBtDkJBaLQ= +github.com/spf13/cobra v1.10.2 h1:DMTTonx5m65Ic0GOoRY2c16WCbHxOOw6xxezuLaBpcU= +github.com/spf13/cobra v1.10.2/go.mod h1:7C1pvHqHw5A4vrJfjNwvOdzYu0Gml16OCs2GRiTUUS4= github.com/spf13/pflag v1.0.9/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= +github.com/spf13/pflag v1.0.10 h1:4EBh2KAYBwaONj6b2Ye1GiHfwjqyROoF4RwYO+vPwFk= +github.com/spf13/pflag v1.0.10/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U= github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= -github.com/tklauser/go-sysconf v0.3.15 h1:VE89k0criAymJ/Os65CSn1IXaol+1wrsFHEB8Ol49K4= -github.com/tklauser/go-sysconf v0.3.15/go.mod h1:Dmjwr6tYFIseJw7a3dRLJfsHAMXZ3nEnL/aZY+0IuI4= -github.com/tklauser/numcpus v0.10.0 h1:18njr6LDBk1zuna922MgdjQuJFjrdppsZG60sHGfjso= -github.com/tklauser/numcpus v0.10.0/go.mod h1:BiTKazU708GQTYF4mB+cmlpT2Is1gLk7XVuEeem8LsQ= +github.com/tklauser/go-sysconf v0.3.16 h1:frioLaCQSsF5Cy1jgRBrzr6t502KIIwQ0MArYICU0nA= +github.com/tklauser/go-sysconf v0.3.16/go.mod h1:/qNL9xxDhc7tx3HSRsLWNnuzbVfh3e7gh/BmM179nYI= +github.com/tklauser/numcpus v0.11.0 h1:nSTwhKH5e1dMNsCdVBukSZrURJRoHbSEQjdEbY+9RXw= +github.com/tklauser/numcpus v0.11.0/go.mod h1:z+LwcLq54uWZTX0u/bGobaV34u6V7KNlTZejzM6/3MQ= github.com/yusufpapurcu/wmi v1.2.4 h1:zFUKzehAFReQwLys1b/iSMl+JQGSCSjtVqQn9bBrPo0= github.com/yusufpapurcu/wmi v1.2.4/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0= go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64= @@ -126,62 +126,62 @@ go.opentelemetry.io/contrib/bridges/otelzap v0.13.0 h1:aBKdhLVieqvwWe9A79UHI/0vg go.opentelemetry.io/contrib/bridges/otelzap v0.13.0/go.mod h1:SYqtxLQE7iINgh6WFuVi2AI70148B8EI35DSk0Wr8m4= go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.63.0 h1:YH4g8lQroajqUwWbq/tr2QX1JFmEXaDLgG+ew9bLMWo= go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.63.0/go.mod h1:fvPi2qXDqFs8M4B4fmJhE92TyQs9Ydjlg3RvfUp+NbQ= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.63.0 h1:RbKq8BG0FI8OiXhBfcRtqqHcZcka+gU3cskNuf05R18= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.63.0/go.mod h1:h06DGIukJOevXaj/xrNjhi/2098RZzcLTbc0jDAUbsg= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.67.0 h1:OyrsyzuttWTSur2qN/Lm0m2a8yqyIjUVBZcxFPuXq2o= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.67.0/go.mod h1:C2NGBr+kAB4bk3xtMXfZ94gqFDtg/GkI7e9zqGh5Beg= go.opentelemetry.io/contrib/otelconf v0.18.0 h1:ciF2Gf00BWs0DnexKFZXcxg9kJ8r3SUW1LOzW3CsKA8= go.opentelemetry.io/contrib/otelconf v0.18.0/go.mod h1:FcP7k+JLwBLdOxS6qY6VQ/4b5VBntI6L6o80IMwhAeI= go.opentelemetry.io/contrib/propagators/b3 v1.38.0 h1:uHsCCOSKl0kLrV2dLkFK+8Ywk9iKa/fptkytc6aFFEo= go.opentelemetry.io/contrib/propagators/b3 v1.38.0/go.mod h1:wMRSZJZcY8ya9mApLLhwIMjqmApy2o/Ml+62lhvxyHU= -go.opentelemetry.io/contrib/zpages v0.63.0 h1:TppOKuZGbqXMgsfjqq3i09N5Vbo1JLtLImUqiTPGnX4= -go.opentelemetry.io/contrib/zpages v0.63.0/go.mod h1:5F8uugz75ay/MMhRRhxAXY33FuaI8dl7jTxefrIy5qk= -go.opentelemetry.io/otel v1.40.0 h1:oA5YeOcpRTXq6NN7frwmwFR0Cn3RhTVZvXsP4duvCms= -go.opentelemetry.io/otel v1.40.0/go.mod h1:IMb+uXZUKkMXdPddhwAHm6UfOwJyh4ct1ybIlV14J0g= -go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.14.0 h1:OMqPldHt79PqWKOMYIAQs3CxAi7RLgPxwfFSwr4ZxtM= -go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.14.0/go.mod h1:1biG4qiqTxKiUCtoWDPpL3fB3KxVwCiGw81j3nKMuHE= -go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.14.0 h1:QQqYw3lkrzwVsoEX0w//EhH/TCnpRdEenKBOOEIMjWc= -go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.14.0/go.mod h1:gSVQcr17jk2ig4jqJ2DX30IdWH251JcNAecvrqTxH1s= -go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.38.0 h1:vl9obrcoWVKp/lwl8tRE33853I8Xru9HFbw/skNeLs8= -go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.38.0/go.mod h1:GAXRxmLJcVM3u22IjTg74zWBrRCKq8BnOqUVLodpcpw= -go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.38.0 h1:Oe2z/BCg5q7k4iXC3cqJxKYg0ieRiOqF0cecFYdPTwk= -go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.38.0/go.mod h1:ZQM5lAJpOsKnYagGg/zV2krVqTtaVdYdDkhMoX6Oalg= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.38.0 h1:GqRJVj7UmLjCVyVJ3ZFLdPRmhDUp2zFmQe3RHIOsw24= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.38.0/go.mod h1:ri3aaHSmCTVYu2AWv44YMauwAQc0aqI9gHKIcSbI1pU= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.38.0 h1:lwI4Dc5leUqENgGuQImwLo4WnuXFPetmPpkLi2IrX54= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.38.0/go.mod h1:Kz/oCE7z5wuyhPxsXDuaPteSWqjSBD5YaSdbxZYGbGk= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.38.0 h1:aTL7F04bJHUlztTsNGJ2l+6he8c+y/b//eR0jjjemT4= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.38.0/go.mod h1:kldtb7jDTeol0l3ewcmd8SDvx3EmIE7lyvqbasU3QC4= -go.opentelemetry.io/otel/exporters/prometheus v0.60.0 h1:cGtQxGvZbnrWdC2GyjZi0PDKVSLWP/Jocix3QWfXtbo= -go.opentelemetry.io/otel/exporters/prometheus v0.60.0/go.mod h1:hkd1EekxNo69PTV4OWFGZcKQiIqg0RfuWExcPKFvepk= -go.opentelemetry.io/otel/exporters/stdout/stdoutlog v0.14.0 h1:B/g+qde6Mkzxbry5ZZag0l7QrQBCtVm7lVjaLgmpje8= -go.opentelemetry.io/otel/exporters/stdout/stdoutlog v0.14.0/go.mod h1:mOJK8eMmgW6ocDJn6Bn11CcZ05gi3P8GylBXEkZtbgA= -go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.38.0 h1:wm/Q0GAAykXv83wzcKzGGqAnnfLFyFe7RslekZuv+VI= -go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.38.0/go.mod h1:ra3Pa40+oKjvYh+ZD3EdxFZZB0xdMfuileHAm4nNN7w= -go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.38.0 h1:kJxSDN4SgWWTjG/hPp3O7LCGLcHXFlvS2/FFOrwL+SE= -go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.38.0/go.mod h1:mgIOzS7iZeKJdeB8/NYHrJ48fdGc71Llo5bJ1J4DWUE= -go.opentelemetry.io/otel/log v0.14.0 h1:2rzJ+pOAZ8qmZ3DDHg73NEKzSZkhkGIua9gXtxNGgrM= -go.opentelemetry.io/otel/log v0.14.0/go.mod h1:5jRG92fEAgx0SU/vFPxmJvhIuDU9E1SUnEQrMlJpOno= +go.opentelemetry.io/contrib/zpages v0.67.0 h1:cIUwWSVDovuLEbDIKreptjdxMuIhGiqwq0uL8YNaq1c= +go.opentelemetry.io/contrib/zpages v0.67.0/go.mod h1:vK8fsYHgPYg4Z/XDbFSEvItSGZDbjWTvjBOu8+AiDhc= +go.opentelemetry.io/otel v1.42.0 h1:lSQGzTgVR3+sgJDAU/7/ZMjN9Z+vUip7leaqBKy4sho= +go.opentelemetry.io/otel v1.42.0/go.mod h1:lJNsdRMxCUIWuMlVJWzecSMuNjE7dOYyWlqOXWkdqCc= +go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.18.0 h1:deI9UQMoGFgrg5iLPgzueqFPHevDl+28YKfSpPTI6rY= +go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.18.0/go.mod h1:PFx9NgpNUKXdf7J4Q3agRxMs3Y07QhTCVipKmLsMKnU= +go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.18.0 h1:icqq3Z34UrEFk2u+HMhTtRsvo7Ues+eiJVjaJt62njs= +go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.18.0/go.mod h1:W2m8P+d5Wn5kipj4/xmbt9uMqezEKfBjzVJadfABSBE= +go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.42.0 h1:MdKucPl/HbzckWWEisiNqMPhRrAOQX8r4jTuGr636gk= +go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.42.0/go.mod h1:RolT8tWtfHcjajEH5wFIZ4Dgh5jpPdFXYV9pTAk/qjc= +go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.42.0 h1:H7O6RlGOMTizyl3R08Kn5pdM06bnH8oscSj7o11tmLA= +go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.42.0/go.mod h1:mBFWu/WOVDkWWsR7Tx7h6EpQB8wsv7P0Yrh0Pb7othc= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.42.0 h1:THuZiwpQZuHPul65w4WcwEnkX2QIuMT+UFoOrygtoJw= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.42.0/go.mod h1:J2pvYM5NGHofZ2/Ru6zw/TNWnEQp5crgyDeSrYpXkAw= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.42.0 h1:zWWrB1U6nqhS/k6zYB74CjRpuiitRtLLi68VcgmOEto= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.42.0/go.mod h1:2qXPNBX1OVRC0IwOnfo1ljoid+RD0QK3443EaqVlsOU= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.42.0 h1:uLXP+3mghfMf7XmV4PkGfFhFKuNWoCvvx5wP/wOXo0o= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.42.0/go.mod h1:v0Tj04armyT59mnURNUJf7RCKcKzq+lgJs6QSjHjaTc= +go.opentelemetry.io/otel/exporters/prometheus v0.64.0 h1:g0LRDXMX/G1SEZtK8zl8Chm4K6GBwRkjPKE36LxiTYs= +go.opentelemetry.io/otel/exporters/prometheus v0.64.0/go.mod h1:UrgcjnarfdlBDP3GjDIJWe6HTprwSazNjwsI+Ru6hro= +go.opentelemetry.io/otel/exporters/stdout/stdoutlog v0.18.0 h1:KJVjPD3rcPb98rIs3HznyJlrfx9ge5oJvxxlGR+P/7s= +go.opentelemetry.io/otel/exporters/stdout/stdoutlog v0.18.0/go.mod h1:K3kRa2ckmHWQaTWQdPRHc7qGXASuVuoEQXzrvlA98Ws= +go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.42.0 h1:lSZHgNHfbmQTPfuTmWVkEu8J8qXaQwuV30pjCcAUvP8= +go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.42.0/go.mod h1:so9ounLcuoRDu033MW/E0AD4hhUjVqswrMF5FoZlBcw= +go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.42.0 h1:s/1iRkCKDfhlh1JF26knRneorus8aOwVIDhvYx9WoDw= +go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.42.0/go.mod h1:UI3wi0FXg1Pofb8ZBiBLhtMzgoTm1TYkMvn71fAqDzs= +go.opentelemetry.io/otel/log v0.18.0 h1:XgeQIIBjZZrliksMEbcwMZefoOSMI1hdjiLEiiB0bAg= +go.opentelemetry.io/otel/log v0.18.0/go.mod h1:KEV1kad0NofR3ycsiDH4Yjcoj0+8206I6Ox2QYFSNgI= go.opentelemetry.io/otel/log/logtest v0.14.0 h1:BGTqNeluJDK2uIHAY8lRqxjVAYfqgcaTbVk1n3MWe5A= go.opentelemetry.io/otel/log/logtest v0.14.0/go.mod h1:IuguGt8XVP4XA4d2oEEDMVDBBCesMg8/tSGWDjuKfoA= -go.opentelemetry.io/otel/metric v1.40.0 h1:rcZe317KPftE2rstWIBitCdVp89A2HqjkxR3c11+p9g= -go.opentelemetry.io/otel/metric v1.40.0/go.mod h1:ib/crwQH7N3r5kfiBZQbwrTge743UDc7DTFVZrrXnqc= -go.opentelemetry.io/otel/sdk v1.40.0 h1:KHW/jUzgo6wsPh9At46+h4upjtccTmuZCFAc9OJ71f8= -go.opentelemetry.io/otel/sdk v1.40.0/go.mod h1:Ph7EFdYvxq72Y8Li9q8KebuYUr2KoeyHx0DRMKrYBUE= -go.opentelemetry.io/otel/sdk/log v0.14.0 h1:JU/U3O7N6fsAXj0+CXz21Czg532dW2V4gG1HE/e8Zrg= -go.opentelemetry.io/otel/sdk/log v0.14.0/go.mod h1:imQvII+0ZylXfKU7/wtOND8Hn4OpT3YUoIgqJVksUkM= -go.opentelemetry.io/otel/sdk/log/logtest v0.14.0 h1:Ijbtz+JKXl8T2MngiwqBlPaHqc4YCaP/i13Qrow6gAM= -go.opentelemetry.io/otel/sdk/log/logtest v0.14.0/go.mod h1:dCU8aEL6q+L9cYTqcVOk8rM9Tp8WdnHOPLiBgp0SGOA= -go.opentelemetry.io/otel/sdk/metric v1.40.0 h1:mtmdVqgQkeRxHgRv4qhyJduP3fYJRMX4AtAlbuWdCYw= -go.opentelemetry.io/otel/sdk/metric v1.40.0/go.mod h1:4Z2bGMf0KSK3uRjlczMOeMhKU2rhUqdWNoKcYrtcBPg= -go.opentelemetry.io/otel/trace v1.40.0 h1:WA4etStDttCSYuhwvEa8OP8I5EWu24lkOzp+ZYblVjw= -go.opentelemetry.io/otel/trace v1.40.0/go.mod h1:zeAhriXecNGP/s2SEG3+Y8X9ujcJOTqQ5RgdEJcawiA= -go.opentelemetry.io/proto/otlp v1.9.0 h1:l706jCMITVouPOqEnii2fIAuO3IVGBRPV5ICjceRb/A= -go.opentelemetry.io/proto/otlp v1.9.0/go.mod h1:xE+Cx5E/eEHw+ISFkwPLwCZefwVjY+pqKg1qcK03+/4= -go.opentelemetry.io/proto/slim/otlp v1.9.0 h1:fPVMv8tP3TrsqlkH1HWYUpbCY9cAIemx184VGkS6vlE= -go.opentelemetry.io/proto/slim/otlp v1.9.0/go.mod h1:xXdeJJ90Gqyll+orzUkY4bOd2HECo5JofeoLpymVqdI= -go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.2.0 h1:o13nadWDNkH/quoDomDUClnQBpdQQ2Qqv0lQBjIXjE8= -go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.2.0/go.mod h1:Gyb6Xe7FTi/6xBHwMmngGoHqL0w29Y4eW8TGFzpefGA= -go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.2.0 h1:EiUYvtwu6PMrMHVjcPfnsG3v+ajPkbUeH+IL93+QYyk= -go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.2.0/go.mod h1:mUUHKFiN2SST3AhJ8XhJxEoeVW12oqfXog0Bo8W3Ec4= +go.opentelemetry.io/otel/metric v1.42.0 h1:2jXG+3oZLNXEPfNmnpxKDeZsFI5o4J+nz6xUlaFdF/4= +go.opentelemetry.io/otel/metric v1.42.0/go.mod h1:RlUN/7vTU7Ao/diDkEpQpnz3/92J9ko05BIwxYa2SSI= +go.opentelemetry.io/otel/sdk v1.42.0 h1:LyC8+jqk6UJwdrI/8VydAq/hvkFKNHZVIWuslJXYsDo= +go.opentelemetry.io/otel/sdk v1.42.0/go.mod h1:rGHCAxd9DAph0joO4W6OPwxjNTYWghRWmkHuGbayMts= +go.opentelemetry.io/otel/sdk/log v0.18.0 h1:n8OyZr7t7otkeTnPTbDNom6rW16TBYGtvyy2Gk6buQw= +go.opentelemetry.io/otel/sdk/log v0.18.0/go.mod h1:C0+wxkTwKpOCZLrlJ3pewPiiQwpzycPI/u6W0Z9fuYk= +go.opentelemetry.io/otel/sdk/log/logtest v0.18.0 h1:l3mYuPsuBx6UKE47BVcPrZoZ0q/KER57vbj2qkgDLXA= +go.opentelemetry.io/otel/sdk/log/logtest v0.18.0/go.mod h1:7cHtiVJpZebB3wybTa4NG+FUo5NPe3PROz1FqB0+qdw= +go.opentelemetry.io/otel/sdk/metric v1.42.0 h1:D/1QR46Clz6ajyZ3G8SgNlTJKBdGp84q9RKCAZ3YGuA= +go.opentelemetry.io/otel/sdk/metric v1.42.0/go.mod h1:Ua6AAlDKdZ7tdvaQKfSmnFTdHx37+J4ba8MwVCYM5hc= +go.opentelemetry.io/otel/trace v1.42.0 h1:OUCgIPt+mzOnaUTpOQcBiM/PLQ/Op7oq6g4LenLmOYY= +go.opentelemetry.io/otel/trace v1.42.0/go.mod h1:f3K9S+IFqnumBkKhRJMeaZeNk9epyhnCmQh/EysQCdc= +go.opentelemetry.io/proto/otlp v1.10.0 h1:IQRWgT5srOCYfiWnpqUYz9CVmbO8bFmKcwYxpuCSL2g= +go.opentelemetry.io/proto/otlp v1.10.0/go.mod h1:/CV4QoCR/S9yaPj8utp3lvQPoqMtxXdzn7ozvvozVqk= +go.opentelemetry.io/proto/slim/otlp v1.10.0 h1:iR97Vs/ZDR+y9TfuP9b1XBtdPWeC+OMslIBmhcLU7jM= +go.opentelemetry.io/proto/slim/otlp v1.10.0/go.mod h1:lV9250stpjYLPNA5viFabIgP2QlUGRT1GdTgAf8SIUk= +go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.3.0 h1:RUF5rO0hAlgiJt1fzQVzcVs3vZVNHIcMLgOgG4rWNcQ= +go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.3.0/go.mod h1:I89cynRj8y+383o7tEQVg2SVA6SRgDVIouWPUVXjx0U= +go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.3.0 h1:CQvJSldHRUN6Z8jsUeYv8J0lXRvygALXIzsmAeCcZE0= +go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.3.0/go.mod h1:xSQ+mEfJe/GjK1LXEyVOoSI1N9JV9ZI923X5kup43W4= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= @@ -192,29 +192,28 @@ go.yaml.in/yaml/v2 v2.4.3 h1:6gvOSjQoTB3vt1l+CU+tSyi/HOjfOjRLJ4YwYZGwRO0= go.yaml.in/yaml/v2 v2.4.3/go.mod h1:zSxWcmIDjOzPXpjlTTbAsKokqkDNAVtZO0WOMiT90s8= go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc= go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg= -golang.org/x/crypto v0.45.0 h1:jMBrvKuj23MTlT0bQEOBcAE0mjg8mK9RXFhRH6nyF3Q= -golang.org/x/crypto v0.45.0/go.mod h1:XTGrrkGJve7CYK7J8PEww4aY7gM3qMCElcJQ8n8JdX4= +golang.org/x/crypto v0.48.0 h1:/VRzVqiRSggnhY7gNRxPauEQ5Drw9haKdM0jqfcCFts= +golang.org/x/crypto v0.48.0/go.mod h1:r0kV5h3qnFPlQnBSrULhlsRfryS2pmewsg+XfMgkVos= golang.org/x/exp v0.0.0-20240506185415-9bf2ced13842 h1:vr/HnozRka3pE4EsMEg1lgkXJkTFJCVUX+S/ZT6wYzM= golang.org/x/exp v0.0.0-20240506185415-9bf2ced13842/go.mod h1:XtvwrStGgqGPLc4cjQfWqZHG1YFdYs6swckp8vpsjnc= -golang.org/x/net v0.47.0 h1:Mx+4dIFzqraBXUugkia1OOvlD6LemFo1ALMHjrXDOhY= -golang.org/x/net v0.47.0/go.mod h1:/jNxtkgq5yWUGYkaZGqo27cfGZ1c5Nen03aYrrKpVRU= +golang.org/x/net v0.51.0 h1:94R/GTO7mt3/4wIKpcR5gkGmRLOuE/2hNGeWq/GBIFo= +golang.org/x/net v0.51.0/go.mod h1:aamm+2QF5ogm02fjy5Bb7CQ0WMt1/WVM7FtyaTLlA9Y= golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201204225414-ed752295db88/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.40.0 h1:DBZZqJ2Rkml6QMQsZywtnjnnGvHza6BTfYFWY9kjEWQ= -golang.org/x/sys v0.40.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= -golang.org/x/text v0.31.0 h1:aC8ghyu4JhP8VojJ2lEHBnochRno1sgL6nEi9WGFGMM= -golang.org/x/text v0.31.0/go.mod h1:tKRAlv61yKIjGGHX/4tP1LTbc13YSec1pxVEWXzfoeM= -golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -gonum.org/v1/gonum v0.16.0 h1:5+ul4Swaf3ESvrOnidPp4GZbzf0mxVQpDCYUQE7OJfk= -gonum.org/v1/gonum v0.16.0/go.mod h1:fef3am4MQ93R2HHpKnLk4/Tbh/s0+wqD5nfa6Pnwy4E= -google.golang.org/genproto/googleapis/api v0.0.0-20251022142026-3a174f9686a8 h1:mepRgnBZa07I4TRuomDE4sTIYieg/osKmzIf4USdWS4= -google.golang.org/genproto/googleapis/api v0.0.0-20251022142026-3a174f9686a8/go.mod h1:fDMmzKV90WSg1NbozdqrE64fkuTv6mlq2zxo9ad+3yo= -google.golang.org/genproto/googleapis/rpc v0.0.0-20251022142026-3a174f9686a8 h1:M1rk8KBnUsBDg1oPGHNCxG4vc1f49epmTO7xscSajMk= -google.golang.org/genproto/googleapis/rpc v0.0.0-20251022142026-3a174f9686a8/go.mod h1:7i2o+ce6H/6BluujYR+kqX3GKH+dChPTQU19wjRPiGk= -google.golang.org/grpc v1.77.0 h1:wVVY6/8cGA6vvffn+wWK5ToddbgdU3d8MNENr4evgXM= -google.golang.org/grpc v1.77.0/go.mod h1:z0BY1iVj0q8E1uSQCjL9cppRj+gnZjzDnzV0dHhrNig= -google.golang.org/protobuf v1.36.10 h1:AYd7cD/uASjIL6Q9LiTjz8JLcrh/88q5UObnmY3aOOE= -google.golang.org/protobuf v1.36.10/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= +golang.org/x/sys v0.41.0 h1:Ivj+2Cp/ylzLiEU89QhWblYnOE9zerudt9Ftecq2C6k= +golang.org/x/sys v0.41.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= +golang.org/x/text v0.34.0 h1:oL/Qq0Kdaqxa1KbNeMKwQq0reLCCaFtqu2eNuSeNHbk= +golang.org/x/text v0.34.0/go.mod h1:homfLqTYRFyVYemLBFl5GgL/DWEiH5wcsQ5gSh1yziA= +gonum.org/v1/gonum v0.17.0 h1:VbpOemQlsSMrYmn7T2OUvQ4dqxQXU+ouZFQsZOx50z4= +gonum.org/v1/gonum v0.17.0/go.mod h1:El3tOrEuMpv2UdMrbNlKEh9vd86bmQ6vqIcDwxEOc1E= +google.golang.org/genproto/googleapis/api v0.0.0-20260226221140-a57be14db171 h1:tu/dtnW1o3wfaxCOjSLn5IRX4YDcJrtlpzYkhHhGaC4= +google.golang.org/genproto/googleapis/api v0.0.0-20260226221140-a57be14db171/go.mod h1:M5krXqk4GhBKvB596udGL3UyjL4I1+cTbK0orROM9ng= +google.golang.org/genproto/googleapis/rpc v0.0.0-20260226221140-a57be14db171 h1:ggcbiqK8WWh6l1dnltU4BgWGIGo+EVYxCaAPih/zQXQ= +google.golang.org/genproto/googleapis/rpc v0.0.0-20260226221140-a57be14db171/go.mod h1:4Hqkh8ycfw05ld/3BWL7rJOSfebL2Q+DVDeRgYgxUU8= +google.golang.org/grpc v1.79.3 h1:sybAEdRIEtvcD68Gx7dmnwjZKlyfuc61Dyo9pGXXkKE= +google.golang.org/grpc v1.79.3/go.mod h1:KmT0Kjez+0dde/v2j9vzwoAScgEPx/Bw1CYChhHLrHQ= +google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE= +google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= diff --git a/internal/e2e/internal_telemetry_test.go b/internal/e2e/internal_telemetry_test.go new file mode 100644 index 000000000000..386af7324667 --- /dev/null +++ b/internal/e2e/internal_telemetry_test.go @@ -0,0 +1,301 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +package e2e + +import ( + "bytes" + "encoding/json" + "encoding/pem" + "fmt" + "io" + "log" + "net/http" + "net/http/httptest" + "net/url" + "os" + "path/filepath" + "slices" + "sync" + "testing" + "time" + + "github.com/google/uuid" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "go.uber.org/zap" + + "go.opentelemetry.io/collector/component" + "go.opentelemetry.io/collector/confmap" + "go.opentelemetry.io/collector/confmap/provider/fileprovider" + "go.opentelemetry.io/collector/confmap/provider/yamlprovider" + "go.opentelemetry.io/collector/consumer/consumertest" + "go.opentelemetry.io/collector/exporter" + "go.opentelemetry.io/collector/exporter/exportertest" + "go.opentelemetry.io/collector/otelcol" + "go.opentelemetry.io/collector/pdata/ptrace/ptraceotlp" + "go.opentelemetry.io/collector/receiver" + "go.opentelemetry.io/collector/receiver/otlpreceiver" + "go.opentelemetry.io/collector/service/telemetry/otelconftelemetry" +) + +// TestInternalTelemetry_ServiceInstanceID verifies that the service.instance.id +// attribute is generated by default (unless overridden), and is is consistent +// across all internal telemetry providers. +func TestInternalTelemetry_ServiceInstanceID(t *testing.T) { + type testcase struct { + extraYamlConfig string + checkServiceInstanceID func(t *testing.T, serviceInstanceID string) + } + + for name, tt := range map[string]testcase{ + "default": { + checkServiceInstanceID: func(t *testing.T, serviceInstanceID string) { + // By default, service.instance.id should be a generated UUIDv4 + _, err := uuid.Parse(serviceInstanceID) + require.NoError(t, err) + }, + }, + "service.instance.id set in config": { + extraYamlConfig: ` +service: + telemetry: + resource: + service.instance.id: "my-custom-instance-id"`, + checkServiceInstanceID: func(t *testing.T, serviceInstanceID string) { + assert.Equal(t, "my-custom-instance-id", serviceInstanceID) + }, + }, + } { + t.Run(name, func(t *testing.T) { + // Set up a TLS server to capture traces from collector's internal telemetry. + // otelconf always attaches a TLS client config for OTLP/HTTP exporters, so + // the test server cert needs to be trusted instead of using insecure HTTP. + traceSink := new(consumertest.TracesSink) + traceServer := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + body, err := io.ReadAll(r.Body) + if err != nil { + http.Error(w, err.Error(), http.StatusBadRequest) + return + } + otlpReq := ptraceotlp.NewExportRequest() + if err := otlpReq.UnmarshalProto(body); err != nil { + http.Error(w, err.Error(), http.StatusBadRequest) + return + } + _ = traceSink.ConsumeTraces(r.Context(), otlpReq.Traces()) + })) + defer traceServer.Close() + traceCertFile := filepath.Join(t.TempDir(), "trace-server-cert.pem") + require.NoError(t, os.WriteFile(traceCertFile, pem.EncodeToMemory(&pem.Block{ + Type: "CERTIFICATE", + Bytes: traceServer.Certificate().Raw, + }), 0o600)) + + logSink := registerTestLogSink(t) + + // Create temporary directory for the config file + tempdir := t.TempDir() + configFile := filepath.Join(tempdir, "config.yaml") + + // Create YAML config + otlphttpPort := getFreePort(t) + metricsPort := getFreePort(t) + require.NoError(t, os.WriteFile(configFile, []byte(fmt.Sprintf(` +receivers: + otlp: + protocols: + http: + endpoint: localhost:%s + +exporters: + nop: + +service: + telemetry: + logs: + level: info + encoding: json + output_paths: [%q] + metrics: + level: normal + readers: + - pull: + exporter: + prometheus: + host: localhost + port: %s + traces: + level: normal + processors: + - simple: + exporter: + otlp: + protocol: http/protobuf + certificate: %s + endpoint: %s + pipelines: + traces: + receivers: [otlp] + exporters: [nop] +`, otlphttpPort, logSink.url, metricsPort, traceCertFile, traceServer.URL)[1:]), 0o600)) + + // Create collector + configURIs := []string{configFile} + if tt.extraYamlConfig != "" { + configURIs = append(configURIs, "yaml:"+tt.extraYamlConfig) + } + collector, err := otelcol.NewCollector(otelcol.CollectorSettings{ + BuildInfo: component.NewDefaultBuildInfo(), + Factories: func() (otelcol.Factories, error) { + otlpreceiverFactory := otlpreceiver.NewFactory() + return otelcol.Factories{ + Receivers: map[component.Type]receiver.Factory{ + otlpreceiverFactory.Type(): otlpreceiverFactory, + }, + Exporters: map[component.Type]exporter.Factory{ + nopType: exportertest.NewNopFactory(), + }, + Telemetry: otelconftelemetry.NewFactory(), + }, nil + }, + ConfigProviderSettings: otelcol.ConfigProviderSettings{ + ResolverSettings: confmap.ResolverSettings{ + URIs: configURIs, + ProviderFactories: []confmap.ProviderFactory{ + fileprovider.NewFactory(), + yamlprovider.NewFactory(), + }, + }, + }, + }) + require.NoError(t, err) + + // Start collector + go func() { + assert.NoError(t, collector.Run(t.Context())) + }() + waitMetricsReady(t, metricsPort) + + // Send some data through the pipeline to trigger internal telemetry + err = sendTestTraces(otlphttpPort) + require.NoError(t, err) + + // Capture service.instance.id from the Prometheus endpoint + var metricInstanceID string + parsed := readMetrics(t, metricsPort) + targetInfo := parsed["target_info"] + require.NotNil(t, targetInfo, "target_info metric not found") + require.Len(t, targetInfo.Metric, 1) + for _, label := range targetInfo.Metric[0].Label { + if label.GetName() == "service_instance_id" { + metricInstanceID = label.GetValue() + break + } + } + tt.checkServiceInstanceID(t, metricInstanceID) + + // Wait for traces, verify service.instance.id matches the one from metrics + require.EventuallyWithT(t, func(t *assert.CollectT) { + allTraces := traceSink.AllTraces() + require.NotEmpty(t, allTraces) + + // Find service.instance.id in resource attributes + for _, td := range allTraces { + for i := 0; i < td.ResourceSpans().Len(); i++ { + rs := td.ResourceSpans().At(i) + if attr, ok := rs.Resource().Attributes().Get("service.instance.id"); ok { + traceInstanceID := attr.AsString() + require.Equal(t, metricInstanceID, traceInstanceID) + } + } + } + }, 10*time.Second, 500*time.Millisecond) + + // Check service.instance.id in logs matches the one from metrics + var logsCount int + logContent := logSink.Bytes() + for line := range bytes.Lines(bytes.TrimSpace(logContent)) { + var logEntry map[string]any + if err := json.Unmarshal(line, &logEntry); err != nil { + continue + } + // Check for resource field with service.instance.id + // Resource attributes are nested under "resource" key as a dictionary + resource, ok := logEntry["resource"].(map[string]any) + require.True(t, ok, "log entry should have resource field") + logInstanceID, ok := resource["service.instance.id"].(string) + require.True(t, ok, "resource should have service.instance.id") + require.Equal(t, metricInstanceID, logInstanceID) + logsCount++ + } + assert.NotZero(t, logsCount) + }) + } +} + +// Test-specific zap sink to capture logs as close as possible to logs being written to file. +// The reason we don't actually write to files is because Zap provides no way of closing file +// sinks created by zap.Config.Build. + +var ( + testSinksMu sync.Mutex + testSinks = make(map[string]*testSink) +) + +type testSink struct { + url string + + mu sync.RWMutex + buf bytes.Buffer +} + +func (s *testSink) Write(p []byte) (n int, err error) { + s.mu.Lock() + defer s.mu.Unlock() + return s.buf.Write(p) +} + +func (s *testSink) Bytes() []byte { + s.mu.RLock() + defer s.mu.RUnlock() + return slices.Clone(s.buf.Bytes()) +} + +func (*testSink) Sync() error { + return nil +} + +func (*testSink) Close() error { + return nil +} + +func registerTestLogSink(tb testing.TB) *testSink { + sink := &testSink{} + sink.url = fmt.Sprintf("test://%s.%p", tb.Name(), sink) + + testSinksMu.Lock() + defer testSinksMu.Unlock() + + testSinks[sink.url] = sink + tb.Cleanup(func() { + testSinksMu.Lock() + defer testSinksMu.Unlock() + delete(testSinks, sink.url) + }) + return sink +} + +func init() { + if err := zap.RegisterSink("test", func(u *url.URL) (zap.Sink, error) { + testSinksMu.Lock() + defer testSinksMu.Unlock() + sink, ok := testSinks[u.String()] + if !ok { + return nil, fmt.Errorf("no test sink registered for URL %q", u.String()) + } + return sink, nil + }); err != nil { + log.Fatal(err) + } +} diff --git a/internal/e2e/metric_stability_test.go b/internal/e2e/metric_stability_test.go index d598ae011828..aca871e115cf 100644 --- a/internal/e2e/metric_stability_test.go +++ b/internal/e2e/metric_stability_test.go @@ -15,6 +15,7 @@ import ( "testing" "time" + dto "github.com/prometheus/client_model/go" "github.com/prometheus/common/expfmt" "github.com/prometheus/common/model" "github.com/stretchr/testify/assert" @@ -27,6 +28,7 @@ import ( "go.opentelemetry.io/collector/confmap/provider/yamlprovider" "go.opentelemetry.io/collector/exporter" "go.opentelemetry.io/collector/exporter/debugexporter" + "go.opentelemetry.io/collector/exporter/otlphttpexporter" "go.opentelemetry.io/collector/otelcol" "go.opentelemetry.io/collector/pdata/pcommon" "go.opentelemetry.io/collector/pdata/plog" @@ -39,25 +41,8 @@ import ( "go.opentelemetry.io/collector/service/telemetry/otelconftelemetry" ) -func assertMetrics(t *testing.T, metricsAddr string, expectedMetrics map[string]bool) bool { - client := &http.Client{} - resp, err := client.Get(fmt.Sprintf("http://%s/metrics", metricsAddr)) - if err != nil { - return false - } - - if resp.StatusCode != http.StatusOK { - return false - } - - defer resp.Body.Close() - - reader := bufio.NewReader(resp.Body) - parser := expfmt.NewTextParser(model.UTF8Validation) - parsed, err := parser.TextToMetricFamilies(reader) - if err != nil { - return false - } +func assertMetrics(t *testing.T, metricsPort string, expectedMetrics map[string]bool) bool { + parsed := readMetrics(t, metricsPort) for metricName, metricFamily := range parsed { if _, ok := expectedMetrics[metricName]; ok { @@ -136,12 +121,11 @@ func TestMetricStability(t *testing.T) { configFile: "metric_stability_test_readers.yaml", expectedMetrics: map[string]bool{ // Process metrics - "otelcol_process_uptime_seconds_total": false, - "otelcol_process_cpu_seconds_total": false, - "otelcol_process_memory_rss_bytes": false, - "otelcol_process_runtime_heap_alloc_bytes": false, - "otelcol_process_runtime_total_alloc_bytes_total": false, - "otelcol_process_runtime_total_sys_memory_bytes": false, + "otelcol_process_uptime_seconds_total": false, + "otelcol_process_cpu_seconds_total": false, + "otelcol_process_memory_rss_bytes": false, + "otelcol_process_runtime_heap_alloc_bytes": false, + "otelcol_process_runtime_total_sys_memory_bytes": false, // Batch processor metrics "otelcol_processor_batch_batch_send_size": false, @@ -204,8 +188,12 @@ func testMetricStability(t *testing.T, configFile string, expectedMetrics map[st return otelcol.Factories{ Receivers: map[component.Type]receiver.Factory{otlpreceiver.NewFactory().Type(): otlpreceiver.NewFactory()}, Processors: map[component.Type]processor.Factory{batchprocessor.NewFactory().Type(): batchprocessor.NewFactory()}, - Exporters: map[component.Type]exporter.Factory{debugexporter.NewFactory().Type(): debugexporter.NewFactory()}, - Telemetry: otelconftelemetry.NewFactory(), + Exporters: map[component.Type]exporter.Factory{ + debugexporter.NewFactory().Type(): debugexporter.NewFactory(), + // otlphttpexporter is needed because the test config files use otlphttp/fail exporter + otlphttpexporter.NewFactory().Type(): otlphttpexporter.NewFactory(), + }, + Telemetry: otelconftelemetry.NewFactory(), }, nil }, ConfigProviderSettings: otelcol.ConfigProviderSettings{ @@ -230,22 +218,14 @@ func testMetricStability(t *testing.T, configFile string, expectedMetrics map[st t.Logf("Collector stopped with error: %v", err) } }() - - require.Eventually(t, func() bool { - resp, err := http.Get(fmt.Sprintf("http://localhost:%s/metrics", metricsPort)) - if err != nil { - return false - } - resp.Body.Close() - return resp.StatusCode == http.StatusOK - }, 5*time.Second, 100*time.Millisecond, "collector failed to start") + waitMetricsReady(t, metricsPort) for range 5 { sendTestData(t, otelPort) } require.Eventually(t, func() bool { - return assertMetrics(t, "localhost:"+metricsPort, expectedMetrics) + return assertMetrics(t, metricsPort, expectedMetrics) }, 10*time.Second, 200*time.Millisecond, "failed to verify metrics") } @@ -275,7 +255,7 @@ func sendTestMetrics(otelPort string) error { return fmt.Errorf("failed to marshal metrics: %w", err) } - req, err := http.NewRequest(http.MethodPost, fmt.Sprintf("http://localhost:%s/v1/metrics", otelPort), bytes.NewReader(metricsBytes)) + req, err := http.NewRequest(http.MethodPost, fmt.Sprintf("http://127.0.0.1:%s/v1/metrics", otelPort), bytes.NewReader(metricsBytes)) if err != nil { return fmt.Errorf("failed to create metrics request: %w", err) } @@ -310,7 +290,7 @@ func sendTestTraces(otelPort string) error { return fmt.Errorf("failed to marshal traces: %w", err) } - req, err := http.NewRequest(http.MethodPost, fmt.Sprintf("http://localhost:%s/v1/traces", otelPort), bytes.NewReader(tracesBytes)) + req, err := http.NewRequest(http.MethodPost, fmt.Sprintf("http://127.0.0.1:%s/v1/traces", otelPort), bytes.NewReader(tracesBytes)) if err != nil { return fmt.Errorf("failed to create traces request: %w", err) } @@ -343,7 +323,7 @@ func sendTestLogs(otelPort string) error { return fmt.Errorf("failed to marshal logs: %w", err) } - req, err := http.NewRequest(http.MethodPost, fmt.Sprintf("http://localhost:%s/v1/logs", otelPort), bytes.NewReader(logsBytes)) + req, err := http.NewRequest(http.MethodPost, fmt.Sprintf("http://127.0.0.1:%s/v1/logs", otelPort), bytes.NewReader(logsBytes)) if err != nil { return fmt.Errorf("failed to create logs request: %w", err) } @@ -367,3 +347,22 @@ func getFreePort(t *testing.T) string { defer l.Close() return strconv.Itoa(l.Addr().(*net.TCPAddr).Port) } + +func waitMetricsReady(t *testing.T, metricsPort string) { + require.EventuallyWithT(t, func(t *assert.CollectT) { + _ = readMetrics(t, metricsPort) + }, 10*time.Second, 100*time.Millisecond, "collector failed to start") +} + +func readMetrics(t require.TestingT, metricsPort string) map[string]*dto.MetricFamily { + resp, err := http.Get(fmt.Sprintf("http://127.0.0.1:%s/metrics", metricsPort)) + require.NoError(t, err) + defer resp.Body.Close() + require.Equal(t, http.StatusOK, resp.StatusCode) + + reader := bufio.NewReader(resp.Body) + parser := expfmt.NewTextParser(model.UTF8Validation) + parsed, err := parser.TextToMetricFamilies(reader) + require.NoError(t, err) + return parsed +} diff --git a/internal/e2e/otlphttp_test.go b/internal/e2e/otlphttp_test.go index 0f7222e7b69c..f5f7b46485b6 100644 --- a/internal/e2e/otlphttp_test.go +++ b/internal/e2e/otlphttp_test.go @@ -29,9 +29,11 @@ import ( "go.opentelemetry.io/collector/component" "go.opentelemetry.io/collector/component/componenttest" "go.opentelemetry.io/collector/config/confighttp" + "go.opentelemetry.io/collector/config/configoptional" "go.opentelemetry.io/collector/consumer" "go.opentelemetry.io/collector/consumer/consumertest" "go.opentelemetry.io/collector/exporter" + "go.opentelemetry.io/collector/exporter/exporterhelper" "go.opentelemetry.io/collector/exporter/exportertest" "go.opentelemetry.io/collector/exporter/otlphttpexporter" "go.opentelemetry.io/collector/internal/testutil" @@ -65,7 +67,7 @@ func TestTraceNoBackend(t *testing.T) { assert.Error(t, exp.ConsumeTraces(context.Background(), td)) } -func TestTraceInvalidUrl(t *testing.T) { +func TestTraceInvalidURL(t *testing.T) { exp := startTraces(t, "http:/\\//this_is_an/*/invalid_url", "") td := testdata.GenerateTraces(1) require.Error(t, exp.ConsumeTraces(context.Background(), td)) @@ -389,7 +391,7 @@ func startLogs(t *testing.T, baseURL, overrideURL string) exporter.Logs { func createConfig(baseURL string, defaultCfg component.Config) *otlphttpexporter.Config { cfg := defaultCfg.(*otlphttpexporter.Config) cfg.ClientConfig.Endpoint = baseURL - cfg.QueueConfig.Enabled = false + cfg.QueueConfig = configoptional.None[exporterhelper.QueueBatchConfig]() cfg.RetryConfig.Enabled = false return cfg } @@ -420,7 +422,7 @@ func startLogsReceiver(t *testing.T, addr string, next consumer.Logs) { func createReceiverConfig(addr string, defaultCfg component.Config) *otlpreceiver.Config { cfg := defaultCfg.(*otlpreceiver.Config) - cfg.HTTP.GetOrInsertDefault().ServerConfig.Endpoint = addr + cfg.HTTP.GetOrInsertDefault().ServerConfig.NetAddr.Endpoint = addr return cfg } diff --git a/internal/e2e/testdata/exporter_failure_attributes_test.yaml b/internal/e2e/testdata/exporter_failure_attributes_test.yaml new file mode 100644 index 000000000000..68b1f79d3f6b --- /dev/null +++ b/internal/e2e/testdata/exporter_failure_attributes_test.yaml @@ -0,0 +1,35 @@ +receivers: + otlp: + protocols: + http: + endpoint: localhost:${env:OTEL_PORT} + +exporters: + otlp_http/test: + endpoint: ${env:EXPORTER_ENDPOINT} + timeout: 100ms + retry_on_failure: + enabled: true + initial_interval: 10ms + max_interval: 50ms + max_elapsed_time: 200ms + sending_queue: + enabled: false + +service: + telemetry: + logs: + level: info + metrics: + level: detailed + readers: + - pull: + exporter: + prometheus: + host: localhost + port: ${env:METRICS_PORT} + + pipelines: + metrics: + receivers: [otlp] + exporters: [otlp_http/test] diff --git a/internal/e2e/testdata/metric_stability_test_no_readers.yaml b/internal/e2e/testdata/metric_stability_test_no_readers.yaml index 381c89a08036..b6e186cf8803 100644 --- a/internal/e2e/testdata/metric_stability_test_no_readers.yaml +++ b/internal/e2e/testdata/metric_stability_test_no_readers.yaml @@ -2,7 +2,7 @@ receivers: otlp: protocols: http: - endpoint: localhost:${env:OTEL_PORT} + endpoint: 127.0.0.1:${env:OTEL_PORT} processors: batch: @@ -12,6 +12,13 @@ processors: exporters: debug: verbosity: detailed + otlp_http/fail: + endpoint: http://127.0.0.1:65535 + timeout: 100ms + retry_on_failure: + enabled: false + sending_queue: + enabled: false service: telemetry: @@ -25,11 +32,20 @@ service: receivers: [otlp] processors: [batch] exporters: [debug] + traces/fail: + receivers: [otlp] + exporters: [otlp_http/fail] metrics: receivers: [otlp] processors: [batch] exporters: [debug] + metrics/fail: + receivers: [otlp] + exporters: [otlp_http/fail] logs: receivers: [otlp] processors: [batch] - exporters: [debug] \ No newline at end of file + exporters: [debug] + logs/fail: + receivers: [otlp] + exporters: [otlp_http/fail] diff --git a/internal/e2e/testdata/metric_stability_test_readers.yaml b/internal/e2e/testdata/metric_stability_test_readers.yaml index 85fa65562ba5..1e018e4a6f1c 100644 --- a/internal/e2e/testdata/metric_stability_test_readers.yaml +++ b/internal/e2e/testdata/metric_stability_test_readers.yaml @@ -2,7 +2,7 @@ receivers: otlp: protocols: http: - endpoint: localhost:${env:OTEL_PORT} + endpoint: 127.0.0.1:${env:OTEL_PORT} processors: batch: @@ -12,6 +12,13 @@ processors: exporters: debug: verbosity: detailed + otlp_http/fail: + endpoint: http://127.0.0.1:65535 + timeout: 100ms + retry_on_failure: + enabled: false + sending_queue: + enabled: false service: telemetry: @@ -23,7 +30,7 @@ service: - pull: exporter: prometheus: - host: localhost + host: 127.0.0.1 port: ${env:METRICS_PORT} pipelines: @@ -31,11 +38,20 @@ service: receivers: [otlp] processors: [batch] exporters: [debug] + traces/fail: + receivers: [otlp] + exporters: [otlp_http/fail] metrics: receivers: [otlp] processors: [batch] exporters: [debug] + metrics/fail: + receivers: [otlp] + exporters: [otlp_http/fail] logs: receivers: [otlp] processors: [batch] - exporters: [debug] \ No newline at end of file + exporters: [debug] + logs/fail: + receivers: [otlp] + exporters: [otlp_http/fail] diff --git a/internal/fanoutconsumer/go.mod b/internal/fanoutconsumer/go.mod index 4a76fd32d3ee..9210dd755270 100644 --- a/internal/fanoutconsumer/go.mod +++ b/internal/fanoutconsumer/go.mod @@ -1,27 +1,27 @@ module go.opentelemetry.io/collector/internal/fanoutconsumer -go 1.24.0 +go 1.25.0 require ( github.com/stretchr/testify v1.11.1 - go.opentelemetry.io/collector/consumer v1.46.0 - go.opentelemetry.io/collector/consumer/consumertest v0.140.0 - go.opentelemetry.io/collector/consumer/xconsumer v0.140.0 - go.opentelemetry.io/collector/pdata v1.46.0 - go.opentelemetry.io/collector/pdata/pprofile v0.140.0 - go.opentelemetry.io/collector/pdata/testdata v0.140.0 + go.opentelemetry.io/collector/consumer v1.54.0 + go.opentelemetry.io/collector/consumer/consumertest v0.148.0 + go.opentelemetry.io/collector/consumer/xconsumer v0.148.0 + go.opentelemetry.io/collector/pdata v1.54.0 + go.opentelemetry.io/collector/pdata/pprofile v0.148.0 + go.opentelemetry.io/collector/pdata/testdata v0.148.0 go.uber.org/goleak v1.3.0 go.uber.org/multierr v1.11.0 ) require ( github.com/davecgh/go-spew v1.1.1 // indirect - github.com/hashicorp/go-version v1.7.0 // indirect + github.com/hashicorp/go-version v1.8.0 // indirect github.com/json-iterator/go v1.1.12 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee // indirect github.com/pmezard/go-difflib v1.0.0 // indirect - go.opentelemetry.io/collector/featuregate v1.46.0 // indirect + go.opentelemetry.io/collector/featuregate v1.54.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/internal/fanoutconsumer/go.sum b/internal/fanoutconsumer/go.sum index 903bf673575c..a38defe5d44d 100644 --- a/internal/fanoutconsumer/go.sum +++ b/internal/fanoutconsumer/go.sum @@ -1,9 +1,11 @@ +github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= +github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= -github.com/hashicorp/go-version v1.7.0 h1:5tqGy27NaOTB8yJKUZELlFAS/LTKJkrmONwQKeRZfjY= -github.com/hashicorp/go-version v1.7.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= +github.com/hashicorp/go-version v1.8.0 h1:KAkNb1HAiZd1ukkxDFGmokVZe1Xy9HG6NUp+bPle2i4= +github.com/hashicorp/go-version v1.8.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= @@ -24,18 +26,20 @@ github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+ github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U= github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= -go.opentelemetry.io/proto/slim/otlp v1.9.0 h1:fPVMv8tP3TrsqlkH1HWYUpbCY9cAIemx184VGkS6vlE= -go.opentelemetry.io/proto/slim/otlp v1.9.0/go.mod h1:xXdeJJ90Gqyll+orzUkY4bOd2HECo5JofeoLpymVqdI= -go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.2.0 h1:o13nadWDNkH/quoDomDUClnQBpdQQ2Qqv0lQBjIXjE8= -go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.2.0/go.mod h1:Gyb6Xe7FTi/6xBHwMmngGoHqL0w29Y4eW8TGFzpefGA= -go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.2.0 h1:EiUYvtwu6PMrMHVjcPfnsG3v+ajPkbUeH+IL93+QYyk= -go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.2.0/go.mod h1:mUUHKFiN2SST3AhJ8XhJxEoeVW12oqfXog0Bo8W3Ec4= +go.opentelemetry.io/otel v1.40.0 h1:oA5YeOcpRTXq6NN7frwmwFR0Cn3RhTVZvXsP4duvCms= +go.opentelemetry.io/otel v1.40.0/go.mod h1:IMb+uXZUKkMXdPddhwAHm6UfOwJyh4ct1ybIlV14J0g= +go.opentelemetry.io/proto/slim/otlp v1.10.0 h1:iR97Vs/ZDR+y9TfuP9b1XBtdPWeC+OMslIBmhcLU7jM= +go.opentelemetry.io/proto/slim/otlp v1.10.0/go.mod h1:lV9250stpjYLPNA5viFabIgP2QlUGRT1GdTgAf8SIUk= +go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.3.0 h1:RUF5rO0hAlgiJt1fzQVzcVs3vZVNHIcMLgOgG4rWNcQ= +go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.3.0/go.mod h1:I89cynRj8y+383o7tEQVg2SVA6SRgDVIouWPUVXjx0U= +go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.3.0 h1:CQvJSldHRUN6Z8jsUeYv8J0lXRvygALXIzsmAeCcZE0= +go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.3.0/go.mod h1:xSQ+mEfJe/GjK1LXEyVOoSI1N9JV9ZI923X5kup43W4= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= -google.golang.org/protobuf v1.36.10 h1:AYd7cD/uASjIL6Q9LiTjz8JLcrh/88q5UObnmY3aOOE= -google.golang.org/protobuf v1.36.10/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= +google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE= +google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= diff --git a/internal/memorylimiter/go.mod b/internal/memorylimiter/go.mod index 9a96e20f2c55..56e40bd6da30 100644 --- a/internal/memorylimiter/go.mod +++ b/internal/memorylimiter/go.mod @@ -1,12 +1,12 @@ module go.opentelemetry.io/collector/internal/memorylimiter -go 1.24.0 +go 1.25.0 require ( - github.com/shirou/gopsutil/v4 v4.25.10 + github.com/shirou/gopsutil/v4 v4.26.2 github.com/stretchr/testify v1.11.1 - go.opentelemetry.io/collector/component v1.46.0 - go.opentelemetry.io/collector/confmap v1.46.0 + go.opentelemetry.io/collector/component v1.54.0 + go.opentelemetry.io/collector/confmap v1.54.0 go.uber.org/goleak v1.3.0 go.uber.org/zap v1.27.1 ) @@ -14,33 +14,33 @@ require ( require ( github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/davecgh/go-spew v1.1.1 // indirect - github.com/ebitengine/purego v0.9.0 // indirect + github.com/ebitengine/purego v0.10.0 // indirect github.com/go-ole/go-ole v1.2.6 // indirect - github.com/go-viper/mapstructure/v2 v2.4.0 // indirect + github.com/go-viper/mapstructure/v2 v2.5.0 // indirect github.com/gobwas/glob v0.2.3 // indirect - github.com/hashicorp/go-version v1.7.0 // indirect + github.com/hashicorp/go-version v1.8.0 // indirect github.com/json-iterator/go v1.1.12 // indirect github.com/knadh/koanf/maps v0.1.2 // indirect github.com/knadh/koanf/providers/confmap v1.0.0 // indirect - github.com/knadh/koanf/v2 v2.3.0 // indirect - github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 // indirect + github.com/knadh/koanf/v2 v2.3.3 // indirect + github.com/lufia/plan9stats v0.0.0-20251013123823-9fd1530e3ec3 // indirect github.com/mitchellh/copystructure v1.2.0 // indirect github.com/mitchellh/reflectwalk v1.0.2 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee // indirect github.com/pmezard/go-difflib v1.0.0 // indirect github.com/power-devops/perfstat v0.0.0-20240221224432-82ca36839d55 // indirect - github.com/tklauser/go-sysconf v0.3.15 // indirect - github.com/tklauser/numcpus v0.10.0 // indirect + github.com/tklauser/go-sysconf v0.3.16 // indirect + github.com/tklauser/numcpus v0.11.0 // indirect github.com/yusufpapurcu/wmi v1.2.4 // indirect - go.opentelemetry.io/collector/featuregate v1.46.0 // indirect + go.opentelemetry.io/collector/featuregate v1.54.0 // indirect go.opentelemetry.io/collector/pdata v1.46.0 // indirect go.opentelemetry.io/otel v1.40.0 // indirect go.opentelemetry.io/otel/metric v1.40.0 // indirect go.opentelemetry.io/otel/trace v1.40.0 // indirect go.uber.org/multierr v1.11.0 // indirect go.yaml.in/yaml/v3 v3.0.4 // indirect - golang.org/x/sys v0.40.0 // indirect + golang.org/x/sys v0.41.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/internal/memorylimiter/go.sum b/internal/memorylimiter/go.sum index c2ac48589e44..7123b88bbf99 100644 --- a/internal/memorylimiter/go.sum +++ b/internal/memorylimiter/go.sum @@ -3,38 +3,37 @@ github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XL github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/ebitengine/purego v0.9.0 h1:mh0zpKBIXDceC63hpvPuGLiJ8ZAa3DfrFTudmfi8A4k= -github.com/ebitengine/purego v0.9.0/go.mod h1:iIjxzd6CiRiOG0UyXP+V1+jWqUXVjPKLAI0mRfJZTmQ= +github.com/ebitengine/purego v0.10.0 h1:QIw4xfpWT6GWTzaW5XEKy3HXoqrJGx1ijYHzTF0/ISU= +github.com/ebitengine/purego v0.10.0/go.mod h1:iIjxzd6CiRiOG0UyXP+V1+jWqUXVjPKLAI0mRfJZTmQ= github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI= github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY= github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0= -github.com/go-viper/mapstructure/v2 v2.4.0 h1:EBsztssimR/CONLSZZ04E8qAkxNYq4Qp9LvH92wZUgs= -github.com/go-viper/mapstructure/v2 v2.4.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM= +github.com/go-viper/mapstructure/v2 v2.5.0 h1:vM5IJoUAy3d7zRSVtIwQgBj7BiWtMPfmPEgAXnvj1Ro= +github.com/go-viper/mapstructure/v2 v2.5.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM= github.com/gobwas/glob v0.2.3 h1:A4xDbljILXROh+kObIiy5kIaPYD8e96x1tgBhUI5J+Y= github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8= -github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= -github.com/hashicorp/go-version v1.7.0 h1:5tqGy27NaOTB8yJKUZELlFAS/LTKJkrmONwQKeRZfjY= -github.com/hashicorp/go-version v1.7.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= +github.com/hashicorp/go-version v1.8.0 h1:KAkNb1HAiZd1ukkxDFGmokVZe1Xy9HG6NUp+bPle2i4= +github.com/hashicorp/go-version v1.8.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= github.com/knadh/koanf/maps v0.1.2 h1:RBfmAW5CnZT+PJ1CVc1QSJKf4Xu9kxfQgYVQSu8hpbo= github.com/knadh/koanf/maps v0.1.2/go.mod h1:npD/QZY3V6ghQDdcQzl1W4ICNVTkohC8E73eI2xW4yI= github.com/knadh/koanf/providers/confmap v1.0.0 h1:mHKLJTE7iXEys6deO5p6olAiZdG5zwp8Aebir+/EaRE= github.com/knadh/koanf/providers/confmap v1.0.0/go.mod h1:txHYHiI2hAtF0/0sCmcuol4IDcuQbKTybiB1nOcUo1A= -github.com/knadh/koanf/v2 v2.3.0 h1:Qg076dDRFHvqnKG97ZEsi9TAg2/nFTa9hCdcSa1lvlM= -github.com/knadh/koanf/v2 v2.3.0/go.mod h1:gRb40VRAbd4iJMYYD5IxZ6hfuopFcXBpc9bbQpZwo28= +github.com/knadh/koanf/v2 v2.3.3 h1:jLJC8XCRfLC7n4F+ZKKdBsbq1bfXTpuFhf4L7t94D94= +github.com/knadh/koanf/v2 v2.3.3/go.mod h1:gRb40VRAbd4iJMYYD5IxZ6hfuopFcXBpc9bbQpZwo28= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= -github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 h1:6E+4a0GO5zZEnZ81pIr0yLvtUWk2if982qA3F3QD6H4= -github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0/go.mod h1:zJYVVT2jmtg6P3p1VtQj7WsuWi/y4VnjVBn7F8KPB3I= +github.com/lufia/plan9stats v0.0.0-20251013123823-9fd1530e3ec3 h1:PwQumkgq4/acIiZhtifTV5OUqqiP82UAl0h87xj/l9k= +github.com/lufia/plan9stats v0.0.0-20251013123823-9fd1530e3ec3/go.mod h1:autxFIvghDt3jPTLoqZ9OZ7s9qTGNAWmYCjVFWPX/zg= github.com/mitchellh/copystructure v1.2.0 h1:vpKXTN4ewci03Vljg/q9QvCGUDttBOGBIa15WveJJGw= github.com/mitchellh/copystructure v1.2.0/go.mod h1:qLl+cE2AmVv+CoeAwDPye/v+N2HKCj9FbZEVFJRxO9s= github.com/mitchellh/reflectwalk v1.0.2 h1:G2LzWKi524PWgd3mLHV8Y5k7s6XUvT0Gef6zxSIeXaQ= @@ -51,16 +50,16 @@ github.com/power-devops/perfstat v0.0.0-20240221224432-82ca36839d55 h1:o4JXh1EVt github.com/power-devops/perfstat v0.0.0-20240221224432-82ca36839d55/go.mod h1:OmDBASR4679mdNQnz2pUhc2G8CO2JrUAVFDRBDP/hJE= github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ= github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc= -github.com/shirou/gopsutil/v4 v4.25.10 h1:at8lk/5T1OgtuCp+AwrDofFRjnvosn0nkN2OLQ6g8tA= -github.com/shirou/gopsutil/v4 v4.25.10/go.mod h1:+kSwyC8DRUD9XXEHCAFjK+0nuArFJM0lva+StQAcskM= +github.com/shirou/gopsutil/v4 v4.26.2 h1:X8i6sicvUFih4BmYIGT1m2wwgw2VG9YgrDTi7cIRGUI= +github.com/shirou/gopsutil/v4 v4.26.2/go.mod h1:LZ6ewCSkBqUpvSOf+LsTGnRinC6iaNUNMGBtDkJBaLQ= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U= github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= -github.com/tklauser/go-sysconf v0.3.15 h1:VE89k0criAymJ/Os65CSn1IXaol+1wrsFHEB8Ol49K4= -github.com/tklauser/go-sysconf v0.3.15/go.mod h1:Dmjwr6tYFIseJw7a3dRLJfsHAMXZ3nEnL/aZY+0IuI4= -github.com/tklauser/numcpus v0.10.0 h1:18njr6LDBk1zuna922MgdjQuJFjrdppsZG60sHGfjso= -github.com/tklauser/numcpus v0.10.0/go.mod h1:BiTKazU708GQTYF4mB+cmlpT2Is1gLk7XVuEeem8LsQ= +github.com/tklauser/go-sysconf v0.3.16 h1:frioLaCQSsF5Cy1jgRBrzr6t502KIIwQ0MArYICU0nA= +github.com/tklauser/go-sysconf v0.3.16/go.mod h1:/qNL9xxDhc7tx3HSRsLWNnuzbVfh3e7gh/BmM179nYI= +github.com/tklauser/numcpus v0.11.0 h1:nSTwhKH5e1dMNsCdVBukSZrURJRoHbSEQjdEbY+9RXw= +github.com/tklauser/numcpus v0.11.0/go.mod h1:z+LwcLq54uWZTX0u/bGobaV34u6V7KNlTZejzM6/3MQ= github.com/yusufpapurcu/wmi v1.2.4 h1:zFUKzehAFReQwLys1b/iSMl+JQGSCSjtVqQn9bBrPo0= github.com/yusufpapurcu/wmi v1.2.4/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0= go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64= @@ -71,12 +70,12 @@ go.opentelemetry.io/otel/metric v1.40.0 h1:rcZe317KPftE2rstWIBitCdVp89A2HqjkxR3c go.opentelemetry.io/otel/metric v1.40.0/go.mod h1:ib/crwQH7N3r5kfiBZQbwrTge743UDc7DTFVZrrXnqc= go.opentelemetry.io/otel/trace v1.40.0 h1:WA4etStDttCSYuhwvEa8OP8I5EWu24lkOzp+ZYblVjw= go.opentelemetry.io/otel/trace v1.40.0/go.mod h1:zeAhriXecNGP/s2SEG3+Y8X9ujcJOTqQ5RgdEJcawiA= -go.opentelemetry.io/proto/slim/otlp v1.9.0 h1:fPVMv8tP3TrsqlkH1HWYUpbCY9cAIemx184VGkS6vlE= -go.opentelemetry.io/proto/slim/otlp v1.9.0/go.mod h1:xXdeJJ90Gqyll+orzUkY4bOd2HECo5JofeoLpymVqdI= -go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.2.0 h1:o13nadWDNkH/quoDomDUClnQBpdQQ2Qqv0lQBjIXjE8= -go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.2.0/go.mod h1:Gyb6Xe7FTi/6xBHwMmngGoHqL0w29Y4eW8TGFzpefGA= -go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.2.0 h1:EiUYvtwu6PMrMHVjcPfnsG3v+ajPkbUeH+IL93+QYyk= -go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.2.0/go.mod h1:mUUHKFiN2SST3AhJ8XhJxEoeVW12oqfXog0Bo8W3Ec4= +go.opentelemetry.io/proto/slim/otlp v1.10.0 h1:iR97Vs/ZDR+y9TfuP9b1XBtdPWeC+OMslIBmhcLU7jM= +go.opentelemetry.io/proto/slim/otlp v1.10.0/go.mod h1:lV9250stpjYLPNA5viFabIgP2QlUGRT1GdTgAf8SIUk= +go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.3.0 h1:RUF5rO0hAlgiJt1fzQVzcVs3vZVNHIcMLgOgG4rWNcQ= +go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.3.0/go.mod h1:I89cynRj8y+383o7tEQVg2SVA6SRgDVIouWPUVXjx0U= +go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.3.0 h1:CQvJSldHRUN6Z8jsUeYv8J0lXRvygALXIzsmAeCcZE0= +go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.3.0/go.mod h1:xSQ+mEfJe/GjK1LXEyVOoSI1N9JV9ZI923X5kup43W4= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= @@ -87,11 +86,10 @@ go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc= go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg= golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201204225414-ed752295db88/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.40.0 h1:DBZZqJ2Rkml6QMQsZywtnjnnGvHza6BTfYFWY9kjEWQ= -golang.org/x/sys v0.40.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= -golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -google.golang.org/protobuf v1.36.10 h1:AYd7cD/uASjIL6Q9LiTjz8JLcrh/88q5UObnmY3aOOE= -google.golang.org/protobuf v1.36.10/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= +golang.org/x/sys v0.41.0 h1:Ivj+2Cp/ylzLiEU89QhWblYnOE9zerudt9Ftecq2C6k= +golang.org/x/sys v0.41.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= +google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE= +google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= diff --git a/internal/memorylimiter/iruntime/total_memory_linux.go b/internal/memorylimiter/iruntime/total_memory_linux.go index 639e239a15b7..2380f5e16e0f 100644 --- a/internal/memorylimiter/iruntime/total_memory_linux.go +++ b/internal/memorylimiter/iruntime/total_memory_linux.go @@ -49,6 +49,5 @@ func TotalMemory() (uint64, error) { return totalMem, nil } - //nolint:gosec return uint64(memoryQuota), nil } diff --git a/internal/memorylimiter/memorylimiter.go b/internal/memorylimiter/memorylimiter.go index 787f4708c235..f10e3360fbad 100644 --- a/internal/memorylimiter/memorylimiter.go +++ b/internal/memorylimiter/memorylimiter.go @@ -94,10 +94,7 @@ func (ml *MemoryLimiter) Start(_ context.Context, _ component.Host) error { ml.refCounter++ if ml.refCounter == 1 { ml.closed = make(chan struct{}) - ml.waitGroup.Add(1) - go func() { - defer ml.waitGroup.Done() - + ml.waitGroup.Go(func() { for { select { case <-ml.ticker.C: @@ -106,7 +103,7 @@ func (ml *MemoryLimiter) Start(_ context.Context, _ component.Host) error { } ml.CheckMemLimits() } - }() + }) } return nil } diff --git a/internal/sharedcomponent/go.mod b/internal/sharedcomponent/go.mod index 56ba749e0e1b..ce2e7874ce83 100644 --- a/internal/sharedcomponent/go.mod +++ b/internal/sharedcomponent/go.mod @@ -1,12 +1,12 @@ module go.opentelemetry.io/collector/internal/sharedcomponent -go 1.24.0 +go 1.25.0 require ( github.com/stretchr/testify v1.11.1 - go.opentelemetry.io/collector/component v1.46.0 - go.opentelemetry.io/collector/component/componentstatus v0.140.0 - go.opentelemetry.io/collector/component/componenttest v0.140.0 + go.opentelemetry.io/collector/component v1.54.0 + go.opentelemetry.io/collector/component/componentstatus v0.148.0 + go.opentelemetry.io/collector/component/componenttest v0.148.0 go.uber.org/goleak v1.3.0 ) @@ -16,15 +16,15 @@ require ( github.com/go-logr/logr v1.4.3 // indirect github.com/go-logr/stdr v1.2.2 // indirect github.com/google/uuid v1.6.0 // indirect - github.com/hashicorp/go-version v1.7.0 // indirect + github.com/hashicorp/go-version v1.8.0 // indirect github.com/json-iterator/go v1.1.12 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee // indirect github.com/pmezard/go-difflib v1.0.0 // indirect go.opentelemetry.io/auto/sdk v1.2.1 // indirect - go.opentelemetry.io/collector/featuregate v1.46.0 // indirect - go.opentelemetry.io/collector/pdata v1.46.0 // indirect - go.opentelemetry.io/collector/pipeline v1.46.0 // indirect + go.opentelemetry.io/collector/featuregate v1.54.0 // indirect + go.opentelemetry.io/collector/pdata v1.54.0 // indirect + go.opentelemetry.io/collector/pipeline v1.54.0 // indirect go.opentelemetry.io/otel v1.40.0 // indirect go.opentelemetry.io/otel/metric v1.40.0 // indirect go.opentelemetry.io/otel/sdk v1.40.0 // indirect @@ -32,7 +32,7 @@ require ( go.opentelemetry.io/otel/trace v1.40.0 // indirect go.uber.org/multierr v1.11.0 // indirect go.uber.org/zap v1.27.1 // indirect - golang.org/x/sys v0.40.0 // indirect + golang.org/x/sys v0.41.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/internal/sharedcomponent/go.sum b/internal/sharedcomponent/go.sum index c102571e7869..1e6789104ba9 100644 --- a/internal/sharedcomponent/go.sum +++ b/internal/sharedcomponent/go.sum @@ -13,8 +13,8 @@ github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/hashicorp/go-version v1.7.0 h1:5tqGy27NaOTB8yJKUZELlFAS/LTKJkrmONwQKeRZfjY= -github.com/hashicorp/go-version v1.7.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= +github.com/hashicorp/go-version v1.8.0 h1:KAkNb1HAiZd1ukkxDFGmokVZe1Xy9HG6NUp+bPle2i4= +github.com/hashicorp/go-version v1.8.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= @@ -47,22 +47,22 @@ go.opentelemetry.io/otel/sdk/metric v1.40.0 h1:mtmdVqgQkeRxHgRv4qhyJduP3fYJRMX4A go.opentelemetry.io/otel/sdk/metric v1.40.0/go.mod h1:4Z2bGMf0KSK3uRjlczMOeMhKU2rhUqdWNoKcYrtcBPg= go.opentelemetry.io/otel/trace v1.40.0 h1:WA4etStDttCSYuhwvEa8OP8I5EWu24lkOzp+ZYblVjw= go.opentelemetry.io/otel/trace v1.40.0/go.mod h1:zeAhriXecNGP/s2SEG3+Y8X9ujcJOTqQ5RgdEJcawiA= -go.opentelemetry.io/proto/slim/otlp v1.9.0 h1:fPVMv8tP3TrsqlkH1HWYUpbCY9cAIemx184VGkS6vlE= -go.opentelemetry.io/proto/slim/otlp v1.9.0/go.mod h1:xXdeJJ90Gqyll+orzUkY4bOd2HECo5JofeoLpymVqdI= -go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.2.0 h1:o13nadWDNkH/quoDomDUClnQBpdQQ2Qqv0lQBjIXjE8= -go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.2.0/go.mod h1:Gyb6Xe7FTi/6xBHwMmngGoHqL0w29Y4eW8TGFzpefGA= -go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.2.0 h1:EiUYvtwu6PMrMHVjcPfnsG3v+ajPkbUeH+IL93+QYyk= -go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.2.0/go.mod h1:mUUHKFiN2SST3AhJ8XhJxEoeVW12oqfXog0Bo8W3Ec4= +go.opentelemetry.io/proto/slim/otlp v1.10.0 h1:iR97Vs/ZDR+y9TfuP9b1XBtdPWeC+OMslIBmhcLU7jM= +go.opentelemetry.io/proto/slim/otlp v1.10.0/go.mod h1:lV9250stpjYLPNA5viFabIgP2QlUGRT1GdTgAf8SIUk= +go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.3.0 h1:RUF5rO0hAlgiJt1fzQVzcVs3vZVNHIcMLgOgG4rWNcQ= +go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.3.0/go.mod h1:I89cynRj8y+383o7tEQVg2SVA6SRgDVIouWPUVXjx0U= +go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.3.0 h1:CQvJSldHRUN6Z8jsUeYv8J0lXRvygALXIzsmAeCcZE0= +go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.3.0/go.mod h1:xSQ+mEfJe/GjK1LXEyVOoSI1N9JV9ZI923X5kup43W4= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= go.uber.org/zap v1.27.1 h1:08RqriUEv8+ArZRYSTXy1LeBScaMpVSTBhCeaZYfMYc= go.uber.org/zap v1.27.1/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= -golang.org/x/sys v0.40.0 h1:DBZZqJ2Rkml6QMQsZywtnjnnGvHza6BTfYFWY9kjEWQ= -golang.org/x/sys v0.40.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= -google.golang.org/protobuf v1.36.10 h1:AYd7cD/uASjIL6Q9LiTjz8JLcrh/88q5UObnmY3aOOE= -google.golang.org/protobuf v1.36.10/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= +golang.org/x/sys v0.41.0 h1:Ivj+2Cp/ylzLiEU89QhWblYnOE9zerudt9Ftecq2C6k= +golang.org/x/sys v0.41.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= +google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE= +google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= diff --git a/internal/telemetry/go.mod b/internal/telemetry/go.mod index 24a9b5f98c5f..27f587cefe1e 100644 --- a/internal/telemetry/go.mod +++ b/internal/telemetry/go.mod @@ -1,11 +1,10 @@ module go.opentelemetry.io/collector/internal/telemetry -go 1.24.0 +go 1.25.0 require ( github.com/stretchr/testify v1.11.1 go.opentelemetry.io/collector/component v1.46.0 - go.opentelemetry.io/collector/featuregate v1.46.0 go.opentelemetry.io/otel v1.40.0 go.opentelemetry.io/otel/metric v1.40.0 go.opentelemetry.io/otel/trace v1.40.0 @@ -15,12 +14,13 @@ require ( require ( github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/davecgh/go-spew v1.1.1 // indirect - github.com/hashicorp/go-version v1.7.0 // indirect + github.com/hashicorp/go-version v1.8.0 // indirect github.com/json-iterator/go v1.1.12 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee // indirect github.com/pmezard/go-difflib v1.0.0 // indirect - go.opentelemetry.io/collector/pdata v1.46.0 // indirect + go.opentelemetry.io/collector/featuregate v1.54.0 // indirect + go.opentelemetry.io/collector/pdata v1.54.0 // indirect go.uber.org/multierr v1.11.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/internal/telemetry/go.sum b/internal/telemetry/go.sum index 37d6edbc3764..46cd6ed8c011 100644 --- a/internal/telemetry/go.sum +++ b/internal/telemetry/go.sum @@ -10,8 +10,8 @@ github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= -github.com/hashicorp/go-version v1.7.0 h1:5tqGy27NaOTB8yJKUZELlFAS/LTKJkrmONwQKeRZfjY= -github.com/hashicorp/go-version v1.7.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= +github.com/hashicorp/go-version v1.8.0 h1:KAkNb1HAiZd1ukkxDFGmokVZe1Xy9HG6NUp+bPle2i4= +github.com/hashicorp/go-version v1.8.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= @@ -40,20 +40,20 @@ go.opentelemetry.io/otel/metric v1.40.0 h1:rcZe317KPftE2rstWIBitCdVp89A2HqjkxR3c go.opentelemetry.io/otel/metric v1.40.0/go.mod h1:ib/crwQH7N3r5kfiBZQbwrTge743UDc7DTFVZrrXnqc= go.opentelemetry.io/otel/trace v1.40.0 h1:WA4etStDttCSYuhwvEa8OP8I5EWu24lkOzp+ZYblVjw= go.opentelemetry.io/otel/trace v1.40.0/go.mod h1:zeAhriXecNGP/s2SEG3+Y8X9ujcJOTqQ5RgdEJcawiA= -go.opentelemetry.io/proto/slim/otlp v1.9.0 h1:fPVMv8tP3TrsqlkH1HWYUpbCY9cAIemx184VGkS6vlE= -go.opentelemetry.io/proto/slim/otlp v1.9.0/go.mod h1:xXdeJJ90Gqyll+orzUkY4bOd2HECo5JofeoLpymVqdI= -go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.2.0 h1:o13nadWDNkH/quoDomDUClnQBpdQQ2Qqv0lQBjIXjE8= -go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.2.0/go.mod h1:Gyb6Xe7FTi/6xBHwMmngGoHqL0w29Y4eW8TGFzpefGA= -go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.2.0 h1:EiUYvtwu6PMrMHVjcPfnsG3v+ajPkbUeH+IL93+QYyk= -go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.2.0/go.mod h1:mUUHKFiN2SST3AhJ8XhJxEoeVW12oqfXog0Bo8W3Ec4= +go.opentelemetry.io/proto/slim/otlp v1.10.0 h1:iR97Vs/ZDR+y9TfuP9b1XBtdPWeC+OMslIBmhcLU7jM= +go.opentelemetry.io/proto/slim/otlp v1.10.0/go.mod h1:lV9250stpjYLPNA5viFabIgP2QlUGRT1GdTgAf8SIUk= +go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.3.0 h1:RUF5rO0hAlgiJt1fzQVzcVs3vZVNHIcMLgOgG4rWNcQ= +go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.3.0/go.mod h1:I89cynRj8y+383o7tEQVg2SVA6SRgDVIouWPUVXjx0U= +go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.3.0 h1:CQvJSldHRUN6Z8jsUeYv8J0lXRvygALXIzsmAeCcZE0= +go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.3.0/go.mod h1:xSQ+mEfJe/GjK1LXEyVOoSI1N9JV9ZI923X5kup43W4= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= go.uber.org/zap v1.27.1 h1:08RqriUEv8+ArZRYSTXy1LeBScaMpVSTBhCeaZYfMYc= go.uber.org/zap v1.27.1/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= -google.golang.org/protobuf v1.36.10 h1:AYd7cD/uASjIL6Q9LiTjz8JLcrh/88q5UObnmY3aOOE= -google.golang.org/protobuf v1.36.10/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= +google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE= +google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= diff --git a/internal/telemetry/telemetry.go b/internal/telemetry/telemetry.go index e792b0b1ae01..9298787a549b 100644 --- a/internal/telemetry/telemetry.go +++ b/internal/telemetry/telemetry.go @@ -10,15 +10,6 @@ import ( "go.uber.org/zap/zapcore" "go.opentelemetry.io/collector/component" - "go.opentelemetry.io/collector/featuregate" -) - -var NewPipelineTelemetryGate = featuregate.GlobalRegistry().MustRegister( - "telemetry.newPipelineTelemetry", - featuregate.StageAlpha, - featuregate.WithRegisterFromVersion("v0.123.0"), - featuregate.WithRegisterReferenceURL("https://github.com/open-telemetry/opentelemetry-collector/blob/main/docs/rfcs/component-universal-telemetry.md"), - featuregate.WithRegisterDescription("Injects component-identifying scope attributes in internal Collector metrics"), ) type injectorCore interface { diff --git a/internal/testutil/benchmarks.go b/internal/testutil/benchmarks.go index 7018e401892e..5e97b6d8971c 100644 --- a/internal/testutil/benchmarks.go +++ b/internal/testutil/benchmarks.go @@ -15,3 +15,12 @@ func SkipMemoryBench(b *testing.B) { b.Skip("Skipping since the 'MEMBENCH' environment variable was not set") } } + +// SkipGCHeavyBench will skip GC-heavy benchmarks on CI. +// These benchmarks tend to be flaky with the current settings since garbage +// collection pauses can take ~50ms which is significant with the current benchmark times. +func SkipGCHeavyBench(b *testing.B) { + if os.Getenv("GCHEAVYBENCH") == "" { + b.Skip("Skipping since the 'GCHEAVYBENCH' environment variable was not set. See https://github.com/open-telemetry/opentelemetry-collector/issues/14257.") + } +} diff --git a/internal/testutil/go.mod b/internal/testutil/go.mod index ed30c788425b..99abd51e9868 100644 --- a/internal/testutil/go.mod +++ b/internal/testutil/go.mod @@ -1,6 +1,6 @@ module go.opentelemetry.io/collector/internal/testutil -go 1.24.0 +go 1.25.0 require ( github.com/stretchr/testify v1.11.1 diff --git a/internal/tools/go.mod b/internal/tools/go.mod index 3855e114d7f2..f91cecf40031 100644 --- a/internal/tools/go.mod +++ b/internal/tools/go.mod @@ -1,10 +1,11 @@ module go.opentelemetry.io/collector/internal/tools -go 1.24.0 +go 1.25.0 tool ( github.com/a8m/envsubst/cmd/envsubst github.com/client9/misspell/cmd/misspell + github.com/dkorunic/betteralign/cmd/betteralign github.com/golangci/golangci-lint/v2/cmd/golangci-lint github.com/google/addlicense github.com/jcchavezs/porto/cmd/porto @@ -18,6 +19,7 @@ tool ( go.opentelemetry.io/build-tools/multimod golang.org/x/exp/cmd/apidiff golang.org/x/tools/cmd/goimports + golang.org/x/tools/go/analysis/passes/modernize/cmd/modernize golang.org/x/vuln/cmd/govulncheck gotest.tools/gotestsum mvdan.cc/gofumpt @@ -39,6 +41,7 @@ require ( github.com/Antonboom/testifylint v1.6.4 // indirect github.com/BurntSushi/toml v1.5.0 // indirect github.com/Djarvur/go-err113 v0.1.1 // indirect + github.com/KimMachineGun/automemlimit v0.7.5 // indirect github.com/Masterminds/semver/v3 v3.4.0 // indirect github.com/Microsoft/go-winio v0.6.2 // indirect github.com/MirrexOne/unqueryvet v1.2.1 // indirect @@ -59,14 +62,14 @@ require ( github.com/bitfield/gotestdox v0.2.2 // indirect github.com/bkielbasa/cyclop v1.2.3 // indirect github.com/blizzy78/varnamelen v0.8.0 // indirect - github.com/bmatcuk/doublestar/v4 v4.9.1 // indirect + github.com/bmatcuk/doublestar/v4 v4.10.0 // indirect github.com/bombsimon/wsl/v4 v4.7.0 // indirect github.com/bombsimon/wsl/v5 v5.3.0 // indirect github.com/breml/bidichk v0.3.3 // indirect github.com/breml/errchkjson v0.4.1 // indirect github.com/butuzov/ireturn v0.4.0 // indirect github.com/butuzov/mirror v1.3.0 // indirect - github.com/catenacyber/perfsprint v0.10.0 // indirect + github.com/catenacyber/perfsprint v0.10.1 // indirect github.com/ccojocar/zxcvbn-go v1.0.4 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/charithe/durationcheck v0.0.11 // indirect @@ -74,16 +77,18 @@ require ( github.com/charmbracelet/lipgloss v1.1.0 // indirect github.com/charmbracelet/x/ansi v0.8.0 // indirect github.com/charmbracelet/x/cellbuf v0.0.13-0.20250311204145-2c3ea96c31dd // indirect - github.com/charmbracelet/x/term v0.2.1 // indirect + github.com/charmbracelet/x/term v0.2.2 // indirect github.com/ckaznocha/intrange v0.3.1 // indirect github.com/client9/misspell v0.3.4 // indirect - github.com/cloudflare/circl v1.6.1 // indirect + github.com/clipperhouse/uax29/v2 v2.2.0 // indirect + github.com/cloudflare/circl v1.6.3 // indirect github.com/curioswitch/go-reassign v0.3.0 // indirect github.com/cyphar/filepath-securejoin v0.5.0 // indirect github.com/daixiang0/gci v0.13.7 // indirect github.com/dave/dst v0.27.3 // indirect github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect github.com/denis-tingaikin/go-header v0.5.0 // indirect + github.com/dkorunic/betteralign v0.8.2 // indirect github.com/dlclark/regexp2 v1.11.5 // indirect github.com/dnephin/pflag v1.0.7 // indirect github.com/emirpasic/gods v1.18.1 // indirect @@ -93,11 +98,11 @@ require ( github.com/firefart/nonamedreturns v1.0.6 // indirect github.com/fsnotify/fsnotify v1.9.0 // indirect github.com/fzipp/gocyclo v0.6.0 // indirect - github.com/ghostiam/protogetter v0.3.17 // indirect + github.com/ghostiam/protogetter v0.3.18 // indirect github.com/go-critic/go-critic v0.14.2 // indirect github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 // indirect github.com/go-git/go-billy/v5 v5.6.2 // indirect - github.com/go-git/go-git/v5 v5.16.3 // indirect + github.com/go-git/go-git/v5 v5.16.5 // indirect github.com/go-json-experiment/json v0.0.0-20250813233538-9b1f9ea2e11b // indirect github.com/go-toolsmith/astcast v1.1.0 // indirect github.com/go-toolsmith/astcopy v1.1.0 // indirect @@ -129,6 +134,7 @@ require ( github.com/google/go-cmp v0.7.0 // indirect github.com/google/go-github/v76 v76.0.0 // indirect github.com/google/go-querystring v1.1.0 // indirect + github.com/google/renameio/v2 v2.0.1 // indirect github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect github.com/gordonklaus/ineffassign v0.2.0 // indirect github.com/gostaticanalysis/analysisutil v0.7.1 // indirect @@ -175,7 +181,7 @@ require ( github.com/matoous/godox v1.1.0 // indirect github.com/mattn/go-colorable v0.1.14 // indirect github.com/mattn/go-isatty v0.0.20 // indirect - github.com/mattn/go-runewidth v0.0.17 // indirect + github.com/mattn/go-runewidth v0.0.19 // indirect github.com/mattn/go-shellwords v1.0.12 // indirect github.com/mgechev/revive v1.12.0 // indirect github.com/mitchellh/go-homedir v1.1.0 // indirect @@ -187,6 +193,7 @@ require ( github.com/nishanths/predeclared v0.2.2 // indirect github.com/nunnatsa/ginkgolinter v0.21.2 // indirect github.com/pavius/impi v0.0.3 // indirect + github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58 // indirect github.com/pelletier/go-toml/v2 v2.2.4 // indirect github.com/pjbgf/sha1cd v0.5.0 // indirect github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect @@ -201,7 +208,7 @@ require ( github.com/quasilyte/regex/syntax v0.0.0-20210819130434-b3f0c404a727 // indirect github.com/quasilyte/stdinfo v0.0.0-20220114132959-f7386bf02567 // indirect github.com/raeperd/recvcheck v0.2.0 // indirect - github.com/rhysd/actionlint v1.7.9 // indirect + github.com/rhysd/actionlint v1.7.11 // indirect github.com/rivo/uniseg v0.4.7 // indirect github.com/robfig/cron/v3 v3.0.1 // indirect github.com/rogpeppe/go-internal v1.14.1 // indirect @@ -214,6 +221,7 @@ require ( github.com/sashamelentyev/usestdlibvars v1.29.0 // indirect github.com/securego/gosec/v2 v2.22.10 // indirect github.com/sergi/go-diff v1.4.0 // indirect + github.com/sirkon/dst v0.26.4 // indirect github.com/sirupsen/logrus v1.9.3 // indirect github.com/sivchari/containedctx v1.0.3 // indirect github.com/skeema/knownhosts v1.3.2 // indirect @@ -221,12 +229,12 @@ require ( github.com/sourcegraph/go-diff v0.7.0 // indirect github.com/spf13/afero v1.15.0 // indirect github.com/spf13/cast v1.10.0 // indirect - github.com/spf13/cobra v1.10.1 // indirect + github.com/spf13/cobra v1.10.2 // indirect github.com/spf13/pflag v1.0.10 // indirect github.com/spf13/viper v1.21.0 // indirect github.com/ssgreg/nlreturn/v2 v2.2.1 // indirect github.com/stbenjam/no-sprintf-host-port v0.2.0 // indirect - github.com/stretchr/objx v0.5.2 // indirect + github.com/stretchr/objx v0.5.3 // indirect github.com/stretchr/testify v1.11.1 // indirect github.com/subosito/gotenv v1.6.0 // indirect github.com/tetafro/godot v1.5.4 // indirect @@ -258,23 +266,23 @@ require ( go.opentelemetry.io/build-tools/multimod v0.29.0 // indirect go.uber.org/automaxprocs v1.6.0 // indirect go.uber.org/multierr v1.11.0 // indirect - go.uber.org/zap v1.27.0 // indirect - go.yaml.in/yaml/v2 v2.4.2 // indirect + go.uber.org/zap v1.27.1 // indirect + go.yaml.in/yaml/v2 v2.4.3 // indirect go.yaml.in/yaml/v3 v3.0.4 // indirect go.yaml.in/yaml/v4 v4.0.0-rc.3 // indirect - golang.org/x/crypto v0.45.0 // indirect + golang.org/x/crypto v0.48.0 // indirect golang.org/x/exp v0.0.0-20240909161429-701f63a606c0 // indirect golang.org/x/exp/typeparams v0.0.0-20251023183803-a4bb9ffd2546 // indirect - golang.org/x/mod v0.29.0 // indirect - golang.org/x/net v0.47.0 // indirect - golang.org/x/sync v0.18.0 // indirect - golang.org/x/sys v0.38.0 // indirect - golang.org/x/telemetry v0.0.0-20251008203120-078029d740a8 // indirect - golang.org/x/term v0.37.0 // indirect - golang.org/x/text v0.31.0 // indirect - golang.org/x/tools v0.38.0 // indirect + golang.org/x/mod v0.33.0 // indirect + golang.org/x/net v0.50.0 // indirect + golang.org/x/sync v0.19.0 // indirect + golang.org/x/sys v0.41.0 // indirect + golang.org/x/telemetry v0.0.0-20260209163413-e7419c687ee4 // indirect + golang.org/x/term v0.40.0 // indirect + golang.org/x/text v0.34.0 // indirect + golang.org/x/tools v0.42.0 // indirect golang.org/x/vuln v1.1.4 // indirect - google.golang.org/protobuf v1.36.8 // indirect + google.golang.org/protobuf v1.36.11 // indirect gopkg.in/warnings.v0 v0.1.2 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect gotest.tools/gotestsum v1.13.0 // indirect diff --git a/internal/tools/go.sum b/internal/tools/go.sum index 529d760119fa..d9b71bc6bf4f 100644 --- a/internal/tools/go.sum +++ b/internal/tools/go.sum @@ -28,6 +28,8 @@ github.com/BurntSushi/toml v1.5.0 h1:W5quZX/G/csjUnuI8SUYlsHs9M38FC7znL0lIO+DvMg github.com/BurntSushi/toml v1.5.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho= github.com/Djarvur/go-err113 v0.1.1 h1:eHfopDqXRwAi+YmCUas75ZE0+hoBHJ2GQNLYRSxao4g= github.com/Djarvur/go-err113 v0.1.1/go.mod h1:IaWJdYFLg76t2ihfflPZnM1LIQszWOsFDh2hhhAVF6k= +github.com/KimMachineGun/automemlimit v0.7.5 h1:RkbaC0MwhjL1ZuBKunGDjE/ggwAX43DwZrJqVwyveTk= +github.com/KimMachineGun/automemlimit v0.7.5/go.mod h1:QZxpHaGOQoYvFhv/r4u3U0JTC2ZcOwbSr11UZF46UBM= github.com/Masterminds/semver/v3 v3.4.0 h1:Zog+i5UMtVoCU8oKka5P7i9q9HgrJeGzI9SA1Xbatp0= github.com/Masterminds/semver/v3 v3.4.0/go.mod h1:4V+yj/TJE1HU9XfppCwVMZq3I84lprf4nC11bSS5beM= github.com/Microsoft/go-winio v0.5.2/go.mod h1:WpS1mjBmmwHBEWmogvA2mj8546UReBk4v8QkMxJ6pZY= @@ -78,8 +80,8 @@ github.com/bkielbasa/cyclop v1.2.3/go.mod h1:kHTwA9Q0uZqOADdupvcFJQtp/ksSnytRMe8 github.com/blizzy78/varnamelen v0.8.0 h1:oqSblyuQvFsW1hbBHh1zfwrKe3kcSj0rnXkKzsQ089M= github.com/blizzy78/varnamelen v0.8.0/go.mod h1:V9TzQZ4fLJ1DSrjVDfl89H7aMnTvKkApdHeyESmyR7k= github.com/bmatcuk/doublestar/v4 v4.0.2/go.mod h1:xBQ8jztBU6kakFMg+8WGxn0c6z1fTSPVIjEY1Wr7jzc= -github.com/bmatcuk/doublestar/v4 v4.9.1 h1:X8jg9rRZmJd4yRy7ZeNDRnM+T3ZfHv15JiBJ/avrEXE= -github.com/bmatcuk/doublestar/v4 v4.9.1/go.mod h1:xBQ8jztBU6kakFMg+8WGxn0c6z1fTSPVIjEY1Wr7jzc= +github.com/bmatcuk/doublestar/v4 v4.10.0 h1:zU9WiOla1YA122oLM6i4EXvGW62DvKZVxIe6TYWexEs= +github.com/bmatcuk/doublestar/v4 v4.10.0/go.mod h1:xBQ8jztBU6kakFMg+8WGxn0c6z1fTSPVIjEY1Wr7jzc= github.com/bombsimon/wsl/v4 v4.7.0 h1:1Ilm9JBPRczjyUs6hvOPKvd7VL1Q++PL8M0SXBDf+jQ= github.com/bombsimon/wsl/v4 v4.7.0/go.mod h1:uV/+6BkffuzSAVYD+yGyld1AChO7/EuLrCF/8xTiapg= github.com/bombsimon/wsl/v5 v5.3.0 h1:nZWREJFL6U3vgW/B1lfDOigl+tEF6qgs6dGGbFeR0UM= @@ -92,8 +94,8 @@ github.com/butuzov/ireturn v0.4.0 h1:+s76bF/PfeKEdbG8b54aCocxXmi0wvYdOVsWxVO7n8E github.com/butuzov/ireturn v0.4.0/go.mod h1:ghI0FrCmap8pDWZwfPisFD1vEc56VKH4NpQUxDHta70= github.com/butuzov/mirror v1.3.0 h1:HdWCXzmwlQHdVhwvsfBb2Au0r3HyINry3bDWLYXiKoc= github.com/butuzov/mirror v1.3.0/go.mod h1:AEij0Z8YMALaq4yQj9CPPVYOyJQyiexpQEQgihajRfI= -github.com/catenacyber/perfsprint v0.10.0 h1:AZj1mYyxbxLRqmnYOeguZXEQwWOgQGm2wzLI5d7Hl/0= -github.com/catenacyber/perfsprint v0.10.0/go.mod h1:DJTGsi/Zufpuus6XPGJyKOTMELe347o6akPvWG9Zcsc= +github.com/catenacyber/perfsprint v0.10.1 h1:u7Riei30bk46XsG8nknMhKLXG9BcXz3+3tl/WpKm0PQ= +github.com/catenacyber/perfsprint v0.10.1/go.mod h1:DJTGsi/Zufpuus6XPGJyKOTMELe347o6akPvWG9Zcsc= github.com/ccojocar/zxcvbn-go v1.0.4 h1:FWnCIRMXPj43ukfX000kvBZvV6raSxakYr1nzyNrUcc= github.com/ccojocar/zxcvbn-go v1.0.4/go.mod h1:3GxGX+rHmueTUMvm5ium7irpyjmm7ikxYFOSJB21Das= github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= @@ -108,14 +110,16 @@ github.com/charmbracelet/x/ansi v0.8.0 h1:9GTq3xq9caJW8ZrBTe0LIe2fvfLR/bYXKTx2ll github.com/charmbracelet/x/ansi v0.8.0/go.mod h1:wdYl/ONOLHLIVmQaxbIYEC/cRKOQyjTkowiI4blgS9Q= github.com/charmbracelet/x/cellbuf v0.0.13-0.20250311204145-2c3ea96c31dd h1:vy0GVL4jeHEwG5YOXDmi86oYw2yuYUGqz6a8sLwg0X8= github.com/charmbracelet/x/cellbuf v0.0.13-0.20250311204145-2c3ea96c31dd/go.mod h1:xe0nKWGd3eJgtqZRaN9RjMtK7xUYchjzPr7q6kcvCCs= -github.com/charmbracelet/x/term v0.2.1 h1:AQeHeLZ1OqSXhrAWpYUtZyX1T3zVxfpZuEQMIQaGIAQ= -github.com/charmbracelet/x/term v0.2.1/go.mod h1:oQ4enTYFV7QN4m0i9mzHrViD7TQKvNEEkHUMCmsxdUg= +github.com/charmbracelet/x/term v0.2.2 h1:xVRT/S2ZcKdhhOuSP4t5cLi5o+JxklsoEObBSgfgZRk= +github.com/charmbracelet/x/term v0.2.2/go.mod h1:kF8CY5RddLWrsgVwpw4kAa6TESp6EB5y3uxGLeCqzAI= github.com/ckaznocha/intrange v0.3.1 h1:j1onQyXvHUsPWujDH6WIjhyH26gkRt/txNlV7LspvJs= github.com/ckaznocha/intrange v0.3.1/go.mod h1:QVepyz1AkUoFQkpEqksSYpNpUo3c5W7nWh/s6SHIJJk= github.com/client9/misspell v0.3.4 h1:ta993UF76GwbvJcIo3Y68y/M3WxlpEHPWIGDkJYwzJI= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= -github.com/cloudflare/circl v1.6.1 h1:zqIqSPIndyBh1bjLVVDHMPpVKqp8Su/V+6MeDzzQBQ0= -github.com/cloudflare/circl v1.6.1/go.mod h1:uddAzsPgqdMAYatqJ0lsjX1oECcQLIlRpzZh3pJrofs= +github.com/clipperhouse/uax29/v2 v2.2.0 h1:ChwIKnQN3kcZteTXMgb1wztSgaU+ZemkgWdohwgs8tY= +github.com/clipperhouse/uax29/v2 v2.2.0/go.mod h1:EFJ2TJMRUaplDxHKj1qAEhCtQPW2tJSwu5BF98AuoVM= +github.com/cloudflare/circl v1.6.3 h1:9GPOhQGF9MCYUeXyMYlqTR6a5gTrgR/fBLXvUgtVcg8= +github.com/cloudflare/circl v1.6.3/go.mod h1:2eXP6Qfat4O/Yhh8BznvKnJ+uzEoTQ6jVKJRn81BiS4= github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g= github.com/curioswitch/go-reassign v0.3.0 h1:dh3kpQHuADL3cobV/sSGETA8DOv457dwl+fbBAhrQPs= github.com/curioswitch/go-reassign v0.3.0/go.mod h1:nApPCCTtqLJN/s8HfItCcKV0jIPwluBOvZP+dsJGA88= @@ -133,6 +137,8 @@ github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1 github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/denis-tingaikin/go-header v0.5.0 h1:SRdnP5ZKvcO9KKRP1KJrhFR3RrlGuD+42t4429eC9k8= github.com/denis-tingaikin/go-header v0.5.0/go.mod h1:mMenU5bWrok6Wl2UsZjy+1okegmwQ3UgWl4V1D8gjlY= +github.com/dkorunic/betteralign v0.8.2 h1:f3sJ/vtuuPOFd2/U3TeGfv8p+VhEyoBLuA05q6mAosU= +github.com/dkorunic/betteralign v0.8.2/go.mod h1:TAkhmNuJ3OKPAN7YgGTauiccHIc9ETjBmtE24fpLxOk= github.com/dlclark/regexp2 v1.11.5 h1:Q/sSnsKerHeCkc/jSTNq1oCm7KiVgUMZRDUoRu0JQZQ= github.com/dlclark/regexp2 v1.11.5/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8= github.com/dnephin/pflag v1.0.7 h1:oxONGlWxhmUct0YzKTgrpQv9AUA1wtPBn7zuSjJqptk= @@ -155,8 +161,8 @@ github.com/fsnotify/fsnotify v1.9.0 h1:2Ml+OJNzbYCTzsxtv8vKSFD9PbJjmhYF14k/jKC7S github.com/fsnotify/fsnotify v1.9.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0= github.com/fzipp/gocyclo v0.6.0 h1:lsblElZG7d3ALtGMx9fmxeTKZaLLpU8mET09yN4BBLo= github.com/fzipp/gocyclo v0.6.0/go.mod h1:rXPyn8fnlpa0R2csP/31uerbiVBugk5whMdlyaLkLoA= -github.com/ghostiam/protogetter v0.3.17 h1:sjGPErP9o7i2Ym+z3LsQzBdLCNaqbYy2iJQPxGXg04Q= -github.com/ghostiam/protogetter v0.3.17/go.mod h1:AivIX1eKA/TcUmzZdzbl+Tb8tjIe8FcyG6JFyemQAH4= +github.com/ghostiam/protogetter v0.3.18 h1:yEpghRGtP9PjKvVXtEzGpYfQj1Wl/ZehAfU6fr62Lfo= +github.com/ghostiam/protogetter v0.3.18/go.mod h1:FjIu5Yfs6FT391m+Fjp3fbAYJ6rkL/J6ySpZBfnODuI= github.com/gliderlabs/ssh v0.3.8 h1:a4YXD1V7xMF9g5nTkdfnja3Sxy1PVDCj1Zg4Wb8vY6c= github.com/gliderlabs/ssh v0.3.8/go.mod h1:xYoytBv1sV0aL3CavoDuJIQNURXkkfPA/wxQ1pL1fAU= github.com/go-critic/go-critic v0.14.2 h1:PMvP5f+LdR8p6B29npvChUXbD1vrNlKDf60NJtgMBOo= @@ -167,8 +173,8 @@ github.com/go-git/go-billy/v5 v5.6.2 h1:6Q86EsPXMa7c3YZ3aLAQsMA0VlWmy43r6FHqa/UN github.com/go-git/go-billy/v5 v5.6.2/go.mod h1:rcFC2rAsp/erv7CMz9GczHcuD0D32fWzH+MJAU+jaUU= github.com/go-git/go-git-fixtures/v4 v4.3.2-0.20231010084843-55a94097c399 h1:eMje31YglSBqCdIqdhKBW8lokaMrL3uTkpGYlE2OOT4= github.com/go-git/go-git-fixtures/v4 v4.3.2-0.20231010084843-55a94097c399/go.mod h1:1OCfN199q1Jm3HZlxleg+Dw/mwps2Wbk9frAWm+4FII= -github.com/go-git/go-git/v5 v5.16.3 h1:Z8BtvxZ09bYm/yYNgPKCzgWtaRqDTgIKRgIRHBfU6Z8= -github.com/go-git/go-git/v5 v5.16.3/go.mod h1:4Ge4alE/5gPs30F2H1esi2gPd69R0C39lolkucHBOp8= +github.com/go-git/go-git/v5 v5.16.5 h1:mdkuqblwr57kVfXri5TTH+nMFLNUxIj9Z7F5ykFbw5s= +github.com/go-git/go-git/v5 v5.16.5/go.mod h1:QOMLpNf1qxuSY4StA/ArOdfFR2TrKEjJiye2kel2m+M= github.com/go-json-experiment/json v0.0.0-20250813233538-9b1f9ea2e11b h1:6Q4zRHXS/YLOl9Ng1b1OOOBWMidAQZR3Gel0UKPC/KU= github.com/go-json-experiment/json v0.0.0-20250813233538-9b1f9ea2e11b/go.mod h1:TiCD2a1pcmjd7YnhGH0f/zKNcCD06B029pHhzV23c2M= github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI= @@ -251,6 +257,8 @@ github.com/google/pprof v0.0.0-20250820193118-f64d9cf942d6 h1:EEHtgt9IwisQ2AZ4pI github.com/google/pprof v0.0.0-20250820193118-f64d9cf942d6/go.mod h1:I6V7YzU0XDpsHqbsyrghnFZLO1gwK6NPTNvmetQIk9U= github.com/google/renameio v0.1.0 h1:GOZbcHa3HfsPKPlmyPyN2KEohoMXOhdMbHrvbpl2QaA= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= +github.com/google/renameio/v2 v2.0.1 h1:HyOM6qd9gF9sf15AvhbptGHUnaLTpEI9akAFFU3VyW0= +github.com/google/renameio/v2 v2.0.1/go.mod h1:BtmJXm5YlszgC+TD4HOEEUFgkJP3nLxehU6hfe7jRt4= github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 h1:El6M4kTTCOh6aBiKaUGG7oYTSPP8MxqL4YI3kZKwcP4= github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3pAXIBCelhxNneeOaAeabZDe5s4K6zSpQ= github.com/gordonklaus/ineffassign v0.2.0 h1:Uths4KnmwxNJNzq87fwQQDDnbNb7De00VOk9Nu0TySs= @@ -361,8 +369,8 @@ github.com/mattn/go-colorable v0.1.14 h1:9A9LHSqF/7dyVVX6g0U9cwm9pG3kP9gSzcuIPHP github.com/mattn/go-colorable v0.1.14/go.mod h1:6LmQG8QLFO4G5z1gPvYEzlUgJ2wF+stgPZH1UqBm1s8= github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= -github.com/mattn/go-runewidth v0.0.17 h1:78v8ZlW0bP43XfmAfPsdXcoNCelfMHsDmd/pkENfrjQ= -github.com/mattn/go-runewidth v0.0.17/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= +github.com/mattn/go-runewidth v0.0.19 h1:v++JhqYnZuu5jSKrk9RbgF5v4CGUjqRfBm05byFGLdw= +github.com/mattn/go-runewidth v0.0.19/go.mod h1:XBkDxAl56ILZc9knddidhrOlY5R/pDhgLpndooCuJAs= github.com/mattn/go-shellwords v1.0.12 h1:M2zGm7EW6UQJvDeQxo4T51eKPurbeFbe8WtebGE2xrk= github.com/mattn/go-shellwords v1.0.12/go.mod h1:EZzvwXDESEeg03EKmM+RmDnNOPKG4lLtQsUlTZDWQ8Y= github.com/mgechev/revive v1.12.0 h1:Q+/kkbbwerrVYPv9d9efaPGmAO/NsxwW/nE6ahpQaCU= @@ -398,6 +406,8 @@ github.com/otiai10/mint v1.6.3 h1:87qsV/aw1F5as1eH1zS/yqHY85ANKVMgkDrf9rcxbQs= github.com/otiai10/mint v1.6.3/go.mod h1:MJm72SBthJjz8qhefc4z1PYEieWmy8Bku7CjcAqyUSM= github.com/pavius/impi v0.0.3 h1:DND6MzU+BLABhOZXbELR3FU8b+zDgcq4dOCNLhiTYuI= github.com/pavius/impi v0.0.3/go.mod h1:x/hU0bfdWIhuOT1SKwiJg++yvkk6EuOtJk8WtDZqgr8= +github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58 h1:onHthvaw9LFnH4t2DcNVpwGmV9E1BkGknEliJkfwQj0= +github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58/go.mod h1:DXv8WO4yhMYhSNPKjeNKa5WY9YCIEBRbNzFFPJbWO6Y= github.com/pelletier/go-toml/v2 v2.2.4 h1:mye9XuhQ6gvn5h28+VilKrrPoQVanw5PMw/TB0t5Ec4= github.com/pelletier/go-toml/v2 v2.2.4/go.mod h1:2gIqNv+qfxSVS7cM2xJQKtLSTLUE9V8t9Stt+h56mCY= github.com/pjbgf/sha1cd v0.5.0 h1:a+UkboSi1znleCDUNT3M5YxjOnN1fz2FhN48FlwCxs0= @@ -431,9 +441,8 @@ github.com/quasilyte/stdinfo v0.0.0-20220114132959-f7386bf02567 h1:M8mH9eK4OUR4l github.com/quasilyte/stdinfo v0.0.0-20220114132959-f7386bf02567/go.mod h1:DWNGW8A4Y+GyBgPuaQJuWiy0XYftx4Xm/y5Jqk9I6VQ= github.com/raeperd/recvcheck v0.2.0 h1:GnU+NsbiCqdC2XX5+vMZzP+jAJC5fht7rcVTAhX74UI= github.com/raeperd/recvcheck v0.2.0/go.mod h1:n04eYkwIR0JbgD73wT8wL4JjPC3wm0nFtzBnWNocnYU= -github.com/rhysd/actionlint v1.7.9 h1:oq4uFwcW6pRTk8BhAS4+RhYoUddUkbvRMcqndja0CT0= -github.com/rhysd/actionlint v1.7.9/go.mod h1:H3q8YpD2es7K4c+mibw3OhTXGQQ7HkZX1u+DXaHLwfE= -github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= +github.com/rhysd/actionlint v1.7.11 h1:m+aSuCpCIClS8X02xMG4Z8s87fCHPsAtYkAoWGQZgEE= +github.com/rhysd/actionlint v1.7.11/go.mod h1:8n50YougV9+50niD7oxgDTZ1KbN/ZnKiQ2xpLFeVhsI= github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ= github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= github.com/robfig/cron/v3 v3.0.1 h1:WdRxkvbJztn8LMz/QEvLN5sBU+xKpSqwwUO1Pjr4qDs= @@ -461,6 +470,8 @@ github.com/sergi/go-diff v1.4.0 h1:n/SP9D5ad1fORl+llWyN+D6qoUETXNZARKjyY2/KVCw= github.com/sergi/go-diff v1.4.0/go.mod h1:A0bzQcvG0E7Rwjx0REVgAGH58e96+X0MeOfepqsbeW4= github.com/shurcooL/go v0.0.0-20180423040247-9e1955d9fb6e/go.mod h1:TDJrrUr11Vxrven61rcy3hJMUqaf/CLWYhHNPmT14Lk= github.com/shurcooL/go-goon v0.0.0-20170922171312-37c2f522c041/go.mod h1:N5mDOmsrJOB+vfqUK+7DmDyjhSLIIBnXo9lvZJj3MWQ= +github.com/sirkon/dst v0.26.4 h1:ETxfjyp5JKE8OCpdybyyhzTyQqq/MwbIIcs7kxcUAcA= +github.com/sirkon/dst v0.26.4/go.mod h1:e6HRc56jU5F2XT6GB8Cyci1Jb5cjX6gLqrm5+T/P7Zo= github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= @@ -476,8 +487,8 @@ github.com/spf13/afero v1.15.0 h1:b/YBCLWAJdFWJTN9cLhiXXcD7mzKn9Dm86dNnfyQw1I= github.com/spf13/afero v1.15.0/go.mod h1:NC2ByUVxtQs4b3sIUphxK0NioZnmxgyCrfzeuq8lxMg= github.com/spf13/cast v1.10.0 h1:h2x0u2shc1QuLHfxi+cTJvs30+ZAHOGRic8uyGTDWxY= github.com/spf13/cast v1.10.0/go.mod h1:jNfB8QC9IA6ZuY2ZjDp0KtFO2LZZlg4S/7bzP6qqeHo= -github.com/spf13/cobra v1.10.1 h1:lJeBwCfmrnXthfAupyUTzJ/J4Nc1RsHC/mSRU2dll/s= -github.com/spf13/cobra v1.10.1/go.mod h1:7SmJGaTHFVBY0jW4NXGluQoLvhqFQM+6XSKD+P4XaB0= +github.com/spf13/cobra v1.10.2 h1:DMTTonx5m65Ic0GOoRY2c16WCbHxOOw6xxezuLaBpcU= +github.com/spf13/cobra v1.10.2/go.mod h1:7C1pvHqHw5A4vrJfjNwvOdzYu0Gml16OCs2GRiTUUS4= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/spf13/pflag v1.0.9/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/spf13/pflag v1.0.10 h1:4EBh2KAYBwaONj6b2Ye1GiHfwjqyROoF4RwYO+vPwFk= @@ -489,8 +500,8 @@ github.com/ssgreg/nlreturn/v2 v2.2.1/go.mod h1:E/iiPB78hV7Szg2YfRgyIrk1AD6JVMTRk github.com/stbenjam/no-sprintf-host-port v0.2.0 h1:i8pxvGrt1+4G0czLr/WnmyH7zbZ8Bg8etvARQ1rpyl4= github.com/stbenjam/no-sprintf-host-port v0.2.0/go.mod h1:eL0bQ9PasS0hsyTyfTjjG+E80QIyPnBVQbYZyv20Jfk= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY= -github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= +github.com/stretchr/objx v0.5.3 h1:jmXUvGomnU1o3W/V5h2VEradbpJDwGrzugQQvL0POH4= +github.com/stretchr/objx v0.5.3/go.mod h1:rDQraq+vQZU7Fde9LOZLr8Tax6zZvy4kuNKF+QYS+U0= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= @@ -571,10 +582,10 @@ go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= -go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8= -go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= -go.yaml.in/yaml/v2 v2.4.2 h1:DzmwEr2rDGHl7lsFgAHxmNz/1NlQ7xLIrlN2h5d1eGI= -go.yaml.in/yaml/v2 v2.4.2/go.mod h1:081UH+NErpNdqlCXm3TtEran0rJZGxAYx9hb/ELlsPU= +go.uber.org/zap v1.27.1 h1:08RqriUEv8+ArZRYSTXy1LeBScaMpVSTBhCeaZYfMYc= +go.uber.org/zap v1.27.1/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= +go.yaml.in/yaml/v2 v2.4.3 h1:6gvOSjQoTB3vt1l+CU+tSyi/HOjfOjRLJ4YwYZGwRO0= +go.yaml.in/yaml/v2 v2.4.3/go.mod h1:zSxWcmIDjOzPXpjlTTbAsKokqkDNAVtZO0WOMiT90s8= go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc= go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg= go.yaml.in/yaml/v4 v4.0.0-rc.3 h1:3h1fjsh1CTAPjW7q/EMe+C8shx5d8ctzZTrLcs/j8Go= @@ -586,8 +597,8 @@ golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5y golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc= golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4= -golang.org/x/crypto v0.45.0 h1:jMBrvKuj23MTlT0bQEOBcAE0mjg8mK9RXFhRH6nyF3Q= -golang.org/x/crypto v0.45.0/go.mod h1:XTGrrkGJve7CYK7J8PEww4aY7gM3qMCElcJQ8n8JdX4= +golang.org/x/crypto v0.48.0 h1:/VRzVqiRSggnhY7gNRxPauEQ5Drw9haKdM0jqfcCFts= +golang.org/x/crypto v0.48.0/go.mod h1:r0kV5h3qnFPlQnBSrULhlsRfryS2pmewsg+XfMgkVos= golang.org/x/exp v0.0.0-20240909161429-701f63a606c0 h1:e66Fs6Z+fZTbFBAxKfP3PALWBtpfqks2bwGcexMxgtk= golang.org/x/exp v0.0.0-20240909161429-701f63a606c0/go.mod h1:2TbTHSBQa924w8M6Xs1QcRcFwyucIwBGpK1p2f1YFFY= golang.org/x/exp/typeparams v0.0.0-20220428152302-39d4317da171/go.mod h1:AbB0pIl9nAr9wVwH+Z2ZpaocVmF5I4GyWCDIsVjR0bk= @@ -603,8 +614,8 @@ golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91 golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/mod v0.13.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= -golang.org/x/mod v0.29.0 h1:HV8lRxZC4l2cr3Zq1LvtOsi/ThTgWnUk/y64QSs8GwA= -golang.org/x/mod v0.29.0/go.mod h1:NyhrlYXJ2H4eJiRy/WDBO6HMqZQ6q9nk4JzS3NuCK+w= +golang.org/x/mod v0.33.0 h1:tHFzIWbBifEmbwtGz65eaWyGiGZatSrT9prnU8DbVL8= +golang.org/x/mod v0.33.0/go.mod h1:swjeQEj+6r7fODbD2cqrnje9PnziFuw4bmLbBZFrQ5w= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= @@ -619,8 +630,8 @@ golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk= golang.org/x/net v0.16.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= -golang.org/x/net v0.47.0 h1:Mx+4dIFzqraBXUugkia1OOvlD6LemFo1ALMHjrXDOhY= -golang.org/x/net v0.47.0/go.mod h1:/jNxtkgq5yWUGYkaZGqo27cfGZ1c5Nen03aYrrKpVRU= +golang.org/x/net v0.50.0 h1:ucWh9eiCGyDR3vtzso0WMQinm2Dnt8cFMuQa9K33J60= +golang.org/x/net v0.50.0/go.mod h1:UgoSli3F/pBgdJBHCTc+tp3gmrU4XswgGRgtnwWTfyM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -630,8 +641,8 @@ golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= golang.org/x/sync v0.4.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= -golang.org/x/sync v0.18.0 h1:kr88TuHDroi+UVf+0hZnirlk8o8T+4MrK6mr60WkH/I= -golang.org/x/sync v0.18.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI= +golang.org/x/sync v0.19.0 h1:vV+1eWNmZ5geRlYjzm2adRgW2/mcpevXNg50YZtPCE4= +golang.org/x/sync v0.19.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -653,18 +664,18 @@ golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.38.0 h1:3yZWxaJjBmCWXqhN1qh02AkOnCQ1poK6oF+a7xWL6Gc= -golang.org/x/sys v0.38.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= -golang.org/x/telemetry v0.0.0-20251008203120-078029d740a8 h1:LvzTn0GQhWuvKH/kVRS3R3bVAsdQWI7hvfLHGgh9+lU= -golang.org/x/telemetry v0.0.0-20251008203120-078029d740a8/go.mod h1:Pi4ztBfryZoJEkyFTI5/Ocsu2jXyDr6iSdgJiYE/uwE= +golang.org/x/sys v0.41.0 h1:Ivj+2Cp/ylzLiEU89QhWblYnOE9zerudt9Ftecq2C6k= +golang.org/x/sys v0.41.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= +golang.org/x/telemetry v0.0.0-20260209163413-e7419c687ee4 h1:bTLqdHv7xrGlFbvf5/TXNxy/iUwwdkjhqQTJDjW7aj0= +golang.org/x/telemetry v0.0.0-20260209163413-e7419c687ee4/go.mod h1:g5NllXBEermZrmR51cJDQxmJUHUOfRAaNyWBM+R+548= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= golang.org/x/term v0.12.0/go.mod h1:owVbMEjm3cBLCHdkQu9b1opXd4ETQWc3BhuQGKgXgvU= golang.org/x/term v0.13.0/go.mod h1:LTmsnFJwVN6bCy1rVCoS+qHT1HhALEFxKncY3WNNh4U= -golang.org/x/term v0.37.0 h1:8EGAD0qCmHYZg6J17DvsMy9/wJ7/D/4pV/wfnld5lTU= -golang.org/x/term v0.37.0/go.mod h1:5pB4lxRNYYVZuTLmy8oR2BH8dflOR+IbTYFD8fi3254= +golang.org/x/term v0.40.0 h1:36e4zGLqU4yhjlmxEaagx2KuYbJq3EwY8K943ZsHcvg= +golang.org/x/term v0.40.0/go.mod h1:w2P8uVp06p2iyKKuvXIm7N/y0UCRt3UfJTfZ7oOpglM= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= @@ -673,8 +684,8 @@ golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= -golang.org/x/text v0.31.0 h1:aC8ghyu4JhP8VojJ2lEHBnochRno1sgL6nEi9WGFGMM= -golang.org/x/text v0.31.0/go.mod h1:tKRAlv61yKIjGGHX/4tP1LTbc13YSec1pxVEWXzfoeM= +golang.org/x/text v0.34.0 h1:oL/Qq0Kdaqxa1KbNeMKwQq0reLCCaFtqu2eNuSeNHbk= +golang.org/x/text v0.34.0/go.mod h1:homfLqTYRFyVYemLBFl5GgL/DWEiH5wcsQ5gSh1yziA= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20200329025819-fd4102a86c65/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8= @@ -687,8 +698,8 @@ golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58= golang.org/x/tools v0.14.0/go.mod h1:uYBEerGOWcJyEORxN+Ek8+TT266gXkNlHdJBwexUsBg= -golang.org/x/tools v0.38.0 h1:Hx2Xv8hISq8Lm16jvBZ2VQf+RLmbd7wVUsALibYI/IQ= -golang.org/x/tools v0.38.0/go.mod h1:yEsQ/d/YK8cjh0L6rZlY8tgtlKiBNTL14pGDJPJpYQs= +golang.org/x/tools v0.42.0 h1:uNgphsn75Tdz5Ji2q36v/nsFSfR/9BRFvqhGBaJGd5k= +golang.org/x/tools v0.42.0/go.mod h1:Ma6lCIwGZvHK6XtgbswSoWroEkhugApmsXyrUmBhfr0= golang.org/x/tools/go/expect v0.1.1-deprecated h1:jpBZDwmgPhXsKZC6WhL20P4b/wmnpsEAGHaNy0n/rJM= golang.org/x/tools/go/expect v0.1.1-deprecated/go.mod h1:eihoPOH+FgIqa3FpoTwguz/bVUSGBlGQU67vpBeOrBY= golang.org/x/tools/go/packages/packagestest v0.1.1-deprecated h1:1h2MnaIAIXISqTFKdENegdpAgUXz6NrPEsbIeWaBRvM= @@ -699,8 +710,8 @@ golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8T golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -google.golang.org/protobuf v1.36.8 h1:xHScyCOEuuwZEc6UtSOvPbAT4zRh0xcNRYekJwfqyMc= -google.golang.org/protobuf v1.36.8/go.mod h1:fuxRtAxBytpl4zzqUh6/eyUujkJdNiuEkXntxiD/uRU= +google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE= +google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= diff --git a/otelcol/collector.go b/otelcol/collector.go index 72b8c56e55ed..726eaf0eda50 100644 --- a/otelcol/collector.go +++ b/otelcol/collector.go @@ -14,7 +14,6 @@ import ( "os/signal" "sync" "sync/atomic" - "syscall" "go.uber.org/multierr" "go.uber.org/zap" @@ -99,7 +98,8 @@ type CollectorSettings struct { // Collector represents a server providing the OpenTelemetry Collector service. type Collector struct { - set CollectorSettings + set CollectorSettings + buildZapLogger func(zap.Config, ...zap.Option) (*zap.Logger, error) configProvider *ConfigProvider @@ -136,9 +136,10 @@ func NewCollector(set CollectorSettings) (*Collector, error) { state := new(atomic.Int64) state.Store(int64(StateStarting)) return &Collector{ - set: set, - state: state, - shutdownChan: make(chan struct{}), + set: set, + buildZapLogger: zap.Config.Build, + state: state, + shutdownChan: make(chan struct{}), // Per signal.Notify documentation, a size of the channel equaled with // the number of signals getting notified on is recommended. signalsChannel: make(chan os.Signal, 3), @@ -196,6 +197,17 @@ func (col *Collector) setupConfigurationComponents(ctx context.Context) error { return fmt.Errorf("could not marshal configuration: %w", err) } + // Wrap the buildZapLogger to append LoggingOptions from collector settings, + // since service.Settings.LoggingOptions is deprecated. + buildZapLogger := col.buildZapLogger + if len(col.set.LoggingOptions) > 0 { + origBuildZapLogger := buildZapLogger + buildZapLogger = func(zapCfg zap.Config, opts ...zap.Option) (*zap.Logger, error) { + opts = append(opts, col.set.LoggingOptions...) + return origBuildZapLogger(zapCfg, opts...) + } + } + col.service, err = service.New(ctx, service.Settings{ BuildInfo: col.set.BuildInfo, CollectorConf: conf, @@ -219,7 +231,7 @@ func (col *Collector) setupConfigurationComponents(ctx context.Context) error { Connector: buildModuleInfo(factories.ConnectorModules), }, AsyncErrorChannel: col.asyncErrorChannel, - LoggingOptions: col.set.LoggingOptions, + BuildZapLogger: buildZapLogger, TelemetryFactory: factories.Telemetry, }, cfg.Service) if err != nil { @@ -335,12 +347,12 @@ func (col *Collector) Run(ctx context.Context) error { } // Always notify with SIGHUP for configuration reloading. - signal.Notify(col.signalsChannel, syscall.SIGHUP) + signal.Notify(col.signalsChannel, SIGHUP) defer signal.Stop(col.signalsChannel) // Only notify with SIGTERM and SIGINT if graceful shutdown is enabled. if !col.set.DisableGracefulShutdown { - signal.Notify(col.signalsChannel, os.Interrupt, syscall.SIGTERM) + signal.Notify(col.signalsChannel, os.Interrupt, SIGTERM) } // Control loop: selects between channels for various interrupts - when this loop is broken, the collector exits. @@ -361,7 +373,7 @@ LOOP: break LOOP case s := <-col.signalsChannel: col.service.Logger().Info("Received signal from OS", zap.String("signal", s.String())) - if s != syscall.SIGHUP { + if s != SIGHUP { break LOOP } if err := col.reloadConfiguration(ctx); err != nil { diff --git a/otelcol/collector_test.go b/otelcol/collector_test.go index 160b45664461..43eb9c770898 100644 --- a/otelcol/collector_test.go +++ b/otelcol/collector_test.go @@ -10,14 +10,15 @@ import ( "os" "path/filepath" "sync" - "syscall" "testing" "time" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "go.uber.org/zap" - yaml "go.yaml.in/yaml/v3" + "go.uber.org/zap/zapcore" + "go.uber.org/zap/zaptest/observer" + "go.yaml.in/yaml/v3" "go.opentelemetry.io/collector/component" "go.opentelemetry.io/collector/component/componentstatus" @@ -303,13 +304,13 @@ func TestCollectorSendSignal(t *testing.T) { return StateRunning == col.GetState() }, 2*time.Second, 200*time.Millisecond) - col.signalsChannel <- syscall.SIGHUP + col.signalsChannel <- SIGHUP assert.Eventually(t, func() bool { return StateRunning == col.GetState() }, 2*time.Second, 200*time.Millisecond) - col.signalsChannel <- syscall.SIGTERM + col.signalsChannel <- SIGTERM wg.Wait() assert.Equal(t, StateClosed, col.GetState()) @@ -326,11 +327,9 @@ func TestCollectorFailedShutdown(t *testing.T) { require.NoError(t, err) wg := sync.WaitGroup{} - wg.Add(1) - go func() { - defer wg.Done() + wg.Go(func() { assert.EqualError(t, col.Run(context.Background()), "failed to shutdown collector telemetry: err1") - }() + }) assert.Eventually(t, func() bool { return StateRunning == col.GetState() @@ -580,11 +579,9 @@ func TestCollectorDryRun(t *testing.T) { func startCollector(ctx context.Context, t *testing.T, col *Collector) *sync.WaitGroup { wg := &sync.WaitGroup{} - wg.Add(1) - go func() { - defer wg.Done() + wg.Go(func() { assert.NoError(t, col.Run(ctx)) - }() + }) return wg } @@ -722,3 +719,55 @@ func TestProviderAndConverterModules(t *testing.T) { col.Shutdown() wg.Wait() } + +func TestCollectorLoggingOptions(t *testing.T) { + // Use zap observer to verify that LoggingOptions are applied + observerCore, observedLogs := observer.New(zapcore.InfoLevel) + + factories, err := nopFactories() + require.NoError(t, err) + + // Create a custom telemetry factory that uses BuildZapLogger + // This ensures BuildZapLogger (which includes LoggingOptions) is used + factories.Telemetry = telemetry.NewFactory( + func() component.Config { return fakeTelemetryConfig{} }, + telemetry.WithCreateLogger( + func(_ context.Context, set telemetry.LoggerSettings, _ component.Config) ( + *zap.Logger, component.ShutdownFunc, error, + ) { + require.Empty(t, set.ZapOptions) // injected through BuidlZapLogger + logger, buildErr := set.BuildZapLogger(zap.NewDevelopmentConfig()) + return logger, nil, buildErr + }, + ), + ) + + set := CollectorSettings{ + BuildInfo: component.NewDefaultBuildInfo(), + Factories: func() (Factories, error) { return factories, nil }, + ConfigProviderSettings: newDefaultConfigProviderSettings(t, + []string{filepath.Join("testdata", "otelcol-nop.yaml")}, + ), + LoggingOptions: []zap.Option{ + zap.WrapCore(func(zapcore.Core) zapcore.Core { + return observerCore + }), + }, + } + + col, err := NewCollector(set) + require.NoError(t, err) + + // Start and stop the collector. + wg := startCollector(context.Background(), t, col) + assert.Eventually(t, func() bool { + return StateRunning == col.GetState() && col.service != nil + }, 2*time.Second, 200*time.Millisecond) + col.Shutdown() + wg.Wait() + + // Check that logs have been redirected to our observer core, + // which proves that LoggingOptions were applied. + entries := observedLogs.All() + require.NotEmpty(t, entries, "Logger should have logged messages") +} diff --git a/otelcol/collector_windows.go b/otelcol/collector_windows.go index ec8aaa3d75b4..949524782771 100644 --- a/otelcol/collector_windows.go +++ b/otelcol/collector_windows.go @@ -10,6 +10,7 @@ import ( "flag" "fmt" "os" + "slices" "time" "go.uber.org/zap" @@ -18,8 +19,6 @@ import ( "golang.org/x/sys/windows/svc/eventlog" "go.opentelemetry.io/collector/featuregate" - "go.opentelemetry.io/collector/service" - "go.opentelemetry.io/collector/service/telemetry/otelconftelemetry" ) type windowsService struct { @@ -93,14 +92,19 @@ func (s *windowsService) start(elog *eventlog.Log, colErrorChannel chan error) e return err } - // The logging options need to be in place before the collector Run method is called - // since the telemetry creates the logger at the time of the Run method call. - // However, the zap.WrapCore function needs to read the serviceConfig to determine - // if the Windows Event Log should be used, however, the serviceConfig is also - // only read at the time of the Run method call. To work around this, we pass the - // serviceConfig as a pointer to the logging options, and then read its value - // when the zap.Logger is created by the telemetry. - s.col.set.LoggingOptions = loggingOptionsWithEventLogCore(elog, &s.col.serviceConfig, s.col.set.LoggingOptions) + // Override the Zap logger to write to the Windows Event Log + // if no file output is specified. + s.col.buildZapLogger = func(cfg zap.Config, opts ...zap.Option) (*zap.Logger, error) { + for _, output := range cfg.OutputPaths { + if output != "stdout" && output != "stderr" { + // A file has been specified in the configuration, + // so do not use the Windows Event Log. + return cfg.Build(opts...) + } + } + opts = slices.Insert(opts, 0, zap.WrapCore(withWindowsCore(elog))) + return cfg.Build(opts...) + } // col.Run blocks until receiving a SIGTERM signal, so needs to be started // asynchronously, but it will exit early if an error occurs on startup @@ -139,20 +143,6 @@ func openEventLog(serviceName string) (*eventlog.Log, error) { return elog, nil } -func loggingOptionsWithEventLogCore( - elog *eventlog.Log, - serviceConfig **service.Config, - userOptions []zap.Option, -) []zap.Option { - return append( - // The order below must be preserved - see PR #11051 - // The event log core must run *after* any user provided options, so it - // must be the first option in this list. - []zap.Option{zap.WrapCore(withWindowsCore(elog, serviceConfig))}, - userOptions..., - ) -} - var _ zapcore.Core = (*windowsEventLogCore)(nil) type windowsEventLogCore struct { @@ -212,20 +202,8 @@ func (w windowsEventLogCore) Sync() error { return w.core.Sync() } -func withWindowsCore(elog *eventlog.Log, serviceConfig **service.Config) func(zapcore.Core) zapcore.Core { +func withWindowsCore(elog *eventlog.Log) func(zapcore.Core) zapcore.Core { return func(core zapcore.Core) zapcore.Core { - if serviceConfig != nil && *serviceConfig != nil { - // TODO remove the dependency on otelconftelemetry - // - // https://github.com/open-telemetry/opentelemetry-collector/issues/14002 - for _, output := range (*serviceConfig).Telemetry.(*otelconftelemetry.Config).Logs.OutputPaths { - if output != "stdout" && output != "stderr" { - // A log file was specified in the configuration, so we should not use the Windows Event Log - return core - } - } - } - // Use the Windows Event Log encoderConfig := zap.NewProductionEncoderConfig() encoderConfig.LineEnding = "\r\n" diff --git a/otelcol/command.go b/otelcol/command.go index 88f3b9a818ed..802ff2716d90 100644 --- a/otelcol/command.go +++ b/otelcol/command.go @@ -3,6 +3,8 @@ package otelcol // import "go.opentelemetry.io/collector/otelcol" +//go:generate mdatagen metadata.yaml + import ( "errors" "flag" @@ -75,6 +77,7 @@ func newFeatureGateCommand() *cobra.Command { Use: "featuregate [feature-id]", Short: "Display feature gates information", Long: "Display information about available feature gates and their status", + Args: cobra.MaximumNArgs(1), RunE: func(_ *cobra.Command, args []string) error { if len(args) > 0 { found := false diff --git a/otelcol/command_components.go b/otelcol/command_components.go index 79961a02ce24..92ffeef40fd6 100644 --- a/otelcol/command_components.go +++ b/otelcol/command_components.go @@ -8,12 +8,14 @@ import ( "sort" "github.com/spf13/cobra" - yaml "go.yaml.in/yaml/v3" + "go.yaml.in/yaml/v3" "go.opentelemetry.io/collector/component" + "go.opentelemetry.io/collector/confmap" "go.opentelemetry.io/collector/connector" "go.opentelemetry.io/collector/exporter" "go.opentelemetry.io/collector/extension" + "go.opentelemetry.io/collector/internal/componentalias" "go.opentelemetry.io/collector/processor" "go.opentelemetry.io/collector/receiver" ) @@ -117,18 +119,12 @@ func newComponentsCommand(set CollectorSettings) *cobra.Command { } components.BuildInfo = set.BuildInfo - for providerScheme, providerModuleModule := range set.ProviderModules { - components.Providers = append(components.Providers, componentWithoutStability{ - Scheme: providerScheme, - Module: providerModuleModule, - }) - } - - for _, converterModule := range set.ConverterModules { - components.Converters = append(components.Converters, componentWithoutStability{ - Module: converterModule, - }) - } + components.Providers = append(components.Providers, sortProvidersByScheme( + set.ProviderModules, + set.ConfigProviderSettings.ResolverSettings.ProviderFactories, + set.ConfigProviderSettings.ResolverSettings.ProviderSettings, + )...) + components.Converters = append(components.Converters, sortConverterModules(set.ConverterModules)...) yamlData, err := yaml.Marshal(components) if err != nil { @@ -155,8 +151,53 @@ func sortFactoriesByType[T component.Factory](factories map[component.Type]T) [] // Build and return list of factories, sorted by component types sortedFactories := make([]T, 0, len(factories)) for _, componentType := range componentTypes { - sortedFactories = append(sortedFactories, factories[componentType]) + if !isComponentAlias(factories[componentType]) { + sortedFactories = append(sortedFactories, factories[componentType]) + } } return sortedFactories } + +func sortProvidersByScheme(providerModules map[string]string, provFactories []confmap.ProviderFactory, set confmap.ProviderSettings) []componentWithoutStability { + schemes := make([]string, 0, len(provFactories)) + for _, f := range provFactories { + provF := f.Create(set) + scheme := provF.Scheme() + if !isComponentAlias(f) { + schemes = append(schemes, scheme) + } + } + + sort.Strings(schemes) + + providerComponents := make([]componentWithoutStability, 0, len(providerModules)) + for _, scheme := range schemes { + providerComponents = append(providerComponents, componentWithoutStability{ + Scheme: scheme, + Module: providerModules[scheme], + }) + } + return providerComponents +} + +func sortConverterModules(modules []string) []componentWithoutStability { + sortedModulesCopy := make([]string, len(modules)) + copy(sortedModulesCopy, modules) + sort.Strings(sortedModulesCopy) + + sortedModules := make([]componentWithoutStability, 0, len(modules)) + for _, mod := range sortedModulesCopy { + sortedModules = append(sortedModules, componentWithoutStability{ + Module: mod, + }) + } + return sortedModules +} + +func isComponentAlias(component any) bool { + if al, ok := component.(componentalias.TypeAliasHolder); ok { + return al.DeprecatedAlias().String() != "" + } + return false +} diff --git a/otelcol/command_components_test.go b/otelcol/command_components_test.go index c88c9ebe6084..4219c879d2e2 100644 --- a/otelcol/command_components_test.go +++ b/otelcol/command_components_test.go @@ -5,6 +5,7 @@ package otelcol import ( "bytes" + "context" "os" "path/filepath" "strings" @@ -14,6 +15,16 @@ import ( "github.com/stretchr/testify/require" "go.opentelemetry.io/collector/component" + "go.opentelemetry.io/collector/connector" + "go.opentelemetry.io/collector/connector/xconnector" + "go.opentelemetry.io/collector/exporter" + "go.opentelemetry.io/collector/exporter/xexporter" + "go.opentelemetry.io/collector/extension" + "go.opentelemetry.io/collector/internal/componentalias" + "go.opentelemetry.io/collector/processor" + "go.opentelemetry.io/collector/processor/xprocessor" + "go.opentelemetry.io/collector/receiver" + "go.opentelemetry.io/collector/receiver/xreceiver" ) func TestNewBuildSubCommand(t *testing.T) { @@ -21,8 +32,10 @@ func TestNewBuildSubCommand(t *testing.T) { BuildInfo: component.NewDefaultBuildInfo(), Factories: nopFactories, ConfigProviderSettings: newDefaultConfigProviderSettings(t, []string{filepath.Join("testdata", "otelcol-nop.yaml")}), + // ensure default providers are referenced by scheme to a module ProviderModules: map[string]string{ - "nop": "go.opentelemetry.io/collector/confmap/provider/testprovider v1.2.3", + "file": "go.opentelemetry.io/collector/confmap/provider/testprovider v1.2.3", + "env": "go.opentelemetry.io/collector/confmap/provider/testprovider v1.2.3", }, ConverterModules: []string{ "go.opentelemetry.io/collector/converter/testconverter v1.2.3", @@ -31,7 +44,7 @@ func TestNewBuildSubCommand(t *testing.T) { cmd := NewCommand(set) cmd.SetArgs([]string{"components"}) - ExpectedOutput, err := os.ReadFile(filepath.Join("testdata", "components-output.yaml")) + expectedOutput, err := os.ReadFile(filepath.Join("testdata", "components-output.yaml")) require.NoError(t, err) b := bytes.NewBufferString("") @@ -41,5 +54,260 @@ func TestNewBuildSubCommand(t *testing.T) { // Trim new line at the end of the two strings to make a better comparison as string() adds an extra new // line that makes the test fail. - assert.Equal(t, strings.ReplaceAll(strings.ReplaceAll(string(ExpectedOutput), "\n", ""), "\r", ""), strings.ReplaceAll(strings.ReplaceAll(b.String(), "\n", ""), "\r", "")) + assert.Equal(t, strings.TrimSpace(string(expectedOutput)), strings.TrimSpace(b.String())) +} + +func TestComponentsStableOutput(t *testing.T) { + set := CollectorSettings{ + BuildInfo: component.NewDefaultBuildInfo(), + Factories: newNamedNopFactories([]string{"bar", "foo", "baz"}), + ConfigProviderSettings: newDefaultConfigProviderSettings(t, []string{filepath.Join("testdata", "otelcol-nop.yaml")}), + // assumes default config provider contains `file`` and `env` schemes`. + ProviderModules: map[string]string{ + "file": "go.opentelemetry.io/collector/confmap/provider/testprovider v1.2.3", + "env": "go.opentelemetry.io/collector/confmap/provider/testprovider v1.2.3", + }, + ConverterModules: []string{ + "go.opentelemetry.io/collector/converter/baz v1.2.3", + "go.opentelemetry.io/collector/converter/foo v1.2.3", + "go.opentelemetry.io/collector/converter/bar v1.2.3", + }, + } + cmd := NewCommand(set) + cmd.SetArgs([]string{"components"}) + + expectedOutput, err := os.ReadFile(filepath.Join("testdata", "components-output-sorted.yaml")) + require.NoError(t, err) + + // ensure output is reasonably consistent + for range 5 { + b := bytes.NewBufferString("") + cmd.SetOut(b) + err = cmd.Execute() + require.NoError(t, err) + // Trim new line at the end of the two strings to make a better comparison as string() adds an extra new + // line that makes the test fail. + assert.Equal(t, strings.TrimSpace(string(expectedOutput)), strings.TrimSpace(b.String())) + } +} + +func newNamedNopFactories( + placeholderTypes []string, +) func() (Factories, error) { + return func() (Factories, error) { + var factories Factories + var err error + + if factories.Connectors, err = MakeFactoryMap(newListNamedConnectorNopFactory( + placeholderTypes, + )...); err != nil { + return Factories{}, err + } + factories.ConnectorModules = make(map[component.Type]string, len(factories.Connectors)) + for _, con := range factories.Connectors { + factories.ConnectorModules[con.Type()] = "go.opentelemetry.io/collector/connector/connectortest v1.2.3" + } + + if factories.Extensions, err = MakeFactoryMap(newListNamedExtensionNopFactory( + placeholderTypes, + )...); err != nil { + return Factories{}, err + } + factories.ExtensionModules = make(map[component.Type]string, len(factories.Extensions)) + for _, ext := range factories.Extensions { + factories.ExtensionModules[ext.Type()] = "go.opentelemetry.io/collector/extension/extensiontest v1.2.3" + } + + if factories.Receivers, err = MakeFactoryMap(newListNamedReceiverNopFactory( + placeholderTypes, + )...); err != nil { + return Factories{}, err + } + factories.ReceiverModules = make(map[component.Type]string, len(factories.Receivers)) + for _, rec := range factories.Receivers { + factories.ReceiverModules[rec.Type()] = "go.opentelemetry.io/collector/receiver/receivertest v1.2.3" + } + + if factories.Exporters, err = MakeFactoryMap(newListNamedExporterNopFactory( + placeholderTypes, + )...); err != nil { + return Factories{}, err + } + factories.ExporterModules = make(map[component.Type]string, len(factories.Exporters)) + for _, exp := range factories.Exporters { + factories.ExporterModules[exp.Type()] = "go.opentelemetry.io/collector/exporter/exportertest v1.2.3" + } + + if factories.Processors, err = MakeFactoryMap(newListNamedProcessorNopFactory( + placeholderTypes, + )...); err != nil { + return Factories{}, err + } + factories.ProcessorModules = make(map[component.Type]string, len(factories.Processors)) + for _, proc := range factories.Processors { + factories.ProcessorModules[proc.Type()] = "go.opentelemetry.io/collector/processor/processortest v1.2.3" + } + + return factories, nil + } +} + +type nopComponent struct { + component.StartFunc + component.ShutdownFunc +} + +func newNamedConnecterNopFactory(typeName string) connector.Factory { + return xconnector.NewFactory( + component.MustNewType(typeName), + func() component.Config { return struct{}{} }, + ) +} + +func newListNamedConnectorNopFactory(typeNames []string) []connector.Factory { + facts := make([]connector.Factory, 0, len(typeNames)) + for _, typ := range typeNames { + facts = append(facts, newNamedConnecterNopFactory(typ)) + } + return facts +} + +func newNamedExtensionNopFactory(typeName string) extension.Factory { + return extension.NewFactory( + component.MustNewType(typeName), + func() component.Config { return struct{}{} }, + func(context.Context, extension.Settings, component.Config) (extension.Extension, error) { + return nopComponent{}, nil + }, + component.StabilityLevelStable, + ) +} + +func newListNamedExtensionNopFactory(typeNames []string) []extension.Factory { + facts := make([]extension.Factory, 0, len(typeNames)) + for _, typ := range typeNames { + facts = append(facts, newNamedExtensionNopFactory(typ)) + } + return facts +} + +func newNamedReceiverNopFactory(typeName string) receiver.Factory { + return xreceiver.NewFactory( + component.MustNewType(typeName), + func() component.Config { return struct{}{} }, + ) +} + +func newListNamedReceiverNopFactory(typeNames []string) []receiver.Factory { + facts := make([]receiver.Factory, 0, len(typeNames)) + for _, typ := range typeNames { + facts = append(facts, newNamedReceiverNopFactory(typ)) + } + return facts +} + +func newNamedProcessorNopFactory(typeName string) processor.Factory { + return xprocessor.NewFactory( + component.MustNewType(typeName), + func() component.Config { return struct{}{} }, + ) +} + +func newListNamedProcessorNopFactory(typeNames []string) []processor.Factory { + facts := make([]processor.Factory, 0, len(typeNames)) + for _, typ := range typeNames { + facts = append(facts, newNamedProcessorNopFactory(typ)) + } + return facts +} + +func newNamedExportersNopFactory(typeName string) exporter.Factory { + return xexporter.NewFactory( + component.MustNewType(typeName), + func() component.Config { return struct{}{} }, + ) +} + +func newListNamedExporterNopFactory(typeNames []string) []exporter.Factory { + facts := make([]exporter.Factory, 0, len(typeNames)) + for _, typ := range typeNames { + facts = append(facts, newNamedExportersNopFactory(typ)) + } + return facts +} + +type mockFactory struct { + componentalias.TypeAliasHolder + name string +} + +func (mockFactory) CreateDefaultConfig() component.Config { + return nil +} + +func (m mockFactory) Type() component.Type { + return component.MustNewType(m.name) +} + +func newMockFactory(name string) mockFactory { + return mockFactory{ + TypeAliasHolder: componentalias.NewTypeAliasHolder(), + name: name, + } +} + +func TestSortFactoriesByType(t *testing.T) { + for _, tt := range []struct { + name string + factories map[component.Type]mockFactory + want []mockFactory + }{ + { + name: "with an empty map", + factories: map[component.Type]mockFactory{}, + want: []mockFactory{}, + }, + { + name: "with a single factory", + factories: map[component.Type]mockFactory{ + component.MustNewType("receiver"): newMockFactory("receiver_factory"), + }, + want: []mockFactory{ + newMockFactory("receiver_factory"), + }, + }, + { + name: "with multiple factories", + factories: map[component.Type]mockFactory{ + component.MustNewType("processor"): newMockFactory("processor_factory"), + component.MustNewType("exporter"): newMockFactory("exporter_factory"), + component.MustNewType("receiver"): newMockFactory("receiver_factory"), + }, + want: []mockFactory{ + newMockFactory("exporter_factory"), + newMockFactory("processor_factory"), + newMockFactory("receiver_factory"), + }, + }, + { + name: "with aliases factories", + factories: func() map[component.Type]mockFactory { + alias := newMockFactory("alias_processor_factory") + alias.SetDeprecatedAlias(alias.Type()) + + return map[component.Type]mockFactory{ + component.MustNewType("processor"): newMockFactory("processor_factory"), + component.MustNewType("alias_processor"): alias, + } + }(), + want: []mockFactory{ + newMockFactory("processor_factory"), + }, + }, + } { + t.Run(tt.name, func(t *testing.T) { + got := sortFactoriesByType(tt.factories) + assert.Equal(t, tt.want, got) + }) + } } diff --git a/otelcol/command_print.go b/otelcol/command_print.go index a35b83e0da30..d4438cbc3956 100644 --- a/otelcol/command_print.go +++ b/otelcol/command_print.go @@ -12,20 +12,11 @@ import ( "strings" "github.com/spf13/cobra" - yaml "go.yaml.in/yaml/v3" + "go.yaml.in/yaml/v3" "go.opentelemetry.io/collector/confmap" "go.opentelemetry.io/collector/confmap/xconfmap" - "go.opentelemetry.io/collector/featuregate" -) - -const featureGateName = "otelcol.printInitialConfig" - -var printCommandFeatureFlag = featuregate.GlobalRegistry().MustRegister( - featureGateName, - featuregate.StageBeta, - featuregate.WithRegisterFromVersion("v0.120.0"), - featuregate.WithRegisterDescription("if set to true, enable the print-config command"), + "go.opentelemetry.io/collector/otelcol/internal/metadata" ) // newConfigPrintSubCommand constructs a new print-config command using the given CollectorSettings. @@ -84,7 +75,7 @@ type printContext struct { } func (pctx *printContext) configPrintSubCommand(flagSet *flag.FlagSet, mode string) error { - if !printCommandFeatureFlag.IsEnabled() { + if !metadata.OtelcolPrintInitialConfigFeatureGate.IsEnabled() { return errors.New("print-config is currently experimental, use the otelcol.printInitialConfig feature gate to enable this command") } err := updateSettingsUsingFlags(&pctx.set, flagSet) diff --git a/otelcol/command_print_test.go b/otelcol/command_print_test.go index 6560742e7b18..4467fa15d0fc 100644 --- a/otelcol/command_print_test.go +++ b/otelcol/command_print_test.go @@ -22,6 +22,7 @@ import ( "go.opentelemetry.io/collector/exporter" "go.opentelemetry.io/collector/exporter/xexporter" "go.opentelemetry.io/collector/featuregate" + "go.opentelemetry.io/collector/otelcol/internal/metadata" "go.opentelemetry.io/collector/receiver" "go.opentelemetry.io/collector/receiver/xreceiver" "go.opentelemetry.io/collector/service/telemetry" @@ -148,16 +149,16 @@ func TestPrintCommand(t *testing.T) { fg := featuregate.GlobalRegistry() fg.VisitAll(func(g *featuregate.Gate) { - if g.ID() == featureGateName { + if g.ID() == metadata.OtelcolPrintInitialConfigFeatureGate.ID() { defer func() { - _ = fg.Set(featureGateName, g.IsEnabled()) + _ = fg.Set(metadata.OtelcolPrintInitialConfigFeatureGate.ID(), g.IsEnabled()) }() } }) if test.disableFF { - require.NoError(t, fg.Set(featureGateName, false)) + require.NoError(t, fg.Set(metadata.OtelcolPrintInitialConfigFeatureGate.ID(), false)) } else { - require.NoError(t, fg.Set(featureGateName, true)) + require.NoError(t, fg.Set(metadata.OtelcolPrintInitialConfigFeatureGate.ID(), true)) } testR := component.MustNewType("r") diff --git a/otelcol/command_test.go b/otelcol/command_test.go index 56445eea4f3d..46f8290f1a16 100644 --- a/otelcol/command_test.go +++ b/otelcol/command_test.go @@ -216,4 +216,11 @@ func TestNewFeatureGateCommand(t *testing.T) { require.Error(t, err) assert.Contains(t, err.Error(), "feature \"non.existent.feature\" not found") }) + + t.Run("rejects multiple arguments", func(t *testing.T) { + cmd := newFeatureGateCommand() + cmd.SetArgs([]string{"gate1", "gate2"}) + err := cmd.Execute() + require.Error(t, err) + }) } diff --git a/otelcol/configprovider_test.go b/otelcol/configprovider_test.go index 927ee204582a..b66d2530b75c 100644 --- a/otelcol/configprovider_test.go +++ b/otelcol/configprovider_test.go @@ -11,7 +11,7 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - yaml "go.yaml.in/yaml/v3" + "go.yaml.in/yaml/v3" "go.opentelemetry.io/collector/component" "go.opentelemetry.io/collector/confmap" diff --git a/otelcol/documentation.md b/otelcol/documentation.md new file mode 100644 index 000000000000..ab4f64d03481 --- /dev/null +++ b/otelcol/documentation.md @@ -0,0 +1,13 @@ +[comment]: <> (Code generated by mdatagen. DO NOT EDIT.) + +# otelcol + +## Feature Gates + +This component has the following feature gates: + +| Feature Gate | Stage | Description | From Version | To Version | Reference | +| ------------ | ----- | ----------- | ------------ | ---------- | --------- | +| `otelcol.printInitialConfig` | beta | if set to true, enable the print-config command | v0.120.0 | N/A | [Link](https://github.com/open-telemetry/opentelemetry-collector/pull/11775) | + +For more information about feature gates, see the [Feature Gates](https://github.com/open-telemetry/opentelemetry-collector/blob/main/featuregate/README.md) documentation. diff --git a/otelcol/factories.go b/otelcol/factories.go index 763770591890..7b3f1baccacc 100644 --- a/otelcol/factories.go +++ b/otelcol/factories.go @@ -10,6 +10,7 @@ import ( "go.opentelemetry.io/collector/connector" "go.opentelemetry.io/collector/exporter" "go.opentelemetry.io/collector/extension" + "go.opentelemetry.io/collector/internal/componentalias" "go.opentelemetry.io/collector/processor" "go.opentelemetry.io/collector/receiver" "go.opentelemetry.io/collector/service/telemetry" @@ -54,13 +55,25 @@ type Factories struct { // MakeFactoryMap takes a list of factories and returns a map with Factory type as keys. // It returns a non-nil error when there are factories with duplicate type. +// If a factory has a deprecated alias, the map will also contain an entry for the alias. func MakeFactoryMap[T component.Factory](factories ...T) (map[component.Type]T, error) { - fMap := map[component.Type]T{} + fMap := make(map[component.Type]T, len(factories)) for _, f := range factories { if _, ok := fMap[f.Type()]; ok { return fMap, fmt.Errorf("duplicate component factory %q", f.Type()) } fMap[f.Type()] = f + + // If factory has a deprecated alias, add it to the map as well + if aliasHolder, ok := any(f).(componentalias.TypeAliasHolder); ok { + alias := aliasHolder.DeprecatedAlias() + if alias.String() != "" { + if _, exists := fMap[alias]; exists { + return fMap, fmt.Errorf("duplicate component factory %q (alias of %q)", alias, f.Type()) + } + fMap[alias] = f + } + } } return fMap, nil } diff --git a/otelcol/factories_test.go b/otelcol/factories_test.go index 52a5f0299e11..d1aa4e48b100 100644 --- a/otelcol/factories_test.go +++ b/otelcol/factories_test.go @@ -20,6 +20,7 @@ import ( "go.opentelemetry.io/collector/processor/processortest" "go.opentelemetry.io/collector/receiver" "go.opentelemetry.io/collector/receiver/receivertest" + "go.opentelemetry.io/collector/receiver/xreceiver" "go.opentelemetry.io/collector/service/telemetry" ) @@ -83,6 +84,7 @@ func TestMakeFactoryMap(t *testing.T) { fRec := receiver.NewFactory(component.MustNewType("rec"), nil) fRec2 := receiver.NewFactory(component.MustNewType("rec"), nil) + fRec3 := xreceiver.NewFactory(component.MustNewType("new_rec"), nil, xreceiver.WithDeprecatedTypeAlias(component.MustNewType("rec"))) fPro := processor.NewFactory(component.MustNewType("pro"), nil) fCon := connector.NewFactory(component.MustNewType("con"), nil) fExp := exporter.NewFactory(component.MustNewType("exp"), nil) @@ -103,6 +105,18 @@ func TestMakeFactoryMap(t *testing.T) { name: "same name", in: []component.Factory{fRec, fPro, fCon, fExp, fExt, fRec2}, }, + { + name: "with deprecated alias", + in: []component.Factory{fRec3}, + out: map[component.Type]component.Factory{ + fRec3.Type(): fRec3, + component.MustNewType("rec"): fRec3, + }, + }, + { + name: "conflicting alias name", + in: []component.Factory{fRec, fRec3}, + }, } for _, tt := range testCases { diff --git a/otelcol/flags.go b/otelcol/flags.go index 06f9989adb3c..9a5e243cac4d 100644 --- a/otelcol/flags.go +++ b/otelcol/flags.go @@ -40,12 +40,12 @@ func flags(reg *featuregate.Registry) *flag.FlagSet { "Set arbitrary component config property. The component has to be defined in the config file and the flag"+ " has a higher precedence. Array config properties are overridden and maps are joined. Example --set=processors.batch.timeout=2s", func(s string) error { - idx := strings.Index(s, "=") - if idx == -1 { + before, after, ok := strings.Cut(s, "=") + if !ok { // No need for more context, see TestSetFlag/invalid_set. return errors.New("missing equal sign") } - cfgs.sets = append(cfgs.sets, "yaml:"+strings.TrimSpace(strings.ReplaceAll(s[:idx], ".", "::"))+": "+strings.TrimSpace(s[idx+1:])) + cfgs.sets = append(cfgs.sets, "yaml:"+strings.TrimSpace(strings.ReplaceAll(before, ".", "::"))+": "+strings.TrimSpace(after)) return nil }) diff --git a/otelcol/package_test.go b/otelcol/generated_package_test.go similarity index 61% rename from otelcol/package_test.go rename to otelcol/generated_package_test.go index 539e88c85c41..52f34e251b79 100644 --- a/otelcol/package_test.go +++ b/otelcol/generated_package_test.go @@ -1,5 +1,4 @@ -// Copyright The OpenTelemetry Authors -// SPDX-License-Identifier: Apache-2.0 +// Code generated by mdatagen. DO NOT EDIT. package otelcol diff --git a/otelcol/go.mod b/otelcol/go.mod index 7afbba62872a..a5bcc6d84c5d 100644 --- a/otelcol/go.mod +++ b/otelcol/go.mod @@ -1,126 +1,124 @@ module go.opentelemetry.io/collector/otelcol -go 1.24.0 +go 1.25.0 require ( - github.com/spf13/cobra v1.10.1 + github.com/spf13/cobra v1.10.2 github.com/stretchr/testify v1.11.1 - go.opentelemetry.io/collector/component v1.46.0 - go.opentelemetry.io/collector/component/componentstatus v0.140.0 - go.opentelemetry.io/collector/config/configopaque v1.46.0 - go.opentelemetry.io/collector/confmap v1.46.0 - go.opentelemetry.io/collector/confmap/provider/fileprovider v1.46.0 - go.opentelemetry.io/collector/confmap/xconfmap v0.140.0 - go.opentelemetry.io/collector/connector v0.140.0 - go.opentelemetry.io/collector/connector/connectortest v0.140.0 - go.opentelemetry.io/collector/consumer v1.46.0 - go.opentelemetry.io/collector/exporter v1.46.0 - go.opentelemetry.io/collector/exporter/exportertest v0.140.0 - go.opentelemetry.io/collector/exporter/xexporter v0.140.0 - go.opentelemetry.io/collector/extension v1.46.0 - go.opentelemetry.io/collector/extension/extensiontest v0.140.0 - go.opentelemetry.io/collector/featuregate v1.46.0 - go.opentelemetry.io/collector/pipeline v1.46.0 - go.opentelemetry.io/collector/processor v1.46.0 - go.opentelemetry.io/collector/processor/processortest v0.140.0 - go.opentelemetry.io/collector/receiver v1.46.0 - go.opentelemetry.io/collector/receiver/receivertest v0.140.0 - go.opentelemetry.io/collector/receiver/xreceiver v0.140.0 - go.opentelemetry.io/collector/service v0.140.0 - go.opentelemetry.io/collector/service/telemetry/telemetrytest v0.140.0 + go.opentelemetry.io/collector/component v1.54.0 + go.opentelemetry.io/collector/component/componentstatus v0.148.0 + go.opentelemetry.io/collector/config/configopaque v1.54.0 + go.opentelemetry.io/collector/confmap v1.54.0 + go.opentelemetry.io/collector/confmap/provider/fileprovider v1.54.0 + go.opentelemetry.io/collector/confmap/xconfmap v0.148.0 + go.opentelemetry.io/collector/connector v0.148.0 + go.opentelemetry.io/collector/connector/connectortest v0.148.0 + go.opentelemetry.io/collector/connector/xconnector v0.148.0 + go.opentelemetry.io/collector/consumer v1.54.0 + go.opentelemetry.io/collector/exporter v1.54.0 + go.opentelemetry.io/collector/exporter/exportertest v0.148.0 + go.opentelemetry.io/collector/exporter/xexporter v0.148.0 + go.opentelemetry.io/collector/extension v1.54.0 + go.opentelemetry.io/collector/extension/extensiontest v0.148.0 + go.opentelemetry.io/collector/featuregate v1.54.0 + go.opentelemetry.io/collector/internal/componentalias v0.148.0 + go.opentelemetry.io/collector/pipeline v1.54.0 + go.opentelemetry.io/collector/processor v1.54.0 + go.opentelemetry.io/collector/processor/processortest v0.148.0 + go.opentelemetry.io/collector/processor/xprocessor v0.148.0 + go.opentelemetry.io/collector/receiver v1.54.0 + go.opentelemetry.io/collector/receiver/receivertest v0.148.0 + go.opentelemetry.io/collector/receiver/xreceiver v0.148.0 + go.opentelemetry.io/collector/service v0.148.0 + go.opentelemetry.io/collector/service/telemetry/telemetrytest v0.148.0 go.uber.org/goleak v1.3.0 go.uber.org/multierr v1.11.0 go.uber.org/zap v1.27.1 go.yaml.in/yaml/v3 v3.0.4 golang.org/x/exp v0.0.0-20240506185415-9bf2ced13842 - golang.org/x/sys v0.40.0 - google.golang.org/grpc v1.77.0 + golang.org/x/sys v0.41.0 + google.golang.org/grpc v1.79.3 ) require ( github.com/beorn7/perks v1.0.1 // indirect github.com/cenkalti/backoff/v5 v5.0.3 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect - github.com/davecgh/go-spew v1.1.1 // indirect - github.com/ebitengine/purego v0.9.0 // indirect + github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect + github.com/ebitengine/purego v0.10.0 // indirect github.com/go-logr/logr v1.4.3 // indirect github.com/go-logr/stdr v1.2.2 // indirect github.com/go-ole/go-ole v1.2.6 // indirect - github.com/go-viper/mapstructure/v2 v2.4.0 // indirect + github.com/go-viper/mapstructure/v2 v2.5.0 // indirect github.com/gobwas/glob v0.2.3 // indirect github.com/google/uuid v1.6.0 // indirect - github.com/grafana/regexp v0.0.0-20240518133315-a468a5bfb3bc // indirect - github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.2 // indirect - github.com/hashicorp/go-version v1.7.0 // indirect + github.com/grpc-ecosystem/grpc-gateway/v2 v2.28.0 // indirect + github.com/hashicorp/go-version v1.8.0 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/json-iterator/go v1.1.12 // indirect github.com/knadh/koanf/maps v0.1.2 // indirect github.com/knadh/koanf/providers/confmap v1.0.0 // indirect - github.com/knadh/koanf/v2 v2.3.0 // indirect - github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 // indirect + github.com/knadh/koanf/v2 v2.3.3 // indirect + github.com/lufia/plan9stats v0.0.0-20251013123823-9fd1530e3ec3 // indirect github.com/mitchellh/copystructure v1.2.0 // indirect github.com/mitchellh/reflectwalk v1.0.2 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee // indirect github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect - github.com/pmezard/go-difflib v1.0.0 // indirect + github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect github.com/power-devops/perfstat v0.0.0-20240221224432-82ca36839d55 // indirect github.com/prometheus/client_golang v1.23.2 // indirect github.com/prometheus/client_model v0.6.2 // indirect - github.com/prometheus/common v0.67.1 // indirect - github.com/prometheus/otlptranslator v0.0.2 // indirect - github.com/prometheus/procfs v0.17.0 // indirect - github.com/shirou/gopsutil/v4 v4.25.10 // indirect - github.com/spf13/pflag v1.0.9 // indirect - github.com/tklauser/go-sysconf v0.3.15 // indirect - github.com/tklauser/numcpus v0.10.0 // indirect + github.com/prometheus/common v0.67.5 // indirect + github.com/prometheus/otlptranslator v1.0.0 // indirect + github.com/prometheus/procfs v0.20.1 // indirect + github.com/shirou/gopsutil/v4 v4.26.2 // indirect + github.com/spf13/pflag v1.0.10 // indirect + github.com/tklauser/go-sysconf v0.3.16 // indirect + github.com/tklauser/numcpus v0.11.0 // indirect github.com/yusufpapurcu/wmi v1.2.4 // indirect go.opentelemetry.io/auto/sdk v1.2.1 // indirect - go.opentelemetry.io/collector/component/componenttest v0.140.0 // indirect + go.opentelemetry.io/collector/component/componenttest v0.148.0 // indirect go.opentelemetry.io/collector/config/configtelemetry v0.140.0 // indirect - go.opentelemetry.io/collector/connector/xconnector v0.140.0 // indirect - go.opentelemetry.io/collector/consumer/consumererror v0.140.0 // indirect - go.opentelemetry.io/collector/consumer/consumertest v0.140.0 // indirect - go.opentelemetry.io/collector/consumer/xconsumer v0.140.0 // indirect + go.opentelemetry.io/collector/consumer/consumererror v0.148.0 // indirect + go.opentelemetry.io/collector/consumer/consumertest v0.148.0 // indirect + go.opentelemetry.io/collector/consumer/xconsumer v0.148.0 // indirect go.opentelemetry.io/collector/extension/extensioncapabilities v0.140.0 // indirect - go.opentelemetry.io/collector/internal/fanoutconsumer v0.140.0 // indirect + go.opentelemetry.io/collector/internal/fanoutconsumer v0.148.0 // indirect go.opentelemetry.io/collector/internal/telemetry v0.140.0 // indirect - go.opentelemetry.io/collector/pdata v1.46.0 // indirect - go.opentelemetry.io/collector/pdata/pprofile v0.140.0 // indirect - go.opentelemetry.io/collector/pdata/testdata v0.140.0 // indirect + go.opentelemetry.io/collector/pdata v1.54.0 // indirect + go.opentelemetry.io/collector/pdata/pprofile v0.148.0 // indirect + go.opentelemetry.io/collector/pdata/testdata v0.148.0 // indirect go.opentelemetry.io/collector/pdata/xpdata v0.140.0 // indirect - go.opentelemetry.io/collector/pipeline/xpipeline v0.140.0 // indirect - go.opentelemetry.io/collector/processor/xprocessor v0.140.0 // indirect + go.opentelemetry.io/collector/pipeline/xpipeline v0.148.0 // indirect go.opentelemetry.io/collector/service/hostcapabilities v0.140.0 // indirect - go.opentelemetry.io/contrib/bridges/otelzap v0.13.0 // indirect go.opentelemetry.io/contrib/otelconf v0.18.0 // indirect - go.opentelemetry.io/contrib/propagators/b3 v1.38.0 // indirect - go.opentelemetry.io/otel v1.40.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.14.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.14.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.38.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.38.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.38.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.38.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.38.0 // indirect - go.opentelemetry.io/otel/exporters/prometheus v0.60.0 // indirect - go.opentelemetry.io/otel/exporters/stdout/stdoutlog v0.14.0 // indirect - go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.38.0 // indirect - go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.38.0 // indirect - go.opentelemetry.io/otel/log v0.14.0 // indirect - go.opentelemetry.io/otel/metric v1.40.0 // indirect - go.opentelemetry.io/otel/sdk v1.40.0 // indirect - go.opentelemetry.io/otel/sdk/log v0.14.0 // indirect - go.opentelemetry.io/otel/sdk/metric v1.40.0 // indirect - go.opentelemetry.io/otel/trace v1.40.0 // indirect - go.opentelemetry.io/proto/otlp v1.7.1 // indirect + go.opentelemetry.io/otel v1.42.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.18.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.18.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.42.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.42.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.42.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.42.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.42.0 // indirect + go.opentelemetry.io/otel/exporters/prometheus v0.64.0 // indirect + go.opentelemetry.io/otel/exporters/stdout/stdoutlog v0.18.0 // indirect + go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.42.0 // indirect + go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.42.0 // indirect + go.opentelemetry.io/otel/log v0.18.0 // indirect + go.opentelemetry.io/otel/metric v1.42.0 // indirect + go.opentelemetry.io/otel/sdk v1.42.0 // indirect + go.opentelemetry.io/otel/sdk/log v0.18.0 // indirect + go.opentelemetry.io/otel/sdk/metric v1.42.0 // indirect + go.opentelemetry.io/otel/trace v1.42.0 // indirect + go.opentelemetry.io/proto/otlp v1.10.0 // indirect go.yaml.in/yaml/v2 v2.4.3 // indirect - golang.org/x/net v0.47.0 // indirect - golang.org/x/text v0.31.0 // indirect - gonum.org/v1/gonum v0.16.0 // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20251022142026-3a174f9686a8 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20251022142026-3a174f9686a8 // indirect - google.golang.org/protobuf v1.36.10 // indirect + golang.org/x/net v0.51.0 // indirect + golang.org/x/text v0.34.0 // indirect + gonum.org/v1/gonum v0.17.0 // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20260226221140-a57be14db171 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20260226221140-a57be14db171 // indirect + google.golang.org/protobuf v1.36.11 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) @@ -233,3 +231,7 @@ replace go.opentelemetry.io/collector/pdata/xpdata => ../pdata/xpdata replace go.opentelemetry.io/collector/exporter/exporterhelper => ../exporter/exporterhelper replace go.opentelemetry.io/collector/internal/testutil => ../internal/testutil + +replace go.opentelemetry.io/collector/internal/componentalias => ../internal/componentalias + +replace go.opentelemetry.io/collector/config/confignet => ../config/confignet diff --git a/otelcol/go.sum b/otelcol/go.sum index 148f8cb6367d..04d5b2da6513 100644 --- a/otelcol/go.sum +++ b/otelcol/go.sum @@ -6,14 +6,15 @@ github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UF github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/ebitengine/purego v0.9.0 h1:mh0zpKBIXDceC63hpvPuGLiJ8ZAa3DfrFTudmfi8A4k= -github.com/ebitengine/purego v0.9.0/go.mod h1:iIjxzd6CiRiOG0UyXP+V1+jWqUXVjPKLAI0mRfJZTmQ= +github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= +github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/ebitengine/purego v0.10.0 h1:QIw4xfpWT6GWTzaW5XEKy3HXoqrJGx1ijYHzTF0/ISU= +github.com/ebitengine/purego v0.10.0/go.mod h1:iIjxzd6CiRiOG0UyXP+V1+jWqUXVjPKLAI0mRfJZTmQ= github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg= github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= -github.com/foxboron/go-tpm-keyfiles v0.0.0-20250903184740-5d135037bd4d h1:EdO/NMMuCZfxhdzTZLuKAciQSnI2DV+Ppg8+vAYrnqA= -github.com/foxboron/go-tpm-keyfiles v0.0.0-20250903184740-5d135037bd4d/go.mod h1:uAyTlAUxchYuiFjTHmuIEJ4nGSm7iOPaGcAyA81fJ80= +github.com/foxboron/go-tpm-keyfiles v0.0.0-20251226215517-609e4778396f h1:RJ+BDPLSHQO7cSjKBqjPJSbi1qfk9WcsjQDtZiw3dZw= +github.com/foxboron/go-tpm-keyfiles v0.0.0-20251226215517-609e4778396f/go.mod h1:VHbbch/X4roIY22jL1s3qRbZhCiRIgUAF/PdSUcx2io= github.com/fsnotify/fsnotify v1.9.0 h1:2Ml+OJNzbYCTzsxtv8vKSFD9PbJjmhYF14k/jKC7S9k= github.com/fsnotify/fsnotify v1.9.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= @@ -23,48 +24,47 @@ github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY= github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0= -github.com/go-viper/mapstructure/v2 v2.4.0 h1:EBsztssimR/CONLSZZ04E8qAkxNYq4Qp9LvH92wZUgs= -github.com/go-viper/mapstructure/v2 v2.4.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM= +github.com/go-viper/mapstructure/v2 v2.5.0 h1:vM5IJoUAy3d7zRSVtIwQgBj7BiWtMPfmPEgAXnvj1Ro= +github.com/go-viper/mapstructure/v2 v2.5.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM= github.com/gobwas/glob v0.2.3 h1:A4xDbljILXROh+kObIiy5kIaPYD8e96x1tgBhUI5J+Y= github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8= github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= github.com/golang/snappy v1.0.0 h1:Oy607GVXHs7RtbggtPBnr2RmDArIsAefDwvrdWvRhGs= github.com/golang/snappy v1.0.0/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= -github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= -github.com/google/go-tpm v0.9.7 h1:u89J4tUUeDTlH8xxC3CTW7OHZjbjKoHdQ9W7gCUhtxA= -github.com/google/go-tpm v0.9.7/go.mod h1:h9jEsEECg7gtLis0upRBQU+GhYVH6jMjrFxI8u6bVUY= +github.com/google/go-tpm v0.9.8 h1:slArAR9Ft+1ybZu0lBwpSmpwhRXaa85hWtMinMyRAWo= +github.com/google/go-tpm v0.9.8/go.mod h1:h9jEsEECg7gtLis0upRBQU+GhYVH6jMjrFxI8u6bVUY= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/grafana/regexp v0.0.0-20240518133315-a468a5bfb3bc h1:GN2Lv3MGO7AS6PrRoT6yV5+wkrOpcszoIsO4+4ds248= -github.com/grafana/regexp v0.0.0-20240518133315-a468a5bfb3bc/go.mod h1:+JKpmjMGhpgPL+rXZ5nsZieVzvarn86asRlBg4uNGnk= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.2 h1:8Tjv8EJ+pM1xP8mK6egEbD1OgnVTyacbefKhmbLhIhU= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.2/go.mod h1:pkJQ2tZHJ0aFOVEEot6oZmaVEZcRme73eIFmhiVuRWs= -github.com/hashicorp/go-version v1.7.0 h1:5tqGy27NaOTB8yJKUZELlFAS/LTKJkrmONwQKeRZfjY= -github.com/hashicorp/go-version v1.7.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.28.0 h1:HWRh5R2+9EifMyIHV7ZV+MIZqgz+PMpZ14Jynv3O2Zs= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.28.0/go.mod h1:JfhWUomR1baixubs02l85lZYYOm7LV6om4ceouMv45c= +github.com/hashicorp/go-version v1.8.0 h1:KAkNb1HAiZd1ukkxDFGmokVZe1Xy9HG6NUp+bPle2i4= +github.com/hashicorp/go-version v1.8.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= +github.com/hashicorp/golang-lru/v2 v2.0.7 h1:a+bsQ5rvGLjzHuww6tVxozPZFVghXaHOwFs4luLUK2k= +github.com/hashicorp/golang-lru/v2 v2.0.7/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyfM2/ZepoAG6RGpeM= github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= -github.com/klauspost/compress v1.18.1 h1:bcSGx7UbpBqMChDtsF28Lw6v/G94LPrrbMbdC3JH2co= -github.com/klauspost/compress v1.18.1/go.mod h1:ZQFFVG+MdnR0P+l6wpXgIL4NTtwiKIdBnrBd8Nrxr+0= +github.com/klauspost/compress v1.18.4 h1:RPhnKRAQ4Fh8zU2FY/6ZFDwTVTxgJ/EMydqSTzE9a2c= +github.com/klauspost/compress v1.18.4/go.mod h1:R0h/fSBs8DE4ENlcrlib3PsXS61voFxhIs2DeRhCvJ4= github.com/knadh/koanf/maps v0.1.2 h1:RBfmAW5CnZT+PJ1CVc1QSJKf4Xu9kxfQgYVQSu8hpbo= github.com/knadh/koanf/maps v0.1.2/go.mod h1:npD/QZY3V6ghQDdcQzl1W4ICNVTkohC8E73eI2xW4yI= github.com/knadh/koanf/providers/confmap v1.0.0 h1:mHKLJTE7iXEys6deO5p6olAiZdG5zwp8Aebir+/EaRE= github.com/knadh/koanf/providers/confmap v1.0.0/go.mod h1:txHYHiI2hAtF0/0sCmcuol4IDcuQbKTybiB1nOcUo1A= -github.com/knadh/koanf/v2 v2.3.0 h1:Qg076dDRFHvqnKG97ZEsi9TAg2/nFTa9hCdcSa1lvlM= -github.com/knadh/koanf/v2 v2.3.0/go.mod h1:gRb40VRAbd4iJMYYD5IxZ6hfuopFcXBpc9bbQpZwo28= +github.com/knadh/koanf/v2 v2.3.3 h1:jLJC8XCRfLC7n4F+ZKKdBsbq1bfXTpuFhf4L7t94D94= +github.com/knadh/koanf/v2 v2.3.3/go.mod h1:gRb40VRAbd4iJMYYD5IxZ6hfuopFcXBpc9bbQpZwo28= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc= github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= -github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 h1:6E+4a0GO5zZEnZ81pIr0yLvtUWk2if982qA3F3QD6H4= -github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0/go.mod h1:zJYVVT2jmtg6P3p1VtQj7WsuWi/y4VnjVBn7F8KPB3I= +github.com/lufia/plan9stats v0.0.0-20251013123823-9fd1530e3ec3 h1:PwQumkgq4/acIiZhtifTV5OUqqiP82UAl0h87xj/l9k= +github.com/lufia/plan9stats v0.0.0-20251013123823-9fd1530e3ec3/go.mod h1:autxFIvghDt3jPTLoqZ9OZ7s9qTGNAWmYCjVFWPX/zg= github.com/mitchellh/copystructure v1.2.0 h1:vpKXTN4ewci03Vljg/q9QvCGUDttBOGBIa15WveJJGw= github.com/mitchellh/copystructure v1.2.0/go.mod h1:qLl+cE2AmVv+CoeAwDPye/v+N2HKCj9FbZEVFJRxO9s= github.com/mitchellh/reflectwalk v1.0.2 h1:G2LzWKi524PWgd3mLHV8Y5k7s6XUvT0Gef6zxSIeXaQ= @@ -77,103 +77,99 @@ github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee h1:W5t00kpgFd github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= -github.com/pierrec/lz4/v4 v4.1.22 h1:cKFw6uJDK+/gfw5BcDL0JL5aBsAFdsIT18eRtLj7VIU= -github.com/pierrec/lz4/v4 v4.1.22/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4= -github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pierrec/lz4/v4 v4.1.26 h1:GrpZw1gZttORinvzBdXPUXATeqlJjqUG/D87TKMnhjY= +github.com/pierrec/lz4/v4 v4.1.26/go.mod h1:EoQMVJgeeEOMsCqCzqFm2O0cJvljX2nGZjcRIPL34O4= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= +github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/power-devops/perfstat v0.0.0-20240221224432-82ca36839d55 h1:o4JXh1EVt9k/+g42oCprj/FisM4qX9L3sZB3upGN2ZU= github.com/power-devops/perfstat v0.0.0-20240221224432-82ca36839d55/go.mod h1:OmDBASR4679mdNQnz2pUhc2G8CO2JrUAVFDRBDP/hJE= github.com/prometheus/client_golang v1.23.2 h1:Je96obch5RDVy3FDMndoUsjAhG5Edi49h0RJWRi/o0o= github.com/prometheus/client_golang v1.23.2/go.mod h1:Tb1a6LWHB3/SPIzCoaDXI4I8UHKeFTEQ1YCr+0Gyqmg= github.com/prometheus/client_model v0.6.2 h1:oBsgwpGs7iVziMvrGhE53c/GrLUsZdHnqNwqPLxwZyk= github.com/prometheus/client_model v0.6.2/go.mod h1:y3m2F6Gdpfy6Ut/GBsUqTWZqCUvMVzSfMLjcu6wAwpE= -github.com/prometheus/common v0.67.1 h1:OTSON1P4DNxzTg4hmKCc37o4ZAZDv0cfXLkOt0oEowI= -github.com/prometheus/common v0.67.1/go.mod h1:RpmT9v35q2Y+lsieQsdOh5sXZ6ajUGC8NjZAmr8vb0Q= -github.com/prometheus/otlptranslator v0.0.2 h1:+1CdeLVrRQ6Psmhnobldo0kTp96Rj80DRXRd5OSnMEQ= -github.com/prometheus/otlptranslator v0.0.2/go.mod h1:P8AwMgdD7XEr6QRUJ2QWLpiAZTgTE2UYgjlu3svompI= -github.com/prometheus/procfs v0.17.0 h1:FuLQ+05u4ZI+SS/w9+BWEM2TXiHKsUQ9TADiRH7DuK0= -github.com/prometheus/procfs v0.17.0/go.mod h1:oPQLaDAMRbA+u8H5Pbfq+dl3VDAvHxMUOVhe0wYB2zw= +github.com/prometheus/common v0.67.5 h1:pIgK94WWlQt1WLwAC5j2ynLaBRDiinoAb86HZHTUGI4= +github.com/prometheus/common v0.67.5/go.mod h1:SjE/0MzDEEAyrdr5Gqc6G+sXI67maCxzaT3A2+HqjUw= +github.com/prometheus/otlptranslator v1.0.0 h1:s0LJW/iN9dkIH+EnhiD3BlkkP5QVIUVEoIwkU+A6qos= +github.com/prometheus/otlptranslator v1.0.0/go.mod h1:vRYWnXvI6aWGpsdY/mOT/cbeVRBlPWtBNDb7kGR3uKM= +github.com/prometheus/procfs v0.20.1 h1:XwbrGOIplXW/AU3YhIhLODXMJYyC1isLFfYCsTEycfc= +github.com/prometheus/procfs v0.20.1/go.mod h1:o9EMBZGRyvDrSPH1RqdxhojkuXstoe4UlK79eF5TGGo= github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ= github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc= github.com/rs/cors v1.11.1 h1:eU3gRzXLRK57F5rKMGMZURNdIG4EoAmX8k94r9wXWHA= github.com/rs/cors v1.11.1/go.mod h1:XyqrcTp5zjWr1wsJ8PIRZssZ8b/WMcMf71DJnit4EMU= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= -github.com/shirou/gopsutil/v4 v4.25.10 h1:at8lk/5T1OgtuCp+AwrDofFRjnvosn0nkN2OLQ6g8tA= -github.com/shirou/gopsutil/v4 v4.25.10/go.mod h1:+kSwyC8DRUD9XXEHCAFjK+0nuArFJM0lva+StQAcskM= -github.com/spf13/cobra v1.10.1 h1:lJeBwCfmrnXthfAupyUTzJ/J4Nc1RsHC/mSRU2dll/s= -github.com/spf13/cobra v1.10.1/go.mod h1:7SmJGaTHFVBY0jW4NXGluQoLvhqFQM+6XSKD+P4XaB0= -github.com/spf13/pflag v1.0.9 h1:9exaQaMOCwffKiiiYk6/BndUBv+iRViNW+4lEMi0PvY= +github.com/shirou/gopsutil/v4 v4.26.2 h1:X8i6sicvUFih4BmYIGT1m2wwgw2VG9YgrDTi7cIRGUI= +github.com/shirou/gopsutil/v4 v4.26.2/go.mod h1:LZ6ewCSkBqUpvSOf+LsTGnRinC6iaNUNMGBtDkJBaLQ= +github.com/spf13/cobra v1.10.2 h1:DMTTonx5m65Ic0GOoRY2c16WCbHxOOw6xxezuLaBpcU= +github.com/spf13/cobra v1.10.2/go.mod h1:7C1pvHqHw5A4vrJfjNwvOdzYu0Gml16OCs2GRiTUUS4= github.com/spf13/pflag v1.0.9/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= +github.com/spf13/pflag v1.0.10 h1:4EBh2KAYBwaONj6b2Ye1GiHfwjqyROoF4RwYO+vPwFk= +github.com/spf13/pflag v1.0.10/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U= github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= -github.com/tklauser/go-sysconf v0.3.15 h1:VE89k0criAymJ/Os65CSn1IXaol+1wrsFHEB8Ol49K4= -github.com/tklauser/go-sysconf v0.3.15/go.mod h1:Dmjwr6tYFIseJw7a3dRLJfsHAMXZ3nEnL/aZY+0IuI4= -github.com/tklauser/numcpus v0.10.0 h1:18njr6LDBk1zuna922MgdjQuJFjrdppsZG60sHGfjso= -github.com/tklauser/numcpus v0.10.0/go.mod h1:BiTKazU708GQTYF4mB+cmlpT2Is1gLk7XVuEeem8LsQ= +github.com/tklauser/go-sysconf v0.3.16 h1:frioLaCQSsF5Cy1jgRBrzr6t502KIIwQ0MArYICU0nA= +github.com/tklauser/go-sysconf v0.3.16/go.mod h1:/qNL9xxDhc7tx3HSRsLWNnuzbVfh3e7gh/BmM179nYI= +github.com/tklauser/numcpus v0.11.0 h1:nSTwhKH5e1dMNsCdVBukSZrURJRoHbSEQjdEbY+9RXw= +github.com/tklauser/numcpus v0.11.0/go.mod h1:z+LwcLq54uWZTX0u/bGobaV34u6V7KNlTZejzM6/3MQ= github.com/yusufpapurcu/wmi v1.2.4 h1:zFUKzehAFReQwLys1b/iSMl+JQGSCSjtVqQn9bBrPo0= github.com/yusufpapurcu/wmi v1.2.4/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0= go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64= go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y= -go.opentelemetry.io/contrib/bridges/otelzap v0.13.0 h1:aBKdhLVieqvwWe9A79UHI/0vgp2t/s2euY8X59pGRlw= -go.opentelemetry.io/contrib/bridges/otelzap v0.13.0/go.mod h1:SYqtxLQE7iINgh6WFuVi2AI70148B8EI35DSk0Wr8m4= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.63.0 h1:RbKq8BG0FI8OiXhBfcRtqqHcZcka+gU3cskNuf05R18= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.63.0/go.mod h1:h06DGIukJOevXaj/xrNjhi/2098RZzcLTbc0jDAUbsg= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.67.0 h1:OyrsyzuttWTSur2qN/Lm0m2a8yqyIjUVBZcxFPuXq2o= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.67.0/go.mod h1:C2NGBr+kAB4bk3xtMXfZ94gqFDtg/GkI7e9zqGh5Beg= go.opentelemetry.io/contrib/otelconf v0.18.0 h1:ciF2Gf00BWs0DnexKFZXcxg9kJ8r3SUW1LOzW3CsKA8= go.opentelemetry.io/contrib/otelconf v0.18.0/go.mod h1:FcP7k+JLwBLdOxS6qY6VQ/4b5VBntI6L6o80IMwhAeI= -go.opentelemetry.io/contrib/propagators/b3 v1.38.0 h1:uHsCCOSKl0kLrV2dLkFK+8Ywk9iKa/fptkytc6aFFEo= -go.opentelemetry.io/contrib/propagators/b3 v1.38.0/go.mod h1:wMRSZJZcY8ya9mApLLhwIMjqmApy2o/Ml+62lhvxyHU= -go.opentelemetry.io/contrib/zpages v0.63.0 h1:TppOKuZGbqXMgsfjqq3i09N5Vbo1JLtLImUqiTPGnX4= -go.opentelemetry.io/contrib/zpages v0.63.0/go.mod h1:5F8uugz75ay/MMhRRhxAXY33FuaI8dl7jTxefrIy5qk= -go.opentelemetry.io/otel v1.40.0 h1:oA5YeOcpRTXq6NN7frwmwFR0Cn3RhTVZvXsP4duvCms= -go.opentelemetry.io/otel v1.40.0/go.mod h1:IMb+uXZUKkMXdPddhwAHm6UfOwJyh4ct1ybIlV14J0g= -go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.14.0 h1:OMqPldHt79PqWKOMYIAQs3CxAi7RLgPxwfFSwr4ZxtM= -go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.14.0/go.mod h1:1biG4qiqTxKiUCtoWDPpL3fB3KxVwCiGw81j3nKMuHE= -go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.14.0 h1:QQqYw3lkrzwVsoEX0w//EhH/TCnpRdEenKBOOEIMjWc= -go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.14.0/go.mod h1:gSVQcr17jk2ig4jqJ2DX30IdWH251JcNAecvrqTxH1s= -go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.38.0 h1:vl9obrcoWVKp/lwl8tRE33853I8Xru9HFbw/skNeLs8= -go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.38.0/go.mod h1:GAXRxmLJcVM3u22IjTg74zWBrRCKq8BnOqUVLodpcpw= -go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.38.0 h1:Oe2z/BCg5q7k4iXC3cqJxKYg0ieRiOqF0cecFYdPTwk= -go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.38.0/go.mod h1:ZQM5lAJpOsKnYagGg/zV2krVqTtaVdYdDkhMoX6Oalg= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.38.0 h1:GqRJVj7UmLjCVyVJ3ZFLdPRmhDUp2zFmQe3RHIOsw24= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.38.0/go.mod h1:ri3aaHSmCTVYu2AWv44YMauwAQc0aqI9gHKIcSbI1pU= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.38.0 h1:lwI4Dc5leUqENgGuQImwLo4WnuXFPetmPpkLi2IrX54= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.38.0/go.mod h1:Kz/oCE7z5wuyhPxsXDuaPteSWqjSBD5YaSdbxZYGbGk= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.38.0 h1:aTL7F04bJHUlztTsNGJ2l+6he8c+y/b//eR0jjjemT4= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.38.0/go.mod h1:kldtb7jDTeol0l3ewcmd8SDvx3EmIE7lyvqbasU3QC4= -go.opentelemetry.io/otel/exporters/prometheus v0.60.0 h1:cGtQxGvZbnrWdC2GyjZi0PDKVSLWP/Jocix3QWfXtbo= -go.opentelemetry.io/otel/exporters/prometheus v0.60.0/go.mod h1:hkd1EekxNo69PTV4OWFGZcKQiIqg0RfuWExcPKFvepk= -go.opentelemetry.io/otel/exporters/stdout/stdoutlog v0.14.0 h1:B/g+qde6Mkzxbry5ZZag0l7QrQBCtVm7lVjaLgmpje8= -go.opentelemetry.io/otel/exporters/stdout/stdoutlog v0.14.0/go.mod h1:mOJK8eMmgW6ocDJn6Bn11CcZ05gi3P8GylBXEkZtbgA= -go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.38.0 h1:wm/Q0GAAykXv83wzcKzGGqAnnfLFyFe7RslekZuv+VI= -go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.38.0/go.mod h1:ra3Pa40+oKjvYh+ZD3EdxFZZB0xdMfuileHAm4nNN7w= -go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.38.0 h1:kJxSDN4SgWWTjG/hPp3O7LCGLcHXFlvS2/FFOrwL+SE= -go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.38.0/go.mod h1:mgIOzS7iZeKJdeB8/NYHrJ48fdGc71Llo5bJ1J4DWUE= -go.opentelemetry.io/otel/log v0.14.0 h1:2rzJ+pOAZ8qmZ3DDHg73NEKzSZkhkGIua9gXtxNGgrM= -go.opentelemetry.io/otel/log v0.14.0/go.mod h1:5jRG92fEAgx0SU/vFPxmJvhIuDU9E1SUnEQrMlJpOno= -go.opentelemetry.io/otel/log/logtest v0.14.0 h1:BGTqNeluJDK2uIHAY8lRqxjVAYfqgcaTbVk1n3MWe5A= -go.opentelemetry.io/otel/log/logtest v0.14.0/go.mod h1:IuguGt8XVP4XA4d2oEEDMVDBBCesMg8/tSGWDjuKfoA= -go.opentelemetry.io/otel/metric v1.40.0 h1:rcZe317KPftE2rstWIBitCdVp89A2HqjkxR3c11+p9g= -go.opentelemetry.io/otel/metric v1.40.0/go.mod h1:ib/crwQH7N3r5kfiBZQbwrTge743UDc7DTFVZrrXnqc= -go.opentelemetry.io/otel/sdk v1.40.0 h1:KHW/jUzgo6wsPh9At46+h4upjtccTmuZCFAc9OJ71f8= -go.opentelemetry.io/otel/sdk v1.40.0/go.mod h1:Ph7EFdYvxq72Y8Li9q8KebuYUr2KoeyHx0DRMKrYBUE= -go.opentelemetry.io/otel/sdk/log v0.14.0 h1:JU/U3O7N6fsAXj0+CXz21Czg532dW2V4gG1HE/e8Zrg= -go.opentelemetry.io/otel/sdk/log v0.14.0/go.mod h1:imQvII+0ZylXfKU7/wtOND8Hn4OpT3YUoIgqJVksUkM= -go.opentelemetry.io/otel/sdk/log/logtest v0.14.0 h1:Ijbtz+JKXl8T2MngiwqBlPaHqc4YCaP/i13Qrow6gAM= -go.opentelemetry.io/otel/sdk/log/logtest v0.14.0/go.mod h1:dCU8aEL6q+L9cYTqcVOk8rM9Tp8WdnHOPLiBgp0SGOA= -go.opentelemetry.io/otel/sdk/metric v1.40.0 h1:mtmdVqgQkeRxHgRv4qhyJduP3fYJRMX4AtAlbuWdCYw= -go.opentelemetry.io/otel/sdk/metric v1.40.0/go.mod h1:4Z2bGMf0KSK3uRjlczMOeMhKU2rhUqdWNoKcYrtcBPg= -go.opentelemetry.io/otel/trace v1.40.0 h1:WA4etStDttCSYuhwvEa8OP8I5EWu24lkOzp+ZYblVjw= -go.opentelemetry.io/otel/trace v1.40.0/go.mod h1:zeAhriXecNGP/s2SEG3+Y8X9ujcJOTqQ5RgdEJcawiA= -go.opentelemetry.io/proto/otlp v1.7.1 h1:gTOMpGDb0WTBOP8JaO72iL3auEZhVmAQg4ipjOVAtj4= -go.opentelemetry.io/proto/otlp v1.7.1/go.mod h1:b2rVh6rfI/s2pHWNlB7ILJcRALpcNDzKhACevjI+ZnE= -go.opentelemetry.io/proto/slim/otlp v1.9.0 h1:fPVMv8tP3TrsqlkH1HWYUpbCY9cAIemx184VGkS6vlE= -go.opentelemetry.io/proto/slim/otlp v1.9.0/go.mod h1:xXdeJJ90Gqyll+orzUkY4bOd2HECo5JofeoLpymVqdI= -go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.2.0 h1:o13nadWDNkH/quoDomDUClnQBpdQQ2Qqv0lQBjIXjE8= -go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.2.0/go.mod h1:Gyb6Xe7FTi/6xBHwMmngGoHqL0w29Y4eW8TGFzpefGA= -go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.2.0 h1:EiUYvtwu6PMrMHVjcPfnsG3v+ajPkbUeH+IL93+QYyk= -go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.2.0/go.mod h1:mUUHKFiN2SST3AhJ8XhJxEoeVW12oqfXog0Bo8W3Ec4= +go.opentelemetry.io/contrib/zpages v0.67.0 h1:cIUwWSVDovuLEbDIKreptjdxMuIhGiqwq0uL8YNaq1c= +go.opentelemetry.io/contrib/zpages v0.67.0/go.mod h1:vK8fsYHgPYg4Z/XDbFSEvItSGZDbjWTvjBOu8+AiDhc= +go.opentelemetry.io/otel v1.42.0 h1:lSQGzTgVR3+sgJDAU/7/ZMjN9Z+vUip7leaqBKy4sho= +go.opentelemetry.io/otel v1.42.0/go.mod h1:lJNsdRMxCUIWuMlVJWzecSMuNjE7dOYyWlqOXWkdqCc= +go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.18.0 h1:deI9UQMoGFgrg5iLPgzueqFPHevDl+28YKfSpPTI6rY= +go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.18.0/go.mod h1:PFx9NgpNUKXdf7J4Q3agRxMs3Y07QhTCVipKmLsMKnU= +go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.18.0 h1:icqq3Z34UrEFk2u+HMhTtRsvo7Ues+eiJVjaJt62njs= +go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.18.0/go.mod h1:W2m8P+d5Wn5kipj4/xmbt9uMqezEKfBjzVJadfABSBE= +go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.42.0 h1:MdKucPl/HbzckWWEisiNqMPhRrAOQX8r4jTuGr636gk= +go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.42.0/go.mod h1:RolT8tWtfHcjajEH5wFIZ4Dgh5jpPdFXYV9pTAk/qjc= +go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.42.0 h1:H7O6RlGOMTizyl3R08Kn5pdM06bnH8oscSj7o11tmLA= +go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.42.0/go.mod h1:mBFWu/WOVDkWWsR7Tx7h6EpQB8wsv7P0Yrh0Pb7othc= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.42.0 h1:THuZiwpQZuHPul65w4WcwEnkX2QIuMT+UFoOrygtoJw= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.42.0/go.mod h1:J2pvYM5NGHofZ2/Ru6zw/TNWnEQp5crgyDeSrYpXkAw= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.42.0 h1:zWWrB1U6nqhS/k6zYB74CjRpuiitRtLLi68VcgmOEto= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.42.0/go.mod h1:2qXPNBX1OVRC0IwOnfo1ljoid+RD0QK3443EaqVlsOU= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.42.0 h1:uLXP+3mghfMf7XmV4PkGfFhFKuNWoCvvx5wP/wOXo0o= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.42.0/go.mod h1:v0Tj04armyT59mnURNUJf7RCKcKzq+lgJs6QSjHjaTc= +go.opentelemetry.io/otel/exporters/prometheus v0.64.0 h1:g0LRDXMX/G1SEZtK8zl8Chm4K6GBwRkjPKE36LxiTYs= +go.opentelemetry.io/otel/exporters/prometheus v0.64.0/go.mod h1:UrgcjnarfdlBDP3GjDIJWe6HTprwSazNjwsI+Ru6hro= +go.opentelemetry.io/otel/exporters/stdout/stdoutlog v0.18.0 h1:KJVjPD3rcPb98rIs3HznyJlrfx9ge5oJvxxlGR+P/7s= +go.opentelemetry.io/otel/exporters/stdout/stdoutlog v0.18.0/go.mod h1:K3kRa2ckmHWQaTWQdPRHc7qGXASuVuoEQXzrvlA98Ws= +go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.42.0 h1:lSZHgNHfbmQTPfuTmWVkEu8J8qXaQwuV30pjCcAUvP8= +go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.42.0/go.mod h1:so9ounLcuoRDu033MW/E0AD4hhUjVqswrMF5FoZlBcw= +go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.42.0 h1:s/1iRkCKDfhlh1JF26knRneorus8aOwVIDhvYx9WoDw= +go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.42.0/go.mod h1:UI3wi0FXg1Pofb8ZBiBLhtMzgoTm1TYkMvn71fAqDzs= +go.opentelemetry.io/otel/log v0.18.0 h1:XgeQIIBjZZrliksMEbcwMZefoOSMI1hdjiLEiiB0bAg= +go.opentelemetry.io/otel/log v0.18.0/go.mod h1:KEV1kad0NofR3ycsiDH4Yjcoj0+8206I6Ox2QYFSNgI= +go.opentelemetry.io/otel/metric v1.42.0 h1:2jXG+3oZLNXEPfNmnpxKDeZsFI5o4J+nz6xUlaFdF/4= +go.opentelemetry.io/otel/metric v1.42.0/go.mod h1:RlUN/7vTU7Ao/diDkEpQpnz3/92J9ko05BIwxYa2SSI= +go.opentelemetry.io/otel/sdk v1.42.0 h1:LyC8+jqk6UJwdrI/8VydAq/hvkFKNHZVIWuslJXYsDo= +go.opentelemetry.io/otel/sdk v1.42.0/go.mod h1:rGHCAxd9DAph0joO4W6OPwxjNTYWghRWmkHuGbayMts= +go.opentelemetry.io/otel/sdk/log v0.18.0 h1:n8OyZr7t7otkeTnPTbDNom6rW16TBYGtvyy2Gk6buQw= +go.opentelemetry.io/otel/sdk/log v0.18.0/go.mod h1:C0+wxkTwKpOCZLrlJ3pewPiiQwpzycPI/u6W0Z9fuYk= +go.opentelemetry.io/otel/sdk/log/logtest v0.18.0 h1:l3mYuPsuBx6UKE47BVcPrZoZ0q/KER57vbj2qkgDLXA= +go.opentelemetry.io/otel/sdk/log/logtest v0.18.0/go.mod h1:7cHtiVJpZebB3wybTa4NG+FUo5NPe3PROz1FqB0+qdw= +go.opentelemetry.io/otel/sdk/metric v1.42.0 h1:D/1QR46Clz6ajyZ3G8SgNlTJKBdGp84q9RKCAZ3YGuA= +go.opentelemetry.io/otel/sdk/metric v1.42.0/go.mod h1:Ua6AAlDKdZ7tdvaQKfSmnFTdHx37+J4ba8MwVCYM5hc= +go.opentelemetry.io/otel/trace v1.42.0 h1:OUCgIPt+mzOnaUTpOQcBiM/PLQ/Op7oq6g4LenLmOYY= +go.opentelemetry.io/otel/trace v1.42.0/go.mod h1:f3K9S+IFqnumBkKhRJMeaZeNk9epyhnCmQh/EysQCdc= +go.opentelemetry.io/proto/otlp v1.10.0 h1:IQRWgT5srOCYfiWnpqUYz9CVmbO8bFmKcwYxpuCSL2g= +go.opentelemetry.io/proto/otlp v1.10.0/go.mod h1:/CV4QoCR/S9yaPj8utp3lvQPoqMtxXdzn7ozvvozVqk= +go.opentelemetry.io/proto/slim/otlp v1.10.0 h1:iR97Vs/ZDR+y9TfuP9b1XBtdPWeC+OMslIBmhcLU7jM= +go.opentelemetry.io/proto/slim/otlp v1.10.0/go.mod h1:lV9250stpjYLPNA5viFabIgP2QlUGRT1GdTgAf8SIUk= +go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.3.0 h1:RUF5rO0hAlgiJt1fzQVzcVs3vZVNHIcMLgOgG4rWNcQ= +go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.3.0/go.mod h1:I89cynRj8y+383o7tEQVg2SVA6SRgDVIouWPUVXjx0U= +go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.3.0 h1:CQvJSldHRUN6Z8jsUeYv8J0lXRvygALXIzsmAeCcZE0= +go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.3.0/go.mod h1:xSQ+mEfJe/GjK1LXEyVOoSI1N9JV9ZI923X5kup43W4= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= @@ -184,29 +180,28 @@ go.yaml.in/yaml/v2 v2.4.3 h1:6gvOSjQoTB3vt1l+CU+tSyi/HOjfOjRLJ4YwYZGwRO0= go.yaml.in/yaml/v2 v2.4.3/go.mod h1:zSxWcmIDjOzPXpjlTTbAsKokqkDNAVtZO0WOMiT90s8= go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc= go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg= -golang.org/x/crypto v0.45.0 h1:jMBrvKuj23MTlT0bQEOBcAE0mjg8mK9RXFhRH6nyF3Q= -golang.org/x/crypto v0.45.0/go.mod h1:XTGrrkGJve7CYK7J8PEww4aY7gM3qMCElcJQ8n8JdX4= +golang.org/x/crypto v0.48.0 h1:/VRzVqiRSggnhY7gNRxPauEQ5Drw9haKdM0jqfcCFts= +golang.org/x/crypto v0.48.0/go.mod h1:r0kV5h3qnFPlQnBSrULhlsRfryS2pmewsg+XfMgkVos= golang.org/x/exp v0.0.0-20240506185415-9bf2ced13842 h1:vr/HnozRka3pE4EsMEg1lgkXJkTFJCVUX+S/ZT6wYzM= golang.org/x/exp v0.0.0-20240506185415-9bf2ced13842/go.mod h1:XtvwrStGgqGPLc4cjQfWqZHG1YFdYs6swckp8vpsjnc= -golang.org/x/net v0.47.0 h1:Mx+4dIFzqraBXUugkia1OOvlD6LemFo1ALMHjrXDOhY= -golang.org/x/net v0.47.0/go.mod h1:/jNxtkgq5yWUGYkaZGqo27cfGZ1c5Nen03aYrrKpVRU= +golang.org/x/net v0.51.0 h1:94R/GTO7mt3/4wIKpcR5gkGmRLOuE/2hNGeWq/GBIFo= +golang.org/x/net v0.51.0/go.mod h1:aamm+2QF5ogm02fjy5Bb7CQ0WMt1/WVM7FtyaTLlA9Y= golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201204225414-ed752295db88/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.40.0 h1:DBZZqJ2Rkml6QMQsZywtnjnnGvHza6BTfYFWY9kjEWQ= -golang.org/x/sys v0.40.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= -golang.org/x/text v0.31.0 h1:aC8ghyu4JhP8VojJ2lEHBnochRno1sgL6nEi9WGFGMM= -golang.org/x/text v0.31.0/go.mod h1:tKRAlv61yKIjGGHX/4tP1LTbc13YSec1pxVEWXzfoeM= -golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -gonum.org/v1/gonum v0.16.0 h1:5+ul4Swaf3ESvrOnidPp4GZbzf0mxVQpDCYUQE7OJfk= -gonum.org/v1/gonum v0.16.0/go.mod h1:fef3am4MQ93R2HHpKnLk4/Tbh/s0+wqD5nfa6Pnwy4E= -google.golang.org/genproto/googleapis/api v0.0.0-20251022142026-3a174f9686a8 h1:mepRgnBZa07I4TRuomDE4sTIYieg/osKmzIf4USdWS4= -google.golang.org/genproto/googleapis/api v0.0.0-20251022142026-3a174f9686a8/go.mod h1:fDMmzKV90WSg1NbozdqrE64fkuTv6mlq2zxo9ad+3yo= -google.golang.org/genproto/googleapis/rpc v0.0.0-20251022142026-3a174f9686a8 h1:M1rk8KBnUsBDg1oPGHNCxG4vc1f49epmTO7xscSajMk= -google.golang.org/genproto/googleapis/rpc v0.0.0-20251022142026-3a174f9686a8/go.mod h1:7i2o+ce6H/6BluujYR+kqX3GKH+dChPTQU19wjRPiGk= -google.golang.org/grpc v1.77.0 h1:wVVY6/8cGA6vvffn+wWK5ToddbgdU3d8MNENr4evgXM= -google.golang.org/grpc v1.77.0/go.mod h1:z0BY1iVj0q8E1uSQCjL9cppRj+gnZjzDnzV0dHhrNig= -google.golang.org/protobuf v1.36.10 h1:AYd7cD/uASjIL6Q9LiTjz8JLcrh/88q5UObnmY3aOOE= -google.golang.org/protobuf v1.36.10/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= +golang.org/x/sys v0.41.0 h1:Ivj+2Cp/ylzLiEU89QhWblYnOE9zerudt9Ftecq2C6k= +golang.org/x/sys v0.41.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= +golang.org/x/text v0.34.0 h1:oL/Qq0Kdaqxa1KbNeMKwQq0reLCCaFtqu2eNuSeNHbk= +golang.org/x/text v0.34.0/go.mod h1:homfLqTYRFyVYemLBFl5GgL/DWEiH5wcsQ5gSh1yziA= +gonum.org/v1/gonum v0.17.0 h1:VbpOemQlsSMrYmn7T2OUvQ4dqxQXU+ouZFQsZOx50z4= +gonum.org/v1/gonum v0.17.0/go.mod h1:El3tOrEuMpv2UdMrbNlKEh9vd86bmQ6vqIcDwxEOc1E= +google.golang.org/genproto/googleapis/api v0.0.0-20260226221140-a57be14db171 h1:tu/dtnW1o3wfaxCOjSLn5IRX4YDcJrtlpzYkhHhGaC4= +google.golang.org/genproto/googleapis/api v0.0.0-20260226221140-a57be14db171/go.mod h1:M5krXqk4GhBKvB596udGL3UyjL4I1+cTbK0orROM9ng= +google.golang.org/genproto/googleapis/rpc v0.0.0-20260226221140-a57be14db171 h1:ggcbiqK8WWh6l1dnltU4BgWGIGo+EVYxCaAPih/zQXQ= +google.golang.org/genproto/googleapis/rpc v0.0.0-20260226221140-a57be14db171/go.mod h1:4Hqkh8ycfw05ld/3BWL7rJOSfebL2Q+DVDeRgYgxUU8= +google.golang.org/grpc v1.79.3 h1:sybAEdRIEtvcD68Gx7dmnwjZKlyfuc61Dyo9pGXXkKE= +google.golang.org/grpc v1.79.3/go.mod h1:KmT0Kjez+0dde/v2j9vzwoAScgEPx/Bw1CYChhHLrHQ= +google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE= +google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= diff --git a/otelcol/internal/metadata/generated_feature_gates.go b/otelcol/internal/metadata/generated_feature_gates.go new file mode 100644 index 000000000000..7f0281a11d80 --- /dev/null +++ b/otelcol/internal/metadata/generated_feature_gates.go @@ -0,0 +1,15 @@ +// Code generated by mdatagen. DO NOT EDIT. + +package metadata + +import ( + "go.opentelemetry.io/collector/featuregate" +) + +var OtelcolPrintInitialConfigFeatureGate = featuregate.GlobalRegistry().MustRegister( + "otelcol.printInitialConfig", + featuregate.StageBeta, + featuregate.WithRegisterDescription("if set to true, enable the print-config command"), + featuregate.WithRegisterReferenceURL("https://github.com/open-telemetry/opentelemetry-collector/pull/11775"), + featuregate.WithRegisterFromVersion("v0.120.0"), +) diff --git a/otelcol/metadata.yaml b/otelcol/metadata.yaml index b27f5133bec1..d283d30e38c2 100644 --- a/otelcol/metadata.yaml +++ b/otelcol/metadata.yaml @@ -5,3 +5,13 @@ status: disable_codecov_badge: true class: pkg distributions: [core, contrib] + stability: + beta: [metrics, traces, logs] + development: [profiles] + +feature_gates: + - id: otelcol.printInitialConfig + description: 'if set to true, enable the print-config command' + stage: beta + from_version: 'v0.120.0' + reference_url: 'https://github.com/open-telemetry/opentelemetry-collector/pull/11775' diff --git a/otelcol/otelcoltest/go.mod b/otelcol/otelcoltest/go.mod index 3972b39b837f..6876c5ab6f85 100644 --- a/otelcol/otelcoltest/go.mod +++ b/otelcol/otelcoltest/go.mod @@ -1,24 +1,24 @@ module go.opentelemetry.io/collector/otelcol/otelcoltest -go 1.24.0 +go 1.25.0 require ( github.com/stretchr/testify v1.11.1 - go.opentelemetry.io/collector/component v1.46.0 - go.opentelemetry.io/collector/confmap v1.46.0 - go.opentelemetry.io/collector/confmap/provider/envprovider v1.46.0 - go.opentelemetry.io/collector/confmap/provider/fileprovider v1.46.0 - go.opentelemetry.io/collector/confmap/provider/httpprovider v1.46.0 - go.opentelemetry.io/collector/confmap/provider/yamlprovider v1.46.0 - go.opentelemetry.io/collector/confmap/xconfmap v0.140.0 - go.opentelemetry.io/collector/connector/connectortest v0.140.0 - go.opentelemetry.io/collector/exporter/exportertest v0.140.0 - go.opentelemetry.io/collector/extension/extensiontest v0.140.0 - go.opentelemetry.io/collector/otelcol v0.140.0 - go.opentelemetry.io/collector/pipeline v1.46.0 - go.opentelemetry.io/collector/processor/processortest v0.140.0 - go.opentelemetry.io/collector/receiver/receivertest v0.140.0 - go.opentelemetry.io/collector/service v0.140.0 + go.opentelemetry.io/collector/component v1.54.0 + go.opentelemetry.io/collector/confmap v1.54.0 + go.opentelemetry.io/collector/confmap/provider/envprovider v1.54.0 + go.opentelemetry.io/collector/confmap/provider/fileprovider v1.54.0 + go.opentelemetry.io/collector/confmap/provider/httpprovider v1.54.0 + go.opentelemetry.io/collector/confmap/provider/yamlprovider v1.54.0 + go.opentelemetry.io/collector/confmap/xconfmap v0.148.0 + go.opentelemetry.io/collector/connector/connectortest v0.148.0 + go.opentelemetry.io/collector/exporter/exportertest v0.148.0 + go.opentelemetry.io/collector/extension/extensiontest v0.148.0 + go.opentelemetry.io/collector/otelcol v0.148.0 + go.opentelemetry.io/collector/pipeline v1.54.0 + go.opentelemetry.io/collector/processor/processortest v0.148.0 + go.opentelemetry.io/collector/receiver/receivertest v0.148.0 + go.opentelemetry.io/collector/service v0.148.0 go.uber.org/goleak v1.3.0 ) @@ -26,103 +26,101 @@ require ( github.com/beorn7/perks v1.0.1 // indirect github.com/cenkalti/backoff/v5 v5.0.3 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect - github.com/davecgh/go-spew v1.1.1 // indirect - github.com/ebitengine/purego v0.9.0 // indirect + github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect + github.com/ebitengine/purego v0.10.0 // indirect github.com/go-logr/logr v1.4.3 // indirect github.com/go-logr/stdr v1.2.2 // indirect github.com/go-ole/go-ole v1.2.6 // indirect - github.com/go-viper/mapstructure/v2 v2.4.0 // indirect + github.com/go-viper/mapstructure/v2 v2.5.0 // indirect github.com/gobwas/glob v0.2.3 // indirect github.com/google/uuid v1.6.0 // indirect - github.com/grafana/regexp v0.0.0-20240518133315-a468a5bfb3bc // indirect - github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.2 // indirect - github.com/hashicorp/go-version v1.7.0 // indirect + github.com/grpc-ecosystem/grpc-gateway/v2 v2.28.0 // indirect + github.com/hashicorp/go-version v1.8.0 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/json-iterator/go v1.1.12 // indirect github.com/knadh/koanf/maps v0.1.2 // indirect github.com/knadh/koanf/providers/confmap v1.0.0 // indirect - github.com/knadh/koanf/v2 v2.3.0 // indirect - github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 // indirect + github.com/knadh/koanf/v2 v2.3.3 // indirect + github.com/lufia/plan9stats v0.0.0-20251013123823-9fd1530e3ec3 // indirect github.com/mitchellh/copystructure v1.2.0 // indirect github.com/mitchellh/reflectwalk v1.0.2 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee // indirect github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect - github.com/pmezard/go-difflib v1.0.0 // indirect + github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect github.com/power-devops/perfstat v0.0.0-20240221224432-82ca36839d55 // indirect github.com/prometheus/client_golang v1.23.2 // indirect github.com/prometheus/client_model v0.6.2 // indirect - github.com/prometheus/common v0.67.1 // indirect - github.com/prometheus/otlptranslator v0.0.2 // indirect - github.com/prometheus/procfs v0.17.0 // indirect - github.com/shirou/gopsutil/v4 v4.25.10 // indirect - github.com/spf13/cobra v1.10.1 // indirect - github.com/spf13/pflag v1.0.9 // indirect - github.com/tklauser/go-sysconf v0.3.15 // indirect - github.com/tklauser/numcpus v0.10.0 // indirect + github.com/prometheus/common v0.67.5 // indirect + github.com/prometheus/otlptranslator v1.0.0 // indirect + github.com/prometheus/procfs v0.20.1 // indirect + github.com/shirou/gopsutil/v4 v4.26.2 // indirect + github.com/spf13/cobra v1.10.2 // indirect + github.com/spf13/pflag v1.0.10 // indirect + github.com/tklauser/go-sysconf v0.3.16 // indirect + github.com/tklauser/numcpus v0.11.0 // indirect github.com/yusufpapurcu/wmi v1.2.4 // indirect go.opentelemetry.io/auto/sdk v1.2.1 // indirect - go.opentelemetry.io/collector/component/componentstatus v0.140.0 // indirect - go.opentelemetry.io/collector/component/componenttest v0.140.0 // indirect + go.opentelemetry.io/collector/component/componentstatus v0.148.0 // indirect + go.opentelemetry.io/collector/component/componenttest v0.148.0 // indirect go.opentelemetry.io/collector/config/configtelemetry v0.140.0 // indirect - go.opentelemetry.io/collector/connector v0.140.0 // indirect - go.opentelemetry.io/collector/connector/xconnector v0.140.0 // indirect - go.opentelemetry.io/collector/consumer v1.46.0 // indirect - go.opentelemetry.io/collector/consumer/consumererror v0.140.0 // indirect - go.opentelemetry.io/collector/consumer/consumertest v0.140.0 // indirect - go.opentelemetry.io/collector/consumer/xconsumer v0.140.0 // indirect - go.opentelemetry.io/collector/exporter v1.46.0 // indirect - go.opentelemetry.io/collector/exporter/xexporter v0.140.0 // indirect - go.opentelemetry.io/collector/extension v1.46.0 // indirect + go.opentelemetry.io/collector/connector v0.148.0 // indirect + go.opentelemetry.io/collector/connector/xconnector v0.148.0 // indirect + go.opentelemetry.io/collector/consumer v1.54.0 // indirect + go.opentelemetry.io/collector/consumer/consumererror v0.148.0 // indirect + go.opentelemetry.io/collector/consumer/consumertest v0.148.0 // indirect + go.opentelemetry.io/collector/consumer/xconsumer v0.148.0 // indirect + go.opentelemetry.io/collector/exporter v1.54.0 // indirect + go.opentelemetry.io/collector/exporter/xexporter v0.148.0 // indirect + go.opentelemetry.io/collector/extension v1.54.0 // indirect go.opentelemetry.io/collector/extension/extensioncapabilities v0.140.0 // indirect - go.opentelemetry.io/collector/featuregate v1.46.0 // indirect - go.opentelemetry.io/collector/internal/fanoutconsumer v0.140.0 // indirect + go.opentelemetry.io/collector/featuregate v1.54.0 // indirect + go.opentelemetry.io/collector/internal/componentalias v0.148.0 // indirect + go.opentelemetry.io/collector/internal/fanoutconsumer v0.148.0 // indirect go.opentelemetry.io/collector/internal/telemetry v0.140.0 // indirect - go.opentelemetry.io/collector/pdata v1.46.0 // indirect - go.opentelemetry.io/collector/pdata/pprofile v0.140.0 // indirect - go.opentelemetry.io/collector/pdata/testdata v0.140.0 // indirect + go.opentelemetry.io/collector/pdata v1.54.0 // indirect + go.opentelemetry.io/collector/pdata/pprofile v0.148.0 // indirect + go.opentelemetry.io/collector/pdata/testdata v0.148.0 // indirect go.opentelemetry.io/collector/pdata/xpdata v0.140.0 // indirect - go.opentelemetry.io/collector/pipeline/xpipeline v0.140.0 // indirect - go.opentelemetry.io/collector/processor v1.46.0 // indirect - go.opentelemetry.io/collector/processor/xprocessor v0.140.0 // indirect - go.opentelemetry.io/collector/receiver v1.46.0 // indirect - go.opentelemetry.io/collector/receiver/xreceiver v0.140.0 // indirect + go.opentelemetry.io/collector/pipeline/xpipeline v0.148.0 // indirect + go.opentelemetry.io/collector/processor v1.54.0 // indirect + go.opentelemetry.io/collector/processor/xprocessor v0.148.0 // indirect + go.opentelemetry.io/collector/receiver v1.54.0 // indirect + go.opentelemetry.io/collector/receiver/xreceiver v0.148.0 // indirect go.opentelemetry.io/collector/service/hostcapabilities v0.140.0 // indirect - go.opentelemetry.io/contrib/bridges/otelzap v0.13.0 // indirect go.opentelemetry.io/contrib/otelconf v0.18.0 // indirect - go.opentelemetry.io/contrib/propagators/b3 v1.38.0 // indirect - go.opentelemetry.io/otel v1.40.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.14.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.14.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.38.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.38.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.38.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.38.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.38.0 // indirect - go.opentelemetry.io/otel/exporters/prometheus v0.60.0 // indirect - go.opentelemetry.io/otel/exporters/stdout/stdoutlog v0.14.0 // indirect - go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.38.0 // indirect - go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.38.0 // indirect - go.opentelemetry.io/otel/log v0.14.0 // indirect - go.opentelemetry.io/otel/metric v1.40.0 // indirect - go.opentelemetry.io/otel/sdk v1.40.0 // indirect - go.opentelemetry.io/otel/sdk/log v0.14.0 // indirect - go.opentelemetry.io/otel/sdk/metric v1.40.0 // indirect - go.opentelemetry.io/otel/trace v1.40.0 // indirect - go.opentelemetry.io/proto/otlp v1.7.1 // indirect + go.opentelemetry.io/otel v1.42.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.18.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.18.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.42.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.42.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.42.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.42.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.42.0 // indirect + go.opentelemetry.io/otel/exporters/prometheus v0.64.0 // indirect + go.opentelemetry.io/otel/exporters/stdout/stdoutlog v0.18.0 // indirect + go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.42.0 // indirect + go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.42.0 // indirect + go.opentelemetry.io/otel/log v0.18.0 // indirect + go.opentelemetry.io/otel/metric v1.42.0 // indirect + go.opentelemetry.io/otel/sdk v1.42.0 // indirect + go.opentelemetry.io/otel/sdk/log v0.18.0 // indirect + go.opentelemetry.io/otel/sdk/metric v1.42.0 // indirect + go.opentelemetry.io/otel/trace v1.42.0 // indirect + go.opentelemetry.io/proto/otlp v1.10.0 // indirect go.uber.org/multierr v1.11.0 // indirect go.uber.org/zap v1.27.1 // indirect go.yaml.in/yaml/v2 v2.4.3 // indirect go.yaml.in/yaml/v3 v3.0.4 // indirect golang.org/x/exp v0.0.0-20240506185415-9bf2ced13842 // indirect - golang.org/x/net v0.47.0 // indirect - golang.org/x/sys v0.40.0 // indirect - golang.org/x/text v0.31.0 // indirect - gonum.org/v1/gonum v0.16.0 // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20251022142026-3a174f9686a8 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20251022142026-3a174f9686a8 // indirect - google.golang.org/grpc v1.77.0 // indirect - google.golang.org/protobuf v1.36.10 // indirect + golang.org/x/net v0.51.0 // indirect + golang.org/x/sys v0.41.0 // indirect + golang.org/x/text v0.34.0 // indirect + gonum.org/v1/gonum v0.17.0 // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20260226221140-a57be14db171 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20260226221140-a57be14db171 // indirect + google.golang.org/grpc v1.79.3 // indirect + google.golang.org/protobuf v1.36.11 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) @@ -243,3 +241,7 @@ replace go.opentelemetry.io/collector/exporter/exporterhelper => ../../exporter/ replace go.opentelemetry.io/collector/config/configoptional => ../../config/configoptional replace go.opentelemetry.io/collector/internal/testutil => ../../internal/testutil + +replace go.opentelemetry.io/collector/internal/componentalias => ../../internal/componentalias + +replace go.opentelemetry.io/collector/config/confignet => ../../config/confignet diff --git a/otelcol/otelcoltest/go.sum b/otelcol/otelcoltest/go.sum index 148f8cb6367d..04d5b2da6513 100644 --- a/otelcol/otelcoltest/go.sum +++ b/otelcol/otelcoltest/go.sum @@ -6,14 +6,15 @@ github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UF github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/ebitengine/purego v0.9.0 h1:mh0zpKBIXDceC63hpvPuGLiJ8ZAa3DfrFTudmfi8A4k= -github.com/ebitengine/purego v0.9.0/go.mod h1:iIjxzd6CiRiOG0UyXP+V1+jWqUXVjPKLAI0mRfJZTmQ= +github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= +github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/ebitengine/purego v0.10.0 h1:QIw4xfpWT6GWTzaW5XEKy3HXoqrJGx1ijYHzTF0/ISU= +github.com/ebitengine/purego v0.10.0/go.mod h1:iIjxzd6CiRiOG0UyXP+V1+jWqUXVjPKLAI0mRfJZTmQ= github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg= github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= -github.com/foxboron/go-tpm-keyfiles v0.0.0-20250903184740-5d135037bd4d h1:EdO/NMMuCZfxhdzTZLuKAciQSnI2DV+Ppg8+vAYrnqA= -github.com/foxboron/go-tpm-keyfiles v0.0.0-20250903184740-5d135037bd4d/go.mod h1:uAyTlAUxchYuiFjTHmuIEJ4nGSm7iOPaGcAyA81fJ80= +github.com/foxboron/go-tpm-keyfiles v0.0.0-20251226215517-609e4778396f h1:RJ+BDPLSHQO7cSjKBqjPJSbi1qfk9WcsjQDtZiw3dZw= +github.com/foxboron/go-tpm-keyfiles v0.0.0-20251226215517-609e4778396f/go.mod h1:VHbbch/X4roIY22jL1s3qRbZhCiRIgUAF/PdSUcx2io= github.com/fsnotify/fsnotify v1.9.0 h1:2Ml+OJNzbYCTzsxtv8vKSFD9PbJjmhYF14k/jKC7S9k= github.com/fsnotify/fsnotify v1.9.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= @@ -23,48 +24,47 @@ github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY= github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0= -github.com/go-viper/mapstructure/v2 v2.4.0 h1:EBsztssimR/CONLSZZ04E8qAkxNYq4Qp9LvH92wZUgs= -github.com/go-viper/mapstructure/v2 v2.4.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM= +github.com/go-viper/mapstructure/v2 v2.5.0 h1:vM5IJoUAy3d7zRSVtIwQgBj7BiWtMPfmPEgAXnvj1Ro= +github.com/go-viper/mapstructure/v2 v2.5.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM= github.com/gobwas/glob v0.2.3 h1:A4xDbljILXROh+kObIiy5kIaPYD8e96x1tgBhUI5J+Y= github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8= github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= github.com/golang/snappy v1.0.0 h1:Oy607GVXHs7RtbggtPBnr2RmDArIsAefDwvrdWvRhGs= github.com/golang/snappy v1.0.0/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= -github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= -github.com/google/go-tpm v0.9.7 h1:u89J4tUUeDTlH8xxC3CTW7OHZjbjKoHdQ9W7gCUhtxA= -github.com/google/go-tpm v0.9.7/go.mod h1:h9jEsEECg7gtLis0upRBQU+GhYVH6jMjrFxI8u6bVUY= +github.com/google/go-tpm v0.9.8 h1:slArAR9Ft+1ybZu0lBwpSmpwhRXaa85hWtMinMyRAWo= +github.com/google/go-tpm v0.9.8/go.mod h1:h9jEsEECg7gtLis0upRBQU+GhYVH6jMjrFxI8u6bVUY= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/grafana/regexp v0.0.0-20240518133315-a468a5bfb3bc h1:GN2Lv3MGO7AS6PrRoT6yV5+wkrOpcszoIsO4+4ds248= -github.com/grafana/regexp v0.0.0-20240518133315-a468a5bfb3bc/go.mod h1:+JKpmjMGhpgPL+rXZ5nsZieVzvarn86asRlBg4uNGnk= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.2 h1:8Tjv8EJ+pM1xP8mK6egEbD1OgnVTyacbefKhmbLhIhU= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.2/go.mod h1:pkJQ2tZHJ0aFOVEEot6oZmaVEZcRme73eIFmhiVuRWs= -github.com/hashicorp/go-version v1.7.0 h1:5tqGy27NaOTB8yJKUZELlFAS/LTKJkrmONwQKeRZfjY= -github.com/hashicorp/go-version v1.7.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.28.0 h1:HWRh5R2+9EifMyIHV7ZV+MIZqgz+PMpZ14Jynv3O2Zs= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.28.0/go.mod h1:JfhWUomR1baixubs02l85lZYYOm7LV6om4ceouMv45c= +github.com/hashicorp/go-version v1.8.0 h1:KAkNb1HAiZd1ukkxDFGmokVZe1Xy9HG6NUp+bPle2i4= +github.com/hashicorp/go-version v1.8.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= +github.com/hashicorp/golang-lru/v2 v2.0.7 h1:a+bsQ5rvGLjzHuww6tVxozPZFVghXaHOwFs4luLUK2k= +github.com/hashicorp/golang-lru/v2 v2.0.7/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyfM2/ZepoAG6RGpeM= github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= -github.com/klauspost/compress v1.18.1 h1:bcSGx7UbpBqMChDtsF28Lw6v/G94LPrrbMbdC3JH2co= -github.com/klauspost/compress v1.18.1/go.mod h1:ZQFFVG+MdnR0P+l6wpXgIL4NTtwiKIdBnrBd8Nrxr+0= +github.com/klauspost/compress v1.18.4 h1:RPhnKRAQ4Fh8zU2FY/6ZFDwTVTxgJ/EMydqSTzE9a2c= +github.com/klauspost/compress v1.18.4/go.mod h1:R0h/fSBs8DE4ENlcrlib3PsXS61voFxhIs2DeRhCvJ4= github.com/knadh/koanf/maps v0.1.2 h1:RBfmAW5CnZT+PJ1CVc1QSJKf4Xu9kxfQgYVQSu8hpbo= github.com/knadh/koanf/maps v0.1.2/go.mod h1:npD/QZY3V6ghQDdcQzl1W4ICNVTkohC8E73eI2xW4yI= github.com/knadh/koanf/providers/confmap v1.0.0 h1:mHKLJTE7iXEys6deO5p6olAiZdG5zwp8Aebir+/EaRE= github.com/knadh/koanf/providers/confmap v1.0.0/go.mod h1:txHYHiI2hAtF0/0sCmcuol4IDcuQbKTybiB1nOcUo1A= -github.com/knadh/koanf/v2 v2.3.0 h1:Qg076dDRFHvqnKG97ZEsi9TAg2/nFTa9hCdcSa1lvlM= -github.com/knadh/koanf/v2 v2.3.0/go.mod h1:gRb40VRAbd4iJMYYD5IxZ6hfuopFcXBpc9bbQpZwo28= +github.com/knadh/koanf/v2 v2.3.3 h1:jLJC8XCRfLC7n4F+ZKKdBsbq1bfXTpuFhf4L7t94D94= +github.com/knadh/koanf/v2 v2.3.3/go.mod h1:gRb40VRAbd4iJMYYD5IxZ6hfuopFcXBpc9bbQpZwo28= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc= github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= -github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 h1:6E+4a0GO5zZEnZ81pIr0yLvtUWk2if982qA3F3QD6H4= -github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0/go.mod h1:zJYVVT2jmtg6P3p1VtQj7WsuWi/y4VnjVBn7F8KPB3I= +github.com/lufia/plan9stats v0.0.0-20251013123823-9fd1530e3ec3 h1:PwQumkgq4/acIiZhtifTV5OUqqiP82UAl0h87xj/l9k= +github.com/lufia/plan9stats v0.0.0-20251013123823-9fd1530e3ec3/go.mod h1:autxFIvghDt3jPTLoqZ9OZ7s9qTGNAWmYCjVFWPX/zg= github.com/mitchellh/copystructure v1.2.0 h1:vpKXTN4ewci03Vljg/q9QvCGUDttBOGBIa15WveJJGw= github.com/mitchellh/copystructure v1.2.0/go.mod h1:qLl+cE2AmVv+CoeAwDPye/v+N2HKCj9FbZEVFJRxO9s= github.com/mitchellh/reflectwalk v1.0.2 h1:G2LzWKi524PWgd3mLHV8Y5k7s6XUvT0Gef6zxSIeXaQ= @@ -77,103 +77,99 @@ github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee h1:W5t00kpgFd github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= -github.com/pierrec/lz4/v4 v4.1.22 h1:cKFw6uJDK+/gfw5BcDL0JL5aBsAFdsIT18eRtLj7VIU= -github.com/pierrec/lz4/v4 v4.1.22/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4= -github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pierrec/lz4/v4 v4.1.26 h1:GrpZw1gZttORinvzBdXPUXATeqlJjqUG/D87TKMnhjY= +github.com/pierrec/lz4/v4 v4.1.26/go.mod h1:EoQMVJgeeEOMsCqCzqFm2O0cJvljX2nGZjcRIPL34O4= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= +github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/power-devops/perfstat v0.0.0-20240221224432-82ca36839d55 h1:o4JXh1EVt9k/+g42oCprj/FisM4qX9L3sZB3upGN2ZU= github.com/power-devops/perfstat v0.0.0-20240221224432-82ca36839d55/go.mod h1:OmDBASR4679mdNQnz2pUhc2G8CO2JrUAVFDRBDP/hJE= github.com/prometheus/client_golang v1.23.2 h1:Je96obch5RDVy3FDMndoUsjAhG5Edi49h0RJWRi/o0o= github.com/prometheus/client_golang v1.23.2/go.mod h1:Tb1a6LWHB3/SPIzCoaDXI4I8UHKeFTEQ1YCr+0Gyqmg= github.com/prometheus/client_model v0.6.2 h1:oBsgwpGs7iVziMvrGhE53c/GrLUsZdHnqNwqPLxwZyk= github.com/prometheus/client_model v0.6.2/go.mod h1:y3m2F6Gdpfy6Ut/GBsUqTWZqCUvMVzSfMLjcu6wAwpE= -github.com/prometheus/common v0.67.1 h1:OTSON1P4DNxzTg4hmKCc37o4ZAZDv0cfXLkOt0oEowI= -github.com/prometheus/common v0.67.1/go.mod h1:RpmT9v35q2Y+lsieQsdOh5sXZ6ajUGC8NjZAmr8vb0Q= -github.com/prometheus/otlptranslator v0.0.2 h1:+1CdeLVrRQ6Psmhnobldo0kTp96Rj80DRXRd5OSnMEQ= -github.com/prometheus/otlptranslator v0.0.2/go.mod h1:P8AwMgdD7XEr6QRUJ2QWLpiAZTgTE2UYgjlu3svompI= -github.com/prometheus/procfs v0.17.0 h1:FuLQ+05u4ZI+SS/w9+BWEM2TXiHKsUQ9TADiRH7DuK0= -github.com/prometheus/procfs v0.17.0/go.mod h1:oPQLaDAMRbA+u8H5Pbfq+dl3VDAvHxMUOVhe0wYB2zw= +github.com/prometheus/common v0.67.5 h1:pIgK94WWlQt1WLwAC5j2ynLaBRDiinoAb86HZHTUGI4= +github.com/prometheus/common v0.67.5/go.mod h1:SjE/0MzDEEAyrdr5Gqc6G+sXI67maCxzaT3A2+HqjUw= +github.com/prometheus/otlptranslator v1.0.0 h1:s0LJW/iN9dkIH+EnhiD3BlkkP5QVIUVEoIwkU+A6qos= +github.com/prometheus/otlptranslator v1.0.0/go.mod h1:vRYWnXvI6aWGpsdY/mOT/cbeVRBlPWtBNDb7kGR3uKM= +github.com/prometheus/procfs v0.20.1 h1:XwbrGOIplXW/AU3YhIhLODXMJYyC1isLFfYCsTEycfc= +github.com/prometheus/procfs v0.20.1/go.mod h1:o9EMBZGRyvDrSPH1RqdxhojkuXstoe4UlK79eF5TGGo= github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ= github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc= github.com/rs/cors v1.11.1 h1:eU3gRzXLRK57F5rKMGMZURNdIG4EoAmX8k94r9wXWHA= github.com/rs/cors v1.11.1/go.mod h1:XyqrcTp5zjWr1wsJ8PIRZssZ8b/WMcMf71DJnit4EMU= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= -github.com/shirou/gopsutil/v4 v4.25.10 h1:at8lk/5T1OgtuCp+AwrDofFRjnvosn0nkN2OLQ6g8tA= -github.com/shirou/gopsutil/v4 v4.25.10/go.mod h1:+kSwyC8DRUD9XXEHCAFjK+0nuArFJM0lva+StQAcskM= -github.com/spf13/cobra v1.10.1 h1:lJeBwCfmrnXthfAupyUTzJ/J4Nc1RsHC/mSRU2dll/s= -github.com/spf13/cobra v1.10.1/go.mod h1:7SmJGaTHFVBY0jW4NXGluQoLvhqFQM+6XSKD+P4XaB0= -github.com/spf13/pflag v1.0.9 h1:9exaQaMOCwffKiiiYk6/BndUBv+iRViNW+4lEMi0PvY= +github.com/shirou/gopsutil/v4 v4.26.2 h1:X8i6sicvUFih4BmYIGT1m2wwgw2VG9YgrDTi7cIRGUI= +github.com/shirou/gopsutil/v4 v4.26.2/go.mod h1:LZ6ewCSkBqUpvSOf+LsTGnRinC6iaNUNMGBtDkJBaLQ= +github.com/spf13/cobra v1.10.2 h1:DMTTonx5m65Ic0GOoRY2c16WCbHxOOw6xxezuLaBpcU= +github.com/spf13/cobra v1.10.2/go.mod h1:7C1pvHqHw5A4vrJfjNwvOdzYu0Gml16OCs2GRiTUUS4= github.com/spf13/pflag v1.0.9/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= +github.com/spf13/pflag v1.0.10 h1:4EBh2KAYBwaONj6b2Ye1GiHfwjqyROoF4RwYO+vPwFk= +github.com/spf13/pflag v1.0.10/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U= github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= -github.com/tklauser/go-sysconf v0.3.15 h1:VE89k0criAymJ/Os65CSn1IXaol+1wrsFHEB8Ol49K4= -github.com/tklauser/go-sysconf v0.3.15/go.mod h1:Dmjwr6tYFIseJw7a3dRLJfsHAMXZ3nEnL/aZY+0IuI4= -github.com/tklauser/numcpus v0.10.0 h1:18njr6LDBk1zuna922MgdjQuJFjrdppsZG60sHGfjso= -github.com/tklauser/numcpus v0.10.0/go.mod h1:BiTKazU708GQTYF4mB+cmlpT2Is1gLk7XVuEeem8LsQ= +github.com/tklauser/go-sysconf v0.3.16 h1:frioLaCQSsF5Cy1jgRBrzr6t502KIIwQ0MArYICU0nA= +github.com/tklauser/go-sysconf v0.3.16/go.mod h1:/qNL9xxDhc7tx3HSRsLWNnuzbVfh3e7gh/BmM179nYI= +github.com/tklauser/numcpus v0.11.0 h1:nSTwhKH5e1dMNsCdVBukSZrURJRoHbSEQjdEbY+9RXw= +github.com/tklauser/numcpus v0.11.0/go.mod h1:z+LwcLq54uWZTX0u/bGobaV34u6V7KNlTZejzM6/3MQ= github.com/yusufpapurcu/wmi v1.2.4 h1:zFUKzehAFReQwLys1b/iSMl+JQGSCSjtVqQn9bBrPo0= github.com/yusufpapurcu/wmi v1.2.4/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0= go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64= go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y= -go.opentelemetry.io/contrib/bridges/otelzap v0.13.0 h1:aBKdhLVieqvwWe9A79UHI/0vgp2t/s2euY8X59pGRlw= -go.opentelemetry.io/contrib/bridges/otelzap v0.13.0/go.mod h1:SYqtxLQE7iINgh6WFuVi2AI70148B8EI35DSk0Wr8m4= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.63.0 h1:RbKq8BG0FI8OiXhBfcRtqqHcZcka+gU3cskNuf05R18= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.63.0/go.mod h1:h06DGIukJOevXaj/xrNjhi/2098RZzcLTbc0jDAUbsg= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.67.0 h1:OyrsyzuttWTSur2qN/Lm0m2a8yqyIjUVBZcxFPuXq2o= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.67.0/go.mod h1:C2NGBr+kAB4bk3xtMXfZ94gqFDtg/GkI7e9zqGh5Beg= go.opentelemetry.io/contrib/otelconf v0.18.0 h1:ciF2Gf00BWs0DnexKFZXcxg9kJ8r3SUW1LOzW3CsKA8= go.opentelemetry.io/contrib/otelconf v0.18.0/go.mod h1:FcP7k+JLwBLdOxS6qY6VQ/4b5VBntI6L6o80IMwhAeI= -go.opentelemetry.io/contrib/propagators/b3 v1.38.0 h1:uHsCCOSKl0kLrV2dLkFK+8Ywk9iKa/fptkytc6aFFEo= -go.opentelemetry.io/contrib/propagators/b3 v1.38.0/go.mod h1:wMRSZJZcY8ya9mApLLhwIMjqmApy2o/Ml+62lhvxyHU= -go.opentelemetry.io/contrib/zpages v0.63.0 h1:TppOKuZGbqXMgsfjqq3i09N5Vbo1JLtLImUqiTPGnX4= -go.opentelemetry.io/contrib/zpages v0.63.0/go.mod h1:5F8uugz75ay/MMhRRhxAXY33FuaI8dl7jTxefrIy5qk= -go.opentelemetry.io/otel v1.40.0 h1:oA5YeOcpRTXq6NN7frwmwFR0Cn3RhTVZvXsP4duvCms= -go.opentelemetry.io/otel v1.40.0/go.mod h1:IMb+uXZUKkMXdPddhwAHm6UfOwJyh4ct1ybIlV14J0g= -go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.14.0 h1:OMqPldHt79PqWKOMYIAQs3CxAi7RLgPxwfFSwr4ZxtM= -go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.14.0/go.mod h1:1biG4qiqTxKiUCtoWDPpL3fB3KxVwCiGw81j3nKMuHE= -go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.14.0 h1:QQqYw3lkrzwVsoEX0w//EhH/TCnpRdEenKBOOEIMjWc= -go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.14.0/go.mod h1:gSVQcr17jk2ig4jqJ2DX30IdWH251JcNAecvrqTxH1s= -go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.38.0 h1:vl9obrcoWVKp/lwl8tRE33853I8Xru9HFbw/skNeLs8= -go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.38.0/go.mod h1:GAXRxmLJcVM3u22IjTg74zWBrRCKq8BnOqUVLodpcpw= -go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.38.0 h1:Oe2z/BCg5q7k4iXC3cqJxKYg0ieRiOqF0cecFYdPTwk= -go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.38.0/go.mod h1:ZQM5lAJpOsKnYagGg/zV2krVqTtaVdYdDkhMoX6Oalg= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.38.0 h1:GqRJVj7UmLjCVyVJ3ZFLdPRmhDUp2zFmQe3RHIOsw24= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.38.0/go.mod h1:ri3aaHSmCTVYu2AWv44YMauwAQc0aqI9gHKIcSbI1pU= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.38.0 h1:lwI4Dc5leUqENgGuQImwLo4WnuXFPetmPpkLi2IrX54= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.38.0/go.mod h1:Kz/oCE7z5wuyhPxsXDuaPteSWqjSBD5YaSdbxZYGbGk= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.38.0 h1:aTL7F04bJHUlztTsNGJ2l+6he8c+y/b//eR0jjjemT4= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.38.0/go.mod h1:kldtb7jDTeol0l3ewcmd8SDvx3EmIE7lyvqbasU3QC4= -go.opentelemetry.io/otel/exporters/prometheus v0.60.0 h1:cGtQxGvZbnrWdC2GyjZi0PDKVSLWP/Jocix3QWfXtbo= -go.opentelemetry.io/otel/exporters/prometheus v0.60.0/go.mod h1:hkd1EekxNo69PTV4OWFGZcKQiIqg0RfuWExcPKFvepk= -go.opentelemetry.io/otel/exporters/stdout/stdoutlog v0.14.0 h1:B/g+qde6Mkzxbry5ZZag0l7QrQBCtVm7lVjaLgmpje8= -go.opentelemetry.io/otel/exporters/stdout/stdoutlog v0.14.0/go.mod h1:mOJK8eMmgW6ocDJn6Bn11CcZ05gi3P8GylBXEkZtbgA= -go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.38.0 h1:wm/Q0GAAykXv83wzcKzGGqAnnfLFyFe7RslekZuv+VI= -go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.38.0/go.mod h1:ra3Pa40+oKjvYh+ZD3EdxFZZB0xdMfuileHAm4nNN7w= -go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.38.0 h1:kJxSDN4SgWWTjG/hPp3O7LCGLcHXFlvS2/FFOrwL+SE= -go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.38.0/go.mod h1:mgIOzS7iZeKJdeB8/NYHrJ48fdGc71Llo5bJ1J4DWUE= -go.opentelemetry.io/otel/log v0.14.0 h1:2rzJ+pOAZ8qmZ3DDHg73NEKzSZkhkGIua9gXtxNGgrM= -go.opentelemetry.io/otel/log v0.14.0/go.mod h1:5jRG92fEAgx0SU/vFPxmJvhIuDU9E1SUnEQrMlJpOno= -go.opentelemetry.io/otel/log/logtest v0.14.0 h1:BGTqNeluJDK2uIHAY8lRqxjVAYfqgcaTbVk1n3MWe5A= -go.opentelemetry.io/otel/log/logtest v0.14.0/go.mod h1:IuguGt8XVP4XA4d2oEEDMVDBBCesMg8/tSGWDjuKfoA= -go.opentelemetry.io/otel/metric v1.40.0 h1:rcZe317KPftE2rstWIBitCdVp89A2HqjkxR3c11+p9g= -go.opentelemetry.io/otel/metric v1.40.0/go.mod h1:ib/crwQH7N3r5kfiBZQbwrTge743UDc7DTFVZrrXnqc= -go.opentelemetry.io/otel/sdk v1.40.0 h1:KHW/jUzgo6wsPh9At46+h4upjtccTmuZCFAc9OJ71f8= -go.opentelemetry.io/otel/sdk v1.40.0/go.mod h1:Ph7EFdYvxq72Y8Li9q8KebuYUr2KoeyHx0DRMKrYBUE= -go.opentelemetry.io/otel/sdk/log v0.14.0 h1:JU/U3O7N6fsAXj0+CXz21Czg532dW2V4gG1HE/e8Zrg= -go.opentelemetry.io/otel/sdk/log v0.14.0/go.mod h1:imQvII+0ZylXfKU7/wtOND8Hn4OpT3YUoIgqJVksUkM= -go.opentelemetry.io/otel/sdk/log/logtest v0.14.0 h1:Ijbtz+JKXl8T2MngiwqBlPaHqc4YCaP/i13Qrow6gAM= -go.opentelemetry.io/otel/sdk/log/logtest v0.14.0/go.mod h1:dCU8aEL6q+L9cYTqcVOk8rM9Tp8WdnHOPLiBgp0SGOA= -go.opentelemetry.io/otel/sdk/metric v1.40.0 h1:mtmdVqgQkeRxHgRv4qhyJduP3fYJRMX4AtAlbuWdCYw= -go.opentelemetry.io/otel/sdk/metric v1.40.0/go.mod h1:4Z2bGMf0KSK3uRjlczMOeMhKU2rhUqdWNoKcYrtcBPg= -go.opentelemetry.io/otel/trace v1.40.0 h1:WA4etStDttCSYuhwvEa8OP8I5EWu24lkOzp+ZYblVjw= -go.opentelemetry.io/otel/trace v1.40.0/go.mod h1:zeAhriXecNGP/s2SEG3+Y8X9ujcJOTqQ5RgdEJcawiA= -go.opentelemetry.io/proto/otlp v1.7.1 h1:gTOMpGDb0WTBOP8JaO72iL3auEZhVmAQg4ipjOVAtj4= -go.opentelemetry.io/proto/otlp v1.7.1/go.mod h1:b2rVh6rfI/s2pHWNlB7ILJcRALpcNDzKhACevjI+ZnE= -go.opentelemetry.io/proto/slim/otlp v1.9.0 h1:fPVMv8tP3TrsqlkH1HWYUpbCY9cAIemx184VGkS6vlE= -go.opentelemetry.io/proto/slim/otlp v1.9.0/go.mod h1:xXdeJJ90Gqyll+orzUkY4bOd2HECo5JofeoLpymVqdI= -go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.2.0 h1:o13nadWDNkH/quoDomDUClnQBpdQQ2Qqv0lQBjIXjE8= -go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.2.0/go.mod h1:Gyb6Xe7FTi/6xBHwMmngGoHqL0w29Y4eW8TGFzpefGA= -go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.2.0 h1:EiUYvtwu6PMrMHVjcPfnsG3v+ajPkbUeH+IL93+QYyk= -go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.2.0/go.mod h1:mUUHKFiN2SST3AhJ8XhJxEoeVW12oqfXog0Bo8W3Ec4= +go.opentelemetry.io/contrib/zpages v0.67.0 h1:cIUwWSVDovuLEbDIKreptjdxMuIhGiqwq0uL8YNaq1c= +go.opentelemetry.io/contrib/zpages v0.67.0/go.mod h1:vK8fsYHgPYg4Z/XDbFSEvItSGZDbjWTvjBOu8+AiDhc= +go.opentelemetry.io/otel v1.42.0 h1:lSQGzTgVR3+sgJDAU/7/ZMjN9Z+vUip7leaqBKy4sho= +go.opentelemetry.io/otel v1.42.0/go.mod h1:lJNsdRMxCUIWuMlVJWzecSMuNjE7dOYyWlqOXWkdqCc= +go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.18.0 h1:deI9UQMoGFgrg5iLPgzueqFPHevDl+28YKfSpPTI6rY= +go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.18.0/go.mod h1:PFx9NgpNUKXdf7J4Q3agRxMs3Y07QhTCVipKmLsMKnU= +go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.18.0 h1:icqq3Z34UrEFk2u+HMhTtRsvo7Ues+eiJVjaJt62njs= +go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.18.0/go.mod h1:W2m8P+d5Wn5kipj4/xmbt9uMqezEKfBjzVJadfABSBE= +go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.42.0 h1:MdKucPl/HbzckWWEisiNqMPhRrAOQX8r4jTuGr636gk= +go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.42.0/go.mod h1:RolT8tWtfHcjajEH5wFIZ4Dgh5jpPdFXYV9pTAk/qjc= +go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.42.0 h1:H7O6RlGOMTizyl3R08Kn5pdM06bnH8oscSj7o11tmLA= +go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.42.0/go.mod h1:mBFWu/WOVDkWWsR7Tx7h6EpQB8wsv7P0Yrh0Pb7othc= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.42.0 h1:THuZiwpQZuHPul65w4WcwEnkX2QIuMT+UFoOrygtoJw= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.42.0/go.mod h1:J2pvYM5NGHofZ2/Ru6zw/TNWnEQp5crgyDeSrYpXkAw= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.42.0 h1:zWWrB1U6nqhS/k6zYB74CjRpuiitRtLLi68VcgmOEto= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.42.0/go.mod h1:2qXPNBX1OVRC0IwOnfo1ljoid+RD0QK3443EaqVlsOU= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.42.0 h1:uLXP+3mghfMf7XmV4PkGfFhFKuNWoCvvx5wP/wOXo0o= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.42.0/go.mod h1:v0Tj04armyT59mnURNUJf7RCKcKzq+lgJs6QSjHjaTc= +go.opentelemetry.io/otel/exporters/prometheus v0.64.0 h1:g0LRDXMX/G1SEZtK8zl8Chm4K6GBwRkjPKE36LxiTYs= +go.opentelemetry.io/otel/exporters/prometheus v0.64.0/go.mod h1:UrgcjnarfdlBDP3GjDIJWe6HTprwSazNjwsI+Ru6hro= +go.opentelemetry.io/otel/exporters/stdout/stdoutlog v0.18.0 h1:KJVjPD3rcPb98rIs3HznyJlrfx9ge5oJvxxlGR+P/7s= +go.opentelemetry.io/otel/exporters/stdout/stdoutlog v0.18.0/go.mod h1:K3kRa2ckmHWQaTWQdPRHc7qGXASuVuoEQXzrvlA98Ws= +go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.42.0 h1:lSZHgNHfbmQTPfuTmWVkEu8J8qXaQwuV30pjCcAUvP8= +go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.42.0/go.mod h1:so9ounLcuoRDu033MW/E0AD4hhUjVqswrMF5FoZlBcw= +go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.42.0 h1:s/1iRkCKDfhlh1JF26knRneorus8aOwVIDhvYx9WoDw= +go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.42.0/go.mod h1:UI3wi0FXg1Pofb8ZBiBLhtMzgoTm1TYkMvn71fAqDzs= +go.opentelemetry.io/otel/log v0.18.0 h1:XgeQIIBjZZrliksMEbcwMZefoOSMI1hdjiLEiiB0bAg= +go.opentelemetry.io/otel/log v0.18.0/go.mod h1:KEV1kad0NofR3ycsiDH4Yjcoj0+8206I6Ox2QYFSNgI= +go.opentelemetry.io/otel/metric v1.42.0 h1:2jXG+3oZLNXEPfNmnpxKDeZsFI5o4J+nz6xUlaFdF/4= +go.opentelemetry.io/otel/metric v1.42.0/go.mod h1:RlUN/7vTU7Ao/diDkEpQpnz3/92J9ko05BIwxYa2SSI= +go.opentelemetry.io/otel/sdk v1.42.0 h1:LyC8+jqk6UJwdrI/8VydAq/hvkFKNHZVIWuslJXYsDo= +go.opentelemetry.io/otel/sdk v1.42.0/go.mod h1:rGHCAxd9DAph0joO4W6OPwxjNTYWghRWmkHuGbayMts= +go.opentelemetry.io/otel/sdk/log v0.18.0 h1:n8OyZr7t7otkeTnPTbDNom6rW16TBYGtvyy2Gk6buQw= +go.opentelemetry.io/otel/sdk/log v0.18.0/go.mod h1:C0+wxkTwKpOCZLrlJ3pewPiiQwpzycPI/u6W0Z9fuYk= +go.opentelemetry.io/otel/sdk/log/logtest v0.18.0 h1:l3mYuPsuBx6UKE47BVcPrZoZ0q/KER57vbj2qkgDLXA= +go.opentelemetry.io/otel/sdk/log/logtest v0.18.0/go.mod h1:7cHtiVJpZebB3wybTa4NG+FUo5NPe3PROz1FqB0+qdw= +go.opentelemetry.io/otel/sdk/metric v1.42.0 h1:D/1QR46Clz6ajyZ3G8SgNlTJKBdGp84q9RKCAZ3YGuA= +go.opentelemetry.io/otel/sdk/metric v1.42.0/go.mod h1:Ua6AAlDKdZ7tdvaQKfSmnFTdHx37+J4ba8MwVCYM5hc= +go.opentelemetry.io/otel/trace v1.42.0 h1:OUCgIPt+mzOnaUTpOQcBiM/PLQ/Op7oq6g4LenLmOYY= +go.opentelemetry.io/otel/trace v1.42.0/go.mod h1:f3K9S+IFqnumBkKhRJMeaZeNk9epyhnCmQh/EysQCdc= +go.opentelemetry.io/proto/otlp v1.10.0 h1:IQRWgT5srOCYfiWnpqUYz9CVmbO8bFmKcwYxpuCSL2g= +go.opentelemetry.io/proto/otlp v1.10.0/go.mod h1:/CV4QoCR/S9yaPj8utp3lvQPoqMtxXdzn7ozvvozVqk= +go.opentelemetry.io/proto/slim/otlp v1.10.0 h1:iR97Vs/ZDR+y9TfuP9b1XBtdPWeC+OMslIBmhcLU7jM= +go.opentelemetry.io/proto/slim/otlp v1.10.0/go.mod h1:lV9250stpjYLPNA5viFabIgP2QlUGRT1GdTgAf8SIUk= +go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.3.0 h1:RUF5rO0hAlgiJt1fzQVzcVs3vZVNHIcMLgOgG4rWNcQ= +go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.3.0/go.mod h1:I89cynRj8y+383o7tEQVg2SVA6SRgDVIouWPUVXjx0U= +go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.3.0 h1:CQvJSldHRUN6Z8jsUeYv8J0lXRvygALXIzsmAeCcZE0= +go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.3.0/go.mod h1:xSQ+mEfJe/GjK1LXEyVOoSI1N9JV9ZI923X5kup43W4= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= @@ -184,29 +180,28 @@ go.yaml.in/yaml/v2 v2.4.3 h1:6gvOSjQoTB3vt1l+CU+tSyi/HOjfOjRLJ4YwYZGwRO0= go.yaml.in/yaml/v2 v2.4.3/go.mod h1:zSxWcmIDjOzPXpjlTTbAsKokqkDNAVtZO0WOMiT90s8= go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc= go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg= -golang.org/x/crypto v0.45.0 h1:jMBrvKuj23MTlT0bQEOBcAE0mjg8mK9RXFhRH6nyF3Q= -golang.org/x/crypto v0.45.0/go.mod h1:XTGrrkGJve7CYK7J8PEww4aY7gM3qMCElcJQ8n8JdX4= +golang.org/x/crypto v0.48.0 h1:/VRzVqiRSggnhY7gNRxPauEQ5Drw9haKdM0jqfcCFts= +golang.org/x/crypto v0.48.0/go.mod h1:r0kV5h3qnFPlQnBSrULhlsRfryS2pmewsg+XfMgkVos= golang.org/x/exp v0.0.0-20240506185415-9bf2ced13842 h1:vr/HnozRka3pE4EsMEg1lgkXJkTFJCVUX+S/ZT6wYzM= golang.org/x/exp v0.0.0-20240506185415-9bf2ced13842/go.mod h1:XtvwrStGgqGPLc4cjQfWqZHG1YFdYs6swckp8vpsjnc= -golang.org/x/net v0.47.0 h1:Mx+4dIFzqraBXUugkia1OOvlD6LemFo1ALMHjrXDOhY= -golang.org/x/net v0.47.0/go.mod h1:/jNxtkgq5yWUGYkaZGqo27cfGZ1c5Nen03aYrrKpVRU= +golang.org/x/net v0.51.0 h1:94R/GTO7mt3/4wIKpcR5gkGmRLOuE/2hNGeWq/GBIFo= +golang.org/x/net v0.51.0/go.mod h1:aamm+2QF5ogm02fjy5Bb7CQ0WMt1/WVM7FtyaTLlA9Y= golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201204225414-ed752295db88/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.40.0 h1:DBZZqJ2Rkml6QMQsZywtnjnnGvHza6BTfYFWY9kjEWQ= -golang.org/x/sys v0.40.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= -golang.org/x/text v0.31.0 h1:aC8ghyu4JhP8VojJ2lEHBnochRno1sgL6nEi9WGFGMM= -golang.org/x/text v0.31.0/go.mod h1:tKRAlv61yKIjGGHX/4tP1LTbc13YSec1pxVEWXzfoeM= -golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -gonum.org/v1/gonum v0.16.0 h1:5+ul4Swaf3ESvrOnidPp4GZbzf0mxVQpDCYUQE7OJfk= -gonum.org/v1/gonum v0.16.0/go.mod h1:fef3am4MQ93R2HHpKnLk4/Tbh/s0+wqD5nfa6Pnwy4E= -google.golang.org/genproto/googleapis/api v0.0.0-20251022142026-3a174f9686a8 h1:mepRgnBZa07I4TRuomDE4sTIYieg/osKmzIf4USdWS4= -google.golang.org/genproto/googleapis/api v0.0.0-20251022142026-3a174f9686a8/go.mod h1:fDMmzKV90WSg1NbozdqrE64fkuTv6mlq2zxo9ad+3yo= -google.golang.org/genproto/googleapis/rpc v0.0.0-20251022142026-3a174f9686a8 h1:M1rk8KBnUsBDg1oPGHNCxG4vc1f49epmTO7xscSajMk= -google.golang.org/genproto/googleapis/rpc v0.0.0-20251022142026-3a174f9686a8/go.mod h1:7i2o+ce6H/6BluujYR+kqX3GKH+dChPTQU19wjRPiGk= -google.golang.org/grpc v1.77.0 h1:wVVY6/8cGA6vvffn+wWK5ToddbgdU3d8MNENr4evgXM= -google.golang.org/grpc v1.77.0/go.mod h1:z0BY1iVj0q8E1uSQCjL9cppRj+gnZjzDnzV0dHhrNig= -google.golang.org/protobuf v1.36.10 h1:AYd7cD/uASjIL6Q9LiTjz8JLcrh/88q5UObnmY3aOOE= -google.golang.org/protobuf v1.36.10/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= +golang.org/x/sys v0.41.0 h1:Ivj+2Cp/ylzLiEU89QhWblYnOE9zerudt9Ftecq2C6k= +golang.org/x/sys v0.41.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= +golang.org/x/text v0.34.0 h1:oL/Qq0Kdaqxa1KbNeMKwQq0reLCCaFtqu2eNuSeNHbk= +golang.org/x/text v0.34.0/go.mod h1:homfLqTYRFyVYemLBFl5GgL/DWEiH5wcsQ5gSh1yziA= +gonum.org/v1/gonum v0.17.0 h1:VbpOemQlsSMrYmn7T2OUvQ4dqxQXU+ouZFQsZOx50z4= +gonum.org/v1/gonum v0.17.0/go.mod h1:El3tOrEuMpv2UdMrbNlKEh9vd86bmQ6vqIcDwxEOc1E= +google.golang.org/genproto/googleapis/api v0.0.0-20260226221140-a57be14db171 h1:tu/dtnW1o3wfaxCOjSLn5IRX4YDcJrtlpzYkhHhGaC4= +google.golang.org/genproto/googleapis/api v0.0.0-20260226221140-a57be14db171/go.mod h1:M5krXqk4GhBKvB596udGL3UyjL4I1+cTbK0orROM9ng= +google.golang.org/genproto/googleapis/rpc v0.0.0-20260226221140-a57be14db171 h1:ggcbiqK8WWh6l1dnltU4BgWGIGo+EVYxCaAPih/zQXQ= +google.golang.org/genproto/googleapis/rpc v0.0.0-20260226221140-a57be14db171/go.mod h1:4Hqkh8ycfw05ld/3BWL7rJOSfebL2Q+DVDeRgYgxUU8= +google.golang.org/grpc v1.79.3 h1:sybAEdRIEtvcD68Gx7dmnwjZKlyfuc61Dyo9pGXXkKE= +google.golang.org/grpc v1.79.3/go.mod h1:KmT0Kjez+0dde/v2j9vzwoAScgEPx/Bw1CYChhHLrHQ= +google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE= +google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= diff --git a/otelcol/otelcoltest/metadata.yaml b/otelcol/otelcoltest/metadata.yaml new file mode 100644 index 000000000000..dc8861bd06ab --- /dev/null +++ b/otelcol/otelcoltest/metadata.yaml @@ -0,0 +1,6 @@ +type: otelcol/otelcoltest +github_project: open-telemetry/opentelemetry-collector + +status: + disable_codecov_badge: true + class: pkg diff --git a/otelcol/signals_others.go b/otelcol/signals_others.go new file mode 100644 index 000000000000..64747d319b42 --- /dev/null +++ b/otelcol/signals_others.go @@ -0,0 +1,15 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +//go:build !(js && wasm) + +package otelcol // import "go.opentelemetry.io/collector/otelcol" + +import ( + "syscall" +) + +const ( + SIGHUP = syscall.SIGHUP + SIGTERM = syscall.SIGTERM +) diff --git a/otelcol/signals_wasm.go b/otelcol/signals_wasm.go new file mode 100644 index 000000000000..2e738f657339 --- /dev/null +++ b/otelcol/signals_wasm.go @@ -0,0 +1,15 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +//go:build js && wasm + +package otelcol // import "go.opentelemetry.io/collector/otelcol" + +import ( + "syscall" +) + +const ( + SIGHUP = syscall.Signal(-1) + SIGTERM = syscall.Signal(-1) +) diff --git a/otelcol/testdata/components-output-sorted.yaml b/otelcol/testdata/components-output-sorted.yaml new file mode 100644 index 000000000000..6ecbcd89d72b --- /dev/null +++ b/otelcol/testdata/components-output-sorted.yaml @@ -0,0 +1,120 @@ +buildinfo: + command: otelcol + description: OpenTelemetry Collector + version: latest +receivers: + - name: bar + module: go.opentelemetry.io/collector/receiver/receivertest v1.2.3 + stability: + logs: Undefined + metrics: Undefined + traces: Undefined + - name: baz + module: go.opentelemetry.io/collector/receiver/receivertest v1.2.3 + stability: + logs: Undefined + metrics: Undefined + traces: Undefined + - name: foo + module: go.opentelemetry.io/collector/receiver/receivertest v1.2.3 + stability: + logs: Undefined + metrics: Undefined + traces: Undefined +processors: + - name: bar + module: go.opentelemetry.io/collector/processor/processortest v1.2.3 + stability: + logs: Undefined + metrics: Undefined + traces: Undefined + - name: baz + module: go.opentelemetry.io/collector/processor/processortest v1.2.3 + stability: + logs: Undefined + metrics: Undefined + traces: Undefined + - name: foo + module: go.opentelemetry.io/collector/processor/processortest v1.2.3 + stability: + logs: Undefined + metrics: Undefined + traces: Undefined +exporters: + - name: bar + module: go.opentelemetry.io/collector/exporter/exportertest v1.2.3 + stability: + logs: Undefined + metrics: Undefined + traces: Undefined + - name: baz + module: go.opentelemetry.io/collector/exporter/exportertest v1.2.3 + stability: + logs: Undefined + metrics: Undefined + traces: Undefined + - name: foo + module: go.opentelemetry.io/collector/exporter/exportertest v1.2.3 + stability: + logs: Undefined + metrics: Undefined + traces: Undefined +connectors: + - name: bar + module: go.opentelemetry.io/collector/connector/connectortest v1.2.3 + stability: + logs-to-logs: Undefined + logs-to-metrics: Undefined + logs-to-traces: Undefined + metrics-to-logs: Undefined + metrics-to-metrics: Undefined + metrics-to-traces: Undefined + traces-to-logs: Undefined + traces-to-metrics: Undefined + traces-to-traces: Undefined + - name: baz + module: go.opentelemetry.io/collector/connector/connectortest v1.2.3 + stability: + logs-to-logs: Undefined + logs-to-metrics: Undefined + logs-to-traces: Undefined + metrics-to-logs: Undefined + metrics-to-metrics: Undefined + metrics-to-traces: Undefined + traces-to-logs: Undefined + traces-to-metrics: Undefined + traces-to-traces: Undefined + - name: foo + module: go.opentelemetry.io/collector/connector/connectortest v1.2.3 + stability: + logs-to-logs: Undefined + logs-to-metrics: Undefined + logs-to-traces: Undefined + metrics-to-logs: Undefined + metrics-to-metrics: Undefined + metrics-to-traces: Undefined + traces-to-logs: Undefined + traces-to-metrics: Undefined + traces-to-traces: Undefined +extensions: + - name: bar + module: go.opentelemetry.io/collector/extension/extensiontest v1.2.3 + stability: + extension: Stable + - name: baz + module: go.opentelemetry.io/collector/extension/extensiontest v1.2.3 + stability: + extension: Stable + - name: foo + module: go.opentelemetry.io/collector/extension/extensiontest v1.2.3 + stability: + extension: Stable +providers: + - scheme: env + module: go.opentelemetry.io/collector/confmap/provider/testprovider v1.2.3 + - scheme: file + module: go.opentelemetry.io/collector/confmap/provider/testprovider v1.2.3 +converters: + - module: go.opentelemetry.io/collector/converter/bar v1.2.3 + - module: go.opentelemetry.io/collector/converter/baz v1.2.3 + - module: go.opentelemetry.io/collector/converter/foo v1.2.3 diff --git a/otelcol/testdata/components-output.yaml b/otelcol/testdata/components-output.yaml index 94e1797f3da1..6f1be859d43f 100644 --- a/otelcol/testdata/components-output.yaml +++ b/otelcol/testdata/components-output.yaml @@ -42,7 +42,9 @@ extensions: stability: extension: Stable providers: - - scheme: nop + - scheme: env + module: go.opentelemetry.io/collector/confmap/provider/testprovider v1.2.3 + - scheme: file module: go.opentelemetry.io/collector/confmap/provider/testprovider v1.2.3 converters: - module: go.opentelemetry.io/collector/converter/testconverter v1.2.3 diff --git a/otelcol/unmarshaler_test.go b/otelcol/unmarshaler_test.go index fafde031f477..7259aca93599 100644 --- a/otelcol/unmarshaler_test.go +++ b/otelcol/unmarshaler_test.go @@ -48,7 +48,7 @@ func TestUnmarshalUnknownTopLevel(t *testing.T) { "unknown_section": nil, }) _, err = unmarshal(conf, factories) - assert.ErrorContains(t, err, "'' has invalid keys: unknown_section") + assert.ErrorContains(t, err, "has invalid keys: unknown_section") } func TestPipelineConfigUnmarshalError(t *testing.T) { @@ -156,7 +156,7 @@ func TestServiceUnmarshalError(t *testing.T) { conf: confmap.NewFromStringMap(map[string]any{ "unknown_section": "string", }), - expectError: "'' has invalid keys: unknown_section", + expectError: "has invalid keys: unknown_section", }, { name: "invalid-pipelines-config", diff --git a/pdata/documentation.md b/pdata/documentation.md new file mode 100644 index 000000000000..93d6ae0406bb --- /dev/null +++ b/pdata/documentation.md @@ -0,0 +1,14 @@ +[comment]: <> (Code generated by mdatagen. DO NOT EDIT.) + +# pdata + +## Feature Gates + +This component has the following feature gates: + +| Feature Gate | Stage | Description | From Version | To Version | Reference | +| ------------ | ----- | ----------- | ------------ | ---------- | --------- | +| `pdata.useCustomProtoEncoding` | stable | When enabled, enable custom proto encoding. This is a required step to enable featuregate pdata.useProtoPooling. | v0.133.0 | v0.137.0 | [Link](https://github.com/open-telemetry/opentelemetry-collector/issues/13631) | +| `pdata.useProtoPooling` | alpha | When enabled, enable using local memory pools for underlying data that the pdata messages are pushed to. | v0.133.0 | N/A | [Link](https://github.com/open-telemetry/opentelemetry-collector/issues/13631) | + +For more information about feature gates, see the [Feature Gates](https://github.com/open-telemetry/opentelemetry-collector/blob/main/featuregate/README.md) documentation. diff --git a/pdata/go.mod b/pdata/go.mod index 9a822b9198fb..67ff08d5a647 100644 --- a/pdata/go.mod +++ b/pdata/go.mod @@ -1,31 +1,31 @@ module go.opentelemetry.io/collector/pdata -go 1.24.0 +go 1.25.0 require ( github.com/json-iterator/go v1.1.12 github.com/stretchr/testify v1.11.1 - go.opentelemetry.io/collector/featuregate v1.46.0 - go.opentelemetry.io/collector/internal/testutil v0.140.0 - go.opentelemetry.io/proto/slim/otlp v1.9.0 - go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.2.0 - go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.2.0 + go.opentelemetry.io/collector/featuregate v1.54.0 + go.opentelemetry.io/collector/internal/testutil v0.148.0 + go.opentelemetry.io/proto/slim/otlp v1.10.0 + go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.3.0 + go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.3.0 go.uber.org/goleak v1.3.0 go.uber.org/multierr v1.11.0 - google.golang.org/grpc v1.77.0 - google.golang.org/protobuf v1.36.10 + google.golang.org/grpc v1.79.3 + google.golang.org/protobuf v1.36.11 ) require ( github.com/davecgh/go-spew v1.1.1 // indirect - github.com/hashicorp/go-version v1.7.0 // indirect + github.com/hashicorp/go-version v1.8.0 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee // indirect github.com/pmezard/go-difflib v1.0.0 // indirect - golang.org/x/net v0.46.1-0.20251013234738-63d1a5100f82 // indirect - golang.org/x/sys v0.37.0 // indirect - golang.org/x/text v0.30.0 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20251022142026-3a174f9686a8 // indirect + golang.org/x/net v0.51.0 // indirect + golang.org/x/sys v0.41.0 // indirect + golang.org/x/text v0.34.0 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20251222181119-0a764e51fe1b // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/pdata/go.sum b/pdata/go.sum index 3ae9da8776e5..e06e5cd25506 100644 --- a/pdata/go.sum +++ b/pdata/go.sum @@ -1,3 +1,5 @@ +github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= +github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= @@ -12,8 +14,8 @@ github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/hashicorp/go-version v1.7.0 h1:5tqGy27NaOTB8yJKUZELlFAS/LTKJkrmONwQKeRZfjY= -github.com/hashicorp/go-version v1.7.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= +github.com/hashicorp/go-version v1.8.0 h1:KAkNb1HAiZd1ukkxDFGmokVZe1Xy9HG6NUp+bPle2i4= +github.com/hashicorp/go-version v1.8.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= @@ -36,40 +38,40 @@ github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64= go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y= -go.opentelemetry.io/otel v1.38.0 h1:RkfdswUDRimDg0m2Az18RKOsnI8UDzppJAtj01/Ymk8= -go.opentelemetry.io/otel v1.38.0/go.mod h1:zcmtmQ1+YmQM9wrNsTGV/q/uyusom3P8RxwExxkZhjM= -go.opentelemetry.io/otel/metric v1.38.0 h1:Kl6lzIYGAh5M159u9NgiRkmoMKjvbsKtYRwgfrA6WpA= -go.opentelemetry.io/otel/metric v1.38.0/go.mod h1:kB5n/QoRM8YwmUahxvI3bO34eVtQf2i4utNVLr9gEmI= -go.opentelemetry.io/otel/sdk v1.38.0 h1:l48sr5YbNf2hpCUj/FoGhW9yDkl+Ma+LrVl8qaM5b+E= -go.opentelemetry.io/otel/sdk v1.38.0/go.mod h1:ghmNdGlVemJI3+ZB5iDEuk4bWA3GkTpW+DOoZMYBVVg= -go.opentelemetry.io/otel/sdk/metric v1.38.0 h1:aSH66iL0aZqo//xXzQLYozmWrXxyFkBJ6qT5wthqPoM= -go.opentelemetry.io/otel/sdk/metric v1.38.0/go.mod h1:dg9PBnW9XdQ1Hd6ZnRz689CbtrUp0wMMs9iPcgT9EZA= -go.opentelemetry.io/otel/trace v1.38.0 h1:Fxk5bKrDZJUH+AMyyIXGcFAPah0oRcT+LuNtJrmcNLE= -go.opentelemetry.io/otel/trace v1.38.0/go.mod h1:j1P9ivuFsTceSWe1oY+EeW3sc+Pp42sO++GHkg4wwhs= -go.opentelemetry.io/proto/slim/otlp v1.9.0 h1:fPVMv8tP3TrsqlkH1HWYUpbCY9cAIemx184VGkS6vlE= -go.opentelemetry.io/proto/slim/otlp v1.9.0/go.mod h1:xXdeJJ90Gqyll+orzUkY4bOd2HECo5JofeoLpymVqdI= -go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.2.0 h1:o13nadWDNkH/quoDomDUClnQBpdQQ2Qqv0lQBjIXjE8= -go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.2.0/go.mod h1:Gyb6Xe7FTi/6xBHwMmngGoHqL0w29Y4eW8TGFzpefGA= -go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.2.0 h1:EiUYvtwu6PMrMHVjcPfnsG3v+ajPkbUeH+IL93+QYyk= -go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.2.0/go.mod h1:mUUHKFiN2SST3AhJ8XhJxEoeVW12oqfXog0Bo8W3Ec4= +go.opentelemetry.io/otel v1.39.0 h1:8yPrr/S0ND9QEfTfdP9V+SiwT4E0G7Y5MO7p85nis48= +go.opentelemetry.io/otel v1.39.0/go.mod h1:kLlFTywNWrFyEdH0oj2xK0bFYZtHRYUdv1NklR/tgc8= +go.opentelemetry.io/otel/metric v1.39.0 h1:d1UzonvEZriVfpNKEVmHXbdf909uGTOQjA0HF0Ls5Q0= +go.opentelemetry.io/otel/metric v1.39.0/go.mod h1:jrZSWL33sD7bBxg1xjrqyDjnuzTUB0x1nBERXd7Ftcs= +go.opentelemetry.io/otel/sdk v1.39.0 h1:nMLYcjVsvdui1B/4FRkwjzoRVsMK8uL/cj0OyhKzt18= +go.opentelemetry.io/otel/sdk v1.39.0/go.mod h1:vDojkC4/jsTJsE+kh+LXYQlbL8CgrEcwmt1ENZszdJE= +go.opentelemetry.io/otel/sdk/metric v1.39.0 h1:cXMVVFVgsIf2YL6QkRF4Urbr/aMInf+2WKg+sEJTtB8= +go.opentelemetry.io/otel/sdk/metric v1.39.0/go.mod h1:xq9HEVH7qeX69/JnwEfp6fVq5wosJsY1mt4lLfYdVew= +go.opentelemetry.io/otel/trace v1.39.0 h1:2d2vfpEDmCJ5zVYz7ijaJdOF59xLomrvj7bjt6/qCJI= +go.opentelemetry.io/otel/trace v1.39.0/go.mod h1:88w4/PnZSazkGzz/w84VHpQafiU4EtqqlVdxWy+rNOA= +go.opentelemetry.io/proto/slim/otlp v1.10.0 h1:iR97Vs/ZDR+y9TfuP9b1XBtdPWeC+OMslIBmhcLU7jM= +go.opentelemetry.io/proto/slim/otlp v1.10.0/go.mod h1:lV9250stpjYLPNA5viFabIgP2QlUGRT1GdTgAf8SIUk= +go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.3.0 h1:RUF5rO0hAlgiJt1fzQVzcVs3vZVNHIcMLgOgG4rWNcQ= +go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.3.0/go.mod h1:I89cynRj8y+383o7tEQVg2SVA6SRgDVIouWPUVXjx0U= +go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.3.0 h1:CQvJSldHRUN6Z8jsUeYv8J0lXRvygALXIzsmAeCcZE0= +go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.3.0/go.mod h1:xSQ+mEfJe/GjK1LXEyVOoSI1N9JV9ZI923X5kup43W4= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= -golang.org/x/net v0.46.1-0.20251013234738-63d1a5100f82 h1:6/3JGEh1C88g7m+qzzTbl3A0FtsLguXieqofVLU/JAo= -golang.org/x/net v0.46.1-0.20251013234738-63d1a5100f82/go.mod h1:Q9BGdFy1y4nkUwiLvT5qtyhAnEHgnQ/zd8PfU6nc210= -golang.org/x/sys v0.37.0 h1:fdNQudmxPjkdUTPnLn5mdQv7Zwvbvpaxqs831goi9kQ= -golang.org/x/sys v0.37.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= -golang.org/x/text v0.30.0 h1:yznKA/E9zq54KzlzBEAWn1NXSQ8DIp/NYMy88xJjl4k= -golang.org/x/text v0.30.0/go.mod h1:yDdHFIX9t+tORqspjENWgzaCVXgk0yYnYuSZ8UzzBVM= +golang.org/x/net v0.51.0 h1:94R/GTO7mt3/4wIKpcR5gkGmRLOuE/2hNGeWq/GBIFo= +golang.org/x/net v0.51.0/go.mod h1:aamm+2QF5ogm02fjy5Bb7CQ0WMt1/WVM7FtyaTLlA9Y= +golang.org/x/sys v0.41.0 h1:Ivj+2Cp/ylzLiEU89QhWblYnOE9zerudt9Ftecq2C6k= +golang.org/x/sys v0.41.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= +golang.org/x/text v0.34.0 h1:oL/Qq0Kdaqxa1KbNeMKwQq0reLCCaFtqu2eNuSeNHbk= +golang.org/x/text v0.34.0/go.mod h1:homfLqTYRFyVYemLBFl5GgL/DWEiH5wcsQ5gSh1yziA= gonum.org/v1/gonum v0.16.0 h1:5+ul4Swaf3ESvrOnidPp4GZbzf0mxVQpDCYUQE7OJfk= gonum.org/v1/gonum v0.16.0/go.mod h1:fef3am4MQ93R2HHpKnLk4/Tbh/s0+wqD5nfa6Pnwy4E= -google.golang.org/genproto/googleapis/rpc v0.0.0-20251022142026-3a174f9686a8 h1:M1rk8KBnUsBDg1oPGHNCxG4vc1f49epmTO7xscSajMk= -google.golang.org/genproto/googleapis/rpc v0.0.0-20251022142026-3a174f9686a8/go.mod h1:7i2o+ce6H/6BluujYR+kqX3GKH+dChPTQU19wjRPiGk= -google.golang.org/grpc v1.77.0 h1:wVVY6/8cGA6vvffn+wWK5ToddbgdU3d8MNENr4evgXM= -google.golang.org/grpc v1.77.0/go.mod h1:z0BY1iVj0q8E1uSQCjL9cppRj+gnZjzDnzV0dHhrNig= -google.golang.org/protobuf v1.36.10 h1:AYd7cD/uASjIL6Q9LiTjz8JLcrh/88q5UObnmY3aOOE= -google.golang.org/protobuf v1.36.10/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= +google.golang.org/genproto/googleapis/rpc v0.0.0-20251222181119-0a764e51fe1b h1:Mv8VFug0MP9e5vUxfBcE3vUkV6CImK3cMNMIDFjmzxU= +google.golang.org/genproto/googleapis/rpc v0.0.0-20251222181119-0a764e51fe1b/go.mod h1:j9x/tPzZkyxcgEFkiKEEGxfvyumM01BEtsW8xzOahRQ= +google.golang.org/grpc v1.79.3 h1:sybAEdRIEtvcD68Gx7dmnwjZKlyfuc61Dyo9pGXXkKE= +google.golang.org/grpc v1.79.3/go.mod h1:KmT0Kjez+0dde/v2j9vzwoAScgEPx/Bw1CYChhHLrHQ= +google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE= +google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= diff --git a/pdata/internal/config.schema.yaml b/pdata/internal/config.schema.yaml new file mode 100644 index 000000000000..ac15a1d583cc --- /dev/null +++ b/pdata/internal/config.schema.yaml @@ -0,0 +1,35 @@ +$defs: + aggregation_temporality: + description: AggregationTemporality defines how a metric aggregator reports aggregated values. It describes how those values relate to the time interval over which they are aggregated. + type: integer + x-customType: int32 + profile_id: + description: ProfileID is a custom data type that is used for all profile_id fields in OTLP Protobuf messages. + type: array + items: + type: string + x-customType: byte + severity_number: + description: SeverityNumber represent possible values for LogRecord.SeverityNumber + type: integer + x-customType: int32 + span_id: + description: SpanID is a custom data type that is used for all span_id fields in OTLP Protobuf messages. + type: array + items: + type: string + x-customType: byte + span_kind: + description: SpanKind is the type of span. Can be used to specify additional relationships between spans in addition to a parent/child relationship. + type: integer + x-customType: int32 + status_code: + description: StatusCode is the status of the span, for the semantics of codes see https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/trace/api.md#set-status + type: integer + x-customType: int32 + trace_id: + description: TraceID is a custom data type that is used for all trace_id fields in OTLP Protobuf messages. + type: array + items: + type: string + x-customType: byte diff --git a/pdata/internal/generated_proto_anyvalue.go b/pdata/internal/generated_proto_anyvalue.go index ddc86601cd86..404c61891b43 100644 --- a/pdata/internal/generated_proto_anyvalue.go +++ b/pdata/internal/generated_proto_anyvalue.go @@ -13,6 +13,7 @@ import ( "sync" "go.opentelemetry.io/collector/pdata/internal/json" + "go.opentelemetry.io/collector/pdata/internal/metadata" "go.opentelemetry.io/collector/pdata/internal/proto" ) @@ -100,6 +101,17 @@ func (m *AnyValue) GetBytesValue() []byte { return nil } +type AnyValue_StringValueStrindex struct { + StringValueStrindex int32 +} + +func (m *AnyValue) GetStringValueStrindex() int32 { + if v, ok := m.GetValue().(*AnyValue_StringValueStrindex); ok { + return v.StringValueStrindex + } + return int32(0) +} + type AnyValue struct { Value any } @@ -152,10 +164,16 @@ var ( return &AnyValue_BytesValue{} }, } + + ProtoPoolAnyValue_StringValueStrindex = sync.Pool{ + New: func() any { + return &AnyValue_StringValueStrindex{} + }, + } ) func NewAnyValue() *AnyValue { - if !UseProtoPooling.IsEnabled() { + if !metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() { return &AnyValue{} } return protoPoolAnyValue.Get().(*AnyValue) @@ -166,29 +184,28 @@ func DeleteAnyValue(orig *AnyValue, nullable bool) { return } - if !UseProtoPooling.IsEnabled() { + if !metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() { orig.Reset() return } - switch ov := orig.Value.(type) { case *AnyValue_StringValue: - if UseProtoPooling.IsEnabled() { + if metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() { ov.StringValue = "" ProtoPoolAnyValue_StringValue.Put(ov) } case *AnyValue_BoolValue: - if UseProtoPooling.IsEnabled() { + if metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() { ov.BoolValue = false ProtoPoolAnyValue_BoolValue.Put(ov) } case *AnyValue_IntValue: - if UseProtoPooling.IsEnabled() { + if metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() { ov.IntValue = int64(0) ProtoPoolAnyValue_IntValue.Put(ov) } case *AnyValue_DoubleValue: - if UseProtoPooling.IsEnabled() { + if metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() { ov.DoubleValue = float64(0) ProtoPoolAnyValue_DoubleValue.Put(ov) } @@ -201,13 +218,16 @@ func DeleteAnyValue(orig *AnyValue, nullable bool) { ov.KvlistValue = nil ProtoPoolAnyValue_KvlistValue.Put(ov) case *AnyValue_BytesValue: - if UseProtoPooling.IsEnabled() { + if metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() { ov.BytesValue = nil ProtoPoolAnyValue_BytesValue.Put(ov) } - + case *AnyValue_StringValueStrindex: + if metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() { + ov.StringValueStrindex = int32(0) + ProtoPoolAnyValue_StringValueStrindex.Put(ov) + } } - orig.Reset() if nullable { protoPoolAnyValue.Put(orig) @@ -230,43 +250,47 @@ func CopyAnyValue(dest, src *AnyValue) *AnyValue { switch t := src.Value.(type) { case *AnyValue_StringValue: var ov *AnyValue_StringValue - if !UseProtoPooling.IsEnabled() { + if !metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() { ov = &AnyValue_StringValue{} } else { ov = ProtoPoolAnyValue_StringValue.Get().(*AnyValue_StringValue) } ov.StringValue = t.StringValue dest.Value = ov + case *AnyValue_BoolValue: var ov *AnyValue_BoolValue - if !UseProtoPooling.IsEnabled() { + if !metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() { ov = &AnyValue_BoolValue{} } else { ov = ProtoPoolAnyValue_BoolValue.Get().(*AnyValue_BoolValue) } ov.BoolValue = t.BoolValue dest.Value = ov + case *AnyValue_IntValue: var ov *AnyValue_IntValue - if !UseProtoPooling.IsEnabled() { + if !metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() { ov = &AnyValue_IntValue{} } else { ov = ProtoPoolAnyValue_IntValue.Get().(*AnyValue_IntValue) } ov.IntValue = t.IntValue dest.Value = ov + case *AnyValue_DoubleValue: var ov *AnyValue_DoubleValue - if !UseProtoPooling.IsEnabled() { + if !metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() { ov = &AnyValue_DoubleValue{} } else { ov = ProtoPoolAnyValue_DoubleValue.Get().(*AnyValue_DoubleValue) } ov.DoubleValue = t.DoubleValue dest.Value = ov + case *AnyValue_ArrayValue: var ov *AnyValue_ArrayValue - if !UseProtoPooling.IsEnabled() { + if !metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() { ov = &AnyValue_ArrayValue{} } else { ov = ProtoPoolAnyValue_ArrayValue.Get().(*AnyValue_ArrayValue) @@ -277,7 +301,7 @@ func CopyAnyValue(dest, src *AnyValue) *AnyValue { case *AnyValue_KvlistValue: var ov *AnyValue_KvlistValue - if !UseProtoPooling.IsEnabled() { + if !metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() { ov = &AnyValue_KvlistValue{} } else { ov = ProtoPoolAnyValue_KvlistValue.Get().(*AnyValue_KvlistValue) @@ -288,13 +312,24 @@ func CopyAnyValue(dest, src *AnyValue) *AnyValue { case *AnyValue_BytesValue: var ov *AnyValue_BytesValue - if !UseProtoPooling.IsEnabled() { + if !metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() { ov = &AnyValue_BytesValue{} } else { ov = ProtoPoolAnyValue_BytesValue.Get().(*AnyValue_BytesValue) } ov.BytesValue = t.BytesValue dest.Value = ov + + case *AnyValue_StringValueStrindex: + var ov *AnyValue_StringValueStrindex + if !metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() { + ov = &AnyValue_StringValueStrindex{} + } else { + ov = ProtoPoolAnyValue_StringValueStrindex.Get().(*AnyValue_StringValueStrindex) + } + ov.StringValueStrindex = t.StringValueStrindex + dest.Value = ov + default: dest.Value = nil } @@ -384,6 +419,9 @@ func (orig *AnyValue) MarshalJSON(dest *json.Stream) { dest.WriteObjectField("bytesValue") dest.WriteBytes(orig.BytesValue) + case *AnyValue_StringValueStrindex: + dest.WriteObjectField("stringValueStrindex") + dest.WriteInt32(orig.StringValueStrindex) } dest.WriteObjectEnd() } @@ -396,7 +434,7 @@ func (orig *AnyValue) UnmarshalJSON(iter *json.Iterator) { case "stringValue", "string_value": { var ov *AnyValue_StringValue - if !UseProtoPooling.IsEnabled() { + if !metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() { ov = &AnyValue_StringValue{} } else { ov = ProtoPoolAnyValue_StringValue.Get().(*AnyValue_StringValue) @@ -404,11 +442,10 @@ func (orig *AnyValue) UnmarshalJSON(iter *json.Iterator) { ov.StringValue = iter.ReadString() orig.Value = ov } - case "boolValue", "bool_value": { var ov *AnyValue_BoolValue - if !UseProtoPooling.IsEnabled() { + if !metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() { ov = &AnyValue_BoolValue{} } else { ov = ProtoPoolAnyValue_BoolValue.Get().(*AnyValue_BoolValue) @@ -416,11 +453,10 @@ func (orig *AnyValue) UnmarshalJSON(iter *json.Iterator) { ov.BoolValue = iter.ReadBool() orig.Value = ov } - case "intValue", "int_value": { var ov *AnyValue_IntValue - if !UseProtoPooling.IsEnabled() { + if !metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() { ov = &AnyValue_IntValue{} } else { ov = ProtoPoolAnyValue_IntValue.Get().(*AnyValue_IntValue) @@ -428,11 +464,10 @@ func (orig *AnyValue) UnmarshalJSON(iter *json.Iterator) { ov.IntValue = iter.ReadInt64() orig.Value = ov } - case "doubleValue", "double_value": { var ov *AnyValue_DoubleValue - if !UseProtoPooling.IsEnabled() { + if !metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() { ov = &AnyValue_DoubleValue{} } else { ov = ProtoPoolAnyValue_DoubleValue.Get().(*AnyValue_DoubleValue) @@ -440,11 +475,10 @@ func (orig *AnyValue) UnmarshalJSON(iter *json.Iterator) { ov.DoubleValue = iter.ReadFloat64() orig.Value = ov } - case "arrayValue", "array_value": { var ov *AnyValue_ArrayValue - if !UseProtoPooling.IsEnabled() { + if !metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() { ov = &AnyValue_ArrayValue{} } else { ov = ProtoPoolAnyValue_ArrayValue.Get().(*AnyValue_ArrayValue) @@ -453,11 +487,10 @@ func (orig *AnyValue) UnmarshalJSON(iter *json.Iterator) { ov.ArrayValue.UnmarshalJSON(iter) orig.Value = ov } - case "kvlistValue", "kvlist_value": { var ov *AnyValue_KvlistValue - if !UseProtoPooling.IsEnabled() { + if !metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() { ov = &AnyValue_KvlistValue{} } else { ov = ProtoPoolAnyValue_KvlistValue.Get().(*AnyValue_KvlistValue) @@ -466,11 +499,10 @@ func (orig *AnyValue) UnmarshalJSON(iter *json.Iterator) { ov.KvlistValue.UnmarshalJSON(iter) orig.Value = ov } - case "bytesValue", "bytes_value": { var ov *AnyValue_BytesValue - if !UseProtoPooling.IsEnabled() { + if !metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() { ov = &AnyValue_BytesValue{} } else { ov = ProtoPoolAnyValue_BytesValue.Get().(*AnyValue_BytesValue) @@ -478,6 +510,17 @@ func (orig *AnyValue) UnmarshalJSON(iter *json.Iterator) { ov.BytesValue = iter.ReadBytes() orig.Value = ov } + case "stringValueStrindex", "string_value_strindex": + { + var ov *AnyValue_StringValueStrindex + if !metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() { + ov = &AnyValue_StringValueStrindex{} + } else { + ov = ProtoPoolAnyValue_StringValueStrindex.Get().(*AnyValue_StringValueStrindex) + } + ov.StringValueStrindex = iter.ReadInt32() + orig.Value = ov + } default: iter.Skip() @@ -497,10 +540,13 @@ func (orig *AnyValue) SizeProto() int { l = len(orig.StringValue) n += 1 + proto.Sov(uint64(l)) + l case *AnyValue_BoolValue: + n += 2 case *AnyValue_IntValue: + n += 1 + proto.Sov(uint64(orig.IntValue)) case *AnyValue_DoubleValue: + n += 9 case *AnyValue_ArrayValue: if orig.ArrayValue != nil { @@ -515,6 +561,9 @@ func (orig *AnyValue) SizeProto() int { case *AnyValue_BytesValue: l = len(orig.BytesValue) n += 1 + proto.Sov(uint64(l)) + l + case *AnyValue_StringValueStrindex: + + n += 1 + proto.Sov(uint64(orig.StringValueStrindex)) } return n } @@ -577,6 +626,11 @@ func (orig *AnyValue) MarshalProto(buf []byte) int { pos-- buf[pos] = 0x3a + case *AnyValue_StringValueStrindex: + pos = proto.EncodeVarint(buf, pos, uint64(orig.StringValueStrindex)) + pos-- + buf[pos] = 0x40 + } return len(buf) - pos } @@ -607,7 +661,7 @@ func (orig *AnyValue) UnmarshalProto(buf []byte) error { } startPos := pos - length var ov *AnyValue_StringValue - if !UseProtoPooling.IsEnabled() { + if !metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() { ov = &AnyValue_StringValue{} } else { ov = ProtoPoolAnyValue_StringValue.Get().(*AnyValue_StringValue) @@ -625,7 +679,7 @@ func (orig *AnyValue) UnmarshalProto(buf []byte) error { return err } var ov *AnyValue_BoolValue - if !UseProtoPooling.IsEnabled() { + if !metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() { ov = &AnyValue_BoolValue{} } else { ov = ProtoPoolAnyValue_BoolValue.Get().(*AnyValue_BoolValue) @@ -643,7 +697,7 @@ func (orig *AnyValue) UnmarshalProto(buf []byte) error { return err } var ov *AnyValue_IntValue - if !UseProtoPooling.IsEnabled() { + if !metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() { ov = &AnyValue_IntValue{} } else { ov = ProtoPoolAnyValue_IntValue.Get().(*AnyValue_IntValue) @@ -661,7 +715,7 @@ func (orig *AnyValue) UnmarshalProto(buf []byte) error { return err } var ov *AnyValue_DoubleValue - if !UseProtoPooling.IsEnabled() { + if !metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() { ov = &AnyValue_DoubleValue{} } else { ov = ProtoPoolAnyValue_DoubleValue.Get().(*AnyValue_DoubleValue) @@ -680,7 +734,7 @@ func (orig *AnyValue) UnmarshalProto(buf []byte) error { } startPos := pos - length var ov *AnyValue_ArrayValue - if !UseProtoPooling.IsEnabled() { + if !metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() { ov = &AnyValue_ArrayValue{} } else { ov = ProtoPoolAnyValue_ArrayValue.Get().(*AnyValue_ArrayValue) @@ -703,7 +757,7 @@ func (orig *AnyValue) UnmarshalProto(buf []byte) error { } startPos := pos - length var ov *AnyValue_KvlistValue - if !UseProtoPooling.IsEnabled() { + if !metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() { ov = &AnyValue_KvlistValue{} } else { ov = ProtoPoolAnyValue_KvlistValue.Get().(*AnyValue_KvlistValue) @@ -726,7 +780,7 @@ func (orig *AnyValue) UnmarshalProto(buf []byte) error { } startPos := pos - length var ov *AnyValue_BytesValue - if !UseProtoPooling.IsEnabled() { + if !metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() { ov = &AnyValue_BytesValue{} } else { ov = ProtoPoolAnyValue_BytesValue.Get().(*AnyValue_BytesValue) @@ -736,6 +790,25 @@ func (orig *AnyValue) UnmarshalProto(buf []byte) error { copy(ov.BytesValue, buf[startPos:pos]) } orig.Value = ov + + case 8: + if wireType != proto.WireTypeVarint { + return fmt.Errorf("proto: wrong wireType = %d for field StringValueStrindex", wireType) + } + var num uint64 + num, pos, err = proto.ConsumeVarint(buf, pos) + if err != nil { + return err + } + var ov *AnyValue_StringValueStrindex + if !metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() { + ov = &AnyValue_StringValueStrindex{} + } else { + ov = ProtoPoolAnyValue_StringValueStrindex.Get().(*AnyValue_StringValueStrindex) + } + ov.StringValueStrindex = int32(num) + orig.Value = ov + default: pos, err = proto.ConsumeUnknown(buf, pos, wireType) if err != nil { diff --git a/pdata/internal/generated_proto_anyvalue_test.go b/pdata/internal/generated_proto_anyvalue_test.go index d13a653e629f..5f9fc0eb2e33 100644 --- a/pdata/internal/generated_proto_anyvalue_test.go +++ b/pdata/internal/generated_proto_anyvalue_test.go @@ -17,16 +17,17 @@ import ( "go.opentelemetry.io/collector/featuregate" "go.opentelemetry.io/collector/pdata/internal/json" + "go.opentelemetry.io/collector/pdata/internal/metadata" ) func TestCopyAnyValue(t *testing.T) { for name, src := range genTestEncodingValuesAnyValue() { for _, pooling := range []bool{true, false} { t.Run(name+"/Pooling="+strconv.FormatBool(pooling), func(t *testing.T) { - prevPooling := UseProtoPooling.IsEnabled() - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), pooling)) + prevPooling := metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), pooling)) defer func() { - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), prevPooling)) + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), prevPooling)) }() dest := NewAnyValue() @@ -102,10 +103,10 @@ func TestMarshalAndUnmarshalJSONAnyValue(t *testing.T) { for name, src := range genTestEncodingValuesAnyValue() { for _, pooling := range []bool{true, false} { t.Run(name+"/Pooling="+strconv.FormatBool(pooling), func(t *testing.T) { - prevPooling := UseProtoPooling.IsEnabled() - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), pooling)) + prevPooling := metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), pooling)) defer func() { - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), prevPooling)) + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), prevPooling)) }() stream := json.BorrowStream(nil) @@ -146,10 +147,10 @@ func TestMarshalAndUnmarshalProtoAnyValue(t *testing.T) { for name, src := range genTestEncodingValuesAnyValue() { for _, pooling := range []bool{true, false} { t.Run(name+"/Pooling="+strconv.FormatBool(pooling), func(t *testing.T) { - prevPooling := UseProtoPooling.IsEnabled() - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), pooling)) + prevPooling := metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), pooling)) defer func() { - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), prevPooling)) + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), prevPooling)) }() buf := make([]byte, src.SizeProto()) @@ -190,26 +191,22 @@ func genTestFailingUnmarshalProtoValuesAnyValue() map[string][]byte { return map[string][]byte{ "invalid_field": {0x02}, - "StringValue/wrong_wire_type": {0xc}, - "StringValue/missing_value": {0xa}, - - "BoolValue/wrong_wire_type": {0x14}, - "BoolValue/missing_value": {0x10}, - - "IntValue/wrong_wire_type": {0x1c}, - "IntValue/missing_value": {0x18}, - - "DoubleValue/wrong_wire_type": {0x24}, - "DoubleValue/missing_value": {0x21}, - - "ArrayValue/wrong_wire_type": {0x2c}, - "ArrayValue/missing_value": {0x2a}, - - "KvlistValue/wrong_wire_type": {0x34}, - "KvlistValue/missing_value": {0x32}, - - "BytesValue/wrong_wire_type": {0x3c}, - "BytesValue/missing_value": {0x3a}, + "StringValue/wrong_wire_type": {0xc}, + "StringValue/missing_value": {0xa}, + "BoolValue/wrong_wire_type": {0x14}, + "BoolValue/missing_value": {0x10}, + "IntValue/wrong_wire_type": {0x1c}, + "IntValue/missing_value": {0x18}, + "DoubleValue/wrong_wire_type": {0x24}, + "DoubleValue/missing_value": {0x21}, + "ArrayValue/wrong_wire_type": {0x2c}, + "ArrayValue/missing_value": {0x2a}, + "KvlistValue/wrong_wire_type": {0x34}, + "KvlistValue/missing_value": {0x32}, + "BytesValue/wrong_wire_type": {0x3c}, + "BytesValue/missing_value": {0x3a}, + "StringValueStrindex/wrong_wire_type": {0x44}, + "StringValueStrindex/missing_value": {0x40}, } } @@ -217,18 +214,13 @@ func genTestEncodingValuesAnyValue() map[string]*AnyValue { return map[string]*AnyValue{ "empty": NewAnyValue(), "StringValue/default": {Value: &AnyValue_StringValue{StringValue: ""}}, - "StringValue/test": {Value: &AnyValue_StringValue{StringValue: "test_stringvalue"}}, - "BoolValue/default": {Value: &AnyValue_BoolValue{BoolValue: false}}, - "BoolValue/test": {Value: &AnyValue_BoolValue{BoolValue: true}}, - "IntValue/default": {Value: &AnyValue_IntValue{IntValue: int64(0)}}, - "IntValue/test": {Value: &AnyValue_IntValue{IntValue: int64(13)}}, - "DoubleValue/default": {Value: &AnyValue_DoubleValue{DoubleValue: float64(0)}}, - "DoubleValue/test": {Value: &AnyValue_DoubleValue{DoubleValue: float64(3.1415926)}}, - "ArrayValue/default": {Value: &AnyValue_ArrayValue{ArrayValue: &ArrayValue{}}}, - "ArrayValue/test": {Value: &AnyValue_ArrayValue{ArrayValue: GenTestArrayValue()}}, - "KvlistValue/default": {Value: &AnyValue_KvlistValue{KvlistValue: &KeyValueList{}}}, - "KvlistValue/test": {Value: &AnyValue_KvlistValue{KvlistValue: GenTestKeyValueList()}}, - "BytesValue/default": {Value: &AnyValue_BytesValue{BytesValue: nil}}, - "BytesValue/test": {Value: &AnyValue_BytesValue{BytesValue: []byte{1, 2, 3}}}, + "StringValue/test": {Value: &AnyValue_StringValue{StringValue: "test_stringvalue"}}, "BoolValue/default": {Value: &AnyValue_BoolValue{BoolValue: false}}, + "BoolValue/test": {Value: &AnyValue_BoolValue{BoolValue: true}}, "IntValue/default": {Value: &AnyValue_IntValue{IntValue: int64(0)}}, + "IntValue/test": {Value: &AnyValue_IntValue{IntValue: int64(13)}}, "DoubleValue/default": {Value: &AnyValue_DoubleValue{DoubleValue: float64(0)}}, + "DoubleValue/test": {Value: &AnyValue_DoubleValue{DoubleValue: float64(3.1415926)}}, "ArrayValue/default": {Value: &AnyValue_ArrayValue{ArrayValue: &ArrayValue{}}}, + "ArrayValue/test": {Value: &AnyValue_ArrayValue{ArrayValue: GenTestArrayValue()}}, "KvlistValue/default": {Value: &AnyValue_KvlistValue{KvlistValue: &KeyValueList{}}}, + "KvlistValue/test": {Value: &AnyValue_KvlistValue{KvlistValue: GenTestKeyValueList()}}, "BytesValue/default": {Value: &AnyValue_BytesValue{BytesValue: nil}}, + "BytesValue/test": {Value: &AnyValue_BytesValue{BytesValue: []byte{1, 2, 3}}}, "StringValueStrindex/default": {Value: &AnyValue_StringValueStrindex{StringValueStrindex: int32(0)}}, + "StringValueStrindex/test": {Value: &AnyValue_StringValueStrindex{StringValueStrindex: int32(13)}}, } } diff --git a/pdata/internal/generated_proto_arrayvalue.go b/pdata/internal/generated_proto_arrayvalue.go index a4367eac263c..dc041f4e6cd1 100644 --- a/pdata/internal/generated_proto_arrayvalue.go +++ b/pdata/internal/generated_proto_arrayvalue.go @@ -11,6 +11,7 @@ import ( "sync" "go.opentelemetry.io/collector/pdata/internal/json" + "go.opentelemetry.io/collector/pdata/internal/metadata" "go.opentelemetry.io/collector/pdata/internal/proto" ) @@ -28,7 +29,7 @@ var ( ) func NewArrayValue() *ArrayValue { - if !UseProtoPooling.IsEnabled() { + if !metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() { return &ArrayValue{} } return protoPoolArrayValue.Get().(*ArrayValue) @@ -39,15 +40,13 @@ func DeleteArrayValue(orig *ArrayValue, nullable bool) { return } - if !UseProtoPooling.IsEnabled() { + if !metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() { orig.Reset() return } - for i := range orig.Values { DeleteAnyValue(&orig.Values[i], false) } - orig.Reset() if nullable { protoPoolArrayValue.Put(orig) diff --git a/pdata/internal/generated_proto_arrayvalue_test.go b/pdata/internal/generated_proto_arrayvalue_test.go index 7b08f3e83ccf..5ee98b06b69b 100644 --- a/pdata/internal/generated_proto_arrayvalue_test.go +++ b/pdata/internal/generated_proto_arrayvalue_test.go @@ -17,16 +17,17 @@ import ( "go.opentelemetry.io/collector/featuregate" "go.opentelemetry.io/collector/pdata/internal/json" + "go.opentelemetry.io/collector/pdata/internal/metadata" ) func TestCopyArrayValue(t *testing.T) { for name, src := range genTestEncodingValuesArrayValue() { for _, pooling := range []bool{true, false} { t.Run(name+"/Pooling="+strconv.FormatBool(pooling), func(t *testing.T) { - prevPooling := UseProtoPooling.IsEnabled() - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), pooling)) + prevPooling := metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), pooling)) defer func() { - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), prevPooling)) + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), prevPooling)) }() dest := NewArrayValue() @@ -102,10 +103,10 @@ func TestMarshalAndUnmarshalJSONArrayValue(t *testing.T) { for name, src := range genTestEncodingValuesArrayValue() { for _, pooling := range []bool{true, false} { t.Run(name+"/Pooling="+strconv.FormatBool(pooling), func(t *testing.T) { - prevPooling := UseProtoPooling.IsEnabled() - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), pooling)) + prevPooling := metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), pooling)) defer func() { - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), prevPooling)) + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), prevPooling)) }() stream := json.BorrowStream(nil) @@ -146,10 +147,10 @@ func TestMarshalAndUnmarshalProtoArrayValue(t *testing.T) { for name, src := range genTestEncodingValuesArrayValue() { for _, pooling := range []bool{true, false} { t.Run(name+"/Pooling="+strconv.FormatBool(pooling), func(t *testing.T) { - prevPooling := UseProtoPooling.IsEnabled() - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), pooling)) + prevPooling := metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), pooling)) defer func() { - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), prevPooling)) + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), prevPooling)) }() buf := make([]byte, src.SizeProto()) diff --git a/pdata/internal/generated_proto_entityref.go b/pdata/internal/generated_proto_entityref.go index 47c562e68138..58c6b3249b73 100644 --- a/pdata/internal/generated_proto_entityref.go +++ b/pdata/internal/generated_proto_entityref.go @@ -11,6 +11,7 @@ import ( "sync" "go.opentelemetry.io/collector/pdata/internal/json" + "go.opentelemetry.io/collector/pdata/internal/metadata" "go.opentelemetry.io/collector/pdata/internal/proto" ) @@ -30,7 +31,7 @@ var ( ) func NewEntityRef() *EntityRef { - if !UseProtoPooling.IsEnabled() { + if !metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() { return &EntityRef{} } return protoPoolEntityRef.Get().(*EntityRef) @@ -41,7 +42,7 @@ func DeleteEntityRef(orig *EntityRef, nullable bool) { return } - if !UseProtoPooling.IsEnabled() { + if !metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() { orig.Reset() return } @@ -66,10 +67,9 @@ func CopyEntityRef(dest, src *EntityRef) *EntityRef { dest = NewEntityRef() } dest.SchemaUrl = src.SchemaUrl - dest.Type = src.Type - dest.IdKeys = append(dest.IdKeys[:0], src.IdKeys...) + dest.DescriptionKeys = append(dest.DescriptionKeys[:0], src.DescriptionKeys...) return dest @@ -148,6 +148,7 @@ func (orig *EntityRef) MarshalJSON(dest *json.Stream) { } dest.WriteArrayEnd() } + if len(orig.DescriptionKeys) > 0 { dest.WriteObjectField("descriptionKeys") dest.WriteArrayStart() @@ -158,6 +159,7 @@ func (orig *EntityRef) MarshalJSON(dest *json.Stream) { } dest.WriteArrayEnd() } + dest.WriteObjectEnd() } @@ -189,10 +191,12 @@ func (orig *EntityRef) SizeProto() int { var n int var l int _ = l + l = len(orig.SchemaUrl) if l > 0 { n += 1 + proto.Sov(uint64(l)) + l } + l = len(orig.Type) if l > 0 { n += 1 + proto.Sov(uint64(l)) + l diff --git a/pdata/internal/generated_proto_entityref_test.go b/pdata/internal/generated_proto_entityref_test.go index ceddc482568f..13cb4e83b366 100644 --- a/pdata/internal/generated_proto_entityref_test.go +++ b/pdata/internal/generated_proto_entityref_test.go @@ -17,16 +17,17 @@ import ( "go.opentelemetry.io/collector/featuregate" "go.opentelemetry.io/collector/pdata/internal/json" + "go.opentelemetry.io/collector/pdata/internal/metadata" ) func TestCopyEntityRef(t *testing.T) { for name, src := range genTestEncodingValuesEntityRef() { for _, pooling := range []bool{true, false} { t.Run(name+"/Pooling="+strconv.FormatBool(pooling), func(t *testing.T) { - prevPooling := UseProtoPooling.IsEnabled() - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), pooling)) + prevPooling := metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), pooling)) defer func() { - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), prevPooling)) + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), prevPooling)) }() dest := NewEntityRef() @@ -102,10 +103,10 @@ func TestMarshalAndUnmarshalJSONEntityRef(t *testing.T) { for name, src := range genTestEncodingValuesEntityRef() { for _, pooling := range []bool{true, false} { t.Run(name+"/Pooling="+strconv.FormatBool(pooling), func(t *testing.T) { - prevPooling := UseProtoPooling.IsEnabled() - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), pooling)) + prevPooling := metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), pooling)) defer func() { - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), prevPooling)) + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), prevPooling)) }() stream := json.BorrowStream(nil) @@ -146,10 +147,10 @@ func TestMarshalAndUnmarshalProtoEntityRef(t *testing.T) { for name, src := range genTestEncodingValuesEntityRef() { for _, pooling := range []bool{true, false} { t.Run(name+"/Pooling="+strconv.FormatBool(pooling), func(t *testing.T) { - prevPooling := UseProtoPooling.IsEnabled() - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), pooling)) + prevPooling := metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), pooling)) defer func() { - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), prevPooling)) + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), prevPooling)) }() buf := make([]byte, src.SizeProto()) diff --git a/pdata/internal/generated_proto_exemplar.go b/pdata/internal/generated_proto_exemplar.go index 29223128d0d6..231d1a79e6c6 100644 --- a/pdata/internal/generated_proto_exemplar.go +++ b/pdata/internal/generated_proto_exemplar.go @@ -13,6 +13,7 @@ import ( "sync" "go.opentelemetry.io/collector/pdata/internal/json" + "go.opentelemetry.io/collector/pdata/internal/metadata" "go.opentelemetry.io/collector/pdata/internal/proto" ) @@ -50,9 +51,9 @@ func (m *Exemplar) GetAsInt() int64 { // Exemplars also hold information about the environment when the measurement was recorded, // for example the span and trace ID of the active span when the exemplar was recorded. type Exemplar struct { + Value any FilteredAttributes []KeyValue TimeUnixNano uint64 - Value any TraceId TraceID SpanId SpanID } @@ -78,7 +79,7 @@ var ( ) func NewExemplar() *Exemplar { - if !UseProtoPooling.IsEnabled() { + if !metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() { return &Exemplar{} } return protoPoolExemplar.Get().(*Exemplar) @@ -89,30 +90,28 @@ func DeleteExemplar(orig *Exemplar, nullable bool) { return } - if !UseProtoPooling.IsEnabled() { + if !metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() { orig.Reset() return } - for i := range orig.FilteredAttributes { DeleteKeyValue(&orig.FilteredAttributes[i], false) } + switch ov := orig.Value.(type) { case *Exemplar_AsDouble: - if UseProtoPooling.IsEnabled() { + if metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() { ov.AsDouble = float64(0) ProtoPoolExemplar_AsDouble.Put(ov) } case *Exemplar_AsInt: - if UseProtoPooling.IsEnabled() { + if metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() { ov.AsInt = int64(0) ProtoPoolExemplar_AsInt.Put(ov) } - } DeleteTraceID(&orig.TraceId, false) DeleteSpanID(&orig.SpanId, false) - orig.Reset() if nullable { protoPoolExemplar.Put(orig) @@ -135,26 +134,27 @@ func CopyExemplar(dest, src *Exemplar) *Exemplar { dest.FilteredAttributes = CopyKeyValueSlice(dest.FilteredAttributes, src.FilteredAttributes) dest.TimeUnixNano = src.TimeUnixNano - switch t := src.Value.(type) { case *Exemplar_AsDouble: var ov *Exemplar_AsDouble - if !UseProtoPooling.IsEnabled() { + if !metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() { ov = &Exemplar_AsDouble{} } else { ov = ProtoPoolExemplar_AsDouble.Get().(*Exemplar_AsDouble) } ov.AsDouble = t.AsDouble dest.Value = ov + case *Exemplar_AsInt: var ov *Exemplar_AsInt - if !UseProtoPooling.IsEnabled() { + if !metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() { ov = &Exemplar_AsInt{} } else { ov = ProtoPoolExemplar_AsInt.Get().(*Exemplar_AsInt) } ov.AsInt = t.AsInt dest.Value = ov + default: dest.Value = nil } @@ -269,7 +269,7 @@ func (orig *Exemplar) UnmarshalJSON(iter *json.Iterator) { case "asDouble", "as_double": { var ov *Exemplar_AsDouble - if !UseProtoPooling.IsEnabled() { + if !metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() { ov = &Exemplar_AsDouble{} } else { ov = ProtoPoolExemplar_AsDouble.Get().(*Exemplar_AsDouble) @@ -277,11 +277,10 @@ func (orig *Exemplar) UnmarshalJSON(iter *json.Iterator) { ov.AsDouble = iter.ReadFloat64() orig.Value = ov } - case "asInt", "as_int": { var ov *Exemplar_AsInt - if !UseProtoPooling.IsEnabled() { + if !metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() { ov = &Exemplar_AsInt{} } else { ov = ProtoPoolExemplar_AsInt.Get().(*Exemplar_AsInt) @@ -310,7 +309,7 @@ func (orig *Exemplar) SizeProto() int { l = orig.FilteredAttributes[i].SizeProto() n += 1 + proto.Sov(uint64(l)) + l } - if orig.TimeUnixNano != 0 { + if orig.TimeUnixNano != uint64(0) { n += 9 } switch orig := orig.Value.(type) { @@ -318,8 +317,10 @@ func (orig *Exemplar) SizeProto() int { _ = orig break case *Exemplar_AsDouble: + n += 9 case *Exemplar_AsInt: + n += 9 } l = orig.TraceId.SizeProto() @@ -340,7 +341,7 @@ func (orig *Exemplar) MarshalProto(buf []byte) int { pos-- buf[pos] = 0x3a } - if orig.TimeUnixNano != 0 { + if orig.TimeUnixNano != uint64(0) { pos -= 8 binary.LittleEndian.PutUint64(buf[pos:], uint64(orig.TimeUnixNano)) pos-- @@ -428,7 +429,7 @@ func (orig *Exemplar) UnmarshalProto(buf []byte) error { return err } var ov *Exemplar_AsDouble - if !UseProtoPooling.IsEnabled() { + if !metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() { ov = &Exemplar_AsDouble{} } else { ov = ProtoPoolExemplar_AsDouble.Get().(*Exemplar_AsDouble) @@ -446,7 +447,7 @@ func (orig *Exemplar) UnmarshalProto(buf []byte) error { return err } var ov *Exemplar_AsInt - if !UseProtoPooling.IsEnabled() { + if !metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() { ov = &Exemplar_AsInt{} } else { ov = ProtoPoolExemplar_AsInt.Get().(*Exemplar_AsInt) diff --git a/pdata/internal/generated_proto_exemplar_test.go b/pdata/internal/generated_proto_exemplar_test.go index bd50bfa99e3a..f083fda8a8b5 100644 --- a/pdata/internal/generated_proto_exemplar_test.go +++ b/pdata/internal/generated_proto_exemplar_test.go @@ -17,16 +17,17 @@ import ( "go.opentelemetry.io/collector/featuregate" "go.opentelemetry.io/collector/pdata/internal/json" + "go.opentelemetry.io/collector/pdata/internal/metadata" ) func TestCopyExemplar(t *testing.T) { for name, src := range genTestEncodingValuesExemplar() { for _, pooling := range []bool{true, false} { t.Run(name+"/Pooling="+strconv.FormatBool(pooling), func(t *testing.T) { - prevPooling := UseProtoPooling.IsEnabled() - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), pooling)) + prevPooling := metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), pooling)) defer func() { - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), prevPooling)) + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), prevPooling)) }() dest := NewExemplar() @@ -102,10 +103,10 @@ func TestMarshalAndUnmarshalJSONExemplar(t *testing.T) { for name, src := range genTestEncodingValuesExemplar() { for _, pooling := range []bool{true, false} { t.Run(name+"/Pooling="+strconv.FormatBool(pooling), func(t *testing.T) { - prevPooling := UseProtoPooling.IsEnabled() - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), pooling)) + prevPooling := metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), pooling)) defer func() { - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), prevPooling)) + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), prevPooling)) }() stream := json.BorrowStream(nil) @@ -146,10 +147,10 @@ func TestMarshalAndUnmarshalProtoExemplar(t *testing.T) { for name, src := range genTestEncodingValuesExemplar() { for _, pooling := range []bool{true, false} { t.Run(name+"/Pooling="+strconv.FormatBool(pooling), func(t *testing.T) { - prevPooling := UseProtoPooling.IsEnabled() - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), pooling)) + prevPooling := metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), pooling)) defer func() { - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), prevPooling)) + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), prevPooling)) }() buf := make([]byte, src.SizeProto()) @@ -196,13 +197,12 @@ func genTestFailingUnmarshalProtoValuesExemplar() map[string][]byte { "AsDouble/wrong_wire_type": {0x1c}, "AsDouble/missing_value": {0x19}, - - "AsInt/wrong_wire_type": {0x34}, - "AsInt/missing_value": {0x31}, - "TraceId/wrong_wire_type": {0x2c}, - "TraceId/missing_value": {0x2a}, - "SpanId/wrong_wire_type": {0x24}, - "SpanId/missing_value": {0x22}, + "AsInt/wrong_wire_type": {0x34}, + "AsInt/missing_value": {0x31}, + "TraceId/wrong_wire_type": {0x2c}, + "TraceId/missing_value": {0x2a}, + "SpanId/wrong_wire_type": {0x24}, + "SpanId/missing_value": {0x22}, } } @@ -212,10 +212,9 @@ func genTestEncodingValuesExemplar() map[string]*Exemplar { "FilteredAttributes/test": {FilteredAttributes: []KeyValue{{}, *GenTestKeyValue()}}, "TimeUnixNano/test": {TimeUnixNano: uint64(13)}, "AsDouble/default": {Value: &Exemplar_AsDouble{AsDouble: float64(0)}}, - "AsDouble/test": {Value: &Exemplar_AsDouble{AsDouble: float64(3.1415926)}}, - "AsInt/default": {Value: &Exemplar_AsInt{AsInt: int64(0)}}, - "AsInt/test": {Value: &Exemplar_AsInt{AsInt: int64(13)}}, - "TraceId/test": {TraceId: *GenTestTraceID()}, - "SpanId/test": {SpanId: *GenTestSpanID()}, + "AsDouble/test": {Value: &Exemplar_AsDouble{AsDouble: float64(3.1415926)}}, "AsInt/default": {Value: &Exemplar_AsInt{AsInt: int64(0)}}, + "AsInt/test": {Value: &Exemplar_AsInt{AsInt: int64(13)}}, + "TraceId/test": {TraceId: *GenTestTraceID()}, + "SpanId/test": {SpanId: *GenTestSpanID()}, } } diff --git a/pdata/internal/generated_proto_exponentialhistogram.go b/pdata/internal/generated_proto_exponentialhistogram.go index 926816346a9b..d46dc13448e6 100644 --- a/pdata/internal/generated_proto_exponentialhistogram.go +++ b/pdata/internal/generated_proto_exponentialhistogram.go @@ -11,6 +11,7 @@ import ( "sync" "go.opentelemetry.io/collector/pdata/internal/json" + "go.opentelemetry.io/collector/pdata/internal/metadata" "go.opentelemetry.io/collector/pdata/internal/proto" ) @@ -30,7 +31,7 @@ var ( ) func NewExponentialHistogram() *ExponentialHistogram { - if !UseProtoPooling.IsEnabled() { + if !metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() { return &ExponentialHistogram{} } return protoPoolExponentialHistogram.Get().(*ExponentialHistogram) @@ -41,11 +42,10 @@ func DeleteExponentialHistogram(orig *ExponentialHistogram, nullable bool) { return } - if !UseProtoPooling.IsEnabled() { + if !metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() { orig.Reset() return } - for i := range orig.DataPoints { DeleteExponentialHistogramDataPoint(orig.DataPoints[i], true) } @@ -175,7 +175,7 @@ func (orig *ExponentialHistogram) SizeProto() int { l = orig.DataPoints[i].SizeProto() n += 1 + proto.Sov(uint64(l)) + l } - if orig.AggregationTemporality != 0 { + if orig.AggregationTemporality != AggregationTemporality(0) { n += 1 + proto.Sov(uint64(orig.AggregationTemporality)) } return n @@ -192,7 +192,7 @@ func (orig *ExponentialHistogram) MarshalProto(buf []byte) int { pos-- buf[pos] = 0xa } - if orig.AggregationTemporality != 0 { + if orig.AggregationTemporality != AggregationTemporality(0) { pos = proto.EncodeVarint(buf, pos, uint64(orig.AggregationTemporality)) pos-- buf[pos] = 0x10 @@ -240,7 +240,6 @@ func (orig *ExponentialHistogram) UnmarshalProto(buf []byte) error { if err != nil { return err } - orig.AggregationTemporality = AggregationTemporality(num) default: pos, err = proto.ConsumeUnknown(buf, pos, wireType) diff --git a/pdata/internal/generated_proto_exponentialhistogram_test.go b/pdata/internal/generated_proto_exponentialhistogram_test.go index 9a153b76830d..e57192ce9a8f 100644 --- a/pdata/internal/generated_proto_exponentialhistogram_test.go +++ b/pdata/internal/generated_proto_exponentialhistogram_test.go @@ -17,16 +17,17 @@ import ( "go.opentelemetry.io/collector/featuregate" "go.opentelemetry.io/collector/pdata/internal/json" + "go.opentelemetry.io/collector/pdata/internal/metadata" ) func TestCopyExponentialHistogram(t *testing.T) { for name, src := range genTestEncodingValuesExponentialHistogram() { for _, pooling := range []bool{true, false} { t.Run(name+"/Pooling="+strconv.FormatBool(pooling), func(t *testing.T) { - prevPooling := UseProtoPooling.IsEnabled() - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), pooling)) + prevPooling := metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), pooling)) defer func() { - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), prevPooling)) + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), prevPooling)) }() dest := NewExponentialHistogram() @@ -102,10 +103,10 @@ func TestMarshalAndUnmarshalJSONExponentialHistogram(t *testing.T) { for name, src := range genTestEncodingValuesExponentialHistogram() { for _, pooling := range []bool{true, false} { t.Run(name+"/Pooling="+strconv.FormatBool(pooling), func(t *testing.T) { - prevPooling := UseProtoPooling.IsEnabled() - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), pooling)) + prevPooling := metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), pooling)) defer func() { - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), prevPooling)) + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), prevPooling)) }() stream := json.BorrowStream(nil) @@ -146,10 +147,10 @@ func TestMarshalAndUnmarshalProtoExponentialHistogram(t *testing.T) { for name, src := range genTestEncodingValuesExponentialHistogram() { for _, pooling := range []bool{true, false} { t.Run(name+"/Pooling="+strconv.FormatBool(pooling), func(t *testing.T) { - prevPooling := UseProtoPooling.IsEnabled() - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), pooling)) + prevPooling := metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), pooling)) defer func() { - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), prevPooling)) + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), prevPooling)) }() buf := make([]byte, src.SizeProto()) diff --git a/pdata/internal/generated_proto_exponentialhistogramdatapoint.go b/pdata/internal/generated_proto_exponentialhistogramdatapoint.go index d16c0120ebdb..c637459b3c6d 100644 --- a/pdata/internal/generated_proto_exponentialhistogramdatapoint.go +++ b/pdata/internal/generated_proto_exponentialhistogramdatapoint.go @@ -13,82 +13,30 @@ import ( "sync" "go.opentelemetry.io/collector/pdata/internal/json" + "go.opentelemetry.io/collector/pdata/internal/metadata" "go.opentelemetry.io/collector/pdata/internal/proto" ) -func (m *ExponentialHistogramDataPoint) GetSum_() any { - if m != nil { - return m.Sum_ - } - return nil -} - -type ExponentialHistogramDataPoint_Sum struct { - Sum float64 -} - -func (m *ExponentialHistogramDataPoint) GetSum() float64 { - if v, ok := m.GetSum_().(*ExponentialHistogramDataPoint_Sum); ok { - return v.Sum - } - return float64(0) -} - -func (m *ExponentialHistogramDataPoint) GetMin_() any { - if m != nil { - return m.Min_ - } - return nil -} - -type ExponentialHistogramDataPoint_Min struct { - Min float64 -} - -func (m *ExponentialHistogramDataPoint) GetMin() float64 { - if v, ok := m.GetMin_().(*ExponentialHistogramDataPoint_Min); ok { - return v.Min - } - return float64(0) -} - -func (m *ExponentialHistogramDataPoint) GetMax_() any { - if m != nil { - return m.Max_ - } - return nil -} - -type ExponentialHistogramDataPoint_Max struct { - Max float64 -} - -func (m *ExponentialHistogramDataPoint) GetMax() float64 { - if v, ok := m.GetMax_().(*ExponentialHistogramDataPoint_Max); ok { - return v.Max - } - return float64(0) -} - // ExponentialHistogramDataPoint is a single data point in a timeseries that describes the // time-varying values of a ExponentialHistogram of double values. A ExponentialHistogram contains // summary statistics for a population of values, it may optionally contain the // distribution of those values across a set of buckets. type ExponentialHistogramDataPoint struct { + Positive ExponentialHistogramDataPointBuckets + Negative ExponentialHistogramDataPointBuckets Attributes []KeyValue + Exemplars []Exemplar StartTimeUnixNano uint64 TimeUnixNano uint64 Count uint64 - Sum_ any - Scale int32 + Sum float64 ZeroCount uint64 - Positive ExponentialHistogramDataPointBuckets - Negative ExponentialHistogramDataPointBuckets - Flags uint32 - Exemplars []Exemplar - Min_ any - Max_ any + Min float64 + Max float64 ZeroThreshold float64 + metadata [1]uint64 + Scale int32 + Flags uint32 } var ( @@ -97,27 +45,10 @@ var ( return &ExponentialHistogramDataPoint{} }, } - ProtoPoolExponentialHistogramDataPoint_Sum = sync.Pool{ - New: func() any { - return &ExponentialHistogramDataPoint_Sum{} - }, - } - - ProtoPoolExponentialHistogramDataPoint_Min = sync.Pool{ - New: func() any { - return &ExponentialHistogramDataPoint_Min{} - }, - } - - ProtoPoolExponentialHistogramDataPoint_Max = sync.Pool{ - New: func() any { - return &ExponentialHistogramDataPoint_Max{} - }, - } ) func NewExponentialHistogramDataPoint() *ExponentialHistogramDataPoint { - if !UseProtoPooling.IsEnabled() { + if !metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() { return &ExponentialHistogramDataPoint{} } return protoPoolExponentialHistogramDataPoint.Get().(*ExponentialHistogramDataPoint) @@ -128,43 +59,20 @@ func DeleteExponentialHistogramDataPoint(orig *ExponentialHistogramDataPoint, nu return } - if !UseProtoPooling.IsEnabled() { + if !metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() { orig.Reset() return } - for i := range orig.Attributes { DeleteKeyValue(&orig.Attributes[i], false) } - switch ov := orig.Sum_.(type) { - case *ExponentialHistogramDataPoint_Sum: - if UseProtoPooling.IsEnabled() { - ov.Sum = float64(0) - ProtoPoolExponentialHistogramDataPoint_Sum.Put(ov) - } - } DeleteExponentialHistogramDataPointBuckets(&orig.Positive, false) DeleteExponentialHistogramDataPointBuckets(&orig.Negative, false) + for i := range orig.Exemplars { DeleteExemplar(&orig.Exemplars[i], false) } - switch ov := orig.Min_.(type) { - case *ExponentialHistogramDataPoint_Min: - if UseProtoPooling.IsEnabled() { - ov.Min = float64(0) - ProtoPoolExponentialHistogramDataPoint_Min.Put(ov) - } - - } - switch ov := orig.Max_.(type) { - case *ExponentialHistogramDataPoint_Max: - if UseProtoPooling.IsEnabled() { - ov.Max = float64(0) - ProtoPoolExponentialHistogramDataPoint_Max.Put(ov) - } - - } orig.Reset() if nullable { @@ -188,63 +96,33 @@ func CopyExponentialHistogramDataPoint(dest, src *ExponentialHistogramDataPoint) dest.Attributes = CopyKeyValueSlice(dest.Attributes, src.Attributes) dest.StartTimeUnixNano = src.StartTimeUnixNano - dest.TimeUnixNano = src.TimeUnixNano - dest.Count = src.Count - - switch t := src.Sum_.(type) { - case *ExponentialHistogramDataPoint_Sum: - var ov *ExponentialHistogramDataPoint_Sum - if !UseProtoPooling.IsEnabled() { - ov = &ExponentialHistogramDataPoint_Sum{} - } else { - ov = ProtoPoolExponentialHistogramDataPoint_Sum.Get().(*ExponentialHistogramDataPoint_Sum) - } - ov.Sum = t.Sum - dest.Sum_ = ov - default: - dest.Sum_ = nil + if src.HasSum() { + dest.SetSum(src.Sum) + } else { + dest.RemoveSum() } dest.Scale = src.Scale - dest.ZeroCount = src.ZeroCount - CopyExponentialHistogramDataPointBuckets(&dest.Positive, &src.Positive) CopyExponentialHistogramDataPointBuckets(&dest.Negative, &src.Negative) dest.Flags = src.Flags - dest.Exemplars = CopyExemplarSlice(dest.Exemplars, src.Exemplars) - switch t := src.Min_.(type) { - case *ExponentialHistogramDataPoint_Min: - var ov *ExponentialHistogramDataPoint_Min - if !UseProtoPooling.IsEnabled() { - ov = &ExponentialHistogramDataPoint_Min{} - } else { - ov = ProtoPoolExponentialHistogramDataPoint_Min.Get().(*ExponentialHistogramDataPoint_Min) - } - ov.Min = t.Min - dest.Min_ = ov - default: - dest.Min_ = nil - } - - switch t := src.Max_.(type) { - case *ExponentialHistogramDataPoint_Max: - var ov *ExponentialHistogramDataPoint_Max - if !UseProtoPooling.IsEnabled() { - ov = &ExponentialHistogramDataPoint_Max{} - } else { - ov = ProtoPoolExponentialHistogramDataPoint_Max.Get().(*ExponentialHistogramDataPoint_Max) - } - ov.Max = t.Max - dest.Max_ = ov - default: - dest.Max_ = nil + if src.HasMin() { + dest.SetMin(src.Min) + } else { + dest.RemoveMin() + } + + if src.HasMax() { + dest.SetMax(src.Max) + } else { + dest.RemoveMax() } dest.ZeroThreshold = src.ZeroThreshold @@ -329,7 +207,7 @@ func (orig *ExponentialHistogramDataPoint) MarshalJSON(dest *json.Stream) { dest.WriteObjectField("count") dest.WriteUint64(orig.Count) } - if orig, ok := orig.Sum_.(*ExponentialHistogramDataPoint_Sum); ok { + if orig.HasSum() { dest.WriteObjectField("sum") dest.WriteFloat64(orig.Sum) } @@ -359,11 +237,11 @@ func (orig *ExponentialHistogramDataPoint) MarshalJSON(dest *json.Stream) { } dest.WriteArrayEnd() } - if orig, ok := orig.Min_.(*ExponentialHistogramDataPoint_Min); ok { + if orig.HasMin() { dest.WriteObjectField("min") dest.WriteFloat64(orig.Min) } - if orig, ok := orig.Max_.(*ExponentialHistogramDataPoint_Max); ok { + if orig.HasMax() { dest.WriteObjectField("max") dest.WriteFloat64(orig.Max) } @@ -391,16 +269,7 @@ func (orig *ExponentialHistogramDataPoint) UnmarshalJSON(iter *json.Iterator) { case "count": orig.Count = iter.ReadUint64() case "sum": - { - var ov *ExponentialHistogramDataPoint_Sum - if !UseProtoPooling.IsEnabled() { - ov = &ExponentialHistogramDataPoint_Sum{} - } else { - ov = ProtoPoolExponentialHistogramDataPoint_Sum.Get().(*ExponentialHistogramDataPoint_Sum) - } - ov.Sum = iter.ReadFloat64() - orig.Sum_ = ov - } + orig.SetSum(iter.ReadFloat64()) case "scale": orig.Scale = iter.ReadInt32() @@ -421,28 +290,10 @@ func (orig *ExponentialHistogramDataPoint) UnmarshalJSON(iter *json.Iterator) { } case "min": - { - var ov *ExponentialHistogramDataPoint_Min - if !UseProtoPooling.IsEnabled() { - ov = &ExponentialHistogramDataPoint_Min{} - } else { - ov = ProtoPoolExponentialHistogramDataPoint_Min.Get().(*ExponentialHistogramDataPoint_Min) - } - ov.Min = iter.ReadFloat64() - orig.Min_ = ov - } + orig.SetMin(iter.ReadFloat64()) case "max": - { - var ov *ExponentialHistogramDataPoint_Max - if !UseProtoPooling.IsEnabled() { - ov = &ExponentialHistogramDataPoint_Max{} - } else { - ov = ProtoPoolExponentialHistogramDataPoint_Max.Get().(*ExponentialHistogramDataPoint_Max) - } - ov.Max = iter.ReadFloat64() - orig.Max_ = ov - } + orig.SetMax(iter.ReadFloat64()) case "zeroThreshold", "zero_threshold": orig.ZeroThreshold = iter.ReadFloat64() @@ -460,45 +311,42 @@ func (orig *ExponentialHistogramDataPoint) SizeProto() int { l = orig.Attributes[i].SizeProto() n += 1 + proto.Sov(uint64(l)) + l } - if orig.StartTimeUnixNano != 0 { + if orig.StartTimeUnixNano != uint64(0) { n += 9 } - if orig.TimeUnixNano != 0 { + if orig.TimeUnixNano != uint64(0) { n += 9 } - if orig.Count != 0 { + if orig.Count != uint64(0) { n += 9 } - if orig, ok := orig.Sum_.(*ExponentialHistogramDataPoint_Sum); ok { - _ = orig + if orig.HasSum() { n += 9 } - if orig.Scale != 0 { + if orig.Scale != int32(0) { n += 1 + proto.Soz(uint64(orig.Scale)) } - if orig.ZeroCount != 0 { + if orig.ZeroCount != uint64(0) { n += 9 } l = orig.Positive.SizeProto() n += 1 + proto.Sov(uint64(l)) + l l = orig.Negative.SizeProto() n += 1 + proto.Sov(uint64(l)) + l - if orig.Flags != 0 { + if orig.Flags != uint32(0) { n += 1 + proto.Sov(uint64(orig.Flags)) } for i := range orig.Exemplars { l = orig.Exemplars[i].SizeProto() n += 1 + proto.Sov(uint64(l)) + l } - if orig, ok := orig.Min_.(*ExponentialHistogramDataPoint_Min); ok { - _ = orig + if orig.HasMin() { n += 9 } - if orig, ok := orig.Max_.(*ExponentialHistogramDataPoint_Max); ok { - _ = orig + if orig.HasMax() { n += 9 } - if orig.ZeroThreshold != 0 { + if orig.ZeroThreshold != float64(0) { n += 9 } return n @@ -515,36 +363,36 @@ func (orig *ExponentialHistogramDataPoint) MarshalProto(buf []byte) int { pos-- buf[pos] = 0xa } - if orig.StartTimeUnixNano != 0 { + if orig.StartTimeUnixNano != uint64(0) { pos -= 8 binary.LittleEndian.PutUint64(buf[pos:], uint64(orig.StartTimeUnixNano)) pos-- buf[pos] = 0x11 } - if orig.TimeUnixNano != 0 { + if orig.TimeUnixNano != uint64(0) { pos -= 8 binary.LittleEndian.PutUint64(buf[pos:], uint64(orig.TimeUnixNano)) pos-- buf[pos] = 0x19 } - if orig.Count != 0 { + if orig.Count != uint64(0) { pos -= 8 binary.LittleEndian.PutUint64(buf[pos:], uint64(orig.Count)) pos-- buf[pos] = 0x21 } - if orig, ok := orig.Sum_.(*ExponentialHistogramDataPoint_Sum); ok { + if orig.HasSum() { pos -= 8 binary.LittleEndian.PutUint64(buf[pos:], math.Float64bits(orig.Sum)) pos-- buf[pos] = 0x29 } - if orig.Scale != 0 { + if orig.Scale != int32(0) { pos = proto.EncodeVarint(buf, pos, uint64((uint32(orig.Scale)<<1)^uint32(orig.Scale>>31))) pos-- buf[pos] = 0x30 } - if orig.ZeroCount != 0 { + if orig.ZeroCount != uint64(0) { pos -= 8 binary.LittleEndian.PutUint64(buf[pos:], uint64(orig.ZeroCount)) pos-- @@ -562,7 +410,7 @@ func (orig *ExponentialHistogramDataPoint) MarshalProto(buf []byte) int { pos-- buf[pos] = 0x4a - if orig.Flags != 0 { + if orig.Flags != uint32(0) { pos = proto.EncodeVarint(buf, pos, uint64(orig.Flags)) pos-- buf[pos] = 0x50 @@ -574,19 +422,19 @@ func (orig *ExponentialHistogramDataPoint) MarshalProto(buf []byte) int { pos-- buf[pos] = 0x5a } - if orig, ok := orig.Min_.(*ExponentialHistogramDataPoint_Min); ok { + if orig.HasMin() { pos -= 8 binary.LittleEndian.PutUint64(buf[pos:], math.Float64bits(orig.Min)) pos-- buf[pos] = 0x61 } - if orig, ok := orig.Max_.(*ExponentialHistogramDataPoint_Max); ok { + if orig.HasMax() { pos -= 8 binary.LittleEndian.PutUint64(buf[pos:], math.Float64bits(orig.Max)) pos-- buf[pos] = 0x69 } - if orig.ZeroThreshold != 0 { + if orig.ZeroThreshold != float64(0) { pos -= 8 binary.LittleEndian.PutUint64(buf[pos:], math.Float64bits(orig.ZeroThreshold)) pos-- @@ -671,14 +519,7 @@ func (orig *ExponentialHistogramDataPoint) UnmarshalProto(buf []byte) error { if err != nil { return err } - var ov *ExponentialHistogramDataPoint_Sum - if !UseProtoPooling.IsEnabled() { - ov = &ExponentialHistogramDataPoint_Sum{} - } else { - ov = ProtoPoolExponentialHistogramDataPoint_Sum.Get().(*ExponentialHistogramDataPoint_Sum) - } - ov.Sum = math.Float64frombits(num) - orig.Sum_ = ov + orig.SetSum(math.Float64frombits(num)) case 6: if wireType != proto.WireTypeVarint { @@ -689,7 +530,6 @@ func (orig *ExponentialHistogramDataPoint) UnmarshalProto(buf []byte) error { if err != nil { return err } - orig.Scale = int32(uint32(num>>1) ^ uint32(int32((num&1)<<31)>>31)) case 7: @@ -745,7 +585,6 @@ func (orig *ExponentialHistogramDataPoint) UnmarshalProto(buf []byte) error { if err != nil { return err } - orig.Flags = uint32(num) case 11: @@ -773,14 +612,7 @@ func (orig *ExponentialHistogramDataPoint) UnmarshalProto(buf []byte) error { if err != nil { return err } - var ov *ExponentialHistogramDataPoint_Min - if !UseProtoPooling.IsEnabled() { - ov = &ExponentialHistogramDataPoint_Min{} - } else { - ov = ProtoPoolExponentialHistogramDataPoint_Min.Get().(*ExponentialHistogramDataPoint_Min) - } - ov.Min = math.Float64frombits(num) - orig.Min_ = ov + orig.SetMin(math.Float64frombits(num)) case 13: if wireType != proto.WireTypeI64 { @@ -791,14 +623,7 @@ func (orig *ExponentialHistogramDataPoint) UnmarshalProto(buf []byte) error { if err != nil { return err } - var ov *ExponentialHistogramDataPoint_Max - if !UseProtoPooling.IsEnabled() { - ov = &ExponentialHistogramDataPoint_Max{} - } else { - ov = ProtoPoolExponentialHistogramDataPoint_Max.Get().(*ExponentialHistogramDataPoint_Max) - } - ov.Max = math.Float64frombits(num) - orig.Max_ = ov + orig.SetMax(math.Float64frombits(num)) case 14: if wireType != proto.WireTypeI64 { @@ -809,7 +634,6 @@ func (orig *ExponentialHistogramDataPoint) UnmarshalProto(buf []byte) error { if err != nil { return err } - orig.ZeroThreshold = math.Float64frombits(num) default: pos, err = proto.ConsumeUnknown(buf, pos, wireType) @@ -821,21 +645,72 @@ func (orig *ExponentialHistogramDataPoint) UnmarshalProto(buf []byte) error { return nil } +const fieldBlockExponentialHistogramDataPointSum = uint64(0 >> 6) +const fieldBitExponentialHistogramDataPointSum = uint64(1 << 0 & 0x3F) + +func (m *ExponentialHistogramDataPoint) SetSum(value float64) { + m.Sum = value + m.metadata[fieldBlockExponentialHistogramDataPointSum] |= fieldBitExponentialHistogramDataPointSum +} + +func (m *ExponentialHistogramDataPoint) RemoveSum() { + m.Sum = float64(0) + m.metadata[fieldBlockExponentialHistogramDataPointSum] &^= fieldBitExponentialHistogramDataPointSum +} + +func (m *ExponentialHistogramDataPoint) HasSum() bool { + return m.metadata[fieldBlockExponentialHistogramDataPointSum]&fieldBitExponentialHistogramDataPointSum != 0 +} + +const fieldBlockExponentialHistogramDataPointMin = uint64(1 >> 6) +const fieldBitExponentialHistogramDataPointMin = uint64(1 << 1 & 0x3F) + +func (m *ExponentialHistogramDataPoint) SetMin(value float64) { + m.Min = value + m.metadata[fieldBlockExponentialHistogramDataPointMin] |= fieldBitExponentialHistogramDataPointMin +} + +func (m *ExponentialHistogramDataPoint) RemoveMin() { + m.Min = float64(0) + m.metadata[fieldBlockExponentialHistogramDataPointMin] &^= fieldBitExponentialHistogramDataPointMin +} + +func (m *ExponentialHistogramDataPoint) HasMin() bool { + return m.metadata[fieldBlockExponentialHistogramDataPointMin]&fieldBitExponentialHistogramDataPointMin != 0 +} + +const fieldBlockExponentialHistogramDataPointMax = uint64(2 >> 6) +const fieldBitExponentialHistogramDataPointMax = uint64(1 << 2 & 0x3F) + +func (m *ExponentialHistogramDataPoint) SetMax(value float64) { + m.Max = value + m.metadata[fieldBlockExponentialHistogramDataPointMax] |= fieldBitExponentialHistogramDataPointMax +} + +func (m *ExponentialHistogramDataPoint) RemoveMax() { + m.Max = float64(0) + m.metadata[fieldBlockExponentialHistogramDataPointMax] &^= fieldBitExponentialHistogramDataPointMax +} + +func (m *ExponentialHistogramDataPoint) HasMax() bool { + return m.metadata[fieldBlockExponentialHistogramDataPointMax]&fieldBitExponentialHistogramDataPointMax != 0 +} + func GenTestExponentialHistogramDataPoint() *ExponentialHistogramDataPoint { orig := NewExponentialHistogramDataPoint() orig.Attributes = []KeyValue{{}, *GenTestKeyValue()} orig.StartTimeUnixNano = uint64(13) orig.TimeUnixNano = uint64(13) orig.Count = uint64(13) - orig.Sum_ = &ExponentialHistogramDataPoint_Sum{Sum: float64(3.1415926)} + orig.SetSum(float64(3.1415926)) orig.Scale = int32(13) orig.ZeroCount = uint64(13) orig.Positive = *GenTestExponentialHistogramDataPointBuckets() orig.Negative = *GenTestExponentialHistogramDataPointBuckets() orig.Flags = uint32(13) orig.Exemplars = []Exemplar{{}, *GenTestExemplar()} - orig.Min_ = &ExponentialHistogramDataPoint_Min{Min: float64(3.1415926)} - orig.Max_ = &ExponentialHistogramDataPoint_Max{Max: float64(3.1415926)} + orig.SetMin(float64(3.1415926)) + orig.SetMax(float64(3.1415926)) orig.ZeroThreshold = float64(3.1415926) return orig } diff --git a/pdata/internal/generated_proto_exponentialhistogramdatapoint_test.go b/pdata/internal/generated_proto_exponentialhistogramdatapoint_test.go index b9e6436ff104..ece79726363a 100644 --- a/pdata/internal/generated_proto_exponentialhistogramdatapoint_test.go +++ b/pdata/internal/generated_proto_exponentialhistogramdatapoint_test.go @@ -17,16 +17,17 @@ import ( "go.opentelemetry.io/collector/featuregate" "go.opentelemetry.io/collector/pdata/internal/json" + "go.opentelemetry.io/collector/pdata/internal/metadata" ) func TestCopyExponentialHistogramDataPoint(t *testing.T) { for name, src := range genTestEncodingValuesExponentialHistogramDataPoint() { for _, pooling := range []bool{true, false} { t.Run(name+"/Pooling="+strconv.FormatBool(pooling), func(t *testing.T) { - prevPooling := UseProtoPooling.IsEnabled() - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), pooling)) + prevPooling := metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), pooling)) defer func() { - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), prevPooling)) + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), prevPooling)) }() dest := NewExponentialHistogramDataPoint() @@ -102,10 +103,10 @@ func TestMarshalAndUnmarshalJSONExponentialHistogramDataPoint(t *testing.T) { for name, src := range genTestEncodingValuesExponentialHistogramDataPoint() { for _, pooling := range []bool{true, false} { t.Run(name+"/Pooling="+strconv.FormatBool(pooling), func(t *testing.T) { - prevPooling := UseProtoPooling.IsEnabled() - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), pooling)) + prevPooling := metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), pooling)) defer func() { - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), prevPooling)) + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), prevPooling)) }() stream := json.BorrowStream(nil) @@ -146,10 +147,10 @@ func TestMarshalAndUnmarshalProtoExponentialHistogramDataPoint(t *testing.T) { for name, src := range genTestEncodingValuesExponentialHistogramDataPoint() { for _, pooling := range []bool{true, false} { t.Run(name+"/Pooling="+strconv.FormatBool(pooling), func(t *testing.T) { - prevPooling := UseProtoPooling.IsEnabled() - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), pooling)) + prevPooling := metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), pooling)) defer func() { - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), prevPooling)) + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), prevPooling)) }() buf := make([]byte, src.SizeProto()) @@ -226,16 +227,28 @@ func genTestEncodingValuesExponentialHistogramDataPoint() map[string]*Exponentia "Attributes/test": {Attributes: []KeyValue{{}, *GenTestKeyValue()}}, "StartTimeUnixNano/test": {StartTimeUnixNano: uint64(13)}, "TimeUnixNano/test": {TimeUnixNano: uint64(13)}, - "Count/test": {Count: uint64(13)}, "Sum/default": {Sum_: &ExponentialHistogramDataPoint_Sum{Sum: float64(0)}}, - "Sum/test": {Sum_: &ExponentialHistogramDataPoint_Sum{Sum: float64(3.1415926)}}, + "Count/test": {Count: uint64(13)}, + "Sum/test": func() *ExponentialHistogramDataPoint { + ms := NewExponentialHistogramDataPoint() + ms.SetSum(float64(3.1415926)) + return ms + }(), "Scale/test": {Scale: int32(13)}, "ZeroCount/test": {ZeroCount: uint64(13)}, "Positive/test": {Positive: *GenTestExponentialHistogramDataPointBuckets()}, "Negative/test": {Negative: *GenTestExponentialHistogramDataPointBuckets()}, "Flags/test": {Flags: uint32(13)}, - "Exemplars/test": {Exemplars: []Exemplar{{}, *GenTestExemplar()}}, "Min/default": {Min_: &ExponentialHistogramDataPoint_Min{Min: float64(0)}}, - "Min/test": {Min_: &ExponentialHistogramDataPoint_Min{Min: float64(3.1415926)}}, "Max/default": {Max_: &ExponentialHistogramDataPoint_Max{Max: float64(0)}}, - "Max/test": {Max_: &ExponentialHistogramDataPoint_Max{Max: float64(3.1415926)}}, + "Exemplars/test": {Exemplars: []Exemplar{{}, *GenTestExemplar()}}, + "Min/test": func() *ExponentialHistogramDataPoint { + ms := NewExponentialHistogramDataPoint() + ms.SetMin(float64(3.1415926)) + return ms + }(), + "Max/test": func() *ExponentialHistogramDataPoint { + ms := NewExponentialHistogramDataPoint() + ms.SetMax(float64(3.1415926)) + return ms + }(), "ZeroThreshold/test": {ZeroThreshold: float64(3.1415926)}, } } diff --git a/pdata/internal/generated_proto_exponentialhistogramdatapointbuckets.go b/pdata/internal/generated_proto_exponentialhistogramdatapointbuckets.go index 459dfe0c38be..6908a66d2665 100644 --- a/pdata/internal/generated_proto_exponentialhistogramdatapointbuckets.go +++ b/pdata/internal/generated_proto_exponentialhistogramdatapointbuckets.go @@ -11,13 +11,14 @@ import ( "sync" "go.opentelemetry.io/collector/pdata/internal/json" + "go.opentelemetry.io/collector/pdata/internal/metadata" "go.opentelemetry.io/collector/pdata/internal/proto" ) // ExponentialHistogramDataPointBuckets are a set of bucket counts, encoded in a contiguous array of counts. type ExponentialHistogramDataPointBuckets struct { - Offset int32 BucketCounts []uint64 + Offset int32 } var ( @@ -29,7 +30,7 @@ var ( ) func NewExponentialHistogramDataPointBuckets() *ExponentialHistogramDataPointBuckets { - if !UseProtoPooling.IsEnabled() { + if !metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() { return &ExponentialHistogramDataPointBuckets{} } return protoPoolExponentialHistogramDataPointBuckets.Get().(*ExponentialHistogramDataPointBuckets) @@ -40,7 +41,7 @@ func DeleteExponentialHistogramDataPointBuckets(orig *ExponentialHistogramDataPo return } - if !UseProtoPooling.IsEnabled() { + if !metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() { orig.Reset() return } @@ -65,7 +66,6 @@ func CopyExponentialHistogramDataPointBuckets(dest, src *ExponentialHistogramDat dest = NewExponentialHistogramDataPointBuckets() } dest.Offset = src.Offset - dest.BucketCounts = append(dest.BucketCounts[:0], src.BucketCounts...) return dest @@ -140,6 +140,7 @@ func (orig *ExponentialHistogramDataPointBuckets) MarshalJSON(dest *json.Stream) } dest.WriteArrayEnd() } + dest.WriteObjectEnd() } @@ -164,9 +165,10 @@ func (orig *ExponentialHistogramDataPointBuckets) SizeProto() int { var n int var l int _ = l - if orig.Offset != 0 { + if orig.Offset != int32(0) { n += 1 + proto.Soz(uint64(orig.Offset)) } + if len(orig.BucketCounts) > 0 { l = 0 for _, e := range orig.BucketCounts { @@ -181,7 +183,7 @@ func (orig *ExponentialHistogramDataPointBuckets) MarshalProto(buf []byte) int { pos := len(buf) var l int _ = l - if orig.Offset != 0 { + if orig.Offset != int32(0) { pos = proto.EncodeVarint(buf, pos, uint64((uint32(orig.Offset)<<1)^uint32(orig.Offset>>31))) pos-- buf[pos] = 0x8 @@ -223,7 +225,6 @@ func (orig *ExponentialHistogramDataPointBuckets) UnmarshalProto(buf []byte) err if err != nil { return err } - orig.Offset = int32(uint32(num>>1) ^ uint32(int32((num&1)<<31)>>31)) case 2: switch wireType { diff --git a/pdata/internal/generated_proto_exponentialhistogramdatapointbuckets_test.go b/pdata/internal/generated_proto_exponentialhistogramdatapointbuckets_test.go index dd89b4812d05..e0227cffc15d 100644 --- a/pdata/internal/generated_proto_exponentialhistogramdatapointbuckets_test.go +++ b/pdata/internal/generated_proto_exponentialhistogramdatapointbuckets_test.go @@ -17,16 +17,17 @@ import ( "go.opentelemetry.io/collector/featuregate" "go.opentelemetry.io/collector/pdata/internal/json" + "go.opentelemetry.io/collector/pdata/internal/metadata" ) func TestCopyExponentialHistogramDataPointBuckets(t *testing.T) { for name, src := range genTestEncodingValuesExponentialHistogramDataPointBuckets() { for _, pooling := range []bool{true, false} { t.Run(name+"/Pooling="+strconv.FormatBool(pooling), func(t *testing.T) { - prevPooling := UseProtoPooling.IsEnabled() - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), pooling)) + prevPooling := metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), pooling)) defer func() { - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), prevPooling)) + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), prevPooling)) }() dest := NewExponentialHistogramDataPointBuckets() @@ -102,10 +103,10 @@ func TestMarshalAndUnmarshalJSONExponentialHistogramDataPointBuckets(t *testing. for name, src := range genTestEncodingValuesExponentialHistogramDataPointBuckets() { for _, pooling := range []bool{true, false} { t.Run(name+"/Pooling="+strconv.FormatBool(pooling), func(t *testing.T) { - prevPooling := UseProtoPooling.IsEnabled() - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), pooling)) + prevPooling := metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), pooling)) defer func() { - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), prevPooling)) + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), prevPooling)) }() stream := json.BorrowStream(nil) @@ -146,10 +147,10 @@ func TestMarshalAndUnmarshalProtoExponentialHistogramDataPointBuckets(t *testing for name, src := range genTestEncodingValuesExponentialHistogramDataPointBuckets() { for _, pooling := range []bool{true, false} { t.Run(name+"/Pooling="+strconv.FormatBool(pooling), func(t *testing.T) { - prevPooling := UseProtoPooling.IsEnabled() - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), pooling)) + prevPooling := metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), pooling)) defer func() { - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), prevPooling)) + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), prevPooling)) }() buf := make([]byte, src.SizeProto()) diff --git a/pdata/internal/generated_proto_exportlogspartialsuccess.go b/pdata/internal/generated_proto_exportlogspartialsuccess.go index f93525d34556..2e3eb5060816 100644 --- a/pdata/internal/generated_proto_exportlogspartialsuccess.go +++ b/pdata/internal/generated_proto_exportlogspartialsuccess.go @@ -11,13 +11,14 @@ import ( "sync" "go.opentelemetry.io/collector/pdata/internal/json" + "go.opentelemetry.io/collector/pdata/internal/metadata" "go.opentelemetry.io/collector/pdata/internal/proto" ) // ExportPartialSuccess represents the details of a partially successful export request. type ExportLogsPartialSuccess struct { - RejectedLogRecords int64 ErrorMessage string + RejectedLogRecords int64 } var ( @@ -29,7 +30,7 @@ var ( ) func NewExportLogsPartialSuccess() *ExportLogsPartialSuccess { - if !UseProtoPooling.IsEnabled() { + if !metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() { return &ExportLogsPartialSuccess{} } return protoPoolExportLogsPartialSuccess.Get().(*ExportLogsPartialSuccess) @@ -40,7 +41,7 @@ func DeleteExportLogsPartialSuccess(orig *ExportLogsPartialSuccess, nullable boo return } - if !UseProtoPooling.IsEnabled() { + if !metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() { orig.Reset() return } @@ -65,7 +66,6 @@ func CopyExportLogsPartialSuccess(dest, src *ExportLogsPartialSuccess) *ExportLo dest = NewExportLogsPartialSuccess() } dest.RejectedLogRecords = src.RejectedLogRecords - dest.ErrorMessage = src.ErrorMessage return dest @@ -155,9 +155,10 @@ func (orig *ExportLogsPartialSuccess) SizeProto() int { var n int var l int _ = l - if orig.RejectedLogRecords != 0 { + if orig.RejectedLogRecords != int64(0) { n += 1 + proto.Sov(uint64(orig.RejectedLogRecords)) } + l = len(orig.ErrorMessage) if l > 0 { n += 1 + proto.Sov(uint64(l)) + l @@ -169,7 +170,7 @@ func (orig *ExportLogsPartialSuccess) MarshalProto(buf []byte) int { pos := len(buf) var l int _ = l - if orig.RejectedLogRecords != 0 { + if orig.RejectedLogRecords != int64(0) { pos = proto.EncodeVarint(buf, pos, uint64(orig.RejectedLogRecords)) pos-- buf[pos] = 0x8 @@ -209,7 +210,6 @@ func (orig *ExportLogsPartialSuccess) UnmarshalProto(buf []byte) error { if err != nil { return err } - orig.RejectedLogRecords = int64(num) case 2: diff --git a/pdata/internal/generated_proto_exportlogspartialsuccess_test.go b/pdata/internal/generated_proto_exportlogspartialsuccess_test.go index f98e8494ab9f..8aaeebc9077a 100644 --- a/pdata/internal/generated_proto_exportlogspartialsuccess_test.go +++ b/pdata/internal/generated_proto_exportlogspartialsuccess_test.go @@ -17,16 +17,17 @@ import ( "go.opentelemetry.io/collector/featuregate" "go.opentelemetry.io/collector/pdata/internal/json" + "go.opentelemetry.io/collector/pdata/internal/metadata" ) func TestCopyExportLogsPartialSuccess(t *testing.T) { for name, src := range genTestEncodingValuesExportLogsPartialSuccess() { for _, pooling := range []bool{true, false} { t.Run(name+"/Pooling="+strconv.FormatBool(pooling), func(t *testing.T) { - prevPooling := UseProtoPooling.IsEnabled() - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), pooling)) + prevPooling := metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), pooling)) defer func() { - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), prevPooling)) + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), prevPooling)) }() dest := NewExportLogsPartialSuccess() @@ -102,10 +103,10 @@ func TestMarshalAndUnmarshalJSONExportLogsPartialSuccess(t *testing.T) { for name, src := range genTestEncodingValuesExportLogsPartialSuccess() { for _, pooling := range []bool{true, false} { t.Run(name+"/Pooling="+strconv.FormatBool(pooling), func(t *testing.T) { - prevPooling := UseProtoPooling.IsEnabled() - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), pooling)) + prevPooling := metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), pooling)) defer func() { - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), prevPooling)) + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), prevPooling)) }() stream := json.BorrowStream(nil) @@ -146,10 +147,10 @@ func TestMarshalAndUnmarshalProtoExportLogsPartialSuccess(t *testing.T) { for name, src := range genTestEncodingValuesExportLogsPartialSuccess() { for _, pooling := range []bool{true, false} { t.Run(name+"/Pooling="+strconv.FormatBool(pooling), func(t *testing.T) { - prevPooling := UseProtoPooling.IsEnabled() - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), pooling)) + prevPooling := metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), pooling)) defer func() { - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), prevPooling)) + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), prevPooling)) }() buf := make([]byte, src.SizeProto()) diff --git a/pdata/internal/generated_proto_exportlogsservicerequest.go b/pdata/internal/generated_proto_exportlogsservicerequest.go index 1c849ec22db9..cdfb591d784f 100644 --- a/pdata/internal/generated_proto_exportlogsservicerequest.go +++ b/pdata/internal/generated_proto_exportlogsservicerequest.go @@ -11,6 +11,7 @@ import ( "sync" "go.opentelemetry.io/collector/pdata/internal/json" + "go.opentelemetry.io/collector/pdata/internal/metadata" "go.opentelemetry.io/collector/pdata/internal/proto" ) @@ -29,7 +30,7 @@ var ( ) func NewExportLogsServiceRequest() *ExportLogsServiceRequest { - if !UseProtoPooling.IsEnabled() { + if !metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() { return &ExportLogsServiceRequest{} } return protoPoolExportLogsServiceRequest.Get().(*ExportLogsServiceRequest) @@ -40,15 +41,13 @@ func DeleteExportLogsServiceRequest(orig *ExportLogsServiceRequest, nullable boo return } - if !UseProtoPooling.IsEnabled() { + if !metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() { orig.Reset() return } - for i := range orig.ResourceLogs { DeleteResourceLogs(orig.ResourceLogs[i], true) } - orig.Reset() if nullable { protoPoolExportLogsServiceRequest.Put(orig) diff --git a/pdata/internal/generated_proto_exportlogsservicerequest_test.go b/pdata/internal/generated_proto_exportlogsservicerequest_test.go index 4ac445918f9e..a912e79622ae 100644 --- a/pdata/internal/generated_proto_exportlogsservicerequest_test.go +++ b/pdata/internal/generated_proto_exportlogsservicerequest_test.go @@ -17,16 +17,17 @@ import ( "go.opentelemetry.io/collector/featuregate" "go.opentelemetry.io/collector/pdata/internal/json" + "go.opentelemetry.io/collector/pdata/internal/metadata" ) func TestCopyExportLogsServiceRequest(t *testing.T) { for name, src := range genTestEncodingValuesExportLogsServiceRequest() { for _, pooling := range []bool{true, false} { t.Run(name+"/Pooling="+strconv.FormatBool(pooling), func(t *testing.T) { - prevPooling := UseProtoPooling.IsEnabled() - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), pooling)) + prevPooling := metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), pooling)) defer func() { - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), prevPooling)) + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), prevPooling)) }() dest := NewExportLogsServiceRequest() @@ -102,10 +103,10 @@ func TestMarshalAndUnmarshalJSONExportLogsServiceRequest(t *testing.T) { for name, src := range genTestEncodingValuesExportLogsServiceRequest() { for _, pooling := range []bool{true, false} { t.Run(name+"/Pooling="+strconv.FormatBool(pooling), func(t *testing.T) { - prevPooling := UseProtoPooling.IsEnabled() - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), pooling)) + prevPooling := metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), pooling)) defer func() { - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), prevPooling)) + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), prevPooling)) }() stream := json.BorrowStream(nil) @@ -146,10 +147,10 @@ func TestMarshalAndUnmarshalProtoExportLogsServiceRequest(t *testing.T) { for name, src := range genTestEncodingValuesExportLogsServiceRequest() { for _, pooling := range []bool{true, false} { t.Run(name+"/Pooling="+strconv.FormatBool(pooling), func(t *testing.T) { - prevPooling := UseProtoPooling.IsEnabled() - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), pooling)) + prevPooling := metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), pooling)) defer func() { - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), prevPooling)) + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), prevPooling)) }() buf := make([]byte, src.SizeProto()) diff --git a/pdata/internal/generated_proto_exportlogsserviceresponse.go b/pdata/internal/generated_proto_exportlogsserviceresponse.go index 7b78c73604d8..b2271520fdd9 100644 --- a/pdata/internal/generated_proto_exportlogsserviceresponse.go +++ b/pdata/internal/generated_proto_exportlogsserviceresponse.go @@ -11,6 +11,7 @@ import ( "sync" "go.opentelemetry.io/collector/pdata/internal/json" + "go.opentelemetry.io/collector/pdata/internal/metadata" "go.opentelemetry.io/collector/pdata/internal/proto" ) @@ -28,7 +29,7 @@ var ( ) func NewExportLogsServiceResponse() *ExportLogsServiceResponse { - if !UseProtoPooling.IsEnabled() { + if !metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() { return &ExportLogsServiceResponse{} } return protoPoolExportLogsServiceResponse.Get().(*ExportLogsServiceResponse) @@ -39,13 +40,11 @@ func DeleteExportLogsServiceResponse(orig *ExportLogsServiceResponse, nullable b return } - if !UseProtoPooling.IsEnabled() { + if !metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() { orig.Reset() return } - DeleteExportLogsPartialSuccess(&orig.PartialSuccess, false) - orig.Reset() if nullable { protoPoolExportLogsServiceResponse.Put(orig) diff --git a/pdata/internal/generated_proto_exportlogsserviceresponse_test.go b/pdata/internal/generated_proto_exportlogsserviceresponse_test.go index adbf08b787f6..563fd670b805 100644 --- a/pdata/internal/generated_proto_exportlogsserviceresponse_test.go +++ b/pdata/internal/generated_proto_exportlogsserviceresponse_test.go @@ -17,16 +17,17 @@ import ( "go.opentelemetry.io/collector/featuregate" "go.opentelemetry.io/collector/pdata/internal/json" + "go.opentelemetry.io/collector/pdata/internal/metadata" ) func TestCopyExportLogsServiceResponse(t *testing.T) { for name, src := range genTestEncodingValuesExportLogsServiceResponse() { for _, pooling := range []bool{true, false} { t.Run(name+"/Pooling="+strconv.FormatBool(pooling), func(t *testing.T) { - prevPooling := UseProtoPooling.IsEnabled() - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), pooling)) + prevPooling := metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), pooling)) defer func() { - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), prevPooling)) + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), prevPooling)) }() dest := NewExportLogsServiceResponse() @@ -102,10 +103,10 @@ func TestMarshalAndUnmarshalJSONExportLogsServiceResponse(t *testing.T) { for name, src := range genTestEncodingValuesExportLogsServiceResponse() { for _, pooling := range []bool{true, false} { t.Run(name+"/Pooling="+strconv.FormatBool(pooling), func(t *testing.T) { - prevPooling := UseProtoPooling.IsEnabled() - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), pooling)) + prevPooling := metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), pooling)) defer func() { - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), prevPooling)) + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), prevPooling)) }() stream := json.BorrowStream(nil) @@ -146,10 +147,10 @@ func TestMarshalAndUnmarshalProtoExportLogsServiceResponse(t *testing.T) { for name, src := range genTestEncodingValuesExportLogsServiceResponse() { for _, pooling := range []bool{true, false} { t.Run(name+"/Pooling="+strconv.FormatBool(pooling), func(t *testing.T) { - prevPooling := UseProtoPooling.IsEnabled() - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), pooling)) + prevPooling := metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), pooling)) defer func() { - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), prevPooling)) + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), prevPooling)) }() buf := make([]byte, src.SizeProto()) diff --git a/pdata/internal/generated_proto_exportmetricspartialsuccess.go b/pdata/internal/generated_proto_exportmetricspartialsuccess.go index ff18f954c52e..27e96564109c 100644 --- a/pdata/internal/generated_proto_exportmetricspartialsuccess.go +++ b/pdata/internal/generated_proto_exportmetricspartialsuccess.go @@ -11,13 +11,14 @@ import ( "sync" "go.opentelemetry.io/collector/pdata/internal/json" + "go.opentelemetry.io/collector/pdata/internal/metadata" "go.opentelemetry.io/collector/pdata/internal/proto" ) // ExportPartialSuccess represents the details of a partially successful export request. type ExportMetricsPartialSuccess struct { - RejectedDataPoints int64 ErrorMessage string + RejectedDataPoints int64 } var ( @@ -29,7 +30,7 @@ var ( ) func NewExportMetricsPartialSuccess() *ExportMetricsPartialSuccess { - if !UseProtoPooling.IsEnabled() { + if !metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() { return &ExportMetricsPartialSuccess{} } return protoPoolExportMetricsPartialSuccess.Get().(*ExportMetricsPartialSuccess) @@ -40,7 +41,7 @@ func DeleteExportMetricsPartialSuccess(orig *ExportMetricsPartialSuccess, nullab return } - if !UseProtoPooling.IsEnabled() { + if !metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() { orig.Reset() return } @@ -65,7 +66,6 @@ func CopyExportMetricsPartialSuccess(dest, src *ExportMetricsPartialSuccess) *Ex dest = NewExportMetricsPartialSuccess() } dest.RejectedDataPoints = src.RejectedDataPoints - dest.ErrorMessage = src.ErrorMessage return dest @@ -155,9 +155,10 @@ func (orig *ExportMetricsPartialSuccess) SizeProto() int { var n int var l int _ = l - if orig.RejectedDataPoints != 0 { + if orig.RejectedDataPoints != int64(0) { n += 1 + proto.Sov(uint64(orig.RejectedDataPoints)) } + l = len(orig.ErrorMessage) if l > 0 { n += 1 + proto.Sov(uint64(l)) + l @@ -169,7 +170,7 @@ func (orig *ExportMetricsPartialSuccess) MarshalProto(buf []byte) int { pos := len(buf) var l int _ = l - if orig.RejectedDataPoints != 0 { + if orig.RejectedDataPoints != int64(0) { pos = proto.EncodeVarint(buf, pos, uint64(orig.RejectedDataPoints)) pos-- buf[pos] = 0x8 @@ -209,7 +210,6 @@ func (orig *ExportMetricsPartialSuccess) UnmarshalProto(buf []byte) error { if err != nil { return err } - orig.RejectedDataPoints = int64(num) case 2: diff --git a/pdata/internal/generated_proto_exportmetricspartialsuccess_test.go b/pdata/internal/generated_proto_exportmetricspartialsuccess_test.go index 5b35a6469cb2..95f4ea2db03b 100644 --- a/pdata/internal/generated_proto_exportmetricspartialsuccess_test.go +++ b/pdata/internal/generated_proto_exportmetricspartialsuccess_test.go @@ -17,16 +17,17 @@ import ( "go.opentelemetry.io/collector/featuregate" "go.opentelemetry.io/collector/pdata/internal/json" + "go.opentelemetry.io/collector/pdata/internal/metadata" ) func TestCopyExportMetricsPartialSuccess(t *testing.T) { for name, src := range genTestEncodingValuesExportMetricsPartialSuccess() { for _, pooling := range []bool{true, false} { t.Run(name+"/Pooling="+strconv.FormatBool(pooling), func(t *testing.T) { - prevPooling := UseProtoPooling.IsEnabled() - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), pooling)) + prevPooling := metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), pooling)) defer func() { - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), prevPooling)) + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), prevPooling)) }() dest := NewExportMetricsPartialSuccess() @@ -102,10 +103,10 @@ func TestMarshalAndUnmarshalJSONExportMetricsPartialSuccess(t *testing.T) { for name, src := range genTestEncodingValuesExportMetricsPartialSuccess() { for _, pooling := range []bool{true, false} { t.Run(name+"/Pooling="+strconv.FormatBool(pooling), func(t *testing.T) { - prevPooling := UseProtoPooling.IsEnabled() - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), pooling)) + prevPooling := metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), pooling)) defer func() { - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), prevPooling)) + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), prevPooling)) }() stream := json.BorrowStream(nil) @@ -146,10 +147,10 @@ func TestMarshalAndUnmarshalProtoExportMetricsPartialSuccess(t *testing.T) { for name, src := range genTestEncodingValuesExportMetricsPartialSuccess() { for _, pooling := range []bool{true, false} { t.Run(name+"/Pooling="+strconv.FormatBool(pooling), func(t *testing.T) { - prevPooling := UseProtoPooling.IsEnabled() - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), pooling)) + prevPooling := metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), pooling)) defer func() { - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), prevPooling)) + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), prevPooling)) }() buf := make([]byte, src.SizeProto()) diff --git a/pdata/internal/generated_proto_exportmetricsservicerequest.go b/pdata/internal/generated_proto_exportmetricsservicerequest.go index f4a4a0fa7b28..c926b5487562 100644 --- a/pdata/internal/generated_proto_exportmetricsservicerequest.go +++ b/pdata/internal/generated_proto_exportmetricsservicerequest.go @@ -11,6 +11,7 @@ import ( "sync" "go.opentelemetry.io/collector/pdata/internal/json" + "go.opentelemetry.io/collector/pdata/internal/metadata" "go.opentelemetry.io/collector/pdata/internal/proto" ) @@ -29,7 +30,7 @@ var ( ) func NewExportMetricsServiceRequest() *ExportMetricsServiceRequest { - if !UseProtoPooling.IsEnabled() { + if !metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() { return &ExportMetricsServiceRequest{} } return protoPoolExportMetricsServiceRequest.Get().(*ExportMetricsServiceRequest) @@ -40,15 +41,13 @@ func DeleteExportMetricsServiceRequest(orig *ExportMetricsServiceRequest, nullab return } - if !UseProtoPooling.IsEnabled() { + if !metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() { orig.Reset() return } - for i := range orig.ResourceMetrics { DeleteResourceMetrics(orig.ResourceMetrics[i], true) } - orig.Reset() if nullable { protoPoolExportMetricsServiceRequest.Put(orig) diff --git a/pdata/internal/generated_proto_exportmetricsservicerequest_test.go b/pdata/internal/generated_proto_exportmetricsservicerequest_test.go index 2582295c3310..0a49d417be2e 100644 --- a/pdata/internal/generated_proto_exportmetricsservicerequest_test.go +++ b/pdata/internal/generated_proto_exportmetricsservicerequest_test.go @@ -17,16 +17,17 @@ import ( "go.opentelemetry.io/collector/featuregate" "go.opentelemetry.io/collector/pdata/internal/json" + "go.opentelemetry.io/collector/pdata/internal/metadata" ) func TestCopyExportMetricsServiceRequest(t *testing.T) { for name, src := range genTestEncodingValuesExportMetricsServiceRequest() { for _, pooling := range []bool{true, false} { t.Run(name+"/Pooling="+strconv.FormatBool(pooling), func(t *testing.T) { - prevPooling := UseProtoPooling.IsEnabled() - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), pooling)) + prevPooling := metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), pooling)) defer func() { - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), prevPooling)) + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), prevPooling)) }() dest := NewExportMetricsServiceRequest() @@ -102,10 +103,10 @@ func TestMarshalAndUnmarshalJSONExportMetricsServiceRequest(t *testing.T) { for name, src := range genTestEncodingValuesExportMetricsServiceRequest() { for _, pooling := range []bool{true, false} { t.Run(name+"/Pooling="+strconv.FormatBool(pooling), func(t *testing.T) { - prevPooling := UseProtoPooling.IsEnabled() - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), pooling)) + prevPooling := metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), pooling)) defer func() { - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), prevPooling)) + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), prevPooling)) }() stream := json.BorrowStream(nil) @@ -146,10 +147,10 @@ func TestMarshalAndUnmarshalProtoExportMetricsServiceRequest(t *testing.T) { for name, src := range genTestEncodingValuesExportMetricsServiceRequest() { for _, pooling := range []bool{true, false} { t.Run(name+"/Pooling="+strconv.FormatBool(pooling), func(t *testing.T) { - prevPooling := UseProtoPooling.IsEnabled() - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), pooling)) + prevPooling := metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), pooling)) defer func() { - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), prevPooling)) + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), prevPooling)) }() buf := make([]byte, src.SizeProto()) diff --git a/pdata/internal/generated_proto_exportmetricsserviceresponse.go b/pdata/internal/generated_proto_exportmetricsserviceresponse.go index 19e69384ed66..222d5825f8fd 100644 --- a/pdata/internal/generated_proto_exportmetricsserviceresponse.go +++ b/pdata/internal/generated_proto_exportmetricsserviceresponse.go @@ -11,6 +11,7 @@ import ( "sync" "go.opentelemetry.io/collector/pdata/internal/json" + "go.opentelemetry.io/collector/pdata/internal/metadata" "go.opentelemetry.io/collector/pdata/internal/proto" ) @@ -28,7 +29,7 @@ var ( ) func NewExportMetricsServiceResponse() *ExportMetricsServiceResponse { - if !UseProtoPooling.IsEnabled() { + if !metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() { return &ExportMetricsServiceResponse{} } return protoPoolExportMetricsServiceResponse.Get().(*ExportMetricsServiceResponse) @@ -39,13 +40,11 @@ func DeleteExportMetricsServiceResponse(orig *ExportMetricsServiceResponse, null return } - if !UseProtoPooling.IsEnabled() { + if !metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() { orig.Reset() return } - DeleteExportMetricsPartialSuccess(&orig.PartialSuccess, false) - orig.Reset() if nullable { protoPoolExportMetricsServiceResponse.Put(orig) diff --git a/pdata/internal/generated_proto_exportmetricsserviceresponse_test.go b/pdata/internal/generated_proto_exportmetricsserviceresponse_test.go index c6ec0a308768..a0092aceda29 100644 --- a/pdata/internal/generated_proto_exportmetricsserviceresponse_test.go +++ b/pdata/internal/generated_proto_exportmetricsserviceresponse_test.go @@ -17,16 +17,17 @@ import ( "go.opentelemetry.io/collector/featuregate" "go.opentelemetry.io/collector/pdata/internal/json" + "go.opentelemetry.io/collector/pdata/internal/metadata" ) func TestCopyExportMetricsServiceResponse(t *testing.T) { for name, src := range genTestEncodingValuesExportMetricsServiceResponse() { for _, pooling := range []bool{true, false} { t.Run(name+"/Pooling="+strconv.FormatBool(pooling), func(t *testing.T) { - prevPooling := UseProtoPooling.IsEnabled() - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), pooling)) + prevPooling := metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), pooling)) defer func() { - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), prevPooling)) + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), prevPooling)) }() dest := NewExportMetricsServiceResponse() @@ -102,10 +103,10 @@ func TestMarshalAndUnmarshalJSONExportMetricsServiceResponse(t *testing.T) { for name, src := range genTestEncodingValuesExportMetricsServiceResponse() { for _, pooling := range []bool{true, false} { t.Run(name+"/Pooling="+strconv.FormatBool(pooling), func(t *testing.T) { - prevPooling := UseProtoPooling.IsEnabled() - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), pooling)) + prevPooling := metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), pooling)) defer func() { - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), prevPooling)) + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), prevPooling)) }() stream := json.BorrowStream(nil) @@ -146,10 +147,10 @@ func TestMarshalAndUnmarshalProtoExportMetricsServiceResponse(t *testing.T) { for name, src := range genTestEncodingValuesExportMetricsServiceResponse() { for _, pooling := range []bool{true, false} { t.Run(name+"/Pooling="+strconv.FormatBool(pooling), func(t *testing.T) { - prevPooling := UseProtoPooling.IsEnabled() - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), pooling)) + prevPooling := metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), pooling)) defer func() { - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), prevPooling)) + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), prevPooling)) }() buf := make([]byte, src.SizeProto()) diff --git a/pdata/internal/generated_proto_exportprofilespartialsuccess.go b/pdata/internal/generated_proto_exportprofilespartialsuccess.go index 03a20a624834..8077e8a04feb 100644 --- a/pdata/internal/generated_proto_exportprofilespartialsuccess.go +++ b/pdata/internal/generated_proto_exportprofilespartialsuccess.go @@ -11,13 +11,14 @@ import ( "sync" "go.opentelemetry.io/collector/pdata/internal/json" + "go.opentelemetry.io/collector/pdata/internal/metadata" "go.opentelemetry.io/collector/pdata/internal/proto" ) // ExportPartialSuccess represents the details of a partially successful export request. type ExportProfilesPartialSuccess struct { - RejectedProfiles int64 ErrorMessage string + RejectedProfiles int64 } var ( @@ -29,7 +30,7 @@ var ( ) func NewExportProfilesPartialSuccess() *ExportProfilesPartialSuccess { - if !UseProtoPooling.IsEnabled() { + if !metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() { return &ExportProfilesPartialSuccess{} } return protoPoolExportProfilesPartialSuccess.Get().(*ExportProfilesPartialSuccess) @@ -40,7 +41,7 @@ func DeleteExportProfilesPartialSuccess(orig *ExportProfilesPartialSuccess, null return } - if !UseProtoPooling.IsEnabled() { + if !metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() { orig.Reset() return } @@ -65,7 +66,6 @@ func CopyExportProfilesPartialSuccess(dest, src *ExportProfilesPartialSuccess) * dest = NewExportProfilesPartialSuccess() } dest.RejectedProfiles = src.RejectedProfiles - dest.ErrorMessage = src.ErrorMessage return dest @@ -155,9 +155,10 @@ func (orig *ExportProfilesPartialSuccess) SizeProto() int { var n int var l int _ = l - if orig.RejectedProfiles != 0 { + if orig.RejectedProfiles != int64(0) { n += 1 + proto.Sov(uint64(orig.RejectedProfiles)) } + l = len(orig.ErrorMessage) if l > 0 { n += 1 + proto.Sov(uint64(l)) + l @@ -169,7 +170,7 @@ func (orig *ExportProfilesPartialSuccess) MarshalProto(buf []byte) int { pos := len(buf) var l int _ = l - if orig.RejectedProfiles != 0 { + if orig.RejectedProfiles != int64(0) { pos = proto.EncodeVarint(buf, pos, uint64(orig.RejectedProfiles)) pos-- buf[pos] = 0x8 @@ -209,7 +210,6 @@ func (orig *ExportProfilesPartialSuccess) UnmarshalProto(buf []byte) error { if err != nil { return err } - orig.RejectedProfiles = int64(num) case 2: diff --git a/pdata/internal/generated_proto_exportprofilespartialsuccess_test.go b/pdata/internal/generated_proto_exportprofilespartialsuccess_test.go index c5b95413d587..fd362fa0ca47 100644 --- a/pdata/internal/generated_proto_exportprofilespartialsuccess_test.go +++ b/pdata/internal/generated_proto_exportprofilespartialsuccess_test.go @@ -17,16 +17,17 @@ import ( "go.opentelemetry.io/collector/featuregate" "go.opentelemetry.io/collector/pdata/internal/json" + "go.opentelemetry.io/collector/pdata/internal/metadata" ) func TestCopyExportProfilesPartialSuccess(t *testing.T) { for name, src := range genTestEncodingValuesExportProfilesPartialSuccess() { for _, pooling := range []bool{true, false} { t.Run(name+"/Pooling="+strconv.FormatBool(pooling), func(t *testing.T) { - prevPooling := UseProtoPooling.IsEnabled() - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), pooling)) + prevPooling := metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), pooling)) defer func() { - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), prevPooling)) + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), prevPooling)) }() dest := NewExportProfilesPartialSuccess() @@ -102,10 +103,10 @@ func TestMarshalAndUnmarshalJSONExportProfilesPartialSuccess(t *testing.T) { for name, src := range genTestEncodingValuesExportProfilesPartialSuccess() { for _, pooling := range []bool{true, false} { t.Run(name+"/Pooling="+strconv.FormatBool(pooling), func(t *testing.T) { - prevPooling := UseProtoPooling.IsEnabled() - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), pooling)) + prevPooling := metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), pooling)) defer func() { - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), prevPooling)) + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), prevPooling)) }() stream := json.BorrowStream(nil) @@ -146,10 +147,10 @@ func TestMarshalAndUnmarshalProtoExportProfilesPartialSuccess(t *testing.T) { for name, src := range genTestEncodingValuesExportProfilesPartialSuccess() { for _, pooling := range []bool{true, false} { t.Run(name+"/Pooling="+strconv.FormatBool(pooling), func(t *testing.T) { - prevPooling := UseProtoPooling.IsEnabled() - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), pooling)) + prevPooling := metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), pooling)) defer func() { - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), prevPooling)) + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), prevPooling)) }() buf := make([]byte, src.SizeProto()) diff --git a/pdata/internal/generated_proto_exportprofilesservicerequest.go b/pdata/internal/generated_proto_exportprofilesservicerequest.go index 5906ce52093f..72d876c97301 100644 --- a/pdata/internal/generated_proto_exportprofilesservicerequest.go +++ b/pdata/internal/generated_proto_exportprofilesservicerequest.go @@ -11,6 +11,7 @@ import ( "sync" "go.opentelemetry.io/collector/pdata/internal/json" + "go.opentelemetry.io/collector/pdata/internal/metadata" "go.opentelemetry.io/collector/pdata/internal/proto" ) @@ -30,7 +31,7 @@ var ( ) func NewExportProfilesServiceRequest() *ExportProfilesServiceRequest { - if !UseProtoPooling.IsEnabled() { + if !metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() { return &ExportProfilesServiceRequest{} } return protoPoolExportProfilesServiceRequest.Get().(*ExportProfilesServiceRequest) @@ -41,16 +42,14 @@ func DeleteExportProfilesServiceRequest(orig *ExportProfilesServiceRequest, null return } - if !UseProtoPooling.IsEnabled() { + if !metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() { orig.Reset() return } - for i := range orig.ResourceProfiles { DeleteResourceProfiles(orig.ResourceProfiles[i], true) } DeleteProfilesDictionary(&orig.Dictionary, false) - orig.Reset() if nullable { protoPoolExportProfilesServiceRequest.Put(orig) diff --git a/pdata/internal/generated_proto_exportprofilesservicerequest_test.go b/pdata/internal/generated_proto_exportprofilesservicerequest_test.go index 18b73da84076..a3249a3b4da4 100644 --- a/pdata/internal/generated_proto_exportprofilesservicerequest_test.go +++ b/pdata/internal/generated_proto_exportprofilesservicerequest_test.go @@ -17,16 +17,17 @@ import ( "go.opentelemetry.io/collector/featuregate" "go.opentelemetry.io/collector/pdata/internal/json" + "go.opentelemetry.io/collector/pdata/internal/metadata" ) func TestCopyExportProfilesServiceRequest(t *testing.T) { for name, src := range genTestEncodingValuesExportProfilesServiceRequest() { for _, pooling := range []bool{true, false} { t.Run(name+"/Pooling="+strconv.FormatBool(pooling), func(t *testing.T) { - prevPooling := UseProtoPooling.IsEnabled() - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), pooling)) + prevPooling := metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), pooling)) defer func() { - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), prevPooling)) + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), prevPooling)) }() dest := NewExportProfilesServiceRequest() @@ -102,10 +103,10 @@ func TestMarshalAndUnmarshalJSONExportProfilesServiceRequest(t *testing.T) { for name, src := range genTestEncodingValuesExportProfilesServiceRequest() { for _, pooling := range []bool{true, false} { t.Run(name+"/Pooling="+strconv.FormatBool(pooling), func(t *testing.T) { - prevPooling := UseProtoPooling.IsEnabled() - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), pooling)) + prevPooling := metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), pooling)) defer func() { - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), prevPooling)) + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), prevPooling)) }() stream := json.BorrowStream(nil) @@ -146,10 +147,10 @@ func TestMarshalAndUnmarshalProtoExportProfilesServiceRequest(t *testing.T) { for name, src := range genTestEncodingValuesExportProfilesServiceRequest() { for _, pooling := range []bool{true, false} { t.Run(name+"/Pooling="+strconv.FormatBool(pooling), func(t *testing.T) { - prevPooling := UseProtoPooling.IsEnabled() - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), pooling)) + prevPooling := metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), pooling)) defer func() { - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), prevPooling)) + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), prevPooling)) }() buf := make([]byte, src.SizeProto()) diff --git a/pdata/internal/generated_proto_exportprofilesserviceresponse.go b/pdata/internal/generated_proto_exportprofilesserviceresponse.go index 0153c0609944..383058bc60cc 100644 --- a/pdata/internal/generated_proto_exportprofilesserviceresponse.go +++ b/pdata/internal/generated_proto_exportprofilesserviceresponse.go @@ -11,6 +11,7 @@ import ( "sync" "go.opentelemetry.io/collector/pdata/internal/json" + "go.opentelemetry.io/collector/pdata/internal/metadata" "go.opentelemetry.io/collector/pdata/internal/proto" ) @@ -28,7 +29,7 @@ var ( ) func NewExportProfilesServiceResponse() *ExportProfilesServiceResponse { - if !UseProtoPooling.IsEnabled() { + if !metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() { return &ExportProfilesServiceResponse{} } return protoPoolExportProfilesServiceResponse.Get().(*ExportProfilesServiceResponse) @@ -39,13 +40,11 @@ func DeleteExportProfilesServiceResponse(orig *ExportProfilesServiceResponse, nu return } - if !UseProtoPooling.IsEnabled() { + if !metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() { orig.Reset() return } - DeleteExportProfilesPartialSuccess(&orig.PartialSuccess, false) - orig.Reset() if nullable { protoPoolExportProfilesServiceResponse.Put(orig) diff --git a/pdata/internal/generated_proto_exportprofilesserviceresponse_test.go b/pdata/internal/generated_proto_exportprofilesserviceresponse_test.go index c2b901d0fd9b..d50fa87706c6 100644 --- a/pdata/internal/generated_proto_exportprofilesserviceresponse_test.go +++ b/pdata/internal/generated_proto_exportprofilesserviceresponse_test.go @@ -17,16 +17,17 @@ import ( "go.opentelemetry.io/collector/featuregate" "go.opentelemetry.io/collector/pdata/internal/json" + "go.opentelemetry.io/collector/pdata/internal/metadata" ) func TestCopyExportProfilesServiceResponse(t *testing.T) { for name, src := range genTestEncodingValuesExportProfilesServiceResponse() { for _, pooling := range []bool{true, false} { t.Run(name+"/Pooling="+strconv.FormatBool(pooling), func(t *testing.T) { - prevPooling := UseProtoPooling.IsEnabled() - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), pooling)) + prevPooling := metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), pooling)) defer func() { - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), prevPooling)) + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), prevPooling)) }() dest := NewExportProfilesServiceResponse() @@ -102,10 +103,10 @@ func TestMarshalAndUnmarshalJSONExportProfilesServiceResponse(t *testing.T) { for name, src := range genTestEncodingValuesExportProfilesServiceResponse() { for _, pooling := range []bool{true, false} { t.Run(name+"/Pooling="+strconv.FormatBool(pooling), func(t *testing.T) { - prevPooling := UseProtoPooling.IsEnabled() - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), pooling)) + prevPooling := metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), pooling)) defer func() { - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), prevPooling)) + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), prevPooling)) }() stream := json.BorrowStream(nil) @@ -146,10 +147,10 @@ func TestMarshalAndUnmarshalProtoExportProfilesServiceResponse(t *testing.T) { for name, src := range genTestEncodingValuesExportProfilesServiceResponse() { for _, pooling := range []bool{true, false} { t.Run(name+"/Pooling="+strconv.FormatBool(pooling), func(t *testing.T) { - prevPooling := UseProtoPooling.IsEnabled() - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), pooling)) + prevPooling := metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), pooling)) defer func() { - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), prevPooling)) + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), prevPooling)) }() buf := make([]byte, src.SizeProto()) diff --git a/pdata/internal/generated_proto_exporttracepartialsuccess.go b/pdata/internal/generated_proto_exporttracepartialsuccess.go index df8025572b4d..bf6b8f6bf82e 100644 --- a/pdata/internal/generated_proto_exporttracepartialsuccess.go +++ b/pdata/internal/generated_proto_exporttracepartialsuccess.go @@ -11,13 +11,14 @@ import ( "sync" "go.opentelemetry.io/collector/pdata/internal/json" + "go.opentelemetry.io/collector/pdata/internal/metadata" "go.opentelemetry.io/collector/pdata/internal/proto" ) // ExportPartialSuccess represents the details of a partially successful export request. type ExportTracePartialSuccess struct { - RejectedSpans int64 ErrorMessage string + RejectedSpans int64 } var ( @@ -29,7 +30,7 @@ var ( ) func NewExportTracePartialSuccess() *ExportTracePartialSuccess { - if !UseProtoPooling.IsEnabled() { + if !metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() { return &ExportTracePartialSuccess{} } return protoPoolExportTracePartialSuccess.Get().(*ExportTracePartialSuccess) @@ -40,7 +41,7 @@ func DeleteExportTracePartialSuccess(orig *ExportTracePartialSuccess, nullable b return } - if !UseProtoPooling.IsEnabled() { + if !metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() { orig.Reset() return } @@ -65,7 +66,6 @@ func CopyExportTracePartialSuccess(dest, src *ExportTracePartialSuccess) *Export dest = NewExportTracePartialSuccess() } dest.RejectedSpans = src.RejectedSpans - dest.ErrorMessage = src.ErrorMessage return dest @@ -155,9 +155,10 @@ func (orig *ExportTracePartialSuccess) SizeProto() int { var n int var l int _ = l - if orig.RejectedSpans != 0 { + if orig.RejectedSpans != int64(0) { n += 1 + proto.Sov(uint64(orig.RejectedSpans)) } + l = len(orig.ErrorMessage) if l > 0 { n += 1 + proto.Sov(uint64(l)) + l @@ -169,7 +170,7 @@ func (orig *ExportTracePartialSuccess) MarshalProto(buf []byte) int { pos := len(buf) var l int _ = l - if orig.RejectedSpans != 0 { + if orig.RejectedSpans != int64(0) { pos = proto.EncodeVarint(buf, pos, uint64(orig.RejectedSpans)) pos-- buf[pos] = 0x8 @@ -209,7 +210,6 @@ func (orig *ExportTracePartialSuccess) UnmarshalProto(buf []byte) error { if err != nil { return err } - orig.RejectedSpans = int64(num) case 2: diff --git a/pdata/internal/generated_proto_exporttracepartialsuccess_test.go b/pdata/internal/generated_proto_exporttracepartialsuccess_test.go index 7331cc17a10a..ea57033934be 100644 --- a/pdata/internal/generated_proto_exporttracepartialsuccess_test.go +++ b/pdata/internal/generated_proto_exporttracepartialsuccess_test.go @@ -17,16 +17,17 @@ import ( "go.opentelemetry.io/collector/featuregate" "go.opentelemetry.io/collector/pdata/internal/json" + "go.opentelemetry.io/collector/pdata/internal/metadata" ) func TestCopyExportTracePartialSuccess(t *testing.T) { for name, src := range genTestEncodingValuesExportTracePartialSuccess() { for _, pooling := range []bool{true, false} { t.Run(name+"/Pooling="+strconv.FormatBool(pooling), func(t *testing.T) { - prevPooling := UseProtoPooling.IsEnabled() - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), pooling)) + prevPooling := metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), pooling)) defer func() { - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), prevPooling)) + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), prevPooling)) }() dest := NewExportTracePartialSuccess() @@ -102,10 +103,10 @@ func TestMarshalAndUnmarshalJSONExportTracePartialSuccess(t *testing.T) { for name, src := range genTestEncodingValuesExportTracePartialSuccess() { for _, pooling := range []bool{true, false} { t.Run(name+"/Pooling="+strconv.FormatBool(pooling), func(t *testing.T) { - prevPooling := UseProtoPooling.IsEnabled() - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), pooling)) + prevPooling := metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), pooling)) defer func() { - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), prevPooling)) + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), prevPooling)) }() stream := json.BorrowStream(nil) @@ -146,10 +147,10 @@ func TestMarshalAndUnmarshalProtoExportTracePartialSuccess(t *testing.T) { for name, src := range genTestEncodingValuesExportTracePartialSuccess() { for _, pooling := range []bool{true, false} { t.Run(name+"/Pooling="+strconv.FormatBool(pooling), func(t *testing.T) { - prevPooling := UseProtoPooling.IsEnabled() - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), pooling)) + prevPooling := metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), pooling)) defer func() { - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), prevPooling)) + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), prevPooling)) }() buf := make([]byte, src.SizeProto()) diff --git a/pdata/internal/generated_proto_exporttraceservicerequest.go b/pdata/internal/generated_proto_exporttraceservicerequest.go index e64316f8f3c4..408d5aa465ed 100644 --- a/pdata/internal/generated_proto_exporttraceservicerequest.go +++ b/pdata/internal/generated_proto_exporttraceservicerequest.go @@ -11,6 +11,7 @@ import ( "sync" "go.opentelemetry.io/collector/pdata/internal/json" + "go.opentelemetry.io/collector/pdata/internal/metadata" "go.opentelemetry.io/collector/pdata/internal/proto" ) @@ -29,7 +30,7 @@ var ( ) func NewExportTraceServiceRequest() *ExportTraceServiceRequest { - if !UseProtoPooling.IsEnabled() { + if !metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() { return &ExportTraceServiceRequest{} } return protoPoolExportTraceServiceRequest.Get().(*ExportTraceServiceRequest) @@ -40,15 +41,13 @@ func DeleteExportTraceServiceRequest(orig *ExportTraceServiceRequest, nullable b return } - if !UseProtoPooling.IsEnabled() { + if !metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() { orig.Reset() return } - for i := range orig.ResourceSpans { DeleteResourceSpans(orig.ResourceSpans[i], true) } - orig.Reset() if nullable { protoPoolExportTraceServiceRequest.Put(orig) diff --git a/pdata/internal/generated_proto_exporttraceservicerequest_test.go b/pdata/internal/generated_proto_exporttraceservicerequest_test.go index 4dbf90c0838c..3bbe0844dec9 100644 --- a/pdata/internal/generated_proto_exporttraceservicerequest_test.go +++ b/pdata/internal/generated_proto_exporttraceservicerequest_test.go @@ -17,16 +17,17 @@ import ( "go.opentelemetry.io/collector/featuregate" "go.opentelemetry.io/collector/pdata/internal/json" + "go.opentelemetry.io/collector/pdata/internal/metadata" ) func TestCopyExportTraceServiceRequest(t *testing.T) { for name, src := range genTestEncodingValuesExportTraceServiceRequest() { for _, pooling := range []bool{true, false} { t.Run(name+"/Pooling="+strconv.FormatBool(pooling), func(t *testing.T) { - prevPooling := UseProtoPooling.IsEnabled() - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), pooling)) + prevPooling := metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), pooling)) defer func() { - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), prevPooling)) + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), prevPooling)) }() dest := NewExportTraceServiceRequest() @@ -102,10 +103,10 @@ func TestMarshalAndUnmarshalJSONExportTraceServiceRequest(t *testing.T) { for name, src := range genTestEncodingValuesExportTraceServiceRequest() { for _, pooling := range []bool{true, false} { t.Run(name+"/Pooling="+strconv.FormatBool(pooling), func(t *testing.T) { - prevPooling := UseProtoPooling.IsEnabled() - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), pooling)) + prevPooling := metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), pooling)) defer func() { - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), prevPooling)) + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), prevPooling)) }() stream := json.BorrowStream(nil) @@ -146,10 +147,10 @@ func TestMarshalAndUnmarshalProtoExportTraceServiceRequest(t *testing.T) { for name, src := range genTestEncodingValuesExportTraceServiceRequest() { for _, pooling := range []bool{true, false} { t.Run(name+"/Pooling="+strconv.FormatBool(pooling), func(t *testing.T) { - prevPooling := UseProtoPooling.IsEnabled() - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), pooling)) + prevPooling := metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), pooling)) defer func() { - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), prevPooling)) + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), prevPooling)) }() buf := make([]byte, src.SizeProto()) diff --git a/pdata/internal/generated_proto_exporttraceserviceresponse.go b/pdata/internal/generated_proto_exporttraceserviceresponse.go index 86be1a0fdafa..4437f3dec5f4 100644 --- a/pdata/internal/generated_proto_exporttraceserviceresponse.go +++ b/pdata/internal/generated_proto_exporttraceserviceresponse.go @@ -11,6 +11,7 @@ import ( "sync" "go.opentelemetry.io/collector/pdata/internal/json" + "go.opentelemetry.io/collector/pdata/internal/metadata" "go.opentelemetry.io/collector/pdata/internal/proto" ) @@ -28,7 +29,7 @@ var ( ) func NewExportTraceServiceResponse() *ExportTraceServiceResponse { - if !UseProtoPooling.IsEnabled() { + if !metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() { return &ExportTraceServiceResponse{} } return protoPoolExportTraceServiceResponse.Get().(*ExportTraceServiceResponse) @@ -39,13 +40,11 @@ func DeleteExportTraceServiceResponse(orig *ExportTraceServiceResponse, nullable return } - if !UseProtoPooling.IsEnabled() { + if !metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() { orig.Reset() return } - DeleteExportTracePartialSuccess(&orig.PartialSuccess, false) - orig.Reset() if nullable { protoPoolExportTraceServiceResponse.Put(orig) diff --git a/pdata/internal/generated_proto_exporttraceserviceresponse_test.go b/pdata/internal/generated_proto_exporttraceserviceresponse_test.go index 74ae7b4f3eda..839e674fe771 100644 --- a/pdata/internal/generated_proto_exporttraceserviceresponse_test.go +++ b/pdata/internal/generated_proto_exporttraceserviceresponse_test.go @@ -17,16 +17,17 @@ import ( "go.opentelemetry.io/collector/featuregate" "go.opentelemetry.io/collector/pdata/internal/json" + "go.opentelemetry.io/collector/pdata/internal/metadata" ) func TestCopyExportTraceServiceResponse(t *testing.T) { for name, src := range genTestEncodingValuesExportTraceServiceResponse() { for _, pooling := range []bool{true, false} { t.Run(name+"/Pooling="+strconv.FormatBool(pooling), func(t *testing.T) { - prevPooling := UseProtoPooling.IsEnabled() - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), pooling)) + prevPooling := metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), pooling)) defer func() { - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), prevPooling)) + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), prevPooling)) }() dest := NewExportTraceServiceResponse() @@ -102,10 +103,10 @@ func TestMarshalAndUnmarshalJSONExportTraceServiceResponse(t *testing.T) { for name, src := range genTestEncodingValuesExportTraceServiceResponse() { for _, pooling := range []bool{true, false} { t.Run(name+"/Pooling="+strconv.FormatBool(pooling), func(t *testing.T) { - prevPooling := UseProtoPooling.IsEnabled() - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), pooling)) + prevPooling := metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), pooling)) defer func() { - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), prevPooling)) + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), prevPooling)) }() stream := json.BorrowStream(nil) @@ -146,10 +147,10 @@ func TestMarshalAndUnmarshalProtoExportTraceServiceResponse(t *testing.T) { for name, src := range genTestEncodingValuesExportTraceServiceResponse() { for _, pooling := range []bool{true, false} { t.Run(name+"/Pooling="+strconv.FormatBool(pooling), func(t *testing.T) { - prevPooling := UseProtoPooling.IsEnabled() - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), pooling)) + prevPooling := metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), pooling)) defer func() { - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), prevPooling)) + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), prevPooling)) }() buf := make([]byte, src.SizeProto()) diff --git a/pdata/internal/generated_proto_function.go b/pdata/internal/generated_proto_function.go index 4e8225390929..a2d0b1b86181 100644 --- a/pdata/internal/generated_proto_function.go +++ b/pdata/internal/generated_proto_function.go @@ -11,6 +11,7 @@ import ( "sync" "go.opentelemetry.io/collector/pdata/internal/json" + "go.opentelemetry.io/collector/pdata/internal/metadata" "go.opentelemetry.io/collector/pdata/internal/proto" ) @@ -31,7 +32,7 @@ var ( ) func NewFunction() *Function { - if !UseProtoPooling.IsEnabled() { + if !metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() { return &Function{} } return protoPoolFunction.Get().(*Function) @@ -42,7 +43,7 @@ func DeleteFunction(orig *Function, nullable bool) { return } - if !UseProtoPooling.IsEnabled() { + if !metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() { orig.Reset() return } @@ -67,11 +68,8 @@ func CopyFunction(dest, src *Function) *Function { dest = NewFunction() } dest.NameStrindex = src.NameStrindex - dest.SystemNameStrindex = src.SystemNameStrindex - dest.FilenameStrindex = src.FilenameStrindex - dest.StartLine = src.StartLine return dest @@ -173,16 +171,16 @@ func (orig *Function) SizeProto() int { var n int var l int _ = l - if orig.NameStrindex != 0 { + if orig.NameStrindex != int32(0) { n += 1 + proto.Sov(uint64(orig.NameStrindex)) } - if orig.SystemNameStrindex != 0 { + if orig.SystemNameStrindex != int32(0) { n += 1 + proto.Sov(uint64(orig.SystemNameStrindex)) } - if orig.FilenameStrindex != 0 { + if orig.FilenameStrindex != int32(0) { n += 1 + proto.Sov(uint64(orig.FilenameStrindex)) } - if orig.StartLine != 0 { + if orig.StartLine != int64(0) { n += 1 + proto.Sov(uint64(orig.StartLine)) } return n @@ -192,22 +190,22 @@ func (orig *Function) MarshalProto(buf []byte) int { pos := len(buf) var l int _ = l - if orig.NameStrindex != 0 { + if orig.NameStrindex != int32(0) { pos = proto.EncodeVarint(buf, pos, uint64(orig.NameStrindex)) pos-- buf[pos] = 0x8 } - if orig.SystemNameStrindex != 0 { + if orig.SystemNameStrindex != int32(0) { pos = proto.EncodeVarint(buf, pos, uint64(orig.SystemNameStrindex)) pos-- buf[pos] = 0x10 } - if orig.FilenameStrindex != 0 { + if orig.FilenameStrindex != int32(0) { pos = proto.EncodeVarint(buf, pos, uint64(orig.FilenameStrindex)) pos-- buf[pos] = 0x18 } - if orig.StartLine != 0 { + if orig.StartLine != int64(0) { pos = proto.EncodeVarint(buf, pos, uint64(orig.StartLine)) pos-- buf[pos] = 0x20 @@ -239,7 +237,6 @@ func (orig *Function) UnmarshalProto(buf []byte) error { if err != nil { return err } - orig.NameStrindex = int32(num) case 2: @@ -251,7 +248,6 @@ func (orig *Function) UnmarshalProto(buf []byte) error { if err != nil { return err } - orig.SystemNameStrindex = int32(num) case 3: @@ -263,7 +259,6 @@ func (orig *Function) UnmarshalProto(buf []byte) error { if err != nil { return err } - orig.FilenameStrindex = int32(num) case 4: @@ -275,7 +270,6 @@ func (orig *Function) UnmarshalProto(buf []byte) error { if err != nil { return err } - orig.StartLine = int64(num) default: pos, err = proto.ConsumeUnknown(buf, pos, wireType) diff --git a/pdata/internal/generated_proto_function_test.go b/pdata/internal/generated_proto_function_test.go index 3947ba9dd643..1d1dd54eb08a 100644 --- a/pdata/internal/generated_proto_function_test.go +++ b/pdata/internal/generated_proto_function_test.go @@ -17,16 +17,17 @@ import ( "go.opentelemetry.io/collector/featuregate" "go.opentelemetry.io/collector/pdata/internal/json" + "go.opentelemetry.io/collector/pdata/internal/metadata" ) func TestCopyFunction(t *testing.T) { for name, src := range genTestEncodingValuesFunction() { for _, pooling := range []bool{true, false} { t.Run(name+"/Pooling="+strconv.FormatBool(pooling), func(t *testing.T) { - prevPooling := UseProtoPooling.IsEnabled() - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), pooling)) + prevPooling := metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), pooling)) defer func() { - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), prevPooling)) + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), prevPooling)) }() dest := NewFunction() @@ -102,10 +103,10 @@ func TestMarshalAndUnmarshalJSONFunction(t *testing.T) { for name, src := range genTestEncodingValuesFunction() { for _, pooling := range []bool{true, false} { t.Run(name+"/Pooling="+strconv.FormatBool(pooling), func(t *testing.T) { - prevPooling := UseProtoPooling.IsEnabled() - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), pooling)) + prevPooling := metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), pooling)) defer func() { - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), prevPooling)) + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), prevPooling)) }() stream := json.BorrowStream(nil) @@ -146,10 +147,10 @@ func TestMarshalAndUnmarshalProtoFunction(t *testing.T) { for name, src := range genTestEncodingValuesFunction() { for _, pooling := range []bool{true, false} { t.Run(name+"/Pooling="+strconv.FormatBool(pooling), func(t *testing.T) { - prevPooling := UseProtoPooling.IsEnabled() - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), pooling)) + prevPooling := metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), pooling)) defer func() { - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), prevPooling)) + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), prevPooling)) }() buf := make([]byte, src.SizeProto()) diff --git a/pdata/internal/generated_proto_gauge.go b/pdata/internal/generated_proto_gauge.go index e39eb2e79588..5d2b46751088 100644 --- a/pdata/internal/generated_proto_gauge.go +++ b/pdata/internal/generated_proto_gauge.go @@ -11,6 +11,7 @@ import ( "sync" "go.opentelemetry.io/collector/pdata/internal/json" + "go.opentelemetry.io/collector/pdata/internal/metadata" "go.opentelemetry.io/collector/pdata/internal/proto" ) @@ -28,7 +29,7 @@ var ( ) func NewGauge() *Gauge { - if !UseProtoPooling.IsEnabled() { + if !metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() { return &Gauge{} } return protoPoolGauge.Get().(*Gauge) @@ -39,15 +40,13 @@ func DeleteGauge(orig *Gauge, nullable bool) { return } - if !UseProtoPooling.IsEnabled() { + if !metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() { orig.Reset() return } - for i := range orig.DataPoints { DeleteNumberDataPoint(orig.DataPoints[i], true) } - orig.Reset() if nullable { protoPoolGauge.Put(orig) diff --git a/pdata/internal/generated_proto_gauge_test.go b/pdata/internal/generated_proto_gauge_test.go index 09f593e78dfd..6e4a46399d99 100644 --- a/pdata/internal/generated_proto_gauge_test.go +++ b/pdata/internal/generated_proto_gauge_test.go @@ -17,16 +17,17 @@ import ( "go.opentelemetry.io/collector/featuregate" "go.opentelemetry.io/collector/pdata/internal/json" + "go.opentelemetry.io/collector/pdata/internal/metadata" ) func TestCopyGauge(t *testing.T) { for name, src := range genTestEncodingValuesGauge() { for _, pooling := range []bool{true, false} { t.Run(name+"/Pooling="+strconv.FormatBool(pooling), func(t *testing.T) { - prevPooling := UseProtoPooling.IsEnabled() - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), pooling)) + prevPooling := metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), pooling)) defer func() { - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), prevPooling)) + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), prevPooling)) }() dest := NewGauge() @@ -102,10 +103,10 @@ func TestMarshalAndUnmarshalJSONGauge(t *testing.T) { for name, src := range genTestEncodingValuesGauge() { for _, pooling := range []bool{true, false} { t.Run(name+"/Pooling="+strconv.FormatBool(pooling), func(t *testing.T) { - prevPooling := UseProtoPooling.IsEnabled() - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), pooling)) + prevPooling := metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), pooling)) defer func() { - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), prevPooling)) + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), prevPooling)) }() stream := json.BorrowStream(nil) @@ -146,10 +147,10 @@ func TestMarshalAndUnmarshalProtoGauge(t *testing.T) { for name, src := range genTestEncodingValuesGauge() { for _, pooling := range []bool{true, false} { t.Run(name+"/Pooling="+strconv.FormatBool(pooling), func(t *testing.T) { - prevPooling := UseProtoPooling.IsEnabled() - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), pooling)) + prevPooling := metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), pooling)) defer func() { - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), prevPooling)) + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), prevPooling)) }() buf := make([]byte, src.SizeProto()) diff --git a/pdata/internal/generated_proto_histogram.go b/pdata/internal/generated_proto_histogram.go index b35b328f9135..3d9c149ce6fa 100644 --- a/pdata/internal/generated_proto_histogram.go +++ b/pdata/internal/generated_proto_histogram.go @@ -11,6 +11,7 @@ import ( "sync" "go.opentelemetry.io/collector/pdata/internal/json" + "go.opentelemetry.io/collector/pdata/internal/metadata" "go.opentelemetry.io/collector/pdata/internal/proto" ) @@ -29,7 +30,7 @@ var ( ) func NewHistogram() *Histogram { - if !UseProtoPooling.IsEnabled() { + if !metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() { return &Histogram{} } return protoPoolHistogram.Get().(*Histogram) @@ -40,11 +41,10 @@ func DeleteHistogram(orig *Histogram, nullable bool) { return } - if !UseProtoPooling.IsEnabled() { + if !metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() { orig.Reset() return } - for i := range orig.DataPoints { DeleteHistogramDataPoint(orig.DataPoints[i], true) } @@ -174,7 +174,7 @@ func (orig *Histogram) SizeProto() int { l = orig.DataPoints[i].SizeProto() n += 1 + proto.Sov(uint64(l)) + l } - if orig.AggregationTemporality != 0 { + if orig.AggregationTemporality != AggregationTemporality(0) { n += 1 + proto.Sov(uint64(orig.AggregationTemporality)) } return n @@ -191,7 +191,7 @@ func (orig *Histogram) MarshalProto(buf []byte) int { pos-- buf[pos] = 0xa } - if orig.AggregationTemporality != 0 { + if orig.AggregationTemporality != AggregationTemporality(0) { pos = proto.EncodeVarint(buf, pos, uint64(orig.AggregationTemporality)) pos-- buf[pos] = 0x10 @@ -239,7 +239,6 @@ func (orig *Histogram) UnmarshalProto(buf []byte) error { if err != nil { return err } - orig.AggregationTemporality = AggregationTemporality(num) default: pos, err = proto.ConsumeUnknown(buf, pos, wireType) diff --git a/pdata/internal/generated_proto_histogram_test.go b/pdata/internal/generated_proto_histogram_test.go index 92704eed114f..88f00ef73358 100644 --- a/pdata/internal/generated_proto_histogram_test.go +++ b/pdata/internal/generated_proto_histogram_test.go @@ -17,16 +17,17 @@ import ( "go.opentelemetry.io/collector/featuregate" "go.opentelemetry.io/collector/pdata/internal/json" + "go.opentelemetry.io/collector/pdata/internal/metadata" ) func TestCopyHistogram(t *testing.T) { for name, src := range genTestEncodingValuesHistogram() { for _, pooling := range []bool{true, false} { t.Run(name+"/Pooling="+strconv.FormatBool(pooling), func(t *testing.T) { - prevPooling := UseProtoPooling.IsEnabled() - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), pooling)) + prevPooling := metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), pooling)) defer func() { - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), prevPooling)) + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), prevPooling)) }() dest := NewHistogram() @@ -102,10 +103,10 @@ func TestMarshalAndUnmarshalJSONHistogram(t *testing.T) { for name, src := range genTestEncodingValuesHistogram() { for _, pooling := range []bool{true, false} { t.Run(name+"/Pooling="+strconv.FormatBool(pooling), func(t *testing.T) { - prevPooling := UseProtoPooling.IsEnabled() - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), pooling)) + prevPooling := metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), pooling)) defer func() { - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), prevPooling)) + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), prevPooling)) }() stream := json.BorrowStream(nil) @@ -146,10 +147,10 @@ func TestMarshalAndUnmarshalProtoHistogram(t *testing.T) { for name, src := range genTestEncodingValuesHistogram() { for _, pooling := range []bool{true, false} { t.Run(name+"/Pooling="+strconv.FormatBool(pooling), func(t *testing.T) { - prevPooling := UseProtoPooling.IsEnabled() - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), pooling)) + prevPooling := metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), pooling)) defer func() { - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), prevPooling)) + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), prevPooling)) }() buf := make([]byte, src.SizeProto()) diff --git a/pdata/internal/generated_proto_histogramdatapoint.go b/pdata/internal/generated_proto_histogramdatapoint.go index 42953b3f91db..0d28369f4c1e 100644 --- a/pdata/internal/generated_proto_histogramdatapoint.go +++ b/pdata/internal/generated_proto_histogramdatapoint.go @@ -13,76 +13,24 @@ import ( "sync" "go.opentelemetry.io/collector/pdata/internal/json" + "go.opentelemetry.io/collector/pdata/internal/metadata" "go.opentelemetry.io/collector/pdata/internal/proto" ) -func (m *HistogramDataPoint) GetSum_() any { - if m != nil { - return m.Sum_ - } - return nil -} - -type HistogramDataPoint_Sum struct { - Sum float64 -} - -func (m *HistogramDataPoint) GetSum() float64 { - if v, ok := m.GetSum_().(*HistogramDataPoint_Sum); ok { - return v.Sum - } - return float64(0) -} - -func (m *HistogramDataPoint) GetMin_() any { - if m != nil { - return m.Min_ - } - return nil -} - -type HistogramDataPoint_Min struct { - Min float64 -} - -func (m *HistogramDataPoint) GetMin() float64 { - if v, ok := m.GetMin_().(*HistogramDataPoint_Min); ok { - return v.Min - } - return float64(0) -} - -func (m *HistogramDataPoint) GetMax_() any { - if m != nil { - return m.Max_ - } - return nil -} - -type HistogramDataPoint_Max struct { - Max float64 -} - -func (m *HistogramDataPoint) GetMax() float64 { - if v, ok := m.GetMax_().(*HistogramDataPoint_Max); ok { - return v.Max - } - return float64(0) -} - // HistogramDataPoint is a single data point in a timeseries that describes the time-varying values of a Histogram of values. type HistogramDataPoint struct { Attributes []KeyValue - StartTimeUnixNano uint64 - TimeUnixNano uint64 - Count uint64 - Sum_ any BucketCounts []uint64 ExplicitBounds []float64 Exemplars []Exemplar + StartTimeUnixNano uint64 + TimeUnixNano uint64 + Count uint64 + Sum float64 + Min float64 + Max float64 + metadata [1]uint64 Flags uint32 - Min_ any - Max_ any } var ( @@ -91,27 +39,10 @@ var ( return &HistogramDataPoint{} }, } - ProtoPoolHistogramDataPoint_Sum = sync.Pool{ - New: func() any { - return &HistogramDataPoint_Sum{} - }, - } - - ProtoPoolHistogramDataPoint_Min = sync.Pool{ - New: func() any { - return &HistogramDataPoint_Min{} - }, - } - - ProtoPoolHistogramDataPoint_Max = sync.Pool{ - New: func() any { - return &HistogramDataPoint_Max{} - }, - } ) func NewHistogramDataPoint() *HistogramDataPoint { - if !UseProtoPooling.IsEnabled() { + if !metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() { return &HistogramDataPoint{} } return protoPoolHistogramDataPoint.Get().(*HistogramDataPoint) @@ -122,41 +53,17 @@ func DeleteHistogramDataPoint(orig *HistogramDataPoint, nullable bool) { return } - if !UseProtoPooling.IsEnabled() { + if !metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() { orig.Reset() return } - for i := range orig.Attributes { DeleteKeyValue(&orig.Attributes[i], false) } - switch ov := orig.Sum_.(type) { - case *HistogramDataPoint_Sum: - if UseProtoPooling.IsEnabled() { - ov.Sum = float64(0) - ProtoPoolHistogramDataPoint_Sum.Put(ov) - } - } for i := range orig.Exemplars { DeleteExemplar(&orig.Exemplars[i], false) } - switch ov := orig.Min_.(type) { - case *HistogramDataPoint_Min: - if UseProtoPooling.IsEnabled() { - ov.Min = float64(0) - ProtoPoolHistogramDataPoint_Min.Put(ov) - } - - } - switch ov := orig.Max_.(type) { - case *HistogramDataPoint_Max: - if UseProtoPooling.IsEnabled() { - ov.Max = float64(0) - ProtoPoolHistogramDataPoint_Max.Put(ov) - } - - } orig.Reset() if nullable { @@ -180,57 +87,31 @@ func CopyHistogramDataPoint(dest, src *HistogramDataPoint) *HistogramDataPoint { dest.Attributes = CopyKeyValueSlice(dest.Attributes, src.Attributes) dest.StartTimeUnixNano = src.StartTimeUnixNano - dest.TimeUnixNano = src.TimeUnixNano - dest.Count = src.Count - - switch t := src.Sum_.(type) { - case *HistogramDataPoint_Sum: - var ov *HistogramDataPoint_Sum - if !UseProtoPooling.IsEnabled() { - ov = &HistogramDataPoint_Sum{} - } else { - ov = ProtoPoolHistogramDataPoint_Sum.Get().(*HistogramDataPoint_Sum) - } - ov.Sum = t.Sum - dest.Sum_ = ov - default: - dest.Sum_ = nil + if src.HasSum() { + dest.SetSum(src.Sum) + } else { + dest.RemoveSum() } dest.BucketCounts = append(dest.BucketCounts[:0], src.BucketCounts...) + dest.ExplicitBounds = append(dest.ExplicitBounds[:0], src.ExplicitBounds...) + dest.Exemplars = CopyExemplarSlice(dest.Exemplars, src.Exemplars) dest.Flags = src.Flags + if src.HasMin() { + dest.SetMin(src.Min) + } else { + dest.RemoveMin() + } - switch t := src.Min_.(type) { - case *HistogramDataPoint_Min: - var ov *HistogramDataPoint_Min - if !UseProtoPooling.IsEnabled() { - ov = &HistogramDataPoint_Min{} - } else { - ov = ProtoPoolHistogramDataPoint_Min.Get().(*HistogramDataPoint_Min) - } - ov.Min = t.Min - dest.Min_ = ov - default: - dest.Min_ = nil - } - - switch t := src.Max_.(type) { - case *HistogramDataPoint_Max: - var ov *HistogramDataPoint_Max - if !UseProtoPooling.IsEnabled() { - ov = &HistogramDataPoint_Max{} - } else { - ov = ProtoPoolHistogramDataPoint_Max.Get().(*HistogramDataPoint_Max) - } - ov.Max = t.Max - dest.Max_ = ov - default: - dest.Max_ = nil + if src.HasMax() { + dest.SetMax(src.Max) + } else { + dest.RemoveMax() } return dest @@ -313,7 +194,7 @@ func (orig *HistogramDataPoint) MarshalJSON(dest *json.Stream) { dest.WriteObjectField("count") dest.WriteUint64(orig.Count) } - if orig, ok := orig.Sum_.(*HistogramDataPoint_Sum); ok { + if orig.HasSum() { dest.WriteObjectField("sum") dest.WriteFloat64(orig.Sum) } @@ -327,6 +208,7 @@ func (orig *HistogramDataPoint) MarshalJSON(dest *json.Stream) { } dest.WriteArrayEnd() } + if len(orig.ExplicitBounds) > 0 { dest.WriteObjectField("explicitBounds") dest.WriteArrayStart() @@ -337,6 +219,7 @@ func (orig *HistogramDataPoint) MarshalJSON(dest *json.Stream) { } dest.WriteArrayEnd() } + if len(orig.Exemplars) > 0 { dest.WriteObjectField("exemplars") dest.WriteArrayStart() @@ -351,11 +234,11 @@ func (orig *HistogramDataPoint) MarshalJSON(dest *json.Stream) { dest.WriteObjectField("flags") dest.WriteUint32(orig.Flags) } - if orig, ok := orig.Min_.(*HistogramDataPoint_Min); ok { + if orig.HasMin() { dest.WriteObjectField("min") dest.WriteFloat64(orig.Min) } - if orig, ok := orig.Max_.(*HistogramDataPoint_Max); ok { + if orig.HasMax() { dest.WriteObjectField("max") dest.WriteFloat64(orig.Max) } @@ -379,16 +262,7 @@ func (orig *HistogramDataPoint) UnmarshalJSON(iter *json.Iterator) { case "count": orig.Count = iter.ReadUint64() case "sum": - { - var ov *HistogramDataPoint_Sum - if !UseProtoPooling.IsEnabled() { - ov = &HistogramDataPoint_Sum{} - } else { - ov = ProtoPoolHistogramDataPoint_Sum.Get().(*HistogramDataPoint_Sum) - } - ov.Sum = iter.ReadFloat64() - orig.Sum_ = ov - } + orig.SetSum(iter.ReadFloat64()) case "bucketCounts", "bucket_counts": for iter.ReadArray() { @@ -409,28 +283,10 @@ func (orig *HistogramDataPoint) UnmarshalJSON(iter *json.Iterator) { case "flags": orig.Flags = iter.ReadUint32() case "min": - { - var ov *HistogramDataPoint_Min - if !UseProtoPooling.IsEnabled() { - ov = &HistogramDataPoint_Min{} - } else { - ov = ProtoPoolHistogramDataPoint_Min.Get().(*HistogramDataPoint_Min) - } - ov.Min = iter.ReadFloat64() - orig.Min_ = ov - } + orig.SetMin(iter.ReadFloat64()) case "max": - { - var ov *HistogramDataPoint_Max - if !UseProtoPooling.IsEnabled() { - ov = &HistogramDataPoint_Max{} - } else { - ov = ProtoPoolHistogramDataPoint_Max.Get().(*HistogramDataPoint_Max) - } - ov.Max = iter.ReadFloat64() - orig.Max_ = ov - } + orig.SetMax(iter.ReadFloat64()) default: iter.Skip() @@ -446,17 +302,16 @@ func (orig *HistogramDataPoint) SizeProto() int { l = orig.Attributes[i].SizeProto() n += 1 + proto.Sov(uint64(l)) + l } - if orig.StartTimeUnixNano != 0 { + if orig.StartTimeUnixNano != uint64(0) { n += 9 } - if orig.TimeUnixNano != 0 { + if orig.TimeUnixNano != uint64(0) { n += 9 } - if orig.Count != 0 { + if orig.Count != uint64(0) { n += 9 } - if orig, ok := orig.Sum_.(*HistogramDataPoint_Sum); ok { - _ = orig + if orig.HasSum() { n += 9 } l = len(orig.BucketCounts) @@ -473,15 +328,13 @@ func (orig *HistogramDataPoint) SizeProto() int { l = orig.Exemplars[i].SizeProto() n += 1 + proto.Sov(uint64(l)) + l } - if orig.Flags != 0 { + if orig.Flags != uint32(0) { n += 1 + proto.Sov(uint64(orig.Flags)) } - if orig, ok := orig.Min_.(*HistogramDataPoint_Min); ok { - _ = orig + if orig.HasMin() { n += 9 } - if orig, ok := orig.Max_.(*HistogramDataPoint_Max); ok { - _ = orig + if orig.HasMax() { n += 9 } return n @@ -498,25 +351,25 @@ func (orig *HistogramDataPoint) MarshalProto(buf []byte) int { pos-- buf[pos] = 0x4a } - if orig.StartTimeUnixNano != 0 { + if orig.StartTimeUnixNano != uint64(0) { pos -= 8 binary.LittleEndian.PutUint64(buf[pos:], uint64(orig.StartTimeUnixNano)) pos-- buf[pos] = 0x11 } - if orig.TimeUnixNano != 0 { + if orig.TimeUnixNano != uint64(0) { pos -= 8 binary.LittleEndian.PutUint64(buf[pos:], uint64(orig.TimeUnixNano)) pos-- buf[pos] = 0x19 } - if orig.Count != 0 { + if orig.Count != uint64(0) { pos -= 8 binary.LittleEndian.PutUint64(buf[pos:], uint64(orig.Count)) pos-- buf[pos] = 0x21 } - if orig, ok := orig.Sum_.(*HistogramDataPoint_Sum); ok { + if orig.HasSum() { pos -= 8 binary.LittleEndian.PutUint64(buf[pos:], math.Float64bits(orig.Sum)) pos-- @@ -549,18 +402,18 @@ func (orig *HistogramDataPoint) MarshalProto(buf []byte) int { pos-- buf[pos] = 0x42 } - if orig.Flags != 0 { + if orig.Flags != uint32(0) { pos = proto.EncodeVarint(buf, pos, uint64(orig.Flags)) pos-- buf[pos] = 0x50 } - if orig, ok := orig.Min_.(*HistogramDataPoint_Min); ok { + if orig.HasMin() { pos -= 8 binary.LittleEndian.PutUint64(buf[pos:], math.Float64bits(orig.Min)) pos-- buf[pos] = 0x59 } - if orig, ok := orig.Max_.(*HistogramDataPoint_Max); ok { + if orig.HasMax() { pos -= 8 binary.LittleEndian.PutUint64(buf[pos:], math.Float64bits(orig.Max)) pos-- @@ -645,14 +498,7 @@ func (orig *HistogramDataPoint) UnmarshalProto(buf []byte) error { if err != nil { return err } - var ov *HistogramDataPoint_Sum - if !UseProtoPooling.IsEnabled() { - ov = &HistogramDataPoint_Sum{} - } else { - ov = ProtoPoolHistogramDataPoint_Sum.Get().(*HistogramDataPoint_Sum) - } - ov.Sum = math.Float64frombits(num) - orig.Sum_ = ov + orig.SetSum(math.Float64frombits(num)) case 6: switch wireType { case proto.WireTypeLen: @@ -743,7 +589,6 @@ func (orig *HistogramDataPoint) UnmarshalProto(buf []byte) error { if err != nil { return err } - orig.Flags = uint32(num) case 11: @@ -755,14 +600,7 @@ func (orig *HistogramDataPoint) UnmarshalProto(buf []byte) error { if err != nil { return err } - var ov *HistogramDataPoint_Min - if !UseProtoPooling.IsEnabled() { - ov = &HistogramDataPoint_Min{} - } else { - ov = ProtoPoolHistogramDataPoint_Min.Get().(*HistogramDataPoint_Min) - } - ov.Min = math.Float64frombits(num) - orig.Min_ = ov + orig.SetMin(math.Float64frombits(num)) case 12: if wireType != proto.WireTypeI64 { @@ -773,14 +611,7 @@ func (orig *HistogramDataPoint) UnmarshalProto(buf []byte) error { if err != nil { return err } - var ov *HistogramDataPoint_Max - if !UseProtoPooling.IsEnabled() { - ov = &HistogramDataPoint_Max{} - } else { - ov = ProtoPoolHistogramDataPoint_Max.Get().(*HistogramDataPoint_Max) - } - ov.Max = math.Float64frombits(num) - orig.Max_ = ov + orig.SetMax(math.Float64frombits(num)) default: pos, err = proto.ConsumeUnknown(buf, pos, wireType) if err != nil { @@ -791,19 +622,70 @@ func (orig *HistogramDataPoint) UnmarshalProto(buf []byte) error { return nil } +const fieldBlockHistogramDataPointSum = uint64(0 >> 6) +const fieldBitHistogramDataPointSum = uint64(1 << 0 & 0x3F) + +func (m *HistogramDataPoint) SetSum(value float64) { + m.Sum = value + m.metadata[fieldBlockHistogramDataPointSum] |= fieldBitHistogramDataPointSum +} + +func (m *HistogramDataPoint) RemoveSum() { + m.Sum = float64(0) + m.metadata[fieldBlockHistogramDataPointSum] &^= fieldBitHistogramDataPointSum +} + +func (m *HistogramDataPoint) HasSum() bool { + return m.metadata[fieldBlockHistogramDataPointSum]&fieldBitHistogramDataPointSum != 0 +} + +const fieldBlockHistogramDataPointMin = uint64(1 >> 6) +const fieldBitHistogramDataPointMin = uint64(1 << 1 & 0x3F) + +func (m *HistogramDataPoint) SetMin(value float64) { + m.Min = value + m.metadata[fieldBlockHistogramDataPointMin] |= fieldBitHistogramDataPointMin +} + +func (m *HistogramDataPoint) RemoveMin() { + m.Min = float64(0) + m.metadata[fieldBlockHistogramDataPointMin] &^= fieldBitHistogramDataPointMin +} + +func (m *HistogramDataPoint) HasMin() bool { + return m.metadata[fieldBlockHistogramDataPointMin]&fieldBitHistogramDataPointMin != 0 +} + +const fieldBlockHistogramDataPointMax = uint64(2 >> 6) +const fieldBitHistogramDataPointMax = uint64(1 << 2 & 0x3F) + +func (m *HistogramDataPoint) SetMax(value float64) { + m.Max = value + m.metadata[fieldBlockHistogramDataPointMax] |= fieldBitHistogramDataPointMax +} + +func (m *HistogramDataPoint) RemoveMax() { + m.Max = float64(0) + m.metadata[fieldBlockHistogramDataPointMax] &^= fieldBitHistogramDataPointMax +} + +func (m *HistogramDataPoint) HasMax() bool { + return m.metadata[fieldBlockHistogramDataPointMax]&fieldBitHistogramDataPointMax != 0 +} + func GenTestHistogramDataPoint() *HistogramDataPoint { orig := NewHistogramDataPoint() orig.Attributes = []KeyValue{{}, *GenTestKeyValue()} orig.StartTimeUnixNano = uint64(13) orig.TimeUnixNano = uint64(13) orig.Count = uint64(13) - orig.Sum_ = &HistogramDataPoint_Sum{Sum: float64(3.1415926)} + orig.SetSum(float64(3.1415926)) orig.BucketCounts = []uint64{uint64(0), uint64(13)} orig.ExplicitBounds = []float64{float64(0), float64(3.1415926)} orig.Exemplars = []Exemplar{{}, *GenTestExemplar()} orig.Flags = uint32(13) - orig.Min_ = &HistogramDataPoint_Min{Min: float64(3.1415926)} - orig.Max_ = &HistogramDataPoint_Max{Max: float64(3.1415926)} + orig.SetMin(float64(3.1415926)) + orig.SetMax(float64(3.1415926)) return orig } diff --git a/pdata/internal/generated_proto_histogramdatapoint_test.go b/pdata/internal/generated_proto_histogramdatapoint_test.go index 9f4d54db8dfe..5d7c598cbad4 100644 --- a/pdata/internal/generated_proto_histogramdatapoint_test.go +++ b/pdata/internal/generated_proto_histogramdatapoint_test.go @@ -17,16 +17,17 @@ import ( "go.opentelemetry.io/collector/featuregate" "go.opentelemetry.io/collector/pdata/internal/json" + "go.opentelemetry.io/collector/pdata/internal/metadata" ) func TestCopyHistogramDataPoint(t *testing.T) { for name, src := range genTestEncodingValuesHistogramDataPoint() { for _, pooling := range []bool{true, false} { t.Run(name+"/Pooling="+strconv.FormatBool(pooling), func(t *testing.T) { - prevPooling := UseProtoPooling.IsEnabled() - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), pooling)) + prevPooling := metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), pooling)) defer func() { - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), prevPooling)) + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), prevPooling)) }() dest := NewHistogramDataPoint() @@ -102,10 +103,10 @@ func TestMarshalAndUnmarshalJSONHistogramDataPoint(t *testing.T) { for name, src := range genTestEncodingValuesHistogramDataPoint() { for _, pooling := range []bool{true, false} { t.Run(name+"/Pooling="+strconv.FormatBool(pooling), func(t *testing.T) { - prevPooling := UseProtoPooling.IsEnabled() - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), pooling)) + prevPooling := metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), pooling)) defer func() { - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), prevPooling)) + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), prevPooling)) }() stream := json.BorrowStream(nil) @@ -146,10 +147,10 @@ func TestMarshalAndUnmarshalProtoHistogramDataPoint(t *testing.T) { for name, src := range genTestEncodingValuesHistogramDataPoint() { for _, pooling := range []bool{true, false} { t.Run(name+"/Pooling="+strconv.FormatBool(pooling), func(t *testing.T) { - prevPooling := UseProtoPooling.IsEnabled() - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), pooling)) + prevPooling := metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), pooling)) defer func() { - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), prevPooling)) + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), prevPooling)) }() buf := make([]byte, src.SizeProto()) @@ -220,13 +221,25 @@ func genTestEncodingValuesHistogramDataPoint() map[string]*HistogramDataPoint { "Attributes/test": {Attributes: []KeyValue{{}, *GenTestKeyValue()}}, "StartTimeUnixNano/test": {StartTimeUnixNano: uint64(13)}, "TimeUnixNano/test": {TimeUnixNano: uint64(13)}, - "Count/test": {Count: uint64(13)}, "Sum/default": {Sum_: &HistogramDataPoint_Sum{Sum: float64(0)}}, - "Sum/test": {Sum_: &HistogramDataPoint_Sum{Sum: float64(3.1415926)}}, + "Count/test": {Count: uint64(13)}, + "Sum/test": func() *HistogramDataPoint { + ms := NewHistogramDataPoint() + ms.SetSum(float64(3.1415926)) + return ms + }(), "BucketCounts/test": {BucketCounts: []uint64{uint64(0), uint64(13)}}, "ExplicitBounds/test": {ExplicitBounds: []float64{float64(0), float64(3.1415926)}}, "Exemplars/test": {Exemplars: []Exemplar{{}, *GenTestExemplar()}}, - "Flags/test": {Flags: uint32(13)}, "Min/default": {Min_: &HistogramDataPoint_Min{Min: float64(0)}}, - "Min/test": {Min_: &HistogramDataPoint_Min{Min: float64(3.1415926)}}, "Max/default": {Max_: &HistogramDataPoint_Max{Max: float64(0)}}, - "Max/test": {Max_: &HistogramDataPoint_Max{Max: float64(3.1415926)}}, + "Flags/test": {Flags: uint32(13)}, + "Min/test": func() *HistogramDataPoint { + ms := NewHistogramDataPoint() + ms.SetMin(float64(3.1415926)) + return ms + }(), + "Max/test": func() *HistogramDataPoint { + ms := NewHistogramDataPoint() + ms.SetMax(float64(3.1415926)) + return ms + }(), } } diff --git a/pdata/internal/generated_proto_instrumentationscope.go b/pdata/internal/generated_proto_instrumentationscope.go index 1e64085e9464..a8162b4338f3 100644 --- a/pdata/internal/generated_proto_instrumentationscope.go +++ b/pdata/internal/generated_proto_instrumentationscope.go @@ -11,6 +11,7 @@ import ( "sync" "go.opentelemetry.io/collector/pdata/internal/json" + "go.opentelemetry.io/collector/pdata/internal/metadata" "go.opentelemetry.io/collector/pdata/internal/proto" ) @@ -31,7 +32,7 @@ var ( ) func NewInstrumentationScope() *InstrumentationScope { - if !UseProtoPooling.IsEnabled() { + if !metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() { return &InstrumentationScope{} } return protoPoolInstrumentationScope.Get().(*InstrumentationScope) @@ -42,7 +43,7 @@ func DeleteInstrumentationScope(orig *InstrumentationScope, nullable bool) { return } - if !UseProtoPooling.IsEnabled() { + if !metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() { orig.Reset() return } @@ -71,9 +72,7 @@ func CopyInstrumentationScope(dest, src *InstrumentationScope) *InstrumentationS dest = NewInstrumentationScope() } dest.Name = src.Name - dest.Version = src.Version - dest.Attributes = CopyKeyValueSlice(dest.Attributes, src.Attributes) dest.DroppedAttributesCount = src.DroppedAttributesCount @@ -187,10 +186,12 @@ func (orig *InstrumentationScope) SizeProto() int { var n int var l int _ = l + l = len(orig.Name) if l > 0 { n += 1 + proto.Sov(uint64(l)) + l } + l = len(orig.Version) if l > 0 { n += 1 + proto.Sov(uint64(l)) + l @@ -199,7 +200,7 @@ func (orig *InstrumentationScope) SizeProto() int { l = orig.Attributes[i].SizeProto() n += 1 + proto.Sov(uint64(l)) + l } - if orig.DroppedAttributesCount != 0 { + if orig.DroppedAttributesCount != uint32(0) { n += 1 + proto.Sov(uint64(orig.DroppedAttributesCount)) } return n @@ -232,7 +233,7 @@ func (orig *InstrumentationScope) MarshalProto(buf []byte) int { pos-- buf[pos] = 0x1a } - if orig.DroppedAttributesCount != 0 { + if orig.DroppedAttributesCount != uint32(0) { pos = proto.EncodeVarint(buf, pos, uint64(orig.DroppedAttributesCount)) pos-- buf[pos] = 0x20 @@ -304,7 +305,6 @@ func (orig *InstrumentationScope) UnmarshalProto(buf []byte) error { if err != nil { return err } - orig.DroppedAttributesCount = uint32(num) default: pos, err = proto.ConsumeUnknown(buf, pos, wireType) diff --git a/pdata/internal/generated_proto_instrumentationscope_test.go b/pdata/internal/generated_proto_instrumentationscope_test.go index 2af0077e9704..495bc8a63bdb 100644 --- a/pdata/internal/generated_proto_instrumentationscope_test.go +++ b/pdata/internal/generated_proto_instrumentationscope_test.go @@ -17,16 +17,17 @@ import ( "go.opentelemetry.io/collector/featuregate" "go.opentelemetry.io/collector/pdata/internal/json" + "go.opentelemetry.io/collector/pdata/internal/metadata" ) func TestCopyInstrumentationScope(t *testing.T) { for name, src := range genTestEncodingValuesInstrumentationScope() { for _, pooling := range []bool{true, false} { t.Run(name+"/Pooling="+strconv.FormatBool(pooling), func(t *testing.T) { - prevPooling := UseProtoPooling.IsEnabled() - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), pooling)) + prevPooling := metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), pooling)) defer func() { - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), prevPooling)) + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), prevPooling)) }() dest := NewInstrumentationScope() @@ -102,10 +103,10 @@ func TestMarshalAndUnmarshalJSONInstrumentationScope(t *testing.T) { for name, src := range genTestEncodingValuesInstrumentationScope() { for _, pooling := range []bool{true, false} { t.Run(name+"/Pooling="+strconv.FormatBool(pooling), func(t *testing.T) { - prevPooling := UseProtoPooling.IsEnabled() - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), pooling)) + prevPooling := metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), pooling)) defer func() { - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), prevPooling)) + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), prevPooling)) }() stream := json.BorrowStream(nil) @@ -146,10 +147,10 @@ func TestMarshalAndUnmarshalProtoInstrumentationScope(t *testing.T) { for name, src := range genTestEncodingValuesInstrumentationScope() { for _, pooling := range []bool{true, false} { t.Run(name+"/Pooling="+strconv.FormatBool(pooling), func(t *testing.T) { - prevPooling := UseProtoPooling.IsEnabled() - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), pooling)) + prevPooling := metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), pooling)) defer func() { - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), prevPooling)) + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), prevPooling)) }() buf := make([]byte, src.SizeProto()) diff --git a/pdata/internal/generated_proto_ipaddr.go b/pdata/internal/generated_proto_ipaddr.go index 2cd6029a63af..3b72d1d22621 100644 --- a/pdata/internal/generated_proto_ipaddr.go +++ b/pdata/internal/generated_proto_ipaddr.go @@ -11,12 +11,13 @@ import ( "sync" "go.opentelemetry.io/collector/pdata/internal/json" + "go.opentelemetry.io/collector/pdata/internal/metadata" "go.opentelemetry.io/collector/pdata/internal/proto" ) type IPAddr struct { - IP []byte Zone string + IP []byte } var ( @@ -28,7 +29,7 @@ var ( ) func NewIPAddr() *IPAddr { - if !UseProtoPooling.IsEnabled() { + if !metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() { return &IPAddr{} } return protoPoolIPAddr.Get().(*IPAddr) @@ -39,7 +40,7 @@ func DeleteIPAddr(orig *IPAddr, nullable bool) { return } - if !UseProtoPooling.IsEnabled() { + if !metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() { orig.Reset() return } @@ -64,7 +65,6 @@ func CopyIPAddr(dest, src *IPAddr) *IPAddr { dest = NewIPAddr() } dest.IP = src.IP - dest.Zone = src.Zone return dest @@ -155,10 +155,12 @@ func (orig *IPAddr) SizeProto() int { var n int var l int _ = l + l = len(orig.IP) if l > 0 { n += 1 + proto.Sov(uint64(l)) + l } + l = len(orig.Zone) if l > 0 { n += 1 + proto.Sov(uint64(l)) + l diff --git a/pdata/internal/generated_proto_ipaddr_test.go b/pdata/internal/generated_proto_ipaddr_test.go index aa982246e4b9..3d591960bdaa 100644 --- a/pdata/internal/generated_proto_ipaddr_test.go +++ b/pdata/internal/generated_proto_ipaddr_test.go @@ -17,16 +17,17 @@ import ( "go.opentelemetry.io/collector/featuregate" "go.opentelemetry.io/collector/pdata/internal/json" + "go.opentelemetry.io/collector/pdata/internal/metadata" ) func TestCopyIPAddr(t *testing.T) { for name, src := range genTestEncodingValuesIPAddr() { for _, pooling := range []bool{true, false} { t.Run(name+"/Pooling="+strconv.FormatBool(pooling), func(t *testing.T) { - prevPooling := UseProtoPooling.IsEnabled() - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), pooling)) + prevPooling := metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), pooling)) defer func() { - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), prevPooling)) + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), prevPooling)) }() dest := NewIPAddr() @@ -102,10 +103,10 @@ func TestMarshalAndUnmarshalJSONIPAddr(t *testing.T) { for name, src := range genTestEncodingValuesIPAddr() { for _, pooling := range []bool{true, false} { t.Run(name+"/Pooling="+strconv.FormatBool(pooling), func(t *testing.T) { - prevPooling := UseProtoPooling.IsEnabled() - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), pooling)) + prevPooling := metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), pooling)) defer func() { - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), prevPooling)) + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), prevPooling)) }() stream := json.BorrowStream(nil) @@ -146,10 +147,10 @@ func TestMarshalAndUnmarshalProtoIPAddr(t *testing.T) { for name, src := range genTestEncodingValuesIPAddr() { for _, pooling := range []bool{true, false} { t.Run(name+"/Pooling="+strconv.FormatBool(pooling), func(t *testing.T) { - prevPooling := UseProtoPooling.IsEnabled() - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), pooling)) + prevPooling := metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), pooling)) defer func() { - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), prevPooling)) + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), prevPooling)) }() buf := make([]byte, src.SizeProto()) diff --git a/pdata/internal/generated_proto_keyvalue.go b/pdata/internal/generated_proto_keyvalue.go index 3208776fb650..5f80a111ab3d 100644 --- a/pdata/internal/generated_proto_keyvalue.go +++ b/pdata/internal/generated_proto_keyvalue.go @@ -11,12 +11,14 @@ import ( "sync" "go.opentelemetry.io/collector/pdata/internal/json" + "go.opentelemetry.io/collector/pdata/internal/metadata" "go.opentelemetry.io/collector/pdata/internal/proto" ) type KeyValue struct { - Key string - Value AnyValue + Value AnyValue + Key string + KeyStrindex int32 } var ( @@ -28,7 +30,7 @@ var ( ) func NewKeyValue() *KeyValue { - if !UseProtoPooling.IsEnabled() { + if !metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() { return &KeyValue{} } return protoPoolKeyValue.Get().(*KeyValue) @@ -39,7 +41,7 @@ func DeleteKeyValue(orig *KeyValue, nullable bool) { return } - if !UseProtoPooling.IsEnabled() { + if !metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() { orig.Reset() return } @@ -66,9 +68,10 @@ func CopyKeyValue(dest, src *KeyValue) *KeyValue { dest = NewKeyValue() } dest.Key = src.Key - CopyAnyValue(&dest.Value, &src.Value) + dest.KeyStrindex = src.KeyStrindex + return dest } @@ -133,6 +136,10 @@ func (orig *KeyValue) MarshalJSON(dest *json.Stream) { } dest.WriteObjectField("value") orig.Value.MarshalJSON(dest) + if orig.KeyStrindex != int32(0) { + dest.WriteObjectField("keyStrindex") + dest.WriteInt32(orig.KeyStrindex) + } dest.WriteObjectEnd() } @@ -145,6 +152,8 @@ func (orig *KeyValue) UnmarshalJSON(iter *json.Iterator) { case "value": orig.Value.UnmarshalJSON(iter) + case "keyStrindex", "key_strindex": + orig.KeyStrindex = iter.ReadInt32() default: iter.Skip() } @@ -155,12 +164,16 @@ func (orig *KeyValue) SizeProto() int { var n int var l int _ = l + l = len(orig.Key) if l > 0 { n += 1 + proto.Sov(uint64(l)) + l } l = orig.Value.SizeProto() n += 1 + proto.Sov(uint64(l)) + l + if orig.KeyStrindex != int32(0) { + n += 1 + proto.Sov(uint64(orig.KeyStrindex)) + } return n } @@ -182,6 +195,11 @@ func (orig *KeyValue) MarshalProto(buf []byte) int { pos-- buf[pos] = 0x12 + if orig.KeyStrindex != int32(0) { + pos = proto.EncodeVarint(buf, pos, uint64(orig.KeyStrindex)) + pos-- + buf[pos] = 0x18 + } return len(buf) - pos } @@ -227,6 +245,17 @@ func (orig *KeyValue) UnmarshalProto(buf []byte) error { if err != nil { return err } + + case 3: + if wireType != proto.WireTypeVarint { + return fmt.Errorf("proto: wrong wireType = %d for field KeyStrindex", wireType) + } + var num uint64 + num, pos, err = proto.ConsumeVarint(buf, pos) + if err != nil { + return err + } + orig.KeyStrindex = int32(num) default: pos, err = proto.ConsumeUnknown(buf, pos, wireType) if err != nil { @@ -241,6 +270,7 @@ func GenTestKeyValue() *KeyValue { orig := NewKeyValue() orig.Key = "test_key" orig.Value = *GenTestAnyValue() + orig.KeyStrindex = int32(13) return orig } diff --git a/pdata/internal/generated_proto_keyvalue_test.go b/pdata/internal/generated_proto_keyvalue_test.go index b8c21046f732..db495e180751 100644 --- a/pdata/internal/generated_proto_keyvalue_test.go +++ b/pdata/internal/generated_proto_keyvalue_test.go @@ -17,16 +17,17 @@ import ( "go.opentelemetry.io/collector/featuregate" "go.opentelemetry.io/collector/pdata/internal/json" + "go.opentelemetry.io/collector/pdata/internal/metadata" ) func TestCopyKeyValue(t *testing.T) { for name, src := range genTestEncodingValuesKeyValue() { for _, pooling := range []bool{true, false} { t.Run(name+"/Pooling="+strconv.FormatBool(pooling), func(t *testing.T) { - prevPooling := UseProtoPooling.IsEnabled() - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), pooling)) + prevPooling := metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), pooling)) defer func() { - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), prevPooling)) + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), prevPooling)) }() dest := NewKeyValue() @@ -102,10 +103,10 @@ func TestMarshalAndUnmarshalJSONKeyValue(t *testing.T) { for name, src := range genTestEncodingValuesKeyValue() { for _, pooling := range []bool{true, false} { t.Run(name+"/Pooling="+strconv.FormatBool(pooling), func(t *testing.T) { - prevPooling := UseProtoPooling.IsEnabled() - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), pooling)) + prevPooling := metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), pooling)) defer func() { - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), prevPooling)) + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), prevPooling)) }() stream := json.BorrowStream(nil) @@ -146,10 +147,10 @@ func TestMarshalAndUnmarshalProtoKeyValue(t *testing.T) { for name, src := range genTestEncodingValuesKeyValue() { for _, pooling := range []bool{true, false} { t.Run(name+"/Pooling="+strconv.FormatBool(pooling), func(t *testing.T) { - prevPooling := UseProtoPooling.IsEnabled() - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), pooling)) + prevPooling := metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), pooling)) defer func() { - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), prevPooling)) + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), prevPooling)) }() buf := make([]byte, src.SizeProto()) @@ -188,18 +189,21 @@ func TestMarshalAndUnmarshalProtoViaProtobufKeyValue(t *testing.T) { func genTestFailingUnmarshalProtoValuesKeyValue() map[string][]byte { return map[string][]byte{ - "invalid_field": {0x02}, - "Key/wrong_wire_type": {0xc}, - "Key/missing_value": {0xa}, - "Value/wrong_wire_type": {0x14}, - "Value/missing_value": {0x12}, + "invalid_field": {0x02}, + "Key/wrong_wire_type": {0xc}, + "Key/missing_value": {0xa}, + "Value/wrong_wire_type": {0x14}, + "Value/missing_value": {0x12}, + "KeyStrindex/wrong_wire_type": {0x1c}, + "KeyStrindex/missing_value": {0x18}, } } func genTestEncodingValuesKeyValue() map[string]*KeyValue { return map[string]*KeyValue{ - "empty": NewKeyValue(), - "Key/test": {Key: "test_key"}, - "Value/test": {Value: *GenTestAnyValue()}, + "empty": NewKeyValue(), + "Key/test": {Key: "test_key"}, + "Value/test": {Value: *GenTestAnyValue()}, + "KeyStrindex/test": {KeyStrindex: int32(13)}, } } diff --git a/pdata/internal/generated_proto_keyvalueandunit.go b/pdata/internal/generated_proto_keyvalueandunit.go index 14c2e763d978..3e0c6cf92527 100644 --- a/pdata/internal/generated_proto_keyvalueandunit.go +++ b/pdata/internal/generated_proto_keyvalueandunit.go @@ -11,6 +11,7 @@ import ( "sync" "go.opentelemetry.io/collector/pdata/internal/json" + "go.opentelemetry.io/collector/pdata/internal/metadata" "go.opentelemetry.io/collector/pdata/internal/proto" ) @@ -18,8 +19,8 @@ import ( // style of encoding attributes which is more convenient // for profiles than opentelemetry.proto.common.v1.KeyValue. type KeyValueAndUnit struct { - KeyStrindex int32 Value AnyValue + KeyStrindex int32 UnitStrindex int32 } @@ -32,7 +33,7 @@ var ( ) func NewKeyValueAndUnit() *KeyValueAndUnit { - if !UseProtoPooling.IsEnabled() { + if !metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() { return &KeyValueAndUnit{} } return protoPoolKeyValueAndUnit.Get().(*KeyValueAndUnit) @@ -43,7 +44,7 @@ func DeleteKeyValueAndUnit(orig *KeyValueAndUnit, nullable bool) { return } - if !UseProtoPooling.IsEnabled() { + if !metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() { orig.Reset() return } @@ -70,7 +71,6 @@ func CopyKeyValueAndUnit(dest, src *KeyValueAndUnit) *KeyValueAndUnit { dest = NewKeyValueAndUnit() } dest.KeyStrindex = src.KeyStrindex - CopyAnyValue(&dest.Value, &src.Value) dest.UnitStrindex = src.UnitStrindex @@ -167,12 +167,12 @@ func (orig *KeyValueAndUnit) SizeProto() int { var n int var l int _ = l - if orig.KeyStrindex != 0 { + if orig.KeyStrindex != int32(0) { n += 1 + proto.Sov(uint64(orig.KeyStrindex)) } l = orig.Value.SizeProto() n += 1 + proto.Sov(uint64(l)) + l - if orig.UnitStrindex != 0 { + if orig.UnitStrindex != int32(0) { n += 1 + proto.Sov(uint64(orig.UnitStrindex)) } return n @@ -182,7 +182,7 @@ func (orig *KeyValueAndUnit) MarshalProto(buf []byte) int { pos := len(buf) var l int _ = l - if orig.KeyStrindex != 0 { + if orig.KeyStrindex != int32(0) { pos = proto.EncodeVarint(buf, pos, uint64(orig.KeyStrindex)) pos-- buf[pos] = 0x8 @@ -193,7 +193,7 @@ func (orig *KeyValueAndUnit) MarshalProto(buf []byte) int { pos-- buf[pos] = 0x12 - if orig.UnitStrindex != 0 { + if orig.UnitStrindex != int32(0) { pos = proto.EncodeVarint(buf, pos, uint64(orig.UnitStrindex)) pos-- buf[pos] = 0x18 @@ -225,7 +225,6 @@ func (orig *KeyValueAndUnit) UnmarshalProto(buf []byte) error { if err != nil { return err } - orig.KeyStrindex = int32(num) case 2: @@ -253,7 +252,6 @@ func (orig *KeyValueAndUnit) UnmarshalProto(buf []byte) error { if err != nil { return err } - orig.UnitStrindex = int32(num) default: pos, err = proto.ConsumeUnknown(buf, pos, wireType) diff --git a/pdata/internal/generated_proto_keyvalueandunit_test.go b/pdata/internal/generated_proto_keyvalueandunit_test.go index 50f28595a2bc..4b66e96ca005 100644 --- a/pdata/internal/generated_proto_keyvalueandunit_test.go +++ b/pdata/internal/generated_proto_keyvalueandunit_test.go @@ -17,16 +17,17 @@ import ( "go.opentelemetry.io/collector/featuregate" "go.opentelemetry.io/collector/pdata/internal/json" + "go.opentelemetry.io/collector/pdata/internal/metadata" ) func TestCopyKeyValueAndUnit(t *testing.T) { for name, src := range genTestEncodingValuesKeyValueAndUnit() { for _, pooling := range []bool{true, false} { t.Run(name+"/Pooling="+strconv.FormatBool(pooling), func(t *testing.T) { - prevPooling := UseProtoPooling.IsEnabled() - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), pooling)) + prevPooling := metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), pooling)) defer func() { - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), prevPooling)) + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), prevPooling)) }() dest := NewKeyValueAndUnit() @@ -102,10 +103,10 @@ func TestMarshalAndUnmarshalJSONKeyValueAndUnit(t *testing.T) { for name, src := range genTestEncodingValuesKeyValueAndUnit() { for _, pooling := range []bool{true, false} { t.Run(name+"/Pooling="+strconv.FormatBool(pooling), func(t *testing.T) { - prevPooling := UseProtoPooling.IsEnabled() - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), pooling)) + prevPooling := metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), pooling)) defer func() { - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), prevPooling)) + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), prevPooling)) }() stream := json.BorrowStream(nil) @@ -146,10 +147,10 @@ func TestMarshalAndUnmarshalProtoKeyValueAndUnit(t *testing.T) { for name, src := range genTestEncodingValuesKeyValueAndUnit() { for _, pooling := range []bool{true, false} { t.Run(name+"/Pooling="+strconv.FormatBool(pooling), func(t *testing.T) { - prevPooling := UseProtoPooling.IsEnabled() - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), pooling)) + prevPooling := metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), pooling)) defer func() { - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), prevPooling)) + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), prevPooling)) }() buf := make([]byte, src.SizeProto()) diff --git a/pdata/internal/generated_proto_keyvaluelist.go b/pdata/internal/generated_proto_keyvaluelist.go index 1cb1fef73c8e..9cb772d4ceb8 100644 --- a/pdata/internal/generated_proto_keyvaluelist.go +++ b/pdata/internal/generated_proto_keyvaluelist.go @@ -11,6 +11,7 @@ import ( "sync" "go.opentelemetry.io/collector/pdata/internal/json" + "go.opentelemetry.io/collector/pdata/internal/metadata" "go.opentelemetry.io/collector/pdata/internal/proto" ) @@ -28,7 +29,7 @@ var ( ) func NewKeyValueList() *KeyValueList { - if !UseProtoPooling.IsEnabled() { + if !metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() { return &KeyValueList{} } return protoPoolKeyValueList.Get().(*KeyValueList) @@ -39,15 +40,13 @@ func DeleteKeyValueList(orig *KeyValueList, nullable bool) { return } - if !UseProtoPooling.IsEnabled() { + if !metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() { orig.Reset() return } - for i := range orig.Values { DeleteKeyValue(&orig.Values[i], false) } - orig.Reset() if nullable { protoPoolKeyValueList.Put(orig) diff --git a/pdata/internal/generated_proto_keyvaluelist_test.go b/pdata/internal/generated_proto_keyvaluelist_test.go index eee0761ab6d1..bd5d2a6cdf3d 100644 --- a/pdata/internal/generated_proto_keyvaluelist_test.go +++ b/pdata/internal/generated_proto_keyvaluelist_test.go @@ -17,16 +17,17 @@ import ( "go.opentelemetry.io/collector/featuregate" "go.opentelemetry.io/collector/pdata/internal/json" + "go.opentelemetry.io/collector/pdata/internal/metadata" ) func TestCopyKeyValueList(t *testing.T) { for name, src := range genTestEncodingValuesKeyValueList() { for _, pooling := range []bool{true, false} { t.Run(name+"/Pooling="+strconv.FormatBool(pooling), func(t *testing.T) { - prevPooling := UseProtoPooling.IsEnabled() - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), pooling)) + prevPooling := metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), pooling)) defer func() { - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), prevPooling)) + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), prevPooling)) }() dest := NewKeyValueList() @@ -102,10 +103,10 @@ func TestMarshalAndUnmarshalJSONKeyValueList(t *testing.T) { for name, src := range genTestEncodingValuesKeyValueList() { for _, pooling := range []bool{true, false} { t.Run(name+"/Pooling="+strconv.FormatBool(pooling), func(t *testing.T) { - prevPooling := UseProtoPooling.IsEnabled() - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), pooling)) + prevPooling := metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), pooling)) defer func() { - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), prevPooling)) + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), prevPooling)) }() stream := json.BorrowStream(nil) @@ -146,10 +147,10 @@ func TestMarshalAndUnmarshalProtoKeyValueList(t *testing.T) { for name, src := range genTestEncodingValuesKeyValueList() { for _, pooling := range []bool{true, false} { t.Run(name+"/Pooling="+strconv.FormatBool(pooling), func(t *testing.T) { - prevPooling := UseProtoPooling.IsEnabled() - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), pooling)) + prevPooling := metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), pooling)) defer func() { - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), prevPooling)) + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), prevPooling)) }() buf := make([]byte, src.SizeProto()) diff --git a/pdata/internal/generated_proto_line.go b/pdata/internal/generated_proto_line.go index f9cde7b965a8..0fe3a738b26e 100644 --- a/pdata/internal/generated_proto_line.go +++ b/pdata/internal/generated_proto_line.go @@ -11,6 +11,7 @@ import ( "sync" "go.opentelemetry.io/collector/pdata/internal/json" + "go.opentelemetry.io/collector/pdata/internal/metadata" "go.opentelemetry.io/collector/pdata/internal/proto" ) @@ -30,7 +31,7 @@ var ( ) func NewLine() *Line { - if !UseProtoPooling.IsEnabled() { + if !metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() { return &Line{} } return protoPoolLine.Get().(*Line) @@ -41,7 +42,7 @@ func DeleteLine(orig *Line, nullable bool) { return } - if !UseProtoPooling.IsEnabled() { + if !metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() { orig.Reset() return } @@ -66,9 +67,7 @@ func CopyLine(dest, src *Line) *Line { dest = NewLine() } dest.FunctionIndex = src.FunctionIndex - dest.Line = src.Line - dest.Column = src.Column return dest @@ -164,13 +163,13 @@ func (orig *Line) SizeProto() int { var n int var l int _ = l - if orig.FunctionIndex != 0 { + if orig.FunctionIndex != int32(0) { n += 1 + proto.Sov(uint64(orig.FunctionIndex)) } - if orig.Line != 0 { + if orig.Line != int64(0) { n += 1 + proto.Sov(uint64(orig.Line)) } - if orig.Column != 0 { + if orig.Column != int64(0) { n += 1 + proto.Sov(uint64(orig.Column)) } return n @@ -180,17 +179,17 @@ func (orig *Line) MarshalProto(buf []byte) int { pos := len(buf) var l int _ = l - if orig.FunctionIndex != 0 { + if orig.FunctionIndex != int32(0) { pos = proto.EncodeVarint(buf, pos, uint64(orig.FunctionIndex)) pos-- buf[pos] = 0x8 } - if orig.Line != 0 { + if orig.Line != int64(0) { pos = proto.EncodeVarint(buf, pos, uint64(orig.Line)) pos-- buf[pos] = 0x10 } - if orig.Column != 0 { + if orig.Column != int64(0) { pos = proto.EncodeVarint(buf, pos, uint64(orig.Column)) pos-- buf[pos] = 0x18 @@ -222,7 +221,6 @@ func (orig *Line) UnmarshalProto(buf []byte) error { if err != nil { return err } - orig.FunctionIndex = int32(num) case 2: @@ -234,7 +232,6 @@ func (orig *Line) UnmarshalProto(buf []byte) error { if err != nil { return err } - orig.Line = int64(num) case 3: @@ -246,7 +243,6 @@ func (orig *Line) UnmarshalProto(buf []byte) error { if err != nil { return err } - orig.Column = int64(num) default: pos, err = proto.ConsumeUnknown(buf, pos, wireType) diff --git a/pdata/internal/generated_proto_line_test.go b/pdata/internal/generated_proto_line_test.go index afdae244d2a3..317a797ee540 100644 --- a/pdata/internal/generated_proto_line_test.go +++ b/pdata/internal/generated_proto_line_test.go @@ -17,16 +17,17 @@ import ( "go.opentelemetry.io/collector/featuregate" "go.opentelemetry.io/collector/pdata/internal/json" + "go.opentelemetry.io/collector/pdata/internal/metadata" ) func TestCopyLine(t *testing.T) { for name, src := range genTestEncodingValuesLine() { for _, pooling := range []bool{true, false} { t.Run(name+"/Pooling="+strconv.FormatBool(pooling), func(t *testing.T) { - prevPooling := UseProtoPooling.IsEnabled() - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), pooling)) + prevPooling := metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), pooling)) defer func() { - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), prevPooling)) + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), prevPooling)) }() dest := NewLine() @@ -102,10 +103,10 @@ func TestMarshalAndUnmarshalJSONLine(t *testing.T) { for name, src := range genTestEncodingValuesLine() { for _, pooling := range []bool{true, false} { t.Run(name+"/Pooling="+strconv.FormatBool(pooling), func(t *testing.T) { - prevPooling := UseProtoPooling.IsEnabled() - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), pooling)) + prevPooling := metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), pooling)) defer func() { - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), prevPooling)) + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), prevPooling)) }() stream := json.BorrowStream(nil) @@ -146,10 +147,10 @@ func TestMarshalAndUnmarshalProtoLine(t *testing.T) { for name, src := range genTestEncodingValuesLine() { for _, pooling := range []bool{true, false} { t.Run(name+"/Pooling="+strconv.FormatBool(pooling), func(t *testing.T) { - prevPooling := UseProtoPooling.IsEnabled() - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), pooling)) + prevPooling := metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), pooling)) defer func() { - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), prevPooling)) + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), prevPooling)) }() buf := make([]byte, src.SizeProto()) diff --git a/pdata/internal/generated_proto_link.go b/pdata/internal/generated_proto_link.go index 26962ad2712f..9d62117e8c7f 100644 --- a/pdata/internal/generated_proto_link.go +++ b/pdata/internal/generated_proto_link.go @@ -11,6 +11,7 @@ import ( "sync" "go.opentelemetry.io/collector/pdata/internal/json" + "go.opentelemetry.io/collector/pdata/internal/metadata" "go.opentelemetry.io/collector/pdata/internal/proto" ) @@ -29,7 +30,7 @@ var ( ) func NewLink() *Link { - if !UseProtoPooling.IsEnabled() { + if !metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() { return &Link{} } return protoPoolLink.Get().(*Link) @@ -40,14 +41,12 @@ func DeleteLink(orig *Link, nullable bool) { return } - if !UseProtoPooling.IsEnabled() { + if !metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() { orig.Reset() return } - DeleteTraceID(&orig.TraceId, false) DeleteSpanID(&orig.SpanId, false) - orig.Reset() if nullable { protoPoolLink.Put(orig) diff --git a/pdata/internal/generated_proto_link_test.go b/pdata/internal/generated_proto_link_test.go index 5887e4d12261..ff15e2241e99 100644 --- a/pdata/internal/generated_proto_link_test.go +++ b/pdata/internal/generated_proto_link_test.go @@ -17,16 +17,17 @@ import ( "go.opentelemetry.io/collector/featuregate" "go.opentelemetry.io/collector/pdata/internal/json" + "go.opentelemetry.io/collector/pdata/internal/metadata" ) func TestCopyLink(t *testing.T) { for name, src := range genTestEncodingValuesLink() { for _, pooling := range []bool{true, false} { t.Run(name+"/Pooling="+strconv.FormatBool(pooling), func(t *testing.T) { - prevPooling := UseProtoPooling.IsEnabled() - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), pooling)) + prevPooling := metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), pooling)) defer func() { - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), prevPooling)) + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), prevPooling)) }() dest := NewLink() @@ -102,10 +103,10 @@ func TestMarshalAndUnmarshalJSONLink(t *testing.T) { for name, src := range genTestEncodingValuesLink() { for _, pooling := range []bool{true, false} { t.Run(name+"/Pooling="+strconv.FormatBool(pooling), func(t *testing.T) { - prevPooling := UseProtoPooling.IsEnabled() - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), pooling)) + prevPooling := metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), pooling)) defer func() { - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), prevPooling)) + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), prevPooling)) }() stream := json.BorrowStream(nil) @@ -146,10 +147,10 @@ func TestMarshalAndUnmarshalProtoLink(t *testing.T) { for name, src := range genTestEncodingValuesLink() { for _, pooling := range []bool{true, false} { t.Run(name+"/Pooling="+strconv.FormatBool(pooling), func(t *testing.T) { - prevPooling := UseProtoPooling.IsEnabled() - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), pooling)) + prevPooling := metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), pooling)) defer func() { - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), prevPooling)) + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), prevPooling)) }() buf := make([]byte, src.SizeProto()) diff --git a/pdata/internal/generated_proto_location.go b/pdata/internal/generated_proto_location.go index bceb75561715..c75ed04c9b96 100644 --- a/pdata/internal/generated_proto_location.go +++ b/pdata/internal/generated_proto_location.go @@ -11,15 +11,16 @@ import ( "sync" "go.opentelemetry.io/collector/pdata/internal/json" + "go.opentelemetry.io/collector/pdata/internal/metadata" "go.opentelemetry.io/collector/pdata/internal/proto" ) // Location describes function and line table debug information. type Location struct { - MappingIndex int32 - Address uint64 Lines []*Line AttributeIndices []int32 + Address uint64 + MappingIndex int32 } var ( @@ -31,7 +32,7 @@ var ( ) func NewLocation() *Location { - if !UseProtoPooling.IsEnabled() { + if !metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() { return &Location{} } return protoPoolLocation.Get().(*Location) @@ -42,7 +43,7 @@ func DeleteLocation(orig *Location, nullable bool) { return } - if !UseProtoPooling.IsEnabled() { + if !metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() { orig.Reset() return } @@ -71,9 +72,7 @@ func CopyLocation(dest, src *Location) *Location { dest = NewLocation() } dest.MappingIndex = src.MappingIndex - dest.Address = src.Address - dest.Lines = CopyLinePtrSlice(dest.Lines, src.Lines) dest.AttributeIndices = append(dest.AttributeIndices[:0], src.AttributeIndices...) @@ -164,6 +163,7 @@ func (orig *Location) MarshalJSON(dest *json.Stream) { } dest.WriteArrayEnd() } + dest.WriteObjectEnd() } @@ -196,16 +196,17 @@ func (orig *Location) SizeProto() int { var n int var l int _ = l - if orig.MappingIndex != 0 { + if orig.MappingIndex != int32(0) { n += 1 + proto.Sov(uint64(orig.MappingIndex)) } - if orig.Address != 0 { + if orig.Address != uint64(0) { n += 1 + proto.Sov(uint64(orig.Address)) } for i := range orig.Lines { l = orig.Lines[i].SizeProto() n += 1 + proto.Sov(uint64(l)) + l } + if len(orig.AttributeIndices) > 0 { l = 0 for _, e := range orig.AttributeIndices { @@ -220,12 +221,12 @@ func (orig *Location) MarshalProto(buf []byte) int { pos := len(buf) var l int _ = l - if orig.MappingIndex != 0 { + if orig.MappingIndex != int32(0) { pos = proto.EncodeVarint(buf, pos, uint64(orig.MappingIndex)) pos-- buf[pos] = 0x8 } - if orig.Address != 0 { + if orig.Address != uint64(0) { pos = proto.EncodeVarint(buf, pos, uint64(orig.Address)) pos-- buf[pos] = 0x10 @@ -274,7 +275,6 @@ func (orig *Location) UnmarshalProto(buf []byte) error { if err != nil { return err } - orig.MappingIndex = int32(num) case 2: @@ -286,7 +286,6 @@ func (orig *Location) UnmarshalProto(buf []byte) error { if err != nil { return err } - orig.Address = uint64(num) case 3: diff --git a/pdata/internal/generated_proto_location_test.go b/pdata/internal/generated_proto_location_test.go index 028012855ce6..e28bbe1f315c 100644 --- a/pdata/internal/generated_proto_location_test.go +++ b/pdata/internal/generated_proto_location_test.go @@ -17,16 +17,17 @@ import ( "go.opentelemetry.io/collector/featuregate" "go.opentelemetry.io/collector/pdata/internal/json" + "go.opentelemetry.io/collector/pdata/internal/metadata" ) func TestCopyLocation(t *testing.T) { for name, src := range genTestEncodingValuesLocation() { for _, pooling := range []bool{true, false} { t.Run(name+"/Pooling="+strconv.FormatBool(pooling), func(t *testing.T) { - prevPooling := UseProtoPooling.IsEnabled() - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), pooling)) + prevPooling := metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), pooling)) defer func() { - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), prevPooling)) + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), prevPooling)) }() dest := NewLocation() @@ -102,10 +103,10 @@ func TestMarshalAndUnmarshalJSONLocation(t *testing.T) { for name, src := range genTestEncodingValuesLocation() { for _, pooling := range []bool{true, false} { t.Run(name+"/Pooling="+strconv.FormatBool(pooling), func(t *testing.T) { - prevPooling := UseProtoPooling.IsEnabled() - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), pooling)) + prevPooling := metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), pooling)) defer func() { - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), prevPooling)) + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), prevPooling)) }() stream := json.BorrowStream(nil) @@ -146,10 +147,10 @@ func TestMarshalAndUnmarshalProtoLocation(t *testing.T) { for name, src := range genTestEncodingValuesLocation() { for _, pooling := range []bool{true, false} { t.Run(name+"/Pooling="+strconv.FormatBool(pooling), func(t *testing.T) { - prevPooling := UseProtoPooling.IsEnabled() - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), pooling)) + prevPooling := metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), pooling)) defer func() { - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), prevPooling)) + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), prevPooling)) }() buf := make([]byte, src.SizeProto()) diff --git a/pdata/internal/generated_proto_logrecord.go b/pdata/internal/generated_proto_logrecord.go index 8ef100c1347a..c3e449246c03 100644 --- a/pdata/internal/generated_proto_logrecord.go +++ b/pdata/internal/generated_proto_logrecord.go @@ -12,23 +12,24 @@ import ( "sync" "go.opentelemetry.io/collector/pdata/internal/json" + "go.opentelemetry.io/collector/pdata/internal/metadata" "go.opentelemetry.io/collector/pdata/internal/proto" ) // LogRecord are experimental implementation of OpenTelemetry Log Data Model. type LogRecord struct { + Body AnyValue + SeverityText string + EventName string + Attributes []KeyValue TimeUnixNano uint64 ObservedTimeUnixNano uint64 SeverityNumber SeverityNumber - SeverityText string - Body AnyValue - Attributes []KeyValue DroppedAttributesCount uint32 Flags uint32 TraceId TraceID SpanId SpanID - EventName string } var ( @@ -40,7 +41,7 @@ var ( ) func NewLogRecord() *LogRecord { - if !UseProtoPooling.IsEnabled() { + if !metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() { return &LogRecord{} } return protoPoolLogRecord.Get().(*LogRecord) @@ -51,7 +52,7 @@ func DeleteLogRecord(orig *LogRecord, nullable bool) { return } - if !UseProtoPooling.IsEnabled() { + if !metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() { orig.Reset() return } @@ -60,6 +61,7 @@ func DeleteLogRecord(orig *LogRecord, nullable bool) { for i := range orig.Attributes { DeleteKeyValue(&orig.Attributes[i], false) } + DeleteTraceID(&orig.TraceId, false) DeleteSpanID(&orig.SpanId, false) @@ -83,21 +85,15 @@ func CopyLogRecord(dest, src *LogRecord) *LogRecord { dest = NewLogRecord() } dest.TimeUnixNano = src.TimeUnixNano - dest.ObservedTimeUnixNano = src.ObservedTimeUnixNano - dest.SeverityNumber = src.SeverityNumber - dest.SeverityText = src.SeverityText - CopyAnyValue(&dest.Body, &src.Body) dest.Attributes = CopyKeyValueSlice(dest.Attributes, src.Attributes) dest.DroppedAttributesCount = src.DroppedAttributesCount - dest.Flags = src.Flags - CopyTraceID(&dest.TraceId, &src.TraceId) CopySpanID(&dest.SpanId, &src.SpanId) @@ -257,15 +253,16 @@ func (orig *LogRecord) SizeProto() int { var n int var l int _ = l - if orig.TimeUnixNano != 0 { + if orig.TimeUnixNano != uint64(0) { n += 9 } - if orig.ObservedTimeUnixNano != 0 { + if orig.ObservedTimeUnixNano != uint64(0) { n += 9 } - if orig.SeverityNumber != 0 { + if orig.SeverityNumber != SeverityNumber(0) { n += 1 + proto.Sov(uint64(orig.SeverityNumber)) } + l = len(orig.SeverityText) if l > 0 { n += 1 + proto.Sov(uint64(l)) + l @@ -276,16 +273,17 @@ func (orig *LogRecord) SizeProto() int { l = orig.Attributes[i].SizeProto() n += 1 + proto.Sov(uint64(l)) + l } - if orig.DroppedAttributesCount != 0 { + if orig.DroppedAttributesCount != uint32(0) { n += 1 + proto.Sov(uint64(orig.DroppedAttributesCount)) } - if orig.Flags != 0 { + if orig.Flags != uint32(0) { n += 5 } l = orig.TraceId.SizeProto() n += 1 + proto.Sov(uint64(l)) + l l = orig.SpanId.SizeProto() n += 1 + proto.Sov(uint64(l)) + l + l = len(orig.EventName) if l > 0 { n += 1 + proto.Sov(uint64(l)) + l @@ -297,19 +295,19 @@ func (orig *LogRecord) MarshalProto(buf []byte) int { pos := len(buf) var l int _ = l - if orig.TimeUnixNano != 0 { + if orig.TimeUnixNano != uint64(0) { pos -= 8 binary.LittleEndian.PutUint64(buf[pos:], uint64(orig.TimeUnixNano)) pos-- buf[pos] = 0x9 } - if orig.ObservedTimeUnixNano != 0 { + if orig.ObservedTimeUnixNano != uint64(0) { pos -= 8 binary.LittleEndian.PutUint64(buf[pos:], uint64(orig.ObservedTimeUnixNano)) pos-- buf[pos] = 0x59 } - if orig.SeverityNumber != 0 { + if orig.SeverityNumber != SeverityNumber(0) { pos = proto.EncodeVarint(buf, pos, uint64(orig.SeverityNumber)) pos-- buf[pos] = 0x10 @@ -335,12 +333,12 @@ func (orig *LogRecord) MarshalProto(buf []byte) int { pos-- buf[pos] = 0x32 } - if orig.DroppedAttributesCount != 0 { + if orig.DroppedAttributesCount != uint32(0) { pos = proto.EncodeVarint(buf, pos, uint64(orig.DroppedAttributesCount)) pos-- buf[pos] = 0x38 } - if orig.Flags != 0 { + if orig.Flags != uint32(0) { pos -= 4 binary.LittleEndian.PutUint32(buf[pos:], uint32(orig.Flags)) pos-- @@ -417,7 +415,6 @@ func (orig *LogRecord) UnmarshalProto(buf []byte) error { if err != nil { return err } - orig.SeverityNumber = SeverityNumber(num) case 3: @@ -473,7 +470,6 @@ func (orig *LogRecord) UnmarshalProto(buf []byte) error { if err != nil { return err } - orig.DroppedAttributesCount = uint32(num) case 8: diff --git a/pdata/internal/generated_proto_logrecord_test.go b/pdata/internal/generated_proto_logrecord_test.go index 6f2df992731a..e00ca5a493d8 100644 --- a/pdata/internal/generated_proto_logrecord_test.go +++ b/pdata/internal/generated_proto_logrecord_test.go @@ -17,16 +17,17 @@ import ( "go.opentelemetry.io/collector/featuregate" "go.opentelemetry.io/collector/pdata/internal/json" + "go.opentelemetry.io/collector/pdata/internal/metadata" ) func TestCopyLogRecord(t *testing.T) { for name, src := range genTestEncodingValuesLogRecord() { for _, pooling := range []bool{true, false} { t.Run(name+"/Pooling="+strconv.FormatBool(pooling), func(t *testing.T) { - prevPooling := UseProtoPooling.IsEnabled() - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), pooling)) + prevPooling := metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), pooling)) defer func() { - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), prevPooling)) + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), prevPooling)) }() dest := NewLogRecord() @@ -102,10 +103,10 @@ func TestMarshalAndUnmarshalJSONLogRecord(t *testing.T) { for name, src := range genTestEncodingValuesLogRecord() { for _, pooling := range []bool{true, false} { t.Run(name+"/Pooling="+strconv.FormatBool(pooling), func(t *testing.T) { - prevPooling := UseProtoPooling.IsEnabled() - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), pooling)) + prevPooling := metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), pooling)) defer func() { - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), prevPooling)) + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), prevPooling)) }() stream := json.BorrowStream(nil) @@ -146,10 +147,10 @@ func TestMarshalAndUnmarshalProtoLogRecord(t *testing.T) { for name, src := range genTestEncodingValuesLogRecord() { for _, pooling := range []bool{true, false} { t.Run(name+"/Pooling="+strconv.FormatBool(pooling), func(t *testing.T) { - prevPooling := UseProtoPooling.IsEnabled() - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), pooling)) + prevPooling := metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), pooling)) defer func() { - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), prevPooling)) + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), prevPooling)) }() buf := make([]byte, src.SizeProto()) diff --git a/pdata/internal/generated_proto_logsdata.go b/pdata/internal/generated_proto_logsdata.go index 8b7cf668f93c..7f7f3bfb9b03 100644 --- a/pdata/internal/generated_proto_logsdata.go +++ b/pdata/internal/generated_proto_logsdata.go @@ -11,6 +11,7 @@ import ( "sync" "go.opentelemetry.io/collector/pdata/internal/json" + "go.opentelemetry.io/collector/pdata/internal/metadata" "go.opentelemetry.io/collector/pdata/internal/proto" ) @@ -30,7 +31,7 @@ var ( ) func NewLogsData() *LogsData { - if !UseProtoPooling.IsEnabled() { + if !metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() { return &LogsData{} } return protoPoolLogsData.Get().(*LogsData) @@ -41,15 +42,13 @@ func DeleteLogsData(orig *LogsData, nullable bool) { return } - if !UseProtoPooling.IsEnabled() { + if !metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() { orig.Reset() return } - for i := range orig.ResourceLogs { DeleteResourceLogs(orig.ResourceLogs[i], true) } - orig.Reset() if nullable { protoPoolLogsData.Put(orig) diff --git a/pdata/internal/generated_proto_logsdata_test.go b/pdata/internal/generated_proto_logsdata_test.go index 871778d1c78f..8781382b4322 100644 --- a/pdata/internal/generated_proto_logsdata_test.go +++ b/pdata/internal/generated_proto_logsdata_test.go @@ -17,16 +17,17 @@ import ( "go.opentelemetry.io/collector/featuregate" "go.opentelemetry.io/collector/pdata/internal/json" + "go.opentelemetry.io/collector/pdata/internal/metadata" ) func TestCopyLogsData(t *testing.T) { for name, src := range genTestEncodingValuesLogsData() { for _, pooling := range []bool{true, false} { t.Run(name+"/Pooling="+strconv.FormatBool(pooling), func(t *testing.T) { - prevPooling := UseProtoPooling.IsEnabled() - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), pooling)) + prevPooling := metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), pooling)) defer func() { - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), prevPooling)) + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), prevPooling)) }() dest := NewLogsData() @@ -102,10 +103,10 @@ func TestMarshalAndUnmarshalJSONLogsData(t *testing.T) { for name, src := range genTestEncodingValuesLogsData() { for _, pooling := range []bool{true, false} { t.Run(name+"/Pooling="+strconv.FormatBool(pooling), func(t *testing.T) { - prevPooling := UseProtoPooling.IsEnabled() - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), pooling)) + prevPooling := metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), pooling)) defer func() { - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), prevPooling)) + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), prevPooling)) }() stream := json.BorrowStream(nil) @@ -146,10 +147,10 @@ func TestMarshalAndUnmarshalProtoLogsData(t *testing.T) { for name, src := range genTestEncodingValuesLogsData() { for _, pooling := range []bool{true, false} { t.Run(name+"/Pooling="+strconv.FormatBool(pooling), func(t *testing.T) { - prevPooling := UseProtoPooling.IsEnabled() - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), pooling)) + prevPooling := metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), pooling)) defer func() { - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), prevPooling)) + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), prevPooling)) }() buf := make([]byte, src.SizeProto()) diff --git a/pdata/internal/generated_proto_logsrequest.go b/pdata/internal/generated_proto_logsrequest.go index 60bae8a78944..4e18c30505e3 100644 --- a/pdata/internal/generated_proto_logsrequest.go +++ b/pdata/internal/generated_proto_logsrequest.go @@ -12,6 +12,7 @@ import ( "sync" "go.opentelemetry.io/collector/pdata/internal/json" + "go.opentelemetry.io/collector/pdata/internal/metadata" "go.opentelemetry.io/collector/pdata/internal/proto" ) @@ -30,7 +31,7 @@ var ( ) func NewLogsRequest() *LogsRequest { - if !UseProtoPooling.IsEnabled() { + if !metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() { return &LogsRequest{} } return protoPoolLogsRequest.Get().(*LogsRequest) @@ -41,11 +42,10 @@ func DeleteLogsRequest(orig *LogsRequest, nullable bool) { return } - if !UseProtoPooling.IsEnabled() { + if !metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() { orig.Reset() return } - DeleteRequestContext(orig.RequestContext, true) DeleteLogsData(&orig.LogsData, false) @@ -173,7 +173,7 @@ func (orig *LogsRequest) SizeProto() int { } l = orig.LogsData.SizeProto() n += 1 + proto.Sov(uint64(l)) + l - if orig.FormatVersion != 0 { + if orig.FormatVersion != uint32(0) { n += 5 } return n @@ -196,7 +196,7 @@ func (orig *LogsRequest) MarshalProto(buf []byte) int { pos-- buf[pos] = 0x1a - if orig.FormatVersion != 0 { + if orig.FormatVersion != uint32(0) { pos -= 4 binary.LittleEndian.PutUint32(buf[pos:], uint32(orig.FormatVersion)) pos-- diff --git a/pdata/internal/generated_proto_logsrequest_test.go b/pdata/internal/generated_proto_logsrequest_test.go index 439c33808331..77de4f0cf05d 100644 --- a/pdata/internal/generated_proto_logsrequest_test.go +++ b/pdata/internal/generated_proto_logsrequest_test.go @@ -17,16 +17,17 @@ import ( "go.opentelemetry.io/collector/featuregate" "go.opentelemetry.io/collector/pdata/internal/json" + "go.opentelemetry.io/collector/pdata/internal/metadata" ) func TestCopyLogsRequest(t *testing.T) { for name, src := range genTestEncodingValuesLogsRequest() { for _, pooling := range []bool{true, false} { t.Run(name+"/Pooling="+strconv.FormatBool(pooling), func(t *testing.T) { - prevPooling := UseProtoPooling.IsEnabled() - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), pooling)) + prevPooling := metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), pooling)) defer func() { - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), prevPooling)) + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), prevPooling)) }() dest := NewLogsRequest() @@ -102,10 +103,10 @@ func TestMarshalAndUnmarshalJSONLogsRequest(t *testing.T) { for name, src := range genTestEncodingValuesLogsRequest() { for _, pooling := range []bool{true, false} { t.Run(name+"/Pooling="+strconv.FormatBool(pooling), func(t *testing.T) { - prevPooling := UseProtoPooling.IsEnabled() - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), pooling)) + prevPooling := metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), pooling)) defer func() { - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), prevPooling)) + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), prevPooling)) }() stream := json.BorrowStream(nil) @@ -146,10 +147,10 @@ func TestMarshalAndUnmarshalProtoLogsRequest(t *testing.T) { for name, src := range genTestEncodingValuesLogsRequest() { for _, pooling := range []bool{true, false} { t.Run(name+"/Pooling="+strconv.FormatBool(pooling), func(t *testing.T) { - prevPooling := UseProtoPooling.IsEnabled() - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), pooling)) + prevPooling := metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), pooling)) defer func() { - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), prevPooling)) + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), prevPooling)) }() buf := make([]byte, src.SizeProto()) diff --git a/pdata/internal/generated_proto_mapping.go b/pdata/internal/generated_proto_mapping.go index 41b746247253..ec1462389896 100644 --- a/pdata/internal/generated_proto_mapping.go +++ b/pdata/internal/generated_proto_mapping.go @@ -11,16 +11,17 @@ import ( "sync" "go.opentelemetry.io/collector/pdata/internal/json" + "go.opentelemetry.io/collector/pdata/internal/metadata" "go.opentelemetry.io/collector/pdata/internal/proto" ) // Mapping describes the mapping of a binary in memory, including its address range, file offset, and metadata like build ID type Mapping struct { + AttributeIndices []int32 MemoryStart uint64 MemoryLimit uint64 FileOffset uint64 FilenameStrindex int32 - AttributeIndices []int32 } var ( @@ -32,7 +33,7 @@ var ( ) func NewMapping() *Mapping { - if !UseProtoPooling.IsEnabled() { + if !metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() { return &Mapping{} } return protoPoolMapping.Get().(*Mapping) @@ -43,7 +44,7 @@ func DeleteMapping(orig *Mapping, nullable bool) { return } - if !UseProtoPooling.IsEnabled() { + if !metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() { orig.Reset() return } @@ -68,13 +69,9 @@ func CopyMapping(dest, src *Mapping) *Mapping { dest = NewMapping() } dest.MemoryStart = src.MemoryStart - dest.MemoryLimit = src.MemoryLimit - dest.FileOffset = src.FileOffset - dest.FilenameStrindex = src.FilenameStrindex - dest.AttributeIndices = append(dest.AttributeIndices[:0], src.AttributeIndices...) return dest @@ -161,6 +158,7 @@ func (orig *Mapping) MarshalJSON(dest *json.Stream) { } dest.WriteArrayEnd() } + dest.WriteObjectEnd() } @@ -191,18 +189,19 @@ func (orig *Mapping) SizeProto() int { var n int var l int _ = l - if orig.MemoryStart != 0 { + if orig.MemoryStart != uint64(0) { n += 1 + proto.Sov(uint64(orig.MemoryStart)) } - if orig.MemoryLimit != 0 { + if orig.MemoryLimit != uint64(0) { n += 1 + proto.Sov(uint64(orig.MemoryLimit)) } - if orig.FileOffset != 0 { + if orig.FileOffset != uint64(0) { n += 1 + proto.Sov(uint64(orig.FileOffset)) } - if orig.FilenameStrindex != 0 { + if orig.FilenameStrindex != int32(0) { n += 1 + proto.Sov(uint64(orig.FilenameStrindex)) } + if len(orig.AttributeIndices) > 0 { l = 0 for _, e := range orig.AttributeIndices { @@ -217,22 +216,22 @@ func (orig *Mapping) MarshalProto(buf []byte) int { pos := len(buf) var l int _ = l - if orig.MemoryStart != 0 { + if orig.MemoryStart != uint64(0) { pos = proto.EncodeVarint(buf, pos, uint64(orig.MemoryStart)) pos-- buf[pos] = 0x8 } - if orig.MemoryLimit != 0 { + if orig.MemoryLimit != uint64(0) { pos = proto.EncodeVarint(buf, pos, uint64(orig.MemoryLimit)) pos-- buf[pos] = 0x10 } - if orig.FileOffset != 0 { + if orig.FileOffset != uint64(0) { pos = proto.EncodeVarint(buf, pos, uint64(orig.FileOffset)) pos-- buf[pos] = 0x18 } - if orig.FilenameStrindex != 0 { + if orig.FilenameStrindex != int32(0) { pos = proto.EncodeVarint(buf, pos, uint64(orig.FilenameStrindex)) pos-- buf[pos] = 0x20 @@ -274,7 +273,6 @@ func (orig *Mapping) UnmarshalProto(buf []byte) error { if err != nil { return err } - orig.MemoryStart = uint64(num) case 2: @@ -286,7 +284,6 @@ func (orig *Mapping) UnmarshalProto(buf []byte) error { if err != nil { return err } - orig.MemoryLimit = uint64(num) case 3: @@ -298,7 +295,6 @@ func (orig *Mapping) UnmarshalProto(buf []byte) error { if err != nil { return err } - orig.FileOffset = uint64(num) case 4: @@ -310,7 +306,6 @@ func (orig *Mapping) UnmarshalProto(buf []byte) error { if err != nil { return err } - orig.FilenameStrindex = int32(num) case 5: switch wireType { diff --git a/pdata/internal/generated_proto_mapping_test.go b/pdata/internal/generated_proto_mapping_test.go index a539f0b74cf4..22296f3c820a 100644 --- a/pdata/internal/generated_proto_mapping_test.go +++ b/pdata/internal/generated_proto_mapping_test.go @@ -17,16 +17,17 @@ import ( "go.opentelemetry.io/collector/featuregate" "go.opentelemetry.io/collector/pdata/internal/json" + "go.opentelemetry.io/collector/pdata/internal/metadata" ) func TestCopyMapping(t *testing.T) { for name, src := range genTestEncodingValuesMapping() { for _, pooling := range []bool{true, false} { t.Run(name+"/Pooling="+strconv.FormatBool(pooling), func(t *testing.T) { - prevPooling := UseProtoPooling.IsEnabled() - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), pooling)) + prevPooling := metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), pooling)) defer func() { - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), prevPooling)) + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), prevPooling)) }() dest := NewMapping() @@ -102,10 +103,10 @@ func TestMarshalAndUnmarshalJSONMapping(t *testing.T) { for name, src := range genTestEncodingValuesMapping() { for _, pooling := range []bool{true, false} { t.Run(name+"/Pooling="+strconv.FormatBool(pooling), func(t *testing.T) { - prevPooling := UseProtoPooling.IsEnabled() - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), pooling)) + prevPooling := metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), pooling)) defer func() { - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), prevPooling)) + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), prevPooling)) }() stream := json.BorrowStream(nil) @@ -146,10 +147,10 @@ func TestMarshalAndUnmarshalProtoMapping(t *testing.T) { for name, src := range genTestEncodingValuesMapping() { for _, pooling := range []bool{true, false} { t.Run(name+"/Pooling="+strconv.FormatBool(pooling), func(t *testing.T) { - prevPooling := UseProtoPooling.IsEnabled() - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), pooling)) + prevPooling := metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), pooling)) defer func() { - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), prevPooling)) + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), prevPooling)) }() buf := make([]byte, src.SizeProto()) diff --git a/pdata/internal/generated_proto_metric.go b/pdata/internal/generated_proto_metric.go index b7f85b27a035..b7c1587b926f 100644 --- a/pdata/internal/generated_proto_metric.go +++ b/pdata/internal/generated_proto_metric.go @@ -11,6 +11,7 @@ import ( "sync" "go.opentelemetry.io/collector/pdata/internal/json" + "go.opentelemetry.io/collector/pdata/internal/metadata" "go.opentelemetry.io/collector/pdata/internal/proto" ) @@ -125,7 +126,7 @@ var ( ) func NewMetric() *Metric { - if !UseProtoPooling.IsEnabled() { + if !metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() { return &Metric{} } return protoPoolMetric.Get().(*Metric) @@ -136,7 +137,7 @@ func DeleteMetric(orig *Metric, nullable bool) { return } - if !UseProtoPooling.IsEnabled() { + if !metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() { orig.Reset() return } @@ -162,12 +163,10 @@ func DeleteMetric(orig *Metric, nullable bool) { DeleteSummary(ov.Summary, true) ov.Summary = nil ProtoPoolMetric_Summary.Put(ov) - } for i := range orig.Metadata { DeleteKeyValue(&orig.Metadata[i], false) } - orig.Reset() if nullable { protoPoolMetric.Put(orig) @@ -188,15 +187,12 @@ func CopyMetric(dest, src *Metric) *Metric { dest = NewMetric() } dest.Name = src.Name - dest.Description = src.Description - dest.Unit = src.Unit - switch t := src.Data.(type) { case *Metric_Gauge: var ov *Metric_Gauge - if !UseProtoPooling.IsEnabled() { + if !metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() { ov = &Metric_Gauge{} } else { ov = ProtoPoolMetric_Gauge.Get().(*Metric_Gauge) @@ -207,7 +203,7 @@ func CopyMetric(dest, src *Metric) *Metric { case *Metric_Sum: var ov *Metric_Sum - if !UseProtoPooling.IsEnabled() { + if !metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() { ov = &Metric_Sum{} } else { ov = ProtoPoolMetric_Sum.Get().(*Metric_Sum) @@ -218,7 +214,7 @@ func CopyMetric(dest, src *Metric) *Metric { case *Metric_Histogram: var ov *Metric_Histogram - if !UseProtoPooling.IsEnabled() { + if !metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() { ov = &Metric_Histogram{} } else { ov = ProtoPoolMetric_Histogram.Get().(*Metric_Histogram) @@ -229,7 +225,7 @@ func CopyMetric(dest, src *Metric) *Metric { case *Metric_ExponentialHistogram: var ov *Metric_ExponentialHistogram - if !UseProtoPooling.IsEnabled() { + if !metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() { ov = &Metric_ExponentialHistogram{} } else { ov = ProtoPoolMetric_ExponentialHistogram.Get().(*Metric_ExponentialHistogram) @@ -240,7 +236,7 @@ func CopyMetric(dest, src *Metric) *Metric { case *Metric_Summary: var ov *Metric_Summary - if !UseProtoPooling.IsEnabled() { + if !metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() { ov = &Metric_Summary{} } else { ov = ProtoPoolMetric_Summary.Get().(*Metric_Summary) @@ -378,7 +374,7 @@ func (orig *Metric) UnmarshalJSON(iter *json.Iterator) { case "gauge": { var ov *Metric_Gauge - if !UseProtoPooling.IsEnabled() { + if !metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() { ov = &Metric_Gauge{} } else { ov = ProtoPoolMetric_Gauge.Get().(*Metric_Gauge) @@ -387,11 +383,10 @@ func (orig *Metric) UnmarshalJSON(iter *json.Iterator) { ov.Gauge.UnmarshalJSON(iter) orig.Data = ov } - case "sum": { var ov *Metric_Sum - if !UseProtoPooling.IsEnabled() { + if !metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() { ov = &Metric_Sum{} } else { ov = ProtoPoolMetric_Sum.Get().(*Metric_Sum) @@ -400,11 +395,10 @@ func (orig *Metric) UnmarshalJSON(iter *json.Iterator) { ov.Sum.UnmarshalJSON(iter) orig.Data = ov } - case "histogram": { var ov *Metric_Histogram - if !UseProtoPooling.IsEnabled() { + if !metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() { ov = &Metric_Histogram{} } else { ov = ProtoPoolMetric_Histogram.Get().(*Metric_Histogram) @@ -413,11 +407,10 @@ func (orig *Metric) UnmarshalJSON(iter *json.Iterator) { ov.Histogram.UnmarshalJSON(iter) orig.Data = ov } - case "exponentialHistogram", "exponential_histogram": { var ov *Metric_ExponentialHistogram - if !UseProtoPooling.IsEnabled() { + if !metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() { ov = &Metric_ExponentialHistogram{} } else { ov = ProtoPoolMetric_ExponentialHistogram.Get().(*Metric_ExponentialHistogram) @@ -426,11 +419,10 @@ func (orig *Metric) UnmarshalJSON(iter *json.Iterator) { ov.ExponentialHistogram.UnmarshalJSON(iter) orig.Data = ov } - case "summary": { var ov *Metric_Summary - if !UseProtoPooling.IsEnabled() { + if !metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() { ov = &Metric_Summary{} } else { ov = ProtoPoolMetric_Summary.Get().(*Metric_Summary) @@ -456,14 +448,17 @@ func (orig *Metric) SizeProto() int { var n int var l int _ = l + l = len(orig.Name) if l > 0 { n += 1 + proto.Sov(uint64(l)) + l } + l = len(orig.Description) if l > 0 { n += 1 + proto.Sov(uint64(l)) + l } + l = len(orig.Unit) if l > 0 { n += 1 + proto.Sov(uint64(l)) + l @@ -647,7 +642,7 @@ func (orig *Metric) UnmarshalProto(buf []byte) error { } startPos := pos - length var ov *Metric_Gauge - if !UseProtoPooling.IsEnabled() { + if !metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() { ov = &Metric_Gauge{} } else { ov = ProtoPoolMetric_Gauge.Get().(*Metric_Gauge) @@ -670,7 +665,7 @@ func (orig *Metric) UnmarshalProto(buf []byte) error { } startPos := pos - length var ov *Metric_Sum - if !UseProtoPooling.IsEnabled() { + if !metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() { ov = &Metric_Sum{} } else { ov = ProtoPoolMetric_Sum.Get().(*Metric_Sum) @@ -693,7 +688,7 @@ func (orig *Metric) UnmarshalProto(buf []byte) error { } startPos := pos - length var ov *Metric_Histogram - if !UseProtoPooling.IsEnabled() { + if !metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() { ov = &Metric_Histogram{} } else { ov = ProtoPoolMetric_Histogram.Get().(*Metric_Histogram) @@ -716,7 +711,7 @@ func (orig *Metric) UnmarshalProto(buf []byte) error { } startPos := pos - length var ov *Metric_ExponentialHistogram - if !UseProtoPooling.IsEnabled() { + if !metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() { ov = &Metric_ExponentialHistogram{} } else { ov = ProtoPoolMetric_ExponentialHistogram.Get().(*Metric_ExponentialHistogram) @@ -739,7 +734,7 @@ func (orig *Metric) UnmarshalProto(buf []byte) error { } startPos := pos - length var ov *Metric_Summary - if !UseProtoPooling.IsEnabled() { + if !metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() { ov = &Metric_Summary{} } else { ov = ProtoPoolMetric_Summary.Get().(*Metric_Summary) diff --git a/pdata/internal/generated_proto_metric_test.go b/pdata/internal/generated_proto_metric_test.go index e538a3c98854..738079eac8ad 100644 --- a/pdata/internal/generated_proto_metric_test.go +++ b/pdata/internal/generated_proto_metric_test.go @@ -17,16 +17,17 @@ import ( "go.opentelemetry.io/collector/featuregate" "go.opentelemetry.io/collector/pdata/internal/json" + "go.opentelemetry.io/collector/pdata/internal/metadata" ) func TestCopyMetric(t *testing.T) { for name, src := range genTestEncodingValuesMetric() { for _, pooling := range []bool{true, false} { t.Run(name+"/Pooling="+strconv.FormatBool(pooling), func(t *testing.T) { - prevPooling := UseProtoPooling.IsEnabled() - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), pooling)) + prevPooling := metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), pooling)) defer func() { - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), prevPooling)) + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), prevPooling)) }() dest := NewMetric() @@ -102,10 +103,10 @@ func TestMarshalAndUnmarshalJSONMetric(t *testing.T) { for name, src := range genTestEncodingValuesMetric() { for _, pooling := range []bool{true, false} { t.Run(name+"/Pooling="+strconv.FormatBool(pooling), func(t *testing.T) { - prevPooling := UseProtoPooling.IsEnabled() - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), pooling)) + prevPooling := metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), pooling)) defer func() { - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), prevPooling)) + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), prevPooling)) }() stream := json.BorrowStream(nil) @@ -146,10 +147,10 @@ func TestMarshalAndUnmarshalProtoMetric(t *testing.T) { for name, src := range genTestEncodingValuesMetric() { for _, pooling := range []bool{true, false} { t.Run(name+"/Pooling="+strconv.FormatBool(pooling), func(t *testing.T) { - prevPooling := UseProtoPooling.IsEnabled() - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), pooling)) + prevPooling := metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), pooling)) defer func() { - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), prevPooling)) + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), prevPooling)) }() buf := make([]byte, src.SizeProto()) @@ -196,41 +197,33 @@ func genTestFailingUnmarshalProtoValuesMetric() map[string][]byte { "Unit/wrong_wire_type": {0x1c}, "Unit/missing_value": {0x1a}, - "Gauge/wrong_wire_type": {0x2c}, - "Gauge/missing_value": {0x2a}, - - "Sum/wrong_wire_type": {0x3c}, - "Sum/missing_value": {0x3a}, - - "Histogram/wrong_wire_type": {0x4c}, - "Histogram/missing_value": {0x4a}, - + "Gauge/wrong_wire_type": {0x2c}, + "Gauge/missing_value": {0x2a}, + "Sum/wrong_wire_type": {0x3c}, + "Sum/missing_value": {0x3a}, + "Histogram/wrong_wire_type": {0x4c}, + "Histogram/missing_value": {0x4a}, "ExponentialHistogram/wrong_wire_type": {0x54}, "ExponentialHistogram/missing_value": {0x52}, - - "Summary/wrong_wire_type": {0x5c}, - "Summary/missing_value": {0x5a}, - "Metadata/wrong_wire_type": {0x64}, - "Metadata/missing_value": {0x62}, + "Summary/wrong_wire_type": {0x5c}, + "Summary/missing_value": {0x5a}, + "Metadata/wrong_wire_type": {0x64}, + "Metadata/missing_value": {0x62}, } } func genTestEncodingValuesMetric() map[string]*Metric { return map[string]*Metric{ - "empty": NewMetric(), - "Name/test": {Name: "test_name"}, - "Description/test": {Description: "test_description"}, - "Unit/test": {Unit: "test_unit"}, - "Gauge/default": {Data: &Metric_Gauge{Gauge: &Gauge{}}}, - "Gauge/test": {Data: &Metric_Gauge{Gauge: GenTestGauge()}}, - "Sum/default": {Data: &Metric_Sum{Sum: &Sum{}}}, - "Sum/test": {Data: &Metric_Sum{Sum: GenTestSum()}}, - "Histogram/default": {Data: &Metric_Histogram{Histogram: &Histogram{}}}, - "Histogram/test": {Data: &Metric_Histogram{Histogram: GenTestHistogram()}}, - "ExponentialHistogram/default": {Data: &Metric_ExponentialHistogram{ExponentialHistogram: &ExponentialHistogram{}}}, - "ExponentialHistogram/test": {Data: &Metric_ExponentialHistogram{ExponentialHistogram: GenTestExponentialHistogram()}}, - "Summary/default": {Data: &Metric_Summary{Summary: &Summary{}}}, - "Summary/test": {Data: &Metric_Summary{Summary: GenTestSummary()}}, - "Metadata/test": {Metadata: []KeyValue{{}, *GenTestKeyValue()}}, + "empty": NewMetric(), + "Name/test": {Name: "test_name"}, + "Description/test": {Description: "test_description"}, + "Unit/test": {Unit: "test_unit"}, + "Gauge/default": {Data: &Metric_Gauge{Gauge: &Gauge{}}}, + "Gauge/test": {Data: &Metric_Gauge{Gauge: GenTestGauge()}}, "Sum/default": {Data: &Metric_Sum{Sum: &Sum{}}}, + "Sum/test": {Data: &Metric_Sum{Sum: GenTestSum()}}, "Histogram/default": {Data: &Metric_Histogram{Histogram: &Histogram{}}}, + "Histogram/test": {Data: &Metric_Histogram{Histogram: GenTestHistogram()}}, "ExponentialHistogram/default": {Data: &Metric_ExponentialHistogram{ExponentialHistogram: &ExponentialHistogram{}}}, + "ExponentialHistogram/test": {Data: &Metric_ExponentialHistogram{ExponentialHistogram: GenTestExponentialHistogram()}}, "Summary/default": {Data: &Metric_Summary{Summary: &Summary{}}}, + "Summary/test": {Data: &Metric_Summary{Summary: GenTestSummary()}}, + "Metadata/test": {Metadata: []KeyValue{{}, *GenTestKeyValue()}}, } } diff --git a/pdata/internal/generated_proto_metricsdata.go b/pdata/internal/generated_proto_metricsdata.go index ad560d67b4b8..48248dc45d06 100644 --- a/pdata/internal/generated_proto_metricsdata.go +++ b/pdata/internal/generated_proto_metricsdata.go @@ -11,6 +11,7 @@ import ( "sync" "go.opentelemetry.io/collector/pdata/internal/json" + "go.opentelemetry.io/collector/pdata/internal/metadata" "go.opentelemetry.io/collector/pdata/internal/proto" ) @@ -30,7 +31,7 @@ var ( ) func NewMetricsData() *MetricsData { - if !UseProtoPooling.IsEnabled() { + if !metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() { return &MetricsData{} } return protoPoolMetricsData.Get().(*MetricsData) @@ -41,15 +42,13 @@ func DeleteMetricsData(orig *MetricsData, nullable bool) { return } - if !UseProtoPooling.IsEnabled() { + if !metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() { orig.Reset() return } - for i := range orig.ResourceMetrics { DeleteResourceMetrics(orig.ResourceMetrics[i], true) } - orig.Reset() if nullable { protoPoolMetricsData.Put(orig) diff --git a/pdata/internal/generated_proto_metricsdata_test.go b/pdata/internal/generated_proto_metricsdata_test.go index 4d310ba85c35..c4bb5a525e1c 100644 --- a/pdata/internal/generated_proto_metricsdata_test.go +++ b/pdata/internal/generated_proto_metricsdata_test.go @@ -17,16 +17,17 @@ import ( "go.opentelemetry.io/collector/featuregate" "go.opentelemetry.io/collector/pdata/internal/json" + "go.opentelemetry.io/collector/pdata/internal/metadata" ) func TestCopyMetricsData(t *testing.T) { for name, src := range genTestEncodingValuesMetricsData() { for _, pooling := range []bool{true, false} { t.Run(name+"/Pooling="+strconv.FormatBool(pooling), func(t *testing.T) { - prevPooling := UseProtoPooling.IsEnabled() - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), pooling)) + prevPooling := metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), pooling)) defer func() { - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), prevPooling)) + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), prevPooling)) }() dest := NewMetricsData() @@ -102,10 +103,10 @@ func TestMarshalAndUnmarshalJSONMetricsData(t *testing.T) { for name, src := range genTestEncodingValuesMetricsData() { for _, pooling := range []bool{true, false} { t.Run(name+"/Pooling="+strconv.FormatBool(pooling), func(t *testing.T) { - prevPooling := UseProtoPooling.IsEnabled() - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), pooling)) + prevPooling := metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), pooling)) defer func() { - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), prevPooling)) + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), prevPooling)) }() stream := json.BorrowStream(nil) @@ -146,10 +147,10 @@ func TestMarshalAndUnmarshalProtoMetricsData(t *testing.T) { for name, src := range genTestEncodingValuesMetricsData() { for _, pooling := range []bool{true, false} { t.Run(name+"/Pooling="+strconv.FormatBool(pooling), func(t *testing.T) { - prevPooling := UseProtoPooling.IsEnabled() - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), pooling)) + prevPooling := metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), pooling)) defer func() { - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), prevPooling)) + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), prevPooling)) }() buf := make([]byte, src.SizeProto()) diff --git a/pdata/internal/generated_proto_metricsrequest.go b/pdata/internal/generated_proto_metricsrequest.go index e4cb0b38f17b..da51b989d251 100644 --- a/pdata/internal/generated_proto_metricsrequest.go +++ b/pdata/internal/generated_proto_metricsrequest.go @@ -12,6 +12,7 @@ import ( "sync" "go.opentelemetry.io/collector/pdata/internal/json" + "go.opentelemetry.io/collector/pdata/internal/metadata" "go.opentelemetry.io/collector/pdata/internal/proto" ) @@ -30,7 +31,7 @@ var ( ) func NewMetricsRequest() *MetricsRequest { - if !UseProtoPooling.IsEnabled() { + if !metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() { return &MetricsRequest{} } return protoPoolMetricsRequest.Get().(*MetricsRequest) @@ -41,11 +42,10 @@ func DeleteMetricsRequest(orig *MetricsRequest, nullable bool) { return } - if !UseProtoPooling.IsEnabled() { + if !metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() { orig.Reset() return } - DeleteRequestContext(orig.RequestContext, true) DeleteMetricsData(&orig.MetricsData, false) @@ -173,7 +173,7 @@ func (orig *MetricsRequest) SizeProto() int { } l = orig.MetricsData.SizeProto() n += 1 + proto.Sov(uint64(l)) + l - if orig.FormatVersion != 0 { + if orig.FormatVersion != uint32(0) { n += 5 } return n @@ -196,7 +196,7 @@ func (orig *MetricsRequest) MarshalProto(buf []byte) int { pos-- buf[pos] = 0x1a - if orig.FormatVersion != 0 { + if orig.FormatVersion != uint32(0) { pos -= 4 binary.LittleEndian.PutUint32(buf[pos:], uint32(orig.FormatVersion)) pos-- diff --git a/pdata/internal/generated_proto_metricsrequest_test.go b/pdata/internal/generated_proto_metricsrequest_test.go index 82dca21a1036..d0a1226a0e21 100644 --- a/pdata/internal/generated_proto_metricsrequest_test.go +++ b/pdata/internal/generated_proto_metricsrequest_test.go @@ -17,16 +17,17 @@ import ( "go.opentelemetry.io/collector/featuregate" "go.opentelemetry.io/collector/pdata/internal/json" + "go.opentelemetry.io/collector/pdata/internal/metadata" ) func TestCopyMetricsRequest(t *testing.T) { for name, src := range genTestEncodingValuesMetricsRequest() { for _, pooling := range []bool{true, false} { t.Run(name+"/Pooling="+strconv.FormatBool(pooling), func(t *testing.T) { - prevPooling := UseProtoPooling.IsEnabled() - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), pooling)) + prevPooling := metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), pooling)) defer func() { - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), prevPooling)) + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), prevPooling)) }() dest := NewMetricsRequest() @@ -102,10 +103,10 @@ func TestMarshalAndUnmarshalJSONMetricsRequest(t *testing.T) { for name, src := range genTestEncodingValuesMetricsRequest() { for _, pooling := range []bool{true, false} { t.Run(name+"/Pooling="+strconv.FormatBool(pooling), func(t *testing.T) { - prevPooling := UseProtoPooling.IsEnabled() - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), pooling)) + prevPooling := metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), pooling)) defer func() { - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), prevPooling)) + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), prevPooling)) }() stream := json.BorrowStream(nil) @@ -146,10 +147,10 @@ func TestMarshalAndUnmarshalProtoMetricsRequest(t *testing.T) { for name, src := range genTestEncodingValuesMetricsRequest() { for _, pooling := range []bool{true, false} { t.Run(name+"/Pooling="+strconv.FormatBool(pooling), func(t *testing.T) { - prevPooling := UseProtoPooling.IsEnabled() - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), pooling)) + prevPooling := metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), pooling)) defer func() { - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), prevPooling)) + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), prevPooling)) }() buf := make([]byte, src.SizeProto()) diff --git a/pdata/internal/generated_proto_numberdatapoint.go b/pdata/internal/generated_proto_numberdatapoint.go index 4b86a7f3a1bf..99f5f766189f 100644 --- a/pdata/internal/generated_proto_numberdatapoint.go +++ b/pdata/internal/generated_proto_numberdatapoint.go @@ -13,6 +13,7 @@ import ( "sync" "go.opentelemetry.io/collector/pdata/internal/json" + "go.opentelemetry.io/collector/pdata/internal/metadata" "go.opentelemetry.io/collector/pdata/internal/proto" ) @@ -47,11 +48,11 @@ func (m *NumberDataPoint) GetAsInt() int64 { // NumberDataPoint is a single data point in a timeseries that describes the time-varying value of a number metric. type NumberDataPoint struct { + Value any Attributes []KeyValue + Exemplars []Exemplar StartTimeUnixNano uint64 TimeUnixNano uint64 - Value any - Exemplars []Exemplar Flags uint32 } @@ -76,7 +77,7 @@ var ( ) func NewNumberDataPoint() *NumberDataPoint { - if !UseProtoPooling.IsEnabled() { + if !metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() { return &NumberDataPoint{} } return protoPoolNumberDataPoint.Get().(*NumberDataPoint) @@ -87,26 +88,25 @@ func DeleteNumberDataPoint(orig *NumberDataPoint, nullable bool) { return } - if !UseProtoPooling.IsEnabled() { + if !metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() { orig.Reset() return } - for i := range orig.Attributes { DeleteKeyValue(&orig.Attributes[i], false) } + switch ov := orig.Value.(type) { case *NumberDataPoint_AsDouble: - if UseProtoPooling.IsEnabled() { + if metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() { ov.AsDouble = float64(0) ProtoPoolNumberDataPoint_AsDouble.Put(ov) } case *NumberDataPoint_AsInt: - if UseProtoPooling.IsEnabled() { + if metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() { ov.AsInt = int64(0) ProtoPoolNumberDataPoint_AsInt.Put(ov) } - } for i := range orig.Exemplars { DeleteExemplar(&orig.Exemplars[i], false) @@ -134,28 +134,28 @@ func CopyNumberDataPoint(dest, src *NumberDataPoint) *NumberDataPoint { dest.Attributes = CopyKeyValueSlice(dest.Attributes, src.Attributes) dest.StartTimeUnixNano = src.StartTimeUnixNano - dest.TimeUnixNano = src.TimeUnixNano - switch t := src.Value.(type) { case *NumberDataPoint_AsDouble: var ov *NumberDataPoint_AsDouble - if !UseProtoPooling.IsEnabled() { + if !metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() { ov = &NumberDataPoint_AsDouble{} } else { ov = ProtoPoolNumberDataPoint_AsDouble.Get().(*NumberDataPoint_AsDouble) } ov.AsDouble = t.AsDouble dest.Value = ov + case *NumberDataPoint_AsInt: var ov *NumberDataPoint_AsInt - if !UseProtoPooling.IsEnabled() { + if !metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() { ov = &NumberDataPoint_AsInt{} } else { ov = ProtoPoolNumberDataPoint_AsInt.Get().(*NumberDataPoint_AsInt) } ov.AsInt = t.AsInt dest.Value = ov + default: dest.Value = nil } @@ -282,7 +282,7 @@ func (orig *NumberDataPoint) UnmarshalJSON(iter *json.Iterator) { case "asDouble", "as_double": { var ov *NumberDataPoint_AsDouble - if !UseProtoPooling.IsEnabled() { + if !metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() { ov = &NumberDataPoint_AsDouble{} } else { ov = ProtoPoolNumberDataPoint_AsDouble.Get().(*NumberDataPoint_AsDouble) @@ -290,11 +290,10 @@ func (orig *NumberDataPoint) UnmarshalJSON(iter *json.Iterator) { ov.AsDouble = iter.ReadFloat64() orig.Value = ov } - case "asInt", "as_int": { var ov *NumberDataPoint_AsInt - if !UseProtoPooling.IsEnabled() { + if !metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() { ov = &NumberDataPoint_AsInt{} } else { ov = ProtoPoolNumberDataPoint_AsInt.Get().(*NumberDataPoint_AsInt) @@ -325,10 +324,10 @@ func (orig *NumberDataPoint) SizeProto() int { l = orig.Attributes[i].SizeProto() n += 1 + proto.Sov(uint64(l)) + l } - if orig.StartTimeUnixNano != 0 { + if orig.StartTimeUnixNano != uint64(0) { n += 9 } - if orig.TimeUnixNano != 0 { + if orig.TimeUnixNano != uint64(0) { n += 9 } switch orig := orig.Value.(type) { @@ -336,15 +335,17 @@ func (orig *NumberDataPoint) SizeProto() int { _ = orig break case *NumberDataPoint_AsDouble: + n += 9 case *NumberDataPoint_AsInt: + n += 9 } for i := range orig.Exemplars { l = orig.Exemplars[i].SizeProto() n += 1 + proto.Sov(uint64(l)) + l } - if orig.Flags != 0 { + if orig.Flags != uint32(0) { n += 1 + proto.Sov(uint64(orig.Flags)) } return n @@ -361,13 +362,13 @@ func (orig *NumberDataPoint) MarshalProto(buf []byte) int { pos-- buf[pos] = 0x3a } - if orig.StartTimeUnixNano != 0 { + if orig.StartTimeUnixNano != uint64(0) { pos -= 8 binary.LittleEndian.PutUint64(buf[pos:], uint64(orig.StartTimeUnixNano)) pos-- buf[pos] = 0x11 } - if orig.TimeUnixNano != 0 { + if orig.TimeUnixNano != uint64(0) { pos -= 8 binary.LittleEndian.PutUint64(buf[pos:], uint64(orig.TimeUnixNano)) pos-- @@ -394,7 +395,7 @@ func (orig *NumberDataPoint) MarshalProto(buf []byte) int { pos-- buf[pos] = 0x2a } - if orig.Flags != 0 { + if orig.Flags != uint32(0) { pos = proto.EncodeVarint(buf, pos, uint64(orig.Flags)) pos-- buf[pos] = 0x40 @@ -467,7 +468,7 @@ func (orig *NumberDataPoint) UnmarshalProto(buf []byte) error { return err } var ov *NumberDataPoint_AsDouble - if !UseProtoPooling.IsEnabled() { + if !metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() { ov = &NumberDataPoint_AsDouble{} } else { ov = ProtoPoolNumberDataPoint_AsDouble.Get().(*NumberDataPoint_AsDouble) @@ -485,7 +486,7 @@ func (orig *NumberDataPoint) UnmarshalProto(buf []byte) error { return err } var ov *NumberDataPoint_AsInt - if !UseProtoPooling.IsEnabled() { + if !metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() { ov = &NumberDataPoint_AsInt{} } else { ov = ProtoPoolNumberDataPoint_AsInt.Get().(*NumberDataPoint_AsInt) @@ -518,7 +519,6 @@ func (orig *NumberDataPoint) UnmarshalProto(buf []byte) error { if err != nil { return err } - orig.Flags = uint32(num) default: pos, err = proto.ConsumeUnknown(buf, pos, wireType) diff --git a/pdata/internal/generated_proto_numberdatapoint_test.go b/pdata/internal/generated_proto_numberdatapoint_test.go index 5c94d8fca728..8b1b3d1ea7a4 100644 --- a/pdata/internal/generated_proto_numberdatapoint_test.go +++ b/pdata/internal/generated_proto_numberdatapoint_test.go @@ -17,16 +17,17 @@ import ( "go.opentelemetry.io/collector/featuregate" "go.opentelemetry.io/collector/pdata/internal/json" + "go.opentelemetry.io/collector/pdata/internal/metadata" ) func TestCopyNumberDataPoint(t *testing.T) { for name, src := range genTestEncodingValuesNumberDataPoint() { for _, pooling := range []bool{true, false} { t.Run(name+"/Pooling="+strconv.FormatBool(pooling), func(t *testing.T) { - prevPooling := UseProtoPooling.IsEnabled() - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), pooling)) + prevPooling := metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), pooling)) defer func() { - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), prevPooling)) + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), prevPooling)) }() dest := NewNumberDataPoint() @@ -102,10 +103,10 @@ func TestMarshalAndUnmarshalJSONNumberDataPoint(t *testing.T) { for name, src := range genTestEncodingValuesNumberDataPoint() { for _, pooling := range []bool{true, false} { t.Run(name+"/Pooling="+strconv.FormatBool(pooling), func(t *testing.T) { - prevPooling := UseProtoPooling.IsEnabled() - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), pooling)) + prevPooling := metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), pooling)) defer func() { - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), prevPooling)) + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), prevPooling)) }() stream := json.BorrowStream(nil) @@ -146,10 +147,10 @@ func TestMarshalAndUnmarshalProtoNumberDataPoint(t *testing.T) { for name, src := range genTestEncodingValuesNumberDataPoint() { for _, pooling := range []bool{true, false} { t.Run(name+"/Pooling="+strconv.FormatBool(pooling), func(t *testing.T) { - prevPooling := UseProtoPooling.IsEnabled() - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), pooling)) + prevPooling := metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), pooling)) defer func() { - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), prevPooling)) + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), prevPooling)) }() buf := make([]byte, src.SizeProto()) @@ -196,9 +197,8 @@ func genTestFailingUnmarshalProtoValuesNumberDataPoint() map[string][]byte { "TimeUnixNano/wrong_wire_type": {0x1c}, "TimeUnixNano/missing_value": {0x19}, - "AsDouble/wrong_wire_type": {0x24}, - "AsDouble/missing_value": {0x21}, - + "AsDouble/wrong_wire_type": {0x24}, + "AsDouble/missing_value": {0x21}, "AsInt/wrong_wire_type": {0x34}, "AsInt/missing_value": {0x31}, "Exemplars/wrong_wire_type": {0x2c}, @@ -215,10 +215,9 @@ func genTestEncodingValuesNumberDataPoint() map[string]*NumberDataPoint { "StartTimeUnixNano/test": {StartTimeUnixNano: uint64(13)}, "TimeUnixNano/test": {TimeUnixNano: uint64(13)}, "AsDouble/default": {Value: &NumberDataPoint_AsDouble{AsDouble: float64(0)}}, - "AsDouble/test": {Value: &NumberDataPoint_AsDouble{AsDouble: float64(3.1415926)}}, - "AsInt/default": {Value: &NumberDataPoint_AsInt{AsInt: int64(0)}}, - "AsInt/test": {Value: &NumberDataPoint_AsInt{AsInt: int64(13)}}, - "Exemplars/test": {Exemplars: []Exemplar{{}, *GenTestExemplar()}}, - "Flags/test": {Flags: uint32(13)}, + "AsDouble/test": {Value: &NumberDataPoint_AsDouble{AsDouble: float64(3.1415926)}}, "AsInt/default": {Value: &NumberDataPoint_AsInt{AsInt: int64(0)}}, + "AsInt/test": {Value: &NumberDataPoint_AsInt{AsInt: int64(13)}}, + "Exemplars/test": {Exemplars: []Exemplar{{}, *GenTestExemplar()}}, + "Flags/test": {Flags: uint32(13)}, } } diff --git a/pdata/internal/generated_proto_profile.go b/pdata/internal/generated_proto_profile.go index c3a6460d20a8..d40303aee256 100644 --- a/pdata/internal/generated_proto_profile.go +++ b/pdata/internal/generated_proto_profile.go @@ -12,23 +12,24 @@ import ( "sync" "go.opentelemetry.io/collector/pdata/internal/json" + "go.opentelemetry.io/collector/pdata/internal/metadata" "go.opentelemetry.io/collector/pdata/internal/proto" ) // Profile are an implementation of the pprofextended data model. type Profile struct { - SampleType ValueType + OriginalPayloadFormat string Samples []*Sample + OriginalPayload []byte + AttributeIndices []int32 TimeUnixNano uint64 DurationNano uint64 - PeriodType ValueType Period int64 - ProfileId ProfileID + SampleType ValueType + PeriodType ValueType DroppedAttributesCount uint32 - OriginalPayloadFormat string - OriginalPayload []byte - AttributeIndices []int32 + ProfileId ProfileID } var ( @@ -40,7 +41,7 @@ var ( ) func NewProfile() *Profile { - if !UseProtoPooling.IsEnabled() { + if !metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() { return &Profile{} } return protoPoolProfile.Get().(*Profile) @@ -51,16 +52,17 @@ func DeleteProfile(orig *Profile, nullable bool) { return } - if !UseProtoPooling.IsEnabled() { + if !metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() { orig.Reset() return } - DeleteValueType(&orig.SampleType, false) for i := range orig.Samples { DeleteSample(orig.Samples[i], true) } + DeleteValueType(&orig.PeriodType, false) + DeleteProfileID(&orig.ProfileId, false) orig.Reset() @@ -87,21 +89,15 @@ func CopyProfile(dest, src *Profile) *Profile { dest.Samples = CopySamplePtrSlice(dest.Samples, src.Samples) dest.TimeUnixNano = src.TimeUnixNano - dest.DurationNano = src.DurationNano - CopyValueType(&dest.PeriodType, &src.PeriodType) dest.Period = src.Period - CopyProfileID(&dest.ProfileId, &src.ProfileId) dest.DroppedAttributesCount = src.DroppedAttributesCount - dest.OriginalPayloadFormat = src.OriginalPayloadFormat - dest.OriginalPayload = src.OriginalPayload - dest.AttributeIndices = append(dest.AttributeIndices[:0], src.AttributeIndices...) return dest @@ -215,6 +211,7 @@ func (orig *Profile) MarshalJSON(dest *json.Stream) { } dest.WriteArrayEnd() } + dest.WriteObjectEnd() } @@ -270,30 +267,33 @@ func (orig *Profile) SizeProto() int { l = orig.Samples[i].SizeProto() n += 1 + proto.Sov(uint64(l)) + l } - if orig.TimeUnixNano != 0 { + if orig.TimeUnixNano != uint64(0) { n += 9 } - if orig.DurationNano != 0 { + if orig.DurationNano != uint64(0) { n += 1 + proto.Sov(uint64(orig.DurationNano)) } l = orig.PeriodType.SizeProto() n += 1 + proto.Sov(uint64(l)) + l - if orig.Period != 0 { + if orig.Period != int64(0) { n += 1 + proto.Sov(uint64(orig.Period)) } l = orig.ProfileId.SizeProto() n += 1 + proto.Sov(uint64(l)) + l - if orig.DroppedAttributesCount != 0 { + if orig.DroppedAttributesCount != uint32(0) { n += 1 + proto.Sov(uint64(orig.DroppedAttributesCount)) } + l = len(orig.OriginalPayloadFormat) if l > 0 { n += 1 + proto.Sov(uint64(l)) + l } + l = len(orig.OriginalPayload) if l > 0 { n += 1 + proto.Sov(uint64(l)) + l } + if len(orig.AttributeIndices) > 0 { l = 0 for _, e := range orig.AttributeIndices { @@ -321,13 +321,13 @@ func (orig *Profile) MarshalProto(buf []byte) int { pos-- buf[pos] = 0x12 } - if orig.TimeUnixNano != 0 { + if orig.TimeUnixNano != uint64(0) { pos -= 8 binary.LittleEndian.PutUint64(buf[pos:], uint64(orig.TimeUnixNano)) pos-- buf[pos] = 0x19 } - if orig.DurationNano != 0 { + if orig.DurationNano != uint64(0) { pos = proto.EncodeVarint(buf, pos, uint64(orig.DurationNano)) pos-- buf[pos] = 0x20 @@ -338,7 +338,7 @@ func (orig *Profile) MarshalProto(buf []byte) int { pos-- buf[pos] = 0x2a - if orig.Period != 0 { + if orig.Period != int64(0) { pos = proto.EncodeVarint(buf, pos, uint64(orig.Period)) pos-- buf[pos] = 0x30 @@ -349,7 +349,7 @@ func (orig *Profile) MarshalProto(buf []byte) int { pos-- buf[pos] = 0x3a - if orig.DroppedAttributesCount != 0 { + if orig.DroppedAttributesCount != uint32(0) { pos = proto.EncodeVarint(buf, pos, uint64(orig.DroppedAttributesCount)) pos-- buf[pos] = 0x40 @@ -451,7 +451,6 @@ func (orig *Profile) UnmarshalProto(buf []byte) error { if err != nil { return err } - orig.DurationNano = uint64(num) case 5: @@ -479,7 +478,6 @@ func (orig *Profile) UnmarshalProto(buf []byte) error { if err != nil { return err } - orig.Period = int64(num) case 7: @@ -507,7 +505,6 @@ func (orig *Profile) UnmarshalProto(buf []byte) error { if err != nil { return err } - orig.DroppedAttributesCount = uint32(num) case 9: diff --git a/pdata/internal/generated_proto_profile_test.go b/pdata/internal/generated_proto_profile_test.go index 76b7d69c67ec..986502e194d9 100644 --- a/pdata/internal/generated_proto_profile_test.go +++ b/pdata/internal/generated_proto_profile_test.go @@ -17,16 +17,17 @@ import ( "go.opentelemetry.io/collector/featuregate" "go.opentelemetry.io/collector/pdata/internal/json" + "go.opentelemetry.io/collector/pdata/internal/metadata" ) func TestCopyProfile(t *testing.T) { for name, src := range genTestEncodingValuesProfile() { for _, pooling := range []bool{true, false} { t.Run(name+"/Pooling="+strconv.FormatBool(pooling), func(t *testing.T) { - prevPooling := UseProtoPooling.IsEnabled() - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), pooling)) + prevPooling := metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), pooling)) defer func() { - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), prevPooling)) + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), prevPooling)) }() dest := NewProfile() @@ -102,10 +103,10 @@ func TestMarshalAndUnmarshalJSONProfile(t *testing.T) { for name, src := range genTestEncodingValuesProfile() { for _, pooling := range []bool{true, false} { t.Run(name+"/Pooling="+strconv.FormatBool(pooling), func(t *testing.T) { - prevPooling := UseProtoPooling.IsEnabled() - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), pooling)) + prevPooling := metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), pooling)) defer func() { - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), prevPooling)) + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), prevPooling)) }() stream := json.BorrowStream(nil) @@ -146,10 +147,10 @@ func TestMarshalAndUnmarshalProtoProfile(t *testing.T) { for name, src := range genTestEncodingValuesProfile() { for _, pooling := range []bool{true, false} { t.Run(name+"/Pooling="+strconv.FormatBool(pooling), func(t *testing.T) { - prevPooling := UseProtoPooling.IsEnabled() - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), pooling)) + prevPooling := metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), pooling)) defer func() { - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), prevPooling)) + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), prevPooling)) }() buf := make([]byte, src.SizeProto()) diff --git a/pdata/internal/generated_proto_profilesdata.go b/pdata/internal/generated_proto_profilesdata.go index f3d1c1a16d9b..491a81955dc0 100644 --- a/pdata/internal/generated_proto_profilesdata.go +++ b/pdata/internal/generated_proto_profilesdata.go @@ -11,6 +11,7 @@ import ( "sync" "go.opentelemetry.io/collector/pdata/internal/json" + "go.opentelemetry.io/collector/pdata/internal/metadata" "go.opentelemetry.io/collector/pdata/internal/proto" ) @@ -31,7 +32,7 @@ var ( ) func NewProfilesData() *ProfilesData { - if !UseProtoPooling.IsEnabled() { + if !metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() { return &ProfilesData{} } return protoPoolProfilesData.Get().(*ProfilesData) @@ -42,16 +43,14 @@ func DeleteProfilesData(orig *ProfilesData, nullable bool) { return } - if !UseProtoPooling.IsEnabled() { + if !metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() { orig.Reset() return } - for i := range orig.ResourceProfiles { DeleteResourceProfiles(orig.ResourceProfiles[i], true) } DeleteProfilesDictionary(&orig.Dictionary, false) - orig.Reset() if nullable { protoPoolProfilesData.Put(orig) diff --git a/pdata/internal/generated_proto_profilesdata_test.go b/pdata/internal/generated_proto_profilesdata_test.go index 99901d13b5f8..8e750f2f50af 100644 --- a/pdata/internal/generated_proto_profilesdata_test.go +++ b/pdata/internal/generated_proto_profilesdata_test.go @@ -17,16 +17,17 @@ import ( "go.opentelemetry.io/collector/featuregate" "go.opentelemetry.io/collector/pdata/internal/json" + "go.opentelemetry.io/collector/pdata/internal/metadata" ) func TestCopyProfilesData(t *testing.T) { for name, src := range genTestEncodingValuesProfilesData() { for _, pooling := range []bool{true, false} { t.Run(name+"/Pooling="+strconv.FormatBool(pooling), func(t *testing.T) { - prevPooling := UseProtoPooling.IsEnabled() - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), pooling)) + prevPooling := metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), pooling)) defer func() { - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), prevPooling)) + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), prevPooling)) }() dest := NewProfilesData() @@ -102,10 +103,10 @@ func TestMarshalAndUnmarshalJSONProfilesData(t *testing.T) { for name, src := range genTestEncodingValuesProfilesData() { for _, pooling := range []bool{true, false} { t.Run(name+"/Pooling="+strconv.FormatBool(pooling), func(t *testing.T) { - prevPooling := UseProtoPooling.IsEnabled() - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), pooling)) + prevPooling := metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), pooling)) defer func() { - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), prevPooling)) + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), prevPooling)) }() stream := json.BorrowStream(nil) @@ -146,10 +147,10 @@ func TestMarshalAndUnmarshalProtoProfilesData(t *testing.T) { for name, src := range genTestEncodingValuesProfilesData() { for _, pooling := range []bool{true, false} { t.Run(name+"/Pooling="+strconv.FormatBool(pooling), func(t *testing.T) { - prevPooling := UseProtoPooling.IsEnabled() - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), pooling)) + prevPooling := metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), pooling)) defer func() { - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), prevPooling)) + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), prevPooling)) }() buf := make([]byte, src.SizeProto()) diff --git a/pdata/internal/generated_proto_profilesdictionary.go b/pdata/internal/generated_proto_profilesdictionary.go index af6168e1174d..8471828e6477 100644 --- a/pdata/internal/generated_proto_profilesdictionary.go +++ b/pdata/internal/generated_proto_profilesdictionary.go @@ -11,6 +11,7 @@ import ( "sync" "go.opentelemetry.io/collector/pdata/internal/json" + "go.opentelemetry.io/collector/pdata/internal/metadata" "go.opentelemetry.io/collector/pdata/internal/proto" ) @@ -34,7 +35,7 @@ var ( ) func NewProfilesDictionary() *ProfilesDictionary { - if !UseProtoPooling.IsEnabled() { + if !metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() { return &ProfilesDictionary{} } return protoPoolProfilesDictionary.Get().(*ProfilesDictionary) @@ -45,11 +46,10 @@ func DeleteProfilesDictionary(orig *ProfilesDictionary, nullable bool) { return } - if !UseProtoPooling.IsEnabled() { + if !metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() { orig.Reset() return } - for i := range orig.MappingTable { DeleteMapping(orig.MappingTable[i], true) } @@ -62,13 +62,13 @@ func DeleteProfilesDictionary(orig *ProfilesDictionary, nullable bool) { for i := range orig.LinkTable { DeleteLink(orig.LinkTable[i], true) } + for i := range orig.AttributeTable { DeleteKeyValueAndUnit(orig.AttributeTable[i], true) } for i := range orig.StackTable { DeleteStack(orig.StackTable[i], true) } - orig.Reset() if nullable { protoPoolProfilesDictionary.Put(orig) @@ -97,6 +97,7 @@ func CopyProfilesDictionary(dest, src *ProfilesDictionary) *ProfilesDictionary { dest.LinkTable = CopyLinkPtrSlice(dest.LinkTable, src.LinkTable) dest.StringTable = append(dest.StringTable[:0], src.StringTable...) + dest.AttributeTable = CopyKeyValueAndUnitPtrSlice(dest.AttributeTable, src.AttributeTable) dest.StackTable = CopyStackPtrSlice(dest.StackTable, src.StackTable) @@ -209,6 +210,7 @@ func (orig *ProfilesDictionary) MarshalJSON(dest *json.Stream) { } dest.WriteArrayEnd() } + if len(orig.AttributeTable) > 0 { dest.WriteObjectField("attributeTable") dest.WriteArrayStart() diff --git a/pdata/internal/generated_proto_profilesdictionary_test.go b/pdata/internal/generated_proto_profilesdictionary_test.go index 8408878a0e80..58720cc7ae43 100644 --- a/pdata/internal/generated_proto_profilesdictionary_test.go +++ b/pdata/internal/generated_proto_profilesdictionary_test.go @@ -17,16 +17,17 @@ import ( "go.opentelemetry.io/collector/featuregate" "go.opentelemetry.io/collector/pdata/internal/json" + "go.opentelemetry.io/collector/pdata/internal/metadata" ) func TestCopyProfilesDictionary(t *testing.T) { for name, src := range genTestEncodingValuesProfilesDictionary() { for _, pooling := range []bool{true, false} { t.Run(name+"/Pooling="+strconv.FormatBool(pooling), func(t *testing.T) { - prevPooling := UseProtoPooling.IsEnabled() - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), pooling)) + prevPooling := metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), pooling)) defer func() { - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), prevPooling)) + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), prevPooling)) }() dest := NewProfilesDictionary() @@ -102,10 +103,10 @@ func TestMarshalAndUnmarshalJSONProfilesDictionary(t *testing.T) { for name, src := range genTestEncodingValuesProfilesDictionary() { for _, pooling := range []bool{true, false} { t.Run(name+"/Pooling="+strconv.FormatBool(pooling), func(t *testing.T) { - prevPooling := UseProtoPooling.IsEnabled() - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), pooling)) + prevPooling := metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), pooling)) defer func() { - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), prevPooling)) + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), prevPooling)) }() stream := json.BorrowStream(nil) @@ -146,10 +147,10 @@ func TestMarshalAndUnmarshalProtoProfilesDictionary(t *testing.T) { for name, src := range genTestEncodingValuesProfilesDictionary() { for _, pooling := range []bool{true, false} { t.Run(name+"/Pooling="+strconv.FormatBool(pooling), func(t *testing.T) { - prevPooling := UseProtoPooling.IsEnabled() - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), pooling)) + prevPooling := metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), pooling)) defer func() { - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), prevPooling)) + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), prevPooling)) }() buf := make([]byte, src.SizeProto()) diff --git a/pdata/internal/generated_proto_profilesrequest.go b/pdata/internal/generated_proto_profilesrequest.go index 287b9ee4d5bd..170547c0930c 100644 --- a/pdata/internal/generated_proto_profilesrequest.go +++ b/pdata/internal/generated_proto_profilesrequest.go @@ -12,6 +12,7 @@ import ( "sync" "go.opentelemetry.io/collector/pdata/internal/json" + "go.opentelemetry.io/collector/pdata/internal/metadata" "go.opentelemetry.io/collector/pdata/internal/proto" ) @@ -30,7 +31,7 @@ var ( ) func NewProfilesRequest() *ProfilesRequest { - if !UseProtoPooling.IsEnabled() { + if !metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() { return &ProfilesRequest{} } return protoPoolProfilesRequest.Get().(*ProfilesRequest) @@ -41,11 +42,10 @@ func DeleteProfilesRequest(orig *ProfilesRequest, nullable bool) { return } - if !UseProtoPooling.IsEnabled() { + if !metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() { orig.Reset() return } - DeleteRequestContext(orig.RequestContext, true) DeleteProfilesData(&orig.ProfilesData, false) @@ -173,7 +173,7 @@ func (orig *ProfilesRequest) SizeProto() int { } l = orig.ProfilesData.SizeProto() n += 1 + proto.Sov(uint64(l)) + l - if orig.FormatVersion != 0 { + if orig.FormatVersion != uint32(0) { n += 5 } return n @@ -196,7 +196,7 @@ func (orig *ProfilesRequest) MarshalProto(buf []byte) int { pos-- buf[pos] = 0x1a - if orig.FormatVersion != 0 { + if orig.FormatVersion != uint32(0) { pos -= 4 binary.LittleEndian.PutUint32(buf[pos:], uint32(orig.FormatVersion)) pos-- diff --git a/pdata/internal/generated_proto_profilesrequest_test.go b/pdata/internal/generated_proto_profilesrequest_test.go index 719688643e52..47a0715f8c22 100644 --- a/pdata/internal/generated_proto_profilesrequest_test.go +++ b/pdata/internal/generated_proto_profilesrequest_test.go @@ -17,16 +17,17 @@ import ( "go.opentelemetry.io/collector/featuregate" "go.opentelemetry.io/collector/pdata/internal/json" + "go.opentelemetry.io/collector/pdata/internal/metadata" ) func TestCopyProfilesRequest(t *testing.T) { for name, src := range genTestEncodingValuesProfilesRequest() { for _, pooling := range []bool{true, false} { t.Run(name+"/Pooling="+strconv.FormatBool(pooling), func(t *testing.T) { - prevPooling := UseProtoPooling.IsEnabled() - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), pooling)) + prevPooling := metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), pooling)) defer func() { - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), prevPooling)) + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), prevPooling)) }() dest := NewProfilesRequest() @@ -102,10 +103,10 @@ func TestMarshalAndUnmarshalJSONProfilesRequest(t *testing.T) { for name, src := range genTestEncodingValuesProfilesRequest() { for _, pooling := range []bool{true, false} { t.Run(name+"/Pooling="+strconv.FormatBool(pooling), func(t *testing.T) { - prevPooling := UseProtoPooling.IsEnabled() - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), pooling)) + prevPooling := metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), pooling)) defer func() { - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), prevPooling)) + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), prevPooling)) }() stream := json.BorrowStream(nil) @@ -146,10 +147,10 @@ func TestMarshalAndUnmarshalProtoProfilesRequest(t *testing.T) { for name, src := range genTestEncodingValuesProfilesRequest() { for _, pooling := range []bool{true, false} { t.Run(name+"/Pooling="+strconv.FormatBool(pooling), func(t *testing.T) { - prevPooling := UseProtoPooling.IsEnabled() - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), pooling)) + prevPooling := metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), pooling)) defer func() { - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), prevPooling)) + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), prevPooling)) }() buf := make([]byte, src.SizeProto()) diff --git a/pdata/internal/generated_proto_requestcontext.go b/pdata/internal/generated_proto_requestcontext.go index 4921ea97f094..3aa89c1ca89a 100644 --- a/pdata/internal/generated_proto_requestcontext.go +++ b/pdata/internal/generated_proto_requestcontext.go @@ -11,6 +11,7 @@ import ( "sync" "go.opentelemetry.io/collector/pdata/internal/json" + "go.opentelemetry.io/collector/pdata/internal/metadata" "go.opentelemetry.io/collector/pdata/internal/proto" ) @@ -66,9 +67,9 @@ func (m *RequestContext) GetUnix() *UnixAddr { } type RequestContext struct { + ClientAddress any SpanContext *SpanContext ClientMetadata []KeyValue - ClientAddress any } var ( @@ -104,7 +105,7 @@ var ( ) func NewRequestContext() *RequestContext { - if !UseProtoPooling.IsEnabled() { + if !metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() { return &RequestContext{} } return protoPoolRequestContext.Get().(*RequestContext) @@ -115,11 +116,10 @@ func DeleteRequestContext(orig *RequestContext, nullable bool) { return } - if !UseProtoPooling.IsEnabled() { + if !metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() { orig.Reset() return } - DeleteSpanContext(orig.SpanContext, true) for i := range orig.ClientMetadata { DeleteKeyValue(&orig.ClientMetadata[i], false) @@ -141,9 +141,7 @@ func DeleteRequestContext(orig *RequestContext, nullable bool) { DeleteUnixAddr(ov.Unix, true) ov.Unix = nil ProtoPoolRequestContext_Unix.Put(ov) - } - orig.Reset() if nullable { protoPoolRequestContext.Put(orig) @@ -170,7 +168,7 @@ func CopyRequestContext(dest, src *RequestContext) *RequestContext { switch t := src.ClientAddress.(type) { case *RequestContext_IP: var ov *RequestContext_IP - if !UseProtoPooling.IsEnabled() { + if !metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() { ov = &RequestContext_IP{} } else { ov = ProtoPoolRequestContext_IP.Get().(*RequestContext_IP) @@ -181,7 +179,7 @@ func CopyRequestContext(dest, src *RequestContext) *RequestContext { case *RequestContext_TCP: var ov *RequestContext_TCP - if !UseProtoPooling.IsEnabled() { + if !metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() { ov = &RequestContext_TCP{} } else { ov = ProtoPoolRequestContext_TCP.Get().(*RequestContext_TCP) @@ -192,7 +190,7 @@ func CopyRequestContext(dest, src *RequestContext) *RequestContext { case *RequestContext_UDP: var ov *RequestContext_UDP - if !UseProtoPooling.IsEnabled() { + if !metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() { ov = &RequestContext_UDP{} } else { ov = ProtoPoolRequestContext_UDP.Get().(*RequestContext_UDP) @@ -203,7 +201,7 @@ func CopyRequestContext(dest, src *RequestContext) *RequestContext { case *RequestContext_Unix: var ov *RequestContext_Unix - if !UseProtoPooling.IsEnabled() { + if !metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() { ov = &RequestContext_Unix{} } else { ov = ProtoPoolRequestContext_Unix.Get().(*RequestContext_Unix) @@ -329,7 +327,7 @@ func (orig *RequestContext) UnmarshalJSON(iter *json.Iterator) { case "iP": { var ov *RequestContext_IP - if !UseProtoPooling.IsEnabled() { + if !metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() { ov = &RequestContext_IP{} } else { ov = ProtoPoolRequestContext_IP.Get().(*RequestContext_IP) @@ -338,11 +336,10 @@ func (orig *RequestContext) UnmarshalJSON(iter *json.Iterator) { ov.IP.UnmarshalJSON(iter) orig.ClientAddress = ov } - case "tCP": { var ov *RequestContext_TCP - if !UseProtoPooling.IsEnabled() { + if !metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() { ov = &RequestContext_TCP{} } else { ov = ProtoPoolRequestContext_TCP.Get().(*RequestContext_TCP) @@ -351,11 +348,10 @@ func (orig *RequestContext) UnmarshalJSON(iter *json.Iterator) { ov.TCP.UnmarshalJSON(iter) orig.ClientAddress = ov } - case "uDP": { var ov *RequestContext_UDP - if !UseProtoPooling.IsEnabled() { + if !metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() { ov = &RequestContext_UDP{} } else { ov = ProtoPoolRequestContext_UDP.Get().(*RequestContext_UDP) @@ -364,11 +360,10 @@ func (orig *RequestContext) UnmarshalJSON(iter *json.Iterator) { ov.UDP.UnmarshalJSON(iter) orig.ClientAddress = ov } - case "unix": { var ov *RequestContext_Unix - if !UseProtoPooling.IsEnabled() { + if !metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() { ov = &RequestContext_Unix{} } else { ov = ProtoPoolRequestContext_Unix.Get().(*RequestContext_Unix) @@ -538,7 +533,7 @@ func (orig *RequestContext) UnmarshalProto(buf []byte) error { } startPos := pos - length var ov *RequestContext_IP - if !UseProtoPooling.IsEnabled() { + if !metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() { ov = &RequestContext_IP{} } else { ov = ProtoPoolRequestContext_IP.Get().(*RequestContext_IP) @@ -561,7 +556,7 @@ func (orig *RequestContext) UnmarshalProto(buf []byte) error { } startPos := pos - length var ov *RequestContext_TCP - if !UseProtoPooling.IsEnabled() { + if !metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() { ov = &RequestContext_TCP{} } else { ov = ProtoPoolRequestContext_TCP.Get().(*RequestContext_TCP) @@ -584,7 +579,7 @@ func (orig *RequestContext) UnmarshalProto(buf []byte) error { } startPos := pos - length var ov *RequestContext_UDP - if !UseProtoPooling.IsEnabled() { + if !metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() { ov = &RequestContext_UDP{} } else { ov = ProtoPoolRequestContext_UDP.Get().(*RequestContext_UDP) @@ -607,7 +602,7 @@ func (orig *RequestContext) UnmarshalProto(buf []byte) error { } startPos := pos - length var ov *RequestContext_Unix - if !UseProtoPooling.IsEnabled() { + if !metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() { ov = &RequestContext_Unix{} } else { ov = ProtoPoolRequestContext_Unix.Get().(*RequestContext_Unix) @@ -618,6 +613,7 @@ func (orig *RequestContext) UnmarshalProto(buf []byte) error { return err } orig.ClientAddress = ov + default: pos, err = proto.ConsumeUnknown(buf, pos, wireType) if err != nil { diff --git a/pdata/internal/generated_proto_requestcontext_test.go b/pdata/internal/generated_proto_requestcontext_test.go index dd85497a1a32..f955f867501d 100644 --- a/pdata/internal/generated_proto_requestcontext_test.go +++ b/pdata/internal/generated_proto_requestcontext_test.go @@ -17,16 +17,17 @@ import ( "go.opentelemetry.io/collector/featuregate" "go.opentelemetry.io/collector/pdata/internal/json" + "go.opentelemetry.io/collector/pdata/internal/metadata" ) func TestCopyRequestContext(t *testing.T) { for name, src := range genTestEncodingValuesRequestContext() { for _, pooling := range []bool{true, false} { t.Run(name+"/Pooling="+strconv.FormatBool(pooling), func(t *testing.T) { - prevPooling := UseProtoPooling.IsEnabled() - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), pooling)) + prevPooling := metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), pooling)) defer func() { - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), prevPooling)) + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), prevPooling)) }() dest := NewRequestContext() @@ -102,10 +103,10 @@ func TestMarshalAndUnmarshalJSONRequestContext(t *testing.T) { for name, src := range genTestEncodingValuesRequestContext() { for _, pooling := range []bool{true, false} { t.Run(name+"/Pooling="+strconv.FormatBool(pooling), func(t *testing.T) { - prevPooling := UseProtoPooling.IsEnabled() - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), pooling)) + prevPooling := metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), pooling)) defer func() { - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), prevPooling)) + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), prevPooling)) }() stream := json.BorrowStream(nil) @@ -146,10 +147,10 @@ func TestMarshalAndUnmarshalProtoRequestContext(t *testing.T) { for name, src := range genTestEncodingValuesRequestContext() { for _, pooling := range []bool{true, false} { t.Run(name+"/Pooling="+strconv.FormatBool(pooling), func(t *testing.T) { - prevPooling := UseProtoPooling.IsEnabled() - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), pooling)) + prevPooling := metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), pooling)) defer func() { - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), prevPooling)) + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), prevPooling)) }() buf := make([]byte, src.SizeProto()) @@ -194,15 +195,12 @@ func genTestFailingUnmarshalProtoValuesRequestContext() map[string][]byte { "ClientMetadata/wrong_wire_type": {0x14}, "ClientMetadata/missing_value": {0x12}, - "IP/wrong_wire_type": {0x1c}, - "IP/missing_value": {0x1a}, - - "TCP/wrong_wire_type": {0x24}, - "TCP/missing_value": {0x22}, - - "UDP/wrong_wire_type": {0x2c}, - "UDP/missing_value": {0x2a}, - + "IP/wrong_wire_type": {0x1c}, + "IP/missing_value": {0x1a}, + "TCP/wrong_wire_type": {0x24}, + "TCP/missing_value": {0x22}, + "UDP/wrong_wire_type": {0x2c}, + "UDP/missing_value": {0x2a}, "Unix/wrong_wire_type": {0x34}, "Unix/missing_value": {0x32}, } @@ -214,12 +212,9 @@ func genTestEncodingValuesRequestContext() map[string]*RequestContext { "SpanContext/test": {SpanContext: GenTestSpanContext()}, "ClientMetadata/test": {ClientMetadata: []KeyValue{{}, *GenTestKeyValue()}}, "IP/default": {ClientAddress: &RequestContext_IP{IP: &IPAddr{}}}, - "IP/test": {ClientAddress: &RequestContext_IP{IP: GenTestIPAddr()}}, - "TCP/default": {ClientAddress: &RequestContext_TCP{TCP: &TCPAddr{}}}, - "TCP/test": {ClientAddress: &RequestContext_TCP{TCP: GenTestTCPAddr()}}, - "UDP/default": {ClientAddress: &RequestContext_UDP{UDP: &UDPAddr{}}}, - "UDP/test": {ClientAddress: &RequestContext_UDP{UDP: GenTestUDPAddr()}}, - "Unix/default": {ClientAddress: &RequestContext_Unix{Unix: &UnixAddr{}}}, - "Unix/test": {ClientAddress: &RequestContext_Unix{Unix: GenTestUnixAddr()}}, + "IP/test": {ClientAddress: &RequestContext_IP{IP: GenTestIPAddr()}}, "TCP/default": {ClientAddress: &RequestContext_TCP{TCP: &TCPAddr{}}}, + "TCP/test": {ClientAddress: &RequestContext_TCP{TCP: GenTestTCPAddr()}}, "UDP/default": {ClientAddress: &RequestContext_UDP{UDP: &UDPAddr{}}}, + "UDP/test": {ClientAddress: &RequestContext_UDP{UDP: GenTestUDPAddr()}}, "Unix/default": {ClientAddress: &RequestContext_Unix{Unix: &UnixAddr{}}}, + "Unix/test": {ClientAddress: &RequestContext_Unix{Unix: GenTestUnixAddr()}}, } } diff --git a/pdata/internal/generated_proto_resource.go b/pdata/internal/generated_proto_resource.go index 7bef0ffcb969..9a1a0bba123e 100644 --- a/pdata/internal/generated_proto_resource.go +++ b/pdata/internal/generated_proto_resource.go @@ -11,14 +11,15 @@ import ( "sync" "go.opentelemetry.io/collector/pdata/internal/json" + "go.opentelemetry.io/collector/pdata/internal/metadata" "go.opentelemetry.io/collector/pdata/internal/proto" ) // Resource is a message representing the resource information. type Resource struct { Attributes []KeyValue - DroppedAttributesCount uint32 EntityRefs []*EntityRef + DroppedAttributesCount uint32 } var ( @@ -30,7 +31,7 @@ var ( ) func NewResource() *Resource { - if !UseProtoPooling.IsEnabled() { + if !metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() { return &Resource{} } return protoPoolResource.Get().(*Resource) @@ -41,18 +42,17 @@ func DeleteResource(orig *Resource, nullable bool) { return } - if !UseProtoPooling.IsEnabled() { + if !metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() { orig.Reset() return } - for i := range orig.Attributes { DeleteKeyValue(&orig.Attributes[i], false) } + for i := range orig.EntityRefs { DeleteEntityRef(orig.EntityRefs[i], true) } - orig.Reset() if nullable { protoPoolResource.Put(orig) @@ -75,7 +75,6 @@ func CopyResource(dest, src *Resource) *Resource { dest.Attributes = CopyKeyValueSlice(dest.Attributes, src.Attributes) dest.DroppedAttributesCount = src.DroppedAttributesCount - dest.EntityRefs = CopyEntityRefPtrSlice(dest.EntityRefs, src.EntityRefs) return dest @@ -195,7 +194,7 @@ func (orig *Resource) SizeProto() int { l = orig.Attributes[i].SizeProto() n += 1 + proto.Sov(uint64(l)) + l } - if orig.DroppedAttributesCount != 0 { + if orig.DroppedAttributesCount != uint32(0) { n += 1 + proto.Sov(uint64(orig.DroppedAttributesCount)) } for i := range orig.EntityRefs { @@ -216,7 +215,7 @@ func (orig *Resource) MarshalProto(buf []byte) int { pos-- buf[pos] = 0xa } - if orig.DroppedAttributesCount != 0 { + if orig.DroppedAttributesCount != uint32(0) { pos = proto.EncodeVarint(buf, pos, uint64(orig.DroppedAttributesCount)) pos-- buf[pos] = 0x10 @@ -271,7 +270,6 @@ func (orig *Resource) UnmarshalProto(buf []byte) error { if err != nil { return err } - orig.DroppedAttributesCount = uint32(num) case 3: diff --git a/pdata/internal/generated_proto_resource_test.go b/pdata/internal/generated_proto_resource_test.go index d88729c6da10..427c4a2a4fc4 100644 --- a/pdata/internal/generated_proto_resource_test.go +++ b/pdata/internal/generated_proto_resource_test.go @@ -17,16 +17,17 @@ import ( "go.opentelemetry.io/collector/featuregate" "go.opentelemetry.io/collector/pdata/internal/json" + "go.opentelemetry.io/collector/pdata/internal/metadata" ) func TestCopyResource(t *testing.T) { for name, src := range genTestEncodingValuesResource() { for _, pooling := range []bool{true, false} { t.Run(name+"/Pooling="+strconv.FormatBool(pooling), func(t *testing.T) { - prevPooling := UseProtoPooling.IsEnabled() - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), pooling)) + prevPooling := metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), pooling)) defer func() { - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), prevPooling)) + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), prevPooling)) }() dest := NewResource() @@ -102,10 +103,10 @@ func TestMarshalAndUnmarshalJSONResource(t *testing.T) { for name, src := range genTestEncodingValuesResource() { for _, pooling := range []bool{true, false} { t.Run(name+"/Pooling="+strconv.FormatBool(pooling), func(t *testing.T) { - prevPooling := UseProtoPooling.IsEnabled() - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), pooling)) + prevPooling := metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), pooling)) defer func() { - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), prevPooling)) + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), prevPooling)) }() stream := json.BorrowStream(nil) @@ -146,10 +147,10 @@ func TestMarshalAndUnmarshalProtoResource(t *testing.T) { for name, src := range genTestEncodingValuesResource() { for _, pooling := range []bool{true, false} { t.Run(name+"/Pooling="+strconv.FormatBool(pooling), func(t *testing.T) { - prevPooling := UseProtoPooling.IsEnabled() - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), pooling)) + prevPooling := metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), pooling)) defer func() { - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), prevPooling)) + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), prevPooling)) }() buf := make([]byte, src.SizeProto()) diff --git a/pdata/internal/generated_proto_resourcelogs.go b/pdata/internal/generated_proto_resourcelogs.go index 57c32e3c17bc..d7b8c732b4a7 100644 --- a/pdata/internal/generated_proto_resourcelogs.go +++ b/pdata/internal/generated_proto_resourcelogs.go @@ -11,6 +11,7 @@ import ( "sync" "go.opentelemetry.io/collector/pdata/internal/json" + "go.opentelemetry.io/collector/pdata/internal/metadata" "go.opentelemetry.io/collector/pdata/internal/proto" ) @@ -31,7 +32,7 @@ var ( ) func NewResourceLogs() *ResourceLogs { - if !UseProtoPooling.IsEnabled() { + if !metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() { return &ResourceLogs{} } return protoPoolResourceLogs.Get().(*ResourceLogs) @@ -42,19 +43,18 @@ func DeleteResourceLogs(orig *ResourceLogs, nullable bool) { return } - if !UseProtoPooling.IsEnabled() { + if !metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() { orig.Reset() return } - DeleteResource(&orig.Resource, false) for i := range orig.ScopeLogs { DeleteScopeLogs(orig.ScopeLogs[i], true) } + for i := range orig.DeprecatedScopeLogs { DeleteScopeLogs(orig.DeprecatedScopeLogs[i], true) } - orig.Reset() if nullable { protoPoolResourceLogs.Put(orig) @@ -79,7 +79,6 @@ func CopyResourceLogs(dest, src *ResourceLogs) *ResourceLogs { dest.ScopeLogs = CopyScopeLogsPtrSlice(dest.ScopeLogs, src.ScopeLogs) dest.SchemaUrl = src.SchemaUrl - dest.DeprecatedScopeLogs = CopyScopeLogsPtrSlice(dest.DeprecatedScopeLogs, src.DeprecatedScopeLogs) return dest @@ -206,6 +205,7 @@ func (orig *ResourceLogs) SizeProto() int { l = orig.ScopeLogs[i].SizeProto() n += 1 + proto.Sov(uint64(l)) + l } + l = len(orig.SchemaUrl) if l > 0 { n += 1 + proto.Sov(uint64(l)) + l diff --git a/pdata/internal/generated_proto_resourcelogs_test.go b/pdata/internal/generated_proto_resourcelogs_test.go index e0ebd849bf17..316843748a25 100644 --- a/pdata/internal/generated_proto_resourcelogs_test.go +++ b/pdata/internal/generated_proto_resourcelogs_test.go @@ -17,16 +17,17 @@ import ( "go.opentelemetry.io/collector/featuregate" "go.opentelemetry.io/collector/pdata/internal/json" + "go.opentelemetry.io/collector/pdata/internal/metadata" ) func TestCopyResourceLogs(t *testing.T) { for name, src := range genTestEncodingValuesResourceLogs() { for _, pooling := range []bool{true, false} { t.Run(name+"/Pooling="+strconv.FormatBool(pooling), func(t *testing.T) { - prevPooling := UseProtoPooling.IsEnabled() - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), pooling)) + prevPooling := metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), pooling)) defer func() { - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), prevPooling)) + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), prevPooling)) }() dest := NewResourceLogs() @@ -102,10 +103,10 @@ func TestMarshalAndUnmarshalJSONResourceLogs(t *testing.T) { for name, src := range genTestEncodingValuesResourceLogs() { for _, pooling := range []bool{true, false} { t.Run(name+"/Pooling="+strconv.FormatBool(pooling), func(t *testing.T) { - prevPooling := UseProtoPooling.IsEnabled() - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), pooling)) + prevPooling := metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), pooling)) defer func() { - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), prevPooling)) + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), prevPooling)) }() stream := json.BorrowStream(nil) @@ -146,10 +147,10 @@ func TestMarshalAndUnmarshalProtoResourceLogs(t *testing.T) { for name, src := range genTestEncodingValuesResourceLogs() { for _, pooling := range []bool{true, false} { t.Run(name+"/Pooling="+strconv.FormatBool(pooling), func(t *testing.T) { - prevPooling := UseProtoPooling.IsEnabled() - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), pooling)) + prevPooling := metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), pooling)) defer func() { - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), prevPooling)) + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), prevPooling)) }() buf := make([]byte, src.SizeProto()) diff --git a/pdata/internal/generated_proto_resourcemetrics.go b/pdata/internal/generated_proto_resourcemetrics.go index a260fe62e4dc..364a719ba43b 100644 --- a/pdata/internal/generated_proto_resourcemetrics.go +++ b/pdata/internal/generated_proto_resourcemetrics.go @@ -11,6 +11,7 @@ import ( "sync" "go.opentelemetry.io/collector/pdata/internal/json" + "go.opentelemetry.io/collector/pdata/internal/metadata" "go.opentelemetry.io/collector/pdata/internal/proto" ) @@ -31,7 +32,7 @@ var ( ) func NewResourceMetrics() *ResourceMetrics { - if !UseProtoPooling.IsEnabled() { + if !metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() { return &ResourceMetrics{} } return protoPoolResourceMetrics.Get().(*ResourceMetrics) @@ -42,19 +43,18 @@ func DeleteResourceMetrics(orig *ResourceMetrics, nullable bool) { return } - if !UseProtoPooling.IsEnabled() { + if !metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() { orig.Reset() return } - DeleteResource(&orig.Resource, false) for i := range orig.ScopeMetrics { DeleteScopeMetrics(orig.ScopeMetrics[i], true) } + for i := range orig.DeprecatedScopeMetrics { DeleteScopeMetrics(orig.DeprecatedScopeMetrics[i], true) } - orig.Reset() if nullable { protoPoolResourceMetrics.Put(orig) @@ -79,7 +79,6 @@ func CopyResourceMetrics(dest, src *ResourceMetrics) *ResourceMetrics { dest.ScopeMetrics = CopyScopeMetricsPtrSlice(dest.ScopeMetrics, src.ScopeMetrics) dest.SchemaUrl = src.SchemaUrl - dest.DeprecatedScopeMetrics = CopyScopeMetricsPtrSlice(dest.DeprecatedScopeMetrics, src.DeprecatedScopeMetrics) return dest @@ -206,6 +205,7 @@ func (orig *ResourceMetrics) SizeProto() int { l = orig.ScopeMetrics[i].SizeProto() n += 1 + proto.Sov(uint64(l)) + l } + l = len(orig.SchemaUrl) if l > 0 { n += 1 + proto.Sov(uint64(l)) + l diff --git a/pdata/internal/generated_proto_resourcemetrics_test.go b/pdata/internal/generated_proto_resourcemetrics_test.go index b02f703b3450..c3807123f493 100644 --- a/pdata/internal/generated_proto_resourcemetrics_test.go +++ b/pdata/internal/generated_proto_resourcemetrics_test.go @@ -17,16 +17,17 @@ import ( "go.opentelemetry.io/collector/featuregate" "go.opentelemetry.io/collector/pdata/internal/json" + "go.opentelemetry.io/collector/pdata/internal/metadata" ) func TestCopyResourceMetrics(t *testing.T) { for name, src := range genTestEncodingValuesResourceMetrics() { for _, pooling := range []bool{true, false} { t.Run(name+"/Pooling="+strconv.FormatBool(pooling), func(t *testing.T) { - prevPooling := UseProtoPooling.IsEnabled() - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), pooling)) + prevPooling := metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), pooling)) defer func() { - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), prevPooling)) + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), prevPooling)) }() dest := NewResourceMetrics() @@ -102,10 +103,10 @@ func TestMarshalAndUnmarshalJSONResourceMetrics(t *testing.T) { for name, src := range genTestEncodingValuesResourceMetrics() { for _, pooling := range []bool{true, false} { t.Run(name+"/Pooling="+strconv.FormatBool(pooling), func(t *testing.T) { - prevPooling := UseProtoPooling.IsEnabled() - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), pooling)) + prevPooling := metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), pooling)) defer func() { - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), prevPooling)) + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), prevPooling)) }() stream := json.BorrowStream(nil) @@ -146,10 +147,10 @@ func TestMarshalAndUnmarshalProtoResourceMetrics(t *testing.T) { for name, src := range genTestEncodingValuesResourceMetrics() { for _, pooling := range []bool{true, false} { t.Run(name+"/Pooling="+strconv.FormatBool(pooling), func(t *testing.T) { - prevPooling := UseProtoPooling.IsEnabled() - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), pooling)) + prevPooling := metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), pooling)) defer func() { - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), prevPooling)) + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), prevPooling)) }() buf := make([]byte, src.SizeProto()) diff --git a/pdata/internal/generated_proto_resourceprofiles.go b/pdata/internal/generated_proto_resourceprofiles.go index 69522c24d841..3a6e83db2955 100644 --- a/pdata/internal/generated_proto_resourceprofiles.go +++ b/pdata/internal/generated_proto_resourceprofiles.go @@ -11,14 +11,15 @@ import ( "sync" "go.opentelemetry.io/collector/pdata/internal/json" + "go.opentelemetry.io/collector/pdata/internal/metadata" "go.opentelemetry.io/collector/pdata/internal/proto" ) // ResourceProfiles is a collection of profiles from a Resource. type ResourceProfiles struct { + SchemaUrl string Resource Resource ScopeProfiles []*ScopeProfiles - SchemaUrl string } var ( @@ -30,7 +31,7 @@ var ( ) func NewResourceProfiles() *ResourceProfiles { - if !UseProtoPooling.IsEnabled() { + if !metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() { return &ResourceProfiles{} } return protoPoolResourceProfiles.Get().(*ResourceProfiles) @@ -41,11 +42,10 @@ func DeleteResourceProfiles(orig *ResourceProfiles, nullable bool) { return } - if !UseProtoPooling.IsEnabled() { + if !metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() { orig.Reset() return } - DeleteResource(&orig.Resource, false) for i := range orig.ScopeProfiles { DeleteScopeProfiles(orig.ScopeProfiles[i], true) @@ -184,6 +184,7 @@ func (orig *ResourceProfiles) SizeProto() int { l = orig.ScopeProfiles[i].SizeProto() n += 1 + proto.Sov(uint64(l)) + l } + l = len(orig.SchemaUrl) if l > 0 { n += 1 + proto.Sov(uint64(l)) + l diff --git a/pdata/internal/generated_proto_resourceprofiles_test.go b/pdata/internal/generated_proto_resourceprofiles_test.go index 49edca21ce5a..4fe938d622d6 100644 --- a/pdata/internal/generated_proto_resourceprofiles_test.go +++ b/pdata/internal/generated_proto_resourceprofiles_test.go @@ -17,16 +17,17 @@ import ( "go.opentelemetry.io/collector/featuregate" "go.opentelemetry.io/collector/pdata/internal/json" + "go.opentelemetry.io/collector/pdata/internal/metadata" ) func TestCopyResourceProfiles(t *testing.T) { for name, src := range genTestEncodingValuesResourceProfiles() { for _, pooling := range []bool{true, false} { t.Run(name+"/Pooling="+strconv.FormatBool(pooling), func(t *testing.T) { - prevPooling := UseProtoPooling.IsEnabled() - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), pooling)) + prevPooling := metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), pooling)) defer func() { - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), prevPooling)) + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), prevPooling)) }() dest := NewResourceProfiles() @@ -102,10 +103,10 @@ func TestMarshalAndUnmarshalJSONResourceProfiles(t *testing.T) { for name, src := range genTestEncodingValuesResourceProfiles() { for _, pooling := range []bool{true, false} { t.Run(name+"/Pooling="+strconv.FormatBool(pooling), func(t *testing.T) { - prevPooling := UseProtoPooling.IsEnabled() - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), pooling)) + prevPooling := metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), pooling)) defer func() { - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), prevPooling)) + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), prevPooling)) }() stream := json.BorrowStream(nil) @@ -146,10 +147,10 @@ func TestMarshalAndUnmarshalProtoResourceProfiles(t *testing.T) { for name, src := range genTestEncodingValuesResourceProfiles() { for _, pooling := range []bool{true, false} { t.Run(name+"/Pooling="+strconv.FormatBool(pooling), func(t *testing.T) { - prevPooling := UseProtoPooling.IsEnabled() - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), pooling)) + prevPooling := metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), pooling)) defer func() { - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), prevPooling)) + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), prevPooling)) }() buf := make([]byte, src.SizeProto()) diff --git a/pdata/internal/generated_proto_resourcespans.go b/pdata/internal/generated_proto_resourcespans.go index bd70dedb80ee..4c1bb0786edf 100644 --- a/pdata/internal/generated_proto_resourcespans.go +++ b/pdata/internal/generated_proto_resourcespans.go @@ -11,6 +11,7 @@ import ( "sync" "go.opentelemetry.io/collector/pdata/internal/json" + "go.opentelemetry.io/collector/pdata/internal/metadata" "go.opentelemetry.io/collector/pdata/internal/proto" ) @@ -31,7 +32,7 @@ var ( ) func NewResourceSpans() *ResourceSpans { - if !UseProtoPooling.IsEnabled() { + if !metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() { return &ResourceSpans{} } return protoPoolResourceSpans.Get().(*ResourceSpans) @@ -42,19 +43,18 @@ func DeleteResourceSpans(orig *ResourceSpans, nullable bool) { return } - if !UseProtoPooling.IsEnabled() { + if !metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() { orig.Reset() return } - DeleteResource(&orig.Resource, false) for i := range orig.ScopeSpans { DeleteScopeSpans(orig.ScopeSpans[i], true) } + for i := range orig.DeprecatedScopeSpans { DeleteScopeSpans(orig.DeprecatedScopeSpans[i], true) } - orig.Reset() if nullable { protoPoolResourceSpans.Put(orig) @@ -79,7 +79,6 @@ func CopyResourceSpans(dest, src *ResourceSpans) *ResourceSpans { dest.ScopeSpans = CopyScopeSpansPtrSlice(dest.ScopeSpans, src.ScopeSpans) dest.SchemaUrl = src.SchemaUrl - dest.DeprecatedScopeSpans = CopyScopeSpansPtrSlice(dest.DeprecatedScopeSpans, src.DeprecatedScopeSpans) return dest @@ -206,6 +205,7 @@ func (orig *ResourceSpans) SizeProto() int { l = orig.ScopeSpans[i].SizeProto() n += 1 + proto.Sov(uint64(l)) + l } + l = len(orig.SchemaUrl) if l > 0 { n += 1 + proto.Sov(uint64(l)) + l diff --git a/pdata/internal/generated_proto_resourcespans_test.go b/pdata/internal/generated_proto_resourcespans_test.go index f0ea9531fd81..4048bf0ba07e 100644 --- a/pdata/internal/generated_proto_resourcespans_test.go +++ b/pdata/internal/generated_proto_resourcespans_test.go @@ -17,16 +17,17 @@ import ( "go.opentelemetry.io/collector/featuregate" "go.opentelemetry.io/collector/pdata/internal/json" + "go.opentelemetry.io/collector/pdata/internal/metadata" ) func TestCopyResourceSpans(t *testing.T) { for name, src := range genTestEncodingValuesResourceSpans() { for _, pooling := range []bool{true, false} { t.Run(name+"/Pooling="+strconv.FormatBool(pooling), func(t *testing.T) { - prevPooling := UseProtoPooling.IsEnabled() - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), pooling)) + prevPooling := metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), pooling)) defer func() { - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), prevPooling)) + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), prevPooling)) }() dest := NewResourceSpans() @@ -102,10 +103,10 @@ func TestMarshalAndUnmarshalJSONResourceSpans(t *testing.T) { for name, src := range genTestEncodingValuesResourceSpans() { for _, pooling := range []bool{true, false} { t.Run(name+"/Pooling="+strconv.FormatBool(pooling), func(t *testing.T) { - prevPooling := UseProtoPooling.IsEnabled() - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), pooling)) + prevPooling := metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), pooling)) defer func() { - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), prevPooling)) + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), prevPooling)) }() stream := json.BorrowStream(nil) @@ -146,10 +147,10 @@ func TestMarshalAndUnmarshalProtoResourceSpans(t *testing.T) { for name, src := range genTestEncodingValuesResourceSpans() { for _, pooling := range []bool{true, false} { t.Run(name+"/Pooling="+strconv.FormatBool(pooling), func(t *testing.T) { - prevPooling := UseProtoPooling.IsEnabled() - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), pooling)) + prevPooling := metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), pooling)) defer func() { - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), prevPooling)) + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), prevPooling)) }() buf := make([]byte, src.SizeProto()) diff --git a/pdata/internal/generated_proto_sample.go b/pdata/internal/generated_proto_sample.go index df89e9b63e1e..c53dc105a2e9 100644 --- a/pdata/internal/generated_proto_sample.go +++ b/pdata/internal/generated_proto_sample.go @@ -12,16 +12,17 @@ import ( "sync" "go.opentelemetry.io/collector/pdata/internal/json" + "go.opentelemetry.io/collector/pdata/internal/metadata" "go.opentelemetry.io/collector/pdata/internal/proto" ) // Sample represents each record value encountered within a profiled program. type Sample struct { - StackIndex int32 - Values []int64 AttributeIndices []int32 - LinkIndex int32 + Values []int64 TimestampsUnixNano []uint64 + StackIndex int32 + LinkIndex int32 } var ( @@ -33,7 +34,7 @@ var ( ) func NewSample() *Sample { - if !UseProtoPooling.IsEnabled() { + if !metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() { return &Sample{} } return protoPoolSample.Get().(*Sample) @@ -44,7 +45,7 @@ func DeleteSample(orig *Sample, nullable bool) { return } - if !UseProtoPooling.IsEnabled() { + if !metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() { orig.Reset() return } @@ -69,10 +70,10 @@ func CopySample(dest, src *Sample) *Sample { dest = NewSample() } dest.StackIndex = src.StackIndex - - dest.Values = append(dest.Values[:0], src.Values...) dest.AttributeIndices = append(dest.AttributeIndices[:0], src.AttributeIndices...) + dest.LinkIndex = src.LinkIndex + dest.Values = append(dest.Values[:0], src.Values...) dest.TimestampsUnixNano = append(dest.TimestampsUnixNano[:0], src.TimestampsUnixNano...) @@ -138,16 +139,6 @@ func (orig *Sample) MarshalJSON(dest *json.Stream) { dest.WriteObjectField("stackIndex") dest.WriteInt32(orig.StackIndex) } - if len(orig.Values) > 0 { - dest.WriteObjectField("values") - dest.WriteArrayStart() - dest.WriteInt64(orig.Values[0]) - for i := 1; i < len(orig.Values); i++ { - dest.WriteMore() - dest.WriteInt64(orig.Values[i]) - } - dest.WriteArrayEnd() - } if len(orig.AttributeIndices) > 0 { dest.WriteObjectField("attributeIndices") dest.WriteArrayStart() @@ -158,10 +149,22 @@ func (orig *Sample) MarshalJSON(dest *json.Stream) { } dest.WriteArrayEnd() } + if orig.LinkIndex != int32(0) { dest.WriteObjectField("linkIndex") dest.WriteInt32(orig.LinkIndex) } + if len(orig.Values) > 0 { + dest.WriteObjectField("values") + dest.WriteArrayStart() + dest.WriteInt64(orig.Values[0]) + for i := 1; i < len(orig.Values); i++ { + dest.WriteMore() + dest.WriteInt64(orig.Values[i]) + } + dest.WriteArrayEnd() + } + if len(orig.TimestampsUnixNano) > 0 { dest.WriteObjectField("timestampsUnixNano") dest.WriteArrayStart() @@ -172,6 +175,7 @@ func (orig *Sample) MarshalJSON(dest *json.Stream) { } dest.WriteArrayEnd() } + dest.WriteObjectEnd() } @@ -181,11 +185,6 @@ func (orig *Sample) UnmarshalJSON(iter *json.Iterator) { switch f { case "stackIndex", "stack_index": orig.StackIndex = iter.ReadInt32() - case "values": - for iter.ReadArray() { - orig.Values = append(orig.Values, iter.ReadInt64()) - } - case "attributeIndices", "attribute_indices": for iter.ReadArray() { orig.AttributeIndices = append(orig.AttributeIndices, iter.ReadInt32()) @@ -193,6 +192,11 @@ func (orig *Sample) UnmarshalJSON(iter *json.Iterator) { case "linkIndex", "link_index": orig.LinkIndex = iter.ReadInt32() + case "values": + for iter.ReadArray() { + orig.Values = append(orig.Values, iter.ReadInt64()) + } + case "timestampsUnixNano", "timestamps_unix_nano": for iter.ReadArray() { orig.TimestampsUnixNano = append(orig.TimestampsUnixNano, iter.ReadUint64()) @@ -208,26 +212,28 @@ func (orig *Sample) SizeProto() int { var n int var l int _ = l - if orig.StackIndex != 0 { + if orig.StackIndex != int32(0) { n += 1 + proto.Sov(uint64(orig.StackIndex)) } - if len(orig.Values) > 0 { + + if len(orig.AttributeIndices) > 0 { l = 0 - for _, e := range orig.Values { + for _, e := range orig.AttributeIndices { l += proto.Sov(uint64(e)) } n += 1 + proto.Sov(uint64(l)) + l } - if len(orig.AttributeIndices) > 0 { + if orig.LinkIndex != int32(0) { + n += 1 + proto.Sov(uint64(orig.LinkIndex)) + } + + if len(orig.Values) > 0 { l = 0 - for _, e := range orig.AttributeIndices { + for _, e := range orig.Values { l += proto.Sov(uint64(e)) } n += 1 + proto.Sov(uint64(l)) + l } - if orig.LinkIndex != 0 { - n += 1 + proto.Sov(uint64(orig.LinkIndex)) - } l = len(orig.TimestampsUnixNano) if l > 0 { l *= 8 @@ -240,35 +246,35 @@ func (orig *Sample) MarshalProto(buf []byte) int { pos := len(buf) var l int _ = l - if orig.StackIndex != 0 { + if orig.StackIndex != int32(0) { pos = proto.EncodeVarint(buf, pos, uint64(orig.StackIndex)) pos-- buf[pos] = 0x8 } - l = len(orig.Values) + l = len(orig.AttributeIndices) if l > 0 { endPos := pos for i := l - 1; i >= 0; i-- { - pos = proto.EncodeVarint(buf, pos, uint64(orig.Values[i])) + pos = proto.EncodeVarint(buf, pos, uint64(orig.AttributeIndices[i])) } pos = proto.EncodeVarint(buf, pos, uint64(endPos-pos)) pos-- buf[pos] = 0x12 } - l = len(orig.AttributeIndices) + if orig.LinkIndex != int32(0) { + pos = proto.EncodeVarint(buf, pos, uint64(orig.LinkIndex)) + pos-- + buf[pos] = 0x18 + } + l = len(orig.Values) if l > 0 { endPos := pos for i := l - 1; i >= 0; i-- { - pos = proto.EncodeVarint(buf, pos, uint64(orig.AttributeIndices[i])) + pos = proto.EncodeVarint(buf, pos, uint64(orig.Values[i])) } pos = proto.EncodeVarint(buf, pos, uint64(endPos-pos)) pos-- - buf[pos] = 0x1a - } - if orig.LinkIndex != 0 { - pos = proto.EncodeVarint(buf, pos, uint64(orig.LinkIndex)) - pos-- - buf[pos] = 0x20 + buf[pos] = 0x22 } l = len(orig.TimestampsUnixNano) if l > 0 { @@ -307,7 +313,6 @@ func (orig *Sample) UnmarshalProto(buf []byte) error { if err != nil { return err } - orig.StackIndex = int32(num) case 2: switch wireType { @@ -324,10 +329,10 @@ func (orig *Sample) UnmarshalProto(buf []byte) error { if err != nil { return err } - orig.Values = append(orig.Values, int64(num)) + orig.AttributeIndices = append(orig.AttributeIndices, int32(num)) } if startPos != pos { - return fmt.Errorf("proto: invalid field len = %d for field Values", pos-startPos) + return fmt.Errorf("proto: invalid field len = %d for field AttributeIndices", pos-startPos) } case proto.WireTypeVarint: var num uint64 @@ -335,11 +340,22 @@ func (orig *Sample) UnmarshalProto(buf []byte) error { if err != nil { return err } - orig.Values = append(orig.Values, int64(num)) + orig.AttributeIndices = append(orig.AttributeIndices, int32(num)) default: - return fmt.Errorf("proto: wrong wireType = %d for field Values", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field AttributeIndices", wireType) } + case 3: + if wireType != proto.WireTypeVarint { + return fmt.Errorf("proto: wrong wireType = %d for field LinkIndex", wireType) + } + var num uint64 + num, pos, err = proto.ConsumeVarint(buf, pos) + if err != nil { + return err + } + orig.LinkIndex = int32(num) + case 4: switch wireType { case proto.WireTypeLen: var length int @@ -354,10 +370,10 @@ func (orig *Sample) UnmarshalProto(buf []byte) error { if err != nil { return err } - orig.AttributeIndices = append(orig.AttributeIndices, int32(num)) + orig.Values = append(orig.Values, int64(num)) } if startPos != pos { - return fmt.Errorf("proto: invalid field len = %d for field AttributeIndices", pos-startPos) + return fmt.Errorf("proto: invalid field len = %d for field Values", pos-startPos) } case proto.WireTypeVarint: var num uint64 @@ -365,22 +381,10 @@ func (orig *Sample) UnmarshalProto(buf []byte) error { if err != nil { return err } - orig.AttributeIndices = append(orig.AttributeIndices, int32(num)) + orig.Values = append(orig.Values, int64(num)) default: - return fmt.Errorf("proto: wrong wireType = %d for field AttributeIndices", wireType) - } - - case 4: - if wireType != proto.WireTypeVarint { - return fmt.Errorf("proto: wrong wireType = %d for field LinkIndex", wireType) - } - var num uint64 - num, pos, err = proto.ConsumeVarint(buf, pos) - if err != nil { - return err + return fmt.Errorf("proto: wrong wireType = %d for field Values", wireType) } - - orig.LinkIndex = int32(num) case 5: switch wireType { case proto.WireTypeLen: @@ -426,9 +430,9 @@ func (orig *Sample) UnmarshalProto(buf []byte) error { func GenTestSample() *Sample { orig := NewSample() orig.StackIndex = int32(13) - orig.Values = []int64{int64(0), int64(13)} orig.AttributeIndices = []int32{int32(0), int32(13)} orig.LinkIndex = int32(13) + orig.Values = []int64{int64(0), int64(13)} orig.TimestampsUnixNano = []uint64{uint64(0), uint64(13)} return orig } diff --git a/pdata/internal/generated_proto_sample_test.go b/pdata/internal/generated_proto_sample_test.go index 4893212c10ce..af8c4d47e3cd 100644 --- a/pdata/internal/generated_proto_sample_test.go +++ b/pdata/internal/generated_proto_sample_test.go @@ -17,16 +17,17 @@ import ( "go.opentelemetry.io/collector/featuregate" "go.opentelemetry.io/collector/pdata/internal/json" + "go.opentelemetry.io/collector/pdata/internal/metadata" ) func TestCopySample(t *testing.T) { for name, src := range genTestEncodingValuesSample() { for _, pooling := range []bool{true, false} { t.Run(name+"/Pooling="+strconv.FormatBool(pooling), func(t *testing.T) { - prevPooling := UseProtoPooling.IsEnabled() - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), pooling)) + prevPooling := metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), pooling)) defer func() { - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), prevPooling)) + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), prevPooling)) }() dest := NewSample() @@ -102,10 +103,10 @@ func TestMarshalAndUnmarshalJSONSample(t *testing.T) { for name, src := range genTestEncodingValuesSample() { for _, pooling := range []bool{true, false} { t.Run(name+"/Pooling="+strconv.FormatBool(pooling), func(t *testing.T) { - prevPooling := UseProtoPooling.IsEnabled() - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), pooling)) + prevPooling := metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), pooling)) defer func() { - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), prevPooling)) + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), prevPooling)) }() stream := json.BorrowStream(nil) @@ -146,10 +147,10 @@ func TestMarshalAndUnmarshalProtoSample(t *testing.T) { for name, src := range genTestEncodingValuesSample() { for _, pooling := range []bool{true, false} { t.Run(name+"/Pooling="+strconv.FormatBool(pooling), func(t *testing.T) { - prevPooling := UseProtoPooling.IsEnabled() - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), pooling)) + prevPooling := metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), pooling)) defer func() { - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), prevPooling)) + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), prevPooling)) }() buf := make([]byte, src.SizeProto()) @@ -191,12 +192,12 @@ func genTestFailingUnmarshalProtoValuesSample() map[string][]byte { "invalid_field": {0x02}, "StackIndex/wrong_wire_type": {0xc}, "StackIndex/missing_value": {0x8}, - "Values/wrong_wire_type": {0x14}, - "Values/missing_value": {0x12}, - "AttributeIndices/wrong_wire_type": {0x1c}, - "AttributeIndices/missing_value": {0x1a}, - "LinkIndex/wrong_wire_type": {0x24}, - "LinkIndex/missing_value": {0x20}, + "AttributeIndices/wrong_wire_type": {0x14}, + "AttributeIndices/missing_value": {0x12}, + "LinkIndex/wrong_wire_type": {0x1c}, + "LinkIndex/missing_value": {0x18}, + "Values/wrong_wire_type": {0x24}, + "Values/missing_value": {0x22}, "TimestampsUnixNano/wrong_wire_type": {0x2c}, "TimestampsUnixNano/missing_value": {0x2a}, } @@ -206,9 +207,9 @@ func genTestEncodingValuesSample() map[string]*Sample { return map[string]*Sample{ "empty": NewSample(), "StackIndex/test": {StackIndex: int32(13)}, - "Values/test": {Values: []int64{int64(0), int64(13)}}, "AttributeIndices/test": {AttributeIndices: []int32{int32(0), int32(13)}}, "LinkIndex/test": {LinkIndex: int32(13)}, + "Values/test": {Values: []int64{int64(0), int64(13)}}, "TimestampsUnixNano/test": {TimestampsUnixNano: []uint64{uint64(0), uint64(13)}}, } } diff --git a/pdata/internal/generated_proto_scopelogs.go b/pdata/internal/generated_proto_scopelogs.go index 8f303264c73a..0a04cfdd36d9 100644 --- a/pdata/internal/generated_proto_scopelogs.go +++ b/pdata/internal/generated_proto_scopelogs.go @@ -11,14 +11,15 @@ import ( "sync" "go.opentelemetry.io/collector/pdata/internal/json" + "go.opentelemetry.io/collector/pdata/internal/metadata" "go.opentelemetry.io/collector/pdata/internal/proto" ) // ScopeLogs is a collection of logs from a LibraryInstrumentation. type ScopeLogs struct { - Scope InstrumentationScope - LogRecords []*LogRecord SchemaUrl string + LogRecords []*LogRecord + Scope InstrumentationScope } var ( @@ -30,7 +31,7 @@ var ( ) func NewScopeLogs() *ScopeLogs { - if !UseProtoPooling.IsEnabled() { + if !metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() { return &ScopeLogs{} } return protoPoolScopeLogs.Get().(*ScopeLogs) @@ -41,11 +42,10 @@ func DeleteScopeLogs(orig *ScopeLogs, nullable bool) { return } - if !UseProtoPooling.IsEnabled() { + if !metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() { orig.Reset() return } - DeleteInstrumentationScope(&orig.Scope, false) for i := range orig.LogRecords { DeleteLogRecord(orig.LogRecords[i], true) @@ -184,6 +184,7 @@ func (orig *ScopeLogs) SizeProto() int { l = orig.LogRecords[i].SizeProto() n += 1 + proto.Sov(uint64(l)) + l } + l = len(orig.SchemaUrl) if l > 0 { n += 1 + proto.Sov(uint64(l)) + l diff --git a/pdata/internal/generated_proto_scopelogs_test.go b/pdata/internal/generated_proto_scopelogs_test.go index b9ce60c6bef3..95234a3af28f 100644 --- a/pdata/internal/generated_proto_scopelogs_test.go +++ b/pdata/internal/generated_proto_scopelogs_test.go @@ -17,16 +17,17 @@ import ( "go.opentelemetry.io/collector/featuregate" "go.opentelemetry.io/collector/pdata/internal/json" + "go.opentelemetry.io/collector/pdata/internal/metadata" ) func TestCopyScopeLogs(t *testing.T) { for name, src := range genTestEncodingValuesScopeLogs() { for _, pooling := range []bool{true, false} { t.Run(name+"/Pooling="+strconv.FormatBool(pooling), func(t *testing.T) { - prevPooling := UseProtoPooling.IsEnabled() - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), pooling)) + prevPooling := metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), pooling)) defer func() { - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), prevPooling)) + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), prevPooling)) }() dest := NewScopeLogs() @@ -102,10 +103,10 @@ func TestMarshalAndUnmarshalJSONScopeLogs(t *testing.T) { for name, src := range genTestEncodingValuesScopeLogs() { for _, pooling := range []bool{true, false} { t.Run(name+"/Pooling="+strconv.FormatBool(pooling), func(t *testing.T) { - prevPooling := UseProtoPooling.IsEnabled() - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), pooling)) + prevPooling := metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), pooling)) defer func() { - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), prevPooling)) + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), prevPooling)) }() stream := json.BorrowStream(nil) @@ -146,10 +147,10 @@ func TestMarshalAndUnmarshalProtoScopeLogs(t *testing.T) { for name, src := range genTestEncodingValuesScopeLogs() { for _, pooling := range []bool{true, false} { t.Run(name+"/Pooling="+strconv.FormatBool(pooling), func(t *testing.T) { - prevPooling := UseProtoPooling.IsEnabled() - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), pooling)) + prevPooling := metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), pooling)) defer func() { - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), prevPooling)) + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), prevPooling)) }() buf := make([]byte, src.SizeProto()) diff --git a/pdata/internal/generated_proto_scopemetrics.go b/pdata/internal/generated_proto_scopemetrics.go index fc521a4017c5..957d103054a3 100644 --- a/pdata/internal/generated_proto_scopemetrics.go +++ b/pdata/internal/generated_proto_scopemetrics.go @@ -11,14 +11,15 @@ import ( "sync" "go.opentelemetry.io/collector/pdata/internal/json" + "go.opentelemetry.io/collector/pdata/internal/metadata" "go.opentelemetry.io/collector/pdata/internal/proto" ) // ScopeMetrics is a collection of metrics from a LibraryInstrumentation. type ScopeMetrics struct { - Scope InstrumentationScope - Metrics []*Metric SchemaUrl string + Metrics []*Metric + Scope InstrumentationScope } var ( @@ -30,7 +31,7 @@ var ( ) func NewScopeMetrics() *ScopeMetrics { - if !UseProtoPooling.IsEnabled() { + if !metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() { return &ScopeMetrics{} } return protoPoolScopeMetrics.Get().(*ScopeMetrics) @@ -41,11 +42,10 @@ func DeleteScopeMetrics(orig *ScopeMetrics, nullable bool) { return } - if !UseProtoPooling.IsEnabled() { + if !metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() { orig.Reset() return } - DeleteInstrumentationScope(&orig.Scope, false) for i := range orig.Metrics { DeleteMetric(orig.Metrics[i], true) @@ -184,6 +184,7 @@ func (orig *ScopeMetrics) SizeProto() int { l = orig.Metrics[i].SizeProto() n += 1 + proto.Sov(uint64(l)) + l } + l = len(orig.SchemaUrl) if l > 0 { n += 1 + proto.Sov(uint64(l)) + l diff --git a/pdata/internal/generated_proto_scopemetrics_test.go b/pdata/internal/generated_proto_scopemetrics_test.go index b00c5a6f2809..d789deed403f 100644 --- a/pdata/internal/generated_proto_scopemetrics_test.go +++ b/pdata/internal/generated_proto_scopemetrics_test.go @@ -17,16 +17,17 @@ import ( "go.opentelemetry.io/collector/featuregate" "go.opentelemetry.io/collector/pdata/internal/json" + "go.opentelemetry.io/collector/pdata/internal/metadata" ) func TestCopyScopeMetrics(t *testing.T) { for name, src := range genTestEncodingValuesScopeMetrics() { for _, pooling := range []bool{true, false} { t.Run(name+"/Pooling="+strconv.FormatBool(pooling), func(t *testing.T) { - prevPooling := UseProtoPooling.IsEnabled() - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), pooling)) + prevPooling := metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), pooling)) defer func() { - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), prevPooling)) + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), prevPooling)) }() dest := NewScopeMetrics() @@ -102,10 +103,10 @@ func TestMarshalAndUnmarshalJSONScopeMetrics(t *testing.T) { for name, src := range genTestEncodingValuesScopeMetrics() { for _, pooling := range []bool{true, false} { t.Run(name+"/Pooling="+strconv.FormatBool(pooling), func(t *testing.T) { - prevPooling := UseProtoPooling.IsEnabled() - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), pooling)) + prevPooling := metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), pooling)) defer func() { - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), prevPooling)) + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), prevPooling)) }() stream := json.BorrowStream(nil) @@ -146,10 +147,10 @@ func TestMarshalAndUnmarshalProtoScopeMetrics(t *testing.T) { for name, src := range genTestEncodingValuesScopeMetrics() { for _, pooling := range []bool{true, false} { t.Run(name+"/Pooling="+strconv.FormatBool(pooling), func(t *testing.T) { - prevPooling := UseProtoPooling.IsEnabled() - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), pooling)) + prevPooling := metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), pooling)) defer func() { - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), prevPooling)) + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), prevPooling)) }() buf := make([]byte, src.SizeProto()) diff --git a/pdata/internal/generated_proto_scopeprofiles.go b/pdata/internal/generated_proto_scopeprofiles.go index c17284b1bbd7..ca13dbc36add 100644 --- a/pdata/internal/generated_proto_scopeprofiles.go +++ b/pdata/internal/generated_proto_scopeprofiles.go @@ -11,14 +11,15 @@ import ( "sync" "go.opentelemetry.io/collector/pdata/internal/json" + "go.opentelemetry.io/collector/pdata/internal/metadata" "go.opentelemetry.io/collector/pdata/internal/proto" ) // ScopeProfiles is a collection of profiles from a LibraryInstrumentation. type ScopeProfiles struct { - Scope InstrumentationScope - Profiles []*Profile SchemaUrl string + Profiles []*Profile + Scope InstrumentationScope } var ( @@ -30,7 +31,7 @@ var ( ) func NewScopeProfiles() *ScopeProfiles { - if !UseProtoPooling.IsEnabled() { + if !metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() { return &ScopeProfiles{} } return protoPoolScopeProfiles.Get().(*ScopeProfiles) @@ -41,11 +42,10 @@ func DeleteScopeProfiles(orig *ScopeProfiles, nullable bool) { return } - if !UseProtoPooling.IsEnabled() { + if !metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() { orig.Reset() return } - DeleteInstrumentationScope(&orig.Scope, false) for i := range orig.Profiles { DeleteProfile(orig.Profiles[i], true) @@ -184,6 +184,7 @@ func (orig *ScopeProfiles) SizeProto() int { l = orig.Profiles[i].SizeProto() n += 1 + proto.Sov(uint64(l)) + l } + l = len(orig.SchemaUrl) if l > 0 { n += 1 + proto.Sov(uint64(l)) + l diff --git a/pdata/internal/generated_proto_scopeprofiles_test.go b/pdata/internal/generated_proto_scopeprofiles_test.go index 7818bdd63b11..a16f8fa4e926 100644 --- a/pdata/internal/generated_proto_scopeprofiles_test.go +++ b/pdata/internal/generated_proto_scopeprofiles_test.go @@ -17,16 +17,17 @@ import ( "go.opentelemetry.io/collector/featuregate" "go.opentelemetry.io/collector/pdata/internal/json" + "go.opentelemetry.io/collector/pdata/internal/metadata" ) func TestCopyScopeProfiles(t *testing.T) { for name, src := range genTestEncodingValuesScopeProfiles() { for _, pooling := range []bool{true, false} { t.Run(name+"/Pooling="+strconv.FormatBool(pooling), func(t *testing.T) { - prevPooling := UseProtoPooling.IsEnabled() - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), pooling)) + prevPooling := metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), pooling)) defer func() { - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), prevPooling)) + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), prevPooling)) }() dest := NewScopeProfiles() @@ -102,10 +103,10 @@ func TestMarshalAndUnmarshalJSONScopeProfiles(t *testing.T) { for name, src := range genTestEncodingValuesScopeProfiles() { for _, pooling := range []bool{true, false} { t.Run(name+"/Pooling="+strconv.FormatBool(pooling), func(t *testing.T) { - prevPooling := UseProtoPooling.IsEnabled() - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), pooling)) + prevPooling := metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), pooling)) defer func() { - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), prevPooling)) + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), prevPooling)) }() stream := json.BorrowStream(nil) @@ -146,10 +147,10 @@ func TestMarshalAndUnmarshalProtoScopeProfiles(t *testing.T) { for name, src := range genTestEncodingValuesScopeProfiles() { for _, pooling := range []bool{true, false} { t.Run(name+"/Pooling="+strconv.FormatBool(pooling), func(t *testing.T) { - prevPooling := UseProtoPooling.IsEnabled() - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), pooling)) + prevPooling := metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), pooling)) defer func() { - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), prevPooling)) + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), prevPooling)) }() buf := make([]byte, src.SizeProto()) diff --git a/pdata/internal/generated_proto_scopespans.go b/pdata/internal/generated_proto_scopespans.go index a02a1c715577..85e4fae2dbd0 100644 --- a/pdata/internal/generated_proto_scopespans.go +++ b/pdata/internal/generated_proto_scopespans.go @@ -11,14 +11,15 @@ import ( "sync" "go.opentelemetry.io/collector/pdata/internal/json" + "go.opentelemetry.io/collector/pdata/internal/metadata" "go.opentelemetry.io/collector/pdata/internal/proto" ) // ScopeSpans is a collection of spans from a LibraryInstrumentation. type ScopeSpans struct { - Scope InstrumentationScope - Spans []*Span SchemaUrl string + Spans []*Span + Scope InstrumentationScope } var ( @@ -30,7 +31,7 @@ var ( ) func NewScopeSpans() *ScopeSpans { - if !UseProtoPooling.IsEnabled() { + if !metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() { return &ScopeSpans{} } return protoPoolScopeSpans.Get().(*ScopeSpans) @@ -41,11 +42,10 @@ func DeleteScopeSpans(orig *ScopeSpans, nullable bool) { return } - if !UseProtoPooling.IsEnabled() { + if !metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() { orig.Reset() return } - DeleteInstrumentationScope(&orig.Scope, false) for i := range orig.Spans { DeleteSpan(orig.Spans[i], true) @@ -184,6 +184,7 @@ func (orig *ScopeSpans) SizeProto() int { l = orig.Spans[i].SizeProto() n += 1 + proto.Sov(uint64(l)) + l } + l = len(orig.SchemaUrl) if l > 0 { n += 1 + proto.Sov(uint64(l)) + l diff --git a/pdata/internal/generated_proto_scopespans_test.go b/pdata/internal/generated_proto_scopespans_test.go index 6c84ceaf9645..28bc11f9c203 100644 --- a/pdata/internal/generated_proto_scopespans_test.go +++ b/pdata/internal/generated_proto_scopespans_test.go @@ -17,16 +17,17 @@ import ( "go.opentelemetry.io/collector/featuregate" "go.opentelemetry.io/collector/pdata/internal/json" + "go.opentelemetry.io/collector/pdata/internal/metadata" ) func TestCopyScopeSpans(t *testing.T) { for name, src := range genTestEncodingValuesScopeSpans() { for _, pooling := range []bool{true, false} { t.Run(name+"/Pooling="+strconv.FormatBool(pooling), func(t *testing.T) { - prevPooling := UseProtoPooling.IsEnabled() - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), pooling)) + prevPooling := metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), pooling)) defer func() { - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), prevPooling)) + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), prevPooling)) }() dest := NewScopeSpans() @@ -102,10 +103,10 @@ func TestMarshalAndUnmarshalJSONScopeSpans(t *testing.T) { for name, src := range genTestEncodingValuesScopeSpans() { for _, pooling := range []bool{true, false} { t.Run(name+"/Pooling="+strconv.FormatBool(pooling), func(t *testing.T) { - prevPooling := UseProtoPooling.IsEnabled() - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), pooling)) + prevPooling := metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), pooling)) defer func() { - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), prevPooling)) + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), prevPooling)) }() stream := json.BorrowStream(nil) @@ -146,10 +147,10 @@ func TestMarshalAndUnmarshalProtoScopeSpans(t *testing.T) { for name, src := range genTestEncodingValuesScopeSpans() { for _, pooling := range []bool{true, false} { t.Run(name+"/Pooling="+strconv.FormatBool(pooling), func(t *testing.T) { - prevPooling := UseProtoPooling.IsEnabled() - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), pooling)) + prevPooling := metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), pooling)) defer func() { - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), prevPooling)) + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), prevPooling)) }() buf := make([]byte, src.SizeProto()) diff --git a/pdata/internal/generated_proto_span.go b/pdata/internal/generated_proto_span.go index 7d0ef5a60420..32dbe4f3c3c0 100644 --- a/pdata/internal/generated_proto_span.go +++ b/pdata/internal/generated_proto_span.go @@ -12,28 +12,29 @@ import ( "sync" "go.opentelemetry.io/collector/pdata/internal/json" + "go.opentelemetry.io/collector/pdata/internal/metadata" "go.opentelemetry.io/collector/pdata/internal/proto" ) // Span represents a single operation within a trace. // See Span definition in OTLP: https://github.com/open-telemetry/opentelemetry-proto/blob/main/opentelemetry/proto/trace/v1/trace.proto type Span struct { - TraceId TraceID - SpanId SpanID TraceState string - ParentSpanId SpanID - Flags uint32 Name string - Kind SpanKind + Attributes []KeyValue + Events []*SpanEvent + Links []*SpanLink + Status Status StartTimeUnixNano uint64 EndTimeUnixNano uint64 - Attributes []KeyValue + Flags uint32 + Kind SpanKind DroppedAttributesCount uint32 - Events []*SpanEvent DroppedEventsCount uint32 - Links []*SpanLink DroppedLinksCount uint32 - Status Status + TraceId TraceID + SpanId SpanID + ParentSpanId SpanID } var ( @@ -45,7 +46,7 @@ var ( ) func NewSpan() *Span { - if !UseProtoPooling.IsEnabled() { + if !metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() { return &Span{} } return protoPoolSpan.Get().(*Span) @@ -56,25 +57,28 @@ func DeleteSpan(orig *Span, nullable bool) { return } - if !UseProtoPooling.IsEnabled() { + if !metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() { orig.Reset() return } - DeleteTraceID(&orig.TraceId, false) DeleteSpanID(&orig.SpanId, false) + DeleteSpanID(&orig.ParentSpanId, false) + for i := range orig.Attributes { DeleteKeyValue(&orig.Attributes[i], false) } + for i := range orig.Events { DeleteSpanEvent(orig.Events[i], true) } + for i := range orig.Links { DeleteSpanLink(orig.Links[i], true) } - DeleteStatus(&orig.Status, false) + DeleteStatus(&orig.Status, false) orig.Reset() if nullable { protoPoolSpan.Put(orig) @@ -99,31 +103,22 @@ func CopySpan(dest, src *Span) *Span { CopySpanID(&dest.SpanId, &src.SpanId) dest.TraceState = src.TraceState - CopySpanID(&dest.ParentSpanId, &src.ParentSpanId) dest.Flags = src.Flags - dest.Name = src.Name - dest.Kind = src.Kind - dest.StartTimeUnixNano = src.StartTimeUnixNano - dest.EndTimeUnixNano = src.EndTimeUnixNano - dest.Attributes = CopyKeyValueSlice(dest.Attributes, src.Attributes) dest.DroppedAttributesCount = src.DroppedAttributesCount - dest.Events = CopySpanEventPtrSlice(dest.Events, src.Events) dest.DroppedEventsCount = src.DroppedEventsCount - dest.Links = CopySpanLinkPtrSlice(dest.Links, src.Links) dest.DroppedLinksCount = src.DroppedLinksCount - CopyStatus(&dest.Status, &src.Status) return dest @@ -334,47 +329,49 @@ func (orig *Span) SizeProto() int { n += 1 + proto.Sov(uint64(l)) + l l = orig.SpanId.SizeProto() n += 1 + proto.Sov(uint64(l)) + l + l = len(orig.TraceState) if l > 0 { n += 1 + proto.Sov(uint64(l)) + l } l = orig.ParentSpanId.SizeProto() n += 1 + proto.Sov(uint64(l)) + l - if orig.Flags != 0 { + if orig.Flags != uint32(0) { n += 6 } + l = len(orig.Name) if l > 0 { n += 1 + proto.Sov(uint64(l)) + l } - if orig.Kind != 0 { + if orig.Kind != SpanKind(0) { n += 1 + proto.Sov(uint64(orig.Kind)) } - if orig.StartTimeUnixNano != 0 { + if orig.StartTimeUnixNano != uint64(0) { n += 9 } - if orig.EndTimeUnixNano != 0 { + if orig.EndTimeUnixNano != uint64(0) { n += 9 } for i := range orig.Attributes { l = orig.Attributes[i].SizeProto() n += 1 + proto.Sov(uint64(l)) + l } - if orig.DroppedAttributesCount != 0 { + if orig.DroppedAttributesCount != uint32(0) { n += 1 + proto.Sov(uint64(orig.DroppedAttributesCount)) } for i := range orig.Events { l = orig.Events[i].SizeProto() n += 1 + proto.Sov(uint64(l)) + l } - if orig.DroppedEventsCount != 0 { + if orig.DroppedEventsCount != uint32(0) { n += 1 + proto.Sov(uint64(orig.DroppedEventsCount)) } for i := range orig.Links { l = orig.Links[i].SizeProto() n += 1 + proto.Sov(uint64(l)) + l } - if orig.DroppedLinksCount != 0 { + if orig.DroppedLinksCount != uint32(0) { n += 1 + proto.Sov(uint64(orig.DroppedLinksCount)) } l = orig.Status.SizeProto() @@ -412,7 +409,7 @@ func (orig *Span) MarshalProto(buf []byte) int { pos-- buf[pos] = 0x22 - if orig.Flags != 0 { + if orig.Flags != uint32(0) { pos -= 4 binary.LittleEndian.PutUint32(buf[pos:], uint32(orig.Flags)) pos-- @@ -428,18 +425,18 @@ func (orig *Span) MarshalProto(buf []byte) int { pos-- buf[pos] = 0x2a } - if orig.Kind != 0 { + if orig.Kind != SpanKind(0) { pos = proto.EncodeVarint(buf, pos, uint64(orig.Kind)) pos-- buf[pos] = 0x30 } - if orig.StartTimeUnixNano != 0 { + if orig.StartTimeUnixNano != uint64(0) { pos -= 8 binary.LittleEndian.PutUint64(buf[pos:], uint64(orig.StartTimeUnixNano)) pos-- buf[pos] = 0x39 } - if orig.EndTimeUnixNano != 0 { + if orig.EndTimeUnixNano != uint64(0) { pos -= 8 binary.LittleEndian.PutUint64(buf[pos:], uint64(orig.EndTimeUnixNano)) pos-- @@ -452,7 +449,7 @@ func (orig *Span) MarshalProto(buf []byte) int { pos-- buf[pos] = 0x4a } - if orig.DroppedAttributesCount != 0 { + if orig.DroppedAttributesCount != uint32(0) { pos = proto.EncodeVarint(buf, pos, uint64(orig.DroppedAttributesCount)) pos-- buf[pos] = 0x50 @@ -464,7 +461,7 @@ func (orig *Span) MarshalProto(buf []byte) int { pos-- buf[pos] = 0x5a } - if orig.DroppedEventsCount != 0 { + if orig.DroppedEventsCount != uint32(0) { pos = proto.EncodeVarint(buf, pos, uint64(orig.DroppedEventsCount)) pos-- buf[pos] = 0x60 @@ -476,7 +473,7 @@ func (orig *Span) MarshalProto(buf []byte) int { pos-- buf[pos] = 0x6a } - if orig.DroppedLinksCount != 0 { + if orig.DroppedLinksCount != uint32(0) { pos = proto.EncodeVarint(buf, pos, uint64(orig.DroppedLinksCount)) pos-- buf[pos] = 0x70 @@ -598,7 +595,6 @@ func (orig *Span) UnmarshalProto(buf []byte) error { if err != nil { return err } - orig.Kind = SpanKind(num) case 7: @@ -650,7 +646,6 @@ func (orig *Span) UnmarshalProto(buf []byte) error { if err != nil { return err } - orig.DroppedAttributesCount = uint32(num) case 11: @@ -678,7 +673,6 @@ func (orig *Span) UnmarshalProto(buf []byte) error { if err != nil { return err } - orig.DroppedEventsCount = uint32(num) case 13: @@ -706,7 +700,6 @@ func (orig *Span) UnmarshalProto(buf []byte) error { if err != nil { return err } - orig.DroppedLinksCount = uint32(num) case 15: diff --git a/pdata/internal/generated_proto_span_test.go b/pdata/internal/generated_proto_span_test.go index 07667ac9006b..76966b556400 100644 --- a/pdata/internal/generated_proto_span_test.go +++ b/pdata/internal/generated_proto_span_test.go @@ -17,16 +17,17 @@ import ( "go.opentelemetry.io/collector/featuregate" "go.opentelemetry.io/collector/pdata/internal/json" + "go.opentelemetry.io/collector/pdata/internal/metadata" ) func TestCopySpan(t *testing.T) { for name, src := range genTestEncodingValuesSpan() { for _, pooling := range []bool{true, false} { t.Run(name+"/Pooling="+strconv.FormatBool(pooling), func(t *testing.T) { - prevPooling := UseProtoPooling.IsEnabled() - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), pooling)) + prevPooling := metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), pooling)) defer func() { - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), prevPooling)) + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), prevPooling)) }() dest := NewSpan() @@ -102,10 +103,10 @@ func TestMarshalAndUnmarshalJSONSpan(t *testing.T) { for name, src := range genTestEncodingValuesSpan() { for _, pooling := range []bool{true, false} { t.Run(name+"/Pooling="+strconv.FormatBool(pooling), func(t *testing.T) { - prevPooling := UseProtoPooling.IsEnabled() - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), pooling)) + prevPooling := metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), pooling)) defer func() { - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), prevPooling)) + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), prevPooling)) }() stream := json.BorrowStream(nil) @@ -146,10 +147,10 @@ func TestMarshalAndUnmarshalProtoSpan(t *testing.T) { for name, src := range genTestEncodingValuesSpan() { for _, pooling := range []bool{true, false} { t.Run(name+"/Pooling="+strconv.FormatBool(pooling), func(t *testing.T) { - prevPooling := UseProtoPooling.IsEnabled() - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), pooling)) + prevPooling := metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), pooling)) defer func() { - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), prevPooling)) + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), prevPooling)) }() buf := make([]byte, src.SizeProto()) diff --git a/pdata/internal/generated_proto_spancontext.go b/pdata/internal/generated_proto_spancontext.go index 7d78787004dd..e63b8ef4904e 100644 --- a/pdata/internal/generated_proto_spancontext.go +++ b/pdata/internal/generated_proto_spancontext.go @@ -12,14 +12,15 @@ import ( "sync" "go.opentelemetry.io/collector/pdata/internal/json" + "go.opentelemetry.io/collector/pdata/internal/metadata" "go.opentelemetry.io/collector/pdata/internal/proto" ) type SpanContext struct { + TraceState string + TraceFlags uint32 TraceID TraceID SpanID SpanID - TraceFlags uint32 - TraceState string Remote bool } @@ -32,7 +33,7 @@ var ( ) func NewSpanContext() *SpanContext { - if !UseProtoPooling.IsEnabled() { + if !metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() { return &SpanContext{} } return protoPoolSpanContext.Get().(*SpanContext) @@ -43,11 +44,10 @@ func DeleteSpanContext(orig *SpanContext, nullable bool) { return } - if !UseProtoPooling.IsEnabled() { + if !metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() { orig.Reset() return } - DeleteTraceID(&orig.TraceID, false) DeleteSpanID(&orig.SpanID, false) @@ -75,9 +75,7 @@ func CopySpanContext(dest, src *SpanContext) *SpanContext { CopySpanID(&dest.SpanID, &src.SpanID) dest.TraceFlags = src.TraceFlags - dest.TraceState = src.TraceState - dest.Remote = src.Remote return dest @@ -191,14 +189,15 @@ func (orig *SpanContext) SizeProto() int { n += 1 + proto.Sov(uint64(l)) + l l = orig.SpanID.SizeProto() n += 1 + proto.Sov(uint64(l)) + l - if orig.TraceFlags != 0 { + if orig.TraceFlags != uint32(0) { n += 5 } + l = len(orig.TraceState) if l > 0 { n += 1 + proto.Sov(uint64(l)) + l } - if orig.Remote { + if orig.Remote != false { n += 2 } return n @@ -220,7 +219,7 @@ func (orig *SpanContext) MarshalProto(buf []byte) int { pos-- buf[pos] = 0x12 - if orig.TraceFlags != 0 { + if orig.TraceFlags != uint32(0) { pos -= 4 binary.LittleEndian.PutUint32(buf[pos:], uint32(orig.TraceFlags)) pos-- @@ -234,7 +233,7 @@ func (orig *SpanContext) MarshalProto(buf []byte) int { pos-- buf[pos] = 0x22 } - if orig.Remote { + if orig.Remote != false { pos-- if orig.Remote { buf[pos] = 1 @@ -327,7 +326,6 @@ func (orig *SpanContext) UnmarshalProto(buf []byte) error { if err != nil { return err } - orig.Remote = num != 0 default: pos, err = proto.ConsumeUnknown(buf, pos, wireType) diff --git a/pdata/internal/generated_proto_spancontext_test.go b/pdata/internal/generated_proto_spancontext_test.go index 47b79925f7d6..cd41326f784c 100644 --- a/pdata/internal/generated_proto_spancontext_test.go +++ b/pdata/internal/generated_proto_spancontext_test.go @@ -17,16 +17,17 @@ import ( "go.opentelemetry.io/collector/featuregate" "go.opentelemetry.io/collector/pdata/internal/json" + "go.opentelemetry.io/collector/pdata/internal/metadata" ) func TestCopySpanContext(t *testing.T) { for name, src := range genTestEncodingValuesSpanContext() { for _, pooling := range []bool{true, false} { t.Run(name+"/Pooling="+strconv.FormatBool(pooling), func(t *testing.T) { - prevPooling := UseProtoPooling.IsEnabled() - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), pooling)) + prevPooling := metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), pooling)) defer func() { - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), prevPooling)) + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), prevPooling)) }() dest := NewSpanContext() @@ -102,10 +103,10 @@ func TestMarshalAndUnmarshalJSONSpanContext(t *testing.T) { for name, src := range genTestEncodingValuesSpanContext() { for _, pooling := range []bool{true, false} { t.Run(name+"/Pooling="+strconv.FormatBool(pooling), func(t *testing.T) { - prevPooling := UseProtoPooling.IsEnabled() - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), pooling)) + prevPooling := metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), pooling)) defer func() { - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), prevPooling)) + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), prevPooling)) }() stream := json.BorrowStream(nil) @@ -146,10 +147,10 @@ func TestMarshalAndUnmarshalProtoSpanContext(t *testing.T) { for name, src := range genTestEncodingValuesSpanContext() { for _, pooling := range []bool{true, false} { t.Run(name+"/Pooling="+strconv.FormatBool(pooling), func(t *testing.T) { - prevPooling := UseProtoPooling.IsEnabled() - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), pooling)) + prevPooling := metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), pooling)) defer func() { - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), prevPooling)) + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), prevPooling)) }() buf := make([]byte, src.SizeProto()) diff --git a/pdata/internal/generated_proto_spanevent.go b/pdata/internal/generated_proto_spanevent.go index 14c0fe1627cb..269aee7d9ac0 100644 --- a/pdata/internal/generated_proto_spanevent.go +++ b/pdata/internal/generated_proto_spanevent.go @@ -12,15 +12,16 @@ import ( "sync" "go.opentelemetry.io/collector/pdata/internal/json" + "go.opentelemetry.io/collector/pdata/internal/metadata" "go.opentelemetry.io/collector/pdata/internal/proto" ) // SpanEvent is a time-stamped annotation of the span, consisting of user-supplied // text description and key-value pairs. See OTLP for event definition. type SpanEvent struct { - TimeUnixNano uint64 Name string Attributes []KeyValue + TimeUnixNano uint64 DroppedAttributesCount uint32 } @@ -33,7 +34,7 @@ var ( ) func NewSpanEvent() *SpanEvent { - if !UseProtoPooling.IsEnabled() { + if !metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() { return &SpanEvent{} } return protoPoolSpanEvent.Get().(*SpanEvent) @@ -44,7 +45,7 @@ func DeleteSpanEvent(orig *SpanEvent, nullable bool) { return } - if !UseProtoPooling.IsEnabled() { + if !metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() { orig.Reset() return } @@ -73,9 +74,7 @@ func CopySpanEvent(dest, src *SpanEvent) *SpanEvent { dest = NewSpanEvent() } dest.TimeUnixNano = src.TimeUnixNano - dest.Name = src.Name - dest.Attributes = CopyKeyValueSlice(dest.Attributes, src.Attributes) dest.DroppedAttributesCount = src.DroppedAttributesCount @@ -189,9 +188,10 @@ func (orig *SpanEvent) SizeProto() int { var n int var l int _ = l - if orig.TimeUnixNano != 0 { + if orig.TimeUnixNano != uint64(0) { n += 9 } + l = len(orig.Name) if l > 0 { n += 1 + proto.Sov(uint64(l)) + l @@ -200,7 +200,7 @@ func (orig *SpanEvent) SizeProto() int { l = orig.Attributes[i].SizeProto() n += 1 + proto.Sov(uint64(l)) + l } - if orig.DroppedAttributesCount != 0 { + if orig.DroppedAttributesCount != uint32(0) { n += 1 + proto.Sov(uint64(orig.DroppedAttributesCount)) } return n @@ -210,7 +210,7 @@ func (orig *SpanEvent) MarshalProto(buf []byte) int { pos := len(buf) var l int _ = l - if orig.TimeUnixNano != 0 { + if orig.TimeUnixNano != uint64(0) { pos -= 8 binary.LittleEndian.PutUint64(buf[pos:], uint64(orig.TimeUnixNano)) pos-- @@ -231,7 +231,7 @@ func (orig *SpanEvent) MarshalProto(buf []byte) int { pos-- buf[pos] = 0x1a } - if orig.DroppedAttributesCount != 0 { + if orig.DroppedAttributesCount != uint32(0) { pos = proto.EncodeVarint(buf, pos, uint64(orig.DroppedAttributesCount)) pos-- buf[pos] = 0x20 @@ -303,7 +303,6 @@ func (orig *SpanEvent) UnmarshalProto(buf []byte) error { if err != nil { return err } - orig.DroppedAttributesCount = uint32(num) default: pos, err = proto.ConsumeUnknown(buf, pos, wireType) diff --git a/pdata/internal/generated_proto_spanevent_test.go b/pdata/internal/generated_proto_spanevent_test.go index 5b2e24feb83c..274207e50c82 100644 --- a/pdata/internal/generated_proto_spanevent_test.go +++ b/pdata/internal/generated_proto_spanevent_test.go @@ -17,16 +17,17 @@ import ( "go.opentelemetry.io/collector/featuregate" "go.opentelemetry.io/collector/pdata/internal/json" + "go.opentelemetry.io/collector/pdata/internal/metadata" ) func TestCopySpanEvent(t *testing.T) { for name, src := range genTestEncodingValuesSpanEvent() { for _, pooling := range []bool{true, false} { t.Run(name+"/Pooling="+strconv.FormatBool(pooling), func(t *testing.T) { - prevPooling := UseProtoPooling.IsEnabled() - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), pooling)) + prevPooling := metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), pooling)) defer func() { - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), prevPooling)) + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), prevPooling)) }() dest := NewSpanEvent() @@ -102,10 +103,10 @@ func TestMarshalAndUnmarshalJSONSpanEvent(t *testing.T) { for name, src := range genTestEncodingValuesSpanEvent() { for _, pooling := range []bool{true, false} { t.Run(name+"/Pooling="+strconv.FormatBool(pooling), func(t *testing.T) { - prevPooling := UseProtoPooling.IsEnabled() - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), pooling)) + prevPooling := metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), pooling)) defer func() { - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), prevPooling)) + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), prevPooling)) }() stream := json.BorrowStream(nil) @@ -146,10 +147,10 @@ func TestMarshalAndUnmarshalProtoSpanEvent(t *testing.T) { for name, src := range genTestEncodingValuesSpanEvent() { for _, pooling := range []bool{true, false} { t.Run(name+"/Pooling="+strconv.FormatBool(pooling), func(t *testing.T) { - prevPooling := UseProtoPooling.IsEnabled() - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), pooling)) + prevPooling := metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), pooling)) defer func() { - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), prevPooling)) + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), prevPooling)) }() buf := make([]byte, src.SizeProto()) diff --git a/pdata/internal/generated_proto_spanlink.go b/pdata/internal/generated_proto_spanlink.go index 07c42640bcf5..ee2ccfa06d48 100644 --- a/pdata/internal/generated_proto_spanlink.go +++ b/pdata/internal/generated_proto_spanlink.go @@ -12,6 +12,7 @@ import ( "sync" "go.opentelemetry.io/collector/pdata/internal/json" + "go.opentelemetry.io/collector/pdata/internal/metadata" "go.opentelemetry.io/collector/pdata/internal/proto" ) @@ -19,12 +20,12 @@ import ( // different trace. // See Link definition in OTLP: https://github.com/open-telemetry/opentelemetry-proto/blob/main/opentelemetry/proto/trace/v1/trace.proto type SpanLink struct { - TraceId TraceID - SpanId SpanID TraceState string Attributes []KeyValue DroppedAttributesCount uint32 Flags uint32 + TraceId TraceID + SpanId SpanID } var ( @@ -36,7 +37,7 @@ var ( ) func NewSpanLink() *SpanLink { - if !UseProtoPooling.IsEnabled() { + if !metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() { return &SpanLink{} } return protoPoolSpanLink.Get().(*SpanLink) @@ -47,13 +48,13 @@ func DeleteSpanLink(orig *SpanLink, nullable bool) { return } - if !UseProtoPooling.IsEnabled() { + if !metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() { orig.Reset() return } - DeleteTraceID(&orig.TraceId, false) DeleteSpanID(&orig.SpanId, false) + for i := range orig.Attributes { DeleteKeyValue(&orig.Attributes[i], false) } @@ -82,11 +83,9 @@ func CopySpanLink(dest, src *SpanLink) *SpanLink { CopySpanID(&dest.SpanId, &src.SpanId) dest.TraceState = src.TraceState - dest.Attributes = CopyKeyValueSlice(dest.Attributes, src.Attributes) dest.DroppedAttributesCount = src.DroppedAttributesCount - dest.Flags = src.Flags return dest @@ -216,6 +215,7 @@ func (orig *SpanLink) SizeProto() int { n += 1 + proto.Sov(uint64(l)) + l l = orig.SpanId.SizeProto() n += 1 + proto.Sov(uint64(l)) + l + l = len(orig.TraceState) if l > 0 { n += 1 + proto.Sov(uint64(l)) + l @@ -224,10 +224,10 @@ func (orig *SpanLink) SizeProto() int { l = orig.Attributes[i].SizeProto() n += 1 + proto.Sov(uint64(l)) + l } - if orig.DroppedAttributesCount != 0 { + if orig.DroppedAttributesCount != uint32(0) { n += 1 + proto.Sov(uint64(orig.DroppedAttributesCount)) } - if orig.Flags != 0 { + if orig.Flags != uint32(0) { n += 5 } return n @@ -264,12 +264,12 @@ func (orig *SpanLink) MarshalProto(buf []byte) int { pos-- buf[pos] = 0x22 } - if orig.DroppedAttributesCount != 0 { + if orig.DroppedAttributesCount != uint32(0) { pos = proto.EncodeVarint(buf, pos, uint64(orig.DroppedAttributesCount)) pos-- buf[pos] = 0x28 } - if orig.Flags != 0 { + if orig.Flags != uint32(0) { pos -= 4 binary.LittleEndian.PutUint32(buf[pos:], uint32(orig.Flags)) pos-- @@ -362,7 +362,6 @@ func (orig *SpanLink) UnmarshalProto(buf []byte) error { if err != nil { return err } - orig.DroppedAttributesCount = uint32(num) case 6: diff --git a/pdata/internal/generated_proto_spanlink_test.go b/pdata/internal/generated_proto_spanlink_test.go index 60ca028819c0..e5d043c9154e 100644 --- a/pdata/internal/generated_proto_spanlink_test.go +++ b/pdata/internal/generated_proto_spanlink_test.go @@ -17,16 +17,17 @@ import ( "go.opentelemetry.io/collector/featuregate" "go.opentelemetry.io/collector/pdata/internal/json" + "go.opentelemetry.io/collector/pdata/internal/metadata" ) func TestCopySpanLink(t *testing.T) { for name, src := range genTestEncodingValuesSpanLink() { for _, pooling := range []bool{true, false} { t.Run(name+"/Pooling="+strconv.FormatBool(pooling), func(t *testing.T) { - prevPooling := UseProtoPooling.IsEnabled() - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), pooling)) + prevPooling := metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), pooling)) defer func() { - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), prevPooling)) + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), prevPooling)) }() dest := NewSpanLink() @@ -102,10 +103,10 @@ func TestMarshalAndUnmarshalJSONSpanLink(t *testing.T) { for name, src := range genTestEncodingValuesSpanLink() { for _, pooling := range []bool{true, false} { t.Run(name+"/Pooling="+strconv.FormatBool(pooling), func(t *testing.T) { - prevPooling := UseProtoPooling.IsEnabled() - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), pooling)) + prevPooling := metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), pooling)) defer func() { - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), prevPooling)) + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), prevPooling)) }() stream := json.BorrowStream(nil) @@ -146,10 +147,10 @@ func TestMarshalAndUnmarshalProtoSpanLink(t *testing.T) { for name, src := range genTestEncodingValuesSpanLink() { for _, pooling := range []bool{true, false} { t.Run(name+"/Pooling="+strconv.FormatBool(pooling), func(t *testing.T) { - prevPooling := UseProtoPooling.IsEnabled() - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), pooling)) + prevPooling := metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), pooling)) defer func() { - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), prevPooling)) + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), prevPooling)) }() buf := make([]byte, src.SizeProto()) diff --git a/pdata/internal/generated_proto_stack.go b/pdata/internal/generated_proto_stack.go index a97599bfc655..90bf79fa2d77 100644 --- a/pdata/internal/generated_proto_stack.go +++ b/pdata/internal/generated_proto_stack.go @@ -11,6 +11,7 @@ import ( "sync" "go.opentelemetry.io/collector/pdata/internal/json" + "go.opentelemetry.io/collector/pdata/internal/metadata" "go.opentelemetry.io/collector/pdata/internal/proto" ) @@ -29,7 +30,7 @@ var ( ) func NewStack() *Stack { - if !UseProtoPooling.IsEnabled() { + if !metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() { return &Stack{} } return protoPoolStack.Get().(*Stack) @@ -40,7 +41,7 @@ func DeleteStack(orig *Stack, nullable bool) { return } - if !UseProtoPooling.IsEnabled() { + if !metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() { orig.Reset() return } @@ -134,6 +135,7 @@ func (orig *Stack) MarshalJSON(dest *json.Stream) { } dest.WriteArrayEnd() } + dest.WriteObjectEnd() } @@ -156,6 +158,7 @@ func (orig *Stack) SizeProto() int { var n int var l int _ = l + if len(orig.LocationIndices) > 0 { l = 0 for _, e := range orig.LocationIndices { diff --git a/pdata/internal/generated_proto_stack_test.go b/pdata/internal/generated_proto_stack_test.go index ab99ba7b0172..d66ae2a60062 100644 --- a/pdata/internal/generated_proto_stack_test.go +++ b/pdata/internal/generated_proto_stack_test.go @@ -17,16 +17,17 @@ import ( "go.opentelemetry.io/collector/featuregate" "go.opentelemetry.io/collector/pdata/internal/json" + "go.opentelemetry.io/collector/pdata/internal/metadata" ) func TestCopyStack(t *testing.T) { for name, src := range genTestEncodingValuesStack() { for _, pooling := range []bool{true, false} { t.Run(name+"/Pooling="+strconv.FormatBool(pooling), func(t *testing.T) { - prevPooling := UseProtoPooling.IsEnabled() - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), pooling)) + prevPooling := metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), pooling)) defer func() { - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), prevPooling)) + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), prevPooling)) }() dest := NewStack() @@ -102,10 +103,10 @@ func TestMarshalAndUnmarshalJSONStack(t *testing.T) { for name, src := range genTestEncodingValuesStack() { for _, pooling := range []bool{true, false} { t.Run(name+"/Pooling="+strconv.FormatBool(pooling), func(t *testing.T) { - prevPooling := UseProtoPooling.IsEnabled() - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), pooling)) + prevPooling := metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), pooling)) defer func() { - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), prevPooling)) + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), prevPooling)) }() stream := json.BorrowStream(nil) @@ -146,10 +147,10 @@ func TestMarshalAndUnmarshalProtoStack(t *testing.T) { for name, src := range genTestEncodingValuesStack() { for _, pooling := range []bool{true, false} { t.Run(name+"/Pooling="+strconv.FormatBool(pooling), func(t *testing.T) { - prevPooling := UseProtoPooling.IsEnabled() - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), pooling)) + prevPooling := metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), pooling)) defer func() { - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), prevPooling)) + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), prevPooling)) }() buf := make([]byte, src.SizeProto()) diff --git a/pdata/internal/generated_proto_status.go b/pdata/internal/generated_proto_status.go index c2f2d37754f2..35ae797c971f 100644 --- a/pdata/internal/generated_proto_status.go +++ b/pdata/internal/generated_proto_status.go @@ -11,6 +11,7 @@ import ( "sync" "go.opentelemetry.io/collector/pdata/internal/json" + "go.opentelemetry.io/collector/pdata/internal/metadata" "go.opentelemetry.io/collector/pdata/internal/proto" ) @@ -30,7 +31,7 @@ var ( ) func NewStatus() *Status { - if !UseProtoPooling.IsEnabled() { + if !metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() { return &Status{} } return protoPoolStatus.Get().(*Status) @@ -41,7 +42,7 @@ func DeleteStatus(orig *Status, nullable bool) { return } - if !UseProtoPooling.IsEnabled() { + if !metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() { orig.Reset() return } @@ -66,7 +67,6 @@ func CopyStatus(dest, src *Status) *Status { dest = NewStatus() } dest.Message = src.Message - dest.Code = src.Code return dest @@ -157,11 +157,12 @@ func (orig *Status) SizeProto() int { var n int var l int _ = l + l = len(orig.Message) if l > 0 { n += 1 + proto.Sov(uint64(l)) + l } - if orig.Code != 0 { + if orig.Code != StatusCode(0) { n += 1 + proto.Sov(uint64(orig.Code)) } return n @@ -179,7 +180,7 @@ func (orig *Status) MarshalProto(buf []byte) int { pos-- buf[pos] = 0x12 } - if orig.Code != 0 { + if orig.Code != StatusCode(0) { pos = proto.EncodeVarint(buf, pos, uint64(orig.Code)) pos-- buf[pos] = 0x18 @@ -223,7 +224,6 @@ func (orig *Status) UnmarshalProto(buf []byte) error { if err != nil { return err } - orig.Code = StatusCode(num) default: pos, err = proto.ConsumeUnknown(buf, pos, wireType) diff --git a/pdata/internal/generated_proto_status_test.go b/pdata/internal/generated_proto_status_test.go index 3511595899df..9a1a39286a86 100644 --- a/pdata/internal/generated_proto_status_test.go +++ b/pdata/internal/generated_proto_status_test.go @@ -17,16 +17,17 @@ import ( "go.opentelemetry.io/collector/featuregate" "go.opentelemetry.io/collector/pdata/internal/json" + "go.opentelemetry.io/collector/pdata/internal/metadata" ) func TestCopyStatus(t *testing.T) { for name, src := range genTestEncodingValuesStatus() { for _, pooling := range []bool{true, false} { t.Run(name+"/Pooling="+strconv.FormatBool(pooling), func(t *testing.T) { - prevPooling := UseProtoPooling.IsEnabled() - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), pooling)) + prevPooling := metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), pooling)) defer func() { - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), prevPooling)) + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), prevPooling)) }() dest := NewStatus() @@ -102,10 +103,10 @@ func TestMarshalAndUnmarshalJSONStatus(t *testing.T) { for name, src := range genTestEncodingValuesStatus() { for _, pooling := range []bool{true, false} { t.Run(name+"/Pooling="+strconv.FormatBool(pooling), func(t *testing.T) { - prevPooling := UseProtoPooling.IsEnabled() - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), pooling)) + prevPooling := metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), pooling)) defer func() { - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), prevPooling)) + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), prevPooling)) }() stream := json.BorrowStream(nil) @@ -146,10 +147,10 @@ func TestMarshalAndUnmarshalProtoStatus(t *testing.T) { for name, src := range genTestEncodingValuesStatus() { for _, pooling := range []bool{true, false} { t.Run(name+"/Pooling="+strconv.FormatBool(pooling), func(t *testing.T) { - prevPooling := UseProtoPooling.IsEnabled() - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), pooling)) + prevPooling := metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), pooling)) defer func() { - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), prevPooling)) + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), prevPooling)) }() buf := make([]byte, src.SizeProto()) diff --git a/pdata/internal/generated_proto_sum.go b/pdata/internal/generated_proto_sum.go index 67be5d00f042..d0c601ee809f 100644 --- a/pdata/internal/generated_proto_sum.go +++ b/pdata/internal/generated_proto_sum.go @@ -11,6 +11,7 @@ import ( "sync" "go.opentelemetry.io/collector/pdata/internal/json" + "go.opentelemetry.io/collector/pdata/internal/metadata" "go.opentelemetry.io/collector/pdata/internal/proto" ) @@ -30,7 +31,7 @@ var ( ) func NewSum() *Sum { - if !UseProtoPooling.IsEnabled() { + if !metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() { return &Sum{} } return protoPoolSum.Get().(*Sum) @@ -41,11 +42,10 @@ func DeleteSum(orig *Sum, nullable bool) { return } - if !UseProtoPooling.IsEnabled() { + if !metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() { orig.Reset() return } - for i := range orig.DataPoints { DeleteNumberDataPoint(orig.DataPoints[i], true) } @@ -72,7 +72,6 @@ func CopySum(dest, src *Sum) *Sum { dest.DataPoints = CopyNumberDataPointPtrSlice(dest.DataPoints, src.DataPoints) dest.AggregationTemporality = src.AggregationTemporality - dest.IsMonotonic = src.IsMonotonic return dest @@ -183,10 +182,10 @@ func (orig *Sum) SizeProto() int { l = orig.DataPoints[i].SizeProto() n += 1 + proto.Sov(uint64(l)) + l } - if orig.AggregationTemporality != 0 { + if orig.AggregationTemporality != AggregationTemporality(0) { n += 1 + proto.Sov(uint64(orig.AggregationTemporality)) } - if orig.IsMonotonic { + if orig.IsMonotonic != false { n += 2 } return n @@ -203,12 +202,12 @@ func (orig *Sum) MarshalProto(buf []byte) int { pos-- buf[pos] = 0xa } - if orig.AggregationTemporality != 0 { + if orig.AggregationTemporality != AggregationTemporality(0) { pos = proto.EncodeVarint(buf, pos, uint64(orig.AggregationTemporality)) pos-- buf[pos] = 0x10 } - if orig.IsMonotonic { + if orig.IsMonotonic != false { pos-- if orig.IsMonotonic { buf[pos] = 1 @@ -261,7 +260,6 @@ func (orig *Sum) UnmarshalProto(buf []byte) error { if err != nil { return err } - orig.AggregationTemporality = AggregationTemporality(num) case 3: @@ -273,7 +271,6 @@ func (orig *Sum) UnmarshalProto(buf []byte) error { if err != nil { return err } - orig.IsMonotonic = num != 0 default: pos, err = proto.ConsumeUnknown(buf, pos, wireType) diff --git a/pdata/internal/generated_proto_sum_test.go b/pdata/internal/generated_proto_sum_test.go index ab4ff295e91c..a7d541011005 100644 --- a/pdata/internal/generated_proto_sum_test.go +++ b/pdata/internal/generated_proto_sum_test.go @@ -17,16 +17,17 @@ import ( "go.opentelemetry.io/collector/featuregate" "go.opentelemetry.io/collector/pdata/internal/json" + "go.opentelemetry.io/collector/pdata/internal/metadata" ) func TestCopySum(t *testing.T) { for name, src := range genTestEncodingValuesSum() { for _, pooling := range []bool{true, false} { t.Run(name+"/Pooling="+strconv.FormatBool(pooling), func(t *testing.T) { - prevPooling := UseProtoPooling.IsEnabled() - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), pooling)) + prevPooling := metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), pooling)) defer func() { - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), prevPooling)) + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), prevPooling)) }() dest := NewSum() @@ -102,10 +103,10 @@ func TestMarshalAndUnmarshalJSONSum(t *testing.T) { for name, src := range genTestEncodingValuesSum() { for _, pooling := range []bool{true, false} { t.Run(name+"/Pooling="+strconv.FormatBool(pooling), func(t *testing.T) { - prevPooling := UseProtoPooling.IsEnabled() - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), pooling)) + prevPooling := metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), pooling)) defer func() { - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), prevPooling)) + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), prevPooling)) }() stream := json.BorrowStream(nil) @@ -146,10 +147,10 @@ func TestMarshalAndUnmarshalProtoSum(t *testing.T) { for name, src := range genTestEncodingValuesSum() { for _, pooling := range []bool{true, false} { t.Run(name+"/Pooling="+strconv.FormatBool(pooling), func(t *testing.T) { - prevPooling := UseProtoPooling.IsEnabled() - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), pooling)) + prevPooling := metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), pooling)) defer func() { - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), prevPooling)) + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), prevPooling)) }() buf := make([]byte, src.SizeProto()) diff --git a/pdata/internal/generated_proto_summary.go b/pdata/internal/generated_proto_summary.go index 8d40bd16603c..0b62ef7659d7 100644 --- a/pdata/internal/generated_proto_summary.go +++ b/pdata/internal/generated_proto_summary.go @@ -11,6 +11,7 @@ import ( "sync" "go.opentelemetry.io/collector/pdata/internal/json" + "go.opentelemetry.io/collector/pdata/internal/metadata" "go.opentelemetry.io/collector/pdata/internal/proto" ) @@ -28,7 +29,7 @@ var ( ) func NewSummary() *Summary { - if !UseProtoPooling.IsEnabled() { + if !metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() { return &Summary{} } return protoPoolSummary.Get().(*Summary) @@ -39,15 +40,13 @@ func DeleteSummary(orig *Summary, nullable bool) { return } - if !UseProtoPooling.IsEnabled() { + if !metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() { orig.Reset() return } - for i := range orig.DataPoints { DeleteSummaryDataPoint(orig.DataPoints[i], true) } - orig.Reset() if nullable { protoPoolSummary.Put(orig) diff --git a/pdata/internal/generated_proto_summary_test.go b/pdata/internal/generated_proto_summary_test.go index 52aa9cc051cf..61587b9e1bf2 100644 --- a/pdata/internal/generated_proto_summary_test.go +++ b/pdata/internal/generated_proto_summary_test.go @@ -17,16 +17,17 @@ import ( "go.opentelemetry.io/collector/featuregate" "go.opentelemetry.io/collector/pdata/internal/json" + "go.opentelemetry.io/collector/pdata/internal/metadata" ) func TestCopySummary(t *testing.T) { for name, src := range genTestEncodingValuesSummary() { for _, pooling := range []bool{true, false} { t.Run(name+"/Pooling="+strconv.FormatBool(pooling), func(t *testing.T) { - prevPooling := UseProtoPooling.IsEnabled() - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), pooling)) + prevPooling := metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), pooling)) defer func() { - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), prevPooling)) + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), prevPooling)) }() dest := NewSummary() @@ -102,10 +103,10 @@ func TestMarshalAndUnmarshalJSONSummary(t *testing.T) { for name, src := range genTestEncodingValuesSummary() { for _, pooling := range []bool{true, false} { t.Run(name+"/Pooling="+strconv.FormatBool(pooling), func(t *testing.T) { - prevPooling := UseProtoPooling.IsEnabled() - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), pooling)) + prevPooling := metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), pooling)) defer func() { - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), prevPooling)) + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), prevPooling)) }() stream := json.BorrowStream(nil) @@ -146,10 +147,10 @@ func TestMarshalAndUnmarshalProtoSummary(t *testing.T) { for name, src := range genTestEncodingValuesSummary() { for _, pooling := range []bool{true, false} { t.Run(name+"/Pooling="+strconv.FormatBool(pooling), func(t *testing.T) { - prevPooling := UseProtoPooling.IsEnabled() - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), pooling)) + prevPooling := metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), pooling)) defer func() { - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), prevPooling)) + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), prevPooling)) }() buf := make([]byte, src.SizeProto()) diff --git a/pdata/internal/generated_proto_summarydatapoint.go b/pdata/internal/generated_proto_summarydatapoint.go index bf30987a6698..5402264ee289 100644 --- a/pdata/internal/generated_proto_summarydatapoint.go +++ b/pdata/internal/generated_proto_summarydatapoint.go @@ -13,17 +13,18 @@ import ( "sync" "go.opentelemetry.io/collector/pdata/internal/json" + "go.opentelemetry.io/collector/pdata/internal/metadata" "go.opentelemetry.io/collector/pdata/internal/proto" ) // SummaryDataPoint is a single data point in a timeseries that describes the time-varying values of a Summary of double values. type SummaryDataPoint struct { Attributes []KeyValue + QuantileValues []*SummaryDataPointValueAtQuantile StartTimeUnixNano uint64 TimeUnixNano uint64 Count uint64 Sum float64 - QuantileValues []*SummaryDataPointValueAtQuantile Flags uint32 } @@ -36,7 +37,7 @@ var ( ) func NewSummaryDataPoint() *SummaryDataPoint { - if !UseProtoPooling.IsEnabled() { + if !metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() { return &SummaryDataPoint{} } return protoPoolSummaryDataPoint.Get().(*SummaryDataPoint) @@ -47,14 +48,14 @@ func DeleteSummaryDataPoint(orig *SummaryDataPoint, nullable bool) { return } - if !UseProtoPooling.IsEnabled() { + if !metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() { orig.Reset() return } - for i := range orig.Attributes { DeleteKeyValue(&orig.Attributes[i], false) } + for i := range orig.QuantileValues { DeleteSummaryDataPointValueAtQuantile(orig.QuantileValues[i], true) } @@ -81,13 +82,9 @@ func CopySummaryDataPoint(dest, src *SummaryDataPoint) *SummaryDataPoint { dest.Attributes = CopyKeyValueSlice(dest.Attributes, src.Attributes) dest.StartTimeUnixNano = src.StartTimeUnixNano - dest.TimeUnixNano = src.TimeUnixNano - dest.Count = src.Count - dest.Sum = src.Sum - dest.QuantileValues = CopySummaryDataPointValueAtQuantilePtrSlice(dest.QuantileValues, src.QuantileValues) dest.Flags = src.Flags @@ -233,23 +230,23 @@ func (orig *SummaryDataPoint) SizeProto() int { l = orig.Attributes[i].SizeProto() n += 1 + proto.Sov(uint64(l)) + l } - if orig.StartTimeUnixNano != 0 { + if orig.StartTimeUnixNano != uint64(0) { n += 9 } - if orig.TimeUnixNano != 0 { + if orig.TimeUnixNano != uint64(0) { n += 9 } - if orig.Count != 0 { + if orig.Count != uint64(0) { n += 9 } - if orig.Sum != 0 { + if orig.Sum != float64(0) { n += 9 } for i := range orig.QuantileValues { l = orig.QuantileValues[i].SizeProto() n += 1 + proto.Sov(uint64(l)) + l } - if orig.Flags != 0 { + if orig.Flags != uint32(0) { n += 1 + proto.Sov(uint64(orig.Flags)) } return n @@ -266,25 +263,25 @@ func (orig *SummaryDataPoint) MarshalProto(buf []byte) int { pos-- buf[pos] = 0x3a } - if orig.StartTimeUnixNano != 0 { + if orig.StartTimeUnixNano != uint64(0) { pos -= 8 binary.LittleEndian.PutUint64(buf[pos:], uint64(orig.StartTimeUnixNano)) pos-- buf[pos] = 0x11 } - if orig.TimeUnixNano != 0 { + if orig.TimeUnixNano != uint64(0) { pos -= 8 binary.LittleEndian.PutUint64(buf[pos:], uint64(orig.TimeUnixNano)) pos-- buf[pos] = 0x19 } - if orig.Count != 0 { + if orig.Count != uint64(0) { pos -= 8 binary.LittleEndian.PutUint64(buf[pos:], uint64(orig.Count)) pos-- buf[pos] = 0x21 } - if orig.Sum != 0 { + if orig.Sum != float64(0) { pos -= 8 binary.LittleEndian.PutUint64(buf[pos:], math.Float64bits(orig.Sum)) pos-- @@ -297,7 +294,7 @@ func (orig *SummaryDataPoint) MarshalProto(buf []byte) int { pos-- buf[pos] = 0x32 } - if orig.Flags != 0 { + if orig.Flags != uint32(0) { pos = proto.EncodeVarint(buf, pos, uint64(orig.Flags)) pos-- buf[pos] = 0x40 @@ -381,7 +378,6 @@ func (orig *SummaryDataPoint) UnmarshalProto(buf []byte) error { if err != nil { return err } - orig.Sum = math.Float64frombits(num) case 6: @@ -409,7 +405,6 @@ func (orig *SummaryDataPoint) UnmarshalProto(buf []byte) error { if err != nil { return err } - orig.Flags = uint32(num) default: pos, err = proto.ConsumeUnknown(buf, pos, wireType) diff --git a/pdata/internal/generated_proto_summarydatapoint_test.go b/pdata/internal/generated_proto_summarydatapoint_test.go index dd10cca66522..040c0871162a 100644 --- a/pdata/internal/generated_proto_summarydatapoint_test.go +++ b/pdata/internal/generated_proto_summarydatapoint_test.go @@ -17,16 +17,17 @@ import ( "go.opentelemetry.io/collector/featuregate" "go.opentelemetry.io/collector/pdata/internal/json" + "go.opentelemetry.io/collector/pdata/internal/metadata" ) func TestCopySummaryDataPoint(t *testing.T) { for name, src := range genTestEncodingValuesSummaryDataPoint() { for _, pooling := range []bool{true, false} { t.Run(name+"/Pooling="+strconv.FormatBool(pooling), func(t *testing.T) { - prevPooling := UseProtoPooling.IsEnabled() - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), pooling)) + prevPooling := metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), pooling)) defer func() { - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), prevPooling)) + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), prevPooling)) }() dest := NewSummaryDataPoint() @@ -102,10 +103,10 @@ func TestMarshalAndUnmarshalJSONSummaryDataPoint(t *testing.T) { for name, src := range genTestEncodingValuesSummaryDataPoint() { for _, pooling := range []bool{true, false} { t.Run(name+"/Pooling="+strconv.FormatBool(pooling), func(t *testing.T) { - prevPooling := UseProtoPooling.IsEnabled() - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), pooling)) + prevPooling := metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), pooling)) defer func() { - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), prevPooling)) + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), prevPooling)) }() stream := json.BorrowStream(nil) @@ -146,10 +147,10 @@ func TestMarshalAndUnmarshalProtoSummaryDataPoint(t *testing.T) { for name, src := range genTestEncodingValuesSummaryDataPoint() { for _, pooling := range []bool{true, false} { t.Run(name+"/Pooling="+strconv.FormatBool(pooling), func(t *testing.T) { - prevPooling := UseProtoPooling.IsEnabled() - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), pooling)) + prevPooling := metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), pooling)) defer func() { - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), prevPooling)) + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), prevPooling)) }() buf := make([]byte, src.SizeProto()) diff --git a/pdata/internal/generated_proto_summarydatapointvalueatquantile.go b/pdata/internal/generated_proto_summarydatapointvalueatquantile.go index ae92399aa41d..a2910b738a6e 100644 --- a/pdata/internal/generated_proto_summarydatapointvalueatquantile.go +++ b/pdata/internal/generated_proto_summarydatapointvalueatquantile.go @@ -13,6 +13,7 @@ import ( "sync" "go.opentelemetry.io/collector/pdata/internal/json" + "go.opentelemetry.io/collector/pdata/internal/metadata" "go.opentelemetry.io/collector/pdata/internal/proto" ) @@ -31,7 +32,7 @@ var ( ) func NewSummaryDataPointValueAtQuantile() *SummaryDataPointValueAtQuantile { - if !UseProtoPooling.IsEnabled() { + if !metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() { return &SummaryDataPointValueAtQuantile{} } return protoPoolSummaryDataPointValueAtQuantile.Get().(*SummaryDataPointValueAtQuantile) @@ -42,7 +43,7 @@ func DeleteSummaryDataPointValueAtQuantile(orig *SummaryDataPointValueAtQuantile return } - if !UseProtoPooling.IsEnabled() { + if !metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() { orig.Reset() return } @@ -67,7 +68,6 @@ func CopySummaryDataPointValueAtQuantile(dest, src *SummaryDataPointValueAtQuant dest = NewSummaryDataPointValueAtQuantile() } dest.Quantile = src.Quantile - dest.Value = src.Value return dest @@ -157,10 +157,10 @@ func (orig *SummaryDataPointValueAtQuantile) SizeProto() int { var n int var l int _ = l - if orig.Quantile != 0 { + if orig.Quantile != float64(0) { n += 9 } - if orig.Value != 0 { + if orig.Value != float64(0) { n += 9 } return n @@ -170,13 +170,13 @@ func (orig *SummaryDataPointValueAtQuantile) MarshalProto(buf []byte) int { pos := len(buf) var l int _ = l - if orig.Quantile != 0 { + if orig.Quantile != float64(0) { pos -= 8 binary.LittleEndian.PutUint64(buf[pos:], math.Float64bits(orig.Quantile)) pos-- buf[pos] = 0x9 } - if orig.Value != 0 { + if orig.Value != float64(0) { pos -= 8 binary.LittleEndian.PutUint64(buf[pos:], math.Float64bits(orig.Value)) pos-- @@ -209,7 +209,6 @@ func (orig *SummaryDataPointValueAtQuantile) UnmarshalProto(buf []byte) error { if err != nil { return err } - orig.Quantile = math.Float64frombits(num) case 2: @@ -221,7 +220,6 @@ func (orig *SummaryDataPointValueAtQuantile) UnmarshalProto(buf []byte) error { if err != nil { return err } - orig.Value = math.Float64frombits(num) default: pos, err = proto.ConsumeUnknown(buf, pos, wireType) diff --git a/pdata/internal/generated_proto_summarydatapointvalueatquantile_test.go b/pdata/internal/generated_proto_summarydatapointvalueatquantile_test.go index 3b4ae3654b4b..c6a8bb9a9497 100644 --- a/pdata/internal/generated_proto_summarydatapointvalueatquantile_test.go +++ b/pdata/internal/generated_proto_summarydatapointvalueatquantile_test.go @@ -17,16 +17,17 @@ import ( "go.opentelemetry.io/collector/featuregate" "go.opentelemetry.io/collector/pdata/internal/json" + "go.opentelemetry.io/collector/pdata/internal/metadata" ) func TestCopySummaryDataPointValueAtQuantile(t *testing.T) { for name, src := range genTestEncodingValuesSummaryDataPointValueAtQuantile() { for _, pooling := range []bool{true, false} { t.Run(name+"/Pooling="+strconv.FormatBool(pooling), func(t *testing.T) { - prevPooling := UseProtoPooling.IsEnabled() - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), pooling)) + prevPooling := metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), pooling)) defer func() { - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), prevPooling)) + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), prevPooling)) }() dest := NewSummaryDataPointValueAtQuantile() @@ -102,10 +103,10 @@ func TestMarshalAndUnmarshalJSONSummaryDataPointValueAtQuantile(t *testing.T) { for name, src := range genTestEncodingValuesSummaryDataPointValueAtQuantile() { for _, pooling := range []bool{true, false} { t.Run(name+"/Pooling="+strconv.FormatBool(pooling), func(t *testing.T) { - prevPooling := UseProtoPooling.IsEnabled() - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), pooling)) + prevPooling := metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), pooling)) defer func() { - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), prevPooling)) + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), prevPooling)) }() stream := json.BorrowStream(nil) @@ -146,10 +147,10 @@ func TestMarshalAndUnmarshalProtoSummaryDataPointValueAtQuantile(t *testing.T) { for name, src := range genTestEncodingValuesSummaryDataPointValueAtQuantile() { for _, pooling := range []bool{true, false} { t.Run(name+"/Pooling="+strconv.FormatBool(pooling), func(t *testing.T) { - prevPooling := UseProtoPooling.IsEnabled() - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), pooling)) + prevPooling := metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), pooling)) defer func() { - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), prevPooling)) + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), prevPooling)) }() buf := make([]byte, src.SizeProto()) diff --git a/pdata/internal/generated_proto_tcpaddr.go b/pdata/internal/generated_proto_tcpaddr.go index d2590bdbb1f5..5392f07d0bad 100644 --- a/pdata/internal/generated_proto_tcpaddr.go +++ b/pdata/internal/generated_proto_tcpaddr.go @@ -11,13 +11,14 @@ import ( "sync" "go.opentelemetry.io/collector/pdata/internal/json" + "go.opentelemetry.io/collector/pdata/internal/metadata" "go.opentelemetry.io/collector/pdata/internal/proto" ) type TCPAddr struct { + Zone string IP []byte Port int64 - Zone string } var ( @@ -29,7 +30,7 @@ var ( ) func NewTCPAddr() *TCPAddr { - if !UseProtoPooling.IsEnabled() { + if !metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() { return &TCPAddr{} } return protoPoolTCPAddr.Get().(*TCPAddr) @@ -40,7 +41,7 @@ func DeleteTCPAddr(orig *TCPAddr, nullable bool) { return } - if !UseProtoPooling.IsEnabled() { + if !metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() { orig.Reset() return } @@ -65,9 +66,7 @@ func CopyTCPAddr(dest, src *TCPAddr) *TCPAddr { dest = NewTCPAddr() } dest.IP = src.IP - dest.Port = src.Port - dest.Zone = src.Zone return dest @@ -164,13 +163,15 @@ func (orig *TCPAddr) SizeProto() int { var n int var l int _ = l + l = len(orig.IP) if l > 0 { n += 1 + proto.Sov(uint64(l)) + l } - if orig.Port != 0 { + if orig.Port != int64(0) { n += 1 + proto.Sov(uint64(orig.Port)) } + l = len(orig.Zone) if l > 0 { n += 1 + proto.Sov(uint64(l)) + l @@ -190,7 +191,7 @@ func (orig *TCPAddr) MarshalProto(buf []byte) int { pos-- buf[pos] = 0xa } - if orig.Port != 0 { + if orig.Port != int64(0) { pos = proto.EncodeVarint(buf, pos, uint64(orig.Port)) pos-- buf[pos] = 0x10 @@ -245,7 +246,6 @@ func (orig *TCPAddr) UnmarshalProto(buf []byte) error { if err != nil { return err } - orig.Port = int64(num) case 3: diff --git a/pdata/internal/generated_proto_tcpaddr_test.go b/pdata/internal/generated_proto_tcpaddr_test.go index 8e731f16c41d..24bff3409104 100644 --- a/pdata/internal/generated_proto_tcpaddr_test.go +++ b/pdata/internal/generated_proto_tcpaddr_test.go @@ -17,16 +17,17 @@ import ( "go.opentelemetry.io/collector/featuregate" "go.opentelemetry.io/collector/pdata/internal/json" + "go.opentelemetry.io/collector/pdata/internal/metadata" ) func TestCopyTCPAddr(t *testing.T) { for name, src := range genTestEncodingValuesTCPAddr() { for _, pooling := range []bool{true, false} { t.Run(name+"/Pooling="+strconv.FormatBool(pooling), func(t *testing.T) { - prevPooling := UseProtoPooling.IsEnabled() - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), pooling)) + prevPooling := metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), pooling)) defer func() { - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), prevPooling)) + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), prevPooling)) }() dest := NewTCPAddr() @@ -102,10 +103,10 @@ func TestMarshalAndUnmarshalJSONTCPAddr(t *testing.T) { for name, src := range genTestEncodingValuesTCPAddr() { for _, pooling := range []bool{true, false} { t.Run(name+"/Pooling="+strconv.FormatBool(pooling), func(t *testing.T) { - prevPooling := UseProtoPooling.IsEnabled() - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), pooling)) + prevPooling := metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), pooling)) defer func() { - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), prevPooling)) + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), prevPooling)) }() stream := json.BorrowStream(nil) @@ -146,10 +147,10 @@ func TestMarshalAndUnmarshalProtoTCPAddr(t *testing.T) { for name, src := range genTestEncodingValuesTCPAddr() { for _, pooling := range []bool{true, false} { t.Run(name+"/Pooling="+strconv.FormatBool(pooling), func(t *testing.T) { - prevPooling := UseProtoPooling.IsEnabled() - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), pooling)) + prevPooling := metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), pooling)) defer func() { - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), prevPooling)) + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), prevPooling)) }() buf := make([]byte, src.SizeProto()) diff --git a/pdata/internal/generated_proto_tracesdata.go b/pdata/internal/generated_proto_tracesdata.go index f63549f1cbc5..e81853de7ae2 100644 --- a/pdata/internal/generated_proto_tracesdata.go +++ b/pdata/internal/generated_proto_tracesdata.go @@ -11,6 +11,7 @@ import ( "sync" "go.opentelemetry.io/collector/pdata/internal/json" + "go.opentelemetry.io/collector/pdata/internal/metadata" "go.opentelemetry.io/collector/pdata/internal/proto" ) @@ -30,7 +31,7 @@ var ( ) func NewTracesData() *TracesData { - if !UseProtoPooling.IsEnabled() { + if !metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() { return &TracesData{} } return protoPoolTracesData.Get().(*TracesData) @@ -41,15 +42,13 @@ func DeleteTracesData(orig *TracesData, nullable bool) { return } - if !UseProtoPooling.IsEnabled() { + if !metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() { orig.Reset() return } - for i := range orig.ResourceSpans { DeleteResourceSpans(orig.ResourceSpans[i], true) } - orig.Reset() if nullable { protoPoolTracesData.Put(orig) diff --git a/pdata/internal/generated_proto_tracesdata_test.go b/pdata/internal/generated_proto_tracesdata_test.go index 33c7fdcb3859..797ea5a658cb 100644 --- a/pdata/internal/generated_proto_tracesdata_test.go +++ b/pdata/internal/generated_proto_tracesdata_test.go @@ -17,16 +17,17 @@ import ( "go.opentelemetry.io/collector/featuregate" "go.opentelemetry.io/collector/pdata/internal/json" + "go.opentelemetry.io/collector/pdata/internal/metadata" ) func TestCopyTracesData(t *testing.T) { for name, src := range genTestEncodingValuesTracesData() { for _, pooling := range []bool{true, false} { t.Run(name+"/Pooling="+strconv.FormatBool(pooling), func(t *testing.T) { - prevPooling := UseProtoPooling.IsEnabled() - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), pooling)) + prevPooling := metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), pooling)) defer func() { - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), prevPooling)) + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), prevPooling)) }() dest := NewTracesData() @@ -102,10 +103,10 @@ func TestMarshalAndUnmarshalJSONTracesData(t *testing.T) { for name, src := range genTestEncodingValuesTracesData() { for _, pooling := range []bool{true, false} { t.Run(name+"/Pooling="+strconv.FormatBool(pooling), func(t *testing.T) { - prevPooling := UseProtoPooling.IsEnabled() - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), pooling)) + prevPooling := metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), pooling)) defer func() { - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), prevPooling)) + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), prevPooling)) }() stream := json.BorrowStream(nil) @@ -146,10 +147,10 @@ func TestMarshalAndUnmarshalProtoTracesData(t *testing.T) { for name, src := range genTestEncodingValuesTracesData() { for _, pooling := range []bool{true, false} { t.Run(name+"/Pooling="+strconv.FormatBool(pooling), func(t *testing.T) { - prevPooling := UseProtoPooling.IsEnabled() - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), pooling)) + prevPooling := metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), pooling)) defer func() { - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), prevPooling)) + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), prevPooling)) }() buf := make([]byte, src.SizeProto()) diff --git a/pdata/internal/generated_proto_tracesrequest.go b/pdata/internal/generated_proto_tracesrequest.go index d3e3fd5633d9..a54dedaefbc5 100644 --- a/pdata/internal/generated_proto_tracesrequest.go +++ b/pdata/internal/generated_proto_tracesrequest.go @@ -12,6 +12,7 @@ import ( "sync" "go.opentelemetry.io/collector/pdata/internal/json" + "go.opentelemetry.io/collector/pdata/internal/metadata" "go.opentelemetry.io/collector/pdata/internal/proto" ) @@ -30,7 +31,7 @@ var ( ) func NewTracesRequest() *TracesRequest { - if !UseProtoPooling.IsEnabled() { + if !metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() { return &TracesRequest{} } return protoPoolTracesRequest.Get().(*TracesRequest) @@ -41,11 +42,10 @@ func DeleteTracesRequest(orig *TracesRequest, nullable bool) { return } - if !UseProtoPooling.IsEnabled() { + if !metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() { orig.Reset() return } - DeleteRequestContext(orig.RequestContext, true) DeleteTracesData(&orig.TracesData, false) @@ -173,7 +173,7 @@ func (orig *TracesRequest) SizeProto() int { } l = orig.TracesData.SizeProto() n += 1 + proto.Sov(uint64(l)) + l - if orig.FormatVersion != 0 { + if orig.FormatVersion != uint32(0) { n += 5 } return n @@ -196,7 +196,7 @@ func (orig *TracesRequest) MarshalProto(buf []byte) int { pos-- buf[pos] = 0x1a - if orig.FormatVersion != 0 { + if orig.FormatVersion != uint32(0) { pos -= 4 binary.LittleEndian.PutUint32(buf[pos:], uint32(orig.FormatVersion)) pos-- diff --git a/pdata/internal/generated_proto_tracesrequest_test.go b/pdata/internal/generated_proto_tracesrequest_test.go index de53ebdc7eef..a049e2ecb3f7 100644 --- a/pdata/internal/generated_proto_tracesrequest_test.go +++ b/pdata/internal/generated_proto_tracesrequest_test.go @@ -17,16 +17,17 @@ import ( "go.opentelemetry.io/collector/featuregate" "go.opentelemetry.io/collector/pdata/internal/json" + "go.opentelemetry.io/collector/pdata/internal/metadata" ) func TestCopyTracesRequest(t *testing.T) { for name, src := range genTestEncodingValuesTracesRequest() { for _, pooling := range []bool{true, false} { t.Run(name+"/Pooling="+strconv.FormatBool(pooling), func(t *testing.T) { - prevPooling := UseProtoPooling.IsEnabled() - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), pooling)) + prevPooling := metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), pooling)) defer func() { - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), prevPooling)) + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), prevPooling)) }() dest := NewTracesRequest() @@ -102,10 +103,10 @@ func TestMarshalAndUnmarshalJSONTracesRequest(t *testing.T) { for name, src := range genTestEncodingValuesTracesRequest() { for _, pooling := range []bool{true, false} { t.Run(name+"/Pooling="+strconv.FormatBool(pooling), func(t *testing.T) { - prevPooling := UseProtoPooling.IsEnabled() - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), pooling)) + prevPooling := metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), pooling)) defer func() { - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), prevPooling)) + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), prevPooling)) }() stream := json.BorrowStream(nil) @@ -146,10 +147,10 @@ func TestMarshalAndUnmarshalProtoTracesRequest(t *testing.T) { for name, src := range genTestEncodingValuesTracesRequest() { for _, pooling := range []bool{true, false} { t.Run(name+"/Pooling="+strconv.FormatBool(pooling), func(t *testing.T) { - prevPooling := UseProtoPooling.IsEnabled() - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), pooling)) + prevPooling := metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), pooling)) defer func() { - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), prevPooling)) + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), prevPooling)) }() buf := make([]byte, src.SizeProto()) diff --git a/pdata/internal/generated_proto_udpaddr.go b/pdata/internal/generated_proto_udpaddr.go index f197afd194a9..efd5399419b7 100644 --- a/pdata/internal/generated_proto_udpaddr.go +++ b/pdata/internal/generated_proto_udpaddr.go @@ -11,13 +11,14 @@ import ( "sync" "go.opentelemetry.io/collector/pdata/internal/json" + "go.opentelemetry.io/collector/pdata/internal/metadata" "go.opentelemetry.io/collector/pdata/internal/proto" ) type UDPAddr struct { + Zone string IP []byte Port int64 - Zone string } var ( @@ -29,7 +30,7 @@ var ( ) func NewUDPAddr() *UDPAddr { - if !UseProtoPooling.IsEnabled() { + if !metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() { return &UDPAddr{} } return protoPoolUDPAddr.Get().(*UDPAddr) @@ -40,7 +41,7 @@ func DeleteUDPAddr(orig *UDPAddr, nullable bool) { return } - if !UseProtoPooling.IsEnabled() { + if !metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() { orig.Reset() return } @@ -65,9 +66,7 @@ func CopyUDPAddr(dest, src *UDPAddr) *UDPAddr { dest = NewUDPAddr() } dest.IP = src.IP - dest.Port = src.Port - dest.Zone = src.Zone return dest @@ -164,13 +163,15 @@ func (orig *UDPAddr) SizeProto() int { var n int var l int _ = l + l = len(orig.IP) if l > 0 { n += 1 + proto.Sov(uint64(l)) + l } - if orig.Port != 0 { + if orig.Port != int64(0) { n += 1 + proto.Sov(uint64(orig.Port)) } + l = len(orig.Zone) if l > 0 { n += 1 + proto.Sov(uint64(l)) + l @@ -190,7 +191,7 @@ func (orig *UDPAddr) MarshalProto(buf []byte) int { pos-- buf[pos] = 0xa } - if orig.Port != 0 { + if orig.Port != int64(0) { pos = proto.EncodeVarint(buf, pos, uint64(orig.Port)) pos-- buf[pos] = 0x10 @@ -245,7 +246,6 @@ func (orig *UDPAddr) UnmarshalProto(buf []byte) error { if err != nil { return err } - orig.Port = int64(num) case 3: diff --git a/pdata/internal/generated_proto_udpaddr_test.go b/pdata/internal/generated_proto_udpaddr_test.go index 027e542fe164..0bf446f81f3e 100644 --- a/pdata/internal/generated_proto_udpaddr_test.go +++ b/pdata/internal/generated_proto_udpaddr_test.go @@ -17,16 +17,17 @@ import ( "go.opentelemetry.io/collector/featuregate" "go.opentelemetry.io/collector/pdata/internal/json" + "go.opentelemetry.io/collector/pdata/internal/metadata" ) func TestCopyUDPAddr(t *testing.T) { for name, src := range genTestEncodingValuesUDPAddr() { for _, pooling := range []bool{true, false} { t.Run(name+"/Pooling="+strconv.FormatBool(pooling), func(t *testing.T) { - prevPooling := UseProtoPooling.IsEnabled() - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), pooling)) + prevPooling := metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), pooling)) defer func() { - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), prevPooling)) + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), prevPooling)) }() dest := NewUDPAddr() @@ -102,10 +103,10 @@ func TestMarshalAndUnmarshalJSONUDPAddr(t *testing.T) { for name, src := range genTestEncodingValuesUDPAddr() { for _, pooling := range []bool{true, false} { t.Run(name+"/Pooling="+strconv.FormatBool(pooling), func(t *testing.T) { - prevPooling := UseProtoPooling.IsEnabled() - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), pooling)) + prevPooling := metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), pooling)) defer func() { - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), prevPooling)) + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), prevPooling)) }() stream := json.BorrowStream(nil) @@ -146,10 +147,10 @@ func TestMarshalAndUnmarshalProtoUDPAddr(t *testing.T) { for name, src := range genTestEncodingValuesUDPAddr() { for _, pooling := range []bool{true, false} { t.Run(name+"/Pooling="+strconv.FormatBool(pooling), func(t *testing.T) { - prevPooling := UseProtoPooling.IsEnabled() - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), pooling)) + prevPooling := metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), pooling)) defer func() { - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), prevPooling)) + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), prevPooling)) }() buf := make([]byte, src.SizeProto()) diff --git a/pdata/internal/generated_proto_unixaddr.go b/pdata/internal/generated_proto_unixaddr.go index b7d25686c023..c301df4878b5 100644 --- a/pdata/internal/generated_proto_unixaddr.go +++ b/pdata/internal/generated_proto_unixaddr.go @@ -11,6 +11,7 @@ import ( "sync" "go.opentelemetry.io/collector/pdata/internal/json" + "go.opentelemetry.io/collector/pdata/internal/metadata" "go.opentelemetry.io/collector/pdata/internal/proto" ) @@ -28,7 +29,7 @@ var ( ) func NewUnixAddr() *UnixAddr { - if !UseProtoPooling.IsEnabled() { + if !metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() { return &UnixAddr{} } return protoPoolUnixAddr.Get().(*UnixAddr) @@ -39,7 +40,7 @@ func DeleteUnixAddr(orig *UnixAddr, nullable bool) { return } - if !UseProtoPooling.IsEnabled() { + if !metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() { orig.Reset() return } @@ -64,7 +65,6 @@ func CopyUnixAddr(dest, src *UnixAddr) *UnixAddr { dest = NewUnixAddr() } dest.Name = src.Name - dest.Net = src.Net return dest @@ -154,10 +154,12 @@ func (orig *UnixAddr) SizeProto() int { var n int var l int _ = l + l = len(orig.Name) if l > 0 { n += 1 + proto.Sov(uint64(l)) + l } + l = len(orig.Net) if l > 0 { n += 1 + proto.Sov(uint64(l)) + l diff --git a/pdata/internal/generated_proto_unixaddr_test.go b/pdata/internal/generated_proto_unixaddr_test.go index 5e1ca9d8afce..1ef3264de955 100644 --- a/pdata/internal/generated_proto_unixaddr_test.go +++ b/pdata/internal/generated_proto_unixaddr_test.go @@ -17,16 +17,17 @@ import ( "go.opentelemetry.io/collector/featuregate" "go.opentelemetry.io/collector/pdata/internal/json" + "go.opentelemetry.io/collector/pdata/internal/metadata" ) func TestCopyUnixAddr(t *testing.T) { for name, src := range genTestEncodingValuesUnixAddr() { for _, pooling := range []bool{true, false} { t.Run(name+"/Pooling="+strconv.FormatBool(pooling), func(t *testing.T) { - prevPooling := UseProtoPooling.IsEnabled() - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), pooling)) + prevPooling := metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), pooling)) defer func() { - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), prevPooling)) + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), prevPooling)) }() dest := NewUnixAddr() @@ -102,10 +103,10 @@ func TestMarshalAndUnmarshalJSONUnixAddr(t *testing.T) { for name, src := range genTestEncodingValuesUnixAddr() { for _, pooling := range []bool{true, false} { t.Run(name+"/Pooling="+strconv.FormatBool(pooling), func(t *testing.T) { - prevPooling := UseProtoPooling.IsEnabled() - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), pooling)) + prevPooling := metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), pooling)) defer func() { - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), prevPooling)) + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), prevPooling)) }() stream := json.BorrowStream(nil) @@ -146,10 +147,10 @@ func TestMarshalAndUnmarshalProtoUnixAddr(t *testing.T) { for name, src := range genTestEncodingValuesUnixAddr() { for _, pooling := range []bool{true, false} { t.Run(name+"/Pooling="+strconv.FormatBool(pooling), func(t *testing.T) { - prevPooling := UseProtoPooling.IsEnabled() - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), pooling)) + prevPooling := metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), pooling)) defer func() { - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), prevPooling)) + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), prevPooling)) }() buf := make([]byte, src.SizeProto()) diff --git a/pdata/internal/generated_proto_valuetype.go b/pdata/internal/generated_proto_valuetype.go index 7742846f24a2..676418994a3f 100644 --- a/pdata/internal/generated_proto_valuetype.go +++ b/pdata/internal/generated_proto_valuetype.go @@ -11,6 +11,7 @@ import ( "sync" "go.opentelemetry.io/collector/pdata/internal/json" + "go.opentelemetry.io/collector/pdata/internal/metadata" "go.opentelemetry.io/collector/pdata/internal/proto" ) @@ -29,7 +30,7 @@ var ( ) func NewValueType() *ValueType { - if !UseProtoPooling.IsEnabled() { + if !metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() { return &ValueType{} } return protoPoolValueType.Get().(*ValueType) @@ -40,7 +41,7 @@ func DeleteValueType(orig *ValueType, nullable bool) { return } - if !UseProtoPooling.IsEnabled() { + if !metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() { orig.Reset() return } @@ -65,7 +66,6 @@ func CopyValueType(dest, src *ValueType) *ValueType { dest = NewValueType() } dest.TypeStrindex = src.TypeStrindex - dest.UnitStrindex = src.UnitStrindex return dest @@ -155,10 +155,10 @@ func (orig *ValueType) SizeProto() int { var n int var l int _ = l - if orig.TypeStrindex != 0 { + if orig.TypeStrindex != int32(0) { n += 1 + proto.Sov(uint64(orig.TypeStrindex)) } - if orig.UnitStrindex != 0 { + if orig.UnitStrindex != int32(0) { n += 1 + proto.Sov(uint64(orig.UnitStrindex)) } return n @@ -168,12 +168,12 @@ func (orig *ValueType) MarshalProto(buf []byte) int { pos := len(buf) var l int _ = l - if orig.TypeStrindex != 0 { + if orig.TypeStrindex != int32(0) { pos = proto.EncodeVarint(buf, pos, uint64(orig.TypeStrindex)) pos-- buf[pos] = 0x8 } - if orig.UnitStrindex != 0 { + if orig.UnitStrindex != int32(0) { pos = proto.EncodeVarint(buf, pos, uint64(orig.UnitStrindex)) pos-- buf[pos] = 0x10 @@ -205,7 +205,6 @@ func (orig *ValueType) UnmarshalProto(buf []byte) error { if err != nil { return err } - orig.TypeStrindex = int32(num) case 2: @@ -217,7 +216,6 @@ func (orig *ValueType) UnmarshalProto(buf []byte) error { if err != nil { return err } - orig.UnitStrindex = int32(num) default: pos, err = proto.ConsumeUnknown(buf, pos, wireType) diff --git a/pdata/internal/generated_proto_valuetype_test.go b/pdata/internal/generated_proto_valuetype_test.go index 037945b23ddf..78510c1eec67 100644 --- a/pdata/internal/generated_proto_valuetype_test.go +++ b/pdata/internal/generated_proto_valuetype_test.go @@ -17,16 +17,17 @@ import ( "go.opentelemetry.io/collector/featuregate" "go.opentelemetry.io/collector/pdata/internal/json" + "go.opentelemetry.io/collector/pdata/internal/metadata" ) func TestCopyValueType(t *testing.T) { for name, src := range genTestEncodingValuesValueType() { for _, pooling := range []bool{true, false} { t.Run(name+"/Pooling="+strconv.FormatBool(pooling), func(t *testing.T) { - prevPooling := UseProtoPooling.IsEnabled() - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), pooling)) + prevPooling := metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), pooling)) defer func() { - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), prevPooling)) + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), prevPooling)) }() dest := NewValueType() @@ -102,10 +103,10 @@ func TestMarshalAndUnmarshalJSONValueType(t *testing.T) { for name, src := range genTestEncodingValuesValueType() { for _, pooling := range []bool{true, false} { t.Run(name+"/Pooling="+strconv.FormatBool(pooling), func(t *testing.T) { - prevPooling := UseProtoPooling.IsEnabled() - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), pooling)) + prevPooling := metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), pooling)) defer func() { - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), prevPooling)) + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), prevPooling)) }() stream := json.BorrowStream(nil) @@ -146,10 +147,10 @@ func TestMarshalAndUnmarshalProtoValueType(t *testing.T) { for name, src := range genTestEncodingValuesValueType() { for _, pooling := range []bool{true, false} { t.Run(name+"/Pooling="+strconv.FormatBool(pooling), func(t *testing.T) { - prevPooling := UseProtoPooling.IsEnabled() - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), pooling)) + prevPooling := metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), pooling)) defer func() { - require.NoError(t, featuregate.GlobalRegistry().Set(UseProtoPooling.ID(), prevPooling)) + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), prevPooling)) }() buf := make([]byte, src.SizeProto()) diff --git a/pdata/internal/metadata/generated_feature_gates.go b/pdata/internal/metadata/generated_feature_gates.go new file mode 100644 index 000000000000..2fb2365cffb8 --- /dev/null +++ b/pdata/internal/metadata/generated_feature_gates.go @@ -0,0 +1,24 @@ +// Code generated by mdatagen. DO NOT EDIT. + +package metadata + +import ( + "go.opentelemetry.io/collector/featuregate" +) + +var PdataUseCustomProtoEncodingFeatureGate = featuregate.GlobalRegistry().MustRegister( + "pdata.useCustomProtoEncoding", + featuregate.StageStable, + featuregate.WithRegisterDescription("When enabled, enable custom proto encoding. This is a required step to enable featuregate pdata.useProtoPooling."), + featuregate.WithRegisterReferenceURL("https://github.com/open-telemetry/opentelemetry-collector/issues/13631"), + featuregate.WithRegisterFromVersion("v0.133.0"), + featuregate.WithRegisterToVersion("v0.137.0"), +) + +var PdataUseProtoPoolingFeatureGate = featuregate.GlobalRegistry().MustRegister( + "pdata.useProtoPooling", + featuregate.StageAlpha, + featuregate.WithRegisterDescription("When enabled, enable using local memory pools for underlying data that the pdata messages are pushed to."), + featuregate.WithRegisterReferenceURL("https://github.com/open-telemetry/opentelemetry-collector/issues/13631"), + featuregate.WithRegisterFromVersion("v0.133.0"), +) diff --git a/pdata/internal/proto/marshal.go b/pdata/internal/proto/marshal.go index 1655533a2cee..b4d494e6e548 100644 --- a/pdata/internal/proto/marshal.go +++ b/pdata/internal/proto/marshal.go @@ -8,7 +8,6 @@ func EncodeVarint(buf []byte, offset int, v uint64) int { offset -= Sov(v) base := offset for v >= 1<<7 { - //nolint:gosec buf[offset] = uint8(v&0x7f | 0x80) v >>= 7 offset++ diff --git a/pdata/internal/proto/size.go b/pdata/internal/proto/size.go index 6f48443bf9d4..bfc521475993 100644 --- a/pdata/internal/proto/size.go +++ b/pdata/internal/proto/size.go @@ -12,6 +12,5 @@ func Sov(x uint64) (n int) { } func Soz(x uint64) (n int) { - //nolint:gosec return Sov((x << 1) ^ uint64((int64(x) >> 63))) } diff --git a/pdata/internal/proto/unmarshal.go b/pdata/internal/proto/unmarshal.go index 6ecf5ca3a3a1..b6dc0c79495d 100644 --- a/pdata/internal/proto/unmarshal.go +++ b/pdata/internal/proto/unmarshal.go @@ -89,7 +89,6 @@ func ConsumeLen(buf []byte, pos int) (int, int, error) { if err != nil { return 0, 0, err } - //nolint:gosec length := int(num) if length < 0 { return 0, 0, ErrInvalidLength @@ -116,9 +115,7 @@ func ConsumeTag(buf []byte, pos int) (int32, WireType, int, error) { if err != nil { return 0, 0, 0, err } - //nolint:gosec fieldNum := int32(tag >> 3) - //nolint:gosec wireType := int8(tag & 0x7) if fieldNum <= 0 { return 0, 0, 0, fmt.Errorf("proto: Link: illegal field=%d (tag=%d, pos=%d)", fieldNum, tag, pos) diff --git a/pdata/internal/state.go b/pdata/internal/state.go index 46f10722dc7f..0e1b92185805 100644 --- a/pdata/internal/state.go +++ b/pdata/internal/state.go @@ -4,28 +4,9 @@ package internal // import "go.opentelemetry.io/collector/pdata/internal" import ( "sync/atomic" - - "go.opentelemetry.io/collector/featuregate" -) - -var _ = featuregate.GlobalRegistry().MustRegister( - "pdata.useCustomProtoEncoding", - featuregate.StageStable, - featuregate.WithRegisterDescription("When enabled, enable custom proto encoding. This is required step to enable featuregate pdata.useProtoPooling."), - featuregate.WithRegisterReferenceURL("https://github.com/open-telemetry/opentelemetry-collector/issues/13631"), - featuregate.WithRegisterFromVersion("v0.133.0"), - featuregate.WithRegisterToVersion("v0.137.0"), -) - -var UseProtoPooling = featuregate.GlobalRegistry().MustRegister( - "pdata.useProtoPooling", - featuregate.StageAlpha, - featuregate.WithRegisterDescription("When enabled, enable using local memory pools for underlying data that the pdata messages are pushed to."), - featuregate.WithRegisterReferenceURL("https://github.com/open-telemetry/opentelemetry-collector/issues/13631"), - featuregate.WithRegisterFromVersion("v0.133.0"), ) -// State defines an ownership state of pmetric.Metrics, plog.Logs or ptrace.Traces. +// State defines an ownership state of pmetric.Metrics, plog.Logs, ptrace.Traces or pprofile.Profiles. type State struct { refs atomic.Int32 state uint32 diff --git a/pdata/internal/wrapper_value.go b/pdata/internal/wrapper_value.go index c0220c8f0103..1471d858bc99 100644 --- a/pdata/internal/wrapper_value.go +++ b/pdata/internal/wrapper_value.go @@ -3,6 +3,8 @@ package internal // import "go.opentelemetry.io/collector/pdata/internal" +import "go.opentelemetry.io/collector/pdata/internal/metadata" + type ValueWrapper struct { orig *AnyValue state *State @@ -26,49 +28,49 @@ func GenTestValueWrapper() ValueWrapper { } func NewAnyValueStringValue() *AnyValue_StringValue { - if !UseProtoPooling.IsEnabled() { + if !metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() { return &AnyValue_StringValue{} } return ProtoPoolAnyValue_StringValue.Get().(*AnyValue_StringValue) } func NewAnyValueIntValue() *AnyValue_IntValue { - if !UseProtoPooling.IsEnabled() { + if !metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() { return &AnyValue_IntValue{} } return ProtoPoolAnyValue_IntValue.Get().(*AnyValue_IntValue) } func NewAnyValueBoolValue() *AnyValue_BoolValue { - if !UseProtoPooling.IsEnabled() { + if !metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() { return &AnyValue_BoolValue{} } return ProtoPoolAnyValue_BoolValue.Get().(*AnyValue_BoolValue) } func NewAnyValueDoubleValue() *AnyValue_DoubleValue { - if !UseProtoPooling.IsEnabled() { + if !metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() { return &AnyValue_DoubleValue{} } return ProtoPoolAnyValue_DoubleValue.Get().(*AnyValue_DoubleValue) } func NewAnyValueBytesValue() *AnyValue_BytesValue { - if !UseProtoPooling.IsEnabled() { + if !metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() { return &AnyValue_BytesValue{} } return ProtoPoolAnyValue_BytesValue.Get().(*AnyValue_BytesValue) } func NewAnyValueArrayValue() *AnyValue_ArrayValue { - if !UseProtoPooling.IsEnabled() { + if !metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() { return &AnyValue_ArrayValue{} } return ProtoPoolAnyValue_ArrayValue.Get().(*AnyValue_ArrayValue) } func NewAnyValueKvlistValue() *AnyValue_KvlistValue { - if !UseProtoPooling.IsEnabled() { + if !metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() { return &AnyValue_KvlistValue{} } return ProtoPoolAnyValue_KvlistValue.Get().(*AnyValue_KvlistValue) diff --git a/pdata/metadata.yaml b/pdata/metadata.yaml index a6b702e9a00d..f79a0901b53d 100644 --- a/pdata/metadata.yaml +++ b/pdata/metadata.yaml @@ -10,3 +10,16 @@ status: - dmitryax stability: stable: [traces, metrics, logs] + +feature_gates: + - id: pdata.useCustomProtoEncoding + description: 'When enabled, enable custom proto encoding. This is a required step to enable featuregate pdata.useProtoPooling.' + stage: stable + from_version: 'v0.133.0' + to_version: 'v0.137.0' + reference_url: 'https://github.com/open-telemetry/opentelemetry-collector/issues/13631' + - id: pdata.useProtoPooling + description: 'When enabled, enable using local memory pools for underlying data that the pdata messages are pushed to.' + stage: alpha + from_version: 'v0.133.0' + reference_url: 'https://github.com/open-telemetry/opentelemetry-collector/issues/13631' diff --git a/pdata/pcommon/timestamp.go b/pdata/pcommon/timestamp.go index 037213a0cafb..5fd1758b1bea 100644 --- a/pdata/pcommon/timestamp.go +++ b/pdata/pcommon/timestamp.go @@ -13,13 +13,11 @@ type Timestamp uint64 // NewTimestampFromTime constructs a new Timestamp from the provided time.Time. func NewTimestampFromTime(t time.Time) Timestamp { - //nolint:gosec return Timestamp(uint64(t.UnixNano())) } // AsTime converts this to a time.Time. func (ts Timestamp) AsTime() time.Time { - //nolint:gosec return time.Unix(0, int64(ts)).UTC() } diff --git a/pdata/pcommon/timestamp_test.go b/pdata/pcommon/timestamp_test.go index f9716a58c021..5cdf7ec5abd7 100644 --- a/pdata/pcommon/timestamp_test.go +++ b/pdata/pcommon/timestamp_test.go @@ -12,7 +12,6 @@ import ( func TestUnixNanosConverters(t *testing.T) { t1 := time.Date(2020, 3, 24, 1, 13, 23, 789, time.UTC) - //nolint:gosec tun := Timestamp(t1.UnixNano()) assert.EqualValues(t, uint64(1585012403000000789), tun) diff --git a/pdata/pcommon/value.go b/pdata/pcommon/value.go index f74fa79467b3..3c39e704ed94 100644 --- a/pdata/pcommon/value.go +++ b/pdata/pcommon/value.go @@ -166,7 +166,6 @@ func (v Value) FromRaw(iv any) error { case int64: v.SetInt(tv) case uint: - //nolint:gosec v.SetInt(int64(tv)) case uint8: v.SetInt(int64(tv)) @@ -175,7 +174,6 @@ func (v Value) FromRaw(iv any) error { case uint32: v.SetInt(int64(tv)) case uint64: - //nolint:gosec v.SetInt(int64(tv)) case float32: v.SetDouble(float64(tv)) diff --git a/pdata/plog/config.schema.yaml b/pdata/plog/config.schema.yaml new file mode 100644 index 000000000000..72b00a634c99 --- /dev/null +++ b/pdata/plog/config.schema.yaml @@ -0,0 +1,12 @@ +$defs: + log_record_flags: + description: LogRecordFlags defines flags for the LogRecord. The 8 least significant bits are the trace flags as defined in W3C Trace Context specification. 24 most significant bits are reserved and must be set to 0. + type: integer + x-customType: uint32 + logs: + description: 'Logs is the top-level struct that is propagated through the logs pipeline. Use NewLogs to create new instance, zero-initialized instance is not valid for use. This is a reference type, if passed by value and callee modifies it the caller will see the modification. Must use NewLogs function to create new instances. Important: zero-initialized instance is not valid for use.' + $ref: go.opentelemetry.io/collector/pdata/internal.logs_wrapper + severity_number: + description: SeverityNumber represents severity number of a log record. + type: integer + x-customType: int32 diff --git a/pdata/plog/fuzz_test.go b/pdata/plog/fuzz_test.go index c08067ac8a64..3a53b1034b0e 100644 --- a/pdata/plog/fuzz_test.go +++ b/pdata/plog/fuzz_test.go @@ -12,7 +12,7 @@ import ( var unexpectedBytes = "expected the same bytes from unmarshaling and marshaling." -func FuzzUnmarshalJsonLogs(f *testing.F) { +func FuzzUnmarshalJSONLogs(f *testing.F) { f.Fuzz(func(t *testing.T, data []byte) { u1 := &JSONUnmarshaler{} ld1, err := u1.UnmarshalLogs(data) diff --git a/pdata/plog/pb_test.go b/pdata/plog/pb_test.go index 3e6bb27b995b..d443a52e4c74 100644 --- a/pdata/plog/pb_test.go +++ b/pdata/plog/pb_test.go @@ -73,9 +73,9 @@ func TestProtoSizerEmptyLogs(t *testing.T) { assert.Equal(t, 0, sizer.LogsSize(NewLogs())) } -func BenchmarkLogsToProto(b *testing.B) { +func BenchmarkLogsToProto2k(b *testing.B) { marshaler := &ProtoMarshaler{} - logs := generateBenchmarkLogs(128) + logs := generateBenchmarkLogs(2_000) for b.Loop() { buf, err := marshaler.MarshalLogs(logs) @@ -84,10 +84,10 @@ func BenchmarkLogsToProto(b *testing.B) { } } -func BenchmarkLogsFromProto(b *testing.B) { +func BenchmarkLogsFromProto2k(b *testing.B) { marshaler := &ProtoMarshaler{} unmarshaler := &ProtoUnmarshaler{} - baseLogs := generateBenchmarkLogs(128) + baseLogs := generateBenchmarkLogs(2_000) buf, err := marshaler.MarshalLogs(baseLogs) require.NoError(b, err) assert.NotEmpty(b, buf) diff --git a/pdata/plog/plogotlp/grpc_test.go b/pdata/plog/plogotlp/grpc_test.go index 7700888267c4..16fe78f5ff79 100644 --- a/pdata/plog/plogotlp/grpc_test.go +++ b/pdata/plog/plogotlp/grpc_test.go @@ -27,11 +27,9 @@ func TestGrpc(t *testing.T) { s := grpc.NewServer() RegisterGRPCServer(s, &fakeLogsServer{t: t}) wg := sync.WaitGroup{} - wg.Add(1) - go func() { - defer wg.Done() + wg.Go(func() { assert.NoError(t, s.Serve(lis)) - }() + }) t.Cleanup(func() { s.Stop() wg.Wait() @@ -60,11 +58,9 @@ func TestGrpcError(t *testing.T) { s := grpc.NewServer() RegisterGRPCServer(s, &fakeLogsServer{t: t, err: errors.New("my error")}) wg := sync.WaitGroup{} - wg.Add(1) - go func() { - defer wg.Done() + wg.Go(func() { assert.NoError(t, s.Serve(lis)) - }() + }) t.Cleanup(func() { s.Stop() wg.Wait() diff --git a/pdata/pmetric/generated_exemplar.go b/pdata/pmetric/generated_exemplar.go index e0681f6d17f9..6fbc8d025dc3 100644 --- a/pdata/pmetric/generated_exemplar.go +++ b/pdata/pmetric/generated_exemplar.go @@ -8,6 +8,7 @@ package pmetric import ( "go.opentelemetry.io/collector/pdata/internal" + "go.opentelemetry.io/collector/pdata/internal/metadata" "go.opentelemetry.io/collector/pdata/pcommon" ) @@ -88,16 +89,14 @@ func (ms Exemplar) DoubleValue() float64 { func (ms Exemplar) SetDoubleValue(v float64) { ms.state.AssertMutable() var ov *internal.Exemplar_AsDouble - if !internal.UseProtoPooling.IsEnabled() { + if !metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() { ov = &internal.Exemplar_AsDouble{} } else { ov = internal.ProtoPoolExemplar_AsDouble.Get().(*internal.Exemplar_AsDouble) } ov.AsDouble = v ms.orig.Value = ov -} - -// IntValue returns the int associated with this Exemplar. +} // IntValue returns the int associated with this Exemplar. func (ms Exemplar) IntValue() int64 { return ms.orig.GetAsInt() } @@ -106,7 +105,7 @@ func (ms Exemplar) IntValue() int64 { func (ms Exemplar) SetIntValue(v int64) { ms.state.AssertMutable() var ov *internal.Exemplar_AsInt - if !internal.UseProtoPooling.IsEnabled() { + if !metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() { ov = &internal.Exemplar_AsInt{} } else { ov = internal.ProtoPoolExemplar_AsInt.Get().(*internal.Exemplar_AsInt) diff --git a/pdata/pmetric/generated_exemplar_test.go b/pdata/pmetric/generated_exemplar_test.go index fedeff3200f3..141e5bef675f 100644 --- a/pdata/pmetric/generated_exemplar_test.go +++ b/pdata/pmetric/generated_exemplar_test.go @@ -72,7 +72,6 @@ func TestExemplar_DoubleValue(t *testing.T) { sharedState.MarkReadOnly() assert.Panics(t, func() { newExemplar(internal.NewExemplar(), sharedState).SetDoubleValue(float64(3.1415926)) }) } - func TestExemplar_IntValue(t *testing.T) { ms := NewExemplar() assert.Equal(t, int64(0), ms.IntValue()) diff --git a/pdata/pmetric/generated_exponentialhistogramdatapoint.go b/pdata/pmetric/generated_exponentialhistogramdatapoint.go index 168fdebb97ad..d21bb1410252 100644 --- a/pdata/pmetric/generated_exponentialhistogramdatapoint.go +++ b/pdata/pmetric/generated_exponentialhistogramdatapoint.go @@ -91,25 +91,25 @@ func (ms ExponentialHistogramDataPoint) SetCount(v uint64) { // Sum returns the sum associated with this ExponentialHistogramDataPoint. func (ms ExponentialHistogramDataPoint) Sum() float64 { - return ms.orig.GetSum() + return ms.orig.Sum } // HasSum returns true if the ExponentialHistogramDataPoint contains a // Sum value otherwise. func (ms ExponentialHistogramDataPoint) HasSum() bool { - return ms.orig.Sum_ != nil + return ms.orig.HasSum() } // SetSum replaces the sum associated with this ExponentialHistogramDataPoint. func (ms ExponentialHistogramDataPoint) SetSum(v float64) { ms.state.AssertMutable() - ms.orig.Sum_ = &internal.ExponentialHistogramDataPoint_Sum{Sum: v} + ms.orig.SetSum(v) } // RemoveSum removes the sum associated with this ExponentialHistogramDataPoint. func (ms ExponentialHistogramDataPoint) RemoveSum() { ms.state.AssertMutable() - ms.orig.Sum_ = nil + ms.orig.RemoveSum() } // Scale returns the scale associated with this ExponentialHistogramDataPoint. @@ -162,48 +162,48 @@ func (ms ExponentialHistogramDataPoint) Exemplars() ExemplarSlice { // Min returns the min associated with this ExponentialHistogramDataPoint. func (ms ExponentialHistogramDataPoint) Min() float64 { - return ms.orig.GetMin() + return ms.orig.Min } // HasMin returns true if the ExponentialHistogramDataPoint contains a // Min value otherwise. func (ms ExponentialHistogramDataPoint) HasMin() bool { - return ms.orig.Min_ != nil + return ms.orig.HasMin() } // SetMin replaces the min associated with this ExponentialHistogramDataPoint. func (ms ExponentialHistogramDataPoint) SetMin(v float64) { ms.state.AssertMutable() - ms.orig.Min_ = &internal.ExponentialHistogramDataPoint_Min{Min: v} + ms.orig.SetMin(v) } // RemoveMin removes the min associated with this ExponentialHistogramDataPoint. func (ms ExponentialHistogramDataPoint) RemoveMin() { ms.state.AssertMutable() - ms.orig.Min_ = nil + ms.orig.RemoveMin() } // Max returns the max associated with this ExponentialHistogramDataPoint. func (ms ExponentialHistogramDataPoint) Max() float64 { - return ms.orig.GetMax() + return ms.orig.Max } // HasMax returns true if the ExponentialHistogramDataPoint contains a // Max value otherwise. func (ms ExponentialHistogramDataPoint) HasMax() bool { - return ms.orig.Max_ != nil + return ms.orig.HasMax() } // SetMax replaces the max associated with this ExponentialHistogramDataPoint. func (ms ExponentialHistogramDataPoint) SetMax(v float64) { ms.state.AssertMutable() - ms.orig.Max_ = &internal.ExponentialHistogramDataPoint_Max{Max: v} + ms.orig.SetMax(v) } // RemoveMax removes the max associated with this ExponentialHistogramDataPoint. func (ms ExponentialHistogramDataPoint) RemoveMax() { ms.state.AssertMutable() - ms.orig.Max_ = nil + ms.orig.RemoveMax() } // ZeroThreshold returns the zerothreshold associated with this ExponentialHistogramDataPoint. diff --git a/pdata/pmetric/generated_histogramdatapoint.go b/pdata/pmetric/generated_histogramdatapoint.go index 3ed9090a5c15..8426506ec66f 100644 --- a/pdata/pmetric/generated_histogramdatapoint.go +++ b/pdata/pmetric/generated_histogramdatapoint.go @@ -88,25 +88,25 @@ func (ms HistogramDataPoint) SetCount(v uint64) { // Sum returns the sum associated with this HistogramDataPoint. func (ms HistogramDataPoint) Sum() float64 { - return ms.orig.GetSum() + return ms.orig.Sum } // HasSum returns true if the HistogramDataPoint contains a // Sum value otherwise. func (ms HistogramDataPoint) HasSum() bool { - return ms.orig.Sum_ != nil + return ms.orig.HasSum() } // SetSum replaces the sum associated with this HistogramDataPoint. func (ms HistogramDataPoint) SetSum(v float64) { ms.state.AssertMutable() - ms.orig.Sum_ = &internal.HistogramDataPoint_Sum{Sum: v} + ms.orig.SetSum(v) } // RemoveSum removes the sum associated with this HistogramDataPoint. func (ms HistogramDataPoint) RemoveSum() { ms.state.AssertMutable() - ms.orig.Sum_ = nil + ms.orig.RemoveSum() } // BucketCounts returns the BucketCounts associated with this HistogramDataPoint. @@ -137,48 +137,48 @@ func (ms HistogramDataPoint) SetFlags(v DataPointFlags) { // Min returns the min associated with this HistogramDataPoint. func (ms HistogramDataPoint) Min() float64 { - return ms.orig.GetMin() + return ms.orig.Min } // HasMin returns true if the HistogramDataPoint contains a // Min value otherwise. func (ms HistogramDataPoint) HasMin() bool { - return ms.orig.Min_ != nil + return ms.orig.HasMin() } // SetMin replaces the min associated with this HistogramDataPoint. func (ms HistogramDataPoint) SetMin(v float64) { ms.state.AssertMutable() - ms.orig.Min_ = &internal.HistogramDataPoint_Min{Min: v} + ms.orig.SetMin(v) } // RemoveMin removes the min associated with this HistogramDataPoint. func (ms HistogramDataPoint) RemoveMin() { ms.state.AssertMutable() - ms.orig.Min_ = nil + ms.orig.RemoveMin() } // Max returns the max associated with this HistogramDataPoint. func (ms HistogramDataPoint) Max() float64 { - return ms.orig.GetMax() + return ms.orig.Max } // HasMax returns true if the HistogramDataPoint contains a // Max value otherwise. func (ms HistogramDataPoint) HasMax() bool { - return ms.orig.Max_ != nil + return ms.orig.HasMax() } // SetMax replaces the max associated with this HistogramDataPoint. func (ms HistogramDataPoint) SetMax(v float64) { ms.state.AssertMutable() - ms.orig.Max_ = &internal.HistogramDataPoint_Max{Max: v} + ms.orig.SetMax(v) } // RemoveMax removes the max associated with this HistogramDataPoint. func (ms HistogramDataPoint) RemoveMax() { ms.state.AssertMutable() - ms.orig.Max_ = nil + ms.orig.RemoveMax() } // CopyTo copies all properties from the current struct overriding the destination. diff --git a/pdata/pmetric/generated_metric.go b/pdata/pmetric/generated_metric.go index 04eebe8e09af..6d83515adf35 100644 --- a/pdata/pmetric/generated_metric.go +++ b/pdata/pmetric/generated_metric.go @@ -8,6 +8,7 @@ package pmetric import ( "go.opentelemetry.io/collector/pdata/internal" + "go.opentelemetry.io/collector/pdata/internal/metadata" "go.opentelemetry.io/collector/pdata/pcommon" ) @@ -122,7 +123,7 @@ func (ms Metric) Gauge() Gauge { func (ms Metric) SetEmptyGauge() Gauge { ms.state.AssertMutable() var ov *internal.Metric_Gauge - if !internal.UseProtoPooling.IsEnabled() { + if !metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() { ov = &internal.Metric_Gauge{} } else { ov = internal.ProtoPoolMetric_Gauge.Get().(*internal.Metric_Gauge) @@ -130,10 +131,7 @@ func (ms Metric) SetEmptyGauge() Gauge { ov.Gauge = internal.NewGauge() ms.orig.Data = ov return newGauge(ov.Gauge, ms.state) -} - -// Sum returns the sum associated with this Metric. -// +} // Sum returns the sum associated with this Metric. // Calling this function when Type() != MetricTypeSum returns an invalid // zero-initialized instance of Sum. Note that using such Sum instance can cause panic. // @@ -154,7 +152,7 @@ func (ms Metric) Sum() Sum { func (ms Metric) SetEmptySum() Sum { ms.state.AssertMutable() var ov *internal.Metric_Sum - if !internal.UseProtoPooling.IsEnabled() { + if !metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() { ov = &internal.Metric_Sum{} } else { ov = internal.ProtoPoolMetric_Sum.Get().(*internal.Metric_Sum) @@ -162,10 +160,7 @@ func (ms Metric) SetEmptySum() Sum { ov.Sum = internal.NewSum() ms.orig.Data = ov return newSum(ov.Sum, ms.state) -} - -// Histogram returns the histogram associated with this Metric. -// +} // Histogram returns the histogram associated with this Metric. // Calling this function when Type() != MetricTypeHistogram returns an invalid // zero-initialized instance of Histogram. Note that using such Histogram instance can cause panic. // @@ -186,7 +181,7 @@ func (ms Metric) Histogram() Histogram { func (ms Metric) SetEmptyHistogram() Histogram { ms.state.AssertMutable() var ov *internal.Metric_Histogram - if !internal.UseProtoPooling.IsEnabled() { + if !metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() { ov = &internal.Metric_Histogram{} } else { ov = internal.ProtoPoolMetric_Histogram.Get().(*internal.Metric_Histogram) @@ -194,10 +189,7 @@ func (ms Metric) SetEmptyHistogram() Histogram { ov.Histogram = internal.NewHistogram() ms.orig.Data = ov return newHistogram(ov.Histogram, ms.state) -} - -// ExponentialHistogram returns the exponentialhistogram associated with this Metric. -// +} // ExponentialHistogram returns the exponentialhistogram associated with this Metric. // Calling this function when Type() != MetricTypeExponentialHistogram returns an invalid // zero-initialized instance of ExponentialHistogram. Note that using such ExponentialHistogram instance can cause panic. // @@ -218,7 +210,7 @@ func (ms Metric) ExponentialHistogram() ExponentialHistogram { func (ms Metric) SetEmptyExponentialHistogram() ExponentialHistogram { ms.state.AssertMutable() var ov *internal.Metric_ExponentialHistogram - if !internal.UseProtoPooling.IsEnabled() { + if !metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() { ov = &internal.Metric_ExponentialHistogram{} } else { ov = internal.ProtoPoolMetric_ExponentialHistogram.Get().(*internal.Metric_ExponentialHistogram) @@ -226,10 +218,7 @@ func (ms Metric) SetEmptyExponentialHistogram() ExponentialHistogram { ov.ExponentialHistogram = internal.NewExponentialHistogram() ms.orig.Data = ov return newExponentialHistogram(ov.ExponentialHistogram, ms.state) -} - -// Summary returns the summary associated with this Metric. -// +} // Summary returns the summary associated with this Metric. // Calling this function when Type() != MetricTypeSummary returns an invalid // zero-initialized instance of Summary. Note that using such Summary instance can cause panic. // @@ -250,7 +239,7 @@ func (ms Metric) Summary() Summary { func (ms Metric) SetEmptySummary() Summary { ms.state.AssertMutable() var ov *internal.Metric_Summary - if !internal.UseProtoPooling.IsEnabled() { + if !metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() { ov = &internal.Metric_Summary{} } else { ov = internal.ProtoPoolMetric_Summary.Get().(*internal.Metric_Summary) diff --git a/pdata/pmetric/generated_metric_test.go b/pdata/pmetric/generated_metric_test.go index 70f91cb3dab5..cce7e34316e2 100644 --- a/pdata/pmetric/generated_metric_test.go +++ b/pdata/pmetric/generated_metric_test.go @@ -88,7 +88,6 @@ func TestMetric_Gauge(t *testing.T) { sharedState.MarkReadOnly() assert.Panics(t, func() { newMetric(internal.NewMetric(), sharedState).SetEmptyGauge() }) } - func TestMetric_Sum(t *testing.T) { ms := NewMetric() ms.SetEmptySum() @@ -100,7 +99,6 @@ func TestMetric_Sum(t *testing.T) { sharedState.MarkReadOnly() assert.Panics(t, func() { newMetric(internal.NewMetric(), sharedState).SetEmptySum() }) } - func TestMetric_Histogram(t *testing.T) { ms := NewMetric() ms.SetEmptyHistogram() @@ -112,7 +110,6 @@ func TestMetric_Histogram(t *testing.T) { sharedState.MarkReadOnly() assert.Panics(t, func() { newMetric(internal.NewMetric(), sharedState).SetEmptyHistogram() }) } - func TestMetric_ExponentialHistogram(t *testing.T) { ms := NewMetric() ms.SetEmptyExponentialHistogram() @@ -124,7 +121,6 @@ func TestMetric_ExponentialHistogram(t *testing.T) { sharedState.MarkReadOnly() assert.Panics(t, func() { newMetric(internal.NewMetric(), sharedState).SetEmptyExponentialHistogram() }) } - func TestMetric_Summary(t *testing.T) { ms := NewMetric() ms.SetEmptySummary() diff --git a/pdata/pmetric/generated_numberdatapoint.go b/pdata/pmetric/generated_numberdatapoint.go index e61eba8a8c55..fd66c724694b 100644 --- a/pdata/pmetric/generated_numberdatapoint.go +++ b/pdata/pmetric/generated_numberdatapoint.go @@ -8,6 +8,7 @@ package pmetric import ( "go.opentelemetry.io/collector/pdata/internal" + "go.opentelemetry.io/collector/pdata/internal/metadata" "go.opentelemetry.io/collector/pdata/pcommon" ) @@ -96,16 +97,14 @@ func (ms NumberDataPoint) DoubleValue() float64 { func (ms NumberDataPoint) SetDoubleValue(v float64) { ms.state.AssertMutable() var ov *internal.NumberDataPoint_AsDouble - if !internal.UseProtoPooling.IsEnabled() { + if !metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() { ov = &internal.NumberDataPoint_AsDouble{} } else { ov = internal.ProtoPoolNumberDataPoint_AsDouble.Get().(*internal.NumberDataPoint_AsDouble) } ov.AsDouble = v ms.orig.Value = ov -} - -// IntValue returns the int associated with this NumberDataPoint. +} // IntValue returns the int associated with this NumberDataPoint. func (ms NumberDataPoint) IntValue() int64 { return ms.orig.GetAsInt() } @@ -114,7 +113,7 @@ func (ms NumberDataPoint) IntValue() int64 { func (ms NumberDataPoint) SetIntValue(v int64) { ms.state.AssertMutable() var ov *internal.NumberDataPoint_AsInt - if !internal.UseProtoPooling.IsEnabled() { + if !metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() { ov = &internal.NumberDataPoint_AsInt{} } else { ov = internal.ProtoPoolNumberDataPoint_AsInt.Get().(*internal.NumberDataPoint_AsInt) diff --git a/pdata/pmetric/generated_numberdatapoint_test.go b/pdata/pmetric/generated_numberdatapoint_test.go index e1c70248a192..710a426876cd 100644 --- a/pdata/pmetric/generated_numberdatapoint_test.go +++ b/pdata/pmetric/generated_numberdatapoint_test.go @@ -82,7 +82,6 @@ func TestNumberDataPoint_DoubleValue(t *testing.T) { newNumberDataPoint(internal.NewNumberDataPoint(), sharedState).SetDoubleValue(float64(3.1415926)) }) } - func TestNumberDataPoint_IntValue(t *testing.T) { ms := NewNumberDataPoint() assert.Equal(t, int64(0), ms.IntValue()) diff --git a/pdata/pmetric/pb_test.go b/pdata/pmetric/pb_test.go index a153f843fd09..62a7e6169212 100644 --- a/pdata/pmetric/pb_test.go +++ b/pdata/pmetric/pb_test.go @@ -73,9 +73,9 @@ func TestProtoSizerEmptyMetrics(t *testing.T) { assert.Equal(t, 0, sizer.MetricsSize(NewMetrics())) } -func BenchmarkMetricsToProto(b *testing.B) { +func BenchmarkMetricsToProto2k(b *testing.B) { marshaler := &ProtoMarshaler{} - metrics := generateBenchmarkMetrics(128) + metrics := generateBenchmarkMetrics(2_000) for b.Loop() { buf, err := marshaler.MarshalMetrics(metrics) @@ -84,10 +84,10 @@ func BenchmarkMetricsToProto(b *testing.B) { } } -func BenchmarkMetricsFromProto(b *testing.B) { +func BenchmarkMetricsFromProto10k(b *testing.B) { marshaler := &ProtoMarshaler{} unmarshaler := &ProtoUnmarshaler{} - baseMetrics := generateBenchmarkMetrics(128) + baseMetrics := generateBenchmarkMetrics(2_000) buf, err := marshaler.MarshalMetrics(baseMetrics) require.NoError(b, err) assert.NotEmpty(b, buf) diff --git a/pdata/pmetric/pmetricotlp/grpc_test.go b/pdata/pmetric/pmetricotlp/grpc_test.go index f31c5b1cf89f..11321e4782cd 100644 --- a/pdata/pmetric/pmetricotlp/grpc_test.go +++ b/pdata/pmetric/pmetricotlp/grpc_test.go @@ -27,11 +27,9 @@ func TestGrpc(t *testing.T) { s := grpc.NewServer() RegisterGRPCServer(s, &fakeMetricsServer{t: t}) wg := sync.WaitGroup{} - wg.Add(1) - go func() { - defer wg.Done() + wg.Go(func() { assert.NoError(t, s.Serve(lis)) - }() + }) t.Cleanup(func() { s.Stop() wg.Wait() @@ -60,11 +58,9 @@ func TestGrpcError(t *testing.T) { s := grpc.NewServer() RegisterGRPCServer(s, &fakeMetricsServer{t: t, err: errors.New("my error")}) wg := sync.WaitGroup{} - wg.Add(1) - go func() { - defer wg.Done() + wg.Go(func() { assert.NoError(t, s.Serve(lis)) - }() + }) t.Cleanup(func() { s.Stop() wg.Wait() diff --git a/pdata/pprofile/aggregation_temporality.go b/pdata/pprofile/aggregation_temporality.go index ca4a52d84bfb..8855f1f6be68 100644 --- a/pdata/pprofile/aggregation_temporality.go +++ b/pdata/pprofile/aggregation_temporality.go @@ -10,18 +10,28 @@ import ( // AggregationTemporality specifies the method of aggregating metric values, // either DELTA (change since last report) or CUMULATIVE (total since a fixed // start time). +// +// Deprecated: [v0.146.0] Type was removed without replacement in the Profiles signal. type AggregationTemporality int32 const ( // AggregationTemporalityUnspecified is the default AggregationTemporality, it MUST NOT be used. + // + // Deprecated: [v0.146.0] This is no longer supported by the Profiles signal. AggregationTemporalityUnspecified = AggregationTemporality(internal.AggregationTemporality_AGGREGATION_TEMPORALITY_UNSPECIFIED) // AggregationTemporalityDelta is a AggregationTemporality for a metric aggregator which reports changes since last report time. + // + // Deprecated: [v0.146.0] This is no longer supported by the Profiles signal. AggregationTemporalityDelta = AggregationTemporality(internal.AggregationTemporality_AGGREGATION_TEMPORALITY_DELTA) // AggregationTemporalityCumulative is a AggregationTemporality for a metric aggregator which reports changes since a fixed start time. + // + // Deprecated: [v0.146.0] This is no longer supported by the Profiles signal. AggregationTemporalityCumulative = AggregationTemporality(internal.AggregationTemporality_AGGREGATION_TEMPORALITY_CUMULATIVE) ) // String returns the string representation of the AggregationTemporality. +// +// Deprecated: [v0.146.0] Type was removed without replacement in the Profiles signal. func (at AggregationTemporality) String() string { switch at { case AggregationTemporalityUnspecified: diff --git a/pdata/pprofile/attributes.go b/pdata/pprofile/attributes.go index 8e70cea8d760..7ba37948ae0e 100644 --- a/pdata/pprofile/attributes.go +++ b/pdata/pprofile/attributes.go @@ -41,7 +41,7 @@ func SetAttribute(table KeyValueAndUnitSlice, attr KeyValueAndUnit) (int32, erro if j > math.MaxInt32 { return 0, errTooManyAttributeTableEntries } - return int32(j), nil //nolint:gosec // G115 overflow checked + return int32(j), nil } } @@ -50,5 +50,5 @@ func SetAttribute(table KeyValueAndUnitSlice, attr KeyValueAndUnit) (int32, erro } attr.CopyTo(table.AppendEmpty()) - return int32(table.Len() - 1), nil //nolint:gosec // G115 overflow checked + return int32(table.Len() - 1), nil } diff --git a/pdata/pprofile/attributes_test.go b/pdata/pprofile/attributes_test.go index cd4e20021170..829b256d9b70 100644 --- a/pdata/pprofile/attributes_test.go +++ b/pdata/pprofile/attributes_test.go @@ -58,7 +58,7 @@ func BenchmarkFromAttributeIndices(b *testing.B) { dic.StringTable().Append(fmt.Sprintf("key_%d", i)) att := table.AppendEmpty() - att.SetKeyStrindex(int32(dic.StringTable().Len())) //nolint:gosec // overflow impossible in test + att.SetKeyStrindex(int32(dic.StringTable().Len())) att.Value().SetStr(fmt.Sprintf("value_%d", i)) } @@ -101,7 +101,7 @@ func TestSetAttribute(t *testing.T) { idx, err = SetAttribute(table, attr2) require.NoError(t, err) assert.Equal(t, 2, table.Len()) - assert.Equal(t, int32(table.Len()-1), idx) //nolint:gosec // G115 + assert.Equal(t, int32(table.Len()-1), idx) // Set an existing value idx, err = SetAttribute(table, attr) @@ -112,7 +112,7 @@ func TestSetAttribute(t *testing.T) { idx, err = SetAttribute(table, attr2) require.NoError(t, err) assert.Equal(t, 2, table.Len()) - assert.Equal(t, int32(table.Len()-1), idx) //nolint:gosec // G115 + assert.Equal(t, int32(table.Len()-1), idx) } func BenchmarkSetAttribute(b *testing.B) { @@ -160,7 +160,7 @@ func BenchmarkSetAttribute(b *testing.B) { runBefore: func(_ *testing.B, table KeyValueAndUnitSlice) { for i := range 100 { l := table.AppendEmpty() - l.SetKeyStrindex(int32(i)) //nolint:gosec // overflow checked + l.SetKeyStrindex(int32(i)) } }, }, diff --git a/pdata/pprofile/dictionary_helpers.go b/pdata/pprofile/dictionary_helpers.go new file mode 100644 index 000000000000..4f1fa43c2f0a --- /dev/null +++ b/pdata/pprofile/dictionary_helpers.go @@ -0,0 +1,160 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +package pprofile // import "go.opentelemetry.io/collector/pdata/pprofile" + +import ( + "go.opentelemetry.io/collector/pdata/internal" + "go.opentelemetry.io/collector/pdata/internal/metadata" + "go.opentelemetry.io/collector/pdata/pcommon" +) + +// mapKeyValues returns the underlying KeyValue slice of a pcommon.Map. +func mapKeyValues(m pcommon.Map) []internal.KeyValue { + return *internal.GetMapOrig(internal.MapWrapper(m)) +} + +// resolveProfilesReferences walks through all profiles data after unmarshaling +// and resolves any string_value_ref and key_ref to their actual string values. +// This ensures the pdata API works transparently with referenced strings. +func resolveProfilesReferences(profiles Profiles) { + dict := profiles.Dictionary() + + // Resolve references in resource attributes + for i := 0; i < profiles.ResourceProfiles().Len(); i++ { + rp := profiles.ResourceProfiles().At(i) + resolveKeyValueReferences(dict, mapKeyValues(rp.Resource().Attributes())) + + // Resolve references in scope attributes + for j := 0; j < rp.ScopeProfiles().Len(); j++ { + sp := rp.ScopeProfiles().At(j) + resolveKeyValueReferences(dict, mapKeyValues(sp.Scope().Attributes())) + } + } +} + +// resolveKeyValueReferences resolves key_ref and string_value_ref in a KeyValue slice +func resolveKeyValueReferences(dict ProfilesDictionary, kvs []internal.KeyValue) { + for i := range kvs { + kv := &kvs[i] + // Resolve key_ref if set + if kv.KeyStrindex >= 0 { + idx := int(kv.KeyStrindex) + if idx < dict.StringTable().Len() { + kv.Key = dict.StringTable().At(idx) + // N.b. keep KeyStrindex set to optimize re-marshaling. This is + // technically a violation of the proto spec, but acceptable + // for the in-memory pdata API since keys are immutable. + } + } + // Resolve string_value_ref if set + resolveAnyValueReference(dict, &kv.Value) + } +} + +// resolveAnyValueReference resolves string_value_ref in an AnyValue +func resolveAnyValueReference(dict ProfilesDictionary, anyValue *internal.AnyValue) { + if ref, ok := anyValue.Value.(*internal.AnyValue_StringValueStrindex); ok && ref.StringValueStrindex != 0 { + idx := int(ref.StringValueStrindex) + if idx >= 0 && idx < dict.StringTable().Len() { + str := dict.StringTable().At(idx) + var ov *internal.AnyValue_StringValue + if !metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() { + ov = &internal.AnyValue_StringValue{} + } else { + ov = internal.ProtoPoolAnyValue_StringValue.Get().(*internal.AnyValue_StringValue) + } + ov.StringValue = str + anyValue.Value = ov + } + } else if kvList, ok := anyValue.Value.(*internal.AnyValue_KvlistValue); ok && kvList.KvlistValue != nil { + resolveKeyValueReferences(dict, kvList.KvlistValue.Values) + } else if arrVal, ok := anyValue.Value.(*internal.AnyValue_ArrayValue); ok && arrVal.ArrayValue != nil { + for i := 0; i < len(arrVal.ArrayValue.Values); i++ { + resolveAnyValueReference(dict, &arrVal.ArrayValue.Values[i]) + } + } +} + +// convertProfilesToReferences walks through all profiles data before marshaling +// and converts string values to references for efficient transmission. +// This builds up the string table in the dictionary and replaces strings with refs. +func convertProfilesToReferences(profiles Profiles) { + dict := profiles.Dictionary() + stringTable := dict.StringTable() + + // Map for quick string lookups - only allocate if needed + var stringIndex map[string]int32 + getStringIndex := func(s string) int32 { + if stringIndex == nil { + stringIndex = make(map[string]int32, stringTable.Len()) + for i := 0; i < stringTable.Len(); i++ { + stringIndex[stringTable.At(i)] = int32(i) + } + } + + if idx, ok := stringIndex[s]; ok { + return idx + } + idx := int32(stringTable.Len()) + stringTable.Append(s) + stringIndex[s] = idx + return idx + } + + // Convert strings in resource attributes + for i := 0; i < profiles.ResourceProfiles().Len(); i++ { + rp := profiles.ResourceProfiles().At(i) + convertKeyValueToReferences(getStringIndex, mapKeyValues(rp.Resource().Attributes())) + + // Convert strings in scope attributes + for j := 0; j < rp.ScopeProfiles().Len(); j++ { + sp := rp.ScopeProfiles().At(j) + convertKeyValueToReferences(getStringIndex, mapKeyValues(sp.Scope().Attributes())) + } + } +} + +// convertKeyValueToReferences converts string keys and values to references in a KeyValue slice +func convertKeyValueToReferences(getStringIndex func(string) int32, kvs []internal.KeyValue) { + for i := range kvs { + kv := &kvs[i] + + // Convert key to reference + if kv.Key != "" && kv.KeyStrindex == 0 { + kv.KeyStrindex = getStringIndex(kv.Key) + kv.Key = "" + } + + // Convert string values to references + convertAnyValueToReference(getStringIndex, &kv.Value) + } +} + +// convertAnyValueToReference converts string values to string_value_ref +func convertAnyValueToReference(getStringIndex func(string) int32, anyValue *internal.AnyValue) { + // Skip if already a reference + if _, ok := anyValue.Value.(*internal.AnyValue_StringValueStrindex); ok { + return + } + + if strVal, ok := anyValue.Value.(*internal.AnyValue_StringValue); ok && strVal.StringValue != "" { + // Convert to reference + idx := getStringIndex(strVal.StringValue) + var ov *internal.AnyValue_StringValueStrindex + if !metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() { + ov = &internal.AnyValue_StringValueStrindex{} + } else { + ov = internal.ProtoPoolAnyValue_StringValueStrindex.Get().(*internal.AnyValue_StringValueStrindex) + } + ov.StringValueStrindex = idx + anyValue.Value = ov + } else if kvList, ok := anyValue.Value.(*internal.AnyValue_KvlistValue); ok && kvList.KvlistValue != nil { + convertKeyValueToReferences(getStringIndex, kvList.KvlistValue.Values) + } else if arrVal, ok := anyValue.Value.(*internal.AnyValue_ArrayValue); ok && arrVal.ArrayValue != nil { + // Recursively convert arrays + for i := 0; i < len(arrVal.ArrayValue.Values); i++ { + convertAnyValueToReference(getStringIndex, &arrVal.ArrayValue.Values[i]) + } + } +} diff --git a/pdata/pprofile/dictionary_helpers_test.go b/pdata/pprofile/dictionary_helpers_test.go new file mode 100644 index 000000000000..e721a68f2e1d --- /dev/null +++ b/pdata/pprofile/dictionary_helpers_test.go @@ -0,0 +1,534 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +package pprofile + +import ( + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + + "go.opentelemetry.io/collector/featuregate" + "go.opentelemetry.io/collector/pdata/internal" + "go.opentelemetry.io/collector/pdata/internal/metadata" +) + +func TestResolveProfilesReferencesEmpty(t *testing.T) { + profiles := NewProfiles() + // Should not panic on empty profiles + resolveProfilesReferences(profiles) + assert.Equal(t, 0, profiles.ResourceProfiles().Len()) +} + +func TestResolveProfilesReferencesWithKeyRef(t *testing.T) { + profiles := NewProfiles() + dict := profiles.Dictionary() + dict.StringTable().Append("") // index 0 + dict.StringTable().Append("test-key") + dict.StringTable().Append("test-value") + + rp := profiles.ResourceProfiles().AppendEmpty() + attrs := rp.Resource().Attributes() + + // Manually create a KeyValue with key_ref + mapOrig := internal.GetMapOrig(internal.MapWrapper(attrs)) + *mapOrig = append(*mapOrig, internal.KeyValue{ + KeyStrindex: 1, // references "test-key" + Value: internal.AnyValue{ + Value: &internal.AnyValue_StringValueStrindex{ + StringValueStrindex: 2, // references "test-value" + }, + }, + }) + + resolveProfilesReferences(profiles) + + // Verify key_ref was resolved + kv := &(*mapOrig)[0] + assert.Equal(t, "test-key", kv.Key) + + // Verify string_value_ref was resolved + strVal, ok := kv.Value.Value.(*internal.AnyValue_StringValue) + assert.True(t, ok) + assert.Equal(t, "test-value", strVal.StringValue) +} + +func TestResolveProfilesReferencesInvalidIndices(t *testing.T) { + profiles := NewProfiles() + dict := profiles.Dictionary() + dict.StringTable().Append("") // index 0 + dict.StringTable().Append("valid") + + rp := profiles.ResourceProfiles().AppendEmpty() + attrs := rp.Resource().Attributes() + + mapOrig := internal.GetMapOrig(internal.MapWrapper(attrs)) + *mapOrig = append(*mapOrig, internal.KeyValue{ + Key: "fallback-key", + KeyStrindex: 999, // invalid index + Value: internal.AnyValue{ + Value: &internal.AnyValue_StringValueStrindex{ + StringValueStrindex: 999, // invalid index + }, + }, + }) + + resolveProfilesReferences(profiles) + + // Key should remain unchanged since ref is invalid + kv := &(*mapOrig)[0] + assert.Equal(t, "fallback-key", kv.Key) + + // Value should remain as StringValueStrindex since index is invalid + _, ok := kv.Value.Value.(*internal.AnyValue_StringValueStrindex) + assert.True(t, ok) +} + +func TestResolveAnyValueReferenceWithPooling(t *testing.T) { + // Test with pooling enabled + prevPooling := metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), true)) + defer func() { + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), prevPooling)) + }() + + profiles := NewProfiles() + dict := profiles.Dictionary() + dict.StringTable().Append("") + dict.StringTable().Append("pooled-value") + + anyVal := &internal.AnyValue{ + Value: &internal.AnyValue_StringValueStrindex{ + StringValueStrindex: 1, + }, + } + + resolveAnyValueReference(dict, anyVal) + + strVal, ok := anyVal.Value.(*internal.AnyValue_StringValue) + assert.True(t, ok) + assert.Equal(t, "pooled-value", strVal.StringValue) +} + +func TestResolveAnyValueReferenceNestedKvList(t *testing.T) { + profiles := NewProfiles() + dict := profiles.Dictionary() + dict.StringTable().Append("") + dict.StringTable().Append("nested-key") + dict.StringTable().Append("nested-value") + + kvList := &internal.KeyValueList{ + Values: []internal.KeyValue{ + { + KeyStrindex: 1, // references "nested-key" + Value: internal.AnyValue{ + Value: &internal.AnyValue_StringValueStrindex{ + StringValueStrindex: 2, // references "nested-value" + }, + }, + }, + }, + } + + anyVal := &internal.AnyValue{ + Value: &internal.AnyValue_KvlistValue{ + KvlistValue: kvList, + }, + } + + resolveAnyValueReference(dict, anyVal) + + // Verify nested key_ref was resolved + assert.Equal(t, "nested-key", kvList.Values[0].Key) + + // Verify nested value was resolved + strVal, ok := kvList.Values[0].Value.Value.(*internal.AnyValue_StringValue) + assert.True(t, ok) + assert.Equal(t, "nested-value", strVal.StringValue) +} + +func TestResolveAnyValueReferenceNestedArray(t *testing.T) { + profiles := NewProfiles() + dict := profiles.Dictionary() + dict.StringTable().Append("") + dict.StringTable().Append("array-item-1") + dict.StringTable().Append("array-item-2") + + arrVal := &internal.ArrayValue{ + Values: []internal.AnyValue{ + { + Value: &internal.AnyValue_StringValueStrindex{ + StringValueStrindex: 1, + }, + }, + { + Value: &internal.AnyValue_StringValueStrindex{ + StringValueStrindex: 2, + }, + }, + }, + } + + anyVal := &internal.AnyValue{ + Value: &internal.AnyValue_ArrayValue{ + ArrayValue: arrVal, + }, + } + + resolveAnyValueReference(dict, anyVal) + + // Verify both array items were resolved + strVal1, ok := arrVal.Values[0].Value.(*internal.AnyValue_StringValue) + assert.True(t, ok) + assert.Equal(t, "array-item-1", strVal1.StringValue) + + strVal2, ok := arrVal.Values[1].Value.(*internal.AnyValue_StringValue) + assert.True(t, ok) + assert.Equal(t, "array-item-2", strVal2.StringValue) +} + +func TestConvertProfilesToReferencesEmpty(t *testing.T) { + profiles := NewProfiles() + dict := profiles.Dictionary() + dict.StringTable().Append("") + + convertProfilesToReferences(profiles) + + // Should only have the initial empty string + assert.Equal(t, 1, dict.StringTable().Len()) +} + +func TestConvertProfilesToReferencesDeduplication(t *testing.T) { + profiles := NewProfiles() + dict := profiles.Dictionary() + dict.StringTable().Append("") + + rp := profiles.ResourceProfiles().AppendEmpty() + rp.Resource().Attributes().PutStr("key1", "duplicated-value") + rp.Resource().Attributes().PutStr("key2", "duplicated-value") + rp.Resource().Attributes().PutStr("key3", "unique-value") + + convertProfilesToReferences(profiles) + + // Should have: "", "key1", "duplicated-value", "key2", "key3", "unique-value" + // But key1, key2, key3 might share indices if they're also deduplicated + // At minimum: "", "key1", "duplicated-value", "key2", "key3", "unique-value" = 6 + assert.GreaterOrEqual(t, dict.StringTable().Len(), 5) + + // Verify references were created + mapOrig := internal.GetMapOrig(internal.MapWrapper(rp.Resource().Attributes())) + for i := 0; i < len(*mapOrig); i++ { + kv := &(*mapOrig)[i] + assert.NotEqual(t, int32(0), kv.KeyStrindex, "Key should have a reference") + + // Values should be converted to StringValueStrindex + _, ok := kv.Value.Value.(*internal.AnyValue_StringValueStrindex) + assert.True(t, ok, "Value should be converted to StringValueStrindex") + } +} + +func TestConvertAnyValueToReferenceWithPooling(t *testing.T) { + prevPooling := metadata.PdataUseProtoPoolingFeatureGate.IsEnabled() + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), true)) + defer func() { + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.PdataUseProtoPoolingFeatureGate.ID(), prevPooling)) + }() + + stringIndex := make(map[string]int32) + stringIndex["test-value"] = 5 + + getStringIndex := func(s string) int32 { + if idx, ok := stringIndex[s]; ok { + return idx + } + idx := int32(len(stringIndex)) + stringIndex[s] = idx + return idx + } + + anyVal := &internal.AnyValue{ + Value: &internal.AnyValue_StringValue{ + StringValue: "test-value", + }, + } + + convertAnyValueToReference(getStringIndex, anyVal) + + refVal, ok := anyVal.Value.(*internal.AnyValue_StringValueStrindex) + assert.True(t, ok) + assert.Equal(t, int32(5), refVal.StringValueStrindex) +} + +func TestConvertAnyValueToReferenceEmptyString(t *testing.T) { + stringIndex := make(map[string]int32) + stringIndex[""] = 0 + + getStringIndex := func(s string) int32 { + if idx, ok := stringIndex[s]; ok { + return idx + } + idx := int32(len(stringIndex)) + stringIndex[s] = idx + return idx + } + + anyVal := &internal.AnyValue{ + Value: &internal.AnyValue_StringValue{ + StringValue: "", // empty string should not be converted + }, + } + + convertAnyValueToReference(getStringIndex, anyVal) + + // Empty string should remain as StringValue, not converted to ref + _, ok := anyVal.Value.(*internal.AnyValue_StringValue) + assert.True(t, ok) +} + +func TestConvertAnyValueToReferenceNestedKvList(t *testing.T) { + stringIndex := make(map[string]int32) + stringIndex[""] = 0 + + counter := int32(1) + getStringIndex := func(s string) int32 { + if idx, ok := stringIndex[s]; ok { + return idx + } + idx := counter + counter++ + stringIndex[s] = idx + return idx + } + + kvList := &internal.KeyValueList{ + Values: []internal.KeyValue{ + { + Key: "nested-key", + Value: internal.AnyValue{ + Value: &internal.AnyValue_StringValue{ + StringValue: "nested-value", + }, + }, + }, + }, + } + + anyVal := &internal.AnyValue{ + Value: &internal.AnyValue_KvlistValue{ + KvlistValue: kvList, + }, + } + + convertAnyValueToReference(getStringIndex, anyVal) + + // Verify nested key was converted + assert.NotEqual(t, int32(0), kvList.Values[0].KeyStrindex) + + // Verify nested value was converted + _, ok := kvList.Values[0].Value.Value.(*internal.AnyValue_StringValueStrindex) + assert.True(t, ok) +} + +func TestConvertAnyValueToReferenceNestedArray(t *testing.T) { + stringIndex := make(map[string]int32) + counter := int32(0) + + getStringIndex := func(s string) int32 { + if idx, ok := stringIndex[s]; ok { + return idx + } + idx := counter + counter++ + stringIndex[s] = idx + return idx + } + + arrVal := &internal.ArrayValue{ + Values: []internal.AnyValue{ + { + Value: &internal.AnyValue_StringValue{ + StringValue: "array-item", + }, + }, + }, + } + + anyVal := &internal.AnyValue{ + Value: &internal.AnyValue_ArrayValue{ + ArrayValue: arrVal, + }, + } + + convertAnyValueToReference(getStringIndex, anyVal) + + // Verify array item was converted + _, ok := arrVal.Values[0].Value.(*internal.AnyValue_StringValueStrindex) + assert.True(t, ok) +} + +func TestConvertMapToReferencesEmptyKey(t *testing.T) { + profiles := NewProfiles() + rp := profiles.ResourceProfiles().AppendEmpty() + attrs := rp.Resource().Attributes() + + // Manually add a KeyValue with empty key + mapOrig := internal.GetMapOrig(internal.MapWrapper(attrs)) + *mapOrig = append(*mapOrig, internal.KeyValue{ + Key: "", // empty key should not be converted + Value: internal.AnyValue{ + Value: &internal.AnyValue_StringValue{ + StringValue: "value", + }, + }, + }) + + getStringIndex := func(_ string) int32 { + return 1 + } + + convertKeyValueToReferences(getStringIndex, mapKeyValues(attrs)) + + // Empty key should not have KeyStrindex set + kv := &(*mapOrig)[0] + assert.Equal(t, int32(0), kv.KeyStrindex) +} + +func TestConvertMapToReferencesExistingKeyRef(t *testing.T) { + profiles := NewProfiles() + rp := profiles.ResourceProfiles().AppendEmpty() + attrs := rp.Resource().Attributes() + + // Manually add a KeyValue with existing KeyStrindex + mapOrig := internal.GetMapOrig(internal.MapWrapper(attrs)) + *mapOrig = append(*mapOrig, internal.KeyValue{ + Key: "test-key", + KeyStrindex: 5, // already has a ref + Value: internal.AnyValue{ + Value: &internal.AnyValue_StringValue{ + StringValue: "value", + }, + }, + }) + + getStringIndex := func(_ string) int32 { + return 99 + } + + convertKeyValueToReferences(getStringIndex, mapKeyValues(attrs)) + + // KeyStrindex should remain unchanged + kv := &(*mapOrig)[0] + assert.Equal(t, int32(5), kv.KeyStrindex) +} + +func TestResolveAnyValueReferenceNonStringTypes(t *testing.T) { + profiles := NewProfiles() + dict := profiles.Dictionary() + dict.StringTable().Append("") + + // Test with int value (should not be affected) + anyVal := &internal.AnyValue{ + Value: &internal.AnyValue_IntValue{ + IntValue: 42, + }, + } + + resolveAnyValueReference(dict, anyVal) + + // Should remain as IntValue + intVal, ok := anyVal.Value.(*internal.AnyValue_IntValue) + assert.True(t, ok) + assert.Equal(t, int64(42), intVal.IntValue) +} + +func TestConvertMapToReferencesClearsKey(t *testing.T) { + profiles := NewProfiles() + rp := profiles.ResourceProfiles().AppendEmpty() + attrs := rp.Resource().Attributes() + + mapOrig := internal.GetMapOrig(internal.MapWrapper(attrs)) + *mapOrig = append(*mapOrig, internal.KeyValue{ + Key: "my-key", + Value: internal.AnyValue{ + Value: &internal.AnyValue_StringValue{ + StringValue: "my-value", + }, + }, + }) + + getStringIndex := func(s string) int32 { + if s == "my-key" { + return 1 + } + return 2 + } + + convertKeyValueToReferences(getStringIndex, mapKeyValues(attrs)) + + kv := &(*mapOrig)[0] + // key_ref should be set + assert.Equal(t, int32(1), kv.KeyStrindex) + // key MUST NOT be set when key_ref is used (per proto spec) + assert.Empty(t, kv.Key, "Key must be cleared when KeyStrindex is set") +} + +func TestConvertAnyValueToReferenceNestedKvListClearsKey(t *testing.T) { + stringIndex := make(map[string]int32) + counter := int32(1) + getStringIndex := func(s string) int32 { + if idx, ok := stringIndex[s]; ok { + return idx + } + idx := counter + counter++ + stringIndex[s] = idx + return idx + } + + kvList := &internal.KeyValueList{ + Values: []internal.KeyValue{ + { + Key: "nested-key", + Value: internal.AnyValue{ + Value: &internal.AnyValue_StringValue{ + StringValue: "nested-value", + }, + }, + }, + }, + } + + anyVal := &internal.AnyValue{ + Value: &internal.AnyValue_KvlistValue{ + KvlistValue: kvList, + }, + } + + convertAnyValueToReference(getStringIndex, anyVal) + + // key_ref should be set + assert.NotEqual(t, int32(0), kvList.Values[0].KeyStrindex) + // key MUST NOT be set when key_ref is used (per proto spec) + assert.Empty(t, kvList.Values[0].Key, "Key must be cleared when KeyStrindex is set in nested kvlist") +} + +func TestConvertAnyValueToReferenceNonStringTypes(t *testing.T) { + getStringIndex := func(_ string) int32 { + return 0 + } + + // Test with bool value (should not be affected) + anyVal := &internal.AnyValue{ + Value: &internal.AnyValue_BoolValue{ + BoolValue: true, + }, + } + + convertAnyValueToReference(getStringIndex, anyVal) + + // Should remain as BoolValue + boolVal, ok := anyVal.Value.(*internal.AnyValue_BoolValue) + assert.True(t, ok) + assert.True(t, boolVal.BoolValue) +} diff --git a/pdata/pprofile/function.go b/pdata/pprofile/function.go index 021cb68a167b..10bb1af91260 100644 --- a/pdata/pprofile/function.go +++ b/pdata/pprofile/function.go @@ -17,7 +17,7 @@ func (fn Function) Equal(val Function) bool { // dictionary to another. func (fn Function) switchDictionary(src, dst ProfilesDictionary) error { if fn.NameStrindex() > 0 { - if src.StringTable().Len() < int(fn.NameStrindex()) { + if src.StringTable().Len() <= int(fn.NameStrindex()) { return fmt.Errorf("invalid name index %d", fn.NameStrindex()) } @@ -29,7 +29,7 @@ func (fn Function) switchDictionary(src, dst ProfilesDictionary) error { } if fn.SystemNameStrindex() > 0 { - if src.StringTable().Len() < int(fn.SystemNameStrindex()) { + if src.StringTable().Len() <= int(fn.SystemNameStrindex()) { return fmt.Errorf("invalid system name index %d", fn.SystemNameStrindex()) } @@ -41,7 +41,7 @@ func (fn Function) switchDictionary(src, dst ProfilesDictionary) error { } if fn.FilenameStrindex() > 0 { - if src.StringTable().Len() < int(fn.FilenameStrindex()) { + if src.StringTable().Len() <= int(fn.FilenameStrindex()) { return fmt.Errorf("invalid filename index %d", fn.FilenameStrindex()) } diff --git a/pdata/pprofile/function_test.go b/pdata/pprofile/function_test.go index f5ef9b6259f7..ff7c7cf7c45b 100644 --- a/pdata/pprofile/function_test.go +++ b/pdata/pprofile/function_test.go @@ -138,6 +138,29 @@ func TestFunctionSwitchDictionary(t *testing.T) { wantDictionary: NewProfilesDictionary(), wantErr: errors.New("invalid name index 1"), }, + { + name: "with a name index equal to the source table length (boundary condition)", + function: func() Function { + fn := NewFunction() + fn.SetNameStrindex(2) // Index 2 with length 2 (indices 0,1 are valid) + return fn + }(), + + src: func() ProfilesDictionary { + d := NewProfilesDictionary() + d.StringTable().Append("", "test") // Length 2: indices 0,1 valid + return d + }(), + dst: NewProfilesDictionary(), + + wantFunction: func() Function { + fn := NewFunction() + fn.SetNameStrindex(2) + return fn + }(), + wantDictionary: NewProfilesDictionary(), + wantErr: errors.New("invalid name index 2"), + }, { name: "with an existing system name", function: func() Function { @@ -187,6 +210,29 @@ func TestFunctionSwitchDictionary(t *testing.T) { wantDictionary: NewProfilesDictionary(), wantErr: errors.New("invalid system name index 1"), }, + { + name: "with a system name index equal to the source table length (boundary condition)", + function: func() Function { + fn := NewFunction() + fn.SetSystemNameStrindex(2) + return fn + }(), + + src: func() ProfilesDictionary { + d := NewProfilesDictionary() + d.StringTable().Append("", "test") + return d + }(), + dst: NewProfilesDictionary(), + + wantFunction: func() Function { + fn := NewFunction() + fn.SetSystemNameStrindex(2) + return fn + }(), + wantDictionary: NewProfilesDictionary(), + wantErr: errors.New("invalid system name index 2"), + }, { name: "with an existing filename", function: func() Function { @@ -236,6 +282,29 @@ func TestFunctionSwitchDictionary(t *testing.T) { wantDictionary: NewProfilesDictionary(), wantErr: errors.New("invalid filename index 1"), }, + { + name: "with a filename index equal to the source table length (boundary condition)", + function: func() Function { + fn := NewFunction() + fn.SetFilenameStrindex(2) + return fn + }(), + + src: func() ProfilesDictionary { + d := NewProfilesDictionary() + d.StringTable().Append("", "test") + return d + }(), + dst: NewProfilesDictionary(), + + wantFunction: func() Function { + fn := NewFunction() + fn.SetFilenameStrindex(2) + return fn + }(), + wantDictionary: NewProfilesDictionary(), + wantErr: errors.New("invalid filename index 2"), + }, } { t.Run(tt.name, func(t *testing.T) { fn := tt.function diff --git a/pdata/pprofile/functions.go b/pdata/pprofile/functions.go index b2ce057bd661..e97f182042c5 100644 --- a/pdata/pprofile/functions.go +++ b/pdata/pprofile/functions.go @@ -18,7 +18,7 @@ func SetFunction(table FunctionSlice, fn Function) (int32, error) { if j > math.MaxInt32 { return 0, errTooManyFunctionTableEntries } - return int32(j), nil //nolint:gosec // G115 overflow checked + return int32(j), nil } } @@ -27,5 +27,5 @@ func SetFunction(table FunctionSlice, fn Function) (int32, error) { } fn.CopyTo(table.AppendEmpty()) - return int32(table.Len() - 1), nil //nolint:gosec // G115 overflow checked + return int32(table.Len() - 1), nil } diff --git a/pdata/pprofile/functions_test.go b/pdata/pprofile/functions_test.go index 101531b454c3..4c7022f4687b 100644 --- a/pdata/pprofile/functions_test.go +++ b/pdata/pprofile/functions_test.go @@ -37,7 +37,7 @@ func TestSetFunction(t *testing.T) { idx, err = SetFunction(table, f2) require.NoError(t, err) assert.Equal(t, 2, table.Len()) - assert.Equal(t, int32(table.Len()-1), idx) //nolint:gosec // G115 + assert.Equal(t, int32(table.Len()-1), idx) // Set an existing function idx, err = SetFunction(table, f) @@ -48,7 +48,7 @@ func TestSetFunction(t *testing.T) { idx, err = SetFunction(table, f2) require.NoError(t, err) assert.Equal(t, 2, table.Len()) - assert.Equal(t, int32(table.Len()-1), idx) //nolint:gosec // G115 + assert.Equal(t, int32(table.Len()-1), idx) } func BenchmarkSetFunction(b *testing.B) { @@ -96,7 +96,7 @@ func BenchmarkSetFunction(b *testing.B) { runBefore: func(_ *testing.B, table FunctionSlice) { for i := range 100 { f := table.AppendEmpty() - f.SetNameStrindex(int32(i)) //nolint:gosec // overflow checked + f.SetNameStrindex(int32(i)) } }, }, diff --git a/pdata/pprofile/generated_sample.go b/pdata/pprofile/generated_sample.go index c50d09d7f4d3..76ac29ea1b55 100644 --- a/pdata/pprofile/generated_sample.go +++ b/pdata/pprofile/generated_sample.go @@ -59,11 +59,6 @@ func (ms Sample) SetStackIndex(v int32) { ms.orig.StackIndex = v } -// Values returns the Values associated with this Sample. -func (ms Sample) Values() pcommon.Int64Slice { - return pcommon.Int64Slice(internal.NewInt64SliceWrapper(&ms.orig.Values, ms.state)) -} - // AttributeIndices returns the AttributeIndices associated with this Sample. func (ms Sample) AttributeIndices() pcommon.Int32Slice { return pcommon.Int32Slice(internal.NewInt32SliceWrapper(&ms.orig.AttributeIndices, ms.state)) @@ -80,6 +75,11 @@ func (ms Sample) SetLinkIndex(v int32) { ms.orig.LinkIndex = v } +// Values returns the Values associated with this Sample. +func (ms Sample) Values() pcommon.Int64Slice { + return pcommon.Int64Slice(internal.NewInt64SliceWrapper(&ms.orig.Values, ms.state)) +} + // TimestampsUnixNano returns the TimestampsUnixNano associated with this Sample. func (ms Sample) TimestampsUnixNano() pcommon.UInt64Slice { return pcommon.UInt64Slice(internal.NewUInt64SliceWrapper(&ms.orig.TimestampsUnixNano, ms.state)) diff --git a/pdata/pprofile/generated_sample_test.go b/pdata/pprofile/generated_sample_test.go index 6be62676ba46..62aeee761a98 100644 --- a/pdata/pprofile/generated_sample_test.go +++ b/pdata/pprofile/generated_sample_test.go @@ -52,13 +52,6 @@ func TestSample_StackIndex(t *testing.T) { assert.Panics(t, func() { newSample(internal.NewSample(), sharedState).SetStackIndex(int32(13)) }) } -func TestSample_Values(t *testing.T) { - ms := NewSample() - assert.Equal(t, pcommon.NewInt64Slice(), ms.Values()) - ms.orig.Values = internal.GenTestInt64Slice() - assert.Equal(t, pcommon.Int64Slice(internal.GenTestInt64SliceWrapper()), ms.Values()) -} - func TestSample_AttributeIndices(t *testing.T) { ms := NewSample() assert.Equal(t, pcommon.NewInt32Slice(), ms.AttributeIndices()) @@ -76,6 +69,13 @@ func TestSample_LinkIndex(t *testing.T) { assert.Panics(t, func() { newSample(internal.NewSample(), sharedState).SetLinkIndex(int32(13)) }) } +func TestSample_Values(t *testing.T) { + ms := NewSample() + assert.Equal(t, pcommon.NewInt64Slice(), ms.Values()) + ms.orig.Values = internal.GenTestInt64Slice() + assert.Equal(t, pcommon.Int64Slice(internal.GenTestInt64SliceWrapper()), ms.Values()) +} + func TestSample_TimestampsUnixNano(t *testing.T) { ms := NewSample() assert.Equal(t, pcommon.NewUInt64Slice(), ms.TimestampsUnixNano()) diff --git a/pdata/pprofile/go.mod b/pdata/pprofile/go.mod index 57aab8f773a7..d252afba2e70 100644 --- a/pdata/pprofile/go.mod +++ b/pdata/pprofile/go.mod @@ -1,32 +1,34 @@ module go.opentelemetry.io/collector/pdata/pprofile -go 1.24.0 +go 1.25.0 require ( github.com/stretchr/testify v1.11.1 - go.opentelemetry.io/collector/internal/testutil v0.140.0 - go.opentelemetry.io/collector/pdata v1.46.0 - go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.2.0 - go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.2.0 + go.opentelemetry.io/collector/featuregate v1.54.0 + go.opentelemetry.io/collector/internal/testutil v0.148.0 + go.opentelemetry.io/collector/pdata v1.54.0 + go.opentelemetry.io/otel v1.40.0 + go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.3.0 + go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.3.0 go.uber.org/goleak v1.3.0 - google.golang.org/grpc v1.77.0 - google.golang.org/protobuf v1.36.10 + google.golang.org/grpc v1.79.3 + google.golang.org/protobuf v1.36.11 ) require ( + github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/davecgh/go-spew v1.1.1 // indirect - github.com/hashicorp/go-version v1.7.0 // indirect + github.com/hashicorp/go-version v1.8.0 // indirect github.com/json-iterator/go v1.1.12 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee // indirect github.com/pmezard/go-difflib v1.0.0 // indirect - go.opentelemetry.io/collector/featuregate v1.46.0 // indirect - go.opentelemetry.io/proto/slim/otlp v1.9.0 // indirect + go.opentelemetry.io/proto/slim/otlp v1.10.0 // indirect go.uber.org/multierr v1.11.0 // indirect - golang.org/x/net v0.46.1-0.20251013234738-63d1a5100f82 // indirect - golang.org/x/sys v0.37.0 // indirect - golang.org/x/text v0.30.0 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20251022142026-3a174f9686a8 // indirect + golang.org/x/net v0.51.0 // indirect + golang.org/x/sys v0.41.0 // indirect + golang.org/x/text v0.34.0 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20251222181119-0a764e51fe1b // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/pdata/pprofile/go.sum b/pdata/pprofile/go.sum index 3ae9da8776e5..2bc3e8d22080 100644 --- a/pdata/pprofile/go.sum +++ b/pdata/pprofile/go.sum @@ -1,3 +1,5 @@ +github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= +github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= @@ -12,8 +14,8 @@ github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/hashicorp/go-version v1.7.0 h1:5tqGy27NaOTB8yJKUZELlFAS/LTKJkrmONwQKeRZfjY= -github.com/hashicorp/go-version v1.7.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= +github.com/hashicorp/go-version v1.8.0 h1:KAkNb1HAiZd1ukkxDFGmokVZe1Xy9HG6NUp+bPle2i4= +github.com/hashicorp/go-version v1.8.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= @@ -36,40 +38,40 @@ github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64= go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y= -go.opentelemetry.io/otel v1.38.0 h1:RkfdswUDRimDg0m2Az18RKOsnI8UDzppJAtj01/Ymk8= -go.opentelemetry.io/otel v1.38.0/go.mod h1:zcmtmQ1+YmQM9wrNsTGV/q/uyusom3P8RxwExxkZhjM= -go.opentelemetry.io/otel/metric v1.38.0 h1:Kl6lzIYGAh5M159u9NgiRkmoMKjvbsKtYRwgfrA6WpA= -go.opentelemetry.io/otel/metric v1.38.0/go.mod h1:kB5n/QoRM8YwmUahxvI3bO34eVtQf2i4utNVLr9gEmI= -go.opentelemetry.io/otel/sdk v1.38.0 h1:l48sr5YbNf2hpCUj/FoGhW9yDkl+Ma+LrVl8qaM5b+E= -go.opentelemetry.io/otel/sdk v1.38.0/go.mod h1:ghmNdGlVemJI3+ZB5iDEuk4bWA3GkTpW+DOoZMYBVVg= -go.opentelemetry.io/otel/sdk/metric v1.38.0 h1:aSH66iL0aZqo//xXzQLYozmWrXxyFkBJ6qT5wthqPoM= -go.opentelemetry.io/otel/sdk/metric v1.38.0/go.mod h1:dg9PBnW9XdQ1Hd6ZnRz689CbtrUp0wMMs9iPcgT9EZA= -go.opentelemetry.io/otel/trace v1.38.0 h1:Fxk5bKrDZJUH+AMyyIXGcFAPah0oRcT+LuNtJrmcNLE= -go.opentelemetry.io/otel/trace v1.38.0/go.mod h1:j1P9ivuFsTceSWe1oY+EeW3sc+Pp42sO++GHkg4wwhs= -go.opentelemetry.io/proto/slim/otlp v1.9.0 h1:fPVMv8tP3TrsqlkH1HWYUpbCY9cAIemx184VGkS6vlE= -go.opentelemetry.io/proto/slim/otlp v1.9.0/go.mod h1:xXdeJJ90Gqyll+orzUkY4bOd2HECo5JofeoLpymVqdI= -go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.2.0 h1:o13nadWDNkH/quoDomDUClnQBpdQQ2Qqv0lQBjIXjE8= -go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.2.0/go.mod h1:Gyb6Xe7FTi/6xBHwMmngGoHqL0w29Y4eW8TGFzpefGA= -go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.2.0 h1:EiUYvtwu6PMrMHVjcPfnsG3v+ajPkbUeH+IL93+QYyk= -go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.2.0/go.mod h1:mUUHKFiN2SST3AhJ8XhJxEoeVW12oqfXog0Bo8W3Ec4= +go.opentelemetry.io/otel v1.40.0 h1:oA5YeOcpRTXq6NN7frwmwFR0Cn3RhTVZvXsP4duvCms= +go.opentelemetry.io/otel v1.40.0/go.mod h1:IMb+uXZUKkMXdPddhwAHm6UfOwJyh4ct1ybIlV14J0g= +go.opentelemetry.io/otel/metric v1.40.0 h1:rcZe317KPftE2rstWIBitCdVp89A2HqjkxR3c11+p9g= +go.opentelemetry.io/otel/metric v1.40.0/go.mod h1:ib/crwQH7N3r5kfiBZQbwrTge743UDc7DTFVZrrXnqc= +go.opentelemetry.io/otel/sdk v1.39.0 h1:nMLYcjVsvdui1B/4FRkwjzoRVsMK8uL/cj0OyhKzt18= +go.opentelemetry.io/otel/sdk v1.39.0/go.mod h1:vDojkC4/jsTJsE+kh+LXYQlbL8CgrEcwmt1ENZszdJE= +go.opentelemetry.io/otel/sdk/metric v1.39.0 h1:cXMVVFVgsIf2YL6QkRF4Urbr/aMInf+2WKg+sEJTtB8= +go.opentelemetry.io/otel/sdk/metric v1.39.0/go.mod h1:xq9HEVH7qeX69/JnwEfp6fVq5wosJsY1mt4lLfYdVew= +go.opentelemetry.io/otel/trace v1.40.0 h1:WA4etStDttCSYuhwvEa8OP8I5EWu24lkOzp+ZYblVjw= +go.opentelemetry.io/otel/trace v1.40.0/go.mod h1:zeAhriXecNGP/s2SEG3+Y8X9ujcJOTqQ5RgdEJcawiA= +go.opentelemetry.io/proto/slim/otlp v1.10.0 h1:iR97Vs/ZDR+y9TfuP9b1XBtdPWeC+OMslIBmhcLU7jM= +go.opentelemetry.io/proto/slim/otlp v1.10.0/go.mod h1:lV9250stpjYLPNA5viFabIgP2QlUGRT1GdTgAf8SIUk= +go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.3.0 h1:RUF5rO0hAlgiJt1fzQVzcVs3vZVNHIcMLgOgG4rWNcQ= +go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.3.0/go.mod h1:I89cynRj8y+383o7tEQVg2SVA6SRgDVIouWPUVXjx0U= +go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.3.0 h1:CQvJSldHRUN6Z8jsUeYv8J0lXRvygALXIzsmAeCcZE0= +go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.3.0/go.mod h1:xSQ+mEfJe/GjK1LXEyVOoSI1N9JV9ZI923X5kup43W4= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= -golang.org/x/net v0.46.1-0.20251013234738-63d1a5100f82 h1:6/3JGEh1C88g7m+qzzTbl3A0FtsLguXieqofVLU/JAo= -golang.org/x/net v0.46.1-0.20251013234738-63d1a5100f82/go.mod h1:Q9BGdFy1y4nkUwiLvT5qtyhAnEHgnQ/zd8PfU6nc210= -golang.org/x/sys v0.37.0 h1:fdNQudmxPjkdUTPnLn5mdQv7Zwvbvpaxqs831goi9kQ= -golang.org/x/sys v0.37.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= -golang.org/x/text v0.30.0 h1:yznKA/E9zq54KzlzBEAWn1NXSQ8DIp/NYMy88xJjl4k= -golang.org/x/text v0.30.0/go.mod h1:yDdHFIX9t+tORqspjENWgzaCVXgk0yYnYuSZ8UzzBVM= +golang.org/x/net v0.51.0 h1:94R/GTO7mt3/4wIKpcR5gkGmRLOuE/2hNGeWq/GBIFo= +golang.org/x/net v0.51.0/go.mod h1:aamm+2QF5ogm02fjy5Bb7CQ0WMt1/WVM7FtyaTLlA9Y= +golang.org/x/sys v0.41.0 h1:Ivj+2Cp/ylzLiEU89QhWblYnOE9zerudt9Ftecq2C6k= +golang.org/x/sys v0.41.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= +golang.org/x/text v0.34.0 h1:oL/Qq0Kdaqxa1KbNeMKwQq0reLCCaFtqu2eNuSeNHbk= +golang.org/x/text v0.34.0/go.mod h1:homfLqTYRFyVYemLBFl5GgL/DWEiH5wcsQ5gSh1yziA= gonum.org/v1/gonum v0.16.0 h1:5+ul4Swaf3ESvrOnidPp4GZbzf0mxVQpDCYUQE7OJfk= gonum.org/v1/gonum v0.16.0/go.mod h1:fef3am4MQ93R2HHpKnLk4/Tbh/s0+wqD5nfa6Pnwy4E= -google.golang.org/genproto/googleapis/rpc v0.0.0-20251022142026-3a174f9686a8 h1:M1rk8KBnUsBDg1oPGHNCxG4vc1f49epmTO7xscSajMk= -google.golang.org/genproto/googleapis/rpc v0.0.0-20251022142026-3a174f9686a8/go.mod h1:7i2o+ce6H/6BluujYR+kqX3GKH+dChPTQU19wjRPiGk= -google.golang.org/grpc v1.77.0 h1:wVVY6/8cGA6vvffn+wWK5ToddbgdU3d8MNENr4evgXM= -google.golang.org/grpc v1.77.0/go.mod h1:z0BY1iVj0q8E1uSQCjL9cppRj+gnZjzDnzV0dHhrNig= -google.golang.org/protobuf v1.36.10 h1:AYd7cD/uASjIL6Q9LiTjz8JLcrh/88q5UObnmY3aOOE= -google.golang.org/protobuf v1.36.10/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= +google.golang.org/genproto/googleapis/rpc v0.0.0-20251222181119-0a764e51fe1b h1:Mv8VFug0MP9e5vUxfBcE3vUkV6CImK3cMNMIDFjmzxU= +google.golang.org/genproto/googleapis/rpc v0.0.0-20251222181119-0a764e51fe1b/go.mod h1:j9x/tPzZkyxcgEFkiKEEGxfvyumM01BEtsW8xzOahRQ= +google.golang.org/grpc v1.79.3 h1:sybAEdRIEtvcD68Gx7dmnwjZKlyfuc61Dyo9pGXXkKE= +google.golang.org/grpc v1.79.3/go.mod h1:KmT0Kjez+0dde/v2j9vzwoAScgEPx/Bw1CYChhHLrHQ= +google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE= +google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= diff --git a/pdata/pprofile/json.go b/pdata/pprofile/json.go index 8b3fa3fac855..b691b81abc7e 100644 --- a/pdata/pprofile/json.go +++ b/pdata/pprofile/json.go @@ -15,6 +15,9 @@ type JSONMarshaler struct{} // MarshalProfiles to the OTLP/JSON format. func (*JSONMarshaler) MarshalProfiles(pd Profiles) ([]byte, error) { + // Convert strings to references for efficient transmission + convertProfilesToReferences(pd) + dest := json.BorrowStream(nil) defer json.ReturnStream(dest) pd.getOrig().MarshalJSON(dest) @@ -37,5 +40,10 @@ func (*JSONUnmarshaler) UnmarshalProfiles(buf []byte) (Profiles, error) { return Profiles{}, iter.Error() } otlp.MigrateProfiles(pd.getOrig().ResourceProfiles) + + // Resolve all string_value_ref and key_ref to their actual strings + // so the pdata API works transparently + resolveProfilesReferences(pd) + return pd, nil } diff --git a/pdata/pprofile/json_references_test.go b/pdata/pprofile/json_references_test.go new file mode 100644 index 000000000000..191bbf0429bb --- /dev/null +++ b/pdata/pprofile/json_references_test.go @@ -0,0 +1,87 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +package pprofile + +import ( + stdjson "encoding/json" + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +// newProfilesWithAttributes creates a Profiles with resource and scope +// attributes for testing reference conversion. +func newProfilesWithAttributes() Profiles { + profiles := NewProfiles() + profiles.Dictionary().StringTable().Append("") // index 0 + + rp := profiles.ResourceProfiles().AppendEmpty() + rp.Resource().Attributes().PutStr("service.name", "test-service") + rp.Resource().Attributes().PutStr("host.name", "test-host") + + sp := rp.ScopeProfiles().AppendEmpty() + sp.Scope().Attributes().PutStr("scope.attr", "scope-value") + + return profiles +} + +func TestJSONMarshalConvertsToReferences(t *testing.T) { + marshaler := JSONMarshaler{} + jsonBytes, err := marshaler.MarshalProfiles(newProfilesWithAttributes()) + require.NoError(t, err) + + // Parse the JSON output to verify references were used + var parsed map[string]any + require.NoError(t, stdjson.Unmarshal(jsonBytes, &parsed)) + + // The dictionary's stringTable should contain the attribute keys and values + dictionary, ok := parsed["dictionary"].(map[string]any) + require.True(t, ok, "JSON output should contain a dictionary object") + stringTable, ok := dictionary["stringTable"].([]any) + require.True(t, ok, "dictionary should contain a stringTable array") + + tableStrs := make([]string, len(stringTable)) + for i, v := range stringTable { + tableStrs[i], _ = v.(string) + } + assert.Contains(t, tableStrs, "service.name") + assert.Contains(t, tableStrs, "test-service") + assert.Contains(t, tableStrs, "host.name") + assert.Contains(t, tableStrs, "test-host") + assert.Contains(t, tableStrs, "scope.attr") + assert.Contains(t, tableStrs, "scope-value") +} + +func TestJSONUnmarshalResolvesReferences(t *testing.T) { + profiles := newProfilesWithAttributes() + + // Manually convert to references before marshaling, so the JSON output + // contains key_ref/string_value_ref regardless of whether the JSON + // marshaler itself calls convertProfilesToReferences. + convertProfilesToReferences(profiles) + + marshaler := JSONMarshaler{} + jsonBytes, err := marshaler.MarshalProfiles(profiles) + require.NoError(t, err) + + // Unmarshal and verify references were resolved + unmarshaler := JSONUnmarshaler{} + restored, err := unmarshaler.UnmarshalProfiles(jsonBytes) + require.NoError(t, err) + + rp := restored.ResourceProfiles().At(0) + serviceNameVal, ok := rp.Resource().Attributes().Get("service.name") + assert.True(t, ok, "service.name attribute should be accessible after JSON unmarshal") + assert.Equal(t, "test-service", serviceNameVal.Str()) + + hostNameVal, ok := rp.Resource().Attributes().Get("host.name") + assert.True(t, ok, "host.name attribute should be accessible after JSON unmarshal") + assert.Equal(t, "test-host", hostNameVal.Str()) + + sp := rp.ScopeProfiles().At(0) + scopeAttrVal, ok := sp.Scope().Attributes().Get("scope.attr") + assert.True(t, ok, "scope.attr should be accessible after JSON unmarshal") + assert.Equal(t, "scope-value", scopeAttrVal.Str()) +} diff --git a/pdata/pprofile/keyvalueandunit.go b/pdata/pprofile/keyvalueandunit.go index 4ec70d911d7c..47bf4d151db0 100644 --- a/pdata/pprofile/keyvalueandunit.go +++ b/pdata/pprofile/keyvalueandunit.go @@ -17,7 +17,7 @@ func (ms KeyValueAndUnit) Equal(val KeyValueAndUnit) bool { // dictionary to another. func (ms KeyValueAndUnit) switchDictionary(src, dst ProfilesDictionary) error { if ms.KeyStrindex() > 0 { - if src.StringTable().Len() < int(ms.KeyStrindex()) { + if src.StringTable().Len() <= int(ms.KeyStrindex()) { return fmt.Errorf("invalid key index %d", ms.KeyStrindex()) } @@ -29,7 +29,7 @@ func (ms KeyValueAndUnit) switchDictionary(src, dst ProfilesDictionary) error { } if ms.UnitStrindex() > 0 { - if src.StringTable().Len() < int(ms.UnitStrindex()) { + if src.StringTable().Len() <= int(ms.UnitStrindex()) { return fmt.Errorf("invalid unit index %d", ms.UnitStrindex()) } diff --git a/pdata/pprofile/keyvalueandunit_test.go b/pdata/pprofile/keyvalueandunit_test.go index bfbb3b7c4d69..db75ec6d574e 100644 --- a/pdata/pprofile/keyvalueandunit_test.go +++ b/pdata/pprofile/keyvalueandunit_test.go @@ -133,6 +133,29 @@ func TestKeyValueAndUnitSwitchDictionary(t *testing.T) { wantDictionary: NewProfilesDictionary(), wantErr: errors.New("invalid key index 1"), }, + { + name: "with a key index equal to the source table length (boundary condition)", + keyValueAndUnit: func() KeyValueAndUnit { + kvu := NewKeyValueAndUnit() + kvu.SetKeyStrindex(2) + return kvu + }(), + + src: func() ProfilesDictionary { + d := NewProfilesDictionary() + d.StringTable().Append("", "test") + return d + }(), + dst: NewProfilesDictionary(), + + wantKeyValueAndUnit: func() KeyValueAndUnit { + kvu := NewKeyValueAndUnit() + kvu.SetKeyStrindex(2) + return kvu + }(), + wantDictionary: NewProfilesDictionary(), + wantErr: errors.New("invalid key index 2"), + }, { name: "with an existing unit", keyValueAndUnit: func() KeyValueAndUnit { @@ -182,6 +205,29 @@ func TestKeyValueAndUnitSwitchDictionary(t *testing.T) { wantDictionary: NewProfilesDictionary(), wantErr: errors.New("invalid unit index 1"), }, + { + name: "with a unit index equal to the source table length (boundary condition)", + keyValueAndUnit: func() KeyValueAndUnit { + kvu := NewKeyValueAndUnit() + kvu.SetUnitStrindex(2) + return kvu + }(), + + src: func() ProfilesDictionary { + d := NewProfilesDictionary() + d.StringTable().Append("", "test") + return d + }(), + dst: NewProfilesDictionary(), + + wantKeyValueAndUnit: func() KeyValueAndUnit { + kvu := NewKeyValueAndUnit() + kvu.SetUnitStrindex(2) + return kvu + }(), + wantDictionary: NewProfilesDictionary(), + wantErr: errors.New("invalid unit index 2"), + }, } { t.Run(tt.name, func(t *testing.T) { kvu := tt.keyValueAndUnit diff --git a/pdata/pprofile/line.go b/pdata/pprofile/line.go index 57ba32bcfe61..7a0e105a0962 100644 --- a/pdata/pprofile/line.go +++ b/pdata/pprofile/line.go @@ -31,16 +31,11 @@ func (l Line) Equal(val Line) bool { // dictionary to another. func (l Line) switchDictionary(src, dst ProfilesDictionary) error { if l.FunctionIndex() > 0 { - if src.FunctionTable().Len() < int(l.FunctionIndex()) { + if src.FunctionTable().Len() <= int(l.FunctionIndex()) { return fmt.Errorf("invalid function index %d", l.FunctionIndex()) } fn := src.FunctionTable().At(int(l.FunctionIndex())) - err := fn.switchDictionary(src, dst) - if err != nil { - return fmt.Errorf("couldn't switch function dictionary: %w", err) - } - idx, err := SetFunction(dst.FunctionTable(), fn) if err != nil { return fmt.Errorf("couldn't set function: %w", err) diff --git a/pdata/pprofile/line_test.go b/pdata/pprofile/line_test.go index 0d87d0b3bda7..3ba9aa3b6162 100644 --- a/pdata/pprofile/line_test.go +++ b/pdata/pprofile/line_test.go @@ -164,26 +164,26 @@ func TestLineSwitchDictionary(t *testing.T) { }(), dst: func() ProfilesDictionary { d := NewProfilesDictionary() - d.StringTable().Append("", "foo") + d.StringTable().Append("", "test") d.FunctionTable().AppendEmpty() - d.FunctionTable().AppendEmpty() + f := d.FunctionTable().AppendEmpty() + f.SetNameStrindex(1) return d }(), wantLine: func() Line { l := NewLine() - l.SetFunctionIndex(2) + l.SetFunctionIndex(1) return l }(), wantDictionary: func() ProfilesDictionary { d := NewProfilesDictionary() - d.StringTable().Append("", "foo", "test") + d.StringTable().Append("", "test") - d.FunctionTable().AppendEmpty() d.FunctionTable().AppendEmpty() f := d.FunctionTable().AppendEmpty() - f.SetNameStrindex(2) + f.SetNameStrindex(1) return d }(), }, @@ -206,6 +206,30 @@ func TestLineSwitchDictionary(t *testing.T) { wantDictionary: NewProfilesDictionary(), wantErr: errors.New("invalid function index 1"), }, + { + name: "with a function index equal to the source table length (boundary condition)", + line: func() Line { + l := NewLine() + l.SetFunctionIndex(2) + return l + }(), + + src: func() ProfilesDictionary { + d := NewProfilesDictionary() + d.FunctionTable().AppendEmpty() + d.FunctionTable().AppendEmpty() // Length 2: indices 0,1 valid + return d + }(), + dst: NewProfilesDictionary(), + + wantLine: func() Line { + l := NewLine() + l.SetFunctionIndex(2) + return l + }(), + wantDictionary: NewProfilesDictionary(), + wantErr: errors.New("invalid function index 2"), + }, } { t.Run(tt.name, func(t *testing.T) { line := tt.line diff --git a/pdata/pprofile/links.go b/pdata/pprofile/links.go index 13a9192a00df..c1cc2d5071ce 100644 --- a/pdata/pprofile/links.go +++ b/pdata/pprofile/links.go @@ -18,7 +18,7 @@ func SetLink(table LinkSlice, li Link) (int32, error) { if j > math.MaxInt32 { return 0, errTooManyLinkTableEntries } - return int32(j), nil //nolint:gosec // G115 overflow checked + return int32(j), nil } } @@ -27,5 +27,5 @@ func SetLink(table LinkSlice, li Link) (int32, error) { } li.CopyTo(table.AppendEmpty()) - return int32(table.Len() - 1), nil //nolint:gosec // G115 overflow checked + return int32(table.Len() - 1), nil } diff --git a/pdata/pprofile/links_test.go b/pdata/pprofile/links_test.go index 1c2b49bcd058..ebe991930d35 100644 --- a/pdata/pprofile/links_test.go +++ b/pdata/pprofile/links_test.go @@ -38,7 +38,7 @@ func TestSetLink(t *testing.T) { idx, err = SetLink(table, l2) require.NoError(t, err) assert.Equal(t, 2, table.Len()) - assert.Equal(t, int32(table.Len()-1), idx) //nolint:gosec // G115 + assert.Equal(t, int32(table.Len()-1), idx) // Set an existing link idx, err = SetLink(table, l) @@ -49,7 +49,7 @@ func TestSetLink(t *testing.T) { idx, err = SetLink(table, l2) require.NoError(t, err) assert.Equal(t, 2, table.Len()) - assert.Equal(t, int32(table.Len()-1), idx) //nolint:gosec // G115 + assert.Equal(t, int32(table.Len()-1), idx) } func BenchmarkSetLink(b *testing.B) { diff --git a/pdata/pprofile/location.go b/pdata/pprofile/location.go index e63f52ce7095..0dd373ee866c 100644 --- a/pdata/pprofile/location.go +++ b/pdata/pprofile/location.go @@ -17,15 +17,11 @@ func (ms Location) Equal(val Location) bool { // dictionary to another. func (ms Location) switchDictionary(src, dst ProfilesDictionary) error { if ms.MappingIndex() > 0 { - if src.MappingTable().Len() < int(ms.MappingIndex()) { + if src.MappingTable().Len() <= int(ms.MappingIndex()) { return fmt.Errorf("invalid mapping index %d", ms.MappingIndex()) } mapping := src.MappingTable().At(int(ms.MappingIndex())) - err := mapping.switchDictionary(src, dst) - if err != nil { - return fmt.Errorf("couldn't switch dictionary for mapping: %w", err) - } idx, err := SetMapping(dst.MappingTable(), mapping) if err != nil { return fmt.Errorf("couldn't set mapping: %w", err) @@ -34,15 +30,11 @@ func (ms Location) switchDictionary(src, dst ProfilesDictionary) error { } for i, v := range ms.AttributeIndices().All() { - if src.AttributeTable().Len() < int(v) { + if src.AttributeTable().Len() <= int(v) { return fmt.Errorf("invalid attribute index %d", v) } attr := src.AttributeTable().At(int(v)) - err := attr.switchDictionary(src, dst) - if err != nil { - return fmt.Errorf("couldn't switch dictionary for attribute %d: %w", i, err) - } idx, err := SetAttribute(dst.AttributeTable(), attr) if err != nil { return fmt.Errorf("couldn't set attribute %d: %w", i, err) diff --git a/pdata/pprofile/location_test.go b/pdata/pprofile/location_test.go index b489b258537b..311e5b733c8a 100644 --- a/pdata/pprofile/location_test.go +++ b/pdata/pprofile/location_test.go @@ -108,26 +108,26 @@ func TestLocationSwitchDictionary(t *testing.T) { }(), dst: func() ProfilesDictionary { d := NewProfilesDictionary() - d.StringTable().Append("", "foo") + d.StringTable().Append("", "test") d.MappingTable().AppendEmpty() - d.MappingTable().AppendEmpty() + m := d.MappingTable().AppendEmpty() + m.SetFilenameStrindex(1) return d }(), wantLocation: func() Location { l := NewLocation() - l.SetMappingIndex(2) + l.SetMappingIndex(1) return l }(), wantDictionary: func() ProfilesDictionary { d := NewProfilesDictionary() - d.StringTable().Append("", "foo", "test") + d.StringTable().Append("", "test") - d.MappingTable().AppendEmpty() d.MappingTable().AppendEmpty() m := d.MappingTable().AppendEmpty() - m.SetFilenameStrindex(2) + m.SetFilenameStrindex(1) return d }(), }, @@ -150,6 +150,30 @@ func TestLocationSwitchDictionary(t *testing.T) { wantDictionary: NewProfilesDictionary(), wantErr: errors.New("invalid mapping index 1"), }, + { + name: "with a mapping index equal to the source table length (boundary condition)", + location: func() Location { + l := NewLocation() + l.SetMappingIndex(2) + return l + }(), + + src: func() ProfilesDictionary { + d := NewProfilesDictionary() + d.MappingTable().AppendEmpty() + d.MappingTable().AppendEmpty() + return d + }(), + dst: NewProfilesDictionary(), + + wantLocation: func() Location { + l := NewLocation() + l.SetMappingIndex(2) + return l + }(), + wantDictionary: NewProfilesDictionary(), + wantErr: errors.New("invalid mapping index 2"), + }, { name: "with an existing attribute", location: func() Location { @@ -170,26 +194,27 @@ func TestLocationSwitchDictionary(t *testing.T) { }(), dst: func() ProfilesDictionary { d := NewProfilesDictionary() - d.StringTable().Append("", "foo") + d.StringTable().Append("", "test") d.AttributeTable().AppendEmpty() - d.AttributeTable().AppendEmpty() + a := d.AttributeTable().AppendEmpty() + a.SetKeyStrindex(1) + return d }(), wantLocation: func() Location { l := NewLocation() - l.AttributeIndices().Append(2) + l.AttributeIndices().Append(1) return l }(), wantDictionary: func() ProfilesDictionary { d := NewProfilesDictionary() - d.StringTable().Append("", "foo", "test") + d.StringTable().Append("", "test") - d.AttributeTable().AppendEmpty() d.AttributeTable().AppendEmpty() a := d.AttributeTable().AppendEmpty() - a.SetKeyStrindex(2) + a.SetKeyStrindex(1) return d }(), }, @@ -212,6 +237,30 @@ func TestLocationSwitchDictionary(t *testing.T) { wantDictionary: NewProfilesDictionary(), wantErr: errors.New("invalid attribute index 1"), }, + { + name: "with an attribute index equal to the source table length (boundary condition)", + location: func() Location { + l := NewLocation() + l.AttributeIndices().Append(2) + return l + }(), + + src: func() ProfilesDictionary { + d := NewProfilesDictionary() + d.AttributeTable().AppendEmpty() + d.AttributeTable().AppendEmpty() + return d + }(), + dst: NewProfilesDictionary(), + + wantLocation: func() Location { + l := NewLocation() + l.AttributeIndices().Append(2) + return l + }(), + wantDictionary: NewProfilesDictionary(), + wantErr: errors.New("invalid attribute index 2"), + }, { name: "with an existing line", location: func() Location { @@ -232,26 +281,27 @@ func TestLocationSwitchDictionary(t *testing.T) { }(), dst: func() ProfilesDictionary { d := NewProfilesDictionary() - d.StringTable().Append("", "foo") + d.StringTable().Append("", "test") d.FunctionTable().AppendEmpty() - d.FunctionTable().AppendEmpty() + f := d.FunctionTable().AppendEmpty() + f.SetNameStrindex(1) + return d }(), wantLocation: func() Location { l := NewLocation() - l.Lines().AppendEmpty().SetFunctionIndex(2) + l.Lines().AppendEmpty().SetFunctionIndex(1) return l }(), wantDictionary: func() ProfilesDictionary { d := NewProfilesDictionary() - d.StringTable().Append("", "foo", "test") + d.StringTable().Append("", "test") - d.FunctionTable().AppendEmpty() d.FunctionTable().AppendEmpty() f := d.FunctionTable().AppendEmpty() - f.SetNameStrindex(2) + f.SetNameStrindex(1) return d }(), }, diff --git a/pdata/pprofile/locations.go b/pdata/pprofile/locations.go index d64334b1f562..12b3cbe1be76 100644 --- a/pdata/pprofile/locations.go +++ b/pdata/pprofile/locations.go @@ -32,7 +32,7 @@ func SetLocation(table LocationSlice, loc Location) (int32, error) { if j > math.MaxInt32 { return 0, errTooManyLocationTableEntries } - return int32(j), nil //nolint:gosec // G115 overflow checked + return int32(j), nil } } @@ -41,5 +41,5 @@ func SetLocation(table LocationSlice, loc Location) (int32, error) { } loc.CopyTo(table.AppendEmpty()) - return int32(table.Len() - 1), nil //nolint:gosec // G115 overflow checked + return int32(table.Len() - 1), nil } diff --git a/pdata/pprofile/locations_test.go b/pdata/pprofile/locations_test.go index 2a14904f434a..acbdbb933d70 100644 --- a/pdata/pprofile/locations_test.go +++ b/pdata/pprofile/locations_test.go @@ -61,7 +61,7 @@ func TestSetLocation(t *testing.T) { idx, err = SetLocation(table, l2) require.NoError(t, err) assert.Equal(t, 2, table.Len()) - assert.Equal(t, int32(table.Len()-1), idx) //nolint:gosec // G115 + assert.Equal(t, int32(table.Len()-1), idx) // Set an existing value idx, err = SetLocation(table, l) @@ -72,14 +72,14 @@ func TestSetLocation(t *testing.T) { idx, err = SetLocation(table, l2) require.NoError(t, err) assert.Equal(t, 2, table.Len()) - assert.Equal(t, int32(table.Len()-1), idx) //nolint:gosec // G115 + assert.Equal(t, int32(table.Len()-1), idx) } func BenchmarkFromLocationIndices(b *testing.B) { table := NewLocationSlice() for i := range 100 { - table.AppendEmpty().SetAddress(uint64(i)) //nolint:gosec // overflow checked + table.AppendEmpty().SetAddress(uint64(i)) } obj := NewStack() @@ -139,7 +139,7 @@ func BenchmarkSetLocation(b *testing.B) { runBefore: func(_ *testing.B, table LocationSlice) { for i := range 100 { l := table.AppendEmpty() - l.SetAddress(uint64(i)) //nolint:gosec // overflow checked + l.SetAddress(uint64(i)) } l := table.AppendEmpty() diff --git a/pdata/pprofile/mapping.go b/pdata/pprofile/mapping.go index 7989f3c14abf..b463ee644fd0 100644 --- a/pdata/pprofile/mapping.go +++ b/pdata/pprofile/mapping.go @@ -18,7 +18,7 @@ func (ms Mapping) Equal(val Mapping) bool { // dictionary to another. func (ms Mapping) switchDictionary(src, dst ProfilesDictionary) error { if ms.FilenameStrindex() > 0 { - if src.StringTable().Len() < int(ms.FilenameStrindex()) { + if src.StringTable().Len() <= int(ms.FilenameStrindex()) { return fmt.Errorf("invalid filename index %d", ms.FilenameStrindex()) } @@ -30,15 +30,11 @@ func (ms Mapping) switchDictionary(src, dst ProfilesDictionary) error { } for i, v := range ms.AttributeIndices().All() { - if src.AttributeTable().Len() < int(v) { + if src.AttributeTable().Len() <= int(v) { return fmt.Errorf("invalid attribute index %d", v) } attr := src.AttributeTable().At(int(v)) - err := attr.switchDictionary(src, dst) - if err != nil { - return fmt.Errorf("couldn't switch dictionary for attribute %d: %w", i, err) - } idx, err := SetAttribute(dst.AttributeTable(), attr) if err != nil { return fmt.Errorf("couldn't set attribute %d: %w", i, err) diff --git a/pdata/pprofile/mapping_test.go b/pdata/pprofile/mapping_test.go index 8be426e6c0be..dd3b9981838a 100644 --- a/pdata/pprofile/mapping_test.go +++ b/pdata/pprofile/mapping_test.go @@ -144,6 +144,29 @@ func TestMappingSwitchDictionary(t *testing.T) { wantDictionary: NewProfilesDictionary(), wantErr: errors.New("invalid filename index 1"), }, + { + name: "with a filename index equal to the source table length (boundary condition)", + mapping: func() Mapping { + m := NewMapping() + m.SetFilenameStrindex(2) + return m + }(), + + src: func() ProfilesDictionary { + d := NewProfilesDictionary() + d.StringTable().Append("", "test") + return d + }(), + dst: NewProfilesDictionary(), + + wantMapping: func() Mapping { + m := NewMapping() + m.SetFilenameStrindex(2) + return m + }(), + wantDictionary: NewProfilesDictionary(), + wantErr: errors.New("invalid filename index 2"), + }, { name: "with an existing attribute", mapping: func() Mapping { @@ -164,26 +187,27 @@ func TestMappingSwitchDictionary(t *testing.T) { }(), dst: func() ProfilesDictionary { d := NewProfilesDictionary() - d.StringTable().Append("", "foo") + d.StringTable().Append("", "test") d.AttributeTable().AppendEmpty() - d.AttributeTable().AppendEmpty() + a := d.AttributeTable().AppendEmpty() + a.SetKeyStrindex(1) + return d }(), wantMapping: func() Mapping { m := NewMapping() - m.AttributeIndices().Append(2) + m.AttributeIndices().Append(1) return m }(), wantDictionary: func() ProfilesDictionary { d := NewProfilesDictionary() - d.StringTable().Append("", "foo", "test") + d.StringTable().Append("", "test") - d.AttributeTable().AppendEmpty() d.AttributeTable().AppendEmpty() a := d.AttributeTable().AppendEmpty() - a.SetKeyStrindex(2) + a.SetKeyStrindex(1) return d }(), }, @@ -206,6 +230,30 @@ func TestMappingSwitchDictionary(t *testing.T) { wantDictionary: NewProfilesDictionary(), wantErr: errors.New("invalid attribute index 1"), }, + { + name: "with an attribute index equal to the source table length (boundary condition)", + mapping: func() Mapping { + m := NewMapping() + m.AttributeIndices().Append(2) + return m + }(), + + src: func() ProfilesDictionary { + d := NewProfilesDictionary() + d.AttributeTable().AppendEmpty() + d.AttributeTable().AppendEmpty() + return d + }(), + dst: NewProfilesDictionary(), + + wantMapping: func() Mapping { + m := NewMapping() + m.AttributeIndices().Append(2) + return m + }(), + wantDictionary: NewProfilesDictionary(), + wantErr: errors.New("invalid attribute index 2"), + }, } { t.Run(tt.name, func(t *testing.T) { m := tt.mapping diff --git a/pdata/pprofile/mappings.go b/pdata/pprofile/mappings.go index 34023f34aae1..39943bf8ea05 100644 --- a/pdata/pprofile/mappings.go +++ b/pdata/pprofile/mappings.go @@ -18,7 +18,7 @@ func SetMapping(table MappingSlice, ma Mapping) (int32, error) { if j > math.MaxInt32 { return 0, errTooManyMappingTableEntries } - return int32(j), nil //nolint:gosec // G115 overflow checked + return int32(j), nil } } @@ -27,5 +27,5 @@ func SetMapping(table MappingSlice, ma Mapping) (int32, error) { } ma.CopyTo(table.AppendEmpty()) - return int32(table.Len() - 1), nil //nolint:gosec // G115 overflow checked + return int32(table.Len() - 1), nil } diff --git a/pdata/pprofile/mappings_test.go b/pdata/pprofile/mappings_test.go index 5abe19fe3895..f28a30851e1a 100644 --- a/pdata/pprofile/mappings_test.go +++ b/pdata/pprofile/mappings_test.go @@ -37,7 +37,7 @@ func TestSetMapping(t *testing.T) { idx, err = SetMapping(table, m2) require.NoError(t, err) assert.Equal(t, 2, table.Len()) - assert.Equal(t, int32(table.Len()-1), idx) //nolint:gosec // G115 + assert.Equal(t, int32(table.Len()-1), idx) // Set an existing mapping idx, err = SetMapping(table, m) @@ -48,7 +48,7 @@ func TestSetMapping(t *testing.T) { idx, err = SetMapping(table, m2) require.NoError(t, err) assert.Equal(t, 2, table.Len()) - assert.Equal(t, int32(table.Len()-1), idx) //nolint:gosec // G115 + assert.Equal(t, int32(table.Len()-1), idx) } func BenchmarkSetMapping(b *testing.B) { @@ -96,7 +96,7 @@ func BenchmarkSetMapping(b *testing.B) { runBefore: func(_ *testing.B, table MappingSlice) { for i := range 100 { m := table.AppendEmpty() - m.SetMemoryLimit(uint64(i)) //nolint:gosec // overflow checked + m.SetMemoryLimit(uint64(i)) } }, }, diff --git a/pdata/pprofile/pb.go b/pdata/pprofile/pb.go index 58f4f179474a..bfb25b04ed5e 100644 --- a/pdata/pprofile/pb.go +++ b/pdata/pprofile/pb.go @@ -8,6 +8,9 @@ var _ MarshalSizer = (*ProtoMarshaler)(nil) type ProtoMarshaler struct{} func (e *ProtoMarshaler) MarshalProfiles(pd Profiles) ([]byte, error) { + // Convert strings to references for efficient transmission + convertProfilesToReferences(pd) + size := pd.getOrig().SizeProto() buf := make([]byte, size) _ = pd.getOrig().MarshalProto(buf) @@ -38,5 +41,10 @@ func (d *ProtoUnmarshaler) UnmarshalProfiles(buf []byte) (Profiles, error) { if err != nil { return Profiles{}, err } + + // Resolve all string_value_ref and key_ref to their actual strings + // so the pdata API works transparently + resolveProfilesReferences(pd) + return pd, nil } diff --git a/pdata/pprofile/pb_references_test.go b/pdata/pprofile/pb_references_test.go new file mode 100644 index 000000000000..ddbe43d4b5d5 --- /dev/null +++ b/pdata/pprofile/pb_references_test.go @@ -0,0 +1,196 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +package pprofile + +import ( + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + + "go.opentelemetry.io/collector/pdata/internal" + "go.opentelemetry.io/collector/pdata/pcommon" +) + +func TestMarshalUnmarshalWithReferences(t *testing.T) { + profiles := NewProfiles() + + dict := profiles.Dictionary() + dict.StringTable().Append("") // index 0, required empty string + + rp := profiles.ResourceProfiles().AppendEmpty() + rp.Resource().Attributes().PutStr("service.name", "test-service") + rp.Resource().Attributes().PutStr("host.name", "test-host") + + sp := rp.ScopeProfiles().AppendEmpty() + sp.Scope().SetName("test-scope") + sp.Scope().Attributes().PutStr("scope.attr", "scope-value") + + profile := sp.Profiles().AppendEmpty() + profile.SetProfileID([16]byte{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}) + + // Marshal to proto bytes + marshaler := ProtoMarshaler{} + bytes, err := marshaler.MarshalProfiles(profiles) + require.NoError(t, err) + require.NotEmpty(t, bytes) + + // Verify that string table was populated (should have more than just the empty string) + assert.Greater(t, dict.StringTable().Len(), 1, "String table should be populated during marshal") + + // Verify references were created in the resource attributes + mapOrig := internal.GetMapOrig(internal.MapWrapper(rp.Resource().Attributes())) + foundRef := false + for i := 0; i < len(*mapOrig); i++ { + kv := (*mapOrig)[i] + if kv.KeyStrindex != 0 { + foundRef = true + break + } + // Check if value is a string reference + if ref, ok := kv.Value.Value.(*internal.AnyValue_StringValueStrindex); ok && ref.StringValueStrindex != 0 { + foundRef = true + break + } + } + assert.True(t, foundRef, "At least one reference should be created in attributes") + + // Unmarshal from proto bytes + unmarshaler := ProtoUnmarshaler{} + profiles2, err := unmarshaler.UnmarshalProfiles(bytes) + require.NoError(t, err) + + // Verify that the API works correctly - attributes should be accessible as strings + rp2 := profiles2.ResourceProfiles().At(0) + serviceNameVal, ok := rp2.Resource().Attributes().Get("service.name") + assert.True(t, ok, "service.name attribute should exist") + assert.Equal(t, "test-service", serviceNameVal.Str(), "service.name should be resolved to string") + + hostNameVal, ok := rp2.Resource().Attributes().Get("host.name") + assert.True(t, ok, "host.name attribute should exist") + assert.Equal(t, "test-host", hostNameVal.Str(), "host.name should be resolved to string") + + sp2 := rp2.ScopeProfiles().At(0) + scopeAttrVal, ok := sp2.Scope().Attributes().Get("scope.attr") + assert.True(t, ok, "scope.attr attribute should exist") + assert.Equal(t, "scope-value", scopeAttrVal.Str(), "scope.attr should be resolved to string") + + // Verify the string table is preserved + dict2 := profiles2.Dictionary() + assert.Greater(t, dict2.StringTable().Len(), 1, "String table should be preserved after unmarshal") +} + +func TestMarshalUnmarshalNestedValues(t *testing.T) { + profiles := NewProfiles() + dict := profiles.Dictionary() + dict.StringTable().Append("") // index 0 + + rp := profiles.ResourceProfiles().AppendEmpty() + attrs := rp.Resource().Attributes() + + kvlist := attrs.PutEmptyMap("nested.map") + kvlist.PutStr("inner.key1", "inner.value1") + kvlist.PutStr("inner.key2", "inner.value2") + + arr := attrs.PutEmptySlice("string.array") + arr.AppendEmpty().SetStr("string1") + arr.AppendEmpty().SetStr("string2") + arr.AppendEmpty().SetStr("string3") + + // Marshal and unmarshal + marshaler := ProtoMarshaler{} + bytes, err := marshaler.MarshalProfiles(profiles) + require.NoError(t, err) + + unmarshaler := ProtoUnmarshaler{} + profiles2, err := unmarshaler.UnmarshalProfiles(bytes) + require.NoError(t, err) + + // Verify nested map values are accessible + rp2 := profiles2.ResourceProfiles().At(0) + kvlist2, ok := rp2.Resource().Attributes().Get("nested.map") + assert.True(t, ok) + assert.Equal(t, pcommon.ValueTypeMap, kvlist2.Type()) + + innerMap := kvlist2.Map() + innerVal1, ok := innerMap.Get("inner.key1") + assert.True(t, ok) + assert.Equal(t, "inner.value1", innerVal1.Str()) + + innerVal2, ok := innerMap.Get("inner.key2") + assert.True(t, ok) + assert.Equal(t, "inner.value2", innerVal2.Str()) + + // Verify array values are accessible + arr2, ok := rp2.Resource().Attributes().Get("string.array") + assert.True(t, ok) + assert.Equal(t, pcommon.ValueTypeSlice, arr2.Type()) + + slice := arr2.Slice() + assert.Equal(t, 3, slice.Len()) + assert.Equal(t, "string1", slice.At(0).Str()) + assert.Equal(t, "string2", slice.At(1).Str()) + assert.Equal(t, "string3", slice.At(2).Str()) +} + +func TestRoundTripWithReferences(t *testing.T) { + original := NewProfiles() + dict := original.Dictionary() + dict.StringTable().Append("") + + for i := range 3 { + rp := original.ResourceProfiles().AppendEmpty() + rp.Resource().Attributes().PutStr("resource.id", "resource-"+string(rune('A'+i))) + + for j := range 2 { + sp := rp.ScopeProfiles().AppendEmpty() + sp.Scope().SetName("scope-" + string(rune('X'+j))) + sp.Scope().Attributes().PutStr("scope.version", "1.0.0") + + profile := sp.Profiles().AppendEmpty() + profile.SetProfileID([16]byte{byte(i), byte(j)}) + } + } + + // Marshal + marshaler := ProtoMarshaler{} + bytes, err := marshaler.MarshalProfiles(original) + require.NoError(t, err) + + // Unmarshal + unmarshaler := ProtoUnmarshaler{} + restored, err := unmarshaler.UnmarshalProfiles(bytes) + require.NoError(t, err) + + // Verify structure is preserved + assert.Equal(t, 3, restored.ResourceProfiles().Len()) + + for i := range 3 { + rp := restored.ResourceProfiles().At(i) + resourceID, ok := rp.Resource().Attributes().Get("resource.id") + assert.True(t, ok) + assert.Equal(t, "resource-"+string(rune('A'+i)), resourceID.Str()) + + assert.Equal(t, 2, rp.ScopeProfiles().Len()) + for j := range 2 { + sp := rp.ScopeProfiles().At(j) + assert.Equal(t, "scope-"+string(rune('X'+j)), sp.Scope().Name()) + + scopeVersion, ok := sp.Scope().Attributes().Get("scope.version") + assert.True(t, ok) + assert.Equal(t, "1.0.0", scopeVersion.Str()) + + assert.Equal(t, 1, sp.Profiles().Len()) + } + } + + // Verify the string table deduplication worked + // We should have fewer strings than if everything was duplicated + dictRestored := restored.Dictionary() + // At minimum we have: "", "resource.id", "resource-A", "resource-B", "resource-C", + // "scope.version", "1.0.0" = 7 entries + // May have more due to scope names + assert.LessOrEqual(t, dictRestored.StringTable().Len(), 7, + "String table should deduplicate strings efficiently") +} diff --git a/pdata/pprofile/pb_test.go b/pdata/pprofile/pb_test.go index c40dabc0fd28..7464db127b88 100644 --- a/pdata/pprofile/pb_test.go +++ b/pdata/pprofile/pb_test.go @@ -4,10 +4,13 @@ package pprofile import ( + "fmt" + "strconv" "testing" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + semconv "go.opentelemetry.io/otel/semconv/v1.38.0" gootlpprofiles "go.opentelemetry.io/proto/slim/otlp/profiles/v1development" goproto "google.golang.org/protobuf/proto" ) @@ -42,9 +45,18 @@ func TestProfilesProtoWireCompatibility(t *testing.T) { td2, err = unmarshaler.UnmarshalProfiles(wire2) require.NoError(t, err) - // Now compare that the original and final ProtoBuf messages are the same. - // This proves that goproto and gogoproto marshaling/unmarshaling are wire compatible. - assert.Equal(t, td, td2) + // After unmarshal, td2 will have resolved references (strings instead of string_value_ref/key_ref) + // while td may have references. Marshal td2 again to verify wire compatibility. + wire3, err := marshaler.MarshalProfiles(td2) + require.NoError(t, err) + + // Verify full round-trip fidelity: unmarshal both wire1 and wire3 into goproto + // messages and compare them semantically. This ensures all data (attributes, + // dictionary, profiles, etc.) survives the round-trip through both libraries. + var check1, check2 gootlpprofiles.ProfilesData + require.NoError(t, goproto.Unmarshal(wire1, &check1)) + require.NoError(t, goproto.Unmarshal(wire3, &check2)) + assert.True(t, goproto.Equal(&check1, &check2), "round-trip through goproto did not preserve profile data") } func TestProtoProfilesUnmarshalerError(t *testing.T) { @@ -75,6 +87,8 @@ func BenchmarkProfilesToProto(b *testing.B) { marshaler := &ProtoMarshaler{} profiles := generateBenchmarkProfiles(128) + b.ResetTimer() + b.ReportAllocs() for b.Loop() { buf, err := marshaler.MarshalProfiles(profiles) require.NoError(b, err) @@ -90,6 +104,7 @@ func BenchmarkProfilesFromProto(b *testing.B) { require.NoError(b, err) assert.NotEmpty(b, buf) + b.ResetTimer() b.ReportAllocs() for b.Loop() { profiles, err := unmarshaler.UnmarshalProfiles(buf) @@ -108,3 +123,213 @@ func generateBenchmarkProfiles(samplesCount int) Profiles { } return md } + +// generateProfiles creates a Profiles object with the specified number of resources, scopes, profiles, and samples. +func generateProfiles(b *testing.B, resourceCount, scopeCount, profileCount, sampleCount int) Profiles { + b.Helper() + + profiles := NewProfiles() + dict := profiles.Dictionary() + + // Pre-populate dictionary with common strings + dict.StringTable().Append("") // Index 0 is always empty string + dict.StringTable().Append("cpu") + dict.StringTable().Append("nanoseconds") + dict.StringTable().Append("samples") + dict.StringTable().Append("count") + + // Generate resource profiles + for r := range resourceCount { + rp := profiles.ResourceProfiles().AppendEmpty() + rp.SetSchemaUrl(semconv.SchemaURL) + resource := rp.Resource() + + // Add resource attributes + attrs := resource.Attributes() + attrs.PutStr(string(semconv.ServiceNameKey), fmt.Sprintf("service-%d", r)) + attrs.PutStr(string(semconv.ServiceVersionKey), fmt.Sprintf("version-%d", r)) + attrs.PutStr(string(semconv.ProcessPIDKey), strconv.Itoa(1000+r)) + attrs.PutStr(string(semconv.K8SPodNameKey), fmt.Sprintf("pod-%d", r%10)) + attrs.PutStr(string(semconv.K8SNamespaceNameKey), "default") + attrs.PutStr(string(semconv.TelemetrySDKNameKey), "opentelemetry") + + // Generate scope profiles + for s := range scopeCount { + sp := rp.ScopeProfiles().AppendEmpty() + sp.SetSchemaUrl(semconv.SchemaURL) + scope := sp.Scope() + scope.SetName(fmt.Sprintf("profiler-scope-%d", s)) + scope.SetVersion("1.0.0") + + // Generate profiles + for range profileCount { + profile := sp.Profiles().AppendEmpty() + + // Add sample types + sampleType := profile.SampleType() + sampleType.SetTypeStrindex(1) // "cpu" + sampleType.SetUnitStrindex(2) // "nanoseconds" + + // Add period type + periodType := profile.PeriodType() + periodType.SetTypeStrindex(1) // "cpu" + periodType.SetUnitStrindex(2) // "nanoseconds" + profile.SetPeriod(1000000) + + // Generate samples + samples := profile.Samples() + for i := range sampleCount { + sample := samples.AppendEmpty() + sample.SetStackIndex(int32(i % 100)) + + // Add attribute indices for samples + sample.AttributeIndices().Append(int32(i % 10)) + } + } + } + } + + return profiles +} + +func BenchmarkUnmarshalProfiles(b *testing.B) { + testCases := []struct { + name string + resourceCount int + scopeCount int + profileCount int + sampleCount int + }{ + { + name: "small", + resourceCount: 1, + scopeCount: 1, + profileCount: 1, + sampleCount: 100, + }, + { + name: "medium", + resourceCount: 5, + scopeCount: 2, + profileCount: 2, + sampleCount: 500, + }, + { + name: "large", + resourceCount: 20, + scopeCount: 3, + profileCount: 5, + sampleCount: 1000, + }, + } + + for _, tc := range testCases { + b.Run(tc.name, func(b *testing.B) { + // Generate profile data and marshal it + profiles := generateProfiles(b, tc.resourceCount, tc.scopeCount, tc.profileCount, tc.sampleCount) + marshaler := &ProtoMarshaler{} + data, err := marshaler.MarshalProfiles(profiles) + if err != nil { + b.Fatalf("failed to marshal profiles: %v", err) + } + + unmarshaler := &ProtoUnmarshaler{} + b.ResetTimer() + b.ReportAllocs() + + for i := 0; i < b.N; i++ { + profiles, err := unmarshaler.UnmarshalProfiles(data) + if err != nil { + b.Fatalf("failed to unmarshal: %v", err) + } + _ = profiles + } + }) + } +} + +func BenchmarkMarshalProfiles(b *testing.B) { + testCases := []struct { + name string + resourceCount int + scopeCount int + profileCount int + sampleCount int + }{ + { + name: "small", + resourceCount: 1, + scopeCount: 1, + profileCount: 1, + sampleCount: 100, + }, + { + name: "medium", + resourceCount: 5, + scopeCount: 2, + profileCount: 2, + sampleCount: 500, + }, + { + name: "large", + resourceCount: 20, + scopeCount: 3, + profileCount: 5, + sampleCount: 1000, + }, + } + + for _, tc := range testCases { + b.Run(tc.name, func(b *testing.B) { + marshaler := &ProtoMarshaler{} + + // with_refs: simulate the normal ingest path where data was + // received on the wire (refs present), then unmarshaled (refs + // resolved but KeyRef kept), and is now being re-marshaled + // without any attribute modifications. + b.Run("with_refs", func(b *testing.B) { + profiles := generateProfiles(b, tc.resourceCount, tc.scopeCount, tc.profileCount, tc.sampleCount) + unmarshaler := &ProtoUnmarshaler{} + buf, err := marshaler.MarshalProfiles(profiles) + if err != nil { + b.Fatalf("failed to marshal: %v", err) + } + profiles, err = unmarshaler.UnmarshalProfiles(buf) + if err != nil { + b.Fatalf("failed to unmarshal: %v", err) + } + + b.ResetTimer() + b.ReportAllocs() + + for i := 0; i < b.N; i++ { + buf, err := marshaler.MarshalProfiles(profiles) + if err != nil { + b.Fatalf("failed to marshal: %v", err) + } + _ = buf + } + }) + + // without_refs: each iteration gets a fresh copy with no refs, + // simulating data that was constructed or had attributes modified. + b.Run("without_refs", func(b *testing.B) { + copies := make([]Profiles, b.N) + for i := range copies { + copies[i] = generateProfiles(b, tc.resourceCount, tc.scopeCount, tc.profileCount, tc.sampleCount) + } + + b.ResetTimer() + b.ReportAllocs() + + for i := 0; i < b.N; i++ { + buf, err := marshaler.MarshalProfiles(copies[i]) + if err != nil { + b.Fatalf("failed to marshal: %v", err) + } + _ = buf + } + }) + }) + } +} diff --git a/pdata/pprofile/pprofileotlp/grpc_test.go b/pdata/pprofile/pprofileotlp/grpc_test.go index fb09ba2af7fb..4a2bd3767b28 100644 --- a/pdata/pprofile/pprofileotlp/grpc_test.go +++ b/pdata/pprofile/pprofileotlp/grpc_test.go @@ -27,11 +27,9 @@ func TestGrpc(t *testing.T) { s := grpc.NewServer() RegisterGRPCServer(s, &fakeProfilesServer{t: t}) wg := sync.WaitGroup{} - wg.Add(1) - go func() { - defer wg.Done() + wg.Go(func() { assert.NoError(t, s.Serve(lis)) - }() + }) t.Cleanup(func() { s.Stop() wg.Wait() @@ -60,11 +58,9 @@ func TestGrpcError(t *testing.T) { s := grpc.NewServer() RegisterGRPCServer(s, &fakeProfilesServer{t: t, err: errors.New("my error")}) wg := sync.WaitGroup{} - wg.Add(1) - go func() { - defer wg.Done() + wg.Go(func() { assert.NoError(t, s.Serve(lis)) - }() + }) t.Cleanup(func() { s.Stop() wg.Wait() diff --git a/pdata/pprofile/profile.go b/pdata/pprofile/profile.go index 34690c6f93ac..58b5eeeb92dd 100644 --- a/pdata/pprofile/profile.go +++ b/pdata/pprofile/profile.go @@ -13,15 +13,11 @@ import ( // dictionary to another. func (ms Profile) switchDictionary(src, dst ProfilesDictionary) error { for i, v := range ms.AttributeIndices().All() { - if src.AttributeTable().Len() < int(v) { + if src.AttributeTable().Len() <= int(v) { return fmt.Errorf("invalid attribute index %d", v) } attr := src.AttributeTable().At(int(v)) - err := attr.switchDictionary(src, dst) - if err != nil { - return fmt.Errorf("couldn't switch dictionary for attribute %d: %w", i, err) - } idx, err := SetAttribute(dst.AttributeTable(), attr) if err != nil { return fmt.Errorf("couldn't set attribute %d: %w", i, err) diff --git a/pdata/pprofile/profile_test.go b/pdata/pprofile/profile_test.go index ff8bedb34220..861af6ea20a6 100644 --- a/pdata/pprofile/profile_test.go +++ b/pdata/pprofile/profile_test.go @@ -56,7 +56,7 @@ func TestProfileSwitchDictionary(t *testing.T) { }(), dst: func() ProfilesDictionary { d := NewProfilesDictionary() - d.StringTable().Append("", "foo") + d.StringTable().Append("", "test") d.AttributeTable().AppendEmpty() d.AttributeTable().AppendEmpty() @@ -70,12 +70,12 @@ func TestProfileSwitchDictionary(t *testing.T) { }(), wantDictionary: func() ProfilesDictionary { d := NewProfilesDictionary() - d.StringTable().Append("", "foo", "test") + d.StringTable().Append("", "test") d.AttributeTable().AppendEmpty() d.AttributeTable().AppendEmpty() a := d.AttributeTable().AppendEmpty() - a.SetKeyStrindex(2) + a.SetKeyStrindex(1) return d }(), }, @@ -98,6 +98,30 @@ func TestProfileSwitchDictionary(t *testing.T) { wantDictionary: NewProfilesDictionary(), wantErr: errors.New("invalid attribute index 1"), }, + { + name: "with an attribute index equal to the source table length (boundary condition)", + profile: func() Profile { + p := NewProfile() + p.AttributeIndices().Append(2) + return p + }(), + + src: func() ProfilesDictionary { + d := NewProfilesDictionary() + d.AttributeTable().AppendEmpty() + d.AttributeTable().AppendEmpty() + return d + }(), + dst: NewProfilesDictionary(), + + wantProfile: func() Profile { + p := NewProfile() + p.AttributeIndices().Append(2) + return p + }(), + wantDictionary: NewProfilesDictionary(), + wantErr: errors.New("invalid attribute index 2"), + }, { name: "with a profile that has a sample", profile: func() Profile { @@ -194,6 +218,101 @@ func TestProfileSwitchDictionary(t *testing.T) { return d }(), }, + { + name: "Profile with various elements", + profile: func() Profile { + p := NewProfile() + + p.SampleType().SetTypeStrindex(1) + p.SampleType().SetUnitStrindex(2) + + p.PeriodType().SetTypeStrindex(3) + p.PeriodType().SetUnitStrindex(4) + + p.AttributeIndices().Append(1) + + return p + }(), + src: func() ProfilesDictionary { + d := NewProfilesDictionary() + // Make sure we are conform with the protocol + d.MappingTable().AppendEmpty() + d.LocationTable().AppendEmpty() + d.FunctionTable().AppendEmpty() + d.LinkTable().AppendEmpty() + d.StringTable().Append("") + d.AttributeTable().AppendEmpty() + d.StackTable().AppendEmpty() + + d.StringTable().Append("sample-type") // 1 + d.StringTable().Append("sample-unit") // 2 + d.StringTable().Append("period-type") // 3 + d.StringTable().Append("period-unit") // 4 + d.StringTable().Append("unrelated-1") // 5 + d.StringTable().Append("unrelated-2") // 6 + d.StringTable().Append("attribute-key") // 7 + d.StringTable().Append("attribute-unit") // 8 + + a := d.AttributeTable().AppendEmpty() + a.SetKeyStrindex(7) + a.Value().SetStr("AnyValue") + a.SetUnitStrindex(8) + + return d + }(), + dst: func() ProfilesDictionary { + d := NewProfilesDictionary() + // Make sure we are conform with the protocol + d.MappingTable().AppendEmpty() + d.LocationTable().AppendEmpty() + d.FunctionTable().AppendEmpty() + d.LinkTable().AppendEmpty() + d.StringTable().Append("") + d.AttributeTable().AppendEmpty() + d.StackTable().AppendEmpty() + + return d + }(), + wantProfile: func() Profile { + p := NewProfile() + + p.AttributeIndices().Append(1) + + // Order of entries depend on the order of + // processing in switchDictionary() + p.SampleType().SetTypeStrindex(3) + p.SampleType().SetUnitStrindex(4) + + p.PeriodType().SetTypeStrindex(1) + p.PeriodType().SetUnitStrindex(2) + + return p + }(), + wantDictionary: func() ProfilesDictionary { + d := NewProfilesDictionary() + // Make sure we are conform with the protocol + d.MappingTable().AppendEmpty() + d.LocationTable().AppendEmpty() + d.FunctionTable().AppendEmpty() + d.LinkTable().AppendEmpty() + d.StringTable().Append("") + d.AttributeTable().AppendEmpty() + d.StackTable().AppendEmpty() + + a := d.AttributeTable().AppendEmpty() + a.SetKeyStrindex(7) + a.SetUnitStrindex(8) + a.Value().SetStr("AnyValue") + + // Order of entries depend on the order of + // processing in switchDictionary() + d.StringTable().Append("period-type") // 1 + d.StringTable().Append("period-unit") // 2 + d.StringTable().Append("sample-type") // 3 + d.StringTable().Append("sample-unit") // 4 + return d + }(), + }, } { t.Run(tt.name, func(t *testing.T) { profile := tt.profile diff --git a/pdata/pprofile/profiles.go b/pdata/pprofile/profiles.go index 285ee1516cbb..1d698bdf4f8b 100644 --- a/pdata/pprofile/profiles.go +++ b/pdata/pprofile/profiles.go @@ -35,6 +35,37 @@ func (ms Profiles) SampleCount() int { // switchDictionary updates the Profiles, switching its indices from one // dictionary to another. func (ms Profiles) switchDictionary(src, dst ProfilesDictionary) error { + for i, v := range ms.Dictionary().AttributeTable().All() { + err := v.switchDictionary(src, dst) + if err != nil { + return fmt.Errorf("couldn't switch attribute %d: %w", i, err) + } + } + for i, v := range ms.Dictionary().FunctionTable().All() { + err := v.switchDictionary(src, dst) + if err != nil { + return fmt.Errorf("couldn't switch function %d: %w", i, err) + } + } + for i, v := range ms.Dictionary().MappingTable().All() { + err := v.switchDictionary(src, dst) + if err != nil { + return fmt.Errorf("couldn't switch mapping %d: %w", i, err) + } + } + for i, v := range ms.Dictionary().LocationTable().All() { + err := v.switchDictionary(src, dst) + if err != nil { + return fmt.Errorf("couldn't switch location %d: %w", i, err) + } + } + for i, v := range ms.Dictionary().StackTable().All() { + err := v.switchDictionary(src, dst) + if err != nil { + return fmt.Errorf("couldn't switch stack %d: %w", i, err) + } + } + for i, v := range ms.ResourceProfiles().All() { err := v.switchDictionary(src, dst) if err != nil { @@ -44,3 +75,17 @@ func (ms Profiles) switchDictionary(src, dst ProfilesDictionary) error { return nil } + +// ProfileCount calculates the total number of profile records. +func (ms Profiles) ProfileCount() int { + profileCount := 0 + rps := ms.ResourceProfiles() + for i := 0; i < rps.Len(); i++ { + rp := rps.At(i) + sps := rp.ScopeProfiles() + for j := 0; j < sps.Len(); j++ { + profileCount += sps.At(j).Profiles().Len() + } + } + return profileCount +} diff --git a/pdata/pprofile/profiles_merge.go b/pdata/pprofile/profiles_merge.go new file mode 100644 index 000000000000..851bf739d990 --- /dev/null +++ b/pdata/pprofile/profiles_merge.go @@ -0,0 +1,24 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +package pprofile // import "go.opentelemetry.io/collector/pdata/pprofile" + +// MergeTo merges the current Profiles into dest, updating the destination +// dictionary as needed and appending the resource profiles. +// The source Profiles is consumed and marked read-only after this operation. +func (ms Profiles) MergeTo(dest Profiles) error { + ms.getState().AssertMutable() + dest.getState().AssertMutable() + if ms.getOrig() == dest.getOrig() { + return nil + } + + if err := ms.switchDictionary(ms.Dictionary(), dest.Dictionary()); err != nil { + return err + } + + ms.ResourceProfiles().MoveAndAppendTo(dest.ResourceProfiles()) + ms.MarkReadOnly() + + return nil +} diff --git a/pdata/pprofile/profiles_merge_test.go b/pdata/pprofile/profiles_merge_test.go new file mode 100644 index 000000000000..c1d5ef653130 --- /dev/null +++ b/pdata/pprofile/profiles_merge_test.go @@ -0,0 +1,620 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +package pprofile + +import ( + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func TestProfilesMergeTo(t *testing.T) { + for _, tt := range []struct { + name string + srcProfiles Profiles + dstProfiles Profiles + + // Expected results after merge + expectedDictionarySizes struct { + StringTable int + AttributeTable int + StackTable int + LocationTable int + FunctionTable int + MappingTable int + LinkTable int + } + expectedProfileCount int + }{ + { + name: "Empty Profiles", + expectedDictionarySizes: struct { + StringTable int + AttributeTable int + StackTable int + LocationTable int + FunctionTable int + MappingTable int + LinkTable int + }{ + StringTable: 1, // Just the empty string + AttributeTable: 1, + StackTable: 1, + LocationTable: 1, + FunctionTable: 1, + MappingTable: 1, + LinkTable: 1, + }, + expectedProfileCount: 0, + srcProfiles: func() Profiles { + p := NewProfiles() + + // Make sure we are conform with the protocol + p.Dictionary().MappingTable().AppendEmpty() + p.Dictionary().LocationTable().AppendEmpty() + p.Dictionary().FunctionTable().AppendEmpty() + p.Dictionary().LinkTable().AppendEmpty() + p.Dictionary().StringTable().Append("") + p.Dictionary().AttributeTable().AppendEmpty() + p.Dictionary().StackTable().AppendEmpty() + return p + }(), + dstProfiles: func() Profiles { + p := NewProfiles() + + // Make sure we are conform with the protocol + p.Dictionary().MappingTable().AppendEmpty() + p.Dictionary().LocationTable().AppendEmpty() + p.Dictionary().FunctionTable().AppendEmpty() + p.Dictionary().LinkTable().AppendEmpty() + p.Dictionary().StringTable().Append("") + p.Dictionary().AttributeTable().AppendEmpty() + p.Dictionary().StackTable().AppendEmpty() + return p + }(), + }, + { + name: "Single Profile", + expectedDictionarySizes: struct { + StringTable int + AttributeTable int + StackTable int + LocationTable int + FunctionTable int + MappingTable int + LinkTable int + }{ + StringTable: 7, // empty + 6 strings + AttributeTable: 2, // empty + a1 + StackTable: 2, // empty + st1 + LocationTable: 3, // empty + loc1 + loc2 + FunctionTable: 1, + MappingTable: 1, + LinkTable: 1, + }, + expectedProfileCount: 1, + srcProfiles: func() Profiles { + ps := NewProfiles() + + // Make sure we are conform with the protocol + ps.Dictionary().MappingTable().AppendEmpty() + ps.Dictionary().LocationTable().AppendEmpty() + ps.Dictionary().FunctionTable().AppendEmpty() + ps.Dictionary().LinkTable().AppendEmpty() + ps.Dictionary().StringTable().Append("") + ps.Dictionary().AttributeTable().AppendEmpty() + ps.Dictionary().StackTable().AppendEmpty() + + ps.Dictionary().StringTable().Append("sample-type") // 1 + ps.Dictionary().StringTable().Append("sample-unit") // 2 + ps.Dictionary().StringTable().Append("period-type") // 3 + ps.Dictionary().StringTable().Append("period-unit") // 4 + ps.Dictionary().StringTable().Append("attribute1-key") // 5 + ps.Dictionary().StringTable().Append("attribute1-unit") // 6 + + a1 := ps.Dictionary().AttributeTable().AppendEmpty() + a1.SetKeyStrindex(5) + a1.SetUnitStrindex(6) + a1.Value().SetStr("AnyValue") + + st1 := ps.Dictionary().StackTable().AppendEmpty() + st1.LocationIndices().Append(1, 2) + + loc1 := ps.Dictionary().LocationTable().AppendEmpty() + loc1.SetAddress(1337) + loc2 := ps.Dictionary().LocationTable().AppendEmpty() + ln1 := loc2.Lines().AppendEmpty() + ln1.SetLine(42) + + rp := ps.ResourceProfiles().AppendEmpty() + rp.SetSchemaUrl("resource-schema-url") + rp.Resource().Attributes().PutStr("resource-attribute-key", + "resource-attribute-value") + + sp := rp.ScopeProfiles().AppendEmpty() + sp.SetSchemaUrl("scope-schema-url") + + p := sp.Profiles().AppendEmpty() + p.SampleType().SetTypeStrindex(1) + p.SampleType().SetUnitStrindex(2) + p.PeriodType().SetTypeStrindex(3) + p.PeriodType().SetUnitStrindex(4) + + s1 := p.Samples().AppendEmpty() + s1.AttributeIndices().Append(1) + s1.SetStackIndex(1) + + return ps + }(), + dstProfiles: func() Profiles { + p := NewProfiles() + + // Make sure we are conform with the protocol + p.Dictionary().MappingTable().AppendEmpty() + p.Dictionary().LocationTable().AppendEmpty() + p.Dictionary().FunctionTable().AppendEmpty() + p.Dictionary().LinkTable().AppendEmpty() + p.Dictionary().StringTable().Append("") + p.Dictionary().AttributeTable().AppendEmpty() + p.Dictionary().StackTable().AppendEmpty() + return p + }(), + }, + { + name: "Multiple Profile", + expectedDictionarySizes: struct { + StringTable int + AttributeTable int + StackTable int + LocationTable int + FunctionTable int + MappingTable int + LinkTable int + }{ + StringTable: 7, // empty + 6 strings + AttributeTable: 1, + StackTable: 1, + LocationTable: 1, + FunctionTable: 1, + MappingTable: 1, + LinkTable: 1, + }, + expectedProfileCount: 3, + srcProfiles: func() Profiles { + ps := NewProfiles() + + // Make sure we are conform with the protocol + ps.Dictionary().MappingTable().AppendEmpty() + ps.Dictionary().LocationTable().AppendEmpty() + ps.Dictionary().FunctionTable().AppendEmpty() + ps.Dictionary().LinkTable().AppendEmpty() + ps.Dictionary().StringTable().Append("") + ps.Dictionary().AttributeTable().AppendEmpty() + ps.Dictionary().StackTable().AppendEmpty() + + ps.Dictionary().StringTable().Append("sample-type-1") // 1 + ps.Dictionary().StringTable().Append("sample-unit-1") // 2 + ps.Dictionary().StringTable().Append("sample-type-2") // 3 + ps.Dictionary().StringTable().Append("sample-unit-2") // 4 + ps.Dictionary().StringTable().Append("sample-type-3") // 5 + ps.Dictionary().StringTable().Append("sample-unit-3") // 6 + + rp := ps.ResourceProfiles().AppendEmpty() + rp.SetSchemaUrl("resource-schema-url") + rp.Resource().Attributes().PutStr("resource-attribute-key", + "resource-attribute-value") + + sp := rp.ScopeProfiles().AppendEmpty() + sp.SetSchemaUrl("scope-schema-url") + + p1 := sp.Profiles().AppendEmpty() + p1.SampleType().SetTypeStrindex(1) + p1.SampleType().SetUnitStrindex(2) + + p2 := sp.Profiles().AppendEmpty() + p2.SampleType().SetTypeStrindex(3) + p2.SampleType().SetUnitStrindex(4) + + p3 := sp.Profiles().AppendEmpty() + p3.SampleType().SetTypeStrindex(5) + p3.SampleType().SetUnitStrindex(6) + + return ps + }(), + dstProfiles: func() Profiles { + p := NewProfiles() + + // Make sure we are conform with the protocol + p.Dictionary().MappingTable().AppendEmpty() + p.Dictionary().LocationTable().AppendEmpty() + p.Dictionary().FunctionTable().AppendEmpty() + p.Dictionary().LinkTable().AppendEmpty() + p.Dictionary().StringTable().Append("") + p.Dictionary().AttributeTable().AppendEmpty() + p.Dictionary().StackTable().AppendEmpty() + return p + }(), + }, + { + name: "Multiple Profile with partly prepopulated destination", + expectedDictionarySizes: struct { + StringTable int + AttributeTable int + StackTable int + LocationTable int + FunctionTable int + MappingTable int + LinkTable int + }{ + StringTable: 10, // empty + 3 unrelated + 6 from src + AttributeTable: 1, + StackTable: 1, + LocationTable: 1, + FunctionTable: 1, + MappingTable: 1, + LinkTable: 1, + }, + expectedProfileCount: 3, + srcProfiles: func() Profiles { + ps := NewProfiles() + + // Make sure we are conform with the protocol + ps.Dictionary().MappingTable().AppendEmpty() + ps.Dictionary().LocationTable().AppendEmpty() + ps.Dictionary().FunctionTable().AppendEmpty() + ps.Dictionary().LinkTable().AppendEmpty() + ps.Dictionary().StringTable().Append("") + ps.Dictionary().AttributeTable().AppendEmpty() + ps.Dictionary().StackTable().AppendEmpty() + + ps.Dictionary().StringTable().Append("sample-type-1") // 1 + ps.Dictionary().StringTable().Append("sample-unit-1") // 2 + ps.Dictionary().StringTable().Append("sample-type-2") // 3 + ps.Dictionary().StringTable().Append("sample-unit-2") // 4 + ps.Dictionary().StringTable().Append("sample-type-3") // 5 + ps.Dictionary().StringTable().Append("sample-unit-3") // 6 + + rp := ps.ResourceProfiles().AppendEmpty() + rp.SetSchemaUrl("resource-schema-url") + rp.Resource().Attributes().PutStr("resource-attribute-key", + "resource-attribute-value") + + sp := rp.ScopeProfiles().AppendEmpty() + sp.SetSchemaUrl("scope-schema-url") + + p1 := sp.Profiles().AppendEmpty() + p1.SampleType().SetTypeStrindex(1) + p1.SampleType().SetUnitStrindex(2) + + p2 := sp.Profiles().AppendEmpty() + p2.SampleType().SetTypeStrindex(3) + p2.SampleType().SetUnitStrindex(4) + + p3 := sp.Profiles().AppendEmpty() + p3.SampleType().SetTypeStrindex(5) + p3.SampleType().SetUnitStrindex(6) + + return ps + }(), + dstProfiles: func() Profiles { + ps := NewProfiles() + + // Make sure we are conform with the protocol + ps.Dictionary().MappingTable().AppendEmpty() + ps.Dictionary().LocationTable().AppendEmpty() + ps.Dictionary().FunctionTable().AppendEmpty() + ps.Dictionary().LinkTable().AppendEmpty() + ps.Dictionary().StringTable().Append("") + ps.Dictionary().AttributeTable().AppendEmpty() + ps.Dictionary().StackTable().AppendEmpty() + + ps.Dictionary().StringTable().Append("unrelated-1") // 1 + ps.Dictionary().StringTable().Append("unrelated-2") // 2 + ps.Dictionary().StringTable().Append("unrelated-3") // 3 + return ps + }(), + }, + { + name: "Multiple Profile with reused samples", + expectedDictionarySizes: struct { + StringTable int + AttributeTable int + StackTable int + LocationTable int + FunctionTable int + MappingTable int + LinkTable int + }{ + StringTable: 9, // empty + 8 unique strings after merge + AttributeTable: 1, + StackTable: 3, // empty + 2 unique stacks + LocationTable: 3, // empty + 2 unique locations + FunctionTable: 2, // empty + fn1 + MappingTable: 1, + LinkTable: 1, + }, + expectedProfileCount: 3, + srcProfiles: func() Profiles { + ps := NewProfiles() + + // Make sure we are conform with the protocol + ps.Dictionary().MappingTable().AppendEmpty() + ps.Dictionary().LocationTable().AppendEmpty() + ps.Dictionary().FunctionTable().AppendEmpty() + ps.Dictionary().LinkTable().AppendEmpty() + ps.Dictionary().StringTable().Append("") + ps.Dictionary().AttributeTable().AppendEmpty() + ps.Dictionary().StackTable().AppendEmpty() + + ps.Dictionary().StringTable().Append("sample-type-1") // 1 + ps.Dictionary().StringTable().Append("sample-unit-1") // 2 + ps.Dictionary().StringTable().Append("sample-type-2") // 3 + ps.Dictionary().StringTable().Append("sample-unit-2") // 4 + ps.Dictionary().StringTable().Append("sample-type-3") // 5 + ps.Dictionary().StringTable().Append("sample-unit-3") // 6 + ps.Dictionary().StringTable().Append("filename-1") // 7 + ps.Dictionary().StringTable().Append("functionname-1") // 8 + + st1 := ps.Dictionary().StackTable().AppendEmpty() + st1.LocationIndices().Append(1) + + st2 := ps.Dictionary().StackTable().AppendEmpty() + st2.LocationIndices().Append(2) + + loc1 := ps.Dictionary().LocationTable().AppendEmpty() + loc1.SetAddress(42) + + loc2 := ps.Dictionary().LocationTable().AppendEmpty() + ln1 := loc2.Lines().AppendEmpty() + ln1.SetFunctionIndex(1) + ln1.SetLine(1337) + + fn1 := ps.Dictionary().FunctionTable().AppendEmpty() + fn1.SetFilenameStrindex(7) + fn1.SetNameStrindex(8) + + rp := ps.ResourceProfiles().AppendEmpty() + rp.SetSchemaUrl("resource-schema-url") + rp.Resource().Attributes().PutStr("resource-attribute-key", + "resource-attribute-value") + + sp := rp.ScopeProfiles().AppendEmpty() + sp.SetSchemaUrl("scope-schema-url") + + p1 := sp.Profiles().AppendEmpty() + p1.SampleType().SetTypeStrindex(1) + p1.SampleType().SetUnitStrindex(2) + s1 := p1.Samples().AppendEmpty() + s1.SetStackIndex(1) + + p2 := sp.Profiles().AppendEmpty() + p2.SampleType().SetTypeStrindex(3) + p2.SampleType().SetUnitStrindex(4) + s2 := p2.Samples().AppendEmpty() + s2.SetStackIndex(2) + + p3 := sp.Profiles().AppendEmpty() + p3.SampleType().SetTypeStrindex(5) + p3.SampleType().SetUnitStrindex(6) + s3 := p3.Samples().AppendEmpty() + s3.SetStackIndex(1) + + return ps + }(), + dstProfiles: func() Profiles { + p := NewProfiles() + + // Make sure we are conform with the protocol + p.Dictionary().MappingTable().AppendEmpty() + p.Dictionary().LocationTable().AppendEmpty() + p.Dictionary().FunctionTable().AppendEmpty() + p.Dictionary().LinkTable().AppendEmpty() + p.Dictionary().StringTable().Append("") + p.Dictionary().AttributeTable().AppendEmpty() + p.Dictionary().StackTable().AppendEmpty() + return p + }(), + }, + { + name: "Multiple ResourceProfiles with reused samples", + expectedDictionarySizes: struct { + StringTable int + AttributeTable int + StackTable int + LocationTable int + FunctionTable int + MappingTable int + LinkTable int + }{ + StringTable: 9, // empty + 8 unique strings + AttributeTable: 1, + StackTable: 3, // empty + 2 unique stacks + LocationTable: 3, // empty + 2 unique locations + FunctionTable: 2, // empty + fn1 + MappingTable: 2, // empty + m1 + LinkTable: 1, + }, + expectedProfileCount: 6, + srcProfiles: func() Profiles { + ps := NewProfiles() + + // Make sure we are conform with the protocol + ps.Dictionary().MappingTable().AppendEmpty() + ps.Dictionary().LocationTable().AppendEmpty() + ps.Dictionary().FunctionTable().AppendEmpty() + ps.Dictionary().LinkTable().AppendEmpty() + ps.Dictionary().StringTable().Append("") + ps.Dictionary().AttributeTable().AppendEmpty() + ps.Dictionary().StackTable().AppendEmpty() + + ps.Dictionary().StringTable().Append("sample-type-1") // 1 + ps.Dictionary().StringTable().Append("sample-unit-1") // 2 + ps.Dictionary().StringTable().Append("sample-type-2") // 3 + ps.Dictionary().StringTable().Append("sample-unit-2") // 4 + ps.Dictionary().StringTable().Append("sample-type-3") // 5 + ps.Dictionary().StringTable().Append("sample-unit-3") // 6 + ps.Dictionary().StringTable().Append("filename-1") // 7 + ps.Dictionary().StringTable().Append("functionname-1") // 8 + + st1 := ps.Dictionary().StackTable().AppendEmpty() + st1.LocationIndices().Append(1) + + st2 := ps.Dictionary().StackTable().AppendEmpty() + st2.LocationIndices().Append(2) + + loc1 := ps.Dictionary().LocationTable().AppendEmpty() + loc1.SetAddress(42) + loc1.SetMappingIndex(1) + + loc2 := ps.Dictionary().LocationTable().AppendEmpty() + ln1 := loc2.Lines().AppendEmpty() + ln1.SetFunctionIndex(1) + ln1.SetLine(1337) + + fn1 := ps.Dictionary().FunctionTable().AppendEmpty() + fn1.SetFilenameStrindex(7) + fn1.SetNameStrindex(8) + + m1 := ps.Dictionary().MappingTable().AppendEmpty() + m1.SetFilenameStrindex(8) + + rp1 := ps.ResourceProfiles().AppendEmpty() + rp1.SetSchemaUrl("resource-schema-url") + rp1.Resource().Attributes().PutStr("resource-attribute-key", + "resource-attribute-value") + + sp1 := rp1.ScopeProfiles().AppendEmpty() + sp1.SetSchemaUrl("scope-schema-url") + + p11 := sp1.Profiles().AppendEmpty() + p11.SampleType().SetTypeStrindex(1) + p11.SampleType().SetUnitStrindex(2) + s11 := p11.Samples().AppendEmpty() + s11.SetStackIndex(1) + + p12 := sp1.Profiles().AppendEmpty() + p12.SampleType().SetTypeStrindex(3) + p12.SampleType().SetUnitStrindex(4) + s12 := p12.Samples().AppendEmpty() + s12.SetStackIndex(2) + + p13 := sp1.Profiles().AppendEmpty() + p13.SampleType().SetTypeStrindex(5) + p13.SampleType().SetUnitStrindex(6) + s13 := p13.Samples().AppendEmpty() + s13.SetStackIndex(1) + + rp2 := ps.ResourceProfiles().AppendEmpty() + rp2.SetSchemaUrl("resource-schema-url") + rp2.Resource().Attributes().PutStr("resource-attribute-key", + "resource-attribute-value") + + sp2 := rp2.ScopeProfiles().AppendEmpty() + sp2.SetSchemaUrl("scope-schema-url") + + p21 := sp2.Profiles().AppendEmpty() + p21.SampleType().SetTypeStrindex(1) + p21.SampleType().SetUnitStrindex(2) + s21 := p21.Samples().AppendEmpty() + s21.SetStackIndex(1) + + p22 := sp2.Profiles().AppendEmpty() + p22.SampleType().SetTypeStrindex(3) + p22.SampleType().SetUnitStrindex(4) + s22 := p22.Samples().AppendEmpty() + s22.SetStackIndex(2) + + p23 := sp2.Profiles().AppendEmpty() + p23.SampleType().SetTypeStrindex(5) + p23.SampleType().SetUnitStrindex(6) + s23 := p23.Samples().AppendEmpty() + s23.SetStackIndex(1) + + return ps + }(), + dstProfiles: func() Profiles { + p := NewProfiles() + + // Make sure we are conform with the protocol + p.Dictionary().MappingTable().AppendEmpty() + p.Dictionary().LocationTable().AppendEmpty() + p.Dictionary().FunctionTable().AppendEmpty() + p.Dictionary().LinkTable().AppendEmpty() + p.Dictionary().StringTable().Append("") + p.Dictionary().AttributeTable().AppendEmpty() + p.Dictionary().StackTable().AppendEmpty() + return p + }(), + }, + } { + t.Run(tt.name, func(t *testing.T) { + srcProfiles := tt.srcProfiles + dstProfiles := tt.dstProfiles + err := srcProfiles.MergeTo(dstProfiles) + require.NoError(t, err) + + // Verify dictionary sizes + assert.Equal(t, tt.expectedDictionarySizes.StringTable, dstProfiles.Dictionary().StringTable().Len(), + "StringTable size mismatch") + assert.Equal(t, tt.expectedDictionarySizes.AttributeTable, dstProfiles.Dictionary().AttributeTable().Len(), + "AttributeTable size mismatch") + assert.Equal(t, tt.expectedDictionarySizes.StackTable, dstProfiles.Dictionary().StackTable().Len(), + "StackTable size mismatch") + assert.Equal(t, tt.expectedDictionarySizes.LocationTable, dstProfiles.Dictionary().LocationTable().Len(), + "LocationTable size mismatch") + assert.Equal(t, tt.expectedDictionarySizes.FunctionTable, dstProfiles.Dictionary().FunctionTable().Len(), + "FunctionTable size mismatch") + assert.Equal(t, tt.expectedDictionarySizes.MappingTable, dstProfiles.Dictionary().MappingTable().Len(), + "MappingTable size mismatch") + assert.Equal(t, tt.expectedDictionarySizes.LinkTable, dstProfiles.Dictionary().LinkTable().Len(), + "LinkTable size mismatch") + + // Verify profile count + totalProfiles := 0 + for _, rp := range dstProfiles.ResourceProfiles().All() { + for _, sp := range rp.ScopeProfiles().All() { + totalProfiles += sp.Profiles().Len() + } + } + assert.Equal(t, tt.expectedProfileCount, totalProfiles, "Total profile count mismatch") + }) + } +} + +func TestProfilesMergeToSelf(t *testing.T) { + profiles := NewProfiles() + profiles.Dictionary().StringTable().Append("", "test") + profiles.ResourceProfiles().AppendEmpty() + + require.NoError(t, profiles.MergeTo(profiles)) + + assert.Equal(t, 2, profiles.Dictionary().StringTable().Len()) + assert.Equal(t, 1, profiles.ResourceProfiles().Len()) +} + +func TestProfilesMergeToError(t *testing.T) { + src := NewProfiles() + dest := NewProfiles() + + stackTable := src.Dictionary().StackTable() + stackTable.AppendEmpty() + stack := stackTable.AppendEmpty() + stack.LocationIndices().Append(1) + + locationTable := src.Dictionary().LocationTable() + locationTable.AppendEmpty() + locationTable.AppendEmpty().SetMappingIndex(1) + + sample := src.ResourceProfiles().AppendEmpty(). + ScopeProfiles().AppendEmpty(). + Profiles().AppendEmpty(). + Samples().AppendEmpty() + sample.SetStackIndex(1) + + err := src.MergeTo(dest) + require.Error(t, err) + + assert.Equal(t, 0, dest.ResourceProfiles().Len()) +} diff --git a/pdata/pprofile/profiles_test.go b/pdata/pprofile/profiles_test.go index fb225a424e73..ec10ca940f5c 100644 --- a/pdata/pprofile/profiles_test.go +++ b/pdata/pprofile/profiles_test.go @@ -61,6 +61,42 @@ func TestSampleCount(t *testing.T) { assert.Equal(t, 7, pd.SampleCount()) } +func TestProfileCount(t *testing.T) { + pd := NewProfiles() + assert.Equal(t, 0, pd.ProfileCount()) + + rs := pd.ResourceProfiles().AppendEmpty() + assert.Equal(t, 0, pd.ProfileCount()) + + ils := rs.ScopeProfiles().AppendEmpty() + assert.Equal(t, 0, pd.ProfileCount()) + + ps := ils.Profiles().AppendEmpty() + assert.Equal(t, 1, pd.ProfileCount()) + + ps.Samples().AppendEmpty() + assert.Equal(t, 1, pd.ProfileCount()) + + ils2 := rs.ScopeProfiles().AppendEmpty() + assert.Equal(t, 1, pd.ProfileCount()) + + ps2 := ils2.Profiles().AppendEmpty() + assert.Equal(t, 2, pd.ProfileCount()) + + ps2.Samples().AppendEmpty() + assert.Equal(t, 2, pd.ProfileCount()) + + rms := pd.ResourceProfiles() + rms.EnsureCapacity(3) + rms.AppendEmpty().ScopeProfiles().AppendEmpty() + ilss := rms.AppendEmpty().ScopeProfiles().AppendEmpty().Profiles().AppendEmpty().Samples() + for range 5 { + ilss.AppendEmpty() + } + // 5 + 2 (from rms.At(0) and rms.At(1) initialized first) + assert.Equal(t, 3, pd.ProfileCount()) +} + func TestSampleCountWithEmpty(t *testing.T) { assert.Equal(t, 0, newProfiles(&internal.ExportProfilesServiceRequest{ ResourceProfiles: []*internal.ResourceProfiles{{}}, diff --git a/pdata/pprofile/sample.go b/pdata/pprofile/sample.go index a0bbd29ffead..eceae78f5c41 100644 --- a/pdata/pprofile/sample.go +++ b/pdata/pprofile/sample.go @@ -9,15 +9,11 @@ import "fmt" // dictionary to another. func (ms Sample) switchDictionary(src, dst ProfilesDictionary) error { for i, v := range ms.AttributeIndices().All() { - if src.AttributeTable().Len() < int(v) { + if src.AttributeTable().Len() <= int(v) { return fmt.Errorf("invalid attribute index %d", v) } attr := src.AttributeTable().At(int(v)) - err := attr.switchDictionary(src, dst) - if err != nil { - return fmt.Errorf("couldn't switch dictionary for attribute %d: %w", i, err) - } idx, err := SetAttribute(dst.AttributeTable(), attr) if err != nil { return fmt.Errorf("couldn't set attribute %d: %w", i, err) @@ -26,7 +22,7 @@ func (ms Sample) switchDictionary(src, dst ProfilesDictionary) error { } if ms.LinkIndex() > 0 { - if src.LinkTable().Len() < int(ms.LinkIndex()) { + if src.LinkTable().Len() <= int(ms.LinkIndex()) { return fmt.Errorf("invalid link index %d", ms.LinkIndex()) } @@ -38,16 +34,11 @@ func (ms Sample) switchDictionary(src, dst ProfilesDictionary) error { } if ms.StackIndex() > 0 { - if src.StackTable().Len() < int(ms.StackIndex()) { + if src.StackTable().Len() <= int(ms.StackIndex()) { return fmt.Errorf("invalid stack index %d", ms.StackIndex()) } stack := src.StackTable().At(int(ms.StackIndex())) - err := stack.switchDictionary(src, dst) - if err != nil { - return fmt.Errorf("couldn't switch stack dictionary: %w", err) - } - idx, err := SetStack(dst.StackTable(), stack) if err != nil { return fmt.Errorf("couldn't set stack: %w", err) diff --git a/pdata/pprofile/sample_test.go b/pdata/pprofile/sample_test.go index 4efe651d5473..7e8331517725 100644 --- a/pdata/pprofile/sample_test.go +++ b/pdata/pprofile/sample_test.go @@ -56,10 +56,12 @@ func TestSampleSwitchDictionary(t *testing.T) { }(), dst: func() ProfilesDictionary { d := NewProfilesDictionary() - d.StringTable().Append("", "foo") + d.StringTable().Append("", "test") d.AttributeTable().AppendEmpty() d.AttributeTable().AppendEmpty() + a := d.AttributeTable().AppendEmpty() + a.SetKeyStrindex(1) return d }(), @@ -70,12 +72,12 @@ func TestSampleSwitchDictionary(t *testing.T) { }(), wantDictionary: func() ProfilesDictionary { d := NewProfilesDictionary() - d.StringTable().Append("", "foo", "test") + d.StringTable().Append("", "test") d.AttributeTable().AppendEmpty() d.AttributeTable().AppendEmpty() a := d.AttributeTable().AppendEmpty() - a.SetKeyStrindex(2) + a.SetKeyStrindex(1) return d }(), }, @@ -98,6 +100,30 @@ func TestSampleSwitchDictionary(t *testing.T) { wantDictionary: NewProfilesDictionary(), wantErr: errors.New("invalid attribute index 1"), }, + { + name: "with an attribute index equal to the source table length (boundary condition)", + sample: func() Sample { + s := NewSample() + s.AttributeIndices().Append(2) + return s + }(), + + src: func() ProfilesDictionary { + d := NewProfilesDictionary() + d.AttributeTable().AppendEmpty() + d.AttributeTable().AppendEmpty() + return d + }(), + dst: NewProfilesDictionary(), + + wantSample: func() Sample { + s := NewSample() + s.AttributeIndices().Append(2) + return s + }(), + wantDictionary: NewProfilesDictionary(), + wantErr: errors.New("invalid attribute index 2"), + }, { name: "with an existing link", sample: func() Sample { @@ -153,6 +179,30 @@ func TestSampleSwitchDictionary(t *testing.T) { wantDictionary: NewProfilesDictionary(), wantErr: errors.New("invalid link index 1"), }, + { + name: "with a link index equal to the source table length (boundary condition)", + sample: func() Sample { + s := NewSample() + s.SetLinkIndex(2) + return s + }(), + + src: func() ProfilesDictionary { + d := NewProfilesDictionary() + d.LinkTable().AppendEmpty() + d.LinkTable().AppendEmpty() + return d + }(), + dst: NewProfilesDictionary(), + + wantSample: func() Sample { + s := NewSample() + s.SetLinkIndex(2) + return s + }(), + wantDictionary: NewProfilesDictionary(), + wantErr: errors.New("invalid link index 2"), + }, { name: "with an existing stack", sample: func() Sample { @@ -173,8 +223,13 @@ func TestSampleSwitchDictionary(t *testing.T) { }(), dst: func() ProfilesDictionary { d := NewProfilesDictionary() + d.LocationTable().AppendEmpty() + d.LocationTable().AppendEmpty().SetAddress(2) + d.StackTable().AppendEmpty() d.StackTable().AppendEmpty() + s := d.StackTable().AppendEmpty() + s.LocationIndices().Append(1) return d }(), @@ -185,12 +240,13 @@ func TestSampleSwitchDictionary(t *testing.T) { }(), wantDictionary: func() ProfilesDictionary { d := NewProfilesDictionary() + d.LocationTable().AppendEmpty() d.LocationTable().AppendEmpty().SetAddress(2) d.StackTable().AppendEmpty() d.StackTable().AppendEmpty() s := d.StackTable().AppendEmpty() - s.LocationIndices().Append(0) + s.LocationIndices().Append(1) return d }(), }, @@ -213,6 +269,30 @@ func TestSampleSwitchDictionary(t *testing.T) { wantDictionary: NewProfilesDictionary(), wantErr: errors.New("invalid stack index 1"), }, + { + name: "with a stack index equal to the source table length (boundary condition)", + sample: func() Sample { + s := NewSample() + s.SetStackIndex(2) + return s + }(), + + src: func() ProfilesDictionary { + d := NewProfilesDictionary() + d.StackTable().AppendEmpty() + d.StackTable().AppendEmpty() + return d + }(), + dst: NewProfilesDictionary(), + + wantSample: func() Sample { + s := NewSample() + s.SetStackIndex(2) + return s + }(), + wantDictionary: NewProfilesDictionary(), + wantErr: errors.New("invalid stack index 2"), + }, } { t.Run(tt.name, func(t *testing.T) { sample := tt.sample diff --git a/pdata/pprofile/stack.go b/pdata/pprofile/stack.go index 87fd216ef3e7..ee4652c241c8 100644 --- a/pdata/pprofile/stack.go +++ b/pdata/pprofile/stack.go @@ -26,15 +26,11 @@ func (ms Stack) Equal(val Stack) bool { // dictionary to another. func (ms Stack) switchDictionary(src, dst ProfilesDictionary) error { for i, v := range ms.LocationIndices().All() { - if src.LocationTable().Len() < int(v) { + if src.LocationTable().Len() <= int(v) { return fmt.Errorf("invalid location index %d", v) } loc := src.LocationTable().At(int(v)) - err := loc.switchDictionary(src, dst) - if err != nil { - return fmt.Errorf("couldn't switch dictionary for location: %w", err) - } idx, err := SetLocation(dst.LocationTable(), loc) if err != nil { return fmt.Errorf("couldn't set location %d: %w", i, err) diff --git a/pdata/pprofile/stack_test.go b/pdata/pprofile/stack_test.go index 00cc33e65ce2..51fa9152f3e0 100644 --- a/pdata/pprofile/stack_test.go +++ b/pdata/pprofile/stack_test.go @@ -178,6 +178,31 @@ func TestStackSwitchDictionary(t *testing.T) { }(), wantDictionary: NewProfilesDictionary(), + wantErr: errors.New("invalid location index 2"), + }, + { + name: "with a location index equal to the source table length (boundary condition)", + stack: func() Stack { + s := NewStack() + s.LocationIndices().Append(2) // Index 2 with length 2 (indices 0,1 are valid) + return s + }(), + + src: func() ProfilesDictionary { + d := NewProfilesDictionary() + d.LocationTable().AppendEmpty() // Index 0 + d.LocationTable().AppendEmpty() // Index 1 + return d + }(), + dst: NewProfilesDictionary(), + + wantStack: func() Stack { + s := NewStack() + s.LocationIndices().Append(2) + return s + }(), + wantDictionary: NewProfilesDictionary(), + wantErr: errors.New("invalid location index 2"), }, } { diff --git a/pdata/pprofile/stacks.go b/pdata/pprofile/stacks.go index 762429d7994f..895f2fc4e6da 100644 --- a/pdata/pprofile/stacks.go +++ b/pdata/pprofile/stacks.go @@ -18,7 +18,7 @@ func SetStack(table StackSlice, st Stack) (int32, error) { if j > math.MaxInt32 { return 0, errTooManyStackTableEntries } - return int32(j), nil //nolint:gosec // G115 overflow checked + return int32(j), nil } } @@ -27,5 +27,5 @@ func SetStack(table StackSlice, st Stack) (int32, error) { } st.CopyTo(table.AppendEmpty()) - return int32(table.Len() - 1), nil //nolint:gosec // G115 overflow checked + return int32(table.Len() - 1), nil } diff --git a/pdata/pprofile/stacks_test.go b/pdata/pprofile/stacks_test.go index 5eaadec38b00..0b4feaa940c8 100644 --- a/pdata/pprofile/stacks_test.go +++ b/pdata/pprofile/stacks_test.go @@ -37,7 +37,7 @@ func TestSetStack(t *testing.T) { idx, err = SetStack(table, s2) require.NoError(t, err) assert.Equal(t, 2, table.Len()) - assert.Equal(t, int32(table.Len()-1), idx) //nolint:gosec // G115 + assert.Equal(t, int32(table.Len()-1), idx) // Set an existing stack idx, err = SetStack(table, s) @@ -48,7 +48,7 @@ func TestSetStack(t *testing.T) { idx, err = SetStack(table, s2) require.NoError(t, err) assert.Equal(t, 2, table.Len()) - assert.Equal(t, int32(table.Len()-1), idx) //nolint:gosec // G115 + assert.Equal(t, int32(table.Len()-1), idx) } func BenchmarkSetStack(b *testing.B) { diff --git a/pdata/pprofile/string_table.go b/pdata/pprofile/string_table.go index 3c1ffb304c83..e1f4d6023f33 100644 --- a/pdata/pprofile/string_table.go +++ b/pdata/pprofile/string_table.go @@ -20,7 +20,7 @@ func SetString(table pcommon.StringSlice, val string) (int32, error) { return 0, errTooManyStringTableEntries } // Return the index of the existing value. - return int32(j), nil //nolint:gosec // G115 overflow checked + return int32(j), nil } } @@ -29,5 +29,5 @@ func SetString(table pcommon.StringSlice, val string) (int32, error) { } table.Append(val) - return int32(table.Len() - 1), nil //nolint:gosec // G115 overflow checked + return int32(table.Len() - 1), nil } diff --git a/pdata/pprofile/string_table_test.go b/pdata/pprofile/string_table_test.go index 5b73b7fcff53..20c36530db73 100644 --- a/pdata/pprofile/string_table_test.go +++ b/pdata/pprofile/string_table_test.go @@ -36,7 +36,7 @@ func TestSetString(t *testing.T) { idx, err = SetString(table, v2) require.NoError(t, err) assert.Equal(t, 2, table.Len()) - assert.Equal(t, int32(table.Len()-1), idx) //nolint:gosec // G115 + assert.Equal(t, int32(table.Len()-1), idx) // Set an existing value idx, err = SetString(table, v) @@ -47,7 +47,7 @@ func TestSetString(t *testing.T) { idx, err = SetString(table, v2) require.NoError(t, err) assert.Equal(t, 2, table.Len()) - assert.Equal(t, int32(table.Len()-1), idx) //nolint:gosec // G115 + assert.Equal(t, int32(table.Len()-1), idx) } func BenchmarkSetString(b *testing.B) { diff --git a/pdata/pprofile/valuetype.go b/pdata/pprofile/valuetype.go index 2d2e735c0187..1d6339f68cf0 100644 --- a/pdata/pprofile/valuetype.go +++ b/pdata/pprofile/valuetype.go @@ -9,7 +9,7 @@ import "fmt" // dictionary to another. func (ms ValueType) switchDictionary(src, dst ProfilesDictionary) error { if ms.TypeStrindex() > 0 { - if src.StringTable().Len() < int(ms.TypeStrindex()) { + if src.StringTable().Len() <= int(ms.TypeStrindex()) { return fmt.Errorf("invalid type index %d", ms.TypeStrindex()) } @@ -21,7 +21,7 @@ func (ms ValueType) switchDictionary(src, dst ProfilesDictionary) error { } if ms.UnitStrindex() > 0 { - if src.StringTable().Len() < int(ms.UnitStrindex()) { + if src.StringTable().Len() <= int(ms.UnitStrindex()) { return fmt.Errorf("invalid unit index %d", ms.UnitStrindex()) } diff --git a/pdata/pprofile/valuetype_test.go b/pdata/pprofile/valuetype_test.go index 19539c5ab02b..999721a443ea 100644 --- a/pdata/pprofile/valuetype_test.go +++ b/pdata/pprofile/valuetype_test.go @@ -84,6 +84,29 @@ func TestValueTypeSwitchDictionary(t *testing.T) { wantDictionary: NewProfilesDictionary(), wantErr: errors.New("invalid type index 1"), }, + { + name: "with a type index equal to the source table length (boundary condition)", + valueType: func() ValueType { + vt := NewValueType() + vt.SetTypeStrindex(2) + return vt + }(), + + src: func() ProfilesDictionary { + d := NewProfilesDictionary() + d.StringTable().Append("", "test") + return d + }(), + dst: NewProfilesDictionary(), + + wantValueType: func() ValueType { + vt := NewValueType() + vt.SetTypeStrindex(2) + return vt + }(), + wantDictionary: NewProfilesDictionary(), + wantErr: errors.New("invalid type index 2"), + }, { name: "with an existing unit", valueType: func() ValueType { @@ -133,6 +156,29 @@ func TestValueTypeSwitchDictionary(t *testing.T) { wantDictionary: NewProfilesDictionary(), wantErr: errors.New("invalid unit index 1"), }, + { + name: "with a unit index equal to the source table length (boundary condition)", + valueType: func() ValueType { + vt := NewValueType() + vt.SetUnitStrindex(2) + return vt + }(), + + src: func() ProfilesDictionary { + d := NewProfilesDictionary() + d.StringTable().Append("", "test") + return d + }(), + dst: NewProfilesDictionary(), + + wantValueType: func() ValueType { + vt := NewValueType() + vt.SetUnitStrindex(2) + return vt + }(), + wantDictionary: NewProfilesDictionary(), + wantErr: errors.New("invalid unit index 2"), + }, } { t.Run(tt.name, func(t *testing.T) { vt := tt.valueType diff --git a/pdata/ptrace/pb_test.go b/pdata/ptrace/pb_test.go index 7f6ad53d4318..7a2d4aeadc5e 100644 --- a/pdata/ptrace/pb_test.go +++ b/pdata/ptrace/pb_test.go @@ -74,9 +74,9 @@ func TestProtoSizerEmptyTraces(t *testing.T) { assert.Equal(t, 0, sizer.TracesSize(NewTraces())) } -func BenchmarkTracesToProto(b *testing.B) { +func BenchmarkTracesToProto2k(b *testing.B) { marshaler := &ProtoMarshaler{} - traces := generateBenchmarkTraces(128) + traces := generateBenchmarkTraces(2_000) for b.Loop() { buf, err := marshaler.MarshalTraces(traces) @@ -85,10 +85,10 @@ func BenchmarkTracesToProto(b *testing.B) { } } -func BenchmarkTracesFromProto(b *testing.B) { +func BenchmarkTracesFromProto2k(b *testing.B) { marshaler := &ProtoMarshaler{} unmarshaler := &ProtoUnmarshaler{} - baseTraces := generateBenchmarkTraces(128) + baseTraces := generateBenchmarkTraces(2_000) buf, err := marshaler.MarshalTraces(baseTraces) require.NoError(b, err) assert.NotEmpty(b, buf) diff --git a/pdata/ptrace/ptraceotlp/grpc_test.go b/pdata/ptrace/ptraceotlp/grpc_test.go index 2172245de618..7c7b8addfbbc 100644 --- a/pdata/ptrace/ptraceotlp/grpc_test.go +++ b/pdata/ptrace/ptraceotlp/grpc_test.go @@ -27,11 +27,9 @@ func TestGrpc(t *testing.T) { s := grpc.NewServer() RegisterGRPCServer(s, &fakeTracesServer{t: t}) wg := sync.WaitGroup{} - wg.Add(1) - go func() { - defer wg.Done() + wg.Go(func() { assert.NoError(t, s.Serve(lis)) - }() + }) t.Cleanup(func() { s.Stop() wg.Wait() @@ -60,11 +58,9 @@ func TestGrpcError(t *testing.T) { s := grpc.NewServer() RegisterGRPCServer(s, &fakeTracesServer{t: t, err: errors.New("my error")}) wg := sync.WaitGroup{} - wg.Add(1) - go func() { - defer wg.Done() + wg.Go(func() { assert.NoError(t, s.Serve(lis)) - }() + }) t.Cleanup(func() { s.Stop() wg.Wait() diff --git a/pdata/testdata/go.mod b/pdata/testdata/go.mod index cda5d60664b5..30b2d243fbbc 100644 --- a/pdata/testdata/go.mod +++ b/pdata/testdata/go.mod @@ -1,18 +1,18 @@ module go.opentelemetry.io/collector/pdata/testdata -go 1.24.0 +go 1.25.0 require ( - go.opentelemetry.io/collector/pdata v1.46.0 - go.opentelemetry.io/collector/pdata/pprofile v0.140.0 + go.opentelemetry.io/collector/pdata v1.54.0 + go.opentelemetry.io/collector/pdata/pprofile v0.148.0 ) require ( - github.com/hashicorp/go-version v1.7.0 // indirect + github.com/hashicorp/go-version v1.8.0 // indirect github.com/json-iterator/go v1.1.12 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee // indirect - go.opentelemetry.io/collector/featuregate v1.46.0 // indirect + go.opentelemetry.io/collector/featuregate v1.54.0 // indirect go.uber.org/multierr v1.11.0 // indirect ) diff --git a/pdata/testdata/go.sum b/pdata/testdata/go.sum index 0241432f46a6..fb9006591bec 100644 --- a/pdata/testdata/go.sum +++ b/pdata/testdata/go.sum @@ -1,9 +1,11 @@ +github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= +github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= -github.com/hashicorp/go-version v1.7.0 h1:5tqGy27NaOTB8yJKUZELlFAS/LTKJkrmONwQKeRZfjY= -github.com/hashicorp/go-version v1.7.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= +github.com/hashicorp/go-version v1.8.0 h1:KAkNb1HAiZd1ukkxDFGmokVZe1Xy9HG6NUp+bPle2i4= +github.com/hashicorp/go-version v1.8.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= @@ -18,17 +20,19 @@ github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+ github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U= github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= -go.opentelemetry.io/proto/slim/otlp v1.9.0 h1:fPVMv8tP3TrsqlkH1HWYUpbCY9cAIemx184VGkS6vlE= -go.opentelemetry.io/proto/slim/otlp v1.9.0/go.mod h1:xXdeJJ90Gqyll+orzUkY4bOd2HECo5JofeoLpymVqdI= -go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.2.0 h1:o13nadWDNkH/quoDomDUClnQBpdQQ2Qqv0lQBjIXjE8= -go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.2.0/go.mod h1:Gyb6Xe7FTi/6xBHwMmngGoHqL0w29Y4eW8TGFzpefGA= -go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.2.0 h1:EiUYvtwu6PMrMHVjcPfnsG3v+ajPkbUeH+IL93+QYyk= -go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.2.0/go.mod h1:mUUHKFiN2SST3AhJ8XhJxEoeVW12oqfXog0Bo8W3Ec4= +go.opentelemetry.io/otel v1.40.0 h1:oA5YeOcpRTXq6NN7frwmwFR0Cn3RhTVZvXsP4duvCms= +go.opentelemetry.io/otel v1.40.0/go.mod h1:IMb+uXZUKkMXdPddhwAHm6UfOwJyh4ct1ybIlV14J0g= +go.opentelemetry.io/proto/slim/otlp v1.10.0 h1:iR97Vs/ZDR+y9TfuP9b1XBtdPWeC+OMslIBmhcLU7jM= +go.opentelemetry.io/proto/slim/otlp v1.10.0/go.mod h1:lV9250stpjYLPNA5viFabIgP2QlUGRT1GdTgAf8SIUk= +go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.3.0 h1:RUF5rO0hAlgiJt1fzQVzcVs3vZVNHIcMLgOgG4rWNcQ= +go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.3.0/go.mod h1:I89cynRj8y+383o7tEQVg2SVA6SRgDVIouWPUVXjx0U= +go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.3.0 h1:CQvJSldHRUN6Z8jsUeYv8J0lXRvygALXIzsmAeCcZE0= +go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.3.0/go.mod h1:xSQ+mEfJe/GjK1LXEyVOoSI1N9JV9ZI923X5kup43W4= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= -google.golang.org/protobuf v1.36.10 h1:AYd7cD/uASjIL6Q9LiTjz8JLcrh/88q5UObnmY3aOOE= -google.golang.org/protobuf v1.36.10/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= +google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE= +google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/pdata/testdata/profile.go b/pdata/testdata/profile.go index a065a3db01a4..4c1368f69652 100644 --- a/pdata/testdata/profile.go +++ b/pdata/testdata/profile.go @@ -19,15 +19,18 @@ func GenerateProfiles(profilesCount int) pprofile.Profiles { ss := td.ResourceProfiles().At(0).ScopeProfiles().AppendEmpty().Profiles() dic := td.Dictionary() + // By convention, the first element is empty dic.StringTable().Append("") dic.StringTable().Append("key") + // By convention, the first element is empty + dic.AttributeTable().AppendEmpty() attr := dic.AttributeTable().AppendEmpty() attr.SetKeyStrindex(1) - attr.Value().SetStr("value") + attr.Value().SetStr("value-1") attr2 := dic.AttributeTable().AppendEmpty() - attr.SetKeyStrindex(1) - attr2.Value().SetStr("value") + attr2.SetKeyStrindex(1) + attr2.Value().SetStr("value-2") ss.EnsureCapacity(profilesCount) for i := range profilesCount { @@ -45,34 +48,36 @@ func GenerateProfiles(profilesCount int) pprofile.Profiles { func fillProfileOne(dic pprofile.ProfilesDictionary, profile pprofile.Profile) { profile.SetProfileID([16]byte{0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10}) profile.SetTime(profileStartTimestamp) - profile.SetDurationNano(uint64(time.Second.Nanoseconds())) //nolint:gosec // G115 overflow checked + profile.SetDurationNano(uint64(time.Second.Nanoseconds())) profile.SetDroppedAttributesCount(1) loc := pprofile.NewLocation() loc.SetAddress(1) - id, _ := pprofile.SetLocation(dic.LocationTable(), loc) - stack := dic.StackTable().AppendEmpty() - stack.LocationIndices().Append(id) + locID, _ := pprofile.SetLocation(dic.LocationTable(), loc) + stack := pprofile.NewStack() + stack.LocationIndices().Append(locID) + stackID, _ := pprofile.SetStack(dic.StackTable(), stack) sample := profile.Samples().AppendEmpty() - sample.SetStackIndex(1) + sample.SetStackIndex(stackID) sample.Values().Append(4) - sample.AttributeIndices().Append(0) + sample.AttributeIndices().Append(1) } func fillProfileTwo(dic pprofile.ProfilesDictionary, profile pprofile.Profile) { profile.SetProfileID([16]byte{0x02, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10}) profile.SetTime(profileStartTimestamp) - profile.SetDurationNano(uint64(time.Second.Nanoseconds())) //nolint:gosec // G115 overflow checked + profile.SetDurationNano(uint64(time.Second.Nanoseconds())) loc := pprofile.NewLocation() loc.SetAddress(2) - id, _ := pprofile.SetLocation(dic.LocationTable(), loc) - stack := dic.StackTable().AppendEmpty() - stack.LocationIndices().Append(id) + locID, _ := pprofile.SetLocation(dic.LocationTable(), loc) + stack := pprofile.NewStack() + stack.LocationIndices().Append(locID) + stackID, _ := pprofile.SetStack(dic.StackTable(), stack) sample := profile.Samples().AppendEmpty() - sample.SetStackIndex(1) + sample.SetStackIndex(stackID) sample.Values().Append(9) - sample.AttributeIndices().Append(0) + sample.AttributeIndices().Append(2) } diff --git a/pdata/xpdata/documentation.md b/pdata/xpdata/documentation.md new file mode 100644 index 000000000000..7851f8a64814 --- /dev/null +++ b/pdata/xpdata/documentation.md @@ -0,0 +1,13 @@ +[comment]: <> (Code generated by mdatagen. DO NOT EDIT.) + +# xpdata + +## Feature Gates + +This component has the following feature gates: + +| Feature Gate | Stage | Description | From Version | To Version | Reference | +| ------------ | ----- | ----------- | ------------ | ---------- | --------- | +| `pdata.enableRefCounting` | beta | When enabled, enables using ref counting to know when pdata memory can be freed up. This featuregate is here only to protect if unexpected bugs happens because of ref counting logic. | v0.133.0 | N/A | [Link](https://github.com/open-telemetry/opentelemetry-collector/issues/13631) | + +For more information about feature gates, see the [Feature Gates](https://github.com/open-telemetry/opentelemetry-collector/blob/main/featuregate/README.md) documentation. diff --git a/pdata/xpdata/entity/entity.go b/pdata/xpdata/entity/entity.go index b3d6a0d28169..899428176c74 100644 --- a/pdata/xpdata/entity/entity.go +++ b/pdata/xpdata/entity/entity.go @@ -16,6 +16,15 @@ type Entity struct { attributes pcommon.Map } +func NewEntity(t string) Entity { + ref := NewEntityRef() + ref.SetType(t) + return Entity{ + ref: ref, + attributes: pcommon.NewMap(), + } +} + func (e Entity) Type() string { return e.ref.Type() } @@ -28,18 +37,29 @@ func (e Entity) SetSchemaURL(schemaURL string) { e.ref.SetSchemaUrl(schemaURL) } -// IDAttributes returns an EntityAttributeMap for managing the entity's id attributes. -func (e Entity) IDAttributes() EntityAttributeMap { +// IdentifyingAttributes returns an EntityAttributeMap for managing the entity's identifying attributes. +func (e Entity) IdentifyingAttributes() EntityAttributeMap { return EntityAttributeMap{ keys: e.ref.IdKeys(), attributes: e.attributes, } } -// DescriptionAttributes returns an EntityAttributeMap for managing the entity's description attributes. -func (e Entity) DescriptionAttributes() EntityAttributeMap { +// DescriptiveAttributes returns an EntityAttributeMap for managing the entity's descriptive attributes. +func (e Entity) DescriptiveAttributes() EntityAttributeMap { return EntityAttributeMap{ keys: e.ref.DescriptionKeys(), attributes: e.attributes, } } + +// CopyToResource moves the entity to the provided resource by overriding existing entities and attributes. +func (e Entity) CopyToResource(res pcommon.Resource) { + ent := ResourceEntities(res).PutEmpty(e.Type()) + for k, v := range e.IdentifyingAttributes().All() { + v.CopyTo(ent.IdentifyingAttributes().PutEmpty(k)) + } + for k, v := range e.DescriptiveAttributes().All() { + v.CopyTo(ent.DescriptiveAttributes().PutEmpty(k)) + } +} diff --git a/pdata/xpdata/entity/entity_attribute_map.go b/pdata/xpdata/entity/entity_attribute_map.go index ddf56194b623..ba6de99a2dac 100644 --- a/pdata/xpdata/entity/entity_attribute_map.go +++ b/pdata/xpdata/entity/entity_attribute_map.go @@ -3,7 +3,11 @@ package entity // import "go.opentelemetry.io/collector/pdata/xpdata/entity" -import "go.opentelemetry.io/collector/pdata/pcommon" +import ( + "iter" + + "go.opentelemetry.io/collector/pdata/pcommon" +) // EntityAttributeMap is a wrapper around pcommon.Map that restricts operations to only the keys // that belong to a specific set of entity attributes (either ID or Description attributes). @@ -35,8 +39,8 @@ func (m EntityAttributeMap) Get(key string) (pcommon.Value, bool) { // // Use this method before calling Put* methods to avoid conflicts: // -// if entity.IDAttributes().CanPut("service.name") { -// entity.IDAttributes().PutStr("service.name", "my-service") +// if entity.IdentifyingAttributes().CanPut("service.name") { +// entity.IdentifyingAttributes().PutStr("service.name", "my-service") // } func (m EntityAttributeMap) CanPut(key string) bool { if m.containsKey(key) { @@ -101,3 +105,15 @@ func (m EntityAttributeMap) containsKey(key string) bool { } return false } + +// All returns an iterator over the key-value pairs of the attributes belonging to this map's key set. +func (m EntityAttributeMap) All() iter.Seq2[string, pcommon.Value] { + return func(yield func(string, pcommon.Value) bool) { + for _, k := range m.keys.All() { + v, ok := m.attributes.Get(k) + if ok && !yield(k, v) { + return + } + } + } +} diff --git a/pdata/xpdata/entity/entity_attribute_map_test.go b/pdata/xpdata/entity/entity_attribute_map_test.go index 38be87cdb5da..ed763f7472e5 100644 --- a/pdata/xpdata/entity/entity_attribute_map_test.go +++ b/pdata/xpdata/entity/entity_attribute_map_test.go @@ -150,6 +150,30 @@ func TestEntityAttributeMap_CanPut(t *testing.T) { assert.True(t, m.CanPut("new-key")) } +func TestEntityAttributeMap_All(t *testing.T) { + m := newTestEntityAttributeMap() + m.PutStr("k1", "v1") + m.PutStr("k2", "v2") + + // Add an attribute not owned by this map — it should not appear in All(). + m.attributes.PutStr("not-owned", "v3") + + got := make(map[string]string) + for k, v := range m.All() { + got[k] = v.Str() + } + + assert.Equal(t, map[string]string{"k1": "v1", "k2": "v2"}, got) + + // Verify early termination: breaking out of the loop stops iteration. + var count int + for range m.All() { + count++ + break + } + assert.Equal(t, 1, count) +} + func newTestEntityAttributeMap() EntityAttributeMap { return EntityAttributeMap{ keys: pcommon.NewStringSlice(), diff --git a/pdata/xpdata/entity/entity_map_test.go b/pdata/xpdata/entity/entity_map_test.go index 2801720208c8..c0d5cdd0f85b 100644 --- a/pdata/xpdata/entity/entity_map_test.go +++ b/pdata/xpdata/entity/entity_map_test.go @@ -35,13 +35,13 @@ func TestEntityMap_PutEmpty(t *testing.T) { func TestEntityMap_PutEmpty_Override(t *testing.T) { em := NewEntityMap() e1 := em.PutEmpty("service") - e1.IDAttributes().PutStr("service.name", "my-service") + e1.IdentifyingAttributes().PutStr("service.name", "my-service") assert.Equal(t, 1, em.Len()) e2 := em.PutEmpty("service") assert.Equal(t, 1, em.Len()) - _, ok := e2.IDAttributes().Get("service.name") + _, ok := e2.IdentifyingAttributes().Get("service.name") assert.False(t, ok) } @@ -61,39 +61,39 @@ func TestEntityMap_AttributesIsolation(t *testing.T) { em := NewEntityMap() e1 := em.PutEmpty("service") - e1.IDAttributes().PutStr("service.name", "my-service") + e1.IdentifyingAttributes().PutStr("service.name", "my-service") e2 := em.PutEmpty("host") - e2.IDAttributes().PutStr("host.name", "my-host") + e2.IdentifyingAttributes().PutStr("host.name", "my-host") service, ok := em.Get("service") assert.True(t, ok) - val, ok := service.IDAttributes().Get("service.name") + val, ok := service.IdentifyingAttributes().Get("service.name") assert.True(t, ok) assert.Equal(t, "my-service", val.Str()) host, ok := em.Get("host") assert.True(t, ok) - val, ok = host.IDAttributes().Get("host.name") + val, ok = host.IdentifyingAttributes().Get("host.name") assert.True(t, ok) assert.Equal(t, "my-host", val.Str()) - _, ok = service.IDAttributes().Get("host.name") + _, ok = service.IdentifyingAttributes().Get("host.name") assert.False(t, ok) - _, ok = host.IDAttributes().Get("service.name") + _, ok = host.IdentifyingAttributes().Get("service.name") assert.False(t, ok) } func TestEntityMap_Get(t *testing.T) { em := NewEntityMap() e1 := em.PutEmpty("service") - e1.IDAttributes().PutStr("service.name", "my-service") + e1.IdentifyingAttributes().PutStr("service.name", "my-service") e2, ok := em.Get("service") assert.True(t, ok) assert.Equal(t, "service", e2.Type()) - val, ok := e2.IDAttributes().Get("service.name") + val, ok := e2.IdentifyingAttributes().Get("service.name") assert.True(t, ok) assert.Equal(t, "my-service", val.Str()) @@ -104,8 +104,8 @@ func TestEntityMap_Get(t *testing.T) { func TestEntityMap_Remove(t *testing.T) { em := NewEntityMap() e1 := em.PutEmpty("service") - e1.IDAttributes().PutStr("service.name", "my-service") - e1.DescriptionAttributes().PutStr("service.version", "1.0.0") + e1.IdentifyingAttributes().PutStr("service.name", "my-service") + e1.DescriptiveAttributes().PutStr("service.version", "1.0.0") assert.Equal(t, 1, em.Len()) assert.Equal(t, 2, em.attributes.Len()) @@ -121,13 +121,13 @@ func TestEntityMap_Remove(t *testing.T) { func TestEntityMap_All(t *testing.T) { em := NewEntityMap() e1 := em.PutEmpty("service") - e1.IDAttributes().PutStr("service.name", "my-service") + e1.IdentifyingAttributes().PutStr("service.name", "my-service") e2 := em.PutEmpty("host") - e2.IDAttributes().PutStr("host.name", "my-host") + e2.IdentifyingAttributes().PutStr("host.name", "my-host") e3 := em.PutEmpty("process") - e3.IDAttributes().PutStr("process.pid", "1234") + e3.IdentifyingAttributes().PutStr("process.pid", "1234") types := make(map[string]bool) attributes := make(map[string]string) @@ -136,15 +136,15 @@ func TestEntityMap_All(t *testing.T) { types[entityType] = true switch entityType { case "service": - val, ok := entity.IDAttributes().Get("service.name") + val, ok := entity.IdentifyingAttributes().Get("service.name") assert.True(t, ok) attributes[entityType] = val.Str() case "host": - val, ok := entity.IDAttributes().Get("host.name") + val, ok := entity.IdentifyingAttributes().Get("host.name") assert.True(t, ok) attributes[entityType] = val.Str() case "process": - val, ok := entity.IDAttributes().Get("process.pid") + val, ok := entity.IdentifyingAttributes().Get("process.pid") assert.True(t, ok) attributes[entityType] = val.Str() } diff --git a/pdata/xpdata/entity/entity_test.go b/pdata/xpdata/entity/entity_test.go index 185059451570..449608d7261f 100644 --- a/pdata/xpdata/entity/entity_test.go +++ b/pdata/xpdata/entity/entity_test.go @@ -7,8 +7,37 @@ import ( "testing" "github.com/stretchr/testify/assert" + + "go.opentelemetry.io/collector/pdata/pcommon" ) +func TestNewEntity(t *testing.T) { + e := NewEntity("service") + assert.Equal(t, "service", e.Type()) + assert.Empty(t, e.SchemaURL()) +} + +func TestEntity_CopyToResource(t *testing.T) { + e := NewEntity("service") + e.IdentifyingAttributes().PutStr("service.name", "my-service") + e.DescriptiveAttributes().PutStr("service.version", "1.0.0") + + res := pcommon.NewResource() + e.CopyToResource(res) + + entities := ResourceEntities(res) + copied, ok := entities.Get("service") + assert.True(t, ok) + + idVal, ok := copied.IdentifyingAttributes().Get("service.name") + assert.True(t, ok) + assert.Equal(t, "my-service", idVal.Str()) + + descVal, ok := copied.DescriptiveAttributes().Get("service.version") + assert.True(t, ok) + assert.Equal(t, "1.0.0", descVal.Str()) +} + func TestEntity_Type(t *testing.T) { em := NewEntityMap() e := em.PutEmpty("service") @@ -29,26 +58,26 @@ func TestEntity_SchemaURL(t *testing.T) { assert.Equal(t, "https://opentelemetry.io/schemas/1.1.0", e.SchemaURL()) } -func TestEntity_IDAttributes(t *testing.T) { +func TestEntity_IdentifyingAttributes(t *testing.T) { em := NewEntityMap() e := em.PutEmpty("service") - idAttrs := e.IDAttributes() + idAttrs := e.IdentifyingAttributes() idAttrs.PutStr("key1", "value1") - val, ok := e.IDAttributes().Get("key1") + val, ok := e.IdentifyingAttributes().Get("key1") assert.True(t, ok) assert.Equal(t, "value1", val.Str()) } -func TestEntity_DescriptionAttributes(t *testing.T) { +func TestEntity_DescriptiveAttributes(t *testing.T) { em := NewEntityMap() e := em.PutEmpty("service") - descAttrs := e.DescriptionAttributes() + descAttrs := e.DescriptiveAttributes() descAttrs.PutStr("key1", "value1") - val, ok := e.DescriptionAttributes().Get("key1") + val, ok := e.DescriptiveAttributes().Get("key1") assert.True(t, ok) assert.Equal(t, "value1", val.Str()) } @@ -57,21 +86,21 @@ func TestEntity_IdAndDescriptionAttributes_Isolated(t *testing.T) { em := NewEntityMap() e := em.PutEmpty("service") - e.IDAttributes().PutStr("id.key", "id-value") - e.DescriptionAttributes().PutStr("desc.key", "desc-value") + e.IdentifyingAttributes().PutStr("id.key", "id-value") + e.DescriptiveAttributes().PutStr("desc.key", "desc-value") - val, ok := e.IDAttributes().Get("id.key") + val, ok := e.IdentifyingAttributes().Get("id.key") assert.True(t, ok) assert.Equal(t, "id-value", val.Str()) - _, ok = e.IDAttributes().Get("desc.key") + _, ok = e.IdentifyingAttributes().Get("desc.key") assert.False(t, ok) - val, ok = e.DescriptionAttributes().Get("desc.key") + val, ok = e.DescriptiveAttributes().Get("desc.key") assert.True(t, ok) assert.Equal(t, "desc-value", val.Str()) - _, ok = e.DescriptionAttributes().Get("id.key") + _, ok = e.DescriptiveAttributes().Get("id.key") assert.False(t, ok) } @@ -79,18 +108,18 @@ func TestEntity_IdAndDescriptionAttributes_CanPut(t *testing.T) { em := NewEntityMap() e := em.PutEmpty("service") - e.IDAttributes().PutStr("shared.key", "id-value") + e.IdentifyingAttributes().PutStr("shared.key", "id-value") - assert.True(t, e.IDAttributes().CanPut("shared.key")) - assert.False(t, e.DescriptionAttributes().CanPut("shared.key")) + assert.True(t, e.IdentifyingAttributes().CanPut("shared.key")) + assert.False(t, e.DescriptiveAttributes().CanPut("shared.key")) - e.DescriptionAttributes().PutStr("shared.key", "desc-value") + e.DescriptiveAttributes().PutStr("shared.key", "desc-value") - val, ok := e.IDAttributes().Get("shared.key") + val, ok := e.IdentifyingAttributes().Get("shared.key") assert.True(t, ok) assert.Equal(t, "desc-value", val.Str()) - val, ok = e.DescriptionAttributes().Get("shared.key") + val, ok = e.DescriptiveAttributes().Get("shared.key") assert.True(t, ok) assert.Equal(t, "desc-value", val.Str()) } diff --git a/pdata/xpdata/generated_package_test.go b/pdata/xpdata/generated_package_test.go new file mode 100644 index 000000000000..a65e87f4f16a --- /dev/null +++ b/pdata/xpdata/generated_package_test.go @@ -0,0 +1,13 @@ +// Code generated by mdatagen. DO NOT EDIT. + +package xpdata + +import ( + "testing" + + "go.uber.org/goleak" +) + +func TestMain(m *testing.M) { + goleak.VerifyTestMain(m) +} diff --git a/pdata/xpdata/go.mod b/pdata/xpdata/go.mod index 24f63e2d1d5b..14167d92ac6f 100644 --- a/pdata/xpdata/go.mod +++ b/pdata/xpdata/go.mod @@ -1,21 +1,22 @@ module go.opentelemetry.io/collector/pdata/xpdata -go 1.24.0 +go 1.25.0 require ( github.com/stretchr/testify v1.11.1 go.opentelemetry.io/collector/client v1.46.0 - go.opentelemetry.io/collector/featuregate v1.46.0 - go.opentelemetry.io/collector/pdata v1.46.0 - go.opentelemetry.io/collector/pdata/pprofile v0.140.0 + go.opentelemetry.io/collector/featuregate v1.54.0 + go.opentelemetry.io/collector/pdata v1.54.0 + go.opentelemetry.io/collector/pdata/pprofile v0.148.0 go.opentelemetry.io/collector/pdata/testdata v0.140.0 go.opentelemetry.io/otel/trace v1.40.0 + go.uber.org/goleak v1.3.0 ) require ( github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/davecgh/go-spew v1.1.1 // indirect - github.com/hashicorp/go-version v1.7.0 // indirect + github.com/hashicorp/go-version v1.8.0 // indirect github.com/json-iterator/go v1.1.12 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee // indirect diff --git a/pdata/xpdata/go.sum b/pdata/xpdata/go.sum index 35e28c225071..e9385a402032 100644 --- a/pdata/xpdata/go.sum +++ b/pdata/xpdata/go.sum @@ -6,8 +6,8 @@ github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= -github.com/hashicorp/go-version v1.7.0 h1:5tqGy27NaOTB8yJKUZELlFAS/LTKJkrmONwQKeRZfjY= -github.com/hashicorp/go-version v1.7.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= +github.com/hashicorp/go-version v1.8.0 h1:KAkNb1HAiZd1ukkxDFGmokVZe1Xy9HG6NUp+bPle2i4= +github.com/hashicorp/go-version v1.8.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= @@ -32,18 +32,18 @@ go.opentelemetry.io/otel v1.40.0 h1:oA5YeOcpRTXq6NN7frwmwFR0Cn3RhTVZvXsP4duvCms= go.opentelemetry.io/otel v1.40.0/go.mod h1:IMb+uXZUKkMXdPddhwAHm6UfOwJyh4ct1ybIlV14J0g= go.opentelemetry.io/otel/trace v1.40.0 h1:WA4etStDttCSYuhwvEa8OP8I5EWu24lkOzp+ZYblVjw= go.opentelemetry.io/otel/trace v1.40.0/go.mod h1:zeAhriXecNGP/s2SEG3+Y8X9ujcJOTqQ5RgdEJcawiA= -go.opentelemetry.io/proto/slim/otlp v1.9.0 h1:fPVMv8tP3TrsqlkH1HWYUpbCY9cAIemx184VGkS6vlE= -go.opentelemetry.io/proto/slim/otlp v1.9.0/go.mod h1:xXdeJJ90Gqyll+orzUkY4bOd2HECo5JofeoLpymVqdI= -go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.2.0 h1:o13nadWDNkH/quoDomDUClnQBpdQQ2Qqv0lQBjIXjE8= -go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.2.0/go.mod h1:Gyb6Xe7FTi/6xBHwMmngGoHqL0w29Y4eW8TGFzpefGA= -go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.2.0 h1:EiUYvtwu6PMrMHVjcPfnsG3v+ajPkbUeH+IL93+QYyk= -go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.2.0/go.mod h1:mUUHKFiN2SST3AhJ8XhJxEoeVW12oqfXog0Bo8W3Ec4= +go.opentelemetry.io/proto/slim/otlp v1.10.0 h1:iR97Vs/ZDR+y9TfuP9b1XBtdPWeC+OMslIBmhcLU7jM= +go.opentelemetry.io/proto/slim/otlp v1.10.0/go.mod h1:lV9250stpjYLPNA5viFabIgP2QlUGRT1GdTgAf8SIUk= +go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.3.0 h1:RUF5rO0hAlgiJt1fzQVzcVs3vZVNHIcMLgOgG4rWNcQ= +go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.3.0/go.mod h1:I89cynRj8y+383o7tEQVg2SVA6SRgDVIouWPUVXjx0U= +go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.3.0 h1:CQvJSldHRUN6Z8jsUeYv8J0lXRvygALXIzsmAeCcZE0= +go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.3.0/go.mod h1:xSQ+mEfJe/GjK1LXEyVOoSI1N9JV9ZI923X5kup43W4= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= -google.golang.org/protobuf v1.36.10 h1:AYd7cD/uASjIL6Q9LiTjz8JLcrh/88q5UObnmY3aOOE= -google.golang.org/protobuf v1.36.10/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= +google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE= +google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= diff --git a/pdata/xpdata/internal/metadata/generated_feature_gates.go b/pdata/xpdata/internal/metadata/generated_feature_gates.go new file mode 100644 index 000000000000..012ec6e4f5b7 --- /dev/null +++ b/pdata/xpdata/internal/metadata/generated_feature_gates.go @@ -0,0 +1,15 @@ +// Code generated by mdatagen. DO NOT EDIT. + +package metadata + +import ( + "go.opentelemetry.io/collector/featuregate" +) + +var PdataEnableRefCountingFeatureGate = featuregate.GlobalRegistry().MustRegister( + "pdata.enableRefCounting", + featuregate.StageBeta, + featuregate.WithRegisterDescription("When enabled, enables using ref counting to know when pdata memory can be freed up. This featuregate is here only to protect if unexpected bugs happens because of ref counting logic."), + featuregate.WithRegisterReferenceURL("https://github.com/open-telemetry/opentelemetry-collector/issues/13631"), + featuregate.WithRegisterFromVersion("v0.133.0"), +) diff --git a/pdata/xpdata/metadata.yaml b/pdata/xpdata/metadata.yaml index b3063e6cd8d2..be6c365f0e35 100644 --- a/pdata/xpdata/metadata.yaml +++ b/pdata/xpdata/metadata.yaml @@ -3,4 +3,13 @@ github_project: open-telemetry/opentelemetry-collector status: disable_codecov_badge: true - class: pdata + class: pkg + stability: + development: [traces, metrics, logs, profiles] + +feature_gates: + - id: pdata.enableRefCounting + description: 'When enabled, enables using ref counting to know when pdata memory can be freed up. This featuregate is here only to protect if unexpected bugs happens because of ref counting logic.' + stage: beta + from_version: 'v0.133.0' + reference_url: 'https://github.com/open-telemetry/opentelemetry-collector/issues/13631' diff --git a/pdata/xpdata/pref/gate.go b/pdata/xpdata/pref/gate.go index ad2deec9e0d6..2a53acd6ef74 100644 --- a/pdata/xpdata/pref/gate.go +++ b/pdata/xpdata/pref/gate.go @@ -4,17 +4,8 @@ package pref // import "go.opentelemetry.io/collector/pdata/xpdata/pref" import ( - "go.opentelemetry.io/collector/featuregate" - "go.opentelemetry.io/collector/pdata/internal" + "go.opentelemetry.io/collector/pdata/internal/metadata" ) // UseProtoPooling temporary expose public to allow testing. -var UseProtoPooling = internal.UseProtoPooling - -var EnableRefCounting = featuregate.GlobalRegistry().MustRegister( - "pdata.enableRefCounting", - featuregate.StageBeta, - featuregate.WithRegisterDescription("When enabled, enables using ref counting to know when pdata memory can be freed up. This featuregate is here only to protect if unexpected bugs happens because of ref counting logic."), - featuregate.WithRegisterReferenceURL("https://github.com/open-telemetry/opentelemetry-collector/issues/13631"), - featuregate.WithRegisterFromVersion("v0.133.0"), -) +var UseProtoPooling = metadata.PdataUseProtoPoolingFeatureGate diff --git a/pdata/xpdata/pref/logs.go b/pdata/xpdata/pref/logs.go index ef19e15be23e..925b80081175 100644 --- a/pdata/xpdata/pref/logs.go +++ b/pdata/xpdata/pref/logs.go @@ -7,7 +7,9 @@ import ( "reflect" "go.opentelemetry.io/collector/pdata/internal" + pmetadata "go.opentelemetry.io/collector/pdata/internal/metadata" "go.opentelemetry.io/collector/pdata/plog" + "go.opentelemetry.io/collector/pdata/xpdata/internal/metadata" ) // MarkPipelineOwnedLogs marks the plog.Logs data as owned by the pipeline, returns true if the data were @@ -17,18 +19,18 @@ func MarkPipelineOwnedLogs(ld plog.Logs) bool { } func RefLogs(ld plog.Logs) { - if EnableRefCounting.IsEnabled() { + if metadata.PdataEnableRefCountingFeatureGate.IsEnabled() { internal.GetLogsState(internal.LogsWrapper(ld)).Ref() } } func UnrefLogs(ld plog.Logs) { - if EnableRefCounting.IsEnabled() { + if metadata.PdataEnableRefCountingFeatureGate.IsEnabled() { if !internal.GetLogsState(internal.LogsWrapper(ld)).Unref() { return } // Don't call DeleteExportLogsServiceRequest without the gate because we reset the data and that may still cause issues. - if internal.UseProtoPooling.IsEnabled() { + if pmetadata.PdataUseProtoPoolingFeatureGate.IsEnabled() { internal.DeleteExportLogsServiceRequest(internal.GetLogsOrig(internal.LogsWrapper(ld)), true) } } diff --git a/pdata/xpdata/pref/metrics.go b/pdata/xpdata/pref/metrics.go index 02610780dca9..8d4e56f1add3 100644 --- a/pdata/xpdata/pref/metrics.go +++ b/pdata/xpdata/pref/metrics.go @@ -7,7 +7,9 @@ import ( "reflect" "go.opentelemetry.io/collector/pdata/internal" + pmetadata "go.opentelemetry.io/collector/pdata/internal/metadata" "go.opentelemetry.io/collector/pdata/pmetric" + "go.opentelemetry.io/collector/pdata/xpdata/internal/metadata" ) // MarkPipelineOwnedMetrics marks the pmetric.Metrics data as owned by the pipeline, returns true if the data were @@ -17,18 +19,18 @@ func MarkPipelineOwnedMetrics(md pmetric.Metrics) bool { } func RefMetrics(md pmetric.Metrics) { - if EnableRefCounting.IsEnabled() { + if metadata.PdataEnableRefCountingFeatureGate.IsEnabled() { internal.GetMetricsState(internal.MetricsWrapper(md)).Ref() } } func UnrefMetrics(md pmetric.Metrics) { - if EnableRefCounting.IsEnabled() { + if metadata.PdataEnableRefCountingFeatureGate.IsEnabled() { if !internal.GetMetricsState(internal.MetricsWrapper(md)).Unref() { return } // Don't call DeleteExportLogsServiceRequest without the gate because we reset the data and that may still cause issues. - if internal.UseProtoPooling.IsEnabled() { + if pmetadata.PdataUseProtoPoolingFeatureGate.IsEnabled() { internal.DeleteExportMetricsServiceRequest(internal.GetMetricsOrig(internal.MetricsWrapper(md)), true) } } diff --git a/pdata/xpdata/pref/profiles.go b/pdata/xpdata/pref/profiles.go index b4a6ad70877a..61dc8c836b52 100644 --- a/pdata/xpdata/pref/profiles.go +++ b/pdata/xpdata/pref/profiles.go @@ -7,7 +7,9 @@ import ( "reflect" "go.opentelemetry.io/collector/pdata/internal" + pmetadata "go.opentelemetry.io/collector/pdata/internal/metadata" "go.opentelemetry.io/collector/pdata/pprofile" + "go.opentelemetry.io/collector/pdata/xpdata/internal/metadata" ) // MarkPipelineOwnedProfiles marks the pprofile.Profiles data as owned by the pipeline, returns true if the data were @@ -17,18 +19,18 @@ func MarkPipelineOwnedProfiles(pd pprofile.Profiles) bool { } func RefProfiles(pd pprofile.Profiles) { - if EnableRefCounting.IsEnabled() { + if metadata.PdataEnableRefCountingFeatureGate.IsEnabled() { internal.GetProfilesState(internal.ProfilesWrapper(pd)).Ref() } } func UnrefProfiles(pd pprofile.Profiles) { - if EnableRefCounting.IsEnabled() { + if metadata.PdataEnableRefCountingFeatureGate.IsEnabled() { if !internal.GetProfilesState(internal.ProfilesWrapper(pd)).Unref() { return } // Don't call DeleteExportLogsServiceRequest without the gate because we reset the data and that may still cause issues. - if internal.UseProtoPooling.IsEnabled() { + if pmetadata.PdataUseProtoPoolingFeatureGate.IsEnabled() { internal.DeleteExportProfilesServiceRequest(internal.GetProfilesOrig(internal.ProfilesWrapper(pd)), true) } } diff --git a/pdata/xpdata/pref/traces.go b/pdata/xpdata/pref/traces.go index 5f21b6a2e0fd..fb876e9b6ffa 100644 --- a/pdata/xpdata/pref/traces.go +++ b/pdata/xpdata/pref/traces.go @@ -7,7 +7,9 @@ import ( "reflect" "go.opentelemetry.io/collector/pdata/internal" + pmetadata "go.opentelemetry.io/collector/pdata/internal/metadata" "go.opentelemetry.io/collector/pdata/ptrace" + "go.opentelemetry.io/collector/pdata/xpdata/internal/metadata" ) // MarkPipelineOwnedTraces marks the ptrace.Traces data as owned by the pipeline, returns true if the data were @@ -21,12 +23,12 @@ func RefTraces(td ptrace.Traces) { } func UnrefTraces(td ptrace.Traces) { - if EnableRefCounting.IsEnabled() { + if metadata.PdataEnableRefCountingFeatureGate.IsEnabled() { if !internal.GetTracesState(internal.TracesWrapper(td)).Unref() { return } // Don't call DeleteExportLogsServiceRequest without the gate because we reset the data and that may still cause issues. - if internal.UseProtoPooling.IsEnabled() { + if pmetadata.PdataUseProtoPoolingFeatureGate.IsEnabled() { internal.DeleteExportTraceServiceRequest(internal.GetTracesOrig(internal.TracesWrapper(td)), true) } } diff --git a/pdata/xpdata/xpdata.go b/pdata/xpdata/xpdata.go new file mode 100644 index 000000000000..05fc0d9d9df5 --- /dev/null +++ b/pdata/xpdata/xpdata.go @@ -0,0 +1,6 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +//go:generate mdatagen metadata.yaml + +package xpdata // import "go.opentelemetry.io/collector/pdata/xpdata" diff --git a/pipeline/go.mod b/pipeline/go.mod index 2adeeacf7b01..866e8ced3179 100644 --- a/pipeline/go.mod +++ b/pipeline/go.mod @@ -1,6 +1,6 @@ module go.opentelemetry.io/collector/pipeline -go 1.24.0 +go 1.25.0 require github.com/stretchr/testify v1.11.1 diff --git a/pipeline/metadata.yaml b/pipeline/metadata.yaml new file mode 100644 index 000000000000..79ab752b3c1e --- /dev/null +++ b/pipeline/metadata.yaml @@ -0,0 +1,6 @@ +type: pipeline +github_project: open-telemetry/opentelemetry-collector + +status: + disable_codecov_badge: true + class: pkg diff --git a/pipeline/xpipeline/go.mod b/pipeline/xpipeline/go.mod index d366452ad3c0..8fd27d6756a4 100644 --- a/pipeline/xpipeline/go.mod +++ b/pipeline/xpipeline/go.mod @@ -1,7 +1,7 @@ module go.opentelemetry.io/collector/pipeline/xpipeline -go 1.24.0 +go 1.25.0 -require go.opentelemetry.io/collector/pipeline v1.46.0 +require go.opentelemetry.io/collector/pipeline v1.54.0 replace go.opentelemetry.io/collector/pipeline => ../ diff --git a/pipeline/xpipeline/metadata.yaml b/pipeline/xpipeline/metadata.yaml new file mode 100644 index 000000000000..68045b330647 --- /dev/null +++ b/pipeline/xpipeline/metadata.yaml @@ -0,0 +1,6 @@ +type: xpipeline +github_project: open-telemetry/opentelemetry-collector + +status: + disable_codecov_badge: true + class: pkg diff --git a/processor/batchprocessor/README.md b/processor/batchprocessor/README.md index 06fdaf37cac5..63b5c37dc4ed 100644 --- a/processor/batchprocessor/README.md +++ b/processor/batchprocessor/README.md @@ -1,6 +1,5 @@ -# Batch Processor - +# Batch Processor | Status | | | ------------- |-----------| | Stability | [beta]: traces, metrics, logs | diff --git a/processor/batchprocessor/batch_processor.go b/processor/batchprocessor/batch_processor.go index 0c43fb6f17b6..f4a097fee224 100644 --- a/processor/batchprocessor/batch_processor.go +++ b/processor/batchprocessor/batch_processor.go @@ -183,13 +183,10 @@ func (bp *batchProcessor[T]) Shutdown(context.Context) error { } func (b *shard[T]) start() { - b.processor.goroutines.Add(1) - go b.startLoop() + b.processor.goroutines.Go(b.startLoop) } func (b *shard[T]) startLoop() { - defer b.processor.goroutines.Done() - // timerCh ensures we only block when there is a // timer, since <- from a nil channel is blocking. var timerCh <-chan time.Time @@ -327,14 +324,12 @@ func (mb *multiShardBatcher[T]) consume(ctx context.Context, data T) error { // Get each metadata key value, form the corresponding // attribute set for use as a map lookup key. info := client.FromContext(ctx) - md := map[string][]string{} - var attrs []attribute.KeyValue + attrs := make([]attribute.KeyValue, 0, len(mb.metadataKeys)) for _, k := range mb.metadataKeys { // Lookup the value in the incoming metadata, copy it // into the outgoing metadata, and create a unique // value for the attributeSet. vs := info.Metadata.Get(k) - md[k] = vs if len(vs) == 1 { attrs = append(attrs, attribute.String(k, vs[0])) } else { @@ -354,6 +349,10 @@ func (mb *multiShardBatcher[T]) consume(ctx context.Context, data T) error { // aset.ToSlice() returns the sorted, deduplicated, // and name-lowercased list of attributes. var loaded bool + md := make(map[string][]string, len(mb.metadataKeys)) + for _, k := range mb.metadataKeys { + md[k] = info.Metadata.Get(k) + } b, loaded = mb.batchers.LoadOrStore(aset, mb.processor.newShard(md)) if !loaded { // Start the goroutine only if we added the object to the map, otherwise is already started. diff --git a/processor/batchprocessor/batch_processor_test.go b/processor/batchprocessor/batch_processor_test.go index 15f1f73cd4cb..58fbe7970791 100644 --- a/processor/batchprocessor/batch_processor_test.go +++ b/processor/batchprocessor/batch_processor_test.go @@ -716,7 +716,7 @@ func BenchmarkTraceSizeSpanCount(b *testing.B) { } } -func BenchmarkBatchMetricProcessor(b *testing.B) { +func BenchmarkBatchMetricProcessor2k(b *testing.B) { b.StopTimer() cfg := &Config{ Timeout: 100 * time.Millisecond, @@ -725,7 +725,7 @@ func BenchmarkBatchMetricProcessor(b *testing.B) { runMetricsProcessorBenchmark(b, cfg) } -func BenchmarkMultiBatchMetricProcessor(b *testing.B) { +func BenchmarkMultiBatchMetricProcessor2k(b *testing.B) { b.StopTimer() cfg := &Config{ Timeout: 100 * time.Millisecond, @@ -742,7 +742,7 @@ func runMetricsProcessorBenchmark(b *testing.B, cfg *Config) { require.NoError(b, err) require.NoError(b, metrics.Start(ctx, componenttest.NewNopHost())) - const metricsPerRequest = 1000 + const metricsPerRequest = 150_000 b.StartTimer() b.RunParallel(func(pb *testing.PB) { for pb.Next() { diff --git a/processor/batchprocessor/documentation.md b/processor/batchprocessor/documentation.md index 90eb7a389143..ed8a4f82dbf2 100644 --- a/processor/batchprocessor/documentation.md +++ b/processor/batchprocessor/documentation.md @@ -8,15 +8,15 @@ The following telemetry is emitted by this component. ### otelcol_processor_batch_batch_send_size -Number of units in the batch [Development] +Number of units in the batch | Unit | Metric Type | Value Type | Stability | | ---- | ----------- | ---------- | --------- | -| {units} | Histogram | Int | Development | +| {unit} | Histogram | Int | Development | ### otelcol_processor_batch_batch_send_size_bytes -Number of bytes in batch that was sent. Only available on detailed level. [Development] +Number of bytes in batch that was sent. Only available on detailed level. | Unit | Metric Type | Value Type | Stability | | ---- | ----------- | ---------- | --------- | @@ -24,24 +24,24 @@ Number of bytes in batch that was sent. Only available on detailed level. [Devel ### otelcol_processor_batch_batch_size_trigger_send -Number of times the batch was sent due to a size trigger [Development] +Number of times the batch was sent due to a size trigger | Unit | Metric Type | Value Type | Monotonic | Stability | | ---- | ----------- | ---------- | --------- | --------- | -| {times} | Sum | Int | true | Development | +| {time} | Sum | Int | true | Development | ### otelcol_processor_batch_metadata_cardinality -Number of distinct metadata value combinations being processed [Development] +Number of distinct metadata value combinations being processed | Unit | Metric Type | Value Type | Monotonic | Stability | | ---- | ----------- | ---------- | --------- | --------- | -| {combinations} | Sum | Int | false | Development | +| {combination} | Sum | Int | false | Development | ### otelcol_processor_batch_timeout_trigger_send -Number of times the batch was sent due to a timeout trigger [Development] +Number of times the batch was sent due to a timeout trigger | Unit | Metric Type | Value Type | Monotonic | Stability | | ---- | ----------- | ---------- | --------- | --------- | -| {times} | Sum | Int | true | Development | +| {time} | Sum | Int | true | Development | diff --git a/processor/batchprocessor/go.mod b/processor/batchprocessor/go.mod index cc030af6aebf..19847fc4512a 100644 --- a/processor/batchprocessor/go.mod +++ b/processor/batchprocessor/go.mod @@ -1,25 +1,25 @@ module go.opentelemetry.io/collector/processor/batchprocessor -go 1.24.0 +go 1.25.0 require ( github.com/stretchr/testify v1.11.1 go.opentelemetry.io/collector/client v1.46.0 - go.opentelemetry.io/collector/component v1.46.0 - go.opentelemetry.io/collector/component/componenttest v0.140.0 + go.opentelemetry.io/collector/component v1.54.0 + go.opentelemetry.io/collector/component/componenttest v0.148.0 go.opentelemetry.io/collector/confmap v1.46.0 - go.opentelemetry.io/collector/consumer v1.46.0 + go.opentelemetry.io/collector/consumer v1.54.0 go.opentelemetry.io/collector/consumer/consumererror v0.140.0 - go.opentelemetry.io/collector/consumer/consumertest v0.140.0 - go.opentelemetry.io/collector/pdata v1.46.0 - go.opentelemetry.io/collector/pdata/testdata v0.140.0 + go.opentelemetry.io/collector/consumer/consumertest v0.148.0 + go.opentelemetry.io/collector/pdata v1.54.0 + go.opentelemetry.io/collector/pdata/testdata v0.148.0 go.opentelemetry.io/collector/pdata/xpdata v0.140.0 - go.opentelemetry.io/collector/processor v1.46.0 + go.opentelemetry.io/collector/processor v1.54.0 go.opentelemetry.io/collector/processor/processortest v0.140.0 - go.opentelemetry.io/otel v1.40.0 - go.opentelemetry.io/otel/metric v1.40.0 + go.opentelemetry.io/otel v1.42.0 + go.opentelemetry.io/otel/metric v1.42.0 go.opentelemetry.io/otel/sdk/metric v1.40.0 - go.opentelemetry.io/otel/trace v1.40.0 + go.opentelemetry.io/otel/trace v1.42.0 go.uber.org/goleak v1.3.0 go.uber.org/zap v1.27.1 ) @@ -29,33 +29,34 @@ require ( github.com/davecgh/go-spew v1.1.1 // indirect github.com/go-logr/logr v1.4.3 // indirect github.com/go-logr/stdr v1.2.2 // indirect - github.com/go-viper/mapstructure/v2 v2.4.0 // indirect + github.com/go-viper/mapstructure/v2 v2.5.0 // indirect github.com/gobwas/glob v0.2.3 // indirect github.com/google/uuid v1.6.0 // indirect - github.com/hashicorp/go-version v1.7.0 // indirect + github.com/hashicorp/go-version v1.8.0 // indirect github.com/json-iterator/go v1.1.12 // indirect github.com/knadh/koanf/maps v0.1.2 // indirect github.com/knadh/koanf/providers/confmap v1.0.0 // indirect - github.com/knadh/koanf/v2 v2.3.0 // indirect + github.com/knadh/koanf/v2 v2.3.3 // indirect github.com/mitchellh/copystructure v1.2.0 // indirect github.com/mitchellh/reflectwalk v1.0.2 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee // indirect github.com/pmezard/go-difflib v1.0.0 // indirect go.opentelemetry.io/auto/sdk v1.2.1 // indirect - go.opentelemetry.io/collector/component/componentstatus v0.140.0 // indirect - go.opentelemetry.io/collector/consumer/xconsumer v0.140.0 // indirect - go.opentelemetry.io/collector/featuregate v1.46.0 // indirect - go.opentelemetry.io/collector/pdata/pprofile v0.140.0 // indirect - go.opentelemetry.io/collector/pipeline v1.46.0 // indirect - go.opentelemetry.io/collector/processor/xprocessor v0.140.0 // indirect + go.opentelemetry.io/collector/component/componentstatus v0.148.0 // indirect + go.opentelemetry.io/collector/consumer/xconsumer v0.148.0 // indirect + go.opentelemetry.io/collector/featuregate v1.54.0 // indirect + go.opentelemetry.io/collector/internal/componentalias v0.148.0 // indirect + go.opentelemetry.io/collector/pdata/pprofile v0.148.0 // indirect + go.opentelemetry.io/collector/pipeline v1.54.0 // indirect + go.opentelemetry.io/collector/processor/xprocessor v0.148.0 // indirect go.opentelemetry.io/otel/sdk v1.40.0 // indirect go.uber.org/multierr v1.11.0 // indirect go.yaml.in/yaml/v3 v3.0.4 // indirect - golang.org/x/sys v0.40.0 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20251022142026-3a174f9686a8 // indirect - google.golang.org/grpc v1.77.0 // indirect - google.golang.org/protobuf v1.36.10 // indirect + golang.org/x/sys v0.41.0 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20251222181119-0a764e51fe1b // indirect + google.golang.org/grpc v1.79.3 // indirect + google.golang.org/protobuf v1.36.11 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) @@ -101,3 +102,5 @@ replace go.opentelemetry.io/collector/consumer/consumererror => ../../consumer/c replace go.opentelemetry.io/collector/featuregate => ../../featuregate replace go.opentelemetry.io/collector/internal/testutil => ../../internal/testutil + +replace go.opentelemetry.io/collector/internal/componentalias => ../../internal/componentalias diff --git a/processor/batchprocessor/go.sum b/processor/batchprocessor/go.sum index 87bcdbea6e91..e0e5bd1c5745 100644 --- a/processor/batchprocessor/go.sum +++ b/processor/batchprocessor/go.sum @@ -8,8 +8,8 @@ github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI= github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= -github.com/go-viper/mapstructure/v2 v2.4.0 h1:EBsztssimR/CONLSZZ04E8qAkxNYq4Qp9LvH92wZUgs= -github.com/go-viper/mapstructure/v2 v2.4.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM= +github.com/go-viper/mapstructure/v2 v2.5.0 h1:vM5IJoUAy3d7zRSVtIwQgBj7BiWtMPfmPEgAXnvj1Ro= +github.com/go-viper/mapstructure/v2 v2.5.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM= github.com/gobwas/glob v0.2.3 h1:A4xDbljILXROh+kObIiy5kIaPYD8e96x1tgBhUI5J+Y= github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8= github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= @@ -19,16 +19,16 @@ github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/hashicorp/go-version v1.7.0 h1:5tqGy27NaOTB8yJKUZELlFAS/LTKJkrmONwQKeRZfjY= -github.com/hashicorp/go-version v1.7.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= +github.com/hashicorp/go-version v1.8.0 h1:KAkNb1HAiZd1ukkxDFGmokVZe1Xy9HG6NUp+bPle2i4= +github.com/hashicorp/go-version v1.8.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= github.com/knadh/koanf/maps v0.1.2 h1:RBfmAW5CnZT+PJ1CVc1QSJKf4Xu9kxfQgYVQSu8hpbo= github.com/knadh/koanf/maps v0.1.2/go.mod h1:npD/QZY3V6ghQDdcQzl1W4ICNVTkohC8E73eI2xW4yI= github.com/knadh/koanf/providers/confmap v1.0.0 h1:mHKLJTE7iXEys6deO5p6olAiZdG5zwp8Aebir+/EaRE= github.com/knadh/koanf/providers/confmap v1.0.0/go.mod h1:txHYHiI2hAtF0/0sCmcuol4IDcuQbKTybiB1nOcUo1A= -github.com/knadh/koanf/v2 v2.3.0 h1:Qg076dDRFHvqnKG97ZEsi9TAg2/nFTa9hCdcSa1lvlM= -github.com/knadh/koanf/v2 v2.3.0/go.mod h1:gRb40VRAbd4iJMYYD5IxZ6hfuopFcXBpc9bbQpZwo28= +github.com/knadh/koanf/v2 v2.3.3 h1:jLJC8XCRfLC7n4F+ZKKdBsbq1bfXTpuFhf4L7t94D94= +github.com/knadh/koanf/v2 v2.3.3/go.mod h1:gRb40VRAbd4iJMYYD5IxZ6hfuopFcXBpc9bbQpZwo28= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= @@ -53,22 +53,22 @@ github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64= go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y= -go.opentelemetry.io/otel v1.40.0 h1:oA5YeOcpRTXq6NN7frwmwFR0Cn3RhTVZvXsP4duvCms= -go.opentelemetry.io/otel v1.40.0/go.mod h1:IMb+uXZUKkMXdPddhwAHm6UfOwJyh4ct1ybIlV14J0g= -go.opentelemetry.io/otel/metric v1.40.0 h1:rcZe317KPftE2rstWIBitCdVp89A2HqjkxR3c11+p9g= -go.opentelemetry.io/otel/metric v1.40.0/go.mod h1:ib/crwQH7N3r5kfiBZQbwrTge743UDc7DTFVZrrXnqc= +go.opentelemetry.io/otel v1.42.0 h1:lSQGzTgVR3+sgJDAU/7/ZMjN9Z+vUip7leaqBKy4sho= +go.opentelemetry.io/otel v1.42.0/go.mod h1:lJNsdRMxCUIWuMlVJWzecSMuNjE7dOYyWlqOXWkdqCc= +go.opentelemetry.io/otel/metric v1.42.0 h1:2jXG+3oZLNXEPfNmnpxKDeZsFI5o4J+nz6xUlaFdF/4= +go.opentelemetry.io/otel/metric v1.42.0/go.mod h1:RlUN/7vTU7Ao/diDkEpQpnz3/92J9ko05BIwxYa2SSI= go.opentelemetry.io/otel/sdk v1.40.0 h1:KHW/jUzgo6wsPh9At46+h4upjtccTmuZCFAc9OJ71f8= go.opentelemetry.io/otel/sdk v1.40.0/go.mod h1:Ph7EFdYvxq72Y8Li9q8KebuYUr2KoeyHx0DRMKrYBUE= go.opentelemetry.io/otel/sdk/metric v1.40.0 h1:mtmdVqgQkeRxHgRv4qhyJduP3fYJRMX4AtAlbuWdCYw= go.opentelemetry.io/otel/sdk/metric v1.40.0/go.mod h1:4Z2bGMf0KSK3uRjlczMOeMhKU2rhUqdWNoKcYrtcBPg= -go.opentelemetry.io/otel/trace v1.40.0 h1:WA4etStDttCSYuhwvEa8OP8I5EWu24lkOzp+ZYblVjw= -go.opentelemetry.io/otel/trace v1.40.0/go.mod h1:zeAhriXecNGP/s2SEG3+Y8X9ujcJOTqQ5RgdEJcawiA= -go.opentelemetry.io/proto/slim/otlp v1.9.0 h1:fPVMv8tP3TrsqlkH1HWYUpbCY9cAIemx184VGkS6vlE= -go.opentelemetry.io/proto/slim/otlp v1.9.0/go.mod h1:xXdeJJ90Gqyll+orzUkY4bOd2HECo5JofeoLpymVqdI= -go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.2.0 h1:o13nadWDNkH/quoDomDUClnQBpdQQ2Qqv0lQBjIXjE8= -go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.2.0/go.mod h1:Gyb6Xe7FTi/6xBHwMmngGoHqL0w29Y4eW8TGFzpefGA= -go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.2.0 h1:EiUYvtwu6PMrMHVjcPfnsG3v+ajPkbUeH+IL93+QYyk= -go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.2.0/go.mod h1:mUUHKFiN2SST3AhJ8XhJxEoeVW12oqfXog0Bo8W3Ec4= +go.opentelemetry.io/otel/trace v1.42.0 h1:OUCgIPt+mzOnaUTpOQcBiM/PLQ/Op7oq6g4LenLmOYY= +go.opentelemetry.io/otel/trace v1.42.0/go.mod h1:f3K9S+IFqnumBkKhRJMeaZeNk9epyhnCmQh/EysQCdc= +go.opentelemetry.io/proto/slim/otlp v1.10.0 h1:iR97Vs/ZDR+y9TfuP9b1XBtdPWeC+OMslIBmhcLU7jM= +go.opentelemetry.io/proto/slim/otlp v1.10.0/go.mod h1:lV9250stpjYLPNA5viFabIgP2QlUGRT1GdTgAf8SIUk= +go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.3.0 h1:RUF5rO0hAlgiJt1fzQVzcVs3vZVNHIcMLgOgG4rWNcQ= +go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.3.0/go.mod h1:I89cynRj8y+383o7tEQVg2SVA6SRgDVIouWPUVXjx0U= +go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.3.0 h1:CQvJSldHRUN6Z8jsUeYv8J0lXRvygALXIzsmAeCcZE0= +go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.3.0/go.mod h1:xSQ+mEfJe/GjK1LXEyVOoSI1N9JV9ZI923X5kup43W4= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= @@ -77,18 +77,18 @@ go.uber.org/zap v1.27.1 h1:08RqriUEv8+ArZRYSTXy1LeBScaMpVSTBhCeaZYfMYc= go.uber.org/zap v1.27.1/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc= go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg= -golang.org/x/net v0.46.1-0.20251013234738-63d1a5100f82 h1:6/3JGEh1C88g7m+qzzTbl3A0FtsLguXieqofVLU/JAo= -golang.org/x/net v0.46.1-0.20251013234738-63d1a5100f82/go.mod h1:Q9BGdFy1y4nkUwiLvT5qtyhAnEHgnQ/zd8PfU6nc210= -golang.org/x/sys v0.40.0 h1:DBZZqJ2Rkml6QMQsZywtnjnnGvHza6BTfYFWY9kjEWQ= -golang.org/x/sys v0.40.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= -golang.org/x/text v0.30.0 h1:yznKA/E9zq54KzlzBEAWn1NXSQ8DIp/NYMy88xJjl4k= -golang.org/x/text v0.30.0/go.mod h1:yDdHFIX9t+tORqspjENWgzaCVXgk0yYnYuSZ8UzzBVM= -google.golang.org/genproto/googleapis/rpc v0.0.0-20251022142026-3a174f9686a8 h1:M1rk8KBnUsBDg1oPGHNCxG4vc1f49epmTO7xscSajMk= -google.golang.org/genproto/googleapis/rpc v0.0.0-20251022142026-3a174f9686a8/go.mod h1:7i2o+ce6H/6BluujYR+kqX3GKH+dChPTQU19wjRPiGk= -google.golang.org/grpc v1.77.0 h1:wVVY6/8cGA6vvffn+wWK5ToddbgdU3d8MNENr4evgXM= -google.golang.org/grpc v1.77.0/go.mod h1:z0BY1iVj0q8E1uSQCjL9cppRj+gnZjzDnzV0dHhrNig= -google.golang.org/protobuf v1.36.10 h1:AYd7cD/uASjIL6Q9LiTjz8JLcrh/88q5UObnmY3aOOE= -google.golang.org/protobuf v1.36.10/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= +golang.org/x/net v0.51.0 h1:94R/GTO7mt3/4wIKpcR5gkGmRLOuE/2hNGeWq/GBIFo= +golang.org/x/net v0.51.0/go.mod h1:aamm+2QF5ogm02fjy5Bb7CQ0WMt1/WVM7FtyaTLlA9Y= +golang.org/x/sys v0.41.0 h1:Ivj+2Cp/ylzLiEU89QhWblYnOE9zerudt9Ftecq2C6k= +golang.org/x/sys v0.41.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= +golang.org/x/text v0.34.0 h1:oL/Qq0Kdaqxa1KbNeMKwQq0reLCCaFtqu2eNuSeNHbk= +golang.org/x/text v0.34.0/go.mod h1:homfLqTYRFyVYemLBFl5GgL/DWEiH5wcsQ5gSh1yziA= +google.golang.org/genproto/googleapis/rpc v0.0.0-20251222181119-0a764e51fe1b h1:Mv8VFug0MP9e5vUxfBcE3vUkV6CImK3cMNMIDFjmzxU= +google.golang.org/genproto/googleapis/rpc v0.0.0-20251222181119-0a764e51fe1b/go.mod h1:j9x/tPzZkyxcgEFkiKEEGxfvyumM01BEtsW8xzOahRQ= +google.golang.org/grpc v1.79.3 h1:sybAEdRIEtvcD68Gx7dmnwjZKlyfuc61Dyo9pGXXkKE= +google.golang.org/grpc v1.79.3/go.mod h1:KmT0Kjez+0dde/v2j9vzwoAScgEPx/Bw1CYChhHLrHQ= +google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE= +google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= diff --git a/processor/batchprocessor/internal/metadata/generated_telemetry.go b/processor/batchprocessor/internal/metadata/generated_telemetry.go index eecfe3fd23bb..889c15d57a4a 100644 --- a/processor/batchprocessor/internal/metadata/generated_telemetry.go +++ b/processor/batchprocessor/internal/metadata/generated_telemetry.go @@ -92,7 +92,7 @@ func NewTelemetryBuilder(settings component.TelemetrySettings, options ...Teleme builder.ProcessorBatchBatchSendSize, err = builder.meter.Int64Histogram( "otelcol_processor_batch_batch_send_size", metric.WithDescription("Number of units in the batch [Development]"), - metric.WithUnit("{units}"), + metric.WithUnit("{unit}"), metric.WithExplicitBucketBoundaries([]float64{10, 25, 50, 75, 100, 250, 500, 750, 1000, 2000, 3000, 4000, 5000, 6000, 7000, 8000, 9000, 10000, 20000, 30000, 50000, 100000}...), ) errs = errors.Join(errs, err) @@ -106,19 +106,19 @@ func NewTelemetryBuilder(settings component.TelemetrySettings, options ...Teleme builder.ProcessorBatchBatchSizeTriggerSend, err = builder.meter.Int64Counter( "otelcol_processor_batch_batch_size_trigger_send", metric.WithDescription("Number of times the batch was sent due to a size trigger [Development]"), - metric.WithUnit("{times}"), + metric.WithUnit("{time}"), ) errs = errors.Join(errs, err) builder.ProcessorBatchMetadataCardinality, err = builder.meter.Int64ObservableUpDownCounter( "otelcol_processor_batch_metadata_cardinality", metric.WithDescription("Number of distinct metadata value combinations being processed [Development]"), - metric.WithUnit("{combinations}"), + metric.WithUnit("{combination}"), ) errs = errors.Join(errs, err) builder.ProcessorBatchTimeoutTriggerSend, err = builder.meter.Int64Counter( "otelcol_processor_batch_timeout_trigger_send", metric.WithDescription("Number of times the batch was sent due to a timeout trigger [Development]"), - metric.WithUnit("{times}"), + metric.WithUnit("{time}"), ) errs = errors.Join(errs, err) return &builder, errs diff --git a/processor/batchprocessor/internal/metadatatest/generated_telemetrytest.go b/processor/batchprocessor/internal/metadatatest/generated_telemetrytest.go index 925d5ec4e4c1..e31007e54337 100644 --- a/processor/batchprocessor/internal/metadatatest/generated_telemetrytest.go +++ b/processor/batchprocessor/internal/metadatatest/generated_telemetrytest.go @@ -26,7 +26,7 @@ func AssertEqualProcessorBatchBatchSendSize(t *testing.T, tt *componenttest.Tele want := metricdata.Metrics{ Name: "otelcol_processor_batch_batch_send_size", Description: "Number of units in the batch [Development]", - Unit: "{units}", + Unit: "{unit}", Data: metricdata.Histogram[int64]{ Temporality: metricdata.CumulativeTemporality, DataPoints: dps, @@ -56,7 +56,7 @@ func AssertEqualProcessorBatchBatchSizeTriggerSend(t *testing.T, tt *componentte want := metricdata.Metrics{ Name: "otelcol_processor_batch_batch_size_trigger_send", Description: "Number of times the batch was sent due to a size trigger [Development]", - Unit: "{times}", + Unit: "{time}", Data: metricdata.Sum[int64]{ Temporality: metricdata.CumulativeTemporality, IsMonotonic: true, @@ -72,7 +72,7 @@ func AssertEqualProcessorBatchMetadataCardinality(t *testing.T, tt *componenttes want := metricdata.Metrics{ Name: "otelcol_processor_batch_metadata_cardinality", Description: "Number of distinct metadata value combinations being processed [Development]", - Unit: "{combinations}", + Unit: "{combination}", Data: metricdata.Sum[int64]{ Temporality: metricdata.CumulativeTemporality, IsMonotonic: false, @@ -88,7 +88,7 @@ func AssertEqualProcessorBatchTimeoutTriggerSend(t *testing.T, tt *componenttest want := metricdata.Metrics{ Name: "otelcol_processor_batch_timeout_trigger_send", Description: "Number of times the batch was sent due to a timeout trigger [Development]", - Unit: "{times}", + Unit: "{time}", Data: metricdata.Sum[int64]{ Temporality: metricdata.CumulativeTemporality, IsMonotonic: true, diff --git a/processor/batchprocessor/metadata.yaml b/processor/batchprocessor/metadata.yaml index a843bfb18d48..bae7c8cbd859 100644 --- a/processor/batchprocessor/metadata.yaml +++ b/processor/batchprocessor/metadata.yaml @@ -1,3 +1,4 @@ +display_name: Batch Processor type: batch github_project: open-telemetry/opentelemetry-collector @@ -14,10 +15,9 @@ telemetry: metrics: processor_batch_batch_send_size: enabled: true - stability: - level: development + stability: development description: Number of units in the batch - unit: "{units}" + unit: "{unit}" histogram: value_type: int bucket_boundaries: @@ -47,8 +47,7 @@ telemetry: ] processor_batch_batch_send_size_bytes: enabled: true - stability: - level: development + stability: development description: Number of bytes in batch that was sent. Only available on detailed level. unit: By histogram: @@ -97,28 +96,25 @@ telemetry: ] processor_batch_batch_size_trigger_send: enabled: true - stability: - level: development + stability: development description: Number of times the batch was sent due to a size trigger - unit: "{times}" + unit: "{time}" sum: value_type: int monotonic: true processor_batch_metadata_cardinality: enabled: true - stability: - level: development + stability: development description: Number of distinct metadata value combinations being processed - unit: "{combinations}" + unit: "{combination}" sum: value_type: int async: true processor_batch_timeout_trigger_send: enabled: true - stability: - level: development + stability: development description: Number of times the batch was sent due to a timeout trigger - unit: "{times}" + unit: "{time}" sum: value_type: int monotonic: true diff --git a/processor/batchprocessor/splitlogs.go b/processor/batchprocessor/splitlogs.go index f1757035118c..3f8ae61a9742 100644 --- a/processor/batchprocessor/splitlogs.go +++ b/processor/batchprocessor/splitlogs.go @@ -31,6 +31,7 @@ func splitLogs(size int, src plog.Logs) plog.Logs { destRl := dest.ResourceLogs().AppendEmpty() srcRl.Resource().CopyTo(destRl.Resource()) + destRl.SetSchemaUrl(srcRl.SchemaUrl()) srcRl.ScopeLogs().RemoveIf(func(srcIll plog.ScopeLogs) bool { // If we are done skip everything else. if totalCopiedLogRecords == size { @@ -47,6 +48,7 @@ func splitLogs(size int, src plog.Logs) plog.Logs { destIll := destRl.ScopeLogs().AppendEmpty() srcIll.Scope().CopyTo(destIll.Scope()) + destIll.SetSchemaUrl(srcIll.SchemaUrl()) srcIll.LogRecords().RemoveIf(func(srcMetric plog.LogRecord) bool { // If we are done skip everything else. if totalCopiedLogRecords == size { diff --git a/processor/batchprocessor/splitlogs_test.go b/processor/batchprocessor/splitlogs_test.go index e9a611d61be5..a93f2f89babc 100644 --- a/processor/batchprocessor/splitlogs_test.go +++ b/processor/batchprocessor/splitlogs_test.go @@ -145,3 +145,16 @@ func TestSplitLogsMultipleILL(t *testing.T) { assert.Equal(t, "test-log-int-0-0", split.ResourceLogs().At(0).ScopeLogs().At(0).LogRecords().At(0).SeverityText()) assert.Equal(t, "test-log-int-0-4", split.ResourceLogs().At(0).ScopeLogs().At(0).LogRecords().At(4).SeverityText()) } + +func TestSplitLogsPreserveSchemaURLOnPartialSplit(t *testing.T) { + resourceSchemaURL := "https://test-resource-schema-url.com/" + scopeSchemaURL := "https://test-scope-schema-url.com/" + td := testdata.GenerateLogs(2) + td.ResourceLogs().At(0).SetSchemaUrl(resourceSchemaURL) + td.ResourceLogs().At(0).ScopeLogs().At(0).SetSchemaUrl(scopeSchemaURL) + + splitSize := 1 + split := splitLogs(splitSize, td) + assert.Equal(t, resourceSchemaURL, split.ResourceLogs().At(0).SchemaUrl()) + assert.Equal(t, scopeSchemaURL, split.ResourceLogs().At(0).ScopeLogs().At(0).SchemaUrl()) +} diff --git a/processor/batchprocessor/splitmetrics.go b/processor/batchprocessor/splitmetrics.go index 96067c659778..603851055d94 100644 --- a/processor/batchprocessor/splitmetrics.go +++ b/processor/batchprocessor/splitmetrics.go @@ -32,6 +32,7 @@ func splitMetrics(size int, src pmetric.Metrics) pmetric.Metrics { destRs := dest.ResourceMetrics().AppendEmpty() srcRs.Resource().CopyTo(destRs.Resource()) + destRs.SetSchemaUrl(srcRs.SchemaUrl()) srcRs.ScopeMetrics().RemoveIf(func(srcIlm pmetric.ScopeMetrics) bool { // If we are done skip everything else. if totalCopiedDataPoints == size { @@ -48,6 +49,7 @@ func splitMetrics(size int, src pmetric.Metrics) pmetric.Metrics { destIlm := destRs.ScopeMetrics().AppendEmpty() srcIlm.Scope().CopyTo(destIlm.Scope()) + destIlm.SetSchemaUrl(srcIlm.SchemaUrl()) srcIlm.Metrics().RemoveIf(func(srcMetric pmetric.Metric) bool { // If we are done skip everything else. if totalCopiedDataPoints == size { diff --git a/processor/batchprocessor/splitmetrics_test.go b/processor/batchprocessor/splitmetrics_test.go index dc46a4a78770..d6ac72768aa1 100644 --- a/processor/batchprocessor/splitmetrics_test.go +++ b/processor/batchprocessor/splitmetrics_test.go @@ -314,3 +314,16 @@ func TestSplitMetricsMultipleILM(t *testing.T) { assert.Equal(t, "test-metric-int-0-0", split.ResourceMetrics().At(0).ScopeMetrics().At(0).Metrics().At(0).Name()) assert.Equal(t, "test-metric-int-0-4", split.ResourceMetrics().At(0).ScopeMetrics().At(0).Metrics().At(4).Name()) } + +func TestSplitMetricsPreserveSchemaURLOnPartialSplit(t *testing.T) { + resourceSchemaURL := "https://test-resource-schema-url.com/" + scopeSchemaURL := "https://test-scope-schema-url.com/" + md := testdata.GenerateMetrics(2) + md.ResourceMetrics().At(0).SetSchemaUrl(resourceSchemaURL) + md.ResourceMetrics().At(0).ScopeMetrics().At(0).SetSchemaUrl(scopeSchemaURL) + + splitSize := 1 + split := splitMetrics(splitSize, md) + assert.Equal(t, resourceSchemaURL, split.ResourceMetrics().At(0).SchemaUrl()) + assert.Equal(t, scopeSchemaURL, split.ResourceMetrics().At(0).ScopeMetrics().At(0).SchemaUrl()) +} diff --git a/processor/batchprocessor/splittraces.go b/processor/batchprocessor/splittraces.go index 23dcbf7d15be..2816033002b4 100644 --- a/processor/batchprocessor/splittraces.go +++ b/processor/batchprocessor/splittraces.go @@ -31,6 +31,7 @@ func splitTraces(size int, src ptrace.Traces) ptrace.Traces { destRs := dest.ResourceSpans().AppendEmpty() srcRs.Resource().CopyTo(destRs.Resource()) + destRs.SetSchemaUrl(srcRs.SchemaUrl()) srcRs.ScopeSpans().RemoveIf(func(srcIls ptrace.ScopeSpans) bool { // If we are done skip everything else. if totalCopiedSpans == size { @@ -47,6 +48,7 @@ func splitTraces(size int, src ptrace.Traces) ptrace.Traces { destIls := destRs.ScopeSpans().AppendEmpty() srcIls.Scope().CopyTo(destIls.Scope()) + destIls.SetSchemaUrl(srcIls.SchemaUrl()) srcIls.Spans().RemoveIf(func(srcSpan ptrace.Span) bool { // If we are done skip everything else. if totalCopiedSpans == size { diff --git a/processor/batchprocessor/splittraces_test.go b/processor/batchprocessor/splittraces_test.go index 1b5569d29352..39e87d8960bc 100644 --- a/processor/batchprocessor/splittraces_test.go +++ b/processor/batchprocessor/splittraces_test.go @@ -145,3 +145,16 @@ func TestSplitTracesMultipleILS(t *testing.T) { assert.Equal(t, "test-span-0-0", split.ResourceSpans().At(0).ScopeSpans().At(0).Spans().At(0).Name()) assert.Equal(t, "test-span-0-4", split.ResourceSpans().At(0).ScopeSpans().At(0).Spans().At(4).Name()) } + +func TestSplitTracesPreserveSchemaURLOnPartialSplit(t *testing.T) { + resourceSchemaURL := "https://test-resource-schema-url.com/" + scopeSchemaURL := "https://test-scope-schema-url.com/" + td := testdata.GenerateTraces(2) + td.ResourceSpans().At(0).SetSchemaUrl(resourceSchemaURL) + td.ResourceSpans().At(0).ScopeSpans().At(0).SetSchemaUrl(scopeSchemaURL) + + splitSize := 1 + split := splitTraces(splitSize, td) + assert.Equal(t, resourceSchemaURL, split.ResourceSpans().At(0).SchemaUrl()) + assert.Equal(t, scopeSchemaURL, split.ResourceSpans().At(0).ScopeSpans().At(0).SchemaUrl()) +} diff --git a/processor/go.mod b/processor/go.mod index 6c018eb86f01..da0fab55a916 100644 --- a/processor/go.mod +++ b/processor/go.mod @@ -1,31 +1,32 @@ module go.opentelemetry.io/collector/processor -go 1.24.0 +go 1.25.0 require ( github.com/stretchr/testify v1.11.1 - go.opentelemetry.io/collector/component v1.46.0 - go.opentelemetry.io/collector/consumer v1.46.0 - go.opentelemetry.io/collector/consumer/consumertest v0.140.0 - go.opentelemetry.io/collector/pipeline v1.46.0 + go.opentelemetry.io/collector/component v1.54.0 + go.opentelemetry.io/collector/consumer v1.54.0 + go.opentelemetry.io/collector/consumer/consumertest v0.148.0 + go.opentelemetry.io/collector/internal/componentalias v0.148.0 + go.opentelemetry.io/collector/pipeline v1.54.0 go.uber.org/goleak v1.3.0 ) require ( github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/davecgh/go-spew v1.1.1 // indirect - github.com/hashicorp/go-version v1.7.0 // indirect + github.com/hashicorp/go-version v1.8.0 // indirect github.com/json-iterator/go v1.1.12 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee // indirect github.com/pmezard/go-difflib v1.0.0 // indirect - go.opentelemetry.io/collector/consumer/xconsumer v0.140.0 // indirect - go.opentelemetry.io/collector/featuregate v1.46.0 // indirect - go.opentelemetry.io/collector/pdata v1.46.0 // indirect - go.opentelemetry.io/collector/pdata/pprofile v0.140.0 // indirect - go.opentelemetry.io/otel v1.40.0 // indirect - go.opentelemetry.io/otel/metric v1.40.0 // indirect - go.opentelemetry.io/otel/trace v1.40.0 // indirect + go.opentelemetry.io/collector/consumer/xconsumer v0.148.0 // indirect + go.opentelemetry.io/collector/featuregate v1.54.0 // indirect + go.opentelemetry.io/collector/pdata v1.54.0 // indirect + go.opentelemetry.io/collector/pdata/pprofile v0.148.0 // indirect + go.opentelemetry.io/otel v1.42.0 // indirect + go.opentelemetry.io/otel/metric v1.42.0 // indirect + go.opentelemetry.io/otel/trace v1.42.0 // indirect go.uber.org/multierr v1.11.0 // indirect go.uber.org/zap v1.27.1 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect @@ -50,3 +51,5 @@ replace go.opentelemetry.io/collector/pipeline => ../pipeline replace go.opentelemetry.io/collector/featuregate => ../featuregate replace go.opentelemetry.io/collector/internal/testutil => ../internal/testutil + +replace go.opentelemetry.io/collector/internal/componentalias => ../internal/componentalias diff --git a/processor/go.sum b/processor/go.sum index 37d6edbc3764..1abfd0c69894 100644 --- a/processor/go.sum +++ b/processor/go.sum @@ -10,8 +10,8 @@ github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= -github.com/hashicorp/go-version v1.7.0 h1:5tqGy27NaOTB8yJKUZELlFAS/LTKJkrmONwQKeRZfjY= -github.com/hashicorp/go-version v1.7.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= +github.com/hashicorp/go-version v1.8.0 h1:KAkNb1HAiZd1ukkxDFGmokVZe1Xy9HG6NUp+bPle2i4= +github.com/hashicorp/go-version v1.8.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= @@ -34,26 +34,26 @@ github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64= go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y= -go.opentelemetry.io/otel v1.40.0 h1:oA5YeOcpRTXq6NN7frwmwFR0Cn3RhTVZvXsP4duvCms= -go.opentelemetry.io/otel v1.40.0/go.mod h1:IMb+uXZUKkMXdPddhwAHm6UfOwJyh4ct1ybIlV14J0g= -go.opentelemetry.io/otel/metric v1.40.0 h1:rcZe317KPftE2rstWIBitCdVp89A2HqjkxR3c11+p9g= -go.opentelemetry.io/otel/metric v1.40.0/go.mod h1:ib/crwQH7N3r5kfiBZQbwrTge743UDc7DTFVZrrXnqc= -go.opentelemetry.io/otel/trace v1.40.0 h1:WA4etStDttCSYuhwvEa8OP8I5EWu24lkOzp+ZYblVjw= -go.opentelemetry.io/otel/trace v1.40.0/go.mod h1:zeAhriXecNGP/s2SEG3+Y8X9ujcJOTqQ5RgdEJcawiA= -go.opentelemetry.io/proto/slim/otlp v1.9.0 h1:fPVMv8tP3TrsqlkH1HWYUpbCY9cAIemx184VGkS6vlE= -go.opentelemetry.io/proto/slim/otlp v1.9.0/go.mod h1:xXdeJJ90Gqyll+orzUkY4bOd2HECo5JofeoLpymVqdI= -go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.2.0 h1:o13nadWDNkH/quoDomDUClnQBpdQQ2Qqv0lQBjIXjE8= -go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.2.0/go.mod h1:Gyb6Xe7FTi/6xBHwMmngGoHqL0w29Y4eW8TGFzpefGA= -go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.2.0 h1:EiUYvtwu6PMrMHVjcPfnsG3v+ajPkbUeH+IL93+QYyk= -go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.2.0/go.mod h1:mUUHKFiN2SST3AhJ8XhJxEoeVW12oqfXog0Bo8W3Ec4= +go.opentelemetry.io/otel v1.42.0 h1:lSQGzTgVR3+sgJDAU/7/ZMjN9Z+vUip7leaqBKy4sho= +go.opentelemetry.io/otel v1.42.0/go.mod h1:lJNsdRMxCUIWuMlVJWzecSMuNjE7dOYyWlqOXWkdqCc= +go.opentelemetry.io/otel/metric v1.42.0 h1:2jXG+3oZLNXEPfNmnpxKDeZsFI5o4J+nz6xUlaFdF/4= +go.opentelemetry.io/otel/metric v1.42.0/go.mod h1:RlUN/7vTU7Ao/diDkEpQpnz3/92J9ko05BIwxYa2SSI= +go.opentelemetry.io/otel/trace v1.42.0 h1:OUCgIPt+mzOnaUTpOQcBiM/PLQ/Op7oq6g4LenLmOYY= +go.opentelemetry.io/otel/trace v1.42.0/go.mod h1:f3K9S+IFqnumBkKhRJMeaZeNk9epyhnCmQh/EysQCdc= +go.opentelemetry.io/proto/slim/otlp v1.10.0 h1:iR97Vs/ZDR+y9TfuP9b1XBtdPWeC+OMslIBmhcLU7jM= +go.opentelemetry.io/proto/slim/otlp v1.10.0/go.mod h1:lV9250stpjYLPNA5viFabIgP2QlUGRT1GdTgAf8SIUk= +go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.3.0 h1:RUF5rO0hAlgiJt1fzQVzcVs3vZVNHIcMLgOgG4rWNcQ= +go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.3.0/go.mod h1:I89cynRj8y+383o7tEQVg2SVA6SRgDVIouWPUVXjx0U= +go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.3.0 h1:CQvJSldHRUN6Z8jsUeYv8J0lXRvygALXIzsmAeCcZE0= +go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.3.0/go.mod h1:xSQ+mEfJe/GjK1LXEyVOoSI1N9JV9ZI923X5kup43W4= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= go.uber.org/zap v1.27.1 h1:08RqriUEv8+ArZRYSTXy1LeBScaMpVSTBhCeaZYfMYc= go.uber.org/zap v1.27.1/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= -google.golang.org/protobuf v1.36.10 h1:AYd7cD/uASjIL6Q9LiTjz8JLcrh/88q5UObnmY3aOOE= -google.golang.org/protobuf v1.36.10/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= +google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE= +google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= diff --git a/processor/memorylimiterprocessor/README.md b/processor/memorylimiterprocessor/README.md index 492f0e1d73b9..e52f6d3ae782 100644 --- a/processor/memorylimiterprocessor/README.md +++ b/processor/memorylimiterprocessor/README.md @@ -1,6 +1,5 @@ -# Memory Limiter Processor - +# Memory Limiter Processor | Status | | | ------------- |-----------| | Stability | [alpha]: profiles | @@ -38,6 +37,13 @@ The processor will enter memory limited mode and will start refusing the data wh memory usage exceeds the soft limit. This is done by returning errors to the preceding component in the pipeline that made the ConsumeLogs/Trace/Metrics function call. +> Warning: Incoming data can consume additional memory in a Collector before the +> memory limiter processor is able to reject it. Be sure to consider this when +> setting your limits, particularly for non-OTLP receivers. +> +> See for +> more. + In memory limited mode the error returned by ConsumeLogs/Trace/Metrics function is a non-permanent error. When receivers see this error they are expected to retry sending the same data. The receivers may also apply backpressure to their own data sources @@ -79,12 +85,33 @@ memory check interval. Otherwise, memory usage may exceed the hard limit, even i A good starting point for `spike_limit_mib` is 20% of the hard limit. Bigger `spike_limit_mib` values may be necessary for spiky traffic or for longer check intervals. +It's recommended to coordinate the hard memory limit with the host environment +of the Collector. As always, you know your environment best, so use your own +judgement to determine the best configuration for your situation. However, the +following points are worth considering when configuring the processor: + +For containerized environments or other similar environments that support +setting memory restrictions on the Collector, `limit_percentage` should +generally be used, which allows the host environment to determine the +Collector's max memory allocation without tying the Collector's own config to +its deployment config. The percentage should be large enough to use the majority +of the Collector's allocated memory, but not so much that it risks running out +of memory. + +For bare metal or virtualized environments where the Collector's memory is not +constrained by the host environment, it is recommended to use `limit_mib` for +environments where you know the rough data throughput and memory consumption you +expect for a given Collector, regardless of the memory capacity of the machine +it runs on. If the Collector's memory consumption is expected to scale with its +host machine's memory capacity, `limit_percentage` may be more appropriate. ## Configuration -Please refer to [memorylimiter.go](../../internal/memorylimiter/memorylimiter.go) for the config spec. +Please refer to [config.go](../../internal/memorylimiter/config.go) for the config spec. + +The following configuration options are available. Note that one of `limit_mib` +or `limit_percentage` must be set. -The following configuration options **must be changed**: - `check_interval` (default = 0s): Time between measurements of memory usage. The recommended value is 1 second. If the expected traffic to the Collector is very spiky then decrease the `check_interval` @@ -94,7 +121,7 @@ allocated by the process heap. Note that typically the total memory usage of process will be about 50MiB higher than this value. This defines the hard limit. - `spike_limit_mib` (default = 20% of `limit_mib`): Maximum spike expected between the measurements of memory usage. The value must be less than `limit_mib`. The soft limit -value will be equal to (limit_mib - spike_limit_mib). +value will be equal to (`limit_mib - spike_limit_mib`). The recommended value for `spike_limit_mib` is about 20% `limit_mib`. - `limit_percentage` (default = 0): Maximum amount of total memory targeted to be allocated by the process heap. This configuration is supported on Linux systems with cgroups @@ -134,6 +161,3 @@ On a machine with 1000 MiB total memory available: - Hard limit will be set to 1000 * 0.80 = **800 MiB**. - Soft limit will be set to 1000 * 0.80 - 1000 * 0.15 = 1000 * 0.65 = **650 MiB**. - -Refer to [config.yaml](../../internal/memorylimiter/testdata/config.yaml) for detailed -examples on using the processor. diff --git a/processor/memorylimiterprocessor/documentation.md b/processor/memorylimiterprocessor/documentation.md index 62fb21f99cb4..43cd5a341f13 100644 --- a/processor/memorylimiterprocessor/documentation.md +++ b/processor/memorylimiterprocessor/documentation.md @@ -8,48 +8,78 @@ The following telemetry is emitted by this component. ### otelcol_processor_accepted_log_records -Number of log records successfully pushed into the next component in the pipeline. [Deprecated since v0.110.0] +Number of log records successfully pushed into the next component in the pipeline. + +> **Deprecated since 0.110.0** +> This metric is deprecated | Unit | Metric Type | Value Type | Monotonic | Stability | | ---- | ----------- | ---------- | --------- | --------- | -| {records} | Sum | Int | true | Deprecated | +| {record} | Sum | Int | true | Deprecated since 0.110.0 | + +**Deprecation note**: This metric is deprecated ### otelcol_processor_accepted_metric_points -Number of metric points successfully pushed into the next component in the pipeline. [Deprecated since v0.110.0] +Number of metric points successfully pushed into the next component in the pipeline. + +> **Deprecated since 0.110.0** +> This metric is deprecated | Unit | Metric Type | Value Type | Monotonic | Stability | | ---- | ----------- | ---------- | --------- | --------- | -| {datapoints} | Sum | Int | true | Deprecated | +| {datapoint} | Sum | Int | true | Deprecated since 0.110.0 | + +**Deprecation note**: This metric is deprecated ### otelcol_processor_accepted_spans -Number of spans successfully pushed into the next component in the pipeline. [Deprecated since v0.110.0] +Number of spans successfully pushed into the next component in the pipeline. + +> **Deprecated since 0.110.0** +> This metric is deprecated | Unit | Metric Type | Value Type | Monotonic | Stability | | ---- | ----------- | ---------- | --------- | --------- | -| {spans} | Sum | Int | true | Deprecated | +| {span} | Sum | Int | true | Deprecated since 0.110.0 | + +**Deprecation note**: This metric is deprecated ### otelcol_processor_refused_log_records -Number of log records that were rejected by the next component in the pipeline. [Deprecated since v0.110.0] +Number of log records that were rejected by the next component in the pipeline. + +> **Deprecated since 0.110.0** +> This metric is deprecated | Unit | Metric Type | Value Type | Monotonic | Stability | | ---- | ----------- | ---------- | --------- | --------- | -| {records} | Sum | Int | true | Deprecated | +| {record} | Sum | Int | true | Deprecated since 0.110.0 | + +**Deprecation note**: This metric is deprecated ### otelcol_processor_refused_metric_points -Number of metric points that were rejected by the next component in the pipeline. [Deprecated since v0.110.0] +Number of metric points that were rejected by the next component in the pipeline. + +> **Deprecated since 0.110.0** +> This metric is deprecated | Unit | Metric Type | Value Type | Monotonic | Stability | | ---- | ----------- | ---------- | --------- | --------- | -| {datapoints} | Sum | Int | true | Deprecated | +| {datapoint} | Sum | Int | true | Deprecated since 0.110.0 | + +**Deprecation note**: This metric is deprecated ### otelcol_processor_refused_spans -Number of spans that were rejected by the next component in the pipeline. [Deprecated since v0.110.0] +Number of spans that were rejected by the next component in the pipeline. + +> **Deprecated since 0.110.0** +> This metric is deprecated | Unit | Metric Type | Value Type | Monotonic | Stability | | ---- | ----------- | ---------- | --------- | --------- | -| {spans} | Sum | Int | true | Deprecated | +| {span} | Sum | Int | true | Deprecated since 0.110.0 | + +**Deprecation note**: This metric is deprecated diff --git a/processor/memorylimiterprocessor/generated_component_test.go b/processor/memorylimiterprocessor/generated_component_test.go index 908970c78923..00acfb21580a 100644 --- a/processor/memorylimiterprocessor/generated_component_test.go +++ b/processor/memorylimiterprocessor/generated_component_test.go @@ -19,6 +19,7 @@ import ( "go.opentelemetry.io/collector/pdata/ptrace" "go.opentelemetry.io/collector/processor" "go.opentelemetry.io/collector/processor/processortest" + "go.opentelemetry.io/collector/processor/xprocessor" ) var typ = component.MustNewType("memory_limiter") @@ -59,6 +60,13 @@ func TestComponentLifecycle(t *testing.T) { return factory.CreateTraces(ctx, set, cfg, consumertest.NewNop()) }, }, + + { + name: "profiles", + createFn: func(ctx context.Context, set processor.Settings, cfg component.Config) (component.Component, error) { + return factory.(xprocessor.Factory).CreateProfiles(ctx, set, cfg, consumertest.NewNop()) + }, + }, } cm, err := confmaptest.LoadConf("metadata.yaml") diff --git a/processor/memorylimiterprocessor/go.mod b/processor/memorylimiterprocessor/go.mod index 2214d6a9ab9c..c7049e045977 100644 --- a/processor/memorylimiterprocessor/go.mod +++ b/processor/memorylimiterprocessor/go.mod @@ -1,72 +1,73 @@ module go.opentelemetry.io/collector/processor/memorylimiterprocessor -go 1.24.0 +go 1.25.0 require ( github.com/stretchr/testify v1.11.1 - go.opentelemetry.io/collector/component v1.46.0 - go.opentelemetry.io/collector/component/componenttest v0.140.0 - go.opentelemetry.io/collector/confmap v1.46.0 - go.opentelemetry.io/collector/consumer v1.46.0 + go.opentelemetry.io/collector/component v1.54.0 + go.opentelemetry.io/collector/component/componenttest v0.148.0 + go.opentelemetry.io/collector/confmap v1.54.0 + go.opentelemetry.io/collector/consumer v1.54.0 go.opentelemetry.io/collector/consumer/consumererror v0.140.0 - go.opentelemetry.io/collector/consumer/consumertest v0.140.0 - go.opentelemetry.io/collector/consumer/xconsumer v0.140.0 + go.opentelemetry.io/collector/consumer/consumertest v0.148.0 + go.opentelemetry.io/collector/consumer/xconsumer v0.148.0 go.opentelemetry.io/collector/internal/memorylimiter v0.140.0 go.opentelemetry.io/collector/internal/telemetry v0.140.0 - go.opentelemetry.io/collector/pdata v1.46.0 - go.opentelemetry.io/collector/pdata/pprofile v0.140.0 - go.opentelemetry.io/collector/pipeline v1.46.0 + go.opentelemetry.io/collector/pdata v1.54.0 + go.opentelemetry.io/collector/pdata/pprofile v0.148.0 + go.opentelemetry.io/collector/pipeline v1.54.0 go.opentelemetry.io/collector/pipeline/xpipeline v0.140.0 - go.opentelemetry.io/collector/processor v1.46.0 - go.opentelemetry.io/collector/processor/processorhelper v0.140.0 + go.opentelemetry.io/collector/processor v1.54.0 + go.opentelemetry.io/collector/processor/processorhelper v0.148.0 go.opentelemetry.io/collector/processor/processorhelper/xprocessorhelper v0.140.0 - go.opentelemetry.io/collector/processor/processortest v0.140.0 - go.opentelemetry.io/collector/processor/xprocessor v0.140.0 - go.opentelemetry.io/otel v1.40.0 - go.opentelemetry.io/otel/metric v1.40.0 + go.opentelemetry.io/collector/processor/processortest v0.148.0 + go.opentelemetry.io/collector/processor/xprocessor v0.148.0 + go.opentelemetry.io/otel v1.42.0 + go.opentelemetry.io/otel/metric v1.42.0 go.opentelemetry.io/otel/sdk/metric v1.40.0 - go.opentelemetry.io/otel/trace v1.40.0 + go.opentelemetry.io/otel/trace v1.42.0 go.uber.org/goleak v1.3.0 ) require ( github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/davecgh/go-spew v1.1.1 // indirect - github.com/ebitengine/purego v0.9.0 // indirect + github.com/ebitengine/purego v0.10.0 // indirect github.com/go-logr/logr v1.4.3 // indirect github.com/go-logr/stdr v1.2.2 // indirect github.com/go-ole/go-ole v1.2.6 // indirect - github.com/go-viper/mapstructure/v2 v2.4.0 // indirect + github.com/go-viper/mapstructure/v2 v2.5.0 // indirect github.com/gobwas/glob v0.2.3 // indirect github.com/google/uuid v1.6.0 // indirect - github.com/hashicorp/go-version v1.7.0 // indirect + github.com/hashicorp/go-version v1.8.0 // indirect github.com/json-iterator/go v1.1.12 // indirect github.com/knadh/koanf/maps v0.1.2 // indirect github.com/knadh/koanf/providers/confmap v1.0.0 // indirect - github.com/knadh/koanf/v2 v2.3.0 // indirect - github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 // indirect + github.com/knadh/koanf/v2 v2.3.3 // indirect + github.com/lufia/plan9stats v0.0.0-20251013123823-9fd1530e3ec3 // indirect github.com/mitchellh/copystructure v1.2.0 // indirect github.com/mitchellh/reflectwalk v1.0.2 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee // indirect github.com/pmezard/go-difflib v1.0.0 // indirect github.com/power-devops/perfstat v0.0.0-20240221224432-82ca36839d55 // indirect - github.com/shirou/gopsutil/v4 v4.25.10 // indirect - github.com/tklauser/go-sysconf v0.3.15 // indirect - github.com/tklauser/numcpus v0.10.0 // indirect + github.com/shirou/gopsutil/v4 v4.26.2 // indirect + github.com/tklauser/go-sysconf v0.3.16 // indirect + github.com/tklauser/numcpus v0.11.0 // indirect github.com/yusufpapurcu/wmi v1.2.4 // indirect go.opentelemetry.io/auto/sdk v1.2.1 // indirect - go.opentelemetry.io/collector/component/componentstatus v0.140.0 // indirect - go.opentelemetry.io/collector/featuregate v1.46.0 // indirect - go.opentelemetry.io/collector/pdata/testdata v0.140.0 // indirect + go.opentelemetry.io/collector/component/componentstatus v0.148.0 // indirect + go.opentelemetry.io/collector/featuregate v1.54.0 // indirect + go.opentelemetry.io/collector/internal/componentalias v0.148.0 // indirect + go.opentelemetry.io/collector/pdata/testdata v0.148.0 // indirect go.opentelemetry.io/otel/sdk v1.40.0 // indirect go.uber.org/multierr v1.11.0 // indirect go.uber.org/zap v1.27.1 // indirect go.yaml.in/yaml/v3 v3.0.4 // indirect - golang.org/x/sys v0.40.0 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20251022142026-3a174f9686a8 // indirect - google.golang.org/grpc v1.77.0 // indirect - google.golang.org/protobuf v1.36.10 // indirect + golang.org/x/sys v0.41.0 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20251222181119-0a764e51fe1b // indirect + google.golang.org/grpc v1.79.3 // indirect + google.golang.org/protobuf v1.36.11 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) @@ -118,3 +119,5 @@ replace go.opentelemetry.io/collector/processor/processorhelper => ../processorh replace go.opentelemetry.io/collector/pipeline/xpipeline => ../../pipeline/xpipeline replace go.opentelemetry.io/collector/internal/testutil => ../../internal/testutil + +replace go.opentelemetry.io/collector/internal/componentalias => ../../internal/componentalias diff --git a/processor/memorylimiterprocessor/go.sum b/processor/memorylimiterprocessor/go.sum index 9f66305bd567..197d590e7010 100644 --- a/processor/memorylimiterprocessor/go.sum +++ b/processor/memorylimiterprocessor/go.sum @@ -3,8 +3,8 @@ github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XL github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/ebitengine/purego v0.9.0 h1:mh0zpKBIXDceC63hpvPuGLiJ8ZAa3DfrFTudmfi8A4k= -github.com/ebitengine/purego v0.9.0/go.mod h1:iIjxzd6CiRiOG0UyXP+V1+jWqUXVjPKLAI0mRfJZTmQ= +github.com/ebitengine/purego v0.10.0 h1:QIw4xfpWT6GWTzaW5XEKy3HXoqrJGx1ijYHzTF0/ISU= +github.com/ebitengine/purego v0.10.0/go.mod h1:iIjxzd6CiRiOG0UyXP+V1+jWqUXVjPKLAI0mRfJZTmQ= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI= github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= @@ -12,34 +12,33 @@ github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY= github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0= -github.com/go-viper/mapstructure/v2 v2.4.0 h1:EBsztssimR/CONLSZZ04E8qAkxNYq4Qp9LvH92wZUgs= -github.com/go-viper/mapstructure/v2 v2.4.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM= +github.com/go-viper/mapstructure/v2 v2.5.0 h1:vM5IJoUAy3d7zRSVtIwQgBj7BiWtMPfmPEgAXnvj1Ro= +github.com/go-viper/mapstructure/v2 v2.5.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM= github.com/gobwas/glob v0.2.3 h1:A4xDbljILXROh+kObIiy5kIaPYD8e96x1tgBhUI5J+Y= github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8= github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= -github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/hashicorp/go-version v1.7.0 h1:5tqGy27NaOTB8yJKUZELlFAS/LTKJkrmONwQKeRZfjY= -github.com/hashicorp/go-version v1.7.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= +github.com/hashicorp/go-version v1.8.0 h1:KAkNb1HAiZd1ukkxDFGmokVZe1Xy9HG6NUp+bPle2i4= +github.com/hashicorp/go-version v1.8.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= github.com/knadh/koanf/maps v0.1.2 h1:RBfmAW5CnZT+PJ1CVc1QSJKf4Xu9kxfQgYVQSu8hpbo= github.com/knadh/koanf/maps v0.1.2/go.mod h1:npD/QZY3V6ghQDdcQzl1W4ICNVTkohC8E73eI2xW4yI= github.com/knadh/koanf/providers/confmap v1.0.0 h1:mHKLJTE7iXEys6deO5p6olAiZdG5zwp8Aebir+/EaRE= github.com/knadh/koanf/providers/confmap v1.0.0/go.mod h1:txHYHiI2hAtF0/0sCmcuol4IDcuQbKTybiB1nOcUo1A= -github.com/knadh/koanf/v2 v2.3.0 h1:Qg076dDRFHvqnKG97ZEsi9TAg2/nFTa9hCdcSa1lvlM= -github.com/knadh/koanf/v2 v2.3.0/go.mod h1:gRb40VRAbd4iJMYYD5IxZ6hfuopFcXBpc9bbQpZwo28= +github.com/knadh/koanf/v2 v2.3.3 h1:jLJC8XCRfLC7n4F+ZKKdBsbq1bfXTpuFhf4L7t94D94= +github.com/knadh/koanf/v2 v2.3.3/go.mod h1:gRb40VRAbd4iJMYYD5IxZ6hfuopFcXBpc9bbQpZwo28= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= -github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 h1:6E+4a0GO5zZEnZ81pIr0yLvtUWk2if982qA3F3QD6H4= -github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0/go.mod h1:zJYVVT2jmtg6P3p1VtQj7WsuWi/y4VnjVBn7F8KPB3I= +github.com/lufia/plan9stats v0.0.0-20251013123823-9fd1530e3ec3 h1:PwQumkgq4/acIiZhtifTV5OUqqiP82UAl0h87xj/l9k= +github.com/lufia/plan9stats v0.0.0-20251013123823-9fd1530e3ec3/go.mod h1:autxFIvghDt3jPTLoqZ9OZ7s9qTGNAWmYCjVFWPX/zg= github.com/mitchellh/copystructure v1.2.0 h1:vpKXTN4ewci03Vljg/q9QvCGUDttBOGBIa15WveJJGw= github.com/mitchellh/copystructure v1.2.0/go.mod h1:qLl+cE2AmVv+CoeAwDPye/v+N2HKCj9FbZEVFJRxO9s= github.com/mitchellh/reflectwalk v1.0.2 h1:G2LzWKi524PWgd3mLHV8Y5k7s6XUvT0Gef6zxSIeXaQ= @@ -56,36 +55,36 @@ github.com/power-devops/perfstat v0.0.0-20240221224432-82ca36839d55 h1:o4JXh1EVt github.com/power-devops/perfstat v0.0.0-20240221224432-82ca36839d55/go.mod h1:OmDBASR4679mdNQnz2pUhc2G8CO2JrUAVFDRBDP/hJE= github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ= github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc= -github.com/shirou/gopsutil/v4 v4.25.10 h1:at8lk/5T1OgtuCp+AwrDofFRjnvosn0nkN2OLQ6g8tA= -github.com/shirou/gopsutil/v4 v4.25.10/go.mod h1:+kSwyC8DRUD9XXEHCAFjK+0nuArFJM0lva+StQAcskM= +github.com/shirou/gopsutil/v4 v4.26.2 h1:X8i6sicvUFih4BmYIGT1m2wwgw2VG9YgrDTi7cIRGUI= +github.com/shirou/gopsutil/v4 v4.26.2/go.mod h1:LZ6ewCSkBqUpvSOf+LsTGnRinC6iaNUNMGBtDkJBaLQ= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U= github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= -github.com/tklauser/go-sysconf v0.3.15 h1:VE89k0criAymJ/Os65CSn1IXaol+1wrsFHEB8Ol49K4= -github.com/tklauser/go-sysconf v0.3.15/go.mod h1:Dmjwr6tYFIseJw7a3dRLJfsHAMXZ3nEnL/aZY+0IuI4= -github.com/tklauser/numcpus v0.10.0 h1:18njr6LDBk1zuna922MgdjQuJFjrdppsZG60sHGfjso= -github.com/tklauser/numcpus v0.10.0/go.mod h1:BiTKazU708GQTYF4mB+cmlpT2Is1gLk7XVuEeem8LsQ= +github.com/tklauser/go-sysconf v0.3.16 h1:frioLaCQSsF5Cy1jgRBrzr6t502KIIwQ0MArYICU0nA= +github.com/tklauser/go-sysconf v0.3.16/go.mod h1:/qNL9xxDhc7tx3HSRsLWNnuzbVfh3e7gh/BmM179nYI= +github.com/tklauser/numcpus v0.11.0 h1:nSTwhKH5e1dMNsCdVBukSZrURJRoHbSEQjdEbY+9RXw= +github.com/tklauser/numcpus v0.11.0/go.mod h1:z+LwcLq54uWZTX0u/bGobaV34u6V7KNlTZejzM6/3MQ= github.com/yusufpapurcu/wmi v1.2.4 h1:zFUKzehAFReQwLys1b/iSMl+JQGSCSjtVqQn9bBrPo0= github.com/yusufpapurcu/wmi v1.2.4/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0= go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64= go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y= -go.opentelemetry.io/otel v1.40.0 h1:oA5YeOcpRTXq6NN7frwmwFR0Cn3RhTVZvXsP4duvCms= -go.opentelemetry.io/otel v1.40.0/go.mod h1:IMb+uXZUKkMXdPddhwAHm6UfOwJyh4ct1ybIlV14J0g= -go.opentelemetry.io/otel/metric v1.40.0 h1:rcZe317KPftE2rstWIBitCdVp89A2HqjkxR3c11+p9g= -go.opentelemetry.io/otel/metric v1.40.0/go.mod h1:ib/crwQH7N3r5kfiBZQbwrTge743UDc7DTFVZrrXnqc= +go.opentelemetry.io/otel v1.42.0 h1:lSQGzTgVR3+sgJDAU/7/ZMjN9Z+vUip7leaqBKy4sho= +go.opentelemetry.io/otel v1.42.0/go.mod h1:lJNsdRMxCUIWuMlVJWzecSMuNjE7dOYyWlqOXWkdqCc= +go.opentelemetry.io/otel/metric v1.42.0 h1:2jXG+3oZLNXEPfNmnpxKDeZsFI5o4J+nz6xUlaFdF/4= +go.opentelemetry.io/otel/metric v1.42.0/go.mod h1:RlUN/7vTU7Ao/diDkEpQpnz3/92J9ko05BIwxYa2SSI= go.opentelemetry.io/otel/sdk v1.40.0 h1:KHW/jUzgo6wsPh9At46+h4upjtccTmuZCFAc9OJ71f8= go.opentelemetry.io/otel/sdk v1.40.0/go.mod h1:Ph7EFdYvxq72Y8Li9q8KebuYUr2KoeyHx0DRMKrYBUE= go.opentelemetry.io/otel/sdk/metric v1.40.0 h1:mtmdVqgQkeRxHgRv4qhyJduP3fYJRMX4AtAlbuWdCYw= go.opentelemetry.io/otel/sdk/metric v1.40.0/go.mod h1:4Z2bGMf0KSK3uRjlczMOeMhKU2rhUqdWNoKcYrtcBPg= -go.opentelemetry.io/otel/trace v1.40.0 h1:WA4etStDttCSYuhwvEa8OP8I5EWu24lkOzp+ZYblVjw= -go.opentelemetry.io/otel/trace v1.40.0/go.mod h1:zeAhriXecNGP/s2SEG3+Y8X9ujcJOTqQ5RgdEJcawiA= -go.opentelemetry.io/proto/slim/otlp v1.9.0 h1:fPVMv8tP3TrsqlkH1HWYUpbCY9cAIemx184VGkS6vlE= -go.opentelemetry.io/proto/slim/otlp v1.9.0/go.mod h1:xXdeJJ90Gqyll+orzUkY4bOd2HECo5JofeoLpymVqdI= -go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.2.0 h1:o13nadWDNkH/quoDomDUClnQBpdQQ2Qqv0lQBjIXjE8= -go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.2.0/go.mod h1:Gyb6Xe7FTi/6xBHwMmngGoHqL0w29Y4eW8TGFzpefGA= -go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.2.0 h1:EiUYvtwu6PMrMHVjcPfnsG3v+ajPkbUeH+IL93+QYyk= -go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.2.0/go.mod h1:mUUHKFiN2SST3AhJ8XhJxEoeVW12oqfXog0Bo8W3Ec4= +go.opentelemetry.io/otel/trace v1.42.0 h1:OUCgIPt+mzOnaUTpOQcBiM/PLQ/Op7oq6g4LenLmOYY= +go.opentelemetry.io/otel/trace v1.42.0/go.mod h1:f3K9S+IFqnumBkKhRJMeaZeNk9epyhnCmQh/EysQCdc= +go.opentelemetry.io/proto/slim/otlp v1.10.0 h1:iR97Vs/ZDR+y9TfuP9b1XBtdPWeC+OMslIBmhcLU7jM= +go.opentelemetry.io/proto/slim/otlp v1.10.0/go.mod h1:lV9250stpjYLPNA5viFabIgP2QlUGRT1GdTgAf8SIUk= +go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.3.0 h1:RUF5rO0hAlgiJt1fzQVzcVs3vZVNHIcMLgOgG4rWNcQ= +go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.3.0/go.mod h1:I89cynRj8y+383o7tEQVg2SVA6SRgDVIouWPUVXjx0U= +go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.3.0 h1:CQvJSldHRUN6Z8jsUeYv8J0lXRvygALXIzsmAeCcZE0= +go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.3.0/go.mod h1:xSQ+mEfJe/GjK1LXEyVOoSI1N9JV9ZI923X5kup43W4= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= @@ -94,21 +93,20 @@ go.uber.org/zap v1.27.1 h1:08RqriUEv8+ArZRYSTXy1LeBScaMpVSTBhCeaZYfMYc= go.uber.org/zap v1.27.1/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc= go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg= -golang.org/x/net v0.46.1-0.20251013234738-63d1a5100f82 h1:6/3JGEh1C88g7m+qzzTbl3A0FtsLguXieqofVLU/JAo= -golang.org/x/net v0.46.1-0.20251013234738-63d1a5100f82/go.mod h1:Q9BGdFy1y4nkUwiLvT5qtyhAnEHgnQ/zd8PfU6nc210= +golang.org/x/net v0.51.0 h1:94R/GTO7mt3/4wIKpcR5gkGmRLOuE/2hNGeWq/GBIFo= +golang.org/x/net v0.51.0/go.mod h1:aamm+2QF5ogm02fjy5Bb7CQ0WMt1/WVM7FtyaTLlA9Y= golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201204225414-ed752295db88/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.40.0 h1:DBZZqJ2Rkml6QMQsZywtnjnnGvHza6BTfYFWY9kjEWQ= -golang.org/x/sys v0.40.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= -golang.org/x/text v0.30.0 h1:yznKA/E9zq54KzlzBEAWn1NXSQ8DIp/NYMy88xJjl4k= -golang.org/x/text v0.30.0/go.mod h1:yDdHFIX9t+tORqspjENWgzaCVXgk0yYnYuSZ8UzzBVM= -golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -google.golang.org/genproto/googleapis/rpc v0.0.0-20251022142026-3a174f9686a8 h1:M1rk8KBnUsBDg1oPGHNCxG4vc1f49epmTO7xscSajMk= -google.golang.org/genproto/googleapis/rpc v0.0.0-20251022142026-3a174f9686a8/go.mod h1:7i2o+ce6H/6BluujYR+kqX3GKH+dChPTQU19wjRPiGk= -google.golang.org/grpc v1.77.0 h1:wVVY6/8cGA6vvffn+wWK5ToddbgdU3d8MNENr4evgXM= -google.golang.org/grpc v1.77.0/go.mod h1:z0BY1iVj0q8E1uSQCjL9cppRj+gnZjzDnzV0dHhrNig= -google.golang.org/protobuf v1.36.10 h1:AYd7cD/uASjIL6Q9LiTjz8JLcrh/88q5UObnmY3aOOE= -google.golang.org/protobuf v1.36.10/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= +golang.org/x/sys v0.41.0 h1:Ivj+2Cp/ylzLiEU89QhWblYnOE9zerudt9Ftecq2C6k= +golang.org/x/sys v0.41.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= +golang.org/x/text v0.34.0 h1:oL/Qq0Kdaqxa1KbNeMKwQq0reLCCaFtqu2eNuSeNHbk= +golang.org/x/text v0.34.0/go.mod h1:homfLqTYRFyVYemLBFl5GgL/DWEiH5wcsQ5gSh1yziA= +google.golang.org/genproto/googleapis/rpc v0.0.0-20251222181119-0a764e51fe1b h1:Mv8VFug0MP9e5vUxfBcE3vUkV6CImK3cMNMIDFjmzxU= +google.golang.org/genproto/googleapis/rpc v0.0.0-20251222181119-0a764e51fe1b/go.mod h1:j9x/tPzZkyxcgEFkiKEEGxfvyumM01BEtsW8xzOahRQ= +google.golang.org/grpc v1.79.3 h1:sybAEdRIEtvcD68Gx7dmnwjZKlyfuc61Dyo9pGXXkKE= +google.golang.org/grpc v1.79.3/go.mod h1:KmT0Kjez+0dde/v2j9vzwoAScgEPx/Bw1CYChhHLrHQ= +google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE= +google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= diff --git a/processor/memorylimiterprocessor/internal/metadata/generated_telemetry.go b/processor/memorylimiterprocessor/internal/metadata/generated_telemetry.go index 176b5f1d8647..6d21bd559a14 100644 --- a/processor/memorylimiterprocessor/internal/metadata/generated_telemetry.go +++ b/processor/memorylimiterprocessor/internal/metadata/generated_telemetry.go @@ -65,38 +65,38 @@ func NewTelemetryBuilder(settings component.TelemetrySettings, options ...Teleme var err, errs error builder.ProcessorAcceptedLogRecords, err = builder.meter.Int64Counter( "otelcol_processor_accepted_log_records", - metric.WithDescription("Number of log records successfully pushed into the next component in the pipeline. [Deprecated since v0.110.0]"), - metric.WithUnit("{records}"), + metric.WithDescription("Number of log records successfully pushed into the next component in the pipeline. [Deprecated]"), + metric.WithUnit("{record}"), ) errs = errors.Join(errs, err) builder.ProcessorAcceptedMetricPoints, err = builder.meter.Int64Counter( "otelcol_processor_accepted_metric_points", - metric.WithDescription("Number of metric points successfully pushed into the next component in the pipeline. [Deprecated since v0.110.0]"), - metric.WithUnit("{datapoints}"), + metric.WithDescription("Number of metric points successfully pushed into the next component in the pipeline. [Deprecated]"), + metric.WithUnit("{datapoint}"), ) errs = errors.Join(errs, err) builder.ProcessorAcceptedSpans, err = builder.meter.Int64Counter( "otelcol_processor_accepted_spans", - metric.WithDescription("Number of spans successfully pushed into the next component in the pipeline. [Deprecated since v0.110.0]"), - metric.WithUnit("{spans}"), + metric.WithDescription("Number of spans successfully pushed into the next component in the pipeline. [Deprecated]"), + metric.WithUnit("{span}"), ) errs = errors.Join(errs, err) builder.ProcessorRefusedLogRecords, err = builder.meter.Int64Counter( "otelcol_processor_refused_log_records", - metric.WithDescription("Number of log records that were rejected by the next component in the pipeline. [Deprecated since v0.110.0]"), - metric.WithUnit("{records}"), + metric.WithDescription("Number of log records that were rejected by the next component in the pipeline. [Deprecated]"), + metric.WithUnit("{record}"), ) errs = errors.Join(errs, err) builder.ProcessorRefusedMetricPoints, err = builder.meter.Int64Counter( "otelcol_processor_refused_metric_points", - metric.WithDescription("Number of metric points that were rejected by the next component in the pipeline. [Deprecated since v0.110.0]"), - metric.WithUnit("{datapoints}"), + metric.WithDescription("Number of metric points that were rejected by the next component in the pipeline. [Deprecated]"), + metric.WithUnit("{datapoint}"), ) errs = errors.Join(errs, err) builder.ProcessorRefusedSpans, err = builder.meter.Int64Counter( "otelcol_processor_refused_spans", - metric.WithDescription("Number of spans that were rejected by the next component in the pipeline. [Deprecated since v0.110.0]"), - metric.WithUnit("{spans}"), + metric.WithDescription("Number of spans that were rejected by the next component in the pipeline. [Deprecated]"), + metric.WithUnit("{span}"), ) errs = errors.Join(errs, err) return &builder, errs diff --git a/processor/memorylimiterprocessor/internal/metadatatest/generated_telemetrytest.go b/processor/memorylimiterprocessor/internal/metadatatest/generated_telemetrytest.go index 0f931acdd80a..2b9584a11857 100644 --- a/processor/memorylimiterprocessor/internal/metadatatest/generated_telemetrytest.go +++ b/processor/memorylimiterprocessor/internal/metadatatest/generated_telemetrytest.go @@ -25,8 +25,8 @@ func NewSettings(tt *componenttest.Telemetry) processor.Settings { func AssertEqualProcessorAcceptedLogRecords(t *testing.T, tt *componenttest.Telemetry, dps []metricdata.DataPoint[int64], opts ...metricdatatest.Option) { want := metricdata.Metrics{ Name: "otelcol_processor_accepted_log_records", - Description: "Number of log records successfully pushed into the next component in the pipeline. [Deprecated since v0.110.0]", - Unit: "{records}", + Description: "Number of log records successfully pushed into the next component in the pipeline. [Deprecated]", + Unit: "{record}", Data: metricdata.Sum[int64]{ Temporality: metricdata.CumulativeTemporality, IsMonotonic: true, @@ -41,8 +41,8 @@ func AssertEqualProcessorAcceptedLogRecords(t *testing.T, tt *componenttest.Tele func AssertEqualProcessorAcceptedMetricPoints(t *testing.T, tt *componenttest.Telemetry, dps []metricdata.DataPoint[int64], opts ...metricdatatest.Option) { want := metricdata.Metrics{ Name: "otelcol_processor_accepted_metric_points", - Description: "Number of metric points successfully pushed into the next component in the pipeline. [Deprecated since v0.110.0]", - Unit: "{datapoints}", + Description: "Number of metric points successfully pushed into the next component in the pipeline. [Deprecated]", + Unit: "{datapoint}", Data: metricdata.Sum[int64]{ Temporality: metricdata.CumulativeTemporality, IsMonotonic: true, @@ -57,8 +57,8 @@ func AssertEqualProcessorAcceptedMetricPoints(t *testing.T, tt *componenttest.Te func AssertEqualProcessorAcceptedSpans(t *testing.T, tt *componenttest.Telemetry, dps []metricdata.DataPoint[int64], opts ...metricdatatest.Option) { want := metricdata.Metrics{ Name: "otelcol_processor_accepted_spans", - Description: "Number of spans successfully pushed into the next component in the pipeline. [Deprecated since v0.110.0]", - Unit: "{spans}", + Description: "Number of spans successfully pushed into the next component in the pipeline. [Deprecated]", + Unit: "{span}", Data: metricdata.Sum[int64]{ Temporality: metricdata.CumulativeTemporality, IsMonotonic: true, @@ -73,8 +73,8 @@ func AssertEqualProcessorAcceptedSpans(t *testing.T, tt *componenttest.Telemetry func AssertEqualProcessorRefusedLogRecords(t *testing.T, tt *componenttest.Telemetry, dps []metricdata.DataPoint[int64], opts ...metricdatatest.Option) { want := metricdata.Metrics{ Name: "otelcol_processor_refused_log_records", - Description: "Number of log records that were rejected by the next component in the pipeline. [Deprecated since v0.110.0]", - Unit: "{records}", + Description: "Number of log records that were rejected by the next component in the pipeline. [Deprecated]", + Unit: "{record}", Data: metricdata.Sum[int64]{ Temporality: metricdata.CumulativeTemporality, IsMonotonic: true, @@ -89,8 +89,8 @@ func AssertEqualProcessorRefusedLogRecords(t *testing.T, tt *componenttest.Telem func AssertEqualProcessorRefusedMetricPoints(t *testing.T, tt *componenttest.Telemetry, dps []metricdata.DataPoint[int64], opts ...metricdatatest.Option) { want := metricdata.Metrics{ Name: "otelcol_processor_refused_metric_points", - Description: "Number of metric points that were rejected by the next component in the pipeline. [Deprecated since v0.110.0]", - Unit: "{datapoints}", + Description: "Number of metric points that were rejected by the next component in the pipeline. [Deprecated]", + Unit: "{datapoint}", Data: metricdata.Sum[int64]{ Temporality: metricdata.CumulativeTemporality, IsMonotonic: true, @@ -105,8 +105,8 @@ func AssertEqualProcessorRefusedMetricPoints(t *testing.T, tt *componenttest.Tel func AssertEqualProcessorRefusedSpans(t *testing.T, tt *componenttest.Telemetry, dps []metricdata.DataPoint[int64], opts ...metricdatatest.Option) { want := metricdata.Metrics{ Name: "otelcol_processor_refused_spans", - Description: "Number of spans that were rejected by the next component in the pipeline. [Deprecated since v0.110.0]", - Unit: "{spans}", + Description: "Number of spans that were rejected by the next component in the pipeline. [Deprecated]", + Unit: "{span}", Data: metricdata.Sum[int64]{ Temporality: metricdata.CumulativeTemporality, IsMonotonic: true, diff --git a/processor/memorylimiterprocessor/memorylimiter_test.go b/processor/memorylimiterprocessor/memorylimiter_test.go index 55d78950efcf..daea8e26e214 100644 --- a/processor/memorylimiterprocessor/memorylimiter_test.go +++ b/processor/memorylimiterprocessor/memorylimiter_test.go @@ -55,7 +55,6 @@ func TestNoDataLoss(t *testing.T) { runtime.ReadMemStats(&ms) // Set the limit to current usage plus expected increase. This means initially we will not be limited. - //nolint:gosec cfg.MemoryLimitMiB = uint32(ms.Alloc/(1024*1024) + expectedMemoryIncreaseMiB) cfg.MemorySpikeLimitMiB = 1 diff --git a/processor/memorylimiterprocessor/metadata.yaml b/processor/memorylimiterprocessor/metadata.yaml index aa8813f1eaf7..ee72f43b6ab3 100644 --- a/processor/memorylimiterprocessor/metadata.yaml +++ b/processor/memorylimiterprocessor/metadata.yaml @@ -1,3 +1,4 @@ +display_name: Memory Limiter Processor type: memory_limiter github_project: open-telemetry/opentelemetry-collector @@ -20,10 +21,11 @@ telemetry: processor_accepted_log_records: enabled: true description: Number of log records successfully pushed into the next component in the pipeline. - stability: - level: deprecated - from: v0.110.0 - unit: "{records}" + stability: deprecated + deprecated: + since: "0.110.0" + note: "This metric is deprecated" + unit: "{record}" sum: value_type: int monotonic: true @@ -31,10 +33,11 @@ telemetry: processor_accepted_metric_points: enabled: true description: Number of metric points successfully pushed into the next component in the pipeline. - stability: - level: deprecated - from: v0.110.0 - unit: "{datapoints}" + stability: deprecated + deprecated: + since: "0.110.0" + note: "This metric is deprecated" + unit: "{datapoint}" sum: value_type: int monotonic: true @@ -42,10 +45,11 @@ telemetry: processor_accepted_spans: enabled: true description: Number of spans successfully pushed into the next component in the pipeline. - stability: - level: deprecated - from: v0.110.0 - unit: "{spans}" + stability: deprecated + deprecated: + since: "0.110.0" + note: "This metric is deprecated" + unit: "{span}" sum: value_type: int monotonic: true @@ -53,10 +57,11 @@ telemetry: processor_refused_log_records: enabled: true description: Number of log records that were rejected by the next component in the pipeline. - stability: - level: deprecated - from: v0.110.0 - unit: "{records}" + stability: deprecated + deprecated: + since: "0.110.0" + note: "This metric is deprecated" + unit: "{record}" sum: value_type: int monotonic: true @@ -64,10 +69,11 @@ telemetry: processor_refused_metric_points: enabled: true description: Number of metric points that were rejected by the next component in the pipeline. - stability: - level: deprecated - from: v0.110.0 - unit: "{datapoints}" + stability: deprecated + deprecated: + since: "0.110.0" + note: "This metric is deprecated" + unit: "{datapoint}" sum: value_type: int monotonic: true @@ -75,10 +81,11 @@ telemetry: processor_refused_spans: enabled: true description: Number of spans that were rejected by the next component in the pipeline. - stability: - level: deprecated - from: v0.110.0 - unit: "{spans}" + stability: deprecated + deprecated: + since: "0.110.0" + note: "This metric is deprecated" + unit: "{span}" sum: value_type: int monotonic: true diff --git a/processor/metadata.yaml b/processor/metadata.yaml new file mode 100644 index 000000000000..ef2a6030f6d9 --- /dev/null +++ b/processor/metadata.yaml @@ -0,0 +1,6 @@ +type: processor +github_project: open-telemetry/opentelemetry-collector + +status: + disable_codecov_badge: true + class: pkg diff --git a/processor/processor.go b/processor/processor.go index 93ed0b69f653..8b1203e9f530 100644 --- a/processor/processor.go +++ b/processor/processor.go @@ -8,8 +8,8 @@ import ( "go.opentelemetry.io/collector/component" "go.opentelemetry.io/collector/consumer" + "go.opentelemetry.io/collector/internal/componentalias" "go.opentelemetry.io/collector/pipeline" - "go.opentelemetry.io/collector/processor/internal" ) // Traces is a processor that can consume traces. @@ -99,6 +99,7 @@ func (f factoryOptionFunc) applyOption(o *factory) { type factory struct { cfgType component.Type component.CreateDefaultConfigFunc + componentalias.TypeAliasHolder createTracesFunc CreateTracesFunc tracesStabilityLevel component.StabilityLevel createMetricsFunc CreateMetricsFunc @@ -130,8 +131,8 @@ func (f *factory) CreateTraces(ctx context.Context, set Settings, cfg component. return nil, pipeline.ErrSignalNotSupported } - if set.ID.Type() != f.Type() { - return nil, internal.ErrIDMismatch(set.ID, f.Type()) + if err := componentalias.ValidateComponentType(f, set.ID); err != nil { + return nil, err } return f.createTracesFunc(ctx, set, cfg, next) @@ -142,8 +143,8 @@ func (f *factory) CreateMetrics(ctx context.Context, set Settings, cfg component return nil, pipeline.ErrSignalNotSupported } - if set.ID.Type() != f.Type() { - return nil, internal.ErrIDMismatch(set.ID, f.Type()) + if err := componentalias.ValidateComponentType(f, set.ID); err != nil { + return nil, err } return f.createMetricsFunc(ctx, set, cfg, next) @@ -154,8 +155,8 @@ func (f *factory) CreateLogs(ctx context.Context, set Settings, cfg component.Co return nil, pipeline.ErrSignalNotSupported } - if set.ID.Type() != f.Type() { - return nil, internal.ErrIDMismatch(set.ID, f.Type()) + if err := componentalias.ValidateComponentType(f, set.ID); err != nil { + return nil, err } return f.createLogsFunc(ctx, set, cfg, next) @@ -199,6 +200,7 @@ func NewFactory(cfgType component.Type, createDefaultConfig component.CreateDefa f := &factory{ cfgType: cfgType, CreateDefaultConfigFunc: createDefaultConfig, + TypeAliasHolder: componentalias.NewTypeAliasHolder(), } for _, opt := range options { opt.applyOption(f) diff --git a/processor/processorhelper/documentation.md b/processor/processorhelper/documentation.md index 780f1312a32f..4c34ca2c7641 100644 --- a/processor/processorhelper/documentation.md +++ b/processor/processorhelper/documentation.md @@ -8,15 +8,15 @@ The following telemetry is emitted by this component. ### otelcol_processor_incoming_items -Number of items passed to the processor. [Alpha] +Number of items passed to the processor. | Unit | Metric Type | Value Type | Monotonic | Stability | | ---- | ----------- | ---------- | --------- | --------- | -| {items} | Sum | Int | true | Alpha | +| {item} | Sum | Int | true | Alpha | ### otelcol_processor_internal_duration -Duration of time taken to process a batch of telemetry data through the processor. [Alpha] +Duration of time taken to process a batch of telemetry data through the processor. | Unit | Metric Type | Value Type | Stability | | ---- | ----------- | ---------- | --------- | @@ -24,8 +24,8 @@ Duration of time taken to process a batch of telemetry data through the processo ### otelcol_processor_outgoing_items -Number of items emitted from the processor. [Alpha] +Number of items emitted from the processor. | Unit | Metric Type | Value Type | Monotonic | Stability | | ---- | ----------- | ---------- | --------- | --------- | -| {items} | Sum | Int | true | Alpha | +| {item} | Sum | Int | true | Alpha | diff --git a/processor/processorhelper/go.mod b/processor/processorhelper/go.mod index 3f4dbaeef31e..aeeaf55fd39f 100644 --- a/processor/processorhelper/go.mod +++ b/processor/processorhelper/go.mod @@ -1,23 +1,23 @@ module go.opentelemetry.io/collector/processor/processorhelper -go 1.24.0 +go 1.25.0 replace go.opentelemetry.io/collector/processor => ../ require ( github.com/stretchr/testify v1.11.1 - go.opentelemetry.io/collector/component v1.46.0 - go.opentelemetry.io/collector/component/componenttest v0.140.0 - go.opentelemetry.io/collector/consumer v1.46.0 - go.opentelemetry.io/collector/consumer/consumertest v0.140.0 - go.opentelemetry.io/collector/pdata v1.46.0 - go.opentelemetry.io/collector/pipeline v1.46.0 - go.opentelemetry.io/collector/processor v1.46.0 + go.opentelemetry.io/collector/component v1.54.0 + go.opentelemetry.io/collector/component/componenttest v0.148.0 + go.opentelemetry.io/collector/consumer v1.54.0 + go.opentelemetry.io/collector/consumer/consumertest v0.148.0 + go.opentelemetry.io/collector/pdata v1.54.0 + go.opentelemetry.io/collector/pipeline v1.54.0 + go.opentelemetry.io/collector/processor v1.54.0 go.opentelemetry.io/collector/processor/processortest v0.140.0 - go.opentelemetry.io/otel v1.40.0 - go.opentelemetry.io/otel/metric v1.40.0 + go.opentelemetry.io/otel v1.42.0 + go.opentelemetry.io/otel/metric v1.42.0 go.opentelemetry.io/otel/sdk/metric v1.40.0 - go.opentelemetry.io/otel/trace v1.40.0 + go.opentelemetry.io/otel/trace v1.42.0 go.uber.org/goleak v1.3.0 ) @@ -27,22 +27,23 @@ require ( github.com/go-logr/logr v1.4.3 // indirect github.com/go-logr/stdr v1.2.2 // indirect github.com/google/uuid v1.6.0 // indirect - github.com/hashicorp/go-version v1.7.0 // indirect + github.com/hashicorp/go-version v1.8.0 // indirect github.com/json-iterator/go v1.1.12 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee // indirect github.com/pmezard/go-difflib v1.0.0 // indirect go.opentelemetry.io/auto/sdk v1.2.1 // indirect - go.opentelemetry.io/collector/component/componentstatus v0.140.0 // indirect - go.opentelemetry.io/collector/consumer/xconsumer v0.140.0 // indirect - go.opentelemetry.io/collector/featuregate v1.46.0 // indirect - go.opentelemetry.io/collector/pdata/pprofile v0.140.0 // indirect - go.opentelemetry.io/collector/pdata/testdata v0.140.0 // indirect - go.opentelemetry.io/collector/processor/xprocessor v0.140.0 // indirect + go.opentelemetry.io/collector/component/componentstatus v0.148.0 // indirect + go.opentelemetry.io/collector/consumer/xconsumer v0.148.0 // indirect + go.opentelemetry.io/collector/featuregate v1.54.0 // indirect + go.opentelemetry.io/collector/internal/componentalias v0.148.0 // indirect + go.opentelemetry.io/collector/pdata/pprofile v0.148.0 // indirect + go.opentelemetry.io/collector/pdata/testdata v0.148.0 // indirect + go.opentelemetry.io/collector/processor/xprocessor v0.148.0 // indirect go.opentelemetry.io/otel/sdk v1.40.0 // indirect go.uber.org/multierr v1.11.0 // indirect go.uber.org/zap v1.27.1 // indirect - golang.org/x/sys v0.40.0 // indirect + golang.org/x/sys v0.41.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) @@ -73,3 +74,5 @@ replace go.opentelemetry.io/collector/component/componentstatus => ../../compone replace go.opentelemetry.io/collector/featuregate => ../../featuregate replace go.opentelemetry.io/collector/internal/testutil => ../../internal/testutil + +replace go.opentelemetry.io/collector/internal/componentalias => ../../internal/componentalias diff --git a/processor/processorhelper/go.sum b/processor/processorhelper/go.sum index c102571e7869..43bdbeb8d219 100644 --- a/processor/processorhelper/go.sum +++ b/processor/processorhelper/go.sum @@ -13,8 +13,8 @@ github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/hashicorp/go-version v1.7.0 h1:5tqGy27NaOTB8yJKUZELlFAS/LTKJkrmONwQKeRZfjY= -github.com/hashicorp/go-version v1.7.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= +github.com/hashicorp/go-version v1.8.0 h1:KAkNb1HAiZd1ukkxDFGmokVZe1Xy9HG6NUp+bPle2i4= +github.com/hashicorp/go-version v1.8.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= @@ -37,32 +37,32 @@ github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64= go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y= -go.opentelemetry.io/otel v1.40.0 h1:oA5YeOcpRTXq6NN7frwmwFR0Cn3RhTVZvXsP4duvCms= -go.opentelemetry.io/otel v1.40.0/go.mod h1:IMb+uXZUKkMXdPddhwAHm6UfOwJyh4ct1ybIlV14J0g= -go.opentelemetry.io/otel/metric v1.40.0 h1:rcZe317KPftE2rstWIBitCdVp89A2HqjkxR3c11+p9g= -go.opentelemetry.io/otel/metric v1.40.0/go.mod h1:ib/crwQH7N3r5kfiBZQbwrTge743UDc7DTFVZrrXnqc= +go.opentelemetry.io/otel v1.42.0 h1:lSQGzTgVR3+sgJDAU/7/ZMjN9Z+vUip7leaqBKy4sho= +go.opentelemetry.io/otel v1.42.0/go.mod h1:lJNsdRMxCUIWuMlVJWzecSMuNjE7dOYyWlqOXWkdqCc= +go.opentelemetry.io/otel/metric v1.42.0 h1:2jXG+3oZLNXEPfNmnpxKDeZsFI5o4J+nz6xUlaFdF/4= +go.opentelemetry.io/otel/metric v1.42.0/go.mod h1:RlUN/7vTU7Ao/diDkEpQpnz3/92J9ko05BIwxYa2SSI= go.opentelemetry.io/otel/sdk v1.40.0 h1:KHW/jUzgo6wsPh9At46+h4upjtccTmuZCFAc9OJ71f8= go.opentelemetry.io/otel/sdk v1.40.0/go.mod h1:Ph7EFdYvxq72Y8Li9q8KebuYUr2KoeyHx0DRMKrYBUE= go.opentelemetry.io/otel/sdk/metric v1.40.0 h1:mtmdVqgQkeRxHgRv4qhyJduP3fYJRMX4AtAlbuWdCYw= go.opentelemetry.io/otel/sdk/metric v1.40.0/go.mod h1:4Z2bGMf0KSK3uRjlczMOeMhKU2rhUqdWNoKcYrtcBPg= -go.opentelemetry.io/otel/trace v1.40.0 h1:WA4etStDttCSYuhwvEa8OP8I5EWu24lkOzp+ZYblVjw= -go.opentelemetry.io/otel/trace v1.40.0/go.mod h1:zeAhriXecNGP/s2SEG3+Y8X9ujcJOTqQ5RgdEJcawiA= -go.opentelemetry.io/proto/slim/otlp v1.9.0 h1:fPVMv8tP3TrsqlkH1HWYUpbCY9cAIemx184VGkS6vlE= -go.opentelemetry.io/proto/slim/otlp v1.9.0/go.mod h1:xXdeJJ90Gqyll+orzUkY4bOd2HECo5JofeoLpymVqdI= -go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.2.0 h1:o13nadWDNkH/quoDomDUClnQBpdQQ2Qqv0lQBjIXjE8= -go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.2.0/go.mod h1:Gyb6Xe7FTi/6xBHwMmngGoHqL0w29Y4eW8TGFzpefGA= -go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.2.0 h1:EiUYvtwu6PMrMHVjcPfnsG3v+ajPkbUeH+IL93+QYyk= -go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.2.0/go.mod h1:mUUHKFiN2SST3AhJ8XhJxEoeVW12oqfXog0Bo8W3Ec4= +go.opentelemetry.io/otel/trace v1.42.0 h1:OUCgIPt+mzOnaUTpOQcBiM/PLQ/Op7oq6g4LenLmOYY= +go.opentelemetry.io/otel/trace v1.42.0/go.mod h1:f3K9S+IFqnumBkKhRJMeaZeNk9epyhnCmQh/EysQCdc= +go.opentelemetry.io/proto/slim/otlp v1.10.0 h1:iR97Vs/ZDR+y9TfuP9b1XBtdPWeC+OMslIBmhcLU7jM= +go.opentelemetry.io/proto/slim/otlp v1.10.0/go.mod h1:lV9250stpjYLPNA5viFabIgP2QlUGRT1GdTgAf8SIUk= +go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.3.0 h1:RUF5rO0hAlgiJt1fzQVzcVs3vZVNHIcMLgOgG4rWNcQ= +go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.3.0/go.mod h1:I89cynRj8y+383o7tEQVg2SVA6SRgDVIouWPUVXjx0U= +go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.3.0 h1:CQvJSldHRUN6Z8jsUeYv8J0lXRvygALXIzsmAeCcZE0= +go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.3.0/go.mod h1:xSQ+mEfJe/GjK1LXEyVOoSI1N9JV9ZI923X5kup43W4= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= go.uber.org/zap v1.27.1 h1:08RqriUEv8+ArZRYSTXy1LeBScaMpVSTBhCeaZYfMYc= go.uber.org/zap v1.27.1/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= -golang.org/x/sys v0.40.0 h1:DBZZqJ2Rkml6QMQsZywtnjnnGvHza6BTfYFWY9kjEWQ= -golang.org/x/sys v0.40.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= -google.golang.org/protobuf v1.36.10 h1:AYd7cD/uASjIL6Q9LiTjz8JLcrh/88q5UObnmY3aOOE= -google.golang.org/protobuf v1.36.10/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= +golang.org/x/sys v0.41.0 h1:Ivj+2Cp/ylzLiEU89QhWblYnOE9zerudt9Ftecq2C6k= +golang.org/x/sys v0.41.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= +google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE= +google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= diff --git a/processor/processorhelper/internal/metadata/generated_telemetry.go b/processor/processorhelper/internal/metadata/generated_telemetry.go index 44247cf128f8..aa5c1a5226a3 100644 --- a/processor/processorhelper/internal/metadata/generated_telemetry.go +++ b/processor/processorhelper/internal/metadata/generated_telemetry.go @@ -63,7 +63,7 @@ func NewTelemetryBuilder(settings component.TelemetrySettings, options ...Teleme builder.ProcessorIncomingItems, err = builder.meter.Int64Counter( "otelcol_processor_incoming_items", metric.WithDescription("Number of items passed to the processor. [Alpha]"), - metric.WithUnit("{items}"), + metric.WithUnit("{item}"), ) errs = errors.Join(errs, err) builder.ProcessorInternalDuration, err = builder.meter.Float64Histogram( @@ -75,7 +75,7 @@ func NewTelemetryBuilder(settings component.TelemetrySettings, options ...Teleme builder.ProcessorOutgoingItems, err = builder.meter.Int64Counter( "otelcol_processor_outgoing_items", metric.WithDescription("Number of items emitted from the processor. [Alpha]"), - metric.WithUnit("{items}"), + metric.WithUnit("{item}"), ) errs = errors.Join(errs, err) return &builder, errs diff --git a/processor/processorhelper/internal/metadatatest/generated_telemetrytest.go b/processor/processorhelper/internal/metadatatest/generated_telemetrytest.go index cf5012f4080f..614b93dfe5bf 100644 --- a/processor/processorhelper/internal/metadatatest/generated_telemetrytest.go +++ b/processor/processorhelper/internal/metadatatest/generated_telemetrytest.go @@ -16,7 +16,7 @@ func AssertEqualProcessorIncomingItems(t *testing.T, tt *componenttest.Telemetry want := metricdata.Metrics{ Name: "otelcol_processor_incoming_items", Description: "Number of items passed to the processor. [Alpha]", - Unit: "{items}", + Unit: "{item}", Data: metricdata.Sum[int64]{ Temporality: metricdata.CumulativeTemporality, IsMonotonic: true, @@ -47,7 +47,7 @@ func AssertEqualProcessorOutgoingItems(t *testing.T, tt *componenttest.Telemetry want := metricdata.Metrics{ Name: "otelcol_processor_outgoing_items", Description: "Number of items emitted from the processor. [Alpha]", - Unit: "{items}", + Unit: "{item}", Data: metricdata.Sum[int64]{ Temporality: metricdata.CumulativeTemporality, IsMonotonic: true, diff --git a/processor/processorhelper/logs_test.go b/processor/processorhelper/logs_test.go index 82dbfd666a4e..8ca9f24369af 100644 --- a/processor/processorhelper/logs_test.go +++ b/processor/processorhelper/logs_test.go @@ -93,13 +93,11 @@ func TestLogsConcurrency(t *testing.T) { var wg sync.WaitGroup for range 10 { - wg.Add(1) - go func() { - defer wg.Done() + wg.Go(func() { for range 10000 { assert.NoError(t, lp.ConsumeLogs(context.Background(), incomingLogs)) } - }() + }) } wg.Wait() assert.NoError(t, lp.Shutdown(context.Background())) diff --git a/processor/processorhelper/metadata.yaml b/processor/processorhelper/metadata.yaml index 97b9e594a1cd..cea7dbfcc89d 100644 --- a/processor/processorhelper/metadata.yaml +++ b/processor/processorhelper/metadata.yaml @@ -11,18 +11,16 @@ telemetry: metrics: processor_incoming_items: enabled: true - stability: - level: alpha + stability: alpha description: Number of items passed to the processor. - unit: "{items}" + unit: "{item}" sum: value_type: int monotonic: true processor_internal_duration: enabled: true - stability: - level: alpha + stability: alpha description: Duration of time taken to process a batch of telemetry data through the processor. unit: s histogram: @@ -31,10 +29,9 @@ telemetry: processor_outgoing_items: enabled: true - stability: - level: alpha + stability: alpha description: Number of items emitted from the processor. - unit: "{items}" + unit: "{item}" sum: value_type: int monotonic: true diff --git a/processor/processorhelper/metrics_test.go b/processor/processorhelper/metrics_test.go index 19d018d6291f..2da25a537aea 100644 --- a/processor/processorhelper/metrics_test.go +++ b/processor/processorhelper/metrics_test.go @@ -91,13 +91,11 @@ func TestMetricsConcurrency(t *testing.T) { var wg sync.WaitGroup for range 10 { - wg.Add(1) - go func() { - defer wg.Done() + wg.Go(func() { for range 10000 { assert.NoError(t, mp.ConsumeMetrics(context.Background(), incomingMetrics)) } - }() + }) } wg.Wait() assert.NoError(t, mp.Shutdown(context.Background())) diff --git a/processor/processorhelper/traces_test.go b/processor/processorhelper/traces_test.go index 8ad59e54f2df..6b0f6f8785e4 100644 --- a/processor/processorhelper/traces_test.go +++ b/processor/processorhelper/traces_test.go @@ -93,13 +93,11 @@ func TestTracesConcurrency(t *testing.T) { var wg sync.WaitGroup for range 10 { - wg.Add(1) - go func() { - defer wg.Done() + wg.Go(func() { for range 10000 { assert.NoError(t, mp.ConsumeTraces(context.Background(), incomingTraces)) } - }() + }) } wg.Wait() assert.NoError(t, mp.Shutdown(context.Background())) diff --git a/processor/processorhelper/xprocessorhelper/go.mod b/processor/processorhelper/xprocessorhelper/go.mod index 25f61880f6a0..4b5de6697700 100644 --- a/processor/processorhelper/xprocessorhelper/go.mod +++ b/processor/processorhelper/xprocessorhelper/go.mod @@ -1,19 +1,19 @@ module go.opentelemetry.io/collector/processor/processorhelper/xprocessorhelper -go 1.24.0 +go 1.25.0 require ( github.com/stretchr/testify v1.11.1 - go.opentelemetry.io/collector/component v1.46.0 - go.opentelemetry.io/collector/component/componenttest v0.140.0 - go.opentelemetry.io/collector/consumer v1.46.0 - go.opentelemetry.io/collector/consumer/consumertest v0.140.0 - go.opentelemetry.io/collector/consumer/xconsumer v0.140.0 - go.opentelemetry.io/collector/pdata/pprofile v0.140.0 - go.opentelemetry.io/collector/processor v1.46.0 - go.opentelemetry.io/collector/processor/processorhelper v0.140.0 - go.opentelemetry.io/collector/processor/processortest v0.140.0 - go.opentelemetry.io/collector/processor/xprocessor v0.140.0 + go.opentelemetry.io/collector/component v1.54.0 + go.opentelemetry.io/collector/component/componenttest v0.148.0 + go.opentelemetry.io/collector/consumer v1.54.0 + go.opentelemetry.io/collector/consumer/consumertest v0.148.0 + go.opentelemetry.io/collector/consumer/xconsumer v0.148.0 + go.opentelemetry.io/collector/pdata/pprofile v0.148.0 + go.opentelemetry.io/collector/processor v1.54.0 + go.opentelemetry.io/collector/processor/processorhelper v0.148.0 + go.opentelemetry.io/collector/processor/processortest v0.148.0 + go.opentelemetry.io/collector/processor/xprocessor v0.148.0 ) require ( @@ -22,25 +22,26 @@ require ( github.com/go-logr/logr v1.4.3 // indirect github.com/go-logr/stdr v1.2.2 // indirect github.com/google/uuid v1.6.0 // indirect - github.com/hashicorp/go-version v1.7.0 // indirect + github.com/hashicorp/go-version v1.8.0 // indirect github.com/json-iterator/go v1.1.12 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee // indirect github.com/pmezard/go-difflib v1.0.0 // indirect go.opentelemetry.io/auto/sdk v1.2.1 // indirect - go.opentelemetry.io/collector/component/componentstatus v0.140.0 // indirect - go.opentelemetry.io/collector/featuregate v1.46.0 // indirect - go.opentelemetry.io/collector/pdata v1.46.0 // indirect - go.opentelemetry.io/collector/pdata/testdata v0.140.0 // indirect - go.opentelemetry.io/collector/pipeline v1.46.0 // indirect - go.opentelemetry.io/otel v1.40.0 // indirect - go.opentelemetry.io/otel/metric v1.40.0 // indirect + go.opentelemetry.io/collector/component/componentstatus v0.148.0 // indirect + go.opentelemetry.io/collector/featuregate v1.54.0 // indirect + go.opentelemetry.io/collector/internal/componentalias v0.148.0 // indirect + go.opentelemetry.io/collector/pdata v1.54.0 // indirect + go.opentelemetry.io/collector/pdata/testdata v0.148.0 // indirect + go.opentelemetry.io/collector/pipeline v1.54.0 // indirect + go.opentelemetry.io/otel v1.42.0 // indirect + go.opentelemetry.io/otel/metric v1.42.0 // indirect go.opentelemetry.io/otel/sdk v1.40.0 // indirect go.opentelemetry.io/otel/sdk/metric v1.40.0 // indirect - go.opentelemetry.io/otel/trace v1.40.0 // indirect + go.opentelemetry.io/otel/trace v1.42.0 // indirect go.uber.org/multierr v1.11.0 // indirect go.uber.org/zap v1.27.1 // indirect - golang.org/x/sys v0.40.0 // indirect + golang.org/x/sys v0.41.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) @@ -75,3 +76,5 @@ replace go.opentelemetry.io/collector/processor/xprocessor => ../../xprocessor replace go.opentelemetry.io/collector/featuregate => ../../../featuregate replace go.opentelemetry.io/collector/internal/testutil => ../../../internal/testutil + +replace go.opentelemetry.io/collector/internal/componentalias => ../../../internal/componentalias diff --git a/processor/processorhelper/xprocessorhelper/go.sum b/processor/processorhelper/xprocessorhelper/go.sum index c102571e7869..43bdbeb8d219 100644 --- a/processor/processorhelper/xprocessorhelper/go.sum +++ b/processor/processorhelper/xprocessorhelper/go.sum @@ -13,8 +13,8 @@ github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/hashicorp/go-version v1.7.0 h1:5tqGy27NaOTB8yJKUZELlFAS/LTKJkrmONwQKeRZfjY= -github.com/hashicorp/go-version v1.7.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= +github.com/hashicorp/go-version v1.8.0 h1:KAkNb1HAiZd1ukkxDFGmokVZe1Xy9HG6NUp+bPle2i4= +github.com/hashicorp/go-version v1.8.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= @@ -37,32 +37,32 @@ github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64= go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y= -go.opentelemetry.io/otel v1.40.0 h1:oA5YeOcpRTXq6NN7frwmwFR0Cn3RhTVZvXsP4duvCms= -go.opentelemetry.io/otel v1.40.0/go.mod h1:IMb+uXZUKkMXdPddhwAHm6UfOwJyh4ct1ybIlV14J0g= -go.opentelemetry.io/otel/metric v1.40.0 h1:rcZe317KPftE2rstWIBitCdVp89A2HqjkxR3c11+p9g= -go.opentelemetry.io/otel/metric v1.40.0/go.mod h1:ib/crwQH7N3r5kfiBZQbwrTge743UDc7DTFVZrrXnqc= +go.opentelemetry.io/otel v1.42.0 h1:lSQGzTgVR3+sgJDAU/7/ZMjN9Z+vUip7leaqBKy4sho= +go.opentelemetry.io/otel v1.42.0/go.mod h1:lJNsdRMxCUIWuMlVJWzecSMuNjE7dOYyWlqOXWkdqCc= +go.opentelemetry.io/otel/metric v1.42.0 h1:2jXG+3oZLNXEPfNmnpxKDeZsFI5o4J+nz6xUlaFdF/4= +go.opentelemetry.io/otel/metric v1.42.0/go.mod h1:RlUN/7vTU7Ao/diDkEpQpnz3/92J9ko05BIwxYa2SSI= go.opentelemetry.io/otel/sdk v1.40.0 h1:KHW/jUzgo6wsPh9At46+h4upjtccTmuZCFAc9OJ71f8= go.opentelemetry.io/otel/sdk v1.40.0/go.mod h1:Ph7EFdYvxq72Y8Li9q8KebuYUr2KoeyHx0DRMKrYBUE= go.opentelemetry.io/otel/sdk/metric v1.40.0 h1:mtmdVqgQkeRxHgRv4qhyJduP3fYJRMX4AtAlbuWdCYw= go.opentelemetry.io/otel/sdk/metric v1.40.0/go.mod h1:4Z2bGMf0KSK3uRjlczMOeMhKU2rhUqdWNoKcYrtcBPg= -go.opentelemetry.io/otel/trace v1.40.0 h1:WA4etStDttCSYuhwvEa8OP8I5EWu24lkOzp+ZYblVjw= -go.opentelemetry.io/otel/trace v1.40.0/go.mod h1:zeAhriXecNGP/s2SEG3+Y8X9ujcJOTqQ5RgdEJcawiA= -go.opentelemetry.io/proto/slim/otlp v1.9.0 h1:fPVMv8tP3TrsqlkH1HWYUpbCY9cAIemx184VGkS6vlE= -go.opentelemetry.io/proto/slim/otlp v1.9.0/go.mod h1:xXdeJJ90Gqyll+orzUkY4bOd2HECo5JofeoLpymVqdI= -go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.2.0 h1:o13nadWDNkH/quoDomDUClnQBpdQQ2Qqv0lQBjIXjE8= -go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.2.0/go.mod h1:Gyb6Xe7FTi/6xBHwMmngGoHqL0w29Y4eW8TGFzpefGA= -go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.2.0 h1:EiUYvtwu6PMrMHVjcPfnsG3v+ajPkbUeH+IL93+QYyk= -go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.2.0/go.mod h1:mUUHKFiN2SST3AhJ8XhJxEoeVW12oqfXog0Bo8W3Ec4= +go.opentelemetry.io/otel/trace v1.42.0 h1:OUCgIPt+mzOnaUTpOQcBiM/PLQ/Op7oq6g4LenLmOYY= +go.opentelemetry.io/otel/trace v1.42.0/go.mod h1:f3K9S+IFqnumBkKhRJMeaZeNk9epyhnCmQh/EysQCdc= +go.opentelemetry.io/proto/slim/otlp v1.10.0 h1:iR97Vs/ZDR+y9TfuP9b1XBtdPWeC+OMslIBmhcLU7jM= +go.opentelemetry.io/proto/slim/otlp v1.10.0/go.mod h1:lV9250stpjYLPNA5viFabIgP2QlUGRT1GdTgAf8SIUk= +go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.3.0 h1:RUF5rO0hAlgiJt1fzQVzcVs3vZVNHIcMLgOgG4rWNcQ= +go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.3.0/go.mod h1:I89cynRj8y+383o7tEQVg2SVA6SRgDVIouWPUVXjx0U= +go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.3.0 h1:CQvJSldHRUN6Z8jsUeYv8J0lXRvygALXIzsmAeCcZE0= +go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.3.0/go.mod h1:xSQ+mEfJe/GjK1LXEyVOoSI1N9JV9ZI923X5kup43W4= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= go.uber.org/zap v1.27.1 h1:08RqriUEv8+ArZRYSTXy1LeBScaMpVSTBhCeaZYfMYc= go.uber.org/zap v1.27.1/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= -golang.org/x/sys v0.40.0 h1:DBZZqJ2Rkml6QMQsZywtnjnnGvHza6BTfYFWY9kjEWQ= -golang.org/x/sys v0.40.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= -google.golang.org/protobuf v1.36.10 h1:AYd7cD/uASjIL6Q9LiTjz8JLcrh/88q5UObnmY3aOOE= -google.golang.org/protobuf v1.36.10/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= +golang.org/x/sys v0.41.0 h1:Ivj+2Cp/ylzLiEU89QhWblYnOE9zerudt9Ftecq2C6k= +golang.org/x/sys v0.41.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= +google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE= +google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= diff --git a/processor/processorhelper/xprocessorhelper/metadata.yaml b/processor/processorhelper/xprocessorhelper/metadata.yaml new file mode 100644 index 000000000000..aead10fa9f78 --- /dev/null +++ b/processor/processorhelper/xprocessorhelper/metadata.yaml @@ -0,0 +1,6 @@ +type: xprocessorhelper +github_project: open-telemetry/opentelemetry-collector + +status: + disable_codecov_badge: true + class: pkg diff --git a/processor/processorhelper/xprocessorhelper/profiles_test.go b/processor/processorhelper/xprocessorhelper/profiles_test.go index c4cc53b8a7f2..d30a018d4395 100644 --- a/processor/processorhelper/xprocessorhelper/profiles_test.go +++ b/processor/processorhelper/xprocessorhelper/profiles_test.go @@ -89,13 +89,11 @@ func TestProfilesConcurrency(t *testing.T) { var wg sync.WaitGroup for range 10 { - wg.Add(1) - go func() { - defer wg.Done() + wg.Go(func() { for range 10000 { assert.NoError(t, pp.ConsumeProfiles(context.Background(), incomingProfiles)) } - }() + }) } wg.Wait() assert.NoError(t, pp.Shutdown(context.Background())) diff --git a/processor/processortest/go.mod b/processor/processortest/go.mod index ef43b6c0d6b7..4e1b59c9ab1a 100644 --- a/processor/processortest/go.mod +++ b/processor/processortest/go.mod @@ -1,21 +1,21 @@ module go.opentelemetry.io/collector/processor/processortest -go 1.24.0 +go 1.25.0 require ( github.com/stretchr/testify v1.11.1 - go.opentelemetry.io/collector/component v1.46.0 - go.opentelemetry.io/collector/component/componentstatus v0.140.0 - go.opentelemetry.io/collector/component/componenttest v0.140.0 - go.opentelemetry.io/collector/consumer v1.46.0 - go.opentelemetry.io/collector/consumer/consumertest v0.140.0 - go.opentelemetry.io/collector/consumer/xconsumer v0.140.0 - go.opentelemetry.io/collector/pdata v1.46.0 - go.opentelemetry.io/collector/pdata/pprofile v0.140.0 - go.opentelemetry.io/collector/pdata/testdata v0.140.0 - go.opentelemetry.io/collector/pipeline v1.46.0 - go.opentelemetry.io/collector/processor v1.46.0 - go.opentelemetry.io/collector/processor/xprocessor v0.140.0 + go.opentelemetry.io/collector/component v1.54.0 + go.opentelemetry.io/collector/component/componentstatus v0.148.0 + go.opentelemetry.io/collector/component/componenttest v0.148.0 + go.opentelemetry.io/collector/consumer v1.54.0 + go.opentelemetry.io/collector/consumer/consumertest v0.148.0 + go.opentelemetry.io/collector/consumer/xconsumer v0.148.0 + go.opentelemetry.io/collector/pdata v1.54.0 + go.opentelemetry.io/collector/pdata/pprofile v0.148.0 + go.opentelemetry.io/collector/pdata/testdata v0.148.0 + go.opentelemetry.io/collector/pipeline v1.54.0 + go.opentelemetry.io/collector/processor v1.54.0 + go.opentelemetry.io/collector/processor/xprocessor v0.148.0 go.uber.org/goleak v1.3.0 ) @@ -25,21 +25,22 @@ require ( github.com/go-logr/logr v1.4.3 // indirect github.com/go-logr/stdr v1.2.2 // indirect github.com/google/uuid v1.6.0 // indirect - github.com/hashicorp/go-version v1.7.0 // indirect + github.com/hashicorp/go-version v1.8.0 // indirect github.com/json-iterator/go v1.1.12 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee // indirect github.com/pmezard/go-difflib v1.0.0 // indirect go.opentelemetry.io/auto/sdk v1.2.1 // indirect - go.opentelemetry.io/collector/featuregate v1.46.0 // indirect - go.opentelemetry.io/otel v1.40.0 // indirect - go.opentelemetry.io/otel/metric v1.40.0 // indirect + go.opentelemetry.io/collector/featuregate v1.54.0 // indirect + go.opentelemetry.io/collector/internal/componentalias v0.148.0 // indirect + go.opentelemetry.io/otel v1.42.0 // indirect + go.opentelemetry.io/otel/metric v1.42.0 // indirect go.opentelemetry.io/otel/sdk v1.40.0 // indirect go.opentelemetry.io/otel/sdk/metric v1.40.0 // indirect - go.opentelemetry.io/otel/trace v1.40.0 // indirect + go.opentelemetry.io/otel/trace v1.42.0 // indirect go.uber.org/multierr v1.11.0 // indirect go.uber.org/zap v1.27.1 // indirect - golang.org/x/sys v0.40.0 // indirect + golang.org/x/sys v0.41.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) @@ -70,3 +71,5 @@ replace go.opentelemetry.io/collector/pipeline => ../../pipeline replace go.opentelemetry.io/collector/featuregate => ../../featuregate replace go.opentelemetry.io/collector/internal/testutil => ../../internal/testutil + +replace go.opentelemetry.io/collector/internal/componentalias => ../../internal/componentalias diff --git a/processor/processortest/go.sum b/processor/processortest/go.sum index c102571e7869..43bdbeb8d219 100644 --- a/processor/processortest/go.sum +++ b/processor/processortest/go.sum @@ -13,8 +13,8 @@ github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/hashicorp/go-version v1.7.0 h1:5tqGy27NaOTB8yJKUZELlFAS/LTKJkrmONwQKeRZfjY= -github.com/hashicorp/go-version v1.7.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= +github.com/hashicorp/go-version v1.8.0 h1:KAkNb1HAiZd1ukkxDFGmokVZe1Xy9HG6NUp+bPle2i4= +github.com/hashicorp/go-version v1.8.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= @@ -37,32 +37,32 @@ github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64= go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y= -go.opentelemetry.io/otel v1.40.0 h1:oA5YeOcpRTXq6NN7frwmwFR0Cn3RhTVZvXsP4duvCms= -go.opentelemetry.io/otel v1.40.0/go.mod h1:IMb+uXZUKkMXdPddhwAHm6UfOwJyh4ct1ybIlV14J0g= -go.opentelemetry.io/otel/metric v1.40.0 h1:rcZe317KPftE2rstWIBitCdVp89A2HqjkxR3c11+p9g= -go.opentelemetry.io/otel/metric v1.40.0/go.mod h1:ib/crwQH7N3r5kfiBZQbwrTge743UDc7DTFVZrrXnqc= +go.opentelemetry.io/otel v1.42.0 h1:lSQGzTgVR3+sgJDAU/7/ZMjN9Z+vUip7leaqBKy4sho= +go.opentelemetry.io/otel v1.42.0/go.mod h1:lJNsdRMxCUIWuMlVJWzecSMuNjE7dOYyWlqOXWkdqCc= +go.opentelemetry.io/otel/metric v1.42.0 h1:2jXG+3oZLNXEPfNmnpxKDeZsFI5o4J+nz6xUlaFdF/4= +go.opentelemetry.io/otel/metric v1.42.0/go.mod h1:RlUN/7vTU7Ao/diDkEpQpnz3/92J9ko05BIwxYa2SSI= go.opentelemetry.io/otel/sdk v1.40.0 h1:KHW/jUzgo6wsPh9At46+h4upjtccTmuZCFAc9OJ71f8= go.opentelemetry.io/otel/sdk v1.40.0/go.mod h1:Ph7EFdYvxq72Y8Li9q8KebuYUr2KoeyHx0DRMKrYBUE= go.opentelemetry.io/otel/sdk/metric v1.40.0 h1:mtmdVqgQkeRxHgRv4qhyJduP3fYJRMX4AtAlbuWdCYw= go.opentelemetry.io/otel/sdk/metric v1.40.0/go.mod h1:4Z2bGMf0KSK3uRjlczMOeMhKU2rhUqdWNoKcYrtcBPg= -go.opentelemetry.io/otel/trace v1.40.0 h1:WA4etStDttCSYuhwvEa8OP8I5EWu24lkOzp+ZYblVjw= -go.opentelemetry.io/otel/trace v1.40.0/go.mod h1:zeAhriXecNGP/s2SEG3+Y8X9ujcJOTqQ5RgdEJcawiA= -go.opentelemetry.io/proto/slim/otlp v1.9.0 h1:fPVMv8tP3TrsqlkH1HWYUpbCY9cAIemx184VGkS6vlE= -go.opentelemetry.io/proto/slim/otlp v1.9.0/go.mod h1:xXdeJJ90Gqyll+orzUkY4bOd2HECo5JofeoLpymVqdI= -go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.2.0 h1:o13nadWDNkH/quoDomDUClnQBpdQQ2Qqv0lQBjIXjE8= -go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.2.0/go.mod h1:Gyb6Xe7FTi/6xBHwMmngGoHqL0w29Y4eW8TGFzpefGA= -go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.2.0 h1:EiUYvtwu6PMrMHVjcPfnsG3v+ajPkbUeH+IL93+QYyk= -go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.2.0/go.mod h1:mUUHKFiN2SST3AhJ8XhJxEoeVW12oqfXog0Bo8W3Ec4= +go.opentelemetry.io/otel/trace v1.42.0 h1:OUCgIPt+mzOnaUTpOQcBiM/PLQ/Op7oq6g4LenLmOYY= +go.opentelemetry.io/otel/trace v1.42.0/go.mod h1:f3K9S+IFqnumBkKhRJMeaZeNk9epyhnCmQh/EysQCdc= +go.opentelemetry.io/proto/slim/otlp v1.10.0 h1:iR97Vs/ZDR+y9TfuP9b1XBtdPWeC+OMslIBmhcLU7jM= +go.opentelemetry.io/proto/slim/otlp v1.10.0/go.mod h1:lV9250stpjYLPNA5viFabIgP2QlUGRT1GdTgAf8SIUk= +go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.3.0 h1:RUF5rO0hAlgiJt1fzQVzcVs3vZVNHIcMLgOgG4rWNcQ= +go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.3.0/go.mod h1:I89cynRj8y+383o7tEQVg2SVA6SRgDVIouWPUVXjx0U= +go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.3.0 h1:CQvJSldHRUN6Z8jsUeYv8J0lXRvygALXIzsmAeCcZE0= +go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.3.0/go.mod h1:xSQ+mEfJe/GjK1LXEyVOoSI1N9JV9ZI923X5kup43W4= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= go.uber.org/zap v1.27.1 h1:08RqriUEv8+ArZRYSTXy1LeBScaMpVSTBhCeaZYfMYc= go.uber.org/zap v1.27.1/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= -golang.org/x/sys v0.40.0 h1:DBZZqJ2Rkml6QMQsZywtnjnnGvHza6BTfYFWY9kjEWQ= -golang.org/x/sys v0.40.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= -google.golang.org/protobuf v1.36.10 h1:AYd7cD/uASjIL6Q9LiTjz8JLcrh/88q5UObnmY3aOOE= -google.golang.org/protobuf v1.36.10/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= +golang.org/x/sys v0.41.0 h1:Ivj+2Cp/ylzLiEU89QhWblYnOE9zerudt9Ftecq2C6k= +golang.org/x/sys v0.41.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= +google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE= +google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= diff --git a/processor/processortest/metadata.yaml b/processor/processortest/metadata.yaml new file mode 100644 index 000000000000..9cc11e704aee --- /dev/null +++ b/processor/processortest/metadata.yaml @@ -0,0 +1,6 @@ +type: processor/processortest +github_project: open-telemetry/opentelemetry-collector + +status: + disable_codecov_badge: true + class: pkg diff --git a/processor/xprocessor/go.mod b/processor/xprocessor/go.mod index 7a1bb20346d8..3d6f1fc8fffe 100644 --- a/processor/xprocessor/go.mod +++ b/processor/xprocessor/go.mod @@ -1,31 +1,32 @@ module go.opentelemetry.io/collector/processor/xprocessor -go 1.24.0 +go 1.25.0 require ( github.com/stretchr/testify v1.11.1 - go.opentelemetry.io/collector/component v1.46.0 - go.opentelemetry.io/collector/consumer/consumertest v0.140.0 - go.opentelemetry.io/collector/consumer/xconsumer v0.140.0 - go.opentelemetry.io/collector/pipeline v1.46.0 - go.opentelemetry.io/collector/processor v1.46.0 + go.opentelemetry.io/collector/component v1.54.0 + go.opentelemetry.io/collector/consumer/consumertest v0.148.0 + go.opentelemetry.io/collector/consumer/xconsumer v0.148.0 + go.opentelemetry.io/collector/internal/componentalias v0.148.0 + go.opentelemetry.io/collector/pipeline v1.54.0 + go.opentelemetry.io/collector/processor v1.54.0 ) require ( github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/davecgh/go-spew v1.1.1 // indirect - github.com/hashicorp/go-version v1.7.0 // indirect + github.com/hashicorp/go-version v1.8.0 // indirect github.com/json-iterator/go v1.1.12 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee // indirect github.com/pmezard/go-difflib v1.0.0 // indirect - go.opentelemetry.io/collector/consumer v1.46.0 // indirect - go.opentelemetry.io/collector/featuregate v1.46.0 // indirect - go.opentelemetry.io/collector/pdata v1.46.0 // indirect - go.opentelemetry.io/collector/pdata/pprofile v0.140.0 // indirect - go.opentelemetry.io/otel v1.40.0 // indirect - go.opentelemetry.io/otel/metric v1.40.0 // indirect - go.opentelemetry.io/otel/trace v1.40.0 // indirect + go.opentelemetry.io/collector/consumer v1.54.0 // indirect + go.opentelemetry.io/collector/featuregate v1.54.0 // indirect + go.opentelemetry.io/collector/pdata v1.54.0 // indirect + go.opentelemetry.io/collector/pdata/pprofile v0.148.0 // indirect + go.opentelemetry.io/otel v1.42.0 // indirect + go.opentelemetry.io/otel/metric v1.42.0 // indirect + go.opentelemetry.io/otel/trace v1.42.0 // indirect go.uber.org/multierr v1.11.0 // indirect go.uber.org/zap v1.27.1 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect @@ -52,3 +53,5 @@ replace go.opentelemetry.io/collector/pipeline => ../../pipeline replace go.opentelemetry.io/collector/featuregate => ../../featuregate replace go.opentelemetry.io/collector/internal/testutil => ../../internal/testutil + +replace go.opentelemetry.io/collector/internal/componentalias => ../../internal/componentalias diff --git a/processor/xprocessor/go.sum b/processor/xprocessor/go.sum index 37d6edbc3764..1abfd0c69894 100644 --- a/processor/xprocessor/go.sum +++ b/processor/xprocessor/go.sum @@ -10,8 +10,8 @@ github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= -github.com/hashicorp/go-version v1.7.0 h1:5tqGy27NaOTB8yJKUZELlFAS/LTKJkrmONwQKeRZfjY= -github.com/hashicorp/go-version v1.7.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= +github.com/hashicorp/go-version v1.8.0 h1:KAkNb1HAiZd1ukkxDFGmokVZe1Xy9HG6NUp+bPle2i4= +github.com/hashicorp/go-version v1.8.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= @@ -34,26 +34,26 @@ github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64= go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y= -go.opentelemetry.io/otel v1.40.0 h1:oA5YeOcpRTXq6NN7frwmwFR0Cn3RhTVZvXsP4duvCms= -go.opentelemetry.io/otel v1.40.0/go.mod h1:IMb+uXZUKkMXdPddhwAHm6UfOwJyh4ct1ybIlV14J0g= -go.opentelemetry.io/otel/metric v1.40.0 h1:rcZe317KPftE2rstWIBitCdVp89A2HqjkxR3c11+p9g= -go.opentelemetry.io/otel/metric v1.40.0/go.mod h1:ib/crwQH7N3r5kfiBZQbwrTge743UDc7DTFVZrrXnqc= -go.opentelemetry.io/otel/trace v1.40.0 h1:WA4etStDttCSYuhwvEa8OP8I5EWu24lkOzp+ZYblVjw= -go.opentelemetry.io/otel/trace v1.40.0/go.mod h1:zeAhriXecNGP/s2SEG3+Y8X9ujcJOTqQ5RgdEJcawiA= -go.opentelemetry.io/proto/slim/otlp v1.9.0 h1:fPVMv8tP3TrsqlkH1HWYUpbCY9cAIemx184VGkS6vlE= -go.opentelemetry.io/proto/slim/otlp v1.9.0/go.mod h1:xXdeJJ90Gqyll+orzUkY4bOd2HECo5JofeoLpymVqdI= -go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.2.0 h1:o13nadWDNkH/quoDomDUClnQBpdQQ2Qqv0lQBjIXjE8= -go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.2.0/go.mod h1:Gyb6Xe7FTi/6xBHwMmngGoHqL0w29Y4eW8TGFzpefGA= -go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.2.0 h1:EiUYvtwu6PMrMHVjcPfnsG3v+ajPkbUeH+IL93+QYyk= -go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.2.0/go.mod h1:mUUHKFiN2SST3AhJ8XhJxEoeVW12oqfXog0Bo8W3Ec4= +go.opentelemetry.io/otel v1.42.0 h1:lSQGzTgVR3+sgJDAU/7/ZMjN9Z+vUip7leaqBKy4sho= +go.opentelemetry.io/otel v1.42.0/go.mod h1:lJNsdRMxCUIWuMlVJWzecSMuNjE7dOYyWlqOXWkdqCc= +go.opentelemetry.io/otel/metric v1.42.0 h1:2jXG+3oZLNXEPfNmnpxKDeZsFI5o4J+nz6xUlaFdF/4= +go.opentelemetry.io/otel/metric v1.42.0/go.mod h1:RlUN/7vTU7Ao/diDkEpQpnz3/92J9ko05BIwxYa2SSI= +go.opentelemetry.io/otel/trace v1.42.0 h1:OUCgIPt+mzOnaUTpOQcBiM/PLQ/Op7oq6g4LenLmOYY= +go.opentelemetry.io/otel/trace v1.42.0/go.mod h1:f3K9S+IFqnumBkKhRJMeaZeNk9epyhnCmQh/EysQCdc= +go.opentelemetry.io/proto/slim/otlp v1.10.0 h1:iR97Vs/ZDR+y9TfuP9b1XBtdPWeC+OMslIBmhcLU7jM= +go.opentelemetry.io/proto/slim/otlp v1.10.0/go.mod h1:lV9250stpjYLPNA5viFabIgP2QlUGRT1GdTgAf8SIUk= +go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.3.0 h1:RUF5rO0hAlgiJt1fzQVzcVs3vZVNHIcMLgOgG4rWNcQ= +go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.3.0/go.mod h1:I89cynRj8y+383o7tEQVg2SVA6SRgDVIouWPUVXjx0U= +go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.3.0 h1:CQvJSldHRUN6Z8jsUeYv8J0lXRvygALXIzsmAeCcZE0= +go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.3.0/go.mod h1:xSQ+mEfJe/GjK1LXEyVOoSI1N9JV9ZI923X5kup43W4= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= go.uber.org/zap v1.27.1 h1:08RqriUEv8+ArZRYSTXy1LeBScaMpVSTBhCeaZYfMYc= go.uber.org/zap v1.27.1/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= -google.golang.org/protobuf v1.36.10 h1:AYd7cD/uASjIL6Q9LiTjz8JLcrh/88q5UObnmY3aOOE= -google.golang.org/protobuf v1.36.10/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= +google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE= +google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= diff --git a/processor/xprocessor/processor.go b/processor/xprocessor/processor.go index b91c44b98894..b2a6e86cd068 100644 --- a/processor/xprocessor/processor.go +++ b/processor/xprocessor/processor.go @@ -8,9 +8,9 @@ import ( "go.opentelemetry.io/collector/component" "go.opentelemetry.io/collector/consumer/xconsumer" + "go.opentelemetry.io/collector/internal/componentalias" "go.opentelemetry.io/collector/pipeline" "go.opentelemetry.io/collector/processor" - "go.opentelemetry.io/collector/processor/internal" ) // Factory is a component.Factory interface for processors. @@ -42,76 +42,82 @@ type CreateProfilesFunc func(context.Context, processor.Settings, component.Conf // FactoryOption apply changes to ReceiverOptions. type FactoryOption interface { // applyOption applies the option. - applyOption(o *factoryOpts) + applyOption(o *factory) } // factoryOptionFunc is an ReceiverFactoryOption created through a function. -type factoryOptionFunc func(*factoryOpts) +type factoryOptionFunc func(*factory) -func (f factoryOptionFunc) applyOption(o *factoryOpts) { +func (f factoryOptionFunc) applyOption(o *factory) { f(o) } type factory struct { processor.Factory + componentalias.TypeAliasHolder + opts []processor.FactoryOption createProfilesFunc CreateProfilesFunc profilesStabilityLevel component.StabilityLevel } -func (f factory) ProfilesStability() component.StabilityLevel { +func (f *factory) ProfilesStability() component.StabilityLevel { return f.profilesStabilityLevel } -func (f factory) CreateProfiles(ctx context.Context, set processor.Settings, cfg component.Config, next xconsumer.Profiles) (Profiles, error) { +func (f *factory) CreateProfiles(ctx context.Context, set processor.Settings, cfg component.Config, next xconsumer.Profiles) (Profiles, error) { if f.createProfilesFunc == nil { return nil, pipeline.ErrSignalNotSupported } - if set.ID.Type() != f.Type() { - return nil, internal.ErrIDMismatch(set.ID, f.Type()) + if err := componentalias.ValidateComponentType(f.Factory, set.ID); err != nil { + return nil, err } return f.createProfilesFunc(ctx, set, cfg, next) } -type factoryOpts struct { - opts []processor.FactoryOption - *factory -} - // WithTraces overrides the default "error not supported" implementation for CreateTraces and the default "undefined" stability level. func WithTraces(createTraces processor.CreateTracesFunc, sl component.StabilityLevel) FactoryOption { - return factoryOptionFunc(func(o *factoryOpts) { + return factoryOptionFunc(func(o *factory) { o.opts = append(o.opts, processor.WithTraces(createTraces, sl)) }) } // WithMetrics overrides the default "error not supported" implementation for CreateMetrics and the default "undefined" stability level. func WithMetrics(createMetrics processor.CreateMetricsFunc, sl component.StabilityLevel) FactoryOption { - return factoryOptionFunc(func(o *factoryOpts) { + return factoryOptionFunc(func(o *factory) { o.opts = append(o.opts, processor.WithMetrics(createMetrics, sl)) }) } // WithLogs overrides the default "error not supported" implementation for CreateLogs and the default "undefined" stability level. func WithLogs(createLogs processor.CreateLogsFunc, sl component.StabilityLevel) FactoryOption { - return factoryOptionFunc(func(o *factoryOpts) { + return factoryOptionFunc(func(o *factory) { o.opts = append(o.opts, processor.WithLogs(createLogs, sl)) }) } // WithProfiles overrides the default "error not supported" implementation for CreateProfiles and the default "undefined" stability level. func WithProfiles(createProfiles CreateProfilesFunc, sl component.StabilityLevel) FactoryOption { - return factoryOptionFunc(func(o *factoryOpts) { + return factoryOptionFunc(func(o *factory) { o.profilesStabilityLevel = sl o.createProfilesFunc = createProfiles }) } -// NewFactory returns a Factory. +// WithDeprecatedTypeAlias configures a deprecated type alias for the processor. Only one alias is supported per processor. +// When the alias is used in configuration, a deprecation warning is automatically logged. +func WithDeprecatedTypeAlias(alias component.Type) FactoryOption { + return factoryOptionFunc(func(o *factory) { + o.SetDeprecatedAlias(alias) + }) +} + +// NewFactory creates a wrapped processor.Factory with experimental capabilities. func NewFactory(cfgType component.Type, createDefaultConfig component.CreateDefaultConfigFunc, options ...FactoryOption) Factory { - opts := factoryOpts{factory: &factory{}} + f := &factory{TypeAliasHolder: componentalias.NewTypeAliasHolder()} for _, opt := range options { - opt.applyOption(&opts) + opt.applyOption(f) } - opts.Factory = processor.NewFactory(cfgType, createDefaultConfig, opts.opts...) - return opts.factory + f.Factory = processor.NewFactory(cfgType, createDefaultConfig, f.opts...) + f.Factory.(componentalias.TypeAliasHolder).SetDeprecatedAlias(f.DeprecatedAlias()) + return f } diff --git a/processor/xprocessor/processor_test.go b/processor/xprocessor/processor_test.go index 215464eba61e..51bdc68f7e57 100644 --- a/processor/xprocessor/processor_test.go +++ b/processor/xprocessor/processor_test.go @@ -13,6 +13,7 @@ import ( "go.opentelemetry.io/collector/component" "go.opentelemetry.io/collector/consumer/consumertest" "go.opentelemetry.io/collector/consumer/xconsumer" + "go.opentelemetry.io/collector/internal/componentalias" "go.opentelemetry.io/collector/processor" "go.opentelemetry.io/collector/processor/internal" ) @@ -54,3 +55,27 @@ type nopProcessor struct { func createProfiles(context.Context, processor.Settings, component.Config, xconsumer.Profiles) (Profiles, error) { return nopInstance, nil } + +func TestNewFactoryWithDeprecatedAlias(t *testing.T) { + testType := component.MustNewType("newname") + aliasType := component.MustNewType("oldname") + defaultCfg := struct{}{} + + f := NewFactory( + testType, + func() component.Config { return &defaultCfg }, + WithProfiles(createProfiles, component.StabilityLevelAlpha), + WithDeprecatedTypeAlias(aliasType), + ) + + assert.Equal(t, testType, f.Type()) + assert.Equal(t, aliasType, f.(*factory).Factory.(componentalias.TypeAliasHolder).DeprecatedAlias()) + assert.EqualValues(t, &defaultCfg, f.CreateDefaultConfig()) + + _, err := f.CreateProfiles(context.Background(), processor.Settings{ID: component.MustNewID("newname")}, &defaultCfg, consumertest.NewNop()) + require.NoError(t, err) + _, err = f.CreateProfiles(context.Background(), processor.Settings{ID: component.MustNewID("oldname")}, &defaultCfg, consumertest.NewNop()) + require.NoError(t, err) + _, err = f.CreateProfiles(context.Background(), processor.Settings{ID: component.MustNewID("wrongname")}, &defaultCfg, consumertest.NewNop()) + require.Error(t, err) +} diff --git a/receiver/go.mod b/receiver/go.mod index f109a8020331..aba586c61306 100644 --- a/receiver/go.mod +++ b/receiver/go.mod @@ -1,31 +1,32 @@ module go.opentelemetry.io/collector/receiver -go 1.24.0 +go 1.25.0 require ( github.com/stretchr/testify v1.11.1 - go.opentelemetry.io/collector/component v1.46.0 - go.opentelemetry.io/collector/consumer v1.46.0 - go.opentelemetry.io/collector/consumer/consumertest v0.140.0 - go.opentelemetry.io/collector/pdata v1.46.0 - go.opentelemetry.io/collector/pipeline v1.46.0 + go.opentelemetry.io/collector/component v1.54.0 + go.opentelemetry.io/collector/consumer v1.54.0 + go.opentelemetry.io/collector/consumer/consumertest v0.148.0 + go.opentelemetry.io/collector/internal/componentalias v0.148.0 + go.opentelemetry.io/collector/pdata v1.54.0 + go.opentelemetry.io/collector/pipeline v1.54.0 go.uber.org/goleak v1.3.0 ) require ( github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/davecgh/go-spew v1.1.1 // indirect - github.com/hashicorp/go-version v1.7.0 // indirect + github.com/hashicorp/go-version v1.8.0 // indirect github.com/json-iterator/go v1.1.12 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee // indirect github.com/pmezard/go-difflib v1.0.0 // indirect - go.opentelemetry.io/collector/consumer/xconsumer v0.140.0 // indirect - go.opentelemetry.io/collector/featuregate v1.46.0 // indirect - go.opentelemetry.io/collector/pdata/pprofile v0.140.0 // indirect - go.opentelemetry.io/otel v1.40.0 // indirect - go.opentelemetry.io/otel/metric v1.40.0 // indirect - go.opentelemetry.io/otel/trace v1.40.0 // indirect + go.opentelemetry.io/collector/consumer/xconsumer v0.148.0 // indirect + go.opentelemetry.io/collector/featuregate v1.54.0 // indirect + go.opentelemetry.io/collector/pdata/pprofile v0.148.0 // indirect + go.opentelemetry.io/otel v1.42.0 // indirect + go.opentelemetry.io/otel/metric v1.42.0 // indirect + go.opentelemetry.io/otel/trace v1.42.0 // indirect go.uber.org/multierr v1.11.0 // indirect go.uber.org/zap v1.27.1 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect @@ -52,3 +53,5 @@ replace go.opentelemetry.io/collector/pipeline => ../pipeline replace go.opentelemetry.io/collector/featuregate => ../featuregate replace go.opentelemetry.io/collector/internal/testutil => ../internal/testutil + +replace go.opentelemetry.io/collector/internal/componentalias => ../internal/componentalias diff --git a/receiver/go.sum b/receiver/go.sum index 37d6edbc3764..1abfd0c69894 100644 --- a/receiver/go.sum +++ b/receiver/go.sum @@ -10,8 +10,8 @@ github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= -github.com/hashicorp/go-version v1.7.0 h1:5tqGy27NaOTB8yJKUZELlFAS/LTKJkrmONwQKeRZfjY= -github.com/hashicorp/go-version v1.7.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= +github.com/hashicorp/go-version v1.8.0 h1:KAkNb1HAiZd1ukkxDFGmokVZe1Xy9HG6NUp+bPle2i4= +github.com/hashicorp/go-version v1.8.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= @@ -34,26 +34,26 @@ github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64= go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y= -go.opentelemetry.io/otel v1.40.0 h1:oA5YeOcpRTXq6NN7frwmwFR0Cn3RhTVZvXsP4duvCms= -go.opentelemetry.io/otel v1.40.0/go.mod h1:IMb+uXZUKkMXdPddhwAHm6UfOwJyh4ct1ybIlV14J0g= -go.opentelemetry.io/otel/metric v1.40.0 h1:rcZe317KPftE2rstWIBitCdVp89A2HqjkxR3c11+p9g= -go.opentelemetry.io/otel/metric v1.40.0/go.mod h1:ib/crwQH7N3r5kfiBZQbwrTge743UDc7DTFVZrrXnqc= -go.opentelemetry.io/otel/trace v1.40.0 h1:WA4etStDttCSYuhwvEa8OP8I5EWu24lkOzp+ZYblVjw= -go.opentelemetry.io/otel/trace v1.40.0/go.mod h1:zeAhriXecNGP/s2SEG3+Y8X9ujcJOTqQ5RgdEJcawiA= -go.opentelemetry.io/proto/slim/otlp v1.9.0 h1:fPVMv8tP3TrsqlkH1HWYUpbCY9cAIemx184VGkS6vlE= -go.opentelemetry.io/proto/slim/otlp v1.9.0/go.mod h1:xXdeJJ90Gqyll+orzUkY4bOd2HECo5JofeoLpymVqdI= -go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.2.0 h1:o13nadWDNkH/quoDomDUClnQBpdQQ2Qqv0lQBjIXjE8= -go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.2.0/go.mod h1:Gyb6Xe7FTi/6xBHwMmngGoHqL0w29Y4eW8TGFzpefGA= -go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.2.0 h1:EiUYvtwu6PMrMHVjcPfnsG3v+ajPkbUeH+IL93+QYyk= -go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.2.0/go.mod h1:mUUHKFiN2SST3AhJ8XhJxEoeVW12oqfXog0Bo8W3Ec4= +go.opentelemetry.io/otel v1.42.0 h1:lSQGzTgVR3+sgJDAU/7/ZMjN9Z+vUip7leaqBKy4sho= +go.opentelemetry.io/otel v1.42.0/go.mod h1:lJNsdRMxCUIWuMlVJWzecSMuNjE7dOYyWlqOXWkdqCc= +go.opentelemetry.io/otel/metric v1.42.0 h1:2jXG+3oZLNXEPfNmnpxKDeZsFI5o4J+nz6xUlaFdF/4= +go.opentelemetry.io/otel/metric v1.42.0/go.mod h1:RlUN/7vTU7Ao/diDkEpQpnz3/92J9ko05BIwxYa2SSI= +go.opentelemetry.io/otel/trace v1.42.0 h1:OUCgIPt+mzOnaUTpOQcBiM/PLQ/Op7oq6g4LenLmOYY= +go.opentelemetry.io/otel/trace v1.42.0/go.mod h1:f3K9S+IFqnumBkKhRJMeaZeNk9epyhnCmQh/EysQCdc= +go.opentelemetry.io/proto/slim/otlp v1.10.0 h1:iR97Vs/ZDR+y9TfuP9b1XBtdPWeC+OMslIBmhcLU7jM= +go.opentelemetry.io/proto/slim/otlp v1.10.0/go.mod h1:lV9250stpjYLPNA5viFabIgP2QlUGRT1GdTgAf8SIUk= +go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.3.0 h1:RUF5rO0hAlgiJt1fzQVzcVs3vZVNHIcMLgOgG4rWNcQ= +go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.3.0/go.mod h1:I89cynRj8y+383o7tEQVg2SVA6SRgDVIouWPUVXjx0U= +go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.3.0 h1:CQvJSldHRUN6Z8jsUeYv8J0lXRvygALXIzsmAeCcZE0= +go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.3.0/go.mod h1:xSQ+mEfJe/GjK1LXEyVOoSI1N9JV9ZI923X5kup43W4= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= go.uber.org/zap v1.27.1 h1:08RqriUEv8+ArZRYSTXy1LeBScaMpVSTBhCeaZYfMYc= go.uber.org/zap v1.27.1/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= -google.golang.org/protobuf v1.36.10 h1:AYd7cD/uASjIL6Q9LiTjz8JLcrh/88q5UObnmY3aOOE= -google.golang.org/protobuf v1.36.10/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= +google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE= +google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= diff --git a/receiver/metadata.yaml b/receiver/metadata.yaml new file mode 100644 index 000000000000..6ce62b175334 --- /dev/null +++ b/receiver/metadata.yaml @@ -0,0 +1,6 @@ +type: receiver +github_project: open-telemetry/opentelemetry-collector + +status: + disable_codecov_badge: true + class: pkg diff --git a/receiver/nopreceiver/README.md b/receiver/nopreceiver/README.md index 027ee2f5e21a..1386b960788b 100644 --- a/receiver/nopreceiver/README.md +++ b/receiver/nopreceiver/README.md @@ -1,13 +1,14 @@ -# No-op Receiver - +# No-op Receiver | Status | | | ------------- |-----------| -| Stability | [beta]: traces, metrics, logs | +| Stability | [development]: profiles | +| | [beta]: traces, metrics, logs | | Distributions | [core], [contrib] | | Issues | [![Open issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector?query=is%3Aissue%20is%3Aopen%20label%3Areceiver%2Fnop%20&label=open&color=orange&logo=opentelemetry)](https://github.com/open-telemetry/opentelemetry-collector/issues?q=is%3Aopen+is%3Aissue+label%3Areceiver%2Fnop) [![Closed issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector?query=is%3Aissue%20is%3Aclosed%20label%3Areceiver%2Fnop%20&label=closed&color=blue&logo=opentelemetry)](https://github.com/open-telemetry/opentelemetry-collector/issues?q=is%3Aclosed+is%3Aissue+label%3Areceiver%2Fnop) | | [Code Owners](https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/main/CONTRIBUTING.md#becoming-a-code-owner) | [@evan-bradley](https://www.github.com/evan-bradley) | +[development]: https://github.com/open-telemetry/opentelemetry-collector/blob/main/docs/component-stability.md#development [beta]: https://github.com/open-telemetry/opentelemetry-collector/blob/main/docs/component-stability.md#beta [core]: https://github.com/open-telemetry/opentelemetry-collector-releases/tree/main/distributions/otelcol [contrib]: https://github.com/open-telemetry/opentelemetry-collector-releases/tree/main/distributions/otelcol-contrib diff --git a/receiver/nopreceiver/generated_component_test.go b/receiver/nopreceiver/generated_component_test.go index bafdd244664a..2be7c59d0449 100644 --- a/receiver/nopreceiver/generated_component_test.go +++ b/receiver/nopreceiver/generated_component_test.go @@ -14,6 +14,7 @@ import ( "go.opentelemetry.io/collector/consumer/consumertest" "go.opentelemetry.io/collector/receiver" "go.opentelemetry.io/collector/receiver/receivertest" + "go.opentelemetry.io/collector/receiver/xreceiver" ) var typ = component.MustNewType("nop") @@ -54,6 +55,13 @@ func TestComponentLifecycle(t *testing.T) { return factory.CreateTraces(ctx, set, cfg, consumertest.NewNop()) }, }, + + { + name: "profiles", + createFn: func(ctx context.Context, set receiver.Settings, cfg component.Config) (component.Component, error) { + return factory.(xreceiver.Factory).CreateProfiles(ctx, set, cfg, consumertest.NewNop()) + }, + }, } cm, err := confmaptest.LoadConf("metadata.yaml") diff --git a/receiver/nopreceiver/go.mod b/receiver/nopreceiver/go.mod index 384f80cf6674..a2cbed7fc063 100644 --- a/receiver/nopreceiver/go.mod +++ b/receiver/nopreceiver/go.mod @@ -1,17 +1,19 @@ module go.opentelemetry.io/collector/receiver/nopreceiver -go 1.24.0 +go 1.25.0 require ( github.com/stretchr/testify v1.11.1 - go.opentelemetry.io/collector/component v1.46.0 - go.opentelemetry.io/collector/component/componenttest v0.140.0 - go.opentelemetry.io/collector/confmap v1.46.0 - go.opentelemetry.io/collector/consumer v1.46.0 - go.opentelemetry.io/collector/consumer/consumertest v0.140.0 - go.opentelemetry.io/collector/pdata v1.46.0 - go.opentelemetry.io/collector/receiver v1.46.0 - go.opentelemetry.io/collector/receiver/receivertest v0.140.0 + go.opentelemetry.io/collector/component v1.54.0 + go.opentelemetry.io/collector/component/componenttest v0.148.0 + go.opentelemetry.io/collector/confmap v1.54.0 + go.opentelemetry.io/collector/consumer v1.54.0 + go.opentelemetry.io/collector/consumer/consumertest v0.148.0 + go.opentelemetry.io/collector/consumer/xconsumer v0.148.0 + go.opentelemetry.io/collector/pdata v1.54.0 + go.opentelemetry.io/collector/receiver v1.54.0 + go.opentelemetry.io/collector/receiver/receivertest v0.148.0 + go.opentelemetry.io/collector/receiver/xreceiver v0.148.0 go.uber.org/goleak v1.3.0 go.uber.org/zap v1.27.1 ) @@ -21,37 +23,36 @@ require ( github.com/davecgh/go-spew v1.1.1 // indirect github.com/go-logr/logr v1.4.3 // indirect github.com/go-logr/stdr v1.2.2 // indirect - github.com/go-viper/mapstructure/v2 v2.4.0 // indirect + github.com/go-viper/mapstructure/v2 v2.5.0 // indirect github.com/gobwas/glob v0.2.3 // indirect github.com/google/uuid v1.6.0 // indirect - github.com/hashicorp/go-version v1.7.0 // indirect + github.com/hashicorp/go-version v1.8.0 // indirect github.com/json-iterator/go v1.1.12 // indirect github.com/knadh/koanf/maps v0.1.2 // indirect github.com/knadh/koanf/providers/confmap v1.0.0 // indirect - github.com/knadh/koanf/v2 v2.3.0 // indirect + github.com/knadh/koanf/v2 v2.3.3 // indirect github.com/mitchellh/copystructure v1.2.0 // indirect github.com/mitchellh/reflectwalk v1.0.2 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee // indirect github.com/pmezard/go-difflib v1.0.0 // indirect go.opentelemetry.io/auto/sdk v1.2.1 // indirect - go.opentelemetry.io/collector/consumer/consumererror v0.140.0 // indirect - go.opentelemetry.io/collector/consumer/xconsumer v0.140.0 // indirect - go.opentelemetry.io/collector/featuregate v1.46.0 // indirect - go.opentelemetry.io/collector/pdata/pprofile v0.140.0 // indirect - go.opentelemetry.io/collector/pipeline v1.46.0 // indirect - go.opentelemetry.io/collector/receiver/xreceiver v0.140.0 // indirect - go.opentelemetry.io/otel v1.40.0 // indirect - go.opentelemetry.io/otel/metric v1.40.0 // indirect + go.opentelemetry.io/collector/consumer/consumererror v0.148.0 // indirect + go.opentelemetry.io/collector/featuregate v1.54.0 // indirect + go.opentelemetry.io/collector/internal/componentalias v0.148.0 // indirect + go.opentelemetry.io/collector/pdata/pprofile v0.148.0 // indirect + go.opentelemetry.io/collector/pipeline v1.54.0 // indirect + go.opentelemetry.io/otel v1.42.0 // indirect + go.opentelemetry.io/otel/metric v1.42.0 // indirect go.opentelemetry.io/otel/sdk v1.40.0 // indirect go.opentelemetry.io/otel/sdk/metric v1.40.0 // indirect - go.opentelemetry.io/otel/trace v1.40.0 // indirect + go.opentelemetry.io/otel/trace v1.42.0 // indirect go.uber.org/multierr v1.11.0 // indirect go.yaml.in/yaml/v3 v3.0.4 // indirect - golang.org/x/sys v0.40.0 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20251022142026-3a174f9686a8 // indirect - google.golang.org/grpc v1.77.0 // indirect - google.golang.org/protobuf v1.36.10 // indirect + golang.org/x/sys v0.41.0 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20251222181119-0a764e51fe1b // indirect + google.golang.org/grpc v1.79.3 // indirect + google.golang.org/protobuf v1.36.11 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) @@ -86,3 +87,5 @@ replace go.opentelemetry.io/collector/consumer/consumererror => ../../consumer/c replace go.opentelemetry.io/collector/featuregate => ../../featuregate replace go.opentelemetry.io/collector/internal/testutil => ../../internal/testutil + +replace go.opentelemetry.io/collector/internal/componentalias => ../../internal/componentalias diff --git a/receiver/nopreceiver/go.sum b/receiver/nopreceiver/go.sum index 87bcdbea6e91..e0e5bd1c5745 100644 --- a/receiver/nopreceiver/go.sum +++ b/receiver/nopreceiver/go.sum @@ -8,8 +8,8 @@ github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI= github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= -github.com/go-viper/mapstructure/v2 v2.4.0 h1:EBsztssimR/CONLSZZ04E8qAkxNYq4Qp9LvH92wZUgs= -github.com/go-viper/mapstructure/v2 v2.4.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM= +github.com/go-viper/mapstructure/v2 v2.5.0 h1:vM5IJoUAy3d7zRSVtIwQgBj7BiWtMPfmPEgAXnvj1Ro= +github.com/go-viper/mapstructure/v2 v2.5.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM= github.com/gobwas/glob v0.2.3 h1:A4xDbljILXROh+kObIiy5kIaPYD8e96x1tgBhUI5J+Y= github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8= github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= @@ -19,16 +19,16 @@ github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/hashicorp/go-version v1.7.0 h1:5tqGy27NaOTB8yJKUZELlFAS/LTKJkrmONwQKeRZfjY= -github.com/hashicorp/go-version v1.7.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= +github.com/hashicorp/go-version v1.8.0 h1:KAkNb1HAiZd1ukkxDFGmokVZe1Xy9HG6NUp+bPle2i4= +github.com/hashicorp/go-version v1.8.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= github.com/knadh/koanf/maps v0.1.2 h1:RBfmAW5CnZT+PJ1CVc1QSJKf4Xu9kxfQgYVQSu8hpbo= github.com/knadh/koanf/maps v0.1.2/go.mod h1:npD/QZY3V6ghQDdcQzl1W4ICNVTkohC8E73eI2xW4yI= github.com/knadh/koanf/providers/confmap v1.0.0 h1:mHKLJTE7iXEys6deO5p6olAiZdG5zwp8Aebir+/EaRE= github.com/knadh/koanf/providers/confmap v1.0.0/go.mod h1:txHYHiI2hAtF0/0sCmcuol4IDcuQbKTybiB1nOcUo1A= -github.com/knadh/koanf/v2 v2.3.0 h1:Qg076dDRFHvqnKG97ZEsi9TAg2/nFTa9hCdcSa1lvlM= -github.com/knadh/koanf/v2 v2.3.0/go.mod h1:gRb40VRAbd4iJMYYD5IxZ6hfuopFcXBpc9bbQpZwo28= +github.com/knadh/koanf/v2 v2.3.3 h1:jLJC8XCRfLC7n4F+ZKKdBsbq1bfXTpuFhf4L7t94D94= +github.com/knadh/koanf/v2 v2.3.3/go.mod h1:gRb40VRAbd4iJMYYD5IxZ6hfuopFcXBpc9bbQpZwo28= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= @@ -53,22 +53,22 @@ github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64= go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y= -go.opentelemetry.io/otel v1.40.0 h1:oA5YeOcpRTXq6NN7frwmwFR0Cn3RhTVZvXsP4duvCms= -go.opentelemetry.io/otel v1.40.0/go.mod h1:IMb+uXZUKkMXdPddhwAHm6UfOwJyh4ct1ybIlV14J0g= -go.opentelemetry.io/otel/metric v1.40.0 h1:rcZe317KPftE2rstWIBitCdVp89A2HqjkxR3c11+p9g= -go.opentelemetry.io/otel/metric v1.40.0/go.mod h1:ib/crwQH7N3r5kfiBZQbwrTge743UDc7DTFVZrrXnqc= +go.opentelemetry.io/otel v1.42.0 h1:lSQGzTgVR3+sgJDAU/7/ZMjN9Z+vUip7leaqBKy4sho= +go.opentelemetry.io/otel v1.42.0/go.mod h1:lJNsdRMxCUIWuMlVJWzecSMuNjE7dOYyWlqOXWkdqCc= +go.opentelemetry.io/otel/metric v1.42.0 h1:2jXG+3oZLNXEPfNmnpxKDeZsFI5o4J+nz6xUlaFdF/4= +go.opentelemetry.io/otel/metric v1.42.0/go.mod h1:RlUN/7vTU7Ao/diDkEpQpnz3/92J9ko05BIwxYa2SSI= go.opentelemetry.io/otel/sdk v1.40.0 h1:KHW/jUzgo6wsPh9At46+h4upjtccTmuZCFAc9OJ71f8= go.opentelemetry.io/otel/sdk v1.40.0/go.mod h1:Ph7EFdYvxq72Y8Li9q8KebuYUr2KoeyHx0DRMKrYBUE= go.opentelemetry.io/otel/sdk/metric v1.40.0 h1:mtmdVqgQkeRxHgRv4qhyJduP3fYJRMX4AtAlbuWdCYw= go.opentelemetry.io/otel/sdk/metric v1.40.0/go.mod h1:4Z2bGMf0KSK3uRjlczMOeMhKU2rhUqdWNoKcYrtcBPg= -go.opentelemetry.io/otel/trace v1.40.0 h1:WA4etStDttCSYuhwvEa8OP8I5EWu24lkOzp+ZYblVjw= -go.opentelemetry.io/otel/trace v1.40.0/go.mod h1:zeAhriXecNGP/s2SEG3+Y8X9ujcJOTqQ5RgdEJcawiA= -go.opentelemetry.io/proto/slim/otlp v1.9.0 h1:fPVMv8tP3TrsqlkH1HWYUpbCY9cAIemx184VGkS6vlE= -go.opentelemetry.io/proto/slim/otlp v1.9.0/go.mod h1:xXdeJJ90Gqyll+orzUkY4bOd2HECo5JofeoLpymVqdI= -go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.2.0 h1:o13nadWDNkH/quoDomDUClnQBpdQQ2Qqv0lQBjIXjE8= -go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.2.0/go.mod h1:Gyb6Xe7FTi/6xBHwMmngGoHqL0w29Y4eW8TGFzpefGA= -go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.2.0 h1:EiUYvtwu6PMrMHVjcPfnsG3v+ajPkbUeH+IL93+QYyk= -go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.2.0/go.mod h1:mUUHKFiN2SST3AhJ8XhJxEoeVW12oqfXog0Bo8W3Ec4= +go.opentelemetry.io/otel/trace v1.42.0 h1:OUCgIPt+mzOnaUTpOQcBiM/PLQ/Op7oq6g4LenLmOYY= +go.opentelemetry.io/otel/trace v1.42.0/go.mod h1:f3K9S+IFqnumBkKhRJMeaZeNk9epyhnCmQh/EysQCdc= +go.opentelemetry.io/proto/slim/otlp v1.10.0 h1:iR97Vs/ZDR+y9TfuP9b1XBtdPWeC+OMslIBmhcLU7jM= +go.opentelemetry.io/proto/slim/otlp v1.10.0/go.mod h1:lV9250stpjYLPNA5viFabIgP2QlUGRT1GdTgAf8SIUk= +go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.3.0 h1:RUF5rO0hAlgiJt1fzQVzcVs3vZVNHIcMLgOgG4rWNcQ= +go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.3.0/go.mod h1:I89cynRj8y+383o7tEQVg2SVA6SRgDVIouWPUVXjx0U= +go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.3.0 h1:CQvJSldHRUN6Z8jsUeYv8J0lXRvygALXIzsmAeCcZE0= +go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.3.0/go.mod h1:xSQ+mEfJe/GjK1LXEyVOoSI1N9JV9ZI923X5kup43W4= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= @@ -77,18 +77,18 @@ go.uber.org/zap v1.27.1 h1:08RqriUEv8+ArZRYSTXy1LeBScaMpVSTBhCeaZYfMYc= go.uber.org/zap v1.27.1/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc= go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg= -golang.org/x/net v0.46.1-0.20251013234738-63d1a5100f82 h1:6/3JGEh1C88g7m+qzzTbl3A0FtsLguXieqofVLU/JAo= -golang.org/x/net v0.46.1-0.20251013234738-63d1a5100f82/go.mod h1:Q9BGdFy1y4nkUwiLvT5qtyhAnEHgnQ/zd8PfU6nc210= -golang.org/x/sys v0.40.0 h1:DBZZqJ2Rkml6QMQsZywtnjnnGvHza6BTfYFWY9kjEWQ= -golang.org/x/sys v0.40.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= -golang.org/x/text v0.30.0 h1:yznKA/E9zq54KzlzBEAWn1NXSQ8DIp/NYMy88xJjl4k= -golang.org/x/text v0.30.0/go.mod h1:yDdHFIX9t+tORqspjENWgzaCVXgk0yYnYuSZ8UzzBVM= -google.golang.org/genproto/googleapis/rpc v0.0.0-20251022142026-3a174f9686a8 h1:M1rk8KBnUsBDg1oPGHNCxG4vc1f49epmTO7xscSajMk= -google.golang.org/genproto/googleapis/rpc v0.0.0-20251022142026-3a174f9686a8/go.mod h1:7i2o+ce6H/6BluujYR+kqX3GKH+dChPTQU19wjRPiGk= -google.golang.org/grpc v1.77.0 h1:wVVY6/8cGA6vvffn+wWK5ToddbgdU3d8MNENr4evgXM= -google.golang.org/grpc v1.77.0/go.mod h1:z0BY1iVj0q8E1uSQCjL9cppRj+gnZjzDnzV0dHhrNig= -google.golang.org/protobuf v1.36.10 h1:AYd7cD/uASjIL6Q9LiTjz8JLcrh/88q5UObnmY3aOOE= -google.golang.org/protobuf v1.36.10/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= +golang.org/x/net v0.51.0 h1:94R/GTO7mt3/4wIKpcR5gkGmRLOuE/2hNGeWq/GBIFo= +golang.org/x/net v0.51.0/go.mod h1:aamm+2QF5ogm02fjy5Bb7CQ0WMt1/WVM7FtyaTLlA9Y= +golang.org/x/sys v0.41.0 h1:Ivj+2Cp/ylzLiEU89QhWblYnOE9zerudt9Ftecq2C6k= +golang.org/x/sys v0.41.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= +golang.org/x/text v0.34.0 h1:oL/Qq0Kdaqxa1KbNeMKwQq0reLCCaFtqu2eNuSeNHbk= +golang.org/x/text v0.34.0/go.mod h1:homfLqTYRFyVYemLBFl5GgL/DWEiH5wcsQ5gSh1yziA= +google.golang.org/genproto/googleapis/rpc v0.0.0-20251222181119-0a764e51fe1b h1:Mv8VFug0MP9e5vUxfBcE3vUkV6CImK3cMNMIDFjmzxU= +google.golang.org/genproto/googleapis/rpc v0.0.0-20251222181119-0a764e51fe1b/go.mod h1:j9x/tPzZkyxcgEFkiKEEGxfvyumM01BEtsW8xzOahRQ= +google.golang.org/grpc v1.79.3 h1:sybAEdRIEtvcD68Gx7dmnwjZKlyfuc61Dyo9pGXXkKE= +google.golang.org/grpc v1.79.3/go.mod h1:KmT0Kjez+0dde/v2j9vzwoAScgEPx/Bw1CYChhHLrHQ= +google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE= +google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= diff --git a/receiver/nopreceiver/internal/metadata/generated_status.go b/receiver/nopreceiver/internal/metadata/generated_status.go index a8716db919c6..568889aa3718 100644 --- a/receiver/nopreceiver/internal/metadata/generated_status.go +++ b/receiver/nopreceiver/internal/metadata/generated_status.go @@ -12,7 +12,8 @@ var ( ) const ( - TracesStability = component.StabilityLevelBeta - MetricsStability = component.StabilityLevelBeta - LogsStability = component.StabilityLevelBeta + ProfilesStability = component.StabilityLevelDevelopment + TracesStability = component.StabilityLevelBeta + MetricsStability = component.StabilityLevelBeta + LogsStability = component.StabilityLevelBeta ) diff --git a/receiver/nopreceiver/metadata.yaml b/receiver/nopreceiver/metadata.yaml index 7bd42e6bed16..724906008d13 100644 --- a/receiver/nopreceiver/metadata.yaml +++ b/receiver/nopreceiver/metadata.yaml @@ -1,3 +1,4 @@ +display_name: No-op Receiver type: nop github_project: open-telemetry/opentelemetry-collector @@ -9,4 +10,5 @@ status: class: receiver stability: beta: [traces, metrics, logs] + development: [profiles] distributions: [core, contrib] diff --git a/receiver/nopreceiver/nop_receiver.go b/receiver/nopreceiver/nop_receiver.go index 6d989daffc92..77f0569ba4ae 100644 --- a/receiver/nopreceiver/nop_receiver.go +++ b/receiver/nopreceiver/nop_receiver.go @@ -8,18 +8,21 @@ import ( "go.opentelemetry.io/collector/component" "go.opentelemetry.io/collector/consumer" + "go.opentelemetry.io/collector/consumer/xconsumer" "go.opentelemetry.io/collector/receiver" "go.opentelemetry.io/collector/receiver/nopreceiver/internal/metadata" + "go.opentelemetry.io/collector/receiver/xreceiver" ) // NewFactory returns a receiver.Factory that constructs nop receivers. -func NewFactory() receiver.Factory { - return receiver.NewFactory( +func NewFactory() xreceiver.Factory { + return xreceiver.NewFactory( metadata.Type, func() component.Config { return &struct{}{} }, - receiver.WithTraces(createTraces, metadata.TracesStability), - receiver.WithMetrics(createMetrics, metadata.MetricsStability), - receiver.WithLogs(createLogs, metadata.LogsStability)) + xreceiver.WithTraces(createTraces, metadata.TracesStability), + xreceiver.WithMetrics(createMetrics, metadata.MetricsStability), + xreceiver.WithProfiles(createProfiles, metadata.ProfilesStability), + xreceiver.WithLogs(createLogs, metadata.LogsStability)) } func createTraces(context.Context, receiver.Settings, component.Config, consumer.Traces) (receiver.Traces, error) { @@ -34,6 +37,10 @@ func createLogs(context.Context, receiver.Settings, component.Config, consumer.L return nopInstance, nil } +func createProfiles(context.Context, receiver.Settings, component.Config, xconsumer.Profiles) (xreceiver.Profiles, error) { + return nopInstance, nil +} + var nopInstance = &nopReceiver{} type nopReceiver struct { diff --git a/receiver/nopreceiver/nop_receiver_test.go b/receiver/nopreceiver/nop_receiver_test.go index 9a477ec418ef..1fed255ee268 100644 --- a/receiver/nopreceiver/nop_receiver_test.go +++ b/receiver/nopreceiver/nop_receiver_test.go @@ -37,4 +37,9 @@ func TestNewNopFactory(t *testing.T) { require.NoError(t, err) assert.NoError(t, logs.Start(context.Background(), componenttest.NewNopHost())) assert.NoError(t, logs.Shutdown(context.Background())) + + profiles, err := factory.CreateProfiles(context.Background(), receivertest.NewNopSettings(receivertest.NopType), cfg, consumertest.NewNop()) + require.NoError(t, err) + assert.NoError(t, profiles.Start(context.Background(), componenttest.NewNopHost())) + assert.NoError(t, profiles.Shutdown(context.Background())) } diff --git a/receiver/otlpreceiver/README.md b/receiver/otlpreceiver/README.md index c313937e29eb..9324dbe0526c 100644 --- a/receiver/otlpreceiver/README.md +++ b/receiver/otlpreceiver/README.md @@ -1,6 +1,5 @@ -# OTLP Receiver - +# OTLP Receiver | Status | | | ------------- |-----------| | Stability | [development]: profiles | diff --git a/receiver/otlpreceiver/config_test.go b/receiver/otlpreceiver/config_test.go index 8a4613779dd4..65fcdda703a3 100644 --- a/receiver/otlpreceiver/config_test.go +++ b/receiver/otlpreceiver/config_test.go @@ -123,12 +123,15 @@ func TestUnmarshalConfig(t *testing.T) { }), HTTP: configoptional.Some(HTTPConfig{ ServerConfig: confighttp.ServerConfig{ + NetAddr: confignet.AddrConfig{ + Endpoint: "localhost:4318", + Transport: confignet.TransportTypeTCP, + }, Auth: configoptional.Some(confighttp.AuthConfig{ Config: configauth.Config{ AuthenticatorID: component.MustNewID("test"), }, }), - Endpoint: "localhost:4318", TLS: configoptional.Some(configtls.ServerConfig{ Config: configtls.Config{ CertFile: "test.crt", @@ -168,7 +171,10 @@ func TestUnmarshalConfigUnix(t *testing.T) { }), HTTP: configoptional.Some(HTTPConfig{ ServerConfig: confighttp.ServerConfig{ - Endpoint: "/tmp/http_otlp.sock", + NetAddr: confignet.AddrConfig{ + Endpoint: "/tmp/http_otlp.sock", + Transport: confignet.TransportTypeUnix, + }, KeepAlivesEnabled: true, }, TracesURLPath: defaultTracesURLPath, diff --git a/receiver/otlpreceiver/factory.go b/receiver/otlpreceiver/factory.go index 1b6f483a1e3e..99c2bb5420e9 100644 --- a/receiver/otlpreceiver/factory.go +++ b/receiver/otlpreceiver/factory.go @@ -46,7 +46,7 @@ func createDefaultConfig() component.Config { grpcCfg.ReadBufferSize = 512 * 1024 httpCfg := confighttp.NewDefaultServerConfig() - httpCfg.Endpoint = "localhost:4318" + httpCfg.NetAddr.Endpoint = "localhost:4318" // For backward compatibility: httpCfg.TLS = configoptional.None[configtls.ServerConfig]() httpCfg.WriteTimeout = 0 diff --git a/receiver/otlpreceiver/factory_test.go b/receiver/otlpreceiver/factory_test.go index bd764bce062d..f06f88f33a4c 100644 --- a/receiver/otlpreceiver/factory_test.go +++ b/receiver/otlpreceiver/factory_test.go @@ -37,7 +37,7 @@ func TestCreateSameReceiver(t *testing.T) { factory := NewFactory() cfg := factory.CreateDefaultConfig().(*Config) cfg.GRPC.GetOrInsertDefault().NetAddr.Endpoint = testutil.GetAvailableLocalAddress(t) - cfg.HTTP.GetOrInsertDefault().ServerConfig.Endpoint = testutil.GetAvailableLocalAddress(t) + cfg.HTTP.GetOrInsertDefault().ServerConfig.NetAddr.Endpoint = testutil.GetAvailableLocalAddress(t) creationSet := receivertest.NewNopSettings(factory.Type()) var droppedAttrs []string @@ -76,7 +76,7 @@ func TestCreateTraces(t *testing.T) { }, }) defaultServerConfig := confighttp.NewDefaultServerConfig() - defaultServerConfig.Endpoint = testutil.GetAvailableLocalAddress(t) + defaultServerConfig.NetAddr.Endpoint = testutil.GetAvailableLocalAddress(t) defaultHTTPSettings := configoptional.Some(HTTPConfig{ ServerConfig: defaultServerConfig, TracesURLPath: defaultTracesURLPath, @@ -124,7 +124,10 @@ func TestCreateTraces(t *testing.T) { GRPC: defaultGRPCSettings, HTTP: configoptional.Some(HTTPConfig{ ServerConfig: confighttp.ServerConfig{ - Endpoint: "localhost:112233", + NetAddr: confignet.AddrConfig{ + Endpoint: "localhost:112233", + Transport: confignet.TransportTypeTCP, + }, }, TracesURLPath: defaultTracesURLPath, }), @@ -170,7 +173,7 @@ func TestCreateMetric(t *testing.T) { }, }) defaultServerConfig := confighttp.NewDefaultServerConfig() - defaultServerConfig.Endpoint = "127.0.0.1:0" + defaultServerConfig.NetAddr.Endpoint = "127.0.0.1:0" defaultHTTPSettings := configoptional.Some(HTTPConfig{ ServerConfig: defaultServerConfig, TracesURLPath: defaultTracesURLPath, @@ -218,7 +221,10 @@ func TestCreateMetric(t *testing.T) { GRPC: defaultGRPCSettings, HTTP: configoptional.Some(HTTPConfig{ ServerConfig: confighttp.ServerConfig{ - Endpoint: "327.0.0.1:1122", + NetAddr: confignet.AddrConfig{ + Endpoint: "327.0.0.1:1122", + Transport: confignet.TransportTypeTCP, + }, }, MetricsURLPath: defaultMetricsURLPath, }), @@ -264,7 +270,7 @@ func TestCreateLogs(t *testing.T) { }, }) defaultServerConfig := confighttp.NewDefaultServerConfig() - defaultServerConfig.Endpoint = testutil.GetAvailableLocalAddress(t) + defaultServerConfig.NetAddr.Endpoint = testutil.GetAvailableLocalAddress(t) defaultHTTPSettings := configoptional.Some(HTTPConfig{ ServerConfig: defaultServerConfig, TracesURLPath: defaultTracesURLPath, @@ -312,7 +318,10 @@ func TestCreateLogs(t *testing.T) { GRPC: defaultGRPCSettings, HTTP: configoptional.Some(HTTPConfig{ ServerConfig: confighttp.ServerConfig{ - Endpoint: "327.0.0.1:1122", + NetAddr: confignet.AddrConfig{ + Endpoint: "327.0.0.1:1122", + Transport: confignet.TransportTypeTCP, + }, }, LogsURLPath: defaultLogsURLPath, }), @@ -358,7 +367,7 @@ func TestCreateProfiles(t *testing.T) { }, }) defaultServerConfig := confighttp.NewDefaultServerConfig() - defaultServerConfig.Endpoint = testutil.GetAvailableLocalAddress(t) + defaultServerConfig.NetAddr.Endpoint = testutil.GetAvailableLocalAddress(t) defaultHTTPSettings := configoptional.Some(HTTPConfig{ ServerConfig: defaultServerConfig, TracesURLPath: defaultTracesURLPath, @@ -406,7 +415,10 @@ func TestCreateProfiles(t *testing.T) { GRPC: defaultGRPCSettings, HTTP: configoptional.Some(HTTPConfig{ ServerConfig: confighttp.ServerConfig{ - Endpoint: "localhost:112233", + NetAddr: confignet.AddrConfig{ + Endpoint: "localhost:112233", + Transport: confignet.TransportTypeTCP, + }, }, }), }, diff --git a/receiver/otlpreceiver/generated_component_test.go b/receiver/otlpreceiver/generated_component_test.go index 651136873022..4cb76d776bc9 100644 --- a/receiver/otlpreceiver/generated_component_test.go +++ b/receiver/otlpreceiver/generated_component_test.go @@ -14,6 +14,7 @@ import ( "go.opentelemetry.io/collector/consumer/consumertest" "go.opentelemetry.io/collector/receiver" "go.opentelemetry.io/collector/receiver/receivertest" + "go.opentelemetry.io/collector/receiver/xreceiver" ) var typ = component.MustNewType("otlp") @@ -54,6 +55,13 @@ func TestComponentLifecycle(t *testing.T) { return factory.CreateTraces(ctx, set, cfg, consumertest.NewNop()) }, }, + + { + name: "profiles", + createFn: func(ctx context.Context, set receiver.Settings, cfg component.Config) (component.Component, error) { + return factory.(xreceiver.Factory).CreateProfiles(ctx, set, cfg, consumertest.NewNop()) + }, + }, } cm, err := confmaptest.LoadConf("metadata.yaml") diff --git a/receiver/otlpreceiver/go.mod b/receiver/otlpreceiver/go.mod index f322272f3ea7..513640ea0f26 100644 --- a/receiver/otlpreceiver/go.mod +++ b/receiver/otlpreceiver/go.mod @@ -1,91 +1,93 @@ module go.opentelemetry.io/collector/receiver/otlpreceiver -go 1.24.0 +go 1.25.0 require ( - github.com/klauspost/compress v1.18.1 + github.com/klauspost/compress v1.18.4 github.com/stretchr/testify v1.11.1 go.opentelemetry.io/collector v0.140.0 - go.opentelemetry.io/collector/component v1.46.0 - go.opentelemetry.io/collector/component/componentstatus v0.140.0 - go.opentelemetry.io/collector/component/componenttest v0.140.0 + go.opentelemetry.io/collector/component v1.54.0 + go.opentelemetry.io/collector/component/componentstatus v0.148.0 + go.opentelemetry.io/collector/component/componenttest v0.148.0 go.opentelemetry.io/collector/config/configauth v1.46.0 go.opentelemetry.io/collector/config/configgrpc v0.140.0 go.opentelemetry.io/collector/config/confighttp v0.140.0 go.opentelemetry.io/collector/config/confignet v1.46.0 go.opentelemetry.io/collector/config/configoptional v1.46.0 go.opentelemetry.io/collector/config/configtls v1.46.0 - go.opentelemetry.io/collector/confmap v1.46.0 - go.opentelemetry.io/collector/confmap/xconfmap v0.140.0 - go.opentelemetry.io/collector/consumer v1.46.0 - go.opentelemetry.io/collector/consumer/consumererror v0.140.0 - go.opentelemetry.io/collector/consumer/consumertest v0.140.0 - go.opentelemetry.io/collector/consumer/xconsumer v0.140.0 + go.opentelemetry.io/collector/confmap v1.54.0 + go.opentelemetry.io/collector/confmap/xconfmap v0.148.0 + go.opentelemetry.io/collector/consumer v1.54.0 + go.opentelemetry.io/collector/consumer/consumererror v0.148.0 + go.opentelemetry.io/collector/consumer/consumertest v0.148.0 + go.opentelemetry.io/collector/consumer/xconsumer v0.148.0 go.opentelemetry.io/collector/internal/sharedcomponent v0.140.0 go.opentelemetry.io/collector/internal/telemetry v0.140.0 - go.opentelemetry.io/collector/internal/testutil v0.140.0 - go.opentelemetry.io/collector/pdata v1.46.0 - go.opentelemetry.io/collector/pdata/pprofile v0.140.0 - go.opentelemetry.io/collector/pdata/testdata v0.140.0 - go.opentelemetry.io/collector/receiver v1.46.0 + go.opentelemetry.io/collector/internal/testutil v0.148.0 + go.opentelemetry.io/collector/pdata v1.54.0 + go.opentelemetry.io/collector/pdata/pprofile v0.148.0 + go.opentelemetry.io/collector/pdata/testdata v0.148.0 + go.opentelemetry.io/collector/receiver v1.54.0 go.opentelemetry.io/collector/receiver/receiverhelper v0.140.0 go.opentelemetry.io/collector/receiver/receivertest v0.140.0 - go.opentelemetry.io/collector/receiver/xreceiver v0.140.0 - go.opentelemetry.io/otel v1.40.0 + go.opentelemetry.io/collector/receiver/xreceiver v0.148.0 + go.opentelemetry.io/otel v1.42.0 go.opentelemetry.io/otel/sdk/metric v1.40.0 go.uber.org/goleak v1.3.0 go.uber.org/zap v1.27.1 - google.golang.org/genproto/googleapis/rpc v0.0.0-20251022142026-3a174f9686a8 - google.golang.org/grpc v1.77.0 - google.golang.org/protobuf v1.36.10 + google.golang.org/genproto/googleapis/rpc v0.0.0-20260226221140-a57be14db171 + google.golang.org/grpc v1.79.3 + google.golang.org/protobuf v1.36.11 ) require ( github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/davecgh/go-spew v1.1.1 // indirect github.com/felixge/httpsnoop v1.0.4 // indirect - github.com/foxboron/go-tpm-keyfiles v0.0.0-20250903184740-5d135037bd4d // indirect + github.com/foxboron/go-tpm-keyfiles v0.0.0-20251226215517-609e4778396f // indirect github.com/fsnotify/fsnotify v1.9.0 // indirect github.com/go-logr/logr v1.4.3 // indirect github.com/go-logr/stdr v1.2.2 // indirect - github.com/go-viper/mapstructure/v2 v2.4.0 // indirect + github.com/go-viper/mapstructure/v2 v2.5.0 // indirect github.com/gobwas/glob v0.2.3 // indirect github.com/golang/snappy v1.0.0 // indirect - github.com/google/go-tpm v0.9.7 // indirect + github.com/google/go-tpm v0.9.8 // indirect github.com/google/uuid v1.6.0 // indirect - github.com/hashicorp/go-version v1.7.0 // indirect + github.com/hashicorp/go-version v1.8.0 // indirect github.com/json-iterator/go v1.1.12 // indirect github.com/knadh/koanf/maps v0.1.2 // indirect github.com/knadh/koanf/providers/confmap v1.0.0 // indirect - github.com/knadh/koanf/v2 v2.3.0 // indirect + github.com/knadh/koanf/v2 v2.3.3 // indirect github.com/mitchellh/copystructure v1.2.0 // indirect github.com/mitchellh/reflectwalk v1.0.2 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee // indirect github.com/mostynb/go-grpc-compression v1.2.3 // indirect - github.com/pierrec/lz4/v4 v4.1.22 // indirect + github.com/pierrec/lz4/v4 v4.1.26 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect github.com/rs/cors v1.11.1 // indirect go.opentelemetry.io/auto/sdk v1.2.1 // indirect go.opentelemetry.io/collector/client v1.46.0 // indirect go.opentelemetry.io/collector/config/configcompression v1.46.0 // indirect go.opentelemetry.io/collector/config/configmiddleware v1.46.0 // indirect - go.opentelemetry.io/collector/config/configopaque v1.46.0 // indirect - go.opentelemetry.io/collector/extension/extensionauth v1.46.0 // indirect - go.opentelemetry.io/collector/extension/extensionmiddleware v0.140.0 // indirect - go.opentelemetry.io/collector/featuregate v1.46.0 // indirect - go.opentelemetry.io/collector/pipeline v1.46.0 // indirect + go.opentelemetry.io/collector/config/configopaque v1.54.0 // indirect + go.opentelemetry.io/collector/extension/extensionauth v1.54.0 // indirect + go.opentelemetry.io/collector/extension/extensionmiddleware v0.148.0 // indirect + go.opentelemetry.io/collector/featuregate v1.54.0 // indirect + go.opentelemetry.io/collector/internal/componentalias v0.148.0 // indirect + go.opentelemetry.io/collector/pipeline v1.54.0 // indirect + go.opentelemetry.io/collector/pipeline/xpipeline v0.0.0-00010101000000-000000000000 // indirect go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.63.0 // indirect go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.63.0 // indirect - go.opentelemetry.io/otel/metric v1.40.0 // indirect + go.opentelemetry.io/otel/metric v1.42.0 // indirect go.opentelemetry.io/otel/sdk v1.40.0 // indirect - go.opentelemetry.io/otel/trace v1.40.0 // indirect + go.opentelemetry.io/otel/trace v1.42.0 // indirect go.uber.org/multierr v1.11.0 // indirect go.yaml.in/yaml/v3 v3.0.4 // indirect - golang.org/x/crypto v0.45.0 // indirect - golang.org/x/net v0.47.0 // indirect - golang.org/x/sys v0.40.0 // indirect - golang.org/x/text v0.31.0 // indirect + golang.org/x/crypto v0.48.0 // indirect + golang.org/x/net v0.51.0 // indirect + golang.org/x/sys v0.41.0 // indirect + golang.org/x/text v0.34.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) @@ -167,3 +169,7 @@ replace go.opentelemetry.io/collector/config/configmiddleware => ../../config/co replace go.opentelemetry.io/collector/extension/extensionmiddleware/extensionmiddlewaretest => ../../extension/extensionmiddleware/extensionmiddlewaretest replace go.opentelemetry.io/collector/internal/testutil => ../../internal/testutil + +replace go.opentelemetry.io/collector/pipeline/xpipeline => ../../pipeline/xpipeline + +replace go.opentelemetry.io/collector/internal/componentalias => ../../internal/componentalias diff --git a/receiver/otlpreceiver/go.sum b/receiver/otlpreceiver/go.sum index 3faac577e17a..7f7989c3bed3 100644 --- a/receiver/otlpreceiver/go.sum +++ b/receiver/otlpreceiver/go.sum @@ -5,10 +5,8 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg= github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= -github.com/foxboron/go-tpm-keyfiles v0.0.0-20250903184740-5d135037bd4d h1:EdO/NMMuCZfxhdzTZLuKAciQSnI2DV+Ppg8+vAYrnqA= -github.com/foxboron/go-tpm-keyfiles v0.0.0-20250903184740-5d135037bd4d/go.mod h1:uAyTlAUxchYuiFjTHmuIEJ4nGSm7iOPaGcAyA81fJ80= -github.com/foxboron/swtpm_test v0.0.0-20230726224112-46aaafdf7006 h1:50sW4r0PcvlpG4PV8tYh2RVCapszJgaOLRCS2subvV4= -github.com/foxboron/swtpm_test v0.0.0-20230726224112-46aaafdf7006/go.mod h1:eIXCMsMYCaqq9m1KSSxXwQG11krpuNPGP3k0uaWrbas= +github.com/foxboron/go-tpm-keyfiles v0.0.0-20251226215517-609e4778396f h1:RJ+BDPLSHQO7cSjKBqjPJSbi1qfk9WcsjQDtZiw3dZw= +github.com/foxboron/go-tpm-keyfiles v0.0.0-20251226215517-609e4778396f/go.mod h1:VHbbch/X4roIY22jL1s3qRbZhCiRIgUAF/PdSUcx2io= github.com/fsnotify/fsnotify v1.9.0 h1:2Ml+OJNzbYCTzsxtv8vKSFD9PbJjmhYF14k/jKC7S9k= github.com/fsnotify/fsnotify v1.9.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= @@ -16,8 +14,8 @@ github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI= github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= -github.com/go-viper/mapstructure/v2 v2.4.0 h1:EBsztssimR/CONLSZZ04E8qAkxNYq4Qp9LvH92wZUgs= -github.com/go-viper/mapstructure/v2 v2.4.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM= +github.com/go-viper/mapstructure/v2 v2.5.0 h1:vM5IJoUAy3d7zRSVtIwQgBj7BiWtMPfmPEgAXnvj1Ro= +github.com/go-viper/mapstructure/v2 v2.5.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM= github.com/gobwas/glob v0.2.3 h1:A4xDbljILXROh+kObIiy5kIaPYD8e96x1tgBhUI5J+Y= github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8= github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= @@ -26,25 +24,25 @@ github.com/golang/snappy v1.0.0 h1:Oy607GVXHs7RtbggtPBnr2RmDArIsAefDwvrdWvRhGs= github.com/golang/snappy v1.0.0/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= -github.com/google/go-tpm v0.9.7 h1:u89J4tUUeDTlH8xxC3CTW7OHZjbjKoHdQ9W7gCUhtxA= -github.com/google/go-tpm v0.9.7/go.mod h1:h9jEsEECg7gtLis0upRBQU+GhYVH6jMjrFxI8u6bVUY= -github.com/google/go-tpm-tools v0.4.4 h1:oiQfAIkc6xTy9Fl5NKTeTJkBTlXdHsxAofmQyxBKY98= -github.com/google/go-tpm-tools v0.4.4/go.mod h1:T8jXkp2s+eltnCDIsXR84/MTcVU9Ja7bh3Mit0pa4AY= +github.com/google/go-tpm v0.9.8 h1:slArAR9Ft+1ybZu0lBwpSmpwhRXaa85hWtMinMyRAWo= +github.com/google/go-tpm v0.9.8/go.mod h1:h9jEsEECg7gtLis0upRBQU+GhYVH6jMjrFxI8u6bVUY= +github.com/google/go-tpm-tools v0.4.7 h1:J3ycC8umYxM9A4eF73EofRZu4BxY0jjQnUnkhIBbvws= +github.com/google/go-tpm-tools v0.4.7/go.mod h1:gSyXTZHe3fgbzb6WEGd90QucmsnT1SRdlye82gH8QjQ= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/hashicorp/go-version v1.7.0 h1:5tqGy27NaOTB8yJKUZELlFAS/LTKJkrmONwQKeRZfjY= -github.com/hashicorp/go-version v1.7.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= +github.com/hashicorp/go-version v1.8.0 h1:KAkNb1HAiZd1ukkxDFGmokVZe1Xy9HG6NUp+bPle2i4= +github.com/hashicorp/go-version v1.8.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= -github.com/klauspost/compress v1.18.1 h1:bcSGx7UbpBqMChDtsF28Lw6v/G94LPrrbMbdC3JH2co= -github.com/klauspost/compress v1.18.1/go.mod h1:ZQFFVG+MdnR0P+l6wpXgIL4NTtwiKIdBnrBd8Nrxr+0= +github.com/klauspost/compress v1.18.4 h1:RPhnKRAQ4Fh8zU2FY/6ZFDwTVTxgJ/EMydqSTzE9a2c= +github.com/klauspost/compress v1.18.4/go.mod h1:R0h/fSBs8DE4ENlcrlib3PsXS61voFxhIs2DeRhCvJ4= github.com/knadh/koanf/maps v0.1.2 h1:RBfmAW5CnZT+PJ1CVc1QSJKf4Xu9kxfQgYVQSu8hpbo= github.com/knadh/koanf/maps v0.1.2/go.mod h1:npD/QZY3V6ghQDdcQzl1W4ICNVTkohC8E73eI2xW4yI= github.com/knadh/koanf/providers/confmap v1.0.0 h1:mHKLJTE7iXEys6deO5p6olAiZdG5zwp8Aebir+/EaRE= github.com/knadh/koanf/providers/confmap v1.0.0/go.mod h1:txHYHiI2hAtF0/0sCmcuol4IDcuQbKTybiB1nOcUo1A= -github.com/knadh/koanf/v2 v2.3.0 h1:Qg076dDRFHvqnKG97ZEsi9TAg2/nFTa9hCdcSa1lvlM= -github.com/knadh/koanf/v2 v2.3.0/go.mod h1:gRb40VRAbd4iJMYYD5IxZ6hfuopFcXBpc9bbQpZwo28= +github.com/knadh/koanf/v2 v2.3.3 h1:jLJC8XCRfLC7n4F+ZKKdBsbq1bfXTpuFhf4L7t94D94= +github.com/knadh/koanf/v2 v2.3.3/go.mod h1:gRb40VRAbd4iJMYYD5IxZ6hfuopFcXBpc9bbQpZwo28= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= @@ -61,8 +59,8 @@ github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee h1:W5t00kpgFd github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= github.com/mostynb/go-grpc-compression v1.2.3 h1:42/BKWMy0KEJGSdWvzqIyOZ95YcR9mLPqKctH7Uo//I= github.com/mostynb/go-grpc-compression v1.2.3/go.mod h1:AghIxF3P57umzqM9yz795+y1Vjs47Km/Y2FE6ouQ7Lg= -github.com/pierrec/lz4/v4 v4.1.22 h1:cKFw6uJDK+/gfw5BcDL0JL5aBsAFdsIT18eRtLj7VIU= -github.com/pierrec/lz4/v4 v4.1.22/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4= +github.com/pierrec/lz4/v4 v4.1.26 h1:GrpZw1gZttORinvzBdXPUXATeqlJjqUG/D87TKMnhjY= +github.com/pierrec/lz4/v4 v4.1.26/go.mod h1:EoQMVJgeeEOMsCqCzqFm2O0cJvljX2nGZjcRIPL34O4= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ= @@ -79,22 +77,22 @@ go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.6 go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.63.0/go.mod h1:fvPi2qXDqFs8M4B4fmJhE92TyQs9Ydjlg3RvfUp+NbQ= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.63.0 h1:RbKq8BG0FI8OiXhBfcRtqqHcZcka+gU3cskNuf05R18= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.63.0/go.mod h1:h06DGIukJOevXaj/xrNjhi/2098RZzcLTbc0jDAUbsg= -go.opentelemetry.io/otel v1.40.0 h1:oA5YeOcpRTXq6NN7frwmwFR0Cn3RhTVZvXsP4duvCms= -go.opentelemetry.io/otel v1.40.0/go.mod h1:IMb+uXZUKkMXdPddhwAHm6UfOwJyh4ct1ybIlV14J0g= -go.opentelemetry.io/otel/metric v1.40.0 h1:rcZe317KPftE2rstWIBitCdVp89A2HqjkxR3c11+p9g= -go.opentelemetry.io/otel/metric v1.40.0/go.mod h1:ib/crwQH7N3r5kfiBZQbwrTge743UDc7DTFVZrrXnqc= +go.opentelemetry.io/otel v1.42.0 h1:lSQGzTgVR3+sgJDAU/7/ZMjN9Z+vUip7leaqBKy4sho= +go.opentelemetry.io/otel v1.42.0/go.mod h1:lJNsdRMxCUIWuMlVJWzecSMuNjE7dOYyWlqOXWkdqCc= +go.opentelemetry.io/otel/metric v1.42.0 h1:2jXG+3oZLNXEPfNmnpxKDeZsFI5o4J+nz6xUlaFdF/4= +go.opentelemetry.io/otel/metric v1.42.0/go.mod h1:RlUN/7vTU7Ao/diDkEpQpnz3/92J9ko05BIwxYa2SSI= go.opentelemetry.io/otel/sdk v1.40.0 h1:KHW/jUzgo6wsPh9At46+h4upjtccTmuZCFAc9OJ71f8= go.opentelemetry.io/otel/sdk v1.40.0/go.mod h1:Ph7EFdYvxq72Y8Li9q8KebuYUr2KoeyHx0DRMKrYBUE= go.opentelemetry.io/otel/sdk/metric v1.40.0 h1:mtmdVqgQkeRxHgRv4qhyJduP3fYJRMX4AtAlbuWdCYw= go.opentelemetry.io/otel/sdk/metric v1.40.0/go.mod h1:4Z2bGMf0KSK3uRjlczMOeMhKU2rhUqdWNoKcYrtcBPg= -go.opentelemetry.io/otel/trace v1.40.0 h1:WA4etStDttCSYuhwvEa8OP8I5EWu24lkOzp+ZYblVjw= -go.opentelemetry.io/otel/trace v1.40.0/go.mod h1:zeAhriXecNGP/s2SEG3+Y8X9ujcJOTqQ5RgdEJcawiA= -go.opentelemetry.io/proto/slim/otlp v1.9.0 h1:fPVMv8tP3TrsqlkH1HWYUpbCY9cAIemx184VGkS6vlE= -go.opentelemetry.io/proto/slim/otlp v1.9.0/go.mod h1:xXdeJJ90Gqyll+orzUkY4bOd2HECo5JofeoLpymVqdI= -go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.2.0 h1:o13nadWDNkH/quoDomDUClnQBpdQQ2Qqv0lQBjIXjE8= -go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.2.0/go.mod h1:Gyb6Xe7FTi/6xBHwMmngGoHqL0w29Y4eW8TGFzpefGA= -go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.2.0 h1:EiUYvtwu6PMrMHVjcPfnsG3v+ajPkbUeH+IL93+QYyk= -go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.2.0/go.mod h1:mUUHKFiN2SST3AhJ8XhJxEoeVW12oqfXog0Bo8W3Ec4= +go.opentelemetry.io/otel/trace v1.42.0 h1:OUCgIPt+mzOnaUTpOQcBiM/PLQ/Op7oq6g4LenLmOYY= +go.opentelemetry.io/otel/trace v1.42.0/go.mod h1:f3K9S+IFqnumBkKhRJMeaZeNk9epyhnCmQh/EysQCdc= +go.opentelemetry.io/proto/slim/otlp v1.10.0 h1:iR97Vs/ZDR+y9TfuP9b1XBtdPWeC+OMslIBmhcLU7jM= +go.opentelemetry.io/proto/slim/otlp v1.10.0/go.mod h1:lV9250stpjYLPNA5viFabIgP2QlUGRT1GdTgAf8SIUk= +go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.3.0 h1:RUF5rO0hAlgiJt1fzQVzcVs3vZVNHIcMLgOgG4rWNcQ= +go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.3.0/go.mod h1:I89cynRj8y+383o7tEQVg2SVA6SRgDVIouWPUVXjx0U= +go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.3.0 h1:CQvJSldHRUN6Z8jsUeYv8J0lXRvygALXIzsmAeCcZE0= +go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.3.0/go.mod h1:xSQ+mEfJe/GjK1LXEyVOoSI1N9JV9ZI923X5kup43W4= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= @@ -103,22 +101,22 @@ go.uber.org/zap v1.27.1 h1:08RqriUEv8+ArZRYSTXy1LeBScaMpVSTBhCeaZYfMYc= go.uber.org/zap v1.27.1/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc= go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg= -golang.org/x/crypto v0.45.0 h1:jMBrvKuj23MTlT0bQEOBcAE0mjg8mK9RXFhRH6nyF3Q= -golang.org/x/crypto v0.45.0/go.mod h1:XTGrrkGJve7CYK7J8PEww4aY7gM3qMCElcJQ8n8JdX4= -golang.org/x/net v0.47.0 h1:Mx+4dIFzqraBXUugkia1OOvlD6LemFo1ALMHjrXDOhY= -golang.org/x/net v0.47.0/go.mod h1:/jNxtkgq5yWUGYkaZGqo27cfGZ1c5Nen03aYrrKpVRU= -golang.org/x/sys v0.40.0 h1:DBZZqJ2Rkml6QMQsZywtnjnnGvHza6BTfYFWY9kjEWQ= -golang.org/x/sys v0.40.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= -golang.org/x/text v0.31.0 h1:aC8ghyu4JhP8VojJ2lEHBnochRno1sgL6nEi9WGFGMM= -golang.org/x/text v0.31.0/go.mod h1:tKRAlv61yKIjGGHX/4tP1LTbc13YSec1pxVEWXzfoeM= +golang.org/x/crypto v0.48.0 h1:/VRzVqiRSggnhY7gNRxPauEQ5Drw9haKdM0jqfcCFts= +golang.org/x/crypto v0.48.0/go.mod h1:r0kV5h3qnFPlQnBSrULhlsRfryS2pmewsg+XfMgkVos= +golang.org/x/net v0.51.0 h1:94R/GTO7mt3/4wIKpcR5gkGmRLOuE/2hNGeWq/GBIFo= +golang.org/x/net v0.51.0/go.mod h1:aamm+2QF5ogm02fjy5Bb7CQ0WMt1/WVM7FtyaTLlA9Y= +golang.org/x/sys v0.41.0 h1:Ivj+2Cp/ylzLiEU89QhWblYnOE9zerudt9Ftecq2C6k= +golang.org/x/sys v0.41.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= +golang.org/x/text v0.34.0 h1:oL/Qq0Kdaqxa1KbNeMKwQq0reLCCaFtqu2eNuSeNHbk= +golang.org/x/text v0.34.0/go.mod h1:homfLqTYRFyVYemLBFl5GgL/DWEiH5wcsQ5gSh1yziA= gonum.org/v1/gonum v0.16.0 h1:5+ul4Swaf3ESvrOnidPp4GZbzf0mxVQpDCYUQE7OJfk= gonum.org/v1/gonum v0.16.0/go.mod h1:fef3am4MQ93R2HHpKnLk4/Tbh/s0+wqD5nfa6Pnwy4E= -google.golang.org/genproto/googleapis/rpc v0.0.0-20251022142026-3a174f9686a8 h1:M1rk8KBnUsBDg1oPGHNCxG4vc1f49epmTO7xscSajMk= -google.golang.org/genproto/googleapis/rpc v0.0.0-20251022142026-3a174f9686a8/go.mod h1:7i2o+ce6H/6BluujYR+kqX3GKH+dChPTQU19wjRPiGk= -google.golang.org/grpc v1.77.0 h1:wVVY6/8cGA6vvffn+wWK5ToddbgdU3d8MNENr4evgXM= -google.golang.org/grpc v1.77.0/go.mod h1:z0BY1iVj0q8E1uSQCjL9cppRj+gnZjzDnzV0dHhrNig= -google.golang.org/protobuf v1.36.10 h1:AYd7cD/uASjIL6Q9LiTjz8JLcrh/88q5UObnmY3aOOE= -google.golang.org/protobuf v1.36.10/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= +google.golang.org/genproto/googleapis/rpc v0.0.0-20260226221140-a57be14db171 h1:ggcbiqK8WWh6l1dnltU4BgWGIGo+EVYxCaAPih/zQXQ= +google.golang.org/genproto/googleapis/rpc v0.0.0-20260226221140-a57be14db171/go.mod h1:4Hqkh8ycfw05ld/3BWL7rJOSfebL2Q+DVDeRgYgxUU8= +google.golang.org/grpc v1.79.3 h1:sybAEdRIEtvcD68Gx7dmnwjZKlyfuc61Dyo9pGXXkKE= +google.golang.org/grpc v1.79.3/go.mod h1:KmT0Kjez+0dde/v2j9vzwoAScgEPx/Bw1CYChhHLrHQ= +google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE= +google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= diff --git a/receiver/otlpreceiver/internal/profiles/otlp.go b/receiver/otlpreceiver/internal/profiles/otlp.go index 269769b6824b..d111618e6ad7 100644 --- a/receiver/otlpreceiver/internal/profiles/otlp.go +++ b/receiver/otlpreceiver/internal/profiles/otlp.go @@ -9,18 +9,23 @@ import ( "go.opentelemetry.io/collector/consumer/xconsumer" "go.opentelemetry.io/collector/pdata/pprofile/pprofileotlp" "go.opentelemetry.io/collector/receiver/otlpreceiver/internal/errors" + "go.opentelemetry.io/collector/receiver/receiverhelper" ) +const dataFormatProtobuf = "protobuf" + // Receiver is the type used to handle spans from OpenTelemetry exporters. type Receiver struct { pprofileotlp.UnimplementedGRPCServer nextConsumer xconsumer.Profiles + obsreport *receiverhelper.ObsReport } // New creates a new Receiver reference. -func New(nextConsumer xconsumer.Profiles) *Receiver { +func New(nextConsumer xconsumer.Profiles, obsreport *receiverhelper.ObsReport) *Receiver { return &Receiver{ nextConsumer: nextConsumer, + obsreport: obsreport, } } @@ -28,12 +33,15 @@ func New(nextConsumer xconsumer.Profiles) *Receiver { func (r *Receiver) Export(ctx context.Context, req pprofileotlp.ExportRequest) (pprofileotlp.ExportResponse, error) { td := req.Profiles() // We need to ensure that it propagates the receiver name as a tag - numProfiles := td.SampleCount() - if numProfiles == 0 { + numSamples := td.SampleCount() + if numSamples == 0 { return pprofileotlp.NewExportResponse(), nil } + ctx = r.obsreport.StartTracesOp(ctx) err := r.nextConsumer.ConsumeProfiles(ctx, td) + r.obsreport.EndTracesOp(ctx, dataFormatProtobuf, numSamples, err) + // Use appropriate status codes for permanent/non-permanent errors // If we return the error straightaway, then the grpc implementation will set status code to Unknown // Refer: https://github.com/grpc/grpc-go/blob/v1.59.0/server.go#L1345 diff --git a/receiver/otlpreceiver/internal/profiles/otlp_test.go b/receiver/otlpreceiver/internal/profiles/otlp_test.go index 1a70049944d3..204c3cd981d3 100644 --- a/receiver/otlpreceiver/internal/profiles/otlp_test.go +++ b/receiver/otlpreceiver/internal/profiles/otlp_test.go @@ -16,11 +16,15 @@ import ( "google.golang.org/grpc/credentials/insecure" "google.golang.org/grpc/status" + "go.opentelemetry.io/collector/component" "go.opentelemetry.io/collector/consumer/consumererror" "go.opentelemetry.io/collector/consumer/consumertest" "go.opentelemetry.io/collector/consumer/xconsumer" "go.opentelemetry.io/collector/pdata/pprofile/pprofileotlp" "go.opentelemetry.io/collector/pdata/testdata" + "go.opentelemetry.io/collector/receiver/otlpreceiver/internal/metadata" + "go.opentelemetry.io/collector/receiver/receiverhelper" + "go.opentelemetry.io/collector/receiver/receivertest" ) func TestExport(t *testing.T) { @@ -86,7 +90,16 @@ func otlpReceiverOnGRPCServer(t *testing.T, tc xconsumer.Profiles) net.Addr { require.NoError(t, ln.Close()) }) - r := New(tc) + set := receivertest.NewNopSettings(metadata.Type) + set.ID = component.MustNewIDWithName("otlp", "profiles") + obsreport, err := receiverhelper.NewObsReport(receiverhelper.ObsReportSettings{ + ReceiverID: set.ID, + Transport: "grpc", + ReceiverCreateSettings: set, + }) + require.NoError(t, err) + + r := New(tc, obsreport) // Now run it as a gRPC server srv := grpc.NewServer() pprofileotlp.RegisterGRPCServer(srv, r) diff --git a/receiver/otlpreceiver/metadata.yaml b/receiver/otlpreceiver/metadata.yaml index adb2cae28f0c..bc971d73f7e1 100644 --- a/receiver/otlpreceiver/metadata.yaml +++ b/receiver/otlpreceiver/metadata.yaml @@ -1,3 +1,4 @@ +display_name: OTLP Receiver type: otlp github_project: open-telemetry/opentelemetry-collector diff --git a/receiver/otlpreceiver/otlp.go b/receiver/otlpreceiver/otlp.go index b18d5323d4c9..5b35b7576c8d 100644 --- a/receiver/otlpreceiver/otlp.go +++ b/receiver/otlpreceiver/otlp.go @@ -110,7 +110,7 @@ func (r *otlpReceiver) startGRPCServer(ctx context.Context, host component.Host) } if r.nextProfiles != nil { - pprofileotlp.RegisterGRPCServer(r.serverGRPC, profiles.New(r.nextProfiles)) + pprofileotlp.RegisterGRPCServer(r.serverGRPC, profiles.New(r.nextProfiles, r.obsrepGRPC)) } var gln net.Listener @@ -119,14 +119,11 @@ func (r *otlpReceiver) startGRPCServer(ctx context.Context, host component.Host) } r.settings.Logger.Info("Starting GRPC server", zap.String("endpoint", gln.Addr().String())) - r.shutdownWG.Add(1) - go func() { - defer r.shutdownWG.Done() - + r.shutdownWG.Go(func() { if errGrpc := r.serverGRPC.Serve(gln); errGrpc != nil && !errors.Is(errGrpc, grpc.ErrServerStopped) { componentstatus.ReportStatus(host, componentstatus.NewFatalErrorEvent(errGrpc)) } - }() + }) return nil } @@ -160,7 +157,7 @@ func (r *otlpReceiver) startHTTPServer(ctx context.Context, host component.Host) } if r.nextProfiles != nil { - httpProfilesReceiver := profiles.New(r.nextProfiles) + httpProfilesReceiver := profiles.New(r.nextProfiles, r.obsrepHTTP) httpMux.HandleFunc(defaultProfilesURLPath, func(resp http.ResponseWriter, req *http.Request) { handleProfiles(resp, req, httpProfilesReceiver) }) @@ -177,14 +174,11 @@ func (r *otlpReceiver) startHTTPServer(ctx context.Context, host component.Host) } r.settings.Logger.Info("Starting HTTP server", zap.String("endpoint", hln.Addr().String())) - r.shutdownWG.Add(1) - go func() { - defer r.shutdownWG.Done() - + r.shutdownWG.Go(func() { if errHTTP := r.serverHTTP.Serve(hln); errHTTP != nil && !errors.Is(errHTTP, http.ErrServerClosed) { componentstatus.ReportStatus(host, componentstatus.NewFatalErrorEvent(errHTTP)) } - }() + }) return nil } diff --git a/receiver/otlpreceiver/otlp_benchmark_test.go b/receiver/otlpreceiver/otlp_benchmark_test.go new file mode 100644 index 000000000000..4218bb359d42 --- /dev/null +++ b/receiver/otlpreceiver/otlp_benchmark_test.go @@ -0,0 +1,97 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +package otlpreceiver + +import ( + "bytes" + "context" + "io" + "net/http" + "testing" + + "github.com/stretchr/testify/require" + "google.golang.org/grpc" + "google.golang.org/grpc/credentials/insecure" + + "go.opentelemetry.io/collector/component/componenttest" + "go.opentelemetry.io/collector/consumer/consumertest" + "go.opentelemetry.io/collector/internal/testutil" + "go.opentelemetry.io/collector/pdata/plog" + "go.opentelemetry.io/collector/pdata/plog/plogotlp" + "go.opentelemetry.io/collector/pdata/testdata" + "go.opentelemetry.io/collector/receiver/otlpreceiver/internal/metadata" + "go.opentelemetry.io/collector/receiver/receivertest" +) + +const ( + itemsPerRequest = 10_000 + protobufContentType = "application/x-protobuf" +) + +func startLogsReceiver(b *testing.B, cfg *Config, sink *consumertest.LogsSink) { + set := receivertest.NewNopSettings(metadata.Type) + factory := NewFactory() + r, err := factory.CreateLogs(b.Context(), set, cfg, sink) + require.NoError(b, err) + + require.NoError(b, r.Start(b.Context(), componenttest.NewNopHost())) + b.Cleanup(func() { + require.NoError(b, r.Shutdown(context.Background())) + }) +} + +// BenchmarkGRPCLogsSequential benchmarks sequentially receiving logs over OTLP/gRPC. +// A typical deployment would receive multiple concurrent requests, this benchmark tries to +// measure the performance of the receiver without concurrency to have a more stable benchmark. +func BenchmarkGRPCLogsSequential(b *testing.B) { + endpoint := testutil.GetAvailableLocalAddress(b) + cfg := createDefaultConfig().(*Config) + cfg.GRPC.GetOrInsertDefault().NetAddr.Endpoint = endpoint + var sink consumertest.LogsSink + startLogsReceiver(b, cfg, &sink) + + cc, err := grpc.NewClient(endpoint, grpc.WithTransportCredentials(insecure.NewCredentials())) + require.NoError(b, err) + b.Cleanup(func() { require.NoError(b, cc.Close()) }) + logClient := plogotlp.NewGRPCClient(cc) + req := plogotlp.NewExportRequestFromLogs(testdata.GenerateLogs(itemsPerRequest)) + + for b.Loop() { + _, err := logClient.Export(b.Context(), req) + require.NoError(b, err) + } + + require.Equal(b, b.N*itemsPerRequest, sink.LogRecordCount()) +} + +// BenchmarkHTTPProtoLogsSequential benchmarks sequentially receiving logs over OTLP/HTTP (proto). +// A typical deployment would receive multiple concurrent requests, this benchmark tries to +// measure the performance of the receiver without concurrency to have a more stable benchmark. +func BenchmarkHTTPProtoLogsSequential(b *testing.B) { + endpoint := testutil.GetAvailableLocalAddress(b) + cfg := createDefaultConfig().(*Config) + cfg.HTTP.GetOrInsertDefault().ServerConfig.NetAddr.Endpoint = endpoint + var sink consumertest.LogsSink + startLogsReceiver(b, cfg, &sink) + + marshaler := &plog.ProtoMarshaler{} + bodyBytes, err := marshaler.MarshalLogs(testdata.GenerateLogs(itemsPerRequest)) + require.NoError(b, err) + req, err := http.NewRequest(http.MethodPost, "http://"+endpoint+defaultLogsURLPath, bytes.NewReader(bodyBytes)) + require.NoError(b, err) + req.Header.Set("Content-Type", protobufContentType) + + reader := bytes.NewReader(bodyBytes) + for b.Loop() { + reader.Reset(bodyBytes) + req.Body = io.NopCloser(reader) + + resp, err := http.DefaultClient.Do(req) + require.NoError(b, err) + require.Equal(b, http.StatusOK, resp.StatusCode) + resp.Body.Close() + } + + require.Equal(b, b.N*itemsPerRequest, sink.LogRecordCount()) +} diff --git a/receiver/otlpreceiver/otlp_test.go b/receiver/otlpreceiver/otlp_test.go index 16e53c7b44e4..8a7a6a0726ab 100644 --- a/receiver/otlpreceiver/otlp_test.go +++ b/receiver/otlpreceiver/otlp_test.go @@ -58,7 +58,7 @@ const otlpReceiverName = "receiver_test" var otlpReceiverID = component.MustNewIDWithName("otlp", otlpReceiverName) -func TestJsonHttp(t *testing.T) { +func TestJSONHTTP(t *testing.T) { tests := []struct { name string encoding string @@ -331,7 +331,7 @@ func TestHandleInvalidRequests(t *testing.T) { require.NoError(t, recv.Shutdown(context.Background())) } -func TestProtoHttp(t *testing.T) { +func TestProtoHTTP(t *testing.T) { tests := []struct { name string encoding string @@ -828,7 +828,10 @@ func TestHTTPInvalidTLSCredentials(t *testing.T) { Protocols: Protocols{ HTTP: configoptional.Some(HTTPConfig{ ServerConfig: confighttp.ServerConfig{ - Endpoint: testutil.GetAvailableLocalAddress(t), + NetAddr: confignet.AddrConfig{ + Endpoint: testutil.GetAvailableLocalAddress(t), + Transport: confignet.TransportTypeTCP, + }, TLS: configoptional.Some(configtls.ServerConfig{ Config: configtls.Config{ CertFile: "willfail", @@ -861,7 +864,10 @@ func testHTTPMaxRequestBodySize(t *testing.T, path, contentType string, payload Protocols: Protocols{ HTTP: configoptional.Some(HTTPConfig{ ServerConfig: confighttp.ServerConfig{ - Endpoint: addr, + NetAddr: confignet.AddrConfig{ + Endpoint: addr, + Transport: confignet.TransportTypeTCP, + }, MaxRequestBodySize: int64(size), }, TracesURLPath: defaultTracesURLPath, @@ -904,7 +910,7 @@ func newGRPCReceiver(t *testing.T, settings component.TelemetrySettings, endpoin func newHTTPReceiver(t *testing.T, settings component.TelemetrySettings, endpoint string, c consumertest.Consumer) component.Component { cfg := createDefaultConfig().(*Config) - cfg.HTTP.GetOrInsertDefault().ServerConfig.Endpoint = endpoint + cfg.HTTP.GetOrInsertDefault().ServerConfig.NetAddr.Endpoint = endpoint return newReceiver(t, settings, cfg, otlpReceiverID, c) } @@ -1085,7 +1091,7 @@ func TestShutdown(t *testing.T) { factory := NewFactory() cfg := factory.CreateDefaultConfig().(*Config) cfg.GRPC.GetOrInsertDefault().NetAddr.Endpoint = endpointGrpc - cfg.HTTP.GetOrInsertDefault().ServerConfig.Endpoint = endpointHTTP + cfg.HTTP.GetOrInsertDefault().ServerConfig.NetAddr.Endpoint = endpointHTTP set := receivertest.NewNopSettings(metadata.Type) set.ID = otlpReceiverID r, err := NewFactory().CreateTraces( @@ -1323,7 +1329,7 @@ func assertReceiverTraces(t *testing.T, tt *componenttest.Telemetry, id componen metricdata.Metrics{ Name: "otelcol_receiver_failed_spans", Description: "The number of spans that failed to be processed by the receiver due to internal errors. [Alpha]", - Unit: "{spans}", + Unit: "{span}", Data: metricdata.Sum[int64]{ Temporality: metricdata.CumulativeTemporality, IsMonotonic: true, @@ -1344,7 +1350,7 @@ func assertReceiverTraces(t *testing.T, tt *componenttest.Telemetry, id componen metricdata.Metrics{ Name: "otelcol_receiver_accepted_spans", Description: "Number of spans successfully pushed into the pipeline. [Alpha]", - Unit: "{spans}", + Unit: "{span}", Data: metricdata.Sum[int64]{ Temporality: metricdata.CumulativeTemporality, IsMonotonic: true, @@ -1365,7 +1371,7 @@ func assertReceiverTraces(t *testing.T, tt *componenttest.Telemetry, id componen metricdata.Metrics{ Name: "otelcol_receiver_refused_spans", Description: "Number of spans that could not be pushed into the pipeline. [Alpha]", - Unit: "{spans}", + Unit: "{span}", Data: metricdata.Sum[int64]{ Temporality: metricdata.CumulativeTemporality, IsMonotonic: true, @@ -1410,7 +1416,7 @@ func assertReceiverTraces(t *testing.T, tt *componenttest.Telemetry, id componen metricdata.Metrics{ Name: "otelcol_receiver_requests", Description: "The number of requests performed.", - Unit: "{requests}", + Unit: "{request}", Data: metricdata.Sum[int64]{ Temporality: metricdata.CumulativeTemporality, IsMonotonic: true, @@ -1442,7 +1448,7 @@ func assertReceiverMetrics(t *testing.T, tt *componenttest.Telemetry, id compone metricdata.Metrics{ Name: "otelcol_receiver_failed_metric_points", Description: "The number of metric points that failed to be processed by the receiver due to internal errors. [Alpha]", - Unit: "{datapoints}", + Unit: "{datapoint}", Data: metricdata.Sum[int64]{ Temporality: metricdata.CumulativeTemporality, IsMonotonic: true, @@ -1463,7 +1469,7 @@ func assertReceiverMetrics(t *testing.T, tt *componenttest.Telemetry, id compone metricdata.Metrics{ Name: "otelcol_receiver_accepted_metric_points", Description: "Number of metric points successfully pushed into the pipeline. [Alpha]", - Unit: "{datapoints}", + Unit: "{datapoint}", Data: metricdata.Sum[int64]{ Temporality: metricdata.CumulativeTemporality, IsMonotonic: true, @@ -1484,7 +1490,7 @@ func assertReceiverMetrics(t *testing.T, tt *componenttest.Telemetry, id compone metricdata.Metrics{ Name: "otelcol_receiver_refused_metric_points", Description: "Number of metric points that could not be pushed into the pipeline. [Alpha]", - Unit: "{datapoints}", + Unit: "{datapoint}", Data: metricdata.Sum[int64]{ Temporality: metricdata.CumulativeTemporality, IsMonotonic: true, @@ -1529,7 +1535,7 @@ func assertReceiverMetrics(t *testing.T, tt *componenttest.Telemetry, id compone metricdata.Metrics{ Name: "otelcol_receiver_requests", Description: "The number of requests performed.", - Unit: "{requests}", + Unit: "{request}", Data: metricdata.Sum[int64]{ Temporality: metricdata.CumulativeTemporality, IsMonotonic: true, diff --git a/receiver/otlpreceiver/otlphttp_test.go b/receiver/otlpreceiver/otlphttp_test.go index f0639297b503..f85684845d4e 100644 --- a/receiver/otlpreceiver/otlphttp_test.go +++ b/receiver/otlpreceiver/otlphttp_test.go @@ -26,7 +26,7 @@ import ( "go.opentelemetry.io/collector/receiver/otlpreceiver/internal/errors" ) -func TestHttpRetryAfter(t *testing.T) { +func TestHTTPRetryAfter(t *testing.T) { tests := []struct { name string contentType string diff --git a/receiver/otlpreceiver/testdata/uds.yaml b/receiver/otlpreceiver/testdata/uds.yaml index d1d70bff7dfd..3304ee015aaa 100644 --- a/receiver/otlpreceiver/testdata/uds.yaml +++ b/receiver/otlpreceiver/testdata/uds.yaml @@ -4,5 +4,5 @@ protocols: transport: unix endpoint: /tmp/grpc_otlp.sock http: - # transport: unix + transport: unix endpoint: /tmp/http_otlp.sock diff --git a/receiver/receiver.go b/receiver/receiver.go index f2aa1fe2c584..833951574fea 100644 --- a/receiver/receiver.go +++ b/receiver/receiver.go @@ -8,8 +8,8 @@ import ( "go.opentelemetry.io/collector/component" "go.opentelemetry.io/collector/consumer" + "go.opentelemetry.io/collector/internal/componentalias" "go.opentelemetry.io/collector/pipeline" - "go.opentelemetry.io/collector/receiver/internal" ) // Traces receiver receives traces. @@ -115,6 +115,7 @@ type CreateLogsFunc func(context.Context, Settings, component.Config, consumer.L type factory struct { cfgType component.Type component.CreateDefaultConfigFunc + componentalias.TypeAliasHolder createTracesFunc CreateTracesFunc tracesStabilityLevel component.StabilityLevel createMetricsFunc CreateMetricsFunc @@ -146,8 +147,8 @@ func (f *factory) CreateTraces(ctx context.Context, set Settings, cfg component. return nil, pipeline.ErrSignalNotSupported } - if set.ID.Type() != f.Type() { - return nil, internal.ErrIDMismatch(set.ID, f.Type()) + if err := componentalias.ValidateComponentType(f, set.ID); err != nil { + return nil, err } return f.createTracesFunc(ctx, set, cfg, next) @@ -158,8 +159,8 @@ func (f *factory) CreateMetrics(ctx context.Context, set Settings, cfg component return nil, pipeline.ErrSignalNotSupported } - if set.ID.Type() != f.Type() { - return nil, internal.ErrIDMismatch(set.ID, f.Type()) + if err := componentalias.ValidateComponentType(f, set.ID); err != nil { + return nil, err } return f.createMetricsFunc(ctx, set, cfg, next) @@ -170,8 +171,8 @@ func (f *factory) CreateLogs(ctx context.Context, set Settings, cfg component.Co return nil, pipeline.ErrSignalNotSupported } - if set.ID.Type() != f.Type() { - return nil, internal.ErrIDMismatch(set.ID, f.Type()) + if err := componentalias.ValidateComponentType(f, set.ID); err != nil { + return nil, err } return f.createLogsFunc(ctx, set, cfg, next) @@ -206,6 +207,7 @@ func NewFactory(cfgType component.Type, createDefaultConfig component.CreateDefa f := &factory{ cfgType: cfgType, CreateDefaultConfigFunc: createDefaultConfig, + TypeAliasHolder: componentalias.NewTypeAliasHolder(), } for _, opt := range options { opt.applyOption(f) diff --git a/receiver/receiverhelper/documentation.md b/receiver/receiverhelper/documentation.md index e25eb5b92190..34e51c3108ce 100644 --- a/receiver/receiverhelper/documentation.md +++ b/receiver/receiverhelper/documentation.md @@ -8,86 +8,120 @@ The following telemetry is emitted by this component. ### otelcol_receiver_accepted_log_records -Number of log records successfully pushed into the pipeline. [Alpha] +Number of log records successfully pushed into the pipeline. | Unit | Metric Type | Value Type | Monotonic | Stability | | ---- | ----------- | ---------- | --------- | --------- | -| {records} | Sum | Int | true | Alpha | +| {record} | Sum | Int | true | Alpha | ### otelcol_receiver_accepted_metric_points -Number of metric points successfully pushed into the pipeline. [Alpha] +Number of metric points successfully pushed into the pipeline. | Unit | Metric Type | Value Type | Monotonic | Stability | | ---- | ----------- | ---------- | --------- | --------- | -| {datapoints} | Sum | Int | true | Alpha | +| {datapoint} | Sum | Int | true | Alpha | + +### otelcol_receiver_accepted_profile_samples + +Number of profile samples successfully pushed into the pipeline. + +| Unit | Metric Type | Value Type | Monotonic | Stability | +| ---- | ----------- | ---------- | --------- | --------- | +| {sample} | Sum | Int | true | Alpha | ### otelcol_receiver_accepted_spans -Number of spans successfully pushed into the pipeline. [Alpha] +Number of spans successfully pushed into the pipeline. | Unit | Metric Type | Value Type | Monotonic | Stability | | ---- | ----------- | ---------- | --------- | --------- | -| {spans} | Sum | Int | true | Alpha | +| {span} | Sum | Int | true | Alpha | ### otelcol_receiver_failed_log_records -The number of log records that failed to be processed by the receiver due to internal errors. [Alpha] +The number of log records that failed to be processed by the receiver due to internal errors. | Unit | Metric Type | Value Type | Monotonic | Stability | | ---- | ----------- | ---------- | --------- | --------- | -| {records} | Sum | Int | true | Alpha | +| {record} | Sum | Int | true | Alpha | ### otelcol_receiver_failed_metric_points -The number of metric points that failed to be processed by the receiver due to internal errors. [Alpha] +The number of metric points that failed to be processed by the receiver due to internal errors. + +| Unit | Metric Type | Value Type | Monotonic | Stability | +| ---- | ----------- | ---------- | --------- | --------- | +| {datapoint} | Sum | Int | true | Alpha | + +### otelcol_receiver_failed_profile_samples + +The number of profile samples that failed to be processed by the receiver due to internal errors. | Unit | Metric Type | Value Type | Monotonic | Stability | | ---- | ----------- | ---------- | --------- | --------- | -| {datapoints} | Sum | Int | true | Alpha | +| {sample} | Sum | Int | true | Alpha | ### otelcol_receiver_failed_spans -The number of spans that failed to be processed by the receiver due to internal errors. [Alpha] +The number of spans that failed to be processed by the receiver due to internal errors. | Unit | Metric Type | Value Type | Monotonic | Stability | | ---- | ----------- | ---------- | --------- | --------- | -| {spans} | Sum | Int | true | Alpha | +| {span} | Sum | Int | true | Alpha | ### otelcol_receiver_refused_log_records -Number of log records that could not be pushed into the pipeline. [Alpha] +Number of log records that could not be pushed into the pipeline. | Unit | Metric Type | Value Type | Monotonic | Stability | | ---- | ----------- | ---------- | --------- | --------- | -| {records} | Sum | Int | true | Alpha | +| {record} | Sum | Int | true | Alpha | ### otelcol_receiver_refused_metric_points -Number of metric points that could not be pushed into the pipeline. [Alpha] +Number of metric points that could not be pushed into the pipeline. | Unit | Metric Type | Value Type | Monotonic | Stability | | ---- | ----------- | ---------- | --------- | --------- | -| {datapoints} | Sum | Int | true | Alpha | +| {datapoint} | Sum | Int | true | Alpha | + +### otelcol_receiver_refused_profile_samples + +Number of profile samples that could not be pushed into the pipeline. + +| Unit | Metric Type | Value Type | Monotonic | Stability | +| ---- | ----------- | ---------- | --------- | --------- | +| {sample} | Sum | Int | true | Alpha | ### otelcol_receiver_refused_spans -Number of spans that could not be pushed into the pipeline. [Alpha] +Number of spans that could not be pushed into the pipeline. | Unit | Metric Type | Value Type | Monotonic | Stability | | ---- | ----------- | ---------- | --------- | --------- | -| {spans} | Sum | Int | true | Alpha | +| {span} | Sum | Int | true | Alpha | ### otelcol_receiver_requests -The number of requests performed. [Alpha] +The number of requests performed. | Unit | Metric Type | Value Type | Monotonic | Stability | | ---- | ----------- | ---------- | --------- | --------- | -| {requests} | Sum | Int | true | Alpha | +| {request} | Sum | Int | true | Alpha | #### Attributes | Name | Description | Values | | ---- | ----------- | ------ | | outcome | The outcome of receiver requests | Str: ``success``, ``refused``, ``failure`` | + +## Feature Gates + +This component has the following feature gates: + +| Feature Gate | Stage | Description | From Version | To Version | Reference | +| ------------ | ----- | ----------- | ------------ | ---------- | --------- | +| `receiverhelper.newReceiverMetrics` | alpha | Controls whether receivers emit new metrics and span attributes to distinguish downstream errors from internal errors. This is a breaking change for the semantics of the otelcol_receiver_refused_metric_points, otelcol_receiver_refused_log_records and otelcol_receiver_refused_spans. | v0.138.0 | N/A | [Link](https://github.com/open-telemetry/opentelemetry-collector/pull/12802) | + +For more information about feature gates, see the [Feature Gates](https://github.com/open-telemetry/opentelemetry-collector/blob/main/featuregate/README.md) documentation. diff --git a/receiver/receiverhelper/featuregates.go b/receiver/receiverhelper/featuregates.go index 3125fc7c7426..352ac10e5cf3 100644 --- a/receiver/receiverhelper/featuregates.go +++ b/receiver/receiverhelper/featuregates.go @@ -3,12 +3,8 @@ package receiverhelper // import "go.opentelemetry.io/collector/receiver/receiverhelper" -import "go.opentelemetry.io/collector/featuregate" +import "go.opentelemetry.io/collector/receiver/receiverhelper/internal/metadata" // NewReceiverMetricsGate is the feature gate that controls whether to distinguish downstream errors from internal errors in pipeline telemetry. -var NewReceiverMetricsGate = featuregate.GlobalRegistry().MustRegister( - "receiverhelper.newReceiverMetrics", - featuregate.StageAlpha, - featuregate.WithRegisterFromVersion("v0.138.0"), - featuregate.WithRegisterDescription("Controls whether receivers emit new metrics and span attributes to distinguish downstream errors from internal errors. This is a breaking change for the semantics of the otelcol_receiver_refused_metric_points, otelcol_receiver_refused_log_records and otelcol_receiver_refused_spans."), -) +// This feature gate is used in OTLP receiver tests, and therefore needs to be public. +var NewReceiverMetricsGate = metadata.ReceiverhelperNewReceiverMetricsFeatureGate diff --git a/receiver/receiverhelper/go.mod b/receiver/receiverhelper/go.mod index 40fe0696195f..c8d6bc484cba 100644 --- a/receiver/receiverhelper/go.mod +++ b/receiver/receiverhelper/go.mod @@ -1,19 +1,20 @@ module go.opentelemetry.io/collector/receiver/receiverhelper -go 1.24.0 +go 1.25.0 require ( github.com/stretchr/testify v1.11.1 - go.opentelemetry.io/collector/component v1.46.0 + go.opentelemetry.io/collector/component v1.54.0 go.opentelemetry.io/collector/component/componenttest v0.140.0 go.opentelemetry.io/collector/consumer/consumererror v0.140.0 - go.opentelemetry.io/collector/featuregate v1.46.0 - go.opentelemetry.io/collector/pipeline v1.46.0 + go.opentelemetry.io/collector/featuregate v1.54.0 + go.opentelemetry.io/collector/pipeline v1.54.0 + go.opentelemetry.io/collector/pipeline/xpipeline v0.0.0-00010101000000-000000000000 go.opentelemetry.io/collector/receiver v1.46.0 - go.opentelemetry.io/otel v1.40.0 - go.opentelemetry.io/otel/metric v1.40.0 + go.opentelemetry.io/otel v1.42.0 + go.opentelemetry.io/otel/metric v1.42.0 go.opentelemetry.io/otel/sdk/metric v1.40.0 - go.opentelemetry.io/otel/trace v1.40.0 + go.opentelemetry.io/otel/trace v1.42.0 go.uber.org/goleak v1.3.0 ) @@ -23,22 +24,23 @@ require ( github.com/go-logr/logr v1.4.3 // indirect github.com/go-logr/stdr v1.2.2 // indirect github.com/google/uuid v1.6.0 // indirect - github.com/hashicorp/go-version v1.7.0 // indirect + github.com/hashicorp/go-version v1.8.0 // indirect github.com/json-iterator/go v1.1.12 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee // indirect github.com/pmezard/go-difflib v1.0.0 // indirect go.opentelemetry.io/auto/sdk v1.2.1 // indirect - go.opentelemetry.io/collector/consumer v1.46.0 // indirect - go.opentelemetry.io/collector/pdata v1.46.0 // indirect - go.opentelemetry.io/collector/pdata/pprofile v0.140.0 // indirect + go.opentelemetry.io/collector/consumer v1.54.0 // indirect + go.opentelemetry.io/collector/internal/componentalias v0.148.0 // indirect + go.opentelemetry.io/collector/pdata v1.54.0 // indirect + go.opentelemetry.io/collector/pdata/pprofile v0.148.0 // indirect go.opentelemetry.io/otel/sdk v1.40.0 // indirect go.uber.org/multierr v1.11.0 // indirect go.uber.org/zap v1.27.1 // indirect - golang.org/x/sys v0.40.0 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20251022142026-3a174f9686a8 // indirect - google.golang.org/grpc v1.77.0 // indirect - google.golang.org/protobuf v1.36.10 // indirect + golang.org/x/sys v0.41.0 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20251222181119-0a764e51fe1b // indirect + google.golang.org/grpc v1.79.3 // indirect + google.golang.org/protobuf v1.36.11 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) @@ -67,3 +69,7 @@ replace go.opentelemetry.io/collector/featuregate => ../../featuregate replace go.opentelemetry.io/collector/consumer/consumererror => ../../consumer/consumererror replace go.opentelemetry.io/collector/internal/testutil => ../../internal/testutil + +replace go.opentelemetry.io/collector/pipeline/xpipeline => ../../pipeline/xpipeline + +replace go.opentelemetry.io/collector/internal/componentalias => ../../internal/componentalias diff --git a/receiver/receiverhelper/go.sum b/receiver/receiverhelper/go.sum index 365c0691917d..bf8635e3851f 100644 --- a/receiver/receiverhelper/go.sum +++ b/receiver/receiverhelper/go.sum @@ -15,8 +15,8 @@ github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/hashicorp/go-version v1.7.0 h1:5tqGy27NaOTB8yJKUZELlFAS/LTKJkrmONwQKeRZfjY= -github.com/hashicorp/go-version v1.7.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= +github.com/hashicorp/go-version v1.8.0 h1:KAkNb1HAiZd1ukkxDFGmokVZe1Xy9HG6NUp+bPle2i4= +github.com/hashicorp/go-version v1.8.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= @@ -39,40 +39,40 @@ github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64= go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y= -go.opentelemetry.io/otel v1.40.0 h1:oA5YeOcpRTXq6NN7frwmwFR0Cn3RhTVZvXsP4duvCms= -go.opentelemetry.io/otel v1.40.0/go.mod h1:IMb+uXZUKkMXdPddhwAHm6UfOwJyh4ct1ybIlV14J0g= -go.opentelemetry.io/otel/metric v1.40.0 h1:rcZe317KPftE2rstWIBitCdVp89A2HqjkxR3c11+p9g= -go.opentelemetry.io/otel/metric v1.40.0/go.mod h1:ib/crwQH7N3r5kfiBZQbwrTge743UDc7DTFVZrrXnqc= +go.opentelemetry.io/otel v1.42.0 h1:lSQGzTgVR3+sgJDAU/7/ZMjN9Z+vUip7leaqBKy4sho= +go.opentelemetry.io/otel v1.42.0/go.mod h1:lJNsdRMxCUIWuMlVJWzecSMuNjE7dOYyWlqOXWkdqCc= +go.opentelemetry.io/otel/metric v1.42.0 h1:2jXG+3oZLNXEPfNmnpxKDeZsFI5o4J+nz6xUlaFdF/4= +go.opentelemetry.io/otel/metric v1.42.0/go.mod h1:RlUN/7vTU7Ao/diDkEpQpnz3/92J9ko05BIwxYa2SSI= go.opentelemetry.io/otel/sdk v1.40.0 h1:KHW/jUzgo6wsPh9At46+h4upjtccTmuZCFAc9OJ71f8= go.opentelemetry.io/otel/sdk v1.40.0/go.mod h1:Ph7EFdYvxq72Y8Li9q8KebuYUr2KoeyHx0DRMKrYBUE= go.opentelemetry.io/otel/sdk/metric v1.40.0 h1:mtmdVqgQkeRxHgRv4qhyJduP3fYJRMX4AtAlbuWdCYw= go.opentelemetry.io/otel/sdk/metric v1.40.0/go.mod h1:4Z2bGMf0KSK3uRjlczMOeMhKU2rhUqdWNoKcYrtcBPg= -go.opentelemetry.io/otel/trace v1.40.0 h1:WA4etStDttCSYuhwvEa8OP8I5EWu24lkOzp+ZYblVjw= -go.opentelemetry.io/otel/trace v1.40.0/go.mod h1:zeAhriXecNGP/s2SEG3+Y8X9ujcJOTqQ5RgdEJcawiA= -go.opentelemetry.io/proto/slim/otlp v1.9.0 h1:fPVMv8tP3TrsqlkH1HWYUpbCY9cAIemx184VGkS6vlE= -go.opentelemetry.io/proto/slim/otlp v1.9.0/go.mod h1:xXdeJJ90Gqyll+orzUkY4bOd2HECo5JofeoLpymVqdI= -go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.2.0 h1:o13nadWDNkH/quoDomDUClnQBpdQQ2Qqv0lQBjIXjE8= -go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.2.0/go.mod h1:Gyb6Xe7FTi/6xBHwMmngGoHqL0w29Y4eW8TGFzpefGA= -go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.2.0 h1:EiUYvtwu6PMrMHVjcPfnsG3v+ajPkbUeH+IL93+QYyk= -go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.2.0/go.mod h1:mUUHKFiN2SST3AhJ8XhJxEoeVW12oqfXog0Bo8W3Ec4= +go.opentelemetry.io/otel/trace v1.42.0 h1:OUCgIPt+mzOnaUTpOQcBiM/PLQ/Op7oq6g4LenLmOYY= +go.opentelemetry.io/otel/trace v1.42.0/go.mod h1:f3K9S+IFqnumBkKhRJMeaZeNk9epyhnCmQh/EysQCdc= +go.opentelemetry.io/proto/slim/otlp v1.10.0 h1:iR97Vs/ZDR+y9TfuP9b1XBtdPWeC+OMslIBmhcLU7jM= +go.opentelemetry.io/proto/slim/otlp v1.10.0/go.mod h1:lV9250stpjYLPNA5viFabIgP2QlUGRT1GdTgAf8SIUk= +go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.3.0 h1:RUF5rO0hAlgiJt1fzQVzcVs3vZVNHIcMLgOgG4rWNcQ= +go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.3.0/go.mod h1:I89cynRj8y+383o7tEQVg2SVA6SRgDVIouWPUVXjx0U= +go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.3.0 h1:CQvJSldHRUN6Z8jsUeYv8J0lXRvygALXIzsmAeCcZE0= +go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.3.0/go.mod h1:xSQ+mEfJe/GjK1LXEyVOoSI1N9JV9ZI923X5kup43W4= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= go.uber.org/zap v1.27.1 h1:08RqriUEv8+ArZRYSTXy1LeBScaMpVSTBhCeaZYfMYc= go.uber.org/zap v1.27.1/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= -golang.org/x/net v0.46.1-0.20251013234738-63d1a5100f82 h1:6/3JGEh1C88g7m+qzzTbl3A0FtsLguXieqofVLU/JAo= -golang.org/x/net v0.46.1-0.20251013234738-63d1a5100f82/go.mod h1:Q9BGdFy1y4nkUwiLvT5qtyhAnEHgnQ/zd8PfU6nc210= -golang.org/x/sys v0.40.0 h1:DBZZqJ2Rkml6QMQsZywtnjnnGvHza6BTfYFWY9kjEWQ= -golang.org/x/sys v0.40.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= -golang.org/x/text v0.30.0 h1:yznKA/E9zq54KzlzBEAWn1NXSQ8DIp/NYMy88xJjl4k= -golang.org/x/text v0.30.0/go.mod h1:yDdHFIX9t+tORqspjENWgzaCVXgk0yYnYuSZ8UzzBVM= -google.golang.org/genproto/googleapis/rpc v0.0.0-20251022142026-3a174f9686a8 h1:M1rk8KBnUsBDg1oPGHNCxG4vc1f49epmTO7xscSajMk= -google.golang.org/genproto/googleapis/rpc v0.0.0-20251022142026-3a174f9686a8/go.mod h1:7i2o+ce6H/6BluujYR+kqX3GKH+dChPTQU19wjRPiGk= -google.golang.org/grpc v1.77.0 h1:wVVY6/8cGA6vvffn+wWK5ToddbgdU3d8MNENr4evgXM= -google.golang.org/grpc v1.77.0/go.mod h1:z0BY1iVj0q8E1uSQCjL9cppRj+gnZjzDnzV0dHhrNig= -google.golang.org/protobuf v1.36.10 h1:AYd7cD/uASjIL6Q9LiTjz8JLcrh/88q5UObnmY3aOOE= -google.golang.org/protobuf v1.36.10/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= +golang.org/x/net v0.51.0 h1:94R/GTO7mt3/4wIKpcR5gkGmRLOuE/2hNGeWq/GBIFo= +golang.org/x/net v0.51.0/go.mod h1:aamm+2QF5ogm02fjy5Bb7CQ0WMt1/WVM7FtyaTLlA9Y= +golang.org/x/sys v0.41.0 h1:Ivj+2Cp/ylzLiEU89QhWblYnOE9zerudt9Ftecq2C6k= +golang.org/x/sys v0.41.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= +golang.org/x/text v0.34.0 h1:oL/Qq0Kdaqxa1KbNeMKwQq0reLCCaFtqu2eNuSeNHbk= +golang.org/x/text v0.34.0/go.mod h1:homfLqTYRFyVYemLBFl5GgL/DWEiH5wcsQ5gSh1yziA= +google.golang.org/genproto/googleapis/rpc v0.0.0-20251222181119-0a764e51fe1b h1:Mv8VFug0MP9e5vUxfBcE3vUkV6CImK3cMNMIDFjmzxU= +google.golang.org/genproto/googleapis/rpc v0.0.0-20251222181119-0a764e51fe1b/go.mod h1:j9x/tPzZkyxcgEFkiKEEGxfvyumM01BEtsW8xzOahRQ= +google.golang.org/grpc v1.79.3 h1:sybAEdRIEtvcD68Gx7dmnwjZKlyfuc61Dyo9pGXXkKE= +google.golang.org/grpc v1.79.3/go.mod h1:KmT0Kjez+0dde/v2j9vzwoAScgEPx/Bw1CYChhHLrHQ= +google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE= +google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= diff --git a/receiver/receiverhelper/internal/metadata/generated_feature_gates.go b/receiver/receiverhelper/internal/metadata/generated_feature_gates.go new file mode 100644 index 000000000000..77eaab370da2 --- /dev/null +++ b/receiver/receiverhelper/internal/metadata/generated_feature_gates.go @@ -0,0 +1,15 @@ +// Code generated by mdatagen. DO NOT EDIT. + +package metadata + +import ( + "go.opentelemetry.io/collector/featuregate" +) + +var ReceiverhelperNewReceiverMetricsFeatureGate = featuregate.GlobalRegistry().MustRegister( + "receiverhelper.newReceiverMetrics", + featuregate.StageAlpha, + featuregate.WithRegisterDescription("Controls whether receivers emit new metrics and span attributes to distinguish downstream errors from internal errors. This is a breaking change for the semantics of the otelcol_receiver_refused_metric_points, otelcol_receiver_refused_log_records and otelcol_receiver_refused_spans."), + featuregate.WithRegisterReferenceURL("https://github.com/open-telemetry/opentelemetry-collector/pull/12802"), + featuregate.WithRegisterFromVersion("v0.138.0"), +) diff --git a/receiver/receiverhelper/internal/metadata/generated_telemetry.go b/receiver/receiverhelper/internal/metadata/generated_telemetry.go index 4409c14891f4..f2631dd16362 100644 --- a/receiver/receiverhelper/internal/metadata/generated_telemetry.go +++ b/receiver/receiverhelper/internal/metadata/generated_telemetry.go @@ -23,19 +23,22 @@ func Tracer(settings component.TelemetrySettings) trace.Tracer { // TelemetryBuilder provides an interface for components to report telemetry // as defined in metadata and user config. type TelemetryBuilder struct { - meter metric.Meter - mu sync.Mutex - registrations []metric.Registration - ReceiverAcceptedLogRecords metric.Int64Counter - ReceiverAcceptedMetricPoints metric.Int64Counter - ReceiverAcceptedSpans metric.Int64Counter - ReceiverFailedLogRecords metric.Int64Counter - ReceiverFailedMetricPoints metric.Int64Counter - ReceiverFailedSpans metric.Int64Counter - ReceiverRefusedLogRecords metric.Int64Counter - ReceiverRefusedMetricPoints metric.Int64Counter - ReceiverRefusedSpans metric.Int64Counter - ReceiverRequests metric.Int64Counter + meter metric.Meter + mu sync.Mutex + registrations []metric.Registration + ReceiverAcceptedLogRecords metric.Int64Counter + ReceiverAcceptedMetricPoints metric.Int64Counter + ReceiverAcceptedProfileSamples metric.Int64Counter + ReceiverAcceptedSpans metric.Int64Counter + ReceiverFailedLogRecords metric.Int64Counter + ReceiverFailedMetricPoints metric.Int64Counter + ReceiverFailedProfileSamples metric.Int64Counter + ReceiverFailedSpans metric.Int64Counter + ReceiverRefusedLogRecords metric.Int64Counter + ReceiverRefusedMetricPoints metric.Int64Counter + ReceiverRefusedProfileSamples metric.Int64Counter + ReceiverRefusedSpans metric.Int64Counter + ReceiverRequests metric.Int64Counter } // TelemetryBuilderOption applies changes to default builder. @@ -70,61 +73,79 @@ func NewTelemetryBuilder(settings component.TelemetrySettings, options ...Teleme builder.ReceiverAcceptedLogRecords, err = builder.meter.Int64Counter( "otelcol_receiver_accepted_log_records", metric.WithDescription("Number of log records successfully pushed into the pipeline. [Alpha]"), - metric.WithUnit("{records}"), + metric.WithUnit("{record}"), ) errs = errors.Join(errs, err) builder.ReceiverAcceptedMetricPoints, err = builder.meter.Int64Counter( "otelcol_receiver_accepted_metric_points", metric.WithDescription("Number of metric points successfully pushed into the pipeline. [Alpha]"), - metric.WithUnit("{datapoints}"), + metric.WithUnit("{datapoint}"), + ) + errs = errors.Join(errs, err) + builder.ReceiverAcceptedProfileSamples, err = builder.meter.Int64Counter( + "otelcol_receiver_accepted_profile_samples", + metric.WithDescription("Number of profile samples successfully pushed into the pipeline. [Alpha]"), + metric.WithUnit("{sample}"), ) errs = errors.Join(errs, err) builder.ReceiverAcceptedSpans, err = builder.meter.Int64Counter( "otelcol_receiver_accepted_spans", metric.WithDescription("Number of spans successfully pushed into the pipeline. [Alpha]"), - metric.WithUnit("{spans}"), + metric.WithUnit("{span}"), ) errs = errors.Join(errs, err) builder.ReceiverFailedLogRecords, err = builder.meter.Int64Counter( "otelcol_receiver_failed_log_records", metric.WithDescription("The number of log records that failed to be processed by the receiver due to internal errors. [Alpha]"), - metric.WithUnit("{records}"), + metric.WithUnit("{record}"), ) errs = errors.Join(errs, err) builder.ReceiverFailedMetricPoints, err = builder.meter.Int64Counter( "otelcol_receiver_failed_metric_points", metric.WithDescription("The number of metric points that failed to be processed by the receiver due to internal errors. [Alpha]"), - metric.WithUnit("{datapoints}"), + metric.WithUnit("{datapoint}"), + ) + errs = errors.Join(errs, err) + builder.ReceiverFailedProfileSamples, err = builder.meter.Int64Counter( + "otelcol_receiver_failed_profile_samples", + metric.WithDescription("The number of profile samples that failed to be processed by the receiver due to internal errors. [Alpha]"), + metric.WithUnit("{sample}"), ) errs = errors.Join(errs, err) builder.ReceiverFailedSpans, err = builder.meter.Int64Counter( "otelcol_receiver_failed_spans", metric.WithDescription("The number of spans that failed to be processed by the receiver due to internal errors. [Alpha]"), - metric.WithUnit("{spans}"), + metric.WithUnit("{span}"), ) errs = errors.Join(errs, err) builder.ReceiverRefusedLogRecords, err = builder.meter.Int64Counter( "otelcol_receiver_refused_log_records", metric.WithDescription("Number of log records that could not be pushed into the pipeline. [Alpha]"), - metric.WithUnit("{records}"), + metric.WithUnit("{record}"), ) errs = errors.Join(errs, err) builder.ReceiverRefusedMetricPoints, err = builder.meter.Int64Counter( "otelcol_receiver_refused_metric_points", metric.WithDescription("Number of metric points that could not be pushed into the pipeline. [Alpha]"), - metric.WithUnit("{datapoints}"), + metric.WithUnit("{datapoint}"), + ) + errs = errors.Join(errs, err) + builder.ReceiverRefusedProfileSamples, err = builder.meter.Int64Counter( + "otelcol_receiver_refused_profile_samples", + metric.WithDescription("Number of profile samples that could not be pushed into the pipeline. [Alpha]"), + metric.WithUnit("{sample}"), ) errs = errors.Join(errs, err) builder.ReceiverRefusedSpans, err = builder.meter.Int64Counter( "otelcol_receiver_refused_spans", metric.WithDescription("Number of spans that could not be pushed into the pipeline. [Alpha]"), - metric.WithUnit("{spans}"), + metric.WithUnit("{span}"), ) errs = errors.Join(errs, err) builder.ReceiverRequests, err = builder.meter.Int64Counter( "otelcol_receiver_requests", metric.WithDescription("The number of requests performed. [Alpha]"), - metric.WithUnit("{requests}"), + metric.WithUnit("{request}"), ) errs = errors.Join(errs, err) return &builder, errs diff --git a/receiver/receiverhelper/internal/metadatatest/generated_telemetrytest.go b/receiver/receiverhelper/internal/metadatatest/generated_telemetrytest.go index d2ad658b53a3..cd435bd19288 100644 --- a/receiver/receiverhelper/internal/metadatatest/generated_telemetrytest.go +++ b/receiver/receiverhelper/internal/metadatatest/generated_telemetrytest.go @@ -16,7 +16,7 @@ func AssertEqualReceiverAcceptedLogRecords(t *testing.T, tt *componenttest.Telem want := metricdata.Metrics{ Name: "otelcol_receiver_accepted_log_records", Description: "Number of log records successfully pushed into the pipeline. [Alpha]", - Unit: "{records}", + Unit: "{record}", Data: metricdata.Sum[int64]{ Temporality: metricdata.CumulativeTemporality, IsMonotonic: true, @@ -32,7 +32,7 @@ func AssertEqualReceiverAcceptedMetricPoints(t *testing.T, tt *componenttest.Tel want := metricdata.Metrics{ Name: "otelcol_receiver_accepted_metric_points", Description: "Number of metric points successfully pushed into the pipeline. [Alpha]", - Unit: "{datapoints}", + Unit: "{datapoint}", Data: metricdata.Sum[int64]{ Temporality: metricdata.CumulativeTemporality, IsMonotonic: true, @@ -44,11 +44,27 @@ func AssertEqualReceiverAcceptedMetricPoints(t *testing.T, tt *componenttest.Tel metricdatatest.AssertEqual(t, want, got, opts...) } +func AssertEqualReceiverAcceptedProfileSamples(t *testing.T, tt *componenttest.Telemetry, dps []metricdata.DataPoint[int64], opts ...metricdatatest.Option) { + want := metricdata.Metrics{ + Name: "otelcol_receiver_accepted_profile_samples", + Description: "Number of profile samples successfully pushed into the pipeline. [Alpha]", + Unit: "{sample}", + Data: metricdata.Sum[int64]{ + Temporality: metricdata.CumulativeTemporality, + IsMonotonic: true, + DataPoints: dps, + }, + } + got, err := tt.GetMetric("otelcol_receiver_accepted_profile_samples") + require.NoError(t, err) + metricdatatest.AssertEqual(t, want, got, opts...) +} + func AssertEqualReceiverAcceptedSpans(t *testing.T, tt *componenttest.Telemetry, dps []metricdata.DataPoint[int64], opts ...metricdatatest.Option) { want := metricdata.Metrics{ Name: "otelcol_receiver_accepted_spans", Description: "Number of spans successfully pushed into the pipeline. [Alpha]", - Unit: "{spans}", + Unit: "{span}", Data: metricdata.Sum[int64]{ Temporality: metricdata.CumulativeTemporality, IsMonotonic: true, @@ -64,7 +80,7 @@ func AssertEqualReceiverFailedLogRecords(t *testing.T, tt *componenttest.Telemet want := metricdata.Metrics{ Name: "otelcol_receiver_failed_log_records", Description: "The number of log records that failed to be processed by the receiver due to internal errors. [Alpha]", - Unit: "{records}", + Unit: "{record}", Data: metricdata.Sum[int64]{ Temporality: metricdata.CumulativeTemporality, IsMonotonic: true, @@ -80,7 +96,7 @@ func AssertEqualReceiverFailedMetricPoints(t *testing.T, tt *componenttest.Telem want := metricdata.Metrics{ Name: "otelcol_receiver_failed_metric_points", Description: "The number of metric points that failed to be processed by the receiver due to internal errors. [Alpha]", - Unit: "{datapoints}", + Unit: "{datapoint}", Data: metricdata.Sum[int64]{ Temporality: metricdata.CumulativeTemporality, IsMonotonic: true, @@ -92,11 +108,27 @@ func AssertEqualReceiverFailedMetricPoints(t *testing.T, tt *componenttest.Telem metricdatatest.AssertEqual(t, want, got, opts...) } +func AssertEqualReceiverFailedProfileSamples(t *testing.T, tt *componenttest.Telemetry, dps []metricdata.DataPoint[int64], opts ...metricdatatest.Option) { + want := metricdata.Metrics{ + Name: "otelcol_receiver_failed_profile_samples", + Description: "The number of profile samples that failed to be processed by the receiver due to internal errors. [Alpha]", + Unit: "{sample}", + Data: metricdata.Sum[int64]{ + Temporality: metricdata.CumulativeTemporality, + IsMonotonic: true, + DataPoints: dps, + }, + } + got, err := tt.GetMetric("otelcol_receiver_failed_profile_samples") + require.NoError(t, err) + metricdatatest.AssertEqual(t, want, got, opts...) +} + func AssertEqualReceiverFailedSpans(t *testing.T, tt *componenttest.Telemetry, dps []metricdata.DataPoint[int64], opts ...metricdatatest.Option) { want := metricdata.Metrics{ Name: "otelcol_receiver_failed_spans", Description: "The number of spans that failed to be processed by the receiver due to internal errors. [Alpha]", - Unit: "{spans}", + Unit: "{span}", Data: metricdata.Sum[int64]{ Temporality: metricdata.CumulativeTemporality, IsMonotonic: true, @@ -112,7 +144,7 @@ func AssertEqualReceiverRefusedLogRecords(t *testing.T, tt *componenttest.Teleme want := metricdata.Metrics{ Name: "otelcol_receiver_refused_log_records", Description: "Number of log records that could not be pushed into the pipeline. [Alpha]", - Unit: "{records}", + Unit: "{record}", Data: metricdata.Sum[int64]{ Temporality: metricdata.CumulativeTemporality, IsMonotonic: true, @@ -128,7 +160,7 @@ func AssertEqualReceiverRefusedMetricPoints(t *testing.T, tt *componenttest.Tele want := metricdata.Metrics{ Name: "otelcol_receiver_refused_metric_points", Description: "Number of metric points that could not be pushed into the pipeline. [Alpha]", - Unit: "{datapoints}", + Unit: "{datapoint}", Data: metricdata.Sum[int64]{ Temporality: metricdata.CumulativeTemporality, IsMonotonic: true, @@ -140,11 +172,27 @@ func AssertEqualReceiverRefusedMetricPoints(t *testing.T, tt *componenttest.Tele metricdatatest.AssertEqual(t, want, got, opts...) } +func AssertEqualReceiverRefusedProfileSamples(t *testing.T, tt *componenttest.Telemetry, dps []metricdata.DataPoint[int64], opts ...metricdatatest.Option) { + want := metricdata.Metrics{ + Name: "otelcol_receiver_refused_profile_samples", + Description: "Number of profile samples that could not be pushed into the pipeline. [Alpha]", + Unit: "{sample}", + Data: metricdata.Sum[int64]{ + Temporality: metricdata.CumulativeTemporality, + IsMonotonic: true, + DataPoints: dps, + }, + } + got, err := tt.GetMetric("otelcol_receiver_refused_profile_samples") + require.NoError(t, err) + metricdatatest.AssertEqual(t, want, got, opts...) +} + func AssertEqualReceiverRefusedSpans(t *testing.T, tt *componenttest.Telemetry, dps []metricdata.DataPoint[int64], opts ...metricdatatest.Option) { want := metricdata.Metrics{ Name: "otelcol_receiver_refused_spans", Description: "Number of spans that could not be pushed into the pipeline. [Alpha]", - Unit: "{spans}", + Unit: "{span}", Data: metricdata.Sum[int64]{ Temporality: metricdata.CumulativeTemporality, IsMonotonic: true, @@ -160,7 +208,7 @@ func AssertEqualReceiverRequests(t *testing.T, tt *componenttest.Telemetry, dps want := metricdata.Metrics{ Name: "otelcol_receiver_requests", Description: "The number of requests performed. [Alpha]", - Unit: "{requests}", + Unit: "{request}", Data: metricdata.Sum[int64]{ Temporality: metricdata.CumulativeTemporality, IsMonotonic: true, diff --git a/receiver/receiverhelper/internal/metadatatest/generated_telemetrytest_test.go b/receiver/receiverhelper/internal/metadatatest/generated_telemetrytest_test.go index e34c4eceb60c..1726f12f62e7 100644 --- a/receiver/receiverhelper/internal/metadatatest/generated_telemetrytest_test.go +++ b/receiver/receiverhelper/internal/metadatatest/generated_telemetrytest_test.go @@ -21,12 +21,15 @@ func TestSetupTelemetry(t *testing.T) { defer tb.Shutdown() tb.ReceiverAcceptedLogRecords.Add(context.Background(), 1) tb.ReceiverAcceptedMetricPoints.Add(context.Background(), 1) + tb.ReceiverAcceptedProfileSamples.Add(context.Background(), 1) tb.ReceiverAcceptedSpans.Add(context.Background(), 1) tb.ReceiverFailedLogRecords.Add(context.Background(), 1) tb.ReceiverFailedMetricPoints.Add(context.Background(), 1) + tb.ReceiverFailedProfileSamples.Add(context.Background(), 1) tb.ReceiverFailedSpans.Add(context.Background(), 1) tb.ReceiverRefusedLogRecords.Add(context.Background(), 1) tb.ReceiverRefusedMetricPoints.Add(context.Background(), 1) + tb.ReceiverRefusedProfileSamples.Add(context.Background(), 1) tb.ReceiverRefusedSpans.Add(context.Background(), 1) tb.ReceiverRequests.Add(context.Background(), 1) AssertEqualReceiverAcceptedLogRecords(t, testTel, @@ -35,6 +38,9 @@ func TestSetupTelemetry(t *testing.T) { AssertEqualReceiverAcceptedMetricPoints(t, testTel, []metricdata.DataPoint[int64]{{Value: 1}}, metricdatatest.IgnoreTimestamp()) + AssertEqualReceiverAcceptedProfileSamples(t, testTel, + []metricdata.DataPoint[int64]{{Value: 1}}, + metricdatatest.IgnoreTimestamp()) AssertEqualReceiverAcceptedSpans(t, testTel, []metricdata.DataPoint[int64]{{Value: 1}}, metricdatatest.IgnoreTimestamp()) @@ -44,6 +50,9 @@ func TestSetupTelemetry(t *testing.T) { AssertEqualReceiverFailedMetricPoints(t, testTel, []metricdata.DataPoint[int64]{{Value: 1}}, metricdatatest.IgnoreTimestamp()) + AssertEqualReceiverFailedProfileSamples(t, testTel, + []metricdata.DataPoint[int64]{{Value: 1}}, + metricdatatest.IgnoreTimestamp()) AssertEqualReceiverFailedSpans(t, testTel, []metricdata.DataPoint[int64]{{Value: 1}}, metricdatatest.IgnoreTimestamp()) @@ -53,6 +62,9 @@ func TestSetupTelemetry(t *testing.T) { AssertEqualReceiverRefusedMetricPoints(t, testTel, []metricdata.DataPoint[int64]{{Value: 1}}, metricdatatest.IgnoreTimestamp()) + AssertEqualReceiverRefusedProfileSamples(t, testTel, + []metricdata.DataPoint[int64]{{Value: 1}}, + metricdatatest.IgnoreTimestamp()) AssertEqualReceiverRefusedSpans(t, testTel, []metricdata.DataPoint[int64]{{Value: 1}}, metricdatatest.IgnoreTimestamp()) diff --git a/receiver/receiverhelper/internal/obsmetrics.go b/receiver/receiverhelper/internal/obsmetrics.go index c44aa2df47ad..79d335d5cdc0 100644 --- a/receiver/receiverhelper/internal/obsmetrics.go +++ b/receiver/receiverhelper/internal/obsmetrics.go @@ -38,7 +38,15 @@ const ( // FailedLogRecordsKey used to identify log records failed to be processed by the Collector. FailedLogRecordsKey = "failed_log_records" + // AcceptedProfileSamplesKey used to identify profile samples accepted by the Collector. + AcceptedProfileSamplesKey = "accepted_profile_samples" + // RefusedProfileSamplesKey used to identify profile samples refused (ie.: not ingested) by the Collector. + RefusedProfileSamplesKey = "refused_profile_samples" + // FailedProfileSamplesKey used to identify profile samples failed to be processed by the Collector. + FailedProfileSamplesKey = "failed_profile_samples" + ReceiveTraceDataOperationSuffix = SpanNameSep + "TraceDataReceived" ReceiverMetricsOperationSuffix = SpanNameSep + "MetricsReceived" ReceiverLogsOperationSuffix = SpanNameSep + "LogsReceived" + ReceiverProfilesOperationSuffix = SpanNameSep + "ProfilesReceived" ) diff --git a/receiver/receiverhelper/metadata.yaml b/receiver/receiverhelper/metadata.yaml index e5854f996b53..d5d592444a16 100644 --- a/receiver/receiverhelper/metadata.yaml +++ b/receiver/receiverhelper/metadata.yaml @@ -9,91 +9,105 @@ telemetry: metrics: receiver_accepted_log_records: enabled: true - stability: - level: alpha + stability: alpha description: Number of log records successfully pushed into the pipeline. - unit: "{records}" + unit: "{record}" sum: value_type: int monotonic: true receiver_accepted_metric_points: - stability: - level: alpha + stability: alpha enabled: true description: Number of metric points successfully pushed into the pipeline. - unit: "{datapoints}" + unit: "{datapoint}" + sum: + value_type: int + monotonic: true + receiver_accepted_profile_samples: + enabled: true + stability: alpha + description: Number of profile samples successfully pushed into the pipeline. + unit: "{sample}" sum: value_type: int monotonic: true receiver_accepted_spans: enabled: true - stability: - level: alpha + stability: alpha description: Number of spans successfully pushed into the pipeline. - unit: "{spans}" + unit: "{span}" sum: value_type: int monotonic: true receiver_failed_log_records: enabled: true - stability: - level: alpha + stability: alpha description: The number of log records that failed to be processed by the receiver due to internal errors. - unit: "{records}" + unit: "{record}" sum: value_type: int monotonic: true receiver_failed_metric_points: enabled: true - stability: - level: alpha + stability: alpha description: The number of metric points that failed to be processed by the receiver due to internal errors. - unit: "{datapoints}" + unit: "{datapoint}" + sum: + value_type: int + monotonic: true + receiver_failed_profile_samples: + enabled: true + stability: alpha + description: The number of profile samples that failed to be processed by the receiver due to internal errors. + unit: "{sample}" sum: value_type: int monotonic: true receiver_failed_spans: enabled: true - stability: - level: alpha + stability: alpha description: The number of spans that failed to be processed by the receiver due to internal errors. - unit: "{spans}" + unit: "{span}" sum: value_type: int monotonic: true receiver_refused_log_records: enabled: true - stability: - level: alpha + stability: alpha description: Number of log records that could not be pushed into the pipeline. - unit: "{records}" + unit: "{record}" sum: value_type: int monotonic: true receiver_refused_metric_points: enabled: true - stability: - level: alpha + stability: alpha description: Number of metric points that could not be pushed into the pipeline. - unit: "{datapoints}" + unit: "{datapoint}" + sum: + value_type: int + monotonic: true + receiver_refused_profile_samples: + enabled: true + stability: alpha + description: Number of profile samples that could not be pushed into the pipeline. + unit: "{sample}" sum: value_type: int monotonic: true receiver_refused_spans: enabled: true - stability: - level: alpha + stability: alpha description: Number of spans that could not be pushed into the pipeline. - unit: "{spans}" + unit: "{span}" sum: value_type: int monotonic: true receiver_requests: enabled: true - stability: - level: alpha + stability: alpha description: The number of requests performed. - unit: "{requests}" + unit: "{request}" sum: value_type: int monotonic: true @@ -107,3 +121,10 @@ attributes: - success - refused - failure + +feature_gates: + - id: receiverhelper.newReceiverMetrics + description: 'Controls whether receivers emit new metrics and span attributes to distinguish downstream errors from internal errors. This is a breaking change for the semantics of the otelcol_receiver_refused_metric_points, otelcol_receiver_refused_log_records and otelcol_receiver_refused_spans.' + stage: alpha + from_version: 'v0.138.0' + reference_url: 'https://github.com/open-telemetry/opentelemetry-collector/pull/12802' diff --git a/receiver/receiverhelper/obsreport.go b/receiver/receiverhelper/obsreport.go index eb7fa68043a3..d402597f2fc2 100644 --- a/receiver/receiverhelper/obsreport.go +++ b/receiver/receiverhelper/obsreport.go @@ -16,6 +16,7 @@ import ( "go.opentelemetry.io/collector/component" "go.opentelemetry.io/collector/consumer/consumererror" "go.opentelemetry.io/collector/pipeline" + "go.opentelemetry.io/collector/pipeline/xpipeline" "go.opentelemetry.io/collector/receiver" "go.opentelemetry.io/collector/receiver/receiverhelper/internal" "go.opentelemetry.io/collector/receiver/receiverhelper/internal/metadata" @@ -126,6 +127,24 @@ func (rec *ObsReport) EndMetricsOp( rec.endOp(receiverCtx, format, numReceivedPoints, err, pipeline.SignalMetrics) } +// StartProfilesOp is called when a request is received from a client. +// The returned context should be used in other calls to the obsreport functions +// dealing with the same receive operation. +func (rec *ObsReport) StartProfilesOp(operationCtx context.Context) context.Context { + return rec.startOp(operationCtx, internal.ReceiverProfilesOperationSuffix) +} + +// EndProfilesOp completes the receive operation that was started with +// StartProfilesOp. +func (rec *ObsReport) EndProfilesOp( + receiverCtx context.Context, + format string, + numReceivedProfileSamples int, + err error, +) { + rec.endOp(receiverCtx, format, numReceivedProfileSamples, err, xpipeline.SignalProfiles) +} + // startOp creates the span used to trace the operation. Returning // the updated context with the created span. func (rec *ObsReport) startOp(receiverCtx context.Context, operationSuffix string) context.Context { @@ -165,7 +184,7 @@ func (rec *ObsReport) endOp( if err != nil { numAccepted = 0 // If gate is enabled, we distinguish between refused and failed. - if NewReceiverMetricsGate.IsEnabled() { + if metadata.ReceiverhelperNewReceiverMetricsFeatureGate.IsEnabled() { if consumererror.IsDownstream(err) { numRefused = numReceivedItems } else { @@ -182,7 +201,7 @@ func (rec *ObsReport) endOp( rec.recordMetrics(receiverCtx, signal, numAccepted, numRefused, numFailedErrors) // The new otelcol_receiver_requests metric is only emitted when the feature gate is enabled. - if NewReceiverMetricsGate.IsEnabled() { + if metadata.ReceiverhelperNewReceiverMetricsFeatureGate.IsEnabled() { var outcome string switch { case err == nil: @@ -211,6 +230,10 @@ func (rec *ObsReport) endOp( acceptedItemsKey = internal.AcceptedLogRecordsKey refusedItemsKey = internal.RefusedLogRecordsKey failedItemsKey = internal.FailedLogRecordsKey + case xpipeline.SignalProfiles: + acceptedItemsKey = internal.AcceptedProfileSamplesKey + refusedItemsKey = internal.RefusedProfileSamplesKey + failedItemsKey = internal.FailedProfileSamplesKey } span.SetAttributes( @@ -241,6 +264,10 @@ func (rec *ObsReport) recordMetrics(receiverCtx context.Context, signal pipeline acceptedMeasure = rec.telemetryBuilder.ReceiverAcceptedLogRecords refusedMeasure = rec.telemetryBuilder.ReceiverRefusedLogRecords failedMeasure = rec.telemetryBuilder.ReceiverFailedLogRecords + case xpipeline.SignalProfiles: + acceptedMeasure = rec.telemetryBuilder.ReceiverAcceptedProfileSamples + refusedMeasure = rec.telemetryBuilder.ReceiverRefusedProfileSamples + failedMeasure = rec.telemetryBuilder.ReceiverFailedProfileSamples } acceptedMeasure.Add(receiverCtx, int64(numAccepted), rec.otelAttrs) diff --git a/receiver/receiverhelper/obsreport_test.go b/receiver/receiverhelper/obsreport_test.go index 47a99981c983..6195ea048917 100644 --- a/receiver/receiverhelper/obsreport_test.go +++ b/receiver/receiverhelper/obsreport_test.go @@ -21,6 +21,7 @@ import ( "go.opentelemetry.io/collector/featuregate" "go.opentelemetry.io/collector/receiver" "go.opentelemetry.io/collector/receiver/receiverhelper/internal" + "go.opentelemetry.io/collector/receiver/receiverhelper/internal/metadata" "go.opentelemetry.io/collector/receiver/receiverhelper/internal/metadatatest" ) @@ -41,9 +42,9 @@ type testParams struct { } func TestReceiveTraceDataOp(t *testing.T) { - originalState := NewReceiverMetricsGate.IsEnabled() + originalState := metadata.ReceiverhelperNewReceiverMetricsFeatureGate.IsEnabled() t.Cleanup(func() { - require.NoError(t, featuregate.GlobalRegistry().Set(NewReceiverMetricsGate.ID(), originalState)) + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.ReceiverhelperNewReceiverMetricsFeatureGate.ID(), originalState)) }) for _, tc := range []struct { @@ -51,7 +52,7 @@ func TestReceiveTraceDataOp(t *testing.T) { enabled bool }{{"gate_enabled", true}, {"gate_disabled", false}} { t.Run(tc.name, func(t *testing.T) { - require.NoError(t, featuregate.GlobalRegistry().Set(NewReceiverMetricsGate.ID(), tc.enabled)) + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.ReceiverhelperNewReceiverMetricsFeatureGate.ID(), tc.enabled)) testTelemetry(t, func(t *testing.T, tt *componenttest.Telemetry) { parentCtx, parentSpan := tt.NewTelemetrySettings().TracerProvider.Tracer("test").Start(context.Background(), t.Name()) defer parentSpan.End() @@ -164,9 +165,9 @@ func TestReceiveTraceDataOp(t *testing.T) { } func TestReceiveLogsOp(t *testing.T) { - originalState := NewReceiverMetricsGate.IsEnabled() + originalState := metadata.ReceiverhelperNewReceiverMetricsFeatureGate.IsEnabled() t.Cleanup(func() { - require.NoError(t, featuregate.GlobalRegistry().Set(NewReceiverMetricsGate.ID(), originalState)) + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.ReceiverhelperNewReceiverMetricsFeatureGate.ID(), originalState)) }) for _, tc := range []struct { @@ -174,7 +175,7 @@ func TestReceiveLogsOp(t *testing.T) { enabled bool }{{"gate_enabled", true}, {"gate_disabled", false}} { t.Run(tc.name, func(t *testing.T) { - require.NoError(t, featuregate.GlobalRegistry().Set(NewReceiverMetricsGate.ID(), tc.enabled)) + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.ReceiverhelperNewReceiverMetricsFeatureGate.ID(), tc.enabled)) testTelemetry(t, func(t *testing.T, tt *componenttest.Telemetry) { parentCtx, parentSpan := tt.NewTelemetrySettings().TracerProvider.Tracer("test").Start(context.Background(), t.Name()) defer parentSpan.End() @@ -286,9 +287,9 @@ func TestReceiveLogsOp(t *testing.T) { } func TestReceiveMetricsOp(t *testing.T) { - originalState := NewReceiverMetricsGate.IsEnabled() + originalState := metadata.ReceiverhelperNewReceiverMetricsFeatureGate.IsEnabled() t.Cleanup(func() { - require.NoError(t, featuregate.GlobalRegistry().Set(NewReceiverMetricsGate.ID(), originalState)) + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.ReceiverhelperNewReceiverMetricsFeatureGate.ID(), originalState)) }) for _, tc := range []struct { @@ -296,7 +297,7 @@ func TestReceiveMetricsOp(t *testing.T) { enabled bool }{{"gate_enabled", true}, {"gate_disabled", false}} { t.Run(tc.name, func(t *testing.T) { - require.NoError(t, featuregate.GlobalRegistry().Set(NewReceiverMetricsGate.ID(), tc.enabled)) + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.ReceiverhelperNewReceiverMetricsFeatureGate.ID(), tc.enabled)) testTelemetry(t, func(t *testing.T, tt *componenttest.Telemetry) { parentCtx, parentSpan := tt.NewTelemetrySettings().TracerProvider.Tracer("test").Start(context.Background(), t.Name()) defer parentSpan.End() @@ -409,10 +410,132 @@ func TestReceiveMetricsOp(t *testing.T) { } } +func TestReceiveProfilesOp(t *testing.T) { + originalState := metadata.ReceiverhelperNewReceiverMetricsFeatureGate.IsEnabled() + t.Cleanup(func() { + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.ReceiverhelperNewReceiverMetricsFeatureGate.ID(), originalState)) + }) + + for _, tc := range []struct { + name string + enabled bool + }{{"gate_enabled", true}, {"gate_disabled", false}} { + t.Run(tc.name, func(t *testing.T) { + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.ReceiverhelperNewReceiverMetricsFeatureGate.ID(), tc.enabled)) + testTelemetry(t, func(t *testing.T, tt *componenttest.Telemetry) { + parentCtx, parentSpan := tt.NewTelemetrySettings().TracerProvider.Tracer("test").Start(context.Background(), t.Name()) + defer parentSpan.End() + + params := []testParams{ + {items: 13, err: consumererror.NewDownstream(errFake)}, + {items: 42, err: nil}, + {items: 7, err: errors.New("non-downstream error")}, + } + for i, param := range params { + rec, err := newReceiver(ObsReportSettings{ + ReceiverID: receiverID, + Transport: transport, + ReceiverCreateSettings: receiver.Settings{ID: receiverID, TelemetrySettings: tt.NewTelemetrySettings(), BuildInfo: component.NewDefaultBuildInfo()}, + }) + require.NoError(t, err) + ctx := rec.StartProfilesOp(parentCtx) + assert.NotNil(t, ctx) + rec.EndProfilesOp(ctx, format, params[i].items, param.err) + } + + spans := tt.SpanRecorder.Ended() + require.Len(t, spans, len(params)) + + var acceptedSamples, refusedSamples, failedSamples int + for i, span := range spans { + assert.Equal(t, "receiver/"+receiverID.String()+"/ProfilesReceived", span.Name()) + err := params[i].err + if err == nil { + acceptedSamples += params[i].items + require.Contains(t, span.Attributes(), attribute.KeyValue{Key: internal.AcceptedProfileSamplesKey, Value: attribute.Int64Value(int64(params[i].items))}) + require.Contains(t, span.Attributes(), attribute.KeyValue{Key: internal.RefusedProfileSamplesKey, Value: attribute.Int64Value(0)}) + require.Contains(t, span.Attributes(), attribute.KeyValue{Key: internal.FailedProfileSamplesKey, Value: attribute.Int64Value(0)}) + assert.Equal(t, codes.Unset, span.Status().Code) + } else { + isDownstream := consumererror.IsDownstream(err) + if !tc.enabled || (tc.enabled && isDownstream) { + refusedSamples += params[i].items + require.Contains(t, span.Attributes(), attribute.KeyValue{Key: internal.RefusedProfileSamplesKey, Value: attribute.Int64Value(int64(params[i].items))}) + require.Contains(t, span.Attributes(), attribute.KeyValue{Key: internal.FailedProfileSamplesKey, Value: attribute.Int64Value(0)}) + } else { + failedSamples += params[i].items + require.Contains(t, span.Attributes(), attribute.KeyValue{Key: internal.RefusedProfileSamplesKey, Value: attribute.Int64Value(0)}) + require.Contains(t, span.Attributes(), attribute.KeyValue{Key: internal.FailedProfileSamplesKey, Value: attribute.Int64Value(int64(params[i].items))}) + } + require.Contains(t, span.Attributes(), attribute.KeyValue{Key: internal.AcceptedProfileSamplesKey, Value: attribute.Int64Value(0)}) + assert.Equal(t, codes.Error, span.Status().Code) + assert.Equal(t, err.Error(), span.Status().Description) + } + } + metadatatest.AssertEqualReceiverAcceptedProfileSamples(t, tt, + []metricdata.DataPoint[int64]{ + { + Attributes: attribute.NewSet( + attribute.String(internal.ReceiverKey, receiverID.String()), + attribute.String(internal.TransportKey, transport)), + Value: int64(acceptedSamples), + }, + }, metricdatatest.IgnoreTimestamp(), metricdatatest.IgnoreExemplars()) + metadatatest.AssertEqualReceiverRefusedProfileSamples(t, tt, + []metricdata.DataPoint[int64]{ + { + Attributes: attribute.NewSet( + attribute.String(internal.ReceiverKey, receiverID.String()), + attribute.String(internal.TransportKey, transport)), + Value: int64(refusedSamples), + }, + }, metricdatatest.IgnoreTimestamp(), metricdatatest.IgnoreExemplars()) + metadatatest.AssertEqualReceiverFailedProfileSamples(t, tt, + []metricdata.DataPoint[int64]{ + { + Attributes: attribute.NewSet( + attribute.String(internal.ReceiverKey, receiverID.String()), + attribute.String(internal.TransportKey, transport)), + Value: int64(failedSamples), + }, + }, metricdatatest.IgnoreTimestamp(), metricdatatest.IgnoreExemplars()) + + // Assert otelcol_receiver_requests metric with outcome attribute + if tc.enabled { + outcomes := make(map[string]int64) + for _, param := range params { + var outcome string + switch { + case param.err == nil: + outcome = "success" + case consumererror.IsDownstream(param.err): + outcome = "refused" + default: + outcome = "failure" + } + outcomes[outcome]++ + } + var expectedRequests []metricdata.DataPoint[int64] + for outcome, count := range outcomes { + expectedRequests = append(expectedRequests, metricdata.DataPoint[int64]{ + Attributes: attribute.NewSet( + attribute.String(internal.ReceiverKey, receiverID.String()), + attribute.String(internal.TransportKey, transport), + attribute.String("outcome", outcome)), + Value: count, + }) + } + metadatatest.AssertEqualReceiverRequests(t, tt, expectedRequests, metricdatatest.IgnoreTimestamp(), metricdatatest.IgnoreExemplars()) + } + }) + }) + } +} + func TestReceiveWithLongLivedCtx(t *testing.T) { - originalState := NewReceiverMetricsGate.IsEnabled() + originalState := metadata.ReceiverhelperNewReceiverMetricsFeatureGate.IsEnabled() t.Cleanup(func() { - require.NoError(t, featuregate.GlobalRegistry().Set(NewReceiverMetricsGate.ID(), originalState)) + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.ReceiverhelperNewReceiverMetricsFeatureGate.ID(), originalState)) }) for _, tc := range []struct { @@ -420,7 +543,7 @@ func TestReceiveWithLongLivedCtx(t *testing.T) { enabled bool }{{"gate_enabled", true}, {"gate_disabled", false}} { t.Run(tc.name, func(t *testing.T) { - require.NoError(t, featuregate.GlobalRegistry().Set(NewReceiverMetricsGate.ID(), tc.enabled)) + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.ReceiverhelperNewReceiverMetricsFeatureGate.ID(), tc.enabled)) tt := componenttest.NewTelemetry() t.Cleanup(func() { require.NoError(t, tt.Shutdown(context.Background())) }) @@ -607,6 +730,49 @@ func TestCheckReceiverLogsViews(t *testing.T) { }, metricdatatest.IgnoreTimestamp(), metricdatatest.IgnoreExemplars()) } +func TestCheckReceiverProfilesViews(t *testing.T) { + tt := componenttest.NewTelemetry() + t.Cleanup(func() { require.NoError(t, tt.Shutdown(context.Background())) }) + + rec, err := NewObsReport(ObsReportSettings{ + ReceiverID: receiverID, + Transport: transport, + ReceiverCreateSettings: receiver.Settings{ID: receiverID, TelemetrySettings: tt.NewTelemetrySettings(), BuildInfo: component.NewDefaultBuildInfo()}, + }) + require.NoError(t, err) + ctx := rec.StartProfilesOp(context.Background()) + require.NotNil(t, ctx) + rec.EndProfilesOp(ctx, format, 7, nil) + + metadatatest.AssertEqualReceiverAcceptedProfileSamples(t, tt, + []metricdata.DataPoint[int64]{ + { + Attributes: attribute.NewSet( + attribute.String(internal.ReceiverKey, receiverID.String()), + attribute.String(internal.TransportKey, transport)), + Value: int64(7), + }, + }, metricdatatest.IgnoreTimestamp(), metricdatatest.IgnoreExemplars()) + metadatatest.AssertEqualReceiverRefusedProfileSamples(t, tt, + []metricdata.DataPoint[int64]{ + { + Attributes: attribute.NewSet( + attribute.String(internal.ReceiverKey, receiverID.String()), + attribute.String(internal.TransportKey, transport)), + Value: int64(0), + }, + }, metricdatatest.IgnoreTimestamp(), metricdatatest.IgnoreExemplars()) + metadatatest.AssertEqualReceiverFailedProfileSamples(t, tt, + []metricdata.DataPoint[int64]{ + { + Attributes: attribute.NewSet( + attribute.String(internal.ReceiverKey, receiverID.String()), + attribute.String(internal.TransportKey, transport)), + Value: int64(0), + }, + }, metricdatatest.IgnoreTimestamp(), metricdatatest.IgnoreExemplars()) +} + func testTelemetry(t *testing.T, testFunc func(t *testing.T, tt *componenttest.Telemetry)) { tt := componenttest.NewTelemetry() t.Cleanup(func() { require.NoError(t, tt.Shutdown(context.Background())) }) diff --git a/receiver/receivertest/contract_checker.go b/receiver/receivertest/contract_checker.go index 048130f73c8a..58c70c43672f 100644 --- a/receiver/receivertest/contract_checker.go +++ b/receiver/receivertest/contract_checker.go @@ -146,9 +146,7 @@ func checkConsumeContractScenario(params CheckConsumeContractParams, decisionFun // The total number of generator calls will be equal to params.GenerateCount. for range concurrency { - wg.Add(1) - go func() { - defer wg.Done() + wg.Go(func() { for atomic.AddInt64(&generatedIndex, 1) <= int64(params.GenerateCount) { ids := params.Generator.Generate() require.NotEmpty(params.T, ids) @@ -161,7 +159,7 @@ func checkConsumeContractScenario(params CheckConsumeContractParams, decisionFun // generated data set. require.Empty(params.T, duplicates) } - }() + }) } // Wait until all generator goroutines are done. diff --git a/receiver/receivertest/go.mod b/receiver/receivertest/go.mod index 6ce449c8a795..cdebd016cf2e 100644 --- a/receiver/receivertest/go.mod +++ b/receiver/receivertest/go.mod @@ -1,20 +1,20 @@ module go.opentelemetry.io/collector/receiver/receivertest -go 1.24.0 +go 1.25.0 require ( github.com/google/uuid v1.6.0 github.com/stretchr/testify v1.11.1 - go.opentelemetry.io/collector/component v1.46.0 - go.opentelemetry.io/collector/component/componenttest v0.140.0 - go.opentelemetry.io/collector/consumer v1.46.0 - go.opentelemetry.io/collector/consumer/consumererror v0.140.0 - go.opentelemetry.io/collector/consumer/consumertest v0.140.0 - go.opentelemetry.io/collector/consumer/xconsumer v0.140.0 - go.opentelemetry.io/collector/pdata v1.46.0 - go.opentelemetry.io/collector/pipeline v1.46.0 - go.opentelemetry.io/collector/receiver v1.46.0 - go.opentelemetry.io/collector/receiver/xreceiver v0.140.0 + go.opentelemetry.io/collector/component v1.54.0 + go.opentelemetry.io/collector/component/componenttest v0.148.0 + go.opentelemetry.io/collector/consumer v1.54.0 + go.opentelemetry.io/collector/consumer/consumererror v0.148.0 + go.opentelemetry.io/collector/consumer/consumertest v0.148.0 + go.opentelemetry.io/collector/consumer/xconsumer v0.148.0 + go.opentelemetry.io/collector/pdata v1.54.0 + go.opentelemetry.io/collector/pipeline v1.54.0 + go.opentelemetry.io/collector/receiver v1.54.0 + go.opentelemetry.io/collector/receiver/xreceiver v0.148.0 go.uber.org/goleak v1.3.0 ) @@ -23,25 +23,26 @@ require ( github.com/davecgh/go-spew v1.1.1 // indirect github.com/go-logr/logr v1.4.3 // indirect github.com/go-logr/stdr v1.2.2 // indirect - github.com/hashicorp/go-version v1.7.0 // indirect + github.com/hashicorp/go-version v1.8.0 // indirect github.com/json-iterator/go v1.1.12 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee // indirect github.com/pmezard/go-difflib v1.0.0 // indirect go.opentelemetry.io/auto/sdk v1.2.1 // indirect - go.opentelemetry.io/collector/featuregate v1.46.0 // indirect - go.opentelemetry.io/collector/pdata/pprofile v0.140.0 // indirect - go.opentelemetry.io/otel v1.40.0 // indirect - go.opentelemetry.io/otel/metric v1.40.0 // indirect + go.opentelemetry.io/collector/featuregate v1.54.0 // indirect + go.opentelemetry.io/collector/internal/componentalias v0.148.0 // indirect + go.opentelemetry.io/collector/pdata/pprofile v0.148.0 // indirect + go.opentelemetry.io/otel v1.42.0 // indirect + go.opentelemetry.io/otel/metric v1.42.0 // indirect go.opentelemetry.io/otel/sdk v1.40.0 // indirect go.opentelemetry.io/otel/sdk/metric v1.40.0 // indirect - go.opentelemetry.io/otel/trace v1.40.0 // indirect + go.opentelemetry.io/otel/trace v1.42.0 // indirect go.uber.org/multierr v1.11.0 // indirect go.uber.org/zap v1.27.1 // indirect - golang.org/x/sys v0.40.0 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20251022142026-3a174f9686a8 // indirect - google.golang.org/grpc v1.77.0 // indirect - google.golang.org/protobuf v1.36.10 // indirect + golang.org/x/sys v0.41.0 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20251222181119-0a764e51fe1b // indirect + google.golang.org/grpc v1.79.3 // indirect + google.golang.org/protobuf v1.36.11 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) @@ -72,3 +73,5 @@ replace go.opentelemetry.io/collector/consumer/consumertest => ../../consumer/co replace go.opentelemetry.io/collector/featuregate => ../../featuregate replace go.opentelemetry.io/collector/internal/testutil => ../../internal/testutil + +replace go.opentelemetry.io/collector/internal/componentalias => ../../internal/componentalias diff --git a/receiver/receivertest/go.sum b/receiver/receivertest/go.sum index 365c0691917d..bf8635e3851f 100644 --- a/receiver/receivertest/go.sum +++ b/receiver/receivertest/go.sum @@ -15,8 +15,8 @@ github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/hashicorp/go-version v1.7.0 h1:5tqGy27NaOTB8yJKUZELlFAS/LTKJkrmONwQKeRZfjY= -github.com/hashicorp/go-version v1.7.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= +github.com/hashicorp/go-version v1.8.0 h1:KAkNb1HAiZd1ukkxDFGmokVZe1Xy9HG6NUp+bPle2i4= +github.com/hashicorp/go-version v1.8.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= @@ -39,40 +39,40 @@ github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64= go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y= -go.opentelemetry.io/otel v1.40.0 h1:oA5YeOcpRTXq6NN7frwmwFR0Cn3RhTVZvXsP4duvCms= -go.opentelemetry.io/otel v1.40.0/go.mod h1:IMb+uXZUKkMXdPddhwAHm6UfOwJyh4ct1ybIlV14J0g= -go.opentelemetry.io/otel/metric v1.40.0 h1:rcZe317KPftE2rstWIBitCdVp89A2HqjkxR3c11+p9g= -go.opentelemetry.io/otel/metric v1.40.0/go.mod h1:ib/crwQH7N3r5kfiBZQbwrTge743UDc7DTFVZrrXnqc= +go.opentelemetry.io/otel v1.42.0 h1:lSQGzTgVR3+sgJDAU/7/ZMjN9Z+vUip7leaqBKy4sho= +go.opentelemetry.io/otel v1.42.0/go.mod h1:lJNsdRMxCUIWuMlVJWzecSMuNjE7dOYyWlqOXWkdqCc= +go.opentelemetry.io/otel/metric v1.42.0 h1:2jXG+3oZLNXEPfNmnpxKDeZsFI5o4J+nz6xUlaFdF/4= +go.opentelemetry.io/otel/metric v1.42.0/go.mod h1:RlUN/7vTU7Ao/diDkEpQpnz3/92J9ko05BIwxYa2SSI= go.opentelemetry.io/otel/sdk v1.40.0 h1:KHW/jUzgo6wsPh9At46+h4upjtccTmuZCFAc9OJ71f8= go.opentelemetry.io/otel/sdk v1.40.0/go.mod h1:Ph7EFdYvxq72Y8Li9q8KebuYUr2KoeyHx0DRMKrYBUE= go.opentelemetry.io/otel/sdk/metric v1.40.0 h1:mtmdVqgQkeRxHgRv4qhyJduP3fYJRMX4AtAlbuWdCYw= go.opentelemetry.io/otel/sdk/metric v1.40.0/go.mod h1:4Z2bGMf0KSK3uRjlczMOeMhKU2rhUqdWNoKcYrtcBPg= -go.opentelemetry.io/otel/trace v1.40.0 h1:WA4etStDttCSYuhwvEa8OP8I5EWu24lkOzp+ZYblVjw= -go.opentelemetry.io/otel/trace v1.40.0/go.mod h1:zeAhriXecNGP/s2SEG3+Y8X9ujcJOTqQ5RgdEJcawiA= -go.opentelemetry.io/proto/slim/otlp v1.9.0 h1:fPVMv8tP3TrsqlkH1HWYUpbCY9cAIemx184VGkS6vlE= -go.opentelemetry.io/proto/slim/otlp v1.9.0/go.mod h1:xXdeJJ90Gqyll+orzUkY4bOd2HECo5JofeoLpymVqdI= -go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.2.0 h1:o13nadWDNkH/quoDomDUClnQBpdQQ2Qqv0lQBjIXjE8= -go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.2.0/go.mod h1:Gyb6Xe7FTi/6xBHwMmngGoHqL0w29Y4eW8TGFzpefGA= -go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.2.0 h1:EiUYvtwu6PMrMHVjcPfnsG3v+ajPkbUeH+IL93+QYyk= -go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.2.0/go.mod h1:mUUHKFiN2SST3AhJ8XhJxEoeVW12oqfXog0Bo8W3Ec4= +go.opentelemetry.io/otel/trace v1.42.0 h1:OUCgIPt+mzOnaUTpOQcBiM/PLQ/Op7oq6g4LenLmOYY= +go.opentelemetry.io/otel/trace v1.42.0/go.mod h1:f3K9S+IFqnumBkKhRJMeaZeNk9epyhnCmQh/EysQCdc= +go.opentelemetry.io/proto/slim/otlp v1.10.0 h1:iR97Vs/ZDR+y9TfuP9b1XBtdPWeC+OMslIBmhcLU7jM= +go.opentelemetry.io/proto/slim/otlp v1.10.0/go.mod h1:lV9250stpjYLPNA5viFabIgP2QlUGRT1GdTgAf8SIUk= +go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.3.0 h1:RUF5rO0hAlgiJt1fzQVzcVs3vZVNHIcMLgOgG4rWNcQ= +go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.3.0/go.mod h1:I89cynRj8y+383o7tEQVg2SVA6SRgDVIouWPUVXjx0U= +go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.3.0 h1:CQvJSldHRUN6Z8jsUeYv8J0lXRvygALXIzsmAeCcZE0= +go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.3.0/go.mod h1:xSQ+mEfJe/GjK1LXEyVOoSI1N9JV9ZI923X5kup43W4= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= go.uber.org/zap v1.27.1 h1:08RqriUEv8+ArZRYSTXy1LeBScaMpVSTBhCeaZYfMYc= go.uber.org/zap v1.27.1/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= -golang.org/x/net v0.46.1-0.20251013234738-63d1a5100f82 h1:6/3JGEh1C88g7m+qzzTbl3A0FtsLguXieqofVLU/JAo= -golang.org/x/net v0.46.1-0.20251013234738-63d1a5100f82/go.mod h1:Q9BGdFy1y4nkUwiLvT5qtyhAnEHgnQ/zd8PfU6nc210= -golang.org/x/sys v0.40.0 h1:DBZZqJ2Rkml6QMQsZywtnjnnGvHza6BTfYFWY9kjEWQ= -golang.org/x/sys v0.40.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= -golang.org/x/text v0.30.0 h1:yznKA/E9zq54KzlzBEAWn1NXSQ8DIp/NYMy88xJjl4k= -golang.org/x/text v0.30.0/go.mod h1:yDdHFIX9t+tORqspjENWgzaCVXgk0yYnYuSZ8UzzBVM= -google.golang.org/genproto/googleapis/rpc v0.0.0-20251022142026-3a174f9686a8 h1:M1rk8KBnUsBDg1oPGHNCxG4vc1f49epmTO7xscSajMk= -google.golang.org/genproto/googleapis/rpc v0.0.0-20251022142026-3a174f9686a8/go.mod h1:7i2o+ce6H/6BluujYR+kqX3GKH+dChPTQU19wjRPiGk= -google.golang.org/grpc v1.77.0 h1:wVVY6/8cGA6vvffn+wWK5ToddbgdU3d8MNENr4evgXM= -google.golang.org/grpc v1.77.0/go.mod h1:z0BY1iVj0q8E1uSQCjL9cppRj+gnZjzDnzV0dHhrNig= -google.golang.org/protobuf v1.36.10 h1:AYd7cD/uASjIL6Q9LiTjz8JLcrh/88q5UObnmY3aOOE= -google.golang.org/protobuf v1.36.10/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= +golang.org/x/net v0.51.0 h1:94R/GTO7mt3/4wIKpcR5gkGmRLOuE/2hNGeWq/GBIFo= +golang.org/x/net v0.51.0/go.mod h1:aamm+2QF5ogm02fjy5Bb7CQ0WMt1/WVM7FtyaTLlA9Y= +golang.org/x/sys v0.41.0 h1:Ivj+2Cp/ylzLiEU89QhWblYnOE9zerudt9Ftecq2C6k= +golang.org/x/sys v0.41.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= +golang.org/x/text v0.34.0 h1:oL/Qq0Kdaqxa1KbNeMKwQq0reLCCaFtqu2eNuSeNHbk= +golang.org/x/text v0.34.0/go.mod h1:homfLqTYRFyVYemLBFl5GgL/DWEiH5wcsQ5gSh1yziA= +google.golang.org/genproto/googleapis/rpc v0.0.0-20251222181119-0a764e51fe1b h1:Mv8VFug0MP9e5vUxfBcE3vUkV6CImK3cMNMIDFjmzxU= +google.golang.org/genproto/googleapis/rpc v0.0.0-20251222181119-0a764e51fe1b/go.mod h1:j9x/tPzZkyxcgEFkiKEEGxfvyumM01BEtsW8xzOahRQ= +google.golang.org/grpc v1.79.3 h1:sybAEdRIEtvcD68Gx7dmnwjZKlyfuc61Dyo9pGXXkKE= +google.golang.org/grpc v1.79.3/go.mod h1:KmT0Kjez+0dde/v2j9vzwoAScgEPx/Bw1CYChhHLrHQ= +google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE= +google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= diff --git a/receiver/receivertest/metadata.yaml b/receiver/receivertest/metadata.yaml new file mode 100644 index 000000000000..8dacfec4bd33 --- /dev/null +++ b/receiver/receivertest/metadata.yaml @@ -0,0 +1,6 @@ +type: receiver/receivertest +github_project: open-telemetry/opentelemetry-collector + +status: + disable_codecov_badge: true + class: pkg diff --git a/receiver/xreceiver/go.mod b/receiver/xreceiver/go.mod index 1b492fcf2a8b..2663313a2c32 100644 --- a/receiver/xreceiver/go.mod +++ b/receiver/xreceiver/go.mod @@ -1,31 +1,32 @@ module go.opentelemetry.io/collector/receiver/xreceiver -go 1.24.0 +go 1.25.0 require ( github.com/stretchr/testify v1.11.1 - go.opentelemetry.io/collector/component v1.46.0 - go.opentelemetry.io/collector/consumer/consumertest v0.140.0 - go.opentelemetry.io/collector/consumer/xconsumer v0.140.0 - go.opentelemetry.io/collector/pipeline v1.46.0 - go.opentelemetry.io/collector/receiver v1.46.0 + go.opentelemetry.io/collector/component v1.54.0 + go.opentelemetry.io/collector/consumer/consumertest v0.148.0 + go.opentelemetry.io/collector/consumer/xconsumer v0.148.0 + go.opentelemetry.io/collector/internal/componentalias v0.148.0 + go.opentelemetry.io/collector/pipeline v1.54.0 + go.opentelemetry.io/collector/receiver v1.54.0 ) require ( github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/davecgh/go-spew v1.1.1 // indirect - github.com/hashicorp/go-version v1.7.0 // indirect + github.com/hashicorp/go-version v1.8.0 // indirect github.com/json-iterator/go v1.1.12 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee // indirect github.com/pmezard/go-difflib v1.0.0 // indirect - go.opentelemetry.io/collector/consumer v1.46.0 // indirect - go.opentelemetry.io/collector/featuregate v1.46.0 // indirect - go.opentelemetry.io/collector/pdata v1.46.0 // indirect - go.opentelemetry.io/collector/pdata/pprofile v0.140.0 // indirect - go.opentelemetry.io/otel v1.40.0 // indirect - go.opentelemetry.io/otel/metric v1.40.0 // indirect - go.opentelemetry.io/otel/trace v1.40.0 // indirect + go.opentelemetry.io/collector/consumer v1.54.0 // indirect + go.opentelemetry.io/collector/featuregate v1.54.0 // indirect + go.opentelemetry.io/collector/pdata v1.54.0 // indirect + go.opentelemetry.io/collector/pdata/pprofile v0.148.0 // indirect + go.opentelemetry.io/otel v1.42.0 // indirect + go.opentelemetry.io/otel/metric v1.42.0 // indirect + go.opentelemetry.io/otel/trace v1.42.0 // indirect go.uber.org/multierr v1.11.0 // indirect go.uber.org/zap v1.27.1 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect @@ -52,3 +53,5 @@ replace go.opentelemetry.io/collector/pipeline => ../../pipeline replace go.opentelemetry.io/collector/featuregate => ../../featuregate replace go.opentelemetry.io/collector/internal/testutil => ../../internal/testutil + +replace go.opentelemetry.io/collector/internal/componentalias => ../../internal/componentalias diff --git a/receiver/xreceiver/go.sum b/receiver/xreceiver/go.sum index 37d6edbc3764..1abfd0c69894 100644 --- a/receiver/xreceiver/go.sum +++ b/receiver/xreceiver/go.sum @@ -10,8 +10,8 @@ github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= -github.com/hashicorp/go-version v1.7.0 h1:5tqGy27NaOTB8yJKUZELlFAS/LTKJkrmONwQKeRZfjY= -github.com/hashicorp/go-version v1.7.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= +github.com/hashicorp/go-version v1.8.0 h1:KAkNb1HAiZd1ukkxDFGmokVZe1Xy9HG6NUp+bPle2i4= +github.com/hashicorp/go-version v1.8.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= @@ -34,26 +34,26 @@ github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64= go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y= -go.opentelemetry.io/otel v1.40.0 h1:oA5YeOcpRTXq6NN7frwmwFR0Cn3RhTVZvXsP4duvCms= -go.opentelemetry.io/otel v1.40.0/go.mod h1:IMb+uXZUKkMXdPddhwAHm6UfOwJyh4ct1ybIlV14J0g= -go.opentelemetry.io/otel/metric v1.40.0 h1:rcZe317KPftE2rstWIBitCdVp89A2HqjkxR3c11+p9g= -go.opentelemetry.io/otel/metric v1.40.0/go.mod h1:ib/crwQH7N3r5kfiBZQbwrTge743UDc7DTFVZrrXnqc= -go.opentelemetry.io/otel/trace v1.40.0 h1:WA4etStDttCSYuhwvEa8OP8I5EWu24lkOzp+ZYblVjw= -go.opentelemetry.io/otel/trace v1.40.0/go.mod h1:zeAhriXecNGP/s2SEG3+Y8X9ujcJOTqQ5RgdEJcawiA= -go.opentelemetry.io/proto/slim/otlp v1.9.0 h1:fPVMv8tP3TrsqlkH1HWYUpbCY9cAIemx184VGkS6vlE= -go.opentelemetry.io/proto/slim/otlp v1.9.0/go.mod h1:xXdeJJ90Gqyll+orzUkY4bOd2HECo5JofeoLpymVqdI= -go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.2.0 h1:o13nadWDNkH/quoDomDUClnQBpdQQ2Qqv0lQBjIXjE8= -go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.2.0/go.mod h1:Gyb6Xe7FTi/6xBHwMmngGoHqL0w29Y4eW8TGFzpefGA= -go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.2.0 h1:EiUYvtwu6PMrMHVjcPfnsG3v+ajPkbUeH+IL93+QYyk= -go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.2.0/go.mod h1:mUUHKFiN2SST3AhJ8XhJxEoeVW12oqfXog0Bo8W3Ec4= +go.opentelemetry.io/otel v1.42.0 h1:lSQGzTgVR3+sgJDAU/7/ZMjN9Z+vUip7leaqBKy4sho= +go.opentelemetry.io/otel v1.42.0/go.mod h1:lJNsdRMxCUIWuMlVJWzecSMuNjE7dOYyWlqOXWkdqCc= +go.opentelemetry.io/otel/metric v1.42.0 h1:2jXG+3oZLNXEPfNmnpxKDeZsFI5o4J+nz6xUlaFdF/4= +go.opentelemetry.io/otel/metric v1.42.0/go.mod h1:RlUN/7vTU7Ao/diDkEpQpnz3/92J9ko05BIwxYa2SSI= +go.opentelemetry.io/otel/trace v1.42.0 h1:OUCgIPt+mzOnaUTpOQcBiM/PLQ/Op7oq6g4LenLmOYY= +go.opentelemetry.io/otel/trace v1.42.0/go.mod h1:f3K9S+IFqnumBkKhRJMeaZeNk9epyhnCmQh/EysQCdc= +go.opentelemetry.io/proto/slim/otlp v1.10.0 h1:iR97Vs/ZDR+y9TfuP9b1XBtdPWeC+OMslIBmhcLU7jM= +go.opentelemetry.io/proto/slim/otlp v1.10.0/go.mod h1:lV9250stpjYLPNA5viFabIgP2QlUGRT1GdTgAf8SIUk= +go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.3.0 h1:RUF5rO0hAlgiJt1fzQVzcVs3vZVNHIcMLgOgG4rWNcQ= +go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.3.0/go.mod h1:I89cynRj8y+383o7tEQVg2SVA6SRgDVIouWPUVXjx0U= +go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.3.0 h1:CQvJSldHRUN6Z8jsUeYv8J0lXRvygALXIzsmAeCcZE0= +go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.3.0/go.mod h1:xSQ+mEfJe/GjK1LXEyVOoSI1N9JV9ZI923X5kup43W4= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= go.uber.org/zap v1.27.1 h1:08RqriUEv8+ArZRYSTXy1LeBScaMpVSTBhCeaZYfMYc= go.uber.org/zap v1.27.1/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= -google.golang.org/protobuf v1.36.10 h1:AYd7cD/uASjIL6Q9LiTjz8JLcrh/88q5UObnmY3aOOE= -google.golang.org/protobuf v1.36.10/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= +google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE= +google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= diff --git a/receiver/xreceiver/profiles.go b/receiver/xreceiver/receiver.go similarity index 75% rename from receiver/xreceiver/profiles.go rename to receiver/xreceiver/receiver.go index 8a912119ab27..9c0ce0e6a5ad 100644 --- a/receiver/xreceiver/profiles.go +++ b/receiver/xreceiver/receiver.go @@ -8,9 +8,9 @@ import ( "go.opentelemetry.io/collector/component" "go.opentelemetry.io/collector/consumer/xconsumer" + "go.opentelemetry.io/collector/internal/componentalias" "go.opentelemetry.io/collector/pipeline" "go.opentelemetry.io/collector/receiver" - "go.opentelemetry.io/collector/receiver/internal" ) // Profiles receiver receives profiles. @@ -44,18 +44,20 @@ type CreateProfilesFunc func(context.Context, receiver.Settings, component.Confi // FactoryOption apply changes to Factory. type FactoryOption interface { // applyOption applies the option. - applyOption(o *factoryOpts) + applyOption(o *factory) } // factoryOptionFunc is a FactoryOption created through a function. -type factoryOptionFunc func(*factoryOpts) +type factoryOptionFunc func(*factory) -func (f factoryOptionFunc) applyOption(o *factoryOpts) { +func (f factoryOptionFunc) applyOption(o *factory) { f(o) } type factory struct { receiver.Factory + componentalias.TypeAliasHolder + opts []receiver.FactoryOption createProfilesFunc CreateProfilesFunc profilesStabilityLevel component.StabilityLevel } @@ -68,52 +70,56 @@ func (f *factory) CreateProfiles(ctx context.Context, set receiver.Settings, cfg if f.createProfilesFunc == nil { return nil, pipeline.ErrSignalNotSupported } - if set.ID.Type() != f.Type() { - return nil, internal.ErrIDMismatch(set.ID, f.Type()) + if err := componentalias.ValidateComponentType(f.Factory, set.ID); err != nil { + return nil, err } return f.createProfilesFunc(ctx, set, cfg, next) } -type factoryOpts struct { - opts []receiver.FactoryOption - *factory -} - // WithTraces overrides the default "error not supported" implementation for Factory.CreateTraces and the default "undefined" stability level. func WithTraces(createTraces receiver.CreateTracesFunc, sl component.StabilityLevel) FactoryOption { - return factoryOptionFunc(func(o *factoryOpts) { + return factoryOptionFunc(func(o *factory) { o.opts = append(o.opts, receiver.WithTraces(createTraces, sl)) }) } // WithMetrics overrides the default "error not supported" implementation for Factory.CreateMetrics and the default "undefined" stability level. func WithMetrics(createMetrics receiver.CreateMetricsFunc, sl component.StabilityLevel) FactoryOption { - return factoryOptionFunc(func(o *factoryOpts) { + return factoryOptionFunc(func(o *factory) { o.opts = append(o.opts, receiver.WithMetrics(createMetrics, sl)) }) } // WithLogs overrides the default "error not supported" implementation for Factory.CreateLogs and the default "undefined" stability level. func WithLogs(createLogs receiver.CreateLogsFunc, sl component.StabilityLevel) FactoryOption { - return factoryOptionFunc(func(o *factoryOpts) { + return factoryOptionFunc(func(o *factory) { o.opts = append(o.opts, receiver.WithLogs(createLogs, sl)) }) } // WithProfiles overrides the default "error not supported" implementation for Factory.CreateProfiles and the default "undefined" stability level. func WithProfiles(createProfiles CreateProfilesFunc, sl component.StabilityLevel) FactoryOption { - return factoryOptionFunc(func(o *factoryOpts) { + return factoryOptionFunc(func(o *factory) { o.profilesStabilityLevel = sl o.createProfilesFunc = createProfiles }) } -// NewFactory returns a Factory. +// WithDeprecatedTypeAlias configures a deprecated type alias for the receiver. Only one alias is supported per receiver. +// When the alias is used in configuration, a deprecation warning is automatically logged. +func WithDeprecatedTypeAlias(alias component.Type) FactoryOption { + return factoryOptionFunc(func(o *factory) { + o.SetDeprecatedAlias(alias) + }) +} + +// NewFactory creates a wrapped receiver.Factory with experimental capabilities. func NewFactory(cfgType component.Type, createDefaultConfig component.CreateDefaultConfigFunc, options ...FactoryOption) Factory { - opts := factoryOpts{factory: &factory{}} + f := &factory{TypeAliasHolder: componentalias.NewTypeAliasHolder()} for _, opt := range options { - opt.applyOption(&opts) + opt.applyOption(f) } - opts.Factory = receiver.NewFactory(cfgType, createDefaultConfig, opts.opts...) - return opts.factory + f.Factory = receiver.NewFactory(cfgType, createDefaultConfig, f.opts...) + f.Factory.(componentalias.TypeAliasHolder).SetDeprecatedAlias(f.DeprecatedAlias()) + return f } diff --git a/receiver/xreceiver/receiver_test.go b/receiver/xreceiver/receiver_test.go index fb9b9c335618..fed7e6c844f0 100644 --- a/receiver/xreceiver/receiver_test.go +++ b/receiver/xreceiver/receiver_test.go @@ -13,6 +13,7 @@ import ( "go.opentelemetry.io/collector/component" "go.opentelemetry.io/collector/consumer/consumertest" "go.opentelemetry.io/collector/consumer/xconsumer" + "go.opentelemetry.io/collector/internal/componentalias" "go.opentelemetry.io/collector/receiver" "go.opentelemetry.io/collector/receiver/internal" ) @@ -53,3 +54,27 @@ type nopReceiver struct { func createProfiles(context.Context, receiver.Settings, component.Config, xconsumer.Profiles) (Profiles, error) { return nopInstance, nil } + +func TestNewFactoryWithDeprecatedAlias(t *testing.T) { + testType := component.MustNewType("newname") + aliasType := component.MustNewType("oldname") + defaultCfg := struct{}{} + + f := NewFactory( + testType, + func() component.Config { return &defaultCfg }, + WithProfiles(createProfiles, component.StabilityLevelAlpha), + WithDeprecatedTypeAlias(aliasType), + ) + + assert.Equal(t, testType, f.Type()) + assert.Equal(t, aliasType, f.(*factory).Factory.(componentalias.TypeAliasHolder).DeprecatedAlias()) + assert.EqualValues(t, &defaultCfg, f.CreateDefaultConfig()) + + _, err := f.CreateProfiles(context.Background(), receiver.Settings{ID: component.MustNewID("newname")}, &defaultCfg, consumertest.NewNop()) + require.NoError(t, err) + _, err = f.CreateProfiles(context.Background(), receiver.Settings{ID: component.MustNewID("oldname")}, &defaultCfg, consumertest.NewNop()) + require.NoError(t, err) + _, err = f.CreateProfiles(context.Background(), receiver.Settings{ID: component.MustNewID("wrongname")}, &defaultCfg, consumertest.NewNop()) + require.Error(t, err) +} diff --git a/renovate.json b/renovate.json index d6eb38a63749..b5e51f72681b 100644 --- a/renovate.json +++ b/renovate.json @@ -5,7 +5,7 @@ "dependencies" ], "constraints": { - "go": "1.24" + "go": "1.25" }, "extends": [ "config:recommended", @@ -86,8 +86,8 @@ "gomod" ], "groupName": "All google.golang.org packages", - "matchSourceUrls": [ - "https://google.golang.org{/,}**" + "matchPackageNames": [ + "google.golang.org{/,}**" ] }, { @@ -144,6 +144,6 @@ "prEditedNotification" ], "postUpdateOptions": [ - "gomodTidy", + "gomodTidy" ] } diff --git a/reports/distributions/contrib.yaml b/reports/distributions/contrib.yaml index 975550e1bdb2..4aeb5b314757 100644 --- a/reports/distributions/contrib.yaml +++ b/reports/distributions/contrib.yaml @@ -7,8 +7,8 @@ components: exporter: - debug - nop - - otlp - - otlphttp + - otlp_grpc + - otlp_http extension: - zpages pkg: diff --git a/reports/distributions/core.yaml b/reports/distributions/core.yaml index 109424b7decc..5be08be3ec95 100644 --- a/reports/distributions/core.yaml +++ b/reports/distributions/core.yaml @@ -7,8 +7,8 @@ components: exporter: - debug - nop - - otlp - - otlphttp + - otlp_grpc + - otlp_http extension: - zpages pkg: diff --git a/reports/distributions/k8s.yaml b/reports/distributions/k8s.yaml index 7b7844012440..e8ba1ead959d 100644 --- a/reports/distributions/k8s.yaml +++ b/reports/distributions/k8s.yaml @@ -7,8 +7,8 @@ components: exporter: - debug - nop - - otlp - - otlphttp + - otlp_grpc + - otlp_http extension: - zpages processor: diff --git a/reports/distributions/otlp.yaml b/reports/distributions/otlp.yaml index 1f62a8063d6c..4fecd644aacc 100644 --- a/reports/distributions/otlp.yaml +++ b/reports/distributions/otlp.yaml @@ -3,7 +3,7 @@ url: https://github.com/open-telemetry/opentelemetry-collector-releases/tree/mai maintainers: [] components: exporter: - - otlp - - otlphttp + - otlp_grpc + - otlp_http receiver: - otlp diff --git a/scraper/go.mod b/scraper/go.mod index 725684467ffb..94baf290404a 100644 --- a/scraper/go.mod +++ b/scraper/go.mod @@ -1,13 +1,13 @@ module go.opentelemetry.io/collector/scraper -go 1.24.0 +go 1.25.0 require ( github.com/stretchr/testify v1.11.1 - go.opentelemetry.io/collector/component v1.46.0 - go.opentelemetry.io/collector/component/componenttest v0.140.0 - go.opentelemetry.io/collector/pdata v1.46.0 - go.opentelemetry.io/collector/pipeline v1.46.0 + go.opentelemetry.io/collector/component v1.54.0 + go.opentelemetry.io/collector/component/componenttest v0.148.0 + go.opentelemetry.io/collector/pdata v1.54.0 + go.opentelemetry.io/collector/pipeline v1.54.0 go.uber.org/goleak v1.3.0 go.uber.org/multierr v1.11.0 ) @@ -18,20 +18,20 @@ require ( github.com/go-logr/logr v1.4.3 // indirect github.com/go-logr/stdr v1.2.2 // indirect github.com/google/uuid v1.6.0 // indirect - github.com/hashicorp/go-version v1.7.0 // indirect + github.com/hashicorp/go-version v1.8.0 // indirect github.com/json-iterator/go v1.1.12 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee // indirect github.com/pmezard/go-difflib v1.0.0 // indirect go.opentelemetry.io/auto/sdk v1.2.1 // indirect - go.opentelemetry.io/collector/featuregate v1.46.0 // indirect + go.opentelemetry.io/collector/featuregate v1.54.0 // indirect go.opentelemetry.io/otel v1.40.0 // indirect go.opentelemetry.io/otel/metric v1.40.0 // indirect go.opentelemetry.io/otel/sdk v1.40.0 // indirect go.opentelemetry.io/otel/sdk/metric v1.40.0 // indirect go.opentelemetry.io/otel/trace v1.40.0 // indirect go.uber.org/zap v1.27.1 // indirect - golang.org/x/sys v0.40.0 // indirect + golang.org/x/sys v0.41.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/scraper/go.sum b/scraper/go.sum index c102571e7869..1e6789104ba9 100644 --- a/scraper/go.sum +++ b/scraper/go.sum @@ -13,8 +13,8 @@ github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/hashicorp/go-version v1.7.0 h1:5tqGy27NaOTB8yJKUZELlFAS/LTKJkrmONwQKeRZfjY= -github.com/hashicorp/go-version v1.7.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= +github.com/hashicorp/go-version v1.8.0 h1:KAkNb1HAiZd1ukkxDFGmokVZe1Xy9HG6NUp+bPle2i4= +github.com/hashicorp/go-version v1.8.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= @@ -47,22 +47,22 @@ go.opentelemetry.io/otel/sdk/metric v1.40.0 h1:mtmdVqgQkeRxHgRv4qhyJduP3fYJRMX4A go.opentelemetry.io/otel/sdk/metric v1.40.0/go.mod h1:4Z2bGMf0KSK3uRjlczMOeMhKU2rhUqdWNoKcYrtcBPg= go.opentelemetry.io/otel/trace v1.40.0 h1:WA4etStDttCSYuhwvEa8OP8I5EWu24lkOzp+ZYblVjw= go.opentelemetry.io/otel/trace v1.40.0/go.mod h1:zeAhriXecNGP/s2SEG3+Y8X9ujcJOTqQ5RgdEJcawiA= -go.opentelemetry.io/proto/slim/otlp v1.9.0 h1:fPVMv8tP3TrsqlkH1HWYUpbCY9cAIemx184VGkS6vlE= -go.opentelemetry.io/proto/slim/otlp v1.9.0/go.mod h1:xXdeJJ90Gqyll+orzUkY4bOd2HECo5JofeoLpymVqdI= -go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.2.0 h1:o13nadWDNkH/quoDomDUClnQBpdQQ2Qqv0lQBjIXjE8= -go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.2.0/go.mod h1:Gyb6Xe7FTi/6xBHwMmngGoHqL0w29Y4eW8TGFzpefGA= -go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.2.0 h1:EiUYvtwu6PMrMHVjcPfnsG3v+ajPkbUeH+IL93+QYyk= -go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.2.0/go.mod h1:mUUHKFiN2SST3AhJ8XhJxEoeVW12oqfXog0Bo8W3Ec4= +go.opentelemetry.io/proto/slim/otlp v1.10.0 h1:iR97Vs/ZDR+y9TfuP9b1XBtdPWeC+OMslIBmhcLU7jM= +go.opentelemetry.io/proto/slim/otlp v1.10.0/go.mod h1:lV9250stpjYLPNA5viFabIgP2QlUGRT1GdTgAf8SIUk= +go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.3.0 h1:RUF5rO0hAlgiJt1fzQVzcVs3vZVNHIcMLgOgG4rWNcQ= +go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.3.0/go.mod h1:I89cynRj8y+383o7tEQVg2SVA6SRgDVIouWPUVXjx0U= +go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.3.0 h1:CQvJSldHRUN6Z8jsUeYv8J0lXRvygALXIzsmAeCcZE0= +go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.3.0/go.mod h1:xSQ+mEfJe/GjK1LXEyVOoSI1N9JV9ZI923X5kup43W4= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= go.uber.org/zap v1.27.1 h1:08RqriUEv8+ArZRYSTXy1LeBScaMpVSTBhCeaZYfMYc= go.uber.org/zap v1.27.1/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= -golang.org/x/sys v0.40.0 h1:DBZZqJ2Rkml6QMQsZywtnjnnGvHza6BTfYFWY9kjEWQ= -golang.org/x/sys v0.40.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= -google.golang.org/protobuf v1.36.10 h1:AYd7cD/uASjIL6Q9LiTjz8JLcrh/88q5UObnmY3aOOE= -google.golang.org/protobuf v1.36.10/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= +golang.org/x/sys v0.41.0 h1:Ivj+2Cp/ylzLiEU89QhWblYnOE9zerudt9Ftecq2C6k= +golang.org/x/sys v0.41.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= +google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE= +google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= diff --git a/scraper/logs_test.go b/scraper/logs_test.go index dc46e522c71b..4fa04ca29b83 100644 --- a/scraper/logs_test.go +++ b/scraper/logs_test.go @@ -59,14 +59,12 @@ func TestLogsConcurrency(t *testing.T) { var wg sync.WaitGroup for range 10 { - wg.Add(1) - go func() { - defer wg.Done() + wg.Go(func() { for range 10000 { _, errScrape := mp.ScrapeLogs(context.Background()) assert.NoError(t, errScrape) } - }() + }) } wg.Wait() require.NoError(t, mp.Shutdown(context.Background())) diff --git a/scraper/metrics_test.go b/scraper/metrics_test.go index bc9f9c52dd04..daf97401a528 100644 --- a/scraper/metrics_test.go +++ b/scraper/metrics_test.go @@ -66,14 +66,12 @@ func TestMetricsConcurrency(t *testing.T) { var wg sync.WaitGroup for range 10 { - wg.Add(1) - go func() { - defer wg.Done() + wg.Go(func() { for range 10000 { _, errScrape := mp.ScrapeMetrics(context.Background()) assert.NoError(t, errScrape) } - }() + }) } wg.Wait() require.NoError(t, mp.Shutdown(context.Background())) diff --git a/scraper/scraperhelper/config.schema.yaml b/scraper/scraperhelper/config.schema.yaml new file mode 100644 index 000000000000..731d01416b0d --- /dev/null +++ b/scraper/scraperhelper/config.schema.yaml @@ -0,0 +1,20 @@ +$defs: + controller_config: + description: ControllerConfig defines common settings for a scraper controller configuration. Scraper controller receivers can embed this struct, instead of receiver.Settings, and extend it with more fields if needed. + type: object + properties: + collection_interval: + description: CollectionInterval sets how frequently the scraper should be called and used as the context timeout to ensure that scrapers don't exceed the interval. + type: string + x-customType: time.Duration + format: duration + initial_delay: + description: InitialDelay sets the initial start delay for the scraper, any non positive value is assumed to be immediately. + type: string + x-customType: time.Duration + format: duration + timeout: + description: Timeout is an optional value used to set scraper's context deadline. + type: string + x-customType: time.Duration + format: duration diff --git a/scraper/scraperhelper/controller.go b/scraper/scraperhelper/controller.go index 257df474ac2c..e0f3c58f7fed 100644 --- a/scraper/scraperhelper/controller.go +++ b/scraper/scraperhelper/controller.go @@ -5,21 +5,26 @@ package scraperhelper // import "go.opentelemetry.io/collector/scraper/scraperhe import ( "context" - "sync" "time" - "go.uber.org/multierr" - "go.opentelemetry.io/collector/component" "go.opentelemetry.io/collector/consumer" "go.opentelemetry.io/collector/pdata/plog" "go.opentelemetry.io/collector/pdata/pmetric" "go.opentelemetry.io/collector/receiver" - "go.opentelemetry.io/collector/receiver/receiverhelper" "go.opentelemetry.io/collector/scraper" "go.opentelemetry.io/collector/scraper/scrapererror" + "go.opentelemetry.io/collector/scraper/scraperhelper/internal/controller" ) +type ControllerConfig = controller.ControllerConfig + +// NewDefaultControllerConfig returns default scraper controller +// settings with a collection interval of one minute. +func NewDefaultControllerConfig() ControllerConfig { + return controller.NewDefaultControllerConfig() +} + // ControllerOption apply changes to internal options. type ControllerOption interface { apply(*controllerOptions) @@ -31,12 +36,12 @@ func (of optionFunc) apply(e *controllerOptions) { of(e) } -// AddScraper configures the scraper.Metrics to be called with the specified options, -// and at the specified collection interval. +// AddMetricsScraper configures the scraper.Metrics to be called with the +// specified options, and at the specified collection interval. // // Observability information will be reported, and the scraped metrics // will be passed to the next consumer. -func AddScraper(t component.Type, sc scraper.Metrics) ControllerOption { +func AddMetricsScraper(t component.Type, sc scraper.Metrics) ControllerOption { f := scraper.NewFactory(t, nil, scraper.WithMetrics(func(context.Context, scraper.Settings, component.Config) (scraper.Metrics, error) { return sc, nil @@ -44,6 +49,17 @@ func AddScraper(t component.Type, sc scraper.Metrics) ControllerOption { return AddFactoryWithConfig(f, nil) } +// AddScraper configures the scraper.Metrics to be called with the +// specified options, and at the specified collection interval. +// +// Observability information will be reported, and the scraped metrics +// will be passed to the next consumer. +// +// Deprecated: [0.144.0] Use AddMetricsScraper instead. +func AddScraper(t component.Type, sc scraper.Metrics) ControllerOption { + return AddMetricsScraper(t, sc) +} + // AddFactoryWithConfig configures the scraper.Factory and associated config that // will be used to create a new scraper. The created scraper will be called with // the specified options, and at the specified collection interval. @@ -75,111 +91,6 @@ type controllerOptions struct { factoriesWithConfig []factoryWithConfig } -type controller[T component.Component] struct { - collectionInterval time.Duration - initialDelay time.Duration - timeout time.Duration - - scrapers []T - scrapeFunc func(*controller[T]) - tickerCh <-chan time.Time - - done chan struct{} - wg sync.WaitGroup - - obsrecv *receiverhelper.ObsReport -} - -func newController[T component.Component]( - cfg *ControllerConfig, - rSet receiver.Settings, - scrapers []T, - scrapeFunc func(*controller[T]), - tickerCh <-chan time.Time, -) (*controller[T], error) { - obsrecv, err := receiverhelper.NewObsReport(receiverhelper.ObsReportSettings{ - ReceiverID: rSet.ID, - Transport: "", - ReceiverCreateSettings: rSet, - }) - if err != nil { - return nil, err - } - - cs := &controller[T]{ - collectionInterval: cfg.CollectionInterval, - initialDelay: cfg.InitialDelay, - timeout: cfg.Timeout, - scrapers: scrapers, - scrapeFunc: scrapeFunc, - done: make(chan struct{}), - tickerCh: tickerCh, - obsrecv: obsrecv, - } - - return cs, nil -} - -// Start the receiver, invoked during service start. -func (sc *controller[T]) Start(ctx context.Context, host component.Host) error { - for _, scrp := range sc.scrapers { - if err := scrp.Start(ctx, host); err != nil { - return err - } - } - - sc.startScraping() - return nil -} - -// Shutdown the receiver, invoked during service shutdown. -func (sc *controller[T]) Shutdown(ctx context.Context) error { - // Signal the goroutine to stop. - close(sc.done) - sc.wg.Wait() - var errs error - for _, scrp := range sc.scrapers { - errs = multierr.Append(errs, scrp.Shutdown(ctx)) - } - - return errs -} - -// startScraping initiates a ticker that calls Scrape based on the configured -// collection interval. -func (sc *controller[T]) startScraping() { - sc.wg.Add(1) - go func() { - defer sc.wg.Done() - if sc.initialDelay > 0 { - select { - case <-time.After(sc.initialDelay): - case <-sc.done: - return - } - } - - if sc.tickerCh == nil { - ticker := time.NewTicker(sc.collectionInterval) - defer ticker.Stop() - - sc.tickerCh = ticker.C - } - // Call scrape method during initialization to ensure - // that scrapers start from when the component starts - // instead of waiting for the full duration to start. - sc.scrapeFunc(sc) - for { - select { - case <-sc.tickerCh: - sc.scrapeFunc(sc) - case <-sc.done: - return - } - } - }() -} - // NewLogsController creates a receiver.Logs with the configured options, that can control multiple scraper.Logs. func NewLogsController(cfg *ControllerConfig, rSet receiver.Settings, @@ -189,7 +100,7 @@ func NewLogsController(cfg *ControllerConfig, co := getOptions(options) scrapers := make([]scraper.Logs, 0, len(co.factoriesWithConfig)) for _, fwc := range co.factoriesWithConfig { - set := getSettings(fwc.f.Type(), rSet) + set := controller.GetSettings(fwc.f.Type(), rSet) s, err := fwc.f.CreateLogs(context.Background(), set, fwc.cfg) if err != nil { return nil, err @@ -200,8 +111,8 @@ func NewLogsController(cfg *ControllerConfig, } scrapers = append(scrapers, s) } - return newController[scraper.Logs]( - cfg, rSet, scrapers, func(c *controller[scraper.Logs]) { scrapeLogs(c, nextConsumer) }, co.tickerCh) + return controller.NewController[scraper.Logs]( + cfg, rSet, scrapers, func(c *controller.Controller[scraper.Logs]) { scrapeLogs(c, nextConsumer) }, co.tickerCh) } // NewMetricsController creates a receiver.Metrics with the configured options, that can control multiple scraper.Metrics. @@ -213,7 +124,7 @@ func NewMetricsController(cfg *ControllerConfig, co := getOptions(options) scrapers := make([]scraper.Metrics, 0, len(co.factoriesWithConfig)) for _, fwc := range co.factoriesWithConfig { - set := getSettings(fwc.f.Type(), rSet) + set := controller.GetSettings(fwc.f.Type(), rSet) s, err := fwc.f.CreateMetrics(context.Background(), set, fwc.cfg) if err != nil { return nil, err @@ -224,17 +135,17 @@ func NewMetricsController(cfg *ControllerConfig, } scrapers = append(scrapers, s) } - return newController[scraper.Metrics]( - cfg, rSet, scrapers, func(c *controller[scraper.Metrics]) { scrapeMetrics(c, nextConsumer) }, co.tickerCh) + return controller.NewController[scraper.Metrics]( + cfg, rSet, scrapers, func(c *controller.Controller[scraper.Metrics]) { scrapeMetrics(c, nextConsumer) }, co.tickerCh) } -func scrapeLogs(c *controller[scraper.Logs], nextConsumer consumer.Logs) { - ctx, done := withScrapeContext(c.timeout) +func scrapeLogs(c *controller.Controller[scraper.Logs], nextConsumer consumer.Logs) { + ctx, done := controller.WithScrapeContext(c.Timeout) defer done() logs := plog.NewLogs() - for i := range c.scrapers { - md, err := c.scrapers[i].ScrapeLogs(ctx) + for i := range c.Scrapers { + md, err := c.Scrapers[i].ScrapeLogs(ctx) if err != nil && !scrapererror.IsPartialScrapeError(err) { continue } @@ -242,18 +153,18 @@ func scrapeLogs(c *controller[scraper.Logs], nextConsumer consumer.Logs) { } logRecordCount := logs.LogRecordCount() - ctx = c.obsrecv.StartMetricsOp(ctx) + ctx = c.Obsrecv.StartLogsOp(ctx) err := nextConsumer.ConsumeLogs(ctx, logs) - c.obsrecv.EndMetricsOp(ctx, "", logRecordCount, err) + c.Obsrecv.EndLogsOp(ctx, "", logRecordCount, err) } -func scrapeMetrics(c *controller[scraper.Metrics], nextConsumer consumer.Metrics) { - ctx, done := withScrapeContext(c.timeout) +func scrapeMetrics(c *controller.Controller[scraper.Metrics], nextConsumer consumer.Metrics) { + ctx, done := controller.WithScrapeContext(c.Timeout) defer done() metrics := pmetric.NewMetrics() - for i := range c.scrapers { - md, err := c.scrapers[i].ScrapeMetrics(ctx) + for i := range c.Scrapers { + md, err := c.Scrapers[i].ScrapeMetrics(ctx) if err != nil && !scrapererror.IsPartialScrapeError(err) { continue } @@ -261,9 +172,9 @@ func scrapeMetrics(c *controller[scraper.Metrics], nextConsumer consumer.Metrics } dataPointCount := metrics.DataPointCount() - ctx = c.obsrecv.StartMetricsOp(ctx) + ctx = c.Obsrecv.StartMetricsOp(ctx) err := nextConsumer.ConsumeMetrics(ctx, metrics) - c.obsrecv.EndMetricsOp(ctx, "", dataPointCount, err) + c.Obsrecv.EndMetricsOp(ctx, "", dataPointCount, err) } func getOptions(options []ControllerOption) controllerOptions { @@ -273,21 +184,3 @@ func getOptions(options []ControllerOption) controllerOptions { } return co } - -func getSettings(sType component.Type, rSet receiver.Settings) scraper.Settings { - return scraper.Settings{ - ID: component.NewID(sType), - TelemetrySettings: rSet.TelemetrySettings, - BuildInfo: rSet.BuildInfo, - } -} - -// withScrapeContext will return a context that has no deadline if timeout is 0 -// which implies no explicit timeout had occurred, otherwise, a context -// with a deadline of the provided timeout is returned. -func withScrapeContext(timeout time.Duration) (context.Context, context.CancelFunc) { - if timeout == 0 { - return context.WithCancel(context.Background()) - } - return context.WithTimeout(context.Background(), timeout) -} diff --git a/scraper/scraperhelper/controller_test.go b/scraper/scraperhelper/controller_test.go index 3217d072fafa..afa73764d520 100644 --- a/scraper/scraperhelper/controller_test.go +++ b/scraper/scraperhelper/controller_test.go @@ -12,11 +12,12 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "go.opentelemetry.io/otel/attribute" - "go.opentelemetry.io/otel/codes" "go.opentelemetry.io/otel/sdk/metric/metricdata" "go.opentelemetry.io/otel/sdk/metric/metricdata/metricdatatest" sdktrace "go.opentelemetry.io/otel/sdk/trace" "go.uber.org/multierr" + "go.uber.org/zap" + "go.uber.org/zap/zaptest/observer" "go.opentelemetry.io/collector/component" "go.opentelemetry.io/collector/component/componenttest" @@ -27,29 +28,11 @@ import ( "go.opentelemetry.io/collector/receiver/receivertest" "go.opentelemetry.io/collector/scraper" "go.opentelemetry.io/collector/scraper/scrapererror" + "go.opentelemetry.io/collector/scraper/scraperhelper/internal/controller" "go.opentelemetry.io/collector/scraper/scraperhelper/internal/metadatatest" + "go.opentelemetry.io/collector/scraper/scraperhelper/internal/testhelper" ) -type testInitialize struct { - ch chan bool - err error -} - -func (ts *testInitialize) start(context.Context, component.Host) error { - ts.ch <- true - return ts.err -} - -type testClose struct { - ch chan bool - err error -} - -func (ts *testClose) shutdown(context.Context) error { - ts.ch <- true - return ts.err -} - type testScrape struct { ch chan int timesScrapeCalled int @@ -167,7 +150,7 @@ func TestLogsScrapeController(t *testing.T) { if expectedStartErr != nil { assert.Equal(t, expectedStartErr, err) } else if test.initialize { - assertChannelsCalled(t, initializeChs, "start was not called") + testhelper.AssertChannelsCalled(t, initializeChs, "start was not called") } const iterations = 5 @@ -198,8 +181,8 @@ func TestLogsScrapeController(t *testing.T) { } spans := tel.SpanRecorder.Ended() - assertReceiverSpan(t, spans) - assertScraperSpan(t, test.scrapeErr, spans, "scraper/scraper/ScrapeLogs") + assertLogsReceiverSpan(t, spans) + testhelper.AssertScraperSpan(t, test.scrapeErr, spans, "scraper/scraper/ScrapeLogs") assertLogsScraperObsMetrics(t, tel, receiverID, component.MustNewID("scraper"), test.scrapeErr, sink) } @@ -208,7 +191,7 @@ func TestLogsScrapeController(t *testing.T) { if expectedShutdownErr != nil { assert.EqualError(t, err, expectedShutdownErr.Error()) } else if test.close { - assertChannelsCalled(t, closeChs, "shutdown was not called") + testhelper.AssertChannelsCalled(t, closeChs, "shutdown was not called") } }) } @@ -278,7 +261,7 @@ func TestMetricsScrapeController(t *testing.T) { if expectedStartErr != nil { assert.Equal(t, expectedStartErr, err) } else if test.initialize { - assertChannelsCalled(t, initializeChs, "start was not called") + testhelper.AssertChannelsCalled(t, initializeChs, "start was not called") } const iterations = 5 @@ -309,8 +292,8 @@ func TestMetricsScrapeController(t *testing.T) { } spans := tel.SpanRecorder.Ended() - assertReceiverSpan(t, spans) - assertScraperSpan(t, test.scrapeErr, spans, "scraper/scraper/ScrapeMetrics") + assertMetricsReceiverSpan(t, spans) + testhelper.AssertScraperSpan(t, test.scrapeErr, spans, "scraper/scraper/ScrapeMetrics") assertMetricsScraperObsMetrics(t, tel, receiverID, component.MustNewID("scraper"), test.scrapeErr, sink) } @@ -319,7 +302,7 @@ func TestMetricsScrapeController(t *testing.T) { if expectedShutdownErr != nil { assert.EqualError(t, err, expectedShutdownErr.Error()) } else if test.close { - assertChannelsCalled(t, closeChs, "shutdown was not called") + testhelper.AssertChannelsCalled(t, closeChs, "shutdown was not called") } }) } @@ -332,13 +315,13 @@ func configureLogOptions(t *testing.T, test scraperTestCase, initializeChs []cha var scraperOptions []scraper.Option if test.initialize { initializeChs[i] = make(chan bool, 1) - ti := &testInitialize{ch: initializeChs[i], err: test.initializeErr} - scraperOptions = append(scraperOptions, scraper.WithStart(ti.start)) + ti := testhelper.NewTestInitialize(initializeChs[i], test.initializeErr) + scraperOptions = append(scraperOptions, scraper.WithStart(ti.Start)) } if test.close { closeChs[i] = make(chan bool, 1) - tc := &testClose{ch: closeChs[i], err: test.closeErr} - scraperOptions = append(scraperOptions, scraper.WithShutdown(tc.shutdown)) + tc := testhelper.NewTestClose(closeChs[i], test.closeErr) + scraperOptions = append(scraperOptions, scraper.WithShutdown(tc.Shutdown)) } scrapeLogsChs[i] = make(chan int) @@ -359,13 +342,13 @@ func configureMetricOptions(t *testing.T, test scraperTestCase, initializeChs [] var scraperOptions []scraper.Option if test.initialize { initializeChs[i] = make(chan bool, 1) - ti := &testInitialize{ch: initializeChs[i], err: test.initializeErr} - scraperOptions = append(scraperOptions, scraper.WithStart(ti.start)) + ti := testhelper.NewTestInitialize(initializeChs[i], test.initializeErr) + scraperOptions = append(scraperOptions, scraper.WithStart(ti.Start)) } if test.close { closeChs[i] = make(chan bool, 1) - tc := &testClose{ch: closeChs[i], err: test.closeErr} - scraperOptions = append(scraperOptions, scraper.WithShutdown(tc.shutdown)) + tc := testhelper.NewTestClose(closeChs[i], test.closeErr) + scraperOptions = append(scraperOptions, scraper.WithShutdown(tc.Shutdown)) } scrapeMetricsChs[i] = make(chan int) @@ -373,7 +356,7 @@ func configureMetricOptions(t *testing.T, test scraperTestCase, initializeChs [] scp, err := scraper.NewMetrics(ts.scrapeMetrics, scraperOptions...) require.NoError(t, err) - metricOptions = append(metricOptions, AddScraper(component.MustNewType("scraper"), scp)) + metricOptions = append(metricOptions, AddMetricsScraper(component.MustNewType("scraper"), scp)) } return metricOptions @@ -395,21 +378,7 @@ func getExpectedShutdownErr(test scraperTestCase) error { return errs } -func assertChannelsCalled(t *testing.T, chs []chan bool, message string) { - for _, ic := range chs { - assertChannelCalled(t, ic, message) - } -} - -func assertChannelCalled(t *testing.T, ch chan bool, message string) { - select { - case <-ch: - default: - assert.Fail(t, message) - } -} - -func assertReceiverSpan(t *testing.T, spans []sdktrace.ReadOnlySpan) { +func assertMetricsReceiverSpan(t *testing.T, spans []sdktrace.ReadOnlySpan) { receiverSpan := false for _, span := range spans { if span.Name() == "receiver/receiver/MetricsReceived" { @@ -420,24 +389,15 @@ func assertReceiverSpan(t *testing.T, spans []sdktrace.ReadOnlySpan) { assert.True(t, receiverSpan) } -func assertScraperSpan(t *testing.T, expectedErr error, spans []sdktrace.ReadOnlySpan, expectedSpanName string) { - expectedStatusCode := codes.Unset - expectedStatusMessage := "" - if expectedErr != nil { - expectedStatusCode = codes.Error - expectedStatusMessage = expectedErr.Error() - } - - scraperSpan := false +func assertLogsReceiverSpan(t *testing.T, spans []sdktrace.ReadOnlySpan) { + receiverSpan := false for _, span := range spans { - if span.Name() == expectedSpanName { - scraperSpan = true - assert.Equal(t, expectedStatusCode, span.Status().Code) - assert.Equal(t, expectedStatusMessage, span.Status().Description) + if span.Name() == "receiver/receiver/LogsReceived" { + receiverSpan = true break } } - assert.True(t, scraperSpan) + assert.True(t, receiverSpan) } func assertLogsScraperObsMetrics(t *testing.T, tel *componenttest.Telemetry, receiver, scraper component.ID, expectedErr error, sink *consumertest.LogsSink) { @@ -575,7 +535,7 @@ func TestSingleMetricsScraperPerInterval(t *testing.T) { cfg, receivertest.NewNopSettings(receivertest.NopType), new(consumertest.MetricsSink), - AddScraper(component.MustNewType("scraper"), scp), + AddMetricsScraper(component.MustNewType("scraper"), scp), WithTickerChannel(tickerCh), ) require.NoError(t, err) @@ -647,7 +607,7 @@ func TestMetricsScraperControllerStartsOnInit(t *testing.T) { }, receivertest.NewNopSettings(receivertest.NopType), new(consumertest.MetricsSink), - AddScraper(component.MustNewType("scraper"), scp), + AddMetricsScraper(component.MustNewType("scraper"), scp), ) require.NoError(t, err, "Must not error when creating scrape controller") @@ -722,7 +682,7 @@ func TestMetricsScraperControllerInitialDelay(t *testing.T) { &cfg, receivertest.NewNopSettings(receivertest.NopType), new(consumertest.MetricsSink), - AddScraper(component.MustNewType("scraper"), scp), + AddMetricsScraper(component.MustNewType("scraper"), scp), ) require.NoError(t, err, "Must not error when creating receiver") @@ -786,7 +746,7 @@ func TestMetricsScraperShutdownBeforeScrapeCanStart(t *testing.T) { &cfg, receivertest.NewNopSettings(receivertest.NopType), new(consumertest.MetricsSink), - AddScraper(component.MustNewType("scraper"), scp), + AddMetricsScraper(component.MustNewType("scraper"), scp), ) require.NoError(t, err, "Must not error when creating receiver") require.NoError(t, r.Start(context.Background(), componenttest.NewNopHost())) @@ -810,3 +770,65 @@ func addLogsScraper(t component.Type, sc scraper.Logs) ControllerOption { }, component.StabilityLevelAlpha)) return AddFactoryWithConfig(f, nil) } + +func TestNewDefaultControllerConfig(t *testing.T) { + controllerConfig := NewDefaultControllerConfig() + intControllerConfig := controller.NewDefaultControllerConfig() + require.Equal(t, intControllerConfig, controllerConfig) +} + +func TestNewMetricsController_ScraperIDInErrorLogs(t *testing.T) { + t.Parallel() + + core, observedLogs := observer.New(zap.ErrorLevel) + tel := componenttest.NewTelemetry() + t.Cleanup(func() { require.NoError(t, tel.Shutdown(context.Background())) }) + telset := tel.NewTelemetrySettings() + telset.Logger = zap.New(core) + + receiverID := component.MustNewID("fakeReceiver") + scraperType := component.MustNewType("fakeScraper") + scrapeErr := errors.New("scrape error") + + scrapeCh := make(chan int, 1) + ts := &testScrape{ch: scrapeCh, err: scrapeErr} + scp, err := scraper.NewMetrics(ts.scrapeMetrics) + require.NoError(t, err) + + cfg := newTestNoDelaySettings() + tickerCh := make(chan time.Time) + + recv, err := NewMetricsController( + cfg, + receiver.Settings{ID: receiverID, TelemetrySettings: telset, BuildInfo: component.NewDefaultBuildInfo()}, + new(consumertest.MetricsSink), + AddMetricsScraper(scraperType, scp), + WithTickerChannel(tickerCh), + ) + require.NoError(t, err) + require.NoError(t, recv.Start(context.Background(), componenttest.NewNopHost())) + defer func() { require.NoError(t, recv.Shutdown(context.Background())) }() + + <-scrapeCh + + require.Eventually(t, func() bool { + return observedLogs.Len() >= 1 + }, time.Second, 10*time.Millisecond) + errorLogs := observedLogs.FilterLevelExact(zap.ErrorLevel).All() + require.Len(t, errorLogs, 1) + + assert.Equal(t, "Error scraping metrics", errorLogs[0].Message) + assert.Equal(t, scraperType.String(), errorLogs[0].ContextMap()["scraper"]) + assert.Equal(t, scrapeErr.Error(), errorLogs[0].ContextMap()["error"]) + + // Verify the original receiver telemetry settings logger was NOT mutated + // by logging something and checking it doesn't have the scraper field + telset.Logger.Error("test log from receiver") + + allLogs := observedLogs.FilterLevelExact(zap.ErrorLevel).All() + require.Len(t, allLogs, 2) + + receiverLog := allLogs[1] + assert.Equal(t, "test log from receiver", receiverLog.Message) + assert.NotContains(t, receiverLog.ContextMap(), "scraper") +} diff --git a/scraper/scraperhelper/documentation.md b/scraper/scraperhelper/documentation.md index 0aa12afb6088..7c414a0a1b9a 100644 --- a/scraper/scraperhelper/documentation.md +++ b/scraper/scraperhelper/documentation.md @@ -8,32 +8,32 @@ The following telemetry is emitted by this component. ### otelcol_scraper_errored_log_records -Number of log records that were unable to be scraped. [Alpha] +Number of log records that were unable to be scraped. | Unit | Metric Type | Value Type | Monotonic | Stability | | ---- | ----------- | ---------- | --------- | --------- | -| {datapoints} | Sum | Int | true | Alpha | +| {datapoint} | Sum | Int | true | Alpha | ### otelcol_scraper_errored_metric_points -Number of metric points that were unable to be scraped. [Alpha] +Number of metric points that were unable to be scraped. | Unit | Metric Type | Value Type | Monotonic | Stability | | ---- | ----------- | ---------- | --------- | --------- | -| {datapoints} | Sum | Int | true | Alpha | +| {datapoint} | Sum | Int | true | Alpha | ### otelcol_scraper_scraped_log_records -Number of log records successfully scraped. [Alpha] +Number of log records successfully scraped. | Unit | Metric Type | Value Type | Monotonic | Stability | | ---- | ----------- | ---------- | --------- | --------- | -| {datapoints} | Sum | Int | true | Alpha | +| {datapoint} | Sum | Int | true | Alpha | ### otelcol_scraper_scraped_metric_points -Number of metric points successfully scraped. [Alpha] +Number of metric points successfully scraped. | Unit | Metric Type | Value Type | Monotonic | Stability | | ---- | ----------- | ---------- | --------- | --------- | -| {datapoints} | Sum | Int | true | Alpha | +| {datapoint} | Sum | Int | true | Alpha | diff --git a/scraper/scraperhelper/go.mod b/scraper/scraperhelper/go.mod index 312beef84186..f8ed1ceb0364 100644 --- a/scraper/scraperhelper/go.mod +++ b/scraper/scraperhelper/go.mod @@ -1,25 +1,25 @@ module go.opentelemetry.io/collector/scraper/scraperhelper -go 1.24.0 +go 1.25.0 require ( github.com/stretchr/testify v1.11.1 - go.opentelemetry.io/collector/component v1.46.0 - go.opentelemetry.io/collector/component/componenttest v0.140.0 - go.opentelemetry.io/collector/consumer v1.46.0 - go.opentelemetry.io/collector/consumer/consumertest v0.140.0 - go.opentelemetry.io/collector/pdata v1.46.0 - go.opentelemetry.io/collector/pdata/testdata v0.140.0 - go.opentelemetry.io/collector/pipeline v1.46.0 - go.opentelemetry.io/collector/receiver v1.46.0 + go.opentelemetry.io/collector/component v1.54.0 + go.opentelemetry.io/collector/component/componenttest v0.148.0 + go.opentelemetry.io/collector/consumer v1.54.0 + go.opentelemetry.io/collector/consumer/consumertest v0.148.0 + go.opentelemetry.io/collector/pdata v1.54.0 + go.opentelemetry.io/collector/pdata/testdata v0.148.0 + go.opentelemetry.io/collector/pipeline v1.54.0 + go.opentelemetry.io/collector/receiver v1.54.0 go.opentelemetry.io/collector/receiver/receiverhelper v0.140.0 go.opentelemetry.io/collector/receiver/receivertest v0.140.0 go.opentelemetry.io/collector/scraper v0.140.0 - go.opentelemetry.io/otel v1.40.0 - go.opentelemetry.io/otel/metric v1.40.0 + go.opentelemetry.io/otel v1.42.0 + go.opentelemetry.io/otel/metric v1.42.0 go.opentelemetry.io/otel/sdk v1.40.0 go.opentelemetry.io/otel/sdk/metric v1.40.0 - go.opentelemetry.io/otel/trace v1.40.0 + go.opentelemetry.io/otel/trace v1.42.0 go.uber.org/goleak v1.3.0 go.uber.org/multierr v1.11.0 go.uber.org/zap v1.27.1 @@ -31,21 +31,23 @@ require ( github.com/go-logr/logr v1.4.3 // indirect github.com/go-logr/stdr v1.2.2 // indirect github.com/google/uuid v1.6.0 // indirect - github.com/hashicorp/go-version v1.7.0 // indirect + github.com/hashicorp/go-version v1.8.0 // indirect github.com/json-iterator/go v1.1.12 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee // indirect github.com/pmezard/go-difflib v1.0.0 // indirect go.opentelemetry.io/auto/sdk v1.2.1 // indirect - go.opentelemetry.io/collector/consumer/consumererror v0.140.0 // indirect - go.opentelemetry.io/collector/consumer/xconsumer v0.140.0 // indirect - go.opentelemetry.io/collector/featuregate v1.46.0 // indirect - go.opentelemetry.io/collector/pdata/pprofile v0.140.0 // indirect - go.opentelemetry.io/collector/receiver/xreceiver v0.140.0 // indirect - golang.org/x/sys v0.40.0 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20251022142026-3a174f9686a8 // indirect - google.golang.org/grpc v1.77.0 // indirect - google.golang.org/protobuf v1.36.10 // indirect + go.opentelemetry.io/collector/consumer/consumererror v0.148.0 // indirect + go.opentelemetry.io/collector/consumer/xconsumer v0.148.0 // indirect + go.opentelemetry.io/collector/featuregate v1.54.0 // indirect + go.opentelemetry.io/collector/internal/componentalias v0.148.0 // indirect + go.opentelemetry.io/collector/pdata/pprofile v0.148.0 // indirect + go.opentelemetry.io/collector/pipeline/xpipeline v0.0.0-00010101000000-000000000000 // indirect + go.opentelemetry.io/collector/receiver/xreceiver v0.148.0 // indirect + golang.org/x/sys v0.41.0 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20251222181119-0a764e51fe1b // indirect + google.golang.org/grpc v1.79.3 // indirect + google.golang.org/protobuf v1.36.11 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) @@ -82,3 +84,7 @@ replace go.opentelemetry.io/collector/consumer/consumertest => ../../consumer/co replace go.opentelemetry.io/collector/featuregate => ../../featuregate replace go.opentelemetry.io/collector/internal/testutil => ../../internal/testutil + +replace go.opentelemetry.io/collector/pipeline/xpipeline => ../../pipeline/xpipeline + +replace go.opentelemetry.io/collector/internal/componentalias => ../../internal/componentalias diff --git a/scraper/scraperhelper/go.sum b/scraper/scraperhelper/go.sum index 365c0691917d..bf8635e3851f 100644 --- a/scraper/scraperhelper/go.sum +++ b/scraper/scraperhelper/go.sum @@ -15,8 +15,8 @@ github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/hashicorp/go-version v1.7.0 h1:5tqGy27NaOTB8yJKUZELlFAS/LTKJkrmONwQKeRZfjY= -github.com/hashicorp/go-version v1.7.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= +github.com/hashicorp/go-version v1.8.0 h1:KAkNb1HAiZd1ukkxDFGmokVZe1Xy9HG6NUp+bPle2i4= +github.com/hashicorp/go-version v1.8.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= @@ -39,40 +39,40 @@ github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64= go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y= -go.opentelemetry.io/otel v1.40.0 h1:oA5YeOcpRTXq6NN7frwmwFR0Cn3RhTVZvXsP4duvCms= -go.opentelemetry.io/otel v1.40.0/go.mod h1:IMb+uXZUKkMXdPddhwAHm6UfOwJyh4ct1ybIlV14J0g= -go.opentelemetry.io/otel/metric v1.40.0 h1:rcZe317KPftE2rstWIBitCdVp89A2HqjkxR3c11+p9g= -go.opentelemetry.io/otel/metric v1.40.0/go.mod h1:ib/crwQH7N3r5kfiBZQbwrTge743UDc7DTFVZrrXnqc= +go.opentelemetry.io/otel v1.42.0 h1:lSQGzTgVR3+sgJDAU/7/ZMjN9Z+vUip7leaqBKy4sho= +go.opentelemetry.io/otel v1.42.0/go.mod h1:lJNsdRMxCUIWuMlVJWzecSMuNjE7dOYyWlqOXWkdqCc= +go.opentelemetry.io/otel/metric v1.42.0 h1:2jXG+3oZLNXEPfNmnpxKDeZsFI5o4J+nz6xUlaFdF/4= +go.opentelemetry.io/otel/metric v1.42.0/go.mod h1:RlUN/7vTU7Ao/diDkEpQpnz3/92J9ko05BIwxYa2SSI= go.opentelemetry.io/otel/sdk v1.40.0 h1:KHW/jUzgo6wsPh9At46+h4upjtccTmuZCFAc9OJ71f8= go.opentelemetry.io/otel/sdk v1.40.0/go.mod h1:Ph7EFdYvxq72Y8Li9q8KebuYUr2KoeyHx0DRMKrYBUE= go.opentelemetry.io/otel/sdk/metric v1.40.0 h1:mtmdVqgQkeRxHgRv4qhyJduP3fYJRMX4AtAlbuWdCYw= go.opentelemetry.io/otel/sdk/metric v1.40.0/go.mod h1:4Z2bGMf0KSK3uRjlczMOeMhKU2rhUqdWNoKcYrtcBPg= -go.opentelemetry.io/otel/trace v1.40.0 h1:WA4etStDttCSYuhwvEa8OP8I5EWu24lkOzp+ZYblVjw= -go.opentelemetry.io/otel/trace v1.40.0/go.mod h1:zeAhriXecNGP/s2SEG3+Y8X9ujcJOTqQ5RgdEJcawiA= -go.opentelemetry.io/proto/slim/otlp v1.9.0 h1:fPVMv8tP3TrsqlkH1HWYUpbCY9cAIemx184VGkS6vlE= -go.opentelemetry.io/proto/slim/otlp v1.9.0/go.mod h1:xXdeJJ90Gqyll+orzUkY4bOd2HECo5JofeoLpymVqdI= -go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.2.0 h1:o13nadWDNkH/quoDomDUClnQBpdQQ2Qqv0lQBjIXjE8= -go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.2.0/go.mod h1:Gyb6Xe7FTi/6xBHwMmngGoHqL0w29Y4eW8TGFzpefGA= -go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.2.0 h1:EiUYvtwu6PMrMHVjcPfnsG3v+ajPkbUeH+IL93+QYyk= -go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.2.0/go.mod h1:mUUHKFiN2SST3AhJ8XhJxEoeVW12oqfXog0Bo8W3Ec4= +go.opentelemetry.io/otel/trace v1.42.0 h1:OUCgIPt+mzOnaUTpOQcBiM/PLQ/Op7oq6g4LenLmOYY= +go.opentelemetry.io/otel/trace v1.42.0/go.mod h1:f3K9S+IFqnumBkKhRJMeaZeNk9epyhnCmQh/EysQCdc= +go.opentelemetry.io/proto/slim/otlp v1.10.0 h1:iR97Vs/ZDR+y9TfuP9b1XBtdPWeC+OMslIBmhcLU7jM= +go.opentelemetry.io/proto/slim/otlp v1.10.0/go.mod h1:lV9250stpjYLPNA5viFabIgP2QlUGRT1GdTgAf8SIUk= +go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.3.0 h1:RUF5rO0hAlgiJt1fzQVzcVs3vZVNHIcMLgOgG4rWNcQ= +go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.3.0/go.mod h1:I89cynRj8y+383o7tEQVg2SVA6SRgDVIouWPUVXjx0U= +go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.3.0 h1:CQvJSldHRUN6Z8jsUeYv8J0lXRvygALXIzsmAeCcZE0= +go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.3.0/go.mod h1:xSQ+mEfJe/GjK1LXEyVOoSI1N9JV9ZI923X5kup43W4= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= go.uber.org/zap v1.27.1 h1:08RqriUEv8+ArZRYSTXy1LeBScaMpVSTBhCeaZYfMYc= go.uber.org/zap v1.27.1/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= -golang.org/x/net v0.46.1-0.20251013234738-63d1a5100f82 h1:6/3JGEh1C88g7m+qzzTbl3A0FtsLguXieqofVLU/JAo= -golang.org/x/net v0.46.1-0.20251013234738-63d1a5100f82/go.mod h1:Q9BGdFy1y4nkUwiLvT5qtyhAnEHgnQ/zd8PfU6nc210= -golang.org/x/sys v0.40.0 h1:DBZZqJ2Rkml6QMQsZywtnjnnGvHza6BTfYFWY9kjEWQ= -golang.org/x/sys v0.40.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= -golang.org/x/text v0.30.0 h1:yznKA/E9zq54KzlzBEAWn1NXSQ8DIp/NYMy88xJjl4k= -golang.org/x/text v0.30.0/go.mod h1:yDdHFIX9t+tORqspjENWgzaCVXgk0yYnYuSZ8UzzBVM= -google.golang.org/genproto/googleapis/rpc v0.0.0-20251022142026-3a174f9686a8 h1:M1rk8KBnUsBDg1oPGHNCxG4vc1f49epmTO7xscSajMk= -google.golang.org/genproto/googleapis/rpc v0.0.0-20251022142026-3a174f9686a8/go.mod h1:7i2o+ce6H/6BluujYR+kqX3GKH+dChPTQU19wjRPiGk= -google.golang.org/grpc v1.77.0 h1:wVVY6/8cGA6vvffn+wWK5ToddbgdU3d8MNENr4evgXM= -google.golang.org/grpc v1.77.0/go.mod h1:z0BY1iVj0q8E1uSQCjL9cppRj+gnZjzDnzV0dHhrNig= -google.golang.org/protobuf v1.36.10 h1:AYd7cD/uASjIL6Q9LiTjz8JLcrh/88q5UObnmY3aOOE= -google.golang.org/protobuf v1.36.10/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= +golang.org/x/net v0.51.0 h1:94R/GTO7mt3/4wIKpcR5gkGmRLOuE/2hNGeWq/GBIFo= +golang.org/x/net v0.51.0/go.mod h1:aamm+2QF5ogm02fjy5Bb7CQ0WMt1/WVM7FtyaTLlA9Y= +golang.org/x/sys v0.41.0 h1:Ivj+2Cp/ylzLiEU89QhWblYnOE9zerudt9Ftecq2C6k= +golang.org/x/sys v0.41.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= +golang.org/x/text v0.34.0 h1:oL/Qq0Kdaqxa1KbNeMKwQq0reLCCaFtqu2eNuSeNHbk= +golang.org/x/text v0.34.0/go.mod h1:homfLqTYRFyVYemLBFl5GgL/DWEiH5wcsQ5gSh1yziA= +google.golang.org/genproto/googleapis/rpc v0.0.0-20251222181119-0a764e51fe1b h1:Mv8VFug0MP9e5vUxfBcE3vUkV6CImK3cMNMIDFjmzxU= +google.golang.org/genproto/googleapis/rpc v0.0.0-20251222181119-0a764e51fe1b/go.mod h1:j9x/tPzZkyxcgEFkiKEEGxfvyumM01BEtsW8xzOahRQ= +google.golang.org/grpc v1.79.3 h1:sybAEdRIEtvcD68Gx7dmnwjZKlyfuc61Dyo9pGXXkKE= +google.golang.org/grpc v1.79.3/go.mod h1:KmT0Kjez+0dde/v2j9vzwoAScgEPx/Bw1CYChhHLrHQ= +google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE= +google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= diff --git a/scraper/scraperhelper/config.go b/scraper/scraperhelper/internal/controller/config.go similarity index 94% rename from scraper/scraperhelper/config.go rename to scraper/scraperhelper/internal/controller/config.go index ebcb68644e1a..dffffac21a2b 100644 --- a/scraper/scraperhelper/config.go +++ b/scraper/scraperhelper/internal/controller/config.go @@ -1,7 +1,7 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -package scraperhelper // import "go.opentelemetry.io/collector/scraper/scraperhelper" +package controller // import "go.opentelemetry.io/collector/scraper/scraperhelper/internal/controller" import ( "errors" diff --git a/scraper/scraperhelper/config_test.go b/scraper/scraperhelper/internal/controller/config_test.go similarity index 90% rename from scraper/scraperhelper/config_test.go rename to scraper/scraperhelper/internal/controller/config_test.go index c82b95ddfda2..52a61866fc48 100644 --- a/scraper/scraperhelper/config_test.go +++ b/scraper/scraperhelper/internal/controller/config_test.go @@ -1,7 +1,7 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -package scraperhelper +package controller // import "go.opentelemetry.io/collector/scraper/scraperhelper/internal/controller" import ( "testing" diff --git a/scraper/scraperhelper/internal/controller/controller.go b/scraper/scraperhelper/internal/controller/controller.go new file mode 100644 index 000000000000..f9cc61757072 --- /dev/null +++ b/scraper/scraperhelper/internal/controller/controller.go @@ -0,0 +1,144 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +// package controller provides functionality used in scraperhelper and xscraperhelper. + +package controller // import "go.opentelemetry.io/collector/scraper/scraperhelper/internal/controller" + +import ( + "context" + "sync" + "time" + + "go.uber.org/multierr" + "go.uber.org/zap" + + "go.opentelemetry.io/collector/component" + "go.opentelemetry.io/collector/receiver" + "go.opentelemetry.io/collector/receiver/receiverhelper" + "go.opentelemetry.io/collector/scraper" +) + +type Controller[T component.Component] struct { + collectionInterval time.Duration + initialDelay time.Duration + Timeout time.Duration + + Scrapers []T + scrapeFunc func(*Controller[T]) + tickerCh <-chan time.Time + + done chan struct{} + wg sync.WaitGroup + + Obsrecv *receiverhelper.ObsReport +} + +func NewController[T component.Component]( + cfg *ControllerConfig, + rSet receiver.Settings, + scrapers []T, + scrapeFunc func(*Controller[T]), + tickerCh <-chan time.Time, +) (*Controller[T], error) { + obsrecv, err := receiverhelper.NewObsReport(receiverhelper.ObsReportSettings{ + ReceiverID: rSet.ID, + Transport: "", + ReceiverCreateSettings: rSet, + }) + if err != nil { + return nil, err + } + + cs := &Controller[T]{ + collectionInterval: cfg.CollectionInterval, + initialDelay: cfg.InitialDelay, + Timeout: cfg.Timeout, + Scrapers: scrapers, + scrapeFunc: scrapeFunc, + done: make(chan struct{}), + tickerCh: tickerCh, + Obsrecv: obsrecv, + } + + return cs, nil +} + +// Start the receiver, invoked during service start. +func (sc *Controller[T]) Start(ctx context.Context, host component.Host) error { + for _, scrp := range sc.Scrapers { + if err := scrp.Start(ctx, host); err != nil { + return err + } + } + + sc.startScraping() + return nil +} + +// Shutdown the receiver, invoked during service shutdown. +func (sc *Controller[T]) Shutdown(ctx context.Context) error { + // Signal the goroutine to stop. + close(sc.done) + sc.wg.Wait() + var errs error + for _, scrp := range sc.Scrapers { + errs = multierr.Append(errs, scrp.Shutdown(ctx)) + } + + return errs +} + +// startScraping initiates a ticker that calls Scrape based on the configured +// collection interval. +func (sc *Controller[T]) startScraping() { + sc.wg.Go(func() { + if sc.initialDelay > 0 { + select { + case <-time.After(sc.initialDelay): + case <-sc.done: + return + } + } + + if sc.tickerCh == nil { + ticker := time.NewTicker(sc.collectionInterval) + defer ticker.Stop() + + sc.tickerCh = ticker.C + } + // Call scrape method during initialization to ensure + // that scrapers start from when the component starts + // instead of waiting for the full duration to start. + sc.scrapeFunc(sc) + for { + select { + case <-sc.tickerCh: + sc.scrapeFunc(sc) + case <-sc.done: + return + } + } + }) +} + +func GetSettings(sType component.Type, rSet receiver.Settings) scraper.Settings { + id := component.NewID(sType) + telemetry := rSet.TelemetrySettings + telemetry.Logger = telemetry.Logger.With(zap.String("scraper", id.String())) + return scraper.Settings{ + ID: id, + TelemetrySettings: telemetry, + BuildInfo: rSet.BuildInfo, + } +} + +// WithScrapeContext will return a context that has no deadline if timeout is 0 +// which implies no explicit timeout had occurred, otherwise, a context +// with a deadline of the provided timeout is returned. +func WithScrapeContext(timeout time.Duration) (context.Context, context.CancelFunc) { + if timeout == 0 { + return context.WithCancel(context.Background()) + } + return context.WithTimeout(context.Background(), timeout) +} diff --git a/scraper/scraperhelper/internal/metadata/generated_telemetry.go b/scraper/scraperhelper/internal/metadata/generated_telemetry.go index a02dc64137c2..87f2625decb3 100644 --- a/scraper/scraperhelper/internal/metadata/generated_telemetry.go +++ b/scraper/scraperhelper/internal/metadata/generated_telemetry.go @@ -64,25 +64,25 @@ func NewTelemetryBuilder(settings component.TelemetrySettings, options ...Teleme builder.ScraperErroredLogRecords, err = builder.meter.Int64Counter( "otelcol_scraper_errored_log_records", metric.WithDescription("Number of log records that were unable to be scraped. [Alpha]"), - metric.WithUnit("{datapoints}"), + metric.WithUnit("{datapoint}"), ) errs = errors.Join(errs, err) builder.ScraperErroredMetricPoints, err = builder.meter.Int64Counter( "otelcol_scraper_errored_metric_points", metric.WithDescription("Number of metric points that were unable to be scraped. [Alpha]"), - metric.WithUnit("{datapoints}"), + metric.WithUnit("{datapoint}"), ) errs = errors.Join(errs, err) builder.ScraperScrapedLogRecords, err = builder.meter.Int64Counter( "otelcol_scraper_scraped_log_records", metric.WithDescription("Number of log records successfully scraped. [Alpha]"), - metric.WithUnit("{datapoints}"), + metric.WithUnit("{datapoint}"), ) errs = errors.Join(errs, err) builder.ScraperScrapedMetricPoints, err = builder.meter.Int64Counter( "otelcol_scraper_scraped_metric_points", metric.WithDescription("Number of metric points successfully scraped. [Alpha]"), - metric.WithUnit("{datapoints}"), + metric.WithUnit("{datapoint}"), ) errs = errors.Join(errs, err) return &builder, errs diff --git a/scraper/scraperhelper/internal/metadatatest/generated_telemetrytest.go b/scraper/scraperhelper/internal/metadatatest/generated_telemetrytest.go index 8e86843fdfb3..d4da93971225 100644 --- a/scraper/scraperhelper/internal/metadatatest/generated_telemetrytest.go +++ b/scraper/scraperhelper/internal/metadatatest/generated_telemetrytest.go @@ -16,7 +16,7 @@ func AssertEqualScraperErroredLogRecords(t *testing.T, tt *componenttest.Telemet want := metricdata.Metrics{ Name: "otelcol_scraper_errored_log_records", Description: "Number of log records that were unable to be scraped. [Alpha]", - Unit: "{datapoints}", + Unit: "{datapoint}", Data: metricdata.Sum[int64]{ Temporality: metricdata.CumulativeTemporality, IsMonotonic: true, @@ -32,7 +32,7 @@ func AssertEqualScraperErroredMetricPoints(t *testing.T, tt *componenttest.Telem want := metricdata.Metrics{ Name: "otelcol_scraper_errored_metric_points", Description: "Number of metric points that were unable to be scraped. [Alpha]", - Unit: "{datapoints}", + Unit: "{datapoint}", Data: metricdata.Sum[int64]{ Temporality: metricdata.CumulativeTemporality, IsMonotonic: true, @@ -48,7 +48,7 @@ func AssertEqualScraperScrapedLogRecords(t *testing.T, tt *componenttest.Telemet want := metricdata.Metrics{ Name: "otelcol_scraper_scraped_log_records", Description: "Number of log records successfully scraped. [Alpha]", - Unit: "{datapoints}", + Unit: "{datapoint}", Data: metricdata.Sum[int64]{ Temporality: metricdata.CumulativeTemporality, IsMonotonic: true, @@ -64,7 +64,7 @@ func AssertEqualScraperScrapedMetricPoints(t *testing.T, tt *componenttest.Telem want := metricdata.Metrics{ Name: "otelcol_scraper_scraped_metric_points", Description: "Number of metric points successfully scraped. [Alpha]", - Unit: "{datapoints}", + Unit: "{datapoint}", Data: metricdata.Sum[int64]{ Temporality: metricdata.CumulativeTemporality, IsMonotonic: true, diff --git a/scraper/scraperhelper/internal/testhelper/helper.go b/scraper/scraperhelper/internal/testhelper/helper.go new file mode 100644 index 000000000000..ec2dfe4cca9e --- /dev/null +++ b/scraper/scraperhelper/internal/testhelper/helper.go @@ -0,0 +1,85 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +// package testhelper provides functionality used in tests in scraperhelper and xscraperhelper. + +package testhelper // import "go.opentelemetry.io/collector/scraper/scraperhelper/internal/testhelper" + +import ( + "context" + "testing" + + "github.com/stretchr/testify/assert" + "go.opentelemetry.io/otel/codes" + sdktrace "go.opentelemetry.io/otel/sdk/trace" + + "go.opentelemetry.io/collector/component" +) + +type TestInitialize struct { + ch chan bool + err error +} + +func NewTestInitialize(ch chan bool, err error) *TestInitialize { + return &TestInitialize{ + ch: ch, + err: err, + } +} + +func (ts *TestInitialize) Start(context.Context, component.Host) error { + ts.ch <- true + return ts.err +} + +type TestClose struct { + ch chan bool + err error +} + +func NewTestClose(ch chan bool, err error) *TestClose { + return &TestClose{ + ch: ch, + err: err, + } +} + +func (ts *TestClose) Shutdown(context.Context) error { + ts.ch <- true + return ts.err +} + +func AssertChannelCalled(t *testing.T, ch chan bool, message string) { + select { + case <-ch: + default: + assert.Fail(t, message) + } +} + +func AssertChannelsCalled(t *testing.T, chs []chan bool, message string) { + for _, ic := range chs { + AssertChannelCalled(t, ic, message) + } +} + +func AssertScraperSpan(t *testing.T, expectedErr error, spans []sdktrace.ReadOnlySpan, expectedSpanName string) { + expectedStatusCode := codes.Unset + expectedStatusMessage := "" + if expectedErr != nil { + expectedStatusCode = codes.Error + expectedStatusMessage = expectedErr.Error() + } + + scraperSpan := false + for _, span := range spans { + if span.Name() == expectedSpanName { + scraperSpan = true + assert.Equal(t, expectedStatusCode, span.Status().Code) + assert.Equal(t, expectedStatusMessage, span.Status().Description) + break + } + } + assert.True(t, scraperSpan) +} diff --git a/scraper/scraperhelper/metadata.yaml b/scraper/scraperhelper/metadata.yaml index 6963d5751d64..54f89939919f 100644 --- a/scraper/scraperhelper/metadata.yaml +++ b/scraper/scraperhelper/metadata.yaml @@ -11,40 +11,36 @@ telemetry: metrics: scraper_errored_log_records: enabled: true - stability: - level: alpha + stability: alpha description: Number of log records that were unable to be scraped. - unit: "{datapoints}" + unit: "{datapoint}" sum: value_type: int monotonic: true scraper_errored_metric_points: enabled: true - stability: - level: alpha + stability: alpha description: Number of metric points that were unable to be scraped. - unit: "{datapoints}" + unit: "{datapoint}" sum: value_type: int monotonic: true scraper_scraped_log_records: enabled: true - stability: - level: alpha + stability: alpha description: Number of log records successfully scraped. - unit: "{datapoints}" + unit: "{datapoint}" sum: value_type: int monotonic: true scraper_scraped_metric_points: enabled: true - stability: - level: alpha + stability: alpha description: Number of metric points successfully scraped. - unit: "{datapoints}" + unit: "{datapoint}" sum: value_type: int monotonic: true diff --git a/scraper/scraperhelper/obs_logs_test.go b/scraper/scraperhelper/obs_logs_test.go index 454bf51f9479..2153580cb88a 100644 --- a/scraper/scraperhelper/obs_logs_test.go +++ b/scraper/scraperhelper/obs_logs_test.go @@ -14,12 +14,16 @@ import ( "go.opentelemetry.io/otel/codes" "go.opentelemetry.io/otel/sdk/metric/metricdata" "go.opentelemetry.io/otel/sdk/metric/metricdata/metricdatatest" + "go.uber.org/zap" + "go.uber.org/zap/zaptest/observer" "go.opentelemetry.io/collector/component" "go.opentelemetry.io/collector/component/componenttest" "go.opentelemetry.io/collector/pdata/plog" "go.opentelemetry.io/collector/pdata/testdata" + "go.opentelemetry.io/collector/receiver" "go.opentelemetry.io/collector/scraper" + "go.opentelemetry.io/collector/scraper/scraperhelper/internal/controller" "go.opentelemetry.io/collector/scraper/scraperhelper/internal/metadatatest" ) @@ -97,6 +101,36 @@ func TestCheckScraperLogs(t *testing.T) { checkScraperLogs(t, tel, receiverID, scraperID, 7, 0) } +func TestScrapeLogsDataOp_LogsScraperID(t *testing.T) { + tel := componenttest.NewTelemetry() + t.Cleanup(func() { require.NoError(t, tel.Shutdown(context.Background())) }) + + core, observedLogs := observer.New(zap.ErrorLevel) + telset := tel.NewTelemetrySettings() + telset.Logger = zap.New(core) + + rSet := receiver.Settings{ + ID: receiverID, + TelemetrySettings: telset, + } + set := controller.GetSettings(scraperID.Type(), rSet) + + sm, err := scraper.NewLogs(func(context.Context) (plog.Logs, error) { + return plog.NewLogs(), errFake + }) + require.NoError(t, err) + sf, err := wrapObsLogs(sm, receiverID, scraperID, set.TelemetrySettings) + require.NoError(t, err) + _, err = sf.ScrapeLogs(context.Background()) + require.ErrorIs(t, err, errFake) + + errorLogs := observedLogs.FilterLevelExact(zap.ErrorLevel).All() + require.Len(t, errorLogs, 1) + assert.Equal(t, "Error scraping logs", errorLogs[0].Message) + assert.Equal(t, scraperID.String(), errorLogs[0].ContextMap()["scraper"]) + assert.Equal(t, errFake.Error(), errorLogs[0].ContextMap()["error"]) +} + func checkScraperLogs(t *testing.T, tel *componenttest.Telemetry, receiver, scraper component.ID, scrapedLogRecords, erroredLogRecords int64) { metadatatest.AssertEqualScraperScrapedLogRecords(t, tel, []metricdata.DataPoint[int64]{ diff --git a/scraper/scraperhelper/obs_metrics_test.go b/scraper/scraperhelper/obs_metrics_test.go index 2a9cf4e989c4..14a0e961983b 100644 --- a/scraper/scraperhelper/obs_metrics_test.go +++ b/scraper/scraperhelper/obs_metrics_test.go @@ -14,13 +14,17 @@ import ( "go.opentelemetry.io/otel/codes" "go.opentelemetry.io/otel/sdk/metric/metricdata" "go.opentelemetry.io/otel/sdk/metric/metricdata/metricdatatest" + "go.uber.org/zap" + "go.uber.org/zap/zaptest/observer" "go.opentelemetry.io/collector/component" "go.opentelemetry.io/collector/component/componenttest" "go.opentelemetry.io/collector/pdata/pmetric" "go.opentelemetry.io/collector/pdata/testdata" + "go.opentelemetry.io/collector/receiver" "go.opentelemetry.io/collector/scraper" "go.opentelemetry.io/collector/scraper/scrapererror" + "go.opentelemetry.io/collector/scraper/scraperhelper/internal/controller" "go.opentelemetry.io/collector/scraper/scraperhelper/internal/metadatatest" ) @@ -110,6 +114,36 @@ func TestCheckScraperMetrics(t *testing.T) { checkScraperMetrics(t, tel, receiverID, scraperID, 7, 0) } +func TestScrapeMetricsDataOp_LogsScraperID(t *testing.T) { + tel := componenttest.NewTelemetry() + t.Cleanup(func() { require.NoError(t, tel.Shutdown(context.Background())) }) + + core, observedLogs := observer.New(zap.ErrorLevel) + telset := tel.NewTelemetrySettings() + telset.Logger = zap.New(core) + + rSet := receiver.Settings{ + ID: receiverID, + TelemetrySettings: telset, + } + set := controller.GetSettings(scraperID.Type(), rSet) + + sm, err := scraper.NewMetrics(func(context.Context) (pmetric.Metrics, error) { + return pmetric.NewMetrics(), errFake + }) + require.NoError(t, err) + sf, err := wrapObsMetrics(sm, receiverID, scraperID, set.TelemetrySettings) + require.NoError(t, err) + _, err = sf.ScrapeMetrics(context.Background()) + require.ErrorIs(t, err, errFake) + + errorLogs := observedLogs.FilterLevelExact(zap.ErrorLevel).All() + require.Len(t, errorLogs, 1) + assert.Equal(t, "Error scraping metrics", errorLogs[0].Message) + assert.Equal(t, scraperID.String(), errorLogs[0].ContextMap()["scraper"]) + assert.Equal(t, errFake.Error(), errorLogs[0].ContextMap()["error"]) +} + func checkScraperMetrics(t *testing.T, tt *componenttest.Telemetry, receiver, scraper component.ID, scrapedMetricPoints, erroredMetricPoints int64) { metadatatest.AssertEqualScraperScrapedMetricPoints(t, tt, []metricdata.DataPoint[int64]{ diff --git a/scraper/scraperhelper/xscraperhelper/Makefile b/scraper/scraperhelper/xscraperhelper/Makefile new file mode 100644 index 000000000000..bdd863a203be --- /dev/null +++ b/scraper/scraperhelper/xscraperhelper/Makefile @@ -0,0 +1 @@ +include ../../../Makefile.Common diff --git a/scraper/scraperhelper/xscraperhelper/controller.go b/scraper/scraperhelper/xscraperhelper/controller.go new file mode 100644 index 000000000000..ab46aa838e2e --- /dev/null +++ b/scraper/scraperhelper/xscraperhelper/controller.go @@ -0,0 +1,136 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +// Package xscraperhelper provides utilities for scrapers. +package xscraperhelper // import "go.opentelemetry.io/collector/scraper/scraperhelper/xscraperhelper" + +import ( + "context" + "time" + + "go.opentelemetry.io/collector/component" + "go.opentelemetry.io/collector/consumer/xconsumer" + "go.opentelemetry.io/collector/pdata/pprofile" + "go.opentelemetry.io/collector/receiver" + "go.opentelemetry.io/collector/receiver/xreceiver" + "go.opentelemetry.io/collector/scraper" + "go.opentelemetry.io/collector/scraper/scrapererror" + "go.opentelemetry.io/collector/scraper/scraperhelper" + "go.opentelemetry.io/collector/scraper/scraperhelper/internal/controller" + "go.opentelemetry.io/collector/scraper/xscraper" +) + +const ( + // scraperKey used to identify scrapers in metrics and traces. + scraperKey = "scraper" + spanNameSep = "/" + // receiverKey used to identify receivers in metrics and traces. + receiverKey = "receiver" + // FormatKey used to identify the format of the data received. + formatKey = "format" +) + +type factoryWithConfig struct { + f xscraper.Factory + cfg component.Config +} + +type controllerOptions struct { + tickerCh <-chan time.Time + factoriesWithConfig []factoryWithConfig +} + +// ControllerOption apply changes to internal options. +type ControllerOption interface { + apply(*controllerOptions) +} + +type optionFunc func(*controllerOptions) + +func (of optionFunc) apply(e *controllerOptions) { + of(e) +} + +// AddProfilesScraper configures the xscraper.Profiles to be called with the specified options, +// and at the specified collection interval. +// +// Observability information will be reported, and the scraped profiles +// will be passed to the next consumer. +func AddProfilesScraper(t component.Type, sc xscraper.Profiles) ControllerOption { + f := xscraper.NewFactory(t, nil, + xscraper.WithProfiles(func(context.Context, scraper.Settings, component.Config) (xscraper.Profiles, error) { + return sc, nil + }, component.StabilityLevelDevelopment)) + return AddFactoryWithConfig(f, nil) +} + +// AddFactoryWithConfig configures the scraper.Factory and associated config that +// will be used to create a new scraper. The created scraper will be called with +// the specified options, and at the specified collection interval. +// +// Observability information will be reported, and the scraped metrics +// will be passed to the next consumer. +func AddFactoryWithConfig(f xscraper.Factory, cfg component.Config) ControllerOption { + return optionFunc(func(o *controllerOptions) { + o.factoriesWithConfig = append(o.factoriesWithConfig, factoryWithConfig{f: f, cfg: cfg}) + }) +} + +// WithTickerChannel allows you to override the scraper controller's ticker +// channel to specify when scrape is called. This is only expected to be +// used by tests. +func WithTickerChannel(tickerCh <-chan time.Time) ControllerOption { + return optionFunc(func(o *controllerOptions) { + o.tickerCh = tickerCh + }) +} + +// NewProfilesController creates a receiver.Profiles with the configured options, that can control multiple xscraper.Profiles. +func NewProfilesController(cfg *scraperhelper.ControllerConfig, + rSet receiver.Settings, + nextConsumer xconsumer.Profiles, + options ...ControllerOption, +) (xreceiver.Profiles, error) { + co := getOptions(options) + scrapers := make([]xscraper.Profiles, 0, len(co.factoriesWithConfig)) + for _, fwc := range co.factoriesWithConfig { + set := controller.GetSettings(fwc.f.Type(), rSet) + s, err := fwc.f.CreateProfiles(context.Background(), set, fwc.cfg) + if err != nil { + return nil, err + } + s, err = wrapObsProfiles(s, rSet.ID, set.ID, set.TelemetrySettings) + if err != nil { + return nil, err + } + scrapers = append(scrapers, s) + } + return controller.NewController[xscraper.Profiles]( + cfg, rSet, scrapers, func(c *controller.Controller[xscraper.Profiles]) { scrapeProfiles(c, nextConsumer) }, co.tickerCh) +} + +func getOptions(options []ControllerOption) controllerOptions { + co := controllerOptions{} + for _, op := range options { + op.apply(&co) + } + return co +} + +func scrapeProfiles(c *controller.Controller[xscraper.Profiles], nextConsumer xconsumer.Profiles) { + ctx, done := controller.WithScrapeContext(c.Timeout) + defer done() + + profiles := pprofile.NewProfiles() + for i := range c.Scrapers { + md, err := c.Scrapers[i].ScrapeProfiles(ctx) + if err != nil && !scrapererror.IsPartialScrapeError(err) { + continue + } + md.ResourceProfiles().MoveAndAppendTo(profiles.ResourceProfiles()) + } + + // TODO: Add proper receiver observability for profiles when receiverhelper supports it + // For now, we skip the obs report and just consume the profiles directly + _ = nextConsumer.ConsumeProfiles(ctx, profiles) +} diff --git a/scraper/scraperhelper/xscraperhelper/controller_test.go b/scraper/scraperhelper/xscraperhelper/controller_test.go new file mode 100644 index 000000000000..460d5a4731a4 --- /dev/null +++ b/scraper/scraperhelper/xscraperhelper/controller_test.go @@ -0,0 +1,484 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +// Package xscraperhelper provides utilities for scrapers. +package xscraperhelper // import "go.opentelemetry.io/collector/scraper/scraperhelper/xscraperhelper" + +import ( + "context" + "errors" + "testing" + "time" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "go.opentelemetry.io/otel/attribute" + "go.opentelemetry.io/otel/metric" + "go.opentelemetry.io/otel/sdk/metric/metricdata" + "go.opentelemetry.io/otel/sdk/metric/metricdata/metricdatatest" + "go.uber.org/multierr" + + "go.opentelemetry.io/collector/component" + "go.opentelemetry.io/collector/component/componenttest" + "go.opentelemetry.io/collector/consumer/consumertest" + "go.opentelemetry.io/collector/pdata/pprofile" + "go.opentelemetry.io/collector/receiver" + "go.opentelemetry.io/collector/receiver/receivertest" + "go.opentelemetry.io/collector/scraper" + "go.opentelemetry.io/collector/scraper/scrapererror" + "go.opentelemetry.io/collector/scraper/scraperhelper" + "go.opentelemetry.io/collector/scraper/scraperhelper/internal/testhelper" + "go.opentelemetry.io/collector/scraper/scraperhelper/xscraperhelper/internal/metadatatest" + "go.opentelemetry.io/collector/scraper/xscraper" +) + +type testScrape struct { + ch chan int + timesScrapeCalled int + err error +} + +func (ts *testScrape) scrapeProfiles(context.Context) (pprofile.Profiles, error) { + ts.timesScrapeCalled++ + ts.ch <- ts.timesScrapeCalled + + if ts.err != nil { + return pprofile.Profiles{}, ts.err + } + + md := pprofile.NewProfiles() + profile := md.ResourceProfiles().AppendEmpty().ScopeProfiles().AppendEmpty().Profiles().AppendEmpty() + profile.Samples().AppendEmpty() + return md, nil +} + +func newTestNoDelaySettings() *scraperhelper.ControllerConfig { + return &scraperhelper.ControllerConfig{ + CollectionInterval: time.Second, + InitialDelay: 0, + } +} + +type scraperTestCase struct { + name string + + scrapers int + scraperControllerSettings *scraperhelper.ControllerConfig + scrapeErr error + expectScraped bool + + initialize bool + close bool + initializeErr error + closeErr error +} + +func TestProfilesScrapeController(t *testing.T) { + testCases := []scraperTestCase{ + { + name: "NoScrapers", + }, + { + name: "AddProfilesScrapersWithCollectionInterval", + scrapers: 2, + expectScraped: true, + }, + { + name: "AddProfilesScrapers_ScrapeError", + scrapers: 2, + scrapeErr: errors.New("err1"), + }, + { + name: "AddProfilesScrapersWithInitializeAndClose", + scrapers: 2, + initialize: true, + expectScraped: true, + close: true, + }, + { + name: "AddProfilesScrapersWithInitializeAndCloseErrors", + scrapers: 2, + initialize: true, + close: true, + initializeErr: errors.New("err1"), + closeErr: errors.New("err2"), + }, + } + + for _, test := range testCases { + t.Run(test.name, func(t *testing.T) { + receiverID := component.MustNewID("receiver") + tel := componenttest.NewTelemetry() + t.Cleanup(func() { require.NoError(t, tel.Shutdown(context.Background())) }) + + set := tel.NewTelemetrySettings() + _, parentSpan := set.TracerProvider.Tracer("test").Start(context.Background(), t.Name()) + defer parentSpan.End() + + initializeChs := make([]chan bool, test.scrapers) + scrapeProfilesChs := make([]chan int, test.scrapers) + closeChs := make([]chan bool, test.scrapers) + options := configureProfilesOptions(t, test, initializeChs, scrapeProfilesChs, closeChs) + + tickerCh := make(chan time.Time) + options = append(options, WithTickerChannel(tickerCh)) + + sink := new(consumertest.ProfilesSink) + cfg := newTestNoDelaySettings() + if test.scraperControllerSettings != nil { + cfg = test.scraperControllerSettings + } + + mr, err := NewProfilesController(cfg, receiver.Settings{ID: receiverID, TelemetrySettings: set, BuildInfo: component.NewDefaultBuildInfo()}, sink, options...) + require.NoError(t, err) + + err = mr.Start(context.Background(), componenttest.NewNopHost()) + expectedStartErr := getExpectedStartErr(test) + if expectedStartErr != nil { + assert.Equal(t, expectedStartErr, err) + } else if test.initialize { + testhelper.AssertChannelsCalled(t, initializeChs, "start was not called") + } + + const iterations = 5 + + if test.expectScraped || test.scrapeErr != nil { + // validate that scrape is called at least N times for each configured scraper + for _, ch := range scrapeProfilesChs { + <-ch + } + // Consume the initial scrapes on start + for range iterations { + tickerCh <- time.Now() + + for _, ch := range scrapeProfilesChs { + <-ch + } + } + + // wait until all calls to scrape have completed + if test.scrapeErr == nil { + require.Eventually(t, func() bool { + return sink.SampleCount() == (1+iterations)*(test.scrapers) + }, time.Second, time.Millisecond) + } + + if test.expectScraped { + assert.GreaterOrEqual(t, sink.SampleCount(), iterations) + } + + spans := tel.SpanRecorder.Ended() + testhelper.AssertScraperSpan(t, test.scrapeErr, spans, "scraper/scraper/ScrapeProfiles") + assertProfilesScraperObsMetrics(t, tel, receiverID, component.MustNewID("scraper"), test.scrapeErr, sink) + } + + err = mr.Shutdown(context.Background()) + expectedShutdownErr := getExpectedShutdownErr(test) + if expectedShutdownErr != nil { + assert.EqualError(t, err, expectedShutdownErr.Error()) + } else if test.close { + testhelper.AssertChannelsCalled(t, closeChs, "shutdown was not called") + } + }) + } +} + +func getExpectedStartErr(test scraperTestCase) error { + return test.initializeErr +} + +func getExpectedShutdownErr(test scraperTestCase) error { + var errs []error + + if test.closeErr != nil { + for i := 0; i < test.scrapers; i++ { + errs = append(errs, test.closeErr) + } + } + + return multierr.Combine(errs...) +} + +func configureProfilesOptions(t *testing.T, test scraperTestCase, initializeChs []chan bool, scrapeProfilesChs []chan int, closeChs []chan bool) []ControllerOption { + var profilesOptions []ControllerOption + + for i := 0; i < test.scrapers; i++ { + scrapeProfilesChs[i] = make(chan int) + ts := &testScrape{ch: scrapeProfilesChs[i], err: test.scrapeErr} + + var xscraperOptions []xscraper.Option + if test.initialize { + initializeChs[i] = make(chan bool, 1) + ti := testhelper.NewTestInitialize(initializeChs[i], test.initializeErr) + xscraperOptions = append(xscraperOptions, xscraper.WithStart(ti.Start)) + } + if test.close { + closeChs[i] = make(chan bool, 1) + tc := testhelper.NewTestClose(closeChs[i], test.closeErr) + xscraperOptions = append(xscraperOptions, xscraper.WithShutdown(tc.Shutdown)) + } + + scp, err := xscraper.NewProfiles(ts.scrapeProfiles, xscraperOptions...) + require.NoError(t, err) + + profilesOptions = append(profilesOptions, AddProfilesScraper(component.MustNewType("scraper"), scp)) + } + + return profilesOptions +} + +func TestSingleProfilesScraperPerInterval(t *testing.T) { + scrapeCh := make(chan int, 10) + ts := &testScrape{ch: scrapeCh} + + cfg := newTestNoDelaySettings() + + tickerCh := make(chan time.Time) + + scp, err := xscraper.NewProfiles(ts.scrapeProfiles) + require.NoError(t, err) + + recv, err := NewProfilesController( + cfg, + receivertest.NewNopSettings(receivertest.NopType), + new(consumertest.ProfilesSink), + AddProfilesScraper(component.MustNewType("scraper"), scp), + WithTickerChannel(tickerCh), + ) + require.NoError(t, err) + + require.NoError(t, recv.Start(context.Background(), componenttest.NewNopHost())) + defer func() { require.NoError(t, recv.Shutdown(context.Background())) }() + + tickerCh <- time.Now() + + assert.Eventually( + t, + func() bool { + return <-scrapeCh == 2 + }, + 300*time.Millisecond, + 100*time.Millisecond, + "Make sure the scraper channel is called twice", + ) + + select { + case <-scrapeCh: + assert.Fail(t, "Scrape was called more than twice") + case <-time.After(100 * time.Millisecond): + return + } +} + +func TestProfilesScraperControllerStartsOnInit(t *testing.T) { + t.Parallel() + + ts := &testScrape{ + ch: make(chan int, 1), + } + + scp, err := xscraper.NewProfiles(ts.scrapeProfiles) + require.NoError(t, err, "Must not error when creating scraper") + + r, err := NewProfilesController( + &scraperhelper.ControllerConfig{ + CollectionInterval: time.Hour, + InitialDelay: 0, + }, + receivertest.NewNopSettings(receivertest.NopType), + new(consumertest.ProfilesSink), + AddProfilesScraper(component.MustNewType("scraper"), scp), + ) + require.NoError(t, err, "Must not error when creating scrape controller") + + assert.NoError(t, r.Start(context.Background(), componenttest.NewNopHost()), "Must not error on start") + <-time.After(500 * time.Nanosecond) + require.NoError(t, r.Shutdown(context.Background()), "Must not have errored on shutdown") + assert.Equal(t, 1, ts.timesScrapeCalled, "Must have been called as soon as the controller started") +} + +func TestProfilesScraperControllerInitialDelay(t *testing.T) { + if testing.Short() { + t.Skip("This requires real time to pass, skipping") + return + } + + t.Parallel() + + var ( + elapsed = make(chan time.Time, 1) + cfg = scraperhelper.ControllerConfig{ + CollectionInterval: time.Second, + InitialDelay: 300 * time.Millisecond, + } + ) + + scp, err := xscraper.NewProfiles(func(context.Context) (pprofile.Profiles, error) { + elapsed <- time.Now() + return pprofile.NewProfiles(), nil + }) + require.NoError(t, err, "Must not error when creating scraper") + + r, err := NewProfilesController( + &cfg, + receivertest.NewNopSettings(receivertest.NopType), + new(consumertest.ProfilesSink), + AddProfilesScraper(component.MustNewType("scraper"), scp), + ) + require.NoError(t, err, "Must not error when creating receiver") + + t0 := time.Now() + require.NoError(t, r.Start(context.Background(), componenttest.NewNopHost()), "Must not error when starting") + t1 := <-elapsed + + assert.GreaterOrEqual(t, t1.Sub(t0), 300*time.Millisecond, "Must have had 300ms pass as defined by initial delay") + + assert.NoError(t, r.Shutdown(context.Background()), "Must not error closing down") +} + +func TestProfilesScraperShutdownBeforeScrapeCanStart(t *testing.T) { + cfg := scraperhelper.ControllerConfig{ + CollectionInterval: time.Second, + InitialDelay: 5 * time.Second, + } + + scp, err := xscraper.NewProfiles(func(context.Context) (pprofile.Profiles, error) { + // make the scraper wait for long enough it would disrupt a shutdown. + time.Sleep(30 * time.Second) + return pprofile.NewProfiles(), nil + }) + require.NoError(t, err, "Must not error when creating scraper") + + r, err := NewProfilesController( + &cfg, + receivertest.NewNopSettings(receivertest.NopType), + new(consumertest.ProfilesSink), + AddProfilesScraper(component.MustNewType("scraper"), scp), + ) + require.NoError(t, err, "Must not error when creating receiver") + require.NoError(t, r.Start(context.Background(), componenttest.NewNopHost())) + shutdown := make(chan struct{}, 1) + go func() { + assert.NoError(t, r.Shutdown(context.Background())) + close(shutdown) + }() + timer := time.NewTicker(10 * time.Second) + select { + case <-timer.C: + require.Fail(t, "shutdown should not wait for scraping") + case <-shutdown: + } +} + +func assertProfilesScraperObsMetrics(t *testing.T, tel *componenttest.Telemetry, receiver, scraper component.ID, expectedErr error, sink *consumertest.ProfilesSink) { + sampleCounts := 0 + for _, md := range sink.AllProfiles() { + sampleCounts += md.SampleCount() + } + + expectedScraped := int64(sink.SampleCount()) + expectedErrored := int64(0) + if expectedErr != nil { + var partialError scrapererror.PartialScrapeError + if errors.As(expectedErr, &partialError) { + expectedErrored = int64(partialError.Failed) + } else { + expectedScraped = int64(0) + expectedErrored = int64(sink.SampleCount()) + } + } + + metadatatest.AssertEqualScraperScrapedProfileRecords(t, tel, + []metricdata.DataPoint[int64]{ + { + Attributes: attribute.NewSet( + attribute.String(receiverKey, receiver.String()), + attribute.String(scraperKey, scraper.String())), + Value: expectedScraped, + }, + }, metricdatatest.IgnoreTimestamp(), metricdatatest.IgnoreExemplars()) + + metadatatest.AssertEqualScraperErroredProfileRecords(t, tel, + []metricdata.DataPoint[int64]{ + { + Attributes: attribute.NewSet( + attribute.String(receiverKey, receiver.String()), + attribute.String(scraperKey, scraper.String())), + Value: expectedErrored, + }, + }, metricdatatest.IgnoreTimestamp(), metricdatatest.IgnoreExemplars()) +} + +// TestNewProfilesControllerCreateError tests that NewProfilesController returns an error +// when the scraper factory's CreateProfiles method fails. +func TestNewProfilesControllerCreateError(t *testing.T) { + expectedErr := errors.New("create profiles error") + f := xscraper.NewFactory(component.MustNewType("scraper"), nil, + xscraper.WithProfiles(func(context.Context, scraper.Settings, component.Config) (xscraper.Profiles, error) { + return nil, expectedErr + }, component.StabilityLevelDevelopment)) + + cfg := newTestNoDelaySettings() + _, err := NewProfilesController( + cfg, + receivertest.NewNopSettings(receivertest.NopType), + new(consumertest.ProfilesSink), + AddFactoryWithConfig(f, nil), + ) + + require.Error(t, err) + assert.Equal(t, expectedErr, err) +} + +// errorMeter is a meter that returns errors when creating instruments. +type errorMeter struct { + metric.Meter +} + +func (errorMeter) Int64Counter(string, ...metric.Int64CounterOption) (metric.Int64Counter, error) { + return nil, errors.New("counter creation error") +} + +// errorMeterProvider provides errorMeter instances. +type errorMeterProvider struct { + metric.MeterProvider +} + +func (errorMeterProvider) Meter(string, ...metric.MeterOption) metric.Meter { + return errorMeter{} +} + +// TestNewProfilesControllerTelemetryError tests that NewProfilesController returns an error +// when telemetry builder creation fails. +func TestNewProfilesControllerTelemetryError(t *testing.T) { + // Create a scraper that works + scp, err := xscraper.NewProfiles(func(context.Context) (pprofile.Profiles, error) { + return pprofile.NewProfiles(), nil + }) + require.NoError(t, err) + + f := xscraper.NewFactory(component.MustNewType("scraper"), nil, + xscraper.WithProfiles(func(context.Context, scraper.Settings, component.Config) (xscraper.Profiles, error) { + return scp, nil + }, component.StabilityLevelDevelopment)) + + // Create telemetry settings with a meter provider that fails + set := componenttest.NewNopTelemetrySettings() + set.MeterProvider = errorMeterProvider{} + + cfg := newTestNoDelaySettings() + _, err = NewProfilesController( + cfg, + receiver.Settings{ + ID: component.MustNewID("receiver"), + TelemetrySettings: set, + BuildInfo: component.NewDefaultBuildInfo(), + }, + new(consumertest.ProfilesSink), + AddFactoryWithConfig(f, nil), + ) + + // The error should be from wrapObsProfiles failing due to telemetry builder creation + require.Error(t, err) + assert.Contains(t, err.Error(), "counter creation error") +} diff --git a/scraper/scraperhelper/xscraperhelper/doc.go b/scraper/scraperhelper/xscraperhelper/doc.go new file mode 100644 index 000000000000..5f903305051b --- /dev/null +++ b/scraper/scraperhelper/xscraperhelper/doc.go @@ -0,0 +1,7 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +//go:generate mdatagen metadata.yaml + +// Package xscraperhelper provides utilities for scrapers. +package xscraperhelper // import "go.opentelemetry.io/collector/scraper/scraperhelper/xscraperhelper" diff --git a/scraper/scraperhelper/xscraperhelper/documentation.md b/scraper/scraperhelper/xscraperhelper/documentation.md new file mode 100644 index 000000000000..021178f5723a --- /dev/null +++ b/scraper/scraperhelper/xscraperhelper/documentation.md @@ -0,0 +1,23 @@ +[comment]: <> (Code generated by mdatagen. DO NOT EDIT.) + +# xscraperhelper + +## Internal Telemetry + +The following telemetry is emitted by this component. + +### otelcol_scraper_errored_profile_records + +Number of profile records that were unable to be scraped. + +| Unit | Metric Type | Value Type | Monotonic | Stability | +| ---- | ----------- | ---------- | --------- | --------- | +| {datapoint} | Sum | Int | true | Alpha | + +### otelcol_scraper_scraped_profile_records + +Number of profile records successfully scraped. + +| Unit | Metric Type | Value Type | Monotonic | Stability | +| ---- | ----------- | ---------- | --------- | --------- | +| {datapoint} | Sum | Int | true | Alpha | diff --git a/scraper/scraperhelper/xscraperhelper/generated_package_test.go b/scraper/scraperhelper/xscraperhelper/generated_package_test.go new file mode 100644 index 000000000000..18a0e9ad5d7e --- /dev/null +++ b/scraper/scraperhelper/xscraperhelper/generated_package_test.go @@ -0,0 +1,13 @@ +// Code generated by mdatagen. DO NOT EDIT. + +package xscraperhelper + +import ( + "testing" + + "go.uber.org/goleak" +) + +func TestMain(m *testing.M) { + goleak.VerifyTestMain(m) +} diff --git a/scraper/scraperhelper/xscraperhelper/go.mod b/scraper/scraperhelper/xscraperhelper/go.mod new file mode 100644 index 000000000000..af91d69b8329 --- /dev/null +++ b/scraper/scraperhelper/xscraperhelper/go.mod @@ -0,0 +1,96 @@ +module go.opentelemetry.io/collector/scraper/scraperhelper/xscraperhelper + +go 1.25.0 + +require ( + github.com/stretchr/testify v1.11.1 + go.opentelemetry.io/collector/component v1.54.0 + go.opentelemetry.io/collector/component/componenttest v0.148.0 + go.opentelemetry.io/collector/consumer/consumertest v0.148.0 + go.opentelemetry.io/collector/consumer/xconsumer v0.148.0 + go.opentelemetry.io/collector/pdata/pprofile v0.148.0 + go.opentelemetry.io/collector/pdata/testdata v0.148.0 + go.opentelemetry.io/collector/pipeline/xpipeline v0.148.0 + go.opentelemetry.io/collector/receiver v1.54.0 + go.opentelemetry.io/collector/receiver/receivertest v0.148.0 + go.opentelemetry.io/collector/receiver/xreceiver v0.148.0 + go.opentelemetry.io/collector/scraper v0.148.0 + go.opentelemetry.io/collector/scraper/scraperhelper v0.148.0 + go.opentelemetry.io/collector/scraper/xscraper v0.148.0 + go.opentelemetry.io/otel v1.42.0 + go.opentelemetry.io/otel/metric v1.42.0 + go.opentelemetry.io/otel/sdk/metric v1.42.0 + go.opentelemetry.io/otel/trace v1.42.0 + go.uber.org/goleak v1.3.0 + go.uber.org/multierr v1.11.0 + go.uber.org/zap v1.27.1 +) + +require ( + github.com/cespare/xxhash/v2 v2.3.0 // indirect + github.com/davecgh/go-spew v1.1.1 // indirect + github.com/go-logr/logr v1.4.3 // indirect + github.com/go-logr/stdr v1.2.2 // indirect + github.com/google/uuid v1.6.0 // indirect + github.com/hashicorp/go-version v1.8.0 // indirect + github.com/json-iterator/go v1.1.12 // indirect + github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect + github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee // indirect + github.com/pmezard/go-difflib v1.0.0 // indirect + go.opentelemetry.io/auto/sdk v1.2.1 // indirect + go.opentelemetry.io/collector/consumer v1.54.0 // indirect + go.opentelemetry.io/collector/consumer/consumererror v0.148.0 // indirect + go.opentelemetry.io/collector/featuregate v1.54.0 // indirect + go.opentelemetry.io/collector/internal/componentalias v0.148.0 // indirect + go.opentelemetry.io/collector/pdata v1.54.0 // indirect + go.opentelemetry.io/collector/pipeline v1.54.0 // indirect + go.opentelemetry.io/collector/receiver/receiverhelper v0.148.0 // indirect + go.opentelemetry.io/otel/sdk v1.42.0 // indirect + golang.org/x/sys v0.41.0 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20251222181119-0a764e51fe1b // indirect + google.golang.org/grpc v1.79.3 // indirect + google.golang.org/protobuf v1.36.11 // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect +) + +replace go.opentelemetry.io/collector/scraper/scraperhelper => .. + +replace go.opentelemetry.io/collector/internal/testutil => ../../../internal/testutil + +replace go.opentelemetry.io/collector/featuregate => ../../../featuregate + +replace go.opentelemetry.io/collector/receiver/receiverhelper => ../../../receiver/receiverhelper + +replace go.opentelemetry.io/collector/pdata => ../../../pdata + +replace go.opentelemetry.io/collector/scraper/xscraper => ../../xscraper + +replace go.opentelemetry.io/collector/scraper => ../.. + +replace go.opentelemetry.io/collector/receiver => ../../../receiver + +replace go.opentelemetry.io/collector/pdata/pprofile => ../../../pdata/pprofile + +replace go.opentelemetry.io/collector/pipeline => ../../../pipeline + +replace go.opentelemetry.io/collector/pdata/testdata => ../../../pdata/testdata + +replace go.opentelemetry.io/collector/receiver/xreceiver => ../../../receiver/xreceiver + +replace go.opentelemetry.io/collector/consumer/xconsumer => ../../../consumer/xconsumer + +replace go.opentelemetry.io/collector/consumer/consumertest => ../../../consumer/consumertest + +replace go.opentelemetry.io/collector/component/componenttest => ../../../component/componenttest + +replace go.opentelemetry.io/collector/consumer/consumererror => ../../../consumer/consumererror + +replace go.opentelemetry.io/collector/consumer => ../../../consumer + +replace go.opentelemetry.io/collector/component => ../../../component + +replace go.opentelemetry.io/collector/receiver/receivertest => ../../../receiver/receivertest + +replace go.opentelemetry.io/collector/pipeline/xpipeline => ../../../pipeline/xpipeline + +replace go.opentelemetry.io/collector/internal/componentalias => ../../../internal/componentalias diff --git a/scraper/scraperhelper/xscraperhelper/go.sum b/scraper/scraperhelper/xscraperhelper/go.sum new file mode 100644 index 000000000000..c50bb5a17a77 --- /dev/null +++ b/scraper/scraperhelper/xscraperhelper/go.sum @@ -0,0 +1,80 @@ +github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= +github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI= +github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= +github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= +github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= +github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= +github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= +github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= +github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= +github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= +github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/hashicorp/go-version v1.8.0 h1:KAkNb1HAiZd1ukkxDFGmokVZe1Xy9HG6NUp+bPle2i4= +github.com/hashicorp/go-version v1.8.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= +github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= +github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= +github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= +github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= +github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= +github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= +github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee h1:W5t00kpgFdJifH4BDsTlE89Zl93FEloxaWZfGcifgq8= +github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ= +github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U= +github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= +go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64= +go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y= +go.opentelemetry.io/otel v1.42.0 h1:lSQGzTgVR3+sgJDAU/7/ZMjN9Z+vUip7leaqBKy4sho= +go.opentelemetry.io/otel v1.42.0/go.mod h1:lJNsdRMxCUIWuMlVJWzecSMuNjE7dOYyWlqOXWkdqCc= +go.opentelemetry.io/otel/metric v1.42.0 h1:2jXG+3oZLNXEPfNmnpxKDeZsFI5o4J+nz6xUlaFdF/4= +go.opentelemetry.io/otel/metric v1.42.0/go.mod h1:RlUN/7vTU7Ao/diDkEpQpnz3/92J9ko05BIwxYa2SSI= +go.opentelemetry.io/otel/sdk v1.42.0 h1:LyC8+jqk6UJwdrI/8VydAq/hvkFKNHZVIWuslJXYsDo= +go.opentelemetry.io/otel/sdk v1.42.0/go.mod h1:rGHCAxd9DAph0joO4W6OPwxjNTYWghRWmkHuGbayMts= +go.opentelemetry.io/otel/sdk/metric v1.42.0 h1:D/1QR46Clz6ajyZ3G8SgNlTJKBdGp84q9RKCAZ3YGuA= +go.opentelemetry.io/otel/sdk/metric v1.42.0/go.mod h1:Ua6AAlDKdZ7tdvaQKfSmnFTdHx37+J4ba8MwVCYM5hc= +go.opentelemetry.io/otel/trace v1.42.0 h1:OUCgIPt+mzOnaUTpOQcBiM/PLQ/Op7oq6g4LenLmOYY= +go.opentelemetry.io/otel/trace v1.42.0/go.mod h1:f3K9S+IFqnumBkKhRJMeaZeNk9epyhnCmQh/EysQCdc= +go.opentelemetry.io/proto/slim/otlp v1.10.0 h1:iR97Vs/ZDR+y9TfuP9b1XBtdPWeC+OMslIBmhcLU7jM= +go.opentelemetry.io/proto/slim/otlp v1.10.0/go.mod h1:lV9250stpjYLPNA5viFabIgP2QlUGRT1GdTgAf8SIUk= +go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.3.0 h1:RUF5rO0hAlgiJt1fzQVzcVs3vZVNHIcMLgOgG4rWNcQ= +go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.3.0/go.mod h1:I89cynRj8y+383o7tEQVg2SVA6SRgDVIouWPUVXjx0U= +go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.3.0 h1:CQvJSldHRUN6Z8jsUeYv8J0lXRvygALXIzsmAeCcZE0= +go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.3.0/go.mod h1:xSQ+mEfJe/GjK1LXEyVOoSI1N9JV9ZI923X5kup43W4= +go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= +go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= +go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= +go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= +go.uber.org/zap v1.27.1 h1:08RqriUEv8+ArZRYSTXy1LeBScaMpVSTBhCeaZYfMYc= +go.uber.org/zap v1.27.1/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= +golang.org/x/net v0.51.0 h1:94R/GTO7mt3/4wIKpcR5gkGmRLOuE/2hNGeWq/GBIFo= +golang.org/x/net v0.51.0/go.mod h1:aamm+2QF5ogm02fjy5Bb7CQ0WMt1/WVM7FtyaTLlA9Y= +golang.org/x/sys v0.41.0 h1:Ivj+2Cp/ylzLiEU89QhWblYnOE9zerudt9Ftecq2C6k= +golang.org/x/sys v0.41.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= +golang.org/x/text v0.34.0 h1:oL/Qq0Kdaqxa1KbNeMKwQq0reLCCaFtqu2eNuSeNHbk= +golang.org/x/text v0.34.0/go.mod h1:homfLqTYRFyVYemLBFl5GgL/DWEiH5wcsQ5gSh1yziA= +google.golang.org/genproto/googleapis/rpc v0.0.0-20251222181119-0a764e51fe1b h1:Mv8VFug0MP9e5vUxfBcE3vUkV6CImK3cMNMIDFjmzxU= +google.golang.org/genproto/googleapis/rpc v0.0.0-20251222181119-0a764e51fe1b/go.mod h1:j9x/tPzZkyxcgEFkiKEEGxfvyumM01BEtsW8xzOahRQ= +google.golang.org/grpc v1.79.3 h1:sybAEdRIEtvcD68Gx7dmnwjZKlyfuc61Dyo9pGXXkKE= +google.golang.org/grpc v1.79.3/go.mod h1:KmT0Kjez+0dde/v2j9vzwoAScgEPx/Bw1CYChhHLrHQ= +google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE= +google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/scraper/scraperhelper/xscraperhelper/internal/metadata/generated_telemetry.go b/scraper/scraperhelper/xscraperhelper/internal/metadata/generated_telemetry.go new file mode 100644 index 000000000000..5c8b7e8bf014 --- /dev/null +++ b/scraper/scraperhelper/xscraperhelper/internal/metadata/generated_telemetry.go @@ -0,0 +1,75 @@ +// Code generated by mdatagen. DO NOT EDIT. + +package metadata + +import ( + "errors" + "sync" + + "go.opentelemetry.io/otel/metric" + "go.opentelemetry.io/otel/trace" + + "go.opentelemetry.io/collector/component" +) + +func Meter(settings component.TelemetrySettings) metric.Meter { + return settings.MeterProvider.Meter("go.opentelemetry.io/collector/scraper/scraperhelper/xscraperhelper") +} + +func Tracer(settings component.TelemetrySettings) trace.Tracer { + return settings.TracerProvider.Tracer("go.opentelemetry.io/collector/scraper/scraperhelper/xscraperhelper") +} + +// TelemetryBuilder provides an interface for components to report telemetry +// as defined in metadata and user config. +type TelemetryBuilder struct { + meter metric.Meter + mu sync.Mutex + registrations []metric.Registration + ScraperErroredProfileRecords metric.Int64Counter + ScraperScrapedProfileRecords metric.Int64Counter +} + +// TelemetryBuilderOption applies changes to default builder. +type TelemetryBuilderOption interface { + apply(*TelemetryBuilder) +} + +type telemetryBuilderOptionFunc func(mb *TelemetryBuilder) + +func (tbof telemetryBuilderOptionFunc) apply(mb *TelemetryBuilder) { + tbof(mb) +} + +// Shutdown unregister all registered callbacks for async instruments. +func (builder *TelemetryBuilder) Shutdown() { + builder.mu.Lock() + defer builder.mu.Unlock() + for _, reg := range builder.registrations { + reg.Unregister() + } +} + +// NewTelemetryBuilder provides a struct with methods to update all internal telemetry +// for a component +func NewTelemetryBuilder(settings component.TelemetrySettings, options ...TelemetryBuilderOption) (*TelemetryBuilder, error) { + builder := TelemetryBuilder{} + for _, op := range options { + op.apply(&builder) + } + builder.meter = Meter(settings) + var err, errs error + builder.ScraperErroredProfileRecords, err = builder.meter.Int64Counter( + "otelcol_scraper_errored_profile_records", + metric.WithDescription("Number of profile records that were unable to be scraped. [Alpha]"), + metric.WithUnit("{datapoint}"), + ) + errs = errors.Join(errs, err) + builder.ScraperScrapedProfileRecords, err = builder.meter.Int64Counter( + "otelcol_scraper_scraped_profile_records", + metric.WithDescription("Number of profile records successfully scraped. [Alpha]"), + metric.WithUnit("{datapoint}"), + ) + errs = errors.Join(errs, err) + return &builder, errs +} diff --git a/scraper/scraperhelper/xscraperhelper/internal/metadata/generated_telemetry_test.go b/scraper/scraperhelper/xscraperhelper/internal/metadata/generated_telemetry_test.go new file mode 100644 index 000000000000..12b4a7b91c34 --- /dev/null +++ b/scraper/scraperhelper/xscraperhelper/internal/metadata/generated_telemetry_test.go @@ -0,0 +1,74 @@ +// Code generated by mdatagen. DO NOT EDIT. + +package metadata + +import ( + "testing" + + "github.com/stretchr/testify/require" + "go.opentelemetry.io/otel/metric" + embeddedmetric "go.opentelemetry.io/otel/metric/embedded" + noopmetric "go.opentelemetry.io/otel/metric/noop" + "go.opentelemetry.io/otel/trace" + embeddedtrace "go.opentelemetry.io/otel/trace/embedded" + nooptrace "go.opentelemetry.io/otel/trace/noop" + + "go.opentelemetry.io/collector/component" + "go.opentelemetry.io/collector/component/componenttest" +) + +type mockMeter struct { + noopmetric.Meter + name string +} +type mockMeterProvider struct { + embeddedmetric.MeterProvider +} + +func (m mockMeterProvider) Meter(name string, opts ...metric.MeterOption) metric.Meter { + return mockMeter{name: name} +} + +type mockTracer struct { + nooptrace.Tracer + name string +} + +type mockTracerProvider struct { + embeddedtrace.TracerProvider +} + +func (m mockTracerProvider) Tracer(name string, opts ...trace.TracerOption) trace.Tracer { + return mockTracer{name: name} +} + +func TestProviders(t *testing.T) { + set := component.TelemetrySettings{ + MeterProvider: mockMeterProvider{}, + TracerProvider: mockTracerProvider{}, + } + + meter := Meter(set) + if m, ok := meter.(mockMeter); ok { + require.Equal(t, "go.opentelemetry.io/collector/scraper/scraperhelper/xscraperhelper", m.name) + } else { + require.Fail(t, "returned Meter not mockMeter") + } + + tracer := Tracer(set) + if m, ok := tracer.(mockTracer); ok { + require.Equal(t, "go.opentelemetry.io/collector/scraper/scraperhelper/xscraperhelper", m.name) + } else { + require.Fail(t, "returned Meter not mockTracer") + } +} + +func TestNewTelemetryBuilder(t *testing.T) { + set := componenttest.NewNopTelemetrySettings() + applied := false + _, err := NewTelemetryBuilder(set, telemetryBuilderOptionFunc(func(b *TelemetryBuilder) { + applied = true + })) + require.NoError(t, err) + require.True(t, applied) +} diff --git a/scraper/scraperhelper/xscraperhelper/internal/metadatatest/generated_telemetrytest.go b/scraper/scraperhelper/xscraperhelper/internal/metadatatest/generated_telemetrytest.go new file mode 100644 index 000000000000..dd5f3aca2838 --- /dev/null +++ b/scraper/scraperhelper/xscraperhelper/internal/metadatatest/generated_telemetrytest.go @@ -0,0 +1,45 @@ +// Code generated by mdatagen. DO NOT EDIT. + +package metadatatest + +import ( + "testing" + + "github.com/stretchr/testify/require" + "go.opentelemetry.io/otel/sdk/metric/metricdata" + "go.opentelemetry.io/otel/sdk/metric/metricdata/metricdatatest" + + "go.opentelemetry.io/collector/component/componenttest" +) + +func AssertEqualScraperErroredProfileRecords(t *testing.T, tt *componenttest.Telemetry, dps []metricdata.DataPoint[int64], opts ...metricdatatest.Option) { + want := metricdata.Metrics{ + Name: "otelcol_scraper_errored_profile_records", + Description: "Number of profile records that were unable to be scraped. [Alpha]", + Unit: "{datapoint}", + Data: metricdata.Sum[int64]{ + Temporality: metricdata.CumulativeTemporality, + IsMonotonic: true, + DataPoints: dps, + }, + } + got, err := tt.GetMetric("otelcol_scraper_errored_profile_records") + require.NoError(t, err) + metricdatatest.AssertEqual(t, want, got, opts...) +} + +func AssertEqualScraperScrapedProfileRecords(t *testing.T, tt *componenttest.Telemetry, dps []metricdata.DataPoint[int64], opts ...metricdatatest.Option) { + want := metricdata.Metrics{ + Name: "otelcol_scraper_scraped_profile_records", + Description: "Number of profile records successfully scraped. [Alpha]", + Unit: "{datapoint}", + Data: metricdata.Sum[int64]{ + Temporality: metricdata.CumulativeTemporality, + IsMonotonic: true, + DataPoints: dps, + }, + } + got, err := tt.GetMetric("otelcol_scraper_scraped_profile_records") + require.NoError(t, err) + metricdatatest.AssertEqual(t, want, got, opts...) +} diff --git a/scraper/scraperhelper/xscraperhelper/internal/metadatatest/generated_telemetrytest_test.go b/scraper/scraperhelper/xscraperhelper/internal/metadatatest/generated_telemetrytest_test.go new file mode 100644 index 000000000000..811dc2363fa8 --- /dev/null +++ b/scraper/scraperhelper/xscraperhelper/internal/metadatatest/generated_telemetrytest_test.go @@ -0,0 +1,32 @@ +// Code generated by mdatagen. DO NOT EDIT. + +package metadatatest + +import ( + "context" + "testing" + + "github.com/stretchr/testify/require" + "go.opentelemetry.io/otel/sdk/metric/metricdata" + "go.opentelemetry.io/otel/sdk/metric/metricdata/metricdatatest" + + "go.opentelemetry.io/collector/component/componenttest" + "go.opentelemetry.io/collector/scraper/scraperhelper/xscraperhelper/internal/metadata" +) + +func TestSetupTelemetry(t *testing.T) { + testTel := componenttest.NewTelemetry() + tb, err := metadata.NewTelemetryBuilder(testTel.NewTelemetrySettings()) + require.NoError(t, err) + defer tb.Shutdown() + tb.ScraperErroredProfileRecords.Add(context.Background(), 1) + tb.ScraperScrapedProfileRecords.Add(context.Background(), 1) + AssertEqualScraperErroredProfileRecords(t, testTel, + []metricdata.DataPoint[int64]{{Value: 1}}, + metricdatatest.IgnoreTimestamp()) + AssertEqualScraperScrapedProfileRecords(t, testTel, + []metricdata.DataPoint[int64]{{Value: 1}}, + metricdatatest.IgnoreTimestamp()) + + require.NoError(t, testTel.Shutdown(context.Background())) +} diff --git a/scraper/scraperhelper/xscraperhelper/metadata.yaml b/scraper/scraperhelper/xscraperhelper/metadata.yaml new file mode 100644 index 000000000000..ae89192b435d --- /dev/null +++ b/scraper/scraperhelper/xscraperhelper/metadata.yaml @@ -0,0 +1,31 @@ +type: xscraperhelper +github_project: open-telemetry/opentelemetry-collector + +status: + disable_codecov_badge: true + class: pkg + codeowners: + active: + - florianl + stability: + development: [profiles] + +telemetry: + metrics: + scraper_errored_profile_records: + enabled: true + stability: alpha + description: Number of profile records that were unable to be scraped. + unit: "{datapoint}" + sum: + value_type: int + monotonic: true + + scraper_scraped_profile_records: + enabled: true + stability: alpha + description: Number of profile records successfully scraped. + unit: "{datapoint}" + sum: + value_type: int + monotonic: true diff --git a/scraper/scraperhelper/xscraperhelper/obs_profiles.go b/scraper/scraperhelper/xscraperhelper/obs_profiles.go new file mode 100644 index 000000000000..084600c24a9b --- /dev/null +++ b/scraper/scraperhelper/xscraperhelper/obs_profiles.go @@ -0,0 +1,85 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +// Package xscraperhelper provides utilities for scrapers. +package xscraperhelper // import "go.opentelemetry.io/collector/scraper/scraperhelper/xscraperhelper" + +import ( + "context" + "errors" + + "go.opentelemetry.io/otel/attribute" + "go.opentelemetry.io/otel/codes" + "go.opentelemetry.io/otel/metric" + "go.uber.org/zap" + + "go.opentelemetry.io/collector/component" + "go.opentelemetry.io/collector/pdata/pprofile" + "go.opentelemetry.io/collector/pipeline/xpipeline" + "go.opentelemetry.io/collector/scraper/scrapererror" + "go.opentelemetry.io/collector/scraper/scraperhelper/xscraperhelper/internal/metadata" + "go.opentelemetry.io/collector/scraper/xscraper" +) + +const ( + + // scrapedProfileRecordsKey used to identify profile records scraped by the + // Collector. + scrapedProfileRecordsKey = "scraped_profile_records" + // erroredProfileRecordsKey used to identify profile records errored (i.e. + // unable to be scraped) by the Collector. + erroredProfileRecordsKey = "errored_profile_records" +) + +func wrapObsProfiles(sc xscraper.Profiles, receiverID, scraperID component.ID, set component.TelemetrySettings) (xscraper.Profiles, error) { + telemetryBuilder, errBuilder := metadata.NewTelemetryBuilder(set) + if errBuilder != nil { + return nil, errBuilder + } + + tracer := metadata.Tracer(set) + spanName := scraperKey + spanNameSep + scraperID.String() + spanNameSep + "ScrapeProfiles" + otelAttrs := metric.WithAttributeSet(attribute.NewSet( + attribute.String(receiverKey, receiverID.String()), + attribute.String(scraperKey, scraperID.String()), + )) + + scraperFuncs := func(ctx context.Context) (pprofile.Profiles, error) { + ctx, span := tracer.Start(ctx, spanName) + defer span.End() + + md, err := sc.ScrapeProfiles(ctx) + numScrapedProfiles := 0 + numErroredProfiles := 0 + if err != nil { + set.Logger.Error("Error scraping profiles", zap.Error(err)) + var partialErr scrapererror.PartialScrapeError + if errors.As(err, &partialErr) { + numErroredProfiles = partialErr.Failed + numScrapedProfiles = md.ProfileCount() + } + } else { + numScrapedProfiles = md.ProfileCount() + } + + telemetryBuilder.ScraperScrapedProfileRecords.Add(ctx, int64(numScrapedProfiles), otelAttrs) + telemetryBuilder.ScraperErroredProfileRecords.Add(ctx, int64(numErroredProfiles), otelAttrs) + + // end span according to errors + if span.IsRecording() { + span.SetAttributes( + attribute.String(formatKey, xpipeline.SignalProfiles.String()), + attribute.Int64(scrapedProfileRecordsKey, int64(numScrapedProfiles)), + attribute.Int64(erroredProfileRecordsKey, int64(numErroredProfiles)), + ) + + if err != nil { + span.SetStatus(codes.Error, err.Error()) + } + } + + return md, err + } + + return xscraper.NewProfiles(scraperFuncs, xscraper.WithStart(sc.Start), xscraper.WithShutdown(sc.Shutdown)) +} diff --git a/scraper/scraperhelper/xscraperhelper/obs_profiles_test.go b/scraper/scraperhelper/xscraperhelper/obs_profiles_test.go new file mode 100644 index 000000000000..3a10da77665f --- /dev/null +++ b/scraper/scraperhelper/xscraperhelper/obs_profiles_test.go @@ -0,0 +1,169 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +// Package xscraperhelper provides utilities for scrapers. +package xscraperhelper // import "go.opentelemetry.io/collector/scraper/scraperhelper/xscraperhelper" + +import ( + "context" + "errors" + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "go.opentelemetry.io/otel/attribute" + "go.opentelemetry.io/otel/codes" + "go.opentelemetry.io/otel/sdk/metric/metricdata" + "go.opentelemetry.io/otel/sdk/metric/metricdata/metricdatatest" + "go.uber.org/zap" + "go.uber.org/zap/zaptest/observer" + + "go.opentelemetry.io/collector/component" + "go.opentelemetry.io/collector/component/componenttest" + "go.opentelemetry.io/collector/pdata/pprofile" + "go.opentelemetry.io/collector/pdata/testdata" + "go.opentelemetry.io/collector/receiver" + "go.opentelemetry.io/collector/scraper/scrapererror" + "go.opentelemetry.io/collector/scraper/scraperhelper/internal/controller" + "go.opentelemetry.io/collector/scraper/scraperhelper/xscraperhelper/internal/metadatatest" + "go.opentelemetry.io/collector/scraper/xscraper" +) + +var ( + receiverID = component.MustNewID("fakeReceiver") + scraperID = component.MustNewID("fakeScraper") + + errFake = errors.New("errFake") + partialErrFake = scrapererror.NewPartialScrapeError(errFake, 2) +) + +type testParams struct { + items int + err error +} + +func TestScrapeProfilesDataOp(t *testing.T) { + tel := componenttest.NewTelemetry() + t.Cleanup(func() { require.NoError(t, tel.Shutdown(context.Background())) }) + + set := tel.NewTelemetrySettings() + + parentCtx, parentSpan := set.TracerProvider.Tracer("test").Start(context.Background(), t.Name()) + defer parentSpan.End() + + params := []testParams{ + {items: 23, err: partialErrFake}, + {items: 29, err: errFake}, + {items: 15, err: nil}, + } + for i := range params { + sm, err := xscraper.NewProfiles(func(context.Context) (pprofile.Profiles, error) { + return testdata.GenerateProfiles(params[i].items), params[i].err + }) + require.NoError(t, err) + sf, err := wrapObsProfiles(sm, receiverID, scraperID, set) + require.NoError(t, err) + _, err = sf.ScrapeProfiles(parentCtx) + require.ErrorIs(t, err, params[i].err) + } + + spans := tel.SpanRecorder.Ended() + require.Len(t, spans, len(params)) + + var scrapedProfileRecords, erroredProfileRecords int + for i, span := range spans { + assert.Equal(t, "scraper/"+scraperID.String()+"/ScrapeProfiles", span.Name()) + switch { + case params[i].err == nil: + scrapedProfileRecords += params[i].items + require.Contains(t, span.Attributes(), attribute.Int64(scrapedProfileRecordsKey, int64(params[i].items))) + require.Contains(t, span.Attributes(), attribute.Int64(erroredProfileRecordsKey, 0)) + assert.Equal(t, codes.Unset, span.Status().Code) + case errors.Is(params[i].err, errFake): + // Since we get an error, we cannot record any metrics because we don't know if the returned pprofile.Profiles is valid instance. + require.Contains(t, span.Attributes(), attribute.Int64(scrapedProfileRecordsKey, 0)) + require.Contains(t, span.Attributes(), attribute.Int64(erroredProfileRecordsKey, 0)) + assert.Equal(t, codes.Error, span.Status().Code) + assert.Equal(t, params[i].err.Error(), span.Status().Description) + case errors.Is(params[i].err, partialErrFake): + scrapedProfileRecords += params[i].items + erroredProfileRecords += 2 + require.Contains(t, span.Attributes(), attribute.Int64(scrapedProfileRecordsKey, int64(params[i].items))) + require.Contains(t, span.Attributes(), attribute.Int64(erroredProfileRecordsKey, 2)) + assert.Equal(t, codes.Error, span.Status().Code) + assert.Equal(t, params[i].err.Error(), span.Status().Description) + default: + t.Fatalf("unexpected err param: %v", params[i].err) + } + } + + checkScraperProfiles(t, tel, receiverID, scraperID, int64(scrapedProfileRecords), int64(erroredProfileRecords)) +} + +func TestCheckScraperProfiles(t *testing.T) { + tel := componenttest.NewTelemetry() + t.Cleanup(func() { require.NoError(t, tel.Shutdown(context.Background())) }) + + sm, err := xscraper.NewProfiles(func(context.Context) (pprofile.Profiles, error) { + return testdata.GenerateProfiles(7), nil + }) + require.NoError(t, err) + sf, err := wrapObsProfiles(sm, receiverID, scraperID, tel.NewTelemetrySettings()) + require.NoError(t, err) + _, err = sf.ScrapeProfiles(context.Background()) + require.NoError(t, err) + + checkScraperProfiles(t, tel, receiverID, scraperID, 7, 0) +} + +func TestScrapeProfilesDataOp_LogsScraperID(t *testing.T) { + tel := componenttest.NewTelemetry() + t.Cleanup(func() { require.NoError(t, tel.Shutdown(context.Background())) }) + + core, observedLogs := observer.New(zap.ErrorLevel) + telset := tel.NewTelemetrySettings() + telset.Logger = zap.New(core) + + rSet := receiver.Settings{ + ID: receiverID, + TelemetrySettings: telset, + } + set := controller.GetSettings(scraperID.Type(), rSet) + + sm, err := xscraper.NewProfiles(func(context.Context) (pprofile.Profiles, error) { + return pprofile.NewProfiles(), errFake + }) + require.NoError(t, err) + sf, err := wrapObsProfiles(sm, receiverID, scraperID, set.TelemetrySettings) + require.NoError(t, err) + _, err = sf.ScrapeProfiles(context.Background()) + require.ErrorIs(t, err, errFake) + + errorLogs := observedLogs.FilterLevelExact(zap.ErrorLevel).All() + require.Len(t, errorLogs, 1) + assert.Equal(t, "Error scraping profiles", errorLogs[0].Message) + assert.Equal(t, scraperID.String(), errorLogs[0].ContextMap()["scraper"]) + assert.Equal(t, errFake.Error(), errorLogs[0].ContextMap()["error"]) +} + +func checkScraperProfiles(t *testing.T, tel *componenttest.Telemetry, receiver, scraper component.ID, scrapedProfileRecords, erroredProfileRecords int64) { + metadatatest.AssertEqualScraperScrapedProfileRecords(t, tel, + []metricdata.DataPoint[int64]{ + { + Attributes: attribute.NewSet( + attribute.String(receiverKey, receiver.String()), + attribute.String(scraperKey, scraper.String())), + Value: scrapedProfileRecords, + }, + }, metricdatatest.IgnoreTimestamp(), metricdatatest.IgnoreExemplars()) + + metadatatest.AssertEqualScraperErroredProfileRecords(t, tel, + []metricdata.DataPoint[int64]{ + { + Attributes: attribute.NewSet( + attribute.String(receiverKey, receiver.String()), + attribute.String(scraperKey, scraper.String())), + Value: erroredProfileRecords, + }, + }, metricdatatest.IgnoreTimestamp(), metricdatatest.IgnoreExemplars()) +} diff --git a/scraper/scrapertest/go.mod b/scraper/scrapertest/go.mod index 7d21e626dc90..431579c28461 100644 --- a/scraper/scrapertest/go.mod +++ b/scraper/scrapertest/go.mod @@ -1,26 +1,26 @@ module go.opentelemetry.io/collector/scraper/scrapertest -go 1.24.0 +go 1.25.0 require ( github.com/google/uuid v1.6.0 - go.opentelemetry.io/collector/component v1.46.0 - go.opentelemetry.io/collector/component/componenttest v0.140.0 - go.opentelemetry.io/collector/scraper v0.140.0 + go.opentelemetry.io/collector/component v1.54.0 + go.opentelemetry.io/collector/component/componenttest v0.148.0 + go.opentelemetry.io/collector/scraper v0.148.0 ) require ( github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/go-logr/logr v1.4.3 // indirect github.com/go-logr/stdr v1.2.2 // indirect - github.com/hashicorp/go-version v1.7.0 // indirect + github.com/hashicorp/go-version v1.8.0 // indirect github.com/json-iterator/go v1.1.12 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee // indirect go.opentelemetry.io/auto/sdk v1.2.1 // indirect - go.opentelemetry.io/collector/featuregate v1.46.0 // indirect - go.opentelemetry.io/collector/pdata v1.46.0 // indirect - go.opentelemetry.io/collector/pipeline v1.46.0 // indirect + go.opentelemetry.io/collector/featuregate v1.54.0 // indirect + go.opentelemetry.io/collector/pdata v1.54.0 // indirect + go.opentelemetry.io/collector/pipeline v1.54.0 // indirect go.opentelemetry.io/otel v1.40.0 // indirect go.opentelemetry.io/otel/metric v1.40.0 // indirect go.opentelemetry.io/otel/sdk v1.40.0 // indirect @@ -28,7 +28,7 @@ require ( go.opentelemetry.io/otel/trace v1.40.0 // indirect go.uber.org/multierr v1.11.0 // indirect go.uber.org/zap v1.27.1 // indirect - golang.org/x/sys v0.40.0 // indirect + golang.org/x/sys v0.41.0 // indirect ) replace go.opentelemetry.io/collector/component/componenttest => ../../component/componenttest diff --git a/scraper/scrapertest/go.sum b/scraper/scrapertest/go.sum index b3bdd601f443..aa095db62625 100644 --- a/scraper/scrapertest/go.sum +++ b/scraper/scrapertest/go.sum @@ -13,8 +13,8 @@ github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/hashicorp/go-version v1.7.0 h1:5tqGy27NaOTB8yJKUZELlFAS/LTKJkrmONwQKeRZfjY= -github.com/hashicorp/go-version v1.7.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= +github.com/hashicorp/go-version v1.8.0 h1:KAkNb1HAiZd1ukkxDFGmokVZe1Xy9HG6NUp+bPle2i4= +github.com/hashicorp/go-version v1.8.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= @@ -41,21 +41,21 @@ go.opentelemetry.io/otel/sdk/metric v1.40.0 h1:mtmdVqgQkeRxHgRv4qhyJduP3fYJRMX4A go.opentelemetry.io/otel/sdk/metric v1.40.0/go.mod h1:4Z2bGMf0KSK3uRjlczMOeMhKU2rhUqdWNoKcYrtcBPg= go.opentelemetry.io/otel/trace v1.40.0 h1:WA4etStDttCSYuhwvEa8OP8I5EWu24lkOzp+ZYblVjw= go.opentelemetry.io/otel/trace v1.40.0/go.mod h1:zeAhriXecNGP/s2SEG3+Y8X9ujcJOTqQ5RgdEJcawiA= -go.opentelemetry.io/proto/slim/otlp v1.9.0 h1:fPVMv8tP3TrsqlkH1HWYUpbCY9cAIemx184VGkS6vlE= -go.opentelemetry.io/proto/slim/otlp v1.9.0/go.mod h1:xXdeJJ90Gqyll+orzUkY4bOd2HECo5JofeoLpymVqdI= -go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.2.0 h1:o13nadWDNkH/quoDomDUClnQBpdQQ2Qqv0lQBjIXjE8= -go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.2.0/go.mod h1:Gyb6Xe7FTi/6xBHwMmngGoHqL0w29Y4eW8TGFzpefGA= -go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.2.0 h1:EiUYvtwu6PMrMHVjcPfnsG3v+ajPkbUeH+IL93+QYyk= -go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.2.0/go.mod h1:mUUHKFiN2SST3AhJ8XhJxEoeVW12oqfXog0Bo8W3Ec4= +go.opentelemetry.io/proto/slim/otlp v1.10.0 h1:iR97Vs/ZDR+y9TfuP9b1XBtdPWeC+OMslIBmhcLU7jM= +go.opentelemetry.io/proto/slim/otlp v1.10.0/go.mod h1:lV9250stpjYLPNA5viFabIgP2QlUGRT1GdTgAf8SIUk= +go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.3.0 h1:RUF5rO0hAlgiJt1fzQVzcVs3vZVNHIcMLgOgG4rWNcQ= +go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.3.0/go.mod h1:I89cynRj8y+383o7tEQVg2SVA6SRgDVIouWPUVXjx0U= +go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.3.0 h1:CQvJSldHRUN6Z8jsUeYv8J0lXRvygALXIzsmAeCcZE0= +go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.3.0/go.mod h1:xSQ+mEfJe/GjK1LXEyVOoSI1N9JV9ZI923X5kup43W4= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= go.uber.org/zap v1.27.1 h1:08RqriUEv8+ArZRYSTXy1LeBScaMpVSTBhCeaZYfMYc= go.uber.org/zap v1.27.1/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= -golang.org/x/sys v0.40.0 h1:DBZZqJ2Rkml6QMQsZywtnjnnGvHza6BTfYFWY9kjEWQ= -golang.org/x/sys v0.40.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= -google.golang.org/protobuf v1.36.10 h1:AYd7cD/uASjIL6Q9LiTjz8JLcrh/88q5UObnmY3aOOE= -google.golang.org/protobuf v1.36.10/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= +golang.org/x/sys v0.41.0 h1:Ivj+2Cp/ylzLiEU89QhWblYnOE9zerudt9Ftecq2C6k= +golang.org/x/sys v0.41.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= +google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE= +google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/scraper/scrapertest/metadata.yaml b/scraper/scrapertest/metadata.yaml new file mode 100644 index 000000000000..ad72b71b345f --- /dev/null +++ b/scraper/scrapertest/metadata.yaml @@ -0,0 +1,6 @@ +type: scraper/scrapertest +github_project: open-telemetry/opentelemetry-collector + +status: + disable_codecov_badge: true + class: pkg diff --git a/scraper/xscraper/factory.go b/scraper/xscraper/factory.go index a848c9635b1b..3e2afca5cf7e 100644 --- a/scraper/xscraper/factory.go +++ b/scraper/xscraper/factory.go @@ -26,25 +26,21 @@ type Factory interface { // FactoryOption apply changes to Options. type FactoryOption interface { // applyOption applies the option. - applyOption(o *factoryOpts) -} - -type factoryOpts struct { - opts []scraper.FactoryOption - *factory + applyOption(o *factory) } var _ FactoryOption = (*factoryOptionFunc)(nil) // factoryOptionFunc is a FactoryOption created through a function. -type factoryOptionFunc func(*factoryOpts) +type factoryOptionFunc func(*factory) -func (f factoryOptionFunc) applyOption(o *factoryOpts) { +func (f factoryOptionFunc) applyOption(o *factory) { f(o) } type factory struct { scraper.Factory + opts []scraper.FactoryOption createProfilesFunc CreateProfilesFunc profilesStabilityLevel component.StabilityLevel @@ -63,14 +59,14 @@ func (f *factory) CreateProfiles(ctx context.Context, set scraper.Settings, cfg // WithLogs overrides the default "error not supported" implementation for CreateLogs and the default "undefined" stability level. func WithLogs(createLogs scraper.CreateLogsFunc, sl component.StabilityLevel) FactoryOption { - return factoryOptionFunc(func(o *factoryOpts) { + return factoryOptionFunc(func(o *factory) { o.opts = append(o.opts, scraper.WithLogs(createLogs, sl)) }) } // WithMetrics overrides the default "error not supported" implementation for CreateMetrics and the default "undefined" stability level. func WithMetrics(createMetrics scraper.CreateMetricsFunc, sl component.StabilityLevel) FactoryOption { - return factoryOptionFunc(func(o *factoryOpts) { + return factoryOptionFunc(func(o *factory) { o.opts = append(o.opts, scraper.WithMetrics(createMetrics, sl)) }) } @@ -80,18 +76,18 @@ type CreateProfilesFunc func(context.Context, scraper.Settings, component.Config // WithProfiles overrides the default "error not supported" implementation for CreateProfiles and the default "undefined" stability level. func WithProfiles(createProfiles CreateProfilesFunc, sl component.StabilityLevel) FactoryOption { - return factoryOptionFunc(func(o *factoryOpts) { + return factoryOptionFunc(func(o *factory) { o.profilesStabilityLevel = sl o.createProfilesFunc = createProfiles }) } -// NewFactory returns a Factory. +// NewFactory creates a Factory with experimental capabilities and wraps a scraper.Factory. func NewFactory(cfgType component.Type, createDefaultConfig component.CreateDefaultConfigFunc, options ...FactoryOption) Factory { - opts := factoryOpts{factory: &factory{}} + f := &factory{} for _, opt := range options { - opt.applyOption(&opts) + opt.applyOption(f) } - opts.Factory = scraper.NewFactory(cfgType, createDefaultConfig, opts.opts...) - return opts.factory + f.Factory = scraper.NewFactory(cfgType, createDefaultConfig, f.opts...) + return f } diff --git a/scraper/xscraper/go.mod b/scraper/xscraper/go.mod index 55ad97a4046d..0a65184332bf 100644 --- a/scraper/xscraper/go.mod +++ b/scraper/xscraper/go.mod @@ -1,15 +1,15 @@ module go.opentelemetry.io/collector/scraper/xscraper -go 1.24.0 +go 1.25.0 require ( github.com/stretchr/testify v1.11.1 - go.opentelemetry.io/collector/component v1.46.0 - go.opentelemetry.io/collector/component/componenttest v0.140.0 - go.opentelemetry.io/collector/pdata v1.46.0 - go.opentelemetry.io/collector/pdata/pprofile v0.140.0 - go.opentelemetry.io/collector/pipeline v1.46.0 - go.opentelemetry.io/collector/scraper v0.140.0 + go.opentelemetry.io/collector/component v1.54.0 + go.opentelemetry.io/collector/component/componenttest v0.148.0 + go.opentelemetry.io/collector/pdata v1.54.0 + go.opentelemetry.io/collector/pdata/pprofile v0.148.0 + go.opentelemetry.io/collector/pipeline v1.54.0 + go.opentelemetry.io/collector/scraper v0.148.0 go.uber.org/goleak v1.3.0 ) @@ -19,13 +19,13 @@ require ( github.com/go-logr/logr v1.4.3 // indirect github.com/go-logr/stdr v1.2.2 // indirect github.com/google/uuid v1.6.0 // indirect - github.com/hashicorp/go-version v1.7.0 // indirect + github.com/hashicorp/go-version v1.8.0 // indirect github.com/json-iterator/go v1.1.12 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee // indirect github.com/pmezard/go-difflib v1.0.0 // indirect go.opentelemetry.io/auto/sdk v1.2.1 // indirect - go.opentelemetry.io/collector/featuregate v1.46.0 // indirect + go.opentelemetry.io/collector/featuregate v1.54.0 // indirect go.opentelemetry.io/otel v1.40.0 // indirect go.opentelemetry.io/otel/metric v1.40.0 // indirect go.opentelemetry.io/otel/sdk v1.40.0 // indirect @@ -33,7 +33,7 @@ require ( go.opentelemetry.io/otel/trace v1.40.0 // indirect go.uber.org/multierr v1.11.0 // indirect go.uber.org/zap v1.27.1 // indirect - golang.org/x/sys v0.40.0 // indirect + golang.org/x/sys v0.41.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/scraper/xscraper/go.sum b/scraper/xscraper/go.sum index c102571e7869..1e6789104ba9 100644 --- a/scraper/xscraper/go.sum +++ b/scraper/xscraper/go.sum @@ -13,8 +13,8 @@ github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/hashicorp/go-version v1.7.0 h1:5tqGy27NaOTB8yJKUZELlFAS/LTKJkrmONwQKeRZfjY= -github.com/hashicorp/go-version v1.7.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= +github.com/hashicorp/go-version v1.8.0 h1:KAkNb1HAiZd1ukkxDFGmokVZe1Xy9HG6NUp+bPle2i4= +github.com/hashicorp/go-version v1.8.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= @@ -47,22 +47,22 @@ go.opentelemetry.io/otel/sdk/metric v1.40.0 h1:mtmdVqgQkeRxHgRv4qhyJduP3fYJRMX4A go.opentelemetry.io/otel/sdk/metric v1.40.0/go.mod h1:4Z2bGMf0KSK3uRjlczMOeMhKU2rhUqdWNoKcYrtcBPg= go.opentelemetry.io/otel/trace v1.40.0 h1:WA4etStDttCSYuhwvEa8OP8I5EWu24lkOzp+ZYblVjw= go.opentelemetry.io/otel/trace v1.40.0/go.mod h1:zeAhriXecNGP/s2SEG3+Y8X9ujcJOTqQ5RgdEJcawiA= -go.opentelemetry.io/proto/slim/otlp v1.9.0 h1:fPVMv8tP3TrsqlkH1HWYUpbCY9cAIemx184VGkS6vlE= -go.opentelemetry.io/proto/slim/otlp v1.9.0/go.mod h1:xXdeJJ90Gqyll+orzUkY4bOd2HECo5JofeoLpymVqdI= -go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.2.0 h1:o13nadWDNkH/quoDomDUClnQBpdQQ2Qqv0lQBjIXjE8= -go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.2.0/go.mod h1:Gyb6Xe7FTi/6xBHwMmngGoHqL0w29Y4eW8TGFzpefGA= -go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.2.0 h1:EiUYvtwu6PMrMHVjcPfnsG3v+ajPkbUeH+IL93+QYyk= -go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.2.0/go.mod h1:mUUHKFiN2SST3AhJ8XhJxEoeVW12oqfXog0Bo8W3Ec4= +go.opentelemetry.io/proto/slim/otlp v1.10.0 h1:iR97Vs/ZDR+y9TfuP9b1XBtdPWeC+OMslIBmhcLU7jM= +go.opentelemetry.io/proto/slim/otlp v1.10.0/go.mod h1:lV9250stpjYLPNA5viFabIgP2QlUGRT1GdTgAf8SIUk= +go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.3.0 h1:RUF5rO0hAlgiJt1fzQVzcVs3vZVNHIcMLgOgG4rWNcQ= +go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.3.0/go.mod h1:I89cynRj8y+383o7tEQVg2SVA6SRgDVIouWPUVXjx0U= +go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.3.0 h1:CQvJSldHRUN6Z8jsUeYv8J0lXRvygALXIzsmAeCcZE0= +go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.3.0/go.mod h1:xSQ+mEfJe/GjK1LXEyVOoSI1N9JV9ZI923X5kup43W4= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= go.uber.org/zap v1.27.1 h1:08RqriUEv8+ArZRYSTXy1LeBScaMpVSTBhCeaZYfMYc= go.uber.org/zap v1.27.1/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= -golang.org/x/sys v0.40.0 h1:DBZZqJ2Rkml6QMQsZywtnjnnGvHza6BTfYFWY9kjEWQ= -golang.org/x/sys v0.40.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= -google.golang.org/protobuf v1.36.10 h1:AYd7cD/uASjIL6Q9LiTjz8JLcrh/88q5UObnmY3aOOE= -google.golang.org/protobuf v1.36.10/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= +golang.org/x/sys v0.41.0 h1:Ivj+2Cp/ylzLiEU89QhWblYnOE9zerudt9Ftecq2C6k= +golang.org/x/sys v0.41.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= +google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE= +google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= diff --git a/scraper/xscraper/profiles_test.go b/scraper/xscraper/profiles_test.go index ac98158ad866..b97e978fa34e 100644 --- a/scraper/xscraper/profiles_test.go +++ b/scraper/xscraper/profiles_test.go @@ -59,14 +59,12 @@ func TestProfilesConcurrency(t *testing.T) { var wg sync.WaitGroup for range 10 { - wg.Add(1) - go func() { - defer wg.Done() + wg.Go(func() { for range 10000 { _, errScrape := mp.ScrapeProfiles(context.Background()) assert.NoError(t, errScrape) } - }() + }) } wg.Wait() require.NoError(t, mp.Shutdown(context.Background())) diff --git a/service/README.md b/service/README.md index 68d0ddb16a29..d01d313ac03f 100644 --- a/service/README.md +++ b/service/README.md @@ -1,181 +1,11 @@ -# OpenTelemetry Collector Service - -## How to provide configuration? - -The `--config` flag accepts either a file path or values in the form of a config URI `":"`. -Currently, the OpenTelemetry Collector supports the following providers `scheme`: -- [file](../confmap/provider/fileprovider/provider.go) - Reads configuration from a file. E.g. `file:path/to/config.yaml`. -- [env](../confmap/provider/envprovider/provider.go) - Reads configuration from an environment variable. E.g. `env:MY_CONFIG_IN_AN_ENVVAR`. -- [yaml](../confmap/provider/yamlprovider/provider.go) - Reads configuration from yaml bytes. E.g. `yaml:exporters::debug::verbosity: detailed`. -- [http](../confmap/provider/httpprovider/provider.go) - Reads configuration from a HTTP URI. E.g. `http://www.example.com` - -For more technical details about how configuration is resolved you can read the [configuration resolving design](../confmap/README.md#configuration-resolving). - -### Single Config Source - -1. Simple local file: - - `./otelcorecol --config=examples/local/otel-config.yaml` - -2. Simple local file using the new URI format: - - `./otelcorecol --config=file:examples/local/otel-config.yaml` - -3. Config provided via an environment variable: - - `./otelcorecol --config=env:MY_CONFIG_IN_AN_ENVVAR` - - -### Multiple Config Sources - -1. Merge a `otel-config.yaml` file with the content of an environment variable `MY_OTHER_CONFIG` and use the merged result as the config: - - `./otelcorecol --config=file:examples/local/otel-config.yaml --config=env:MY_OTHER_CONFIG` - -2. Merge a `config.yaml` file with the content of a yaml bytes configuration (overwrites the `exporters::debug::verbosity` config) and use the content as the config: - - `./otelcorecol --config=file:examples/local/otel-config.yaml --config="yaml:exporters::debug::verbosity: normal"` - -### Embedding other configuration providers - -One configuration provider can also make references to other config providers, like the following: - -```yaml -receivers: - otlp: - protocols: - grpc: - -exporters: ${file:otlp-exporter.yaml} - -service: - extensions: [ ] - pipelines: - traces: - receivers: [ otlp ] - processors: [ ] - exporters: [ otlp ] -``` - -## How to override config properties? - -The `--set` flag allows to set arbitrary config property. The `--set` values are merged into the final configuration -after all the sources specified by the `--config` are resolved and merged. - -### The Format and Limitations of `--set` - -#### Simple property - -The `--set` option takes always one key/value pair, and it is used like this: `--set key=value`. The YAML equivalent of that is: - -```yaml -key: value -``` - -#### Complex nested keys - -Use dot (`.`) in the pair's name as key separator to reference nested map values. For example, `--set outer.inner=value` is translated into this: - -```yaml -outer: - inner: value -``` - -#### Multiple values - -To set multiple values specify multiple --set flags, so `--set a=b --set c=d` becomes: - -```yaml -a: b -c: d -``` - - -#### Array values - -Arrays can be expressed by enclosing values in `[]`. For example, `--set "key=[a, b, c]"` translates to: - -```yaml -key: - - a - - b - - c -``` - -#### Map values - -Maps can be expressed by enclosing values in `{}`. For example, `"--set "key={a: c}"` translates to: - -```yaml -key: - a: c -``` - -#### Limitations - -1. Does not support setting a key that contains a dot `.`. -2. Does not support setting a key that contains a equal sign `=`. -3. The configuration key separator inside the value part of the property is "::". For example `--set "name={a::b: c}"` is equivalent with `--set name.a.b=c`. - -## How to check components available in a distribution - -Use the sub command build-info. Below is an example: - -```bash - ./otelcorecol components -``` -Sample output: - -```yaml -buildinfo: - command: otelcorecol - description: Local OpenTelemetry Collector binary, testing only. - version: 0.62.1-dev -receivers: - - otlp -processors: - - memory_limiter -exporters: - - otlp - - otlphttp - - debug -extensions: - - zpages -``` - -## How to validate configuration file and return all errors without running collector - -```bash - ./otelcorecol validate --config=file:examples/local/otel-config.yaml -``` - -## How to examine the final configuration after resolving, parsing and validating? - -Use `print-config` in the default mode (`--mode=redacted`) and `--feature-gates=otelcol.printInitialConfig`: - -```bash - ./otelcorecol print-config --config=file:examples/local/otel-config.yaml -``` - -Note that by default the configuration will only print when it is -valid, and that sensitive information will be redacted. To print a -potentially invalid configuration, use `--validate=false`. - -## How to examine the final configuration including sensitive fields? - -Use `print-config` with `--mode=unredacted` and `--feature-gates=otelcol.printInitialConfig`: - -```bash - ./otelcorecol print-config --mode=unredacted --config=file:examples/local/otel-config.yaml -``` - -## How to print the final configuration in JSON format? - -Use `print-config` with `--format=json` and -`--feature-gates=otelcol.printInitialConfig`. Note that JSON format is -considered unstable. - -```bash - ./otelcorecol print-config --format=json --config=file:examples/local/otel-config.yaml -``` - + +# Service +| Status | | +| ------------- |-----------| +| Stability | [development]: traces, metrics, logs, profiles | +| Issues | [![Open issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector?query=is%3Aissue%20is%3Aopen%20label%3Apkg%2Fservice%20&label=open&color=orange&logo=opentelemetry)](https://github.com/open-telemetry/opentelemetry-collector/issues?q=is%3Aopen+is%3Aissue+label%3Apkg%2Fservice) [![Closed issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector?query=is%3Aissue%20is%3Aclosed%20label%3Apkg%2Fservice%20&label=closed&color=blue&logo=opentelemetry)](https://github.com/open-telemetry/opentelemetry-collector/issues?q=is%3Aclosed+is%3Aissue+label%3Apkg%2Fservice) | + +[development]: https://github.com/open-telemetry/opentelemetry-collector/blob/main/docs/component-stability.md#development +[core]: https://github.com/open-telemetry/opentelemetry-collector-releases/tree/main/distributions/otelcol +[contrib]: https://github.com/open-telemetry/opentelemetry-collector-releases/tree/main/distributions/otelcol-contrib + diff --git a/service/documentation.md b/service/documentation.md index 4c46bee5e11c..dc89fa63e929 100644 --- a/service/documentation.md +++ b/service/documentation.md @@ -8,7 +8,7 @@ The following telemetry is emitted by this component. ### otelcol.connector.consumed.items -Number of items passed to the connector. [Development] +Number of items passed to the connector. | Unit | Metric Type | Value Type | Monotonic | Stability | | ---- | ----------- | ---------- | --------- | --------- | @@ -16,7 +16,7 @@ Number of items passed to the connector. [Development] ### otelcol.connector.produced.items -Number of items emitted from the connector. [Development] +Number of items emitted from the connector. | Unit | Metric Type | Value Type | Monotonic | Stability | | ---- | ----------- | ---------- | --------- | --------- | @@ -24,7 +24,7 @@ Number of items emitted from the connector. [Development] ### otelcol.exporter.consumed.items -Number of items passed to the exporter. [Development] +Number of items passed to the exporter. | Unit | Metric Type | Value Type | Monotonic | Stability | | ---- | ----------- | ---------- | --------- | --------- | @@ -32,7 +32,7 @@ Number of items passed to the exporter. [Development] ### otelcol_process_cpu_seconds -Total CPU user and system time in seconds [Alpha] +Total CPU user and system time in seconds | Unit | Metric Type | Value Type | Monotonic | Stability | | ---- | ----------- | ---------- | --------- | --------- | @@ -40,7 +40,7 @@ Total CPU user and system time in seconds [Alpha] ### otelcol_process_memory_rss -Total physical memory (resident set size) [Alpha] +Total physical memory (resident set size) | Unit | Metric Type | Value Type | Stability | | ---- | ----------- | ---------- | --------- | @@ -48,7 +48,7 @@ Total physical memory (resident set size) [Alpha] ### otelcol_process_runtime_heap_alloc_bytes -Bytes of allocated heap objects (see 'go doc runtime.MemStats.HeapAlloc') [Alpha] +Bytes of allocated heap objects (see 'go doc runtime.MemStats.HeapAlloc') | Unit | Metric Type | Value Type | Stability | | ---- | ----------- | ---------- | --------- | @@ -56,7 +56,7 @@ Bytes of allocated heap objects (see 'go doc runtime.MemStats.HeapAlloc') [Alpha ### otelcol_process_runtime_total_alloc_bytes -Cumulative bytes allocated for heap objects (see 'go doc runtime.MemStats.TotalAlloc') [Alpha] +Cumulative bytes allocated for heap objects (see 'go doc runtime.MemStats.TotalAlloc') | Unit | Metric Type | Value Type | Monotonic | Stability | | ---- | ----------- | ---------- | --------- | --------- | @@ -64,7 +64,7 @@ Cumulative bytes allocated for heap objects (see 'go doc runtime.MemStats.TotalA ### otelcol_process_runtime_total_sys_memory_bytes -Total bytes of memory obtained from the OS (see 'go doc runtime.MemStats.Sys') [Alpha] +Total bytes of memory obtained from the OS (see 'go doc runtime.MemStats.Sys') | Unit | Metric Type | Value Type | Stability | | ---- | ----------- | ---------- | --------- | @@ -72,7 +72,7 @@ Total bytes of memory obtained from the OS (see 'go doc runtime.MemStats.Sys') [ ### otelcol_process_uptime -Uptime of the process [Alpha] +Uptime of the process | Unit | Metric Type | Value Type | Monotonic | Stability | | ---- | ----------- | ---------- | --------- | --------- | @@ -80,7 +80,7 @@ Uptime of the process [Alpha] ### otelcol.processor.consumed.items -Number of items passed to the processor. [Development] +Number of items passed to the processor. | Unit | Metric Type | Value Type | Monotonic | Stability | | ---- | ----------- | ---------- | --------- | --------- | @@ -88,7 +88,7 @@ Number of items passed to the processor. [Development] ### otelcol.processor.produced.items -Number of items emitted from the processor. [Development] +Number of items emitted from the processor. | Unit | Metric Type | Value Type | Monotonic | Stability | | ---- | ----------- | ---------- | --------- | --------- | @@ -96,8 +96,21 @@ Number of items emitted from the processor. [Development] ### otelcol.receiver.produced.items -Number of items emitted from the receiver. [Development] +Number of items emitted from the receiver. | Unit | Metric Type | Value Type | Monotonic | Stability | | ---- | ----------- | ---------- | --------- | --------- | | {item} | Sum | Int | true | Development | + +## Feature Gates + +This component has the following feature gates: + +| Feature Gate | Stage | Description | From Version | To Version | Reference | +| ------------ | ----- | ----------- | ------------ | ---------- | --------- | +| `service.AllowNoPipelines` | alpha | Allow starting the Collector without starting any pipelines. | v0.122.0 | N/A | [Link](https://github.com/open-telemetry/opentelemetry-collector/pull/12613) | +| `service.profilesSupport` | alpha | Controls whether profiles support can be enabled | v0.112.0 | N/A | [Link](https://github.com/open-telemetry/opentelemetry-collector/pull/11477) | +| `telemetry.UseLocalHostAsDefaultMetricsAddress` | beta | Controls whether default Prometheus metrics server use localhost as the default host for their endpoints | v0.111.0 | N/A | [Link](https://github.com/open-telemetry/opentelemetry-collector/pull/11251) | +| `telemetry.newPipelineTelemetry` | alpha | Injects component-identifying scope attributes in internal Collector metrics | v0.123.0 | N/A | [Link](https://github.com/open-telemetry/opentelemetry-collector/blob/main/docs/rfcs/component-universal-telemetry.md) | + +For more information about feature gates, see the [Feature Gates](https://github.com/open-telemetry/opentelemetry-collector/blob/main/featuregate/README.md) documentation. diff --git a/service/go.mod b/service/go.mod index 7d4b836f1d27..f0393569c49b 100644 --- a/service/go.mod +++ b/service/go.mod @@ -1,147 +1,148 @@ module go.opentelemetry.io/collector/service -go 1.24.0 +go 1.25.0 require ( github.com/google/uuid v1.6.0 github.com/prometheus/client_model v0.6.2 - github.com/prometheus/common v0.67.1 - github.com/shirou/gopsutil/v4 v4.25.10 + github.com/prometheus/common v0.67.5 + github.com/shirou/gopsutil/v4 v4.26.2 github.com/stretchr/testify v1.11.1 - go.opentelemetry.io/collector/component v1.46.0 - go.opentelemetry.io/collector/component/componentstatus v0.140.0 - go.opentelemetry.io/collector/component/componenttest v0.140.0 + go.opentelemetry.io/collector/component v1.54.0 + go.opentelemetry.io/collector/component/componentstatus v0.148.0 + go.opentelemetry.io/collector/component/componenttest v0.148.0 go.opentelemetry.io/collector/config/confighttp v0.140.0 + go.opentelemetry.io/collector/config/confignet v0.0.0-00010101000000-000000000000 go.opentelemetry.io/collector/config/configtelemetry v0.140.0 - go.opentelemetry.io/collector/confmap v1.46.0 - go.opentelemetry.io/collector/confmap/xconfmap v0.140.0 - go.opentelemetry.io/collector/connector v0.140.0 - go.opentelemetry.io/collector/connector/connectortest v0.140.0 - go.opentelemetry.io/collector/connector/xconnector v0.140.0 - go.opentelemetry.io/collector/consumer v1.46.0 - go.opentelemetry.io/collector/consumer/consumererror v0.140.0 - go.opentelemetry.io/collector/consumer/consumertest v0.140.0 - go.opentelemetry.io/collector/consumer/xconsumer v0.140.0 - go.opentelemetry.io/collector/exporter v1.46.0 - go.opentelemetry.io/collector/exporter/exportertest v0.140.0 - go.opentelemetry.io/collector/exporter/xexporter v0.140.0 - go.opentelemetry.io/collector/extension v1.46.0 + go.opentelemetry.io/collector/confmap v1.54.0 + go.opentelemetry.io/collector/confmap/xconfmap v0.148.0 + go.opentelemetry.io/collector/connector v0.148.0 + go.opentelemetry.io/collector/connector/connectortest v0.148.0 + go.opentelemetry.io/collector/connector/xconnector v0.148.0 + go.opentelemetry.io/collector/consumer v1.54.0 + go.opentelemetry.io/collector/consumer/consumererror v0.148.0 + go.opentelemetry.io/collector/consumer/consumertest v0.148.0 + go.opentelemetry.io/collector/consumer/xconsumer v0.148.0 + go.opentelemetry.io/collector/exporter v1.54.0 + go.opentelemetry.io/collector/exporter/exportertest v0.148.0 + go.opentelemetry.io/collector/exporter/xexporter v0.148.0 + go.opentelemetry.io/collector/extension v1.54.0 go.opentelemetry.io/collector/extension/extensioncapabilities v0.140.0 - go.opentelemetry.io/collector/extension/extensiontest v0.140.0 + go.opentelemetry.io/collector/extension/extensiontest v0.148.0 go.opentelemetry.io/collector/extension/zpagesextension v0.140.0 - go.opentelemetry.io/collector/featuregate v1.46.0 - go.opentelemetry.io/collector/internal/fanoutconsumer v0.140.0 + go.opentelemetry.io/collector/featuregate v1.54.0 + go.opentelemetry.io/collector/internal/componentalias v0.148.0 + go.opentelemetry.io/collector/internal/fanoutconsumer v0.148.0 go.opentelemetry.io/collector/internal/telemetry v0.140.0 - go.opentelemetry.io/collector/internal/testutil v0.140.0 + go.opentelemetry.io/collector/internal/testutil v0.148.0 go.opentelemetry.io/collector/otelcol v0.140.0 - go.opentelemetry.io/collector/pdata v1.46.0 - go.opentelemetry.io/collector/pdata/pprofile v0.140.0 - go.opentelemetry.io/collector/pdata/testdata v0.140.0 + go.opentelemetry.io/collector/pdata v1.54.0 + go.opentelemetry.io/collector/pdata/pprofile v0.148.0 + go.opentelemetry.io/collector/pdata/testdata v0.148.0 go.opentelemetry.io/collector/pdata/xpdata v0.140.0 - go.opentelemetry.io/collector/pipeline v1.46.0 - go.opentelemetry.io/collector/pipeline/xpipeline v0.140.0 - go.opentelemetry.io/collector/processor v1.46.0 - go.opentelemetry.io/collector/processor/processortest v0.140.0 - go.opentelemetry.io/collector/processor/xprocessor v0.140.0 - go.opentelemetry.io/collector/receiver v1.46.0 - go.opentelemetry.io/collector/receiver/receivertest v0.140.0 - go.opentelemetry.io/collector/receiver/xreceiver v0.140.0 + go.opentelemetry.io/collector/pipeline v1.54.0 + go.opentelemetry.io/collector/pipeline/xpipeline v0.148.0 + go.opentelemetry.io/collector/processor v1.54.0 + go.opentelemetry.io/collector/processor/processortest v0.148.0 + go.opentelemetry.io/collector/processor/xprocessor v0.148.0 + go.opentelemetry.io/collector/receiver v1.54.0 + go.opentelemetry.io/collector/receiver/receivertest v0.148.0 + go.opentelemetry.io/collector/receiver/xreceiver v0.148.0 go.opentelemetry.io/collector/service/hostcapabilities v0.140.0 - go.opentelemetry.io/collector/service/telemetry/telemetrytest v0.140.0 + go.opentelemetry.io/collector/service/telemetry/telemetrytest v0.148.0 go.opentelemetry.io/contrib/bridges/otelzap v0.13.0 go.opentelemetry.io/contrib/otelconf v0.18.0 go.opentelemetry.io/contrib/propagators/b3 v1.38.0 - go.opentelemetry.io/otel v1.40.0 - go.opentelemetry.io/otel/log v0.14.0 - go.opentelemetry.io/otel/metric v1.40.0 - go.opentelemetry.io/otel/sdk v1.40.0 - go.opentelemetry.io/otel/sdk/metric v1.40.0 - go.opentelemetry.io/otel/trace v1.40.0 + go.opentelemetry.io/otel v1.42.0 + go.opentelemetry.io/otel/log v0.18.0 + go.opentelemetry.io/otel/metric v1.42.0 + go.opentelemetry.io/otel/sdk v1.42.0 + go.opentelemetry.io/otel/sdk/metric v1.42.0 + go.opentelemetry.io/otel/trace v1.42.0 go.uber.org/goleak v1.3.0 go.uber.org/multierr v1.11.0 go.uber.org/zap v1.27.1 - gonum.org/v1/gonum v0.16.0 + gonum.org/v1/gonum v0.17.0 ) require ( github.com/beorn7/perks v1.0.1 // indirect github.com/cenkalti/backoff/v5 v5.0.3 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect - github.com/davecgh/go-spew v1.1.1 // indirect - github.com/ebitengine/purego v0.9.0 // indirect + github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect + github.com/ebitengine/purego v0.10.0 // indirect github.com/felixge/httpsnoop v1.0.4 // indirect - github.com/foxboron/go-tpm-keyfiles v0.0.0-20250903184740-5d135037bd4d // indirect + github.com/foxboron/go-tpm-keyfiles v0.0.0-20251226215517-609e4778396f // indirect github.com/fsnotify/fsnotify v1.9.0 // indirect github.com/go-logr/logr v1.4.3 // indirect github.com/go-logr/stdr v1.2.2 // indirect github.com/go-ole/go-ole v1.2.6 // indirect - github.com/go-viper/mapstructure/v2 v2.4.0 // indirect + github.com/go-viper/mapstructure/v2 v2.5.0 // indirect github.com/gobwas/glob v0.2.3 // indirect github.com/golang/snappy v1.0.0 // indirect - github.com/google/go-tpm v0.9.7 // indirect - github.com/grafana/regexp v0.0.0-20240518133315-a468a5bfb3bc // indirect - github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.2 // indirect - github.com/hashicorp/go-version v1.7.0 // indirect + github.com/google/go-tpm v0.9.8 // indirect + github.com/grpc-ecosystem/grpc-gateway/v2 v2.28.0 // indirect + github.com/hashicorp/go-version v1.8.0 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/json-iterator/go v1.1.12 // indirect - github.com/klauspost/compress v1.18.1 // indirect + github.com/klauspost/compress v1.18.4 // indirect github.com/knadh/koanf/maps v0.1.2 // indirect github.com/knadh/koanf/providers/confmap v1.0.0 // indirect - github.com/knadh/koanf/v2 v2.3.0 // indirect - github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 // indirect + github.com/knadh/koanf/v2 v2.3.3 // indirect + github.com/lufia/plan9stats v0.0.0-20251013123823-9fd1530e3ec3 // indirect github.com/mitchellh/copystructure v1.2.0 // indirect github.com/mitchellh/reflectwalk v1.0.2 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee // indirect github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect - github.com/pierrec/lz4/v4 v4.1.22 // indirect - github.com/pmezard/go-difflib v1.0.0 // indirect + github.com/pierrec/lz4/v4 v4.1.26 // indirect + github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect github.com/power-devops/perfstat v0.0.0-20240221224432-82ca36839d55 // indirect github.com/prometheus/client_golang v1.23.2 // indirect - github.com/prometheus/otlptranslator v0.0.2 // indirect - github.com/prometheus/procfs v0.17.0 // indirect + github.com/prometheus/otlptranslator v1.0.0 // indirect + github.com/prometheus/procfs v0.20.1 // indirect github.com/rs/cors v1.11.1 // indirect - github.com/spf13/cobra v1.10.1 // indirect - github.com/spf13/pflag v1.0.9 // indirect - github.com/tklauser/go-sysconf v0.3.15 // indirect - github.com/tklauser/numcpus v0.10.0 // indirect + github.com/spf13/cobra v1.10.2 // indirect + github.com/spf13/pflag v1.0.10 // indirect + github.com/tklauser/go-sysconf v0.3.16 // indirect + github.com/tklauser/numcpus v0.11.0 // indirect github.com/yusufpapurcu/wmi v1.2.4 // indirect go.opentelemetry.io/auto/sdk v1.2.1 // indirect - go.opentelemetry.io/collector/client v1.46.0 // indirect - go.opentelemetry.io/collector/config/configauth v1.46.0 // indirect - go.opentelemetry.io/collector/config/configcompression v1.46.0 // indirect - go.opentelemetry.io/collector/config/configmiddleware v1.46.0 // indirect - go.opentelemetry.io/collector/config/configopaque v1.46.0 // indirect - go.opentelemetry.io/collector/config/configoptional v1.46.0 // indirect - go.opentelemetry.io/collector/config/configtls v1.46.0 // indirect - go.opentelemetry.io/collector/extension/extensionauth v1.46.0 // indirect - go.opentelemetry.io/collector/extension/extensionmiddleware v0.140.0 // indirect - go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.63.0 // indirect - go.opentelemetry.io/contrib/zpages v0.63.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.14.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.14.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.38.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.38.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.38.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.38.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.38.0 // indirect - go.opentelemetry.io/otel/exporters/prometheus v0.60.0 // indirect - go.opentelemetry.io/otel/exporters/stdout/stdoutlog v0.14.0 // indirect - go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.38.0 // indirect - go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.38.0 // indirect - go.opentelemetry.io/otel/sdk/log v0.14.0 // indirect - go.opentelemetry.io/proto/otlp v1.7.1 // indirect + go.opentelemetry.io/collector/client v1.54.0 // indirect + go.opentelemetry.io/collector/config/configauth v1.54.0 // indirect + go.opentelemetry.io/collector/config/configcompression v1.54.0 // indirect + go.opentelemetry.io/collector/config/configmiddleware v1.54.0 // indirect + go.opentelemetry.io/collector/config/configopaque v1.54.0 // indirect + go.opentelemetry.io/collector/config/configoptional v1.54.0 // indirect + go.opentelemetry.io/collector/config/configtls v1.54.0 // indirect + go.opentelemetry.io/collector/extension/extensionauth v1.54.0 // indirect + go.opentelemetry.io/collector/extension/extensionmiddleware v0.148.0 // indirect + go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.67.0 // indirect + go.opentelemetry.io/contrib/zpages v0.67.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.18.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.18.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.42.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.42.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.42.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.42.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.42.0 // indirect + go.opentelemetry.io/otel/exporters/prometheus v0.64.0 // indirect + go.opentelemetry.io/otel/exporters/stdout/stdoutlog v0.18.0 // indirect + go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.42.0 // indirect + go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.42.0 // indirect + go.opentelemetry.io/otel/sdk/log v0.18.0 // indirect + go.opentelemetry.io/proto/otlp v1.10.0 // indirect go.yaml.in/yaml/v2 v2.4.3 // indirect go.yaml.in/yaml/v3 v3.0.4 // indirect - golang.org/x/crypto v0.45.0 // indirect + golang.org/x/crypto v0.48.0 // indirect golang.org/x/exp v0.0.0-20240506185415-9bf2ced13842 // indirect - golang.org/x/net v0.47.0 // indirect - golang.org/x/sys v0.40.0 // indirect - golang.org/x/text v0.31.0 // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20251022142026-3a174f9686a8 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20251022142026-3a174f9686a8 // indirect - google.golang.org/grpc v1.77.0 // indirect - google.golang.org/protobuf v1.36.10 // indirect + golang.org/x/net v0.51.0 // indirect + golang.org/x/sys v0.41.0 // indirect + golang.org/x/text v0.34.0 // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20260226221140-a57be14db171 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20260226221140-a57be14db171 // indirect + google.golang.org/grpc v1.79.3 // indirect + google.golang.org/protobuf v1.36.11 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) @@ -254,3 +255,7 @@ replace go.opentelemetry.io/collector/exporter/exporterhelper => ../exporter/exp replace go.opentelemetry.io/collector/config/configoptional => ../config/configoptional replace go.opentelemetry.io/collector/internal/testutil => ../internal/testutil + +replace go.opentelemetry.io/collector/internal/componentalias => ../internal/componentalias + +replace go.opentelemetry.io/collector/config/confignet => ../config/confignet diff --git a/service/go.sum b/service/go.sum index d382d7e1a93b..5f829cd0056b 100644 --- a/service/go.sum +++ b/service/go.sum @@ -6,16 +6,15 @@ github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UF github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/ebitengine/purego v0.9.0 h1:mh0zpKBIXDceC63hpvPuGLiJ8ZAa3DfrFTudmfi8A4k= -github.com/ebitengine/purego v0.9.0/go.mod h1:iIjxzd6CiRiOG0UyXP+V1+jWqUXVjPKLAI0mRfJZTmQ= +github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= +github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/ebitengine/purego v0.10.0 h1:QIw4xfpWT6GWTzaW5XEKy3HXoqrJGx1ijYHzTF0/ISU= +github.com/ebitengine/purego v0.10.0/go.mod h1:iIjxzd6CiRiOG0UyXP+V1+jWqUXVjPKLAI0mRfJZTmQ= github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg= github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= -github.com/foxboron/go-tpm-keyfiles v0.0.0-20250903184740-5d135037bd4d h1:EdO/NMMuCZfxhdzTZLuKAciQSnI2DV+Ppg8+vAYrnqA= -github.com/foxboron/go-tpm-keyfiles v0.0.0-20250903184740-5d135037bd4d/go.mod h1:uAyTlAUxchYuiFjTHmuIEJ4nGSm7iOPaGcAyA81fJ80= -github.com/foxboron/swtpm_test v0.0.0-20230726224112-46aaafdf7006 h1:50sW4r0PcvlpG4PV8tYh2RVCapszJgaOLRCS2subvV4= -github.com/foxboron/swtpm_test v0.0.0-20230726224112-46aaafdf7006/go.mod h1:eIXCMsMYCaqq9m1KSSxXwQG11krpuNPGP3k0uaWrbas= +github.com/foxboron/go-tpm-keyfiles v0.0.0-20251226215517-609e4778396f h1:RJ+BDPLSHQO7cSjKBqjPJSbi1qfk9WcsjQDtZiw3dZw= +github.com/foxboron/go-tpm-keyfiles v0.0.0-20251226215517-609e4778396f/go.mod h1:VHbbch/X4roIY22jL1s3qRbZhCiRIgUAF/PdSUcx2io= github.com/fsnotify/fsnotify v1.9.0 h1:2Ml+OJNzbYCTzsxtv8vKSFD9PbJjmhYF14k/jKC7S9k= github.com/fsnotify/fsnotify v1.9.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= @@ -25,50 +24,49 @@ github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY= github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0= -github.com/go-viper/mapstructure/v2 v2.4.0 h1:EBsztssimR/CONLSZZ04E8qAkxNYq4Qp9LvH92wZUgs= -github.com/go-viper/mapstructure/v2 v2.4.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM= +github.com/go-viper/mapstructure/v2 v2.5.0 h1:vM5IJoUAy3d7zRSVtIwQgBj7BiWtMPfmPEgAXnvj1Ro= +github.com/go-viper/mapstructure/v2 v2.5.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM= github.com/gobwas/glob v0.2.3 h1:A4xDbljILXROh+kObIiy5kIaPYD8e96x1tgBhUI5J+Y= github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8= github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= github.com/golang/snappy v1.0.0 h1:Oy607GVXHs7RtbggtPBnr2RmDArIsAefDwvrdWvRhGs= github.com/golang/snappy v1.0.0/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= -github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= -github.com/google/go-tpm v0.9.7 h1:u89J4tUUeDTlH8xxC3CTW7OHZjbjKoHdQ9W7gCUhtxA= -github.com/google/go-tpm v0.9.7/go.mod h1:h9jEsEECg7gtLis0upRBQU+GhYVH6jMjrFxI8u6bVUY= -github.com/google/go-tpm-tools v0.4.4 h1:oiQfAIkc6xTy9Fl5NKTeTJkBTlXdHsxAofmQyxBKY98= -github.com/google/go-tpm-tools v0.4.4/go.mod h1:T8jXkp2s+eltnCDIsXR84/MTcVU9Ja7bh3Mit0pa4AY= +github.com/google/go-tpm v0.9.8 h1:slArAR9Ft+1ybZu0lBwpSmpwhRXaa85hWtMinMyRAWo= +github.com/google/go-tpm v0.9.8/go.mod h1:h9jEsEECg7gtLis0upRBQU+GhYVH6jMjrFxI8u6bVUY= +github.com/google/go-tpm-tools v0.4.7 h1:J3ycC8umYxM9A4eF73EofRZu4BxY0jjQnUnkhIBbvws= +github.com/google/go-tpm-tools v0.4.7/go.mod h1:gSyXTZHe3fgbzb6WEGd90QucmsnT1SRdlye82gH8QjQ= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/grafana/regexp v0.0.0-20240518133315-a468a5bfb3bc h1:GN2Lv3MGO7AS6PrRoT6yV5+wkrOpcszoIsO4+4ds248= -github.com/grafana/regexp v0.0.0-20240518133315-a468a5bfb3bc/go.mod h1:+JKpmjMGhpgPL+rXZ5nsZieVzvarn86asRlBg4uNGnk= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.2 h1:8Tjv8EJ+pM1xP8mK6egEbD1OgnVTyacbefKhmbLhIhU= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.2/go.mod h1:pkJQ2tZHJ0aFOVEEot6oZmaVEZcRme73eIFmhiVuRWs= -github.com/hashicorp/go-version v1.7.0 h1:5tqGy27NaOTB8yJKUZELlFAS/LTKJkrmONwQKeRZfjY= -github.com/hashicorp/go-version v1.7.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.28.0 h1:HWRh5R2+9EifMyIHV7ZV+MIZqgz+PMpZ14Jynv3O2Zs= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.28.0/go.mod h1:JfhWUomR1baixubs02l85lZYYOm7LV6om4ceouMv45c= +github.com/hashicorp/go-version v1.8.0 h1:KAkNb1HAiZd1ukkxDFGmokVZe1Xy9HG6NUp+bPle2i4= +github.com/hashicorp/go-version v1.8.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= +github.com/hashicorp/golang-lru/v2 v2.0.7 h1:a+bsQ5rvGLjzHuww6tVxozPZFVghXaHOwFs4luLUK2k= +github.com/hashicorp/golang-lru/v2 v2.0.7/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyfM2/ZepoAG6RGpeM= github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= -github.com/klauspost/compress v1.18.1 h1:bcSGx7UbpBqMChDtsF28Lw6v/G94LPrrbMbdC3JH2co= -github.com/klauspost/compress v1.18.1/go.mod h1:ZQFFVG+MdnR0P+l6wpXgIL4NTtwiKIdBnrBd8Nrxr+0= +github.com/klauspost/compress v1.18.4 h1:RPhnKRAQ4Fh8zU2FY/6ZFDwTVTxgJ/EMydqSTzE9a2c= +github.com/klauspost/compress v1.18.4/go.mod h1:R0h/fSBs8DE4ENlcrlib3PsXS61voFxhIs2DeRhCvJ4= github.com/knadh/koanf/maps v0.1.2 h1:RBfmAW5CnZT+PJ1CVc1QSJKf4Xu9kxfQgYVQSu8hpbo= github.com/knadh/koanf/maps v0.1.2/go.mod h1:npD/QZY3V6ghQDdcQzl1W4ICNVTkohC8E73eI2xW4yI= github.com/knadh/koanf/providers/confmap v1.0.0 h1:mHKLJTE7iXEys6deO5p6olAiZdG5zwp8Aebir+/EaRE= github.com/knadh/koanf/providers/confmap v1.0.0/go.mod h1:txHYHiI2hAtF0/0sCmcuol4IDcuQbKTybiB1nOcUo1A= -github.com/knadh/koanf/v2 v2.3.0 h1:Qg076dDRFHvqnKG97ZEsi9TAg2/nFTa9hCdcSa1lvlM= -github.com/knadh/koanf/v2 v2.3.0/go.mod h1:gRb40VRAbd4iJMYYD5IxZ6hfuopFcXBpc9bbQpZwo28= +github.com/knadh/koanf/v2 v2.3.3 h1:jLJC8XCRfLC7n4F+ZKKdBsbq1bfXTpuFhf4L7t94D94= +github.com/knadh/koanf/v2 v2.3.3/go.mod h1:gRb40VRAbd4iJMYYD5IxZ6hfuopFcXBpc9bbQpZwo28= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc= github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= -github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 h1:6E+4a0GO5zZEnZ81pIr0yLvtUWk2if982qA3F3QD6H4= -github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0/go.mod h1:zJYVVT2jmtg6P3p1VtQj7WsuWi/y4VnjVBn7F8KPB3I= +github.com/lufia/plan9stats v0.0.0-20251013123823-9fd1530e3ec3 h1:PwQumkgq4/acIiZhtifTV5OUqqiP82UAl0h87xj/l9k= +github.com/lufia/plan9stats v0.0.0-20251013123823-9fd1530e3ec3/go.mod h1:autxFIvghDt3jPTLoqZ9OZ7s9qTGNAWmYCjVFWPX/zg= github.com/mitchellh/copystructure v1.2.0 h1:vpKXTN4ewci03Vljg/q9QvCGUDttBOGBIa15WveJJGw= github.com/mitchellh/copystructure v1.2.0/go.mod h1:qLl+cE2AmVv+CoeAwDPye/v+N2HKCj9FbZEVFJRxO9s= github.com/mitchellh/reflectwalk v1.0.2 h1:G2LzWKi524PWgd3mLHV8Y5k7s6XUvT0Gef6zxSIeXaQ= @@ -81,103 +79,105 @@ github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee h1:W5t00kpgFd github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= -github.com/pierrec/lz4/v4 v4.1.22 h1:cKFw6uJDK+/gfw5BcDL0JL5aBsAFdsIT18eRtLj7VIU= -github.com/pierrec/lz4/v4 v4.1.22/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4= -github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pierrec/lz4/v4 v4.1.26 h1:GrpZw1gZttORinvzBdXPUXATeqlJjqUG/D87TKMnhjY= +github.com/pierrec/lz4/v4 v4.1.26/go.mod h1:EoQMVJgeeEOMsCqCzqFm2O0cJvljX2nGZjcRIPL34O4= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= +github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/power-devops/perfstat v0.0.0-20240221224432-82ca36839d55 h1:o4JXh1EVt9k/+g42oCprj/FisM4qX9L3sZB3upGN2ZU= github.com/power-devops/perfstat v0.0.0-20240221224432-82ca36839d55/go.mod h1:OmDBASR4679mdNQnz2pUhc2G8CO2JrUAVFDRBDP/hJE= github.com/prometheus/client_golang v1.23.2 h1:Je96obch5RDVy3FDMndoUsjAhG5Edi49h0RJWRi/o0o= github.com/prometheus/client_golang v1.23.2/go.mod h1:Tb1a6LWHB3/SPIzCoaDXI4I8UHKeFTEQ1YCr+0Gyqmg= github.com/prometheus/client_model v0.6.2 h1:oBsgwpGs7iVziMvrGhE53c/GrLUsZdHnqNwqPLxwZyk= github.com/prometheus/client_model v0.6.2/go.mod h1:y3m2F6Gdpfy6Ut/GBsUqTWZqCUvMVzSfMLjcu6wAwpE= -github.com/prometheus/common v0.67.1 h1:OTSON1P4DNxzTg4hmKCc37o4ZAZDv0cfXLkOt0oEowI= -github.com/prometheus/common v0.67.1/go.mod h1:RpmT9v35q2Y+lsieQsdOh5sXZ6ajUGC8NjZAmr8vb0Q= -github.com/prometheus/otlptranslator v0.0.2 h1:+1CdeLVrRQ6Psmhnobldo0kTp96Rj80DRXRd5OSnMEQ= -github.com/prometheus/otlptranslator v0.0.2/go.mod h1:P8AwMgdD7XEr6QRUJ2QWLpiAZTgTE2UYgjlu3svompI= -github.com/prometheus/procfs v0.17.0 h1:FuLQ+05u4ZI+SS/w9+BWEM2TXiHKsUQ9TADiRH7DuK0= -github.com/prometheus/procfs v0.17.0/go.mod h1:oPQLaDAMRbA+u8H5Pbfq+dl3VDAvHxMUOVhe0wYB2zw= +github.com/prometheus/common v0.67.5 h1:pIgK94WWlQt1WLwAC5j2ynLaBRDiinoAb86HZHTUGI4= +github.com/prometheus/common v0.67.5/go.mod h1:SjE/0MzDEEAyrdr5Gqc6G+sXI67maCxzaT3A2+HqjUw= +github.com/prometheus/otlptranslator v1.0.0 h1:s0LJW/iN9dkIH+EnhiD3BlkkP5QVIUVEoIwkU+A6qos= +github.com/prometheus/otlptranslator v1.0.0/go.mod h1:vRYWnXvI6aWGpsdY/mOT/cbeVRBlPWtBNDb7kGR3uKM= +github.com/prometheus/procfs v0.20.1 h1:XwbrGOIplXW/AU3YhIhLODXMJYyC1isLFfYCsTEycfc= +github.com/prometheus/procfs v0.20.1/go.mod h1:o9EMBZGRyvDrSPH1RqdxhojkuXstoe4UlK79eF5TGGo= github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ= github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc= github.com/rs/cors v1.11.1 h1:eU3gRzXLRK57F5rKMGMZURNdIG4EoAmX8k94r9wXWHA= github.com/rs/cors v1.11.1/go.mod h1:XyqrcTp5zjWr1wsJ8PIRZssZ8b/WMcMf71DJnit4EMU= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= -github.com/shirou/gopsutil/v4 v4.25.10 h1:at8lk/5T1OgtuCp+AwrDofFRjnvosn0nkN2OLQ6g8tA= -github.com/shirou/gopsutil/v4 v4.25.10/go.mod h1:+kSwyC8DRUD9XXEHCAFjK+0nuArFJM0lva+StQAcskM= -github.com/spf13/cobra v1.10.1 h1:lJeBwCfmrnXthfAupyUTzJ/J4Nc1RsHC/mSRU2dll/s= -github.com/spf13/cobra v1.10.1/go.mod h1:7SmJGaTHFVBY0jW4NXGluQoLvhqFQM+6XSKD+P4XaB0= -github.com/spf13/pflag v1.0.9 h1:9exaQaMOCwffKiiiYk6/BndUBv+iRViNW+4lEMi0PvY= +github.com/shirou/gopsutil/v4 v4.26.2 h1:X8i6sicvUFih4BmYIGT1m2wwgw2VG9YgrDTi7cIRGUI= +github.com/shirou/gopsutil/v4 v4.26.2/go.mod h1:LZ6ewCSkBqUpvSOf+LsTGnRinC6iaNUNMGBtDkJBaLQ= +github.com/spf13/cobra v1.10.2 h1:DMTTonx5m65Ic0GOoRY2c16WCbHxOOw6xxezuLaBpcU= +github.com/spf13/cobra v1.10.2/go.mod h1:7C1pvHqHw5A4vrJfjNwvOdzYu0Gml16OCs2GRiTUUS4= github.com/spf13/pflag v1.0.9/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= +github.com/spf13/pflag v1.0.10 h1:4EBh2KAYBwaONj6b2Ye1GiHfwjqyROoF4RwYO+vPwFk= +github.com/spf13/pflag v1.0.10/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U= github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= -github.com/tklauser/go-sysconf v0.3.15 h1:VE89k0criAymJ/Os65CSn1IXaol+1wrsFHEB8Ol49K4= -github.com/tklauser/go-sysconf v0.3.15/go.mod h1:Dmjwr6tYFIseJw7a3dRLJfsHAMXZ3nEnL/aZY+0IuI4= -github.com/tklauser/numcpus v0.10.0 h1:18njr6LDBk1zuna922MgdjQuJFjrdppsZG60sHGfjso= -github.com/tklauser/numcpus v0.10.0/go.mod h1:BiTKazU708GQTYF4mB+cmlpT2Is1gLk7XVuEeem8LsQ= +github.com/tklauser/go-sysconf v0.3.16 h1:frioLaCQSsF5Cy1jgRBrzr6t502KIIwQ0MArYICU0nA= +github.com/tklauser/go-sysconf v0.3.16/go.mod h1:/qNL9xxDhc7tx3HSRsLWNnuzbVfh3e7gh/BmM179nYI= +github.com/tklauser/numcpus v0.11.0 h1:nSTwhKH5e1dMNsCdVBukSZrURJRoHbSEQjdEbY+9RXw= +github.com/tklauser/numcpus v0.11.0/go.mod h1:z+LwcLq54uWZTX0u/bGobaV34u6V7KNlTZejzM6/3MQ= github.com/yusufpapurcu/wmi v1.2.4 h1:zFUKzehAFReQwLys1b/iSMl+JQGSCSjtVqQn9bBrPo0= github.com/yusufpapurcu/wmi v1.2.4/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0= go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64= go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y= go.opentelemetry.io/contrib/bridges/otelzap v0.13.0 h1:aBKdhLVieqvwWe9A79UHI/0vgp2t/s2euY8X59pGRlw= go.opentelemetry.io/contrib/bridges/otelzap v0.13.0/go.mod h1:SYqtxLQE7iINgh6WFuVi2AI70148B8EI35DSk0Wr8m4= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.63.0 h1:RbKq8BG0FI8OiXhBfcRtqqHcZcka+gU3cskNuf05R18= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.63.0/go.mod h1:h06DGIukJOevXaj/xrNjhi/2098RZzcLTbc0jDAUbsg= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.67.0 h1:OyrsyzuttWTSur2qN/Lm0m2a8yqyIjUVBZcxFPuXq2o= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.67.0/go.mod h1:C2NGBr+kAB4bk3xtMXfZ94gqFDtg/GkI7e9zqGh5Beg= go.opentelemetry.io/contrib/otelconf v0.18.0 h1:ciF2Gf00BWs0DnexKFZXcxg9kJ8r3SUW1LOzW3CsKA8= go.opentelemetry.io/contrib/otelconf v0.18.0/go.mod h1:FcP7k+JLwBLdOxS6qY6VQ/4b5VBntI6L6o80IMwhAeI= go.opentelemetry.io/contrib/propagators/b3 v1.38.0 h1:uHsCCOSKl0kLrV2dLkFK+8Ywk9iKa/fptkytc6aFFEo= go.opentelemetry.io/contrib/propagators/b3 v1.38.0/go.mod h1:wMRSZJZcY8ya9mApLLhwIMjqmApy2o/Ml+62lhvxyHU= -go.opentelemetry.io/contrib/zpages v0.63.0 h1:TppOKuZGbqXMgsfjqq3i09N5Vbo1JLtLImUqiTPGnX4= -go.opentelemetry.io/contrib/zpages v0.63.0/go.mod h1:5F8uugz75ay/MMhRRhxAXY33FuaI8dl7jTxefrIy5qk= -go.opentelemetry.io/otel v1.40.0 h1:oA5YeOcpRTXq6NN7frwmwFR0Cn3RhTVZvXsP4duvCms= -go.opentelemetry.io/otel v1.40.0/go.mod h1:IMb+uXZUKkMXdPddhwAHm6UfOwJyh4ct1ybIlV14J0g= -go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.14.0 h1:OMqPldHt79PqWKOMYIAQs3CxAi7RLgPxwfFSwr4ZxtM= -go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.14.0/go.mod h1:1biG4qiqTxKiUCtoWDPpL3fB3KxVwCiGw81j3nKMuHE= -go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.14.0 h1:QQqYw3lkrzwVsoEX0w//EhH/TCnpRdEenKBOOEIMjWc= -go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.14.0/go.mod h1:gSVQcr17jk2ig4jqJ2DX30IdWH251JcNAecvrqTxH1s= -go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.38.0 h1:vl9obrcoWVKp/lwl8tRE33853I8Xru9HFbw/skNeLs8= -go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.38.0/go.mod h1:GAXRxmLJcVM3u22IjTg74zWBrRCKq8BnOqUVLodpcpw= -go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.38.0 h1:Oe2z/BCg5q7k4iXC3cqJxKYg0ieRiOqF0cecFYdPTwk= -go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.38.0/go.mod h1:ZQM5lAJpOsKnYagGg/zV2krVqTtaVdYdDkhMoX6Oalg= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.38.0 h1:GqRJVj7UmLjCVyVJ3ZFLdPRmhDUp2zFmQe3RHIOsw24= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.38.0/go.mod h1:ri3aaHSmCTVYu2AWv44YMauwAQc0aqI9gHKIcSbI1pU= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.38.0 h1:lwI4Dc5leUqENgGuQImwLo4WnuXFPetmPpkLi2IrX54= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.38.0/go.mod h1:Kz/oCE7z5wuyhPxsXDuaPteSWqjSBD5YaSdbxZYGbGk= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.38.0 h1:aTL7F04bJHUlztTsNGJ2l+6he8c+y/b//eR0jjjemT4= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.38.0/go.mod h1:kldtb7jDTeol0l3ewcmd8SDvx3EmIE7lyvqbasU3QC4= -go.opentelemetry.io/otel/exporters/prometheus v0.60.0 h1:cGtQxGvZbnrWdC2GyjZi0PDKVSLWP/Jocix3QWfXtbo= -go.opentelemetry.io/otel/exporters/prometheus v0.60.0/go.mod h1:hkd1EekxNo69PTV4OWFGZcKQiIqg0RfuWExcPKFvepk= -go.opentelemetry.io/otel/exporters/stdout/stdoutlog v0.14.0 h1:B/g+qde6Mkzxbry5ZZag0l7QrQBCtVm7lVjaLgmpje8= -go.opentelemetry.io/otel/exporters/stdout/stdoutlog v0.14.0/go.mod h1:mOJK8eMmgW6ocDJn6Bn11CcZ05gi3P8GylBXEkZtbgA= -go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.38.0 h1:wm/Q0GAAykXv83wzcKzGGqAnnfLFyFe7RslekZuv+VI= -go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.38.0/go.mod h1:ra3Pa40+oKjvYh+ZD3EdxFZZB0xdMfuileHAm4nNN7w= -go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.38.0 h1:kJxSDN4SgWWTjG/hPp3O7LCGLcHXFlvS2/FFOrwL+SE= -go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.38.0/go.mod h1:mgIOzS7iZeKJdeB8/NYHrJ48fdGc71Llo5bJ1J4DWUE= -go.opentelemetry.io/otel/log v0.14.0 h1:2rzJ+pOAZ8qmZ3DDHg73NEKzSZkhkGIua9gXtxNGgrM= -go.opentelemetry.io/otel/log v0.14.0/go.mod h1:5jRG92fEAgx0SU/vFPxmJvhIuDU9E1SUnEQrMlJpOno= +go.opentelemetry.io/contrib/zpages v0.67.0 h1:cIUwWSVDovuLEbDIKreptjdxMuIhGiqwq0uL8YNaq1c= +go.opentelemetry.io/contrib/zpages v0.67.0/go.mod h1:vK8fsYHgPYg4Z/XDbFSEvItSGZDbjWTvjBOu8+AiDhc= +go.opentelemetry.io/otel v1.42.0 h1:lSQGzTgVR3+sgJDAU/7/ZMjN9Z+vUip7leaqBKy4sho= +go.opentelemetry.io/otel v1.42.0/go.mod h1:lJNsdRMxCUIWuMlVJWzecSMuNjE7dOYyWlqOXWkdqCc= +go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.18.0 h1:deI9UQMoGFgrg5iLPgzueqFPHevDl+28YKfSpPTI6rY= +go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.18.0/go.mod h1:PFx9NgpNUKXdf7J4Q3agRxMs3Y07QhTCVipKmLsMKnU= +go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.18.0 h1:icqq3Z34UrEFk2u+HMhTtRsvo7Ues+eiJVjaJt62njs= +go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.18.0/go.mod h1:W2m8P+d5Wn5kipj4/xmbt9uMqezEKfBjzVJadfABSBE= +go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.42.0 h1:MdKucPl/HbzckWWEisiNqMPhRrAOQX8r4jTuGr636gk= +go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.42.0/go.mod h1:RolT8tWtfHcjajEH5wFIZ4Dgh5jpPdFXYV9pTAk/qjc= +go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.42.0 h1:H7O6RlGOMTizyl3R08Kn5pdM06bnH8oscSj7o11tmLA= +go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.42.0/go.mod h1:mBFWu/WOVDkWWsR7Tx7h6EpQB8wsv7P0Yrh0Pb7othc= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.42.0 h1:THuZiwpQZuHPul65w4WcwEnkX2QIuMT+UFoOrygtoJw= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.42.0/go.mod h1:J2pvYM5NGHofZ2/Ru6zw/TNWnEQp5crgyDeSrYpXkAw= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.42.0 h1:zWWrB1U6nqhS/k6zYB74CjRpuiitRtLLi68VcgmOEto= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.42.0/go.mod h1:2qXPNBX1OVRC0IwOnfo1ljoid+RD0QK3443EaqVlsOU= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.42.0 h1:uLXP+3mghfMf7XmV4PkGfFhFKuNWoCvvx5wP/wOXo0o= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.42.0/go.mod h1:v0Tj04armyT59mnURNUJf7RCKcKzq+lgJs6QSjHjaTc= +go.opentelemetry.io/otel/exporters/prometheus v0.64.0 h1:g0LRDXMX/G1SEZtK8zl8Chm4K6GBwRkjPKE36LxiTYs= +go.opentelemetry.io/otel/exporters/prometheus v0.64.0/go.mod h1:UrgcjnarfdlBDP3GjDIJWe6HTprwSazNjwsI+Ru6hro= +go.opentelemetry.io/otel/exporters/stdout/stdoutlog v0.18.0 h1:KJVjPD3rcPb98rIs3HznyJlrfx9ge5oJvxxlGR+P/7s= +go.opentelemetry.io/otel/exporters/stdout/stdoutlog v0.18.0/go.mod h1:K3kRa2ckmHWQaTWQdPRHc7qGXASuVuoEQXzrvlA98Ws= +go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.42.0 h1:lSZHgNHfbmQTPfuTmWVkEu8J8qXaQwuV30pjCcAUvP8= +go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.42.0/go.mod h1:so9ounLcuoRDu033MW/E0AD4hhUjVqswrMF5FoZlBcw= +go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.42.0 h1:s/1iRkCKDfhlh1JF26knRneorus8aOwVIDhvYx9WoDw= +go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.42.0/go.mod h1:UI3wi0FXg1Pofb8ZBiBLhtMzgoTm1TYkMvn71fAqDzs= +go.opentelemetry.io/otel/log v0.18.0 h1:XgeQIIBjZZrliksMEbcwMZefoOSMI1hdjiLEiiB0bAg= +go.opentelemetry.io/otel/log v0.18.0/go.mod h1:KEV1kad0NofR3ycsiDH4Yjcoj0+8206I6Ox2QYFSNgI= go.opentelemetry.io/otel/log/logtest v0.14.0 h1:BGTqNeluJDK2uIHAY8lRqxjVAYfqgcaTbVk1n3MWe5A= go.opentelemetry.io/otel/log/logtest v0.14.0/go.mod h1:IuguGt8XVP4XA4d2oEEDMVDBBCesMg8/tSGWDjuKfoA= -go.opentelemetry.io/otel/metric v1.40.0 h1:rcZe317KPftE2rstWIBitCdVp89A2HqjkxR3c11+p9g= -go.opentelemetry.io/otel/metric v1.40.0/go.mod h1:ib/crwQH7N3r5kfiBZQbwrTge743UDc7DTFVZrrXnqc= -go.opentelemetry.io/otel/sdk v1.40.0 h1:KHW/jUzgo6wsPh9At46+h4upjtccTmuZCFAc9OJ71f8= -go.opentelemetry.io/otel/sdk v1.40.0/go.mod h1:Ph7EFdYvxq72Y8Li9q8KebuYUr2KoeyHx0DRMKrYBUE= -go.opentelemetry.io/otel/sdk/log v0.14.0 h1:JU/U3O7N6fsAXj0+CXz21Czg532dW2V4gG1HE/e8Zrg= -go.opentelemetry.io/otel/sdk/log v0.14.0/go.mod h1:imQvII+0ZylXfKU7/wtOND8Hn4OpT3YUoIgqJVksUkM= -go.opentelemetry.io/otel/sdk/log/logtest v0.14.0 h1:Ijbtz+JKXl8T2MngiwqBlPaHqc4YCaP/i13Qrow6gAM= -go.opentelemetry.io/otel/sdk/log/logtest v0.14.0/go.mod h1:dCU8aEL6q+L9cYTqcVOk8rM9Tp8WdnHOPLiBgp0SGOA= -go.opentelemetry.io/otel/sdk/metric v1.40.0 h1:mtmdVqgQkeRxHgRv4qhyJduP3fYJRMX4AtAlbuWdCYw= -go.opentelemetry.io/otel/sdk/metric v1.40.0/go.mod h1:4Z2bGMf0KSK3uRjlczMOeMhKU2rhUqdWNoKcYrtcBPg= -go.opentelemetry.io/otel/trace v1.40.0 h1:WA4etStDttCSYuhwvEa8OP8I5EWu24lkOzp+ZYblVjw= -go.opentelemetry.io/otel/trace v1.40.0/go.mod h1:zeAhriXecNGP/s2SEG3+Y8X9ujcJOTqQ5RgdEJcawiA= -go.opentelemetry.io/proto/otlp v1.7.1 h1:gTOMpGDb0WTBOP8JaO72iL3auEZhVmAQg4ipjOVAtj4= -go.opentelemetry.io/proto/otlp v1.7.1/go.mod h1:b2rVh6rfI/s2pHWNlB7ILJcRALpcNDzKhACevjI+ZnE= -go.opentelemetry.io/proto/slim/otlp v1.9.0 h1:fPVMv8tP3TrsqlkH1HWYUpbCY9cAIemx184VGkS6vlE= -go.opentelemetry.io/proto/slim/otlp v1.9.0/go.mod h1:xXdeJJ90Gqyll+orzUkY4bOd2HECo5JofeoLpymVqdI= -go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.2.0 h1:o13nadWDNkH/quoDomDUClnQBpdQQ2Qqv0lQBjIXjE8= -go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.2.0/go.mod h1:Gyb6Xe7FTi/6xBHwMmngGoHqL0w29Y4eW8TGFzpefGA= -go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.2.0 h1:EiUYvtwu6PMrMHVjcPfnsG3v+ajPkbUeH+IL93+QYyk= -go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.2.0/go.mod h1:mUUHKFiN2SST3AhJ8XhJxEoeVW12oqfXog0Bo8W3Ec4= +go.opentelemetry.io/otel/metric v1.42.0 h1:2jXG+3oZLNXEPfNmnpxKDeZsFI5o4J+nz6xUlaFdF/4= +go.opentelemetry.io/otel/metric v1.42.0/go.mod h1:RlUN/7vTU7Ao/diDkEpQpnz3/92J9ko05BIwxYa2SSI= +go.opentelemetry.io/otel/sdk v1.42.0 h1:LyC8+jqk6UJwdrI/8VydAq/hvkFKNHZVIWuslJXYsDo= +go.opentelemetry.io/otel/sdk v1.42.0/go.mod h1:rGHCAxd9DAph0joO4W6OPwxjNTYWghRWmkHuGbayMts= +go.opentelemetry.io/otel/sdk/log v0.18.0 h1:n8OyZr7t7otkeTnPTbDNom6rW16TBYGtvyy2Gk6buQw= +go.opentelemetry.io/otel/sdk/log v0.18.0/go.mod h1:C0+wxkTwKpOCZLrlJ3pewPiiQwpzycPI/u6W0Z9fuYk= +go.opentelemetry.io/otel/sdk/log/logtest v0.18.0 h1:l3mYuPsuBx6UKE47BVcPrZoZ0q/KER57vbj2qkgDLXA= +go.opentelemetry.io/otel/sdk/log/logtest v0.18.0/go.mod h1:7cHtiVJpZebB3wybTa4NG+FUo5NPe3PROz1FqB0+qdw= +go.opentelemetry.io/otel/sdk/metric v1.42.0 h1:D/1QR46Clz6ajyZ3G8SgNlTJKBdGp84q9RKCAZ3YGuA= +go.opentelemetry.io/otel/sdk/metric v1.42.0/go.mod h1:Ua6AAlDKdZ7tdvaQKfSmnFTdHx37+J4ba8MwVCYM5hc= +go.opentelemetry.io/otel/trace v1.42.0 h1:OUCgIPt+mzOnaUTpOQcBiM/PLQ/Op7oq6g4LenLmOYY= +go.opentelemetry.io/otel/trace v1.42.0/go.mod h1:f3K9S+IFqnumBkKhRJMeaZeNk9epyhnCmQh/EysQCdc= +go.opentelemetry.io/proto/otlp v1.10.0 h1:IQRWgT5srOCYfiWnpqUYz9CVmbO8bFmKcwYxpuCSL2g= +go.opentelemetry.io/proto/otlp v1.10.0/go.mod h1:/CV4QoCR/S9yaPj8utp3lvQPoqMtxXdzn7ozvvozVqk= +go.opentelemetry.io/proto/slim/otlp v1.10.0 h1:iR97Vs/ZDR+y9TfuP9b1XBtdPWeC+OMslIBmhcLU7jM= +go.opentelemetry.io/proto/slim/otlp v1.10.0/go.mod h1:lV9250stpjYLPNA5viFabIgP2QlUGRT1GdTgAf8SIUk= +go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.3.0 h1:RUF5rO0hAlgiJt1fzQVzcVs3vZVNHIcMLgOgG4rWNcQ= +go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.3.0/go.mod h1:I89cynRj8y+383o7tEQVg2SVA6SRgDVIouWPUVXjx0U= +go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.3.0 h1:CQvJSldHRUN6Z8jsUeYv8J0lXRvygALXIzsmAeCcZE0= +go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.3.0/go.mod h1:xSQ+mEfJe/GjK1LXEyVOoSI1N9JV9ZI923X5kup43W4= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= @@ -188,29 +188,28 @@ go.yaml.in/yaml/v2 v2.4.3 h1:6gvOSjQoTB3vt1l+CU+tSyi/HOjfOjRLJ4YwYZGwRO0= go.yaml.in/yaml/v2 v2.4.3/go.mod h1:zSxWcmIDjOzPXpjlTTbAsKokqkDNAVtZO0WOMiT90s8= go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc= go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg= -golang.org/x/crypto v0.45.0 h1:jMBrvKuj23MTlT0bQEOBcAE0mjg8mK9RXFhRH6nyF3Q= -golang.org/x/crypto v0.45.0/go.mod h1:XTGrrkGJve7CYK7J8PEww4aY7gM3qMCElcJQ8n8JdX4= +golang.org/x/crypto v0.48.0 h1:/VRzVqiRSggnhY7gNRxPauEQ5Drw9haKdM0jqfcCFts= +golang.org/x/crypto v0.48.0/go.mod h1:r0kV5h3qnFPlQnBSrULhlsRfryS2pmewsg+XfMgkVos= golang.org/x/exp v0.0.0-20240506185415-9bf2ced13842 h1:vr/HnozRka3pE4EsMEg1lgkXJkTFJCVUX+S/ZT6wYzM= golang.org/x/exp v0.0.0-20240506185415-9bf2ced13842/go.mod h1:XtvwrStGgqGPLc4cjQfWqZHG1YFdYs6swckp8vpsjnc= -golang.org/x/net v0.47.0 h1:Mx+4dIFzqraBXUugkia1OOvlD6LemFo1ALMHjrXDOhY= -golang.org/x/net v0.47.0/go.mod h1:/jNxtkgq5yWUGYkaZGqo27cfGZ1c5Nen03aYrrKpVRU= +golang.org/x/net v0.51.0 h1:94R/GTO7mt3/4wIKpcR5gkGmRLOuE/2hNGeWq/GBIFo= +golang.org/x/net v0.51.0/go.mod h1:aamm+2QF5ogm02fjy5Bb7CQ0WMt1/WVM7FtyaTLlA9Y= golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201204225414-ed752295db88/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.40.0 h1:DBZZqJ2Rkml6QMQsZywtnjnnGvHza6BTfYFWY9kjEWQ= -golang.org/x/sys v0.40.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= -golang.org/x/text v0.31.0 h1:aC8ghyu4JhP8VojJ2lEHBnochRno1sgL6nEi9WGFGMM= -golang.org/x/text v0.31.0/go.mod h1:tKRAlv61yKIjGGHX/4tP1LTbc13YSec1pxVEWXzfoeM= -golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -gonum.org/v1/gonum v0.16.0 h1:5+ul4Swaf3ESvrOnidPp4GZbzf0mxVQpDCYUQE7OJfk= -gonum.org/v1/gonum v0.16.0/go.mod h1:fef3am4MQ93R2HHpKnLk4/Tbh/s0+wqD5nfa6Pnwy4E= -google.golang.org/genproto/googleapis/api v0.0.0-20251022142026-3a174f9686a8 h1:mepRgnBZa07I4TRuomDE4sTIYieg/osKmzIf4USdWS4= -google.golang.org/genproto/googleapis/api v0.0.0-20251022142026-3a174f9686a8/go.mod h1:fDMmzKV90WSg1NbozdqrE64fkuTv6mlq2zxo9ad+3yo= -google.golang.org/genproto/googleapis/rpc v0.0.0-20251022142026-3a174f9686a8 h1:M1rk8KBnUsBDg1oPGHNCxG4vc1f49epmTO7xscSajMk= -google.golang.org/genproto/googleapis/rpc v0.0.0-20251022142026-3a174f9686a8/go.mod h1:7i2o+ce6H/6BluujYR+kqX3GKH+dChPTQU19wjRPiGk= -google.golang.org/grpc v1.77.0 h1:wVVY6/8cGA6vvffn+wWK5ToddbgdU3d8MNENr4evgXM= -google.golang.org/grpc v1.77.0/go.mod h1:z0BY1iVj0q8E1uSQCjL9cppRj+gnZjzDnzV0dHhrNig= -google.golang.org/protobuf v1.36.10 h1:AYd7cD/uASjIL6Q9LiTjz8JLcrh/88q5UObnmY3aOOE= -google.golang.org/protobuf v1.36.10/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= +golang.org/x/sys v0.41.0 h1:Ivj+2Cp/ylzLiEU89QhWblYnOE9zerudt9Ftecq2C6k= +golang.org/x/sys v0.41.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= +golang.org/x/text v0.34.0 h1:oL/Qq0Kdaqxa1KbNeMKwQq0reLCCaFtqu2eNuSeNHbk= +golang.org/x/text v0.34.0/go.mod h1:homfLqTYRFyVYemLBFl5GgL/DWEiH5wcsQ5gSh1yziA= +gonum.org/v1/gonum v0.17.0 h1:VbpOemQlsSMrYmn7T2OUvQ4dqxQXU+ouZFQsZOx50z4= +gonum.org/v1/gonum v0.17.0/go.mod h1:El3tOrEuMpv2UdMrbNlKEh9vd86bmQ6vqIcDwxEOc1E= +google.golang.org/genproto/googleapis/api v0.0.0-20260226221140-a57be14db171 h1:tu/dtnW1o3wfaxCOjSLn5IRX4YDcJrtlpzYkhHhGaC4= +google.golang.org/genproto/googleapis/api v0.0.0-20260226221140-a57be14db171/go.mod h1:M5krXqk4GhBKvB596udGL3UyjL4I1+cTbK0orROM9ng= +google.golang.org/genproto/googleapis/rpc v0.0.0-20260226221140-a57be14db171 h1:ggcbiqK8WWh6l1dnltU4BgWGIGo+EVYxCaAPih/zQXQ= +google.golang.org/genproto/googleapis/rpc v0.0.0-20260226221140-a57be14db171/go.mod h1:4Hqkh8ycfw05ld/3BWL7rJOSfebL2Q+DVDeRgYgxUU8= +google.golang.org/grpc v1.79.3 h1:sybAEdRIEtvcD68Gx7dmnwjZKlyfuc61Dyo9pGXXkKE= +google.golang.org/grpc v1.79.3/go.mod h1:KmT0Kjez+0dde/v2j9vzwoAScgEPx/Bw1CYChhHLrHQ= +google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE= +google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= diff --git a/service/hostcapabilities/go.mod b/service/hostcapabilities/go.mod index 948b93e3d367..8170f9ca23ed 100644 --- a/service/hostcapabilities/go.mod +++ b/service/hostcapabilities/go.mod @@ -1,24 +1,24 @@ module go.opentelemetry.io/collector/service/hostcapabilities -go 1.24.0 +go 1.25.0 require ( - go.opentelemetry.io/collector/component v1.46.0 - go.opentelemetry.io/collector/pipeline v1.46.0 - go.opentelemetry.io/collector/service v0.140.0 + go.opentelemetry.io/collector/component v1.54.0 + go.opentelemetry.io/collector/pipeline v1.54.0 + go.opentelemetry.io/collector/service v0.148.0 ) require ( github.com/cespare/xxhash/v2 v2.3.0 // indirect - github.com/hashicorp/go-version v1.7.0 // indirect + github.com/hashicorp/go-version v1.8.0 // indirect github.com/json-iterator/go v1.1.12 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee // indirect - go.opentelemetry.io/collector/featuregate v1.46.0 // indirect - go.opentelemetry.io/collector/pdata v1.46.0 // indirect - go.opentelemetry.io/otel v1.40.0 // indirect - go.opentelemetry.io/otel/metric v1.40.0 // indirect - go.opentelemetry.io/otel/trace v1.40.0 // indirect + go.opentelemetry.io/collector/featuregate v1.54.0 // indirect + go.opentelemetry.io/collector/pdata v1.54.0 // indirect + go.opentelemetry.io/otel v1.42.0 // indirect + go.opentelemetry.io/otel/metric v1.42.0 // indirect + go.opentelemetry.io/otel/trace v1.42.0 // indirect go.uber.org/multierr v1.11.0 // indirect go.uber.org/zap v1.27.1 // indirect ) @@ -91,3 +91,7 @@ replace go.opentelemetry.io/collector/config/configoptional => ../../config/conf replace go.opentelemetry.io/collector/service/telemetry/telemetrytest => ../telemetry/telemetrytest replace go.opentelemetry.io/collector/internal/testutil => ../../internal/testutil + +replace go.opentelemetry.io/collector/internal/componentalias => ../../internal/componentalias + +replace go.opentelemetry.io/collector/config/confignet => ../../config/confignet diff --git a/service/hostcapabilities/go.sum b/service/hostcapabilities/go.sum index 55f5e17e95dd..1baf5763d49c 100644 --- a/service/hostcapabilities/go.sum +++ b/service/hostcapabilities/go.sum @@ -1,8 +1,9 @@ github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= +github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI= github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= @@ -10,8 +11,8 @@ github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= -github.com/hashicorp/go-version v1.7.0 h1:5tqGy27NaOTB8yJKUZELlFAS/LTKJkrmONwQKeRZfjY= -github.com/hashicorp/go-version v1.7.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= +github.com/hashicorp/go-version v1.8.0 h1:KAkNb1HAiZd1ukkxDFGmokVZe1Xy9HG6NUp+bPle2i4= +github.com/hashicorp/go-version v1.8.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= @@ -20,33 +21,34 @@ github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJ github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee h1:W5t00kpgFdJifH4BDsTlE89Zl93FEloxaWZfGcifgq8= github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= -github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= +github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U= github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64= go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y= -go.opentelemetry.io/otel v1.40.0 h1:oA5YeOcpRTXq6NN7frwmwFR0Cn3RhTVZvXsP4duvCms= -go.opentelemetry.io/otel v1.40.0/go.mod h1:IMb+uXZUKkMXdPddhwAHm6UfOwJyh4ct1ybIlV14J0g= -go.opentelemetry.io/otel/metric v1.40.0 h1:rcZe317KPftE2rstWIBitCdVp89A2HqjkxR3c11+p9g= -go.opentelemetry.io/otel/metric v1.40.0/go.mod h1:ib/crwQH7N3r5kfiBZQbwrTge743UDc7DTFVZrrXnqc= -go.opentelemetry.io/otel/trace v1.40.0 h1:WA4etStDttCSYuhwvEa8OP8I5EWu24lkOzp+ZYblVjw= -go.opentelemetry.io/otel/trace v1.40.0/go.mod h1:zeAhriXecNGP/s2SEG3+Y8X9ujcJOTqQ5RgdEJcawiA= -go.opentelemetry.io/proto/slim/otlp v1.9.0 h1:fPVMv8tP3TrsqlkH1HWYUpbCY9cAIemx184VGkS6vlE= -go.opentelemetry.io/proto/slim/otlp v1.9.0/go.mod h1:xXdeJJ90Gqyll+orzUkY4bOd2HECo5JofeoLpymVqdI= -go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.2.0 h1:o13nadWDNkH/quoDomDUClnQBpdQQ2Qqv0lQBjIXjE8= -go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.2.0/go.mod h1:Gyb6Xe7FTi/6xBHwMmngGoHqL0w29Y4eW8TGFzpefGA= -go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.2.0 h1:EiUYvtwu6PMrMHVjcPfnsG3v+ajPkbUeH+IL93+QYyk= -go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.2.0/go.mod h1:mUUHKFiN2SST3AhJ8XhJxEoeVW12oqfXog0Bo8W3Ec4= +go.opentelemetry.io/otel v1.42.0 h1:lSQGzTgVR3+sgJDAU/7/ZMjN9Z+vUip7leaqBKy4sho= +go.opentelemetry.io/otel v1.42.0/go.mod h1:lJNsdRMxCUIWuMlVJWzecSMuNjE7dOYyWlqOXWkdqCc= +go.opentelemetry.io/otel/metric v1.42.0 h1:2jXG+3oZLNXEPfNmnpxKDeZsFI5o4J+nz6xUlaFdF/4= +go.opentelemetry.io/otel/metric v1.42.0/go.mod h1:RlUN/7vTU7Ao/diDkEpQpnz3/92J9ko05BIwxYa2SSI= +go.opentelemetry.io/otel/trace v1.42.0 h1:OUCgIPt+mzOnaUTpOQcBiM/PLQ/Op7oq6g4LenLmOYY= +go.opentelemetry.io/otel/trace v1.42.0/go.mod h1:f3K9S+IFqnumBkKhRJMeaZeNk9epyhnCmQh/EysQCdc= +go.opentelemetry.io/proto/slim/otlp v1.10.0 h1:iR97Vs/ZDR+y9TfuP9b1XBtdPWeC+OMslIBmhcLU7jM= +go.opentelemetry.io/proto/slim/otlp v1.10.0/go.mod h1:lV9250stpjYLPNA5viFabIgP2QlUGRT1GdTgAf8SIUk= +go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.3.0 h1:RUF5rO0hAlgiJt1fzQVzcVs3vZVNHIcMLgOgG4rWNcQ= +go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.3.0/go.mod h1:I89cynRj8y+383o7tEQVg2SVA6SRgDVIouWPUVXjx0U= +go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.3.0 h1:CQvJSldHRUN6Z8jsUeYv8J0lXRvygALXIzsmAeCcZE0= +go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.3.0/go.mod h1:xSQ+mEfJe/GjK1LXEyVOoSI1N9JV9ZI923X5kup43W4= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= go.uber.org/zap v1.27.1 h1:08RqriUEv8+ArZRYSTXy1LeBScaMpVSTBhCeaZYfMYc= go.uber.org/zap v1.27.1/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= -google.golang.org/protobuf v1.36.10 h1:AYd7cD/uASjIL6Q9LiTjz8JLcrh/88q5UObnmY3aOOE= -google.golang.org/protobuf v1.36.10/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= +google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE= +google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/service/hostcapabilities/metadata.yaml b/service/hostcapabilities/metadata.yaml new file mode 100644 index 000000000000..f63429ab174b --- /dev/null +++ b/service/hostcapabilities/metadata.yaml @@ -0,0 +1,6 @@ +type: service/hostcapabilities +github_project: open-telemetry/opentelemetry-collector + +status: + disable_codecov_badge: true + class: pkg diff --git a/service/internal/builders/builders.go b/service/internal/builders/builders.go index 4e332b3012a0..fd773d7b3b0d 100644 --- a/service/internal/builders/builders.go +++ b/service/internal/builders/builders.go @@ -5,10 +5,12 @@ package builders // import "go.opentelemetry.io/collector/service/internal/build import ( "errors" + "fmt" "go.uber.org/zap" "go.opentelemetry.io/collector/component" + "go.opentelemetry.io/collector/internal/componentalias" ) var ( @@ -26,3 +28,15 @@ func logStabilityLevel(logger *zap.Logger, sl component.StabilityLevel) { logger.Info(sl.LogMessage()) } } + +// logDeprecatedTypeAlias checks if the provided type is a deprecated alias and logs a warning if so. +func logDeprecatedTypeAlias(logger *zap.Logger, factory component.Factory, usedType component.Type) { + tah, ok := factory.(componentalias.TypeAliasHolder) + if !ok { + return + } + alias := tah.DeprecatedAlias() + if alias.String() != "" && usedType == alias { + logger.Warn(fmt.Sprintf("%q alias is deprecated; use %q instead", alias.String(), factory.Type().String())) + } +} diff --git a/service/internal/builders/builders_test.go b/service/internal/builders/builders_test.go new file mode 100644 index 000000000000..c158fd37e21b --- /dev/null +++ b/service/internal/builders/builders_test.go @@ -0,0 +1,128 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +package builders + +import ( + "testing" + + "go.uber.org/zap" + "go.uber.org/zap/zaptest/observer" + + "go.opentelemetry.io/collector/component" + "go.opentelemetry.io/collector/internal/componentalias" +) + +// mockFactory is a test factory that implements component.Factory +type mockFactory struct { + factoryType component.Type +} + +func (m *mockFactory) Type() component.Type { + return m.factoryType +} + +func (m *mockFactory) CreateDefaultConfig() component.Config { + return nil +} + +// mockFactoryWithAlias is a test factory that implements both component.Factory and componentalias.TypeAliasHolder +type mockFactoryWithAlias struct { + factoryType component.Type + aliasHolder componentalias.TypeAliasHolder +} + +func (m *mockFactoryWithAlias) Type() component.Type { + return m.factoryType +} + +func (m *mockFactoryWithAlias) CreateDefaultConfig() component.Config { + return nil +} + +func (m *mockFactoryWithAlias) DeprecatedAlias() component.Type { + return m.aliasHolder.DeprecatedAlias() +} + +func (m *mockFactoryWithAlias) SetDeprecatedAlias(alias component.Type) { + m.aliasHolder.SetDeprecatedAlias(alias) +} + +func TestLogDeprecatedTypeAlias(t *testing.T) { + tests := []struct { + name string + factory component.Factory + usedType component.Type + expectWarning bool + }{ + { + name: "no_alias_holder", + factory: &mockFactory{factoryType: component.MustNewType("test")}, + usedType: component.MustNewType("test"), + expectWarning: false, + }, + { + name: "no_alias_set", + factory: &mockFactoryWithAlias{ + factoryType: component.MustNewType("test"), + aliasHolder: componentalias.NewTypeAliasHolder(), + }, + usedType: component.MustNewType("test"), + expectWarning: false, + }, + { + name: "using_current_type", + factory: func() component.Factory { + f := &mockFactoryWithAlias{ + factoryType: component.MustNewType("new"), + aliasHolder: componentalias.NewTypeAliasHolder(), + } + f.aliasHolder.SetDeprecatedAlias(component.MustNewType("old")) + return f + }(), + usedType: component.MustNewType("new"), + expectWarning: false, + }, + { + name: "using_deprecated_alias", + factory: func() component.Factory { + f := &mockFactoryWithAlias{ + factoryType: component.MustNewType("new"), + aliasHolder: componentalias.NewTypeAliasHolder(), + } + f.aliasHolder.SetDeprecatedAlias(component.MustNewType("old")) + return f + }(), + usedType: component.MustNewType("old"), + expectWarning: true, + }, + { + name: "using_unrelated_type", + factory: func() component.Factory { + f := &mockFactoryWithAlias{ + factoryType: component.MustNewType("new"), + aliasHolder: componentalias.NewTypeAliasHolder(), + } + f.aliasHolder.SetDeprecatedAlias(component.MustNewType("old")) + return f + }(), + usedType: component.MustNewType("other"), + expectWarning: false, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + core, logs := observer.New(zap.WarnLevel) + logger := zap.New(core) + + logDeprecatedTypeAlias(logger, tt.factory, tt.usedType) + + if tt.expectWarning && logs.Len() != 1 { + t.Errorf("expected 1 warning log but got %d", logs.Len()) + } else if !tt.expectWarning && logs.Len() > 0 { + t.Errorf("expected no warning log but got %d", logs.Len()) + } + }) + } +} diff --git a/service/internal/builders/connector.go b/service/internal/builders/connector.go index dffc3bb0f653..27519be1fd84 100644 --- a/service/internal/builders/connector.go +++ b/service/internal/builders/connector.go @@ -47,6 +47,7 @@ func (b *ConnectorBuilder) CreateTracesToTraces(ctx context.Context, set connect return nil, fmt.Errorf("connector factory not available for: %q", set.ID) } + logDeprecatedTypeAlias(set.Logger, f, set.ID.Type()) logStabilityLevel(set.Logger, f.TracesToTracesStability()) return f.CreateTracesToTraces(ctx, set, cfg, next) } @@ -66,6 +67,7 @@ func (b *ConnectorBuilder) CreateTracesToMetrics(ctx context.Context, set connec return nil, fmt.Errorf("connector factory not available for: %q", set.ID) } + logDeprecatedTypeAlias(set.Logger, f, set.ID.Type()) logStabilityLevel(set.Logger, f.TracesToMetricsStability()) return f.CreateTracesToMetrics(ctx, set, cfg, next) } @@ -85,6 +87,7 @@ func (b *ConnectorBuilder) CreateTracesToLogs(ctx context.Context, set connector return nil, fmt.Errorf("connector factory not available for: %q", set.ID) } + logDeprecatedTypeAlias(set.Logger, f, set.ID.Type()) logStabilityLevel(set.Logger, f.TracesToLogsStability()) return f.CreateTracesToLogs(ctx, set, cfg, next) } @@ -109,6 +112,7 @@ func (b *ConnectorBuilder) CreateTracesToProfiles(ctx context.Context, set conne return nil, errDataTypes(set.ID, pipeline.SignalTraces, xpipeline.SignalProfiles) } + logDeprecatedTypeAlias(set.Logger, f, set.ID.Type()) logStabilityLevel(set.Logger, f.TracesToProfilesStability()) return f.CreateTracesToProfiles(ctx, set, cfg, next) } @@ -128,6 +132,7 @@ func (b *ConnectorBuilder) CreateMetricsToTraces(ctx context.Context, set connec return nil, fmt.Errorf("connector factory not available for: %q", set.ID) } + logDeprecatedTypeAlias(set.Logger, f, set.ID.Type()) logStabilityLevel(set.Logger, f.MetricsToTracesStability()) return f.CreateMetricsToTraces(ctx, set, cfg, next) } @@ -147,6 +152,7 @@ func (b *ConnectorBuilder) CreateMetricsToMetrics(ctx context.Context, set conne return nil, fmt.Errorf("connector factory not available for: %q", set.ID) } + logDeprecatedTypeAlias(set.Logger, f, set.ID.Type()) logStabilityLevel(set.Logger, f.MetricsToMetricsStability()) return f.CreateMetricsToMetrics(ctx, set, cfg, next) } @@ -166,6 +172,7 @@ func (b *ConnectorBuilder) CreateMetricsToLogs(ctx context.Context, set connecto return nil, fmt.Errorf("connector factory not available for: %q", set.ID) } + logDeprecatedTypeAlias(set.Logger, f, set.ID.Type()) logStabilityLevel(set.Logger, f.MetricsToLogsStability()) return f.CreateMetricsToLogs(ctx, set, cfg, next) } @@ -190,6 +197,7 @@ func (b *ConnectorBuilder) CreateMetricsToProfiles(ctx context.Context, set conn return nil, errDataTypes(set.ID, pipeline.SignalMetrics, xpipeline.SignalProfiles) } + logDeprecatedTypeAlias(set.Logger, f, set.ID.Type()) logStabilityLevel(set.Logger, f.MetricsToProfilesStability()) return f.CreateMetricsToProfiles(ctx, set, cfg, next) } @@ -209,6 +217,7 @@ func (b *ConnectorBuilder) CreateLogsToTraces(ctx context.Context, set connector return nil, fmt.Errorf("connector factory not available for: %q", set.ID) } + logDeprecatedTypeAlias(set.Logger, f, set.ID.Type()) logStabilityLevel(set.Logger, f.LogsToTracesStability()) return f.CreateLogsToTraces(ctx, set, cfg, next) } @@ -228,6 +237,7 @@ func (b *ConnectorBuilder) CreateLogsToMetrics(ctx context.Context, set connecto return nil, fmt.Errorf("connector factory not available for: %q", set.ID) } + logDeprecatedTypeAlias(set.Logger, f, set.ID.Type()) logStabilityLevel(set.Logger, f.LogsToMetricsStability()) return f.CreateLogsToMetrics(ctx, set, cfg, next) } @@ -247,6 +257,7 @@ func (b *ConnectorBuilder) CreateLogsToLogs(ctx context.Context, set connector.S return nil, fmt.Errorf("connector factory not available for: %q", set.ID) } + logDeprecatedTypeAlias(set.Logger, f, set.ID.Type()) logStabilityLevel(set.Logger, f.LogsToLogsStability()) return f.CreateLogsToLogs(ctx, set, cfg, next) } @@ -271,6 +282,7 @@ func (b *ConnectorBuilder) CreateLogsToProfiles(ctx context.Context, set connect return nil, errDataTypes(set.ID, pipeline.SignalLogs, xpipeline.SignalProfiles) } + logDeprecatedTypeAlias(set.Logger, f, set.ID.Type()) logStabilityLevel(set.Logger, f.LogsToProfilesStability()) return f.CreateLogsToProfiles(ctx, set, cfg, next) } @@ -295,6 +307,7 @@ func (b *ConnectorBuilder) CreateProfilesToTraces(ctx context.Context, set conne return nil, errDataTypes(set.ID, xpipeline.SignalProfiles, pipeline.SignalTraces) } + logDeprecatedTypeAlias(set.Logger, f, set.ID.Type()) logStabilityLevel(set.Logger, f.ProfilesToTracesStability()) return f.CreateProfilesToTraces(ctx, set, cfg, next) } @@ -319,6 +332,7 @@ func (b *ConnectorBuilder) CreateProfilesToMetrics(ctx context.Context, set conn return nil, errDataTypes(set.ID, xpipeline.SignalProfiles, pipeline.SignalMetrics) } + logDeprecatedTypeAlias(set.Logger, f, set.ID.Type()) logStabilityLevel(set.Logger, f.ProfilesToMetricsStability()) return f.CreateProfilesToMetrics(ctx, set, cfg, next) } @@ -343,6 +357,7 @@ func (b *ConnectorBuilder) CreateProfilesToLogs(ctx context.Context, set connect return nil, errDataTypes(set.ID, xpipeline.SignalProfiles, pipeline.SignalLogs) } + logDeprecatedTypeAlias(set.Logger, f, set.ID.Type()) logStabilityLevel(set.Logger, f.ProfilesToLogsStability()) return f.CreateProfilesToLogs(ctx, set, cfg, next) } @@ -367,6 +382,7 @@ func (b *ConnectorBuilder) CreateProfilesToProfiles(ctx context.Context, set con return nil, errDataTypes(set.ID, xpipeline.SignalProfiles, xpipeline.SignalProfiles) } + logDeprecatedTypeAlias(set.Logger, f, set.ID.Type()) logStabilityLevel(set.Logger, f.ProfilesToProfilesStability()) return f.CreateProfilesToProfiles(ctx, set, cfg, next) } diff --git a/service/internal/builders/exporter.go b/service/internal/builders/exporter.go index bb2367d22b74..9520eb4eddb6 100644 --- a/service/internal/builders/exporter.go +++ b/service/internal/builders/exporter.go @@ -37,6 +37,7 @@ func (b *ExporterBuilder) CreateTraces(ctx context.Context, set exporter.Setting return nil, fmt.Errorf("exporter factory not available for: %q", set.ID) } + logDeprecatedTypeAlias(set.Logger, f, set.ID.Type()) logStabilityLevel(set.Logger, f.TracesStability()) return f.CreateTraces(ctx, set, cfg) } @@ -53,6 +54,7 @@ func (b *ExporterBuilder) CreateMetrics(ctx context.Context, set exporter.Settin return nil, fmt.Errorf("exporter factory not available for: %q", set.ID) } + logDeprecatedTypeAlias(set.Logger, f, set.ID.Type()) logStabilityLevel(set.Logger, f.MetricsStability()) return f.CreateMetrics(ctx, set, cfg) } @@ -69,6 +71,7 @@ func (b *ExporterBuilder) CreateLogs(ctx context.Context, set exporter.Settings) return nil, fmt.Errorf("exporter factory not available for: %q", set.ID) } + logDeprecatedTypeAlias(set.Logger, f, set.ID.Type()) logStabilityLevel(set.Logger, f.LogsStability()) return f.CreateLogs(ctx, set, cfg) } @@ -90,6 +93,7 @@ func (b *ExporterBuilder) CreateProfiles(ctx context.Context, set exporter.Setti return nil, pipeline.ErrSignalNotSupported } + logDeprecatedTypeAlias(set.Logger, f, set.ID.Type()) logStabilityLevel(set.Logger, f.ProfilesStability()) return f.CreateProfiles(ctx, set, cfg) } diff --git a/service/internal/builders/extension.go b/service/internal/builders/extension.go index 35c2bead4aa9..c7f379370480 100644 --- a/service/internal/builders/extension.go +++ b/service/internal/builders/extension.go @@ -43,12 +43,8 @@ func (b *ExtensionBuilder) Create(ctx context.Context, set extension.Settings) ( return nil, fmt.Errorf("extension factory not available for: %q", set.ID) } - sl := f.Stability() - if sl >= component.StabilityLevelAlpha { - set.Logger.Debug(sl.LogMessage()) - } else { - set.Logger.Info(sl.LogMessage()) - } + logDeprecatedTypeAlias(set.Logger, f, set.ID.Type()) + logStabilityLevel(set.Logger, f.Stability()) return f.Create(ctx, set, cfg) } diff --git a/service/internal/builders/processor.go b/service/internal/builders/processor.go index 8e19bed3ea9a..023f41d17a5b 100644 --- a/service/internal/builders/processor.go +++ b/service/internal/builders/processor.go @@ -43,6 +43,7 @@ func (b *ProcessorBuilder) CreateTraces(ctx context.Context, set processor.Setti return nil, fmt.Errorf("processor factory not available for: %q", set.ID) } + logDeprecatedTypeAlias(set.Logger, f, set.ID.Type()) logStabilityLevel(set.Logger, f.TracesStability()) return f.CreateTraces(ctx, set, cfg, next) } @@ -62,6 +63,7 @@ func (b *ProcessorBuilder) CreateMetrics(ctx context.Context, set processor.Sett return nil, fmt.Errorf("processor factory not available for: %q", set.ID) } + logDeprecatedTypeAlias(set.Logger, f, set.ID.Type()) logStabilityLevel(set.Logger, f.MetricsStability()) return f.CreateMetrics(ctx, set, cfg, next) } @@ -81,6 +83,7 @@ func (b *ProcessorBuilder) CreateLogs(ctx context.Context, set processor.Setting return nil, fmt.Errorf("processor factory not available for: %q", set.ID) } + logDeprecatedTypeAlias(set.Logger, f, set.ID.Type()) logStabilityLevel(set.Logger, f.LogsStability()) return f.CreateLogs(ctx, set, cfg, next) } @@ -104,6 +107,7 @@ func (b *ProcessorBuilder) CreateProfiles(ctx context.Context, set processor.Set if !ok { return nil, pipeline.ErrSignalNotSupported } + logDeprecatedTypeAlias(set.Logger, f, set.ID.Type()) logStabilityLevel(set.Logger, f.ProfilesStability()) return f.CreateProfiles(ctx, set, cfg, next) } diff --git a/service/internal/builders/receiver.go b/service/internal/builders/receiver.go index 2568392622be..2277b1b4ca36 100644 --- a/service/internal/builders/receiver.go +++ b/service/internal/builders/receiver.go @@ -44,6 +44,7 @@ func (b *ReceiverBuilder) CreateTraces(ctx context.Context, set receiver.Setting return nil, fmt.Errorf("receiver factory not available for: %q", set.ID) } + logDeprecatedTypeAlias(set.Logger, f, set.ID.Type()) logStabilityLevel(set.Logger, f.TracesStability()) return f.CreateTraces(ctx, set, cfg, next) } @@ -63,6 +64,7 @@ func (b *ReceiverBuilder) CreateMetrics(ctx context.Context, set receiver.Settin return nil, fmt.Errorf("receiver factory not available for: %q", set.ID) } + logDeprecatedTypeAlias(set.Logger, f, set.ID.Type()) logStabilityLevel(set.Logger, f.MetricsStability()) return f.CreateMetrics(ctx, set, cfg, next) } @@ -82,6 +84,7 @@ func (b *ReceiverBuilder) CreateLogs(ctx context.Context, set receiver.Settings, return nil, fmt.Errorf("receiver factory not available for: %q", set.ID) } + logDeprecatedTypeAlias(set.Logger, f, set.ID.Type()) logStabilityLevel(set.Logger, f.LogsStability()) return f.CreateLogs(ctx, set, cfg, next) } @@ -106,6 +109,7 @@ func (b *ReceiverBuilder) CreateProfiles(ctx context.Context, set receiver.Setti return nil, pipeline.ErrSignalNotSupported } + logDeprecatedTypeAlias(set.Logger, f, set.ID.Type()) logStabilityLevel(set.Logger, f.ProfilesStability()) return f.CreateProfiles(ctx, set, cfg, next) } diff --git a/service/internal/componentattribute/telemetry.go b/service/internal/componentattribute/telemetry.go index cea5df76450d..6269fce3e7e2 100644 --- a/service/internal/componentattribute/telemetry.go +++ b/service/internal/componentattribute/telemetry.go @@ -7,7 +7,7 @@ import ( "go.opentelemetry.io/otel/attribute" "go.opentelemetry.io/collector/component" - "go.opentelemetry.io/collector/internal/telemetry" + "go.opentelemetry.io/collector/service/internal/metadata" ) func TelemetrySettingsWithAttributes(ts component.TelemetrySettings, attrSet attribute.Set) component.TelemetrySettings { @@ -17,7 +17,7 @@ func TelemetrySettingsWithAttributes(ts component.TelemetrySettings, attrSet att TracerProvider: ts.TracerProvider, attrs: attrs, } - if telemetry.NewPipelineTelemetryGate.IsEnabled() { + if metadata.TelemetryNewPipelineTelemetryFeatureGate.IsEnabled() { ts.MeterProvider = meterProviderWithAttributes{ MeterProvider: ts.MeterProvider, attrs: attrs, diff --git a/service/internal/componentattribute/telemetry_test.go b/service/internal/componentattribute/telemetry_test.go index d7d167b2ec32..c7dc2b8d65e4 100644 --- a/service/internal/componentattribute/telemetry_test.go +++ b/service/internal/componentattribute/telemetry_test.go @@ -26,6 +26,7 @@ import ( "go.opentelemetry.io/collector/featuregate" "go.opentelemetry.io/collector/internal/telemetry" "go.opentelemetry.io/collector/service/internal/componentattribute" + "go.opentelemetry.io/collector/service/internal/metadata" ) func findScopeAttributesField(context []zap.Field) ([]attribute.KeyValue, bool) { @@ -116,10 +117,10 @@ type tracerProviderWrapper struct { } func testTelemetryWithAttributes(t *testing.T, useTraceSdk bool) { - prevState := telemetry.NewPipelineTelemetryGate.IsEnabled() - require.NoError(t, featuregate.GlobalRegistry().Set(telemetry.NewPipelineTelemetryGate.ID(), true)) + prevState := metadata.TelemetryNewPipelineTelemetryFeatureGate.IsEnabled() + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.TelemetryNewPipelineTelemetryFeatureGate.ID(), true)) defer func() { - require.NoError(t, featuregate.GlobalRegistry().Set(telemetry.NewPipelineTelemetryGate.ID(), prevState)) + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.TelemetryNewPipelineTelemetryFeatureGate.ID(), prevState)) }() // Setup mock TelemetrySettings diff --git a/service/internal/graph/graph.go b/service/internal/graph/graph.go index 1b008cb44f7f..349bc8ff7aa0 100644 --- a/service/internal/graph/graph.go +++ b/service/internal/graph/graph.go @@ -493,21 +493,21 @@ func (g *Graph) ShutdownAll(ctx context.Context, reporter status.Reporter) error } func (g *Graph) GetExporters() map[pipeline.Signal]map[component.ID]component.Component { - exportersMap := make(map[pipeline.Signal]map[component.ID]component.Component) - exportersMap[pipeline.SignalTraces] = make(map[component.ID]component.Component) - exportersMap[pipeline.SignalMetrics] = make(map[component.ID]component.Component) - exportersMap[pipeline.SignalLogs] = make(map[component.ID]component.Component) - exportersMap[xpipeline.SignalProfiles] = make(map[component.ID]component.Component) + exporters := make(map[pipeline.Signal]map[component.ID]component.Component) + exporters[pipeline.SignalTraces] = make(map[component.ID]component.Component) + exporters[pipeline.SignalMetrics] = make(map[component.ID]component.Component) + exporters[pipeline.SignalLogs] = make(map[component.ID]component.Component) + exporters[xpipeline.SignalProfiles] = make(map[component.ID]component.Component) for _, pg := range g.pipelines { for _, expNode := range pg.exporters { // Skip connectors, otherwise individual components can introduce cycles if expNode, ok := g.componentGraph.Node(expNode.ID()).(*exporterNode); ok { - exportersMap[expNode.pipelineType][expNode.componentID] = expNode.Component + exporters[expNode.pipelineType][expNode.componentID] = expNode.Component } } } - return exportersMap + return exporters } func cycleErr(err error, cycles [][]graph.Node) error { diff --git a/service/internal/graph/obs_test.go b/service/internal/graph/obs_test.go index bd18c3d50922..24624970901d 100644 --- a/service/internal/graph/obs_test.go +++ b/service/internal/graph/obs_test.go @@ -548,7 +548,7 @@ func TestComponentInstrumentation(t *testing.T) { "otelcol.receiver.produced.size": simpleMetric{ attribute.NewSet( attribute.String(obsconsumer.ComponentOutcome, "success"), - ): 1118, + ): 1055, }, }, attribute.NewSet( @@ -570,12 +570,12 @@ func TestComponentInstrumentation(t *testing.T) { "otelcol.processor.consumed.size": simpleMetric{ attribute.NewSet( attribute.String(obsconsumer.ComponentOutcome, "success"), - ): 1118, + ): 1055, }, "otelcol.processor.produced.size": simpleMetric{ attribute.NewSet( attribute.String(obsconsumer.ComponentOutcome, "success"), - ): 1118, + ): 1055, }, }, attribute.NewSet( @@ -602,17 +602,17 @@ func TestComponentInstrumentation(t *testing.T) { "otelcol.connector.consumed.size": simpleMetric{ attribute.NewSet( attribute.String(obsconsumer.ComponentOutcome, "success"), - ): 1118, + ): 1055, }, "otelcol.connector.produced.size": simpleMetric{ attribute.NewSet( attribute.String(obsconsumer.ComponentOutcome, "success"), attribute.String("otelcol.pipeline.id", "profiles/right"), - ): 587, + ): 552, attribute.NewSet( attribute.String(obsconsumer.ComponentOutcome, "success"), attribute.String("otelcol.pipeline.id", "profiles/left"), - ): 531, + ): 503, }, }, attribute.NewSet( @@ -628,7 +628,7 @@ func TestComponentInstrumentation(t *testing.T) { "otelcol.exporter.consumed.size": simpleMetric{ attribute.NewSet( attribute.String(obsconsumer.ComponentOutcome, "success"), - ): 587, + ): 552, }, }, attribute.NewSet( @@ -644,7 +644,7 @@ func TestComponentInstrumentation(t *testing.T) { "otelcol.exporter.consumed.size": simpleMetric{ attribute.NewSet( attribute.String(obsconsumer.ComponentOutcome, "success"), - ): 531, + ): 503, }, }, } diff --git a/service/internal/graph/util_test.go b/service/internal/graph/util_test.go index c296dd854dda..e3439e8a9b1f 100644 --- a/service/internal/graph/util_test.go +++ b/service/internal/graph/util_test.go @@ -21,13 +21,13 @@ import ( "go.opentelemetry.io/collector/exporter" "go.opentelemetry.io/collector/exporter/xexporter" "go.opentelemetry.io/collector/featuregate" - "go.opentelemetry.io/collector/internal/telemetry" "go.opentelemetry.io/collector/pipeline" "go.opentelemetry.io/collector/pipeline/xpipeline" "go.opentelemetry.io/collector/processor" "go.opentelemetry.io/collector/processor/xprocessor" "go.opentelemetry.io/collector/receiver" "go.opentelemetry.io/collector/receiver/xreceiver" + "go.opentelemetry.io/collector/service/internal/metadata" "go.opentelemetry.io/collector/service/pipelines" ) @@ -311,9 +311,9 @@ func (e errComponent) Shutdown(context.Context) error { } func setObsConsumerGateForTest(t *testing.T, enabled bool) { - initial := telemetry.NewPipelineTelemetryGate.IsEnabled() - require.NoError(t, featuregate.GlobalRegistry().Set(telemetry.NewPipelineTelemetryGate.ID(), enabled)) + initial := metadata.TelemetryNewPipelineTelemetryFeatureGate.IsEnabled() + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.TelemetryNewPipelineTelemetryFeatureGate.ID(), enabled)) t.Cleanup(func() { - require.NoError(t, featuregate.GlobalRegistry().Set(telemetry.NewPipelineTelemetryGate.ID(), initial)) + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.TelemetryNewPipelineTelemetryFeatureGate.ID(), initial)) }) } diff --git a/service/internal/metadata/generated_feature_gates.go b/service/internal/metadata/generated_feature_gates.go new file mode 100644 index 000000000000..720a232a2308 --- /dev/null +++ b/service/internal/metadata/generated_feature_gates.go @@ -0,0 +1,39 @@ +// Code generated by mdatagen. DO NOT EDIT. + +package metadata + +import ( + "go.opentelemetry.io/collector/featuregate" +) + +var ServiceAllowNoPipelinesFeatureGate = featuregate.GlobalRegistry().MustRegister( + "service.AllowNoPipelines", + featuregate.StageAlpha, + featuregate.WithRegisterDescription("Allow starting the Collector without starting any pipelines."), + featuregate.WithRegisterReferenceURL("https://github.com/open-telemetry/opentelemetry-collector/pull/12613"), + featuregate.WithRegisterFromVersion("v0.122.0"), +) + +var ServiceProfilesSupportFeatureGate = featuregate.GlobalRegistry().MustRegister( + "service.profilesSupport", + featuregate.StageAlpha, + featuregate.WithRegisterDescription("Controls whether profiles support can be enabled"), + featuregate.WithRegisterReferenceURL("https://github.com/open-telemetry/opentelemetry-collector/pull/11477"), + featuregate.WithRegisterFromVersion("v0.112.0"), +) + +var TelemetryUseLocalHostAsDefaultMetricsAddressFeatureGate = featuregate.GlobalRegistry().MustRegister( + "telemetry.UseLocalHostAsDefaultMetricsAddress", + featuregate.StageBeta, + featuregate.WithRegisterDescription("Controls whether default Prometheus metrics server use localhost as the default host for their endpoints"), + featuregate.WithRegisterReferenceURL("https://github.com/open-telemetry/opentelemetry-collector/pull/11251"), + featuregate.WithRegisterFromVersion("v0.111.0"), +) + +var TelemetryNewPipelineTelemetryFeatureGate = featuregate.GlobalRegistry().MustRegister( + "telemetry.newPipelineTelemetry", + featuregate.StageAlpha, + featuregate.WithRegisterDescription("Injects component-identifying scope attributes in internal Collector metrics"), + featuregate.WithRegisterReferenceURL("https://github.com/open-telemetry/opentelemetry-collector/blob/main/docs/rfcs/component-universal-telemetry.md"), + featuregate.WithRegisterFromVersion("v0.123.0"), +) diff --git a/service/internal/metricviews/views.go b/service/internal/metricviews/views.go new file mode 100644 index 000000000000..137bffd6e06e --- /dev/null +++ b/service/internal/metricviews/views.go @@ -0,0 +1,162 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +package metricviews // import "go.opentelemetry.io/collector/service/internal/metricviews" + +import ( + config "go.opentelemetry.io/contrib/otelconf/v0.3.0" + + "go.opentelemetry.io/collector/config/configtelemetry" +) + +// DefaultViews builds the default metric views used by the service. +func DefaultViews(level configtelemetry.Level) []config.View { + views := []config.View{} + + if level < configtelemetry.LevelDetailed { + // Drop all otelhttp and otelgrpc metrics if the level is not detailed. + views = append(views, + dropViewOption(&config.ViewSelector{ + MeterName: ptr("go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc"), + }), + dropViewOption(&config.ViewSelector{ + MeterName: ptr("go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp"), + }), + // Drop duration metric if the level is not detailed + dropViewOption(&config.ViewSelector{ + MeterName: ptr("go.opentelemetry.io/collector/processor/processorhelper"), + InstrumentName: ptr("otelcol_processor_internal_duration"), + }), + ) + } + + // otel-arrow library metrics + // See https://github.com/open-telemetry/otel-arrow/blob/c39257/pkg/otel/arrow_record/consumer.go#L174-L176 + if level < configtelemetry.LevelNormal { + scope := ptr("otel-arrow/pkg/otel/arrow_record") + views = append(views, + dropViewOption(&config.ViewSelector{ + MeterName: scope, + InstrumentName: ptr("arrow_batch_records"), + }), + dropViewOption(&config.ViewSelector{ + MeterName: scope, + InstrumentName: ptr("arrow_schema_resets"), + }), + dropViewOption(&config.ViewSelector{ + MeterName: scope, + InstrumentName: ptr("arrow_memory_inuse"), + }), + ) + } + + // contrib's internal/otelarrow/netstats metrics + // See + // - https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/a25f05/internal/otelarrow/netstats/netstats.go#L130 + // - https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/a25f05/internal/otelarrow/netstats/netstats.go#L165 + if level < configtelemetry.LevelDetailed { + scope := ptr("github.com/open-telemetry/opentelemetry-collector-contrib/internal/otelarrow/netstats") + + views = append(views, + // Compressed size metrics. + dropViewOption(&config.ViewSelector{ + MeterName: scope, + InstrumentName: ptr("otelcol_*_compressed_size"), + }), + dropViewOption(&config.ViewSelector{ + MeterName: scope, + InstrumentName: ptr("otelcol_*_compressed_size"), + }), + + // makeRecvMetrics for exporters. + dropViewOption(&config.ViewSelector{ + MeterName: scope, + InstrumentName: ptr("otelcol_exporter_recv"), + }), + dropViewOption(&config.ViewSelector{ + MeterName: scope, + InstrumentName: ptr("otelcol_exporter_recv_wire"), + }), + + // makeSentMetrics for receivers. + dropViewOption(&config.ViewSelector{ + MeterName: scope, + InstrumentName: ptr("otelcol_receiver_sent"), + }), + dropViewOption(&config.ViewSelector{ + MeterName: scope, + InstrumentName: ptr("otelcol_receiver_sent_wire"), + }), + ) + } + + // Batch exporter metrics + if level < configtelemetry.LevelDetailed { + scope := ptr("go.opentelemetry.io/collector/exporter/exporterhelper") + views = append(views, + dropViewOption(&config.ViewSelector{ + MeterName: scope, + InstrumentName: ptr("otelcol_exporter_queue_batch_send_size_bytes"), + }), + dropViewOption(&config.ViewSelector{ + MeterName: scope, + InstrumentName: ptr("otelcol_exporter_queue_batch_send_size"), + }), + config.View{ + Selector: &config.ViewSelector{ + MeterName: scope, + InstrumentName: ptr("otelcol_exporter_send_failed_*"), + }, + Stream: &config.ViewStream{ + AttributeKeys: &config.IncludeExclude{ + Excluded: []string{"error.type", "error.permanent"}, + }, + }, + }, + ) + } + + // Batch processor metrics + scope := ptr("go.opentelemetry.io/collector/processor/batchprocessor") + if level < configtelemetry.LevelNormal { + views = append(views, dropViewOption(&config.ViewSelector{ + MeterName: scope, + })) + } else if level < configtelemetry.LevelDetailed { + views = append(views, dropViewOption(&config.ViewSelector{ + MeterName: scope, + InstrumentName: ptr("otelcol_processor_batch_batch_send_size_bytes"), + })) + } + + // Internal graph metrics + graphScope := ptr("go.opentelemetry.io/collector/service") + if level < configtelemetry.LevelDetailed { + views = append(views, + dropViewOption(&config.ViewSelector{ + MeterName: graphScope, + InstrumentName: ptr("otelcol.*.consumed.size"), + }), + dropViewOption(&config.ViewSelector{ + MeterName: graphScope, + InstrumentName: ptr("otelcol.*.produced.size"), + })) + } + + return views +} + +func dropViewOption(selector *config.ViewSelector) config.View { + return config.View{ + Selector: selector, + Stream: &config.ViewStream{ + Aggregation: &config.ViewStreamAggregation{ + Drop: config.ViewStreamAggregationDrop{}, + }, + }, + } +} + +func ptr[T any](v T) *T { + return &v +} diff --git a/service/internal/metricviews/views_test.go b/service/internal/metricviews/views_test.go new file mode 100644 index 000000000000..5625a510e4d2 --- /dev/null +++ b/service/internal/metricviews/views_test.go @@ -0,0 +1,168 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +package metricviews + +import ( + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + + "go.opentelemetry.io/collector/config/configtelemetry" +) + +func TestDefaultViews(t *testing.T) { + for _, tt := range []struct { + name string + level configtelemetry.Level + + wantViewsCount int + }{ + { + name: "None", + level: configtelemetry.LevelNone, + wantViewsCount: 18, + }, + { + name: "Basic", + level: configtelemetry.LevelBasic, + wantViewsCount: 18, + }, + { + name: "Normal", + level: configtelemetry.LevelNormal, + wantViewsCount: 15, + }, + { + name: "Detailed", + level: configtelemetry.LevelDetailed, + wantViewsCount: 0, + }, + } { + t.Run(tt.name, func(t *testing.T) { + views := DefaultViews(tt.level) + assert.Len(t, views, tt.wantViewsCount) + }) + } +} + +func TestDefaultViewsFiltersSendFailedAttributes(t *testing.T) { + tests := []struct { + name string + level configtelemetry.Level + expectSendFailedFilteredView bool + }{ + { + name: "basic level filters send_failed attributes", + level: configtelemetry.LevelBasic, + expectSendFailedFilteredView: true, + }, + { + name: "normal level filters send_failed attributes", + level: configtelemetry.LevelNormal, + expectSendFailedFilteredView: true, + }, + { + name: "detailed level does not filter send_failed attributes", + level: configtelemetry.LevelDetailed, + expectSendFailedFilteredView: false, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + views := DefaultViews(tt.level) + + foundSendFailedView := false + for _, view := range views { + if view.Selector == nil || + view.Selector.InstrumentName == nil || + *view.Selector.InstrumentName != "otelcol_exporter_send_failed_*" { + continue + } + foundSendFailedView = true + require.NotNil(t, view.Stream, "send_failed view should have a stream") + require.NotNil(t, view.Stream.AttributeKeys, "send_failed view should have attribute keys") + require.Equal(t, []string{"error.type", "error.permanent"}, view.Stream.AttributeKeys.Excluded, + "send_failed view should exclude 'error.type' and 'error.permanent' attributes") + break + } + + if tt.expectSendFailedFilteredView { + assert.True(t, foundSendFailedView, + "Expected to find send_failed attribute filtering view at level %s", tt.level) + } else { + assert.False(t, foundSendFailedView, + "Did not expect to find send_failed attribute filtering view at level %s", tt.level) + } + }) + } +} + +func TestDefaultViews_BatchExporterMetrics(t *testing.T) { + tests := []struct { + name string + level configtelemetry.Level + shouldDropBucket bool + shouldDropBytes bool + }{ + { + name: "basic level drops bytes", + level: configtelemetry.LevelBasic, + shouldDropBucket: true, + shouldDropBytes: true, + }, + { + name: "normal level drops bytes", + level: configtelemetry.LevelNormal, + shouldDropBucket: true, + shouldDropBytes: true, + }, + { + name: "detailed level does not drop bytes", + level: configtelemetry.LevelDetailed, + shouldDropBucket: false, + shouldDropBytes: false, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + views := DefaultViews(tt.level) + + exporterHelperScope := "go.opentelemetry.io/collector/exporter/exporterhelper" + bucketMetricName := "otelcol_exporter_queue_batch_send_size" + bytesMetricName := "otelcol_exporter_queue_batch_send_size_bytes" + + var foundBucketDrop, foundBytesDrop bool + for _, view := range views { + if view.Selector != nil { + if view.Selector.MeterName != nil && *view.Selector.MeterName == exporterHelperScope { + if view.Selector.InstrumentName != nil { + if *view.Selector.InstrumentName == bucketMetricName { + foundBucketDrop = true + // Verify it's a drop view + require.NotNil(t, view.Stream) + require.NotNil(t, view.Stream.Aggregation) + require.NotNil(t, view.Stream.Aggregation.Drop) + } + if *view.Selector.InstrumentName == bytesMetricName { + foundBytesDrop = true + // Verify it's a drop view + require.NotNil(t, view.Stream) + require.NotNil(t, view.Stream.Aggregation) + require.NotNil(t, view.Stream.Aggregation.Drop) + } + } + } + } + } + + assert.Equal(t, tt.shouldDropBucket, foundBucketDrop, + "bucket metric drop view should be %v for level %v", tt.shouldDropBucket, tt.level) + assert.Equal(t, tt.shouldDropBytes, foundBytesDrop, + "bytes metric drop view should be %v for level %v", tt.shouldDropBytes, tt.level) + }) + } +} diff --git a/service/internal/obsconsumer/gate_test.go b/service/internal/obsconsumer/gate_test.go index 317fcda27601..8ead3bbf2d70 100644 --- a/service/internal/obsconsumer/gate_test.go +++ b/service/internal/obsconsumer/gate_test.go @@ -9,13 +9,13 @@ import ( "github.com/stretchr/testify/require" "go.opentelemetry.io/collector/featuregate" - "go.opentelemetry.io/collector/internal/telemetry" + "go.opentelemetry.io/collector/service/internal/metadata" ) func setGateForTest(t *testing.T, enabled bool) { - initial := telemetry.NewPipelineTelemetryGate.IsEnabled() - require.NoError(t, featuregate.GlobalRegistry().Set(telemetry.NewPipelineTelemetryGate.ID(), enabled)) + initial := metadata.TelemetryNewPipelineTelemetryFeatureGate.IsEnabled() + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.TelemetryNewPipelineTelemetryFeatureGate.ID(), enabled)) t.Cleanup(func() { - require.NoError(t, featuregate.GlobalRegistry().Set(telemetry.NewPipelineTelemetryGate.ID(), initial)) + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.TelemetryNewPipelineTelemetryFeatureGate.ID(), initial)) }) } diff --git a/service/internal/obsconsumer/logs.go b/service/internal/obsconsumer/logs.go index ff58afda9273..f9e716904ab4 100644 --- a/service/internal/obsconsumer/logs.go +++ b/service/internal/obsconsumer/logs.go @@ -12,6 +12,7 @@ import ( "go.opentelemetry.io/collector/consumer/consumererror" "go.opentelemetry.io/collector/internal/telemetry" "go.opentelemetry.io/collector/pdata/plog" + "go.opentelemetry.io/collector/service/internal/metadata" ) var ( @@ -20,7 +21,7 @@ var ( ) func NewLogs(cons consumer.Logs, set Settings, opts ...Option) consumer.Logs { - if !telemetry.NewPipelineTelemetryGate.IsEnabled() { + if !metadata.TelemetryNewPipelineTelemetryFeatureGate.IsEnabled() { return cons } diff --git a/service/internal/obsconsumer/metrics.go b/service/internal/obsconsumer/metrics.go index bcbf4dec829d..5301639d796f 100644 --- a/service/internal/obsconsumer/metrics.go +++ b/service/internal/obsconsumer/metrics.go @@ -12,6 +12,7 @@ import ( "go.opentelemetry.io/collector/consumer/consumererror" "go.opentelemetry.io/collector/internal/telemetry" "go.opentelemetry.io/collector/pdata/pmetric" + "go.opentelemetry.io/collector/service/internal/metadata" ) var ( @@ -20,7 +21,7 @@ var ( ) func NewMetrics(cons consumer.Metrics, set Settings, opts ...Option) consumer.Metrics { - if !telemetry.NewPipelineTelemetryGate.IsEnabled() { + if !metadata.TelemetryNewPipelineTelemetryFeatureGate.IsEnabled() { return cons } diff --git a/service/internal/obsconsumer/profiles.go b/service/internal/obsconsumer/profiles.go index 6c1f757b4919..76551a0f0008 100644 --- a/service/internal/obsconsumer/profiles.go +++ b/service/internal/obsconsumer/profiles.go @@ -13,6 +13,7 @@ import ( "go.opentelemetry.io/collector/consumer/xconsumer" "go.opentelemetry.io/collector/internal/telemetry" "go.opentelemetry.io/collector/pdata/pprofile" + "go.opentelemetry.io/collector/service/internal/metadata" ) var ( @@ -21,7 +22,7 @@ var ( ) func NewProfiles(cons xconsumer.Profiles, set Settings, opts ...Option) xconsumer.Profiles { - if !telemetry.NewPipelineTelemetryGate.IsEnabled() { + if !metadata.TelemetryNewPipelineTelemetryFeatureGate.IsEnabled() { return cons } diff --git a/service/internal/obsconsumer/traces.go b/service/internal/obsconsumer/traces.go index 0fd89dd33fef..49d9136e34f1 100644 --- a/service/internal/obsconsumer/traces.go +++ b/service/internal/obsconsumer/traces.go @@ -12,6 +12,7 @@ import ( "go.opentelemetry.io/collector/consumer/consumererror" "go.opentelemetry.io/collector/internal/telemetry" "go.opentelemetry.io/collector/pdata/ptrace" + "go.opentelemetry.io/collector/service/internal/metadata" ) var ( @@ -20,7 +21,7 @@ var ( ) func NewTraces(cons consumer.Traces, set Settings, opts ...Option) consumer.Traces { - if !telemetry.NewPipelineTelemetryGate.IsEnabled() { + if !metadata.TelemetryNewPipelineTelemetryFeatureGate.IsEnabled() { return cons } diff --git a/service/internal/proctelemetry/process_telemetry.go b/service/internal/proctelemetry/process_telemetry.go index e1f36ca61f9f..af00d2b62345 100644 --- a/service/internal/proctelemetry/process_telemetry.go +++ b/service/internal/proctelemetry/process_telemetry.go @@ -70,7 +70,6 @@ func RegisterProcessMetrics(cfg component.TelemetrySettings, opts ...RegisterOpt ctx = context.WithValue(ctx, common.EnvKey, common.EnvMap{common.HostProcEnvKey: set.hostProc}) } pm.context = ctx - //nolint:gosec pm.proc, err = process.NewProcessWithContext(pm.context, int32(os.Getpid())) if err != nil { return err @@ -100,7 +99,6 @@ func (pm *processMetrics) updateAllocMem(_ context.Context, obs metric.Int64Obse pm.mu.Lock() defer pm.mu.Unlock() pm.readMemStatsIfNeeded() - //nolint:gosec obs.Observe(int64(pm.ms.Alloc)) return nil } @@ -109,7 +107,6 @@ func (pm *processMetrics) updateTotalAllocMem(_ context.Context, obs metric.Int6 pm.mu.Lock() defer pm.mu.Unlock() pm.readMemStatsIfNeeded() - //nolint:gosec obs.Observe(int64(pm.ms.TotalAlloc)) return nil } @@ -118,7 +115,6 @@ func (pm *processMetrics) updateSysMem(_ context.Context, obs metric.Int64Observ pm.mu.Lock() defer pm.mu.Unlock() pm.readMemStatsIfNeeded() - //nolint:gosec obs.Observe(int64(pm.ms.Sys)) return nil } @@ -139,7 +135,6 @@ func (pm *processMetrics) updateRSSMemory(_ context.Context, obs metric.Int64Obs if err != nil { return err } - //nolint:gosec obs.Observe(int64(mem.RSS)) return nil } diff --git a/service/internal/refconsumer/logs_test.go b/service/internal/refconsumer/logs_test.go index 2b1065b48904..8adab6e47239 100644 --- a/service/internal/refconsumer/logs_test.go +++ b/service/internal/refconsumer/logs_test.go @@ -11,16 +11,16 @@ import ( "go.opentelemetry.io/collector/consumer/consumertest" "go.opentelemetry.io/collector/featuregate" - "go.opentelemetry.io/collector/internal/telemetry" "go.opentelemetry.io/collector/pdata/testdata" "go.opentelemetry.io/collector/pdata/xpdata/pref" + "go.opentelemetry.io/collector/service/internal/metadata" ) func TestLogsNopWhenGateDisabled(t *testing.T) { initial := pref.UseProtoPooling.IsEnabled() require.NoError(t, featuregate.GlobalRegistry().Set(pref.UseProtoPooling.ID(), false)) t.Cleanup(func() { - require.NoError(t, featuregate.GlobalRegistry().Set(telemetry.NewPipelineTelemetryGate.ID(), initial)) + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.TelemetryNewPipelineTelemetryFeatureGate.ID(), initial)) }) refCons := NewLogs(consumertest.NewNop()) @@ -34,7 +34,7 @@ func TestLogs(t *testing.T) { initial := pref.UseProtoPooling.IsEnabled() require.NoError(t, featuregate.GlobalRegistry().Set(pref.UseProtoPooling.ID(), true)) t.Cleanup(func() { - require.NoError(t, featuregate.GlobalRegistry().Set(telemetry.NewPipelineTelemetryGate.ID(), initial)) + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.TelemetryNewPipelineTelemetryFeatureGate.ID(), initial)) }) refCons := NewLogs(consumertest.NewNop()) diff --git a/service/internal/refconsumer/metrics_test.go b/service/internal/refconsumer/metrics_test.go index 97772cb69043..4f62fb2e4a92 100644 --- a/service/internal/refconsumer/metrics_test.go +++ b/service/internal/refconsumer/metrics_test.go @@ -11,16 +11,16 @@ import ( "go.opentelemetry.io/collector/consumer/consumertest" "go.opentelemetry.io/collector/featuregate" - "go.opentelemetry.io/collector/internal/telemetry" "go.opentelemetry.io/collector/pdata/testdata" "go.opentelemetry.io/collector/pdata/xpdata/pref" + "go.opentelemetry.io/collector/service/internal/metadata" ) func TestMetricsNopWhenGateDisabled(t *testing.T) { initial := pref.UseProtoPooling.IsEnabled() require.NoError(t, featuregate.GlobalRegistry().Set(pref.UseProtoPooling.ID(), false)) t.Cleanup(func() { - require.NoError(t, featuregate.GlobalRegistry().Set(telemetry.NewPipelineTelemetryGate.ID(), initial)) + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.TelemetryNewPipelineTelemetryFeatureGate.ID(), initial)) }) refCons := NewMetrics(consumertest.NewNop()) @@ -34,7 +34,7 @@ func TestMetrics(t *testing.T) { initial := pref.UseProtoPooling.IsEnabled() require.NoError(t, featuregate.GlobalRegistry().Set(pref.UseProtoPooling.ID(), true)) t.Cleanup(func() { - require.NoError(t, featuregate.GlobalRegistry().Set(telemetry.NewPipelineTelemetryGate.ID(), initial)) + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.TelemetryNewPipelineTelemetryFeatureGate.ID(), initial)) }) refCons := NewMetrics(consumertest.NewNop()) diff --git a/service/internal/refconsumer/profiles_test.go b/service/internal/refconsumer/profiles_test.go index 5d6b0d7fd268..f74293589b1e 100644 --- a/service/internal/refconsumer/profiles_test.go +++ b/service/internal/refconsumer/profiles_test.go @@ -11,16 +11,16 @@ import ( "go.opentelemetry.io/collector/consumer/consumertest" "go.opentelemetry.io/collector/featuregate" - "go.opentelemetry.io/collector/internal/telemetry" "go.opentelemetry.io/collector/pdata/testdata" "go.opentelemetry.io/collector/pdata/xpdata/pref" + "go.opentelemetry.io/collector/service/internal/metadata" ) func TestProfilesNopWhenGateDisabled(t *testing.T) { initial := pref.UseProtoPooling.IsEnabled() require.NoError(t, featuregate.GlobalRegistry().Set(pref.UseProtoPooling.ID(), false)) t.Cleanup(func() { - require.NoError(t, featuregate.GlobalRegistry().Set(telemetry.NewPipelineTelemetryGate.ID(), initial)) + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.TelemetryNewPipelineTelemetryFeatureGate.ID(), initial)) }) refCons := NewProfiles(consumertest.NewNop()) @@ -34,7 +34,7 @@ func TestProfiles(t *testing.T) { initial := pref.UseProtoPooling.IsEnabled() require.NoError(t, featuregate.GlobalRegistry().Set(pref.UseProtoPooling.ID(), true)) t.Cleanup(func() { - require.NoError(t, featuregate.GlobalRegistry().Set(telemetry.NewPipelineTelemetryGate.ID(), initial)) + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.TelemetryNewPipelineTelemetryFeatureGate.ID(), initial)) }) refCons := NewProfiles(consumertest.NewNop()) diff --git a/service/internal/refconsumer/traces_test.go b/service/internal/refconsumer/traces_test.go index 89b01b827e84..e1f687dca8b7 100644 --- a/service/internal/refconsumer/traces_test.go +++ b/service/internal/refconsumer/traces_test.go @@ -11,16 +11,16 @@ import ( "go.opentelemetry.io/collector/consumer/consumertest" "go.opentelemetry.io/collector/featuregate" - "go.opentelemetry.io/collector/internal/telemetry" "go.opentelemetry.io/collector/pdata/testdata" "go.opentelemetry.io/collector/pdata/xpdata/pref" + "go.opentelemetry.io/collector/service/internal/metadata" ) func TestTracesNopWhenGateDisabled(t *testing.T) { initial := pref.UseProtoPooling.IsEnabled() require.NoError(t, featuregate.GlobalRegistry().Set(pref.UseProtoPooling.ID(), false)) t.Cleanup(func() { - require.NoError(t, featuregate.GlobalRegistry().Set(telemetry.NewPipelineTelemetryGate.ID(), initial)) + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.TelemetryNewPipelineTelemetryFeatureGate.ID(), initial)) }) refCons := NewTraces(consumertest.NewNop()) @@ -34,7 +34,7 @@ func TestTraces(t *testing.T) { initial := pref.UseProtoPooling.IsEnabled() require.NoError(t, featuregate.GlobalRegistry().Set(pref.UseProtoPooling.ID(), true)) t.Cleanup(func() { - require.NoError(t, featuregate.GlobalRegistry().Set(telemetry.NewPipelineTelemetryGate.ID(), initial)) + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.TelemetryNewPipelineTelemetryFeatureGate.ID(), initial)) }) refCons := NewTraces(consumertest.NewNop()) diff --git a/service/internal/resource/config.go b/service/internal/resource/config.go index a233bbafe291..af6ea739fba5 100644 --- a/service/internal/resource/config.go +++ b/service/internal/resource/config.go @@ -7,7 +7,7 @@ import ( "github.com/google/uuid" "go.opentelemetry.io/otel/attribute" "go.opentelemetry.io/otel/sdk/resource" - semconv "go.opentelemetry.io/otel/semconv/v1.18.0" + semconv "go.opentelemetry.io/otel/semconv/v1.38.0" "go.opentelemetry.io/collector/component" ) diff --git a/service/internal/resource/config_test.go b/service/internal/resource/config_test.go index 8e406abc0c30..3ebfd04e3068 100644 --- a/service/internal/resource/config_test.go +++ b/service/internal/resource/config_test.go @@ -10,7 +10,6 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" sdkresource "go.opentelemetry.io/otel/sdk/resource" - semconv "go.opentelemetry.io/otel/semconv/v1.18.0" "go.opentelemetry.io/collector/component" "go.opentelemetry.io/collector/pdata/pcommon" @@ -137,9 +136,9 @@ func TestBuildResource(t *testing.T) { // Check override by nil resMap = map[string]*string{ - string(semconv.ServiceNameKey): nil, - string(semconv.ServiceVersionKey): nil, - string(semconv.ServiceInstanceIDKey): nil, + "service.name": nil, + "service.version": nil, + "service.instance.id": nil, } otelRes = New(buildInfo, resMap) res = pdataFromSdk(otelRes) @@ -150,9 +149,9 @@ func TestBuildResource(t *testing.T) { // Check override values strPtr := func(v string) *string { return &v } resMap = map[string]*string{ - string(semconv.ServiceNameKey): strPtr("a"), - string(semconv.ServiceVersionKey): strPtr("b"), - string(semconv.ServiceInstanceIDKey): strPtr("c"), + "service.name": strPtr("a"), + "service.version": strPtr("b"), + "service.instance.id": strPtr("c"), } otelRes = New(buildInfo, resMap) res = pdataFromSdk(otelRes) diff --git a/service/internal/status/status.go b/service/internal/status/status.go index 5a44a02665fc..bc83a0804bbc 100644 --- a/service/internal/status/status.go +++ b/service/internal/status/status.go @@ -43,6 +43,7 @@ func (m *fsm) transition(ev *componentstatus.Event) error { // newFSM creates a state machine with all valid transitions for componentstatus.Status. // The initial state is set to componentstatus.StatusNone. +// Transitions between the same status value are always allowed, as the new event may come with updated metadata. func newFSM(onTransition onTransitionFunc) *fsm { return &fsm{ current: componentstatus.NewEvent(componentstatus.StatusNone), @@ -59,16 +60,18 @@ func newFSM(onTransition onTransitionFunc) *fsm { componentstatus.StatusStopping: {}, }, componentstatus.StatusOK: { + componentstatus.StatusOK: {}, componentstatus.StatusRecoverableError: {}, componentstatus.StatusPermanentError: {}, componentstatus.StatusFatalError: {}, componentstatus.StatusStopping: {}, }, componentstatus.StatusRecoverableError: { - componentstatus.StatusOK: {}, - componentstatus.StatusPermanentError: {}, - componentstatus.StatusFatalError: {}, - componentstatus.StatusStopping: {}, + componentstatus.StatusRecoverableError: {}, + componentstatus.StatusOK: {}, + componentstatus.StatusPermanentError: {}, + componentstatus.StatusFatalError: {}, + componentstatus.StatusStopping: {}, }, componentstatus.StatusPermanentError: { componentstatus.StatusStopping: {}, diff --git a/service/internal/status/status_test.go b/service/internal/status/status_test.go index 74ffcc781cd8..6ac498ab37e5 100644 --- a/service/internal/status/status_test.go +++ b/service/internal/status/status_test.go @@ -53,13 +53,14 @@ func TestStatusFSM(t *testing.T) { }, }, { - name: "repeated events are errors", + name: "repeated OK and RecoverableError events are valid", reportedStatuses: []componentstatus.Status{ componentstatus.StatusStarting, componentstatus.StatusOK, + componentstatus.StatusOK, componentstatus.StatusRecoverableError, componentstatus.StatusRecoverableError, - componentstatus.StatusRecoverableError, + componentstatus.StatusOK, componentstatus.StatusOK, componentstatus.StatusStopping, componentstatus.StatusStopped, @@ -67,12 +68,14 @@ func TestStatusFSM(t *testing.T) { expectedStatuses: []componentstatus.Status{ componentstatus.StatusStarting, componentstatus.StatusOK, + componentstatus.StatusOK, + componentstatus.StatusRecoverableError, componentstatus.StatusRecoverableError, componentstatus.StatusOK, + componentstatus.StatusOK, componentstatus.StatusStopping, componentstatus.StatusStopped, }, - expectedErrorCount: 2, }, { name: "PermanentError is stoppable", diff --git a/service/metadata.yaml b/service/metadata.yaml index 5f59e270e25c..22337bef9cdf 100644 --- a/service/metadata.yaml +++ b/service/metadata.yaml @@ -1,3 +1,4 @@ +display_name: Service type: service github_project: open-telemetry/opentelemetry-collector @@ -5,7 +6,7 @@ status: disable_codecov_badge: true class: pkg stability: - development: [traces, metrics, logs] + development: [traces, metrics, logs, profiles] distributions: [core, contrib] telemetry: @@ -13,8 +14,7 @@ telemetry: connector.consumed.items: prefix: otelcol. enabled: true - stability: - level: development + stability: development description: Number of items passed to the connector. unit: "{item}" sum: @@ -24,8 +24,7 @@ telemetry: connector.consumed.size: prefix: otelcol. enabled: false - stability: - level: development + stability: development description: Size of items passed to the connector, based on ProtoMarshaler.Sizer. unit: "{item}" sum: @@ -35,8 +34,7 @@ telemetry: connector.produced.items: prefix: otelcol. enabled: true - stability: - level: development + stability: development description: Number of items emitted from the connector. unit: "{item}" sum: @@ -46,8 +44,7 @@ telemetry: connector.produced.size: prefix: otelcol. enabled: false - stability: - level: development + stability: development description: Size of items emitted from the connector, based on ProtoMarshaler.Sizer. unit: "{item}" sum: @@ -57,8 +54,7 @@ telemetry: exporter.consumed.items: prefix: otelcol. enabled: true - stability: - level: development + stability: development description: Number of items passed to the exporter. unit: "{item}" sum: @@ -68,8 +64,7 @@ telemetry: exporter.consumed.size: prefix: otelcol. enabled: false - stability: - level: development + stability: development description: Size of items passed to the exporter, based on ProtoMarshaler.Sizer. unit: "{item}" sum: @@ -78,8 +73,7 @@ telemetry: process_cpu_seconds: enabled: true - stability: - level: alpha + stability: alpha description: Total CPU user and system time in seconds unit: s sum: @@ -89,8 +83,7 @@ telemetry: process_memory_rss: enabled: true - stability: - level: alpha + stability: alpha description: Total physical memory (resident set size) unit: By gauge: @@ -99,8 +92,7 @@ telemetry: process_runtime_heap_alloc_bytes: enabled: true - stability: - level: alpha + stability: alpha description: Bytes of allocated heap objects (see 'go doc runtime.MemStats.HeapAlloc') unit: By gauge: @@ -109,8 +101,7 @@ telemetry: process_runtime_total_alloc_bytes: enabled: true - stability: - level: alpha + stability: alpha description: Cumulative bytes allocated for heap objects (see 'go doc runtime.MemStats.TotalAlloc') unit: By sum: @@ -120,8 +111,7 @@ telemetry: process_runtime_total_sys_memory_bytes: enabled: true - stability: - level: alpha + stability: alpha description: Total bytes of memory obtained from the OS (see 'go doc runtime.MemStats.Sys') unit: By gauge: @@ -130,8 +120,7 @@ telemetry: process_uptime: enabled: true - stability: - level: alpha + stability: alpha description: Uptime of the process unit: s sum: @@ -142,8 +131,7 @@ telemetry: processor.consumed.items: prefix: otelcol. enabled: true - stability: - level: development + stability: development description: Number of items passed to the processor. unit: "{item}" sum: @@ -153,8 +141,7 @@ telemetry: processor.consumed.size: prefix: otelcol. enabled: false - stability: - level: development + stability: development description: Size of items passed to the processor, based on ProtoMarshaler.Sizer. unit: "{item}" sum: @@ -164,8 +151,7 @@ telemetry: processor.produced.items: prefix: otelcol. enabled: true - stability: - level: development + stability: development description: Number of items emitted from the processor. unit: "{item}" sum: @@ -175,8 +161,7 @@ telemetry: processor.produced.size: prefix: otelcol. enabled: false - stability: - level: development + stability: development description: Size of items emitted from the processor, based on ProtoMarshaler.Sizer. unit: "{item}" sum: @@ -186,8 +171,7 @@ telemetry: receiver.produced.items: prefix: otelcol. enabled: true - stability: - level: development + stability: development description: Number of items emitted from the receiver. unit: "{item}" sum: @@ -197,10 +181,31 @@ telemetry: receiver.produced.size: prefix: otelcol. enabled: false - stability: - level: development + stability: development description: Size of items emitted from the receiver, based on ProtoMarshaler.Sizer. unit: "{item}" sum: value_type: int monotonic: true + +feature_gates: + - id: service.AllowNoPipelines + description: 'Allow starting the Collector without starting any pipelines.' + stage: alpha + from_version: 'v0.122.0' + reference_url: 'https://github.com/open-telemetry/opentelemetry-collector/pull/12613' + - id: service.profilesSupport + description: 'Controls whether profiles support can be enabled' + stage: alpha + from_version: 'v0.112.0' + reference_url: 'https://github.com/open-telemetry/opentelemetry-collector/pull/11477' + - id: telemetry.UseLocalHostAsDefaultMetricsAddress + description: 'Controls whether default Prometheus metrics server use localhost as the default host for their endpoints' + stage: beta + from_version: 'v0.111.0' + reference_url: 'https://github.com/open-telemetry/opentelemetry-collector/pull/11251' + - id: telemetry.newPipelineTelemetry + description: 'Injects component-identifying scope attributes in internal Collector metrics' + stage: alpha + from_version: 'v0.123.0' + reference_url: 'https://github.com/open-telemetry/opentelemetry-collector/blob/main/docs/rfcs/component-universal-telemetry.md' diff --git a/service/pipelines/config.go b/service/pipelines/config.go index b30afa0090b1..154d848a1e21 100644 --- a/service/pipelines/config.go +++ b/service/pipelines/config.go @@ -8,9 +8,9 @@ import ( "fmt" "go.opentelemetry.io/collector/component" - "go.opentelemetry.io/collector/featuregate" "go.opentelemetry.io/collector/pipeline" "go.opentelemetry.io/collector/pipeline/xpipeline" + "go.opentelemetry.io/collector/service/internal/metadata" ) var ( @@ -18,19 +18,7 @@ var ( errMissingServicePipelineReceivers = errors.New("must have at least one receiver") errMissingServicePipelineExporters = errors.New("must have at least one exporter") - serviceProfileSupportGateID = "service.profilesSupport" - serviceProfileSupportGate = featuregate.GlobalRegistry().MustRegister( - serviceProfileSupportGateID, - featuregate.StageAlpha, - featuregate.WithRegisterFromVersion("v0.112.0"), - featuregate.WithRegisterDescription("Controls whether profiles support can be enabled"), - ) - AllowNoPipelines = featuregate.GlobalRegistry().MustRegister( - "service.AllowNoPipelines", - featuregate.StageAlpha, - featuregate.WithRegisterFromVersion("v0.122.0"), - featuregate.WithRegisterDescription("Allow starting the Collector without starting any pipelines."), - ) + AllowNoPipelines = metadata.ServiceAllowNoPipelinesFeatureGate ) // Config defines the configurable settings for service telemetry. @@ -38,11 +26,11 @@ type Config map[pipeline.ID]*PipelineConfig func (cfg Config) Validate() error { // Must have at least one pipeline unless explicitly disabled. - if !AllowNoPipelines.IsEnabled() && len(cfg) == 0 { + if !metadata.ServiceAllowNoPipelinesFeatureGate.IsEnabled() && len(cfg) == 0 { return errMissingServicePipelines } - if !serviceProfileSupportGate.IsEnabled() { + if !metadata.ServiceProfilesSupportFeatureGate.IsEnabled() { // Check that all pipelines have at least one receiver and one exporter, and they reference // only configured components. for pipelineID := range cfg { @@ -50,7 +38,7 @@ func (cfg Config) Validate() error { return fmt.Errorf( "pipeline %q: profiling signal support is at alpha level, gated under the %q feature gate", pipelineID.String(), - serviceProfileSupportGateID, + metadata.ServiceProfilesSupportFeatureGate.ID(), ) } } diff --git a/service/pipelines/config_test.go b/service/pipelines/config_test.go index 59c84e71ce62..d4d7c4cc209a 100644 --- a/service/pipelines/config_test.go +++ b/service/pipelines/config_test.go @@ -14,6 +14,7 @@ import ( "go.opentelemetry.io/collector/featuregate" "go.opentelemetry.io/collector/pipeline" "go.opentelemetry.io/collector/pipeline/xpipeline" + "go.opentelemetry.io/collector/service/internal/metadata" ) func TestConfigValidate(t *testing.T) { @@ -78,7 +79,7 @@ func TestConfigValidate(t *testing.T) { { name: "enabled-featuregate-profiles", cfgFn: func(t *testing.T) Config { - require.NoError(t, featuregate.GlobalRegistry().Set(serviceProfileSupportGateID, true)) + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.ServiceProfilesSupportFeatureGate.ID(), true)) cfg := generateConfig(t) cfg[pipeline.NewID(xpipeline.SignalProfiles)] = &PipelineConfig{ @@ -102,7 +103,7 @@ func TestConfigValidate(t *testing.T) { } // Clean up the profiles support gate, which may have been enabled in `cfgFn`. - require.NoError(t, featuregate.GlobalRegistry().Set(serviceProfileSupportGateID, false)) + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.ServiceProfilesSupportFeatureGate.ID(), false)) }) } } diff --git a/service/service.go b/service/service.go index 016000bae221..0780648a4070 100644 --- a/service/service.go +++ b/service/service.go @@ -11,40 +11,29 @@ import ( "fmt" "runtime" - config "go.opentelemetry.io/contrib/otelconf/v0.3.0" noopmetric "go.opentelemetry.io/otel/metric/noop" nooptrace "go.opentelemetry.io/otel/trace/noop" "go.uber.org/multierr" "go.uber.org/zap" "go.opentelemetry.io/collector/component" - "go.opentelemetry.io/collector/config/configtelemetry" "go.opentelemetry.io/collector/confmap" "go.opentelemetry.io/collector/connector" "go.opentelemetry.io/collector/exporter" "go.opentelemetry.io/collector/extension" - "go.opentelemetry.io/collector/featuregate" "go.opentelemetry.io/collector/pdata/pcommon" "go.opentelemetry.io/collector/processor" "go.opentelemetry.io/collector/receiver" "go.opentelemetry.io/collector/service/extensions" "go.opentelemetry.io/collector/service/internal/builders" "go.opentelemetry.io/collector/service/internal/graph" + "go.opentelemetry.io/collector/service/internal/metricviews" "go.opentelemetry.io/collector/service/internal/moduleinfo" "go.opentelemetry.io/collector/service/internal/proctelemetry" "go.opentelemetry.io/collector/service/internal/status" "go.opentelemetry.io/collector/service/telemetry" ) -// This feature gate is deprecated and will be removed in 1.40.0. Views can now be configured. -var _ = featuregate.GlobalRegistry().MustRegister( - "telemetry.disableHighCardinalityMetrics", - featuregate.StageDeprecated, - featuregate.WithRegisterToVersion("0.133.0"), - featuregate.WithRegisterDescription( - "Controls whether the collector should enable potentially high "+ - "cardinality metrics. Deprecated, configure service::telemetry::metrics::views instead.")) - // ModuleInfo describes the Go module for a particular component. type ModuleInfo = moduleinfo.ModuleInfo @@ -89,8 +78,20 @@ type Settings struct { AsyncErrorChannel chan error // LoggingOptions provides a way to change behavior of zap logging. + // + // These options will be appended to any options passed to BuildZapLogger. + // + // Deprecated [v0.142.0]: use BuildZapLogger instead. This field will be + // removed in the future, and options must be injected through BuildZapLogger. LoggingOptions []zap.Option + // BuildZapLogger holds an optional function for creating a Zap logger from + // a zap.Config and options. If this is unspecified, zap.Config.Build will + // be used. + // + // NOTE: in the future this field will be required. + BuildZapLogger func(zap.Config, ...zap.Option) (*zap.Logger, error) + // TelemetryFactory is the factory for creating internal telemetry providers. TelemetryFactory telemetry.Factory } @@ -137,9 +138,23 @@ func New(ctx context.Context, set Settings, cfg Config) (_ *Service, resultErr e } telemetrySettings.Resource = &resource + // Create a function for telemetry providers to build the Zap logger. + // This injects any LoggingOptions specified in the Settings. + buildZapLogger := set.BuildZapLogger + if buildZapLogger == nil { + buildZapLogger = zap.Config.Build + } + if len(set.LoggingOptions) > 0 { + origBuildZapLogger := buildZapLogger + buildZapLogger = func(cfg zap.Config, opts ...zap.Option) (*zap.Logger, error) { + opts = append(opts, set.LoggingOptions...) + return origBuildZapLogger(cfg, opts...) + } + } + loggerSettings := telemetry.LoggerSettings{ - Settings: telemetrySettings, - ZapOptions: set.LoggingOptions, + Settings: telemetrySettings, + BuildZapLogger: buildZapLogger, } logger, loggerShutdownFunc, err := set.TelemetryFactory.CreateLogger(ctx, loggerSettings, cfg.Telemetry) if err != nil { @@ -156,7 +171,7 @@ func New(ctx context.Context, set Settings, cfg Config) (_ *Service, resultErr e meterSettings := telemetry.MeterSettings{ Settings: telemetrySettings, Logger: logger, - DefaultViews: configureViews, + DefaultViews: metricviews.DefaultViews, } meterProvider, err := set.TelemetryFactory.CreateMeterProvider(ctx, meterSettings, cfg.Telemetry) if err != nil { @@ -208,9 +223,11 @@ func New(ctx context.Context, set Settings, cfg Config) (_ *Service, resultErr e return nil, err } - if err := proctelemetry.RegisterProcessMetrics(srv.telemetrySettings); err != nil { - return nil, fmt.Errorf("failed to register process metrics: %w", err) + // Register process metrics on supported OSes. + if err := registerProcessMetrics(srv, runtime.GOOS, proctelemetry.RegisterProcessMetrics); err != nil { + return nil, err } + return srv, nil } @@ -327,140 +344,6 @@ func (srv *Service) Logger() *zap.Logger { return srv.telemetrySettings.Logger } -func dropViewOption(selector *config.ViewSelector) config.View { - return config.View{ - Selector: selector, - Stream: &config.ViewStream{ - Aggregation: &config.ViewStreamAggregation{ - Drop: config.ViewStreamAggregationDrop{}, - }, - }, - } -} - -func configureViews(level configtelemetry.Level) []config.View { - views := []config.View{} - - if level < configtelemetry.LevelDetailed { - // Drop all otelhttp and otelgrpc metrics if the level is not detailed. - views = append(views, - dropViewOption(&config.ViewSelector{ - MeterName: ptr("go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc"), - }), - dropViewOption(&config.ViewSelector{ - MeterName: ptr("go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp"), - }), - // Drop duration metric if the level is not detailed - dropViewOption(&config.ViewSelector{ - MeterName: ptr("go.opentelemetry.io/collector/processor/processorhelper"), - InstrumentName: ptr("otelcol_processor_internal_duration"), - }), - ) - } - - // otel-arrow library metrics - // See https://github.com/open-telemetry/otel-arrow/blob/c39257/pkg/otel/arrow_record/consumer.go#L174-L176 - if level < configtelemetry.LevelNormal { - scope := ptr("otel-arrow/pkg/otel/arrow_record") - views = append(views, - dropViewOption(&config.ViewSelector{ - MeterName: scope, - InstrumentName: ptr("arrow_batch_records"), - }), - dropViewOption(&config.ViewSelector{ - MeterName: scope, - InstrumentName: ptr("arrow_schema_resets"), - }), - dropViewOption(&config.ViewSelector{ - MeterName: scope, - InstrumentName: ptr("arrow_memory_inuse"), - }), - ) - } - - // contrib's internal/otelarrow/netstats metrics - // See - // - https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/a25f05/internal/otelarrow/netstats/netstats.go#L130 - // - https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/a25f05/internal/otelarrow/netstats/netstats.go#L165 - if level < configtelemetry.LevelDetailed { - scope := ptr("github.com/open-telemetry/opentelemetry-collector-contrib/internal/otelarrow/netstats") - - views = append(views, - // Compressed size metrics. - dropViewOption(&config.ViewSelector{ - MeterName: scope, - InstrumentName: ptr("otelcol_*_compressed_size"), - }), - dropViewOption(&config.ViewSelector{ - MeterName: scope, - InstrumentName: ptr("otelcol_*_compressed_size"), - }), - - // makeRecvMetrics for exporters. - dropViewOption(&config.ViewSelector{ - MeterName: scope, - InstrumentName: ptr("otelcol_exporter_recv"), - }), - dropViewOption(&config.ViewSelector{ - MeterName: scope, - InstrumentName: ptr("otelcol_exporter_recv_wire"), - }), - - // makeSentMetrics for receivers. - dropViewOption(&config.ViewSelector{ - MeterName: scope, - InstrumentName: ptr("otelcol_receiver_sent"), - }), - dropViewOption(&config.ViewSelector{ - MeterName: scope, - InstrumentName: ptr("otelcol_receiver_sent_wire"), - }), - ) - } - - // Batch exporter metrics - if level < configtelemetry.LevelDetailed { - scope := ptr("go.opentelemetry.io/collector/exporter/exporterhelper") - views = append(views, dropViewOption(&config.ViewSelector{ - MeterName: scope, - InstrumentName: ptr("otelcol_exporter_queue_batch_send_size_bytes"), - })) - } - - // Batch processor metrics - scope := ptr("go.opentelemetry.io/collector/processor/batchprocessor") - if level < configtelemetry.LevelNormal { - views = append(views, dropViewOption(&config.ViewSelector{ - MeterName: scope, - })) - } else if level < configtelemetry.LevelDetailed { - views = append(views, dropViewOption(&config.ViewSelector{ - MeterName: scope, - InstrumentName: ptr("otelcol_processor_batch_batch_send_size_bytes"), - })) - } - - // Internal graph metrics - graphScope := ptr("go.opentelemetry.io/collector/service") - if level < configtelemetry.LevelDetailed { - views = append(views, - dropViewOption(&config.ViewSelector{ - MeterName: graphScope, - InstrumentName: ptr("otelcol.*.consumed.size"), - }), - dropViewOption(&config.ViewSelector{ - MeterName: graphScope, - InstrumentName: ptr("otelcol.*.produced.size"), - })) - } - - return views -} - -func ptr[T any](v T) *T { - return &v -} - // Validate verifies the graph by calling the internal graph.Build. func Validate(ctx context.Context, set Settings, cfg Config) error { tel := component.TelemetrySettings{ @@ -483,3 +366,30 @@ func Validate(ctx context.Context, set Settings, cfg Config) error { } return nil } + +// registerProcessMetrics registers process metrics on supported operating systems. +// +// Historically, attempting to register process metrics on unsupported platforms +// (e.g. AIX) caused the Collector to fail at startup. +// See https://github.com/open-telemetry/opentelemetry-collector/issues/12098 +func registerProcessMetrics( + srv *Service, + goos string, + register func(component.TelemetrySettings, ...proctelemetry.RegisterOption) error, +) error { + switch goos { + // Only support the OSes that we explicitly test and build for, + // plus others that are known to have some support in gopsutil. + case "linux", "darwin", "windows", "freebsd", "openbsd", "solaris", "plan9": + if err := register(srv.telemetrySettings); err != nil { + return fmt.Errorf("failed to register process metrics: %w", err) + } + default: + // On unsupported OSes, log a warning and continue startup. + srv.telemetrySettings.Logger.Warn( + "Process metrics are disabled on this operating system", + zap.String("os", goos), + ) + } + return nil +} diff --git a/service/service_host_test.go b/service/service_host_test.go new file mode 100644 index 000000000000..d99ea656f1e8 --- /dev/null +++ b/service/service_host_test.go @@ -0,0 +1,112 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +package service + +import ( + "context" + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + + "go.opentelemetry.io/collector/component" + "go.opentelemetry.io/collector/component/componentstatus" + "go.opentelemetry.io/collector/pipeline" + "go.opentelemetry.io/collector/pipeline/xpipeline" +) + +var wrongType = component.MustNewType("wrong") + +func TestService_Host_GetFactory(t *testing.T) { + set := newNopSettings() + srv, err := New(context.Background(), set, newNopConfig()) + require.NoError(t, err) + + assert.NoError(t, srv.Start(context.Background())) + t.Cleanup(func() { + assert.NoError(t, srv.Shutdown(context.Background())) + }) + + assert.Nil(t, srv.host.GetFactory(component.KindReceiver, wrongType)) + assert.Equal(t, srv.host.Receivers.Factory(nopType), srv.host.GetFactory(component.KindReceiver, nopType)) + + assert.Nil(t, srv.host.GetFactory(component.KindProcessor, wrongType)) + assert.Equal(t, srv.host.Processors.Factory(nopType), srv.host.GetFactory(component.KindProcessor, nopType)) + + assert.Nil(t, srv.host.GetFactory(component.KindExporter, wrongType)) + assert.Equal(t, srv.host.Exporters.Factory(nopType), srv.host.GetFactory(component.KindExporter, nopType)) + + assert.Nil(t, srv.host.GetFactory(component.KindConnector, wrongType)) + assert.Equal(t, srv.host.Connectors.Factory(nopType), srv.host.GetFactory(component.KindConnector, nopType)) + + assert.Nil(t, srv.host.GetFactory(component.KindExtension, wrongType)) + assert.Equal(t, srv.host.Extensions.Factory(nopType), srv.host.GetFactory(component.KindExtension, nopType)) + + // Try retrieve non existing component.Kind. + assert.Nil(t, srv.host.GetFactory(component.Kind{}, nopType)) +} + +func TestService_Host_GetExtensions(t *testing.T) { + srv, err := New(context.Background(), newNopSettings(), newNopConfig()) + require.NoError(t, err) + + assert.NoError(t, srv.Start(context.Background())) + t.Cleanup(func() { + assert.NoError(t, srv.Shutdown(context.Background())) + }) + + extMap := srv.host.GetExtensions() + + assert.Len(t, extMap, 1) + assert.Contains(t, extMap, component.NewID(nopType)) +} + +func TestService_Host_GetExporters(t *testing.T) { + srv, err := New(context.Background(), newNopSettings(), newNopConfig()) + require.NoError(t, err) + + assert.NoError(t, srv.Start(context.Background())) + t.Cleanup(func() { + assert.NoError(t, srv.Shutdown(context.Background())) + }) + + //nolint:staticcheck + expMap := srv.host.GetExporters() + + v, ok := expMap[pipeline.SignalTraces] + assert.True(t, ok) + assert.NotNil(t, v) + + assert.Len(t, expMap, 4) + assert.Len(t, expMap[pipeline.SignalTraces], 1) + assert.Contains(t, expMap[pipeline.SignalTraces], component.NewID(nopType)) + assert.Len(t, expMap[pipeline.SignalMetrics], 1) + assert.Contains(t, expMap[pipeline.SignalMetrics], component.NewID(nopType)) + assert.Len(t, expMap[pipeline.SignalLogs], 1) + assert.Contains(t, expMap[pipeline.SignalLogs], component.NewID(nopType)) + assert.Len(t, expMap[xpipeline.SignalProfiles], 1) + assert.Contains(t, expMap[xpipeline.SignalProfiles], component.NewID(nopType)) +} + +func TestService_Host_FatalError(t *testing.T) { + set := newNopSettings() + set.AsyncErrorChannel = make(chan error) + + srv, err := New(context.Background(), set, newNopConfig()) + require.NoError(t, err) + + assert.NoError(t, srv.Start(context.Background())) + t.Cleanup(func() { + assert.NoError(t, srv.Shutdown(context.Background())) + }) + + go func() { + ev := componentstatus.NewFatalErrorEvent(assert.AnError) + srv.host.NotifyComponentStatusChange(&componentstatus.InstanceID{}, ev) + }() + + err = <-srv.host.AsyncErrorChannel + + require.ErrorIs(t, err, assert.AnError) +} diff --git a/service/service_test.go b/service/service_test.go index b6e686234abc..c104421af1b4 100644 --- a/service/service_test.go +++ b/service/service_test.go @@ -23,8 +23,8 @@ import ( "go.uber.org/zap/zaptest/observer" "go.opentelemetry.io/collector/component" - "go.opentelemetry.io/collector/component/componentstatus" "go.opentelemetry.io/collector/config/confighttp" + "go.opentelemetry.io/collector/config/confignet" "go.opentelemetry.io/collector/config/configtelemetry" "go.opentelemetry.io/collector/confmap" "go.opentelemetry.io/collector/extension" @@ -35,9 +35,9 @@ import ( "go.opentelemetry.io/collector/pipeline/xpipeline" "go.opentelemetry.io/collector/service/extensions" "go.opentelemetry.io/collector/service/internal/builders" + "go.opentelemetry.io/collector/service/internal/proctelemetry" "go.opentelemetry.io/collector/service/pipelines" "go.opentelemetry.io/collector/service/telemetry" - "go.opentelemetry.io/collector/service/telemetry/otelconftelemetry" "go.opentelemetry.io/collector/service/telemetry/telemetrytest" ) @@ -45,81 +45,7 @@ const ( otelCommand = "otelcoltest" ) -var ( - nopType = component.MustNewType("nop") - wrongType = component.MustNewType("wrong") -) - -func TestServiceGetFactory(t *testing.T) { - set := newNopSettings() - srv, err := New(context.Background(), set, newNopConfig()) - require.NoError(t, err) - - assert.NoError(t, srv.Start(context.Background())) - t.Cleanup(func() { - assert.NoError(t, srv.Shutdown(context.Background())) - }) - - assert.Nil(t, srv.host.GetFactory(component.KindReceiver, wrongType)) - assert.Equal(t, srv.host.Receivers.Factory(nopType), srv.host.GetFactory(component.KindReceiver, nopType)) - - assert.Nil(t, srv.host.GetFactory(component.KindProcessor, wrongType)) - assert.Equal(t, srv.host.Processors.Factory(nopType), srv.host.GetFactory(component.KindProcessor, nopType)) - - assert.Nil(t, srv.host.GetFactory(component.KindExporter, wrongType)) - assert.Equal(t, srv.host.Exporters.Factory(nopType), srv.host.GetFactory(component.KindExporter, nopType)) - - assert.Nil(t, srv.host.GetFactory(component.KindConnector, wrongType)) - assert.Equal(t, srv.host.Connectors.Factory(nopType), srv.host.GetFactory(component.KindConnector, nopType)) - - assert.Nil(t, srv.host.GetFactory(component.KindExtension, wrongType)) - assert.Equal(t, srv.host.Extensions.Factory(nopType), srv.host.GetFactory(component.KindExtension, nopType)) - - // Try retrieve non existing component.Kind. - assert.Nil(t, srv.host.GetFactory(component.Kind{}, nopType)) -} - -func TestServiceGetExtensions(t *testing.T) { - srv, err := New(context.Background(), newNopSettings(), newNopConfig()) - require.NoError(t, err) - - assert.NoError(t, srv.Start(context.Background())) - t.Cleanup(func() { - assert.NoError(t, srv.Shutdown(context.Background())) - }) - - extMap := srv.host.GetExtensions() - - assert.Len(t, extMap, 1) - assert.Contains(t, extMap, component.NewID(nopType)) -} - -func TestServiceGetExporters(t *testing.T) { - srv, err := New(context.Background(), newNopSettings(), newNopConfig()) - require.NoError(t, err) - - assert.NoError(t, srv.Start(context.Background())) - t.Cleanup(func() { - assert.NoError(t, srv.Shutdown(context.Background())) - }) - - //nolint:staticcheck - expMap := srv.host.GetExporters() - - v, ok := expMap[pipeline.SignalTraces] - assert.True(t, ok) - assert.NotNil(t, v) - - assert.Len(t, expMap, 4) - assert.Len(t, expMap[pipeline.SignalTraces], 1) - assert.Contains(t, expMap[pipeline.SignalTraces], component.NewID(nopType)) - assert.Len(t, expMap[pipeline.SignalMetrics], 1) - assert.Contains(t, expMap[pipeline.SignalMetrics], component.NewID(nopType)) - assert.Len(t, expMap[pipeline.SignalLogs], 1) - assert.Contains(t, expMap[pipeline.SignalLogs], component.NewID(nopType)) - assert.Len(t, expMap[xpipeline.SignalProfiles], 1) - assert.Contains(t, expMap[xpipeline.SignalProfiles], component.NewID(nopType)) -} +var nopType = component.MustNewType("nop") // TestServiceTelemetryCleanupOnError tests that if newService errors due to an invalid config telemetry is cleaned up // and another service with a valid config can be started right after. @@ -166,6 +92,49 @@ func TestServiceTelemetryLogging(t *testing.T) { assert.Equal(t, "warn_message", entries[0].Message) } +func TestServiceTelemetryLogging_Settings(t *testing.T) { + observerCore, observedLogs := observer.New(zapcore.WarnLevel) + zapConfig := zap.Config{Encoding: "foo"} + + set := newNopSettings() + set.BuildZapLogger = func(cfg zap.Config, opts ...zap.Option) (*zap.Logger, error) { + require.Equal(t, zapConfig, cfg) + return zap.New(observerCore, opts...), nil + } + set.LoggingOptions = []zap.Option{zap.Fields(zap.String("extra.field", "value"))} + set.BuildInfo = component.BuildInfo{Version: "test version", Command: otelCommand} + set.TelemetryFactory = telemetry.NewFactory( + func() component.Config { return nil }, + telemetry.WithCreateLogger( + func(_ context.Context, set telemetry.LoggerSettings, _ component.Config) ( + *zap.Logger, component.ShutdownFunc, error, + ) { + require.NotNil(t, set.BuildZapLogger) + require.Empty(t, set.ZapOptions) + logger, err := set.BuildZapLogger(zapConfig) + return logger, nil, err + }, + ), + ) + + cfg := newNopConfig() + srv, err := New(context.Background(), set, cfg) + require.NoError(t, err) + require.NoError(t, srv.Start(context.Background())) + defer func() { + assert.NoError(t, srv.Shutdown(context.Background())) + }() + + require.NotNil(t, srv.telemetrySettings.Logger) + assert.Equal(t, srv.telemetrySettings.Logger, srv.Logger()) + assert.Equal(t, zapcore.WarnLevel, srv.telemetrySettings.Logger.Level()) + srv.telemetrySettings.Logger.Warn("warn_message") + + entries := observedLogs.All() + require.Len(t, entries, 1) + assert.Contains(t, entries[0].ContextMap(), "extra.field") +} + func TestServiceTelemetryMetrics(t *testing.T) { // Start a service and check that metrics are produced as expected. // We do this twice to ensure that the server is stopped cleanly. @@ -251,7 +220,12 @@ func testZPages(t *testing.T, zpagesAddr string) { set.BuildInfo = component.BuildInfo{Version: "test version", Command: otelCommand} set.ExtensionsConfigs = map[component.ID]component.Config{ component.MustNewID("zpages"): &zpagesextension.Config{ - ServerConfig: confighttp.ServerConfig{Endpoint: zpagesAddr}, + ServerConfig: confighttp.ServerConfig{ + NetAddr: confignet.AddrConfig{ + Endpoint: zpagesAddr, + Transport: confignet.TransportTypeTCP, + }, + }, }, } set.ExtensionsFactories = map[component.Type]extension.Factory{ @@ -445,28 +419,6 @@ func TestServiceTelemetryLogger(t *testing.T) { assert.NotNil(t, srv.telemetrySettings.Logger) } -func TestServiceFatalError(t *testing.T) { - set := newNopSettings() - set.AsyncErrorChannel = make(chan error) - - srv, err := New(context.Background(), set, newNopConfig()) - require.NoError(t, err) - - assert.NoError(t, srv.Start(context.Background())) - t.Cleanup(func() { - assert.NoError(t, srv.Shutdown(context.Background())) - }) - - go func() { - ev := componentstatus.NewFatalErrorEvent(assert.AnError) - srv.host.NotifyComponentStatusChange(&componentstatus.InstanceID{}, ev) - }() - - err = <-srv.host.AsyncErrorChannel - - require.ErrorIs(t, err, assert.AnError) -} - func TestServiceTelemetryCreateProvidersError(t *testing.T) { loggerOpt := telemetry.WithCreateLogger( func(context.Context, telemetry.LoggerSettings, component.Config) (*zap.Logger, component.ShutdownFunc, error) { @@ -527,81 +479,6 @@ func TestNew_NilTelemetryProvider(t *testing.T) { require.EqualError(t, err, "telemetry factory not provided") } -func TestServiceTelemetryConsistentInstanceID(t *testing.T) { - var loggerResource, meterResource, tracerResource *pcommon.Resource - - createLoggerCalled := false - createMeterCalled := false - createTracerCalled := false - - baseFactory := otelconftelemetry.NewFactory() - - set := newNopSettings() - set.TelemetryFactory = telemetry.NewFactory( - baseFactory.CreateDefaultConfig, - telemetry.WithCreateResource(baseFactory.CreateResource), - telemetry.WithCreateLogger(func(ctx context.Context, settings telemetry.LoggerSettings, cfg component.Config) (*zap.Logger, component.ShutdownFunc, error) { - createLoggerCalled = true - loggerResource = settings.Resource - return baseFactory.CreateLogger(ctx, settings, cfg) - }), - telemetry.WithCreateMeterProvider(func(ctx context.Context, settings telemetry.MeterSettings, cfg component.Config) (telemetry.MeterProvider, error) { - createMeterCalled = true - meterResource = settings.Resource - return baseFactory.CreateMeterProvider(ctx, settings, cfg) - }), - telemetry.WithCreateTracerProvider(func(ctx context.Context, settings telemetry.TracerSettings, cfg component.Config) (telemetry.TracerProvider, error) { - createTracerCalled = true - tracerResource = settings.Resource - return baseFactory.CreateTracerProvider(ctx, settings, cfg) - }), - ) - - cfg := newNopConfig() - srv, err := New(context.Background(), set, cfg) - require.NoError(t, err) - - require.True(t, createLoggerCalled, "logger should have been created") - require.True(t, createMeterCalled, "meter provider should have been created") - require.True(t, createTracerCalled, "tracer provider should have been created") - - var serviceInstanceID string - if sid, ok := srv.telemetrySettings.Resource.Attributes().Get("service.instance.id"); ok { - serviceInstanceID = sid.AsString() - } - require.NotEmpty(t, serviceInstanceID, "service.instance.id not found in service resource") - - require.NotNil(t, loggerResource, "logger should have received a resource") - require.NotNil(t, meterResource, "meter provider should have received a resource") - require.NotNil(t, tracerResource, "tracer provider should have received a resource") - - var loggerInstanceID, meterInstanceID, tracerInstanceID string - if sid, ok := loggerResource.Attributes().Get("service.instance.id"); ok { - loggerInstanceID = sid.AsString() - } - if sid, ok := meterResource.Attributes().Get("service.instance.id"); ok { - meterInstanceID = sid.AsString() - } - if sid, ok := tracerResource.Attributes().Get("service.instance.id"); ok { - tracerInstanceID = sid.AsString() - } - - require.NotEmpty(t, loggerInstanceID, "logger resource should have service.instance.id") - require.NotEmpty(t, meterInstanceID, "meter resource should have service.instance.id") - require.NotEmpty(t, tracerInstanceID, "tracer resource should have service.instance.id") - - assert.Equal(t, serviceInstanceID, loggerInstanceID, - "logger should use the same service.instance.id as the service resource") - assert.Equal(t, serviceInstanceID, meterInstanceID, - "meter provider should use the same service.instance.id as the service resource") - assert.Equal(t, serviceInstanceID, tracerInstanceID, - "tracer provider should use the same service.instance.id as the service resource") - - t.Logf("service.instance.id = %s (shared by logger, meter, and tracer)", serviceInstanceID) - - require.NoError(t, srv.Shutdown(context.Background())) -} - func newNopSettings() Settings { receiversConfigs, receiversFactories := builders.NewNopReceiverConfigsAndFactories() processorsConfigs, processorsFactories := builders.NewNopProcessorConfigsAndFactories() @@ -657,27 +534,6 @@ func newNopConfigPipelineConfigs(pipelineCfgs pipelines.Config) Config { return Config{ Extensions: extensions.Config{component.NewID(nopType)}, Pipelines: pipelineCfgs, - Telemetry: &otelconftelemetry.Config{ - Logs: otelconftelemetry.LogsConfig{ - Level: zapcore.InfoLevel, - Development: false, - Encoding: "console", - Sampling: &otelconftelemetry.LogsSamplingConfig{ - Enabled: true, - Tick: 10 * time.Second, - Initial: 100, - Thereafter: 100, - }, - OutputPaths: []string{"stderr"}, - ErrorOutputPaths: []string{"stderr"}, - DisableCaller: false, - DisableStacktrace: false, - InitialFields: map[string]any(nil), - }, - Metrics: otelconftelemetry.MetricsConfig{ - Level: configtelemetry.LevelBasic, - }, - }, } } @@ -873,3 +729,59 @@ func TestValidateGraph(t *testing.T) { }) } } + +func TestRegisterProcessMetrics_UnsupportedOS_Warns(t *testing.T) { + mockRegister := func(_ component.TelemetrySettings, _ ...proctelemetry.RegisterOption) error { + t.Fatalf("should not be called on unsupported OS") + return nil + } + + core, logs := observer.New(zapcore.WarnLevel) + logger := zap.New(core) + + srv := &Service{ + telemetrySettings: component.TelemetrySettings{Logger: logger}, + } + + err := registerProcessMetrics(srv, "aix", mockRegister) + + require.NoError(t, err) + require.Equal(t, 1, logs.Len(), "Expected exactly one warning log") + entry := logs.All()[0] + require.Equal(t, "Process metrics are disabled on this operating system", entry.Message) + require.Equal(t, "aix", entry.ContextMap()["os"], "Log should contain the OS field") +} + +func TestRegisterProcessMetrics_SupportedOS_CallsRegister(t *testing.T) { + called := false + mockRegister := func(_ component.TelemetrySettings, _ ...proctelemetry.RegisterOption) error { + called = true + return nil + } + + srv := &Service{ + telemetrySettings: component.TelemetrySettings{Logger: zap.NewNop()}, + } + + err := registerProcessMetrics(srv, "linux", mockRegister) + + require.NoError(t, err) + require.True(t, called, "Registration function should be called on supported OS") +} + +func TestRegisterProcessMetrics_SupportedOS_RegisterFails_ReturnsError(t *testing.T) { + wantErr := errors.New("boom") + mockRegister := func(_ component.TelemetrySettings, _ ...proctelemetry.RegisterOption) error { + return wantErr + } + + srv := &Service{ + telemetrySettings: component.TelemetrySettings{Logger: zap.NewNop()}, + } + + err := registerProcessMetrics(srv, "linux", mockRegister) + + require.Error(t, err) + require.ErrorIs(t, err, wantErr) + require.Contains(t, err.Error(), "failed to register process metrics") +} diff --git a/service/telemetry/otelconftelemetry/config.go b/service/telemetry/otelconftelemetry/config.go index 0229e7c740cc..5b131538a750 100644 --- a/service/telemetry/otelconftelemetry/config.go +++ b/service/telemetry/otelconftelemetry/config.go @@ -7,7 +7,7 @@ import ( "errors" "go.opentelemetry.io/collector/config/configtelemetry" - "go.opentelemetry.io/collector/service/telemetry/internal/migration" + "go.opentelemetry.io/collector/service/telemetry/otelconftelemetry/internal/migration" ) // Config defines the configurable settings for service telemetry. diff --git a/service/telemetry/otelconftelemetry/factory.go b/service/telemetry/otelconftelemetry/factory.go index bffadf6be9da..04141ba51f3f 100644 --- a/service/telemetry/otelconftelemetry/factory.go +++ b/service/telemetry/otelconftelemetry/factory.go @@ -11,17 +11,10 @@ import ( "go.opentelemetry.io/collector/component" "go.opentelemetry.io/collector/config/configtelemetry" - "go.opentelemetry.io/collector/featuregate" + "go.opentelemetry.io/collector/service/internal/metadata" "go.opentelemetry.io/collector/service/telemetry" ) -var useLocalHostAsDefaultMetricsAddressFeatureGate = featuregate.GlobalRegistry().MustRegister( - "telemetry.UseLocalHostAsDefaultMetricsAddress", - featuregate.StageBeta, - featuregate.WithRegisterFromVersion("v0.111.0"), - featuregate.WithRegisterDescription("controls whether default Prometheus metrics server use localhost as the default host for their endpoints"), -) - // NewFactory creates a new telemetry.Factory that uses otelconf // to configure opentelemetry-go SDK telemetry providers. func NewFactory() telemetry.Factory { @@ -36,7 +29,7 @@ func NewFactory() telemetry.Factory { func createDefaultConfig() component.Config { metricsHost := "localhost" - if !useLocalHostAsDefaultMetricsAddressFeatureGate.IsEnabled() { + if !metadata.TelemetryUseLocalHostAsDefaultMetricsAddressFeatureGate.IsEnabled() { metricsHost = "" } @@ -51,11 +44,12 @@ func createDefaultConfig() component.Config { Initial: 10, Thereafter: 100, }, - OutputPaths: []string{"stderr"}, - ErrorOutputPaths: []string{"stderr"}, - DisableCaller: false, - DisableStacktrace: false, - InitialFields: map[string]any(nil), + OutputPaths: []string{"stderr"}, + ErrorOutputPaths: []string{"stderr"}, + DisableCaller: false, + DisableStacktrace: false, + InitialFields: map[string]any(nil), + DisableZapResource: false, }, Metrics: MetricsConfig{ Level: configtelemetry.LevelNormal, diff --git a/service/telemetry/otelconftelemetry/factory_test.go b/service/telemetry/otelconftelemetry/factory_test.go index 7c991df9ed74..c74e03b0efe6 100644 --- a/service/telemetry/otelconftelemetry/factory_test.go +++ b/service/telemetry/otelconftelemetry/factory_test.go @@ -11,6 +11,7 @@ import ( "github.com/stretchr/testify/require" "go.opentelemetry.io/collector/featuregate" + "go.opentelemetry.io/collector/service/internal/metadata" ) func TestDefaultConfig(t *testing.T) { @@ -30,11 +31,11 @@ func TestDefaultConfig(t *testing.T) { for _, tt := range tests { t.Run("UseLocalHostAsDefaultMetricsAddress/"+strconv.FormatBool(tt.gate), func(t *testing.T) { - prev := useLocalHostAsDefaultMetricsAddressFeatureGate.IsEnabled() - require.NoError(t, featuregate.GlobalRegistry().Set(useLocalHostAsDefaultMetricsAddressFeatureGate.ID(), tt.gate)) + prev := metadata.TelemetryUseLocalHostAsDefaultMetricsAddressFeatureGate.IsEnabled() + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.TelemetryUseLocalHostAsDefaultMetricsAddressFeatureGate.ID(), tt.gate)) defer func() { // Restore previous value. - require.NoError(t, featuregate.GlobalRegistry().Set(useLocalHostAsDefaultMetricsAddressFeatureGate.ID(), prev)) + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.TelemetryUseLocalHostAsDefaultMetricsAddressFeatureGate.ID(), prev)) }() cfg := NewFactory().CreateDefaultConfig() require.Len(t, cfg.(*Config).Metrics.Readers, 1) diff --git a/service/telemetry/internal/migration/normalize.go b/service/telemetry/otelconftelemetry/internal/migration/normalize.go similarity index 90% rename from service/telemetry/internal/migration/normalize.go rename to service/telemetry/otelconftelemetry/internal/migration/normalize.go index 1f7ff8dfa8de..fb7af03c6d93 100644 --- a/service/telemetry/internal/migration/normalize.go +++ b/service/telemetry/otelconftelemetry/internal/migration/normalize.go @@ -1,7 +1,7 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -package migration // import "go.opentelemetry.io/collector/service/telemetry/internal/migration" +package migration // import "go.opentelemetry.io/collector/service/telemetry/otelconftelemetry/internal/migration" import "strings" diff --git a/service/telemetry/internal/migration/testdata/v0.2.0_logs.yaml b/service/telemetry/otelconftelemetry/internal/migration/testdata/v0.2.0_logs.yaml similarity index 100% rename from service/telemetry/internal/migration/testdata/v0.2.0_logs.yaml rename to service/telemetry/otelconftelemetry/internal/migration/testdata/v0.2.0_logs.yaml diff --git a/service/telemetry/internal/migration/testdata/v0.2.0_metrics.yaml b/service/telemetry/otelconftelemetry/internal/migration/testdata/v0.2.0_metrics.yaml similarity index 100% rename from service/telemetry/internal/migration/testdata/v0.2.0_metrics.yaml rename to service/telemetry/otelconftelemetry/internal/migration/testdata/v0.2.0_metrics.yaml diff --git a/service/telemetry/internal/migration/testdata/v0.2.0_traces.yaml b/service/telemetry/otelconftelemetry/internal/migration/testdata/v0.2.0_traces.yaml similarity index 100% rename from service/telemetry/internal/migration/testdata/v0.2.0_traces.yaml rename to service/telemetry/otelconftelemetry/internal/migration/testdata/v0.2.0_traces.yaml diff --git a/service/telemetry/internal/migration/testdata/v0.3.0_logs.yaml b/service/telemetry/otelconftelemetry/internal/migration/testdata/v0.3.0_logs.yaml similarity index 100% rename from service/telemetry/internal/migration/testdata/v0.3.0_logs.yaml rename to service/telemetry/otelconftelemetry/internal/migration/testdata/v0.3.0_logs.yaml diff --git a/service/telemetry/internal/migration/testdata/v0.3.0_metrics.yaml b/service/telemetry/otelconftelemetry/internal/migration/testdata/v0.3.0_metrics.yaml similarity index 100% rename from service/telemetry/internal/migration/testdata/v0.3.0_metrics.yaml rename to service/telemetry/otelconftelemetry/internal/migration/testdata/v0.3.0_metrics.yaml diff --git a/service/telemetry/internal/migration/testdata/v0.3.0_traces.yaml b/service/telemetry/otelconftelemetry/internal/migration/testdata/v0.3.0_traces.yaml similarity index 100% rename from service/telemetry/internal/migration/testdata/v0.3.0_traces.yaml rename to service/telemetry/otelconftelemetry/internal/migration/testdata/v0.3.0_traces.yaml diff --git a/service/telemetry/internal/migration/v0.2.0.go b/service/telemetry/otelconftelemetry/internal/migration/v0.2.0.go similarity index 99% rename from service/telemetry/internal/migration/v0.2.0.go rename to service/telemetry/otelconftelemetry/internal/migration/v0.2.0.go index 094b37a357b3..06881cee8cdf 100644 --- a/service/telemetry/internal/migration/v0.2.0.go +++ b/service/telemetry/otelconftelemetry/internal/migration/v0.2.0.go @@ -1,7 +1,7 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -package migration // import "go.opentelemetry.io/collector/service/telemetry/internal/migration" +package migration // import "go.opentelemetry.io/collector/service/telemetry/otelconftelemetry/internal/migration" import ( configv02 "go.opentelemetry.io/contrib/otelconf/v0.2.0" diff --git a/service/telemetry/internal/migration/v0.2.0_test.go b/service/telemetry/otelconftelemetry/internal/migration/v0.2.0_test.go similarity index 100% rename from service/telemetry/internal/migration/v0.2.0_test.go rename to service/telemetry/otelconftelemetry/internal/migration/v0.2.0_test.go diff --git a/service/telemetry/internal/migration/v0.3.0.go b/service/telemetry/otelconftelemetry/internal/migration/v0.3.0.go similarity index 96% rename from service/telemetry/internal/migration/v0.3.0.go rename to service/telemetry/otelconftelemetry/internal/migration/v0.3.0.go index 6a1415cc753e..8d35fabe9b49 100644 --- a/service/telemetry/internal/migration/v0.3.0.go +++ b/service/telemetry/otelconftelemetry/internal/migration/v0.3.0.go @@ -1,7 +1,7 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -package migration // import "go.opentelemetry.io/collector/service/telemetry/internal/migration" +package migration // import "go.opentelemetry.io/collector/service/telemetry/otelconftelemetry/internal/migration" import ( "time" @@ -162,6 +162,9 @@ type LogsConfigV030 struct { // Processors allow configuration of log record processors to emit logs to // any number of supported backends. Processors []config.LogRecordProcessor `mapstructure:"processors,omitempty"` + + // DisableZapResource disables adding resource attributes to logs exported through Zap. This does not affect logs exported through OTLP. + DisableZapResource bool `mapstructure:"disable_zap_resource,omitempty"` } // LogsSamplingConfig sets a sampling strategy for the logger. Sampling caps the diff --git a/service/telemetry/internal/migration/v0.3.0_test.go b/service/telemetry/otelconftelemetry/internal/migration/v0.3.0_test.go similarity index 100% rename from service/telemetry/internal/migration/v0.3.0_test.go rename to service/telemetry/otelconftelemetry/internal/migration/v0.3.0_test.go diff --git a/service/telemetry/otelconftelemetry/logger.go b/service/telemetry/otelconftelemetry/logger.go index b53a6d16b9cd..f4b80c7fb2fd 100644 --- a/service/telemetry/otelconftelemetry/logger.go +++ b/service/telemetry/otelconftelemetry/logger.go @@ -28,7 +28,7 @@ func createLogger( // Copied from NewProductionConfig. ec := zap.NewProductionEncoderConfig() ec.EncodeTime = zapcore.ISO8601TimeEncoder - zapCfg := &zap.Config{ + zapCfg := zap.Config{ Level: zap.NewAtomicLevelAt(cfg.Logs.Level), Development: cfg.Logs.Development, Encoding: cfg.Logs.Encoding, @@ -45,7 +45,13 @@ func createLogger( zapCfg.EncoderConfig.EncodeTime = zapcore.ISO8601TimeEncoder } - logger, err := zapCfg.Build(set.ZapOptions...) + buildZapLogger := set.BuildZapLogger + if buildZapLogger == nil { + // For backwards compatibility, use zap.Config.Build + // if set.BuildZapLogger is not provided. + buildZapLogger = zap.Config.Build + } + logger, err := buildZapLogger(zapCfg, set.ZapOptions...) if err != nil { return nil, nil, err } @@ -57,7 +63,7 @@ func createLogger( // add them to the logger using With, because that would apply to all logs, // even ones exported through the core that wraps the LoggerProvider, // meaning that the attributes would be exported twice. - if res != nil && len(res.Attributes()) > 0 { + if !cfg.Logs.DisableZapResource && res != nil && len(res.Attributes()) > 0 { logger = logger.WithOptions(zap.WrapCore(func(c zapcore.Core) zapcore.Core { var fields []zap.Field for _, attr := range res.Attributes() { diff --git a/service/telemetry/otelconftelemetry/logger_test.go b/service/telemetry/otelconftelemetry/logger_test.go index 98697b53f0f2..d28dc3f7e212 100644 --- a/service/telemetry/otelconftelemetry/logger_test.go +++ b/service/telemetry/otelconftelemetry/logger_test.go @@ -9,7 +9,6 @@ import ( "errors" "io" "net/http" - "net/http/httptest" "strings" "testing" "time" @@ -18,7 +17,6 @@ import ( "github.com/stretchr/testify/require" config "go.opentelemetry.io/contrib/otelconf/v0.3.0" "go.opentelemetry.io/otel/attribute" - semconv "go.opentelemetry.io/otel/semconv/v1.18.0" "go.uber.org/zap" "go.uber.org/zap/zapcore" "go.uber.org/zap/zaptest/observer" @@ -129,6 +127,22 @@ func TestCreateLogger(t *testing.T) { }, }, }, + { + name: "log config with `disable_resource_attributes` enabled", + cfg: Config{ + Logs: LogsConfig{ + Level: zapcore.InfoLevel, + Development: false, + Encoding: "console", + OutputPaths: []string{"stderr"}, + ErrorOutputPaths: []string{"stderr"}, + DisableCaller: false, + DisableStacktrace: false, + InitialFields: map[string]any(nil), + DisableZapResource: true, + }, + }, + }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { @@ -137,9 +151,12 @@ func TestCreateLogger(t *testing.T) { resource, err := factory.CreateResource(context.Background(), telemetry.Settings{BuildInfo: buildInfo}, &tt.cfg) require.NoError(t, err) - _, provider, err := factory.CreateLogger(context.Background(), telemetry.LoggerSettings{ - Settings: telemetry.Settings{BuildInfo: buildInfo, Resource: &resource}, - }, &tt.cfg) + _, provider, err := factory.CreateLogger( + context.Background(), telemetry.LoggerSettings{ + Settings: telemetry.Settings{BuildInfo: buildInfo, Resource: &resource}, + BuildZapLogger: zap.Config.Build, + }, &tt.cfg, + ) if tt.wantErr != nil { require.ErrorContains(t, err, tt.wantErr.Error()) } else { @@ -156,6 +173,7 @@ func TestCreateLoggerWithResource(t *testing.T) { buildInfo component.BuildInfo resourceConfig map[string]*string wantFields map[string]string + setConfig func(cfg *Config) }{ { name: "auto-populated fields only", @@ -165,9 +183,9 @@ func TestCreateLoggerWithResource(t *testing.T) { }, resourceConfig: map[string]*string{}, wantFields: map[string]string{ - string(semconv.ServiceNameKey): "mycommand", - string(semconv.ServiceVersionKey): "1.0.0", - string(semconv.ServiceInstanceIDKey): "", + "service.name": "mycommand", + "service.version": "1.0.0", + "service.instance.id": "", }, }, { @@ -177,12 +195,12 @@ func TestCreateLoggerWithResource(t *testing.T) { Version: "1.0.0", }, resourceConfig: map[string]*string{ - string(semconv.ServiceNameKey): ptr("custom-service"), + "service.name": ptr("custom-service"), }, wantFields: map[string]string{ - string(semconv.ServiceNameKey): "custom-service", - string(semconv.ServiceVersionKey): "1.0.0", - string(semconv.ServiceInstanceIDKey): "", + "service.name": "custom-service", + "service.version": "1.0.0", + "service.instance.id": "", }, }, { @@ -192,12 +210,12 @@ func TestCreateLoggerWithResource(t *testing.T) { Version: "1.0.0", }, resourceConfig: map[string]*string{ - string(semconv.ServiceVersionKey): ptr("2.0.0"), + "service.version": ptr("2.0.0"), }, wantFields: map[string]string{ - string(semconv.ServiceNameKey): "mycommand", - string(semconv.ServiceVersionKey): "2.0.0", - string(semconv.ServiceInstanceIDKey): "", + "service.name": "mycommand", + "service.version": "2.0.0", + "service.instance.id": "", }, }, { @@ -210,10 +228,10 @@ func TestCreateLoggerWithResource(t *testing.T) { "custom.field": ptr("custom-value"), }, wantFields: map[string]string{ - string(semconv.ServiceNameKey): "mycommand", - string(semconv.ServiceVersionKey): "1.0.0", - string(semconv.ServiceInstanceIDKey): "", // Just check presence - "custom.field": "custom-value", + "service.name": "mycommand", + "service.version": "1.0.0", + "service.instance.id": "", // Just check presence + "custom.field": "custom-value", }, }, { @@ -222,7 +240,19 @@ func TestCreateLoggerWithResource(t *testing.T) { resourceConfig: nil, wantFields: map[string]string{ // A random UUID is injected for service.instance.id by default - string(semconv.ServiceInstanceIDKey): "", // Just check presence + "service.instance.id": "", // Just check presence + }, + }, + { + name: "validate `DisableResourceAttributes=true` shouldn't add resource fields", + buildInfo: component.BuildInfo{ + Command: "mycommand", + Version: "1.0.0", + }, + resourceConfig: map[string]*string{}, + wantFields: map[string]string{}, + setConfig: func(cfg *Config) { + cfg.Logs.DisableZapResource = true }, }, } @@ -230,6 +260,7 @@ func TestCreateLoggerWithResource(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { core, observedLogs := observer.New(zapcore.DebugLevel) + cfg := &Config{ Logs: LogsConfig{ Level: zapcore.InfoLevel, @@ -237,15 +268,18 @@ func TestCreateLoggerWithResource(t *testing.T) { }, Resource: tt.resourceConfig, } + if tt.setConfig != nil { + tt.setConfig(cfg) + } resource, err := createResource(t.Context(), telemetry.Settings{BuildInfo: tt.buildInfo}, cfg) require.NoError(t, err) set := telemetry.LoggerSettings{ Settings: telemetry.Settings{BuildInfo: tt.buildInfo, Resource: &resource}, - ZapOptions: []zap.Option{ + BuildZapLogger: func(zap.Config, ...zap.Option) (*zap.Logger, error) { // Redirect logs to the observer core - zap.WrapCore(func(zapcore.Core) zapcore.Core { return core }), + return zap.New(core), nil }, } @@ -259,7 +293,8 @@ func TestCreateLoggerWithResource(t *testing.T) { require.Len(t, observedLogs.All(), 1) entry := observedLogs.All()[0] - if tt.wantFields == nil { + // treat empty map as "no expected fields" + if len(tt.wantFields) == 0 { assert.Empty(t, entry.Context) return } @@ -271,7 +306,7 @@ func TestCreateLoggerWithResource(t *testing.T) { // Verify all expected fields for k, v := range tt.wantFields { - if k == string(semconv.ServiceInstanceIDKey) { + if k == "service.instance.id" { // For service.instance.id just verify it exists since it's auto-generated assert.Contains(t, enc.Fields, k) } else { @@ -282,6 +317,47 @@ func TestCreateLoggerWithResource(t *testing.T) { } } +func TestCreateLoggerZapOptions(t *testing.T) { + buildInfo := component.BuildInfo{} + factory := NewFactory() + cfg := &Config{ + Logs: LogsConfig{ + Level: zapcore.InfoLevel, + Encoding: "json", + }, + } + resource, err := factory.CreateResource( + context.Background(), telemetry.Settings{BuildInfo: buildInfo}, cfg, + ) + require.NoError(t, err) + + core, observedLogs := observer.New(zapcore.DebugLevel) + set := telemetry.LoggerSettings{ + Settings: telemetry.Settings{BuildInfo: buildInfo, Resource: &resource}, + + // Test deprecated behavior: no BuildZapLogger, but ZapOptions provided. + BuildZapLogger: nil, + ZapOptions: []zap.Option{ + zap.WrapCore(func(zapcore.Core) zapcore.Core { return core }), + }, + } + + logger, provider, err := factory.CreateLogger(context.Background(), set, cfg) + require.NoError(t, err) + require.NotNil(t, provider) + defer func() { + assert.NoError(t, provider.Shutdown(context.Background())) + }() + + testMessage := "Test deprecated zap options" + logger.Info(testMessage) + + require.Len(t, observedLogs.All(), 1) + logEntry := observedLogs.All()[0] + assert.Equal(t, testMessage, logEntry.Message) + assert.Equal(t, zapcore.InfoLevel, logEntry.Level) +} + func TestLogger_OTLP(t *testing.T) { // Create a backend to receive the logs and assert the content receivedLogs := 0 @@ -290,16 +366,16 @@ func TestLogger_OTLP(t *testing.T) { rl := logs.ResourceLogs().At(0) resourceAttrs := rl.Resource().Attributes().AsRaw() - assert.Equal(t, service, resourceAttrs[string(semconv.ServiceNameKey)]) - assert.Equal(t, version, resourceAttrs[string(semconv.ServiceVersionKey)]) + assert.Equal(t, service, resourceAttrs["service.name"]) + assert.Equal(t, version, resourceAttrs["service.version"]) assert.Equal(t, testValue, resourceAttrs[testAttribute]) // Check that the resource attributes are not duplicated in the log records sl := rl.ScopeLogs().At(0) logRecord := sl.LogRecords().At(0) attrs := logRecord.Attributes().AsRaw() - assert.NotContains(t, attrs, string(semconv.ServiceNameKey)) - assert.NotContains(t, attrs, string(semconv.ServiceVersionKey)) + assert.NotContains(t, attrs, "service.name") + assert.NotContains(t, attrs, "service.version") assert.NotContains(t, attrs, testAttribute) receivedLogs++ @@ -315,16 +391,26 @@ func TestLogger_OTLP(t *testing.T) { } func newOTLPLogger(t *testing.T, level zapcore.Level, handler func(plogotlp.ExportRequest)) *zap.Logger { - srv := createLogsBackend(t, "/v1/logs", handler) - t.Cleanup(srv.Close) + srv, certFile := newTLSBackend(t, http.HandlerFunc(func(_ http.ResponseWriter, request *http.Request) { + body, err := io.ReadAll(request.Body) + assert.NoError(t, err) + defer request.Body.Close() + + // Unmarshal the protobuf body into logs + req := plogotlp.NewExportRequest() + err = req.UnmarshalProto(body) + assert.NoError(t, err) + + handler(req) + })) processors := []config.LogRecordProcessor{{ Simple: &config.SimpleLogRecordProcessor{ Exporter: config.LogRecordExporter{ OTLP: &config.OTLP{ - Endpoint: ptr(srv.URL), - Protocol: ptr("http/protobuf"), - Insecure: ptr(true), + Endpoint: ptr(srv.URL), + Protocol: ptr("http/protobuf"), + Certificate: ptr(certFile), }, }, }, @@ -339,9 +425,9 @@ func newOTLPLogger(t *testing.T, level zapcore.Level, handler func(plogotlp.Expo // written to the OTLP processor }, Resource: map[string]*string{ - string(semconv.ServiceNameKey): ptr(service), - string(semconv.ServiceVersionKey): ptr(version), - testAttribute: ptr(testValue), + "service.name": ptr(service), + "service.version": ptr(version), + testAttribute: ptr(testValue), }, } @@ -349,7 +435,8 @@ func newOTLPLogger(t *testing.T, level zapcore.Level, handler func(plogotlp.Expo require.NoError(t, err) logger, shutdown, err := createLogger(t.Context(), telemetry.LoggerSettings{ - Settings: telemetry.Settings{Resource: &resource}, + Settings: telemetry.Settings{Resource: &resource}, + BuildZapLogger: zap.Config.Build, }, cfg) require.NoError(t, err) t.Cleanup(func() { @@ -358,31 +445,21 @@ func newOTLPLogger(t *testing.T, level zapcore.Level, handler func(plogotlp.Expo return logger } -func createLogsBackend(t *testing.T, endpoint string, handler func(plogotlp.ExportRequest)) *httptest.Server { - mux := http.NewServeMux() - mux.HandleFunc(endpoint, func(_ http.ResponseWriter, request *http.Request) { +func TestLogAttributeInjection(t *testing.T) { + core, consoleLogs := observer.New(zapcore.DebugLevel) + + var otlpLogs []plogotlp.ExportRequest + srv, certFile := newTLSBackend(t, http.HandlerFunc(func(_ http.ResponseWriter, request *http.Request) { body, err := io.ReadAll(request.Body) assert.NoError(t, err) defer request.Body.Close() - // Unmarshal the protobuf body into logs req := plogotlp.NewExportRequest() err = req.UnmarshalProto(body) assert.NoError(t, err) - handler(req) - }) - return httptest.NewServer(mux) -} - -func TestLogAttributeInjection(t *testing.T) { - core, consoleLogs := observer.New(zapcore.DebugLevel) - - var otlpLogs []plogotlp.ExportRequest - srv := createLogsBackend(t, "/v1/logs", func(req plogotlp.ExportRequest) { otlpLogs = append(otlpLogs, req) - }) - t.Cleanup(srv.Close) + })) cfg := &Config{ Resource: map[string]*string{ @@ -397,9 +474,9 @@ func TestLogAttributeInjection(t *testing.T) { Exporter: config.LogRecordExporter{ OTLP: &config.OTLP{ // Send OTLP logs to the mock backend - Endpoint: ptr(srv.URL), - Protocol: ptr("http/protobuf"), - Insecure: ptr(true), + Endpoint: ptr(srv.URL), + Protocol: ptr("http/protobuf"), + Certificate: ptr(certFile), }, }, }, @@ -412,9 +489,9 @@ func TestLogAttributeInjection(t *testing.T) { set := telemetry.LoggerSettings{ Settings: telemetry.Settings{Resource: &resource}, - ZapOptions: []zap.Option{ + BuildZapLogger: func(zap.Config, ...zap.Option) (*zap.Logger, error) { // Redirect console logs to the observer core - zap.WrapCore(func(zapcore.Core) zapcore.Core { return core }), + return zap.New(core), nil }, } diff --git a/service/telemetry/otelconftelemetry/metrics_test.go b/service/telemetry/otelconftelemetry/metrics_test.go index 4c3ed5fb9e55..4da99fb21ba5 100644 --- a/service/telemetry/otelconftelemetry/metrics_test.go +++ b/service/telemetry/otelconftelemetry/metrics_test.go @@ -8,7 +8,6 @@ import ( "fmt" "io" "net/http" - "net/http/httptest" "testing" "time" @@ -20,7 +19,6 @@ import ( config "go.opentelemetry.io/contrib/otelconf/v0.3.0" "go.opentelemetry.io/otel/attribute" "go.opentelemetry.io/otel/metric" - semconv "go.opentelemetry.io/otel/semconv/v1.26.0" "go.uber.org/zap" "go.uber.org/zap/zapcore" "go.uber.org/zap/zaptest/observer" @@ -113,9 +111,9 @@ func TestCreateMeterProvider(t *testing.T) { }, } cfg.Resource = map[string]*string{ - string(semconv.ServiceNameKey): ptr("otelcol"), - string(semconv.ServiceVersionKey): ptr("latest"), - string(semconv.ServiceInstanceIDKey): ptr(testInstanceID), + "service.name": ptr("otelcol"), + "service.version": ptr("latest"), + "service.instance.id": ptr(testInstanceID), } t.Run(tt.name, func(t *testing.T) { @@ -164,13 +162,13 @@ func createTestMetrics(t *testing.T, mp metric.MeterProvider) { grpcExampleCounter, err := mp.Meter("go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc").Int64Counter(metricPrefix + grpcPrefix + counterName) require.NoError(t, err) grpcExampleCounter.Add(context.Background(), 11, metric.WithAttributeSet(attribute.NewSet( - attribute.String(string(semconv.RPCSystemKey), "grpc"), + attribute.String("rpc.system", "grpc"), ))) httpExampleCounter, err := mp.Meter("go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp").Int64Counter(metricPrefix + httpPrefix + counterName) require.NoError(t, err) httpExampleCounter.Add(context.Background(), 10, metric.WithAttributeSet(attribute.NewSet( - attribute.String(string(semconv.HTTPRequestMethodKey), "GET"), + attribute.String("http.request.method", "GET"), ))) } @@ -357,7 +355,7 @@ func TestTelemetryMetrics_DefaultViews(t *testing.T) { } { t.Run(name, func(t *testing.T) { var metrics pmetric.Metrics - srv := httptest.NewServer(http.HandlerFunc(func(_ http.ResponseWriter, req *http.Request) { + srv, certFile := newTLSBackend(t, http.HandlerFunc(func(_ http.ResponseWriter, req *http.Request) { body, err := io.ReadAll(req.Body) assert.NoError(t, err) @@ -365,7 +363,6 @@ func TestTelemetryMetrics_DefaultViews(t *testing.T) { assert.NoError(t, exportRequest.UnmarshalProto(body)) metrics = exportRequest.Metrics() })) - defer srv.Close() cfg := createDefaultConfig().(*Config) cfg.Metrics.Level = configtelemetry.LevelDetailed @@ -374,9 +371,9 @@ func TestTelemetryMetrics_DefaultViews(t *testing.T) { Periodic: &config.PeriodicMetricReader{ Exporter: config.PushMetricExporter{ OTLP: &config.OTLPMetric{ - Endpoint: ptr(srv.URL), - Protocol: ptr("http/protobuf"), - Insecure: ptr(true), + Endpoint: ptr(srv.URL), + Protocol: ptr("http/protobuf"), + Certificate: ptr(certFile), }, }, }, diff --git a/service/telemetry/otelconftelemetry/sdk.go b/service/telemetry/otelconftelemetry/sdk.go index 7b4456ab3117..94c0cb9d3581 100644 --- a/service/telemetry/otelconftelemetry/sdk.go +++ b/service/telemetry/otelconftelemetry/sdk.go @@ -8,7 +8,7 @@ import ( config "go.opentelemetry.io/contrib/otelconf/v0.3.0" sdkresource "go.opentelemetry.io/otel/sdk/resource" - semconv "go.opentelemetry.io/otel/semconv/v1.26.0" + semconv "go.opentelemetry.io/otel/semconv/v1.38.0" ) func newSDK(ctx context.Context, res *sdkresource.Resource, conf config.OpenTelemetryConfiguration) (config.SDK, error) { diff --git a/service/telemetry/otelconftelemetry/testserver_test.go b/service/telemetry/otelconftelemetry/testserver_test.go new file mode 100644 index 000000000000..38b4b84bb4bf --- /dev/null +++ b/service/telemetry/otelconftelemetry/testserver_test.go @@ -0,0 +1,30 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +package otelconftelemetry + +import ( + "encoding/pem" + "net/http" + "net/http/httptest" + "os" + "path/filepath" + "testing" + + "github.com/stretchr/testify/require" +) + +func newTLSBackend(t *testing.T, handler http.Handler) (*httptest.Server, string) { + t.Helper() + + srv := httptest.NewTLSServer(handler) + t.Cleanup(srv.Close) + + certFile := filepath.Join(t.TempDir(), "server-cert.pem") + require.NoError(t, os.WriteFile(certFile, pem.EncodeToMemory(&pem.Block{ + Type: "CERTIFICATE", + Bytes: srv.Certificate().Raw, + }), 0o600)) + + return srv, certFile +} diff --git a/service/telemetry/otelconftelemetry/tracer.go b/service/telemetry/otelconftelemetry/tracer.go index f4f84ebf7136..dd90bacf84e7 100644 --- a/service/telemetry/otelconftelemetry/tracer.go +++ b/service/telemetry/otelconftelemetry/tracer.go @@ -19,16 +19,9 @@ import ( "go.opentelemetry.io/collector/component" "go.opentelemetry.io/collector/config/configtelemetry" - "go.opentelemetry.io/collector/featuregate" "go.opentelemetry.io/collector/service/telemetry" ) -var _ = featuregate.GlobalRegistry().MustRegister("service.noopTracerProvider", - featuregate.StageDeprecated, - featuregate.WithRegisterFromVersion("v0.107.0"), - featuregate.WithRegisterToVersion("v0.109.0"), - featuregate.WithRegisterDescription("Sets a Noop OpenTelemetry TracerProvider to reduce memory allocations. This featuregate is incompatible with the zPages extension.")) - const ( // supported trace propagators traceContextPropagator = "tracecontext" diff --git a/service/telemetry/otelconftelemetry/tracer_test.go b/service/telemetry/otelconftelemetry/tracer_test.go index 490f71242bb5..d67097b2a46b 100644 --- a/service/telemetry/otelconftelemetry/tracer_test.go +++ b/service/telemetry/otelconftelemetry/tracer_test.go @@ -37,12 +37,11 @@ func TestCreateTracerProvider(t *testing.T) { assert.NoError(t, exportRequest.UnmarshalProto(body)) received = append(received, exportRequest.Traces()) }) - srv := httptest.NewServer(mux) - defer srv.Close() + srv, certFile := newTLSBackend(t, mux) cfg := createDefaultConfig().(*Config) cfg.Traces.Propagators = []string{"b3", "tracecontext"} - cfg.Traces.Processors = []config.SpanProcessor{newOTLPSimpleSpanProcessor(srv)} + cfg.Traces.Processors = []config.SpanProcessor{newOTLPSimpleSpanProcessor(srv, certFile)} resource, err := createResource(t.Context(), telemetry.Settings{ BuildInfo: component.BuildInfo{Command: "otelcol", Version: "latest"}, @@ -93,12 +92,11 @@ func TestCreateTracerProvider_Invalid(t *testing.T) { func TestCreateTracerProvider_Propagators(t *testing.T) { mux := http.NewServeMux() mux.HandleFunc("/v1/traces", func(http.ResponseWriter, *http.Request) {}) - srv := httptest.NewServer(mux) - defer srv.Close() + srv, certFile := newTLSBackend(t, mux) cfg := createDefaultConfig().(*Config) cfg.Traces.Propagators = []string{"b3", "tracecontext"} - cfg.Traces.Processors = []config.SpanProcessor{newOTLPSimpleSpanProcessor(srv)} + cfg.Traces.Processors = []config.SpanProcessor{newOTLPSimpleSpanProcessor(srv, certFile)} resource, err := createResource(t.Context(), telemetry.Settings{ BuildInfo: component.BuildInfo{Command: "otelcol", Version: "latest"}, @@ -148,12 +146,11 @@ func TestCreateTracerProvider_Disabled(t *testing.T) { mux.HandleFunc("/v1/traces", func(http.ResponseWriter, *http.Request) { received++ }) - srv := httptest.NewServer(mux) - defer srv.Close() + srv, certFile := newTLSBackend(t, mux) cfg := createDefaultConfig().(*Config) cfg.Traces.Level = configtelemetry.LevelNone - cfg.Traces.Processors = []config.SpanProcessor{newOTLPSimpleSpanProcessor(srv)} + cfg.Traces.Processors = []config.SpanProcessor{newOTLPSimpleSpanProcessor(srv, certFile)} core, observedLogs := observer.New(zapcore.DebugLevel) @@ -185,14 +182,14 @@ func TestCreateTracerProvider_Disabled(t *testing.T) { assert.Equal(t, 0, received) } -func newOTLPSimpleSpanProcessor(srv *httptest.Server) config.SpanProcessor { +func newOTLPSimpleSpanProcessor(srv *httptest.Server, certFile string) config.SpanProcessor { return config.SpanProcessor{ Simple: &config.SimpleSpanProcessor{ Exporter: config.SpanExporter{ OTLP: &config.OTLP{ - Endpoint: ptr(srv.URL), - Protocol: ptr("http/protobuf"), - Insecure: ptr(true), + Endpoint: ptr(srv.URL), + Protocol: ptr("http/protobuf"), + Certificate: ptr(certFile), }, }, }, diff --git a/service/telemetry/telemetry.go b/service/telemetry/telemetry.go index b8328dfb5375..fcc0d6cf0cb4 100644 --- a/service/telemetry/telemetry.go +++ b/service/telemetry/telemetry.go @@ -23,7 +23,18 @@ type LoggerSettings struct { Settings // ZapOptions contains options for creating the zap logger. + // + // Deprecated [v0.142.0]: use BuildZapLogger instead. + // This field will be removed in the future, and options + // must be injected through BuildZapLogger. ZapOptions []zap.Option + + // BuildZapLogger holds a function for building a *zap.Logger + // from a zap.Config and options. + // + // If BuildZapLogger is nil, zap.Config.Build should be used. + // NOTE: in the future this field will be required. + BuildZapLogger func(zap.Config, ...zap.Option) (*zap.Logger, error) } // MeterSettings holds settings for building meter providers. diff --git a/service/telemetry/telemetrytest/go.mod b/service/telemetry/telemetrytest/go.mod index 6fba2f123eb6..94224ac0477a 100644 --- a/service/telemetry/telemetrytest/go.mod +++ b/service/telemetry/telemetrytest/go.mod @@ -1,14 +1,14 @@ module go.opentelemetry.io/collector/service/telemetry/telemetrytest -go 1.24.0 +go 1.25.0 require ( github.com/stretchr/testify v1.11.1 - go.opentelemetry.io/collector/component v1.46.0 - go.opentelemetry.io/collector/pdata v1.46.0 + go.opentelemetry.io/collector/component v1.54.0 + go.opentelemetry.io/collector/pdata v1.54.0 go.opentelemetry.io/collector/service v0.140.0 - go.opentelemetry.io/otel/metric v1.40.0 - go.opentelemetry.io/otel/trace v1.40.0 + go.opentelemetry.io/otel/metric v1.42.0 + go.opentelemetry.io/otel/trace v1.42.0 go.uber.org/zap v1.27.1 ) @@ -16,54 +16,53 @@ require ( github.com/beorn7/perks v1.0.1 // indirect github.com/cenkalti/backoff/v5 v5.0.3 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect - github.com/davecgh/go-spew v1.1.1 // indirect + github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect github.com/go-logr/logr v1.4.3 // indirect github.com/go-logr/stdr v1.2.2 // indirect github.com/google/uuid v1.6.0 // indirect - github.com/grafana/regexp v0.0.0-20240518133315-a468a5bfb3bc // indirect - github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.2 // indirect - github.com/hashicorp/go-version v1.7.0 // indirect + github.com/grpc-ecosystem/grpc-gateway/v2 v2.28.0 // indirect + github.com/hashicorp/go-version v1.8.0 // indirect github.com/json-iterator/go v1.1.12 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee // indirect github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect - github.com/pmezard/go-difflib v1.0.0 // indirect + github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect github.com/prometheus/client_golang v1.23.2 // indirect github.com/prometheus/client_model v0.6.2 // indirect - github.com/prometheus/common v0.67.1 // indirect - github.com/prometheus/otlptranslator v0.0.2 // indirect - github.com/prometheus/procfs v0.17.0 // indirect + github.com/prometheus/common v0.67.5 // indirect + github.com/prometheus/otlptranslator v1.0.0 // indirect + github.com/prometheus/procfs v0.20.1 // indirect go.opentelemetry.io/auto/sdk v1.2.1 // indirect go.opentelemetry.io/collector/config/configtelemetry v0.140.0 // indirect - go.opentelemetry.io/collector/featuregate v1.46.0 // indirect + go.opentelemetry.io/collector/featuregate v1.54.0 // indirect go.opentelemetry.io/contrib/otelconf v0.18.0 // indirect - go.opentelemetry.io/otel v1.40.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.14.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.14.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.38.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.38.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.38.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.38.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.38.0 // indirect - go.opentelemetry.io/otel/exporters/prometheus v0.60.0 // indirect - go.opentelemetry.io/otel/exporters/stdout/stdoutlog v0.14.0 // indirect - go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.38.0 // indirect - go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.38.0 // indirect - go.opentelemetry.io/otel/log v0.14.0 // indirect - go.opentelemetry.io/otel/sdk v1.40.0 // indirect - go.opentelemetry.io/otel/sdk/log v0.14.0 // indirect - go.opentelemetry.io/otel/sdk/metric v1.40.0 // indirect - go.opentelemetry.io/proto/otlp v1.7.1 // indirect + go.opentelemetry.io/otel v1.42.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.18.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.18.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.42.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.42.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.42.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.42.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.42.0 // indirect + go.opentelemetry.io/otel/exporters/prometheus v0.64.0 // indirect + go.opentelemetry.io/otel/exporters/stdout/stdoutlog v0.18.0 // indirect + go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.42.0 // indirect + go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.42.0 // indirect + go.opentelemetry.io/otel/log v0.18.0 // indirect + go.opentelemetry.io/otel/sdk v1.42.0 // indirect + go.opentelemetry.io/otel/sdk/log v0.18.0 // indirect + go.opentelemetry.io/otel/sdk/metric v1.42.0 // indirect + go.opentelemetry.io/proto/otlp v1.10.0 // indirect go.uber.org/multierr v1.11.0 // indirect go.yaml.in/yaml/v2 v2.4.3 // indirect go.yaml.in/yaml/v3 v3.0.4 // indirect - golang.org/x/net v0.47.0 // indirect - golang.org/x/sys v0.40.0 // indirect - golang.org/x/text v0.31.0 // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20251022142026-3a174f9686a8 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20251022142026-3a174f9686a8 // indirect - google.golang.org/grpc v1.77.0 // indirect - google.golang.org/protobuf v1.36.10 // indirect + golang.org/x/net v0.51.0 // indirect + golang.org/x/sys v0.41.0 // indirect + golang.org/x/text v0.34.0 // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20260226221140-a57be14db171 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20260226221140-a57be14db171 // indirect + google.golang.org/grpc v1.79.3 // indirect + google.golang.org/protobuf v1.36.11 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) @@ -176,3 +175,7 @@ replace go.opentelemetry.io/collector/component/componenttest => ../../../compon replace go.opentelemetry.io/collector/component/componentstatus => ../../../component/componentstatus replace go.opentelemetry.io/collector/internal/testutil => ../../../internal/testutil + +replace go.opentelemetry.io/collector/internal/componentalias => ../../../internal/componentalias + +replace go.opentelemetry.io/collector/config/confignet => ../../../config/confignet diff --git a/service/telemetry/telemetrytest/go.sum b/service/telemetry/telemetrytest/go.sum index 78f30e160ef5..a38dc3bd93d9 100644 --- a/service/telemetry/telemetrytest/go.sum +++ b/service/telemetry/telemetrytest/go.sum @@ -5,8 +5,9 @@ github.com/cenkalti/backoff/v5 v5.0.3/go.mod h1:rkhZdG3JZukswDf7f0cwqPNk4K0sa+F9 github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= +github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI= github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= @@ -19,16 +20,14 @@ github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/grafana/regexp v0.0.0-20240518133315-a468a5bfb3bc h1:GN2Lv3MGO7AS6PrRoT6yV5+wkrOpcszoIsO4+4ds248= -github.com/grafana/regexp v0.0.0-20240518133315-a468a5bfb3bc/go.mod h1:+JKpmjMGhpgPL+rXZ5nsZieVzvarn86asRlBg4uNGnk= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.2 h1:8Tjv8EJ+pM1xP8mK6egEbD1OgnVTyacbefKhmbLhIhU= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.2/go.mod h1:pkJQ2tZHJ0aFOVEEot6oZmaVEZcRme73eIFmhiVuRWs= -github.com/hashicorp/go-version v1.7.0 h1:5tqGy27NaOTB8yJKUZELlFAS/LTKJkrmONwQKeRZfjY= -github.com/hashicorp/go-version v1.7.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.28.0 h1:HWRh5R2+9EifMyIHV7ZV+MIZqgz+PMpZ14Jynv3O2Zs= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.28.0/go.mod h1:JfhWUomR1baixubs02l85lZYYOm7LV6om4ceouMv45c= +github.com/hashicorp/go-version v1.8.0 h1:KAkNb1HAiZd1ukkxDFGmokVZe1Xy9HG6NUp+bPle2i4= +github.com/hashicorp/go-version v1.8.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= -github.com/klauspost/compress v1.18.1 h1:bcSGx7UbpBqMChDtsF28Lw6v/G94LPrrbMbdC3JH2co= -github.com/klauspost/compress v1.18.1/go.mod h1:ZQFFVG+MdnR0P+l6wpXgIL4NTtwiKIdBnrBd8Nrxr+0= +github.com/klauspost/compress v1.18.4 h1:RPhnKRAQ4Fh8zU2FY/6ZFDwTVTxgJ/EMydqSTzE9a2c= +github.com/klauspost/compress v1.18.4/go.mod h1:R0h/fSBs8DE4ENlcrlib3PsXS61voFxhIs2DeRhCvJ4= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= @@ -43,18 +42,19 @@ github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee h1:W5t00kpgFd github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= -github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= +github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/prometheus/client_golang v1.23.2 h1:Je96obch5RDVy3FDMndoUsjAhG5Edi49h0RJWRi/o0o= github.com/prometheus/client_golang v1.23.2/go.mod h1:Tb1a6LWHB3/SPIzCoaDXI4I8UHKeFTEQ1YCr+0Gyqmg= github.com/prometheus/client_model v0.6.2 h1:oBsgwpGs7iVziMvrGhE53c/GrLUsZdHnqNwqPLxwZyk= github.com/prometheus/client_model v0.6.2/go.mod h1:y3m2F6Gdpfy6Ut/GBsUqTWZqCUvMVzSfMLjcu6wAwpE= -github.com/prometheus/common v0.67.1 h1:OTSON1P4DNxzTg4hmKCc37o4ZAZDv0cfXLkOt0oEowI= -github.com/prometheus/common v0.67.1/go.mod h1:RpmT9v35q2Y+lsieQsdOh5sXZ6ajUGC8NjZAmr8vb0Q= -github.com/prometheus/otlptranslator v0.0.2 h1:+1CdeLVrRQ6Psmhnobldo0kTp96Rj80DRXRd5OSnMEQ= -github.com/prometheus/otlptranslator v0.0.2/go.mod h1:P8AwMgdD7XEr6QRUJ2QWLpiAZTgTE2UYgjlu3svompI= -github.com/prometheus/procfs v0.17.0 h1:FuLQ+05u4ZI+SS/w9+BWEM2TXiHKsUQ9TADiRH7DuK0= -github.com/prometheus/procfs v0.17.0/go.mod h1:oPQLaDAMRbA+u8H5Pbfq+dl3VDAvHxMUOVhe0wYB2zw= +github.com/prometheus/common v0.67.5 h1:pIgK94WWlQt1WLwAC5j2ynLaBRDiinoAb86HZHTUGI4= +github.com/prometheus/common v0.67.5/go.mod h1:SjE/0MzDEEAyrdr5Gqc6G+sXI67maCxzaT3A2+HqjUw= +github.com/prometheus/otlptranslator v1.0.0 h1:s0LJW/iN9dkIH+EnhiD3BlkkP5QVIUVEoIwkU+A6qos= +github.com/prometheus/otlptranslator v1.0.0/go.mod h1:vRYWnXvI6aWGpsdY/mOT/cbeVRBlPWtBNDb7kGR3uKM= +github.com/prometheus/procfs v0.20.1 h1:XwbrGOIplXW/AU3YhIhLODXMJYyC1isLFfYCsTEycfc= +github.com/prometheus/procfs v0.20.1/go.mod h1:o9EMBZGRyvDrSPH1RqdxhojkuXstoe4UlK79eF5TGGo= github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ= github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= @@ -65,52 +65,52 @@ go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y= go.opentelemetry.io/contrib/otelconf v0.18.0 h1:ciF2Gf00BWs0DnexKFZXcxg9kJ8r3SUW1LOzW3CsKA8= go.opentelemetry.io/contrib/otelconf v0.18.0/go.mod h1:FcP7k+JLwBLdOxS6qY6VQ/4b5VBntI6L6o80IMwhAeI= -go.opentelemetry.io/otel v1.40.0 h1:oA5YeOcpRTXq6NN7frwmwFR0Cn3RhTVZvXsP4duvCms= -go.opentelemetry.io/otel v1.40.0/go.mod h1:IMb+uXZUKkMXdPddhwAHm6UfOwJyh4ct1ybIlV14J0g= -go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.14.0 h1:OMqPldHt79PqWKOMYIAQs3CxAi7RLgPxwfFSwr4ZxtM= -go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.14.0/go.mod h1:1biG4qiqTxKiUCtoWDPpL3fB3KxVwCiGw81j3nKMuHE= -go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.14.0 h1:QQqYw3lkrzwVsoEX0w//EhH/TCnpRdEenKBOOEIMjWc= -go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.14.0/go.mod h1:gSVQcr17jk2ig4jqJ2DX30IdWH251JcNAecvrqTxH1s= -go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.38.0 h1:vl9obrcoWVKp/lwl8tRE33853I8Xru9HFbw/skNeLs8= -go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.38.0/go.mod h1:GAXRxmLJcVM3u22IjTg74zWBrRCKq8BnOqUVLodpcpw= -go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.38.0 h1:Oe2z/BCg5q7k4iXC3cqJxKYg0ieRiOqF0cecFYdPTwk= -go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.38.0/go.mod h1:ZQM5lAJpOsKnYagGg/zV2krVqTtaVdYdDkhMoX6Oalg= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.38.0 h1:GqRJVj7UmLjCVyVJ3ZFLdPRmhDUp2zFmQe3RHIOsw24= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.38.0/go.mod h1:ri3aaHSmCTVYu2AWv44YMauwAQc0aqI9gHKIcSbI1pU= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.38.0 h1:lwI4Dc5leUqENgGuQImwLo4WnuXFPetmPpkLi2IrX54= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.38.0/go.mod h1:Kz/oCE7z5wuyhPxsXDuaPteSWqjSBD5YaSdbxZYGbGk= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.38.0 h1:aTL7F04bJHUlztTsNGJ2l+6he8c+y/b//eR0jjjemT4= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.38.0/go.mod h1:kldtb7jDTeol0l3ewcmd8SDvx3EmIE7lyvqbasU3QC4= -go.opentelemetry.io/otel/exporters/prometheus v0.60.0 h1:cGtQxGvZbnrWdC2GyjZi0PDKVSLWP/Jocix3QWfXtbo= -go.opentelemetry.io/otel/exporters/prometheus v0.60.0/go.mod h1:hkd1EekxNo69PTV4OWFGZcKQiIqg0RfuWExcPKFvepk= -go.opentelemetry.io/otel/exporters/stdout/stdoutlog v0.14.0 h1:B/g+qde6Mkzxbry5ZZag0l7QrQBCtVm7lVjaLgmpje8= -go.opentelemetry.io/otel/exporters/stdout/stdoutlog v0.14.0/go.mod h1:mOJK8eMmgW6ocDJn6Bn11CcZ05gi3P8GylBXEkZtbgA= -go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.38.0 h1:wm/Q0GAAykXv83wzcKzGGqAnnfLFyFe7RslekZuv+VI= -go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.38.0/go.mod h1:ra3Pa40+oKjvYh+ZD3EdxFZZB0xdMfuileHAm4nNN7w= -go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.38.0 h1:kJxSDN4SgWWTjG/hPp3O7LCGLcHXFlvS2/FFOrwL+SE= -go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.38.0/go.mod h1:mgIOzS7iZeKJdeB8/NYHrJ48fdGc71Llo5bJ1J4DWUE= -go.opentelemetry.io/otel/log v0.14.0 h1:2rzJ+pOAZ8qmZ3DDHg73NEKzSZkhkGIua9gXtxNGgrM= -go.opentelemetry.io/otel/log v0.14.0/go.mod h1:5jRG92fEAgx0SU/vFPxmJvhIuDU9E1SUnEQrMlJpOno= -go.opentelemetry.io/otel/metric v1.40.0 h1:rcZe317KPftE2rstWIBitCdVp89A2HqjkxR3c11+p9g= -go.opentelemetry.io/otel/metric v1.40.0/go.mod h1:ib/crwQH7N3r5kfiBZQbwrTge743UDc7DTFVZrrXnqc= -go.opentelemetry.io/otel/sdk v1.40.0 h1:KHW/jUzgo6wsPh9At46+h4upjtccTmuZCFAc9OJ71f8= -go.opentelemetry.io/otel/sdk v1.40.0/go.mod h1:Ph7EFdYvxq72Y8Li9q8KebuYUr2KoeyHx0DRMKrYBUE= -go.opentelemetry.io/otel/sdk/log v0.14.0 h1:JU/U3O7N6fsAXj0+CXz21Czg532dW2V4gG1HE/e8Zrg= -go.opentelemetry.io/otel/sdk/log v0.14.0/go.mod h1:imQvII+0ZylXfKU7/wtOND8Hn4OpT3YUoIgqJVksUkM= -go.opentelemetry.io/otel/sdk/log/logtest v0.14.0 h1:Ijbtz+JKXl8T2MngiwqBlPaHqc4YCaP/i13Qrow6gAM= -go.opentelemetry.io/otel/sdk/log/logtest v0.14.0/go.mod h1:dCU8aEL6q+L9cYTqcVOk8rM9Tp8WdnHOPLiBgp0SGOA= -go.opentelemetry.io/otel/sdk/metric v1.40.0 h1:mtmdVqgQkeRxHgRv4qhyJduP3fYJRMX4AtAlbuWdCYw= -go.opentelemetry.io/otel/sdk/metric v1.40.0/go.mod h1:4Z2bGMf0KSK3uRjlczMOeMhKU2rhUqdWNoKcYrtcBPg= -go.opentelemetry.io/otel/trace v1.40.0 h1:WA4etStDttCSYuhwvEa8OP8I5EWu24lkOzp+ZYblVjw= -go.opentelemetry.io/otel/trace v1.40.0/go.mod h1:zeAhriXecNGP/s2SEG3+Y8X9ujcJOTqQ5RgdEJcawiA= -go.opentelemetry.io/proto/otlp v1.7.1 h1:gTOMpGDb0WTBOP8JaO72iL3auEZhVmAQg4ipjOVAtj4= -go.opentelemetry.io/proto/otlp v1.7.1/go.mod h1:b2rVh6rfI/s2pHWNlB7ILJcRALpcNDzKhACevjI+ZnE= -go.opentelemetry.io/proto/slim/otlp v1.9.0 h1:fPVMv8tP3TrsqlkH1HWYUpbCY9cAIemx184VGkS6vlE= -go.opentelemetry.io/proto/slim/otlp v1.9.0/go.mod h1:xXdeJJ90Gqyll+orzUkY4bOd2HECo5JofeoLpymVqdI= -go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.2.0 h1:o13nadWDNkH/quoDomDUClnQBpdQQ2Qqv0lQBjIXjE8= -go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.2.0/go.mod h1:Gyb6Xe7FTi/6xBHwMmngGoHqL0w29Y4eW8TGFzpefGA= -go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.2.0 h1:EiUYvtwu6PMrMHVjcPfnsG3v+ajPkbUeH+IL93+QYyk= -go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.2.0/go.mod h1:mUUHKFiN2SST3AhJ8XhJxEoeVW12oqfXog0Bo8W3Ec4= +go.opentelemetry.io/otel v1.42.0 h1:lSQGzTgVR3+sgJDAU/7/ZMjN9Z+vUip7leaqBKy4sho= +go.opentelemetry.io/otel v1.42.0/go.mod h1:lJNsdRMxCUIWuMlVJWzecSMuNjE7dOYyWlqOXWkdqCc= +go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.18.0 h1:deI9UQMoGFgrg5iLPgzueqFPHevDl+28YKfSpPTI6rY= +go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.18.0/go.mod h1:PFx9NgpNUKXdf7J4Q3agRxMs3Y07QhTCVipKmLsMKnU= +go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.18.0 h1:icqq3Z34UrEFk2u+HMhTtRsvo7Ues+eiJVjaJt62njs= +go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.18.0/go.mod h1:W2m8P+d5Wn5kipj4/xmbt9uMqezEKfBjzVJadfABSBE= +go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.42.0 h1:MdKucPl/HbzckWWEisiNqMPhRrAOQX8r4jTuGr636gk= +go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.42.0/go.mod h1:RolT8tWtfHcjajEH5wFIZ4Dgh5jpPdFXYV9pTAk/qjc= +go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.42.0 h1:H7O6RlGOMTizyl3R08Kn5pdM06bnH8oscSj7o11tmLA= +go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.42.0/go.mod h1:mBFWu/WOVDkWWsR7Tx7h6EpQB8wsv7P0Yrh0Pb7othc= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.42.0 h1:THuZiwpQZuHPul65w4WcwEnkX2QIuMT+UFoOrygtoJw= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.42.0/go.mod h1:J2pvYM5NGHofZ2/Ru6zw/TNWnEQp5crgyDeSrYpXkAw= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.42.0 h1:zWWrB1U6nqhS/k6zYB74CjRpuiitRtLLi68VcgmOEto= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.42.0/go.mod h1:2qXPNBX1OVRC0IwOnfo1ljoid+RD0QK3443EaqVlsOU= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.42.0 h1:uLXP+3mghfMf7XmV4PkGfFhFKuNWoCvvx5wP/wOXo0o= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.42.0/go.mod h1:v0Tj04armyT59mnURNUJf7RCKcKzq+lgJs6QSjHjaTc= +go.opentelemetry.io/otel/exporters/prometheus v0.64.0 h1:g0LRDXMX/G1SEZtK8zl8Chm4K6GBwRkjPKE36LxiTYs= +go.opentelemetry.io/otel/exporters/prometheus v0.64.0/go.mod h1:UrgcjnarfdlBDP3GjDIJWe6HTprwSazNjwsI+Ru6hro= +go.opentelemetry.io/otel/exporters/stdout/stdoutlog v0.18.0 h1:KJVjPD3rcPb98rIs3HznyJlrfx9ge5oJvxxlGR+P/7s= +go.opentelemetry.io/otel/exporters/stdout/stdoutlog v0.18.0/go.mod h1:K3kRa2ckmHWQaTWQdPRHc7qGXASuVuoEQXzrvlA98Ws= +go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.42.0 h1:lSZHgNHfbmQTPfuTmWVkEu8J8qXaQwuV30pjCcAUvP8= +go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.42.0/go.mod h1:so9ounLcuoRDu033MW/E0AD4hhUjVqswrMF5FoZlBcw= +go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.42.0 h1:s/1iRkCKDfhlh1JF26knRneorus8aOwVIDhvYx9WoDw= +go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.42.0/go.mod h1:UI3wi0FXg1Pofb8ZBiBLhtMzgoTm1TYkMvn71fAqDzs= +go.opentelemetry.io/otel/log v0.18.0 h1:XgeQIIBjZZrliksMEbcwMZefoOSMI1hdjiLEiiB0bAg= +go.opentelemetry.io/otel/log v0.18.0/go.mod h1:KEV1kad0NofR3ycsiDH4Yjcoj0+8206I6Ox2QYFSNgI= +go.opentelemetry.io/otel/metric v1.42.0 h1:2jXG+3oZLNXEPfNmnpxKDeZsFI5o4J+nz6xUlaFdF/4= +go.opentelemetry.io/otel/metric v1.42.0/go.mod h1:RlUN/7vTU7Ao/diDkEpQpnz3/92J9ko05BIwxYa2SSI= +go.opentelemetry.io/otel/sdk v1.42.0 h1:LyC8+jqk6UJwdrI/8VydAq/hvkFKNHZVIWuslJXYsDo= +go.opentelemetry.io/otel/sdk v1.42.0/go.mod h1:rGHCAxd9DAph0joO4W6OPwxjNTYWghRWmkHuGbayMts= +go.opentelemetry.io/otel/sdk/log v0.18.0 h1:n8OyZr7t7otkeTnPTbDNom6rW16TBYGtvyy2Gk6buQw= +go.opentelemetry.io/otel/sdk/log v0.18.0/go.mod h1:C0+wxkTwKpOCZLrlJ3pewPiiQwpzycPI/u6W0Z9fuYk= +go.opentelemetry.io/otel/sdk/log/logtest v0.18.0 h1:l3mYuPsuBx6UKE47BVcPrZoZ0q/KER57vbj2qkgDLXA= +go.opentelemetry.io/otel/sdk/log/logtest v0.18.0/go.mod h1:7cHtiVJpZebB3wybTa4NG+FUo5NPe3PROz1FqB0+qdw= +go.opentelemetry.io/otel/sdk/metric v1.42.0 h1:D/1QR46Clz6ajyZ3G8SgNlTJKBdGp84q9RKCAZ3YGuA= +go.opentelemetry.io/otel/sdk/metric v1.42.0/go.mod h1:Ua6AAlDKdZ7tdvaQKfSmnFTdHx37+J4ba8MwVCYM5hc= +go.opentelemetry.io/otel/trace v1.42.0 h1:OUCgIPt+mzOnaUTpOQcBiM/PLQ/Op7oq6g4LenLmOYY= +go.opentelemetry.io/otel/trace v1.42.0/go.mod h1:f3K9S+IFqnumBkKhRJMeaZeNk9epyhnCmQh/EysQCdc= +go.opentelemetry.io/proto/otlp v1.10.0 h1:IQRWgT5srOCYfiWnpqUYz9CVmbO8bFmKcwYxpuCSL2g= +go.opentelemetry.io/proto/otlp v1.10.0/go.mod h1:/CV4QoCR/S9yaPj8utp3lvQPoqMtxXdzn7ozvvozVqk= +go.opentelemetry.io/proto/slim/otlp v1.10.0 h1:iR97Vs/ZDR+y9TfuP9b1XBtdPWeC+OMslIBmhcLU7jM= +go.opentelemetry.io/proto/slim/otlp v1.10.0/go.mod h1:lV9250stpjYLPNA5viFabIgP2QlUGRT1GdTgAf8SIUk= +go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.3.0 h1:RUF5rO0hAlgiJt1fzQVzcVs3vZVNHIcMLgOgG4rWNcQ= +go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.3.0/go.mod h1:I89cynRj8y+383o7tEQVg2SVA6SRgDVIouWPUVXjx0U= +go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.3.0 h1:CQvJSldHRUN6Z8jsUeYv8J0lXRvygALXIzsmAeCcZE0= +go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.3.0/go.mod h1:xSQ+mEfJe/GjK1LXEyVOoSI1N9JV9ZI923X5kup43W4= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= @@ -121,22 +121,22 @@ go.yaml.in/yaml/v2 v2.4.3 h1:6gvOSjQoTB3vt1l+CU+tSyi/HOjfOjRLJ4YwYZGwRO0= go.yaml.in/yaml/v2 v2.4.3/go.mod h1:zSxWcmIDjOzPXpjlTTbAsKokqkDNAVtZO0WOMiT90s8= go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc= go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg= -golang.org/x/net v0.47.0 h1:Mx+4dIFzqraBXUugkia1OOvlD6LemFo1ALMHjrXDOhY= -golang.org/x/net v0.47.0/go.mod h1:/jNxtkgq5yWUGYkaZGqo27cfGZ1c5Nen03aYrrKpVRU= -golang.org/x/sys v0.40.0 h1:DBZZqJ2Rkml6QMQsZywtnjnnGvHza6BTfYFWY9kjEWQ= -golang.org/x/sys v0.40.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= -golang.org/x/text v0.31.0 h1:aC8ghyu4JhP8VojJ2lEHBnochRno1sgL6nEi9WGFGMM= -golang.org/x/text v0.31.0/go.mod h1:tKRAlv61yKIjGGHX/4tP1LTbc13YSec1pxVEWXzfoeM= -gonum.org/v1/gonum v0.16.0 h1:5+ul4Swaf3ESvrOnidPp4GZbzf0mxVQpDCYUQE7OJfk= -gonum.org/v1/gonum v0.16.0/go.mod h1:fef3am4MQ93R2HHpKnLk4/Tbh/s0+wqD5nfa6Pnwy4E= -google.golang.org/genproto/googleapis/api v0.0.0-20251022142026-3a174f9686a8 h1:mepRgnBZa07I4TRuomDE4sTIYieg/osKmzIf4USdWS4= -google.golang.org/genproto/googleapis/api v0.0.0-20251022142026-3a174f9686a8/go.mod h1:fDMmzKV90WSg1NbozdqrE64fkuTv6mlq2zxo9ad+3yo= -google.golang.org/genproto/googleapis/rpc v0.0.0-20251022142026-3a174f9686a8 h1:M1rk8KBnUsBDg1oPGHNCxG4vc1f49epmTO7xscSajMk= -google.golang.org/genproto/googleapis/rpc v0.0.0-20251022142026-3a174f9686a8/go.mod h1:7i2o+ce6H/6BluujYR+kqX3GKH+dChPTQU19wjRPiGk= -google.golang.org/grpc v1.77.0 h1:wVVY6/8cGA6vvffn+wWK5ToddbgdU3d8MNENr4evgXM= -google.golang.org/grpc v1.77.0/go.mod h1:z0BY1iVj0q8E1uSQCjL9cppRj+gnZjzDnzV0dHhrNig= -google.golang.org/protobuf v1.36.10 h1:AYd7cD/uASjIL6Q9LiTjz8JLcrh/88q5UObnmY3aOOE= -google.golang.org/protobuf v1.36.10/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= +golang.org/x/net v0.51.0 h1:94R/GTO7mt3/4wIKpcR5gkGmRLOuE/2hNGeWq/GBIFo= +golang.org/x/net v0.51.0/go.mod h1:aamm+2QF5ogm02fjy5Bb7CQ0WMt1/WVM7FtyaTLlA9Y= +golang.org/x/sys v0.41.0 h1:Ivj+2Cp/ylzLiEU89QhWblYnOE9zerudt9Ftecq2C6k= +golang.org/x/sys v0.41.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= +golang.org/x/text v0.34.0 h1:oL/Qq0Kdaqxa1KbNeMKwQq0reLCCaFtqu2eNuSeNHbk= +golang.org/x/text v0.34.0/go.mod h1:homfLqTYRFyVYemLBFl5GgL/DWEiH5wcsQ5gSh1yziA= +gonum.org/v1/gonum v0.17.0 h1:VbpOemQlsSMrYmn7T2OUvQ4dqxQXU+ouZFQsZOx50z4= +gonum.org/v1/gonum v0.17.0/go.mod h1:El3tOrEuMpv2UdMrbNlKEh9vd86bmQ6vqIcDwxEOc1E= +google.golang.org/genproto/googleapis/api v0.0.0-20260226221140-a57be14db171 h1:tu/dtnW1o3wfaxCOjSLn5IRX4YDcJrtlpzYkhHhGaC4= +google.golang.org/genproto/googleapis/api v0.0.0-20260226221140-a57be14db171/go.mod h1:M5krXqk4GhBKvB596udGL3UyjL4I1+cTbK0orROM9ng= +google.golang.org/genproto/googleapis/rpc v0.0.0-20260226221140-a57be14db171 h1:ggcbiqK8WWh6l1dnltU4BgWGIGo+EVYxCaAPih/zQXQ= +google.golang.org/genproto/googleapis/rpc v0.0.0-20260226221140-a57be14db171/go.mod h1:4Hqkh8ycfw05ld/3BWL7rJOSfebL2Q+DVDeRgYgxUU8= +google.golang.org/grpc v1.79.3 h1:sybAEdRIEtvcD68Gx7dmnwjZKlyfuc61Dyo9pGXXkKE= +google.golang.org/grpc v1.79.3/go.mod h1:KmT0Kjez+0dde/v2j9vzwoAScgEPx/Bw1CYChhHLrHQ= +google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE= +google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= diff --git a/service/telemetry/telemetrytest/metadata.yaml b/service/telemetry/telemetrytest/metadata.yaml new file mode 100644 index 000000000000..15b0daa23c19 --- /dev/null +++ b/service/telemetry/telemetrytest/metadata.yaml @@ -0,0 +1,6 @@ +type: service/telemetry/telemetrytest +github_project: open-telemetry/opentelemetry-collector + +status: + disable_codecov_badge: true + class: pkg diff --git a/versions.yaml b/versions.yaml index 4384eec2c3c9..691309fb8e9d 100644 --- a/versions.yaml +++ b/versions.yaml @@ -3,7 +3,7 @@ module-sets: stable: - version: v1.46.0 + version: v1.54.0 modules: - go.opentelemetry.io/collector/client - go.opentelemetry.io/collector/featuregate @@ -31,9 +31,10 @@ module-sets: - go.opentelemetry.io/collector/processor - go.opentelemetry.io/collector/receiver beta: - version: v0.140.0 + version: v0.148.0 modules: - go.opentelemetry.io/collector + - go.opentelemetry.io/collector/internal/componentalias - go.opentelemetry.io/collector/internal/memorylimiter - go.opentelemetry.io/collector/internal/fanoutconsumer - go.opentelemetry.io/collector/internal/sharedcomponent @@ -91,6 +92,7 @@ module-sets: - go.opentelemetry.io/collector/receiver/xreceiver - go.opentelemetry.io/collector/scraper - go.opentelemetry.io/collector/scraper/scraperhelper + - go.opentelemetry.io/collector/scraper/scraperhelper/xscraperhelper - go.opentelemetry.io/collector/scraper/scrapertest - go.opentelemetry.io/collector/scraper/xscraper - go.opentelemetry.io/collector/service