schematika arithmetic with facets + multi-argument runtime polymorphism
- C++ 94.2%
- CMake 5.8%
| .github/workflows | ||
| cmake | ||
| example | ||
| img | ||
| include/indentlog | ||
| utest | ||
| BUILD.md | ||
| CMakeLists.txt | ||
| FAQ | ||
| FILES | ||
| LICENSE | ||
| README.md | ||
indentlog -- logging with automatic call-graph indenting
Indentlog is a lightweight header-only library for console logging.
Features
- header-only; nothing to link
- easy-to-read format uses indenting to show call structure. indentation has user-controlled upper limit to preserve readability with deeply nested call graphs
- colorized output using vt100 color codes (ansi or xterm)
- automatically captures + displays timestamp, function name and code location. supports several function-name formats to reflect tradeoff readability for precision
- application code may issue logging code that contains embedded newlines and/or color escapes; logger preserves indentation.
- logger is 'truthy' -> only pay for formatting when entry points is enabled.
- also provides family of convenience stream-inserters
Getting Started
copy repository locally
$ git clone git@github.com:rconybea/indentlog.git
$ ls -d indentlog
indentlog
build & install
$ cd indentlog
$ mkdir build
$ cd build
$ cmake -DCMAKE_INSTALL_PREFIX=/usr/local ..
$ make
$ make install
alternatively, if you're a nix user:
$ git clone git@github.com:rconybea/indentlog-nix.git
$ ls -d indentlog-nix
indentlog-nix
$ cd indentlog-nix
$ nix-build
For some more detail see BUILD.md
Examples
1
#include "indentlog/scope.hpp"
using namespace xo;
void inner(int x) {
scope log(XO_ENTER0(always), ":x ", x);
}
void outer(int y) {
scope log(XO_ENTER0(always), ":y ", y);
inner(2*y);
}
int
main(int argc, char ** argv) {
outer(123);
}
- indentlog types are provided in the
xonamespace. macros are prefixed withXO_ - indentation reflects call structure. We don't see anything for
main(), since we didn't put any logging there
2 slightly more elaborate example
/* examples ex2/ex2.cpp */
#include "indentlog/scope.hpp"
using namespace xo;
int
fib(int n) {
scope log(XO_ENTER0(info), ":n ", n);
int retval = 1;
if (n >= 2) {
retval = fib(n - 1) + fib(n - 2);
log && log(":n ", n);
}
log.end_scope("<- :retval ", retval);
return retval;
}
int
main(int argc, char ** argv) {
log_config::min_log_level = xo::log_level::info;
log_config::indent_width = 4;
int n = 4;
scope log(XO_ENTER0(info), ":n ", 4);
int fn = fib(n);
log && log(":n ", n);
log && log("<- :fib(n) ", fn);
}
- global configuration settings live in the
xo::log_configclass. see log_config.hpp - the recommended form
log && log(...)tests whether logging at this site is enabled /before/ evaluating/formatting the log message; when logging is disabled, this saves the cost of computing and formatting that message.
3 example exposing runtime configuration options
/* examples ex3/ex3.cpp */
#include "indentlog/scope.hpp"
using namespace xo;
int
fib(int n) {
scope log(XO_ENTER0(info), tag("n", n));
int retval = 1;
if (n >= 2) {
retval = fib(n - 1) + fib(n - 2);
}
log.end_scope(tag("n", n), " <-", xtag("retval", retval));
return retval;
}
int
main(int argc, char ** argv) {
log_config::min_log_level = log_level::info;
log_config::time_enabled = true;
log_config::time_local_flag = true;
log_config::style = FS_Streamlined;
log_config::indent_width = 4;
log_config::max_indent_width = 30;
log_config::location_tab = 80;
log_config::encoding = CE_Xterm;
log_config::function_entry_color = 69;
log_config::function_exit_color = 70;
log_config::code_location_color = 166;
int n = 3;
scope log(XO_ENTER0(info), ":n ", 4);
int fn = fib(n);
log && log(tag("n", n));
log && log("<-", xtag("fib(n)", fn));
}
/* ex3/ex3.cpp */
4 example: function signatures
/* @file ex4.cpp */
#include "indentlog/scope.hpp"
using namespace xo;
class Quadratic {
public:
Quadratic(double a, double b, double c) : a_{a}, b_{b}, c_{c} {}
double operator() (double x) const {
scope log(XO_ENTER0(info), tag("a", a_), xtag("b", b_), xtag("c", c_), xtag("x", x));
double retval = (a_ * x * x) + (b_ * x) + c_;
log.end_scope("<-", xtag("retval", retval));
return retval;
}
private:
double a_ = 0.0;;
double b_ = 0.0;
double c_ = 0.0;
};
int
main(int argc, char ** argv) {
//log_config::style = FS_Pretty;
log_config::style = FS_Streamlined;
log_config::min_log_level = log_level::info;
scope log(XO_ENTER0(info));
Quadratic quadratic(2.0, -5.0, 7.0);
double x = 3.0;
double r = 0.0;
log_config::style = FS_Pretty;
r = quadratic(x);
log_config::style = FS_Streamlined;
r = quadratic(x);
log_config::style = FS_Simple;
r = quadratic(x);
}
/* end ex4.cpp */
output:



