Azure 使用log4net的遥测相关应用
我希望我们的分布式事件日志具有适当的相关性。对于我们的Web应用程序来说,这似乎是自动的。来自我们的一个应用程序服务API的相关日志示例: 然而,对于我们的其他(非ASP、非WebApp)服务,我们使用Log4Net和App Insights appender,我们的日志不相关。我尝试了以下说明: 即使在为每个操作添加了唯一的操作Id属性之后,我们也看不到日志关联(我还尝试了“操作Id”)。无相关日志条目的示例: 任何关于如何使用log4net实现这一点的帮助都将不胜感激Azure 使用log4net的遥测相关应用,azure,log4net,azure-application-insights,azure-log-analytics,Azure,Log4net,Azure Application Insights,Azure Log Analytics,我希望我们的分布式事件日志具有适当的相关性。对于我们的Web应用程序来说,这似乎是自动的。来自我们的一个应用程序服务API的相关日志示例: 然而,对于我们的其他(非ASP、非WebApp)服务,我们使用Log4Net和App Insights appender,我们的日志不相关。我尝试了以下说明: 即使在为每个操作添加了唯一的操作Id属性之后,我们也看不到日志关联(我还尝试了“操作Id”)。无相关日志条目的示例: 任何关于如何使用log4net实现这一点的帮助都将不胜感激 干杯 跨服务关联I
干杯 跨服务关联ID主要通过头进行传播。当为Web应用程序启用AI时,它从传入的头读取ID/上下文,然后用适当的ID/上下文更新传出的头。在服务中,使用活动对象跟踪操作,发出的每个遥测将与此活动关联,从而共享必要的关联ID 在服务总线/事件集线器通信的情况下,传播(ID/上下文作为元数据传播) 如果服务不是基于web的,并且AI自动关联传播不起作用,则来自某些元数据的信息(如果存在),还原/启动活动,使用此活动启动AI操作。当遥测项在该活动的范围内生成时,它将获得正确的ID,并将成为总体跟踪的一部分。这样,如果遥测是从在AI操作上下文范围内执行的Log4net跟踪生成的,那么遥测应该得到正确的ID 要从标题访问相关性,请执行以下操作:
public class ApplicationInsightsMiddleware : OwinMiddleware
{
// you may create a new TelemetryConfiguration instance, reuse one you already have
// or fetch the instance created by Application Insights SDK.
private readonly TelemetryConfiguration telemetryConfiguration = TelemetryConfiguration.CreateDefault();
private readonly TelemetryClient telemetryClient = new TelemetryClient(telemetryConfiguration);
public ApplicationInsightsMiddleware(OwinMiddleware next) : base(next) {}
public override async Task Invoke(IOwinContext context)
{
// Let's create and start RequestTelemetry.
var requestTelemetry = new RequestTelemetry
{
Name = $"{context.Request.Method} {context.Request.Uri.GetLeftPart(UriPartial.Path)}"
};
// If there is a Request-Id received from the upstream service, set the telemetry context accordingly.
if (context.Request.Headers.ContainsKey("Request-Id"))
{
var requestId = context.Request.Headers.Get("Request-Id");
// Get the operation ID from the Request-Id (if you follow the HTTP Protocol for Correlation).
requestTelemetry.Context.Operation.Id = GetOperationId(requestId);
requestTelemetry.Context.Operation.ParentId = requestId;
}
// StartOperation is a helper method that allows correlation of
// current operations with nested operations/telemetry
// and initializes start time and duration on telemetry items.
var operation = telemetryClient.StartOperation(requestTelemetry);
// Process the request.
try
{
await Next.Invoke(context);
}
catch (Exception e)
{
requestTelemetry.Success = false;
telemetryClient.TrackException(e);
throw;
}
finally
{
// Update status code and success as appropriate.
if (context.Response != null)
{
requestTelemetry.ResponseCode = context.Response.StatusCode.ToString();
requestTelemetry.Success = context.Response.StatusCode >= 200 && context.Response.StatusCode <= 299;
}
else
{
requestTelemetry.Success = false;
}
// Now it's time to stop the operation (and track telemetry).
telemetryClient.StopOperation(operation);
}
}
public static string GetOperationId(string id)
{
// Returns the root ID from the '|' to the first '.' if any.
int rootEnd = id.IndexOf('.');
if (rootEnd < 0)
rootEnd = id.Length;
int rootStart = id[0] == '|' ? 1 : 0;
return id.Substring(rootStart, rootEnd - rootStart);
}
}
公共类应用程序InsightsMiddleware:OWIN中间件
{
//您可以创建一个新的TelemetryConfiguration实例,重用已有的实例
//或者获取Application Insights SDK创建的实例。
私有只读遥测配置遥测配置=遥测配置。CreateDefault();
专用只读遥测客户端遥测客户端=新遥测客户端(遥测配置);
公共应用程序RightsMiddleware(OWINNEXT中间件):基本(next){
公共重写异步任务调用(IOwinContext上下文)
{
//让我们创建并启动RequestTelemetry。
var requestTelemetry=新的requestTelemetry
{
Name=$“{context.Request.Method}{context.Request.Uri.GetLeftPart(UriPartial.Path)}”
};
//如果从上游服务接收到请求Id,则相应地设置遥测上下文。
if(context.Request.Headers.ContainsKey(“请求Id”))
{
var requestId=context.Request.Headers.Get(“请求Id”);
//从请求ID获取操作ID(如果遵循HTTP协议进行关联)。
requestTelemetry.Context.Operation.Id=GetOperationId(requestId);
requestTelemetry.Context.Operation.ParentId=requestId;
}
//StartOperation是一种辅助方法,允许关联
//当前操作与嵌套操作/遥测
//并初始化遥测项目的开始时间和持续时间。
var操作=遥测客户端.StartOperation(请求遥测);
//处理请求。
尝试
{
等待下一步。调用(上下文);
}
捕获(例外e)
{
requestTelemetry.Success=false;
遥测客户端.TrackException(e);
投掷;
}
最后
{
//根据需要更新状态代码和成功。
if(context.Response!=null)
{
requestTelemetry.ResponseCode=context.Response.StatusCode.ToString();
requestTelemetry.Success=context.Response.StatusCode>=200&&context.Response.StatusCode我会尝试一下并报告回来-感谢您的详细回复!
async Task BackgroundTask()
{
var operation = telemetryClient.StartOperation<DependencyTelemetry>(taskName);
operation.Telemetry.Type = "Background";
try
{
int progress = 0;
while (progress < 100)
{
// Process the task.
telemetryClient.TrackTrace($"done {progress++}%");
}
// Update status code and success as appropriate.
}
catch (Exception e)
{
telemetryClient.TrackException(e);
// Update status code and success as appropriate.
throw;
}
finally
{
telemetryClient.StopOperation(operation);
}
}