需求
已经在VPS上部署了一个网站,现在需要对Nginx的日志文件进行统计以监控请求流量、请求页面等内容,还需要对这些数据进行可视化。
流程
主要分为三部分,分别是数据处理、数据写入、数据可视化:
- 数据处理,基本流程是读取
access.log
,然后对读取的数据正则处理 - 将处理后的数据写入
InfluxDB
,InfluxDB
是一个时序数据库,特别适合用于处理和分析资源监控数据这类时序数据 - 数据可视化由
Grafana
实现 - 此外还实现了一个通用的由
httpserver
实现的Monitor
,可以返回Json
形式的监控系统运行状况信息
说明
上述前三步的流程可以总结如下:实时读取日志文件与对日志文件进行解析,并将其写入InfluxDB
, 用Grafana
进行可视化展示。这是一个线性的流程,其实可以把这个流程再进行细分,改为并发的执行模型。
首先将整个流程拆分成三个模块:数据读取
、数据解析
、数据写入
,再将这三个模块分别用单独的goroutine
并发执行,模块间通过channel
进行数据同步,这样的执行效率应该会比线性执行的模型更高,至于程序到底是并发还是并行地执行其实不需要去关心,因为Go为我们屏蔽了底层的实现细节。
具体实现如下:先定义一个LogProcess
结构体用以封装整个模块的基本功能,其中两个名为wc
和rc
的Channel
用以负责读取数据与写入数据的同步,Reader read
和Writer write
用以引入读写模块。1
2
3
4
5
6type LogProcess struct {
rc chan []byte
wc chan *Message
read Reader
write Writer
}
读取模块从日志文件末尾逐行读取数据并写入Channel rc
。
解析模块从Channel rc
中读取到每行的日志数据,通过正则表达式提取所需数据(ip address, path, status, method 等),再写入Channel wc
。其中数据结构体如下:
1 | type Message struct { |
写入模块先初始化influxdb client
,从Channel wc
中读取监控数据,再构造数据写入Influxdb
以持久化,结构如下:
- Tags : Path, Method, Scheme, Status
- Fields: UpstreamTime, RequestTime, BytesSent
- Time: TimeLocal
最后由Grafana读取Influxdb
内的数据进行可视化:
其他
Monitor
监控模块中负责将程序运行时的处理日志数、运行时间、Channel rc
长度、Channel wc
长度、错误数、吞吐量等使用httpserver
以Json
形式返回。1
2
3
4
5
6
7
8{
"handleLine": 999,
"tps": 123,
"readChanLen": 456,
"writeChanLen": 456,
"runTime": "8h47m51.6090878s",
"errNum": 123
}
使用
Get influxDB in Go
1
$ go get github.com/influxdata/influxdb
Install and run InfluxDB
1
2$ docker pull influxdb
$ docker run influxdbInstall and run Grafana
1
2
3$ wget https://s3-us-west-2.amazonaws.com/grafana-releases/release/grafana_5.3.2_amd64.deb
$ sudo dpkg -i grafana_5.3.2_amd64.deb
$ sudo service grafana-server startRun
procrss.go
and open the follwing url , then you will see the visualization1
https://localhost:3000
Open
https://localhost:9999/monitor
will return monitor’s general info with json1
2
3
4
5
6
7
8{
"handleLine": 999,
"tps": 123,
"readChanLen": 456,
"writeChanLen": 456,
"runTime": "8h47m51.6090878s",
"errNum": 123
}