ASP .NET Core 集成 Exceptionless 日誌

Exceptionless簡介

Exceptionless是一款分佈式日誌管理框架,它可以統一收集管理並展示出來程序的日誌,這樣的話減少了傳統開發過程中還需要去服務器查找日誌的痛苦,大大提升對程序的運維效率。 Exceptionless依賴於Redis和Elasticsearch。

官網地址:https://exceptionless.com/
官方文檔地址:https://exceptionless.com/docs/
官方Github地址:https://github.com/exceptionless/Exceptionless
Docker鏡像地址:https://hub.docker.com/r/exceptionless/exceptionless
日誌搜索文檔:https://exceptionless.com/docs/filtering-and-searching

目前支持JavaScript, Node, .NET Core, .NET相關應用程序的異常信息採集。爲何僅支持.Net .Net Core和JS相關的?原因很簡單,Exceptionless是基於.NET Core開發的。如果你有別的語言的開發需求也想使用Exceptionless,這個時候不要氣餒,因爲Exceptionless本質是基於http接口的形式上報數據的,這個可在官方文檔上找到如何使用http上報日誌信息相關

官方文檔api地址:https://exceptionless.com/docs/api/api-getting-started/
api官方文檔地址:https://api.exceptionless.io/
api官方swagger地址:https://api.exceptionless.io/docs/index.html

部署Exceptionless

官網提供了兩種使用的方式

  • 在官方網站註冊賬號然後獲取apiKey,這樣的話不用自己搭建Exceptionless,而是將日誌直接收集上報到Exceptionless服務器上。但是,一般基於安全和性能考慮,這種方式並不常用。
  • 自建Exceptionless服務,也是本篇我們要使用的方式。之前的低版本支持在window服務器上自建服務,但是高版本已經是基於docker的方式構建了。而使用docker的方式也是我個人日常學習中比較喜歡的方式。

基於docker-compose部署。官方yml文件地址

https://github.com/exceptionless/Exceptionless/blob/main/docker-compose.yml
https://github.com/exceptionless/Exceptionless/blob/main/samples/docker-compose.yml

簡化版docker-compose.yml

version: '3.7'

services:
  app:
    depends_on:
      - elasticsearch
    image: exceptionless/app:7.2.1
    environment:
      EX_AppMode: Production
      EX_ConnectionStrings__Cache: provider=redis
      EX_ConnectionStrings__Elasticsearch: server=http://elasticsearch:9200
      EX_ConnectionStrings__MessageBus: provider=redis
      EX_ConnectionStrings__Queue: provider=redis
      EX_ConnectionStrings__Redis: server=192.168.1.5:6379,abortConnect=false
      EX_RunJobsInProcess: 'false'
    ports:
      - 5000:80
    volumes:
      - appdata:/app/storage

  jobs:
    depends_on:
      - app
    image: exceptionless/job:7.2.1
    environment:
      EX_AppMode: Production
      EX_BaseURL: http://192.168.1.5:5000
      EX_ConnectionStrings__Cache: provider=redis
      EX_ConnectionStrings__Elasticsearch: server=http://elasticsearch:9200
      EX_ConnectionStrings__MessageBus: provider=redis
      EX_ConnectionStrings__Queue: provider=redis
      EX_ConnectionStrings__Redis: server=192.168.1.5:6379,abortConnect=false
      EX_ConnectionStrings__Storage: provider=folder;path=/app/storage
    volumes:
      - appdata:/app/storage

  elasticsearch:
    image: exceptionless/elasticsearch:7.15.2
    environment:
      discovery.type: single-node
      xpack.security.enabled: 'false'
      xpack.ml.enabled: 'false'
      ES_JAVA_OPTS: -Xms1g -Xmx1g
    ports:
      - 9200:9200
      - 9300:9300
    volumes:
      - esdata7:/usr/share/elasticsearch/data

volumes:
  esdata7:
    driver: local
  appdata:
    driver: local

yml下載到服務器後直接docker-compose up -d啓動站點

Exceptionless 使用

訪問站點http://192.168.1.5:5000/,首次登陸使用註冊郵箱賬號

註冊成功後登陸就可以看到主界面了

新建一個組織

組織中新建一個項目,項目與組織綁定關係是爲了後續組織邀請其他用戶方便管理查看日誌


輸入項目名稱

項目類型選擇ASP.NET Core,然後選擇管理項目

進入項目詳情,選擇API祕鑰,在ASP.NET Core項目中需要此祕鑰配置

ASP .NET Core 集成 Exceptionless

appsettings.json添加Exceptionless配置

"Exceptionless": {
    "ServerUrl": "http://192.168.1.5:5000",
    "ApiKey": "2oWkeKEw0gKqb4gu2vsMvr4b3mK1V47fshjaYyJ2"
}

使用官方包集成

Neget安裝包

Exceptionless.AspNetCore

Startup.cs添加配置

services.AddExceptionless(Configuration);
//或者
//ExceptionlessClient.Default.Configuration.ApiKey = Configuration["ExceptionLess:ApiKey"];
//ExceptionlessClient.Default.Configuration.ServerUrl = Configuration["ExceptionLess:ServerUrl"];

services.AddSingleton<ILogger, ExceptionLessLogger>();

app.UseExceptionless();

添加日誌

ExceptionlessClient.Default.CreateLog("GUID", LogLevel.Warn).AddTags("tag").Submit();

擴展類

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Exceptionless;
using Exceptionless.Logging;

