diff options
author | Rainer Gerhards <rgerhards@adiscon.com> | 2004-11-23 17:10:55 +0000 |
---|---|---|
committer | Rainer Gerhards <rgerhards@adiscon.com> | 2004-11-23 17:10:55 +0000 |
commit | fb3b06185460107ac5720b8d2b79114293cbce19 (patch) | |
tree | da441112f7b0d9e67dac96a00bbea0748c705ce7 | |
parent | fc45231d62fdb3b75d2466d8b3b8135e17252abe (diff) | |
download | rsyslog-fb3b06185460107ac5720b8d2b79114293cbce19.tar.gz rsyslog-fb3b06185460107ac5720b8d2b79114293cbce19.tar.xz rsyslog-fb3b06185460107ac5720b8d2b79114293cbce19.zip |
everything in place now to support writing to SQL
-rw-r--r-- | syslogd.c | 112 | ||||
-rw-r--r-- | template.c | 119 | ||||
-rw-r--r-- | template.h | 8 | ||||
-rw-r--r-- | test.conf | 2 |
4 files changed, 190 insertions, 51 deletions
@@ -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, @@ -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 */ @@ -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; }; @@ -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 |