lsquic_logger.h revision e8bd737d
1/* Copyright (c) 2017 - 2018 LiteSpeed Technologies Inc. See LICENSE. */ 2/* 3 * lsquic_logger.h -- logging functions and macros. 4 * 5 * Usage (this assumes MY_MODULE) is a part of enum lsquic_logger_module): 6 * #define LSQUIC_LOGGER_MODULE MY_MODULE 7 * #include "lsquic_logger.h" 8 * LSQ_INFO("info message"); 9 * 10 * If you want log messages from your module to contain connection ID, #define 11 * LSQUIC_LOG_CONN_ID so that it evaluates to connection ID. If, in addition, 12 * you want stream ID to be logged, #define LSQUIC_LOG_STREAM_ID similarly. 13 * See existing code for examples. 14 * 15 * To add a module: 16 * 1. Add entry to enum lsquic_logger_module. 17 * 2. Update lsqlm_to_str. 18 * 3. Update lsq_log_levels. 19 */ 20 21#ifndef LSQUIC_LOGGER_H 22#define LSQUIC_LOGGER_H 23 24#include <stdint.h> 25#include <stdio.h> 26 27#ifdef __cplusplus 28extern "C" { 29#endif 30 31#ifndef LSQUIC_LOWEST_LOG_LEVEL 32# define LSQUIC_LOWEST_LOG_LEVEL LSQ_LOG_DEBUG 33#endif 34 35/* Same levels as in sys/syslog.h: */ 36enum lsq_log_level { 37 LSQ_LOG_EMERG, 38 LSQ_LOG_ALERT, 39 LSQ_LOG_CRIT, 40 LSQ_LOG_ERROR, 41 LSQ_LOG_WARN, 42 LSQ_LOG_NOTICE, 43 LSQ_LOG_INFO, 44 LSQ_LOG_DEBUG, 45 N_LSQUIC_LOG_LEVELS 46}; 47 48enum lsquic_logger_module { 49 LSQLM_NOMODULE, 50 LSQLM_LOGGER, 51 LSQLM_EVENT, 52 LSQLM_ENGINE, 53 LSQLM_CONN, 54 LSQLM_RECHIST, 55 LSQLM_STREAM, 56 LSQLM_PARSE, 57 LSQLM_CFCW, 58 LSQLM_SFCW, 59 LSQLM_SENDCTL, 60 LSQLM_ALARMSET, 61 LSQLM_CRYPTO, 62 LSQLM_HANDSHAKE, 63 LSQLM_HSK_ADAPTER, 64 LSQLM_CUBIC, 65 LSQLM_HEADERS, 66 LSQLM_FRAME_WRITER, 67 LSQLM_FRAME_READER, 68 LSQLM_CONN_HASH, 69 LSQLM_ENG_HIST, 70 LSQLM_SPI, 71 LSQLM_DI, 72 LSQLM_PACER, 73 LSQLM_MIN_HEAP, 74 N_LSQUIC_LOGGER_MODULES 75}; 76 77/* Each module has its own log level. 78 */ 79extern enum lsq_log_level lsq_log_levels[N_LSQUIC_LOGGER_MODULES]; 80 81extern const char *const lsqlm_to_str[N_LSQUIC_LOGGER_MODULES]; 82 83extern const char *const lsq_loglevel2str[N_LSQUIC_LOG_LEVELS]; 84 85#define LSQ_LOG_ENABLED_EXT(level, module) ( \ 86 level <= LSQUIC_LOWEST_LOG_LEVEL && level <= lsq_log_levels[module]) 87 88#define LSQ_LOG_ENABLED(level) LSQ_LOG_ENABLED_EXT(level, LSQUIC_LOGGER_MODULE) 89 90/* The functions that perform actual logging are void. This is an 91 * optimization. In majority of cases the calls will succeed; even if 92 * they fail, there is nothing (at least, nothing simple) to be done to 93 * handle logging failure. 94 */ 95 96/* There are four levels of log functions, depending on whether they take 97 * the following arguments: 98 * 1. Logger module 99 * 2. Connection ID 100 * 3. Stream ID 101 * 102 * Each level of logging function supports one additional argument, as seen 103 * below. LSQ_LOG is set to one of LSQ_LOG0, LSQ_LOG1, LSQ_LOG2, or LSQ_LOG3. 104 * You can still use LSQ_LOG{0..3} directly. 105 */ 106 107void 108lsquic_logger_log3 (enum lsq_log_level, enum lsquic_logger_module, 109 uint64_t conn_id, uint32_t stream_id, 110 const char *format, ...) 111#if __GNUC__ 112 __attribute__((format(printf, 5, 6))) 113#endif 114; 115# define LSQ_LOG3(level, ...) do { \ 116 if (LSQ_LOG_ENABLED(level)) \ 117 lsquic_logger_log3(level, LSQUIC_LOGGER_MODULE, \ 118 LSQUIC_LOG_CONN_ID, LSQUIC_LOG_STREAM_ID, __VA_ARGS__); \ 119 } while (0) 120 121void 122lsquic_logger_log2 (enum lsq_log_level, enum lsquic_logger_module, 123 uint64_t conn_id, const char *format, ...) 124#if __GNUC__ 125 __attribute__((format(printf, 4, 5))) 126#endif 127; 128# define LSQ_LOG2(level, ...) do { \ 129 if (LSQ_LOG_ENABLED(level)) \ 130 lsquic_logger_log2(level, LSQUIC_LOGGER_MODULE, \ 131 LSQUIC_LOG_CONN_ID, __VA_ARGS__); \ 132 } while (0) 133 134void 135lsquic_logger_log1 (enum lsq_log_level, enum lsquic_logger_module, 136 const char *format, ...) 137#if __GNUC__ 138 __attribute__((format(printf, 3, 4))) 139#endif 140; 141# define LSQ_LOG1(level, ...) do { \ 142 if (LSQ_LOG_ENABLED(level)) \ 143 lsquic_logger_log1(level, LSQUIC_LOGGER_MODULE, __VA_ARGS__); \ 144 } while (0) 145 146void 147lsquic_logger_log0 (enum lsq_log_level, const char *format, ...) 148#if __GNUC__ 149 __attribute__((format(printf, 2, 3))) 150#endif 151; 152# define LSQ_LOG0(level, ...) do { \ 153 if (LSQ_LOG_ENABLED(level)) \ 154 lsquic_logger_log0(level, __VA_ARGS__); \ 155 } while (0) 156 157#if defined(LSQUIC_LOGGER_MODULE) 158#if defined(LSQUIC_LOG_CONN_ID) 159#if defined(LSQUIC_LOG_STREAM_ID) 160# define LSQ_LOG LSQ_LOG3 161#else 162# define LSQ_LOG LSQ_LOG2 163#endif 164#else 165# define LSQ_LOG LSQ_LOG1 166#endif 167#else 168# define LSQ_LOG LSQ_LOG0 169# define LSQUIC_LOGGER_MODULE LSQLM_NOMODULE 170#endif 171 172#define LSQ_DEBUG(...) LSQ_LOG(LSQ_LOG_DEBUG, __VA_ARGS__) 173#define LSQ_WARN(...) LSQ_LOG(LSQ_LOG_WARN, __VA_ARGS__) 174#define LSQ_ALERT(...) LSQ_LOG(LSQ_LOG_ALERT, __VA_ARGS__) 175#define LSQ_CRIT(...) LSQ_LOG(LSQ_LOG_CRIT, __VA_ARGS__) 176#define LSQ_ERROR(...) LSQ_LOG(LSQ_LOG_ERROR, __VA_ARGS__) 177#define LSQ_NOTICE(...) LSQ_LOG(LSQ_LOG_NOTICE, __VA_ARGS__) 178#define LSQ_INFO(...) LSQ_LOG(LSQ_LOG_INFO, __VA_ARGS__) 179#define LSQ_EMERG(...) LSQ_LOG(LSQ_LOG_EMERG, __VA_ARGS__) 180 181/* Shorthand for printing to file streams using internal lsquic_logger_if 182 */ 183void 184lsquic_log_to_fstream (FILE *, unsigned llts); 185 186enum lsquic_logger_module 187lsquic_str_to_logger_module (const char *); 188 189enum lsq_log_level 190lsquic_str_to_log_level (const char *); 191 192/* Parse and set log levels passed via -l flag. If an error is encountered, 193 * an error message is printed to stderr and negative value is returned. 194 */ 195int 196lsquic_logger_lopt (const char *optarg); 197 198#ifdef __cplusplus 199} 200#endif 201 202#endif 203