本文是Util应用框架日志记录的第四篇,介绍安装和写入 Exceptionless 日志系统的配置方法.

Exceptionless 是一个日志管理系统,使用 Asp.Net Core 开发,比 Seq 的模糊搜索能力弱,使用它可能需要一些技巧.

Util应用框架目前主要使用 SeqExceptionless 管理日志.

你可以从中选择一个合适的.

本节介绍使用 Docker 简单安装 Exceptionless,用于开发测试,部署到生产环境请参考官方文档.

安装 Exceptionless

创建 exceptionless-data 卷, 运行命令.

docker volume create exceptionless-data

创建 Exceptionless 容器, 运行命令.

docker run --name exceptionless -d --restart=always -v exceptionless-data:/usr/share/elasticsearch/data -p 5480:80 exceptionless/exceptionless:8.0.0-elasticsearch7

容器名称: exceptionless

连接端口: 5480

安装成功后,Docker容器列表出现 exceptionless 容器.

运行 Exceptionless

打开 http://localhost:5480 ,可以看到 Exceptionless 管理界面.

Exceptionless 启动需要一些时间,请稍后刷新页面.

如果 Exceptionless 持续无法启动,请删除 exceptionless-data 卷,并重新安装.

创建 Exceptionless 用户

点击 Signup 按钮进入注册页面.

使用下面的信息注册,或按你自己的喜好设置.

名称: admin

邮箱: admin@a.com

密码: admin123

点击创建我的帐户按钮,进入管理界面.

创建 Exceptionless 项目

填写组织名称,范例: Util

填写项目名称,范例: Demo

点击创建项目按钮.

选择顶部菜单的所有项目 ,点击Demo项目设置按钮.

在 Demo 项目设置界面,选择 API密钥 选项卡.

项目开发时,配置以下信息将日志写入 Exceptionless.

API密钥: 复制你的API密钥,如上图所示.

Exceptionless服务地址: http://localhost:5480

日志配置

  • 引用Nuget包

    Nuget包名: Util.Logging.Serilog.Exceptionless

  • AddExceptionless

    使用 AddExceptionless 扩展方法启用 Exceptionless 日志操作.

    • 默认不带参数,你可以在配置文件中指定 Exceptionless 的配置信息.

      var builder = WebApplication.CreateBuilder( args );
      builder.AsBuild().AddExceptionless();
    • 如果要清除默认设置的日志提供程序,传入 true.

      Asp.Net Core 默认日志提供程序会把消息输出到控制台,你可以清除它们.

      builder.AsBuild().AddExceptionless( true );
    • 设置应用程序名称.

      对于微服务应用,记录产生日志的应用名称,能方便排查问题.

      builder.AsBuild().AddExceptionless( "权限服务" );
    • 指定Api密钥和服务地址.

      builder.AsBuild().AddExceptionless( t => {
      t.ApiKey = "";
      t.ServerUrl = "";
      } );

      指定Api密钥和服务地址并清除默认设置的日志提供程序.

      builder.AsBuild().AddExceptionless( t => {
      t.ApiKey = "";
      t.ServerUrl = "";
      }, true );
  • 添加 appsettings 配置节

    appsettings.json 配置文件添加 Exceptionless 配置节.

    {
    "Logging": {
    "LogLevel": {
    "Default": "Trace"
    }
    },
    "Exceptionless": {
    "ApiKey": "8JtknZBV1NRC7bdsv6SF5cbBFrMZipWMkARZxkxo",
    "ServerUrl": "http://localhost:5480"
    }
    }

    ApiKey 指定 API 密钥.

    ServerUrl 指定 Exceptionless 服务地址.

    最简化配置仅需设置 API 密钥和 Exceptionless 服务地址.

    本教程 Exceptionless 安装示例使用 5480 端口.

    API 密钥替换成你自己的.

    其它参数请参考 Exceptionless 文档.

查看 Exceptionless

配置完成后,可以启动你的项目,查看 Exceptionless 日志界面.

可以看到由 Asp.Net Core 写入的系统日志.

结构化日志支持

下面的示例比较结构化日志与普通日志的差别.

范例使用 ILog 接口写入日志,你也可以使用 ILogger 替代.

先记录普通日志消息,方便后续比较.

_log.Message( "用户admin已删除" ).LogInformation();

查看扩展属性.

