~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to plugin/logging_syslog/logging_syslog.cc

  • Committer: Mark Atwood
  • Date: 2010-06-24 03:15:21 UTC
  • mto: (1637.2.4 build)
  • mto: This revision was merged to the branch mainline in revision 1639.
  • Revision ID: me@mark.atwood.name-20100624031521-gafmppfbf5afm68w
new syslog module, with plugins for query log, error message, and SYSLOG() function

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* -*- mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; -*-
2
 
 *  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
3
 
 *
4
 
 *  Copyright (C) 2009 Sun Microsystems
5
 
 *
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.
9
 
 *
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.
14
 
 *
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
18
 
 */
19
 
 
20
 
#include "config.h"
21
 
#include <drizzled/plugin/logging.h>
22
 
#include <drizzled/gettext.h>
23
 
#include <drizzled/session.h>
24
 
 
25
 
#ifdef __sun
26
 
# include <syslog.h>
27
 
# include <plugin/logging_syslog/names.h>
28
 
#else
29
 
# define SYSLOG_NAMES 1
30
 
# include <syslog.h>
31
 
#endif
32
 
 
33
 
#include <stdarg.h>
34
 
#include <limits.h>
35
 
#include <sys/time.h>
36
 
#include <sys/types.h>
37
 
#include <sys/stat.h>
38
 
#include <fcntl.h>
39
 
 
40
 
 
41
 
using namespace drizzled;
42
 
 
43
 
static bool sysvar_logging_syslog_enable= false;
44
 
static char* sysvar_logging_syslog_ident= NULL;
45
 
static char* sysvar_logging_syslog_facility= NULL;
46
 
static char* sysvar_logging_syslog_priority= NULL;
47
 
static ulong sysvar_logging_syslog_threshold_slow= 0;
48
 
static ulong sysvar_logging_syslog_threshold_big_resultset= 0;
49
 
static ulong sysvar_logging_syslog_threshold_big_examined= 0;
50
 
 
51
 
/* stolen from mysys/my_getsystime
52
 
   until the Session has a good utime "now" we can use
53
 
   will have to use this instead */
54
 
 
55
 
static uint64_t get_microtime()
56
 
{
57
 
#if defined(HAVE_GETHRTIME)
58
 
  return gethrtime()/1000;
59
 
#else
60
 
  uint64_t newtime;
61
 
  struct timeval t;
62
 
  /* loop is because gettimeofday may fail on some systems */
63
 
  while (gettimeofday(&t, NULL) != 0) {}
64
 
  newtime= (uint64_t)t.tv_sec * 1000000 + t.tv_usec;
65
 
  return newtime;
66
 
#endif
67
 
}
68
 
 
69
 
class Logging_syslog: public drizzled::plugin::Logging
70
 
