Add file log 59/180859/5
authorjusung son <jusung07.son@samsung.com>
Tue, 5 Jun 2018 04:21:33 +0000 (13:21 +0900)
committerjusung son <jusung07.son@samsung.com>
Thu, 7 Jun 2018 01:51:14 +0000 (10:51 +0900)
Change-Id: Ieb3b8b76c1f88793081fd2111692863e1a744312
Signed-off-by: jusung son <jusung07.son@samsung.com>
client/c_direct.c
common/config.c
common/config.h
common/direct.c
common/direct.h
daemon/daemon.c
daemon/daemon.h
packaging/buxton2.conf

index 451d051..d9eda3d 100644 (file)
@@ -22,6 +22,9 @@
 #include <pwd.h>
 #include <sys/types.h>
 #include <unistd.h>
+#include <inttypes.h>
+#include <sys/stat.h>
+#include <fcntl.h>
 
 #include "common.h"
 #include "direct.h"
 #include "c_log.h"
 #include "c_common.h"
 #include "c_direct.h"
-#include <inttypes.h>
 
 #define BUFFER_SIZE 1024
+#define BXT_LOG_FOLDER "/run/buxton2/log"
+#define BXT_NULL_STRING "(VCONF_NULL)"
+
+static FILE *_fp;
+static int _log_max_line = 2000;
+static bool _log_on = true;
 
 static const char *confpath;
 static const char const *type_names[BUXTON_TYPE_MAX] = {
@@ -65,7 +73,7 @@ static int c_init(void)
        int r;
        char err_buf[BUFFER_SIZE];
 
-       r = direct_init(MODULE_DIR, confpath ? confpath : CONFPATH);
+       r = direct_init(MODULE_DIR, confpath ? confpath : CONFPATH, &_log_on, &_log_max_line);
        if (r == -1) {
                strerror_r(errno, err_buf, sizeof(err_buf));
                bxt_err("Init: %s", err_buf);
@@ -115,6 +123,83 @@ int c_direct_get(const struct buxton_layer *layer,
        return 0;
 }
 
+static bool _init_log()
+{
+       char buffer[256] = {0, };
+       int ret;
+
+       ret = mkdir(BXT_LOG_FOLDER, 0755);
+       if (ret < 0  && errno != EEXIST) {
+               bxt_err("Failed to mkdir %s - %d", BXT_LOG_FOLDER, errno);
+               return false;
+       }
+
+       snprintf(buffer, sizeof(buffer),
+                       "%s/direct_log_%d.log", BXT_LOG_FOLDER, getpid());
+       _fp = fopen(buffer, "wt");
+       if (_fp == NULL) {
+               bxt_err("Failed to open %s - %d", buffer, errno);
+               return false;
+       }
+
+       return true;
+}
+
+static void _write_file_log(const char *key, const char *value)
+{
+       char buf[512] = {0,};
+       char time_buf[32] = {0,};
+       int ret = 0;
+       int fd;
+       time_t now;
+       static int _log_index = 0;
+       char app_id[512] = {0,};
+       const char *refined_value;
+
+       if (_log_on == false)
+               return;
+
+       if (_fp == NULL) {
+               if (_init_log() == false)
+                       return;
+       }
+
+       snprintf(buf, sizeof(buf), "/proc/%d/cmdline", getppid());
+
+       fd = open(buf, O_RDONLY);
+       if (fd > 0) {
+               ret = read(fd, app_id, sizeof(app_id) - 1);
+               close(fd);
+       }
+
+       time(&now);
+       ctime_r(&now, time_buf);
+
+       /* remove newline */
+       if (strlen(time_buf) > 1)
+               time_buf[strlen(time_buf) -1] = '\0';
+
+       if (value == NULL || strlen(value) == 0)
+               refined_value = BXT_NULL_STRING;
+       else
+               refined_value = value;
+
+       _log_index++;
+       snprintf(buf, sizeof(buf), "\n[%5d]%s DirectSet - ppid(%d:%s) - %s ",
+               _log_index, time_buf, getppid(), app_id, key);
+       ret = fwrite(buf, strlen(buf), 1 , _fp);
+       if (ret < 0) {
+               bxt_err("Cannot write the key log: %d, %s %s", errno, buf, refined_value);
+               return;
+       }
+
+       ret = fwrite(refined_value, strlen(refined_value), 1 , _fp);
+       if (ret < 0) {
+               bxt_err("Cannot write the value log: %d, %s %s", errno, buf, refined_value);
+               return;
+       }
+}
+
 static int c_direct_set(const struct buxton_layer *layer,
                const char *key, const char *value, enum buxton_key_type type)
 {
@@ -151,6 +236,8 @@ static int c_direct_set(const struct buxton_layer *layer,
                                err_buf);
        }
 
+       _write_file_log(key, value);
+
        return r;
 }
 
index db144d7..84bb6e8 100644 (file)
 #define K_B_DB     "persistent"
 #define K_B_MEM    "volatile"
 
+#define G_LOG_CONF "log-config"
+#define K_LOG_ON   "OnOff"
+#define K_LOG_MAX  "MaxLine"
+
 static GHashTable *layers;
 
 static void free_layer(struct layer *layer)
@@ -230,6 +234,65 @@ static void add_layers(GKeyFile *kf, GList *backends)
        g_free(lays);
 }
 
+static void load_log_conf(GKeyFile *kf, bool *log_on, int *max_line)
+{
+       GError *err = NULL;
+       gchar *buf = NULL;
+       assert(kf);
+
+       bool onoff;
+       int max = 0;
+
+       /* 'OnOff' */
+       buf = g_key_file_get_string(kf, G_LOG_CONF, K_LOG_ON, &err);
+       if (!buf) {
+               bxt_err("get_string failed :Group '%s', Key '%s' : %s",
+                               G_LOG_CONF, K_LOG_ON, err ? err->message : "");
+               goto out;
+       }
+       if (strcasecmp(buf, "ON") == 0) {
+               onoff = true;
+       } else if (strcasecmp(buf, "OFF") == 0) {
+               onoff = false;
+       } else {
+               bxt_err("get_string failed : Group '%s', Key '%s' : '%s'(len:%d)",
+                               G_LOG_CONF, K_LOG_ON, buf, strlen(buf));
+               goto out;
+       }
+
+       if (onoff) {
+               g_free(buf);
+               buf = NULL;
+
+               /* max line */
+               buf = g_key_file_get_string(kf, G_LOG_CONF, K_LOG_MAX, &err);
+               if (!buf) {
+                       bxt_err("get_string failed : Group '%s', Key '%s' : '%s'",
+                                       G_LOG_CONF, K_LOG_MAX, err ? err->message : "");
+                       goto out;
+               }
+
+               max = atoi(buf);
+               if (max <= 0) {
+                       bxt_err("atoi failed : Group '%s', Key '%s' : '%s'",
+                               G_LOG_CONF, K_LOG_MAX, buf);
+                       goto out;
+               }
+       }
+
+       *log_on = onoff;
+       *max_line = max;
+       bxt_err("log config log on : %s , max line %d", onoff ? "True" : "False", max);
+
+out:
+       if (err)
+               g_clear_error(&err);
+       if (buf)
+               g_free(buf);
+
+       g_key_file_remove_group(kf, G_LOG_CONF, NULL);
+}
+
 const struct layer *conf_get_layer(const char *name)
 {
        const struct layer *layer;
@@ -273,7 +336,7 @@ void conf_exit(void)
        layers = NULL;
 }
 
-int conf_init(const char *confpath, GList *backends)
+int conf_init(const char *confpath, GList *backends, bool *log_on, int *max_line)
 {
        GKeyFile *kf;
 
@@ -297,6 +360,8 @@ int conf_init(const char *confpath, GList *backends)
                return -1;
        }
 
+       load_log_conf(kf, log_on, max_line);
+
        add_layers(kf, backends);
 
        g_key_file_free(kf);
