Nilorea Library
C utilities for networking, threading, graphics
Loading...
Searching...
No Matches
n_nodup_log.c
Go to the documentation of this file.
1
9#ifndef _GNU_SOURCE
11#define _GNU_SOURCE
13#define _GNU_SOURCE_WAS_NOT_DEFINED
14#endif
15#include <stdio.h>
16#include <stdarg.h>
17#ifdef _GNU_SOURCE_WAS_NOT_DEFINED
18#undef _GNU_SOURCE
19#endif
20
21#include "nilorea/n_common.h"
22#include "nilorea/n_log.h"
23#include "nilorea/n_str.h"
24#include "nilorea/n_list.h"
25#include "nilorea/n_hash.h"
26
27#include "nilorea/n_nodup_log.h"
28
31
36int init_nodup_log(size_t max) {
37 if (_n_nodup_table != NULL) {
38 n_log(LOG_ERR, "Could not allocate the internal hash table because it's already done");
39 return FALSE;
40 }
41 if (max <= 0)
42 max = 1024;
43
45
46 if (_n_nodup_table == NULL) {
47 n_log(LOG_ERR, "Could not allocate the internal hash with size %d", max);
48 return FALSE;
49 } else {
50 n_log(LOG_DEBUG, "LOGGING: nodup system activated with a hash table of %d cells", max);
51 }
52
53 return TRUE;
54} /* init_nodup_log() */
55
61 __n_assert(_n_nodup_table, return FALSE);
63} /* empty_nodup_table() */
64
70 __n_assert(_n_nodup_table, return FALSE);
72} /* close_nodup_log() */
73
81static char* get_nodup_key(const char* file, const char* func, int line) {
82 N_STR* nstr = NULL;
83 char* ptr = NULL;
84 nstrprintf(nstr, "%s%s%d", file, func, line);
85 __n_assert(nstr, return NULL);
86 ptr = nstr->data;
87 Free(nstr);
88 return ptr;
89} /* get_nodup_key */
90
99static char* get_nodup_indexed_key(const char* file, const char* func, const char* prefix, int line) {
100 N_STR* nstr = NULL;
101 char* ptr = NULL;
102 nstrprintf(nstr, "%s%s%s%d", file, func, prefix, line);
103 __n_assert(nstr, return NULL);
104 ptr = nstr->data;
105 Free(nstr);
106 return ptr;
107} /* get_nodup_key */
108
118int check_n_log_dup(const char* log, const char* file, const char* func, int line) {
119 HASH_NODE* node = NULL;
120 char* key = NULL;
121
122 /* check if the nopdup session is on, else do a normal n_log */
123 if (!_n_nodup_table) {
124 return 3;
125 }
126
127 key = get_nodup_key(file, func, line);
128
129 __n_assert(key, return FALSE);
130
132
133 Free(key);
134
135 if (node) {
136 if (strcmp(log, node->data.string) == 0) {
137 return 1;
138 }
139 return 2;
140 }
141 return 0;
142
143} /* check_n_log_dup(...) */
144
155int check_n_log_dup_indexed(const char* log, const char* file, const char* func, int line, const char* prefix) {
156 HASH_NODE* node = NULL;
157 char* key = NULL;
158
159 /* check if the nopdup session is on, else do a normal n_log */
160 if (!_n_nodup_table) {
161 return 3;
162 }
163
164 key = get_nodup_indexed_key(file, func, prefix, line);
165
166 __n_assert(key, return FALSE);
167
169
170 Free(key)
171
172 if (node) {
173 if (strcmp(log, node->data.string) == 0) {
174 return 1;
175 }
176 return 2;
177 }
178 return 0;
179} /* check_nolog_dup_indexed() */
180
189void _n_nodup_log(int LEVEL, const char* file, const char* func, int line, const char* format, ...) {
190 __n_assert(file, return);
191 __n_assert(func, return);
192 __n_assert(format, return);
193
194 HASH_NODE* node = NULL;
195 va_list args;
196
197 char* syslogbuffer = NULL;
198
199 va_start(args, format);
200 if (vasprintf(&syslogbuffer, format, args) == -1) {
201 int error = errno;
202 n_log(LOG_ERR, "=>%s:%s:%d unable to parse '%s', %s", file, func, line, format, strerror(error));
203 }
204 va_end(args);
205
206 char* key = get_nodup_key(file, func, line);
207 int is_dup = check_n_log_dup(syslogbuffer, file, func, line);
208
209 switch (is_dup) {
210 /* new log entry for file,func,line */
211 case 0:
212 if (_n_nodup_table) {
213 ht_put_string(_n_nodup_table, key, syslogbuffer);
214 }
215 _n_log(LEVEL, file, func, line, "%s", syslogbuffer);
216 break;
217
218 /* exising and same log entry, do nothing (maybe latter we will add a timeout to repeat logging) */
219 case 1:
220 break;
221 /* existing but different entry. We have to refresh and log it one time*/
222 case 2:
224 if (node && node->data.string) {
225 Free(node->data.string);
226 node->data.string = syslogbuffer;
227 }
228 _n_log(LEVEL, file, func, line, "%s", syslogbuffer);
229 break;
230 /* no nodup session started, normal loggin */
231 case 3:
232 default:
233 _n_log(LEVEL, file, func, line, "%s", syslogbuffer);
234 break;
235 }
236
237 Free(syslogbuffer);
238 Free(key);
239
240} /* _n_nodup_log() */
241
251void _n_nodup_log_indexed(int LEVEL, const char* prefix, const char* file, const char* func, int line, const char* format, ...) {
252 HASH_NODE* node = NULL;
253 va_list args;
254
255 char* syslogbuffer = NULL;
256
257 va_start(args, format);
258 if (vasprintf(&syslogbuffer, format, args) == -1) {
259 int error = errno;
260 n_log(LOG_ERR, "=>%s:%s:%d unable to parse '%s:%s', %s", file, func, line, prefix, format, strerror(error));
261 }
262 va_end(args);
263
264 char* key = get_nodup_indexed_key(file, func, prefix, line);
265 int is_dup = check_n_log_dup_indexed(syslogbuffer, file, func, line, prefix);
266
267 switch (is_dup) {
268 /* new log entry for file,func,line */
269 case 0:
270 if (_n_nodup_table) {
271 ht_put_string(_n_nodup_table, key, syslogbuffer);
272 }
273 _n_log(LEVEL, file, func, line, "%s", syslogbuffer);
274 break;
275
276 /* exising and same log entry, do nothing (maybe latter we will add a timeout to repeat logging) */
277 case 1:
278 break;
279 /* existing but different entry. We have to refresh and log it one time*/
280 case 2:
282 if (node && node->data.string) {
283 Free(node->data.string);
284 node->data.string = syslogbuffer;
285 }
286 _n_log(LEVEL, file, func, line, "%s", syslogbuffer);
287 break;
288 /* no nodup session started, normal loggin */
289 case 3:
290 default:
291 _n_log(LEVEL, file, func, line, "%s", syslogbuffer);
292 break;
293 }
294
295 Free(syslogbuffer);
296 Free(key);
297
298} /* _n_nodup_log_indexed() */
299
307int dump_nodup_log(char* file) {
308 FILE* out = NULL;
309 HASH_NODE* hash_node = NULL;
310 __n_assert(file, return FALSE);
311 __n_assert(_n_nodup_table, return FALSE);
312
313 char* tmpfile = NULL;
314 n_log(LOG_DEBUG, "outfile:%s", file);
315 strprintf(tmpfile, "%s.tmp", file);
316 if (!tmpfile) {
317 n_log(LOG_ERR, "could not create tmp file name from filename %s", _str(file));
318 return FALSE;
319 }
320
321 int fd = open(tmpfile, O_CREAT | O_WRONLY | O_TRUNC, 0600); // Only owner can read/write
322 if (fd < 0) {
323 n_log(LOG_ERR, "could not create file %s with 0600 permissions", _str(tmpfile));
324 Free(tmpfile);
325 return FALSE;
326 }
327
328 out = fdopen(fd, "wb");
329 __n_assert(out, close(fd); Free(tmpfile); return FALSE);
330
331 if (_n_nodup_table) {
332 for (unsigned long int it = 0; it < _n_nodup_table->size; it++) {
333 list_foreach(list_node, _n_nodup_table->hash_table[it]) {
334 hash_node = (HASH_NODE*)list_node->ptr;
335 fprintf(out, "%s\n", hash_node->data.string);
336 }
337 }
338 }
339 fclose(out);
340
341 int error = 0;
342 if (rename(tmpfile, file) != 0) {
343 error = errno;
344 n_log(LOG_ERR, "could not rename '%s' to '%s' , %s", tmpfile, file,
345 strerror(error));
346 }
347 Free(tmpfile);
348
349 return TRUE;
350
351} /* dump_nodup_log() */
char * key
#define __n_assert(__ptr, __ret)
macro to assert things
Definition n_common.h:256
#define _str(__PTR)
define true
Definition n_common.h:174
#define Free(__ptr)
Free Handler to get errors.
Definition n_common.h:240
union HASH_DATA data
data inside the node
Definition n_hash.h:103
LIST ** hash_table
HASH_CLASSIC mode: preallocated hash table.
Definition n_hash.h:125
char * string
char *type
Definition n_hash.h:89
size_t size
size of the hash table
Definition n_hash.h:119
int destroy_ht(HASH_TABLE **table)
empty a table and destroy it
Definition n_hash.c:2148
HASH_TABLE * new_ht(size_t size)
Create a hash table with the given size.
Definition n_hash.c:1916
int empty_ht(HASH_TABLE *table)
empty a table
Definition n_hash.c:2138
int ht_put_string(HASH_TABLE *table, const char *key, char *string)
put a string value (copy/dup) with given key in the targeted hash table
Definition n_hash.c:2081
HASH_NODE * ht_get_node(HASH_TABLE *table, const char *key)
get node at 'key' from 'table'
Definition n_hash.c:1976
structure of a hash table node
Definition n_hash.h:93
structure of a hash table
Definition n_hash.h:117
#define list_foreach(__ITEM_, __LIST_)
ForEach macro helper.
Definition n_list.h:66
#define n_log(__LEVEL__,...)
Logging function wrapper to get line and func.
Definition n_log.h:70
#define LOG_DEBUG
debug-level messages
Definition n_log.h:65
#define LOG_ERR
error conditions
Definition n_log.h:57
void _n_log(int level, const char *file, const char *func, int line, const char *format,...)
Logging function.
Definition n_log.c:244
int init_nodup_log(size_t max)
initialize the no duplicate logging system
Definition n_nodup_log.c:36
int dump_nodup_log(char *file)
Dump the duplicate error log hash table in a file The table is first written to a temporary file whic...
int close_nodup_log()
Empty nodup logtable and close the no duplicate logging session.
Definition n_nodup_log.c:69
void _n_nodup_log(int LEVEL, const char *file, const char *func, int line, const char *format,...)
Logging function.
int empty_nodup_table()
Empty the nodup internal table.
Definition n_nodup_log.c:60
void _n_nodup_log_indexed(int LEVEL, const char *prefix, const char *file, const char *func, int line, const char *format,...)
Logging function.
char * data
the string
Definition n_str.h:41
#define strprintf(__n_var,...)
Macro to quickly allocate and sprintf to a char.
Definition n_str.h:72
#define nstrprintf(__nstr_var, __format,...)
Macro to quickly allocate and sprintf to N_STR.
Definition n_str.h:94
A box including a string and his lenght.
Definition n_str.h:39
Common headers and low-level functions & define.
Hash functions and table.
List structures and definitions.
int vasprintf(char **strp, const char *fmt, va_list ap)
snprintf from a va_list, helper for asprintf
Definition n_log.c:203
Generic log system.
int check_n_log_dup(const char *log, const char *file, const char *func, int line)
check if a log was already done or not at the given line, func, file
int check_n_log_dup_indexed(const char *log, const char *file, const char *func, int line, const char *prefix)
check if a log was already done or not at the given line, func, file
static char * get_nodup_key(const char *file, const char *func, int line)
internal, get a key for a log entry
Definition n_nodup_log.c:81
static HASH_TABLE * _n_nodup_table
internal: no dup hash_table log save
Definition n_nodup_log.c:30
static char * get_nodup_indexed_key(const char *file, const char *func, const char *prefix, int line)
internal, get a key for an indexed log entry
Definition n_nodup_log.c:99
Generic No Dup Log system.
N_STR and string function declaration.