110 lines
5.0 KiB
C
110 lines
5.0 KiB
C
#ifndef LOG_H
|
|
#define LOG_H
|
|
|
|
#include <stdio.h>
|
|
#include <stdbool.h>
|
|
#include <stdint.h>
|
|
|
|
/* Ask the compiler to type-check the printf-style arguments of the variadic
|
|
* logging helpers. Only enabled for GNU-compatible compilers (gcc/clang). */
|
|
#if defined(__GNUC__)
|
|
#define LOG_PRINTF_ATTR(fmt_idx, first_vararg_idx) \
|
|
__attribute__((format(printf, fmt_idx, first_vararg_idx)))
|
|
#else
|
|
#define LOG_PRINTF_ATTR(fmt_idx, first_vararg_idx)
|
|
#endif
|
|
|
|
typedef enum { LOG_LEVEL_DEBUG, LOG_LEVEL_INFO, LOG_LEVEL_WARNING, LOG_LEVEL_ERROR } LogLevel;
|
|
/* --stderr=MODE destinations. ERRORS keeps errors on stderr and everything
|
|
* else on stdout; ALL sends every message to stderr; CLIENT routes the client's
|
|
* own diagnostics over the protocol stream to the peer's stderr (rsync's
|
|
* --stderr=client / --no-msgs2stderr). */
|
|
typedef enum { LOG_STDERR_ERRORS, LOG_STDERR_ALL, LOG_STDERR_CLIENT } LogStderrMode;
|
|
|
|
typedef enum {
|
|
LOG_DEBUG_IO = 1u << 0,
|
|
LOG_DEBUG_PROTO = 1u << 1,
|
|
LOG_DEBUG_PACK = 1u << 2,
|
|
LOG_DEBUG_UTIL = 1u << 3,
|
|
/* rsync --debug categories that now map to a natural FastSync event:
|
|
* flist (file-list scan progress), del (deletions), hash/deltasum
|
|
* (whole-file hashing and delta-sum generation), recv (receiver
|
|
* responses/signatures), filter (selection/exclusion decisions) and send
|
|
* (files handed to the sender). Only emitted when the category is
|
|
* explicitly enabled; a normal run stays silent. */
|
|
LOG_DEBUG_FLIST = 1u << 4,
|
|
LOG_DEBUG_DEL = 1u << 5,
|
|
LOG_DEBUG_HASH = 1u << 6,
|
|
LOG_DEBUG_RECV = 1u << 7,
|
|
LOG_DEBUG_FILTER = 1u << 8,
|
|
LOG_DEBUG_SEND = 1u << 9,
|
|
LOG_DEBUG_ALL = (1u << 10) - 1,
|
|
} LogDebugFlag;
|
|
|
|
typedef enum {
|
|
LOG_INFO_COPY = 1u << 0,
|
|
LOG_INFO_MISC = 1u << 1,
|
|
LOG_INFO_SKIP = 1u << 2,
|
|
LOG_INFO_STATS = 1u << 3,
|
|
/* rsync categories that map to a FastSync event (emitted in rsync's line
|
|
* format): del (deletions), remove (sender-side source removal), name
|
|
* (transferred entry names), flist (file-list header), nonreg (skipped
|
|
* non-regular files), progress (per-file progress). rsync's `backup`
|
|
* category is accepted for CLI parity but stays silent: the receiver does the
|
|
* backing-up and FastSync has no backup event to report from the sender. */
|
|
LOG_INFO_DEL = 1u << 4,
|
|
LOG_INFO_REMOVE = 1u << 5,
|
|
LOG_INFO_NAME = 1u << 6,
|
|
LOG_INFO_FLIST = 1u << 7,
|
|
LOG_INFO_NONREG = 1u << 8,
|
|
LOG_INFO_PROGRESS = 1u << 9,
|
|
/* Marker for `--info=name2` and higher: also print rsync's
|
|
"NAME is uptodate" line for entries the receiver already has. It rides in
|
|
the info_level bitset (there is no separate Config field) and is never set
|
|
by --info=all (which selects level 1). */
|
|
LOG_INFO_NAME_UPTODATE = 1u << 10,
|
|
/* --info=mount: print rsync's `[sender] skipping mount-point dir NAME` when
|
|
* -xx/--one-file-system drops a mount-point directory (FastSync's client is
|
|
* the sender). */
|
|
LOG_INFO_MOUNT = 1u << 11,
|
|
LOG_INFO_ALL = LOG_INFO_COPY | LOG_INFO_MISC | LOG_INFO_SKIP | LOG_INFO_STATS | LOG_INFO_DEL |
|
|
LOG_INFO_REMOVE | LOG_INFO_NAME | LOG_INFO_FLIST | LOG_INFO_NONREG |
|
|
LOG_INFO_PROGRESS | LOG_INFO_MOUNT,
|
|
} LogInfoFlag;
|
|
|
|
void log_message(LogLevel log_level, const char* message, ...) LOG_PRINTF_ATTR(2, 3);
|
|
void log_perror(const char* context);
|
|
void set_log_level(LogLevel level);
|
|
void set_log_debug_flags(uint32_t flags);
|
|
uint32_t get_log_debug_flags(void);
|
|
/* True when a log_debug_message() call with the same flag would actually emit:
|
|
* the debug log level is enabled AND the flag is selected. Hot paths use this
|
|
* to skip expensive message formatting/escaping when the line is filtered. */
|
|
bool log_debug_enabled(LogDebugFlag flag);
|
|
void log_debug_message(LogDebugFlag flag, const char* message, ...) LOG_PRINTF_ATTR(2, 3);
|
|
void set_log_info_flags(uint32_t flags);
|
|
uint32_t get_log_info_flags(void);
|
|
void log_info_message(LogInfoFlag flag, const char* message, ...) LOG_PRINTF_ATTR(2, 3);
|
|
void log_set_file(FILE* fp);
|
|
void log_set_8_bit_output(bool enabled);
|
|
bool log_get_8_bit_output(void);
|
|
void log_set_stderr_mode(LogStderrMode mode);
|
|
LogStderrMode log_get_stderr_mode(void);
|
|
/* Write a message a peer forwarded over the client-message channel to this
|
|
* process's stderr (and log file), with the standard log prefix. Used by the
|
|
* server side of rsync's --stderr=client. */
|
|
void log_client_message(const char* message);
|
|
|
|
/* Sink for LOG_STDERR_CLIENT. log_message() passes the un-prefixed message
|
|
* body to the installed sink; a `true` return means the sink took ownership
|
|
* (e.g. queued it for protocol transmission) and the message must NOT also be
|
|
* written locally. A `false` return (or a NULL sink) makes log_message fall
|
|
* back to the normal local destination, so a diagnostic emitted before the peer
|
|
* connection exists is never lost (rsync's documented fallback). The sink may
|
|
* be called from any thread and must be tolerant of that. */
|
|
typedef bool (*LogClientMsgSink)(const char* message);
|
|
void log_set_client_msg_sink(LogClientMsgSink sink);
|
|
LogClientMsgSink log_get_client_msg_sink(void);
|
|
|
|
#endif
|