Skip to main content
Version: 2.8.1

HTTP Log

HTTP Log

用途說明#

傳送請求及回應日誌至 HTTP server。

日誌格式請參考下方:日誌格式

欄位配置說明#

啟用時可以看到以下畫面:

插件啟用配置圖

對應的配置說明如下:

參數類型預設值說明必填
http_endpointstring日誌欲發送的 HTTP URL 端點(包括要使用的協定)。
例如: http://mockbin.org/bin/logs
V
methodstringPOST用於將日誌發送到HTTP server的方法。
此欄位可填入的值為以下其一:POSTPUTPATCH
content_typestringapplication/json表明發送的日誌數據類型。
唯一可用的類型選項是 application/json
timeoutnumber10000發送日誌到服務器的超時時間(以毫秒為單位)。
keepalivenumber60000定義空閒連接關閉前的存活時間(以毫秒為單位)。
retry_countinteger10將日誌發送到服務器時重試的次數。
queue_sizeinteger1每次發送到服務器的最大日誌紀錄數量。
flush_timeoutnumber2如果設定的 queue_size > 1,則表示在發送的日誌記錄數量尚未達到 queue_size 之前的最大空閒連接過期時間。(以秒為單位)。
custom_fields_by_luamapkey-value pairs 列表,其中 key 是日誌字段的名稱,value 是一段 Lua 代碼,其返回 value sets 或替換日誌字段 value。
note

如果 http_endpoint 有包含帳號及密碼,例如:http://bob:password@example.com/logs ,則 GOC API Gateway 會在日誌請求中自動包含由帳號與密碼轉換 basic-auth 的 Authorization header。

用法示例#

日誌格式#

如果參數 queue_size 設定 > 1,則日誌使用 JSON 的格式來組成,說明如下:

  • request 包含有關客戶端發送的請求。
  • response 包含發送給客戶端的回應。
  • tries 包含負載均衡器對此請求進行的(成功和失敗)列表。
  • route 包含請求所對應之特定的 GOC API Gateway 路由設定資料。
  • service 包含請求所對應之 GOC API Gateway 路由關聯的服務設定資料。
  • authenticated_entity 如果已啟動身份認證插件,則會包含認證憑據。
  • workspaces 包含與請求的路由所屬的工作區資料。目前版本的 services 及 routes 資訊內的 ws_id 欄位會對應其所屬的 workspace ID 資訊。
  • consumer 如果已啟動身份認證插件,則會包含認證的用戶設定資料。
  • latencies 包含有關延遲的一些數據:
    • proxy 是最終服務處理請求所花費的時間。
    • kong 是運行所有插件所需的內部延遲。
    • request 是從客戶端讀取第一個字節到將最後一個字節發送到客戶端之間經過的時間。對於檢測速度較慢的客戶端很有用。
  • client_ip 包含原始客戶端 IP 地址。
  • started_at 包含開始處理請求的時間的 UTC 時區時戳。

範例:

{
"latencies": {
"request": 515,
"kong": 58,
"proxy": 457
},
"service": {
"host": "httpbin.org",
"created_at": 1614232642,
"connect_timeout": 60000,
"id": "167290ee-c682-4ebf-bdea-e49a3ac5e260",
"protocol": "http",
"read_timeout": 60000,
"port": 80,
"path": "/anything",
"updated_at": 1614232642,
"write_timeout": 60000,
"retries": 5,
"ws_id": "54baa5a9-23d6-41e0-9c9a-02434b010b25"
},
"request": {
"querystring": {},
"size": 138,
"uri": "/log",
"url": "http://localhost:8000/log",
"headers": {
"host": "localhost:8000",
"accept-encoding": "gzip, deflate",
"user-agent": "HTTPie/2.4.0",
"accept": "*/*",
"connection": "keep-alive"
},
"method": "GET"
},
"tries": [
{
"balancer_latency": 0,
"port": 80,
"balancer_start": 1614232668399,
"ip": "18.211.130.98"
}
],
"client_ip": "192.168.144.1",
"upstream_uri": "/anything",
"response": {
"headers": {
"content-type": "application/json",
"date": "Thu, 25 Feb 2021 05:57:48 GMT",
"connection": "close",
"access-control-allow-credentials": "true",
"content-length": "503",
"server": "gunicorn/19.9.0",
"via": "kong/2.2.1.0-enterprise-edition",
"x-kong-proxy-latency": "57",
"x-kong-upstream-latency": "457",
"access-control-allow-origin": "*"
},
"status": 200,
"size": 827
},
"route": {
"id": "78f79740-c410-4fd9-a998-d0a60a99dc9b",
"paths": [
"/log"
],
"protocols": [
"http"
],
"strip_path": true,
"created_at": 1614232648,
"ws_id": "54baa5a9-23d6-41e0-9c9a-02434b010b25",
"request_buffering": true,
"updated_at": 1614232648,
"preserve_host": false,
"regex_priority": 0,
"response_buffering": true,
"https_redirect_status_code": 426,
"path_handling": "v0",
"service": {
"id": "167290ee-c682-4ebf-bdea-e49a3ac5e260"
}
},
"started_at": 1614232668342
}

