Skip to content

Commit

Permalink
Add details statistics about the Process to /metrics endpoint
Browse files Browse the repository at this point in the history
  • Loading branch information
mattwarren committed Nov 15, 2024
1 parent 97a9c75 commit 47dab05
Showing 1 changed file with 86 additions and 2 deletions.
88 changes: 86 additions & 2 deletions src/Contrast.K8s.AgentOperator/Controllers/MetricsController.cs
Original file line number Diff line number Diff line change
@@ -1,18 +1,24 @@
// Contrast Security, Inc licenses this file to you under the Apache 2.0 License.
// See the LICENSE file in the project root for more information.

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Contrast.K8s.AgentOperator.Core.Telemetry;
using Contrast.K8s.AgentOperator.Core.Telemetry.Services.Metrics;
using Microsoft.AspNetCore.Mvc;
using NLog;

namespace Contrast.K8s.AgentOperator.Controllers;

[ApiController, Route("api/v1/metrics")]
public class MetricsController : Controller
{
private static readonly Logger Logger = LogManager.GetCurrentClassLogger();

private readonly StatusReportGenerator _reportGenerator;
private readonly DefaultTagsFactory _defaultTagsFactory;

Expand All @@ -30,12 +36,17 @@ public async Task<IActionResult> GetMetrics(CancellationToken cancellationToken
// Combine the Values and Tags from the report into a single output
var output = new Dictionary<string, object>();

foreach (var value in report.Values)
foreach (var value in report.Values.OrderBy(r => r.Key))
{
output.Add(value.Key, value.Value);
}

foreach (var tag in report.ExtraTags)
foreach (var stat in GenerateProcessingStatistics())
{
output.Add(stat.Key, stat.Value);
}

foreach (var tag in report.ExtraTags.OrderBy(r => r.Key))
{
output.Add(tag.Key, tag.Value);
}
Expand All @@ -49,4 +60,77 @@ public async Task<IActionResult> GetTags(CancellationToken cancellationToken = d
var tags = await _defaultTagsFactory.GetDefaultTags();
return Ok(tags);
}

private IDictionary<string, object> GenerateProcessingStatistics()
{
var statistics = new Dictionary<string, object>();

try
{
var currentProcess = Process.GetCurrentProcess();

// Do them in groups because they can all throw InvalidOperationException/NotSupportedException
// Makes the code messier, but it means we'll still get as many as we can if some don't work
try
{
statistics.Add("Process.WorkingSet64", currentProcess.WorkingSet64);
statistics.Add("Process.MinWorkingSet", currentProcess.MinWorkingSet.ToInt64());
statistics.Add("Process.MaxWorkingSet", currentProcess.MaxWorkingSet.ToInt64());
statistics.Add("Process.PeakWorkingSet64", currentProcess.PeakWorkingSet64);
}
catch (Exception ex)
{
Logger.Warn(ex);
}

try
{
statistics.Add("Process.PrivateMemorySize64", currentProcess.PrivateMemorySize64);
statistics.Add("Process.VirtualMemorySize64", currentProcess.VirtualMemorySize64);
statistics.Add("Process.PeakVirtualMemorySize64", currentProcess.PeakVirtualMemorySize64);
}
catch (Exception ex)
{
Logger.Warn(ex);
}

try
{
statistics.Add("Process.PagedMemorySize64", currentProcess.PagedMemorySize64);
statistics.Add("Process.PeakPagedMemorySize64", currentProcess.PeakPagedMemorySize64);
statistics.Add("Process.NonpagedSystemMemorySize64", currentProcess.NonpagedSystemMemorySize64);
}
catch (Exception ex)
{
Logger.Warn(ex);
}

try
{
statistics.Add("Process.TotalProcessorTime", currentProcess.TotalProcessorTime);
statistics.Add("Process.UserProcessorTime", currentProcess.UserProcessorTime);
statistics.Add("Process.PrivilegedProcessorTime", currentProcess.PrivilegedProcessorTime);
}
catch (Exception ex)
{
Logger.Warn(ex);
}

try
{
statistics.Add("Process.Thread", currentProcess.Threads.Count);
statistics.Add("Process.Modules", currentProcess.Modules.Count);
}
catch (Exception ex)
{
Logger.Warn(ex);
}
}
catch (Exception ex)
{
Logger.Warn(ex);
}

return statistics;
}
}

0 comments on commit 47dab05

Please sign in to comment.