mirror of
https://github.com/rsyslog/rsyslog.git
synced 2026-08-30 14:00:17 +02:00
added support for field-based text extraction in the property replacer.
This is untested so far (the evening came quicker than anticipated ;))
This commit is contained in:
parent
e3a271c816
commit
cb4ebecb2f
3
NEWS
3
NEWS
@ -1,11 +1,12 @@
|
|||||||
---------------------------------------------------------------------------
|
---------------------------------------------------------------------------
|
||||||
Version 1.12.2 (RGer), 2005-11-??
|
Version 1.12.2 (RGer), 2005-12-??
|
||||||
- fixed a bug in the RFC 3339 date formater. An extra space was added
|
- fixed a bug in the RFC 3339 date formater. An extra space was added
|
||||||
after the actual timestamp
|
after the actual timestamp
|
||||||
- added support for providing high-precision RFC3339 timestamps for
|
- added support for providing high-precision RFC3339 timestamps for
|
||||||
(rsyslogd-)internally-generated messages
|
(rsyslogd-)internally-generated messages
|
||||||
- very (!) experimental support for syslog-protocol internet draft
|
- very (!) experimental support for syslog-protocol internet draft
|
||||||
added
|
added
|
||||||
|
- added support for field-extracting in the property replacer
|
||||||
---------------------------------------------------------------------------
|
---------------------------------------------------------------------------
|
||||||
Version 1.12.1 (RGer), 2005-11-23
|
Version 1.12.1 (RGer), 2005-11-23
|
||||||
- made multithreading work with BSD. Some signal-handling needed to be
|
- made multithreading work with BSD. Some signal-handling needed to be
|
||||||
|
|||||||
68
syslogd.c
68
syslogd.c
@ -2670,7 +2670,6 @@ static rsRetVal aquirePROCIDFromTAG(struct msg *pM)
|
|||||||
register int i;
|
register int i;
|
||||||
int iRet;
|
int iRet;
|
||||||
|
|
||||||
dprintf("PROCIDFromTAG: in\n");
|
|
||||||
assert(pM != NULL);
|
assert(pM != NULL);
|
||||||
if(pM->pCSPROCID != NULL)
|
if(pM->pCSPROCID != NULL)
|
||||||
return RS_RET_OK; /* we are already done ;) */
|
return RS_RET_OK; /* we are already done ;) */
|
||||||
@ -2712,7 +2711,6 @@ dprintf("PROCIDFromTAG: in\n");
|
|||||||
if((iRet = rsCStrFinish(pM->pCSPROCID)) != RS_RET_OK)
|
if((iRet = rsCStrFinish(pM->pCSPROCID)) != RS_RET_OK)
|
||||||
return iRet;
|
return iRet;
|
||||||
|
|
||||||
dprintf("PROCIDFromTAG: out\n");
|
|
||||||
return RS_RET_OK;
|
return RS_RET_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2976,6 +2974,9 @@ static char *MsgGetProp(struct msg *pMsg, struct templateEntry *pTpe,
|
|||||||
{
|
{
|
||||||
char *pName;
|
char *pName;
|
||||||
char *pRes; /* result pointer */
|
char *pRes; /* result pointer */
|
||||||
|
char *pBufStart;
|
||||||
|
char *pBuf;
|
||||||
|
int iLen;
|
||||||
|
|
||||||
#ifdef FEATURE_REGEXP
|
#ifdef FEATURE_REGEXP
|
||||||
/* Variables necessary for regular expression matching */
|
/* Variables necessary for regular expression matching */
|
||||||
@ -3051,12 +3052,67 @@ static char *MsgGetProp(struct msg *pMsg, struct templateEntry *pTpe,
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/* substring extraction */
|
/* substring extraction */
|
||||||
if(pTpe->data.field.iFromPos != 0 || pTpe->data.field.iToPos != 0) {
|
/* first we check if we need to extract by field number
|
||||||
|
* rgerhards, 2005-12-22
|
||||||
|
*/
|
||||||
|
if(pTpe->data.field.has_fields == 1) {
|
||||||
|
int iCurrFld;
|
||||||
|
char *pFld;
|
||||||
|
char *pFldEnd;
|
||||||
|
/* first, skip to the field in question. For now, a field
|
||||||
|
* is made up of HT (tab) characters. This should be
|
||||||
|
* configurable over time.
|
||||||
|
*/
|
||||||
|
iCurrFld = 1;
|
||||||
|
pFld = pRes;
|
||||||
|
while(*pFld && iCurrFld < pTpe->data.field.iFromPos) {
|
||||||
|
/* skip fields until the requested field or end of string is found */
|
||||||
|
while(*pFld && *pFld != '\t')
|
||||||
|
++pFld; /* skip to field terminator */
|
||||||
|
if(*pFld == '\t') {
|
||||||
|
++pFld; /* eat it */
|
||||||
|
++iCurrFld;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
dprintf("field requested %d, field found %d\n", pTpe->data.field.iFromPos, iCurrFld);
|
||||||
|
|
||||||
|
|
||||||
|
if(iCurrFld == pTpe->data.field.iFromPos) {
|
||||||
|
/* field found, now extract it */
|
||||||
|
/* first of all, we need to find the end */
|
||||||
|
pFldEnd = pFld;
|
||||||
|
while(*pFldEnd && *pFldEnd != '\t')
|
||||||
|
++pFldEnd;
|
||||||
|
if(*pFldEnd == '\0')
|
||||||
|
--pFldEnd; /* back of to last real char */
|
||||||
|
/* we got our end pointer, now do the copy */
|
||||||
|
/* TODO: code copied from below, this is a candidate for a separate function */
|
||||||
|
iLen = pFldEnd - pFld + 1; /* the +1 is for an actual char, NOT \0! */
|
||||||
|
dprintf("field len %d, start '%s'\n", iLen, pFld);
|
||||||
|
pBufStart = pBuf = malloc((iLen + 1) * sizeof(char));
|
||||||
|
if(pBuf == NULL) {
|
||||||
|
if(*pbMustBeFreed == 1)
|
||||||
|
free(pRes);
|
||||||
|
*pbMustBeFreed = 0;
|
||||||
|
return "**OUT OF MEMORY**";
|
||||||
|
}
|
||||||
|
/* now copy */
|
||||||
|
memcpy(pBuf, pFld, iLen);
|
||||||
|
pBuf[iLen] = '\0'; /* terminate it */
|
||||||
|
if(*pbMustBeFreed == 1)
|
||||||
|
free(pRes);
|
||||||
|
pRes = pBufStart;
|
||||||
|
*pbMustBeFreed = 1;
|
||||||
|
} else {
|
||||||
|
/* field not found, return error */
|
||||||
|
if(*pbMustBeFreed == 1)
|
||||||
|
free(pRes);
|
||||||
|
*pbMustBeFreed = 0;
|
||||||
|
return "**FIELD NOT FOUND**";
|
||||||
|
}
|
||||||
|
} else if(pTpe->data.field.iFromPos != 0 || pTpe->data.field.iToPos != 0) {
|
||||||
/* we need to obtain a private copy */
|
/* we need to obtain a private copy */
|
||||||
int iLen;
|
|
||||||
int iFrom, iTo;
|
int iFrom, iTo;
|
||||||
char *pBufStart;
|
|
||||||
char *pBuf;
|
|
||||||
iFrom = pTpe->data.field.iFromPos;
|
iFrom = pTpe->data.field.iFromPos;
|
||||||
iTo = pTpe->data.field.iToPos;
|
iTo = pTpe->data.field.iToPos;
|
||||||
/* need to zero-base to and from (they are 1-based!) */
|
/* need to zero-base to and from (they are 1-based!) */
|
||||||
|
|||||||
21
template.c
21
template.c
@ -286,6 +286,14 @@ static int do_Parameter(char **pp, struct template *pTpl)
|
|||||||
} else {
|
} else {
|
||||||
/* now we fall through the "regular" FromPos code */
|
/* now we fall through the "regular" FromPos code */
|
||||||
#endif /* #ifdef FEATURE_REGEXP */
|
#endif /* #ifdef FEATURE_REGEXP */
|
||||||
|
if(*p == 'F') {
|
||||||
|
/* we have a field counter, so indicate it in the template */
|
||||||
|
++p; /* eat 'F' */
|
||||||
|
pTpe->data.field.has_fields = 1;
|
||||||
|
}
|
||||||
|
/* we now fall through, as this is only a modifier, but it is followed
|
||||||
|
* by a count as usual. rgerhards, 2005-12-22
|
||||||
|
*/
|
||||||
iNum = 0;
|
iNum = 0;
|
||||||
while(isdigit(*p))
|
while(isdigit(*p))
|
||||||
iNum = iNum * 10 + *p++ - '0';
|
iNum = iNum * 10 + *p++ - '0';
|
||||||
@ -314,7 +322,7 @@ static int do_Parameter(char **pp, struct template *pTpl)
|
|||||||
/* TODO : this is hardcoded and cant be escaped, please change */
|
/* TODO : this is hardcoded and cant be escaped, please change */
|
||||||
regex_end = strstr(p, "--end");
|
regex_end = strstr(p, "--end");
|
||||||
if (regex_end == NULL) {
|
if (regex_end == NULL) {
|
||||||
dprintf("error: Cant find regex end in: '%s'\n", p);
|
dprintf("error: can not find regex end in: '%s'\n", p);
|
||||||
pTpe->data.field.has_regex = 0;
|
pTpe->data.field.has_regex = 0;
|
||||||
} else {
|
} else {
|
||||||
/* We get here ONLY if the regex end was found */
|
/* We get here ONLY if the regex end was found */
|
||||||
@ -339,7 +347,7 @@ static int do_Parameter(char **pp, struct template *pTpl)
|
|||||||
/* Now i compile the regex */
|
/* Now i compile the regex */
|
||||||
/* Remember that the re is an attribute of the Template entry */
|
/* Remember that the re is an attribute of the Template entry */
|
||||||
if (regcomp(&(pTpe->data.field.re), regex_char, 0) != 0) {
|
if (regcomp(&(pTpe->data.field.re), regex_char, 0) != 0) {
|
||||||
dprintf("error: Cant compile regex: '%s'\n", regex_char);
|
dprintf("error: can not compile regex: '%s'\n", regex_char);
|
||||||
pTpe->data.field.has_regex = 2;
|
pTpe->data.field.has_regex = 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -368,7 +376,7 @@ static int do_Parameter(char **pp, struct template *pTpl)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* TODO: add more sanity checks. For now, we do the bare minimum */
|
/* TODO: add more sanity checks. For now, we do the bare minimum */
|
||||||
if(pTpe->data.field.iToPos < pTpe->data.field.iFromPos) {
|
if((pTpe->data.field.has_fields == 0) && (pTpe->data.field.iToPos < pTpe->data.field.iFromPos)) {
|
||||||
iNum = pTpe->data.field.iToPos;
|
iNum = pTpe->data.field.iToPos;
|
||||||
pTpe->data.field.iToPos = pTpe->data.field.iFromPos;
|
pTpe->data.field.iToPos = pTpe->data.field.iFromPos;
|
||||||
pTpe->data.field.iFromPos = iNum;
|
pTpe->data.field.iFromPos = iNum;
|
||||||
@ -628,8 +636,11 @@ void tplPrintList(void)
|
|||||||
if(pTpe->data.field.options.bDropLastLF) {
|
if(pTpe->data.field.options.bDropLastLF) {
|
||||||
dprintf("[drop last LF in msg] ");
|
dprintf("[drop last LF in msg] ");
|
||||||
}
|
}
|
||||||
if(pTpe->data.field.iFromPos != 0 ||
|
if(pTpe->data.field.has_fields == 1) {
|
||||||
pTpe->data.field.iToPos != 0) {
|
dprintf("[substring, field #%d only] ",
|
||||||
|
pTpe->data.field.iFromPos);
|
||||||
|
} else if(pTpe->data.field.iFromPos != 0 ||
|
||||||
|
pTpe->data.field.iToPos != 0) {
|
||||||
dprintf("[substring, from character %d to %d] ",
|
dprintf("[substring, from character %d to %d] ",
|
||||||
pTpe->data.field.iFromPos,
|
pTpe->data.field.iFromPos,
|
||||||
pTpe->data.field.iToPos);
|
pTpe->data.field.iToPos);
|
||||||
|
|||||||
@ -44,10 +44,11 @@ struct templateEntry {
|
|||||||
char *pPropRepl; /* pointer to property replacer string */
|
char *pPropRepl; /* pointer to property replacer string */
|
||||||
unsigned iFromPos; /* for partial strings only chars from this position ... */
|
unsigned iFromPos; /* for partial strings only chars from this position ... */
|
||||||
unsigned iToPos; /* up to that one... */
|
unsigned iToPos; /* up to that one... */
|
||||||
#ifdef FEATURE_REGEXP
|
#ifdef FEATURE_REGEXP
|
||||||
regex_t re; /* APR: this is the regular expression */
|
regex_t re; /* APR: this is the regular expression */
|
||||||
unsigned has_regex;
|
unsigned has_regex;
|
||||||
#endif
|
#endif
|
||||||
|
unsigned has_fields; /* support for field-couting */
|
||||||
enum tplFormatTypes eDateFormat;
|
enum tplFormatTypes eDateFormat;
|
||||||
enum tplFormatCaseConvTypes eCaseConv;
|
enum tplFormatCaseConvTypes eCaseConv;
|
||||||
struct { /* bit fields! */
|
struct { /* bit fields! */
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user