Dastur so'rovlarida Post so'rovining tanasini ko'rish

Application so'rovlarida Post so'rovining tanasini ko'rish mumkinmi?

Murojaatlar tafsilotlarini ko'ra olaman, lekin foydali yuk ilovaning ma'lumotlariga joylashtirilmaydi. Buni ba'zi kodlash bilan kuzatib turishim kerakmi?

Men MVC core 1.1 Web Api'ni qurmoqdaman.

POST request

24

6 javoblar

Siz o'zingizni Telemetriya Initiator :

Misol uchun, foydali yukni chiqaradigan va so'rov telemetrining maxsus o'lchami sifatida qo'shadigan dasturning quyida:

public class RequestBodyInitializer : ITelemetryInitializer
{
    public void Initialize(ITelemetry telemetry)
    {
        var requestTelemetry = telemetry as RequestTelemetry;
        if (requestTelemetry != null && (requestTelemetry.HttpMethod == HttpMethod.Post.ToString() || requestTelemetry.HttpMethod == HttpMethod.Put.ToString()))
        {
            using (var reader = new StreamReader(HttpContext.Current.Request.InputStream))
            {
                string requestBody = reader.ReadToEnd();
                requestTelemetry.Properties.Add("body", requestBody);
            }
        }
    }
}

Keyin uni Konfiguratsiya fayli yoki kod orqali:

TelemetryConfiguration.Active.TelemetryInitializers.Add(new RequestBodyInitializer());

Keyin Analytics-da so'rovni bajaring:

requests | limit 1 | project customDimensions.body
16
qo'shib qo'ydi
@Schenz yangilangan hujjatlarga muvofiq, AI. NET SDK ning yangi versiyalari uchun endi spam nomining xususiyatidan olinishi kerak. So'rov nomining namunasi: 'GET/values ​​/ {id}' Batafsil ma'lumot bu yerda: docs.microsoft.com/en-us/azure/application-insights/…
qo'shib qo'ydi muallif yonisha, manba
@ShyamalParikh requestTelemetry.HttpMethod o'rniga HttpContext.Current.Request.HttpMethod dan foydalanishingiz mumkin.
qo'shib qo'ydi muallif Frederiek, manba
@yonisha Sizning yangi versiyangiz uchun javobingizni yangilashingiz mumkinmi?
qo'shib qo'ydi muallif Shyamal Parikh, manba
Talab qilinganTelemetry.HttpMethod eskirgan ko'rinadi. HttpMethodni qidirib qaerga borish kerakligiga ishonchim komil emas.
qo'shib qo'ydi muallif Schenz, manba
"Response Body" ni ham yoza olsam bo'ladimi? Ha bo'lsa, agar iloji bo'lsa, kimdir ba'zi ko'rsatmalarni yoki kod snippetini almashishi mumkin.
qo'shib qo'ydi muallif Muhammad Umar, manba
Tanani o'qish uchun so'rovning inputStream holatini tiklash kerak edi. HttpContext.Current.Request.InputStream.Position = 0;
qo'shib qo'ydi muallif user2279473, manba
Shuni esda tutingki, ushbu kod ikki marta bajariladi: so'rovdan bir marta va so'rovdan keyin bir marta. So'rov organi ikkinchi marta bo'sh, shuning uchun siz kiritilgan narsalarni qo'shishdan avval (yoki bekor qilmasdan) kirish oqimining uzunligini tekshirishingiz mumkin!
qo'shib qo'ydi muallif Thomas D, manba

@Yonisha tomonidan taqdim etilgan yechim, mening fikrimcha, eng toza mavjud. Biroq siz hali ham o'sha erda httpcontextingizni olishingiz kerak va buning uchun sizga qo'shimcha kod kerak. Bundan tashqari, yuqoridagi kod misollaridan olingan yoki olingan ba'zi izohlarni kiritganman. Sizning so'rovingiz o'rnini qayta tiklash muhim, chunki u sizning ma'lumotlaringizni yo'qotadi.

Bu men sinovdan o'tgan va menga jonsonni bergan qarorim:

public class RequestBodyInitializer : ITelemetryInitializer
{
    readonly IHttpContextAccessor httpContextAccessor;

    public RequestBodyInitializer(IHttpContextAccessor httpContextAccessor)
    {
        this.httpContextAccessor = httpContextAccessor;
    }

