Skip to content

Commit

Permalink
Merge branch 'master' into feature/profiler-auto-instrumentation
Browse files Browse the repository at this point in the history
  • Loading branch information
russcam authored Nov 3, 2021
2 parents 4d706fe + b33d209 commit 477899c
Show file tree
Hide file tree
Showing 2 changed files with 55 additions and 13 deletions.
20 changes: 20 additions & 0 deletions docs/metrics.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,26 @@ The metrics will be stored in the `apm-*` index and have the `processor.event` p

As of APM version 6.6, these metrics will be visualized in the APM app.

[IMPORTANT]
--
System CPU usage metric is collected using Performance Counters on Windows. The account under which a traced
application runs must be part of the **Performance Monitor Users** group to be able to access
performance counter values.

An account can be added to the **Performance Monitor Users** group from the command line

[source,sh]
----
net localgroup "Performance Monitor Users" "<Account Name>" /add <1>
----
<1> `<Account Name>` is the account under which the traced application runs

For applications running in IIS,
https://docs.microsoft.com/en-us/iis/manage/configuring-security/application-pool-identities[IIS application pool identities use _virtual_ accounts]
with a name following the convention `IIS APPPOOL\<Application pool name>`. An individual application pool identity
can be added to the **Performance Monitor Users** group using the `net localgroup` command above.
--

For more system metrics, consider installing {metricbeat-ref}/index.html[metricbeat] on your hosts.

*`system.cpu.total.norm.pct`*::
Expand Down
48 changes: 35 additions & 13 deletions src/Elastic.Apm/Metrics/MetricsProvider/SystemTotalCpuProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -30,31 +30,53 @@ public SystemTotalCpuProvider(IApmLogger logger)
_logger = logger.Scoped(nameof(SystemTotalCpuProvider));
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
{
var categoryName = "Processor";
try
{
_processorTimePerfCounter = new PerformanceCounter("Processor", "% Processor Time", "_Total");
try
{
_processorTimePerfCounter = new PerformanceCounter(categoryName, "% Processor Time", "_Total");
}
catch (InvalidOperationException e)
{
_logger.Debug()?.LogException(e, "Error instantiating '{CategoryName}' performance counter.", categoryName);
_processorTimePerfCounter?.Dispose();
// If the Processor performance counter category does not exist, try Processor Information.
categoryName = "Processor Information";
_processorTimePerfCounter = new PerformanceCounter(categoryName, "% Processor Time", "_Total");
}

//The perf. counter API returns 0 the for the 1. call (probably because there is no delta in the 1. call) - so we just call it here first
_processorTimePerfCounter.NextValue();
}
catch (Exception e)
{
_logger.Error()
?.LogException(e, "Failed instantiating PerformanceCounter "
+ "- please make sure the current user has permissions to read performance counters. E.g. make sure the current user is member of "
+ "the 'Performance Monitor Users' group");

if (e is UnauthorizedAccessException)
{
_logger.Error()
?.LogException(e, "Error instantiating '{CategoryName}' performance counter."
+ " Process does not have permissions to read performance counters."
+ " See https://www.elastic.co/guide/en/apm/agent/dotnet/current/metrics.html#metrics-system to see how to configure.", categoryName);
}
else
{
_logger.Error()
?.LogException(e, "Error instantiating '{CategoryName}' performance counter", categoryName);
}

_logger.Warning()?.Log("System metrics won't be collected");
_processorTimePerfCounter?.Dispose();
_processorTimePerfCounter = null;
}
}
else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
{
var (success, idle, total) = ReadProcStat();
if (!success) return;

if (!RuntimeInformation.IsOSPlatform(OSPlatform.Linux)) return;

var (success, idle, total) = ReadProcStat();
if (!success) return;

_prevIdleTime = idle;
_prevTotalTime = total;
_prevIdleTime = idle;
_prevTotalTime = total;
}
}

internal SystemTotalCpuProvider(IApmLogger logger, StreamReader procStatStreamReader)
Expand Down

0 comments on commit 477899c

Please sign in to comment.