feat: Add PathViewer and RiskDriftCard components with templates and styles
- Implemented PathViewerComponent for visualizing reachability call paths. - Added RiskDriftCardComponent to display reachability drift results. - Created corresponding HTML templates and SCSS styles for both components. - Introduced test fixtures for reachability analysis in JSON format. - Enhanced user interaction with collapsible and expandable features in PathViewer. - Included risk trend visualization and summary metrics in RiskDriftCard.
This commit is contained in:
@@ -0,0 +1,233 @@
|
||||
// -----------------------------------------------------------------------------
|
||||
// VulnSurfaceMetrics.cs
|
||||
// Sprint: SPRINT_3700_0002_0001_vuln_surfaces_core
|
||||
// Task: SURF-019
|
||||
// Description: Metrics for vulnerability surface computation.
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
using System.Diagnostics.Metrics;
|
||||
|
||||
namespace StellaOps.Scanner.VulnSurfaces.Diagnostics;
|
||||
|
||||
/// <summary>
|
||||
/// Metrics for vulnerability surface computation and caching.
|
||||
/// </summary>
|
||||
public static class VulnSurfaceMetrics
|
||||
{
|
||||
private static readonly Meter Meter = new("StellaOps.Scanner.VulnSurfaces", "1.0.0");
|
||||
|
||||
// ===== BUILD COUNTERS =====
|
||||
|
||||
/// <summary>
|
||||
/// Total surface build requests by ecosystem.
|
||||
/// </summary>
|
||||
public static readonly Counter<long> BuildRequests = Meter.CreateCounter<long>(
|
||||
"stellaops_vulnsurface_build_requests_total",
|
||||
description: "Total vulnerability surface build requests");
|
||||
|
||||
/// <summary>
|
||||
/// Successful surface builds by ecosystem.
|
||||
/// </summary>
|
||||
public static readonly Counter<long> BuildSuccesses = Meter.CreateCounter<long>(
|
||||
"stellaops_vulnsurface_build_successes_total",
|
||||
description: "Total successful vulnerability surface builds");
|
||||
|
||||
/// <summary>
|
||||
/// Failed surface builds by ecosystem and reason.
|
||||
/// </summary>
|
||||
public static readonly Counter<long> BuildFailures = Meter.CreateCounter<long>(
|
||||
"stellaops_vulnsurface_build_failures_total",
|
||||
description: "Total failed vulnerability surface builds");
|
||||
|
||||
/// <summary>
|
||||
/// Cache hits when surface already computed.
|
||||
/// </summary>
|
||||
public static readonly Counter<long> CacheHits = Meter.CreateCounter<long>(
|
||||
"stellaops_vulnsurface_cache_hits_total",
|
||||
description: "Total cache hits for pre-computed surfaces");
|
||||
|
||||
// ===== DOWNLOAD COUNTERS =====
|
||||
|
||||
/// <summary>
|
||||
/// Package downloads attempted by ecosystem.
|
||||
/// </summary>
|
||||
public static readonly Counter<long> DownloadAttempts = Meter.CreateCounter<long>(
|
||||
"stellaops_vulnsurface_downloads_attempted_total",
|
||||
description: "Total package download attempts");
|
||||
|
||||
/// <summary>
|
||||
/// Successful package downloads.
|
||||
/// </summary>
|
||||
public static readonly Counter<long> DownloadSuccesses = Meter.CreateCounter<long>(
|
||||
"stellaops_vulnsurface_downloads_succeeded_total",
|
||||
description: "Total successful package downloads");
|
||||
|
||||
/// <summary>
|
||||
/// Failed package downloads.
|
||||
/// </summary>
|
||||
public static readonly Counter<long> DownloadFailures = Meter.CreateCounter<long>(
|
||||
"stellaops_vulnsurface_downloads_failed_total",
|
||||
description: "Total failed package downloads");
|
||||
|
||||
// ===== FINGERPRINT COUNTERS =====
|
||||
|
||||
/// <summary>
|
||||
/// Methods fingerprinted by ecosystem.
|
||||
/// </summary>
|
||||
public static readonly Counter<long> MethodsFingerprinted = Meter.CreateCounter<long>(
|
||||
"stellaops_vulnsurface_methods_fingerprinted_total",
|
||||
description: "Total methods fingerprinted");
|
||||
|
||||
/// <summary>
|
||||
/// Methods changed (sinks) identified.
|
||||
/// </summary>
|
||||
public static readonly Counter<long> SinksIdentified = Meter.CreateCounter<long>(
|
||||
"stellaops_vulnsurface_sinks_identified_total",
|
||||
description: "Total sink methods (changed methods) identified");
|
||||
|
||||
// ===== TIMING HISTOGRAMS =====
|
||||
|
||||
/// <summary>
|
||||
/// End-to-end surface build duration.
|
||||
/// </summary>
|
||||
public static readonly Histogram<double> BuildDurationSeconds = Meter.CreateHistogram<double>(
|
||||
"stellaops_vulnsurface_build_duration_seconds",
|
||||
unit: "s",
|
||||
description: "Duration of surface build operations",
|
||||
advice: new InstrumentAdvice<double>
|
||||
{
|
||||
HistogramBucketBoundaries = [0.1, 0.5, 1.0, 2.5, 5.0, 10.0, 30.0, 60.0, 120.0]
|
||||
});
|
||||
|
||||
/// <summary>
|
||||
/// Package download duration.
|
||||
/// </summary>
|
||||
public static readonly Histogram<double> DownloadDurationSeconds = Meter.CreateHistogram<double>(
|
||||
"stellaops_vulnsurface_download_duration_seconds",
|
||||
unit: "s",
|
||||
description: "Duration of package download operations",
|
||||
advice: new InstrumentAdvice<double>
|
||||
{
|
||||
HistogramBucketBoundaries = [0.1, 0.5, 1.0, 2.5, 5.0, 10.0, 30.0]
|
||||
});
|
||||
|
||||
/// <summary>
|
||||
/// Fingerprinting duration per package.
|
||||
/// </summary>
|
||||
public static readonly Histogram<double> FingerprintDurationSeconds = Meter.CreateHistogram<double>(
|
||||
"stellaops_vulnsurface_fingerprint_duration_seconds",
|
||||
unit: "s",
|
||||
description: "Duration of fingerprinting operations",
|
||||
advice: new InstrumentAdvice<double>
|
||||
{
|
||||
HistogramBucketBoundaries = [0.05, 0.1, 0.25, 0.5, 1.0, 2.5, 5.0, 10.0]
|
||||
});
|
||||
|
||||
/// <summary>
|
||||
/// Diff computation duration.
|
||||
/// </summary>
|
||||
public static readonly Histogram<double> DiffDurationSeconds = Meter.CreateHistogram<double>(
|
||||
"stellaops_vulnsurface_diff_duration_seconds",
|
||||
unit: "s",
|
||||
description: "Duration of diff computation",
|
||||
advice: new InstrumentAdvice<double>
|
||||
{
|
||||
HistogramBucketBoundaries = [0.001, 0.01, 0.05, 0.1, 0.25, 0.5, 1.0]
|
||||
});
|
||||
|
||||
// ===== SIZE HISTOGRAMS =====
|
||||
|
||||
/// <summary>
|
||||
/// Number of methods per package version.
|
||||
/// </summary>
|
||||
public static readonly Histogram<int> MethodsPerPackage = Meter.CreateHistogram<int>(
|
||||
"stellaops_vulnsurface_methods_per_package",
|
||||
description: "Number of methods per analyzed package version",
|
||||
advice: new InstrumentAdvice<int>
|
||||
{
|
||||
HistogramBucketBoundaries = [10, 50, 100, 250, 500, 1000, 2500, 5000, 10000]
|
||||
});
|
||||
|
||||
/// <summary>
|
||||
/// Number of sinks per surface.
|
||||
/// </summary>
|
||||
public static readonly Histogram<int> SinksPerSurface = Meter.CreateHistogram<int>(
|
||||
"stellaops_vulnsurface_sinks_per_surface",
|
||||
description: "Number of sink methods per vulnerability surface",
|
||||
advice: new InstrumentAdvice<int>
|
||||
{
|
||||
HistogramBucketBoundaries = [1, 2, 5, 10, 25, 50, 100, 250]
|
||||
});
|
||||
|
||||
// ===== ECOSYSTEM DISTRIBUTION =====
|
||||
|
||||
private static int _nugetSurfaces;
|
||||
private static int _npmSurfaces;
|
||||
private static int _mavenSurfaces;
|
||||
private static int _pypiSurfaces;
|
||||
|
||||
/// <summary>
|
||||
/// Current count of NuGet surfaces.
|
||||
/// </summary>
|
||||
public static readonly ObservableGauge<int> NuGetSurfaceCount = Meter.CreateObservableGauge(
|
||||
"stellaops_vulnsurface_nuget_count",
|
||||
() => _nugetSurfaces,
|
||||
description: "Current count of NuGet vulnerability surfaces");
|
||||
|
||||
/// <summary>
|
||||
/// Current count of npm surfaces.
|
||||
/// </summary>
|
||||
public static readonly ObservableGauge<int> NpmSurfaceCount = Meter.CreateObservableGauge(
|
||||
"stellaops_vulnsurface_npm_count",
|
||||
() => _npmSurfaces,
|
||||
description: "Current count of npm vulnerability surfaces");
|
||||
|
||||
/// <summary>
|
||||
/// Current count of Maven surfaces.
|
||||
/// </summary>
|
||||
public static readonly ObservableGauge<int> MavenSurfaceCount = Meter.CreateObservableGauge(
|
||||
"stellaops_vulnsurface_maven_count",
|
||||
() => _mavenSurfaces,
|
||||
description: "Current count of Maven vulnerability surfaces");
|
||||
|
||||
/// <summary>
|
||||
/// Current count of PyPI surfaces.
|
||||
/// </summary>
|
||||
public static readonly ObservableGauge<int> PyPISurfaceCount = Meter.CreateObservableGauge(
|
||||
"stellaops_vulnsurface_pypi_count",
|
||||
() => _pypiSurfaces,
|
||||
description: "Current count of PyPI vulnerability surfaces");
|
||||
|
||||
/// <summary>
|
||||
/// Updates the ecosystem surface counts.
|
||||
/// </summary>
|
||||
public static void SetEcosystemCounts(int nuget, int npm, int maven, int pypi)
|
||||
{
|
||||
Interlocked.Exchange(ref _nugetSurfaces, nuget);
|
||||
Interlocked.Exchange(ref _npmSurfaces, npm);
|
||||
Interlocked.Exchange(ref _mavenSurfaces, maven);
|
||||
Interlocked.Exchange(ref _pypiSurfaces, pypi);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Increments the surface count for an ecosystem.
|
||||
/// </summary>
|
||||
public static void IncrementEcosystemCount(string ecosystem)
|
||||
{
|
||||
switch (ecosystem.ToLowerInvariant())
|
||||
{
|
||||
case "nuget":
|
||||
Interlocked.Increment(ref _nugetSurfaces);
|
||||
break;
|
||||
case "npm":
|
||||
Interlocked.Increment(ref _npmSurfaces);
|
||||
break;
|
||||
case "maven":
|
||||
Interlocked.Increment(ref _mavenSurfaces);
|
||||
break;
|
||||
case "pypi":
|
||||
Interlocked.Increment(ref _pypiSurfaces);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user