Fixposition SDK 0.0.0-heads/main-0-g4e80ed3
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 SIGPIPE
97 *
98 * On construction this installs a handler for SIGPIE. 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 SigPipeHelper in a app.
100 */
102{
103 public:
104 /**
105 * @brief Constructor
106 *
107 * @param[in] warn Print a WARNING() (true) or a DEBUG() (false, default)
108 */
109 SigPipeHelper(const bool warn = false);
110
111 /**
112 * @brief Destructor
113 */
115
116 /**
117 * @brief Check if signal was raised
118 *
119 * @returns true if signal was raised, false otherwise
120 */
121 bool Raised();
122};
123
124/**
125 * @brief Helper to print a strack trace on SIGSEGV and SIGABRT
126 *
127 * On construction this installs a handler for SIGSEGV and SIGABRT, which prints a stack trace.
128 * Note that signal handlers are global and therefore you can only use one StacktraceHelper in a app.
129 * It is probably a good idea to only include this in non-Release builds.
130 *
131 * Example:
132 *
133 * @code{.cpp}
134 * int main(int, char**) {
135 * #ifndef NDEBUG
136 * StacktraceHelper stacktrace;
137 * #endif
138 *
139 * // Do stuff...
140 *
141 * return 0;
142 * }
143 * @endcode
144 */
146{
147 public:
150};
151
152/**
153 * @brief Prints a stacktrace to stderr
154 */
156
157/**
158 * @brief Program options
159 */
161{
162 public:
163 /**
164 * @brief A program option
165 *
166 * Reserved options are: 'h' / "help", 'V' / "version", 'v' / "verbose", 'q' / "quiet", 'J' / "journal", '?', '*',
167 * and ':'.
168 */
169 struct Option
170 {
171 char flag; //!< The flag (some are reserved, see above)
172 bool has_argument; //!< True if flag requires an an argument, false if not
173 const char* name = nullptr; //!< Long option name (or nullptr, some are reserved, see above)
174 };
175
176 /**
177 * @brief Constructor
178 */
179 ProgramOptions(const std::string& app_name, const std::vector<Option>& options);
180
181 /**
182 * @brief Destructor
183 */
185
186 /**
187 * @brief Load arguments from argv[]
188 *
189 * @param[in,out] argc Number of arguments
190 * @param[in,out] argv Command-line arguments
191 * @return
192 */
193 bool LoadFromArgv(int argc, char** argv);
194
195 /**
196 * @brief Print the help screen and exit(0)
197 */
198 virtual void PrintHelp() = 0;
199
200 /**
201 * @brief Print version information
202 */
203 virtual void PrintVersion();
204
205 /**
206 * @brief Handle a command-line flag argument
207 *
208 * @param[in] option The option
209 * @param[in] argument Option argument (if the option requires one)
210 *
211 * @returns true if option was accepted, false otherwise
212 */
213 virtual bool HandleOption(const Option& option, const std::string& argument) = 0;
214
215 /**
216 * @brief Check options, and handle non-flag arguments
217 *
218 * @param[in] args The non-flag arguments
219 *
220 * @returns true if options are good, false otherwise
221 */
222 virtual bool CheckOptions(const std::vector<std::string>& args);
223
224 protected:
225 //! Help screen for common options @hideinitializer
226 static constexpr const char* COMMON_FLAGS_HELP = /* clang-format off */
227 " -h, --help -- Print program help screen, and exit\n"
228 " -V, --version -- Print program, version and license information, and exit\n"
229 " -v, --verbose / -q, --quiet\n"
230 " -- Increase / decrease logging verbosity, multiple flags accumulate\n"
231 " -J, --journal -- Use systemd journal logging markers instead of colours\n"; // clang-format on
232
233 std::string app_name_; //!< App name
235 std::vector<std::string> argv_; //!< argv[] of program
236
237 private:
238 std::vector<Option> options_; //!< Program options
239};
240
241/**
242 * @brief App performance stats
243 */
245{
246 PerfStats(); //!< Constructor
247 void Reset(); //!< Reset stats
248 void Update(); //!< Update stats
249
250 // Data, becomes valid after first call to Update()
251 double mem_curr_ = 0.0; //!< Current memory usage [MiB]
252 double mem_peak_ = 0.0; //!< Peak memory usage [MiB]
253 double cpu_curr_ = 0.0; //!< Current (= average since last call to Update()) CPU usage [%]
254 double cpu_avg_ = 0.0; //!< Average (since start) CPU usage [%]
255 double cpu_peak_ = 0.0; //!< Peak CPU usage [%]
256 time::Duration uptime_; //!< Time since start
257 uint64_t pid_ = 0; //!< Process ID
258
259 private:
260 time::Time start_; //!< Start time
261 uint64_t start_m_ = 0; //!< CPU usage
262 uint64_t start_c_ = 0; //!< CPU usage
263 uint64_t last_m_ = 0; //!< CPU usage
264 uint64_t last_c_ = 0; //!< CPU usage
265};
266
267/**
268 * @brief Memory usage
269 */
271{
272 double size_ = 0.0; // Total size [MiB]
273 double resident_ = 0.0; // Resident set size [MiB]
274 double shared_ = 0.0; // Resident shared [MiB]
275 double text_ = 0.0; // Text (code) [MiB]
276 double data_ = 0.0; // Data + stack [MiB]
277};
278
279/**
280 * @brief Get memory usage
281 *
282 * @returns the current memory usage
283 */
285
286/* ****************************************************************************************************************** */
287} // namespace app
288} // namespace common
289} // namespace fpsdk
290#endif // __FPSDK_COMMON_APP_HPP__
std::vector< std::string > argv_
argv[] of program
Definition app.hpp:235
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:233
logging::LoggingParams logging_params_
Logging params.
Definition app.hpp:234
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:226
virtual bool HandleOption(const Option &option, const std::string &argument)=0
Handle a command-line flag argument.
virtual ~ProgramOptions()
Destructor.
Helper to catch SIGINT (CTRL-c)
Definition app.hpp:64
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.
Helper to catch SIGPIPE.
Definition app.hpp:102
SigPipeHelper(const bool warn=false)
Constructor.
bool Raised()
Check if signal was raised.
Helper to print a strack trace on SIGSEGV and SIGABRT.
Definition app.hpp:146
Fixposition SDK: Logging.
void PrintStacktrace()
Prints a stacktrace to stderr.
MemUsage GetMemUsage()
Get memory usage.
Fixposition SDK.
App performance stats.
Definition app.hpp:245
double mem_peak_
Peak memory usage [MiB].
Definition app.hpp:252
void Update()
Update stats.
double mem_curr_
Current memory usage [MiB].
Definition app.hpp:251
void Reset()
Reset stats.
time::Duration uptime_
Time since start.
Definition app.hpp:256
uint64_t pid_
Process ID.
Definition app.hpp:257
double cpu_curr_
Current (= average since last call to Update()) CPU usage [%].
Definition app.hpp:253
double cpu_avg_
Average (since start) CPU usage [%].
Definition app.hpp:254
double cpu_peak_
Peak CPU usage [%].
Definition app.hpp:255
const char * name
Long option name (or nullptr, some are reserved, see above)
Definition app.hpp:173
bool has_argument
True if flag requires an an argument, false if not.
Definition app.hpp:172
char flag
The flag (some are reserved, see above)
Definition app.hpp:171
Fixposition SDK: Time utilities.