すべてのプロダクト
Search
ドキュメントセンター

Microservices Engine:Lua プラグインの使用

最終更新日:Nov 09, 2025

Lua は、軽量で効率的なスクリプト言語です。ゲートウェイ開発では、Lua を使用して、API ゲートウェイ、メッセージゲートウェイ、リバースプロキシなど、さまざまなゲートウェイプログラムを作成および実行できます。Lua スクリプトを使用すると、開発者はリクエストルーティング、フィルタリング、認証などの機能を実装し、カスタム処理を実行できます。Lua を Nginx や Envoy などのプロキシに埋め込んで、リクエストと応答を処理したり、ログを出力したり、その他のカスタム操作を実行したりできます。このトピックでは、Envoy プロキシで Lua スクリプトを使用してリクエストと応答を処理し、それらのヘッダーと本文をログとして出力する方法について説明します。

制限事項

  • MSE クラウドネイティブゲートウェイのバージョンが 1.2.11 以降である必要があります。

  • セキュリティ上の理由から、MSE クラウドネイティブゲートウェイは、デフォルトで次の Lua ライブラリと関数を無効にします。

    • debug.debug

    • debug.getfenv

    • debug.getregistry

    • dofile

    • io

    • loadfile

    • os.execute

    • os.getenv

    • os.remove

    • os.rename

    • os.tmpname

ルーティングルールの構成

  1. MSE コンソールにログインし、上部のナビゲーションバーでリージョンを選択します。

  2. 左側のナビゲーションウィンドウで、Cloud-Native Gateway > ゲートウェイリスト を選択します。[ゲートウェイ] ページで、ゲートウェイの ID をクリックします。

  3. [ゲートウェイ詳細] ページの左側のナビゲーションウィンドウで、Plug-in Marketplace をクリックします。

  4. All Plug-ins > Custom タブで、[lua] リソースカードをクリックします。

  5. [プラグイン構成] タブで、ルールの適用レベルを選択し、ルールを構成できます。

    説明

    ゲートウェイに送信されるすべてのリクエストは、ルートレベル、ドメインレベル、インスタンスレベルの順にプラグインルールと照合されます。

    ルートレベルのプラグインルール

    1. [ルールを作成] をクリックします。表示されたページで、スイッチをオンにし、ターゲットルートを選択して、[ルールの構成] エディターに Lua スクリプトを入力します。

    2. 構成が完了したら、[OK] をクリックします。

    ドメインレベルのプラグインルール

    1. [ルールを作成] をクリックします。表示されたパネルで、スイッチをオンにし、ターゲットドメイン名を選択して、[ルールの構成] エディターに Lua スクリプトを入力します。

      重要

      Lua プラグインルールは、アスタリスク (*) を含むドメイン名をサポートしていません。

    2. 構成が完了したら、[OK] をクリックします。

    インスタンスレベルのプラグインルール

    インスタンスレベルのプラグインルールは、デフォルトで Lua プラグイン用に構成されています。ルールを編集するには、まず編集ロックを無効にする必要があります。

    1. スイッチを有効にし、[ルールの構成] エディターに Lua スクリプトを入力します。

    2. 完了したら、[保存] をクリックします。

API リファレンス

クラウドネイティブゲートウェイが提供する Lua API の詳細については、「Lua」をご参照ください。

JSON を使用するには、次のメソッドを使用します。

  • JSON データをシリアル化する: local json_str = json.encode(obj)

  • JSON データを逆シリアル化する: local obj = json.decode(json_str)

シリアル化または逆シリアル化中にエラーが発生した場合、Lua はエラー関数を呼び出してエラーをスローし、現在のプロセスを停止します。

一般的なユースケース

