GoLang日志监控系统实现

目录
  • 日志监控系统
  • 项目简答介绍
  • 系统架构
  • 读取模块具体实现
  • 日志解析模块

日志监控系统

Nginx(日志文件) -> log_process (实时读取解析写入) -> influxdb(存储) ->grafana(前端日志展示器)

influxdb 属于GO语言编写的开源的时序型数据,着力于高性能 查询与存储时序型数据,influxdb 广泛的应用于存储系统的监控数据,IOT行业的实时数据。

目前市面上流行 TSDB(时序型处理数据库):influxDB, TimescaleDB, QuestDBinfluxDB 类似于NOSQL体验,自动适合标记集模型的技术的数据集;TimescaleDB 与 postgreSQL 兼容, 更加适合物联网数据,与PostgreSQL更好的兼容QuestDB: 支持InfluxDB内联协议和PostgreSQL, 但是生态问题比较大

项目简答介绍

本日志系统 DEMO,但是可以直接使用到生产环境上面,使用LOG_Process 读取Nginx ./Access.log, 使用influxDB 进行存取

log_process -path ./access.log influxdsn http://127.0.0.1:8086@imooc@imoocpass@immoc@s

常见并发模型

  • 解决C10k 的问题 采用异步非阻塞的模型(Nginx, libevent, NodeJS)-- 问题 复杂度高 大量回调函数
  • 协程(Go,Erlang, lua): 协线性函数一样写代码;理解根加轻量级别的线程
  • 程序并行执行 go foo() // 执行函数
  • mgs:= <- c 多个gorountine 需要进行通信
  • select 从多个channel 中读取数据 ,多个 channel 随机选择一个进行消费
  • 并发: 一个任务通过调度器让任务看起来运行 属于单核CPU(逻辑运行)对于IO密集型比较友好
  • 并行:任务真正的运行

在go 语言中 并发执行 ,使用三个不同 gorountine, 一个负责装填,一个负责运输,一个负责处理 ,让程序并发的运行起来,让任务更加的职责单一化 这种思想 也可以将 日志解析读取,写入模块进行单独小模块,每个模块让使用gorountine ,通过channel 数据交互,至于这么多gorountine 是在一个CPU调度执行还是分配到多个CPU上进行执行 ,取决于系统.

go 语言有自己的调度器, go fun() 属于一个独立的工作单元,go的调度器,根据每个可用的物理处理器分配一个逻辑处理器,通过这个逻辑处理器对 独立单元进行处理,
通过设置: runtime.GOMAXPROCS(1)//给调度器分配多小个具体的逻辑处理器
一台服务器的 物理处理器越多 ,go 获取到逻辑处理器也越多,导致器允许速度越快。 参考:传送门

系统架构

日志解析的基本流程化的伪函数,如下的函数有两个缺陷,解析介入和解析后输出只能写死,所以需要进行扩展,接口方式进行扩展

package main
import (
	"fmt"
	"strings"
	"time"
)
/**
* 日志解析系统分为: 解析,读取,写入
 */
type LogProcess struct {
	path        string      // 读取文件路径
	influxDBDsn string      // influx data source
	rc          chan string // read module to process
	wc          chan string // process to influx
}
// 返回函数使用 指针, 结构体很大 不需要进行拷贝 性能优化
func (l *LogProcess) ReadFromFile() {
	// 文件读取模块
	line := "message"
	l.rc <- line
}
func (l *LogProcess) Process() {
	// 文件解析模块
	data := <-l.rc
	l.wc <- strings.ToUpper(data)
}
func (l *LogProcess) writeToInfluxDB() {
	fmt.Println(<-l.wc)
}
func main() {
	// lp 引用类型
	lp := &LogProcess{
		path:        "./tmp/access.log",
		influxDBDsn: "username&password...",
		rc:          make(chan string),
		wc:          make(chan string),
	}
	// tree goroutine run
	go lp.ReadFromFile()
	go lp.Process()
	// 需要定义 chan 将 Process 数据 传递给 influxDB
	go lp.writeToInfluxDB()
	time.Sleep(2 * time.Second)
}

接口方式约束 输入和输出 进行优化

package main
import (
	"fmt"
	"strings"
	"time"
)
/**
* 日志解析系统分为: 解析,读取,写入
 */
type LogProcess struct {
	rc    chan string // read module to process
	wc    chan string // process to influx
	read  Read
	write Writer
}
func (l *LogProcess) Process() {
	// 文件解析模块
	data := <-l.rc
	l.wc <- strings.ToUpper(data)
}
type Writer interface {
	writer(wc chan string)
}
type WriteToInfluxDB struct {
	influxDBDsn string // influx data source
}
func (w *WriteToInfluxDB) writer(wc chan string) {
	fmt.Println(<-wc)
}
type Read interface {
	read(rc chan string)
}
type ReadFromFile struct {
	path string // 读取文件
}
func (r *ReadFromFile) read(rc chan string) {
	// 读取模块
	line := "message"
	rc <- line
}
func main() {
	// lp 引用类型
	r := &ReadFromFile{
		path: "./tmp/access.log",
	}
	w := &WriteToInfluxDB{
		influxDBDsn: "username&password"}
	lp := &LogProcess{
		rc:    make(chan string),
		wc:    make(chan string),
		read:  r,
		write: w,
	}
	// 通过接口方式 约束其功能
	go lp.read.read(lp.rc)
	go lp.Process()
	go lp.write.writer(lp.wc)
	// 通过参数注入方式
	time.Sleep(2 * time.Second)
}

读取模块具体实现

从上次读取光标后开始逐行进行读取,无需每次都全部文件读取

package main
import (
	"bufio"
	"fmt"
	"io"
	"os"
	"strings"
	"time"
)
/**
* 日志解析系统分为: 解析,读取,写入
 */
type LogProcess struct {
	rc    chan []byte // read module to process
	wc    chan string // process to influx
	read  Read
	write Writer
}
func (l *LogProcess) Process() {
	// 文件解析模块
	for v := range l.rc {
		l.wc <- strings.ToUpper(string(v))
	}
}
type Writer interface {
	writer(wc chan string)
}
type WriteToInfluxDB struct {
	influxDBDsn string // influx data source
}
func (w *WriteToInfluxDB) writer(wc chan string) {
	// wc 通道另外一种读取方式
	for x := range wc {
		fmt.Println(x)
	}
}
type Read interface {
	read(rc chan []byte)
}
type ReadFromFile struct {
	path string // 读取文件
}
func (r *ReadFromFile) read(rc chan []byte) {
	// 实时系统: 从文件末尾逐行进行读取
	f, err := os.Open(r.path)
	if err != nil {
		panic(fmt.Sprintln("open file error:%s", err.Error()))
	}
	// 文件末尾最开始进行读取
	f.Seek(0, 2)
	rd := bufio.NewReader(f)
	for {
		line, err := rd.ReadBytes('\n')
		if err == io.EOF {
			// d读取到文件末尾, 日志还没有写入
			time.Sleep(500 * time.Millisecond)
			continue
		} else if err != nil {
			panic(fmt.Sprintln("ReadBytes error:%s", err.Error()))
		}
		rc <- line[:len(line)-1]
	}
}
func main() {
	// lp 引用类型
	r := &ReadFromFile{
		path: "H:\\code\\goprogarm\\src\\access.log",
	}
	w := &WriteToInfluxDB{
		influxDBDsn: "username&password"}
	lp := &LogProcess{
		rc:    make(chan []byte),
		wc:    make(chan string),
		read:  r,
		write: w,
	}
	// 通过接口方式 约束其功能
	go lp.read.read(lp.rc)
	go lp.Process()
	go lp.write.writer(lp.wc)
	// 通过参数注入方式
	time.Sleep(100 * time.Second)
}

日志解析模块

  • 冲Read Chan 中读取每一行数据
  • 正则方式提取所需要的监控数据
  • 将数据写入到influxDB
package main
import (
	"bufio"
	"fmt"
	"io"
	"log"
	"os"
	"regexp"
	"strconv"
	"time"
)
/**
* 日志解析系统分为: 解析,读取,写入
 */
