上一篇说如何搭建elk的环境(不清楚的可以看我的上一篇博客http://www.cnblogs.com/never-give-up-1015/p/5715904.html),现在来说一下如何用Nlog将日志通过logstash写入elasticsearch。
新建一个项目,用nuget引入Nlog,随便写几行打日志的代码(写成循环是为了方便测试)
var log = LogManager.GetCurrentClassLogger();
while (true)
{
log.Info("high Hkaos one");
log.Debug("high Hkaos two");
log.Warn("high Hkaos three");
log.Error("high Hkaos four");
Console.WriteLine("success");
Console.ReadKey();
}
我是采用udp的方式传输,所以在配置Nlog的时候需要设置type为Network,至于message的格式可以在layout中配置(网上一大堆,一搜就出来了),下面是我的配置文件
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
<section name="nlog" type="NLog.Config.ConfigSectionHandler, NLog"/>
</configSections>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
</startup>
<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<targets>
<target name="network" xsi:type="Network" address="udp://192.168.4.12:4561" layout="${message}"/>
</targets>
<rules>
<logger name="*" minlevel="Debug" writeTo="network" />
</rules>
</nlog>
</configuration>
一开始没有写configSections和rules,所以一直没有打日志,晕死。
配置完毕之后,在配置logstash。由于Nlog是通过udp一直向配置的地址端口发送日志,所以在配置文件(这个配置就是自己手动建的文件,不懂的看上一篇博客)中的input要监听Nlog中配置的地址。logstash的input中可以写多种搜集日志的方式,有兴趣的可以去官网地址看看(https://www.elastic.co/guide/en/logstash/current/input-plugins.html)。
input {
udp{
host=>"192.168.4.12"
port=>
}
}
output {
stdout{
}
}
input下面可以写多个搜集方式,比如
input {
stdin{ }
udp{
host=>"192.168.4.12"
port=>
}
}
配置完成之后就可以测试一下。运行程序之前记得启动logstash,elasticsearch和kibana暂时不用可以不用启动。
同时观察启动logstash的窗口
出现了刚刚打印的日志,yes! 成功了。
那我们先看看如何把日志写到elasticsearch里面并且通过kibana查看。很简单,我们在output中把原先输入到屏幕上的信息同时也输入到elasticsearch中就Ok了。同时呢,output的输出方式也有很多,可以去看看(https://www.elastic.co/guide/en/logstash/current/output-plugins.html),elasticsearch的选项有很多,这里有详细的介绍(https://www.elastic.co/guide/en/logstash/current/plugins-outputs-elasticsearch.html),下面是我的配置
output {
stdout{
}
elasticsearch {
hosts => ["127.0.0.1:9200"]
index => "logstash-%{+YYYY.MM.dd}"
document_type => "logs"
}
}
hosts就是elasticsearch的地址,可以配置多个,是个数组,index是索引的名称,相当于数据库的库名字,这里就是命名就是logstash-当天日期,每天都会新建一个库,document_type是类型的名称,相当于数据库中的表,老版本是index_type,新版本不让用了,如果用的话就会报错,告诉你这个方法被弃用了,让你用document_type。配置好之后需要重新启动logstash,首先要先启动elasticsearch和kibana。(Tip:重启logstash的话可以用Ctrl+C重启,连续按,能输入为止)。走起!
界面是没啥变化,这时候要登录kibana看看,地址在启动kibana的时候被被打印出来
界面如下:
刚刚的日志被打印了出来,bingo!右边的字段可以自己选择添加是否显示在右边,右上角有个last 15 minutes,表示查看最新15分钟的,点击之后你可以任意选择你想查看的时间段。
同时呢,elasticsearch也自带了查询的插件,不过需要安装,方法也简单,cmd进入elasticsearch的目录 运行plugin -install mobz/elasticsearch-head,就会自动安装了,成功之后地址为http://localhost:9200/_plugin/head/,可以直接访问,下面是界面
在基本查询里面你可以查询打印的日志,还有执行的查询语句和原始的json。
但是这些只能打印出message,比如我要打印其他的东西怎么办,比如方法名,hash值,是debug还是info还是error以及其他自定义的字段,这时候会有人说那就全部打印在message里面,那为啥还要这么麻烦用这个工具呢,直接打印到文件里面直接Ctrl+F就好了。所以我们要通过Nlog打印自定义的字段。这就要自己在Nlog里面定义了。
这也是在网上查找了资料才找到的方法,需要继承Nlog的LayoutRenderer,重写Append方法
[LayoutRenderer("json")]
public class JsonLayoutRenderer : LayoutRenderer
{
protected override void Append(StringBuilder builder, LogEventInfo loggingEvent)
{
var msg = loggingEvent.FormattedMessage.AsJson<JsonLogMessage>(); msg.priority = loggingEvent.Level.ToString();
msg.logger_name = loggingEvent.LoggerName;
msg.thread = loggingEvent.SequenceID.ToString();
msg.application = "TestApplication";
var json = msg.AsJsonString();
builder.Append(json);
}
}
本来是通过赋值的方法在LogEventInfo中取我想要的值比如Method,file,class等等,Log4net中是直接可以取得到的,但是Nlog不行,唉,蛋疼,所以只能吧数据写到json序列化之后写到message里面,然后在这个方法里面反序列化回来。大神们有什么好方法希望给解惑啊!
这是对象信息
public class JsonLogMessage
{
public string @class { get; set; }
public string file { get; set; }
public string host { get; set; }
public string logger_name { get; set; }
public string path { get; set; }
public string priority { get; set; }
public string thread { get; set; }
public string application { get; set; }
public string message { get; set; }
public string addUser { get; set; }
public string addUserName { get; set; }
public string objName { get; set; }
public string objId { get; set; }
public int hash { get; set; }
public string method { get; set; }
public DateTime timestamp { get; set; }
}
本来timestamp字段不想写上去的,但是后来通过代码取不到时间,也是一个蛋疼的问题。
那message的格式修改了,所以打日志的方法也就要变了,由于Append的方式改变了,所以布局方式需要重新修改,只要在程序运行前加一段代码就好,代码里面用的AsJosn和AsJosnString是封装好的json序列化和反序列化的方法,所以大家要用的话就直接用json原生的方法就好了。另外在配置文件中需要改变layout的布局方式,将layout="${message}修改成layout="${json}
private static void Main(string[] args)
{
ConfigurationItemFactory.Default.LayoutRenderers.RegisterDefinition("json", typeof(JsonLayoutRenderer)); var log = LogManager.GetCurrentClassLogger();
while (true)
{
var josn1 = new JsonLogMessage("Main", -, "high Hkaos one", "tester", "testName", "objName", "objId");
var josn2 = new JsonLogMessage("Main", -, "high Hkaos two", "tester", "testName", "objName", "objId");
var josn3 = new JsonLogMessage("Main", -, "high Hkaos three", "tester", "testName", "objName", "objId");
var josn4 = new JsonLogMessage("Main", -, "high Hkaos four", "tester", "testName", "objName", "objId"); log.Info(josn1.AsJsonString());
log.Debug(josn2.AsJsonString());
log.Warn(josn3.AsJsonString());
log.Error(josn4.AsJsonString());
Console.WriteLine("success");
Console.ReadKey();
}
}
运行!
完蛋了,看到这个我就知道有错了,虽然日志出来了,但是我们在head插件或者kibana中看看(我用的是head插件)
日志的信息全部打印到message里面,操蛋了。我要的不是这样子的。去Google了一下,发现要是用json的话,需要在input里面加codec=>"json",好了,那就修改一下input
input {
stdin{ }
udp{
host=>"192.168.4.12"
port=>
codec=>"json"
}
}
重启一下logstash,再来一遍
这次明显打印的不一样了,再看看head里面数据
yes!要的就是这个效果。
之后我吧Nlog的配置改成了代码写的,使用配置文件总有一些不方便的地方,比如说地址。下面是代码
private static void Main(string[] args)
{
ConfigurationItemFactory.Default.LayoutRenderers.RegisterDefinition("json", typeof(JsonLayoutRenderer)); var log = LogManager.GetCurrentClassLogger();
var udpTarget = new NetworkTarget()
{
Address = "udp://192.168.4.12:4561",
Encoding = Encoding.UTF8,
Layout = "${json}",
NewLine = true,
}; var config = new LoggingConfiguration();
config.LoggingRules.Add(new LoggingRule("*", LogLevel.Debug, udpTarget));
LogManager.Configuration = config; while (true)
{
var josn1 = new JsonLogMessage("Main", -, "high Hkaos one", "tester", "testName", "objName", "objId");
var josn2 = new JsonLogMessage("Main", -, "high Hkaos two", "tester", "testName", "objName", "objId");
var josn3 = new JsonLogMessage("Main", -, "high Hkaos three", "tester", "testName", "objName", "objId");
var josn4 = new JsonLogMessage("Main", -, "high Hkaos four", "tester", "testName", "objName", "objId"); log.Info(josn1.AsJsonString());
log.Debug(josn2.AsJsonString());
log.Warn(josn3.AsJsonString());
log.Error(josn4.AsJsonString());
Console.WriteLine("success");
Console.ReadKey();
}
}
配置文件里面直接删除原来添加的东西就好了。
就写到这里吧,下一篇准备些一下如何用C#链接日志服务,根据条件查询日志,如何配置模板和映射等。
Nlog、elasticsearch、Kibana以及logstash在项目中的应用(二)的更多相关文章
-
Nlog、elasticsearch、Kibana以及logstash在项目中的应用(一)
前言 最近在做文档管理中,需要记录每个管理员以及用户在使用过程中的所有操作记录,本来是通过EF直接将操作数据记录在数据库中,在查询的时候直接从数据库中读取,但是这样太蠢了,于是在网上找到了logsta ...
-
NLog——ElasticSearch——Kibana
Nlog.elasticsearch.Kibana以及logstash在项目中的应用(一) Nlog.elasticsearch.Kibana以及logstash在项目中的应用(二) ASP.NET ...
-
ElasticSearch[v6.2] 在实际项目中的应用
摘要:本文所讲述的内容,为ElasticSearch(以下简称ES)全文搜索引擎在实际大数据项目的应用:ES的底层是开源库 Lucene.但是,你没法直接用 Lucene,必须自己写代码去调用它的接口 ...
-
setBit testBit权限管理(shiro项目中来的二)
一,setBit testBit权限管理的理解 1.1.jdk7文档解释 public boolean testBit(int n)Returns true if and only if the de ...
-
vue项目中批量打印二维码
前提:项目中要打印的二维码为后台返回,批量选择后,点击打印,先打开二维码预览界面,再执行打印. 以下代码中 codePicList为选中的二维码数组.重点css:page-break-after:al ...
-
ElasticSearch Kibana 和Logstash 安装x-pack记录
前言 最近用到了ELK的集群,想想还是用使用官方的x-pack的monitor功能对其进行监控,这里先上图看看: 环境如下: 操作系统: window 2012 R2 ELK : elasticsea ...
-
elasticsearch kibana的安装部署与简单使用(二)
介绍一下elasticsearch和kibana的简单使用 es其实我理解为一个数据库,一个数据库无非就是增删改查, Delete PUT GET POST 这些接口关键字完美对应 比如,我想查一张 ...
-
Elasticsearch,Kibana,Logstash,NLog实现ASP.NET Core 分布式日志系统
Elasticsearch - 简介 Elasticsearch 作为核心的部分,是一个具有强大索引功能的文档存储库,并且可以通过 REST API 来搜索数据.它使用 Java 编写,基于 Apac ...
-
elasticsearch + kibana + x-pack + logstash_集群部署安装
elasticsearch 部分总体描述: 1.elasticsearch 的概念及特点.概念:elasticsearch 是一个基于 lucene 的搜索服务器.lucene 是全文搜索的一个框架. ...
随机推荐
-
Servlet的生命周期+实现方式
1.Servlet的生命周期: (1)被创建: 默认情况下,Servlet第一次被访问时,被服务器创建.会调用init()方法. 一个 ...
-
jquery 之 Deferred 使用与实现
观察者模式是开发中经常使用的模式,这个模式由两个主要部分组成:主题和观察者.通过观察者模式,实现主题和观察者的解耦. 主题负责发布内容,而观察者则接收主题发布的内容.通常情况下,观察者都是多个,所以, ...
-
POJ3368 Frequent values(RMQ线段树)
题目大概说给一个递增序列,询问区间出现最多的数. 用莫队算法比较直观,虽然应该会T..好像也可以主席树..不过题目给的序列是有序的,因而相同的数会聚在一起. 考虑把序列分成一段一段,使每段都包含极大的 ...
-
Repeater控件 ---属性(ItemCommand事件)
epeater的Command操作:1.ItemCommand事件 - 在Repeater中所有能触发事件的控件,都会来触发这一个事件 2.CommandName - 判断点击的是什么按钮,e.Com ...
-
Tautology(structure)
Tautology Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 10061 Accepted: 3826 Descri ...
-
Qt实战之开发CSDN下载助手 (3)(结束篇)
再次申明下,开发这款助手,主要是用来学习交流,并不是用来开发什么刷积分的软件. 好了,言归正传,这次,主要的分析下CSDN的下载,评论,验证码获取机制等等. 好,回到第二篇,当我们成功登陆时,CSDN ...
-
Oracle 12C 新特性之表分区带 异步全局索引异步维护(一次add、truncate、drop、spilt、merge多个分区)
实验准备:-- 创建实验表CREATE TABLE p_andy(ID number(10), NAME varchar2(40))PARTITION BY RANGE (id)(PARTITION ...
-
python web框架篇:views视图函数
Django请求的生命周期是怎样的? 简单地说,通过URL对应关系匹配 ->找到对应的函数(或者类)->返回字符串(或者读取Html之后返回渲染的字符串) 解剖起来如下: 1. 当用户在浏 ...
-
java中的参数传递是按引用传递还是按值传递
最近去面试,有一个面试官问到java中参数传递的问题,感觉自己对于这一块还是理解的不够深.今天我们就一起来学习一下Java中的接口和抽象类.下面是本文的目录大纲: 一 . 什么是按值传递,什么是按引用 ...
-
RESTful杂记
在网上找了许久的关于REST的资料,发现网上大部分都是说的比较片面,虽然有部分说出了本质,但也没有详细提出,所以在这里记录一下. RESTful是什么 首先,*是这样说的: 表现层状态转换(RE ...