Skip to content

Commit

Permalink
add event_log_filter
Browse files Browse the repository at this point in the history
  • Loading branch information
jean-christophe81 committed Feb 18, 2025
1 parent fe7a42a commit 56b8959
Show file tree
Hide file tree
Showing 5 changed files with 148 additions and 27 deletions.
30 changes: 20 additions & 10 deletions agent/native_windows/inc/com/centreon/agent/check_event_log.hh
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@
#include <winevt.h>

#include <boost/flyweight.hpp>
#include <string_view>

#include "check.hh"
#include "filter.hh"
Expand All @@ -41,18 +40,27 @@ class event_data : public testable {
std::unique_ptr<uint8_t[]> _data;
DWORD _property_count;

protected:
/**
* @brief Used only for tests
*/
event_data() : _property_count(0) {}

public:
event_data(EVT_HANDLE render_context, EVT_HANDLE event_handle);

std::wstring_view get_provider() const;
uint16_t get_event_id() const;
uint8_t get_level() const;
uint16_t get_task() const;
int64_t get_keywords() const;
uint64_t get_time_created() const;
uint64_t get_record_id() const;
std::wstring_view get_computer() const;
std::wstring_view get_channel() const; // file
~event_data() = default;

// all getters are virtual in order to mock it in ut
virtual std::wstring_view get_provider() const;
virtual uint16_t get_event_id() const;
virtual uint8_t get_level() const;
virtual uint16_t get_task() const;
virtual int64_t get_keywords() const;
virtual uint64_t get_time_created() const;
virtual uint64_t get_record_id() const;
virtual std::wstring_view get_computer() const;
virtual std::wstring_view get_channel() const; // file
};

class event_filter {
Expand Down Expand Up @@ -82,6 +90,8 @@ class event_filter {
public:
event_filter(const std::string_view& filter_str,
const std::shared_ptr<spdlog::logger>& logger);

bool allow(event_data& data) const { return _filter.check(data); }
};

class event {
Expand Down
34 changes: 19 additions & 15 deletions agent/src/filter_rules.cc
Original file line number Diff line number Diff line change
Expand Up @@ -52,10 +52,10 @@ const bp::symbols<label_compare_to_value::comparison> comparison_symbols = {
{"=", label_compare_to_value::comparison::equal}};

const auto label_compare_to_value_rule_def =
(+bp::char_('a', 'z') >> *bp::ws >> comparison_symbols >> *bp::ws >>
bp::double_ >> *bp::char_('a', 'z')) |
(+(bp::char_('a', 'z') | bp::lit('_')) >> *bp::ws >> comparison_symbols >>
*bp::ws >> bp::double_ >> *bp::char_('a', 'z')) |
(bp::double_ >> *bp::char_('a', 'z') >> *bp::ws >> comparison_symbols >>
*bp::ws >> *bp::char_('a', 'z'));
*bp::ws >> +(bp::char_('a', 'z') | bp::lit('_')));

/************************************************************************
label_compare_to_string grammar
Expand All @@ -74,7 +74,9 @@ const bp::symbols<string_comparison> str_comparison_symbols = {
{"==", string_comparison::equal},
{"=", string_comparison::equal}};

const auto label_compare_to_string_rule_def = +bp::char_('a', 'z') >> *bp::ws >>
const auto label_compare_to_string_rule_def = +(bp::char_('a', 'z') |
bp::lit('_')) >>
*bp::ws >>
str_comparison_symbols >>
*bp::ws >> bp::quoted_string("'");

Expand All @@ -92,10 +94,12 @@ const bp::symbols<in_not> in_symbols = {{"in", in_not::in},
{"not_in", in_not::not_in}};

const auto label_in_rule_def =
+bp::char_('a', 'z') >> *bp::ws >> in_symbols >> *bp::ws >> '(' >>
*bp::ws >> (bp::quoted_string("'\"") | +bp::char_('a', 'z')) >>
+(bp::char_('a', 'z') | bp::lit('_')) >> *bp::ws >> in_symbols >> *bp::ws >>
'(' >> *bp::ws >>
(bp::quoted_string("'\"") | +(bp::char_('a', 'z') | bp::char_('0', '9'))) >>
*(*bp::ws >> ',' >> *bp::ws >>
(bp::quoted_string("'\"") | +bp::char_('a', 'z'))) >>
(bp::quoted_string("'\"") |
+(bp::char_('a', 'z') | bp::char_('0', '9')))) >>
*bp::ws >> ')';

/************************************************************************
Expand Down Expand Up @@ -144,17 +148,17 @@ const auto filter_combinator_rule_def = (filter_combinator_rule1 |
* wchar_t version
*/

const auto label_compare_to_string_rule_w_def = +bp::char_('a', 'z') >>
*bp::ws >>
str_comparison_symbols >>
*bp::ws >>
bp::quoted_string("'");
const auto label_compare_to_string_rule_w_def =
+(bp::char_('a', 'z') | bp::lit('_')) >> *bp::ws >>
str_comparison_symbols >> *bp::ws >> bp::quoted_string("'");

const auto label_in_rule_w_def =
+bp::char_('a', 'z') >> *bp::ws >> in_symbols >> *bp::ws >> '(' >>
*bp::ws >> (bp::quoted_string("'\"") | +bp::char_('a', 'z')) >>
+(bp::char_('a', 'z') | bp::lit('_')) >> *bp::ws >> in_symbols >> *bp::ws >>
'(' >> *bp::ws >>
(bp::quoted_string("'\"") | +(bp::char_('a', 'z') | bp::char_('0', '9'))) >>
*(*bp::ws >> ',' >> *bp::ws >>
(bp::quoted_string("'\"") | +bp::char_('a', 'z'))) >>
(bp::quoted_string("'\"") |
+(bp::char_('a', 'z') | bp::char_('0', '9')))) >>
*bp::ws >> ')';

