簡體   English   中英

Application Insights - ILogger 參數呈現為自定義維度中的對象名稱

[英]Application Insights - ILogger arguments rendered as name of the object in custom dimensions

當作為參數傳遞給 ilogger 時,對象在 Application Insights 自定義維度中呈現為字符串(對象的名稱)。 未顯示實際值。

注冊應用洞察

services.AddApplicationInsightsTelemetry();

新日志

public class HealthController : ControllerBase
{
    private readonly ILogger<HealthController> _logger;

    public HealthController(ILogger<HealthController> logger)
    {
        _logger = logger;
    }

    [HttpGet]
    public IActionResult Get()
    {
        var health = new HealthViewModel()
        {
             ok = false
        };

        _logger.LogInformation("Hlep me pls {health}", health);

        return Ok(health);
    }
}

結果

在此處輸入圖片說明

我不想對每個日志都這樣做:

var health = new HealthViewModel()
{
     ok = false
};

_logger.LogInformation("Hlep me pls {health}", JsonConvert.SerializeObject(health));

我嘗試為應用程序洞察創建一個中間件,但值仍然是對象的名稱。

在此處輸入圖片說明

為什么參數不呈現為 json?

編輯

這好像是

var health = new
{
     ok = false
};

_logger.LogInformation("HEJ2 {health}", health);

有效但無效

var health = new HealthViewModel
{
     ok = false
};

_logger.LogInformation("HEJ2 {health}", health);

不支持

引自https://github.com/microsoft/ApplicationInsights-dotnet/issues/1722

我認為您對記錄器的期望過高。 它不知道 JSON 格式,它只是在屬性上調用 Convert.ToString

Convert.ToString 通常調用 ToString() 並且新類的默認 ToString 實現只是返回類型名稱

你可以做什么

對記錄到 ILogger 的對象使用 ToJson() 並為應用程序洞察創建中間件並修改日志的名稱和自定義維度。

中間件

public class ProcessApiTraceFilter : ITelemetryProcessor
{
    private ITelemetryProcessor Next { get; set; }
    private readonly IIdentity _identity;
    private readonly IHostEnvironment _hostEnvironment;

    public ProcessApiTraceFilter(ITelemetryProcessor next, IHostEnvironment hostEnvironment, IIdentity identity)
    {
        Next = next;
        _identity = identity;
        _hostEnvironment = hostEnvironment;
    }

    public void Process(ITelemetry item)
    {
        item.Process(_hostEnvironment, _identity);

        Next.Process(item);
    }
}

執行

public static class ApplicationInsightsExtensions
{
    public static void Process(this ITelemetry item, IHostEnvironment hostEnvironment, IIdentity identity)
    {
        if (item is TraceTelemetry)
        {
            var traceTelemetry = item as TraceTelemetry;
            var originalMessage = traceTelemetry.Properties.FirstOrDefault(x => x.Key == "{OriginalFormat}");

            if (!string.IsNullOrEmpty(originalMessage.Key))
            {
                var reg = new Regex("{([A-z]*)*}", RegexOptions.Compiled);
                var match = reg.Matches(originalMessage.Value);
                var formattedMessage = originalMessage.Value;
                foreach (Match arg in match)
                {
                    var parameterName = arg.Value.Replace("{", "").Replace("}", "");
                    var parameterValue = traceTelemetry.Properties.FirstOrDefault(x => x.Key == parameterName);
                    formattedMessage = formattedMessage.Replace(arg.Value, "");
                }

                traceTelemetry.Message = formattedMessage.Trim();
            }

            if (identity != null)
            {
                var isAuthenticated = identity.IsAuthenticated();
                const string customerKey = "customer";

                if (isAuthenticated && !traceTelemetry.Properties.ContainsKey(customerKey))
                {
                    var customer = identity.Customer();

                    if (customer != null)
                    {
                        traceTelemetry.Properties.Add(customerKey, customer.ToJson());
                    }
                }

                var request = identity.Request();
                const string requestKey = "request";

                if (request != null && !traceTelemetry.Properties.ContainsKey(requestKey))
                {
                    traceTelemetry.Properties.Add(requestKey, request.ToJson());
                }
            }

            var applicationNameKey = "applicationName";

            if (hostEnvironment != null && !string.IsNullOrEmpty(hostEnvironment.ApplicationName) && !traceTelemetry.Properties.ContainsKey(applicationNameKey))
            {
                traceTelemetry.Properties.Add(applicationNameKey, hostEnvironment.ApplicationName);
            }
        }
    }
}

在啟動時注冊應用程序洞察和中間件

services.AddApplicationInsightsTelemetry();
services.AddApplicationInsightsTelemetryProcessor<ProcessApiTraceFilter>();

ToJson

public static class ObjectExtensions
{
    private static readonly string Null = "null";
    private static readonly string Exception = "Could not serialize object to json";

    public static string ToJson(this object value, Formatting formatting = Formatting.None)
    {
        if (value == null) return Null;

        try
        {
            string json = JsonConvert.SerializeObject(value, formatting);

            return json;
        }
        catch (Exception ex)
        {
            return $"{Exception} - {ex?.Message}";
        }
    }
}

日志

//Log object? _smtpAppSettings.ToJson()

_logger.LogInformation("Email sent {to} {from} {subject}", to, _smtpAppSettings.From, subject)

結果

在此處輸入圖片說明

從您的自定義維度中,我可以看到它沒有將健康 obj 參數視為額外數據

_logger.LogInformation("Hlep me pls {health}", health);

嘗試在字符串本身中使用 jsonConverter。

_logger.LogInformation($"Hlep me pls {JsonConvert.SerializeObject(health)}");

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM