Skip to content

Commit

Permalink
Adding a log event when reading .autorest_generated.json file (Azure#…
Browse files Browse the repository at this point in the history
…6746)

* Adding a log event when reading .autorest_generated.json file
The change is to generate a log event when the `.autorest_generated.json` file exists in any existing function app. This file is added by stencil plugins and need to be sent to inform us how many deployed function apps have been generated by Stencil plugins.
  • Loading branch information
vrdmr authored Oct 7, 2020
1 parent 1722f50 commit 9f9c866
Show file tree
Hide file tree
Showing 5 changed files with 109 additions and 1 deletion.
25 changes: 24 additions & 1 deletion src/WebJobs.Script/Diagnostics/Extensions/LoggerExtension.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

using System;
using Microsoft.Extensions.Logging;
using static System.Environment;

namespace Microsoft.Azure.WebJobs.Script.Diagnostics.Extensions
{
Expand Down Expand Up @@ -206,7 +207,19 @@ internal static class LoggerExtension
LoggerMessage.Define(
LogLevel.Information,
new EventId(331, nameof(JobHostFunctionTimeoutNotSet)),
"FunctioTimeout is not set.");
"FunctionTimeout is not set.");

private static readonly Action<ILogger, string, Exception> _autorestGeneratedFunctionApplication =
LoggerMessage.Define<string>(
LogLevel.Information,
new EventId(332, nameof(AutorestGeneratedFunctionApplication)),
"autorest_generated.json file found generated by Autorest (https://aka.ms/stencil) | file content:\n{sanitizedAutorestJson}");

private static readonly Action<ILogger, string, Exception> _incorrectAutorestGeneratedJSONFile =
LoggerMessage.Define<string>(
LogLevel.Warning,
new EventId(333, nameof(IncorrectAutorestGeneratedJsonFile)),
"autorest_generated.json file found is incorrect (https://aka.ms/stencil) | exception:\n{contents}");

public static void ExtensionsManagerRestoring(this ILogger logger)
{
Expand Down Expand Up @@ -379,5 +392,15 @@ public static void JobHostFunctionTimeoutNotSet(this ILogger logger)
{
_jobHostFunctionTimeoutNotSet(logger, null);
}

public static void AutorestGeneratedFunctionApplication(this ILogger logger, string sanitizedAutorestJson)
{
_autorestGeneratedFunctionApplication(logger, sanitizedAutorestJson, null);
}

public static void IncorrectAutorestGeneratedJsonFile(this ILogger logger, string contents)
{
_incorrectAutorestGeneratedJSONFile(logger, contents, null);
}
}
}
2 changes: 2 additions & 0 deletions src/WebJobs.Script/Host/ScriptHost.cs
Original file line number Diff line number Diff line change
Expand Up @@ -295,6 +295,8 @@ public async Task InitializeAsync(CancellationToken cancellationToken = default)
}

_metricsLogger.LogEvent(string.Format(MetricEventNames.HostStartupRuntimeLanguage, runtimeStack));

Utility.LogAutorestGeneratedJsonIfExists(ScriptOptions.RootScriptPath, _logger);
}

var directTypes = GetDirectTypes(functionMetadataList);
Expand Down
1 change: 1 addition & 0 deletions src/WebJobs.Script/ScriptConstants.cs
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ public static class ScriptConstants
public const string DiagnosticSentinelFileName = "diagnostic_sentinel";
public const string HostMetadataFileName = "host.json";
public const string FunctionMetadataFileName = "function.json";
public const string AutorestGeenratedMetadataFileName = ".autorest_generated.json";
public const string ProxyMetadataFileName = "proxies.json";
public const string ExtensionsMetadataFileName = "extensions.json";
public const string AppOfflineFileName = "app_offline.htm";
Expand Down
28 changes: 28 additions & 0 deletions src/WebJobs.Script/Utility.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
using Microsoft.Azure.WebJobs.Host;
using Microsoft.Azure.WebJobs.Logging;
using Microsoft.Azure.WebJobs.Script.Description;
using Microsoft.Azure.WebJobs.Script.Diagnostics.Extensions;
using Microsoft.Azure.WebJobs.Script.Workers.Rpc;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
Expand Down Expand Up @@ -796,6 +797,33 @@ public static void ValidateRetryOptions(RetryOptions
}
}

