Add Native platform information log on/off option
[framework/system/dlog.git] / log.c
diff --git a/log.c b/log.c
index ac14f05..ef91176 100755 (executable)
--- a/log.c
+++ b/log.c
@@ -1,4 +1,4 @@
-/*
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: t -*-
  * DLOG
  * Copyright (c) 2005-2008, The Android Open Source Project
  * Copyright (c) 2012-2013 Samsung Electronics Co., Ltd.
@@ -15,6 +15,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+#include "config.h"
 #include <pthread.h>
 #include <stdlib.h>
 #include <string.h>
@@ -24,7 +25,8 @@
 #include <stdio.h>
 #include <errno.h>
 #include <dlog.h>
-#ifdef SD_JOURNAL_SUPPORT
+#ifdef HAVE_SYSTEMD_JOURNAL
+#define SD_JOURNAL_SUPPRESS_LOCATION 1
 #include <syslog.h>
 #include <systemd/sd-journal.h>
 #endif
 #define LOG_SYSTEM     "log_system"
 #define LOG_APPS       "log_apps"
 
-static int log_fds[(int)LOG_ID_MAX] = { -1, -1, -1, -1 };
-
-static int g_logging_on = 1;
-static int g_dlog_level = DLOG_SILENT;
+#define VALUE_MAX 2
+#define PLATFORMLOG_CONF "/tmp/.platformlog.conf"
+#define PLATFORMLOG_ORG_CONF "/opt/etc/platformlog.conf"
 
-static int __dlog_init(log_id_t, log_priority, const char *tag, const char *msg);
-static int (*write_to_log)(log_id_t, log_priority, const char *tag, const char *msg) = __dlog_init;
+static int platformlog = 0;
+static int log_fds[(int)LOG_ID_MAX] = { -1, -1, -1, -1 };
+static int (*write_to_log)(log_id_t, log_priority, const char *tag, const char *msg) = NULL;
 static pthread_mutex_t log_init_lock = PTHREAD_MUTEX_INITIALIZER;
+
 static int __write_to_log_null(log_id_t log_id, log_priority prio, const char *tag, const char *msg)
 {
        return -1;
@@ -53,13 +56,6 @@ static int __write_to_log_kernel(log_id_t log_id, log_priority prio, const char
        int log_fd;
        struct iovec vec[3];
 
-       if (log_id < LOG_ID_APPS) {
-               if(prio < g_dlog_level) {
-                       return 0;
-               }
-       } else if (LOG_ID_MAX <= log_id) {
-               return 0;
-       }
        if (log_id < LOG_ID_MAX)
                log_fd = log_fds[log_id];
        else
@@ -82,133 +78,142 @@ static int __write_to_log_kernel(log_id_t log_id, log_priority prio, const char
 
        return ret;
 }
+
 static char dlog_pri_to_char (log_priority pri)
 {
-       switch (pri) {
-               case DLOG_VERBOSE:       return 'V';
-               case DLOG_DEBUG:         return 'D';
-               case DLOG_INFO:          return 'I';
-               case DLOG_WARN:          return 'W';
-               case DLOG_ERROR:         return 'E';
-               case DLOG_FATAL:         return 'F';
-               case DLOG_SILENT:        return 'S';
-
-               case DLOG_DEFAULT:
-               case DLOG_UNKNOWN:
-               default:
-                                                                return '?';
-       }
+       static const char pri_table[DLOG_PRIO_MAX] = {
+               [DLOG_VERBOSE] = 'V',
+               [DLOG_DEBUG] = 'D',
+               [DLOG_INFO] = 'I',
+               [DLOG_WARN] = 'W',
+               [DLOG_ERROR] = 'E',
+               [DLOG_FATAL] = 'F',
+               [DLOG_SILENT] = 'S',
+       };
+
+       if (pri < 0 || DLOG_PRIO_MAX <= pri || !pri_table[pri])
+               return '?';
+       return pri_table[pri];
 }
-#ifdef SD_JOURNAL_SUPPORT
-static int dlog_pri_to_journal_pri(log_priority prio)
+
+#ifdef HAVE_SYSTEMD_JOURNAL
+static inline int dlog_pri_to_journal_pri(log_priority prio)
 {
-       int journal_prio = LOG_DEBUG;
-
-       switch(prio) {
-       case DLOG_UNKNOWN:
-       case DLOG_DEFAULT:
-       case DLOG_VERBOSE:
-               journal_prio = LOG_DEBUG;
-               break;
-       case DLOG_DEBUG:
-               journal_prio = LOG_DEBUG;
-               break;
-       case DLOG_INFO:
-               journal_prio = LOG_INFO;
-               break;
-       case DLOG_WARN:
-               journal_prio = LOG_WARNING;
-               break;
-       case DLOG_ERROR:
-               journal_prio = LOG_ERR;
-               break;
-       case DLOG_FATAL:
-               journal_prio = LOG_CRIT;
-               break;
-       case DLOG_SILENT:
-       default:
-               journal_prio = -1;
-               break;
-       }
-       return journal_prio;
+       static int pri_table[DLOG_PRIO_MAX] = {
+               [DLOG_UNKNOWN] = LOG_DEBUG,
+               [DLOG_DEFAULT] = LOG_DEBUG,
+               [DLOG_VERBOSE] = LOG_DEBUG,
+               [DLOG_DEBUG] = LOG_DEBUG,
+               [DLOG_INFO] = LOG_INFO,
+               [DLOG_WARN] = LOG_WARNING,
+               [DLOG_ERROR] = LOG_ERR,
+               [DLOG_FATAL] = LOG_CRIT,
+               [DLOG_SILENT] = -1,
+       };
+
+       if (prio < 0 || prio >= DLOG_PRIO_MAX)
+               return -EINVAL;
+
+       return pri_table[prio];
 }
-static int __write_to_log_sd_journal_print(log_id_t log_id, log_priority prio, const char *tag, const char *msg)
+
+static inline const char* dlog_id_to_string(log_id_t log_id)
 {
-       ssize_t ret;
-       int log_fd;
+       static const char* id_table[LOG_ID_MAX] = {
+               [LOG_ID_MAIN]   = LOG_MAIN,
+               [LOG_ID_RADIO]  = LOG_RADIO,
+               [LOG_ID_SYSTEM] = LOG_SYSTEM,
+               [LOG_ID_APPS]   = LOG_APPS,
+       };
 
-       if (log_id < LOG_ID_APPS) {
-               if(prio < g_dlog_level) {
-                       return 0;
-               }
-       } else if (LOG_ID_MAX <= log_id) {
-               return 0;
-       }
-       if (log_id < LOG_ID_MAX)
-               log_fd = log_fds[log_id];
-       else
-               return -1;
-       return sd_journal_print(dlog_pri_to_journal_pri(prio), "%c %s: %s",dlog_pri_to_char(prio), tag, msg);
+       if (log_id < 0 || log_id >= LOG_ID_MAX || !id_table[log_id])
+               return "UNKNOWN";
+
+       return id_table[log_id];
+}
+
+static int __write_to_log_sd_journal(log_id_t log_id, log_priority prio, const char *tag, const char *msg)
+{
+       /* XXX: sd_journal_sendv() with manually filed iov-s might be faster */
+       return sd_journal_send("MESSAGE=%s", msg,
+                              "PRIORITY=%i", dlog_pri_to_journal_pri(prio),
+                              "DLOG_PRIORITY=%d", prio,
+                              "DLOG_TAG=%s", tag,
+                              "DLOG_ID=%s", dlog_id_to_string(log_id),
+                              NULL);
 }
 #endif
-void init_dlog_level(void)
+
+static int __read_config(char *file, int *value)
 {
-       char *dlog_level_env;
-       char *logging_mode_env;
-       if (g_logging_on) {
-               logging_mode_env = getenv("TIZEN_PLATFORMLOGGING_MODE");
-               if (!logging_mode_env)
-                               g_logging_on = 0;
-                       else
-                               g_logging_on = atoi(logging_mode_env);
+       int fd, ret;
+       char val[VALUE_MAX];
+
+       if (file == NULL || value == NULL)
+               return 0;
+       memset(val, 0, sizeof(val));
+       fd = open(file, O_RDONLY);
+       if (fd < 0) {
+               return 0;
        }
-       if (g_logging_on) {
-               dlog_level_env = getenv("TIZEN_DLOG_LEVEL");
-               if (!dlog_level_env) {
-                       g_dlog_level = 8;
-               } else {
-                       g_dlog_level = atoi(dlog_level_env);
-               }
-       } else
-               g_dlog_level = 8;
+       ret = read(fd, val, 1);
+       close(fd);
+       if (ret != 1)
+               return 0;
+       *value = atoi(val);
+       return 1;
+}
+
+static void __configure(void)
+{
+       int ret;
+       ret = __read_config(PLATFORMLOG_CONF, &platformlog);
+       if (!ret)
+               ret = __read_config(PLATFORMLOG_ORG_CONF, &platformlog);
+       if (!ret)
+               platformlog = 0;
 }
-static int __dlog_init(log_id_t log_id, log_priority prio, const char *tag, const char *msg)
+
+static void __dlog_init(void)
 {
        pthread_mutex_lock(&log_init_lock);
-       // get filtering info
-       // open device
-       if (write_to_log == __dlog_init) {
-               init_dlog_level();
-
-               log_fds[LOG_ID_MAIN] = open("/dev/"LOG_MAIN, O_WRONLY);
-               log_fds[LOG_ID_RADIO] = open("/dev/"LOG_RADIO, O_WRONLY);
-               log_fds[LOG_ID_SYSTEM] = open("/dev/"LOG_SYSTEM, O_WRONLY);
-               log_fds[LOG_ID_APPS] = open("/dev/"LOG_APPS, O_WRONLY);
-
-               if (log_fds[LOG_ID_MAIN] < 0 || log_fds[LOG_ID_RADIO] < 0) {
-                       write_to_log = __write_to_log_null;
-               } else {
-#ifdef SD_JOURNAL_SUPPORT
-                       write_to_log = __write_to_log_sd_journal_print;
+       /* configuration */
+       __configure();
+       /* open device */
+       log_fds[LOG_ID_MAIN] = open("/dev/"LOG_MAIN, O_WRONLY);
+       log_fds[LOG_ID_RADIO] = open("/dev/"LOG_RADIO, O_WRONLY);
+       log_fds[LOG_ID_SYSTEM] = open("/dev/"LOG_SYSTEM, O_WRONLY);
+       log_fds[LOG_ID_APPS] = open("/dev/"LOG_APPS, O_WRONLY);
+       if (log_fds[LOG_ID_MAIN] < 0 || log_fds[LOG_ID_RADIO] < 0) {
+               write_to_log = __write_to_log_null;
+       } else {
+#ifdef HAVE_SYSTEMD_JOURNAL
+               write_to_log = __write_to_log_sd_journal;
 #else
-                       write_to_log = __write_to_log_kernel;
+               write_to_log = __write_to_log_kernel;
 #endif
-               }
-
-               if (log_fds[LOG_ID_SYSTEM] < 0)
-                       log_fds[LOG_ID_SYSTEM] = log_fds[LOG_ID_MAIN];
-
-               if (log_fds[LOG_ID_APPS] < 0)
-                       log_fds[LOG_ID_APPS] = log_fds[LOG_ID_MAIN];
        }
+
+       if (log_fds[LOG_ID_SYSTEM] < 0)
+               log_fds[LOG_ID_SYSTEM] = log_fds[LOG_ID_MAIN];
+       if (log_fds[LOG_ID_APPS] < 0)
+               log_fds[LOG_ID_APPS] = log_fds[LOG_ID_MAIN];
        pthread_mutex_unlock(&log_init_lock);
-       return write_to_log(log_id, prio, tag, msg);
 }
 
 int __dlog_vprint(log_id_t log_id, int prio, const char *tag, const char *fmt, va_list ap)
 {
        char buf[LOG_BUF_SIZE];
 
+       if (LOG_ID_MAX <= log_id)
+               return 0;
+
+       if (write_to_log == NULL)
+               __dlog_init();
+
+       if (log_id != LOG_ID_APPS && !platformlog)
+               return 0;
+
        vsnprintf(buf, LOG_BUF_SIZE, fmt, ap);
 
        return write_to_log(log_id, prio, tag, buf);
@@ -219,13 +224,23 @@ int __dlog_print(log_id_t log_id, int prio, const char *tag, const char *fmt, ..
        va_list ap;
        char buf[LOG_BUF_SIZE];
 
+       if (LOG_ID_MAX <= log_id)
+               return 0;
+
+       if (write_to_log == NULL)
+               __dlog_init();
+
+       if (log_id != LOG_ID_APPS && !platformlog)
+               return 0;
+
        va_start(ap, fmt);
        vsnprintf(buf, LOG_BUF_SIZE, fmt, ap);
        va_end(ap);
 
        return write_to_log(log_id, prio, tag, buf);
 }
+
 int _get_logging_on(void)
 {
-       return g_logging_on;
+       return 1;
 }