Leosac  0.8.0
Open Source Access Control
MonitorModule.cpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2014-2016 Leosac
3 
4  This file is part of Leosac.
5 
6  Leosac is free software: you can redistribute it and/or modify
7  it under the terms of the GNU Affero General Public License as published by
8  the Free Software Foundation, either version 3 of the License, or
9  (at your option) any later version.
10 
11  Leosac is distributed in the hope that it will be useful,
12  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  GNU Affero General Public License for more details.
15 
16  You should have received a copy of the GNU Affero General Public License
17  along with this program. If not, see <http://www.gnu.org/licenses/>.
18 */
19 
20 #include "MonitorModule.hpp"
21 #include "tools/log.hpp"
23 #include <zmqpp/z85.hpp>
24 
25 using namespace Leosac::Module::Monitor;
26 
27 static std::string z85_pad(const std::string &in, char pad_char)
28 {
29  std::string out(in);
30 
31  while (out.size() % 4)
32  out += pad_char;
33  return out;
34 }
35 
36 MonitorModule::MonitorModule(zmqpp::context &ctx, zmqpp::socket *pipe,
37  const boost::property_tree::ptree &cfg,
38  CoreUtilsPtr utils)
39  : BaseModule(ctx, pipe, cfg, utils)
40  , bus_(ctx, zmqpp::socket_type::sub)
41  , verbose_(false)
42  , last_ping_(TimePoint::max())
43  , kernel_(ctx, zmqpp::socket_type::req)
44 {
45  kernel_.connect("inproc://leosac-kernel");
46  reactor_.add(bus_, std::bind(&MonitorModule::log_system_bus, this));
47  bus_.connect("inproc://zmq-bus-pub");
48 
50 }
51 
53 {
54  while (is_running_)
55  {
56  reactor_.poll(1000);
57  if (last_ping_ == TimePoint::max() ||
58  std::chrono::duration_cast<std::chrono::seconds>(
59  std::chrono::system_clock::now() - last_ping_)
60  .count() > 3)
61  {
62  test_ping();
63  last_ping_ = std::chrono::system_clock::now();
64  }
65  }
66 }
67 
69 {
70  auto system_bus_logger = spdlog::get("system_bus_event");
71  assert(system_bus_logger);
72 
73  std::string src;
74  std::stringstream full_msg;
75  zmqpp::message msg;
76  bus_.receive(msg);
77 
78  for (size_t i = 0; i < msg.parts(); ++i)
79  {
80  std::string buf;
81  msg >> buf;
82  if (i == 0)
83  {
84  src = buf;
85  }
86  if (std::find_if(buf.begin(), buf.end(),
87  [](char c) { return !isprint(c); }) != buf.end())
88  {
89  // encode frame in z85 since it contains non printable char
90  buf = zmqpp::z85::encode(z85_pad(buf, 0));
91  full_msg << "F" << i << ": {" << buf << "} ; ";
92  }
93  else
94  {
95  full_msg << "F" << i << ": {" << buf << "} ; ";
96  }
97  }
98  system_bus_logger->info(full_msg.str());
99  if (verbose_)
100  {
101  auto monitor_stdout = spdlog::get("monitor_stdout");
102  assert(monitor_stdout);
103  monitor_stdout->info(full_msg.str());
104  }
105 
106  // reader activity check
107  if (src == ("S_" + reader_to_watch_) && reader_led_)
108  {
109  reader_led_->turnOn(500);
110  }
111 
112  // system readiness check
113  if (src == "KERNEL" && system_led_)
114  {
115  system_led_->turnOn();
116  }
117 }
118 
120 {
121  if (addr_to_ping_.empty())
122  return;
123  Tools::UnixShellScript script(req_scripts_dir() + "/ping.sh");
124 
125  int ret = script.run(addr_to_ping_);
126  if (ret == 0)
127  {
128  INFO("Ping against " << addr_to_ping_
129  << " was successful. Looks like network is up.");
130  network_led_->turnOn();
131  }
132  else
133  {
134  INFO("Ping against " << addr_to_ping_
135  << " failed. Network is probably down.");
136  network_led_->turnOff();
137  }
138 }
139 
141 {
142  std::string ret;
143  kernel_.send("SCRIPTS_DIR");
144 
145  zmqpp::poller poller;
146  poller.add(kernel_);
147  poller.poll(1000);
148  if (poller.has_input(kernel_))
149  kernel_.receive(ret);
150  else
151  throw std::runtime_error("Internal Error, timeout'd");
152  return ret;
153 }
154 
156 {
157  std::string system_bus_log_file =
158  config_.get_child("module_config").get<std::string>("file-bus", "");
159  if (!system_bus_log_file.empty())
160  {
161  bus_.subscribe("");
162  spdlog::rotating_logger_mt("system_bus_event", system_bus_log_file,
163  1024 * 1024 * 3, 2);
164  }
165  verbose_ = config_.get_child("module_config").get<bool>("verbose", false);
166  if (verbose_)
167  {
168  spdlog::stdout_logger_mt("monitor_stdout");
169  }
170 
171  std::string system_led_name =
172  config_.get_child("module_config").get<std::string>("system_ok", "");
173  if (!system_led_name.empty())
174  {
175  system_led_ =
176  std::make_unique<Leosac::Hardware::FLED>(ctx_, system_led_name);
177  }
178 
181 }
182 
184 {
185  auto ping_node = config_.get_child("module_config").get_child_optional("ping");
186  if (ping_node)
187  {
188  addr_to_ping_ = ping_node->get<std::string>("ip");
189  std::string network_led_name = ping_node->get<std::string>("led");
190  network_led_ =
191  std::make_unique<Leosac::Hardware::FLED>(ctx_, network_led_name);
192  }
193 }
194 
196 {
197  auto reader_node =
198  config_.get_child("module_config").get_child_optional("reader");
199  if (reader_node)
200  {
201  reader_to_watch_ = reader_node->get<std::string>("name");
202  bus_.subscribe("S_" + reader_to_watch_);
203  std::string reader_led_name = reader_node->get<std::string>("led");
204  reader_led_ =
205  std::make_unique<Leosac::Hardware::FLED>(ctx_, reader_led_name);
206  }
207 }
Leosac::Module::Monitor::MonitorModule::MonitorModule
MonitorModule(zmqpp::context &ctx, zmqpp::socket *pipe, const boost::property_tree::ptree &cfg, CoreUtilsPtr utils)
Definition: MonitorModule.cpp:36
Leosac::Module::Monitor::MonitorModule::reader_to_watch_
std::string reader_to_watch_
Definition: MonitorModule.hpp:89
Leosac::Module::Monitor::MonitorModule::run
virtual void run() override
This is the main loop of the module.
Definition: MonitorModule.cpp:52
Leosac::Module::Monitor::MonitorModule::process_config
void process_config()
Definition: MonitorModule.cpp:155
Leosac::Module::BaseModule
Base class for module implementation.
Definition: BaseModule.hpp:110
unixshellscript.hpp
UnixShellScript class declaration.
zmqpp
Definition: CoreUtils.hpp:27
Leosac::Module::Monitor::MonitorModule::process_reader_config
void process_reader_config()
Load config related to reader activity monitoring.
Definition: MonitorModule.cpp:195
MonitorModule.hpp
Leosac::Module::Monitor::MonitorModule::last_ping_
TimePoint last_ping_
Definition: MonitorModule.hpp:106
Leosac::Module::Monitor::MonitorModule::verbose_
bool verbose_
Definition: MonitorModule.hpp:85
INFO
@ INFO
Definition: log.hpp:34
Leosac::Module::Monitor::MonitorModule::reader_led_
std::unique_ptr< Leosac::Hardware::FLED > reader_led_
Led for feedback about reader activity.
Definition: MonitorModule.hpp:99
Leosac::Tools::UnixShellScript::run
int run(const std::string &args=std::string())
Definition: unixshellscript.cpp:46
Leosac::Module::Monitor
A module that provide visual feedback to the end-user about system's activity.
Definition: MonitorModule.hpp:34
Leosac::Module::Monitor::MonitorModule::process_network_config
void process_network_config()
Load config related to network monitoring.
Definition: MonitorModule.cpp:183
Leosac::Module::Monitor::MonitorModule::network_led_
std::unique_ptr< Leosac::Hardware::FLED > network_led_
Led for feedback about network availability.
Definition: MonitorModule.hpp:94
Leosac::Module::BaseModule::config_
boost::property_tree::ptree config_
The configuration tree passed to the start_module function.
Definition: BaseModule.hpp:193
Leosac::Module::BaseModule::reactor_
zmqpp::reactor reactor_
The reactor object we poll() on in the main loop.
Definition: BaseModule.hpp:214
Leosac::Module::Monitor::MonitorModule::test_ping
void test_ping()
Definition: MonitorModule.cpp:119
Leosac::Module::Monitor::MonitorModule::log_system_bus
void log_system_bus()
Called when a message arrives on the system bus and we are configured to log that.
Definition: MonitorModule.cpp:68
Leosac::Module::BaseModule::is_running_
bool is_running_
Boolean indicating whether the main loop should run or not.
Definition: BaseModule.hpp:203
Leosac::Module::Monitor::MonitorModule::TimePoint
std::chrono::system_clock::time_point TimePoint
Definition: MonitorModule.hpp:56
Leosac::Module::Monitor::MonitorModule::system_led_
std::unique_ptr< Leosac::Hardware::FLED > system_led_
Led for feedback about system readiness.
Definition: MonitorModule.hpp:104
log.hpp
Leosac::Tools::UnixShellScript
Definition: unixshellscript.hpp:36
Leosac::Module::Monitor::MonitorModule::req_scripts_dir
std::string req_scripts_dir()
Get scripts directory from kernel.
Definition: MonitorModule.cpp:140
Leosac::Module::Monitor::MonitorModule::addr_to_ping_
std::string addr_to_ping_
Definition: MonitorModule.hpp:87
Leosac::Module::Monitor::MonitorModule::bus_
zmqpp::socket bus_
Definition: MonitorModule.hpp:83
Leosac::Module::BaseModule::ctx_
zmqpp::context & ctx_
A reference to the ZeroMQ context in case you need it to create additional socket.
Definition: BaseModule.hpp:183
Leosac::CoreUtilsPtr
std::shared_ptr< CoreUtils > CoreUtilsPtr
Definition: LeosacFwd.hpp:35
Leosac::Module::Monitor::MonitorModule::kernel_
zmqpp::socket kernel_
Definition: MonitorModule.hpp:108