chore(deps): bump google.golang.org/grpc from 1.73.0 to 1.74.2

Bumps [google.golang.org/grpc](https://github.com/grpc/grpc-go) from 1.73.0 to 1.74.2.
- [Release notes](https://github.com/grpc/grpc-go/releases)
- [Commits](https://github.com/grpc/grpc-go/compare/v1.73.0...v1.74.2)

---
updated-dependencies:
- dependency-name: google.golang.org/grpc
  dependency-version: 1.74.2
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
This commit is contained in:
dependabot[bot]
2025-08-04 08:52:26 +00:00
committed by GitHub
parent 4c5e8ac53a
commit dc3570678d
53 changed files with 795 additions and 586 deletions

View File

@@ -1,13 +1,9 @@
# See https://github.com/golangci/golangci-lint#config-file
version: "2"
run:
issues-exit-code: 1 #Default
tests: true #Default
issues-exit-code: 1
tests: true
linters:
# Disable everything by default so upgrades to not include new "default
# enabled" linters.
disable-all: true
# Specifically enable linters we want to use.
default: none
enable:
- asasalint
- bodyclose
@@ -15,10 +11,7 @@ linters:
- errcheck
- errorlint
- godot
- gofumpt
- goimports
- gosec
- gosimple
- govet
- ineffassign
- misspell
@@ -26,227 +19,230 @@ linters:
- revive
- staticcheck
- testifylint
- typecheck
- unconvert
- unused
- unparam
- unused
- usestdlibvars
- usetesting
settings:
depguard:
rules:
auto/sdk:
files:
- '!internal/global/trace.go'
- ~internal/global/trace_test.go
deny:
- pkg: go.opentelemetry.io/auto/sdk
desc: Do not use SDK from automatic instrumentation.
non-tests:
files:
- '!$test'
- '!**/*test/*.go'
- '!**/internal/matchers/*.go'
deny:
- pkg: testing
- pkg: github.com/stretchr/testify
- pkg: crypto/md5
- pkg: crypto/sha1
- pkg: crypto/**/pkix
otel-internal:
files:
- '**/sdk/*.go'
- '**/sdk/**/*.go'
- '**/exporters/*.go'
- '**/exporters/**/*.go'
- '**/schema/*.go'
- '**/schema/**/*.go'
- '**/metric/*.go'
- '**/metric/**/*.go'
- '**/bridge/*.go'
- '**/bridge/**/*.go'
- '**/trace/*.go'
- '**/trace/**/*.go'
- '**/log/*.go'
- '**/log/**/*.go'
deny:
- pkg: go.opentelemetry.io/otel/internal$
desc: Do not use cross-module internal packages.
- pkg: go.opentelemetry.io/otel/internal/internaltest
desc: Do not use cross-module internal packages.
- pkg: go.opentelemetry.io/otel/internal/matchers
desc: Do not use cross-module internal packages.
otlp-internal:
files:
- '!**/exporters/otlp/internal/**/*.go'
deny:
- pkg: go.opentelemetry.io/otel/exporters/otlp/internal
desc: Do not use cross-module internal packages.
otlpmetric-internal:
files:
- '!**/exporters/otlp/otlpmetric/internal/*.go'
- '!**/exporters/otlp/otlpmetric/internal/**/*.go'
deny:
- pkg: go.opentelemetry.io/otel/exporters/otlp/otlpmetric/internal
desc: Do not use cross-module internal packages.
otlptrace-internal:
files:
- '!**/exporters/otlp/otlptrace/*.go'
- '!**/exporters/otlp/otlptrace/internal/**.go'
deny:
- pkg: go.opentelemetry.io/otel/exporters/otlp/otlptrace/internal
desc: Do not use cross-module internal packages.
godot:
exclude:
# Exclude links.
- '^ *\[[^]]+\]:'
# Exclude sentence fragments for lists.
- ^[ ]*[-•]
# Exclude sentences prefixing a list.
- :$
misspell:
locale: US
ignore-rules:
- cancelled
perfsprint:
int-conversion: true
err-error: true
errorf: true
sprintf1: true
strconcat: true
revive:
confidence: 0.01
rules:
- name: blank-imports
- name: bool-literal-in-expr
- name: constant-logical-expr
- name: context-as-argument
arguments:
- allowTypesBefore: '*testing.T'
disabled: true
- name: context-keys-type
- name: deep-exit
- name: defer
arguments:
- - call-chain
- loop
- name: dot-imports
- name: duplicated-imports
- name: early-return
arguments:
- preserveScope
- name: empty-block
- name: empty-lines
- name: error-naming
- name: error-return
- name: error-strings
- name: errorf
- name: exported
arguments:
- sayRepetitiveInsteadOfStutters
- name: flag-parameter
- name: identical-branches
- name: if-return
- name: import-shadowing
- name: increment-decrement
- name: indent-error-flow
arguments:
- preserveScope
- name: package-comments
- name: range
- name: range-val-in-closure
- name: range-val-address
- name: redefines-builtin-id
- name: string-format
arguments:
- - panic
- /^[^\n]*$/
- must not contain line breaks
- name: struct-tag
- name: superfluous-else
arguments:
- preserveScope
- name: time-equal
- name: unconditional-recursion
- name: unexported-return
- name: unhandled-error
arguments:
- fmt.Fprint
- fmt.Fprintf
- fmt.Fprintln
- fmt.Print
- fmt.Printf
- fmt.Println
- name: unnecessary-stmt
- name: useless-break
- name: var-declaration
- name: var-naming
arguments:
- ["ID"] # AllowList
- ["Otel", "Aws", "Gcp"] # DenyList
- name: waitgroup-by-value
testifylint:
enable-all: true
disable:
- float-compare
- go-require
- require-error
exclusions:
generated: lax
presets:
- common-false-positives
- legacy
- std-error-handling
rules:
# TODO: Having appropriate comments for exported objects helps development,
# even for objects in internal packages. Appropriate comments for all
# exported objects should be added and this exclusion removed.
- linters:
- revive
path: .*internal/.*
text: exported (method|function|type|const) (.+) should have comment or be unexported
# Yes, they are, but it's okay in a test.
- linters:
- revive
path: _test\.go
text: exported func.*returns unexported type.*which can be annoying to use
# Example test functions should be treated like main.
- linters:
- revive
path: example.*_test\.go
text: calls to (.+) only in main[(][)] or init[(][)] functions
# It's okay to not run gosec and perfsprint in a test.
- linters:
- gosec
- perfsprint
path: _test\.go
# Ignoring gosec G404: Use of weak random number generator (math/rand instead of crypto/rand)
# as we commonly use it in tests and examples.
- linters:
- gosec
text: 'G404:'
# Ignoring gosec G402: TLS MinVersion too low
# as the https://pkg.go.dev/crypto/tls#Config handles MinVersion default well.
- linters:
- gosec
text: 'G402: TLS MinVersion too low.'
paths:
- third_party$
- builtin$
- examples$
issues:
# Maximum issues count per one linter.
# Set to 0 to disable.
# Default: 50
# Setting to unlimited so the linter only is run once to debug all issues.
max-issues-per-linter: 0
# Maximum count of issues with the same text.
# Set to 0 to disable.
# Default: 3
# Setting to unlimited so the linter only is run once to debug all issues.
max-same-issues: 0
# Excluding configuration per-path, per-linter, per-text and per-source.
exclude-rules:
# TODO: Having appropriate comments for exported objects helps development,
# even for objects in internal packages. Appropriate comments for all
# exported objects should be added and this exclusion removed.
- path: '.*internal/.*'
text: "exported (method|function|type|const) (.+) should have comment or be unexported"
linters:
- revive
# Yes, they are, but it's okay in a test.
- path: _test\.go
text: "exported func.*returns unexported type.*which can be annoying to use"
linters:
- revive
# Example test functions should be treated like main.
- path: example.*_test\.go
text: "calls to (.+) only in main[(][)] or init[(][)] functions"
linters:
- revive
# It's okay to not run gosec and perfsprint in a test.
- path: _test\.go
linters:
- gosec
- perfsprint
# Ignoring gosec G404: Use of weak random number generator (math/rand instead of crypto/rand)
# as we commonly use it in tests and examples.
- text: "G404:"
linters:
- gosec
# Ignoring gosec G402: TLS MinVersion too low
# as the https://pkg.go.dev/crypto/tls#Config handles MinVersion default well.
- text: "G402: TLS MinVersion too low."
linters:
- gosec
include:
# revive exported should have comment or be unexported.
- EXC0012
# revive package comment should be of the form ...
- EXC0013
linters-settings:
depguard:
rules:
non-tests:
files:
- "!$test"
- "!**/*test/*.go"
- "!**/internal/matchers/*.go"
deny:
- pkg: "testing"
- pkg: "github.com/stretchr/testify"
- pkg: "crypto/md5"
- pkg: "crypto/sha1"
- pkg: "crypto/**/pkix"
auto/sdk:
files:
- "!internal/global/trace.go"
- "~internal/global/trace_test.go"
deny:
- pkg: "go.opentelemetry.io/auto/sdk"
desc: Do not use SDK from automatic instrumentation.
otlp-internal:
files:
- "!**/exporters/otlp/internal/**/*.go"
deny:
- pkg: "go.opentelemetry.io/otel/exporters/otlp/internal"
desc: Do not use cross-module internal packages.
otlptrace-internal:
files:
- "!**/exporters/otlp/otlptrace/*.go"
- "!**/exporters/otlp/otlptrace/internal/**.go"
deny:
- pkg: "go.opentelemetry.io/otel/exporters/otlp/otlptrace/internal"
desc: Do not use cross-module internal packages.
otlpmetric-internal:
files:
- "!**/exporters/otlp/otlpmetric/internal/*.go"
- "!**/exporters/otlp/otlpmetric/internal/**/*.go"
deny:
- pkg: "go.opentelemetry.io/otel/exporters/otlp/otlpmetric/internal"
desc: Do not use cross-module internal packages.
otel-internal:
files:
- "**/sdk/*.go"
- "**/sdk/**/*.go"
- "**/exporters/*.go"
- "**/exporters/**/*.go"
- "**/schema/*.go"
- "**/schema/**/*.go"
- "**/metric/*.go"
- "**/metric/**/*.go"
- "**/bridge/*.go"
- "**/bridge/**/*.go"
- "**/trace/*.go"
- "**/trace/**/*.go"
- "**/log/*.go"
- "**/log/**/*.go"
deny:
- pkg: "go.opentelemetry.io/otel/internal$"
desc: Do not use cross-module internal packages.
- pkg: "go.opentelemetry.io/otel/internal/attribute"
desc: Do not use cross-module internal packages.
- pkg: "go.opentelemetry.io/otel/internal/internaltest"
desc: Do not use cross-module internal packages.
- pkg: "go.opentelemetry.io/otel/internal/matchers"
desc: Do not use cross-module internal packages.
godot:
exclude:
# Exclude links.
- '^ *\[[^]]+\]:'
# Exclude sentence fragments for lists.
- '^[ ]*[-•]'
# Exclude sentences prefixing a list.
- ':$'
goimports:
local-prefixes: go.opentelemetry.io
misspell:
locale: US
ignore-words:
- cancelled
perfsprint:
err-error: true
errorf: true
int-conversion: true
sprintf1: true
strconcat: true
revive:
# Sets the default failure confidence.
# This means that linting errors with less than 0.8 confidence will be ignored.
# Default: 0.8
confidence: 0.01
# https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md
rules:
- name: blank-imports
- name: bool-literal-in-expr
- name: constant-logical-expr
- name: context-as-argument
disabled: true
arguments:
- allowTypesBefore: "*testing.T"
- name: context-keys-type
- name: deep-exit
- name: defer
arguments:
- ["call-chain", "loop"]
- name: dot-imports
- name: duplicated-imports
- name: early-return
arguments:
- "preserveScope"
- name: empty-block
- name: empty-lines
- name: error-naming
- name: error-return
- name: error-strings
- name: errorf
- name: exported
arguments:
- "sayRepetitiveInsteadOfStutters"
- name: flag-parameter
- name: identical-branches
- name: if-return
- name: import-shadowing
- name: increment-decrement
- name: indent-error-flow
arguments:
- "preserveScope"
- name: package-comments
- name: range
- name: range-val-in-closure
- name: range-val-address
- name: redefines-builtin-id
- name: string-format
arguments:
- - panic
- '/^[^\n]*$/'
- must not contain line breaks
- name: struct-tag
- name: superfluous-else
arguments:
- "preserveScope"
- name: time-equal
- name: unconditional-recursion
- name: unexported-return
- name: unhandled-error
arguments:
- "fmt.Fprint"
- "fmt.Fprintf"
- "fmt.Fprintln"
- "fmt.Print"
- "fmt.Printf"
- "fmt.Println"
- name: unnecessary-stmt
- name: useless-break
- name: var-declaration
- name: var-naming
arguments:
- ["ID"] # AllowList
- ["Otel", "Aws", "Gcp"] # DenyList
- name: waitgroup-by-value
testifylint:
enable-all: true
disable:
- float-compare
- go-require
- require-error
formatters:
enable:
- gofumpt
- goimports
- golines
settings:
goimports:
local-prefixes:
- go.opentelemetry.io
golines:
max-len: 120
exclusions:
generated: lax
paths:
- third_party$
- builtin$
- examples$

View File

@@ -11,6 +11,57 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm
<!-- Released section -->
<!-- Don't change this section unless doing release -->
## [1.36.0/0.58.0/0.12.0] 2025-05-20
### Added
- Add exponential histogram support in `go.opentelemetry.io/otel/exporters/prometheus`. (#6421)
- The `go.opentelemetry.io/otel/semconv/v1.31.0` package.
The package contains semantic conventions from the `v1.31.0` version of the OpenTelemetry Semantic Conventions.
See the [migration documentation](./semconv/v1.31.0/MIGRATION.md) for information on how to upgrade from `go.opentelemetry.io/otel/semconv/v1.30.0`. (#6479)
- Add `Recording`, `Scope`, and `Record` types in `go.opentelemetry.io/otel/log/logtest`. (#6507)
- Add `WithHTTPClient` option to configure the `http.Client` used by `go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp`. (#6751)
- Add `WithHTTPClient` option to configure the `http.Client` used by `go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp`. (#6752)
- Add `WithHTTPClient` option to configure the `http.Client` used by `go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp`. (#6688)
- Add `ValuesGetter` in `go.opentelemetry.io/otel/propagation`, a `TextMapCarrier` that supports retrieving multiple values for a single key. (#5973)
- Add `Values` method to `HeaderCarrier` to implement the new `ValuesGetter` interface in `go.opentelemetry.io/otel/propagation`. (#5973)
- Update `Baggage` in `go.opentelemetry.io/otel/propagation` to retrieve multiple values for a key when the carrier implements `ValuesGetter`. (#5973)
- Add `AssertEqual` function in `go.opentelemetry.io/otel/log/logtest`. (#6662)
- The `go.opentelemetry.io/otel/semconv/v1.32.0` package.
The package contains semantic conventions from the `v1.32.0` version of the OpenTelemetry Semantic Conventions.
See the [migration documentation](./semconv/v1.32.0/MIGRATION.md) for information on how to upgrade from `go.opentelemetry.io/otel/semconv/v1.31.0`(#6782)
- Add `Transform` option in `go.opentelemetry.io/otel/log/logtest`. (#6794)
- Add `Desc` option in `go.opentelemetry.io/otel/log/logtest`. (#6796)
### Removed
- Drop support for [Go 1.22]. (#6381, #6418)
- Remove `Resource` field from `EnabledParameters` in `go.opentelemetry.io/otel/sdk/log`. (#6494)
- Remove `RecordFactory` type from `go.opentelemetry.io/otel/log/logtest`. (#6492)
- Remove `ScopeRecords`, `EmittedRecord`, and `RecordFactory` types from `go.opentelemetry.io/otel/log/logtest`. (#6507)
- Remove `AssertRecordEqual` function in `go.opentelemetry.io/otel/log/logtest`, use `AssertEqual` instead. (#6662)
### Changed
- ⚠️ Update `github.com/prometheus/client_golang` to `v1.21.1`, which changes the `NameValidationScheme` to `UTF8Validation`.
This allows metrics names to keep original delimiters (e.g. `.`), rather than replacing with underscores.
This can be reverted by setting `github.com/prometheus/common/model.NameValidationScheme` to `LegacyValidation` in `github.com/prometheus/common/model`. (#6433)
- Initialize map with `len(keys)` in `NewAllowKeysFilter` and `NewDenyKeysFilter` to avoid unnecessary allocations in `go.opentelemetry.io/otel/attribute`. (#6455)
- `go.opentelemetry.io/otel/log/logtest` is now a separate Go module. (#6465)
- `go.opentelemetry.io/otel/sdk/log/logtest` is now a separate Go module. (#6466)
- `Recorder` in `go.opentelemetry.io/otel/log/logtest` no longer separately stores records emitted by loggers with the same instrumentation scope. (#6507)
- Improve performance of `BatchProcessor` in `go.opentelemetry.io/otel/sdk/log` by not exporting when exporter cannot accept more. (#6569, #6641)
### Deprecated
- Deprecate support for `model.LegacyValidation` for `go.opentelemetry.io/otel/exporters/prometheus`. (#6449)
### Fixes
- Stop percent encoding header environment variables in `go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc` and `go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp`. (#6392)
- Ensure the `noopSpan.tracerProvider` method is not inlined in `go.opentelemetry.io/otel/trace` so the `go.opentelemetry.io/auto` instrumentation can instrument non-recording spans. (#6456)
- Use a `sync.Pool` instead of allocating `metricdata.ResourceMetrics` in `go.opentelemetry.io/otel/exporters/prometheus`. (#6472)
## [1.35.0/0.57.0/0.11.0] 2025-03-05
This release is the last to support [Go 1.22].
@@ -3237,7 +3288,8 @@ It contains api and sdk for trace and meter.
- CircleCI build CI manifest files.
- CODEOWNERS file to track owners of this project.
[Unreleased]: https://github.com/open-telemetry/opentelemetry-go/compare/v1.35.0...HEAD
[Unreleased]: https://github.com/open-telemetry/opentelemetry-go/compare/v1.36.0...HEAD
[1.36.0/0.58.0/0.12.0]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v1.36.0
[1.35.0/0.57.0/0.11.0]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v1.35.0
[1.34.0/0.56.0/0.10.0]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v1.34.0
[1.33.0/0.55.0/0.9.0/0.0.12]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v1.33.0

View File

@@ -643,6 +643,7 @@ should be canceled.
### Triagers
- [Alex Kats](https://github.com/akats7), Capital One
- [Cheng-Zhen Yang](https://github.com/scorpionknifes), Independent
### Approvers

View File

@@ -43,8 +43,11 @@ $(TOOLS)/crosslink: PACKAGE=go.opentelemetry.io/build-tools/crosslink
SEMCONVKIT = $(TOOLS)/semconvkit
$(TOOLS)/semconvkit: PACKAGE=go.opentelemetry.io/otel/$(TOOLS_MOD_DIR)/semconvkit
VERIFYREADMES = $(TOOLS)/verifyreadmes
$(TOOLS)/verifyreadmes: PACKAGE=go.opentelemetry.io/otel/$(TOOLS_MOD_DIR)/verifyreadmes
GOLANGCI_LINT = $(TOOLS)/golangci-lint
$(TOOLS)/golangci-lint: PACKAGE=github.com/golangci/golangci-lint/cmd/golangci-lint
$(TOOLS)/golangci-lint: PACKAGE=github.com/golangci/golangci-lint/v2/cmd/golangci-lint
MISSPELL = $(TOOLS)/misspell
$(TOOLS)/misspell: PACKAGE=github.com/client9/misspell/cmd/misspell
@@ -68,7 +71,7 @@ GOVULNCHECK = $(TOOLS)/govulncheck
$(TOOLS)/govulncheck: PACKAGE=golang.org/x/vuln/cmd/govulncheck
.PHONY: tools
tools: $(CROSSLINK) $(GOLANGCI_LINT) $(MISSPELL) $(GOCOVMERGE) $(STRINGER) $(PORTO) $(SEMCONVGEN) $(MULTIMOD) $(SEMCONVKIT) $(GOTMPL) $(GORELEASE)
tools: $(CROSSLINK) $(GOLANGCI_LINT) $(MISSPELL) $(GOCOVMERGE) $(STRINGER) $(PORTO) $(SEMCONVGEN) $(VERIFYREADMES) $(MULTIMOD) $(SEMCONVKIT) $(GOTMPL) $(GORELEASE)
# Virtualized python tools via docker
@@ -213,11 +216,8 @@ go-mod-tidy/%: crosslink
&& cd $(DIR) \
&& $(GO) mod tidy -compat=1.21
.PHONY: lint-modules
lint-modules: go-mod-tidy
.PHONY: lint
lint: misspell lint-modules golangci-lint govulncheck
lint: misspell go-mod-tidy golangci-lint govulncheck
.PHONY: vanity-import-check
vanity-import-check: $(PORTO)
@@ -319,10 +319,11 @@ add-tags: verify-mods
@[ "${MODSET}" ] || ( echo ">> env var MODSET is not set"; exit 1 )
$(MULTIMOD) tag -m ${MODSET} -c ${COMMIT}
MARKDOWNIMAGE := $(shell awk '$$4=="markdown" {print $$2}' $(DEPENDENCIES_DOCKERFILE))
.PHONY: lint-markdown
lint-markdown:
docker run -v "$(CURDIR):$(WORKDIR)" avtodev/markdown-lint:v1 -c $(WORKDIR)/.markdownlint.yaml $(WORKDIR)/**/*.md
docker run --rm -u $(DOCKER_USER) -v "$(CURDIR):$(WORKDIR)" $(MARKDOWNIMAGE) -c $(WORKDIR)/.markdownlint.yaml $(WORKDIR)/**/*.md
.PHONY: verify-readmes
verify-readmes:
./verify_readmes.sh
verify-readmes: $(VERIFYREADMES)
$(VERIFYREADMES)

View File

@@ -6,6 +6,7 @@
[![Go Report Card](https://goreportcard.com/badge/go.opentelemetry.io/otel)](https://goreportcard.com/report/go.opentelemetry.io/otel)
[![OpenSSF Scorecard](https://api.scorecard.dev/projects/github.com/open-telemetry/opentelemetry-go/badge)](https://scorecard.dev/viewer/?uri=github.com/open-telemetry/opentelemetry-go)
[![OpenSSF Best Practices](https://www.bestpractices.dev/projects/9996/badge)](https://www.bestpractices.dev/projects/9996)
[![Fuzzing Status](https://oss-fuzz-build-logs.storage.googleapis.com/badges/opentelemetry-go.svg)](https://issues.oss-fuzz.com/issues?q=project:opentelemetry-go)
[![Slack](https://img.shields.io/badge/slack-@cncf/otel--go-brightgreen.svg?logo=slack)](https://cloud-native.slack.com/archives/C01NPAXACKT)
OpenTelemetry-Go is the [Go](https://golang.org/) implementation of [OpenTelemetry](https://opentelemetry.io/).
@@ -53,25 +54,18 @@ Currently, this project supports the following environments.
|----------|------------|--------------|
| Ubuntu | 1.24 | amd64 |
| Ubuntu | 1.23 | amd64 |
| Ubuntu | 1.22 | amd64 |
| Ubuntu | 1.24 | 386 |
| Ubuntu | 1.23 | 386 |
| Ubuntu | 1.22 | 386 |
| Ubuntu | 1.24 | arm64 |
| Ubuntu | 1.23 | arm64 |
| Ubuntu | 1.22 | arm64 |
| macOS 13 | 1.24 | amd64 |
| macOS 13 | 1.23 | amd64 |
| macOS 13 | 1.22 | amd64 |
| macOS | 1.24 | arm64 |
| macOS | 1.23 | arm64 |
| macOS | 1.22 | arm64 |
| Windows | 1.24 | amd64 |
| Windows | 1.23 | amd64 |
| Windows | 1.22 | amd64 |
| Windows | 1.24 | 386 |
| Windows | 1.23 | 386 |
| Windows | 1.22 | 386 |
While this project should work for other systems, no compatibility guarantees
are made for those systems currently.

View File

@@ -1,5 +1,9 @@
# Release Process
## Create a `Version Release` issue
Create a `Version Release` issue to track the release process.
## Semantic Convention Generation
New versions of the [OpenTelemetry Semantic Conventions] mean new versions of the `semconv` package need to be generated.
@@ -123,6 +127,16 @@ Importantly, bump any package versions referenced to be the latest one you just
[Go instrumentation documentation]: https://opentelemetry.io/docs/languages/go/
[content/en/docs/languages/go]: https://github.com/open-telemetry/opentelemetry.io/tree/main/content/en/docs/languages/go
### Close the milestone
Once a release is made, ensure all issues that were fixed and PRs that were merged as part of this release are added to the corresponding milestone.
This helps track what changes were included in each release.
- To find issues that haven't been included in a milestone, use this [GitHub search query](https://github.com/open-telemetry/opentelemetry-go/issues?q=is%3Aissue%20no%3Amilestone%20is%3Aclosed%20sort%3Aupdated-desc%20reason%3Acompleted%20-label%3AStale%20linked%3Apr)
- To find merged PRs that haven't been included in a milestone, use this [GitHub search query](https://github.com/open-telemetry/opentelemetry-go/pulls?q=is%3Apr+no%3Amilestone+is%3Amerged).
Once all related issues and PRs have been added to the milestone, close the milestone.
### Demo Repository
Bump the dependencies in the following Go services:
@@ -130,3 +144,7 @@ Bump the dependencies in the following Go services:
- [`accounting`](https://github.com/open-telemetry/opentelemetry-demo/tree/main/src/accounting)
- [`checkoutservice`](https://github.com/open-telemetry/opentelemetry-demo/tree/main/src/checkout)
- [`productcatalogservice`](https://github.com/open-telemetry/opentelemetry-demo/tree/main/src/product-catalog)
### Close the `Version Release` issue
Once the todo list in the `Version Release` issue is complete, close the issue.

View File

@@ -19,7 +19,7 @@ func NewAllowKeysFilter(keys ...Key) Filter {
return func(kv KeyValue) bool { return false }
}
allowed := make(map[Key]struct{})
allowed := make(map[Key]struct{}, len(keys))
for _, k := range keys {
allowed[k] = struct{}{}
}
@@ -38,7 +38,7 @@ func NewDenyKeysFilter(keys ...Key) Filter {
return func(kv KeyValue) bool { return true }
}
forbid := make(map[Key]struct{})
forbid := make(map[Key]struct{}, len(keys))
for _, k := range keys {
forbid[k] = struct{}{}
}

View File

@@ -5,7 +5,7 @@
Package attribute provide several helper functions for some commonly used
logic of processing attributes.
*/
package attribute // import "go.opentelemetry.io/otel/internal/attribute"
package attribute // import "go.opentelemetry.io/otel/attribute/internal"
import (
"reflect"

View File

@@ -0,0 +1,37 @@
// Copyright The OpenTelemetry Authors
// SPDX-License-Identifier: Apache-2.0
package attribute // import "go.opentelemetry.io/otel/attribute"
import (
"math"
)
func boolToRaw(b bool) uint64 { // nolint:revive // b is not a control flag.
if b {
return 1
}
return 0
}
func rawToBool(r uint64) bool {
return r != 0
}
func int64ToRaw(i int64) uint64 {
// Assumes original was a valid int64 (overflow not checked).
return uint64(i) // nolint: gosec
}
func rawToInt64(r uint64) int64 {
// Assumes original was a valid int64 (overflow not checked).
return int64(r) // nolint: gosec
}
func float64ToRaw(f float64) uint64 {
return math.Float64bits(f)
}
func rawToFloat64(r uint64) float64 {
return math.Float64frombits(r)
}

View File

@@ -9,8 +9,7 @@ import (
"reflect"
"strconv"
"go.opentelemetry.io/otel/internal"
"go.opentelemetry.io/otel/internal/attribute"
attribute "go.opentelemetry.io/otel/attribute/internal"
)
//go:generate stringer -type=Type
@@ -51,7 +50,7 @@ const (
func BoolValue(v bool) Value {
return Value{
vtype: BOOL,
numeric: internal.BoolToRaw(v),
numeric: boolToRaw(v),
}
}
@@ -82,7 +81,7 @@ func IntSliceValue(v []int) Value {
func Int64Value(v int64) Value {
return Value{
vtype: INT64,
numeric: internal.Int64ToRaw(v),
numeric: int64ToRaw(v),
}
}
@@ -95,7 +94,7 @@ func Int64SliceValue(v []int64) Value {
func Float64Value(v float64) Value {
return Value{
vtype: FLOAT64,
numeric: internal.Float64ToRaw(v),
numeric: float64ToRaw(v),
}
}
@@ -125,7 +124,7 @@ func (v Value) Type() Type {
// AsBool returns the bool value. Make sure that the Value's type is
// BOOL.
func (v Value) AsBool() bool {
return internal.RawToBool(v.numeric)
return rawToBool(v.numeric)
}
// AsBoolSlice returns the []bool value. Make sure that the Value's type is
@@ -144,7 +143,7 @@ func (v Value) asBoolSlice() []bool {
// AsInt64 returns the int64 value. Make sure that the Value's type is
// INT64.
func (v Value) AsInt64() int64 {
return internal.RawToInt64(v.numeric)
return rawToInt64(v.numeric)
}
// AsInt64Slice returns the []int64 value. Make sure that the Value's type is
@@ -163,7 +162,7 @@ func (v Value) asInt64Slice() []int64 {
// AsFloat64 returns the float64 value. Make sure that the Value's
// type is FLOAT64.
func (v Value) AsFloat64() float64 {
return internal.RawToFloat64(v.numeric)
return rawToFloat64(v.numeric)
}
// AsFloat64Slice returns the []float64 value. Make sure that the Value's type is

View File

@@ -1,3 +1,4 @@
# This is a renovate-friendly source of Docker images.
FROM python:3.13.2-slim-bullseye@sha256:31b581c8218e1f3c58672481b3b7dba8e898852866b408c6a984c22832523935 AS python
FROM otel/weaver:v0.13.2@sha256:ae7346b992e477f629ea327e0979e8a416a97f7956ab1f7e95ac1f44edf1a893 AS weaver
FROM python:3.13.3-slim-bullseye@sha256:9e3f9243e06fd68eb9519074b49878eda20ad39a855fac51aaffb741de20726e AS python
FROM otel/weaver:v0.15.0@sha256:1cf1c72eaed57dad813c2e359133b8a15bd4facf305aae5b13bdca6d3eccff56 AS weaver
FROM avtodev/markdown-lint:v1@sha256:6aeedc2f49138ce7a1cd0adffc1b1c0321b841dc2102408967d9301c031949ee AS markdown

View File

@@ -1,30 +0,0 @@
#!/usr/bin/env bash
# Copyright The OpenTelemetry Authors
# SPDX-License-Identifier: Apache-2.0
set -euo pipefail
top_dir='.'
if [[ $# -gt 0 ]]; then
top_dir="${1}"
fi
p=$(pwd)
mod_dirs=()
# Note `mapfile` does not exist in older bash versions:
# https://stackoverflow.com/questions/41475261/need-alternative-to-readarray-mapfile-for-script-on-older-version-of-bash
while IFS= read -r line; do
mod_dirs+=("$line")
done < <(find "${top_dir}" -type f -name 'go.mod' -exec dirname {} \; | sort)
for mod_dir in "${mod_dirs[@]}"; do
cd "${mod_dir}"
while IFS= read -r line; do
echo ".${line#${p}}"
done < <(go list --find -f '{{.Name}}|{{.Dir}}' ./... | grep '^main|' | cut -f 2- -d '|')
cd "${p}"
done

View File

@@ -1,18 +0,0 @@
// Copyright The OpenTelemetry Authors
// SPDX-License-Identifier: Apache-2.0
package internal // import "go.opentelemetry.io/otel/internal"
//go:generate gotmpl --body=./shared/matchers/expectation.go.tmpl "--data={}" --out=matchers/expectation.go
//go:generate gotmpl --body=./shared/matchers/expecter.go.tmpl "--data={}" --out=matchers/expecter.go
//go:generate gotmpl --body=./shared/matchers/temporal_matcher.go.tmpl "--data={}" --out=matchers/temporal_matcher.go
//go:generate gotmpl --body=./shared/internaltest/alignment.go.tmpl "--data={}" --out=internaltest/alignment.go
//go:generate gotmpl --body=./shared/internaltest/env.go.tmpl "--data={}" --out=internaltest/env.go
//go:generate gotmpl --body=./shared/internaltest/env_test.go.tmpl "--data={}" --out=internaltest/env_test.go
//go:generate gotmpl --body=./shared/internaltest/errors.go.tmpl "--data={}" --out=internaltest/errors.go
//go:generate gotmpl --body=./shared/internaltest/harness.go.tmpl "--data={\"matchersImportPath\": \"go.opentelemetry.io/otel/internal/matchers\"}" --out=internaltest/harness.go
//go:generate gotmpl --body=./shared/internaltest/text_map_carrier.go.tmpl "--data={}" --out=internaltest/text_map_carrier.go
//go:generate gotmpl --body=./shared/internaltest/text_map_carrier_test.go.tmpl "--data={}" --out=internaltest/text_map_carrier_test.go
//go:generate gotmpl --body=./shared/internaltest/text_map_propagator.go.tmpl "--data={}" --out=internaltest/text_map_propagator.go
//go:generate gotmpl --body=./shared/internaltest/text_map_propagator_test.go.tmpl "--data={}" --out=internaltest/text_map_propagator_test.go

View File

@@ -1,6 +1,7 @@
// Copyright The OpenTelemetry Authors
// SPDX-License-Identifier: Apache-2.0
// Package global provides the OpenTelemetry global API.
package global // import "go.opentelemetry.io/otel/internal/global"
import (

View File

@@ -169,7 +169,10 @@ func (m *meter) Int64Counter(name string, options ...metric.Int64CounterOption)
return i, nil
}
func (m *meter) Int64UpDownCounter(name string, options ...metric.Int64UpDownCounterOption) (metric.Int64UpDownCounter, error) {
func (m *meter) Int64UpDownCounter(
name string,
options ...metric.Int64UpDownCounterOption,
) (metric.Int64UpDownCounter, error) {
m.mtx.Lock()
defer m.mtx.Unlock()
@@ -238,7 +241,10 @@ func (m *meter) Int64Gauge(name string, options ...metric.Int64GaugeOption) (met
return i, nil
}
func (m *meter) Int64ObservableCounter(name string, options ...metric.Int64ObservableCounterOption) (metric.Int64ObservableCounter, error) {
func (m *meter) Int64ObservableCounter(
name string,
options ...metric.Int64ObservableCounterOption,
) (metric.Int64ObservableCounter, error) {
m.mtx.Lock()
defer m.mtx.Unlock()
@@ -261,7 +267,10 @@ func (m *meter) Int64ObservableCounter(name string, options ...metric.Int64Obser
return i, nil
}
func (m *meter) Int64ObservableUpDownCounter(name string, options ...metric.Int64ObservableUpDownCounterOption) (metric.Int64ObservableUpDownCounter, error) {
func (m *meter) Int64ObservableUpDownCounter(
name string,
options ...metric.Int64ObservableUpDownCounterOption,
) (metric.Int64ObservableUpDownCounter, error) {
m.mtx.Lock()
defer m.mtx.Unlock()
@@ -284,7 +293,10 @@ func (m *meter) Int64ObservableUpDownCounter(name string, options ...metric.Int6
return i, nil
}
func (m *meter) Int64ObservableGauge(name string, options ...metric.Int64ObservableGaugeOption) (metric.Int64ObservableGauge, error) {
func (m *meter) Int64ObservableGauge(
name string,
options ...metric.Int64ObservableGaugeOption,
) (metric.Int64ObservableGauge, error) {
m.mtx.Lock()
defer m.mtx.Unlock()
@@ -330,7 +342,10 @@ func (m *meter) Float64Counter(name string, options ...metric.Float64CounterOpti
return i, nil
}
func (m *meter) Float64UpDownCounter(name string, options ...metric.Float64UpDownCounterOption) (metric.Float64UpDownCounter, error) {
func (m *meter) Float64UpDownCounter(
name string,
options ...metric.Float64UpDownCounterOption,
) (metric.Float64UpDownCounter, error) {
m.mtx.Lock()
defer m.mtx.Unlock()
@@ -353,7 +368,10 @@ func (m *meter) Float64UpDownCounter(name string, options ...metric.Float64UpDow
return i, nil
}
func (m *meter) Float64Histogram(name string, options ...metric.Float64HistogramOption) (metric.Float64Histogram, error) {
func (m *meter) Float64Histogram(
name string,
options ...metric.Float64HistogramOption,
) (metric.Float64Histogram, error) {
m.mtx.Lock()
defer m.mtx.Unlock()
@@ -399,7 +417,10 @@ func (m *meter) Float64Gauge(name string, options ...metric.Float64GaugeOption)
return i, nil
}
func (m *meter) Float64ObservableCounter(name string, options ...metric.Float64ObservableCounterOption) (metric.Float64ObservableCounter, error) {
func (m *meter) Float64ObservableCounter(
name string,
options ...metric.Float64ObservableCounterOption,
) (metric.Float64ObservableCounter, error) {
m.mtx.Lock()
defer m.mtx.Unlock()
@@ -422,7 +443,10 @@ func (m *meter) Float64ObservableCounter(name string, options ...metric.Float64O
return i, nil
}
func (m *meter) Float64ObservableUpDownCounter(name string, options ...metric.Float64ObservableUpDownCounterOption) (metric.Float64ObservableUpDownCounter, error) {
func (m *meter) Float64ObservableUpDownCounter(
name string,
options ...metric.Float64ObservableUpDownCounterOption,
) (metric.Float64ObservableUpDownCounter, error) {
m.mtx.Lock()
defer m.mtx.Unlock()
@@ -445,7 +469,10 @@ func (m *meter) Float64ObservableUpDownCounter(name string, options ...metric.Fl
return i, nil
}
func (m *meter) Float64ObservableGauge(name string, options ...metric.Float64ObservableGaugeOption) (metric.Float64ObservableGauge, error) {
func (m *meter) Float64ObservableGauge(
name string,
options ...metric.Float64ObservableGaugeOption,
) (metric.Float64ObservableGauge, error) {
m.mtx.Lock()
defer m.mtx.Unlock()

View File

@@ -158,7 +158,18 @@ func (t *tracer) Start(ctx context.Context, name string, opts ...trace.SpanStart
// a nonRecordingSpan by default.
var autoInstEnabled = new(bool)
func (t *tracer) newSpan(ctx context.Context, autoSpan *bool, name string, opts []trace.SpanStartOption) (context.Context, trace.Span) {
// newSpan is called by tracer.Start so auto-instrumentation can attach an eBPF
// uprobe to this code.
//
// "noinline" pragma prevents the method from ever being inlined.
//
//go:noinline
func (t *tracer) newSpan(
ctx context.Context,
autoSpan *bool,
name string,
opts []trace.SpanStartOption,
) (context.Context, trace.Span) {
// autoInstEnabled is passed to newSpan via the autoSpan parameter. This is
// so the auto-instrumentation can define a uprobe for (*t).newSpan and be
// provided with the address of the bool autoInstEnabled points to. It

View File

@@ -1,48 +0,0 @@
// Copyright The OpenTelemetry Authors
// SPDX-License-Identifier: Apache-2.0
package internal // import "go.opentelemetry.io/otel/internal"
import (
"math"
"unsafe"
)
func BoolToRaw(b bool) uint64 { // nolint:revive // b is not a control flag.
if b {
return 1
}
return 0
}
func RawToBool(r uint64) bool {
return r != 0
}
func Int64ToRaw(i int64) uint64 {
// Assumes original was a valid int64 (overflow not checked).
return uint64(i) // nolint: gosec
}
func RawToInt64(r uint64) int64 {
// Assumes original was a valid int64 (overflow not checked).
return int64(r) // nolint: gosec
}
func Float64ToRaw(f float64) uint64 {
return math.Float64bits(f)
}
func RawToFloat64(r uint64) float64 {
return math.Float64frombits(r)
}
func RawPtrToFloat64Ptr(r *uint64) *float64 {
// Assumes original was a valid *float64 (overflow not checked).
return (*float64)(unsafe.Pointer(r)) // nolint: gosec
}
func RawPtrToInt64Ptr(r *uint64) *int64 {
// Assumes original was a valid *int64 (overflow not checked).
return (*int64)(unsafe.Pointer(r)) // nolint: gosec
}

View File

@@ -106,7 +106,9 @@ type Float64ObservableUpDownCounterConfig struct {
// NewFloat64ObservableUpDownCounterConfig returns a new
// [Float64ObservableUpDownCounterConfig] with all opts applied.
func NewFloat64ObservableUpDownCounterConfig(opts ...Float64ObservableUpDownCounterOption) Float64ObservableUpDownCounterConfig {
func NewFloat64ObservableUpDownCounterConfig(
opts ...Float64ObservableUpDownCounterOption,
) Float64ObservableUpDownCounterConfig {
var config Float64ObservableUpDownCounterConfig
for _, o := range opts {
config = o.applyFloat64ObservableUpDownCounter(config)
@@ -239,12 +241,16 @@ type float64CallbackOpt struct {
cback Float64Callback
}
func (o float64CallbackOpt) applyFloat64ObservableCounter(cfg Float64ObservableCounterConfig) Float64ObservableCounterConfig {
func (o float64CallbackOpt) applyFloat64ObservableCounter(
cfg Float64ObservableCounterConfig,
) Float64ObservableCounterConfig {
cfg.callbacks = append(cfg.callbacks, o.cback)
return cfg
}
func (o float64CallbackOpt) applyFloat64ObservableUpDownCounter(cfg Float64ObservableUpDownCounterConfig) Float64ObservableUpDownCounterConfig {
func (o float64CallbackOpt) applyFloat64ObservableUpDownCounter(
cfg Float64ObservableUpDownCounterConfig,
) Float64ObservableUpDownCounterConfig {
cfg.callbacks = append(cfg.callbacks, o.cback)
return cfg
}

View File

@@ -105,7 +105,9 @@ type Int64ObservableUpDownCounterConfig struct {
// NewInt64ObservableUpDownCounterConfig returns a new
// [Int64ObservableUpDownCounterConfig] with all opts applied.
func NewInt64ObservableUpDownCounterConfig(opts ...Int64ObservableUpDownCounterOption) Int64ObservableUpDownCounterConfig {
func NewInt64ObservableUpDownCounterConfig(
opts ...Int64ObservableUpDownCounterOption,
) Int64ObservableUpDownCounterConfig {
var config Int64ObservableUpDownCounterConfig
for _, o := range opts {
config = o.applyInt64ObservableUpDownCounter(config)
@@ -242,7 +244,9 @@ func (o int64CallbackOpt) applyInt64ObservableCounter(cfg Int64ObservableCounter
return cfg
}
func (o int64CallbackOpt) applyInt64ObservableUpDownCounter(cfg Int64ObservableUpDownCounterConfig) Int64ObservableUpDownCounterConfig {
func (o int64CallbackOpt) applyInt64ObservableUpDownCounter(
cfg Int64ObservableUpDownCounterConfig,
) Int64ObservableUpDownCounterConfig {
cfg.callbacks = append(cfg.callbacks, o.cback)
return cfg
}

View File

@@ -63,7 +63,9 @@ func (o descOpt) applyFloat64ObservableCounter(c Float64ObservableCounterConfig)
return c
}
func (o descOpt) applyFloat64ObservableUpDownCounter(c Float64ObservableUpDownCounterConfig) Float64ObservableUpDownCounterConfig {
func (o descOpt) applyFloat64ObservableUpDownCounter(
c Float64ObservableUpDownCounterConfig,
) Float64ObservableUpDownCounterConfig {
c.description = string(o)
return c
}
@@ -98,7 +100,9 @@ func (o descOpt) applyInt64ObservableCounter(c Int64ObservableCounterConfig) Int
return c
}
func (o descOpt) applyInt64ObservableUpDownCounter(c Int64ObservableUpDownCounterConfig) Int64ObservableUpDownCounterConfig {
func (o descOpt) applyInt64ObservableUpDownCounter(
c Int64ObservableUpDownCounterConfig,
) Int64ObservableUpDownCounterConfig {
c.description = string(o)
return c
}
@@ -138,7 +142,9 @@ func (o unitOpt) applyFloat64ObservableCounter(c Float64ObservableCounterConfig)
return c
}
func (o unitOpt) applyFloat64ObservableUpDownCounter(c Float64ObservableUpDownCounterConfig) Float64ObservableUpDownCounterConfig {
func (o unitOpt) applyFloat64ObservableUpDownCounter(
c Float64ObservableUpDownCounterConfig,
) Float64ObservableUpDownCounterConfig {
c.unit = string(o)
return c
}
@@ -173,7 +179,9 @@ func (o unitOpt) applyInt64ObservableCounter(c Int64ObservableCounterConfig) Int
return c
}
func (o unitOpt) applyInt64ObservableUpDownCounter(c Int64ObservableUpDownCounterConfig) Int64ObservableUpDownCounterConfig {
func (o unitOpt) applyInt64ObservableUpDownCounter(
c Int64ObservableUpDownCounterConfig,
) Int64ObservableUpDownCounterConfig {
c.unit = string(o)
return c
}

View File

@@ -110,7 +110,10 @@ type Meter interface {
// The name needs to conform to the OpenTelemetry instrument name syntax.
// See the Instrument Name section of the package documentation for more
// information.
Int64ObservableUpDownCounter(name string, options ...Int64ObservableUpDownCounterOption) (Int64ObservableUpDownCounter, error)
Int64ObservableUpDownCounter(
name string,
options ...Int64ObservableUpDownCounterOption,
) (Int64ObservableUpDownCounter, error)
// Int64ObservableGauge returns a new Int64ObservableGauge instrument
// identified by name and configured with options. The instrument is used
@@ -194,7 +197,10 @@ type Meter interface {
// The name needs to conform to the OpenTelemetry instrument name syntax.
// See the Instrument Name section of the package documentation for more
// information.
Float64ObservableUpDownCounter(name string, options ...Float64ObservableUpDownCounterOption) (Float64ObservableUpDownCounter, error)
Float64ObservableUpDownCounter(
name string,
options ...Float64ObservableUpDownCounterOption,
) (Float64ObservableUpDownCounter, error)
// Float64ObservableGauge returns a new Float64ObservableGauge instrument
// identified by name and configured with options. The instrument is used

View File

@@ -86,13 +86,19 @@ func (Meter) Int64Gauge(string, ...metric.Int64GaugeOption) (metric.Int64Gauge,
// Int64ObservableCounter returns an ObservableCounter used to record int64
// measurements that produces no telemetry.
func (Meter) Int64ObservableCounter(string, ...metric.Int64ObservableCounterOption) (metric.Int64ObservableCounter, error) {
func (Meter) Int64ObservableCounter(
string,
...metric.Int64ObservableCounterOption,
) (metric.Int64ObservableCounter, error) {
return Int64ObservableCounter{}, nil
}
// Int64ObservableUpDownCounter returns an ObservableUpDownCounter used to
// record int64 measurements that produces no telemetry.
func (Meter) Int64ObservableUpDownCounter(string, ...metric.Int64ObservableUpDownCounterOption) (metric.Int64ObservableUpDownCounter, error) {
func (Meter) Int64ObservableUpDownCounter(
string,
...metric.Int64ObservableUpDownCounterOption,
) (metric.Int64ObservableUpDownCounter, error) {
return Int64ObservableUpDownCounter{}, nil
}
@@ -128,19 +134,28 @@ func (Meter) Float64Gauge(string, ...metric.Float64GaugeOption) (metric.Float64G
// Float64ObservableCounter returns an ObservableCounter used to record int64
// measurements that produces no telemetry.
func (Meter) Float64ObservableCounter(string, ...metric.Float64ObservableCounterOption) (metric.Float64ObservableCounter, error) {
func (Meter) Float64ObservableCounter(
string,
...metric.Float64ObservableCounterOption,
) (metric.Float64ObservableCounter, error) {
return Float64ObservableCounter{}, nil
}
// Float64ObservableUpDownCounter returns an ObservableUpDownCounter used to
// record int64 measurements that produces no telemetry.
func (Meter) Float64ObservableUpDownCounter(string, ...metric.Float64ObservableUpDownCounterOption) (metric.Float64ObservableUpDownCounter, error) {
func (Meter) Float64ObservableUpDownCounter(
string,
...metric.Float64ObservableUpDownCounterOption,
) (metric.Float64ObservableUpDownCounter, error) {
return Float64ObservableUpDownCounter{}, nil
}
// Float64ObservableGauge returns an ObservableGauge used to record int64
// measurements that produces no telemetry.
func (Meter) Float64ObservableGauge(string, ...metric.Float64ObservableGaugeOption) (metric.Float64ObservableGauge, error) {
func (Meter) Float64ObservableGauge(
string,
...metric.Float64ObservableGaugeOption,
) (metric.Float64ObservableGauge, error) {
return Float64ObservableGauge{}, nil
}

View File

@@ -28,7 +28,21 @@ func (b Baggage) Inject(ctx context.Context, carrier TextMapCarrier) {
}
// Extract returns a copy of parent with the baggage from the carrier added.
// If carrier implements [ValuesGetter] (e.g. [HeaderCarrier]), Values is invoked
// for multiple values extraction. Otherwise, Get is called.
func (b Baggage) Extract(parent context.Context, carrier TextMapCarrier) context.Context {
if multiCarrier, ok := carrier.(ValuesGetter); ok {
return extractMultiBaggage(parent, multiCarrier)
}
return extractSingleBaggage(parent, carrier)
}
// Fields returns the keys who's values are set with Inject.
func (b Baggage) Fields() []string {
return []string{baggageHeader}
}
func extractSingleBaggage(parent context.Context, carrier TextMapCarrier) context.Context {
bStr := carrier.Get(baggageHeader)
if bStr == "" {
return parent
@@ -41,7 +55,23 @@ func (b Baggage) Extract(parent context.Context, carrier TextMapCarrier) context
return baggage.ContextWithBaggage(parent, bag)
}
// Fields returns the keys who's values are set with Inject.
func (b Baggage) Fields() []string {
return []string{baggageHeader}
func extractMultiBaggage(parent context.Context, carrier ValuesGetter) context.Context {
bVals := carrier.Values(baggageHeader)
if len(bVals) == 0 {
return parent
}
var members []baggage.Member
for _, bStr := range bVals {
currBag, err := baggage.Parse(bStr)
if err != nil {
continue
}
members = append(members, currBag.Members()...)
}
b, err := baggage.New(members...)
if err != nil || b.Len() == 0 {
return parent
}
return baggage.ContextWithBaggage(parent, b)
}

View File

@@ -9,6 +9,7 @@ import (
)
// TextMapCarrier is the storage medium used by a TextMapPropagator.
// See ValuesGetter for how a TextMapCarrier can get multiple values for a key.
type TextMapCarrier interface {
// DO NOT CHANGE: any modification will not be backwards compatible and
// must never be done outside of a new major release.
@@ -29,6 +30,18 @@ type TextMapCarrier interface {
// must never be done outside of a new major release.
}
// ValuesGetter can return multiple values for a single key,
// with contrast to TextMapCarrier.Get which returns a single value.
type ValuesGetter interface {
// DO NOT CHANGE: any modification will not be backwards compatible and
// must never be done outside of a new major release.
// Values returns all values associated with the passed key.
Values(key string) []string
// DO NOT CHANGE: any modification will not be backwards compatible and
// must never be done outside of a new major release.
}
// MapCarrier is a TextMapCarrier that uses a map held in memory as a storage
// medium for propagated key-value pairs.
type MapCarrier map[string]string
@@ -55,14 +68,25 @@ func (c MapCarrier) Keys() []string {
return keys
}
// HeaderCarrier adapts http.Header to satisfy the TextMapCarrier interface.
// HeaderCarrier adapts http.Header to satisfy the TextMapCarrier and ValuesGetter interfaces.
type HeaderCarrier http.Header
// Get returns the value associated with the passed key.
// Compile time check that HeaderCarrier implements ValuesGetter.
var _ TextMapCarrier = HeaderCarrier{}
// Compile time check that HeaderCarrier implements TextMapCarrier.
var _ ValuesGetter = HeaderCarrier{}
// Get returns the first value associated with the passed key.
func (hc HeaderCarrier) Get(key string) string {
return http.Header(hc).Get(key)
}
// Values returns all values associated with the passed key.
func (hc HeaderCarrier) Values(key string) []string {
return http.Header(hc).Values(key)
}
// Set stores the key-value pair.
func (hc HeaderCarrier) Set(key string, value string) {
http.Header(hc).Set(key, value)
@@ -89,6 +113,8 @@ type TextMapPropagator interface {
// must never be done outside of a new major release.
// Extract reads cross-cutting concerns from the carrier into a Context.
// Implementations may check if the carrier implements ValuesGetter,
// to support extraction of multiple values per key.
Extract(ctx context.Context, carrier TextMapCarrier) context.Context
// DO NOT CHANGE: any modification will not be backwards compatible and
// must never be done outside of a new major release.

View File

@@ -1,7 +1,8 @@
{
"$schema": "https://docs.renovatebot.com/renovate-schema.json",
"extends": [
"config:best-practices"
"config:best-practices",
"helpers:pinGitHubActionDigestsToSemver"
],
"ignorePaths": [],
"labels": ["Skip Changelog", "dependencies"],
@@ -25,6 +26,10 @@
{
"matchPackageNames": ["golang.org/x/**"],
"groupName": "golang.org/x"
},
{
"matchPackageNames": ["go.opentelemetry.io/otel/sdk/log/logtest"],
"enabled": false
}
]
}

View File

@@ -57,14 +57,15 @@ type autoTracer struct {
var _ Tracer = autoTracer{}
func (t autoTracer) Start(ctx context.Context, name string, opts ...SpanStartOption) (context.Context, Span) {
var psc SpanContext
var psc, sc SpanContext
sampled := true
span := new(autoSpan)
// Ask eBPF for sampling decision and span context info.
t.start(ctx, span, &psc, &sampled, &span.spanContext)
t.start(ctx, span, &psc, &sampled, &sc)
span.sampled.Store(sampled)
span.spanContext = sc
ctx = ContextWithSpan(ctx, span)

View File

@@ -251,13 +251,20 @@ func (s *Span) UnmarshalJSON(data []byte) error {
type SpanFlags int32
const (
// SpanFlagsTraceFlagsMask is a mask for trace-flags.
//
// Bits 0-7 are used for trace flags.
SpanFlagsTraceFlagsMask SpanFlags = 255
// Bits 8 and 9 are used to indicate that the parent span or link span is remote.
// Bit 8 (`HAS_IS_REMOTE`) indicates whether the value is known.
// Bit 9 (`IS_REMOTE`) indicates whether the span or link is remote.
// SpanFlagsContextHasIsRemoteMask is a mask for HAS_IS_REMOTE status.
//
// Bits 8 and 9 are used to indicate that the parent span or link span is
// remote. Bit 8 (`HAS_IS_REMOTE`) indicates whether the value is known.
SpanFlagsContextHasIsRemoteMask SpanFlags = 256
// SpanFlagsContextHasIsRemoteMask indicates the Span is remote.
// SpanFlagsContextIsRemoteMask is a mask for IS_REMOTE status.
//
// Bits 8 and 9 are used to indicate that the parent span or link span is
// remote. Bit 9 (`IS_REMOTE`) indicates whether the span or link is
// remote.
SpanFlagsContextIsRemoteMask SpanFlags = 512
)
@@ -266,27 +273,31 @@ const (
type SpanKind int32
const (
// Indicates that the span represents an internal operation within an application,
// as opposed to an operation happening at the boundaries. Default value.
// SpanKindInternal indicates that the span represents an internal
// operation within an application, as opposed to an operation happening at
// the boundaries.
SpanKindInternal SpanKind = 1
// Indicates that the span covers server-side handling of an RPC or other
// remote network request.
// SpanKindServer indicates that the span covers server-side handling of an
// RPC or other remote network request.
SpanKindServer SpanKind = 2
// Indicates that the span describes a request to some remote service.
// SpanKindClient indicates that the span describes a request to some
// remote service.
SpanKindClient SpanKind = 3
// Indicates that the span describes a producer sending a message to a broker.
// Unlike CLIENT and SERVER, there is often no direct critical path latency relationship
// between producer and consumer spans. A PRODUCER span ends when the message was accepted
// by the broker while the logical processing of the message might span a much longer time.
// SpanKindProducer indicates that the span describes a producer sending a
// message to a broker. Unlike SpanKindClient and SpanKindServer, there is
// often no direct critical path latency relationship between producer and
// consumer spans. A SpanKindProducer span ends when the message was
// accepted by the broker while the logical processing of the message might
// span a much longer time.
SpanKindProducer SpanKind = 4
// Indicates that the span describes consumer receiving a message from a broker.
// Like the PRODUCER kind, there is often no direct critical path latency relationship
// between producer and consumer spans.
// SpanKindConsumer indicates that the span describes a consumer receiving
// a message from a broker. Like SpanKindProducer, there is often no direct
// critical path latency relationship between producer and consumer spans.
SpanKindConsumer SpanKind = 5
)
// Event is a time-stamped annotation of the span, consisting of user-supplied
// text description and key-value pairs.
// SpanEvent is a time-stamped annotation of the span, consisting of
// user-supplied text description and key-value pairs.
type SpanEvent struct {
// time_unix_nano is the time the event occurred.
Time time.Time `json:"timeUnixNano,omitempty"`
@@ -369,10 +380,11 @@ func (se *SpanEvent) UnmarshalJSON(data []byte) error {
return nil
}
// A pointer from the current span to another span in the same trace or in a
// different trace. For example, this can be used in batching operations,
// where a single batch handler processes multiple requests from different
// traces or when the handler receives a request from a different project.
// SpanLink is a reference from the current span to another span in the same
// trace or in a different trace. For example, this can be used in batching
// operations, where a single batch handler processes multiple requests from
// different traces or when the handler receives a request from a different
// project.
type SpanLink struct {
// A unique identifier of a trace that this linked span is part of. The ID is a
// 16-byte array.

View File

@@ -3,17 +3,19 @@
package telemetry // import "go.opentelemetry.io/otel/trace/internal/telemetry"
// StatusCode is the status of a Span.
//
// For the semantics of status codes see
// https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/trace/api.md#set-status
type StatusCode int32
const (
// The default status.
// StatusCodeUnset is the default status.
StatusCodeUnset StatusCode = 0
// The Span has been validated by an Application developer or Operator to
// have completed successfully.
// StatusCodeOK is used when the Span has been validated by an Application
// developer or Operator to have completed successfully.
StatusCodeOK StatusCode = 1
// The Span contains an error.
// StatusCodeError is used when the Span contains an error.
StatusCodeError StatusCode = 2
)
@@ -30,7 +32,7 @@ func (s StatusCode) String() string {
return "<unknown telemetry.StatusCode>"
}
// The Status type defines a logical error model that is suitable for different
// Status defines a logical error model that is suitable for different
// programming environments, including REST APIs and RPC APIs.
type Status struct {
// A developer-facing human readable error message.

View File

@@ -71,7 +71,7 @@ func (td *Traces) UnmarshalJSON(data []byte) error {
return nil
}
// A collection of ScopeSpans from a Resource.
// ResourceSpans is a collection of ScopeSpans from a Resource.
type ResourceSpans struct {
// The resource for the spans in this message.
// If this field is not set then no resource info is known.
@@ -128,7 +128,7 @@ func (rs *ResourceSpans) UnmarshalJSON(data []byte) error {
return nil
}
// A collection of Spans produced by an InstrumentationScope.
// ScopeSpans is a collection of Spans produced by an InstrumentationScope.
type ScopeSpans struct {
// The instrumentation scope information for the spans in this message.
// Semantically when InstrumentationScope isn't set, it is equivalent with

View File

@@ -316,7 +316,7 @@ func (v Value) String() string {
case ValueKindBool:
return strconv.FormatBool(v.asBool())
case ValueKindBytes:
return fmt.Sprint(v.asBytes())
return string(v.asBytes())
case ValueKindMap:
return fmt.Sprint(v.asMap())
case ValueKindSlice:

View File

@@ -95,6 +95,8 @@ var autoInstEnabled = new(bool)
// tracerProvider return a noopTracerProvider if autoEnabled is false,
// otherwise it will return a TracerProvider from the sdk package used in
// auto-instrumentation.
//
//go:noinline
func (noopSpan) tracerProvider(autoEnabled *bool) TracerProvider {
if *autoEnabled {
return newAutoTracerProvider()

View File

@@ -1,21 +0,0 @@
#!/bin/bash
# Copyright The OpenTelemetry Authors
# SPDX-License-Identifier: Apache-2.0
set -euo pipefail
dirs=$(find . -type d -not -path "*/internal*" -not -path "*/test*" -not -path "*/example*" -not -path "*/.*" | sort)
missingReadme=false
for dir in $dirs; do
if [ ! -f "$dir/README.md" ]; then
echo "couldn't find README.md for $dir"
missingReadme=true
fi
done
if [ "$missingReadme" = true ] ; then
echo "Error: some READMEs couldn't be found."
exit 1
fi

View File

@@ -5,5 +5,5 @@ package otel // import "go.opentelemetry.io/otel"
// Version is the current release version of OpenTelemetry in use.
func Version() string {
return "1.35.0"
return "1.36.0"
}

View File

@@ -3,7 +3,7 @@
module-sets:
stable-v1:
version: v1.35.0
version: v1.36.0
modules:
- go.opentelemetry.io/otel
- go.opentelemetry.io/otel/bridge/opencensus
@@ -23,11 +23,11 @@ module-sets:
- go.opentelemetry.io/otel/sdk/metric
- go.opentelemetry.io/otel/trace
experimental-metrics:
version: v0.57.0
version: v0.58.0
modules:
- go.opentelemetry.io/otel/exporters/prometheus
experimental-logs:
version: v0.11.0
version: v0.12.0
modules:
- go.opentelemetry.io/otel/log
- go.opentelemetry.io/otel/sdk/log
@@ -40,4 +40,6 @@ module-sets:
- go.opentelemetry.io/otel/schema
excluded-modules:
- go.opentelemetry.io/otel/internal/tools
- go.opentelemetry.io/otel/log/logtest
- go.opentelemetry.io/otel/sdk/log/logtest
- go.opentelemetry.io/otel/trace/internal/telemetry/test

View File

@@ -360,6 +360,10 @@ type Balancer interface {
// call SubConn.Shutdown for its existing SubConns; however, this will be
// required in a future release, so it is recommended.
Close()
// ExitIdle instructs the LB policy to reconnect to backends / exit the
// IDLE state, if appropriate and possible. Note that SubConns that enter
// the IDLE state will not reconnect until SubConn.Connect is called.
ExitIdle()
}
// ExitIdler is an optional interface for balancers to implement. If
@@ -367,8 +371,8 @@ type Balancer interface {
// the ClientConn is idle. If unimplemented, ClientConn.Connect will cause
// all SubConns to connect.
//
// Notice: it will be required for all balancers to implement this in a future
// release.
// Deprecated: All balancers must implement this interface. This interface will
// be removed in a future release.
type ExitIdler interface {
// ExitIdle instructs the LB policy to reconnect to backends / exit the
// IDLE state, if appropriate and possible. Note that SubConns that enter

View File

@@ -45,7 +45,15 @@ type ChildState struct {
// Balancer exposes only the ExitIdler interface of the child LB policy.
// Other methods of the child policy are called only by endpointsharding.
Balancer balancer.ExitIdler
Balancer ExitIdler
}
// ExitIdler provides access to only the ExitIdle method of the child balancer.
type ExitIdler interface {
// ExitIdle instructs the LB policy to reconnect to backends / exit the
// IDLE state, if appropriate and possible. Note that SubConns that enter
// the IDLE state will not reconnect until SubConn.Connect is called.
ExitIdle()
}
// Options are the options to configure the behaviour of the
@@ -205,6 +213,16 @@ func (es *endpointSharding) Close() {
}
}
func (es *endpointSharding) ExitIdle() {
es.childMu.Lock()
defer es.childMu.Unlock()
for _, bw := range es.children.Load().Values() {
if !bw.isClosed {
bw.child.ExitIdle()
}
}
}
// updateState updates this component's state. It sends the aggregated state,
// and a picker with round robin behavior with all the child states present if
// needed.
@@ -326,15 +344,13 @@ func (bw *balancerWrapper) UpdateState(state balancer.State) {
// ExitIdle pings an IDLE child balancer to exit idle in a new goroutine to
// avoid deadlocks due to synchronous balancer state updates.
func (bw *balancerWrapper) ExitIdle() {
if ei, ok := bw.child.(balancer.ExitIdler); ok {
go func() {
bw.es.childMu.Lock()
if !bw.isClosed {
ei.ExitIdle()
}
bw.es.childMu.Unlock()
}()
}
go func() {
bw.es.childMu.Lock()
if !bw.isClosed {
bw.child.ExitIdle()
}
bw.es.childMu.Unlock()
}()
}
// updateClientConnStateLocked delivers the ClientConnState to the child

View File

@@ -54,18 +54,9 @@ func init() {
balancer.Register(pickfirstBuilder{})
}
type (
// enableHealthListenerKeyType is a unique key type used in resolver
// attributes to indicate whether the health listener usage is enabled.
enableHealthListenerKeyType struct{}
// managedByPickfirstKeyType is an attribute key type to inform Outlier
// Detection that the generic health listener is being used.
// TODO: https://github.com/grpc/grpc-go/issues/7915 - Remove this when
// implementing the dualstack design. This is a hack. Once Dualstack is
// completed, outlier detection will stop sending ejection updates through
// the connectivity listener.
managedByPickfirstKeyType struct{}
)
// enableHealthListenerKeyType is a unique key type used in resolver
// attributes to indicate whether the health listener usage is enabled.
type enableHealthListenerKeyType struct{}
var (
logger = grpclog.Component("pick-first-leaf-lb")
@@ -149,17 +140,6 @@ func EnableHealthListener(state resolver.State) resolver.State {
return state
}
// IsManagedByPickfirst returns whether an address belongs to a SubConn
// managed by the pickfirst LB policy.
// TODO: https://github.com/grpc/grpc-go/issues/7915 - This is a hack to disable
// outlier_detection via the with connectivity listener when using pick_first.
// Once Dualstack changes are complete, all SubConns will be created by
// pick_first and outlier detection will only use the health listener for
// ejection. This hack can then be removed.
func IsManagedByPickfirst(addr resolver.Address) bool {
return addr.BalancerAttributes.Value(managedByPickfirstKeyType{}) != nil
}
type pfConfig struct {
serviceconfig.LoadBalancingConfig `json:"-"`
@@ -186,7 +166,6 @@ type scData struct {
}
func (b *pickfirstBalancer) newSCData(addr resolver.Address) (*scData, error) {
addr.BalancerAttributes = addr.BalancerAttributes.WithValue(managedByPickfirstKeyType{}, true)
sd := &scData{
rawConnectivityState: connectivity.Idle,
effectiveState: connectivity.Idle,

View File

@@ -70,10 +70,3 @@ func (b *rrBalancer) UpdateClientConnState(ccs balancer.ClientConnState) error {
ResolverState: pickfirstleaf.EnableHealthListener(ccs.ResolverState),
})
}
func (b *rrBalancer) ExitIdle() {
// Should always be ok, as child is endpoint sharding.
if ei, ok := b.Balancer.(balancer.ExitIdler); ok {
ei.ExitIdle()
}
}

View File

@@ -213,6 +213,7 @@ func WithReadBufferSize(s int) DialOption {
func WithInitialWindowSize(s int32) DialOption {
return newFuncDialOption(func(o *dialOptions) {
o.copts.InitialWindowSize = s
o.copts.StaticWindowSize = true
})
}
@@ -222,6 +223,26 @@ func WithInitialWindowSize(s int32) DialOption {
func WithInitialConnWindowSize(s int32) DialOption {
return newFuncDialOption(func(o *dialOptions) {
o.copts.InitialConnWindowSize = s
o.copts.StaticWindowSize = true
})
}
// WithStaticStreamWindowSize returns a DialOption which sets the initial
// stream window size to the value provided and disables dynamic flow control.
func WithStaticStreamWindowSize(s int32) DialOption {
return newFuncDialOption(func(o *dialOptions) {
o.copts.InitialWindowSize = s
o.copts.StaticWindowSize = true
})
}
// WithStaticConnWindowSize returns a DialOption which sets the initial
// connection window size to the value provided and disables dynamic flow
// control.
func WithStaticConnWindowSize(s int32) DialOption {
return newFuncDialOption(func(o *dialOptions) {
o.copts.InitialConnWindowSize = s
o.copts.StaticWindowSize = true
})
}

View File

@@ -223,15 +223,7 @@ func (gsb *Balancer) ExitIdle() {
// There is no need to protect this read with a mutex, as the write to the
// Balancer field happens in SwitchTo, which completes before this can be
// called.
if ei, ok := balToUpdate.Balancer.(balancer.ExitIdler); ok {
ei.ExitIdle()
return
}
gsb.mu.Lock()
defer gsb.mu.Unlock()
for sc := range balToUpdate.subconns {
sc.Connect()
}
balToUpdate.ExitIdle()
}
// updateSubConnState forwards the update to the appropriate child.

View File

@@ -33,10 +33,6 @@ var (
// "GRPC_RING_HASH_CAP". This does not override the default bounds
// checking which NACKs configs specifying ring sizes > 8*1024*1024 (~8M).
RingHashCap = uint64FromEnv("GRPC_RING_HASH_CAP", 4096, 1, 8*1024*1024)
// LeastRequestLB is set if we should support the least_request_experimental
// LB policy, which can be enabled by setting the environment variable
// "GRPC_EXPERIMENTAL_ENABLE_LEAST_REQUEST" to "true".
LeastRequestLB = boolFromEnv("GRPC_EXPERIMENTAL_ENABLE_LEAST_REQUEST", true)
// ALTSMaxConcurrentHandshakes is the maximum number of concurrent ALTS
// handshakes that can be performed.
ALTSMaxConcurrentHandshakes = uint64FromEnv("GRPC_ALTS_MAX_CONCURRENT_HANDSHAKES", 100, 1, 100)

View File

@@ -40,6 +40,13 @@ var updateHeaderTblSize = func(e *hpack.Encoder, v uint32) {
e.SetMaxDynamicTableSizeLimit(v)
}
// itemNodePool is used to reduce heap allocations.
var itemNodePool = sync.Pool{
New: func() any {
return &itemNode{}
},
}
type itemNode struct {
it any
next *itemNode
@@ -51,7 +58,9 @@ type itemList struct {
}
func (il *itemList) enqueue(i any) {
n := &itemNode{it: i}
n := itemNodePool.Get().(*itemNode)
n.next = nil
n.it = i
if il.tail == nil {
il.head, il.tail = n, n
return
@@ -71,7 +80,9 @@ func (il *itemList) dequeue() any {
return nil
}
i := il.head.it
temp := il.head
il.head = il.head.next
itemNodePool.Put(temp)
if il.head == nil {
il.tail = nil
}
@@ -146,10 +157,11 @@ type earlyAbortStream struct {
func (*earlyAbortStream) isTransportResponseFrame() bool { return false }
type dataFrame struct {
streamID uint32
endStream bool
h []byte
reader mem.Reader
streamID uint32
endStream bool
h []byte
data mem.BufferSlice
processing bool
// onEachWrite is called every time
// a part of data is written out.
onEachWrite func()
@@ -234,6 +246,7 @@ type outStream struct {
itl *itemList
bytesOutStanding int
wq *writeQuota
reader mem.Reader
next *outStream
prev *outStream
@@ -461,7 +474,9 @@ func (c *controlBuffer) finish() {
v.onOrphaned(ErrConnClosing)
}
case *dataFrame:
_ = v.reader.Close()
if !v.processing {
v.data.Free()
}
}
}
@@ -650,10 +665,11 @@ func (l *loopyWriter) incomingSettingsHandler(s *incomingSettings) error {
func (l *loopyWriter) registerStreamHandler(h *registerStream) {
str := &outStream{
id: h.streamID,
state: empty,
itl: &itemList{},
wq: h.wq,
id: h.streamID,
state: empty,
itl: &itemList{},
wq: h.wq,
reader: mem.BufferSlice{}.Reader(),
}
l.estdStreams[h.streamID] = str
}
@@ -685,10 +701,11 @@ func (l *loopyWriter) headerHandler(h *headerFrame) error {
}
// Case 2: Client wants to originate stream.
str := &outStream{
id: h.streamID,
state: empty,
itl: &itemList{},
wq: h.wq,
id: h.streamID,
state: empty,
itl: &itemList{},
wq: h.wq,
reader: mem.BufferSlice{}.Reader(),
}
return l.originateStream(str, h)
}
@@ -790,10 +807,13 @@ func (l *loopyWriter) cleanupStreamHandler(c *cleanupStream) error {
// a RST_STREAM before stream initialization thus the stream might
// not be established yet.
delete(l.estdStreams, c.streamID)
str.reader.Close()
str.deleteSelf()
for head := str.itl.dequeueAll(); head != nil; head = head.next {
if df, ok := head.it.(*dataFrame); ok {
_ = df.reader.Close()
if !df.processing {
df.data.Free()
}
}
}
}
@@ -928,7 +948,13 @@ func (l *loopyWriter) processData() (bool, error) {
if str == nil {
return true, nil
}
reader := str.reader
dataItem := str.itl.peek().(*dataFrame) // Peek at the first data item this stream.
if !dataItem.processing {
dataItem.processing = true
str.reader.Reset(dataItem.data)
dataItem.data.Free()
}
// A data item is represented by a dataFrame, since it later translates into
// multiple HTTP2 data frames.
// Every dataFrame has two buffers; h that keeps grpc-message header and data
@@ -936,13 +962,13 @@ func (l *loopyWriter) processData() (bool, error) {
// from data is copied to h to make as big as the maximum possible HTTP2 frame
// size.
if len(dataItem.h) == 0 && dataItem.reader.Remaining() == 0 { // Empty data frame
if len(dataItem.h) == 0 && reader.Remaining() == 0 { // Empty data frame
// Client sends out empty data frame with endStream = true
if err := l.framer.fr.WriteData(dataItem.streamID, dataItem.endStream, nil); err != nil {
return false, err
}
str.itl.dequeue() // remove the empty data item from stream
_ = dataItem.reader.Close()
_ = reader.Close()
if str.itl.isEmpty() {
str.state = empty
} else if trailer, ok := str.itl.peek().(*headerFrame); ok { // the next item is trailers.
@@ -971,8 +997,8 @@ func (l *loopyWriter) processData() (bool, error) {
}
// Compute how much of the header and data we can send within quota and max frame length
hSize := min(maxSize, len(dataItem.h))
dSize := min(maxSize-hSize, dataItem.reader.Remaining())
remainingBytes := len(dataItem.h) + dataItem.reader.Remaining() - hSize - dSize
dSize := min(maxSize-hSize, reader.Remaining())
remainingBytes := len(dataItem.h) + reader.Remaining() - hSize - dSize
size := hSize + dSize
var buf *[]byte
@@ -993,7 +1019,7 @@ func (l *loopyWriter) processData() (bool, error) {
defer pool.Put(buf)
copy((*buf)[:hSize], dataItem.h)
_, _ = dataItem.reader.Read((*buf)[hSize:])
_, _ = reader.Read((*buf)[hSize:])
}
// Now that outgoing flow controls are checked we can replenish str's write quota
@@ -1014,7 +1040,7 @@ func (l *loopyWriter) processData() (bool, error) {
dataItem.h = dataItem.h[hSize:]
if remainingBytes == 0 { // All the data from that message was written out.
_ = dataItem.reader.Close()
_ = reader.Close()
str.itl.dequeue()
}
if str.itl.isEmpty() {

View File

@@ -309,11 +309,9 @@ func NewHTTP2Client(connectCtx, ctx context.Context, addr resolver.Address, opts
scheme = "https"
}
}
dynamicWindow := true
icwz := int32(initialWindowSize)
if opts.InitialConnWindowSize >= defaultWindowSize {
icwz = opts.InitialConnWindowSize
dynamicWindow = false
}
writeBufSize := opts.WriteBufferSize
readBufSize := opts.ReadBufferSize
@@ -381,9 +379,8 @@ func NewHTTP2Client(connectCtx, ctx context.Context, addr resolver.Address, opts
t.controlBuf = newControlBuffer(t.ctxDone)
if opts.InitialWindowSize >= defaultWindowSize {
t.initialWindowSize = opts.InitialWindowSize
dynamicWindow = false
}
if dynamicWindow {
if !opts.StaticWindowSize {
t.bdpEst = &bdpEstimator{
bdp: initialWindowSize,
updateFlowControl: t.updateFlowControl,
@@ -1091,32 +1088,29 @@ func (t *http2Client) GracefulClose() {
// Write formats the data into HTTP2 data frame(s) and sends it out. The caller
// should proceed only if Write returns nil.
func (t *http2Client) write(s *ClientStream, hdr []byte, data mem.BufferSlice, opts *WriteOptions) error {
reader := data.Reader()
if opts.Last {
// If it's the last message, update stream state.
if !s.compareAndSwapState(streamActive, streamWriteDone) {
_ = reader.Close()
return errStreamDone
}
} else if s.getState() != streamActive {
_ = reader.Close()
return errStreamDone
}
df := &dataFrame{
streamID: s.id,
endStream: opts.Last,
h: hdr,
reader: reader,
data: data,
}
if hdr != nil || df.reader.Remaining() != 0 { // If it's not an empty data frame, check quota.
if err := s.wq.get(int32(len(hdr) + df.reader.Remaining())); err != nil {
_ = reader.Close()
dataLen := data.Len()
if hdr != nil || dataLen != 0 { // If it's not an empty data frame, check quota.
if err := s.wq.get(int32(len(hdr) + dataLen)); err != nil {
return err
}
}
data.Ref()
if err := t.controlBuf.put(df); err != nil {
_ = reader.Close()
data.Free()
return err
}
t.incrMsgSent()

View File

@@ -132,6 +132,10 @@ type http2Server struct {
maxStreamID uint32 // max stream ID ever seen
logger *grpclog.PrefixLogger
// setResetPingStrikes is stored as a closure instead of making this a
// method on http2Server to avoid a heap allocation when converting a method
// to a closure for passing to frames objects.
setResetPingStrikes func()
}
// NewServerTransport creates a http2 transport with conn and configuration
@@ -176,16 +180,13 @@ func NewServerTransport(conn net.Conn, config *ServerConfig) (_ ServerTransport,
Val: config.MaxStreams,
})
}
dynamicWindow := true
iwz := int32(initialWindowSize)
if config.InitialWindowSize >= defaultWindowSize {
iwz = config.InitialWindowSize
dynamicWindow = false
}
icwz := int32(initialWindowSize)
if config.InitialConnWindowSize >= defaultWindowSize {
icwz = config.InitialConnWindowSize
dynamicWindow = false
}
if iwz != defaultWindowSize {
isettings = append(isettings, http2.Setting{
@@ -266,6 +267,9 @@ func NewServerTransport(conn net.Conn, config *ServerConfig) (_ ServerTransport,
initialWindowSize: iwz,
bufferPool: config.BufferPool,
}
t.setResetPingStrikes = func() {
atomic.StoreUint32(&t.resetPingStrikes, 1)
}
var czSecurity credentials.ChannelzSecurityValue
if au, ok := authInfo.(credentials.ChannelzSecurityInfo); ok {
czSecurity = au.GetSecurityValue()
@@ -285,7 +289,7 @@ func NewServerTransport(conn net.Conn, config *ServerConfig) (_ ServerTransport,
t.logger = prefixLoggerForServerTransport(t)
t.controlBuf = newControlBuffer(t.done)
if dynamicWindow {
if !config.StaticWindowSize {
t.bdpEst = &bdpEstimator{
bdp: initialWindowSize,
updateFlowControl: t.updateFlowControl,
@@ -596,10 +600,25 @@ func (t *http2Server) operateHeaders(ctx context.Context, frame *http2.MetaHeade
return nil
}
}
if s.ctx.Err() != nil {
t.mu.Unlock()
// Early abort in case the timeout was zero or so low it already fired.
t.controlBuf.put(&earlyAbortStream{
httpStatus: http.StatusOK,
streamID: s.id,
contentSubtype: s.contentSubtype,
status: status.New(codes.DeadlineExceeded, context.DeadlineExceeded.Error()),
rst: !frame.StreamEnded(),
})
return nil
}
t.activeStreams[streamID] = s
if len(t.activeStreams) == 1 {
t.idle = time.Time{}
}
// Start a timer to close the stream on reaching the deadline.
if timeoutSet {
// We need to wait for s.cancel to be updated before calling
@@ -1016,10 +1035,6 @@ func (t *http2Server) writeHeader(s *ServerStream, md metadata.MD) error {
return nil
}
func (t *http2Server) setResetPingStrikes() {
atomic.StoreUint32(&t.resetPingStrikes, 1)
}
func (t *http2Server) writeHeaderLocked(s *ServerStream) error {
// TODO(mmukhi): Benchmark if the performance gets better if count the metadata and other header fields
// first and create a slice of that exact size.
@@ -1132,17 +1147,13 @@ func (t *http2Server) writeStatus(s *ServerStream, st *status.Status) error {
// Write converts the data into HTTP2 data frame and sends it out. Non-nil error
// is returns if it fails (e.g., framing error, transport error).
func (t *http2Server) write(s *ServerStream, hdr []byte, data mem.BufferSlice, _ *WriteOptions) error {
reader := data.Reader()
if !s.isHeaderSent() { // Headers haven't been written yet.
if err := t.writeHeader(s, nil); err != nil {
_ = reader.Close()
return err
}
} else {
// Writing headers checks for this condition.
if s.getState() == streamDone {
_ = reader.Close()
return t.streamContextErr(s)
}
}
@@ -1150,15 +1161,16 @@ func (t *http2Server) write(s *ServerStream, hdr []byte, data mem.BufferSlice, _
df := &dataFrame{
streamID: s.id,
h: hdr,
reader: reader,
data: data,
onEachWrite: t.setResetPingStrikes,
}
if err := s.wq.get(int32(len(hdr) + df.reader.Remaining())); err != nil {
_ = reader.Close()
dataLen := data.Len()
if err := s.wq.get(int32(len(hdr) + dataLen)); err != nil {
return t.streamContextErr(s)
}
data.Ref()
if err := t.controlBuf.put(df); err != nil {
_ = reader.Close()
data.Free()
return err
}
t.incrMsgSent()

View File

@@ -200,9 +200,6 @@ func decodeTimeout(s string) (time.Duration, error) {
if err != nil {
return 0, err
}
if t == 0 {
return 0, fmt.Errorf("transport: timeout must be positive: %q", s)
}
const maxHours = math.MaxInt64 / uint64(time.Hour)
if d == time.Hour && t > maxHours {
// This timeout would overflow math.MaxInt64; clamp it.

View File

@@ -466,6 +466,7 @@ type ServerConfig struct {
MaxHeaderListSize *uint32
HeaderTableSize *uint32
BufferPool mem.BufferPool
StaticWindowSize bool
}
// ConnectOptions covers all relevant options for communicating with the server.
@@ -504,6 +505,8 @@ type ConnectOptions struct {
MaxHeaderListSize *uint32
// The mem.BufferPool to use when reading/writing to the wire.
BufferPool mem.BufferPool
// StaticWindowSize controls whether dynamic window sizing is enabled.
StaticWindowSize bool
}
// WriteOptions provides additional hints and information for message

View File

@@ -137,6 +137,9 @@ type Reader interface {
Close() error
// Remaining returns the number of unread bytes remaining in the slice.
Remaining() int
// Reset frees the currently held buffer slice and starts reading from the
// provided slice. This allows reusing the reader object.
Reset(s BufferSlice)
}
type sliceReader struct {
@@ -150,6 +153,14 @@ func (r *sliceReader) Remaining() int {
return r.len
}
func (r *sliceReader) Reset(s BufferSlice) {
r.data.Free()
s.Ref()
r.data = s
r.len = s.Len()
r.bufferIdx = 0
}
func (r *sliceReader) Close() error {
r.data.Free()
r.data = nil

View File

@@ -179,6 +179,7 @@ type serverOptions struct {
numServerWorkers uint32
bufferPool mem.BufferPool
waitForHandlers bool
staticWindowSize bool
}
var defaultServerOptions = serverOptions{
@@ -279,6 +280,7 @@ func ReadBufferSize(s int) ServerOption {
func InitialWindowSize(s int32) ServerOption {
return newFuncServerOption(func(o *serverOptions) {
o.initialWindowSize = s
o.staticWindowSize = true
})
}
@@ -287,6 +289,29 @@ func InitialWindowSize(s int32) ServerOption {
func InitialConnWindowSize(s int32) ServerOption {
return newFuncServerOption(func(o *serverOptions) {
o.initialConnWindowSize = s
o.staticWindowSize = true
})
}
// StaticStreamWindowSize returns a ServerOption to set the initial stream
// window size to the value provided and disables dynamic flow control.
// The lower bound for window size is 64K and any value smaller than that
// will be ignored.
func StaticStreamWindowSize(s int32) ServerOption {
return newFuncServerOption(func(o *serverOptions) {
o.initialWindowSize = s
o.staticWindowSize = true
})
}
// StaticConnWindowSize returns a ServerOption to set the initial connection
// window size to the value provided and disables dynamic flow control.
// The lower bound for window size is 64K and any value smaller than that
// will be ignored.
func StaticConnWindowSize(s int32) ServerOption {
return newFuncServerOption(func(o *serverOptions) {
o.initialConnWindowSize = s
o.staticWindowSize = true
})
}
@@ -986,6 +1011,7 @@ func (s *Server) newHTTP2Transport(c net.Conn) transport.ServerTransport {
MaxHeaderListSize: s.opts.maxHeaderListSize,
HeaderTableSize: s.opts.headerTableSize,
BufferPool: s.opts.bufferPool,
StaticWindowSize: s.opts.staticWindowSize,
}
st, err := transport.NewServerTransport(c, config)
if err != nil {

View File

@@ -1171,7 +1171,7 @@ func (a *csAttempt) recvMsg(m any, payInfo *payloadInfo) (err error) {
} else if err != nil {
return toRPCErr(err)
}
return toRPCErr(errors.New("grpc: client streaming protocol violation: get <nil>, want <EOF>"))
return status.Errorf(codes.Internal, "cardinality violation: expected <EOF> for non server-streaming RPCs, but received another message")
}
func (a *csAttempt) finish(err error) {
@@ -1495,7 +1495,7 @@ func (as *addrConnStream) RecvMsg(m any) (err error) {
} else if err != nil {
return toRPCErr(err)
}
return toRPCErr(errors.New("grpc: client streaming protocol violation: get <nil>, want <EOF>"))
return status.Errorf(codes.Internal, "cardinality violation: expected <EOF> for non server-streaming RPCs, but received another message")
}
func (as *addrConnStream) finish(err error) {

View File

@@ -19,4 +19,4 @@
package grpc
// Version is the current grpc version.
const Version = "1.73.0"
const Version = "1.74.2"

19
vendor/modules.txt vendored
View File

@@ -484,26 +484,25 @@ go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/internal/request
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/internal/semconv
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/internal/semconvutil
# go.opentelemetry.io/otel v1.35.0
## explicit; go 1.22.0
# go.opentelemetry.io/otel v1.36.0
## explicit; go 1.23.0
go.opentelemetry.io/otel
go.opentelemetry.io/otel/attribute
go.opentelemetry.io/otel/attribute/internal
go.opentelemetry.io/otel/baggage
go.opentelemetry.io/otel/codes
go.opentelemetry.io/otel/internal
go.opentelemetry.io/otel/internal/attribute
go.opentelemetry.io/otel/internal/baggage
go.opentelemetry.io/otel/internal/global
go.opentelemetry.io/otel/propagation
go.opentelemetry.io/otel/semconv/v1.20.0
go.opentelemetry.io/otel/semconv/v1.26.0
# go.opentelemetry.io/otel/metric v1.35.0
## explicit; go 1.22.0
# go.opentelemetry.io/otel/metric v1.36.0
## explicit; go 1.23.0
go.opentelemetry.io/otel/metric
go.opentelemetry.io/otel/metric/embedded
go.opentelemetry.io/otel/metric/noop
# go.opentelemetry.io/otel/trace v1.35.0
## explicit; go 1.22.0
# go.opentelemetry.io/otel/trace v1.36.0
## explicit; go 1.23.0
go.opentelemetry.io/otel/trace
go.opentelemetry.io/otel/trace/embedded
go.opentelemetry.io/otel/trace/internal/telemetry
@@ -565,10 +564,10 @@ golang.org/x/text/width
# golang.org/x/time v0.11.0
## explicit; go 1.23.0
golang.org/x/time/rate
# google.golang.org/genproto/googleapis/rpc v0.0.0-20250324211829-b45e905df463
# google.golang.org/genproto/googleapis/rpc v0.0.0-20250528174236-200df99c418a
## explicit; go 1.23.0
google.golang.org/genproto/googleapis/rpc/status
# google.golang.org/grpc v1.73.0
# google.golang.org/grpc v1.74.2
## explicit; go 1.23.0
google.golang.org/grpc
google.golang.org/grpc/attributes