{
71
 
 
72
 
  int syslog_facility;
73
 
  int syslog_priority;
74
 
 
75
 
public:
76
 
 
77
 
  Logging_syslog()
78
 
    : drizzled::plugin::Logging("Logging_syslog"),
79
 
      syslog_facility(-1), syslog_priority(-1)
80
 
  {
81
 
 
82
 
    for (int ndx= 0; facilitynames[ndx].c_name; ndx++)
83
 
    {
84
 
      if (strcasecmp(facilitynames[ndx].c_name, sysvar_logging_syslog_facility) == 0)
85
 
      {
86
 
        syslog_facility= facilitynames[ndx].c_val;
87
 
        break;
88
 
      }
89
 
    }
90
 
    if (syslog_facility == -1)
91
 
    {
92
 
      errmsg_printf(ERRMSG_LVL_WARN,
93
 
                    _("syslog facility \"%s\" not known, using \"local0\""),
94
 
                    sysvar_logging_syslog_facility);
95
 
      syslog_facility= LOG_LOCAL0;
96
 
    }
97
 
 
98
 
    for (int ndx= 0; prioritynames[ndx].c_name; ndx++)
99
 
    {
100
 
      if (strcasecmp(prioritynames[ndx].c_name, sysvar_logging_syslog_priority) == 0)
101
 
      {
102
 
        syslog_priority= prioritynames[ndx].c_val;
103
 
        break;
104
 
      }
105
 
    }
106
 
    if (syslog_priority == -1)
107
 
    {
108
 
      errmsg_printf(ERRMSG_LVL_WARN,
109
 
                    _("syslog priority \"%s\" not known, using \"info\""),
110
 
                    sysvar_logging_syslog_priority);
111
 
      syslog_priority= LOG_INFO;
112
 
    }
113
 
 
114
 
    openlog(sysvar_logging_syslog_ident,
115
 
            LOG_PID, syslog_facility);
116
 
  }
117
 
 
118
 
  ~Logging_syslog()
119
 
  {
120
 
    closelog();
121
 
  }
122
 
 
123
 
  virtual bool post (Session *session)
124
 
  {
125
 
    assert(session != NULL);
126
 
  
127
 
    // return if not enabled or query was too fast or resultset was too small
128
 
    if (sysvar_logging_syslog_enable == false)
129
 
      return false;
130
 
    if (session->sent_row_count < sysvar_logging_syslog_threshold_big_resultset)
131
 
      return false;
132
 
    if (session->examined_row_count < sysvar_logging_syslog_threshold_big_examined)
133
 
      return false;
134
 
  
135
 
    /* TODO, the session object should have a "utime command completed"
136
 
       inside itself, so be more accurate, and so this doesnt have to
137
 
       keep calling current_utime, which can be slow */
138
 
  
139
 
    uint64_t t_mark= get_microtime();
140
 
  
141
 
    if ((t_mark - session->start_utime) < sysvar_logging_syslog_threshold_slow)
142
 
      return false;
143
 
  
144
 
    /* to avoid trying to printf %s something that is potentially NULL */
145
 
  
146
 
    const char *dbs= session->db.empty() ? "" : session->db.c_str();
147
 
  
148
 
    const char *qys= (! session->getQueryString().empty()) ? session->getQueryString().c_str() : "";
149
 
    int qyl= 0;
150
 
    if (qys)
151
 
      qyl= session->getQueryLength();
152
 
    
153
 
    syslog(syslog_priority,
154
 
           "thread_id=%ld query_id=%ld"
155
 
           " db=\"%.*s\""
156
 
           " query=\"%.*s\""
157
 
           " command=\"%.*s\""
158
 
           " t_connect=%lld t_start=%lld t_lock=%lld"
159
 
           " rows_sent=%ld rows_examined=%ld"
160
 
           " tmp_table=%ld total_warn_count=%ld\n",
161
 
           (unsigned long) session->thread_id,
162
 
           (unsigned long) session->getQueryId(),
163
 
           (int)session->db.length(), dbs,
164
 
           qyl, qys,
165
 
           (int) command_name[session->command].length,
166
 
           command_name[session->command].str,
167
 
           (unsigned long long) (t_mark - session->getConnectMicroseconds()),
168
 
           (unsigned long long) (t_mark - session->start_utime),
169
 
           (unsigned long long) (t_mark - session->utime_after_lock),
170
 
           (unsigned long) session->sent_row_count,
171
 
           (unsigned long) session->examined_row_count,
172
 
           (unsigned long) session->tmp_table,
173
 
           (unsigned long) session->total_warn_count);
174
 
  
175
 
    return false;
176
 
  }
177
 
};
178
 
 
179
 
static Logging_syslog *handler= NULL;
180
 
 
181
 
static int logging_syslog_plugin_init(drizzled::module::Context &context)
182
 
{
183
 
  handler= new Logging_syslog();
184
 
  context.add(handler);
185
 
 
186
 
  return 0;
187
 
}
188
 
 
189
 
static DRIZZLE_SYSVAR_BOOL(
190
 
  enable,
191
 
  sysvar_logging_syslog_enable,
192
 
  PLUGIN_VAR_NOCMDARG,
193
 
  N_("Enable logging to syslog"),
194
 
  NULL, /* check func */
195
 
  NULL, /* update func */
196
 
  false /* default */);
