lsquic_logger.h revision 10c492f0
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    N_LSQUIC_LOGGER_MODULES
74};
75
76/* Each module has its own log level.
77 */
78extern enum lsq_log_level lsq_log_levels[N_LSQUIC_LOGGER_MODULES];
79
80extern const char *const lsqlm_to_str[N_LSQUIC_LOGGER_MODULES];
81
82extern const char *const lsq_loglevel2str[N_LSQUIC_LOG_LEVELS];
83
84#define LSQ_LOG_ENABLED_EXT(level, module) (                            \
85    level <= LSQUIC_LOWEST_LOG_LEVEL && level <= lsq_log_levels[module])
86
87#define LSQ_LOG_ENABLED(level) LSQ_LOG_ENABLED_EXT(level, LSQUIC_LOGGER_MODULE)
88
89/* The functions that perform actual logging are void.  This is an
90 * optimization.  In majority of cases the calls will succeed; even if
91 * they fail, there is nothing (at least, nothing simple) to be done to
92 * handle logging failure.
93 */
94
95/* There are four levels of log functions, depending on whether they take
96 * the following arguments:
97 *  1. Logger module
98 *  2. Connection ID
99 *  3. Stream ID
100 *
101 * Each level of logging function supports one additional argument, as seen
102 * below.  LSQ_LOG is set to one of LSQ_LOG0, LSQ_LOG1, LSQ_LOG2, or LSQ_LOG3.
103 * You can still use LSQ_LOG{0..3} directly.
104 */
105
106void
107lsquic_logger_log3 (enum lsq_log_level, enum lsquic_logger_module,
108                    uint64_t conn_id, uint32_t stream_id,
109                    const char *format, ...)
110#if __GNUC__
111            __attribute__((format(printf, 5, 6)))
112#endif
113;
114#   define LSQ_LOG3(level, ...) do {                                         \
115        if (LSQ_LOG_ENABLED(level))                                          \
116            lsquic_logger_log3(level, LSQUIC_LOGGER_MODULE,                  \
117                     LSQUIC_LOG_CONN_ID, LSQUIC_LOG_STREAM_ID, __VA_ARGS__); \
118    } while (0)
119
120void
121lsquic_logger_log2 (enum lsq_log_level, enum lsquic_logger_module,
122                    uint64_t conn_id, const char *format, ...)
123#if __GNUC__
124            __attribute__((format(printf, 4, 5)))
125#endif
126;
127#   define LSQ_LOG2(level, ...) do {                                         \
128        if (LSQ_LOG_ENABLED(level))                                          \
129            lsquic_logger_log2(level, LSQUIC_LOGGER_MODULE,                  \
130                                        LSQUIC_LOG_CONN_ID, __VA_ARGS__);    \
131    } while (0)
132
133void
134lsquic_logger_log1 (enum lsq_log_level, enum lsquic_logger_module,
135                    const char *format, ...)
136#if __GNUC__
137            __attribute__((format(printf, 3, 4)))
138#endif
139;
140#   define LSQ_LOG1(level, ...) do {                                         \
141        if (LSQ_LOG_ENABLED(level))                                          \
142            lsquic_logger_log1(level, LSQUIC_LOGGER_MODULE, __VA_ARGS__);    \
143    } while (0)
144
145void
146lsquic_logger_log0 (enum lsq_log_level, const char *format, ...)
147#if __GNUC__
148            __attribute__((format(printf, 2, 3)))
149#endif
150;
151#   define LSQ_LOG0(level, ...) do {                                         \
152        if (LSQ_LOG_ENABLED(level))                                          \
153            lsquic_logger_log0(level, __VA_ARGS__);                          \
154    } while (0)
155
156#if defined(LSQUIC_LOGGER_MODULE)
157#if defined(LSQUIC_LOG_CONN_ID)
158#if defined(LSQUIC_LOG_STREAM_ID)
159#       define LSQ_LOG LSQ_LOG3
160#else
161#       define LSQ_LOG LSQ_LOG2
162#endif
163#else
164#       define LSQ_LOG LSQ_LOG1
165#endif
166#else
167#       define LSQ_LOG LSQ_LOG0
168#       define LSQUIC_LOGGER_MODULE LSQLM_NOMODULE
169#endif
170
171#define LSQ_DEBUG(...)   LSQ_LOG(LSQ_LOG_DEBUG,  __VA_ARGS__)
172#define LSQ_WARN(...)    LSQ_LOG(LSQ_LOG_WARN,   __VA_ARGS__)
173#define LSQ_ALERT(...)   LSQ_LOG(LSQ_LOG_ALERT,  __VA_ARGS__)
174#define LSQ_CRIT(...)    LSQ_LOG(LSQ_LOG_CRIT,   __VA_ARGS__)
175#define LSQ_ERROR(...)   LSQ_LOG(LSQ_LOG_ERROR,  __VA_ARGS__)
176#define LSQ_NOTICE(...)  LSQ_LOG(LSQ_LOG_NOTICE, __VA_ARGS__)
177#define LSQ_INFO(...)    LSQ_LOG(LSQ_LOG_INFO,   __VA_ARGS__)
178#define LSQ_EMERG(...)   LSQ_LOG(LSQ_LOG_EMERG,  __VA_ARGS__)
179
180/* Shorthand for printing to file streams using internal lsquic_logger_if
181 */
182void
183lsquic_log_to_fstream (FILE *, unsigned llts);
184
185enum lsquic_logger_module
186lsquic_str_to_logger_module (const char *);
187
188enum lsq_log_level
189lsquic_str_to_log_level (const char *);
190
191/* Parse and set log levels passed via -l flag.  If an error is encountered,
192 * an error message is printed to stderr and negative value is returned.
193 */
194int
195lsquic_logger_lopt (const char *optarg);
196
197#ifdef __cplusplus
198}
199#endif
200
201#endif
202