I there an idiomatic way of getting Logs written to a Span? This would accomplish two things at once - eliminate the need for collecting running console outputs and on the other hand it would enable the user to decouple the code from direcly writing to the logs of the current span... The issue I'm facing here is that I am not really clear on the best method to get something like this done. One solution I cam up with was to write an ILogger and ILoggerFactory that look something like this:
internal class Factory : ILoggerProvider
{
public ILogger CreateLogger(string categoryName)
{
return new ToSpanLogger(categoryName);
}
public void Dispose()
{
// nothing to dispose here...
}
}
internal class ToSpanLogger : ILogger
{
private readonly string category;
public ToSpanLogger(string category)
{
this.category = category;
}
public TelemetrySpan Span { get; set; }
public IDisposable BeginScope<TState>(TState state)
{
if (state is TelemetrySpan span)
{
return new SpanScope(this, span);
}
return null;
}
public bool IsEnabled(LogLevel logLevel)
{
return true;
}
public void Log<TState>(LogLevel logLevel, EventId eventId, TState state, Exception exception, Func<TState, Exception, string> formatter)
{
if (this.Span != null)
{
if (logLevel == LogLevel.Error)
{
Span.SetAttribute("error", true);
}
Span.AddEvent(formatter(state, exception));
}
}
}
internal class SpanScope : IDisposable
{
public SpanScope(ToSpanLogger logger, TelemetrySpan span)
{
Logger = logger;
Logger.Span = span;
}
public ToSpanLogger Logger { get; }
public void Dispose()
{
Logger.Span = null;
}
}
}
which could then be used like this:
var span = tracer.StartRootSpan("test", SpanKind.Client, new SpanCreationOptions {});
var logger = scope.ServiceProvider.GetRequiredService<ILogger<Type>>();
using (var logscope = logger.BeginScope(span))
{
logger.LogInformation("starting here");
DoSomeWork();
logger.LogError("ended in desaster");
}
span.End();
I there an idiomatic way of getting Logs written to a Span? This would accomplish two things at once - eliminate the need for collecting running console outputs and on the other hand it would enable the user to decouple the code from direcly writing to the logs of the current span... The issue I'm facing here is that I am not really clear on the best method to get something like this done. One solution I cam up with was to write an
ILoggerandILoggerFactorythat look something like this:which could then be used like this: