diff options
author | irungentoo <irungentoo@gmail.com> | 2015-01-10 21:39:40 -0500 |
---|---|---|
committer | irungentoo <irungentoo@gmail.com> | 2015-01-10 21:39:40 -0500 |
commit | 90f68f578cafd8f81d0b2b2742de016ffe06851e (patch) | |
tree | 9cddefa5d894a650d360678e81ec7018be7dfa82 /toxcore/logger.c | |
parent | dd51e03857913bb1b73bc604a64adf5e2740cfe6 (diff) | |
parent | ad672595356f034d81990c307f4e19c619198076 (diff) |
Merge branch 'mannol-master'
Diffstat (limited to 'toxcore/logger.c')
-rw-r--r-- | toxcore/logger.c | 239 |
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 | ||
45 | static struct logger_config { | 44 | |
45 | typedef 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; |
50 | logger = { | 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 | |||
60 | logger *global = NULL; | ||
61 | |||
62 | const 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 | ||
56 | void __attribute__((destructor)) terminate_logger() | 70 | char *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 | ||
68 | unsigned logger_get_pid() | 82 | |
83 | /** | ||
84 | * Public Functions | ||
85 | */ | ||
86 | logger *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 | ||
78 | const 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 | ||
91 | int 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 | ||
116 | void 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 | |||
134 | ERROR: | ||
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 | ||
133 | char *logger_timestr(char *dest, size_t max_size) | 146 | void 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 | ||
151 | char *logger_posstr (char *dest, size_t max_size, const char *file, int line) | 170 | void logger_kill_global(void) |
152 | { | 171 | { |
153 | snprintf(dest, max_size, "%s:%d", file, line); | 172 | logger_kill(global); |
154 | return dest; | 173 | } |
174 | |||
175 | void logger_set_global(logger *log) | ||
176 | { | ||
177 | #ifndef LOGGING /* Disabled */ | ||
178 | return; | ||
179 | #endif | ||
180 | |||
181 | global = log; | ||
182 | } | ||
183 | |||
184 | logger *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 */ | 193 | void 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 | } | ||