Verified Commit 119ee8c6 authored by Karel Koci's avatar Karel Koci 🤘

Split off logging to its own file

parent 9d2e3c86
......@@ -27,7 +27,8 @@ libupdater_MODULES := \
journal \
locks \
picosat \
util
util \
logging
ifdef COV
libupdater_MODULES += lcoverage.embed
endif
......
......@@ -19,6 +19,7 @@
#include "arguments.h"
#include "util.h"
#include "logging.h"
#include <unistd.h>
#include <stdlib.h>
......
......@@ -19,6 +19,7 @@
#include "events.h"
#include "util.h"
#include "logging.h"
#include "embed_types.h"
#include <event2/event.h>
......
......@@ -19,6 +19,7 @@
#include "inject.h"
#include "util.h"
#include "logging.h"
void inject_func_n(lua_State *L, const char *module, const struct inject_func *inject, size_t count) {
// Inject the functions
......
......@@ -19,6 +19,7 @@
#include "interpreter.h"
#include "util.h"
#include "logging.h"
#include "events.h"
#include "journal.h"
#include "locks.h"
......
......@@ -19,6 +19,7 @@
#include "journal.h"
#include "util.h"
#include "logging.h"
#include "inject.h"
#include <lua.h>
......
......@@ -20,6 +20,7 @@
#include "locks.h"
#include "inject.h"
#include "util.h"
#include "logging.h"
#include <lauxlib.h>
#include <lualib.h>
......
/*
* Copyright 2018, CZ.NIC z.s.p.o. (http://www.nic.cz/)
*
* This file is part of the turris updater.
*
* Updater is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Updater is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Updater. If not, see <http://www.gnu.org/licenses/>.
*/
#include "logging.h"
#include <syslog.h>
#include <errno.h>
#include <stdarg.h>
#include <string.h>
struct level_info {
const char *prefix;
const char *name;
int syslog_prio;
};
static const struct level_info levels[] = {
[LL_DISABLE] = { "!!!!", "DISABLE", LOG_CRIT }, // This shouldn't actually appear
[LL_DIE] = { "\x1b[31;1mDIE\x1b[0m", "DIE", LOG_CRIT },
[LL_ERROR] = { "\x1b[31mERROR\x1b[0m", "ERROR", LOG_ERR },
[LL_WARN] = { "\x1b[35mWARN\x1b[0m", "WARN", LOG_WARNING },
[LL_INFO] = { "\x1b[34mINFO\x1b[0m", "INFO", LOG_INFO },
[LL_DBG] = { "DEBUG", "DBG", LOG_DEBUG },
[LL_TRACE] = { "TRACE", "TRACE", LOG_DEBUG },
[LL_UNKNOWN] = { "????", "UNKNOWN", LOG_WARNING }
};
static enum log_level syslog_level = LL_DISABLE;
static enum log_level stderr_level = LL_WARN;
static bool syslog_opened = false;
bool state_log_enabled = false;
void set_state_log(bool state_log) {
state_log_enabled = state_log;
}
void state_dump(const char *msg) {
if (state_log_enabled) {
FILE *f = fopen("/tmp/update-state/state", "w");
if (f) {
fprintf(f, "%s\n", msg);
fclose(f);
} else {
WARN("Could not dump state: %s", strerror(errno));
}
}
}
void err_dump(const char *msg) {
if (state_log_enabled) {
FILE *f = fopen("/tmp/update-state/last_error", "w");
if (f) {
fprintf(f, "%s\n", msg);
fclose(f);
}
}
}
void log_internal(enum log_level level, const char *file, size_t line, const char *func, const char *format, ...) {
bool do_syslog = (level <= syslog_level);
bool do_stderr = (level <= stderr_level);
if (!do_syslog && !do_stderr)
return;
va_list args;
va_start(args, format);
size_t msg_size = vsnprintf(NULL, 0, format, args) + 1;
va_end(args);
char *msg = alloca(msg_size);
va_start(args, format);
vsprintf(msg, format, args);
va_end(args);
if (do_syslog) {
if (!syslog_opened)
log_syslog_name("updater");
syslog(LOG_MAKEPRI(LOG_DAEMON, levels[level].syslog_prio), "%s:%zu (%s): %s", file, line, func, msg);
}
if (do_stderr) {
if (stderr_level < LL_DBG)
fprintf(stderr, "%s:%s\n", levels[level].prefix, msg);
else
fprintf(stderr, "%s:%s:%zu (%s):%s\n", levels[level].prefix, file, line, func, msg);
}
if (level == LL_DIE) {
state_dump("error");
err_dump(msg);
}
}
bool would_log(enum log_level level) {
return (level <= syslog_level) || (level <= stderr_level);
}
void log_buffer_init(struct log_buffer *buff, enum log_level level) {
if (would_log(level)) {
buff->f = open_memstream(&buff->char_buffer, &buff->buffer_len);
if (buff->f)
return;
WARN("Message creation failed!");
}
buff->f = NULL;
}
void log_syslog_level(enum log_level level) {
syslog_level = level;
}
void log_stderr_level(enum log_level level) {
stderr_level = level;
}
void log_syslog_name(const char *name) {
ASSERT(!syslog_opened);
openlog(name, LOG_CONS | LOG_PID, LOG_DAEMON);
syslog_opened = true;
}
enum log_level log_level_get(const char *level) {
for (size_t i = 0; i < sizeof levels / sizeof *levels; i ++) {
if (strcasecmp(level, levels[i].name) == 0)
return i;
}
return LL_UNKNOWN;
}
/*
* Copyright 2018, CZ.NIC z.s.p.o. (http://www.nic.cz/)
*
* This file is part of the turris updater.
*
* Updater is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Updater is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Updater. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef UPDATER_LOGGING_H
#define UPDATER_LOGGING_H
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include "util.h"
enum log_level {
LL_DISABLE,
LL_DIE,
LL_ERROR,
LL_WARN,
LL_INFO,
LL_DBG,
LL_TRACE,
LL_UNKNOWN
};
void log_internal(enum log_level level, const char *file, size_t line, const char
*func, const char *format, ...) __attribute__((format(printf, 5, 6)));
// Picosat is compiled with TRACE defined. We really want to use that name for our
// log output so let's redefine it here. Picosat expect it being defined so result
// is the same.
#undef TRACE
#define LOG(level, ...) log_internal(level, __FILE__, __LINE__, __func__, __VA_ARGS__)
#define ERROR(...) LOG(LL_ERROR, __VA_ARGS__)
#define WARN(...) LOG(LL_WARN, __VA_ARGS__)
#define INFO(...) LOG(LL_INFO, __VA_ARGS__)
#define DBG(...) LOG(LL_DBG, __VA_ARGS__)
#define TRACE(...) LOG(LL_TRACE, __VA_ARGS__)
#define DIE(...) do { LOG(LL_DIE, __VA_ARGS__); cleanup_run_all(); abort(); } while (0)
#define ASSERT_MSG(COND, ...) do { if (!(COND)) DIE(__VA_ARGS__); } while (0)
#define ASSERT(COND) do { if (!(COND)) DIE("Failed assert: " #COND); } while (0)
// If prepare of log would be long, check if it would be printed first.
bool would_log(enum log_level level);
enum log_level log_level_get(const char *str) __attribute__((nonnull));
// FILE log buffer. Initialize it and then you can build message using FILE. To print it use char_buffer.
struct log_buffer {
FILE *f; // Use this as output and before printing it close this with fclose(f).
char *char_buffer; // This contains resulting text. Don't forget to free this buffer.
size_t buffer_len;
};
// Initialize log buffer (if would_log(level)
void log_buffer_init(struct log_buffer *buf, enum log_level level) __attribute__((nonnull));
// Sets if state and error should be dumped into files in /tmp/updater-state directory
void set_state_log(bool state_log);
// In the full updater mode, dump current state into /tmp/update-state/state
void state_dump(const char *msg) __attribute__((nonnull));
// In the full updater mode, dump the error into /tmp/update-state/error
void err_dump(const char *msg) __attribute__((nonnull));
void log_syslog_level(enum log_level level);
void log_syslog_name(const char *name);
void log_stderr_level(enum log_level level);
void setup_logging(enum log_level tty, enum log_level syslog);
#endif
......@@ -21,6 +21,7 @@
#include "picosat.h"
#include "inject.h"
#include "util.h"
#include "logging.h"
#include <lauxlib.h>
#include <lualib.h>
......
......@@ -20,132 +20,17 @@
#define _GNU_SOURCE
#include "util.h"
#include "logging.h"
#include <stdio.h>
#include <stdarg.h>
#include <string.h>
#include <errno.h>
#include <syslog.h>
#include <unistd.h>
#include <sys/types.h>
#include <dirent.h>
#include <signal.h>
#include <poll.h>
struct level_info {
const char *prefix;
const char *name;
int syslog_prio;
};
static const struct level_info levels[] = {
[LL_DISABLE] = { "!!!!", "DISABLE", LOG_CRIT }, // This shouldn't actually appear
[LL_DIE] = { "\x1b[31;1mDIE\x1b[0m", "DIE", LOG_CRIT },
[LL_ERROR] = { "\x1b[31mERROR\x1b[0m", "ERROR", LOG_ERR },
[LL_WARN] = { "\x1b[35mWARN\x1b[0m", "WARN", LOG_WARNING },
[LL_INFO] = { "\x1b[34mINFO\x1b[0m", "INFO", LOG_INFO },
[LL_DBG] = { "DEBUG", "DBG", LOG_DEBUG },
[LL_TRACE] = { "TRACE", "TRACE", LOG_DEBUG },
[LL_UNKNOWN] = { "????", "UNKNOWN", LOG_WARNING }
};
static enum log_level syslog_level = LL_DISABLE;
static enum log_level stderr_level = LL_WARN;
static bool syslog_opened = false;
bool state_log_enabled = false;
void set_state_log(bool state_log) {
state_log_enabled = state_log;
}
void state_dump(const char *msg) {
if (state_log_enabled) {
FILE *f = fopen("/tmp/update-state/state", "w");
if (f) {
fprintf(f, "%s\n", msg);
fclose(f);
} else {
WARN("Could not dump state: %s", strerror(errno));
}
}
}
void err_dump(const char *msg) {
if (state_log_enabled) {
FILE *f = fopen("/tmp/update-state/last_error", "w");
if (f) {
fprintf(f, "%s\n", msg);
fclose(f);
}
}
}
void log_internal(enum log_level level, const char *file, size_t line, const char *func, const char *format, ...) {
bool do_syslog = (level <= syslog_level);
bool do_stderr = (level <= stderr_level);
if (!do_syslog && !do_stderr)
return;
va_list args;
va_start(args, format);
size_t msg_size = vsnprintf(NULL, 0, format, args) + 1;
va_end(args);
char *msg = alloca(msg_size);
va_start(args, format);
vsprintf(msg, format, args);
va_end(args);
if (do_syslog) {
if (!syslog_opened)
log_syslog_name("updater");
syslog(LOG_MAKEPRI(LOG_DAEMON, levels[level].syslog_prio), "%s:%zu (%s): %s", file, line, func, msg);
}
if (do_stderr) {
if (stderr_level < LL_DBG)
fprintf(stderr, "%s:%s\n", levels[level].prefix, msg);
else
fprintf(stderr, "%s:%s:%zu (%s):%s\n", levels[level].prefix, file, line, func, msg);
}
if (level == LL_DIE) {
state_dump("error");
err_dump(msg);
}
}
bool would_log(enum log_level level) {
return (level <= syslog_level) || (level <= stderr_level);
}
void log_buffer_init(struct log_buffer *buff, enum log_level level) {
if (would_log(level)) {
buff->f = open_memstream(&buff->char_buffer, &buff->buffer_len);
if (buff->f)
return;
WARN("Message creation failed!");
}
buff->f = NULL;
}
void log_syslog_level(enum log_level level) {
syslog_level = level;
}
void log_stderr_level(enum log_level level) {
stderr_level = level;
}
void log_syslog_name(const char *name) {
ASSERT(!syslog_opened);
openlog(name, LOG_CONS | LOG_PID, LOG_DAEMON);
syslog_opened = true;
}
enum log_level log_level_get(const char *level) {
for (size_t i = 0; i < sizeof levels / sizeof *levels; i ++) {
if (strcasecmp(level, levels[i].name) == 0)
return i;
}
return LL_UNKNOWN;
}
bool dump2file (const char *file, const char *text) {
FILE *f = fopen(file, "w");
if (!f)
......
......@@ -26,60 +26,6 @@
#include <stdio.h>
#include <stdbool.h>
#include <alloca.h>
#include "util.h"
enum log_level {
LL_DISABLE,
LL_DIE,
LL_ERROR,
LL_WARN,
LL_INFO,
LL_DBG,
LL_TRACE,
LL_UNKNOWN
};
void log_internal(enum log_level level, const char *file, size_t line, const char *func, const char *format, ...) __attribute__((format(printf, 5, 6)));
// Picosat is compiled with TRACE defined. We really want to use that name for our
// log output so let's redefine it here. Picosat expect it being defined so result
// is the same.
#undef TRACE
#define LOG(level, ...) log_internal(level, __FILE__, __LINE__, __func__, __VA_ARGS__)
#define ERROR(...) LOG(LL_ERROR, __VA_ARGS__)
#define WARN(...) LOG(LL_WARN, __VA_ARGS__)
#define INFO(...) LOG(LL_INFO, __VA_ARGS__)
#define DBG(...) LOG(LL_DBG, __VA_ARGS__)
#define TRACE(...) LOG(LL_TRACE, __VA_ARGS__)
#define DIE(...) do { LOG(LL_DIE, __VA_ARGS__); cleanup_run_all(); abort(); } while (0)
#define ASSERT_MSG(COND, ...) do { if (!(COND)) DIE(__VA_ARGS__); } while (0)
#define ASSERT(COND) do { if (!(COND)) DIE("Failed assert: " #COND); } while (0)
// If prepare of log would be long, check if it would be printed first.
bool would_log(enum log_level level);
enum log_level log_level_get(const char *str) __attribute__((nonnull));
// FILE log buffer. Initialize it and then you can build message using FILE. To print it use char_buffer.
struct log_buffer {
FILE *f; // Use this as output and before printing it close this with fclose(f).
char *char_buffer; // This contains resulting text. Don't forget to free this buffer.
size_t buffer_len;
};
// Initialize log buffer (if would_log(level)
void log_buffer_init(struct log_buffer *buf, enum log_level level) __attribute__((nonnull));
// Sets if state and error should be dumped into files in /tmp/updater-state directory
void set_state_log(bool state_log);
// In the full updater mode, dump current state into /tmp/update-state/state
void state_dump(const char *msg) __attribute__((nonnull));
// In the full updater mode, dump the error into /tmp/update-state/error
void err_dump(const char *msg) __attribute__((nonnull));
void log_syslog_level(enum log_level level);
void log_syslog_name(const char *name);
void log_stderr_level(enum log_level level);
// Writes given text to file. Be aware that no information about failure is given.
bool dump2file (const char *file, const char *text) __attribute__((nonnull,nonnull));
......
......@@ -21,6 +21,7 @@
#include "../lib/events.h"
#include "../lib/interpreter.h"
#include "../lib/util.h"
#include "../lib/logging.h"
#include <stdlib.h>
#include <stdio.h>
......
......@@ -20,6 +20,7 @@
#include "../lib/events.h"
#include "../lib/interpreter.h"
#include "../lib/util.h"
#include "../lib/logging.h"
#include "../lib/arguments.h"
#include "../lib/journal.h"
......
......@@ -18,7 +18,7 @@
*/
#include "ctest.h"
#include "../src/lib/util.h"
#include "../src/lib/logging.h"
int main(void) {
const char *suppress_log = getenv("SUPPRESS_LOG");
......
......@@ -19,6 +19,7 @@
#include "../src/lib/interpreter.h"
#include "../src/lib/util.h"
#include "../src/lib/logging.h"
#include "../src/lib/events.h"
#include <string.h>
......
......@@ -18,7 +18,7 @@
*/
#include "../../src/lib/interpreter.h"
#include "../../src/lib/util.h"
#include "../../src/lib/logging.h"
#include "../../src/lib/embed_types.h"
#include "../../src/lib/events.h"
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment