golang Gin框架中间件插件rk-gin实现日志监控认证链路追踪功能
Golang Gin框架中间件插件rk-gin实现日志监控认证链路追踪功能
rk-gin是一个为Gin框架提供中间件和服务器配置注入的插件,它属于rk-boot家族的一部分。通过YAML文件配置,可以快速启用日志、监控、认证和链路追踪等功能。
架构
快速入门
以下示例展示了如何通过YAML配置启动一个包含以下功能的微服务:
- Gin服务器
- Swagger UI
- 文档
- 通用服务
- Prometheus指标(中间件)
- 日志(中间件)
- 元数据(中间件)
1. 安装
go get github.com/rookie-ninja/rk-gin/v2
2. 创建boot.yaml
---
gin:
- name: greeter # 必填
port: 8080 # 必填
enabled: true # 必填
commonService: # 可选
enabled: true # 可选,默认: false
sw: # 可选
enabled: true # 可选,默认: false
docs: # 可选
enabled: true # 可选,默认: false
prom:
enabled: true # 可选,默认: false
middleware:
logging:
enabled: true
prom:
enabled: true
meta:
enabled: true
3. 创建main.go
// Copyright (c) 2021 rookie-ninja
//
// Use of this source code is governed by an Apache-style
// license that can be found in the LICENSE file.
package main
import (
"context"
"embed"
_ "embed"
"fmt"
"github.com/gin-gonic/gin"
"github.com/rookie-ninja/rk-entry/v2/entry"
"github.com/rookie-ninja/rk-gin/v2/boot"
"net/http"
)
// 使用embed.FS嵌入文件
//go:embed docs
var docsFS embed.FS
func init() {
rkentry.GlobalAppCtx.AddEmbedFS(rkentry.SWEntryType, "greeter", &docsFS)
}
//go:embed boot.yaml
var boot []byte
// @title RK Swagger for Gin
// @version 1.0
// @description This is a greeter service with rk-boot.
func main() {
// 预加载入口
rkentry.BootstrapPreloadEntryYAML(boot)
// 从boot配置注册Gin入口
res := rkgin.RegisterGinEntryYAML(boot)
// 获取GinEntry
ginEntry := res["greeter"].(*rkgin.GinEntry)
ginEntry.Router.GET("/v1/greeter", Greeter)
// 启动Gin入口
ginEntry.Bootstrap(context.Background())
// 等待关闭信号
rkentry.GlobalAppCtx.WaitForShutdownSig()
// 中断Gin入口
ginEntry.Interrupt(context.Background())
}
// Greeter handler
// @Summary Greeter service
// @Id 1
// @version 1.0
// @produce application/json
// @Param name query string true "Input name"
// @Success 200 {object} GreeterResponse
// @Router /v1/greeter [get]
func Greeter(ctx *gin.Context) {
ctx.JSON(http.StatusOK, &GreeterResponse{
Message: fmt.Sprintf("Hello %s!", ctx.Query("name")),
})
}
type GreeterResponse struct {
Message string
}
4. 启动服务器
$ go run main.go
5. 验证
5.1 Gin服务器
测试通用服务:
$ curl localhost:8080/rk/v1/ready
{
"ready": true
}
$ curl localhost:8080/rk/v1/alive
{
"alive": true
}
5.2 Swagger UI
默认情况下,我们可以通过http://localhost:8080/sw访问Swagger UI。
5.3 文档UI
默认情况下,我们可以通过http://localhost:8080/docs访问文档UI。
5.4 Prometheus指标
默认情况下,我们可以通过http://localhost:8080/metrics访问Prometheus客户端。
5.5 日志
默认情况下,我们启用了zap日志记录器和事件日志记录器,编码类型为[console]。也支持[json]和[flatten]编码类型。
5.6 元数据
默认情况下,我们会将一些元数据发送回客户端,包括带有header的网关。
5.7 发送请求
我们注册了/v1/greeter API,让我们验证一下:
$ curl -vs "localhost:8080/v1/greeter?name=rk-dev"
* Trying ::1...
* TCP_NODELAY set
* Connected to localhost (::1) port 8080 (#0)
> GET /v1/greeter?name=rk-dev HTTP/1.1
> Host: localhost:8080
> User-Agent: curl/7.64.1
> Accept: */*
>
< HTTP/1.1 200 OK
< Content-Type: application/json; charset=utf-8
< X-Request-Id: a96ab531-e28f-47ca-a082-fc3f8ef14187
< X-Rk-App-Name: rk
< X-Rk-App-Unix-Time: 2021-12-28T02:22:03.289469+08:00
< X-Rk-Received-Time: 2021-12-28T02:22:03.289469+08:00
< Date: Mon, 27 Dec 2021 18:22:03 GMT
< Content-Length: 27
<
* Connection #0 to host localhost left intact
{"Message":"Hello rk-dev!"}
5.8 RPC日志
标准输出中会打印以下日志:
------------------------------------------------------------------------
endTime=2021-12-28T02:22:03.289585+08:00
startTime=2021-12-28T02:22:03.289457+08:00
elapsedNano=128210
timezone=CST
ids={"eventId":"a96ab531-e28f-47ca-a082-fc3f8ef14187","requestId":"a96ab531-e28f-47ca-a082-fc3f8ef14187"}
app={"appName":"rk","appVersion":"","entryName":"greeter","entryType":"GinEntry"}
env={"arch":"amd64","az":"*","domain":"*","hostname":"lark.local","localIP":"10.8.0.2","os":"darwin","realm":"*","region":"*"}
payloads={"apiMethod":"GET","apiPath":"/v1/greeter","apiProtocol":"HTTP/1.1","apiQuery":"name=rk-dev","userAgent":"curl/7.64.1"}
error={}
counters={}
pairs={}
timing={}
remoteAddr=localhost:54028
operation=/v1/greeter
resCode=200
eventStatus=Ended
EOE
5.9 RPC Prometheus指标
Prometheus客户端会自动注册到/metrics端点。
访问http://localhost:8080/metrics
支持的功能
用户可以按需启用以下任何功能!没有强制绑定!
实例 | 描述 |
---|---|
gin.Router | 兼容原始gin-gonic/gin服务功能 |
Config | 配置spf13/viper作为配置实例并从YAML引用 |
Logger | 配置uber-go/zap日志记录器配置并从YAML引用 |
Event | 使用rk-query配置RPC日志记录并从YAML引用 |
Cert | 获取TLS/SSL证书启动微服务 |
Prometheus | 在客户端启动prometheus客户端并按需将指标推送到pushgateway |
Swagger | 内置swagger UI处理程序 |
Docs | 内置RapiDoc实例,可用于替换swagger和RK TV |
CommonService | 通用API列表 |
StaticFileHandler | 显示可从服务器下载文件的Web UI,目前支持本地和embed.FS源 |
PProf | PProf web UI |
支持的中间件
所有中间件都可以通过YAML或代码配置。用户可以按需启用以下任何中间件!没有强制绑定!
中间件 | 描述 |
---|---|
Prom | 收集RPC指标并导出到prometheus客户端 |
Logging | 使用rk-query记录每个RPC请求作为事件 |
Trace | 收集RPC跟踪并将其导出到stdout、文件或jaeger |
Panic | 从RPC请求的panic中恢复并记录 |
Meta | 将微服务元数据作为header发送到客户端 |
Auth | 支持[基本认证]和[API密钥]授权类型 |
RateLimit | 全局或按路径限制RPC速率 |
Timeout | 通过配置超时请求 |
Gzip | 基于请求头使用gzip格式压缩和解压缩消息体 |
CORS | 服务器端CORS验证 |
JWT | 服务器端JWT验证 |
Secure | 服务器端安全验证 |
CSRF | 服务器端csrf验证 |
YAML选项
用户可以同时启动多个gin-gonic/gin实例。请确保使用不同的端口和名称。
完整的YAML配置选项请参考文档中的详细说明。
更多关于golang Gin框架中间件插件rk-gin实现日志监控认证链路追踪功能的实战教程也可以访问 https://www.itying.com/category-94-b0.html
更多关于golang Gin框架中间件插件rk-gin实现日志监控认证链路追踪功能的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
使用rk-gin实现Gin框架的日志、监控、认证和链路追踪功能
rk-gin是一个基于Gin框架的插件,提供了企业级应用所需的日志记录、监控指标、认证授权和分布式链路追踪等功能。下面我将详细介绍如何使用rk-gin来实现这些功能。
安装rk-gin
首先需要安装rk-gin和相关依赖:
go get github.com/rookie-ninja/rk-boot
go get github.com/rookie-ninja/rk-gin
基本使用示例
package main
import (
"context"
"github.com/gin-gonic/gin"
"github.com/rookie-ninja/rk-boot"
"github.com/rookie-ninja/rk-gin/boot"
)
func main() {
// 创建boot实例
boot := rkboot.NewBoot()
// 注册Gin服务
ginEntry := rkgin.GetGinEntry("my-service")
ginEntry.Router.GET("/v1/hello", func(ctx *gin.Context) {
ctx.JSON(200, gin.H{
"message": "hello world!",
})
})
// 添加bootstrap选项
boot.Bootstrap(context.TODO())
// 等待关闭信号
boot.WaitForShutdownSig(context.TODO())
}
日志功能
rk-gin内置了日志中间件,可以自动记录请求和响应日志:
func main() {
boot := rkboot.NewBoot(
rkboot.WithBootConfigPath("config/boot.yaml"),
)
// 从boot.yaml中读取配置
ginEntry := rkgin.GetGinEntry("my-service")
// 自定义日志中间件
ginEntry.Router.Use(func(ctx *gin.Context) {
// 在请求处理前记录日志
rkginctx.GetLogger(ctx).Info("Request received")
ctx.Next()
// 在请求处理后记录日志
rkginctx.GetLogger(ctx).Info("Request processed")
})
// ...其他代码
}
监控功能
rk-gin集成了Prometheus监控:
func main() {
boot := rkboot.NewBoot(
rkboot.WithBootConfigPath("config/boot.yaml"),
)
// 访问 /metrics 端点可以获取Prometheus格式的指标
ginEntry := rkgin.GetGinEntry("my-service")
// 自定义业务指标
counter := prometheus.NewCounter(prometheus.CounterOpts{
Name: "my_custom_counter",
Help: "This is my custom counter",
})
prometheus.MustRegister(counter)
ginEntry.Router.GET("/v1/count", func(ctx *gin.Context) {
counter.Inc()
ctx.JSON(200, gin.H{
"count": "incremented",
})
})
// ...其他代码
}
认证功能
rk-gin支持JWT、Basic Auth等多种认证方式:
func main() {
boot := rkboot.NewBoot(
rkboot.WithBootConfigPath("config/boot.yaml"),
)
ginEntry := rkgin.GetGinEntry("my-service")
// 添加JWT认证中间件
ginEntry.Router.Use(rkginauth.JwtAuth())
// 添加Basic认证中间件
ginEntry.Router.Use(rkginauth.BasicAuth("user", "pass"))
// 添加API Key认证
ginEntry.Router.Use(rkginauth.ApiKeyAuth("my-api-key"))
// ...其他代码
}
链路追踪
rk-gin支持OpenTelemetry和Jaeger等分布式追踪系统:
func main() {
boot := rkboot.NewBoot(
rkboot.WithBootConfigPath("config/boot.yaml"),
rkboot.WithJaegerEnabled(true),
rkboot.WithJaegerAgentHost("localhost"),
rkboot.WithJaegerAgentPort(6831),
)
ginEntry := rkgin.GetGinEntry("my-service")
// 自动添加链路追踪中间件
ginEntry.Router.GET("/v1/trace", func(ctx *gin.Context) {
// 获取当前span
span := rkginctx.GetTraceSpan(ctx)
if span != nil {
span.AddEvent("custom event")
}
ctx.JSON(200, gin.H{
"trace": "enabled",
})
})
// ...其他代码
}
完整配置示例
config/boot.yaml
配置文件示例:
gin:
- name: my-service
port: 8080
enabled: true
commonService:
enabled: true
prom:
enabled: true
sw:
enabled: true
tv:
enabled: true
loggerEntry:
zapLogger:
encoding: json
outputPaths: ["stdout", "logs/app.log"]
jaegerEntry:
agent:
enabled: true
host: "localhost"
port: 6831
certEntry:
enabled: false
总结
rk-gin为Gin框架提供了以下企业级功能:
- 日志:结构化日志记录,支持多种输出格式
- 监控:Prometheus指标自动收集和暴露
- 认证:多种认证方式开箱即用
- 链路追踪:分布式追踪系统集成
- Swagger UI:API文档自动生成
- Tv:可视化API调用关系
通过简单的配置和中间件集成,rk-gin可以快速为Gin应用添加这些功能,大大减少了企业级应用的开发成本。