评论

收藏

[.Net] .net core 使用阿里云分布式日志的配置方法

编程语言 编程语言 发布于:2021-08-04 10:24 | 阅读数:429 | 评论:0

前言
好久没有出来夸白了,今天教大家简单的使用阿里云分布式日志,来存储日志,没有阿里云账号的,可以免费注册一个
DSC0000.gif

开通阿里云分布式日志(有一定的免费额度,个人测试学习完全没问题的,香)
阿里云日志地址:https://sls.console.aliyun.com/lognext/profile
先开通阿里云日志,这个比较简单授权就可以了
选择接入数据,我们这里选 .NET
DSC0001.jpg

选择项目名称,没有项目的可以去创建一个,项目名称后面会用到,如果你有购买阿里云ECS,项目区域最好选择跟ECS同一个区域(每个区域的地址不一样,同一个区域可以选择内网通讯,速度更快),如果没有,就随便选个区域,我这里选择的是杭州
DSC0002.png

选择日志库,没有就创建一个
DSC0003.png

数据源配置,这个先不用管,后面有教程
设置分析配置,例如我这里设置了两个,可以根据业务需求来,没有特殊要求不用设置
DSC0004.png

开通完成,可以正常看到仪盘表
DSC0005.png

设置密钥
DSC0006.png

通过SDK 写入日志
阿里云有提供对应的SDK(阿里云 .NET SDK的质量大家都懂),它主要是通过构造一个静态对象来提供访问的,地址: https://github.com/aliyun/aliyun-log-dotnetcore-sdk
阿里云代码
LogServiceClientBuilders.HttpBuilder
  .Endpoint("<endpoint>", "<projectName>")
  .Credential("<accessKeyId>", "<accessKey>")
  .Build();
阿里云提供的依赖注入代码(autofac),很遗憾按照这个方式,并没有获取到对象
using Aliyun.Api.LogService;
using Autofac;
namespace Examples.DependencyInjection
{
  public static class AutofacExample
  {
    public static void Register(ContainerBuilder containerBuilder)
    {
      containerBuilder
        .Register(context => LogServiceClientBuilders.HttpBuilder
          // 服务入口<endpoint>及项目名<projectName>
          .Endpoint("<endpoint>", "<projectName>")
          // 访问密钥信息
          .Credential("<accessKeyId>", "<accessKey>")
          .Build())
        // `ILogServiceClient`所有成员是线程安全的,建议使用Singleton模式。
        .SingleInstance();
    }
  }
}
中间个有小插曲,由于公司使用阿里云日志比较早,也非常稳定,替换成我申请的阿里云日志的配置,发送日志一直报错,找了半天没找到原因,提了工单,原来阿里云使用了新的SDK
DSC0007.png
DSC0008.png

DSC0009.jpg

重新封装阿里云日志SDK(Aliyun.Log.Core) https://github.com/wmowm/Aliyun.Log.Core问了下群友,刚好有大佬重写过向阿里云提交日志这块,一番py交易,代码块到手,主要是数据组装,加密,发送,发送部分的代码基于http的protobuf服务实现,这里直接从阿里云开源的SDK里拷贝过来,开始重新封装,主要实现以下功能
       
  • 实现.net core DI   
  • 加入队列,让日志先入列,再提交到阿里云,提高系统吞吐量   
  • 对日志模型进行封装,满足基础业务需求
代码如下
添加ServiceCollection 拓展,定义一个阿里云日志的配置信息委托,然后将需要注入的服务注册进去即可
public static AliyunLogBuilder AddAliyunLog(this IServiceCollection services, Action<AliyunSLSOptions> setupAction)
  {
    if (setupAction == null)
    {
      throw new ArgumentNullException(nameof(setupAction));
    }
    //var options = new AliyunSLSOptions();
    //setupAction(options);
    services.Configure(setupAction);
    services.AddHttpClient();
    services.AddSingleton<AliyunSLSClient>();
    services.AddSingleton<AliyunLogClient>();
    services.AddHostedService<HostedService>();
    return new AliyunLogBuilder(services);
  }
加入队列比较简单,定义一个队列,使用HostedService 消费队列
/// <summary>
  /// 写日志
  /// </summary>
  /// <param name="log"></param>
  /// <returns></returns>
  public async Task Log(LogModel log)
  {
    AliyunLogBuilder.logQueue.Enqueue(log);
  }
