ascii-chat
Binary v0.15.83-53-gb711d8720
Library lib/v0.3.2-701-gb711d8720
Video chat in your terminal
Loading...
Searching...
No Matches
log/log.h
Go to the documentation of this file.
1
23
24#pragma once
25
27
28#include <stdarg.h>
29#include <libplatform/atomic.h>
30// Use atomic.h API for all platforms (C and C++)
31// atomic_t is available in both C and C++ contexts
32#define LOG_ATOMIC_UINT64 atomic_t
33#ifdef NDEBUG
34#define LOG_ATOMIC_UINT64_INIT(val) {.impl = (uint64_t)0}
35#else
36// In debug mode, atomic_t has debug fields that need initialization
37#define LOG_ATOMIC_UINT64_INIT(val) \
38 {.impl = (uint64_t)0, \
39 .change_count = (uint64_t)0, \
40 .last_store_time_ns = (uint64_t)0, \
41 .last_load_time_ns = (uint64_t)0, \
42 .store_count = (uint64_t)0, \
43 .load_count = (uint64_t)0, \
44 .cas_count = (uint64_t)0, \
45 .cas_success_count = (uint64_t)0, \
46 .fetch_count = (uint64_t)0}
47#endif
48#include <stdbool.h>
49#include <stdint.h>
50#include <time.h>
51#include <libplatform/socket.h>
52#include <libplatform/system.h>
53
54/* Forward declarations */
55struct crypto_context_t;
56struct color_scheme_t; /* Opaque - full definition in ui/colors.h, only included in logging.c */
58struct session_log_buffer; /* Opaque - full definition in session/session_log_buffer.h */
60
61
62/* Include log types (must be before network/log.h to avoid circular dependency) */
63#include "types.h"
64
65#include "../network/log.h"
66
67#ifndef NDEBUG
69#define DEFAULT_LOG_LEVEL LOG_DEBUG
70#else
72#define DEFAULT_LOG_LEVEL LOG_INFO
73#endif
74
76#define MAX_LOG_SIZE (3 * 1024 * 1024)
77
79#define MAX_TERMINAL_BUFFER_SIZE (64 * 1024)
80
82#define MAX_TERMINAL_BUFFER_ENTRIES 256
83
84/* ============================================================================
85 * Logging Buffer Size Constants
86 * ============================================================================
87 * Named constants for internal buffer sizes. Messages exceeding these sizes
88 * will be truncated with no error indication.
89 */
90
92#define LOG_MSG_BUFFER_SIZE 4096
93
95#define LOG_MMAP_MSG_BUFFER_SIZE 1024
96
98#define LOG_HEADER_BUFFER_SIZE 512
99
101#define LOG_TIMESTAMP_BUFFER_SIZE 32
102
104#define LOG_TERMINAL_BUFFER_SIZE 16384
105
107#define LOG_TERMINAL_ENTRY_BUFFER_SIZE (LOG_HEADER_BUFFER_SIZE + LOG_TERMINAL_BUFFER_SIZE)
108
109/* ============================================================================
110 * Compile-Time Log Level Stripping
111 * ============================================================================
112 * By default, all log levels are compiled in (LOG_DEV) so that runtime
113 * verbosity flags like -vvv work in both debug and release builds.
114 *
115 * Define LOG_COMPILE_LEVEL to strip logs at compile-time for smaller binaries:
116 * -DLOG_COMPILE_LEVEL=LOG_INFO -> Strip DEV and DEBUG
117 * -DLOG_COMPILE_LEVEL=LOG_WARN -> Strip DEV, DEBUG, and INFO
118 * -DLOG_COMPILE_LEVEL=LOG_DEV -> Keep all log levels (default)
119 */
120#ifndef LOG_COMPILE_LEVEL
122#define LOG_COMPILE_LEVEL LOG_DEV
123#endif
124
133typedef struct {
134 bool use_stderr; /* true for stderr, false for stdout */
135 char *message; /* Formatted message (heap allocated) */
137
138/* Implementation details (g_log struct, color arrays) are in logging.c */
139
158
159#ifdef __cplusplus
160extern "C" {
161#endif
162
177void log_init(const char *filename, log_level_t level, bool force_stderr, bool use_mmap);
178
183void log_destroy(void);
184
193void log_system_init(void);
194
203void log_system_destroy(void);
204
210void log_set_level(log_level_t level);
211
218
227asciichat_error_t log_set_format(const char *format_str, bool console_only);
228
235
241bool log_get_terminal_output(void);
242
255
261bool log_get_force_stderr(void);
262
270void log_disable_file_output(void);
271
278void log_truncate_if_large(void);
279
290void log_msg(log_level_t level, const char *file, int line, const char *func, const char *fmt, ...);
291
305void log_terminal_msg(log_level_t level, const char *file, int line, const char *func, const char *fmt, ...);
306
318void log_colored_msg_impl(log_level_t level, const char *file, int line, const char *func, const char *colored_message,
319 const char *plain_message);
320#define log_colored_msg(level, colored_message, plain_message) \
321 log_colored_msg_impl((level), __FILE__, __LINE__, __func__, (colored_message), (plain_message))
322
332void log_terminal_colored_msg_impl(log_level_t level, const char *file, int line, const char *func,
333 const char *colored_message, const char *plain_message);
334#define log_terminal_colored_msg(level, colored_message, plain_message) \
335 log_terminal_colored_msg_impl((level), __FILE__, __LINE__, __func__, (colored_message), (plain_message))
336
345void log_plain_msg(const char *fmt, ...);
346
355void log_plain_stderr_msg(const char *fmt, ...);
356
366void log_plain_stdout_msg(const char *fmt, ...);
367
377void log_plain_stderr_nonewline_msg(const char *fmt, ...);
378
387void log_file_msg(const char *fmt, ...);
388
401void log_labeled(const char *label, log_color_t color, const char *message, ...);
402
409const char *log_level_color(log_color_t color);
410
415const char *log_level_color_for_output(log_color_t color, bool enabled);
416
424const char **log_get_color_array(void);
425
427const char *log_get_foreground_color(void);
428
430int log_get_color_mode(void);
431
439
448void log_init_colors(void);
449
459void log_set_color_scheme(const color_scheme_t *scheme);
460
478bool log_lock_terminal(void);
479
489void log_unlock_terminal(bool previous_state);
490
501void log_set_flush_delay(unsigned int delay_ms);
502
510char *format_message(const char *format, va_list args);
511
518size_t get_current_time_formatted(char *time_buf);
519
520struct acip_transport;
521
535 const char *file, int line, const char *func, const char *fmt, ...);
536
544
552#ifdef NDEBUG
553#define log_as(level, ...) log_msg(level, NULL, 0, NULL, __VA_ARGS__)
554#else
555#define log_as(level, ...) log_msg(level, __FILE__, __LINE__, __func__, __VA_ARGS__)
556#endif
557
566#define log_only(bitmask, level, ...) \
567 ({ \
568 if ((bitmask) & LOG_BIT(level)) \
569 log_as(level, __VA_ARGS__); \
570 })
571
580#if LOG_COMPILE_LEVEL <= LOG_DEV
581#define log_dev(...) log_only(LOG_BIT(LOG_DEV), LOG_DEV, __VA_ARGS__)
582#else
583#define log_dev(...) ((void)0)
584#endif
585
594#if LOG_COMPILE_LEVEL <= LOG_DEBUG
595#define log_debug(...) log_only(LOG_BIT(LOG_DEBUG), LOG_DEBUG, __VA_ARGS__)
596#else
597#define log_debug(...) ((void)0)
598#endif
599
607#if LOG_COMPILE_LEVEL <= LOG_INFO
608#define log_info(...) log_only(LOG_BIT(LOG_INFO), LOG_INFO, __VA_ARGS__)
609#else
610#define log_info(...) ((void)0)
611#endif
612
620#if LOG_COMPILE_LEVEL <= LOG_WARN
621#define log_warn(...) log_only(LOG_BIT(LOG_WARN), LOG_WARN, __VA_ARGS__)
622#else
623#define log_warn(...) ((void)0)
624#endif
625
633#if LOG_COMPILE_LEVEL <= LOG_ERROR
634#define log_error(...) log_only(LOG_BIT(LOG_ERROR), LOG_ERROR, __VA_ARGS__)
635#else
636#define log_error(...) ((void)0)
637#endif
638
646#define log_fatal(...) log_only(LOG_BIT(LOG_FATAL), LOG_FATAL, __VA_ARGS__)
647
649
657
659
665#define log_plain(...) log_plain_msg(__VA_ARGS__)
666
672#define log_plain_stderr(...) log_plain_stderr_msg(__VA_ARGS__)
673
679#define log_plain_stdout(...) log_plain_stdout_msg(__VA_ARGS__)
680
686#define log_plain_stderr_nonewline(...) log_plain_stderr_nonewline_msg(__VA_ARGS__)
687
693#define log_file(...) log_file_msg(__VA_ARGS__)
694
696
714#ifdef NDEBUG
715#define log_every(log_level, interval_us, fmt, ...) \
716 do { \
717 static LOG_ATOMIC_UINT64 _log_every_last_time = LOG_ATOMIC_UINT64_INIT(0); \
718 uint64_t _log_every_now = platform_get_monotonic_time_us(); \
719 uint64_t _log_every_last = atomic_load_u64(&_log_every_last_time); \
720 if (_log_every_now - _log_every_last >= (uint64_t)(interval_us)) { \
721 if (atomic_cas_u64(&_log_every_last_time, &_log_every_last, _log_every_now)) { \
722 log_msg(LOG_##log_level, NULL, 0, NULL, fmt, ##__VA_ARGS__); \
723 } \
724 } \
725 } while (0)
726#else
727#define log_every(log_level, interval_us, fmt, ...) \
728 do { \
729 static LOG_ATOMIC_UINT64 _log_every_last_time = LOG_ATOMIC_UINT64_INIT(0); \
730 uint64_t _log_every_now = platform_get_monotonic_time_us(); \
731 uint64_t _log_every_last = atomic_load_u64(&_log_every_last_time); \
732 if (_log_every_now - _log_every_last >= (uint64_t)(interval_us)) { \
733 if (atomic_cas_u64(&_log_every_last_time, &_log_every_last, _log_every_now)) { \
734 log_msg(LOG_##log_level, __FILE__, __LINE__, __func__, fmt, ##__VA_ARGS__); \
735 } \
736 } \
737 } while (0)
738#endif
739
744
746#define log_dev_every(interval_us, fmt, ...) log_every(DEV, interval_us, fmt, ##__VA_ARGS__)
747
749#define log_debug_every(interval_us, fmt, ...) log_every(DEBUG, interval_us, fmt, ##__VA_ARGS__)
750
752#define log_info_every(interval_us, fmt, ...) log_every(INFO, interval_us, fmt, ##__VA_ARGS__)
753
755#define log_warn_every(interval_us, fmt, ...) log_every(WARN, interval_us, fmt, ##__VA_ARGS__)
756
758#define log_error_every(interval_us, fmt, ...) log_every(ERROR, interval_us, fmt, ##__VA_ARGS__)
759
761#define log_fatal_every(interval_us, fmt, ...) log_every(FATAL, interval_us, fmt, ##__VA_ARGS__)
762
764
783#ifdef NDEBUG
784#define log_nth(log_level, n, fmt, ...) \
785 do { \
786 static LOG_ATOMIC_UINT64 _log_nth_counter = LOG_ATOMIC_UINT64_INIT(0); \
787 uint64_t _log_nth_count = atomic_load_u64(&_log_nth_counter); \
788 uint64_t _log_nth_new = _log_nth_count + 1; \
789 atomic_store_u64(&_log_nth_counter, _log_nth_new); \
790 if (_log_nth_new % (uint64_t)(n) == 0) { \
791 log_msg(LOG_##log_level, NULL, 0, NULL, fmt, ##__VA_ARGS__); \
792 } \
793 } while (0)
794#else
795#define log_nth(log_level, n, fmt, ...) \
796 do { \
797 static LOG_ATOMIC_UINT64 _log_nth_counter = LOG_ATOMIC_UINT64_INIT(0); \
798 uint64_t _log_nth_count = atomic_load_u64(&_log_nth_counter); \
799 uint64_t _log_nth_new = _log_nth_count + 1; \
800 atomic_store_u64(&_log_nth_counter, _log_nth_new); \
801 if (_log_nth_new % (uint64_t)(n) == 0) { \
802 log_msg(LOG_##log_level, __FILE__, __LINE__, __func__, fmt, ##__VA_ARGS__); \
803 } \
804 } while (0)
805#endif
806
824#ifdef NDEBUG
825#define log_once(log_level, fmt, ...) \
826 do { \
827 static LOG_ATOMIC_UINT64 _log_once_counter = LOG_ATOMIC_UINT64_INIT(0); \
828 uint64_t _log_once_count = atomic_load_u64(&_log_once_counter); \
829 if (_log_once_count == 0) { \
830 atomic_store_u64(&_log_once_counter, 1); \
831 log_msg(LOG_##log_level, NULL, 0, NULL, fmt, ##__VA_ARGS__); \
832 } \
833 } while (0)
834#else
835#define log_once(log_level, fmt, ...) \
836 do { \
837 static LOG_ATOMIC_UINT64 _log_once_counter = LOG_ATOMIC_UINT64_INIT(0); \
838 uint64_t _log_once_count = atomic_load_u64(&_log_once_counter); \
839 if (_log_once_count == 0) { \
840 atomic_store_u64(&_log_once_counter, 1); \
841 log_msg(LOG_##log_level, __FILE__, __LINE__, __func__, fmt, ##__VA_ARGS__); \
842 } \
843 } while (0)
844#endif
845
850
852#define log_dev_nth(n, fmt, ...) log_nth(DEV, n, fmt, ##__VA_ARGS__)
853
855#define log_debug_nth(n, fmt, ...) log_nth(DEBUG, n, fmt, ##__VA_ARGS__)
856
858#define log_info_nth(n, fmt, ...) log_nth(INFO, n, fmt, ##__VA_ARGS__)
859
861#define log_warn_nth(n, fmt, ...) log_nth(WARN, n, fmt, ##__VA_ARGS__)
862
864#define log_error_nth(n, fmt, ...) log_nth(ERROR, n, fmt, ##__VA_ARGS__)
865
867#define log_fatal_nth(n, fmt, ...) log_nth(FATAL, n, fmt, ##__VA_ARGS__)
868
870
875
877#define log_dev_once(fmt, ...) log_once(DEV, fmt, ##__VA_ARGS__)
878
880#define log_debug_once(fmt, ...) log_once(DEBUG, fmt, ##__VA_ARGS__)
881
883#define log_info_once(fmt, ...) log_once(INFO, fmt, ##__VA_ARGS__)
884
886#define log_warn_once(fmt, ...) log_once(WARN, fmt, ##__VA_ARGS__)
887
889#define log_error_once(fmt, ...) log_once(ERROR, fmt, ##__VA_ARGS__)
890
892#define log_fatal_once(fmt, ...) log_once(FATAL, fmt, ##__VA_ARGS__)
893
895
896/* LOGGING_INTERNAL_ERROR macro is defined in logging.c (internal use only) */
897
898/* Network logging convenience macros (log_*_net) are defined in src/server/client.h
899 * since they require access to client_info_t. The base function log_net_message()
900 * is available here for generic use. */
901
902/* ============================================================================
903 * Lock-Free MMAP Logging
904 * ============================================================================ */
905
906/* Forward declaration - full definition in log/mmap.h */
907struct log_mmap_config;
909
930
940
947void log_disable_mmap(void);
948
960void log_shutdown_begin(void);
961
968void log_shutdown_end(void);
969
977void log_cleanup_colors(void);
978
989
999
1010
1033size_t log_recolor_plain_entry(const char *plain_line, char *colored_buf, size_t buf_size);
1034
1035/* ============================================================================
1036 * Internal Utilities (used by log formatting modules)
1037 * ============================================================================ */
1038
1045const char *get_level_string_padded(log_level_t level);
1046
1047// Console-only logging helper (text or JSON, no file output)
1048// For signal handlers and initialization paths where file logging is not safe
1049// Automatically chooses between text and JSON based on --json flag
1050// Captures call site (file, line, function) for better debugging
1051void log_console_impl(log_level_t level, const char *file, int line, const char *func, const char *message);
1052#define log_console(level, message) log_console_impl((level), __FILE__, __LINE__, __func__, (message))
1053
1068void *log_get_template(void);
1069
1070/* Include crypto.h at the end to avoid circular dependency with time.h */
1071#include "../crypto/crypto.h"
1072
1073#ifdef __cplusplus
1074}
1075#endif
1076 /* logging */
action_args_t args
Definition actions.c:78
Synchronized per-thread pending error stacks and value snapshots. SET_ERRNO pushes,...
bool enabled
Is filtering active?
Definition grep.c:62
asciichat_error_t
Error and exit codes - unified status values (0-255).
Definition error_codes.h:44
void log_truncate_if_large(void)
Manually truncate large log files.
Definition log.c:853
void log_plain_stderr_nonewline_msg(const char *fmt,...)
Plain logging to stderr without trailing newline.
Definition log.c:1672
void log_plain_msg(const char *fmt,...)
Plain logging without timestamps or levels.
Definition log.c:1509
bool log_get_terminal_output(void)
Get current terminal output setting.
Definition log.c:763
asciichat_error_t log_enable_mmap(const char *log_path)
Enable lock-free mmap-based logging.
Definition log.c:1977
void log_init_colors(void)
Initialize logging color system with current terminal capabilities.
Definition log.c:1963
void log_system_init(void)
Initialize the logging system internal state (system-level init).
Definition log.c:712
void log_msg(log_level_t level, const char *file, int line, const char *func, const char *fmt,...)
Log a message at a specific level.
Definition log.c:1196
void log_shutdown_end(void)
End shutdown phase - restore previous logging settings.
Definition log.c:2018
asciichat_error_t log_net_message(struct acip_transport *transport, log_level_t level, remote_log_direction_t direction, const char *file, int line, const char *func, const char *fmt,...)
Log a message to all destinations (network, file, and terminal).
Definition log.c:1810
void log_destroy(void)
Destroy the logging system and close log file.
Definition log.c:667
void log_colored_msg_impl(log_level_t level, const char *file, int line, const char *func, const char *colored_message, const char *plain_message)
Write semantically colored terminal text and an ANSI-free log equivalent.
Definition log.c:1499
void log_set_force_stderr(bool enabled)
Force all terminal log output to stderr.
Definition log.c:767
enum remote_log_direction remote_log_direction_t
Remote log packet direction enumeration.
log_level_t log_get_level(void)
Get the current minimum log level.
Definition log.c:742
const char ** log_get_color_array(void)
Get the appropriate color array based on terminal capabilities.
Definition log.c:1911
const char * log_level_color_for_output(log_color_t color, bool enabled)
Definition log.c:1942
const char * log_level_color(log_color_t color)
Get color string for a given color enum.
Definition log.c:1929
struct session_log_buffer session_log_buffer_t
Thread-safe fixed-size history ring for session-screen log lines.
void log_set_flush_delay(unsigned int delay_ms)
Set the delay between flushing buffered log entries.
Definition log.c:849
const char * log_get_foreground_color(void)
Definition log.c:1924
session_log_buffer_t * log_get_session_log_buffer(void)
Get the currently registered session log buffer.
Definition log.c:2071
char * format_message(const char *format, va_list args)
Format a message using va_list.
Definition log.c:278
log_color_t
Color enum for logging - indexes into color arrays.
Definition log/log.h:147
void log_cleanup_colors(void)
Clean up compiled color scheme.
Definition log.c:2034
void log_shutdown_begin(void)
Begin shutdown phase - disable console logging but keep file logging.
Definition log.c:2007
void log_disable_file_output(void)
Disable file output and use stderr instead.
Definition log.c:779
bool log_get_force_stderr(void)
Get current force_stderr setting.
Definition log.c:771
void log_set_level(log_level_t level)
Set the minimum log level.
Definition log.c:737
size_t log_recolor_plain_entry(const char *plain_line, char *colored_buf, size_t buf_size)
Recolor a plain (non-colored) log line with proper ANSI codes.
Definition log.c:2085
void log_clear_session_log_buffer(void)
Unregister the session log buffer.
Definition log.c:2057
void log_plain_stdout_msg(const char *fmt,...)
Plain logging to stdout with newline.
Definition log.c:1751
void log_set_session_log_buffer(session_log_buffer_t *buf)
Register a session log buffer with the logger.
Definition log.c:2048
void log_system_destroy(void)
Shutdown the logging system internal state (system-level cleanup).
Definition log.c:729
void log_init(const char *filename, log_level_t level, bool force_stderr, bool use_mmap)
Initialize the logging system.
Definition log.c:569
bool log_lock_terminal(void)
Lock terminal output for exclusive access by the calling thread.
Definition log.c:833
log_level_t
Logging levels enumeration.
Definition types.h:29
void log_labeled(const char *label, log_color_t color, const char *message,...)
Print a labeled message with color.
asciichat_error_t log_set_format(const char *format_str, bool console_only)
Set a custom log format string.
Definition log.c:790
size_t get_current_time_formatted(char *time_buf)
Get current time as formatted string.
Definition log.c:246
asciichat_error_t log_enable_mmap_sized(const char *log_path, size_t max_size)
Enable lock-free mmap logging with custom file size.
Definition log.c:1981
void log_file_msg(const char *fmt,...)
Log to file only, no stderr output.
Definition log.c:1765
void log_disable_mmap(void)
Disable mmap logging and return to mutex-based logging.
Definition log.c:1996
void log_set_terminal_output(bool enabled)
Control stderr output to terminal.
Definition log.c:746
void * log_get_template(void)
Get the current log format template (opaque pointer).
Definition log.c:2375
int log_get_color_mode(void)
Definition log.c:1919
void log_set_color_scheme(const color_scheme_t *scheme)
Set the color scheme for logging output.
Definition log.c:1969
void log_plain_stderr_msg(const char *fmt,...)
Plain logging to stderr with newline.
Definition log.c:1658
void log_redetect_terminal_capabilities(void)
Re-detect terminal capabilities after logging is initialized.
Definition log.c:1880
void log_unlock_terminal(bool previous_state)
Release terminal lock and flush buffered messages.
Definition log.c:842
void log_terminal_colored_msg_impl(log_level_t level, const char *file, int line, const char *func, const char *colored_message, const char *plain_message)
Write semantically colored terminal text without persistent logging.
Definition log.c:1504
void log_terminal_msg(log_level_t level, const char *file, int line, const char *func, const char *fmt,...)
Log a message to terminal only (no file output).
Definition log.c:1389
@ LOG_COLOR_RESET
Definition log/log.h:155
@ LOG_COLOR_GREY
Definition log/log.h:154
@ LOG_COLOR_FATAL
Definition log/log.h:153
@ LOG_COLOR_ERROR
Definition log/log.h:152
@ LOG_COLOR_DEV
Definition log/log.h:148
@ LOG_COLOR_DEBUG
Definition log/log.h:149
@ LOG_COLOR_INFO
Definition log/log.h:150
@ LOG_COLOR_WARN
Definition log/log.h:151
@ LOG_COLOR_WHITE
Definition log/log.h:156
session_log_buffer_t * log_get_history_buffer(void)
Definition log.c:565
struct log_mmap_config log_mmap_config_t
Definition log/log.h:908
const char * get_level_string_padded(log_level_t level)
Get padded log level string (internal utility for formatting).
Definition log.c:183
void log_console_impl(log_level_t level, const char *file, int line, const char *func, const char *message)
Definition log.c:2334
Color scheme definition.
Definition colorscheme.h:76
Endpoint cryptographic state for handshake, packet protection, authentication, and rekeying.
Heap-backed message waiting for the logging output thread.
Definition log/log.h:133
char * message
Definition log/log.h:135
bool use_stderr
Definition log/log.h:134
Path and size limits for the memory-mapped log file.
Definition log/mmap.h:56
size_t max_size
Definition log/mmap.h:58
const char * log_path
Definition log/mmap.h:57
Thread-safe fixed-size history ring for session-screen log lines.
⏱️ High-precision timing utilities using sokol_time.h and uthash
Log level types and constants.