HttpContext и TelemetryInitializer

Я хочу прикрепить заявку "client_id" пользователя в качестве свойства к каждому запросу, отправленному в Application Insights.

Из того, что я прочитал, я должен реализоватьITelemetryInitializer но мне нужноHttpContext для запроса, чтобы получить "client_id". Смотрите мой инициализатор:

public class ClaimTelemetryInitializer : ITelemetryInitializer
{
    public HttpContext HttpContext { get; set; }

    public void Initialize(ITelemetry telemetry)
    {
        this.AddTelemetryContextPropertFromClaims(telemetry, "client_id");
    }

    private void AddTelemetryContextPropertFromClaims(ITelemetry telemetry, string claimName)
    {
        if (HttpContext != null)
        {
            var requestTelemetry = telemetry as RequestTelemetry;

            var claim = HttpContext.User.Claims.SingleOrDefault(x => x.Type.Equals(claimName, StringComparison.InvariantCultureIgnoreCase));

            if (claim != null)
            {
                telemetry.Context.Properties[claimName] = claim.Value;
            }
        }
    }
}

Я мог бы создать фильтр действий для установки контекста каждый раз, но это ужасно:

public class TrackClaimsAttribute : ActionFilterAttribute
{
    public override Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next)
    {
        var initialiser = TelemetryConfiguration.Active.TelemetryInitializers.OfType<ClaimTelemetryInitializer>().Single();

        initialiser.HttpContext = context.HttpContext;

        return base.OnActionExecutionAsync(context, next);
    }
}

Есть ли лучший способ достичь того, что я хочу сделать?

Ответы на вопрос(2)

чтобы это было разработано в AppInsights, но вы можете напрямую использовать статическийHttpContext.Current, Вы можете использовать его по запросуItems словарь в качестве кратковременного (почти не имеющего состояния) пространства хранения для доставки пользовательских значений в пользовательский обработчик телеметрии.

Так что постарайтесь

class AppInsightCustomProps : ITelemetryInitializer
{
    public void Initialize(ITelemetry telemetry)
    {
        var requestTelemetry = telemetry as RequestTelemetry;
        // Is this a TrackRequest() ?
        if (requestTelemetry == null) return;

        var httpCtx = HttpContext.Current;
        if (httpCtx != null)
        {
            var customPropVal = (string)httpCtx.Items["PerRequestMyCustomProp"];
            if (!string.IsNullOrWhiteSpace(customPropVal))
            {
                requestTelemetry.Properties["MyCustomProp"] = customPropVal;
            }
        }
    }
}

И чтобы запрограммировать желаемое пользовательское свойство, в любом месте вашего конвейера запросов есть что-то вроде

if (HttpContext.Current != null)
{
    HttpContext.Current.Items["PerRequestMyCustomProp"] = myCustomPropValue;
}
 Dave New14 февр. 2019 г., 20:39
Спасибо за ваш ответ
Решение Вопроса

WebTelemetryInitializerBase который предоставляет вам HttpContext.

Ваш код должен выглядеть так:

public class ClaimTelemetryInitializer : WebTelemetryInitializerBase
{
    protected override void OnInitializeTelemetry(
            HttpContext platformContext,
            RequestTelemetry rootRequestTelemetry, 
            ITelemetry telemetry) {

            var claim = HttpContext.User.Claims.SingleOrDefault(x => x.Type.Equals(claimName, StringComparison.InvariantCultureIgnoreCase));

            if (claim != null)
            {
                telemetry.Context.Properties[claimName] = claim.Value;
            }
    }
}
 Dave New17 июл. 2016 г., 08:49
К сожалению, это не совместимо с ASP.NET Core / MVC6.
 Britt Wescott12 июл. 2018 г., 16:46
Кто-нибудь нашел решение по этому вопросу? Я не могу получить доступ к HttpContext с помощью приложения MVC6.
 Martin Meixger10 янв. 2018 г., 11:37
WebTelemetryInitializerBase использует внутренне HttpContext.Current
 Dave New17 июл. 2016 г., 08:56
 UserControl07 мар. 2017 г., 07:44
Как вы можете извлечь изWebTelemetryInitializerBase если его ctor является внутренним (основывается на 2.2.0 источниках)?
 Dave New26 апр. 2017 г., 16:15
Точно так же с TelemetryInitializerBase

Ваш ответ на вопрос