Open alexmojaki opened 1 month ago
The same problem exists for process.runtime.cpu.utilization
, but it's more easily fixable:
import time
from opentelemetry.instrumentation.system_metrics import SystemMetricsInstrumentor
from opentelemetry.sdk.metrics import MeterProvider
from opentelemetry.sdk.metrics.export import (
ConsoleMetricExporter,
PeriodicExportingMetricReader,
)
exporter = ConsoleMetricExporter()
reader = PeriodicExportingMetricReader(exporter)
meter_provider = MeterProvider(metric_readers=[reader])
config = {'process.runtime.cpu.utilization': None}
instrumentor = SystemMetricsInstrumentor(config=config)
instrumentor.instrument(meter_provider=meter_provider)
# Uncomment to get nonzero values
# instrumentor._proc.cpu_percent()
# Use some CPU
sum(list(range(int(1e7))))
# Wait a bit to get realistic measurements
time.sleep(1)
Adding self._proc.cpu_percent()
to the place where the instrument is created should fix it, because these values aren't tracked per thread. Maybe that'll change one day.
What happened?
Combining
PeriodicExportingMetricReader
andSystemMetricsInstrumentor
produces only zero values forsystem.cpu.utilization
in the first export, which may be the only export if the process doesn't last long.Steps to Reproduce
Output:
Expected Result
Some
value
s greater than 0.Actual Result
"value": 0.0
for every data point.Additional context
In https://psutil.readthedocs.io/en/latest/#psutil.cpu_times_percent it says:
which is where the problem comes from. However, the first time a user calls
cpu_times_percent
in the main thread, it actually returns a nonzero value. This is becausepsutil
has this at the top level of the module:This means that when metrics are read on the main thread (e.g. by adding
meter_provider.force_flush()
to the script above, or by usingInMemoryMetricReader
) then the CPU values are nonzero.The problem is that
PeriodicExportingMetricReader
naturally has to perform readings on a separate thread. From the same psutil docs:Adding the following code to the script above anywhere between
reader = ...
andtime.sleep
seems to fix the problem:Actually implementing this fix in a sensible and maintainable way seems more complicated.
Would you like to implement a fix?
No