基本上,每个系统都有日志输出这一功能。不管采用什么成熟框架,或者自己开发吧,大多是保存到数据库,或者输出到文件,然后对这些数据进行分析、展示。
这种思路,主体还是各人自扫门前雪,每个系统自己负责日志的输出、存储、应用。
现在微服务时代,日志也可以独立划分出去,对外提供服务。比如下面介绍的这个logstash。
logstash,从名字看,是日志存储器之意。实际上,我觉得它叫日志收集器更合适。它提供多种方式对应用程序进行日志收集,比如日志文件,http,tcp;然后收集到的日志,可以存储到数据库里,比如ES(Elasticsearch)。显然,logstash在其中,只是一个日志贩子或中介。
下面以我们实际项目为例,介绍一下logstash的用法。
1、运行logstash
logstash是一个服务,下载下来以后就可以直接运行。运行的时候指定配置文件就行,如:
bin/logstash -f config/default.conf
default.conf是我自己编辑的,内容如下:
input {
#接收http提交方式
http{
#可接收来自任何IP地址提交的日志
host => "0.0.0.0"
port => 9090
codec => json
}
#接收tcp提交方式
tcp{
port => 5044
#json_lines,比较长的json
codec => json_lines
}
}
output {
#输出到控制台
stdout {}
#输出到文件
file{
path => "./test-%{+YYYY-MM-dd}.txt"
}
}
通过这个配置文件,应用程序可以通过http方式,或者socket方式,将日志以json格式提交给logstash。
logstash接收到以后,会在控制台中展示,同时还保存到按日期命名的日志文件里。
2、提交日志给logstash
应用系统将日志写入logstash,java有现成的例子,但.net就惨了。极少,我只看到过网上有提到使用serilog的。但这个东东需要.net core或者很高版本的。net framework支持。我们项目,有的还在用.net3.5,怎么搞?
其实根本不需要这个serilog,直接提交就好。示例如下:
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.IO;
using System.Net;
using System.Net.Sockets;
using System.Text;
namespace UnitTestProject
{
[TestClass]
public class TestLogstash
{
[TestMethod]
public void testTcp()
{//通过socket方式提交给logstash
//通过服务器的ip和端口号,创建TcpClient实例
using (TcpClient client = new TcpClient("192.168.0.98", 5044))
{
NetworkStream clientStream = client.GetStream();
BinaryWriter bw = new BinaryWriter(clientStream, Encoding.UTF8);
string sj = getJsonString();
byte[] postData = Encoding.UTF8.GetBytes(sj);
bw.Write(postData);
bw.Close();
client.Close();
}
}
[TestMethod]
public void TestHttp()
{//通过http方式提交给logstash
string url = "http://localhost:9090";
string sj = getJsonString();
byte[] postData = Encoding.UTF8.GetBytes(sj);
string re;
using (WebClient webClient = new WebClient())
{
webClient.Encoding = Encoding.GetEncoding("utf-8");
webClient.Headers.Add("Content-Type", "application/json");
byte[] responseData = webClient.UploadData(url, "POST", postData);//得到返回字符流
re = Encoding.UTF8.GetString(responseData);
}
}
string getJsonString()
{
JObject jobj = getJson();
return JsonConvert.SerializeObject(jobj);
}
JObject getJson()
{
string datajson = @"{
""host"": ""192.168.0.98"",
""service"": ""花果山林地租赁系统"",
""pid"": ""1"",
""log"": ""hello world""
}";
return (JObject)JsonConvert.DeserializeObject<object>(datajson);
}
}
}
3、展示日志
![](https://img.laitimes.com/img/_0nNw4CM6IyYiwiM6ICdiwiI0gTMx81dsQWZ4lmZf1GLlpXazVmcvwFciV2dsQXYtJ3bm9CX9s2RkBnVHFmb1clWvB3MaVnRtp1XlBXe0xCMy81dvRWYoNHLwEzX5xCMx8FesU2cfdGLwMzX0xiRGZkRGZ0Xy9GbvNGLpZTY1EmMZVDUSFTU4VFRR9Fd4VGdsYTMfVmepNHLrJXYtJXZ0F2dvwVZnFWbp1zczV2YvJHctM3cv1Ce-cmbw5SO5YTM0UDMlRTZhNDMjljZyYzXyQDM0ETM1EzLchDMyIDMy8CXn9Gbi9CXzV2Zh1WavwVbvNmLvR3YxUjLyM3Lc9CX6MHc0RHaiojIsJye.png)
上图只是控制台的展示。实际应用中,可以将日志存在ES,然后用Kibana进行可视化展示。