Merge lp:~ev/whoopsie/be-more-verbose into lp:whoopsie
- be-more-verbose
- Merge into trunk
Status: | Merged |
---|---|
Merged at revision: | 562 |
Proposed branch: | lp:~ev/whoopsie/be-more-verbose |
Merge into: | lp:whoopsie |
Diff against target: |
911 lines (+378/-57) 20 files modified
.bzrignore (+1/-0) Makefile (+1/-0) debian/copyright (+2/-2) src/connectivity.c (+1/-1) src/connectivity.h (+1/-1) src/globals.h (+25/-0) src/logging.c (+59/-0) src/logging.h (+27/-0) src/monitor.c (+1/-1) src/monitor.h (+1/-1) src/tests/Makefile (+14/-2) src/tests/test_identifier.c (+4/-1) src/tests/test_logging.c (+177/-0) src/tests/test_monitor.c (+4/-1) src/tests/test_parse_report.c (+4/-1) src/tests/test_utils.c (+4/-1) src/utils.c (+1/-1) src/utils.h (+1/-1) src/whoopsie.c (+49/-42) src/whoopsie.h (+1/-1) |
To merge this branch: | bzr merge lp:~ev/whoopsie/be-more-verbose |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
James Hunt (community) | Approve | ||
Daisy Pluckers | Pending | ||
Review via email: mp+178788@code.launchpad.net |
Commit message
Description of the change
This branch finally adds a log file (/var/log/
James Hunt (jamesodhunt) wrote : | # |
On 7 August 2013 09:59, James Hunt <email address hidden> wrote:
> Finally, what's the reason for not using syslog(3) out of interest?
A very fair point, and one I had not considered. I'll update the MP to
use that instead. Thanks for the review!
- 567. By Evan
-
Use syslog instead of /var/log/
whoopsie/ whoopsie. log. - 568. By Evan
-
Test logging (stdout) when running in the foreground.
- 569. By Evan
-
Move logging startup further forward to close the gaps. Include the PID in syslog logging.
- 570. By Evan
-
No longer needed.
- 571. By Evan
-
Also no longer needed.
- 572. By Evan
-
Test logging to syslog (in stderr mode) as well.
- 573. By Evan
-
Fix resetting stdout and stderr in the logging tests.
Okay, I believe this is ready for review again.
I've moved to using syslog for the backend logging and have expanded the unit tests to cover both foreground logging (stdout) and syslog logging (stderr via the LOG_PERROR option).
James Hunt (jamesodhunt) wrote : | # |
LGTM. Only comment is that in some places your calls to log_msg() have multiple NLs specified which will look odd when logged to syslog. For example:
if (response > 200)
log_msg ("Server replied with:\n%s\n", s.p);
This will result in all except the last '\n's displaying in syslog as "#012" which probably isn't what you want. I guess the easiest solution is to just make 2 calls to log_msg() in those scenarios.
Preview Diff
1 | === modified file '.bzrignore' |
2 | --- .bzrignore 2012-05-27 19:39:06 +0000 |
3 | +++ .bzrignore 2013-08-08 08:46:01 +0000 |
4 | @@ -12,3 +12,4 @@ |
5 | src/tests/test_utils |
6 | src/tests/test_monitor |
7 | src/tests/test_identifier |
8 | +src/tests/test_logging |
9 | |
10 | === modified file 'Makefile' |
11 | --- Makefile 2013-02-26 10:36:50 +0000 |
12 | +++ Makefile 2013-08-08 08:46:01 +0000 |
13 | @@ -18,6 +18,7 @@ |
14 | src/utils.c \ |
15 | src/connectivity.c \ |
16 | src/monitor.c \ |
17 | + src/logging.c \ |
18 | lib/bson/bson.c \ |
19 | lib/bson/encoding.c \ |
20 | lib/bson/numbers.c |
21 | |
22 | === modified file 'debian/copyright' |
23 | --- debian/copyright 2012-06-18 08:32:13 +0000 |
24 | +++ debian/copyright 2013-08-08 08:46:01 +0000 |
25 | @@ -3,8 +3,8 @@ |
26 | Source: http://code.launchpad.net/whoopsie |
27 | |
28 | Files: src/* |
29 | -Copyright: 2011-2012 Canonical Ltd. |
30 | - 2011-2012 Evan Dandrea <ev@ubuntu.com> |
31 | +Copyright: 2011-2013 Canonical Ltd. |
32 | + 2011-2013 Evan Dandrea <ev@ubuntu.com> |
33 | License: GPL-3 |
34 | This package is free software; you can redistribute it and/or modify |
35 | it under the terms of the GNU General Public License as published by |
36 | |
37 | === modified file 'src/connectivity.c' |
38 | --- src/connectivity.c 2013-02-26 10:50:53 +0000 |
39 | +++ src/connectivity.c 2013-08-08 08:46:01 +0000 |
40 | @@ -1,6 +1,6 @@ |
41 | /* whoopsie |
42 | * |
43 | - * Copyright © 2011-2012 Canonical Ltd. |
44 | + * Copyright © 2011-2013 Canonical Ltd. |
45 | * Author: Evan Dandrea <evan.dandrea@canonical.com> |
46 | * |
47 | * This program is free software: you can redistribute it and/or modify |
48 | |
49 | === modified file 'src/connectivity.h' |
50 | --- src/connectivity.h 2013-01-28 15:38:09 +0000 |
51 | +++ src/connectivity.h 2013-08-08 08:46:01 +0000 |
52 | @@ -1,6 +1,6 @@ |
53 | /* whoopsie |
54 | * |
55 | - * Copyright © 2011-2012 Canonical Ltd. |
56 | + * Copyright © 2011-2013 Canonical Ltd. |
57 | * Author: Evan Dandrea <evan.dandrea@canonical.com> |
58 | * |
59 | * This program is free software: you can redistribute it and/or modify |
60 | |
61 | === added file 'src/globals.h' |
62 | --- src/globals.h 1970-01-01 00:00:00 +0000 |
63 | +++ src/globals.h 2013-08-08 08:46:01 +0000 |
64 | @@ -0,0 +1,25 @@ |
65 | +/* whoopsie |
66 | + * |
67 | + * Copyright © 2011-2013 Canonical Ltd. |
68 | + * Author: Evan Dandrea <evan.dandrea@canonical.com> |
69 | + * |
70 | + * This program is free software: you can redistribute it and/or modify |
71 | + * it under the terms of the GNU General Public License as published by |
72 | + * the Free Software Foundation; version 3 of the License. |
73 | + * |
74 | + * This program is distributed in the hope that it will be useful, |
75 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
76 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
77 | + * GNU General Public License for more details. |
78 | + * |
79 | + * You should have received a copy of the GNU General Public License |
80 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
81 | + */ |
82 | + |
83 | +#ifndef GLOBALS_H |
84 | +#define GLOBALS_H |
85 | + |
86 | +/* Options */ |
87 | +extern int foreground; |
88 | + |
89 | +#endif /* GLOBALS_H */ |
90 | |
91 | === added file 'src/logging.c' |
92 | --- src/logging.c 1970-01-01 00:00:00 +0000 |
93 | +++ src/logging.c 2013-08-08 08:46:01 +0000 |
94 | @@ -0,0 +1,59 @@ |
95 | +/* whoopsie |
96 | + * |
97 | + * Copyright © 2011-2013 Canonical Ltd. |
98 | + * Author: Evan Dandrea <evan.dandrea@canonical.com> |
99 | + * |
100 | + * This program is free software: you can redistribute it and/or modify |
101 | + * it under the terms of the GNU General Public License as published by |
102 | + * the Free Software Foundation; version 3 of the License. |
103 | + * |
104 | + * This program is distributed in the hope that it will be useful, |
105 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
106 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
107 | + * GNU General Public License for more details. |
108 | + * |
109 | + * You should have received a copy of the GNU General Public License |
110 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
111 | + */ |
112 | + |
113 | +#define _BSD_SOURCE |
114 | + |
115 | +#include <stdio.h> |
116 | +#include <syslog.h> |
117 | +#include <stdarg.h> |
118 | + |
119 | +#include "globals.h" |
120 | + |
121 | +static int logging_started = 0; |
122 | +int logging_flags = LOG_PID; |
123 | + |
124 | +void |
125 | +log_msg (const char* fmt, ...) |
126 | +{ |
127 | + va_list argp; |
128 | + va_start (argp, fmt); |
129 | + |
130 | + if (foreground || !logging_started) { |
131 | + vfprintf (stdout, fmt, argp); |
132 | + fflush (stdout); |
133 | + } else { |
134 | + vsyslog(LOG_INFO, fmt, argp); |
135 | + } |
136 | + |
137 | + va_end (argp); |
138 | +} |
139 | + |
140 | +void |
141 | +open_log (void) |
142 | +{ |
143 | + logging_started = 1; |
144 | + openlog ("whoopsie", logging_flags, LOG_DAEMON); |
145 | + log_msg ("whoopsie " VERSION " starting up.\n"); |
146 | +} |
147 | + |
148 | +void |
149 | +close_log (void) |
150 | +{ |
151 | + if (!foreground && logging_started) |
152 | + closelog (); |
153 | +} |
154 | |
155 | === added file 'src/logging.h' |
156 | --- src/logging.h 1970-01-01 00:00:00 +0000 |
157 | +++ src/logging.h 2013-08-08 08:46:01 +0000 |
158 | @@ -0,0 +1,27 @@ |
159 | +/* whoopsie |
160 | + * |
161 | + * Copyright © 2011-2013 Canonical Ltd. |
162 | + * Author: Evan Dandrea <evan.dandrea@canonical.com> |
163 | + * |
164 | + * This program is free software: you can redistribute it and/or modify |
165 | + * it under the terms of the GNU General Public License as published by |
166 | + * the Free Software Foundation; version 3 of the License. |
167 | + * |
168 | + * This program is distributed in the hope that it will be useful, |
169 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
170 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
171 | + * GNU General Public License for more details. |
172 | + * |
173 | + * You should have received a copy of the GNU General Public License |
174 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
175 | + */ |
176 | + |
177 | +#ifndef LOGGING_H |
178 | +#define LOGGING_H |
179 | + |
180 | +void log_msg (const char* fmt, ...); |
181 | +void open_log (void); |
182 | +void close_log (void); |
183 | +void initialise_logging (void); |
184 | + |
185 | +#endif /* LOGGING_H */ |
186 | |
187 | === modified file 'src/monitor.c' |
188 | --- src/monitor.c 2013-02-08 11:58:46 +0000 |
189 | +++ src/monitor.c 2013-08-08 08:46:01 +0000 |
190 | @@ -1,6 +1,6 @@ |
191 | /* whoopsie |
192 | * |
193 | - * Copyright © 2011-2012 Canonical Ltd. |
194 | + * Copyright © 2011-2013 Canonical Ltd. |
195 | * Author: Evan Dandrea <evan.dandrea@canonical.com> |
196 | * |
197 | * This program is free software: you can redistribute it and/or modify |
198 | |
199 | === modified file 'src/monitor.h' |
200 | --- src/monitor.h 2013-01-29 17:23:14 +0000 |
201 | +++ src/monitor.h 2013-08-08 08:46:01 +0000 |
202 | @@ -1,6 +1,6 @@ |
203 | /* whoopsie |
204 | * |
205 | - * Copyright © 2011-2012 Canonical Ltd. |
206 | + * Copyright © 2011-2013 Canonical Ltd. |
207 | * Author: Evan Dandrea <evan.dandrea@canonical.com> |
208 | * |
209 | * This program is free software: you can redistribute it and/or modify |
210 | |
211 | === modified file 'src/tests/Makefile' |
212 | --- src/tests/Makefile 2013-02-26 11:02:35 +0000 |
213 | +++ src/tests/Makefile 2013-08-08 08:46:01 +0000 |
214 | @@ -7,6 +7,7 @@ |
215 | |
216 | test_parse_report_SOURCES=test_parse_report.c \ |
217 | ../whoopsie.c \ |
218 | + ../logging.c \ |
219 | ../utils.c \ |
220 | ../identifier.c \ |
221 | ../../lib/bson/bson.c \ |
222 | @@ -31,11 +32,16 @@ |
223 | test_identifier_EXECUTABLE=test_identifier |
224 | test_identifier_OBJECTS=$(test_identifier_SOURCES:.c=.test.o) |
225 | |
226 | +test_logging_SOURCES=test_logging.c \ |
227 | + ../logging.c |
228 | +test_logging_EXECUTABLE=test_logging |
229 | +test_logging_OBJECTS=$(test_logging_SOURCES:.c=.test.o) |
230 | + |
231 | .PHONY: all clean check |
232 | |
233 | all: check |
234 | |
235 | -check: $(test_parse_report_EXECUTABLE) $(test_utils_EXECUTABLE) $(test_monitor_EXECUTABLE) $(test_identifier_EXECUTABLE) |
236 | +check: $(test_parse_report_EXECUTABLE) $(test_utils_EXECUTABLE) $(test_monitor_EXECUTABLE) $(test_identifier_EXECUTABLE) $(test_logging_EXECUTABLE) |
237 | $(foreach p, $^, ./$p -k;) |
238 | |
239 | $(test_parse_report_EXECUTABLE): $(test_parse_report_OBJECTS) |
240 | @@ -46,6 +52,8 @@ |
241 | $(CC) -std=c99 $^ $(LIBS) -o $@ |
242 | $(test_identifier_EXECUTABLE): $(test_identifier_OBJECTS) |
243 | $(CC) -std=c99 $^ $(LIBS) -o $@ |
244 | +$(test_logging_EXECUTABLE): $(test_logging_OBJECTS) |
245 | + $(CC) -std=c99 $^ $(LIBS) -o $@ |
246 | |
247 | test_parse_report_coverage: $(test_parse_report_OBJECTS:.test.o=.coverage.o) |
248 | $(CC) -std=c99 $^ $(LIBS) -lgcov -o $@ |
249 | @@ -55,7 +63,9 @@ |
250 | $(CC) -std=c99 $^ $(LIBS) -lgcov -o $@ |
251 | test_identifier_coverage: $(test_identifier_OBJECTS:.test.o=.coverage.o) |
252 | $(CC) -std=c99 $^ $(LIBS) -lgcov -o $@ |
253 | -coverage: test_parse_report_coverage test_utils_coverage test_monitor_coverage test_identifier_coverage |
254 | +test_logging_coverage: $(test_logging_OBJECTS:.test.o=.coverage.o) |
255 | + $(CC) -std=c99 $^ $(LIBS) -lgcov -o $@ |
256 | +coverage: test_parse_report_coverage test_utils_coverage test_monitor_coverage test_identifier_coverage test_logging_coverage |
257 | $(foreach p, $^, ./$p -k;) |
258 | $(foreach p, $(wildcard ../*.c), gcov $p -o $(p:.c=.coverage.o);) |
259 | |
260 | @@ -68,9 +78,11 @@ |
261 | $(test_monitor_EXECUTABLE) \ |
262 | $(test_identifier_OBJECTS) \ |
263 | $(test_identifier_EXECUTABLE) \ |
264 | + $(test_logging_EXECUTABLE) \ |
265 | test_parse_report_coverage \ |
266 | test_utils_coverage \ |
267 | test_identifier_coverage \ |
268 | + test_logging_coverage \ |
269 | coverage |
270 | find ../.. \( -name '*.coverage.o' -o \ |
271 | -name '*.gcda' -o \ |
272 | |
273 | === modified file 'src/tests/test_identifier.c' |
274 | --- src/tests/test_identifier.c 2013-02-20 18:36:11 +0000 |
275 | +++ src/tests/test_identifier.c 2013-08-08 08:46:01 +0000 |
276 | @@ -1,6 +1,6 @@ |
277 | /* whoopsie |
278 | * |
279 | - * Copyright © 2011-2012 Canonical Ltd. |
280 | + * Copyright © 2011-2013 Canonical Ltd. |
281 | * Author: Evan Dandrea <evan.dandrea@canonical.com> |
282 | * |
283 | * This program is free software: you can redistribute it and/or modify |
284 | @@ -166,7 +166,10 @@ |
285 | int |
286 | main (int argc, char** argv) |
287 | { |
288 | +#if GLIB_MAJOR_VERSION <= 2 && GLIB_MINOR_VERSION < 35 |
289 | + /* Deprecated in glib 2.35/2.36. */ |
290 | g_type_init (); |
291 | +#endif |
292 | g_test_init (&argc, &argv, NULL); |
293 | |
294 | /* This wont work when running under fakeroot. */ |
295 | |
296 | === added file 'src/tests/test_logging.c' |
297 | --- src/tests/test_logging.c 1970-01-01 00:00:00 +0000 |
298 | +++ src/tests/test_logging.c 2013-08-08 08:46:01 +0000 |
299 | @@ -0,0 +1,177 @@ |
300 | +/* whoopsie |
301 | + * |
302 | + * Copyright © 2011-2013 Canonical Ltd. |
303 | + * Author: Evan Dandrea <evan.dandrea@canonical.com> |
304 | + * |
305 | + * This program is free software: you can redistribute it and/or modify |
306 | + * it under the terms of the GNU General Public License as published by |
307 | + * the Free Software Foundation; version 3 of the License. |
308 | + * |
309 | + * This program is distributed in the hope that it will be useful, |
310 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
311 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
312 | + * GNU General Public License for more details. |
313 | + * |
314 | + * You should have received a copy of the GNU General Public License |
315 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
316 | + */ |
317 | + |
318 | +#define _XOPEN_SOURCE 500 |
319 | + |
320 | +#include <unistd.h> |
321 | +#include <glib.h> |
322 | +#include <stdlib.h> |
323 | +#include <string.h> |
324 | +#include <stdio.h> |
325 | +#include <syslog.h> |
326 | + |
327 | +#include "../src/globals.h" |
328 | +#include "../src/logging.h" |
329 | + |
330 | +int foreground; |
331 | + |
332 | +void |
333 | +test_logging (void) |
334 | +{ |
335 | + char template[] = "/tmp/XXXXXX"; |
336 | + |
337 | + char buf[512] = {0}; |
338 | + FILE* fp = NULL; |
339 | + const char *expected = "whoopsie " VERSION " starting up.\nHello.\n"; |
340 | + |
341 | + foreground = 1; |
342 | + |
343 | + int fd; |
344 | + fpos_t pos; |
345 | + |
346 | + /* http://c-faq.com/stdio/undofreopen.html */ |
347 | + fflush (stdout); |
348 | + fgetpos (stdout, &pos); |
349 | + fd = dup (fileno (stdout)); |
350 | + |
351 | + tmpnam (template); |
352 | + if (freopen (template, "w", stdout) == NULL) { |
353 | + g_printerr ("Could not open temporary stdout.\n"); |
354 | + g_test_fail (); |
355 | + goto out; |
356 | + } |
357 | + |
358 | + /* Test opening, writing to, and closing the log. */ |
359 | + open_log (); |
360 | + log_msg ("Hello.\n"); |
361 | + close_log (); |
362 | + |
363 | + /* Did we write a log file? */ |
364 | + if (access (template, F_OK) < 0) { |
365 | + g_printerr ("We did not write anything to stdout.\n"); |
366 | + g_test_fail (); |
367 | + } |
368 | + |
369 | + /* Now ensure we've logged exactly what was expected. */ |
370 | + if ((fp = fopen (template, "r")) == NULL) { |
371 | + g_printerr ("Could not open temporary stdout for reading.\n"); |
372 | + g_test_fail (); |
373 | + } |
374 | + |
375 | + fread (buf, 512, 1, fp); |
376 | + if (strcmp (buf, expected) != 0) { |
377 | + g_printerr ("We did not write what was expected to stdout:\n%s", buf); |
378 | + g_test_fail (); |
379 | + } |
380 | + |
381 | + /* Clean up */ |
382 | + if (fclose (fp)) |
383 | + g_printerr ("Could not close the file pointer.\n"); |
384 | + |
385 | + if (unlink (template) < 0) { |
386 | + g_printerr ("Could not remove temporary stdout.\n"); |
387 | + g_test_fail (); |
388 | + } |
389 | +out: |
390 | + dup2 (fd, fileno (stdout)); |
391 | + close (fd); |
392 | + clearerr (stdout); |
393 | + fsetpos (stdout, &pos); |
394 | +} |
395 | + |
396 | +void |
397 | +test_logging_syslog (void) |
398 | +{ |
399 | + char template[] = "/tmp/XXXXXX"; |
400 | + |
401 | + char buf[512] = {0}; |
402 | + FILE* fp = NULL; |
403 | + |
404 | + extern int logging_flags; |
405 | + const char *expected = "whoopsie: whoopsie " VERSION " starting up.\nwhoopsie: Hello.\n"; |
406 | + |
407 | + logging_flags = LOG_PERROR; |
408 | + foreground = 0; |
409 | + |
410 | + int fd; |
411 | + fpos_t pos; |
412 | + |
413 | + /* http://c-faq.com/stdio/undofreopen.html */ |
414 | + fflush (stderr); |
415 | + fgetpos (stderr, &pos); |
416 | + fd = dup (fileno (stderr)); |
417 | + |
418 | + tmpnam (template); |
419 | + if (freopen (template, "w", stderr) == NULL) { |
420 | + g_print ("Could not open temporary stderr.\n"); |
421 | + g_test_fail (); |
422 | + goto out; |
423 | + } |
424 | + |
425 | + open_log (); |
426 | + log_msg ("Hello.\n"); |
427 | + fflush (stderr); |
428 | + close_log (); |
429 | + |
430 | + /* Did we write a log file? */ |
431 | + if (access (template, F_OK) < 0) { |
432 | + g_print ("We did not write anything to stderr.\n"); |
433 | + g_test_fail (); |
434 | + } |
435 | + |
436 | + /* Now ensure we've logged exactly what was expected. */ |
437 | + if ((fp = fopen (template, "r")) == NULL) { |
438 | + g_print ("Could not open temporary stderr for reading.\n"); |
439 | + g_test_fail (); |
440 | + } |
441 | + |
442 | + fread (buf, 512, 1, fp); |
443 | + if (strcmp (buf, expected) != 0) { |
444 | + g_print ("We did not write what was expected to stderr:\n%s", buf); |
445 | + g_test_fail (); |
446 | + } |
447 | + |
448 | + /* Clean up */ |
449 | + if (fclose (fp)) |
450 | + g_print ("Could not close the file pointer.\n"); |
451 | + |
452 | + if (unlink (template) < 0) { |
453 | + g_print ("Could not remove temporary stderr.\n"); |
454 | + g_test_fail (); |
455 | + } |
456 | +out: |
457 | + dup2 (fd, fileno (stderr)); |
458 | + close (fd); |
459 | + clearerr (stderr); |
460 | + fsetpos (stderr, &pos); |
461 | +} |
462 | + |
463 | +int |
464 | +main (int argc, char** argv) |
465 | +{ |
466 | +#if GLIB_MAJOR_VERSION <= 2 && GLIB_MINOR_VERSION < 35 |
467 | + /* Deprecated in glib 2.35/2.36. */ |
468 | + g_type_init (); |
469 | +#endif |
470 | + g_test_init (&argc, &argv, NULL); |
471 | + g_test_add_func ("/whoopsie/logging", |
472 | + test_logging); |
473 | + g_test_add_func ("/whoopsie/logging-syslog", |
474 | + test_logging_syslog); |
475 | + return g_test_run (); |
476 | +} |
477 | |
478 | === modified file 'src/tests/test_monitor.c' |
479 | --- src/tests/test_monitor.c 2013-02-06 17:22:07 +0000 |
480 | +++ src/tests/test_monitor.c 2013-08-08 08:46:01 +0000 |
481 | @@ -1,6 +1,6 @@ |
482 | /* whoopsie |
483 | * |
484 | - * Copyright © 2011-2012 Canonical Ltd. |
485 | + * Copyright © 2011-2013 Canonical Ltd. |
486 | * Author: Evan Dandrea <evan.dandrea@canonical.com> |
487 | * |
488 | * This program is free software: you can redistribute it and/or modify |
489 | @@ -215,7 +215,10 @@ |
490 | int |
491 | main (int argc, char** argv) |
492 | { |
493 | +#if GLIB_MAJOR_VERSION <= 2 && GLIB_MINOR_VERSION < 35 |
494 | + /* Deprecated in glib 2.35/2.36. */ |
495 | g_type_init (); |
496 | +#endif |
497 | g_test_init (&argc, &argv, NULL); |
498 | g_test_add_func ("/whoopsie/callback-never-triggered", |
499 | test_callback_never_triggered); |
500 | |
501 | === modified file 'src/tests/test_parse_report.c' |
502 | --- src/tests/test_parse_report.c 2013-01-31 14:39:18 +0000 |
503 | +++ src/tests/test_parse_report.c 2013-08-08 08:46:01 +0000 |
504 | @@ -1,6 +1,6 @@ |
505 | /* whoopsie |
506 | * |
507 | - * Copyright © 2011-2012 Canonical Ltd. |
508 | + * Copyright © 2011-2013 Canonical Ltd. |
509 | * Author: Evan Dandrea <evan.dandrea@canonical.com> |
510 | * |
511 | * This program is free software: you can redistribute it and/or modify |
512 | @@ -381,7 +381,10 @@ |
513 | int |
514 | main (int argc, char** argv) |
515 | { |
516 | +#if GLIB_MAJOR_VERSION <= 2 && GLIB_MINOR_VERSION < 35 |
517 | + /* Deprecated in glib 2.35/2.36. */ |
518 | g_type_init (); |
519 | +#endif |
520 | g_test_init (&argc, &argv, NULL); |
521 | |
522 | g_test_add_func ("/whoopsie/parse-report", test_parse_report); |
523 | |
524 | === modified file 'src/tests/test_utils.c' |
525 | --- src/tests/test_utils.c 2013-01-31 14:39:18 +0000 |
526 | +++ src/tests/test_utils.c 2013-08-08 08:46:01 +0000 |
527 | @@ -1,6 +1,6 @@ |
528 | /* whoopsie |
529 | * |
530 | - * Copyright © 2011-2012 Canonical Ltd. |
531 | + * Copyright © 2011-2013 Canonical Ltd. |
532 | * Author: Evan Dandrea <evan.dandrea@canonical.com> |
533 | * |
534 | * This program is free software: you can redistribute it and/or modify |
535 | @@ -213,7 +213,10 @@ |
536 | int |
537 | main (int argc, char** argv) |
538 | { |
539 | +#if GLIB_MAJOR_VERSION <= 2 && GLIB_MINOR_VERSION < 35 |
540 | + /* Deprecated in glib 2.35/2.36. */ |
541 | g_type_init (); |
542 | +#endif |
543 | g_test_init (&argc, &argv, NULL); |
544 | g_test_add_func ("/whoopsie/change-file-extension", test_change_file_extension); |
545 | g_test_add_func ("/whoopsie/already-handled-report", test_already_handled_report); |
546 | |
547 | === modified file 'src/utils.c' |
548 | --- src/utils.c 2013-01-31 14:39:18 +0000 |
549 | +++ src/utils.c 2013-08-08 08:46:01 +0000 |
550 | @@ -1,6 +1,6 @@ |
551 | /* whoopsie |
552 | * |
553 | - * Copyright © 2011-2012 Canonical Ltd. |
554 | + * Copyright © 2011-2013 Canonical Ltd. |
555 | * Author: Evan Dandrea <evan.dandrea@canonical.com> |
556 | * |
557 | * This program is free software: you can redistribute it and/or modify |
558 | |
559 | === modified file 'src/utils.h' |
560 | --- src/utils.h 2012-03-27 13:38:10 +0000 |
561 | +++ src/utils.h 2013-08-08 08:46:01 +0000 |
562 | @@ -1,6 +1,6 @@ |
563 | /* whoopsie |
564 | * |
565 | - * Copyright © 2011-2012 Canonical Ltd. |
566 | + * Copyright © 2011-2013 Canonical Ltd. |
567 | * Author: Evan Dandrea <evan.dandrea@canonical.com> |
568 | * |
569 | * This program is free software: you can redistribute it and/or modify |
570 | |
571 | === modified file 'src/whoopsie.c' |
572 | --- src/whoopsie.c 2013-07-26 15:16:39 +0000 |
573 | +++ src/whoopsie.c 2013-08-08 08:46:01 +0000 |
574 | @@ -1,6 +1,6 @@ |
575 | /* whoopsie |
576 | * |
577 | - * Copyright © 2011-2012 Canonical Ltd. |
578 | + * Copyright © 2011-2013 Canonical Ltd. |
579 | * Author: Evan Dandrea <evan.dandrea@canonical.com> |
580 | * |
581 | * This program is free software: you can redistribute it and/or modify |
582 | @@ -46,6 +46,8 @@ |
583 | #include "connectivity.h" |
584 | #include "monitor.h" |
585 | #include "identifier.h" |
586 | +#include "logging.h" |
587 | +#include "globals.h" |
588 | |
589 | /* The length of time to wait before processing outstanding crashes, in seconds |
590 | */ |
591 | @@ -58,6 +60,9 @@ |
592 | /* The URL of the crash database. */ |
593 | static char* crash_db_url = NULL; |
594 | |
595 | +/* Username we will run under */ |
596 | +static const char* username = "whoopsie"; |
597 | + |
598 | /* The database identifier. Either: |
599 | * - The system UUID, taken from the DMI tables and SHA-512 hashed |
600 | * - The MAC address of the first non-loopback device, SHA-512 hashed */ |
601 | @@ -66,9 +71,6 @@ |
602 | /* The URL for sending the initial crash report */ |
603 | static char* crash_db_submit_url = NULL; |
604 | |
605 | -/* Username we will run under */ |
606 | -static const char username[] = "whoopsie"; |
607 | - |
608 | /* The file path and descriptor for our instance lock */ |
609 | static const char* lock_path = "/var/lock/whoopsie/lock"; |
610 | static int lock_fd = 0; |
611 | @@ -77,10 +79,9 @@ |
612 | static const char* report_dir = "/var/crash"; |
613 | |
614 | /* Options */ |
615 | +int foreground = 0; |
616 | |
617 | #ifndef TEST |
618 | -static gboolean foreground = FALSE; |
619 | - |
620 | static GOptionEntry option_entries[] = { |
621 | { "foreground", 'f', 0, G_OPTION_ARG_NONE, &foreground, |
622 | "Run in the foreground", NULL }, |
623 | @@ -264,12 +265,12 @@ |
624 | /* TODO use curl_share for DNS caching. */ |
625 | /* Repeated calls to curl_global_init will have no effect. */ |
626 | if (curl_global_init (CURL_GLOBAL_SSL)) { |
627 | - g_print ("Unable to initialize curl.\n\n"); |
628 | + log_msg ("Unable to initialize curl.\n\n"); |
629 | exit (EXIT_FAILURE); |
630 | } |
631 | |
632 | if ((curl = curl_easy_init ()) == NULL) { |
633 | - printf ("Couldn't init curl.\n"); |
634 | + log_msg ("Couldn't init curl.\n"); |
635 | return FALSE; |
636 | } |
637 | curl_easy_setopt (curl, CURLOPT_POST, 1); |
638 | @@ -288,9 +289,9 @@ |
639 | curl_slist_free_all(list); |
640 | curl_easy_getinfo (curl, CURLINFO_RESPONSE_CODE, &response_code); |
641 | |
642 | - printf ("Sent; server replied with: %s\n", |
643 | + log_msg ("Sent; server replied with: %s\n", |
644 | curl_easy_strerror (result_code)); |
645 | - printf ("Response code: %ld\n", response_code); |
646 | + log_msg ("Response code: %ld\n", response_code); |
647 | curl_easy_cleanup (curl); |
648 | |
649 | if (result_code != CURLE_OK) |
650 | @@ -515,7 +516,7 @@ |
651 | /* TODO use CURLOPT_READFUNCTION to transparently compress data with |
652 | * Snappy. */ |
653 | if ((curl = curl_easy_init ()) == NULL) { |
654 | - printf ("Couldn't init curl.\n"); |
655 | + log_msg ("Couldn't init curl.\n"); |
656 | g_free (crash_db_core_url); |
657 | return FALSE; |
658 | } |
659 | @@ -536,9 +537,9 @@ |
660 | |
661 | curl_easy_getinfo (curl, CURLINFO_RESPONSE_CODE, &response_code); |
662 | |
663 | - printf ("Sent; server replied with: %s\n", |
664 | + log_msg ("Sent; server replied with: %s\n", |
665 | curl_easy_strerror (result_code)); |
666 | - printf ("Response code: %ld\n", response_code); |
667 | + log_msg ("Response code: %ld\n", response_code); |
668 | curl_easy_cleanup (curl); |
669 | g_free (crash_db_core_url); |
670 | destroy_response_string (&s); |
671 | @@ -568,11 +569,11 @@ |
672 | /* We do not retry the upload. Once is a big enough hit to |
673 | * their Internet connection, and we can always count on |
674 | * the next person in line to send it. */ |
675 | - printf ("Upload of the core dump failed.\n"); |
676 | + log_msg ("Upload of the core dump failed.\n"); |
677 | } else |
678 | - printf ("Asked for a core dump that we don't have.\n"); |
679 | + log_msg ("Asked for a core dump that we don't have.\n"); |
680 | } else |
681 | - printf ("Got command: %s\n", command); |
682 | + log_msg ("Got command: %s\n", command); |
683 | } |
684 | } |
685 | |
686 | @@ -588,28 +589,28 @@ |
687 | bson b[1]; |
688 | int response = 0; |
689 | |
690 | - g_print ("Parsing %s.\n", crash_file); |
691 | + log_msg ("Parsing %s.\n", crash_file); |
692 | report = parse_report (crash_file, FALSE, &error); |
693 | if (!report) { |
694 | if (error) { |
695 | - g_print ("Unable to parse report (%s): %s\n", crash_file, |
696 | + log_msg ("Unable to parse report (%s): %s\n", crash_file, |
697 | error->message); |
698 | g_error_free (error); |
699 | } else { |
700 | - g_print ("Unable to parse report (%s)\n", crash_file); |
701 | + log_msg ("Unable to parse report (%s)\n", crash_file); |
702 | } |
703 | /* Do not keep trying to parse and upload this */ |
704 | return TRUE; |
705 | } |
706 | |
707 | if (!bsonify (report, b, &message_data, &message_len)) { |
708 | - g_print ("Unable to bsonify report (%s)\n", crash_file); |
709 | + log_msg ("Unable to bsonify report (%s)\n", crash_file); |
710 | if (bson_data (b)) |
711 | bson_destroy (b); |
712 | /* Do not keep trying to parse and upload this */ |
713 | success = TRUE; |
714 | } else { |
715 | - g_print ("Uploading %s.\n", crash_file); |
716 | + log_msg ("Uploading %s.\n", crash_file); |
717 | init_response_string (&s); |
718 | response = upload_report (message_data, message_len, &s); |
719 | if (bson_data (b)) |
720 | @@ -625,7 +626,7 @@ |
721 | success = FALSE; |
722 | |
723 | if (response > 200) |
724 | - g_print ("Server replied with:\n%s\n", s.p); |
725 | + log_msg ("Server replied with:\n%s\n", s.p); |
726 | |
727 | if (response == 200 && s.length > 0) |
728 | handle_response (report, s.p); |
729 | @@ -672,7 +673,7 @@ |
730 | continue; |
731 | } else if (online_state && parse_and_upload_report (crash_file)) { |
732 | if (!mark_handled (crash_file)) |
733 | - g_print ("Unable to mark report as seen (%s)\n", crash_file); |
734 | + log_msg ("Unable to mark report as seen (%s)\n", crash_file); |
735 | |
736 | } |
737 | |
738 | @@ -691,7 +692,7 @@ |
739 | struct rlimit rl = {0}; |
740 | |
741 | if (getrlimit (RLIMIT_NOFILE, &rl) < 0) { |
742 | - g_print ("Could not get resource limits.\n"); |
743 | + log_msg ("Could not get resource limits.\n"); |
744 | exit (EXIT_FAILURE); |
745 | } |
746 | |
747 | @@ -713,7 +714,7 @@ |
748 | if ((open ("/dev/null", O_RDWR) != 0) || |
749 | (dup (0) != 1) || |
750 | (dup (0) != 2)) { |
751 | - g_print ("Could not redirect file descriptors to /dev/null.\n"); |
752 | + log_msg ("Could not redirect file descriptors to /dev/null.\n"); |
753 | exit (EXIT_FAILURE); |
754 | } |
755 | } |
756 | @@ -730,21 +731,21 @@ |
757 | /* use system directory */ |
758 | if (mkdir ("/var/lock/whoopsie", 0755) < 0) { |
759 | if (errno != EEXIST) { |
760 | - g_print ("Could not create lock directory.\n"); |
761 | + log_msg ("Could not create lock directory.\n"); |
762 | } |
763 | } |
764 | } |
765 | |
766 | - g_print("Using lock path: %s\n", lock_path); |
767 | + log_msg ("Using lock path: %s\n", lock_path); |
768 | |
769 | lock_fd = open (lock_path, O_CREAT | O_RDWR, 0600); |
770 | rc = flock (lock_fd, LOCK_EX | LOCK_NB); |
771 | if (rc) { |
772 | if (EWOULDBLOCK == errno) { |
773 | - g_print ("Another instance is already running.\n"); |
774 | + log_msg ("Another instance is already running.\n"); |
775 | exit (1); |
776 | } else { |
777 | - g_print ("Could not create lock file: %s\n", strerror (errno)); |
778 | + log_msg ("Could not create lock file: %s\n", strerror (errno)); |
779 | } |
780 | } |
781 | } |
782 | @@ -806,7 +807,7 @@ |
783 | void |
784 | network_changed (gboolean available) |
785 | { |
786 | - g_print (available ? "online\n" : "offline\n"); |
787 | + log_msg (available ? "online\n" : "offline\n"); |
788 | if (!available) { |
789 | online_state = FALSE; |
790 | return; |
791 | @@ -825,12 +826,12 @@ |
792 | check_online_then_upload (const char* crash_file) { |
793 | |
794 | if (!online_state) { |
795 | - g_print ("Not online; processing later (%s).\n", crash_file); |
796 | + log_msg ("Not online; processing later (%s).\n", crash_file); |
797 | return FALSE; |
798 | } |
799 | |
800 | if (!parse_and_upload_report (crash_file)) { |
801 | - g_print ("Could not upload; processing later (%s).\n", crash_file); |
802 | + log_msg ("Could not upload; processing later (%s).\n", crash_file); |
803 | return FALSE; |
804 | } |
805 | |
806 | @@ -838,31 +839,32 @@ |
807 | } |
808 | |
809 | void |
810 | -create_directory (void) |
811 | +create_crash_directory (void) |
812 | { |
813 | struct passwd *pw = NULL; |
814 | |
815 | if (mkdir (report_dir, 0755) < 0) { |
816 | if (errno != EEXIST) { |
817 | - g_print ("Could not create non-existent directory to monitor (%d): %s.\n", errno, report_dir); |
818 | + log_msg ("Could not create non-existent report_directory to monitor (%d): %s.\n", errno, report_dir); |
819 | exit (EXIT_FAILURE); |
820 | } |
821 | } else { |
822 | /* Only change the permissions if we've just created it */ |
823 | if (!(pw = getpwnam (username))) { |
824 | - g_print ("Could not find user, %s.\n", username); |
825 | + log_msg ("Could not find user, %s.\n", username); |
826 | exit (EXIT_FAILURE); |
827 | } |
828 | if (chown (report_dir, -1, pw->pw_gid) < 0) { |
829 | - g_print ("Could not change ownership of %s.\n", report_dir); |
830 | + log_msg ("Could not change ownership of %s.\n", report_dir); |
831 | exit (EXIT_FAILURE); |
832 | } |
833 | if (chmod (report_dir, 03777) < 0) { |
834 | - g_print ("Could not change permissions on %s.\n", report_dir); |
835 | + log_msg ("Could not change permissions on %s.\n", report_dir); |
836 | exit (EXIT_FAILURE); |
837 | } |
838 | } |
839 | } |
840 | + |
841 | #ifndef TEST |
842 | static GMainLoop* loop = NULL; |
843 | |
844 | @@ -875,7 +877,7 @@ |
845 | context = g_option_context_new (NULL); |
846 | g_option_context_add_main_entries (context, option_entries, NULL); |
847 | if (!g_option_context_parse (context, argc, argv, &err)) { |
848 | - g_print ("whoopsie: %s\n", err->message); |
849 | + log_msg ("whoopsie: %s\n", err->message); |
850 | g_error_free (err); |
851 | exit (EXIT_FAILURE); |
852 | } |
853 | @@ -916,10 +918,13 @@ |
854 | parse_arguments (&argc, &argv); |
855 | |
856 | if ((crash_db_url = get_crash_db_url ()) == NULL) { |
857 | - g_print ("Could not get crash database location.\n"); |
858 | + log_msg ("Could not get crash database location.\n"); |
859 | exit (EXIT_FAILURE); |
860 | } |
861 | |
862 | + if (!foreground) |
863 | + open_log (); |
864 | + |
865 | /* environment might change report directory and identifier */ |
866 | env = g_getenv ("APPORT_REPORT_DIR"); |
867 | if (env != NULL) |
868 | @@ -932,7 +937,7 @@ |
869 | whoopsie_identifier_generate (&whoopsie_identifier, &err); |
870 | |
871 | if (err) { |
872 | - g_print ("%s\n", err->message); |
873 | + log_msg ("%s\n", err->message); |
874 | g_error_free (err); |
875 | err = NULL; |
876 | crash_db_submit_url = strdup (crash_db_url); |
877 | @@ -942,11 +947,11 @@ |
878 | whoopsie_identifier); |
879 | } |
880 | |
881 | - create_directory (); |
882 | + create_crash_directory (); |
883 | |
884 | drop_privileges (&err); |
885 | if (err) { |
886 | - g_print ("%s\n", err->message); |
887 | + log_msg ("%s\n", err->message); |
888 | g_error_free (err); |
889 | exit (EXIT_FAILURE); |
890 | } |
891 | @@ -975,6 +980,8 @@ |
892 | unmonitor_directory (monitor, check_online_then_upload); |
893 | unmonitor_connectivity (); |
894 | |
895 | + close_log (); |
896 | + |
897 | g_unlink (lock_path); |
898 | close (lock_fd); |
899 | curl_global_cleanup (); |
900 | |
901 | === modified file 'src/whoopsie.h' |
902 | --- src/whoopsie.h 2013-07-26 15:16:39 +0000 |
903 | +++ src/whoopsie.h 2013-08-08 08:46:01 +0000 |
904 | @@ -1,6 +1,6 @@ |
905 | /* whoopsie |
906 | * |
907 | - * Copyright © 2011-2012 Canonical Ltd. |
908 | + * Copyright © 2011-2013 Canonical Ltd. |
909 | * Author: Evan Dandrea <evan.dandrea@canonical.com> |
910 | * |
911 | * This program is free software: you can redistribute it and/or modify |
* main(): logging( ). I can see that this actually works logging( ):
- There are 2 calls to log_msg() before the call to initialise_
since log_msg() checks log_file_p, but it looks a little alarming initially :)
* initialise_
- Print errno values for error conditions?
* log_msg():
- You might want that fflush() to apply in both scenario since stdout is buffered by default.
* open_log():
- I'd make the file perms 0640 for security reasons.
- Might be worth adding in the pid whoopsie is running under to the startup message.
- I'd add an "assert (! log_file_p)" to the start of the function.
Might be worth having open_log() call initialise_ logging( ) itself (and then use a static variable in open_log() to determine if the logging subsystem has already been initialised) since it's slightly confusing seeing two calls in main that both seem to do something similar.
Finally, what's the reason for not using syslog(3) out of interest?