From e4ca8a3119ece504819605b340a3f5ba36b3eab6 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Tue, 3 Nov 2009 09:20:02 +0100 Subject: added function getenv() to RainerScript --- ChangeLog | 1 + doc/expression.html | 21 +++++++++++-------- doc/rainerscript.html | 18 +++++++++++++--- runtime/vm.c | 44 ++++++++++++++++++++++++++++++++++++++++ tests/Makefile.am | 3 +++ tests/diag.sh | 2 +- tests/rsf_getenv.sh | 17 ++++++++++++++++ tests/testsuites/rsf_getenv.conf | 17 ++++++++++++++++ 8 files changed, 111 insertions(+), 12 deletions(-) create mode 100755 tests/rsf_getenv.sh create mode 100644 tests/testsuites/rsf_getenv.conf diff --git a/ChangeLog b/ChangeLog index c36dbbad..d9466e9a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,6 @@ --------------------------------------------------------------------------- Version 4.7.0 [v4-devel] (rgerhards), 2009-09-?? +- added function getenv() to RainerScript - added new config option $InputUnixListenSocketCreatePath to permit the auto-creation of pathes to additional log sockets. This turns out to be useful if they reside on temporary file systems and diff --git a/doc/expression.html b/doc/expression.html index 9e37cb7a..c401d9ab 100644 --- a/doc/expression.html +++ b/doc/expression.html @@ -1,17 +1,22 @@ -Expressions + +Expressions in rsyslog -back -

Expressions

+back to rsyslog filter conditions +

Expressions in rsyslog

Rsyslog supports expressions at a growing number of places. So -far, they are supported for filtering messages.

Expression support is provided by RainerScript. For now, please see the formal expression definition in RainerScript ABNF. It is the "expr" node.

C-like comments (/* some comment */) are supported inside the expression, but not yet in the rest of the configuration file.

[rsyslog.conf overview] +far, they are supported for filtering messages.

+

Expression support is provided by RainerScript. Please see the +RainerScript documentation for more details.

+

C-like comments (/* some comment */) are supported inside the expression, +but not yet in the rest of the configuration file.

+ +

[rsyslog.conf overview] [manual index] [rsyslog site]

This documentation is part of the -rsyslog -project.
-Copyright © 2008 by Rainer -Gerhards and +rsyslog project.
+Copyright © 2008, 2009 by Rainer Gerhards and Adiscon. Released under the GNU GPL version 3 or higher.

diff --git a/doc/rainerscript.html b/doc/rainerscript.html index ef0e41cb..63a79040 100644 --- a/doc/rainerscript.html +++ b/doc/rainerscript.html @@ -51,13 +51,25 @@ of a and b should be tested as "a <> b". The "not" operator should be reserved to cases where it actually is needed to form a complex boolean expression. In those cases, parenthesis are highly recommended. +

Functions

+

RainerScript supports a currently quite limited set of functions: +

+

The following example can be used to build a dynamic filter based on some environment +variable: +

+if $msg contains getenv('TRIGGERVAR') then /path/to/errfile
+

[rsyslog.conf overview] [manual index] [rsyslog site]

This documentation is part of the rsyslog project.
-Copyright © 2008 by Rainer -Gerhards and +Copyright © 2008, 2009 by Rainer Gerhards and Adiscon. Released under the GNU GPL version 3 or higher.

- \ No newline at end of file + diff --git a/runtime/vm.c b/runtime/vm.c index d7cd52d5..a1d992c3 100644 --- a/runtime/vm.c +++ b/runtime/vm.c @@ -34,6 +34,7 @@ #include "vm.h" #include "sysvar.h" #include "stringbuf.h" +#include "unicode-helper.h" /* static data */ DEFobjStaticHelpers @@ -41,6 +42,8 @@ DEFobjCurrIf(vmstk) DEFobjCurrIf(var) DEFobjCurrIf(sysvar) +static pthread_mutex_t mutGetenv; /* we need to make this global because otherwise we can not guarantee proper init! */ + /* ------------------------------ function registry code and structures ------------------------------ */ /* we maintain a registry of known functions */ @@ -539,6 +542,42 @@ finalize_it: } +/* The getenv function. Note that we guard the OS call by a mutex, as that + * function is not guaranteed to be thread-safe. This implementation here is far from + * being optimal, at least we should cache the result. This is left TODO for + * a later revision. + * rgerhards, 2009-11-03 + */ +static rsRetVal +rsf_getenv(vmstk_t *pStk, int numOperands) +{ + DEFiRet; + var_t *operand1; + char *envResult; + cstr_t *pCstr; + + if(numOperands != 1) + ABORT_FINALIZE(RS_RET_INVLD_NBR_ARGUMENTS); + + /* pop args and do operaton (trivial case here...) */ + vmstk.PopString(pStk, &operand1); + d_pthread_mutex_lock(&mutGetenv); + envResult = getenv((char*) rsCStrGetSzStr(operand1->val.pStr)); + DBGPRINTF("rsf_getenv(): envvar '%s', return '%s'\n", rsCStrGetSzStr(operand1->val.pStr), + envResult == NULL ? "(NULL)" : envResult); + iRet = rsCStrConstructFromszStr(&pCstr, (envResult == NULL) ? UCHAR_CONSTANT("") : (uchar*)envResult); + d_pthread_mutex_unlock(&mutGetenv); + if(iRet != RS_RET_OK) + FINALIZE; /* need to do this after mutex is unlocked! */ + + /* Store result and cleanup */ + var.SetString(operand1, pCstr); + vmstk.Push(pStk, operand1); +finalize_it: + RETiRet; +} + + /* The "tolower" function, which converts its sole argument to lower case. * Quite honestly, currently this is primarily a test driver for me... * rgerhards, 2009-04-06 @@ -756,6 +795,8 @@ BEGINObjClassExit(vm, OBJ_IS_CORE_MODULE) /* class, version */ objRelease(sysvar, CORE_COMPONENT); objRelease(var, CORE_COMPONENT); objRelease(vmstk, CORE_COMPONENT); + + pthread_mutex_destroy(&mutGetenv); ENDObjClassExit(vm) @@ -776,6 +817,9 @@ BEGINObjClassInit(vm, 1, OBJ_IS_CORE_MODULE) /* class, version */ /* register built-in functions // TODO: move to its own module */ CHKiRet(rsfrAddFunction((uchar*)"strlen", rsf_strlen)); CHKiRet(rsfrAddFunction((uchar*)"tolower", rsf_tolower)); + CHKiRet(rsfrAddFunction((uchar*)"getenv", rsf_getenv)); + + pthread_mutex_init(&mutGetenv, NULL); ENDObjClassInit(vm) diff --git a/tests/Makefile.am b/tests/Makefile.am index c5deaa47..33f94eef 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -7,6 +7,7 @@ TESTS = $(TESTRUNS) cfg.sh \ diskqueue.sh \ diskqueue-fsync.sh \ manytcp.sh \ + rsf_getenv.sh \ queue-persist.sh if ENABLE_OMSTDOUT @@ -90,6 +91,8 @@ EXTRA_DIST= 1.rstest 2.rstest 3.rstest err1.rstest \ killrsyslog.sh \ parsertest.sh \ fieldtest.sh \ + rsf_getenv.sh \ + testsuites/rsf_getenv.conf \ diskqueue.sh \ testsuites/diskqueue.conf \ diskqueue-fsync.sh \ diff --git a/tests/diag.sh b/tests/diag.sh index 13bb877d..b2bd13ac 100755 --- a/tests/diag.sh +++ b/tests/diag.sh @@ -9,7 +9,7 @@ #valgrind="valgrind --tool=drd --log-fd=1" #valgrind="valgrind --tool=helgrind --log-fd=1" #set -o xtrace -#export RSYSLOG_DEBUG="debug nostdout printmutexaction" +#export RSYSLOG_DEBUG="debug nostdout noprintmutexaction" #export RSYSLOG_DEBUGLOG="log" case $1 in 'init') $srcdir/killrsyslog.sh # kill rsyslogd if it runs for some reason diff --git a/tests/rsf_getenv.sh b/tests/rsf_getenv.sh new file mode 100755 index 00000000..42de20fe --- /dev/null +++ b/tests/rsf_getenv.sh @@ -0,0 +1,17 @@ +# Test for the getenv() rainerscript function +# this is a quick test, but it gurantees that the code path is +# at least progressed (but we do not check for unset envvars!) +# added 2009-11-03 by Rgerhards +# This file is part of the rsyslog project, released under GPLv3 +# uncomment for debugging support: +echo =============================================================================== +echo \[rsf_getenv.sh\]: testing RainerScript getenv\(\) function +export MSGNUM="msgnum:" +source $srcdir/diag.sh init +source $srcdir/diag.sh startup rsf_getenv.conf +source $srcdir/diag.sh tcpflood 127.0.0.1 13514 1 10000 +source $srcdir/diag.sh shutdown-when-empty # shut down rsyslogd when done processing messages +source $srcdir/diag.sh wait-shutdown +source $srcdir/diag.sh seq-check 0 9999 +unset MSGNUM +source $srcdir/diag.sh exit diff --git a/tests/testsuites/rsf_getenv.conf b/tests/testsuites/rsf_getenv.conf new file mode 100644 index 00000000..2f2eb58c --- /dev/null +++ b/tests/testsuites/rsf_getenv.conf @@ -0,0 +1,17 @@ +# Test for RainerScript getenv() function (see .sh file for details) +# Note envvar MSGNUM must be set to "msgnum:" +# rgerhards, 2009-11-03 +$IncludeConfig diag-common.conf + +$ModLoad ../plugins/imtcp/.libs/imtcp +$MainMsgQueueTimeoutShutdown 10000 +$InputTCPServerRun 13514 + +# set spool locations and switch queue to disk-only mode +$WorkDirectory test-spool +$MainMsgQueueFilename mainq +$MainMsgQueueType disk + +$template outfmt,"%msg:F,58:2%\n" +$template dynfile,"rsyslog.out.log" # trick to use relative path names! +if $msg contains getenv('MSGNUM') then ?dynfile;outfmt -- cgit