summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRainer Gerhards <rgerhards@adiscon.com>2004-11-23 17:10:55 +0000
committerRainer Gerhards <rgerhards@adiscon.com>2004-11-23 17:10:55 +0000
commitfb3b06185460107ac5720b8d2b79114293cbce19 (patch)
treeda441112f7b0d9e67dac96a00bbea0748c705ce7
parentfc45231d62fdb3b75d2466d8b3b8135e17252abe (diff)
downloadrsyslog-fb3b06185460107ac5720b8d2b79114293cbce19.tar.gz
rsyslog-fb3b06185460107ac5720b8d2b79114293cbce19.tar.xz
rsyslog-fb3b06185460107ac5720b8d2b79114293cbce19.zip
everything in place now to support writing to SQL
-rw-r--r--syslogd.c112
-rw-r--r--template.c119
-rw-r--r--template.h8
-rw-r--r--test.conf2
4 files changed, 190 insertions, 51 deletions
diff --git a/syslogd.c b/syslogd.c
index 81300460..e8f54cbc 100644
--- a/syslogd.c
+++ b/syslogd.c
@@ -755,33 +755,35 @@ struct msg {
#define SOURCE_STDIN 1
#define SOURCE_UNIXAF 2
#define SOURCE_INET 3
-/**/ short iSeverity; /* the severity 0..7 */
-/**/ char *pszSeverity; /* severity as string... */
-/**/ int iLenSeverity; /* ... and its length. */
-/**/ int iFacility; /* Facility code (up to 2^32-1) */
-/**/ char *pszFacility; /* Facility as string... */
-/**/ int iLenFacility; /* ... and its length. */
-/**/ char *pszPRI; /* the PRI as a string */
-/**/ int iLenPRI; /* and its length */
-/**/ char *pszRawMsg; /* message as it was received on the
+ short iSeverity; /* the severity 0..7 */
+ char *pszSeverity; /* severity as string... */
+ int iLenSeverity; /* ... and its length. */
+ int iFacility; /* Facility code (up to 2^32-1) */
+ char *pszFacility; /* Facility as string... */
+ int iLenFacility; /* ... and its length. */
+ char *pszPRI; /* the PRI as a string */
+ int iLenPRI; /* and its length */
+ char *pszRawMsg; /* message as it was received on the
* wire. This is important in case we
* need to preserve cryptographic verifiers.
*/
-/**/ int iLenRawMsg; /* length of raw message */
-/**/ char *pszMSG; /* the MSG part itself */
-/**/ int iLenMSG; /* Length of the MSG part */
-/**/ char *pszUxTradMsg; /* the traditional UNIX message */
-/**/ int iLenUxTradMsg;/* Length of the traditional UNIX message */
-/**/ char *pszTAG; /* pointer to tag value */
-/**/ int iLenTAG; /* Length of the TAG part */
-/**/ char *pszHOSTNAME; /* HOSTNAME from syslog message */
-/**/ int iLenHOSTNAME; /* Length of HOSTNAME */
-/**/ char *pszRcvFrom; /* System message was received from */
-/**/ int iLenRcvFrom; /* Length of pszRcvFrom */
-/**/ struct syslogTime tRcvdAt;/* time the message entered this program */
-/**/ char *pszRcvdAt3164; /* time as RFC3164 formatted string (always 15 chracters) */
-/**/ struct syslogTime tTIMESTAMP;/* (parsed) value of the timestamp */
-/**/ char *pszTIMESTAMP3164; /* TIMESTAMP as RFC3164 formatted string (always 15 chracters) */
+ int iLenRawMsg; /* length of raw message */
+ char *pszMSG; /* the MSG part itself */
+ int iLenMSG; /* Length of the MSG part */
+ char *pszUxTradMsg; /* the traditional UNIX message */
+ int iLenUxTradMsg;/* Length of the traditional UNIX message */
+ char *pszTAG; /* pointer to tag value */
+ int iLenTAG; /* Length of the TAG part */
+ char *pszHOSTNAME; /* HOSTNAME from syslog message */
+ int iLenHOSTNAME; /* Length of HOSTNAME */
+ char *pszRcvFrom; /* System message was received from */
+ int iLenRcvFrom; /* Length of pszRcvFrom */
+ struct syslogTime tRcvdAt;/* time the message entered this program */
+ char *pszRcvdAt3164; /* time as RFC3164 formatted string (always 15 chracters) */
+ char *pszRcvdAt_MySQL; /* rcvdAt as MySQL formatted string (always 14 chracters) */
+ struct syslogTime tTIMESTAMP;/* (parsed) value of the timestamp */
+ char *pszTIMESTAMP3164; /* TIMESTAMP as RFC3164 formatted string (always 15 chracters) */
+ char *pszTIMESTAMP_MySQL;/* TIMESTAMP as MySQL formatted string (always 14 chracters) */
};
/*
@@ -1189,7 +1191,6 @@ static int srSLMGParseTIMESTAMP3164(struct syslogTime *pTime, unsigned char* psz
* END CODE-LIBLOGGING *
*******************************************************************/
-#ifdef WITH_DB
/**
* Format a syslogTimestamp into format required by MySQL.
* We are using the 14 digits format. For example 20041111122600
@@ -1213,7 +1214,6 @@ int formatTimestampToMySQL(struct syslogTime *ts, char* pDst, size_t iLenDst)
ts->year, ts->month, ts->day, ts->hour, ts->minute, ts->second));
}
-#endif
/**
* Format a syslogTimestamp to a RFC3164 timestamp sring.
@@ -1374,8 +1374,12 @@ void MsgDestruct(struct msg * pM)
free(pM->pszSeverity);
if(pM->pszRcvdAt3164 != NULL)
free(pM->pszRcvdAt3164);
+ if(pM->pszRcvdAt_MySQL != NULL)
+ free(pM->pszRcvdAt_MySQL);
if(pM->pszTIMESTAMP3164 != NULL)
free(pM->pszTIMESTAMP3164);
+ if(pM->pszTIMESTAMP_MySQL != NULL)
+ free(pM->pszTIMESTAMP_MySQL);
if(pM->pszPRI != NULL)
free(pM->pszPRI);
free(pM);
@@ -1448,19 +1452,50 @@ char *getPRI(struct msg *pM)
}
-char *getTimeReported(struct msg *pM)
+char *getTimeReported(struct msg *pM, enum tplFormatTypes eFmt)
{
if(pM == NULL)
return "";
- if(pM->pszTIMESTAMP3164 == NULL) {
- if((pM->pszTIMESTAMP3164 = malloc(16)) == NULL) return "";
- formatTimestamp3164(&pM->tTIMESTAMP, pM->pszTIMESTAMP3164, 16);
+ switch(eFmt) {
+ case tplFmtDefault:
+ if(pM->pszTIMESTAMP3164 == NULL) {
+ if((pM->pszTIMESTAMP3164 = malloc(16)) == NULL) return "";
+ formatTimestamp3164(&pM->tTIMESTAMP, pM->pszTIMESTAMP3164, 16);
+ }
+ return(pM->pszTIMESTAMP3164);
+ case tplFmtMySQLDate:
+ if(pM->pszTIMESTAMP_MySQL == NULL) {
+ if((pM->pszTIMESTAMP_MySQL = malloc(15)) == NULL) return "";
+ formatTimestampToMySQL(&pM->tTIMESTAMP, pM->pszTIMESTAMP_MySQL, 15);
+ }
+ return(pM->pszTIMESTAMP_MySQL);
}
+ return "INVALID eFmt OPTION!";
+}
+char *getTimeGenerated(struct msg *pM, enum tplFormatTypes eFmt)
+{
+ if(pM == NULL)
+ return "";
- return(pM->pszTIMESTAMP3164);
+ switch(eFmt) {
+ case tplFmtDefault:
+ if(pM->pszRcvdAt3164 == NULL) {
+ if((pM->pszRcvdAt3164 = malloc(16)) == NULL) return "";
+ formatTimestamp3164(&pM->tRcvdAt, pM->pszRcvdAt3164, 16);
+ }
+ return(pM->pszRcvdAt3164);
+ case tplFmtMySQLDate:
+ if(pM->pszRcvdAt_MySQL == NULL) {
+ if((pM->pszRcvdAt_MySQL = malloc(15)) == NULL) return "";
+ formatTimestampToMySQL(&pM->tRcvdAt, pM->pszRcvdAt_MySQL, 15);
+ }
+ return(pM->pszRcvdAt_MySQL);
+ }
+ return "INVALID eFmt OPTION!";
}
+#if 0
char *getTimeGenerated(struct msg *pM)
{
@@ -1474,7 +1509,7 @@ char *getTimeGenerated(struct msg *pM)
return(pM->pszRcvdAt3164);
}
-
+#endif
char *getSeverity(struct msg *pM)
{
@@ -1719,12 +1754,15 @@ int MsgSetRawMsg(struct msg *pMsg, char* pszRawMsg)
* to us ;)
* rgerhards 2004-11-18
*/
-char *MsgGetProp(struct msg *pMsg, char *pName)
+char *MsgGetProp(struct msg *pMsg, struct templateEntry *pTpe)
{
+ char *pName;
char *pRes; /* result pointer */
assert(pMsg != NULL);
- assert(pName != NULL);
+ assert(pTpe != NULL);
+
+ pName = pTpe->data.field.pPropRepl;
/* sometimes there are aliases to the original MonitoWare
* property names. These come after || in the ifs below. */
@@ -1746,10 +1784,10 @@ char *MsgGetProp(struct msg *pMsg, char *pName)
} else if(!strcmp(pName, "syslogpriority")) {
pRes = getSeverity(pMsg);
} else if(!strcmp(pName, "timegenerated")) {
- pRes = getTimeGenerated(pMsg);
+ pRes = getTimeGenerated(pMsg, pTpe->data.field.eDateFormat);
} else if(!strcmp(pName, "timereported")
|| !strcmp(pName, "TIMESTAMP")) {
- pRes = getTimeReported(pMsg);
+ pRes = getTimeReported(pMsg, pTpe->data.field.eDateFormat);
} else {
pRes = "INVALID PROPERTY NAME"; /* NULL;*/
}
@@ -2966,7 +3004,7 @@ void iovCreate(struct filed *f)
++v;
++iIOVused;
} else if(pTpe->eEntryType == FIELD) {
- v->iov_base = MsgGetProp(pMsg, pTpe->data.field.pPropRepl);
+ v->iov_base = MsgGetProp(pMsg, pTpe);
v->iov_len = strlen(v->iov_base);
/* TODO: performance optimize - can we obtain the length? */
/* we now need to check if we should use SQL option. In this case,
diff --git a/template.c b/template.c
index 3ddc8e24..1bb61157 100644
--- a/template.c
+++ b/template.c
@@ -158,13 +158,60 @@ static int do_Constant(char **pp, struct template *pTpl)
}
+/* Helper to do_Parameter(). This parses the formatting options
+ * specified in a template variable. It returns the passed-in pointer
+ * updated to the next processed character.
+ */
+static void doOptions(char **pp, struct templateEntry *pTpe)
+{
+ register char *p;
+ char Buf[64];
+ int i;
+
+ assert(pp != NULL);
+ assert(*pp != NULL);
+ assert(pTpe != NULL);
+
+ p = *pp;
+
+ while(*p && *p != '%') {
+ /* outer loop - until end of options */
+ i = 0;
+ while((i < sizeof(Buf) / sizeof(char)) &&
+ *p && *p != '%' && *p != ',') {
+ /* inner loop - until end of ONE option */
+ Buf[i++] = tolower(*p);
+ ++p;
+ }
+ Buf[i] = '\0'; /* terminate */
+ /* check if we need to skip oversize option */
+ while(*p && *p != '%' && *p != ',')
+ ++p; /* just skip */
+ /* OK, we got the option, so now lets look what
+ * it tells us...
+ */
+ if(!strcmp(Buf, "date-mysql")) {
+ pTpe->data.field.eDateFormat = tplFmtMySQLDate;
+ } else if(!strcmp(Buf, "lowercase")) {
+ pTpe->data.field.eCaseConv = tplCaseConvLower;
+ } else if(!strcmp(Buf, "uppercase")) {
+ pTpe->data.field.eCaseConv = tplCaseConvUpper;
+ } else {
+ dprintf("Invalid field option '%s' specified - ignored.\n", Buf);
+ }
+ }
+
+ *pp = p;
+}
+
+
/* helper to tplAddLine. Parses a parameter and generates
* the necessary structure.
* returns: 0 - ok, 1 - failure
*/
static int do_Parameter(char **pp, struct template *pTpl)
{
- register char *p;
+ char *p;
sbStrBObj *pStrB;
struct templateEntry *pTpe;
@@ -176,20 +223,48 @@ static int do_Parameter(char **pp, struct template *pTpl)
if((pStrB = sbStrBConstruct()) == NULL)
return 1;
- while(*p && *p != '%') {
- sbStrBAppendChar(pStrB, *p++);
- }
- if(*p) ++p; /* eat '%' */
- /* now store param */
if((pTpe = tpeConstruct(pTpl)) == NULL) {
/* TODO: add handler */
dprintf("Could not allocate memory for template parameter!\n");
return 1;
}
pTpe->eEntryType = FIELD;
+
+ while(*p && *p != '%' && *p != ':') {
+ sbStrBAppendChar(pStrB, *p++);
+ }
+
+ /* got the name*/
pTpe->data.field.pPropRepl = sbStrBFinish(pStrB);
+
+ /* check frompos */
+ if(*p == ':') {
+ ++p; /* eat ':' */
+ while(*p && *p != '%' && *p != ':') {
+ /* for now, just skip it */
+ ++p;
+ }
+ }
+
+ /* check topos */
+ if(*p == ':') {
+ ++p; /* eat ':' */
+ while(*p && *p != '%' && *p != ':') {
+ /* for now, just skip it */
+ ++p;
+ }
+ }
+
+ /* check options */
+ if(*p == ':') {
+ ++p; /* eat ':' */
+ doOptions(&p, pTpe);
+ }
+
+ if(*p) ++p; /* eat '%' */
+
*pp = p;
return 0;
}
@@ -359,17 +434,35 @@ void tplPrintList(void)
while(pTpe != NULL) {
dprintf("\tEntry(%x): type %d, ", (unsigned) pTpe, pTpe->eEntryType);
switch(pTpe->eEntryType) {
- case UNDEFINED:
- dprintf("(UNDEFINED)\n");
+ case UNDEFINED:
+ dprintf("(UNDEFINED)");
+ break;
+ case CONSTANT:
+ dprintf("(CONSTANT), value: '%s'",
+ pTpe->data.constant.pConstant);
+ break;
+ case FIELD:
+ dprintf("(FIELD), value: '%s' ", pTpe->data.field.pPropRepl);
+ switch(pTpe->data.field.eDateFormat) {
+ case tplFmtDefault:
break;
- case CONSTANT:
- dprintf("(CONSTANT), value: '%s'\n",
- pTpe->data.constant.pConstant);
+ case tplFmtMySQLDate:
+ dprintf("[Format as MySQL-Date] ");
break;
- case FIELD:
- dprintf("(FIELD), value: '%s'\n", pTpe->data.field.pPropRepl);
+ }
+ switch(pTpe->data.field.eCaseConv) {
+ case tplCaseConvNo:
break;
+ case tplCaseConvLower:
+ dprintf("[Converted to Lower Case] ");
+ break;
+ case tplCaseConvUpper:
+ dprintf("[Converted to Upper Case] ");
+ break;
+ }
+ break;
}
+ dprintf("\n");
pTpe = pTpe->pNext;
}
pTpl = pTpl->pNext; /* done, go next */
diff --git a/template.h b/template.h
index 52869761..5f09dd8d 100644
--- a/template.h
+++ b/template.h
@@ -18,6 +18,8 @@ struct template {
};
enum EntryTypes { UNDEFINED = 0, CONSTANT = 1, FIELD = 2 };
+enum tplFormatTypes { tplFmtDefault = 0, tplFmtMySQLDate = 1 };
+enum tplFormatCaseConvTypes { tplCaseConvNo = 0, tplCaseConvUpper = 1, tplCaseConvLower = 2 };
/* a specific parse entry */
struct templateEntry {
@@ -30,6 +32,12 @@ struct templateEntry {
} constant;
struct {
char *pPropRepl; /* pointer to property replacer string */
+ unsigned iFromPos; /* for partial strings only chars from this position ... */
+ unsigned iToPos; /* up to that one... */
+ enum tplFormatTypes eDateFormat;
+ enum tplFormatCaseConvTypes eCaseConv;
+ struct {
+ } options; /* options as bit fields */
} field;
} data;
};
diff --git a/test.conf b/test.conf
index 82cf2150..1957f53d 100644
--- a/test.conf
+++ b/test.conf
@@ -23,7 +23,7 @@ $template RFC3164fmt,"<%PRI%>%TIMESTAMP% %HOSTNAME% %syslogtag%%msg%"
#$template precise,"%syslogpriority%,%syslogfacility%,%timegenerated::fulltime%,%HOSTNAME%,%syslogtag%,%msg%\n",1024
$template usermsg," %syslogtag%%msg%\n\r"
$template wallmsg,"\r\n\7Message from syslogd@%HOSTNAME% at %timegenerated% ...\r\n %syslogtag%%msg%\n\r"
-$template MySQLInsert,"insert iut, msg values (1, '%msg%') into systemevents", SQL
+$template MySQLInsert,"insert iut, message, receivedat values (1, '%msg:::UPPERCASE%', '%timegenerated:::date-mysql%') into systemevents", SQL
# Selector lines are now modified
# The "action" (e.g. file logging) can be followed