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



背景
- 上面的数据来自elk日志统计。因为elk通过kibana进行展示,但是kibana有一定学习成本且不太能满足定制化的需求,所以考虑用编程的方式对数据进行处理
- 首先是接口统计,kibana的页面只会在 字段uri 的 top500 进行百分比统计,展示前5条数据,统计不够充分

- 其次是网关日志,ip来源的采集字段是通过x_forward_for,这记录了各级的代理来源ip。并不能直接对用户的ip进行数据聚合的统计
- 举例,这里面 “223.104.195.51,192.168.29.135” ,这种数据我需要拿到223.104.195.51,因为这才是用户的ip。所以需要进行编程的处理

- 举例,这里面 “223.104.195.51,192.168.29.135” ,这种数据我需要拿到223.104.195.51,因为这才是用户的ip。所以需要进行编程的处理
环境
- 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-es发送eql后,es的回复体的struct源码

- 可以看到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 []bytebodyBytes, 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 esinitimport ("github.com/elastic/go-elasticsearch/v7""io/ioutil""log"
)var EsClient *elasticsearch.Clientfunc 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的模块进行处理,就能够得到数据。然后便可进行渲染
相关文章:
【Go】go-es统计接口被刷数和ip访问来源
go-es模块统计日志中接口被刷数和ip访问来源 以下是使用go的web框架gin作为后端,展示的统计页面 背景 上面的数据来自elk日志统计。因为elk通过kibana进行展示,但是kibana有一定学习成本且不太能满足定制化的需求,所以考虑用编程的方式…...
debian 安装 pg --chatGpt
pgt: 要在Debian上安装PostgreSQL (通常缩写为PG) 数据库,您可以使用apt包管理器来执行安装操作。以下是安装PostgreSQL的步骤: 1. 打开终端。 2. 使用sudo权限以管理员身份运行以下命令,以更新包信息并安装PostgreSQL: bash …...
商城小程序代客下单程序开发演示
一款专为传统电商、实体商家开发的商城系统小程序,做私域、做留存、做社交必备功能全都有。 1、丰富的营销玩法:拼团、秒杀、定金预售、分销、社区团购、积分商城、支付有礼等主流获客玩法都有。 2、强大的会员体系:普通会员、付费会员、会…...
SpringBoot 整合 jetcache缓存
目前 jetcache 支持的本地缓存方案有两种,远程缓存支持两种,分别如下: 本地缓存(Local) LinkedHashMapCaffeine 远程缓存(Remote) Redis Tair 依赖导入 <dependency><groupId>…...
HTML5+CSS3+移动web 前端开发入门笔记(二)HTML标签详解
HTML标签:排版标签 排版标签用于对网页内容进行布局和样式的调整。下面是对常见排版标签的详细介绍: <h1>: 定义一级标题,通常用于标题栏或页面主要内容的标题。<p>: 定义段落,用于将文字分段展示,段落之…...
Maven 配置阿里云镜像
1. 查找maven setting.xml配置文件 find / -name "setting.xml" 2. 添加阿里云镜像 修改maven根目录下的conf文件夹中的setting.xml文件中的mirrors下添加mirror标签 <settings> <localRepository>E:\Maven\repository</localRepository> <…...
矢量图绘制软件EazyDraw mac中文版软件介绍
EazyDraw mac是一款功能强大且易于使用的矢量绘图软件。 EazyDraw mac软件介绍 矢量绘图工具:EazyDraw 提供了一套全面的矢量绘图工具,包括直线、曲线、多边形、文本框、图形填充等。用户可以使用这些工具创建和编辑精确的矢量图形,无论是简…...
Cocos Creator3.8 项目实战(四)巧用九宫格图像拉伸
一、为什么要使用九宫格图像拉伸 相信做过前端的同学都知道,ui (图片)资源对包体大小和内存都有非常直接的影响。 通常ui 资源都是图片,也是最占资源量的资源类型,游戏中的ui 资源还是人机交互的最重要的部分ÿ…...
怎么使用jenkins设置web自动打包
在Jenkins中设置Web自动打包需要完成以下步骤: 1.环境基础 安装Jenkins:首先,你需要在服务器上安装Jenkins。 你可以从Jenkins官网下载Jenkins的安装包,并按照官方指导进行安装。 2.使用jenkins设置web自动打包步骤 创建Jenk…...
完美解决 flex 实现一行三个,显示多行,左对齐
效果图 代码 <body><section class"content"><div class"item">元素</div><div class"item">元素</div><div class"item">元素</div><div class"item">元素</di…...
初识Spring
目录 1.Spring 基础 2.传统程序开发 3.IoC程序开发(解耦) 4.DI 4.1 IoC 和 DI 有什么区别 1.Spring 基础 Spring 指的是 Spring Framework(Spring 框架),它是⼀个开源框架,有着活跃⽽庞⼤的社区&…...
Mybatis 使用参数时$与#的区别
之前我们介绍了mybatis中参数的使用,本篇我们在此基础上介绍Mybatis中使用参数时$与#的区别。 如果您对mybatis中参数的使用不太了解,建议您先进行了解后再阅读本篇,可以参考: Mybatis参数(parameterType)https://blog.csdn.net…...
解锁Spring Boot的强大配置功能:@ConfigurationProperties与@PropertySources详解
解锁Spring Boot的强大配置功能:ConfigurationProperties与PropertySources详解 前言什么是ConfigurationProperties和PropertySourcesConfigurationProperties的使用步骤 1: 创建 Java POJO 类步骤 2: 配置类步骤 3: 配置文件步骤 4: 注入配置属性 PropertySources…...
Java和Vue字符串加密
字符串加密 AES 加密算法 在 Java 中,可以使用不同的加密算法来对字符串进行加密。以下是使用 AES 加密算法的示例代码,演示如何对一个字符串进行加密: import javax.crypto.Cipher; import javax.crypto.spec.SecretKeySpec; import java…...
Java:java版结巴分词:jieba-analysis
文档 https://github.com/huaban/jieba-analysishttps://mvnrepository.com/artifact/com.huaban/jieba-analysis 依赖 <!-- https://mvnrepository.com/artifact/com.huaban/jieba-analysis --> <dependency><groupId>com.huaban</groupId><art…...
java生成一个符合密码学和安全性的随机秘钥
有时 我们在生成token 或者完成某种加密形式时会需要一个秘钥 但是 有些时候 项目开发并没有规定用什么秘钥 但是 秘钥都是要有一定格式规范的 我们可以通过以下代码生成一个随机秘钥 import java.security.SecureRandom; import java.util.Base64;public class TokenGenerat…...
C++ - 右值引用 和 移动拷贝
右值引用 我们先来了解什么是左值,什么是右值: 左值 和 有值 区分 首先,左值 和 右值 并不是完全意味着 在 "" 左边的就是 左值 ; 在 "" 右边的就是右值。这是不一定的。只能说,在左边的大概率是…...
项目成员积分规则
在当下的项目/团队管理种,如何让成员能清晰的看到,自己的工作、努力在团队种属于那个段位,通过这个形式,并配合其他方式去点燃成员的进步之心。以积分的形式,代替绩效考核,一些零散的想法,欢迎各…...
Linux CentOS7 vim多窗口编辑
我们在用vim编辑文件时,有各种需求。如有时需要在多个文件之间来回操作,一会关闭一个文件,一会再打开另外一个文件,这样来回操作显得太笨拙。有时,vim编辑多行的大文件,来回查看、编辑前面一部分及最后一部…...
挑战杯推荐项目
“人工智能”创意赛 - 智能艺术创作助手:借助大模型技术,开发能根据用户输入的主题、风格等要求,生成绘画、音乐、文学作品等多种形式艺术创作灵感或初稿的应用,帮助艺术家和创意爱好者激发创意、提高创作效率。 - 个性化梦境…...
stm32G473的flash模式是单bank还是双bank?
今天突然有人stm32G473的flash模式是单bank还是双bank?由于时间太久,我真忘记了。搜搜发现,还真有人和我一样。见下面的链接:https://shequ.stmicroelectronics.cn/forum.php?modviewthread&tid644563 根据STM32G4系列参考手…...
阿里云ACP云计算备考笔记 (5)——弹性伸缩
目录 第一章 概述 第二章 弹性伸缩简介 1、弹性伸缩 2、垂直伸缩 3、优势 4、应用场景 ① 无规律的业务量波动 ② 有规律的业务量波动 ③ 无明显业务量波动 ④ 混合型业务 ⑤ 消息通知 ⑥ 生命周期挂钩 ⑦ 自定义方式 ⑧ 滚的升级 5、使用限制 第三章 主要定义 …...
练习(含atoi的模拟实现,自定义类型等练习)
一、结构体大小的计算及位段 (结构体大小计算及位段 详解请看:自定义类型:结构体进阶-CSDN博客) 1.在32位系统环境,编译选项为4字节对齐,那么sizeof(A)和sizeof(B)是多少? #pragma pack(4)st…...
Python爬虫实战:研究feedparser库相关技术
1. 引言 1.1 研究背景与意义 在当今信息爆炸的时代,互联网上存在着海量的信息资源。RSS(Really Simple Syndication)作为一种标准化的信息聚合技术,被广泛用于网站内容的发布和订阅。通过 RSS,用户可以方便地获取网站更新的内容,而无需频繁访问各个网站。 然而,互联网…...
【JVM】- 内存结构
引言 JVM:Java Virtual Machine 定义:Java虚拟机,Java二进制字节码的运行环境好处: 一次编写,到处运行自动内存管理,垃圾回收的功能数组下标越界检查(会抛异常,不会覆盖到其他代码…...
渗透实战PortSwigger靶场-XSS Lab 14:大多数标签和属性被阻止
<script>标签被拦截 我们需要把全部可用的 tag 和 event 进行暴力破解 XSS cheat sheet: https://portswigger.net/web-security/cross-site-scripting/cheat-sheet 通过爆破发现body可以用 再把全部 events 放进去爆破 这些 event 全部可用 <body onres…...
MySQL中【正则表达式】用法
MySQL 中正则表达式通过 REGEXP 或 RLIKE 操作符实现(两者等价),用于在 WHERE 子句中进行复杂的字符串模式匹配。以下是核心用法和示例: 一、基础语法 SELECT column_name FROM table_name WHERE column_name REGEXP pattern; …...
汇编常见指令
汇编常见指令 一、数据传送指令 指令功能示例说明MOV数据传送MOV EAX, 10将立即数 10 送入 EAXMOV [EBX], EAX将 EAX 值存入 EBX 指向的内存LEA加载有效地址LEA EAX, [EBX4]将 EBX4 的地址存入 EAX(不访问内存)XCHG交换数据XCHG EAX, EBX交换 EAX 和 EB…...
RNN避坑指南:从数学推导到LSTM/GRU工业级部署实战流程
本文较长,建议点赞收藏,以免遗失。更多AI大模型应用开发学习视频及资料,尽在聚客AI学院。 本文全面剖析RNN核心原理,深入讲解梯度消失/爆炸问题,并通过LSTM/GRU结构实现解决方案,提供时间序列预测和文本生成…...