Custom Fields by Lua#

custom_fields_by_lua 配置允許使用 Lua 代碼動態修改日誌字段。

以下是刪除日誌中現有路由字段的範例配置:

custom_fields_by_lua.route="return nil"

同樣也可以添加新字段:

custom_fields_by_lua.header="return kong.request.get_header('h1')"

限制#

Lua 代碼運行在一個受限的沙箱環境中,其行為受 untrusted_lua 配置屬性的約束。

為了提高安全性,沙盒在 Lua 代碼的執行方式中包含幾個限制。 以下功能不可用,因為它們可以用來濫用系統:

  • string.rep:可用於在一次操作中分配數百萬 bytes。
  • {set|get}metatable:可用於修改全局對象(字符串、數字)的 metatables。
  • collectgarbage:可以被濫用來扼殺其他 workers 的效能。
  • _G:是根節點,可以訪問所有函數。它被臨時 table 所屏蔽。
  • load{file|string}:被認為是不安全的,因為它可以授予對全局環境的訪問權限。
  • raw{get|set|equal}:可能不安全,因為沙盒依賴於一些 metatable 操作。
  • string.dump:可以顯示機密的 server 信息(比如 functions 的實作內容)。
  • math.randomseed:可以影響主機系統。 GOC API Gateway 已經正確地為隨機數生成器提供 seed。
  • 所有 os.*os.clockos.difftimeos.time 除外)。 os.execute 可以顯著改變主機系統。
  • io.*:提供對硬碟驅動器的訪問。
  • dofile|require:提供對硬碟驅動器的訪問。

排除 require 意味著插件只能使用 PDK functions,像是: kong.*

ngx.* 抽象方法也可用,但不能保證在插件的未來版本中支援。

除上述限制外:

  • 所有提供的模塊(如 stringtable)都是唯讀的,不能修改。
  • 禁用 Bytecode 執行。

此外,由於代碼在 log phase 中運行,因此只能使用該 phase 可用的 PDK 方法。

在全局啟用插件#

  1. 從網站左邊 Menu 中 外掛插件 頁面中,點選右上角的 新增外掛插件

全局啟用畫面

  1. 點選後,選擇 日誌 頁籤,並啟用 HTTP Log,填寫內容參考欄位配置說明,設定成功後,任何請求(不分服務、路由、用戶)的日誌都會透過 HTTP 請求發送給該服務。

在服務端上啟用插件#

  1. 從網站左邊 Menu 中 服務 > 服務列表 頁面中,選擇要啟用此插件的服務,假設為 google,點選對應的編輯按鈕:

服務啟用畫面1

  1. 在編輯畫面中,點選上方的 外掛插件 頁籤,再點選頁籤內容上方的 新增外掛插件 按鈕:

服務啟用畫面2

點選後,選擇 日誌 頁籤,並啟用 HTTP Log,填寫內容參考欄位配置說明,設定成功後,僅有此服務(範例為google)請求的日誌會透過 HTTP 請求發送給指定的服務。

在路由端上啟用插件#

可以由兩種方式來選擇路由,並啟用插件:

方式一:路由列表#

  1. 從網站左邊 Menu 中 服務 > 路由列表 頁面中,選擇要啟用此插件的路由,假設為 google,點選對應的編輯按鈕 :

路由啟用畫面1

方式二:服務 > 服務列表 > 路由列表#

  1. 從網站左邊 Menu 中 服務 > 服務列表 頁面中,選擇要啟用此插件的路由 所屬之服務(假設為 google),點選對應的編輯按鈕。

在編輯畫面中,點選上方的 路由 頁籤,選擇要啟用此插件的路由(假設為 google),點選對應的編輯按鈕:

路由啟用畫面2


  1. 承第1步,點擊上述兩種方式之一的編輯按鈕後,在編輯畫面中,點選上方的 外掛插件 頁籤,再點選頁籤內容上方的 新增外掛插件 按鈕:

路由啟用畫面3

點選新增外掛插件 按鈕後,選擇 日誌 頁籤,並啟用 HTTP Log,填寫內容參考欄位配置說明,設定成功後,僅有此路由(範例為google)請求的日誌會透過HTTP請求發送給指定的服務。

在用戶端上啟用插件#

  1. 從網站左邊 Menu 中 訂閱用戶 > 用戶列表 頁面中,選擇要啟用此插件的用戶,假設為 portaladmin,點選對應的編輯按鈕 :

用戶啟用畫面1

  1. 在編輯畫面中,點選上方的 外掛插件 頁籤,再點選頁籤內容上方的 新增外掛插件 按鈕:

用戶啟用畫面2

