基本上,每個系統都有日志輸出這一功能。不管采用什麼成熟架構,或者自己開發吧,大多是儲存到資料庫,或者輸出到檔案,然後對這些資料進行分析、展示。
這種思路,主體還是各人自掃門前雪,每個系統自己負責日志的輸出、存儲、應用。
現在微服務時代,日志也可以獨立劃分出去,對外提供服務。比如下面介紹的這個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、展示日志
上圖隻是控制台的展示。實際應用中,可以将日志存在ES,然後用Kibana進行可視化展示。