Additional error checking and documentation.

Implementation of topfilter options
This commit is contained in:
Mark Riddoch
2014-06-10 11:57:48 +01:00
parent 77e1426dbf
commit a8def0d670
4 changed files with 111 additions and 8 deletions

View File

@ -135,6 +135,19 @@ FILTER_DEF *filter;
return filter;
}
/**
* Check a parameter to see if it is a standard filter parameter
*
* @param name Parameter name to check
*/
int
filter_standard_parameter(char *name)
{
if (strcmp(name, "type") == 0 || strcmp(name, "module") == 0)
return 1;
return 0;
}
/**
* Print all filters to a DCB
*
@ -285,6 +298,17 @@ int i;
spinlock_release(&filter->spin);
}
/**
* Connect the downstream filter chain for a filter.
*
* This will create the filter instance, loading the filter module, and
* conenct the fitler into the downstream chain.
*
* @param filter The filter to add into the chain
* @param session The client session
* @param downstream The filter downstream of this filter
* @return The downstream component for the next filter
*/
DOWNSTREAM *
filterApply(FILTER_DEF *filter, SESSION *session, DOWNSTREAM *downstream)
{
@ -315,6 +339,19 @@ DOWNSTREAM *me;
return me;
}
/**
* Connect a filter in the up stream filter chain for a session
*
* Note, the filter will have been created when the downstream chian was
* previously setup.
* Note all filters require to be in the upstream chain, so this routine
* may skip a filter if it does not provide an upstream interface.
*
* @param filter The fitler to add to the chain
* @param fsession The filter session
* @param upstream The filter that should be upstream of this filter
* @return The upstream component for the next filter
*/
UPSTREAM *
filterUpstream(FILTER_DEF *filter, void *fsession, UPSTREAM *upstream)
{

View File

@ -111,6 +111,8 @@ FILTER_DEF *filter_find(char *);
void filterAddOption(FILTER_DEF *, char *);
void filterAddParameter(FILTER_DEF *, char *, char *);
DOWNSTREAM *filterApply(FILTER_DEF *, SESSION *, DOWNSTREAM *);
UPSTREAM *filterUpstream(FILTER_DEF *, void *, UPSTREAM *);
int filter_standard_parameter(char *);
void dprintAllFilters(DCB *);
void dprintFilter(DCB *, FILTER_DEF *);
void dListFilters(DCB *);

View File

@ -19,9 +19,13 @@
#include <filter.h>
#include <modinfo.h>
#include <modutil.h>
#include <skygw_utils.h>
#include <log_manager.h>
#include <string.h>
#include <regex.h>
extern int lm_enabled_logfiles_bitmask;
/**
* regexfilter.c - a very simple regular expression rewrite filter.
*
@ -126,7 +130,7 @@ static FILTER *
createInstance(char **options, FILTER_PARAMETER **params)
{
REGEX_INSTANCE *my_instance;
int i;
int i, cflags = REG_ICASE;
if ((my_instance = calloc(1, sizeof(REGEX_INSTANCE))) != NULL)
{
@ -137,9 +141,36 @@ int i;
{
if (!strcmp(params[i]->name, "match"))
my_instance->match = strdup(params[i]->value);
if (!strcmp(params[i]->name, "replace"))
else if (!strcmp(params[i]->name, "replace"))
my_instance->replace = strdup(params[i]->value);
else if (!filter_standard_parameter(params[i]->name))
{
LOGIF(LE, (skygw_log_write_flush(
LOGFILE_ERROR,
"regexfilter: Unexpected parameter '%s'.\n",
params[i]->name)));
}
}
for (i = 0; options[i]; i++)
{
if (!strcasecmp(options[i], "ignorecase"))
{
cflags |= REG_ICASE;
}
else if (!strcasecmp(options[i], "case"))
{
cflags &= ~REG_ICASE;
}
else
{
LOGIF(LE, (skygw_log_write_flush(
LOGFILE_ERROR,
"regexfilter: unsupported option '%s'.\n",
options[i])));
}
}
if (my_instance->match == NULL || my_instance->replace == NULL)
{
return NULL;
@ -147,6 +178,9 @@ int i;
if (regcomp(&my_instance->re, my_instance->match, REG_ICASE))
{
LOGIF(LE, (skygw_log_write_flush(LOGFILE_ERROR,
"regexfilter: Invalid regular expression '%s'.\n",
my_instance->match)));
free(my_instance->match);
free(my_instance->replace);
free(my_instance);

View File

@ -33,10 +33,14 @@
#include <filter.h>
#include <modinfo.h>
#include <modutil.h>
#include <skygw_utils.h>
#include <log_manager.h>
#include <string.h>
#include <time.h>
#include <sys/time.h>
extern int lm_enabled_logfiles_bitmask;
MODULE_INFO info = {
MODULE_API_FILTER,
MODULE_ALPHA_RELEASE,
@ -105,6 +109,7 @@ typedef struct topnq {
typedef struct {
DOWNSTREAM down;
UPSTREAM up;
char *clientHost;
char *filename;
int fd;
struct timeval start;
@ -112,6 +117,8 @@ typedef struct {
TOPNQ **top;
int n_statements;
struct timeval total;
struct timeval connect;
struct timeval disconnect;
} TOPN_SESSION;
/**
@ -168,8 +175,15 @@ TOPN_INSTANCE *my_instance;
{
if (!strcmp(params[i]->name, "count"))
my_instance->topN = atoi(params[i]->value);
if (!strcmp(params[i]->name, "filebase"))
else if (!strcmp(params[i]->name, "filebase"))
my_instance->filebase = strdup(params[i]->value);
else if (!filter_standard_parameter(params[i]->name))
{
LOGIF(LE, (skygw_log_write_flush(
LOGFILE_ERROR,
"topfilter: Unexpected parameter '%s'.\n",
params[i]->name)));
}
}
my_instance->sessions = 0;
}
@ -214,6 +228,11 @@ int i;
my_session->n_statements = 0;
my_session->total.tv_sec = 0;
my_session->total.tv_usec = 0;
if (session && session->client && session->client->remote)
my_session->clientHost = strdup(session->client->remote);
else
my_session->clientHost = NULL;
gettimeofday(&my_session->connect, NULL);
}
return my_session;
@ -232,9 +251,12 @@ closeSession(FILTER *instance, void *session)
{
TOPN_INSTANCE *my_instance = (TOPN_INSTANCE *)instance;
TOPN_SESSION *my_session = (TOPN_SESSION *)session;
struct timeval diff;
int i;
FILE *fp;
gettimeofday(&my_session->disconnect, NULL);
timersub((&my_session->disconnect), &(my_session->connect), &diff);
if ((fp = fopen(my_session->filename, "w")) != NULL)
{
fprintf(fp, "Top %d longest running queries in session.\n",
@ -243,21 +265,27 @@ FILE *fp;
{
if (my_session->top[i]->sql)
{
fprintf(fp, "%4d.%-3d, %s\n",
my_session->top[i]->duration.tv_sec,
my_session->top[i]->duration.tv_usec / 1000,
fprintf(fp, "%.3f, %s\n",
(double)((my_session->top[i]->duration.tv_sec * 1000)
+ (my_session->top[i]->duration.tv_usec / 1000) / 1000
),
my_session->top[i]->sql);
}
}
fprintf(fp, "\n\nTotal of %d statements executed.\n",
my_session->n_statements);
fprintf(fp, "Total statement execution time %d.%d seconds\n",
my_session->total.tv_sec,
my_session->total.tv_usec / 1000);
(int)my_session->total.tv_sec,
(int)my_session->total.tv_usec / 1000);
fprintf(fp, "Average statement execution time %.3f.\n",
(double)((my_session->total.tv_sec * 1000)
+ (my_session->total.tv_usec / 1000))
/ (1000 * my_session->n_statements));
fprintf(fp, "Total connection time %d.%d seconds\n",
(int)diff.tv_sec, (int)diff.tv_usec / 1000);
if (my_session->clientHost)
fprintf(fp, "Connection from %s\n",
my_session->clientHost);
fclose(fp);
}
}
@ -274,6 +302,8 @@ freeSession(FILTER *instance, void *session)
TOPN_SESSION *my_session = (TOPN_SESSION *)session;
free(my_session->filename);
if (my_session->clientHost)
free(my_session->clientHost);
free(session);
return;
}