MXS-1220: Add old filter diagnostic interface

Added old diagnostic interface for filters.
This commit is contained in:
Markus Mäkelä 2017-04-21 12:13:46 +03:00 committed by Markus Mäkelä
parent dd68069471
commit 07175ed86b
24 changed files with 645 additions and 62 deletions

View File

@ -82,7 +82,35 @@ bool Cache::Create(const CACHE_CONFIG& config,
return pFactory != NULL;
}
json_t* Cache::show() const
void Cache::show(DCB* pDcb) const
{
bool showed = false;
json_t* pInfo = get_info(INFO_ALL);
if (pInfo)
{
size_t flags = JSON_PRESERVE_ORDER;
size_t indent = 2;
char* z = json_dumps(pInfo, JSON_PRESERVE_ORDER | JSON_INDENT(indent));
if (z)
{
dcb_printf(pDcb, "%s\n", z);
free(z);
showed = true;
}
json_decref(pInfo);
}
if (!showed)
{
// So as not to upset anyone expecting a JSON object.
dcb_printf(pDcb, "{\n}\n");
}
}
json_t* Cache::show_json() const
{
return get_info(INFO_ALL);
}

View File

@ -40,7 +40,8 @@ public:
virtual ~Cache();
json_t* show() const;
void show(DCB* pDcb) const;
json_t* show_json() const;
const CACHE_CONFIG& config() const
{

View File

@ -98,15 +98,7 @@ bool cache_command_show(const MODULECMD_ARG* pArgs)
ss_dassert(pFilterDef);
CacheFilter* pFilter = reinterpret_cast<CacheFilter*>(filter_def_get_instance(pFilterDef));
json_t* json = NULL;
MXS_EXCEPTION_GUARD(json = pFilter->cache().show());
if (json)
{
string str = mxs::json_dump(json, JSON_INDENT(4));
dcb_printf(pDcb, "%s\n", str.c_str());
}
MXS_EXCEPTION_GUARD(pFilter->cache().show(pDcb));
return true;
}
@ -306,9 +298,15 @@ CacheFilterSession* CacheFilter::newSession(MXS_SESSION* pSession)
}
// static
json_t* CacheFilter::diagnostics() const
void CacheFilter::diagnostics(DCB* pDcb)
{
return m_sCache->show();
m_sCache->show(pDcb);
}
// static
json_t* CacheFilter::diagnostics_json() const
{
return m_sCache->show_json();
}
uint64_t CacheFilter::getCapabilities()

View File

@ -37,7 +37,8 @@ public:
CacheFilterSession* newSession(MXS_SESSION* pSession);
json_t* diagnostics() const;
void diagnostics(DCB* pDcb);
json_t* diagnostics_json() const;
uint64_t getCapabilities();

View File

