热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

goinfluxdbgrafana读取日志展示

最近在学go,所以就用go写了一个脚本,读取服务器的log日志,根据正则匹配,从log日志中匹配想要的内容,然后存到influxdb数据库作为数据源,最后将数据在grafana中展

最近在学go,所以就用go写了一个脚本,读取服务器的log日志,根据正则匹配,从log日志中匹配想要的内容,然后存到influxdb数据库作为数据源,最后将数据在grafana中展示

下面写一下详细的安装步骤:

首先我找了一个服务器,在服务器上先进行安装influxdb、安装go、安装grafana。

因为我找的服务器系统有点老,是centos6.5,所以安装跟高版本的还是不太一样

安装grafana:

1、下载安装包:

wget https://s3-us-west-2.amazonaws.com/grafana-releases/release/grafana-4.6.3-1.x86_64.rpm --no-check-certificate

 

go influxdb grafana 读取日志展示

 

 2、安装环境依赖

yum install initscripts

yum install fontconfig

yum install freetype*

yum install urw-fonts

安装grafana服务

rpm -Uvh grafana-4.6.3-1.x86_64.rpm

 

3、安装完成后修改配置文件/etc/grafana/grafana.ini

配置文件可以根据说明自行修改需要的行即可

 

4、安装后这些文件的存放路径

安装二进制文件 /usr/sbin/grafana-server

将init.d脚本复制到 /etc/init.d/grafana-server

安装默认文件(环境变量) /etc/sysconfig/grafana-server

将配置文件复制到 /etc/grafana/grafana.ini

安装systemd服务(如果systemd可用)名称 grafana-server.service

默认配置使用日志文件 /var/log/grafana/grafana.log

 

5、grafana服务

启动:service grafana-server start

停止:service grafana-server stop

重启:service grafana-server restart

加入开机自启动: chkconfig --add grafana-server on

6、安装zabbix插件

grafana-cli plugins install alexanderzobnin-zabbix-app

 

7、安装其他面板插件

例:

grafana-cli plugins install grafana-clock-panel

grafana-cli plugins install grafana-piechart-panel

grafana-cli plugins install raintank-worldping-app

grafana-cli plugins install jasonlashua-prtg-datasourc

grafana-cli plugins install jasonlashua-prtg-datasource g

rafana-cli plugins install grafana-worldmap-panel

 

8、卸载插件

例:

grafana-cli plugins uninstall jasonlashua-prtg-datasource

grafana-cli plugins uninstall raintank-worldping-app

 

9、安装或卸载完成后,需要重启服务

service grafana-server restart

 

10、验证

查看端口3000 是否监听:netstat nuplt 


查看运行情况命令:
rpm -qa | grep -i grafana

go influxdb grafana 读取日志展示

 

 

 

 

浏览器输入http://ip:3000 查看登录页面是否正常:

 

go influxdb grafana 读取日志展示

 

 出现这个页面说明安装正常:账号和密码都默认admin 

安装influx:

1、wget https://dl.influxdata.com/influxdb/releases/influxdb-1.7.8.x86_64.rpm

2、sudo yum localinstall influxdb-1.7.8.x86_64.rpm
3、sudo service influxdb start
 
连接数据库、查看表操作、log_test表就是我用go语言读取log日志,用正则进行解析之后存入表的数据,如图:
go influxdb grafana 读取日志展示

 

 提示:在用go语言定义字段的类型的时候要注意跟数据表的类型对应上,否则会出现插入不到表的情况,会提示类型错误之类的问题。

influx跟mysql不一样,它没有专门的创建表的语句,它在执行插入操作的时候就默认建了一张表,下面的例子就是默认access_test表不存在,直接执行inser操作插入一条数据

go influxdb grafana 读取日志展示

 

 

关于go的代码:

1、我本地测试的,在目录下有一个access.log日志的脚本

2、代码文件log文件进行读取log日志,写入influx数据库,这里强调一下go influxdb grafana 读取日志展示

 

 代码,需要下载go的clinet,地址:https://github.com/influxdata/influxdb-client-go

否则无法连接

log文件代码:

package main

import (
"bufio"
"flag"
"fmt"
client "github.com/influxdata/influxdb1-client/v2"
"io"
"log"
"net/http"
"net/url"
"os"
"regexp"
"strconv"
"strings"
"time"
"encoding/json"
)

type Reader interface {
Read(rc chan []byte)
}

type Writer interface {
Write(wc chan *Message)
}

type LogProcess struct {
rc chan []byte
wc chan *Message
read Reader
write Writer
}

type ReadFromFile struct {
path string // 读取文件的路径
}

type WriteToInfluxDB struct {
influxDBDsn string // influx data source
}

