### Added
- Add `Reset` method to `SpanRecorder` in
`go.opentelemetry.io/otel/sdk/trace/tracetest`. (#5994)
- Add `EnabledInstrument` interface in
`go.opentelemetry.io/otel/sdk/metric/internal/x`. This is an
experimental interface that is implemented by synchronous instruments
provided by `go.opentelemetry.io/otel/sdk/metric`. Users can use it to
avoid performing computationally expensive operations when recording
measurements. It does not fall within the scope of the OpenTelemetry Go
versioning and stability [policy](./VERSIONING.md) and it may be changed
in backwards incompatible ways or removed in feature releases. (#6016)
### Changed
- The default global API now supports full auto-instrumentation from the
`go.opentelemetry.io/auto` package. See that package for more
information. (#5920)
- Propagate non-retryable error messages to client in
`go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp`. (#5929)
- Propagate non-retryable error messages to client in
`go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp`.
(#5929)
- Propagate non-retryable error messages to client in
`go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp`.
(#5929)
- Performance improvements for attribute value `AsStringSlice`,
`AsFloat64Slice`, `AsInt64Slice`, `AsBoolSlice`. (#6011)
- Change `EnabledParameters` to have a `Severity` field instead of a
getter and setter in `go.opentelemetry.io/otel/log`. (#6009)
### Fixed
- Fix inconsistent request body closing in
`go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp`. (#5954)
- Fix inconsistent request body closing in
`go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp`.
(#5954)
- Fix inconsistent request body closing in
`go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp`.
(#5954)
- Fix invalid exemplar keys in
`go.opentelemetry.io/otel/exporters/prometheus`. (#5995)
- Fix attribute value truncation in
`go.opentelemetry.io/otel/sdk/trace`. (#5997)
- Fix attribute value truncation in `go.opentelemetry.io/otel/sdk/log`.
(#6032)
Good day,
This PR changes As[Bool|Int64|Float64|String]Slice to use a little less
reflection.
The benchstat result of this is as follows.
```
goos: linux
goarch: amd64
pkg: go.opentelemetry.io/otel/internal/attribute
cpu: AMD Ryzen 7 Pro 7735U with Radeon Graphics
│ org.txt │ new.txt │
│ sec/op │ sec/op vs base │
AsFloat64Slice-16 373.3n ± 41% 181.0n ± 42% -51.51% (p=0.000 n=10)
│ org.txt │ new.txt │
│ B/op │ B/op vs base │
AsFloat64Slice-16 64.00 ± 0% 40.00 ± 0% -37.50% (p=0.000 n=10)
│ org.txt │ new.txt │
│ allocs/op │ allocs/op vs base │
AsFloat64Slice-16 3.000 ± 0% 2.000 ± 0% -33.33% (p=0.000 n=10)
```
---------
Co-authored-by: Damien Mathieu <42@dmathieu.com>
Fix#5996
### Correctness
From the [OTel
specification](88bffeac48/specification/common/README.md (attribute-limits)):
> - set an attribute value length limit such that for each attribute
value:
> - if it is a string, if it exceeds that limit (counting any character
in it as 1), SDKs MUST truncate that value, so that its length is at
most equal to the limit...
Our current implementation truncates on number of bytes not characters.
Unit tests are added/updated to validate this fix and prevent
regressions.
### Performance
```
goos: linux
goarch: amd64
pkg: go.opentelemetry.io/otel/sdk/trace
cpu: Intel(R) Core(TM) i7-8550U CPU @ 1.80GHz
│ commit-b6264913(old).txt │ commit-54c61ac2(new).txt │
│ sec/op │ sec/op vs base │
Truncate/Unlimited-8 1.2300n ± 7% 0.8757n ± 3% -28.80% (p=0.000 n=10)
Truncate/Zero-8 2.341n ± 2% 1.550n ± 9% -33.77% (p=0.000 n=10)
Truncate/Short-8 31.6800n ± 3% 0.9960n ± 4% -96.86% (p=0.000 n=10)
Truncate/ASCII-8 8.821n ± 1% 3.567n ± 3% -59.57% (p=0.000 n=10)
Truncate/ValidUTF-8-8 11.960n ± 1% 7.163n ± 1% -40.10% (p=0.000 n=10)
Truncate/InvalidUTF-8-8 56.35n ± 0% 37.34n ± 18% -33.74% (p=0.000 n=10)
Truncate/MixedUTF-8-8 81.83n ± 1% 50.00n ± 1% -38.90% (p=0.000 n=10)
geomean 12.37n 4.865n -60.68%
│ commit-b6264913(old).txt │ commit-54c61ac2(new).txt │
│ B/op │ B/op vs base │
Truncate/Unlimited-8 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹
Truncate/Zero-8 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹
Truncate/Short-8 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹
Truncate/ASCII-8 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹
Truncate/ValidUTF-8-8 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹
Truncate/InvalidUTF-8-8 16.00 ± 0% 16.00 ± 0% ~ (p=1.000 n=10) ¹
Truncate/MixedUTF-8-8 32.00 ± 0% 32.00 ± 0% ~ (p=1.000 n=10) ¹
geomean ² +0.00% ²
¹ all samples are equal
² summaries must be >0 to compute geomean
│ commit-b6264913(old).txt │ commit-54c61ac2(new).txt │
│ allocs/op │ allocs/op vs base │
Truncate/Unlimited-8 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹
Truncate/Zero-8 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹
Truncate/Short-8 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹
Truncate/ASCII-8 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹
Truncate/ValidUTF-8-8 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹
Truncate/InvalidUTF-8-8 1.000 ± 0% 1.000 ± 0% ~ (p=1.000 n=10) ¹
Truncate/MixedUTF-8-8 1.000 ± 0% 1.000 ± 0% ~ (p=1.000 n=10) ¹
geomean ² +0.00% ²
¹ all samples are equal
² summaries must be >0 to compute geomean
```
#### Values shorter than limit
This is the default code path. Most attribute values will be shorter
than the default 128 limit that users will not modify.
The current code, `safeTruncate` requires a full iteration of the value
to determine it is valid and under the limit.
The replacement, `truncate`, first checks if the number of bytes in the
value are less than or equal to the limit (which guarantees the number
of characters are less than or equal to the limit) and returns
immediately. This will mean that invalid encoding less than the limit is
not changed, which meets the specification requirements.
#### Values longer than the limit
For values who's number of bytes exceeds the limit, they are iterated
only once with the replacement, `truncate`.
In comparison, the current code, `safeTruncate`, can iterate the string
up to three separate times when the string contains invalid characters.
When the auto-instrumentation attaches to a process using the global
TracerProvider, and there has not been a delegate set, create a span
from the go.opentelemetry.io/auto/sdk package so the OTel Go
auto-instrumentation can instrument the application by default.
Resolve#5702
### Benchmarks
```terminal
goos: linux
goarch: amd64
pkg: go.opentelemetry.io/otel/internal/global
cpu: Intel(R) Core(TM) i7-8550U CPU @ 1.80GHz
│ old.txt │ new.txt │
│ sec/op │ sec/op vs base │
StartEndSpanNoSDK-8 244.2n ± 21% 250.2n ± 23% ~ (p=0.739 n=10)
```
PR #5541 (and issue #5536) enhance error handling, returning body text
as part of the error. However, this is only done for retryable errors;
if non-retryable, error text still does not propagate to clients.
This PR adds handling of non-retryable errors, ensuring any body text is
part of the message returned to the user's code. There is no change to
the circumstances under which errors are reported, just an enhancement
of the content of such an error.
---------
Co-authored-by: Damien Mathieu <42@dmathieu.com>
There were inconsistencies in closing the response body. For traces, the
Close happened in a defer statement and any error was logged. Logs and
metrics were less rigorous. It appeared Close() wasn't always called,
and when it was, errors were returned sometimes and ignored at other
times.
This applies the defer logic from traces to the other two and removes
other Close() calls.
This was part of PR #5929, and has been split out as
requested:
https://github.com/open-telemetry/opentelemetry-go/pull/5929#issuecomment-2446153958).
### Added
- Add `go.opentelemetry.io/otel/sdk/metric/exemplar.AlwaysOffFilter`,
which can be used to disable exemplar recording. (#5850)
- Add `go.opentelemetry.io/otel/sdk/metric.WithExemplarFilter`, which
can be used to configure the exemplar filter used by the metrics SDK.
(#5850)
- Add `ExemplarReservoirProviderSelector` and
`DefaultExemplarReservoirProviderSelector` to
`go.opentelemetry.io/otel/sdk/metric`, which defines the exemplar
reservoir to use based on the aggregation of the metric. (#5861)
- Add `ExemplarReservoirProviderSelector` to
`go.opentelemetry.io/otel/sdk/metric.Stream` to allow using views to
configure the exemplar reservoir to use for a metric. (#5861)
- Add `ReservoirProvider`, `HistogramReservoirProvider` and
`FixedSizeReservoirProvider` to
`go.opentelemetry.io/otel/sdk/metric/exemplar` to make it convenient to
use providers of Reservoirs. (#5861)
- The `go.opentelemetry.io/otel/semconv/v1.27.0` package.
The package contains semantic conventions from the `v1.27.0` version of
the OpenTelemetry Semantic Conventions. (#5894)
- Add `Attributes attribute.Set` field to `Scope` in
`go.opentelemetry.io/otel/sdk/instrumentation`. (#5903)
- Add `Attributes attribute.Set` field to `ScopeRecords` in
`go.opentelemetry.io/otel/log/logtest`. (#5927)
- `go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc` adds
instrumentation scope attributes. (#5934)
- `go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp` adds
instrumentation scope attributes. (#5934)
- `go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc`
adds instrumentation scope attributes. (#5935)
- `go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp`
adds instrumentation scope attributes. (#5935)
- `go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc` adds
instrumentation scope attributes. (#5933)
- `go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp` adds
instrumentation scope attributes. (#5933)
- `go.opentelemetry.io/otel/exporters/prometheus` adds instrumentation
scope attributes in `otel_scope_info` metric as labels. (#5932)
### Changed
- Support scope attributes and make them as identifying for `Tracer` in
`go.opentelemetry.io/otel` and `go.opentelemetry.io/otel/sdk/trace`.
(#5924)
- Support scope attributes and make them as identifying for `Meter` in
`go.opentelemetry.io/otel` and `go.opentelemetry.io/otel/sdk/metric`.
(#5926)
- Support scope attributes and make them as identifying for `Logger` in
`go.opentelemetry.io/otel` and `go.opentelemetry.io/otel/sdk/log`.
(#5925)
- Make schema URL and scope attributes as identifying for `Tracer` in
`go.opentelemetry.io/otel/bridge/opentracing`. (#5931)
- Clear unneeded slice elements to allow GC to collect the objects in
`go.opentelemetry.io/otel/sdk/metric` and
`go.opentelemetry.io/otel/sdk/trace`. (#5804)
### Fixed
- Global MeterProvider registration unwraps global instrument Observers,
the undocumented Unwrap() methods are now private. (#5881)
- `go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc`
now keeps the metadata already present in the context when `WithHeaders`
is used. (#5892)
- `go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc` now
keeps the metadata already present in the context when `WithHeaders` is
used. (#5911)
- `go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc` now
keeps the metadata already present in the context when `WithHeaders` is
used. (#5915)
- Fix `go.opentelemetry.io/otel/exporters/prometheus` trying to add
exemplars to Gauge metrics, which is unsupported. (#5912)
- Fix `WithEndpointURL` to always use a secure connection when an https
URL is passed in
`go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc`.
(#5944)
- Fix `WithEndpointURL` to always use a secure connection when an https
URL is passed in
`go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp`.
(#5944)
- Fix `WithEndpointURL` to always use a secure connection when an https
URL is passed in
`go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc`.
(#5944)
- Fix `WithEndpointURL` to always use a secure connection when an https
URL is passed in
`go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp`.
(#5944)
- Fix incorrect metrics generated from callbacks when multiple readers
are used in `go.opentelemetry.io/otel/sdk/metric`. (#5900)
### Removed
- Remove all examples under `go.opentelemetry.io/otel/example` as they
are moved to [Contrib
repository](https://github.com/open-telemetry/opentelemetry-go-contrib/tree/main/examples).
(#5930)
```go
type interInst struct {
x int
}
type inter interface {
}
var sink []inter
func BenchmarkX(b *testing.B) {
sink = make([]inter, b.N)
for i := 0; i < b.N; i++ {
sink[i] = &interInst{}
}
clear(sink)
sink = sink[:0]
runtime.GC()
var ms runtime.MemStats
runtime.ReadMemStats(&ms)
b.Log(b.N, ms.Frees) // Frees is the cumulative count of heap objects freed.
}
```
```
clear:
ioz_test.go:35: 1 589
ioz_test.go:35: 100 711
ioz_test.go:35: 10000 10729
ioz_test.go:35: 1000000 1010750 <-- 1m+ freed
ioz_test.go:35: 16076874 17087643
ioz_test.go:35: 19514749 36602412
```
```
no clear:
ioz_test.go:35: 1 585
ioz_test.go:35: 100 606
ioz_test.go:35: 10000 725
ioz_test.go:35: 1000000 10745 <-- some "overhead" objects freed, not the slice.
ioz_test.go:35: 16391445 1010765
ioz_test.go:35: 21765238 17402230
```
This is documented at https://go.dev/wiki/SliceTricks:
> NOTE If the type of the element is a pointer or a struct with pointer
fields, which need to be garbage collected, the above implementations of
Cut and Delete have a potential memory leak problem: some elements with
values are still referenced by slice a’s underlying array, just not
“visible” in the slice. Because the “deleted” value is referenced in the
underlying array, the deleted value is still “reachable” during GC, even
though the value cannot be referenced by your code. If the underlying
array is long-lived, this represents a leak.
Followed by examples of how zeroing out the slice elements solves
the problem. This PR does the same.
When an endpoint is set in both Environment variable with "http" and
passed in WithEndpointURL with "https", Insecure is set to true while
the endpoint is used from WithEndpointURL.
Example
- OTEL_EXPORTER_OTLP_ENDPOINT is set to "http://env.endpoint/prefix"
- WithEndpointURL is passed "https://someendpoint/somepath"
The real endpoint used is "http://someendpoint/somepath", which is
actually neither of both.
---------
Co-authored-by: Robert Pająk <pellared@hotmail.com>
Prometheus Gauge metrics don't support exemplars and while
`addGaugeMetric()` doesn't add them, `addSumMetric()` will if the metric
is monotonic. This causes the prometheus client to throw an error:
```
* error collecting metric Desc{fqName: "http_server_request_body_size_bytes", help: "Measures size of RPC request messages (uncompressed).", constLabels: {}, variableLabels: {net_protocol_name,net_protocol_version,http_method,http_route,http_scheme,net_host_name,net_host_port,otel_scope_name,otel_scope_version}}: cannot inject exemplar into Gauge, Summary or Untyped
```
---------
Co-authored-by: Damien Mathieu <42@dmathieu.com>
Co-authored-by: David Ashpole <dashpole@google.com>
When using otlpmetricgrpc, we can inject metadata dynamically with
`metadata.AppendToOutgoingContext`. However when specifying headers with
`WithHeaders`, it becomes impossible to add additional metadata.
For example, the code below sends additional metadata in the header
```go
exp := otlpmetricgrpc.New(context.Background())
ctx := context.Background()
ctx = metadata.AppendToOutgoingContext(ctx, "dynamic-key", "value")
exp.Export(ctx, &metricdata.ResourceMetrics{}))
```
But when using `WithHeader` like below, no additional metadata will be
sent
```go
exp := otlpmetricgrpc.New(context.Background(), otlpmetricgrpc.WithHeaders("custom-key", "value"))
ctx := context.Background()
ctx = metadata.AppendToOutgoingContext(ctx, "dynamic-key", "value")
exp.Export(ctx, &metricdata.ResourceMetrics{}))
```
To eliminate this inconsistency, keep the metadata in the context and
send them in the header.
---------
Co-authored-by: Tyler Yahn <MrAlias@users.noreply.github.com>
~Two defects are fixed here. However, note that async instrument
delegation appears to have been broken a long time.~
Internalizes and tests the behavior of the Global MeterProvider. This
moves the call to `Unwrap()` out of the SDK, fully concealing it within
the internal/global package (using an un-exported method).
This adds a test for the new functionality. While this test is not
comprehensive, because it doesn't test every instrument variation, it
explicitly tests that both the NewCallback function and the Observe
functions receive objects constructed by the alternate SDK.
Fixes#5827
---------
Co-authored-by: David Ashpole <dashpole@google.com>
Co-authored-by: Robert Pająk <pellared@hotmail.com>
Resolve https://github.com/open-telemetry/opentelemetry-go/issues/5249
### Spec
> exemplar_reservoir: A functional type that generates an exemplar
reservoir a MeterProvider will use when storing exemplars. This
functional type needs to be a factory or callback similar to aggregation
selection functionality which allows different reservoirs to be chosen
by the aggregation.
> Users can provide an exemplar_reservoir, but it is up to their
discretion. Therefore, the stream configuration parameter needs to be
structured to accept an exemplar_reservoir, but MUST NOT obligate a user
to provide one. If the user does not provide an exemplar_reservoir
value, the MeterProvider MUST apply a [default exemplar
reservoir](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/sdk.md#exemplar-defaults).
Also,
> the reservoir MUST be given the Attributes associated with its
timeseries point either at construction so that additional sampling
performed by the reservoir has access to all attributes from a
measurement in the "offer" method.
### Changes
In sdk/metric/exemplar, add:
* `exemplar.ReservoirProvider`
* `exemplar.HistogramReservoirProvider`
* `exemplar.FixedSizeReservoirProvider`
In sdk/metric, add:
* `metric.ExemplarReservoirProviderSelector` (func Aggregation ->
ReservoirProvider)
* `metric.DefaultExemplarReservoirProviderSelector` (our default
implementation)
* `ExemplarReservoirProviderSelector` added to `metric.Stream`
Note: the only required public types are
`metric.ExemplarReservoirProviderSelector` and
`ExemplarReservoirProviderSelector` in `metric.Stream`. Others are for
convenience and readability.
### Alternatives considered
#### Add ExemplarReservoirProvider directly to metric.Stream, instead of
ExemplarReservoirProviderSelector
This would mean users can configure a `func() exemplar.Reservoir`
instead of a `func(Aggregation) func() exemplar.Reservoir`.
I don't think this complies with the statement: `This functional type
needs to be a factory or callback similar to aggregation selection
functionality which allows different reservoirs to be chosen by the
aggregation.`. I'm interpreting "allows different reservoirs to be
chosen by the aggregation" as meaning "allows different reservoirs to be
chosen **based on the** aggregation", rather than meaning that the
aggregation is somehow choosing the reservoir.
### Future work
There is some refactoring I plan to do after this to simplify the
interaction between the internal/aggregate and exemplar package. I've
omitted that from this PR to keep the diff smaller.
---------
Co-authored-by: Tyler Yahn <MrAlias@users.noreply.github.com>
Co-authored-by: Robert Pająk <pellared@hotmail.com>
### Added
- Add `go.opentelemetry.io/otel/sdk/metric/exemplar` package which
includes `Exemplar`, `Filter`, `TraceBasedFilter`, `AlwaysOnFilter`,
`HistogramReservoir`, `FixedSizeReservoir`, `Reservoir`, `Value` and
`ValueType` types. These will be used for configuring the exemplar
reservoir for the metrics sdk. (#5747, #5862)
- Add `WithExportBufferSize` option to log batch processor.(#5877)
### Changed
- Enable exemplars by default in `go.opentelemetry.io/otel/sdk/metric`.
Exemplars can be disabled by setting
`OTEL_METRICS_EXEMPLAR_FILTER=always_off` (#5778)
- `Logger.Enabled` in `go.opentelemetry.io/otel/log` now accepts a newly
introduced `EnabledParameters` type instead of `Record`. (#5791)
- `FilterProcessor.Enabled` in
`go.opentelemetry.io/otel/sdk/log/internal/x` now accepts
`EnabledParameters` instead of `Record`. (#5791)
- The `Record` type in `go.opentelemetry.io/otel/log` is no longer
comparable. (#5847)
- Performance improvements for the trace SDK `SetAttributes` method in
`Span`. (#5864)
- Reduce memory allocations for the `Event` and `Link` lists in `Span`.
(#5858)
- Performance improvements for the trace SDK `AddEvent`, `AddLink`,
`RecordError` and `End` methods in `Span`. (#5874)
### Deprecated
- Deprecate all examples under `go.opentelemetry.io/otel/example` as
they are moved to [Contrib
repository](https://github.com/open-telemetry/opentelemetry-go-contrib/tree/main/examples).
(#5854)
### Fixed
- The race condition for multiple `FixedSize` exemplar reservoirs
identified in #5814 is resolved. (#5819)
- Fix log records duplication in case of heterogeneous resource
attributes by correctly mapping each log record to it's resource and
scope. (#5803)
- Fix timer channel drain to avoid hanging on Go 1.23. (#5868)
- Fix delegation for global meter providers, and panic when calling
otel.SetMeterProvider. (#5827)
- Change the `reflect.TypeOf` to use a nil pointer to not allocate on
the heap unless necessary. (#5827)
Good day,
While working on
https://github.com/open-telemetry/opentelemetry-go/pull/5858 I found
some other possible improvements.
This PR:
- Adds an early return to `SetAttributes` when no attributes are
provided.
- Only increases `s.attributes` to guarantee that there is enough space
for elements to be added.
- Fixes and issue where `truncateAttr` was not used when a attribute was
being updated in `addOverCapAttrs`.
Thanks for reviewing and please let me know if any changes are needed.
---------
Co-authored-by: Damien Mathieu <42@dmathieu.com>
The specification calls this filter "TraceBased":
https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/sdk.md#tracebased
I don't have a huge preference between the two, but lean towards
TraceBasedFilter to match the specification, and to match our
environment variable configuration (and probably the future file
configuration).
This PR must be merged or closed prior to the v1.31 release, since we
can't change it after the release.
---------
Co-authored-by: Tyler Yahn <MrAlias@users.noreply.github.com>
Part of https://github.com/open-telemetry/opentelemetry-go/issues/5249
This makes all existing types designed to implement the public Exemplar
API public by moving most of `internal/exemplar` to `exemplar`. The only
types that are not being made public are `exemplar.Drop`, and
`exemplar.FilteredReservoir`. Those types are moved to
`internal/aggregate`, and are renamed to `DropReservoir` and
`FilteredExemplarReservoir`.
The following types are made public:
* `exemplar.Exemplar`
* `exemplar.Filter`
* `exemplar.SampledFilter`
* `exemplar.AlwaysOnFilter`
* `exemplar.HistogramReservoir`
* `exemplar.FixedSizeReservoir`
* `exemplar.Reservoir`
* `exemplar.Value`
* `exemplar.ValueType`
Instead of using a global random number generator for all `randRes`,
have each value use its own. This removes the need for locking and
managing concurrent safe access to the global. Also, the field, given
the `Reservoir` type is not concurrent safe and the metric pipeline
guards this, does not need a `sync.Mutex` to guard it.
Supersedes https://github.com/open-telemetry/opentelemetry-go/pull/5815Fix#5814
### Performance Analysis
This change has approximately equivalent performance as the existing
code based on existing benchmarks.
```terminal
goos: linux
goarch: amd64
pkg: go.opentelemetry.io/otel/sdk/metric
cpu: Intel(R) Core(TM) i7-8550U CPU @ 1.80GHz
│ old.txt │ new.txt │
│ sec/op │ sec/op vs base │
Exemplars/Int64Counter/8-8 14.00µ ± 3% 13.44µ ± 4% -3.98% (p=0.001 n=10)
│ old.txt │ new.txt │
│ B/op │ B/op vs base │
Exemplars/Int64Counter/8-8 3.791Ki ± 0% 3.791Ki ± 0% ~ (p=1.000 n=10) ¹
¹ all samples are equal
│ old.txt │ new.txt │
│ allocs/op │ allocs/op vs base │
Exemplars/Int64Counter/8-8 84.00 ± 0% 84.00 ± 0% ~ (p=1.000 n=10) ¹
¹ all samples are equal
```
### Added
- Support `OTEL_EXPORTER_OTLP_LOGS_INSECURE` and
`OTEL_EXPORTER_OTLP_INSECURE` environments in
`go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc`. (#5739)
- The `WithResource` option for `NewMeterProvider` now merges the
provided resources with the ones from environment variables. (#5773)
- The `WithResource` option for `NewLoggerProvider` now merges the
provided resources with the ones from environment variables. (#5773)
- Add UTF-8 support to `go.opentelemetry.io/otel/exporters/prometheus`.
(#5755)
### Fixed
- Fix memory leak in the global `MeterProvider` when identical
instruments are repeatedly created. (#5754)
- Fix panic instruments creation when setting meter provider. (#5758)
- Fix panic on instruments creation when setting meter provider. (#5758)
- Fix an issue where `SetMeterProvider` in `go.opentelemetry.io/otel`
might miss the delegation for instruments and registries. (#5780)
### Removed
- Drop support for [Go 1.21](https://go.dev/doc/go1.21). (#5736, #5740,
#5800)