initial commit
This commit is contained in:
51
src/Aggregator.h
Normal file
51
src/Aggregator.h
Normal file
@@ -0,0 +1,51 @@
|
||||
// +------------------------------------------------------------------+
|
||||
// | ____ _ _ __ __ _ __ |
|
||||
// | / ___| |__ ___ ___| | __ | \/ | |/ / |
|
||||
// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / |
|
||||
// | | |___| | | | __/ (__| < | | | | . \ |
|
||||
// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ |
|
||||
// | |
|
||||
// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de |
|
||||
// +------------------------------------------------------------------+
|
||||
//
|
||||
// This file is part of Check_MK.
|
||||
// The official homepage is at http://mathias-kettner.de/check_mk.
|
||||
//
|
||||
// check_mk is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation in version 2. check_mk is distributed
|
||||
// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with-
|
||||
// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
// PARTICULAR PURPOSE. See the GNU General Public License for more de-
|
||||
// tails. You should have received a copy of the GNU General Public
|
||||
// License along with GNU Make; see the file COPYING. If not, write
|
||||
// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
// Boston, MA 02110-1301 USA.
|
||||
|
||||
#ifndef Aggregator_h
|
||||
#define Aggregator_h
|
||||
|
||||
#include "config.h" // IWYU pragma: keep
|
||||
#include <cmath>
|
||||
#include <functional>
|
||||
#include "Renderer.h"
|
||||
#include "Row.h"
|
||||
#include "contact_fwd.h"
|
||||
class Query;
|
||||
|
||||
class Aggregation {
|
||||
public:
|
||||
virtual ~Aggregation() = default;
|
||||
virtual void update(double value) = 0;
|
||||
[[nodiscard]] virtual double value() const = 0;
|
||||
};
|
||||
|
||||
class Aggregator {
|
||||
public:
|
||||
virtual ~Aggregator() = default;
|
||||
virtual void consume(Row row, const contact *auth_user,
|
||||
std::chrono::seconds timezone_offset) = 0;
|
||||
virtual void output(RowRenderer &r) const = 0;
|
||||
};
|
||||
|
||||
#endif // Aggregator_h
|
||||
167
src/AndingFilter.cc
Normal file
167
src/AndingFilter.cc
Normal file
@@ -0,0 +1,167 @@
|
||||
// +------------------------------------------------------------------+
|
||||
// | ____ _ _ __ __ _ __ |
|
||||
// | / ___| |__ ___ ___| | __ | \/ | |/ / |
|
||||
// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / |
|
||||
// | | |___| | | | __/ (__| < | | | | . \ |
|
||||
// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ |
|
||||
// | |
|
||||
// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de |
|
||||
// +------------------------------------------------------------------+
|
||||
//
|
||||
// This file is part of Check_MK.
|
||||
// The official homepage is at http://mathias-kettner.de/check_mk.
|
||||
//
|
||||
// check_mk is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation in version 2. check_mk is distributed
|
||||
// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with-
|
||||
// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
// PARTICULAR PURPOSE. See the GNU General Public License for more de-
|
||||
// tails. You should have received a copy of the GNU General Public
|
||||
// License along with GNU Make; see the file COPYING. If not, write
|
||||
// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
// Boston, MA 02110-1301 USA.
|
||||
|
||||
#include "AndingFilter.h"
|
||||
#include <algorithm>
|
||||
#include <iterator>
|
||||
#include <memory>
|
||||
#include <ostream>
|
||||
#include <type_traits>
|
||||
#include <vector>
|
||||
#include "Filter.h"
|
||||
#include "OringFilter.h"
|
||||
#include "Row.h"
|
||||
|
||||
// static
|
||||
std::unique_ptr<Filter> AndingFilter::make(Kind kind, Filters subfilters) {
|
||||
Filters filters;
|
||||
for (const auto &filter : subfilters) {
|
||||
if (filter->is_contradiction()) {
|
||||
return OringFilter::make(kind, Filters());
|
||||
}
|
||||
auto conjuncts = filter->conjuncts();
|
||||
filters.insert(filters.end(),
|
||||
std::make_move_iterator(conjuncts.begin()),
|
||||
std::make_move_iterator(conjuncts.end()));
|
||||
}
|
||||
return filters.size() == 1 ? std::move(filters[0])
|
||||
: std::make_unique<AndingFilter>(
|
||||
kind, std::move(filters), Secret());
|
||||
}
|
||||
|
||||
bool AndingFilter::accepts(Row row, const contact *auth_user,
|
||||
std::chrono::seconds timezone_offset) const {
|
||||
for (const auto &filter : _subfilters) {
|
||||
if (!filter->accepts(row, auth_user, timezone_offset)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
std::unique_ptr<Filter> AndingFilter::partialFilter(
|
||||
std::function<bool(const Column &)> predicate) const {
|
||||
Filters filters;
|
||||
std::transform(
|
||||
_subfilters.begin(), _subfilters.end(), std::back_inserter(filters),
|
||||
[&](const auto &filter) { return filter->partialFilter(predicate); });
|
||||
return make(kind(), std::move(filters));
|
||||
}
|
||||
|
||||
std::optional<std::string> AndingFilter::stringValueRestrictionFor(
|
||||
const std::string &column_name) const {
|
||||
for (const auto &filter : _subfilters) {
|
||||
if (auto value = filter->stringValueRestrictionFor(column_name)) {
|
||||
return {value};
|
||||
}
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
std::optional<int32_t> AndingFilter::greatestLowerBoundFor(
|
||||
const std::string &column_name,
|
||||
std::chrono::seconds timezone_offset) const {
|
||||
std::optional<int32_t> result;
|
||||
for (const auto &filter : _subfilters) {
|
||||
if (auto glb =
|
||||
filter->greatestLowerBoundFor(column_name, timezone_offset)) {
|
||||
result = result ? std::max(*result, *glb) : glb;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
std::optional<int32_t> AndingFilter::leastUpperBoundFor(
|
||||
const std::string &column_name,
|
||||
std::chrono::seconds timezone_offset) const {
|
||||
std::optional<int32_t> result;
|
||||
for (const auto &filter : _subfilters) {
|
||||
if (auto lub =
|
||||
filter->leastUpperBoundFor(column_name, timezone_offset)) {
|
||||
result = result ? std::min(*result, *lub) : lub;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
std::optional<std::bitset<32>> AndingFilter::valueSetLeastUpperBoundFor(
|
||||
const std::string &column_name,
|
||||
std::chrono::seconds timezone_offset) const {
|
||||
std::optional<std::bitset<32>> result;
|
||||
for (const auto &filter : _subfilters) {
|
||||
if (auto foo = filter->valueSetLeastUpperBoundFor(column_name,
|
||||
timezone_offset)) {
|
||||
result = result ? (*result & *foo) : foo;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
std::unique_ptr<Filter> AndingFilter::copy() const {
|
||||
return make(kind(), conjuncts());
|
||||
}
|
||||
|
||||
std::unique_ptr<Filter> AndingFilter::negate() const {
|
||||
Filters filters;
|
||||
std::transform(_subfilters.begin(), _subfilters.end(),
|
||||
std::back_inserter(filters),
|
||||
[](const auto &filter) { return filter->negate(); });
|
||||
return OringFilter::make(kind(), std::move(filters));
|
||||
}
|
||||
|
||||
bool AndingFilter::is_tautology() const { return _subfilters.empty(); }
|
||||
|
||||
bool AndingFilter::is_contradiction() const { return false; }
|
||||
|
||||
Filters AndingFilter::disjuncts() const {
|
||||
Filters filters;
|
||||
filters.push_back(copy());
|
||||
return filters;
|
||||
}
|
||||
|
||||
Filters AndingFilter::conjuncts() const {
|
||||
Filters filters;
|
||||
std::transform(_subfilters.begin(), _subfilters.end(),
|
||||
std::back_inserter(filters),
|
||||
[](const auto &filter) { return filter->copy(); });
|
||||
return filters;
|
||||
}
|
||||
|
||||
std::ostream &AndingFilter::print(std::ostream &os) const {
|
||||
for (const auto &filter : _subfilters) {
|
||||
os << *filter << "\\n";
|
||||
}
|
||||
switch (kind()) {
|
||||
case Kind::row:
|
||||
os << "And";
|
||||
break;
|
||||
case Kind::stats:
|
||||
os << "StatsAnd";
|
||||
break;
|
||||
case Kind::wait_condition:
|
||||
os << "WaitConditionAnd";
|
||||
break;
|
||||
}
|
||||
return os << ": " << _subfilters.size();
|
||||
}
|
||||
81
src/AndingFilter.h
Normal file
81
src/AndingFilter.h
Normal file
@@ -0,0 +1,81 @@
|
||||
// +------------------------------------------------------------------+
|
||||
// | ____ _ _ __ __ _ __ |
|
||||
// | / ___| |__ ___ ___| | __ | \/ | |/ / |
|
||||
// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / |
|
||||
// | | |___| | | | __/ (__| < | | | | . \ |
|
||||
// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ |
|
||||
// | |
|
||||
// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de |
|
||||
// +------------------------------------------------------------------+
|
||||
//
|
||||
// This file is part of Check_MK.
|
||||
// The official homepage is at http://mathias-kettner.de/check_mk.
|
||||
//
|
||||
// check_mk is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation in version 2. check_mk is distributed
|
||||
// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with-
|
||||
// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
// PARTICULAR PURPOSE. See the GNU General Public License for more de-
|
||||
// tails. You should have received a copy of the GNU General Public
|
||||
// License along with GNU Make; see the file COPYING. If not, write
|
||||
// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
// Boston, MA 02110-1301 USA.
|
||||
|
||||
#ifndef AndingFilter_h
|
||||
#define AndingFilter_h
|
||||
|
||||
#include "config.h" // IWYU pragma: keep
|
||||
#include <bitset>
|
||||
#include <chrono>
|
||||
#include <cstdint>
|
||||
#include <functional>
|
||||
#include <iosfwd>
|
||||
#include <memory>
|
||||
#include <optional>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include "Filter.h"
|
||||
#include "contact_fwd.h"
|
||||
class Column;
|
||||
class Row;
|
||||
|
||||
class AndingFilter : public Filter {
|
||||
struct Secret {};
|
||||
|
||||
public:
|
||||
static std::unique_ptr<Filter> make(Kind kind, Filters subfilters);
|
||||
bool accepts(Row row, const contact *auth_user,
|
||||
std::chrono::seconds timezone_offset) const override;
|
||||
std::unique_ptr<Filter> partialFilter(
|
||||
std::function<bool(const Column &)> predicate) const override;
|
||||
[[nodiscard]] std::optional<std::string> stringValueRestrictionFor(
|
||||
const std::string &column_name) const override;
|
||||
[[nodiscard]] std::optional<int32_t> greatestLowerBoundFor(
|
||||
const std::string &column_name,
|
||||
std::chrono::seconds timezone_offset) const override;
|
||||
[[nodiscard]] std::optional<int32_t> leastUpperBoundFor(
|
||||
const std::string &column_name,
|
||||
std::chrono::seconds timezone_offset) const override;
|
||||
[[nodiscard]] std::optional<std::bitset<32>> valueSetLeastUpperBoundFor(
|
||||
const std::string &column_name,
|
||||
std::chrono::seconds timezone_offset) const override;
|
||||
[[nodiscard]] std::unique_ptr<Filter> copy() const override;
|
||||
[[nodiscard]] std::unique_ptr<Filter> negate() const override;
|
||||
[[nodiscard]] bool is_tautology() const override;
|
||||
[[nodiscard]] bool is_contradiction() const override;
|
||||
[[nodiscard]] Filters disjuncts() const override;
|
||||
[[nodiscard]] Filters conjuncts() const override;
|
||||
|
||||
// NOTE: This is effectively private, but it can't be declared like this
|
||||
// because of std::make_unique.
|
||||
AndingFilter(Kind kind, Filters subfilters, Secret /*unused*/)
|
||||
: Filter(kind), _subfilters(std::move(subfilters)) {}
|
||||
|
||||
private:
|
||||
Filters _subfilters;
|
||||
|
||||
std::ostream &print(std::ostream &os) const override;
|
||||
};
|
||||
|
||||
#endif // AndingFilter_h
|
||||
48
src/AtomicInt32PointerColumn.h
Normal file
48
src/AtomicInt32PointerColumn.h
Normal file
@@ -0,0 +1,48 @@
|
||||
// +------------------------------------------------------------------+
|
||||
// | ____ _ _ __ __ _ __ |
|
||||
// | / ___| |__ ___ ___| | __ | \/ | |/ / |
|
||||
// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / |
|
||||
// | | |___| | | | __/ (__| < | | | | . \ |
|
||||
// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ |
|
||||
// | |
|
||||
// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de |
|
||||
// +------------------------------------------------------------------+
|
||||
//
|
||||
// This file is part of Check_MK.
|
||||
// The official homepage is at http://mathias-kettner.de/check_mk.
|
||||
//
|
||||
// check_mk is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation in version 2. check_mk is distributed
|
||||
// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with-
|
||||
// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
// PARTICULAR PURPOSE. See the GNU General Public License for more de-
|
||||
// tails. You should have received a copy of the GNU General Public
|
||||
// License along with GNU Make; see the file COPYING. If not, write
|
||||
// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
// Boston, MA 02110-1301 USA.
|
||||
|
||||
#ifndef AtomicInt32PointerColumn_h
|
||||
#define AtomicInt32PointerColumn_h
|
||||
|
||||
#include "config.h" // IWYU pragma: keep
|
||||
#include <atomic>
|
||||
#include "IntColumn.h"
|
||||
|
||||
class AtomicInt32PointerColumn : public IntColumn {
|
||||
public:
|
||||
AtomicInt32PointerColumn(const std::string& name,
|
||||
const std::string& description,
|
||||
const std::atomic_int32_t* number)
|
||||
: IntColumn(name, description, -1, -1, -1, 0), _number(number) {}
|
||||
|
||||
int32_t getValue(Row /* row */,
|
||||
const contact* /* auth_user */) const override {
|
||||
return _number->load();
|
||||
}
|
||||
|
||||
private:
|
||||
const std::atomic_int32_t* const _number;
|
||||
};
|
||||
|
||||
#endif // AtomicInt32PointerColumn_h
|
||||
103
src/AttributeListAsIntColumn.cc
Normal file
103
src/AttributeListAsIntColumn.cc
Normal file
@@ -0,0 +1,103 @@
|
||||
// +------------------------------------------------------------------+
|
||||
// | ____ _ _ __ __ _ __ |
|
||||
// | / ___| |__ ___ ___| | __ | \/ | |/ / |
|
||||
// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / |
|
||||
// | | |___| | | | __/ (__| < | | | | . \ |
|
||||
// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ |
|
||||
// | |
|
||||
// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de |
|
||||
// +------------------------------------------------------------------+
|
||||
//
|
||||
// This file is part of Check_MK.
|
||||
// The official homepage is at http://mathias-kettner.de/check_mk.
|
||||
//
|
||||
// check_mk is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation in version 2. check_mk is distributed
|
||||
// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with-
|
||||
// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
// PARTICULAR PURPOSE. See the GNU General Public License for more de-
|
||||
// tails. You should have received a copy of the GNU General Public
|
||||
// License along with GNU Make; see the file COPYING. If not, write
|
||||
// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
// Boston, MA 02110-1301 USA.
|
||||
|
||||
#include "AttributeListAsIntColumn.h"
|
||||
#include <bitset>
|
||||
#include <cctype>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <ostream>
|
||||
#include <utility>
|
||||
#include "Filter.h"
|
||||
#include "IntFilter.h"
|
||||
#include "Logger.h"
|
||||
#include "Row.h"
|
||||
#include "strutil.h"
|
||||
|
||||
namespace {
|
||||
// see MODATTR_FOO in nagios/common.h
|
||||
std::map<std::string, unsigned long> known_attributes = {
|
||||
{"notifications_enabled", 0}, {"active_checks_enabled", 1},
|
||||
{"passive_checks_enabled", 2}, {"event_handler_enabled", 3},
|
||||
{"flap_detection_enabled", 4}, {"failure_prediction_enabled", 5},
|
||||
{"performance_data_enabled", 6}, {"obsessive_handler_enabled", 7},
|
||||
{"event_handler_command", 8}, {"check_command", 9},
|
||||
{"normal_check_interval", 10}, {"retry_check_interval", 11},
|
||||
{"max_check_attempts", 12}, {"freshness_checks_enabled", 13},
|
||||
{"check_timeperiod", 14}, {"custom_variable", 15},
|
||||
{"notification_timeperiod", 16}};
|
||||
|
||||
using modified_atttibutes = std::bitset<32>;
|
||||
|
||||
std::string refValueFor(const std::string &value, Logger *logger) {
|
||||
if (isdigit(value[0]) != 0) {
|
||||
return value;
|
||||
}
|
||||
|
||||
std::vector<char> value_vec(value.begin(), value.end());
|
||||
value_vec.push_back('\0');
|
||||
char *scan = &value_vec[0];
|
||||
|
||||
modified_atttibutes values;
|
||||
for (const char *t; (t = next_token(&scan, ',')) != nullptr;) {
|
||||
auto it = known_attributes.find(t);
|
||||
if (it == known_attributes.end()) {
|
||||
Informational(logger)
|
||||
<< "Ignoring invalid value '" << t << "' for attribute list";
|
||||
continue;
|
||||
}
|
||||
values[it->second] = true;
|
||||
}
|
||||
return std::to_string(values.to_ulong());
|
||||
}
|
||||
} // namespace
|
||||
|
||||
std::unique_ptr<Filter> AttributeListAsIntColumn::createFilter(
|
||||
Filter::Kind kind, RelationalOperator relOp,
|
||||
const std::string &value) const {
|
||||
return std::make_unique<IntFilter>(kind, *this, relOp,
|
||||
refValueFor(value, logger()));
|
||||
}
|
||||
|
||||
int32_t AttributeListAsIntColumn::getValue(
|
||||
Row row, const contact * /*auth_user*/) const {
|
||||
if (auto p = columnData<unsigned long>(row)) {
|
||||
return static_cast<int32_t>(*p);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
std::vector<std::string> AttributeListAsIntColumn::getAttributes(
|
||||
Row row) const {
|
||||
std::vector<std::string> attributes;
|
||||
if (auto p = columnData<unsigned long>(row)) {
|
||||
modified_atttibutes values(*p);
|
||||
for (const auto &entry : known_attributes) {
|
||||
if (values[entry.second]) {
|
||||
attributes.push_back(entry.first);
|
||||
}
|
||||
}
|
||||
}
|
||||
return attributes;
|
||||
}
|
||||
57
src/AttributeListAsIntColumn.h
Normal file
57
src/AttributeListAsIntColumn.h
Normal file
@@ -0,0 +1,57 @@
|
||||
// +------------------------------------------------------------------+
|
||||
// | ____ _ _ __ __ _ __ |
|
||||
// | / ___| |__ ___ ___| | __ | \/ | |/ / |
|
||||
// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / |
|
||||
// | | |___| | | | __/ (__| < | | | | . \ |
|
||||
// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ |
|
||||
// | |
|
||||
// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de |
|
||||
// +------------------------------------------------------------------+
|
||||
//
|
||||
// This file is part of Check_MK.
|
||||
// The official homepage is at http://mathias-kettner.de/check_mk.
|
||||
//
|
||||
// check_mk is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation in version 2. check_mk is distributed
|
||||
// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with-
|
||||
// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
// PARTICULAR PURPOSE. See the GNU General Public License for more de-
|
||||
// tails. You should have received a copy of the GNU General Public
|
||||
// License along with GNU Make; see the file COPYING. If not, write
|
||||
// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
// Boston, MA 02110-1301 USA.
|
||||
|
||||
#ifndef AttributeListAsIntColumn_h
|
||||
#define AttributeListAsIntColumn_h
|
||||
|
||||
#include "config.h" // IWYU pragma: keep
|
||||
#include <cstdint>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include "Filter.h"
|
||||
#include "IntColumn.h"
|
||||
#include "contact_fwd.h"
|
||||
#include "opids.h"
|
||||
class Row;
|
||||
|
||||
class AttributeListAsIntColumn : public IntColumn {
|
||||
public:
|
||||
AttributeListAsIntColumn(const std::string &name,
|
||||
const std::string &description,
|
||||
int indirect_offset, int extra_offset,
|
||||
int extra_extra_offset, int offset)
|
||||
: IntColumn(name, description, indirect_offset, extra_offset,
|
||||
extra_extra_offset, offset) {}
|
||||
|
||||
[[nodiscard]] std::unique_ptr<Filter> createFilter(
|
||||
Filter::Kind kind, RelationalOperator relOp,
|
||||
const std::string &value) const override;
|
||||
|
||||
int32_t getValue(Row row, const contact *auth_user) const override;
|
||||
|
||||
[[nodiscard]] std::vector<std::string> getAttributes(Row row) const;
|
||||
};
|
||||
|
||||
#endif // AttributeListAsIntColumn_h
|
||||
41
src/AttributeListColumn.cc
Normal file
41
src/AttributeListColumn.cc
Normal file
@@ -0,0 +1,41 @@
|
||||
// +------------------------------------------------------------------+
|
||||
// | ____ _ _ __ __ _ __ |
|
||||
// | / ___| |__ ___ ___| | __ | \/ | |/ / |
|
||||
// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / |
|
||||
// | | |___| | | | __/ (__| < | | | | . \ |
|
||||
// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ |
|
||||
// | |
|
||||
// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de |
|
||||
// +------------------------------------------------------------------+
|
||||
//
|
||||
// This file is part of Check_MK.
|
||||
// The official homepage is at http://mathias-kettner.de/check_mk.
|
||||
//
|
||||
// check_mk is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation in version 2. check_mk is distributed
|
||||
// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with-
|
||||
// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
// PARTICULAR PURPOSE. See the GNU General Public License for more de-
|
||||
// tails. You should have received a copy of the GNU General Public
|
||||
// License along with GNU Make; see the file COPYING. If not, write
|
||||
// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
// Boston, MA 02110-1301 USA.
|
||||
|
||||
#include "AttributeListColumn.h"
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
#include "Filter.h" // IWYU pragma: keep
|
||||
#include "Row.h"
|
||||
|
||||
std::unique_ptr<Filter> AttributeListColumn::createFilter(
|
||||
Filter::Kind kind, RelationalOperator relOp,
|
||||
const std::string &value) const {
|
||||
return _int_view_column.createFilter(kind, relOp, value);
|
||||
}
|
||||
|
||||
std::vector<std::string> AttributeListColumn::getValue(
|
||||
Row row, const contact * /*auth_user*/,
|
||||
std::chrono::seconds /*timezone_offset*/) const {
|
||||
return _int_view_column.getAttributes(row);
|
||||
}
|
||||
62
src/AttributeListColumn.h
Normal file
62
src/AttributeListColumn.h
Normal file
@@ -0,0 +1,62 @@
|
||||
// +------------------------------------------------------------------+
|
||||
// | ____ _ _ __ __ _ __ |
|
||||
// | / ___| |__ ___ ___| | __ | \/ | |/ / |
|
||||
// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / |
|
||||
// | | |___| | | | __/ (__| < | | | | . \ |
|
||||
// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ |
|
||||
// | |
|
||||
// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de |
|
||||
// +------------------------------------------------------------------+
|
||||
//
|
||||
// This file is part of Check_MK.
|
||||
// The official homepage is at http://mathias-kettner.de/check_mk.
|
||||
//
|
||||
// check_mk is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation in version 2. check_mk is distributed
|
||||
// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with-
|
||||
// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
// PARTICULAR PURPOSE. See the GNU General Public License for more de-
|
||||
// tails. You should have received a copy of the GNU General Public
|
||||
// License along with GNU Make; see the file COPYING. If not, write
|
||||
// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
// Boston, MA 02110-1301 USA.
|
||||
|
||||
#ifndef AttributeListColumn_h
|
||||
#define AttributeListColumn_h
|
||||
|
||||
#include "config.h" // IWYU pragma: keep
|
||||
#include <chrono>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include "AttributeListAsIntColumn.h"
|
||||
#include "Filter.h"
|
||||
#include "ListColumn.h"
|
||||
#include "contact_fwd.h"
|
||||
#include "opids.h"
|
||||
class Row;
|
||||
|
||||
class AttributeListColumn : public ListColumn {
|
||||
public:
|
||||
AttributeListColumn(const std::string &name, const std::string &description,
|
||||
int indirect_offset, int extra_offset,
|
||||
int extra_extra_offset, int offset)
|
||||
: ListColumn(name, description, indirect_offset, extra_offset,
|
||||
extra_extra_offset, offset)
|
||||
, _int_view_column(name, description, indirect_offset, extra_offset,
|
||||
extra_extra_offset, offset) {}
|
||||
|
||||
[[nodiscard]] std::unique_ptr<Filter> createFilter(
|
||||
Filter::Kind kind, RelationalOperator relOp,
|
||||
const std::string &value) const override;
|
||||
|
||||
std::vector<std::string> getValue(
|
||||
Row row, const contact *auth_user,
|
||||
std::chrono::seconds timezone_offset) const override;
|
||||
|
||||
private:
|
||||
AttributeListAsIntColumn _int_view_column;
|
||||
};
|
||||
|
||||
#endif // AttributeListColumn_h
|
||||
99
src/BitMask.h
Normal file
99
src/BitMask.h
Normal file
@@ -0,0 +1,99 @@
|
||||
// +------------------------------------------------------------------+
|
||||
// | ____ _ _ __ __ _ __ |
|
||||
// | / ___| |__ ___ ___| | __ | \/ | |/ / |
|
||||
// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / |
|
||||
// | | |___| | | | __/ (__| < | | | | . \ |
|
||||
// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ |
|
||||
// | |
|
||||
// | Copyright Mathias Kettner 2017 mk@mathias-kettner.de |
|
||||
// +------------------------------------------------------------------+
|
||||
//
|
||||
// This file is part of Check_MK.
|
||||
// The official homepage is at http://mathias-kettner.de/check_mk.
|
||||
//
|
||||
// check_mk is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation in version 2. check_mk is distributed
|
||||
// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with-
|
||||
// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
// PARTICULAR PURPOSE. See the GNU General Public License for more de-
|
||||
// tails. You should have received a copy of the GNU General Public
|
||||
// License along with GNU Make; see the file COPYING. If not, write
|
||||
// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
// Boston, MA 02110-1301 USA.
|
||||
|
||||
#ifndef BitMask_h
|
||||
#define BitMask_h
|
||||
|
||||
#include "config.h" // IWYU pragma: keep
|
||||
#include <type_traits>
|
||||
|
||||
namespace mk {
|
||||
// Return the enumerator's value as a compile-time constant, see Scott Meyer's
|
||||
// "Effective Modern C++", item 10.
|
||||
template <typename Enum>
|
||||
constexpr auto toUType(Enum e) noexcept {
|
||||
return static_cast<std::underlying_type_t<Enum>>(e);
|
||||
}
|
||||
|
||||
// A marker trait which enables the bit mask operators
|
||||
template <typename Enum>
|
||||
struct is_bit_mask {
|
||||
static const bool value = false;
|
||||
};
|
||||
|
||||
// A helper macro to make the use sites of the marker trait less verbose
|
||||
#define IS_BIT_MASK(ENUM) \
|
||||
namespace mk { \
|
||||
template <> \
|
||||
struct is_bit_mask<ENUM> { \
|
||||
static const bool value = true; \
|
||||
}; \
|
||||
}
|
||||
|
||||
// A helper template to make template definitions a bit shorter
|
||||
template <typename T>
|
||||
constexpr bool is_bit_mask_v = is_bit_mask<T>::value;
|
||||
} // namespace mk
|
||||
|
||||
template <typename Enum, typename = std::enable_if_t<mk::is_bit_mask_v<Enum>>>
|
||||
inline constexpr Enum operator&(Enum x, Enum y) {
|
||||
return x &= y;
|
||||
}
|
||||
|
||||
template <typename Enum, typename = std::enable_if_t<mk::is_bit_mask_v<Enum>>>
|
||||
inline constexpr Enum operator|(Enum x, Enum y) {
|
||||
return x |= y;
|
||||
}
|
||||
|
||||
template <typename Enum, typename = std::enable_if_t<mk::is_bit_mask_v<Enum>>>
|
||||
inline constexpr Enum operator^(Enum x, Enum y) {
|
||||
return x ^= y;
|
||||
}
|
||||
|
||||
template <typename Enum, typename = std::enable_if_t<mk::is_bit_mask_v<Enum>>>
|
||||
inline constexpr Enum operator~(Enum x) {
|
||||
return Enum(~mk::toUType(x));
|
||||
}
|
||||
|
||||
template <typename Enum, typename = std::enable_if_t<mk::is_bit_mask_v<Enum>>>
|
||||
inline Enum &operator|=(Enum &x, Enum y) {
|
||||
return x = Enum(mk::toUType(x) | mk::toUType(y));
|
||||
}
|
||||
|
||||
template <typename Enum, typename = std::enable_if_t<mk::is_bit_mask_v<Enum>>>
|
||||
inline const Enum &operator&=(Enum &x, Enum y) {
|
||||
return x = Enum(mk::toUType(x) & mk::toUType(y));
|
||||
}
|
||||
|
||||
template <typename Enum, typename = std::enable_if_t<mk::is_bit_mask_v<Enum>>>
|
||||
inline Enum &operator^=(Enum &x, Enum y) {
|
||||
return x = Enum(mk::toUType(x) ^ mk::toUType(y));
|
||||
}
|
||||
|
||||
template <typename Enum, typename = std::enable_if_t<mk::is_bit_mask_v<Enum>>>
|
||||
inline bool is_empty_bit_mask(Enum x) {
|
||||
return x == Enum(0);
|
||||
}
|
||||
|
||||
#endif // BitMask_h
|
||||
50
src/BlobColumn.cc
Normal file
50
src/BlobColumn.cc
Normal file
@@ -0,0 +1,50 @@
|
||||
// +------------------------------------------------------------------+
|
||||
// | ____ _ _ __ __ _ __ |
|
||||
// | / ___| |__ ___ ___| | __ | \/ | |/ / |
|
||||
// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / |
|
||||
// | | |___| | | | __/ (__| < | | | | . \ |
|
||||
// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ |
|
||||
// | |
|
||||
// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de |
|
||||
// +------------------------------------------------------------------+
|
||||
//
|
||||
// This file is part of Check_MK.
|
||||
// The official homepage is at http://mathias-kettner.de/check_mk.
|
||||
//
|
||||
// check_mk is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation in version 2. check_mk is distributed
|
||||
// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with-
|
||||
// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
// PARTICULAR PURPOSE. See the GNU General Public License for more de-
|
||||
// tails. You should have received a copy of the GNU General Public
|
||||
// License along with GNU Make; see the file COPYING. If not, write
|
||||
// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
// Boston, MA 02110-1301 USA.
|
||||
|
||||
#include "BlobColumn.h"
|
||||
#include <stdexcept>
|
||||
#include "Renderer.h"
|
||||
#include "Row.h"
|
||||
|
||||
void BlobColumn::output(Row row, RowRenderer& r, const contact* /*auth_user*/,
|
||||
std::chrono::seconds /*timezone_offset*/) const {
|
||||
if (std::unique_ptr<std::vector<char>> blob = getValue(row)) {
|
||||
r.output(*blob);
|
||||
} else {
|
||||
r.output(Null());
|
||||
}
|
||||
}
|
||||
|
||||
std::unique_ptr<Filter> BlobColumn::createFilter(
|
||||
Filter::Kind /*unused*/, RelationalOperator /*unused*/,
|
||||
const std::string& /*unused*/) const {
|
||||
throw std::runtime_error("filtering on blob column '" + name() +
|
||||
"' not supported");
|
||||
}
|
||||
|
||||
std::unique_ptr<Aggregator> BlobColumn::createAggregator(
|
||||
AggregationFactory /*factory*/) const {
|
||||
throw std::runtime_error("aggregating on blob column '" + name() +
|
||||
"' not supported");
|
||||
}
|
||||
65
src/BlobColumn.h
Normal file
65
src/BlobColumn.h
Normal file
@@ -0,0 +1,65 @@
|
||||
// +------------------------------------------------------------------+
|
||||
// | ____ _ _ __ __ _ __ |
|
||||
// | / ___| |__ ___ ___| | __ | \/ | |/ / |
|
||||
// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / |
|
||||
// | | |___| | | | __/ (__| < | | | | . \ |
|
||||
// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ |
|
||||
// | |
|
||||
// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de |
|
||||
// +------------------------------------------------------------------+
|
||||
//
|
||||
// This file is part of Check_MK.
|
||||
// The official homepage is at http://mathias-kettner.de/check_mk.
|
||||
//
|
||||
// check_mk is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation in version 2. check_mk is distributed
|
||||
// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with-
|
||||
// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
// PARTICULAR PURPOSE. See the GNU General Public License for more de-
|
||||
// tails. You should have received a copy of the GNU General Public
|
||||
// License along with GNU Make; see the file COPYING. If not, write
|
||||
// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
// Boston, MA 02110-1301 USA.
|
||||
|
||||
#ifndef BlobColumn_h
|
||||
#define BlobColumn_h
|
||||
|
||||
#include "config.h" // IWYU pragma: keep
|
||||
#include <chrono>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include "Column.h"
|
||||
#include "Filter.h"
|
||||
#include "contact_fwd.h"
|
||||
#include "opids.h"
|
||||
class Aggregator;
|
||||
class Row;
|
||||
class RowRenderer;
|
||||
|
||||
class BlobColumn : public Column {
|
||||
public:
|
||||
BlobColumn(const std::string &name, const std::string &description,
|
||||
int indirect_offset, int extra_offset, int extra_extra_offset,
|
||||
int offset)
|
||||
: Column(name, description, indirect_offset, extra_offset,
|
||||
extra_extra_offset, offset) {}
|
||||
|
||||
[[nodiscard]] ColumnType type() const override { return ColumnType::blob; }
|
||||
|
||||
void output(Row row, RowRenderer &r, const contact *auth_user,
|
||||
std::chrono::seconds timezone_offset) const override;
|
||||
|
||||
[[nodiscard]] std::unique_ptr<Filter> createFilter(
|
||||
Filter::Kind kind, RelationalOperator relOp,
|
||||
const std::string &value) const override;
|
||||
|
||||
[[nodiscard]] std::unique_ptr<Aggregator> createAggregator(
|
||||
AggregationFactory factory) const override;
|
||||
|
||||
[[nodiscard]] virtual std::unique_ptr<std::vector<char>> getValue(
|
||||
Row row) const = 0;
|
||||
};
|
||||
|
||||
#endif // BlobColumn_h
|
||||
142
src/ChronoUtils.h
Normal file
142
src/ChronoUtils.h
Normal file
@@ -0,0 +1,142 @@
|
||||
// +------------------------------------------------------------------+
|
||||
// | ____ _ _ __ __ _ __ |
|
||||
// | / ___| |__ ___ ___| | __ | \/ | |/ / |
|
||||
// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / |
|
||||
// | | |___| | | | __/ (__| < | | | | . \ |
|
||||
// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ |
|
||||
// | |
|
||||
// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de |
|
||||
// +------------------------------------------------------------------+
|
||||
//
|
||||
// This file is part of Check_MK.
|
||||
// The official homepage is at http://mathias-kettner.de/check_mk.
|
||||
//
|
||||
// check_mk is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation in version 2. check_mk is distributed
|
||||
// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with-
|
||||
// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
// PARTICULAR PURPOSE. See the GNU General Public License for more de-
|
||||
// tails. You should have received a copy of the GNU General Public
|
||||
// License along with GNU Make; see the file COPYING. If not, write
|
||||
// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
// Boston, MA 02110-1301 USA.
|
||||
|
||||
#ifndef ChronoUtils_h
|
||||
#define ChronoUtils_h
|
||||
|
||||
#include "config.h" // IWYU pragma: keep
|
||||
#include <chrono>
|
||||
#include <cstdlib>
|
||||
#include <ctime>
|
||||
#include <iomanip>
|
||||
#include <ratio>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
|
||||
using minutes_d = std::chrono::duration<double, std::ratio<60>>;
|
||||
|
||||
inline double elapsed_ms_since(std::chrono::steady_clock::time_point then) {
|
||||
return std::chrono::duration_cast<
|
||||
std::chrono::duration<double, std::milli>>(
|
||||
std::chrono::steady_clock::now() - then)
|
||||
.count();
|
||||
}
|
||||
|
||||
inline tm to_tm(std::chrono::system_clock::time_point tp) {
|
||||
time_t t = std::chrono::system_clock::to_time_t(tp);
|
||||
struct tm ret;
|
||||
// NOTE: A brilliant example of how to make a simple API function a total
|
||||
// chaos follows...
|
||||
#if defined(__STDC_LIB_EXT1__)
|
||||
// C11 function, only guaranteed to be available when a
|
||||
// #define __STDC_WANT_LIB_EXT1_ 1
|
||||
// is done before including <time.h>. Signature:
|
||||
// struct tm *localtime_s(const time_t *restrict timer,
|
||||
// struct tm *restrict result)
|
||||
localtime_s(&t, &ret);
|
||||
#elif defined(__WIN32)
|
||||
// Win32 variant, it keeps us entertained with swapped parameters and a
|
||||
// different return value, yay! Signature:
|
||||
// errno_t localtime_s(struct tm* _tm, const time_t *time)
|
||||
// We have to de-confuse cppcheck:
|
||||
// cppcheck-suppress uninitvar
|
||||
localtime_s(&ret, &t);
|
||||
#else
|
||||
// POSIX.1-2008 variant, available under MinGW64 only under obscure
|
||||
// circumstances, so better avoid it there. Signature:
|
||||
// struct tm *localtime_r(const time_t *restrict timer,
|
||||
// struct tm *restrict result);
|
||||
localtime_r(&t, &ret);
|
||||
#endif
|
||||
// Reason: see Win32 section above
|
||||
// cppcheck-suppress uninitvar
|
||||
return ret;
|
||||
}
|
||||
|
||||
inline std::chrono::system_clock::time_point from_tm(tm tp) {
|
||||
return std::chrono::system_clock::from_time_t(mktime(&tp));
|
||||
}
|
||||
|
||||
template <typename Rep, typename Period>
|
||||
inline timeval to_timeval(std::chrono::duration<Rep, Period> dur) {
|
||||
timeval tv;
|
||||
// NOTE: The static_casts below are needed to avoid warning on e.g. some
|
||||
// 32bit platforms, because the underlying types might be larger than the
|
||||
// timeval fields. We can't use the correct POSIX types time_t and
|
||||
// suseconds_t because of the broken MinGW cross compiler, so we revert to
|
||||
// decltype.
|
||||
tv.tv_sec = static_cast<decltype(tv.tv_sec)>(
|
||||
std::chrono::duration_cast<std::chrono::seconds>(dur).count());
|
||||
tv.tv_usec = static_cast<decltype(tv.tv_usec)>(
|
||||
std::chrono::duration_cast<std::chrono::microseconds>(
|
||||
dur % std::chrono::seconds(1))
|
||||
.count());
|
||||
return tv;
|
||||
}
|
||||
|
||||
inline std::chrono::system_clock::time_point from_timeval(const timeval &tv) {
|
||||
return std::chrono::system_clock::time_point(
|
||||
std::chrono::seconds(tv.tv_sec) +
|
||||
std::chrono::microseconds(tv.tv_usec));
|
||||
}
|
||||
|
||||
inline std::chrono::system_clock::time_point parse_time_t(
|
||||
const std::string &str) {
|
||||
return std::chrono::system_clock::from_time_t(atoi(str.c_str()));
|
||||
}
|
||||
|
||||
template <typename Dur>
|
||||
typename Dur::rep time_point_part(std::chrono::system_clock::time_point &tp) {
|
||||
return std::chrono::duration_cast<Dur>(tp.time_since_epoch() % Dur(1000))
|
||||
.count();
|
||||
}
|
||||
|
||||
class FormattedTimePoint {
|
||||
public:
|
||||
explicit FormattedTimePoint(std::chrono::system_clock::time_point tp,
|
||||
std::string format = default_format)
|
||||
: _tp(tp), _format(std::move(format)) {}
|
||||
explicit FormattedTimePoint(time_t t, std::string format = default_format)
|
||||
: _tp(std::chrono::system_clock::from_time_t(t))
|
||||
, _format(std::move(format)) {}
|
||||
|
||||
friend std::ostream &operator<<(std::ostream &os,
|
||||
const FormattedTimePoint &f) {
|
||||
tm local = to_tm(f._tp);
|
||||
return os << std::put_time(&local, f._format.c_str());
|
||||
}
|
||||
|
||||
private:
|
||||
std::chrono::system_clock::time_point _tp;
|
||||
std::string _format;
|
||||
|
||||
// NOTE: In a perfect world we would simply use "%F %T" below, but the "%F"
|
||||
// format is a C99 addition, and the "%T" format is part of The Single Unix
|
||||
// Specification. Both formats should be available in any C++11-compliant
|
||||
// compiler, but the MinGW cross compiler doesn't get this right. So let's
|
||||
// use their ancient expansions...
|
||||
static constexpr auto default_format = "%Y-%m-%d %H:%M:%S";
|
||||
};
|
||||
|
||||
#endif // ChronoUtils_h
|
||||
64
src/ClientQueue.cc
Normal file
64
src/ClientQueue.cc
Normal file
@@ -0,0 +1,64 @@
|
||||
// +------------------------------------------------------------------+
|
||||
// | ____ _ _ __ __ _ __ |
|
||||
// | / ___| |__ ___ ___| | __ | \/ | |/ / |
|
||||
// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / |
|
||||
// | | |___| | | | __/ (__| < | | | | . \ |
|
||||
// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ |
|
||||
// | |
|
||||
// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de |
|
||||
// +------------------------------------------------------------------+
|
||||
//
|
||||
// This file is part of Check_MK.
|
||||
// The official homepage is at http://mathias-kettner.de/check_mk.
|
||||
//
|
||||
// check_mk is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation in version 2. check_mk is distributed
|
||||
// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with-
|
||||
// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
// PARTICULAR PURPOSE. See the GNU General Public License for more de-
|
||||
// tails. You should have received a copy of the GNU General Public
|
||||
// License along with GNU Make; see the file COPYING. If not, write
|
||||
// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
// Boston, MA 02110-1301 USA.
|
||||
|
||||
#include "ClientQueue.h"
|
||||
#include <unistd.h>
|
||||
#include <algorithm>
|
||||
|
||||
ClientQueue::ClientQueue() : _should_terminate(false) {}
|
||||
|
||||
ClientQueue::~ClientQueue() {
|
||||
std::for_each(_queue.begin(), _queue.end(), close);
|
||||
}
|
||||
|
||||
void ClientQueue::addConnection(int fd) {
|
||||
{
|
||||
std::lock_guard<std::mutex> lg(_mutex);
|
||||
_queue.push_back(fd);
|
||||
}
|
||||
_cond.notify_one();
|
||||
}
|
||||
|
||||
int ClientQueue::popConnection() {
|
||||
std::unique_lock<std::mutex> ul(_mutex);
|
||||
while (_queue.empty() && !_should_terminate) {
|
||||
_cond.wait(ul);
|
||||
}
|
||||
if (_queue.empty()) {
|
||||
return -1;
|
||||
}
|
||||
int fd = _queue.front();
|
||||
_queue.pop_front();
|
||||
return fd;
|
||||
}
|
||||
|
||||
// Note: What we *really* want here is the functionality of
|
||||
// notify_all_at_thread_exit.
|
||||
void ClientQueue::terminate() {
|
||||
{
|
||||
std::lock_guard<std::mutex> lg(_mutex);
|
||||
_should_terminate = true;
|
||||
}
|
||||
_cond.notify_all();
|
||||
}
|
||||
50
src/ClientQueue.h
Normal file
50
src/ClientQueue.h
Normal file
@@ -0,0 +1,50 @@
|
||||
// +------------------------------------------------------------------+
|
||||
// | ____ _ _ __ __ _ __ |
|
||||
// | / ___| |__ ___ ___| | __ | \/ | |/ / |
|
||||
// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / |
|
||||
// | | |___| | | | __/ (__| < | | | | . \ |
|
||||
// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ |
|
||||
// | |
|
||||
// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de |
|
||||
// +------------------------------------------------------------------+
|
||||
//
|
||||
// This file is part of Check_MK.
|
||||
// The official homepage is at http://mathias-kettner.de/check_mk.
|
||||
//
|
||||
// check_mk is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation in version 2. check_mk is distributed
|
||||
// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with-
|
||||
// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
// PARTICULAR PURPOSE. See the GNU General Public License for more de-
|
||||
// tails. You should have received a copy of the GNU General Public
|
||||
// License along with GNU Make; see the file COPYING. If not, write
|
||||
// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
// Boston, MA 02110-1301 USA.
|
||||
|
||||
#ifndef ClientQueue_h
|
||||
#define ClientQueue_h
|
||||
|
||||
#include "config.h" // IWYU pragma: keep
|
||||
#include <condition_variable>
|
||||
#include <deque>
|
||||
#include <mutex>
|
||||
|
||||
class ClientQueue {
|
||||
public:
|
||||
ClientQueue();
|
||||
~ClientQueue();
|
||||
void addConnection(int fd);
|
||||
int popConnection();
|
||||
void terminate();
|
||||
|
||||
private:
|
||||
// The mutext protects _queue and _should_terminate, and it works together
|
||||
// with the condition variable.
|
||||
std::mutex _mutex;
|
||||
std::deque<int> _queue;
|
||||
bool _should_terminate;
|
||||
std::condition_variable _cond;
|
||||
};
|
||||
|
||||
#endif // ClientQueue_h
|
||||
57
src/Column.cc
Normal file
57
src/Column.cc
Normal file
@@ -0,0 +1,57 @@
|
||||
// +------------------------------------------------------------------+
|
||||
// | ____ _ _ __ __ _ __ |
|
||||
// | / ___| |__ ___ ___| | __ | \/ | |/ / |
|
||||
// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / |
|
||||
// | | |___| | | | __/ (__| < | | | | . \ |
|
||||
// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ |
|
||||
// | |
|
||||
// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de |
|
||||
// +------------------------------------------------------------------+
|
||||
//
|
||||
// This file is part of Check_MK.
|
||||
// The official homepage is at http://mathias-kettner.de/check_mk.
|
||||
//
|
||||
// check_mk is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation in version 2. check_mk is distributed
|
||||
// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with-
|
||||
// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
// PARTICULAR PURPOSE. See the GNU General Public License for more de-
|
||||
// tails. You should have received a copy of the GNU General Public
|
||||
// License along with GNU Make; see the file COPYING. If not, write
|
||||
// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
// Boston, MA 02110-1301 USA.
|
||||
|
||||
#include "Column.h"
|
||||
#include <utility>
|
||||
#include "Logger.h"
|
||||
|
||||
Column::Column(std::string name, std::string description, int indirect_offset,
|
||||
int extra_offset, int extra_extra_offset, int offset)
|
||||
: _logger(Logger::getLogger("cmk.livestatus"))
|
||||
, _name(std::move(name))
|
||||
, _description(std::move(description))
|
||||
, _indirect_offset(indirect_offset)
|
||||
, _extra_offset(extra_offset)
|
||||
, _extra_extra_offset(extra_extra_offset)
|
||||
, _offset(offset) {}
|
||||
|
||||
namespace {
|
||||
const void *add(const void *data, int offset) {
|
||||
return (data == nullptr || offset < 0) ? data
|
||||
: offset_cast<void>(data, offset);
|
||||
}
|
||||
|
||||
const void *shift(const void *data, int offset) {
|
||||
return (data == nullptr || offset < 0)
|
||||
? data
|
||||
: *offset_cast<const void *>(data, offset);
|
||||
}
|
||||
} // namespace
|
||||
|
||||
const void *Column::shiftPointer(Row row) const {
|
||||
return add(shift(shift(shift(row.rawData<const void>(), _indirect_offset),
|
||||
_extra_offset),
|
||||
_extra_extra_offset),
|
||||
_offset);
|
||||
}
|
||||
95
src/Column.h
Normal file
95
src/Column.h
Normal file
@@ -0,0 +1,95 @@
|
||||
// +------------------------------------------------------------------+
|
||||
// | ____ _ _ __ __ _ __ |
|
||||
// | / ___| |__ ___ ___| | __ | \/ | |/ / |
|
||||
// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / |
|
||||
// | | |___| | | | __/ (__| < | | | | . \ |
|
||||
// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ |
|
||||
// | |
|
||||
// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de |
|
||||
// +------------------------------------------------------------------+
|
||||
//
|
||||
// This file is part of Check_MK.
|
||||
// The official homepage is at http://mathias-kettner.de/check_mk.
|
||||
//
|
||||
// check_mk is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation in version 2. check_mk is distributed
|
||||
// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with-
|
||||
// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
// PARTICULAR PURPOSE. See the GNU General Public License for more de-
|
||||
// tails. You should have received a copy of the GNU General Public
|
||||
// License along with GNU Make; see the file COPYING. If not, write
|
||||
// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
// Boston, MA 02110-1301 USA.
|
||||
|
||||
#ifndef Column_h
|
||||
#define Column_h
|
||||
|
||||
#include "config.h" // IWYU pragma: keep
|
||||
#include <chrono>
|
||||
#include <cstddef>
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include "Filter.h"
|
||||
#include "Row.h"
|
||||
#include "contact_fwd.h"
|
||||
#include "opids.h"
|
||||
class Aggregation;
|
||||
class Aggregator;
|
||||
class Logger;
|
||||
class RowRenderer;
|
||||
|
||||
template <typename T>
|
||||
const T *offset_cast(const void *ptr, size_t offset) {
|
||||
// cppcheck is too dumb to see that this is just pointer arithmetic... :-/
|
||||
// cppcheck-suppress invalidPointerCast
|
||||
return reinterpret_cast<const T *>(reinterpret_cast<const char *>(ptr) +
|
||||
offset);
|
||||
}
|
||||
|
||||
enum class ColumnType { int_, double_, string, list, time, dict, blob, null };
|
||||
|
||||
using AggregationFactory = std::function<std::unique_ptr<Aggregation>()>;
|
||||
|
||||
class Column {
|
||||
public:
|
||||
Column(std::string name, std::string description, int indirect_offset,
|
||||
int extra_offset, int extra_extra_offset, int offset);
|
||||
virtual ~Column() = default;
|
||||
|
||||
[[nodiscard]] std::string name() const { return _name; }
|
||||
[[nodiscard]] std::string description() const { return _description; }
|
||||
|
||||
template <typename T>
|
||||
[[nodiscard]] const T *columnData(Row row) const {
|
||||
return static_cast<const T *>(shiftPointer(row));
|
||||
}
|
||||
|
||||
[[nodiscard]] virtual ColumnType type() const = 0;
|
||||
|
||||
virtual void output(Row row, RowRenderer &r, const contact *auth_user,
|
||||
std::chrono::seconds timezone_offset) const = 0;
|
||||
|
||||
[[nodiscard]] virtual std::unique_ptr<Filter> createFilter(
|
||||
Filter::Kind kind, RelationalOperator relOp,
|
||||
const std::string &value) const = 0;
|
||||
|
||||
[[nodiscard]] virtual std::unique_ptr<Aggregator> createAggregator(
|
||||
AggregationFactory factory) const = 0;
|
||||
|
||||
[[nodiscard]] Logger *logger() const { return _logger; }
|
||||
|
||||
private:
|
||||
Logger *const _logger;
|
||||
std::string _name;
|
||||
std::string _description;
|
||||
int _indirect_offset;
|
||||
int _extra_offset;
|
||||
int _extra_extra_offset;
|
||||
int _offset;
|
||||
|
||||
[[nodiscard]] const void *shiftPointer(Row row) const;
|
||||
};
|
||||
|
||||
#endif // Column_h
|
||||
51
src/ColumnFilter.cc
Normal file
51
src/ColumnFilter.cc
Normal file
@@ -0,0 +1,51 @@
|
||||
// +------------------------------------------------------------------+
|
||||
// | ____ _ _ __ __ _ __ |
|
||||
// | / ___| |__ ___ ___| | __ | \/ | |/ / |
|
||||
// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / |
|
||||
// | | |___| | | | __/ (__| < | | | | . \ |
|
||||
// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ |
|
||||
// | |
|
||||
// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de |
|
||||
// +------------------------------------------------------------------+
|
||||
//
|
||||
// This file is part of Check_MK.
|
||||
// The official homepage is at http://mathias-kettner.de/check_mk.
|
||||
//
|
||||
// check_mk is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation in version 2. check_mk is distributed
|
||||
// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with-
|
||||
// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
// PARTICULAR PURPOSE. See the GNU General Public License for more de-
|
||||
// tails. You should have received a copy of the GNU General Public
|
||||
// License along with GNU Make; see the file COPYING. If not, write
|
||||
// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
// Boston, MA 02110-1301 USA.
|
||||
|
||||
#include "ColumnFilter.h"
|
||||
#include "AndingFilter.h"
|
||||
|
||||
std::unique_ptr<Filter> ColumnFilter::partialFilter(
|
||||
std::function<bool(const Column &)> predicate) const {
|
||||
return predicate(_column) ? copy() : AndingFilter::make(kind(), Filters());
|
||||
}
|
||||
|
||||
bool ColumnFilter::is_tautology() const { return false; }
|
||||
|
||||
bool ColumnFilter::is_contradiction() const { return false; }
|
||||
|
||||
Filters ColumnFilter::disjuncts() const {
|
||||
Filters filters;
|
||||
filters.push_back(copy());
|
||||
return filters;
|
||||
}
|
||||
|
||||
Filters ColumnFilter::conjuncts() const {
|
||||
Filters filters;
|
||||
filters.push_back(copy());
|
||||
return filters;
|
||||
}
|
||||
|
||||
std::ostream &ColumnFilter::print(std::ostream &os) const {
|
||||
return os << "Filter: " << columnName() << " " << oper() << " " << value();
|
||||
}
|
||||
64
src/ColumnFilter.h
Normal file
64
src/ColumnFilter.h
Normal file
@@ -0,0 +1,64 @@
|
||||
// +------------------------------------------------------------------+
|
||||
// | ____ _ _ __ __ _ __ |
|
||||
// | / ___| |__ ___ ___| | __ | \/ | |/ / |
|
||||
// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / |
|
||||
// | | |___| | | | __/ (__| < | | | | . \ |
|
||||
// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ |
|
||||
// | |
|
||||
// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de |
|
||||
// +------------------------------------------------------------------+
|
||||
//
|
||||
// This file is part of Check_MK.
|
||||
// The official homepage is at http://mathias-kettner.de/check_mk.
|
||||
//
|
||||
// check_mk is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation in version 2. check_mk is distributed
|
||||
// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with-
|
||||
// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
// PARTICULAR PURPOSE. See the GNU General Public License for more de-
|
||||
// tails. You should have received a copy of the GNU General Public
|
||||
// License along with GNU Make; see the file COPYING. If not, write
|
||||
// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
// Boston, MA 02110-1301 USA.
|
||||
|
||||
#ifndef ColumnFilter_h
|
||||
#define ColumnFilter_h
|
||||
|
||||
#include "config.h" // IWYU pragma: keep
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
#include <ostream>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include "Column.h"
|
||||
#include "Filter.h"
|
||||
#include "opids.h"
|
||||
|
||||
class ColumnFilter : public Filter {
|
||||
public:
|
||||
ColumnFilter(Kind kind, const Column &column, RelationalOperator relOp,
|
||||
std::string value)
|
||||
: Filter(kind)
|
||||
, _column(column)
|
||||
, _relOp(relOp)
|
||||
, _value(std::move(value)) {}
|
||||
[[nodiscard]] std::string columnName() const { return _column.name(); }
|
||||
[[nodiscard]] RelationalOperator oper() const { return _relOp; }
|
||||
[[nodiscard]] std::string value() const { return _value; }
|
||||
std::unique_ptr<Filter> partialFilter(
|
||||
std::function<bool(const Column &)> predicate) const override;
|
||||
[[nodiscard]] bool is_tautology() const override;
|
||||
[[nodiscard]] bool is_contradiction() const override;
|
||||
[[nodiscard]] Filters disjuncts() const override;
|
||||
[[nodiscard]] Filters conjuncts() const override;
|
||||
|
||||
private:
|
||||
const Column &_column;
|
||||
const RelationalOperator _relOp;
|
||||
const std::string _value;
|
||||
|
||||
std::ostream &print(std::ostream &os) const override;
|
||||
};
|
||||
|
||||
#endif // ColumnFilter_h
|
||||
35
src/ColumnsColumn.cc
Normal file
35
src/ColumnsColumn.cc
Normal file
@@ -0,0 +1,35 @@
|
||||
// +------------------------------------------------------------------+
|
||||
// | ____ _ _ __ __ _ __ |
|
||||
// | / ___| |__ ___ ___| | __ | \/ | |/ / |
|
||||
// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / |
|
||||
// | | |___| | | | __/ (__| < | | | | . \ |
|
||||
// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ |
|
||||
// | |
|
||||
// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de |
|
||||
// +------------------------------------------------------------------+
|
||||
//
|
||||
// This file is part of Check_MK.
|
||||
// The official homepage is at http://mathias-kettner.de/check_mk.
|
||||
//
|
||||
// check_mk is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation in version 2. check_mk is distributed
|
||||
// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with-
|
||||
// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
// PARTICULAR PURPOSE. See the GNU General Public License for more de-
|
||||
// tails. You should have received a copy of the GNU General Public
|
||||
// License along with GNU Make; see the file COPYING. If not, write
|
||||
// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
// Boston, MA 02110-1301 USA.
|
||||
|
||||
#include "ColumnsColumn.h"
|
||||
#include "Row.h"
|
||||
#include "TableColumns.h"
|
||||
class Column;
|
||||
|
||||
std::string ColumnsColumn::getValue(Row row) const {
|
||||
if (auto p = columnData<Column>(row)) {
|
||||
return _table_columns.getValue(p, _colcol);
|
||||
}
|
||||
return "";
|
||||
}
|
||||
52
src/ColumnsColumn.h
Normal file
52
src/ColumnsColumn.h
Normal file
@@ -0,0 +1,52 @@
|
||||
// +------------------------------------------------------------------+
|
||||
// | ____ _ _ __ __ _ __ |
|
||||
// | / ___| |__ ___ ___| | __ | \/ | |/ / |
|
||||
// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / |
|
||||
// | | |___| | | | __/ (__| < | | | | . \ |
|
||||
// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ |
|
||||
// | |
|
||||
// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de |
|
||||
// +------------------------------------------------------------------+
|
||||
//
|
||||
// This file is part of Check_MK.
|
||||
// The official homepage is at http://mathias-kettner.de/check_mk.
|
||||
//
|
||||
// check_mk is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation in version 2. check_mk is distributed
|
||||
// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with-
|
||||
// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
// PARTICULAR PURPOSE. See the GNU General Public License for more de-
|
||||
// tails. You should have received a copy of the GNU General Public
|
||||
// License along with GNU Make; see the file COPYING. If not, write
|
||||
// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
// Boston, MA 02110-1301 USA.
|
||||
|
||||
#ifndef ColumnsColumn_h
|
||||
#define ColumnsColumn_h
|
||||
|
||||
#include "config.h" // IWYU pragma: keep
|
||||
#include <string>
|
||||
#include "StringColumn.h"
|
||||
class Row;
|
||||
class TableColumns;
|
||||
|
||||
class ColumnsColumn : public StringColumn {
|
||||
public:
|
||||
enum class Type { table, name, description, type };
|
||||
|
||||
ColumnsColumn(const std::string &name, const std::string &description,
|
||||
int indirect_offset, int extra_offset, int extra_extra_offset,
|
||||
int offset, Type colcol, const TableColumns &tablecols)
|
||||
: StringColumn(name, description, indirect_offset, extra_offset,
|
||||
extra_extra_offset, offset)
|
||||
, _colcol(colcol)
|
||||
, _table_columns(tablecols) {}
|
||||
[[nodiscard]] std::string getValue(Row row) const override;
|
||||
|
||||
private:
|
||||
const Type _colcol;
|
||||
const TableColumns &_table_columns;
|
||||
};
|
||||
|
||||
#endif // ColumnsColumn_h
|
||||
76
src/CommentColumn.cc
Normal file
76
src/CommentColumn.cc
Normal file
@@ -0,0 +1,76 @@
|
||||
// +------------------------------------------------------------------+
|
||||
// | ____ _ _ __ __ _ __ |
|
||||
// | / ___| |__ ___ ___| | __ | \/ | |/ / |
|
||||
// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / |
|
||||
// | | |___| | | | __/ (__| < | | | | . \ |
|
||||
// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ |
|
||||
// | |
|
||||
// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de |
|
||||
// +------------------------------------------------------------------+
|
||||
//
|
||||
// This file is part of Check_MK.
|
||||
// The official homepage is at http://mathias-kettner.de/check_mk.
|
||||
//
|
||||
// check_mk is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation in version 2. check_mk is distributed
|
||||
// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with-
|
||||
// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
// PARTICULAR PURPOSE. See the GNU General Public License for more de-
|
||||
// tails. You should have received a copy of the GNU General Public
|
||||
// License along with GNU Make; see the file COPYING. If not, write
|
||||
// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
// Boston, MA 02110-1301 USA.
|
||||
|
||||
#include "CommentColumn.h"
|
||||
#include <algorithm>
|
||||
#include <chrono>
|
||||
#include <cstdint>
|
||||
#include <iterator>
|
||||
#include "MonitoringCore.h"
|
||||
#include "Renderer.h"
|
||||
#include "Row.h"
|
||||
#include "nagios.h"
|
||||
|
||||
void CommentColumn::output(Row row, RowRenderer &r,
|
||||
const contact * /*auth_user*/,
|
||||
std::chrono::seconds /*timezone_offset*/) const {
|
||||
ListRenderer l(r);
|
||||
for (const auto &comment : comments_for_row(row)) {
|
||||
if (_with_info) {
|
||||
SublistRenderer s(l);
|
||||
s.output(comment._id);
|
||||
s.output(comment._author);
|
||||
s.output(comment._comment);
|
||||
if (_with_extra_info) {
|
||||
s.output(comment._entry_type);
|
||||
s.output(comment._entry_time);
|
||||
}
|
||||
} else {
|
||||
l.output(comment._id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<std::string> CommentColumn::getValue(
|
||||
Row row, const contact * /*auth_user*/,
|
||||
std::chrono::seconds /*timezone_offset*/) const {
|
||||
std::vector<std::string> ids;
|
||||
auto comments = comments_for_row(row);
|
||||
std::transform(
|
||||
comments.begin(), comments.end(), std::back_inserter(ids),
|
||||
[](const auto &comment) { return std::to_string(comment._id); });
|
||||
return ids;
|
||||
}
|
||||
|
||||
std::vector<CommentData> CommentColumn::comments_for_row(Row row) const {
|
||||
if (auto data = columnData<void>(row)) {
|
||||
return _is_service
|
||||
? _mc->comments_for_service(
|
||||
reinterpret_cast<const MonitoringCore::Service *>(
|
||||
data))
|
||||
: _mc->comments_for_host(
|
||||
reinterpret_cast<const MonitoringCore::Host *>(data));
|
||||
}
|
||||
return {};
|
||||
}
|
||||
68
src/CommentColumn.h
Normal file
68
src/CommentColumn.h
Normal file
@@ -0,0 +1,68 @@
|
||||
// +------------------------------------------------------------------+
|
||||
// | ____ _ _ __ __ _ __ |
|
||||
// | / ___| |__ ___ ___| | __ | \/ | |/ / |
|
||||
// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / |
|
||||
// | | |___| | | | __/ (__| < | | | | . \ |
|
||||
// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ |
|
||||
// | |
|
||||
// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de |
|
||||
// +------------------------------------------------------------------+
|
||||
//
|
||||
// This file is part of Check_MK.
|
||||
// The official homepage is at http://mathias-kettner.de/check_mk.
|
||||
//
|
||||
// check_mk is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation in version 2. check_mk is distributed
|
||||
// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with-
|
||||
// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
// PARTICULAR PURPOSE. See the GNU General Public License for more de-
|
||||
// tails. You should have received a copy of the GNU General Public
|
||||
// License along with GNU Make; see the file COPYING. If not, write
|
||||
// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
// Boston, MA 02110-1301 USA.
|
||||
|
||||
#ifndef CommentColumn_h
|
||||
#define CommentColumn_h
|
||||
|
||||
#include "config.h" // IWYU pragma: keep
|
||||
#include <chrono>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include "ListColumn.h"
|
||||
#include "contact_fwd.h"
|
||||
struct CommentData;
|
||||
class MonitoringCore;
|
||||
class RowRenderer;
|
||||
class Row;
|
||||
|
||||
class CommentColumn : public ListColumn {
|
||||
public:
|
||||
CommentColumn(const std::string &name, const std::string &description,
|
||||
int indirect_offset, int extra_offset, int extra_extra_offset,
|
||||
int offset, MonitoringCore *mc, bool is_service,
|
||||
bool with_info, bool with_extra_info)
|
||||
: ListColumn(name, description, indirect_offset, extra_offset,
|
||||
extra_extra_offset, offset)
|
||||
, _mc(mc)
|
||||
, _is_service(is_service)
|
||||
, _with_info(with_info)
|
||||
, _with_extra_info(with_extra_info) {}
|
||||
|
||||
void output(Row row, RowRenderer &r, const contact *auth_user,
|
||||
std::chrono::seconds timezone_offset) const override;
|
||||
|
||||
std::vector<std::string> getValue(
|
||||
Row row, const contact *auth_user,
|
||||
std::chrono::seconds timezone_offset) const override;
|
||||
|
||||
private:
|
||||
MonitoringCore *_mc;
|
||||
bool _is_service;
|
||||
bool _with_info;
|
||||
bool _with_extra_info;
|
||||
|
||||
[[nodiscard]] std::vector<CommentData> comments_for_row(Row row) const;
|
||||
};
|
||||
|
||||
#endif // CommentColumn_h
|
||||
54
src/ContactGroupsColumn.cc
Normal file
54
src/ContactGroupsColumn.cc
Normal file
@@ -0,0 +1,54 @@
|
||||
// +------------------------------------------------------------------+
|
||||
// | ____ _ _ __ __ _ __ |
|
||||
// | / ___| |__ ___ ___| | __ | \/ | |/ / |
|
||||
// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / |
|
||||
// | | |___| | | | __/ (__| < | | | | . \ |
|
||||
// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ |
|
||||
// | |
|
||||
// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de |
|
||||
// +------------------------------------------------------------------+
|
||||
//
|
||||
// This file is part of Check_MK.
|
||||
// The official homepage is at http://mathias-kettner.de/check_mk.
|
||||
//
|
||||
// check_mk is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation in version 2. check_mk is distributed
|
||||
// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with-
|
||||
// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
// PARTICULAR PURPOSE. See the GNU General Public License for more de-
|
||||
// tails. You should have received a copy of the GNU General Public
|
||||
// License along with GNU Make; see the file COPYING. If not, write
|
||||
// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
// Boston, MA 02110-1301 USA.
|
||||
|
||||
#include "ContactGroupsColumn.h"
|
||||
#include "Row.h"
|
||||
|
||||
#ifdef CMC
|
||||
#include "ContactList.h"
|
||||
#include "Object.h"
|
||||
#include "cmc.h"
|
||||
#else
|
||||
#include "nagios.h"
|
||||
#endif
|
||||
|
||||
std::vector<std::string> ContactGroupsColumn::getValue(
|
||||
Row row, const contact * /*auth_user*/,
|
||||
std::chrono::seconds /*timezone_offset*/) const {
|
||||
std::vector<std::string> names;
|
||||
#ifdef CMC
|
||||
if (auto object = columnData<Object>(row)) {
|
||||
for (const auto &name : object->_contact_list->groupNames()) {
|
||||
names.push_back(name);
|
||||
}
|
||||
}
|
||||
#else
|
||||
if (auto p = columnData<contactgroupsmember *>(row)) {
|
||||
for (auto cgm = *p; cgm != nullptr; cgm = cgm->next) {
|
||||
names.emplace_back(cgm->group_ptr->group_name);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return names;
|
||||
}
|
||||
49
src/ContactGroupsColumn.h
Normal file
49
src/ContactGroupsColumn.h
Normal file
@@ -0,0 +1,49 @@
|
||||
// +------------------------------------------------------------------+
|
||||
// | ____ _ _ __ __ _ __ |
|
||||
// | / ___| |__ ___ ___| | __ | \/ | |/ / |
|
||||
// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / |
|
||||
// | | |___| | | | __/ (__| < | | | | . \ |
|
||||
// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ |
|
||||
// | |
|
||||
// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de |
|
||||
// +------------------------------------------------------------------+
|
||||
//
|
||||
// This file is part of Check_MK.
|
||||
// The official homepage is at http://mathias-kettner.de/check_mk.
|
||||
//
|
||||
// check_mk is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation in version 2. check_mk is distributed
|
||||
// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with-
|
||||
// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
// PARTICULAR PURPOSE. See the GNU General Public License for more de-
|
||||
// tails. You should have received a copy of the GNU General Public
|
||||
// License along with GNU Make; see the file COPYING. If not, write
|
||||
// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
// Boston, MA 02110-1301 USA.
|
||||
|
||||
#ifndef ContactGroupsColumn_h
|
||||
#define ContactGroupsColumn_h
|
||||
|
||||
#include "config.h" // IWYU pragma: keep
|
||||
#include <chrono>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include "ListColumn.h"
|
||||
#include "contact_fwd.h"
|
||||
class Row;
|
||||
|
||||
class ContactGroupsColumn : public ListColumn {
|
||||
public:
|
||||
ContactGroupsColumn(const std::string &name, const std::string &description,
|
||||
int indirect_offset, int extra_offset,
|
||||
int extra_extra_offset, int offset)
|
||||
: ListColumn(name, description, indirect_offset, extra_offset,
|
||||
extra_extra_offset, offset) {}
|
||||
|
||||
std::vector<std::string> getValue(
|
||||
Row row, const contact *auth_user,
|
||||
std::chrono::seconds timezone_offset) const override;
|
||||
};
|
||||
|
||||
#endif // ContactGroupsColumn_h
|
||||
51
src/ContactGroupsMemberColumn.cc
Normal file
51
src/ContactGroupsMemberColumn.cc
Normal file
@@ -0,0 +1,51 @@
|
||||
// +------------------------------------------------------------------+
|
||||
// | ____ _ _ __ __ _ __ |
|
||||
// | / ___| |__ ___ ___| | __ | \/ | |/ / |
|
||||
// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / |
|
||||
// | | |___| | | | __/ (__| < | | | | . \ |
|
||||
// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ |
|
||||
// | |
|
||||
// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de |
|
||||
// +------------------------------------------------------------------+
|
||||
//
|
||||
// This file is part of Check_MK.
|
||||
// The official homepage is at http://mathias-kettner.de/check_mk.
|
||||
//
|
||||
// check_mk is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation in version 2. check_mk is distributed
|
||||
// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with-
|
||||
// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
// PARTICULAR PURPOSE. See the GNU General Public License for more de-
|
||||
// tails. You should have received a copy of the GNU General Public
|
||||
// License along with GNU Make; see the file COPYING. If not, write
|
||||
// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
// Boston, MA 02110-1301 USA.
|
||||
|
||||
#include "ContactGroupsMemberColumn.h"
|
||||
#include "Row.h"
|
||||
|
||||
#ifdef CMC
|
||||
#include "ContactGroup.h"
|
||||
#else
|
||||
#include "nagios.h"
|
||||
#endif
|
||||
|
||||
std::vector<std::string> ContactGroupsMemberColumn::getValue(
|
||||
Row row, const contact* /*auth_user*/,
|
||||
std::chrono::seconds /*timezone_offset*/) const {
|
||||
#ifdef CMC
|
||||
if (auto cg = columnData<ContactGroup>(row)) {
|
||||
return cg->contactNames();
|
||||
}
|
||||
return {};
|
||||
#else
|
||||
std::vector<std::string> names;
|
||||
if (auto cg = columnData<contactgroup>(row)) {
|
||||
for (auto cm = cg->members; cm != nullptr; cm = cm->next) {
|
||||
names.emplace_back(cm->contact_ptr->name);
|
||||
}
|
||||
}
|
||||
return names;
|
||||
#endif
|
||||
}
|
||||
50
src/ContactGroupsMemberColumn.h
Normal file
50
src/ContactGroupsMemberColumn.h
Normal file
@@ -0,0 +1,50 @@
|
||||
// +------------------------------------------------------------------+
|
||||
// | ____ _ _ __ __ _ __ |
|
||||
// | / ___| |__ ___ ___| | __ | \/ | |/ / |
|
||||
// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / |
|
||||
// | | |___| | | | __/ (__| < | | | | . \ |
|
||||
// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ |
|
||||
// | |
|
||||
// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de |
|
||||
// +------------------------------------------------------------------+
|
||||
//
|
||||
// This file is part of Check_MK.
|
||||
// The official homepage is at http://mathias-kettner.de/check_mk.
|
||||
//
|
||||
// check_mk is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation in version 2. check_mk is distributed
|
||||
// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with-
|
||||
// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
// PARTICULAR PURPOSE. See the GNU General Public License for more de-
|
||||
// tails. You should have received a copy of the GNU General Public
|
||||
// License along with GNU Make; see the file COPYING. If not, write
|
||||
// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
// Boston, MA 02110-1301 USA.
|
||||
|
||||
#ifndef ContactGroupsMemberColumn_h
|
||||
#define ContactGroupsMemberColumn_h
|
||||
|
||||
#include "config.h" // IWYU pragma: keep
|
||||
#include <chrono>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include "ListColumn.h"
|
||||
#include "contact_fwd.h"
|
||||
class Row;
|
||||
|
||||
class ContactGroupsMemberColumn : public ListColumn {
|
||||
public:
|
||||
ContactGroupsMemberColumn(const std::string& name,
|
||||
const std::string& description,
|
||||
int indirect_offset, int extra_offset,
|
||||
int extra_extra_offset, int offset)
|
||||
: ListColumn(name, description, indirect_offset, extra_offset,
|
||||
extra_extra_offset, offset) {}
|
||||
|
||||
std::vector<std::string> getValue(
|
||||
Row row, const contact* auth_user,
|
||||
std::chrono::seconds timezone_offset) const override;
|
||||
};
|
||||
|
||||
#endif // ContactGroupsMemberColumn_h
|
||||
37
src/CountAggregator.cc
Normal file
37
src/CountAggregator.cc
Normal file
@@ -0,0 +1,37 @@
|
||||
// +------------------------------------------------------------------+
|
||||
// | ____ _ _ __ __ _ __ |
|
||||
// | / ___| |__ ___ ___| | __ | \/ | |/ / |
|
||||
// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / |
|
||||
// | | |___| | | | __/ (__| < | | | | . \ |
|
||||
// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ |
|
||||
// | |
|
||||
// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de |
|
||||
// +------------------------------------------------------------------+
|
||||
//
|
||||
// This file is part of Check_MK.
|
||||
// The official homepage is at http://mathias-kettner.de/check_mk.
|
||||
//
|
||||
// check_mk is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation in version 2. check_mk is distributed
|
||||
// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with-
|
||||
// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
// PARTICULAR PURPOSE. See the GNU General Public License for more de-
|
||||
// tails. You should have received a copy of the GNU General Public
|
||||
// License along with GNU Make; see the file COPYING. If not, write
|
||||
// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
// Boston, MA 02110-1301 USA.
|
||||
|
||||
#include "CountAggregator.h"
|
||||
#include "Filter.h"
|
||||
#include "Renderer.h"
|
||||
#include "Row.h"
|
||||
|
||||
void CountAggregator::consume(Row row, const contact* auth_user,
|
||||
std::chrono::seconds timezone_offset) {
|
||||
if (_filter->accepts(row, auth_user, timezone_offset)) {
|
||||
_count++;
|
||||
}
|
||||
}
|
||||
|
||||
void CountAggregator::output(RowRenderer& r) const { r.output(_count); }
|
||||
50
src/CountAggregator.h
Normal file
50
src/CountAggregator.h
Normal file
@@ -0,0 +1,50 @@
|
||||
// +------------------------------------------------------------------+
|
||||
// | ____ _ _ __ __ _ __ |
|
||||
// | / ___| |__ ___ ___| | __ | \/ | |/ / |
|
||||
// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / |
|
||||
// | | |___| | | | __/ (__| < | | | | . \ |
|
||||
// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ |
|
||||
// | |
|
||||
// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de |
|
||||
// +------------------------------------------------------------------+
|
||||
//
|
||||
// This file is part of Check_MK.
|
||||
// The official homepage is at http://mathias-kettner.de/check_mk.
|
||||
//
|
||||
// check_mk is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation in version 2. check_mk is distributed
|
||||
// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with-
|
||||
// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
// PARTICULAR PURPOSE. See the GNU General Public License for more de-
|
||||
// tails. You should have received a copy of the GNU General Public
|
||||
// License along with GNU Make; see the file COPYING. If not, write
|
||||
// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
// Boston, MA 02110-1301 USA.
|
||||
|
||||
#ifndef CountAggregator_h
|
||||
#define CountAggregator_h
|
||||
|
||||
#include "config.h" // IWYU pragma: keep
|
||||
#include <chrono>
|
||||
#include <cstdint>
|
||||
#include "Aggregator.h"
|
||||
#include "contact_fwd.h"
|
||||
class Filter;
|
||||
class Row;
|
||||
class RowRenderer;
|
||||
|
||||
class CountAggregator : public Aggregator {
|
||||
public:
|
||||
explicit CountAggregator(const Filter *filter)
|
||||
: _filter(filter), _count(0) {}
|
||||
void consume(Row row, const contact *auth_user,
|
||||
std::chrono::seconds timezone_offset) override;
|
||||
void output(RowRenderer &r) const override;
|
||||
|
||||
private:
|
||||
const Filter *const _filter;
|
||||
std::uint32_t _count;
|
||||
};
|
||||
|
||||
#endif // CountAggregator_h
|
||||
50
src/CustomTimeperiodColumn.cc
Normal file
50
src/CustomTimeperiodColumn.cc
Normal file
@@ -0,0 +1,50 @@
|
||||
// +------------------------------------------------------------------+
|
||||
// | ____ _ _ __ __ _ __ |
|
||||
// | / ___| |__ ___ ___| | __ | \/ | |/ / |
|
||||
// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / |
|
||||
// | | |___| | | | __/ (__| < | | | | . \ |
|
||||
// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ |
|
||||
// | |
|
||||
// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de |
|
||||
// +------------------------------------------------------------------+
|
||||
//
|
||||
// This file is part of Check_MK.
|
||||
// The official homepage is at http://mathias-kettner.de/check_mk.
|
||||
//
|
||||
// check_mk is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation in version 2. check_mk is distributed
|
||||
// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with-
|
||||
// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
// PARTICULAR PURPOSE. See the GNU General Public License for more de-
|
||||
// tails. You should have received a copy of the GNU General Public
|
||||
// License along with GNU Make; see the file COPYING. If not, write
|
||||
// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
// Boston, MA 02110-1301 USA.
|
||||
|
||||
#include "CustomTimeperiodColumn.h"
|
||||
#include "Row.h"
|
||||
#include "TimeperiodsCache.h"
|
||||
|
||||
extern TimeperiodsCache *g_timeperiods_cache;
|
||||
|
||||
// Get the name of a timeperiod from a custom variable and lookup the current
|
||||
// state of that period
|
||||
int32_t CustomTimeperiodColumn::getValue(
|
||||
Row row, const contact * /* auth_user */) const {
|
||||
for (customvariablesmember *cvm = getCVM(row); cvm != nullptr;
|
||||
cvm = cvm->next) {
|
||||
if (cvm->variable_name == _varname) {
|
||||
return static_cast<int32_t>(
|
||||
g_timeperiods_cache->inTimeperiod(cvm->variable_value));
|
||||
}
|
||||
}
|
||||
return 1; // assume 24X7
|
||||
}
|
||||
|
||||
customvariablesmember *CustomTimeperiodColumn::getCVM(Row row) const {
|
||||
if (auto p = columnData<customvariablesmember *>(row)) {
|
||||
return *p;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
53
src/CustomTimeperiodColumn.h
Normal file
53
src/CustomTimeperiodColumn.h
Normal file
@@ -0,0 +1,53 @@
|
||||
// +------------------------------------------------------------------+
|
||||
// | ____ _ _ __ __ _ __ |
|
||||
// | / ___| |__ ___ ___| | __ | \/ | |/ / |
|
||||
// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / |
|
||||
// | | |___| | | | __/ (__| < | | | | . \ |
|
||||
// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ |
|
||||
// | |
|
||||
// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de |
|
||||
// +------------------------------------------------------------------+
|
||||
//
|
||||
// This file is part of Check_MK.
|
||||
// The official homepage is at http://mathias-kettner.de/check_mk.
|
||||
//
|
||||
// check_mk is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation in version 2. check_mk is distributed
|
||||
// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with-
|
||||
// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
// PARTICULAR PURPOSE. See the GNU General Public License for more de-
|
||||
// tails. You should have received a copy of the GNU General Public
|
||||
// License along with GNU Make; see the file COPYING. If not, write
|
||||
// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
// Boston, MA 02110-1301 USA.
|
||||
|
||||
#ifndef CustomTimeperiodColumn_h
|
||||
#define CustomTimeperiodColumn_h
|
||||
|
||||
#include "config.h" // IWYU pragma: keep
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include "IntColumn.h"
|
||||
#include "nagios.h"
|
||||
class Row;
|
||||
|
||||
class CustomTimeperiodColumn : public IntColumn {
|
||||
public:
|
||||
CustomTimeperiodColumn(const std::string &name,
|
||||
const std::string &description, int indirect_offset,
|
||||
int extra_offset, int extra_extra_offset, int offset,
|
||||
std::string varname)
|
||||
: IntColumn(name, description, indirect_offset, extra_offset,
|
||||
extra_extra_offset, offset)
|
||||
, _varname(std::move(varname)) {}
|
||||
int32_t getValue(Row row, const contact *auth_user) const override;
|
||||
|
||||
private:
|
||||
std::string _varname;
|
||||
|
||||
[[nodiscard]] customvariablesmember *getCVM(Row row) const;
|
||||
};
|
||||
|
||||
#endif // CustomTimeperiodColumn_h
|
||||
77
src/CustomVarsDictColumn.cc
Normal file
77
src/CustomVarsDictColumn.cc
Normal file
@@ -0,0 +1,77 @@
|
||||
// +------------------------------------------------------------------+
|
||||
// | ____ _ _ __ __ _ __ |
|
||||
// | / ___| |__ ___ ___| | __ | \/ | |/ / |
|
||||
// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / |
|
||||
// | | |___| | | | __/ (__| < | | | | . \ |
|
||||
// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ |
|
||||
// | |
|
||||
// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de |
|
||||
// +------------------------------------------------------------------+
|
||||
//
|
||||
// This file is part of Check_MK.
|
||||
// The official homepage is at http://mathias-kettner.de/check_mk.
|
||||
//
|
||||
// check_mk is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation in version 2. check_mk is distributed
|
||||
// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with-
|
||||
// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
// PARTICULAR PURPOSE. See the GNU General Public License for more de-
|
||||
// tails. You should have received a copy of the GNU General Public
|
||||
// License along with GNU Make; see the file COPYING. If not, write
|
||||
// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
// Boston, MA 02110-1301 USA.
|
||||
|
||||
#include "CustomVarsDictColumn.h"
|
||||
#include <stdexcept>
|
||||
#include <utility>
|
||||
#include "CustomVarsDictFilter.h"
|
||||
#include "Filter.h"
|
||||
#include "Renderer.h"
|
||||
#include "Row.h"
|
||||
class Aggregator;
|
||||
|
||||
#ifdef CMC
|
||||
#include "Object.h"
|
||||
#include "cmc.h"
|
||||
#else
|
||||
#include "nagios.h"
|
||||
#endif
|
||||
|
||||
void CustomVarsDictColumn::output(
|
||||
Row row, RowRenderer &r, const contact * /*auth_user*/,
|
||||
std::chrono::seconds /*timezone_offset*/) const {
|
||||
DictRenderer d(r);
|
||||
for (const auto &it : getValue(row)) {
|
||||
d.output(it.first, it.second);
|
||||
}
|
||||
}
|
||||
|
||||
std::unique_ptr<Filter> CustomVarsDictColumn::createFilter(
|
||||
Filter::Kind kind, RelationalOperator relOp,
|
||||
const std::string &value) const {
|
||||
return std::make_unique<CustomVarsDictFilter>(kind, *this, relOp, value);
|
||||
}
|
||||
|
||||
std::unique_ptr<Aggregator> CustomVarsDictColumn::createAggregator(
|
||||
AggregationFactory /*factory*/) const {
|
||||
throw std::runtime_error("aggregating on dictionary column '" + name() +
|
||||
"' not supported");
|
||||
}
|
||||
|
||||
std::unordered_map<std::string, std::string> CustomVarsDictColumn::getValue(
|
||||
Row row) const {
|
||||
std::unordered_map<std::string, std::string> dict;
|
||||
#ifdef CMC
|
||||
if (auto *object = columnData<Object>(row)) {
|
||||
return object->customAttributes();
|
||||
}
|
||||
#else
|
||||
if (auto p = columnData<customvariablesmember *>(row)) {
|
||||
for (auto cvm = *p; cvm != nullptr; cvm = cvm->next) {
|
||||
dict.emplace(cvm->variable_name, cvm->variable_value);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return dict;
|
||||
}
|
||||
66
src/CustomVarsDictColumn.h
Normal file
66
src/CustomVarsDictColumn.h
Normal file
@@ -0,0 +1,66 @@
|
||||
// +------------------------------------------------------------------+
|
||||
// | ____ _ _ __ __ _ __ |
|
||||
// | / ___| |__ ___ ___| | __ | \/ | |/ / |
|
||||
// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / |
|
||||
// | | |___| | | | __/ (__| < | | | | . \ |
|
||||
// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ |
|
||||
// | |
|
||||
// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de |
|
||||
// +------------------------------------------------------------------+
|
||||
//
|
||||
// This file is part of Check_MK.
|
||||
// The official homepage is at http://mathias-kettner.de/check_mk.
|
||||
//
|
||||
// check_mk is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation in version 2. check_mk is distributed
|
||||
// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with-
|
||||
// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
// PARTICULAR PURPOSE. See the GNU General Public License for more de-
|
||||
// tails. You should have received a copy of the GNU General Public
|
||||
// License along with GNU Make; see the file COPYING. If not, write
|
||||
// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
// Boston, MA 02110-1301 USA.
|
||||
|
||||
#ifndef CustomVarsDictColumn_h
|
||||
#define CustomVarsDictColumn_h
|
||||
|
||||
#include "config.h" // IWYU pragma: keep
|
||||
#include <chrono>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
#include <utility>
|
||||
#include "Column.h"
|
||||
#include "Filter.h"
|
||||
#include "contact_fwd.h"
|
||||
#include "opids.h"
|
||||
class Aggregator;
|
||||
class Row;
|
||||
class RowRenderer;
|
||||
|
||||
class CustomVarsDictColumn : public Column {
|
||||
public:
|
||||
CustomVarsDictColumn(std::string name, std::string description,
|
||||
int indirect_offset, int extra_offset,
|
||||
int extra_extra_offset, int offset)
|
||||
: Column(std::move(name), std::move(description), indirect_offset,
|
||||
extra_offset, extra_extra_offset, offset) {}
|
||||
|
||||
[[nodiscard]] ColumnType type() const override { return ColumnType::dict; };
|
||||
|
||||
void output(Row row, RowRenderer &r, const contact *auth_user,
|
||||
std::chrono::seconds timezone_offset) const override;
|
||||
|
||||
[[nodiscard]] std::unique_ptr<Filter> createFilter(
|
||||
Filter::Kind kind, RelationalOperator relOp,
|
||||
const std::string &value) const override;
|
||||
|
||||
[[nodiscard]] std::unique_ptr<Aggregator> createAggregator(
|
||||
AggregationFactory factory) const override;
|
||||
|
||||
[[nodiscard]] std::unordered_map<std::string, std::string> getValue(
|
||||
Row row) const;
|
||||
};
|
||||
|
||||
#endif // CustomVarsDictColumn_h
|
||||
87
src/CustomVarsDictFilter.cc
Normal file
87
src/CustomVarsDictFilter.cc
Normal file
@@ -0,0 +1,87 @@
|
||||
// +------------------------------------------------------------------+
|
||||
// | ____ _ _ __ __ _ __ |
|
||||
// | / ___| |__ ___ ___| | __ | \/ | |/ / |
|
||||
// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / |
|
||||
// | | |___| | | | __/ (__| < | | | | . \ |
|
||||
// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ |
|
||||
// | |
|
||||
// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de |
|
||||
// +------------------------------------------------------------------+
|
||||
//
|
||||
// This file is part of Check_MK.
|
||||
// The official homepage is at http://mathias-kettner.de/check_mk.
|
||||
//
|
||||
// check_mk is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation in version 2. check_mk is distributed
|
||||
// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with-
|
||||
// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
// PARTICULAR PURPOSE. See the GNU General Public License for more de-
|
||||
// tails. You should have received a copy of the GNU General Public
|
||||
// License along with GNU Make; see the file COPYING. If not, write
|
||||
// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
// Boston, MA 02110-1301 USA.
|
||||
|
||||
#include "CustomVarsDictFilter.h"
|
||||
#include <tuple>
|
||||
#include <unordered_map>
|
||||
#include <utility>
|
||||
#include "CustomVarsDictColumn.h"
|
||||
#include "Filter.h"
|
||||
#include "RegExp.h"
|
||||
#include "Row.h"
|
||||
#include "StringUtils.h"
|
||||
|
||||
CustomVarsDictFilter::CustomVarsDictFilter(Kind kind,
|
||||
const CustomVarsDictColumn &column,
|
||||
RelationalOperator relOp,
|
||||
const std::string &value)
|
||||
: ColumnFilter(kind, column, relOp, value), _column(column) {
|
||||
// Filter for custom_variables:
|
||||
// Filter: custom_variables = PATH /hirni.mk
|
||||
// The variable name is part of the value and separated with spaces
|
||||
std::tie(_ref_varname, _ref_string) = mk::nextField(value);
|
||||
_ref_string = mk::lstrip(_ref_string);
|
||||
_regExp = makeRegExpFor(oper(), _ref_string);
|
||||
}
|
||||
|
||||
bool CustomVarsDictFilter::accepts(
|
||||
Row row, const contact * /* auth_user */,
|
||||
std::chrono::seconds /* timezone_offset */) const {
|
||||
auto cvm = _column.getValue(row);
|
||||
auto it = cvm.find(_ref_varname);
|
||||
auto act_string = it == cvm.end() ? "" : it->second;
|
||||
switch (oper()) {
|
||||
case RelationalOperator::equal:
|
||||
case RelationalOperator::equal_icase:
|
||||
return _regExp->match(act_string);
|
||||
case RelationalOperator::not_equal:
|
||||
case RelationalOperator::not_equal_icase:
|
||||
return !_regExp->match(act_string);
|
||||
case RelationalOperator::matches:
|
||||
case RelationalOperator::matches_icase:
|
||||
return _regExp->search(act_string);
|
||||
case RelationalOperator::doesnt_match:
|
||||
case RelationalOperator::doesnt_match_icase:
|
||||
return !_regExp->search(act_string);
|
||||
// FIXME: The cases below are nonsense for UTF-8...
|
||||
case RelationalOperator::less:
|
||||
return act_string < _ref_string;
|
||||
case RelationalOperator::greater_or_equal:
|
||||
return act_string >= _ref_string;
|
||||
case RelationalOperator::greater:
|
||||
return act_string > _ref_string;
|
||||
case RelationalOperator::less_or_equal:
|
||||
return act_string <= _ref_string;
|
||||
}
|
||||
return false; // unreachable
|
||||
}
|
||||
|
||||
std::unique_ptr<Filter> CustomVarsDictFilter::copy() const {
|
||||
return std::make_unique<CustomVarsDictFilter>(*this);
|
||||
}
|
||||
|
||||
std::unique_ptr<Filter> CustomVarsDictFilter::negate() const {
|
||||
return std::make_unique<CustomVarsDictFilter>(
|
||||
kind(), _column, negateRelationalOperator(oper()), value());
|
||||
}
|
||||
56
src/CustomVarsDictFilter.h
Normal file
56
src/CustomVarsDictFilter.h
Normal file
@@ -0,0 +1,56 @@
|
||||
// +------------------------------------------------------------------+
|
||||
// | ____ _ _ __ __ _ __ |
|
||||
// | / ___| |__ ___ ___| | __ | \/ | |/ / |
|
||||
// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / |
|
||||
// | | |___| | | | __/ (__| < | | | | . \ |
|
||||
// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ |
|
||||
// | |
|
||||
// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de |
|
||||
// +------------------------------------------------------------------+
|
||||
//
|
||||
// This file is part of Check_MK.
|
||||
// The official homepage is at http://mathias-kettner.de/check_mk.
|
||||
//
|
||||
// check_mk is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation in version 2. check_mk is distributed
|
||||
// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with-
|
||||
// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
// PARTICULAR PURPOSE. See the GNU General Public License for more de-
|
||||
// tails. You should have received a copy of the GNU General Public
|
||||
// License along with GNU Make; see the file COPYING. If not, write
|
||||
// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
// Boston, MA 02110-1301 USA.
|
||||
|
||||
#ifndef CustomVarsDictFilter_h
|
||||
#define CustomVarsDictFilter_h
|
||||
|
||||
#include "config.h" // IWYU pragma: keep
|
||||
#include <chrono>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include "ColumnFilter.h"
|
||||
#include "Filter.h"
|
||||
#include "contact_fwd.h"
|
||||
#include "opids.h"
|
||||
class CustomVarsDictColumn;
|
||||
class RegExp;
|
||||
class Row;
|
||||
|
||||
class CustomVarsDictFilter : public ColumnFilter {
|
||||
public:
|
||||
CustomVarsDictFilter(Kind kind, const CustomVarsDictColumn &column,
|
||||
RelationalOperator relOp, const std::string &value);
|
||||
bool accepts(Row row, const contact *auth_user,
|
||||
std::chrono::seconds timezone_offset) const override;
|
||||
[[nodiscard]] std::unique_ptr<Filter> copy() const override;
|
||||
[[nodiscard]] std::unique_ptr<Filter> negate() const override;
|
||||
|
||||
private:
|
||||
const CustomVarsDictColumn &_column;
|
||||
std::shared_ptr<RegExp> _regExp;
|
||||
std::string _ref_string;
|
||||
std::string _ref_varname;
|
||||
};
|
||||
|
||||
#endif // CustomVarsDictFilter_h
|
||||
43
src/CustomVarsExplicitColumn.cc
Normal file
43
src/CustomVarsExplicitColumn.cc
Normal file
@@ -0,0 +1,43 @@
|
||||
// +------------------------------------------------------------------+
|
||||
// | ____ _ _ __ __ _ __ |
|
||||
// | / ___| |__ ___ ___| | __ | \/ | |/ / |
|
||||
// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / |
|
||||
// | | |___| | | | __/ (__| < | | | | . \ |
|
||||
// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ |
|
||||
// | |
|
||||
// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de |
|
||||
// +------------------------------------------------------------------+
|
||||
//
|
||||
// This file is part of Check_MK.
|
||||
// The official homepage is at http://mathias-kettner.de/check_mk.
|
||||
//
|
||||
// check_mk is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation in version 2. check_mk is distributed
|
||||
// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with-
|
||||
// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
// PARTICULAR PURPOSE. See the GNU General Public License for more de-
|
||||
// tails. You should have received a copy of the GNU General Public
|
||||
// License along with GNU Make; see the file COPYING. If not, write
|
||||
// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
// Boston, MA 02110-1301 USA.
|
||||
|
||||
#include "CustomVarsExplicitColumn.h"
|
||||
#include "Row.h"
|
||||
|
||||
std::string CustomVarsExplicitColumn::getValue(Row row) const {
|
||||
for (customvariablesmember *cvm = getCVM(row); cvm != nullptr;
|
||||
cvm = cvm->next) {
|
||||
if (cvm->variable_name == _varname) {
|
||||
return cvm->variable_value;
|
||||
}
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
customvariablesmember *CustomVarsExplicitColumn::getCVM(Row row) const {
|
||||
if (auto p = columnData<customvariablesmember *>(row)) {
|
||||
return *p;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
52
src/CustomVarsExplicitColumn.h
Normal file
52
src/CustomVarsExplicitColumn.h
Normal file
@@ -0,0 +1,52 @@
|
||||
// +------------------------------------------------------------------+
|
||||
// | ____ _ _ __ __ _ __ |
|
||||
// | / ___| |__ ___ ___| | __ | \/ | |/ / |
|
||||
// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / |
|
||||
// | | |___| | | | __/ (__| < | | | | . \ |
|
||||
// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ |
|
||||
// | |
|
||||
// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de |
|
||||
// +------------------------------------------------------------------+
|
||||
//
|
||||
// This file is part of Check_MK.
|
||||
// The official homepage is at http://mathias-kettner.de/check_mk.
|
||||
//
|
||||
// check_mk is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation in version 2. check_mk is distributed
|
||||
// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with-
|
||||
// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
// PARTICULAR PURPOSE. See the GNU General Public License for more de-
|
||||
// tails. You should have received a copy of the GNU General Public
|
||||
// License along with GNU Make; see the file COPYING. If not, write
|
||||
// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
// Boston, MA 02110-1301 USA.
|
||||
|
||||
#ifndef CustomVarsExplicitColumn_h
|
||||
#define CustomVarsExplicitColumn_h
|
||||
|
||||
#include "config.h" // IWYU pragma: keep
|
||||
#include <string>
|
||||
#include "StringColumn.h"
|
||||
#include "nagios.h"
|
||||
class Row;
|
||||
|
||||
class CustomVarsExplicitColumn : public StringColumn {
|
||||
public:
|
||||
CustomVarsExplicitColumn(const std::string &name,
|
||||
const std::string &description,
|
||||
int indirect_offset, int extra_offset,
|
||||
int extra_extra_offset, int offset,
|
||||
const char *varname)
|
||||
: StringColumn(name, description, indirect_offset, extra_offset,
|
||||
extra_extra_offset, offset)
|
||||
, _varname(varname) {}
|
||||
[[nodiscard]] std::string getValue(Row row) const override;
|
||||
|
||||
private:
|
||||
std::string _varname;
|
||||
|
||||
[[nodiscard]] customvariablesmember *getCVM(Row row) const;
|
||||
};
|
||||
|
||||
#endif // CustomVarsExplicitColumn_h
|
||||
56
src/CustomVarsNamesColumn.cc
Normal file
56
src/CustomVarsNamesColumn.cc
Normal file
@@ -0,0 +1,56 @@
|
||||
// +------------------------------------------------------------------+
|
||||
// | ____ _ _ __ __ _ __ |
|
||||
// | / ___| |__ ___ ___| | __ | \/ | |/ / |
|
||||
// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / |
|
||||
// | | |___| | | | __/ (__| < | | | | . \ |
|
||||
// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ |
|
||||
// | |
|
||||
// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de |
|
||||
// +------------------------------------------------------------------+
|
||||
//
|
||||
// This file is part of Check_MK.
|
||||
// The official homepage is at http://mathias-kettner.de/check_mk.
|
||||
//
|
||||
// check_mk is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation in version 2. check_mk is distributed
|
||||
// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with-
|
||||
// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
// PARTICULAR PURPOSE. See the GNU General Public License for more de-
|
||||
// tails. You should have received a copy of the GNU General Public
|
||||
// License along with GNU Make; see the file COPYING. If not, write
|
||||
// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
// Boston, MA 02110-1301 USA.
|
||||
|
||||
#include "CustomVarsNamesColumn.h"
|
||||
#include "Row.h"
|
||||
|
||||
#ifdef CMC
|
||||
#include <algorithm>
|
||||
#include <iterator>
|
||||
#include <unordered_map>
|
||||
#include "Object.h"
|
||||
#include "cmc.h"
|
||||
#else
|
||||
#include "nagios.h"
|
||||
#endif
|
||||
|
||||
std::vector<std::string> CustomVarsNamesColumn::getValue(
|
||||
Row row, const contact * /*auth_user*/,
|
||||
std::chrono::seconds /*timezone_offset*/) const {
|
||||
std::vector<std::string> names;
|
||||
#ifdef CMC
|
||||
if (auto *object = columnData<Object>(row)) {
|
||||
auto attrs = object->customAttributes();
|
||||
std::transform(attrs.begin(), attrs.end(), std::back_inserter(names),
|
||||
[](const auto &entry) { return entry.first; });
|
||||
}
|
||||
#else
|
||||
if (auto p = columnData<customvariablesmember *>(row)) {
|
||||
for (auto cvm = *p; cvm != nullptr; cvm = cvm->next) {
|
||||
names.emplace_back(cvm->variable_name);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return names;
|
||||
}
|
||||
49
src/CustomVarsNamesColumn.h
Normal file
49
src/CustomVarsNamesColumn.h
Normal file
@@ -0,0 +1,49 @@
|
||||
// +------------------------------------------------------------------+
|
||||
// | ____ _ _ __ __ _ __ |
|
||||
// | / ___| |__ ___ ___| | __ | \/ | |/ / |
|
||||
// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / |
|
||||
// | | |___| | | | __/ (__| < | | | | . \ |
|
||||
// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ |
|
||||
// | |
|
||||
// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de |
|
||||
// +------------------------------------------------------------------+
|
||||
//
|
||||
// This file is part of Check_MK.
|
||||
// The official homepage is at http://mathias-kettner.de/check_mk.
|
||||
//
|
||||
// check_mk is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation in version 2. check_mk is distributed
|
||||
// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with-
|
||||
// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
// PARTICULAR PURPOSE. See the GNU General Public License for more de-
|
||||
// tails. You should have received a copy of the GNU General Public
|
||||
// License along with GNU Make; see the file COPYING. If not, write
|
||||
// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
// Boston, MA 02110-1301 USA.
|
||||
|
||||
#ifndef CustomVarsNamesColumn_h
|
||||
#define CustomVarsNamesColumn_h
|
||||
|
||||
#include "config.h" // IWYU pragma: keep
|
||||
#include <chrono>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include "ListColumn.h"
|
||||
#include "contact_fwd.h"
|
||||
class Row;
|
||||
|
||||
class CustomVarsNamesColumn : public ListColumn {
|
||||
public:
|
||||
CustomVarsNamesColumn(const std::string &name,
|
||||
const std::string &description, int indirect_offset,
|
||||
int extra_offset, int extra_extra_offset, int offset)
|
||||
: ListColumn(name, description, indirect_offset, extra_offset,
|
||||
extra_extra_offset, offset) {}
|
||||
|
||||
std::vector<std::string> getValue(
|
||||
Row row, const contact *auth_user,
|
||||
std::chrono::seconds timezone_offset) const override;
|
||||
};
|
||||
|
||||
#endif // CustomVarsNamesColumn_h
|
||||
56
src/CustomVarsValuesColumn.cc
Normal file
56
src/CustomVarsValuesColumn.cc
Normal file
@@ -0,0 +1,56 @@
|
||||
// +------------------------------------------------------------------+
|
||||
// | ____ _ _ __ __ _ __ |
|
||||
// | / ___| |__ ___ ___| | __ | \/ | |/ / |
|
||||
// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / |
|
||||
// | | |___| | | | __/ (__| < | | | | . \ |
|
||||
// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ |
|
||||
// | |
|
||||
// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de |
|
||||
// +------------------------------------------------------------------+
|
||||
//
|
||||
// This file is part of Check_MK.
|
||||
// The official homepage is at http://mathias-kettner.de/check_mk.
|
||||
//
|
||||
// check_mk is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation in version 2. check_mk is distributed
|
||||
// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with-
|
||||
// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
// PARTICULAR PURPOSE. See the GNU General Public License for more de-
|
||||
// tails. You should have received a copy of the GNU General Public
|
||||
// License along with GNU Make; see the file COPYING. If not, write
|
||||
// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
// Boston, MA 02110-1301 USA.
|
||||
|
||||
#include "CustomVarsValuesColumn.h"
|
||||
#include "Row.h"
|
||||
|
||||
#ifdef CMC
|
||||
#include <algorithm>
|
||||
#include <iterator>
|
||||
#include <unordered_map>
|
||||
#include "Object.h"
|
||||
#include "cmc.h"
|
||||
#else
|
||||
#include "nagios.h"
|
||||
#endif
|
||||
|
||||
std::vector<std::string> CustomVarsValuesColumn::getValue(
|
||||
Row row, const contact * /*auth_user*/,
|
||||
std::chrono::seconds /*timezone_offset*/) const {
|
||||
std::vector<std::string> values;
|
||||
#ifdef CMC
|
||||
if (auto *object = columnData<Object>(row)) {
|
||||
auto attrs = object->customAttributes();
|
||||
std::transform(attrs.begin(), attrs.end(), std::back_inserter(values),
|
||||
[](const auto &entry) { return entry.second; });
|
||||
}
|
||||
#else
|
||||
if (auto p = columnData<customvariablesmember *>(row)) {
|
||||
for (auto cvm = *p; cvm != nullptr; cvm = cvm->next) {
|
||||
values.emplace_back(cvm->variable_value);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return values;
|
||||
}
|
||||
49
src/CustomVarsValuesColumn.h
Normal file
49
src/CustomVarsValuesColumn.h
Normal file
@@ -0,0 +1,49 @@
|
||||
// +------------------------------------------------------------------+
|
||||
// | ____ _ _ __ __ _ __ |
|
||||
// | / ___| |__ ___ ___| | __ | \/ | |/ / |
|
||||
// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / |
|
||||
// | | |___| | | | __/ (__| < | | | | . \ |
|
||||
// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ |
|
||||
// | |
|
||||
// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de |
|
||||
// +------------------------------------------------------------------+
|
||||
//
|
||||
// This file is part of Check_MK.
|
||||
// The official homepage is at http://mathias-kettner.de/check_mk.
|
||||
//
|
||||
// check_mk is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation in version 2. check_mk is distributed
|
||||
// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with-
|
||||
// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
// PARTICULAR PURPOSE. See the GNU General Public License for more de-
|
||||
// tails. You should have received a copy of the GNU General Public
|
||||
// License along with GNU Make; see the file COPYING. If not, write
|
||||
// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
// Boston, MA 02110-1301 USA.
|
||||
|
||||
#ifndef CustomVarsValuesColumn_h
|
||||
#define CustomVarsValuesColumn_h
|
||||
|
||||
#include "config.h" // IWYU pragma: keep
|
||||
#include <chrono>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include "ListColumn.h"
|
||||
#include "contact_fwd.h"
|
||||
class Row;
|
||||
|
||||
class CustomVarsValuesColumn : public ListColumn {
|
||||
public:
|
||||
CustomVarsValuesColumn(const std::string &name,
|
||||
const std::string &description, int indirect_offset,
|
||||
int extra_offset, int extra_extra_offset, int offset)
|
||||
: ListColumn(name, description, indirect_offset, extra_offset,
|
||||
extra_extra_offset, offset) {}
|
||||
|
||||
std::vector<std::string> getValue(
|
||||
Row row, const contact *auth_user,
|
||||
std::chrono::seconds timezone_offset) const override;
|
||||
};
|
||||
|
||||
#endif // CustomVarsValuesColumn_h
|
||||
56
src/DoubleAggregator.h
Normal file
56
src/DoubleAggregator.h
Normal file
@@ -0,0 +1,56 @@
|
||||
// +------------------------------------------------------------------+
|
||||
// | ____ _ _ __ __ _ __ |
|
||||
// | / ___| |__ ___ ___| | __ | \/ | |/ / |
|
||||
// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / |
|
||||
// | | |___| | | | __/ (__| < | | | | . \ |
|
||||
// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ |
|
||||
// | |
|
||||
// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de |
|
||||
// +------------------------------------------------------------------+
|
||||
//
|
||||
// This file is part of Check_MK.
|
||||
// The official homepage is at http://mathias-kettner.de/check_mk.
|
||||
//
|
||||
// check_mk is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation in version 2. check_mk is distributed
|
||||
// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with-
|
||||
// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
// PARTICULAR PURPOSE. See the GNU General Public License for more de-
|
||||
// tails. You should have received a copy of the GNU General Public
|
||||
// License along with GNU Make; see the file COPYING. If not, write
|
||||
// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
// Boston, MA 02110-1301 USA.
|
||||
|
||||
#ifndef DoubleAggregator_h
|
||||
#define DoubleAggregator_h
|
||||
|
||||
#include "config.h" // IWYU pragma: keep
|
||||
#include <chrono>
|
||||
#include "Aggregator.h"
|
||||
#include "DoubleColumn.h"
|
||||
#include "contact_fwd.h"
|
||||
class Row;
|
||||
class RowRenderer;
|
||||
|
||||
class DoubleAggregator : public Aggregator {
|
||||
public:
|
||||
DoubleAggregator(const AggregationFactory &factory,
|
||||
const DoubleColumn *column)
|
||||
: _aggregation(factory()), _column(column) {}
|
||||
|
||||
void consume(Row row, const contact * /*contact*/,
|
||||
std::chrono::seconds /*timezone_offset*/) override {
|
||||
_aggregation->update(_column->getValue(row));
|
||||
}
|
||||
|
||||
void output(RowRenderer &r) const override {
|
||||
r.output(_aggregation->value());
|
||||
}
|
||||
|
||||
private:
|
||||
std::unique_ptr<Aggregation> _aggregation;
|
||||
const DoubleColumn *const _column;
|
||||
};
|
||||
|
||||
#endif // DoubleAggregator_h
|
||||
48
src/DoubleColumn.cc
Normal file
48
src/DoubleColumn.cc
Normal file
@@ -0,0 +1,48 @@
|
||||
// +------------------------------------------------------------------+
|
||||
// | ____ _ _ __ __ _ __ |
|
||||
// | / ___| |__ ___ ___| | __ | \/ | |/ / |
|
||||
// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / |
|
||||
// | | |___| | | | __/ (__| < | | | | . \ |
|
||||
// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ |
|
||||
// | |
|
||||
// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de |
|
||||
// +------------------------------------------------------------------+
|
||||
//
|
||||
// This file is part of Check_MK.
|
||||
// The official homepage is at http://mathias-kettner.de/check_mk.
|
||||
//
|
||||
// check_mk is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation in version 2. check_mk is distributed
|
||||
// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with-
|
||||
// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
// PARTICULAR PURPOSE. See the GNU General Public License for more de-
|
||||
// tails. You should have received a copy of the GNU General Public
|
||||
// License along with GNU Make; see the file COPYING. If not, write
|
||||
// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
// Boston, MA 02110-1301 USA.
|
||||
|
||||
#include "DoubleColumn.h"
|
||||
#include "Aggregator.h"
|
||||
#include "DoubleAggregator.h"
|
||||
#include "DoubleFilter.h"
|
||||
#include "Filter.h"
|
||||
#include "Renderer.h"
|
||||
#include "Row.h"
|
||||
|
||||
void DoubleColumn::output(Row row, RowRenderer &r,
|
||||
const contact * /*auth_user*/,
|
||||
std::chrono::seconds /*timezone_offset*/) const {
|
||||
r.output(getValue(row));
|
||||
}
|
||||
|
||||
std::unique_ptr<Filter> DoubleColumn::createFilter(
|
||||
Filter::Kind kind, RelationalOperator relOp,
|
||||
const std::string &value) const {
|
||||
return std::make_unique<DoubleFilter>(kind, *this, relOp, value);
|
||||
}
|
||||
|
||||
std::unique_ptr<Aggregator> DoubleColumn::createAggregator(
|
||||
AggregationFactory factory) const {
|
||||
return std::make_unique<DoubleAggregator>(factory, this);
|
||||
}
|
||||
60
src/DoubleColumn.h
Normal file
60
src/DoubleColumn.h
Normal file
@@ -0,0 +1,60 @@
|
||||
// +------------------------------------------------------------------+
|
||||
// | ____ _ _ __ __ _ __ |
|
||||
// | / ___| |__ ___ ___| | __ | \/ | |/ / |
|
||||
// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / |
|
||||
// | | |___| | | | __/ (__| < | | | | . \ |
|
||||
// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ |
|
||||
// | |
|
||||
// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de |
|
||||
// +------------------------------------------------------------------+
|
||||
//
|
||||
// This file is part of Check_MK.
|
||||
// The official homepage is at http://mathias-kettner.de/check_mk.
|
||||
//
|
||||
// check_mk is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation in version 2. check_mk is distributed
|
||||
// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with-
|
||||
// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
// PARTICULAR PURPOSE. See the GNU General Public License for more de-
|
||||
// tails. You should have received a copy of the GNU General Public
|
||||
// License along with GNU Make; see the file COPYING. If not, write
|
||||
// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
// Boston, MA 02110-1301 USA.
|
||||
|
||||
#ifndef DoubleColumn_h
|
||||
#define DoubleColumn_h
|
||||
|
||||
#include "config.h" // IWYU pragma: keep
|
||||
#include <chrono>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include "Column.h"
|
||||
#include "Filter.h"
|
||||
#include "contact_fwd.h"
|
||||
#include "opids.h"
|
||||
class Aggregator;
|
||||
class Row;
|
||||
class RowRenderer;
|
||||
|
||||
class DoubleColumn : public Column {
|
||||
public:
|
||||
DoubleColumn(const std::string &name, const std::string &description,
|
||||
int indirect_offset, int extra_offset, int extra_extra_offset,
|
||||
int offset)
|
||||
: Column(name, description, indirect_offset, extra_offset,
|
||||
extra_extra_offset, offset) {}
|
||||
[[nodiscard]] virtual double getValue(Row row) const = 0;
|
||||
void output(Row row, RowRenderer &r, const contact *auth_user,
|
||||
std::chrono::seconds timezone_offset) const override;
|
||||
[[nodiscard]] ColumnType type() const override {
|
||||
return ColumnType::double_;
|
||||
}
|
||||
[[nodiscard]] std::unique_ptr<Filter> createFilter(
|
||||
Filter::Kind kind, RelationalOperator relOp,
|
||||
const std::string &value) const override;
|
||||
[[nodiscard]] std::unique_ptr<Aggregator> createAggregator(
|
||||
AggregationFactory factory) const override;
|
||||
};
|
||||
|
||||
#endif // DoubleColumn_h
|
||||
76
src/DoubleFilter.cc
Normal file
76
src/DoubleFilter.cc
Normal file
@@ -0,0 +1,76 @@
|
||||
// +------------------------------------------------------------------+
|
||||
// | ____ _ _ __ __ _ __ |
|
||||
// | / ___| |__ ___ ___| | __ | \/ | |/ / |
|
||||
// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / |
|
||||
// | | |___| | | | __/ (__| < | | | | . \ |
|
||||
// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ |
|
||||
// | |
|
||||
// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de |
|
||||
// +------------------------------------------------------------------+
|
||||
//
|
||||
// This file is part of Check_MK.
|
||||
// The official homepage is at http://mathias-kettner.de/check_mk.
|
||||
//
|
||||
// check_mk is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation in version 2. check_mk is distributed
|
||||
// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with-
|
||||
// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
// PARTICULAR PURPOSE. See the GNU General Public License for more de-
|
||||
// tails. You should have received a copy of the GNU General Public
|
||||
// License along with GNU Make; see the file COPYING. If not, write
|
||||
// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
// Boston, MA 02110-1301 USA.
|
||||
|
||||
#include "DoubleFilter.h"
|
||||
#include <cstdlib>
|
||||
#include <ostream>
|
||||
#include "DoubleColumn.h"
|
||||
#include "Filter.h"
|
||||
#include "Logger.h"
|
||||
#include "Row.h"
|
||||
|
||||
DoubleFilter::DoubleFilter(Kind kind, const DoubleColumn &column,
|
||||
RelationalOperator relOp, const std::string &value)
|
||||
: ColumnFilter(kind, column, relOp, value)
|
||||
, _column(column)
|
||||
, _ref_value(atof(value.c_str())) {}
|
||||
|
||||
bool DoubleFilter::accepts(Row row, const contact * /* auth_user */,
|
||||
std::chrono::seconds /* timezone_offset */) const {
|
||||
double act_value = _column.getValue(row);
|
||||
switch (oper()) {
|
||||
case RelationalOperator::equal:
|
||||
return act_value == _ref_value;
|
||||
case RelationalOperator::not_equal:
|
||||
return act_value != _ref_value;
|
||||
case RelationalOperator::less:
|
||||
return act_value < _ref_value;
|
||||
case RelationalOperator::greater_or_equal:
|
||||
return act_value >= _ref_value;
|
||||
case RelationalOperator::greater:
|
||||
return act_value > _ref_value;
|
||||
case RelationalOperator::less_or_equal:
|
||||
return act_value <= _ref_value;
|
||||
case RelationalOperator::matches:
|
||||
case RelationalOperator::doesnt_match:
|
||||
case RelationalOperator::equal_icase:
|
||||
case RelationalOperator::not_equal_icase:
|
||||
case RelationalOperator::matches_icase:
|
||||
case RelationalOperator::doesnt_match_icase:
|
||||
Informational(_column.logger())
|
||||
<< "Sorry. Operator " << oper()
|
||||
<< " for float columns not implemented.";
|
||||
return false;
|
||||
}
|
||||
return false; // unreachable
|
||||
}
|
||||
|
||||
std::unique_ptr<Filter> DoubleFilter::copy() const {
|
||||
return std::make_unique<DoubleFilter>(*this);
|
||||
}
|
||||
|
||||
std::unique_ptr<Filter> DoubleFilter::negate() const {
|
||||
return std::make_unique<DoubleFilter>(
|
||||
kind(), _column, negateRelationalOperator(oper()), value());
|
||||
}
|
||||
53
src/DoubleFilter.h
Normal file
53
src/DoubleFilter.h
Normal file
@@ -0,0 +1,53 @@
|
||||
// +------------------------------------------------------------------+
|
||||
// | ____ _ _ __ __ _ __ |
|
||||
// | / ___| |__ ___ ___| | __ | \/ | |/ / |
|
||||
// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / |
|
||||
// | | |___| | | | __/ (__| < | | | | . \ |
|
||||
// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ |
|
||||
// | |
|
||||
// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de |
|
||||
// +------------------------------------------------------------------+
|
||||
//
|
||||
// This file is part of Check_MK.
|
||||
// The official homepage is at http://mathias-kettner.de/check_mk.
|
||||
//
|
||||
// check_mk is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation in version 2. check_mk is distributed
|
||||
// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with-
|
||||
// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
// PARTICULAR PURPOSE. See the GNU General Public License for more de-
|
||||
// tails. You should have received a copy of the GNU General Public
|
||||
// License along with GNU Make; see the file COPYING. If not, write
|
||||
// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
// Boston, MA 02110-1301 USA.
|
||||
|
||||
#ifndef DoubleFilter_h
|
||||
#define DoubleFilter_h
|
||||
|
||||
#include "config.h" // IWYU pragma: keep
|
||||
#include <chrono>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include "ColumnFilter.h"
|
||||
#include "Filter.h"
|
||||
#include "contact_fwd.h"
|
||||
#include "opids.h"
|
||||
class DoubleColumn;
|
||||
class Row;
|
||||
|
||||
class DoubleFilter : public ColumnFilter {
|
||||
public:
|
||||
DoubleFilter(Kind kind, const DoubleColumn &column,
|
||||
RelationalOperator relOp, const std::string &value);
|
||||
bool accepts(Row row, const contact *auth_user,
|
||||
std::chrono::seconds timezone_offset) const override;
|
||||
[[nodiscard]] std::unique_ptr<Filter> copy() const override;
|
||||
[[nodiscard]] std::unique_ptr<Filter> negate() const override;
|
||||
|
||||
private:
|
||||
const DoubleColumn &_column;
|
||||
const double _ref_value;
|
||||
};
|
||||
|
||||
#endif // DoubleFilter_h
|
||||
45
src/DoublePointerColumn.h
Normal file
45
src/DoublePointerColumn.h
Normal file
@@ -0,0 +1,45 @@
|
||||
// +------------------------------------------------------------------+
|
||||
// | ____ _ _ __ __ _ __ |
|
||||
// | / ___| |__ ___ ___| | __ | \/ | |/ / |
|
||||
// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / |
|
||||
// | | |___| | | | __/ (__| < | | | | . \ |
|
||||
// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ |
|
||||
// | |
|
||||
// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de |
|
||||
// +------------------------------------------------------------------+
|
||||
//
|
||||
// This file is part of Check_MK.
|
||||
// The official homepage is at http://mathias-kettner.de/check_mk.
|
||||
//
|
||||
// check_mk is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation in version 2. check_mk is distributed
|
||||
// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with-
|
||||
// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
// PARTICULAR PURPOSE. See the GNU General Public License for more de-
|
||||
// tails. You should have received a copy of the GNU General Public
|
||||
// License along with GNU Make; see the file COPYING. If not, write
|
||||
// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
// Boston, MA 02110-1301 USA.
|
||||
|
||||
#ifndef DoublePointerColumn_h
|
||||
#define DoublePointerColumn_h
|
||||
|
||||
#include "config.h" // IWYU pragma: keep
|
||||
#include "DoubleColumn.h"
|
||||
|
||||
class DoublePointerColumn : public DoubleColumn {
|
||||
public:
|
||||
DoublePointerColumn(const std::string &name, const std::string &description,
|
||||
const double *number)
|
||||
: DoubleColumn(name, description, -1, -1, -1, 0), _number(number) {}
|
||||
|
||||
[[nodiscard]] double getValue(Row /*unused*/) const override {
|
||||
return *_number;
|
||||
}
|
||||
|
||||
private:
|
||||
const double *const _number;
|
||||
};
|
||||
|
||||
#endif // DoublePointerColumn_h
|
||||
70
src/DowntimeColumn.cc
Normal file
70
src/DowntimeColumn.cc
Normal file
@@ -0,0 +1,70 @@
|
||||
// +------------------------------------------------------------------+
|
||||
// | ____ _ _ __ __ _ __ |
|
||||
// | / ___| |__ ___ ___| | __ | \/ | |/ / |
|
||||
// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / |
|
||||
// | | |___| | | | __/ (__| < | | | | . \ |
|
||||
// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ |
|
||||
// | |
|
||||
// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de |
|
||||
// +------------------------------------------------------------------+
|
||||
//
|
||||
// This file is part of Check_MK.
|
||||
// The official homepage is at http://mathias-kettner.de/check_mk.
|
||||
//
|
||||
// check_mk is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation in version 2. check_mk is distributed
|
||||
// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with-
|
||||
// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
// PARTICULAR PURPOSE. See the GNU General Public License for more de-
|
||||
// tails. You should have received a copy of the GNU General Public
|
||||
// License along with GNU Make; see the file COPYING. If not, write
|
||||
// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
// Boston, MA 02110-1301 USA.
|
||||
|
||||
#include "DowntimeColumn.h"
|
||||
#include "MonitoringCore.h"
|
||||
#include "Renderer.h"
|
||||
#include "Row.h"
|
||||
|
||||
#ifndef CMC
|
||||
#include "nagios.h"
|
||||
#endif
|
||||
|
||||
void DowntimeColumn::output(Row row, RowRenderer &r,
|
||||
const contact * /*auth_user*/,
|
||||
std::chrono::seconds /*timezone_offset*/) const {
|
||||
ListRenderer l(r);
|
||||
for (const auto &downtime : downtimes_for_row(row)) {
|
||||
if (_with_info) {
|
||||
SublistRenderer s(l);
|
||||
s.output(downtime._id);
|
||||
s.output(downtime._author);
|
||||
s.output(downtime._comment);
|
||||
} else {
|
||||
l.output(downtime._id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<std::string> DowntimeColumn::getValue(
|
||||
Row row, const contact * /*auth_user*/,
|
||||
std::chrono::seconds /*timezone_offset*/) const {
|
||||
std::vector<std::string> ids;
|
||||
for (const auto &downtime : downtimes_for_row(row)) {
|
||||
ids.push_back(std::to_string(downtime._id));
|
||||
}
|
||||
return ids;
|
||||
}
|
||||
|
||||
std::vector<DowntimeData> DowntimeColumn::downtimes_for_row(Row row) const {
|
||||
if (auto data = columnData<void>(row)) {
|
||||
return _is_service
|
||||
? _mc->downtimes_for_service(
|
||||
reinterpret_cast<const MonitoringCore::Service *>(
|
||||
data))
|
||||
: _mc->downtimes_for_host(
|
||||
reinterpret_cast<const MonitoringCore::Host *>(data));
|
||||
}
|
||||
return {};
|
||||
}
|
||||
66
src/DowntimeColumn.h
Normal file
66
src/DowntimeColumn.h
Normal file
@@ -0,0 +1,66 @@
|
||||
// +------------------------------------------------------------------+
|
||||
// | ____ _ _ __ __ _ __ |
|
||||
// | / ___| |__ ___ ___| | __ | \/ | |/ / |
|
||||
// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / |
|
||||
// | | |___| | | | __/ (__| < | | | | . \ |
|
||||
// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ |
|
||||
// | |
|
||||
// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de |
|
||||
// +------------------------------------------------------------------+
|
||||
//
|
||||
// This file is part of Check_MK.
|
||||
// The official homepage is at http://mathias-kettner.de/check_mk.
|
||||
//
|
||||
// check_mk is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation in version 2. check_mk is distributed
|
||||
// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with-
|
||||
// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
// PARTICULAR PURPOSE. See the GNU General Public License for more de-
|
||||
// tails. You should have received a copy of the GNU General Public
|
||||
// License along with GNU Make; see the file COPYING. If not, write
|
||||
// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
// Boston, MA 02110-1301 USA.
|
||||
|
||||
#ifndef DowntimeColumn_h
|
||||
#define DowntimeColumn_h
|
||||
|
||||
#include "config.h" // IWYU pragma: keep
|
||||
#include <chrono>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include "ListColumn.h"
|
||||
#include "contact_fwd.h"
|
||||
struct DowntimeData;
|
||||
class MonitoringCore;
|
||||
class Row;
|
||||
class RowRenderer;
|
||||
|
||||
class DowntimeColumn : public ListColumn {
|
||||
public:
|
||||
DowntimeColumn(const std::string &name, const std::string &description,
|
||||
int indirect_offset, int extra_offset,
|
||||
int extra_extra_offset, int offset, MonitoringCore *mc,
|
||||
bool is_service, bool with_info)
|
||||
: ListColumn(name, description, indirect_offset, extra_offset,
|
||||
extra_extra_offset, offset)
|
||||
, _mc(mc)
|
||||
, _is_service(is_service)
|
||||
, _with_info(with_info) {}
|
||||
|
||||
void output(Row row, RowRenderer &r, const contact *auth_user,
|
||||
std::chrono::seconds timezone_offset) const override;
|
||||
|
||||
std::vector<std::string> getValue(
|
||||
Row row, const contact *auth_user,
|
||||
std::chrono::seconds timezone_offset) const override;
|
||||
|
||||
private:
|
||||
MonitoringCore *_mc;
|
||||
bool _is_service;
|
||||
bool _with_info;
|
||||
|
||||
[[nodiscard]] std::vector<DowntimeData> downtimes_for_row(Row row) const;
|
||||
};
|
||||
|
||||
#endif // DowntimeColumn_h
|
||||
57
src/DowntimeOrComment.cc
Normal file
57
src/DowntimeOrComment.cc
Normal file
@@ -0,0 +1,57 @@
|
||||
// +------------------------------------------------------------------+
|
||||
// | ____ _ _ __ __ _ __ |
|
||||
// | / ___| |__ ___ ___| | __ | \/ | |/ / |
|
||||
// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / |
|
||||
// | | |___| | | | __/ (__| < | | | | . \ |
|
||||
// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ |
|
||||
// | |
|
||||
// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de |
|
||||
// +------------------------------------------------------------------+
|
||||
//
|
||||
// This file is part of Check_MK.
|
||||
// The official homepage is at http://mathias-kettner.de/check_mk.
|
||||
//
|
||||
// check_mk is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation in version 2. check_mk is distributed
|
||||
// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with-
|
||||
// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
// PARTICULAR PURPOSE. See the GNU General Public License for more de-
|
||||
// tails. You should have received a copy of the GNU General Public
|
||||
// License along with GNU Make; see the file COPYING. If not, write
|
||||
// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
// Boston, MA 02110-1301 USA.
|
||||
|
||||
#include "DowntimeOrComment.h"
|
||||
|
||||
DowntimeOrComment::DowntimeOrComment(nebstruct_downtime_struct *dt,
|
||||
unsigned long id)
|
||||
: _type(dt->downtime_type)
|
||||
, _is_service(dt->service_description != nullptr)
|
||||
, _host(find_host(dt->host_name))
|
||||
, _service(_is_service
|
||||
? find_service(dt->host_name, dt->service_description)
|
||||
: nullptr)
|
||||
, _entry_time(dt->entry_time)
|
||||
, _author_name(dt->author_name)
|
||||
, _comment(dt->comment_data)
|
||||
, _id(id) {}
|
||||
|
||||
DowntimeOrComment::~DowntimeOrComment() = default;
|
||||
|
||||
Downtime::Downtime(nebstruct_downtime_struct *dt)
|
||||
: DowntimeOrComment(dt, dt->downtime_id)
|
||||
, _start_time(dt->start_time)
|
||||
, _end_time(dt->end_time)
|
||||
, _fixed(dt->fixed)
|
||||
, _duration(static_cast<int>(dt->duration))
|
||||
, _triggered_by(static_cast<int>(dt->triggered_by)) {}
|
||||
|
||||
Comment::Comment(nebstruct_comment_struct *co)
|
||||
: DowntimeOrComment(reinterpret_cast<nebstruct_downtime_struct *>(co),
|
||||
co->comment_id)
|
||||
, _expire_time(co->expire_time)
|
||||
, _persistent(co->persistent)
|
||||
, _source(co->source)
|
||||
, _entry_type(co->entry_type)
|
||||
, _expires(co->expires) {}
|
||||
119
src/DowntimeOrComment.h
Normal file
119
src/DowntimeOrComment.h
Normal file
@@ -0,0 +1,119 @@
|
||||
// +------------------------------------------------------------------+
|
||||
// | ____ _ _ __ __ _ __ |
|
||||
// | / ___| |__ ___ ___| | __ | \/ | |/ / |
|
||||
// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / |
|
||||
// | | |___| | | | __/ (__| < | | | | . \ |
|
||||
// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ |
|
||||
// | |
|
||||
// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de |
|
||||
// +------------------------------------------------------------------+
|
||||
//
|
||||
// This file is part of Check_MK.
|
||||
// The official homepage is at http://mathias-kettner.de/check_mk.
|
||||
//
|
||||
// check_mk is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation in version 2. check_mk is distributed
|
||||
// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with-
|
||||
// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
// PARTICULAR PURPOSE. See the GNU General Public License for more de-
|
||||
// tails. You should have received a copy of the GNU General Public
|
||||
// License along with GNU Make; see the file COPYING. If not, write
|
||||
// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
// Boston, MA 02110-1301 USA.
|
||||
|
||||
#ifndef DowntimeOrComment_h
|
||||
#define DowntimeOrComment_h
|
||||
|
||||
#include "config.h" // IWYU pragma: keep
|
||||
#include <ctime>
|
||||
#include <string>
|
||||
#include "nagios.h"
|
||||
|
||||
/* The structs for downtime and comment are so similar, that
|
||||
we handle them with the same logic */
|
||||
|
||||
/*
|
||||
typedef struct nebstruct_downtime_struct{
|
||||
int type;
|
||||
int flags;
|
||||
int attr;
|
||||
struct timeval timestamp;
|
||||
|
||||
int downtime_type;
|
||||
char *host_name;
|
||||
char *service_description;
|
||||
time_t entry_time;
|
||||
char *author_name;
|
||||
char *comment_data;
|
||||
time_t start_time;
|
||||
time_t end_time;
|
||||
int fixed;
|
||||
unsigned long duration;
|
||||
unsigned long triggered_by;
|
||||
unsigned long downtime_id;
|
||||
|
||||
void *object_ptr; // not implemented yet
|
||||
}nebstruct_downtime_data;
|
||||
|
||||
typedef struct nebstruct_comment_struct{
|
||||
int type;
|
||||
int flags;
|
||||
int attr;
|
||||
struct timeval timestamp;
|
||||
|
||||
int comment_type;
|
||||
char *host_name;
|
||||
char *service_description;
|
||||
time_t entry_time;
|
||||
char *author_name;
|
||||
char *comment_data;
|
||||
int persistent;
|
||||
int source;
|
||||
int entry_type;
|
||||
int expires;
|
||||
time_t expire_time;
|
||||
unsigned long comment_id;
|
||||
|
||||
void *object_ptr; // not implemented yet
|
||||
}nebstruct_comment_data;
|
||||
*/
|
||||
|
||||
class DowntimeOrComment {
|
||||
public:
|
||||
int _type;
|
||||
bool _is_service;
|
||||
host *_host;
|
||||
service *_service;
|
||||
time_t _entry_time;
|
||||
std::string _author_name;
|
||||
std::string _comment;
|
||||
unsigned long _id;
|
||||
|
||||
DowntimeOrComment(nebstruct_downtime_struct *dt, unsigned long id);
|
||||
virtual ~DowntimeOrComment();
|
||||
};
|
||||
|
||||
class Downtime : public DowntimeOrComment {
|
||||
public:
|
||||
time_t _start_time;
|
||||
time_t _end_time;
|
||||
int _fixed;
|
||||
// TODO(sp): Wrong types, caused by TableDowntimes accessing it via
|
||||
// OffsetIntColumn, should be unsigned long
|
||||
int _duration;
|
||||
int _triggered_by;
|
||||
explicit Downtime(nebstruct_downtime_struct *dt);
|
||||
};
|
||||
|
||||
class Comment : public DowntimeOrComment {
|
||||
public:
|
||||
time_t _expire_time;
|
||||
int _persistent;
|
||||
int _source;
|
||||
int _entry_type;
|
||||
int _expires;
|
||||
explicit Comment(nebstruct_comment_struct *co);
|
||||
};
|
||||
|
||||
#endif // DowntimeOrComment_h
|
||||
67
src/DowntimesOrComments.cc
Normal file
67
src/DowntimesOrComments.cc
Normal file
@@ -0,0 +1,67 @@
|
||||
// +------------------------------------------------------------------+
|
||||
// | ____ _ _ __ __ _ __ |
|
||||
// | / ___| |__ ___ ___| | __ | \/ | |/ / |
|
||||
// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / |
|
||||
// | | |___| | | | __/ (__| < | | | | . \ |
|
||||
// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ |
|
||||
// | |
|
||||
// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de |
|
||||
// +------------------------------------------------------------------+
|
||||
//
|
||||
// This file is part of Check_MK.
|
||||
// The official homepage is at http://mathias-kettner.de/check_mk.
|
||||
//
|
||||
// check_mk is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation in version 2. check_mk is distributed
|
||||
// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with-
|
||||
// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
// PARTICULAR PURPOSE. See the GNU General Public License for more de-
|
||||
// tails. You should have received a copy of the GNU General Public
|
||||
// License along with GNU Make; see the file COPYING. If not, write
|
||||
// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
// Boston, MA 02110-1301 USA.
|
||||
|
||||
#include "DowntimesOrComments.h"
|
||||
#include <iosfwd>
|
||||
#include "DowntimeOrComment.h"
|
||||
#include "Logger.h"
|
||||
|
||||
DowntimesOrComments::DowntimesOrComments()
|
||||
: _logger(Logger::getLogger("cmk.livestatus")) {}
|
||||
|
||||
void DowntimesOrComments::registerDowntime(nebstruct_downtime_data *data) {
|
||||
unsigned long id = data->downtime_id;
|
||||
switch (data->type) {
|
||||
case NEBTYPE_DOWNTIME_ADD:
|
||||
case NEBTYPE_DOWNTIME_LOAD:
|
||||
_entries[id] = std::make_unique<Downtime>(data);
|
||||
break;
|
||||
case NEBTYPE_DOWNTIME_DELETE:
|
||||
if (_entries.erase(id) == 0) {
|
||||
Informational(_logger)
|
||||
<< "Cannot delete non-existing downtime " << id;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void DowntimesOrComments::registerComment(nebstruct_comment_data *data) {
|
||||
unsigned long id = data->comment_id;
|
||||
switch (data->type) {
|
||||
case NEBTYPE_COMMENT_ADD:
|
||||
case NEBTYPE_COMMENT_LOAD:
|
||||
_entries[id] = std::make_unique<Comment>(data);
|
||||
break;
|
||||
case NEBTYPE_COMMENT_DELETE:
|
||||
if (_entries.erase(id) == 0) {
|
||||
Informational(_logger)
|
||||
<< "Cannot delete non-existing comment " << id;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
48
src/DowntimesOrComments.h
Normal file
48
src/DowntimesOrComments.h
Normal file
@@ -0,0 +1,48 @@
|
||||
// +------------------------------------------------------------------+
|
||||
// | ____ _ _ __ __ _ __ |
|
||||
// | / ___| |__ ___ ___| | __ | \/ | |/ / |
|
||||
// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / |
|
||||
// | | |___| | | | __/ (__| < | | | | . \ |
|
||||
// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ |
|
||||
// | |
|
||||
// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de |
|
||||
// +------------------------------------------------------------------+
|
||||
//
|
||||
// This file is part of Check_MK.
|
||||
// The official homepage is at http://mathias-kettner.de/check_mk.
|
||||
//
|
||||
// check_mk is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation in version 2. check_mk is distributed
|
||||
// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with-
|
||||
// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
// PARTICULAR PURPOSE. See the GNU General Public License for more de-
|
||||
// tails. You should have received a copy of the GNU General Public
|
||||
// License along with GNU Make; see the file COPYING. If not, write
|
||||
// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
// Boston, MA 02110-1301 USA.
|
||||
|
||||
#ifndef DowntimesOrComments_h
|
||||
#define DowntimesOrComments_h
|
||||
|
||||
#include "config.h" // IWYU pragma: keep
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include "nagios.h"
|
||||
class DowntimeOrComment;
|
||||
class Logger;
|
||||
|
||||
class DowntimesOrComments {
|
||||
public:
|
||||
DowntimesOrComments();
|
||||
void registerDowntime(nebstruct_downtime_data *data);
|
||||
void registerComment(nebstruct_comment_data *data);
|
||||
[[nodiscard]] auto begin() const { return _entries.cbegin(); }
|
||||
[[nodiscard]] auto end() const { return _entries.cend(); }
|
||||
|
||||
private:
|
||||
std::map<unsigned long, std::unique_ptr<DowntimeOrComment>> _entries;
|
||||
Logger *const _logger;
|
||||
};
|
||||
|
||||
#endif // DowntimesOrComments_h
|
||||
40
src/DynamicColumn.cc
Normal file
40
src/DynamicColumn.cc
Normal file
@@ -0,0 +1,40 @@
|
||||
// +------------------------------------------------------------------+
|
||||
// | ____ _ _ __ __ _ __ |
|
||||
// | / ___| |__ ___ ___| | __ | \/ | |/ / |
|
||||
// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / |
|
||||
// | | |___| | | | __/ (__| < | | | | . \ |
|
||||
// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ |
|
||||
// | |
|
||||
// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de |
|
||||
// +------------------------------------------------------------------+
|
||||
//
|
||||
// This file is part of Check_MK.
|
||||
// The official homepage is at http://mathias-kettner.de/check_mk.
|
||||
//
|
||||
// check_mk is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation in version 2. check_mk is distributed
|
||||
// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with-
|
||||
// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
// PARTICULAR PURPOSE. See the GNU General Public License for more de-
|
||||
// tails. You should have received a copy of the GNU General Public
|
||||
// License along with GNU Make; see the file COPYING. If not, write
|
||||
// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
// Boston, MA 02110-1301 USA.
|
||||
|
||||
#include "DynamicColumn.h"
|
||||
#include <utility>
|
||||
|
||||
DynamicColumn::DynamicColumn(std::string name, std::string description,
|
||||
Logger *logger, int indirect_offset,
|
||||
int extra_offset, int extra_extra_offset)
|
||||
: _name(std::move(name))
|
||||
, _description(std::move(description))
|
||||
, _logger(logger)
|
||||
, _indirect_offset(indirect_offset)
|
||||
, _extra_offset(extra_offset)
|
||||
, _extra_extra_offset(extra_extra_offset) {}
|
||||
|
||||
DynamicColumn::~DynamicColumn() = default;
|
||||
|
||||
std::string DynamicColumn::name() const { return _name; }
|
||||
53
src/DynamicColumn.h
Normal file
53
src/DynamicColumn.h
Normal file
@@ -0,0 +1,53 @@
|
||||
// +------------------------------------------------------------------+
|
||||
// | ____ _ _ __ __ _ __ |
|
||||
// | / ___| |__ ___ ___| | __ | \/ | |/ / |
|
||||
// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / |
|
||||
// | | |___| | | | __/ (__| < | | | | . \ |
|
||||
// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ |
|
||||
// | |
|
||||
// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de |
|
||||
// +------------------------------------------------------------------+
|
||||
//
|
||||
// This file is part of Check_MK.
|
||||
// The official homepage is at http://mathias-kettner.de/check_mk.
|
||||
//
|
||||
// check_mk is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation in version 2. check_mk is distributed
|
||||
// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with-
|
||||
// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
// PARTICULAR PURPOSE. See the GNU General Public License for more de-
|
||||
// tails. You should have received a copy of the GNU General Public
|
||||
// License along with GNU Make; see the file COPYING. If not, write
|
||||
// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
// Boston, MA 02110-1301 USA.
|
||||
|
||||
#ifndef DynamicColumn_h
|
||||
#define DynamicColumn_h
|
||||
|
||||
#include "config.h" // IWYU pragma: keep
|
||||
#include <memory>
|
||||
#include <string>
|
||||
class Column;
|
||||
class Logger;
|
||||
|
||||
class DynamicColumn {
|
||||
public:
|
||||
DynamicColumn(std::string name, std::string description, Logger *logger,
|
||||
int indirect_offset, int extra_offset,
|
||||
int extra_extra_offset);
|
||||
virtual ~DynamicColumn();
|
||||
[[nodiscard]] std::string name() const;
|
||||
virtual std::unique_ptr<Column> createColumn(
|
||||
const std::string &name, const std::string &arguments) = 0;
|
||||
|
||||
protected:
|
||||
const std::string _name;
|
||||
const std::string _description; // Note: Currently unused!
|
||||
Logger *const _logger;
|
||||
const int _indirect_offset;
|
||||
const int _extra_offset;
|
||||
const int _extra_extra_offset;
|
||||
};
|
||||
|
||||
#endif // DynamicColumn_h
|
||||
95
src/DynamicEventConsoleReplicationColumn.cc
Normal file
95
src/DynamicEventConsoleReplicationColumn.cc
Normal file
@@ -0,0 +1,95 @@
|
||||
// +------------------------------------------------------------------+
|
||||
// | ____ _ _ __ __ _ __ |
|
||||
// | / ___| |__ ___ ___| | __ | \/ | |/ / |
|
||||
// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / |
|
||||
// | | |___| | | | __/ (__| < | | | | . \ |
|
||||
// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ |
|
||||
// | |
|
||||
// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de |
|
||||
// +------------------------------------------------------------------+
|
||||
//
|
||||
// This file is part of Check_MK.
|
||||
// The official homepage is at http://mathias-kettner.de/check_mk.
|
||||
//
|
||||
// check_mk is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation in version 2. check_mk is distributed
|
||||
// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with-
|
||||
// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
// PARTICULAR PURPOSE. See the GNU General Public License for more de-
|
||||
// tails. You should have received a copy of the GNU General Public
|
||||
// License along with GNU Make; see the file COPYING. If not, write
|
||||
// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
// Boston, MA 02110-1301 USA.
|
||||
|
||||
#include "DynamicEventConsoleReplicationColumn.h"
|
||||
#include <iosfwd>
|
||||
#include <memory>
|
||||
#include <stdexcept>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
#include "BlobColumn.h"
|
||||
#include "Column.h"
|
||||
#include "EventConsoleConnection.h"
|
||||
#include "Logger.h"
|
||||
#include "MonitoringCore.h"
|
||||
#include "Row.h"
|
||||
|
||||
namespace {
|
||||
class ECTableConnection : public EventConsoleConnection {
|
||||
public:
|
||||
ECTableConnection(MonitoringCore *mc, std::string command)
|
||||
: EventConsoleConnection(mc->loggerLivestatus(),
|
||||
mc->mkeventdSocketPath())
|
||||
, _command(std::move(command)) {}
|
||||
[[nodiscard]] std::string getResult() const { return _result; }
|
||||
|
||||
private:
|
||||
void sendRequest(std::ostream &os) override { os << _command; }
|
||||
void receiveReply(std::istream &is) override { std::getline(is, _result); }
|
||||
|
||||
const std::string _command;
|
||||
std::string _result;
|
||||
};
|
||||
|
||||
class ReplicationColumn : public BlobColumn {
|
||||
public:
|
||||
ReplicationColumn(const std::string &name, const std::string &description,
|
||||
std::string blob, int indirect_offset, int extra_offset,
|
||||
int extra_extra_offset, int offset)
|
||||
: BlobColumn(name, description, indirect_offset, extra_offset,
|
||||
extra_extra_offset, offset)
|
||||
, _blob(std::move(blob)) {}
|
||||
|
||||
[[nodiscard]] std::unique_ptr<std::vector<char>> getValue(
|
||||
Row /* unused */) const override {
|
||||
return std::make_unique<std::vector<char>>(_blob.begin(), _blob.end());
|
||||
};
|
||||
|
||||
private:
|
||||
const std::string _blob;
|
||||
};
|
||||
} // namespace
|
||||
|
||||
DynamicEventConsoleReplicationColumn::DynamicEventConsoleReplicationColumn(
|
||||
const std::string &name, const std::string &description, MonitoringCore *mc,
|
||||
int indirect_offset, int extra_offset, int extra_extra_offset)
|
||||
: DynamicColumn(name, description, mc->loggerLivestatus(), indirect_offset,
|
||||
extra_offset, extra_extra_offset)
|
||||
, _mc(mc) {}
|
||||
|
||||
std::unique_ptr<Column> DynamicEventConsoleReplicationColumn::createColumn(
|
||||
const std::string &name, const std::string &arguments) {
|
||||
std::string result;
|
||||
if (_mc->mkeventdEnabled()) {
|
||||
try {
|
||||
ECTableConnection ec(_mc, "REPLICATE " + arguments);
|
||||
ec.run();
|
||||
result = ec.getResult();
|
||||
} catch (const std::runtime_error &err) {
|
||||
Alert(_mc->loggerLivestatus()) << err.what();
|
||||
}
|
||||
}
|
||||
return std::make_unique<ReplicationColumn>(name, "replication value",
|
||||
result, -1, -1, -1, 0);
|
||||
}
|
||||
50
src/DynamicEventConsoleReplicationColumn.h
Normal file
50
src/DynamicEventConsoleReplicationColumn.h
Normal file
@@ -0,0 +1,50 @@
|
||||
// +------------------------------------------------------------------+
|
||||
// | ____ _ _ __ __ _ __ |
|
||||
// | / ___| |__ ___ ___| | __ | \/ | |/ / |
|
||||
// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / |
|
||||
// | | |___| | | | __/ (__| < | | | | . \ |
|
||||
// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ |
|
||||
// | |
|
||||
// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de |
|
||||
// +------------------------------------------------------------------+
|
||||
//
|
||||
// This file is part of Check_MK.
|
||||
// The official homepage is at http://mathias-kettner.de/check_mk.
|
||||
//
|
||||
// check_mk is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation in version 2. check_mk is distributed
|
||||
// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with-
|
||||
// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
// PARTICULAR PURPOSE. See the GNU General Public License for more de-
|
||||
// tails. You should have received a copy of the GNU General Public
|
||||
// License along with GNU Make; see the file COPYING. If not, write
|
||||
// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
// Boston, MA 02110-1301 USA.
|
||||
|
||||
#ifndef DynamicEventConsoleReplicationColumn_h
|
||||
#define DynamicEventConsoleReplicationColumn_h
|
||||
|
||||
#include "config.h" // IWYU pragma: keep
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include "DynamicColumn.h"
|
||||
class Column;
|
||||
class MonitoringCore;
|
||||
|
||||
class DynamicEventConsoleReplicationColumn : public DynamicColumn {
|
||||
public:
|
||||
DynamicEventConsoleReplicationColumn(const std::string &name,
|
||||
const std::string &description,
|
||||
MonitoringCore *mc,
|
||||
int indirect_offset, int extra_offset,
|
||||
int extra_extra_offset);
|
||||
|
||||
std::unique_ptr<Column> createColumn(const std::string &name,
|
||||
const std::string &arguments) override;
|
||||
|
||||
private:
|
||||
MonitoringCore *_mc;
|
||||
};
|
||||
|
||||
#endif // DynamicEventConsoleReplicationColumn_h
|
||||
69
src/DynamicLogwatchFileColumn.cc
Normal file
69
src/DynamicLogwatchFileColumn.cc
Normal file
@@ -0,0 +1,69 @@
|
||||
// +------------------------------------------------------------------+
|
||||
// | ____ _ _ __ __ _ __ |
|
||||
// | / ___| |__ ___ ___| | __ | \/ | |/ / |
|
||||
// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / |
|
||||
// | | |___| | | | __/ (__| < | | | | . \ |
|
||||
// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ |
|
||||
// | |
|
||||
// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de |
|
||||
// +------------------------------------------------------------------+
|
||||
//
|
||||
// This file is part of Check_MK.
|
||||
// The official homepage is at http://mathias-kettner.de/check_mk.
|
||||
//
|
||||
// check_mk is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation in version 2. check_mk is distributed
|
||||
// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with-
|
||||
// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
// PARTICULAR PURPOSE. See the GNU General Public License for more de-
|
||||
// tails. You should have received a copy of the GNU General Public
|
||||
// License along with GNU Make; see the file COPYING. If not, write
|
||||
// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
// Boston, MA 02110-1301 USA.
|
||||
|
||||
#include "DynamicLogwatchFileColumn.h"
|
||||
#include <stdexcept>
|
||||
#include "Column.h"
|
||||
#include "HostFileColumn.h"
|
||||
#include "MonitoringCore.h"
|
||||
|
||||
namespace {
|
||||
// Replace \\ with \ and \s with space
|
||||
std::string unescape_filename(std::string filename) {
|
||||
std::string filename_native;
|
||||
bool quote_active = false;
|
||||
for (auto c : filename) {
|
||||
if (quote_active) {
|
||||
if (c == 's') {
|
||||
filename_native += ' ';
|
||||
} else {
|
||||
filename_native += c;
|
||||
}
|
||||
quote_active = false;
|
||||
} else if (c == '\\') {
|
||||
quote_active = true;
|
||||
} else {
|
||||
filename_native += c;
|
||||
}
|
||||
}
|
||||
return filename_native;
|
||||
}
|
||||
} // namespace
|
||||
|
||||
std::unique_ptr<Column> DynamicLogwatchFileColumn::createColumn(
|
||||
const std::string &name, const std::string &arguments) {
|
||||
// arguments contains a file name
|
||||
if (arguments.empty()) {
|
||||
throw std::runtime_error("invalid arguments for column '" + _name +
|
||||
"': missing file name");
|
||||
}
|
||||
if (arguments.find('/') != std::string::npos) {
|
||||
throw std::runtime_error("invalid arguments for column '" + _name +
|
||||
"': file name '" + arguments +
|
||||
"' contains slash");
|
||||
}
|
||||
return std::make_unique<HostFileColumn>(
|
||||
name, "Contents of logwatch file", _indirect_offset, _extra_offset, -1,
|
||||
0, _mc->mkLogwatchPath(), "/" + unescape_filename(arguments));
|
||||
}
|
||||
53
src/DynamicLogwatchFileColumn.h
Normal file
53
src/DynamicLogwatchFileColumn.h
Normal file
@@ -0,0 +1,53 @@
|
||||
// +------------------------------------------------------------------+
|
||||
// | ____ _ _ __ __ _ __ |
|
||||
// | / ___| |__ ___ ___| | __ | \/ | |/ / |
|
||||
// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / |
|
||||
// | | |___| | | | __/ (__| < | | | | . \ |
|
||||
// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ |
|
||||
// | |
|
||||
// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de |
|
||||
// +------------------------------------------------------------------+
|
||||
//
|
||||
// This file is part of Check_MK.
|
||||
// The official homepage is at http://mathias-kettner.de/check_mk.
|
||||
//
|
||||
// check_mk is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation in version 2. check_mk is distributed
|
||||
// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with-
|
||||
// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
// PARTICULAR PURPOSE. See the GNU General Public License for more de-
|
||||
// tails. You should have received a copy of the GNU General Public
|
||||
// License along with GNU Make; see the file COPYING. If not, write
|
||||
// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
// Boston, MA 02110-1301 USA.
|
||||
|
||||
#ifndef DynamicLogwatchFileColumn_h
|
||||
#define DynamicLogwatchFileColumn_h
|
||||
|
||||
#include "config.h" // IWYU pragma: keep
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include "DynamicColumn.h"
|
||||
class Column;
|
||||
class Logger;
|
||||
class MonitoringCore;
|
||||
|
||||
class DynamicLogwatchFileColumn : public DynamicColumn {
|
||||
public:
|
||||
DynamicLogwatchFileColumn(const std::string &name,
|
||||
const std::string &description, Logger *logger,
|
||||
MonitoringCore *mc, int indirect_offset,
|
||||
int extra_offset, int extra_extra_offset)
|
||||
: DynamicColumn(name, description, logger, indirect_offset,
|
||||
extra_offset, extra_extra_offset)
|
||||
, _mc(mc) {}
|
||||
~DynamicLogwatchFileColumn() override = default;
|
||||
std::unique_ptr<Column> createColumn(const std::string &name,
|
||||
const std::string &arguments) override;
|
||||
|
||||
private:
|
||||
MonitoringCore *_mc;
|
||||
};
|
||||
|
||||
#endif // DynamicLogwatchFileColumn_h
|
||||
89
src/EventConsoleConnection.cc
Normal file
89
src/EventConsoleConnection.cc
Normal file
@@ -0,0 +1,89 @@
|
||||
// +------------------------------------------------------------------+
|
||||
// | ____ _ _ __ __ _ __ |
|
||||
// | / ___| |__ ___ ___| | __ | \/ | |/ / |
|
||||
// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / |
|
||||
// | | |___| | | | __/ (__| < | | | | . \ |
|
||||
// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ |
|
||||
// | |
|
||||
// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de |
|
||||
// +------------------------------------------------------------------+
|
||||
//
|
||||
// This file is part of Check_MK.
|
||||
// The official homepage is at http://mathias-kettner.de/check_mk.
|
||||
//
|
||||
// check_mk is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation in version 2. check_mk is distributed
|
||||
// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with-
|
||||
// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
// PARTICULAR PURPOSE. See the GNU General Public License for more de-
|
||||
// tails. You should have received a copy of the GNU General Public
|
||||
// License along with GNU Make; see the file COPYING. If not, write
|
||||
// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
// Boston, MA 02110-1301 USA.
|
||||
|
||||
#include "EventConsoleConnection.h"
|
||||
#include <boost/asio/basic_socket_streambuf.hpp>
|
||||
#include <boost/asio/socket_base.hpp>
|
||||
#include <boost/system/error_code.hpp>
|
||||
#include <boost/system/system_error.hpp>
|
||||
#include <chrono>
|
||||
#include <ostream>
|
||||
#include <thread>
|
||||
#include <utility>
|
||||
#include "Logger.h"
|
||||
|
||||
EventConsoleConnection::EventConsoleConnection(Logger *logger, std::string path)
|
||||
: _logger(logger), _path(std::move(path)) {}
|
||||
|
||||
EventConsoleConnection::~EventConsoleConnection() {
|
||||
Debug(_logger) << prefix("closing connection");
|
||||
}
|
||||
|
||||
void EventConsoleConnection::run() {
|
||||
boost::asio::local::stream_protocol::endpoint ep(_path);
|
||||
// Attention, tricky timing-dependent stuff ahead: When we connect very
|
||||
// rapidly, a no_buffer_space (= ENOBUFS) error can happen. This is probably
|
||||
// caused by some internal Boost Kung Fu, remapping EGAIN to ENOBUFS, and
|
||||
// looks like a bug in Boost, but that's a bit unclear. So instead of
|
||||
// relying on Boost to retry under these circumstances, we do it ourselves.
|
||||
boost::asio::local::stream_protocol::iostream stream;
|
||||
while (true) {
|
||||
stream.connect(ep);
|
||||
if (stream.error() !=
|
||||
boost::system::error_code(boost::system::errc::no_buffer_space,
|
||||
boost::system::system_category())) {
|
||||
break;
|
||||
}
|
||||
Debug(_logger) << "retrying to connect";
|
||||
stream.clear();
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(1));
|
||||
}
|
||||
|
||||
check(stream, "connect");
|
||||
Debug(_logger) << prefix("successfully connected");
|
||||
|
||||
stream << std::nounitbuf;
|
||||
sendRequest(stream);
|
||||
stream.flush();
|
||||
stream.rdbuf()->shutdown(boost::asio::socket_base::shutdown_send);
|
||||
check(stream, "send request");
|
||||
|
||||
receiveReply(stream);
|
||||
check(stream, "receive reply");
|
||||
}
|
||||
|
||||
std::string EventConsoleConnection::prefix(const std::string &message) const {
|
||||
return "[mkeventd at " + _path + "] " + message;
|
||||
}
|
||||
|
||||
void EventConsoleConnection::check(
|
||||
boost::asio::local::stream_protocol::iostream &stream,
|
||||
const std::string &what) const {
|
||||
if (!stream && !stream.eof()) {
|
||||
// NOTE: Boost's system_error has a mutable string member for lazy
|
||||
// construction of what(), this screws up cert-err60-cpp. :-P
|
||||
throw boost::system::system_error(stream.error(),
|
||||
prefix("cannot " + what)); // NOLINT
|
||||
}
|
||||
}
|
||||
52
src/EventConsoleConnection.h
Normal file
52
src/EventConsoleConnection.h
Normal file
@@ -0,0 +1,52 @@
|
||||
// +------------------------------------------------------------------+
|
||||
// | ____ _ _ __ __ _ __ |
|
||||
// | / ___| |__ ___ ___| | __ | \/ | |/ / |
|
||||
// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / |
|
||||
// | | |___| | | | __/ (__| < | | | | . \ |
|
||||
// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ |
|
||||
// | |
|
||||
// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de |
|
||||
// +------------------------------------------------------------------+
|
||||
//
|
||||
// This file is part of Check_MK.
|
||||
// The official homepage is at http://mathias-kettner.de/check_mk.
|
||||
//
|
||||
// check_mk is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation in version 2. check_mk is distributed
|
||||
// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with-
|
||||
// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
// PARTICULAR PURPOSE. See the GNU General Public License for more de-
|
||||
// tails. You should have received a copy of the GNU General Public
|
||||
// License along with GNU Make; see the file COPYING. If not, write
|
||||
// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
// Boston, MA 02110-1301 USA.
|
||||
|
||||
#ifndef EventConsoleConnection_h
|
||||
#define EventConsoleConnection_h
|
||||
|
||||
#include "config.h" // IWYU pragma: keep
|
||||
#include <boost/asio/local/stream_protocol.hpp>
|
||||
#include <iosfwd>
|
||||
#include <string>
|
||||
class Logger;
|
||||
|
||||
class EventConsoleConnection {
|
||||
public:
|
||||
EventConsoleConnection(Logger *logger, std::string path);
|
||||
~EventConsoleConnection();
|
||||
void run();
|
||||
|
||||
private:
|
||||
virtual void sendRequest(std::ostream &os) = 0;
|
||||
virtual void receiveReply(std::istream &is) = 0;
|
||||
|
||||
[[nodiscard]] std::string prefix(const std::string &message) const;
|
||||
void check(boost::asio::local::stream_protocol::iostream &stream,
|
||||
const std::string &what) const;
|
||||
|
||||
Logger *const _logger;
|
||||
const std::string _path;
|
||||
};
|
||||
|
||||
#endif // EventConsoleConnection_h
|
||||
34
src/FileSystem.h
Normal file
34
src/FileSystem.h
Normal file
@@ -0,0 +1,34 @@
|
||||
// +------------------------------------------------------------------+
|
||||
// | ____ _ _ __ __ _ __ |
|
||||
// | / ___| |__ ___ ___| | __ | \/ | |/ / |
|
||||
// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / |
|
||||
// | | |___| | | | __/ (__| < | | | | . \ |
|
||||
// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ |
|
||||
// | |
|
||||
// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de |
|
||||
// +------------------------------------------------------------------+
|
||||
//
|
||||
// This file is part of Check_MK.
|
||||
// The official homepage is at http://mathias-kettner.de/check_mk.
|
||||
//
|
||||
// check_mk is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation in version 2. check_mk is distributed
|
||||
// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with-
|
||||
// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
// PARTICULAR PURPOSE. See the GNU General Public License for more de-
|
||||
// tails. You should have received a copy of the GNU General Public
|
||||
// License along with GNU Make; see the file COPYING. If not, write
|
||||
// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
// Boston, MA 02110-1301 USA.
|
||||
|
||||
#ifndef FileSystem_h
|
||||
#define FileSystem_h
|
||||
|
||||
// IWYU pragma: begin_exports
|
||||
#include <experimental/filesystem>
|
||||
// IWYU pragma: end_exports
|
||||
|
||||
namespace fs = std::experimental::filesystem;
|
||||
|
||||
#endif // FileSystem_h
|
||||
50
src/Filter.cc
Normal file
50
src/Filter.cc
Normal file
@@ -0,0 +1,50 @@
|
||||
// +------------------------------------------------------------------+
|
||||
// | ____ _ _ __ __ _ __ |
|
||||
// | / ___| |__ ___ ___| | __ | \/ | |/ / |
|
||||
// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / |
|
||||
// | | |___| | | | __/ (__| < | | | | . \ |
|
||||
// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ |
|
||||
// | |
|
||||
// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de |
|
||||
// +------------------------------------------------------------------+
|
||||
//
|
||||
// This file is part of Check_MK.
|
||||
// The official homepage is at http://mathias-kettner.de/check_mk.
|
||||
//
|
||||
// check_mk is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation in version 2. check_mk is distributed
|
||||
// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with-
|
||||
// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
// PARTICULAR PURPOSE. See the GNU General Public License for more de-
|
||||
// tails. You should have received a copy of the GNU General Public
|
||||
// License along with GNU Make; see the file COPYING. If not, write
|
||||
// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
// Boston, MA 02110-1301 USA.
|
||||
|
||||
#include "Filter.h"
|
||||
|
||||
Filter::~Filter() = default;
|
||||
|
||||
std::optional<std::string> Filter::stringValueRestrictionFor(
|
||||
const std::string& /* column_name */) const {
|
||||
return {};
|
||||
}
|
||||
|
||||
std::optional<int32_t> Filter::greatestLowerBoundFor(
|
||||
const std::string& /* column_name */,
|
||||
std::chrono::seconds /* timezone_offset */) const {
|
||||
return {};
|
||||
}
|
||||
|
||||
std::optional<int32_t> Filter::leastUpperBoundFor(
|
||||
const std::string& /* column_name */,
|
||||
std::chrono::seconds /* timezone_offset */) const {
|
||||
return {};
|
||||
}
|
||||
|
||||
std::optional<std::bitset<32>> Filter::valueSetLeastUpperBoundFor(
|
||||
const std::string& /* column_name */,
|
||||
std::chrono::seconds /* timezone_offset */) const {
|
||||
return {};
|
||||
}
|
||||
102
src/Filter.h
Normal file
102
src/Filter.h
Normal file
@@ -0,0 +1,102 @@
|
||||
// +------------------------------------------------------------------+
|
||||
// | ____ _ _ __ __ _ __ |
|
||||
// | / ___| |__ ___ ___| | __ | \/ | |/ / |
|
||||
// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / |
|
||||
// | | |___| | | | __/ (__| < | | | | . \ |
|
||||
// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ |
|
||||
// | |
|
||||
// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de |
|
||||
// +------------------------------------------------------------------+
|
||||
//
|
||||
// This file is part of Check_MK.
|
||||
// The official homepage is at http://mathias-kettner.de/check_mk.
|
||||
//
|
||||
// check_mk is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation in version 2. check_mk is distributed
|
||||
// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with-
|
||||
// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
// PARTICULAR PURPOSE. See the GNU General Public License for more de-
|
||||
// tails. You should have received a copy of the GNU General Public
|
||||
// License along with GNU Make; see the file COPYING. If not, write
|
||||
// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
// Boston, MA 02110-1301 USA.
|
||||
|
||||
#ifndef Filter_h
|
||||
#define Filter_h
|
||||
|
||||
#include "config.h" // IWYU pragma: keep
|
||||
#include <bitset>
|
||||
#include <chrono>
|
||||
#include <cstdint>
|
||||
#include <functional>
|
||||
#include <iosfwd>
|
||||
#include <memory>
|
||||
#include <optional>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include "contact_fwd.h"
|
||||
class Column;
|
||||
class Filter;
|
||||
class Row;
|
||||
|
||||
using Filters = std::vector<std::unique_ptr<Filter>>;
|
||||
|
||||
/// A propositional formula over column value relations, kept in negation normal
|
||||
/// form.
|
||||
class Filter {
|
||||
public:
|
||||
enum Kind { row, stats, wait_condition };
|
||||
|
||||
explicit Filter(Kind kind) : _kind(kind) {}
|
||||
virtual ~Filter();
|
||||
[[nodiscard]] Kind kind() const { return _kind; }
|
||||
virtual bool accepts(Row row, const contact *auth_user,
|
||||
std::chrono::seconds timezone_offset) const = 0;
|
||||
virtual std::unique_ptr<Filter> partialFilter(
|
||||
std::function<bool(const Column &)> predicate) const = 0;
|
||||
|
||||
// TODO(sp) We might be able to unify all the methods below if we make the
|
||||
// underlying lattice structure explicit, i.e. provide a set type and
|
||||
// corresponding meet/join operations. Perhaps we can even get rid of the
|
||||
// std::optional by making the lattice bounded, i.e. by providing bottom/top
|
||||
// values.
|
||||
[[nodiscard]] virtual std::optional<std::string> stringValueRestrictionFor(
|
||||
const std::string &column_name) const;
|
||||
[[nodiscard]] virtual std::optional<int32_t> greatestLowerBoundFor(
|
||||
const std::string &column_name,
|
||||
std::chrono::seconds timezone_offset) const;
|
||||
[[nodiscard]] virtual std::optional<int32_t> leastUpperBoundFor(
|
||||
const std::string &column_name,
|
||||
std::chrono::seconds timezone_offset) const;
|
||||
[[nodiscard]] virtual std::optional<std::bitset<32>>
|
||||
valueSetLeastUpperBoundFor(const std::string &column_name,
|
||||
std::chrono::seconds timezone_offset) const;
|
||||
|
||||
[[nodiscard]] virtual std::unique_ptr<Filter> copy() const = 0;
|
||||
[[nodiscard]] virtual std::unique_ptr<Filter> negate() const = 0;
|
||||
|
||||
/// Checks for a *syntactic* tautology.
|
||||
[[nodiscard]] virtual bool is_tautology() const = 0;
|
||||
|
||||
/// Checks for a *syntactic* contradiction.
|
||||
[[nodiscard]] virtual bool is_contradiction() const = 0;
|
||||
|
||||
/// Combining the returned filters with *or* yields a filter equivalent to
|
||||
/// the current one.
|
||||
[[nodiscard]] virtual Filters disjuncts() const = 0;
|
||||
|
||||
/// Combining the returned filters with *and* yields a filter equivalent to
|
||||
/// the current one.
|
||||
[[nodiscard]] virtual Filters conjuncts() const = 0;
|
||||
|
||||
friend std::ostream &operator<<(std::ostream &os, const Filter &filter) {
|
||||
return filter.print(os);
|
||||
}
|
||||
|
||||
private:
|
||||
const Kind _kind;
|
||||
virtual std::ostream &print(std::ostream &os) const = 0;
|
||||
};
|
||||
|
||||
#endif // Filter_h
|
||||
46
src/FixedIntColumn.h
Normal file
46
src/FixedIntColumn.h
Normal file
@@ -0,0 +1,46 @@
|
||||
// +------------------------------------------------------------------+
|
||||
// | ____ _ _ __ __ _ __ |
|
||||
// | / ___| |__ ___ ___| | __ | \/ | |/ / |
|
||||
// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / |
|
||||
// | | |___| | | | __/ (__| < | | | | . \ |
|
||||
// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ |
|
||||
// | |
|
||||
// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de |
|
||||
// +------------------------------------------------------------------+
|
||||
//
|
||||
// This file is part of Check_MK.
|
||||
// The official homepage is at http://mathias-kettner.de/check_mk.
|
||||
//
|
||||
// check_mk is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation in version 2. check_mk is distributed
|
||||
// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with-
|
||||
// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
// PARTICULAR PURPOSE. See the GNU General Public License for more de-
|
||||
// tails. You should have received a copy of the GNU General Public
|
||||
// License along with GNU Make; see the file COPYING. If not, write
|
||||
// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
// Boston, MA 02110-1301 USA.
|
||||
|
||||
#ifndef FixedIntColumn_h
|
||||
#define FixedIntColumn_h
|
||||
|
||||
#include "config.h" // IWYU pragma: keep
|
||||
#include "IntColumn.h"
|
||||
|
||||
class FixedIntColumn : public IntColumn {
|
||||
public:
|
||||
FixedIntColumn(const std::string& name, const std::string& description,
|
||||
int value)
|
||||
: IntColumn(name, description, -1, -1, -1, 0), _value(value) {}
|
||||
|
||||
int32_t getValue(Row /* row */,
|
||||
const contact* /* auth_user */) const override {
|
||||
return _value;
|
||||
}
|
||||
|
||||
private:
|
||||
const int32_t _value;
|
||||
};
|
||||
|
||||
#endif // FixedIntColumn_h
|
||||
60
src/HostContactsColumn.cc
Normal file
60
src/HostContactsColumn.cc
Normal file
@@ -0,0 +1,60 @@
|
||||
// +------------------------------------------------------------------+
|
||||
// | ____ _ _ __ __ _ __ |
|
||||
// | / ___| |__ ___ ___| | __ | \/ | |/ / |
|
||||
// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / |
|
||||
// | | |___| | | | __/ (__| < | | | | . \ |
|
||||
// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ |
|
||||
// | |
|
||||
// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de |
|
||||
// +------------------------------------------------------------------+
|
||||
//
|
||||
// This file is part of Check_MK.
|
||||
// The official homepage is at http://mathias-kettner.de/check_mk.
|
||||
//
|
||||
// check_mk is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation in version 2. check_mk is distributed
|
||||
// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with-
|
||||
// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
// PARTICULAR PURPOSE. See the GNU General Public License for more de-
|
||||
// tails. You should have received a copy of the GNU General Public
|
||||
// License along with GNU Make; see the file COPYING. If not, write
|
||||
// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
// Boston, MA 02110-1301 USA.
|
||||
|
||||
#include "HostContactsColumn.h"
|
||||
#include "Row.h"
|
||||
|
||||
#ifdef CMC
|
||||
#include "ContactList.h"
|
||||
#include "Object.h"
|
||||
#include "cmc.h"
|
||||
#else
|
||||
#include <unordered_set>
|
||||
#include "nagios.h"
|
||||
#endif
|
||||
|
||||
std::vector<std::string> HostContactsColumn::getValue(
|
||||
Row row, const contact* /*auth_user*/,
|
||||
std::chrono::seconds /*timezone_offset*/) const {
|
||||
#ifdef CMC
|
||||
if (auto object = columnData<Object>(row)) {
|
||||
return object->_contact_list->contactNames();
|
||||
}
|
||||
return {};
|
||||
#else
|
||||
std::unordered_set<std::string> names;
|
||||
if (auto hst = columnData<host>(row)) {
|
||||
for (auto cm = hst->contacts; cm != nullptr; cm = cm->next) {
|
||||
names.insert(cm->contact_ptr->name);
|
||||
}
|
||||
for (auto cgm = hst->contact_groups; cgm != nullptr; cgm = cgm->next) {
|
||||
for (auto cm = cgm->group_ptr->members; cm != nullptr;
|
||||
cm = cm->next) {
|
||||
names.insert(cm->contact_ptr->name);
|
||||
}
|
||||
}
|
||||
}
|
||||
return std::vector<std::string>(names.begin(), names.end());
|
||||
#endif
|
||||
}
|
||||
49
src/HostContactsColumn.h
Normal file
49
src/HostContactsColumn.h
Normal file
@@ -0,0 +1,49 @@
|
||||
// +------------------------------------------------------------------+
|
||||
// | ____ _ _ __ __ _ __ |
|
||||
// | / ___| |__ ___ ___| | __ | \/ | |/ / |
|
||||
// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / |
|
||||
// | | |___| | | | __/ (__| < | | | | . \ |
|
||||
// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ |
|
||||
// | |
|
||||
// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de |
|
||||
// +------------------------------------------------------------------+
|
||||
//
|
||||
// This file is part of Check_MK.
|
||||
// The official homepage is at http://mathias-kettner.de/check_mk.
|
||||
//
|
||||
// check_mk is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation in version 2. check_mk is distributed
|
||||
// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with-
|
||||
// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
// PARTICULAR PURPOSE. See the GNU General Public License for more de-
|
||||
// tails. You should have received a copy of the GNU General Public
|
||||
// License along with GNU Make; see the file COPYING. If not, write
|
||||
// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
// Boston, MA 02110-1301 USA.
|
||||
|
||||
#ifndef HostContactsColumn_h
|
||||
#define HostContactsColumn_h
|
||||
|
||||
#include "config.h" // IWYU pragma: keep
|
||||
#include <chrono>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include "ListColumn.h"
|
||||
#include "contact_fwd.h"
|
||||
class Row;
|
||||
|
||||
class HostContactsColumn : public ListColumn {
|
||||
public:
|
||||
HostContactsColumn(const std::string& name, const std::string& description,
|
||||
int indirect_offset, int extra_offset,
|
||||
int extra_extra_offset, int offset)
|
||||
: ListColumn(name, description, indirect_offset, extra_offset,
|
||||
extra_extra_offset, offset) {}
|
||||
|
||||
std::vector<std::string> getValue(
|
||||
Row row, const contact* auth_user,
|
||||
std::chrono::seconds timezone_offset) const override;
|
||||
};
|
||||
|
||||
#endif // HostContactsColumn_h
|
||||
117
src/HostFileColumn.cc
Normal file
117
src/HostFileColumn.cc
Normal file
@@ -0,0 +1,117 @@
|
||||
// +------------------------------------------------------------------+
|
||||
// | ____ _ _ __ __ _ __ |
|
||||
// | / ___| |__ ___ ___| | __ | \/ | |/ / |
|
||||
// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / |
|
||||
// | | |___| | | | __/ (__| < | | | | . \ |
|
||||
// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ |
|
||||
// | |
|
||||
// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de |
|
||||
// +------------------------------------------------------------------+
|
||||
//
|
||||
// This file is part of Check_MK.
|
||||
// The official homepage is at http://mathias-kettner.de/check_mk.
|
||||
//
|
||||
// check_mk is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation in version 2. check_mk is distributed
|
||||
// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with-
|
||||
// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
// PARTICULAR PURPOSE. See the GNU General Public License for more de-
|
||||
// tails. You should have received a copy of the GNU General Public
|
||||
// License along with GNU Make; see the file COPYING. If not, write
|
||||
// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
// Boston, MA 02110-1301 USA.
|
||||
|
||||
#include "HostFileColumn.h"
|
||||
#include <fcntl.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
#include <cerrno>
|
||||
#include <cstring>
|
||||
#include <ostream>
|
||||
#include <utility>
|
||||
#include "Logger.h"
|
||||
#include "Row.h"
|
||||
|
||||
#ifdef CMC
|
||||
#include "Host.h"
|
||||
#else
|
||||
#include "nagios.h"
|
||||
#endif
|
||||
|
||||
HostFileColumn::HostFileColumn(const std::string& name,
|
||||
const std::string& description,
|
||||
int indirect_offset, int extra_offset,
|
||||
int extra_extra_offset, int offset,
|
||||
std::string base_dir, std::string suffix)
|
||||
: BlobColumn(name, description, indirect_offset, extra_offset,
|
||||
extra_extra_offset, offset)
|
||||
, _base_dir(std::move(base_dir))
|
||||
, _suffix(std::move(suffix)) {}
|
||||
|
||||
std::unique_ptr<std::vector<char>> HostFileColumn::getValue(Row row) const {
|
||||
if (_base_dir.empty()) {
|
||||
return nullptr; // Path is not configured
|
||||
}
|
||||
|
||||
#ifdef CMC
|
||||
auto hst = columnData<Host>(row);
|
||||
if (hst == nullptr) {
|
||||
return nullptr;
|
||||
}
|
||||
std::string host_name = hst->name();
|
||||
#else
|
||||
auto hst = columnData<host>(row);
|
||||
if (hst == nullptr) {
|
||||
return nullptr;
|
||||
}
|
||||
std::string host_name = hst->name;
|
||||
#endif
|
||||
|
||||
std::string path = _base_dir + "/" + host_name + _suffix;
|
||||
int fd = open(path.c_str(), O_RDONLY);
|
||||
if (fd == -1) {
|
||||
// It is OK when inventory/logwatch files do not exist.
|
||||
if (errno != ENOENT) {
|
||||
generic_error ge("cannot open " + path);
|
||||
Warning(logger()) << ge;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
struct stat st;
|
||||
if (fstat(fd, &st) == -1) {
|
||||
generic_error ge("cannot stat " + path);
|
||||
Warning(logger()) << ge;
|
||||
return nullptr;
|
||||
}
|
||||
if (!S_ISREG(st.st_mode)) {
|
||||
Warning(logger()) << path << " is not a regular file";
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
size_t bytes_to_read = st.st_size;
|
||||
auto result = std::make_unique<std::vector<char>>(bytes_to_read);
|
||||
char* buffer = &(*result)[0];
|
||||
while (bytes_to_read > 0) {
|
||||
ssize_t bytes_read = read(fd, buffer, bytes_to_read);
|
||||
if (bytes_read == -1) {
|
||||
if (errno != EINTR) {
|
||||
generic_error ge("could not read " + path);
|
||||
Warning(logger()) << ge;
|
||||
close(fd);
|
||||
return nullptr;
|
||||
}
|
||||
} else if (bytes_read == 0) {
|
||||
Warning(logger()) << "premature EOF reading " << path;
|
||||
close(fd);
|
||||
return nullptr;
|
||||
} else {
|
||||
bytes_to_read -= bytes_read;
|
||||
buffer += bytes_read;
|
||||
}
|
||||
}
|
||||
|
||||
close(fd);
|
||||
return result;
|
||||
}
|
||||
50
src/HostFileColumn.h
Normal file
50
src/HostFileColumn.h
Normal file
@@ -0,0 +1,50 @@
|
||||
// +------------------------------------------------------------------+
|
||||
// | ____ _ _ __ __ _ __ |
|
||||
// | / ___| |__ ___ ___| | __ | \/ | |/ / |
|
||||
// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / |
|
||||
// | | |___| | | | __/ (__| < | | | | . \ |
|
||||
// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ |
|
||||
// | |
|
||||
// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de |
|
||||
// +------------------------------------------------------------------+
|
||||
//
|
||||
// This file is part of Check_MK.
|
||||
// The official homepage is at http://mathias-kettner.de/check_mk.
|
||||
//
|
||||
// check_mk is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation in version 2. check_mk is distributed
|
||||
// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with-
|
||||
// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
// PARTICULAR PURPOSE. See the GNU General Public License for more de-
|
||||
// tails. You should have received a copy of the GNU General Public
|
||||
// License along with GNU Make; see the file COPYING. If not, write
|
||||
// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
// Boston, MA 02110-1301 USA.
|
||||
|
||||
#ifndef HostFileColumn_h
|
||||
#define HostFileColumn_h
|
||||
|
||||
#include "config.h" // IWYU pragma: keep
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include "BlobColumn.h"
|
||||
class Row;
|
||||
|
||||
class HostFileColumn : public BlobColumn {
|
||||
public:
|
||||
HostFileColumn(const std::string& name, const std::string& description,
|
||||
int indirect_offset, int extra_offset,
|
||||
int extra_extra_offset, int offset, std::string base_dir,
|
||||
std::string suffix);
|
||||
|
||||
[[nodiscard]] std::unique_ptr<std::vector<char>> getValue(
|
||||
Row row) const override;
|
||||
|
||||
private:
|
||||
std::string _base_dir;
|
||||
std::string _suffix;
|
||||
};
|
||||
|
||||
#endif // HostFileColumn_h
|
||||
60
src/HostGroupsColumn.cc
Normal file
60
src/HostGroupsColumn.cc
Normal file
@@ -0,0 +1,60 @@
|
||||
// +------------------------------------------------------------------+
|
||||
// | ____ _ _ __ __ _ __ |
|
||||
// | / ___| |__ ___ ___| | __ | \/ | |/ / |
|
||||
// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / |
|
||||
// | | |___| | | | __/ (__| < | | | | . \ |
|
||||
// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ |
|
||||
// | |
|
||||
// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de |
|
||||
// +------------------------------------------------------------------+
|
||||
//
|
||||
// This file is part of Check_MK.
|
||||
// The official homepage is at http://mathias-kettner.de/check_mk.
|
||||
//
|
||||
// check_mk is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation in version 2. check_mk is distributed
|
||||
// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with-
|
||||
// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
// PARTICULAR PURPOSE. See the GNU General Public License for more de-
|
||||
// tails. You should have received a copy of the GNU General Public
|
||||
// License along with GNU Make; see the file COPYING. If not, write
|
||||
// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
// Boston, MA 02110-1301 USA.
|
||||
|
||||
#include "HostGroupsColumn.h"
|
||||
#include "Row.h"
|
||||
|
||||
#ifdef CMC
|
||||
#include "Object.h"
|
||||
#include "ObjectGroup.h"
|
||||
#include "cmc.h"
|
||||
#else
|
||||
#include "auth.h"
|
||||
#include "nagios.h"
|
||||
#endif
|
||||
|
||||
std::vector<std::string> HostGroupsColumn::getValue(
|
||||
Row row, const contact *auth_user,
|
||||
std::chrono::seconds /*timezone_offset*/) const {
|
||||
std::vector<std::string> group_names;
|
||||
#ifdef CMC
|
||||
if (auto object = columnData<Object>(row)) {
|
||||
for (const auto &og : object->_groups) {
|
||||
if (og->isContactAuthorized(_mc, auth_user)) {
|
||||
group_names.push_back(og->name());
|
||||
}
|
||||
}
|
||||
}
|
||||
#else
|
||||
if (auto p = columnData<objectlist *>(row)) {
|
||||
for (objectlist *list = *p; list != nullptr; list = list->next) {
|
||||
auto hg = static_cast<hostgroup *>(list->object_ptr);
|
||||
if (is_authorized_for_host_group(_mc, hg, auth_user)) {
|
||||
group_names.emplace_back(hg->group_name);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return group_names;
|
||||
}
|
||||
54
src/HostGroupsColumn.h
Normal file
54
src/HostGroupsColumn.h
Normal file
@@ -0,0 +1,54 @@
|
||||
// +------------------------------------------------------------------+
|
||||
// | ____ _ _ __ __ _ __ |
|
||||
// | / ___| |__ ___ ___| | __ | \/ | |/ / |
|
||||
// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / |
|
||||
// | | |___| | | | __/ (__| < | | | | . \ |
|
||||
// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ |
|
||||
// | |
|
||||
// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de |
|
||||
// +------------------------------------------------------------------+
|
||||
//
|
||||
// This file is part of Check_MK.
|
||||
// The official homepage is at http://mathias-kettner.de/check_mk.
|
||||
//
|
||||
// check_mk is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation in version 2. check_mk is distributed
|
||||
// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with-
|
||||
// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
// PARTICULAR PURPOSE. See the GNU General Public License for more de-
|
||||
// tails. You should have received a copy of the GNU General Public
|
||||
// License along with GNU Make; see the file COPYING. If not, write
|
||||
// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
// Boston, MA 02110-1301 USA.
|
||||
|
||||
#ifndef HostGroupsColumn_h
|
||||
#define HostGroupsColumn_h
|
||||
|
||||
#include "config.h" // IWYU pragma: keep
|
||||
#include <chrono>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include "ListColumn.h"
|
||||
#include "contact_fwd.h"
|
||||
class MonitoringCore;
|
||||
class Row;
|
||||
|
||||
class HostGroupsColumn : public ListColumn {
|
||||
public:
|
||||
HostGroupsColumn(const std::string &name, const std::string &description,
|
||||
int indirect_offset, int extra_offset,
|
||||
int extra_extra_offset, int offset, MonitoringCore *mc)
|
||||
: ListColumn(name, description, indirect_offset, extra_offset,
|
||||
extra_extra_offset, offset)
|
||||
, _mc(mc) {}
|
||||
|
||||
std::vector<std::string> getValue(
|
||||
Row row, const contact *auth_user,
|
||||
std::chrono::seconds timezone_offset) const override;
|
||||
|
||||
private:
|
||||
MonitoringCore *const _mc;
|
||||
};
|
||||
|
||||
#endif // HostGroupsColumn_h
|
||||
96
src/HostListColumn.cc
Normal file
96
src/HostListColumn.cc
Normal file
@@ -0,0 +1,96 @@
|
||||
// +------------------------------------------------------------------+
|
||||
// | ____ _ _ __ __ _ __ |
|
||||
// | / ___| |__ ___ ___| | __ | \/ | |/ / |
|
||||
// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / |
|
||||
// | | |___| | | | __/ (__| < | | | | . \ |
|
||||
// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ |
|
||||
// | |
|
||||
// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de |
|
||||
// +------------------------------------------------------------------+
|
||||
//
|
||||
// This file is part of Check_MK.
|
||||
// The official homepage is at http://mathias-kettner.de/check_mk.
|
||||
//
|
||||
// check_mk is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation in version 2. check_mk is distributed
|
||||
// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with-
|
||||
// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
// PARTICULAR PURPOSE. See the GNU General Public License for more de-
|
||||
// tails. You should have received a copy of the GNU General Public
|
||||
// License along with GNU Make; see the file COPYING. If not, write
|
||||
// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
// Boston, MA 02110-1301 USA.
|
||||
|
||||
#include "HostListColumn.h"
|
||||
#include <algorithm>
|
||||
#include <iterator>
|
||||
#include "Renderer.h"
|
||||
#include "Row.h"
|
||||
|
||||
#ifdef CMC
|
||||
#include <unordered_set>
|
||||
#include "Host.h"
|
||||
#include "LogEntry.h"
|
||||
#include "State.h"
|
||||
#include "cmc.h"
|
||||
#else
|
||||
#include "auth.h"
|
||||
#include "nagios.h"
|
||||
#endif
|
||||
|
||||
void HostListColumn::output(Row row, RowRenderer &r, const contact *auth_user,
|
||||
std::chrono::seconds /*timezone_offset*/) const {
|
||||
ListRenderer l(r);
|
||||
for (const auto &member : getMembers(row, auth_user)) {
|
||||
if (_show_state) {
|
||||
SublistRenderer s(l);
|
||||
s.output(member.host_name);
|
||||
s.output(static_cast<int>(member.current_state));
|
||||
s.output(static_cast<int>(member.has_been_checked));
|
||||
} else {
|
||||
l.output(member.host_name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<std::string> HostListColumn::getValue(
|
||||
Row row, const contact *auth_user,
|
||||
std::chrono::seconds /*timezone_offset*/) const {
|
||||
auto members = getMembers(row, auth_user);
|
||||
std::vector<std::string> host_names;
|
||||
std::transform(members.begin(), members.end(),
|
||||
std::back_inserter(host_names),
|
||||
[](const auto &member) { return member.host_name; });
|
||||
return host_names;
|
||||
};
|
||||
|
||||
std::vector<HostListColumn::Member> HostListColumn::getMembers(
|
||||
Row row, const contact *auth_user) const {
|
||||
std::vector<Member> members;
|
||||
#ifdef CMC
|
||||
if (auto p = columnData<std::unordered_set<Host *>>(row)) {
|
||||
for (const auto &hst : *p) {
|
||||
if (auth_user == nullptr || hst->hasContact(_mc, auth_user)) {
|
||||
members.emplace_back(
|
||||
hst->name(),
|
||||
static_cast<HostState>(hst->state()->_current_state),
|
||||
hst->state()->_has_been_checked);
|
||||
}
|
||||
}
|
||||
}
|
||||
#else
|
||||
if (auto p = columnData<hostsmember *>(row)) {
|
||||
for (const hostsmember *mem = *p; mem != nullptr; mem = mem->next) {
|
||||
host *hst = mem->host_ptr;
|
||||
if (auth_user == nullptr ||
|
||||
is_authorized_for(_mc, auth_user, hst, nullptr)) {
|
||||
members.emplace_back(hst->name,
|
||||
static_cast<HostState>(hst->current_state),
|
||||
hst->has_been_checked != 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return members;
|
||||
}
|
||||
76
src/HostListColumn.h
Normal file
76
src/HostListColumn.h
Normal file
@@ -0,0 +1,76 @@
|
||||
// +------------------------------------------------------------------+
|
||||
// | ____ _ _ __ __ _ __ |
|
||||
// | / ___| |__ ___ ___| | __ | \/ | |/ / |
|
||||
// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / |
|
||||
// | | |___| | | | __/ (__| < | | | | . \ |
|
||||
// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ |
|
||||
// | |
|
||||
// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de |
|
||||
// +------------------------------------------------------------------+
|
||||
//
|
||||
// This file is part of Check_MK.
|
||||
// The official homepage is at http://mathias-kettner.de/check_mk.
|
||||
//
|
||||
// check_mk is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation in version 2. check_mk is distributed
|
||||
// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with-
|
||||
// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
// PARTICULAR PURPOSE. See the GNU General Public License for more de-
|
||||
// tails. You should have received a copy of the GNU General Public
|
||||
// License along with GNU Make; see the file COPYING. If not, write
|
||||
// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
// Boston, MA 02110-1301 USA.
|
||||
|
||||
#ifndef HostListColumn_h
|
||||
#define HostListColumn_h
|
||||
|
||||
#include "config.h" // IWYU pragma: keep
|
||||
#include <chrono>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
#include "ListColumn.h"
|
||||
#include "contact_fwd.h"
|
||||
enum class HostState;
|
||||
class MonitoringCore;
|
||||
class Row;
|
||||
class RowRenderer;
|
||||
|
||||
class HostListColumn : public ListColumn {
|
||||
public:
|
||||
HostListColumn(const std::string &name, const std::string &description,
|
||||
int indirect_offset, int extra_offset,
|
||||
int extra_extra_offset, int offset, MonitoringCore *mc,
|
||||
bool show_state)
|
||||
: ListColumn(name, description, indirect_offset, extra_offset,
|
||||
extra_extra_offset, offset)
|
||||
, _mc(mc)
|
||||
, _show_state(show_state) {}
|
||||
|
||||
void output(Row row, RowRenderer &r, const contact *auth_user,
|
||||
std::chrono::seconds /*timezone_offset*/) const override;
|
||||
|
||||
std::vector<std::string> getValue(
|
||||
Row row, const contact *auth_user,
|
||||
std::chrono::seconds timezone_offset) const override;
|
||||
|
||||
private:
|
||||
MonitoringCore *_mc;
|
||||
const bool _show_state;
|
||||
|
||||
struct Member {
|
||||
Member(std::string hn, HostState cs, bool hbc)
|
||||
: host_name(std::move(hn))
|
||||
, current_state(cs)
|
||||
, has_been_checked(hbc) {}
|
||||
|
||||
std::string host_name;
|
||||
HostState current_state;
|
||||
bool has_been_checked;
|
||||
};
|
||||
|
||||
std::vector<Member> getMembers(Row row, const contact *auth_user) const;
|
||||
};
|
||||
|
||||
#endif // HostListColumn_h
|
||||
129
src/HostListStateColumn.cc
Normal file
129
src/HostListStateColumn.cc
Normal file
@@ -0,0 +1,129 @@
|
||||
// +------------------------------------------------------------------+
|
||||
// | ____ _ _ __ __ _ __ |
|
||||
// | / ___| |__ ___ ___| | __ | \/ | |/ / |
|
||||
// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / |
|
||||
// | | |___| | | | __/ (__| < | | | | . \ |
|
||||
// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ |
|
||||
// | |
|
||||
// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de |
|
||||
// +------------------------------------------------------------------+
|
||||
//
|
||||
// This file is part of Check_MK.
|
||||
// The official homepage is at http://mathias-kettner.de/check_mk.
|
||||
//
|
||||
// check_mk is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation in version 2. check_mk is distributed
|
||||
// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with-
|
||||
// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
// PARTICULAR PURPOSE. See the GNU General Public License for more de-
|
||||
// tails. You should have received a copy of the GNU General Public
|
||||
// License along with GNU Make; see the file COPYING. If not, write
|
||||
// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
// Boston, MA 02110-1301 USA.
|
||||
|
||||
#include "HostListStateColumn.h"
|
||||
#include "LogEntry.h"
|
||||
#include "Row.h"
|
||||
|
||||
#ifdef CMC
|
||||
#include <unordered_set>
|
||||
#include "Host.h"
|
||||
#include "State.h"
|
||||
#else
|
||||
#include "auth.h"
|
||||
#endif
|
||||
|
||||
int32_t HostListStateColumn::getValue(Row row, const contact *auth_user) const {
|
||||
int32_t result = 0;
|
||||
#ifdef CMC
|
||||
if (auto p = columnData<std::unordered_set<Host *>>(row)) {
|
||||
for (auto hst : *p) {
|
||||
if (auth_user == nullptr || hst->hasContact(_mc, auth_user)) {
|
||||
update(hst, auth_user, result);
|
||||
}
|
||||
}
|
||||
}
|
||||
#else
|
||||
if (auto p = columnData<hostsmember *>(row)) {
|
||||
for (hostsmember *mem = *p; mem != nullptr; mem = mem->next) {
|
||||
host *hst = mem->host_ptr;
|
||||
if (auth_user == nullptr ||
|
||||
is_authorized_for(_mc, auth_user, hst, nullptr)) {
|
||||
update(hst, auth_user, result);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return result;
|
||||
}
|
||||
|
||||
void HostListStateColumn::update(host *hst, const contact *auth_user,
|
||||
int32_t &result) const {
|
||||
#ifdef CMC
|
||||
ServiceListStateColumn::service_list services = &hst->_services;
|
||||
bool has_been_checked = hst->state()->_has_been_checked;
|
||||
auto current_state = static_cast<int>(hst->state()->_current_state);
|
||||
#else
|
||||
ServiceListStateColumn::service_list services = hst->services;
|
||||
bool has_been_checked = hst->has_been_checked != 0;
|
||||
int current_state = hst->current_state;
|
||||
#endif
|
||||
switch (_logictype) {
|
||||
case Type::num_svc_pending:
|
||||
case Type::num_svc_ok:
|
||||
case Type::num_svc_warn:
|
||||
case Type::num_svc_crit:
|
||||
case Type::num_svc_unknown:
|
||||
case Type::num_svc:
|
||||
result += ServiceListStateColumn::getValueFromServices(
|
||||
_mc, static_cast<ServiceListStateColumn::Type>(_logictype),
|
||||
services, auth_user);
|
||||
break;
|
||||
|
||||
case Type::worst_svc_state: {
|
||||
int state = ServiceListStateColumn::getValueFromServices(
|
||||
_mc, static_cast<ServiceListStateColumn::Type>(_logictype),
|
||||
services, auth_user);
|
||||
if (worse(static_cast<ServiceState>(state),
|
||||
static_cast<ServiceState>(result))) {
|
||||
result = state;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case Type::num_hst_up:
|
||||
case Type::num_hst_down:
|
||||
case Type::num_hst_unreach:
|
||||
if (has_been_checked &&
|
||||
current_state == static_cast<int>(_logictype) -
|
||||
static_cast<int>(Type::num_hst_up)) {
|
||||
result++;
|
||||
}
|
||||
break;
|
||||
|
||||
case Type::num_hst_pending:
|
||||
if (!has_been_checked) {
|
||||
result++;
|
||||
}
|
||||
break;
|
||||
|
||||
case Type::num_hst:
|
||||
result++;
|
||||
break;
|
||||
|
||||
case Type::worst_hst_state:
|
||||
if (worse(static_cast<HostState>(current_state),
|
||||
static_cast<HostState>(result))) {
|
||||
result = current_state;
|
||||
}
|
||||
break;
|
||||
case Type::num_svc_hard_ok:
|
||||
case Type::num_svc_hard_warn:
|
||||
case Type::num_svc_hard_crit:
|
||||
case Type::num_svc_hard_unknown:
|
||||
case Type::worst_svc_hard_state:
|
||||
// TODO(sp) Why are these not handled?
|
||||
break;
|
||||
}
|
||||
}
|
||||
92
src/HostListStateColumn.h
Normal file
92
src/HostListStateColumn.h
Normal file
@@ -0,0 +1,92 @@
|
||||
// +------------------------------------------------------------------+
|
||||
// | ____ _ _ __ __ _ __ |
|
||||
// | / ___| |__ ___ ___| | __ | \/ | |/ / |
|
||||
// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / |
|
||||
// | | |___| | | | __/ (__| < | | | | . \ |
|
||||
// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ |
|
||||
// | |
|
||||
// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de |
|
||||
// +------------------------------------------------------------------+
|
||||
//
|
||||
// This file is part of Check_MK.
|
||||
// The official homepage is at http://mathias-kettner.de/check_mk.
|
||||
//
|
||||
// check_mk is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation in version 2. check_mk is distributed
|
||||
// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with-
|
||||
// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
// PARTICULAR PURPOSE. See the GNU General Public License for more de-
|
||||
// tails. You should have received a copy of the GNU General Public
|
||||
// License along with GNU Make; see the file COPYING. If not, write
|
||||
// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
// Boston, MA 02110-1301 USA.
|
||||
|
||||
#ifndef HostListStateColumn_h
|
||||
#define HostListStateColumn_h
|
||||
|
||||
#include "config.h" // IWYU pragma: keep
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
#include "IntColumn.h"
|
||||
#include "ServiceListStateColumn.h"
|
||||
class MonitoringCore;
|
||||
class Row;
|
||||
|
||||
#ifdef CMC
|
||||
#include "cmc.h"
|
||||
#else
|
||||
#include "nagios.h"
|
||||
#endif
|
||||
|
||||
class HostListStateColumn : public IntColumn {
|
||||
public:
|
||||
// TODO(sp) Remove the magic arithmetic
|
||||
enum class Type {
|
||||
num_svc = static_cast<int>(ServiceListStateColumn::Type::num),
|
||||
num_svc_pending =
|
||||
static_cast<int>(ServiceListStateColumn::Type::num_pending),
|
||||
num_svc_ok = static_cast<int>(ServiceListStateColumn::Type::num_ok),
|
||||
num_svc_warn = static_cast<int>(ServiceListStateColumn::Type::num_warn),
|
||||
num_svc_crit = static_cast<int>(ServiceListStateColumn::Type::num_crit),
|
||||
num_svc_unknown =
|
||||
static_cast<int>(ServiceListStateColumn::Type::num_unknown),
|
||||
worst_svc_state =
|
||||
static_cast<int>(ServiceListStateColumn::Type::worst_state),
|
||||
num_svc_hard_ok =
|
||||
static_cast<int>(ServiceListStateColumn::Type::num_hard_ok),
|
||||
num_svc_hard_warn =
|
||||
static_cast<int>(ServiceListStateColumn::Type::num_hard_warn),
|
||||
num_svc_hard_crit =
|
||||
static_cast<int>(ServiceListStateColumn::Type::num_hard_crit),
|
||||
num_svc_hard_unknown =
|
||||
static_cast<int>(ServiceListStateColumn::Type::num_hard_unknown),
|
||||
worst_svc_hard_state =
|
||||
static_cast<int>(ServiceListStateColumn::Type::worst_hard_state),
|
||||
num_hst_up = 10,
|
||||
num_hst_down = 11,
|
||||
num_hst_unreach = 12,
|
||||
num_hst_pending = 13,
|
||||
num_hst = -11,
|
||||
worst_hst_state = -12,
|
||||
};
|
||||
|
||||
HostListStateColumn(const std::string &name, const std::string &description,
|
||||
int indirect_offset, int extra_offset,
|
||||
int extra_extra_offset, int offset, MonitoringCore *mc,
|
||||
Type logictype)
|
||||
: IntColumn(name, description, indirect_offset, extra_offset,
|
||||
extra_extra_offset, offset)
|
||||
, _mc(mc)
|
||||
, _logictype(logictype) {}
|
||||
|
||||
int32_t getValue(Row row, const contact *auth_user) const override;
|
||||
|
||||
private:
|
||||
MonitoringCore *_mc;
|
||||
const Type _logictype;
|
||||
|
||||
void update(host *hst, const contact *auth_user, int32_t &result) const;
|
||||
};
|
||||
|
||||
#endif // HostListStateColumn_h
|
||||
94
src/HostServiceState.cc
Normal file
94
src/HostServiceState.cc
Normal file
@@ -0,0 +1,94 @@
|
||||
// +------------------------------------------------------------------+
|
||||
// | ____ _ _ __ __ _ __ |
|
||||
// | / ___| |__ ___ ___| | __ | \/ | |/ / |
|
||||
// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / |
|
||||
// | | |___| | | | __/ (__| < | | | | . \ |
|
||||
// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ |
|
||||
// | |
|
||||
// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de |
|
||||
// +------------------------------------------------------------------+
|
||||
//
|
||||
// This file is part of Check_MK.
|
||||
// The official homepage is at http://mathias-kettner.de/check_mk.
|
||||
//
|
||||
// check_mk is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation in version 2. check_mk is distributed
|
||||
// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with-
|
||||
// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
// PARTICULAR PURPOSE. See the GNU General Public License for more de-
|
||||
// tails. You should have received a copy of the GNU General Public
|
||||
// License along with GNU Make; see the file COPYING. If not, write
|
||||
// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
// Boston, MA 02110-1301 USA.
|
||||
|
||||
#include "HostServiceState.h"
|
||||
|
||||
HostServiceState::HostServiceState()
|
||||
: _is_host(false)
|
||||
, _time(0)
|
||||
, _lineno(0)
|
||||
, _from(0)
|
||||
, _until(0)
|
||||
, _duration(0)
|
||||
, _duration_part(0)
|
||||
, _duration_state_UNMONITORED(0)
|
||||
, _duration_part_UNMONITORED(0)
|
||||
, _duration_state_OK(0)
|
||||
, _duration_part_OK(0)
|
||||
, _duration_state_WARNING(0)
|
||||
, _duration_part_WARNING(0)
|
||||
, _duration_state_CRITICAL(0)
|
||||
, _duration_part_CRITICAL(0)
|
||||
, _duration_state_UNKNOWN(0)
|
||||
, _duration_part_UNKNOWN(0)
|
||||
, _host_down(0)
|
||||
, _state(0)
|
||||
, _in_notification_period(0)
|
||||
, _in_service_period(0)
|
||||
, _in_downtime(0)
|
||||
, _in_host_downtime(0)
|
||||
, _is_flapping(0)
|
||||
, _may_no_longer_exist(false)
|
||||
, _has_vanished(false)
|
||||
, _last_known_time(0)
|
||||
, _host(nullptr)
|
||||
, _service(nullptr) {}
|
||||
|
||||
#ifdef CMC
|
||||
void HostServiceState::computePerStateDurations() {
|
||||
_duration_state_UNMONITORED = 0;
|
||||
_duration_part_UNMONITORED = 0;
|
||||
_duration_state_OK = 0;
|
||||
_duration_part_OK = 0;
|
||||
_duration_state_WARNING = 0;
|
||||
_duration_part_WARNING = 0;
|
||||
_duration_state_CRITICAL = 0;
|
||||
_duration_part_CRITICAL = 0;
|
||||
_duration_state_UNKNOWN = 0;
|
||||
_duration_part_UNKNOWN = 0;
|
||||
|
||||
switch (_state) {
|
||||
case -1:
|
||||
_duration_state_UNMONITORED = _duration;
|
||||
_duration_part_UNMONITORED = _duration_part;
|
||||
break;
|
||||
case 0:
|
||||
_duration_state_OK = _duration;
|
||||
_duration_part_OK = _duration_part;
|
||||
break;
|
||||
case 1:
|
||||
_duration_state_WARNING = _duration;
|
||||
_duration_part_WARNING = _duration_part;
|
||||
break;
|
||||
case 2:
|
||||
_duration_state_CRITICAL = _duration;
|
||||
_duration_part_CRITICAL = _duration_part;
|
||||
break;
|
||||
case 3:
|
||||
_duration_state_UNKNOWN = _duration;
|
||||
_duration_part_UNKNOWN = _duration_part;
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
107
src/HostServiceState.h
Normal file
107
src/HostServiceState.h
Normal file
@@ -0,0 +1,107 @@
|
||||
// +------------------------------------------------------------------+
|
||||
// | ____ _ _ __ __ _ __ |
|
||||
// | / ___| |__ ___ ___| | __ | \/ | |/ / |
|
||||
// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / |
|
||||
// | | |___| | | | __/ (__| < | | | | . \ |
|
||||
// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ |
|
||||
// | |
|
||||
// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de |
|
||||
// +------------------------------------------------------------------+
|
||||
//
|
||||
// This file is part of Check_MK.
|
||||
// The official homepage is at http://mathias-kettner.de/check_mk.
|
||||
//
|
||||
// check_mk is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation in version 2. check_mk is distributed
|
||||
// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with-
|
||||
// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
// PARTICULAR PURPOSE. See the GNU General Public License for more de-
|
||||
// tails. You should have received a copy of the GNU General Public
|
||||
// License along with GNU Make; see the file COPYING. If not, write
|
||||
// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
// Boston, MA 02110-1301 USA.
|
||||
|
||||
#ifndef HostServiceState_h
|
||||
#define HostServiceState_h
|
||||
|
||||
#include "config.h" // IWYU pragma: keep
|
||||
#include <cstdint>
|
||||
#include <ctime>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
class HostServiceState;
|
||||
|
||||
// for host/service, ugly...
|
||||
#ifdef CMC
|
||||
#include "cmc.h"
|
||||
#else
|
||||
#include "nagios.h"
|
||||
#endif
|
||||
|
||||
using HostServices = std::vector<HostServiceState *>;
|
||||
|
||||
using HostServiceKey = void *;
|
||||
|
||||
class HostServiceState {
|
||||
public:
|
||||
bool _is_host;
|
||||
time_t _time;
|
||||
int32_t _lineno;
|
||||
time_t _from;
|
||||
time_t _until;
|
||||
|
||||
time_t _duration;
|
||||
double _duration_part;
|
||||
|
||||
time_t _duration_state_UNMONITORED;
|
||||
double _duration_part_UNMONITORED;
|
||||
|
||||
time_t _duration_state_OK;
|
||||
double _duration_part_OK;
|
||||
|
||||
time_t _duration_state_WARNING;
|
||||
double _duration_part_WARNING;
|
||||
|
||||
time_t _duration_state_CRITICAL;
|
||||
double _duration_part_CRITICAL;
|
||||
|
||||
time_t _duration_state_UNKNOWN;
|
||||
double _duration_part_UNKNOWN;
|
||||
|
||||
// State information
|
||||
int _host_down; // used if service
|
||||
int _state; // -1/0/1/2/3
|
||||
int _in_notification_period;
|
||||
int _in_service_period;
|
||||
int _in_downtime;
|
||||
int _in_host_downtime;
|
||||
int _is_flapping;
|
||||
|
||||
// Service information
|
||||
HostServices _services;
|
||||
|
||||
// Absent state handling
|
||||
bool _may_no_longer_exist;
|
||||
bool _has_vanished;
|
||||
time_t _last_known_time;
|
||||
|
||||
std::string _debug_info;
|
||||
std::string _log_output;
|
||||
|
||||
// maybe "": -> no period known, we assume "always"
|
||||
std::string _notification_period;
|
||||
// maybe "": -> no period known, we assume "always"
|
||||
std::string _service_period;
|
||||
host *_host;
|
||||
service *_service;
|
||||
std::string _host_name; // Fallback if host no longer exists
|
||||
std::string _service_description; // Fallback if service no longer exists
|
||||
|
||||
HostServiceState();
|
||||
#ifdef CMC
|
||||
void computePerStateDurations();
|
||||
#endif
|
||||
};
|
||||
|
||||
#endif // HostServiceState_h
|
||||
133
src/HostSpecialDoubleColumn.cc
Normal file
133
src/HostSpecialDoubleColumn.cc
Normal file
@@ -0,0 +1,133 @@
|
||||
// +------------------------------------------------------------------+
|
||||
// | ____ _ _ __ __ _ __ |
|
||||
// | / ___| |__ ___ ___| | __ | \/ | |/ / |
|
||||
// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / |
|
||||
// | | |___| | | | __/ (__| < | | | | . \ |
|
||||
// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ |
|
||||
// | |
|
||||
// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de |
|
||||
// +------------------------------------------------------------------+
|
||||
//
|
||||
// This file is part of Check_MK.
|
||||
// The official homepage is at http://mathias-kettner.de/check_mk.
|
||||
//
|
||||
// check_mk is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation in version 2. check_mk is distributed
|
||||
// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with-
|
||||
// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
// PARTICULAR PURPOSE. See the GNU General Public License for more de-
|
||||
// tails. You should have received a copy of the GNU General Public
|
||||
// License along with GNU Make; see the file COPYING. If not, write
|
||||
// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
// Boston, MA 02110-1301 USA.
|
||||
|
||||
#include "HostSpecialDoubleColumn.h"
|
||||
#include "Row.h"
|
||||
|
||||
#ifdef CMC
|
||||
#include <chrono>
|
||||
#include "Object.h"
|
||||
#include "State.h"
|
||||
#include "Timeperiod.h"
|
||||
#else
|
||||
#include <ctime>
|
||||
#include "nagios.h"
|
||||
#endif
|
||||
|
||||
double HostSpecialDoubleColumn::getValue(Row row) const {
|
||||
#ifdef CMC
|
||||
if (auto object = columnData<Object>(row)) {
|
||||
switch (_type) {
|
||||
case Type::staleness:
|
||||
return staleness(object);
|
||||
}
|
||||
}
|
||||
#else
|
||||
if (auto hst = columnData<host>(row)) {
|
||||
switch (_type) {
|
||||
case Type::staleness: {
|
||||
extern int interval_length;
|
||||
return static_cast<double>(time(nullptr) - hst->last_check) /
|
||||
((hst->check_interval == 0 ? 1 : hst->check_interval) *
|
||||
interval_length);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CMC
|
||||
// static
|
||||
double HostSpecialDoubleColumn::staleness(const Object *object) {
|
||||
auto state = object->state();
|
||||
std::chrono::system_clock::duration check_result_age;
|
||||
const Timeperiod *check_period = object->_check_period;
|
||||
std::chrono::system_clock::time_point last_period_change =
|
||||
check_period->lastStateChange();
|
||||
std::chrono::system_clock::time_point last_check = state->_last_check;
|
||||
|
||||
// Compute the age of the check result. When the check is currently in its
|
||||
// check period then...
|
||||
auto m_now = std::chrono::system_clock::now();
|
||||
if (check_period->isActive()) {
|
||||
// Has a check happened since the beginning of the current phase? Then
|
||||
// simply compare last check with current time. This should be the 99%
|
||||
// case.
|
||||
if (last_check >= last_period_change) {
|
||||
check_result_age = m_now - last_check;
|
||||
|
||||
} else {
|
||||
// otherwise the active phase has just begun. Take the time since
|
||||
// the beginning of the phase.
|
||||
check_result_age = m_now - last_period_change;
|
||||
|
||||
// Add time at the end of the pre-last transition
|
||||
std::chrono::system_clock::time_point prelast_period_change =
|
||||
check_period->previousLastStateChange();
|
||||
if (prelast_period_change !=
|
||||
std::chrono::system_clock::time_point()) {
|
||||
if (last_check < prelast_period_change) {
|
||||
check_result_age += prelast_period_change - last_check;
|
||||
}
|
||||
// else: a check happend out of the check period. Ignore this
|
||||
}
|
||||
// else: no information about past. Ignore this
|
||||
}
|
||||
} else {
|
||||
// Check is currently out of its check period? Then use the beginning of
|
||||
// the inactive phase as reference for computing the check age. This
|
||||
// effectively freezes the staleness value when a goes goes into its
|
||||
// inactive phase.
|
||||
if (last_period_change != std::chrono::system_clock::time_point()) {
|
||||
check_result_age = last_period_change - last_check;
|
||||
} else {
|
||||
// e.g. for timeperiod "never"
|
||||
check_result_age = std::chrono::seconds(0);
|
||||
}
|
||||
}
|
||||
|
||||
// Is the checks' result based on cached agent data? Then use the age of
|
||||
// that data as check result age
|
||||
std::chrono::duration<double> interval;
|
||||
if (state->_cached_at != std::chrono::system_clock::time_point()) {
|
||||
// Cache interval and check interval can add up in the worst case.
|
||||
interval = state->_cache_interval + object->_check_interval;
|
||||
|
||||
std::chrono::system_clock::duration cached_age =
|
||||
m_now - state->_cached_at;
|
||||
if (cached_age > check_result_age) {
|
||||
check_result_age = cached_age;
|
||||
}
|
||||
} else {
|
||||
interval = object->_check_interval;
|
||||
}
|
||||
|
||||
// Check_MK configures the interval for its passive checks correctly. Just
|
||||
// make sure that we do not fail if it is set to 0 by some error.
|
||||
return std::chrono::duration_cast<std::chrono::seconds>(check_result_age)
|
||||
.count() /
|
||||
(interval == std::chrono::seconds(0) ? 1 : interval.count());
|
||||
}
|
||||
#endif
|
||||
59
src/HostSpecialDoubleColumn.h
Normal file
59
src/HostSpecialDoubleColumn.h
Normal file
@@ -0,0 +1,59 @@
|
||||
// +------------------------------------------------------------------+
|
||||
// | ____ _ _ __ __ _ __ |
|
||||
// | / ___| |__ ___ ___| | __ | \/ | |/ / |
|
||||
// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / |
|
||||
// | | |___| | | | __/ (__| < | | | | . \ |
|
||||
// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ |
|
||||
// | |
|
||||
// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de |
|
||||
// +------------------------------------------------------------------+
|
||||
//
|
||||
// This file is part of Check_MK.
|
||||
// The official homepage is at http://mathias-kettner.de/check_mk.
|
||||
//
|
||||
// check_mk is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation in version 2. check_mk is distributed
|
||||
// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with-
|
||||
// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
// PARTICULAR PURPOSE. See the GNU General Public License for more de-
|
||||
// tails. You should have received a copy of the GNU General Public
|
||||
// License along with GNU Make; see the file COPYING. If not, write
|
||||
// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
// Boston, MA 02110-1301 USA.
|
||||
|
||||
#ifndef HostSpecialDoubleColumn_h
|
||||
#define HostSpecialDoubleColumn_h
|
||||
|
||||
#include "config.h" // IWYU pragma: keep
|
||||
#include <string>
|
||||
#include "DoubleColumn.h"
|
||||
class Row;
|
||||
|
||||
#ifdef CMC
|
||||
class Object;
|
||||
#endif
|
||||
|
||||
class HostSpecialDoubleColumn : public DoubleColumn {
|
||||
public:
|
||||
enum class Type { staleness };
|
||||
|
||||
HostSpecialDoubleColumn(const std::string& name,
|
||||
const std::string& description, int indirect,
|
||||
int extra_offset, int extra_extra_offset,
|
||||
int offset, Type hsdc_type)
|
||||
: DoubleColumn(name, description, indirect, extra_offset,
|
||||
extra_extra_offset, offset)
|
||||
, _type(hsdc_type) {}
|
||||
|
||||
[[nodiscard]] double getValue(Row row) const override;
|
||||
|
||||
#ifdef CMC
|
||||
static double staleness(const Object* object);
|
||||
#endif
|
||||
|
||||
private:
|
||||
const Type _type;
|
||||
};
|
||||
|
||||
#endif // HostSpecialDoubleColumn_h
|
||||
92
src/HostSpecialIntColumn.cc
Normal file
92
src/HostSpecialIntColumn.cc
Normal file
@@ -0,0 +1,92 @@
|
||||
// +------------------------------------------------------------------+
|
||||
// | ____ _ _ __ __ _ __ |
|
||||
// | / ___| |__ ___ ___| | __ | \/ | |/ / |
|
||||
// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / |
|
||||
// | | |___| | | | __/ (__| < | | | | . \ |
|
||||
// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ |
|
||||
// | |
|
||||
// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de |
|
||||
// +------------------------------------------------------------------+
|
||||
//
|
||||
// This file is part of Check_MK.
|
||||
// The official homepage is at http://mathias-kettner.de/check_mk.
|
||||
//
|
||||
// check_mk is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation in version 2. check_mk is distributed
|
||||
// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with-
|
||||
// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
// PARTICULAR PURPOSE. See the GNU General Public License for more de-
|
||||
// tails. You should have received a copy of the GNU General Public
|
||||
// License along with GNU Make; see the file COPYING. If not, write
|
||||
// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
// Boston, MA 02110-1301 USA.
|
||||
|
||||
#include "HostSpecialIntColumn.h"
|
||||
#include "MonitoringCore.h"
|
||||
#include "Row.h"
|
||||
#include "mk_inventory.h"
|
||||
|
||||
#ifdef CMC
|
||||
#include "Core.h"
|
||||
#include "Host.h"
|
||||
#include "Object.h"
|
||||
#include "RRDBackend.h"
|
||||
#include "RRDInfoCache.h"
|
||||
#include "State.h"
|
||||
#include "cmc.h"
|
||||
#else
|
||||
#include "nagios.h"
|
||||
#include "pnp4nagios.h"
|
||||
#endif
|
||||
|
||||
int32_t HostSpecialIntColumn::getValue(Row row,
|
||||
const contact* /* auth_user */) const {
|
||||
#ifdef CMC
|
||||
if (auto object = columnData<Object>(row)) {
|
||||
switch (_type) {
|
||||
case Type::real_hard_state: {
|
||||
if (object->isCurrentStateOK()) {
|
||||
return 0;
|
||||
}
|
||||
auto state = object->state();
|
||||
return state->_state_type == StateType::hard
|
||||
? state->_current_state
|
||||
: state->_last_hard_state;
|
||||
}
|
||||
case Type::pnp_graph_present:
|
||||
return _mc->impl<Core>()
|
||||
->_rrd_backend.infoFor(object)
|
||||
._names.empty()
|
||||
? 0
|
||||
: 1;
|
||||
case Type::mk_inventory_last:
|
||||
return static_cast<int32_t>(mk_inventory_last(
|
||||
_mc->mkInventoryPath() + "/" + object->host()->name()));
|
||||
}
|
||||
}
|
||||
#else
|
||||
if (auto hst = columnData<host>(row)) {
|
||||
switch (_type) {
|
||||
case Type::real_hard_state:
|
||||
if (hst->current_state == 0) {
|
||||
return 0;
|
||||
}
|
||||
if (hst->state_type == HARD_STATE) {
|
||||
return hst->current_state;
|
||||
}
|
||||
return hst->last_hard_state;
|
||||
|
||||
case Type::pnp_graph_present:
|
||||
return pnpgraph_present(_mc, hst->name,
|
||||
dummy_service_description());
|
||||
|
||||
case Type::mk_inventory_last: {
|
||||
return static_cast<int32_t>(mk_inventory_last(
|
||||
_mc->mkInventoryPath() + "/" + hst->name));
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
56
src/HostSpecialIntColumn.h
Normal file
56
src/HostSpecialIntColumn.h
Normal file
@@ -0,0 +1,56 @@
|
||||
// +------------------------------------------------------------------+
|
||||
// | ____ _ _ __ __ _ __ |
|
||||
// | / ___| |__ ___ ___| | __ | \/ | |/ / |
|
||||
// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / |
|
||||
// | | |___| | | | __/ (__| < | | | | . \ |
|
||||
// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ |
|
||||
// | |
|
||||
// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de |
|
||||
// +------------------------------------------------------------------+
|
||||
//
|
||||
// This file is part of Check_MK.
|
||||
// The official homepage is at http://mathias-kettner.de/check_mk.
|
||||
//
|
||||
// check_mk is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation in version 2. check_mk is distributed
|
||||
// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with-
|
||||
// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
// PARTICULAR PURPOSE. See the GNU General Public License for more de-
|
||||
// tails. You should have received a copy of the GNU General Public
|
||||
// License along with GNU Make; see the file COPYING. If not, write
|
||||
// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
// Boston, MA 02110-1301 USA.
|
||||
|
||||
#ifndef HostSpecialIntColumn_h
|
||||
#define HostSpecialIntColumn_h
|
||||
|
||||
#include "config.h" // IWYU pragma: keep
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
#include "IntColumn.h"
|
||||
#include "contact_fwd.h"
|
||||
class MonitoringCore;
|
||||
class Row;
|
||||
|
||||
class HostSpecialIntColumn : public IntColumn {
|
||||
public:
|
||||
enum class Type { real_hard_state, pnp_graph_present, mk_inventory_last };
|
||||
|
||||
HostSpecialIntColumn(const std::string &name,
|
||||
const std::string &description, int indirect_offset,
|
||||
int extra_offset, int extra_extra_offset, int offset,
|
||||
MonitoringCore *mc, Type hsic_type)
|
||||
: IntColumn(name, description, indirect_offset, extra_offset,
|
||||
extra_extra_offset, offset)
|
||||
, _mc(mc)
|
||||
, _type(hsic_type) {}
|
||||
|
||||
int32_t getValue(Row row, const contact *auth_user) const override;
|
||||
|
||||
private:
|
||||
MonitoringCore *_mc;
|
||||
const Type _type;
|
||||
};
|
||||
|
||||
#endif // HostSpecialIntColumn_h
|
||||
252
src/InputBuffer.cc
Normal file
252
src/InputBuffer.cc
Normal file
@@ -0,0 +1,252 @@
|
||||
// +------------------------------------------------------------------+
|
||||
// | ____ _ _ __ __ _ __ |
|
||||
// | / ___| |__ ___ ___| | __ | \/ | |/ / |
|
||||
// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / |
|
||||
// | | |___| | | | __/ (__| < | | | | . \ |
|
||||
// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ |
|
||||
// | |
|
||||
// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de |
|
||||
// +------------------------------------------------------------------+
|
||||
//
|
||||
// This file is part of Check_MK.
|
||||
// The official homepage is at http://mathias-kettner.de/check_mk.
|
||||
//
|
||||
// check_mk is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation in version 2. check_mk is distributed
|
||||
// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with-
|
||||
// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
// PARTICULAR PURPOSE. See the GNU General Public License for more de-
|
||||
// tails. You should have received a copy of the GNU General Public
|
||||
// License along with GNU Make; see the file COPYING. If not, write
|
||||
// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
// Boston, MA 02110-1301 USA.
|
||||
|
||||
#include "InputBuffer.h"
|
||||
#include <unistd.h>
|
||||
#include <cctype>
|
||||
#include <cstring>
|
||||
#include <ostream>
|
||||
#include <type_traits>
|
||||
#include "Logger.h"
|
||||
#include "Poller.h"
|
||||
|
||||
namespace {
|
||||
const size_t initial_buffer_size = 4096;
|
||||
// TODO(sp): Make this configurable?
|
||||
const size_t maximum_buffer_size = 500 * 1024 * 1024;
|
||||
|
||||
bool timeout_reached(const std::chrono::system_clock::time_point &start,
|
||||
const std::chrono::milliseconds &timeout) {
|
||||
return (timeout != std::chrono::milliseconds(0)) &&
|
||||
(std::chrono::system_clock::now() - start >= timeout);
|
||||
}
|
||||
} // namespace
|
||||
|
||||
std::ostream &operator<<(std::ostream &os, const InputBuffer::Result &r) {
|
||||
switch (r) {
|
||||
case InputBuffer::Result::request_read:
|
||||
return os << "request read";
|
||||
case InputBuffer::Result::data_read:
|
||||
return os << "data read";
|
||||
case InputBuffer::Result::unexpected_eof:
|
||||
return os << "unexpected EOF";
|
||||
case InputBuffer::Result::should_terminate:
|
||||
return os << "should terminate";
|
||||
case InputBuffer::Result::line_too_long:
|
||||
return os << "line too long";
|
||||
case InputBuffer::Result::eof:
|
||||
return os << "EOF";
|
||||
case InputBuffer::Result::empty_request:
|
||||
return os << "empty request";
|
||||
case InputBuffer::Result::timeout:
|
||||
return os << "timeout";
|
||||
}
|
||||
return os; // never reached
|
||||
}
|
||||
|
||||
InputBuffer::InputBuffer(int fd, const bool &termination_flag, Logger *logger,
|
||||
std::chrono::milliseconds query_timeout,
|
||||
std::chrono::milliseconds idle_timeout)
|
||||
: _fd(fd)
|
||||
, _termination_flag(termination_flag)
|
||||
, _query_timeout(query_timeout)
|
||||
, _idle_timeout(idle_timeout)
|
||||
, _readahead_buffer(initial_buffer_size)
|
||||
, _logger(logger) {
|
||||
_read_index = 0; // points to data not yet processed
|
||||
_write_index = 0; // points to end of data in buffer
|
||||
}
|
||||
|
||||
// read in data enough for one complete request (and maybe more).
|
||||
InputBuffer::Result InputBuffer::readRequest() {
|
||||
// Remember when we started waiting for a request. This is needed for the
|
||||
// idle_timeout. A connection may not be idle longer than that value.
|
||||
auto start_of_idle = std::chrono::system_clock::now();
|
||||
|
||||
// Remember if we have read some part of the query. During
|
||||
// a query the timeout is another (short) than between
|
||||
// queries.
|
||||
bool query_started = false;
|
||||
|
||||
// _read_index points to the place in the buffer, where the
|
||||
// next valid data begins. This data ends at _write_index.
|
||||
// That data might have been read while reading the previous
|
||||
// request.
|
||||
|
||||
// r is used to find the end of the line
|
||||
size_t r = _read_index;
|
||||
|
||||
while (true) {
|
||||
// Try to find end of the current line in buffer
|
||||
while (r < _write_index && _readahead_buffer[r] != '\n') {
|
||||
r++; // now r is at end of data or at '\n'
|
||||
}
|
||||
|
||||
// If we cannot find the end of line in the data
|
||||
// already read, then we need to read new data from
|
||||
// the client.
|
||||
if (r == _write_index) {
|
||||
// Is there still space left in the buffer => read in
|
||||
// further data into the buffer.
|
||||
if (_write_index < _readahead_buffer.capacity()) {
|
||||
Result rd =
|
||||
readData(); // tries to read in further data into buffer
|
||||
if (rd == Result::timeout) {
|
||||
if (query_started) {
|
||||
Informational(_logger)
|
||||
<< "Timeout of " << _query_timeout.count()
|
||||
<< " ms exceeded while reading query";
|
||||
return Result::timeout;
|
||||
}
|
||||
// Check if we exceeded the maximum time between two queries
|
||||
if (timeout_reached(start_of_idle, _idle_timeout)) {
|
||||
Informational(_logger)
|
||||
<< "Idle timeout of " << _idle_timeout.count()
|
||||
<< " ms exceeded. Going to close connection.";
|
||||
return Result::timeout;
|
||||
}
|
||||
}
|
||||
|
||||
// Are we at end of file? That is only an error, if we've
|
||||
// read an incomplete line. If the last thing we read was
|
||||
// a linefeed, then we consider the current request to
|
||||
// be valid, if it is not empty.
|
||||
else if (
|
||||
rd == Result::eof &&
|
||||
r == _read_index /* currently at beginning of a line */) {
|
||||
if (_request_lines.empty()) {
|
||||
return Result::eof; // empty request -> no request
|
||||
}
|
||||
// socket has been closed but request is complete
|
||||
return Result::request_read;
|
||||
// the current state is now:
|
||||
// _read_index == r == _write_index => buffer is empty
|
||||
// that way, if the main program tries to read the
|
||||
// next request, it will get an IB_UNEXPECTED_EOF
|
||||
|
||||
}
|
||||
// if we are *not* at an end of line while reading
|
||||
// a request, we got an invalid request.
|
||||
else if (rd == Result::eof) {
|
||||
return Result::unexpected_eof;
|
||||
|
||||
// Other status codes
|
||||
} else if (rd == Result::should_terminate) {
|
||||
return rd;
|
||||
}
|
||||
}
|
||||
// OK. So no space is left in the buffer. But maybe at the
|
||||
// *beginning* of the buffer is space left again. This is
|
||||
// very probable if _write_index == _readahead_buffer.capacity().
|
||||
// Most
|
||||
// of the buffer's content is already processed. So we simply
|
||||
// shift the yet unprocessed data to the very left of the buffer.
|
||||
else if (_read_index > 0) {
|
||||
size_t shift_by =
|
||||
_read_index; // distance to beginning of buffer
|
||||
size_t size =
|
||||
_write_index - _read_index; // amount of data to shift
|
||||
memmove(&_readahead_buffer[0], &_readahead_buffer[_read_index],
|
||||
size);
|
||||
_read_index = 0; // unread data is now at the beginning
|
||||
_write_index -= shift_by; // write pointer shifted to the left
|
||||
r -= shift_by; // current scan position also shift left
|
||||
// continue -> still no data in buffer, but it will
|
||||
// be read, as now is space
|
||||
}
|
||||
// buffer is full, but still no end of line found
|
||||
else {
|
||||
size_t new_capacity = _readahead_buffer.capacity() * 2;
|
||||
if (new_capacity > maximum_buffer_size) {
|
||||
Informational(_logger)
|
||||
<< "Error: maximum length of request line exceeded";
|
||||
return Result::line_too_long;
|
||||
}
|
||||
_readahead_buffer.resize(new_capacity);
|
||||
}
|
||||
} else // end of line found
|
||||
{
|
||||
if (_read_index == r) { // empty line found => end of request
|
||||
_read_index = r + 1;
|
||||
// Was ist, wenn noch keine korrekte Zeile gelesen wurde?
|
||||
if (_request_lines.empty()) {
|
||||
return Result::empty_request;
|
||||
}
|
||||
return Result::request_read;
|
||||
|
||||
} // non-empty line: belongs to current request
|
||||
size_t length = r - _read_index;
|
||||
for (size_t end = r; end > _read_index &&
|
||||
(isspace(_readahead_buffer[--end]) != 0);) {
|
||||
length--;
|
||||
}
|
||||
if (length > 0) {
|
||||
_request_lines.emplace_back(&_readahead_buffer[_read_index],
|
||||
length);
|
||||
} else {
|
||||
Informational(_logger)
|
||||
<< "Warning ignoring line containing only whitespace";
|
||||
}
|
||||
query_started = true;
|
||||
_read_index = r + 1;
|
||||
r = _read_index;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// read at least *some* data. Return IB_TIMEOUT if that lasts more than
|
||||
// _query_timeout msecs.
|
||||
InputBuffer::Result InputBuffer::readData() {
|
||||
auto start = std::chrono::system_clock::now();
|
||||
while (!_termination_flag) {
|
||||
if (timeout_reached(start, _query_timeout)) {
|
||||
return Result::timeout;
|
||||
}
|
||||
|
||||
Poller poller;
|
||||
poller.addFileDescriptor(_fd, PollEvents::in);
|
||||
int retval = poller.poll(std::chrono::milliseconds(200));
|
||||
if (retval > 0 && poller.isFileDescriptorSet(_fd, PollEvents::in)) {
|
||||
ssize_t r = read(_fd, &_readahead_buffer[_write_index],
|
||||
_readahead_buffer.capacity() - _write_index);
|
||||
if (r < 0) {
|
||||
return Result::eof;
|
||||
}
|
||||
if (r == 0) {
|
||||
return Result::eof;
|
||||
}
|
||||
_write_index += r;
|
||||
return Result::data_read;
|
||||
}
|
||||
}
|
||||
return Result::should_terminate;
|
||||
}
|
||||
|
||||
bool InputBuffer::empty() const { return _request_lines.empty(); }
|
||||
|
||||
std::string InputBuffer::nextLine() {
|
||||
std::string s = _request_lines.front();
|
||||
_request_lines.pop_front();
|
||||
return s;
|
||||
}
|
||||
73
src/InputBuffer.h
Normal file
73
src/InputBuffer.h
Normal file
@@ -0,0 +1,73 @@
|
||||
// +------------------------------------------------------------------+
|
||||
// | ____ _ _ __ __ _ __ |
|
||||
// | / ___| |__ ___ ___| | __ | \/ | |/ / |
|
||||
// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / |
|
||||
// | | |___| | | | __/ (__| < | | | | . \ |
|
||||
// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ |
|
||||
// | |
|
||||
// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de |
|
||||
// +------------------------------------------------------------------+
|
||||
//
|
||||
// This file is part of Check_MK.
|
||||
// The official homepage is at http://mathias-kettner.de/check_mk.
|
||||
//
|
||||
// check_mk is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation in version 2. check_mk is distributed
|
||||
// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with-
|
||||
// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
// PARTICULAR PURPOSE. See the GNU General Public License for more de-
|
||||
// tails. You should have received a copy of the GNU General Public
|
||||
// License along with GNU Make; see the file COPYING. If not, write
|
||||
// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
// Boston, MA 02110-1301 USA.
|
||||
|
||||
#ifndef InputBuffer_h
|
||||
#define InputBuffer_h
|
||||
|
||||
#include "config.h" // IWYU pragma: keep
|
||||
#include <chrono>
|
||||
#include <cstddef>
|
||||
#include <iosfwd>
|
||||
#include <list>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
class Logger;
|
||||
|
||||
class InputBuffer {
|
||||
public:
|
||||
enum class Result {
|
||||
request_read,
|
||||
data_read,
|
||||
unexpected_eof,
|
||||
should_terminate,
|
||||
line_too_long,
|
||||
eof,
|
||||
empty_request,
|
||||
timeout
|
||||
};
|
||||
|
||||
friend std::ostream &operator<<(std::ostream &os, const Result &r);
|
||||
|
||||
InputBuffer(int fd, const bool &termination_flag, Logger *logger,
|
||||
std::chrono::milliseconds query_timeout,
|
||||
std::chrono::milliseconds idle_timeout);
|
||||
Result readRequest();
|
||||
[[nodiscard]] bool empty() const;
|
||||
std::string nextLine();
|
||||
|
||||
private:
|
||||
int _fd;
|
||||
const bool &_termination_flag;
|
||||
std::chrono::milliseconds _query_timeout;
|
||||
std::chrono::milliseconds _idle_timeout;
|
||||
std::vector<char> _readahead_buffer;
|
||||
size_t _read_index;
|
||||
size_t _write_index;
|
||||
std::list<std::string> _request_lines;
|
||||
Logger *const _logger;
|
||||
|
||||
Result readData();
|
||||
};
|
||||
|
||||
#endif // InputBuffer_h
|
||||
55
src/IntAggregator.h
Normal file
55
src/IntAggregator.h
Normal file
@@ -0,0 +1,55 @@
|
||||
// +------------------------------------------------------------------+
|
||||
// | ____ _ _ __ __ _ __ |
|
||||
// | / ___| |__ ___ ___| | __ | \/ | |/ / |
|
||||
// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / |
|
||||
// | | |___| | | | __/ (__| < | | | | . \ |
|
||||
// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ |
|
||||
// | |
|
||||
// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de |
|
||||
// +------------------------------------------------------------------+
|
||||
//
|
||||
// This file is part of Check_MK.
|
||||
// The official homepage is at http://mathias-kettner.de/check_mk.
|
||||
//
|
||||
// check_mk is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation in version 2. check_mk is distributed
|
||||
// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with-
|
||||
// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
// PARTICULAR PURPOSE. See the GNU General Public License for more de-
|
||||
// tails. You should have received a copy of the GNU General Public
|
||||
// License along with GNU Make; see the file COPYING. If not, write
|
||||
// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
// Boston, MA 02110-1301 USA.
|
||||
|
||||
#ifndef IntAggregator_h
|
||||
#define IntAggregator_h
|
||||
|
||||
#include "config.h" // IWYU pragma: keep
|
||||
#include <chrono>
|
||||
#include "Aggregator.h"
|
||||
#include "IntColumn.h"
|
||||
#include "contact_fwd.h"
|
||||
class Row;
|
||||
class RowRenderer;
|
||||
|
||||
class IntAggregator : public Aggregator {
|
||||
public:
|
||||
IntAggregator(const AggregationFactory &factory, const IntColumn *column)
|
||||
: _aggregation(factory()), _column(column) {}
|
||||
|
||||
void consume(Row row, const contact *auth_user,
|
||||
std::chrono::seconds /* timezone_offset*/) override {
|
||||
_aggregation->update(_column->getValue(row, auth_user));
|
||||
}
|
||||
|
||||
void output(RowRenderer &r) const override {
|
||||
r.output(_aggregation->value());
|
||||
}
|
||||
|
||||
private:
|
||||
std::unique_ptr<Aggregation> _aggregation;
|
||||
const IntColumn *const _column;
|
||||
};
|
||||
|
||||
#endif // IntAggregator_h
|
||||
47
src/IntColumn.cc
Normal file
47
src/IntColumn.cc
Normal file
@@ -0,0 +1,47 @@
|
||||
// +------------------------------------------------------------------+
|
||||
// | ____ _ _ __ __ _ __ |
|
||||
// | / ___| |__ ___ ___| | __ | \/ | |/ / |
|
||||
// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / |
|
||||
// | | |___| | | | __/ (__| < | | | | . \ |
|
||||
// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ |
|
||||
// | |
|
||||
// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de |
|
||||
// +------------------------------------------------------------------+
|
||||
//
|
||||
// This file is part of Check_MK.
|
||||
// The official homepage is at http://mathias-kettner.de/check_mk.
|
||||
//
|
||||
// check_mk is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation in version 2. check_mk is distributed
|
||||
// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with-
|
||||
// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
// PARTICULAR PURPOSE. See the GNU General Public License for more de-
|
||||
// tails. You should have received a copy of the GNU General Public
|
||||
// License along with GNU Make; see the file COPYING. If not, write
|
||||
// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
// Boston, MA 02110-1301 USA.
|
||||
|
||||
#include "IntColumn.h"
|
||||
#include "Aggregator.h"
|
||||
#include "Filter.h"
|
||||
#include "IntAggregator.h"
|
||||
#include "IntFilter.h"
|
||||
#include "Renderer.h"
|
||||
#include "Row.h"
|
||||
|
||||
void IntColumn::output(Row row, RowRenderer &r, const contact *auth_user,
|
||||
std::chrono::seconds /*timezone_offset*/) const {
|
||||
r.output(getValue(row, auth_user));
|
||||
}
|
||||
|
||||
std::unique_ptr<Filter> IntColumn::createFilter(
|
||||
Filter::Kind kind, RelationalOperator relOp,
|
||||
const std::string &value) const {
|
||||
return std::make_unique<IntFilter>(kind, *this, relOp, value);
|
||||
}
|
||||
|
||||
std::unique_ptr<Aggregator> IntColumn::createAggregator(
|
||||
AggregationFactory factory) const {
|
||||
return std::make_unique<IntAggregator>(factory, this);
|
||||
}
|
||||
64
src/IntColumn.h
Normal file
64
src/IntColumn.h
Normal file
@@ -0,0 +1,64 @@
|
||||
// +------------------------------------------------------------------+
|
||||
// | ____ _ _ __ __ _ __ |
|
||||
// | / ___| |__ ___ ___| | __ | \/ | |/ / |
|
||||
// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / |
|
||||
// | | |___| | | | __/ (__| < | | | | . \ |
|
||||
// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ |
|
||||
// | |
|
||||
// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de |
|
||||
// +------------------------------------------------------------------+
|
||||
//
|
||||
// This file is part of Check_MK.
|
||||
// The official homepage is at http://mathias-kettner.de/check_mk.
|
||||
//
|
||||
// check_mk is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation in version 2. check_mk is distributed
|
||||
// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with-
|
||||
// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
// PARTICULAR PURPOSE. See the GNU General Public License for more de-
|
||||
// tails. You should have received a copy of the GNU General Public
|
||||
// License along with GNU Make; see the file COPYING. If not, write
|
||||
// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
// Boston, MA 02110-1301 USA.
|
||||
|
||||
#ifndef IntColumn_h
|
||||
#define IntColumn_h
|
||||
|
||||
#include "config.h" // IWYU pragma: keep
|
||||
#include <chrono>
|
||||
#include <cstdint>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include "Column.h"
|
||||
#include "Filter.h"
|
||||
#include "contact_fwd.h"
|
||||
#include "opids.h"
|
||||
class Aggregator;
|
||||
class Row;
|
||||
class RowRenderer;
|
||||
|
||||
class IntColumn : public Column {
|
||||
public:
|
||||
IntColumn(const std::string &name, const std::string &description,
|
||||
int indirect_offset, int extra_offset, int extra_extra_offset,
|
||||
int offset)
|
||||
: Column(name, description, indirect_offset, extra_offset,
|
||||
extra_extra_offset, offset) {}
|
||||
|
||||
[[nodiscard]] ColumnType type() const override { return ColumnType::int_; }
|
||||
|
||||
void output(Row row, RowRenderer &r, const contact *auth_user,
|
||||
std::chrono::seconds timezone_offset) const override;
|
||||
|
||||
[[nodiscard]] std::unique_ptr<Filter> createFilter(
|
||||
Filter::Kind kind, RelationalOperator relOp,
|
||||
const std::string &value) const override;
|
||||
|
||||
[[nodiscard]] std::unique_ptr<Aggregator> createAggregator(
|
||||
AggregationFactory factory) const override;
|
||||
|
||||
virtual int32_t getValue(Row row, const contact *auth_user) const = 0;
|
||||
};
|
||||
|
||||
#endif // IntColumn_h
|
||||
149
src/IntFilter.cc
Normal file
149
src/IntFilter.cc
Normal file
@@ -0,0 +1,149 @@
|
||||
// +------------------------------------------------------------------+
|
||||
// | ____ _ _ __ __ _ __ |
|
||||
// | / ___| |__ ___ ___| | __ | \/ | |/ / |
|
||||
// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / |
|
||||
// | | |___| | | | __/ (__| < | | | | . \ |
|
||||
// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ |
|
||||
// | |
|
||||
// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de |
|
||||
// +------------------------------------------------------------------+
|
||||
//
|
||||
// This file is part of Check_MK.
|
||||
// The official homepage is at http://mathias-kettner.de/check_mk.
|
||||
//
|
||||
// check_mk is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation in version 2. check_mk is distributed
|
||||
// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with-
|
||||
// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
// PARTICULAR PURPOSE. See the GNU General Public License for more de-
|
||||
// tails. You should have received a copy of the GNU General Public
|
||||
// License along with GNU Make; see the file COPYING. If not, write
|
||||
// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
// Boston, MA 02110-1301 USA.
|
||||
|
||||
#include "IntFilter.h"
|
||||
#include <cstdlib>
|
||||
#include "Filter.h"
|
||||
#include "IntColumn.h"
|
||||
#include "Row.h"
|
||||
|
||||
IntFilter::IntFilter(Kind kind, const IntColumn &column,
|
||||
RelationalOperator relOp, const std::string &value)
|
||||
: ColumnFilter(kind, column, relOp, value)
|
||||
, _column(column)
|
||||
, _ref_value(atoi(value.c_str())) {}
|
||||
|
||||
namespace {
|
||||
bool eval(int32_t x, RelationalOperator op, int32_t y) {
|
||||
switch (op) {
|
||||
case RelationalOperator::equal:
|
||||
return x == y;
|
||||
case RelationalOperator::not_equal:
|
||||
return x != y;
|
||||
case RelationalOperator::matches: // superset
|
||||
return (x & y) == y;
|
||||
case RelationalOperator::doesnt_match: // not superset
|
||||
return (x & y) != y;
|
||||
case RelationalOperator::equal_icase: // subset
|
||||
return (x & y) == x;
|
||||
case RelationalOperator::not_equal_icase: // not subset
|
||||
return (x & y) != x;
|
||||
case RelationalOperator::matches_icase: // contains any
|
||||
return (x & y) != 0;
|
||||
case RelationalOperator::doesnt_match_icase: // contains none of
|
||||
return (x & y) == 0;
|
||||
case RelationalOperator::less:
|
||||
return x < y;
|
||||
case RelationalOperator::greater_or_equal:
|
||||
return x >= y;
|
||||
case RelationalOperator::greater:
|
||||
return x > y;
|
||||
case RelationalOperator::less_or_equal:
|
||||
return x <= y;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
} // namespace
|
||||
|
||||
bool IntFilter::accepts(Row row, const contact *auth_user,
|
||||
std::chrono::seconds /*timezone_offset*/) const {
|
||||
return eval(_column.getValue(row, auth_user), oper(), _ref_value);
|
||||
}
|
||||
|
||||
std::optional<int32_t> IntFilter::greatestLowerBoundFor(
|
||||
const std::string &column_name,
|
||||
std::chrono::seconds /* timezone_offset */) const {
|
||||
if (column_name != columnName()) {
|
||||
return {}; // wrong column
|
||||
}
|
||||
switch (oper()) {
|
||||
case RelationalOperator::equal:
|
||||
case RelationalOperator::greater_or_equal:
|
||||
return {_ref_value};
|
||||
case RelationalOperator::greater:
|
||||
return {_ref_value + 1};
|
||||
case RelationalOperator::not_equal:
|
||||
case RelationalOperator::matches: // superset
|
||||
case RelationalOperator::doesnt_match: // not superset
|
||||
case RelationalOperator::equal_icase: // subset
|
||||
case RelationalOperator::not_equal_icase: // not subset
|
||||
case RelationalOperator::matches_icase: // contains any
|
||||
case RelationalOperator::doesnt_match_icase: // contains none of
|
||||
case RelationalOperator::less:
|
||||
case RelationalOperator::less_or_equal:
|
||||
// NOTE: If we use the equivalent 'return {}' here and the other
|
||||
// std::nullopt occurences below, we run into g++/libstdc++ bug
|
||||
// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86465. :-/
|
||||
return std::nullopt;
|
||||
}
|
||||
return std::nullopt; // unreachable
|
||||
}
|
||||
|
||||
std::optional<int32_t> IntFilter::leastUpperBoundFor(
|
||||
const std::string &column_name,
|
||||
std::chrono::seconds /* timezone_offset */) const {
|
||||
if (column_name != columnName()) {
|
||||
return {}; // wrong column
|
||||
}
|
||||
switch (oper()) {
|
||||
case RelationalOperator::equal:
|
||||
case RelationalOperator::less_or_equal:
|
||||
return {_ref_value};
|
||||
case RelationalOperator::less:
|
||||
return {_ref_value - 1};
|
||||
case RelationalOperator::not_equal:
|
||||
case RelationalOperator::matches: // superset
|
||||
case RelationalOperator::doesnt_match: // not superset
|
||||
case RelationalOperator::equal_icase: // subset
|
||||
case RelationalOperator::not_equal_icase: // not subset
|
||||
case RelationalOperator::matches_icase: // contains any
|
||||
case RelationalOperator::doesnt_match_icase: // contains none of
|
||||
case RelationalOperator::greater_or_equal:
|
||||
case RelationalOperator::greater:
|
||||
return std::nullopt;
|
||||
}
|
||||
return std::nullopt; // unreachable
|
||||
}
|
||||
|
||||
std::optional<std::bitset<32>> IntFilter::valueSetLeastUpperBoundFor(
|
||||
const std::string &column_name,
|
||||
std::chrono::seconds /* timezone_offset */) const {
|
||||
if (column_name != columnName()) {
|
||||
return {}; // wrong column
|
||||
}
|
||||
std::bitset<32> result;
|
||||
for (int32_t bit = 0; bit < 32; ++bit) {
|
||||
result[bit] = eval(bit, oper(), _ref_value);
|
||||
}
|
||||
return {result};
|
||||
}
|
||||
|
||||
std::unique_ptr<Filter> IntFilter::copy() const {
|
||||
return std::make_unique<IntFilter>(*this);
|
||||
}
|
||||
|
||||
std::unique_ptr<Filter> IntFilter::negate() const {
|
||||
return std::make_unique<IntFilter>(
|
||||
kind(), _column, negateRelationalOperator(oper()), value());
|
||||
}
|
||||
70
src/IntFilter.h
Normal file
70
src/IntFilter.h
Normal file
@@ -0,0 +1,70 @@
|
||||
// +------------------------------------------------------------------+
|
||||
// | ____ _ _ __ __ _ __ |
|
||||
// | / ___| |__ ___ ___| | __ | \/ | |/ / |
|
||||
// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / |
|
||||
// | | |___| | | | __/ (__| < | | | | . \ |
|
||||
// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ |
|
||||
// | |
|
||||
// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de |
|
||||
// +------------------------------------------------------------------+
|
||||
//
|
||||
// This file is part of Check_MK.
|
||||
// The official homepage is at http://mathias-kettner.de/check_mk.
|
||||
//
|
||||
// check_mk is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation in version 2. check_mk is distributed
|
||||
// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with-
|
||||
// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
// PARTICULAR PURPOSE. See the GNU General Public License for more de-
|
||||
// tails. You should have received a copy of the GNU General Public
|
||||
// License along with GNU Make; see the file COPYING. If not, write
|
||||
// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
// Boston, MA 02110-1301 USA.
|
||||
|
||||
#ifndef IntFilter_h
|
||||
#define IntFilter_h
|
||||
|
||||
#include "config.h" // IWYU pragma: keep
|
||||
#include <bitset>
|
||||
#include <chrono>
|
||||
#include <cstdint>
|
||||
#include <memory>
|
||||
#include <optional>
|
||||
#include <string>
|
||||
#include "ColumnFilter.h"
|
||||
#include "Filter.h"
|
||||
#include "contact_fwd.h"
|
||||
#include "opids.h"
|
||||
class IntColumn;
|
||||
class Row;
|
||||
|
||||
class IntFilter : public ColumnFilter {
|
||||
public:
|
||||
IntFilter(Kind kind, const IntColumn &column, RelationalOperator relOp,
|
||||
const std::string &value);
|
||||
|
||||
bool accepts(Row row, const contact *auth_user,
|
||||
std::chrono::seconds timezone_offset) const override;
|
||||
|
||||
[[nodiscard]] std::optional<int32_t> greatestLowerBoundFor(
|
||||
const std::string &column_name,
|
||||
std::chrono::seconds timezone_offset) const override;
|
||||
|
||||
[[nodiscard]] std::optional<int32_t> leastUpperBoundFor(
|
||||
const std::string &column_name,
|
||||
std::chrono::seconds timezone_offset) const override;
|
||||
|
||||
[[nodiscard]] std::optional<std::bitset<32>> valueSetLeastUpperBoundFor(
|
||||
const std::string &column_name,
|
||||
std::chrono::seconds timezone_offset) const override;
|
||||
|
||||
[[nodiscard]] std::unique_ptr<Filter> copy() const override;
|
||||
[[nodiscard]] std::unique_ptr<Filter> negate() const override;
|
||||
|
||||
private:
|
||||
const IntColumn &_column;
|
||||
const int32_t _ref_value;
|
||||
};
|
||||
|
||||
#endif // IntFilter_h
|
||||
46
src/IntPointerColumn.h
Normal file
46
src/IntPointerColumn.h
Normal file
@@ -0,0 +1,46 @@
|
||||
// +------------------------------------------------------------------+
|
||||
// | ____ _ _ __ __ _ __ |
|
||||
// | / ___| |__ ___ ___| | __ | \/ | |/ / |
|
||||
// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / |
|
||||
// | | |___| | | | __/ (__| < | | | | . \ |
|
||||
// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ |
|
||||
// | |
|
||||
// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de |
|
||||
// +------------------------------------------------------------------+
|
||||
//
|
||||
// This file is part of Check_MK.
|
||||
// The official homepage is at http://mathias-kettner.de/check_mk.
|
||||
//
|
||||
// check_mk is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation in version 2. check_mk is distributed
|
||||
// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with-
|
||||
// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
// PARTICULAR PURPOSE. See the GNU General Public License for more de-
|
||||
// tails. You should have received a copy of the GNU General Public
|
||||
// License along with GNU Make; see the file COPYING. If not, write
|
||||
// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
// Boston, MA 02110-1301 USA.
|
||||
|
||||
#ifndef IntPointerColumn_h
|
||||
#define IntPointerColumn_h
|
||||
|
||||
#include "config.h" // IWYU pragma: keep
|
||||
#include "IntColumn.h"
|
||||
|
||||
class IntPointerColumn : public IntColumn {
|
||||
public:
|
||||
IntPointerColumn(const std::string& name, const std::string& description,
|
||||
const int* number)
|
||||
: IntColumn(name, description, -1, -1, -1, 0), _number(number) {}
|
||||
|
||||
int32_t getValue(Row /* row */,
|
||||
const contact* /* auth_user */) const override {
|
||||
return *_number;
|
||||
}
|
||||
|
||||
private:
|
||||
const int* const _number;
|
||||
};
|
||||
|
||||
#endif // IntPointerColumn_h
|
||||
50
src/ListColumn.cc
Normal file
50
src/ListColumn.cc
Normal file
@@ -0,0 +1,50 @@
|
||||
// +------------------------------------------------------------------+
|
||||
// | ____ _ _ __ __ _ __ |
|
||||
// | / ___| |__ ___ ___| | __ | \/ | |/ / |
|
||||
// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / |
|
||||
// | | |___| | | | __/ (__| < | | | | . \ |
|
||||
// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ |
|
||||
// | |
|
||||
// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de |
|
||||
// +------------------------------------------------------------------+
|
||||
//
|
||||
// This file is part of Check_MK.
|
||||
// The official homepage is at http://mathias-kettner.de/check_mk.
|
||||
//
|
||||
// check_mk is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation in version 2. check_mk is distributed
|
||||
// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with-
|
||||
// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
// PARTICULAR PURPOSE. See the GNU General Public License for more de-
|
||||
// tails. You should have received a copy of the GNU General Public
|
||||
// License along with GNU Make; see the file COPYING. If not, write
|
||||
// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
// Boston, MA 02110-1301 USA.
|
||||
|
||||
#include "ListColumn.h"
|
||||
#include <stdexcept>
|
||||
#include "Filter.h"
|
||||
#include "ListFilter.h"
|
||||
#include "Renderer.h"
|
||||
#include "Row.h"
|
||||
|
||||
void ListColumn::output(Row row, RowRenderer &r, const contact *auth_user,
|
||||
std::chrono::seconds timezone_offset) const {
|
||||
ListRenderer l(r);
|
||||
for (const auto &val : getValue(row, auth_user, timezone_offset)) {
|
||||
l.output(val);
|
||||
}
|
||||
}
|
||||
|
||||
std::unique_ptr<Filter> ListColumn::createFilter(
|
||||
Filter::Kind kind, RelationalOperator relOp,
|
||||
const std::string &value) const {
|
||||
return std::make_unique<ListFilter>(kind, *this, relOp, value);
|
||||
}
|
||||
|
||||
std::unique_ptr<Aggregator> ListColumn::createAggregator(
|
||||
AggregationFactory /*factory*/) const {
|
||||
throw std::runtime_error("aggregating on list column '" + name() +
|
||||
"' not supported");
|
||||
}
|
||||
68
src/ListColumn.h
Normal file
68
src/ListColumn.h
Normal file
@@ -0,0 +1,68 @@
|
||||
// +------------------------------------------------------------------+
|
||||
// | ____ _ _ __ __ _ __ |
|
||||
// | / ___| |__ ___ ___| | __ | \/ | |/ / |
|
||||
// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / |
|
||||
// | | |___| | | | __/ (__| < | | | | . \ |
|
||||
// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ |
|
||||
// | |
|
||||
// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de |
|
||||
// +------------------------------------------------------------------+
|
||||
//
|
||||
// This file is part of Check_MK.
|
||||
// The official homepage is at http://mathias-kettner.de/check_mk.
|
||||
//
|
||||
// check_mk is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation in version 2. check_mk is distributed
|
||||
// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with-
|
||||
// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
// PARTICULAR PURPOSE. See the GNU General Public License for more de-
|
||||
// tails. You should have received a copy of the GNU General Public
|
||||
// License along with GNU Make; see the file COPYING. If not, write
|
||||
// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
// Boston, MA 02110-1301 USA.
|
||||
|
||||
#ifndef ListColumn_h
|
||||
#define ListColumn_h
|
||||
|
||||
#include "config.h" // IWYU pragma: keep
|
||||
#include <chrono>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include "Column.h"
|
||||
#include "Filter.h"
|
||||
#include "contact_fwd.h"
|
||||
#include "opids.h"
|
||||
class Aggregator;
|
||||
class Row;
|
||||
class RowRenderer;
|
||||
|
||||
class ListColumn : public Column {
|
||||
public:
|
||||
ListColumn(const std::string &name, const std::string &description,
|
||||
int indirect_offset, int extra_offset, int extra_extra_offset,
|
||||
int offset)
|
||||
: Column(name, description, indirect_offset, extra_offset,
|
||||
extra_extra_offset, offset) {}
|
||||
|
||||
[[nodiscard]] ColumnType type() const override { return ColumnType::list; }
|
||||
|
||||
void output(Row row, RowRenderer &r, const contact *auth_user,
|
||||
std::chrono::seconds timezone_offset) const override;
|
||||
|
||||
[[nodiscard]] std::unique_ptr<Filter> createFilter(
|
||||
Filter::Kind kind, RelationalOperator relOp,
|
||||
const std::string &value) const override;
|
||||
|
||||
[[nodiscard]] std::unique_ptr<Aggregator> createAggregator(
|
||||
AggregationFactory factory) const override;
|
||||
|
||||
// TODO(sp) What we actually want here is a stream of strings, not a
|
||||
// concrete container.
|
||||
virtual std::vector<std::string> getValue(
|
||||
Row row, const contact *auth_user,
|
||||
std::chrono::seconds timezone_offset) const = 0;
|
||||
};
|
||||
|
||||
#endif // ListColumn_h
|
||||
145
src/ListFilter.cc
Normal file
145
src/ListFilter.cc
Normal file
@@ -0,0 +1,145 @@
|
||||
// +------------------------------------------------------------------+
|
||||
// | ____ _ _ __ __ _ __ |
|
||||
// | / ___| |__ ___ ___| | __ | \/ | |/ / |
|
||||
// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / |
|
||||
// | | |___| | | | __/ (__| < | | | | . \ |
|
||||
// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ |
|
||||
// | |
|
||||
// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de |
|
||||
// +------------------------------------------------------------------+
|
||||
//
|
||||
// This file is part of Check_MK.
|
||||
// The official homepage is at http://mathias-kettner.de/check_mk.
|
||||
//
|
||||
// check_mk is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation in version 2. check_mk is distributed
|
||||
// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with-
|
||||
// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
// PARTICULAR PURPOSE. See the GNU General Public License for more de-
|
||||
// tails. You should have received a copy of the GNU General Public
|
||||
// License along with GNU Make; see the file COPYING. If not, write
|
||||
// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
// Boston, MA 02110-1301 USA.
|
||||
|
||||
#include "ListFilter.h"
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include "Filter.h"
|
||||
#include "ListColumn.h"
|
||||
#include "Logger.h"
|
||||
#include "RegExp.h"
|
||||
#include "Row.h"
|
||||
|
||||
namespace {
|
||||
RelationalOperator relOpForElement(RelationalOperator relOp) {
|
||||
switch (relOp) {
|
||||
case RelationalOperator::matches:
|
||||
case RelationalOperator::doesnt_match:
|
||||
case RelationalOperator::matches_icase:
|
||||
case RelationalOperator::doesnt_match_icase:
|
||||
return relOp;
|
||||
case RelationalOperator::less:
|
||||
case RelationalOperator::greater_or_equal:
|
||||
return RelationalOperator::equal;
|
||||
case RelationalOperator::greater:
|
||||
case RelationalOperator::less_or_equal:
|
||||
return RelationalOperator::equal_icase;
|
||||
case RelationalOperator::equal:
|
||||
case RelationalOperator::not_equal:
|
||||
case RelationalOperator::equal_icase:
|
||||
case RelationalOperator::not_equal_icase:
|
||||
// optimization: do not create a RegExp later
|
||||
return RelationalOperator::less;
|
||||
};
|
||||
return relOp; // make the compiler happy...
|
||||
}
|
||||
} // namespace
|
||||
|
||||
ListFilter::ListFilter(Kind kind, const ListColumn &column,
|
||||
RelationalOperator relOp, const std::string &value)
|
||||
: ColumnFilter(kind, column, relOp, value)
|
||||
, _column(column)
|
||||
, _regExp(makeRegExpFor(relOpForElement(relOp), value)) {}
|
||||
|
||||
bool ListFilter::accepts(Row row, const contact *auth_user,
|
||||
std::chrono::seconds timezone_offset) const {
|
||||
switch (oper()) {
|
||||
case RelationalOperator::equal:
|
||||
if (!value().empty()) {
|
||||
Informational(_column.logger())
|
||||
<< "Sorry, equality for lists implemented only for emptiness";
|
||||
return false;
|
||||
}
|
||||
return !any(row, auth_user, timezone_offset,
|
||||
[](const std::string & /*unused*/) { return true; });
|
||||
case RelationalOperator::not_equal:
|
||||
if (!value().empty()) {
|
||||
Informational(_column.logger())
|
||||
<< "Sorry, inequality for lists implemented only for emptiness";
|
||||
return false;
|
||||
}
|
||||
return any(row, auth_user, timezone_offset,
|
||||
[](const std::string & /*unused*/) { return true; });
|
||||
case RelationalOperator::matches:
|
||||
case RelationalOperator::matches_icase:
|
||||
return any(
|
||||
row, auth_user, timezone_offset,
|
||||
[&](const std::string &elem) { return _regExp->search(elem); });
|
||||
case RelationalOperator::doesnt_match:
|
||||
case RelationalOperator::doesnt_match_icase:
|
||||
return !any(
|
||||
row, auth_user, timezone_offset,
|
||||
[&](const std::string &elem) { return _regExp->search(elem); });
|
||||
case RelationalOperator::greater_or_equal:
|
||||
case RelationalOperator::less_or_equal:
|
||||
return any(
|
||||
row, auth_user, timezone_offset,
|
||||
[&](const std::string &elem) { return _regExp->match(elem); });
|
||||
case RelationalOperator::less:
|
||||
case RelationalOperator::greater:
|
||||
return !any(
|
||||
row, auth_user, timezone_offset,
|
||||
[&](const std::string &elem) { return _regExp->match(elem); });
|
||||
case RelationalOperator::equal_icase:
|
||||
case RelationalOperator::not_equal_icase:
|
||||
Informational(_column.logger())
|
||||
<< "Sorry. Operator " << oper()
|
||||
<< " for list columns not implemented.";
|
||||
return false;
|
||||
}
|
||||
return false; // unreachable
|
||||
}
|
||||
|
||||
std::optional<std::string> ListFilter::stringValueRestrictionFor(
|
||||
const std::string &column_name) const {
|
||||
if (column_name != columnName()) {
|
||||
return {}; // wrong column
|
||||
}
|
||||
switch (oper()) {
|
||||
case RelationalOperator::greater_or_equal:
|
||||
return {value()};
|
||||
case RelationalOperator::equal:
|
||||
case RelationalOperator::not_equal:
|
||||
case RelationalOperator::matches:
|
||||
case RelationalOperator::doesnt_match:
|
||||
case RelationalOperator::equal_icase:
|
||||
case RelationalOperator::not_equal_icase:
|
||||
case RelationalOperator::matches_icase:
|
||||
case RelationalOperator::doesnt_match_icase:
|
||||
case RelationalOperator::less:
|
||||
case RelationalOperator::greater:
|
||||
case RelationalOperator::less_or_equal:
|
||||
return {};
|
||||
}
|
||||
return {}; // unreachable
|
||||
}
|
||||
|
||||
std::unique_ptr<Filter> ListFilter::copy() const {
|
||||
return std::make_unique<ListFilter>(*this);
|
||||
}
|
||||
|
||||
std::unique_ptr<Filter> ListFilter::negate() const {
|
||||
return std::make_unique<ListFilter>(
|
||||
kind(), _column, negateRelationalOperator(oper()), value());
|
||||
}
|
||||
66
src/ListFilter.h
Normal file
66
src/ListFilter.h
Normal file
@@ -0,0 +1,66 @@
|
||||
// +------------------------------------------------------------------+
|
||||
// | ____ _ _ __ __ _ __ |
|
||||
// | / ___| |__ ___ ___| | __ | \/ | |/ / |
|
||||
// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / |
|
||||
// | | |___| | | | __/ (__| < | | | | . \ |
|
||||
// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ |
|
||||
// | |
|
||||
// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de |
|
||||
// +------------------------------------------------------------------+
|
||||
//
|
||||
// This file is part of Check_MK.
|
||||
// The official homepage is at http://mathias-kettner.de/check_mk.
|
||||
//
|
||||
// check_mk is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation in version 2. check_mk is distributed
|
||||
// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with-
|
||||
// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
// PARTICULAR PURPOSE. See the GNU General Public License for more de-
|
||||
// tails. You should have received a copy of the GNU General Public
|
||||
// License along with GNU Make; see the file COPYING. If not, write
|
||||
// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
// Boston, MA 02110-1301 USA.
|
||||
|
||||
#ifndef ListFilter_h
|
||||
#define ListFilter_h
|
||||
|
||||
#include "config.h" // IWYU pragma: keep
|
||||
#include <algorithm>
|
||||
#include <chrono>
|
||||
#include <memory>
|
||||
#include <optional>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include "ColumnFilter.h"
|
||||
#include "Filter.h"
|
||||
#include "ListColumn.h"
|
||||
#include "Row.h"
|
||||
#include "contact_fwd.h"
|
||||
#include "opids.h"
|
||||
class RegExp;
|
||||
|
||||
class ListFilter : public ColumnFilter {
|
||||
public:
|
||||
ListFilter(Kind kind, const ListColumn &column, RelationalOperator relOp,
|
||||
const std::string &value);
|
||||
bool accepts(Row row, const contact *auth_user,
|
||||
std::chrono::seconds timezone_offset) const override;
|
||||
[[nodiscard]] std::optional<std::string> stringValueRestrictionFor(
|
||||
const std::string &column_name) const override;
|
||||
[[nodiscard]] std::unique_ptr<Filter> copy() const override;
|
||||
[[nodiscard]] std::unique_ptr<Filter> negate() const override;
|
||||
|
||||
private:
|
||||
const ListColumn &_column;
|
||||
std::shared_ptr<RegExp> _regExp;
|
||||
|
||||
template <typename UnaryPredicate>
|
||||
bool any(Row row, const contact *auth_user,
|
||||
std::chrono::seconds timezone_offset, UnaryPredicate pred) const {
|
||||
auto val = _column.getValue(row, auth_user, timezone_offset);
|
||||
return std::any_of(val.begin(), val.end(), pred);
|
||||
}
|
||||
};
|
||||
|
||||
#endif // ListFilter_h
|
||||
206
src/LogCache.cc
Normal file
206
src/LogCache.cc
Normal file
@@ -0,0 +1,206 @@
|
||||
// +------------------------------------------------------------------+
|
||||
// | ____ _ _ __ __ _ __ |
|
||||
// | / ___| |__ ___ ___| | __ | \/ | |/ / |
|
||||
// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / |
|
||||
// | | |___| | | | __/ (__| < | | | | . \ |
|
||||
// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ |
|
||||
// | |
|
||||
// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de |
|
||||
// +------------------------------------------------------------------+
|
||||
//
|
||||
// This file is part of Check_MK.
|
||||
// The official homepage is at http://mathias-kettner.de/check_mk.
|
||||
//
|
||||
// check_mk is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation in version 2. check_mk is distributed
|
||||
// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with-
|
||||
// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
// PARTICULAR PURPOSE. See the GNU General Public License for more de-
|
||||
// tails. You should have received a copy of the GNU General Public
|
||||
// License along with GNU Make; see the file COPYING. If not, write
|
||||
// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
// Boston, MA 02110-1301 USA.
|
||||
|
||||
#include "LogCache.h"
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include "FileSystem.h"
|
||||
#include "LogEntry.h" // IWYU pragma: keep
|
||||
#include "Logfile.h"
|
||||
#include "Logger.h"
|
||||
#include "MonitoringCore.h"
|
||||
|
||||
namespace {
|
||||
// Check memory every N'th new message
|
||||
constexpr unsigned long check_mem_cycle = 1000;
|
||||
} // namespace
|
||||
|
||||
int num_cached_log_messages = 0;
|
||||
|
||||
LogCache::LogCache(MonitoringCore *mc, unsigned long max_cached_messages)
|
||||
: _mc(mc)
|
||||
, _max_cached_messages(max_cached_messages)
|
||||
, _num_at_last_check(0) {
|
||||
update();
|
||||
}
|
||||
|
||||
#ifdef CMC
|
||||
void LogCache::setMaxCachedMessages(unsigned long m) {
|
||||
if (m != _max_cached_messages) {
|
||||
Notice(logger())
|
||||
<< "changing maximum number of messages for log file cache to "
|
||||
<< m;
|
||||
_max_cached_messages = m;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
void LogCache::update() {
|
||||
if (!_logfiles.empty() &&
|
||||
_mc->last_logfile_rotation() <= _last_index_update) {
|
||||
return;
|
||||
}
|
||||
|
||||
Informational(logger()) << "updating log file index";
|
||||
|
||||
_logfiles.clear();
|
||||
num_cached_log_messages = 0;
|
||||
|
||||
_last_index_update = std::chrono::system_clock::now();
|
||||
// We need to find all relevant logfiles. This includes directory, the
|
||||
// current nagios.log and all files in the archive.
|
||||
addToIndex(
|
||||
std::make_unique<Logfile>(_mc, this, _mc->historyFilePath(), true));
|
||||
|
||||
fs::path dirpath = _mc->logArchivePath();
|
||||
try {
|
||||
for (const auto &entry : fs::directory_iterator(dirpath)) {
|
||||
addToIndex(
|
||||
std::make_unique<Logfile>(_mc, this, entry.path(), false));
|
||||
}
|
||||
} catch (const fs::filesystem_error &e) {
|
||||
Warning(logger()) << "updating log file index: " << e.what();
|
||||
}
|
||||
|
||||
if (_logfiles.empty()) {
|
||||
Notice(logger()) << "no log file found, not even "
|
||||
<< _mc->historyFilePath();
|
||||
}
|
||||
}
|
||||
|
||||
void LogCache::addToIndex(std::unique_ptr<Logfile> logfile) {
|
||||
time_t since = logfile->since();
|
||||
if (since == 0) {
|
||||
return;
|
||||
}
|
||||
// make sure that no entry with that 'since' is existing yet. Under normal
|
||||
// circumstances this never happens, but the user might have copied files
|
||||
// around.
|
||||
if (_logfiles.find(since) != _logfiles.end()) {
|
||||
Warning(logger()) << "ignoring duplicate log file " << logfile->path();
|
||||
return;
|
||||
}
|
||||
|
||||
_logfiles.emplace(since, std::move(logfile));
|
||||
}
|
||||
|
||||
/* This method is called each time a log message is loaded
|
||||
into memory. If the number of messages loaded in memory
|
||||
is to large, memory will be freed by flushing logfiles
|
||||
and message not needed by the current query.
|
||||
|
||||
The parameters to this method reflect the current query,
|
||||
not the messages that just has been loaded.
|
||||
*/
|
||||
void LogCache::logLineHasBeenAdded(Logfile *logfile, unsigned logclasses) {
|
||||
if (static_cast<unsigned long>(++num_cached_log_messages) <=
|
||||
_max_cached_messages) {
|
||||
return; // current message count still allowed, everything ok
|
||||
}
|
||||
|
||||
/* Memory checking an freeing consumes CPU ressources. We save
|
||||
ressources, by avoiding to make the memory check each time
|
||||
a new message is loaded when being in a sitation where no
|
||||
memory can be freed. We do this by suppressing the check when
|
||||
the number of messages loaded into memory has not grown
|
||||
by at least check_mem_cycle messages */
|
||||
if (static_cast<unsigned long>(num_cached_log_messages) <
|
||||
_num_at_last_check + check_mem_cycle) {
|
||||
return; // Do not check this time
|
||||
}
|
||||
|
||||
// [1] Begin by deleting old logfiles
|
||||
// Begin deleting with the oldest logfile available
|
||||
logfiles_t::iterator it;
|
||||
for (it = _logfiles.begin(); it != _logfiles.end(); ++it) {
|
||||
if (it->second.get() == logfile) {
|
||||
// Do not touch the logfile the Query is currently accessing
|
||||
break;
|
||||
}
|
||||
if (it->second->size() > 0) {
|
||||
num_cached_log_messages -= it->second->size();
|
||||
it->second->flush(); // drop all messages of that file
|
||||
if (static_cast<unsigned long>(num_cached_log_messages) <=
|
||||
_max_cached_messages) {
|
||||
// remember the number of log messages in cache when
|
||||
// the last memory-release was done. No further
|
||||
// release-check shall be done until that number changes.
|
||||
_num_at_last_check = num_cached_log_messages;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
// The end of this loop must be reached by 'break'. At least one logfile
|
||||
// must be the current logfile. So now 'it' points to the current logfile.
|
||||
// We save that pointer for later.
|
||||
auto queryit = it;
|
||||
|
||||
// [2] Delete message classes irrelevent to current query
|
||||
// Starting from the current logfile (wo broke out of the
|
||||
// previous loop just when 'it' pointed to that)
|
||||
for (; it != _logfiles.end(); ++it) {
|
||||
if (it->second->size() > 0 &&
|
||||
(it->second->classesRead() & ~logclasses) != 0) {
|
||||
Debug(logger()) << "freeing classes " << ~logclasses << " of file "
|
||||
<< it->second->path();
|
||||
// flush only messages not needed for current query
|
||||
long freed = it->second->freeMessages(~logclasses);
|
||||
num_cached_log_messages -= freed;
|
||||
if (static_cast<unsigned long>(num_cached_log_messages) <=
|
||||
_max_cached_messages) {
|
||||
_num_at_last_check = num_cached_log_messages;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// [3] Flush newest logfiles
|
||||
// If there are still too many messages loaded, continue
|
||||
// flushing logfiles from the oldest to the newest starting
|
||||
// at the file just after (i.e. newer than) the current logfile
|
||||
for (it = ++queryit; it != _logfiles.end(); ++it) {
|
||||
if (it->second->size() > 0) {
|
||||
Debug(logger()) << "flush newer log, " << it->second->size()
|
||||
<< " number of entries";
|
||||
num_cached_log_messages -= it->second->size();
|
||||
it->second->flush();
|
||||
if (static_cast<unsigned long>(num_cached_log_messages) <=
|
||||
_max_cached_messages) {
|
||||
_num_at_last_check = num_cached_log_messages;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
_num_at_last_check = num_cached_log_messages;
|
||||
// If we reach this point, no more logfiles can be unloaded,
|
||||
// despite the fact that there are still too many messages
|
||||
// loaded.
|
||||
|
||||
Debug(logger()) << "cannot unload more messages, still "
|
||||
<< num_cached_log_messages << " loaded (max is "
|
||||
<< _max_cached_messages << ")";
|
||||
}
|
||||
|
||||
Logger *LogCache::logger() const { return _mc->loggerLivestatus(); }
|
||||
64
src/LogCache.h
Normal file
64
src/LogCache.h
Normal file
@@ -0,0 +1,64 @@
|
||||
// +------------------------------------------------------------------+
|
||||
// | ____ _ _ __ __ _ __ |
|
||||
// | / ___| |__ ___ ___| | __ | \/ | |/ / |
|
||||
// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / |
|
||||
// | | |___| | | | __/ (__| < | | | | . \ |
|
||||
// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ |
|
||||
// | |
|
||||
// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de |
|
||||
// +------------------------------------------------------------------+
|
||||
//
|
||||
// This file is part of Check_MK.
|
||||
// The official homepage is at http://mathias-kettner.de/check_mk.
|
||||
//
|
||||
// check_mk is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation in version 2. check_mk is distributed
|
||||
// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with-
|
||||
// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
// PARTICULAR PURPOSE. See the GNU General Public License for more de-
|
||||
// tails. You should have received a copy of the GNU General Public
|
||||
// License along with GNU Make; see the file COPYING. If not, write
|
||||
// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
// Boston, MA 02110-1301 USA.
|
||||
|
||||
#ifndef LogCache_h
|
||||
#define LogCache_h
|
||||
|
||||
#include "config.h" // IWYU pragma: keep
|
||||
#include <chrono>
|
||||
#include <ctime>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <mutex>
|
||||
class Logfile;
|
||||
class Logger;
|
||||
class MonitoringCore;
|
||||
|
||||
using logfiles_t = std::map<time_t, std::unique_ptr<Logfile>>;
|
||||
|
||||
class LogCache {
|
||||
public:
|
||||
std::mutex _lock;
|
||||
|
||||
LogCache(MonitoringCore *mc, unsigned long max_cached_messages);
|
||||
#ifdef CMC
|
||||
void setMaxCachedMessages(unsigned long m);
|
||||
#endif
|
||||
void logLineHasBeenAdded(Logfile *logfile, unsigned logclasses);
|
||||
void update();
|
||||
auto begin() { return _logfiles.begin(); }
|
||||
auto end() { return _logfiles.end(); }
|
||||
|
||||
private:
|
||||
MonitoringCore *const _mc;
|
||||
unsigned long _max_cached_messages;
|
||||
unsigned long _num_at_last_check;
|
||||
logfiles_t _logfiles;
|
||||
std::chrono::system_clock::time_point _last_index_update;
|
||||
|
||||
void addToIndex(std::unique_ptr<Logfile> logfile);
|
||||
[[nodiscard]] Logger *logger() const;
|
||||
};
|
||||
|
||||
#endif // LogCache_h
|
||||
417
src/LogEntry.cc
Normal file
417
src/LogEntry.cc
Normal file
@@ -0,0 +1,417 @@
|
||||
// +------------------------------------------------------------------+
|
||||
// | ____ _ _ __ __ _ __ |
|
||||
// | / ___| |__ ___ ___| | __ | \/ | |/ / |
|
||||
// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / |
|
||||
// | | |___| | | | __/ (__| < | | | | . \ |
|
||||
// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ |
|
||||
// | |
|
||||
// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de |
|
||||
// +------------------------------------------------------------------+
|
||||
//
|
||||
// This file is part of Check_MK.
|
||||
// The official homepage is at http://mathias-kettner.de/check_mk.
|
||||
//
|
||||
// check_mk is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation in version 2. check_mk is distributed
|
||||
// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with-
|
||||
// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
// PARTICULAR PURPOSE. See the GNU General Public License for more de-
|
||||
// tails. You should have received a copy of the GNU General Public
|
||||
// License along with GNU Make; see the file COPYING. If not, write
|
||||
// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
// Boston, MA 02110-1301 USA.
|
||||
|
||||
#include "LogEntry.h"
|
||||
#include <cstdlib>
|
||||
#include <stdexcept>
|
||||
#include <unordered_map>
|
||||
#include <utility>
|
||||
#include "MonitoringCore.h"
|
||||
|
||||
// 0123456789012345678901234567890
|
||||
// [1234567890] FOO BAR: blah blah
|
||||
static constexpr size_t timestamp_prefix_length = 13;
|
||||
|
||||
// TODO(sp) Fix classifyLogMessage() below to always set all fields and remove
|
||||
// this set-me-to-zero-to-be-sure-block.
|
||||
LogEntry::LogEntry(MonitoringCore *mc, size_t lineno, std::string line)
|
||||
: _lineno(static_cast<int32_t>(lineno))
|
||||
, _complete(std::move(line))
|
||||
, _state(0)
|
||||
, _attempt(0)
|
||||
, _host(nullptr)
|
||||
, _service(nullptr)
|
||||
, _contact(nullptr) {
|
||||
// pointer to options (everything after ':')
|
||||
size_t pos = _complete.find(':');
|
||||
if (pos != std::string::npos) {
|
||||
pos = _complete.find_first_not_of(' ', pos + 1);
|
||||
}
|
||||
if (pos == std::string::npos) {
|
||||
pos = _complete.size();
|
||||
}
|
||||
_options = &_complete[pos];
|
||||
|
||||
try {
|
||||
if (_complete.size() < timestamp_prefix_length || _complete[0] != '[' ||
|
||||
_complete[11] != ']' || _complete[12] != ' ') {
|
||||
throw std::invalid_argument("timestamp delimiter");
|
||||
}
|
||||
_time = std::stoi(_complete.substr(1, 10));
|
||||
} catch (const std::logic_error &e) {
|
||||
_logclass = Class::invalid;
|
||||
_type = LogEntryType::none;
|
||||
return; // ignore invalid lines silently
|
||||
}
|
||||
|
||||
classifyLogMessage();
|
||||
applyWorkarounds();
|
||||
updateReferences(mc);
|
||||
}
|
||||
|
||||
bool LogEntry::assign(Param par, const std::string &field) {
|
||||
switch (par) {
|
||||
case Param::HostName:
|
||||
this->_host_name = field;
|
||||
break;
|
||||
case Param::SvcDesc:
|
||||
this->_svc_desc = field;
|
||||
break;
|
||||
case Param::HostState:
|
||||
this->_state = static_cast<int>(parseHostState(field));
|
||||
break;
|
||||
case Param::ServiceState:
|
||||
this->_state = static_cast<int>(parseServiceState(field));
|
||||
break;
|
||||
case Param::State:
|
||||
this->_state = atoi(field.c_str());
|
||||
break;
|
||||
case Param::StateType:
|
||||
this->_state_type = field;
|
||||
break;
|
||||
case Param::Attempt:
|
||||
this->_attempt = atoi(field.c_str());
|
||||
break;
|
||||
case Param::Comment:
|
||||
this->_comment = field;
|
||||
break;
|
||||
case Param::CommandName:
|
||||
this->_command_name = field;
|
||||
break;
|
||||
case Param::ContactName:
|
||||
this->_contact_name = field;
|
||||
break;
|
||||
case Param::CheckOutput:
|
||||
this->_check_output = field;
|
||||
break;
|
||||
}
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
std::vector<LogEntry::LogDef> LogEntry::log_definitions{
|
||||
LogDef{"INITIAL HOST STATE",
|
||||
Class::state,
|
||||
LogEntryType::state_host_initial,
|
||||
{Param::HostName, Param::HostState, Param::StateType, Param::Attempt,
|
||||
Param::CheckOutput}},
|
||||
////////////////
|
||||
LogDef{"CURRENT HOST STATE",
|
||||
Class::state,
|
||||
LogEntryType::state_host,
|
||||
{Param::HostName, Param::HostState, Param::StateType, Param::Attempt,
|
||||
Param::CheckOutput}},
|
||||
////////////////
|
||||
LogDef{"HOST ALERT",
|
||||
Class::alert,
|
||||
LogEntryType::alert_host,
|
||||
{Param::HostName, Param::HostState, Param::StateType, Param::Attempt,
|
||||
Param::CheckOutput}},
|
||||
////////////////
|
||||
LogDef{"HOST DOWNTIME ALERT",
|
||||
Class::alert,
|
||||
LogEntryType::downtime_alert_host,
|
||||
{Param::HostName, Param::StateType, Param::Comment}},
|
||||
////////////////
|
||||
LogDef{"HOST ACKNOWLEDGE ALERT",
|
||||
Class::alert,
|
||||
LogEntryType::acknowledge_alert_host,
|
||||
{Param::HostName, Param::StateType, Param::ContactName,
|
||||
Param::Comment}},
|
||||
////////////////
|
||||
LogDef{"HOST FLAPPING ALERT",
|
||||
Class::alert,
|
||||
LogEntryType::flapping_host,
|
||||
{Param::HostName, Param::StateType, Param::Comment}},
|
||||
////////////////
|
||||
LogDef{"INITIAL SERVICE STATE",
|
||||
Class::state,
|
||||
LogEntryType::state_service_initial,
|
||||
{Param::HostName, Param::SvcDesc, Param::ServiceState,
|
||||
Param::StateType, Param::Attempt, Param::CheckOutput}},
|
||||
////////////////
|
||||
LogDef{"CURRENT SERVICE STATE",
|
||||
Class::state,
|
||||
LogEntryType::state_service,
|
||||
{Param::HostName, Param::SvcDesc, Param::ServiceState,
|
||||
Param::StateType, Param::Attempt, Param::CheckOutput}},
|
||||
////////////////
|
||||
LogDef{"SERVICE ALERT",
|
||||
Class::alert,
|
||||
LogEntryType::alert_service,
|
||||
{Param::HostName, Param::SvcDesc, Param::ServiceState,
|
||||
Param::StateType, Param::Attempt, Param::CheckOutput}},
|
||||
////////////////
|
||||
LogDef{"SERVICE DOWNTIME ALERT",
|
||||
Class::alert,
|
||||
LogEntryType::downtime_alert_service,
|
||||
{Param::HostName, Param::SvcDesc, Param::StateType, Param::Comment}},
|
||||
////////////////
|
||||
LogDef{"SERVICE ACKNOWLEDGE ALERT",
|
||||
Class::alert,
|
||||
LogEntryType::acknowledge_alert_service,
|
||||
{Param::HostName, Param::SvcDesc, Param::StateType,
|
||||
Param::ContactName, Param::Comment}},
|
||||
////////////////
|
||||
LogDef{"SERVICE FLAPPING ALERT",
|
||||
Class::alert,
|
||||
LogEntryType::flapping_service,
|
||||
{Param::HostName, Param::SvcDesc, Param::StateType, Param::Comment}},
|
||||
////////////////
|
||||
LogDef{"TIMEPERIOD TRANSITION",
|
||||
Class::state,
|
||||
LogEntryType::timeperiod_transition,
|
||||
{}},
|
||||
////////////////
|
||||
LogDef{"HOST NOTIFICATION",
|
||||
Class::hs_notification,
|
||||
LogEntryType::none,
|
||||
{Param::ContactName, Param::HostName, Param::StateType,
|
||||
Param::CommandName, Param::CheckOutput}},
|
||||
////////////////
|
||||
LogDef{"SERVICE NOTIFICATION",
|
||||
Class::hs_notification,
|
||||
LogEntryType::none,
|
||||
{Param::ContactName, Param::HostName, Param::SvcDesc,
|
||||
Param::StateType, Param::CommandName, Param::CheckOutput}},
|
||||
////////////////
|
||||
LogDef{"HOST NOTIFICATION RESULT",
|
||||
Class::hs_notification,
|
||||
LogEntryType::none,
|
||||
{Param::ContactName, Param::HostName, Param::StateType,
|
||||
Param::CommandName, Param::CheckOutput, Param::Comment}},
|
||||
////////////////
|
||||
LogDef{
|
||||
"SERVICE NOTIFICATION RESULT",
|
||||
Class::hs_notification,
|
||||
LogEntryType::none,
|
||||
{Param::ContactName, Param::HostName, Param::SvcDesc, Param::StateType,
|
||||
Param::CommandName, Param::CheckOutput, Param::Comment}},
|
||||
////////////////
|
||||
LogDef{"HOST NOTIFICATION PROGRESS",
|
||||
Class::hs_notification,
|
||||
LogEntryType::none,
|
||||
{Param::ContactName, Param::HostName, Param::StateType,
|
||||
Param::CommandName, Param::CheckOutput}},
|
||||
////////////////
|
||||
LogDef{"SERVICE NOTIFICATION PROGRESS",
|
||||
Class::hs_notification,
|
||||
LogEntryType::none,
|
||||
{Param::ContactName, Param::HostName, Param::SvcDesc,
|
||||
Param::StateType, Param::CommandName, Param::CheckOutput}},
|
||||
////////////////
|
||||
LogDef{"HOST ALERT HANDLER STARTED",
|
||||
Class::alert_handlers,
|
||||
LogEntryType::none,
|
||||
{Param::HostName, Param::CommandName}},
|
||||
////////////////
|
||||
LogDef{"SERVICE ALERT HANDLER STARTED",
|
||||
Class::alert_handlers,
|
||||
LogEntryType::none,
|
||||
{Param::HostName, Param::SvcDesc, Param::CommandName}},
|
||||
////////////////
|
||||
LogDef{"HOST ALERT HANDLER STOPPED",
|
||||
Class::alert_handlers,
|
||||
LogEntryType::none,
|
||||
{Param::HostName, Param::CommandName, Param::ServiceState,
|
||||
Param::CheckOutput}},
|
||||
////////////////
|
||||
LogDef{"SERVICE ALERT HANDLER STOPPED",
|
||||
Class::alert_handlers,
|
||||
LogEntryType::none,
|
||||
{Param::HostName, Param::SvcDesc, Param::CommandName,
|
||||
Param::ServiceState, Param::CheckOutput}},
|
||||
////////////////
|
||||
LogDef{"PASSIVE SERVICE CHECK",
|
||||
Class::passivecheck,
|
||||
LogEntryType::none,
|
||||
{Param::HostName, Param::SvcDesc, Param::State, Param::CheckOutput}},
|
||||
////////////////
|
||||
LogDef{"PASSIVE HOST CHECK",
|
||||
Class::passivecheck,
|
||||
LogEntryType::none,
|
||||
{Param::HostName, Param::State, Param::CheckOutput}},
|
||||
////////////////
|
||||
LogDef{"EXTERNAL COMMAND", Class::ext_command, LogEntryType::none, {}}};
|
||||
|
||||
// A bit verbose, but we avoid unnecessary string copies below.
|
||||
void LogEntry::classifyLogMessage() {
|
||||
for (const auto &def : log_definitions) {
|
||||
if (textStartsWith(def.prefix) &&
|
||||
_complete.compare(timestamp_prefix_length + def.prefix.size(), 2,
|
||||
": ") == 0) {
|
||||
_text = &def.prefix[0];
|
||||
_logclass = def.log_class;
|
||||
_type = def.log_type;
|
||||
// TODO(sp) Use boost::tokenizer instead of this index fiddling
|
||||
size_t pos = timestamp_prefix_length + def.prefix.size() + 2;
|
||||
for (Param par : def.params) {
|
||||
size_t sep_pos = _complete.find(';', pos);
|
||||
size_t end_pos =
|
||||
sep_pos == std::string::npos ? _complete.size() : sep_pos;
|
||||
assign(par, _complete.substr(pos, end_pos - pos));
|
||||
pos = sep_pos == std::string::npos ? _complete.size()
|
||||
: (sep_pos + 1);
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
_text = &_complete[timestamp_prefix_length];
|
||||
if (textStartsWith("LOG VERSION: 2.0")) {
|
||||
_logclass = Class::program;
|
||||
_type = LogEntryType::log_version;
|
||||
return;
|
||||
}
|
||||
if (textStartsWith("logging initial states") ||
|
||||
textStartsWith("logging intitial states")) {
|
||||
_logclass = Class::program;
|
||||
_type = LogEntryType::log_initial_states;
|
||||
return;
|
||||
}
|
||||
if (textContains("starting...") || textContains("active mode...")) {
|
||||
_logclass = Class::program;
|
||||
_type = LogEntryType::core_starting;
|
||||
return;
|
||||
}
|
||||
if (textContains("shutting down...") || textContains("Bailing out") ||
|
||||
textContains("standby mode...")) {
|
||||
_logclass = Class::program;
|
||||
_type = LogEntryType::core_stopping;
|
||||
return;
|
||||
}
|
||||
if (textContains("restarting...")) {
|
||||
_logclass = Class::program;
|
||||
_type = LogEntryType::none;
|
||||
return;
|
||||
}
|
||||
_logclass = Class::info;
|
||||
_type = LogEntryType::none;
|
||||
}
|
||||
|
||||
bool LogEntry::textStartsWith(const std::string &what) {
|
||||
return _complete.compare(timestamp_prefix_length, what.size(), what) == 0;
|
||||
}
|
||||
|
||||
bool LogEntry::textContains(const std::string &what) {
|
||||
return _complete.find(what, timestamp_prefix_length) != std::string::npos;
|
||||
}
|
||||
|
||||
// The NotifyHelper class has a long, tragic history: Through a long series of
|
||||
// commits, it suffered from spelling mistakes like "HOST_NOTIFICATION" or "HOST
|
||||
// NOTIFICATION" (without a colon), parameter lists not matching the
|
||||
// corresponding format strings, and last but not least wrong ordering of
|
||||
// fields. The net result of this tragedy is that due to legacy reasons, we have
|
||||
// to support parsing an incorrect ordering of "state type" and "command name"
|
||||
// fields. :-P
|
||||
void LogEntry::applyWorkarounds() {
|
||||
if (_logclass != Class::hs_notification || // no need for any workaround
|
||||
_state_type.empty()) { // extremely broken line
|
||||
return;
|
||||
}
|
||||
|
||||
if (_state_type == "check-mk-notify") {
|
||||
// Ooops, we encounter one of our own buggy lines...
|
||||
std::swap(_state_type, _command_name);
|
||||
}
|
||||
|
||||
if (_state_type.empty()) {
|
||||
return; // extremely broken line, even after a potential swap
|
||||
}
|
||||
|
||||
_state = _svc_desc.empty()
|
||||
? static_cast<int>(parseHostState(_state_type))
|
||||
: static_cast<int>(parseServiceState(_state_type));
|
||||
}
|
||||
|
||||
namespace {
|
||||
// Ugly: Depending on where we're called, the actual state type can be in
|
||||
// parentheses at the end, e.g. "ALERTHANDLER (OK)".
|
||||
std::string extractStateType(const std::string &str) {
|
||||
if (!str.empty() && str[str.size() - 1] == ')') {
|
||||
size_t lparen = str.rfind('(');
|
||||
if (lparen != std::string::npos) {
|
||||
return str.substr(lparen + 1, str.size() - lparen - 2);
|
||||
}
|
||||
}
|
||||
return str;
|
||||
}
|
||||
|
||||
std::unordered_map<std::string, ServiceState> serviceStateTypes{
|
||||
// normal states
|
||||
{"OK", ServiceState::ok},
|
||||
{"WARNING", ServiceState::warning},
|
||||
{"CRITICAL", ServiceState::critical},
|
||||
{"UNKNOWN", ServiceState::unknown},
|
||||
// states from "... ALERT"/"... NOTIFICATION"
|
||||
{"RECOVERY", ServiceState::ok}};
|
||||
|
||||
std::unordered_map<std::string, HostState> hostStateTypes{
|
||||
// normal states
|
||||
{"UP", HostState::up},
|
||||
{"DOWN", HostState::down},
|
||||
{"UNREACHABLE", HostState::unreachable},
|
||||
// states from "... ALERT"/"... NOTIFICATION"
|
||||
{"RECOVERY", HostState::up},
|
||||
// states from "... ALERT HANDLER STOPPED" and "(HOST|SERVICE) NOTIFICATION
|
||||
// (RESULT|PROGRESS)"
|
||||
{"OK", HostState::up},
|
||||
{"WARNING", HostState::down},
|
||||
{"CRITICAL", HostState::unreachable},
|
||||
{"UNKNOWN", HostState::up}};
|
||||
} // namespace
|
||||
|
||||
ServiceState LogEntry::parseServiceState(const std::string &str) {
|
||||
auto it = serviceStateTypes.find(extractStateType(str));
|
||||
return it == serviceStateTypes.end() ? ServiceState::ok : it->second;
|
||||
}
|
||||
|
||||
HostState LogEntry::parseHostState(const std::string &str) {
|
||||
auto it = hostStateTypes.find(extractStateType(str));
|
||||
return it == hostStateTypes.end() ? HostState::up : it->second;
|
||||
}
|
||||
|
||||
unsigned LogEntry::updateReferences(MonitoringCore *mc) {
|
||||
unsigned updated = 0;
|
||||
if (!_host_name.empty()) {
|
||||
// Older Nagios headers are not const-correct... :-P
|
||||
_host = find_host(const_cast<char *>(_host_name.c_str()));
|
||||
updated++;
|
||||
}
|
||||
if (!_svc_desc.empty()) {
|
||||
// Older Nagios headers are not const-correct... :-P
|
||||
_service = find_service(const_cast<char *>(_host_name.c_str()),
|
||||
const_cast<char *>(_svc_desc.c_str()));
|
||||
updated++;
|
||||
}
|
||||
if (!_contact_name.empty()) {
|
||||
// Older Nagios headers are not const-correct... :-P
|
||||
_contact = find_contact(const_cast<char *>(_contact_name.c_str()));
|
||||
updated++;
|
||||
}
|
||||
if (!_command_name.empty()) {
|
||||
_command = mc->find_command(_command_name);
|
||||
updated++;
|
||||
}
|
||||
return updated;
|
||||
}
|
||||
166
src/LogEntry.h
Normal file
166
src/LogEntry.h
Normal file
@@ -0,0 +1,166 @@
|
||||
// +------------------------------------------------------------------+
|
||||
// | ____ _ _ __ __ _ __ |
|
||||
// | / ___| |__ ___ ___| | __ | \/ | |/ / |
|
||||
// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / |
|
||||
// | | |___| | | | __/ (__| < | | | | . \ |
|
||||
// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ |
|
||||
// | |
|
||||
// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de |
|
||||
// +------------------------------------------------------------------+
|
||||
//
|
||||
// This file is part of Check_MK.
|
||||
// The official homepage is at http://mathias-kettner.de/check_mk.
|
||||
//
|
||||
// check_mk is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation in version 2. check_mk is distributed
|
||||
// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with-
|
||||
// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
// PARTICULAR PURPOSE. See the GNU General Public License for more de-
|
||||
// tails. You should have received a copy of the GNU General Public
|
||||
// License along with GNU Make; see the file COPYING. If not, write
|
||||
// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
// Boston, MA 02110-1301 USA.
|
||||
|
||||
#ifndef LogEntry_h
|
||||
#define LogEntry_h
|
||||
|
||||
#include "config.h" // IWYU pragma: keep
|
||||
#include <cstdint>
|
||||
#include <ctime>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include "MonitoringCore.h"
|
||||
#include "nagios.h"
|
||||
|
||||
enum class ServiceState { ok = 0, warning = 1, critical = 2, unknown = 3 };
|
||||
|
||||
inline double badness(ServiceState state) {
|
||||
// unknown is effectively between warning and critical
|
||||
return state == ServiceState::unknown
|
||||
? (static_cast<double>(ServiceState::warning) +
|
||||
static_cast<double>(ServiceState::critical)) /
|
||||
2.0
|
||||
: static_cast<double>(state);
|
||||
}
|
||||
|
||||
inline bool worse(ServiceState state1, ServiceState state2) {
|
||||
return badness(state1) > badness(state2);
|
||||
}
|
||||
|
||||
enum class HostState { up = 0, down = 1, unreachable = 2 };
|
||||
|
||||
inline double badness(HostState state) {
|
||||
// unreachable is effectively between up and down
|
||||
return state == HostState::unreachable
|
||||
? (static_cast<double>(HostState::up) +
|
||||
static_cast<double>(HostState::down)) /
|
||||
2.0
|
||||
: static_cast<double>(state);
|
||||
}
|
||||
|
||||
inline bool worse(HostState state1, HostState state2) {
|
||||
return badness(state1) > badness(state2);
|
||||
}
|
||||
|
||||
enum class LogEntryType {
|
||||
none,
|
||||
alert_host,
|
||||
alert_service,
|
||||
downtime_alert_host,
|
||||
downtime_alert_service,
|
||||
state_host,
|
||||
state_host_initial,
|
||||
state_service,
|
||||
state_service_initial,
|
||||
flapping_host,
|
||||
flapping_service,
|
||||
timeperiod_transition,
|
||||
core_starting,
|
||||
core_stopping,
|
||||
log_version,
|
||||
log_initial_states,
|
||||
acknowledge_alert_host,
|
||||
acknowledge_alert_service
|
||||
};
|
||||
|
||||
class LogEntry {
|
||||
public:
|
||||
enum class Class {
|
||||
info = 0, // all messages not in any other class
|
||||
alert = 1, // alerts: the change service/host state
|
||||
program = 2, // important programm events (restart, ...)
|
||||
hs_notification = 3, // host/service notifications
|
||||
passivecheck = 4, // passive checks
|
||||
ext_command = 5, // external commands
|
||||
state = 6, // initial or current states
|
||||
text = 7, // specific text passages
|
||||
alert_handlers = 8, // Started and stopped alert handlers
|
||||
|
||||
// TODO(sp): This class sets different logclasses on match -> fix this
|
||||
invalid = 0x7fffffff // never stored
|
||||
};
|
||||
static constexpr uint32_t all_classes = 0xffffU;
|
||||
|
||||
// TODO(sp): Wrong type, caused by TableLog accessing it via
|
||||
// OffsetIntColumn, should be size_t
|
||||
int _lineno; // line number in file
|
||||
time_t _time;
|
||||
Class _logclass;
|
||||
LogEntryType _type;
|
||||
std::string _complete; // copy of complete unsplit message
|
||||
const char *_options; // points into _complete after ':'
|
||||
const char *_text; // points into _complete or into static data
|
||||
std::string _host_name;
|
||||
std::string _svc_desc;
|
||||
std::string _command_name;
|
||||
std::string _contact_name;
|
||||
int _state;
|
||||
std::string _state_type;
|
||||
int _attempt;
|
||||
std::string _check_output;
|
||||
std::string _comment;
|
||||
|
||||
host *_host;
|
||||
service *_service;
|
||||
contact *_contact;
|
||||
Command _command;
|
||||
|
||||
// NOTE: line gets modified!
|
||||
LogEntry(MonitoringCore *mc, size_t lineno, std::string line);
|
||||
unsigned updateReferences(MonitoringCore *mc);
|
||||
static ServiceState parseServiceState(const std::string &str);
|
||||
static HostState parseHostState(const std::string &str);
|
||||
|
||||
private:
|
||||
enum class Param {
|
||||
HostName,
|
||||
SvcDesc,
|
||||
CommandName,
|
||||
ContactName,
|
||||
HostState,
|
||||
ServiceState,
|
||||
State,
|
||||
StateType,
|
||||
Attempt,
|
||||
Comment,
|
||||
CheckOutput
|
||||
};
|
||||
|
||||
struct LogDef {
|
||||
std::string prefix;
|
||||
Class log_class;
|
||||
LogEntryType log_type;
|
||||
std::vector<Param> params;
|
||||
};
|
||||
|
||||
static std::vector<LogDef> log_definitions;
|
||||
|
||||
bool assign(Param par, const std::string &field);
|
||||
void applyWorkarounds();
|
||||
void classifyLogMessage();
|
||||
bool textStartsWith(const std::string &what);
|
||||
bool textContains(const std::string &what);
|
||||
};
|
||||
|
||||
#endif // LogEntry_h
|
||||
252
src/Logfile.cc
Normal file
252
src/Logfile.cc
Normal file
@@ -0,0 +1,252 @@
|
||||
// +------------------------------------------------------------------+
|
||||
// | ____ _ _ __ __ _ __ |
|
||||
// | / ___| |__ ___ ___| | __ | \/ | |/ / |
|
||||
// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / |
|
||||
// | | |___| | | | __/ (__| < | | | | . \ |
|
||||
// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ |
|
||||
// | |
|
||||
// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de |
|
||||
// +------------------------------------------------------------------+
|
||||
//
|
||||
// This file is part of Check_MK.
|
||||
// The official homepage is at http://mathias-kettner.de/check_mk.
|
||||
//
|
||||
// check_mk is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation in version 2. check_mk is distributed
|
||||
// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with-
|
||||
// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
// PARTICULAR PURPOSE. See the GNU General Public License for more de-
|
||||
// tails. You should have received a copy of the GNU General Public
|
||||
// License along with GNU Make; see the file COPYING. If not, write
|
||||
// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
// Boston, MA 02110-1301 USA.
|
||||
|
||||
// https://github.com/include-what-you-use/include-what-you-use/issues/166
|
||||
// IWYU pragma: no_include <ext/alloc_traits.h>
|
||||
#include "Logfile.h"
|
||||
#include <fcntl.h>
|
||||
#include <cstdlib>
|
||||
#include <sstream>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
#include "LogCache.h"
|
||||
#include "LogEntry.h"
|
||||
#include "Logger.h"
|
||||
#include "MonitoringCore.h"
|
||||
#include "Query.h"
|
||||
#include "Row.h"
|
||||
|
||||
#ifdef CMC
|
||||
#include "cmc.h"
|
||||
#endif
|
||||
|
||||
namespace {
|
||||
time_t firstTimestampOf(const fs::path &path, Logger *logger) {
|
||||
std::ifstream is(path, std::ios::binary);
|
||||
if (!is) {
|
||||
generic_error ge("cannot open logfile " + path.string());
|
||||
Informational(logger) << ge;
|
||||
return 0;
|
||||
}
|
||||
|
||||
char line[12];
|
||||
is.read(line, sizeof(line));
|
||||
if (!is) {
|
||||
return 0; // ignoring. might be empty
|
||||
}
|
||||
|
||||
if (line[0] != '[' || line[11] != ']') {
|
||||
Informational(logger) << "ignoring logfile '" << path
|
||||
<< "': does not begin with '[123456789] '";
|
||||
return 0;
|
||||
}
|
||||
|
||||
line[11] = 0;
|
||||
return atoi(line + 1);
|
||||
}
|
||||
} // namespace
|
||||
|
||||
Logfile::Logfile(MonitoringCore *mc, LogCache *logcache, fs::path path,
|
||||
bool watch)
|
||||
: _mc(mc)
|
||||
, _logcache(logcache)
|
||||
, _path(std::move(path))
|
||||
, _since(firstTimestampOf(_path, logger()))
|
||||
, _watch(watch)
|
||||
, _read_pos{}
|
||||
, _lineno(0)
|
||||
#ifdef CMC
|
||||
, _world(nullptr)
|
||||
#endif
|
||||
, _logclasses_read(0) {
|
||||
}
|
||||
|
||||
void Logfile::flush() {
|
||||
_entries.clear();
|
||||
_logclasses_read = 0;
|
||||
}
|
||||
|
||||
void Logfile::load(unsigned logclasses) {
|
||||
unsigned missing_types = logclasses & ~_logclasses_read;
|
||||
// The current logfile has the _watch flag set to true.
|
||||
// In that case, if the logfile has grown, we need to
|
||||
// load the rest of the file, even if no logclasses
|
||||
// are missing.
|
||||
if (_watch) {
|
||||
FILE *file = fopen(_path.c_str(), "r");
|
||||
if (file == nullptr) {
|
||||
generic_error ge("cannot open logfile " + _path.string());
|
||||
Informational(logger()) << ge;
|
||||
return;
|
||||
}
|
||||
// If we read this file for the first time, we initialize
|
||||
// the current file position to 0
|
||||
if (_lineno == 0) {
|
||||
fgetpos(file, &_read_pos);
|
||||
}
|
||||
|
||||
// file might have grown. Read all classes that we already
|
||||
// have read to the end of the file
|
||||
if (_logclasses_read != 0U) {
|
||||
fsetpos(file, &_read_pos); // continue at previous end
|
||||
loadRange(file, _logclasses_read, logclasses);
|
||||
fgetpos(file, &_read_pos);
|
||||
}
|
||||
if (missing_types != 0U) {
|
||||
fseek(file, 0, SEEK_SET);
|
||||
_lineno = 0;
|
||||
loadRange(file, missing_types, logclasses);
|
||||
_logclasses_read |= missing_types;
|
||||
fgetpos(file, &_read_pos); // remember current end of file
|
||||
}
|
||||
fclose(file);
|
||||
} else {
|
||||
if (missing_types == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
FILE *file = fopen(_path.c_str(), "r");
|
||||
if (file == nullptr) {
|
||||
generic_error ge("cannot open logfile " + _path.string());
|
||||
Informational(logger()) << ge;
|
||||
return;
|
||||
}
|
||||
|
||||
_lineno = 0;
|
||||
loadRange(file, missing_types, logclasses);
|
||||
_logclasses_read |= missing_types;
|
||||
fclose(file);
|
||||
}
|
||||
}
|
||||
|
||||
void Logfile::loadRange(FILE *file, unsigned missing_types,
|
||||
unsigned logclasses) {
|
||||
std::vector<char> linebuffer(65536);
|
||||
// TODO(sp) We should really use C++ I/O here...
|
||||
while (fgets(&linebuffer[0], static_cast<int>(linebuffer.size()), file) !=
|
||||
nullptr) {
|
||||
if (_lineno >= _mc->maxLinesPerLogFile()) {
|
||||
Error(logger()) << "more than " << _mc->maxLinesPerLogFile()
|
||||
<< " lines in " << _path << ", ignoring the rest!";
|
||||
return;
|
||||
}
|
||||
_lineno++;
|
||||
// remove trailing newline (should be nuked, see above)
|
||||
for (auto &ch : linebuffer) {
|
||||
if (ch == '\0' || ch == '\n') {
|
||||
ch = '\0';
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (processLogLine(_lineno, &linebuffer[0], missing_types)) {
|
||||
_logcache->logLineHasBeenAdded(this, logclasses);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
long Logfile::freeMessages(unsigned logclasses) {
|
||||
long freed = 0;
|
||||
// We have to be careful here: Erasing an element from an associative
|
||||
// container invalidates the iterator pointing to it. The solution is the
|
||||
// usual post-increment idiom, see Scott Meyers' "Effective STL", item 9
|
||||
// ("Choose carefully among erasing options.").
|
||||
for (auto it = _entries.begin(); it != _entries.end();) {
|
||||
if (((1U << static_cast<int>(it->second->_logclass)) & logclasses) !=
|
||||
0U) {
|
||||
_entries.erase(it++);
|
||||
freed++;
|
||||
} else {
|
||||
++it;
|
||||
}
|
||||
}
|
||||
_logclasses_read &= ~logclasses;
|
||||
return freed;
|
||||
}
|
||||
|
||||
bool Logfile::processLogLine(size_t lineno, std::string line,
|
||||
unsigned logclasses) {
|
||||
auto entry = std::make_unique<LogEntry>(_mc, lineno, std::move(line));
|
||||
// ignored invalid lines
|
||||
if (entry->_logclass == LogEntry::Class::invalid) {
|
||||
return false;
|
||||
}
|
||||
if (((1U << static_cast<int>(entry->_logclass)) & logclasses) == 0U) {
|
||||
return false;
|
||||
}
|
||||
uint64_t key = makeKey(entry->_time, entry->_lineno);
|
||||
if (_entries.find(key) != _entries.end()) {
|
||||
// this should never happen. The lineno must be unique!
|
||||
Error(logger()) << "strange duplicate logfile line "
|
||||
<< entry->_complete;
|
||||
return false;
|
||||
}
|
||||
_entries[key] = std::move(entry);
|
||||
return true;
|
||||
}
|
||||
|
||||
const logfile_entries_t *Logfile::getEntriesFor(unsigned logclasses) {
|
||||
// Make sure existing references to objects point to correct world
|
||||
updateReferences();
|
||||
// make sure all messages are present
|
||||
load(logclasses);
|
||||
return &_entries;
|
||||
}
|
||||
|
||||
bool Logfile::answerQueryReverse(Query *query, time_t since, time_t until,
|
||||
unsigned logclasses) {
|
||||
auto entries = getEntriesFor(logclasses);
|
||||
// TODO(sp) Move the stuff below out of this class. Tricky part: makeKey
|
||||
auto it = entries->upper_bound(makeKey(until, 999999999));
|
||||
while (it != entries->begin()) {
|
||||
--it;
|
||||
// end found or limit exceeded?
|
||||
if (it->second->_time < since ||
|
||||
!query->processDataset(Row(it->second.get()))) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
uint64_t Logfile::makeKey(time_t t, size_t lineno) {
|
||||
return (static_cast<uint64_t>(t) << 32) | static_cast<uint64_t>(lineno);
|
||||
}
|
||||
|
||||
void Logfile::updateReferences() {
|
||||
#ifdef CMC
|
||||
// If our references in cached log entries do not point to the currently
|
||||
// active configuration world, then update all references
|
||||
if (_world != g_live_world) {
|
||||
unsigned num = 0;
|
||||
for (auto &entry : _entries) {
|
||||
num += entry.second->updateReferences(_mc);
|
||||
}
|
||||
Notice(logger()) << "updated " << num << " log cache references of "
|
||||
<< _path << " to new world.";
|
||||
_world = g_live_world;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
Logger *Logfile::logger() const { return _mc->loggerLivestatus(); }
|
||||
90
src/Logfile.h
Normal file
90
src/Logfile.h
Normal file
@@ -0,0 +1,90 @@
|
||||
// +------------------------------------------------------------------+
|
||||
// | ____ _ _ __ __ _ __ |
|
||||
// | / ___| |__ ___ ___| | __ | \/ | |/ / |
|
||||
// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / |
|
||||
// | | |___| | | | __/ (__| < | | | | . \ |
|
||||
// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ |
|
||||
// | |
|
||||
// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de |
|
||||
// +------------------------------------------------------------------+
|
||||
//
|
||||
// This file is part of Check_MK.
|
||||
// The official homepage is at http://mathias-kettner.de/check_mk.
|
||||
//
|
||||
// check_mk is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation in version 2. check_mk is distributed
|
||||
// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with-
|
||||
// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
// PARTICULAR PURPOSE. See the GNU General Public License for more de-
|
||||
// tails. You should have received a copy of the GNU General Public
|
||||
// License along with GNU Make; see the file COPYING. If not, write
|
||||
// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
// Boston, MA 02110-1301 USA.
|
||||
|
||||
#ifndef Logfile_h
|
||||
#define Logfile_h
|
||||
|
||||
#include "config.h" // IWYU pragma: keep
|
||||
#include <cstdint>
|
||||
#include <cstdio>
|
||||
#include <ctime>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include "FileSystem.h"
|
||||
class LogCache;
|
||||
class LogEntry;
|
||||
class Logger;
|
||||
class MonitoringCore;
|
||||
class Query;
|
||||
|
||||
#ifdef CMC
|
||||
class World;
|
||||
#endif
|
||||
|
||||
// key is time_t . lineno
|
||||
using logfile_entries_t = std::map<uint64_t, std::unique_ptr<LogEntry>>;
|
||||
|
||||
class Logfile {
|
||||
public:
|
||||
Logfile(MonitoringCore *mc, LogCache *logcache, fs::path path, bool watch);
|
||||
[[nodiscard]] fs::path path() const { return _path; }
|
||||
|
||||
// for tricky protocol between LogCache::logLineHasBeenAdded and this class
|
||||
void flush();
|
||||
[[nodiscard]] time_t since() const { return _since; }
|
||||
[[nodiscard]] unsigned classesRead() const { return _logclasses_read; }
|
||||
[[nodiscard]] size_t size() const { return _entries.size(); }
|
||||
long freeMessages(unsigned logclasses);
|
||||
|
||||
// for TableStateHistory
|
||||
const logfile_entries_t *getEntriesFor(unsigned logclasses);
|
||||
|
||||
// for TableLog::answerQuery
|
||||
bool answerQueryReverse(Query *query, time_t since, time_t until,
|
||||
unsigned logclasses);
|
||||
|
||||
private:
|
||||
MonitoringCore *const _mc;
|
||||
LogCache *const _logcache;
|
||||
const fs::path _path;
|
||||
const time_t _since; // time of first entry
|
||||
const bool _watch; // true only for current logfile
|
||||
fpos_t _read_pos; // read until this position
|
||||
size_t _lineno; // read until this line
|
||||
logfile_entries_t _entries;
|
||||
#ifdef CMC
|
||||
World *_world; // CMC: world our references point into
|
||||
#endif
|
||||
unsigned _logclasses_read; // only these types have been read
|
||||
|
||||
void load(unsigned logclasses);
|
||||
void loadRange(FILE *file, unsigned missing_types, unsigned logclasses);
|
||||
bool processLogLine(size_t lineno, std::string line, unsigned logclasses);
|
||||
uint64_t makeKey(time_t t, size_t lineno);
|
||||
void updateReferences();
|
||||
[[nodiscard]] Logger *logger() const;
|
||||
};
|
||||
|
||||
#endif // Logfile_h
|
||||
192
src/Logger.cc
Normal file
192
src/Logger.cc
Normal file
@@ -0,0 +1,192 @@
|
||||
// +------------------------------------------------------------------+
|
||||
// | ____ _ _ __ __ _ __ |
|
||||
// | / ___| |__ ___ ___| | __ | \/ | |/ / |
|
||||
// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / |
|
||||
// | | |___| | | | __/ (__| < | | | | . \ |
|
||||
// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ |
|
||||
// | |
|
||||
// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de |
|
||||
// +------------------------------------------------------------------+
|
||||
//
|
||||
// This file is part of Check_MK.
|
||||
// The official homepage is at http://mathias-kettner.de/check_mk.
|
||||
//
|
||||
// check_mk is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation in version 2. check_mk is distributed
|
||||
// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with-
|
||||
// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
// PARTICULAR PURPOSE. See the GNU General Public License for more de-
|
||||
// tails. You should have received a copy of the GNU General Public
|
||||
// License along with GNU Make; see the file COPYING. If not, write
|
||||
// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
// Boston, MA 02110-1301 USA.
|
||||
|
||||
#include "Logger.h"
|
||||
#include <cstddef>
|
||||
#include <iostream>
|
||||
#include <utility>
|
||||
#include "ChronoUtils.h"
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
std::ostream &operator<<(std::ostream &os, const LogLevel &c) {
|
||||
return os << static_cast<int>(c);
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
void SimpleFormatter::format(std::ostream &os, const LogRecord &record) {
|
||||
os << FormattedTimePoint(record.getTimePoint()) << //
|
||||
" [" << record.getLevel() << "] " << record.getMessage();
|
||||
}
|
||||
|
||||
SharedStreamHandler::SharedStreamHandler(std::mutex &mutex, std::ostream &os)
|
||||
: _mutex(mutex), _os(os) {}
|
||||
|
||||
void SharedStreamHandler::publish(const LogRecord &record) {
|
||||
std::lock_guard<std::mutex> lg(_mutex);
|
||||
getFormatter()->format(_os, record);
|
||||
_os << std::endl;
|
||||
}
|
||||
|
||||
StreamHandler::StreamHandler(std::ostream &os)
|
||||
: SharedStreamHandler(_mutex, os) {}
|
||||
|
||||
FileHandler::FileHandler(const std::string &filename) : StreamHandler(_os) {
|
||||
_os.open(filename, std::ofstream::app);
|
||||
if (!_os) {
|
||||
throw generic_error("could not open logfile " + filename);
|
||||
}
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
// static
|
||||
Logger *Logger::getLogger(const std::string &name) {
|
||||
return LogManager::getLogManager()->getLogger(name);
|
||||
}
|
||||
|
||||
bool Logger::isLoggable(LogLevel level) const { return level <= getLevel(); }
|
||||
|
||||
ConcreteLogger::ConcreteLogger(const std::string &name, Logger *parent)
|
||||
: _name(name)
|
||||
, _parent(parent)
|
||||
, _level(LogLevel::debug)
|
||||
, _handler(name.empty() ? nullptr : new StreamHandler(std::cerr))
|
||||
, _use_parent_handlers(true) {}
|
||||
|
||||
ConcreteLogger::~ConcreteLogger() { delete _handler; }
|
||||
|
||||
std::string ConcreteLogger::getName() const { return _name; }
|
||||
|
||||
Logger *ConcreteLogger::getParent() const { return _parent; }
|
||||
|
||||
LogLevel ConcreteLogger::getLevel() const { return _level; }
|
||||
|
||||
void ConcreteLogger::setLevel(LogLevel level) { _level = level; }
|
||||
|
||||
Handler *ConcreteLogger::getHandler() const { return _handler; }
|
||||
|
||||
void ConcreteLogger::setHandler(std::unique_ptr<Handler> handler) {
|
||||
delete _handler;
|
||||
_handler = handler.release();
|
||||
}
|
||||
|
||||
bool ConcreteLogger::getUseParentHandlers() const {
|
||||
return _use_parent_handlers;
|
||||
}
|
||||
void ConcreteLogger::setUseParentHandlers(bool useParentHandlers) {
|
||||
_use_parent_handlers = useParentHandlers;
|
||||
}
|
||||
|
||||
void ConcreteLogger::emitContext(std::ostream & /*unused*/) const {}
|
||||
|
||||
void ConcreteLogger::log(const LogRecord &record) {
|
||||
if (!isLoggable(record.getLevel())) {
|
||||
return;
|
||||
}
|
||||
for (Logger *logger = this; logger != nullptr;
|
||||
logger = logger->getParent()) {
|
||||
if (Handler *handler = logger->getHandler()) {
|
||||
handler->publish(record);
|
||||
}
|
||||
if (!logger->getUseParentHandlers()) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
LoggerDecorator::LoggerDecorator(Logger *logger) : _logger(logger) {}
|
||||
|
||||
std::string LoggerDecorator::getName() const { return _logger->getName(); }
|
||||
|
||||
Logger *LoggerDecorator::getParent() const { return _logger->getParent(); }
|
||||
|
||||
LogLevel LoggerDecorator::getLevel() const { return _logger->getLevel(); }
|
||||
|
||||
void LoggerDecorator::setLevel(LogLevel level) { _logger->setLevel(level); }
|
||||
|
||||
Handler *LoggerDecorator::getHandler() const { return _logger->getHandler(); }
|
||||
|
||||
void LoggerDecorator::setHandler(std::unique_ptr<Handler> handler) {
|
||||
_logger->setHandler(std::move(handler));
|
||||
}
|
||||
|
||||
bool LoggerDecorator::getUseParentHandlers() const {
|
||||
return _logger->getUseParentHandlers();
|
||||
}
|
||||
|
||||
void LoggerDecorator::setUseParentHandlers(bool useParentHandlers) {
|
||||
_logger->setUseParentHandlers(useParentHandlers);
|
||||
}
|
||||
|
||||
void LoggerDecorator::emitContext(std::ostream &os) const {
|
||||
_logger->emitContext(os);
|
||||
}
|
||||
|
||||
void LoggerDecorator::log(const LogRecord &record) { _logger->log(record); }
|
||||
|
||||
void ContextLogger::emitContext(std::ostream &os) const {
|
||||
_logger->emitContext(os);
|
||||
_context(os);
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
Logger *LogManager::getLogger(const std::string &name) {
|
||||
Logger *current = lookup("", nullptr);
|
||||
for (size_t pos = 0; pos <= name.size();) {
|
||||
size_t dot = name.find('.', pos);
|
||||
if (dot == std::string::npos) {
|
||||
dot = name.size();
|
||||
}
|
||||
if (dot != pos) {
|
||||
current = lookup(
|
||||
(current->getName().empty() ? "" : (current->getName() + ".")) +
|
||||
name.substr(pos, dot - pos),
|
||||
current);
|
||||
}
|
||||
pos = dot + 1;
|
||||
}
|
||||
return current;
|
||||
}
|
||||
|
||||
Logger *LogManager::lookup(const std::string &name, Logger *parent) {
|
||||
std::lock_guard<std::mutex> lg(_mutex);
|
||||
auto it = _known_loggers.find(name);
|
||||
if (it == _known_loggers.end()) {
|
||||
it = _known_loggers
|
||||
.emplace(name, std::make_unique<ConcreteLogger>(name, parent))
|
||||
.first;
|
||||
}
|
||||
return it->second.get();
|
||||
}
|
||||
|
||||
LogManager LogManager::_global_log_manager;
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
std::ostream &operator<<(std::ostream &os, const generic_error &ge) {
|
||||
return os << ge.what();
|
||||
}
|
||||
341
src/Logger.h
Normal file
341
src/Logger.h
Normal file
@@ -0,0 +1,341 @@
|
||||
// +------------------------------------------------------------------+
|
||||
// | ____ _ _ __ __ _ __ |
|
||||
// | / ___| |__ ___ ___| | __ | \/ | |/ / |
|
||||
// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / |
|
||||
// | | |___| | | | __/ (__| < | | | | . \ |
|
||||
// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ |
|
||||
// | |
|
||||
// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de |
|
||||
// +------------------------------------------------------------------+
|
||||
//
|
||||
// This file is part of Check_MK.
|
||||
// The official homepage is at http://mathias-kettner.de/check_mk.
|
||||
//
|
||||
// check_mk is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation in version 2. check_mk is distributed
|
||||
// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with-
|
||||
// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
// PARTICULAR PURPOSE. See the GNU General Public License for more de-
|
||||
// tails. You should have received a copy of the GNU General Public
|
||||
// License along with GNU Make; see the file COPYING. If not, write
|
||||
// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
// Boston, MA 02110-1301 USA.
|
||||
|
||||
#ifndef Logger_h
|
||||
#define Logger_h
|
||||
|
||||
#include "config.h" // IWYU pragma: keep
|
||||
#include <atomic>
|
||||
#include <cerrno>
|
||||
#include <chrono>
|
||||
#include <fstream>
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
#include <mutex>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <system_error>
|
||||
#include <unordered_map>
|
||||
#include <utility>
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
// values must be in sync with config
|
||||
enum class LogLevel {
|
||||
emergency = 0,
|
||||
alert = 1,
|
||||
critical = 2,
|
||||
error = 3,
|
||||
warning = 4,
|
||||
notice = 5,
|
||||
informational = 6,
|
||||
debug = 7
|
||||
};
|
||||
|
||||
std::ostream &operator<<(std::ostream &os, const LogLevel &c);
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
class LogRecord {
|
||||
public:
|
||||
LogRecord(LogLevel level, std::string message)
|
||||
: _level(level)
|
||||
, _message(std::move(message))
|
||||
, _time_point(std::chrono::system_clock::now()) {}
|
||||
virtual ~LogRecord() = default;
|
||||
|
||||
[[nodiscard]] LogLevel getLevel() const { return _level; }
|
||||
void setLevel(LogLevel level) { _level = level; }
|
||||
|
||||
[[nodiscard]] std::string getMessage() const { return _message; }
|
||||
void setMessage(const std::string &message) { _message = message; }
|
||||
|
||||
[[nodiscard]] std::chrono::system_clock::time_point getTimePoint() const {
|
||||
return _time_point;
|
||||
}
|
||||
void setTimePoint(std::chrono::system_clock::time_point time_point) {
|
||||
_time_point = time_point;
|
||||
}
|
||||
|
||||
private:
|
||||
LogLevel _level;
|
||||
std::string _message;
|
||||
std::chrono::system_clock::time_point _time_point;
|
||||
};
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
class Formatter {
|
||||
public:
|
||||
virtual ~Formatter() = default;
|
||||
virtual void format(std::ostream &os, const LogRecord &record) = 0;
|
||||
};
|
||||
|
||||
class SimpleFormatter : public Formatter {
|
||||
friend class Handler;
|
||||
void format(std::ostream &os, const LogRecord &record) override;
|
||||
};
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
class Handler {
|
||||
public:
|
||||
virtual ~Handler() { setFormatter(std::unique_ptr<Formatter>()); }
|
||||
virtual void publish(const LogRecord &record) = 0;
|
||||
|
||||
[[nodiscard]] Formatter *getFormatter() const { return _formatter; }
|
||||
void setFormatter(std::unique_ptr<Formatter> formatter) {
|
||||
delete _formatter;
|
||||
_formatter = formatter.release();
|
||||
}
|
||||
|
||||
protected:
|
||||
Handler() : _formatter(new SimpleFormatter()) {}
|
||||
|
||||
private:
|
||||
std::atomic<Formatter *> _formatter;
|
||||
};
|
||||
|
||||
class SharedStreamHandler : public Handler {
|
||||
public:
|
||||
SharedStreamHandler(std::mutex &mutex, std::ostream &os);
|
||||
|
||||
private:
|
||||
// The mutex protects the _os.
|
||||
std::mutex &_mutex;
|
||||
std::ostream &_os;
|
||||
|
||||
void publish(const LogRecord &record) override;
|
||||
};
|
||||
|
||||
class StreamHandler : public SharedStreamHandler {
|
||||
public:
|
||||
explicit StreamHandler(std::ostream &os);
|
||||
|
||||
private:
|
||||
// The mutex protects the output stream, see SharedStreamHandler.
|
||||
std::mutex _mutex;
|
||||
};
|
||||
|
||||
class FileHandler : public StreamHandler {
|
||||
public:
|
||||
explicit FileHandler(const std::string &filename);
|
||||
|
||||
private:
|
||||
std::ofstream _os;
|
||||
};
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
class Logger {
|
||||
public:
|
||||
static Logger *getLogger(const std::string &name);
|
||||
|
||||
virtual ~Logger() = default;
|
||||
|
||||
[[nodiscard]] bool isLoggable(LogLevel level) const;
|
||||
|
||||
[[nodiscard]] virtual std::string getName() const = 0;
|
||||
|
||||
[[nodiscard]] virtual Logger *getParent() const = 0;
|
||||
|
||||
[[nodiscard]] virtual LogLevel getLevel() const = 0;
|
||||
virtual void setLevel(LogLevel level) = 0;
|
||||
|
||||
[[nodiscard]] virtual Handler *getHandler() const = 0;
|
||||
virtual void setHandler(std::unique_ptr<Handler> handler) = 0;
|
||||
|
||||
[[nodiscard]] virtual bool getUseParentHandlers() const = 0;
|
||||
virtual void setUseParentHandlers(bool useParentHandlers) = 0;
|
||||
|
||||
virtual void emitContext(std::ostream &os) const = 0;
|
||||
|
||||
virtual void log(const LogRecord &record) = 0;
|
||||
};
|
||||
|
||||
class ConcreteLogger : public Logger {
|
||||
public:
|
||||
ConcreteLogger(const std::string &name, Logger *parent);
|
||||
~ConcreteLogger() override;
|
||||
|
||||
[[nodiscard]] std::string getName() const override;
|
||||
|
||||
[[nodiscard]] Logger *getParent() const override;
|
||||
|
||||
[[nodiscard]] LogLevel getLevel() const override;
|
||||
void setLevel(LogLevel level) override;
|
||||
|
||||
[[nodiscard]] Handler *getHandler() const override;
|
||||
void setHandler(std::unique_ptr<Handler> handler) override;
|
||||
|
||||
[[nodiscard]] bool getUseParentHandlers() const override;
|
||||
void setUseParentHandlers(bool useParentHandlers) override;
|
||||
|
||||
void emitContext(std::ostream &os) const override;
|
||||
|
||||
void log(const LogRecord &record) override;
|
||||
|
||||
private:
|
||||
const std::string _name;
|
||||
Logger *const _parent;
|
||||
std::atomic<LogLevel> _level;
|
||||
std::atomic<Handler *> _handler;
|
||||
std::atomic<bool> _use_parent_handlers;
|
||||
};
|
||||
|
||||
class LoggerDecorator : public Logger {
|
||||
public:
|
||||
explicit LoggerDecorator(Logger *logger);
|
||||
|
||||
[[nodiscard]] std::string getName() const override;
|
||||
|
||||
[[nodiscard]] Logger *getParent() const override;
|
||||
|
||||
[[nodiscard]] LogLevel getLevel() const override;
|
||||
void setLevel(LogLevel level) override;
|
||||
|
||||
[[nodiscard]] Handler *getHandler() const override;
|
||||
void setHandler(std::unique_ptr<Handler> handler) override;
|
||||
|
||||
[[nodiscard]] bool getUseParentHandlers() const override;
|
||||
void setUseParentHandlers(bool useParentHandlers) override;
|
||||
|
||||
void emitContext(std::ostream &os) const override;
|
||||
|
||||
void log(const LogRecord &record) override;
|
||||
|
||||
protected:
|
||||
Logger *const _logger;
|
||||
};
|
||||
|
||||
class ContextLogger : public LoggerDecorator {
|
||||
public:
|
||||
using ContextEmitter = std::function<void(std::ostream &)>;
|
||||
|
||||
ContextLogger(Logger *logger, ContextEmitter context)
|
||||
: LoggerDecorator(logger), _context(std::move(context)) {}
|
||||
|
||||
void emitContext(std::ostream &os) const override;
|
||||
|
||||
private:
|
||||
const ContextEmitter _context;
|
||||
};
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
class LogManager {
|
||||
public:
|
||||
static LogManager *getLogManager() { return &_global_log_manager; }
|
||||
Logger *getLogger(const std::string &name);
|
||||
|
||||
private:
|
||||
static LogManager _global_log_manager;
|
||||
|
||||
// The mutex protects _known_loggers.
|
||||
std::mutex _mutex;
|
||||
std::unordered_map<std::string, std::unique_ptr<Logger>> _known_loggers;
|
||||
|
||||
Logger *lookup(const std::string &name, Logger *parent);
|
||||
};
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
class LogStream {
|
||||
public:
|
||||
LogStream(Logger *logger, LogLevel level) : _logger(logger), _level(level) {
|
||||
// The test and all the similar ones below are just optimizations.
|
||||
if (_logger->isLoggable(_level)) {
|
||||
_logger->emitContext(_os);
|
||||
}
|
||||
}
|
||||
|
||||
virtual ~LogStream() {
|
||||
if (_logger->isLoggable(_level)) {
|
||||
_logger->log(LogRecord(_level, _os.str()));
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
std::ostream &operator<<(const T &t) {
|
||||
return _logger->isLoggable(_level) ? (_os << t) : _os;
|
||||
}
|
||||
|
||||
protected:
|
||||
Logger *const _logger;
|
||||
const LogLevel _level;
|
||||
std::ostringstream _os;
|
||||
};
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
struct Emergency : public LogStream {
|
||||
explicit Emergency(Logger *logger)
|
||||
: LogStream(logger, LogLevel::emergency) {}
|
||||
};
|
||||
|
||||
struct Alert : public LogStream {
|
||||
explicit Alert(Logger *logger) : LogStream(logger, LogLevel::alert) {}
|
||||
};
|
||||
|
||||
struct Critical : public LogStream {
|
||||
explicit Critical(Logger *logger) : LogStream(logger, LogLevel::critical) {}
|
||||
};
|
||||
|
||||
struct Error : public LogStream {
|
||||
explicit Error(Logger *logger) : LogStream(logger, LogLevel::error) {}
|
||||
};
|
||||
|
||||
struct Warning : public LogStream {
|
||||
explicit Warning(Logger *logger) : LogStream(logger, LogLevel::warning) {}
|
||||
};
|
||||
|
||||
struct Notice : public LogStream {
|
||||
explicit Notice(Logger *logger) : LogStream(logger, LogLevel::notice) {}
|
||||
};
|
||||
|
||||
struct Informational : public LogStream {
|
||||
explicit Informational(Logger *logger)
|
||||
: LogStream(logger, LogLevel::informational) {}
|
||||
};
|
||||
|
||||
struct Debug : public LogStream {
|
||||
explicit Debug(Logger *logger) : LogStream(logger, LogLevel::debug) {}
|
||||
};
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
class generic_error : public std::system_error {
|
||||
public:
|
||||
generic_error() : std::system_error(errno, std::generic_category()) {}
|
||||
|
||||
explicit generic_error(const char *what_arg)
|
||||
: std::system_error(errno, std::generic_category(), what_arg) {}
|
||||
|
||||
explicit generic_error(const std::string &what_arg)
|
||||
: std::system_error(errno, std::generic_category(), what_arg) {}
|
||||
};
|
||||
|
||||
std::ostream &operator<<(std::ostream &os, const generic_error &ge);
|
||||
|
||||
#endif // Logger_h
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user