Syslog logging when file i/o is not available (ESP32)

This commit is contained in:
folkert van heusden 2024-04-21 11:49:13 +02:00
parent fe68ef9134
commit bccf8c69cf
Signed by untrusted user who does not match committer: folkert
GPG key ID: 6B6455EDFEED3BD1
4 changed files with 64 additions and 12 deletions

View file

@ -1067,6 +1067,25 @@ void debugger(console *const cnsl, bus *const b, std::atomic_uint32_t *const sto
setll(ll_screen, ll_file); 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") { else if (cmd == "qi") {
show_queued_interrupts(cnsl, c); show_queued_interrupts(cnsl, c);
@ -1106,6 +1125,7 @@ void debugger(console *const cnsl, bus *const b, std::atomic_uint32_t *const sto
" registers", " registers",
"trace/t - toggle tracing", "trace/t - toggle tracing",
"setll - set loglevel: terminal,file", "setll - set loglevel: terminal,file",
"setsl - set syslog target: requires a hostname and a loglevel",
"turbo - toggle turbo mode (cannot be interrupted)", "turbo - toggle turbo mode (cannot be interrupted)",
"debug - enable CPU debug mode", "debug - enable CPU debug mode",
"bt - show backtrace - need to enable debug first", "bt - show backtrace - need to enable debug first",

43
log.cpp
View file

@ -7,6 +7,9 @@
#include <string.h> #include <string.h>
#include <time.h> #include <time.h>
#include <unistd.h> #include <unistd.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <sys/types.h> #include <sys/types.h>
#include "error.h" #include "error.h"
@ -16,6 +19,8 @@
static const char *logfile = strdup("/tmp/kek.log"); 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_file = warning;
log_level_t log_level_screen = warning; log_level_t log_level_screen = warning;
FILE *lfh = nullptr; FILE *lfh = nullptr;
@ -30,13 +35,15 @@ int gettid()
} }
#endif #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) if (lfh)
fclose(lfh); fclose(lfh);
free((void *)logfile); free((void *)logfile);
is_file = true;
logfile = lf ? strdup(lf) : nullptr; logfile = lf ? strdup(lf) : nullptr;
log_level_file = ll_file; log_level_file = ll_file;
@ -47,6 +54,18 @@ void setlog(const char *lf, const log_level_t ll_file, const log_level_t ll_scre
atexit(closelog); 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) void setll(const log_level_t ll_file, const log_level_t ll_screen)
{ {
log_level_file = ll_file; log_level_file = ll_file;
@ -59,6 +78,15 @@ void setloguid(const int uid, const int gid)
lf_gid = 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<sockaddr *>(&syslog_ip_addr), sizeof syslog_ip_addr);
close(s);
}
void closelog() void closelog()
{ {
if (lfh) { if (lfh) {
@ -76,7 +104,6 @@ void dolog(const log_level_t ll, const char *fmt, ...)
lfh = fopen(logfile, "a+"); lfh = fopen(logfile, "a+");
if (!lfh) if (!lfh)
error_exit(true, "Cannot access log-file %s", logfile); error_exit(true, "Cannot access log-file %s", logfile);
#if !defined(_WIN32) #if !defined(_WIN32)
if (lf_uid != -1 && fchown(fileno(lfh), lf_uid, lf_gid) == -1) if (lf_uid != -1 && fchown(fileno(lfh), lf_uid, lf_gid) == -1)
error_exit(true, "Cannot change logfile (%s) ownership", logfile); 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), 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]); ll_names[ll]);
if (ll <= log_level_file && is_file == false)
send_syslog(ll, str);
#if !defined(ESP32) #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); fprintf(lfh, "%s%s\n", ts_str, str);
#endif #endif
if (ll >= log_level_screen) if (ll <= log_level_screen)
printf("%s%s\r\n", ts_str, str); printf("%s%s\r\n", ts_str, str);
free(ts_str); free(ts_str);
} }
else { else {
if (ll <= log_level_file && is_file == false)
send_syslog(ll, str);
#if !defined(ESP32) #if !defined(ESP32)
if (ll >= log_level_file && lfh != nullptr) if (ll <= log_level_file && lfh != nullptr)
fprintf(lfh, "%s\n", str); fprintf(lfh, "%s\n", str);
#endif #endif
if (ll >= log_level_screen) if (ll <= log_level_screen)
printf("%s\r\n", str); printf("%s\r\n", str);
} }

7
log.h
View file

@ -8,10 +8,11 @@
#include "config.h" #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); 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 setll(const log_level_t ll_file, const log_level_t ll_screen);
void setloguid(const int uid, const int gid); void setloguid(const int uid, const int gid);
void closelog(); void closelog();
@ -23,7 +24,7 @@ void dolog(const log_level_t ll, const char *fmt, ...);
#define DOLOG(ll, always, fmt, ...) do { \ #define DOLOG(ll, always, fmt, ...) do { \
extern log_level_t log_level_file, log_level_screen; \ 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__); \ dolog(ll, fmt, ##__VA_ARGS__); \
} while(0) } while(0)
#endif #endif

View file

@ -493,7 +493,7 @@ int main(int argc, char *argv[])
console *cnsl = nullptr; console *cnsl = nullptr;
setlog(logfile, ll_file, ll_screen, timestamp); setlogfile(logfile, ll_file, ll_screen, timestamp);
if (validate_json.empty() == false) if (validate_json.empty() == false)
return run_cpu_validation(validate_json); return run_cpu_validation(validate_json);