Skip to content

Allow for the UserLogDefaultLogLevel to be set independent of system logs #4318

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
Show file tree
Hide file tree
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,7 @@ public override ICommandLineParserResult ParseArgs(string[] args)

private async Task<IWebHost> BuildWebHost(ScriptApplicationHostOptions hostOptions, Uri listenAddress, Uri baseAddress, X509Certificate2 certificate)
{
LoggingFilterHelper loggingFilterHelper = new LoggingFilterHelper(_hostJsonConfig, VerboseLogging);
LoggingFilterHelper loggingFilterHelper = new LoggingFilterHelper(_hostJsonConfig, VerboseLogging, GetUserLogLevel());
if (GlobalCoreToolsSettings.CurrentWorkerRuntime == WorkerRuntime.dotnet ||
GlobalCoreToolsSettings.CurrentWorkerRuntime == WorkerRuntime.dotnetIsolated)
{
Expand Down Expand Up @@ -831,5 +831,13 @@ private void EnsureWorkerRuntimeIsSet()
// Update local.settings.json
WorkerRuntimeLanguageHelper.SetWorkerRuntime(_secretsManager, GlobalCoreToolsSettings.CurrentWorkerRuntime.ToString());
}

private string GetUserLogLevel()
{
var UserLogLevel = Environment.GetEnvironmentVariable(Constants.FunctionsLoggingLogLevel)
?? _secretsManager.GetSecrets().FirstOrDefault(s => s.Key.Equals(Constants.FunctionsLoggingLogLevel, StringComparison.OrdinalIgnoreCase)).Value;

return UserLogLevel;
}
}
}
1 change: 1 addition & 0 deletions src/Azure.Functions.Cli/Common/Constants.cs
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ internal static class Constants
public const string AzureDevSessionsRemoteHostName = "AzureDevSessionsRemoteHostName";
public const string AzureDevSessionsPortSuffixPlaceholder = "<port>";
public const string GitHubReleaseApiUrl = "https://api.github.com/repos/Azure/azure-functions-core-tools/releases/latest";
public const string FunctionsLoggingLogLevel = "AzureFunctionsJobHost__Logging__LogLevel__Function";

// Sample format https://n12abc3t-<port>.asse.devtunnels.ms/

Expand Down
13 changes: 11 additions & 2 deletions src/Azure.Functions.Cli/Diagnostics/LoggingFilterHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ public class LoggingFilterHelper
public const string Ci_Build_Number = "BUILD_NUMBER"; // Travis CI, Cirrus CI
public const string Ci_Run_Id = "RUN_ID"; // TaskCluster, dsari

public LoggingFilterHelper(IConfigurationRoot hostJsonConfig, bool? verboseLogging)
public LoggingFilterHelper(IConfigurationRoot hostJsonConfig, bool? verboseLogging, string userLogLevel = null)
{
VerboseLogging = verboseLogging.HasValue && verboseLogging.Value;

Expand All @@ -34,7 +34,15 @@ public LoggingFilterHelper(IConfigurationRoot hostJsonConfig, bool? verboseLoggi
if (Utilities.LogLevelExists(hostJsonConfig, Utilities.LogLevelDefaultSection, out LogLevel logLevel))
{
SystemLogDefaultLogLevel = logLevel;
UserLogDefaultLogLevel = logLevel;
}

// Check for user log level
if (!string.IsNullOrEmpty(userLogLevel))
{
if (Enum.TryParse(userLogLevel, true, out LogLevel UserLogLevel))
{
UserLogDefaultLogLevel = UserLogLevel;
}
}
}

Expand Down Expand Up @@ -68,5 +76,6 @@ internal bool IsCiEnvironment(bool verboseLoggingArgExists)
}
return false;
}

}
}
70 changes: 70 additions & 0 deletions test/Azure.Functions.Cli.Tests/E2E/StartTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
using Azure.Functions.Cli.Common;
using Azure.Functions.Cli.Tests.E2E.Helpers;
using FluentAssertions;
using Microsoft.Azure.Storage;
using Xunit;
using Xunit.Abstractions;

Expand Down Expand Up @@ -1857,6 +1858,75 @@ await CliTester.Run(new RunConfiguration[]
}
}

[Fact]
[Trait(TestTraits.Group, TestTraits.RequiresNestedInProcArtifacts)]
public async Task Start_DotnetApp_WithDebugLogs_DisplaysDebugLogsInConsole()
{
var DebugLogMessage = "This is a debug log message";

await CliTester.Run(new RunConfiguration[]
{
new RunConfiguration
{
Commands = new[]
{
"init . --worker-runtime dotnet",
"new --template Httptrigger --name HttpTrigger"
},
Test = async (workingDir, _, _) =>
{
// Add debug logs to FunctionApp.cs
var functionAppPath = Path.Combine(workingDir, "HttpTrigger.cs");
if (File.Exists(functionAppPath))
{
var content = await File.ReadAllTextAsync(functionAppPath);
content = content.Replace(
"log.LogInformation(\"C# HTTP trigger function processed a request.\");",
$"log.LogInformation(\"C# HTTP trigger function processed a request.\");\nlog.LogDebug(\"{DebugLogMessage}\");"
);
await File.WriteAllTextAsync(functionAppPath, content);
}

// Update local.settings.json
var localSettingsPath = Path.Combine(workingDir, "local.settings.json");
if (File.Exists(localSettingsPath))
{
var settingsContent = await File.ReadAllTextAsync(localSettingsPath);
settingsContent = settingsContent.Replace(
"\"Values\": {",
"\"Values\": {\n \"AzureFunctionsJobHost__Logging__LogLevel__Function\": \"Debug\","
);
await File.WriteAllTextAsync(localSettingsPath, settingsContent);
}
},
CommandTimeout = TimeSpan.FromSeconds(300)
},
new RunConfiguration
{
Commands = new[]
{
$"start --port {_funcHostPort}"
},
ExpectExit = false,
OutputContains = new[]
{
DebugLogMessage
},
Test = async (_, p, stdout) =>
{
using (var client = new HttpClient() { BaseAddress = new Uri($"http://localhost:{_funcHostPort}/") })
{
(await WaitUntilReady(client)).Should().BeTrue(because: _serverNotReady);
var response = await client.GetAsync("/api/HttpTrigger?name=Test");
response.StatusCode.Should().Be(HttpStatusCode.OK);
p.Kill();
}
},
CommandTimeout = TimeSpan.FromSeconds(300)
}
}, _output);
}

private async Task<bool> WaitUntilReady(HttpClient client)
{
for (var limit = 0; limit < 10; limit++)
Expand Down
1 change: 0 additions & 1 deletion test/Azure.Functions.Cli.Tests/LoggingFilterHelperTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@ public void LoggingFilterHelper_Tests(string categoryKey, bool? verboseLogging,
}
if ( !string.IsNullOrEmpty(categoryKey) && categoryKey.Equals("Default", StringComparison.OrdinalIgnoreCase))
{
Assert.Equal(expectedDefaultLogLevel, loggingFilterHelper.UserLogDefaultLogLevel);
Assert.Equal(expectedDefaultLogLevel, loggingFilterHelper.SystemLogDefaultLogLevel);
}
else
Expand Down