完全なリクエストと応答の情報をプラグインログに出力する

  1. ルーティングルールを構成する際に、次の Lua コードを使用します。

    このコードは、次の content-type 値のリクエスト本文と応答本文のみを出力します。本文は 1024 バイト (1 KB) を超えることはできません。

    • application/x-www-form-urlencoded

    • application/json

    • text/plain

    local maxBodySize = 1024
    
    function check_content_readable(type)
      if type == nil then
        return false
      end
      if string.find(type, "application/x-www-form-urlencoded",1,true) or string.find(type, "application/json",1,true) or string.find(type, "text/plain",1,true) then
         return true
      end
      return false
    end
    
    function envoy_on_request(request_handle)
      local headers = request_handle:headers()
      local headersStr = ""
      local contentType
      for key, value in pairs(headers) do
        if key == "content-type" then
           contentType = value
        end
        headersStr = headersStr  .. key .. "=" .. value .. ", "
      end
      request_handle:streamInfo():dynamicMetadata():set("envoy.lua","request_headers",headersStr)
      local requestBody = ""
      if check_content_readable(contentType) then
        for chunk in request_handle:bodyChunks() do
          if (chunk:length() > 0) then
            requestBody = requestBody .. chunk:getBytes(0, chunk:length())
          end
          if (#requestBody > maxBodySize) then
             requestBody = requestBody .. "<truncated>"
             break
          end
        end
      end
      request_handle:streamInfo():dynamicMetadata():set("envoy.lua","request_body",string.gsub(requestBody,"\n","\\n"))
    end
    
    function envoy_on_response(response_handle)
      local headers = response_handle:headers()
      local headersStr = ""
      local contentType
      local contentEncoding = false
      for key, value in pairs(headers) do
        if key == "content-type" then
           contentType = value
        elseif key == "content-encoding" then
           contentEncoding = true
        end
        headersStr = headersStr .. key .. "=" .. value .. ", "
      end
      local responseBody = ""
      if check_content_readable(contentType) and not contentEncoding then
        for chunk in response_handle:bodyChunks() do
          if (chunk:length() > 0) then
            responseBody = responseBody .. chunk:getBytes(0, chunk:length())
          end
          if (#responseBody > maxBodySize) then
             responseBody = responseBody .. "<truncated>"
             break
          end
        end
      end
      local reqHeaders = ""
      local reqBody = ""
      local metadata = response_handle:streamInfo():dynamicMetadata():get("envoy.lua")
      if metadata ~= nil then
        local headers = response_handle:streamInfo():dynamicMetadata():get("envoy.lua")["request_headers"]
        if headers ~= nil then
          reqHeaders = headers
        end
        local body = response_handle:streamInfo():dynamicMetadata():get("envoy.lua")["request_body"]
        if body ~= nil then
          reqBody = body
        end
      end
      response_handle:logInfo("request Headers: [" .. reqHeaders .. "] request Body: [" .. string.gsub(reqBody,"\n","\\n") .. "] response Headers: [" .. headersStr .. "] response Body: [" .. string.gsub(responseBody,"\n","\\n") .. "]")
    end
  2. プラグインログを表示します。

    この機能を使用するには、ゲートウェイプラグインのログ配信を有効にする必要があります。有効になっていない場合は、[ログ配信を有効にする] をクリックします。有効にすると、プラグインログは Simple Log Service (SLS) に配信され、ページで表示できます。次の図に示すように、アクセスログの request-id を使用して、Lua プラグインログで完全なリクエストと応答の情報を見つけることができます。

    1

アクセスログに完全なリクエストと応答の情報を追加する

  1. ルーティングルールを構成する際に、次の Lua コードを使用します。

    ゲートウェイのアクセスログパラメーターは、カスタム動的メタデータをサポートしています。まず、プラグインでメタデータを定義する必要があります。次のコードは、リクエストヘッダー、リクエストボディ、レスポンスヘッダー、レスポンスボディに対応する 4 つのメタデータフィールドを定義します:

    • envoy.lua:request_headers

    • envoy.lua:request_body

    • envoy.lua:response_headers

    • envoy.lua:response_body

    local maxBodySize = 1024
    
    function check_content_readable(type)
      if type == nil then
        return false
      end
      if string.find(type, "application/x-www-form-urlencoded",1,true) or string.find(type, "application/json",1,true) or string.find(type, "text/plain",1,true) then
         return true
      end
      return false
    end
    
    function envoy_on_request(request_handle)
      local headers = request_handle:headers()
      local headersStr = ""
      local contentType
      for key, value in pairs(headers) do
        if key == "content-type" then
           contentType = value
        end
        headersStr = headersStr  .. key .. "=" .. value .. ", "
      end
      request_handle:streamInfo():dynamicMetadata():set("envoy.lua","request_headers",headersStr)
      local requestBody = ""
      if check_content_readable(contentType) then
        for chunk in request_handle:bodyChunks() do
          if (chunk:length() > 0) then
            requestBody = requestBody .. chunk:getBytes(0, chunk:length())
          end
          if (#requestBody > maxBodySize) then
             requestBody = requestBody .. "<truncated>"
             break
          end
        end
      end
      request_handle:streamInfo():dynamicMetadata():set("envoy.lua","request_body",string.gsub(requestBody,"\n","\\n"))
    end
    
    function envoy_on_response(response_handle)
      local headers = response_handle:headers()
      local headersStr = ""
      local contentType
      local contentEncoding = false
      for key, value in pairs(headers) do
        if key == "content-type" then
           contentType = value
        elseif key == "content-encoding" then
           contentEncoding = true
        end
        headersStr = headersStr .. key .. "=" .. value .. ", "
      end
      response_handle:streamInfo():dynamicMetadata():set("envoy.lua","response_headers",headersStr)
      local responseBody = ""
      if check_content_readable(contentType) and not contentEncoding then
        for chunk in response_handle:bodyChunks() do
          if (chunk:length() > 0) then
            responseBody = responseBody .. chunk:getBytes(0, chunk:length())
          end
          if (#responseBody > maxBodySize) then
             responseBody = responseBody .. "<truncated>"
             break
          end
        end
      end
      response_handle:streamInfo():dynamicMetadata():set("envoy.lua","response_body",string.gsub(responseBody,"\n","\\n"))
    end
  2. ログフォーマットを調整します。

    ゲートウェイインスタンスの左側のナビゲーションウィンドウで、[パラメーター設定] をクリックし、次に [デフォルトフォーマット (クリックしてカスタマイズ)] をクリックします。対応するメタデータをカスタムログフィールドに追加します。その後、アクセスログでメタデータを表示できます。

    image