【Go】go-es统计接口被刷数和ip访问来源

这篇具有很好参考价值的文章主要介绍了【Go】go-es统计接口被刷数和ip访问来源。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

go-es模块统计日志中接口被刷数和ip访问来源

  • 以下是使用go的web框架gin作为后端,展示的统计页面
    【Go】go-es统计接口被刷数和ip访问来源,go,golang,elasticsearch
    【Go】go-es统计接口被刷数和ip访问来源,go,golang,elasticsearch
    【Go】go-es统计接口被刷数和ip访问来源,go,golang,elasticsearch

背景

  • 上面的数据来自elk日志统计。因为elk通过kibana进行展示,但是kibana有一定学习成本且不太能满足定制化的需求,所以考虑用编程的方式对数据进行处理
  • 首先是接口统计,kibana的页面只会在 字段uri 的 top500 进行百分比统计,展示前5条数据,统计不够充分
    【Go】go-es统计接口被刷数和ip访问来源,go,golang,elasticsearch
  • 其次是网关日志,ip来源的采集字段是通过x_forward_for,这记录了各级的代理来源ip。并不能直接对用户的ip进行数据聚合的统计
    • 举例,这里面 “223.104.195.51,192.168.29.135” ,这种数据我需要拿到223.104.195.51,因为这才是用户的ip。所以需要进行编程的处理
      【Go】go-es统计接口被刷数和ip访问来源,go,golang,elasticsearch

环境

  • elk 7.9
https://www.elastic.co/downloads/past-releases/elasticsearch-7-9-3
  • go 1.17 ,gin 1.6.3,go-elasticsearch 7.9.0
# go1.17下载地址
https://go.dev/dl/
# 模块下载
go env -w GOPROXY=https://goproxy.cn,direct
go mod init go-ops  # 本项目的go mod 名字
go get github.com/elastic/go-elasticsearch/v7@v7.9.0
go get github.com/gin-gonic/gin@v1.6.3
  • 前端:layui 和 echarts
# layui下载
http://layui.dotnetcms.cn/res/static/download/layui/layui-v2.6.8.zip?v=1
# layui框架代码
http://layui.dotnetcms.cn/web/demo/admin.html
# layui数据表格
http://layui.dotnetcms.cn/web/demo/table.html
# echarts下载(需魔法)
https://cdn.jsdelivr.net/npm/echarts@5.4.3/dist/echarts.min.js
# echarts直方图
https://echarts.apache.org/handbook/zh/get-started/
# echarts 饼图
https://echarts.apache.org/handbook/zh/how-to/chart-types/pie/basic-pie/
  • 后端
# gin静态文件服务(导入js、css、图片用的)
https://learnku.com/docs/gin-gonic/1.7/examples-serving-static-files/11402
# gin模板引擎(前后端不分离,后端数据渲染前端)
https://learnku.com/docs/gin-gonic/1.7/examples-html-rendering/11363
# gin绑定Uri(动态获取二级路由)
https://learnku.com/docs/gin-gonic/1.7/examples-bind-uri/11391

go-elasticsearch 模块

  • 顾名思义此模块作用是充当es的客户端往es索引中读取数据,其原理和kibana上的dev tools一样,都是对es的restful api调用
# 以下是go-elasticsearch 的增删查改文档
https://www.elastic.co/guide/en/elasticsearch/client/go-api/current/getting-started-go.html

eql

  • 实现统计数据分析的核心就是eql(es查询语言),通过go-elasticsearch模块进行eql的发送,再接收es返回的回复体
    【Go】go-es统计接口被刷数和ip访问来源,go,golang,elasticsearch
  • 以下是使用go-es发送eql后,es的回复体的struct源码
    【Go】go-es统计接口被刷数和ip访问来源,go,golang,elasticsearch
  • 可以看到type Response struct 中,我们想要的json数据在Body中,但是注意Body的类型为 io.ReadCloser , 因此是需要用go的io模块进行获取json数据
    • 这边解决读取问题的代码如下。该函数接收es响应体,并返回未序列化的byte切片
// 处理es的响应,获取响应体里的Body
func getResponseBody(result *esapi.Response, context *gin.Context) []byte {
	// 接收es回复体里返回的数据,这里返回io流,需要用对应方法接收
	var bodyBytes []byte
	bodyBytes, err := io.ReadAll(result.Body)
	if err != nil {
		panic(err)
	}
	return bodyBytes
}

