NLog整合Exceptionless

前言

    在实际的.Net Core相关项目开发中,很多人都会把NLog作为日志框架的首选,主要是源于它的强大和它的扩展性。同时很多时候我们需要集中式的采集日志,这时候仅仅使用NLog是不够的,NLog主要是负责代码中日志的落地,也就是收集程序中的日志。类似的使用ELK(Elasticsearch+Logstash+Kibana)或EFK(Elasticsearch+Filebeat+Kibana)的集中式日志管理平台负责统一采集各个应用端通过日志框架手机的日志并统一的管理和展示。但是无论是ELK还是EFK,操作都有一定的复杂度,而且这是重型武器,有时候可能还不需要这么大的排场,这时候就需要一种轻量级的解决方案,而Exceptionless正式这种轻量级的分布式日志管理平台。

概念

可能有的同学对于Exceptionless或者是NLog还不是很了解,这里咱们就简单的介绍一下。

Exceptionless

    简单的来说Exceptionless就是一款分布式日志管理框架,它可以统一收集管理并展示出来程序的日志,这样的话减少了传统开发过程中还需要去服务器查找日志的痛苦,大大提升对程序的运维效率。接下来我们先亮出来自学三件套

  • 官网地址:https://exceptionless.com/

  • 官方文档地址:https://exceptionless.com/docs/

  • 官方Github地址:https://github.com/exceptionless/Exceptionless

目前支持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通过http接口对接的所有信息,通过它可以封装自己的sdk。

NLog

    相信很多同学对NLog已经相当熟悉了,它是一款日志框架,完美的支持.Net和.Net Core,它在.Net Core的流行度和使用广泛度完全不亚于之前的Log4Net,最重要的它功能很强大,而且扩展起来非常方便,它支持将日志输入到多种target形式,比如txt文件、Sql Server、MySQL、Redis、Mq、MongoDb、ElasticSearch等,几乎能想到的所有存储相关的组件,而且还支持过时日志打包压缩自动删除等高级功能,也是我个人非常推荐的一款日志框架,而且它可以直接对接到.Net Core Logger组件上,废话不多说自学N件套地址

  • 官方GitHub地址:https://github.com/NLog/NLog

  • 官方文档地址:https://nlog-project.org/

  • 文档地址:https://github.com/NLog/NLog/wiki

  • 配置相关地址:https://nlog-project.org/config/

NLog最大的优势就是强大,强大到你能用到的它几乎都支持,而且你想不到的它可能也支持了,而且使用起来也是非常的简单。作为日志框架,我觉得它是最值得一试的一款。

环境搭建

    上面我们已经分别介绍了Exceptionless和NLog知道了他们的概念。Exceptionless支持直接采集日志信息上报到Exceptionless,也就是原始的方式,这个官方文档上都有相关的介绍,这里咱们就不过多介绍这种方式了,使用原始方式的的时候可能会存在许多的问题,比如上报形式单一采集格式的问题等。许多时候我们是使用日志框架记录程序日志相关的,它的优势在于target丰富,而且支持自定义日志格式等等,恰恰NLog足够强大,支持直接将Log数据上报到Exceptionless,接下来我们就来看一下它们之间的整合方式。

Exceptionless搭建

官网提供了两种使用的方式

  • 一种是在官方网站注册账号然后获取apiKey,这样的话不用自己搭建Exceptionless,而是将日志直接收集上报到Exceptionless服务器上。但是,一般基于安全和性能考虑,这种方式并不常用。

  • 另一种则是自建Exceptionless服务,也是本篇我们要使用的方式。之前的低版本支持在window服务器上自建服务,但是高版本已经是基于docker的方式构建了。而使用docker的方式也是我个人日常学习中比较喜欢的方式。

官方也是提供了两种方式去基于docker构建Exceptionless,一种是基于源码自行构建,另一种则是通过官方docker镜像直接运行容器。因为Exceptionless依赖Elasticsearch存储所以官方也是也是直接提供了docker-compose的方式去运行容器。
如果使用基于源码的方式构建,首先是找到Exceptionless的官方GitHub地址https://github.com/exceptionless/Exceptionless去clone源代码,或者直接下载源码的Release包https://github.com/exceptionless/Exceptionless/releases。下载完成之后进入项目根目录找到docker-compose.dev.yml文件,文件内容如下

