1a74702c6SGeorge Wang/* Copyright (c) 2017 - 2022 LiteSpeed Technologies Inc. See LICENSE. */ 250aadb33SDmitri Tikhonov/* 350aadb33SDmitri Tikhonov * lsquic_logger.h -- logging functions and macros. 450aadb33SDmitri Tikhonov * 550aadb33SDmitri Tikhonov * Usage (this assumes MY_MODULE) is a part of enum lsquic_logger_module): 650aadb33SDmitri Tikhonov * #define LSQUIC_LOGGER_MODULE MY_MODULE 750aadb33SDmitri Tikhonov * #include "lsquic_logger.h" 850aadb33SDmitri Tikhonov * LSQ_INFO("info message"); 950aadb33SDmitri Tikhonov * 1050aadb33SDmitri Tikhonov * If you want log messages from your module to contain connection ID, #define 1150aadb33SDmitri Tikhonov * LSQUIC_LOG_CONN_ID so that it evaluates to connection ID. If, in addition, 1250aadb33SDmitri Tikhonov * you want stream ID to be logged, #define LSQUIC_LOG_STREAM_ID similarly. 1350aadb33SDmitri Tikhonov * See existing code for examples. 1450aadb33SDmitri Tikhonov * 1550aadb33SDmitri Tikhonov * To add a module: 1650aadb33SDmitri Tikhonov * 1. Add entry to enum lsquic_logger_module. 1750aadb33SDmitri Tikhonov * 2. Update lsqlm_to_str. 1850aadb33SDmitri Tikhonov * 3. Update lsq_log_levels. 1950aadb33SDmitri Tikhonov */ 2050aadb33SDmitri Tikhonov 2150aadb33SDmitri Tikhonov#ifndef LSQUIC_LOGGER_H 2250aadb33SDmitri Tikhonov#define LSQUIC_LOGGER_H 2350aadb33SDmitri Tikhonov 2450aadb33SDmitri Tikhonov#include <stdint.h> 2550aadb33SDmitri Tikhonov#include <stdio.h> 2650aadb33SDmitri Tikhonov 27f07b3eaeSTyler Young#include "lsquic_shared_support.h" 28f07b3eaeSTyler Young 2950aadb33SDmitri Tikhonov#ifdef __cplusplus 3050aadb33SDmitri Tikhonovextern "C" { 3150aadb33SDmitri Tikhonov#endif 3250aadb33SDmitri Tikhonov 3350aadb33SDmitri Tikhonov#ifndef LSQUIC_LOWEST_LOG_LEVEL 3450aadb33SDmitri Tikhonov# define LSQUIC_LOWEST_LOG_LEVEL LSQ_LOG_DEBUG 3550aadb33SDmitri Tikhonov#endif 3650aadb33SDmitri Tikhonov 3750aadb33SDmitri Tikhonov/* Same levels as in sys/syslog.h: */ 3850aadb33SDmitri Tikhonovenum lsq_log_level { 3950aadb33SDmitri Tikhonov LSQ_LOG_EMERG, 4050aadb33SDmitri Tikhonov LSQ_LOG_ALERT, 4150aadb33SDmitri Tikhonov LSQ_LOG_CRIT, 4250aadb33SDmitri Tikhonov LSQ_LOG_ERROR, 4350aadb33SDmitri Tikhonov LSQ_LOG_WARN, 4450aadb33SDmitri Tikhonov LSQ_LOG_NOTICE, 4550aadb33SDmitri Tikhonov LSQ_LOG_INFO, 4650aadb33SDmitri Tikhonov LSQ_LOG_DEBUG, 4750aadb33SDmitri Tikhonov N_LSQUIC_LOG_LEVELS 4850aadb33SDmitri Tikhonov}; 4950aadb33SDmitri Tikhonov 5050aadb33SDmitri Tikhonovenum lsquic_logger_module { 5150aadb33SDmitri Tikhonov LSQLM_NOMODULE, 5250aadb33SDmitri Tikhonov LSQLM_LOGGER, 5350aadb33SDmitri Tikhonov LSQLM_EVENT, 5450aadb33SDmitri Tikhonov LSQLM_ENGINE, 5550aadb33SDmitri Tikhonov LSQLM_CONN, 5650aadb33SDmitri Tikhonov LSQLM_STREAM, 5750aadb33SDmitri Tikhonov LSQLM_PARSE, 5850aadb33SDmitri Tikhonov LSQLM_CFCW, 5950aadb33SDmitri Tikhonov LSQLM_SFCW, 6050aadb33SDmitri Tikhonov LSQLM_SENDCTL, 6150aadb33SDmitri Tikhonov LSQLM_ALARMSET, 6250aadb33SDmitri Tikhonov LSQLM_CRYPTO, 6350aadb33SDmitri Tikhonov LSQLM_HANDSHAKE, 6450aadb33SDmitri Tikhonov LSQLM_HSK_ADAPTER, 655392f7a3SLiteSpeed Tech LSQLM_BBR, 6650aadb33SDmitri Tikhonov LSQLM_CUBIC, 67b1a7c3f9SDmitri Tikhonov LSQLM_ADAPTIVE_CC, 6850aadb33SDmitri Tikhonov LSQLM_HEADERS, 6950aadb33SDmitri Tikhonov LSQLM_FRAME_WRITER, 7050aadb33SDmitri Tikhonov LSQLM_FRAME_READER, 715392f7a3SLiteSpeed Tech LSQLM_MINI_CONN, 725392f7a3SLiteSpeed Tech LSQLM_TOKGEN, 7350aadb33SDmitri Tikhonov LSQLM_ENG_HIST, 7450aadb33SDmitri Tikhonov LSQLM_SPI, 75fbc6cc04SDmitri Tikhonov LSQLM_HPI, 7650aadb33SDmitri Tikhonov LSQLM_DI, 775392f7a3SLiteSpeed Tech LSQLM_PRQ, 7850aadb33SDmitri Tikhonov LSQLM_PACER, 793b55e6aeSDmitri Tikhonov LSQLM_HTTP1X, 8055cd0b38SDmitri Tikhonov LSQLM_QLOG, 815392f7a3SLiteSpeed Tech LSQLM_TRAPA, 825392f7a3SLiteSpeed Tech LSQLM_PURGA, 835392f7a3SLiteSpeed Tech LSQLM_HCSI_READER, 845392f7a3SLiteSpeed Tech LSQLM_HCSO_WRITER, 855392f7a3SLiteSpeed Tech LSQLM_QENC_HDL, 865392f7a3SLiteSpeed Tech LSQLM_QDEC_HDL, 875392f7a3SLiteSpeed Tech LSQLM_QPACK_ENC, 885392f7a3SLiteSpeed Tech LSQLM_QPACK_DEC, 895392f7a3SLiteSpeed Tech LSQLM_PRIO, 905392f7a3SLiteSpeed Tech LSQLM_BW_SAMPLER, 91b8fa6195SDmitri Tikhonov LSQLM_PACKET_RESIZE, 92758aff32SDmitri Tikhonov LSQLM_CONN_STATS, 9350aadb33SDmitri Tikhonov N_LSQUIC_LOGGER_MODULES 9450aadb33SDmitri Tikhonov}; 9550aadb33SDmitri Tikhonov 9650aadb33SDmitri Tikhonov/* Each module has its own log level. 9750aadb33SDmitri Tikhonov */ 98f07b3eaeSTyler Young 99f07b3eaeSTyler YoungLSQUIC_EXTERN enum lsq_log_level lsq_log_levels[N_LSQUIC_LOGGER_MODULES]; 10050aadb33SDmitri Tikhonov 10150aadb33SDmitri Tikhonovextern const char *const lsqlm_to_str[N_LSQUIC_LOGGER_MODULES]; 10250aadb33SDmitri Tikhonov 10350aadb33SDmitri Tikhonovextern const char *const lsq_loglevel2str[N_LSQUIC_LOG_LEVELS]; 10450aadb33SDmitri Tikhonov 10550aadb33SDmitri Tikhonov#define LSQ_LOG_ENABLED_EXT(level, module) ( \ 10650aadb33SDmitri Tikhonov level <= LSQUIC_LOWEST_LOG_LEVEL && level <= lsq_log_levels[module]) 10750aadb33SDmitri Tikhonov 10850aadb33SDmitri Tikhonov#define LSQ_LOG_ENABLED(level) LSQ_LOG_ENABLED_EXT(level, LSQUIC_LOGGER_MODULE) 10950aadb33SDmitri Tikhonov 1105392f7a3SLiteSpeed Techstruct lsquic_cid; 1115392f7a3SLiteSpeed Tech 11250aadb33SDmitri Tikhonov/* The functions that perform actual logging are void. This is an 11350aadb33SDmitri Tikhonov * optimization. In majority of cases the calls will succeed; even if 11450aadb33SDmitri Tikhonov * they fail, there is nothing (at least, nothing simple) to be done to 11550aadb33SDmitri Tikhonov * handle logging failure. 11650aadb33SDmitri Tikhonov */ 11750aadb33SDmitri Tikhonov 11850aadb33SDmitri Tikhonov/* There are four levels of log functions, depending on whether they take 11950aadb33SDmitri Tikhonov * the following arguments: 12050aadb33SDmitri Tikhonov * 1. Logger module 12150aadb33SDmitri Tikhonov * 2. Connection ID 12250aadb33SDmitri Tikhonov * 3. Stream ID 12350aadb33SDmitri Tikhonov * 12450aadb33SDmitri Tikhonov * Each level of logging function supports one additional argument, as seen 12550aadb33SDmitri Tikhonov * below. LSQ_LOG is set to one of LSQ_LOG0, LSQ_LOG1, LSQ_LOG2, or LSQ_LOG3. 12650aadb33SDmitri Tikhonov * You can still use LSQ_LOG{0..3} directly. 12750aadb33SDmitri Tikhonov */ 12850aadb33SDmitri Tikhonov 12950aadb33SDmitri Tikhonovvoid 13050aadb33SDmitri Tikhonovlsquic_logger_log3 (enum lsq_log_level, enum lsquic_logger_module, 1315392f7a3SLiteSpeed Tech const struct lsquic_cid *conn_id, 1325392f7a3SLiteSpeed Tech lsquic_stream_id_t stream_id, const char *format, ...) 13350aadb33SDmitri Tikhonov#if __GNUC__ 13450aadb33SDmitri Tikhonov __attribute__((format(printf, 5, 6))) 13550aadb33SDmitri Tikhonov#endif 13650aadb33SDmitri Tikhonov; 13750aadb33SDmitri Tikhonov# define LSQ_LOG3(level, ...) do { \ 13850aadb33SDmitri Tikhonov if (LSQ_LOG_ENABLED(level)) \ 13950aadb33SDmitri Tikhonov lsquic_logger_log3(level, LSQUIC_LOGGER_MODULE, \ 1405392f7a3SLiteSpeed Tech LSQUIC_LOG_CONN_ID, LSQUIC_LOG_STREAM_ID, __VA_ARGS__); \ 14150aadb33SDmitri Tikhonov } while (0) 14250aadb33SDmitri Tikhonov 1435392f7a3SLiteSpeed Tech 14450aadb33SDmitri Tikhonovvoid 14550aadb33SDmitri Tikhonovlsquic_logger_log2 (enum lsq_log_level, enum lsquic_logger_module, 1465392f7a3SLiteSpeed Tech const struct lsquic_cid *conn_id, const char *format, ...) 14750aadb33SDmitri Tikhonov#if __GNUC__ 14850aadb33SDmitri Tikhonov __attribute__((format(printf, 4, 5))) 14950aadb33SDmitri Tikhonov#endif 15050aadb33SDmitri Tikhonov; 15150aadb33SDmitri Tikhonov# define LSQ_LOG2(level, ...) do { \ 15250aadb33SDmitri Tikhonov if (LSQ_LOG_ENABLED(level)) \ 15350aadb33SDmitri Tikhonov lsquic_logger_log2(level, LSQUIC_LOGGER_MODULE, \ 1545392f7a3SLiteSpeed Tech LSQUIC_LOG_CONN_ID, __VA_ARGS__); \ 1555392f7a3SLiteSpeed Tech } while (0) 1565392f7a3SLiteSpeed Tech# define LSQ_LOG2C(level, ...) do { \ 1575392f7a3SLiteSpeed Tech if (LSQ_LOG_ENABLED(level)) \ 1585392f7a3SLiteSpeed Tech { \ 1595392f7a3SLiteSpeed Tech char cidbuf_[MAX_CID_LEN * 2 + 1]; \ 1605392f7a3SLiteSpeed Tech lsquic_logger_log2(level, LSQUIC_LOGGER_MODULE, \ 1615392f7a3SLiteSpeed Tech LSQUIC_LOG_CONN_ID, __VA_ARGS__); \ 1625392f7a3SLiteSpeed Tech } \ 16350aadb33SDmitri Tikhonov } while (0) 16450aadb33SDmitri Tikhonov 16550aadb33SDmitri Tikhonovvoid 16650aadb33SDmitri Tikhonovlsquic_logger_log1 (enum lsq_log_level, enum lsquic_logger_module, 16750aadb33SDmitri Tikhonov const char *format, ...) 16850aadb33SDmitri Tikhonov#if __GNUC__ 16950aadb33SDmitri Tikhonov __attribute__((format(printf, 3, 4))) 17050aadb33SDmitri Tikhonov#endif 17150aadb33SDmitri Tikhonov; 17250aadb33SDmitri Tikhonov# define LSQ_LOG1(level, ...) do { \ 17350aadb33SDmitri Tikhonov if (LSQ_LOG_ENABLED(level)) \ 17450aadb33SDmitri Tikhonov lsquic_logger_log1(level, LSQUIC_LOGGER_MODULE, __VA_ARGS__); \ 17550aadb33SDmitri Tikhonov } while (0) 1765392f7a3SLiteSpeed Tech# define LSQ_LOG1C(level, ...) do { \ 1775392f7a3SLiteSpeed Tech if (LSQ_LOG_ENABLED(level)) \ 1785392f7a3SLiteSpeed Tech { \ 1795392f7a3SLiteSpeed Tech char cidbuf_[MAX_CID_LEN * 2 + 1]; \ 1805392f7a3SLiteSpeed Tech lsquic_logger_log1(level, LSQUIC_LOGGER_MODULE, __VA_ARGS__); \ 1815392f7a3SLiteSpeed Tech } \ 1825392f7a3SLiteSpeed Tech } while (0) 18350aadb33SDmitri Tikhonov 18450aadb33SDmitri Tikhonovvoid 18550aadb33SDmitri Tikhonovlsquic_logger_log0 (enum lsq_log_level, const char *format, ...) 18650aadb33SDmitri Tikhonov#if __GNUC__ 18750aadb33SDmitri Tikhonov __attribute__((format(printf, 2, 3))) 18850aadb33SDmitri Tikhonov#endif 18950aadb33SDmitri Tikhonov; 19050aadb33SDmitri Tikhonov# define LSQ_LOG0(level, ...) do { \ 19150aadb33SDmitri Tikhonov if (LSQ_LOG_ENABLED(level)) \ 19250aadb33SDmitri Tikhonov lsquic_logger_log0(level, __VA_ARGS__); \ 19350aadb33SDmitri Tikhonov } while (0) 1945392f7a3SLiteSpeed Tech# define LSQ_LOG0C(level, ...) do { \ 1955392f7a3SLiteSpeed Tech if (LSQ_LOG_ENABLED(level)) \ 1965392f7a3SLiteSpeed Tech { \ 1975392f7a3SLiteSpeed Tech char cidbuf_[MAX_CID_LEN * 2 + 1]; \ 1985392f7a3SLiteSpeed Tech lsquic_logger_log0(level, __VA_ARGS__); \ 1995392f7a3SLiteSpeed Tech } \ 2005392f7a3SLiteSpeed Tech } while (0) 20150aadb33SDmitri Tikhonov 20250aadb33SDmitri Tikhonov#if defined(LSQUIC_LOGGER_MODULE) 20350aadb33SDmitri Tikhonov#if defined(LSQUIC_LOG_CONN_ID) 20450aadb33SDmitri Tikhonov#if defined(LSQUIC_LOG_STREAM_ID) 20550aadb33SDmitri Tikhonov# define LSQ_LOG LSQ_LOG3 20650aadb33SDmitri Tikhonov#else 20750aadb33SDmitri Tikhonov# define LSQ_LOG LSQ_LOG2 2085392f7a3SLiteSpeed Tech# define LSQ_LOGC LSQ_LOG2C 20950aadb33SDmitri Tikhonov#endif 21050aadb33SDmitri Tikhonov#else 21150aadb33SDmitri Tikhonov# define LSQ_LOG LSQ_LOG1 2125392f7a3SLiteSpeed Tech# define LSQ_LOGC LSQ_LOG1C 21350aadb33SDmitri Tikhonov#endif 21450aadb33SDmitri Tikhonov#else 21550aadb33SDmitri Tikhonov# define LSQ_LOG LSQ_LOG0 2165392f7a3SLiteSpeed Tech# define LSQ_LOGC LSQ_LOG0C 21750aadb33SDmitri Tikhonov# define LSQUIC_LOGGER_MODULE LSQLM_NOMODULE 21850aadb33SDmitri Tikhonov#endif 21950aadb33SDmitri Tikhonov 22050aadb33SDmitri Tikhonov#define LSQ_DEBUG(...) LSQ_LOG(LSQ_LOG_DEBUG, __VA_ARGS__) 22150aadb33SDmitri Tikhonov#define LSQ_WARN(...) LSQ_LOG(LSQ_LOG_WARN, __VA_ARGS__) 22250aadb33SDmitri Tikhonov#define LSQ_ALERT(...) LSQ_LOG(LSQ_LOG_ALERT, __VA_ARGS__) 22350aadb33SDmitri Tikhonov#define LSQ_CRIT(...) LSQ_LOG(LSQ_LOG_CRIT, __VA_ARGS__) 22450aadb33SDmitri Tikhonov#define LSQ_ERROR(...) LSQ_LOG(LSQ_LOG_ERROR, __VA_ARGS__) 22550aadb33SDmitri Tikhonov#define LSQ_NOTICE(...) LSQ_LOG(LSQ_LOG_NOTICE, __VA_ARGS__) 22650aadb33SDmitri Tikhonov#define LSQ_INFO(...) LSQ_LOG(LSQ_LOG_INFO, __VA_ARGS__) 22750aadb33SDmitri Tikhonov#define LSQ_EMERG(...) LSQ_LOG(LSQ_LOG_EMERG, __VA_ARGS__) 22850aadb33SDmitri Tikhonov 2295392f7a3SLiteSpeed Tech#define LSQ_DEBUGC(...) LSQ_LOGC(LSQ_LOG_DEBUG, __VA_ARGS__) 2305392f7a3SLiteSpeed Tech#define LSQ_WARNC(...) LSQ_LOGC(LSQ_LOG_WARN, __VA_ARGS__) 2315392f7a3SLiteSpeed Tech#define LSQ_ALERTC(...) LSQ_LOGC(LSQ_LOG_ALERT, __VA_ARGS__) 2325392f7a3SLiteSpeed Tech#define LSQ_CRITC(...) LSQ_LOGC(LSQ_LOG_CRIT, __VA_ARGS__) 2335392f7a3SLiteSpeed Tech#define LSQ_ERRORC(...) LSQ_LOGC(LSQ_LOG_ERROR, __VA_ARGS__) 2345392f7a3SLiteSpeed Tech#define LSQ_NOTICEC(...) LSQ_LOGC(LSQ_LOG_NOTICE, __VA_ARGS__) 2355392f7a3SLiteSpeed Tech#define LSQ_INFOC(...) LSQ_LOGC(LSQ_LOG_INFO, __VA_ARGS__) 2365392f7a3SLiteSpeed Tech#define LSQ_EMERGC(...) LSQ_LOGC(LSQ_LOG_EMERG, __VA_ARGS__) 2375392f7a3SLiteSpeed Tech 23850aadb33SDmitri Tikhonov/* Shorthand for printing to file streams using internal lsquic_logger_if 23950aadb33SDmitri Tikhonov */ 24050aadb33SDmitri Tikhonovvoid 24150aadb33SDmitri Tikhonovlsquic_log_to_fstream (FILE *, unsigned llts); 24250aadb33SDmitri Tikhonov 24350aadb33SDmitri Tikhonovenum lsquic_logger_module 24450aadb33SDmitri Tikhonovlsquic_str_to_logger_module (const char *); 24550aadb33SDmitri Tikhonov 24650aadb33SDmitri Tikhonovenum lsq_log_level 24750aadb33SDmitri Tikhonovlsquic_str_to_log_level (const char *); 24850aadb33SDmitri Tikhonov 24950aadb33SDmitri Tikhonov/* Parse and set log levels passed via -l flag. If an error is encountered, 25050aadb33SDmitri Tikhonov * an error message is printed to stderr and negative value is returned. 25150aadb33SDmitri Tikhonov */ 25250aadb33SDmitri Tikhonovint 25350aadb33SDmitri Tikhonovlsquic_logger_lopt (const char *optarg); 25450aadb33SDmitri Tikhonov 2555392f7a3SLiteSpeed Tech#define CID_FMT ".*s" 2565392f7a3SLiteSpeed Tech 257fb73393fSDmitri Tikhonov#define CID_BITS_B(cid, b) 2 * (int) (cid)->len, \ 258fb73393fSDmitri Tikhonov (lsquic_cid2str(cid, b), b) 259fb73393fSDmitri Tikhonov 260fb73393fSDmitri Tikhonov#define CID_BITS(cid) CID_BITS_B(cid, cidbuf_) 2615392f7a3SLiteSpeed Tech 2625392f7a3SLiteSpeed Techvoid 2635392f7a3SLiteSpeed Techlsquic_cid2str (const struct lsquic_cid *, char *out); 2645392f7a3SLiteSpeed Tech 2655392f7a3SLiteSpeed Techconst struct lsquic_cid * 2665392f7a3SLiteSpeed Techlsquic_conn_log_cid (const struct lsquic_conn *); 2675392f7a3SLiteSpeed Tech 26850aadb33SDmitri Tikhonov#ifdef __cplusplus 26950aadb33SDmitri Tikhonov} 27050aadb33SDmitri Tikhonov#endif 27150aadb33SDmitri Tikhonov 27250aadb33SDmitri Tikhonov#endif 273