es客户端建立连接

  • 文档地址
https://www.elastic.co/guide/en/elasticsearch/client/go-api/current/connecting.html
  • 这边给的是https连接 + 用户名密码认证 + 不受信任证书的解决方法
package esinit

import (
	"github.com/elastic/go-elasticsearch/v7"
	"io/ioutil"
	"log"
)

var EsClient *elasticsearch.Client

func init() {
	EsClient = newEsClient()
}

func newEsClient() *elasticsearch.Client {
	cert, certErr := ioutil.ReadFile("esinit/es.crt")  // 你的不受信任的https证书
	if certErr != nil {
		log.Println(certErr)
	}
	EsClient, error := elasticsearch.NewClient(elasticsearch.Config{
		Username: "你的用户名",
		Password: "你的密码",
		Addresses: []string{
			"https://es-cluster1:9200",
			"https://es-cluster2:9200",
			"https://es-cluster3:9200",
		},
		CACert: cert,
	})
	if error != nil {
		panic(error)
	}
	return EsClient
}

实现统计的三段eql

  • 这里eql使用 fmt.Sprintf() 方法进行参数传递
  • 第一段eql是统计PV
    • 这里注意的是,我们在东八区,所以统计pv从16:00开始。这里根据@timestamp字段进行“aggs”聚合统计
func getPvResponse(startYear int, startMonth int, startDay int, endYear, endMonth int, endDay int) *esapi.Response {
	query := fmt.Sprintf(`
{
  "query": {
	"bool": {
	  "must": [
		{
		  "range": {
			"@timestamp": {
			  "gte": "%d-%02d-%02dT16:00:00",
			  "lte": "%d-%02d-%02dT16:00:00"
			}
		  }
		}
	  ]
	}
  },
  "aggs": {
	"log_count": {
	  "value_count": {
		"field": "@timestamp"
	  }
	}
  }
}
`, startYear, startMonth, startDay, endYear, endMonth, endDay)
	result, _ := esinit.EsClient.Search(
		esinit.EsClient.Search.WithIndex("k8s-istio-ingress*"), // 索引名
		esinit.EsClient.Search.WithBody(strings.NewReader(query)), // eql
	)
	return result
}
  • 第二段是对微服务(java)的接口(uri字段)的聚合统计
    • 这里用的 sortUri 是gin的绑定uri功能(动态获取二级路由的名字)
    • 这里返回前1天10000条es文档的uri字段数据
func getSortResponse(context *gin.Context) *esapi.Response {
	if err := context.ShouldBindUri(&sortUri); err != nil { // sortUri二级路由,传递索引名
		context.JSON(400, gin.H{"msg": err})
	}
	//搜索文档
	// eql 搜索时间范围内10000条记录,并只展示uri字段的内容
	query := fmt.Sprintf(`
		{
		  "_source": ["uri"],
		  "query": {
			"bool": {
			  "filter": [
				{
				  "range": {
					"@timestamp": {
					  "gte": "now-1d/d",
					  "lte": "now/d"
					}
				  }
				}
			  ]
			}
		  },
		  "size": 10000
		}
		`)
	// 对应索引进行搜索
	result, _ := esinit.EsClient.Search(
		esinit.EsClient.Search.WithIndex(sortUri.Name+"*"),
		esinit.EsClient.Search.WithBody(strings.NewReader(query)),
	)
	return result
}
  • 第三段是对istio前一小时的ip请求统计,返回2000条记录
func getIstioDataResponse() *esapi.Response {
	query := `
{
  "_source": [
    "x_forwarded_for",
    "@timestamp",
    "path",
    "user_agent_a",
    "response_code",
    "method",
    "upstream_cluster"
  ],
  "query": {
    "bool": {
      "filter": [
        {
          "range": {
            "@timestamp": {
              "gte": "now-1h/h",
              "lte": "now/d"
            }
          }
        }
      ]
    }
  },
  "size": 2000
}
`
	result, _ := esinit.EsClient.Search(
		esinit.EsClient.Search.WithIndex("k8s-istio-ingress*"),
		esinit.EsClient.Search.WithBody(strings.NewReader(query)),
	)
	return result
}
  • 上面的eql函数,会return 一个 []byte切片,可以进行 json.Unmarshal 或其他struct转json的模块进行处理,就能够得到数据。然后便可进行渲染

文章来源地址https://www.toymoban.com/news/detail-713712.html

到了这里,关于【Go】go-es统计接口被刷数和ip访问来源的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

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

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