version: '3.7'services:#通过源码自行构建镜像app:#依赖elasticsearch和redisdepends_on:- elasticsearch- redisbuild:context: .target: appimage: exceptionless/app:latestenvironment:EX_AppMode: ProductionEX_ConnectionStrings__Cache: provider=redisEX_ConnectionStrings__Elasticsearch: server=http://elasticsearch:9200#redis的作用是消息总线、消息队列和缓存EX_ConnectionStrings__MessageBus: provider=redisEX_ConnectionStrings__Queue: provider=redisEX_ConnectionStrings__Redis: server=redis,abortConnect=falseEX_RunJobsInProcess: 'false'#暴露访问端口ports:- 5000:80- 5001:443volumes:- appdata:/app/storage- ssldata:/httpsjobs:depends_on:- appimage: exceptionless/job:latestbuild:context: .target: jobenvironment:EX_AppMode: ProductionEX_BaseURL: http://localhost:5000EX_ConnectionStrings__Cache: provider=redisEX_ConnectionStrings__Elasticsearch: server=http://elasticsearch:9200EX_ConnectionStrings__MessageBus: provider=redisEX_ConnectionStrings__Queue: provider=redisEX_ConnectionStrings__Redis: server=redis,abortConnect=falseEX_ConnectionStrings__Storage: provider=folder;path=/app/storagevolumes:- appdata:/app/storageelasticsearch:image: exceptionless/elasticsearch:7.10.0environment:discovery.type: single-nodexpack.security.enabled: 'false'ES_JAVA_OPTS: -Xms1g -Xmx1gports:- 9200:9200- 9300:9300volumes:- esdata7:/usr/share/elasticsearch/datakibana:depends_on:- elasticsearchimage: docker.elastic.co/kibana/kibana:7.10.0ports:- 5601:5601redis:image: redis:6.0-alpineports:- 6379:6379volumes:esdata7:driver: localappdata:driver: localssldata:driver: local

通过上面的docker-compose文件我们可以看出目前Exceptionless依赖elasticsearch和redis,大致可以看出Exceptionless存储是依赖elasticsearch,而提升性能的则是redis,比如消息总线防止并发的缓冲队列都是依赖redis的,具体实现细节我们这里就不做过多套路了。因为使用dev的方式构建镜像的方式依赖Exceptionless源码,所以不建议移动该docker-compose文件位置,使用docker-compose的指令直接运行该文件

docker-compose -f docker-compose.dev.yml up

上面的方式虽然可以直接依靠源码去构建,但是其实大可不必这么复杂比如kibana这种完全就是多余的,而且他的这种方式是依赖源码的,生产环境我们不可能把代码直接copy过去,所以我们需要精简一下,如下所示

version: '3.7'services:app:depends_on:- elasticsearch- redisimage: exceptionless/exceptionless:latestenvironment:EX_AppMode: ProductionEX_ConnectionStrings__Cache: provider=redisEX_ConnectionStrings__Elasticsearch: server=http://elasticsearch:9200EX_ConnectionStrings__MessageBus: provider=redisEX_ConnectionStrings__Queue: provider=redisEX_ConnectionStrings__Redis: server=redis:6379,abortConnect=falseEX_RunJobsInProcess: 'false'ports:- 5000:80volumes:- appdata:/app/storagejobs:depends_on:- appimage: exceptionless/job:latestenvironment:EX_AppMode: ProductionEX_BaseURL: http://localhost:5000EX_ConnectionStrings__Cache: provider=redisEX_ConnectionStrings__Elasticsearch: server=http://elasticsearch:9200EX_ConnectionStrings__MessageBus: provider=redisEX_ConnectionStrings__Queue: provider=redisEX_ConnectionStrings__Redis: server=redis:6379,abortConnect=falseEX_ConnectionStrings__Storage: provider=folder;path=/app/storagevolumes:- appdata:/app/storageelasticsearch:image: exceptionless/elasticsearch:7.10.0environment:discovery.type: single-nodexpack.security.enabled: 'false'xpack.ml.enabled: 'false'ES_JAVA_OPTS: -Xms1g -Xmx1gports:- 9200:9200- 9300:9300volumes:- esdata7:/usr/share/elasticsearch/dataredis:image: redis:6.0-alpineports:- 6379:6379volumes:esdata7:driver: localappdata:driver: local

