mirror of
https://github.com/justinian/jsix.git
synced 2025-12-10 00:14:32 -08:00
The logger had a lot of code that was due to it being in kutil instead of the kernel. Simplifying it a bit here in order to make the uart logger easier and eventual paring down of the logger easier. - Log areas are no longer hashes of their names, just an enum - Log level settings are no longer saved in 4 bits, just a byte - System signal updating is done in the logger now
132 lines
3.8 KiB
C++
132 lines
3.8 KiB
C++
#pragma once
|
|
/// \file logger.h
|
|
/// Kernel logging facility.
|
|
|
|
#include <stdarg.h>
|
|
#include <stdint.h>
|
|
|
|
#include <util/bip_buffer.h>
|
|
#include <util/spinlock.h>
|
|
|
|
enum class logs : uint8_t {
|
|
#define LOG(name, lvl) name,
|
|
#include <j6/tables/log_areas.inc>
|
|
#undef LOG
|
|
COUNT
|
|
};
|
|
|
|
namespace log {
|
|
|
|
enum class level : uint8_t {
|
|
none, debug, info, warn, error, fatal, max
|
|
};
|
|
|
|
constexpr unsigned areas_count =
|
|
static_cast<unsigned>(logs::COUNT);
|
|
|
|
class logger
|
|
{
|
|
public:
|
|
/// Callback type for immediate-mode logging
|
|
typedef void (*immediate_cb)(logs, level, const char *);
|
|
|
|
/// Default constructor. Creates a logger without a backing store.
|
|
/// \arg output Immediate-mode logging output function
|
|
logger(immediate_cb output = nullptr);
|
|
|
|
/// Constructor. Logs are written to the given buffer.
|
|
/// \arg buffer Buffer to which logs are written
|
|
/// \arg size Size of `buffer`, in bytes
|
|
/// \arg output Immediate-mode logging output function
|
|
logger(uint8_t *buffer, size_t size, immediate_cb output = nullptr);
|
|
|
|
/// Get the current immediate-mode callback
|
|
inline immediate_cb get_immediate() const { return m_immediate; }
|
|
|
|
/// Register an immediate-mode log callback
|
|
inline void set_immediate(immediate_cb cb) { m_immediate = cb; }
|
|
|
|
/// Get the default logger.
|
|
inline logger & get() { return *s_log; }
|
|
|
|
/// Get the registered name for a given area
|
|
inline const char * area_name(logs area) const { return s_area_names[static_cast<unsigned>(area)]; }
|
|
|
|
/// Get the name of a level
|
|
inline const char * level_name(level l) const { return s_level_names[static_cast<unsigned>(l)]; }
|
|
|
|
/// Write to the log
|
|
/// \arg severity The severity of the message
|
|
/// \arg area The log area to write to
|
|
/// \arg fmt A printf-like format string
|
|
inline void log(level severity, logs area, const char *fmt, ...)
|
|
{
|
|
level limit = get_level(area);
|
|
if (limit == level::none || severity < limit)
|
|
return;
|
|
|
|
va_list args;
|
|
va_start(args, fmt);
|
|
output(severity, area, fmt, args);
|
|
va_end(args);
|
|
}
|
|
|
|
struct entry
|
|
{
|
|
uint8_t bytes;
|
|
logs area;
|
|
level severity;
|
|
uint8_t sequence;
|
|
char message[0];
|
|
};
|
|
|
|
/// Get the next log entry from the buffer
|
|
/// \arg buffer The buffer to copy the log message into
|
|
/// \arg size Size of the passed-in buffer, in bytes
|
|
/// \returns The size of the log entry (if larger than the
|
|
/// buffer, then no data was copied)
|
|
size_t get_entry(void *buffer, size_t size);
|
|
|
|
/// Get whether there is currently data in the log buffer
|
|
inline bool has_log() const { return m_buffer.size(); }
|
|
|
|
private:
|
|
friend void debug(logs area, const char *fmt, ...);
|
|
friend void info (logs area, const char *fmt, ...);
|
|
friend void warn (logs area, const char *fmt, ...);
|
|
friend void error(logs area, const char *fmt, ...);
|
|
friend void fatal(logs area, const char *fmt, ...);
|
|
|
|
void output(level severity, logs area, const char *fmt, va_list args);
|
|
|
|
inline void set_level(logs area, level l) {
|
|
m_levels[static_cast<unsigned>(area)] = l;
|
|
}
|
|
|
|
inline level get_level(logs area) {
|
|
return m_levels[static_cast<unsigned>(area)];
|
|
}
|
|
|
|
level m_levels[areas_count];
|
|
immediate_cb m_immediate;
|
|
|
|
uint8_t m_sequence;
|
|
|
|
util::bip_buffer m_buffer;
|
|
util::spinlock m_lock;
|
|
|
|
static logger *s_log;
|
|
static const char *s_area_names[areas_count+1];
|
|
static const char *s_level_names[static_cast<unsigned>(level::max)];
|
|
};
|
|
|
|
void debug(logs area, const char *fmt, ...);
|
|
void info (logs area, const char *fmt, ...);
|
|
void warn (logs area, const char *fmt, ...);
|
|
void error(logs area, const char *fmt, ...);
|
|
void fatal(logs area, const char *fmt, ...);
|
|
|
|
extern log::logger &g_logger;
|
|
|
|
} // namespace log
|