diff options
author | Rainer Gerhards <rgerhards@adiscon.com> | 2012-04-23 14:51:34 +0200 |
---|---|---|
committer | Rainer Gerhards <rgerhards@adiscon.com> | 2012-04-23 14:51:34 +0200 |
commit | 2eea95f626badb5a93ff7eca97cc68e5d2f3940a (patch) | |
tree | c7467c2ace398cda5d39e0f6fbda07e38fdc8e5c /runtime/msg.c | |
parent | 7d8ac48a4a214da917f7455f24b4c292c3e6d015 (diff) | |
parent | 9b06a4c26422b0a8727e1b3c6cc7141226186105 (diff) | |
download | rsyslog-2eea95f626badb5a93ff7eca97cc68e5d2f3940a.tar.gz rsyslog-2eea95f626badb5a93ff7eca97cc68e5d2f3940a.tar.bz2 rsyslog-2eea95f626badb5a93ff7eca97cc68e5d2f3940a.zip |
Merge branch 'master' into master-elasticsearch
Conflicts:
plugins/omelasticsearch/omelasticsearch.c
Diffstat (limited to 'runtime/msg.c')
-rw-r--r-- | runtime/msg.c | 172 |
1 files changed, 135 insertions, 37 deletions
diff --git a/runtime/msg.c b/runtime/msg.c index 8f92565a..9c7a2203 100644 --- a/runtime/msg.c +++ b/runtime/msg.c @@ -36,6 +36,7 @@ #include <assert.h> #include <ctype.h> #include <sys/socket.h> +#include <sys/sysinfo.h> #include <netdb.h> #include <libestr.h> #include <libee/libee.h> @@ -55,6 +56,7 @@ #include "ruleset.h" #include "prop.h" #include "net.h" +#include "rsconf.h" /* static data */ DEFobjStaticHelpers @@ -261,6 +263,9 @@ static struct { { UCHAR_CONSTANT("190"), 5}, { UCHAR_CONSTANT("191"), 5} }; +static char hexdigit[16] = + {'0', '1', '2', '3', '4', '5', '6', '7', '8', + '9', 'A', 'B', 'C', 'D', 'E', 'F' }; /*syslog facility names (as of RFC5424) */ static char *syslog_fac_names[24] = { "kern", "user", "mail", "daemon", "auth", "syslog", "lpr", @@ -421,7 +426,6 @@ resolveDNS(msg_t *pMsg) { uchar fromHostFQDN[NI_MAXHOST]; DEFiRet; -dbgprintf("XXXX: in msg/resolveDNS (dnscache)\n"); MsgLock(pMsg); CHKiRet(objUse(net, CORE_COMPONENT)); if(pMsg->msgFlags & NEEDS_DNSRESOL) { @@ -562,6 +566,8 @@ propNameStrToID(uchar *pName, propid_t *pPropID) *pPropID = PROP_CEE; } else if(!strcmp((char*) pName, "$bom")) { *pPropID = PROP_SYS_BOM; + } else if(!strcmp((char*) pName, "$uptime")) { + *pPropID = PROP_SYS_UPTIME; } else { *pPropID = PROP_INVALID; iRet = RS_RET_VAR_NOT_FOUND; @@ -1069,6 +1075,12 @@ static rsRetVal MsgSerialize(msg_t *pThis, strm_t *pStrm) objSerializePTR(pStrm, pCSAPPNAME, CSTR); objSerializePTR(pStrm, pCSPROCID, CSTR); objSerializePTR(pStrm, pCSMSGID, CSTR); + + if(pThis->pRuleset != NULL) { + rulesetGetName(pThis->pRuleset); + CHKiRet(obj.SerializeProp(pStrm, UCHAR_CONSTANT("pszRuleset"), PROPTYPE_PSZ, + rulesetGetName(pThis->pRuleset))); + } /* offset must be serialized after pszRawMsg, because we need that to obtain the correct * MSG size. @@ -1694,6 +1706,16 @@ void MsgSetRuleset(msg_t *pMsg, ruleset_t *pRuleset) } +/* rgerhards 2012-04-18: set associated ruleset (by ruleset name) + * If ruleset cannot be found, no update is done. + */ +static void +MsgSetRulesetByName(msg_t *pMsg, cstr_t *rulesetName) +{ + rulesetGetRuleset(runConf, &(pMsg->pRuleset), rsCStrGetSzStrNoNULL(rulesetName)); +} + + /* set TAG in msg object * (rewritten 2009-06-18 rgerhards) */ @@ -2351,81 +2373,67 @@ finalize_it: } -/* encode a property in JSON escaped format. This is a helper - * to MsgGetProp. It needs to update all provided parameters. - * Note: Code is borrowed from libee (my own code, so ASL 2.0 - * is fine with it); this function may later be replaced by - * some "better" and more complete implementation (maybe from - * libee or its helpers). - * For performance reasons, we begin to copy the string only - * when we recognice that we actually need to do some escaping. - * rgerhards, 2012-03-16 +/* Encode a JSON value and add it to provided string. Note that + * the string object may be NULL. In this case, it is created + * if and only if escaping is needed. */ static rsRetVal -jsonEncode(uchar **ppRes, unsigned short *pbMustBeFreed, int *pBufLen) +jsonAddVal(uchar *pSrc, unsigned buflen, es_str_t **dst) { - static char hexdigit[16] = - {'0', '1', '2', '3', '4', '5', '6', '7', '8', - '9', 'A', 'B', 'C', 'D', 'E', 'F' }; unsigned char c; es_size_t i; char numbuf[4]; int j; - unsigned buflen; - uchar *pSrc; - es_str_t *dst = NULL; DEFiRet; - pSrc = *ppRes; - buflen = (*pBufLen == -1) ? ustrlen(pSrc) : *pBufLen; for(i = 0 ; i < buflen ; ++i) { c = pSrc[i]; if( (c >= 0x23 && c <= 0x5b) || (c >= 0x5d /* && c <= 0x10FFFF*/) || c == 0x20 || c == 0x21) { /* no need to escape */ - if(dst != NULL) - es_addChar(&dst, c); + if(*dst != NULL) + es_addChar(dst, c); } else { - if(dst == NULL) { + if(*dst == NULL) { if(i == 0) { /* we hope we have only few escapes... */ - dst = es_newStr(buflen+10); + *dst = es_newStr(buflen+10); } else { - dst = es_newStrFromBuf((char*)pSrc, i-1); + *dst = es_newStrFromBuf((char*)pSrc, i-1); } - if(dst == NULL) { + if(*dst == NULL) { ABORT_FINALIZE(RS_RET_OUT_OF_MEMORY); } } /* we must escape, try RFC4627-defined special sequences first */ switch(c) { case '\0': - es_addBuf(&dst, "\\u0000", 6); + es_addBuf(dst, "\\u0000", 6); break; case '\"': - es_addBuf(&dst, "\\\"", 2); + es_addBuf(dst, "\\\"", 2); break; case '/': - es_addBuf(&dst, "\\/", 2); + es_addBuf(dst, "\\/", 2); break; case '\\': - es_addBuf(&dst, "\\\\", 2); + es_addBuf(dst, "\\\\", 2); break; case '\010': - es_addBuf(&dst, "\\b", 2); + es_addBuf(dst, "\\b", 2); break; case '\014': - es_addBuf(&dst, "\\f", 2); + es_addBuf(dst, "\\f", 2); break; case '\n': - es_addBuf(&dst, "\\n", 2); + es_addBuf(dst, "\\n", 2); break; case '\r': - es_addBuf(&dst, "\\r", 2); + es_addBuf(dst, "\\r", 2); break; case '\t': - es_addBuf(&dst, "\\t", 2); + es_addBuf(dst, "\\t", 2); break; default: /* TODO : proper Unicode encoding (see header comment) */ @@ -2433,12 +2441,38 @@ jsonEncode(uchar **ppRes, unsigned short *pbMustBeFreed, int *pBufLen) numbuf[3-j] = hexdigit[c % 16]; c = c / 16; } - es_addBuf(&dst, "\\u", 2); - es_addBuf(&dst, numbuf, 4); + es_addBuf(dst, "\\u", 2); + es_addBuf(dst, numbuf, 4); break; } } } +finalize_it: + RETiRet; +} + + +/* encode a property in JSON escaped format. This is a helper + * to MsgGetProp. It needs to update all provided parameters. + * Note: Code is borrowed from libee (my own code, so ASL 2.0 + * is fine with it); this function may later be replaced by + * some "better" and more complete implementation (maybe from + * libee or its helpers). + * For performance reasons, we begin to copy the string only + * when we recognice that we actually need to do some escaping. + * rgerhards, 2012-03-16 + */ +static rsRetVal +jsonEncode(uchar **ppRes, unsigned short *pbMustBeFreed, int *pBufLen) +{ + unsigned buflen; + uchar *pSrc; + es_str_t *dst = NULL; + DEFiRet; + + pSrc = *ppRes; + buflen = (*pBufLen == -1) ? ustrlen(pSrc) : *pBufLen; + CHKiRet(jsonAddVal(pSrc, buflen, &dst)); if(dst != NULL) { /* we updated the string and need to replace the @@ -2448,6 +2482,7 @@ jsonEncode(uchar **ppRes, unsigned short *pbMustBeFreed, int *pBufLen) free(*ppRes); *ppRes = (uchar*)es_str2cstr(dst, NULL); *pbMustBeFreed = 1; + *pBufLen = -1; es_deleteStr(dst); } @@ -2456,6 +2491,46 @@ finalize_it: } +/* Format a property as JSON field, that means + * "name"="value" + * where value is JSON-escaped (here we assume that the name + * only contains characters from the valid character set). + * Note: this function duplicates code from jsonEncode(). + * TODO: these two functions should be combined, at least if + * that makes any sense from a performance PoV - definitely + * something to consider at a later stage. rgerhards, 2012-04-19 + */ +static rsRetVal +jsonField(struct templateEntry *pTpe, uchar **ppRes, unsigned short *pbMustBeFreed, int *pBufLen) +{ + unsigned buflen; + uchar *pSrc; + es_str_t *dst = NULL; + DEFiRet; + + pSrc = *ppRes; + buflen = (*pBufLen == -1) ? ustrlen(pSrc) : *pBufLen; + /* we hope we have only few escapes... */ + dst = es_newStr(buflen+es_strlen(pTpe->data.field.fieldName)+15); + es_addChar(&dst, '"'); + es_addStr(&dst, pTpe->data.field.fieldName); + es_addBufConstcstr(&dst, "\"=\""); + CHKiRet(jsonAddVal(pSrc, buflen, &dst)); + es_addChar(&dst, '"'); + + if(*pbMustBeFreed) + free(*ppRes); + /* we know we do not have \0 chars - so the size does not change */ + *pBufLen = es_strlen(dst); + *ppRes = (uchar*)es_str2cstr(dst, NULL); + *pbMustBeFreed = 1; + es_deleteStr(dst); + +finalize_it: + RETiRet; +} + + /* This function returns a string-representation of the * requested message property. This is a generic function used * to abstract properties so that these can be easier @@ -2673,6 +2748,23 @@ uchar *MsgGetProp(msg_t *pMsg, struct templateEntry *pTpe, pRes = (uchar*) "\xEF\xBB\xBF"; *pbMustBeFreed = 0; break; + case PROP_SYS_UPTIME: + { + struct sysinfo s_info; + + if((pRes = (uchar*) MALLOC(sizeof(uchar) * 32)) == NULL) { + RET_OUT_OF_MEMORY; + } + *pbMustBeFreed = 1; + + if(sysinfo(&s_info) < 0) { + *pPropLen = sizeof("**SYSCALL FAILED**") - 1; + return(UCHAR_CONSTANT("**SYSCALL FAILED**")); + } + + snprintf((char*) pRes, sizeof(uchar) * 32, "%ld", s_info.uptime); + } + break; default: /* there is no point in continuing, we may even otherwise render the * error message unreadable. rgerhards, 2007-07-10 @@ -3264,6 +3356,8 @@ dbgprintf("prop repl 4, pRes='%s', len %d\n", pRes, bufLen); *pbMustBeFreed = 1; } else if(pTpe->data.field.options.bJSON) { jsonEncode(&pRes, pbMustBeFreed, &bufLen); + } else if(pTpe->data.field.options.bJSONf) { + jsonField(pTpe, &pRes, pbMustBeFreed, &bufLen); } if(bufLen == -1) @@ -3332,7 +3426,6 @@ msgGetMsgVarNew(msg_t *pThis, uchar *name) propNameStrToID(name, &propid); pszProp = (uchar*) MsgGetProp(pThis, NULL, propid, NULL, &propLen, &bMustBeFreed); -dbgprintf("ZZZZ: var %s returns '%s'\n", name, pszProp); estr = es_newStrFromCStr((char*)pszProp, propLen); if(bMustBeFreed) free(pszProp); @@ -3403,8 +3496,13 @@ rsRetVal MsgSetProperty(msg_t *pThis, var_t *pProp) memcpy(&pThis->tRcvdAt, &pProp->val.vSyslogTime, sizeof(struct syslogTime)); } else if(isProp("tTIMESTAMP")) { memcpy(&pThis->tTIMESTAMP, &pProp->val.vSyslogTime, sizeof(struct syslogTime)); + } else if(isProp("pszRuleset")) { + MsgSetRulesetByName(pThis, pProp->val.pStr); } else if(isProp("pszMSG")) { dbgprintf("no longer supported property pszMSG silently ignored\n"); + } else { + dbgprintf("unknown supported property '%s' silently ignored\n", + rsCStrGetSzStrNoNULL(pProp->pcsName)); } finalize_it: |