Jakob Haufe <[EMAIL PROTECTED]> wrote on Sat, 1 Dec 2007 23:01:26 +0100
in [EMAIL PROTECTED]:
> Jakob Haufe <[EMAIL PROTECTED]> wrote on Sat, 1 Dec 2007 22:36:44 +0100
> in [EMAIL PROTECTED]:
>
> > The attached patch does the following:
> >
> > * add plugins/ompgsql/*
>
> Erm, yes. Maybe i should have noticed, that cvs doesn't recurse into
> new subdirectories... so here are the files for the plugins/ompgsql
> directory.
Ok, mailman doesn't like any mimetypes but text/plain... next try *grml*
pkglibdir = $(libdir)/rsyslog
pkglib_LTLIBRARIES = ompgsql.la
ompgsql_la_SOURCES = ompgsql.c ompgsql.h
ompgsql_la_CPPFLAGS = $(pgsql_cflags) -I$(srcdir)/../..
ompgsql_la_LDFLAGS = -module -avoid-version
ompgsql_la_LIBADD = $(pgsql_libs)
EXTRA_DIST = createDB.sql
CREATE DATABASE "Syslog";
\c Syslog;
CREATE TABLE SystemEvents
(
ID serial not null primary key,
CustomerID bigint,
ReceivedAt timestamp without time zone NULL,
DeviceReportedTime timestamp without time zone NULL,
Facility smallint NULL,
Priority smallint NULL,
FromHost varchar(60) NULL,
Message text,
NTSeverity int NULL,
Importance int NULL,
EventSource varchar(60),
EventUser varchar(60) NULL,
EventCategory int NULL,
EventID int NULL,
EventBinaryData text NULL,
MaxAvailable int NULL,
CurrUsage int NULL,
MinUsage int NULL,
MaxUsage int NULL,
InfoUnitID int NULL ,
SysLogTag varchar(60),
EventLogType varchar(60),
GenericFileName VarChar(60),
SystemID int NULL
);
CREATE TABLE SystemEventsProperties
(
ID serial not null primary key,
SystemEventID int NULL ,
ParamName varchar(255) NULL ,
ParamValue text NULL
);
/* ompgsql.c
* This is the implementation of the build-in output module for PgSQL.
*
* NOTE: read comments in module-template.h to understand how this file
* works!
*
* File begun on 2007-10-18 by sur5r (converted from ommysql.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.
*/
#include "config.h"
#include "rsyslog.h"
#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 <libpq-fe.h>
#include "syslogd.h"
#include "syslogd-types.h"
#include "srUtils.h"
#include "template.h"
#include "ompgsql.h"
#include "module-template.h"
/* internal structures
*/
DEF_OMOD_STATIC_DATA
typedef struct _instanceData {
PGconn *f_hpgsql; /* handle to PgSQL */
char f_dbsrv[MAXHOSTNAMELEN+1]; /* IP or hostname of DB
server*/
char f_dbname[_DB_MAXDBLEN+1]; /* DB name */
char f_dbuid[_DB_MAXUNAMELEN+1]; /* DB user */
char f_dbpwd[_DB_MAXPWDLEN+1]; /* DB user's password */
ConnStatusType eLastPgSQLStatus; /* last status from postgres */
} instanceData;
BEGINcreateInstance
CODESTARTcreateInstance
ENDcreateInstance
BEGINisCompatibleWithFeature
CODESTARTisCompatibleWithFeature
if(eFeat == sFEATURERepeatedMsgReduction)
iRet = RS_RET_OK;
ENDisCompatibleWithFeature
/* The following function is responsible for closing a
* PgSQL connection.
*/
static void closePgSQL(instanceData *pData)
{
assert(pData != NULL);
if(pData->f_hpgsql != NULL) { /* just to be on the safe side... */
PQfinish(pData->f_hpgsql);
pData->f_hpgsql = NULL;
}
}
BEGINfreeInstance
CODESTARTfreeInstance
closePgSQL(pData);
ENDfreeInstance
BEGINneedUDPSocket
CODESTARTneedUDPSocket
ENDneedUDPSocket
BEGINdbgPrintInstInfo
CODESTARTdbgPrintInstInfo
/* nothing special here */
ENDdbgPrintInstInfo
BEGINonSelectReadyWrite
CODESTARTonSelectReadyWrite
ENDonSelectReadyWrite
BEGINgetWriteFDForSelect
CODESTARTgetWriteFDForSelect
ENDgetWriteFDForSelect
/* log a database error with descriptive message.
* We 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 reportDBError(instanceData *pData, int bSilent)
{
char errMsg[512];
ConnStatusType ePgSQLStatus;
assert(pData != NULL);
dbgprintf("bSilent was %i\n", bSilent);
bSilent=0;
/* output log message */
errno = 0;
if(pData->f_hpgsql == NULL) {
logerror("unknown DB error occured - could not obtain PgSQL
handle");
} else { /* we can ask pgsql for the error description... */
ePgSQLStatus = PQstatus(pData->f_hpgsql);
snprintf(errMsg, sizeof(errMsg)/sizeof(char), "db error (%d):
%s\n", ePgSQLStatus,
PQerrorMessage(pData->f_hpgsql));
if(bSilent || ePgSQLStatus == pData->eLastPgSQLStatus)
dbgprintf("pgsql, DBError(silent): %s\n", errMsg);
else {
pData->eLastPgSQLStatus = ePgSQLStatus;
logerror(errMsg);
}
}
return;
}
/* The following function is responsible for initializing a
* PgSQL connection.
*/
static rsRetVal initPgSQL(instanceData *pData, int bSilent)
{
DEFiRet;
assert(pData != NULL);
assert(pData->f_hpgsql == NULL);
dbgprintf("host=%s dbname=%s uid=%s
pswd=%s\n",pData->f_dbsrv,pData->f_dbname,pData->f_dbuid,pData->f_dbpwd);
/*
pData->f_hmysql = mysql_init(NULL);
if(pData->f_hmysql == NULL) {
logerror("can not initialize MySQL handle");
iRet = RS_RET_SUSPENDED;
} else { / * we could get the handle, now on with work... */
/* Connect to database */
if((pData->f_hpgsql=PQsetdbLogin(pData->f_dbsrv, NULL, NULL,
NULL,
pData->f_dbname, pData->f_dbuid,
pData->f_dbpwd)) == NULL) {
reportDBError(pData, bSilent);
closePgSQL(pData); /* ignore any error we may get */
iRet = RS_RET_SUSPENDED;
}
/*}*/
return iRet;
}
/* The following function writes the current log entry
* to an established PgSQL session.
*/
rsRetVal writePgSQL(uchar *psz, instanceData *pData)
{
DEFiRet;
assert(psz != NULL);
assert(pData != NULL);
dbgprintf("writePgSQL: %s", psz);
/* try insert */
PQexec(pData->f_hpgsql, (char*)psz);
if(PQstatus(pData->f_hpgsql)!=CONNECTION_OK) {
/* error occured, try to re-init connection and retry */
closePgSQL(pData); /* close the current handle */
CHKiRet(initPgSQL(pData, 0)); /* try to re-open */
PQexec(pData->f_hpgsql, (char*)psz);
if(PQstatus(pData->f_hpgsql)!=CONNECTION_OK) { /* re-try insert
*/
/* we failed, giving up for now */
reportDBError(pData, 0);
closePgSQL(pData); /* free ressources */
ABORT_FINALIZE(RS_RET_SUSPENDED);
}
}
finalize_it:
if(iRet == RS_RET_OK) {
pData->eLastPgSQLStatus = CONNECTION_OK; /* reset error for
error supression */
}
return iRet;
}
BEGINtryResume
CODESTARTtryResume
if(pData->f_hpgsql == NULL) {
iRet = initPgSQL(pData, 1);
}
ENDtryResume
BEGINdoAction
CODESTARTdoAction
dbgprintf("\n");
iRet = writePgSQL(ppString[0], pData);
ENDdoAction
BEGINparseSelectorAct
int iPgSQLPropErr = 0;
CODESTARTparseSelectorAct
CODE_STD_STRING_REQUESTparseSelectorAct(1)
/* first check if this config line is actually for us
* The first test [*p == '>'] can be skipped if a module shall only
* support the newer slection syntax [:modname:]. This is in fact
* recommended for new modules. Please note that over time this part
* will be handled by rsyslogd itself, but for the time being it is
* a good compromise to do it at the module level.
* rgerhards, 2007-10-15
*/
dbgprintf("%p:%s\n",p,p);
if(!strncmp((char*) p, ":ompgsql:", sizeof(":ompgsql:") - 1)) {
p += strlen(":ompgsql:"); /* eat indicator sequence */
} else {
ABORT_FINALIZE(RS_RET_CONFLINE_UNPROCESSED);
}
dbgprintf("%p:%s\n",p,p);
/* ok, if we reach this point, we have something for us */
if((iRet = createInstance(&pData)) != RS_RET_OK)
goto finalize_it;
/* sur5r 2007-10-18: added support for PgSQL
* :ompgsql:server,dbname,userid,password
* Now we read the PgSQL connection properties
* and verify that the properties are valid.
*/
if(getSubString(&p, pData->f_dbsrv, MAXHOSTNAMELEN+1, ','))
iPgSQLPropErr++;
dbgprintf("%p:%s\n",p,p);
if(*pData->f_dbsrv == '\0')
iPgSQLPropErr++;
if(getSubString(&p, pData->f_dbname, _DB_MAXDBLEN+1, ','))
iPgSQLPropErr++;
if(*pData->f_dbname == '\0')
iPgSQLPropErr++;
if(getSubString(&p, pData->f_dbuid, _DB_MAXUNAMELEN+1, ','))
iPgSQLPropErr++;
if(*pData->f_dbuid == '\0')
iPgSQLPropErr++;
if(getSubString(&p, pData->f_dbpwd, _DB_MAXPWDLEN+1, ';'))
iPgSQLPropErr++;
/* now check for template
* We specify that the SQL option must be present in the template.
* This is for your own protection (prevent sql injection).
*/
if(*(p-1) == ';')
--p; /* TODO: the whole parsing of the MySQL module needs to
be re-thought - but this here
* is clean enough for the time being --
rgerhards, 2007-07-30
* kept it for pgsql -- sur5r, 2007-10-19
*/
CHKiRet(cflineParseTemplateName(&p, *ppOMSR, 0, OMSR_RQD_TPL_OPT_SQL,
(uchar*) " StdPgSQLFmt"));
/* If we detect invalid properties, we disable logging,
* because right properties are vital at this place.
* Retries make no sense.
*/
if (iPgSQLPropErr) {
logerror("Trouble with PgSQL connection properties. -PgSQL
logging disabled");
ABORT_FINALIZE(RS_RET_INVALID_PARAMS);
} else {
CHKiRet(initPgSQL(pData, 0));
}
CODE_STD_FINALIZERparseSelectorAct
ENDparseSelectorAct
BEGINmodExit
CODESTARTmodExit
ENDmodExit
BEGINqueryEtryPt
CODESTARTqueryEtryPt
CODEqueryEtryPt_STD_OMOD_QUERIES
ENDqueryEtryPt
BEGINmodInit()
CODESTARTmodInit
*ipIFVersProvided = 1; /* so far, we only support the initial
definition */
CODEmodInit_QueryRegCFSLineHdlr
ENDmodInit
/*
* vi:set ai:
*/
/* ompgsql.h
* These are the definitions for the build-in PgSQL output module.
*
* File begun on 2007-10-18 by sur5r (converted from ompgsql.h)
*
* 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 OMPGSQL_H_INCLUDED
#define OMPGSQL_H_INCLUDED 1
/* prototypes */
/* prototypes will be removed as syslogd needs no longer to directly
* call into the module!
*/
rsRetVal modInitPgSQL(int iIFVersRequested __attribute__((unused)), int
*ipIFVersProvided, rsRetVal (**pQueryEtryPt)(), rsRetVal
(*pHostQueryEtryPt)(uchar*, rsRetVal (**)()));
#endif /* #ifndef OMPGSQL_H_INCLUDED */
/*
* vi:set ai:
*/
_______________________________________________
rsyslog mailing list
http://lists.adiscon.net/mailman/listinfo/rsyslog