From fcb1078cae6bb1ad0f8c59f302eccfdb91a3cbd4 Mon Sep 17 00:00:00 2001 From: Andra Lungu Date: Tue, 31 May 2016 17:41:10 +0300 Subject: [PATCH 1/5] Added tracing support --- .../tracking/RequestTrackingManager.lua | 9 +- src/lua/api-gateway/tracking/factory.lua | 10 +- .../validator/debuggingRulesValidator.lua | 42 +++++++ .../validator/delayingRulesValidator.lua | 3 + .../validator/tracingRulesValidator.lua | 80 +++++++++++++ .../validator/tracingRulesValidator.t | 110 ++++++++++++++++++ 6 files changed, 250 insertions(+), 4 deletions(-) create mode 100644 src/lua/api-gateway/tracking/validator/debuggingRulesValidator.lua create mode 100644 src/lua/api-gateway/tracking/validator/tracingRulesValidator.lua create mode 100644 test/perl/api-gateway/tracking/validator/tracingRulesValidator.t diff --git a/src/lua/api-gateway/tracking/RequestTrackingManager.lua b/src/lua/api-gateway/tracking/RequestTrackingManager.lua index fdfa30b..a848a48 100644 --- a/src/lua/api-gateway/tracking/RequestTrackingManager.lua +++ b/src/lua/api-gateway/tracking/RequestTrackingManager.lua @@ -14,7 +14,7 @@ -- --- Exposes utility functions to add/remove Tracking rules ( BLOCK, TRACK, DEBUG, DELAY, RETRY-AFTER ) +-- Exposes utility functions to add/remove Tracking rules ( BLOCK, TRACK, TRACE, DEBUG, DELAY, RETRY-AFTER ) -- -- You should map this to a REST API Endpoint: -- @@ -34,6 +34,7 @@ local KNWON_RULES = { BLOCK = "blocking_rules_dict", TRACK = "tracking_rules_dict", + TRACE = "traceing_rules_dict", DEBUG = "debuging_rules_dict", DELAY = "delaying_rules_dict", REWRITE = "rewriting_rules_dict", @@ -43,6 +44,7 @@ local KNWON_RULES = local last_modified_date = { BLOCK = -1, TRACK = -1, + TRACE = -1, DEBUG = -1, DELAY = -1, REWRITE = -1, @@ -52,6 +54,7 @@ local last_modified_date = { local cached_rules = { BLOCK = {}, --- holds a per worker cache of the BLOCK rules TRACK = {}, --- holds a per worker cache of the TRACK rules + TRACE = {}, --- holds a per worker cache of the TRACE rules DEBUG = {}, --- holds a per worker cache of the DEBUG rules DELAY = {}, --- holds a per worker cache of the DELAY rules REWRITE = {}, --- holds a per worker cache of the REWRITE rules @@ -140,7 +143,7 @@ end --- Returns an object with the current active rules for the given rule_type -- --- @param rule_type BLOCK, TRACK, DEBUG, DELAY or RETRY-AFTER +-- @param rule_type BLOCK, TRACK, TRACE, DEBUG, DELAY or RETRY-AFTER -- function _M:getRulesForType(rule_type) local rule_type = string.upper(rule_type) @@ -268,7 +271,7 @@ end --- -- Returns an object with only the rules matching the current request variables. It's up to the caller to decide what to do with the result --- @param rule_type BLOCK, TRACK, DEBUG, DELAY or RETRY-AFTER +-- @param rule_type BLOCK, TRACK, TRACE, DEBUG, DELAY or RETRY-AFTER -- @param separator For instance ";". It's the character separating the values and variables -- @param exit_on_first_match Default:true. When true the method exits on the first match. -- This is useful for BLOCK, DELAY or RETRY-AFTER behaviours when the first match would alter the request status. diff --git a/src/lua/api-gateway/tracking/factory.lua b/src/lua/api-gateway/tracking/factory.lua index 5b126ba..dd190cf 100644 --- a/src/lua/api-gateway/tracking/factory.lua +++ b/src/lua/api-gateway/tracking/factory.lua @@ -30,6 +30,8 @@ local RequestTrackingManager = require "api-gateway.tracking.RequestTrackingMana local RequestVariableManager = require "api-gateway.tracking.RequestVariableManager" local BlockingRulesValidator = require "api-gateway.tracking.validator.blockingRulesValidator" local DelayingRulesValidator = require "api-gateway.tracking.validator.delayingRulesValidator" +local TracingRulesValidator = require "api-gateway.tracking.validator.tracingRulesValidator" +local DebuggingRulesValidator = require "api-gateway.tracking.validator.debuggingRulesValidator" local TrackingRulesLogger = require "api-gateway.tracking.log.trackingRulesLogger" local cjson = require "cjson" @@ -75,12 +77,17 @@ local function _validateServicePlan() return delayingRulesValidator:validateRequest() end +local function _traceRequest() + local tracingRulesValidator = TracingRulesValidator:new() + return tracingRulesValidator:validate_tracing_rules() +end + --- Track the rules that are active, sending an async message to a queue with the usage -- This method should be called from the log phase ( log_by_lua ) -- local function _trackRequest() local trackingRulesLogger = TrackingRulesLogger:new() - return trackingRulesLogger:log() + return trackingRulesLogger:log() end return { @@ -88,6 +95,7 @@ return { variableManager = RequestVariableManager, validateServicePlan = _validateServicePlan, track = _trackRequest, + trace = _traceRequest, POST_HANDLER = _API_POST_Handler, GET_HANDLER = _API_GET_Handler } \ No newline at end of file diff --git a/src/lua/api-gateway/tracking/validator/debuggingRulesValidator.lua b/src/lua/api-gateway/tracking/validator/debuggingRulesValidator.lua new file mode 100644 index 0000000..2a23735 --- /dev/null +++ b/src/lua/api-gateway/tracking/validator/debuggingRulesValidator.lua @@ -0,0 +1,42 @@ +--[[ + Copyright 2016 Adobe Systems Incorporated. All rights reserved. + + This file is licensed to you under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software distributed under the License + is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR RESPRESENTATIONS OF ANY KIND, + either express or implied. See the License for the specific language governing permissions and + limitations under the License. + ]] + +local BaseValidator = require "api-gateway.validation.validator" +local _M = BaseValidator:new() + +--- +-- @param config_obj configuration object +-- returns the meta field of the first matched rule. +-- +function _M:validate_debug_rules(config_obj) + local trackingManager = ngx.apiGateway.tracking.manager + if ( trackingManager == nil ) then + ngx.log(ngx.WARN, "Please initialize RequestTrackingManager before calling this method") + end + -- 1. read the keys in the shared dict and compare it with the current request + local stop_at_first_block_match = true + local debug_rule = trackingManager:getMatchingRulesForRequest("debug",";", stop_at_first_block_match) + if debug_rule == nil then -- there is no match, so we return nil + return nil + end + + return debug_rule.meta or nil +end + +function _M:validateRequest(obj) + local debug_message = self:validate_trace_rules(obj) + return debug_message +end + +return _M \ No newline at end of file diff --git a/src/lua/api-gateway/tracking/validator/delayingRulesValidator.lua b/src/lua/api-gateway/tracking/validator/delayingRulesValidator.lua index b46b9e9..4e68bde 100644 --- a/src/lua/api-gateway/tracking/validator/delayingRulesValidator.lua +++ b/src/lua/api-gateway/tracking/validator/delayingRulesValidator.lua @@ -39,6 +39,9 @@ local function getActualDelay( delaying_rule ) return math.random( actualDelay / 2, actualDelay ) end +--- +-- @param config_obj configuration object +-- function _M:validate_delaying_rules(config_obj) local trackingManager = ngx.apiGateway.tracking.manager if ( trackingManager == nil ) then diff --git a/src/lua/api-gateway/tracking/validator/tracingRulesValidator.lua b/src/lua/api-gateway/tracking/validator/tracingRulesValidator.lua new file mode 100644 index 0000000..c7ad0b9 --- /dev/null +++ b/src/lua/api-gateway/tracking/validator/tracingRulesValidator.lua @@ -0,0 +1,80 @@ +--[[ + Copyright 2016 Adobe Systems Incorporated. All rights reserved. + + This file is licensed to you under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software distributed under the License + is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR RESPRESENTATIONS OF ANY KIND, + either express or implied. See the License for the specific language governing permissions and + limitations under the License. + ]] + +local cjson = require "cjson" +local BaseValidator = require "api-gateway.validation.validator" +local _M = BaseValidator:new() + +local kinesisLogger + +function _M:sendKinesisMessage(kinesis_data) + local partition_key = ngx.utctime() .."-".. math.random(ngx.now() * 1000) + + -- Send logs to kinesis + kinesisLogger:logMetrics(partition_key, cjson.encode(kinesis_data)) + +end + +function _M:getKinesisMessage(rule) + local kinesis_data = {} + + kinesis_data["id"] = tostring(rule.id) + kinesis_data["domain"] = tostring(rule.domain) + kinesis_data["request_body"] = tostring(ngx.var.request_body) + + for key,value in pairs(ngx.header) do + kinesis_data[tostring(key)] = tostring(value) + end + + return kinesis_data +end + +--- +-- @param config_obj configuration object +-- +function _M:validate_trace_rules(config_obj) + local trackingManager = ngx.apiGateway.tracking.manager + if ( trackingManager == nil ) then + ngx.log(ngx.WARN, "Please initialize RequestTrackingManager before calling this method") + end + + kinesisLogger = ngx.apiGateway.getAsyncLogger("kinesis-logger") + if ( kinesisLogger == nil ) then + ngx.log(ngx.WARN, "Could not track request. kinesis logger should not be nil") + return + end + + -- 1. read the keys in the shared dict and compare them with the current request + local stop_at_first_block_match = false + local traceing_rules = trackingManager:getMatchingRulesForRequest("trace", ";", stop_at_first_block_match) + if (traceing_rules == nil) then + return + end + -- 2. for each traceing rule matching the request publish a kinesis message asyncronously + for i, rule in pairs(traceing_rules) do + if ( rule ~= nil ) then + local message = self:getKinesisMessage(rule) + self:sendMessage(message) + end + end +end + +function _M:validateRequest(obj) + local traced_message = self:validate_trace_rules(obj) + return traced_message +end + +return _M + + diff --git a/test/perl/api-gateway/tracking/validator/tracingRulesValidator.t b/test/perl/api-gateway/tracking/validator/tracingRulesValidator.t new file mode 100644 index 0000000..bbc988b --- /dev/null +++ b/test/perl/api-gateway/tracking/validator/tracingRulesValidator.t @@ -0,0 +1,110 @@ +# /* +# * Copyright 2016 Adobe Systems Incorporated. All rights reserved. +# * +# * This file is licensed to you under the Apache License, Version 2.0 (the "License"); +# * you may not use this file except in compliance with the License. You may obtain a copy of the License at +# * +# * http://www.apache.org/licenses/LICENSE-2.0 +# * +# * Unless required by applicable law or agreed to in writing, software distributed under the License +# * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR RESPRESENTATIONS OF ANY KIND, +# * either express or implied. See the License for the specific language governing permissions and +# * limitations under the License. +# */ +# vim:set ft= ts=4 sw=4 et fdm=marker: +use lib 'lib'; +use strict; +use warnings; +use Test::Nginx::Socket::Lua; +use Cwd qw(cwd); + +#worker_connections(1014); +#master_process_enabled(1); +#log_level('warn'); + +repeat_each(1); + +plan tests => repeat_each() * (blocks() * 5) + 1 ; + +my $pwd = cwd(); + +our $HttpConfig = <<_EOC_; + # lua_package_path "$pwd/scripts/?.lua;;"; + lua_package_path "src/lua/?.lua;/usr/local/lib/lua/?.lua;;"; + init_by_lua ' + local v = require "jit.v" + v.on("$Test::Nginx::Util::ErrLogFile") + require "resty.core" + '; + init_worker_by_lua ' + ngx.apiGateway = ngx.apiGateway or {} + ngx.apiGateway.validation = require "api-gateway.validation.factory" + ngx.apiGateway.tracking = require "api-gateway.tracking.factory" + '; + include "$pwd/conf.d/http.d/*.conf"; + upstream cache_rw_backend { + server 127.0.0.1:6379; + } + upstream cache_read_only_backend { # Default config for redis health check test + server 127.0.0.1:6379; + } + lua_shared_dict blocking_rules_dict 5m; + lua_shared_dict tracking_rules_dict 5m; + lua_shared_dict traceing_rules_dict 5m; + lua_shared_dict debugging_rules_dict 5m; + lua_shared_dict delaying_rules_dict 5m; + lua_shared_dict retrying_rules_dict 5m; + + client_body_temp_path /tmp/; + proxy_temp_path /tmp/; + fastcgi_temp_path /tmp/; +_EOC_ + +#no_diff(); +no_long_string(); +run_tests(); + +__DATA__ + + +=== TEST 1: test that we can trace the request +--- http_config eval: $::HttpConfig +--- config + include ../../api-gateway/default_validators.conf; + include ../../api-gateway/tracking_service.conf; + set $publisher_org_name 'pub1'; + + error_log ../test-logs/tracingRequestValidator_test1_error.log debug; + + location ~ /trace { + set $validate_service_plan "on; path=/validate_service_plan; order=1; "; + + access_by_lua "ngx.apiGateway.validation.validateRequest()"; + content_by_lua 'ngx.say(ngx.var.validate_request_response_time)'; + + } +--- timeout: 10 +--- pipelined_requests eval +['POST /tracking/ +[{ + "id": 222, + "domain" : "pub1", + "format": "$publisher_org_name;$subpath", + "expire_at_utc": 1583910454, + "action" : "TRACE" +}] +', +"GET /trace" +] +--- response_body_like eval +[ +'\{"result":"success"\}.*', +'0', +'(\d{2,4})+', +'(\d{2,4})+', +'.*{"domain":"pub1","format":"\$publisher_org_name;\$subpath","id":222,"action":"TRACE","expire_at_utc":1583910454}.*' +] +--- error_code_like eval + [200, 200, 200, 200, 200] +--- no_error_log +[error] From 42688b84ce16b5adea478e5021f8f4b66d83d5f7 Mon Sep 17 00:00:00 2001 From: Andra Lungu Date: Wed, 1 Jun 2016 18:26:57 +0300 Subject: [PATCH 2/5] Merged debug and trace logic in a single file. (WIP - needs extra tests and bug fixes) --- .../tracking/RequestTrackingManager.lua | 2 +- .../tracking/RequestVariableManager.lua | 8 ++- src/lua/api-gateway/tracking/factory.lua | 12 ++-- .../tracingRulesLogger.lua} | 58 +++++++++++++------ .../validator/debuggingRulesValidator.lua | 42 -------------- .../tracingRulesLogger.t} | 19 ++++-- .../tracking/log/trackingRulesLogger.t | 5 ++ 7 files changed, 70 insertions(+), 76 deletions(-) rename src/lua/api-gateway/tracking/{validator/tracingRulesValidator.lua => log/tracingRulesLogger.lua} (53%) delete mode 100644 src/lua/api-gateway/tracking/validator/debuggingRulesValidator.lua rename test/perl/api-gateway/tracking/{validator/tracingRulesValidator.t => log/tracingRulesLogger.t} (85%) diff --git a/src/lua/api-gateway/tracking/RequestTrackingManager.lua b/src/lua/api-gateway/tracking/RequestTrackingManager.lua index a848a48..4760e98 100644 --- a/src/lua/api-gateway/tracking/RequestTrackingManager.lua +++ b/src/lua/api-gateway/tracking/RequestTrackingManager.lua @@ -34,7 +34,7 @@ local KNWON_RULES = { BLOCK = "blocking_rules_dict", TRACK = "tracking_rules_dict", - TRACE = "traceing_rules_dict", + TRACE = "tracing_rules_dict", DEBUG = "debuging_rules_dict", DELAY = "delaying_rules_dict", REWRITE = "rewriting_rules_dict", diff --git a/src/lua/api-gateway/tracking/RequestVariableManager.lua b/src/lua/api-gateway/tracking/RequestVariableManager.lua index 550e70b..68de4c6 100644 --- a/src/lua/api-gateway/tracking/RequestVariableManager.lua +++ b/src/lua/api-gateway/tracking/RequestVariableManager.lua @@ -31,12 +31,16 @@ function _M:getRequestVariable(request_var, cache) local ctx_var = ngx.ctx[request_var] if ctx_var ~= nil then - cache[request_var] = ctx_var + if cache ~= nil then + cache[request_var] = ctx_var + end return ctx_var end local ngx_var = ngx.var[request_var] - cache[request_var] = ngx_var + if cache ~= nil then + cache[request_var] = ngx_var + end return ngx_var end diff --git a/src/lua/api-gateway/tracking/factory.lua b/src/lua/api-gateway/tracking/factory.lua index dd190cf..dc252de 100644 --- a/src/lua/api-gateway/tracking/factory.lua +++ b/src/lua/api-gateway/tracking/factory.lua @@ -30,8 +30,7 @@ local RequestTrackingManager = require "api-gateway.tracking.RequestTrackingMana local RequestVariableManager = require "api-gateway.tracking.RequestVariableManager" local BlockingRulesValidator = require "api-gateway.tracking.validator.blockingRulesValidator" local DelayingRulesValidator = require "api-gateway.tracking.validator.delayingRulesValidator" -local TracingRulesValidator = require "api-gateway.tracking.validator.tracingRulesValidator" -local DebuggingRulesValidator = require "api-gateway.tracking.validator.debuggingRulesValidator" +local TracingRulesLogger = require "api-gateway.tracking.log.tracingRulesLogger" local TrackingRulesLogger = require "api-gateway.tracking.log.trackingRulesLogger" local cjson = require "cjson" @@ -77,15 +76,13 @@ local function _validateServicePlan() return delayingRulesValidator:validateRequest() end -local function _traceRequest() - local tracingRulesValidator = TracingRulesValidator:new() - return tracingRulesValidator:validate_tracing_rules() -end - --- Track the rules that are active, sending an async message to a queue with the usage -- This method should be called from the log phase ( log_by_lua ) -- local function _trackRequest() + local tracingRulesLogger = TracingRulesLogger:new() + tracingRulesLogger:log_trace_rules() + local trackingRulesLogger = TrackingRulesLogger:new() return trackingRulesLogger:log() end @@ -95,7 +92,6 @@ return { variableManager = RequestVariableManager, validateServicePlan = _validateServicePlan, track = _trackRequest, - trace = _traceRequest, POST_HANDLER = _API_POST_Handler, GET_HANDLER = _API_GET_Handler } \ No newline at end of file diff --git a/src/lua/api-gateway/tracking/validator/tracingRulesValidator.lua b/src/lua/api-gateway/tracking/log/tracingRulesLogger.lua similarity index 53% rename from src/lua/api-gateway/tracking/validator/tracingRulesValidator.lua rename to src/lua/api-gateway/tracking/log/tracingRulesLogger.lua index c7ad0b9..f9f0bdd 100644 --- a/src/lua/api-gateway/tracking/validator/tracingRulesValidator.lua +++ b/src/lua/api-gateway/tracking/log/tracingRulesLogger.lua @@ -13,16 +13,31 @@ ]] local cjson = require "cjson" -local BaseValidator = require "api-gateway.validation.validator" -local _M = BaseValidator:new() +local _M = {} local kinesisLogger +function _M:new(o) + local o = o or {} + setmetatable(o, self) + self.__index = self + return o +end + function _M:sendKinesisMessage(kinesis_data) - local partition_key = ngx.utctime() .."-".. math.random(ngx.now() * 1000) - -- Send logs to kinesis - kinesisLogger:logMetrics(partition_key, cjson.encode(kinesis_data)) + local kinesisSwitch = ngx.var.kinesisSwitch + if (kinesisSwitch == nil or kinesisSwitch == "") then + kinesisSwitch = "on" + end + if ( kinesisLogger ~= nil and (kinesisSwitch ~= nil and kinesisSwitch == "on")) then + local partition_key = ngx.utctime() .."-".. math.random(ngx.now() * 1000) + + -- Send logs to kinesis + kinesisLogger:logMetrics(partition_key, cjson.encode(kinesis_data)) + else + ngx.log(ngx.WARN, "Trace info not sent to kinesis") + end end @@ -37,19 +52,29 @@ function _M:getKinesisMessage(rule) kinesis_data[tostring(key)] = tostring(value) end + local meta = rule.meta + local meta_length = table.getn(meta) + + local var_value, index + for index = 1, meta_length do + local variableManager = ngx.apiGateway.tracking.variableManager + var_value = variableManager:getRequestVariable(meta[index], nil) + kinesis_data[tostring(meta[index])] = tostring(var_value) + end + return kinesis_data end --- -- @param config_obj configuration object -- -function _M:validate_trace_rules(config_obj) +function _M:log_trace_rules(config_obj) local trackingManager = ngx.apiGateway.tracking.manager if ( trackingManager == nil ) then ngx.log(ngx.WARN, "Please initialize RequestTrackingManager before calling this method") end - kinesisLogger = ngx.apiGateway.getAsyncLogger("kinesis-logger") + kinesisLogger = ngx.apiGateway.getAsyncLogger("api-gateway-debugging") if ( kinesisLogger == nil ) then ngx.log(ngx.WARN, "Could not track request. kinesis logger should not be nil") return @@ -57,24 +82,21 @@ function _M:validate_trace_rules(config_obj) -- 1. read the keys in the shared dict and compare them with the current request local stop_at_first_block_match = false - local traceing_rules = trackingManager:getMatchingRulesForRequest("trace", ";", stop_at_first_block_match) - if (traceing_rules == nil) then + local tracing_rules = trackingManager:getMatchingRulesForRequest("trace", ";", stop_at_first_block_match) + if (tracing_rules == nil) then return end - -- 2. for each traceing rule matching the request publish a kinesis message asyncronously - for i, rule in pairs(traceing_rules) do + -- 2. for each tracing rule matching the request publish a kinesis message asyncronously + for i, rule in pairs(tracing_rules) do if ( rule ~= nil ) then local message = self:getKinesisMessage(rule) - self:sendMessage(message) + if ( message ~= nil ) then + ngx.log(ngx.DEBUG, "Sending tracing info to kinesis: " .. cjson.encode(message)) + self:sendKinesisMessage(message) + end end end end -function _M:validateRequest(obj) - local traced_message = self:validate_trace_rules(obj) - return traced_message -end - return _M - diff --git a/src/lua/api-gateway/tracking/validator/debuggingRulesValidator.lua b/src/lua/api-gateway/tracking/validator/debuggingRulesValidator.lua deleted file mode 100644 index 2a23735..0000000 --- a/src/lua/api-gateway/tracking/validator/debuggingRulesValidator.lua +++ /dev/null @@ -1,42 +0,0 @@ ---[[ - Copyright 2016 Adobe Systems Incorporated. All rights reserved. - - This file is licensed to you under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software distributed under the License - is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR RESPRESENTATIONS OF ANY KIND, - either express or implied. See the License for the specific language governing permissions and - limitations under the License. - ]] - -local BaseValidator = require "api-gateway.validation.validator" -local _M = BaseValidator:new() - ---- --- @param config_obj configuration object --- returns the meta field of the first matched rule. --- -function _M:validate_debug_rules(config_obj) - local trackingManager = ngx.apiGateway.tracking.manager - if ( trackingManager == nil ) then - ngx.log(ngx.WARN, "Please initialize RequestTrackingManager before calling this method") - end - -- 1. read the keys in the shared dict and compare it with the current request - local stop_at_first_block_match = true - local debug_rule = trackingManager:getMatchingRulesForRequest("debug",";", stop_at_first_block_match) - if debug_rule == nil then -- there is no match, so we return nil - return nil - end - - return debug_rule.meta or nil -end - -function _M:validateRequest(obj) - local debug_message = self:validate_trace_rules(obj) - return debug_message -end - -return _M \ No newline at end of file diff --git a/test/perl/api-gateway/tracking/validator/tracingRulesValidator.t b/test/perl/api-gateway/tracking/log/tracingRulesLogger.t similarity index 85% rename from test/perl/api-gateway/tracking/validator/tracingRulesValidator.t rename to test/perl/api-gateway/tracking/log/tracingRulesLogger.t index bbc988b..e6249fc 100644 --- a/test/perl/api-gateway/tracking/validator/tracingRulesValidator.t +++ b/test/perl/api-gateway/tracking/log/tracingRulesLogger.t @@ -40,6 +40,11 @@ our $HttpConfig = <<_EOC_; ngx.apiGateway = ngx.apiGateway or {} ngx.apiGateway.validation = require "api-gateway.validation.factory" ngx.apiGateway.tracking = require "api-gateway.tracking.factory" + + local function get_logger(name) + return {} + end + ngx.apiGateway.getAsyncLogger = get_logger '; include "$pwd/conf.d/http.d/*.conf"; upstream cache_rw_backend { @@ -50,7 +55,7 @@ our $HttpConfig = <<_EOC_; } lua_shared_dict blocking_rules_dict 5m; lua_shared_dict tracking_rules_dict 5m; - lua_shared_dict traceing_rules_dict 5m; + lua_shared_dict tracing_rules_dict 5m; lua_shared_dict debugging_rules_dict 5m; lua_shared_dict delaying_rules_dict 5m; lua_shared_dict retrying_rules_dict 5m; @@ -79,7 +84,10 @@ __DATA__ location ~ /trace { set $validate_service_plan "on; path=/validate_service_plan; order=1; "; - access_by_lua "ngx.apiGateway.validation.validateRequest()"; + access_by_lua " + ngx.apiGateway.tracking.track() + ngx.apiGateway.validation.validateRequest() + "; content_by_lua 'ngx.say(ngx.var.validate_request_response_time)'; } @@ -89,9 +97,10 @@ __DATA__ [{ "id": 222, "domain" : "pub1", - "format": "$publisher_org_name;$subpath", + "format": "$publisher_org_name", "expire_at_utc": 1583910454, - "action" : "TRACE" + "action" : "TRACE", + "meta" : ["$request_uri"] }] ', "GET /trace" @@ -102,7 +111,7 @@ __DATA__ '0', '(\d{2,4})+', '(\d{2,4})+', -'.*{"domain":"pub1","format":"\$publisher_org_name;\$subpath","id":222,"action":"TRACE","expire_at_utc":1583910454}.*' +'.*{"domain":"pub1","format":"\$publisher_org_name","id":222,"action":"TRACE","expire_at_utc":1583910454}.*' ] --- error_code_like eval [200, 200, 200, 200, 200] diff --git a/test/perl/api-gateway/tracking/log/trackingRulesLogger.t b/test/perl/api-gateway/tracking/log/trackingRulesLogger.t index 5ac6c65..4ee93ed 100644 --- a/test/perl/api-gateway/tracking/log/trackingRulesLogger.t +++ b/test/perl/api-gateway/tracking/log/trackingRulesLogger.t @@ -41,6 +41,11 @@ our $HttpConfig = <<_EOC_; ngx.apiGateway.validation = require "api-gateway.validation.factory" ngx.apiGateway.tracking = require "api-gateway.tracking.factory" + local function get_logger(name) + return {} + end + ngx.apiGateway.getAsyncLogger = get_logger + local function loadrequire(module) local function requiref(module) require(module) From 91d5ed44ecab643dd18d2a789a6e0815383aaa69 Mon Sep 17 00:00:00 2001 From: ccristia Date: Thu, 2 Jun 2016 15:55:39 +0300 Subject: [PATCH 3/5] Added mock tracing logger for testing purposes --- .../tracking/log/tracingRulesLogger.lua | 58 +++++++------------ .../api-gateway/tracking/util/stringutil.lua | 26 +++++++++ .../tracking/log/tracingRulesLogger.t | 30 +++++----- 3 files changed, 64 insertions(+), 50 deletions(-) create mode 100644 src/lua/api-gateway/tracking/util/stringutil.lua diff --git a/src/lua/api-gateway/tracking/log/tracingRulesLogger.lua b/src/lua/api-gateway/tracking/log/tracingRulesLogger.lua index f9f0bdd..c6cedf4 100644 --- a/src/lua/api-gateway/tracking/log/tracingRulesLogger.lua +++ b/src/lua/api-gateway/tracking/log/tracingRulesLogger.lua @@ -13,9 +13,9 @@ ]] local cjson = require "cjson" -local _M = {} +local su = require "api-gateway.tracking.util.stringutil" -local kinesisLogger +local _M = {} function _M:new(o) local o = o or {} @@ -24,45 +24,30 @@ function _M:new(o) return o end -function _M:sendKinesisMessage(kinesis_data) - - local kinesisSwitch = ngx.var.kinesisSwitch - if (kinesisSwitch == nil or kinesisSwitch == "") then - kinesisSwitch = "on" - end - if ( kinesisLogger ~= nil and (kinesisSwitch ~= nil and kinesisSwitch == "on")) then - local partition_key = ngx.utctime() .."-".. math.random(ngx.now() * 1000) - - -- Send logs to kinesis - kinesisLogger:logMetrics(partition_key, cjson.encode(kinesis_data)) - else - ngx.log(ngx.WARN, "Trace info not sent to kinesis") - end - -end - -function _M:getKinesisMessage(rule) - local kinesis_data = {} +function _M:buildTraceMessage(rule) + local data = {} - kinesis_data["id"] = tostring(rule.id) - kinesis_data["domain"] = tostring(rule.domain) - kinesis_data["request_body"] = tostring(ngx.var.request_body) + data["id"] = tostring(rule.id) + data["domain"] = tostring(rule.domain) + data["request_body"] = tostring(ngx.var.request_body) + data["status"] = tostring(ngx.var.status) for key,value in pairs(ngx.header) do - kinesis_data[tostring(key)] = tostring(value) + data[tostring(key)] = tostring(value) end - local meta = rule.meta + local meta = rule.meta:split(";") local meta_length = table.getn(meta) local var_value, index for index = 1, meta_length do local variableManager = ngx.apiGateway.tracking.variableManager - var_value = variableManager:getRequestVariable(meta[index], nil) - kinesis_data[tostring(meta[index])] = tostring(var_value) + local var_name = string.sub(su.trim(meta[index]), 2); + var_value = variableManager:getRequestVariable(var_name, nil) + data[var_name] = tostring(var_value) end - return kinesis_data + return data end --- @@ -74,9 +59,9 @@ function _M:log_trace_rules(config_obj) ngx.log(ngx.WARN, "Please initialize RequestTrackingManager before calling this method") end - kinesisLogger = ngx.apiGateway.getAsyncLogger("api-gateway-debugging") - if ( kinesisLogger == nil ) then - ngx.log(ngx.WARN, "Could not track request. kinesis logger should not be nil") + local tracingLogger = ngx.apiGateway.getAsyncLogger("api-gateway-debugging") + if ( tracingLogger == nil ) then + ngx.log(ngx.WARN, "Could not track request. Tracing logger should not be nil") return end @@ -86,13 +71,14 @@ function _M:log_trace_rules(config_obj) if (tracing_rules == nil) then return end - -- 2. for each tracing rule matching the request publish a kinesis message asyncronously + -- 2. for each tracing rule matching the request publish a tracing message asyncronously for i, rule in pairs(tracing_rules) do if ( rule ~= nil ) then - local message = self:getKinesisMessage(rule) + local message = self:buildTraceMessage(rule) if ( message ~= nil ) then - ngx.log(ngx.DEBUG, "Sending tracing info to kinesis: " .. cjson.encode(message)) - self:sendKinesisMessage(message) + local partition_key = ngx.utctime() .."-".. math.random(ngx.now() * 1000) + ngx.log(ngx.DEBUG, "Logging tracing info: " .. cjson.encode(message)) + tracingLogger:logMetrics(partition_key, cjson.encode(message)); end end end diff --git a/src/lua/api-gateway/tracking/util/stringutil.lua b/src/lua/api-gateway/tracking/util/stringutil.lua new file mode 100644 index 0000000..a8afc79 --- /dev/null +++ b/src/lua/api-gateway/tracking/util/stringutil.lua @@ -0,0 +1,26 @@ +local stringutil = {} + +-- http://coronalabs.com/blog/2013/04/16/lua-string-magic/ +function string:split( pattern, results ) + if not results then + results = { } + end + local start = 1 + local split_start, split_end = string.find( self, pattern, start ) + while split_start do + table.insert( results, string.sub( self, start, split_start - 1 ) ) + start = split_end + 1 + split_start, split_end = string.find( self, pattern, start ) + end + table.insert( results, string.sub( self, start ) ) + return results +end + +-- http://coronalabs.com/blog/2013/04/16/lua-string-magic/ +local function trim( s ) + return string.match( s,"^()%s*$") and "" or string.match(s,"^%s*(.*%S)" ) +end + +stringutil.trim = trim + +return stringutil \ No newline at end of file diff --git a/test/perl/api-gateway/tracking/log/tracingRulesLogger.t b/test/perl/api-gateway/tracking/log/tracingRulesLogger.t index e6249fc..3c8a031 100644 --- a/test/perl/api-gateway/tracking/log/tracingRulesLogger.t +++ b/test/perl/api-gateway/tracking/log/tracingRulesLogger.t @@ -24,7 +24,7 @@ use Cwd qw(cwd); repeat_each(1); -plan tests => repeat_each() * (blocks() * 5) + 1 ; +plan tests => repeat_each() * (blocks() * 5) + 3 ; my $pwd = cwd(); @@ -42,7 +42,11 @@ our $HttpConfig = <<_EOC_; ngx.apiGateway.tracking = require "api-gateway.tracking.factory" local function get_logger(name) - return {} + return { + logMetrics = function (self, key, value) + ngx.log(ngx.INFO, "Received " .. tostring(value)) + end + } end ngx.apiGateway.getAsyncLogger = get_logger '; @@ -81,14 +85,12 @@ __DATA__ error_log ../test-logs/tracingRequestValidator_test1_error.log debug; - location ~ /trace { - set $validate_service_plan "on; path=/validate_service_plan; order=1; "; + location /trace { - access_by_lua " + log_by_lua ' ngx.apiGateway.tracking.track() - ngx.apiGateway.validation.validateRequest() - "; - content_by_lua 'ngx.say(ngx.var.validate_request_response_time)'; + '; + content_by_lua 'ngx.say("OK")'; } --- timeout: 10 @@ -100,7 +102,7 @@ __DATA__ "format": "$publisher_org_name", "expire_at_utc": 1583910454, "action" : "TRACE", - "meta" : ["$request_uri"] + "meta" : "$request_uri; $request_method;$publisher_org_name" }] ', "GET /trace" @@ -108,12 +110,12 @@ __DATA__ --- response_body_like eval [ '\{"result":"success"\}.*', -'0', -'(\d{2,4})+', -'(\d{2,4})+', -'.*{"domain":"pub1","format":"\$publisher_org_name","id":222,"action":"TRACE","expire_at_utc":1583910454}.*' +'OK' ] --- error_code_like eval - [200, 200, 200, 200, 200] + [200, 200] +--- grep_error_log eval: qr/Received .*?/ +--- grep_error_log_out +request_uri --- no_error_log [error] From 428f8358037acb46136d808796ca638b0df75692 Mon Sep 17 00:00:00 2001 From: Cristian Constantin Date: Thu, 2 Jun 2016 17:57:00 +0300 Subject: [PATCH 4/5] Removed grep_error_log tests which don't seem to work in a Docker environment --- test/perl/api-gateway/tracking/log/tracingRulesLogger.t | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/test/perl/api-gateway/tracking/log/tracingRulesLogger.t b/test/perl/api-gateway/tracking/log/tracingRulesLogger.t index 3c8a031..3cc7199 100644 --- a/test/perl/api-gateway/tracking/log/tracingRulesLogger.t +++ b/test/perl/api-gateway/tracking/log/tracingRulesLogger.t @@ -24,7 +24,7 @@ use Cwd qw(cwd); repeat_each(1); -plan tests => repeat_each() * (blocks() * 5) + 3 ; +plan tests => repeat_each() * (blocks() * 5) + 1 ; my $pwd = cwd(); @@ -114,8 +114,5 @@ __DATA__ ] --- error_code_like eval [200, 200] ---- grep_error_log eval: qr/Received .*?/ ---- grep_error_log_out -request_uri --- no_error_log [error] From 4f1db04ed6a41402c5b7e56bb551358a0fb801ff Mon Sep 17 00:00:00 2001 From: Cristian Constantin Date: Fri, 10 Jun 2016 16:52:34 +0300 Subject: [PATCH 5/5] Added missing directories to the install instructions --- Makefile | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Makefile b/Makefile index 888c5b4..809fe75 100644 --- a/Makefile +++ b/Makefile @@ -15,9 +15,11 @@ all: ; install: all $(INSTALL) -d $(DESTDIR)/$(LUA_LIB_DIR)/api-gateway/tracking/ $(INSTALL) -d $(DESTDIR)/$(LUA_LIB_DIR)/api-gateway/tracking/log/ + $(INSTALL) -d $(DESTDIR)/$(LUA_LIB_DIR)/api-gateway/tracking/util/ $(INSTALL) -d $(DESTDIR)/$(LUA_LIB_DIR)/api-gateway/tracking/validator/ $(INSTALL) src/lua/api-gateway/tracking/*.lua $(DESTDIR)/$(LUA_LIB_DIR)/api-gateway/tracking/ $(INSTALL) src/lua/api-gateway/tracking/log/*.lua $(DESTDIR)/$(LUA_LIB_DIR)/api-gateway/tracking/log/ + $(INSTALL) src/lua/api-gateway/tracking/util/*.lua $(DESTDIR)/$(LUA_LIB_DIR)/api-gateway/tracking/util/ $(INSTALL) src/lua/api-gateway/tracking/validator/*.lua $(DESTDIR)/$(LUA_LIB_DIR)/api-gateway/tracking/validator/ test: redis