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

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

最終更新日:Mar 01, 2026

Lua は、軽量で高効率なスクリプト言語です。ゲートウェイ開発において、Lua を使用して、API ゲートウェイ、メッセージゲートウェイ、リバースプロキシなど、さまざまなゲートウェイプログラムを作成・実行できます。開発者は Lua を使用して、リクエストのルーティング、フィルタリング、認証のためのスクリプトを作成し、カスタマイズされた処理を実行できます。Lua は、NGINX や Envoy などのプロキシに埋め込んで、リクエストとレスポンスの処理、ログ出力、その他のカスタマイズされた操作を実行できます。このトピックでは、Lua を Envoy プロキシに埋め込んでリクエストとレスポンスを処理し、リクエストとレスポンスのヘッダーとボディをログに記録する方法について説明します。

制限事項

  • ご利用の Microservices Engine (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 に配布され、コンソールで表示できます。次の図に示すように、アクセスログの 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