结构化日志语法

  • {}

    • {} 用来定义日志属性.

    • 范例:

      _log.Message( "用户{User}已删除", "admin" ).LogInformation();

      {User} 定义了名为 User 的字符串属性.

      查看 Exceptionless 扩展属性界面, 可以看到已经添加了 User 属性.

      识别出了 User 属性,就可以使用它进行搜索.

      搜索框输入下面的表达式.

      data.User:"admin"

      User 是一个扩展属性,Exceptionless 要求扩展属性前加上 data.

      属性名与属性值使用 : 分隔,表示相等,即 属性名=属性值 .

      字符串值可以放进双引号中,比如 "admin"

      字符串值也可不带双引号,比如 admin.

      但是不能放在单引号中, 比如 'admin' .

      Exceptionless 的模糊匹配能力有限,只支持头匹配,类似 like 'xx%' ,不能完全模糊搜索.

      Exceptionless 使用 * 进行模糊匹配,只能放在参数值右方, 比如 adm* .

      带 * 的参数值不能放在双引号中 .

      范例:

      以 adm 开头模糊搜索 User 扩展属性.

      data.User:adm*

      注意: 不要将结构化日志 {} 与 .Net 字符串语法 $"{}" 混淆.

      var user = "admin";
      _log.Message( $"用户{user}已删除" ).LogInformation();

      $"" 中的 {user} 将被 user 变量值 'admin' 替换, 等效于.

      _log.Message( "用户admin已删除" ).LogInformation();

      它仅是普通日志消息,不是结构化日志.

    • {@} 用来定义日志属性,并强制序列化对象.

      前面的示例使用简单的字符串参数,如果传入对象参数是什么结果?

    • 范例:

      定义 User 对象.

      namespace Demo;
      
      public class User {
      public int Id { get; set; }
      public string Name { get; set; }
      }

      现在传入 User 对象.

      var user = new User { Id = 1, Name = "a" };
      _log.Message( "用户{User}已删除", user ).LogInformation();

      {User} 被替换为字符串 "Demo.User" ,这是通过调用 User 对象的 ToString() 方法得到的.

      这与我们的预期不符合,我们希望序列化 User 对象,从而获取对象的结构进行搜索.

      Serilog 对 {} 参数的处理有一套内置规则,如果传入对象,有些结构能序列化,比如字典 Dictionary<string,int> ,有些则不能.

      不应该依赖 Serilog 自动序列化的能力,而是应明确指定是否序列化.

      {@} 强制序列化对象,从而保留对象结构,以方便日志系统展示和搜索.

      var user = new User { Id = 1, Name = "a" };
      _log.Message( "用户{@User}已删除", user ).LogInformation();

      遗憾的是, Exceptionless 无法搜索对象属性.

      虽然 Exceptionless 对扩展属性的搜索支持有限,但它内置了很多搜索语法,可以参考官方文档.

    • {$} 用来定义日志属性,并强制字符串化.

      {$} 让 Serilog 以明确的方式显示对象的字符串表示.

      var user = new User { Id = 1, Name = "a" };
      _log.Message( "用户{$User}已删除", user ).LogInformation();

      {$User} 调用user对象的 ToString() 方法显示为字符串.

