我已经编写了许多Azure函数(Http,ServiceBus,EventHub和CosmosDB触发器)。对于应用程序日志记录,我实现了自己的Logger类,该类创建 TelemetryClient 对象以在Application Insight中接收日志。
我可以在Application Insight中看到所有的跟踪,异常和异常日志,但是如果没有 OperationName 和 OperationId
,我将无法关联现在,我手动调用TelemetryClient StartOperation 和 StopOperation 创建OperationId。
AzureFunction
[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);
}
}
我不想在每个函数中都放置try-catch块,所以我使用postsharp创建了Aspect(AOP),它按预期工作,但是免费版本仅允许10个函数。
我看不到其他任何可以很好地替代postharp的工具(尝试过sprint.net,Cauldron.Interception等)
代替该代码,我可以做什么来创建关联(OperationId)?
答案 0 :(得分:1)
我得到了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);
}
}
}
仍然开放以获得更好的建议。