ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

引入Jaeger——扩展

2022-02-02 20:34:53  阅读:131  来源: 互联网

标签:set string get Jaeger 扩展 var 引入 using public


  Jaeger是收集全链路跟踪的信息,在Jaeger收集的信息中,有请求的url信息,有每个请求的时间间隔,借助这些信息可以进行报警,比如一次较长的请求,或者是某些请求的次数和先后等。不管报警的业务规则是什么,首先得收集Jaeger中的信息。

  Jaeger有api可以提供这些信息,比如

  /api/services,获取所有服务

  /api/traces?service={servicename}获取该服务下的所有跟踪

  /api/traces/{traceid}获取某个跟踪的信息等

  /api/traces?end={endtime}&limit={20}&lookback={1h}&service={servicename}&start={starttime}按条件查询跟踪信息等api

下面代码定义Jaeger中的实体类,类中的属性可以根据自己的型业务规则收集,这里定义不完整

 

using System.Collections.Generic;

namespace JaegerAlert
{
    /// <summary>
    /// 服务报警
    /// </summary>
    public class AlertList
    {
        public string ServiceName { get; set; }
        public List<AlertItem> Alerts { get; set; }
    }
    /// <summary>
    /// 报警条目
    /// </summary>
    public class AlertItem
    {
        public string TraceID { get; set; }
        public long StartTime { get; set; }

        public long Duration { get; set; }

        public string Method { get; set; }

        public string Operation { get; set; }
    }

    /// <summary>
    /// 服务数据
    /// </summary>
    public class ServicesData
    {
        public string[] Data { get; set; }
        public int Total { get; set; }
        public int Limit { get; set; }
        public int Offset { get; set; }
    }

    /// <summary>
    /// 跟踪数据
    /// </summary>
    public class TracesData
    {
        public TracesItem[] Data { get; set; }
        public int Total { get; set; }
        public int Limit { get; set; }
        public int Offset { get; set; }
    }
    /// <summary>
    /// 跟踪条目
    /// </summary>
    public class TracesItem
    {
        public string TraceID { get; set; }

        public Span[] Spans { get; set; }
    }
    /// <summary>
    /// Span
    /// </summary>
    public class Span
    {
        public string TraceID { get; set; }
        public string SpanID { get; set; }
        public bool IsAlertMark => TraceID == SpanID;
        public int Flags { get; set; }
        public string OperationName { get; set; }
        public long StartTime { get; set; }

        public long Duration { get; set; }
        public Tag[] Tags { get; set; }
    }
    /// <summary>
    /// Tag
    /// </summary>
    public class Tag
    {
        public string Key { get; set; }
        public string Type { get; set; }

        public string Value { get; set; }
    }
}

这里简单进行了收集,转换成了自己的数据集合,方便对接自己的报警平台:

using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Threading.Tasks;

namespace JaegerAlert.Controllers
{
    [ApiController]
    [Route("[controller]")]
    public class HomeController : ControllerBase
    {
        private readonly IHttpClientFactory _clientFactory;
        private readonly ILogger<HomeController> _logger;

        public HomeController(ILogger<HomeController> logger, IHttpClientFactory clientFactory)
        {
            _clientFactory = clientFactory;
            _logger = logger;
        }

        [HttpGet]
        public async Task<IEnumerable<AlertList>> Get()
        {
            _logger.LogInformation("获取警报列表");
            return await GetServices();
        }
        /// <summary>
        /// 获取所有服务
        /// </summary>
        /// <returns></returns>
        async Task<IEnumerable<AlertList>> GetServices()
        {
            var service = await GetJaegerServices();
            var services = new List<AlertList>();
            foreach (var serviceName in service.Data)
            {
                if (serviceName == "jaeger-query")
                {
                    continue;
                }
                var alerts = new List<AlertItem>();
                var tracesModels = await GetJaegerTraces(serviceName);
                foreach (var traces in tracesModels.Data)
                {
                    foreach (var span in traces.Spans)
                    {
                        if (span.IsAlertMark)
                        {
                            var method = span.Tags.SingleOrDefault(s => s.Key == "http.method")?.Value;
                            var operation = span.Tags.SingleOrDefault(s => s.Key == "http.url")?.Value;
                            alerts.Add(new AlertItem { TraceID = traces.TraceID, Duration = span.Duration, Method = method, Operation = operation, StartTime = span.StartTime });
                        }
                    }
                }
                services.Add(new AlertList() { ServiceName = serviceName, Alerts = alerts });
            }
            return services;
        }

        /// <summary>
        /// 获取服务下的跟踪条目
        /// </summary>
        /// <param name="serviceName"></param>
        /// <returns></returns>
        async Task<TracesData> GetJaegerTraces(string serviceName)
        {
            using var client = _clientFactory.CreateClient("Jaeger");
            var request = new HttpRequestMessage(HttpMethod.Get, $"/api/traces?service={serviceName}");

            using var response = await client.SendAsync(request);
            if (response.IsSuccessStatusCode)
            {
                var jsonString = await response.Content.ReadAsStringAsync();
                var traces = Newtonsoft.Json.JsonConvert.DeserializeObject<TracesData>(jsonString);
                return traces;
            }
            else
            {
                return new TracesData();
            }
        }
        /// <summary>
        /// 获取服务
        /// </summary>
        /// <returns></returns>
        async Task<ServicesData> GetJaegerServices()
        {
            using var client = _clientFactory.CreateClient("Jaeger");
            var request = new HttpRequestMessage(HttpMethod.Get, "/api/services");
            using var response = await client.SendAsync(request);
            if (response.IsSuccessStatusCode)
            {
                var jsonString = await response.Content.ReadAsStringAsync();
                var service = Newtonsoft.Json.JsonConvert.DeserializeObject<ServicesData>(jsonString);
                return service;
            }
            else
            {
                return new ServicesData();
            }
        }
    }   
}

请求结果:

 

  收集到数据后,就可以应用到报警平台上,如果报警平台有api,可以进行调用处理;还可以把这些数据推送到时序数据库中,如InfluxDB,再通过Grafana展示出来,进行实时展时跟踪,关于跟踪的细节和业务规则有关系,如果以后工作中遇到这类处理,到时再追加一篇博文进行细说。

 

  想要更快更方便的了解相关知识,可以关注微信公众号   

 

 

标签:set,string,get,Jaeger,扩展,var,引入,using,public
来源: https://www.cnblogs.com/ljknlb/p/15860684.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有