lua-resty-moesif

A Lua library for Moesif, compatible with Openresty

Moesif Plugin for NGINX OpenResty

NGINX OpenResty plugin that logs API calls to Moesif for API analytics and monitoring. This plugin can be used with a generic NGINX OpenResty installation or for API gateways that are built on top of OpenResty such as 3Scale API Gateway.

Github Repo

How to install

The recommended way to install Moesif is via Luarocks:

    luarocks install --server=http://luarocks.org/manifests/moesif lua-resty-moesif

Alternatively, OpenResty provides its own package manager, OPM, which can be used to install Moesif. Keep in mind OPM is not well maintained and release acceptance may be delayed by a few days, which is why we recommend LuaRocks, if possible.

    opm get Moesif/lua-resty-moesif

How to use (Generic OpenResty)

Edit your nginx.conf file to configure Moesif OpenResty plugin: Replace /usr/local/openresty/luajit/share/lua/5.1/resty with the correct lua plugin installation path, if necessary.

If you're unsure of the installation path, you can find it via: find / -name "moesif" -type d. Sometimes luarocks installs packages in multiple locations, just choose one.

    lua_shared_dict moesif_conf 5m;
    
    init_by_lua_block {
       local config = ngx.shared.moesif_conf;
       config:set("application_id", "Your Moesif Application Id")
    }
    
    lua_package_cpath ";;${prefix}?.so;${prefix}src/?.so;/usr/share/lua/5.1/lua/resty/moesif/?.so;/usr/share/lua/5.1/?.so;/usr/lib64/lua/5.1/?.so;/usr/lib/lua/5.1/?.so;/usr/local/openresty/luajit/share/lua/5.1/lua/resty?.so";
    lua_package_path ";;${prefix}?.lua;${prefix}src/?.lua;/usr/share/lua/5.1/lua/resty/moesif/?.lua;/usr/share/lua/5.1/?.lua;/usr/lib64/lua/5.1/?.lua;/usr/lib/lua/5.1/?.lua;/usr/local/openresty/luajit/share/lua/5.1/lua/resty?.lua";
    
    server {
      listen 80;
      resolver 8.8.8.8;
    
      # Customer identity variables that Moesif will read downstream
      set $moesif_user_id nil;
      set $moesif_company_id nil;
    
      # Request/Response body variable that Moesif will use downstream
      set $moesif_req_body nil;
      set $moesif_res_body nil;
    
      # Optionally, identify the user and the company (account)
      # from a request or response header, query param, NGINX var, etc
      header_filter_by_lua_block  { 
        ngx.var.moesif_user_id = ngx.req.get_headers()["X-User-Id"]
        ngx.var.moesif_company_id = ngx.req.get_headers()["X-Company-Id"]
      }
    
      access_by_lua_file /usr/local/openresty/luajit/share/lua/5.1/resty/moesif/read_req_body.lua;
      body_filter_by_lua_file /usr/local/openresty/luajit/share/lua/5.1/resty/moesif/read_res_body.lua;
      log_by_lua_file /usr/local/openresty/luajit/share/lua/5.1/resty/moesif/send_event.lua;
    
      # Sample Hello World API
      location /api {
         add_header Content-Type "application/json";
         return 200 '{\r\n  \"message\": \"Hello World\",\r\n  \"completed\": true\r\n}';
      }
    }

How to use (3Scale API Gateway)

Installing Moesif plugin for 3Scale API Gateway is the same as vanilla installation except for two changes:

  1. Add 3scale specific configuration options to fetch additional user context from 3scale management API

  2. Replace send_event.lua, with send_event_3Scale.lua

Edit your nginx.conf file to configure Moesif OpenResty plugin: Replace /usr/share/lua/5.1/lua/resty with the correct lua plugin installation path, if necessary.

If you're unsure of the installation path, you can find it via: find / -name "moesif" -type d. Sometimes luarocks installs packages in multiple locations, just choose one.

