Этот конкретный случай: приложение представляет собой веб-API .net Core 9. Он выполняет HTTP-вызов к другой службе (надежная функция) и должен регистрировать ответ в формате JSON со всеми URL-адресами состояния — тот же ответ, который вы получаете, если используете бегун на портале Azure.
Проблема в том, что в этом случае App Insights просто перестает регистрировать любые пользовательские измерения в этом одном классе, в то время как другие места в том же коде API работают нормально и пишут customDimensions.
Для конфигурации у нас есть что-то вроде этого:
где рассматриваемый код находится в пространстве имен MyApi.Api.Application.Common.Services
Код: Выделить всё
{
"Logging": {
"LogLevel": {
"Default": "Debug",
"Microsoft": "Error",
"Microsoft.AspNetCore": "Error",
"Microsoft.Hosting.Lifetime": "Error",
"Microsoft.EntityFrameworkCore": "Error",
"MyApi.Api.Application.Common.Services": "Debug"
},
"ApplicationInsights": {
"samplingSettings": {
"isEnabled": false
},
"EnableLiveMetricsFilters": false,
"LogLevel": {
"Default": "Debug",
"Microsoft": "Error",
"Microsoft.AspNetCore": "Error",
"Microsoft.Hosting.Lifetime": "Error",
"Microsoft.EntityFrameworkCore": "Error",
"MyApi.Api.Application.Common.Services": "Debug"
}
}
},
"AllowedHosts": "*"
}
Регистрация службы App Insights выглядит следующим образом:
Код: Выделить всё
public static void RegisterLogging(this IServiceCollection services, IConfiguration configuration, IWebHostEnvironment environment)
{
services.AddSingleton(environment);
if (!string.IsNullOrEmpty(configuration["APPLICATIONINSIGHTS_CONNECTION_STRING"]))
{
services.AddLogging(builder =>
{
builder.AddApplicationInsights();
});
services.TryAddScoped();
services.AddApplicationInsightsTelemetry(options =>
{
options.ConnectionString = configuration["APPLICATIONINSIGHTS_CONNECTION_STRING"];
});
}
}
У нас есть несколько методов расширения, которые мы используем, чтобы абстрагировать некоторые тонкости ведения журнала, поэтому я собираюсь показать пример пути, используемого одной из наших наиболее распространенных реализаций.
Код: Выделить всё
public static ILogger WriteDebug(this ILogger logger, string message,
params (string, object)[] properties)
{
logger.WriteDebug(message, properties.ToLoggingScope(), null);
return logger;
}
public static void WriteDebug(this ILogger logger, string message, IDictionary properties = null, params object[] arguments)
{
properties = properties ?? CreateDefaultScope();
using (logger.BeginScope(properties))
{
logger.LogDebug(message, arguments);
}
}
public static IDictionary ToLoggingScope(this (string, object)[] properties)
{
return properties
.GroupBy(prop => prop.Item1, StringComparer.OrdinalIgnoreCase)
.Select(grp => new KeyValuePair(grp.Key, grp.LastOrDefault().Item2))
.ToDictionary(kvp => kvp.Key, kvp => kvp.Value);
}
private static IDictionary CreateDefaultScope()
{
return new Dictionary()
{
["ScopeId"] = Guid.NewGuid().ToString("N")
};
}
Код: Выделить всё
public class MyService(ILoggerFactory loggerFactory)
{
private readonly ILogger = loggerFactory.CreateLogger();
public void DoSomething(int myId)
{
_logger.WriteDebug("Begin DoSomething",
(nameof(myId), myId));
}
}
Подробнее здесь: https://stackoverflow.com/questions/797 ... dimensions
Мобильная версия