Merge lp:~ev/whoopsie/be-more-verbose into lp:whoopsie

Proposed by Evan
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
Reviewer Review Type Date Requested Status
James Hunt (community) Approve
Daisy Pluckers Pending
Review via email: mp+178788@code.launchpad.net

Description of the change

This branch finally adds a log file (/var/log/whoopsie/whoopsie.log) to whoopsie. It is only written to when whoopsie is run as a daemon.

To post a comment you must log in.
Revision history for this message
James Hunt (jamesodhunt) wrote :

* main():
  - There are 2 calls to log_msg() before the call to initialise_logging(). I can see that this actually works
    since log_msg() checks log_file_p, but it looks a little alarming initially :)
* initialise_logging():
  - 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?

Revision history for this message
Evan (ev) 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!

lp:~ev/whoopsie/be-more-verbose updated
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.

Revision history for this message
Evan (ev) wrote :

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).

Revision history for this message
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.

review: Approve
Revision history for this message
Evan (ev) wrote :

Thanks!

Good spot on the newlines. I'll fix those up in the merge.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
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

Subscribers

People subscribed via source and target branches

to all changes:
to status/vote changes: