Skip to content

Commit

Permalink
add agent client server
Browse files Browse the repository at this point in the history
add engine client server

use of configured logger

process uses po::split_unix to split command line

add tests

add agent_check_result_builder
  • Loading branch information
jean-christophe81 committed Jun 18, 2024
1 parent 46dd77e commit 54f3afe
Show file tree
Hide file tree
Showing 66 changed files with 4,391 additions and 413 deletions.
5 changes: 5 additions & 0 deletions agent/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@ add_custom_command(
add_library(centreon_agent_lib STATIC
${SRC_DIR}/agent.grpc.pb.cc
${SRC_DIR}/agent.pb.cc
${SRC_DIR}/bireactor.cc
${SRC_DIR}/check.cc
${SRC_DIR}/check_exec.cc
${SRC_DIR}/opentelemetry/proto/collector/metrics/v1/metrics_service.grpc.pb.cc
Expand All @@ -108,12 +109,15 @@ add_library(centreon_agent_lib STATIC
${SRC_DIR}/opentelemetry/proto/common/v1/common.pb.cc
${SRC_DIR}/opentelemetry/proto/resource/v1/resource.pb.cc
${SRC_DIR}/scheduler.cc
${SRC_DIR}/streaming_client.cc
${SRC_DIR}/streaming_server.cc
)

include_directories(
${INCLUDE_DIR}
${SRC_DIR}
${CMAKE_SOURCE_DIR}/common/inc
${CMAKE_SOURCE_DIR}/common/grpc/inc
)

target_precompile_headers(centreon_agent_lib PRIVATE precomp_inc/precomp.hh)
Expand All @@ -128,6 +132,7 @@ target_link_libraries(
# berpc
centreon_agent_lib
centreon_common
centreon_grpc
-L${Boost_LIBRARY_DIR_RELEASE}
boost_program_options
fmt::fmt)
Expand Down
5 changes: 3 additions & 2 deletions agent/doc/agent-doc.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,12 @@
## Introduction

The goal of this program is to execute checks in both windows and linux OS
It's full asynchronous, excepted grpc layers, it's single threaded and you won't find mutex in code.
It's full asynchronous, excepted grpc layers, it's single threaded and you won't find mutex in non grpc code.
This is why when we receive request, we post it to asio in order to process it in the main thread.

## Configuration
configuration is given by Engine by a AgentConfiguration sent over grpc
The configuration object is embedded in EngineToAgent::config
The configuration object is embedded in MessageToAgent::config

## Scheduler
We trie to spread checks over check_period.
Expand Down
84 changes: 84 additions & 0 deletions agent/inc/com/centreon/agent/bireactor.hh
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
/**
* Copyright 2024 Centreon
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* For more information : [email protected]
*/

#ifndef CENTREON_AGENT_BIREACTOR_HH
#define CENTREON_AGENT_BIREACTOR_HH

#include "agent.grpc.pb.h"

namespace com::centreon::agent {

template <class bireactor_class>
class bireactor
: public bireactor_class,
public std::enable_shared_from_this<bireactor<bireactor_class>> {
private:
static std::set<std::shared_ptr<bireactor>> _instances;
static std::mutex _instances_m;

bool _write_pending;
std::deque<std::shared_ptr<MessageFromAgent>> _write_queue;
std::shared_ptr<MessageToAgent> _read_current;

const std::string_view _class_name;

const std::string _peer;

protected:
std::shared_ptr<boost::asio::io_context> _io_context;
std::shared_ptr<spdlog::logger> _logger;

bool _alive;
mutable std::mutex _protect;

public:
bireactor(const std::shared_ptr<boost::asio::io_context>& io_context,
const std::shared_ptr<spdlog::logger>& logger,
const std::string_view& class_name,
const std::string& peer);

virtual ~bireactor();

static void register_stream(const std::shared_ptr<bireactor>& strm);

void start_read();

void start_write();
void write(const std::shared_ptr<MessageFromAgent>& request);

// bireactor part
void OnReadDone(bool ok) override;

virtual void on_incomming_request(
const std::shared_ptr<MessageToAgent>& request) = 0;

virtual void on_error() = 0;

void OnWriteDone(bool ok) override;

// server version
void OnDone();
// client version
void OnDone(const ::grpc::Status& /*s*/);

virtual void shutdown();
};

} // namespace com::centreon::agent

#endif
19 changes: 2 additions & 17 deletions agent/inc/com/centreon/agent/check.hh
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
namespace com::centreon::agent {

using engine_to_agent_request_ptr =
std::shared_ptr<com::centreon::agent::EngineToAgent>;
std::shared_ptr<com::centreon::agent::MessageToAgent>;

using time_point = std::chrono::system_clock::time_point;
using duration = std::chrono::system_clock::duration;
Expand All @@ -46,7 +46,6 @@ class check : public std::enable_shared_from_this<check> {

private:
time_point _start_expected;
const std::string& _host;
const std::string& _service;
const std::string& _command_name;
const std::string& _command_line;
Expand Down Expand Up @@ -77,26 +76,14 @@ class check : public std::enable_shared_from_this<check> {
public:
using pointer = std::shared_ptr<check>;

template <typename handler_type>
check(const std::shared_ptr<asio::io_context>& io_context,
const std::shared_ptr<spdlog::logger>& logger,
time_point exp,
const std::string& hst,
const std::string& serv,
const std::string& command_name,
const std::string& cmd_line,
const engine_to_agent_request_ptr& cnf,
handler_type&& handler)
: _start_expected(exp),
_host(hst),
_service(serv),
_command_name(command_name),
_command_line(cmd_line),
_conf(cnf),
_io_context(io_context),
_logger(logger),
_time_out_timer(*io_context),
_completion_handler(handler) {}
completion_handler&& handler);

virtual ~check() = default;

Expand All @@ -111,8 +98,6 @@ class check : public std::enable_shared_from_this<check> {

time_point get_start_expected() const { return _start_expected; }

const std::string& get_host() const { return _host; }

const std::string& get_service() const { return _service; }

const std::string& get_command_name() const { return _command_name; }
Expand Down
51 changes: 3 additions & 48 deletions agent/inc/com/centreon/agent/check_exec.hh
Original file line number Diff line number Diff line change
Expand Up @@ -88,75 +88,30 @@ class check_exec : public check {
void _init();

public:
template <typename handler_type>
check_exec(const std::shared_ptr<asio::io_context>& io_context,
const std::shared_ptr<spdlog::logger>& logger,
time_point exp,
const std::string& hst,
const std::string& serv,
const std::string& cmd_name,
const std::string& cmd_line,
const engine_to_agent_request_ptr& cnf,
handler_type&& handler)
: check(io_context,
logger,
exp,
hst,
serv,
cmd_name,
cmd_line,
cnf,
handler) {}

template <typename handler_type>
check::completion_handler&& handler);

static std::shared_ptr<check_exec> load(
const std::shared_ptr<asio::io_context>& io_context,
const std::shared_ptr<spdlog::logger>& logger,
time_point exp,
const std::string& hst,
const std::string& serv,
const std::string& cmd_name,
const std::string& cmd_line,
const engine_to_agent_request_ptr& cnf,
handler_type&& handler);
check::completion_handler&& handler);

void start_check(const duration& timeout) override;

void on_completion(unsigned running_index);
};

/**
* @brief create and initialize a check_exec object (don't use constructor)
*
* @tparam handler_type
* @param io_context
* @param logger
* @param exp start expected
* @param hst
* @param serv
* @param cmd_name
* @param cmd_line
* @param cnf agent configuration
* @param handler completion handler
* @return std::shared_ptr<check_exec>
*/
template <typename handler_type>
std::shared_ptr<check_exec> check_exec::load(
const std::shared_ptr<asio::io_context>& io_context,
const std::shared_ptr<spdlog::logger>& logger,
time_point exp,
const std::string& hst,
const std::string& serv,
const std::string& cmd_name,
const std::string& cmd_line,
const engine_to_agent_request_ptr& cnf,
handler_type&& handler) {
std::shared_ptr<check_exec> ret = std::make_shared<check_exec>(
io_context, logger, exp, hst, serv, cmd_name, cmd_line, cnf, handler);
ret->_init();
return ret;
}

} // namespace com::centreon::agent

#endif
43 changes: 25 additions & 18 deletions agent/inc/com/centreon/agent/scheduler.hh
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,6 @@

namespace com::centreon::agent {

using export_metric_request =
::opentelemetry::proto::collector::metrics::v1::ExportMetricsServiceRequest;
using export_metric_request_ptr = std::shared_ptr<export_metric_request>;

/**
* @brief the core of the agent
* It has to create check object with chck_builder passed in parameter of load
Expand All @@ -35,12 +31,12 @@ using export_metric_request_ptr = std::shared_ptr<export_metric_request>;
*/
class scheduler : public std::enable_shared_from_this<scheduler> {
public:
using metric_sender = std::function<void(const export_metric_request_ptr&)>;
using metric_sender =
std::function<void(const std::shared_ptr<MessageFromAgent>&)>;
using check_builder = std::function<std::shared_ptr<check>(
const std::shared_ptr<asio::io_context>&,
const std::shared_ptr<spdlog::logger>& /*logger*/,
time_point /* start expected*/,
const std::string& /*host*/,
const std::string& /*service*/,
const std::string& /*cmd_name*/,
const std::string& /*cmd_line*/,
Expand All @@ -55,7 +51,7 @@ class scheduler : public std::enable_shared_from_this<scheduler> {
bool _alive = true;

// request that will be sent to engine
export_metric_request_ptr _current_request;
std::shared_ptr<MessageFromAgent> _current_request;

struct scope_metric_request {
::opentelemetry::proto::metrics::v1::ScopeMetrics* scope_metric;
Expand All @@ -64,11 +60,11 @@ class scheduler : public std::enable_shared_from_this<scheduler> {
metrics;
};

absl::flat_hash_map<std::pair<std::string, std::string>, scope_metric_request>
_host_serv_to_scope_metrics;
absl::flat_hash_map<std::string, scope_metric_request> _serv_to_scope_metrics;

std::shared_ptr<asio::io_context> _io_context;
std::shared_ptr<spdlog::logger> _logger;
std::string _supervised_host;
metric_sender _metric_sender;
asio::system_timer _send_timer;
asio::system_timer _check_timer;
Expand All @@ -95,14 +91,13 @@ class scheduler : public std::enable_shared_from_this<scheduler> {
unsigned status,
const std::list<com::centreon::common::perfdata>& perfdata,
const std::list<std::string>& outputs);
void _store_result_in_metrics_and_examplars(
void _store_result_in_metrics_and_exemplars(
const check::pointer& check,
unsigned status,
const std::list<com::centreon::common::perfdata>& perfdata,
const std::list<std::string>& outputs);

scope_metric_request& _get_scope_metrics(const std::string& host,
const std::string& service);
scope_metric_request& _get_scope_metrics(const std::string& service);

::opentelemetry::proto::metrics::v1::Metric* _get_metric(
scope_metric_request& scope_metric,
Expand All @@ -127,23 +122,32 @@ class scheduler : public std::enable_shared_from_this<scheduler> {
template <typename sender, typename chck_builder>
scheduler(const std::shared_ptr<asio::io_context>& io_context,
const std::shared_ptr<spdlog::logger>& logger,
const std::shared_ptr<com::centreon::agent::EngineToAgent>& config,
const std::string& supervised_host,
const std::shared_ptr<com::centreon::agent::MessageToAgent>& config,
sender&& met_sender,
chck_builder&& builder);

scheduler(const scheduler&) = delete;
scheduler operator=(const scheduler&) = delete;

void update(const engine_to_agent_request_ptr& conf);

static std::shared_ptr<com::centreon::agent::EngineToAgent> default_config();
static std::shared_ptr<com::centreon::agent::MessageToAgent> default_config();

template <typename sender, typename chck_builder>
static std::shared_ptr<scheduler> load(
const std::shared_ptr<asio::io_context>& io_context,
const std::shared_ptr<spdlog::logger>& logger,
const std::shared_ptr<com::centreon::agent::EngineToAgent>& config,
const std::string& supervised_host,
const std::shared_ptr<com::centreon::agent::MessageToAgent>& config,
sender&& met_sender,
chck_builder&& chk_builder);

void stop();

engine_to_agent_request_ptr get_last_message_to_agent() const {
return _conf;
}
};

/**
Expand All @@ -158,12 +162,14 @@ template <typename sender, typename chck_builder>
scheduler::scheduler(
const std::shared_ptr<asio::io_context>& io_context,
const std::shared_ptr<spdlog::logger>& logger,
const std::shared_ptr<com::centreon::agent::EngineToAgent>& config,
const std::string& supervised_host,
const std::shared_ptr<com::centreon::agent::MessageToAgent>& config,
sender&& met_sender,
chck_builder&& builder)
: _metric_sender(met_sender),
_io_context(io_context),
_logger(logger),
_supervised_host(supervised_host),
_send_timer(*io_context),
_check_timer(*io_context),
_check_builder(builder),
Expand All @@ -181,11 +187,12 @@ template <typename sender, typename chck_builder>
std::shared_ptr<scheduler> scheduler::load(
const std::shared_ptr<asio::io_context>& io_context,
const std::shared_ptr<spdlog::logger>& logger,
const std::shared_ptr<com::centreon::agent::EngineToAgent>& config,
const std::string& supervised_host,
const std::shared_ptr<com::centreon::agent::MessageToAgent>& config,
sender&& met_sender,
chck_builder&& chk_builder) {
std::shared_ptr<scheduler> to_start = std::make_shared<scheduler>(
io_context, logger, config, std::move(met_sender),
io_context, logger, supervised_host, config, std::move(met_sender),
std::move(chk_builder));
to_start->_start();
return to_start;
Expand Down
Loading

0 comments on commit 54f3afe

Please sign in to comment.