From bccf8c69cf6998f4438af7217608f29042b63e27 Mon Sep 17 00:00:00 2001 From: folkert van heusden Date: Sun, 21 Apr 2024 11:49:13 +0200 Subject: [PATCH] Syslog logging when file i/o is not available (ESP32) --- debugger.cpp | 20 ++++++++++++++++++++ log.cpp | 47 +++++++++++++++++++++++++++++++++++++++-------- log.h | 7 ++++--- main.cpp | 2 +- 4 files changed, 64 insertions(+), 12 deletions(-) diff --git a/debugger.cpp b/debugger.cpp index 114dfa3..1a9e921 100644 --- a/debugger.cpp +++ b/debugger.cpp @@ -1067,6 +1067,25 @@ void debugger(console *const cnsl, bus *const b, std::atomic_uint32_t *const sto setll(ll_screen, ll_file); } } + else if (parts[0] == "setll" && parts.size() == 2) { + auto ll_parts = split(parts[1], ","); + + if (ll_parts.size() != 2) + cnsl->put_string_lf("Loglevel for either screen or file missing"); + else { + log_level_t ll_screen = parse_ll(ll_parts[0]); + log_level_t ll_file = parse_ll(ll_parts[1]); + + setll(ll_screen, ll_file); + } + + continue; + } + else if (parts[0] == "setsl" && parts.size() == 3) { + setloghost(parts.at(1).c_str(), parse_ll(parts[2])); + + continue; + } else if (cmd == "qi") { show_queued_interrupts(cnsl, c); @@ -1106,6 +1125,7 @@ void debugger(console *const cnsl, bus *const b, std::atomic_uint32_t *const sto " registers", "trace/t - toggle tracing", "setll - set loglevel: terminal,file", + "setsl - set syslog target: requires a hostname and a loglevel", "turbo - toggle turbo mode (cannot be interrupted)", "debug - enable CPU debug mode", "bt - show backtrace - need to enable debug first", diff --git a/log.cpp b/log.cpp index 1eb2b8c..c9986cc 100644 --- a/log.cpp +++ b/log.cpp @@ -7,6 +7,9 @@ #include #include #include +#include +#include +#include #include #include "error.h" @@ -16,9 +19,11 @@ static const char *logfile = strdup("/tmp/kek.log"); +static sockaddr_in syslog_ip_addr = { }; +static bool is_file = true; log_level_t log_level_file = warning; log_level_t log_level_screen = warning; -FILE *lfh = nullptr; +FILE *lfh = nullptr; static int lf_uid = -1; static int lf_gid = -1; static bool l_timestamp = true; @@ -30,23 +35,37 @@ int gettid() } #endif -void setlog(const char *lf, const log_level_t ll_file, const log_level_t ll_screen, const bool timestamp) +void setlogfile(const char *const lf, const log_level_t ll_file, const log_level_t ll_screen, const bool timestamp) { if (lfh) fclose(lfh); free((void *)logfile); + is_file = true; + logfile = lf ? strdup(lf) : nullptr; log_level_file = ll_file; log_level_screen = ll_screen; - l_timestamp = timestamp; + l_timestamp = timestamp; atexit(closelog); } +void setloghost(const char *const host, const log_level_t ll) +{ + inet_aton(host, &syslog_ip_addr.sin_addr); + syslog_ip_addr.sin_port = htons(514); + + is_file = false; + + log_level_file = ll; + + l_timestamp = false; +} + void setll(const log_level_t ll_file, const log_level_t ll_screen) { log_level_file = ll_file; @@ -59,6 +78,15 @@ void setloguid(const int uid, const int gid) lf_gid = gid; } +void send_syslog(const int ll, const std::string & what) +{ + std::string msg = format("<%d>%s", 16 * 8 + ll, what.c_str()); + + int s = socket(AF_INET, SOCK_DGRAM, 0); + (void)sendto(s, msg.c_str(), msg.size(), 0, reinterpret_cast(&syslog_ip_addr), sizeof syslog_ip_addr); + close(s); +} + void closelog() { if (lfh) { @@ -76,7 +104,6 @@ void dolog(const log_level_t ll, const char *fmt, ...) lfh = fopen(logfile, "a+"); if (!lfh) error_exit(true, "Cannot access log-file %s", logfile); - #if !defined(_WIN32) if (lf_uid != -1 && fchown(fileno(lfh), lf_uid, lf_gid) == -1) error_exit(true, "Cannot change logfile (%s) ownership", logfile); @@ -113,23 +140,27 @@ void dolog(const log_level_t ll, const char *fmt, ...) tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec, int(now % 1000000), ll_names[ll]); + if (ll <= log_level_file && is_file == false) + send_syslog(ll, str); #if !defined(ESP32) - if (ll >= log_level_file && lfh != nullptr) + if (ll <= log_level_file && lfh != nullptr) fprintf(lfh, "%s%s\n", ts_str, str); #endif - if (ll >= log_level_screen) + if (ll <= log_level_screen) printf("%s%s\r\n", ts_str, str); free(ts_str); } else { + if (ll <= log_level_file && is_file == false) + send_syslog(ll, str); #if !defined(ESP32) - if (ll >= log_level_file && lfh != nullptr) + if (ll <= log_level_file && lfh != nullptr) fprintf(lfh, "%s\n", str); #endif - if (ll >= log_level_screen) + if (ll <= log_level_screen) printf("%s\r\n", str); } diff --git a/log.h b/log.h index 2cfce16..88172c0 100644 --- a/log.h +++ b/log.h @@ -8,10 +8,11 @@ #include "config.h" -typedef enum { debug, info, warning, ll_error, none } log_level_t; // TODO ll_ prefix +typedef enum { ll_emerg = 0, ll_alert, ll_critical, ll_error, warning, notice, info, debug, none } log_level_t; // TODO ll_ prefix log_level_t parse_ll(const std::string & str); -void setlog(const char *lf, const log_level_t ll_file, const log_level_t ll_screen, const bool l_timestamp); +void setlogfile(const char *const lf, const log_level_t ll_file, const log_level_t ll_screen, const bool l_timestamp); +void setloghost(const char *const host, const log_level_t ll); void setll(const log_level_t ll_file, const log_level_t ll_screen); void setloguid(const int uid, const int gid); void closelog(); @@ -23,7 +24,7 @@ void dolog(const log_level_t ll, const char *fmt, ...); #define DOLOG(ll, always, fmt, ...) do { \ extern log_level_t log_level_file, log_level_screen; \ \ - if (always || ll >= log_level_file || ll >= log_level_screen) \ + if (always || ll <= log_level_file || ll <= log_level_screen) \ dolog(ll, fmt, ##__VA_ARGS__); \ } while(0) #endif diff --git a/main.cpp b/main.cpp index 98198fa..d2161aa 100644 --- a/main.cpp +++ b/main.cpp @@ -493,7 +493,7 @@ int main(int argc, char *argv[]) console *cnsl = nullptr; - setlog(logfile, ll_file, ll_screen, timestamp); + setlogfile(logfile, ll_file, ll_screen, timestamp); if (validate_json.empty() == false) return run_cpu_validation(validate_json);