source: trunk/drmaa_utils/drmaa_utils/logging.c @ 1

Revision 1, 5.0 KB checked in by mmamonski, 13 years ago (diff)

Torque/PBS DRMAA initial commit

Line 
1/* $Id: logging.c 2 2009-10-12 09:51:22Z mamonski $ */
2/*
3 *  FedStage DRMAA utilities library
4 *  Copyright (C) 2006-2008  FedStage Systems
5 *
6 *  This program is free software: you can redistribute it and/or modify
7 *  it under the terms of the GNU General Public License as published by
8 *  the Free Software Foundation, either version 3 of the License, or
9 *  (at your option) any later version.
10 *
11 *  This program is distributed in the hope that it will be useful,
12 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 *  GNU General Public License for more details.
15 *
16 *  You should have received a copy of the GNU General Public License
17 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
18 */
19
20#ifdef HAVE_CONFIG_H
21#       include <config.h>
22#endif
23
24#include <sys/time.h>
25
26#include <stdio.h>
27#include <stdlib.h>
28#include <stdarg.h>
29#include <string.h>
30#include <unistd.h>
31#ifdef HAVE_EXECINFO_H
32#       include <execinfo.h>
33#endif
34
35#include <drmaa_utils/common.h>
36#include <drmaa_utils/logging.h>
37#include <drmaa_utils/lookup3.h>
38#include <drmaa_utils/thread.h>
39
40#ifndef lint
41static char rcsid[]
42#       ifdef __GNUC__
43                __attribute__ ((unused))
44#       endif
45        = "$Id: logging.c 2 2009-10-12 09:51:22Z mamonski $";
46#endif
47
48
49static int fsd_logging_output = 2;
50
51fsd_verbose_level_t fsd_verbose_level =
52#ifdef DEBUGGING
53        FSD_LOG_TRACE
54#else
55        FSD_LOG_WARNING
56#endif
57;
58
59static struct timeval fsd_logging_start = {0, 0};
60
61
62void
63fsd_set_verbosity_level( fsd_verbose_level_t level )
64{
65        fsd_verbose_level = level;
66}
67
68void
69fsd_set_logging_fd( int fd )
70{
71        fsd_logging_output = fd;
72}
73
74
75void
76fsd_color( char *output, size_t len, int n )
77{
78        uint32_t k = n;
79        k = hashword( &k, 1, 0 );
80        k %= 12;
81        snprintf( output, len, "\033[0;%d;%dm", k>=6, 31+k%6 );
82}
83
84
85char
86fsd_log_level_char( int level )
87{
88        switch( level )
89         {
90                case FSD_LOG_TRACE:    return 't';
91                case FSD_LOG_DEBUG:    return 'd';
92                case FSD_LOG_INFO:     return 'I';
93                case FSD_LOG_WARNING:  return 'W';
94                case FSD_LOG_ERROR:    return 'E';
95                case FSD_LOG_FATAL:    return 'F';
96                default:               return '?';
97         }
98}
99
100
101void
102_fsd_log( int level, const char *file, const char *function,
103                int kind, char *message )
104{
105        const bool color = false;
106        char colorbeg[16];
107        const char *colorend;
108        int tid;
109        long int seconds, microseconds;
110        const char *prefix;
111        const char *p;
112
113        if( level < (int)fsd_verbose_level )
114                return;
115
116        if( message == NULL )
117                return;
118
119        tid = fsd_thread_id();
120        if( color )
121         {
122                fsd_color( colorbeg, sizeof(colorbeg), tid );
123                colorend = "\033[0m";
124         }
125        else
126         {
127                colorbeg[0] = '\0';
128                colorend = "";
129         }
130
131         {
132                struct timeval tv;
133                gettimeofday( &tv, NULL );
134                seconds = tv.tv_sec;
135                microseconds = tv.tv_usec;
136         }
137        if( fsd_logging_start.tv_sec == 0 )
138         {
139                time_t t;
140                struct tm utc;
141                char rep[32];
142                fsd_logging_start.tv_sec = seconds;
143                fsd_logging_start.tv_usec = microseconds;
144                t = seconds;
145                gmtime_r( &t, &utc );
146                strftime( rep, sizeof(rep), "%Y-%m-%d %H:%M:%S", &utc );
147                fsd_log_debug(( "logging started at: %s.%02ld Z",
148                                        rep, microseconds/10000 ));
149         }
150        if( microseconds < fsd_logging_start.tv_usec )
151         {
152                seconds --;
153                microseconds += 1000000;
154         }
155        seconds -= fsd_logging_start.tv_sec;
156        microseconds -= fsd_logging_start.tv_usec;
157
158        switch( kind )
159         {
160                case _FSD_LOG_ENTER:   prefix = "->";  break;
161                case _FSD_LOG_RETURN:  prefix = "<-";  break;
162                default:
163                        prefix = " *";
164                        function = "";
165                        break;
166         }
167
168        p = message;
169        do {
170                if( *p == '\n' )
171                 {
172                        prefix = " |";
173                        function = "";
174                        p++;
175                 }
176                else
177                 {
178                        const char *end;
179                        char *line = NULL;
180                        int rc;
181                        end = strchr( p, '\n' );
182                        if( end == NULL )
183                                end = p + strlen(p);
184                        rc = asprintf( &line, "%c #%s%04x%s [%6ld.%02ld] %s %s%.*s\n",
185                                        fsd_log_level_char(level), colorbeg, tid, colorend,
186                                        seconds, microseconds/10000, prefix, function, (int)(end-p), p
187                                        );
188                        if( rc != -1 )
189                                write( fsd_logging_output, line, strlen(line) );
190                        else
191                                return;
192                        free( line );
193                        p = end;
194                 }
195        } while( *p != '\0' );
196
197        free( message );
198}
199
200
201void
202fsd_log_fmt( int level, const char *fmt, ... )
203{
204        va_list args;
205        va_start( args, fmt );
206        fsd_log_fmtv( level, fmt, args );
207        va_end( args );
208}
209
210
211void
212fsd_log_fmtv( int level, const char *fmt, va_list args )
213{
214        _fsd_log( level, NULL, NULL, _FSD_LOG_MSG, fsd_vasprintf(fmt, args) );
215}
216
217
218#if defined(__GNUC__) && defined(HAVE_EXECINFO_H)
219#define MAX_STACKTRACE 128
220void
221fsd_log_stacktrace( int skip, int limit )
222{
223        void **ptr_buf = NULL;
224        const char **symbols = NULL;
225        int i, n;
226
227        if( limit == 0 )
228                limit = 128;
229        skip++; /* without fsd_log_stacktrace() frame */
230        n = skip + limit;
231
232        ptr_buf = (void**)calloc( n, sizeof(void*) );
233        if( ptr_buf == NULL )
234                return;
235        n = backtrace( ptr_buf, n );
236        symbols = (const char**)backtrace_symbols( ptr_buf, n );
237        if( symbols != NULL )
238         {
239                fsd_log_debug(( "Stacktrace (most recent call last):" ));
240                for( i = n-skip;  i >= 0;  i-- )
241                        fsd_log_debug(( "\n  %s", symbols[i] ));
242                free( symbols );
243         }
244}
245#else
246void fsd_log_stacktrace( int skip, int limit ) {}
247#endif
248
249
250
Note: See TracBrowser for help on using the repository browser.