23RCSID(
"$Id: af0ea632b71a0a52a03638ff97da49c442b78b3b $")
25#include <freeradius-devel/util/debug.h>
26#include <freeradius-devel/util/log.h>
27#include <freeradius-devel/util/print.h>
28#include <freeradius-devel/util/syserror.h>
29#include <freeradius-devel/util/value.h>
89 size_t offset, prefix, suffix;
104 if (offset >
inlen) {
105 *sp = talloc_strdup(ctx,
"");
106 *text = talloc_strdup(ctx,
"");
115 size_t skip = offset - 30;
128 if (
inlen > (offset + 30)) {
136 value = talloc_array(ctx,
char, prefix +
inlen + 1 + suffix);
138 memcpy(
value,
"... ", 4);
150 for (p =
value; *p !=
'\0'; p++) {
151 if (*p ==
'\t') *p =
' ';
157 spaces = talloc_array(ctx,
char, prefix + offset + 1);
158 memset(
spaces,
' ', prefix + offset);
159 spaces[prefix + offset] =
'\0';
191 fr_sbuff_marker(&m_start, &sbuff);
192 fr_sbuff_marker(&m_end, &sbuff);
202 if ((slen < 0) && (errno == EINTR))
continue;
221 log_info->
prefix ?
" - " :
"",
231 if (slen <= 0)
break;
266#define VTC_RED "\x1b[31m"
267#define VTC_YELLOW "\x1b[33m"
268#define VTC_BOLD "\x1b[1m"
269#define VTC_RESET "\x1b[0m"
321 pool = talloc_pool(NULL, 16384);
323 fr_perror(
"Failed allocating memory for vlog_request_pool");
345 TALLOC_CTX *pool, *thread_log_pool;
346 char const *fmt_colour =
"";
347 char const *fmt_location =
"";
349 char const *fmt_facility =
"";
350 char const *fmt_type =
"";
353 static char const *
spaces =
" ";
364 pool = talloc_new(thread_log_pool);
371 if (!fmt_colour) colourise =
false;
382 str = talloc_asprintf(pool,
"%s:%i",
file,
line);
383 len = talloc_array_length(str) - 1;
394 fmt_location = talloc_asprintf_append_buffer(str,
"%.*s : ", pad,
spaces);
457 end = p + talloc_array_length(fmt_msg) - 1;
462 for (p = fmt_msg; p < end; p++) {
491 int syslog_priority =
L_DBG;
500 syslog_priority= LOG_DEBUG;
504 syslog_priority = LOG_INFO;
508 syslog_priority = LOG_WARNING;
512 syslog_priority = LOG_ERR;
516 syslog_priority = LOG_AUTH | LOG_INFO;
519 syslog(syslog_priority,
524 fmt_time[0] ?
": " :
"",
536 buffer = talloc_asprintf(pool,
546 colourise ? fmt_colour :
"",
549 fmt_time[0] ?
": " :
"",
555 len = talloc_array_length(
buffer) - 1;
556 wrote = write(log->
fd,
buffer, len);
557 if (wrote < len)
return;
617 TALLOC_CTX *thread_log_pool;
628 if (!f_rules) f_rules = &default_f_rules;
635 fr_sbuff_init_talloc(thread_log_pool, &sbuff, &tctx, 1024, 16384);
649 if (!error && !
fmt)
return;
671 fr_sbuff_set_to_start(&sbuff);
674 fr_sbuff_marker(&prefix_m, &sbuff);
732 char const *str,
size_t str_len,
733 ssize_t marker_idx,
char const *marker,
char const *line_prefix_fmt, ...)
735 char const *ellipses =
"";
738 char *line_prefix = NULL;
739 static char const marker_spaces[] =
" ";
741 if (str_len == SIZE_MAX) str_len = strlen(str);
743 if (marker_idx < 0) marker_idx = marker_idx * -1;
745 if ((
size_t)marker_idx >=
sizeof(marker_spaces)) {
746 size_t offset = (marker_idx - (
sizeof(marker_spaces) - 1)) + (
sizeof(marker_spaces) * 0.75);
747 marker_idx -= offset;
749 if (offset > str_len) offset = str_len;
756 if (line_prefix_fmt) {
758 line_prefix =
fr_vasprintf(thread_log_pool, line_prefix_fmt, ap);
763 line_prefix ? line_prefix :
"", ellipses, (int)str_len, str);
765 line_prefix ? line_prefix :
"", ellipses, (int)marker_idx, marker_spaces, marker);
782 uint8_t const *
data,
size_t data_len,
char const *line_prefix_fmt, ...)
785 char buffer[(0x10 * 3) + 1];
788 char *line_prefix = NULL;
790 if (line_prefix_fmt) {
794 line_prefix =
fr_vasprintf(thread_log_pool, line_prefix_fmt, ap);
798 for (i = 0; i < data_len; i += 0x10) {
800 if ((i + len) > data_len) len = data_len - i;
802 for (p =
buffer, j = 0; j < len; j++, p += 3)
snprintf(p, end - p,
"%02x ",
data[i + j]);
804 if (line_prefix_fmt) {
806 line_prefix, (
unsigned int) i,
buffer);
830 ssize_t marker_idx,
char const *marker,
char const *line_prefix_fmt, ...)
833 char buffer[(0x10 * 3) + 1];
837 char *line_prefix = NULL;
838 static char spaces[3 * 0x10];
842 if (marker_idx < 0) marker_idx = marker_idx * -1;
843 if (line_prefix_fmt) {
847 line_prefix =
fr_vasprintf(thread_log_pool, line_prefix_fmt, ap);
851 for (i = 0; i < data_len; i += 0x10) {
853 if ((i + len) > data_len) len = data_len - i;
855 for (p =
buffer, j = 0; j < len; j++, p += 3)
snprintf(p, end - p,
"%02x ",
data[i + j]);
857 if (line_prefix_fmt) {
859 line_prefix, (
unsigned int) i,
buffer);
867 if (((
size_t)marker_idx >= i) && ((
size_t)marker_idx < (i + 0x10))) {
868 if (line_prefix_fmt) {
870 (
int)((marker_idx - i) * 3),
spaces, marker);
873 (
int)((marker_idx - i) * 3),
spaces, marker);
929 devnull_legacy = open(
"/dev/null", O_RDWR);
930 if (devnull_legacy < 0) {
944 log->
fd = STDOUT_FILENO;
955 dup2(STDOUT_FILENO, STDERR_FILENO);
957 dup2(devnull_legacy, STDERR_FILENO);
962 log->
fd = STDERR_FILENO;
973 dup2(STDERR_FILENO, STDOUT_FILENO);
975 dup2(devnull_legacy, STDOUT_FILENO);
984 dup2(devnull_legacy, STDOUT_FILENO);
985 dup2(devnull_legacy, STDERR_FILENO);
993 dup2(log->
fd, STDOUT_FILENO);
994 dup2(log->
fd, STDERR_FILENO);
1004 dup2(devnull_legacy, STDOUT_FILENO);
1005 dup2(devnull_legacy, STDERR_FILENO);
1008 close(devnull_legacy);
1027 memset(log, 0,
sizeof(*log));
1029 log->dst = dst_type;
1032 log->handle = stdout;
1036 log->handle = stderr;
1061 memset(log, 0,
sizeof(*log));
1103 static int syslog_priority_table[] = {
1104 [
L_DBG] = LOG_DEBUG,
1117 [
L_AUTH] = LOG_AUTH | LOG_INFO
1120 syslog(syslog_priority_table[
log_msg_type],
"%.*s", (
int)size, buf);
1134 memset(log, 0,
sizeof(*log));
1164 memset(log, 0,
sizeof(*log));
1327 devnull = fopen(
"/dev/null",
"w");
static int const char char buffer[256]
static int const char * fmt
bool fr_atexit_is_exiting(void)
Return whether we're currently in the teardown phase.
#define fr_atexit_thread_local(_name, _free, _uctx)
#define L(_str)
Helper for initialising arrays of string literals.
#define FALL_THROUGH
clang 10 doesn't recognised the FALL-THROUGH comment anymore
static fr_atomic_queue_t * aq
void fr_fault_set_log_fd(int fd)
Set a file descriptor to log memory reports to.
void fr_fault_set_cb(fr_fault_cb_t func)
Set a callback to be called before fr_fault()
#define fr_event_fd_insert(...)
@ FR_EVENT_FILTER_IO
Combined filter for read/write functions/.
FILE * fopencookie(void *cookie, const char *mode, cookie_io_functions_t io_funcs)
int(* cookie_close_function_t)(void *cookie)
ssize_t(* cookie_write_function_t)(void *cookie, const char *buf, size_t size)
static char const spaces[]
int fr_event_fd_delete(fr_event_list_t *el, int fd, fr_event_filter_t filter)
Remove a file descriptor from the event loop.
Stores all information relating to an event list.
fr_table_num_ordered_t const fr_log_levels[]
Maps log categories to message prefixes.
int fr_log_init_legacy(fr_log_t *log, bool daemonize)
Initialise file descriptors based on logging destination.
#define VTC_RED
Colour following text red.
static ssize_t _syslog_write(UNUSED void *cookie, const char *buf, size_t size)
Write complete lines to syslog.
TALLOC_CTX * fr_log_pool_init(void)
talloc ctx to use when composing log messages
int fr_log_init_syslog(fr_log_t *log)
Initialise a syslog logging destination.
int fr_log_global_init(fr_event_list_t *el, bool daemonize)
Manipulate stderr and stdout so that was capture all data send to it from libraries.
void fr_log_hex(fr_log_t const *log, fr_log_type_t type, char const *file, int line, uint8_t const *data, size_t data_len, char const *line_prefix_fmt,...)
Print out hex block.
static FILE * devnull
File handle for /dev/null.
void fr_log_hex_marker(fr_log_t const *log, fr_log_type_t type, char const *file, int line, uint8_t const *data, size_t data_len, ssize_t marker_idx, char const *marker, char const *line_prefix_fmt,...)
Print out hex block.
#define VTC_YELLOW
Colour following text yellow.
void fr_log_global_free(void)
Restores the original stdout and stderr FDs, closes the pipes and removes them from the event loop.
static int _restore_std_legacy(UNUSED int sig)
On fault, reset STDOUT and STDERR to something useful.
static int stdout_fd
The original unmolested stdout file descriptor.
int fr_log_init_std(fr_log_t *log, fr_log_dst_t dst_type)
Initialise log dst for stdout, stderr or /dev/null.
int fr_log_init_func(fr_log_t *log, cookie_write_function_t write, cookie_close_function_t close, void *uctx)
Initialise a function based logging destination.
#define VTC_RESET
Reset terminal text to default style/colour.
static fr_log_fd_event_ctx_t stderr_ctx
Logging ctx for stderr.
static uint32_t location_indent
static fr_table_num_ordered_t const colours[]
Maps log categories to VT100 style/colour escape sequences.
void fr_log_marker(fr_log_t const *log, fr_log_type_t type, char const *file, int line, char const *str, size_t str_len, ssize_t marker_idx, char const *marker, char const *line_prefix_fmt,...)
Print out an error marker.
void fr_log_fd_event(UNUSED fr_event_list_t *el, int fd, UNUSED int flags, void *uctx)
Function to provide as the readable callback to the event loop.
static fr_event_list_t * log_el
Event loop we use for process logging data.
int fr_log_init_file(fr_log_t *log, char const *file)
Initialise a file logging destination.
static _Thread_local fr_log_type_t log_msg_type
The type of the last message logged.
static int stdout_pipe[2]
Pipe we use to transport stdout data.
static int stderr_pipe[2]
Pipe we use to transport stderr data.
bool fr_log_rate_limit
Whether repeated log entries should be rate limited.
void fr_log_perror(fr_log_t const *log, fr_log_type_t type, char const *file, int line, fr_log_perror_format_t const *rules, char const *fmt,...)
Drain any outstanding messages from the fr_strerror buffers.
int fr_log_init_fp(fr_log_t *log, FILE *fp)
Initialise a file logging destination to a FILE*.
void fr_vlog_perror(fr_log_t const *log, fr_log_type_t type, char const *file, int line, fr_log_perror_format_t const *f_rules, char const *fmt, va_list ap)
Drain any outstanding messages from the fr_strerror buffers.
void fr_vlog(fr_log_t const *log, fr_log_type_t type, char const *file, int line, char const *fmt, va_list ap)
Send a server log message to its destination.
static _Thread_local TALLOC_CTX * fr_log_pool
static fr_log_fd_event_ctx_t stdout_ctx
Logging ctx for stdout.
static int _fr_log_pool_free(void *arg)
Cleanup the memory pool used by vlog_request.
void fr_canonicalize_error(TALLOC_CTX *ctx, char **sp, char **text, ssize_t slen, char const *fmt)
Canonicalize error strings, removing tabs, and generate spaces for error marker.
void fr_log(fr_log_t const *log, fr_log_type_t type, char const *file, int line, char const *fmt,...)
Send a server log message to its destination.
static int stderr_fd
The original unmolested stderr file descriptor.
static size_t colours_len
int fr_log_close(fr_log_t *log)
Universal close function for all logging destinations.
#define VTC_BOLD
Embolden following text.
@ L_DST_NULL
Discard log messages.
@ L_DST_STDERR
Log to stderr.
@ L_DST_FILES
Log to a file on disk.
@ L_DST_FUNC
Send log messages to a FILE*, via fopencookie()
@ L_DST_STDOUT
Log to stdout.
@ L_DST_SYSLOG
Log to syslog.
@ L_TIMESTAMP_ON
Always log timestamps.
@ L_TIMESTAMP_OFF
Never log timestamps.
@ L_TIMESTAMP_AUTO
Timestamp logging preference not specified.
@ L_DBG_LVL_2
2nd highest priority debug messages (-xx | -X).
@ L_DBG_LVL_OFF
No debug messages.
char const * prefix
To add to log messages.
char const * first_prefix
Prefix for the first line printed.
char const * subsq_prefix
Prefix for subsequent lines.
fr_log_lvl_t lvl
Priority of the message.
fr_log_type_t type
What type of log message it is.
fr_log_t const * dst
Where to log to.
@ L_DBG_INFO
Info only displayed when debugging is enabled.
@ L_DBG_WARN_REQ
Less severe warning only displayed when debugging is enabled.
@ L_DBG_ERR
Error only displayed when debugging is enabled.
@ L_DBG_ERR_REQ
Less severe error only displayed when debugging is enabled.
@ L_DBG_WARN
Warning only displayed when debugging is enabled.
@ L_AUTH
Authentication logs.
@ L_INFO
Informational message.
@ L_DBG
Only displayed when debugging is enabled.
Context structure for the log fd event function.
size_t fr_utf8_char(uint8_t const *str, ssize_t inlen)
Checks for utf-8, taken from http://www.w3.org/International/questions/qa-forms-utf-8.
char * fr_vasprintf(TALLOC_CTX *ctx, char const *fmt, va_list ap)
ssize_t fr_sbuff_in_strcpy(fr_sbuff_t *sbuff, char const *str)
Copy bytes into the sbuff up to the first \0.
size_t fr_sbuff_shift(fr_sbuff_t *sbuff, size_t shift, bool move_end)
Shift the contents of the sbuff, returning the number of bytes we managed to shift.
bool fr_sbuff_is_terminal(fr_sbuff_t *in, fr_sbuff_term_t const *tt)
Efficient terminal string search.
size_t fr_sbuff_adv_until(fr_sbuff_t *sbuff, size_t len, fr_sbuff_term_t const *tt, char escape_chr)
Wind position until we hit a character in the terminal set.
ssize_t fr_sbuff_in_vsprintf(fr_sbuff_t *sbuff, char const *fmt, va_list ap)
Print using a fmt string to an sbuff.
#define fr_sbuff_start(_sbuff_or_marker)
#define fr_sbuff_set(_dst, _src)
#define fr_sbuff_current(_sbuff_or_marker)
#define FR_SBUFF_TERMS(...)
Initialise a terminal structure with a list of sorted strings.
#define fr_sbuff_init_out(_out, _start, _len_or_end)
#define fr_sbuff_advance(_sbuff_or_marker, _len)
#define fr_sbuff_remaining(_sbuff_or_marker)
#define FR_SBUFF_OUT(_start, _len_or_end)
#define fr_sbuff_used(_sbuff_or_marker)
#define fr_sbuff_behind(_sbuff_or_marker)
#define fr_sbuff_ahead(_sbuff_or_marker)
Set of terminal elements.
Talloc sbuff extension structure.
PUBLIC int snprintf(char *string, size_t length, char *format, va_alist)
fr_aka_sim_id_type_t type
#define fr_time()
Allow us to arbitrarily manipulate time.
bool dates_utc
Whether timestamps should be UTC or local timezone.
void * uctx
User data associated with the fr_log_t.
bool colourise
Prefix log messages with VT100 escape codes to change text colour.
fr_log_dst_t dst
Log destination.
bool line_number
Log src file and line number.
int fd
File descriptor to write messages to.
fr_log_timestamp_t timestamp
Prefix log messages with timestamps.
char const * file
Path to log file.
bool print_level
sometimes we don't want log levels printed
FILE * handle
Path to log file.
char const * fr_syserror(int num)
Guaranteed to be thread-safe version of strerror.
#define fr_table_str_by_value(_table, _number, _def)
Convert an integer to a string.
An element in an arbitrarily ordered array of name to num mappings.
fr_slen_t fr_unix_time_to_str(fr_sbuff_t *out, fr_unix_time_t time, fr_time_res_t res, bool utc)
Convert unix time to string.
static fr_unix_time_t fr_time_to_unix_time(fr_time_t when)
Convert an fr_time_t (internal time) to our version of unix time (wallclock time)
static fr_event_list_t * el
void fr_perror(char const *fmt,...)
Print the current error to stderr with a prefix.
char const * fr_strerror_pop(void)
Pop the last library error.
#define fr_strerror_printf(_fmt,...)
Log to thread local error buffer.
#define fr_strerror_const_push(_msg)
#define fr_strerror_const(_msg)
#define fr_box_strvalue_len(_val, _len)
static size_t char fr_sbuff_t size_t inlen