    public void Initialize(ITelemetry telemetry)
    {
        if (telemetry is RequestTelemetry requestTelemetry)
        {
            if ((httpContextAccessor.HttpContext.Request.Method == HttpMethods.Post ||
                 httpContextAccessor.HttpContext.Request.Method == HttpMethods.Put) &&
                httpContextAccessor.HttpContext.Request.Body.CanRead)
            {
                const string jsonBody = "JsonBody";

                if (requestTelemetry.Properties.ContainsKey(jsonBody))
                {
                    return;
                }

                //Allows re-usage of the stream
                httpContextAccessor.HttpContext.Request.EnableRewind();

                var stream = new StreamReader(httpContextAccessor.HttpContext.Request.Body);
                var body = stream.ReadToEnd();

                //Reset the stream so data is not lost
                httpContextAccessor.HttpContext.Request.Body.Position = 0;
                requestTelemetry.Properties.Add(jsonBody, body);
            }
        }
    }

Then also be sure to add this to your Startup -> ConfigureServices

services.AddSingleton();

EDIT:

Agar siz ham javobni qabul qilmoqchi bo'lsangiz, men bir qavatli qidiruv dasturini yaratish uchun foydalandim (dotnet yadrolari ramka haqida ishonchli emas). Avvalo siz javob beradigan va so'rovni yozgan yondashuvni oldim, lekin ko'pincha ularni birgalikda istayman.

    public async Task Invoke(HttpContext context)
    {
        var reqBody = await this.GetRequestBodyForTelemetry(context.Request);

        var respBody = await this.GetResponseBodyForTelemetry(context);
        this.SendDataToTelemetryLog(reqBody, respBody, context);
    }

Bu ham talab, ham javobni kutadi, bu erda so'rov, bu vazifa emas, balki yuqorida ko'rsatilganidek deyarli bir xil.

Javob kodini ishlatish uchun quyidagi kodni qo'lladim, men ham 204 raqamdan chetlashdi, chunki bu nullrefga olib keladi:

public async Task GetResponseBodyForTelemetry(HttpContext context)
{
    Stream originalBody = context.Response.Body;

        try
        {
            using (var memStream = new MemoryStream())
            {
                context.Response.Body = memStream;

                //await the responsebody
                await next(context);
                if (context.Response.StatusCode == 204)
                {
                    return null;
                }

                memStream.Position = 0;
                var responseBody = new StreamReader(memStream).ReadToEnd();

                //make sure to reset the position so the actual body is still available for the client
                memStream.Position = 0;
                await memStream.CopyToAsync(originalBody);

                return responseBody;
            }
        }
        finally
        {
            context.Response.Body = originalBody;
        }
    }
4
qo'shib qo'ydi
Thanks, kodingiz ishladi. "Response Body" ni ham yoza olsam bo'ladimi? Agar iloji bo'lsa, iloji bo'lsa, ba'zi ko'rsatmalarni yoki kod parchasini almashing.
qo'shib qo'ydi muallif Muhammad Umar, manba
Men "Response Body" ga kirishni xohlaymanmi?
qo'shib qo'ydi muallif Muhammad Umar, manba
Bundan tashqari, "middle telemetry" ni ishlab chiqdim, lekin "Telemetriya boshlang'ichi" bilan amalga oshirilishi mumkinmi, deb hayron bo'ldim. Yaxshiyamki, katta yordam.
qo'shib qo'ydi muallif Muhammad Umar, manba
Ha, bu muammo :). Biroq, men kodni faqat bir marta jurnalga o'zgartirish uchun o'zgartirdim. @joerivrij
qo'shib qo'ydi muallif Muhammad Umar, manba
Narsa siz boshlang'ichni ishlatganda siz hali javob bermayapsiz, shuning uchun uni qanday kutishingiz kerak. Menga yoqmagan narsa, sizdan ikkita alohida jurnalni olishingiz kerak edi, buning o'rniga talab va javob bilan 1 telemetriya elementida bo'lish kerak edi.
qo'shib qo'ydi muallif joerivrij, manba

Buning uchun qidiruv dasturni amalga oshirdim,

Invoke usuli,

 if (context.Request.Method == "POST" || context.Request.Method == "PUT")
        {
            var bodyStr = GetRequestBody(context);
            var telemetryClient = new TelemetryClient();
            var traceTelemetry = new TraceTelemetry
            {
                Message = bodyStr,
                SeverityLevel = SeverityLevel.Verbose
            };
            //Send a trace message for display in Diagnostic Search. 
            telemetryClient.TrackTrace(traceTelemetry);
        }

Qaerda, GetRequestBody o'xshaydi,

private static string GetRequestBody(HttpContext context)
    {
        var bodyStr = "";
        var req = context.Request;

        //Allows using several time the stream in ASP.Net Core.
        req.EnableRewind();

        //Important: keep stream opened to read when handling the request.
        using (var reader = new StreamReader(req.Body, Encoding.UTF8, true, 1024, true))
        {
            bodyStr = reader.ReadToEnd();
        }

       //Rewind, so the core is not lost when it looks the body for the request.
        req.Body.Position = 0;
        return bodyStr;
    }
