首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >OpenTracing不使用Serilog发送日志

OpenTracing不使用Serilog发送日志
EN

Stack Overflow用户
提问于 2019-05-16 04:02:44
回答 2查看 2.8K关注 0票数 17

我正在尝试将OpenTracing.Contrib.NetCore与Serilog结合使用。我需要把我的自定义日志发送给Jaeger。现在,只有当我使用默认的记录器工厂Microsoft.Extensions.Logging.ILoggerFactory时,它才能工作

我的初创公司:

代码语言:javascript
复制
public void ConfigureServices(IServiceCollection services)
{
    services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);

    services.AddSingleton<ITracer>(sp =>
    {
        var loggerFactory = sp.GetRequiredService<ILoggerFactory>();
        string serviceName = sp.GetRequiredService<IHostingEnvironment>().ApplicationName;

        var samplerConfiguration = new Configuration.SamplerConfiguration(loggerFactory)
            .WithType(ConstSampler.Type)
            .WithParam(1);

        var senderConfiguration = new Configuration.SenderConfiguration(loggerFactory)
            .WithAgentHost("localhost")
            .WithAgentPort(6831);

        var reporterConfiguration = new Configuration.ReporterConfiguration(loggerFactory)
            .WithLogSpans(true)
            .WithSender(senderConfiguration);

        var tracer = (Tracer)new Configuration(serviceName, loggerFactory)
            .WithSampler(samplerConfiguration)
            .WithReporter(reporterConfiguration)
            .GetTracer();

        //GlobalTracer.Register(tracer);
        return tracer;
    });
    services.AddOpenTracing();
}

在控制器中的某个位置:

代码语言:javascript
复制
[Route("api/[controller]")]
public class ValuesController : ControllerBase
{
    private readonly ILogger<ValuesController> _logger;

    public ValuesController(ILogger<ValuesController> logger)
    {
        _logger = logger;
    }

    [HttpGet("{id}")]
    public ActionResult<string> Get(int id)
    {
        _logger.LogWarning("Get values by id: {valueId}", id);
        return "value";
    }
}

因此,我将能够在Jaeger UI中看到日志

但是当我使用Serilog时,没有任何自定义日志。我已经在WebHostBuilder中添加了UseSerilog(),以及在控制台中可以看到但在积家中看不到的所有自定义日志。github中存在未解决的问题。你能建议我如何在OpenTracing中使用Serilog吗?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2019-05-21 03:55:44

这是Serilog记录器工厂实现中的一个限制;具体地说,Serilog目前忽略了添加的提供程序,并假设Serilog接收器将替换它们。

因此,解决方案是通过一个简单的WriteTo.OpenTracing()方法将Serilog直接连接到OpenTracing

代码语言:javascript
复制
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));
    }
}
票数 12
EN

Stack Overflow用户

发布于 2021-05-16 02:40:12

您必须告诉Serilog使用writeToProviders: true将日志条目传递给ILoggerProvider

代码语言:javascript
复制
.UseSerilog(
    (hostingContext, services, loggerConfiguration) => /* snip! */,
    writeToProviders: true)

这只转发使用ILogger编写的内容。写到SeriLog日志方法中的东西似乎并没有成功。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/56156809

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档