将上面的yml内容直接复制到一个新建的docker-compose.yml的空文件中就可以直运行了,无任何额外的依赖,在yml文件所在路径直接运行以下命令

docker-compose up -d

如果你的服务器已经拥有了elasticsearch和redis服务,也就是不需要使用以上docker-compose的方式进行构建,那么可以直接使用官方docker镜像的方式直接启动Exceptionless容器,可以使用docker原生的方式直接运行

sudo docker run -d -e EX_AppMode=Production -e EX_ConnectionStrings__Cache="provider=redis" -e EX_ConnectionStrings__Elasticsearch="server=http://10.255.198.168:9200" -e EX_ConnectionStrings__MessageBus="provider=redis" -e EX_ConnectionStrings__Queue="provider=redis" -e EX_ConnectionStrings__Redis="server=10.255.198.168:6379,abortConnect=false" -e EX_RunJobsInProcess=false -e EX_Html5Mode=true -p 5000:80 exceptionless/exceptionless:latest

这里注意修改下相关服务的ip地址,因为我粘贴的是我本机的地址,而且注意elasticsearch的版本必须是7.x版本的,否则的话会报错。程序启动完成后再浏览器输输入http://ip:5000后会自动跳转到登录界面如果没有登录账户需要注册一个新的用户后,登录到首页如图所示因为Exceptionless每个项目的日志信息是根据apiKey去区分的,所以要在Exceptionless中添加你需要采集日志的项目,具体操作如以下步骤

  • 首先,点击所有项目--->创建项目

  • 然后,输入组织名称和项目名称

  • 然后,选择项目类型,这里以Asp.Net Core程序为例

  • 完成之后,点击项目管理,这里的API秘钥正是我们上传到Exceptionless服务所需要的凭证

到了这一步Exceptionless搭建基本上就完成了。

集成NLog

新建一个名叫ProductApi的Asp.Net Core的项目,项目名称任意。然后添加Exceptionless.NLog包,这个包就是将NLog数据上报到Exceptionless的包

<PackageReference Include="Exceptionless.NLog" Version="4.6.2" />
<PackageReference Include="NLog.Web.AspNetCore" Version="4.10.0" />

Exceptionless.NLog的Github项目地址位于https://github.com/exceptionless/Exceptionless.Net/tree/master/src/Platforms/Exceptionless.NLog这个地址相当隐蔽不太容易被发现,而且说明文档也是很低调几乎没啥内容,可能是觉得NLog的文档写的太完善了,不用多说大家就能知道怎么用。添加完nuget包引用之后,修改Program.cs程序添加NLog的Logging扩展。仅仅添加UseNLog即可,因为我们使用了NLog.Web.AspNetCore扩展包,所以NLog会集成到Asp.Net Core自带的Microsoft.Extensions.Logging中去,不得不说.Net Core的整体扩展性还是非常强的,这样的话我们可以设置默认的Logging的配置即可,几乎感知不到NLog的存在

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

接下来需要在项目根目录中新建nlog.config用来配置nlog相关信息,新建完成之后添加以下配置

