question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

No custom logs when using Serilog

See original GitHub issue

Requirement - what kind of business use case are you trying to solve?

I need to send to Jaeger custom logs. Now it works only when I use Microsoft.Extensions.Logging.ILoggerFactory

My Startup

public void ConfigureServices(IServiceCollection services)
{
	services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);

	services.AddOpenTracing();
	services.AddSingleton<ITracer>(sp =>
	{
		var loggerFactory = sp.GetRequiredService<ILoggerFactory>();

		var reporter = new RemoteReporter.Builder()
			.WithSender(new UdpSender())
			.WithLoggerFactory(loggerFactory)
			.Build();		

		var tracer = new Tracer
				.Builder("Sample service")
			.WithReporter(reporter)
			.WithSampler(new ConstSampler(true))
			.Build();

		GlobalTracer.Register(tracer);
		return tracer;
	});
}

Somewhere in controller: using Microsoft.Extensions.Logging;

namespace WebApplication2.Controllers
{
    [Route("api/[controller]")]
    public class ValuesController : ControllerBase
    {
        private readonly ILogger<ValuesController> _logger;

        public ValuesController(ILogger<ValuesController> logger)
        {
            _logger = logger;
        }
		
        // GET api/values/5
        [HttpGet("{id}")]
        public ActionResult<string> Get(int id)
        {
            _logger.LogWarning("Get values by id: {valueId}", id);
            return "value";
        }

Result image

Problem - what in Jaeger blocks you from solving the requirement?

But when I use Serilog, there are no any custom logs. I just install serilog and add

public static IWebHostBuilder CreateWebHostBuilder(string[] args)
{
	return WebHost.CreateDefaultBuilder(args)
		.UseStartup<Startup>()
		.UseSerilog();
}

Could you please suggest why custom logging doesn’t work with Serilog?

Issue Analytics

  • State:closed
  • Created 4 years ago
  • Comments:5

github_iconTop GitHub Comments

3reactions
nblumhardtcommented, May 19, 2019

Hi @Marusyk

WriteTo.OpenTracing() would just be a convenience wrapper for WriteTo.Sink(new OpenTracingSink(...)), so the sink class would be the best place to start.

This would need to implement Serilog’s ILogEventSink, and do almost exactly what this method does - accept a LogEvent from Serilog, convert its properties into a fields dictionary, and pass these through _tracer.ActiveSpan.Log(...).

There are quite a lot of implementations of ILogEventSink out there to examine for examples (any Serilog.Sink.* will have one.

The trick will be how to get an ITracer into the sink, somehow - either via its constructor or some other mechanism. Order of initialization can be a bit tricky but generally there’s a way 😃

Hope this helps! Nick

1reaction
Marusykcommented, May 20, 2019

Thanks a lot. It was very helpful. My implementations of that:

public class OpenTracingSink : ILogEventSink
{
	private readonly ITracer _tracer;
	private readonly IFormatProvider _formatProvider;

	public OpenTracingSink(ITracer tracer, IFormatProvider formatProvider)
	{
		_tracer = tracer;
		_formatProvider = formatProvider;
	}

	public void Emit(LogEvent logEvent)
	{
		ISpan span = _tracer.ActiveSpan;

		if (span == null)
		{
			// Creating a new span for a log message seems brutal so we ignore messages if we can't attach it to an active span.
			return;
		}

		var fields = new Dictionary<string, object>
		{
			{ "component", logEvent.Properties["SourceContext"] },
			{ "level", logEvent.Level.ToString() }
		};

		fields[LogFields.Event] = "log";

		try
		{
			fields[LogFields.Message] = logEvent.RenderMessage(_formatProvider);
			fields["message.template"] = logEvent.MessageTemplate.Text;

			if (logEvent.Exception != null)
			{
				fields[LogFields.ErrorKind] = logEvent.Exception.GetType().FullName;
				fields[LogFields.ErrorObject] = logEvent.Exception;
			}

			if (logEvent.Properties != null)
			{
				foreach (var property in logEvent.Properties)
				{
					fields[property.Key] = property.Value;
				}
			}
		}
		catch (Exception logException)
		{
			fields["mbv.common.logging.error"] = logException.ToString();
		}

		span.Log(fields);
	}
}

public static class OpenTracingSinkExtensions
{
	public static LoggerConfiguration OpenTracing(
			  this LoggerSinkConfiguration loggerConfiguration,
			  IFormatProvider formatProvider = null)
	{
		return loggerConfiguration.Sink(new OpenTracingSink(GlobalTracer.Instance, formatProvider));
	}
}

After merge your PR, should it work without this sink?

Read more comments on GitHub >

github_iconTop Results From Across the Web

How to force Serilog to log only my custom log messages
Because your own custom log message will not be logged under a Microsoft category, you will still see that in the output.
Read more >
No custom logs when using Serilog · Issue #146
It looks like Serilog is not using the normal ILoggerProvider singleton that are regularily used and that is registered with AddOpenTracing() .
Read more >
Troubleshoot no logging using Serilog
Tried to enable the SelfLog to log in the console while debugging but I get no message there either. Any clue about how...
Read more >
Serilog Tutorial for .NET Logging: 16 Best Practices and Tips
Serilog makes it easy to record custom object properties and output your logs to JSON. Read this Serilog tutorial for best practices and ......
Read more >
Setting up Serilog in ASP.NET Core - Detailed Beginner ...
This article covers the implementation of Serilog in ASP.NET Core which provides structured logging that is easier to be read by programs.
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found