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