summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Makefile.am2
-rw-r--r--ommysql.c275
-rw-r--r--ommysql.h45
-rw-r--r--omusrmsg.c2
-rw-r--r--syslogd-types.h9
-rw-r--r--syslogd.c241
6 files changed, 338 insertions, 236 deletions
diff --git a/Makefile.am b/Makefile.am
index 3da81d7f..b1c85466 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -7,7 +7,7 @@ rfc3195d_SOURCES=rfc3195d.c rsyslog.h
man_MANS = rfc3195d.8 rklogd.8 rsyslogd.8 rsyslog.conf.5
-rsyslogd_SOURCES=syslogd.c pidfile.c template.c outchannel.c stringbuf.c srUtils.c parse.c syslogd-types.h template.h outchannel.h syslogd.h stringbuf.h parse.h srUtils.h liblogging-stub.h net.h msg.c msg.h omshell.c omshell.h omusrmsg.c omusrmsg.h
+rsyslogd_SOURCES=syslogd.c pidfile.c template.c outchannel.c stringbuf.c srUtils.c parse.c syslogd-types.h template.h outchannel.h syslogd.h stringbuf.h parse.h srUtils.h liblogging-stub.h net.h msg.c msg.h omshell.c omshell.h omusrmsg.c omusrmsg.h ommysql.c ommysql.h
rsyslogd_CPPFLAGS=$(mysql_includes)
rsyslogd_LDADD=$(mysql_libs) $(zlib_libs) $(pthreads_libs)
diff --git a/ommysql.c b/ommysql.c
new file mode 100644
index 00000000..eda2490a
--- /dev/null
+++ b/ommysql.c
@@ -0,0 +1,275 @@
+/* omusrmsg.c
+ * This is the implementation of the build-in output module for MySQL.
+ *
+ * File begun on 2007-07-20 by RGerhards (extracted from syslogd.c)
+ * This file is under development and has not yet arrived at being fully
+ * self-contained and a real object. So far, it is mostly an excerpt
+ * of the "old" message code without any modifications. However, it
+ * helps to have things at the right place one we go to the meat of it.
+ *
+ * Copyright 2007 Rainer Gerhards and Adiscon GmbH.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * A copy of the GPL can be found in the file "COPYING" in this distribution.
+ */
+#include "config.h"
+#ifdef WITH_DB
+#include <stdio.h>
+#include <stdarg.h>
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+#include <signal.h>
+#include <errno.h>
+#include <time.h>
+#include "rsyslog.h"
+#include "syslogd.h"
+#include "syslogd-types.h"
+#include "srUtils.h"
+#include "ommysql.h"
+#include "mysql/mysql.h"
+#include "mysql/errmsg.h"
+
+
+/**
+ * DBErrorHandler
+ *
+ * Call this function if an db error apears. It will initiate
+ * the "delay" handling which stopped the db logging for some
+ * time.
+ *
+ * We now check if we have a valid MySQL handle. If not, we simply
+ * report an error, but can not be specific. RGerhards, 2007-01-30
+ */
+static void DBErrorHandler(register selector_t *f)
+{
+ char errMsg[512];
+
+ assert(f != NULL);
+
+ /* TODO:
+ * NO DB connection -> Can not log to DB
+ * --------------------
+ * Case 1: db server unavailable
+ * We can check after a specified time interval if the server is up.
+ * Also a reason can be a down DNS service.
+ * Case 2: uid, pwd or dbname are incorrect
+ * If this is a fault in the syslog.conf we have no chance to recover. But
+ * if it is a problem of the DB we can make a retry after some time. Possible
+ * are that the admin has not already set up the database table. Or he has not
+ * created the database user yet.
+ * Case 3: unkown error
+ * If we get an unkowon error here, we should in any case try to recover after
+ * a specified time interval.
+ *
+ * Insert failed -> Can not log to DB
+ * --------------------
+ * If the insert fails it is never a good idea to give up. Only an
+ * invalid sql sturcture (wrong template) force us to disable db
+ * logging.
+ *
+ * Think about different "delay" for different errors!
+ */
+ if(f->f_un.f_mysql.f_hmysql == NULL) {
+ logerror("unknown DB error occured - called error handler with NULL MySQL handle.");
+ } else { /* we can ask mysql for the error description... */
+ errno = 0;
+ snprintf(errMsg, sizeof(errMsg)/sizeof(char),
+ "db error (%d): %s\n", mysql_errno(f->f_un.f_mysql.f_hmysql),
+ mysql_error(f->f_un.f_mysql.f_hmysql));
+ f->f_un.f_mysql.f_iLastDBErrNo = mysql_errno(f->f_un.f_mysql.f_hmysql);
+ logerror(errMsg);
+ }
+
+ /* Enable "delay" */
+ f->f_un.f_mysql.f_timeResumeOnError = time(&f->f_un.f_mysql.f_timeResumeOnError) + _DB_DELAYTIMEONERROR ;
+}
+
+
+/**
+ * checkDBErrorState
+ *
+ * Check if we can go on with database logging or if we should wait
+ * a little bit longer. It also check if the DB hanlde is still valid.
+ * If it is necessary, it takes action to reinitiate the db connection.
+ *
+ * \ret int Returns 0 if successful (no error)
+ */
+int checkDBErrorState(register selector_t *f)
+{
+ time_t now;
+ assert(f != NULL);
+ /* dprintf("in checkDBErrorState, timeResumeOnError: %d\n", f->f_timeResumeOnError); */
+
+ /* If timeResumeOnError == 0 no error occured,
+ we can return with 0 (no error) */
+ if (f->f_un.f_mysql.f_timeResumeOnError == 0)
+ return 0;
+
+ (void) time(&now);
+ /* Now we know an error occured. We check timeResumeOnError
+ if we can process. If we have not reach the resume time
+ yet, we return an error status. */
+ if (f->f_un.f_mysql.f_timeResumeOnError > now)
+ {
+ /* dprintf("Wait time is not over yet.\n"); */
+ return 1;
+ }
+
+ /* Ok, we can try to resume the database logging. First
+ we have to reset the status (timeResumeOnError) and
+ the last error no. */
+ /* To improve this code it would be better to check
+ if we really need to reInit the db connection. If
+ only the insert failed and the db conncetcion is
+ still valid, we need no reInit.
+ Of course, if an unkown error appeared, we should
+ reInit. */
+ /* rgerhards 2004-12-08: I think it is pretty unlikely
+ * that we can re-use a connection after the error. So I guess
+ * the connection must be closed and re-opened in all cases
+ * (as it is done currently). When we come back to optimize
+ * this code, we should anyhow see if there are cases where
+ * we could keep it open. I just doubt this won't be the case.
+ * I added this comment (and did not remove Michaels) just so
+ * that we all know what we are looking for.
+ */
+ f->f_un.f_mysql.f_timeResumeOnError = 0;
+ f->f_un.f_mysql.f_iLastDBErrNo = 0;
+ reInitMySQL(f);
+ return 0;
+
+}
+
+/*
+ * The following function is responsible for initializing a
+ * MySQL connection.
+ * Initially added 2004-10-28 mmeckelein
+ */
+void initMySQL(register selector_t *f)
+{
+ int iCounter = 0;
+ assert(f != NULL);
+
+ if (checkDBErrorState(f))
+ return;
+
+ f->f_un.f_mysql.f_hmysql = mysql_init(NULL);
+ if(f->f_un.f_mysql.f_hmysql == NULL) {
+ logerror("can not initialize MySQL handle - ignoring this action");
+ /* The next statement causes a redundant message, but it is the
+ * best thing we can do in this situation. -- rgerhards, 2007-01-30
+ */
+ f->f_type = F_UNUSED;
+ } else { /* we could get the handle, now on with work... */
+ do {
+ /* Connect to database */
+ if (!mysql_real_connect(f->f_un.f_mysql.f_hmysql, f->f_un.f_mysql.f_dbsrv, f->f_un.f_mysql.f_dbuid,
+ f->f_un.f_mysql.f_dbpwd, f->f_un.f_mysql.f_dbname, 0, NULL, 0)) {
+ /* if also the second attempt failed
+ we call the error handler */
+ if(iCounter)
+ DBErrorHandler(f);
+ } else {
+ f->f_un.f_mysql.f_timeResumeOnError = 0; /* We have a working db connection */
+ dprintf("connected successfully to db\n");
+ }
+ iCounter++;
+ } while (mysql_errno(f->f_un.f_mysql.f_hmysql) && iCounter<2);
+ }
+}
+
+/*
+ * The following function is responsible for closing a
+ * MySQL connection.
+ * Initially added 2004-10-28
+ */
+void closeMySQL(register selector_t *f)
+{
+ assert(f != NULL);
+ dprintf("in closeMySQL\n");
+ if(f->f_un.f_mysql.f_hmysql != NULL) /* just to be on the safe side... */
+ mysql_close(f->f_un.f_mysql.f_hmysql);
+}
+
+/*
+ * Reconnect a MySQL connection.
+ * Initially added 2004-12-02
+ */
+void reInitMySQL(register selector_t *f)
+{
+ assert(f != NULL);
+
+ dprintf("reInitMySQL\n");
+ closeMySQL(f); /* close the current handle */
+ initMySQL(f); /* new connection */
+}
+
+
+
+/* The following function writes the current log entry
+ * to an established MySQL session.
+ * Initially added 2004-10-28 mmeckelein
+ */
+void writeMySQL(register selector_t *f)
+{
+ char *psz;
+ int iCounter=0;
+ assert(f != NULL);
+
+ iovCreate(f);
+ psz = iovAsString(f);
+
+ if (checkDBErrorState(f))
+ return;
+
+ /* Now we are trying to insert the data.
+ *
+ * If the first attampt fails we simply try a second one. If that
+ * fails too, we discard the message and enable "delay" error handling.
+ */
+ do {
+ /* query */
+ if(mysql_query(f->f_un.f_mysql.f_hmysql, psz)) {
+ /* if the second attempt fails
+ we call the error handler */
+ if(iCounter)
+ DBErrorHandler(f);
+ }
+ else {
+ /* dprintf("db insert sucessfully\n"); */
+ }
+ iCounter++;
+ } while (mysql_errno(f->f_un.f_mysql.f_hmysql) && iCounter<2);
+}
+
+/* call the shell action
+ * returns 0 if it succeeds, something else otherwise
+ */
+int doActionMySQL(selector_t *f, time_t now)
+{
+ assert(f != NULL);
+
+ f->f_time = now;
+ dprintf("\n");
+ writeMySQL(f);
+ return 0;
+}
+
+#endif /* #ifdef WITH_DB */
+/*
+ * vi:set ai:
+ */
diff --git a/ommysql.h b/ommysql.h
new file mode 100644
index 00000000..685734db
--- /dev/null
+++ b/ommysql.h
@@ -0,0 +1,45 @@
+/* omusrmsg.c
+ * These are the definitions for the build-in MySQL output module.
+ *
+ * File begun on 2007-07-13 by RGerhards (extracted from syslogd.c)
+ *
+ * Copyright 2007 Rainer Gerhards and Adiscon GmbH.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * A copy of the GPL can be found in the file "COPYING" in this distribution.
+ */
+#ifndef OMMYSQL_H_INCLUDED
+#define OMMYSQL_H_INCLUDED 1
+#ifdef WITH_DB
+
+/* prototypes */
+/* prototypes will be removed as syslogd needs no longer to directly
+ * call into the module!
+ */
+void initMySQL(register selector_t *f);
+void writeMySQL(register selector_t *f);
+void closeMySQL(register selector_t *f);
+void reInitMySQL(register selector_t *f);
+int checkDBErrorState(register selector_t *f);
+//void DBErrorHandler(register selector_t *f);
+
+int doActionMySQL(selector_t *f, time_t now);
+
+#endif /* #ifdef WITH_DB */
+#endif /* #ifndef OMMYSQL_H_INCLUDED */
+/*
+ * vi:set ai:
+ */
diff --git a/omusrmsg.c b/omusrmsg.c
index 0d914888..123cd938 100644
--- a/omusrmsg.c
+++ b/omusrmsg.c
@@ -48,7 +48,7 @@
#include "syslogd.h"
#include "syslogd-types.h"
#include "srUtils.h"
-#include "omshell.h"
+#include "omusrmsg.h"
jmp_buf ttybuf;
diff --git a/syslogd-types.h b/syslogd-types.h
index 3428db2a..c5da7da4 100644
--- a/syslogd-types.h
+++ b/syslogd-types.h
@@ -38,6 +38,15 @@
#define MAXUNAMES 20 /* maximum number of user names */
#define MAXFNAME 200 /* max file pathname length */
+#ifdef WITH_DB
+#include "mysql/mysql.h"
+#define _DB_MAXDBLEN 128 /* maximum number of db */
+#define _DB_MAXUNAMELEN 128 /* maximum number of user name */
+#define _DB_MAXPWDLEN 128 /* maximum number of user's pass */
+#define _DB_DELAYTIMEONERROR 20 /* If an error occur we stop logging until
+ a delayed time is over */
+#endif
+
/* we define our own facility and severities */
/* facility and severity codes */
diff --git a/syslogd.c b/syslogd.c
index 5411bfa4..ef80657b 100644
--- a/syslogd.c
+++ b/syslogd.c
@@ -186,11 +186,6 @@
#include <assert.h>
-#ifdef WITH_DB
-#include "mysql/mysql.h"
-#include "mysql/errmsg.h"
-#endif
-
#ifdef USE_PTHREADS
#include <pthread.h>
#endif
@@ -221,6 +216,11 @@
(sizeof(*(su)) - sizeof((su)->sun_path) + strlen((su)->sun_path))
#endif
+#ifdef WITH_DB
+#include "mysql/mysql.h"
+#include "mysql/errmsg.h"
+#endif
+
#include "rsyslog.h"
#include "template.h"
#include "outchannel.h"
@@ -232,6 +232,7 @@
#include "msg.h"
#include "omshell.h"
#include "omusrmsg.h"
+#include "ommysql.h"
/* We define our own set of syslog defintions so that we
* do not need to rely on (possibly different) implementations.
@@ -294,13 +295,6 @@ syslogCODE rs_facilitynames[] =
{ NULL, -1 }
};
-#ifdef WITH_DB
-#define _DB_MAXDBLEN 128 /* maximum number of db */
-#define _DB_MAXUNAMELEN 128 /* maximum number of user name */
-#define _DB_MAXPWDLEN 128 /* maximum number of user's pass */
-#define _DB_DELAYTIMEONERROR 20 /* If an error occur we stop logging until
- a delayed time is over */
-#endif
#ifndef UTMP_FILE
#ifdef UTMP_FILENAME
@@ -778,14 +772,6 @@ static rsRetVal cfline(char *line, register selector_t *f);
static int decode(uchar *name, struct code *codetab);
static void sighup_handler();
static void die(int sig);
-#ifdef WITH_DB
-static void initMySQL(register selector_t *f);
-static void writeMySQL(register selector_t *f);
-static void closeMySQL(register selector_t *f);
-static void reInitMySQL(register selector_t *f);
-static int checkDBErrorState(register selector_t *f);
-static void DBErrorHandler(register selector_t *f);
-#endif
static int getSubString(uchar **pSrc, char *pDst, size_t DstSize, char cSep);
static void cflineSetTemplateAndIOV(selector_t *f, char *pTemplateName);
@@ -5696,9 +5682,7 @@ void fprintlog(register selector_t *f)
#ifdef WITH_DB
case F_MYSQL:
- f->f_time = now;
- dprintf("\n");
- writeMySQL(f);
+ doActionMySQL(f, now);
break;
#endif
@@ -8174,217 +8158,6 @@ void sighup_handler()
return;
}
-#ifdef WITH_DB
-/*
- * The following function is responsible for initializing a
- * MySQL connection.
- * Initially added 2004-10-28 mmeckelein
- */
-static void initMySQL(register selector_t *f)
-{
- int iCounter = 0;
- assert(f != NULL);
-
- if (checkDBErrorState(f))
- return;
-
- f->f_un.f_mysql.f_hmysql = mysql_init(NULL);
- if(f->f_un.f_mysql.f_hmysql == NULL) {
- logerror("can not initialize MySQL handle - ignoring this action");
- /* The next statement causes a redundant message, but it is the
- * best thing we can do in this situation. -- rgerhards, 2007-01-30
- */
- f->f_type = F_UNUSED;
- } else { /* we could get the handle, now on with work... */
- do {
- /* Connect to database */
- if (!mysql_real_connect(f->f_un.f_mysql.f_hmysql, f->f_un.f_mysql.f_dbsrv, f->f_un.f_mysql.f_dbuid,
- f->f_un.f_mysql.f_dbpwd, f->f_un.f_mysql.f_dbname, 0, NULL, 0)) {
- /* if also the second attempt failed
- we call the error handler */
- if(iCounter)
- DBErrorHandler(f);
- } else {
- f->f_un.f_mysql.f_timeResumeOnError = 0; /* We have a working db connection */
- dprintf("connected successfully to db\n");
- }
- iCounter++;
- } while (mysql_errno(f->f_un.f_mysql.f_hmysql) && iCounter<2);
- }
-}
-
-/*
- * The following function is responsible for closing a
- * MySQL connection.
- * Initially added 2004-10-28
- */
-static void closeMySQL(register selector_t *f)
-{
- assert(f != NULL);
- dprintf("in closeMySQL\n");
- if(f->f_un.f_mysql.f_hmysql != NULL) /* just to be on the safe side... */
- mysql_close(f->f_un.f_mysql.f_hmysql);
-}
-
-/*
- * Reconnect a MySQL connection.
- * Initially added 2004-12-02
- */
-static void reInitMySQL(register selector_t *f)
-{
- assert(f != NULL);
-
- dprintf("reInitMySQL\n");
- closeMySQL(f); /* close the current handle */
- initMySQL(f); /* new connection */
-}
-
-/*
- * The following function writes the current log entry
- * to an established MySQL session.
- * Initially added 2004-10-28
- */
-static void writeMySQL(register selector_t *f)
-{
- char *psz;
- int iCounter=0;
- assert(f != NULL);
-
- iovCreate(f);
- psz = iovAsString(f);
-
- if (checkDBErrorState(f))
- return;
-
- /* Now we are trying to insert the data.
- *
- * If the first attampt fails we simply try a second one. If that
- * fails too, we discard the message and enable "delay" error handling.
- */
- do {
- /* query */
- if(mysql_query(f->f_un.f_mysql.f_hmysql, psz)) {
- /* if the second attempt fails
- we call the error handler */
- if(iCounter)
- DBErrorHandler(f);
- }
- else {
- /* dprintf("db insert sucessfully\n"); */
- }
- iCounter++;
- } while (mysql_errno(f->f_un.f_mysql.f_hmysql) && iCounter<2);
-}
-
-/**
- * DBErrorHandler
- *
- * Call this function if an db error apears. It will initiate
- * the "delay" handling which stopped the db logging for some
- * time.
- *
- * We now check if we have a valid MySQL handle. If not, we simply
- * report an error, but can not be specific. RGerhards, 2007-01-30
- */
-static void DBErrorHandler(register selector_t *f)
-{
- char errMsg[512];
-
- assert(f != NULL);
-
- /* TODO:
- * NO DB connection -> Can not log to DB
- * --------------------
- * Case 1: db server unavailable
- * We can check after a specified time interval if the server is up.
- * Also a reason can be a down DNS service.
- * Case 2: uid, pwd or dbname are incorrect
- * If this is a fault in the syslog.conf we have no chance to recover. But
- * if it is a problem of the DB we can make a retry after some time. Possible
- * are that the admin has not already set up the database table. Or he has not
- * created the database user yet.
- * Case 3: unkown error
- * If we get an unkowon error here, we should in any case try to recover after
- * a specified time interval.
- *
- * Insert failed -> Can not log to DB
- * --------------------
- * If the insert fails it is never a good idea to give up. Only an
- * invalid sql sturcture (wrong template) force us to disable db
- * logging.
- *
- * Think about different "delay" for different errors!
- */
- if(f->f_un.f_mysql.f_hmysql == NULL) {
- logerror("unknown DB error occured - called error handler with NULL MySQL handle.");
- } else { /* we can ask mysql for the error description... */
- errno = 0;
- snprintf(errMsg, sizeof(errMsg)/sizeof(char),
- "db error (%d): %s\n", mysql_errno(f->f_un.f_mysql.f_hmysql),
- mysql_error(f->f_un.f_mysql.f_hmysql));
- f->f_un.f_mysql.f_iLastDBErrNo = mysql_errno(f->f_un.f_mysql.f_hmysql);
- logerror(errMsg);
- }
-
- /* Enable "delay" */
- f->f_un.f_mysql.f_timeResumeOnError = time(&f->f_un.f_mysql.f_timeResumeOnError) + _DB_DELAYTIMEONERROR ;
-}
-
-/**
- * checkDBErrorState
- *
- * Check if we can go on with database logging or if we should wait
- * a little bit longer. It also check if the DB hanlde is still valid.
- * If it is necessary, it takes action to reinitiate the db connection.
- *
- * \ret int Returns 0 if successful (no error)
- */
-int checkDBErrorState(register selector_t *f)
-{
- assert(f != NULL);
- /* dprintf("in checkDBErrorState, timeResumeOnError: %d\n", f->f_timeResumeOnError); */
-
- /* If timeResumeOnError == 0 no error occured,
- we can return with 0 (no error) */
- if (f->f_un.f_mysql.f_timeResumeOnError == 0)
- return 0;
-
- (void) time(&now);
- /* Now we know an error occured. We check timeResumeOnError
- if we can process. If we have not reach the resume time
- yet, we return an error status. */
- if (f->f_un.f_mysql.f_timeResumeOnError > now)
- {
- /* dprintf("Wait time is not over yet.\n"); */
- return 1;
- }
-
- /* Ok, we can try to resume the database logging. First
- we have to reset the status (timeResumeOnError) and
- the last error no. */
- /* To improve this code it would be better to check
- if we really need to reInit the db connection. If
- only the insert failed and the db conncetcion is
- still valid, we need no reInit.
- Of course, if an unkown error appeared, we should
- reInit. */
- /* rgerhards 2004-12-08: I think it is pretty unlikely
- * that we can re-use a connection after the error. So I guess
- * the connection must be closed and re-opened in all cases
- * (as it is done currently). When we come back to optimize
- * this code, we should anyhow see if there are cases where
- * we could keep it open. I just doubt this won't be the case.
- * I added this comment (and did not remove Michaels) just so
- * that we all know what we are looking for.
- */
- f->f_un.f_mysql.f_timeResumeOnError = 0;
- f->f_un.f_mysql.f_iLastDBErrNo = 0;
- reInitMySQL(f);
- return 0;
-
-}
-
-#endif /* #ifdef WITH_DB */
/**
* getSubString