项目依赖

Starter项目里,打开Nuget包管理器,搜索并安装NLog.Targets.Seq(也可以非侵入式依赖,直接拷贝dll文件到对应程序文件夹内也可) 以下两种方式配合修改配置均可引入Seq

  1. Nuget引用NLog.Targets.Seq

  2. 在应用位置植入NLog.Targets.Seq.dll

修改NLog.config加入以下配置块

<nlog>标签里添加

<extensions>
    <add assembly="NLog.Targets.Seq"/>
</extensions>

<targets>标签里添加


<target name="seq" xsi:type="BufferingWrapper" bufferSize="1000" flushTimeout="2000">

    <target xsi:type="Seq" serverUrl="http://具体IP:5341" apiKey="xxx" />

</target>

<rules>标签里添加

<logger name="*" minlevel="Info" writeTo="seq" />

通用词语定义

所有通用key均以小写拼写,多个字母以_分隔(下划线) 约定俗成的key

  • app: 具体服务应用(his、mam、mdm等)
  • env: 服务环境(dev、test、pre、prod)

基本搜索

搜索表达式

下面介绍常用的搜索方式。

字符串模糊检索

直接输入字符串,所有匹配字符串的都会检索出来,这种写法不会区分大小写。同时支持使用'和”

key检索

通过预先定义好key-value键值对来检索,一般用于区分环境和应用程序。

这里展示了在对应系统的ApiKey位置加入对应的key-value

逻辑运算符

支持常见的逻辑运算符,如and、or、not等,也支持他们的简写语法(command语法)

逻辑运算符 Command语法
and &&
or &#124&#124
not

同时还支持常见sql运算符

<>、<、<=、>、>=、==、!=

如下图

查询不是his系统的日志

内置属性

Seq支持许多内置属性,像是@Level等

常用属性如下

内置属性名 作用
@Level 日志级别(Info、Warn、Error等)
@Timestamp 日志记录时间,时间戳格式
@Message 日志信息
@Exception 日志如果包含异常信息和堆栈信息,会记录到这里面
@Data 日志结构
@Property 日志附带属性

字符串常见检索方式

  • like和% 这一点与SQL几乎一样,字符串可支持这样检索。

  • ci 忽略大小写

  • 正则表达式

支持复杂的正则表达式,具体正则表达式可以参考这个链接菜鸟教程-正则表达式

数据类型

Seq支持多种数据类型,如下

  • 'single quoted'- 字符串;引号字符可以通过加倍来转义:''Can''t'(两个引号即可转义一个引号,这一点与SQL一致)
  • 123, , - 数字,内部表示为 128 位十进制值0.450xc0ffee
  • 30d, - 持续时间,像是8h,1h15m,1m15s等等
  • true和false,布尔值
  • [1, 'test', true]- 具有从零开始的数字索引的数组[0]
  • {ace: 1, 'beta gamma': 23}- 带有字符串或标识符键的对象文字,Json对象等
  • null,可以检测用于日志是否为空

常用表达式

  • IN表达式 用于检索包含在多种数据(数组)的数据
  • 条件表达式 Seq同时支持if then else的条件语法结构,在后续的Select表达式中常用。

快速筛选同类型日志

在实际日志使用中,我们的日志往往很多是结构化的。如下图。 它们的结构化方式都是RemoveUnhealthyAddress Timer 耗时:{耗时}

如果我们要定位同类型日志时,可以使用EventType(事件类型),在Seq中点开日志详情,即可获取EventType。

可以在Type下点击 Find 来查看这个类型下的所有日志。记录该EventType即可在后续日志查询中使用该EventType快速定位。

使用时间来定位日志

时间戳和日期时间

支持常见的时间戳定位

同时也支持常见的时间格式查询,注意一点,初始未设置的Seq默认时间用的是格林威治时间,换算成北京时要-8h

时间范围和时间运算符

在Seq中支持时间范围标记,Seq的最小单位时是100纳秒(Ticks) 时间范围可以指定为任意整数天 ( d)、小时 (h )、分钟 (m )、秒 (s ) 和毫秒 ( ms),并且这些可以链接在一起以表示更复杂的持续时间,例如.1h30m 例如,之前我们谈到要减8小时变成北京时,就可以在这里操作

