From e4832239ca19deac5a35ec3cedcfcf78e340196f Mon Sep 17 00:00:00 2001 From: JP Swinski Date: Wed, 25 Oct 2023 13:00:08 +0000 Subject: [PATCH 01/14] added debug dependencies to readme --- README.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/README.md b/README.md index 70bc4eebf..a8209f5bb 100644 --- a/README.md +++ b/README.md @@ -34,6 +34,11 @@ If you are a science data user interested in using SlideRule to process Earth sc 3. For dependencies associated with a specific package, see the package readme at `packages/{package}/README.md` for additional installation instructions. +4. For debug builds, there are additional tools that are needed for static analysis: + + ```bash + $ sudo apt install clang clang-tidy cppcheck + ``` ## II. Building with CMake From 809576dc55a2e0134828bebdf2dbcb7af35139a0 Mon Sep 17 00:00:00 2001 From: JP Swinski Date: Thu, 26 Oct 2023 16:31:26 +0000 Subject: [PATCH 02/14] added metric monitor --- packages/core/EventLib.cpp | 4 +- packages/core/EventLib.h | 3 + packages/netsvc/AoiMetrics.cpp | 4 +- packages/netsvc/AoiMetrics.h | 2 +- packages/netsvc/CMakeLists.txt | 2 + packages/netsvc/MetricMonitor.cpp | 96 +++++++++++++++++++ packages/netsvc/MetricMonitor.h | 77 +++++++++++++++ packages/netsvc/OrchestratorLib.cpp | 71 +++++++++++--- packages/netsvc/OrchestratorLib.h | 29 +++--- packages/netsvc/netsvc.cpp | 1 + packages/netsvc/netsvc.h | 1 + project-config.cmake | 1 - targets/orchestrator-haproxy/orchestrator.lua | 39 +++++++- .../intelligent-load-balancer/haproxy.cfg | 1 + 14 files changed, 298 insertions(+), 33 deletions(-) create mode 100644 packages/netsvc/MetricMonitor.cpp create mode 100644 packages/netsvc/MetricMonitor.h diff --git a/packages/core/EventLib.cpp b/packages/core/EventLib.cpp index d48ec1097..2074fa287 100644 --- a/packages/core/EventLib.cpp +++ b/packages/core/EventLib.cpp @@ -342,9 +342,9 @@ void EventLib::generateMetric (event_level_t lvl, const char* name, metric_subty /* Initialize Log Message */ event.systime = TimeLib::gpstime(); event.tid = Thread::getId(); - event.id = subtype; + event.id = ORIGIN; event.parent = ORIGIN; - event.flags = 0; + event.flags = subtype; event.type = METRIC; event.level = lvl; diff --git a/packages/core/EventLib.h b/packages/core/EventLib.h index 646a0f311..09fde2fd9 100644 --- a/packages/core/EventLib.h +++ b/packages/core/EventLib.h @@ -56,6 +56,9 @@ #define stop_trace(lvl,id,...) {(void)lvl; (void)id;} #endif +#define count_metric(lvl,name,value) EventLib::generateMetric(lvl,name,EventLib::COUNTER,value) +#define gauge_metric(lvl,name,value) EventLib::generateMetric(lvl,name,EventLib::GAUGE,value) + /****************************************************************************** * EVENT LIBRARY CLASS ******************************************************************************/ diff --git a/packages/netsvc/AoiMetrics.cpp b/packages/netsvc/AoiMetrics.cpp index 85cfea8a8..a469fc706 100644 --- a/packages/netsvc/AoiMetrics.cpp +++ b/packages/netsvc/AoiMetrics.cpp @@ -286,9 +286,9 @@ bool AoiMetrics::init (void) /*---------------------------------------------------------------------------- - * setRegion + * getRegion *----------------------------------------------------------------------------*/ -AoiMetrics::regions_t AoiMetrics::setRegion (NetsvcParms* parms) +AoiMetrics::regions_t AoiMetrics::getRegion (NetsvcParms* parms) { regions_t region_found = REGION_UNKNOWN; if(parms->polygon.length() > 0) diff --git a/packages/netsvc/AoiMetrics.h b/packages/netsvc/AoiMetrics.h index 9d37fea79..d8f9ea950 100644 --- a/packages/netsvc/AoiMetrics.h +++ b/packages/netsvc/AoiMetrics.h @@ -89,7 +89,7 @@ class AoiMetrics *--------------------------------------------------------------------*/ static bool init (void); - static regions_t setRegion (NetsvcParms* parms); + static regions_t getRegion (NetsvcParms* parms); private: diff --git a/packages/netsvc/CMakeLists.txt b/packages/netsvc/CMakeLists.txt index e37c9dd74..608a4f7a2 100644 --- a/packages/netsvc/CMakeLists.txt +++ b/packages/netsvc/CMakeLists.txt @@ -23,6 +23,7 @@ if (CURL_FOUND AND RapidJSON_FOUND) ${CMAKE_CURRENT_LIST_DIR}/EndpointProxy.cpp ${CMAKE_CURRENT_LIST_DIR}/OrchestratorLib.cpp ${CMAKE_CURRENT_LIST_DIR}/ProvisioningSystemLib.cpp + ${CMAKE_CURRENT_LIST_DIR}/MetricMonitor.cpp ${CMAKE_CURRENT_LIST_DIR}/NetsvcParms.cpp ) @@ -40,6 +41,7 @@ if (CURL_FOUND AND RapidJSON_FOUND) ${CMAKE_CURRENT_LIST_DIR}/EndpointProxy.h ${CMAKE_CURRENT_LIST_DIR}/OrchestratorLib.h ${CMAKE_CURRENT_LIST_DIR}/ProvisioningSystemLib.h + ${CMAKE_CURRENT_LIST_DIR}/MetricMonitor.h ${CMAKE_CURRENT_LIST_DIR}/NetsvcParms.h DESTINATION ${INCDIR} diff --git a/packages/netsvc/MetricMonitor.cpp b/packages/netsvc/MetricMonitor.cpp new file mode 100644 index 000000000..dceeb92eb --- /dev/null +++ b/packages/netsvc/MetricMonitor.cpp @@ -0,0 +1,96 @@ +/* + * Copyright (c) 2021, University of Washington + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. Neither the name of the University of Washington nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY OF WASHINGTON AND CONTRIBUTORS + * “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE UNIVERSITY OF WASHINGTON OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/****************************************************************************** + * INCLUDES + ******************************************************************************/ + +#include "MetricMonitor.h" +#include "Monitor.h" +#include "EventLib.h" +#include "TimeLib.h" +#include "RecordObject.h" +#include "OrchestratorLib.h" + +/****************************************************************************** + * PUBLIC METHODS + ******************************************************************************/ + +/*---------------------------------------------------------------------------- + * luaCreate - create() + *----------------------------------------------------------------------------*/ +int MetricMonitor::luaCreate (lua_State* L) +{ + try + { + /* Get Parmeters */ + event_level_t level = (event_level_t)getLuaInteger(L, 1); + + /* Return Dispatch Object */ + return createLuaObject(L, new MetricMonitor(L, level)); + } + catch(const RunTimeException& e) + { + mlog(e.level(), "Error creating %s: %s", LUA_META_NAME, e.what()); + return returnLuaStatus(L, false); + } +} + +/****************************************************************************** + * PROTECTED METHODS + ******************************************************************************/ + +/*---------------------------------------------------------------------------- + * processEvent + *----------------------------------------------------------------------------*/ +void MetricMonitor::processEvent(const unsigned char* event_buf_ptr, int event_size) +{ + OrchestratorLib::metric(event_buf_ptr, event_size); +} + +/****************************************************************************** + * PRIVATE METHODS + ******************************************************************************/ + +/*---------------------------------------------------------------------------- + * Constructor + *----------------------------------------------------------------------------*/ +MetricMonitor::MetricMonitor(lua_State* L, event_level_t level): + Monitor(L, EventLib::METRIC, level, Monitor::JSON) +{ +} + +/*---------------------------------------------------------------------------- + * Destructor + *----------------------------------------------------------------------------*/ +MetricMonitor::~MetricMonitor(void) +{ +} diff --git a/packages/netsvc/MetricMonitor.h b/packages/netsvc/MetricMonitor.h new file mode 100644 index 000000000..5e3aa544a --- /dev/null +++ b/packages/netsvc/MetricMonitor.h @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2021, University of Washington + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. Neither the name of the University of Washington nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY OF WASHINGTON AND CONTRIBUTORS + * “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE UNIVERSITY OF WASHINGTON OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef __metric_monitor__ +#define __metric_monitor__ + +/****************************************************************************** + * INCLUDES + ******************************************************************************/ + +#include "MsgQ.h" +#include "Monitor.h" +#include "RecordObject.h" +#include "OsApi.h" +#include "EventLib.h" + +/****************************************************************************** + * METRIC MONITOR CLASS + ******************************************************************************/ + +class MetricMonitor: public Monitor +{ + public: + + /*-------------------------------------------------------------------- + * Methods + *--------------------------------------------------------------------*/ + + static int luaCreate (lua_State* L); + + protected: + + /*-------------------------------------------------------------------- + * Methods + *--------------------------------------------------------------------*/ + + void processEvent (const unsigned char* event_buf_ptr, int event_size) override; + + private: + + /*-------------------------------------------------------------------- + * Methods + *--------------------------------------------------------------------*/ + + MetricMonitor (lua_State* L, event_level_t level); + ~MetricMonitor (void); +}; + +#endif /* __publish_monitor__ */ diff --git a/packages/netsvc/OrchestratorLib.cpp b/packages/netsvc/OrchestratorLib.cpp index ec2c41d8e..bf310676a 100644 --- a/packages/netsvc/OrchestratorLib.cpp +++ b/packages/netsvc/OrchestratorLib.cpp @@ -47,7 +47,9 @@ * Static Data *----------------------------------------------------------------------------*/ -const char* OrchestratorLib::URL = NULL; +const char* OrchestratorLib::URL = NULL; +HttpClient* OrchestratorLib::client = NULL; +Mutex OrchestratorLib::rqstMutex; /*---------------------------------------------------------------------------- * init @@ -63,6 +65,37 @@ void OrchestratorLib::init (void) void OrchestratorLib::deinit (void) { delete [] URL; + delete client; +} + +/*---------------------------------------------------------------------------- + * deinit + *----------------------------------------------------------------------------*/ +HttpClient::rsps_t OrchestratorLib::request (EndpointObject::verb_t verb, const char* resource, const char* data) +{ + /* enter mutual exclusion zone */ + rqstMutex.lock(); + + /* create client if it doesn't exist */ + if(!client) + { + client = new HttpClient(NULL, URL); + } + + /* perform request */ + HttpClient::rsps_t rsps = client->request(verb, resource, data, true, NULL); + if(rsps.code == EndpointObject::Service_Unavailable) + { + mlog(CRITICAL, "Failed request to orchestrator at %s, recreating client", URL); + delete client; + client = NULL; + } + + /* exit mutual exclusion zone */ + rqstMutex.unlock(); + + /* return response */ + return rsps; } /*---------------------------------------------------------------------------- @@ -72,10 +105,8 @@ bool OrchestratorLib::registerService (const char* service, int lifetime, const { bool status = true; - HttpClient orchestrator(NULL, URL); FString rqst("{\"service\":\"%s\", \"lifetime\": %d, \"address\": \"%s\"}", service, lifetime, address); - - HttpClient::rsps_t rsps = orchestrator.request(EndpointObject::POST, "/discovery/register", rqst.c_str(), false, NULL); + HttpClient::rsps_t rsps = request(EndpointObject::POST, "/discovery/register", rqst.c_str()); if(rsps.code == EndpointObject::OK) { try @@ -118,10 +149,9 @@ bool OrchestratorLib::registerService (const char* service, int lifetime, const vector* OrchestratorLib::lock (const char* service, int nodes_needed, int timeout_secs, bool verbose) { vector* nodes = NULL; - HttpClient orchestrator(NULL, URL); - FString rqst("{\"service\":\"%s\", \"nodesNeeded\": %d, \"timeout\": %d}", service, nodes_needed, timeout_secs); - HttpClient::rsps_t rsps = orchestrator.request(EndpointObject::POST, "/discovery/lock", rqst.c_str(), false, NULL); + FString rqst("{\"service\":\"%s\", \"nodesNeeded\": %d, \"timeout\": %d}", service, nodes_needed, timeout_secs); + HttpClient::rsps_t rsps = request(EndpointObject::POST, "/discovery/lock", rqst.c_str()); if(rsps.code == EndpointObject::OK) { try @@ -188,14 +218,13 @@ bool OrchestratorLib::unlock (long transactions[], int num_transactions, bool ve bool status = true; - HttpClient orchestrator(NULL, URL); char strbuf[64]; string rqst; rqst += StringLib::format(strbuf, 64, "{\"transactions\": [%ld", transactions[0]); for(int t = 1; t < num_transactions; t++) rqst += StringLib::format(strbuf, 64, ",%ld", transactions[t]); rqst += "]}"; - HttpClient::rsps_t rsps = orchestrator.request(EndpointObject::POST, "/discovery/unlock", rqst.c_str(), false, NULL); + HttpClient::rsps_t rsps = request(EndpointObject::POST, "/discovery/unlock", rqst.c_str()); if(rsps.code == EndpointObject::OK) { try @@ -234,9 +263,7 @@ bool OrchestratorLib::health (void) { bool status = false; - HttpClient orchestrator(NULL, URL); - - HttpClient::rsps_t rsps = orchestrator.request(EndpointObject::GET, "/discovery/health", NULL, false, NULL); + HttpClient::rsps_t rsps = request(EndpointObject::GET, "/discovery/health", NULL); if(rsps.code == EndpointObject::OK) { try @@ -258,6 +285,26 @@ bool OrchestratorLib::health (void) return status; } +/*---------------------------------------------------------------------------- + * metric + *----------------------------------------------------------------------------*/ +bool OrchestratorLib::metric (const unsigned char* metric_buf, int buf_size) +{ + (void)buf_size; + + bool status = false; + + HttpClient::rsps_t rsps = request(EndpointObject::POST, "/discovery/metric", reinterpret_cast(metric_buf)); + if(rsps.code == EndpointObject::OK) + { + status = true; + } + + delete [] rsps.response; + + return status; +} + /*---------------------------------------------------------------------------- * luaUrl - orchurl() *----------------------------------------------------------------------------*/ diff --git a/packages/netsvc/OrchestratorLib.h b/packages/netsvc/OrchestratorLib.h index e5de0d69b..5d925f8fa 100644 --- a/packages/netsvc/OrchestratorLib.h +++ b/packages/netsvc/OrchestratorLib.h @@ -69,25 +69,30 @@ class OrchestratorLib * Methods *--------------------------------------------------------------------*/ - static void init (void); - static void deinit (void); + static void init (void); + static void deinit (void); - static bool registerService (const char* service, int lifetime, const char* address, bool verbose=false); - static vector* lock (const char* service, int nodes_needed, int timeout_secs, bool verbose=false); - static bool unlock (long transactions[], int num_transactions, bool verbose=false); - static bool health (void); + static HttpClient::rsps_t request (EndpointObject::verb_t verb, const char* resource, const char* data); - static int luaUrl (lua_State* L); - static int luaRegisterService (lua_State* L); - static int luaLock (lua_State* L); - static int luaUnlock (lua_State* L); - static int luaHealth (lua_State* L); + static bool registerService (const char* service, int lifetime, const char* address, bool verbose=false); + static vector* lock (const char* service, int nodes_needed, int timeout_secs, bool verbose=false); + static bool unlock (long transactions[], int num_transactions, bool verbose=false); + static bool health (void); + static bool metric (const unsigned char* metric_buf, int buf_size); + + static int luaUrl (lua_State* L); + static int luaRegisterService (lua_State* L); + static int luaLock (lua_State* L); + static int luaUnlock (lua_State* L); + static int luaHealth (lua_State* L); /*-------------------------------------------------------------------- * Data *--------------------------------------------------------------------*/ - static const char* URL; + static const char* URL; + static HttpClient* client; + static Mutex rqstMutex; }; #endif /* __orchestrator_lib__ */ diff --git a/packages/netsvc/netsvc.cpp b/packages/netsvc/netsvc.cpp index b4e591573..46f770f6b 100644 --- a/packages/netsvc/netsvc.cpp +++ b/packages/netsvc/netsvc.cpp @@ -65,6 +65,7 @@ int netsvc_open (lua_State* L) {"pslogin", ProvisioningSystemLib::luaLogin}, {"psvalidate", ProvisioningSystemLib::luaValidate}, {"psauth", ProvisioningSystemLib::Authenticator::luaCreate}, + {"mmonitor", MetricMonitor::luaCreate}, {"parms", NetsvcParms::luaCreate}, {NULL, NULL} }; diff --git a/packages/netsvc/netsvc.h b/packages/netsvc/netsvc.h index 26d1dcf53..3ed1c3404 100644 --- a/packages/netsvc/netsvc.h +++ b/packages/netsvc/netsvc.h @@ -41,6 +41,7 @@ #include "EndpointProxy.h" #include "OrchestratorLib.h" #include "ProvisioningSystemLib.h" +#include "MetricMonitor.h" #include "NetsvcParms.h" /****************************************************************************** diff --git a/project-config.cmake b/project-config.cmake index bdaa5c98a..de87b655c 100644 --- a/project-config.cmake +++ b/project-config.cmake @@ -42,7 +42,6 @@ if(CMAKE_BUILD_TYPE MATCHES "Debug") clang-tidy; -header-filter=.; -checks=${CLANG_TIDY_CHECKS_PARM}; -# -checks=clang-analyzer-*,concurrency-*,misc-*,performance-*,portability-*,readability-*,-readability-braces-around-statements,-readability-implicit-bool-conversion,-readability-magic-numbers,-misc-non-private-member-variables-in-classes; -warnings-as-errors=*; ) diff --git a/targets/orchestrator-haproxy/orchestrator.lua b/targets/orchestrator-haproxy/orchestrator.lua index 12e8d0f1e..ff5675111 100644 --- a/targets/orchestrator-haproxy/orchestrator.lua +++ b/targets/orchestrator-haproxy/orchestrator.lua @@ -142,7 +142,9 @@ StatData = { numFailures = 0, numTimeouts = 0, numActiveLocks = 0, - memberCounts = {} + memberCounts = {}, + gaugeAppMetrics = {}, + countAppMetrics = {} } -- @@ -387,7 +389,11 @@ num_timeouts %d # TYPE num_active_locks counter num_active_locks %d -]], StatData["numRequests"], StatData["numComplete"], StatData["numFailures"], StatData["numTimeouts"], StatData["numActiveLocks"]) +]], StatData["numRequests"], + StatData["numComplete"], + StatData["numFailures"], + StatData["numTimeouts"], + StatData["numActiveLocks"]) -- add member counts to response for member_metric,_ in pairs(StatData["memberCounts"]) do @@ -395,7 +401,9 @@ num_active_locks %d # TYPE %s counter %s %d -]], member_metric, member_metric, StatData["memberCounts"][member_metric]) +]], member_metric, + member_metric, + StatData["memberCounts"][member_metric]) end -- send response @@ -420,6 +428,30 @@ local function api_health(applet) end +-- +-- API: /discovery/metric +-- +local function api_metric(applet) + + -- process request + local body = applet:receive() + local request = json.decode(body) + local metric_type = request["transactions"] + + -- store metrics + for i,m in ipairs(request) do + + end + -- send response + local response = string.format([[{"health":true}]]) + applet:set_status(200) + applet:add_header("content-length", string.len(response)) + applet:add_header("content-type", "application/json") + applet:start_response() + applet:send(response) + +end + -- -- API: /discovery/status -- @@ -586,6 +618,7 @@ core.register_service("orchestrator_lock", "http", api_lock) core.register_service("orchestrator_unlock", "http", api_unlock) core.register_service("orchestrator_prometheus", "http", api_prometheus) core.register_service("orchestrator_health", "http", api_health) +core.register_service("orchestrator_metric", "http", api_metric) core.register_service("orchestrator_status", "http", api_status) core.register_task(backgroud_scrubber) core.register_fetches("next_node", orchestrator_next_node) diff --git a/targets/slideruleearth-aws/docker/intelligent-load-balancer/haproxy.cfg b/targets/slideruleearth-aws/docker/intelligent-load-balancer/haproxy.cfg index 1373f383d..62743e8d5 100644 --- a/targets/slideruleearth-aws/docker/intelligent-load-balancer/haproxy.cfg +++ b/targets/slideruleearth-aws/docker/intelligent-load-balancer/haproxy.cfg @@ -35,6 +35,7 @@ frontend orchestrator http-request use-service lua.orchestrator_unlock if { path /discovery/unlock } http-request use-service lua.orchestrator_prometheus if { path /discovery/prometheus } http-request use-service lua.orchestrator_health if { path /discovery/health } + http-request use-service lua.orchestrator_metric if { path /discovery/metric } backend cluster .if !streq("$IS_PUBLIC",True) From aaf930b0e1ba65c74a1ee54088ead05005efe263 Mon Sep 17 00:00:00 2001 From: JP Swinski Date: Thu, 26 Oct 2023 20:22:39 +0000 Subject: [PATCH 03/14] added metric api to orchestrator --- targets/orchestrator-haproxy/orchestrator.lua | 77 +++++++++++++------ targets/slideruleearth-aws/docker-compose.yml | 1 + 2 files changed, 54 insertions(+), 24 deletions(-) diff --git a/targets/orchestrator-haproxy/orchestrator.lua b/targets/orchestrator-haproxy/orchestrator.lua index ff5675111..8b4c05ea4 100644 --- a/targets/orchestrator-haproxy/orchestrator.lua +++ b/targets/orchestrator-haproxy/orchestrator.lua @@ -373,7 +373,43 @@ end -- local function api_prometheus(applet) - -- build initial response + -- create application count metrics + local application_count_metric = "" + for name,value in pairs(StatData.countAppMetrics) do + application_count_metric = application_count_metric .. string.format([[ + +# TYPE %s counter +%s %d +]], name, + name, + value) + end + + -- create application gauge metrics + local application_gauge_metric = "" + for name,value in pairs(StatData.gaugeAppMetrics) do + application_gauge_metric = application_gauge_metric .. string.format([[ + +# TYPE %s gauge +%s %d +]], name, + name, + value) + end + + -- create member count metrics + local member_count_metric = "" + for member_metric,_ in pairs(StatData["memberCounts"]) do + member_count_metric = member_count_metric .. string.format([[ + +# TYPE %s counter +%s %d +]], member_metric, + member_metric, + StatData["memberCounts"][member_metric]) + end + + -- build full response local response = string.format([[ # TYPE num_requests counter num_requests %d @@ -388,23 +424,15 @@ num_failures %d num_timeouts %d # TYPE num_active_locks counter -num_active_locks %d +num_active_locks %d%s%s%s ]], StatData["numRequests"], StatData["numComplete"], StatData["numFailures"], StatData["numTimeouts"], - StatData["numActiveLocks"]) - - -- add member counts to response - for member_metric,_ in pairs(StatData["memberCounts"]) do - response = response .. string.format([[ - -# TYPE %s counter -%s %d -]], member_metric, - member_metric, - StatData["memberCounts"][member_metric]) - end + StatData["numActiveLocks"], + member_count_metric, + application_count_metric, + application_gauge_metric) -- send response applet:set_status(200) @@ -436,19 +464,20 @@ local function api_metric(applet) -- process request local body = applet:receive() local request = json.decode(body) - local metric_type = request["transactions"] + local metric_name = request["name"] + local metric_value = tonumber(request["attr"]) + local metric_type = request["flags"] -- store metrics - for i,m in ipairs(request) do - + if metric_type == 0 then + StatData.countAppMetrics[metric_name] = StatData.countAppMetrics[metric_name] + metric_value + applet:set_status(200) + elseif metric_type == 1 then + StatData.gaugeAppMetrics[metric_name] = metric_value + applet:set_status(200) + else + applet:set_status(400) end - -- send response - local response = string.format([[{"health":true}]]) - applet:set_status(200) - applet:add_header("content-length", string.len(response)) - applet:add_header("content-type", "application/json") - applet:start_response() - applet:send(response) end diff --git a/targets/slideruleearth-aws/docker-compose.yml b/targets/slideruleearth-aws/docker-compose.yml index ff854b91f..036b5f87e 100644 --- a/targets/slideruleearth-aws/docker-compose.yml +++ b/targets/slideruleearth-aws/docker-compose.yml @@ -11,6 +11,7 @@ services: ulimits: nofile: soft: "8192" + hard: "8192" volumes: - /etc/ssl/certs:/etc/ssl/certs - /data:/data From 0b99c68a938d49b3105c3afb2e04212b967b7fd5 Mon Sep 17 00:00:00 2001 From: JP Swinski Date: Fri, 27 Oct 2023 16:43:54 +0000 Subject: [PATCH 04/14] metrics being pushed to orchestrator --- packages/core/LuaEndpoint.cpp | 7 ++++- packages/netsvc/OrchestratorLib.cpp | 28 ++----------------- packages/netsvc/OrchestratorLib.h | 2 -- scripts/apps/server.lua | 9 +++--- targets/orchestrator-haproxy/orchestrator.lua | 14 +++++++++- 5 files changed, 26 insertions(+), 34 deletions(-) diff --git a/packages/core/LuaEndpoint.cpp b/packages/core/LuaEndpoint.cpp index b2a7d7815..4c1f627be 100644 --- a/packages/core/LuaEndpoint.cpp +++ b/packages/core/LuaEndpoint.cpp @@ -175,6 +175,7 @@ void* LuaEndpoint::requestThread (void* parm) EndpointObject::info_t* info = (EndpointObject::info_t*)parm; EndpointObject::Request* request = info->request; LuaEndpoint* lua_endpoint = dynamic_cast(info->endpoint); + double start = TimeLib::latchtime(); /* Get Request Script */ const char* script_pathname = LuaEngine::sanitize(request->resource); @@ -230,6 +231,10 @@ void* LuaEndpoint::requestThread (void* parm) /* End Response */ rspq->postCopy("", 0); + /* Generate Metric for Endpoint */ + double duration = TimeLib::latchtime() - start; + gauge_metric(INFO, request->resource, duration); + /* Clean Up */ delete rspq; delete [] script_pathname; @@ -238,7 +243,7 @@ void* LuaEndpoint::requestThread (void* parm) /* Stop Trace */ stop_trace(INFO, trace_id); - + /* Return */ return NULL; } diff --git a/packages/netsvc/OrchestratorLib.cpp b/packages/netsvc/OrchestratorLib.cpp index bf310676a..0e1a06236 100644 --- a/packages/netsvc/OrchestratorLib.cpp +++ b/packages/netsvc/OrchestratorLib.cpp @@ -48,8 +48,6 @@ *----------------------------------------------------------------------------*/ const char* OrchestratorLib::URL = NULL; -HttpClient* OrchestratorLib::client = NULL; -Mutex OrchestratorLib::rqstMutex; /*---------------------------------------------------------------------------- * init @@ -65,7 +63,6 @@ void OrchestratorLib::init (void) void OrchestratorLib::deinit (void) { delete [] URL; - delete client; } /*---------------------------------------------------------------------------- @@ -73,29 +70,8 @@ void OrchestratorLib::deinit (void) *----------------------------------------------------------------------------*/ HttpClient::rsps_t OrchestratorLib::request (EndpointObject::verb_t verb, const char* resource, const char* data) { - /* enter mutual exclusion zone */ - rqstMutex.lock(); - - /* create client if it doesn't exist */ - if(!client) - { - client = new HttpClient(NULL, URL); - } - - /* perform request */ - HttpClient::rsps_t rsps = client->request(verb, resource, data, true, NULL); - if(rsps.code == EndpointObject::Service_Unavailable) - { - mlog(CRITICAL, "Failed request to orchestrator at %s, recreating client", URL); - delete client; - client = NULL; - } - - /* exit mutual exclusion zone */ - rqstMutex.unlock(); - - /* return response */ - return rsps; + HttpClient client(NULL, URL); + return client.request(verb, resource, data, false, NULL); } /*---------------------------------------------------------------------------- diff --git a/packages/netsvc/OrchestratorLib.h b/packages/netsvc/OrchestratorLib.h index 5d925f8fa..b5a42faae 100644 --- a/packages/netsvc/OrchestratorLib.h +++ b/packages/netsvc/OrchestratorLib.h @@ -91,8 +91,6 @@ class OrchestratorLib *--------------------------------------------------------------------*/ static const char* URL; - static HttpClient* client; - static Mutex rqstMutex; }; #endif /* __orchestrator_lib__ */ diff --git a/scripts/apps/server.lua b/scripts/apps/server.lua index 99c7f6379..56cd9eeef 100644 --- a/scripts/apps/server.lua +++ b/scripts/apps/server.lua @@ -51,11 +51,12 @@ sys.setstddepth(msgq_depth) -- Configure Monitoring -- sys.setlvl(core.LOG | core.TRACE | core.METRIC, event_level) -- set level globally -local monitor = core.monitor(core.LOG, core.DEBUG, event_format):name("EventMonitor") -- monitor only logs -monitor:tail(1024) - +local log_monitor = core.monitor(core.LOG, core.DEBUG, event_format):name("LogMonitor") -- monitor logs and write to stdout +log_monitor:tail(1024) +local metric_monitor = netsvc.mmonitor(core.DEBUG):name("MetricMonitor") -- monitor metrics and push to orchestrator local dispatcher = core.dispatcher(core.EVENTQ, 1):name("EventDispatcher") -dispatcher:attach(monitor, "eventrec") +dispatcher:attach(log_monitor, "eventrec") +dispatcher:attach(metric_monitor, "eventrec") dispatcher:run() -- Configure Assets -- diff --git a/targets/orchestrator-haproxy/orchestrator.lua b/targets/orchestrator-haproxy/orchestrator.lua index 8b4c05ea4..c7e4712a3 100644 --- a/targets/orchestrator-haproxy/orchestrator.lua +++ b/targets/orchestrator-haproxy/orchestrator.lua @@ -459,6 +459,15 @@ end -- -- API: /discovery/metric -- +-- Updates metric data +-- +-- INPUT: +-- { +-- "name": "" +-- "value": "" +-- "flags": "" +-- } +-- local function api_metric(applet) -- process request @@ -470,15 +479,18 @@ local function api_metric(applet) -- store metrics if metric_type == 0 then - StatData.countAppMetrics[metric_name] = StatData.countAppMetrics[metric_name] + metric_value + StatData.countAppMetrics[metric_name] = (StatData.countAppMetrics[metric_name] or 0) + metric_value applet:set_status(200) elseif metric_type == 1 then StatData.gaugeAppMetrics[metric_name] = metric_value + StatData.countAppMetrics[metric_name .. ".count"] = (StatData.countAppMetrics[metric_name .. ".count"] or 0) + 1 applet:set_status(200) else applet:set_status(400) end + -- send response + applet:start_response() end -- From fb7545d55c4c416e5340dd74df8f3990ce7f2c11 Mon Sep 17 00:00:00 2001 From: JP Swinski Date: Fri, 27 Oct 2023 18:27:52 +0000 Subject: [PATCH 05/14] different versions of docker compose have different requirements for ulimits in compose file --- targets/slideruleearth-aws/docker-compose.yml | 4 ++-- .../terraform/cluster/docker-compose-sliderule.yml | 3 ++- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/targets/slideruleearth-aws/docker-compose.yml b/targets/slideruleearth-aws/docker-compose.yml index 036b5f87e..f44bfbaba 100644 --- a/targets/slideruleearth-aws/docker-compose.yml +++ b/targets/slideruleearth-aws/docker-compose.yml @@ -10,8 +10,8 @@ services: tty: true # docker run -t ulimits: nofile: - soft: "8192" - hard: "8192" + soft: 8192 + hard: 8192 volumes: - /etc/ssl/certs:/etc/ssl/certs - /data:/data diff --git a/targets/slideruleearth-aws/terraform/cluster/docker-compose-sliderule.yml b/targets/slideruleearth-aws/terraform/cluster/docker-compose-sliderule.yml index d65d7e197..bca450d99 100644 --- a/targets/slideruleearth-aws/terraform/cluster/docker-compose-sliderule.yml +++ b/targets/slideruleearth-aws/terraform/cluster/docker-compose-sliderule.yml @@ -10,7 +10,8 @@ services: tty: true # docker run -t ulimits: nofile: - soft: "8192" + soft: 8192 + hard: 8192 volumes: - /etc/ssl/certs:/etc/ssl/certs - /data:/data From eadc928c57f5e7accbb448f19dd13b1cfe8a2ff9 Mon Sep 17 00:00:00 2001 From: JP Swinski Date: Fri, 27 Oct 2023 19:41:14 +0000 Subject: [PATCH 06/14] fixed formatting issues in prometheus orchestrator api --- targets/orchestrator-haproxy/orchestrator.lua | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/targets/orchestrator-haproxy/orchestrator.lua b/targets/orchestrator-haproxy/orchestrator.lua index c7e4712a3..f60a65412 100644 --- a/targets/orchestrator-haproxy/orchestrator.lua +++ b/targets/orchestrator-haproxy/orchestrator.lua @@ -391,7 +391,7 @@ local function api_prometheus(applet) application_gauge_metric = application_gauge_metric .. string.format([[ # TYPE %s gauge -%s %d +%s %f ]], name, name, value) @@ -424,7 +424,8 @@ num_failures %d num_timeouts %d # TYPE num_active_locks counter -num_active_locks %d%s%s%s +num_active_locks %d +%s%s%s ]], StatData["numRequests"], StatData["numComplete"], StatData["numFailures"], From d49206188815cddd512f18fdab8844ad657a0996 Mon Sep 17 00:00:00 2001 From: JP Swinski Date: Mon, 30 Oct 2023 16:17:27 +0000 Subject: [PATCH 07/14] updated orchestrator and endpoint proxy to use curl --- packages/core/HttpClient.h | 2 +- packages/core/RecordObject.h | 12 +- packages/netsvc/CurlLib.cpp | 601 ++++++++++++++++++++-------- packages/netsvc/CurlLib.h | 50 ++- packages/netsvc/EndpointProxy.cpp | 9 +- packages/netsvc/OrchestratorLib.cpp | 38 +- packages/netsvc/OrchestratorLib.h | 32 +- 7 files changed, 531 insertions(+), 213 deletions(-) diff --git a/packages/core/HttpClient.h b/packages/core/HttpClient.h index 5302d8b0f..82e1b13cf 100644 --- a/packages/core/HttpClient.h +++ b/packages/core/HttpClient.h @@ -46,7 +46,7 @@ #include "EndpointObject.h" /****************************************************************************** - * HTTP SERVER CLASS + * HTTP CLIENT CLASS ******************************************************************************/ class HttpClient: public LuaObject diff --git a/packages/core/RecordObject.h b/packages/core/RecordObject.h index a0db73807..8828dac0f 100644 --- a/packages/core/RecordObject.h +++ b/packages/core/RecordObject.h @@ -150,6 +150,12 @@ class RecordObject double double_val; } type_cast_t; + typedef struct { + uint16_t version; + uint16_t type_size; + uint32_t data_size; + } rec_hdr_t; + /*-------------------------------------------------------------------- * Constants *--------------------------------------------------------------------*/ @@ -274,12 +280,6 @@ class RecordObject * Types *--------------------------------------------------------------------*/ - typedef struct { - uint16_t version; - uint16_t type_size; - uint32_t data_size; - } rec_hdr_t; - struct definition_t { const char* type_name; // the name of the type of record diff --git a/packages/netsvc/CurlLib.cpp b/packages/netsvc/CurlLib.cpp index 98bce78f6..4b636bd7c 100644 --- a/packages/netsvc/CurlLib.cpp +++ b/packages/netsvc/CurlLib.cpp @@ -60,119 +60,341 @@ void CurlLib::deinit (void) } /*---------------------------------------------------------------------------- - * luaGet + * get *----------------------------------------------------------------------------*/ -int CurlLib::luaGet (lua_State* L) +long CurlLib::get (const char* url, const char* data, const char** response, int* size, bool verify_peer, bool verify_hostname) { - bool status = false; + long http_code = 0; CURL* curl = NULL; - try + /* Initialize Request */ + data_t rqst; + rqst.data = (char*)data; + rqst.size = StringLib::size(data); + + /* Initialize Response */ + List rsps_set(EXPECTED_RESPONSE_SEGMENTS); + if(response) *response = NULL; + if(size) *size = 0; + + /* Initialize cURL */ + curl = curl_easy_init(); + if(curl) { - /* Get Parameters */ - const char* url = LuaObject::getLuaString(L, 1); - bool verify_peer = LuaObject::getLuaBoolean(L, 2, true, false); - bool verify_hostname = LuaObject::getLuaBoolean(L, 3, true, false); - const char* data = LuaObject::getLuaString(L, 4, true, ""); + curl_easy_setopt(curl, CURLOPT_URL, url); + curl_easy_setopt(curl, CURLOPT_BUFFERSIZE, CURL_MAX_READ_SIZE); // TODO: test out performance + curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, CONNECTION_TIMEOUT); // seconds + curl_easy_setopt(curl, CURLOPT_TIMEOUT, DATA_TIMEOUT); // seconds + curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, CurlLib::writeData); + curl_easy_setopt(curl, CURLOPT_WRITEDATA, &rsps_set); + curl_easy_setopt(curl, CURLOPT_NETRC, 1L); + curl_easy_setopt(curl, CURLOPT_COOKIEFILE, ".cookies"); + curl_easy_setopt(curl, CURLOPT_COOKIEJAR, ".cookies"); + curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L); + if(rqst.size > 0) + { + curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "GET"); + curl_easy_setopt(curl, CURLOPT_POSTFIELDS, rqst.data); + curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, (long)rqst.size); + } - /* Initialize Request */ - data_t rqst; - rqst.data = (char*)data; - rqst.size = StringLib::size(data); + /* + * If you want to connect to a site who isn't using a certificate that is + * signed by one of the certs in the CA bundle you have, you can skip the + * verification of the server's certificate. This makes the connection + * A LOT LESS SECURE. + * + * If you have a CA cert for the server stored someplace else than in the + * default bundle, then the CURLOPT_CAPATH option might come handy for + * you. + */ + if(!verify_peer) + { + curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L); + } - /* Initialize Response */ - List rsps_set; + /* + * If the site you're connecting to uses a different host name that what + * they have mentioned in their server certificate's commonName (or + * subjectAltName) fields, libcurl will refuse to connect. You can skip + * this check, but this will make the connection less secure. + */ + if(!verify_hostname) + { + curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L); + } - /* Initialize cURL */ - curl = curl_easy_init(); - if(curl) + /* Perform the request, res will get the return code */ + CURLcode res = curl_easy_perform(curl); + + /* Check for Success */ + if(res == CURLE_OK) { - curl_easy_setopt(curl, CURLOPT_URL, url); - curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, CurlLib::writeData); - curl_easy_setopt(curl, CURLOPT_WRITEDATA, &rsps_set); - curl_easy_setopt(curl, CURLOPT_NETRC, 1L); - curl_easy_setopt(curl, CURLOPT_COOKIEFILE, ".cookies"); - curl_easy_setopt(curl, CURLOPT_COOKIEJAR, ".cookies"); - curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L); - if(rqst.size > 0) - { - curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "GET"); - curl_easy_setopt(curl, CURLOPT_POSTFIELDS, rqst.data); - curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, (long)rqst.size); - } + /* Get HTTP Code */ + curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &http_code); - /* - * If you want to connect to a site who isn't using a certificate that is - * signed by one of the certs in the CA bundle you have, you can skip the - * verification of the server's certificate. This makes the connection - * A LOT LESS SECURE. - * - * If you have a CA cert for the server stored someplace else than in the - * default bundle, then the CURLOPT_CAPATH option might come handy for - * you. - */ - if(verify_peer) - { - curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 1L); - } + /* Get Response */ + CurlLib::combineResponse(&rsps_set, response, size); + } + else + { + /* Unable to Perform cURL Call */ + FString error_msg("%s", curl_easy_strerror(res)); + *response = error_msg.c_str(true); + http_code = EndpointObject::Service_Unavailable; + } - /* - * If the site you're connecting to uses a different host name that what - * they have mentioned in their server certificate's commonName (or - * subjectAltName) fields, libcurl will refuse to connect. You can skip - * this check, but this will make the connection less secure. - */ - if(verify_hostname) - { - curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 1L); - } + /* Always Cleanup */ + curl_easy_cleanup(curl); + } - /* Perform the request, res will get the return code */ - CURLcode res = curl_easy_perform(curl); + /* Return HTTP Code */ + return http_code; +} - /* Check for Success */ - if(res == CURLE_OK) - { - /* Get HTTP Code */ - long http_code = 0; - curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &http_code); - if(http_code == 200) - { - /* Set Successfull */ - status = true; - } +/*---------------------------------------------------------------------------- + * post + *----------------------------------------------------------------------------*/ +long CurlLib::post (const char* url, const char* data, const char** response, int* size, bool verify_peer, bool verify_hostname) +{ + long http_code = 0; + CURL* curl = NULL; - /* Get Total Response Size */ - int total_rsps_size = 0; - for(int i = 0; i < rsps_set.length(); i++) - { - total_rsps_size += rsps_set[i].size; - } + /* Initialize Request */ + data_t rqst; + rqst.data = (char*)data; + rqst.size = StringLib::size(data); - /* Allocate and Populate Total Response */ - int total_rsps_index = 0; - char* total_rsps = new char [total_rsps_size + 1]; - for(int i = 0; i < rsps_set.length(); i++) - { - memcpy(&total_rsps[total_rsps_index], rsps_set[i].data, rsps_set[i].size); - total_rsps_index += rsps_set[i].size; - delete [] rsps_set[i].data; - } - total_rsps[total_rsps_index] = '\0'; + /* Initialize Response */ + List rsps_set; + if(response) *response = NULL; + if(size) *size = 0; - /* Return Response String */ - lua_pushlstring(L, total_rsps, total_rsps_index); - delete [] total_rsps; - } - else - { - /* Return NIL in place of Response String */ - lua_pushnil(L); - } + /* Initialize cURL */ + curl = curl_easy_init(); + if(curl) + { + curl_easy_setopt(curl, CURLOPT_URL, url); + curl_easy_setopt(curl, CURLOPT_POST, 1L); + curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, CONNECTION_TIMEOUT); // seconds + curl_easy_setopt(curl, CURLOPT_TIMEOUT, DATA_TIMEOUT); // seconds + curl_easy_setopt(curl, CURLOPT_READFUNCTION, CurlLib::readData); + curl_easy_setopt(curl, CURLOPT_READDATA, &rqst); + curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, (long)rqst.size); + curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, CurlLib::writeData); + curl_easy_setopt(curl, CURLOPT_WRITEDATA, &rsps_set); + + /* + * If you want to connect to a site who isn't using a certificate that is + * signed by one of the certs in the CA bundle you have, you can skip the + * verification of the server's certificate. This makes the connection + * A LOT LESS SECURE. + * + * If you have a CA cert for the server stored someplace else than in the + * default bundle, then the CURLOPT_CAPATH option might come handy for + * you. + */ + if(!verify_peer) + { + curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L); + } + + /* + * If the site you're connecting to uses a different host name that what + * they have mentioned in their server certificate's commonName (or + * subjectAltName) fields, libcurl will refuse to connect. You can skip + * this check, but this will make the connection less secure. + */ + if(!verify_hostname) + { + curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L); + } + + /* Perform the request, res will get the return code */ + CURLcode res = curl_easy_perform(curl); + + /* Check for Success */ + if(res == CURLE_OK) + { + /* Get HTTP Code */ + curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &http_code); + + /* Get Response */ + CurlLib::combineResponse(&rsps_set, response, size); + } + else + { + /* Unable to Perform cURL Call */ + mlog(ERROR, "Unable to perform cRUL call on %s: %s", url, curl_easy_strerror(res)); + http_code = EndpointObject::Service_Unavailable; + } + + /* Always Cleanup */ + curl_easy_cleanup(curl); + } + + /* Return HTTP Code */ + return http_code; +} + +/*---------------------------------------------------------------------------- + * postAsStream + *----------------------------------------------------------------------------*/ +long CurlLib::postAsStream (const char* url, const char* data, Publisher* outq, bool with_terminator) +{ + long http_code = 0; + CURL* curl = NULL; + + /* Initialize Request */ + data_t rqst; + rqst.data = (char*)data; + rqst.size = StringLib::size(data); + + /* Initialize cURL */ + curl = curl_easy_init(); + if(curl) + { + curl_easy_setopt(curl, CURLOPT_URL, url); + curl_easy_setopt(curl, CURLOPT_BUFFERSIZE, CURL_MAX_READ_SIZE); // TODO: test out performance + curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L); + curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L); + curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, CONNECTION_TIMEOUT); // seconds + curl_easy_setopt(curl, CURLOPT_TIMEOUT, DATA_TIMEOUT); // seconds + curl_easy_setopt(curl, CURLOPT_POST, 1L); + curl_easy_setopt(curl, CURLOPT_READFUNCTION, CurlLib::readData); + curl_easy_setopt(curl, CURLOPT_READDATA, &rqst); + curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, (long)rqst.size); + curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, CurlLib::postData); + curl_easy_setopt(curl, CURLOPT_WRITEDATA, outq); + + /* Perform the request, res will get the return code */ + CURLcode res = curl_easy_perform(curl); + + /* Check for Success */ + if(res == CURLE_OK) + { + /* Get HTTP Code */ + curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &http_code); + } + else + { + /* Unable to Perform cURL Call */ + mlog(ERROR, "Unable to perform cRUL call on %s: %s", url, curl_easy_strerror(res)); + http_code = EndpointObject::Service_Unavailable; + } + + /* Always Cleanup */ + curl_easy_cleanup(curl); + } + + /* Terminate Stream */ + if(with_terminator) + { + outq->postCopy("", 0); + } + + /* Return HTTP Code */ + return http_code; +} + +/*---------------------------------------------------------------------------- + * postAsRecord + *----------------------------------------------------------------------------*/ +long CurlLib::postAsRecord (const char* url, const char* data, Publisher* outq, bool with_terminator, int timeout, bool* active) +{ + long http_code = 0; + CURL* curl = NULL; + + /* Initialize Request */ + data_t rqst; + rqst.data = (char*)data; + rqst.size = StringLib::size(data); + + /* Initialize Response (only used if as_record is true) */ + parser_t parser = { + .hdr_index = 0, + .rec_size = 0, + .rec_index = 0, + .rec_buf = NULL, + .outq = outq, + .url = url, + .active = active + }; + + /* Initialize cURL */ + curl = curl_easy_init(); + if(curl) + { + curl_easy_setopt(curl, CURLOPT_URL, url); + curl_easy_setopt(curl, CURLOPT_BUFFERSIZE, CURL_MAX_READ_SIZE); // TODO: test out performance + curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L); + curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L); + curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, CONNECTION_TIMEOUT); // seconds + curl_easy_setopt(curl, CURLOPT_TIMEOUT, timeout); // seconds + curl_easy_setopt(curl, CURLOPT_POST, 1L); + curl_easy_setopt(curl, CURLOPT_READFUNCTION, CurlLib::readData); + curl_easy_setopt(curl, CURLOPT_READDATA, &rqst); + curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, (long)rqst.size); + curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, CurlLib::postRecords); + curl_easy_setopt(curl, CURLOPT_WRITEDATA, &parser); + + /* Perform the request, res will get the return code */ + CURLcode res = curl_easy_perform(curl); + + /* Check for Success */ + if(res == CURLE_OK) + { + /* Get HTTP Code */ + curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &http_code); + } + else + { + /* Unable to Perform cURL Call */ + mlog(ERROR, "Unable to perform cRUL call on %s: %s", url, curl_easy_strerror(res)); + http_code = EndpointObject::Service_Unavailable; + } + + /* Always Cleanup */ + curl_easy_cleanup(curl); + } + + /* Terminate Stream */ + if(with_terminator) + { + outq->postCopy("", 0); + } + + /* Return HTTP Code */ + return http_code; +} + +/*---------------------------------------------------------------------------- + * luaGet + *----------------------------------------------------------------------------*/ +int CurlLib::luaGet (lua_State* L) +{ + bool status = false; + + try + { + /* Get Parameters */ + const char* url = LuaObject::getLuaString(L, 1); + bool verify_peer = LuaObject::getLuaBoolean(L, 2, true, false); + bool verify_hostname = LuaObject::getLuaBoolean(L, 3, true, false); + const char* data = LuaObject::getLuaString(L, 4, true, ""); + + /* Perform Request */ + const char* response = NULL; + int size = 0; + long http_code = CurlLib::get(url, data, &response, &size, verify_peer, verify_hostname); + if(response) + { + status = (http_code >= 200 && http_code < 300); + lua_pushlstring(L, response, size); + delete [] response; } else { - /* Return NIL in place of Response String */ lua_pushnil(L); } } @@ -182,9 +404,6 @@ int CurlLib::luaGet (lua_State* L) lua_pushnil(L); } - /* Always Cleanup */ - if(curl) curl_easy_cleanup(curl); - /* Return Status */ lua_pushboolean(L, status); return 2; @@ -196,7 +415,6 @@ int CurlLib::luaGet (lua_State* L) int CurlLib::luaPost (lua_State* L) { bool status = false; - CURL* curl = NULL; try { @@ -204,75 +422,19 @@ int CurlLib::luaPost (lua_State* L) const char* url = LuaObject::getLuaString(L, 1); const char* data = LuaObject::getLuaString(L, 2, true, "{}"); - /* Initialize Request */ - data_t rqst; - rqst.data = (char*)data; - rqst.size = StringLib::size(data); - - /* Initialize Response */ - List rsps_set; - - /* Initialize cURL */ - curl = curl_easy_init(); - if(curl) + /* Perform Request */ + const char* response = NULL; + int size = 0; + long http_code = CurlLib::post(url, data, &response, &size); + if(response) { - curl_easy_setopt(curl, CURLOPT_URL, url); - curl_easy_setopt(curl, CURLOPT_POST, 1L); - curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 10L); // seconds - curl_easy_setopt(curl, CURLOPT_TIMEOUT, 10L); // seconds - curl_easy_setopt(curl, CURLOPT_READFUNCTION, CurlLib::readData); - curl_easy_setopt(curl, CURLOPT_READDATA, &rqst); - curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, (long)rqst.size); - curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, CurlLib::writeData); - curl_easy_setopt(curl, CURLOPT_WRITEDATA, &rsps_set); - - /* Perform the request, res will get the return code */ - CURLcode res = curl_easy_perform(curl); - - /* Check for Success */ - if(res == CURLE_OK) - { - /* Get HTTP Code */ - long http_code = 0; - curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &http_code); - if(http_code == 200) - { - /* Set Successfull */ - status = true; - } - - /* Get Total Response Size */ - int total_rsps_size = 0; - for(int i = 0; i < rsps_set.length(); i++) - { - total_rsps_size += rsps_set[i].size; - } - - /* Allocate and Populate Total Response */ - int total_rsps_index = 0; - char* total_rsps = new char [total_rsps_size + 1]; - for(int i = 0; i < rsps_set.length(); i++) - { - memcpy(&total_rsps[total_rsps_index], rsps_set[i].data, rsps_set[i].size); - total_rsps_index += rsps_set[i].size; - delete [] rsps_set[i].data; - } - total_rsps[total_rsps_index] = '\0'; - - /* Return Response String */ - lua_pushlstring(L, total_rsps, total_rsps_index); - delete [] total_rsps; - } - else - { - /* Failed Request */ - lua_pushstring(L, curl_easy_strerror(res)); - } + status = (http_code >= 200 && http_code < 300); + lua_pushlstring(L, response, size); + delete [] response; } else { - /* Error Response String */ - lua_pushstring(L, "unable to initialize net services"); + lua_pushnil(L); } } catch(const RunTimeException& e) @@ -281,20 +443,123 @@ int CurlLib::luaPost (lua_State* L) lua_pushnil(L); } - /* Always Cleanup */ - if(curl) curl_easy_cleanup(curl); - /* Return Status */ lua_pushboolean(L, status); return 2; } +/*---------------------------------------------------------------------------- + * CurlLib::combineResponse + *----------------------------------------------------------------------------*/ +void CurlLib::combineResponse (List* rsps_set, const char** response, int* size) +{ + /* Get Total Response Size */ + int total_rsps_size = 0; + for(int i = 0; i < rsps_set->length(); i++) + { + total_rsps_size += (*rsps_set)[i].size; + } + + /* Allocate and Populate Total Response */ + int total_rsps_index = 0; + char* total_rsps = new char [total_rsps_size + 1]; + for(int i = 0; i < rsps_set->length(); i++) + { + memcpy(&total_rsps[total_rsps_index], (*rsps_set)[i].data, (*rsps_set)[i].size); + total_rsps_index += (*rsps_set)[i].size; + delete [] (*rsps_set)[i].data; + } + total_rsps[total_rsps_index] = '\0'; + + /* Return Response */ + if(size) *size = total_rsps_index; + if(response) *response = total_rsps; + else delete [] total_rsps; +} + +/*---------------------------------------------------------------------------- + * CurlLib::postRecords + *----------------------------------------------------------------------------*/ +size_t CurlLib::postRecords(void *buffer, size_t size, size_t nmemb, void *userp) +{ + parser_t* parser = static_cast(userp); + int32_t bytes_to_process = static_cast(size * nmemb); + uint8_t* input_data = static_cast(buffer); + uint32_t input_index = 0; + + while(bytes_to_process > 0) + { + if(parser->rec_size == 0) // record header + { + int32_t hdr_bytes_needed = RECOBJ_HDR_SIZE - parser->hdr_index; + int32_t hdr_bytes_to_process = MIN(hdr_bytes_needed, bytes_to_process); + for(int i = 0; i < hdr_bytes_to_process; i++) parser->hdr_buf[parser->hdr_index++] = input_data[input_index++]; + bytes_to_process -= hdr_bytes_to_process; + + // check header complete + if(parser->hdr_index == RECOBJ_HDR_SIZE) + { + // allocate record and copy header + RecordObject::rec_hdr_t* rec_hdr = reinterpret_cast(parser->hdr_buf); + parser->rec_size = sizeof(RecordObject::rec_hdr_t) + rec_hdr->type_size + rec_hdr->data_size; + parser->rec_buf = new uint8_t [parser->rec_size]; + memcpy(&parser->rec_buf[0], &parser->hdr_buf[0], sizeof(RecordObject::rec_hdr_t)); + parser->rec_index = sizeof(RecordObject::rec_hdr_t); + + // reset header + parser->hdr_index = 0; + } + } + else // record body + { + int32_t rec_bytes_needed = parser->rec_size - parser->rec_index; + int32_t rec_bytes_to_process = MIN(rec_bytes_needed, bytes_to_process); + memcpy(&parser->rec_buf[parser->rec_index], &input_data[input_index], rec_bytes_to_process); + parser->rec_index += rec_bytes_to_process; + input_index += rec_bytes_to_process; + bytes_to_process -= rec_bytes_to_process; + + // check body complete + if(parser->rec_index == parser->rec_size) + { + // post record + int post_status = MsgQ::STATE_TIMEOUT; + while((!parser->active || *parser->active) && post_status == MsgQ::STATE_TIMEOUT) + { + post_status = parser->outq->postRef(parser->rec_buf, parser->rec_size, SYS_TIMEOUT); + if(post_status < 0) + { + // handle post errors + delete [] parser->rec_buf; + mlog(CRITICAL, "Failed to post response for %s: %d", parser->url, post_status); + } + } + + // reset body + parser->rec_index = 0; + parser->rec_size = 0; + } + } + } + + return size * nmemb; +} + +/*---------------------------------------------------------------------------- + * CurlLib::postData + *----------------------------------------------------------------------------*/ +size_t CurlLib::postData(void *buffer, size_t size, size_t nmemb, void *userp) +{ + Publisher* outq = static_cast(userp); + return outq->postCopy(buffer, size * nmemb); +} + /*---------------------------------------------------------------------------- * CurlLib::writeData *----------------------------------------------------------------------------*/ size_t CurlLib::writeData(void *buffer, size_t size, size_t nmemb, void *userp) { - List* rsps_set = (List*)userp; + List* rsps_set = static_cast*>(userp); data_t rsps; rsps.size = size * nmemb; @@ -313,7 +578,7 @@ size_t CurlLib::writeData(void *buffer, size_t size, size_t nmemb, void *userp) *----------------------------------------------------------------------------*/ size_t CurlLib::readData(void* buffer, size_t size, size_t nmemb, void *userp) { - data_t* rqst = (data_t*)userp; + data_t* rqst = static_cast(userp); size_t buffer_size = size * nmemb; size_t bytes_to_copy = rqst->size; diff --git a/packages/netsvc/CurlLib.h b/packages/netsvc/CurlLib.h index 6dbbce3bf..06ae75bfc 100644 --- a/packages/netsvc/CurlLib.h +++ b/packages/netsvc/CurlLib.h @@ -46,15 +46,6 @@ class CurlLib { public: - /*-------------------------------------------------------------------- - * Typedefs - *--------------------------------------------------------------------*/ - - typedef struct { - char* data; - size_t size; - } data_t; - /*-------------------------------------------------------------------- * Methods *--------------------------------------------------------------------*/ @@ -62,17 +53,54 @@ class CurlLib static void init (void); static void deinit (void); + static long get (const char* url, const char* data, const char** response, int* size=NULL, bool verify_peer=false, bool verify_hostname=false); + static long post (const char* url, const char* data, const char** response, int* size=NULL, bool verify_peer=false, bool verify_hostname=false); + static long postAsStream (const char* url, const char* data, Publisher* outq, bool with_terminator); + static long postAsRecord (const char* url, const char* data, Publisher* outq, bool with_terminator, int timeout, bool* active=NULL); static int luaGet (lua_State* L); static int luaPost (lua_State* L); private: + /*-------------------------------------------------------------------- + * Constants + *--------------------------------------------------------------------*/ + + static const int EXPECTED_RESPONSE_SEGMENTS = 16; + static const int CONNECTION_TIMEOUT = 10L; // seconds + static const int DATA_TIMEOUT = 60L; // seconds + + static const int RECOBJ_HDR_SIZE = 8; // bytes + + /*-------------------------------------------------------------------- + * Typedefs + *--------------------------------------------------------------------*/ + + typedef struct { + char* data; + size_t size; + } data_t; + + typedef struct { + uint8_t hdr_buf[RECOBJ_HDR_SIZE]; + uint32_t hdr_index; + uint32_t rec_size; + uint32_t rec_index; + uint8_t* rec_buf; + Publisher* outq; + const char* url; + bool* active; + } parser_t; + /*-------------------------------------------------------------------- * Methods *--------------------------------------------------------------------*/ - static size_t writeData (void *buffer, size_t size, size_t nmemb, void *userp); - static size_t readData (void* buffer, size_t size, size_t nmemb, void *userp); + static void combineResponse (List* rsps_set, const char** response, int* size); + static size_t postRecords (void *buffer, size_t size, size_t nmemb, void *userp); + static size_t postData (void *buffer, size_t size, size_t nmemb, void *userp); + static size_t writeData (void *buffer, size_t size, size_t nmemb, void *userp); + static size_t readData (void* buffer, size_t size, size_t nmemb, void *userp); }; #endif /* __curl_lib__ */ diff --git a/packages/netsvc/EndpointProxy.cpp b/packages/netsvc/EndpointProxy.cpp index 1769ca160..3e14944a6 100644 --- a/packages/netsvc/EndpointProxy.cpp +++ b/packages/netsvc/EndpointProxy.cpp @@ -317,12 +317,11 @@ void* EndpointProxy::proxyThread (void* parm) { try { - FString path("/source/%s", proxy->endpoint); + FString url("%s/source/%s", node->member, proxy->endpoint); FString data("{\"resource\": \"%s\", \"parms\": %s, \"timeout\": %d, \"shard\": %d}", resource, proxy->parameters, proxy->timeout, current_resource); - HttpClient client(NULL, node->member); - HttpClient::rsps_t rsps = client.request(EndpointObject::POST, path.c_str(), data.c_str(), false, proxy->outQ, proxy->timeout * 1000); - if(rsps.code == EndpointObject::OK) valid = true; - else throw RunTimeException(CRITICAL, RTE_ERROR, "Error code returned from request to %s: %d", node->member, (int)rsps.code); + long http_code = CurlLib::postAsRecord(url.c_str(), data.c_str(), proxy->outQ, false, proxy->timeout, &proxy->active); + if(http_code == EndpointObject::OK) valid = true; + else throw RunTimeException(CRITICAL, RTE_ERROR, "Error code returned from request to %s: %d", node->member, (int)http_code); } catch(const RunTimeException& e) { diff --git a/packages/netsvc/OrchestratorLib.cpp b/packages/netsvc/OrchestratorLib.cpp index 0e1a06236..44c9008ee 100644 --- a/packages/netsvc/OrchestratorLib.cpp +++ b/packages/netsvc/OrchestratorLib.cpp @@ -35,6 +35,7 @@ #include "OrchestratorLib.h" +#include "netsvc.h" #include "core.h" #include @@ -68,10 +69,29 @@ void OrchestratorLib::deinit (void) /*---------------------------------------------------------------------------- * deinit *----------------------------------------------------------------------------*/ -HttpClient::rsps_t OrchestratorLib::request (EndpointObject::verb_t verb, const char* resource, const char* data) +OrchestratorLib::rsps_t OrchestratorLib::request (EndpointObject::verb_t verb, const char* resource, const char* data) { - HttpClient client(NULL, URL); - return client.request(verb, resource, data, false, NULL); + FString path("%s%s", URL, resource); + if(verb == EndpointObject::GET) + { + rsps_t rsps; + rsps.code = CurlLib::get(path.c_str(), data, &rsps.response, &rsps.size); + return rsps; + } + + if(verb == EndpointObject::POST) + { + rsps_t rsps; + rsps.code = CurlLib::post(path.c_str(), data, &rsps.response, &rsps.size); + return rsps; + } + + rsps_t err_rsps = { + .code = static_cast(EndpointObject::Bad_Request), + .response = NULL, + .size = 0 + }; + return err_rsps; } /*---------------------------------------------------------------------------- @@ -82,7 +102,7 @@ bool OrchestratorLib::registerService (const char* service, int lifetime, const bool status = true; FString rqst("{\"service\":\"%s\", \"lifetime\": %d, \"address\": \"%s\"}", service, lifetime, address); - HttpClient::rsps_t rsps = request(EndpointObject::POST, "/discovery/register", rqst.c_str()); + rsps_t rsps = request(EndpointObject::POST, "/discovery/register", rqst.c_str()); if(rsps.code == EndpointObject::OK) { try @@ -127,7 +147,7 @@ vector* OrchestratorLib::lock (const char* service, int vector* nodes = NULL; FString rqst("{\"service\":\"%s\", \"nodesNeeded\": %d, \"timeout\": %d}", service, nodes_needed, timeout_secs); - HttpClient::rsps_t rsps = request(EndpointObject::POST, "/discovery/lock", rqst.c_str()); + rsps_t rsps = request(EndpointObject::POST, "/discovery/lock", rqst.c_str()); if(rsps.code == EndpointObject::OK) { try @@ -177,7 +197,7 @@ vector* OrchestratorLib::lock (const char* service, int } else { - mlog(CRITICAL, "Encountered HTTP error <%d> when locking nodes on %s", rsps.code, service); + mlog(CRITICAL, "Encountered HTTP error <%ld> when locking nodes on %s", rsps.code, service); } delete [] rsps.response; @@ -200,7 +220,7 @@ bool OrchestratorLib::unlock (long transactions[], int num_transactions, bool ve for(int t = 1; t < num_transactions; t++) rqst += StringLib::format(strbuf, 64, ",%ld", transactions[t]); rqst += "]}"; - HttpClient::rsps_t rsps = request(EndpointObject::POST, "/discovery/unlock", rqst.c_str()); + rsps_t rsps = request(EndpointObject::POST, "/discovery/unlock", rqst.c_str()); if(rsps.code == EndpointObject::OK) { try @@ -239,7 +259,7 @@ bool OrchestratorLib::health (void) { bool status = false; - HttpClient::rsps_t rsps = request(EndpointObject::GET, "/discovery/health", NULL); + rsps_t rsps = request(EndpointObject::GET, "/discovery/health", NULL); if(rsps.code == EndpointObject::OK) { try @@ -270,7 +290,7 @@ bool OrchestratorLib::metric (const unsigned char* metric_buf, int buf_size) bool status = false; - HttpClient::rsps_t rsps = request(EndpointObject::POST, "/discovery/metric", reinterpret_cast(metric_buf)); + rsps_t rsps = request(EndpointObject::POST, "/discovery/metric", reinterpret_cast(metric_buf)); if(rsps.code == EndpointObject::OK) { status = true; diff --git a/packages/netsvc/OrchestratorLib.h b/packages/netsvc/OrchestratorLib.h index b5a42faae..aa52706b2 100644 --- a/packages/netsvc/OrchestratorLib.h +++ b/packages/netsvc/OrchestratorLib.h @@ -65,26 +65,32 @@ class OrchestratorLib } }; + typedef struct { + long code; + const char* response; + int size; + } rsps_t; + /*-------------------------------------------------------------------- * Methods *--------------------------------------------------------------------*/ - static void init (void); - static void deinit (void); + static void init (void); + static void deinit (void); - static HttpClient::rsps_t request (EndpointObject::verb_t verb, const char* resource, const char* data); + static rsps_t request (EndpointObject::verb_t verb, const char* resource, const char* data); - static bool registerService (const char* service, int lifetime, const char* address, bool verbose=false); - static vector* lock (const char* service, int nodes_needed, int timeout_secs, bool verbose=false); - static bool unlock (long transactions[], int num_transactions, bool verbose=false); - static bool health (void); - static bool metric (const unsigned char* metric_buf, int buf_size); + static bool registerService (const char* service, int lifetime, const char* address, bool verbose=false); + static vector* lock (const char* service, int nodes_needed, int timeout_secs, bool verbose=false); + static bool unlock (long transactions[], int num_transactions, bool verbose=false); + static bool health (void); + static bool metric (const unsigned char* metric_buf, int buf_size); - static int luaUrl (lua_State* L); - static int luaRegisterService (lua_State* L); - static int luaLock (lua_State* L); - static int luaUnlock (lua_State* L); - static int luaHealth (lua_State* L); + static int luaUrl (lua_State* L); + static int luaRegisterService (lua_State* L); + static int luaLock (lua_State* L); + static int luaUnlock (lua_State* L); + static int luaHealth (lua_State* L); /*-------------------------------------------------------------------- * Data From 458afa42aa17ddfee0335c2e0f1f59ffbe4c6fc7 Mon Sep 17 00:00:00 2001 From: JP Swinski Date: Mon, 30 Oct 2023 16:27:17 +0000 Subject: [PATCH 08/14] fixed compiler warning in CurlLib --- packages/netsvc/CurlLib.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/netsvc/CurlLib.cpp b/packages/netsvc/CurlLib.cpp index 4b636bd7c..bc44a07a4 100644 --- a/packages/netsvc/CurlLib.cpp +++ b/packages/netsvc/CurlLib.cpp @@ -312,6 +312,7 @@ long CurlLib::postAsRecord (const char* url, const char* data, Publisher* outq, /* Initialize Response (only used if as_record is true) */ parser_t parser = { + .hdr_buf = {0, 0, 0, 0, 0, 0, 0, 0}, .hdr_index = 0, .rec_size = 0, .rec_index = 0, From eb65db03b8ca14de65ec99462eb9a826c0a7d5bc Mon Sep 17 00:00:00 2001 From: JP Swinski Date: Mon, 30 Oct 2023 17:25:42 +0000 Subject: [PATCH 09/14] fixed bug in how rec hdr was decommed --- packages/netsvc/CurlLib.cpp | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/packages/netsvc/CurlLib.cpp b/packages/netsvc/CurlLib.cpp index bc44a07a4..972cb6872 100644 --- a/packages/netsvc/CurlLib.cpp +++ b/packages/netsvc/CurlLib.cpp @@ -357,6 +357,12 @@ long CurlLib::postAsRecord (const char* url, const char* data, Publisher* outq, /* Always Cleanup */ curl_easy_cleanup(curl); + + /* Free Left-Over Response (if present) */ + if(parser.rec_size > 0) + { + delete [] parser.rec_buf; + } } /* Terminate Stream */ @@ -500,9 +506,19 @@ size_t CurlLib::postRecords(void *buffer, size_t size, size_t nmemb, void *userp // check header complete if(parser->hdr_index == RECOBJ_HDR_SIZE) { - // allocate record and copy header + // parser header RecordObject::rec_hdr_t* rec_hdr = reinterpret_cast(parser->hdr_buf); - parser->rec_size = sizeof(RecordObject::rec_hdr_t) + rec_hdr->type_size + rec_hdr->data_size; + uint16_t version = OsApi::swaps(rec_hdr->version); + uint16_t type_size = OsApi::swaps(rec_hdr->type_size); + uint32_t data_size = OsApi::swapl(rec_hdr->data_size); + if(version != RecordObject::RECORD_FORMAT_VERSION) + { + mlog(CRITICAL, "Invalid record version in response from %s: %d", parser->url, version); + return 0; + } + + // allocate record and copy header + parser->rec_size = sizeof(RecordObject::rec_hdr_t) + type_size + data_size; parser->rec_buf = new uint8_t [parser->rec_size]; memcpy(&parser->rec_buf[0], &parser->hdr_buf[0], sizeof(RecordObject::rec_hdr_t)); parser->rec_index = sizeof(RecordObject::rec_hdr_t); From 7cbb1030cf5f4206c6da7debc1d3dfe2d875cc87 Mon Sep 17 00:00:00 2001 From: JP Swinski Date: Mon, 30 Oct 2023 19:37:06 +0000 Subject: [PATCH 10/14] string lib size no longer has a max string length --- packages/aws/CredentialStore.h | 17 +++++++------ packages/core/CsvDispatch.cpp | 4 ++-- packages/core/EndpointObject.cpp | 2 +- packages/core/HttpClient.cpp | 8 +++---- packages/core/HttpServer.cpp | 2 +- packages/core/LuaEndpoint.cpp | 2 +- packages/core/LuaEndpoint.h | 1 - packages/core/LuaEngine.cpp | 2 +- packages/core/Monitor.cpp | 2 +- packages/core/RecordObject.cpp | 4 ++-- packages/core/StringLib.cpp | 29 ++++++++++++++--------- packages/core/StringLib.h | 10 ++++---- packages/geo/GeoParms.cpp | 2 +- packages/h5/H5Coro.cpp | 2 +- packages/netsvc/EndpointProxy.cpp | 2 +- packages/netsvc/EndpointProxy.h | 1 - packages/netsvc/ProvisioningSystemLib.cpp | 2 +- 17 files changed, 48 insertions(+), 44 deletions(-) diff --git a/packages/aws/CredentialStore.h b/packages/aws/CredentialStore.h index e7dc1a284..40dc19335 100644 --- a/packages/aws/CredentialStore.h +++ b/packages/aws/CredentialStore.h @@ -55,7 +55,6 @@ class CredentialStore *--------------------------------------------------------------------*/ static const int STARTING_STORE_SIZE = 8; - static const int MAX_KEY_SIZE = 2048; static const char* LIBRARY_NAME; static const char* EXPIRATION_GPS_METRIC; @@ -132,7 +131,7 @@ class CredentialStore } } const char* access_key_id_str = LuaObject::getLuaString(L, -1); - accessKeyId = StringLib::duplicate(access_key_id_str, MAX_KEY_SIZE); + accessKeyId = StringLib::duplicate(access_key_id_str); lua_pop(L, 1); /* Get Secret Access Key */ @@ -146,7 +145,7 @@ class CredentialStore } } const char* secret_access_key_str = LuaObject::getLuaString(L, -1); - secretAccessKey = StringLib::duplicate(secret_access_key_str, MAX_KEY_SIZE); + secretAccessKey = StringLib::duplicate(secret_access_key_str); lua_pop(L, 1); /* Get Session Token */ @@ -160,7 +159,7 @@ class CredentialStore } } const char* session_token_str = LuaObject::getLuaString(L, -1); - sessionToken = StringLib::duplicate(session_token_str, MAX_KEY_SIZE); + sessionToken = StringLib::duplicate(session_token_str); lua_pop(L, 1); /* Get Expiration Date */ @@ -170,7 +169,7 @@ class CredentialStore lua_getfield(L, index, EXPIRATION_STR1); } const char* expiration_str = LuaObject::getLuaString(L, -1, true, NULL); - expiration = StringLib::duplicate(expiration_str, MAX_KEY_SIZE); + expiration = StringLib::duplicate(expiration_str); if(expiration) expirationGps = TimeLib::str2gpstime(expiration); else expirationGps = 0; lua_pop(L, 1); @@ -226,10 +225,10 @@ class CredentialStore void copy (const Credential& c) { provided = c.provided; - accessKeyId = StringLib::duplicate(c.accessKeyId, MAX_KEY_SIZE); - secretAccessKey = StringLib::duplicate(c.secretAccessKey, MAX_KEY_SIZE); - sessionToken = StringLib::duplicate(c.sessionToken, MAX_KEY_SIZE); - expiration = StringLib::duplicate(c.expiration, MAX_KEY_SIZE); + accessKeyId = StringLib::duplicate(c.accessKeyId); + secretAccessKey = StringLib::duplicate(c.secretAccessKey); + sessionToken = StringLib::duplicate(c.sessionToken); + expiration = StringLib::duplicate(c.expiration); expirationGps = c.expirationGps; } }; diff --git a/packages/core/CsvDispatch.cpp b/packages/core/CsvDispatch.cpp index b3cb71075..344a9c47c 100644 --- a/packages/core/CsvDispatch.cpp +++ b/packages/core/CsvDispatch.cpp @@ -125,7 +125,7 @@ CsvDispatch::CsvDispatch (lua_State* L, const char* outq_name, const char** _col } /* Send Out Header Row */ - int len = StringLib::size(hdrrow, MAX_STR_SIZE) + 1; + int len = StringLib::size(hdrrow) + 1; outQ->postCopy(hdrrow, len, SYS_TIMEOUT); } @@ -172,7 +172,7 @@ bool CsvDispatch::processRecord (RecordObject* record, okey_t key, recVec_t* rec } /* Send Out Row */ - int len = StringLib::size(valrow, MAX_STR_SIZE) + 1; + int len = StringLib::size(valrow) + 1; int status = outQ->postCopy(valrow, len, SYS_TIMEOUT); /* Check and Return Status */ diff --git a/packages/core/EndpointObject.cpp b/packages/core/EndpointObject.cpp index dd3d0e944..7c36243f0 100644 --- a/packages/core/EndpointObject.cpp +++ b/packages/core/EndpointObject.cpp @@ -178,5 +178,5 @@ int EndpointObject::buildheader (char hdr_str[MAX_HDR_SIZE], code_t code, const StringLib::concat(hdr_str, "\r\n", MAX_HDR_SIZE); - return StringLib::size(hdr_str, MAX_HDR_SIZE); + return StringLib::size(hdr_str); } diff --git a/packages/core/HttpClient.cpp b/packages/core/HttpClient.cpp index 84b51e1c3..d0436523f 100644 --- a/packages/core/HttpClient.cpp +++ b/packages/core/HttpClient.cpp @@ -113,7 +113,7 @@ HttpClient::HttpClient(lua_State* L, const char* url): // Parse URL char url_buf[MAX_URL_LEN]; StringLib::copy(url_buf, url, MAX_URL_LEN); - char* proto_term = StringLib::find(url_buf, "://", MAX_URL_LEN); + char* proto_term = StringLib::find(url_buf, "://"); if(proto_term) { char* proto = url_buf; @@ -121,7 +121,7 @@ HttpClient::HttpClient(lua_State* L, const char* url): *proto_term = '\0'; if((_ip_addr - proto) < MAX_URL_LEN) { - char* ip_addr_term = StringLib::find(_ip_addr, ":", MAX_URL_LEN); + char* ip_addr_term = StringLib::find(_ip_addr, ":"); if(ip_addr_term) { char* _port_str = ip_addr_term + 1; @@ -232,8 +232,8 @@ bool HttpClient::makeRequest (EndpointObject::verb_t verb, const char* resource, int content_length = 0; if(data) { - content_length = StringLib::size(data, MAX_RQST_BUF_LEN); - if(content_length == MAX_RQST_BUF_LEN) + content_length = StringLib::size(data); + if(content_length >= MAX_RQST_BUF_LEN) { throw RunTimeException(ERROR, RTE_ERROR, "data exceeds maximum allowed size: %d > %d", content_length, MAX_RQST_BUF_LEN); } diff --git a/packages/core/HttpServer.cpp b/packages/core/HttpServer.cpp index 24ec93d74..3fa475378 100644 --- a/packages/core/HttpServer.cpp +++ b/packages/core/HttpServer.cpp @@ -556,7 +556,7 @@ int HttpServer::onWrite(int fd) /* Write Chunk Header - HTTP */ unsigned long chunk_size = state->ref.size > 0 ? state->ref.size : 0; StringLib::format((char*)state->stream_buf, STREAM_OVERHEAD_SIZE, "%lX\r\n", chunk_size); - state->stream_buf_size = StringLib::size((const char*)state->stream_buf, state->stream_mem_size); + state->stream_buf_size = StringLib::size((const char*)state->stream_buf); if(state->ref.size > 0) { diff --git a/packages/core/LuaEndpoint.cpp b/packages/core/LuaEndpoint.cpp index 4c1f627be..feae824f4 100644 --- a/packages/core/LuaEndpoint.cpp +++ b/packages/core/LuaEndpoint.cpp @@ -289,7 +289,7 @@ void LuaEndpoint::normalResponse (const char* scriptpath, Request* request, Publ const char* result = engine->getResult(); if(result) { - int result_length = StringLib::size(result, MAX_SOURCED_RESPONSE_SIZE); + int result_length = StringLib::size(result); int header_length = buildheader(header, OK, "text/plain", result_length, NULL, serverHead.c_str()); rspq->postCopy(header, header_length); rspq->postCopy(result, result_length); diff --git a/packages/core/LuaEndpoint.h b/packages/core/LuaEndpoint.h index b00f10a86..d3095092e 100644 --- a/packages/core/LuaEndpoint.h +++ b/packages/core/LuaEndpoint.h @@ -65,7 +65,6 @@ class LuaEndpoint: public EndpointObject static const double DEFAULT_NORMAL_REQUEST_MEMORY_THRESHOLD; static const double DEFAULT_STREAM_REQUEST_MEMORY_THRESHOLD; - static const int MAX_SOURCED_RESPONSE_SIZE = 0x8000000; // 128M static const int MAX_RESPONSE_TIME_MS = 5000; static const int MAX_EXCEPTION_TEXT_SIZE = 256; static const char* LUA_RESPONSE_QUEUE; diff --git a/packages/core/LuaEngine.cpp b/packages/core/LuaEngine.cpp index 123a10713..1ebfa9d0b 100644 --- a/packages/core/LuaEngine.cpp +++ b/packages/core/LuaEngine.cpp @@ -113,7 +113,7 @@ LuaEngine::LuaEngine(const char* script, const char* arg, uint32_t trace_id, lua dInfo = new directThread_t; dInfo->engine = this; dInfo->script = StringLib::duplicate(script); - dInfo->arg = StringLib::duplicate(arg, 0); + dInfo->arg = StringLib::duplicate(arg); /* Start Script Thread */ engineActive = false; diff --git a/packages/core/Monitor.cpp b/packages/core/Monitor.cpp index 160d7758c..e1f6a600c 100644 --- a/packages/core/Monitor.cpp +++ b/packages/core/Monitor.cpp @@ -387,7 +387,7 @@ int Monitor::luaCat (lua_State* L) } else if(mode == MSGQ) { - int msg_size = StringLib::size(event_msg, MAX_EVENT_SIZE - 1) + 1; + int msg_size = StringLib::nsize(event_msg, MAX_EVENT_SIZE - 1) + 1; outq->postCopy(event_msg, msg_size, IO_CHECK); } } diff --git a/packages/core/RecordObject.cpp b/packages/core/RecordObject.cpp index 8454e71ed..476b5b010 100644 --- a/packages/core/RecordObject.cpp +++ b/packages/core/RecordObject.cpp @@ -495,7 +495,7 @@ bool RecordObject::populate (const char* populate_string) char(*toks)[MAX_STR_SIZE] = new (char[MAX_INITIALIZERS][MAX_STR_SIZE]); - int numtoks = StringLib::tokenizeLine(populate_string, (int)StringLib::size(populate_string, MAX_STR_SIZE - 1) + 1, ' ', MAX_INITIALIZERS, toks); + int numtoks = StringLib::tokenizeLine(populate_string, (int)StringLib::nsize(populate_string, MAX_STR_SIZE - 1) + 1, ' ', MAX_INITIALIZERS, toks); for(int i = 0; i < numtoks; i++) { @@ -588,7 +588,7 @@ void RecordObject::setValueText(const field_t& f, const char* val, int element) } else if(val_type == TEXT) { - int val_len = (int)StringLib::size(val, MAX_VAL_STR_SIZE) + 1; + int val_len = (int)StringLib::nsize(val, MAX_VAL_STR_SIZE) + 1; if(val_len <= f.elements) { memcpy(recordData + TOBYTES(f.offset), (unsigned char*)val, val_len); diff --git a/packages/core/StringLib.cpp b/packages/core/StringLib.cpp index e94ca529b..3a8cf3160 100644 --- a/packages/core/StringLib.cpp +++ b/packages/core/StringLib.cpp @@ -133,12 +133,11 @@ long StringLib::FormattedString::size(void) const /*---------------------------------------------------------------------------- * duplicate *----------------------------------------------------------------------------*/ -char* StringLib::duplicate(const char* str1, int size) +char* StringLib::duplicate(const char* str1) { int len; if(str1 == NULL) return NULL; - if(size > 0) len = (int)strnlen(str1, size - 1) + 1; - else len = (int)strlen(str1) + 1; + len = (int)strlen(str1) + 1; if(len < 1) return NULL; char* dup = new char[len]; StringLib::copy(dup, str1, len); @@ -243,16 +242,16 @@ char* StringLib::copy(char* dst, const char* src, int _size) * * returns -1 if string not found *----------------------------------------------------------------------------*/ -char* StringLib::find(const char* big, const char* little, int len) +char* StringLib::find(const char* big, const char* little) { - int little_len = strnlen(little, len); - int big_len = strnlen(big, len); + int little_len = strlen(little); + int big_len = strlen(big); if(little_len > 0) { for(int i=0; i<=(big_len - little_len); i++) { - if((big[i] == little[0]) && StringLib::match(&big[i], little, little_len)) + if((big[i] == little[0]) && StringLib::match(&big[i], little)) { return (char*)&big[i]; } @@ -276,9 +275,17 @@ char* StringLib::find(const char* str, char c, bool first) /*---------------------------------------------------------------------------- * size *----------------------------------------------------------------------------*/ -int StringLib::size(const char* str, int len) +int StringLib::size(const char* str) { - return strnlen(str, len); + return strlen(str); +} + +/*---------------------------------------------------------------------------- + * nsize + *----------------------------------------------------------------------------*/ +int StringLib::nsize(const char* str, int size) +{ + return strnlen(str, size); } /*---------------------------------------------------------------------------- @@ -286,9 +293,9 @@ int StringLib::size(const char* str, int len) * * exact match only *----------------------------------------------------------------------------*/ -bool StringLib::match(const char* str1, const char* str2, int len) +bool StringLib::match(const char* str1, const char* str2) { - return strncmp(str1, str2, len) == 0; + return strcmp(str1, str2) == 0; } /*---------------------------------------------------------------------------- diff --git a/packages/core/StringLib.h b/packages/core/StringLib.h index f77c8e851..bfbb05b35 100644 --- a/packages/core/StringLib.h +++ b/packages/core/StringLib.h @@ -42,7 +42,6 @@ /****************************************************************************** * STRING LIBRARY CLASS ******************************************************************************/ - class StringLib { public: @@ -68,16 +67,17 @@ class StringLib * Methods *--------------------------------------------------------------------*/ - static char* duplicate (const char* str, int size=MAX_STR_SIZE); + static char* duplicate (const char* str); static char* concat (const char* str1, const char* str2, const char* str3=NULL); static void concat (char* str1, const char* str2, int size); static char* format (char* dststr, int size, const char* _format, ...) VARG_CHECK(printf, 3, 4); static int formats (char* dststr, int size, const char* _format, ...) VARG_CHECK(printf, 3, 4); static char* copy (char* dst, const char* src, int _size); - static char* find (const char* big, const char* little, int len=MAX_STR_SIZE); + static char* find (const char* big, const char* little); static char* find (const char* str, char c, bool first=true); - static int size (const char* str, int len=MAX_STR_SIZE); - static bool match (const char* str1, const char* str2, int len=MAX_STR_SIZE); + static int size (const char* str); + static int nsize (const char* str, int size); + static bool match (const char* str1, const char* str2); static List* split (const char* str, int len, char separator, bool strip=true); static void convertUpper (char* str); static char* convertUpper (char* dst, char* src); diff --git a/packages/geo/GeoParms.cpp b/packages/geo/GeoParms.cpp index f0fbe4447..563ec1dbc 100644 --- a/packages/geo/GeoParms.cpp +++ b/packages/geo/GeoParms.cpp @@ -247,7 +247,7 @@ GeoParms::GeoParms (lua_State* L, int index, bool asset_required): /* Catalog */ lua_getfield(L, index, CATALOG); const char* catalog_str = LuaObject::getLuaString(L, -1, true, NULL); - catalog = StringLib::duplicate(catalog_str, 0); + catalog = StringLib::duplicate(catalog_str); if(catalog) mlog(DEBUG, "Setting %s to user provided geojson", CATALOG); lua_pop(L, 1); diff --git a/packages/h5/H5Coro.cpp b/packages/h5/H5Coro.cpp index 407d9d6bc..4dcfbe744 100644 --- a/packages/h5/H5Coro.cpp +++ b/packages/h5/H5Coro.cpp @@ -244,7 +244,7 @@ H5FileBuffer::H5FileBuffer (info_t* info, io_context_t* context, const Asset* as { if(metaRepo.find(meta_key, meta_repo_t::MATCH_EXACTLY, &metaData, true)) { - meta_found = StringLib::match(metaData.url, meta_url, MAX_META_NAME_SIZE); + meta_found = StringLib::match(metaData.url, meta_url); } } metaMutex.unlock(); diff --git a/packages/netsvc/EndpointProxy.cpp b/packages/netsvc/EndpointProxy.cpp index 3e14944a6..8241468a7 100644 --- a/packages/netsvc/EndpointProxy.cpp +++ b/packages/netsvc/EndpointProxy.cpp @@ -162,7 +162,7 @@ EndpointProxy::EndpointProxy (lua_State* L, const char* _endpoint, const char** /* Allocate Data Members */ endpoint = StringLib::duplicate(_endpoint); - parameters = StringLib::duplicate(_parameters, MAX_REQUEST_PARAMETER_SIZE); + parameters = StringLib::duplicate(_parameters); outQ = new Publisher(_outq_name, Publisher::defaultFree, numProxyThreads); /* Populate Resources Array */ diff --git a/packages/netsvc/EndpointProxy.h b/packages/netsvc/EndpointProxy.h index 3a600b52e..b339dcec6 100644 --- a/packages/netsvc/EndpointProxy.h +++ b/packages/netsvc/EndpointProxy.h @@ -53,7 +53,6 @@ class EndpointProxy: public LuaObject * Constants *--------------------------------------------------------------------*/ - static const int MAX_REQUEST_PARAMETER_SIZE = 0x2000000; // 32MB static const int CPU_LOAD_FACTOR = 10; // number of concurrent requests per cpu static const int COLLATOR_POLL_RATE = 1000; // milliseconds static const int DEFAULT_PROXY_QUEUE_DEPTH = 1000; diff --git a/packages/netsvc/ProvisioningSystemLib.cpp b/packages/netsvc/ProvisioningSystemLib.cpp index 82e2e2167..095cc41ed 100644 --- a/packages/netsvc/ProvisioningSystemLib.cpp +++ b/packages/netsvc/ProvisioningSystemLib.cpp @@ -378,7 +378,7 @@ ProvisioningSystemLib::Authenticator::~Authenticator (void) *----------------------------------------------------------------------------*/ bool ProvisioningSystemLib::Authenticator::isValid (const char* token) { - if(StringLib::match(ProvisioningSystemLib::Organization, DEFAULT_ORGANIZATION_NAME, MAX_STR_SIZE)) + if(StringLib::match(ProvisioningSystemLib::Organization, DEFAULT_ORGANIZATION_NAME)) { return true; // no authentication used for default organization name } From 61fd6dbc5fcd3299f19790d72177f67a1b03b85f Mon Sep 17 00:00:00 2001 From: JP Swinski Date: Tue, 31 Oct 2023 13:52:12 +0000 Subject: [PATCH 11/14] added social login support to python client --- clients/python/sliderule/sliderule.py | 33 +++++++++++++++++++-------- 1 file changed, 24 insertions(+), 9 deletions(-) diff --git a/clients/python/sliderule/sliderule.py b/clients/python/sliderule/sliderule.py index a99cf29cc..b94d4d9f5 100644 --- a/clients/python/sliderule/sliderule.py +++ b/clients/python/sliderule/sliderule.py @@ -995,12 +995,12 @@ def scaleout(desired_nodes, time_to_live, bypass_dns): # # authenticate # -def authenticate (ps_organization, ps_username=None, ps_password=None): +def authenticate (ps_organization, ps_username=None, ps_password=None, github_token=None): ''' Authenticate to SlideRule Provisioning System The username and password can be provided the following way in order of priority: - (1) The passed in arguments `ps_username' and 'ps_password'; - (2) The O.S. environment variables 'PS_USERNAME' and 'PS_PASSWORD'; + (1) The passed in arguments `github_token` or `ps_username` and `ps_password`; + (2) The O.S. environment variables `PS_GITHUB_TOKEN` or `PS_USERNAME` and `PS_PASSWORD`; (3) The `ps.` entry in the .netrc file in your home directory Parameters @@ -1013,6 +1013,10 @@ def authenticate (ps_organization, ps_username=None, ps_password=None): ps_password: str SlideRule provisioning system account password + + github_token: str + GitHub access token (minimum scope/permissions require) + Returns ------- status @@ -1036,12 +1040,13 @@ def authenticate (ps_organization, ps_username=None, ps_password=None): return True # attempt retrieving from environment - if not ps_username or not ps_password: + if not github_token and not ps_username and not ps_password: + github_token = os.environ.get("PS_GITHUB_TOKEN") ps_username = os.environ.get("PS_USERNAME") ps_password = os.environ.get("PS_PASSWORD") # attempt retrieving from netrc file - if not ps_username or not ps_password: + if not github_token and not ps_username and not ps_password: try: netrc_file = netrc.netrc() login_credentials = netrc_file.hosts[ps_url] @@ -1051,12 +1056,22 @@ def authenticate (ps_organization, ps_username=None, ps_password=None): if ps_organization != PUBLIC_ORG: logger.warning("Unable to retrieve username and password from netrc file for machine: {}".format(e)) - # authenticate to provisioning system - if ps_username and ps_password: + # build authentication request + user = None + if github_token: + user = "github" + rqst = {"org_name": ps_organization, "access_token": github_token} + headers = {'Content-Type': 'application/json'} + api = "https://" + ps_url + "/api/org_token_github/" + elif ps_username or ps_password: + user = "local" rqst = {"username": ps_username, "password": ps_password, "org_name": ps_organization} headers = {'Content-Type': 'application/json'} + api = "https://" + ps_url + "/api/org_token/" + + # authenticate to provisioning system + if user: try: - api = "https://" + ps_url + "/api/org_token/" rsps = session.post(api, data=json.dumps(rqst), headers=headers, timeout=request_timeout) rsps.raise_for_status() rsps = rsps.json() @@ -1066,7 +1081,7 @@ def authenticate (ps_organization, ps_username=None, ps_password=None): login_status = True except: if ps_organization != PUBLIC_ORG: - logger.error("Unable to authenticate user %s to %s" % (ps_username, api)) + logger.error("Unable to authenticate %s user to %s" % (user, api)) # return login status return login_status From 93700d49da537ee15325b8d209c8356949acbd06 Mon Sep 17 00:00:00 2001 From: JP Swinski Date: Tue, 31 Oct 2023 14:45:04 +0000 Subject: [PATCH 12/14] fixed orchestrator metric names --- packages/core/LuaLibrarySys.cpp | 2 +- targets/orchestrator-haproxy/orchestrator.lua | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/packages/core/LuaLibrarySys.cpp b/packages/core/LuaLibrarySys.cpp index b57fd8658..7d9cd3a3c 100644 --- a/packages/core/LuaLibrarySys.cpp +++ b/packages/core/LuaLibrarySys.cpp @@ -231,7 +231,7 @@ int LuaLibrarySys::lsys_log (lua_State* L) * lsys_metric - .metric(<...) *----------------------------------------------------------------------------*/ int LuaLibrarySys::lsys_metric (lua_State* L) -//TODO: need to create a metric like the log function +//TODO: need to populate with metrics... { (void)L; return 0; diff --git a/targets/orchestrator-haproxy/orchestrator.lua b/targets/orchestrator-haproxy/orchestrator.lua index f60a65412..ad1952402 100644 --- a/targets/orchestrator-haproxy/orchestrator.lua +++ b/targets/orchestrator-haproxy/orchestrator.lua @@ -484,7 +484,8 @@ local function api_metric(applet) applet:set_status(200) elseif metric_type == 1 then StatData.gaugeAppMetrics[metric_name] = metric_value - StatData.countAppMetrics[metric_name .. ".count"] = (StatData.countAppMetrics[metric_name .. ".count"] or 0) + 1 + StatData.gaugeAppMetrics[metric_name .. "_sum"] = (StatData.countAppMetrics[metric_name .. "_sum"] or 0.0) + metric_value + StatData.countAppMetrics[metric_name .. "_count"] = (StatData.countAppMetrics[metric_name .. "_count"] or 0) + 1 applet:set_status(200) else applet:set_status(400) From 334d5c45c1dc4739fb01480e2096727596b50111 Mon Sep 17 00:00:00 2001 From: JP Swinski Date: Wed, 1 Nov 2023 12:11:38 +0000 Subject: [PATCH 13/14] added a provisioning system token refresh pytest --- clients/python/sliderule/sliderule.py | 52 +++++++++++------------ clients/python/tests/test_provisioning.py | 7 +++ 2 files changed, 33 insertions(+), 26 deletions(-) diff --git a/clients/python/sliderule/sliderule.py b/clients/python/sliderule/sliderule.py index b94d4d9f5..69c51fa75 100644 --- a/clients/python/sliderule/sliderule.py +++ b/clients/python/sliderule/sliderule.py @@ -377,29 +377,6 @@ def __parse_native(data, callbacks): return recs -# -# __build_auth_header -# -def __build_auth_header(): - """ - Build authentication header for use with provisioning system - """ - global service_url, ps_access_token, ps_refresh_token, ps_token_exp - headers = None - if ps_access_token: - # Check if Refresh Needed - if time.time() > ps_token_exp: - host = "https://ps." + service_url + "/api/org_token/refresh/" - rqst = {"refresh": ps_refresh_token} - hdrs = {'Content-Type': 'application/json', 'Authorization': 'Bearer ' + ps_access_token} - rsps = session.post(host, data=json.dumps(rqst), headers=hdrs, timeout=request_timeout).json() - ps_refresh_token = rsps["refresh"] - ps_access_token = rsps["access"] - ps_token_exp = time.time() + (float(rsps["access_lifetime"]) / 2) - # Build Authentication Header - headers = {'Authorization': 'Bearer ' + ps_access_token} - return headers - ############################################################################### # Overriding DNS @@ -430,7 +407,7 @@ def __dnsoverridden(): def __jamdns(): global service_url, service_org, request_timeout url = service_org + "." + service_url - headers = __build_auth_header() + headers = buildauthheader() host = "https://ps." + service_url + "/api/org_ip_adr/" + service_org + "/" rsps = session.get(host, headers=headers, timeout=request_timeout).json() if rsps["status"] == "SUCCESS": @@ -505,6 +482,29 @@ def __arrowrec(rec): # INTERNAL APIs ############################################################################### +# +# buildauthheader +# +def buildauthheader(force_refresh=False): + """ + Build authentication header for use with provisioning system + """ + global service_url, ps_access_token, ps_refresh_token, ps_token_exp + headers = None + if ps_access_token: + # Check if Refresh Needed + if time.time() > ps_token_exp or force_refresh: + host = "https://ps." + service_url + "/api/org_token/refresh/" + rqst = {"refresh": ps_refresh_token} + hdrs = {'Content-Type': 'application/json', 'Authorization': 'Bearer ' + ps_access_token} + rsps = session.post(host, data=json.dumps(rqst), headers=hdrs, timeout=request_timeout).json() + ps_refresh_token = rsps["refresh"] + ps_access_token = rsps["access"] + ps_token_exp = time.time() + (float(rsps["access_lifetime"]) / 2) + # Build Authentication Header + headers = {'Authorization': 'Bearer ' + ps_access_token} + return headers + # # GeoDataFrame to Polygon # @@ -734,7 +734,7 @@ def source (api, parm={}, stream=False, callbacks={}, path="/source", silence=Fa # Construct Request URL and Authorization if service_org: url = 'https://%s.%s%s/%s' % (service_org, service_url, path, api) - headers = __build_auth_header() + headers = buildauthheader() else: url = 'http://%s%s/%s' % (service_url, path, api) # Perform Request @@ -903,7 +903,7 @@ def update_available_servers (desired_nodes=None, time_to_live=None): if type(desired_nodes) == int: rsps_body = {} requested_nodes = desired_nodes - headers = __build_auth_header() + headers = buildauthheader() # Get boundaries of cluster and calculate nodes to request try: diff --git a/clients/python/tests/test_provisioning.py b/clients/python/tests/test_provisioning.py index d71fa2d4b..9b7933d57 100644 --- a/clients/python/tests/test_provisioning.py +++ b/clients/python/tests/test_provisioning.py @@ -10,6 +10,13 @@ def test_authenticate(self, domain, organization): status = sliderule.authenticate(organization) assert status + def test_refresh(self, domain, organization): + sliderule.set_url(domain) + status = sliderule.authenticate(organization) + headers = sliderule.buildauthheader(force_refresh=True) + assert status + assert len(headers['Authorization']) > 8 + def test_num_nodes_update(self, domain, organization): sliderule.set_url(domain) status = sliderule.authenticate(organization) From 1b718e3b15946f4119b161c991c663581d7770f5 Mon Sep 17 00:00:00 2001 From: JP Swinski Date: Wed, 1 Nov 2023 15:12:44 +0000 Subject: [PATCH 14/14] fix in orchestrator for gauge metrics; updated sliderule node application metrics grafana page --- targets/orchestrator-haproxy/orchestrator.lua | 2 +- .../dashboard-sliderule-node-app-metrics.json | 2171 ++++++++++++++++- 2 files changed, 2062 insertions(+), 111 deletions(-) diff --git a/targets/orchestrator-haproxy/orchestrator.lua b/targets/orchestrator-haproxy/orchestrator.lua index ad1952402..b204c7760 100644 --- a/targets/orchestrator-haproxy/orchestrator.lua +++ b/targets/orchestrator-haproxy/orchestrator.lua @@ -484,7 +484,7 @@ local function api_metric(applet) applet:set_status(200) elseif metric_type == 1 then StatData.gaugeAppMetrics[metric_name] = metric_value - StatData.gaugeAppMetrics[metric_name .. "_sum"] = (StatData.countAppMetrics[metric_name .. "_sum"] or 0.0) + metric_value + StatData.gaugeAppMetrics[metric_name .. "_sum"] = (StatData.gaugeAppMetrics[metric_name .. "_sum"] or 0.0) + metric_value StatData.countAppMetrics[metric_name .. "_count"] = (StatData.countAppMetrics[metric_name .. "_count"] or 0) + 1 applet:set_status(200) else diff --git a/targets/slideruleearth-aws/docker/monitor/dashboard-sliderule-node-app-metrics.json b/targets/slideruleearth-aws/docker/monitor/dashboard-sliderule-node-app-metrics.json index a05676092..058edb638 100644 --- a/targets/slideruleearth-aws/docker/monitor/dashboard-sliderule-node-app-metrics.json +++ b/targets/slideruleearth-aws/docker/monitor/dashboard-sliderule-node-app-metrics.json @@ -25,8 +25,1827 @@ "links": [], "liveNow": false, "panels": [ + { + "cacheTimeout": null, + "datasource": "Prometheus", + "description": "", + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "decimals": 1, + "mappings": [ + { + "options": { + "match": "null", + "result": { + "text": "N/A" + } + }, + "type": "special" + } + ], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "rgba(245, 54, 54, 0.9)", + "value": null + }, + { + "color": "rgba(237, 129, 40, 0.89)", + "value": 1 + }, + { + "color": "rgba(50, 172, 45, 0.97)", + "value": 2 + } + ] + }, + "unit": "s" + }, + "overrides": [] + }, + "gridPos": { + "h": 3, + "w": 4, + "x": 0, + "y": 0 + }, + "hideTimeOverride": true, + "id": 22, + "interval": null, + "links": [], + "maxDataPoints": 100, + "options": { + "colorMode": "value", + "graphMode": "none", + "justifyMode": "auto", + "orientation": "horizontal", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "text": {}, + "textMode": "auto" + }, + "pluginVersion": "8.2.1", + "targets": [ + { + "exemplar": true, + "expr": "max_over_time(atl03s{job=\"orchestrator_app\"}[1y])", + "format": "time_series", + "hide": false, + "instant": true, + "interval": "", + "intervalFactor": 1, + "legendFormat": "", + "refId": "A", + "step": 40 + } + ], + "title": "max atl03s", + "type": "stat" + }, + { + "cacheTimeout": null, + "datasource": "Prometheus", + "description": "", + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "decimals": 1, + "mappings": [ + { + "options": { + "match": "null", + "result": { + "text": "N/A" + } + }, + "type": "special" + } + ], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "rgba(245, 54, 54, 0.9)", + "value": null + }, + { + "color": "rgba(237, 129, 40, 0.89)", + "value": 1 + }, + { + "color": "rgba(50, 172, 45, 0.97)", + "value": 2 + } + ] + }, + "unit": "s" + }, + "overrides": [] + }, + "gridPos": { + "h": 3, + "w": 4, + "x": 4, + "y": 0 + }, + "hideTimeOverride": true, + "id": 21, + "interval": null, + "links": [], + "maxDataPoints": 100, + "options": { + "colorMode": "value", + "graphMode": "none", + "justifyMode": "auto", + "orientation": "horizontal", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "text": {}, + "textMode": "auto" + }, + "pluginVersion": "8.2.1", + "targets": [ + { + "exemplar": true, + "expr": "max_over_time(atl06{job=\"orchestrator_app\"}[1y])", + "format": "time_series", + "hide": false, + "instant": true, + "interval": "", + "intervalFactor": 1, + "legendFormat": "", + "refId": "A", + "step": 40 + } + ], + "title": "max atl06", + "type": "stat" + }, + { + "cacheTimeout": null, + "datasource": "Prometheus", + "description": "", + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "decimals": 1, + "mappings": [ + { + "options": { + "match": "null", + "result": { + "text": "N/A" + } + }, + "type": "special" + } + ], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "rgba(245, 54, 54, 0.9)", + "value": null + }, + { + "color": "rgba(237, 129, 40, 0.89)", + "value": 1 + }, + { + "color": "rgba(50, 172, 45, 0.97)", + "value": 2 + } + ] + }, + "unit": "s" + }, + "overrides": [] + }, + "gridPos": { + "h": 3, + "w": 4, + "x": 8, + "y": 0 + }, + "hideTimeOverride": true, + "id": 24, + "interval": null, + "links": [], + "maxDataPoints": 100, + "options": { + "colorMode": "value", + "graphMode": "none", + "justifyMode": "auto", + "orientation": "horizontal", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "text": {}, + "textMode": "auto" + }, + "pluginVersion": "8.2.1", + "targets": [ + { + "exemplar": true, + "expr": "max_over_time(atl08{job=\"orchestrator_app\"}[1y])", + "format": "time_series", + "hide": false, + "instant": true, + "interval": "", + "intervalFactor": 1, + "legendFormat": "", + "refId": "A", + "step": 40 + } + ], + "title": "max atl08", + "type": "stat" + }, + { + "cacheTimeout": null, + "datasource": "Prometheus", + "description": "", + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "decimals": 1, + "mappings": [ + { + "options": { + "match": "null", + "result": { + "text": "N/A" + } + }, + "type": "special" + } + ], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "rgba(245, 54, 54, 0.9)", + "value": null + }, + { + "color": "rgba(237, 129, 40, 0.89)", + "value": 1 + }, + { + "color": "rgba(50, 172, 45, 0.97)", + "value": 2 + } + ] + }, + "unit": "s" + }, + "overrides": [] + }, + "gridPos": { + "h": 3, + "w": 4, + "x": 12, + "y": 0 + }, + "hideTimeOverride": true, + "id": 19, + "interval": null, + "links": [], + "maxDataPoints": 100, + "options": { + "colorMode": "value", + "graphMode": "none", + "justifyMode": "auto", + "orientation": "horizontal", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "text": {}, + "textMode": "auto" + }, + "pluginVersion": "8.2.1", + "targets": [ + { + "exemplar": true, + "expr": "max_over_time(atl03sp{job=\"orchestrator_app\"}[1y])", + "format": "time_series", + "hide": false, + "instant": true, + "interval": "", + "intervalFactor": 1, + "legendFormat": "", + "refId": "A", + "step": 40 + } + ], + "title": "max atl03sp", + "type": "stat" + }, + { + "cacheTimeout": null, + "datasource": "Prometheus", + "description": "", + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "decimals": 1, + "mappings": [ + { + "options": { + "match": "null", + "result": { + "text": "N/A" + } + }, + "type": "special" + } + ], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "rgba(245, 54, 54, 0.9)", + "value": null + }, + { + "color": "rgba(237, 129, 40, 0.89)", + "value": 1 + }, + { + "color": "rgba(50, 172, 45, 0.97)", + "value": 2 + } + ] + }, + "unit": "s" + }, + "overrides": [] + }, + "gridPos": { + "h": 3, + "w": 4, + "x": 16, + "y": 0 + }, + "hideTimeOverride": true, + "id": 20, + "interval": null, + "links": [], + "maxDataPoints": 100, + "options": { + "colorMode": "value", + "graphMode": "none", + "justifyMode": "auto", + "orientation": "horizontal", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "text": {}, + "textMode": "auto" + }, + "pluginVersion": "8.2.1", + "targets": [ + { + "exemplar": true, + "expr": "max_over_time(atl06p{job=\"orchestrator_app\"}[1y])", + "format": "time_series", + "hide": false, + "instant": true, + "interval": "", + "intervalFactor": 1, + "legendFormat": "", + "refId": "A", + "step": 40 + } + ], + "title": "max atl06p", + "type": "stat" + }, + { + "cacheTimeout": null, + "datasource": "Prometheus", + "description": "", + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "decimals": 1, + "mappings": [ + { + "options": { + "match": "null", + "result": { + "text": "N/A" + } + }, + "type": "special" + } + ], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "rgba(245, 54, 54, 0.9)", + "value": null + }, + { + "color": "rgba(237, 129, 40, 0.89)", + "value": 1 + }, + { + "color": "rgba(50, 172, 45, 0.97)", + "value": 2 + } + ] + }, + "unit": "s" + }, + "overrides": [] + }, + "gridPos": { + "h": 3, + "w": 4, + "x": 20, + "y": 0 + }, + "hideTimeOverride": true, + "id": 23, + "interval": null, + "links": [], + "maxDataPoints": 100, + "options": { + "colorMode": "value", + "graphMode": "none", + "justifyMode": "auto", + "orientation": "horizontal", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "text": {}, + "textMode": "auto" + }, + "pluginVersion": "8.2.1", + "targets": [ + { + "exemplar": true, + "expr": "max_over_time(atl08p{job=\"orchestrator_app\"}[1y])", + "format": "time_series", + "hide": false, + "instant": true, + "interval": "", + "intervalFactor": 1, + "legendFormat": "", + "refId": "A", + "step": 40 + } + ], + "title": "max atl08p", + "type": "stat" + }, + { + "cacheTimeout": null, + "datasource": "Prometheus", + "description": "", + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "decimals": 0, + "mappings": [ + { + "options": { + "match": "null", + "result": { + "text": "N/A" + } + }, + "type": "special" + } + ], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "rgba(245, 54, 54, 0.9)", + "value": null + }, + { + "color": "rgba(237, 129, 40, 0.89)", + "value": 1 + }, + { + "color": "rgba(50, 172, 45, 0.97)", + "value": 2 + } + ] + }, + "unit": "none" + }, + "overrides": [] + }, + "gridPos": { + "h": 3, + "w": 4, + "x": 0, + "y": 3 + }, + "hideTimeOverride": true, + "id": 25, + "interval": null, + "links": [], + "maxDataPoints": 100, + "options": { + "colorMode": "value", + "graphMode": "none", + "justifyMode": "auto", + "orientation": "horizontal", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "text": {}, + "textMode": "auto" + }, + "pluginVersion": "8.2.1", + "targets": [ + { + "exemplar": true, + "expr": "atl03s_count{job=\"orchestrator_app\"} + atl06_count{job=\"orchestrator_app\"} + atl08_count{job=\"orchestrator_app\"}", + "format": "time_series", + "hide": false, + "instant": true, + "interval": "", + "intervalFactor": 1, + "legendFormat": "", + "refId": "A", + "step": 40 + } + ], + "title": "total atl03 granules", + "type": "stat" + }, + { + "cacheTimeout": null, + "datasource": "Prometheus", + "description": "", + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "decimals": 0, + "mappings": [ + { + "options": { + "match": "null", + "result": { + "text": "N/A" + } + }, + "type": "special" + } + ], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "rgba(245, 54, 54, 0.9)", + "value": null + }, + { + "color": "rgba(237, 129, 40, 0.89)", + "value": 1 + }, + { + "color": "rgba(50, 172, 45, 0.97)", + "value": 2 + } + ] + }, + "unit": "none" + }, + "overrides": [] + }, + "gridPos": { + "h": 3, + "w": 4, + "x": 4, + "y": 3 + }, + "hideTimeOverride": true, + "id": 26, + "interval": null, + "links": [], + "maxDataPoints": 100, + "options": { + "colorMode": "value", + "graphMode": "none", + "justifyMode": "auto", + "orientation": "horizontal", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "text": {}, + "textMode": "auto" + }, + "pluginVersion": "8.2.1", + "targets": [ + { + "exemplar": true, + "expr": "atl03sp_count{job=\"orchestrator_app\"} + atl06p_count{job=\"orchestrator_app\"} + atl08p_count{job=\"orchestrator_app\"}", + "format": "time_series", + "hide": false, + "instant": true, + "interval": "", + "intervalFactor": 1, + "legendFormat": "", + "refId": "A", + "step": 40 + } + ], + "title": "total icesat2 proxied requests", + "type": "stat" + }, + { + "cacheTimeout": null, + "datasource": "Prometheus", + "description": "", + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "decimals": 0, + "mappings": [ + { + "options": { + "match": "null", + "result": { + "text": "N/A" + } + }, + "type": "special" + } + ], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "rgba(245, 54, 54, 0.9)", + "value": null + }, + { + "color": "rgba(237, 129, 40, 0.89)", + "value": 1 + }, + { + "color": "rgba(50, 172, 45, 0.97)", + "value": 2 + } + ] + }, + "unit": "none" + }, + "overrides": [] + }, + "gridPos": { + "h": 3, + "w": 4, + "x": 8, + "y": 3 + }, + "hideTimeOverride": true, + "id": 27, + "interval": null, + "links": [], + "maxDataPoints": 100, + "options": { + "colorMode": "value", + "graphMode": "none", + "justifyMode": "auto", + "orientation": "horizontal", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "text": {}, + "textMode": "auto" + }, + "pluginVersion": "8.2.1", + "targets": [ + { + "exemplar": true, + "expr": "gedi01bp_count{job=\"orchestrator_app\"} + gedi02ap_count{job=\"orchestrator_app\"} + gedi04ap_count{job=\"orchestrator_app\"}", + "format": "time_series", + "hide": false, + "instant": true, + "interval": "", + "intervalFactor": 1, + "legendFormat": "", + "refId": "A", + "step": 40 + } + ], + "title": "total gedi proxied requests", + "type": "stat" + }, + { + "cacheTimeout": null, + "datasource": "Prometheus", + "description": "", + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "decimals": 0, + "mappings": [ + { + "options": { + "match": "null", + "result": { + "text": "N/A" + } + }, + "type": "special" + } + ], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "rgba(245, 54, 54, 0.9)", + "value": null + }, + { + "color": "rgba(237, 129, 40, 0.89)", + "value": 1 + }, + { + "color": "rgba(50, 172, 45, 0.97)", + "value": 2 + } + ] + }, + "unit": "none" + }, + "overrides": [] + }, + "gridPos": { + "h": 3, + "w": 4, + "x": 12, + "y": 3 + }, + "hideTimeOverride": true, + "id": 28, + "interval": null, + "links": [], + "maxDataPoints": 100, + "options": { + "colorMode": "value", + "graphMode": "none", + "justifyMode": "auto", + "orientation": "horizontal", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "text": {}, + "textMode": "auto" + }, + "pluginVersion": "8.2.1", + "targets": [ + { + "exemplar": true, + "expr": "gedi01b_count{job=\"orchestrator_app\"} + gedi02a_count{job=\"orchestrator_app\"} + gedi04a_count{job=\"orchestrator_app\"}", + "format": "time_series", + "hide": false, + "instant": true, + "interval": "", + "intervalFactor": 1, + "legendFormat": "", + "refId": "A", + "step": 40 + } + ], + "title": "total gedi granules", + "type": "stat" + }, + { + "cacheTimeout": null, + "datasource": "Prometheus", + "description": "", + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "decimals": 0, + "mappings": [ + { + "options": { + "match": "null", + "result": { + "text": "N/A" + } + }, + "type": "special" + } + ], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "rgba(245, 54, 54, 0.9)", + "value": null + }, + { + "color": "rgba(237, 129, 40, 0.89)", + "value": 1 + }, + { + "color": "rgba(50, 172, 45, 0.97)", + "value": 2 + } + ] + }, + "unit": "none" + }, + "overrides": [] + }, + "gridPos": { + "h": 3, + "w": 4, + "x": 16, + "y": 3 + }, + "hideTimeOverride": true, + "id": 29, + "interval": null, + "links": [], + "maxDataPoints": 100, + "options": { + "colorMode": "value", + "graphMode": "none", + "justifyMode": "auto", + "orientation": "horizontal", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "text": {}, + "textMode": "auto" + }, + "pluginVersion": "8.2.1", + "targets": [ + { + "exemplar": true, + "expr": "version_count{job=\"orchestrator_app\"}", + "format": "time_series", + "hide": false, + "instant": true, + "interval": "", + "intervalFactor": 1, + "legendFormat": "", + "refId": "A", + "step": 40 + } + ], + "title": "total version requests", + "type": "stat" + }, + { + "cacheTimeout": null, + "datasource": "Prometheus", + "description": "", + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "decimals": 0, + "mappings": [ + { + "options": { + "match": "null", + "result": { + "text": "N/A" + } + }, + "type": "special" + } + ], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "rgba(245, 54, 54, 0.9)", + "value": null + }, + { + "color": "rgba(237, 129, 40, 0.89)", + "value": 1 + }, + { + "color": "rgba(50, 172, 45, 0.97)", + "value": 2 + } + ] + }, + "unit": "none" + }, + "overrides": [] + }, + "gridPos": { + "h": 3, + "w": 4, + "x": 20, + "y": 3 + }, + "hideTimeOverride": true, + "id": 30, + "interval": null, + "links": [], + "maxDataPoints": 100, + "options": { + "colorMode": "value", + "graphMode": "none", + "justifyMode": "auto", + "orientation": "horizontal", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "text": {}, + "textMode": "auto" + }, + "pluginVersion": "8.2.1", + "targets": [ + { + "exemplar": true, + "expr": "samples_count{job=\"orchestrator_app\"} + subsets_count{job=\"orchestrator_app\"}", + "format": "time_series", + "hide": false, + "instant": true, + "interval": "", + "intervalFactor": 1, + "legendFormat": "", + "refId": "A", + "step": 40 + } + ], + "title": "total raster requests", + "type": "stat" + }, + { + "datasource": null, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 0, + "y": 6 + }, + "id": 2, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom" + }, + "tooltip": { + "mode": "single" + } + }, + "targets": [ + { + "exemplar": true, + "expr": "atl03s_count{job=\"orchestrator_app\"}", + "interval": "", + "legendFormat": "atl03s", + "refId": "A" + }, + { + "exemplar": true, + "expr": "atl06_count{job=\"orchestrator_app\"}", + "hide": false, + "interval": "", + "legendFormat": "atl06", + "refId": "B" + }, + { + "exemplar": true, + "expr": "atl08_count{job=\"orchestrator_app\"}", + "hide": false, + "interval": "", + "legendFormat": "atl08", + "refId": "C" + }, + { + "exemplar": true, + "expr": "gedi01b_count{job=\"orchestrator_app\"}", + "hide": false, + "interval": "", + "legendFormat": "gedi01b", + "refId": "D" + }, + { + "exemplar": true, + "expr": "gedi02a_count{job=\"orchestrator_app\"}", + "hide": false, + "interval": "", + "legendFormat": "gedi02a", + "refId": "E" + }, + { + "exemplar": true, + "expr": "gedi04a_count{job=\"orchestrator_app\"}", + "hide": false, + "interval": "", + "legendFormat": "gedi04a", + "refId": "F" + }, + { + "exemplar": true, + "expr": "h5_count{job=\"orchestrator_app\"}", + "hide": false, + "interval": "", + "legendFormat": "h5", + "refId": "G" + } + ], + "title": "Endpoint Counts", + "type": "timeseries" + }, + { + "datasource": null, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 12, + "y": 6 + }, + "id": 9, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom" + }, + "tooltip": { + "mode": "single" + } + }, + "targets": [ + { + "exemplar": true, + "expr": "atl03sp_count{job=\"orchestrator_app\"}", + "interval": "", + "legendFormat": "atl03sp", + "refId": "A" + }, + { + "exemplar": true, + "expr": "atl06p_count{job=\"orchestrator_app\"}", + "hide": false, + "interval": "", + "legendFormat": "atl06p", + "refId": "B" + }, + { + "exemplar": true, + "expr": "atl08p_count{job=\"orchestrator_app\"}", + "hide": false, + "interval": "", + "legendFormat": "atl08p", + "refId": "C" + }, + { + "exemplar": true, + "expr": "gedi01bp_count{job=\"orchestrator_app\"}", + "hide": false, + "interval": "", + "legendFormat": "gedi01bp", + "refId": "D" + }, + { + "exemplar": true, + "expr": "gedi02ap_count{job=\"orchestrator_app\"}", + "hide": false, + "interval": "", + "legendFormat": "gedi02ap", + "refId": "E" + }, + { + "exemplar": true, + "expr": "gedi04ap_count{job=\"orchestrator_app\"}", + "hide": false, + "interval": "", + "legendFormat": "gedi04ap", + "refId": "F" + }, + { + "exemplar": true, + "expr": "h5p_count{job=\"orchestrator_app\"}", + "hide": false, + "interval": "", + "legendFormat": "h5p", + "refId": "G" + } + ], + "title": "Proxied Endpoint Counts", + "type": "timeseries" + }, + { + "datasource": null, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 0, + "y": 14 + }, + "id": 7, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom" + }, + "tooltip": { + "mode": "single" + } + }, + "targets": [ + { + "exemplar": true, + "expr": "rate(atl03s_count{job=\"orchestrator_app\"}[1m])", + "interval": "", + "legendFormat": "atl03s", + "refId": "A" + }, + { + "exemplar": true, + "expr": "rate(atl06_count{job=\"orchestrator_app\"}[1m])", + "hide": false, + "interval": "", + "legendFormat": "atl06", + "refId": "B" + }, + { + "exemplar": true, + "expr": "rate(atl08_count{job=\"orchestrator_app\"}[1m])", + "hide": false, + "interval": "", + "legendFormat": "atl08", + "refId": "C" + }, + { + "exemplar": true, + "expr": "rate(gedi01b_count{job=\"orchestrator_app\"}[1m])", + "hide": false, + "interval": "", + "legendFormat": "gedi01b", + "refId": "D" + }, + { + "exemplar": true, + "expr": "rate(gedi02a_count{job=\"orchestrator_app\"}[1m])", + "hide": false, + "interval": "", + "legendFormat": "gedi02a", + "refId": "E" + }, + { + "exemplar": true, + "expr": "rate(gedi04a_count{job=\"orchestrator_app\"}[1m]) ", + "hide": false, + "interval": "", + "legendFormat": "gedi04a", + "refId": "F" + }, + { + "exemplar": true, + "expr": "rate(h5_count{job=\"orchestrator_app\"}[1m]) ", + "hide": false, + "interval": "", + "legendFormat": "h5", + "refId": "G" + } + ], + "title": "Endpoint Rates", + "type": "timeseries" + }, + { + "datasource": null, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 12, + "y": 14 + }, + "id": 8, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom" + }, + "tooltip": { + "mode": "single" + } + }, + "targets": [ + { + "exemplar": true, + "expr": "rate(atl03sp_count{job=\"orchestrator_app\"}[1m])", + "interval": "", + "legendFormat": "atl03sp", + "refId": "A" + }, + { + "exemplar": true, + "expr": "rate(atl06p_count{job=\"orchestrator_app\"}[1m])", + "hide": false, + "interval": "", + "legendFormat": "atl06p", + "refId": "B" + }, + { + "exemplar": true, + "expr": "rate(atl08p_count{job=\"orchestrator_app\"}[1m])", + "hide": false, + "interval": "", + "legendFormat": "atl08p", + "refId": "C" + }, + { + "exemplar": true, + "expr": "rate(gedi01bp_count{job=\"orchestrator_app\"}[1m])", + "hide": false, + "interval": "", + "legendFormat": "gedi01bp", + "refId": "D" + }, + { + "exemplar": true, + "expr": "rate(gedi02ap_count{job=\"orchestrator_app\"}[1m])", + "hide": false, + "interval": "", + "legendFormat": "gedi02ap", + "refId": "E" + }, + { + "exemplar": true, + "expr": "rate(gedi04ap_count{job=\"orchestrator_app\"}[1m]) ", + "hide": false, + "interval": "", + "legendFormat": "gedi04ap", + "refId": "F" + }, + { + "exemplar": true, + "expr": "rate(h5p_count{job=\"orchestrator_app\"}[1m]) ", + "hide": false, + "interval": "", + "legendFormat": "h5p", + "refId": "G" + } + ], + "title": "Proxied Endpoint Rates", + "type": "timeseries" + }, + { + "datasource": null, + "description": "", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 0, + "y": 22 + }, + "id": 4, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom" + }, + "tooltip": { + "mode": "single" + } + }, + "targets": [ + { + "exemplar": true, + "expr": "atl03s{job=\"orchestrator_app\"}", + "interval": "", + "legendFormat": "atl03s-sampled", + "refId": "A" + }, + { + "exemplar": true, + "expr": "atl03s_sum{job=\"orchestrator_app\"} / atl03s_count{job=\"orchestrator_app\"}", + "hide": false, + "interval": "", + "legendFormat": "atl03s-average", + "refId": "B" + } + ], + "title": "atl03s durations (seconds)", + "type": "timeseries" + }, + { + "datasource": null, + "description": "", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 12, + "y": 22 + }, + "id": 10, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom" + }, + "tooltip": { + "mode": "single" + } + }, + "targets": [ + { + "exemplar": true, + "expr": "atl03sp{job=\"orchestrator_app\"}", + "interval": "", + "legendFormat": "atl03sp-sampled", + "refId": "A" + }, + { + "exemplar": true, + "expr": "atl03sp_sum{job=\"orchestrator_app\"} / atl03sp_count{job=\"orchestrator_app\"}", + "hide": false, + "interval": "", + "legendFormat": "atl03sp-average", + "refId": "B" + } + ], + "title": "atl03sp durations (seconds)", + "type": "timeseries" + }, + { + "datasource": null, + "description": "", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 0, + "y": 30 + }, + "id": 11, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom" + }, + "tooltip": { + "mode": "single" + } + }, + "targets": [ + { + "exemplar": true, + "expr": "atl06{job=\"orchestrator_app\"}", + "interval": "", + "legendFormat": "atl06-sampled", + "refId": "A" + }, + { + "exemplar": true, + "expr": "atl06_sum{job=\"orchestrator_app\"} / atl06_count{job=\"orchestrator_app\"}", + "hide": false, + "interval": "", + "legendFormat": "atl06-average", + "refId": "B" + } + ], + "title": "atl06 durations (seconds)", + "type": "timeseries" + }, { "datasource": null, + "description": "", "fieldConfig": { "defaults": { "color": { @@ -79,11 +1898,11 @@ }, "gridPos": { "h": 8, - "w": 24, - "x": 0, - "y": 0 + "w": 12, + "x": 12, + "y": 30 }, - "id": 2, + "id": 12, "options": { "legend": { "calcs": [], @@ -97,49 +1916,116 @@ "targets": [ { "exemplar": true, - "expr": "sum by (job) (rate(SourceEndpoint_atl03s_hits{}[1m]))", + "expr": "atl06p{job=\"orchestrator_app\"}", "interval": "", - "legendFormat": "atl03s", + "legendFormat": "atl06p-sampled", "refId": "A" }, { "exemplar": true, - "expr": "sum by (job) (rate(SourceEndpoint_atl06_hits{}[1m]))", + "expr": "atl06p_sum{job=\"orchestrator_app\"} / atl06p_count{job=\"orchestrator_app\"}", "hide": false, "interval": "", - "legendFormat": "atl06", + "legendFormat": "atl06p-average", "refId": "B" + } + ], + "title": "atl06p durations (seconds)", + "type": "timeseries" + }, + { + "datasource": null, + "description": "", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } }, - { - "exemplar": true, - "expr": "sum by (job) (rate(SourceEndpoint_definition_hits{}[1m]))", - "hide": false, - "interval": "", - "legendFormat": "definition", - "refId": "C" + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 0, + "y": 38 + }, + "id": 14, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom" }, + "tooltip": { + "mode": "single" + } + }, + "targets": [ { "exemplar": true, - "expr": "sum by (job) (rate(SourceEndpoint_h5_hits{}[1m]))", - "hide": false, + "expr": "atl08{job=\"orchestrator_app\"}", "interval": "", - "legendFormat": "h5", - "refId": "D" + "legendFormat": "atl08-sampled", + "refId": "A" }, { "exemplar": true, - "expr": "sum by (job) (rate(SourceEndpoint_h5p_hits{}[1m]))", + "expr": "atl08_sum{job=\"orchestrator_app\"} / atl08_count{job=\"orchestrator_app\"}", "hide": false, "interval": "", - "legendFormat": "h5p", - "refId": "E" + "legendFormat": "atl08-average", + "refId": "B" } ], - "title": "Endpoint Rates", + "title": "atl08 durations (seconds)", "type": "timeseries" }, { "datasource": null, + "description": "", "fieldConfig": { "defaults": { "color": { @@ -191,12 +2077,12 @@ "overrides": [] }, "gridPos": { - "h": 7, - "w": 24, - "x": 0, - "y": 8 + "h": 8, + "w": 12, + "x": 12, + "y": 38 }, - "id": 4, + "id": 13, "options": { "legend": { "calcs": [], @@ -210,38 +2096,62 @@ "targets": [ { "exemplar": true, - "expr": "rate(AppServer_duration{job=\"sliderule_node_app\"}[1m])", + "expr": "atl08p{job=\"orchestrator_app\"}", "interval": "", - "legendFormat": "", + "legendFormat": "atl08p-sampled", "refId": "A" + }, + { + "exemplar": true, + "expr": "atl08p_sum{job=\"orchestrator_app\"} / atl08p_count{job=\"orchestrator_app\"}", + "hide": false, + "interval": "", + "legendFormat": "atl08p-average", + "refId": "B" } ], - "title": "Request Processing Rate", + "title": "atl08p durations (seconds)", "type": "timeseries" }, { "datasource": null, + "description": "", "fieldConfig": { "defaults": { "color": { - "mode": "thresholds" + "mode": "palette-classic" }, "custom": { "axisLabel": "", "axisPlacement": "auto", - "axisSoftMin": 0, - "fillOpacity": 80, + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, "gradientMode": "none", "hideFrom": { "legend": false, "tooltip": false, "viz": false }, - "lineWidth": 1 + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } }, "mappings": [], "thresholds": { - "mode": "percentage", + "mode": "absolute", "steps": [ { "color": "green", @@ -258,23 +2168,17 @@ }, "gridPos": { "h": 8, - "w": 24, + "w": 12, "x": 0, - "y": 15 + "y": 46 }, - "id": 6, + "id": 17, "options": { - "barWidth": 0.97, - "groupWidth": 0.7, "legend": { "calcs": [], "displayMode": "list", "placement": "bottom" }, - "orientation": "auto", - "showValue": "auto", - "stacking": "none", - "text": {}, "tooltip": { "mode": "single" } @@ -282,129 +2186,176 @@ "targets": [ { "exemplar": true, - "expr": "sum by (job) (icesat2_alaska_hits{job=\"sliderule_node_app\"})", - "hide": false, + "expr": "gedi01b{job=\"orchestrator_app\"}", "interval": "", - "legendFormat": "Alaska", - "refId": "B" + "legendFormat": "gedi01b-sampled", + "refId": "A" }, { "exemplar": true, - "expr": "sum by (job) (icesat2_canada_hits{job=\"sliderule_node_app\"})", + "expr": "gedi01b_sum{job=\"orchestrator_app\"} / gedi01b_count{job=\"orchestrator_app\"}", "hide": false, "interval": "", - "legendFormat": "Canada", - "refId": "C" + "legendFormat": "gedi01b-average", + "refId": "B" }, { "exemplar": true, - "expr": "sum by (job) (icesat2_greenland_hits{job=\"sliderule_node_app\"})", + "expr": "gedi02a{job=\"orchestrator_app\"}", "hide": false, "interval": "", - "legendFormat": "Greenland", - "refId": "D" + "legendFormat": "gedi02a-sampled", + "refId": "C" }, { "exemplar": true, - "expr": "sum by (job) (icesat2_continental_us_hits{job=\"sliderule_node_app\"})", + "expr": "gedi02a_sum{job=\"orchestrator_app\"} / gedi02a_count{job=\"orchestrator_app\"}", + "hide": false, "interval": "", - "legendFormat": "Continental US", - "refId": "A" + "legendFormat": "gedi02a-average", + "refId": "D" }, { "exemplar": true, - "expr": "sum by (job) (icesat2_central_america_hits{job=\"sliderule_node_app\"})", + "expr": "gedi04a{job=\"orchestrator_app\"}", "hide": false, "interval": "", - "legendFormat": "Central America", + "legendFormat": "gedi04a-sampled", "refId": "E" }, { "exemplar": true, - "expr": "sum by (job) (icesat2_south_america_hits{job=\"sliderule_node_app\"})", + "expr": "gedi04a_sum{job=\"orchestrator_app\"} / gedi04a_count{job=\"orchestrator_app\"}", "hide": false, "interval": "", - "legendFormat": "South America", + "legendFormat": "gedi04a-average", "refId": "F" + } + ], + "title": "gedi durations (seconds)", + "type": "timeseries" + }, + { + "datasource": null, + "description": "", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } }, - { - "exemplar": true, - "expr": "sum by (job) (icesat2_africa_hits{job=\"sliderule_node_app\"})", - "hide": false, - "interval": "", - "legendFormat": "Africa", - "refId": "G" - }, - { - "exemplar": true, - "expr": "sum by (job) (icesat2_middle_east_hits{job=\"sliderule_node_app\"})", - "hide": false, - "interval": "", - "legendFormat": "Middle East", - "refId": "H" + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 12, + "y": 46 + }, + "id": 16, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom" }, + "tooltip": { + "mode": "single" + } + }, + "targets": [ { "exemplar": true, - "expr": "sum by (job) (icesat2_europe_hits{job=\"sliderule_node_app\"})", - "hide": false, + "expr": "gedi01bp{job=\"orchestrator_app\"}", "interval": "", - "legendFormat": "Europe", - "refId": "I" + "legendFormat": "gedi01bp-sampled", + "refId": "A" }, { "exemplar": true, - "expr": "sum by (job) (icesat2_north_asia_hits{job=\"sliderule_node_app\"})", + "expr": "gedi01bp_sum{job=\"orchestrator_app\"} / gedi01bp_count{job=\"orchestrator_app\"}", "hide": false, "interval": "", - "legendFormat": "North Asia", - "refId": "J" + "legendFormat": "gedi01bp-average", + "refId": "B" }, { "exemplar": true, - "expr": "sum by (job) (icesat2_south_asia_hits{job=\"sliderule_node_app\"})", + "expr": "gedi02ap{job=\"orchestrator_app\"}", "hide": false, "interval": "", - "legendFormat": "South Asia", - "refId": "K" + "legendFormat": "gedi02ap-sampled", + "refId": "C" }, { "exemplar": true, - "expr": "sum by (job) (icesat2_oceania_hits{job=\"sliderule_node_app\"})", + "expr": "gedi02ap_sum{job=\"orchestrator_app\"} / gedi02ap_count{job=\"orchestrator_app\"}", "hide": false, "interval": "", - "legendFormat": "Oceania", - "refId": "L" + "legendFormat": "gedi02ap-average", + "refId": "D" }, { "exemplar": true, - "expr": "sum by (job) (icesat2_antarctica_hits{job=\"sliderule_node_app\"})", + "expr": "gedi04ap{job=\"orchestrator_app\"}", "hide": false, "interval": "", - "legendFormat": "Antarctica", - "refId": "M" + "legendFormat": "gedi04ap-sampled", + "refId": "E" }, { "exemplar": true, - "expr": "sum by (job) (icesat2_unknown_region_hits{job=\"sliderule_node_app\"})", + "expr": "gedi04ap_sum{job=\"orchestrator_app\"} / gedi04ap_count{job=\"orchestrator_app\"}", "hide": false, "interval": "", - "legendFormat": "Unknown", - "refId": "N" - } - ], - "title": "Request Regions", - "transformations": [ - { - "id": "reduce", - "options": { - "labelsToFields": false, - "reducers": [ - "max" - ] - } + "legendFormat": "gedi04ap-average", + "refId": "F" } ], - "type": "barchart" + "title": "gedi[p] durations (seconds)", + "type": "timeseries" } ], "schemaVersion": 31, @@ -414,7 +2365,7 @@ "list": [] }, "time": { - "from": "now-30m", + "from": "now-1h", "to": "now" }, "timepicker": {},