Anklang 0.3.0-460-gc4ef46ba
ASE — Anklang Sound Engine (C++)

« « « Anklang Documentation
Loading...
Searching...
No Matches
logging.cc
Go to the documentation of this file.
1 // This Source Code Form is licensed MPL-2.0: http://mozilla.org/MPL/2.0
2#include "logging.hh"
3#include "platform.hh"
4#include "path.hh"
5#include "regex.hh"
6#include <cstdarg>
7#include <cstring>
8
9namespace Ase {
10
11LogFlags log_setup (int*) __attribute__ ((__weak__));
12
15{
16 struct timeval tv = { 0, 0 };
17 gettimeofday (&tv, nullptr);
18 return tv.tv_sec * 1000000ULL + tv.tv_usec;
19}
20
21static uint64 programstart_timestamp = timestamp_now();
22static uint32_t log_flags = 0;
23static int log_fd = -1;
24static bool log_colorize = true;
25
26static void
27logstart()
28{
29 if (log_flags) [[likely]] return;
30 log_colorize = AnsiColors::colorize_tty();
31 if (log_setup) {
32 log_flags = log_setup (&log_fd);
33 if (log_fd >= 0)
34 log_flags |= LOG_FILE;
35 } else
36 log_flags |= LOG_STDERR;
37 const time_t now = programstart_timestamp / 1000000;
38 struct tm stm{};
39 localtime_r (&now, &stm);
40 char tbuf[128] = { 0, };
41 strftime (tbuf, sizeof (tbuf) - 1, "%Y-%m-%d %H:%M:%S %z", &stm);
42 const std::string exec = executable_path();
43 const char *bexec = strrchr (exec.c_str(), '/');
44 bexec = bexec ? bexec+1 : exec.c_str();
45 char pidbuf[64] = { 0, };
46 snprintf (pidbuf, sizeof (pidbuf) - 1, " pid=%u", getpid());
47 std::string msg = std::string (bexec) + ": programstart=\"" + tbuf + "\"" + pidbuf + " executable=\"" + executable_path() + "\"";
48 logmsg (msg, "", 0, "");
49}
50
51void
52logmsg (const std::string &msg, const char *const filename, const uint64_t columnline, const char *const function_name)
53{
54 const uint32_t line = uint32_t (columnline), column = columnline >> 32;
55 logstart();
56 ScopedPosixLocale posix_locale; // use POSIX locale for this scope
57 if (msg.empty()) return;
58 String s = msg;
59 if (s[s.size()-1] != '\n')
60 s += "\n";
61 {
62 char tstamp[64] = { 0, };
63 snprintf (tstamp, sizeof (tstamp) - 1, "%.6f: ", 0.000001 * (timestamp_now() - programstart_timestamp));
64 s = tstamp + s;
65 }
66 if ((log_flags & LOG_LOCATIONS) &&
67 filename && filename[0] && function_name) {
68 char linein[128] = { 0, };
69 snprintf (linein, sizeof (linein) - 1, ":%u:%u: logging at: ", line, column);
70 s = filename + std::string (linein) + function_name + ":\n" + s;
71 }
72 if (log_fd == 2 || log_flags & LOG_STDERR)
73 fflush (stderr);
74 if (!log_colorize && log_flags & LOG_STDERR)
75 write (2, s.data(), s.size());
76 if (log_fd >= 0)
77 write (log_fd, s.data(), s.size());
78 if (log_colorize && log_flags & LOG_STDERR) {
79 using namespace AnsiColors;
80 const auto C = color (FG_CYAN), G = color (BOLD, FG_GREEN), B = color (FG_BLUE), Y = color (FG_YELLOW), R = color (RESET);
81 const std::string HEXINT = "0[xX][0-9abcdefABCDEF]+";
82 const std::string FULLFLOAT = "([1-9][0-9]*|0)([.][0-9]*)?([eE][+-]?[0-9]+)?";
83 const std::string FRACTFLOAT = "[.][0-9]+([eE][+-]?[0-9]+)?";
84 const std::string NUMBER = HEXINT + "|" + FULLFLOAT + "|" + FRACTFLOAT;
85 s = Re::sub ("=(" + NUMBER + ")", "=" + Y + "$1" + R, s);
86 s = Re::sub ("=(\"(?:[^\"\\\\]|\\\\.)*\")", "=" + B + "$1" + R, s);
87 s = Re::sub (" (\\w+)=", " " + C + "$1" + R + "=", s);
88 s = Re::sub (": ([a-zA-Z.0-9_:-]+): ", ": " + G + "$1:" + R + " ", s);
89 s = Re::sub ("^(\\d+[.]\\d+):", Y + "$1:" + R, s, Re::M);
90 write (2, s.data(), s.size());
91 }
92}
93
94} // Ase
T c_str(T... args)
static String sub(const String &regex, const String &subst, const String &input, Flags=DEFAULT)
Substitute regex in input by sbref with backreferences $00…$99 or $&.
Definition regex.cc:249
snprintf
T empty(T... args)
fflush
getpid
gettimeofday
localtime_r
std::string color(Colors acolor, Colors c1, Colors c2, Colors c3, Colors c4, Colors c5, Colors c6)
Return ANSI code for the specified color if stdout & stderr should be colorized, see colorize_tty().
Definition platform.cc:190
bool colorize_tty(int fd)
Check whether the tty fd should use colorization, checks ASE_COLOR if fd == -1.
Definition platform.cc:161
The Anklang C++ API namespace.
Definition api.hh:9
uint64_t uint64
A 64-bit unsigned integer, use PRI*64 in format strings.
Definition cxxaux.hh:25
std::string executable_path()
Retrieve the path to the currently running executable.
Definition platform.cc:734
LogFlags
Flags to configure logging behaviour.
Definition logging.hh:26
std::string String
Convenience alias for std::string.
Definition cxxaux.hh:35
LogFlags log_setup(int *) __attribute__((__weak__))
Configurable handler to open log files.
Definition main.cc:152
uint64_t timestamp_now()
Current time in µseconds.
Definition logging.cc:14
write
typedef uint64_t
strftime
strrchr
typedef time_t