type Message struct {
TimeLocal time.Time
BytesSent float64
Path, Method, Scheme, Status string
UpstreamTime, RequestTime float64
}

// 系统状态监控
type SystemInfo struct {
HandleLine int `json:"handleLine"` // 总处理日志行数
Tps float64 `json:"tps"` // 系统吞出量
ReadChanLen int `json:"readChanLen"` // read channel 长度
WriteChanLen int `json:"writeChanLen"` // write channel 长度
RunTime string `json:"runTime"` // 运行总时间
ErrNum int `json:"errNum"` // 错误数
}

const (
TypeHandleLine = 0
TypeErrNum = 1
)

var TypeMOnitorChan= make(chan int, 200)

type Monitor struct {
startTime time.Time
data SystemInfo
tpsSli []int
}

func (m *Monitor) start(lp *LogProcess) {

go func() {
for n := range TypeMonitorChan {
switch n {
case TypeErrNum:
m.data.ErrNum += 1
case TypeHandleLine:
m.data.HandleLine += 1
}
}
}()

ticker := time.NewTicker(time.Second * 5)
go func() {
for {
<-ticker.C
m.tpsSli = append(m.tpsSli, m.data.HandleLine)
if len(m.tpsSli) > 2 {
m.tpsSli = m.tpsSli[1:]
}
}
}()

http.HandleFunc("/monitor", func(writer http.ResponseWriter, request *http.Request) {
m.data.RunTime = time.Now().Sub(m.startTime).String()
m.data.ReadChanLen = len(lp.rc)
m.data.WriteChanLen = len(lp.wc)

if len(m.tpsSli) >= 2 {
m.data.Tps = float64(m.tpsSli[1]-m.tpsSli[0]) / 5
}

ret, _ := json.MarshalIndent(m.data, "", "\t")
io.WriteString(writer, string(ret))
})

http.ListenAndServe(":9193", nil)
}

func (r *ReadFromFile) Read(rc chan []byte) {
// 读取模块
fmt.Println("start readfromfile")
// 打开文件
fmt.Println(r.path)
f, err := os.Open(r.path)

fmt.Println(f)

if err != nil {
panic(fmt.Sprintf("open file error:%s", err.Error()))
}

// 从文件末尾开始逐行读取文件内容
//f.Seek(0, 2)
rd := bufio.NewReader(f)
fmt.Println("rd",rd)

for {
fmt.Println("for")
line, err := rd.ReadBytes('\n')

fmt.Println("line:",line)
fmt.Println("err:",err)
fmt.Println("ioeof:",io.EOF)
fmt.Println("linetorc",line[:len(line)-1])

if err == io.EOF {
time.Sleep(500 * time.Millisecond)
continue
} else if err != nil {
panic(fmt.Sprintf("ReadBytes error:", err.Error()))
}

TypeMonitorChan <- TypeHandleLine
rc <- line[:len(line)-1]
fmt.Println("read foreach success",rc)

}

fmt.Println("read success")
}

func (w *WriteToInfluxDB) Write(wc chan *Message) {
// 写入模块

fmt.Println("writetoinfluxdb")

// Create a new HTTPClient

c, err := client.NewHTTPClient(client.HTTPConfig{
Addr: "http://127.0.0.1:8086",
Username: "admin",
Password: "",
})


fmt.Println("client.newhttpclient",c)
if err != nil {
fmt.Println("err")
log.Fatal(err)
}

fmt.Println("wc",wc)


for v := range wc {
fmt.Println("wccccc")
// Create a new point batch
bp, err := client.NewBatchPoints(client.BatchPointsConfig{
Database: "mylogdb",
Precision: "s",
})

fmt.Println("bp:",bp)
if err != nil {
log.Fatal(err)
}

// Create a point and add to batch
// Tags: Path, Method, Scheme, Status
tags := map[string]string{"Path": v.Path, "Method": v.Method, "Scheme": v.Scheme, "Status": v.Status}
// Fields: UpstreamTime, RequestTime, BytesSent
fields := map[string]interface{}{
"UpstreamTime": v.UpstreamTime,
"RequestTime": v.RequestTime,
"BytesSent": v.BytesSent,
}

pt, err := client.NewPoint("log_test", tags, fields, v.TimeLocal)
fmt.Println("pt:",pt)
if err != nil {
log.Fatal(err)
}
bp.AddPoint(pt)

// Write the batch
if err := c.Write(bp); err != nil {
log.Fatal(err)
}

log.Println("write success!")
fmt.Println("write foreach success!")
}
fmt.Println("write success")
}

