Azure functions Azure应用程序洞察关联功能中的方面
我已经编写了许多Azure函数(Http、ServiceBus、EventHub和CosmosDB触发器)。对于应用程序日志记录,我实现了自己的Logger类,它创建TelemetryClient对象来接收application Insight中的日志 我可以在Application Insight中查看我的所有跟踪、异常和异常日志,但如果没有OperationName和OperationId 现在我正在手动调用TelemetryClientStartOperation和StopOperation来创建OperationId AzureFunctionAzure functions Azure应用程序洞察关联功能中的方面,azure-functions,aop,azure-application-insights,Azure Functions,Aop,Azure Application Insights,我已经编写了许多Azure函数(Http、ServiceBus、EventHub和CosmosDB触发器)。对于应用程序日志记录,我实现了自己的Logger类,它创建TelemetryClient对象来接收application Insight中的日志 我可以在Application Insight中查看我的所有跟踪、异常和异常日志,但如果没有OperationName和OperationId 现在我正在手动调用TelemetryClientStartOperation和StopOperatio
[FunctionName("AlertEventStoreFunction")]
public static async Task Run([EventHubTrigger("%AlertEventHub%", Connection = "AlertEventHubConnection", ConsumerGroup = "cg1")]EventData eventMessage,
[Inject]IEventService eventService, [Inject]ILog log)
{
log.StartOperation("AlertEventStoreFunction");
try
{
log.Info($"Event PartitionKey {eventMessage.PartitionKey}, Offset {eventMessage.Offset} and SequenceNumber {eventMessage.SequenceNumber}");
string message = Encoding.UTF8.GetString(eventMessage.GetBytes());
log.Verbose(message);
await eventService.SaveAlertEventAsync(message);
}
catch (Exception ex)
{
log.Error(ex.Message, ex);
}
finally
{
log.StopOperation();
}
}
记录器类
public class Log : ILog
{
private static TelemetryClient telemetryClient = new TelemetryClient() { InstrumentationKey = ConfigurationManager.AppSettings["InstrumentationKey"] };
private IOperationHolder<RequestTelemetry> operation;
private bool status = true;
public TelemetryClient TelemetryClient
{
get
{
return telemetryClient;
}
}
/// <summary>
/// This method will start new session for particular request, we can correlate each log by Operation_Id
/// </summary>
/// <param name="functionName">function name</param>
public void StartOperation(string functionName)
{
RequestTelemetry requestTelemetry = new RequestTelemetry { Name = functionName };
this.operation = telemetryClient.StartOperation(requestTelemetry);
telemetryClient.TrackTrace($"{functionName} trigger");
}
/// <summary>
/// this method will close session
/// </summary>
public void StopOperation()
{
telemetryClient.StopOperation(this.operation);
this.operation.Telemetry.Success = status;
}
public void Error(string message, Exception ex = null)
{
telemetryClient.TrackTrace(message, SeverityLevel.Error);
if (ex != null)
telemetryClient.TrackException(ex);
status = false;
}
public void Info(string message)
{
telemetryClient.TrackTrace(message, SeverityLevel.Information);
}
public void Verbose(string message)
{
telemetryClient.TrackTrace(message, SeverityLevel.Verbose);
}
public void Warning(string message)
{
telemetryClient.TrackTrace(message, SeverityLevel.Warning);
}
}
公共类日志:ILog
{
私有静态遥测客户端遥测客户端=新遥测客户端(){InstrumentationKey=ConfigurationManager.AppSettings[“InstrumentationKey”]};
私人运营持有人运营;
私有布尔状态=真;
公共遥测客户端遥测客户端
{
得到
{
返回遥测客户端;
}
}
///
///此方法将为特定请求启动新会话,我们可以通过操作\u Id关联每个日志
///
///函数名
公共无效开始操作(字符串函数名)
{
RequestTelemetry RequestTelemetry=new RequestTelemetry{Name=functionName};
this.operation=telemetryClient.StartOperation(请求遥测);
TrackTrace($“{functionName}触发器”);
}
///
///此方法将关闭会话
///
公共无效停止操作()
{
telemetryClient.StopOperation(此操作);
this.operation.Telemetry.Success=状态;
}
公共无效错误(字符串消息,异常ex=null)
{
telemetryClient.TrackTrace(消息,严重级别错误);
如果(ex!=null)
telemetryClient.TrackException(ex);
状态=假;
}
公共无效信息(字符串消息)
{
telemetryClient.TrackTrace(消息、服务器级别信息);
}
公共无效详细信息(字符串消息)
{
telemetryClient.TrackTrace(消息,SeverityLevel.Verbose);
}
公共无效警告(字符串消息)
{
telemetryClient.TrackTrace(消息,严重级别警告);
}
}
我不想把try-catch块放在每个函数中,所以我使用postsharp创建了Aspect(AOP),它按预期工作,但免费版本只允许10个函数
我没有看到任何其他优秀的postsharp替代品(试过sprint.net、Cauldron.Interception等)
除了这段代码,我能做些什么来创建相关性(OperationId)?我得到了Postsharp的备选“MrAdvice”,新版本没有任何依赖性
public class LoggerAspect : Attribute, IMethodAdvice
{
private ILog log;
private IOperationHolder<RequestTelemetry> operation;
public void Advise(MethodAdviceContext context)
{
try
{
log = LogManager.GetLogger();
RequestTelemetry requestTelemetry = new RequestTelemetry { Name = context.TargetType.Name };
operation = log.TelemetryClient.StartOperation(requestTelemetry);
operation.Telemetry.Success = true;
context.Proceed(); // this calls the original method
}
catch (Exception ex)
{
operation.Telemetry.Success = false;
log.Error(ex.Message, ex);
}
finally
{
log.TelemetryClient.StopOperation(operation);
}
}
}
公共类LoggerAspect:属性,IMethodDevice
{
私人ILog日志;
私人运营持有人运营;
public void advice(methodadvice上下文)
{
尝试
{
log=LogManager.GetLogger();
RequestTelemetry RequestTelemetry=new RequestTelemetry{Name=context.TargetType.Name};
操作=log.TelemetryClient.startoOperation(请求遥测);
operation.Telemetry.Success=true;
context.procedure();//这将调用原始方法
}
捕获(例外情况除外)
{
operation.Telemetry.Success=false;
日志错误(例如消息,例如);
}
最后
{
日志.遥测客户端.停止操作(操作);
}
}
}
仍然欢迎更好的建议