Util应用框架基础(六) - 日志记录(四) - 写入 Exceptionless的更多相关文章

  1. 从零开始编写自己的C#框架(20)——框架异常处理及日志记录

    最近很忙,杂事也多,所以开发本框架也是断断续续的,终于在前两天将前面设定的功能都基本完成了,剩下一些小功能遗漏的以后发现再补上.接下来的章节主要都是讲解在本框架的基础上进行开发的小巧. 本框架主要有四 ...

  2. [编程基础] Python日志记录库logging总结

    Python日志记录教程展示了如何使用日志记录模块在Python中进行日志记录. 文章目录 1 介绍 1.1 背景 1.2 Python日志记录模块 1.3 根记录器 2 Python logging ...

  3. Android WiFi 日志记录(四次握手)

    记录一下四次握手的log. PMK: PMK(Pairwise Master Key,成对主密钥 STA和AP得到PMK后,将进行密匙派生以得到PTK.最后,PTK被设置到硬件中, 用于数据的加解密. ...

  4. Gin 框架 - 使用 logrus 进行日志记录

    目录 概述 日志格式 Logrus 使用 推荐阅读 概述 上篇文章分享了 Gin 框架的路由配置,这篇文章分享日志记录. 查了很多资料,Go 的日志记录用的最多的还是 github.com/sirup ...

  5. 在android中配置 slf4j + log4j 日志记录框架

    需求: 在项目开发中,需要记录 操作日志 .起初自己写了个简单的日志记录文本写入到文本的方法,后来随着项目的膨胀,需要考虑更多的操作,开始考虑性能问题. 实现: 考虑使用 slf4j + log4j ...

  6. slf4j+log4j在Java中实现日志记录

    小Alan今天来跟大家聊聊开发中既简单又常用但必不可少的一样东西,那是什么呢?那就是日志记录,日志输出,日志保存. 后面就统一用日志记录四个字来形容啦. 日志记录是项目的开发中必不可少的一个环节,特别 ...

  7. PHP框架中的日志系统

    现在在一家公司做PHP后台开发程序猿(我们组没有前端,做活动时会做前端的东西),刚开始到公司的时候花2个周赶出了一个前端加后台的活动(记得当时做不出来周末加了两天班...),到现在过去4个多月了,可以 ...

  8. Asp.Net Core 2.0 项目实战(9) 日志记录,基于Nlog或Microsoft.Extensions.Logging的实现及调用实例

    本文目录 1. Net下日志记录 2. NLog的使用     2.1 添加nuget引用NLog.Web.AspNetCore     2.2 配置文件设置     2.3 依赖配置及调用     ...

  9. 如何定制.NET6.0的日志记录

    在本章中,也就是整个系列的第一部分将介绍如何定制日志记录.默认日志记录仅写入控制台或调试窗口,这在大多数情况下都很好,但有时需要写入到文件或数据库,或者,您可能希望扩展日志记录的其他信息.在这些情况下 ...

  10. 《手把手教你》系列基础篇(八十四)-java+ selenium自动化测试-框架设计基础-TestNG日志-上篇(详解教程)

    1.简介 TestNG还为我们提供了测试的记录功能-日志.例如,在运行测试用例期间,用户希望在控制台中记录一些信息.信息可以是任何细节取决于目的.牢记我们正在使用Selenium进行测试,我们需要有助 ...

随机推荐

  1. Asp.Net MVC中Action跳转小结(转载)

    来源: https://www.cnblogs.com/surfing/p/3542826.html 首先我觉得action的跳转大致可以这样归一下类,跳转到同一控制器内的action和不同控制器内的 ...

  2. pandas 格式化日期

    output_data["ShipDate"] = output_data["ShipDate"].dt.strftime("%Y/%m/%d&quo ...

  3. 笔记:KMP的复习

    Record 一个重要的字符串算法,这是第三次复习. 通过总结我认为之所以某个算法总是忘记,是因为大脑始终没有认可这种算法的逻辑(也就是脑回路). 本篇主要讲解从KMP的应用场景,再到算法知识,以及例 ...

  4. Canvas好难,如何让研发低成本实现Web端流程图设计功能

    摘要:本文由葡萄城技术团队于博客园原创并首发.转载请注明出处:葡萄城官网,葡萄城为开发者提供专业的开发工具.解决方案和服务,赋能开发者. 前言 相信大家在职场中经常会用到流程图,在互联网行业,绘制流程 ...

  5. CVE-2020-0796 SMB远程代码执行漏洞复现

    前言: 这个windows的永恒之黑漏洞,不得不复现一下啦! 这个漏洞诸多大佬都已经复现了,现在跟随大佬的脚步,逐个复现一下: 可参考:https://www.adminxe.com/1220.htm ...

  6. centos7.X安装mysql5.7 – 东凭渭水流

    1.下载mysql5.7 可以使用windows下载好后上传至Linux.网络条件好的推荐使用 wget https://dev.mysql.com/get/Downloads/MySQL-5.7/m ...

  7. Flutter系列文章-Flutter在实际业务中的应用

    不同场景下的解决方案 1. 跨平台开发: 在移动应用开发中,面对不同的平台(iOS和Android),我们通常需要编写两套不同的代码.而Flutter通过一套代码可以构建适用于多个平台的应用,大大提高 ...

  8. Empowering Long-tail Item Recommendation through Cross Decoupling Network (CDN)

    Empowering Long-tail Item Recommendation through Cross Decoupling Network (CDN) 来源: KDD'2023 Google ...

  9. 手把手教你使用Vite构建第一个Vue3项目

    写在前面 在之前的文章中写过"如何创建第一个vue项目",但那篇文章写的是创建vue2的 项目. 传送门如何创建第一个vue项目 打开Vue.js官网:https://cn.vue ...

  10. 全是中文的txt文件查找特定字符并输出该行到新文件

    tangshi.txt文件为全为汉唐诗 在该文件中查找指定字符 codecs库为打开中文文件的库,详情自行知乎 tangshi.txt大概十几万行,需要该文件练手的同学下方评论 要点:更改文件字符编码 ...