11
/*___INFO__MARK_BEGIN__*/
12
/*************************************************************************
14
* The Contents of this file are made available subject to the terms of
15
* the Sun Industry Standards Source License Version 1.2
17
* Sun Microsystems Inc., March, 2001
20
* Sun Industry Standards Source License Version 1.2
21
* =================================================
22
* The contents of this file are subject to the Sun Industry Standards
23
* Source License Version 1.2 (the "License"); You may not use this file
24
* except in compliance with the License. You may obtain a copy of the
25
* License at http://gridengine.sunsource.net/Gridengine_SISSL_license.html
27
* Software provided under this License is provided on an "AS IS" basis,
28
* WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
29
* WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
30
* MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
31
* See the License for the specific provisions governing your rights and
32
* obligations concerning the Software.
34
* The Initial Developer of the Original Code is: Sun Microsystems, Inc.
36
* Copyright: 2001 by Sun Microsystems, Inc.
38
* All Rights Reserved.
40
************************************************************************/
41
/*___INFO__MARK_END__*/
43
static pthread_mutex_t global_cl_log_list_mutex = PTHREAD_MUTEX_INITIALIZER;
44
static cl_raw_list_t* global_cl_log_list = NULL;
47
/* this functions must lock / unlock the raw list manually */
48
static int cl_log_list_add_log(cl_raw_list_t* list_p, const char* thread_name, int line, const char* function_name, const char* module_name, int thread_id, int thread_state,cl_log_t log_type ,const char* message, const char* parameter ); /* CR check */
51
/* this functions are not needed */
52
static cl_log_list_elem_t* cl_log_list_get_next_elem(cl_raw_list_t* list_p, cl_log_list_elem_t* elem);
53
static cl_log_list_elem_t* cl_log_list_get_last_elem(cl_raw_list_t* list_p, cl_log_list_elem_t* elem);
57
#ifdef __CL_FUNCTION__
58
#undef __CL_FUNCTION__
60
#define __CL_FUNCTION__ "cl_log_list_add_log()"
61
static int cl_log_list_add_log(cl_raw_list_t* list_p, const char* thread_name, int line, const char* function_name, const char* module_name, int thread_id, int thread_state, cl_log_t log_type, const char* message , const char* parameter) { /* CR check */
62
cl_log_list_elem_t* new_elem = NULL;
63
int module_length = 0;
64
char* mod_name_start1 = NULL;
65
char* mod_name_start = NULL;
69
if (list_p == NULL || thread_name == NULL || function_name == NULL || module_name == NULL || message == NULL) {
70
return CL_RETVAL_PARAMS;
73
/* create new cl_log_list_elem_t element */
74
new_elem = (cl_log_list_elem_t*) malloc(sizeof(cl_log_list_elem_t));
75
if (new_elem == NULL) {
76
return CL_RETVAL_MALLOC;
79
new_elem->log_parameter = NULL;
81
if (parameter != NULL) {
82
new_elem->log_parameter = strdup(parameter);
83
if (new_elem->log_parameter == NULL) {
85
return CL_RETVAL_MALLOC;
89
new_elem->log_message = strdup(message); /* malloc */
90
if (new_elem->log_message == NULL) {
91
free(new_elem->log_parameter);
93
return CL_RETVAL_MALLOC;
96
new_elem->log_thread_name = strdup(thread_name); /* malloc */
97
if (new_elem->log_thread_name == NULL) {
98
free(new_elem->log_message);
99
free(new_elem->log_parameter);
101
return CL_RETVAL_MALLOC;
104
/* this is b a s e n a m e ( ) */
105
mod_name_start1 = strrchr(module_name,'/');
106
if (mod_name_start1 != NULL) {
107
mod_name_start = mod_name_start1;
110
if (mod_name_start == NULL) {
111
mod_name_start = (char*)module_name;
114
module_length = strlen(function_name) + strlen(mod_name_start) + cl_util_get_int_number_length(line) + 1 + 4;
115
new_elem->log_module_name = (char*) malloc (sizeof(char) * module_length);
116
if (new_elem->log_module_name == NULL) {
117
free(new_elem->log_message);
118
free(new_elem->log_thread_name);
119
free(new_elem->log_parameter);
121
return CL_RETVAL_MALLOC;
123
snprintf(new_elem->log_module_name,module_length, "%s [%s/%d]", function_name, mod_name_start, line );
125
new_elem->log_thread_id = thread_id;
126
new_elem->log_thread_state = thread_state;
127
new_elem->log_type = log_type;
129
/* append elem and set elem pointer in new element */
130
new_elem->raw_elem = cl_raw_list_append_elem(list_p, (void*) new_elem);
132
if ( new_elem->raw_elem == NULL) {
133
free(new_elem->log_message);
134
free(new_elem->log_thread_name);
135
free(new_elem->log_parameter);
136
free(new_elem->log_module_name);
138
return CL_RETVAL_MALLOC;
144
#ifdef __CL_FUNCTION__
145
#undef __CL_FUNCTION__
147
#define __CL_FUNCTION__ "cl_log_list_convert_type_id()"
148
const char* cl_log_list_convert_type_id(cl_log_t id) { /* CR check */
156
return "LOG_WARNING";
166
#ifdef __CL_FUNCTION__
167
#undef __CL_FUNCTION__
169
#define __CL_FUNCTION__ "cl_log_list_set_log_level()"
170
int cl_log_list_set_log_level(cl_raw_list_t* list_p, cl_log_t new_log_level) { /* CR check */
171
cl_log_list_data_t* ldata = NULL;
172
cl_log_t log_level = CL_LOG_OFF;
173
char* env_sge_commlib_debug = NULL;
174
if (list_p == NULL) {
175
return CL_RETVAL_PARAMS;
178
/* check for environment variable SGE_COMMLIB_DEBUG */
179
log_level = new_log_level;
180
env_sge_commlib_debug = getenv("SGE_COMMLIB_DEBUG");
181
if (env_sge_commlib_debug != NULL) {
182
log_level = (cl_log_t) cl_util_get_ulong_value(env_sge_commlib_debug);
185
if (log_level < CL_LOG_OFF || log_level > CL_LOG_DEBUG) {
186
CL_LOG(CL_LOG_ERROR,"undefined log level");
187
return CL_RETVAL_PARAMS;
190
ldata = list_p->list_data;
192
CL_LOG_STR(CL_LOG_INFO,"setting loglevel to", cl_log_list_convert_type_id(log_level));
193
ldata->current_log_level = log_level;
197
return CL_RETVAL_LIST_DATA_IS_NULL;
200
#ifdef __CL_FUNCTION__
201
#undef __CL_FUNCTION__
203
#define __CL_FUNCTION__ "cl_log_list_del_log()"
204
int cl_log_list_del_log(cl_raw_list_t* list_p) { /* CR check */
205
cl_log_list_elem_t* elem = NULL;
207
/* search for element */
208
elem = cl_log_list_get_first_elem(list_p);
210
/* remove elem from list and delete elem */
212
cl_raw_list_remove_elem(list_p,elem->raw_elem);
213
free(elem->log_parameter);
214
free(elem->log_message);
215
free(elem->log_thread_name);
216
free(elem->log_module_name);
220
return CL_RETVAL_THREAD_NOT_FOUND;
224
#ifdef __CL_FUNCTION__
225
#undef __CL_FUNCTION__
227
#define __CL_FUNCTION__ "cl_log_list_get_first_elem()"
228
cl_log_list_elem_t* cl_log_list_get_first_elem(cl_raw_list_t* list_p) { /* CR check */
229
cl_raw_list_elem_t* raw_elem = cl_raw_list_get_first_elem(list_p);
231
return (cl_log_list_elem_t*) raw_elem->data;
237
#ifdef __CL_FUNCTION__
238
#undef __CL_FUNCTION__
240
#define __CL_FUNCTION__ "cl_log_list_get_next_elem()"
241
static cl_log_list_elem_t* cl_log_list_get_next_elem(cl_raw_list_t* list_p, cl_log_list_elem_t* elem) {
242
cl_raw_list_elem_t* next_raw_elem = NULL;
245
cl_raw_list_elem_t* raw_elem = elem->raw_elem;
246
next_raw_elem = cl_raw_list_get_next_elem(raw_elem);
248
return (cl_log_list_elem_t*) next_raw_elem->data;
254
#ifdef __CL_FUNCTION__
255
#undef __CL_FUNCTION__
257
#define __CL_FUNCTION__ "cl_log_list_get_last_elem()"
258
static cl_log_list_elem_t* cl_log_list_get_last_elem(cl_raw_list_t* list_p, cl_log_list_elem_t* elem) {
259
cl_raw_list_elem_t* last_raw_elem = NULL;
262
cl_raw_list_elem_t* raw_elem = elem->raw_elem;
263
last_raw_elem = cl_raw_list_get_last_elem(raw_elem);
265
return (cl_log_list_elem_t*) last_raw_elem->data;
273
/* functions from header file */
279
cl_raw_list_t** list_p -> address to raw list pointer to setup
280
const char* creator_name -> name of the creator thread (e.g. "application")
285
CL_RETVAL_OK - list initalized, to cleanup call cl_log_list_cleanup()
286
CL_RETVAL_XXX - error code
288
CL_RETVAL_XXX integer
290
#ifdef __CL_FUNCTION__
291
#undef __CL_FUNCTION__
293
#define __CL_FUNCTION__ "cl_log_list_setup()"
294
int cl_log_list_setup(cl_raw_list_t** list_p, const char* creator_name, int creator_id, cl_log_list_flush_method_t flush_type, cl_log_func_t flush_func ) {
296
char* env_sge_commlib_debug = NULL;
298
cl_log_list_data_t* ldata = NULL;
299
cl_thread_settings_t* creator_settings = NULL;
301
if (list_p == NULL || creator_name == NULL) {
302
/* parameter error */
303
return CL_RETVAL_PARAMS;
306
if (*list_p != NULL) {
307
/* the list is already initialized */
308
return CL_RETVAL_PARAMS;
311
/* malloc creator and list data structures */
312
creator_settings = (cl_thread_settings_t*)malloc(sizeof(cl_thread_settings_t));
313
if (creator_settings == NULL) {
314
return CL_RETVAL_MALLOC;
317
ldata = (cl_log_list_data_t*) malloc(sizeof(cl_log_list_data_t));
319
free(creator_settings);
320
return CL_RETVAL_MALLOC;
322
ldata->list_creator_settings = NULL; /* init the list data to NULL */
324
/* all CL_LOG() macro function calls in startup phase of the log list
325
are lost, because the list is not completey set up !!! */
327
/* create a raw list */
328
ret_val = cl_raw_list_setup(list_p,"log list", 1);/* enable list locking */
329
if (ret_val != CL_RETVAL_OK) {
330
free(creator_settings);
335
/* set list_data pointer to NULL to disable logging */
336
(*list_p)->list_data = NULL; /* do not log in setup phase */
337
(*list_p)->list_type = CL_LOG_LIST;
340
/* setup creator thread information */
341
if ( (ret_val=cl_thread_setup(creator_settings,*list_p,creator_name,creator_id , NULL, NULL, NULL)) != CL_RETVAL_OK) {
342
cl_thread_cleanup(creator_settings);
343
free(creator_settings);
345
cl_log_list_cleanup(list_p);
349
/* initialization done, now set list_data to enable logging */
350
(*list_p)->list_data = ldata;
351
ldata->list_creator_settings = creator_settings;
352
ldata->current_log_level = CL_LOG_WARNING; /* initial loglevel is CL_LOG_WARNING */
353
ldata->flush_type = flush_type;
354
if (flush_func != NULL) {
355
ldata->flush_function = *flush_func;
357
ldata->flush_function = cl_log_list_flush_list;
360
/* check for environment variable SGE_COMMLIB_DEBUG */
361
env_sge_commlib_debug=getenv("SGE_COMMLIB_DEBUG");
362
if ( env_sge_commlib_debug != NULL) {
363
ldata->current_log_level = (cl_log_t) cl_util_get_ulong_value(env_sge_commlib_debug);
366
CL_LOG(CL_LOG_INFO,"cl_log_list_setup() complete");
368
switch(ldata->flush_type) {
370
CL_LOG(CL_LOG_INFO,"log entries are flushed by application");
372
case CL_LOG_IMMEDIATE:
373
CL_LOG(CL_LOG_INFO,"log entires are flushed immediate");
377
pthread_mutex_lock(&global_cl_log_list_mutex);
378
global_cl_log_list = *list_p;
379
pthread_mutex_unlock(&global_cl_log_list_mutex);
385
#ifdef __CL_FUNCTION__
386
#undef __CL_FUNCTION__
388
#define __CL_FUNCTION__ "cl_log_list_cleanup()"
389
int cl_log_list_cleanup(cl_raw_list_t** list_p ) { /* CR check */
392
cl_log_list_data_t* ldata = NULL;
393
cl_thread_settings_t* creator_settings = NULL;
395
if (list_p == NULL) {
396
return CL_RETVAL_PARAMS;
398
if (*list_p == NULL) {
399
return CL_RETVAL_PARAMS;
402
pthread_mutex_lock(&global_cl_log_list_mutex);
403
global_cl_log_list = NULL;
404
pthread_mutex_unlock(&global_cl_log_list_mutex);
406
/* set ldata and creator_settings */
407
ldata = (cl_log_list_data_t*) (*list_p)->list_data;
409
creator_settings = ldata->list_creator_settings;
412
/* cleanup creator thread */
413
ret_val = cl_thread_cleanup(creator_settings);
415
/* flush all list content to get list empty*/
416
cl_log_list_flush_list(*list_p );
420
(*list_p)->list_data = NULL;
422
/* free creator_settings */
423
free(creator_settings);
425
ret_val2 = cl_raw_list_cleanup(list_p);
427
if (ret_val != CL_RETVAL_OK) {
435
#ifdef __CL_FUNCTION__
436
#undef __CL_FUNCTION__
438
#define __CL_FUNCTION__ "cl_log_list_get_creator_thread()"
439
cl_thread_settings_t* cl_log_list_get_creator_thread(cl_thread_settings_t* thread_config) { /* CR check */
440
cl_raw_list_t* log_list = NULL;
441
cl_thread_settings_t* creator_thread = NULL;
442
cl_log_list_data_t* ldata = NULL;
444
if (thread_config == NULL) {
448
log_list = thread_config->thread_log_list;
449
if (log_list != NULL) {
450
ldata = log_list->list_data;
452
creator_thread = ldata->list_creator_settings;
455
return creator_thread;
459
#ifdef __CL_FUNCTION__
460
#undef __CL_FUNCTION__
462
#define __CL_FUNCTION__ "cl_log_list_log()"
463
int cl_log_list_log(cl_log_t log_type,int line, const char* function_name,const char* module_name, const char* log_text, const char* log_param) {
467
cl_thread_settings_t* thread_config = NULL;
468
cl_log_list_data_t* ldata = NULL;
470
if (log_text == NULL || module_name == NULL || function_name == NULL) {
471
return CL_RETVAL_PARAMS;
474
/* get the thread configuration for the calling thread */
475
thread_config = cl_thread_get_thread_config();
478
/* This is to get all debug messages at startup of log list, only enable this
479
for debugging the log list code */
480
if (thread_config == NULL) {
481
printf("cl_log_list_log(): cl_thread_get_thread_config() returns NULL\n");
482
if (log_text && module_name && log_param) { printf("%s:%s %s\n",function_name , log_text, log_param);}
487
if (thread_config != NULL) {
488
if (thread_config->thread_log_list == NULL) {
489
return CL_RETVAL_LOG_NO_LOGLIST;
493
/* check current log level */
494
ldata = thread_config->thread_log_list->list_data;
496
if (ldata->current_log_level < log_type || ldata->current_log_level == CL_LOG_OFF) {
497
return CL_RETVAL_OK; /* message log doesn't match current log level or is switched off */
500
return CL_RETVAL_OK; /* never try logging without list data ( this happens on setting up the log list ) */
503
if ( ( ret_val = cl_raw_list_lock(thread_config->thread_log_list)) != CL_RETVAL_OK) {
507
ret_val2 = cl_log_list_add_log( thread_config->thread_log_list,
508
thread_config->thread_name,
512
thread_config->thread_id,
513
thread_config->thread_state,
518
if ( ( ret_val = cl_raw_list_unlock(thread_config->thread_log_list)) != CL_RETVAL_OK) {
522
if(ldata->flush_type == CL_LOG_IMMEDIATE) {
529
* This happens to threads of application which have not started
530
* commlib setup function. A thread config should be provided for these
531
* threads, or the application should use commlib threads ( lists/thread module )
533
pthread_mutex_lock(&global_cl_log_list_mutex);
534
/* This must be an application thread */
535
if ( global_cl_log_list != NULL) {
536
ldata = global_cl_log_list->list_data;
538
if (ldata->current_log_level < log_type || ldata->current_log_level == CL_LOG_OFF) {
539
pthread_mutex_unlock(&global_cl_log_list_mutex);
540
return CL_RETVAL_OK; /* message log doesn't match current log level or is switched off */
543
pthread_mutex_unlock(&global_cl_log_list_mutex);
544
return CL_RETVAL_OK; /* never try logging without list data ( this happens on setting up the log list ) */
546
if ( ( ret_val = cl_raw_list_lock(global_cl_log_list)) != CL_RETVAL_OK) {
547
pthread_mutex_unlock(&global_cl_log_list_mutex);
551
ret_val2 = cl_log_list_add_log( global_cl_log_list,
562
if ( ( ret_val = cl_raw_list_unlock(global_cl_log_list)) != CL_RETVAL_OK) {
563
pthread_mutex_unlock(&global_cl_log_list_mutex);
567
if(ldata->flush_type == CL_LOG_IMMEDIATE) {
571
pthread_mutex_unlock(&global_cl_log_list_mutex);
574
pthread_mutex_unlock(&global_cl_log_list_mutex);
575
return CL_RETVAL_LOG_NO_LOGLIST;
579
#ifdef __CL_FUNCTION__
580
#undef __CL_FUNCTION__
582
#define __CL_FUNCTION__ "cl_log_list_log_ssi()"
583
int cl_log_list_log_ssi(cl_log_t log_type,int line, const char* function_name,const char* module_name, const char* log_text,
584
const char* log_1 , const char* log_2 ,int log_3 ) {
587
cl_thread_settings_t* thread_config = NULL;
588
cl_log_list_data_t* ldata = NULL;
589
const char* help_null = "NULL";
590
const char* log_param1 = NULL;
591
const char* log_param2 = NULL;
593
/* get the thread configuration for the calling thread */
594
thread_config = cl_thread_get_thread_config();
595
if (thread_config != NULL) {
596
if (thread_config->thread_log_list == NULL) {
597
return CL_RETVAL_LOG_NO_LOGLIST;
599
ldata = thread_config->thread_log_list->list_data;
602
* This happens to threads of application which have not started
603
* commlib setup function. A thread config should be provided for these
604
* threads, or the application should use commlib threads ( lists/thread module )
606
pthread_mutex_lock(&global_cl_log_list_mutex);
607
if ( global_cl_log_list != NULL) {
608
ldata = global_cl_log_list->list_data;
610
pthread_mutex_unlock(&global_cl_log_list_mutex);
614
if (ldata->current_log_level < log_type || ldata->current_log_level == CL_LOG_OFF) {
615
return CL_RETVAL_OK; /* message log doesn't match current log level or is switched off */
618
return CL_RETVAL_OK; /* never try logging without list data ( this happens on setting up the log list ) */
621
log_param1 = help_null;
627
log_param2 = help_null;
631
snprintf(my_buffer, 512, "\"%s/%s/%d\"", log_param1, log_param2, log_3);
632
ret_val = cl_log_list_log( log_type, line, function_name, module_name, log_text, my_buffer);
637
#ifdef __CL_FUNCTION__
638
#undef __CL_FUNCTION__
640
#define __CL_FUNCTION__ "cl_log_list_log_int()"
641
int cl_log_list_log_int(cl_log_t log_type,int line, const char* function_name,const char* module_name, const char* log_text, int param) {
643
char my_int_buffer[512];
644
cl_thread_settings_t* thread_config = NULL;
645
cl_log_list_data_t* ldata = NULL;
647
/* get the thread configuration for the calling thread */
648
thread_config = cl_thread_get_thread_config();
649
if (thread_config != NULL) {
650
if (thread_config->thread_log_list == NULL) {
651
return CL_RETVAL_LOG_NO_LOGLIST;
653
ldata = thread_config->thread_log_list->list_data;
656
* This happens to threads of application which have not started
657
* commlib setup function. A thread config should be provided for these
658
* threads, or the application should use commlib threads ( lists/thread module )
660
pthread_mutex_lock(&global_cl_log_list_mutex);
661
if ( global_cl_log_list != NULL) {
662
ldata = global_cl_log_list->list_data;
664
pthread_mutex_unlock(&global_cl_log_list_mutex);
668
if (ldata->current_log_level < log_type || ldata->current_log_level == CL_LOG_OFF) {
669
return CL_RETVAL_OK; /* message log doesn't match current log level or is switched off */
672
return CL_RETVAL_OK; /* never try logging without list data ( this happens on setting up the log list ) */
675
snprintf(my_int_buffer, 512, "%d", param);
676
ret_val = cl_log_list_log( log_type, line, function_name, module_name, log_text, my_int_buffer);
681
#ifdef __CL_FUNCTION__
682
#undef __CL_FUNCTION__
684
#define __CL_FUNCTION__ "cl_log_list_flush()"
685
int cl_log_list_flush(void) { /* CR check */
686
cl_raw_list_t* list_p = NULL;
687
cl_thread_settings_t* thread_config = NULL;
688
cl_log_list_data_t* ldata = NULL;
690
/* get the thread configuration for the calling thread */
691
thread_config = cl_thread_get_thread_config();
692
if (thread_config == NULL) {
693
/* This thread has had no setup by commlib, it must be an
696
list_p = global_cl_log_list;
698
/* This is a commlib internal thread use thread config */
699
list_p = thread_config->thread_log_list;
702
if (list_p == NULL) {
703
return CL_RETVAL_LOG_NO_LOGLIST;
706
/* here we have a log list pointer, check if
707
* there is a log function definition */
708
if (list_p->list_data != NULL) {
709
ldata = (cl_log_list_data_t*)list_p->list_data;
710
if (ldata->flush_function != NULL) {
711
return ldata->flush_function(list_p);
714
return cl_log_list_flush_list(list_p);
719
#ifdef __CL_FUNCTION__
720
#undef __CL_FUNCTION__
722
#define __CL_FUNCTION__ "cl_log_list_flush_list()"
723
int cl_log_list_flush_list(cl_raw_list_t* list_p) { /* CR check */
725
cl_log_list_elem_t* elem = NULL;
729
if (list_p == NULL) {
730
return CL_RETVAL_LOG_NO_LOGLIST;
733
if ( ( ret_val = cl_raw_list_lock(list_p)) != CL_RETVAL_OK) {
737
while ( (elem = cl_log_list_get_first_elem(list_p) ) != NULL) {
738
/* TODO: rework logging output (log to file? call foreign log function, got by function pointer ?) */
740
gettimeofday(&now,NULL);
742
printf("%-76s|", elem->log_module_name);
743
if (elem->log_parameter == NULL) {
744
#define CL_COM_PRINT_THREAD_ID 0
746
#if CL_COM_PRINT_THREAD_ID
747
printf("%ld.%ld|%20s|%4d|%10s|%8s| %s\n",
749
printf("%ld.%ld|%20s|%10s|%8s| %s\n",
754
elem->log_thread_name,
755
#if CL_COM_PRINT_THREAD_ID
758
cl_thread_convert_state_id(elem->log_thread_state),
759
cl_log_list_convert_type_id(elem->log_type),
762
#if CL_COM_PRINT_THREAD_ID
763
printf("%ld.%ld|%20s|%4d|%10s|%8s| %s %s\n",
765
printf("%ld.%ld|%20s|%10s|%8s| %s %s\n",
770
elem->log_thread_name,
771
#if CL_COM_PRINT_THREAD_ID
774
cl_thread_convert_state_id(elem->log_thread_state),
775
cl_log_list_convert_type_id(elem->log_type),
777
elem->log_parameter);
779
cl_log_list_del_log(list_p);
783
if ( ( ret_val = cl_raw_list_unlock(list_p)) != CL_RETVAL_OK) {