From 74f91062431831291bd90fbbed77565d019b4610 Mon Sep 17 00:00:00 2001 From: Michael Friedrich Date: Tue, 5 Nov 2013 17:05:41 +0100 Subject: [PATCH] Implement regex match attribute filters (~, ~~) Requires the boost regex library. Refs #5007 Signed-off-by: Michael Friedrich --- CMakeLists.txt | 2 +- components/livestatus/attributefilter.cpp | 24 +++++++++++++++++++++++ icinga2.spec | 3 +++ test/livestatus/queries/log/alerts | 6 ++++++ 4 files changed, 34 insertions(+), 1 deletion(-) create mode 100644 test/livestatus/queries/log/alerts diff --git a/CMakeLists.txt b/CMakeLists.txt index 6403fca18..e6829a81b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -48,7 +48,7 @@ if(WIN32) add_definitions(-DBOOST_ALL_NO_LIB) endif() -find_package(Boost 1.41.0 COMPONENTS thread system program_options REQUIRED) +find_package(Boost 1.41.0 COMPONENTS thread system program_options regex REQUIRED) link_directories(${Boost_LIBRARY_DIRS}) include_directories(${Boost_INCLUDE_DIRS}) diff --git a/components/livestatus/attributefilter.cpp b/components/livestatus/attributefilter.cpp index ad1cee34b..76dcf508e 100644 --- a/components/livestatus/attributefilter.cpp +++ b/components/livestatus/attributefilter.cpp @@ -21,7 +21,9 @@ #include "base/convert.h" #include "base/array.h" #include "base/objectlock.h" +#include "base/logger_fwd.h" #include +#include using namespace icinga; using namespace livestatus; @@ -59,11 +61,33 @@ bool AttributeFilter::Apply(const Table::Ptr& table, const Value& row) else return (static_cast(value) == m_Operand); } else if (m_Operator == "~") { + boost::regex expr(static_cast(m_Operand)); + boost::smatch what; + String val = static_cast(value); + std::string::const_iterator begin = val.Begin(); + std::string::const_iterator end = val.End(); + bool ret = boost::regex_search(begin, end, what, expr); + + //Log(LogDebug, "livestatus", "Attribute filter '" + m_Operand + " " + m_Operator + " " + + // static_cast(value) + "' " + (ret ? "matches" : "doesn't match") + "." ); + + return ret; } else if (m_Operator == "=~") { return string_iless()(value, m_Operand); } else if (m_Operator == "~~") { + boost::regex expr(static_cast(m_Operand), boost::regex::icase); + boost::smatch what; + String val = static_cast(value); + std::string::const_iterator begin = val.Begin(); + std::string::const_iterator end = val.End(); + bool ret = boost::regex_search(begin, end, what, expr); + + //Log(LogDebug, "livestatus", "Attribute filter '" + m_Operand + " " + m_Operator + " " + + // static_cast(value) + "' " + (ret ? "matches" : "doesn't match") + "." ); + + return ret; } else if (m_Operator == "<") { if (value.GetType() == ValueNumber) return (static_cast(value) < Convert::ToDouble(m_Operand)); diff --git a/icinga2.spec b/icinga2.spec index 8de8ccfaa..c311807c6 100644 --- a/icinga2.spec +++ b/icinga2.spec @@ -73,12 +73,14 @@ Requires: boost%{el5_boost_version}-program-options Requires: boost%{el5_boost_version}-system Requires: boost%{el5_boost_version}-test Requires: boost%{el5_boost_version}-thread +Requires: boost%{el5_boost_version}-regex %else BuildRequires: boost-devel >= 1.41 Requires: boost-program-options >= 1.41 Requires: boost-system >= 1.41 Requires: boost-test >= 1.41 Requires: boost-thread >= 1.41 +Requires: boost-regex >= 1.41 %endif %endif @@ -98,6 +100,7 @@ Requires: libboost_program_options%{opensuse_boost_version} Requires: libboost_system%{opensuse_boost_version} Requires: libboost_test%{opensuse_boost_version} Requires: libboost_thread%{opensuse_boost_version} +Requires: libboost_regex%{opensuse_boost_version} %endif %endif diff --git a/test/livestatus/queries/log/alerts b/test/livestatus/queries/log/alerts new file mode 100644 index 000000000..8c4740acf --- /dev/null +++ b/test/livestatus/queries/log/alerts @@ -0,0 +1,6 @@ +GET log +Columns: host_name service_description time lineno class type options plugin_output state state_type comment contact_name command_name +Filter: time >= 1348657741 +Filter: message ~ ALERT +ResponseHeader: fixed16 +