Skip to content

Commit 190e3f6

Browse files
Adding diagnostics for seabreeze (#4324)
1 parent 4c3c3a3 commit 190e3f6

File tree

4 files changed

+59
-12
lines changed

4 files changed

+59
-12
lines changed

src/WebJobs.Script.WebHost/Diagnostics/LinuxContainerEventGenerator.cs

Lines changed: 35 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,39 +10,68 @@ internal class LinuxContainerEventGenerator : LinuxEventGenerator
1010
{
1111
private readonly Action<string> _writeEvent;
1212
private readonly bool _consoleEnabled = true;
13+
private readonly IEnvironment _environment;
14+
private string _containerName;
15+
private string _stampName;
16+
private string _tenantId;
1317

14-
public LinuxContainerEventGenerator(Action<string> writeEvent = null)
18+
public LinuxContainerEventGenerator(IEnvironment environment, Action<string> writeEvent = null)
1519
{
1620
_writeEvent = writeEvent ?? ConsoleWriter;
17-
21+
_environment = environment;
1822
if (Environment.GetEnvironmentVariable(EnvironmentSettingNames.ConsoleLoggingDisabled) == "1")
1923
{
2024
_consoleEnabled = false;
2125
}
26+
_containerName = _environment.GetEnvironmentVariable(EnvironmentSettingNames.ContainerName)?.ToUpperInvariant();
2227
}
2328

2429
// Note: the strange escaping of backslashes in these expressions for string literals (e.g. '\\\\\"') is because
2530
// of the current JSON serialization our log messages undergoe.
26-
public static string TraceEventRegex { get; } = $"{ScriptConstants.LinuxLogEventStreamName} (?<Level>[0-6]),(?<SubscriptionId>[^,]*),(?<AppName>[^,]*),(?<FunctionName>[^,]*),(?<EventName>[^,]*),(?<Source>[^,]*),\\\\\"(?<Details>.*)\\\\\",\\\\\"(?<Summary>.*)\\\\\",(?<HostVersion>[^,]*),(?<EventTimestamp>[^,]+),(?<ExceptionType>[^,]*),\\\\\"(?<ExceptionMessage>.*)\\\\\",(?<FunctionInvocationId>[^,]*),(?<HostInstanceId>[^,]*),(?<ActivityId>[^,\"]*)";
31+
public static string TraceEventRegex { get; } = $"{ScriptConstants.LinuxLogEventStreamName} (?<Level>[0-6]),(?<SubscriptionId>[^,]*),(?<AppName>[^,]*),(?<FunctionName>[^,]*),(?<EventName>[^,]*),(?<Source>[^,]*),\\\\\"(?<Details>.*)\\\\\",\\\\\"(?<Summary>.*)\\\\\",(?<HostVersion>[^,]*),(?<EventTimestamp>[^,]+),(?<ExceptionType>[^,]*),\\\\\"(?<ExceptionMessage>.*)\\\\\",(?<FunctionInvocationId>[^,]*),(?<HostInstanceId>[^,]*),(?<ActivityId>[^,\"]*),(?<ContainerName>[^,\"]*),(?<StampName>[^,\"]*),(?<TenantId>[^,\"]*)";
2732

28-
public static string MetricEventRegex { get; } = $"{ScriptConstants.LinuxMetricEventStreamName} (?<SubscriptionId>[^,]*),(?<AppName>[^,]*),(?<FunctionName>[^,]*),(?<EventName>[^,]*),(?<Average>\\d*),(?<Min>\\d*),(?<Max>\\d*),(?<Count>\\d*),(?<HostVersion>[^,]*),(?<EventTimestamp>[^,]+),(?<Details>[^,\"]*)";
33+
public static string MetricEventRegex { get; } = $"{ScriptConstants.LinuxMetricEventStreamName} (?<SubscriptionId>[^,]*),(?<AppName>[^,]*),(?<FunctionName>[^,]*),(?<EventName>[^,]*),(?<Average>\\d*),(?<Min>\\d*),(?<Max>\\d*),(?<Count>\\d*),(?<HostVersion>[^,]*),(?<EventTimestamp>[^,]+),\\\\\"(?<Data>.*)\\\\\",(?<ContainerName>[^,\"]*),(?<StampName>[^,\"]*),(?<TenantId>[^,\"]*)";
2934

3035
public static string DetailsEventRegex { get; } = $"{ScriptConstants.LinuxFunctionDetailsEventStreamName} (?<AppName>[^,]*),(?<FunctionName>[^,]*),\\\\\"(?<InputBindings>.*)\\\\\",\\\\\"(?<OutputBindings>.*)\\\\\",(?<ScriptType>[^,]*),(?<IsDisabled>[0|1])";
3136

37+
private string StampName
38+
{
39+
get
40+
{
41+
if (string.IsNullOrEmpty(_stampName))
42+
{
43+
_stampName = _environment.GetEnvironmentVariable(EnvironmentSettingNames.WebSiteHomeStampName)?.ToLowerInvariant();
44+
}
45+
return _stampName;
46+
}
47+
}
48+
49+
private string TenantId
50+
{
51+
get
52+
{
53+
if (string.IsNullOrEmpty(_tenantId))
54+
{
55+
_tenantId = _environment.GetEnvironmentVariable(EnvironmentSettingNames.WebSiteStampDeploymentId)?.ToLowerInvariant();
56+
}
57+
return _tenantId;
58+
}
59+
}
60+
3261
public override void LogFunctionTraceEvent(LogLevel level, string subscriptionId, string appName, string functionName, string eventName, string source, string details, string summary, string exceptionType, string exceptionMessage, string functionInvocationId, string hostInstanceId, string activityId)
3362
{
3463
string eventTimestamp = DateTime.UtcNow.ToString(EventTimestampFormat);
3564
string hostVersion = ScriptHost.Version;
3665
FunctionsSystemLogsEventSource.Instance.SetActivityId(activityId);
3766

38-
_writeEvent($"{ScriptConstants.LinuxLogEventStreamName} {(int)ToEventLevel(level)},{subscriptionId},{appName},{functionName},{eventName},{source},{NormalizeString(details)},{NormalizeString(summary)},{hostVersion},{eventTimestamp},{exceptionType},{NormalizeString(exceptionMessage)},{functionInvocationId},{hostInstanceId},{activityId}");
67+
_writeEvent($"{ScriptConstants.LinuxLogEventStreamName} {(int)ToEventLevel(level)},{subscriptionId},{appName},{functionName},{eventName},{source},{NormalizeString(details)},{NormalizeString(summary)},{hostVersion},{eventTimestamp},{exceptionType},{NormalizeString(exceptionMessage)},{functionInvocationId},{hostInstanceId},{activityId},{_containerName},{StampName},{TenantId}");
3968
}
4069

4170
public override void LogFunctionMetricEvent(string subscriptionId, string appName, string functionName, string eventName, long average, long minimum, long maximum, long count, DateTime eventTimestamp, string data)
4271
{
4372
string hostVersion = ScriptHost.Version;
4473

45-
_writeEvent($"{ScriptConstants.LinuxMetricEventStreamName} {subscriptionId},{appName},{functionName},{eventName},{average},{minimum},{maximum},{count},{hostVersion},{eventTimestamp.ToString(EventTimestampFormat)},{data}");
74+
_writeEvent($"{ScriptConstants.LinuxMetricEventStreamName} {subscriptionId},{appName},{functionName},{eventName},{average},{minimum},{maximum},{count},{hostVersion},{eventTimestamp.ToString(EventTimestampFormat)},{NormalizeString(data)},{_containerName},{StampName},{TenantId},,,,");
4675
}
4776

4877
public override void LogFunctionDetailsEvent(string siteName, string functionName, string inputBindings, string outputBindings, string scriptType, bool isDisabled)

src/WebJobs.Script.WebHost/WebHostServiceCollectionExtensions.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ public static void AddWebJobsScriptHost(this IServiceCollection services, IConfi
8383
var environment = p.GetService<IEnvironment>();
8484
if (environment.IsLinuxContainerEnvironment())
8585
{
86-
return new LinuxContainerEventGenerator();
86+
return new LinuxContainerEventGenerator(environment);
8787
}
8888
else if (SystemEnvironment.Instance.IsLinuxAppServiceEnvironment())
8989
{

src/WebJobs.Script/Environment/EnvironmentSettingNames.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@ public static class EnvironmentSettingNames
2424
public const string AppInsightsQuickPulseAuthApiKey = "APPINSIGHTS_QUICKPULSEAUTHAPIKEY";
2525
public const string FunctionsExtensionVersion = "FUNCTIONS_EXTENSION_VERSION";
2626
public const string ContainerName = "CONTAINER_NAME";
27+
public const string WebSiteHomeStampName = "WEBSITE_HOME_STAMPNAME";
28+
public const string WebSiteStampDeploymentId = "WEBSITE_STAMP_DEPLOYMENT_ID";
2729
public const string WebSiteAuthEncryptionKey = "WEBSITE_AUTH_ENCRYPTION_KEY";
2830
public const string ContainerEncryptionKey = "CONTAINER_ENCRYPTION_KEY";
2931
public const string ConsoleLoggingDisabled = "CONSOLE_LOGGING_DISABLED";

test/WebJobs.Script.Tests/Diagnostics/LinuxContainerEventGeneratorTests.cs

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
using System.Text.RegularExpressions;
99
using Microsoft.Azure.WebJobs.Script.WebHost.Diagnostics;
1010
using Microsoft.Extensions.Logging;
11+
using Moq;
1112
using Newtonsoft.Json;
1213
using Newtonsoft.Json.Linq;
1314
using Xunit;
@@ -18,6 +19,9 @@ public class LinuxContainerEventGeneratorTests
1819
{
1920
private readonly LinuxContainerEventGenerator _generator;
2021
private readonly List<string> _events;
22+
private readonly string _containerName = "test-container";
23+
private readonly string _stampName = "test-stamp";
24+
private readonly string _tenantId = "test-tenant";
2125

2226
public LinuxContainerEventGeneratorTests()
2327
{
@@ -26,7 +30,13 @@ public LinuxContainerEventGeneratorTests()
2630
{
2731
_events.Add(s);
2832
};
29-
_generator = new LinuxContainerEventGenerator(writer);
33+
34+
var mockEnvironment = new Mock<IEnvironment>(MockBehavior.Strict);
35+
mockEnvironment.Setup(p => p.GetEnvironmentVariable(EnvironmentSettingNames.ContainerName)).Returns(_containerName);
36+
mockEnvironment.Setup(p => p.GetEnvironmentVariable(EnvironmentSettingNames.WebSiteHomeStampName)).Returns(_stampName);
37+
mockEnvironment.Setup(p => p.GetEnvironmentVariable(EnvironmentSettingNames.WebSiteStampDeploymentId)).Returns(_tenantId);
38+
39+
_generator = new LinuxContainerEventGenerator(mockEnvironment.Object, writer);
3040
}
3141

3242
[Theory]
@@ -42,7 +52,7 @@ public void ParseLogEvents(LogLevel level, string subscriptionId, string appName
4252
var match = regex.Match(evt);
4353

4454
Assert.True(match.Success);
45-
Assert.Equal(16, match.Groups.Count);
55+
Assert.Equal(19, match.Groups.Count);
4656

4757
DateTime dt;
4858
var groupMatches = match.Groups.Select(p => p.Value).Skip(1).ToArray();
@@ -61,7 +71,10 @@ public void ParseLogEvents(LogLevel level, string subscriptionId, string appName
6171
p => Assert.Equal(exceptionMessage, JsonUnescape(p)),
6272
p => Assert.Equal(functionInvocationId, p),
6373
p => Assert.Equal(hostInstanceId, p),
64-
p => Assert.Equal(activityId, p));
74+
p => Assert.Equal(activityId, p),
75+
p => Assert.Equal(_containerName.ToUpperInvariant(), p),
76+
p => Assert.Equal(_stampName, p),
77+
p => Assert.Equal(_tenantId, p));
6578
}
6679

6780
private static string JsonUnescape(string value)
@@ -104,7 +117,7 @@ public void ParseMetricEvents(string subscriptionId, string appName, string func
104117
var match = regex.Match(evt);
105118

106119
Assert.True(match.Success);
107-
Assert.Equal(12, match.Groups.Count);
120+
Assert.Equal(15, match.Groups.Count);
108121

109122
DateTime dt;
110123
var groupMatches = match.Groups.Select(p => p.Value).Skip(1).ToArray();
@@ -119,7 +132,10 @@ public void ParseMetricEvents(string subscriptionId, string appName, string func
119132
p => Assert.Equal(count, long.Parse(p)),
120133
p => Assert.Equal(ScriptHost.Version, p),
121134
p => Assert.True(DateTime.TryParse(p, out dt)),
122-
p => Assert.Equal(data, p));
135+
p => Assert.Equal(data, JsonUnescape(p)),
136+
p => Assert.Equal(_containerName.ToUpperInvariant(), p),
137+
p => Assert.Equal(_stampName, p),
138+
p => Assert.Equal(_tenantId, p));
123139
}
124140

125141
[Theory]

0 commit comments

Comments
 (0)