<?xml version="1.0" encoding="utf-8" ?>
<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"throwExceptions="true" internalLogFile="internal-nlog.log" internalLogLevel="Debug" ><extensions><!--添加扩展Exceptionless程序集--><add assembly="Exceptionless.NLog"/></extensions><targets async="true"><!--写入本地文件--><target name="File" xsi:type="File" fileName="${basedir}/logs/${shortdate}.log"layout=" ${longdate}|${event-properties:item=EventId_Id:whenEmpty=0}|${uppercase:${level}}|${logger}|${message} ${exception:format=tostring}|url: ${aspnet-request-url}|action: ${aspnet-mvc-action}| ${newline}" ></target><!--上报Exceptionless--><!--xsi:type:固定是Exceptionless--><!--apiKey:即我们在Exceptionless中添加完项目后得到的apiKey--><!--serverUrl:Exceptionless的地址--><target xsi:type="Exceptionless" name="Exceptionless" apiKey="d66B6fXD6sz3kAuqdc5Fe04td7iIygunkDa5GoUt"serverUrl="http://10.255.52.93:5000/"><!--堆栈信息--><field name="StackTrace" layout="${stacktrace}"/><!--Message信息--><field name="Message" layout="${message}"/><field name="LogLevel" layout="${level}"/><field name="CreateDate" layout="${date}"/><!--物理名称--><field name="MachineName" layout="${machinename}" /><!--线程ID--><field name="ThreadId" layout="${threadid}"/><!--发生源--><field name="CallSite" layout="${callsite}"/><field name="AppdomainVersion" layout="${assembly-version}"/><field name="Appdomain" layout="${appdomain}"/> </target></targets><rules><!--本地文件--><logger name="*" writeTo="File"/><!--上报Exceptionless--><logger name='*' writeTo='Exceptionless'/></rules>
</nlog>

新建完nlog.config之后不要忘了将右击该文件 属性--->复制到输出路径--->始终复制,或修改该项目的csproj文件添加

<ItemGroup><Content Update="nlog.config"><CopyToOutputDirectory>Always</CopyToOutputDirectory></Content>
</ItemGroup>

到这里为止关于NLog整合Exceptionless的环境搭建就已经完成了,是不是非常的简单,抛开环境搭建工作量其实并不大,这一切都是源于.Net Core的强大和它那灵活的可扩展性。

简单测试一下

通过上面的操作我们已经把NLog整合Exceptionless的环境搭建起来了,接下来我们随便写点代码测试一波随便建个类,就是为了演示异常,代码无任何实质意义,不喜勿喷。。。,这里我是模拟了一个ApiController抛出异常,然后用Logger记录了信息

[Route("productapi/[controller]")]
public class ProductController : ControllerBase
{private readonly ILogger _logger;public ProductController(ILogger<ProductController> logger){_logger = logger;}[HttpGet("exceptiontest")]public string ExceptionTest(){try{throw new Exception("发生了未知的异常");}catch (Exception ex){_logger.LogError(ex,$"{HttpContext.Connection.RemoteIpAddress}调用了productapi/product/exceptiontest接口返回了失败");}return "调用失败";}
}

运行起来项目调用一下这段代码之后,查看Exceptionless,如果环境配置啥的都是正确的话,会展示出一下效果,点击All菜单展示出来的信息会比较全可以点击查看详情,详情信息记录的非常详细,不得不说Exceptionless还是非常强大非常人性非常实用的还能查看更详细的信息到这里为止,关于NLog整合Exceptionless的操作就全部完成了,感叹一句就是不仅简单而且强大。

总结

    通过本次整合NLog和Exceptionless,我们既感受到Exceptionless的简单和强大,也感受到了NLog的扩展性之强,希望更多地人能够尝试一下NLog。这一切还是得益于.Net Core自身的扩展性,特别是它内置的一些抽象,完全成为了构建.Net Core程序的核心,而且基于这些内置的核心抽象操作可以很轻松的扩展许多操作,使得模块之间的耦合性变得非常低,而这种设计的思想才是我们真正在编程中应该学习的。

????欢迎扫码关注我的公众号????

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/304667.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

40个只有程序员才看得懂的段子

1. 一程序员去面试&#xff0c;面试官问&#xff1a;“你毕业才两年&#xff0c;这三年工作经验是怎么来的&#xff1f;&#xff01;”程序员答&#xff1a;“加班。”2. 某程序员对书法十分感兴趣&#xff0c;退休后决定在这方面有所建树。于是花重金购买了上等的文房四宝。一…