const auto filter_combinator_rule1_w_def =
Expand Down
1 change: 1 addition & 0 deletions agent/test/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ if(${CMAKE_SYSTEM_NAME} STREQUAL "Linux")
set(SRC ${SRC_COMMON} config_test.cc check_linux_cpu_test.cc)
else()
set(SRC ${SRC_COMMON}
check_event_log_test.cc
check_windows_cpu_test.cc
check_windows_memory_test.cc
check_uptime_test.cc
Expand Down
108 changes: 108 additions & 0 deletions agent/test/check_event_log_test.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
/**
* Copyright 2024 Centreon
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* For more information : [email protected]
*/

#include <gtest/gtest.h>
#include <spdlog/spdlog.h>

#include "check_event_log.hh"

using namespace com::centreon::agent;
using namespace com::centreon::agent::check_event_log_detail;

struct mock_event_data : public event_data {
std::wstring provider;
uint16_t event_id;
uint8_t level;
uint16_t task;
int64_t keywords;
uint64_t time_created;
uint64_t record_id;
std::wstring computer;
std::wstring channel;

mock_event_data() {}

std::wstring_view get_provider() const override { return provider; }

uint16_t get_event_id() const override { return event_id; }

uint8_t get_level() const override { return level; }

uint16_t get_task() const override { return task; }

int64_t get_keywords() const override { return keywords; }

uint64_t get_time_created() const override { return time_created; }

uint64_t get_record_id() const override { return record_id; }

std::wstring_view get_computer() const override { return computer; }

std::wstring_view get_channel() const override { return channel; }
};

TEST(eventlog_filter, provider) {
event_filter filter1("provider == 'provider1'", spdlog::default_logger());
event_filter filter2("provider != 'provider1'", spdlog::default_logger());
event_filter filter3("provider in ('provider1', 'provider2')",
spdlog::default_logger());
event_filter filter4("provider == 'provider1' or provider == 'provider2'",
spdlog::default_logger());
event_filter filter5(
"provider in ('provider1', 'provider2') or provider in ( provider3 )",
spdlog::default_logger());

mock_event_data data;

data.provider = L"provider1";
EXPECT_TRUE(filter1.allow(data));
EXPECT_FALSE(filter2.allow(data));
EXPECT_TRUE(filter3.allow(data));
EXPECT_TRUE(filter4.allow(data));
EXPECT_TRUE(filter5.allow(data));

data.provider = L"provider2";
EXPECT_FALSE(filter1.allow(data));
EXPECT_TRUE(filter2.allow(data));
EXPECT_TRUE(filter3.allow(data));
EXPECT_TRUE(filter4.allow(data));
EXPECT_TRUE(filter5.allow(data));

data.provider = L"provider3";
EXPECT_FALSE(filter1.allow(data));
EXPECT_TRUE(filter2.allow(data));
EXPECT_FALSE(filter3.allow(data));
EXPECT_FALSE(filter4.allow(data));
EXPECT_TRUE(filter5.allow(data));

data.provider = L"provider4";
EXPECT_FALSE(filter1.allow(data));
EXPECT_TRUE(filter2.allow(data));
EXPECT_FALSE(filter3.allow(data));
EXPECT_FALSE(filter4.allow(data));
EXPECT_FALSE(filter5.allow(data));
}

TEST(eventlog_filter, event_id) {
event_filter filter1("event_id=5", spdlog::default_logger());
event_filter filter2("event_id!=5", spdlog::default_logger());
event_filter filter3("event_id in (5, 6)", spdlog::default_logger());
event_filter filter4("event_id=5 or event_id=6", spdlog::default_logger());
event_filter filter5("event_id in (5, 6) or event_id in (7)",
spdlog::default_logger());
}
2 changes: 0 additions & 2 deletions agent/test/filter_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,6 @@
*/

#include <gtest/gtest.h>
#include <spdlog/spdlog.h>
#include <stdexcept>

#include "filter.hh"
#include "filter_rules.cc"
Expand Down

0 comments on commit 56b8959

Please sign in to comment.