相关文章

  • 初识Elasticsearch——GO集成ES

    Elasticsearch是一个分布式文档存储。Elasticsearch存储的是序列化为JSON文档的复杂数据结构,而不是以行列数据的形式存储的信息。当集群中有多个Elasticsearch节点时,存储的文档分布在整个集群中,可以立即从任何节点访问。 当存储文档时,它几乎是实时的——在1秒内就可以被

    2024年02月03日
    浏览(38)
  • R语言、04 案例P143 Go bananas、《商务与经济统计》案例题

    编程教材 《R语言实战·第2版》Robert I. Kabacoff 课程教材 《商务与经济统计·原书第13版》 (安德森) 每周有4.5%的概率会中断生产,考虑到企业利润,时间就是金钱。大部分公司生产线日产量是以万为单位的,暂停生产线进行调试对食品公司来说是极大的损失。应当修改策略方案

    2024年01月20日
    浏览(47)
  • Go访问Redis代码封装

    GO中可用于访问Redis的依赖包有下边4个: https://github.com/gomodule/redigo https://github.com/go-redis/redis https://github.com/bsm/redeo https://github.com/shomali11/xredis 其中go-redishttps://redis.uptrace.dev/zh/是与Redis官方有合作的,在Github的收藏数量也是最多,本文使用go-redis。 go-redis中文教程:https://red

    2024年02月12日
    浏览(31)
  • 深入理解Go语言接口

    接口是一种定义了软件组件之间交互规范的重要概念,其促进了代码的解耦、模块化和可扩展性,提供了多态性和抽象的能力,简化了依赖管理和替换,方便进行单元测试和集成测试。这些特性使得接口成为构建可靠、可维护和可扩展的软件系统的关键工具之一。 在现代编程

    2024年02月09日
    浏览(47)
  • Go结构体&接口&反射

    0、Type Golang中通过type定义一个结构体,需要注意的是,数组和结构体都是值类型 Go语言中可以使用type来定义自定义类型: 类型别名规定:TypeAlias只是Type的别名,本质上TypeAlias与Type是同一个类型 rune 和 byte 就是类型别名,他们的底层代码如下: 1、struct定

    2024年02月08日
    浏览(33)
  • Go 接口和多态

    在讲解具体的接口之前,先看如下问题。 使用面向对象的方式,设计一个加减的计算器 代码如下: 以上实现非常简单,但是有个问题,在main()函数中,当我们想使用减法操作时,创建减法类的对象,调用其对应的减法的方法。但是,有一天,系统需求发生了变化,要求使用

    2024年02月09日
    浏览(36)
  • 12 Go的接口

    概述         在上一节的内容中,我们介绍了Go的作用域,包括:局部作用域、全局作用域、命名空间作用域等。在本节中,我们将介绍Go的接口。Go语言中的接口是一种类型,它定义了一组函数的集合。接口是一种抽象的描述,它定义了一个对象的行为,而不关心对象的

    2024年02月05日
    浏览(29)
  • go基础-接口

    接口是面向对象编程的重要概念,接口是对行为的抽象和概括,在主流面向对象语言Java、C++,接口和类之间有明确关系,称为“实现接口”。这种关系一般会以“类派生图”的方式进行,经常可以看到大型软件极为复杂的派生树,随着系统的功能不断增加,这棵“派生树”会

    2024年02月14日
    浏览(28)
  • Go 接口-契约介绍

    目录 Go 接口-契约介绍 一、接口基本介绍 1.1 接口类型介绍 1.2 为什么要使用接口 1.3 面向接口编程 1.4 接口的定义 二、空接口 2.1 空接口的定义 2.2 空接口的应用 2.2.1 空接口作为函数的参数 2.2.2 空接口作为map的值 2.3 接口类型变量 2.4 类型断言 三、尽量定义“小接口” 3.1 “小

    2024年02月05日
    浏览(40)
  • Go 获取 IP 地址

    使用 net 包可以获取本地机器的 IP 地址。以下是一个获取本地 IP 地址的简单示例: 在 Go 中,可以使用 net/http 包中的 Request 结构体来获取客户端的 IP 地址。具体来说, Request 结构体中的 RemoteAddr 字段包含了客户端的 IP 地址和端口号。 以下是一个简单的示例: 在这个例子中

    2024年02月05日
    浏览(42)

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

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

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

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

二维码1

领取红包

二维码2

领红包