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
=== modified file '.bzrignore'
--- .bzrignore 2012-05-27 19:39:06 +0000
+++ .bzrignore 2013-08-08 08:46:01 +0000
@@ -12,3 +12,4 @@
12src/tests/test_utils12src/tests/test_utils
13src/tests/test_monitor13src/tests/test_monitor
14src/tests/test_identifier14src/tests/test_identifier
15src/tests/test_logging
1516
=== modified file 'Makefile'
--- Makefile 2013-02-26 10:36:50 +0000
+++ Makefile 2013-08-08 08:46:01 +0000
@@ -18,6 +18,7 @@
18 src/utils.c \18 src/utils.c \
19 src/connectivity.c \19 src/connectivity.c \
20 src/monitor.c \20 src/monitor.c \
21 src/logging.c \
21 lib/bson/bson.c \22 lib/bson/bson.c \
22 lib/bson/encoding.c \23 lib/bson/encoding.c \
23 lib/bson/numbers.c24 lib/bson/numbers.c
2425
=== modified file 'debian/copyright'
--- debian/copyright 2012-06-18 08:32:13 +0000
+++ debian/copyright 2013-08-08 08:46:01 +0000
@@ -3,8 +3,8 @@
3Source: http://code.launchpad.net/whoopsie3Source: http://code.launchpad.net/whoopsie
44
5Files: src/*5Files: src/*
6Copyright: 2011-2012 Canonical Ltd.6Copyright: 2011-2013 Canonical Ltd.
7 2011-2012 Evan Dandrea <ev@ubuntu.com>7 2011-2013 Evan Dandrea <ev@ubuntu.com>
8License: GPL-38License: GPL-3
9 This package is free software; you can redistribute it and/or modify9 This package is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by10 it under the terms of the GNU General Public License as published by
1111
=== modified file 'src/connectivity.c'
--- src/connectivity.c 2013-02-26 10:50:53 +0000
+++ src/connectivity.c 2013-08-08 08:46:01 +0000
@@ -1,6 +1,6 @@
1/* whoopsie1/* whoopsie
2 * 2 *
3 * Copyright © 2011-2012 Canonical Ltd.3 * Copyright © 2011-2013 Canonical Ltd.
4 * Author: Evan Dandrea <evan.dandrea@canonical.com>4 * Author: Evan Dandrea <evan.dandrea@canonical.com>
5 * 5 *
6 * This program is free software: you can redistribute it and/or modify6 * This program is free software: you can redistribute it and/or modify
77
=== modified file 'src/connectivity.h'
--- src/connectivity.h 2013-01-28 15:38:09 +0000
+++ src/connectivity.h 2013-08-08 08:46:01 +0000
@@ -1,6 +1,6 @@
1/* whoopsie1/* whoopsie
2 * 2 *
3 * Copyright © 2011-2012 Canonical Ltd.3 * Copyright © 2011-2013 Canonical Ltd.
4 * Author: Evan Dandrea <evan.dandrea@canonical.com>4 * Author: Evan Dandrea <evan.dandrea@canonical.com>
5 * 5 *
6 * This program is free software: you can redistribute it and/or modify6 * This program is free software: you can redistribute it and/or modify
77
=== added file 'src/globals.h'
--- src/globals.h 1970-01-01 00:00:00 +0000
+++ src/globals.h 2013-08-08 08:46:01 +0000
@@ -0,0 +1,25 @@
1/* whoopsie
2 *
3 * Copyright © 2011-2013 Canonical Ltd.
4 * Author: Evan Dandrea <evan.dandrea@canonical.com>
5 *
6 * This program is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; version 3 of the License.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18
19#ifndef GLOBALS_H
20#define GLOBALS_H
21
22/* Options */
23extern int foreground;
24
25#endif /* GLOBALS_H */
026
=== added file 'src/logging.c'
--- src/logging.c 1970-01-01 00:00:00 +0000
+++ src/logging.c 2013-08-08 08:46:01 +0000
@@ -0,0 +1,59 @@
1/* whoopsie
2 *
3 * Copyright © 2011-2013 Canonical Ltd.
4 * Author: Evan Dandrea <evan.dandrea@canonical.com>
5 *
6 * This program is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; version 3 of the License.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18
19#define _BSD_SOURCE
20
21#include <stdio.h>
22#include <syslog.h>
23#include <stdarg.h>
24
25#include "globals.h"
26
27static int logging_started = 0;
28int logging_flags = LOG_PID;
29
30void
31log_msg (const char* fmt, ...)
32{
33 va_list argp;
34 va_start (argp, fmt);
35
36 if (foreground || !logging_started) {
37 vfprintf (stdout, fmt, argp);
38 fflush (stdout);
39 } else {
40 vsyslog(LOG_INFO, fmt, argp);
41 }
42
43 va_end (argp);
44}
45
46void
47open_log (void)
48{
49 logging_started = 1;
50 openlog ("whoopsie", logging_flags, LOG_DAEMON);
51 log_msg ("whoopsie " VERSION " starting up.\n");
52}
53
54void
55close_log (void)
56{
57 if (!foreground && logging_started)
58 closelog ();
59}
060
=== added file 'src/logging.h'
--- src/logging.h 1970-01-01 00:00:00 +0000
+++ src/logging.h 2013-08-08 08:46:01 +0000
@@ -0,0 +1,27 @@
1/* whoopsie
2 *
3 * Copyright © 2011-2013 Canonical Ltd.
4 * Author: Evan Dandrea <evan.dandrea@canonical.com>
5 *
6 * This program is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; version 3 of the License.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18
19#ifndef LOGGING_H
20#define LOGGING_H
21
22void log_msg (const char* fmt, ...);
23void open_log (void);
24void close_log (void);
25void initialise_logging (void);
26
27#endif /* LOGGING_H */
028
=== modified file 'src/monitor.c'
--- src/monitor.c 2013-02-08 11:58:46 +0000
+++ src/monitor.c 2013-08-08 08:46:01 +0000
@@ -1,6 +1,6 @@
1/* whoopsie1/* whoopsie
2 * 2 *
3 * Copyright © 2011-2012 Canonical Ltd.3 * Copyright © 2011-2013 Canonical Ltd.
4 * Author: Evan Dandrea <evan.dandrea@canonical.com>4 * Author: Evan Dandrea <evan.dandrea@canonical.com>
5 * 5 *
6 * This program is free software: you can redistribute it and/or modify6 * This program is free software: you can redistribute it and/or modify
77
=== modified file 'src/monitor.h'
--- src/monitor.h 2013-01-29 17:23:14 +0000
+++ src/monitor.h 2013-08-08 08:46:01 +0000
@@ -1,6 +1,6 @@
1/* whoopsie1/* whoopsie
2 * 2 *
3 * Copyright © 2011-2012 Canonical Ltd.3 * Copyright © 2011-2013 Canonical Ltd.
4 * Author: Evan Dandrea <evan.dandrea@canonical.com>4 * Author: Evan Dandrea <evan.dandrea@canonical.com>
5 * 5 *
6 * This program is free software: you can redistribute it and/or modify6 * This program is free software: you can redistribute it and/or modify
77
=== modified file 'src/tests/Makefile'
--- src/tests/Makefile 2013-02-26 11:02:35 +0000
+++ src/tests/Makefile 2013-08-08 08:46:01 +0000
@@ -7,6 +7,7 @@
77
8test_parse_report_SOURCES=test_parse_report.c \8test_parse_report_SOURCES=test_parse_report.c \
9 ../whoopsie.c \9 ../whoopsie.c \
10 ../logging.c \
10 ../utils.c \11 ../utils.c \
11 ../identifier.c \12 ../identifier.c \
12 ../../lib/bson/bson.c \13 ../../lib/bson/bson.c \
@@ -31,11 +32,16 @@
31test_identifier_EXECUTABLE=test_identifier32test_identifier_EXECUTABLE=test_identifier
32test_identifier_OBJECTS=$(test_identifier_SOURCES:.c=.test.o)33test_identifier_OBJECTS=$(test_identifier_SOURCES:.c=.test.o)
3334
35test_logging_SOURCES=test_logging.c \
36 ../logging.c
37test_logging_EXECUTABLE=test_logging
38test_logging_OBJECTS=$(test_logging_SOURCES:.c=.test.o)
39
34.PHONY: all clean check40.PHONY: all clean check
3541
36all: check42all: check
3743
38check: $(test_parse_report_EXECUTABLE) $(test_utils_EXECUTABLE) $(test_monitor_EXECUTABLE) $(test_identifier_EXECUTABLE)44check: $(test_parse_report_EXECUTABLE) $(test_utils_EXECUTABLE) $(test_monitor_EXECUTABLE) $(test_identifier_EXECUTABLE) $(test_logging_EXECUTABLE)
39 $(foreach p, $^, ./$p -k;)45 $(foreach p, $^, ./$p -k;)
4046
41$(test_parse_report_EXECUTABLE): $(test_parse_report_OBJECTS)47$(test_parse_report_EXECUTABLE): $(test_parse_report_OBJECTS)
@@ -46,6 +52,8 @@
46 $(CC) -std=c99 $^ $(LIBS) -o $@52 $(CC) -std=c99 $^ $(LIBS) -o $@
47$(test_identifier_EXECUTABLE): $(test_identifier_OBJECTS)53$(test_identifier_EXECUTABLE): $(test_identifier_OBJECTS)
48 $(CC) -std=c99 $^ $(LIBS) -o $@54 $(CC) -std=c99 $^ $(LIBS) -o $@
55$(test_logging_EXECUTABLE): $(test_logging_OBJECTS)
56 $(CC) -std=c99 $^ $(LIBS) -o $@
4957
50test_parse_report_coverage: $(test_parse_report_OBJECTS:.test.o=.coverage.o)58test_parse_report_coverage: $(test_parse_report_OBJECTS:.test.o=.coverage.o)
51 $(CC) -std=c99 $^ $(LIBS) -lgcov -o $@59 $(CC) -std=c99 $^ $(LIBS) -lgcov -o $@
@@ -55,7 +63,9 @@
55 $(CC) -std=c99 $^ $(LIBS) -lgcov -o $@63 $(CC) -std=c99 $^ $(LIBS) -lgcov -o $@
56test_identifier_coverage: $(test_identifier_OBJECTS:.test.o=.coverage.o)64test_identifier_coverage: $(test_identifier_OBJECTS:.test.o=.coverage.o)
57 $(CC) -std=c99 $^ $(LIBS) -lgcov -o $@65 $(CC) -std=c99 $^ $(LIBS) -lgcov -o $@
58coverage: test_parse_report_coverage test_utils_coverage test_monitor_coverage test_identifier_coverage66test_logging_coverage: $(test_logging_OBJECTS:.test.o=.coverage.o)
67 $(CC) -std=c99 $^ $(LIBS) -lgcov -o $@
68coverage: test_parse_report_coverage test_utils_coverage test_monitor_coverage test_identifier_coverage test_logging_coverage
59 $(foreach p, $^, ./$p -k;)69 $(foreach p, $^, ./$p -k;)
60 $(foreach p, $(wildcard ../*.c), gcov $p -o $(p:.c=.coverage.o);)70 $(foreach p, $(wildcard ../*.c), gcov $p -o $(p:.c=.coverage.o);)
6171
@@ -68,9 +78,11 @@
68 $(test_monitor_EXECUTABLE) \78 $(test_monitor_EXECUTABLE) \
69 $(test_identifier_OBJECTS) \79 $(test_identifier_OBJECTS) \
70 $(test_identifier_EXECUTABLE) \80 $(test_identifier_EXECUTABLE) \
81 $(test_logging_EXECUTABLE) \
71 test_parse_report_coverage \82 test_parse_report_coverage \
72 test_utils_coverage \83 test_utils_coverage \
73 test_identifier_coverage \84 test_identifier_coverage \
85 test_logging_coverage \
74 coverage86 coverage
75 find ../.. \( -name '*.coverage.o' -o \87 find ../.. \( -name '*.coverage.o' -o \
76 -name '*.gcda' -o \88 -name '*.gcda' -o \
7789
=== modified file 'src/tests/test_identifier.c'
--- src/tests/test_identifier.c 2013-02-20 18:36:11 +0000
+++ src/tests/test_identifier.c 2013-08-08 08:46:01 +0000
@@ -1,6 +1,6 @@
1/* whoopsie1/* whoopsie
2 * 2 *
3 * Copyright © 2011-2012 Canonical Ltd.3 * Copyright © 2011-2013 Canonical Ltd.
4 * Author: Evan Dandrea <evan.dandrea@canonical.com>4 * Author: Evan Dandrea <evan.dandrea@canonical.com>
5 * 5 *
6 * This program is free software: you can redistribute it and/or modify6 * This program is free software: you can redistribute it and/or modify
@@ -166,7 +166,10 @@
166int166int
167main (int argc, char** argv)167main (int argc, char** argv)
168{168{
169#if GLIB_MAJOR_VERSION <= 2 && GLIB_MINOR_VERSION < 35
170 /* Deprecated in glib 2.35/2.36. */
169 g_type_init ();171 g_type_init ();
172#endif
170 g_test_init (&argc, &argv, NULL);173 g_test_init (&argc, &argv, NULL);
171174
172 /* This wont work when running under fakeroot. */175 /* This wont work when running under fakeroot. */
173176
=== added file 'src/tests/test_logging.c'
--- src/tests/test_logging.c 1970-01-01 00:00:00 +0000
+++ src/tests/test_logging.c 2013-08-08 08:46:01 +0000
@@ -0,0 +1,177 @@
1/* whoopsie
2 *
3 * Copyright © 2011-2013 Canonical Ltd.
4 * Author: Evan Dandrea <evan.dandrea@canonical.com>
5 *
6 * This program is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; version 3 of the License.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18
19#define _XOPEN_SOURCE 500
20
21#include <unistd.h>
22#include <glib.h>
23#include <stdlib.h>
24#include <string.h>
25#include <stdio.h>
26#include <syslog.h>
27
28#include "../src/globals.h"
29#include "../src/logging.h"
30
31int foreground;
32
33void
34test_logging (void)
35{
36 char template[] = "/tmp/XXXXXX";
37
38 char buf[512] = {0};
39 FILE* fp = NULL;
40 const char *expected = "whoopsie " VERSION " starting up.\nHello.\n";
41
42 foreground = 1;
43
44 int fd;
45 fpos_t pos;
46
47 /* http://c-faq.com/stdio/undofreopen.html */
48 fflush (stdout);
49 fgetpos (stdout, &pos);
50 fd = dup (fileno (stdout));
51
52 tmpnam (template);
53 if (freopen (template, "w", stdout) == NULL) {
54 g_printerr ("Could not open temporary stdout.\n");
55 g_test_fail ();
56 goto out;
57 }
58
59 /* Test opening, writing to, and closing the log. */
60 open_log ();
61 log_msg ("Hello.\n");
62 close_log ();
63
64 /* Did we write a log file? */
65 if (access (template, F_OK) < 0) {
66 g_printerr ("We did not write anything to stdout.\n");
67 g_test_fail ();
68 }
69
70 /* Now ensure we've logged exactly what was expected. */
71 if ((fp = fopen (template, "r")) == NULL) {
72 g_printerr ("Could not open temporary stdout for reading.\n");
73 g_test_fail ();
74 }
75
76 fread (buf, 512, 1, fp);
77 if (strcmp (buf, expected) != 0) {
78 g_printerr ("We did not write what was expected to stdout:\n%s", buf);
79 g_test_fail ();
80 }
81
82 /* Clean up */
83 if (fclose (fp))
84 g_printerr ("Could not close the file pointer.\n");
85
86 if (unlink (template) < 0) {
87 g_printerr ("Could not remove temporary stdout.\n");
88 g_test_fail ();
89 }
90out:
91 dup2 (fd, fileno (stdout));
92 close (fd);
93 clearerr (stdout);
94 fsetpos (stdout, &pos);
95}
96
97void
98test_logging_syslog (void)
99{
100 char template[] = "/tmp/XXXXXX";
101
102 char buf[512] = {0};
103 FILE* fp = NULL;
104
105 extern int logging_flags;
106 const char *expected = "whoopsie: whoopsie " VERSION " starting up.\nwhoopsie: Hello.\n";
107
108 logging_flags = LOG_PERROR;
109 foreground = 0;
110
111 int fd;
112 fpos_t pos;
113
114 /* http://c-faq.com/stdio/undofreopen.html */
115 fflush (stderr);
116 fgetpos (stderr, &pos);
117 fd = dup (fileno (stderr));
118
119 tmpnam (template);
120 if (freopen (template, "w", stderr) == NULL) {
121 g_print ("Could not open temporary stderr.\n");
122 g_test_fail ();
123 goto out;
124 }
125
126 open_log ();
127 log_msg ("Hello.\n");
128 fflush (stderr);
129 close_log ();
130
131 /* Did we write a log file? */
132 if (access (template, F_OK) < 0) {
133 g_print ("We did not write anything to stderr.\n");
134 g_test_fail ();
135 }
136
137 /* Now ensure we've logged exactly what was expected. */
138 if ((fp = fopen (template, "r")) == NULL) {
139 g_print ("Could not open temporary stderr for reading.\n");
140 g_test_fail ();
141 }
142
143 fread (buf, 512, 1, fp);
144 if (strcmp (buf, expected) != 0) {
145 g_print ("We did not write what was expected to stderr:\n%s", buf);
146 g_test_fail ();
147 }
148
149 /* Clean up */
150 if (fclose (fp))
151 g_print ("Could not close the file pointer.\n");
152
153 if (unlink (template) < 0) {
154 g_print ("Could not remove temporary stderr.\n");
155 g_test_fail ();
156 }
157out:
158 dup2 (fd, fileno (stderr));
159 close (fd);
160 clearerr (stderr);
161 fsetpos (stderr, &pos);
162}
163
164int
165main (int argc, char** argv)
166{
167#if GLIB_MAJOR_VERSION <= 2 && GLIB_MINOR_VERSION < 35
168 /* Deprecated in glib 2.35/2.36. */
169 g_type_init ();
170#endif
171 g_test_init (&argc, &argv, NULL);
172 g_test_add_func ("/whoopsie/logging",
173 test_logging);
174 g_test_add_func ("/whoopsie/logging-syslog",
175 test_logging_syslog);
176 return g_test_run ();
177}
0178
=== modified file 'src/tests/test_monitor.c'
--- src/tests/test_monitor.c 2013-02-06 17:22:07 +0000
+++ src/tests/test_monitor.c 2013-08-08 08:46:01 +0000
@@ -1,6 +1,6 @@
1/* whoopsie1/* whoopsie
2 * 2 *
3 * Copyright © 2011-2012 Canonical Ltd.3 * Copyright © 2011-2013 Canonical Ltd.
4 * Author: Evan Dandrea <evan.dandrea@canonical.com>4 * Author: Evan Dandrea <evan.dandrea@canonical.com>
5 * 5 *
6 * This program is free software: you can redistribute it and/or modify6 * This program is free software: you can redistribute it and/or modify
@@ -215,7 +215,10 @@
215int215int
216main (int argc, char** argv)216main (int argc, char** argv)
217{217{
218#if GLIB_MAJOR_VERSION <= 2 && GLIB_MINOR_VERSION < 35
219 /* Deprecated in glib 2.35/2.36. */
218 g_type_init ();220 g_type_init ();
221#endif
219 g_test_init (&argc, &argv, NULL);222 g_test_init (&argc, &argv, NULL);
220 g_test_add_func ("/whoopsie/callback-never-triggered",223 g_test_add_func ("/whoopsie/callback-never-triggered",
221 test_callback_never_triggered);224 test_callback_never_triggered);
222225
=== modified file 'src/tests/test_parse_report.c'
--- src/tests/test_parse_report.c 2013-01-31 14:39:18 +0000
+++ src/tests/test_parse_report.c 2013-08-08 08:46:01 +0000
@@ -1,6 +1,6 @@
1/* whoopsie1/* whoopsie
2 * 2 *
3 * Copyright © 2011-2012 Canonical Ltd.3 * Copyright © 2011-2013 Canonical Ltd.
4 * Author: Evan Dandrea <evan.dandrea@canonical.com>4 * Author: Evan Dandrea <evan.dandrea@canonical.com>
5 * 5 *
6 * This program is free software: you can redistribute it and/or modify6 * This program is free software: you can redistribute it and/or modify
@@ -381,7 +381,10 @@
381int381int
382main (int argc, char** argv)382main (int argc, char** argv)
383{383{
384#if GLIB_MAJOR_VERSION <= 2 && GLIB_MINOR_VERSION < 35
385 /* Deprecated in glib 2.35/2.36. */
384 g_type_init ();386 g_type_init ();
387#endif
385 g_test_init (&argc, &argv, NULL);388 g_test_init (&argc, &argv, NULL);
386389
387 g_test_add_func ("/whoopsie/parse-report", test_parse_report);390 g_test_add_func ("/whoopsie/parse-report", test_parse_report);
388391
=== modified file 'src/tests/test_utils.c'
--- src/tests/test_utils.c 2013-01-31 14:39:18 +0000
+++ src/tests/test_utils.c 2013-08-08 08:46:01 +0000
@@ -1,6 +1,6 @@
1/* whoopsie1/* whoopsie
2 * 2 *
3 * Copyright © 2011-2012 Canonical Ltd.3 * Copyright © 2011-2013 Canonical Ltd.
4 * Author: Evan Dandrea <evan.dandrea@canonical.com>4 * Author: Evan Dandrea <evan.dandrea@canonical.com>
5 * 5 *
6 * This program is free software: you can redistribute it and/or modify6 * This program is free software: you can redistribute it and/or modify
@@ -213,7 +213,10 @@
213int213int
214main (int argc, char** argv)214main (int argc, char** argv)
215{215{
216#if GLIB_MAJOR_VERSION <= 2 && GLIB_MINOR_VERSION < 35
217 /* Deprecated in glib 2.35/2.36. */
216 g_type_init ();218 g_type_init ();
219#endif
217 g_test_init (&argc, &argv, NULL);220 g_test_init (&argc, &argv, NULL);
218 g_test_add_func ("/whoopsie/change-file-extension", test_change_file_extension);221 g_test_add_func ("/whoopsie/change-file-extension", test_change_file_extension);
219 g_test_add_func ("/whoopsie/already-handled-report", test_already_handled_report);222 g_test_add_func ("/whoopsie/already-handled-report", test_already_handled_report);
220223
=== modified file 'src/utils.c'
--- src/utils.c 2013-01-31 14:39:18 +0000
+++ src/utils.c 2013-08-08 08:46:01 +0000
@@ -1,6 +1,6 @@
1/* whoopsie1/* whoopsie
2 * 2 *
3 * Copyright © 2011-2012 Canonical Ltd.3 * Copyright © 2011-2013 Canonical Ltd.
4 * Author: Evan Dandrea <evan.dandrea@canonical.com>4 * Author: Evan Dandrea <evan.dandrea@canonical.com>
5 * 5 *
6 * This program is free software: you can redistribute it and/or modify6 * This program is free software: you can redistribute it and/or modify
77
=== modified file 'src/utils.h'
--- src/utils.h 2012-03-27 13:38:10 +0000
+++ src/utils.h 2013-08-08 08:46:01 +0000
@@ -1,6 +1,6 @@
1/* whoopsie1/* whoopsie
2 * 2 *
3 * Copyright © 2011-2012 Canonical Ltd.3 * Copyright © 2011-2013 Canonical Ltd.
4 * Author: Evan Dandrea <evan.dandrea@canonical.com>4 * Author: Evan Dandrea <evan.dandrea@canonical.com>
5 * 5 *
6 * This program is free software: you can redistribute it and/or modify6 * This program is free software: you can redistribute it and/or modify
77
=== modified file 'src/whoopsie.c'
--- src/whoopsie.c 2013-07-26 15:16:39 +0000
+++ src/whoopsie.c 2013-08-08 08:46:01 +0000
@@ -1,6 +1,6 @@
1/* whoopsie1/* whoopsie
2 * 2 *
3 * Copyright © 2011-2012 Canonical Ltd.3 * Copyright © 2011-2013 Canonical Ltd.
4 * Author: Evan Dandrea <evan.dandrea@canonical.com>4 * Author: Evan Dandrea <evan.dandrea@canonical.com>
5 * 5 *
6 * This program is free software: you can redistribute it and/or modify6 * This program is free software: you can redistribute it and/or modify
@@ -46,6 +46,8 @@
46#include "connectivity.h"46#include "connectivity.h"
47#include "monitor.h"47#include "monitor.h"
48#include "identifier.h"48#include "identifier.h"
49#include "logging.h"
50#include "globals.h"
4951
50/* The length of time to wait before processing outstanding crashes, in seconds52/* The length of time to wait before processing outstanding crashes, in seconds
51 */53 */
@@ -58,6 +60,9 @@
58/* The URL of the crash database. */60/* The URL of the crash database. */
59static char* crash_db_url = NULL;61static char* crash_db_url = NULL;
6062
63/* Username we will run under */
64static const char* username = "whoopsie";
65
61/* The database identifier. Either:66/* The database identifier. Either:
62 * - The system UUID, taken from the DMI tables and SHA-512 hashed67 * - The system UUID, taken from the DMI tables and SHA-512 hashed
63 * - The MAC address of the first non-loopback device, SHA-512 hashed */68 * - The MAC address of the first non-loopback device, SHA-512 hashed */
@@ -66,9 +71,6 @@
66/* The URL for sending the initial crash report */71/* The URL for sending the initial crash report */
67static char* crash_db_submit_url = NULL;72static char* crash_db_submit_url = NULL;
6873
69/* Username we will run under */
70static const char username[] = "whoopsie";
71
72/* The file path and descriptor for our instance lock */74/* The file path and descriptor for our instance lock */
73static const char* lock_path = "/var/lock/whoopsie/lock";75static const char* lock_path = "/var/lock/whoopsie/lock";
74static int lock_fd = 0;76static int lock_fd = 0;
@@ -77,10 +79,9 @@
77static const char* report_dir = "/var/crash";79static const char* report_dir = "/var/crash";
7880
79/* Options */81/* Options */
82int foreground = 0;
8083
81#ifndef TEST84#ifndef TEST
82static gboolean foreground = FALSE;
83
84static GOptionEntry option_entries[] = {85static GOptionEntry option_entries[] = {
85 { "foreground", 'f', 0, G_OPTION_ARG_NONE, &foreground,86 { "foreground", 'f', 0, G_OPTION_ARG_NONE, &foreground,
86 "Run in the foreground", NULL },87 "Run in the foreground", NULL },
@@ -264,12 +265,12 @@
264 /* TODO use curl_share for DNS caching. */265 /* TODO use curl_share for DNS caching. */
265 /* Repeated calls to curl_global_init will have no effect. */266 /* Repeated calls to curl_global_init will have no effect. */
266 if (curl_global_init (CURL_GLOBAL_SSL)) {267 if (curl_global_init (CURL_GLOBAL_SSL)) {
267 g_print ("Unable to initialize curl.\n\n");268 log_msg ("Unable to initialize curl.\n\n");
268 exit (EXIT_FAILURE);269 exit (EXIT_FAILURE);
269 }270 }
270271
271 if ((curl = curl_easy_init ()) == NULL) {272 if ((curl = curl_easy_init ()) == NULL) {
272 printf ("Couldn't init curl.\n");273 log_msg ("Couldn't init curl.\n");
273 return FALSE;274 return FALSE;
274 }275 }
275 curl_easy_setopt (curl, CURLOPT_POST, 1);276 curl_easy_setopt (curl, CURLOPT_POST, 1);
@@ -288,9 +289,9 @@
288 curl_slist_free_all(list);289 curl_slist_free_all(list);
289 curl_easy_getinfo (curl, CURLINFO_RESPONSE_CODE, &response_code);290 curl_easy_getinfo (curl, CURLINFO_RESPONSE_CODE, &response_code);
290291
291 printf ("Sent; server replied with: %s\n",292 log_msg ("Sent; server replied with: %s\n",
292 curl_easy_strerror (result_code));293 curl_easy_strerror (result_code));
293 printf ("Response code: %ld\n", response_code);294 log_msg ("Response code: %ld\n", response_code);
294 curl_easy_cleanup (curl);295 curl_easy_cleanup (curl);
295296
296 if (result_code != CURLE_OK)297 if (result_code != CURLE_OK)
@@ -515,7 +516,7 @@
515 /* TODO use CURLOPT_READFUNCTION to transparently compress data with516 /* TODO use CURLOPT_READFUNCTION to transparently compress data with
516 * Snappy. */517 * Snappy. */
517 if ((curl = curl_easy_init ()) == NULL) {518 if ((curl = curl_easy_init ()) == NULL) {
518 printf ("Couldn't init curl.\n");519 log_msg ("Couldn't init curl.\n");
519 g_free (crash_db_core_url);520 g_free (crash_db_core_url);
520 return FALSE;521 return FALSE;
521 }522 }
@@ -536,9 +537,9 @@
536537
537 curl_easy_getinfo (curl, CURLINFO_RESPONSE_CODE, &response_code);538 curl_easy_getinfo (curl, CURLINFO_RESPONSE_CODE, &response_code);
538539
539 printf ("Sent; server replied with: %s\n",540 log_msg ("Sent; server replied with: %s\n",
540 curl_easy_strerror (result_code));541 curl_easy_strerror (result_code));
541 printf ("Response code: %ld\n", response_code);542 log_msg ("Response code: %ld\n", response_code);
542 curl_easy_cleanup (curl);543 curl_easy_cleanup (curl);
543 g_free (crash_db_core_url);544 g_free (crash_db_core_url);
544 destroy_response_string (&s);545 destroy_response_string (&s);
@@ -568,11 +569,11 @@
568 /* We do not retry the upload. Once is a big enough hit to569 /* We do not retry the upload. Once is a big enough hit to
569 * their Internet connection, and we can always count on570 * their Internet connection, and we can always count on
570 * the next person in line to send it. */571 * the next person in line to send it. */
571 printf ("Upload of the core dump failed.\n");572 log_msg ("Upload of the core dump failed.\n");
572 } else573 } else
573 printf ("Asked for a core dump that we don't have.\n");574 log_msg ("Asked for a core dump that we don't have.\n");
574 } else575 } else
575 printf ("Got command: %s\n", command);576 log_msg ("Got command: %s\n", command);
576 }577 }
577}578}
578579
@@ -588,28 +589,28 @@
588 bson b[1];589 bson b[1];
589 int response = 0;590 int response = 0;
590591
591 g_print ("Parsing %s.\n", crash_file);592 log_msg ("Parsing %s.\n", crash_file);
592 report = parse_report (crash_file, FALSE, &error);593 report = parse_report (crash_file, FALSE, &error);
593 if (!report) {594 if (!report) {
594 if (error) {595 if (error) {
595 g_print ("Unable to parse report (%s): %s\n", crash_file,596 log_msg ("Unable to parse report (%s): %s\n", crash_file,
596 error->message);597 error->message);
597 g_error_free (error);598 g_error_free (error);
598 } else {599 } else {
599 g_print ("Unable to parse report (%s)\n", crash_file);600 log_msg ("Unable to parse report (%s)\n", crash_file);
600 }601 }
601 /* Do not keep trying to parse and upload this */602 /* Do not keep trying to parse and upload this */
602 return TRUE;603 return TRUE;
603 }604 }
604605
605 if (!bsonify (report, b, &message_data, &message_len)) {606 if (!bsonify (report, b, &message_data, &message_len)) {
606 g_print ("Unable to bsonify report (%s)\n", crash_file);607 log_msg ("Unable to bsonify report (%s)\n", crash_file);
607 if (bson_data (b))608 if (bson_data (b))
608 bson_destroy (b);609 bson_destroy (b);
609 /* Do not keep trying to parse and upload this */610 /* Do not keep trying to parse and upload this */
610 success = TRUE;611 success = TRUE;
611 } else {612 } else {
612 g_print ("Uploading %s.\n", crash_file);613 log_msg ("Uploading %s.\n", crash_file);
613 init_response_string (&s);614 init_response_string (&s);
614 response = upload_report (message_data, message_len, &s);615 response = upload_report (message_data, message_len, &s);
615 if (bson_data (b))616 if (bson_data (b))
@@ -625,7 +626,7 @@
625 success = FALSE;626 success = FALSE;
626627
627 if (response > 200)628 if (response > 200)
628 g_print ("Server replied with:\n%s\n", s.p);629 log_msg ("Server replied with:\n%s\n", s.p);
629630
630 if (response == 200 && s.length > 0)631 if (response == 200 && s.length > 0)
631 handle_response (report, s.p);632 handle_response (report, s.p);
@@ -672,7 +673,7 @@
672 continue;673 continue;
673 } else if (online_state && parse_and_upload_report (crash_file)) {674 } else if (online_state && parse_and_upload_report (crash_file)) {
674 if (!mark_handled (crash_file))675 if (!mark_handled (crash_file))
675 g_print ("Unable to mark report as seen (%s)\n", crash_file);676 log_msg ("Unable to mark report as seen (%s)\n", crash_file);
676677
677 } 678 }
678679
@@ -691,7 +692,7 @@
691 struct rlimit rl = {0};692 struct rlimit rl = {0};
692693
693 if (getrlimit (RLIMIT_NOFILE, &rl) < 0) {694 if (getrlimit (RLIMIT_NOFILE, &rl) < 0) {
694 g_print ("Could not get resource limits.\n");695 log_msg ("Could not get resource limits.\n");
695 exit (EXIT_FAILURE);696 exit (EXIT_FAILURE);
696 }697 }
697698
@@ -713,7 +714,7 @@
713 if ((open ("/dev/null", O_RDWR) != 0) ||714 if ((open ("/dev/null", O_RDWR) != 0) ||
714 (dup (0) != 1) ||715 (dup (0) != 1) ||
715 (dup (0) != 2)) {716 (dup (0) != 2)) {
716 g_print ("Could not redirect file descriptors to /dev/null.\n");717 log_msg ("Could not redirect file descriptors to /dev/null.\n");
717 exit (EXIT_FAILURE);718 exit (EXIT_FAILURE);
718 }719 }
719}720}
@@ -730,21 +731,21 @@
730 /* use system directory */731 /* use system directory */
731 if (mkdir ("/var/lock/whoopsie", 0755) < 0) {732 if (mkdir ("/var/lock/whoopsie", 0755) < 0) {
732 if (errno != EEXIST) {733 if (errno != EEXIST) {
733 g_print ("Could not create lock directory.\n");734 log_msg ("Could not create lock directory.\n");
734 }735 }
735 }736 }
736 }737 }
737738
738 g_print("Using lock path: %s\n", lock_path);739 log_msg ("Using lock path: %s\n", lock_path);
739740
740 lock_fd = open (lock_path, O_CREAT | O_RDWR, 0600);741 lock_fd = open (lock_path, O_CREAT | O_RDWR, 0600);
741 rc = flock (lock_fd, LOCK_EX | LOCK_NB);742 rc = flock (lock_fd, LOCK_EX | LOCK_NB);
742 if (rc) {743 if (rc) {
743 if (EWOULDBLOCK == errno) {744 if (EWOULDBLOCK == errno) {
744 g_print ("Another instance is already running.\n");745 log_msg ("Another instance is already running.\n");
745 exit (1);746 exit (1);
746 } else {747 } else {
747 g_print ("Could not create lock file: %s\n", strerror (errno));748 log_msg ("Could not create lock file: %s\n", strerror (errno));
748 }749 }
749 }750 }
750}751}
@@ -806,7 +807,7 @@
806void807void
807network_changed (gboolean available)808network_changed (gboolean available)
808{809{
809 g_print (available ? "online\n" : "offline\n");810 log_msg (available ? "online\n" : "offline\n");
810 if (!available) {811 if (!available) {
811 online_state = FALSE;812 online_state = FALSE;
812 return;813 return;
@@ -825,12 +826,12 @@
825check_online_then_upload (const char* crash_file) {826check_online_then_upload (const char* crash_file) {
826827
827 if (!online_state) {828 if (!online_state) {
828 g_print ("Not online; processing later (%s).\n", crash_file);829 log_msg ("Not online; processing later (%s).\n", crash_file);
829 return FALSE;830 return FALSE;
830 }831 }
831832
832 if (!parse_and_upload_report (crash_file)) {833 if (!parse_and_upload_report (crash_file)) {
833 g_print ("Could not upload; processing later (%s).\n", crash_file);834 log_msg ("Could not upload; processing later (%s).\n", crash_file);
834 return FALSE;835 return FALSE;
835 }836 }
836837
@@ -838,31 +839,32 @@
838}839}
839840
840void841void
841create_directory (void)842create_crash_directory (void)
842{843{
843 struct passwd *pw = NULL;844 struct passwd *pw = NULL;
844845
845 if (mkdir (report_dir, 0755) < 0) {846 if (mkdir (report_dir, 0755) < 0) {
846 if (errno != EEXIST) {847 if (errno != EEXIST) {
847 g_print ("Could not create non-existent directory to monitor (%d): %s.\n", errno, report_dir);848 log_msg ("Could not create non-existent report_directory to monitor (%d): %s.\n", errno, report_dir);
848 exit (EXIT_FAILURE);849 exit (EXIT_FAILURE);
849 }850 }
850 } else {851 } else {
851 /* Only change the permissions if we've just created it */852 /* Only change the permissions if we've just created it */
852 if (!(pw = getpwnam (username))) {853 if (!(pw = getpwnam (username))) {
853 g_print ("Could not find user, %s.\n", username);854 log_msg ("Could not find user, %s.\n", username);
854 exit (EXIT_FAILURE);855 exit (EXIT_FAILURE);
855 }856 }
856 if (chown (report_dir, -1, pw->pw_gid) < 0) {857 if (chown (report_dir, -1, pw->pw_gid) < 0) {
857 g_print ("Could not change ownership of %s.\n", report_dir);858 log_msg ("Could not change ownership of %s.\n", report_dir);
858 exit (EXIT_FAILURE);859 exit (EXIT_FAILURE);
859 }860 }
860 if (chmod (report_dir, 03777) < 0) {861 if (chmod (report_dir, 03777) < 0) {
861 g_print ("Could not change permissions on %s.\n", report_dir);862 log_msg ("Could not change permissions on %s.\n", report_dir);
862 exit (EXIT_FAILURE);863 exit (EXIT_FAILURE);
863 }864 }
864 }865 }
865}866}
867
866#ifndef TEST868#ifndef TEST
867static GMainLoop* loop = NULL;869static GMainLoop* loop = NULL;
868870
@@ -875,7 +877,7 @@
875 context = g_option_context_new (NULL);877 context = g_option_context_new (NULL);
876 g_option_context_add_main_entries (context, option_entries, NULL);878 g_option_context_add_main_entries (context, option_entries, NULL);
877 if (!g_option_context_parse (context, argc, argv, &err)) {879 if (!g_option_context_parse (context, argc, argv, &err)) {
878 g_print ("whoopsie: %s\n", err->message);880 log_msg ("whoopsie: %s\n", err->message);
879 g_error_free (err);881 g_error_free (err);
880 exit (EXIT_FAILURE);882 exit (EXIT_FAILURE);
881 }883 }
@@ -916,10 +918,13 @@
916 parse_arguments (&argc, &argv);918 parse_arguments (&argc, &argv);
917919
918 if ((crash_db_url = get_crash_db_url ()) == NULL) {920 if ((crash_db_url = get_crash_db_url ()) == NULL) {
919 g_print ("Could not get crash database location.\n");921 log_msg ("Could not get crash database location.\n");
920 exit (EXIT_FAILURE);922 exit (EXIT_FAILURE);
921 }923 }
922924
925 if (!foreground)
926 open_log ();
927
923 /* environment might change report directory and identifier */928 /* environment might change report directory and identifier */
924 env = g_getenv ("APPORT_REPORT_DIR");929 env = g_getenv ("APPORT_REPORT_DIR");
925 if (env != NULL)930 if (env != NULL)
@@ -932,7 +937,7 @@
932 whoopsie_identifier_generate (&whoopsie_identifier, &err);937 whoopsie_identifier_generate (&whoopsie_identifier, &err);
933938
934 if (err) {939 if (err) {
935 g_print ("%s\n", err->message);940 log_msg ("%s\n", err->message);
936 g_error_free (err);941 g_error_free (err);
937 err = NULL;942 err = NULL;
938 crash_db_submit_url = strdup (crash_db_url);943 crash_db_submit_url = strdup (crash_db_url);
@@ -942,11 +947,11 @@
942 whoopsie_identifier);947 whoopsie_identifier);
943 }948 }
944949
945 create_directory ();950 create_crash_directory ();
946951
947 drop_privileges (&err);952 drop_privileges (&err);
948 if (err) {953 if (err) {
949 g_print ("%s\n", err->message);954 log_msg ("%s\n", err->message);
950 g_error_free (err);955 g_error_free (err);
951 exit (EXIT_FAILURE);956 exit (EXIT_FAILURE);
952 }957 }
@@ -975,6 +980,8 @@
975 unmonitor_directory (monitor, check_online_then_upload);980 unmonitor_directory (monitor, check_online_then_upload);
976 unmonitor_connectivity ();981 unmonitor_connectivity ();
977982
983 close_log ();
984
978 g_unlink (lock_path);985 g_unlink (lock_path);
979 close (lock_fd);986 close (lock_fd);
980 curl_global_cleanup ();987 curl_global_cleanup ();
981988
=== modified file 'src/whoopsie.h'
--- src/whoopsie.h 2013-07-26 15:16:39 +0000
+++ src/whoopsie.h 2013-08-08 08:46:01 +0000
@@ -1,6 +1,6 @@
1/* whoopsie1/* whoopsie
2 * 2 *
3 * Copyright © 2011-2012 Canonical Ltd.3 * Copyright © 2011-2013 Canonical Ltd.
4 * Author: Evan Dandrea <evan.dandrea@canonical.com>4 * Author: Evan Dandrea <evan.dandrea@canonical.com>
5 * 5 *
6 * This program is free software: you can redistribute it and/or modify6 * 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: