1
/* -*- mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; -*-
2
* vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
4
* Copyright (C) 2009 Mark Atwood
6
* This program is free software; you can redistribute it and/or modify
7
* it under the terms of the GNU General Public License as published by
8
* the Free Software Foundation; version 2 of the License.
10
* This program is distributed in the hope that it will be useful,
11
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
* GNU General Public License for more details.
15
* You should have received a copy of the GNU General Public License
16
* along with this program; if not, write to the Free Software
17
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
20
#include <drizzled/server_includes.h>
21
#include <drizzled/plugin_logging.h>
22
#include <drizzled/gettext.h>
23
#include <drizzled/session.h>
27
# include <plugin/logging_syslog/names.h>
29
# define SYSLOG_NAMES 1
35
static bool sysvar_logging_syslog_enable= false;
36
static char* sysvar_logging_syslog_ident= NULL;
37
static char* sysvar_logging_syslog_facility= NULL;
38
static char* sysvar_logging_syslog_priority= NULL;
39
static ulong sysvar_logging_syslog_threshold_slow= 0;
40
static ulong sysvar_logging_syslog_threshold_big_resultset= 0;
41
static ulong sysvar_logging_syslog_threshold_big_examined= 0;
43
static int syslog_facility= -1;
44
static int syslog_priority= -1;
46
/* stolen from mysys/my_getsystime
47
until the Session has a good utime "now" we can use
48
will have to use this instead */
51
static uint64_t get_microtime()
53
#if defined(HAVE_GETHRTIME)
54
return gethrtime()/1000;
58
/* loop is because gettimeofday may fail on some systems */
59
while (gettimeofday(&t, NULL) != 0) {}
60
newtime= (uint64_t)t.tv_sec * 1000000 + t.tv_usec;
65
bool logging_syslog_func_post (Session *session)
67
assert(session != NULL);
69
// return if not enabled or query was too fast or resultset was too small
70
if (sysvar_logging_syslog_enable == false)
72
if (session->sent_row_count < sysvar_logging_syslog_threshold_big_resultset)
74
if (session->examined_row_count < sysvar_logging_syslog_threshold_big_examined)
77
/* TODO, looks like connect_utime isnt being set in the session
78
object. We could store the time this plugin was loaded, but that
79
would just be a dumb workaround. */
80
/* TODO, the session object should have a "utime command completed"
81
inside itself, so be more accurate, and so this doesnt have to
82
keep calling current_utime, which can be slow */
84
uint64_t t_mark= get_microtime();
86
if ((t_mark - session->start_utime) < sysvar_logging_syslog_threshold_slow)
89
/* to avoid trying to printf %s something that is potentially NULL */
91
const char *dbs= (session->db) ? session->db : "";
94
dbl= session->db_length;
96
const char *qys= (session->query) ? session->query : "";
99
qyl= session->query_length;
101
syslog(syslog_priority,
102
"thread_id=%ld query_id=%ld"
106
" t_connect=%lld t_start=%lld t_lock=%lld"
107
" rows_sent=%ld rows_examined=%ld\n",
108
(unsigned long) session->thread_id,
109
(unsigned long) session->query_id,
112
(int) command_name[session->command].length,
113
command_name[session->command].str,
114
(unsigned long long) (t_mark - session->connect_utime),
115
(unsigned long long) (t_mark - session->start_utime),
116
(unsigned long long) (t_mark - session->utime_after_lock),
117
(unsigned long) session->sent_row_count,
118
(unsigned long) session->examined_row_count);
121
syslog(syslog_priority,
122
"thread_id=%ld query_id=%ld"
126
" t_connect=%lld t_start=%lld t_lock=%lld"
127
" rows_sent=%ld rows_examined=%ld\n",
128
(unsigned long) session->thread_id,
129
(unsigned long) session->query_id,
130
session->db_length, session->db,
131
// dont need to quote the query, because syslog does it itself
132
session->query_length, session->query,
133
(int) command_name[session->command].length,
134
command_name[session->command].str,
135
(unsigned long long) (t_mark - session->connect_utime),
136
(unsigned long long) (t_mark - session->start_utime),
137
(unsigned long long) (t_mark - session->utime_after_lock),
138
(unsigned long) session->sent_row_count,
139
(unsigned long) session->examined_row_count);
146
static int logging_syslog_plugin_init(void *p)
148
logging_t *l= (logging_t *) p;
151
for (int ndx= 0; facilitynames[ndx].c_name; ndx++)
153
if (strcasecmp(facilitynames[ndx].c_name, sysvar_logging_syslog_facility) == 0)
155
syslog_facility= facilitynames[ndx].c_val;
159
if (syslog_facility == -1)
161
errmsg_printf(ERRMSG_LVL_WARN,
162
_("syslog facility \"%s\" not known, using \"local0\""),
163
sysvar_logging_syslog_facility);
164
syslog_facility= LOG_LOCAL0;
168
for (int ndx= 0; prioritynames[ndx].c_name; ndx++)
170
if (strcasecmp(prioritynames[ndx].c_name, sysvar_logging_syslog_priority) == 0)
172
syslog_priority= prioritynames[ndx].c_val;
176
if (syslog_priority == -1)
178
errmsg_printf(ERRMSG_LVL_WARN,
179
_("syslog priority \"%s\" not known, using \"info\""),
180
sysvar_logging_syslog_priority);
181
syslog_priority= LOG_INFO;
184
openlog(sysvar_logging_syslog_ident,
185
LOG_PID, syslog_facility);
187
l->logging_pre= NULL;
188
l->logging_post= logging_syslog_func_post;
193
static int logging_syslog_plugin_deinit(void *p)
195
logging_st *l= (logging_st *) p;
197
l->logging_pre= NULL;
198
l->logging_post= NULL;
203
static DRIZZLE_SYSVAR_BOOL(
205
sysvar_logging_syslog_enable,
207
N_("Enable logging"),
208
NULL, /* check func */
209
NULL, /* update func */
210
false /* default */);
212
static DRIZZLE_SYSVAR_STR(
214
sysvar_logging_syslog_ident,
217
NULL, /* check func */
218
NULL, /* update func*/
219
"drizzled" /* default */);
221
static DRIZZLE_SYSVAR_STR(
223
sysvar_logging_syslog_facility,
225
N_("Syslog Facility"),
226
NULL, /* check func */
227
NULL, /* update func*/
228
"local0" /* default */); // local0 is what PostGreSQL uses by default
230
static DRIZZLE_SYSVAR_STR(
232
sysvar_logging_syslog_priority,
234
N_("Syslog Priority"),
235
NULL, /* check func */
236
NULL, /* update func*/
237
"info" /* default */);
239
static DRIZZLE_SYSVAR_ULONG(
241
sysvar_logging_syslog_threshold_slow,
243
N_("Threshold for logging slow queries, in microseconds"),
244
NULL, /* check func */
245
NULL, /* update func */
251
static DRIZZLE_SYSVAR_ULONG(
252
threshold_big_resultset,
253
sysvar_logging_syslog_threshold_big_resultset,
255
N_("Threshold for logging big queries, for rows returned"),
256
NULL, /* check func */
257
NULL, /* update func */
263
static DRIZZLE_SYSVAR_ULONG(
264
threshold_big_examined,
265
sysvar_logging_syslog_threshold_big_examined,
267
N_("Threshold for logging big queries, for rows examined"),
268
NULL, /* check func */
269
NULL, /* update func */
275
static struct st_mysql_sys_var* logging_syslog_system_variables[]= {
276
DRIZZLE_SYSVAR(enable),
277
DRIZZLE_SYSVAR(ident),
278
DRIZZLE_SYSVAR(facility),
279
DRIZZLE_SYSVAR(priority),
280
DRIZZLE_SYSVAR(threshold_slow),
281
DRIZZLE_SYSVAR(threshold_big_resultset),
282
DRIZZLE_SYSVAR(threshold_big_examined),
286
drizzle_declare_plugin(logging_syslog)
288
DRIZZLE_LOGGER_PLUGIN,
291
"Mark Atwood <mark@fallenpegasus.com>",
294
logging_syslog_plugin_init,
295
logging_syslog_plugin_deinit,
296
NULL, /* status variables */
297
logging_syslog_system_variables,
300
drizzle_declare_plugin_end;