summaryrefslogtreecommitdiff
path: root/src/common/log.c
diff options
context:
space:
mode:
authorAlexander Færøy <ahf@torproject.org>2017-12-11 13:12:25 +0000
committerAlexander Færøy <ahf@torproject.org>2017-12-11 13:22:39 +0000
commitb0b8f7c30c8296344c77d06a24821f35b667e3dd (patch)
treeff08bbf8bf55a202760a61f197cf484c98875c63 /src/common/log.c
parent78a582ed880166a73be284ae799397e84fac36a3 (diff)
downloadtor-b0b8f7c30c8296344c77d06a24821f35b667e3dd.tar.gz
tor-b0b8f7c30c8296344c77d06a24821f35b667e3dd.zip
Add support for Android's logging subsystem.
This patch adds support for Android's logging subsystem in Tor. When debugging Android applications it is useful to be able to collect information about the application running on the platform via the various system services that is available on the platform. This patch allows you to add "Log notice android" to your torrc and have Tor send everything above and including the notice severity to Android's ring buffer which can be inspected using the 'adb logcat' program. See: https://bugs.torproject.org/24362
Diffstat (limited to 'src/common/log.c')
-rw-r--r--src/common/log.c80
1 files changed, 76 insertions, 4 deletions
diff --git a/src/common/log.c b/src/common/log.c
index 80055fda04..ad3d1affd5 100644
--- a/src/common/log.c
+++ b/src/common/log.c
@@ -35,6 +35,9 @@
#define LOG_PRIVATE
#include "torlog.h"
#include "container.h"
+#ifdef HAVE_ANDROID_LOG_H
+#include <android/log.h>
+#endif // HAVE_ANDROID_LOG_H.
/** Given a severity, yields an index into log_severity_list_t.masks to use
* for that severity. */
@@ -58,6 +61,8 @@ typedef struct logfile_t {
int needs_close; /**< Boolean: true if the stream gets closed on shutdown. */
int is_temporary; /**< Boolean: close after initializing logging subsystem.*/
int is_syslog; /**< Boolean: send messages to syslog. */
+ int is_android; /**< Boolean: send messages to Android's log subsystem. */
+ char *android_tag; /**< Identity Tag used in Android's log subsystem. */
log_callback callback; /**< If not NULL, send messages to this function. */
log_severity_list_t *severities; /**< Which severity of messages should we
* log for each log domain? */
@@ -103,6 +108,33 @@ should_log_function_name(log_domain_mask_t domain, int severity)
}
}
+#ifdef HAVE_ANDROID_LOG_H
+/** Helper function to convert Tor's log severity into the matching
+ * Android log priority.
+ */
+static int
+severity_to_android_log_priority(int severity)
+{
+ switch (severity) {
+ case LOG_DEBUG:
+ return ANDROID_LOG_VERBOSE;
+ case LOG_INFO:
+ return ANDROID_LOG_DEBUG;
+ case LOG_NOTICE:
+ return ANDROID_LOG_INFO;
+ case LOG_WARN:
+ return ANDROID_LOG_WARN;
+ case LOG_ERR:
+ return ANDROID_LOG_ERROR;
+ default:
+ // LCOV_EXCL_START
+ raw_assert(0);
+ return 0;
+ // LCOV_EXCL_STOP
+ }
+}
+#endif // HAVE_ANDROID_LOG_H.
+
/** A mutex to guard changes to logfiles and logging. */
static tor_mutex_t log_mutex;
/** True iff we have initialized log_mutex */
@@ -411,7 +443,7 @@ logfile_wants_message(const logfile_t *lf, int severity,
if (! (lf->severities->masks[SEVERITY_MASK_IDX(severity)] & domain)) {
return 0;
}
- if (! (lf->fd >= 0 || lf->is_syslog || lf->callback)) {
+ if (! (lf->fd >= 0 || lf->is_syslog || lf->is_android || lf->callback)) {
return 0;
}
if (lf->seems_dead) {
@@ -454,6 +486,11 @@ logfile_deliver(logfile_t *lf, const char *buf, size_t msg_len,
syslog(severity, "%s", msg_after_prefix);
#endif /* defined(MAXLINE) */
#endif /* defined(HAVE_SYSLOG_H) */
+ } else if (lf->is_android) {
+#ifdef HAVE_ANDROID_LOG_H
+ int priority = severity_to_android_log_priority(severity);
+ __android_log_write(priority, lf->android_tag, msg_after_prefix);
+#endif // HAVE_ANDROID_LOG_H.
} else if (lf->callback) {
if (domain & LD_NOCB) {
if (!*callbacks_deferred && pending_cb_messages) {
@@ -646,7 +683,7 @@ tor_log_update_sigsafe_err_fds(void)
/* Don't try callback to the control port, or syslogs: We can't
* do them from a signal handler. Don't try stdout: we always do stderr.
*/
- if (lf->is_temporary || lf->is_syslog ||
+ if (lf->is_temporary || lf->is_syslog || lf->is_android ||
lf->callback || lf->seems_dead || lf->fd < 0)
continue;
if (lf->severities->masks[SEVERITY_MASK_IDX(LOG_ERR)] &
@@ -683,7 +720,7 @@ tor_log_get_logfile_names(smartlist_t *out)
LOCK_LOGS();
for (lf = logfiles; lf; lf = lf->next) {
- if (lf->is_temporary || lf->is_syslog || lf->callback)
+ if (lf->is_temporary || lf->is_syslog || lf->is_android || lf->callback)
continue;
if (lf->filename == NULL)
continue;
@@ -732,6 +769,7 @@ log_free_(logfile_t *victim)
return;
tor_free(victim->severities);
tor_free(victim->filename);
+ tor_free(victim->android_tag);
tor_free(victim);
}
@@ -1151,6 +1189,39 @@ add_syslog_log(const log_severity_list_t *severity,
}
#endif /* defined(HAVE_SYSLOG_H) */
+#ifdef HAVE_ANDROID_LOG_H
+/**
+ * Add a log handler to send messages to the Android platform log facility.
+ */
+int
+add_android_log(const log_severity_list_t *severity,
+ const char *android_tag)
+{
+ logfile_t *lf = NULL;
+
+ lf = tor_malloc_zero(sizeof(logfile_t));
+ lf->fd = -1;
+ lf->severities = tor_memdup(severity, sizeof(log_severity_list_t));
+ lf->filename = tor_strdup("<android>");
+ lf->is_android = 1;
+
+ if (android_tag == NULL)
+ lf->android_tag = tor_strdup("Tor");
+ else {
+ char buf[256];
+ tor_snprintf(buf, sizeof(buf), "Tor-%s", android_tag);
+ lf->android_tag = tor_strdup(buf);
+ }
+
+ LOCK_LOGS();
+ lf->next = logfiles;
+ logfiles = lf;
+ log_global_min_severity_ = get_min_log_level();
+ UNLOCK_LOGS();
+ return 0;
+}
+#endif // HAVE_ANDROID_LOG_H.
+
/** If <b>level</b> is a valid log severity, return the corresponding
* numeric value. Otherwise, return -1. */
int
@@ -1318,7 +1389,8 @@ parse_log_severity_config(const char **cfg_ptr,
if (!strcasecmpstart(cfg, "file") ||
!strcasecmpstart(cfg, "stderr") ||
!strcasecmpstart(cfg, "stdout") ||
- !strcasecmpstart(cfg, "syslog")) {
+ !strcasecmpstart(cfg, "syslog") ||
+ !strcasecmpstart(cfg, "android")) {
goto done;
}
if (got_an_unqualified_range > 1)