func (l *LogProcess) Process() {
// 解析模块

/**
172.0.0.12 - - [04/Mar/2018:13:49:52 +0000] http "GET /foo?query=t HTTP/1.0" 200 2133 "-" "KeepAliveClient" "-" 1.005 1.854
*/
fmt.Println("l logprocess")

r := regexp.MustCompile(`([\d\.]+)\s+([^ \[]+)\s+([^ \[]+)\s+\[([^\]]+)\]\s+([a-z]+)\s+\"([^"]+)\"\s+(\d{3})\s+(\d+)\s+\"([^"]+)\"\s+\"(.*?)\"\s+\"([\d\.-]+)\"\s+([\d\.-]+)\s+([\d\.-]+)`)

loc, _ := time.LoadLocation("Asia/Shanghai")

fmt.Println("for process lrc",l.rc)

for v := range l.rc {

ret := r.FindStringSubmatch(string(v))

fmt.Println("logproces-s-ret",ret[5])

fmt.Println("ret length:", len(ret))

if len(ret) != 14 {
TypeMonitorChan <- TypeErrNum
log.Println("FindStringSubmatch fail:", string(v))
continue
}

message := &Message{}

t, err := time.ParseInLocation("02/Jan/2006:15:04:05 +0000", ret[4], loc)
if err != nil {
TypeMonitorChan <- TypeErrNum
log.Println("ParseInLocation fail:", err.Error(), ret[4])
continue
}
message.TimeLocal = t

byteSent, _ := strconv.Atoi(ret[8])
//byteSent, _ := ret[8]
message.BytesSent = float64(byteSent)

// GET /foo?query=t HTTP/1.0
reqSli := strings.Split(ret[6], " ")
if len(reqSli) != 3 {
TypeMonitorChan <- TypeErrNum
log.Println("strings.Split fail", ret[6])
continue
}
message.Method = reqSli[0]

u, err := url.Parse(reqSli[1])
if err != nil {
log.Println("url parse fail:", err)
TypeMonitorChan <- TypeErrNum
continue
}
message.Path = u.Path

message.Scheme = ret[5]
message.Status = ret[7]

upstreamTime, _ := strconv.ParseFloat(ret[12], 64)
requestTime, _ := strconv.ParseFloat(ret[13], 64)
message.UpstreamTime = upstreamTime
message.RequestTime = requestTime

l.wc <- message
fmt.Println("logprocess foreach success")
}
fmt.Println("logprocess success")
}

func main() {

//定义路径、数据库变量
var path, influxDsn string

//变量path、influxdsn赋值
flag.StringVar(&path, "path", "/Users/luoyan3/go/src/go-grafana-log/access_test.log", "read file path")
flag.StringVar(&influxDsn, "influxDsn", "http://127.0.0.1:8086@admin@@mylogdb@s", "influx data source")
flag.Parse()
fmt.Println("accccccess_log_path",path)

r := &ReadFromFile{
path: path,
}

fmt.Println("readfromfile:", r)


w := &WriteToInfluxDB{
influxDBDsn: influxDsn,
}
fmt.Println("writetoinfluxdb:",w)

lp := &LogProcess{
rc: make(chan []byte, 200),
wc: make(chan *Message, 200),
read: r,
write: w,
}

fmt.Println("logprocess:", lp.wc)


go lp.read.Read(lp.rc)


for i := 0; i <2 ; i++ {
fmt.Println("for one")
go lp.Process()
}

fmt.Println("wccccc", lp.wc)

for i := 0; i <4 ; i++ {
fmt.Println("for two")
go lp.write.Write(lp.wc)
}


m := &Monitor{
startTime: time.Now(),
data: SystemInfo{},
}
m.start(lp)
fmt.Println("success")
}

我这个脚本是可以跑通的。
最后在grafana展示的结果是:
go influxdb grafana 读取日志展示

 

 



最后总结一下,在linux服务器上安装一些东西的时候会有很多报错信息,不要担心,根据报错的内容去谷歌一下看看还需要下载什么,挨个安装就可以了。最后总会安装成功的。

后期自己会把这一套用在自己的一些项目上,可以看看自己项目的log日志对于各个接口的进行监控。

 


