Skip to content

Filter Azure monitor logs when customer does not subscribe for the categories #10982

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

Open
wants to merge 5 commits into
base: dev
Choose a base branch
from

Conversation

manikantanallagatla
Copy link
Contributor

Issue describing the changes in this PR

For a few SKUs in functions, we want to filter azure monitor logs based on the categories subscribed by the user. This PR checks for the env variable for the categories and skips logging.

Pull request checklist

IMPORTANT: Currently, changes must be backported to the in-proc branch to be included in Core Tools and non-Flex deployments.

  • Backporting to the in-proc branch is not required
    • Otherwise: Link to backporting PR
  • My changes do not require documentation changes
    • Otherwise: Documentation issue linked to PR
  • My changes should not be added to the release notes for the next release
    • Otherwise: I've added my notes to release_notes.md
  • My changes do not need to be backported to a previous version
    • Otherwise: Backport tracked by issue/PR #issue_or_pr
  • My changes do not require diagnostic events changes
    • Otherwise: I have added/updated all related diagnostic events and their documentation (Documentation issue linked to PR)
  • I have added all required tests (Unit tests, E2E tests)

Additional information

Additional PR information

@manikantanallagatla manikantanallagatla requested a review from a team as a code owner April 7, 2025 09:10
Copy link
Contributor

@jviau jviau left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you give an example of these categories? Are they regular ILogger categories?

If so, we should use built in filtering with Microsoft.Extensions.Logging. We can either transform configuration, or we can simply call:

Part 1: log level filter

// condition on if this is the right sku
services.AddOptions<LoggerFilterOptions>()
    .Configure<IConfiguration>((options, config) =>
    {
        string setting = config[EnvironmentSettingNames.AzureMonitorCategories];
        options.AddFilter<AzureMonitorDiagnosticLoggerProvider>((category, level) =>
        {
            // return false when AzureMonitorCategories does not contain FunctionAppLogs
        });
    });

Part 2: IsEnabled update

// AzureMonitorDiagnosticLogger.cs
// Update the below method to return false when AzureMonitorCategories does not contain FunctionAppLogs
public bool IsEnabled(LogLevel logLevel)
{
    // We want to instantiate this Logger in placeholder mode to warm it up, but do not want to log anything.
    return !string.IsNullOrEmpty(_hostNameProvider.Value) && !_environment.IsPlaceholderModeEnabled();
}

Although I have to ask - who sets EnvironmentSettingNames.AzureMonitorCategories? Is it from the platform, or does the user explicitly set it?

@RohitRanjanMS
Copy link
Member

I agree with @jviau that providing more context about the scenario would be beneficial.
A simple list of categories alone might not be enough; the log level will also be necessary.
The environment variable is applicable only to LinuxContainerEventGenerator and does not extend to AzureMonitor/Diagnostic Settings integrations for other skus.
If these are specified by the customer, can the existing logging configuration in host.json be leveraged instead?

@manikantanallagatla
Copy link
Contributor Author

Can you give an example of these categories? Are they regular ILogger categories?

If so, we should use built in filtering with Microsoft.Extensions.Logging. We can either transform configuration, or we can simply call:

Part 1: log level filter

// condition on if this is the right sku
services.AddOptions<LoggerFilterOptions>()
    .Configure<IConfiguration>((options, config) =>
    {
        string setting = config[EnvironmentSettingNames.AzureMonitorCategories];
        options.AddFilter<AzureMonitorDiagnosticLoggerProvider>((category, level) =>
        {
            // return false when AzureMonitorCategories does not contain FunctionAppLogs
        });
    });

Part 2: IsEnabled update

// AzureMonitorDiagnosticLogger.cs
// Update the below method to return false when AzureMonitorCategories does not contain FunctionAppLogs
public bool IsEnabled(LogLevel logLevel)
{
    // We want to instantiate this Logger in placeholder mode to warm it up, but do not want to log anything.
    return !string.IsNullOrEmpty(_hostNameProvider.Value) && !_environment.IsPlaceholderModeEnabled();
}

Although I have to ask - who sets EnvironmentSettingNames.AzureMonitorCategories? Is it from the platform, or does the user explicitly set it?

I have removed all the changes. We already have category filter in the host code. I just had to called it in isenabled class

@jviau
Copy link
Contributor

jviau commented Apr 17, 2025

@manikantanallagatla I believe you will need to also add the filter callback I suggested. It may seem redundant but they have different purposes:

  1. filter: avoid running templating on the log message
  2. IsEnabled: give Logger users a hook to wrap their log statements in incase they have pre-templating code they want to skip.

I also am wondering about the IsAzureMonitorEnabled implementation as is being used in this new code paths. These are hot-paths, we need to make sure they are as performant as possible. IsAzureMonitorEnabled will be allocating an array and perform string comparison on each run. Can we optimize that? Cache the results of it somewhere?

Also this change will affect all skus - is the behavior of that env variable consistent across all skus?

@manikantanallagatla manikantanallagatla force-pushed the user/mnallagatla/diagnostic_logging branch from 6f22843 to 14d46af Compare April 22, 2025 05:21
});
});
}
else
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we put this in else, would the provider still gets added as a singleton.

@@ -54,6 +54,10 @@ public AzureMonitorDiagnosticLogger(string category, string hostInstanceId, IEve

public bool IsEnabled(LogLevel logLevel)
{
if (_environment.IsLegionBasedSku() && !_environment.IsAzureMonitorEnabled(useCache:true))
{
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did we validate the logs are not being emitted in placeholder mode..

if (useCache && isAzureMonitorLogsSubscribed != null)
{
return isAzureMonitorLogsSubscribed.Value;
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can this impact other SKUs? should we scope down these changes only to Legion.

/// </summary>
/// <param name="environment">The environment to verify.</param>
/// <returns><see cref="true"/> if running on legion, false otherwise.</returns>
public static bool IsLegionBasedSku(this IEnvironment environment)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we already have a method called IsConsumptionOnLegion which we can use instead of adding new method

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants