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

news2024/12/24 2:40:13

写在前面

这篇文章我们来讲讲怎么把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是日志输出的文件路径,也就是相当于类似下面这种日志文件。
在这里插入图片描述

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

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("测试日志文件")
}

在这里插入图片描述

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函数中加入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

在这里插入图片描述
根目录下执行

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

在这里插入图片描述

在这里插入图片描述

看到这个 status 是 up 的状态即可。

然后我们浏览器访问 http://localhost:9200/ 出现以下信息即可
在这里插入图片描述

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

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

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

结果如下
在这里插入图片描述
验证一下

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

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

在这里插入图片描述

以上就是全部内容了,下一章我们来解析一下eslogrus包中所做的东西,了解是如何hook到es的!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/748583.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

第一章 SegFormer(语义分割篇)——SegFormer: 简单高效的基于Transformer的语义分割设计

0.摘要 我们提出了SegFormer,这是一个简单、高效且强大的语义分割框架,它将Transformer与轻量级多层感知机(MLP)解码器结合在一起。 SegFormer具有两个吸引人的特点: 1)SegFormer包含一个新颖的层次结构的…

【C语言】猜数字游戏

问题描述 猜数字游戏是令游戏机随机产生一个100以内的正整数,用户输入一个数对其进行猜测,需要你编写程序自动对其与随机产生的被猜数进行比较,并提示大了(“Too big”),还是小了(“Too small”…

springboot项目target下面没有mapper.xml文件

文件结构是这个样子,mapper.xml文件在resources/mappers/fdms目录下面 通常来说, 将mapper打包到target目录下只需要在maven下面配置 <resources><resource><directory>src/main/resources</directory><filtering>true</filtering><inc…

prometheus采集服务的jmx数据,grafana通过dashboard展示jmx数据

prometheus采集服务的jmx数据&#xff0c;grafana通过dashboard展示jmx数据 一、下载prometheus二、解压prometheus三、查看prometheus目录四、查看prometheus版本五、查看prometheus的配置文件六、启动prometheus七、登陆prometheus八、查看prometheus jmx九、下载grafana十、…

嵌入式内核及驱动开发高级

一、起源 仅devfs&#xff0c;导致开发不方便以及一些功能难以支持&#xff1a; 热插拔 不支持一些针对所有设备的统一操作&#xff08;如电源管理&#xff09; 不能自动mknod 用户查看不了设备信息 设备信息硬编码&#xff0c;导致驱动代码通用性差&#xff0c;即没有分离…

AI实现口语练习技术解决方案

最近AI技术取得了技术上的突破&#xff0c;可以非常智能化的实现人机交互。在应用场景上很自然会想到利用AI来实现口语练习&#xff0c;下面和大家分享AI实现口语练习的AI技术方案和开发流程&#xff0c;只列出的整体思路和概略步骤&#xff0c;具体的步骤可能会根据具体的需求…

HttpClient——入门案例(发送http请求)

前言介绍 总结就是使得可以在java程序中发送http请求。 导入依赖 <dependency><groupId>org.apache.httpcomponents</groupId><artifactId>httpclient</artifactId><version>4.5.13</version></dependency> 发送get请求 用…

分享电商平台美食产品—味尚拉面半干面

很高兴跟您分享电商平台上一款刚推出的热门美食产品——味尚拉面 半干面。 味尚拉面 半干面&#xff0c;由厂家精心制作而成&#xff0c;是一款十分劲道爽口的拉面&#xff0c;让您在繁忙的生活中享受到美味的口感。 作为一款电商平台上备受瞩目的产品&#xff0c;味尚拉面 半干…

​揭示嵌入式系统中的难题和解决方案

嵌入式系统设计和开发过程中存在一些常见难题&#xff0c;下面是这些难题以及相应的解决方案的简要概述。 处理资源受限&#xff1a;嵌入式系统通常具有有限的处理能力、存储容量和能源。解决方案包括&#xff1a;优化算法和数据结构&#xff0c;选择适合的硬件平台&#xff0c…

VUE2教程-基础-简介

Vue.js 是什么 Vue (读音 /vjuː/&#xff0c;类似于 view) 是一套用于构建用户界面的渐进式框架。与其它大型框架不同的是&#xff0c;Vue 被设计为可以自底向上逐层应用。Vue 的核心库只关注视图层&#xff0c;不仅易于上手&#xff0c;还便于与第三方库或既有项目整合。另一…

【教程】爬取和统计Google Scholar上指定关键词的文章信息

转载请注明出处&#xff1a;小锋学长生活大爆炸[xfxuezhang.cn] 目录 背景介绍 未来改进 参考代码 背景介绍 通过自动点击页面来抓取文章信息。这个脚本对于用来看某个关键词在近几年的研究趋势很有用~半自动&#xff1a;当遇到谷歌人机验证&#xff0c;需要手动完成。注意…

SAP MIRO发票过账报错 这个项目不允许输入税

SAP MIRO发票过账报错 这个项目不允许输入税 J3税额0.01为手动输入 原因是含税金额0.08 * J3对应税率&#xff0c;结果保留2位小数大小&#xff0c;系统不允许输入税额

HarmonyOS/OpenHarmony应用开发-Stage模型UIAbility组件使用(四)

UIAbility组件与UI的数据同步 基于HarmonyOS的应用模型&#xff0c;可以通过以下两种方式来实现UIAbility组件与UI之间的数据同步。 1.EventHub&#xff1a;基于发布订阅模式来实现&#xff0c;事件需要先订阅后发布&#xff0c;订阅者收到消息后进行处理。 2.globalThis&…

XSS靶场【1-10关】攻击攻略

文章目录 第一关第二关第三关第四关第五关第六关第七关第八关第九关第十关 通过&#xff08;xss-labs-master&#xff09;[]PHPStudy搭建的XSS靶场1-10关的攻击教程需要下载好XSS靶场源码&#xff0c;导入到phpstudy的WWW目录下攻击主机需要安装BurpSuit、FoxyProxy浏览器插件&…

第三十章:数据库其他调优策略

第三十章&#xff1a;数据库其他调优策略 30.1&#xff1a;数据库调优的措施 调优的目标 尽可能的节省系统资源&#xff0c;以便系统可以提供更大负荷的服务(吞吐量更大)。合理的结构设计和参数调整&#xff0c;以提高用户操作响应的速度。(响应速度更快)。减少系统的瓶颈&…

Win32汇编对话框子控件复习学习

在此已经做了Win32汇编的对话框子控件ListBox和ComboBox&#xff1b; Win32汇编ListBox最简Demo_win32 list列表_bcbobo21cn的博客-CSDN博客 Win32汇编最简ComboBox Demo_bcbobo21cn的博客-CSDN博客 它们的代码是相似的&#xff1b; 以ComboBox为例&#xff1b; 首先是要…

java 如何快速实现异步调用方法

java 如何快速实现异步调用方法 什么是异步编程CompletableFuturejava 演示 什么是异步编程 在实现异步调用之前&#xff0c;我们先了解一下&#xff0c;什么是异步编程&#xff1f;什么场景下适用等等情况。 我们都知道&#xff0c;在传统的同步编程中&#xff0c;当一个操作…

Linux——深度解析IO文件流缓冲区问题(原理详解+代码手撕)

深度剖析缓存区 1.&#x1f4ad;缓冲区介绍1.1&#x1f4ab;什么是缓冲区1.2&#x1f4ab;缓冲区有什么用1.3 &#x1f4ab;缓冲区的初步认识 2.&#x1f4ad;缓存区测试3.&#x1f951;缓冲区是谁提供的3.1测试 一下 在fork&#xff08;&#xff09;之前刷新缓冲区会怎么样&am…

avue 表单绑定值;avue表单项根据某项的值去联动显隐或是联动下拉数据;avue select切换与另外一个select的options联动

效果&#xff1a;发布type为shp时 数据相关的都隐藏&#xff0c;当发布type为postgis时则显示 1.avue表单绑定值 html <avue-form :option"option" v-model"publishForm"></avue-form> js data中定义 data() {return {publishForm: {},optio…

Go语言基础教程:变量、基本数据类型、输出、注释、运算符、if-else条件判断、函数

文章目录 一、变量的使用1.1 定义变量1.2 常量1.3 变量的赋值与内存相关 二、变量基本类型2.1 有符号整型2.2 无符号整型2.3 string类型2.4 bool类型 三、输出3.1 常用打印功能3.2 格式化输出3.3 内置输出方法与fmt的区别 四、注释五、运算符六、条件语句6.1 基本使用6.2 条件嵌…