]> git.evergreen-ils.org Git - OpenSRF.git/blob - src/libopensrf/log.c
92023ae9242d764580e0b6f60d659b2c19e95147
[OpenSRF.git] / src / libopensrf / log.c
1 #include <opensrf/log.h>
2
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;
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( const char* msg, ... );
18 static void _osrfLogSetXid( const 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         _osrfLogAppname = NULL;
28         free(_osrfLogFile);
29         _osrfLogFile = NULL;
30         _osrfLogType = OSRF_LOG_TYPE_STDERR;
31 }
32
33
34 void osrfLogInit( int type, const char* appname, int maxlevel ) {
35         osrfLogSetType(type);
36         if(appname) osrfLogSetAppname(appname);
37         osrfLogSetLevel(maxlevel);
38         if( type == OSRF_LOG_TYPE_SYSLOG ) 
39                 openlog(_osrfLogAppname, 0, _osrfLogFacility );
40 }
41
42 static void _osrfLogSetXid( const char* xid ) {
43    if(xid) {
44       if(_osrfLogXid) free(_osrfLogXid);
45       _osrfLogXid = strdup(xid);
46    }
47 }
48
49 void osrfLogClearXid() { _osrfLogSetXid(""); }
50 void osrfLogSetXid(char* xid) {
51    if(!_osrfLogIsClient) _osrfLogSetXid(xid);
52 }
53
54 void osrfLogMkXid() {
55    if(_osrfLogIsClient) {
56       static int _osrfLogXidInc = 0; /* increments with each new xid for uniqueness */
57       char buf[32];
58       memset(buf, 0x0, 32);
59       snprintf(buf, 32, "%s%d", _osrfLogXidPfx, _osrfLogXidInc);
60       _osrfLogSetXid(buf);
61       _osrfLogXidInc++;
62    }
63 }
64
65 char* osrfLogGetXid() {
66    return _osrfLogXid;
67 }
68
69 void osrfLogSetIsClient(int is) {
70    _osrfLogIsClient = is;
71    if(!is) return;
72    /* go ahead and create the xid prefix so it will be consistent later */
73    static char buff[32];
74    memset(buff, 0x0, 32);
75    snprintf(buff, 32, "%d%ld", (int)time(NULL), (long) getpid());
76    _osrfLogXidPfx = buff;
77 }
78
79 /** Sets the type of logging to perform.  See log types */
80 static void osrfLogSetType( int logtype ) {
81
82         switch( logtype )
83         {
84                 case OSRF_LOG_TYPE_FILE :
85                 case OSRF_LOG_TYPE_SYSLOG :
86                 case OSRF_LOG_TYPE_STDERR :
87                         _osrfLogType = logtype;
88                         break;
89                 default :
90                         fprintf(stderr, "Unrecognized log type.  Logging to stderr\n");
91                         _osrfLogType = OSRF_LOG_TYPE_STDERR;
92                         break;
93         }
94 }
95
96 void osrfLogSetFile( const char* logfile ) {
97         if(!logfile) return;
98         if(_osrfLogFile) free(_osrfLogFile);
99         _osrfLogFile = strdup(logfile);
100 }
101
102 void osrfLogSetActivityEnabled( int enabled ) {
103         _osrfLogActivityEnabled = enabled;
104 }
105
106 void osrfLogSetAppname( const char* appname ) {
107         if(!appname) return;
108         if(_osrfLogAppname) free(_osrfLogAppname);
109         _osrfLogAppname = strdup(appname);
110
111         /* if syslogging, re-open the log with the appname */
112         if( _osrfLogType == OSRF_LOG_TYPE_SYSLOG) {
113                 closelog();
114                 openlog(_osrfLogAppname, 0, _osrfLogFacility);
115         }
116 }
117
118 void osrfLogSetSyslogFacility( int facility ) {
119         _osrfLogFacility = facility;
120 }
121 void osrfLogSetSyslogActFacility( int facility ) {
122         _osrfLogActFacility = facility;
123 }
124
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;
129 }
130
131 /** Gets the current global log level. **/
132 int osrfLogGetLevel( void ) {
133         return _osrfLogLevel;
134 }
135
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 */
149 }
150
151 /** Actually does the logging */
152 static void _osrfLogDetail( int level, const char* filename, int line, char* msg ) {
153
154         if( level == OSRF_LOG_ACTIVITY && ! _osrfLogActivityEnabled ) return;
155         if( level > _osrfLogLevel ) return;
156         if(!msg) return;
157         if(!filename) filename = "";
158
159         char* label = "INFO";           /* level name */
160         int lvl = LOG_INFO;     /* syslog level */
161         int fac = _osrfLogFacility;
162
163         switch( level ) {
164                 case OSRF_LOG_ERROR:            
165                         label = "ERR "; 
166                         lvl = LOG_ERR;
167                         break;
168
169                 case OSRF_LOG_WARNING:  
170                         label = "WARN"; 
171                         lvl = LOG_WARNING;
172                         break;
173
174                 case OSRF_LOG_INFO:             
175                         label = "INFO"; 
176                         lvl = LOG_INFO;
177                         break;
178
179                 case OSRF_LOG_DEBUG:    
180                         label = "DEBG"; 
181                         lvl = LOG_DEBUG;
182                         break;
183
184                 case OSRF_LOG_INTERNAL: 
185                         label = "INT "; 
186                         lvl = LOG_DEBUG;
187                         break;
188
189                 case OSRF_LOG_ACTIVITY: 
190                         label = "ACT"; 
191                         lvl = LOG_INFO;
192                         fac = _osrfLogActFacility;
193                         break;
194         }
195
196    char* xid = (_osrfLogXid) ? _osrfLogXid : "";
197
198         if(_osrfLogType == OSRF_LOG_TYPE_SYSLOG ) {
199                 char buf[1536];  
200                 memset(buf, 0x0, 1536);
201                 /* give syslog some breathing room, and be cute about it */
202                 strncat(buf, msg, 1535);
203                 buf[1532] = '.';
204                 buf[1533] = '.';
205                 buf[1534] = '.';
206                 buf[1535] = '\0';
207                 syslog( fac | lvl, "[%s:%ld:%s:%d:%s] %s", label, (long) getpid(), filename, line, xid, buf );
208         }
209
210         else if( _osrfLogType == OSRF_LOG_TYPE_FILE )
211                 _osrfLogToFile( "[%s:%ld:%s:%d:%s] %s", label, (long) getpid(), filename, line, xid, msg );
212
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 );
215 }
216
217
218 static void _osrfLogToFile( const char* msg, ... ) {
219
220         if(!msg) return;
221         if(!_osrfLogFile) return;
222         VA_LIST_TO_STRING(msg);
223
224         if(!_osrfLogAppname) _osrfLogAppname = strdup("osrf");
225
226         char datebuf[36];
227         time_t t = time(NULL);
228         struct tm* tms = localtime(&t);
229         strftime(datebuf, sizeof( datebuf ), "%Y-%m-%d %H:%M:%S", tms);
230
231         FILE* file = fopen(_osrfLogFile, "a");
232         if(!file) {
233                 fprintf(stderr, "Unable to fopen log file %s for writing\n", _osrfLogFile);
234                 return;
235         }
236
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));
240
241 }
242
243
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;
256         }
257         return LOG_LOCAL0;
258 }
259
260