Skip to content

Commit 20f0c6d

Browse files
authored
Fix runtime stack metric logging (#5643)
1 parent 99cf7c8 commit 20f0c6d

File tree

3 files changed

+99
-11
lines changed

3 files changed

+99
-11
lines changed

src/WebJobs.Script/Environment/EnvironmentSettingNames.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ public static class EnvironmentSettingNames
2525
public const string AppInsightsConnectionString = "APPLICATIONINSIGHTS_CONNECTION_STRING";
2626
public const string AppInsightsQuickPulseAuthApiKey = "APPINSIGHTS_QUICKPULSEAUTHAPIKEY";
2727
public const string FunctionsExtensionVersion = "FUNCTIONS_EXTENSION_VERSION";
28+
public const string WebsiteNodeDefaultVersion = "WEBSITE_NODE_DEFAULT_VERSION";
2829
public const string ContainerName = "CONTAINER_NAME";
2930
public const string WebSiteHomeStampName = "WEBSITE_HOME_STAMPNAME";
3031
public const string WebSiteStampDeploymentId = "WEBSITE_STAMP_DEPLOYMENT_ID";

src/WebJobs.Script/Host/ScriptHost.cs

Lines changed: 32 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -274,17 +274,9 @@ public async Task InitializeAsync(CancellationToken cancellationToken = default)
274274

275275
if (!_environment.IsPlaceholderModeEnabled())
276276
{
277-
string runtimeStack = _workerRuntime;
278-
279-
// Appending the runtime version is currently only enabled for linux consumption. This will be eventually enabled for
280-
// Windows Consumption as well.
281-
string runtimeVersion = _environment.GetEnvironmentVariable(RpcWorkerConstants.FunctionWorkerRuntimeVersionSettingName);
282-
283-
if (!string.IsNullOrEmpty(runtimeVersion))
284-
{
285-
runtimeStack = string.Concat(runtimeStack, "-", runtimeVersion);
286-
}
287-
277+
// Appending the runtime version is currently only enabled for linux consumption.
278+
// This will be eventually enabled for Windows Consumption as well.
279+
string runtimeStack = GetPreciseRuntimeStack(_workerRuntime);
288280
_metricsLogger.LogEvent(string.Format(MetricEventNames.HostStartupRuntimeLanguage, runtimeStack));
289281
}
290282

@@ -300,6 +292,35 @@ public async Task InitializeAsync(CancellationToken cancellationToken = default)
300292
}
301293
}
302294

295+
/// <summary>
296+
/// Appends specific functions worker runtime version after runtime stack
297+
/// </summary>
298+
/// <returns>A string contains specific runtime stack (e.g. python-3.6, dotnet-~2) or single stack</returns>
299+
private string GetPreciseRuntimeStack(string runtime)
300+
{
301+
string runtimeStack = runtime?.ToLower() ?? string.Empty;
302+
string preciseRuntime = string.Empty;
303+
switch (runtimeStack)
304+
{
305+
case "dotnet":
306+
// Get Dotnet version from FUNCTIONS_EXTENSION_VERSION
307+
preciseRuntime = $"dotnet-{_environment.GetEnvironmentVariable(EnvironmentSettingNames.FunctionsExtensionVersion)}";
308+
break;
309+
case "node":
310+
// Get Node version from WEBSITE_NODE_DEFAULT_VERSION
311+
preciseRuntime = $"node-{_environment.GetEnvironmentVariable(EnvironmentSettingNames.WebsiteNodeDefaultVersion)}";
312+
break;
313+
case "python":
314+
preciseRuntime = $"python-{_environment.GetEnvironmentVariable(RpcWorkerConstants.FunctionWorkerRuntimeVersionSettingName)}";
315+
break;
316+
default:
317+
// PowerShell, Java only has single version
318+
preciseRuntime = runtimeStack;
319+
break;
320+
}
321+
return preciseRuntime.TrimEnd('-');
322+
}
323+
303324
private async Task LogInitializationAsync()
304325
{
305326
// If the host id is explicitly set, emit a warning that this could cause issues and shouldn't be done

test/WebJobs.Script.Tests/ScriptHostTests.cs

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
using Microsoft.Azure.WebJobs.Script.Config;
1616
using Microsoft.Azure.WebJobs.Script.Configuration;
1717
using Microsoft.Azure.WebJobs.Script.Description;
18+
using Microsoft.Azure.WebJobs.Script.Diagnostics;
1819
using Microsoft.Azure.WebJobs.Script.Eventing;
1920
using Microsoft.Azure.WebJobs.Script.Workers.Rpc;
2021
using Microsoft.Extensions.Configuration;
@@ -404,6 +405,71 @@ public async Task Initialize_WithLatestSiteExtensionVersion_LogsWarning()
404405
}
405406
}
406407

