1 /* SPDX-License-Identifier: GPL-3.0-or-later
2 * Copyright © 2016-2018 The TokTok team.
3 * Copyright © 2013,2015 Tox project.
4 */
5
6 /*
7 * Text logging abstraction.
8 */
9 #ifdef HAVE_CONFIG_H
10 #include "config.h"
11 #endif
12
13 #include "logger.h"
14
15 #include <assert.h>
16 #include <stdarg.h>
17 #include <stdio.h>
18 #include <stdlib.h>
19 #include <string.h>
20
21
22 struct Logger {
23 logger_cb *callback;
24 void *context;
25 void *userdata;
26 };
27
28 #ifdef USE_STDERR_LOGGER
logger_level_name(Logger_Level level)29 static const char *logger_level_name(Logger_Level level)
30 {
31 switch (level) {
32 case LOGGER_LEVEL_TRACE:
33 return "TRACE";
34
35 case LOGGER_LEVEL_DEBUG:
36 return "DEBUG";
37
38 case LOGGER_LEVEL_INFO:
39 return "INFO";
40
41 case LOGGER_LEVEL_WARNING:
42 return "WARNING";
43
44 case LOGGER_LEVEL_ERROR:
45 return "ERROR";
46 }
47
48 return "<unknown>";
49 }
50
logger_stderr_handler(void * context,Logger_Level level,const char * file,int line,const char * func,const char * message,void * userdata)51 static void logger_stderr_handler(void *context, Logger_Level level, const char *file, int line, const char *func,
52 const char *message, void *userdata)
53 {
54 // GL stands for "global logger".
55 fprintf(stderr, "[GL] %s %s:%d(%s): %s\n", logger_level_name(level), file, line, func, message);
56 }
57
58 static const Logger logger_stderr = {
59 logger_stderr_handler,
60 nullptr,
61 nullptr,
62 };
63 #endif
64
65 /**
66 * Public Functions
67 */
logger_new(void)68 Logger *logger_new(void)
69 {
70 return (Logger *)calloc(1, sizeof(Logger));
71 }
72
logger_kill(Logger * log)73 void logger_kill(Logger *log)
74 {
75 free(log);
76 }
77
logger_callback_log(Logger * log,logger_cb * function,void * context,void * userdata)78 void logger_callback_log(Logger *log, logger_cb *function, void *context, void *userdata)
79 {
80 log->callback = function;
81 log->context = context;
82 log->userdata = userdata;
83 }
84
logger_write(const Logger * log,Logger_Level level,const char * file,int line,const char * func,const char * format,...)85 void logger_write(const Logger *log, Logger_Level level, const char *file, int line, const char *func,
86 const char *format, ...)
87 {
88 if (!log) {
89 #ifdef USE_STDERR_LOGGER
90 log = &logger_stderr;
91 #else
92 fprintf(stderr, "NULL logger not permitted.\n");
93 abort();
94 #endif
95 }
96
97 if (!log->callback) {
98 return;
99 }
100
101 // Only pass the file name, not the entire file path, for privacy reasons.
102 // The full path may contain PII of the person compiling toxcore (their
103 // username and directory layout).
104 const char *filename = strrchr(file, '/');
105 file = filename ? filename + 1 : file;
106 #if defined(_WIN32) || defined(__CYGWIN__)
107 // On Windows, the path separator *may* be a backslash, so we look for that
108 // one too.
109 const char *windows_filename = strrchr(file, '\\');
110 file = windows_filename ? windows_filename + 1 : file;
111 #endif
112
113 // Format message
114 char msg[1024];
115 va_list args;
116 va_start(args, format);
117 vsnprintf(msg, sizeof(msg), format, args);
118 va_end(args);
119
120 log->callback(log->context, level, file, line, func, msg, log->userdata);
121 }
122