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