1
/*___INFO__MARK_BEGIN__*/
2
/*************************************************************************
4
* The Contents of this file are made available subject to the terms of
5
* the Sun Industry Standards Source License Version 1.2
7
* Sun Microsystems Inc., March, 2001
10
* Sun Industry Standards Source License Version 1.2
11
* =================================================
12
* The contents of this file are subject to the Sun Industry Standards
13
* Source License Version 1.2 (the "License"); You may not use this file
14
* except in compliance with the License. You may obtain a copy of the
15
* License at http://gridengine.sunsource.net/Gridengine_SISSL_license.html
17
* Software provided under this License is provided on an "AS IS" basis,
18
* WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
19
* WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
20
* MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
21
* See the License for the specific provisions governing your rights and
22
* obligations concerning the Software.
24
* The Initial Developer of the Original Code is: Sun Microsystems, Inc.
26
* Copyright: 2001 by Sun Microsystems, Inc.
28
* All Rights Reserved.
30
************************************************************************/
31
/*___INFO__MARK_END__*/
39
#include <sys/types.h>
44
#include "sge_dstring.h"
47
#include "sge_uidgid.h"
48
#include "sge_mtutil.h"
49
#include "gdi/sge_gdi_ctx.h"
51
#include "msg_utilib.h"
55
pthread_mutex_t mutex;
58
int log_as_admin_user;
64
char log_buffer[4 * MAX_STRING_SIZE]; /* a.k.a. SGE_EVENT */
68
sge_gdi_ctx_class_t *context;
72
static log_state_t Log_State = {PTHREAD_MUTEX_INITIALIZER, TMP_ERR_FILE_SNBU, LOG_WARNING, 0, 1, 1};
74
static pthread_once_t log_buffer_once = PTHREAD_ONCE_INIT;
75
static pthread_key_t log_buffer_key;
77
static pthread_once_t log_context_once = PTHREAD_ONCE_INIT;
78
static pthread_key_t log_context_key;
80
static void log_buffer_once_init(void);
81
static void log_context_once_init(void);
83
static void log_buffer_destroy(void* theState);
84
static log_buffer_t* log_buffer_getspecific(void);
86
static void log_context_destroy(void* theState);
87
static log_context_t* log_context_getspecific(void);
88
static sge_gdi_ctx_class_t* log_state_get_log_context(void);
91
static void sge_do_log(u_long32 prog_number,
93
const char *unqualified_hostname,
95
const char* aMessage);
97
static sge_gdi_ctx_class_t *log_get_log_context(void);
98
static void log_set_log_context(sge_gdi_ctx_class_t *theCtx);
100
/****** uti/log/log_get_log_buffer() ******************************************
102
* log_get_log_buffer() -- Return a buffer that can be used to build logging
106
* char *log_get_log_buffer(void)
109
* Return a buffer that can be used to build logging strings
114
******************************************************************************/
115
char *log_get_log_buffer(void)
117
log_buffer_t *buf = NULL;
118
char *log_buffer = NULL;
120
buf = log_buffer_getspecific();
123
log_buffer = buf->log_buffer;
129
/****** uti/log/log_get_log_context() ******************************************
131
* log_get_log_context() -- Return a context for the specific thread
134
* sge_gdi_ctx_class_t* log_get_log_context(void)
137
* Return a context for the specific thread
140
* sge_gdi_ctx_class_t*
142
******************************************************************************/
143
static sge_gdi_ctx_class_t* log_get_log_context(void)
145
log_context_t *log_ctx = NULL;
146
sge_gdi_ctx_class_t *context = NULL;
148
log_ctx = log_context_getspecific();
150
if (log_ctx != NULL) {
151
context = log_ctx->context;
157
/****** uti/log/log_set_log_context() ******************************************
159
* log_set_log_context() -- set a context for the specific thread
162
* void log_set_log_context(void *newctx)
165
* Return a context for the specific thread
168
* void newctx - the new ctx
173
* MT-NOTE: log_state_set_log_file() is not MT safe.
175
* MT-NOTE: It is safe, however, to call this function from within multiple
176
* MT-NOTE: threads as long as no other thread calls log_state_set_log_file()
178
******************************************************************************/
179
static void log_set_log_context(sge_gdi_ctx_class_t *newctx)
181
log_context_t *log_ctx = NULL;
183
log_ctx = log_context_getspecific();
185
if (log_ctx != NULL) {
186
log_ctx->context = newctx;
190
/****** uti/log/log_state_get_log_level() ******************************************
192
* log_state_get_log_level() -- Return log level.
195
* u_long32 log_state_get_log_level(void)
203
******************************************************************************/
204
u_long32 log_state_get_log_level(void)
208
sge_mutex_lock("Log_State_Lock", "log_state_get_log_level", __LINE__, &Log_State.mutex);
210
level = Log_State.log_level;
212
sge_mutex_unlock("Log_State_Lock", "log_state_get_log_level", __LINE__, &Log_State.mutex);
217
/****** uti/sge_log/log_state_get_log_file() ***********************************
219
* log_state_get_log_file() -- get log file name
222
* const char* log_state_get_log_file(void)
225
* Return name of current log file. The string returned may or may not
232
* const char* - log file name (with relative or absolute path)
235
* MT-NOTE: log_state_get_log_file() is not MT safe.
237
* MT-NOTE: It is safe, however, to call this function from within multiple
238
* MT-NOTE: threads as long as no other thread does change 'Log_File'.
241
* BUGBUG-AD: This function should use something like a barrier for
242
* BUGBUG-AD: synchronization.
244
*******************************************************************************/
245
const char *log_state_get_log_file(void)
249
sge_mutex_lock("Log_State_Lock", "log_state_get_log_file", __LINE__, &Log_State.mutex);
251
file = Log_State.log_file;
253
sge_mutex_unlock("Log_State_Lock", "log_state_get_log_file", __LINE__, &Log_State.mutex);
258
/****** uti/log/log_state_get_log_verbose() ******************************************
260
* log_state_get_log_verbose() -- Is verbose logging enabled?
263
* int log_state_get_log_verbose(void)
266
* Is verbose logging enabled?
267
* With verbose logging enabled not only ERROR/CRITICAL messages are
268
* printed to stderr but also WARNING/INFO.
274
* uti/log/log_state_set_log_verbose()
275
******************************************************************************/
276
int log_state_get_log_verbose(void)
280
sge_mutex_lock("Log_State_Lock", "log_state_get_log_verbose", __LINE__, &Log_State.mutex);
282
verbose = Log_State.verbose;
284
sge_mutex_unlock("Log_State_Lock", "log_state_get_log_verbose", __LINE__, &Log_State.mutex);
289
/****** uti/log/log_state_get_log_gui() ******************************************
291
* log_state_get_log_gui() -- Is GUI logging enabled?
294
* int log_state_get_log_gui(void)
297
* Is GUI logging enabled?
298
* With GUI logging enabled messages are printed to stderr/stdout.
304
* uti/log/log_state_set_log_gui()
305
******************************************************************************/
306
int log_state_get_log_gui(void)
310
sge_mutex_lock("Log_State_Lock", "log_state_get_log_gui", __LINE__, &Log_State.mutex);
312
gui_log = Log_State.gui_log;
314
sge_mutex_unlock("Log_State_Lock", "log_state_get_log_gui", __LINE__, &Log_State.mutex);
319
/****** uti/log/log_state_get_log_as_admin_user() ******************************************
321
* log_state_get_log_as_admin_user() -- Needs sge_log() to change into admin user?
324
* trace_func_type log_state_get_log_as_admin_user(void)
327
* Returns whether logging shall be done as admin user.
333
* uti/log/log_state_set_log_as_admin_user()
334
******************************************************************************/
335
int log_state_get_log_as_admin_user(void)
337
int log_as_admin_user = 0;
339
sge_mutex_lock("Log_State_Lock", "log_state_get_log_as_admin_user", __LINE__, &Log_State.mutex);
341
log_as_admin_user = Log_State.log_as_admin_user;
343
sge_mutex_unlock("Log_State_Lock", "log_state_get_log_as_admin_user", __LINE__, &Log_State.mutex);
345
return log_as_admin_user;
348
/****** uti/log/log_state_set_log_level() *****************************************
350
* log_state_set_log_level() -- Set log level to be used.
353
* void log_state_set_log_level(int i)
356
* Set log level to be used.
362
* uti/log/log_state_get_log_level()
363
******************************************************************************/
364
void log_state_set_log_level(u_long32 theLevel)
367
sge_mutex_lock("Log_State_Lock", "log_state_set_log_level", __LINE__, &Log_State.mutex);
369
Log_State.log_level = theLevel;
371
sge_mutex_unlock("Log_State_Lock", "log_state_set_log_level", __LINE__, &Log_State.mutex);
376
void log_state_set_log_file(char *theFile)
378
sge_mutex_lock("Log_State_Lock", "log_state_set_log_file", __LINE__, &Log_State.mutex);
380
Log_State.log_file = theFile;
382
sge_mutex_unlock("Log_State_Lock", "log_state_set_log_file", __LINE__, &Log_State.mutex);
387
/****** uti/log/log_state_set_log_verbose() *****************************************
389
* log_state_set_log_verbose() -- Enable/disable verbose logging
392
* void log_state_set_log_verbose(int i)
395
* Enable/disable verbose logging
401
* uti/log/log_state_get_log_verbose()
402
******************************************************************************/
403
void log_state_set_log_verbose(int i)
405
sge_mutex_lock("Log_State_Lock", "log_state_set_log_verbose", __LINE__, &Log_State.mutex);
407
Log_State.verbose = i;
409
sge_mutex_unlock("Log_State_Lock", "log_state_set_log_verbose", __LINE__, &Log_State.mutex);
414
/****** uti/log/log_state_set_log_gui() ********************************************
416
* log_state_set_log_gui() -- Enable/disable logging for GUIs
419
* void log_state_set_log_gui(int i)
422
* Enable/disable logging for GUIs
423
* With GUI logging enabled messages are printed to stderr/stdout.
427
******************************************************************************/
428
void log_state_set_log_gui(int i)
431
sge_mutex_lock("Log_State_Lock", "log_state_set_log_gui", __LINE__, &Log_State.mutex);
433
Log_State.gui_log = i;
435
sge_mutex_unlock("Log_State_Lock", "log_state_set_log_gui", __LINE__, &Log_State.mutex);
440
/****** uti/log/log_state_set_log_as_admin_user() *****************************
442
* log_state_set_log_as_admin_user() -- Enable/Disable logging as admin user
445
* void log_state_set_log_as_admin_user(int i)
448
* This function enables/disables logging as admin user. This
449
* means that the function/macros switches from start user to
450
* admin user before any messages will be written. After that
451
* they will switch back to 'start' user.
457
* uti/uidgid/sge_switch2admin_user
458
* uti/uidgid/sge_switch2start_user
459
******************************************************************************/
460
void log_state_set_log_as_admin_user(int i)
462
sge_mutex_lock("Log_State_Lock", "log_state_set_log_as_admin_user", __LINE__, &Log_State.mutex);
464
Log_State.log_as_admin_user = i;
466
sge_mutex_unlock("Log_State_Lock", "log_state_set_log_as_admin_user", __LINE__, &Log_State.mutex);
470
static sge_gdi_ctx_class_t* log_state_get_log_context(void)
472
sge_gdi_ctx_class_t *log_context = NULL;
474
/* sge_mutex_lock("Log_State_Lock", "log_state_get_log_context", __LINE__, &Log_State.mutex); */
476
log_context = log_get_log_context();
478
/* sge_mutex_unlock("Log_State_Lock", "log_state_get_log_context", __LINE__, &Log_State.mutex); */
483
void log_state_set_log_context(void *theCtx)
485
sge_mutex_lock("Log_State_Lock", "log_state_set_log_context", __LINE__, &Log_State.mutex);
487
log_set_log_context((sge_gdi_ctx_class_t*)theCtx);
489
sge_mutex_unlock("Log_State_Lock", "log_state_set_log_context", __LINE__, &Log_State.mutex);
494
/****** uti/log/sge_log() *****************************************************
496
* sge_log() -- Low level logging function
499
* int sge_log(int log_level, char *mesg, char *file__,
500
* char *func__, int line__)
503
* Low level logging function. Used by various macros.
504
* Do not use this function directly.
507
* int log_level - Logging Level
508
* char *mesg - Message
509
* char *file__ - Filename
510
* char *func__ - Function Name
511
* int line__ - Line within 'file__'
525
* MT-NOTE: sge_log() is not MT safe due to sge_switch2admin_user()
526
* MT-NOTE: sge_log() can be used in clients where no admin user switching
527
* MT-NOTE: takes place
528
* MT-NOTE: sge_log() is not MT safe due rmon_condition()
529
* MT-NOTE: sge_log() can be used if DENTER_MAIN() is called only by one
531
******************************************************************************/
532
int sge_log(int log_level, const char *mesg, const char *file__, const char *func__, int line__)
536
char levelstring[32*4];
538
sge_gdi_ctx_class_t *ctx = NULL;
539
/* TODO: this must be kept for qmaster and should be done in a different
540
way (qmaster context) !!! */
542
const char *threadname = NULL;
543
const char *unqualified_hostname = NULL;
544
int is_daemonized = 0;
546
DENTER(TOP_LAYER, "sge_log");
548
ctx = log_state_get_log_context();
551
me = ctx->get_who(ctx);
552
threadname = ctx->get_thread_name(ctx);
553
unqualified_hostname = ctx->get_unqualified_hostname(ctx);
554
is_daemonized = ctx->is_daemonized(ctx);
556
DPRINTF(("sge_log: ctx is NULL\n"));
559
/* Make sure to have at least a one byte logging string */
560
if (!mesg || mesg[0] == '\0') {
561
sprintf(buf, MSG_LOG_CALLEDLOGGINGSTRING_S,
562
mesg ? MSG_LOG_ZEROLENGTH : MSG_POINTER_NULL);
566
DPRINTF(("%s %d %s\n", file__, line__, mesg));
568
/* quick exit if nothing to log */
569
if (log_level > MAX(log_state_get_log_level(), LOG_WARNING)) {
573
if (!log_state_get_log_gui()) {
579
strcpy(levelstring, MSG_LOG_PROFILING);
583
strcpy(levelstring, MSG_LOG_CRITICALERROR);
587
strcpy(levelstring, MSG_LOG_ERROR);
591
strcpy(levelstring, "");
595
strcpy(levelstring, "");
599
strcpy(levelstring, "");
603
strcpy(levelstring, "");
607
strcpy(levelstring, "");
612
/* avoid double output in debug mode */
613
if (!is_daemonized && !rmon_condition(TOP_LAYER, INFOPRINT) &&
614
(log_state_get_log_verbose() || log_level <= LOG_ERR)) {
615
fprintf(stderr, "%s%s\n", levelstring, mesg);
618
sge_do_log(me, threadname, unqualified_hostname, levelchar, mesg);
623
/****** uti/sge_log/sge_do_log() ***********************************************
625
* sge_do_log() -- Write message to log file
628
* static void sge_do_log(int aLevel, const char *aMessage, const char
634
* int aLevel - log level
635
* const char *aMessage - log message
641
* MT-NOTE: sge_do_log() is MT safe.
643
*******************************************************************************/
644
static void sge_do_log(u_long32 me, const char* progname, const char* unqualified_hostname,
645
int aLevel, const char *aMessage)
649
if (me == QMASTER || me == EXECD || me == SCHEDD || me == SHADOWD) {
650
if ((fd = SGE_OPEN3(log_state_get_log_file(), O_WRONLY | O_APPEND | O_CREAT, 0666)) >= 0) {
651
char msg2log[4*MAX_STRING_SIZE];
654
sge_dstring_init(&msg, msg2log, sizeof(msg2log));
656
append_time((time_t)sge_get_gmt(), &msg, false);
658
sge_dstring_sprintf_append(&msg, "|%6.6s|%s|%c|%s\n",
660
unqualified_hostname,
664
write(fd, msg2log, strlen(msg2log));
672
/****** uti/log/log_buffer_once_init() ********************************************
674
* log_buffer_once_init() -- One-time logging initialization.
677
* static log_buffer_once_init(void)
680
* Create access key for thread local storage. Register cleanup function.
681
* This function must be called exactly once.
690
* MT-NOTE: log_buffer_once_init() is MT safe.
692
*******************************************************************************/
693
static void log_buffer_once_init(void)
695
pthread_key_create(&log_buffer_key, &log_buffer_destroy);
696
} /* log_once_init */
698
/****** uti/log/log_buffer_destroy() ****************************************
700
* log_buffer_destroy() -- Free thread local storage
703
* static void log_buffer_destroy(void* theState)
706
* Free thread local storage.
709
* void* theState - Pointer to memroy which should be freed.
715
* MT-NOTE: log_buffer_destroy() is MT safe.
717
*******************************************************************************/
718
static void log_buffer_destroy(void* theBuffer)
720
sge_free((char*)theBuffer);
723
/****** uti/log/log_buffer_getspecific() ****************************************
725
* log_buffer_getspecific() -- Get thread local log state
728
* static log_buffer_t* log_buffer_getspecific()
731
* Return thread local log state.
733
* If a given thread does call this function for the first time, no thread
734
* local log state is available for this particular thread. In this case the
735
* thread local log state is allocated and set.
738
* static log_buffer_t* - Pointer to thread local log state.
741
* MT-NOTE: log_buffer_getspecific() is MT safe
743
*******************************************************************************/
744
static log_buffer_t* log_buffer_getspecific(void)
746
log_buffer_t *buf = NULL;
749
pthread_once(&log_buffer_once, log_buffer_once_init);
751
if ((buf = pthread_getspecific(log_buffer_key)) != NULL) {
755
buf = (log_buffer_t*)sge_malloc(sizeof(log_buffer_t));
756
memset((void*)(buf), 0, sizeof(log_buffer_t));
758
res = pthread_setspecific(log_buffer_key, (const void*)buf);
761
fprintf(stderr, "pthread_set_specific(%s) failed: %s\n", "log_buffer_getspecific", strerror(res));
766
} /* log_buffer_getspecific() */
769
/****** uti/log/log_context_once_init() ********************************************
771
* log_context_once_init() -- One-time logging initialization.
774
* static log_context_once_init(void)
777
* Create access key for thread local storage. Register cleanup function.
778
* This function must be called exactly once.
787
* MT-NOTE: log_context_once_init() is MT safe.
789
*******************************************************************************/
790
static void log_context_once_init(void)
792
pthread_key_create(&log_context_key, &log_context_destroy);
793
} /* log_once_init */
795
/****** uti/log/log_context_destroy() ****************************************
797
* log_context_destroy() -- Free thread local storage
800
* static void log_context_destroy(void* theState)
803
* Free thread local storage.
806
* void* theState - Pointer to memroy which should be freed.
812
* MT-NOTE: log_context_destroy() is MT safe.
814
*******************************************************************************/
815
static void log_context_destroy(void* theContext)
817
sge_free((char*)theContext);
820
/****** uti/log/log_context_getspecific() ****************************************
822
* log_context_getspecific() -- Get thread local log context
825
* static log_context_t* log_context_getspecific()
828
* Return thread local log context.
830
* If a given thread does call this function for the first time, no thread
831
* local log state is available for this particular thread. In this case the
832
* thread local log state is allocated and set.
835
* static log_context_t* - Pointer to thread local log context.
838
* MT-NOTE: log_context_getspecific() is MT safe
840
*******************************************************************************/
841
static log_context_t* log_context_getspecific(void)
843
log_context_t *myctx = NULL;
846
pthread_once(&log_context_once, log_context_once_init);
848
if ((myctx = pthread_getspecific(log_context_key)) != NULL) {
852
myctx = (log_context_t*)sge_malloc(sizeof(log_context_t));
854
myctx->context = NULL;
856
res = pthread_setspecific(log_context_key, (const void*)myctx);
859
fprintf(stderr, "pthread_set_specific(%s) failed: %s\n", "log_context_getspecific", strerror(res));
864
} /* log_context_getspecific() */