197
 
 
198
 
static DRIZZLE_SYSVAR_STR(
199
 
  ident,
200
 
  sysvar_logging_syslog_ident,
201
 
  PLUGIN_VAR_READONLY,
202
 
  N_("Syslog Ident"),
203
 
  NULL, /* check func */
204
 
  NULL, /* update func*/
205
 
  "drizzled" /* default */);
206
 
 
207
 
static DRIZZLE_SYSVAR_STR(
208
 
  facility,
209
 
  sysvar_logging_syslog_facility,
210
 
  PLUGIN_VAR_READONLY,
211
 
  N_("Syslog Facility"),
212
 
  NULL, /* check func */
213
 
  NULL, /* update func*/
214
 
  "local0" /* default */);  // local0 is what PostGreSQL uses by default
215
 
 
216
 
static DRIZZLE_SYSVAR_STR(
217
 
  priority,
218
 
  sysvar_logging_syslog_priority,
219
 
  PLUGIN_VAR_READONLY,
220
 
  N_("Syslog Priority"),
221
 
  NULL, /* check func */
222
 
  NULL, /* update func*/
223
 
  "info" /* default */);
224
 
 
225
 
static DRIZZLE_SYSVAR_ULONG(
226
 
  threshold_slow,
227
 
  sysvar_logging_syslog_threshold_slow,
228
 
  PLUGIN_VAR_OPCMDARG,
229
 
  N_("Threshold for logging slow queries, in microseconds"),
230
 
  NULL, /* check func */
231
 
  NULL, /* update func */
232
 
  0, /* default */
233
 
  0, /* min */
234
 
  ULONG_MAX, /* max */
235
 
  0 /* blksiz */);
236
 
 
237
 
static DRIZZLE_SYSVAR_ULONG(
238
 
  threshold_big_resultset,
239
 
  sysvar_logging_syslog_threshold_big_resultset,
240
 
  PLUGIN_VAR_OPCMDARG,
241
 
  N_("Threshold for logging big queries, for rows returned"),
242
 
  NULL, /* check func */
243
 
  NULL, /* update func */
244
 
  0, /* default */
245
 
  0, /* min */
246
 
  ULONG_MAX, /* max */
247
 
  0 /* blksiz */);
248
 
 
249
 
static DRIZZLE_SYSVAR_ULONG(
250
 
  threshold_big_examined,
251
 
  sysvar_logging_syslog_threshold_big_examined,
252
 
  PLUGIN_VAR_OPCMDARG,
253
 
  N_("Threshold for logging big queries, for rows examined"),
254
 
  NULL, /* check func */
255
 
  NULL, /* update func */
256
 
  0, /* default */
257
 
  0, /* min */
258
 
  ULONG_MAX, /* max */
259
 
  0 /* blksiz */);
260
 
 
261
 
static drizzle_sys_var* logging_syslog_system_variables[]= {
262
 
  DRIZZLE_SYSVAR(enable),
263
 
  DRIZZLE_SYSVAR(ident),
264
 
  DRIZZLE_SYSVAR(facility),
265
 
  DRIZZLE_SYSVAR(priority),
266
 
  DRIZZLE_SYSVAR(threshold_slow),
267
 
  DRIZZLE_SYSVAR(threshold_big_resultset),
268
 
  DRIZZLE_SYSVAR(threshold_big_examined),
269
 
  NULL
270
 
};
271
 
 
272
 
DRIZZLE_DECLARE_PLUGIN
273
 
{
274
 
  DRIZZLE_VERSION_ID,
275
 
  "logging_syslog",
276
 
  "0.2",
277
 
  "Mark Atwood <mark@fallenpegasus.com>",
278
 
  N_("Log to syslog"),
279
 
  PLUGIN_LICENSE_GPL,
280
 
  logging_syslog_plugin_init,
281
 
  logging_syslog_system_variables,
282
 
  NULL
283
 
}
284
 
DRIZZLE_DECLARE_PLUGIN_END;