From 73a5eb055170e761f1815a3d68d0931bae2cc405 Mon Sep 17 00:00:00 2001 From: Jakub Filak Date: Tue, 29 Oct 2013 18:39:20 +0100 Subject: [PATCH 11/39] Add support for journald and syslog Two new command line arguments: syslog=(on|yes) - disabled by default - logs a stack trace to syslog with LOG_ERR level journald=(off|no) - disabled by default - logs a stack trace to journald with LOG_ERR level - the stack trace is saved in STACK_TRACE field Related to rhbz#1023081 Related to rhbz#1055581 Signed-off-by: Jakub Filak --- README | 13 ++++++ package/abrt-java-connector.spec | 1 + src/CMakeLists.txt | 3 ++ src/abrt-checker.c | 92 ++++++++++++++++++++++++++++++++-------- 4 files changed, 91 insertions(+), 18 deletions(-) diff --git a/README b/README index abbed4f..f9545bd 100644 --- a/README +++ b/README @@ -50,3 +50,16 @@ Example4: - user must provide a colon separated list of exception type names $ java -agentlib:abrt-java-connector=caught=java.io.FileNotFoundException:java.io.FileNotFoundException $MyClass -platform.jvmtiSupported true + +Example5: +- this example shows hot to enable syslog and disable journald +- abrt-java-connector reports detected problems to journald by default +- problems reported to journald has stack trace stored in STACK_TRACE field +- problems reported to syslog are written to syslog with entire backtrace + +- disable journald +$ java -agentlib:abrt-java-connector=journald=off $MyClass -platform.jvmtiSupported true + + +- enable syslog +$ java -agentlib:abrt-java-connector=syslog=on $MyClass -platform.jvmtiSupported true diff --git a/package/abrt-java-connector.spec b/package/abrt-java-connector.spec index abb0fee..88ecfc6 100644 --- a/package/abrt-java-connector.spec +++ b/package/abrt-java-connector.spec @@ -14,6 +14,7 @@ Source0: https://github.com/jfilak/%{name}/archive/%{commit}/%{name}-%{version}- BuildRequires: cmake BuildRequires: libreport-devel BuildRequires: java-1.7.0-openjdk-devel +BuildRequires: systemd-devel Requires: abrt diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index e7c8a8e..a00fe77 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -3,7 +3,9 @@ include_directories(${JAVA_INCLUDE_PATH} ${JAVA_INCLUDE_PATH2}) include(FindPkgConfig) pkg_check_modules(PC_ABRT REQUIRED libreport) +pkg_check_modules(PC_JOURNALD REQUIRED libsystemd-journal) include_directories(${PC_ABRT_INCLUDE_DIRS}) +include_directories(${PC_JOURNALD_INCLUDE_DIRS}) add_definitions(-D_GNU_SOURCE) set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wextra -std=c99 -pedantic") @@ -19,5 +21,6 @@ set_target_properties( OUTPUT_NAME abrt-java-connector) target_link_libraries(AbrtChecker ${PC_ABRT_LIBRARIES}) +target_link_libraries(AbrtChecker ${PC_JOURNALD_LIBRARIES}) install(TARGETS AbrtChecker DESTINATION ${LIB_INSTALL_DIR}) diff --git a/src/abrt-checker.c b/src/abrt-checker.c index 3eac971..26665d6 100644 --- a/src/abrt-checker.c +++ b/src/abrt-checker.c @@ -39,6 +39,8 @@ #include #include #include +#include +#include /* Shared macros and so on */ #include "abrt-checker.h" @@ -168,6 +170,8 @@ typedef struct { typedef enum { ED_TERMINAL = 1, ///< Report errors to the terminal ED_ABRT = ED_TERMINAL << 1, ///< Submit error reports to ABRT + ED_SYSLOG = ED_ABRT << 1, ///< Submit error reports to syslog + ED_JOURNALD = ED_SYSLOG << 1, ///< Submit error reports to journald } T_errorDestination; /* Global monitor lock */ @@ -191,7 +195,7 @@ T_jvmEnvironment jvmEnvironment; T_processProperties processProperties; /* Global configuration of report destination */ -T_errorDestination reportErrosTo; +T_errorDestination reportErrosTo = ED_JOURNALD; /* Path (not necessary absolute) to output file */ char *outputFileName = DISABLED_LOG_OUTPUT; @@ -471,7 +475,10 @@ static void add_process_properties_data(problem_data_t *pd) * Register new ABRT event using given message and a method name. * If reportErrosTo global flags doesn't contain ED_ABRT, this function does nothing. */ -static void register_abrt_event(char * executable, char * message, char * backtrace) +static void register_abrt_event( + const char *executable, + const char *message, + const char *backtrace) { if ((reportErrosTo & ED_ABRT) == 0) { @@ -510,6 +517,46 @@ static void register_abrt_event(char * executable, char * message, char * backtr /* + * Report a stack trace to all systems + */ +static void report_stacktrace( + const char *message, + const char *stacktrace, + int sure_unique) +{ + if (reportErrosTo & ED_SYSLOG) + { + VERBOSE_PRINT("Reporting stack trace to syslog\n"); + syslog(LOG_ERR, "%s\n%s", message, stacktrace); + } + + if (reportErrosTo & ED_JOURNALD) + { + VERBOSE_PRINT("Reporting stack trace to JournalD\n"); + sd_journal_send("MESSAGE=%s", message, + "PRIORITY=%d", LOG_ERR, + "STACK_TRACE=%s", stacktrace ? stacktrace : "no stack trace", + NULL); + + } + + log_print("%s\n", message); + + if (stacktrace) + { + log_print("%s", stacktrace); + } + + if (NULL != stacktrace && sure_unique) + { + VERBOSE_PRINT("Reporting stack trace to ABRT"); + register_abrt_event(processProperties.main_class, message, stacktrace); + } +} + + + +/* * Print a message when any JVM TI error occurs. */ static void print_jvmti_error( @@ -2026,23 +2073,16 @@ static void JNICALL callback_on_exception( char *message = format_exception_reason_message(/*caught?*/NULL != catch_method, updated_exception_name_ptr, class_name_ptr, method_name_ptr); - if (NULL != message) - { - log_print("%s\n", message); + char *stack_trace_str = generate_thread_stack_trace(jvmti_env, jni_env, tname, exception_object); - //char *stack_trace_str = generate_stack_trace(jvmti_env, jni_env, thr, tname, updated_exception_name_ptr); - char *stack_trace_str = generate_thread_stack_trace(jvmti_env, jni_env, tname, exception_object); - if (NULL != stack_trace_str) - { - log_print("%s", stack_trace_str); - if (NULL != threads_exc_buf) - { - register_abrt_event(processProperties.main_class, message, stack_trace_str); - } - free(stack_trace_str); - } - free(message); - } + const char *report_message = message; + if (NULL == report_message) + report_message = (NULL != catch_method) ? "Caught exception" : "Uncaught exception"; + + report_stacktrace(report_message, stack_trace_str, NULL != threads_exc_buf); + + free(message); + free(stack_trace_str); } else { @@ -2602,6 +2642,22 @@ void parse_commandline_options(char *options) reportErrosTo |= ED_ABRT; } } + else if (strcmp("syslog", key) == 0) + { + if (value != NULL && (strcasecmp("on", value) == 0 || strcasecmp("yes", value) == 0)) + { + VERBOSE_PRINT("Enabling errors reporting to syslog\n"); + reportErrosTo |= ED_SYSLOG; + } + } + else if (strcmp("journald", key) == 0) + { + if (value != NULL && (strcasecmp("off", value) == 0 || strcasecmp("no", value) == 0)) + { + VERBOSE_PRINT("Disable errors reporting to JournalD\n"); + reportErrosTo &= ~ED_JOURNALD; + } + } else if(strcmp("output", key) == 0) { if (DISABLED_LOG_OUTPUT != outputFileName) -- 1.8.3.1