Fixposition SDK 0.0.0-heads/main-0-g155c724
Collection of c++ libraries and apps for use with Fixposition products on Linux
Loading...
Searching...
No Matches
app.hpp
Go to the documentation of this file.
1/**
2 * \verbatim
3 * ___ ___
4 * \ \ / /
5 * \ \/ / Copyright (c) Fixposition AG (www.fixposition.com) and contributors
6 * / /\ \ License: see the LICENSE file
7 * /__/ \__\
8 * \endverbatim
9 *
10 * @file
11 * @brief Fixposition SDK: Utilities for apps
12 *
13 * @page FPSDK_COMMON_APPS Utilities for apps
14 *
15 * **API**: fpsdk_common/app.hpp and fpsdk::common::app
16 *
17 */
18#ifndef __FPSDK_COMMON_APP_HPP__
19#define __FPSDK_COMMON_APP_HPP__
20
21/* LIBC/STL */
22#include <cstdint>
23
24/* EXTERNAL */
25
26/* PACKAGE */
27#include "logging.hpp"
28#include "time.hpp"
29
30namespace fpsdk {
31namespace common {
32/**
33 * @brief Utilities for apps
34 */
35namespace app {
36/* ****************************************************************************************************************** */
37
38/**
39 * @brief Helper to catch SIGINT (CTRL-c)
40 *
41 * On construction this installs a handler for SIGINT. On destruction it sets the handler back to its previous state.
42 * Note that signal handlers are global and therefore you can only use one SigIntHelper in a app.
43 *
44 * When the signal is received it (optionally) prints a message and ShouldAbort() and WaitAbort() react accordingly.
45 * Also, the signal handler is reset to the previous state (typically, but not necessarily, the default handler) and any
46 * further SIGINT triggers the previously set handler. This allows for apps to handle the the first SIGINT
47 * nicely and allows the user to "SIGINT again" and trigger the previous handler (typically the default one,
48 * i.e. "hard abort").
49 *
50 * Example:
51 *
52 * @code{.cpp}
53 * SigIntHelper sigint;
54 * while (!sigint.ShouldAbort()) {
55 * // do stuff..
56 * }
57 *
58 * if (sigint.ShouldAbort()) {
59 * INFO("We've been asked to stop");
60 * }
61 * @endcode
62 */
64{
65 public:
66 /**
67 * @brief Constructor
68 *
69 * @param[in] warn Print a WARNING() (true, default) or a DEBUG() (false) on signal
70 */
71 SigIntHelper(const bool warn = true);
72
73 /**
74 * @brief Destructor
75 */
77
78 /**
79 * @brief Check if signal was raised and we should abort
80 *
81 * @returns true if signal was raised and we should abort, false otherwise
82 */
84
85 /**
86 * @brief Wait (block) until signal is raised and we should abort
87 *
88 * @param[in] millis Wait at most this long [ms], 0 = forever
89 *
90 * @returns true if the signal was raised, false if timeout expired
91 */
92 bool WaitAbort(const uint32_t millis = 0);
93};
94
95/**
96 * @brief Helper to catch SIGTERM
97 *
98 * On construction this installs a handler for SIGTERM. On destruction it sets the handler back to its previous state.
99 * Note that signal handlers are global and therefore you can only use one SigTermHelper in a app.
100 */
102{
103 public:
104 /**
105 * @brief Constructor
106 *
107 * @param[in] warn Print a WARNING() (true, default) or a DEBUG() (false) on signal
108 */
109 SigTermHelper(const bool warn = true);
110
111 /**
112 * @brief Destructor
113 */
115
116 /**
117 * @brief Check if signal was raised and we should abort
118 *
119 * @returns true if signal was raised and we should abort, false otherwise
120 */
122
123 /**
124 * @brief Wait (block) until signal is raised and we should abort
125 *
126 * @param[in] millis Wait at most this long [ms], 0 = forever
127 *
128 * @returns true if the signal was raised, false if timeout expired
129 */
130 bool WaitAbort(const uint32_t millis = 0);
131};
132
133/**
134 * @brief Helper to catch SIGPIPE
135 *
136 * On construction this installs a handler for SIGPIPE. On destruction it sets the handler back to its previous state.
137 * Note that signal handlers are global and therefore you can only use one SigPipeHelper in a app.
138 */
140{
141 public:
142 /**
143 * @brief Constructor
144 *
145 * @param[in] warn Print a WARNING() (true) or a DEBUG() (false, default)
146 */
147 SigPipeHelper(const bool warn = false);
148
149 /**
150 * @brief Destructor
151 */
153
154 /**
155 * @brief Check if signal was raised
156 *
157 * @returns true if signal was raised, false otherwise
158 */
159 bool Raised();
160};
161
162/**
163 * @brief Helper to print a strack trace on SIGSEGV and SIGABRT
164 *
165 * On construction this installs a handler for SIGSEGV and SIGABRT, which prints a stack trace.
166 * Note that signal handlers are global and therefore you can only use one StacktraceHelper in a app.
167 * It is probably a good idea to only include this in non-Release builds.
168 *
169 * Example:
170 *
171 * @code{.cpp}
172 * int main(int, char**) {
173 * #ifndef NDEBUG
174 * StacktraceHelper stacktrace;
175 * #endif
176 *
177 * // Do stuff...
178 *
179 * return 0;
180 * }
181 * @endcode
182 */
183class StacktraceHelper
184{
185 public:
186 StacktraceHelper();
187 ~StacktraceHelper();
188};
189
190/**
191 * @brief Prints a stacktrace to stderr
192 */
194
195/**
196 * @brief Program options
197 */
199{
200 public:
201 /**
202 * @brief A program option
203 *
204 * Reserved options are: 'h' / "help", 'V' / "version", 'v' / "verbose", 'q' / "quiet", 'J' / "journal", '?', '*',
205 * and ':'.
206 */
207 struct Option
208 {
209 char flag; //!< The flag (some are reserved, see above)
210 bool has_argument; //!< True if flag requires an an argument, false if not
211 const char* name = nullptr; //!< Long option name (or nullptr, some are reserved, see above)
212 };
213
214 /**
215 * @brief Constructor
216 */
217 ProgramOptions(const std::string& app_name, const std::vector<Option>& options);
218
219 /**
220 * @brief Destructor
221 */
223
224 /**
225 * @brief Load arguments from argv[]
226 *
227 * @param[in,out] argc Number of arguments
228 * @param[in,out] argv Command-line arguments
229 * @return
230 */
231 bool LoadFromArgv(int argc, char** argv);
232
233 /**
234 * @brief Print the help screen and exit(0)
235 */
236 virtual void PrintHelp() = 0;
237
238 /**
239 * @brief Print version information
240 */
241 virtual void PrintVersion();
242
243 /**
244 * @brief Handle a command-line flag argument
245 *
246 * @param[in] option The option
247 * @param[in] argument Option argument (if the option requires one)
248 *
249 * @returns true if option was accepted, false otherwise
250 */
251 virtual bool HandleOption(const Option& option, const std::string& argument) = 0;
252
253 /**
254 * @brief Check options, and handle non-flag arguments
255 *
256 * @param[in] args The non-flag arguments
257 *
258 * @returns true if options are good, false otherwise
259 */
260 virtual bool CheckOptions(const std::vector<std::string>& args);
261
262 protected:
263 //! Help screen for common options @hideinitializer
264 static constexpr const char* COMMON_FLAGS_HELP = /* clang-format off */
265 " -h, --help -- Print program help screen, and exit\n"
266 " -V, --version -- Print program, version and license information, and exit\n"
267 " -v, --verbose -- Increase logging verbosity, multiple flags accumulate\n"
268 " -q, --quiet -- Decrease logging verbosity, multiple flags accumulate\n"
269 " -J, --journal -- Use systemd journal logging markers instead of colours (default: auto)\n"; // clang-format on
270
271 std::string app_name_; //!< App name
273 std::vector<std::string> argv_; //!< argv[] of program
274
275 private:
276 std::vector<Option> options_; //!< Program options
277};
278
279/**
280 * @brief App performance stats
281 */
283{
284 PerfStats(); //!< Constructor
285 void Reset(); //!< Reset stats
286 void Update(); //!< Update stats
287
288 // Data, becomes valid after first call to Update()
289 double mem_curr_ = 0.0; //!< Current memory usage [MiB]
290 double mem_peak_ = 0.0; //!< Peak memory usage [MiB]
291 double cpu_curr_ = 0.0; //!< Current (= average since last call to Update()) CPU usage [%]
292 double cpu_avg_ = 0.0; //!< Average (since start) CPU usage [%]
293 double cpu_peak_ = 0.0; //!< Peak CPU usage [%]
294 time::Duration uptime_; //!< Time since start
295 uint64_t pid_ = 0; //!< Process ID
296
297 private:
298 time::Time start_; //!< Start time
299 uint64_t start_m_ = 0; //!< CPU usage
300 uint64_t start_c_ = 0; //!< CPU usage
301 uint64_t last_m_ = 0; //!< CPU usage
302 uint64_t last_c_ = 0; //!< CPU usage
303};
304
305/**
306 * @brief Memory usage
307 */
309{
310 double size_ = 0.0; //!< Total size [MiB]
311 double resident_ = 0.0; //!< Resident set size [MiB]
312 double shared_ = 0.0; //!< Resident shared [MiB]
313 double text_ = 0.0; //!< Text (code) [MiB]
314 double data_ = 0.0; //!< Data + stack [MiB]
315};
316
317/**
318 * @brief Get memory usage
319 *
320 * @returns the current memory usage
321 */
323
324/* ****************************************************************************************************************** */
325} // namespace app
326} // namespace common
327} // namespace fpsdk
328#endif // __FPSDK_COMMON_APP_HPP__
std::vector< std::string > argv_
argv[] of program
Definition app.hpp:273
virtual void PrintHelp()=0
Print the help screen and exit(0)
virtual void PrintVersion()
Print version information.
std::string app_name_
App name.
Definition app.hpp:271
logging::LoggingParams logging_params_
Logging params.
Definition app.hpp:272
ProgramOptions(const std::string &app_name, const std::vector< Option > &options)
Constructor.
virtual bool CheckOptions(const std::vector< std::string > &args)
Check options, and handle non-flag arguments.
bool LoadFromArgv(int argc, char **argv)
Load arguments from argv[].
static constexpr const char * COMMON_FLAGS_HELP
Help screen for common options.
Definition app.hpp:264
virtual bool HandleOption(const Option &option, const std::string &argument)=0
Handle a command-line flag argument.
virtual ~ProgramOptions()
Destructor.
bool ShouldAbort()
Check if signal was raised and we should abort.
SigIntHelper(const bool warn=true)
Constructor.
bool WaitAbort(const uint32_t millis=0)
Wait (block) until signal is raised and we should abort.
SigPipeHelper(const bool warn=false)
Constructor.
bool Raised()
Check if signal was raised.
SigTermHelper(const bool warn=true)
Constructor.
bool WaitAbort(const uint32_t millis=0)
Wait (block) until signal is raised and we should abort.
bool ShouldAbort()
Check if signal was raised and we should abort.
Fixposition SDK: Logging.
Utilities for apps.
Definition app.hpp:35
void PrintStacktrace()
Prints a stacktrace to stderr.
MemUsage GetMemUsage()
Get memory usage.
Fixposition SDK: Common library.
Definition doc.hpp:21
Fixposition SDK.
double shared_
Resident shared [MiB].
Definition app.hpp:312
double resident_
Resident set size [MiB].
Definition app.hpp:311
double text_
Text (code) [MiB].
Definition app.hpp:313
double size_
Total size [MiB].
Definition app.hpp:310
double data_
Data + stack [MiB].
Definition app.hpp:314
double mem_peak_
Peak memory usage [MiB].
Definition app.hpp:290
void Update()
Update stats.
double mem_curr_
Current memory usage [MiB].
Definition app.hpp:289
void Reset()
Reset stats.
time::Duration uptime_
Time since start.
Definition app.hpp:294
uint64_t pid_
Process ID.
Definition app.hpp:295
double cpu_curr_
Current (= average since last call to Update()) CPU usage [%].
Definition app.hpp:291
double cpu_avg_
Average (since start) CPU usage [%].
Definition app.hpp:292
double cpu_peak_
Peak CPU usage [%].
Definition app.hpp:293
const char * name
Long option name (or nullptr, some are reserved, see above)
Definition app.hpp:211
bool has_argument
True if flag requires an an argument, false if not.
Definition app.hpp:210
char flag
The flag (some are reserved, see above)
Definition app.hpp:209
Fixposition SDK: Time utilities.