借助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多平台发布

相关推荐
一弓虽6 分钟前
SpringBoot 学习
java·spring boot·后端·学习
姑苏洛言14 分钟前
扫码小程序实现仓库进销存管理中遇到的问题 setStorageSync 存储大小限制错误解决方案
前端·后端
光而不耀@lgy29 分钟前
C++初登门槛
linux·开发语言·网络·c++·后端
方圆想当图灵1 小时前
由 Mybatis 源码畅谈软件设计(七):SQL “染色” 拦截器实战
后端·mybatis·代码规范
毅航1 小时前
MyBatis 事务管理:一文掌握Mybatis事务管理核心逻辑
java·后端·mybatis
我的golang之路果然有问题1 小时前
速成GO访问sql,个人笔记
经验分享·笔记·后端·sql·golang·go·database
柏油2 小时前
MySql InnoDB 事务实现之 undo log 日志
数据库·后端·mysql
写bug写bug3 小时前
Java Streams 中的7个常见错误
java·后端
Luck小吕4 小时前
两天两夜!这个 GB28181 的坑让我差点卸载 VSCode
后端·网络协议
M1A14 小时前
全栈开发必备:Windows安装VS Code全流程
前端·后端·全栈