點選後,選擇 日誌 頁籤,並啟用 HTTP Log,填寫內容參考欄位配置說明,設定成功後,僅有此用戶(範例為 portaladmin)請求的日誌會透過 HTTP 請求發送給指定的服務。

驗證#

假設目前對應收取日誌的 HTTP server URL 端點為 http://172.35.1.146/logs,方法是使用 POST,啟用此插件時,填入對應的 http_endpoint、method。

透過 GOC API Gateway 去呼叫服務,範例如下(使用 curl 命令來測試):

curl -XGET < GOC API Gateway protocol>://< GOC API Gateway ip>:< GOC API Gateway port>/api/v2/users/ \
-H 'X-API-HOST: gocv3' \
-H 'X-API-KEY: 7338ebd5-a29c-469a-8501-ad861e1821c8' \
-uadmin:password -i
[{"id":"2513b24e-21da-4c8a-ae41-26c1e5c96bcd","username":"demo222","email":"xxx@xxx.com","display_name":"demo222","create_time":"2020-08-21T08:55:28Z"},{"id":"25a52372-c8ce-4d02-b175-7eae8ee18ad1","username":"jop","email":"j.op@aaa.com"...()

GOC API Gateway 在取得服務的回應後,會將該次的請求&回應之日誌,使用 POST 方法來傳送給 http://172.35.1.146/logs

觀察 HTTP server (http://172.35.1.146/logs 所在的服務)確實有接收到日誌,內容範例如下,即為設定驗證成功。

{
"latencies": {
"request": 63,
"kong": 2,
"proxy": 61
},
"service": {
"host": "10.xx.xx.xx",
"created_at": 1592296411,
"connect_timeout": 60000,
"id": "6799854c-1e31-41b4-ac75-b5f55c4653a1",
"protocol": "https",
"name": "gocv3",
"read_timeout": 60000,
"retries": 5,
"updated_at": 1592296411,
"write_timeout": 60000,
"port": 443
},
"request": {
"querystring": {},
"size": "201",
"uri": "/api/v2/users/",
"url": "http://localhost:8000/api/v2/users/",
"headers": {
"host": "localhost:9000",
"authorization": "Basic YWRtaW46cGFzc3dvcmQ=",
"user-agent": "curl/7.65.3",
"accept": "*/*",
"x-api-host": "gocv3",
"x-api-key": "7338ebd5-a29c-469a-8501-ad861e1821c8"
},
"method": "GET"
},
"client_ip": "172.18.0.1",
"tries": [
{
"balancer_latency": 0,
"port": 443,
"balancer_start": 1616655328908,
"ip": "10.xx.xx.xx"
}
],
"upstream_uri": "/api/v2/users/",
"response": {
"headers": {
"content-type": "application/json",
"date": "Thu, 25 Mar 2021 06:55:28 GMT",
"connection": "close",
"via": "kong/2.0.4",
"x-kong-proxy-latency": "2",
"vary": "Accept,Accept-Language,Cookie",
"x-kong-upstream-latency": "61",
"access-control-allow-origin": "*",
"set-cookie": [
"csrftoken=VzUNkdKnHfOdNlqw5XYMXreeUooREfR8; expires=Thu, 24-Mar-2022 06:55:28 GMT; Max-Age=31449600; Path=/",
"sessionid=\".eJxNjstOwzAQRUMhtAVKJb6iKysVqdNsYcEurEZiZ40fbSxSu5PY7JD4dAxtpWzn3HPv_Ey-6WoF0ziYXlhNk488yzLUB-voGhYCY2jFBd6MYA7L3uytd8I4ffTWBbptYJmSX1aZQZwgTRuYB-PQhb-CWQNPo0qJ6jPZNIfN3qvOR80G38WQRHbsMOx8f2CJ_CvsnGZv768vZ_EOZpcc3UMGefDpTg_pkdFMi0NLC1iV26Iq11KVtd48S44F56quFTdVxaWUhUKFcisNPUb2CwjwXoY:1lPJtw:CJSWgDu_cLoRABg0Gr2R1ZuVkhA\"; expires=Thu, 25-Mar-2021 07:53:48 GMT; httponly; Max-Age=3500; Path=/"
],
"server": "Apache/2.4.7 (Ubuntu)",
"transfer-encoding": "chunked",
"allow": "GET, POST, HEAD, OPTIONS",
"content-language": "en",
"x-frame-options": "SAMEORIGIN"
},
"status": 200,
"size": "4569"
},
"route": {
"tags": [
"p1",
"p2"
],
"created_at": 1609211603,
"id": "a9d3404d-15bf-481c-88ac-63bfdb522cd4",
"service": {
"id": "6799854c-1e31-41b4-ac75-b5f55c4653a1"
},
"name": "gocv312",
"hosts": [
"gocv3"
],
"preserve_host": false,
"regex_priority": 0,
"strip_path": false,
"updated_at": 1611039120,
"https_redirect_status_code": 426,
"protocols": [
"http",
"https"
],
"path_handling": "v0"
},
"started_at": 1616655328906
}