Added osrfLogGetLevel method, then applied
[OpenSRF.git] / src / utils / log.c
1 #include "log.h"
2
3 static int _osrfLogType                         = -1;
4 static int _osrfLogFacility                     = LOG_LOCAL0;
5 static int _osrfLogActFacility          = LOG_LOCAL1;
6 static char* _osrfLogFile                       = NULL;
7 static char* _osrfLogAppname            = NULL;
8 static int _osrfLogLevel                        = OSRF_LOG_INFO;
9 static int _osrfLogActivityEnabled      = 1;
10 static int _osrfLogIsClient         = 0;
11
12 static char* _osrfLogXid            = NULL; /* current xid */
13 static char* _osrfLogXidPfx         = NULL; /* xid prefix string */
14
15 static void osrfLogSetType( int logtype );
16 static void _osrfLogDetail( int level, const char* filename, int line, char* msg );
17 static void _osrfLogToFile( char* msg, ... );
18 static void _osrfLogSetXid(char* xid);
19
20 #define OSRF_LOG_GO(f,li,m,l)   \
21         if(!m) return;          \
22         VA_LIST_TO_STRING(m);   \
23         _osrfLogDetail( l, f, li, VA_BUF );
24
25 void osrfLogCleanup() {
26         free(_osrfLogAppname);
27         free(_osrfLogFile);
28 }
29
30
31 void osrfLogInit( int type, const char* appname, int maxlevel ) {
32         osrfLogSetType(type);
33         if(appname) osrfLogSetAppname(appname);
34         osrfLogSetLevel(maxlevel);
35         if( type == OSRF_LOG_TYPE_SYSLOG ) 
36                 openlog(_osrfLogAppname, 0, _osrfLogFacility );
37 }
38
39 static void _osrfLogSetXid(char* xid) {
40    if(xid) {
41       if(_osrfLogXid) free(_osrfLogXid);
42       _osrfLogXid = strdup(xid);
43    }
44 }
45
46 void osrfLogClearXid() { _osrfLogSetXid(""); }
47 void osrfLogSetXid(char* xid) {
48    if(!_osrfLogIsClient) _osrfLogSetXid(xid);
49 }
50
51 void osrfLogMkXid() {
52    if(_osrfLogIsClient) {
53       static int _osrfLogXidInc = 0; /* increments with each new xid for uniqueness */
54       char buf[32];
55       memset(buf, 0x0, 32);
56       snprintf(buf, 32, "%s%d", _osrfLogXidPfx, _osrfLogXidInc);
57       _osrfLogSetXid(buf);
58       _osrfLogXidInc++;
59    }
60 }
61
62 char* osrfLogGetXid() {
63    return _osrfLogXid;
64 }
65
66 void osrfLogSetIsClient(int is) {
67    _osrfLogIsClient = is;
68    if(!is) return;
69    /* go ahead and create the xid prefix so it will be consistent later */
70    static char buff[32];
71    memset(buff, 0x0, 32);
72    snprintf(buff, 32, "%d%ld", (int)time(NULL), (long) getpid());
73    _osrfLogXidPfx = buff;
74 }
75
76 /** Sets the type of logging to perform.  See log types */
77 static void osrfLogSetType( int logtype ) { 
78         if( logtype != OSRF_LOG_TYPE_FILE &&
79                         logtype != OSRF_LOG_TYPE_SYSLOG ) {
80                 fprintf(stderr, "Unrecognized log type.  Logging to stderr\n");
81                 return;
82         }
83         _osrfLogType = logtype;
84 }
85
86 void osrfLogSetFile( const char* logfile ) {
87         if(!logfile) return;
88         if(_osrfLogFile) free(_osrfLogFile);
89         _osrfLogFile = strdup(logfile);
90 }
91
92 void osrfLogSetActivityEnabled( int enabled ) {
93         _osrfLogActivityEnabled = enabled;
94 }
95
96 void osrfLogSetAppname( const char* appname ) {
97         if(!appname) return;
98         if(_osrfLogAppname) free(_osrfLogAppname);
99         _osrfLogAppname = strdup(appname);
100
101         /* if syslogging, re-open the log with the appname */
102         if( _osrfLogType == OSRF_LOG_TYPE_SYSLOG) {
103                 closelog();
104                 openlog(_osrfLogAppname, 0, _osrfLogFacility);
105         }
106 }
107
108 void osrfLogSetSyslogFacility( int facility ) {
109         _osrfLogFacility = facility;
110 }
111 void osrfLogSetSyslogActFacility( int facility ) {
112         _osrfLogActFacility = facility;
113 }
114
115 /** Sets the global log level.  Any log statements with a higher level
116  * than "level" will not be logged */
117 void osrfLogSetLevel( int loglevel ) {
118         _osrfLogLevel = loglevel;
119 }
120
121 /** Gets the current global log level. **/
122 void osrfLogGetLevel( void ) {
123         return _osrfLogLevel;
124 }
125
126 void osrfLogError( const char* file, int line, const char* msg, ... ) 
127         { OSRF_LOG_GO(file, line, msg, OSRF_LOG_ERROR); }
128 void osrfLogWarning( const char* file, int line, const char* msg, ... ) 
129         { OSRF_LOG_GO(file, line, msg, OSRF_LOG_WARNING); }
130 void osrfLogInfo( const char* file, int line, const char* msg, ... ) 
131         { OSRF_LOG_GO(file, line, msg, OSRF_LOG_INFO); }
132 void osrfLogDebug( const char* file, int line, const char* msg, ... ) 
133         { OSRF_LOG_GO(file, line, msg, OSRF_LOG_DEBUG); }
134 void osrfLogInternal( const char* file, int line, const char* msg, ... ) 
135         { OSRF_LOG_GO(file, line, msg, OSRF_LOG_INTERNAL); }
136 void osrfLogActivity( const char* file, int line, const char* msg, ... ) { 
137         OSRF_LOG_GO(file, line, msg, OSRF_LOG_ACTIVITY); 
138         _osrfLogDetail( OSRF_LOG_INFO, file, line, VA_BUF ); /* also log at info level */
139 }
140
141 /** Actually does the logging */
142 static void _osrfLogDetail( int level, const char* filename, int line, char* msg ) {
143
144         if( level == OSRF_LOG_ACTIVITY && ! _osrfLogActivityEnabled ) return;
145         if( level > _osrfLogLevel ) return;
146         if(!msg) return;
147         if(!filename) filename = "";
148
149         char* l = "INFO";               /* level name */
150         int lvl = LOG_INFO;     /* syslog level */
151         int fac = _osrfLogFacility;
152
153         switch( level ) {
154                 case OSRF_LOG_ERROR:            
155                         l = "ERR "; 
156                         lvl = LOG_ERR;
157                         break;
158
159                 case OSRF_LOG_WARNING:  
160                         l = "WARN"; 
161                         lvl = LOG_WARNING;
162                         break;
163
164                 case OSRF_LOG_INFO:             
165                         l = "INFO"; 
166                         lvl = LOG_INFO;
167                         break;
168
169                 case OSRF_LOG_DEBUG:    
170                         l = "DEBG"; 
171                         lvl = LOG_DEBUG;
172                         break;
173
174                 case OSRF_LOG_INTERNAL: 
175                         l = "INT "; 
176                         lvl = LOG_DEBUG;
177                         break;
178
179                 case OSRF_LOG_ACTIVITY: 
180                         l = "ACT"; 
181                         lvl = LOG_INFO;
182                         fac = _osrfLogActFacility;
183                         break;
184         }
185
186    char* xid = (_osrfLogXid) ? _osrfLogXid : "";
187
188         if(_osrfLogType == OSRF_LOG_TYPE_SYSLOG ) {
189                 char buf[1536];  
190                 memset(buf, 0x0, 1536);
191                 /* give syslog some breathing room, and be cute about it */
192                 strncat(buf, msg, 1535);
193                 buf[1532] = '.';
194                 buf[1533] = '.';
195                 buf[1534] = '.';
196                 buf[1535] = '\0';
197                 syslog( fac | lvl, "[%s:%ld:%s:%d:%s] %s", l, (long) getpid(), filename, line, xid, buf );
198         }
199
200         else if( _osrfLogType == OSRF_LOG_TYPE_FILE )
201                 _osrfLogToFile("[%s:%ld:%s:%d:%s] %s", l, (long) getpid(), filename, line, xid, msg );
202
203 }
204
205
206 static void _osrfLogToFile( char* msg, ... ) {
207
208         if(!msg) return;
209         if(!_osrfLogFile) return;
210         VA_LIST_TO_STRING(msg);
211
212         if(!_osrfLogAppname) _osrfLogAppname = strdup("osrf");
213         int l = strlen(VA_BUF) + strlen(_osrfLogAppname) + 36;
214         char buf[l];
215         bzero(buf,l);
216
217         char datebuf[36];
218         bzero(datebuf,36);
219         time_t t = time(NULL);
220         struct tm* tms = localtime(&t);
221         strftime(datebuf, 36, "%Y-%m-%d %H:%M:%S", tms);
222
223         FILE* file = fopen(_osrfLogFile, "a");
224         if(!file) {
225                 fprintf(stderr, "Unable to fopen file %s for writing\n", _osrfLogFile);
226                 return;
227         }
228
229         fprintf(file, "%s %s %s\n", _osrfLogAppname, datebuf, VA_BUF );
230         if( fclose(file) != 0 ) 
231                 osrfLogWarning(OSRF_LOG_MARK, "Error closing log file: %s", strerror(errno));
232
233 }
234
235
236 int osrfLogFacilityToInt( char* facility ) {
237         if(!facility) return LOG_LOCAL0;
238         if(strlen(facility) < 6) return LOG_LOCAL0;
239         switch( facility[5] ) {
240                 case '0': return LOG_LOCAL0;
241                 case '1': return LOG_LOCAL1;
242                 case '2': return LOG_LOCAL2;
243                 case '3': return LOG_LOCAL3;
244                 case '4': return LOG_LOCAL4;
245                 case '5': return LOG_LOCAL5;
246                 case '6': return LOG_LOCAL6;
247                 case '7': return LOG_LOCAL7;
248         }
249         return LOG_LOCAL0;
250 }
251
252