You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

AKS部署Identity Server:健康检查日志过滤代码失效,注释探针后日志消失

问题描述

我在部署于AKS集群的Identity Server应用中,尝试通过代码将健康检查日志排除在Application Insights之外,但健康检查日志仍会被记录。当注释掉deployment.yaml中的存活探针(livenessProbe)和就绪探针(readinessProbe)配置后,健康检查日志就不再出现了。


Startup 代码

var applicationInsightsConfig = Configuration.GetSection("LoggingConfigurations:ApplicationInsights");
var applicationInsights = LoggingConfiguration.Get<ApplicationInsights>();
services.Configure<ApplicationInsights>(applicationInsightsConfig);
services.AddApplicationInsights(); 

public static void AddApplicationInsights(this IServiceCollection services)
{
    var aiOptions = new ApplicationInsightsServiceOptions();
    aiOptions.EnableAdaptiveSampling = false;

    services.AddApplicationInsightsTelemetry(aiOptions);

    services.Configure<TelemetryConfiguration>((config) =>
    {
        var builder = config.DefaultTelemetrySink.TelemetryProcessorChainBuilder;
        builder.UseAdaptiveSampling(new SamplingPercentageEstimatorSettings
        {
            MinSamplingPercentage = 0.01,
            MaxSamplingPercentage = 100,
            MaxTelemetryItemsPerSecond = 5
        }, null, excludedTypes: "Exception");

        var serviceProvider = services.BuildServiceProvider();
        var options = serviceProvider.GetRequiredService<IOptions<ApplicationInsights>>();
        var httpContextAccessor = serviceProvider.GetRequiredService<IHttpContextAccessor>();

        config.DefaultTelemetrySink.TelemetryProcessorChainBuilder
            .Use(next => new HealthCheckFilterProcessor(next, options, httpContextAccessor))
            .Build();
    });
}

HealthCheckFilterProcessor 代码

public class HealthCheckFilterProcessor : ITelemetryProcessor
{
    private ITelemetryProcessor _next { get; set; }
    private readonly IOptions<ApplicationInsights> _config;
    private readonly IHttpContextAccessor _httpContextAccessor;
    List<string> mandatoryExclusionPaths = new List<string> { "/favicon.ico", "/health" };
    List<string> defaultExclusionPaths = new List<string> { "home/index", "/swagger", "/health", ".js", ".css", ".html", ".chtml", ".png", ".jpg", ".jpeg", ".gif", ".svg", ".ico", ".woff", ".woff2", ".ttf", ".map" };

    public HealthCheckFilterProcessor(ITelemetryProcessor next, IOptions<ApplicationInsights> config, IHttpContextAccessor httpContextAccessor)
    {
        _next = next;
        _config = config;
        _httpContextAccessor = httpContextAccessor;
    }

    public void Process(ITelemetry item)
    {
        switch (item)
        {
            case RequestTelemetry request:
                if (item is RequestTelemetry request1)
                {
                    var path = request1.Url.AbsolutePath.ToLowerInvariant();

                    if (path.Contains("/health"))
                    {
                        return; // Do not log this telemetry
                    }
                }
                break;

            case TraceTelemetry trace:
                var message = trace.Message;
                var operationName = trace.Context.Operation?.Name;
                Console.WriteLine("message" + message);
                Console.WriteLine("operationName" + operationName);
                if ((message?.Contains("/health", StringComparison.OrdinalIgnoreCase) ?? false) ||
                    (operationName?.Contains("/health", StringComparison.OrdinalIgnoreCase) ?? false))
                    return;
                break;

            case ExceptionTelemetry exception:
                Console.WriteLine("exception.Exception?.Message" + exception.Context.Operation?.Name);
                Console.WriteLine("exception.Exception?.Message" + exception.Exception?.Message);
                if ((exception.Context.Operation?.Name?.Contains("/health", StringComparison.OrdinalIgnoreCase) ?? false) ||
                    (exception.Exception?.Message?.Contains("/health", StringComparison.OrdinalIgnoreCase) ?? false))
                    return;
                break;

            case DependencyTelemetry dependency:
                Console.WriteLine("dependency.Target" + dependency.Context.Operation?.Name);
                Console.WriteLine("dependency.Target" + dependency.Target);
                if ((dependency.Context.Operation?.Name?.Contains("/health", StringComparison.OrdinalIgnoreCase) ?? false) ||
                    (dependency.Target?.Contains("/health", StringComparison.OrdinalIgnoreCase) ?? false))
                    return;
                break;
        }

        _next.Process(item);
    }
}

deployment.yaml 配置片段

livenessProbe: 
  httpGet:
    path: /health
    port: 8080
  periodSeconds: {{ .Values.iam.web.probes.liveness.periodSeconds }}
  initialDelaySeconds: {{ .Values.iam.web.probes.liveness.initialDelaySeconds }}
  timeoutSeconds: {{ .Values.iam.web.probes.liveness.timeoutSeconds }}
readinessProbe: 
  httpGet:
    path: /health
    port: 8080
  periodSeconds: {{ .Values.iam.web.probes.readiness.periodSeconds }}
  initialDelaySeconds: {{ .Values.iam.web.probes.readiness.initialDelaySeconds }}
  timeoutSeconds: {{ .Values.iam.web.probes.readiness.timeoutSeconds }}

解决方案

问题核心是AKS的存活/就绪探针请求不经过ASP.NET Core的中间件管道,直接由Kubelet发起,绕过了你写的Telemetry Processor过滤逻辑,导致这些请求的日志仍会进入Application Insights。以下是几种可行的解决方法:

方法1:识别Kubelet探针请求并过滤

Kubelet发起的探针请求会带有特定的User-Agent头,你可以在Telemetry Processor中检查该头来过滤:

case RequestTelemetry request:
    if (item is RequestTelemetry request1)
    {
        var path = request1.Url.AbsolutePath.ToLowerInvariant();
        // 检查请求是否来自Kubelet
        var isKubeletProbe = request1.Context.Properties.TryGetValue("AspNetCore.HttpContext.Request.Headers.User-Agent", out var userAgent) 
                             && userAgent.Contains("kubelet");
        
        if (path.Contains("/health") || isKubeletProbe)
        {
            return;
        }
    }
    break;

方法2:在采样规则中直接排除健康检查请求

修改Application Insights的采样配置,针对/health路径的请求设置采样率为0:

builder.UseAdaptiveSampling(new SamplingPercentageEstimatorSettings
{
    MinSamplingPercentage = 0.01,
    MaxSamplingPercentage = 100,
    MaxTelemetryItemsPerSecond = 5
}, 
// 添加自定义采样过滤器
samplingFilter: (telemetry) =>
{
    if (telemetry is RequestTelemetry request && request.Url.AbsolutePath.ToLowerInvariant().Contains("/health"))
    {
        return false; // 完全排除该请求的遥测
    }
    return true;
},
excludedTypes: "Exception");

方法3:在健康检查配置中标记忽略遥测

在Startup的Configure方法中配置健康检查时,直接标记该请求不需要被Application Insights追踪:

app.UseHealthChecks("/health", new HealthCheckOptions
{
    AllowCachingResponses = false,
    ResponseWriter = async (context, report) =>
    {
        context.Response.ContentType = "application/json";
        await context.Response.WriteAsync(JsonSerializer.Serialize(new
        {
            status = report.Status.ToString(),
            checks = report.Entries.Select(e => new { name = e.Key, status = e.Value.Status.ToString(), description = e.Value.Description })
        }));
    },
    // 标记该请求忽略遥测
    OnBeforeHealthCheck = (context) =>
    {
        context.Items["ApplicationInsights:IgnoreTelemetry"] = true;
        return Task.CompletedTask;
    }
});

内容的提问来源于stack exchange,提问作者Gouthami Shivakoti

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.12 18:54:54