推荐阅读
  • 本文介绍了在mac环境下使用nginx配置nodejs代理服务器的步骤,包括安装nginx、创建目录和文件、配置代理的域名和日志记录等。 ... [详细]
  • 基于PgpoolII的PostgreSQL集群安装与配置教程
    本文介绍了基于PgpoolII的PostgreSQL集群的安装与配置教程。Pgpool-II是一个位于PostgreSQL服务器和PostgreSQL数据库客户端之间的中间件,提供了连接池、复制、负载均衡、缓存、看门狗、限制链接等功能,可以用于搭建高可用的PostgreSQL集群。文章详细介绍了通过yum安装Pgpool-II的步骤,并提供了相关的官方参考地址。 ... [详细]
  • 本文介绍了Python高级网络编程及TCP/IP协议簇的OSI七层模型。首先简单介绍了七层模型的各层及其封装解封装过程。然后讨论了程序开发中涉及到的网络通信内容,主要包括TCP协议、UDP协议和IPV4协议。最后还介绍了socket编程、聊天socket实现、远程执行命令、上传文件、socketserver及其源码分析等相关内容。 ... [详细]
  • 本文讨论了在Windows 8上安装gvim中插件时出现的错误加载问题。作者将EasyMotion插件放在了正确的位置,但加载时却出现了错误。作者提供了下载链接和之前放置插件的位置,并列出了出现的错误信息。 ... [详细]
  • Metasploit攻击渗透实践
    本文介绍了Metasploit攻击渗透实践的内容和要求,包括主动攻击、针对浏览器和客户端的攻击,以及成功应用辅助模块的实践过程。其中涉及使用Hydra在不知道密码的情况下攻击metsploit2靶机获取密码,以及攻击浏览器中的tomcat服务的具体步骤。同时还讲解了爆破密码的方法和设置攻击目标主机的相关参数。 ... [详细]
  • Android Studio Bumblebee | 2021.1.1(大黄蜂版本使用介绍)
    本文介绍了Android Studio Bumblebee | 2021.1.1(大黄蜂版本)的使用方法和相关知识,包括Gradle的介绍、设备管理器的配置、无线调试、新版本问题等内容。同时还提供了更新版本的下载地址和启动页面截图。 ... [详细]
  • 解决Cydia数据库错误:could not open file /var/lib/dpkg/status 的方法
    本文介绍了解决iOS系统中Cydia数据库错误的方法。通过使用苹果电脑上的Impactor工具和NewTerm软件,以及ifunbox工具和终端命令,可以解决该问题。具体步骤包括下载所需工具、连接手机到电脑、安装NewTerm、下载ifunbox并注册Dropbox账号、下载并解压lib.zip文件、将lib文件夹拖入Books文件夹中,并将lib文件夹拷贝到/var/目录下。以上方法适用于已经越狱且出现Cydia数据库错误的iPhone手机。 ... [详细]
  • 本文介绍了在Windows环境下如何配置php+apache环境,包括下载php7和apache2.4、安装vc2015运行时环境、启动php7和apache2.4等步骤。希望对需要搭建php7环境的读者有一定的参考价值。摘要长度为169字。 ... [详细]
  • Linux如何安装Mongodb的详细步骤和注意事项
    本文介绍了Linux如何安装Mongodb的详细步骤和注意事项,同时介绍了Mongodb的特点和优势。Mongodb是一个开源的数据库,适用于各种规模的企业和各类应用程序。它具有灵活的数据模式和高性能的数据读写操作,能够提高企业的敏捷性和可扩展性。文章还提供了Mongodb的下载安装包地址。 ... [详细]
  • CentOS 6.5安装VMware Tools及共享文件夹显示问题解决方法
    本文介绍了在CentOS 6.5上安装VMware Tools及解决共享文件夹显示问题的方法。包括清空CD/DVD使用的ISO镜像文件、创建挂载目录、改变光驱设备的读写权限等步骤。最后给出了拷贝解压VMware Tools的操作。 ... [详细]
  • 本文介绍了Windows操作系统的版本及其特点,包括Windows 7系统的6个版本:Starter、Home Basic、Home Premium、Professional、Enterprise、Ultimate。Windows操作系统是微软公司研发的一套操作系统,具有人机操作性优异、支持的应用软件较多、对硬件支持良好等优点。Windows 7 Starter是功能最少的版本,缺乏Aero特效功能,没有64位支持,最初设计不能同时运行三个以上应用程序。 ... [详细]
  • 本文介绍了在CentOS上安装Python2.7.2的详细步骤,包括下载、解压、编译和安装等操作。同时提供了一些注意事项,以及测试安装是否成功的方法。 ... [详细]
  • RouterOS 5.16软路由安装图解教程
    本文介绍了如何安装RouterOS 5.16软路由系统,包括系统要求、安装步骤和登录方式。同时提供了详细的图解教程,方便读者进行操作。 ... [详细]
  • CEPH LIO iSCSI Gateway及其使用参考文档
    本文介绍了CEPH LIO iSCSI Gateway以及使用该网关的参考文档,包括Ceph Block Device、CEPH ISCSI GATEWAY、USING AN ISCSI GATEWAY等。同时提供了多个参考链接,详细介绍了CEPH LIO iSCSI Gateway的配置和使用方法。 ... [详细]
  • 如何查询zone下的表的信息
    本文介绍了如何通过TcaplusDB知识库查询zone下的表的信息。包括请求地址、GET请求参数说明、返回参数说明等内容。通过curl方法发起请求,并提供了请求示例。 ... [详细]
author-avatar
乱七八糟的孤岛_217
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有