同时Seq支持大量的时间运算符和比较符,除了最常见的=之外还有

运算符:+、-、*、/(常见的加减乘除) 比较符:<>、<、<=、>、>=(不等于、小于、小于等于、大于、大于等于)

同时还支持获取当前时间,使用方法Now(),例如我这里获取最近1分15秒内的日志

定位Seq时间

有时,Seq时间并不一定就是格林威治时间,我们需要定位Seq服务器的时间。 可以使用Select ToTimeString(Now())或者Select ToIsoString(Now())的形式来定位当前Seq时间 可根据Seq时间来决定实际的时间查询方式。

获取具体时区误差 时区代码表参考:维基-时区表

注:北京时间是Asia/Shanghai 由于过于复杂, 推荐还是使用-8h的操作,只有在需要进行时区操作和划算的时候才推荐使用此功能

DatePart(时间部分)

需要通过某个时间部分来定位日志,比如要定位所有六月的日志、所有星期三的日志、所有12号的日志 例如定位周三的日志: DatePart(时间,时间部分,误差值)

时间部分 描述
date 表示 0:00(午夜 AM)的日期/时间,以刻度为单位
time 从午夜 AM 到指定的持续时间,以刻度为单位
year 年份部分为整数,例如 2021-01-05,这里的部分就是2021
month 月份部分,例如 2021-01-05,这里的部分就是1
day 天部分,例如 2021-01-05,这里的部分就是5
hour (24 小时制)的小时部分,例如 13 表示下午 1 点,2021-01-05 11:03:54的hour部分就是11
minute 分钟,例如2021-01-05 11:03:54的hour部分就是3
second 秒,例如2021-01-05 11:03:54的hour部分就是54
weekday 星期几,星期日=0,星期一=1,……

复杂查询

在复杂查询下,更多细节推荐查阅官方文档:官方文档

函数

Seq支持很多函数来辅助日志分析,我们在使用中常常不需要关注所有的函数列表,官方提供了一份常用的函数表:函数表

这里写几个最常用的函数用法

DateTime(str) 尝试将字符串转换为日期时间。如果无法正确解析,将返回null;正确解析则返回这个时间的Seq时间单位。

DatePart(datetime, part, offset) 获取日期时间部分,用于获取日期时间的一部分。在[[Seq#DatePart(时间部分)|前面的时间部分]]有讨论过。

Now() 获取当前时间的时间单位,返回Seq时间单位

Round(value, places) 四舍五入指定的小数位,value是传入值,places是最终保留小数位

Substring(str, start, length) 切割字符串,在复杂查询中极其常用的函数。常配合Length一同使用。

ToIsoString(datetime) 获取Iso-8601时间(也就是我们最常见的时间格式),需要传入Seq时间单位。

ToJson(arg) 将对象值转换为Json。

FromJson(json) 将Json转换为对象,序列化后即可直接从中取出字段使用。该函数消耗较大,尽量慎用。

ToNumber(str) 将字符串解析为数字。如果无法解析直接返回null。数字类型即可在Seq中做数字计算和比较。常用于耗时统计和筛选。

查询

在Seq下,全面支持SQL语法。像select、from等关键字与SQL使用一致。

select [<column> [as <label>],] //查询那些列,as即别名
[from stream //从哪里获取数据,最常用的即是stream
  [where <predicate>] //Where条件
  [group by [time(<d>)|<grouping>,]] //分组
  [having <predicate>] //Having条件
  [order by [time|<label>] [asc|desc]] //排序
  [limit <n>] //Top多少条
  [for refresh]]

聚合函数

与SQL一样,Seq也支持聚合函数来辅助统计和分析日志。 这里只谈到常用的聚合函数,更多资料参考官方文档-聚合函数

Count() 使用Count可以快速确认有多少符合条件的日志数 `select count(*) from stream where @Level='Error'

Distinct() 去除重复日志 `select distinct(@Message) from stream where @Level='Error'

Sum() 统计符合条件的字段/值之和 `select sum(1) from stream where @Level='Error' group by app

变量和Seq分组

待更新

一些应用场景

查询指定应用下近1个小时内的报错日志

select * from stream where @Level='Error' and @Timestamp > now()-1h and app='his'

复杂查询,查询指定日志信息,耗时>x值的

报表

results matching ""

    No results matching ""