Skip to content

Commit d9e8a7c

Browse files
author
Aayush Maini
committed
Add telemetry for rust detection
1 parent e743edd commit d9e8a7c

File tree

2 files changed

+98
-1
lines changed

2 files changed

+98
-1
lines changed
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
namespace Microsoft.ComponentDetection.Common.Telemetry.Records;
2+
3+
public class RustDetectionTelemetryRecord : BaseDetectionTelemetryRecord
4+
{
5+
public override string RecordName => "RustDetection";
6+
7+
public string DetectionMode { get; set; }
8+
9+
public int SkippedCargoTomlCount { get; set; }
10+
11+
public int SkippedCargoLockCount { get; set; }
12+
13+
public int TotalSkippedFiles { get; set; }
14+
15+
public int ProcessedCargoTomlCount { get; set; }
16+
17+
public int ProcessedCargoLockCount { get; set; }
18+
19+
public int ProcessedSbomCount { get; set; }
20+
21+
public int TotalProcessedFiles { get; set; }
22+
23+
public int OwnershipMapPackageCount { get; set; }
24+
25+
public bool OwnershipMapAvailable { get; set; }
26+
27+
public string SkipRatio { get; set; }
28+
}

src/Microsoft.ComponentDetection.Detectors/rust/RustSbomDetector.cs

Lines changed: 70 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ namespace Microsoft.ComponentDetection.Detectors.Rust;
99
using System.Threading;
1010
using System.Threading.Tasks;
1111
using global::DotNet.Globbing;
12+
using Microsoft.ComponentDetection.Common.Telemetry.Records;
1213
using Microsoft.ComponentDetection.Contracts;
1314
using Microsoft.ComponentDetection.Contracts.Internal;
1415
using Microsoft.ComponentDetection.Contracts.TypedComponent;
@@ -43,6 +44,14 @@ public class RustSbomDetector : FileComponentDetector
4344
private Dictionary<string, Contracts.CargoMetadata> manifestMetadataCache;
4445
private DetectionMode mode;
4546

47+
// Telemetry counters
48+
private int skippedCargoTomlCount;
49+
private int skippedCargoLockCount;
50+
private int processedCargoTomlCount;
51+
private int processedCargoLockCount;
52+
private int processedSbomCount;
53+
private int totalPackagesInOwnershipMap;
54+
4655
public RustSbomDetector(
4756
IComponentStreamEnumerableFactory componentStreamEnumerableFactory,
4857
IObservableDirectoryWalkerFactory walkerFactory,
@@ -72,6 +81,14 @@ public RustSbomDetector(
7281
this.visitedDirs = new HashSet<string>(this.pathComparer);
7382
this.visitedGlobRules = [];
7483
this.manifestMetadataCache = new Dictionary<string, Contracts.CargoMetadata>(this.pathComparer);
84+
85+
// Initialize telemetry counters
86+
this.skippedCargoTomlCount = 0;
87+
this.skippedCargoLockCount = 0;
88+
this.processedCargoTomlCount = 0;
89+
this.processedCargoLockCount = 0;
90+
this.processedSbomCount = 0;
91+
this.totalPackagesInOwnershipMap = 0;
7592
}
7693

7794
/// <summary>
@@ -159,9 +176,11 @@ protected override async Task<IObservable<ProcessRequest>> OnPrepareDetectionAsy
159176
var ownership = await this.metadataContextBuilder.BuildPackageOwnershipMapAsync(tomlPaths, cancellationToken);
160177
this.ownershipMap = ownership.PackageToTomls;
161178
this.manifestMetadataCache = ownership.ManifestToMetadata;
179+
this.totalPackagesInOwnershipMap = this.ownershipMap?.Count ?? 0;
180+
162181
this.Logger.LogInformation(
163182
"Loaded Rust ownership (packages: {PkgCount}) and metadata cache (manifests: {ManifestCount})",
164-
this.ownershipMap?.Count ?? 0,
183+
this.totalPackagesInOwnershipMap,
165184
this.manifestMetadataCache?.Count ?? 0);
166185

167186
if (ownership.FailedManifests?.Count > 0)
@@ -177,13 +196,15 @@ protected override async Task<IObservable<ProcessRequest>> OnPrepareDetectionAsy
177196
this.Logger.LogWarning(ex, "Failed to compute Rust ownership/metadata cache; proceeding without cache");
178197
this.ownershipMap = null;
179198
this.manifestMetadataCache = null;
199+
this.totalPackagesInOwnershipMap = 0;
180200
}
181201
}
182202
else
183203
{
184204
this.Logger.LogInformation("No Cargo.toml files found; ownership and metadata cache unavailable");
185205
this.ownershipMap = null;
186206
this.manifestMetadataCache = null;
207+
this.totalPackagesInOwnershipMap = 0;
187208
}
188209