/// <summary>
  /// 消费队列
  /// </summary>
  Task.Run(async () =>
  {
    using (var serviceScope = _provider.GetService<IServiceScopeFactory>().CreateScope())
    {
      var _options = serviceScope.ServiceProvider.GetRequiredService<IOptions<AliyunSLSOptions>>();
      var _client = serviceScope.ServiceProvider.GetRequiredService<AliyunSLSClient>();
      while (true)
      {
        try
        {
          if (AliyunLogBuilder.logQueue.Count>0)
          {
            var log = AliyunLogBuilder.logQueue.Dequeue();
            var logInfo = new LogInfo
            {
              Contents =
            {
              {"Topic", log.Topic.ToString()},
              {"OrderNo", log.OrderNo},
              {"ClassName", log.ClassName},
              { "Desc",log.Desc},
              { "Html",log.Html},
              { "PostDate",log.PostDate},
            },
              Time = DateTime.Parse(log.PostDate)
            };
            List<LogInfo> list = new List<LogInfo>() { logInfo };
            var logGroupInfo = new LogGroupInfo
            {
              Topic = log.Topic.ToString(),
              Source = "localhost",
              Logs = list
            };
            await _client.PostLogs(new PostLogsRequest(_options.Value.LogStoreName, logGroupInfo));
          }
          else
          {
            await Task.Delay(1000);
          }
        }
        catch (Exception ex)
        {
          await Task.Delay(1000);
        }
      }
    }
  });
定义日志模型,可以根据业务情况拓展
public class LogModel
  {
    /// <summary>
    /// 所在类
    /// </summary>
    public string ClassName { get; set; }

    /// <summary>
    /// 订单号
    /// </summary>
    public string OrderNo { get; set; }

    /// <summary>
    /// 提交时间
    /// </summary>
    public string PostDate { get; set; }

    /// <summary>
    /// 描述
    /// </summary>
    public string Desc { get; set; }

    /// <summary>
    /// 长字段描述
    /// </summary>
    public string Html { get; set; }
    /// <summary>
    /// 日志主题
    /// </summary>
    public string Topic { get; set; } = "3";
  }
使用Aliyun.Log.Core
获取Aliyun.Log.Core包
方案A. install-package Aliyun.Log.Core 
方案B. nuget包管理工具搜索 Aliyun.Log.Core
添加中间件
services.AddAliyunLog(m =>
  {
    m.AccessKey = sls.GetValue<string>("AccessKey");
    m.AccessKeyId = sls.GetValue<string>("AccessKeyId");
    m.Endpoint = sls.GetValue<string>("Host");
    m.Project = sls.GetValue<string>("Project");
    m.LogStoreName = sls.GetValue<string>("LogstoreName");
  });
写入日志
//获取对象
private readonly IOptions<SlsOptions> _options;
private readonly AliyunLogClient _aliyunLogClient;
public HomeController(IOptions<SlsOptions> options, AliyunLogClient aliyunLogClient)
{
  _options = options;
  _aliyunLogClient = aliyunLogClient;
}
[HttpGet("/api/sendlog")]
public async Task<JsonResult> SendLog(string topic="1")
{
  //日志模型
  LogModel logModel = new LogModel()
  {
    ClassName = "Aliyun.log",
    Desc = "6666666666xxxxxx",
    Html = "99999999999xxxxx",
    Topic = topic,
    OrderNo = Guid.NewGuid().ToString("N"),
    PostDate = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")
  };
  await _aliyunLogClient.Log(logModel);
  return Json("0");
}
简单的查询日志
同事写了一个查询阿里云日志的工具,非常实用,我用 .net core又抄了一遍,一并开源在github,地址: https://github.com/wmowm/Aliyun.Log.Core/tree/main/Aliyun.Log.Core.Client
DSC00010.png

推荐我自己写的一个Redis消息队列中间件InitQ,操作简单可以下载的玩玩
https://github.com/wmowm/initq
到此这篇关于.net core 使用阿里云分布式日志的文章就介绍到这了,更多相关.net core分布式日志内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

关注下面的标签,发现更多相似文章