From 06ce7c2ede9b38f34d3abb41cd484da87a9988c5 Mon Sep 17 00:00:00 2001 From: Cedric Bail Date: Sat, 16 Mar 2013 18:46:45 +0900 Subject: [PATCH] eina: add support for Systemd journal in Eina_Log. NOTE: if you start your process with Systemd it will automatically use Journald API. You will need to overide the default logging function to change that behavior. --- ChangeLog | 1 + NEWS | 1 + configure.ac | 7 +++- src/lib/eina/eina_log.c | 83 +++++++++++++++++++++++++++++++++++++++++ src/lib/eina/eina_log.h | 29 ++++++++++++++ 5 files changed, 120 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 65fb3f8d9d..bc79778c6f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,6 +1,7 @@ 2013-03-16 Cedric Bail * Remove Glew and Direct3d code from Ecore_Evas module. + * Add Eina_Log integration for Systemd journal. 2013-03-15 Carsten Haitzler (The Rasterman) diff --git a/NEWS b/NEWS index 05f0f984b9..46738b43f6 100644 --- a/NEWS +++ b/NEWS @@ -19,6 +19,7 @@ Additions: eina_xattr_fd_copy() - Add eina_stringshare_refplace() - Add eina_file_copy() + - Add eina_log_print_cb_journald() * Add Cserve2 scalecache support * ecore_x: - Add window profile support. diff --git a/configure.ac b/configure.ac index fd087cc09b..b4c07cf09c 100644 --- a/configure.ac +++ b/configure.ac @@ -290,7 +290,7 @@ AM_CONDITIONAL([HAVE_CRYPTO_OPENSSL], [test "${build_crypto}" = "openssl"]) # check for systemd library if requested if test "x{want_systemd}" = "xyes"; then - PKG_CHECK_MODULES([SYSTEMD], [libsystemd-daemon], + PKG_CHECK_MODULES([SYSTEMD], [libsystemd-daemon libsystemd-journal], [want_systemd="yes"], [want_systemd="no"]) fi @@ -695,6 +695,8 @@ AC_DEFINE_IF([EINA_DEBUG_MALLOC], [test "x${ac_cv_func_malloc_usable_size}" = "xyes" && test "x${want_debug_malloc}" = "xyes"], [1], [Turn on debugging overhead in mempool]) +EFL_OPTIONAL_DEPEND_PKG([EINA], [${want_systemd}], [SYSTEMD], [libsystemd-journal]) + EFL_EVAL_PKGS([EINA]) ## Examples @@ -761,6 +763,8 @@ EINA_CHECK_MODULE([chained-pool], [static], [chained pool]) EINA_CHECK_MODULE([pass-through], [static], [pass through]) EINA_CHECK_MODULE([one-big], [static], [one big]) +EFL_ADD_FEATURE([EINA], [systemd-journal], [${have_systemd}]) + EFL_LIB_END([Eina]) #### End of Eina @@ -3740,6 +3744,7 @@ echo " Image Loaders.: ${features_evas_loader}" if test "x${have_pixman}" = "xyes" ; then echo " Pixman........: ${features_evas_pixman}" fi +echo "Eina............: yes (${features_eina})" echo "Ecore...........: yes (${features_ecore})" echo "Ecore_Con.......: yes (${features_ecore_con})" echo "Ecore_File......: yes" diff --git a/src/lib/eina/eina_log.c b/src/lib/eina/eina_log.c index 0be1cb8a08..ec2d1ed2a8 100644 --- a/src/lib/eina/eina_log.c +++ b/src/lib/eina/eina_log.c @@ -34,6 +34,10 @@ # define EINA_LOG_BACKTRACE #endif +#ifdef HAVE_SYSTEMD +# include +#endif + #ifdef HAVE_EVIL # include #endif @@ -43,6 +47,8 @@ #include "eina_inlist.h" #include "eina_lock.h" #include "eina_thread.h" +#include "eina_convert.h" +#include "eina_strbuf.h" /* undefs EINA_ARG_NONULL() so NULL checks are not compiled out! */ #include "eina_safety_checks.h" @@ -1354,6 +1360,11 @@ eina_log_init(void) } #endif +#ifdef HAVE_SYSTEMD + if (getenv("NOTIFY_SOCKET")) + _print_cb = eina_log_print_cb_journald; +#endif + if ((tmp = getenv(EINA_LOG_ENV_FILE_DISABLE)) && (atoi(tmp) == 1)) _disable_file = EINA_TRUE; @@ -1371,6 +1382,10 @@ eina_log_init(void) // Global log level if ((level = getenv(EINA_LOG_ENV_LEVEL))) _log_level = atoi(level); +#ifdef HAVE_SYSTEMD + else if (getenv("NOTIFY_SOCKET") && (_print_cb == eina_log_print_cb_journald)) + _log_level = EINA_LOG_LEVEL_INFO; +#endif // Register UNKNOWN domain, the default logger EINA_LOG_DOMAIN_GLOBAL = eina_log_domain_register("", NULL); @@ -1874,6 +1889,74 @@ eina_log_print_cb_stdout(const Eina_Log_Domain *d, #endif } +EAPI void +eina_log_print_cb_journald(const Eina_Log_Domain *d, + Eina_Log_Level level, + const char *file, + const char *fnc, + int line, + const char *fmt, + void *data EINA_UNUSED, + va_list args) +{ +#ifdef HAVE_SYSTEMD + char buf[12]; + char *tmp; + Eina_Thread cur; + + vasprintf(&tmp, fmt, args); + + eina_convert_itoa(line, buf); + + cur = SELF(); + +#ifdef EINA_LOG_BACKTRACE + if (EINA_LIKELY(level >= _backtrace_level)) +#endif + sd_journal_send_with_location(file, buf, fnc, + "PRIORITY=%i", level, + "MESSAGE=%s", tmp, + "EFL_DOMAIN=%s", d->domain_str, + "THREAD=%lu", cur, + NULL); +#ifdef EINA_LOG_BACKTRACE + else + { + Eina_Strbuf *bts; + char **strings; + void *bt[256]; + int btlen; + int i; + + btlen = backtrace((void **)bt, 256); + strings = backtrace_symbols((void **)bt, btlen); + + bts = eina_strbuf_new(); + for (i = 0; i < btlen; i++) + if (i + 1 == btlen) + eina_strbuf_append_printf(bts, "[%s]", strings[i]); + else + eina_strbuf_append_printf(bts, "[%s], ", strings[i]); + + sd_journal_send_with_location(file, buf, fnc, + "PRIORITY=%i", level, + "MESSAGE=%s", tmp, + "EFL_DOMAIN=%s", d->domain_str, + "THREAD=%lu", cur, + "BACKTRACE=%s", eina_strbuf_string_get(bts), + NULL); + eina_strbuf_free(bts); + free(strings); + } +#endif + + free(tmp); + +#else + eina_log_print_cb_stderr(d, level, file, fnc, line, fmt, data, args); +#endif +} + EAPI void eina_log_print_cb_file(const Eina_Log_Domain *d, EINA_UNUSED Eina_Log_Level level, diff --git a/src/lib/eina/eina_log.h b/src/lib/eina/eina_log.h index ea50c21002..f3980bffc8 100644 --- a/src/lib/eina/eina_log.h +++ b/src/lib/eina/eina_log.h @@ -891,6 +891,35 @@ EAPI void eina_log_print_cb_file(const Eina_Log_Domain *d, void *data, va_list args); + +/** + * Alternative logging method, this will output to systemd journal. + * + * @param d The domain. + * @param level Not used. + * @param file The file which is logged. + * @param fnc The function which is logged. + * @param line The line which is logged. + * @param fmt The ouptut format to use. + * @param data The file which will store the output (as a FILE *). + * @param args The arguments needed by the format. + * + * This method will never output color. + * + * @note if systemd journal is not there it will display error on stderr. + * @note if the process has been started by systemd this will be the default logging method. + * + * @since 1.8 + */ +EAPI void eina_log_print_cb_journald(const Eina_Log_Domain *d, + Eina_Log_Level level, + const char *file, + const char *fnc, + int line, + const char *fmt, + void *data, + va_list args); + /** * Configure console color of given file. *