summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--go.mod1
-rw-r--r--go.sum2
-rw-r--r--internal/observability/metrics.go7
-rw-r--r--vendor/go.opentelemetry.io/contrib/instrumentation/runtime/LICENSE201
-rw-r--r--vendor/go.opentelemetry.io/contrib/instrumentation/runtime/doc.go34
-rw-r--r--vendor/go.opentelemetry.io/contrib/instrumentation/runtime/internal/deprecatedruntime/doc.go22
-rw-r--r--vendor/go.opentelemetry.io/contrib/instrumentation/runtime/internal/deprecatedruntime/runtime.go296
-rw-r--r--vendor/go.opentelemetry.io/contrib/instrumentation/runtime/internal/x/README.md38
-rw-r--r--vendor/go.opentelemetry.io/contrib/instrumentation/runtime/internal/x/x.go53
-rw-r--r--vendor/go.opentelemetry.io/contrib/instrumentation/runtime/options.go99
-rw-r--r--vendor/go.opentelemetry.io/contrib/instrumentation/runtime/producer.go120
-rw-r--r--vendor/go.opentelemetry.io/contrib/instrumentation/runtime/runtime.go229
-rw-r--r--vendor/go.opentelemetry.io/contrib/instrumentation/runtime/version.go17
-rw-r--r--vendor/modules.txt5
14 files changed, 1124 insertions, 0 deletions
diff --git a/go.mod b/go.mod
index d809ff56d..755601231 100644
--- a/go.mod
+++ b/go.mod
@@ -73,6 +73,7 @@ require (
github.com/wagslane/go-password-validator v0.3.0
github.com/yuin/goldmark v1.7.11
go.opentelemetry.io/contrib/exporters/autoexport v0.60.0
+ go.opentelemetry.io/contrib/instrumentation/runtime v0.60.0
go.opentelemetry.io/otel v1.35.0
go.opentelemetry.io/otel/metric v1.35.0
go.opentelemetry.io/otel/sdk v1.35.0
diff --git a/go.sum b/go.sum
index c4770d31d..57fa44caa 100644
--- a/go.sum
+++ b/go.sum
@@ -495,6 +495,8 @@ go.opentelemetry.io/contrib/bridges/prometheus v0.60.0 h1:x7sPooQCwSg27SjtQee8Gy
go.opentelemetry.io/contrib/bridges/prometheus v0.60.0/go.mod h1:4K5UXgiHxV484efGs42ejD7E2J/sIlepYgdGoPXe7hE=
go.opentelemetry.io/contrib/exporters/autoexport v0.60.0 h1:GuQXpvSXNjpswpweIem84U9BNauqHHi2w1GtNAalvpM=
go.opentelemetry.io/contrib/exporters/autoexport v0.60.0/go.mod h1:CkmxekdHco4d7thFJNPQ7Mby4jMBgZUclnrxT4e+ryk=
+go.opentelemetry.io/contrib/instrumentation/runtime v0.60.0 h1:0NgN/3SYkqYJ9NBlDfl/2lzVlwos/YQLvi8sUrzJRBE=
+go.opentelemetry.io/contrib/instrumentation/runtime v0.60.0/go.mod h1:oxpUfhTkhgQaYIjtBt3T3w135dLoxq//qo3WPlPIKkE=
go.opentelemetry.io/otel v1.35.0 h1:xKWKPxrxB6OtMCbmMY021CqC45J+3Onta9MqjhnusiQ=
go.opentelemetry.io/otel v1.35.0/go.mod h1:UEqy8Zp11hpkUrL73gSlELM0DupHoiq72dR+Zqel/+Y=
go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.11.0 h1:HMUytBT3uGhPKYY/u/G5MR9itrlSO2SMOsSD3Tk3k7A=
diff --git a/internal/observability/metrics.go b/internal/observability/metrics.go
index 785397834..09556dc77 100644
--- a/internal/observability/metrics.go
+++ b/internal/observability/metrics.go
@@ -29,6 +29,7 @@ import (
"github.com/gin-gonic/gin"
"github.com/technologize/otel-go-contrib/otelginmetrics"
"go.opentelemetry.io/contrib/exporters/autoexport"
+ "go.opentelemetry.io/contrib/instrumentation/runtime"
"go.opentelemetry.io/otel"
"go.opentelemetry.io/otel/metric"
sdk "go.opentelemetry.io/otel/sdk/metric"
@@ -59,6 +60,12 @@ func InitializeMetrics(ctx context.Context, db db.DB) error {
otel.SetMeterProvider(meterProvider)
+ if err := runtime.Start(
+ runtime.WithMeterProvider(meterProvider),
+ ); err != nil {
+ return err
+ }
+
meter := meterProvider.Meter(serviceName)
thisInstance := config.GetHost()
diff --git a/vendor/go.opentelemetry.io/contrib/instrumentation/runtime/LICENSE b/vendor/go.opentelemetry.io/contrib/instrumentation/runtime/LICENSE
new file mode 100644
index 000000000..261eeb9e9
--- /dev/null
+++ b/vendor/go.opentelemetry.io/contrib/instrumentation/runtime/LICENSE
@@ -0,0 +1,201 @@
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright [yyyy] [name of copyright owner]
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
diff --git a/vendor/go.opentelemetry.io/contrib/instrumentation/runtime/doc.go b/vendor/go.opentelemetry.io/contrib/instrumentation/runtime/doc.go
new file mode 100644
index 000000000..2b5e78686
--- /dev/null
+++ b/vendor/go.opentelemetry.io/contrib/instrumentation/runtime/doc.go
@@ -0,0 +1,34 @@
+// Copyright The OpenTelemetry Authors
+// SPDX-License-Identifier: Apache-2.0
+
+// Package runtime implements the conventional runtime metrics specified by OpenTelemetry.
+//
+// The metric events produced are:
+//
+// runtime.go.cgo.calls - Number of cgo calls made by the current process
+// runtime.go.gc.count - Number of completed garbage collection cycles
+// runtime.go.gc.pause_ns (ns) Amount of nanoseconds in GC stop-the-world pauses
+// runtime.go.gc.pause_total_ns (ns) Cumulative nanoseconds in GC stop-the-world pauses since the program started
+// runtime.go.goroutines - Number of goroutines that currently exist
+// runtime.go.lookups - Number of pointer lookups performed by the runtime
+// runtime.go.mem.heap_alloc (bytes) Bytes of allocated heap objects
+// runtime.go.mem.heap_idle (bytes) Bytes in idle (unused) spans
+// runtime.go.mem.heap_inuse (bytes) Bytes in in-use spans
+// runtime.go.mem.heap_objects - Number of allocated heap objects
+// runtime.go.mem.heap_released (bytes) Bytes of idle spans whose physical memory has been returned to the OS
+// runtime.go.mem.heap_sys (bytes) Bytes of heap memory obtained from the OS
+// runtime.go.mem.live_objects - Number of live objects is the number of cumulative Mallocs - Frees
+// runtime.uptime (ms) Milliseconds since application was initialized
+//
+// When the OTEL_GO_X_DEPRECATED_RUNTIME_METRICS environment variable is set to
+// false, the metrics produced are:
+//
+// go.memory.used By Memory used by the Go runtime.
+// go.memory.limit By Go runtime memory limit configured by the user, if a limit exists.
+// go.memory.allocated By Memory allocated to the heap by the application.
+// go.memory.allocations {allocation} Count of allocations to the heap by the application.
+// go.memory.gc.goal By Heap size target for the end of the GC cycle.
+// go.goroutine.count {goroutine} Count of live goroutines.
+// go.processor.limit {thread} The number of OS threads that can execute user-level Go code simultaneously.
+// go.config.gogc % Heap size target percentage configured by the user, otherwise 100.
+package runtime // import "go.opentelemetry.io/contrib/instrumentation/runtime"
diff --git a/vendor/go.opentelemetry.io/contrib/instrumentation/runtime/internal/deprecatedruntime/doc.go b/vendor/go.opentelemetry.io/contrib/instrumentation/runtime/internal/deprecatedruntime/doc.go
new file mode 100644
index 000000000..9fb44efa8
--- /dev/null
+++ b/vendor/go.opentelemetry.io/contrib/instrumentation/runtime/internal/deprecatedruntime/doc.go
@@ -0,0 +1,22 @@
+// Copyright The OpenTelemetry Authors
+// SPDX-License-Identifier: Apache-2.0
+
+// Package deprecatedruntime implements the deprecated runtime metrics for OpenTelemetry.
+//
+// The metric events produced are:
+//
+// runtime.go.cgo.calls - Number of cgo calls made by the current process
+// runtime.go.gc.count - Number of completed garbage collection cycles
+// runtime.go.gc.pause_ns (ns) Amount of nanoseconds in GC stop-the-world pauses
+// runtime.go.gc.pause_total_ns (ns) Cumulative nanoseconds in GC stop-the-world pauses since the program started
+// runtime.go.goroutines - Number of goroutines that currently exist
+// runtime.go.lookups - Number of pointer lookups performed by the runtime
+// runtime.go.mem.heap_alloc (bytes) Bytes of allocated heap objects
+// runtime.go.mem.heap_idle (bytes) Bytes in idle (unused) spans
+// runtime.go.mem.heap_inuse (bytes) Bytes in in-use spans
+// runtime.go.mem.heap_objects - Number of allocated heap objects
+// runtime.go.mem.heap_released (bytes) Bytes of idle spans whose physical memory has been returned to the OS
+// runtime.go.mem.heap_sys (bytes) Bytes of heap memory obtained from the OS
+// runtime.go.mem.live_objects - Number of live objects is the number of cumulative Mallocs - Frees
+// runtime.uptime (ms) Milliseconds since application was initialized
+package deprecatedruntime // import "go.opentelemetry.io/contrib/instrumentation/runtime/internal/deprecatedruntime"
diff --git a/vendor/go.opentelemetry.io/contrib/instrumentation/runtime/internal/deprecatedruntime/runtime.go b/vendor/go.opentelemetry.io/contrib/instrumentation/runtime/internal/deprecatedruntime/runtime.go
new file mode 100644
index 000000000..86c7c9e34
--- /dev/null
+++ b/vendor/go.opentelemetry.io/contrib/instrumentation/runtime/internal/deprecatedruntime/runtime.go
@@ -0,0 +1,296 @@
+// Copyright The OpenTelemetry Authors
+// SPDX-License-Identifier: Apache-2.0
+
+package deprecatedruntime // import "go.opentelemetry.io/contrib/instrumentation/runtime/internal/deprecatedruntime"
+
+import (
+ "context"
+ "math"
+ goruntime "runtime"
+ "sync"
+ "time"
+
+ "go.opentelemetry.io/otel/metric"
+)
+
+// Runtime reports the work-in-progress conventional runtime metrics specified by OpenTelemetry.
+type runtime struct {
+ minimumReadMemStatsInterval time.Duration
+ meter metric.Meter
+}
+
+// Start initializes reporting of runtime metrics using the supplied config.
+func Start(meter metric.Meter, minimumReadMemStatsInterval time.Duration) error {
+ r := &runtime{
+ meter: meter,
+ minimumReadMemStatsInterval: minimumReadMemStatsInterval,
+ }
+ return r.register()
+}
+
+func (r *runtime) register() error {
+ startTime := time.Now()
+ uptime, err := r.meter.Int64ObservableCounter(
+ "runtime.uptime",
+ metric.WithUnit("ms"),
+ metric.WithDescription("Milliseconds since application was initialized"),
+ )
+ if err != nil {
+ return err
+ }
+
+ goroutines, err := r.meter.Int64ObservableUpDownCounter(
+ "process.runtime.go.goroutines",
+ metric.WithDescription("Number of goroutines that currently exist"),
+ )
+ if err != nil {
+ return err
+ }
+
+ cgoCalls, err := r.meter.Int64ObservableUpDownCounter(
+ "process.runtime.go.cgo.calls",
+ metric.WithDescription("Number of cgo calls made by the current process"),
+ )
+ if err != nil {
+ return err
+ }
+
+ _, err = r.meter.RegisterCallback(
+ func(ctx context.Context, o metric.Observer) error {
+ o.ObserveInt64(uptime, time.Since(startTime).Milliseconds())
+ o.ObserveInt64(goroutines, int64(goruntime.NumGoroutine()))
+ o.ObserveInt64(cgoCalls, goruntime.NumCgoCall())
+ return nil
+ },
+ uptime,
+ goroutines,
+ cgoCalls,
+ )
+ if err != nil {
+ return err
+ }
+
+ return r.registerMemStats()
+}
+
+func (r *runtime) registerMemStats() error {
+ var (
+ err error
+
+ heapAlloc metric.Int64ObservableUpDownCounter
+ heapIdle metric.Int64ObservableUpDownCounter
+ heapInuse metric.Int64ObservableUpDownCounter
+ heapObjects metric.Int64ObservableUpDownCounter
+ heapReleased metric.Int64ObservableUpDownCounter
+ heapSys metric.Int64ObservableUpDownCounter
+ liveObjects metric.Int64ObservableUpDownCounter
+
+ // TODO: is ptrLookups useful? I've not seen a value
+ // other than zero.
+ ptrLookups metric.Int64ObservableCounter
+
+ gcCount metric.Int64ObservableCounter
+ pauseTotalNs metric.Int64ObservableCounter
+ gcPauseNs metric.Int64Histogram
+
+ lastNumGC uint32
+ lastMemStats time.Time
+ memStats goruntime.MemStats
+
+ // lock prevents a race between batch observer and instrument registration.
+ lock sync.Mutex
+ )
+
+ lock.Lock()
+ defer lock.Unlock()
+
+ if heapAlloc, err = r.meter.Int64ObservableUpDownCounter(
+ "process.runtime.go.mem.heap_alloc",
+ metric.WithUnit("By"),
+ metric.WithDescription("Bytes of allocated heap objects"),
+ ); err != nil {
+ return err
+ }
+
+ if heapIdle, err = r.meter.Int64ObservableUpDownCounter(
+ "process.runtime.go.mem.heap_idle",
+ metric.WithUnit("By"),
+ metric.WithDescription("Bytes in idle (unused) spans"),
+ ); err != nil {
+ return err
+ }
+
+ if heapInuse, err = r.meter.Int64ObservableUpDownCounter(
+ "process.runtime.go.mem.heap_inuse",
+ metric.WithUnit("By"),
+ metric.WithDescription("Bytes in in-use spans"),
+ ); err != nil {
+ return err
+ }
+
+ if heapObjects, err = r.meter.Int64ObservableUpDownCounter(
+ "process.runtime.go.mem.heap_objects",
+ metric.WithDescription("Number of allocated heap objects"),
+ ); err != nil {
+ return err
+ }
+
+ // FYI see https://github.com/golang/go/issues/32284 to help
+ // understand the meaning of this value.
+ if heapReleased, err = r.meter.Int64ObservableUpDownCounter(
+ "process.runtime.go.mem.heap_released",
+ metric.WithUnit("By"),
+ metric.WithDescription("Bytes of idle spans whose physical memory has been returned to the OS"),
+ ); err != nil {
+ return err
+ }
+
+ if heapSys, err = r.meter.Int64ObservableUpDownCounter(
+ "process.runtime.go.mem.heap_sys",
+ metric.WithUnit("By"),
+ metric.WithDescription("Bytes of heap memory obtained from the OS"),
+ ); err != nil {
+ return err
+ }
+
+ if ptrLookups, err = r.meter.Int64ObservableCounter(
+ "process.runtime.go.mem.lookups",
+ metric.WithDescription("Number of pointer lookups performed by the runtime"),
+ ); err != nil {
+ return err
+ }
+
+ if liveObjects, err = r.meter.Int64ObservableUpDownCounter(
+ "process.runtime.go.mem.live_objects",
+ metric.WithDescription("Number of live objects is the number of cumulative Mallocs - Frees"),
+ ); err != nil {
+ return err
+ }
+
+ if gcCount, err = r.meter.Int64ObservableCounter(
+ "process.runtime.go.gc.count",
+ metric.WithDescription("Number of completed garbage collection cycles"),
+ ); err != nil {
+ return err
+ }
+
+ // Note that the following could be derived as a sum of
+ // individual pauses, but we may lose individual pauses if the
+ // observation interval is too slow.
+ if pauseTotalNs, err = r.meter.Int64ObservableCounter(
+ "process.runtime.go.gc.pause_total_ns",
+ // TODO: nanoseconds units
+ metric.WithDescription("Cumulative nanoseconds in GC stop-the-world pauses since the program started"),
+ ); err != nil {
+ return err
+ }
+
+ if gcPauseNs, err = r.meter.Int64Histogram(
+ "process.runtime.go.gc.pause_ns",
+ // TODO: nanoseconds units
+ metric.WithDescription("Amount of nanoseconds in GC stop-the-world pauses"),
+ ); err != nil {
+ return err
+ }
+
+ _, err = r.meter.RegisterCallback(
+ func(ctx context.Context, o metric.Observer) error {
+ lock.Lock()
+ defer lock.Unlock()
+
+ now := time.Now()
+ if now.Sub(lastMemStats) >= r.minimumReadMemStatsInterval {
+ goruntime.ReadMemStats(&memStats)
+ lastMemStats = now
+ }
+
+ o.ObserveInt64(heapAlloc, clampUint64(memStats.HeapAlloc))
+ o.ObserveInt64(heapIdle, clampUint64(memStats.HeapIdle))
+ o.ObserveInt64(heapInuse, clampUint64(memStats.HeapInuse))
+ o.ObserveInt64(heapObjects, clampUint64(memStats.HeapObjects))
+ o.ObserveInt64(heapReleased, clampUint64(memStats.HeapReleased))
+ o.ObserveInt64(heapSys, clampUint64(memStats.HeapSys))
+ o.ObserveInt64(liveObjects, clampUint64(memStats.Mallocs-memStats.Frees))
+ o.ObserveInt64(ptrLookups, clampUint64(memStats.Lookups))
+ o.ObserveInt64(gcCount, int64(memStats.NumGC))
+ o.ObserveInt64(pauseTotalNs, clampUint64(memStats.PauseTotalNs))
+
+ computeGCPauses(ctx, gcPauseNs, memStats.PauseNs[:], lastNumGC, memStats.NumGC)
+
+ lastNumGC = memStats.NumGC
+
+ return nil
+ },
+ heapAlloc,
+ heapIdle,
+ heapInuse,
+ heapObjects,
+ heapReleased,
+ heapSys,
+ liveObjects,
+
+ ptrLookups,
+
+ gcCount,
+ pauseTotalNs,
+ )
+ if err != nil {
+ return err
+ }
+ return nil
+}
+
+func clampUint64(v uint64) int64 {
+ if v > math.MaxInt64 {
+ return math.MaxInt64
+ }
+ return int64(v) // nolint: gosec // Overflow checked above.
+}
+
+func computeGCPauses(
+ ctx context.Context,
+ recorder metric.Int64Histogram,
+ circular []uint64,
+ lastNumGC, currentNumGC uint32,
+) {
+ delta := int(int64(currentNumGC) - int64(lastNumGC))
+
+ if delta == 0 {
+ return
+ }
+
+ if delta >= len(circular) {
+ // There were > 256 collections, some may have been lost.
+ recordGCPauses(ctx, recorder, circular)
+ return
+ }
+
+ n := len(circular)
+ if n < 0 {
+ // Only the case in error situations.
+ return
+ }
+
+ length := uint64(n) // nolint: gosec // n >= 0
+
+ i := uint64(lastNumGC) % length
+ j := uint64(currentNumGC) % length
+
+ if j < i { // wrap around the circular buffer
+ recordGCPauses(ctx, recorder, circular[i:])
+ recordGCPauses(ctx, recorder, circular[:j])
+ return
+ }
+
+ recordGCPauses(ctx, recorder, circular[i:j])
+}
+
+func recordGCPauses(
+ ctx context.Context,
+ recorder metric.Int64Histogram,
+ pauses []uint64,
+) {
+ for _, pause := range pauses {
+ recorder.Record(ctx, clampUint64(pause))
+ }
+}
diff --git a/vendor/go.opentelemetry.io/contrib/instrumentation/runtime/internal/x/README.md b/vendor/go.opentelemetry.io/contrib/instrumentation/runtime/internal/x/README.md
new file mode 100644
index 000000000..a2367651a
--- /dev/null
+++ b/vendor/go.opentelemetry.io/contrib/instrumentation/runtime/internal/x/README.md
@@ -0,0 +1,38 @@
+# Feature Gates
+
+The runtime package contains a feature gate used to ease the migration
+from the [previous runtime metrics conventions] to the new [OpenTelemetry Go
+Runtime conventions].
+
+Note that the new runtime metrics conventions are still experimental, and may
+change in backwards incompatible ways as feedback is applied.
+
+## Features
+
+- [Include Deprecated Metrics](#include-deprecated-metrics)
+
+### Include Deprecated Metrics
+
+Once new experimental runtime metrics are added, they will be produced
+**in addition to** the existing runtime metrics. Users that migrate right away
+can disable the old runtime metrics:
+
+```console
+export OTEL_GO_X_DEPRECATED_RUNTIME_METRICS=false
+```
+
+In a later release, the deprecated runtime metrics will stop being produced by
+default. To temporarily re-enable the deprecated metrics:
+
+```console
+export OTEL_GO_X_DEPRECATED_RUNTIME_METRICS=true
+```
+
+After two additional releases, the deprecated runtime metrics will be removed,
+and setting the environment variable will no longer have any effect.
+
+The value set must be the case-insensitive string of `"true"` to enable the
+feature, and `"false"` to disable the feature. All other values are ignored.
+
+[previous runtime metrics conventions]: https://pkg.go.dev/go.opentelemetry.io/contrib/instrumentation/runtime@v0.52.0
+[OpenTelemetry Go Runtime conventions]: https://github.com/open-telemetry/semantic-conventions/blob/main/docs/runtime/go-metrics.md
diff --git a/vendor/go.opentelemetry.io/contrib/instrumentation/runtime/internal/x/x.go b/vendor/go.opentelemetry.io/contrib/instrumentation/runtime/internal/x/x.go
new file mode 100644
index 000000000..7ffb473ad
--- /dev/null
+++ b/vendor/go.opentelemetry.io/contrib/instrumentation/runtime/internal/x/x.go
@@ -0,0 +1,53 @@
+// Copyright The OpenTelemetry Authors
+// SPDX-License-Identifier: Apache-2.0
+
+// Package x contains support for OTel runtime instrumentation experimental features.
+//
+// This package should only be used for features defined in the specification.
+// It should not be used for experiments or new project ideas.
+package x // import "go.opentelemetry.io/contrib/instrumentation/runtime/internal/x"
+
+import (
+ "os"
+ "strings"
+)
+
+// DeprecatedRuntimeMetrics is an experimental feature flag that defines if the deprecated
+// runtime metrics should be produced. During development of the new
+// conventions, it is enabled by default.
+//
+// To disable this feature set the OTEL_GO_X_DEPRECATED_RUNTIME_METRICS environment variable
+// to the case-insensitive string value of "false" (i.e. "False" and "FALSE"
+// will also enable this).
+var DeprecatedRuntimeMetrics = newFeature("DEPRECATED_RUNTIME_METRICS", true)
+
+// BoolFeature is an experimental feature control flag. It provides a uniform way
+// to interact with these feature flags and parse their values.
+type BoolFeature struct {
+ key string
+ defaultVal bool
+}
+
+func newFeature(suffix string, defaultVal bool) BoolFeature {
+ const envKeyRoot = "OTEL_GO_X_"
+ return BoolFeature{
+ key: envKeyRoot + suffix,
+ defaultVal: defaultVal,
+ }
+}
+
+// Key returns the environment variable key that needs to be set to enable the
+// feature.
+func (f BoolFeature) Key() string { return f.key }
+
+// Enabled returns if the feature is enabled.
+func (f BoolFeature) Enabled() bool {
+ v := os.Getenv(f.key)
+ if strings.ToLower(v) == "false" {
+ return false
+ }
+ if strings.ToLower(v) == "true" {
+ return true
+ }
+ return f.defaultVal
+}
diff --git a/vendor/go.opentelemetry.io/contrib/instrumentation/runtime/options.go b/vendor/go.opentelemetry.io/contrib/instrumentation/runtime/options.go
new file mode 100644
index 000000000..580dc5dcd
--- /dev/null
+++ b/vendor/go.opentelemetry.io/contrib/instrumentation/runtime/options.go
@@ -0,0 +1,99 @@
+// Copyright The OpenTelemetry Authors
+// SPDX-License-Identifier: Apache-2.0
+
+package runtime // import "go.opentelemetry.io/contrib/instrumentation/runtime"
+
+import (
+ "time"
+
+ "go.opentelemetry.io/otel"
+ "go.opentelemetry.io/otel/metric"
+)
+
+// config contains optional settings for reporting runtime metrics.
+type config struct {
+ // MinimumReadMemStatsInterval sets the minimum interval
+ // between calls to runtime.ReadMemStats(). Negative values
+ // are ignored.
+ MinimumReadMemStatsInterval time.Duration
+
+ // MeterProvider sets the metric.MeterProvider. If nil, the global
+ // Provider will be used.
+ MeterProvider metric.MeterProvider
+}
+
+// Option supports configuring optional settings for runtime metrics.
+type Option interface {
+ apply(*config)
+}
+
+// ProducerOption supports configuring optional settings for runtime metrics using a
+// metric producer in addition to standard instrumentation.
+type ProducerOption interface {
+ Option
+ applyProducer(*config)
+}
+
+// DefaultMinimumReadMemStatsInterval is the default minimum interval
+// between calls to runtime.ReadMemStats(). Use the
+// WithMinimumReadMemStatsInterval() option to modify this setting in
+// Start().
+const DefaultMinimumReadMemStatsInterval time.Duration = 15 * time.Second
+
+// WithMinimumReadMemStatsInterval sets a minimum interval between calls to
+// runtime.ReadMemStats(), which is a relatively expensive call to make
+// frequently. This setting is ignored when `d` is negative.
+func WithMinimumReadMemStatsInterval(d time.Duration) Option {
+ return minimumReadMemStatsIntervalOption(d)
+}
+
+type minimumReadMemStatsIntervalOption time.Duration
+
+func (o minimumReadMemStatsIntervalOption) apply(c *config) {
+ if o >= 0 {
+ c.MinimumReadMemStatsInterval = time.Duration(o)
+ }
+}
+
+func (o minimumReadMemStatsIntervalOption) applyProducer(c *config) { o.apply(c) }
+
+// WithMeterProvider sets the Metric implementation to use for
+// reporting. If this option is not used, the global metric.MeterProvider
+// will be used. `provider` must be non-nil.
+func WithMeterProvider(provider metric.MeterProvider) Option {
+ return metricProviderOption{provider}
+}
+
+type metricProviderOption struct{ metric.MeterProvider }
+
+func (o metricProviderOption) apply(c *config) {
+ if o.MeterProvider != nil {
+ c.MeterProvider = o.MeterProvider
+ }
+}
+
+// newConfig computes a config from the supplied Options.
+func newConfig(opts ...Option) config {
+ c := config{
+ MeterProvider: otel.GetMeterProvider(),
+ }
+ for _, opt := range opts {
+ opt.apply(&c)
+ }
+ if c.MinimumReadMemStatsInterval <= 0 {
+ c.MinimumReadMemStatsInterval = DefaultMinimumReadMemStatsInterval
+ }
+ return c
+}
+
+// newConfig computes a config from the supplied ProducerOptions.
+func newProducerConfig(opts ...ProducerOption) config {
+ c := config{}
+ for _, opt := range opts {
+ opt.applyProducer(&c)
+ }
+ if c.MinimumReadMemStatsInterval <= 0 {
+ c.MinimumReadMemStatsInterval = DefaultMinimumReadMemStatsInterval
+ }
+ return c
+}
diff --git a/vendor/go.opentelemetry.io/contrib/instrumentation/runtime/producer.go b/vendor/go.opentelemetry.io/contrib/instrumentation/runtime/producer.go
new file mode 100644
index 000000000..82426b3f2
--- /dev/null
+++ b/vendor/go.opentelemetry.io/contrib/instrumentation/runtime/producer.go
@@ -0,0 +1,120 @@
+// Copyright The OpenTelemetry Authors
+// SPDX-License-Identifier: Apache-2.0
+
+package runtime // import "go.opentelemetry.io/contrib/instrumentation/runtime"
+
+import (
+ "context"
+ "errors"
+ "math"
+ "runtime/metrics"
+ "sync"
+ "time"
+
+ "go.opentelemetry.io/otel/attribute"
+ "go.opentelemetry.io/otel/sdk/instrumentation"
+ "go.opentelemetry.io/otel/sdk/metric"
+ "go.opentelemetry.io/otel/sdk/metric/metricdata"
+)
+
+var startTime time.Time
+
+func init() {
+ startTime = time.Now()
+}
+
+var histogramMetrics = []string{goSchedLatencies}
+
+// Producer is a metric.Producer, which provides precomputed histogram metrics from the go runtime.
+type Producer struct {
+ lock sync.Mutex
+ collector *goCollector
+}
+
+var _ metric.Producer = (*Producer)(nil)
+
+// NewProducer creates a Producer which provides precomputed histogram metrics from the go runtime.
+func NewProducer(opts ...ProducerOption) *Producer {
+ c := newProducerConfig(opts...)
+ return &Producer{
+ collector: newCollector(c.MinimumReadMemStatsInterval, histogramMetrics),
+ }
+}
+
+// Produce returns precomputed histogram metrics from the go runtime, or an error if unsuccessful.
+func (p *Producer) Produce(context.Context) ([]metricdata.ScopeMetrics, error) {
+ p.lock.Lock()
+ p.collector.refresh()
+ schedHist := p.collector.getHistogram(goSchedLatencies)
+ p.lock.Unlock()
+ // Use the last collection time (which may or may not be now) for the timestamp.
+ histDp := convertRuntimeHistogram(schedHist, p.collector.lastCollect)
+ if len(histDp) == 0 {
+ return nil, errors.New("unable to obtain go.schedule.duration metric from the runtime")
+ }
+ return []metricdata.ScopeMetrics{
+ {
+ Scope: instrumentation.Scope{
+ Name: ScopeName,
+ Version: Version(),
+ },
+ Metrics: []metricdata.Metrics{
+ {
+ Name: "go.schedule.duration",
+ Description: "The time goroutines have spent in the scheduler in a runnable state before actually running.",
+ Unit: "s",
+ Data: metricdata.Histogram[float64]{
+ Temporality: metricdata.CumulativeTemporality,
+ DataPoints: histDp,
+ },
+ },
+ },
+ },
+ }, nil
+}
+
+var emptySet = attribute.EmptySet()
+
+func convertRuntimeHistogram(runtimeHist *metrics.Float64Histogram, ts time.Time) []metricdata.HistogramDataPoint[float64] {
+ if runtimeHist == nil {
+ return nil
+ }
+ bounds := runtimeHist.Buckets
+ counts := runtimeHist.Counts
+ if len(bounds) < 2 {
+ // runtime histograms are guaranteed to have at least two bucket boundaries.
+ return nil
+ }
+ // trim the first bucket since it is a lower bound. OTel histogram boundaries only have an upper bound.
+ bounds = bounds[1:]
+ if bounds[len(bounds)-1] == math.Inf(1) {
+ // trim the last bucket if it is +Inf, since the +Inf boundary is implicit in OTel.
+ bounds = bounds[:len(bounds)-1]
+ } else {
+ // if the last bucket is not +Inf, append an extra zero count since
+ // the implicit +Inf bucket won't have any observations.
+ counts = append(counts, 0)
+ }
+ count := uint64(0)
+ sum := float64(0)
+ for i, c := range counts {
+ count += c
+ // This computed sum is an underestimate, since it assumes each
+ // observation happens at the bucket's lower bound.
+ if i > 0 && count != 0 {
+ sum += bounds[i-1] * float64(count)
+ }
+ }
+
+ return []metricdata.HistogramDataPoint[float64]{
+ {
+ StartTime: startTime,
+ Count: count,
+ Sum: sum,
+ Time: ts,
+ Bounds: bounds,
+ BucketCounts: counts,
+ Attributes: *emptySet,
+ },
+ }
+}
diff --git a/vendor/go.opentelemetry.io/contrib/instrumentation/runtime/runtime.go b/vendor/go.opentelemetry.io/contrib/instrumentation/runtime/runtime.go
new file mode 100644
index 000000000..d0ffe2764
--- /dev/null
+++ b/vendor/go.opentelemetry.io/contrib/instrumentation/runtime/runtime.go
@@ -0,0 +1,229 @@
+// Copyright The OpenTelemetry Authors
+// SPDX-License-Identifier: Apache-2.0
+
+package runtime // import "go.opentelemetry.io/contrib/instrumentation/runtime"
+
+import (
+ "context"
+ "math"
+ "runtime/metrics"
+ "sync"
+ "time"
+
+ "go.opentelemetry.io/otel/attribute"
+ "go.opentelemetry.io/otel/metric"
+
+ "go.opentelemetry.io/contrib/instrumentation/runtime/internal/deprecatedruntime"
+ "go.opentelemetry.io/contrib/instrumentation/runtime/internal/x"
+)
+
+// ScopeName is the instrumentation scope name.
+const ScopeName = "go.opentelemetry.io/contrib/instrumentation/runtime"
+
+const (
+ goTotalMemory = "/memory/classes/total:bytes"
+ goMemoryReleased = "/memory/classes/heap/released:bytes"
+ goHeapMemory = "/memory/classes/heap/stacks:bytes"
+ goMemoryLimit = "/gc/gomemlimit:bytes"
+ goMemoryAllocated = "/gc/heap/allocs:bytes"
+ goMemoryAllocations = "/gc/heap/allocs:objects"
+ goMemoryGoal = "/gc/heap/goal:bytes"
+ goGoroutines = "/sched/goroutines:goroutines"
+ goMaxProcs = "/sched/gomaxprocs:threads"
+ goConfigGC = "/gc/gogc:percent"
+ goSchedLatencies = "/sched/latencies:seconds"
+)
+
+// Start initializes reporting of runtime metrics using the supplied config.
+// For goroutine scheduling metrics, additionally see [NewProducer].
+func Start(opts ...Option) error {
+ c := newConfig(opts...)
+ meter := c.MeterProvider.Meter(
+ ScopeName,
+ metric.WithInstrumentationVersion(Version()),
+ )
+ if x.DeprecatedRuntimeMetrics.Enabled() {
+ return deprecatedruntime.Start(meter, c.MinimumReadMemStatsInterval)
+ }
+ memoryUsedInstrument, err := meter.Int64ObservableUpDownCounter(
+ "go.memory.used",
+ metric.WithUnit("By"),
+ metric.WithDescription("Memory used by the Go runtime."),
+ )
+ if err != nil {
+ return err
+ }
+ memoryLimitInstrument, err := meter.Int64ObservableUpDownCounter(
+ "go.memory.limit",
+ metric.WithUnit("By"),
+ metric.WithDescription("Go runtime memory limit configured by the user, if a limit exists."),
+ )
+ if err != nil {
+ return err
+ }
+ memoryAllocatedInstrument, err := meter.Int64ObservableCounter(
+ "go.memory.allocated",
+ metric.WithUnit("By"),
+ metric.WithDescription("Memory allocated to the heap by the application."),
+ )
+ if err != nil {
+ return err
+ }
+ memoryAllocationsInstrument, err := meter.Int64ObservableCounter(
+ "go.memory.allocations",
+ metric.WithUnit("{allocation}"),
+ metric.WithDescription("Count of allocations to the heap by the application."),
+ )
+ if err != nil {
+ return err
+ }
+ memoryGCGoalInstrument, err := meter.Int64ObservableUpDownCounter(
+ "go.memory.gc.goal",
+ metric.WithUnit("By"),
+ metric.WithDescription("Heap size target for the end of the GC cycle."),
+ )
+ if err != nil {
+ return err
+ }
+ goroutineCountInstrument, err := meter.Int64ObservableUpDownCounter(
+ "go.goroutine.count",
+ metric.WithUnit("{goroutine}"),
+ metric.WithDescription("Count of live goroutines."),
+ )
+ if err != nil {
+ return err
+ }
+ processorLimitInstrument, err := meter.Int64ObservableUpDownCounter(
+ "go.processor.limit",
+ metric.WithUnit("{thread}"),
+ metric.WithDescription("The number of OS threads that can execute user-level Go code simultaneously."),
+ )
+ if err != nil {
+ return err
+ }
+ gogcConfigInstrument, err := meter.Int64ObservableUpDownCounter(
+ "go.config.gogc",
+ metric.WithUnit("%"),
+ metric.WithDescription("Heap size target percentage configured by the user, otherwise 100."),
+ )
+ if err != nil {
+ return err
+ }
+
+ otherMemoryOpt := metric.WithAttributeSet(
+ attribute.NewSet(attribute.String("go.memory.type", "other")),
+ )
+ stackMemoryOpt := metric.WithAttributeSet(
+ attribute.NewSet(attribute.String("go.memory.type", "stack")),
+ )
+ collector := newCollector(c.MinimumReadMemStatsInterval, runtimeMetrics)
+ var lock sync.Mutex
+ _, err = meter.RegisterCallback(
+ func(ctx context.Context, o metric.Observer) error {
+ lock.Lock()
+ defer lock.Unlock()
+ collector.refresh()
+ stackMemory := collector.getInt(goHeapMemory)
+ o.ObserveInt64(memoryUsedInstrument, stackMemory, stackMemoryOpt)
+ totalMemory := collector.getInt(goTotalMemory) - collector.getInt(goMemoryReleased)
+ otherMemory := totalMemory - stackMemory
+ o.ObserveInt64(memoryUsedInstrument, otherMemory, otherMemoryOpt)
+ // Only observe the limit metric if a limit exists
+ if limit := collector.getInt(goMemoryLimit); limit != math.MaxInt64 {
+ o.ObserveInt64(memoryLimitInstrument, limit)
+ }
+ o.ObserveInt64(memoryAllocatedInstrument, collector.getInt(goMemoryAllocated))
+ o.ObserveInt64(memoryAllocationsInstrument, collector.getInt(goMemoryAllocations))
+ o.ObserveInt64(memoryGCGoalInstrument, collector.getInt(goMemoryGoal))
+ o.ObserveInt64(goroutineCountInstrument, collector.getInt(goGoroutines))
+ o.ObserveInt64(processorLimitInstrument, collector.getInt(goMaxProcs))
+ o.ObserveInt64(gogcConfigInstrument, collector.getInt(goConfigGC))
+ return nil
+ },
+ memoryUsedInstrument,
+ memoryLimitInstrument,
+ memoryAllocatedInstrument,
+ memoryAllocationsInstrument,
+ memoryGCGoalInstrument,
+ goroutineCountInstrument,
+ processorLimitInstrument,
+ gogcConfigInstrument,
+ )
+ if err != nil {
+ return err
+ }
+ return nil
+}
+
+// These are the metrics we actually fetch from the go runtime.
+var runtimeMetrics = []string{
+ goTotalMemory,
+ goMemoryReleased,
+ goHeapMemory,
+ goMemoryLimit,
+ goMemoryAllocated,
+ goMemoryAllocations,
+ goMemoryGoal,
+ goGoroutines,
+ goMaxProcs,
+ goConfigGC,
+}
+
+type goCollector struct {
+ // now is used to replace the implementation of time.Now for testing
+ now func() time.Time
+ // lastCollect tracks the last time metrics were refreshed
+ lastCollect time.Time
+ // minimumInterval is the minimum amount of time between calls to metrics.Read
+ minimumInterval time.Duration
+ // sampleBuffer is populated by runtime/metrics
+ sampleBuffer []metrics.Sample
+ // sampleMap allows us to easily get the value of a single metric
+ sampleMap map[string]*metrics.Sample
+}
+
+func newCollector(minimumInterval time.Duration, metricNames []string) *goCollector {
+ g := &goCollector{
+ sampleBuffer: make([]metrics.Sample, 0, len(metricNames)),
+ sampleMap: make(map[string]*metrics.Sample, len(metricNames)),
+ minimumInterval: minimumInterval,
+ now: time.Now,
+ }
+ for _, metricName := range metricNames {
+ g.sampleBuffer = append(g.sampleBuffer, metrics.Sample{Name: metricName})
+ // sampleMap references a position in the sampleBuffer slice. If an
+ // element is appended to sampleBuffer, it must be added to sampleMap
+ // for the sample to be accessible in sampleMap.
+ g.sampleMap[metricName] = &g.sampleBuffer[len(g.sampleBuffer)-1]
+ }
+ return g
+}
+
+func (g *goCollector) refresh() {
+ now := g.now()
+ if now.Sub(g.lastCollect) < g.minimumInterval {
+ // refresh was invoked more frequently than allowed by the minimum
+ // interval. Do nothing.
+ return
+ }
+ metrics.Read(g.sampleBuffer)
+ g.lastCollect = now
+}
+
+func (g *goCollector) getInt(name string) int64 {
+ if s, ok := g.sampleMap[name]; ok && s.Value.Kind() == metrics.KindUint64 {
+ v := s.Value.Uint64()
+ if v > math.MaxInt64 {
+ return math.MaxInt64
+ }
+ return int64(v) // nolint: gosec // Overflow checked above.
+ }
+ return 0
+}
+
+func (g *goCollector) getHistogram(name string) *metrics.Float64Histogram {
+ if s, ok := g.sampleMap[name]; ok && s.Value.Kind() == metrics.KindFloat64Histogram {
+ return s.Value.Float64Histogram()
+ }
+ return nil
+}
diff --git a/vendor/go.opentelemetry.io/contrib/instrumentation/runtime/version.go b/vendor/go.opentelemetry.io/contrib/instrumentation/runtime/version.go
new file mode 100644
index 000000000..6df851609
--- /dev/null
+++ b/vendor/go.opentelemetry.io/contrib/instrumentation/runtime/version.go
@@ -0,0 +1,17 @@
+// Copyright The OpenTelemetry Authors
+// SPDX-License-Identifier: Apache-2.0
+
+package runtime // import "go.opentelemetry.io/contrib/instrumentation/runtime"
+
+// Version is the current release version of the runtime instrumentation.
+func Version() string {
+ return "0.60.0"
+ // This string is updated by the pre_release.sh script during release
+}
+
+// SemVersion is the semantic version to be supplied to tracer/meter creation.
+//
+// Deprecated: Use [Version] instead.
+func SemVersion() string {
+ return Version()
+}
diff --git a/vendor/modules.txt b/vendor/modules.txt
index 2ddcdc434..568c36fdc 100644
--- a/vendor/modules.txt
+++ b/vendor/modules.txt
@@ -984,6 +984,11 @@ go.opentelemetry.io/contrib/bridges/prometheus
# go.opentelemetry.io/contrib/exporters/autoexport v0.60.0
## explicit; go 1.22.0
go.opentelemetry.io/contrib/exporters/autoexport
+# go.opentelemetry.io/contrib/instrumentation/runtime v0.60.0
+## explicit; go 1.22.0
+go.opentelemetry.io/contrib/instrumentation/runtime
+go.opentelemetry.io/contrib/instrumentation/runtime/internal/deprecatedruntime
+go.opentelemetry.io/contrib/instrumentation/runtime/internal/x
# go.opentelemetry.io/otel v1.35.0
## explicit; go 1.22.0
go.opentelemetry.io/otel