408+
[Theory]
409+
[InlineData("dotnet", "", "", "", "dotnet")]
410+
[InlineData("dotnet", "~2", "", "", "dotnet-~2")]
411+
[InlineData("python", "~2", "", "", "python")]
412+
[InlineData("python", "~2", "", "3.6", "python-3.6")]
413+
[InlineData("python", "~3", "~8", "3.7", "python-3.7")]
414+
[InlineData("node", "~3", "", "3.6", "node")]
415+
[InlineData("node", "~2", "~8", "3.6", "node-~8")]
416+
[InlineData("powershell", "~2", "", "", "powershell")]
417+
[InlineData("powershell", "~2", "~10", "3.6", "powershell")]
418+
[InlineData("java", "~3", "", "", "java")]
419+
[InlineData("java", "~3", "~8", "3.6", "java")]
420+
public async Task Initialize_WithRuntimeAndWorkerVersion_ReportRuntimeToMetricsTable(
421+
string functionsWorkerRuntime,
422+
string functionsExtensionVersion,
423+
string websiteNodeDefaultVersion,
424+
string functionsWorkerRuntimeVersion,
425+
string expectedRuntimeStack)
426+
{
427+
try
428+
{
429+
using (var tempDirectory = new TempDirectory())
430+
{
431+
string rootPath = Path.Combine(tempDirectory.Path, Guid.NewGuid().ToString());
432+
Directory.CreateDirectory(rootPath);
433+
var metricsLogger = new TestMetricsLogger();
434+
var environment = new TestEnvironment();
435+
436+
environment.SetEnvironmentVariable(
437+
RpcWorkerConstants.FunctionWorkerRuntimeSettingName, functionsWorkerRuntime);
438+
environment.SetEnvironmentVariable(
439+
EnvironmentSettingNames.FunctionsExtensionVersion, functionsExtensionVersion);
440+
environment.SetEnvironmentVariable(
441+
EnvironmentSettingNames.WebsiteNodeDefaultVersion, websiteNodeDefaultVersion);
442+
environment.SetEnvironmentVariable(
443+
RpcWorkerConstants.FunctionWorkerRuntimeVersionSettingName, functionsWorkerRuntimeVersion);
444+
445+
IHost host = new HostBuilder()
446+
.ConfigureServices(s =>
447+
{
448+
s.AddSingleton<IEnvironment>(environment);
449+
})
450+
.ConfigureDefaultTestWebScriptHost(
451+
null,
452+
o =>
453+
{
454+
o.ScriptPath = rootPath;
455+
},
456+
false,
457+
s =>
458+
{
459+
s.AddSingleton<IMetricsLogger>(metricsLogger);
460+
})
461+
.Build();
462+
var scriptHost = host.GetScriptHost();
463+
await scriptHost.InitializeAsync();
464+
Assert.Single(metricsLogger.LoggedEvents, e => e.Equals($"host.startup.runtime.language.{expectedRuntimeStack}"));
465+
}
466+
}
467+
finally
468+
{
469+
EnvironmentExtensions.BaseDirectory = null;
470+
}
471+
}
472+
407473
// TODO: Newer TODO - ApplyConfiguration no longer exists. Validate logic (moved to HostJsonFileConfigurationSource)
408474
// TODO: Move this test into a new WebJobsCoreScriptBindingProvider class since
409475
// the functionality moved. Also add tests for the ServiceBus config, etc.

0 commit comments

Comments
 (0)