【Go语言开发】将logrus日志送到elasticsearch构成elk体系

这篇具有很好参考价值的文章主要介绍了【Go语言开发】将logrus日志送到elasticsearch构成elk体系。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

写在前面

这篇文章我们来讲讲怎么把logrus日志送到es。

使用的日志库是 github.com/sirupsen/logrus,由于这个包中的日志对象是可以接入很多个hook的,所以我们可以使用hook来接入 elasticsearch 来操作 。

hook 就是钩子,当设置hook在某个点之后,hook会执行这个点之后异步进行。
比如让我们把hook设置到log日志的地方,当我们log日志的时候,就会异步执行hook。

1. logrus对象创建

先定义一个logrus对象

var LogrusObj *logrus.Logger

初始化这个logrus

func InitLog() {
	if LogrusObj != nil {
		src, _ := setOutputFile()	// 设置输出
		LogrusObj.Out = src
		return
	}
	logger := logrus.New() 	// 实例化
	src, _ := setOutputFile()
	logger.Out = src	// 设置输出
	logger.SetLevel(logrus.DebugLevel)	// 设置日志级别
	// 设置日志格式
	logger.SetFormatter(&logrus.JSONFormatter{
		TimestampFormat: "2006-01-02 15:04:05",
	})
	LogrusObj = logger
}

上面函数方法中设置的src是日志输出的文件路径,也就是相当于类似下面这种日志文件。
【Go语言开发】将logrus日志送到elasticsearch构成elk体系,遇见Golang,拥抱未来,golang,elasticsearch,elk

我们用天数来进行日志文件的区分。日志文件如果不存在就创建,存在就进行添加写入日志。

func setOutputFile() (*os.File, error) {
	now := time.Now()
	logFilePath := ""
	if dir, err := os.Getwd(); err == nil {
		logFilePath = dir + "/logs/" // 日志文件存储路径
	}
	_, err := os.Stat(logFilePath)
	if os.IsNotExist(err) {
		if err := os.MkdirAll(logFilePath, 0777); err != nil {
			log.Println(err.Error())
			return nil, err
		}
	}
	logFileName := now.Format("2006-01-02") + ".log"
	// 日志文件
	fileName := path.Join(logFilePath, logFileName)
	if _, err := os.Stat(fileName); err != nil {
		if _, err := os.Create(fileName); err != nil {
			log.Println(err.Error())
			return nil, err
		}
	}
	// 写入文件
	src, err := os.OpenFile(fileName, os.O_APPEND|os.O_WRONLY, os.ModeAppend)
	if err != nil {
		log.Println(err)
		return nil, err
	}
	return src, nil
}

至此我们的logrus对象就添加成功了,我们来测试一下。

func TestLogrus(t *testing.T) {
	InitLog()
	LogrusObj.Infoln("测试日志文件")
}

【Go语言开发】将logrus日志送到elasticsearch构成elk体系,遇见Golang,拥抱未来,golang,elasticsearch,elk

2. logrus hook

2.1 初始化ES

我们这里用的 es 包是 elastic "github.com/elastic/go-elasticsearch"
定义一个es client对象。

var EsClient *elastic.Client

初始化es client对象

// InitEs 初始化es
func InitEs() {
	esConn := fmt.Sprintf("http://%s:%s", "localhost", "9200")
	cfg := elastic.Config{
		Addresses: []string{esConn},
	}
	client, err := elastic.NewClient(cfg)
	if err != nil {
		log.Panic(err)
	}
	EsClient = client
}

2.2 初始化hook

我们这里用的hook是 github.com/CocaineCong/eslogrus 这是我之前封装的一个 logrus 到 es 的小hook。

func EsHookLog() *eslogrus.ElasticHook {
	hook, err := eslogrus.NewElasticHook(EsClient, "localhost", logrus.DebugLevel, "index")
	if err != nil {
		log.Panic(err)
	}
	return hook
}

调用 eslogrus 包中的 NewElasticHook 方法,传入 es client 对象,es的host,以及日志的输出等级和日志所存储的index。

然后在创建logrus的init函数中,也就是InitLog函数的最后,加入hook即可

hook := es.EsHookLog()
logger.AddHook(hook)

2.3 效果展示

先使用docker启动es,新建docker-compose.yml文件

version: '3.7'

services:
  elasticsearch:
    image: elasticsearch:8.4.2
    container_name: elasticsearch
    environment:
      bootstrap.memory_lock: "true"
      ES_JAVA_OPTS: "-Xms512m -Xmx512m"
      discovery.type: single-node
      ingest.geoip.downloader.enabled: "false"
      TZ: Asia/Shanghai
      xpack.security.enabled: "false"
    healthcheck:
      test: ["CMD-SHELL", "curl -sf http://localhost:9200/_cluster/health || exit 1"] #⼼跳检测,成功之后不再执⾏后⾯的退出
      interval: 60s #⼼跳检测间隔周期
      timeout: 10s
      retries: 3
      start_period: 60s #⾸次检测延迟时间
    ulimits:
      memlock:
        soft: -1
        hard: -1
    volumes:
      - /usr/local/elasticsearch/data:/usr/local/elasticsearch/data
      - /usr/local/elasticsearch/config/es/config:/usr/local/elasticsearch/config
    ports:
      - "9200:9200"
    restart: always

【Go语言开发】将logrus日志送到elasticsearch构成elk体系,遇见Golang,拥抱未来,golang,elasticsearch,elk
根目录下执行

docker-compose -f docker-compose.yml up -d

结果
【Go语言开发】将logrus日志送到elasticsearch构成elk体系,遇见Golang,拥抱未来,golang,elasticsearch,elk
看到这个 status 是 up 的状态即可。
【Go语言开发】将logrus日志送到elasticsearch构成elk体系,遇见Golang,拥抱未来,golang,elasticsearch,elk

然后我们浏览器访问 http://localhost:9200/ 出现以下信息即可
【Go语言开发】将logrus日志送到elasticsearch构成elk体系,遇见Golang,拥抱未来,golang,elasticsearch,elk

然后我们再执行一次即可,注意我们的初始化一定要先初始化ES再初始化log。因为log里面用到了es。

这也提到了go中的init函数,在实际开发中,我们不要使用init函数,因为这个init函数是不可控的,不可控意味着这个顺序是不可控的,最好自己手动init。

func TestLogrus(t *testing.T) {
	InitEs()
	InitLog()
	LogrusObj.Infoln("测试日志文件")
}

结果如下
【Go语言开发】将logrus日志送到elasticsearch构成elk体系,遇见Golang,拥抱未来,golang,elasticsearch,elk
验证一下

curl --location 'http://localhost:9200/index/_search'\?pretty

我们请求一下这个es的查询接口,以及把我们的日志信息放进去了。 index 就是我们的索引,_search就是搜索功能,pretty只是让展示好看一点而已。

【Go语言开发】将logrus日志送到elasticsearch构成elk体系,遇见Golang,拥抱未来,golang,elasticsearch,elk

下面我们来解析一下eslogrus包中所做的东西,看看我们的log是如何hook到es的!

3. eslogrus

接下来,我们来讲一下eslogrus包是如何 hook 到 es 的

定义一个ES的hook

type ElasticHook struct {
	client    *elastic.Client    // es的客户端
	host      string             // es 的 host
	index     IndexNameFunc      // 获取索引的名字
	levels    []logrus.Level     // 日志的级别 info,error
	ctx       context.Context    // 上下文
	ctxCancel context.CancelFunc // 上下文cancel的函数,
	fireFunc  fireFunc           // 需要实现这个
}

定义发送到es的一个消息结构体

// 发送到es的信息结构
type message struct {
	Host      string
	Timestamp string `json:"@timestamp"`
	Message   string
	Data      logrus.Fields
	Level     string
}

新建es hook对象的函数

// NewElasticHook 新建一个es hook对象
func NewElasticHook(client *elastic.Client, host string, level logrus.Level, index string) (*ElasticHook, error) {
	return NewElasticHookWithFunc(client, host, level, func() string { return index })
}

func NewElasticHookWithFunc(client *elastic.Client, host string, level logrus.Level, indexFunc IndexNameFunc) (*ElasticHook, error) {
	return newHookFuncAndFireFunc(client, host, level, indexFunc, syncFireFunc)
}

新建一个hook

func newHookFuncAndFireFunc(client *elastic.Client, host string, level logrus.Level, indexFunc IndexNameFunc, fireFunc fireFunc) (*ElasticHook, error) {
	var levels []logrus.Level
	for _, l := range []logrus.Level{
		logrus.PanicLevel,
		logrus.FatalLevel,
		logrus.ErrorLevel,
		logrus.WarnLevel,
		logrus.InfoLevel,
		logrus.DebugLevel,
	} {
		if l <= level {
			levels = append(levels, l)
		}
	}

	ctx, cancel := context.WithCancel(context.TODO())

	return &ElasticHook{
		client:    client,
		host:      host,
		index:     indexFunc,
		levels:    levels,
		ctx:       ctx,
		ctxCancel: cancel,
		fireFunc:  fireFunc,
	}, nil
}

创建消息

// createMessage 创建信息
func createMessage(entry *logrus.Entry, hook *ElasticHook) *message {
	level := entry.Level.String()

	if e, ok := entry.Data[logrus.ErrorKey]; ok && e != nil {
		if err, ok := e.(error); ok {
			entry.Data[logrus.ErrorKey] = err.Error()
		}
	}

	return &message{
		hook.host,
		entry.Time.UTC().Format(time.RFC3339Nano),
		entry.Message,
		entry.Data,
		strings.ToUpper(level),
	}
}

异步发送到es

func syncFireFunc(entry *logrus.Entry, hook *ElasticHook) error {
	data, err := json.Marshal(createMessage(entry, hook))

	req := esapi.IndexRequest{
		Index:   hook.index(),
		Body:    bytes.NewReader(data),
		Refresh: "true",
	}

	res, err := req.Do(hook.ctx, hook.client)
	if err != nil {
		log.Fatalf("Error getting response: %s", err)
	}
	var r map[string]interface{}
	if err := json.NewDecoder(res.Body).Decode(&r); err != nil {
		log.Printf("Error parsing the response body: %s", err)
	} else {
		// Print the response status and indexed document version.
		log.Printf("[%s] %s; version=%d", res.Status(), r["result"], int(r["_version"].(float64)))
	}
	return err
}

这两个是必须要实现的

// Fire 实现 logrus hook 必须要的接口函数
func (hook *ElasticHook) Fire(entry *logrus.Entry) error {
	return hook.fireFunc(entry, hook)
}

// Levels 实现 logrus hook 必须要的接口函数
func (hook *ElasticHook) Levels() []logrus.Level {
	return hook.levels
}

以上就是所有 eslogrus 的代码了,短短几十行就能实现 logrus 到 es 的异步了。文章来源地址https://www.toymoban.com/news/detail-656040.html

到了这里,关于【Go语言开发】将logrus日志送到elasticsearch构成elk体系的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • ELK 企业级日志分析系统的概念、ELK Elasticsearch 集群部署

    1、ELK 简介 ELK平台是一套完整的日志集中处理解决方案,将 ==ElasticSearch、Logstash 和 Kiabana ==三个开源工具配合使用, 完成更强大的用户对日志的查询、排序、统计需求。 ElasticSearch 是基于Lucene(一个全文检索引擎的架构)开发的分布式存储检索引擎,用来存储各类日志。 E

    2024年02月16日
    浏览(36)
  • Linux:ELK:日志分析系统(使用elasticsearch集群)

    1. 将日志进行集中化管理(beats) 2. 将日志格式化(logstash) 将其安装在那个上面就对那个进行监控 3. 对格式化后的数据进行索引和存储(elasticsearch) 4. 前端数据的展示(kibana) 要准备安装包 elasticsearch elasticsearch-head kibana logstash node phantomjs 这些安装包都在网上很好找,自

    2024年02月14日
    浏览(32)
  • Filebeat+Kafka+ELK日志采集(五)——Elasticsearch

    1、下载 2、解压: 3、配置 启动Elasticsearch,进入/bin目录下 ./elasticsearch ,不出意外的外会报以下错误: 报错1:能打开的文件或进程数太低。 解决方法: 修改/etc/security/limits.conf 配置文件,添加配置如下: 报错2: 解决方法: 修改/etc/sysctl.conf 配置文件,添加配置如下: 修

    2024年02月05日
    浏览(41)
  • elasticsearch定期删除策略 - 日志分析系统ELK搭建

    日志分析系统ELK搭建 ELK ELK是日志收集、索引与检索三件套,包含了三个组件 ElasticSearch Logstash Kibana 其中ElasticSearch完成日志的索引,并提供查询接口,Logstash完成日志的收集,Kibana则提供可视化展示 有了ELK,我们不再需要到线上的每一台机器上grep日志,而且能可视化查询任

    2023年04月08日
    浏览(30)
  • ELK(Elasticsearch+Logstash+Kibana)日志分析系统

    目录 前言 一、ELK日志分析系统概述 1、三大组件工具介绍 1.1 Elasticsearch 1.1.1 Elasticsearch概念 1.1.2 关系型数据库和ElasticSearch中的对应关系 1.1.3 Elasticsearch提供的操作命令 1.2 Logstash 1.2.1 Logstash概念 1.2.2 Logstash的主要组件 1.2.3 Logstash主机分类 1.2.4 Logstash工作过程 1.3 Kiabana 2、

    2024年04月25日
    浏览(30)
  • ELK日志平台(elasticsearch+logstash+kibana)搭建

    提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 为了实现分布式日志数据统一收集,实现集中式查询和管理 故障排查 安全信息和事件管理 ELK 是三个开源项目的首字母缩写,这三个项目分别是: Elasticsearch 、 Logstash 和 Kibana 。 • Elasticsearch 是一个搜索

    2024年02月03日
    浏览(31)
  • elk(elasticsearch+logstash+kibana)搭建日志监控平台

    目录 elk架构原理 安装部署elasticsearch 什么是elasticsearch 创建elasticserch docker容器  安装部署kibana 什么是Kinana 创建Kibana docker容器         拉取镜像         创建配置文件:D:Programsdockerkibanakibana.yml          创建并运行kibana容器         验证登录kibana 安装部署logstash 什么

    2024年02月04日
    浏览(50)
  • Elasticsearch基本操作+集成SpringBoot+ELK日志平台搭建

    Elasticsearch是一种开源的搜索和分析引擎,最初由开源搜索引擎Lucene的作者于2010年创建。它提供了一个可伸缩、高性能的搜索和数据分析平台,可用于多种用途,包括 文本搜索、应用程序性能监控、业务分析、日志聚合 等。 Elasticsearch使用分布式架构,可以处理大量数据并实

    2024年02月06日
    浏览(50)
  • golang 日志库logrus实践

    logrus 完全兼容标准的 log 库,还支持文本、JSON 两种日志输出格式。很多知名的开源项目都使用了这个库,如大名鼎鼎的 docker。 第三方库需要先安装: 后使用: logrus 的使用非常简单,与标准库 log 类似。 logrus 支持更多的日志级别: Panic :记录日志,然后 panic 。 Fatal :致

    2024年02月17日
    浏览(37)
  • 1-ELK+ Elasticsearch+head+kibana、企业内部日志分析系统

    ELK由ElasticSearch、Logstash和Kibana三个开源工具组成: 概念图    1、Elasticsearch: ElasticSearch是一个基于Lucene的开源分布式搜索服务。 只搜索和分析日志 特点:分布式,零配置,自动发现,索引自动分片,索引副本机制,多数据源等。它提供了一个分布式多用户能力的全文搜索引

    2024年02月06日
    浏览(38)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包