rsyslog配置动态日志文件-outchannel补丁

Debian Bug report logs - #477351报出了一个bug,正是我最近头疼的问题,原文如下:
Package: rsyslog
Version: 2.0.2-1~bpo40+1
Severity: normal


Hello,

on my /etc/rsyslog.conf you can read:
$template DynFile,"/var/log/system-%HOSTNAME%.log"
$outchannel porHost,$DynFile,104857600,echo test
*.* $porHost


rsyslog wants to create "/$DynFile" file, and not create
/var/log/system-%HOSTNAME%.log file .

This is with rsyslog from etch-backports.

I'll probe the sid version

-- System Information:
Debian Release: 4.0
  APT prefers stable
  APT policy: (500, 'stable')
Architecture: amd64 (x86_64)
Shell:  /bin/sh linked to /bin/bash
Kernel: Linux 2.6.18-5-xen-amd64
Locale: LANG=es_ES.UTF-8, LC_CTYPE=es_ES.UTF-8 (charmap=UTF-8)

Versions of packages rsyslog depends on:
ii  libc6                  2.3.6.ds1-13etch4 GNU C Library: Shared libraries
ii  lsb-base               3.1-23.2etch1     Linux Standard Base 3.1 init scrip
ii  zlib1g                 1:1.2.3-13        compression library - runtime

Versions of packages rsyslog recommends:
ii  logrotate                     3.7.1-3    Log rotation utility

起初,我真的以为这是个bug,后来查了源代码发现,rsyslog根本就没有实现动态文件对outchannel的支持,难道这位老兄不知道察看一下代码吗?既然rsyslog是开源的,源代码都在手上,还有什么不能做的啊?动手修改代码才是王道!以下是自用的patch,应用这个patch后可以解决自己的问题:

