Заполнение поля идентификатора пользователя в приложении Insights из ASP.NET Core - PullRequest
0 голосов
/ 11 июля 2019

Я бы хотел заполнить поле User Id в Application Insights данными о моем реальном имени пользователя.Это внутреннее приложение, поэтому вопросы конфиденциальности с простым полем имени пользователя не имеют значения.

Насколько я могу судить, все доступные в сети решения для этого строго работают в .NET Framework, а не .NET Core.

Вы можете найти это решение в нескольких местах, включая некоторую старую документацию по ИИ на GitHub.Однако, когда я запускаю его, я получаю сообщение об ошибке при запуске, указывающее, что зависимость от объекта IHttpContextAccessor с областью действия недопустима для одного объекта, что, конечно, логично.Я не понимаю, как это могло когда-либо работать, если предыдущая версия DI .NET Core не позволяла это (я на 2.2).

Эта проблема на GitHub вроде как разоблачаетпроблема, но она была закрыта после того, как команда AI указала, что вы должны использовать синглтон.Я попробовал варианты того, что в OP и первом ответе, и пока код работал, поле User Id на AI продолжало заполняться бессмысленными данными.

Есть ли способ сделать поле User Id вИИ наполняете чем-то полезным для запросов к серверу из приложения ASP.NET Core?

РЕДАКТИРОВАТЬ

Увидев приведенный ниже ответ, что мой код должен был работать нормально, я вернулся и понял, чтов сообщении об исключении не упоминается конкретно IHttpContextAccessor:

System.InvalidOperationException: 'Не удается использовать службу с ограниченным доступом' Microsoft.ApplicationInsights.Extensibility.ITelemetryInitializer 'из одиночного' Microsoft.Extensions.Options.IConfigureOptions`1 [Microsoft.ApplicationInsights.Extensibility.TelemetryConfiguration] '.' *

Теперь мой код выглядит примерно так же, как и ответ @PeterBons 'ниже, поэтому на первый взгляд это исключение не сделалосмысл.TelemetryConfiguration событие не появляется в моем коде.Но потом я вспомнил, что я использую Scrutor для ленивой регистрации DI при запуске:

    services.Scan(scan => scan
        .FromAssembliesOf(typeof(Startup), typeof(MyDbContext))
        .AddClasses()
        .AsSelfWithInterfaces().WithScopedLifetime());

Я предполагаю, что проблема заключалась в том, что мне нужно было зарегистрировать мой ITelemetryInitializer в качестве Singleton, и этот код был непреднамеренно удален или повторнорегистрируя его как ограниченный.Поэтому я изменил последние две строки на:

        .AddClasses(f => f.Where(t => t != typeof(RealUserAIProvider)))
        .AsSelfWithInterfaces().WithScopedLifetime());

И это сработало.Вместо того, чтобы отредактировать мою ошибку выше, я оставлю это.Ответ @PeterBons, приведенный ниже, по-прежнему будет полезен для других людей, и, возможно, моя путаница со Scrutor кому-то тоже поможет.

1 Ответ

1 голос
/ 11 июля 2019

Вам не нужно регистрировать HttpContextAccessor в качестве зависимой области. Просто используйте синглтон.

У нас есть эта работа в производстве, используя это:

services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();

в сочетании с этим инициализатором:

public class SessionDetailsTelemetryEnrichment : TelemetryInitializerBase
{
    public SessionDetailsTelemetryEnrichment(IHttpContextAccessor httpContextAccessor) : base(httpContextAccessor)
    {

    }

    protected override void OnInitializeTelemetry(HttpContext platformContext, RequestTelemetry requestTelemetry, ITelemetry telemetry)
    {
        telemetry.Context.User.AuthenticatedUserId =
            platformContext.User?.Claims.FirstOrDefault(c => c.Type == "Username")?.Value ?? string.Empty;

    }
}
...