23RCSID(
"$Id: 7cd26d1de5d5e9760b52794fab523aab72c053a6 $")
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/sbuff.h>
29#include <freeradius-devel/util/syserror.h>
30#include <freeradius-devel/util/atexit.h>
31#include <freeradius-devel/util/value.h>
32#include <freeradius-devel/util/time.h>
92 size_t offset, prefix, suffix;
107 if (offset >
inlen) {
108 *sp = talloc_strdup(ctx,
"");
109 *text = talloc_strdup(ctx,
"");
118 size_t skip = offset - 30;
131 if (
inlen > (offset + 30)) {
139 value = talloc_array(ctx,
char, prefix +
inlen + 1 + suffix);
141 memcpy(
value,
"... ", 4);
153 for (p =
value; *p !=
'\0'; p++) {
154 if (*p ==
'\t') *p =
' ';
160 spaces = talloc_array(ctx,
char, prefix + offset + 1);
161 memset(
spaces,
' ', prefix + offset);
162 spaces[prefix + offset] =
'\0';
194 fr_sbuff_marker(&m_start, &sbuff);
195 fr_sbuff_marker(&m_end, &sbuff);
205 if ((slen < 0) && (errno == EINTR))
continue;
224 log_info->
prefix ?
" - " :
"",
234 if (slen <= 0)
break;
269#define VTC_RED "\x1b[31m"
270#define VTC_YELLOW "\x1b[33m"
271#define VTC_BOLD "\x1b[1m"
272#define VTC_RESET "\x1b[0m"
324 pool = talloc_pool(NULL, 16384);
326 fr_perror(
"Failed allocating memory for vlog_request_pool");
348 TALLOC_CTX *pool, *thread_log_pool;
349 char const *fmt_colour =
"";
350 char const *fmt_location =
"";
352 char const *fmt_facility =
"";
353 char const *fmt_type =
"";
356 static char const *
spaces =
" ";
367 pool = talloc_new(thread_log_pool);
374 if (!fmt_colour) colourise =
false;
385 str = talloc_asprintf(pool,
"%s:%i",
file,
line);
386 len = talloc_array_length(str) - 1;
397 fmt_location = talloc_asprintf_append_buffer(str,
"%.*s : ", pad,
spaces);
460 end = p + talloc_array_length(fmt_msg) - 1;
465 for (p = fmt_msg; p < end; p++) {
494 int syslog_priority =
L_DBG;
503 syslog_priority= LOG_DEBUG;
507 syslog_priority = LOG_INFO;
511 syslog_priority = LOG_WARNING;
515 syslog_priority = LOG_ERR;
519 syslog_priority = LOG_AUTH | LOG_INFO;
522 syslog(syslog_priority,
527 fmt_time[0] ?
": " :
"",
539 buffer = talloc_asprintf(pool,
549 colourise ? fmt_colour :
"",
552 fmt_time[0] ?
": " :
"",
558 len = talloc_array_length(
buffer) - 1;
559 wrote = write(log->
fd,
buffer, len);
560 if (wrote < len)
return;
620 TALLOC_CTX *thread_log_pool;
631 if (!f_rules) f_rules = &default_f_rules;
638 fr_sbuff_init_talloc(thread_log_pool, &sbuff, &tctx, 1024, 16384);
652 if (!error && !
fmt)
return;
674 fr_sbuff_set_to_start(&sbuff);
677 fr_sbuff_marker(&prefix_m, &sbuff);
735 char const *str,
size_t str_len,
736 ssize_t marker_idx,
char const *marker,
char const *line_prefix_fmt, ...)
738 char const *ellipses =
"";
741 char *line_prefix = NULL;
742 static char const marker_spaces[] =
" ";
744 if (str_len == SIZE_MAX) str_len = strlen(str);
746 if (marker_idx < 0) marker_idx = marker_idx * -1;
748 if ((
size_t)marker_idx >=
sizeof(marker_spaces)) {
749 size_t offset = (marker_idx - (
sizeof(marker_spaces) - 1)) + (
sizeof(marker_spaces) * 0.75);
750 marker_idx -= offset;
752 if (offset > str_len) offset = str_len;
759 if (line_prefix_fmt) {
761 line_prefix =
fr_vasprintf(thread_log_pool, line_prefix_fmt, ap);
766 line_prefix ? line_prefix :
"", ellipses, (int)str_len, str);
768 line_prefix ? line_prefix :
"", ellipses, (int)marker_idx, marker_spaces, marker);
785 uint8_t const *
data,
size_t data_len,
char const *line_prefix_fmt, ...)
788 char buffer[(0x10 * 3) + 1];
791 char *line_prefix = NULL;
793 if (line_prefix_fmt) {
797 line_prefix =
fr_vasprintf(thread_log_pool, line_prefix_fmt, ap);
801 for (i = 0; i < data_len; i += 0x10) {
803 if ((i + len) > data_len) len = data_len - i;
805 for (p =
buffer, j = 0; j < len; j++, p += 3)
snprintf(p, end - p,
"%02x ",
data[i + j]);
807 if (line_prefix_fmt) {
809 line_prefix, (
unsigned int) i,
buffer);
833 ssize_t marker_idx,
char const *marker,
char const *line_prefix_fmt, ...)
836 char buffer[(0x10 * 3) + 1];
840 char *line_prefix = NULL;
841 static char spaces[3 * 0x10];
845 if (marker_idx < 0) marker_idx = marker_idx * -1;
846 if (line_prefix_fmt) {
850 line_prefix =
fr_vasprintf(thread_log_pool, line_prefix_fmt, ap);
854 for (i = 0; i < data_len; i += 0x10) {
856 if ((i + len) > data_len) len = data_len - i;
858 for (p =
buffer, j = 0; j < len; j++, p += 3)
snprintf(p, end - p,
"%02x ",
data[i + j]);
860 if (line_prefix_fmt) {
862 line_prefix, (
unsigned int) i,
buffer);
870 if (((
size_t)marker_idx >= i) && ((
size_t)marker_idx < (i + 0x10))) {
871 if (line_prefix_fmt) {
873 (
int)((marker_idx - i) * 3),
spaces, marker);
876 (
int)((marker_idx - i) * 3),
spaces, marker);
932 devnull_legacy = open(
"/dev/null", O_RDWR);
933 if (devnull_legacy < 0) {
947 log->
fd = STDOUT_FILENO;
958 dup2(STDOUT_FILENO, STDERR_FILENO);
960 dup2(devnull_legacy, STDERR_FILENO);
965 log->
fd = STDERR_FILENO;
976 dup2(STDERR_FILENO, STDOUT_FILENO);
978 dup2(devnull_legacy, STDOUT_FILENO);
987 dup2(devnull_legacy, STDOUT_FILENO);
988 dup2(devnull_legacy, STDERR_FILENO);
996 dup2(log->
fd, STDOUT_FILENO);
997 dup2(log->
fd, STDERR_FILENO);
1007 dup2(devnull_legacy, STDOUT_FILENO);
1008 dup2(devnull_legacy, STDERR_FILENO);
1011 close(devnull_legacy);
1030 memset(log, 0,
sizeof(*log));
1032 log->dst = dst_type;
1035 log->handle = stdout;
1039 log->handle = stderr;
1064 memset(log, 0,
sizeof(*log));
1106 static int syslog_priority_table[] = {
1107 [
L_DBG] = LOG_DEBUG,
1120 [
L_AUTH] = LOG_AUTH | LOG_INFO
1123 syslog(syslog_priority_table[
log_msg_type],
"%.*s", (
int)size, buf);
1137 memset(log, 0,
sizeof(*log));
1167 memset(log, 0,
sizeof(*log));
1330 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)
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