如何为多个服务返回一个单一的 traceid - APM Elasticsearch

问题描述

我有一个 asp.net 核心 Web 应用程序 (mvc) 项目,该项目使用 serilog 将日志写入 elasticsearch。我的目标是每当我打开浏览器并执行操作时,将其存储为单个会话 ID,因此当我提取该 ID 时,该会话 ID 的那些日志将填充,因此我可以查看是否可以说有错误在里面,我可以进入它并找出导致它的原因。

我知道使用 APM 我可以关联我的日志。 我有 3 个相互调用的服务:A -> B -> C,我如何将它设置为 traceid 在任何给定调用的 3 个服务上相同的位置。如果假设 C 失败,我可以通过所有 3 个服务看到 APM 跟踪和日志。

在我的 Program.cs 文件中,我正在使用 serilog 和 .Enrich.WithElasticApmCorrelationInfo() 基于我遇到的这个 article 写入 elasticsearch。

public class Program
    {
        public static void Main(string[] args)
        {
            CreateHostBuilder(args).Build().Run();

        }


        public static IHostBuilder CreateHostBuilder(string[] args) =>
            Host.CreateDefaultBuilder(args)
                .UseSerilog((context,configuration) =>
                {
                    configuration.Enrich.FromLogContext()
                        .Enrich.WithElasticApmCorrelationInfo()
                        .Enrich.WithMachineName()
                        .Writeto.Console()
                        .Writeto.Elasticsearch(new ElasticsearchSinkOptions(new Uri(context.Configuration["ElasticConfiguration:Uri"]))
                        {
                            IndexFormat = $"{context.Configuration["ApplicationName"]}-logs-{context.HostingEnvironment.EnvironmentName?.ToLower().Replace(".","-")}-{DateTime.UtcNow:yyyy-MM}",AutoRegisterTemplate = true
                        })
                        .Enrich.WithProperty("Environment",context.HostingEnvironment.EnvironmentName)
                        .ReadFrom.Configuration(context.Configuration);
                })
                .ConfigureWebHostDefaults(webBuilder =>
                {
                    webBuilder.UseStartup<Startup>();
                })
                .UseAllElasticApm();
    }

我有 3 个控制器:

HomeController

public class HomeController : Controller
    {
        private readonly ILogger<HomeController> _logger;

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

        public IActionResult Index()
        {

            return View();
        }

    }

SecondController

public class SecondController : Controller
    {

        private readonly ILogger<SecondController> _logger;

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

        public IActionResult SecIndex()
        { 
            return View();
        }

        [HttpPost]
        public IActionResult SecIndex(TextInput form)
        {
            try
            {
                if (ModelState.IsValid)
                    return RedirectToAction("FinalIndex","Final");
                else
                    throw new Exception("Looks like you did not type something!");
             
            }
            catch(Exception ex)
            {
                _logger.LogError(ex,"Empty textfield!");
                return RedirectToAction("FinalIndex","Final");
            }
        }     
    }

我的最后一个控制器:

public class CompletedController : Controller
    {
        public IActionResult Completedindex()
        {
            return View();
        }
    }

我怎样才能做到这一点?任何建议/指南将不胜感激。

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)