bra型手机链

左看看&#xff0c;右瞧瞧&#xff0c;真不敢相信这个居然是手机链&#xff1f;带上它出门&#xff0c;回头率一定很高哦&#xff01;就是有点贵&#xff0c;70元&#xff01;转载于:https://blog.51cto.com/laizhngn5376/180850

MySQL8的inodb参数设置_MySQL8.0自适应参数innodb_dedicated_server

MySQL8.0有了一个新参数又叫自适应参数 innodb_dedicated_server将innodb_dedicated_server开启的时候&#xff0c;它可以自动的调整下面这四个参数的值&#xff1a;innodb_buffer_pool_size 总内存大小innodb_log_file_size redo文件大小innodb_log_files_in_group redo文件数…

让 gRPC 提供 REST 服务

让 gRPC 提供 REST 服务IntrogRPC 是一个高性能、开源和通用的 RPC 框架&#xff0c;面向移动和 HTTP/2 设计。gRPC 基于 HTTP/2 标准设计&#xff0c;带来诸如双向流、流控、头部压缩、单 TCP 连接上的多复用请求等特。这些特性使得其在移动设备上表现更好&#xff0c;更省电…

python提取cad坐标到excel_使用python来操作autocad,并且将坐标点转换成cad可见对象...

由于工作需要&#xff0c;在项目中遇到一个棘手的问题&#xff0c;如何将(mssql)数据库中的BLOB文件转成cad可见图形(可能每个项目需求不一样&#xff0c;解决方式不同)第一步 . 需要转换的图形类型第二步 . 那我们先查询这个字段第三步 试试将这个写入一个文本中 看看是那种图…

10张图看懂瞎忙和高效的区别

时间是最公平的&#xff0c;每个人一天都是24小时&#xff0c;一年都是365天。但是&#xff0c;不同的人的产出却是天差地别。人和人的差距为什么这么大&#xff1f;而且这种差距&#xff0c;并不是家庭背景、权利财富或天赋带来的&#xff0c;仅仅是我们对时间的掌控。正好看到…

pc模式 华为mate30_华为mate30与电脑连不上怎么回事

大家好&#xff0c;我是时间财富网智能客服时间君&#xff0c;上述问题将由我为大家进行解答。系统版本为EMUI 10.1&#xff0c;华为mate30与电脑连不上的原因&#xff1a;1、可能是USB线连接不正常。建议更换数据线试试。2、确认电脑上的手机USB 驱动已经安装成功&#xff0c;…

ASP.NET Core 中的配置

背景ASP.NET Core 提供了一个灵活可扩展,基于键值的配置系统. 但是配置系统独立于ASP.NET Core是Microsoft.Extensions 类库的部分. 它可以用于任何类型的应用程序。1、以键-值对的形式读取配置appsettings.json 文件&#xff1a;{"Position": {"Title": &…

Canvas的save和restore

在创建新的控件或修改现有的控件时&#xff0c;我们都会涉及到重写控件或View的onDraw方法。 onDraw方法会传入一个Canvas对象&#xff0c;它是你用来绘制控件视觉界面的画布。 在onDraw方法里&#xff0c;我们经常会看到调用save和restore方法&#xff0c;它们到底是干什么用的…

vs code python 插件_工具篇-vscode效率提升插件

工欲善其事必先利其器&#xff0c;开发前先把所以提升效率的利器搭好会让今后慢慢的编程长路舒服很多&#xff0c;我本来一直用pycharm&#xff0c;后来发现vscode貌似确实会好很多。。。就慢慢转过来了&#xff0c;下面介绍一些我在机器学习编程时经常会用到的一些插件。1. au…

鉴别一个人是否 js 入门的标准竟然是?!

不知不觉跳入前端「大坑」也已经有大半年了&#xff0c;学到了很多知识。为了让知识更好地沉淀&#xff0c;我打算写一系列的知识总结&#xff0c;希望能在回顾知识的同时也能帮到别的同学。忘记在哪里看到过&#xff0c;有人说鉴别一个人是否 js 入门的标准就是看他有没有理解…

