借助Kong记录接口的请求和响应内容

和APISIX类似,Kong也是一个Api GateWay。

运行在调用Api之前,以插件的扩展方式为Api提供管理, 如 鉴权、限流、监控、健康检查等. Kong是基于Lua语言、Nginx以及OpenResty开发的,拥有动态路由、负载均衡、高可用、高性能、熔断(基于健康检查)等功能。

和APIXIS不同,不用etcd做存储,而使用PostgreSQL,最早用的是Apache Cassandra

基础使用

安装过程忽略,可使用docker一键搭建

假设我有一个服务A,对外提供多个接口。现在想要使用Kong对其进行管理

服务A所在的机器,和运行kong的机器不一定是一台.

Kong就是个网关,统一入口。

服务A如下,

go 复制代码
package main

import (
        "fmt"
        "net/http"
        "time"
)

func helloHandler(w http.ResponseWriter, r *http.Request) {
        if r.URL.Path == "/hello" {
                currentTime := time.Now().Format("2006-01-02 15:04:05")
                response := fmt.Sprintf("你好,当前时间是%s", currentTime)
                fmt.Fprint(w, response)
        } else {
                http.NotFound(w, r)
        }
}

func main() {
        http.HandleFunc("/", helloHandler)
        fmt.Println("Server is running on port 58888")
        err := http.ListenAndServe(":58888", nil)
        if err != nil {
                fmt.Println("Error starting server:", err)
        }
}

curl 服务所在机器的公网IP:58888/hello 会返回当前的时间

在kong的控制台, http://Kong所在机器的公网IP:8002 创建一个Gateway Service,

其中,Host写要代理的那个服务的地址(即A所在机器的公网IP),端口写相应的端口

如果是域名,则端口写默认的80

然后新建一条Routes

然后, 就可以通过 curl http://Kong服务的公网IP:8000/上图写的Paths/hello 来访问了

得到的结果还是一样的,但会先通过kong,就能做很多事情了...比如限流,鉴权,日志啥的...

记录接口的请求和响应内容

Kong也提供了很多直接可用的插件,下面以HTTP Log插件为例, 使用该插件,可以记录接口的请求和响应内容

在Plugins处点击New Plugin,

搜索HTTP

再写一个服务(该服务监听20017端口),提供一个接口,用来接收:58888 这个服务全部的请求和响应内容

go 复制代码
package main

import (
	"fmt"
	"io/ioutil"
	"log"
	"net/http"
)

func getRequestHandler(w http.ResponseWriter, r *http.Request) {
	if r.Method != http.MethodPost {
		w.WriteHeader(http.StatusMethodNotAllowed)
		return
	}

	body, err := ioutil.ReadAll(r.Body)
	if err != nil {
		w.WriteHeader(http.StatusBadRequest)
		fmt.Fprintf(w, "Error reading request body: %v", err)
		return
	}
	defer r.Body.Close()

	log.Printf("Received request: %s", string(body))

	// 在这里可以对请求体进行处理
	// ...

	// 如果需要响应内容,可以在这里写入响应体
	w.WriteHeader(http.StatusOK)
	fmt.Fprint(w, "Request received successfully")
}

func main() {
	http.HandleFunc("/getrequest", getRequestHandler)

	log.Println("Starting server on port 20017...")
	err := http.ListenAndServe(":20017", nil)
	if err != nil {
		log.Fatalf("Failed to start server: %v", err)
	}
}

然后执行 curl http://kong所在机器的公网IP:port/xxxx/hello\?1121312

:20017服务能够收到请求如下:

json 复制代码
{
	"service": {
		"retries": 5,
		"created_at": 1716538997,
		"updated_at": 1716551161,
		"write_timeout": 60000,
		"port": 58888,
		"name": "xxxxxxx",
		"protocol": "http",
		"connect_timeout": 60000,
		"read_timeout": 60000,
		"host": "111.222.222.111",
		"enabled": true,
		"ws_id": "7aa29e13-25cb-4920-992e-fe5b64576c21",
		"tags": ["xxxxx-test"],
		"id": "55bd77b4-b182-4e6b-87f1-a46608d27435"
	},
	"client_ip": "1.2.3.4",
	"route": {
		"created_at": 1716551271,
		"updated_at": 1716551271,
		"regex_priority": 0,
		"service": {
			"id": "55bd77b4-b182-4e6b-87f1-a46608d27435"
		},
		"paths": ["/xxxxx"],
		"name": "xxxxxxx123",
		"path_handling": "v0",
		"id": "8481a0d0-05c2-4631-89eb-19d9aad10642",
		"ws_id": "7aa29e13-25cb-4920-992e-fe5b64576c21",
		"protocols": ["http"],
		"strip_path": true,
		"preserve_host": false,
		"request_buffering": true,
		"response_buffering": true,
		"tags": [],
		"https_redirect_status_code": 426
	},
	"started_at": 1716555189008,
	"source": "upstream",
	"tries": [{
		"balancer_start": 1716555189008,
		"balancer_start_ns": 1.7165551890087e+18,
		"ip": "110.120.119.114",
		"balancer_latency": 0,
		"port": 58888,
		"balancer_latency_ns": 15616
	}],
	"response": {
		"size": 306,
		"status": 200,
		"headers": {
			"x-kong-request-id": "d32e6a5e11bec9085663513c9430565b",
			"date": "Fri, 24 May 2024 12:53:09 GMT",
			"via": "kong/3.6.1",
			"x-kong-proxy-latency": "0",
			"content-length": "41",
			"connection": "close",
			"x-kong-upstream-latency": "98",
			"content-type": "text/plain; charset=utf-8"
		}
	},
	"upstream_status": "200",
	"upstream_uri": "/hello",
	"latencies": {
		"kong": 0,
		"request": 98,
		"proxy": 98
	},
	"request": {
		"size": 94,
		"id": "d32e6a5e11bec9085663513c9430565b",
		"headers": {
			"user-agent": "curl/8.4.0",
			"host": "xxx.xxx.xxx.xxx:8000",
			"accept": "*/*"
		},
		"url": "http://xxxxxxxx:8000/xxxxx/hello",
		"querystring": {},
		"uri": "/xxxxx/hello",
		"method": "GET"
	}
}

但发现此时,request内容是比较详细的,但缺少response部分

参考 https://tech.aufomm.com/how-to-log-request-and-response-body-with-kong/

搜索Kong Functions (Pre-Plugins)插件,

并设置Access为: kong.log.set_serialize_value("request.body", kong.request.get_raw_body())

Body Filter为: kong.log.set_serialize_value("response.body", kong.response.get_raw_body())

再次执行 curl http://Kong所在机器公网IP:8000/xxxxx/hello\?1121312

此时就能获取到完整的response内容

本文由mdnice多平台发布

相关推荐
customer085 分钟前
【开源免费】基于SpringBoot+Vue.JS周边产品销售网站(JAVA毕业设计)
java·vue.js·spring boot·后端·spring cloud·java-ee·开源
Yaml41 小时前
智能化健身房管理:Spring Boot与Vue的创新解决方案
前端·spring boot·后端·mysql·vue·健身房管理
小码编匠2 小时前
一款 C# 编写的神经网络计算图框架
后端·神经网络·c#
AskHarries2 小时前
Java字节码增强库ByteBuddy
java·后端
佳佳_2 小时前
Spring Boot 应用启动时打印配置类信息
spring boot·后端
许野平4 小时前
Rust: 利用 chrono 库实现日期和字符串互相转换
开发语言·后端·rust·字符串·转换·日期·chrono
BiteCode_咬一口代码5 小时前
信息泄露!默认密码的危害,记一次网络安全研究
后端
齐 飞5 小时前
MongoDB笔记01-概念与安装
前端·数据库·笔记·后端·mongodb