Nilorea Library
C utilities for networking, threading, graphics
n_nodup_log.c
Go to the documentation of this file.
1
8#ifndef _GNU_SOURCE
10#define _GNU_SOURCE
12#define _GNU_SOURCE_WAS_NOT_DEFINED
13#endif
14#include <stdio.h>
15#include <stdarg.h>
16#ifdef _GNU_SOURCE_WAS_NOT_DEFINED
17#undef _GNU_SOURCE
18#endif
19
20#include "nilorea/n_common.h"
21#include "nilorea/n_log.h"
22#include "nilorea/n_str.h"
23#include "nilorea/n_list.h"
24#include "nilorea/n_hash.h"
25
26#include "nilorea/n_nodup_log.h"
27
29static HASH_TABLE *_n_nodup_table = NULL ;
30
36int init_nodup_log( int max )
37{
38 if( _n_nodup_table != NULL )
39 {
40 n_log( LOG_ERR, "Could not allocate the internal hash table because it's already done" );
41 return FALSE ;
42 }
43 if( max <= 0 )
44 max = 1024 ;
45
46 _n_nodup_table = new_ht( max );
47
48 if( _n_nodup_table == NULL )
49 {
50 n_log( LOG_ERR, "Could not allocate the internal hash with size %d", max );
51 return FALSE ;
52 }
53 else
54 {
55 n_log( LOG_DEBUG, "LOGGING: nodup system activated with a hash table of %d cells", max );
56 }
57
58 return TRUE ;
59} /* init_nodup_log() */
60
61
62
68{
69 __n_assert( _n_nodup_table, return FALSE );
70 return empty_ht( _n_nodup_table );
71} /* empty_nodup_table() */
72
73
74
80{
81 __n_assert( _n_nodup_table, return FALSE );
82 return destroy_ht( &_n_nodup_table );
83} /* close_nodup_log() */
84
85
93static char *get_nodup_key( const char *file, const char *func, int line )
94{
95 N_STR *nstr = NULL ;
96 char *ptr = NULL ;
97 nstrprintf( nstr, "%s%s%d", file, func, line );
98 __n_assert( nstr, return NULL );
99 ptr = nstr -> data ;
100 Free( nstr );
101 return ptr ;
102} /* get_nodup_key */
103
104
105
114static char *get_nodup_indexed_key( const char *file, const char *func, const char *prefix, int line )
115{
116 N_STR *nstr = NULL ;
117 char *ptr = NULL ;
118 nstrprintf( nstr, "%s%s%s%d", file, func, prefix, line );
119 __n_assert( nstr, return NULL );
120 ptr = nstr -> data ;
121 Free( nstr );
122 return ptr ;
123} /* get_nodup_key */
124
125
126
127
137int check_n_log_dup( const char *log, const char *file, const char *func, int line )
138{
139 HASH_NODE *node = NULL ;
140 char *key = NULL ;
141
142 /* check if the nopdup session is on, else do a normal n_log */
143 if( !_n_nodup_table )
144 {
145 return 3 ;
146 }
147
148
149 key = get_nodup_key( file, func, line );
150
151 __n_assert( key, return FALSE );
152
153 node = ht_get_node( _n_nodup_table, key );
154
155 Free( key );
156
157 if( node )
158 {
159 if( strcmp( log, node -> data . string ) == 0 )
160 {
161 return 1 ;
162 }
163 return 2 ;
164 }
165 return 0 ;
166
167} /* check_n_log_dup(...) */
168
169
180int check_n_log_dup_indexed( const char *log, const char *file, const char *func, int line, const char *prefix )
181{
182 HASH_NODE *node = NULL ;
183 char *key = NULL ;
184
185 /* check if the nopdup session is on, else do a normal n_log */
186 if( !_n_nodup_table )
187 {
188 return 3 ;
189 }
190
191 key = get_nodup_indexed_key( file, func, prefix, line );
192
193 __n_assert( key, return FALSE );
194
195 node = ht_get_node( _n_nodup_table, key );
196
197 Free( key )
198
199 if( node )
200 {
201 if( strcmp( log, node -> data . string ) == 0 )
202 {
203 return 1 ;
204 }
205 return 2 ;
206 }
207 return 0 ;
208} /* check_nolog_dup_indexed() */
209
210
211
220void _n_nodup_log( int LEVEL, const char *file, const char *func, int line, const char *format, ... )
221{
222 __n_assert( file , return );
223 __n_assert( func , return );
224 __n_assert( format , return );
225
226 HASH_NODE *node = NULL ;
227 va_list args ;
228
229 char *syslogbuffer = NULL ;
230
231 va_start (args, format);
232 if( vasprintf( &syslogbuffer, format, args ) == -1 )
233 {
234 int error = errno ;
235 n_log( LOG_ERR , "=>%s:%s:%d unable to parse '%s', %s" , file , func , line , format , strerror( error ) );
236 }
237 va_end( args );
238
239 char *key = get_nodup_key( file, func, line );
240 int is_dup = check_n_log_dup( syslogbuffer, file, func, line );
241
242 switch( is_dup )
243 {
244 /* new log entry for file,func,line */
245 case 0 :
246 if( _n_nodup_table )
247 {
248 ht_put_string( _n_nodup_table, key, syslogbuffer );
249 }
250 _n_log( LEVEL, file, func, line, "%s", syslogbuffer );
251 break ;
252
253 /* exising and same log entry, do nothing (maybe latter we will add a timeout to repeat logging) */
254 case 1 :
255 break ;
256 /* existing but different entry. We have to refresh and log it one time*/
257 case 2 :
258 node = ht_get_node( _n_nodup_table, key );
259 if( node && node -> data . string )
260 {
261 Free( node -> data . string );
262 node -> data . string = syslogbuffer ;
263 }
264 _n_log( LEVEL, file, func, line, "%s", syslogbuffer );
265 break ;
266 /* no nodup session started, normal loggin */
267 case 3 :
268 default:
269 _n_log( LEVEL, file, func, line, "%s", syslogbuffer );
270 break ;
271 }
272
273 Free( syslogbuffer );
274 Free( key );
275
276} /* _n_nodup_log() */
277
278
288void _n_nodup_log_indexed( int LEVEL, const char *prefix, const char *file, const char *func, int line, const char *format, ... )
289{
290 HASH_NODE *node = NULL ;
291 va_list args ;
292
293 char *syslogbuffer = NULL ;
294
295 va_start (args, format);
296 if( vasprintf( &syslogbuffer, format, args ) == -1 )
297 {
298 int error = errno ;
299 n_log( LOG_ERR , "=>%s:%s:%d unable to parse '%s:%s', %s" , file , func , line , prefix , format , strerror( error ) );
300 }
301 va_end( args );
302
303 char *key = get_nodup_indexed_key( file, func, prefix, line );
304 int is_dup = check_n_log_dup_indexed( syslogbuffer, file, func, line, prefix );
305
306 switch( is_dup )
307 {
308 /* new log entry for file,func,line */
309 case 0 :
310 if( _n_nodup_table )
311 {
312 ht_put_string( _n_nodup_table, key, syslogbuffer );
313 }
314 _n_log( LEVEL, file, func, line, "%s", syslogbuffer );
315 break ;
316
317 /* exising and same log entry, do nothing (maybe latter we will add a timeout to repeat logging) */
318 case 1 :
319 break ;
320 /* existing but different entry. We have to refresh and log it one time*/
321 case 2 :
322 node = ht_get_node( _n_nodup_table, key );
323 if( node && node -> data . string )
324 {
325 Free( node -> data . string );
326 node -> data . string = syslogbuffer ;
327 }
328 _n_log( LEVEL, file, func, line, "%s", syslogbuffer );
329 break ;
330 /* no nodup session started, normal loggin */
331 case 3 :
332 default:
333 _n_log( LEVEL, file, func, line, "%s", syslogbuffer );
334 break ;
335
336 }
337
338 Free( syslogbuffer );
339 Free( key );
340
341} /* _n_nodup_log_indexed() */
342
343
344
350int dump_nodup_log( char *file )
351{
352 FILE *out = NULL ;
353 HASH_NODE *hash_node = NULL ;
354 __n_assert( file, return FALSE );
355 __n_assert( _n_nodup_table, return FALSE );
356
357 char *tmpfile = NULL ;
358 n_log( LOG_DEBUG, "outfile:%s", file );
359 strprintf( tmpfile, "%s.tmp", file );
360
361 out = fopen( tmpfile, "wb" );
362 __n_assert( out, return FALSE );
363
364 if( _n_nodup_table )
365 {
366 for( unsigned long int it = 0 ; it < _n_nodup_table -> size ; it ++ )
367 {
368 list_foreach( list_node, _n_nodup_table -> hash_table[ it ] )
369 {
370 hash_node = (HASH_NODE *)list_node -> ptr ;
371 fprintf( out, "%s\n", hash_node -> data . string );
372 }
373 }
374 }
375 fclose( out );
376
377 char *cmd = NULL ;
378 strprintf( cmd, "mv -f %s %s ; chmod 644 %s", tmpfile, file, file );
379 n_log( LOG_DEBUG, "%s", cmd );
380 int ret = system( cmd );
381 int error = errno ;
382 if( ret == -1 )
383 {
384 n_log( LOG_ERR , "could not run '%s' , %s" , cmd , strerror( error ) );
385 }
386
387 Free( cmd );
388 Free( tmpfile );
389
390 return TRUE ;
391
392} /* dump_nodup_log() */
#define __n_assert(__ptr, __ret)
macro to assert things
Definition: n_common.h:276
#define Free(__ptr)
Free Handler to get errors.
Definition: n_common.h:256
int destroy_ht(HASH_TABLE **table)
empty a table and destroy it
Definition: n_hash.c:2448
HASH_TABLE * new_ht(size_t size)
Create a hash table with the given size.
Definition: n_hash.c:2167
int empty_ht(HASH_TABLE *table)
empty a table
Definition: n_hash.c:2435
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:2363
HASH_NODE * ht_get_node(HASH_TABLE *table, const char *key)
get node at 'key' from 'table'
Definition: n_hash.c:2234
structure of a hash table node
Definition: n_hash.h:83
structure of a hash table
Definition: n_hash.h:109
#define list_foreach(__ITEM_, __LIST_)
ForEach macro helper.
Definition: n_list.h:70
#define n_log(__LEVEL__,...)
Logging function wrapper to get line and func.
Definition: n_log.h:74
#define LOG_DEBUG
debug-level messages
Definition: n_log.h:66
#define LOG_ERR
error conditions
Definition: n_log.h:58
void _n_log(int level, const char *file, const char *func, int line, const char *format,...)
Logging function.
Definition: n_log.c:234
int dump_nodup_log(char *file)
Dump the duplicate error log hash table in a file.
Definition: n_nodup_log.c:350
int close_nodup_log()
Empty nodup logtable and close the no duplicate logging session.
Definition: n_nodup_log.c:79
void _n_nodup_log(int LEVEL, const char *file, const char *func, int line, const char *format,...)
Logging function.
Definition: n_nodup_log.c:220
int empty_nodup_table()
Empty the nodup internal table.
Definition: n_nodup_log.c:67
void _n_nodup_log_indexed(int LEVEL, const char *prefix, const char *file, const char *func, int line, const char *format,...)
Logging function.
Definition: n_nodup_log.c:288
int init_nodup_log(int max)
initialize the no duplicate logging system
Definition: n_nodup_log.c:36
#define nstrprintf(__nstr_var,...)
Macro to quickly allocate and sprintf to N_STR *.
Definition: n_str.h:97
#define strprintf(__n_var,...)
Macro to quickly allocate and sprintf to a char *.
Definition: n_str.h:77
A box including a string and his lenght.
Definition: n_str.h:173
Common headers and low-level hugly 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:191
Generic log system.
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
Definition: n_nodup_log.c:180
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:93
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:114
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
Definition: n_nodup_log.c:137
static HASH_TABLE * _n_nodup_table
internal: no dup hash_table log save
Definition: n_nodup_log.c:29
Generic No Dup Log system.
N_STR and string function declaration.