truncate messages more to prevent syslog overflow errors
[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
11
12 void osrfLogCleanup() {
13         free(__osrfLogAppname);
14         free(__osrfLogFile);
15 }
16
17
18 void osrfLogInit( int type, const char* appname, int maxlevel ) {
19         osrfLogSetType(type);
20         if(appname) osrfLogSetAppname(appname);
21         osrfLogSetLevel(maxlevel);
22         if( type == OSRF_LOG_TYPE_SYSLOG ) 
23                 openlog(__osrfLogAppname, 0, __osrfLogFacility );
24 }
25
26 void osrfLogSetType( int logtype ) { 
27         if( logtype != OSRF_LOG_TYPE_FILE &&
28                         logtype != OSRF_LOG_TYPE_SYSLOG ) {
29                 fprintf(stderr, "Unrecognized log type.  Logging to stderr\n");
30                 return;
31         }
32         __osrfLogType = logtype; 
33 }
34
35 void osrfLogSetFile( const char* logfile ) {
36         if(!logfile) return;
37         if(__osrfLogFile) free(__osrfLogFile);
38         __osrfLogFile = strdup(logfile);
39 }
40
41 void osrfLogSetActivityEnabled( int enabled ) {
42         __osrfLogActivityEnabled = enabled;
43 }
44
45 void osrfLogSetAppname( const char* appname ) {
46         if(!appname) return;
47         if(__osrfLogAppname) free(__osrfLogAppname);
48         __osrfLogAppname = strdup(appname);
49
50         /* if syslogging, re-open the log with the appname */
51         if( __osrfLogType == OSRF_LOG_TYPE_SYSLOG) {
52                 closelog();
53                 openlog(__osrfLogAppname, 0, __osrfLogFacility);
54         }
55 }
56
57 void osrfLogSetSyslogFacility( int facility ) {
58         __osrfLogFacility = facility;
59 }
60 void osrfLogSetSyslogActFacility( int facility ) {
61         __osrfLogActFacility = facility;
62 }
63
64 void osrfLogSetLevel( int loglevel ) {
65         __osrfLogLevel = loglevel;
66 }
67
68 void osrfLogError( const char* file, int line, const char* msg, ... ) 
69         { OSRF_LOG_GO(file, line, msg, OSRF_LOG_ERROR); }
70 void osrfLogWarning( const char* file, int line, const char* msg, ... ) 
71         { OSRF_LOG_GO(file, line, msg, OSRF_LOG_WARNING); }
72 void osrfLogInfo( const char* file, int line, const char* msg, ... ) 
73         { OSRF_LOG_GO(file, line, msg, OSRF_LOG_INFO); }
74 void osrfLogDebug( const char* file, int line, const char* msg, ... ) 
75         { OSRF_LOG_GO(file, line, msg, OSRF_LOG_DEBUG); }
76 void osrfLogInternal( const char* file, int line, const char* msg, ... ) 
77         { OSRF_LOG_GO(file, line, msg, OSRF_LOG_INTERNAL); }
78 void osrfLogActivity( const char* file, int line, const char* msg, ... ) { 
79         OSRF_LOG_GO(file, line, msg, OSRF_LOG_ACTIVITY); 
80         _osrfLogDetail( OSRF_LOG_INFO, file, line, VA_BUF ); /* also log at info level */
81 }
82
83 void _osrfLogDetail( int level, const char* filename, int line, char* msg ) {
84
85         if( level == OSRF_LOG_ACTIVITY && ! __osrfLogActivityEnabled ) return;
86         if( level > __osrfLogLevel ) return;
87         if(!msg) return;
88         if(!filename) filename = "";
89
90         char* l = "INFO";               /* level name */
91         int lvl = LOG_INFO;     /* syslog level */
92         int fac = __osrfLogFacility;
93
94         switch( level ) {
95                 case OSRF_LOG_ERROR:            
96                         l = "ERR "; 
97                         lvl = LOG_ERR;
98                         break;
99
100                 case OSRF_LOG_WARNING:  
101                         l = "WARN"; 
102                         lvl = LOG_WARNING;
103                         break;
104
105                 case OSRF_LOG_INFO:             
106                         l = "INFO"; 
107                         lvl = LOG_INFO;
108                         break;
109
110                 case OSRF_LOG_DEBUG:    
111                         l = "DEBG"; 
112                         lvl = LOG_DEBUG;
113                         break;
114
115                 case OSRF_LOG_INTERNAL: 
116                         l = "INT "; 
117                         lvl = LOG_DEBUG;
118                         break;
119
120                 case OSRF_LOG_ACTIVITY: 
121                         l = "ACT"; 
122                         lvl = LOG_INFO;
123                         fac = __osrfLogActFacility;
124                         break;
125         }
126
127         if(__osrfLogType == OSRF_LOG_TYPE_SYSLOG ) {
128                 char buf[1536];  
129                 /* give syslog some breathing room, and be cute about it */
130                 strncat(buf, msg, 1535);
131                 buf[1532] = '.';
132                 buf[1533] = '.';
133                 buf[1534] = '.';
134                 buf[1535] = '\0';
135                 syslog( fac | lvl, "[%s:%d:%s:%d] %s", l, getpid(), filename, line, buf );
136         }
137
138         else if( __osrfLogType == OSRF_LOG_TYPE_FILE )
139                 _osrfLogToFile("[%s:%d:%s:%d] %s", l, getpid(), filename, line, msg );
140
141 }
142
143
144 void _osrfLogToFile( char* msg, ... ) {
145
146         if(!msg) return;
147         if(!__osrfLogFile) return;
148         VA_LIST_TO_STRING(msg);
149
150         if(!__osrfLogAppname) __osrfLogAppname = strdup("osrf");
151         int l = strlen(VA_BUF) + strlen(__osrfLogAppname) + 36;
152         char buf[l];
153         bzero(buf,l);
154
155         char datebuf[36];
156         bzero(datebuf,36);
157         time_t t = time(NULL);
158         struct tm* tms = localtime(&t);
159         strftime(datebuf, 36, "%Y-%m-%d %H:%M:%S", tms);
160
161         FILE* file = fopen(__osrfLogFile, "a");
162         if(!file) {
163                 fprintf(stderr, "Unable to fopen file %s for writing", __osrfLogFile);
164                 return;
165         }
166
167         fprintf(file, "%s %s %s\n", __osrfLogAppname, datebuf, VA_BUF );
168         if( fclose(file) != 0 ) 
169                 osrfLogWarning(OSRF_LOG_MARK, "Error closing log file: %s", strerror(errno));
170         
171 }
172
173
174 int osrfLogFacilityToInt( char* facility ) {
175         if(!facility) return LOG_LOCAL0;
176         if(strlen(facility) < 6) return LOG_LOCAL0;
177         switch( facility[5] ) {
178                 case '0': return LOG_LOCAL0;
179                 case '1': return LOG_LOCAL1;
180                 case '2': return LOG_LOCAL2;
181                 case '3': return LOG_LOCAL3;
182                 case '4': return LOG_LOCAL4;
183                 case '5': return LOG_LOCAL5;
184                 case '6': return LOG_LOCAL6;
185                 case '7': return LOG_LOCAL7;
186         }
187         return LOG_LOCAL0;
188 }
189
190