index 52bce85..fc7ee68 100644 (file)
@@ -22,7 +22,7 @@
 
 #include "common.h"
 
-int conf_init(const char *confpath, GList *backends);
+int conf_init(const char *confpath, GList *backends, bool *log_on, int *max_line);
 void conf_exit(void);
 
 const struct layer *conf_get_layer(const char *name);
index 1c5e002..87d3764 100644 (file)
@@ -738,7 +738,7 @@ void direct_exit(void)
        backend_exit();
 }
 
-int direct_init(const char *moddir, const char *confpath)
+int direct_init(const char *moddir, const char *confpath, bool *log_on, int *max_line)
 {
        int r;
        GList *backends;
@@ -756,7 +756,7 @@ int direct_init(const char *moddir, const char *confpath)
        if (!backends)
                return -1;
 
-       r = conf_init(confpath, backends);
+       r = conf_init(confpath, backends, log_on, max_line);
 
        g_list_free(backends);
 
index 380877c..62bf869 100644 (file)
@@ -20,7 +20,7 @@
 
 #include "buxton2.h"
 
-int direct_init(const char *moddir, const char *confpath);
+int direct_init(const char *moddir, const char *confpath, bool *log_on, int *max_line);
 void direct_exit(void);
 
 int direct_get(const struct buxton_layer *layer,
index e7ff808..cd6ebb2 100644 (file)
@@ -23,7 +23,9 @@
 #include <assert.h>
 #include <signal.h>
 #include <sys/signalfd.h>
+#include <sys/stat.h>
 #include <string.h>
+#include <inttypes.h>
 
 #include <glib.h>
 #include <glib-unix.h>
 #include "dbus.h"
 #include "cache.h"
 
+#define BXT_LOG_FOLDER "/run/buxton2/log"
+#define BXT_NULL_STRING "(VCONF_NULL)"
+
+static int _log_max_line = 2000;
+static bool _log_on = true;
+
+static FILE *_fp;
+
+static enum log_type {
+       LOG_SET,
+       LOG_NOTI,
+       LOG_DELAYED_NOTI,
+       LOG_SEND_DELAYED_NOTI,
+       LOG_REG_NOTI,
+       LOG_UNREG_NOTI,
+       LOG_MAX
+};
+
+static char *log_map[] = {
+       "SET",
+       "NOTIFY",
+       "DELAYED_NOTI",
+       "SEND_DELAYED_NOTI",
+       "REG_NOTI",
+       "UNREG_NOTI"
+};
+
+
 struct bxt_noti {
        char *layer_key;
        GList *clients; /* struct bxt_client */
 };
 
+static bool _init_log();
+static void _write_file_log(enum log_type type, struct bxt_client *cli, struct request *rqst);
+
 static gboolean signal_cb(gint fd, GIOCondition cond, gpointer data)
 {
        struct bxt_daemon *bxtd = data;
@@ -230,6 +263,8 @@ static gboolean _send_notis(gpointer key, gpointer value, gpointer data)
                }
        }
 
+       _write_file_log(LOG_SEND_DELAYED_NOTI, cli, NULL);
+
        free(_data);
        return TRUE;
 }
@@ -308,8 +343,10 @@ static void send_notis(struct bxt_daemon *bxtd, struct request *rqst)
 
                                g_hash_table_replace(cli->delay_notilist,
                                                strdup(rqst->key), _data);
+                               _write_file_log(LOG_DELAYED_NOTI, cli, rqst);
                        }
                } else {
+                       _write_file_log(LOG_NOTI, cli, rqst);
                        if (cli->delay_notilist)
                                g_hash_table_remove(cli->delay_notilist, rqst->key);
                }
@@ -331,6 +368,8 @@ static void proc_set(struct bxt_client *cli,
                resp->res = errno;
                return;
        }
+       _write_file_log(LOG_SET, cli, rqst);
+
        resp->res = 0;
 }
 
@@ -464,8 +503,10 @@ static void proc_notify(struct bxt_client *cli,
        } else {
                free(lykey);
        }
