Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Instrumentation.Process] Added memory related metrics. #595

Merged
merged 19 commits into from
Aug 26, 2022

Conversation

Yun-Ting
Copy link
Contributor

@Yun-Ting Yun-Ting commented Aug 19, 2022

Changes

Working towards: #447
Background: #335

Adding 2 memory related metrics following the semantic conventions for OS process metrics as starters.
https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/semantic_conventions/process-metrics.md#metric-instruments

Will be working on adding more metrics (cpu related and others) in the upcoming PRs.

@Yun-Ting Yun-Ting closed this Aug 19, 2022
@codecov
Copy link

codecov bot commented Aug 23, 2022

Codecov Report

Merging #595 (b731dff) into main (426f1a6) will increase coverage by 0.30%.
The diff coverage is 100.00%.

Impacted file tree graph

@@            Coverage Diff             @@
##             main     #595      +/-   ##
==========================================
+ Coverage   76.40%   76.70%   +0.30%     
==========================================
  Files         170      170              
  Lines        5141     5160      +19     
==========================================
+ Hits         3928     3958      +30     
+ Misses       1213     1202      -11     
Impacted Files Coverage Δ
...elemetry.Instrumentation.Process/ProcessMetrics.cs 100.00% <100.00%> (+100.00%) ⬆️
...entation.Process/MeterProviderBuilderExtensions.cs 100.00% <0.00%> (+100.00%) ⬆️

@utpilla utpilla added the comp:instrumentation.process Things related to OpenTelemetry.Instrumentation.Process label Aug 24, 2022
@Yun-Ting Yun-Ting changed the title [WIP] Process Instrumentation [Instrumentation.Process] Starting by adding memory related metrics. Aug 24, 2022
@Yun-Ting Yun-Ting changed the title [Instrumentation.Process] Starting by adding memory related metrics. [Instrumentation.Process] Added memory related metrics. Aug 24, 2022
@Yun-Ting Yun-Ting marked this pull request as ready for review August 24, 2022 00:35
@Yun-Ting Yun-Ting requested a review from a team August 24, 2022 00:35
// TODO: change to ObservableUpDownCounter
MeterInstance.CreateObservableGauge(
"process.memory.usage",
() => CurrentProcess.WorkingSet64,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's been awhile since I've studied the difference between WorkingSet64 and PrivateMemorySize64, so I'll admit I'm a bit fuzzy on the semantics of one over the other.

This seems to suggest that PrivateMemorySize64 may be useful as well https://stackoverflow.com/a/1986486/2052722.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah ha, thanks, yea I agree.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would say all of these are useful (otherwise the NT OS kernel folks wouldn't invent these concepts):

image

I guess the struggle is do we want to just want to do a .NET specific thing (similar to what we ended up with https://github.com/open-telemetry/opentelemetry-dotnet-contrib/tree/main/src/OpenTelemetry.Instrumentation.Runtime) or try to align with / wait for the spec (or maybe help the spec to move forward). I can also see that the spec might struggle when it comes to some verbose memory management concepts because those could be OS specific (or even specific to certain versions of the NT kernel).

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, I suspect this would be hard to generalize at the spec level. Maybe something like a process.dotnet.* namespace would be useful. Though, yea process.{os}.{os_distribution}.* might be more accurate but still hard to generalize across windows, linux, and whatever else.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There was an effort a few years back to port these properties to equivalents for linux dotnet/corefx#41122. So at least for .NET and the distros of linux that it supports there should be some level of generalization across OSes.

Copy link
Member

@alanwest alanwest left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not certain what the overhead of calling Refresh() for each metric is. If we find out it's expensive, we might consider this strategy in the future dotnet/runtime#62027 (comment).

Though... if Refresh is deemed cheap enough, then 👍 to keeping things simple.

@cijothomas cijothomas merged commit 1eccf86 into open-telemetry:main Aug 26, 2022

namespace OpenTelemetry.Instrumentation.Process;

internal class ProcessMetrics
{
internal static readonly AssemblyName AssemblyName = typeof(ProcessMetrics).Assembly.GetName();
internal static readonly Meter MeterInstance = new(AssemblyName.Name, AssemblyName.Version.ToString());
private static readonly Diagnostics.Process CurrentProcess = Diagnostics.Process.GetCurrentProcess();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This, combined with Refresh, look like a source of race condition.

image

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Yun-Ting You could probably just use a closure a la:

    static ProcessMetrics()
    {
        Diagnostics.Process currentProcess = Diagnostics.Process.GetCurrentProcess();

        // TODO: change to ObservableUpDownCounter
        MeterInstance.CreateObservableGauge(
            "process.memory.usage",
            () =>
            {
                currentProcess.Refresh();
                return currentProcess.WorkingSet64;
            },
            unit: "By",
            description: "The amount of physical memory in use.");

        // TODO: change to ObservableUpDownCounter
        MeterInstance.CreateObservableGauge(
            "process.memory.virtual",
            () =>
            {
                currentProcess.Refresh();
                return currentProcess.VirtualMemorySize64;
            },
            unit: "By",
            description: "The amount of committed virtual memory.");
    }

Is Process.Refresh() expensive? We'll be invoking it twice here anytime metrics are collected. If it is expensive we might want to create a state object we can refresh once and then return the result to the two counters in the callback.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you very much for pointing it out. Please refer to #612 for the update.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please refer to the latest PR #624 instead. Thanks!

@Yun-Ting
Copy link
Contributor Author

Yun-Ting commented Sep 7, 2022

I'm not certain what the overhead of calling Refresh() for each metric is. If we find out it's expensive, we might consider this strategy in the future dotnet/runtime#62027 (comment).

Though... if Refresh is deemed cheap enough, then 👍 to keeping things simple.

Please refer to the latest PR: #624 instead. Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
comp:instrumentation.process Things related to OpenTelemetry.Instrumentation.Process
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants