Unverified Commit fb7fb71a authored by Lemon's avatar Lemon Committed by GitHub

Record request logs and exception stack (#42)

parent c2f591a8
using System;
using Microsoft.AspNetCore.Mvc;
namespace SkyWalking.Sample.Backend.Controllers
{
[Route("api/[controller]")]
public class ErrorsController :Controller
{
public string Get()
{
throw new InvalidOperationException("error sample.");
}
}
}
\ No newline at end of file
...@@ -17,7 +17,10 @@ ...@@ -17,7 +17,10 @@
*/ */
using System; using System;
using System.Collections.Generic;
using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Http.Extensions;
using Microsoft.AspNetCore.Mvc.Abstractions;
using SkyWalking.Context; using SkyWalking.Context;
using SkyWalking.Context.Tag; using SkyWalking.Context.Tag;
using SkyWalking.Context.Trace; using SkyWalking.Context.Trace;
...@@ -31,46 +34,86 @@ namespace SkyWalking.AspNetCore.Diagnostics ...@@ -31,46 +34,86 @@ namespace SkyWalking.AspNetCore.Diagnostics
public string ListenerName { get; } = "Microsoft.AspNetCore"; public string ListenerName { get; } = "Microsoft.AspNetCore";
[DiagnosticName("Microsoft.AspNetCore.Hosting.BeginRequest")] [DiagnosticName("Microsoft.AspNetCore.Hosting.BeginRequest")]
public void BeginRequest([Property]HttpContext httpContext) public void BeginRequest([Property] HttpContext httpContext)
{ {
var carrier = new ContextCarrier(); var carrier = new ContextCarrier();
foreach (var item in carrier.Items) foreach (var item in carrier.Items)
item.HeadValue = httpContext.Request.Headers[item.HeadKey]; item.HeadValue = httpContext.Request.Headers[item.HeadKey];
var httpRequestSpan = ContextManager.CreateEntrySpan(httpContext.Request.Path, carrier); var httpRequestSpan = ContextManager.CreateEntrySpan(httpContext.Request.Path, carrier);
httpRequestSpan.AsHttp(); httpRequestSpan.AsHttp();
httpRequestSpan.SetComponent(ComponentsDefine.AspNetCore); httpRequestSpan.SetComponent(ComponentsDefine.AspNetCore);
Tags.Url.Set(httpRequestSpan, httpContext.Request.Path); Tags.Url.Set(httpRequestSpan, httpContext.Request.Path);
Tags.HTTP.Method.Set(httpRequestSpan, httpContext.Request.Method); Tags.HTTP.Method.Set(httpRequestSpan, httpContext.Request.Method);
httpRequestSpan.Log(DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(),
new Dictionary<string, object>
{
{"event", "AspNetCore Hosting BeginRequest"},
{"message", $"Request starting {httpContext.Request.Protocol} {httpContext.Request.Method} {httpContext.Request.GetDisplayUrl()}"}
});
httpContext.Items[HttpContextDiagnosticStrings.SpanKey] = httpRequestSpan;
} }
[DiagnosticName("Microsoft.AspNetCore.Hosting.EndRequest")] [DiagnosticName("Microsoft.AspNetCore.Hosting.EndRequest")]
public void EndRequest([Property]HttpContext httpContext) public void EndRequest([Property] HttpContext httpContext)
{ {
var httpRequestSpan = ContextManager.ActiveSpan; var httpRequestSpan = ContextManager.ActiveSpan;
if (httpRequestSpan == null) if (httpRequestSpan == null)
{ {
return; return;
} }
var statusCode = httpContext.Response.StatusCode; var statusCode = httpContext.Response.StatusCode;
if (statusCode >= 400) if (statusCode >= 400)
{ {
httpRequestSpan.ErrorOccurred(); httpRequestSpan.ErrorOccurred();
} }
Tags.StatusCode.Set(httpRequestSpan, statusCode.ToString()); Tags.StatusCode.Set(httpRequestSpan, statusCode.ToString());
httpRequestSpan.Log(DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(),
new Dictionary<string, object>
{
{"event", "AspNetCore Hosting EndRequest"},
{"message", $"Request finished {httpContext.Response.StatusCode} {httpContext.Response.ContentType}"}
});
ContextManager.StopSpan(httpRequestSpan); ContextManager.StopSpan(httpRequestSpan);
} }
[DiagnosticName("Microsoft.AspNetCore.Diagnostics.UnhandledException")] [DiagnosticName("Microsoft.AspNetCore.Diagnostics.UnhandledException")]
public void DiagnosticUnhandledException(HttpContext httpContext, Exception exception) public void DiagnosticUnhandledException([Property]HttpContext httpContext, [Property]Exception exception)
{ {
ContextManager.ActiveSpan.ErrorOccurred(); ContextManager.ActiveSpan?.ErrorOccurred()?.Log(exception);
} }
[DiagnosticName("Microsoft.AspNetCore.Hosting.UnhandledException")] [DiagnosticName("Microsoft.AspNetCore.Hosting.UnhandledException")]
public void HostingUnhandledException([Property]HttpContext httpContext, [Property]Exception exception) public void HostingUnhandledException([Property]HttpContext httpContext, [Property]Exception exception)
{ {
ContextManager.ActiveSpan.ErrorOccurred(); ContextManager.ActiveSpan?.ErrorOccurred()?.Log(exception);
}
[DiagnosticName("Microsoft.AspNetCore.Mvc.BeforeAction")]
public void BeforeAction([Property]ActionDescriptor actionDescriptor, [Property]HttpContext httpContext)
{
var span = httpContext.Items[HttpContextDiagnosticStrings.SpanKey] as ISpan;
if (span == null)
{
return;
}
var events = new Dictionary<string, object> {{"event", "AspNetCore.Mvc Executing action method"}, {"Action method", actionDescriptor.DisplayName}};
span.Log(DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(), events);
}
[DiagnosticName("Microsoft.AspNetCore.Mvc.AfterAction")]
public void AfterAction([Property]ActionDescriptor actionDescriptor, [Property]HttpContext httpContext)
{
var span = httpContext.Items[HttpContextDiagnosticStrings.SpanKey] as ISpan;
if (span == null)
{
return;
}
var events = new Dictionary<string, object> {{"event", "AspNetCore.Mvc Executed action method"}};
span.Log(DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(), events);
} }
} }
} }
\ No newline at end of file
/*
* Licensed to the OpenSkywalking under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
namespace SkyWalking.AspNetCore.Diagnostics
{
internal static class HttpContextDiagnosticStrings
{
public const string SpanKey = "sw3-http";
}
}
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment