MXS-2050 Move more static functions to class methods
This commit is contained in:
@ -79,13 +79,9 @@ enum log_options
|
|||||||
};
|
};
|
||||||
|
|
||||||
/* The filter entry points */
|
/* The filter entry points */
|
||||||
static int routeQuery(MXS_FILTER* instance, MXS_FILTER_SESSION* fsession, GWBUF* queue);
|
|
||||||
static int clientReply(MXS_FILTER* instance, MXS_FILTER_SESSION* session, GWBUF* queue);
|
|
||||||
static void diagnostic(MXS_FILTER* instance, MXS_FILTER_SESSION* fsession, DCB* dcb);
|
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 json_t* diagnostic_json(const MXS_FILTER* instance, const MXS_FILTER_SESSION* fsession);
|
||||||
|
|
||||||
static int write_log_entry(FILE*, QlaInstance*, QlaFilterSession*, uint32_t,
|
|
||||||
const char*, const char*, size_t, int);
|
|
||||||
static bool cb_log(const MODULECMD_ARG* argv, json_t** output);
|
static bool cb_log(const MODULECMD_ARG* argv, json_t** output);
|
||||||
|
|
||||||
static const MXS_ENUM_VALUE option_values[] =
|
static const MXS_ENUM_VALUE option_values[] =
|
||||||
@ -115,41 +111,42 @@ static const MXS_ENUM_VALUE log_data_values[] =
|
|||||||
};
|
};
|
||||||
|
|
||||||
QlaInstance::QlaInstance(const string& name, MXS_CONFIG_PARAMETER* params)
|
QlaInstance::QlaInstance(const string& name, MXS_CONFIG_PARAMETER* params)
|
||||||
: name(name)
|
: m_name(name)
|
||||||
, log_mode_flags(params->get_enum(PARAM_LOG_TYPE, log_type_values))
|
, m_log_mode_flags(params->get_enum(PARAM_LOG_TYPE, log_type_values))
|
||||||
, log_file_data_flags(params->get_enum(PARAM_LOG_DATA, log_data_values))
|
, m_log_file_data_flags(params->get_enum(PARAM_LOG_DATA, log_data_values))
|
||||||
, filebase(params->get_string(PARAM_FILEBASE))
|
, m_filebase(params->get_string(PARAM_FILEBASE))
|
||||||
, unified_fp(NULL)
|
, m_unified_fp(NULL)
|
||||||
, flush_writes(params->get_bool(PARAM_FLUSH))
|
, m_flush_writes(params->get_bool(PARAM_FLUSH))
|
||||||
, append(params->get_bool(PARAM_APPEND))
|
, m_append(params->get_bool(PARAM_APPEND))
|
||||||
, query_newline(params->get_string(PARAM_NEWLINE))
|
, m_query_newline(params->get_string(PARAM_NEWLINE))
|
||||||
, separator(params->get_string(PARAM_SEPARATOR))
|
, m_separator(params->get_string(PARAM_SEPARATOR))
|
||||||
, write_warning_given(false)
|
, m_write_warning_given(false)
|
||||||
, user_name(params->get_string(PARAM_USER))
|
, m_user_name(params->get_string(PARAM_USER))
|
||||||
, source(params->get_string(PARAM_SOURCE))
|
, m_source(params->get_string(PARAM_SOURCE))
|
||||||
, match(params->get_string(PARAM_MATCH))
|
, m_match(params->get_string(PARAM_MATCH))
|
||||||
, exclude(params->get_string(PARAM_EXCLUDE))
|
, m_exclude(params->get_string(PARAM_EXCLUDE))
|
||||||
, re_match(NULL)
|
, m_re_match(NULL)
|
||||||
, re_exclude(NULL)
|
, m_re_exclude(NULL)
|
||||||
, ovec_size(0)
|
, m_ovec_size(0)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
QlaInstance::~QlaInstance()
|
QlaInstance::~QlaInstance()
|
||||||
{
|
{
|
||||||
pcre2_code_free(re_match);
|
pcre2_code_free(m_re_match);
|
||||||
pcre2_code_free(re_exclude);
|
pcre2_code_free(m_re_exclude);
|
||||||
if (unified_fp != NULL)
|
if (m_unified_fp != NULL)
|
||||||
{
|
{
|
||||||
fclose(unified_fp);
|
fclose(m_unified_fp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
QlaFilterSession::QlaFilterSession(const char* user, const char* remote, bool ses_active,
|
QlaFilterSession::QlaFilterSession(const char* user, const char* remote, bool ses_active,
|
||||||
pcre2_match_data* mdata,
|
pcre2_match_data* mdata,
|
||||||
const string& ses_filename, FILE* ses_file,
|
const string& ses_filename, FILE* ses_file,
|
||||||
size_t ses_id, const char* service)
|
size_t ses_id, const char* service, QlaInstance& instance)
|
||||||
: m_user(user)
|
: m_instance(instance)
|
||||||
|
, m_user(user)
|
||||||
, m_remote(remote)
|
, m_remote(remote)
|
||||||
, m_active(ses_active)
|
, m_active(ses_active)
|
||||||
, m_mdata(mdata)
|
, m_mdata(mdata)
|
||||||
@ -200,20 +197,20 @@ QlaInstance* QlaInstance::create(const std::string name, MXS_CONFIG_PARAMETER* p
|
|||||||
my_instance = new(std::nothrow) QlaInstance(name, params);
|
my_instance = new(std::nothrow) QlaInstance(name, params);
|
||||||
if (my_instance)
|
if (my_instance)
|
||||||
{
|
{
|
||||||
my_instance->re_match = re_match;
|
my_instance->m_re_match = re_match;
|
||||||
my_instance->re_exclude = re_exclude;
|
my_instance->m_re_exclude = re_exclude;
|
||||||
my_instance->ovec_size = ovec_size;
|
my_instance->m_ovec_size = ovec_size;
|
||||||
// Try to open the unified log file
|
// Try to open the unified log file
|
||||||
if (my_instance->log_mode_flags & CONFIG_FILE_UNIFIED)
|
if (my_instance->m_log_mode_flags & CONFIG_FILE_UNIFIED)
|
||||||
{
|
{
|
||||||
string unified_filename = my_instance->filebase + ".unified";
|
string unified_filename = my_instance->m_filebase + ".unified";
|
||||||
// Open the file. It is only closed at program exit.
|
// Open the file. It is only closed at program exit.
|
||||||
FILE* unified_fp = my_instance->open_log_file(my_instance->log_file_data_flags,
|
FILE* unified_fp = my_instance->open_log_file(my_instance->m_log_file_data_flags,
|
||||||
unified_filename.c_str());
|
unified_filename.c_str());
|
||||||
if (unified_fp != NULL)
|
if (unified_fp != NULL)
|
||||||
{
|
{
|
||||||
my_instance->unified_filename = unified_filename;
|
my_instance->m_unified_filename = unified_filename;
|
||||||
my_instance->unified_fp = unified_fp;
|
my_instance->m_unified_fp = unified_fp;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -257,15 +254,15 @@ QlaFilterSession* QlaInstance::newSession(MXS_SESSION* session)
|
|||||||
bool error = false;
|
bool error = false;
|
||||||
|
|
||||||
mxb_assert(userName && remote);
|
mxb_assert(userName && remote);
|
||||||
if ((!this->source.empty() && remote && this->source != remote)
|
if ((!m_source.empty() && remote && m_source != remote)
|
||||||
|| (!this->user_name.empty() && userName && this->user_name != userName))
|
|| (!m_user_name.empty() && userName && m_user_name != userName))
|
||||||
{
|
{
|
||||||
ses_active = false;
|
ses_active = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this->ovec_size > 0)
|
if (m_ovec_size > 0)
|
||||||
{
|
{
|
||||||
mdata = pcre2_match_data_create(this->ovec_size, NULL);
|
mdata = pcre2_match_data_create(m_ovec_size, NULL);
|
||||||
if (mdata == NULL)
|
if (mdata == NULL)
|
||||||
{
|
{
|
||||||
// Can this happen? Would require pcre2 to fail completely.
|
// Can this happen? Would require pcre2 to fail completely.
|
||||||
@ -275,14 +272,14 @@ QlaFilterSession* QlaInstance::newSession(MXS_SESSION* session)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Only open the session file if the corresponding mode setting is used
|
// Only open the session file if the corresponding mode setting is used
|
||||||
if (!error && ses_active && this->log_mode_flags & CONFIG_FILE_SESSION)
|
if (!error && ses_active && m_log_mode_flags & CONFIG_FILE_SESSION)
|
||||||
{
|
{
|
||||||
std::stringstream filename_helper;
|
std::stringstream filename_helper;
|
||||||
filename_helper << this->filebase << "." << session->ses_id;
|
filename_helper << m_filebase << "." << session->ses_id;
|
||||||
filename = filename_helper.str();
|
filename = filename_helper.str();
|
||||||
|
|
||||||
// Session numbers are not printed to session files
|
// Session numbers are not printed to session files
|
||||||
uint32_t data_flags = (this->log_file_data_flags & ~LOG_DATA_SESSION);
|
uint32_t data_flags = (m_log_file_data_flags & ~LOG_DATA_SESSION);
|
||||||
|
|
||||||
session_file = open_log_file(data_flags, filename.c_str());
|
session_file = open_log_file(data_flags, filename.c_str());
|
||||||
if (session_file == NULL)
|
if (session_file == NULL)
|
||||||
@ -297,14 +294,10 @@ QlaFilterSession* QlaInstance::newSession(MXS_SESSION* session)
|
|||||||
QlaFilterSession* my_session = NULL;
|
QlaFilterSession* my_session = NULL;
|
||||||
if (!error)
|
if (!error)
|
||||||
{
|
{
|
||||||
my_session = new(std::nothrow) QlaFilterSession(userName,
|
my_session = new(std::nothrow) QlaFilterSession(userName, remote, ses_active, mdata,
|
||||||
remote,
|
filename, session_file,
|
||||||
ses_active,
|
session->ses_id, session->service->name,
|
||||||
mdata,
|
*this);
|
||||||
filename,
|
|
||||||
session_file,
|
|
||||||
session->ses_id,
|
|
||||||
session->service->name);
|
|
||||||
if (my_session == NULL)
|
if (my_session == NULL)
|
||||||
{
|
{
|
||||||
error = true;
|
error = true;
|
||||||
@ -332,22 +325,16 @@ QlaFilterSession* QlaInstance::newSession(MXS_SESSION* session)
|
|||||||
* @param querylen Query string length
|
* @param querylen Query string length
|
||||||
* @param elapsed_ms Query execution time, in milliseconds
|
* @param elapsed_ms Query execution time, in milliseconds
|
||||||
*/
|
*/
|
||||||
void write_log_entries(QlaInstance* my_instance,
|
void QlaFilterSession::write_log_entries(const char* date_string, const char* query, int querylen,
|
||||||
QlaFilterSession* my_session,
|
|
||||||
const char* date_string,
|
|
||||||
const char* query,
|
|
||||||
int querylen,
|
|
||||||
int elapsed_ms)
|
int elapsed_ms)
|
||||||
{
|
{
|
||||||
bool write_error = false;
|
bool write_error = false;
|
||||||
if (my_instance->log_mode_flags & CONFIG_FILE_SESSION)
|
if (m_instance.m_log_mode_flags & CONFIG_FILE_SESSION)
|
||||||
{
|
{
|
||||||
// In this case there is no need to write the session
|
// In this case there is no need to write the session
|
||||||
// number into the files.
|
// number into the files.
|
||||||
uint32_t data_flags = (my_instance->log_file_data_flags & ~LOG_DATA_SESSION);
|
uint32_t data_flags = (m_instance.m_log_file_data_flags & ~LOG_DATA_SESSION);
|
||||||
if (write_log_entry(my_session->m_logfile,
|
if (write_log_entry(m_logfile,
|
||||||
my_instance,
|
|
||||||
my_session,
|
|
||||||
data_flags,
|
data_flags,
|
||||||
date_string,
|
date_string,
|
||||||
query,
|
query,
|
||||||
@ -357,12 +344,10 @@ void write_log_entries(QlaInstance* my_instance,
|
|||||||
write_error = true;
|
write_error = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (my_instance->log_mode_flags & CONFIG_FILE_UNIFIED)
|
if (m_instance.m_log_mode_flags & CONFIG_FILE_UNIFIED)
|
||||||
{
|
{
|
||||||
uint32_t data_flags = my_instance->log_file_data_flags;
|
uint32_t data_flags = m_instance.m_log_file_data_flags;
|
||||||
if (write_log_entry(my_instance->unified_fp,
|
if (write_log_entry(m_instance.m_unified_fp,
|
||||||
my_instance,
|
|
||||||
my_session,
|
|
||||||
data_flags,
|
data_flags,
|
||||||
date_string,
|
date_string,
|
||||||
query,
|
query,
|
||||||
@ -372,43 +357,27 @@ void write_log_entries(QlaInstance* my_instance,
|
|||||||
write_error = true;
|
write_error = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (write_error && !my_instance->write_warning_given)
|
if (write_error && !m_instance.m_write_warning_given)
|
||||||
{
|
{
|
||||||
MXS_ERROR("qla-filter '%s': Log file write failed. "
|
MXS_ERROR("qla-filter '%s': Log file write failed. Suppressing further similar warnings.",
|
||||||
"Suppressing further similar warnings.",
|
m_instance.m_name.c_str());
|
||||||
my_instance->name.c_str());
|
m_instance.m_write_warning_given = true;
|
||||||
my_instance->write_warning_given = true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
int QlaFilterSession::routeQuery(GWBUF* queue)
|
||||||
* The routeQuery entry point. This is passed the query buffer
|
|
||||||
* to which the filter should be applied. Once applied the
|
|
||||||
* query should normally be passed to the downstream component
|
|
||||||
* (filter or router) in the filter chain.
|
|
||||||
*
|
|
||||||
* @param instance The filter instance data
|
|
||||||
* @param session The filter session
|
|
||||||
* @param queue The query data
|
|
||||||
*/
|
|
||||||
static int routeQuery(MXS_FILTER* instance, MXS_FILTER_SESSION* session, GWBUF* queue)
|
|
||||||
{
|
{
|
||||||
QlaInstance* my_instance = (QlaInstance*) instance;
|
|
||||||
QlaFilterSession* my_session = (QlaFilterSession*) session;
|
|
||||||
char* query = NULL;
|
char* query = NULL;
|
||||||
int query_len = 0;
|
int query_len = 0;
|
||||||
|
|
||||||
if (my_session->m_active
|
if (m_active
|
||||||
&& modutil_extract_SQL(queue, &query, &query_len)
|
&& modutil_extract_SQL(queue, &query, &query_len)
|
||||||
&& mxs_pcre2_check_match_exclude(my_instance->re_match,
|
&& mxs_pcre2_check_match_exclude(m_instance.m_re_match, m_instance.m_re_exclude, m_mdata,
|
||||||
my_instance->re_exclude,
|
query, query_len,
|
||||||
my_session->m_mdata,
|
|
||||||
query,
|
|
||||||
query_len,
|
|
||||||
MXS_MODULE_NAME))
|
MXS_MODULE_NAME))
|
||||||
{
|
{
|
||||||
const uint32_t data_flags = my_instance->log_file_data_flags;
|
const uint32_t data_flags = m_instance.m_log_file_data_flags;
|
||||||
LogEventData& event = my_session->m_event_data;
|
LogEventData& event = m_event_data;
|
||||||
if (data_flags & LOG_DATA_DATE)
|
if (data_flags & LOG_DATA_DATE)
|
||||||
{
|
{
|
||||||
// Print current date to a buffer. Use the buffer in the event data struct even if execution time
|
// Print current date to a buffer. Use the buffer in the event data struct even if execution time
|
||||||
@ -438,51 +407,38 @@ static int routeQuery(MXS_FILTER* instance, MXS_FILTER_SESSION* session, GWBUF*
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
// If execution times are not logged, write the log entry now.
|
// If execution times are not logged, write the log entry now.
|
||||||
write_log_entries(my_instance, my_session, event.query_date, query, query_len, -1);
|
write_log_entries(event.query_date, query, query_len, -1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* Pass the query downstream */
|
/* Pass the query downstream */
|
||||||
return my_session->down.routeQuery(my_session->down.instance,
|
return down.routeQuery(down.instance, down.session, queue);
|
||||||
my_session->down.session,
|
|
||||||
queue);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
int QlaFilterSession::clientReply(GWBUF* queue)
|
||||||
* The clientReply entry point. Required for measuring and printing query execution time.
|
|
||||||
*
|
|
||||||
* @param instance The filter instance data
|
|
||||||
* @param session The filter session
|
|
||||||
* @param queue The query data
|
|
||||||
*/
|
|
||||||
static int clientReply(MXS_FILTER* instance, MXS_FILTER_SESSION* session, GWBUF* queue)
|
|
||||||
{
|
{
|
||||||
QlaInstance* my_instance = (QlaInstance*) instance;
|
LogEventData& event = m_event_data;
|
||||||
QlaFilterSession* my_session = (QlaFilterSession*) session;
|
|
||||||
LogEventData& event = my_session->m_event_data;
|
|
||||||
if (event.has_message)
|
if (event.has_message)
|
||||||
{
|
{
|
||||||
const uint32_t data_flags = my_instance->log_file_data_flags;
|
const uint32_t data_flags = m_instance.m_log_file_data_flags;
|
||||||
mxb_assert(data_flags & LOG_DATA_REPLY_TIME);
|
mxb_assert(data_flags & LOG_DATA_REPLY_TIME);
|
||||||
|
|
||||||
char* query = NULL;
|
char* query = NULL;
|
||||||
int query_len = 0;
|
int query_len = 0;
|
||||||
if (data_flags & LOG_DATA_QUERY)
|
if (data_flags & LOG_DATA_QUERY)
|
||||||
{
|
{
|
||||||
modutil_extract_SQL(event.query_clone, &query, &query_len);
|
modutil_extract_SQL(event.query_clone, &query, &query_len);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Calculate elapsed time in milliseconds.
|
||||||
timespec now;
|
timespec now;
|
||||||
clock_gettime(CLOCK_MONOTONIC, &now); // Gives time in seconds + nanoseconds
|
clock_gettime(CLOCK_MONOTONIC, &now); // Gives time in seconds + nanoseconds
|
||||||
// Calculate elapsed time in milliseconds.
|
|
||||||
double elapsed_ms = 1E3 * (now.tv_sec - event.begin_time.tv_sec)
|
double elapsed_ms = 1E3 * (now.tv_sec - event.begin_time.tv_sec)
|
||||||
+ (now.tv_nsec - event.begin_time.tv_nsec) / (double)1E6;
|
+ (now.tv_nsec - event.begin_time.tv_nsec) / (double)1E6;
|
||||||
write_log_entries(my_instance,
|
|
||||||
my_session,
|
write_log_entries(event.query_date, query, query_len, std::floor(elapsed_ms + 0.5));
|
||||||
event.query_date,
|
|
||||||
query,
|
|
||||||
query_len,
|
|
||||||
std::floor(elapsed_ms + 0.5));
|
|
||||||
event.clear();
|
event.clear();
|
||||||
}
|
}
|
||||||
return my_session->up.clientReply(my_session->up.instance, my_session->up.session, queue);
|
return up.clientReply(up.instance, up.session, queue);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -507,36 +463,36 @@ static void diagnostic(MXS_FILTER* instance, MXS_FILTER_SESSION* fsession, DCB*
|
|||||||
"\t\tLogging to file %s.\n",
|
"\t\tLogging to file %s.\n",
|
||||||
my_session->m_filename.c_str());
|
my_session->m_filename.c_str());
|
||||||
}
|
}
|
||||||
if (!my_instance->source.empty())
|
if (!my_instance->m_source.empty())
|
||||||
{
|
{
|
||||||
dcb_printf(dcb,
|
dcb_printf(dcb,
|
||||||
"\t\tLimit logging to connections from %s\n",
|
"\t\tLimit logging to connections from %s\n",
|
||||||
my_instance->source.c_str());
|
my_instance->m_source.c_str());
|
||||||
}
|
}
|
||||||
if (!my_instance->user_name.empty())
|
if (!my_instance->m_user_name.empty())
|
||||||
{
|
{
|
||||||
dcb_printf(dcb,
|
dcb_printf(dcb,
|
||||||
"\t\tLimit logging to user %s\n",
|
"\t\tLimit logging to user %s\n",
|
||||||
my_instance->user_name.c_str());
|
my_instance->m_user_name.c_str());
|
||||||
}
|
}
|
||||||
if (!my_instance->match.empty())
|
if (!my_instance->m_match.empty())
|
||||||
{
|
{
|
||||||
dcb_printf(dcb,
|
dcb_printf(dcb,
|
||||||
"\t\tInclude queries that match %s\n",
|
"\t\tInclude queries that match %s\n",
|
||||||
my_instance->match.c_str());
|
my_instance->m_match.c_str());
|
||||||
}
|
}
|
||||||
if (!my_instance->exclude.empty())
|
if (!my_instance->m_exclude.empty())
|
||||||
{
|
{
|
||||||
dcb_printf(dcb,
|
dcb_printf(dcb,
|
||||||
"\t\tExclude queries that match %s\n",
|
"\t\tExclude queries that match %s\n",
|
||||||
my_instance->exclude.c_str());
|
my_instance->m_exclude.c_str());
|
||||||
}
|
}
|
||||||
dcb_printf(dcb,
|
dcb_printf(dcb,
|
||||||
"\t\tColumn separator %s\n",
|
"\t\tColumn separator %s\n",
|
||||||
my_instance->separator.c_str());
|
my_instance->m_separator.c_str());
|
||||||
dcb_printf(dcb,
|
dcb_printf(dcb,
|
||||||
"\t\tNewline replacement %s\n",
|
"\t\tNewline replacement %s\n",
|
||||||
my_instance->query_newline.c_str());
|
my_instance->m_query_newline.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -561,27 +517,27 @@ static json_t* diagnostic_json(const MXS_FILTER* instance, const MXS_FILTER_SESS
|
|||||||
json_object_set_new(rval, "session_filename", json_string(my_session->m_filename.c_str()));
|
json_object_set_new(rval, "session_filename", json_string(my_session->m_filename.c_str()));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!my_instance->source.empty())
|
if (!my_instance->m_source.empty())
|
||||||
{
|
{
|
||||||
json_object_set_new(rval, PARAM_SOURCE, json_string(my_instance->source.c_str()));
|
json_object_set_new(rval, PARAM_SOURCE, json_string(my_instance->m_source.c_str()));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!my_instance->user_name.empty())
|
if (!my_instance->m_user_name.empty())
|
||||||
{
|
{
|
||||||
json_object_set_new(rval, PARAM_USER, json_string(my_instance->user_name.c_str()));
|
json_object_set_new(rval, PARAM_USER, json_string(my_instance->m_user_name.c_str()));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!my_instance->match.empty())
|
if (!my_instance->m_match.empty())
|
||||||
{
|
{
|
||||||
json_object_set_new(rval, PARAM_MATCH, json_string(my_instance->match.c_str()));
|
json_object_set_new(rval, PARAM_MATCH, json_string(my_instance->m_match.c_str()));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!my_instance->exclude.empty())
|
if (!my_instance->m_exclude.empty())
|
||||||
{
|
{
|
||||||
json_object_set_new(rval, PARAM_EXCLUDE, json_string(my_instance->exclude.c_str()));
|
json_object_set_new(rval, PARAM_EXCLUDE, json_string(my_instance->m_exclude.c_str()));
|
||||||
}
|
}
|
||||||
json_object_set_new(rval, PARAM_SEPARATOR, json_string(my_instance->separator.c_str()));
|
json_object_set_new(rval, PARAM_SEPARATOR, json_string(my_instance->m_separator.c_str()));
|
||||||
json_object_set_new(rval, PARAM_NEWLINE, json_string(my_instance->query_newline.c_str()));
|
json_object_set_new(rval, PARAM_NEWLINE, json_string(my_instance->m_query_newline.c_str()));
|
||||||
|
|
||||||
return rval;
|
return rval;
|
||||||
}
|
}
|
||||||
@ -599,7 +555,7 @@ FILE* QlaInstance::open_log_file(uint32_t data_flags, const char* filename)
|
|||||||
auto instance = this;
|
auto instance = this;
|
||||||
bool file_existed = false;
|
bool file_existed = false;
|
||||||
FILE* fp = NULL;
|
FILE* fp = NULL;
|
||||||
if (instance->append == false)
|
if (instance->m_append == false)
|
||||||
{
|
{
|
||||||
// Just open the file (possibly overwriting) and then print header.
|
// Just open the file (possibly overwriting) and then print header.
|
||||||
fp = fopen(filename, "w");
|
fp = fopen(filename, "w");
|
||||||
@ -635,7 +591,7 @@ FILE* QlaInstance::open_log_file(uint32_t data_flags, const char* filename)
|
|||||||
|
|
||||||
std::stringstream header;
|
std::stringstream header;
|
||||||
string curr_sep; // Use empty string as the first separator
|
string curr_sep; // Use empty string as the first separator
|
||||||
const string& real_sep = instance->separator;
|
const string& real_sep = instance->m_separator;
|
||||||
|
|
||||||
if (data_flags & LOG_DATA_SERVICE)
|
if (data_flags & LOG_DATA_SERVICE)
|
||||||
{
|
{
|
||||||
@ -671,7 +627,7 @@ FILE* QlaInstance::open_log_file(uint32_t data_flags, const char* filename)
|
|||||||
// Finally, write the log header.
|
// Finally, write the log header.
|
||||||
int written = fprintf(fp, "%s", header.str().c_str());
|
int written = fprintf(fp, "%s", header.str().c_str());
|
||||||
|
|
||||||
if ((written <= 0) || ((instance->flush_writes) && (fflush(fp) < 0)))
|
if ((written <= 0) || ((instance->m_flush_writes) && (fflush(fp) < 0)))
|
||||||
{
|
{
|
||||||
// Weird error, file opened but a write failed. Best to stop.
|
// Weird error, file opened but a write failed. Best to stop.
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
@ -738,8 +694,6 @@ static void print_string_replace_newlines(const char* sql_string,
|
|||||||
* Write an entry to the log file.
|
* Write an entry to the log file.
|
||||||
*
|
*
|
||||||
* @param logfile Target file
|
* @param logfile Target file
|
||||||
* @param instance Filter instance
|
|
||||||
* @param session Filter session
|
|
||||||
* @param data_flags Controls what to write
|
* @param data_flags Controls what to write
|
||||||
* @param time_string Date entry
|
* @param time_string Date entry
|
||||||
* @param sql_string SQL-query, *not* NULL terminated
|
* @param sql_string SQL-query, *not* NULL terminated
|
||||||
@ -747,14 +701,8 @@ static void print_string_replace_newlines(const char* sql_string,
|
|||||||
* @param elapsed_ms Query execution time, in milliseconds
|
* @param elapsed_ms Query execution time, in milliseconds
|
||||||
* @return The number of characters written, or a negative value on failure
|
* @return The number of characters written, or a negative value on failure
|
||||||
*/
|
*/
|
||||||
static int write_log_entry(FILE* logfile,
|
int QlaFilterSession::write_log_entry(FILE* logfile, uint32_t data_flags, const char* time_string,
|
||||||
QlaInstance* instance,
|
const char* sql_string, size_t sql_str_len, int elapsed_ms)
|
||||||
QlaFilterSession* session,
|
|
||||||
uint32_t data_flags,
|
|
||||||
const char* time_string,
|
|
||||||
const char* sql_string,
|
|
||||||
size_t sql_str_len,
|
|
||||||
int elapsed_ms)
|
|
||||||
{
|
{
|
||||||
mxb_assert(logfile != NULL);
|
mxb_assert(logfile != NULL);
|
||||||
if (data_flags == 0)
|
if (data_flags == 0)
|
||||||
@ -767,16 +715,16 @@ static int write_log_entry(FILE* logfile,
|
|||||||
* simultaneously, so we have to first print to a string. */
|
* simultaneously, so we have to first print to a string. */
|
||||||
std::stringstream output;
|
std::stringstream output;
|
||||||
string curr_sep; // Use empty string as the first separator
|
string curr_sep; // Use empty string as the first separator
|
||||||
const string& real_sep = instance->separator;
|
const string& real_sep = m_instance.m_separator;
|
||||||
|
|
||||||
if (data_flags & LOG_DATA_SERVICE)
|
if (data_flags & LOG_DATA_SERVICE)
|
||||||
{
|
{
|
||||||
output << session->m_service;
|
output << m_service;
|
||||||
curr_sep = real_sep;
|
curr_sep = real_sep;
|
||||||
}
|
}
|
||||||
if (data_flags & LOG_DATA_SESSION)
|
if (data_flags & LOG_DATA_SESSION)
|
||||||
{
|
{
|
||||||
output << curr_sep << session->m_ses_id;
|
output << curr_sep << m_ses_id;
|
||||||
curr_sep = real_sep;
|
curr_sep = real_sep;
|
||||||
}
|
}
|
||||||
if (data_flags & LOG_DATA_DATE)
|
if (data_flags & LOG_DATA_DATE)
|
||||||
@ -786,7 +734,7 @@ static int write_log_entry(FILE* logfile,
|
|||||||
}
|
}
|
||||||
if (data_flags & LOG_DATA_USER)
|
if (data_flags & LOG_DATA_USER)
|
||||||
{
|
{
|
||||||
output << curr_sep << session->m_user << "@" << session->m_remote;
|
output << curr_sep << m_user << "@" << m_remote;
|
||||||
curr_sep = real_sep;
|
curr_sep = real_sep;
|
||||||
}
|
}
|
||||||
if (data_flags & LOG_DATA_REPLY_TIME)
|
if (data_flags & LOG_DATA_REPLY_TIME)
|
||||||
@ -797,9 +745,11 @@ static int write_log_entry(FILE* logfile,
|
|||||||
if (data_flags & LOG_DATA_QUERY)
|
if (data_flags & LOG_DATA_QUERY)
|
||||||
{
|
{
|
||||||
output << curr_sep;
|
output << curr_sep;
|
||||||
if (!instance->query_newline.empty())
|
if (!m_instance.m_query_newline.empty())
|
||||||
{
|
{
|
||||||
print_string_replace_newlines(sql_string, sql_str_len, instance->query_newline.c_str(), &output);
|
print_string_replace_newlines(sql_string, sql_str_len,
|
||||||
|
m_instance.m_query_newline.c_str(),
|
||||||
|
&output);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -812,7 +762,7 @@ static int write_log_entry(FILE* logfile,
|
|||||||
// Finally, write the log event.
|
// Finally, write the log event.
|
||||||
int written = fprintf(logfile, "%s", output.str().c_str());
|
int written = fprintf(logfile, "%s", output.str().c_str());
|
||||||
|
|
||||||
if ((!instance->flush_writes) || (written <= 0))
|
if ((!m_instance.m_flush_writes) || (written <= 0))
|
||||||
{
|
{
|
||||||
return written;
|
return written;
|
||||||
}
|
}
|
||||||
@ -837,10 +787,10 @@ static bool cb_log(const MODULECMD_ARG* argv, json_t** output)
|
|||||||
QlaInstance* instance = reinterpret_cast<QlaInstance*>(filter_def_get_instance(filter));
|
QlaInstance* instance = reinterpret_cast<QlaInstance*>(filter_def_get_instance(filter));
|
||||||
bool rval = false;
|
bool rval = false;
|
||||||
|
|
||||||
if (instance->log_mode_flags & CONFIG_FILE_UNIFIED)
|
if (instance->m_log_mode_flags & CONFIG_FILE_UNIFIED)
|
||||||
{
|
{
|
||||||
mxb_assert(instance->unified_fp && !instance->unified_filename.empty());
|
mxb_assert(instance->m_unified_fp && !instance->m_unified_filename.empty());
|
||||||
std::ifstream file(instance->unified_filename);
|
std::ifstream file(instance->m_unified_filename);
|
||||||
|
|
||||||
if (file)
|
if (file)
|
||||||
{
|
{
|
||||||
@ -867,7 +817,7 @@ static bool cb_log(const MODULECMD_ARG* argv, json_t** output)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
*output = mxs_json_error("Failed to open file '%s'",
|
*output = mxs_json_error("Failed to open file '%s'",
|
||||||
instance->unified_filename.c_str());
|
instance->m_unified_filename.c_str());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -922,6 +872,18 @@ uint64_t getCapabilities(MXS_FILTER* instance)
|
|||||||
return RCAP_TYPE_NONE;
|
return RCAP_TYPE_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int routeQuery(MXS_FILTER* instance, MXS_FILTER_SESSION* session, GWBUF* queue)
|
||||||
|
{
|
||||||
|
QlaFilterSession* my_session = (QlaFilterSession*) session;
|
||||||
|
return my_session->routeQuery(queue);
|
||||||
|
}
|
||||||
|
|
||||||
|
int clientReply(MXS_FILTER* instance, MXS_FILTER_SESSION* session, GWBUF* queue)
|
||||||
|
{
|
||||||
|
QlaFilterSession* my_session = (QlaFilterSession*) session;
|
||||||
|
return my_session->clientReply(queue);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -92,29 +92,29 @@ public:
|
|||||||
*/
|
*/
|
||||||
static QlaInstance* create(const std::string name, MXS_CONFIG_PARAMETER* params);
|
static QlaInstance* create(const std::string name, MXS_CONFIG_PARAMETER* params);
|
||||||
|
|
||||||
std::string name; /* Filter definition name */
|
const std::string m_name; /* Filter definition name */
|
||||||
|
|
||||||
uint32_t log_mode_flags; /* Log file mode settings */
|
uint32_t m_log_mode_flags; /* Log file mode settings */
|
||||||
uint32_t log_file_data_flags; /* What data is saved to the files */
|
uint32_t m_log_file_data_flags; /* What data is saved to the files */
|
||||||
|
std::string m_filebase; /* The filename base */
|
||||||
|
std::string m_unified_filename; /* Filename of the unified log file */
|
||||||
|
|
||||||
std::string filebase; /* The filename base */
|
FILE* m_unified_fp; /* Unified log file. The pointer needs to be shared here
|
||||||
std::string unified_filename; /* Filename of the unified log file */
|
|
||||||
FILE* unified_fp; /* Unified log file. The pointer needs to be shared here
|
|
||||||
* to avoid garbled printing. */
|
* to avoid garbled printing. */
|
||||||
bool flush_writes; /* Flush log file after every write? */
|
bool m_flush_writes; /* Flush log file after every write? */
|
||||||
bool append; /* Open files in append-mode? */
|
bool m_append; /* Open files in append-mode? */
|
||||||
std::string query_newline; /* Character(s) used to replace a newline within a query */
|
std::string m_query_newline; /* Character(s) used to replace a newline within a query */
|
||||||
std::string separator; /* Character(s) used to separate elements */
|
std::string m_separator; /* Character(s) used to separate elements */
|
||||||
bool write_warning_given;/* Avoid repeatedly printing some errors/warnings. */
|
bool m_write_warning_given;/* Avoid repeatedly printing some errors/warnings. */
|
||||||
|
|
||||||
std::string user_name; /* The user name to filter on */
|
std::string m_user_name; /* The user name to filter on */
|
||||||
std::string source; /* The source of the client connection to filter on */
|
std::string m_source; /* The source of the client connection to filter on */
|
||||||
|
|
||||||
std::string match; /* Optional text to match against */
|
std::string m_match; /* Optional text to match against */
|
||||||
std::string exclude; /* Optional text to match against for exclusion */
|
std::string m_exclude; /* Optional text to match against for exclusion */
|
||||||
pcre2_code* re_match; /* Compiled regex text */
|
pcre2_code* m_re_match; /* Compiled regex text */
|
||||||
pcre2_code* re_exclude; /* Compiled regex nomatch text */
|
pcre2_code* m_re_exclude; /* Compiled regex nomatch text */
|
||||||
uint32_t ovec_size; /* PCRE2 match data ovector size */
|
uint32_t m_ovec_size; /* PCRE2 match data ovector size */
|
||||||
|
|
||||||
private:
|
private:
|
||||||
FILE* open_log_file(uint32_t, const char*);
|
FILE* open_log_file(uint32_t, const char*);
|
||||||
@ -128,14 +128,32 @@ public:
|
|||||||
QlaFilterSession& operator=(const QlaFilterSession&);
|
QlaFilterSession& operator=(const QlaFilterSession&);
|
||||||
QlaFilterSession(const char* user, const char* remote, bool ses_active,
|
QlaFilterSession(const char* user, const char* remote, bool ses_active,
|
||||||
pcre2_match_data* mdata, const std::string& ses_filename, FILE* ses_file,
|
pcre2_match_data* mdata, const std::string& ses_filename, FILE* ses_file,
|
||||||
size_t ses_id, const char* service);
|
size_t ses_id, const char* service, QlaInstance& instance);
|
||||||
~QlaFilterSession();
|
~QlaFilterSession();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Route a query.
|
||||||
|
*
|
||||||
|
* @param query
|
||||||
|
* @return 0 on success
|
||||||
|
*/
|
||||||
|
int routeQuery(GWBUF* query);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Route a reply from backend. Required for measuring and printing query execution time.
|
||||||
|
*
|
||||||
|
* @param reply Reply from server
|
||||||
|
* @return 0 on success
|
||||||
|
*/
|
||||||
|
int clientReply(GWBUF* reply);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Close a session with the filter. Close the file descriptor and reset event info.
|
* Close a session with the filter. Close the file descriptor and reset event info.
|
||||||
*/
|
*/
|
||||||
void close();
|
void close();
|
||||||
|
|
||||||
|
QlaInstance& m_instance;
|
||||||
|
|
||||||
const char* m_user; /* Client username */
|
const char* m_user; /* Client username */
|
||||||
const char* m_remote; /* Client address */
|
const char* m_remote; /* Client address */
|
||||||
bool m_active; /* Is session active? */
|
bool m_active; /* Is session active? */
|
||||||
@ -148,4 +166,8 @@ public:
|
|||||||
|
|
||||||
MXS_UPSTREAM up;
|
MXS_UPSTREAM up;
|
||||||
MXS_DOWNSTREAM down;
|
MXS_DOWNSTREAM down;
|
||||||
|
|
||||||
|
void write_log_entries(const char* date_string, const char* query, int querylen, int elapsed_ms);
|
||||||
|
int write_log_entry(FILE* logfile, uint32_t data_flags, const char* time_string,
|
||||||
|
const char* sql_string, size_t sql_str_len, int elapsed_ms);
|
||||||
};
|
};
|
||||||
|
Reference in New Issue
Block a user