@ -447,7 +447,16 @@ int CacheFilterSession::clientReply(GWBUF* pData)
return rv;
}
json_t* CacheFilterSession::diagnostics() const
void CacheFilterSession::diagnostics(DCB* pDcb)
{
// Not printing anything. Session of the same instance share the same cache, in
// which case the same information would be printed once per session, or all
// threads (but not sessions) share the same cache, in which case the output
// would be nonsensical.
dcb_printf(pDcb, "\n");
}
json_t* CacheFilterSession::diagnostics_json() const
{
// Not printing anything. Session of the same instance share the same cache, in
// which case the same information would be printed once per session, or all

View File

@ -83,7 +83,12 @@ public:
/**
* Print diagnostics of the session cache.
*/
json_t* diagnostics() const;
void diagnostics(DCB *dcb);
/**
* Print diagnostics of the session cache.
*/
json_t* diagnostics_json() const;
private:
int handle_expecting_fields();

View File

@ -55,7 +55,8 @@ static void closeSession(MXS_FILTER *instance, MXS_FILTER_SESSION *session);
static void freeSession(MXS_FILTER *instance, MXS_FILTER_SESSION *session);
static void setDownstream(MXS_FILTER *instance, MXS_FILTER_SESSION *fsession, MXS_DOWNSTREAM *downstream);
static int routeQuery(MXS_FILTER *instance, MXS_FILTER_SESSION *fsession, GWBUF *queue);
static json_t* diagnostic(const MXS_FILTER *instance, const MXS_FILTER_SESSION *fsession);
static void diagnostic(MXS_FILTER *instance, MXS_FILTER_SESSION *fsession, DCB *dcb);
static json_t* diagnostic_json(const MXS_FILTER *instance, const MXS_FILTER_SESSION *fsession);
static uint64_t getCapabilities(MXS_FILTER* instance);
#define CCR_DEFAULT_TIME "60"
@ -123,6 +124,7 @@ MXS_MODULE* MXS_CREATE_MODULE()
routeQuery,
NULL, // No clientReply
diagnostic,
diagnostic_json,
getCapabilities,
NULL, // No destroyInstance
};
@ -358,7 +360,42 @@ routeQuery(MXS_FILTER *instance, MXS_FILTER_SESSION *session, GWBUF *queue)
* @param fsession Filter session, may be NULL
* @param dcb The DCB for diagnostic output
*/
static json_t* diagnostic(const MXS_FILTER *instance, const MXS_FILTER_SESSION *fsession)
static void
diagnostic(MXS_FILTER *instance, MXS_FILTER_SESSION *fsession, DCB *dcb)
{
CCR_INSTANCE *my_instance = (CCR_INSTANCE *)instance;
dcb_printf(dcb, "Configuration:\n\tCount: %d\n", my_instance->count);
dcb_printf(dcb, "\tTime: %d seconds\n", my_instance->time);
if (my_instance->match)
{
dcb_printf(dcb, "\tMatch regex: %s\n", my_instance->match);
}
if (my_instance->nomatch)
{
dcb_printf(dcb, "\tExclude regex: %s\n", my_instance->nomatch);
}
dcb_printf(dcb, "\nStatistics:\n");
dcb_printf(dcb, "\tNo. of data modifications: %d\n", my_instance->stats.n_modified);
dcb_printf(dcb, "\tNo. of hints added based on count: %d\n", my_instance->stats.n_add_count);
dcb_printf(dcb, "\tNo. of hints added based on time: %d\n", my_instance->stats.n_add_time);
}
/**
* Diagnostics routine
*
* If fsession is NULL then print diagnostics on the filter
* instance as a whole, otherwise print diagnostics for the
* particular session.
*
* @param instance The filter instance
* @param fsession Filter session, may be NULL
* @param dcb The DCB for diagnostic output
*/
static json_t* diagnostic_json(const MXS_FILTER *instance, const MXS_FILTER_SESSION *fsession)
{
CCR_INSTANCE *my_instance = (CCR_INSTANCE *)instance;
json_t* rval = json_object();

View File

@ -101,7 +101,8 @@ static void closeSession(MXS_FILTER *instance, MXS_FILTER_SESSION *session);
static void freeSession(MXS_FILTER *instance, MXS_FILTER_SESSION *session);
static void setDownstream(MXS_FILTER *instance, MXS_FILTER_SESSION *fsession, MXS_DOWNSTREAM *downstream);
static int routeQuery(MXS_FILTER *instance, MXS_FILTER_SESSION *fsession, GWBUF *queue);
static json_t* diagnostic(const MXS_FILTER *instance, const MXS_FILTER_SESSION *fsession);
static void diagnostic(MXS_FILTER *instance, MXS_FILTER_SESSION *fsession, DCB *dcb);
static json_t* diagnostic_json(const MXS_FILTER *instance, const MXS_FILTER_SESSION *fsession);
static uint64_t getCapabilities(MXS_FILTER* instance);
/**
@ -274,6 +275,21 @@ static void rule_free_all(RULE* rule);
static bool process_rule_file(const char* filename, RULE** rules, HASHTABLE **users);
bool replace_rules(FW_INSTANCE* instance);
static void print_rule(RULE *rules, char *dest)
{
int type = 0;
if ((int)rules->type > 0 && (int)rules->type < rule_names_len)
{
type = (int)rules->type;
}
sprintf(dest, "%s, %s, %d",
rules->name,
rule_names[type],
rules->times_matched);
}
static json_t* rule_to_json(RULE *rule)
{
int type = 0;
@ -766,6 +782,8 @@ bool dbfw_show_rules(const MODULECMD_ARG *argv)
MXS_FILTER_DEF *filter = argv->argv[1].value.filter;
FW_INSTANCE *inst = (FW_INSTANCE*)filter_def_get_instance(filter);
dcb_printf(dcb, "Rule, Type, Times Matched\n");
if (!thr_rules || !thr_users)
{
if (!replace_rules(inst))
@ -774,18 +792,11 @@ bool dbfw_show_rules(const MODULECMD_ARG *argv)
}
}
json_t* json = rules_to_json(thr_rules);
if (json)
for (RULE *rule = thr_rules; rule; rule = rule->next)
{
char* dump = json_dumps(json, JSON_INDENT(4));
if (dump)
{
dcb_printf(dcb, "%s\n", dump);
}
MXS_FREE(dump);
char buf[strlen(rule->name) + 200]; // Some extra space
print_rule(rule, buf);
dcb_printf(dcb, "%s\n", buf);
}
return true;
@ -836,6 +847,7 @@ MXS_MODULE* MXS_CREATE_MODULE()
routeQuery,
NULL, // No clientReply
diagnostic,
diagnostic_json,
getCapabilities,
NULL, // No destroyInstance
};
@ -2503,8 +2515,33 @@ routeQuery(MXS_FILTER *instance, MXS_FILTER_SESSION *session, GWBUF *queue)
* @param fsession Filter session, may be NULL
* @param dcb The DCB for diagnostic output
*/
static json_t*
diagnostic(const MXS_FILTER *instance, const MXS_FILTER_SESSION *fsession)
static void
diagnostic(MXS_FILTER *instance, MXS_FILTER_SESSION *fsession, DCB *dcb)
{
FW_INSTANCE *my_instance = (FW_INSTANCE *) instance;
dcb_printf(dcb, "Firewall Filter\n");
dcb_printf(dcb, "Rule, Type, Times Matched\n");
for (RULE *rule = thr_rules; rule; rule = rule->next)
{
char buf[strlen(rule->name) + 200];
print_rule(rule, buf);
dcb_printf(dcb, "%s\n", buf);
}
}
/**
* Diagnostics routine
*
* Prints the connection details and the names of the exchange,
* queue and the routing key.
*
* @param instance The filter instance
* @param fsession Filter session, may be NULL
* @param dcb The DCB for diagnostic output
*/
static json_t* diagnostic_json(const MXS_FILTER *instance, const MXS_FILTER_SESSION *fsession)
{
return rules_to_json(thr_rules);
}

View File

@ -32,7 +32,8 @@ static void closeSession(MXS_FILTER *instance, MXS_FILTER_SESSION *session);
static void freeSession(MXS_FILTER *instance, MXS_FILTER_SESSION *session);
static void setDownstream(MXS_FILTER *instance, MXS_FILTER_SESSION *fsession, MXS_DOWNSTREAM *downstream);
static int routeQuery(MXS_FILTER *instance, MXS_FILTER_SESSION *fsession, GWBUF *queue);
static json_t* diagnostic(const MXS_FILTER *instance, const MXS_FILTER_SESSION *fsession);
static void diagnostic(MXS_FILTER *instance, MXS_FILTER_SESSION *fsession, DCB *dcb);
static json_t* diagnostic_json(const MXS_FILTER *instance, const MXS_FILTER_SESSION *fsession);
static uint64_t getCapabilities(MXS_FILTER* instance);
/**
@ -56,6 +57,7 @@ MXS_MODULE* MXS_CREATE_MODULE()
routeQuery,
NULL, // No clientReply
diagnostic,
diagnostic_json,
getCapabilities,
NULL, // No destroyInstance
};
@ -215,6 +217,25 @@ routeQuery(MXS_FILTER *instance, MXS_FILTER_SESSION *session, GWBUF *queue)
my_session->down.session, queue);
}
/**
* Diagnostics routine
*
* If fsession is NULL then print diagnostics on the filter
* instance as a whole, otherwise print diagnostics for the
* particular session.
*
* @param instance The filter instance
* @param fsession Filter session, may be NULL
* @param dcb The DCB for diagnostic output
*/
static void
diagnostic(MXS_FILTER *instance, MXS_FILTER_SESSION *fsession, DCB *dcb)
{
HINT_INSTANCE *my_instance = (HINT_INSTANCE *)instance;
HINT_SESSION *my_session = (HINT_SESSION *)fsession;
}
/**
* Diagnostics routine
*
@ -222,7 +243,7 @@ routeQuery(MXS_FILTER *instance, MXS_FILTER_SESSION *session, GWBUF *queue)
* @param fsession Filter session, may be NULL
*/
static json_t*
diagnostic(const MXS_FILTER *instance, const MXS_FILTER_SESSION *fsession)
diagnostic_json(const MXS_FILTER *instance, const MXS_FILTER_SESSION *fsession)
{
return NULL;
}

View File

@ -37,7 +37,8 @@ static void freeSession(MXS_FILTER *instance, MXS_FILTER_SESSION *session);
static void setDownstream(MXS_FILTER *instance, MXS_FILTER_SESSION *fsession, MXS_DOWNSTREAM *downstream);
static void setUpstream(MXS_FILTER *instance, MXS_FILTER_SESSION *session, MXS_UPSTREAM *upstream);
static int32_t routeQuery(MXS_FILTER *instance, MXS_FILTER_SESSION *fsession, GWBUF *queue);
static json_t* diagnostic(const MXS_FILTER *instance, const MXS_FILTER_SESSION *fsession);
static void diagnostic(MXS_FILTER *instance, MXS_FILTER_SESSION *fsession, DCB *dcb);
static json_t* diagnostic_json(const MXS_FILTER *instance, const MXS_FILTER_SESSION *fsession);
static uint64_t getCapabilities(MXS_FILTER *instance);
static int32_t clientReply(MXS_FILTER* instance, MXS_FILTER_SESSION *session, GWBUF *reply);
static bool extract_insert_target(GWBUF *buffer, char* target, int len);
@ -99,6 +100,7 @@ MXS_MODULE* MXS_CREATE_MODULE()
routeQuery,
clientReply,
diagnostic,
diagnostic_json,
getCapabilities,
NULL,
};
@ -497,8 +499,33 @@ static int32_t clientReply(MXS_FILTER* instance, MXS_FILTER_SESSION *session, GW
*
* @param instance The filter instance
* @param fsession Filter session, may be NULL
* @param dcb The DCB for diagnostic output
*/
static json_t* diagnostic(const MXS_FILTER *instance, const MXS_FILTER_SESSION *fsession)
static void diagnostic(MXS_FILTER *instance, MXS_FILTER_SESSION *fsession, DCB *dcb)
{
DS_INSTANCE *my_instance = (DS_INSTANCE *) instance;
if (my_instance->source)
{
dcb_printf(dcb, "\t\tReplacement limited to connections from %s\n", my_instance->source);
}
if (my_instance->user)
{
dcb_printf(dcb, "\t\tReplacement limit to user %s\n", my_instance->user);
}
}
/**
* Diagnostics routine
*
* If fsession is NULL then print diagnostics on the filter
* instance as a whole, otherwise print diagnostics for the
* particular session.
*
* @param instance The filter instance
* @param fsession Filter session, may be NULL
*/
static json_t* diagnostic_json(const MXS_FILTER *instance, const MXS_FILTER_SESSION *fsession)
{
DS_INSTANCE *my_instance = (DS_INSTANCE*)instance;

View File

@ -63,7 +63,8 @@ static void setDownstream(MXS_FILTER *instance, MXS_FILTER_SESSION *fsession, M
static void setUpstream(MXS_FILTER *instance, MXS_FILTER_SESSION *fsession, MXS_UPSTREAM *upstream);
static int32_t routeQuery(MXS_FILTER *instance, MXS_FILTER_SESSION *fsession, GWBUF *queue);
static int32_t clientReply(MXS_FILTER *instance, MXS_FILTER_SESSION *fsession, GWBUF *queue);
static json_t* diagnostic(const MXS_FILTER *instance, const MXS_FILTER_SESSION *fsession);
static void diagnostic(MXS_FILTER *instance, MXS_FILTER_SESSION *fsession, DCB *dcb);
static json_t* diagnostic_json(const MXS_FILTER *instance, const MXS_FILTER_SESSION *fsession);
static uint64_t getCapabilities(MXS_FILTER *instance);
/**
@ -87,6 +88,7 @@ MXS_MODULE* MXS_CREATE_MODULE()
routeQuery,
clientReply,
diagnostic,
diagnostic_json,
getCapabilities,
NULL, // No destroyInstance
};
@ -615,6 +617,55 @@ static int32_t routeQuery(MXS_FILTER *instance, MXS_FILTER_SESSION *session, GWB
return rc;
}
/**
* Diagnostics routine.
*
* This will call the matching diagnostics entry point in the Lua script. If the
* Lua function returns a string, it will be printed to the client DCB.
* @param instance The filter instance
* @param fsession Filter session, may be NULL
* @param dcb The DCB for diagnostic output
*/
static void diagnostic(MXS_FILTER *instance, MXS_FILTER_SESSION *fsession, DCB *dcb)
{
LUA_INSTANCE *my_instance = (LUA_INSTANCE *) instance;
if (my_instance)
{
if (my_instance->global_lua_state)
{
spinlock_acquire(&my_instance->lock);
lua_getglobal(my_instance->global_lua_state, "diagnostic");
if (lua_pcall(my_instance->global_lua_state, 0, 1, 0) == 0)
{
lua_gettop(my_instance->global_lua_state);
if (lua_isstring(my_instance->global_lua_state, -1))
{
dcb_printf(dcb, "%s", lua_tostring(my_instance->global_lua_state, -1));
dcb_printf(dcb, "\n");
}
}
else
{
dcb_printf(dcb, "Global scope call to 'diagnostic' failed: '%s'.\n",
lua_tostring(my_instance->global_lua_state, -1));
lua_pop(my_instance->global_lua_state, -1);
}
spinlock_release(&my_instance->lock);
}
if (my_instance->global_script)
{
dcb_printf(dcb, "Global script: %s\n", my_instance->global_script);
}
if (my_instance->session_script)
{
dcb_printf(dcb, "Session script: %s\n", my_instance->session_script);
}
}
}
/**
* Diagnostics routine.
*
@ -624,7 +675,7 @@ static int32_t routeQuery(MXS_FILTER *instance, MXS_FILTER_SESSION *session, GWB
* @param instance The filter instance
* @param fsession Filter session, may be NULL
*/
static json_t* diagnostic(const MXS_FILTER *instance, const MXS_FILTER_SESSION *fsession)
static json_t* diagnostic_json(const MXS_FILTER *instance, const MXS_FILTER_SESSION *fsession)
{
LUA_INSTANCE *my_instance = (LUA_INSTANCE *)instance;
json_t* rval = json_object();

View File

@ -138,7 +138,13 @@ MaskingFilterSession* MaskingFilter::newSession(MXS_SESSION* pSession)
}
// static
json_t* MaskingFilter::diagnostics() const
void MaskingFilter::diagnostics(DCB* pDcb)
{
dcb_printf(pDcb, "Hello, World!\n");
}
// static
json_t* MaskingFilter::diagnostics_json() const
{
return NULL;
}

View File

@ -33,7 +33,8 @@ public:
MaskingFilterSession* newSession(MXS_SESSION* pSession);
json_t* diagnostics() const;
void diagnostics(DCB* pDcb);
json_t* diagnostics_json() const;
uint64_t getCapabilities();

View File

@ -67,7 +67,10 @@ static int routeQuery(MXS_FILTER *instance,
static int clientReply(MXS_FILTER *instance,
MXS_FILTER_SESSION *sdata,
GWBUF *queue);
static json_t* diagnostics(const MXS_FILTER *instance,
static void diagnostics(MXS_FILTER *instance,
MXS_FILTER_SESSION *sdata,
DCB *dcb);
static json_t* diagnostics_json(const MXS_FILTER *instance,
const MXS_FILTER_SESSION *sdata);
static uint64_t getCapabilities(MXS_FILTER *instance);
@ -106,6 +109,7 @@ MXS_MODULE* MXS_CREATE_MODULE()
routeQuery,
clientReply,
diagnostics,
diagnostics_json,
getCapabilities,
NULL, // No destroyInstance
};
@ -487,12 +491,29 @@ static int clientReply(MXS_FILTER *instance,
* @param fsession Filter session, may be NULL
* @param dcb The DCB for diagnostic output
*/
static json_t* diagnostics(const MXS_FILTER *instance, const MXS_FILTER_SESSION *sdata)
static void diagnostics(MXS_FILTER *instance, MXS_FILTER_SESSION *sdata, DCB *dcb)
{
MAXROWS_INSTANCE *cinstance = (MAXROWS_INSTANCE*)instance;
MAXROWS_SESSION_DATA *csdata = (MAXROWS_SESSION_DATA*)sdata;
dcb_printf(dcb, "Maxrows filter is working\n");
}
/**
* Diagnostics routine
*
* If csdata is NULL then print diagnostics on the instance as a whole,
* otherwise print diagnostics for the particular session.
*
* @param instance The filter instance
* @param fsession Filter session, may be NULL
* @param dcb The DCB for diagnostic output
*/
static json_t* diagnostics_json(const MXS_FILTER *instance, const MXS_FILTER_SESSION *sdata)
{
return NULL;
}
/**
* Capability routine.
*

View File

@ -94,7 +94,8 @@ static void setDownstream(MXS_FILTER *instance, MXS_FILTER_SESSION *fsession, MX
static void setUpstream(MXS_FILTER *instance, MXS_FILTER_SESSION *fsession, MXS_UPSTREAM *upstream);
static int routeQuery(MXS_FILTER *instance, MXS_FILTER_SESSION *fsession, GWBUF *queue);
static int clientReply(MXS_FILTER *instance, MXS_FILTER_SESSION *fsession, GWBUF *queue);
static json_t* diagnostic(const MXS_FILTER *instance, const MXS_FILTER_SESSION *fsession);
static void diagnostic(MXS_FILTER *instance, MXS_FILTER_SESSION *fsession, DCB *dcb);
static json_t* diagnostic_json(const MXS_FILTER *instance, const MXS_FILTER_SESSION *fsession);
static uint64_t getCapabilities(MXS_FILTER *instance);
/**
@ -270,6 +271,7 @@ MXS_MODULE* MXS_CREATE_MODULE()
routeQuery,
clientReply,
diagnostic,
diagnostic_json,
getCapabilities,
NULL, // No destroyInstance
};
@ -1474,6 +1476,38 @@ static int clientReply(MXS_FILTER* instance, MXS_FILTER_SESSION *session, GWBUF
my_session->up.session, reply);
}
/**
* Diagnostics routine
*
* Prints the connection details and the names of the exchange,
* queue and the routing key.
*
* @param instance The filter instance
* @param fsession Filter session, may be NULL
* @param dcb The DCB for diagnostic output
*/
static void
diagnostic(MXS_FILTER *instance, MXS_FILTER_SESSION *fsession, DCB *dcb)
{
MQ_INSTANCE *my_instance = (MQ_INSTANCE *) instance;
if (my_instance)
{
dcb_printf(dcb, "Connecting to [%s]:%d as '%s'.\nVhost: %s\tExchange: %s\nKey: %s\tQueue: %s\n\n",
my_instance->hostname, my_instance->port,
my_instance->username,
my_instance->vhost, my_instance->exchange,
my_instance->key, my_instance->queue
);
dcb_printf(dcb, "%-16s%-16s%-16s\n",
"Messages", "Queued", "Sent");
dcb_printf(dcb, "%-16d%-16d%-16d\n",
my_instance->stats.n_msg,
my_instance->stats.n_queued,
my_instance->stats.n_sent);
}
}
/**
* Diagnostics routine
*
@ -1484,7 +1518,7 @@ static int clientReply(MXS_FILTER* instance, MXS_FILTER_SESSION *session, GWBUF
* @param fsession Filter session, may be NULL
*/
static json_t*
diagnostic(const MXS_FILTER *instance, const MXS_FILTER_SESSION *fsession)
diagnostic_json(const MXS_FILTER *instance, const MXS_FILTER_SESSION *fsession)
{
MQ_INSTANCE *my_instance = (MQ_INSTANCE*)instance;
json_t* rval = json_object();

View File

@ -311,10 +311,27 @@ RegexHintFilter::create(const char* name, char** options, MXS_CONFIG_PARAMETER*
*
* @param dcb The DCB for diagnostic output
*/
json_t* RegexHintFSession::diagnostics() const
void RegexHintFSession::diagnostics(DCB* dcb)
{
json_t* rval = m_fil_inst.diagnostics(); /* Print overall diagnostics */
m_fil_inst.diagnostics(dcb); /* Print overall diagnostics */
dcb_printf(dcb, "\t\tNo. of queries diverted by filter (session): %d\n",
m_n_diverted);
dcb_printf(dcb, "\t\tNo. of queries not diverted by filter (session): %d\n",
m_n_undiverted);
}
/**
* Diagnostics routine
*
* Print diagnostics on the filter instance as a whole + session-specific info.
*
* @param dcb The DCB for diagnostic output
*/
json_t* RegexHintFSession::diagnostics_json() const
{
json_t* rval = m_fil_inst.diagnostics_json(); /* Print overall diagnostics */
json_object_set_new(rval, "session_queries_diverted", json_integer(m_n_diverted));
json_object_set_new(rval, "session_queries_undiverted", json_integer(m_n_undiverted));
@ -329,7 +346,50 @@ json_t* RegexHintFSession::diagnostics() const
*
* @param dcb The DCB for diagnostic output
*/
json_t* RegexHintFilter::diagnostics() const
void RegexHintFilter::diagnostics(DCB* dcb)
{
if (m_mapping.size() > 0)
{
dcb_printf(dcb, "\t\tMatches and routes:\n");
}
for (unsigned int i = 0; i < m_mapping.size(); i++)
{
dcb_printf(dcb, "\t\t\t/%s/ -> ",
m_mapping[i].m_match.c_str());
dcb_printf(dcb, "%s", m_mapping[i].m_targets[0].c_str());
for (unsigned int j = 1; j < m_mapping[i].m_targets.size(); j++)
{
dcb_printf(dcb, ", %s", m_mapping[i].m_targets[j].c_str());
}
dcb_printf(dcb, "\n");
}
dcb_printf(dcb, "\t\tTotal no. of queries diverted by filter (approx.): %d\n",
m_total_diverted);
dcb_printf(dcb, "\t\tTotal no. of queries not diverted by filter (approx.): %d\n",
m_total_undiverted);
if (m_source)
{
dcb_printf(dcb,
"\t\tReplacement limited to connections from %s\n",
m_source->m_address.c_str());
}
if (m_user.length())
{
dcb_printf(dcb,
"\t\tReplacement limit to user %s\n",
m_user.c_str());
}
}
/**
* Diagnostics routine
*
* Print diagnostics on the filter instance as a whole.
*
* @param dcb The DCB for diagnostic output
*/
json_t* RegexHintFilter::diagnostics_json() const
{
json_t* rval = json_object();

View File

@ -57,7 +57,8 @@ public:
static RegexHintFilter* create(const char* zName, char** pzOptions,
MXS_CONFIG_PARAMETER* ppParams);
RegexHintFSession* newSession(MXS_SESSION *session);
json_t* diagnostics() const;
void diagnostics(DCB* dcb);
json_t* diagnostics_json() const;
uint64_t getCapabilities();
const RegexToServers* find_servers(char* sql, int sql_len, pcre2_match_data* mdata);
@ -86,7 +87,8 @@ public:
pcre2_match_data* md);
~RegexHintFSession();
json_t* diagnostics() const;
void diagnostics(DCB* pDcb);
json_t* diagnostics_json() const;
int routeQuery(GWBUF* buffer);
};

View File

@ -142,7 +142,13 @@ NullFilterSession* NullFilter::newSession(MXS_SESSION* pSession)
}
// static
json_t* NullFilter::diagnostics() const
void NullFilter::diagnostics(DCB* pDcb)
{
dcb_printf(pDcb, "Hello, World!\n");
}
// static
json_t* NullFilter::diagnostics_json() const
{
return NULL;
}

View File

@ -24,7 +24,8 @@ public:
NullFilterSession* newSession(MXS_SESSION* pSession);
json_t* diagnostics() const;
void diagnostics(DCB* pDcb);
json_t* diagnostics_json() const;
uint64_t getCapabilities();

View File

@ -81,7 +81,8 @@ static void closeSession(MXS_FILTER *instance, MXS_FILTER_SESSION *session);
static void freeSession(MXS_FILTER *instance, MXS_FILTER_SESSION *session);
static void setDownstream(MXS_FILTER *instance, MXS_FILTER_SESSION *fsession, MXS_DOWNSTREAM *downstream);
static int routeQuery(MXS_FILTER *instance, MXS_FILTER_SESSION *fsession, GWBUF *queue);
static json_t* diagnostic(const MXS_FILTER *instance, const MXS_FILTER_SESSION *fsession);
static void diagnostic(MXS_FILTER *instance, MXS_FILTER_SESSION *fsession, DCB *dcb);
static json_t* diagnostic_json(const MXS_FILTER *instance, const MXS_FILTER_SESSION *fsession);
static uint64_t getCapabilities(MXS_FILTER* instance);
/**
@ -182,6 +183,7 @@ MXS_MODULE* MXS_CREATE_MODULE()
routeQuery,
NULL, // No client reply
diagnostic,
diagnostic_json,
getCapabilities,
NULL, // No destroyInstance
};
@ -578,8 +580,52 @@ routeQuery(MXS_FILTER *instance, MXS_FILTER_SESSION *session, GWBUF *queue)
*
* @param instance The filter instance
* @param fsession Filter session, may be NULL
* @param dcb The DCB for diagnostic output
*/
static json_t* diagnostic(const MXS_FILTER *instance, const MXS_FILTER_SESSION *fsession)
static void
diagnostic(MXS_FILTER *instance, MXS_FILTER_SESSION *fsession, DCB *dcb)
{
QLA_INSTANCE *my_instance = (QLA_INSTANCE *) instance;
QLA_SESSION *my_session = (QLA_SESSION *) fsession;
if (my_session)
{
dcb_printf(dcb, "\t\tLogging to file %s.\n",
my_session->filename);
}
if (my_instance->source)
{
dcb_printf(dcb, "\t\tLimit logging to connections from %s\n",
my_instance->source);
}
if (my_instance->user_name)
{
dcb_printf(dcb, "\t\tLimit logging to user %s\n",
my_instance->user_name);
}
if (my_instance->match)
{
dcb_printf(dcb, "\t\tInclude queries that match %s\n",
my_instance->match);
}
if (my_instance->nomatch)
{
dcb_printf(dcb, "\t\tExclude queries that match %s\n",
my_instance->nomatch);
}
}
/**
* Diagnostics routine
*
* If fsession is NULL then print diagnostics on the filter
* instance as a whole, otherwise print diagnostics for the
* particular session.
*
* @param instance The filter instance
* @param fsession Filter session, may be NULL
*/
static json_t* diagnostic_json(const MXS_FILTER *instance, const MXS_FILTER_SESSION *fsession)
{
QLA_INSTANCE *my_instance = (QLA_INSTANCE*)instance;
QLA_SESSION *my_session = (QLA_SESSION*)fsession;

View File

@ -48,7 +48,8 @@ static void closeSession(MXS_FILTER *instance, MXS_FILTER_SESSION *session);
static void freeSession(MXS_FILTER *instance, MXS_FILTER_SESSION *session);
static void setDownstream(MXS_FILTER *instance, MXS_FILTER_SESSION *fsession, MXS_DOWNSTREAM *downstream);
static int routeQuery(MXS_FILTER *instance, MXS_FILTER_SESSION *fsession, GWBUF *queue);
static json_t* diagnostic(const MXS_FILTER *instance, const MXS_FILTER_SESSION *fsession);
static void diagnostic(MXS_FILTER *instance, MXS_FILTER_SESSION *fsession, DCB *dcb);
static json_t* diagnostic_json(const MXS_FILTER *instance, const MXS_FILTER_SESSION *fsession);
static uint64_t getCapabilities(MXS_FILTER* instance);
static char *regex_replace(const char *sql, pcre2_code *re, pcre2_match_data *study,
@ -112,6 +113,7 @@ MXS_MODULE* MXS_CREATE_MODULE()
routeQuery,
NULL, // No clientReply
diagnostic,
diagnostic_json,
getCapabilities,
NULL, // No destroyInstance
};
@ -376,8 +378,48 @@ routeQuery(MXS_FILTER *instance, MXS_FILTER_SESSION *session, GWBUF *queue)
*
* @param instance The filter instance
* @param fsession Filter session, may be NULL
* @param dcb The DCB for diagnostic output
*/
static json_t* diagnostic(const MXS_FILTER *instance, const MXS_FILTER_SESSION *fsession)
static void
diagnostic(MXS_FILTER *instance, MXS_FILTER_SESSION *fsession, DCB *dcb)
{
REGEX_INSTANCE *my_instance = (REGEX_INSTANCE *) instance;
REGEX_SESSION *my_session = (REGEX_SESSION *) fsession;
dcb_printf(dcb, "\t\tSearch and replace: s/%s/%s/\n",
my_instance->match, my_instance->replace);
if (my_session)
{
dcb_printf(dcb, "\t\tNo. of queries unaltered by filter: %d\n",
my_session->no_change);
dcb_printf(dcb, "\t\tNo. of queries altered by filter: %d\n",
my_session->replacements);
}
if (my_instance->source)
{
dcb_printf(dcb,
"\t\tReplacement limited to connections from %s\n",
my_instance->source);
}
if (my_instance->user)
{
dcb_printf(dcb,
"\t\tReplacement limit to user %s\n",
my_instance->user);
}
}
/**
* Diagnostics routine
*
* If fsession is NULL then print diagnostics on the filter
* instance as a whole, otherwise print diagnostics for the
* particular session.
*
* @param instance The filter instance
* @param fsession Filter session, may be NULL
*/
static json_t* diagnostic_json(const MXS_FILTER *instance, const MXS_FILTER_SESSION *fsession)
{
REGEX_INSTANCE *my_instance = (REGEX_INSTANCE*)instance;
REGEX_SESSION *my_session = (REGEX_SESSION*)fsession;

View File

@ -106,7 +106,8 @@ static void setDownstream(MXS_FILTER *instance, MXS_FILTER_SESSION *fsession, MX
static void setUpstream(MXS_FILTER *instance, MXS_FILTER_SESSION *fsession, MXS_UPSTREAM *upstream);
static int routeQuery(MXS_FILTER *instance, MXS_FILTER_SESSION *fsession, GWBUF *queue);
static int clientReply(MXS_FILTER *instance, MXS_FILTER_SESSION *fsession, GWBUF *queue);
static json_t* diagnostic(const MXS_FILTER *instance, const MXS_FILTER_SESSION *fsession);
static void diagnostic(MXS_FILTER *instance, MXS_FILTER_SESSION *fsession, DCB *dcb);
static json_t* diagnostic_json(const MXS_FILTER *instance, const MXS_FILTER_SESSION *fsession);
static uint64_t getCapabilities(MXS_FILTER* instance);
/**
@ -315,6 +316,7 @@ MXS_MODULE* MXS_CREATE_MODULE()
routeQuery,
clientReply,
diagnostic,
diagnostic_json,
getCapabilities,
NULL, // No destroyInstance
};
@ -697,8 +699,56 @@ clientReply(MXS_FILTER* instance, MXS_FILTER_SESSION *session, GWBUF *reply)
*
* @param instance The filter instance
* @param fsession Filter session, may be NULL
* @param dcb The DCB for diagnostic output
*/
static json_t* diagnostic(const MXS_FILTER *instance, const MXS_FILTER_SESSION *fsession)
static void
diagnostic(MXS_FILTER *instance, MXS_FILTER_SESSION *fsession, DCB *dcb)
{
TEE_INSTANCE *my_instance = (TEE_INSTANCE *) instance;
TEE_SESSION *my_session = (TEE_SESSION *) fsession;
if (my_instance->source)
{
dcb_printf(dcb, "\t\tLimit to connections from %s\n",
my_instance->source);
}
dcb_printf(dcb, "\t\tDuplicate statements to service %s\n",
my_instance->service->name);
if (my_instance->userName)
{
dcb_printf(dcb, "\t\tLimit to user %s\n",
my_instance->userName);
}
if (my_instance->match)
{
dcb_printf(dcb, "\t\tInclude queries that match %s\n",
my_instance->match);
}
if (my_instance->nomatch)
{
dcb_printf(dcb, "\t\tExclude queries that match %s\n",
my_instance->nomatch);
}
if (my_session)
{
dcb_printf(dcb, "\t\tNo. of statements duplicated: %d.\n",
my_session->n_duped);
dcb_printf(dcb, "\t\tNo. of statements rejected: %d.\n",
my_session->n_rejected);
}
}
/**
* Diagnostics routine
*
* If fsession is NULL then print diagnostics on the filter
* instance as a whole, otherwise print diagnostics for the
* particular session.
*
* @param instance The filter instance
* @param fsession Filter session, may be NULL
*/
static json_t* diagnostic_json(const MXS_FILTER *instance, const MXS_FILTER_SESSION *fsession)
{
TEE_INSTANCE *my_instance = (TEE_INSTANCE*)instance;
TEE_SESSION *my_session = (TEE_SESSION*)fsession;

View File

@ -58,7 +58,8 @@ static void setDownstream(MXS_FILTER *instance, MXS_FILTER_SESSION *fsession, MX
static void setUpstream(MXS_FILTER *instance, MXS_FILTER_SESSION *fsession, MXS_UPSTREAM *upstream);
static int routeQuery(MXS_FILTER *instance, MXS_FILTER_SESSION *fsession, GWBUF *queue);
static int clientReply(MXS_FILTER *instance, MXS_FILTER_SESSION *fsession, GWBUF *queue);
static json_t* diagnostic(const MXS_FILTER *instance, const MXS_FILTER_SESSION *fsession);
static void diagnostic(MXS_FILTER *instance, MXS_FILTER_SESSION *fsession, DCB *dcb);
static json_t* diagnostic_json(const MXS_FILTER *instance, const MXS_FILTER_SESSION *fsession);
static uint64_t getCapabilities(MXS_FILTER* instance);
/**
@ -146,6 +147,7 @@ MXS_MODULE* MXS_CREATE_MODULE()
routeQuery,
clientReply,
diagnostic,
diagnostic_json,
getCapabilities,
NULL, // No destroyInstance
};
@ -573,8 +575,68 @@ clientReply(MXS_FILTER *instance, MXS_FILTER_SESSION *session, GWBUF *reply)
*
* @param instance The filter instance
* @param fsession Filter session, may be NULL
* @param dcb The DCB for diagnostic output
*/
static json_t* diagnostic(const MXS_FILTER *instance, const MXS_FILTER_SESSION *fsession)
static void
diagnostic(MXS_FILTER *instance, MXS_FILTER_SESSION *fsession, DCB *dcb)
{
TOPN_INSTANCE *my_instance = (TOPN_INSTANCE *) instance;
TOPN_SESSION *my_session = (TOPN_SESSION *) fsession;
int i;
dcb_printf(dcb, "\t\tReport size %d\n",
my_instance->topN);
if (my_instance->source)
{
dcb_printf(dcb, "\t\tLimit logging to connections from %s\n",
my_instance->source);
}
if (my_instance->user)
{
dcb_printf(dcb, "\t\tLimit logging to user %s\n",
my_instance->user);
}
if (my_instance->match)
{
dcb_printf(dcb, "\t\tInclude queries that match %s\n",
my_instance->match);
}
if (my_instance->exclude)
{
dcb_printf(dcb, "\t\tExclude queries that match %s\n",
my_instance->exclude);
}
if (my_session)
{
dcb_printf(dcb, "\t\tLogging to file %s.\n",
my_session->filename);
dcb_printf(dcb, "\t\tCurrent Top %d:\n", my_instance->topN);
for (i = 0; i < my_instance->topN; i++)
{
if (my_session->top[i]->sql)
{
dcb_printf(dcb, "\t\t%d place:\n", i + 1);
dcb_printf(dcb, "\t\t\tExecution time: %.3f seconds\n",
(double) ((my_session->top[i]->duration.tv_sec * 1000)
+ (my_session->top[i]->duration.tv_usec / 1000)) / 1000);
dcb_printf(dcb, "\t\t\tSQL: %s\n",
my_session->top[i]->sql);
}
}
}
}
/**
* Diagnostics routine
*
* If fsession is NULL then print diagnostics on the filter
* instance as a whole, otherwise print diagnostics for the
* particular session.
*
* @param instance The filter instance
* @param fsession Filter session, may be NULL
*/
static json_t* diagnostic_json(const MXS_FILTER *instance, const MXS_FILTER_SESSION *fsession)
{
TOPN_INSTANCE *my_instance = (TOPN_INSTANCE*)instance;
TOPN_SESSION *my_session = (TOPN_SESSION*)fsession;

View File

@ -85,7 +85,8 @@ static void setDownstream(MXS_FILTER *instance, MXS_FILTER_SESSION *fsession
static void setUpstream(MXS_FILTER *instance, MXS_FILTER_SESSION *fsession, MXS_UPSTREAM *upstream);
static int routeQuery(MXS_FILTER *instance, MXS_FILTER_SESSION *fsession, GWBUF *queue);
static int clientReply(MXS_FILTER *instance, MXS_FILTER_SESSION *fsession, GWBUF *queue);
static json_t* diagnostic(const MXS_FILTER *instance, const MXS_FILTER_SESSION *fsession);
static void diagnostic(MXS_FILTER *instance, MXS_FILTER_SESSION *fsession, DCB *dcb);
static json_t* diagnostic_json(const MXS_FILTER *instance, const MXS_FILTER_SESSION *fsession);
static uint64_t getCapabilities(MXS_FILTER* instance);
static void checkNamedPipe(void *args);
@ -156,6 +157,7 @@ MXS_MODULE* MXS_CREATE_MODULE()
routeQuery,
clientReply,
diagnostic,
diagnostic_json,
getCapabilities,
NULL, // No destroyInstance
};
@ -563,6 +565,41 @@ clientReply(MXS_FILTER *instance, MXS_FILTER_SESSION *session, GWBUF *reply)
my_session->up.session, reply);
}
/**
* Diagnostics routine
*
* If fsession is NULL then print diagnostics on the filter
* instance as a whole, otherwise print diagnostics for the
* particular session.
*
* @param instance The filter instance
* @param fsession Filter session, may be NULL
* @param dcb The DCB for diagnostic output
*/
static void
diagnostic(MXS_FILTER *instance, MXS_FILTER_SESSION *fsession, DCB *dcb)
{
TPM_INSTANCE *my_instance = (TPM_INSTANCE *)instance;
TPM_SESSION *my_session = (TPM_SESSION *)fsession;
int i;
if (my_instance->source)
dcb_printf(dcb, "\t\tLimit logging to connections from %s\n",
my_instance->source);
if (my_instance->user)
dcb_printf(dcb, "\t\tLimit logging to user %s\n",
my_instance->user);
if (my_instance->filename)
dcb_printf(dcb, "\t\tLogging to file %s.\n",
my_instance->filename);
if (my_instance->delimiter)
dcb_printf(dcb, "\t\tLogging with delimiter %s.\n",
my_instance->delimiter);
if (my_instance->query_delimiter)
dcb_printf(dcb, "\t\tLogging with query delimiter %s.\n",
my_instance->query_delimiter);
}
/**
* Diagnostics routine
*
@ -574,7 +611,7 @@ clientReply(MXS_FILTER *instance, MXS_FILTER_SESSION *session, GWBUF *reply)
* @param fsession Filter session, may be NULL
*/
static json_t*
diagnostic(const MXS_FILTER *instance, const MXS_FILTER_SESSION *fsession)
diagnostic_json(const MXS_FILTER *instance, const MXS_FILTER_SESSION *fsession)
{
TPM_INSTANCE *my_instance = (TPM_INSTANCE*)instance;