type LogProcess struct {
	rc    chan []byte // read module to process
	wc    chan *Message // process to influx
	read  Read
	write Writer
}
//日志写入结构体
type Message struct {
	TimeLocal time.Time
	BytesSent int
	Path, Method, Scheme, Status string
	UpstreamTime, RequestTime float64
}
func (l *LogProcess) Process() {
	// 通过正则表达式进行解析数据
	r := regexp.MustCompile(`(\s*)`)
	loc, _ := time.LoadLocation("Asia/shanghai")
	// 文件解析模块
	for v := range l.rc {
		ret := r.FindStringSubmatch(string(v))
		if len(ret) != 13 {
			log.Println("FindStringSub match fail:", string(v))
			continue
		}
		message := &Message{
		}
		location, err := time.ParseInLocation("02/Jan/2006:15:04:05 +0000", ret[4], loc)
		if err != nil {
			log.Println("ParseInLocation fail:", err.Error(), ret[4])
		}
		message.TimeLocal = location
		// 字符串类型转换成int
		atoi, err := strconv.Atoi(ret[8])
		if err != nil {
			log.Println("strconv.Atoi fail:", err.Error(), ret[4])
		}
		message.BytesSent = atoi
		l.wc <- message
	}
}
type Writer interface {
	writer(wc chan *Message)
}
type WriteToInfluxDB struct {
	influxDBDsn string // influx data source
}
func (w *WriteToInfluxDB) writer(wc chan *Message) {
	// wc 通道另外一种读取方式
	for x := range wc {
		fmt.Println(x)
	}
}
type Read interface {
	read(rc chan []byte)
}
type ReadFromFile struct {
	path string // 读取文件
}
func (r *ReadFromFile) read(rc chan []byte) {
	// 实时系统: 从文件末尾逐行进行读取
	f, err := os.Open(r.path)
	if err != nil {
		panic(fmt.Sprintf("open file error:%s\n", err.Error()))
	}
	// 文件末尾最开始进行读取
	f.Seek(0, 2)
	rd := bufio.NewReader(f)
	for {
		line, err := rd.ReadBytes('\n')
		if err == io.EOF {
			// d读取到文件末尾, 日志还没有写入
			time.Sleep(500 * time.Millisecond)
			continue
		} else if err != nil {
			panic(fmt.Sprintf("ReadBytes error:%s\n", err.Error()))
		}
		rc <- line[:len(line)-1]
	}
}
func main() {
	// lp 引用类型
	r := &ReadFromFile{
		path: "H:\\code\\goprogarm\\src\\access.log",
	}
	w := &WriteToInfluxDB{
		influxDBDsn: "username&password"}
	lp := &LogProcess{
		rc:    make(chan []byte),
		wc:    make(chan *Message),
		read:  r,
		write: w,
	}
	// 通过接口方式 约束其功能
	go lp.read.read(lp.rc)
	go lp.Process()
	go lp.write.writer(lp.wc)
	// 通过参数注入方式
	time.Sleep(100 * time.Second)
}

到此这篇关于GoLang日志监控系统实现的文章就介绍到这了,更多相关GoLang日志监控内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • Django超详细讲解图书管理系统的实现

    目录 1.用户管理模块 2.图书管理模块 3.数据管理模块 4.前端模块 项目使用python开发,采用Django框架,数据库采用MySQL,根据用户人员的不同分成两套系统,分别是学生系统和管理员系统,功能模块具体分成四个,分别是用户管理模块.图书管理模块.数据管理模块.前端模块. 1.用户管理模块 用户管理模块实现的功能包括用户注册(分为学生注册和管理员注册).用户信息修改.用户登录和判定 用户注册和登录 views.py中用户注册及登陆判定代码段 def login(request):#登

  • Go开源项目分布式唯一ID生成系统

    目录 前言 项目背景 项目使用 HTTP 方式 gRPC 方式 本地开发 项目架构 前言 今天跟大家介绍一个开源项目:id-maker,主要功能是用来在分布式环境下生成唯一 ID.上周停更了一周,也是用来开发和测试这个项目的相关代码. 美团有一个开源项目叫 Leaf,使用 Java 开发.本项目就是在此思路的基础上,使用 Go 开发实现的. 项目整体代码量并不多,不管是想要在实际生产环境中使用,还是想找个项目练手,我觉得都是一个不错的选择. 项目背景 在大部分系统中,全局唯一 ID 都是一个强需

  • Go语言实战之实现一个简单分布式系统

    目录 引子 思路 实战 节点通信 主节点 工作节点 将它们放在一起 代码效果 总结 引子 如今很多云原生系统.分布式系统,例如 Kubernetes,都是用 Go 语言写的,这是因为 Go 语言天然支持异步编程,而且静态语言能保证应用系统的稳定性.笔者的开源项目 Crawlab 作为爬虫管理平台,也应用到了分布式系统.本篇文章将介绍如何用 Go 语言编写一个简单的分布式系统. 思路 在开始写代码之前,我们先思考一下需要实现些什么. 主节点(Master Node):中控系统,相当于军队中的指挥官

  • Golang 获取系统信息的实现

    目录 问题提出 golang 的编译选项 获取系统信息 本文介绍获取系统信息的方法,另外给出根据不同系统编译的方法. 问题提出 由于多年来接触了不同系统的兼容工程,对使用宏区分不同的代码一直有一种莫名的感觉.像 Linux 内核中就有很多这样的代码,coreboot 中有,nRF52 SDK中也有.在实现的工程库也要往这方向考虑,比如线程库和socket库.当接触 golang 后,因其跨平台,编码快,所以在工作中也使用了.但并不是所有代码都是跨平台,像 syscall这样的包,就无法做到.最近

  • Go-客户信息关系系统的实现

    目录 项目需求分析 项目的界面设计 主菜单界面 添加客户界面 删除客户界面 客户列表界面 客户关系管理系统的程序框架图 项目功能实现-显示主菜单和完成退出软件功能 项目功能实现-完成显示客户列表的功能 项目功能实现-添加客户的功能 项目功能实现-完成删除客户的功能 项目需求分析 模拟实现基于文本界面的<客户信息管理软件>. 该软件能够实现对客户对象的插入.修改和删除(用切片实现),并能够打印客户明细表 项目的界面设计 主菜单界面 添加客户界面 删除客户界面 客户列表界面 客户关系管理系统的程序

  • GoLang日志监控系统实现

    目录 日志监控系统 项目简答介绍 系统架构 读取模块具体实现 日志解析模块 日志监控系统 Nginx(日志文件) -> log_process (实时读取解析写入) -> influxdb(存储) ->grafana(前端日志展示器) influxdb 属于GO语言编写的开源的时序型数据,着力于高性能 查询与存储时序型数据,influxdb 广泛的应用于存储系统的监控数据,IOT行业的实时数据. 目前市面上流行 TSDB(时序型处理数据库):influxDB, TimescaleDB,

  • Python pyinotify日志监控系统处理日志的方法

    前言 最近项目中遇到一个用于监控日志文件的Python包pyinotify,结合自己的项目经验和网上的一些资料总结一下,总的原理是利用pyinotify模块监控日志文件夹,当日志到来的情况下,触发相应的函数进行处理,处理完毕后删除日志文件的过程,下面就着重介绍下pyinotify pyinotify Pyinotify是一个Python模块,用来监测文件系统的变化. Pyinotify依赖于Linux内核的功能-inotify(内核2.6.13合并). inotify的是一个事件驱动的通知器,其

  • golang日志框架之logrus的使用

    golang日志库 golang标准库的日志框架非常简单,仅仅提供了print,panic和fatal三个函数对于更精细的日志级别.日志文件分割以及日志分发等方面并没有提供支持.所以催生了很多第三方的日志库,但是在golang的世界里,没有一个日志库像slf4j那样在Java中具有绝对统治地位.golang中,流行的日志框架包括logrus.zap.zerolog.seelog等. logrus是目前Github上star数量最多的日志库,目前(2018.08,下同)star数量为8119,fo

  • Sentry错误日志监控使用方法解析

    无论作为新手还是老手程序员在程序的开发过程中,代码运行时难免会抛出异常,而且项目在部署到测试.生产环境后,我们便不可能像在开发时那样容易的及时发现处理错误了.一般我们都是在错误发生一段时间后,错误信息才会传递到开发人员那里,然后一顿操作查看程序运行的日志,就熟练使用awk和grep去分析日志,但是往往我们会因为日志中缺少上下文关系,导致很难分析真正的错误是什么. Sentry由此应运而生成为了解决这个问题的一个很好的工具,设计了诸多特性帮助开发者更快.更方面.更直观的监控错误信息. 关于日志管理

  • shell脚本监控系统负载、CPU和内存使用情况

    在没有nagios监控软件的情况下,只要服务器能上互联网,就可通过发邮件的方式来提醒管理员系统负载与CPU占用的使用情况. 一.安装linux下面的一个邮件客户端msmtp软件(类似于一个foxmail的工具) 1.下载安装:  http://downloads.sourceforge.net/msmtp/msmtp-1.4.16.tar.bz2?modtime=1217206451&big_mirror=0 复制代码 代码如下: # tar jxvf msmtp-1.4.16.tar.bz2

  • eBay 打造基于 Apache Druid 的大数据实时监控系统

    首先需要注意的是,本文即将提到的 Druid,并非阿里巴巴的 Druid 数据库连接池,而是另一个大数据场景下的解决方案:Apache Druid. Apache Druid 是一个用于大数据实时查询和分析的高容错.高性能开源分布式时序数据库系统,旨在快速处理大规模的数据,并能够实现快速查询和分析.尤其是当发生代码部署.机器故障以及其他产品系统遇到宕机等情况时,Druid 仍能够保持 100% 正常运行.创建 Druid 的最初意图主要是为了解决查询延迟问题,当时试图使用 Hadoop 来实现交

  • 浅析springcloud 整合 zipkin-server 内存日志监控

    Zipkin Zipkin是一款开源的分布式实时数据追踪系统(Distributed Tracking System),基于 Google Dapper的论文设计而来,由 Twitter 公司开发贡献.其主要功能是聚集来自各个异构系统的实时监控数据. Zipkin主要包括四个模块  - Collector           接收或收集各应用传输的数据  - Storage            存储接受或收集过来的数据,当前支持Memory,MySQL,Cassandra,ElasticSea

  • 分布式监控系统之Zabbix主动、被动及web监控的过程详解

    前文我们了解了zabbix的网络发现功能,以及结合action实现自动发现主机并将主机添加到zabbix hosts中,链接指定模板进行监控:回顾请参考https://www.jb51.net/article/200678.htm:今天我们来了解下zabbix的主动监控.被动监控以及web监控相关话题: 1.什么是主动监控?什么是被动监控? 我们知道获取数据的方式有两种,一种是get,一种是push:在zabbix中描述主动监控和被动监控都是站在agent的一方来描述的:我们把agent主动将数

  • golang日志包logger的用法详解

    1. logger包介绍 import "github.com/wonderivan/logger" 在我们开发go程序的过程中,发现记录程序日志已经不是fmt.print这么简单,我们想到的是打印输出能够明确指定当时运行时间.运行代码段,当然我们可以引入go官方自带包 import "log",然后通过log.Printf.log.Println等方式输出,而且默认是日志输出时只带时间的,想要同时输出所运行代码段位置,还需要通过执行一下指定进行相关简单的设置 lo

  • web项目中golang性能监控解析

    目录 性能监控 一.web项目(如gin中) 二.单个的go文件如果查看gc 性能监控 一.web项目(如gin中) 1.使用ginpprof import "github.com/DeanThompson/ginpprof" router := gin.Default() ginpprof.Wrap(router) 2.使用pprof 只需要在main.go中引入:_ “net/http/pprof” 访问:127.0.0.1:8080/debug/pprof /debug/ppro

随机推荐