189210
IEnumerable<ProcessRequest> filteredRequests;
@@ -251,27 +272,75 @@ protected override async Task OnFileFoundAsync(
251272
if (this.ShouldSkip(directory, fileKind, location))
252273
{
253274
this.Logger.LogInformation("Skipping file due to skip rules: {Location}", normLocation);
275+
276+
// Increment skip counters
277+
switch (fileKind)
278+
{
279+
case FileKind.CargoToml:
280+
Interlocked.Increment(ref this.skippedCargoTomlCount);
281+
break;
282+
case FileKind.CargoLock:
283+
Interlocked.Increment(ref this.skippedCargoLockCount);
284+
break;
285+
case FileKind.CargoSbom:
286+
break;
287+
default:
288+
break;
289+
}
290+
254291
return;
255292
}
256293

257294
if (this.mode == DetectionMode.SBOM_ONLY)
258295
{
259296
await this.ProcessSbomFileAsync(processRequest, cancellationToken);
297+
Interlocked.Increment(ref this.processedSbomCount);
260298
}
261299
else
262300
{
263301
// FALLBACK mode
264302
if (fileKind == FileKind.CargoToml)
265303
{
266304
await this.ProcessCargoTomlAsync(processRequest, directory, cancellationToken);
305+
Interlocked.Increment(ref this.processedCargoTomlCount);
267306
}
268307
else if (fileKind == FileKind.CargoLock)
269308
{
270309
await this.ProcessCargoLockAsync(processRequest, directory, cancellationToken);
310+
Interlocked.Increment(ref this.processedCargoLockCount);
271311
}
272312
}
273313
}
274314

315+
/// <inheritdoc />
316+
protected override Task OnDetectionFinishedAsync()
317+
{
318+
// Record telemetry using the using pattern
319+
var totalSkippedFiles = this.skippedCargoTomlCount + this.skippedCargoLockCount;
320+
var totalProcessedFiles = this.processedCargoTomlCount + this.processedCargoLockCount + this.processedSbomCount;
321+
var totalFiles = totalSkippedFiles + totalProcessedFiles;
322+
var skipRatio = totalFiles > 0
323+
? $"{100.0 * totalSkippedFiles / totalFiles:0.00}%"
324+
: "0.00%";
325+
326+
using var telemetryRecord = new RustDetectionTelemetryRecord
327+
{
328+
DetectionMode = this.mode.ToString(),
329+
SkippedCargoTomlCount = this.skippedCargoTomlCount,
330+
SkippedCargoLockCount = this.skippedCargoLockCount,
331+
TotalSkippedFiles = totalSkippedFiles,
332+
ProcessedCargoTomlCount = this.processedCargoTomlCount,
333+
ProcessedCargoLockCount = this.processedCargoLockCount,
334+
ProcessedSbomCount = this.processedSbomCount,
335+
TotalProcessedFiles = totalProcessedFiles,
336+
OwnershipMapPackageCount = this.totalPackagesInOwnershipMap,
337+
OwnershipMapAvailable = this.ownershipMap != null,
338+
SkipRatio = skipRatio,
339+
};
340+
341+
return Task.CompletedTask;
342+
}
343+
275344
/// <summary>
276345
/// Calculates the depth of a directory path by counting the number of directory separators.
277346
/// </summary>

0 commit comments

Comments
 (0)