namespace ExceptionlessDemo
{

    public static class Extensions
    {
        /// <summary>
        /// 跟蹤
        /// </summary>
        public static void TraceExceptionless(this Microsoft.Extensions.Logging.ILogger log, string message, params string[] tags)
        {
            ExceptionlessClient.Default.CreateLog(message, LogLevel.Trace).AddTags(tags).Submit();
        }

        /// <summary>
        /// 信息
        /// </summary>
        public static void InfoExceptionless(this ILogger log, string message, params string[] tags)
        {
            ExceptionlessClient.Default.CreateLog(message, LogLevel.Info).AddTags(tags).Submit();
        }

        /// <summary>
        /// 警告
        /// </summary>
        public static void WarnExceptionless(this Microsoft.Extensions.Logging.ILogger log, string message, params string[] tags)
        {
            ExceptionlessClient.Default.CreateLog(message, LogLevel.Warn).AddTags(tags).Submit();
        }

        /// <summary>
        /// 錯誤
        /// </summary>
        public static void ErrorExceptionless(this ILogger log, string message, params string[] tags)
        {
            ExceptionlessClient.Default.CreateLog(message, LogLevel.Error).AddTags(tags).Submit();
        }

        /// <summary>
        /// 錯誤
        /// </summary>
        public static void ErrorExceptionless(this Microsoft.Extensions.Logging.ILogger log, Exception exception, params string[] tags)
        {
            ExceptionlessClient.Default.CreateException(exception).AddTags(tags).Submit();
        }
    }


    public interface ILogger
    {
        void Trace(string message, params string[] args);
        void Debug(string message, params string[] args);
        void Info(string message, params string[] args);
        void Warn(string message, params string[] args);
        void Error(string message, params string[] args);
        void Error(Exception ex, params string[] args);
    }

    public class ExceptionLessLogger : ILogger
    {
        /// <summary>
        /// Trace
        /// </summary>
        public void Trace(string message, params string[] tags)
        {
            ExceptionlessClient.Default.CreateLog(message, LogLevel.Trace).AddTags(tags).Submit();
        }

        /// <summary>
        /// Debug
        /// </summary>
        public void Debug(string message, params string[] tags)
        {
            ExceptionlessClient.Default.CreateLog(message, LogLevel.Debug).AddTags(tags).Submit();
        }

        /// <summary>
        /// Info
        /// </summary>
        public void Info(string message, params string[] tags)
        {
            ExceptionlessClient.Default.CreateLog(message, LogLevel.Info).AddTags(tags).Submit();
        }

        /// <summary>
        /// Warn
        /// </summary>
        public void Warn(string message, params string[] tags)
        {
            ExceptionlessClient.Default.CreateLog(message, LogLevel.Warn).AddTags(tags).Submit();
        }

        /// <summary>
        /// Error
        /// </summary>
        public void Error(string message, params string[] tags)
        {
            ExceptionlessClient.Default.CreateLog(message, LogLevel.Error).AddTags(tags).Submit();
        }

        /// <summary>
        /// 錯誤
        /// </summary>
        public void Error(Exception exception, params string[] tags)
        {
            ExceptionlessClient.Default.CreateException(exception).AddTags(tags).Submit();
        }
    }
    //日誌Tags
    public static class LogTags
    {
        public const string LogTag = "TestProjectLogTag";
    }
}

Controllers發送日誌

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

namespace ExceptionlessDemo.Controllers
{
    [ApiController]
    [Route("[controller]")]
    public class WeatherForecastController : ControllerBase
    {
        //建議使用 _logger2
        public ILogger<WeatherForecastController> Logger { get; set; }
        private readonly ILogger _logger2;
        public WeatherForecastController(ILogger<WeatherForecastController> logger, ILogger logger2)
        {
            _logger2 = logger2;
            Logger = logger;
            //Logger = NullLogger<WeatherForecastController>.Instance;
        }

        [HttpGet]
        public string Get()
        {
            Logger.WarnExceptionless("微軟日誌擴展", "LogInformation");
            _logger2.Debug("12321321", "Debug1");

            return Guid.NewGuid().ToString();
        }
    }
}

使用Serilog集成

Neget安裝包

Serilog.AspNetCore
Serilog.Sinks.Exceptionless

Program.cs添加配置

using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Hosting;
using Serilog;
using Serilog.Events;
using System.Text;

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

        public static IHostBuilder CreateHostBuilder(string[] args) =>
            Host.CreateDefaultBuilder(args)
                .ConfigureWebHostDefaults(webBuilder =>
                {
                    webBuilder.UseStartup<Startup>();
                })
                .UseSerilog(ConfigureSerilog);

        static void ConfigureSerilog(HostBuilderContext context, LoggerConfiguration logger)
        {
            var apiKey = context.Configuration["ExceptionLess:ApiKey"];
            var serverUrl = context.Configuration["ExceptionLess:ServerUrl"];

            logger
                .MinimumLevel.Information()
                .MinimumLevel.Override("Microsoft", LogEventLevel.Warning)
                .MinimumLevel.Override("Microsoft.EntityFrameworkCore", LogEventLevel.Warning)
                .Enrich.FromLogContext()
                //添加Exceptionless
                .WriteTo.Exceptionless(apiKey, serverUrl);
        }
    }
}

查看日誌

參考文檔

https://www.cnblogs.com/wucy/p/14401650.html
https://www.dongchuanmin.com/net/3230.html
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章