面向对象编程设计模式--简单工厂模式讲解(历史上最简单明白的例子)

工作之余&#xff0c;在看资料过程中发现一个极易理解的简单工厂模式的例子&#xff0c;自己亲自试练一番,感觉对这个设计模式不熟悉的朋友&#xff0c;一看马上就知道是什么回事了。 简单工厂模式根据提供给它的数据&#xff0c;返回几个可能类中的一个类的实例。通常它返的类…

.NET 6 Preview 1 开箱,带你体验新版本

最近 .NET 6 Preview 1 发布了&#xff0c;.NET 统一是此版本的核心。大家可以读一下原文博客&#xff1a;https://devblogs.microsoft.com/dotnet/announcing-net-6-preview-1/.NET 6.0 SDK 和 Runtime 下载地址&#xff1a;https://dotnet.microsoft.com/download/dotnet/6.0…

redis 清空缓存_「镜头回放」简直了!spring中清除redis缓存导致应用挂死

异常场景springWeb应用一直运行正常&#xff0c;同事最近反应&#xff0c;每次版本更新完毕&#xff0c;刷新缓存&#xff0c;就会导致应用挂死。只有重启redis应用才恢复正常。项目概况springWeb项目&#xff0c;常用配置表做了redis缓存&#xff0c;配置表中只有少量数据&…

25岁社招进阿里,从电商到有赞新零售,他仅1年就打开了马云一直想做的新领域!

最近关于「新零售」的声音此起彼伏&#xff1a;阿里巨资收购高鑫零售&#xff0c;腾讯确认入股永辉超市……自2016年10月马云第一次提出了「新零售」概念之后&#xff0c;各巨头跑马圈地&#xff0c;线下成为了必争之地&#xff0c;新零售的蓝海才刚刚打开。而李星&#xff0c;…

优美的测试代码 - 行为驱动开发(BDD)

可理解的代码非常重要&#xff0c;测试代码也是如此。在我看来&#xff0c;优秀的测试代码&#xff0c;必须做到一个重要的事情就是保持测试逻辑的清晰。一个完整的测试案例通常包括三个部分&#xff1a;1. SetUp2. Exercise3. Verifiy4. TearDown一 个测试案例如果能清晰的区分…

C#连接MySQL数据库实例

项目目的&#xff1a;连接mysql查询数据并将数据显示到界面的datagridview里面.Step1:添加动态链接库文件Visual Studio,在 项目(右键)-管理NuGet程序包(N) 然后在浏览里面搜索MySql.Data并进行安装。Step2&#xff1a;using所需要的库using MySql.Data.MySqlClient;step3&…

java字符串比大小_Java字符串比较(3种方法)

字符串比较是常见的操作&#xff0c;包括比较相等、比较大小、比较前缀和后缀串等。在 Java 中&#xff0c;比较字符串的常用方法有 3 个&#xff1a;equals() 方法、equalsIgnoreCase() 方法、 compareTo() 方法。下面详细介绍这 3 个方法的使用。equals() 方法equals() 方法将…

链接服务器 慢_redis服务器cpu100%的原因和解决方案

首先引起cpu100%可能的几大原因&#xff1a;1.redis连接数过高2.数据持久化导致的阻塞3.主从存在频繁全量同步4.value值过大5.redis慢查询为了模拟redis服务器cpu100%&#xff0c;临时买了一台阿里云ecs&#xff0c;并把那天清空前的redis备份还原到服务器上。下面我们按照顺序…

有人问我:AI这么火,要不要去追赶AI的热潮?

12月14日&#xff0c;吴恩达发布微博&#xff1a;我很高兴地宣布Landing.ai的成立&#xff0c;开始进入AI产业。 作为一家人工智能&#xff08;AI&#xff09;公司&#xff0c;Landing.ai旨在帮助企业在人工智能时代实现转型。这一动作让人们对AI的关注度在2017年的末尾又一次升…