Below is a sample configuration for 3scale:

    lua_shared_dict moesif_conf 5m;
    lua_shared_dict user_id_cache 5m;
    lua_shared_dict company_id_cache 5m;
    
    init_by_lua_block {
       local config = ngx.shared.moesif_conf;
       config:set("application_id", "Your Moesif Application Id")
       config:set("3scale_domain", "YOUR_ACCOUNT-admin.3scale.net")
       config:set("3scale_access_token", "Your 3scale Access Token")
    }
    
    lua_package_cpath ";;${prefix}?.so;${prefix}src/?.so;/usr/share/lua/5.1/lua/resty/moesif/?.so;/usr/share/lua/5.1/?.so;/usr/lib64/lua/5.1/?.so;/usr/lib/lua/5.1/?.so;/usr/local/openresty/luajit/share/lua/5.1/lua/resty?.so";
    lua_package_path ";;${prefix}?.lua;${prefix}src/?.lua;/usr/share/lua/5.1/lua/resty/moesif/?.lua;/usr/share/lua/5.1/?.lua;/usr/lib64/lua/5.1/?.lua;/usr/lib/lua/5.1/?.lua;/usr/local/openresty/luajit/share/lua/5.1/lua/resty?.lua";
    
    server {
      listen 80;
      resolver 8.8.8.8;
    
      # Customer identity variables that Moesif will read downstream
      # Set automatically from 3scale management API
      set $moesif_user_id nil;
      set $moesif_company_id nil;
    
      # Request/Response body variable that Moesif will use downstream
      set $moesif_req_body nil;
      set $moesif_res_body nil;
    
      access_by_lua_file /usr/share/lua/5.1/lua/resty/moesif/read_req_body.lua;
      body_filter_by_lua_file /usr/share/lua/5.1/lua/resty/moesif/read_res_body.lua;
      log_by_lua_file /usr/share/lua/5.1/lua/resty/moesif/send_event_3Scale.lua;
    
      # Sample Hello World API
      location /api {
          add_header Content-Type "application/json";
          return 200 '{\r\n  \"message\": \"Hello World\",\r\n  \"completed\": true\r\n}';
      }
    }

Configuration options

Static options that are set once on startup such as in init_by_lua_block.

application_id__

(required), string, Application Id to authenticate with Moesif.

disable_capture_request_body__

(optional) boolean, An option to disable logging of request body. false by default.

disable_capture_response_body__

(optional) boolean, An option to disable logging of response body. false by default.

request_header_masks__

(optional) string, An option to mask a specific request header fields. Separate multiple fields by comma such as "header_a, header_b"

request_body_masks__

(optional) string, An option to mask a specific request body fields. Separate multiple fields by comma such as "field_a, field_b"

response_header_masks__

(optional) string, An option to mask a specific response header fields. Separate multiple fields by comma such as "header_a, header_b"

response_body_masks__

(optional) string, An option to mask a specific response body fields. Separate multiple fields by comma such as "field_a, field_b"

disable_transaction_id__

(optional) boolean, Setting to true will prevent insertion of the <code>X-Moesif-Transaction-Id</code> header. false by default.

debug__

(optional) boolean, Set to true to print debug logs if you're having integration issues.

3Scale specific options

If you installed for 3Scale API Gateway using send_event_3Scale.lua, you have additional static options:

3scale_domain__

(required), string, your full 3Scale admin domain such as YOUR_ACCOUNT-admin.3scale.net.

3scale_access_token__

(required), string, an admin ACCESS_TOKEN, that you can get from your 3scale admin portal.

3scale_user_id_name__

(optional) string, The 3scale field name from 3scale's application XML entity used to identify the user in Moesif. This is id by default., but other valid examples include user_account_id and service_id. More info.

3scale_auth_api_key__

(optional) string, If you configured 3scale to authenticate via a single userkey_ string, set the field name here. This is user_key by default. More info.

