UNPKG

6.05 kBtext/x-cView Raw
1/*
2Copyright (c) 2009-2013 Roger Light <roger@atchoo.org>
3All rights reserved.
4
5Redistribution and use in source and binary forms, with or without
6modification, are permitted provided that the following conditions are met:
7
81. Redistributions of source code must retain the above copyright notice,
9 this list of conditions and the following disclaimer.
102. Redistributions in binary form must reproduce the above copyright
11 notice, this list of conditions and the following disclaimer in the
12 documentation and/or other materials provided with the distribution.
133. Neither the name of mosquitto nor the names of its
14 contributors may be used to endorse or promote products derived from
15 this software without specific prior written permission.
16
17THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
21LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27POSSIBILITY OF SUCH DAMAGE.
28*/
29#include <stdarg.h>
30#include <stdio.h>
31#include <string.h>
32#ifndef WIN32
33#include <syslog.h>
34#endif
35
36#ifndef CMAKE
37#include <config.h>
38#endif
39
40#include <mosquitto_broker.h>
41#include <memory_mosq.h>
42
43extern struct mosquitto_db int_db;
44
45#ifdef WIN32
46HANDLE syslog_h;
47#endif
48
49/* Options for logging should be:
50 *
51 * A combination of:
52 * Via syslog
53 * To a file
54 * To stdout/stderr
55 * To topics
56 */
57
58/* Give option of logging timestamp.
59 * Logging pid.
60 */
61static int log_destinations = MQTT3_LOG_STDERR;
62static int log_priorities = MOSQ_LOG_ERR | MOSQ_LOG_WARNING | MOSQ_LOG_NOTICE | MOSQ_LOG_INFO;
63
64int mqtt3_log_init(int priorities, int destinations)
65{
66 int rc = 0;
67
68 log_priorities = priorities;
69 log_destinations = destinations;
70
71 if(log_destinations & MQTT3_LOG_SYSLOG){
72#ifndef WIN32
73 openlog("mosquitto", LOG_PID, LOG_DAEMON);
74#else
75 syslog_h = OpenEventLog(NULL, "mosquitto");
76#endif
77 }
78
79 return rc;
80}
81
82int mqtt3_log_close(void)
83{
84 if(log_destinations & MQTT3_LOG_SYSLOG){
85#ifndef WIN32
86 closelog();
87#else
88 CloseEventLog(syslog_h);
89#endif
90 }
91 /* FIXME - do something for all destinations! */
92
93 return MOSQ_ERR_SUCCESS;
94}
95
96int _mosquitto_log_printf(struct mosquitto *mosq, int priority, const char *fmt, ...)
97{
98 va_list va;
99 char *s;
100 char *st;
101 int len;
102#ifdef WIN32
103 char *sp;
104#endif
105 const char *topic;
106 int syslog_priority;
107 time_t now = time(NULL);
108
109 if((log_priorities & priority) && log_destinations != MQTT3_LOG_NONE){
110 switch(priority){
111 case MOSQ_LOG_SUBSCRIBE:
112 topic = "$SYS/broker/log/M/subscribe";
113#ifndef WIN32
114 syslog_priority = LOG_NOTICE;
115#else
116 syslog_priority = EVENTLOG_INFORMATION_TYPE;
117#endif
118 break;
119 case MOSQ_LOG_UNSUBSCRIBE:
120 topic = "$SYS/broker/log/M/unsubscribe";
121#ifndef WIN32
122 syslog_priority = LOG_NOTICE;
123#else
124 syslog_priority = EVENTLOG_INFORMATION_TYPE;
125#endif
126 break;
127 case MOSQ_LOG_DEBUG:
128 topic = "$SYS/broker/log/D";
129#ifndef WIN32
130 syslog_priority = LOG_DEBUG;
131#else
132 syslog_priority = EVENTLOG_INFORMATION_TYPE;
133#endif
134 break;
135 case MOSQ_LOG_ERR:
136 topic = "$SYS/broker/log/E";
137#ifndef WIN32
138 syslog_priority = LOG_ERR;
139#else
140 syslog_priority = EVENTLOG_ERROR_TYPE;
141#endif
142 break;
143 case MOSQ_LOG_WARNING:
144 topic = "$SYS/broker/log/W";
145#ifndef WIN32
146 syslog_priority = LOG_WARNING;
147#else
148 syslog_priority = EVENTLOG_WARNING_TYPE;
149#endif
150 break;
151 case MOSQ_LOG_NOTICE:
152 topic = "$SYS/broker/log/N";
153#ifndef WIN32
154 syslog_priority = LOG_NOTICE;
155#else
156 syslog_priority = EVENTLOG_INFORMATION_TYPE;
157#endif
158 break;
159 case MOSQ_LOG_INFO:
160 topic = "$SYS/broker/log/I";
161#ifndef WIN32
162 syslog_priority = LOG_INFO;
163#else
164 syslog_priority = EVENTLOG_INFORMATION_TYPE;
165#endif
166 break;
167 default:
168 topic = "$SYS/broker/log/E";
169#ifndef WIN32
170 syslog_priority = LOG_ERR;
171#else
172 syslog_priority = EVENTLOG_ERROR_TYPE;
173#endif
174 }
175 len = strlen(fmt) + 500;
176 s = _mosquitto_malloc(len*sizeof(char));
177 if(!s) return MOSQ_ERR_NOMEM;
178
179 va_start(va, fmt);
180 vsnprintf(s, len, fmt, va);
181 va_end(va);
182 s[len-1] = '\0'; /* Ensure string is null terminated. */
183
184 if(log_destinations & MQTT3_LOG_STDOUT){
185 if(int_db.config && int_db.config->log_timestamp){
186 fprintf(stdout, "%d: %s\n", (int)now, s);
187 }else{
188 fprintf(stdout, "%s\n", s);
189 }
190 fflush(stdout);
191 }
192 if(log_destinations & MQTT3_LOG_STDERR){
193 if(int_db.config && int_db.config->log_timestamp){
194 fprintf(stderr, "%d: %s\n", (int)now, s);
195 }else{
196 fprintf(stderr, "%s\n", s);
197 }
198 fflush(stderr);
199 }
200 if(log_destinations & MQTT3_LOG_FILE && int_db.config->log_fptr){
201 if(int_db.config && int_db.config->log_timestamp){
202 fprintf(int_db.config->log_fptr, "%d: %s\n", (int)now, s);
203 }else{
204 fprintf(int_db.config->log_fptr, "%s\n", s);
205 }
206 }
207 if(log_destinations & MQTT3_LOG_SYSLOG){
208#ifndef WIN32
209 syslog(syslog_priority, "%s", s);
210#else
211 sp = (char *)s;
212 ReportEvent(syslog_h, syslog_priority, 0, 0, NULL, 1, 0, &sp, NULL);
213#endif
214 }
215 if(log_destinations & MQTT3_LOG_TOPIC && priority != MOSQ_LOG_DEBUG){
216 if(int_db.config && int_db.config->log_timestamp){
217 len += 30;
218 st = _mosquitto_malloc(len*sizeof(char));
219 if(!st){
220 _mosquitto_free(s);
221 return MOSQ_ERR_NOMEM;
222 }
223 snprintf(st, len, "%d: %s", (int)now, s);
224 mqtt3_db_messages_easy_queue(&int_db, NULL, topic, 2, strlen(st), st, 0);
225 _mosquitto_free(st);
226 }else{
227 mqtt3_db_messages_easy_queue(&int_db, NULL, topic, 2, strlen(s), s, 0);
228 }
229 }
230 _mosquitto_free(s);
231 }
232
233 return MOSQ_ERR_SUCCESS;
234}
235