1
qo'shib qo'ydi
bu kabi holatlar uchun SDK imkoniyatlaridan foydalanishingiz mumkinligini inobatga olgan murakkab echim. Bundan tashqari, iz telemetriyasini tegishli spam-telemetryga mos kelishi kerak
qo'shib qo'ydi muallif yonisha, manba
@ Dhanuka777, yuqoridagi javobni ko'ring. SDK telemetriya boshlang'ich qurilmalari singari bunday holatlar uchun kengaytirilganligini ta'minlaydi. Mening javobimdagi misolga qarang
qo'shib qo'ydi muallif yonisha, manba
Asp.Net yadroida "Microsoft.AspNetCore.Http.Internal.BufferingHelper" da HttpRequest uchun ushbu kengaytma usuli mavjud. docs.microsoft.com/ sahifasiga tashrif buyuring. en-us/aspnet/core/api/hellip;
qo'shib qo'ydi muallif Dhanuka777, manba
@yonisha: "SDK qobiliyatlari" nimani anglatadi?
qo'shib qo'ydi muallif Dhanuka777, manba
Req.EnableRewind() usuli qaerdan keladi?
qo'shib qo'ydi muallif Kai G, manba

Buning o'rniga men DelegatingHandler dan foydalanib, @ yonisha ning javobini qabul qilmadim:

public class MessageTracingHandler : DelegatingHandler
{
    protected override async Task SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
    {
       //Trace the request
        await TraceRequest(request);

       //Execute the request
        var response = await base.SendAsync(request, cancellationToken);

       //Trace the response
        await TraceResponse(response);

        return response;
    }

    private async Task TraceRequest(HttpRequestMessage request)
    {
        try
        {
            var requestTelemetry = HttpContext.Current?.GetRequestTelemetry();

            var requestTraceInfo = request.Content != null ? await request.Content.ReadAsByteArrayAsync() : null;

            var body = requestTraceInfo.ToString();

            if (!string.IsNullOrWhiteSpace(body) && requestTelemetry != null)
            {
                requestTelemetry.Properties.Add("Request Body", body);
            }
        }
        catch (Exception exception)
        {
           //Log exception
        }
    }

    private async Task TraceResponse(HttpResponseMessage response)
    {
        try
        {
            var requestTelemetry = HttpContext.Current?.GetRequestTelemetry();

            var responseTraceInfo = response.Content != null ? await response.Content.ReadAsByteArrayAsync() : null;

            var body = responseTraceInfo.ToString();

            if (!string.IsNullOrWhiteSpace(body) && requestTelemetry != null)
            {
                requestTelemetry.Properties.Add("Response Body", body); 
            }
        }
        catch (Exception exception)
        {
           //Log exception
        }
    }
}

.GetRequestTelemetry() is an extension method from Microsoft.ApplicationInsights.Web.

0
qo'shib qo'ydi

Yonishma tomonidan taqdim etilgan yechim toza, lekin men uchun bu .Net Core 2.0 da ishlamaydi. Agar JSON tanangiz bo'lsa, bu ishlaydi:

public IActionResult MyAction ([FromBody] PayloadObject payloadObject)
{
    //create a dictionary to store the json string
    var customDataDict = new Dictionary();

    //convert the object to a json string
    string activationRequestJson = JsonConvert.SerializeObject(
    new
    {
        payloadObject = payloadObject
    });

    customDataDict.Add("body", activationRequestJson);

    //Track this event, with the json string, in Application Insights
    telemetryClient.TrackEvent("MyAction", customDataDict);

    return Ok();
}
0
qo'shib qo'ydi

Kechirasiz, @ yonishaning echimi. NET 4.7 da ishlamayapti. Ilova tushuntirishlari qismi yaxshi ishlaydi, lekin aslida teletermiya boshlang'ichining ichidagi so'rovni tanasini olish uchun oddiy usul yo'q. . NET 4.7 kanalni olish uchun GetBufferlessInputStream() dan foydalanadi va ushbu oqim "bir marta o'qiladi". Bitta mumkin bo'lgan kod shundaydir:

private static void LogRequestBody(ISupportProperties requestTelemetry)
{
    var requestStream = HttpContext.Current?.Request?.GetBufferlessInputStream();

    if (requestStream?.Length > 0)
        using (var reader = new StreamReader(requestStream))
        {
            string body = reader.ReadToEnd();
            requestTelemetry.Properties["body"] = body.Substring(0, Math.Min(body.Length, 8192));
        }
}

Ammo GetBufferlessInputStream() dan qaytib kelganligi allaqachon eskirgan va qidirishni qo'llab-quvvatlamaydi. Shuning uchun tananing har doim bo'sh bo'lagi bo'ladi.

0
qo'shib qo'ydi