From 499fcb776d691da06ec2da9a0fbadc3cbcf8758f Mon Sep 17 00:00:00 2001 From: Determinant Date: Sun, 18 Nov 2018 17:53:58 -0500 Subject: make logger thread-safe and add tty color --- include/salticidae/conn.h | 1 - include/salticidae/netaddr.h | 1 + include/salticidae/util.h | 51 ++++++++++++++++-------------- src/util.cpp | 74 +++++++++++++++++++++++++++++++++++++------- test/test_queue.cpp | 2 +- 5 files changed, 92 insertions(+), 37 deletions(-) diff --git a/include/salticidae/conn.h b/include/salticidae/conn.h index 265a02a..79b1a89 100644 --- a/include/salticidae/conn.h +++ b/include/salticidae/conn.h @@ -27,7 +27,6 @@ #include #include -#include #include #include diff --git a/include/salticidae/netaddr.h b/include/salticidae/netaddr.h index 5639c1b..224d1d4 100644 --- a/include/salticidae/netaddr.h +++ b/include/salticidae/netaddr.h @@ -29,6 +29,7 @@ #include #include #include +#include #include "salticidae/util.h" #include "salticidae/stream.h" diff --git a/include/salticidae/util.h b/include/salticidae/util.h index 7552f8e..ed7d980 100644 --- a/include/salticidae/util.h +++ b/include/salticidae/util.h @@ -32,7 +32,8 @@ #include #include #include -#include +#include +#include #include "salticidae/config.h" #include "salticidae/ref.h" @@ -40,13 +41,14 @@ namespace salticidae { void sec2tv(double t, struct timeval &tv); -void event_add_with_timeout(struct event *ev, double timeout); double gen_rand_timeout(double base_timeout, double alpha = 0.5); std::string trim(const std::string &s, const std::string &space = "\t\r\n "); std::vector split(const std::string &s, const std::string &delim); std::vector trim_all(const std::vector &ss); +std::string vstringprintf(const char *fmt, va_list ap); +std::string stringprintf(const char *fmt, ...); class SalticidaeError: public std::exception { std::string msg; @@ -55,47 +57,48 @@ class SalticidaeError: public std::exception { template SalticidaeError(const std::string &fmt, Args... args) { - int guessed_size = 128; - std::string buff; - for (;;) - { - buff.resize(guessed_size); - int nwrote = snprintf((char *)buff.data(), guessed_size, fmt.c_str(), args...); - if (nwrote < 0 || nwrote == guessed_size) - { - guessed_size <<= 1; - continue; - } - buff.resize(nwrote); - msg = std::move(buff); - break; - } + msg = stringprintf(fmt.c_str(), args...); } operator std::string() const { return msg; } const char *what() const throw() override { return msg.c_str(); } }; +extern const char *TTY_COLOR_RED; +extern const char *TTY_COLOR_GREEN; +extern const char *TTY_COLOR_YELLOW; +extern const char *TTY_COLOR_BLUE; +extern const char *TTY_COLOR_MAGENT; +extern const char *TTY_COLOR_CYAN; +extern const char *TTY_COLOR_RESET; + class Logger { + const char *color_info; + const char *color_debug; + const char *color_warning; + const char *color_error; protected: - FILE *output; + int output; bool opened; const char *prefix; - void write(const char *tag, const char *fmt, va_list ap); + void write(const char *tag, const char *color, + const char *fmt, va_list ap); + void set_color(); public: - Logger(const char *prefix, FILE *file = stderr): - output(file), opened(false), prefix(prefix) {} + Logger(const char *prefix, int fd = 2): + output(fd), opened(false), prefix(prefix) { set_color(); } Logger(const char *prefix, const char *filename): opened(true), prefix(prefix) { - if ((output = fopen(filename, "w")) == nullptr) + if ((output = open(filename, O_CREAT | O_WRONLY)) == -1) throw SalticidaeError("logger cannot open file %s", filename); + set_color(); } - ~Logger() { if (opened) fclose(output); } + ~Logger() { if (opened) close(output); } - void debug(const char *fmt, ...); void info(const char *fmt, ...); + void debug(const char *fmt, ...); void warning(const char *fmt, ...); void error(const char *fmt, ...); }; diff --git a/src/util.cpp b/src/util.cpp index b975f13..d764ad5 100644 --- a/src/util.cpp +++ b/src/util.cpp @@ -27,13 +27,21 @@ #include #include #include -#include #include +#include #include "salticidae/util.h" namespace salticidae { +const char *TTY_COLOR_RED = "\x1b[31m"; +const char *TTY_COLOR_GREEN = "\x1b[32m"; +const char *TTY_COLOR_YELLOW = "\x1b[33m"; +const char *TTY_COLOR_BLUE = "\x1b[34m"; +const char *TTY_COLOR_MAGENTA = "\x1b[35m"; +const char *TTY_COLOR_CYAN = "\x1b[36m"; +const char *TTY_COLOR_RESET = "\x1b[0m"; + void sec2tv(double t, struct timeval &tv) { tv.tv_sec = trunc(t); tv.tv_usec = trunc((t - tv.tv_sec) * 1e6); @@ -43,6 +51,32 @@ double gen_rand_timeout(double base_timeout, double alpha) { return base_timeout + rand() / (double)RAND_MAX * alpha * base_timeout; } +std::string vstringprintf(const char *fmt, va_list ap) { + int guessed_size = 1024; + std::string buff; + buff.resize(guessed_size); + int nwrote = vsnprintf(&buff[0], guessed_size, fmt, ap); + if (nwrote < 0) buff = ""; + else + { + buff.resize(nwrote); + if (nwrote > guessed_size) + { + if (vsnprintf(&buff[0], nwrote, fmt, ap) != nwrote) + buff = ""; + } + } + return std::move(buff); +} + +std::string stringprintf(const char *fmt, ...) { + va_list ap; + va_start(ap, fmt); + auto ret = vstringprintf(fmt, ap); + va_end(ap); + return std::move(ret); +} + const std::string get_current_datetime() { /* credit: http://stackoverflow.com/a/41381479/544806 */ char fmt[64], buf[64]; @@ -56,36 +90,54 @@ const std::string get_current_datetime() { SalticidaeError::SalticidaeError() : msg("unknown") {} -void Logger::write(const char *tag, const char *fmt, va_list ap) { - fprintf(output, "%s [%s %s] ", get_current_datetime().c_str(), prefix, tag); - vfprintf(output, fmt, ap); - fprintf(output, "\n"); +void Logger::set_color() { + if (isatty(output)) + { + color_info = TTY_COLOR_GREEN; + color_debug = TTY_COLOR_BLUE; + color_warning = TTY_COLOR_YELLOW; + color_error = TTY_COLOR_RED; + } + else + { + color_info = color_debug = color_warning = color_error = nullptr; + } } -void Logger::debug(const char *fmt, ...) { +void Logger::write(const char *tag, const char *color, + const char *fmt, va_list ap) { + std::string buff = color ? color : ""; + buff += stringprintf("%s [%s %s] ", get_current_datetime().c_str(), prefix, tag); + if (color) buff += TTY_COLOR_RESET; + buff += vstringprintf(fmt, ap); + buff.push_back('\n'); + ::write(output, &buff[0], buff.length()); +} + +void Logger::info(const char *fmt, ...) { va_list ap; va_start(ap, fmt); - write("debug", fmt, ap); + write("info", color_info, fmt, ap); va_end(ap); } -void Logger::info(const char *fmt, ...) { +void Logger::debug(const char *fmt, ...) { va_list ap; va_start(ap, fmt); - write("info", fmt, ap); + write("debug", color_debug, fmt, ap); va_end(ap); } void Logger::warning(const char *fmt, ...) { va_list ap; va_start(ap, fmt); - write("warn", fmt, ap); + write("warn", color_warning, fmt, ap); va_end(ap); } void Logger::error(const char *fmt, ...) { va_list ap; va_start(ap, fmt); - write("error", fmt, ap); + write("error", color_error, fmt, ap); va_end(ap); } diff --git a/test/test_queue.cpp b/test/test_queue.cpp index 5a7b548..41c6f88 100644 --- a/test/test_queue.cpp +++ b/test/test_queue.cpp @@ -26,7 +26,7 @@ void test_mpsc(int nproducers = 16, int nops = 100000, size_t burst_size = 128) salticidae::Event timer(ec, -1, [&ec, &collected, total](int, short) { if (collected.load() == total) ec.stop(); }); - timer.add_with_timeout(1, EV_TIMEOUT | EV_PERSIST); + timer.add_with_timeout(1, 0); ec.dispatch(); }); for (int i = 0; i < nproducers; i++) -- cgit v1.2.3-70-g09d2