summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--client/c_direct.c91
-rw-r--r--common/config.c67
-rw-r--r--common/config.h2
-rw-r--r--common/direct.c4
-rw-r--r--common/direct.h2
-rw-r--r--daemon/daemon.c197
-rw-r--r--daemon/daemon.h1
-rw-r--r--packaging/buxton2.conf4
8 files changed, 358 insertions, 10 deletions
diff --git a/client/c_direct.c b/client/c_direct.c
index 451d051..d9eda3d 100644
--- a/client/c_direct.c
+++ b/client/c_direct.c
@@ -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"
@@ -29,9 +32,14 @@
#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;
}
diff --git a/common/config.c b/common/config.c
index db144d7..84bb6e8 100644
--- a/common/config.c
+++ b/common/config.c
@@ -38,6 +38,10 @@
#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);
diff --git a/common/config.h b/common/config.h
index 52bce85..fc7ee68 100644
--- a/common/config.h
+++ b/common/config.h
@@ -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);
diff --git a/common/direct.c b/common/direct.c
index 1c5e002..87d3764 100644
--- a/common/direct.c
+++ b/common/direct.c
@@ -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);
diff --git a/common/direct.h b/common/direct.h
index 380877c..62bf869 100644
--- a/common/direct.h
+++ b/common/direct.h
@@ -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,
diff --git a/daemon/daemon.c b/daemon/daemon.c
index e7ff808..cd6ebb2 100644
--- a/daemon/daemon.c
+++ b/daemon/daemon.c
@@ -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>
@@ -41,11 +43,42 @@
#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;
diff --git a/daemon/daemon.h b/daemon/daemon.h
index 439c065..9f0762c 100644
--- a/daemon/daemon.h
+++ b/daemon/daemon.h
@@ -42,6 +42,7 @@ struct bxt_client {
struct ucred cred;
char *label;
+ char *process_name;
GList *notilist; /* struct bxt_noti */
GHashTable *delay_notilist;
diff --git a/packaging/buxton2.conf b/packaging/buxton2.conf
index 79e93c3..ef9e956 100644
--- a/packaging/buxton2.conf
+++ b/packaging/buxton2.conf
@@ -2,6 +2,10 @@
# buxton2 config file for Tizen
#
+[log-config]
+OnOff=on
+MaxLine=2000
+
[system]
Type=System
Backend=sqlite