diff -urN rsyslog-4.6.5.orig/runtime/conf.c rsyslog-4.6.5/runtime/conf.c --- rsyslog-4.6.5.orig/runtime/conf.c    2010-11-24 22:47:07.000000000 +0800 +++ rsyslog-4.6.5/runtime/conf.c    2012-08-14 08:26:25.000000000 +0800 @@ -502,6 +502,32 @@      RETiRet;  }   +/* Get a FileName from a outchannel + */ +rsRetVal channParseFileName(uchar* p, uchar *szBuf) +{ +        DEFiRet; +        size_t i; +        char szChn[128]; +        struct outchannel *pOch; + +        ++p; /* skip '$' */ +        i = 0; +        /* get outchannel name */ +        while(*p && *p != ';' && *p != ' ' && +              i < sizeof(szChn) / sizeof(char)) { +              szChn[i++] = *p++; +        } +        szChn[i] = '\0'; +        pOch = ochFind(szChn, i); +        if (pOch != NULL && +                pOch->pszFileTemplate != NULL) { +                strcpy(szBuf, pOch->pszFileTemplate); +        } + +finalize_it: +        RETiRet; +}    /* Helper to cfline() and its helpers. Parses a template name   * from an "action" line. Must be called with the Line pointer diff -urN rsyslog-4.6.5.orig/runtime/stream.c rsyslog-4.6.5/runtime/stream.c --- rsyslog-4.6.5.orig/runtime/stream.c    2010-11-24 22:47:07.000000000 +0800 +++ rsyslog-4.6.5/runtime/stream.c    2012-08-14 08:30:25.000000000 +0800 @@ -96,6 +96,8 @@  resolveFileSizeLimit(strm_t *pThis, uchar *pszCurrFName)  {      uchar *pParams; +    int len; +    uchar params[512] = {0};      uchar *pCmd;      uchar *p;      off_t actualFileSize; @@ -121,15 +123,22 @@      if(*p == ' ') {          *p = '\0'; /* pretend string-end */          pParams = p+1; -    } else +        len = strlen(pParams); +        strcpy(params, pParams); +    } else {          pParams = NULL; +        len = 0; +    } +     +    //拼接动态文件的名字 +    strcpy(params+len, pszCurrFName);        /* the execProg() below is probably not great, but at least is is       * fairly secure now. Once we change the way file size limits are       * handled, we should also revisit how this command is run (and       * with which parameters).   rgerhards, 2007-07-20       */ -    execProg(pCmd, 1, pParams); +    execProg(pCmd, 1, params);        free(pCmd);   diff -urN rsyslog-4.6.5.orig/tools/omfile.c rsyslog-4.6.5/tools/omfile.c --- rsyslog-4.6.5.orig/tools/omfile.c    2010-11-24 22:47:07.000000000 +0800 +++ rsyslog-4.6.5/tools/omfile.c    2012-08-14 08:26:17.000000000 +0800 @@ -661,19 +661,33 @@      pData->iSizeLimit = 0; /* default value, use outchannels to configure! */        switch(*p) { -        case '$': -        CODE_STD_STRING_REQUESTparseSelectorAct(1) -        /* rgerhards 2005-06-21: this is a special setting for output-channel -         * definitions. In the long term, this setting will probably replace -         * anything else, but for the time being we must co-exist with the -         * traditional mode lines. -         * rgerhards, 2007-07-24: output-channels will go away. We keep them -         * for compatibility reasons, but seems to have been a bad idea. -         */ -        CHKiRet(cflineParseOutchannel(pData, p, *ppOMSR, 0, OMSR_NO_RQD_TPL_OPTS)); -        pData->bDynamicName = 0; +        case '$': { +        uchar szFileName[128] = {0}; +        channParseFileName(p, szFileName); +        if (szFileName[0] == '$') { +            CODE_STD_STRING_REQUESTparseSelectorAct(2) +            CHKiRet(cflineParseOutchannel(pData, p, *ppOMSR, 0, OMSR_NO_RQD_TPL_OPTS)); +            strcpy(pData->f_fname, ""); +            CHKiRet(OMSRsetEntry(*ppOMSR, 1, ustrdup(&szFileName[1]), OMSR_NO_RQD_TPL_OPTS)); +            pData->bDynamicName = 1; +            pData->iCurrElt = -1;          /* no current element */ +            CHKmalloc(pData->dynCache = (dynaFileCacheEntry**) +                calloc(iDynaFileCacheSize, sizeof(dynaFileCacheEntry*))); +             +        } else { +            CODE_STD_STRING_REQUESTparseSelectorAct(1) +            /* rgerhards 2005-06-21: this is a special setting for output-channel +              * definitions. In the long term, this setting will probably replace +              * anything else, but for the time being we must co-exist with the +              * traditional mode lines. +              * rgerhards, 2007-07-24: output-channels will go away. We keep them +              * for compatibility reasons, but seems to have been a bad idea. +              */ +            CHKiRet(cflineParseOutchannel(pData, p, *ppOMSR, 0, OMSR_NO_RQD_TPL_OPTS)); +            pData->bDynamicName = 0; +        }          break; - +    }      case '?': /* This is much like a regular file handle, but we need to obtain             * a template name. rgerhards, 2007-07-03             */


打补丁时,只需要进入rsyslog-4.6.5目录,然后将patch文件放在上一级,执行patch -p1 <../rsyslog-dynchannel.patch即可。此外,还向rsyslog maillist提交了一个正式的patch:


subject:add dynimic filename support for outchannel to:[email protected]  From e82f42dc9eb78fd2132b875c8718151ab9218acf Mon Sep 17 00:00:00 2001 From: zhaoya <[email protected]> Date: Tue, 7 Aug 2012 08:07:12 -0700 Subject: [PATCH] add dynimic filename support for outchannel  The URL: http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=477351 present a FALSE BUG! Up to the newest version,rsyslogd's "outchannel [still] doesn't get variable from template"! ---  runtime/stream.c |   13 +++++++++-  tools/omfile.c   |   63 +++++++++++++++++++++++++++++++++++++++++++----------  2 files changed, 62 insertions(+), 14 deletions(-)  diff --git a/runtime/stream.c b/runtime/stream.c index bb1a0a4..49e7ec4 100644 --- a/runtime/stream.c +++ b/runtime/stream.c @@ -96,6 +96,8 @@ static rsRetVal  resolveFileSizeLimit(strm_t *pThis, uchar *pszCurrFName)  {      uchar *pParams; +    uchar params[512] = {0}; +    int len;      uchar *pCmd;      uchar *p;      off_t actualFileSize; @@ -121,15 +123,22 @@ resolveFileSizeLimit(strm_t *pThis, uchar *pszCurrFName)      if(*p == ' ') {          *p = '\0'; /* pretend string-end */          pParams = p+1; -    } else +        len = strlen(pParams); +        strcpy(params, pParams); +    } else {          pParams = NULL; +        len = 0; +    } + +    //�麓陆�露炉�卢��录镁碌��没�� +    strcpy(params+len, pszCurrFName);        /* the execProg() below is probably not great, but at least is is       * fairly secure now. Once we change the way file size limits are       * handled, we should also revisit how this command is run (and       * with which parameters).   rgerhards, 2007-07-20       */ -    execProg(pCmd, 1, pParams); +    execProg(pCmd, 1, params);        free(pCmd);   diff --git a/tools/omfile.c b/tools/omfile.c index 1a36343..a877555 100644 --- a/tools/omfile.c +++ b/tools/omfile.c @@ -333,6 +333,32 @@ rsRetVal setDynaFileCacheSize(void __attribute__((unused)) *pVal, int iNewVal)      RETiRet;  }   +/* Get a FileName from a outchannel + */ +rsRetVal channParseFileName(uchar* p, uchar *szBuf) +{ +        DEFiRet; +        size_t i; +        char szChn[128]; +        struct outchannel *pOch; + +        ++p; /* skip '$' */ +        i = 0; +        /* get outchannel name */ +        while(*p && *p != ';' && *p != ' ' && +              i < sizeof(szChn) / sizeof(char)) { +              szChn[i++] = *p++; +        } +        szChn[i] = '\0'; +        pOch = ochFind(szChn, i); +        if (pOch != NULL && +                pOch->pszFileTemplate != NULL) { +                strcpy(szBuf, pOch->pszFileTemplate); +        } + +finalize_it: +        RETiRet; +}    /* Helper to cfline(). Parses a output channel name up until the first   * comma and then looks for the template specifier. Tries @@ -1004,19 +1030,32 @@ CODESTARTparseSelectorAct      pData->iSizeLimit = 0; /* default value, use outchannels to configure! */        switch(*p) { -        case '$': -        CODE_STD_STRING_REQUESTparseSelectorAct(1) -        /* rgerhards 2005-06-21: this is a special setting for output-channel -         * definitions. In the long term, this setting will probably replace -         * anything else, but for the time being we must co-exist with the -         * traditional mode lines. -         * rgerhards, 2007-07-24: output-channels will go away. We keep them -         * for compatibility reasons, but seems to have been a bad idea. -         */ -        CHKiRet(cflineParseOutchannel(pData, p, *ppOMSR, 0, OMSR_NO_RQD_TPL_OPTS)); -        pData->bDynamicName = 0; +        case '$': { +        uchar szFileName[128] = {0}; +        channParseFileName(p, szFileName); +        if (szFileName[0] == '$') { +            CODE_STD_STRING_REQUESTparseSelectorAct(2) +            CHKiRet(cflineParseOutchannel(pData, p, *ppOMSR, 0, OMSR_NO_RQD_TPL_OPTS)); +            strcpy(pData->f_fname, ""); +            CHKiRet(OMSRsetEntry(*ppOMSR, 1, ustrdup(&szFileName[1]), OMSR_NO_RQD_TPL_OPTS)); +            pData->bDynamicName = 1; +            pData->iCurrElt = -1;          /* no current element */ +            CHKmalloc(pData->dynCache = (dynaFileCacheEntry**) +                calloc(iDynaFileCacheSize, sizeof(dynaFileCacheEntry*))); +        } else {     +            CODE_STD_STRING_REQUESTparseSelectorAct(1) +            /* rgerhards 2005-06-21: this is a special setting for output-channel +             * definitions. In the long term, this setting will probably replace +             * anything else, but for the time being we must co-exist with the +             * traditional mode lines. +             * rgerhards, 2007-07-24: output-channels will go away. We keep them +             * for compatibility reasons, but seems to have been a bad idea. +             */ +            CHKiRet(cflineParseOutchannel(pData, p, *ppOMSR, 0, OMSR_NO_RQD_TPL_OPTS)); +            pData->bDynamicName = 0; +        }          break; - +    }      case '?': /* This is much like a regular file handle, but we need to obtain             * a template name. rgerhards, 2007-07-03             */ --  1.7.4.1


此patch的意义绝大部分是为了自用,本着GPL才提交的。如此patch,就可以在配置文件中使用下面的配置了:
$template DynFile,"/var/log/system-%HOSTNAME%.log"
$outchannel porHost,$DynFile,104857600,echo test
*.* $porHost



你可能感兴趣的:(Debian,String,null,Parameters,patch,compression)