public async Task InsertRecordAsync(HttpEntry record) { var path = Path.Combine(_location, record.LoggingId.ToString("d")); using (var stream = File.OpenWrite(path)) using (var writer = new StreamWriter(stream)) await writer.WriteAsync(JsonConvert.SerializeObject(record)); }
/// <summary> /// Processes the incoming HTTP call and capture details about /// the request, the response, the identity of the caller and the /// call duration to persistent storage. /// </summary> /// <param name="context">A reference to the Owin context.</param> /// <returns /> public override async Task Invoke(IOwinContext context) { var request = context.Request; var response = context.Response; // capture details about the caller identity var identity = request.User != null && request.User.Identity.IsAuthenticated ? request.User.Identity.Name : "(anonymous)" ; var record = new HttpEntry { CallerIdentity = identity, }; // replace the request stream in order to intercept downstream reads var requestBuffer = new MemoryStream(); var requestStream = new ContentStream(requestBuffer, request.Body); request.Body = requestStream; // replace the response stream in order to intercept downstream writes var responseBuffer = new MemoryStream(); var responseStream = new ContentStream(responseBuffer, response.Body); response.Body = responseStream; // add the "Http-Tracking-Id" response header context.Response.OnSendingHeaders(state => { var ctx = state as IOwinContext; if (ctx == null) return; var resp = ctx.Response; // adding the tracking id response header so that the user // of the API can correlate the call back to this entry //resp.Headers.Add(_trackingIdPropertyName, new[] { record.LoggingId.ToString("d"), }); }, context); // invoke the next middleware in the pipeline await Next.Invoke(context); // rewind the request and response buffers // and record their content WriteRequestHeaders(request, record); record.RequestLength = requestStream.ContentLength; record.Request = await WriteContentAsync(requestStream, record.RequestHeaders, _maxRequestLength); WriteResponseHeaders(response, record); record.ResponseLength = responseStream.ContentLength; record.Response = await WriteContentAsync(responseStream, record.ResponseHeaders, _maxResponseLength); // persist details of the call to durable storage await HttpLoggingStore.InsertRecordAsync(record); }
private static void WriteResponseHeaders(IOwinResponse response, HttpEntry record) { record.StatusCode = response.StatusCode; record.ReasonPhrase = response.ReasonPhrase; record.ResponseHeaders = response.Headers; }
private static void WriteRequestHeaders(IOwinRequest request, HttpEntry record) { record.Verb = request.Method; record.RequestUri = request.Uri; record.RequestHeaders = request.Headers; }