-
        add_cli(noti, cli);
+
+       _write_file_log(LOG_REG_NOTI, cli, rqst);
+
        resp->res = 0;
 }
 
@@ -503,6 +544,8 @@ static void proc_unnotify(struct bxt_client *cli,
        if (!noti->clients) /* no client */
                g_hash_table_remove(cli->bxtd->notis, lykey);
 
+       _write_file_log(LOG_UNREG_NOTI, cli, rqst);
+
        resp->res = 0;
 
        free(lykey);
@@ -831,7 +874,9 @@ static int proc_client_msg(struct bxt_client *cli)
 
 static gboolean client_cb(gint fd, GIOCondition cond, gpointer data)
 {
-       int r;
+       int r, proc_fd;
+       char proc_name[512] = {0,};
+       char buf[512] = {0,};
        struct bxt_client *cli = data;
 
        assert(cli);
@@ -853,6 +898,17 @@ static gboolean client_cb(gint fd, GIOCondition cond, gpointer data)
        if (cli->cred.pid == 0) {
                sock_get_client_cred(fd, &cli->cred);
                sock_get_client_label(fd, &cli->label);
+
+               snprintf(buf, sizeof(buf), "/proc/%d/cmdline", cli->cred.pid);
+
+               proc_fd = open(buf, O_RDONLY);
+               if (proc_fd > 0) {
+                       r = read(proc_fd, proc_name, sizeof(proc_name) - 1);
+                       close(proc_fd);
+
+                       if (strlen(proc_name) > 0)
+                               cli->process_name = strdup(proc_name);
+               }
        }
 
        r = proc_client_msg(cli);
@@ -957,11 +1013,146 @@ static void free_client(struct bxt_client *cli)
        if (cli->fd != -1)
                close(cli->fd);
 
+       if (cli->process_name)
+               free(cli->process_name);
+
        free(cli->label);
        free(cli);
        bxt_dbg("free client %p", cli);
 }
 
+static bool _init_log()
+{
+       char buffer[256] = {0, };
+       int ret;
+
+       ret = mkdir(BXT_LOG_FOLDER, 0755);
+       if (ret < 0  && errno != EEXIST) {
+               bxt_err("Failed to mkdir %s - %d", BXT_LOG_FOLDER, errno);
+               return false;
+       }
+
+       snprintf(buffer, sizeof(buffer),
+                       "%s/log_%d.log", BXT_LOG_FOLDER, getpid());
+       _fp = fopen(buffer, "wt");
+
+       if (_fp == NULL) {
+               bxt_err("Failed to open %s - %d", buffer, errno);
+               return false;
+       }
+
+       return true;
+}
+
+static void _write_file_log(enum log_type type, struct bxt_client *cli, struct request *rqst)
+{
+       char buf[512] = {0,};
+       char time_buf[32] = {0,};
+       char tmp_value[32] = {0,};
+       char *label;
+       char *value = NULL;
+       int ret = 0;
+       time_t now;
+
+       static enum log_type prev_type = LOG_MAX;
+       static int _log_index = 0;
+
+       if (_log_on == false)
+               return;
+
+       if (_fp == NULL) {
+               if (_init_log() == false)
+                       return;
+       }
+
+       if (_log_index >= _log_max_line) {
+               fseek(_fp, 0, SEEK_SET);
+               _log_index = 0;
+       }
+
+       if (cli->process_name != NULL)
+               label = cli->process_name;
+       else
+               label = cli->label;
+
+       time(&now);
+       ctime_r(&now, time_buf);
+
+       /* remove newline */
+       if (strlen(time_buf) > 1)
+               time_buf[strlen(time_buf) -1] = '\0';
+
+       if (type == LOG_NOTI) {
+               if (prev_type != type) {
+                       _log_index++;
+                       snprintf(buf, sizeof(buf), "\n[%5d]%s %-18s %s - pid(%d:%s)",
+                               _log_index, time_buf, log_map[type], rqst->key, cli->cred.pid, label);
+
+               } else {
+                       snprintf(buf, sizeof(buf), ", pid(%d:%s)", cli->cred.pid, label);
+               }
+       } else {
+               _log_index++;
+               snprintf(buf, sizeof(buf), "\n[%5d]%s %-18s - pid(%d:%s) - %s ",
+                       _log_index, time_buf, log_map[type], cli->cred.pid, label, rqst ? rqst->key : "NULL");
+
+               if (type == LOG_SET && rqst) {
+                       value = tmp_value;
+
+                       switch (rqst->val->type) {
+                       case BUXTON_TYPE_STRING:
+                               value = rqst->val->value.s;
+                               break;
+                       case BUXTON_TYPE_INT32:
+                               snprintf(tmp_value, sizeof(tmp_value), "%d", rqst->val->value.i);
+                               break;
+                       case BUXTON_TYPE_UINT32:
+                               snprintf(tmp_value, sizeof(tmp_value), "%u", rqst->val->value.u);
+                               break;
+                       case BUXTON_TYPE_INT64:
+                               snprintf(tmp_value, sizeof(tmp_value), "%"PRId64, rqst->val->value.i64);
+                               break;
+                       case BUXTON_TYPE_UINT64:
+                               snprintf(tmp_value, sizeof(tmp_value), "%"PRIu64, rqst->val->value.u64);
+                               break;
+                       case BUXTON_TYPE_DOUBLE:
+                               snprintf(tmp_value, sizeof(tmp_value), "%lf", rqst->val->value.d);
+                               break;
+                       case BUXTON_TYPE_BOOLEAN:
+                               if (rqst->val->value.b)
+                                       snprintf(tmp_value, sizeof(tmp_value), "True");
+                               else
+                                       snprintf(tmp_value, sizeof(tmp_value), "False");
+                               break;
+                       default:
+                               snprintf(tmp_value, sizeof(tmp_value), "Unknown type");
+                               break;
+                       }
+               }
+       }
+
+       if (value == NULL || strlen(value) == 0)
+               value = BXT_NULL_STRING;
+
+       ret = fwrite(buf, strlen(buf), 1 , _fp);
+       if (ret <= 0) {
+               bxt_err("Cannot write the key log: %d, type(%d) pid(%d:%s) %s %s",
+                       errno, type, cli->cred.pid, label, rqst ? rqst->key : BXT_NULL_STRING, value);
+               return;
+       }
+
+       if (type == LOG_SET) {
+               ret = fwrite(value, strlen(value), 1, _fp);
+               if (ret <= 0) {
+                       bxt_err("Cannot write the value log: %d, type(%d) pid(%d:%s) %s %s",
+                               errno, type, cli->cred.pid, label, rqst ? rqst->key : BXT_NULL_STRING, value);
+                       return;
+               }
+       }
+
+       prev_type = type;
+}
+
 static void bxt_exit(struct bxt_daemon *bxtd)
 {
        buxton_cynara_exit();
@@ -1004,7 +1195,7 @@ static int bxt_init(struct bxt_daemon *bxtd, const char *confpath)
        bxtd->sigfd = create_sigfd();
        g_unix_fd_add(bxtd->sigfd, G_IO_IN, signal_cb, bxtd);
 
-       r = direct_init(MODULE_DIR, confpath);
+       r = direct_init(MODULE_DIR, confpath, &_log_on, &_log_max_line);
        if (r == -1)
                return -1;
 
index 439c065..9f0762c 100644 (file)
@@ -42,6 +42,7 @@ struct bxt_client {
 
        struct ucred cred;
        char *label;
+       char *process_name;
 
        GList *notilist; /* struct bxt_noti */
        GHashTable *delay_notilist;
index 79e93c3..ef9e956 100644 (file)
@@ -2,6 +2,10 @@
 # buxton2 config file for Tizen
 #
 
+[log-config]
+OnOff=on
+MaxLine=2000
+
 [system]
 Type=System
 Backend=sqlite