src/shared/logcommon.c \
include/dlog.h \
include/dlog-internal.h \
- src/libdlog/logconfig.c \
+ src/shared/logconfig.c \
include/logconfig.h \
src/libdlog/loglimiter.c \
include/loglimiter.h
src/shared/logprint.c \
src/shared/queued_entry.c \
src/shared/log_file.c \
+ src/shared/logconfig.c \
include/dlog_ioctl.h \
include/logcommon.h \
include/queued_entry.h \
dlogutil_SOURCES += src/logutil/logutil_journal.c
endif
-sbin_PROGRAMS = dloginit
-
if !WITH_SYSTEMD_JOURNAL
bin_PROGRAMS += dlog_logger
dlog_logger_SOURCES = \
src/shared/dlog_ioctl.c \
src/shared/logcommon.c \
+ src/shared/logconfig.c \
src/shared/logprint.c \
src/logger/logger.c \
src/shared/queued_entry.c \
endif
+if WITH_KMSG
+sbin_PROGRAMS = dloginit
dloginit_CFLAGS = \
$(AM_CFLAGS) \
$(LIBUDEV_CFLAGS) \
dloginit_SOURCES = \
src/loginit/loginit.c \
+ src/shared/logconfig.c \
+ src/shared/logcommon.c \
include/logcommon.h \
include/dlog.h
+endif
+
+bin_PROGRAMS += dlogctrl
+dlogctrl_CFLAGS = \
+ $(AM_CFLAGS) \
+ -fPIE
+
+dlogctrl_LDFLAGS = \
+ $(AM_LDFLAGS) \
+ -pie
+
+dlogctrl_SOURCES = \
+ src/shared/logconfig.c \
+ src/logctrl/logctrl.c \
+ include/logconfig.h
+
+# conf files
+
+.PHONY: dlog.conf
+
+if WITH_KMSG
+dlog.conf: configs/dlog.conf.kmsg
+ cp configs/dlog.conf.kmsg dlog.conf
+endif
+if WITH_ANDROID_LOGGER
+dlog.conf: configs/dlog.conf.logger
+ cp configs/dlog.conf.logger dlog.conf
+endif
+if WITH_SYSTEMD_JOURNAL
+dlog.conf: configs/dlog.conf.journal
+ cp configs/dlog.conf.journal dlog.conf
+endif
+
+optetcdir = /opt/etc
+optetc_DATA = dlog.conf
-# conf file
pkgconfigdir = $(libdir)/pkgconfig
pkgconfig_DATA = dlog.pc
--- /dev/null
+plog=1
+limiter=0
+limiter|*|*=allow
--- /dev/null
+plog=1
+limiter=0
+limiter|*|*=allow
+main_size=1048576
+apps_size=1048576
+system_size=1048576
+radio_size=1048576
+dlog_logger_conf_0=dlogutil -b system -r 5120 -n 1 -f /var/log/dlog/system -v kerneltime *:I
+dlog_logger_conf_1=dlogutil -b main -r 3072 -n 1 -f /var/log/dlog/main -v kerneltime *:W
+dlog_logger_conf_2=dlogutil -b radio -r 1024 -n 1 -f /var/log/dlog/radio -v kerneltime
--- /dev/null
+plog=1
+limiter=0
+limiter|*|*=allow
+main=/dev/log_main
+apps=/dev/log/log_apps
+system=/dev/log_system
+radio=/dev/log_radio
+main_size=1048576
+apps_size=1048576
+system_size=1048576
+radio_size=1048576
+dlog_logger_conf_0=dlogutil -b system -r 5120 -n 1 -f /var/log/dlog/system -v kerneltime *:I
+dlog_logger_conf_1=dlogutil -b main -r 3072 -n 1 -f /var/log/dlog/main -v kerneltime *:W
+dlog_logger_conf_2=dlogutil -b radio -r 1024 -n 1 -f /var/log/dlog/radio -v kerneltime
# output files
AC_CONFIG_FILES([Makefile dlog.pc]
- scripts/dlogctrl
)
AC_OUTPUT
#endif
#define _E(...) fprintf(stderr, __VA_ARGS__)
-#define LOG_MAIN_CONF_PREFIX "LOG_MAIN="
-#define LOG_RADIO_CONF_PREFIX "LOG_RADIO="
-#define LOG_SYSTEM_CONF_PREFIX "LOG_SYSTEM="
-#define LOG_APPS_CONF_PREFIX "LOG_APPS="
-#define LOG_TYPE_CONF_PREFIX "LOG_TYPE="
-
/*
* LOG_ATOMIC_SIZE is calculated according to kernel value
* 976 = 1024(size of log line) - 48(size of max prefix length)
#define LOG_BUF_SIZE 1024
#define LOG_MAX_SIZE 4076
-#define LOG_CONFIG_FILE TZ_SYS_ETC"/dlog.conf"
-
#define gettid() syscall(SYS_gettid)
-int get_log_dev_names(char devs[LOG_ID_MAX][PATH_MAX]);
-
-log_id_t log_id_by_name(const char *name);
-
+char * log_name_by_id (log_id_t id);
+log_id_t log_id_by_name (const char *name);
+void syslog_critical_failure (const char * message);
#endif /* _LOGCOMMON_H */
#ifndef _LOGCONFIG_H_
#define _LOGCONFIG_H_
+#define MAX_CONF_KEY_LEN 32
+#define MAX_CONF_VAL_LEN 256
+#define MAX_CONF_ENTRY_LEN (MAX_CONF_KEY_LEN + MAX_CONF_VAL_LEN + 2) // +2 for the delimiter and newline
+
+typedef enum {
+ CONFIG_TYPE_KMSG,
+ CONFIG_TYPE_COMMON,
+ CONFIG_TYPE_MAX
+} config_type;
+
+struct log_conf_entry;
+
struct log_config {
- int lc_plog; /* Platform logging enable/disable */
- int lc_limiter; /* Log limiter enable/disable */
+ struct log_conf_entry *begin;
+ struct log_conf_entry *last;
};
-int __log_config_read(const char* config_file, struct log_config* config);
+const char * get_config_filename (config_type type);
+
+int log_config_set (struct log_config* config, const char* key, const char* value);
+const char* log_config_get (struct log_config* config, const char* key);
+int log_config_read (struct log_config* config);
+int log_config_read_file (struct log_config* config, char const* filename);
+int log_config_write(struct log_config* config, char const* filename);
+void log_config_free (struct log_config* config);
+
+void log_config_print_out (struct log_config* config);
+int log_config_print_key (struct log_config* config, const char* key);
+void log_config_push (struct log_config* config, const char* key, const char* value);
+int log_config_remove (struct log_config* config, const char* key);
+int log_config_foreach (struct log_config* config, int (*func)(const char* key, const char* value));
-#endif /* _LOGCONFIG_H_ */
\ No newline at end of file
+#endif /* _LOGCONFIG_H_ */
log_print_format format);
/**
+ * Returns a deep copy of the passed object.
+ */
+log_format *log_format_from_format(log_format *p_format);
+
+/**
* Returns FORMAT_OFF on invalid string
*/
log_print_format log_format_from_string(const char *s);
struct logger_entry {
uint16_t len; /* length of the payload */
- uint16_t __pad; /* no matter what, we get 2 bytes of padding */
+ uint16_t buf_id; /* ID of the log buffer */
int32_t pid; /* generating process's pid */
int32_t tid; /* generating process's tid */
int32_t sec; /* seconds since Epoch */
int32_t nsec; /* nanoseconds */
- char msg[]; /* the entry's payload */
+ char msg[]; /* the entry's payload */
};
struct queued_entry_t {
+++ /dev/null
-#
-# Dlog configuration file.
-#
-# Lines beginning with '#' are comments.
-#
-# Following file configures dlog library.
-# First section contains global configuration for library.
-# It allows to disable or enable platform logs and log limiter features.
-
-PlatformLogs on # Possible values are 'on' and 'off'
-LogLimiter off
-
-# Second section controls filtering rules for dlog limiter.
-# Each line represent a rule for a filter. Filtering is done
-# at runtime, but configuration is read only at the boot time.
-# Log lines filtered out are not written to log buffers.
-# Filtering is done for "TAG"|priority pair, where TAG is string defined by application.
-# Which should be quoted with '"' character. It may contain spaces but not TABs.
-# Priority is one character from the following values:
-#
-# V or v or 1 - Verbose messages,
-# D or d or 2 - Debug messages,
-# I or i or 3 - Informational messages,
-# W or w or 4 - Warning messages,
-# E or e or 5 - Error messages,
-# F or f or 6 - Fatal messages.
-#
-# Limiter can define rules 'for all' by using an '*' character.
-# It's a wildcard replacing all TAGs not mentioned in this file.
-# '*' could be used also as wildcard for priority.
-# An asterisk is not evaluated, which means rules like "WOR*" are threated as a TAGs.
-# Log filter works according to rules presented below:
-#
-# case 1) The "TAG"|priority pair is not presented on the list.
-# - Use "TAG"|* rule to decide what to do.
-# - If "TAG"|* is not defined, use "*"|priority rule to decide what to do.
-# - If "*"|priority pair is not present, use "*"|* rule.
-# - If rule "*"|* is not present, then allow logging.
-#
-# case 2) The "TAG"|priority pair is on the list (applies to
-# "*" |priority and "*"|* rules).
-# - If policy = ALLOW, then log speed is unlimited.
-# - If policy = <number> then limit to <number> logs per minute.
-# - If policy = DENY then forbid logging.
-#
-# Maximum <number> is 10000, which gives 10000 log line per minute.
-# Please keep in mind that dlog uses constant size log storage, thus
-# when the application writes many logs, it may cause older entries overwriting.
-#
-# The configuration file has following format:
-# Lines beginning with # are threated as comments.
-# TAG can contain any ASCII letter or digit and spaces, but
-# not a TAB character. TAG has to be quoted using '"' character.
-# TAG is separated from priority with pipe '|' character.
-# Priority is one character long, the possible values are presented above.
-# Policy is separated from the "TAG"|priority pair with TAB character.
-# Policy is expressed as ALLOW, DENY or number from 0 to 10000 (not case sensitive).
-# Setting policy as 0 is the same as DENY.
-# Setting policy to more than 10000 is threated as allow.
-
-
-
-
-# TAG|priority POLICY
-"*"|* ALLOW
Source0: %{name}-%{version}.tar.gz
Source101: packaging/dlogutil.manifest
Source102: packaging/libdlog.manifest
-Source201: packaging/dlog.conf.in
-Source202: packaging/dlog_logger.conf.in
Source301: packaging/dlog_logger.service
Source302: packaging/dlog_logger.path.kmsg
-Source303: packaging/dlog_logger.path.logger
+Source303: packaging/dlog_logger.path.logger
Source401: packaging/dloginit.service
Source501: packaging/01-dlog.rules.kmsg
-Source502: packaging/01-dlog.rules.logger
+Source502: packaging/01-dlog.rules.logger
# Choose dlog backend log device
# Warning : MUST be only one "ON" in below three switches
--enable-debug_mode \
TZ_SYS_ETC=%{TZ_SYS_ETC}
make %{?jobs:-j%jobs} \
- CFLAGS+=-DKMSG_DEV_CONFIG_FILE=\\\"/run/dloginit.conf\\\" \
CFLAGS+=-DTZ_SYS_ETC=\\\"%{TZ_SYS_ETC}\\\" \
%if %{?backend_journal} == ON
CFLAGS+=-DDLOG_BACKEND_JOURNAL
%make_install
mkdir -p %{buildroot}/usr/bin/
-cp %{_builddir}/%{name}-%{version}/scripts/dlogctrl %{buildroot}/usr/bin/dlogctrl
mkdir -p %{buildroot}%{TZ_SYS_ETC}
-cp %SOURCE201 %{buildroot}%{TZ_SYS_ETC}/dlog.conf
%if %{?backend_journal} == OFF
ln -s ../dlog_logger.path %{buildroot}%{_unitdir}/multi-user.target.wants/dlog_logger.path
-# default set log output to external files
-cp %SOURCE202 %{buildroot}%{TZ_SYS_ETC}/dlog_logger.conf
-
%endif
+%if %{?backend_kmsg} == ON
mkdir -p %{buildroot}%{_unitdir}/sysinit.target.wants/
install -m 0644 %SOURCE401 %{buildroot}%{_unitdir}
ln -s ../dloginit.service %{buildroot}%{_unitdir}/sysinit.target.wants/dloginit.service
+%endif
mkdir -p %{buildroot}%{_udevrulesdir}
%if %{?backend_journal} == OFF
%{_udevrulesdir}/01-dlog.rules
%attr(750,log,log) %{_bindir}/dlog_logger
-%attr(664,log,log) %{TZ_SYS_ETC}/dlog_logger.conf
%{_unitdir}/dlog_logger.service
%{_unitdir}/dlog_logger.path
%{_unitdir}/multi-user.target.wants/dlog_logger.path
%{_libdir}/libdlog.so.0.0.0
%attr(664,log,log) %{TZ_SYS_ETC}/dlog.conf
/usr/share/license/%{name}
+%if %{?backend_kmsg} == ON
%attr(700,log,log) %{_sbindir}/dloginit
%attr(-,log,log) %{_unitdir}/dloginit.service
%{_unitdir}/sysinit.target.wants/dloginit.service
+%endif
%files -n libdlog-devel
%{_includedir}/dlog/dlog.h
+++ /dev/null
-dlogutil -b system -r 5120 -n 1 -f /var/log/dlog/system -v threadtime *:I
-dlogutil -b main -r 3072 -n 1 -f /var/log/dlog/main -v threadtime *:W
-dlogutil -b radio -r 1024 -n 1 -f /var/log/dlog/radio -v threadtime
Description=Path activation for dlog_logger
[Path]
-PathExists=/run/dloginit.conf
+PathExists=/run/dlog.conf
+++ /dev/null
-#!/bin/sh
-
-MODE=none
-OBJ=none
-VAL=none
-CONFIG_PATH=@TZ_SYS_ETC@
-
-function Usage()
-{
- /bin/echo "Usage: dlogctrl {get|set} {platformlog | loglimiter } {on|off}"
- exit 1
-}
-
-case "$1" in
-get)
- MODE=get
-;;
-set)
- MODE=set
-;;
-*)
- Usage
-esac
-
-case "$2" in
-platformlog)
- OBJ=PlatformLogs
-;;
-loglimiter)
- OBJ=LogLimiter
-;;
-*)
- Usage
-esac
-
-if [ "$MODE" = "set" ]; then
- case "$3" in
- 1|on)
- VAL=on
- ;;
- 0|off)
- VAL=off
- ;;
- *)
- Usage
- esac
-
- echo "Setting $OBJ=$VAL"
- /bin/sed "s/$OBJ[\t ]*[onf]*/$OBJ $VAL/" < "$CONFIG_PATH/dlog.conf" > /tmp/dlog.conf.new
- /bin/cp /tmp/dlog.conf.new "$CONFIG_PATH/dlog.conf"
- /bin/sync
- echo "You must reboot this target to apply the change!"
-else
- case "$(grep "$OBJ" "$CONFIG_PATH/dlog.conf" | awk '{ print $2 }')" in
- on)
- /bin/echo "1"
- ;;
- off)
- /bin/echo "0"
- ;;
- esac
-fi
-
-exit 0
*/
#include <pthread.h>
+#include <stdlib.h>
#include <dlog.h>
#include <logcommon.h>
/*
* @brief Points to a function which writes a log message
* @details The function pointed to depends on the backend used
- * @param log_id ID of the buffer to log to. Belongs to [0, LOG_ID_MAX)
+ * @param log_id ID of the buffer to log to. Belongs to (LOG_ID_INVALID, LOG_ID_MAX) non-inclusive
* @param prio Priority of the message.
* @param tag The message tag, identifies the sender.
* @param msg The contents of the message.
* @seealso __dlog_init_backend
*/
int (*write_to_log)(log_id_t log_id, log_priority prio, const char *tag, const char *msg);
-
-static pthread_mutex_t log_init_lock = PTHREAD_MUTEX_INITIALIZER;
-static struct log_config config;
+pthread_mutex_t log_init_lock = PTHREAD_MUTEX_INITIALIZER;
extern void __dlog_init_backend();
+static int limiter;
+static int plog;
+
static int __write_to_log_null(log_id_t log_id, log_priority prio, const char *tag, const char *msg)
{
return DLOG_ERROR_NOT_PERMITTED;
}
+static int __config_iteration(const char* key, const char* value)
+{
+ const int prefix_len = strlen("limiter|");
+ char * delimiter_pos;
+ char limiter_tag [MAX_CONF_KEY_LEN];
+ int limit;
+
+ if (!strcmp(key, "limiter|"))
+ return 1;
+
+ delimiter_pos = strchr(key + prefix_len + 1, '|');
+ if (!delimiter_pos || (delimiter_pos + 1 == key + strlen(key)))
+ return 1;
+
+ snprintf(limiter_tag, delimiter_pos - (key + prefix_len), "%s", key + prefix_len);
+
+ if (!strcmp(value, "allow"))
+ limit = __LOG_LIMITER_LIMIT_MAX + 1;
+ else if (!strcmp(value, "deny" ))
+ limit = 0;
+ else
+ limit = atoi(value);
+
+ __log_limiter_add_rule(limiter_tag, *(delimiter_pos + 1), limit);
+ return 0;
+}
+
static void __configure(void)
{
- if (0 > __log_config_read(LOG_CONFIG_FILE, &config)) {
- config.lc_limiter = 0;
- config.lc_plog = 0;
- }
+ struct log_config conf;
+ const char * conf_value;
- if (config.lc_limiter) {
- if (0 > __log_limiter_initialize())
- config.lc_limiter = 0;
- }
+ limiter = 0;
+ plog = 0;
+
+ if (!log_config_read(&conf))
+ return;
+
+ conf_value = log_config_get (&conf, "plog");
+ if (!conf_value)
+ return;
+ plog = atoi (conf_value);
+
+ conf_value = log_config_get (&conf, "limiter");
+ if (!conf_value)
+ return;
+ limiter = atoi (conf_value);
+
+ log_config_foreach(&conf, __config_iteration);
+ log_config_free (&conf);
+
+ if (limiter && (0 > __log_limiter_initialize()))
+ limiter = 0;
}
static void __dlog_init(void)
if (log_id == LOG_ID_INVALID || LOG_ID_MAX <= log_id)
return DLOG_ERROR_INVALID_PARAMETER;
- if (log_id != LOG_ID_APPS && !config.lc_plog)
+ if (log_id != LOG_ID_APPS && !plog)
return DLOG_ERROR_NOT_PERMITTED;
- if (config.lc_limiter) {
+ if (limiter) {
should_log = __log_limiter_pass_log(tag, prio);
if (!should_log) {
#include <dlog.h>
#include <logcommon.h>
+#include <logconfig.h>
extern int (*write_to_log)(log_id_t, log_priority, const char *tag, const char *msg);
static int log_fds[(int)LOG_ID_MAX] = { -1, -1, -1, -1 };
-static char log_devs[LOG_ID_MAX][PATH_MAX];
static int __write_to_log_android(log_id_t log_id, log_priority prio, const char *tag, const char *msg)
{
void __dlog_init_backend()
{
- if (0 == get_log_dev_names(log_devs)) {
- log_fds[LOG_ID_MAIN] = open(log_devs[LOG_ID_MAIN], O_WRONLY);
- log_fds[LOG_ID_SYSTEM] = open(log_devs[LOG_ID_SYSTEM], O_WRONLY);
- log_fds[LOG_ID_RADIO] = open(log_devs[LOG_ID_RADIO], O_WRONLY);
- log_fds[LOG_ID_APPS] = open(log_devs[LOG_ID_APPS], O_WRONLY);
+ struct log_config conf;
+ log_id_t buf_id;
+
+ if (!log_config_read (&conf))
+ return;
+
+ for (buf_id = 0; buf_id < LOG_ID_MAX; ++buf_id) {
+ const char * const buffer_name = log_config_get(&conf, log_name_by_id(buf_id));
+
+ if (!buffer_name) {
+ char err_message [MAX_CONF_VAL_LEN + 64];
+ snprintf (err_message, MAX_CONF_VAL_LEN + 64, "LOG BUFFER #%d %s HAS NO PATH SET IN CONFIG", buf_id, buffer_name);
+ syslog_critical_failure (err_message);
+ return;
+ }
+
+ log_fds[buf_id] = open(buffer_name, O_WRONLY);
}
- if (log_fds[LOG_ID_MAIN] >= 0)
- write_to_log = __write_to_log_android;
-
- if (log_fds[LOG_ID_RADIO] < 0)
- log_fds[LOG_ID_RADIO] = 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];
+
+ log_config_free (&conf);
+
+ if (log_fds[LOG_ID_MAIN] < 0) {
+ syslog_critical_failure ("COULD NOT OPEN MAIN LOG");
+ return;
+ }
+
+ write_to_log = __write_to_log_android;
+
+ for (buf_id = 0; buf_id < LOG_ID_MAX; ++buf_id)
+ if ((buf_id != LOG_ID_MAIN) && (log_fds[buf_id] < 0))
+ log_fds[buf_id] = log_fds[LOG_ID_MAIN];
}
#include <dlog.h>
#include <logcommon.h>
+#include <logconfig.h>
extern int (*write_to_log)(log_id_t, log_priority, const char *tag, const char *msg);
static int log_fds[(int)LOG_ID_MAX] = { -1, -1, -1, -1 };
-static char log_devs[LOG_ID_MAX][PATH_MAX];
static int __write_to_log_kmsg(log_id_t log_id, log_priority prio, const char *tag, const char *msg)
{
void __dlog_init_backend()
{
- if (0 == get_log_dev_names(log_devs)) {
- log_fds[LOG_ID_MAIN] = open(log_devs[LOG_ID_MAIN], O_WRONLY);
- log_fds[LOG_ID_SYSTEM] = open(log_devs[LOG_ID_SYSTEM], O_WRONLY);
- log_fds[LOG_ID_RADIO] = open(log_devs[LOG_ID_RADIO], O_WRONLY);
- log_fds[LOG_ID_APPS] = open(log_devs[LOG_ID_APPS], O_WRONLY);
+ struct log_config conf;
+ log_id_t buf_id;
+
+ if (!log_config_read (&conf))
+ return;
+
+ for (buf_id = 0; buf_id < LOG_ID_MAX; ++buf_id) {
+ const char * const buffer_name = log_config_get(&conf, log_name_by_id(buf_id));
+
+ if (!buffer_name) {
+ char err_message [MAX_CONF_VAL_LEN + 64];
+ snprintf (err_message, MAX_CONF_VAL_LEN + 64, "LOG BUFFER #%d %s HAS NO PATH SET IN CONFIG", buf_id, buffer_name);
+ syslog_critical_failure (err_message);
+ return;
+ }
+
+ log_fds[buf_id] = open(buffer_name, O_WRONLY);
}
- if (log_fds[LOG_ID_MAIN] >= 0)
- write_to_log = __write_to_log_kmsg;
-
- if (log_fds[LOG_ID_RADIO] < 0)
- log_fds[LOG_ID_RADIO] = 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];
+
+ log_config_free (&conf);
+
+ if (log_fds[LOG_ID_MAIN] < 0) {
+ syslog_critical_failure ("COULD NOT OPEN MAIN LOG");
+ return;
+ }
+
+ write_to_log = __write_to_log_kmsg;
+
+ for (buf_id = 0; buf_id < LOG_ID_MAX; ++buf_id)
+ if ((buf_id != LOG_ID_MAIN) && (log_fds[buf_id] < 0))
+ log_fds[buf_id] = log_fds[LOG_ID_MAIN];
}
+++ /dev/null
-/*
- * DLOG
- * Copyright (c) 2013 Samsung Electronics Co., Ltd.
- *
- * Licensed under the Apache License, Version 2.0 (the License);
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <errno.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "logconfig.h"
-#include "loglimiter.h"
-
-/* Functions possible return value */
-#define RET_ERROR (-1)
-#define RET_SUCCESS 0
-
-#define CONFIG_LINE_MAX_LEN 256
-#define CONFIG_OPTION_MAX_LEN 64
-
-/* Shortcut macros */
-#define isCOMMENT(c) ('#' == c)
-#define isNEWLINE(c) ('\n' == c || '\r' == c)
-
-/* Dlog options definition */
-#define LOG_PLATFORM_STRING "PlatformLogs"
-#define LOG_LIMITER_STRING "LogLimiter"
-
-/* Define options possible values */
-#define ALLOW_STRING "allow"
-#define DENY_STRING "deny"
-#define ON_STRING "on"
-#define OFF_STRING "off"
-#define isYES(c) (c == '1')
-#define isNO(c) (c == '0')
-
-
-static int log_config_multiplex_opt(char* opt_str, char* val_str, int prio,
- struct log_config* config)
-{
- int value = 0;
-
- /* There are only two ways to interpret the lines, so make here a short circuit */
- if (0 < prio) { /* Is it a rule or an option ? */
- /* For the filtering rule ... */
-
- if (!strncasecmp(ALLOW_STRING, val_str, sizeof(ALLOW_STRING))) {
- value = __LOG_LIMITER_LIMIT_MAX + 1;
- } else if (!strncasecmp(DENY_STRING, val_str, sizeof(DENY_STRING))) {
- value = 0;
- } else {
- char* endptr = NULL;
-
- value = strtoul(val_str, &endptr, 0);
- if (*endptr != '\0')
- return RET_ERROR;
- }
-
- return __log_limiter_add_rule(opt_str, prio, value);
-
- } else { /* It's an option then */
- if (isYES(*val_str)) {
- value = 1;
- } else if (isNO(*val_str)) {
- value = 0;
- } else if (!strncasecmp(ON_STRING, val_str, sizeof(ON_STRING))) {
- value = 1;
- } else if (!strncasecmp(OFF_STRING, val_str, sizeof(OFF_STRING))) {
- value = 0;
- } else {
- return RET_ERROR;
- }
-
- if (!strncasecmp(LOG_PLATFORM_STRING, opt_str,
- sizeof(LOG_PLATFORM_STRING))) {
- config->lc_plog = value;
- } else if (!strncasecmp(LOG_LIMITER_STRING, opt_str,
- sizeof(LOG_LIMITER_STRING))) {
- config->lc_limiter = value;
- } else {
- return RET_ERROR;
- }
- }
-
- return RET_SUCCESS;
-}
-
-/* Function returns 0 for success or -1 when error occurred */
-int __log_config_read(const char* config_file, struct log_config* config)
-{
- FILE* fconfig = NULL;
- char buf[CONFIG_LINE_MAX_LEN];
- char opt[CONFIG_OPTION_MAX_LEN];
- char opt_value[CONFIG_OPTION_MAX_LEN];
- int prio = (-1);
- int ret = 0;
-
- /* Check input */
- if (NULL == config_file || NULL == config) {
- return RET_ERROR;
- }
-
- if (NULL == (fconfig = fopen(config_file, "r"))) {
- return RET_ERROR;
- }
-
- while (1) {
- memset(buf, 0, CONFIG_LINE_MAX_LEN);
- errno = 0;
- if (NULL == fgets(buf, CONFIG_LINE_MAX_LEN, fconfig)) {
- if (!errno) {
- break;
- }
- goto bailout;
- }
-
- /* We ignore comments and blank lines */
- if (isCOMMENT(*buf) || isNEWLINE(*buf)) {
- continue;
- }
-
- memset(opt, 0, sizeof(opt));
- memset(opt_value, 0, sizeof(opt_value));
- prio = (-1);
- /* Read configure line, sscanf() should return two tokens,
- * even for tag filtering rule */
- ret = sscanf(buf, "%[A-z0-9-]\t%[A-z0-9]", opt, opt_value);
- if (ret != 2) { /* The line is malformed ? */
- char c = 0;
- /* This could be rule with space inside TAG */
- ret = sscanf(buf, "\"%[]A-z0-9*\x20_+:;/-]\"\t|\t%c\t%[A-z0-9]",
- opt, &c, opt_value);
- if (ret != 3) {
- goto bailout;
- }
- prio = (int)c;
- }
-
-
- if (0 > log_config_multiplex_opt(opt, opt_value, prio, config)) {
- goto bailout;
- }
- }
-
- fclose(fconfig);
- return RET_SUCCESS;
-
-bailout:
- /* These actions should warranty that
- we cleanly handle initialization errors */
- fclose(fconfig);
- /* Clean rules list to prevent log limiter initialization,
- if configuration error occured. */
- __log_limiter_rules_purge();
-
- return RET_ERROR;
-}
/* Included for priorities level */
#include <dlog.h>
#include "loglimiter.h"
-
-/* Defines maximal meaningful tag length */
-#define TAG_REASONABLE_LEN 32
+#include <logconfig.h>
/* Some random big odd number to make hash more diverse */
#define HASH_MAGIC_THINGY 5237231
int limit;
int hit;
time_t start;
- char tag[TAG_REASONABLE_LEN];
+ char tag[MAX_CONF_KEY_LEN];
};
typedef int (*hash_cmp_func_t)(struct rule*, struct rule*);
memset(r, 0, sizeof(struct rule));
- snprintf(r->tag, TAG_REASONABLE_LEN, "%s", tag);
+ snprintf(r->tag, MAX_CONF_KEY_LEN, "%s", tag);
r->prio = util_prio_to_char(prio);
r->hash = util_hash_key(tag, r->prio);
r->limit = limit;
--- /dev/null
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include <logconfig.h>
+
+void print_help ()
+{
+ printf ("dlogctrl - provides control over dlog configuration. Options:\n"
+ "\t-p Precludes -k. Prints all entries in the config.\n"
+ "\t-k key Precludes -p and requires one of -gs. Specifies a config key.\n"
+ "\t-g Requires -k, precludes -cs. Gets and prints the value of the entry assigned to the key.\n"
+ "\t-s value Requires -k, precludes -cg. Sets the value of the entry associated with the key.\n"
+ "\t-c Requires -k, precludes -gs. Clears the entry.\n"
+ "Having either -p or -k is mandatory.\n"
+ );
+}
+
+struct options {
+ int print_all;
+ int has_key;
+ int should_get;
+ int should_set;
+ int should_clear;
+};
+
+int validate (struct options o) {
+ int valid = 1;
+
+ if (!o.has_key && !o.print_all) {
+ printf ("Having either -p or -k is mandatory!\n");
+ valid = 0;
+ }
+ if (o.has_key && !(o.should_get || o.should_set || o.should_clear)) {
+ printf ("-k requires either -c, -g, or -s!\n");
+ valid = 0;
+ }
+ if (o.has_key && o.print_all) {
+ printf ("-p and -k preclude each other!\n");
+ valid = 0;
+ }
+ if (o.should_set + o.should_get + o.should_clear > 1) {
+ printf ("-c, -g and -s preclude each other!\n");
+ valid = 0;
+ }
+ if (!o.has_key && (o.should_set || o.should_get || o.should_clear)) {
+ printf ("-c, -g and -s require -k!\n");
+ valid = 0;
+ }
+
+ return valid;
+}
+
+int main (int argc, char ** argv)
+{
+ struct log_config conf;
+ char key [MAX_CONF_KEY_LEN];
+ char val [MAX_CONF_VAL_LEN];
+ struct options opt = {0,0,0,0,0};
+ const char * filename = getenv ("DLOG_CONFIG_PATH") ?: get_config_filename (CONFIG_TYPE_COMMON);
+
+ if (argc == 1) {
+ print_help (argv[0]);
+ return 0;
+ }
+
+ for (;;) {
+ int ret = getopt(argc, argv, "pt:k:gs:c");
+
+ if (ret < 0)
+ break;
+
+ switch (ret) {
+ case 'p':
+ opt.print_all = 1;
+ break;
+ case 'k':
+ snprintf (key, MAX_CONF_KEY_LEN, "%s", optarg);
+ opt.has_key = 1;
+ break;
+ case 'g':
+ opt.should_get = 1;
+ break;
+ case 'c':
+ opt.should_clear = 1;
+ break;
+ case 's':
+ opt.should_set = 1;
+ snprintf(val, MAX_CONF_VAL_LEN, "%s", optarg);
+ break;
+ }
+ }
+
+ if (!validate(opt)) {
+ print_help (argv[0]);
+ return 1;
+ }
+
+ if (!log_config_read (&conf)) {
+ printf ("Error: cannot open the config file!\n");
+ return 1;
+ }
+
+ if (opt.print_all) {
+ log_config_print_out (&conf);
+ } else if (opt.should_get) {
+ if (!log_config_print_key (&conf, key))
+ goto err_entry;
+ } else if (opt.should_clear) {
+ if (!log_config_remove(&conf, key))
+ goto err_entry;
+ if (!log_config_write (&conf, filename))
+ goto err_save;
+ } else if (opt.should_set) {
+ if (!log_config_set(&conf, key, val))
+ log_config_push(&conf, key, val);
+ if (!log_config_write (&conf, filename))
+ goto err_save;
+ } else {
+ printf ("Error: invalid options\n");
+ return 1;
+ }
+
+ return 0;
+
+err_save:
+ printf("Cannot save file\n");
+ return 1;
+
+err_entry:
+ printf ("Entry not found\n");
+ return 1;
+}
#include <log_file.h>
#include <logprint.h>
#include <dlog_ioctl.h>
+#include <logconfig.h>
#define COMMAND_MAX 5
#define DELIMITER " "
#define BUFFER_MAX 100
#define INTERVAL_MAX 60*60
-#define CONFIG_FILE TZ_SYS_ETC"/dlog_logger.conf"
-
#define ARRAY_SIZE(name) (sizeof(name)/sizeof(name[0]))
struct log_command {
struct log_device *next;
};
-static char device_path_table[LOG_ID_MAX][PATH_MAX];
+static struct log_config conf;
static struct log_work *works;
static struct log_device *devices;
logwork->printed = true;
snprintf(buf, sizeof(buf),
"--------- beginning of %s\n",
- device_path_table[dev->id]);
+ log_config_get(&conf, log_name_by_id(dev->id)));
if (write(logwork->file.fd, buf, strlen(buf)) < 0) {
_E("maybe work error");
exit(EXIT_FAILURE);
return NULL;
}
dev->id = id;
- dev->fd = open(device_path_table[id], O_RDONLY);
+ dev->fd = open(log_config_get(&conf, log_name_by_id(id)), O_RDONLY);
if (dev->fd < 0) {
_E("Unable to open log device %s (%d)",
- device_path_table[id],
+ log_config_get(&conf, log_name_by_id(id)),
errno);
free(dev);
return NULL;
get_log_read_size_max(dev->fd, &dev->log_read_size_max);
_D("device %s log read size max %u\n",
- device_path_table[id], dev->log_read_size_max);
+ log_config_get(&conf, log_name_by_id(id)), dev->log_read_size_max);
#if DLOG_BACKEND_KMSG
off_t off;
off = lseek(dev->fd, 0, SEEK_DATA);
if (off == -1) {
_E("Unable to lseek device %s. %d\n",
- device_path_table[id], errno);
+ log_config_get(&conf, log_name_by_id(id)), errno);
exit(EXIT_FAILURE);
}
#endif
devices = device_new(id);
if (devices == NULL) {
_E("failed to device_new: %s\n",
- device_path_table[id]);
+ log_config_get(&conf, log_name_by_id(id)));
exit(EXIT_FAILURE);
}
} else {
if (device_add_to_tail(devices, device_new(id)) < 0) {
_E("failed to device_add_to_tail: %s\n",
- device_path_table[id]);
+ log_config_get(&conf, log_name_by_id(id)));
exit(EXIT_FAILURE);
}
}
* parse command line
* using getopt function
*/
-static int parse_command_line(char *linebuffer, struct log_command *cmd)
+static int parse_command_line(char const *linebuffer, struct log_command *cmd)
{
int i, ret, id, argc;
char *argv[MAX_ARGS];
*/
static int parse_command(struct log_command *command_list)
{
- FILE *fp;
+ struct log_config conf;
+ char conf_key [MAX_CONF_KEY_LEN];
+ const char * conf_val;
int ncmd;
- char *line_p;
- char linebuffer[1024];
- fp = fopen(CONFIG_FILE, "re");
- if (!fp) {
- _E("no config file\n");
- goto exit;
- }
+ if (!log_config_read (&conf))
+ return 0;
+
ncmd = 0;
- while (fgets(linebuffer, sizeof(linebuffer), fp) != NULL) {
- line_p = strchr(linebuffer, '\n');
- if (line_p != NULL)
- *line_p = '\0';
- if (parse_command_line(linebuffer, &command_list[ncmd]) == 0)
+ while (1) {
+ sprintf (conf_key, "dlog_logger_conf_%d", ncmd);
+ conf_val = log_config_get (&conf, conf_key);
+ if (!conf_val)
+ break;
+ if (parse_command_line(conf_val, &command_list[ncmd]) == 0)
ncmd++;
if (COMMAND_MAX <= ncmd)
break;
}
- fclose(fp);
- return ncmd;
+ log_config_free (&conf);
-exit:
- return 0;
+ return ncmd;
}
/*
if (!ncmd)
goto exit;
- if (0 != get_log_dev_names(device_path_table))
+ if (!log_config_read (&conf))
goto exit;
/* create log device */
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <libudev.h>
#include <logcommon.h>
+#include <logconfig.h>
#include <dlog.h>
-#ifdef DLOG_BACKEND_KMSG
-
-#define DEV_KMSG "/dev/kmsg"
+#define DEV_KMSG "/dev/kmsg"
+#define BACKUP_SIZE 1048576
int g_minors[LOG_ID_MAX] = {-1, -1, -1, -1};
-static int create_kmsg_devs(int fd)
+static int create_kmsg_devs(int fd, struct log_config *conf)
{
int i;
struct kmsg_cmd_buffer_add cmd = {
- .size = 1024*256,
.mode = 0662,
};
for (i = 0; i < LOG_ID_MAX; i++) {
+ char key [MAX_CONF_KEY_LEN];
+ const char *size_str;
+ char *size_str_end;
+
+ snprintf (key, MAX_CONF_KEY_LEN, "%s_size", log_name_by_id(i));
+ size_str = log_config_get (conf, key);
+ errno = 0;
+
+ if (!size_str) {
+ cmd.size = BACKUP_SIZE;
+ } else {
+ cmd.size = strtol(size_str, &size_str_end, 10);
+ if (errno || (cmd.size <= 0) || (*size_str_end != '\0'))
+ cmd.size = BACKUP_SIZE;
+ }
+
if (0 > ioctl(fd, KMSG_CMD_BUFFER_ADD, &cmd)) {
_E("ioctl KMSG_CMD_BUFFER_ADD failed. (%d)\n", errno);
return -1;
}
}
-static int write_config_kmsg(FILE *config_file)
-{
- return fprintf(config_file,
- "%s%s\n"
- "%s%s%d\n"
- "%s%s%d\n"
- "%s%s%d\n"
- "%s%s%d",
- LOG_TYPE_CONF_PREFIX, "kmsg",
- LOG_MAIN_CONF_PREFIX, DEV_KMSG, g_minors[LOG_ID_MAIN],
- LOG_RADIO_CONF_PREFIX, DEV_KMSG, g_minors[LOG_ID_RADIO],
- LOG_SYSTEM_CONF_PREFIX, DEV_KMSG, g_minors[LOG_ID_SYSTEM],
- LOG_APPS_CONF_PREFIX, DEV_KMSG, g_minors[LOG_ID_APPS]);
-}
-
-#elif DLOG_BACKEND_LOGGER
-
-static void write_config_logger(FILE *config_file)
-{
- fprintf(config_file,
- "%s%s\n"
- "%s%s\n"
- "%s%s\n"
- "%s%s\n"
- "%s%s",
- LOG_TYPE_CONF_PREFIX, "logger",
- LOG_MAIN_CONF_PREFIX, "/dev/log_main",
- LOG_RADIO_CONF_PREFIX, "/dev/log_radio",
- LOG_SYSTEM_CONF_PREFIX, "/dev/log_system",
- LOG_APPS_CONF_PREFIX, "/dev/log_apps");
-}
-
-#elif DLOG_BACKEND_JOURNAL
-
-static void write_config_journal(FILE *config_file)
-{
- fprintf(config_file, "%s%s",
- LOG_TYPE_CONF_PREFIX, "journal");
-}
-
-#endif
-
int main()
{
- FILE *config_file = fopen(KMSG_DEV_CONFIG_FILE, "w");
- if (!config_file) {
- _E("Unable to open %s config file\n", KMSG_DEV_CONFIG_FILE);
- exit(EXIT_FAILURE);
- }
+ int kmsg_fd, i;
+ struct log_config conf_in;
+ struct log_config conf_out;
-#ifdef DLOG_BACKEND_KMSG
- int kmsg_fd;
+ log_config_read (&conf_in);
+ memset (&conf_out, 0, sizeof(struct log_config));
kmsg_fd = open(DEV_KMSG, O_RDWR);
if (kmsg_fd < 0) {
exit(EXIT_FAILURE);
}
- if (0 > create_kmsg_devs(kmsg_fd))
+ if (0 > create_kmsg_devs(kmsg_fd, &conf_in))
goto error;
- if (0 > write_config_kmsg(config_file))
- goto error;
+ for (i = 0; i < LOG_ID_MAX; ++i) {
+ char key [MAX_CONF_KEY_LEN];
+ char val [MAX_CONF_VAL_LEN];
- return 0;
+ snprintf(key, MAX_CONF_KEY_LEN, "%s_size", log_name_by_id(i));
+ snprintf(val, MAX_CONF_VAL_LEN, "%s", log_config_get (&conf_in, key));
+ log_config_push (&conf_out, key, val);
-error:
- remove_kmsg_devs(kmsg_fd);
- exit(EXIT_FAILURE);
+ snprintf(val, MAX_CONF_VAL_LEN, "%s%d", DEV_KMSG, g_minors[i]);
+ log_config_push (&conf_out, log_name_by_id(i), val);
+ }
-#elif DLOG_BACKEND_LOGGER
- write_config_logger(config_file);
- return 0;
+ log_config_write (&conf_out, get_config_filename (CONFIG_TYPE_KMSG));
-#elif DLOG_BACKEND_JOURNAL
- write_config_journal(config_file);
return 0;
-#endif
+error:
+ remove_kmsg_devs(kmsg_fd);
+ exit(EXIT_FAILURE);
}
#include <log_file.h>
#include <logprint.h>
#include <dlog_ioctl.h>
+#include <logconfig.h>
#define DEFAULT_LOG_ROTATE_SIZE_KBYTES 16
#define DEFAULT_MAX_ROTATED_LOGS 4
struct log_device_t* next;
};
-static char g_devs[LOG_ID_MAX][PATH_MAX];
+static struct log_config conf;
static void processBuffer(struct log_device_t* dev, struct logger_entry *buf)
{
return 0;
}
-int main (int argc, char **argv)
+int main(int argc, char **argv)
{
int err;
int has_set_log_format = 0;
show_help(argv[0]);
exit(0);
}
-
- if (0 != get_log_dev_names(g_devs)) {
+ if (!log_config_read(&conf)) {
_E("Unable to read initial configuration\n");
exit(-1);
}
exit(-1);
}
- dev = log_devices_new(g_devs[id]);
+ dev = log_devices_new(log_config_get(&conf, log_name_by_id(id)));
if (dev == NULL) {
- _E("Can't add log device: %s\n", g_devs[id]);
+ _E("Can't add log device: %s\n", log_config_get(&conf, log_name_by_id(id)));
exit(-1);
}
if (devices) {
if (log_devices_add_to_tail(devices, dev)) {
- _E("Open log device %s failed\n", g_devs[id]);
+ _E("Open log device %s failed\n", log_config_get(&conf, log_name_by_id(id)));
exit(-1);
}
} else {
}
if (!devices) {
- devices = log_devices_new(g_devs[LOG_ID_MAIN]);
+ devices = log_devices_new(log_config_get(&conf, log_name_by_id(LOG_ID_MAIN)));
if (devices == NULL) {
- _E("Can't add log device: %s\n", g_devs[LOG_ID_MAIN]);
+ _E("Can't add log device: %s\n", log_config_get(&conf, log_name_by_id(LOG_ID_MAIN)));
exit(-1);
}
g_dev_count = 1;
accessmode = W_OK;
/* only add this if it's available */
- if (0 == access(g_devs[LOG_ID_SYSTEM], accessmode)) {
- if (log_devices_add_to_tail(devices, log_devices_new(g_devs[LOG_ID_SYSTEM]))) {
- _E("Can't add log device: %s\n", g_devs[LOG_ID_SYSTEM]);
+ if (0 == access(log_config_get(&conf, log_name_by_id(LOG_ID_SYSTEM)), accessmode)) {
+ if (log_devices_add_to_tail(devices, log_devices_new(log_config_get(&conf, log_name_by_id(LOG_ID_SYSTEM))))) {
+ _E("Can't add log device: %s\n", log_config_get(&conf, log_name_by_id(LOG_ID_SYSTEM)));
exit(-1);
}
}
- if (0 == access(g_devs[LOG_ID_APPS], accessmode)) {
- if (log_devices_add_to_tail(devices, log_devices_new(g_devs[LOG_ID_APPS]))) {
- _E("Can't add log device: %s\n", g_devs[LOG_ID_APPS]);
+ if (0 == access(log_config_get(&conf, log_name_by_id(LOG_ID_APPS)), accessmode)) {
+ if (log_devices_add_to_tail(devices, log_devices_new(log_config_get(&conf, log_name_by_id(LOG_ID_APPS))))) {
+ _E("Can't add log device: %s\n", log_config_get(&conf, log_name_by_id(LOG_ID_APPS)));
exit(-1);
}
}
*/
#include <string.h>
+#include <syslog.h>
#include <logcommon.h>
#define MAX_PREFIX_SIZE 32
#define LINE_MAX (MAX_PREFIX_SIZE+PATH_MAX)
-static char* get_dev_from_line(char *line, char *prefix)
-{
- size_t len = strlen(prefix);
- if (strncmp(line, prefix, len))
- return NULL;
- return line + len;
-}
+static struct {
+ log_id_t id;
+ char * name;
+} logid_map [] = {
+ { .id = LOG_ID_MAIN, .name = "main" },
+ { .id = LOG_ID_RADIO, .name = "radio" },
+ { .id = LOG_ID_SYSTEM, .name = "system" },
+ { .id = LOG_ID_APPS, .name = "apps" },
+};
-int get_log_dev_names(char devs[LOG_ID_MAX][PATH_MAX])
+log_id_t log_id_by_name(const char *name)
{
- int i;
- FILE *config_file;
- char line[LINE_MAX];
-
- for (i = 0; i < LOG_ID_MAX; i++)
- devs[i][0] = '\0';
-
- config_file = fopen(KMSG_DEV_CONFIG_FILE, "r");
- if (!config_file)
- return -1;
-
- while (fgets(line, LINE_MAX, config_file)) {
- char *dev;
- int len = strlen(line);
+ log_id_t i;
- if (line[0] == '\n' || line[0] == '#')
- continue;
+ for (i = 0; i < LOG_ID_MAX; ++i)
+ if (!strcmp (name, logid_map[i].name))
+ return logid_map[i].id;
- if (line[len-1] == '\n')
- line[len-1] = '\0';
-
- dev = get_dev_from_line(line, LOG_TYPE_CONF_PREFIX);
- if (dev)
- continue;
-
- dev = get_dev_from_line(line, LOG_MAIN_CONF_PREFIX);
- if (dev) {
- strncpy(devs[LOG_ID_MAIN], dev, PATH_MAX);
- continue;
- }
- dev = get_dev_from_line(line, LOG_RADIO_CONF_PREFIX);
- if (dev) {
- strncpy(devs[LOG_ID_RADIO], dev, PATH_MAX);
- continue;
- }
- dev = get_dev_from_line(line, LOG_SYSTEM_CONF_PREFIX);
- if (dev) {
- strncpy(devs[LOG_ID_SYSTEM], dev, PATH_MAX);
- continue;
- }
- dev = get_dev_from_line(line, LOG_APPS_CONF_PREFIX);
- if (dev) {
- strncpy(devs[LOG_ID_APPS], dev, PATH_MAX);
- continue;
- }
-
- goto error;
- }
+ return LOG_ID_INVALID;
+}
- for (i = 0; i < LOG_ID_MAX; i++) {
- if (devs[i][0] == '\0')
- goto error;
- }
+char * log_name_by_id (log_id_t id)
+{
+ log_id_t i;
- fclose(config_file);
- return 0;
+ for (i = 0; i < LOG_ID_MAX; ++i)
+ if (id == logid_map[i].id)
+ return logid_map[i].name;
-error:
- fclose(config_file);
- return -1;
+ return "";
}
-log_id_t log_id_by_name(const char *name)
+/* Sends a message to syslog in case dlog has a critical failure and cannot make its own log */
+void syslog_critical_failure (const char * message)
{
- if (0 == strcmp(name, "main"))
- return LOG_ID_MAIN;
- else if (0 == strcmp(name, "radio"))
- return LOG_ID_RADIO;
- else if (0 == strcmp(name, "system"))
- return LOG_ID_SYSTEM;
- else if (0 == strcmp(name, "apps"))
- return LOG_ID_APPS;
- else
- return LOG_ID_INVALID;
+ openlog (NULL, LOG_PERROR | LOG_CONS | LOG_PID | LOG_NDELAY, 0);
+ syslog (LOG_CRIT, "DLOG CRITIAL FAILURE: %s", message);
+ closelog ();
}
--- /dev/null
+#include <logconfig.h>
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#ifndef TZ_SYS_ETC
+#define TZ_SYS_ETC "/opt/etc"
+#endif
+
+const char * get_config_filename (config_type type)
+{
+ switch (type) {
+ case CONFIG_TYPE_COMMON:
+ return TZ_SYS_ETC "/dlog.conf";
+ case CONFIG_TYPE_KMSG:
+ return "/run/dlog.conf";
+ default:
+ return NULL;
+ }
+}
+
+struct log_conf_entry {
+ char key [MAX_CONF_KEY_LEN];
+ char value [MAX_CONF_VAL_LEN];
+ struct log_conf_entry * next;
+};
+
+const char * log_config_get (struct log_config* c, const char* key)
+{
+ struct log_conf_entry * e;
+
+ if (!c)
+ return NULL;
+
+ e = c->begin;
+ while (e)
+ if (!strcmp (e->key, key))
+ return e->value;
+ else
+ e = e->next;
+
+ return NULL;
+}
+
+int log_config_set (struct log_config* c, const char* key, const char* value)
+{
+ struct log_conf_entry * e;
+
+ if (!c || !key || !value)
+ return 0;
+
+ e = c->begin;
+ while (e) {
+ if (!strcmp (e->key, key)) {
+ strncpy (e->value, value, MAX_CONF_VAL_LEN);
+ return 1;
+ }
+ e = e->next;
+ }
+ return 0;
+}
+
+int log_config_read (struct log_config* config)
+{
+ int i;
+ int ret = 0;
+ char const * override;
+
+ if (!config)
+ return 0;
+
+ config->begin = config->last = NULL;
+
+ override = getenv ("DLOG_CONFIG_PATH");
+ if (override)
+ return log_config_read_file (config, override);
+#ifdef DLOG_BACKEND_KMSG
+ ret |= log_config_read_file (config, get_config_filename (CONFIG_TYPE_KMSG)); // fixme: ugly
+#endif
+ ret |= log_config_read_file (config, get_config_filename (CONFIG_TYPE_COMMON));
+
+ return ret;
+}
+
+int log_config_read_file (struct log_config* config, const char* filename)
+{
+ FILE * file;
+ char line [MAX_CONF_ENTRY_LEN];
+ char * tok;
+
+ if (!config)
+ return 0;
+
+ file = fopen (filename, "r");
+ if (!file)
+ return 0;
+
+ while (fgets(line, MAX_CONF_ENTRY_LEN, file)) {
+ int len = strlen (line);
+ char key [MAX_CONF_KEY_LEN];
+
+ if (len <= 1 || line[0] == '#')
+ continue;
+
+ if (line[len - 1] == '\n')
+ line [len - 1] = '\0';
+
+ tok = strchr (line, '=');
+ if (!tok || (tok - line > MAX_CONF_KEY_LEN))
+ continue;
+ ++tok;
+
+ snprintf (key, tok - line, "%s", line);
+ if (!log_config_get (config, key))
+ log_config_push (config, key, tok);
+ }
+
+ fclose (file);
+ return 1;
+}
+
+void log_config_free (struct log_config* config)
+{
+ struct log_conf_entry * current = config->begin, * prev;
+
+ while (current) {
+ prev = current;
+ current = current->next;
+ free (prev);
+ }
+}
+
+int log_config_write (struct log_config* config, char const * filename)
+{
+ FILE * file;
+ int r;
+ struct log_conf_entry * e;
+
+ if (!config)
+ return 0;
+
+ file = fopen (filename, "w");
+ if (!file)
+ return 0;
+
+ e = config->begin;
+
+ while (e) {
+ r = fprintf (file, "%s=%s\n", e->key, e->value);
+ if (r < 0)
+ return 0;
+
+ e = e->next;
+ }
+
+ fclose (file);
+ return 1;
+}
+
+void log_config_print_out (struct log_config* config)
+{
+ struct log_conf_entry* e = config->begin;
+ while (e) {
+ printf ("[%s] = %s\n", e->key, e->value);
+ e = e->next;
+ }
+}
+
+int log_config_print_key (struct log_config* config, const char* key)
+{
+ struct log_conf_entry* e = config->begin;
+ while (e) {
+ if (!strcmp(key, e->key)) {
+ printf ("%s\n", e->value);
+ return 1;
+ }
+ e = e->next;
+ }
+ return 0;
+}
+
+void log_config_push (struct log_config* config, const char* key, const char* value)
+{
+ struct log_conf_entry* e = calloc (1, sizeof(struct log_conf_entry));
+ snprintf(e->key, MAX_CONF_KEY_LEN, "%s", key);
+ snprintf(e->value, MAX_CONF_VAL_LEN, "%s", value);
+
+ if (!config->last) {
+ config->begin = config->last = e;
+ return;
+ }
+
+ config->last->next = e;
+ config->last = e;
+}
+
+int log_config_remove (struct log_config* config, const char* key)
+{
+ struct log_conf_entry* prev;
+ struct log_conf_entry* e = config->begin;
+ prev = NULL;
+ while (e) {
+ if (!strcmp(key, e->key)) {
+ if (prev)
+ prev->next = e->next;
+ else
+ config->begin = e->next;
+
+ if (e == config->last)
+ config->last = prev;
+
+ free (e);
+ return 1;
+ }
+ prev = e;
+ e = e->next;
+
+ }
+ return 0;
+}
+
+int log_config_foreach (struct log_config* config, int (*func)(const char* key, const char* value))
+{
+ int r = -1;
+ struct log_conf_entry* e = config->begin;
+ while (e)
+ {
+ if (!(r = func(e->key, e->value)))
+ break;
+
+ e = e->next;
+ }
+ return r;
+}
return p_ret;
}
+log_format *log_format_from_format(log_format *p_format)
+{
+ log_format *p_ret;
+ FilterInfo *p_info, *p_info_old = NULL;
+
+ if (!(p_ret = log_format_new()))
+ return NULL;
+
+ *p_ret = *p_format;
+
+ p_info = p_format->filters;
+
+ while (p_info != NULL) {
+ FilterInfo *p_tmp;
+ p_tmp = filterinfo_new(p_info->mTag, p_info->mPri);
+ if (!p_tmp)
+ {
+ log_format_free(p_ret);
+ return NULL;
+ }
+
+ if (!p_info_old)
+ p_format->filters = p_tmp;
+ else
+ p_info_old->p_next = p_tmp;
+
+ p_info_old = p_tmp;
+ p_info = p_info->p_next;
+ }
+ return p_ret;
+}
+
void log_format_free(log_format *p_format)
{
FilterInfo *p_info, *p_info_old;