37{
39 const ConfigParser config(input.cmdOptionExists(
"--config") ? input.getCmdOption(
"--config") :
"config.json");
40 const MainLogger logger(config.get(
"LOKI_ADDRESS"), config.get(
"SENTRY_ADDRESS"));
41
42
43 if (curl_global_init(CURL_GLOBAL_DEFAULT) < 0)
44 {
45 spdlog::critical("Can't init curl");
46 return EXIT_FAILURE;
47 }
48
49
50 if (input.cmdOptionExists("-v"))
51 {
52 spdlog::set_level(spdlog::level::info);
53 }
54 if (input.cmdOptionExists("-vv"))
55 {
56 spdlog::set_level(spdlog::level::debug);
57 }
58 if (input.cmdOptionExists("-vvv"))
59 {
60 spdlog::set_level(spdlog::level::trace);
61 }
62
63
64 spdlog::debug("======== Detected input arguments ========");
65 for (const auto &entry : input.getCmdOptions())
66 {
67 spdlog::debug("{} = {}", entry.first, entry.second);
68 }
69
70
71 spdlog::debug("======== Detected configuration ========");
72 for (const auto &entry : config.getConfigMap())
73 {
74 spdlog::debug("{} = {}", entry.first, entry.second);
75 }
76
77
78 if (std::signal(SIGINT, interruptFunc) == SIG_ERR)
79 {
80 spdlog::critical(
"Can't set signal handler (SIGINT): {}",
getErrnoString(errno));
81 return EXIT_FAILURE;
82 }
83
84
85 if (std::signal(SIGTERM, interruptFunc) == SIG_ERR)
86 {
87 spdlog::critical(
"Can't set signal handler (SIGTERM): {}",
getErrnoString(errno));
88 return EXIT_FAILURE;
89 }
90
91
92 if (std::signal(SIGALRM, alarmFunc) == SIG_ERR)
93 {
94 spdlog::critical(
"Can't set signal handler (SIGALRM): {}",
getErrnoString(errno));
95 return EXIT_FAILURE;
96 }
98
99
100 std::unique_ptr<Tracer> crashpadController(nullptr);
101 vCheckFlag.emplace_back(
"Crashpad Handler", std::make_shared<std::atomic_flag>(
false));
102 crashpadController = std::make_unique<Tracer>(
103 vCheckFlag[
vCheckFlag.size() - 1].second, config.get(
"CRASHPAD_REMOTE"), config.get(
"CRASHPAD_PROXY"),
104 config.get("CRASHPAD_EXECUTABLE_DIR"), config.get("CRASHPAD_REPORT_DIR"));
105
106
107 std::unique_ptr<PrometheusServer> mainPrometheusServer(nullptr);
108 const std::string prometheusAddr = input.getCmdOption("--enable-prometheus");
109 if (!prometheusAddr.empty())
110 {
111 try
112 {
113 mainPrometheusServer = std::make_unique<PrometheusServer>(prometheusAddr);
114 spdlog::info("Prometheus server start at {}", prometheusAddr);
115 }
116 catch (const std::exception &e)
117 {
118 spdlog::error("Can't start Prometheus Server: {}", e.what());
119 return EXIT_FAILURE;
120 }
121 }
122
123
124 std::unique_ptr<ProcessMetrics> selfMonitor(nullptr);
125 vCheckFlag.emplace_back(
"Self Monitor", std::make_shared<std::atomic_flag>(
false));
126 if (mainPrometheusServer)
127 {
129 mainPrometheusServer->createNewRegistry());
130 }
131
132
133 std::unique_ptr<ZeroMQServer> zmqController(nullptr);
134 vCheckFlag.emplace_back(
"ZeroMQ Server", std::make_shared<std::atomic_flag>(
false));
135 const std::string zeromqServerAddr = input.getCmdOption("--enable-zeromq");
136 if (!zeromqServerAddr.empty())
137 {
138 try
139 {
140 zmqController = std::make_unique<ZeroMQServer>(
142 mainPrometheusServer ? mainPrometheusServer->createNewRegistry() : nullptr);
144 zmqController->initialise();
145 }
146 catch (const std::exception &e)
147 {
148 spdlog::error("Can't start ZeroMQ Server: {}", e.what());
149 return EXIT_FAILURE;
150 }
151 }
152
153
154 std::unique_ptr<TelnetServer> telnetController(nullptr);
155 vCheckFlag.emplace_back(
"Telnet Server", std::make_shared<std::atomic_flag>(
false));
156 const unsigned long telnetPort =
157 input.cmdOptionExists("--enable-telnet") ? std::stoul(input.getCmdOption("--enable-telnet")) : 0;
158 if (telnetPort > 0 && telnetPort < 65536)
159 {
160 try
161 {
162 telnetController = std::make_unique<TelnetServer>();
167 mainPrometheusServer ? mainPrometheusServer->createNewRegistry() : nullptr);
168 }
169 catch (const std::exception &e)
170 {
171 spdlog::error("Can't start Telnet Server: {}", e.what());
172 return EXIT_FAILURE;
173 }
174 }
175 else if (telnetPort != 0)
176 {
177 spdlog::error("Invalid Telnet port: {}", telnetPort);
178 return EXIT_FAILURE;
179 }
180
181
182
183
184
185
186
187
188
190 {
191 std::this_thread::sleep_for(std::chrono::milliseconds(500));
192 }
193
194
195
196
197
198
199
200
201
202 curl_global_cleanup();
203
204 return EXIT_SUCCESS;
205}
std::vector< std::pair< std::string, std::shared_ptr< std::atomic_flag > > > vCheckFlag
Global variable to check if the servers are running.
std::string getErrnoString(int errVal)
void TelnetConnectedCallback(const SP_TelnetSession &session)
std::string TelnetTabCallback(const SP_TelnetSession &session, std::string_view line)
bool TelnetMessageCallback(const SP_TelnetSession &session, const std::string &line)
bool ZeroMQServerMessageCallback(const std::vector< zmq::message_t > &recvMsgs, std::vector< zmq::message_t > &replyMsgs)
volatile sig_atomic_t interruptFlag
constexpr uintmax_t alarmInterval