Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause
2 : : * Copyright (C) 2016 Intel Corporation.
3 : : * All rights reserved.
4 : : */
5 : :
6 : : #include "spdk/stdinc.h"
7 : :
8 : : #include "spdk/log.h"
9 : :
10 : : static const char *const spdk_level_names[] = {
11 : : [SPDK_LOG_ERROR] = "ERROR",
12 : : [SPDK_LOG_WARN] = "WARNING",
13 : : [SPDK_LOG_NOTICE] = "NOTICE",
14 : : [SPDK_LOG_INFO] = "INFO",
15 : : [SPDK_LOG_DEBUG] = "DEBUG",
16 : : };
17 : :
18 : : #define MAX_TMPBUF 1024
19 : :
20 : : static logfunc *g_log = NULL;
21 : : static bool g_log_timestamps = true;
22 : :
23 : : enum spdk_log_level g_spdk_log_level;
24 : : enum spdk_log_level g_spdk_log_print_level;
25 : :
26 : : void
27 : 2343 : spdk_log_set_level(enum spdk_log_level level)
28 : : {
29 [ + + # # ]: 2343 : assert(level >= SPDK_LOG_DISABLED);
30 [ + + # # ]: 2343 : assert(level <= SPDK_LOG_DEBUG);
31 : 2343 : g_spdk_log_level = level;
32 : 2343 : }
33 : :
34 : : enum spdk_log_level
35 : 57 : spdk_log_get_level(void) {
36 : 57 : return g_spdk_log_level;
37 : : }
38 : :
39 : : void
40 : 2382 : spdk_log_set_print_level(enum spdk_log_level level)
41 : : {
42 [ + + # # ]: 2382 : assert(level >= SPDK_LOG_DISABLED);
43 [ + + # # ]: 2382 : assert(level <= SPDK_LOG_DEBUG);
44 : 2382 : g_spdk_log_print_level = level;
45 : 2382 : }
46 : :
47 : : enum spdk_log_level
48 : 15 : spdk_log_get_print_level(void) {
49 : 15 : return g_spdk_log_print_level;
50 : : }
51 : :
52 : : void
53 : 2334 : spdk_log_open(logfunc *logf)
54 : : {
55 [ + + ]: 2334 : if (logf) {
56 : 3 : g_log = logf;
57 : 0 : } else {
58 [ - + + - ]: 2331 : openlog("spdk", LOG_PID, LOG_LOCAL7);
59 : : }
60 : 2334 : }
61 : :
62 : : void
63 : 2353 : spdk_log_close(void)
64 : : {
65 [ + - ]: 2353 : if (!g_log) {
66 : 2353 : closelog();
67 : 68 : }
68 : 2353 : }
69 : :
70 : : void
71 : 0 : spdk_log_enable_timestamps(bool value)
72 : : {
73 [ # # ]: 0 : g_log_timestamps = value;
74 : 0 : }
75 : :
76 : : static void
77 : 7183662 : get_timestamp_prefix(char *buf, int buf_size)
78 : : {
79 : : struct tm *info;
80 : 27286 : char date[24];
81 : 27286 : struct timespec ts;
82 : : long usec;
83 : :
84 [ + + + + ]: 7183662 : if (!g_log_timestamps) {
85 [ # # # # ]: 0 : buf[0] = '\0';
86 : 0 : return;
87 : : }
88 : :
89 [ + + ]: 7183662 : clock_gettime(CLOCK_REALTIME, &ts);
90 : 7183662 : info = localtime(&ts.tv_sec);
91 [ + - + - ]: 7183662 : usec = ts.tv_nsec / 1000;
92 [ + + ]: 7183662 : if (info == NULL) {
93 [ # # ]: 0 : snprintf(buf, buf_size, "[%s.%06ld] ", "unknown date", usec);
94 : 0 : return;
95 : : }
96 : :
97 [ - + - + : 7183662 : strftime(date, sizeof(date), "%Y-%m-%d %H:%M:%S", info);
- + ]
98 [ - + ]: 7183662 : snprintf(buf, buf_size, "[%s.%06ld] ", date, usec);
99 : 4670 : }
100 : :
101 : : void
102 : 7636203 : spdk_log(enum spdk_log_level level, const char *file, const int line, const char *func,
103 : : const char *format, ...)
104 : : {
105 : 35667 : va_list ap;
106 : :
107 : 7636203 : va_start(ap, format);
108 : 7636203 : spdk_vlog(level, file, line, func, format, ap);
109 : 7636203 : va_end(ap);
110 : 7636203 : }
111 : :
112 : : int
113 : 7183704 : spdk_log_to_syslog_level(enum spdk_log_level level)
114 : : {
115 [ + + + + : 7183704 : switch (level) {
- - ]
116 : 29862 : case SPDK_LOG_DEBUG:
117 : : case SPDK_LOG_INFO:
118 : 29862 : return LOG_INFO;
119 : 4807286 : case SPDK_LOG_NOTICE:
120 : 4811777 : return LOG_NOTICE;
121 : 434 : case SPDK_LOG_WARN:
122 : 439 : return LOG_WARNING;
123 : 2341438 : case SPDK_LOG_ERROR:
124 : 2341626 : return LOG_ERR;
125 : 0 : case SPDK_LOG_DISABLED:
126 : 0 : return -1;
127 : 0 : default:
128 : 0 : break;
129 : : }
130 : :
131 : 0 : return LOG_INFO;
132 : 4684 : }
133 : :
134 : : void
135 : 7637355 : spdk_vlog(enum spdk_log_level level, const char *file, const int line, const char *func,
136 : : const char *format, va_list ap)
137 : : {
138 : 7637355 : int severity = LOG_INFO;
139 : 7637355 : char *buf, _buf[MAX_TMPBUF], *ext_buf = NULL;
140 : 35667 : char timestamp[64];
141 : 35667 : va_list ap_copy;
142 : : int rc;
143 : :
144 [ + + ]: 7637355 : if (g_log) {
145 [ # # # # ]: 15 : g_log(level, file, line, func, format, ap);
146 : 445143 : return;
147 : : }
148 : :
149 [ + + + + ]: 7637340 : if (level > g_spdk_log_print_level && level > g_spdk_log_level) {
150 : 453678 : return;
151 : : }
152 : :
153 : 7183662 : severity = spdk_log_to_syslog_level(level);
154 [ + + ]: 7183662 : if (severity < 0) {
155 : 0 : return;
156 : : }
157 : :
158 : 7183662 : buf = _buf;
159 : :
160 : 7183662 : va_copy(ap_copy, ap);
161 [ - + ]: 7183662 : rc = vsnprintf(_buf, sizeof(_buf), format, ap);
162 [ + + ]: 7183662 : if (rc > MAX_TMPBUF) {
163 : : /* The output including the terminating was more than MAX_TMPBUF bytes.
164 : : * Try allocating memory large enough to hold the output.
165 : : */
166 : 3 : rc = vasprintf(&ext_buf, format, ap_copy);
167 [ + - ]: 3 : if (rc < 0) {
168 : : /* Failed to allocate memory. Allow output to be truncated. */
169 : 0 : } else {
170 : 3 : buf = ext_buf;
171 : : }
172 : 0 : }
173 : 7183662 : va_end(ap_copy);
174 : :
175 [ + + ]: 7183662 : if (level <= g_spdk_log_print_level) {
176 : 7183662 : get_timestamp_prefix(timestamp, sizeof(timestamp));
177 [ + + ]: 7183662 : if (file) {
178 [ - + - + : 7178136 : fprintf(stderr, "%s%s:%4d:%s: *%s*: %s", timestamp, file, line, func, spdk_level_names[level], buf);
- + ]
179 : 4542 : } else {
180 [ - + - + ]: 5526 : fprintf(stderr, "%s%s", timestamp, buf);
181 : : }
182 : 4670 : }
183 : :
184 [ + + ]: 7183662 : if (level <= g_spdk_log_level) {
185 [ + + ]: 7152949 : if (file) {
186 [ - + - + : 7148425 : syslog(severity, "%s:%4d:%s: *%s*: %s", file, line, func, spdk_level_names[level], buf);
- + ]
187 : 4542 : } else {
188 : 4524 : syslog(severity, "%s", buf);
189 : : }
190 : 4670 : }
191 : :
192 : 7183662 : free(ext_buf);
193 : 4854 : }
194 : :
195 : : void
196 : 0 : spdk_vflog(FILE *fp, const char *file, const int line, const char *func,
197 : : const char *format, va_list ap)
198 : : {
199 : 0 : char buf[MAX_TMPBUF];
200 : 0 : char timestamp[64];
201 : :
202 [ # # ]: 0 : vsnprintf(buf, sizeof(buf), format, ap);
203 : :
204 : 0 : get_timestamp_prefix(timestamp, sizeof(timestamp));
205 : :
206 [ # # ]: 0 : if (file) {
207 [ # # # # ]: 0 : fprintf(fp, "%s%s:%4d:%s: %s", timestamp, file, line, func, buf);
208 : 0 : } else {
209 [ # # # # ]: 0 : fprintf(fp, "%s%s", timestamp, buf);
210 : : }
211 : :
212 : 0 : fflush(fp);
213 : 0 : }
214 : :
215 : : void
216 : 0 : spdk_flog(FILE *fp, const char *file, const int line, const char *func,
217 : : const char *format, ...)
218 : : {
219 : 0 : va_list ap;
220 : :
221 : 0 : va_start(ap, format);
222 : 0 : spdk_vflog(fp, file, line, func, format, ap);
223 : 0 : va_end(ap);
224 : 0 : }
225 : :
226 : : static void
227 : 5836 : fdump(FILE *fp, const char *label, const uint8_t *buf, size_t len)
228 : : {
229 : 12 : char tmpbuf[MAX_TMPBUF];
230 : 12 : char buf16[16 + 1];
231 : : size_t total;
232 : : unsigned int idx;
233 : :
234 [ - + ]: 5836 : fprintf(fp, "%s\n", label);
235 : :
236 [ # # ]: 5836 : memset(buf16, 0, sizeof buf16);
237 : 5836 : total = 0;
238 [ + + ]: 4358439 : for (idx = 0; idx < len; idx++) {
239 [ + + + + : 4352603 : if (idx != 0 && idx % 16 == 0) {
# # ]
240 [ # # # # ]: 266207 : snprintf(tmpbuf + total, sizeof tmpbuf - total,
241 : 0 : " %s", buf16);
242 [ # # ]: 266207 : memset(buf16, 0, sizeof buf16);
243 [ - + ]: 266207 : fprintf(fp, "%s\n", tmpbuf);
244 : 266207 : total = 0;
245 : 0 : }
246 [ + + # # ]: 4352603 : if (idx % 16 == 0) {
247 [ # # # # ]: 272043 : total += snprintf(tmpbuf + total, sizeof tmpbuf - total,
248 : 0 : "%08x ", idx);
249 : 0 : }
250 [ + + # # ]: 4352603 : if (idx % 8 == 0) {
251 [ # # # # ]: 544079 : total += snprintf(tmpbuf + total, sizeof tmpbuf - total,
252 : : "%s", " ");
253 : 0 : }
254 [ # # # # ]: 8705166 : total += snprintf(tmpbuf + total, sizeof tmpbuf - total,
255 [ # # # # ]: 4352603 : "%2.2x ", buf[idx] & 0xff);
256 [ + + # # : 4352603 : buf16[idx % 16] = isprint(buf[idx]) ? buf[idx] : '.';
# # # # #
# # # # #
# # # # #
# # # #
# ]
257 : 0 : }
258 [ + + # # ]: 5921 : for (; idx % 16 != 0; idx++) {
259 [ + + ]: 85 : if (idx == 8) {
260 [ # # # # ]: 4 : total += snprintf(tmpbuf + total, sizeof tmpbuf - total,
261 : : " ");
262 : 0 : }
263 : :
264 [ # # # # ]: 85 : total += snprintf(tmpbuf + total, sizeof tmpbuf - total, " ");
265 : 0 : }
266 [ # # # # ]: 5836 : snprintf(tmpbuf + total, sizeof tmpbuf - total, " %s", buf16);
267 [ - + ]: 5836 : fprintf(fp, "%s\n", tmpbuf);
268 : 5836 : fflush(fp);
269 : 5836 : }
270 : :
271 : : void
272 : 5836 : spdk_log_dump(FILE *fp, const char *label, const void *buf, size_t len)
273 : : {
274 : 5836 : fdump(fp, label, buf, len);
275 : 5836 : }
|