Skip to content

Commit 572d95d

Browse files
committed
[gh-1150] Update feature metrics to use dimensions
1 parent b521cbe commit 572d95d

37 files changed

+651
-747
lines changed

source/Container.Manager/Azure/ContainerCountMetricReporter.cs

Lines changed: 27 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -8,39 +8,39 @@
88
using Microsoft.Extensions.Hosting;
99
using Microsoft.Extensions.Logging;
1010

11-
namespace SharpLab.Container.Manager.Azure {
12-
public class ContainerCountMetricReporter : BackgroundService {
13-
private static readonly string ContainerProcessName = Path.GetFileNameWithoutExtension(Container.Program.ExeFileName);
14-
private static readonly MetricIdentifier ContainerCountMetric = new("Custom Metrics", "Container Count");
11+
namespace SharpLab.Container.Manager.Azure;
1512

16-
private readonly TelemetryClient _telemetryClient;
17-
private readonly ILogger<ContainerCountMetricReporter> _logger;
13+
public class ContainerCountMetricReporter : BackgroundService {
14+
private static readonly string ContainerProcessName = Path.GetFileNameWithoutExtension(Container.Program.ExeFileName);
15+
private static readonly MetricIdentifier ContainerCountMetric = new("Custom Metrics", "Container Count");
1816

19-
public ContainerCountMetricReporter(
20-
TelemetryClient telemetryClient,
21-
ILogger<ContainerCountMetricReporter> logger
22-
) {
23-
_telemetryClient = telemetryClient;
24-
_logger = logger;
25-
}
17+
private readonly TelemetryClient _telemetryClient;
18+
private readonly ILogger<ContainerCountMetricReporter> _logger;
2619

27-
protected override async Task ExecuteAsync(CancellationToken stoppingToken) {
28-
while (!stoppingToken.IsCancellationRequested) {
29-
try {
30-
var count = 0;
31-
foreach (var process in Process.GetProcessesByName(ContainerProcessName)) {
32-
count += 1;
33-
process.Dispose();
34-
}
20+
public ContainerCountMetricReporter(
21+
TelemetryClient telemetryClient,
22+
ILogger<ContainerCountMetricReporter> logger
23+
) {
24+
_telemetryClient = telemetryClient;
25+
_logger = logger;
26+
}
3527

36-
_telemetryClient.GetMetric(ContainerCountMetric).TrackValue(count);
37-
}
38-
catch (Exception ex) {
39-
_logger.LogError(ex, "Failed to report container count");
40-
await Task.Delay(TimeSpan.FromMinutes(4), stoppingToken);
28+
protected override async Task ExecuteAsync(CancellationToken stoppingToken) {
29+
while (!stoppingToken.IsCancellationRequested) {
30+
try {
31+
var count = 0;
32+
foreach (var process in Process.GetProcessesByName(ContainerProcessName)) {
33+
count += 1;
34+
process.Dispose();
4135
}
42-
await Task.Delay(TimeSpan.FromMinutes(1), stoppingToken);
36+
37+
_telemetryClient.GetMetric(ContainerCountMetric).TrackValue(count);
38+
}
39+
catch (Exception ex) {
40+
_logger.LogError(ex, "Failed to report container count");
41+
await Task.Delay(TimeSpan.FromMinutes(4), stoppingToken);
4342
}
43+
await Task.Delay(TimeSpan.FromMinutes(1), stoppingToken);
4444
}
4545
}
4646
}

source/Container.Manager/Startup.cs

Lines changed: 50 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -9,67 +9,67 @@
99
using SharpLab.Container.Manager.Endpoints;
1010
using SharpLab.Container.Manager.Internal;
1111

12-
namespace SharpLab.Container.Manager {
13-
[SupportedOSPlatform("windows")]
14-
public class Startup {
15-
// This method gets called by the runtime. Use this method to add services to the container.
16-
// For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940
12+
namespace SharpLab.Container.Manager;
1713

18-
public void ConfigureServices(IServiceCollection services)
19-
{
20-
// TODO: proper DI, e.g. Autofac
21-
services.AddSingleton(new ProcessRunnerConfiguration(
22-
workingDirectoryPath: AppContext.BaseDirectory,
23-
exeFileName: Container.Program.ExeFileName,
24-
essentialAccessCapabilitySid: "S-1-15-3-1024-4233803318-1181731508-1220533431-3050556506-2713139869-1168708946-594703785-1824610955",
25-
maximumMemorySize: 30 * 1024 * 1024,
26-
maximumCpuPercentage: 1
27-
));
28-
services.AddSingleton<IProcessRunner, ProcessRunner>();
29-
services.AddSingleton<IDateTimeProvider, DateTimeProvider>();
14+
[SupportedOSPlatform("windows")]
15+
public class Startup {
16+
// This method gets called by the runtime. Use this method to add services to the container.
17+
// For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940
3018

31-
services.AddSingleton<StatusEndpoint>();
19+
public void ConfigureServices(IServiceCollection services)
20+
{
21+
// TODO: proper DI, e.g. Autofac
22+
services.AddSingleton(new ProcessRunnerConfiguration(
23+
workingDirectoryPath: AppContext.BaseDirectory,
24+
exeFileName: Container.Program.ExeFileName,
25+
essentialAccessCapabilitySid: "S-1-15-3-1024-4233803318-1181731508-1220533431-3050556506-2713139869-1168708946-594703785-1824610955",
26+
maximumMemorySize: 30 * 1024 * 1024,
27+
maximumCpuPercentage: 1
28+
));
29+
services.AddSingleton<IProcessRunner, ProcessRunner>();
30+
services.AddSingleton<IDateTimeProvider, DateTimeProvider>();
3231

33-
var authorizationToken = Environment.GetEnvironmentVariable("SHARPLAB_CONTAINER_HOST_AUTHORIZATION_TOKEN")
34-
?? throw new Exception("Required environment variable SHARPLAB_CONTAINER_HOST_AUTHORIZATION_TOKEN was not provided.");
35-
services.AddSingleton(new ExecutionEndpointSettings(authorizationToken));
36-
services.AddSingleton<ExecutionEndpoint>();
32+
services.AddSingleton<StatusEndpoint>();
3733

38-
services.AddSingleton<ContainerPool>();
34+
var authorizationToken = Environment.GetEnvironmentVariable("SHARPLAB_CONTAINER_HOST_AUTHORIZATION_TOKEN")
35+
?? throw new Exception("Required environment variable SHARPLAB_CONTAINER_HOST_AUTHORIZATION_TOKEN was not provided.");
36+
services.AddSingleton(new ExecutionEndpointSettings(authorizationToken));
37+
services.AddSingleton<ExecutionEndpoint>();
3938

40-
services.AddHostedService<ContainerAllocationWorker>();
41-
services.AddSingleton<ContainerCleanupWorker>();
42-
services.AddHostedService(c => c.GetRequiredService<ContainerCleanupWorker>());
39+
services.AddSingleton<ContainerPool>();
4340

44-
services.AddSingleton<StdinWriter>();
45-
services.AddSingleton<StdoutReader>();
46-
services.AddSingleton<ExecutionProcessor>();
47-
services.AddSingleton<CrashSuspensionManager>();
48-
services.AddSingleton<ExecutionManager>();
41+
services.AddHostedService<ContainerAllocationWorker>();
42+
services.AddSingleton<ContainerCleanupWorker>();
43+
services.AddHostedService(c => c.GetRequiredService<ContainerCleanupWorker>());
4944

50-
ConfigureAzureDependentServices(services);
51-
}
45+
services.AddSingleton<StdinWriter>();
46+
services.AddSingleton<StdoutReader>();
47+
services.AddSingleton<ExecutionProcessor>();
48+
services.AddSingleton<CrashSuspensionManager>();
49+
services.AddSingleton<ExecutionManager>();
5250

53-
private void ConfigureAzureDependentServices(IServiceCollection services) {
54-
var connectionString = Environment.GetEnvironmentVariable("SHARPLAB_TELEMETRY_CONNECTION_STRING");
55-
if (connectionString == null) {
56-
Console.WriteLine("[WARN] AppInsights connection string was not found.");
57-
return;
58-
}
51+
ConfigureAzureDependentServices(services);
52+
}
5953

60-
var configuration = new TelemetryConfiguration { ConnectionString = connectionString };
61-
services.AddSingleton(new TelemetryClient(configuration));
62-
services.AddHostedService<ContainerCountMetricReporter>();
54+
private void ConfigureAzureDependentServices(IServiceCollection services) {
55+
var connectionString = Environment.GetEnvironmentVariable("SHARPLAB_TELEMETRY_CONNECTION_STRING");
56+
if (connectionString == null) {
57+
Console.WriteLine("[WARN] AppInsights connection string was not found.");
58+
return;
6359
}
6460

65-
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
66-
public void Configure(IApplicationBuilder app) {
67-
app.UseRouting();
61+
var configuration = new TelemetryConfiguration { ConnectionString = connectionString };
62+
services.AddSingleton(new TelemetryClient(configuration));
63+
services.AddHostedService<ContainerCountMetricReporter>();
64+
}
6865

69-
app.UseEndpoints(endpoints => {
70-
endpoints.MapGet("/status", app.ApplicationServices.GetRequiredService<StatusEndpoint>().ExecuteAsync);
71-
endpoints.MapPost("/", app.ApplicationServices.GetRequiredService<ExecutionEndpoint>().ExecuteAsync);
72-
});
73-
}
66+
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
67+
public void Configure(IApplicationBuilder app) {
68+
app.UseRouting();
69+
70+
app.UseEndpoints(endpoints => {
71+
endpoints.MapGet("/status", app.ApplicationServices.GetRequiredService<StatusEndpoint>().ExecuteAsync);
72+
endpoints.MapPost("/", app.ApplicationServices.GetRequiredService<ExecutionEndpoint>().ExecuteAsync);
73+
});
7474
}
7575
}

source/NetFramework/Server/Common/CommonModule.cs

Lines changed: 51 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -7,56 +7,56 @@
77
using SharpLab.Server.Common.Internal;
88
using SharpLab.Server.Common.Languages;
99

10-
namespace SharpLab.Server.Common {
11-
[UsedImplicitly]
12-
public class CommonModule : Module {
13-
protected override void Load(ContainerBuilder builder) {
14-
RegisterExternals(builder);
15-
16-
builder.RegisterType<AssemblyReferenceCollector>()
17-
.As<IAssemblyReferenceCollector>()
18-
.SingleInstance();
19-
20-
builder.RegisterType<PreCachedAssemblyResolver>()
21-
.As<ICSharpCode.Decompiler.Metadata.IAssemblyResolver>()
22-
.As<Mono.Cecil.IAssemblyResolver>()
23-
.SingleInstance();
24-
25-
builder.RegisterType<CSharpAdapter>()
26-
.As<ILanguageAdapter>()
27-
.SingleInstance();
28-
29-
builder.RegisterType<VisualBasicAdapter>()
30-
.As<ILanguageAdapter>()
31-
.SingleInstance();
32-
33-
builder.RegisterType<FSharpAdapter>()
34-
.As<ILanguageAdapter>()
35-
.SingleInstance();
36-
37-
builder.RegisterType<ILAdapter>()
38-
.As<ILanguageAdapter>()
39-
.SingleInstance();
40-
41-
var webAppName = EnvironmentHelper.GetRequiredEnvironmentVariable("SHARPLAB_WEBAPP_NAME");
42-
builder.RegisterType<FeatureTracker>()
43-
.As<IFeatureTracker>()
44-
.SingleInstance()
45-
.WithParameter("webAppName", webAppName);
46-
}
47-
48-
private void RegisterExternals(ContainerBuilder builder) {
49-
builder.RegisterInstance(new RecyclableMemoryStreamManager())
50-
.AsSelf();
51-
52-
builder.RegisterInstance<Func<HttpClient>>(() => new HttpClient())
53-
.As<Func<HttpClient>>()
54-
.SingleInstance()
55-
.PreserveExistingDefaults(); // allows tests and other overrides
56-
57-
builder.RegisterType<PortablePdbReaderProvider>()
58-
.As<ISymbolReaderProvider>()
59-
.SingleInstance();
60-
}
10+
namespace SharpLab.Server.Common;
11+
12+
[UsedImplicitly]
13+
public class CommonModule : Module {
14+
protected override void Load(ContainerBuilder builder) {
15+
RegisterExternals(builder);
16+
17+
builder.RegisterType<AssemblyReferenceCollector>()
18+
.As<IAssemblyReferenceCollector>()
19+
.SingleInstance();
20+
21+
builder.RegisterType<PreCachedAssemblyResolver>()
22+
.As<ICSharpCode.Decompiler.Metadata.IAssemblyResolver>()
23+
.As<Mono.Cecil.IAssemblyResolver>()
24+
.SingleInstance();
25+
26+
builder.RegisterType<CSharpAdapter>()
27+
.As<ILanguageAdapter>()
28+
.SingleInstance();
29+
30+
builder.RegisterType<VisualBasicAdapter>()
31+
.As<ILanguageAdapter>()
32+
.SingleInstance();
33+
34+
builder.RegisterType<FSharpAdapter>()
35+
.As<ILanguageAdapter>()
36+
.SingleInstance();
37+
38+
builder.RegisterType<ILAdapter>()
39+
.As<ILanguageAdapter>()
40+
.SingleInstance();
41+
42+
var webAppName = EnvironmentHelper.GetRequiredEnvironmentVariable("SHARPLAB_WEBAPP_NAME");
43+
builder.RegisterType<FeatureTracker>()
44+
.As<IFeatureTracker>()
45+
.SingleInstance()
46+
.WithParameter("webAppName", webAppName);
47+
}
48+
49+
private void RegisterExternals(ContainerBuilder builder) {
50+
builder.RegisterInstance(new RecyclableMemoryStreamManager())
51+
.AsSelf();
52+
53+
builder.RegisterInstance<Func<HttpClient>>(() => new HttpClient())
54+
.As<Func<HttpClient>>()
55+
.SingleInstance()
56+
.PreserveExistingDefaults(); // allows tests and other overrides
57+
58+
builder.RegisterType<PortablePdbReaderProvider>()
59+
.As<ISymbolReaderProvider>()
60+
.SingleInstance();
6161
}
6262
}
Lines changed: 15 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,51 +1,35 @@
11
using SharpLab.Server.Monitoring;
2-
using System.Collections.Generic;
3-
using System.Linq;
42

53
namespace SharpLab.Server.Common;
64

75
public class FeatureTracker : IFeatureTracker {
8-
private readonly IMetricMonitor _branchMonitor;
9-
private readonly IReadOnlyDictionary<string, IMetricMonitor> _languageMetricMonitors;
10-
private readonly IReadOnlyDictionary<string, IMetricMonitor> _targetMetricMonitors;
11-
private readonly IMetricMonitor _optimizeDebugMonitor;
12-
private readonly IMetricMonitor _optimizeReleaseMonitor;
6+
private readonly string _webAppName;
7+
private readonly IOneDimensionMetricMonitor _branchMetricMonitor;
8+
private readonly IOneDimensionMetricMonitor _languageMetricMonitor;
9+
private readonly IOneDimensionMetricMonitor _targetMetricMonitor;
10+
private readonly IOneDimensionMetricMonitor _optimizeMetricMonitor;
1311

1412
public FeatureTracker(IMonitor monitor, string webAppName) {
15-
_branchMonitor = monitor.MetricSlow("feature", $"Branch: {webAppName}");
16-
_languageMetricMonitors = LanguageNames.All.ToDictionary(
17-
name => name,
18-
name => monitor.MetricSlow("feature", $"Language: {name}")
19-
);
20-
_targetMetricMonitors = TargetNames.All.ToDictionary(
21-
name => name,
22-
name => monitor.MetricSlow("feature", $"Target: {name}")
23-
);
24-
25-
_optimizeDebugMonitor = monitor.MetricSlow("feature", "Optimize: Debug");
26-
_optimizeReleaseMonitor = monitor.MetricSlow("feature", "Optimize: Release");
13+
_webAppName = webAppName;
14+
_branchMetricMonitor = monitor.MetricSlow("feature", "Branch", "Branch");
15+
_languageMetricMonitor = monitor.MetricSlow("feature", "Language", "Language");
16+
_targetMetricMonitor = monitor.MetricSlow("feature", "Target", "Target");
17+
_optimizeMetricMonitor = monitor.MetricSlow("feature", "Optimize", "Optimize");
2718
}
2819

2920
public void TrackBranch() {
30-
_branchMonitor.Track(1);
21+
_branchMetricMonitor.Track(_webAppName, 1);
3122
}
3223

3324
public void TrackLanguage(string languageName) {
34-
if (_languageMetricMonitors.TryGetValue(languageName, out var metricMonitor))
35-
metricMonitor.Track(1);
25+
_languageMetricMonitor.Track(languageName, 1);
3626
}
3727

3828
public void TrackTarget(string targetName) {
39-
if (_targetMetricMonitors.TryGetValue(targetName, out var metricMonitor))
40-
metricMonitor.Track(1);
29+
_targetMetricMonitor.Track(targetName, 1);
4130
}
4231

43-
public void TrackOptimize(string? optimize) {
44-
var monitor = optimize switch {
45-
Optimize.Debug => _optimizeDebugMonitor,
46-
Optimize.Release => _optimizeReleaseMonitor,
47-
_ => null
48-
};
49-
monitor?.Track(1);
32+
public void TrackOptimize(string optimize) {
33+
_optimizeMetricMonitor.Track(optimize, 1);
5034
}
5135
}

source/NetFramework/Server/Common/IFeatureTracker.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,5 @@ public interface IFeatureTracker {
44
void TrackBranch();
55
void TrackLanguage(string languageName);
66
void TrackTarget(string targetName);
7-
void TrackOptimize(string? optimize);
7+
void TrackOptimize(string optimize);
88
}
Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
using System.Collections.Immutable;
21
using CodeAnalysis = Microsoft.CodeAnalysis;
32

43
namespace SharpLab.Server.Common;
@@ -8,8 +7,4 @@ public class LanguageNames {
87
public const string VisualBasic = CodeAnalysis.LanguageNames.VisualBasic;
98
public const string FSharp = CodeAnalysis.LanguageNames.FSharp;
109
public const string IL = "IL";
11-
12-
public static readonly ImmutableArray<string> All = ImmutableArray.Create(
13-
CSharp, VisualBasic, FSharp, IL
14-
);
1510
}
Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
using System.Collections.Immutable;
2-
31
namespace SharpLab.Server.Common;
42

53
public static class TargetNames {
@@ -10,8 +8,4 @@ public static class TargetNames {
108
public const string Run = "Run";
119
public const string Verify = "Verify";
1210
public const string Explain = "Explain";
13-
14-
public static readonly ImmutableArray<string> All = ImmutableArray.Create(
15-
CSharp, IL, Ast, JitAsm, Run, Verify, Explain
16-
);
1711
}

0 commit comments

Comments
 (0)