public static void LogAutorestGeneratedJsonIfExists(string rootScriptPath, ILogger logger)
{
string autorestGeneratedJsonPath = Path.Combine(rootScriptPath, ScriptConstants.AutorestGeenratedMetadataFileName);
JObject autorestGeneratedJson;

if (FileUtility.FileExists(autorestGeneratedJsonPath))
{
string autorestGeneratedJsonPathContents = FileUtility.ReadAllText(autorestGeneratedJsonPath);
try
{
autorestGeneratedJson = JObject.Parse(autorestGeneratedJsonPathContents);
logger.AutorestGeneratedFunctionApplication(autorestGeneratedJson.ToString());
}
catch (JsonException ex)
{
logger.IncorrectAutorestGeneratedJsonFile($"Unable to parse autorest configuration file '{autorestGeneratedJsonPath}'" +
$" with content '{autorestGeneratedJsonPathContents}' | exception: {ex.StackTrace}");
}
catch (Exception ex)
{
logger.IncorrectAutorestGeneratedJsonFile($"Caught exception while parsing .autorest_generated.json | " +
$"exception: {ex.StackTrace}");
}
}
// If we dont find the .autorest_generated.json in the function app, we just don't log anything.
}

private class FilteredExpandoObjectConverter : ExpandoObjectConverter
{
public override bool CanWrite => true;
Expand Down
54 changes: 54 additions & 0 deletions test/WebJobs.Script.Tests/UtilityTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,15 @@
using System.Diagnostics;
using System.Dynamic;
using System.Globalization;
using System.IO;
using System.IO.Abstractions;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Azure.WebJobs.Logging;
using Microsoft.Azure.WebJobs.Script.Description;
using Microsoft.Extensions.Logging;
using Microsoft.WebJobs.Script.Tests;
using Moq;
using Newtonsoft.Json.Linq;
Expand Down Expand Up @@ -50,6 +53,8 @@ public class TestPocoEx : TestPoco

public class UtilityTests
{
private TestLogger _testLogger = new TestLogger("test");

[Fact]
public async Task InvokeWithRetriesAsync_Throws_WhenRetryCountExceeded()
{
Expand Down Expand Up @@ -595,5 +600,54 @@ public void TryGetFunctionName_ReturnsExpectedResult(string keyName, bool expect
Assert.Equal("test", functionName);
}
}

[Fact]
public async Task Test_LogAutorestGeneratedJson_Without_AutorestGeneratedJson()
{
string functionAppDirectory = GetTemporaryDirectory();
try
{
Utility.LogAutorestGeneratedJsonIfExists(functionAppDirectory, _testLogger);
var allLogs = _testLogger.GetLogMessages();
Assert.Empty(allLogs);
}
finally
{
await FileUtility.DeleteDirectoryAsync(functionAppDirectory, true);
}
}

[Theory]
[InlineData("{\"name\":\"@autorest/azure-functions-csharp\",\"version\":\"0.2.0-preview\"}", "autorest_generated.json file found generated by Autorest (https://aka.ms/stencil) | file content", LogLevel.Information)]
[InlineData("{\"name\":\"@autorest/azure-functions-csharp\",\"version\"\"0.2.0-preview\"}", "autorest_generated.json file found is incorrect (https://aka.ms/stencil) | exception", LogLevel.Warning)]
public async Task Test_LogAutorestGeneratedJson_With_AutorestGeneratedJson(string autorestGeneratedJsonContent, string expectedContents, LogLevel expectedLogLevel)
{
string functionAppDirectory = GetTemporaryDirectory();
try
{
File.WriteAllText(Path.Combine(functionAppDirectory, ScriptConstants.AutorestGeenratedMetadataFileName), autorestGeneratedJsonContent);
Utility.LogAutorestGeneratedJsonIfExists(functionAppDirectory, _testLogger);
var allLogs = _testLogger.GetLogMessages();
VerifyLogLevel(allLogs, expectedContents, expectedLogLevel);
}
finally
{
await FileUtility.DeleteDirectoryAsync(functionAppDirectory, true);
}
}

private static void VerifyLogLevel(IList<LogMessage> allLogs, string msg, LogLevel expectedLevel)
{
var message = allLogs.Where(l => l.FormattedMessage.Contains(msg)).FirstOrDefault();
Assert.NotNull(message);
Assert.Equal(expectedLevel, message.Level);
}

private static string GetTemporaryDirectory()
{
string tempDirectory = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName());
FileUtility.EnsureDirectoryExists(tempDirectory);
return tempDirectory;
}
}
}

0 comments on commit 9f9c866

Please sign in to comment.