3scale_auth_app_id__

(optional) string, If you configured 3scale to authenticate via appid_ and appkey_ pair, set app_id field name here. This is app_id by default. If set, you need to set 3scale_auth_app_key_pair. More info.

3scale_auth_app_key_pair__

(optional) string, If you configured 3scale to authenticate via appid_ and appkey_ pair, set app_key field name here. This is app_key by default. If set, you need to set 3scale_auth_app_id. More info.

Dynamic variables

Variables that are dynamic for each HTTP request. Set these variables on the ngx.var dictionary such as in header_filter_by_lua_block or in a body_filter_by_lua_block.

    header_filter_by_lua_block  { 
      -- Read user id from request query param
      ngx.var.moesif_user_id     = ngx.req.arg_user_id
      
      -- Read version from request header
      ngx.var.moesif_api_version = ngx.req.get_headers()["X-API-Version"]
    }
    
    body_filter_by_lua_block  { 
      -- Read company id from response header
      ngx.var.moesif_company_id  = ngx.resp.get_headers()["X-Company-Id"]
    }

moesif_user_id__

(optional) string, Attribute API requests to individual users so you can track who calling your API. This can also be used with ngx.var.moesif_company_id to track account level usage. If you installed for 3scale, you do not need to set this field as this is handled automatically

moesif_company_id__

(optional) string, Attribute API requests to companies or accounts so you can track who calling your API. This can be used with ngx.var.moesif_company_id. If you installed for 3scale, you do not need to set this field as this is handled automatically

moesif_api_version__

(optional) boolean, An optional API Version you want to tag this request with.

Troubleshooting

Response body not being logged

If you find response body is not being logged in Moesif, your setup may require an internal proxy_pass which can be added with a few lines of code to your nginx.conf.

For the following sample server:

    server {
      listen 80;
      resolver 8.8.8.8;
    
      # Sample Hello World API
      location /api {
         add_header Content-Type "application/json";
         return 200 '{\r\n  \"message\": \"Hello World\",\r\n  \"completed\": true\r\n}';
      }
    }

One with proxy_pass would look like so:

    server {
      listen 80;
      resolver 8.8.8.8;
    
      # Sample Hello World API
      location /api {
        proxy_pass http://127.0.0.1:80/internal;
      }
    
      location /internal {
          add_header Content-Type "application/json";
          return 200 '{\r\n  \"message\": \"Hello World\",\r\n  \"completed\": true\r\n}';
      }
    }

Example

An example Moesif integration is available based on the quick start tutorial of Openresty

Congratulations! If everything was done correctly, Moesif should now be tracking all network requests that match the route you specified earlier. If you have any issues with set up, please reach out to support@moesif.com.

Other integrations

To view more documentation on integration options, please visit the Integration Options Documentation.

POD ERRORS

Hey! The above document had some coding errors, which are explained below:

Around line 150:

Unterminated B<...> sequence

Around line 155:

Unterminated B<...> sequence

Around line 160:

Unterminated B<...> sequence

Around line 165:

Unterminated B<...> sequence

Around line 170:

Unterminated B<...> sequence

Around line 175:

Unterminated B<...> sequence

Around line 180:

Unterminated B<...> sequence

Around line 185:

Unterminated B<...> sequence

Around line 190:

Unterminated B<...> sequence

Around line 202:

Unterminated B<...> sequence

Around line 207:

Unterminated B<...> sequence

Around line 212:

Unterminated B<...> sequence

Around line 218:

Unterminated B<...> sequence

Around line 224:

Unterminated B<...> sequence

Around line 230:

Unterminated B<...> sequence

Around line 257:

Unterminated B<...> sequence

Around line 263:

Unterminated B<...> sequence

Around line 269:

Unterminated B<...> sequence

Authors

Keyur Doshi (Moesif)

License

2bsd

Versions