summaryrefslogtreecommitdiff
path: root/toxcore/logger.c
diff options
context:
space:
mode:
authorirungentoo <irungentoo@gmail.com>2015-01-10 21:39:40 -0500
committerirungentoo <irungentoo@gmail.com>2015-01-10 21:39:40 -0500
commit90f68f578cafd8f81d0b2b2742de016ffe06851e (patch)
tree9cddefa5d894a650d360678e81ec7018be7dfa82 /toxcore/logger.c
parentdd51e03857913bb1b73bc604a64adf5e2740cfe6 (diff)
parentad672595356f034d81990c307f4e19c619198076 (diff)
Merge branch 'mannol-master'
Diffstat (limited to 'toxcore/logger.c')
-rw-r--r--toxcore/logger.c239
1 files changed, 158 insertions, 81 deletions
diff --git a/toxcore/logger.c b/toxcore/logger.c
index 674d72e9..fa9d1760 100644
--- a/toxcore/logger.c
+++ b/toxcore/logger.c
@@ -1,7 +1,5 @@
1/* logger.c 1/* logger.c
2 * 2 *
3 * Wrapping logger functions in nice macros
4 *
5 * Copyright (C) 2013 Tox project All Rights Reserved. 3 * Copyright (C) 2013 Tox project All Rights Reserved.
6 * 4 *
7 * This file is part of Tox. 5 * This file is part of Tox.
@@ -26,10 +24,7 @@
26#endif /* HAVE_CONFIG_H */ 24#endif /* HAVE_CONFIG_H */
27 25
28#include "logger.h" 26#include "logger.h"
29 27#include "crypto_core.h" /* for random_int() */
30#ifdef LOGGING
31
32#include "network.h" /* for time */
33 28
34#include <stdio.h> 29#include <stdio.h>
35#include <errno.h> 30#include <errno.h>
@@ -37,121 +32,203 @@
37#include <stdarg.h> 32#include <stdarg.h>
38#include <inttypes.h> 33#include <inttypes.h>
39#include <time.h> 34#include <time.h>
35#include <pthread.h>
40 36
41#if defined(_WIN32) || defined(__WIN32__) || defined (WIN32) 37#if defined(_WIN32) || defined(__WIN32__) || defined (WIN32)
42#define strerror_r(errno,buf,len) strerror_s(buf,len,errno) 38# define getpid() ((unsigned) GetCurrentProcessId())
39# define SFILE(FILE__M) (strrchr(FILE__M, '\\') ? strrchr(FILE__M, '\\') + 1 : FILE__M)
40#else
41# define SFILE(FILE__M) (strrchr(FILE__M, '/') ? strrchr(FILE__M, '/') + 1 : FILE__M)
43#endif 42#endif
44 43
45static struct logger_config { 44
45typedef struct logger {
46 FILE *log_file; 46 FILE *log_file;
47 LoggerLevel level; 47 LOG_LEVEL level;
48 uint64_t start_time; /* Time when lib loaded */ 48 uint64_t start_time; /* Time when lib loaded */
49} 49 char *id;
50logger = { 50
51 NULL, 51 /* Allocate these once */
52 DEBUG, 52 char *tstr;
53 0 53 char *posstr;
54 char *msg;
55
56 /* For thread synchronisation */
57 pthread_mutex_t mutex[1];
58} logger;
59
60logger *global = NULL;
61
62const char *LOG_LEVEL_STR [] = {
63 [LOG_TRACE] = "TRACE",
64 [LOG_DEBUG] = "DEBUG",
65 [LOG_INFO] = "INFO" ,
66 [LOG_WARNING] = "WARN" ,
67 [LOG_ERROR] = "ERROR",
54}; 68};
55 69
56void __attribute__((destructor)) terminate_logger() 70char *strtime(char *dest, size_t max_len)
57{ 71{
58 if ( !logger.log_file ) return; 72 time_t timer;
59 73 struct tm *tm_info;
60 time_t tim = time(NULL);
61 74
62 logger_write(ERROR, "\n============== Closing logger [%u] ==============\n" 75 time(&timer);
63 "Time: %s", logger_get_pid(), asctime(localtime(&tim))); 76 tm_info = localtime(&timer);
64 77
65 fclose(logger.log_file); 78 strftime(dest, max_len, "%m:%d %H:%M:%S", tm_info);
79 return dest;
66} 80}
67 81
68unsigned logger_get_pid() 82
83/**
84 * Public Functions
85 */
86logger *logger_new (const char *file_name, LOG_LEVEL level, const char *id)
69{ 87{
70 return 88#ifndef LOGGING /* Disabled */
71#if defined(_WIN32) || defined(__WIN32__) || defined (WIN32) 89 return NULL;
72 GetCurrentProcessId();
73#else
74 getpid();
75#endif 90#endif
76}
77 91
78const char *logger_stringify_level(LoggerLevel level) 92 logger *retu = calloc(1, sizeof(logger));
79{
80 static const char *strings [] = {
81 "INFO",
82 "DEBUG",
83 "WARN",
84 "ERROR"
85 };
86
87 return strings[level];
88}
89 93
94 if (!retu)
95 return NULL;
90 96
91int logger_init(const char *file_name, LoggerLevel level) 97 if ( pthread_mutex_init(retu->mutex, NULL) != 0 ) {
92{ 98 free(retu);
93 if (logger.log_file) { 99 return NULL;
94 fprintf(stderr, "Error opening logger name: %s with level %d: file already opened!\n",
95 file_name, level);
96 return -1;
97 } 100 }
98 101
99 logger.log_file = fopen(file_name, "ab"); 102 if (!(retu->log_file = fopen(file_name, "ab"))) {
100
101 if (logger.log_file == NULL) {
102 fprintf(stderr, "Error opening logger file: %s; info: %s\n", file_name, strerror(errno)); 103 fprintf(stderr, "Error opening logger file: %s; info: %s\n", file_name, strerror(errno));
103 return -1; 104 free(retu);
105 pthread_mutex_destroy(retu->mutex);
106 return NULL;
104 } 107 }
105 108
106 logger.level = level; 109 if (!(retu->tstr = calloc(16, sizeof (char))) ||
107 logger.start_time = current_time_monotonic(); 110 !(retu->posstr = calloc(300, sizeof (char))) ||
111 !(retu->msg = calloc(4096, sizeof (char))) )
112 goto ERROR;
108 113
109 time_t tim = time(NULL); 114 if (id) {
110 logger_write(ERROR, "\n============== Starting logger [%u] ==============\n" 115 if (!(retu->id = calloc(strlen(id) + 1, 1)))
111 "Time: %s", logger_get_pid(), asctime(localtime(&tim))); 116 goto ERROR;
112 return 0;
113}
114 117
118 strcpy(retu->id, id);
119 } else {
120 if (!(retu->id = malloc(8)))
121 goto ERROR;
115 122
116void logger_write (LoggerLevel level, const char *format, ...) 123 snprintf(retu->id, 8, "%u", random_int());
117{
118 if (logger.log_file == NULL) {
119 /*fprintf(stderr, "Logger file is NULL!\n");*/
120 return;
121 } 124 }
122 125
123 if (logger.level > level) return; /* Don't print some levels xuh */ 126 retu->level = level;
127 retu->start_time = current_time_monotonic();
124 128
125 va_list _arg; 129 fprintf(retu->log_file, "Successfully created and running logger id: %s; time: %s\n",
126 va_start (_arg, format); 130 retu->id, strtime(retu->tstr, 16));
127 vfprintf (logger.log_file, format, _arg);
128 va_end (_arg);
129 131
130 fflush(logger.log_file); 132 return retu;
133
134ERROR:
135 fprintf(stderr, "Failed to create logger!\n");
136 pthread_mutex_destroy(retu->mutex);
137 fclose(retu->log_file);
138 free(retu->tstr);
139 free(retu->posstr);
140 free(retu->msg);
141 free(retu->id);
142 free(retu);
143 return NULL;
131} 144}
132 145
133char *logger_timestr(char *dest, size_t max_size) 146void logger_kill(logger *log)
134{ 147{
135 time_t timer; 148#ifndef LOGGING /* Disabled */
136 struct tm *tm_info; 149 return;
150#endif
137 151
138 time(&timer); 152 if (!log)
139 tm_info = localtime(&timer); 153 return;
140 154
141 strftime(dest, max_size, "%m:%d %H:%M:%S", tm_info); 155 pthread_mutex_lock(log->mutex);
156 free(log->id);
157 free(log->tstr);
158 free(log->posstr);
159 free(log->msg);
142 160
143 return dest; 161 if (fclose(log->log_file) != 0 )
162 perror("Could not close log file");
144 163
145 /*uint64_t diff = (current_time_monotonic() - logger.start_time); /* ms * / 164 pthread_mutex_unlock(log->mutex);
146 snprintf(dest, max_size, "%"PRIu64"", diff); 165 pthread_mutex_destroy(log->mutex);
147 166
148 return dest; */ 167 free(log);
149} 168}
150 169
151char *logger_posstr (char *dest, size_t max_size, const char *file, int line) 170void logger_kill_global(void)
152{ 171{
153 snprintf(dest, max_size, "%s:%d", file, line); 172 logger_kill(global);
154 return dest; 173}
174
175void logger_set_global(logger *log)
176{
177#ifndef LOGGING /* Disabled */
178 return;
179#endif
180
181 global = log;
182}
183
184logger *logger_get_global(void)
185{
186#ifndef LOGGING /* Disabled */
187 return NULL;
188#endif
189
190 return global;
155} 191}
156 192
157#endif /* LOGGING */ 193void logger_write (logger *log, LOG_LEVEL level, const char *file, int line, const char *format, ...)
194{
195#ifndef LOGGING /* Disabled */
196 return;
197#endif
198
199 static const char *logger_format =
200 "%s " /* Logger id string */
201 "%-16s" /* Time string of format: %m:%d %H:%M:%S */
202 "%u " /* Thread id */
203 "%-5s " /* Logger lever string */
204 "%-20s " /* File:line string */
205 "- %s" /* Output message */
206 "\n"; /* Every new print new line */
207
208
209 logger *this_log = log ? log : global;
210
211 if (!this_log)
212 return;
213
214 /* Don't print levels lesser than set one */
215 if (this_log->level > level)
216 return;
217
218 pthread_mutex_lock(this_log->mutex);
219
220 /* Set position str */
221 snprintf(this_log->posstr, 300, "%s:%d", SFILE(file), line);
222
223 /* Set message */
224 va_list args;
225 va_start (args, format);
226 vsnprintf(this_log->msg, 4096, format, args);
227 va_end (args);
228
229 fprintf(this_log->log_file, logger_format, this_log->id, strtime(this_log->tstr, 16), pthread_self(),
230 LOG_LEVEL_STR[level], this_log->posstr, this_log->msg);
231 fflush(this_log->log_file);
232
233 pthread_mutex_unlock(this_log->mutex);
234}