1 #include <opensrf/log.h>
3 static int _osrfLogType = OSRF_LOG_TYPE_STDERR;
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;
12 static char* _osrfLogXid = NULL; /* current xid */
13 static char* _osrfLogXidPfx = NULL; /* xid prefix string */
15 static void osrfLogSetType( int logtype );
16 static void _osrfLogDetail( int level, const char* filename, int line, char* msg );
17 static void _osrfLogToFile( const char* msg, ... );
18 static void _osrfLogSetXid( const char* xid );
20 #define OSRF_LOG_GO(f,li,m,l) \
22 VA_LIST_TO_STRING(m); \
23 _osrfLogDetail( l, f, li, VA_BUF );
25 void osrfLogCleanup() {
26 free(_osrfLogAppname);
27 _osrfLogAppname = NULL;
30 _osrfLogType = OSRF_LOG_TYPE_STDERR;
34 void osrfLogInit( int type, const char* appname, int maxlevel ) {
36 if(appname) osrfLogSetAppname(appname);
37 osrfLogSetLevel(maxlevel);
38 if( type == OSRF_LOG_TYPE_SYSLOG )
39 openlog(_osrfLogAppname, 0, _osrfLogFacility );
42 static void _osrfLogSetXid( const char* xid ) {
44 if(_osrfLogXid) free(_osrfLogXid);
45 _osrfLogXid = strdup(xid);
49 void osrfLogClearXid() { _osrfLogSetXid(""); }
50 void osrfLogSetXid(char* xid) {
51 if(!_osrfLogIsClient) _osrfLogSetXid(xid);
55 if(_osrfLogIsClient) {
56 static int _osrfLogXidInc = 0; /* increments with each new xid for uniqueness */
59 snprintf(buf, 32, "%s%d", _osrfLogXidPfx, _osrfLogXidInc);
65 char* osrfLogGetXid() {
69 void osrfLogSetIsClient(int is) {
70 _osrfLogIsClient = is;
72 /* go ahead and create the xid prefix so it will be consistent later */
74 memset(buff, 0x0, 32);
75 snprintf(buff, 32, "%d%ld", (int)time(NULL), (long) getpid());
76 _osrfLogXidPfx = buff;
79 /** Sets the type of logging to perform. See log types */
80 static void osrfLogSetType( int logtype ) {
84 case OSRF_LOG_TYPE_FILE :
85 case OSRF_LOG_TYPE_SYSLOG :
86 case OSRF_LOG_TYPE_STDERR :
87 _osrfLogType = logtype;
90 fprintf(stderr, "Unrecognized log type. Logging to stderr\n");
91 _osrfLogType = OSRF_LOG_TYPE_STDERR;
96 void osrfLogSetFile( const char* logfile ) {
98 if(_osrfLogFile) free(_osrfLogFile);
99 _osrfLogFile = strdup(logfile);
102 void osrfLogSetActivityEnabled( int enabled ) {
103 _osrfLogActivityEnabled = enabled;
106 void osrfLogSetAppname( const char* appname ) {
108 if(_osrfLogAppname) free(_osrfLogAppname);
109 _osrfLogAppname = strdup(appname);
111 /* if syslogging, re-open the log with the appname */
112 if( _osrfLogType == OSRF_LOG_TYPE_SYSLOG) {
114 openlog(_osrfLogAppname, 0, _osrfLogFacility);
118 void osrfLogSetSyslogFacility( int facility ) {
119 _osrfLogFacility = facility;
121 void osrfLogSetSyslogActFacility( int facility ) {
122 _osrfLogActFacility = facility;
125 /** Sets the global log level. Any log statements with a higher level
126 * than "level" will not be logged */
127 void osrfLogSetLevel( int loglevel ) {
128 _osrfLogLevel = loglevel;
131 /** Gets the current global log level. **/
132 int osrfLogGetLevel( void ) {
133 return _osrfLogLevel;
136 void osrfLogError( const char* file, int line, const char* msg, ... )
137 { OSRF_LOG_GO(file, line, msg, OSRF_LOG_ERROR); }
138 void osrfLogWarning( const char* file, int line, const char* msg, ... )
139 { OSRF_LOG_GO(file, line, msg, OSRF_LOG_WARNING); }
140 void osrfLogInfo( const char* file, int line, const char* msg, ... )
141 { OSRF_LOG_GO(file, line, msg, OSRF_LOG_INFO); }
142 void osrfLogDebug( const char* file, int line, const char* msg, ... )
143 { OSRF_LOG_GO(file, line, msg, OSRF_LOG_DEBUG); }
144 void osrfLogInternal( const char* file, int line, const char* msg, ... )
145 { OSRF_LOG_GO(file, line, msg, OSRF_LOG_INTERNAL); }
146 void osrfLogActivity( const char* file, int line, const char* msg, ... ) {
147 OSRF_LOG_GO(file, line, msg, OSRF_LOG_ACTIVITY);
148 _osrfLogDetail( OSRF_LOG_INFO, file, line, VA_BUF ); /* also log at info level */
151 /** Actually does the logging */
152 static void _osrfLogDetail( int level, const char* filename, int line, char* msg ) {
154 if( level == OSRF_LOG_ACTIVITY && ! _osrfLogActivityEnabled ) return;
155 if( level > _osrfLogLevel ) return;
157 if(!filename) filename = "";
159 char* label = "INFO"; /* level name */
160 int lvl = LOG_INFO; /* syslog level */
161 int fac = _osrfLogFacility;
169 case OSRF_LOG_WARNING:
184 case OSRF_LOG_INTERNAL:
189 case OSRF_LOG_ACTIVITY:
192 fac = _osrfLogActFacility;
196 char* xid = (_osrfLogXid) ? _osrfLogXid : "";
198 if(_osrfLogType == OSRF_LOG_TYPE_SYSLOG ) {
200 memset(buf, 0x0, 1536);
201 /* give syslog some breathing room, and be cute about it */
202 strncat(buf, msg, 1535);
207 syslog( fac | lvl, "[%s:%ld:%s:%d:%s] %s", label, (long) getpid(), filename, line, xid, buf );
210 else if( _osrfLogType == OSRF_LOG_TYPE_FILE )
211 _osrfLogToFile( "[%s:%ld:%s:%d:%s] %s", label, (long) getpid(), filename, line, xid, msg );
213 else if( _osrfLogType == OSRF_LOG_TYPE_STDERR )
214 fprintf( stderr, "[%s:%ld:%s:%d:%s] %s\n", label, (long) getpid(), filename, line, xid, msg );
218 static void _osrfLogToFile( const char* msg, ... ) {
221 if(!_osrfLogFile) return;
222 VA_LIST_TO_STRING(msg);
224 if(!_osrfLogAppname) _osrfLogAppname = strdup("osrf");
227 time_t t = time(NULL);
228 struct tm* tms = localtime(&t);
229 strftime(datebuf, sizeof( datebuf ), "%Y-%m-%d %H:%M:%S", tms);
231 FILE* file = fopen(_osrfLogFile, "a");
233 fprintf(stderr, "Unable to fopen log file %s for writing\n", _osrfLogFile);
237 fprintf(file, "%s %s %s\n", _osrfLogAppname, datebuf, VA_BUF );
238 if( fclose(file) != 0 )
239 fprintf( stderr, "Error closing log file: %s", strerror(errno));
244 int osrfLogFacilityToInt( char* facility ) {
245 if(!facility) return LOG_LOCAL0;
246 if(strlen(facility) < 6) return LOG_LOCAL0;
247 switch( facility[5] ) {
248 case '0': return LOG_LOCAL0;
249 case '1': return LOG_LOCAL1;
250 case '2': return LOG_LOCAL2;
251 case '3': return LOG_LOCAL3;
252 case '4': return LOG_LOCAL4;
253 case '5': return LOG_LOCAL5;
254 case '6': return LOG_LOCAL6;
255 case '7': return LOG_LOCAL7;