Files
57b9ef078e fix(deps): update all golang.org/x packages (#14223)
This PR contains the following updates:

| Package | Change | Age | Confidence |
|---|---|---|---|
| golang.org/x/mod | `v0.28.0` -> `v0.30.0` |
[![age](https://developer.mend.io/api/mc/badges/age/go/golang.org%2fx%2fmod/v0.30.0?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![confidence](https://developer.mend.io/api/mc/badges/confidence/go/golang.org%2fx%2fmod/v0.28.0/v0.30.0?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
| golang.org/x/sys | `v0.37.0` -> `v0.38.0` |
[![age](https://developer.mend.io/api/mc/badges/age/go/golang.org%2fx%2fsys/v0.38.0?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![confidence](https://developer.mend.io/api/mc/badges/confidence/go/golang.org%2fx%2fsys/v0.37.0/v0.38.0?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
| golang.org/x/tools | `v0.38.0` -> `v0.39.0` |
[![age](https://developer.mend.io/api/mc/badges/age/go/golang.org%2fx%2ftools/v0.39.0?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![confidence](https://developer.mend.io/api/mc/badges/confidence/go/golang.org%2fx%2ftools/v0.38.0/v0.39.0?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|

---

> [!WARNING]
> Some dependencies could not be looked up. Check the Dependency
Dashboard for more information.

---

### Configuration

📅 **Schedule**: Branch creation - "on tuesday" (UTC), Automerge - At any
time (no schedule defined).

🚦 **Automerge**: Disabled by config. Please merge this manually once you
are satisfied.

♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the
rebase/retry checkbox.

👻 **Immortal**: This PR will be recreated if closed unmerged. Get
[config
help](https://redirect.github.com/renovatebot/renovate/discussions) if
that's undesired.

---

- [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check
this box

---

This PR was generated by [Mend Renovate](https://mend.io/renovate/).
View the [repository job
log](https://developer.mend.io/github/open-telemetry/opentelemetry-collector).

<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0Mi4xOS45IiwidXBkYXRlZEluVmVyIjoiNDIuMTkuOSIsInRhcmdldEJyYW5jaCI6Im1haW4iLCJsYWJlbHMiOlsiZGVwZW5kZW5jaWVzIiwicmVub3ZhdGVib3QiXX0=-->

---------

Signed-off-by: alex boten <[email protected]>
Co-authored-by: Hanzo Dev <[email protected]>
Co-authored-by: Pablo Baeyens <[email protected]>
Co-authored-by: Alex Boten <[email protected]>
Co-authored-by: Pablo Baeyens <[email protected]>
2025-11-28 16:04:38 +00:00

151 lines
4.0 KiB
Go

// Copyright The OpenTelemetry Authors
// SPDX-License-Identifier: Apache-2.0
package proctelemetry // import "go.opentelemetry.io/collector/service/internal/proctelemetry"
import (
"context"
"errors"
"os"
"runtime"
"sync"
"time"
"github.com/shirou/gopsutil/v4/common"
"github.com/shirou/gopsutil/v4/process"
"go.opentelemetry.io/otel/metric"
"go.opentelemetry.io/collector/component"
"go.opentelemetry.io/collector/service/internal/metadata"
)
// processMetrics is a struct that contains views related to process metrics (cpu, mem, etc)
type processMetrics struct {
startTimeUnixNano int64
proc *process.Process
context context.Context
// mu protects everything bellow.
mu sync.Mutex
lastMsRead time.Time
ms *runtime.MemStats
}
type RegisterOption interface {
apply(*registerOption)
}
type registerOption struct {
hostProc string
}
type registerOptionFunc func(*registerOption)
func (fn registerOptionFunc) apply(set *registerOption) {
fn(set)
}
// WithHostProc overrides the /proc folder on Linux used by process telemetry.
func WithHostProc(hostProc string) RegisterOption {
return registerOptionFunc(func(uo *registerOption) {
uo.hostProc = hostProc
})
}
// RegisterProcessMetrics creates a new set of processMetrics (mem, cpu) that can be used to measure
// basic information about this process.
func RegisterProcessMetrics(cfg component.TelemetrySettings, opts ...RegisterOption) error {
set := registerOption{}
for _, opt := range opts {
opt.apply(&set)
}
var err error
pm := &processMetrics{
startTimeUnixNano: time.Now().UnixNano(),
ms: &runtime.MemStats{},
}
ctx := context.Background()
if set.hostProc != "" {
ctx = context.WithValue(ctx, common.EnvKey, common.EnvMap{common.HostProcEnvKey: set.hostProc})
}
pm.context = ctx
pm.proc, err = process.NewProcessWithContext(pm.context, int32(os.Getpid()))
if err != nil {
return err
}
tb, err := metadata.NewTelemetryBuilder(cfg)
if err != nil {
return err
}
return errors.Join(
tb.RegisterProcessUptimeCallback(pm.updateProcessUptime),
tb.RegisterProcessRuntimeHeapAllocBytesCallback(pm.updateAllocMem),
tb.RegisterProcessRuntimeTotalAllocBytesCallback(pm.updateTotalAllocMem),
tb.RegisterProcessRuntimeTotalSysMemoryBytesCallback(pm.updateSysMem),
tb.RegisterProcessCPUSecondsCallback(pm.updateCPUSeconds),
tb.RegisterProcessMemoryRssCallback(pm.updateRSSMemory),
)
}
func (pm *processMetrics) updateProcessUptime(_ context.Context, obs metric.Float64Observer) error {
now := time.Now().UnixNano()
obs.Observe(float64(now-pm.startTimeUnixNano) / 1e9)
return nil
}
func (pm *processMetrics) updateAllocMem(_ context.Context, obs metric.Int64Observer) error {
pm.mu.Lock()
defer pm.mu.Unlock()
pm.readMemStatsIfNeeded()
obs.Observe(int64(pm.ms.Alloc))
return nil
}
func (pm *processMetrics) updateTotalAllocMem(_ context.Context, obs metric.Int64Observer) error {
pm.mu.Lock()
defer pm.mu.Unlock()
pm.readMemStatsIfNeeded()
obs.Observe(int64(pm.ms.TotalAlloc))
return nil
}
func (pm *processMetrics) updateSysMem(_ context.Context, obs metric.Int64Observer) error {
pm.mu.Lock()
defer pm.mu.Unlock()
pm.readMemStatsIfNeeded()
obs.Observe(int64(pm.ms.Sys))
return nil
}
func (pm *processMetrics) updateCPUSeconds(_ context.Context, obs metric.Float64Observer) error {
times, err := pm.proc.TimesWithContext(pm.context) //nolint:contextcheck
if err != nil {
return err
}
obs.Observe(times.User + times.System + times.Idle + times.Nice +
times.Iowait + times.Irq + times.Softirq + times.Steal)
return nil
}
func (pm *processMetrics) updateRSSMemory(_ context.Context, obs metric.Int64Observer) error {
mem, err := pm.proc.MemoryInfoWithContext(pm.context) //nolint:contextcheck
if err != nil {
return err
}
obs.Observe(int64(mem.RSS))
return nil
}
func (pm *processMetrics) readMemStatsIfNeeded() {
now := time.Now()
// If last time we read was less than one second ago just reuse the values
if now.Sub(pm.lastMsRead) < time.Second {
return
}
pm.lastMsRead = now
runtime.ReadMemStats(pm.ms)
}