基于Go实现的Nginx日志实时监控系统

需求

已经在VPS上部署了一个网站,现在需要对Nginx的日志文件进行统计以监控请求流量、请求页面等内容,还需要对这些数据进行可视化。

流程

主要分为三部分,分别是数据处理、数据写入、数据可视化:

  • 数据处理,基本流程是读取access.log,然后对读取的数据正则处理
  • 将处理后的数据写入InfluxDBInfluxDB是一个时序数据库,特别适合用于处理和分析资源监控数据这类时序数据
  • 数据可视化由Grafana实现
  • 此外还实现了一个通用的由httpserver实现的Monitor,可以返回Json形式的监控系统运行状况信息

说明

上述前三步的流程可以总结如下:实时读取日志文件与对日志文件进行解析,并将其写入InfluxDB, 用Grafana进行可视化展示。这是一个线性的流程,其实可以把这个流程再进行细分,改为并发的执行模型。

首先将整个流程拆分成三个模块:数据读取数据解析数据写入,再将这三个模块分别用单独的goroutine并发执行,模块间通过channel进行数据同步,这样的执行效率应该会比线性执行的模型更高,至于程序到底是并发还是并行地执行其实不需要去关心,因为Go为我们屏蔽了底层的实现细节。

具体实现如下:先定义一个LogProcess结构体用以封装整个模块的基本功能,其中两个名为wcrcChannel用以负责读取数据与写入数据的同步,Reader readWriter write用以引入读写模块。

1
2
3
4
5
6
type LogProcess struct {
rc chan []byte
wc chan *Message
read Reader
write Writer
}

读取模块从日志文件末尾逐行读取数据并写入Channel rc

解析模块从Channel rc中读取到每行的日志数据,通过正则表达式提取所需数据(ip address, path, status, method 等),再写入Channel wc。其中数据结构体如下:

1
2
3
4
5
6
type Message struct {
TimeLocal time.Time
BytesSent int
Path, Method, Scheme, Status string
UpstreamTime, RequestTime float64
}

写入模块先初始化influxdb client,从Channel wc中读取监控数据,再构造数据写入Influxdb以持久化,结构如下:

  • Tags : Path, Method, Scheme, Status
  • Fields: UpstreamTime, RequestTime, BytesSent
  • Time: TimeLocal

最后由Grafana读取Influxdb内的数据进行可视化:

其他

Monitor监控模块中负责将程序运行时的处理日志数、运行时间、Channel rc长度、Channel wc长度、错误数、吞吐量等使用httpserverJson形式返回。

1
2
3
4
5
6
7
8
{
"handleLine": 999,
"tps": 123,
"readChanLen": 456,
"writeChanLen": 456,
"runTime": "8h47m51.6090878s",
"errNum": 123
}

使用

Github地址点此

  • Get influxDB in Go

    1
    $ go get github.com/influxdata/influxdb
  • Install and run InfluxDB

    1
    2
    $ docker pull influxdb
    $ docker run influxdb
  • Install 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 start
  • Run procrss.go and open the follwing url , then you will see the visualization

    1
    https://localhost:3000
  • Open https://localhost:9999/monitor will return monitor’s general info with json

    1
    2
    3
    4
    5
    6
    7
    8
    {
    "handleLine": 999,
    "tps": 123,
    "readChanLen": 456,
    "writeChanLen": 456,
    "runTime": "8h47m51.6090878s",
    "errNum": 123
    }
  • 本文作者: Marticles
  • 版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 3.0 许可协议。转载请注明出处!