From 9ea301983d145e6afbf835a9104ffa9f86974a68 Mon Sep 17 00:00:00 2001 From: David FORT Date: Fri, 30 Oct 2015 14:50:14 +0100 Subject: [PATCH] Adds a systemd journal appender --- CMakeLists.txt | 14 ++ cmake/Findlibsystemd.cmake | 44 +++++ config.h.in | 1 + winpr/include/winpr/wlog.h | 11 ++ winpr/libwinpr/utils/CMakeLists.txt | 11 ++ winpr/libwinpr/utils/wlog/Appender.c | 10 ++ winpr/libwinpr/utils/wlog/Appender.h | 4 + winpr/libwinpr/utils/wlog/JournaldAppender.c | 172 +++++++++++++++++++ winpr/libwinpr/utils/wlog/JournaldAppender.h | 35 ++++ winpr/libwinpr/utils/wlog/wlog.c | 4 + 10 files changed, 306 insertions(+) create mode 100644 cmake/Findlibsystemd.cmake create mode 100644 winpr/libwinpr/utils/wlog/JournaldAppender.c create mode 100644 winpr/libwinpr/utils/wlog/JournaldAppender.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 94e807499..e8268be12 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -605,6 +605,20 @@ if(ANDROID) set(OPENSLES_FEATURE_TYPE "REQUIRED") endif() +if(UNIX) + set(WLOG_SYSTEMD_JOURNAL_FEATURE_TYPE "RECOMMENDED") + set(WLOG_SYSTEMD_JOURNAL_FEATURE_PURPOSE "systemd journal appender") + set(WLOG_SYSTEMD_JOURNAL_FEATURE_DESCRIPTION "allows to export wLog to systemd journal") + + #include(Findlibsystemd) + find_feature(libsystemd ${WLOG_SYSTEMD_JOURNAL_FEATURE_TYPE} ${WLOG_SYSTEMD_JOURNAL_FEATURE_PURPOSE} ${WLOG_SYSTEMD_JOURNAL_FEATURE_DESCRIPTION}) + + if(LIBSYSTEMD_FOUND) + set(HAVE_JOURNALD_H TRUE) + else() + unset(HAVE_JOURNALD_H) + endif() +endif(UNIX) find_feature(X11 ${X11_FEATURE_TYPE} ${X11_FEATURE_PURPOSE} ${X11_FEATURE_DESCRIPTION}) find_feature(Wayland ${WAYLAND_FEATURE_TYPE} ${WAYLAND_FEATURE_PURPOSE} ${WAYLAND_FEATURE_DESCRIPTION}) diff --git a/cmake/Findlibsystemd.cmake b/cmake/Findlibsystemd.cmake new file mode 100644 index 000000000..ee00c782c --- /dev/null +++ b/cmake/Findlibsystemd.cmake @@ -0,0 +1,44 @@ +# Module defines +# LIBSYSTEMD_FOUND - libsystemd libraries and includes found +# LIBSYSTEMD_INCLUDE_DIRS - the libsystemd include directories +# LIBSYSTEMD_LIBRARIES - the libsystemd libraries +# +# Cache entries: +# LIBSYSTEMD_LIBRARY - detected libsystemd library +# LIBSYSTEMD_INCLUDE_DIR - detected libsystemd include dir(s) +# + +if(LIBSYSTEMD_INCLUDE_DIR AND LIBSYSTEMD_LIBRARY) + # in cache already + set(LIBSYSTEMD_FOUND TRUE) + set(LIBSYSTEMD_LIBRARIES ${LIBSYSTEMD_LIBRARY}) + set(LIBSYSTEMD_INCLUDE_DIRS ${LIBSYSTEMD_INCLUDE_DIR}) +else() + + find_package(PkgConfig) + if(PKG_CONFIG_FOUND) + pkg_check_modules(_LIBSYSTEMD_PC QUIET "libsystemd") + endif(PKG_CONFIG_FOUND) + + find_path(LIBSYSTEMD_INCLUDE_DIR systemd/sd-journal.h + ${_LIBSYSTEMD_PC_INCLUDE_DIRS} + /usr/include + /usr/local/include + ) + mark_as_advanced(LIBSYSTEMD_INCLUDE_DIR) + + find_library (LIBSYSTEMD_LIBRARY NAMES systemd + PATHS + ${_LIBSYSTEMD_PC_LIBDIR} + ) + mark_as_advanced(LIBSYSTEMD_LIBRARY) + + include(FindPackageHandleStandardArgs) + FIND_PACKAGE_HANDLE_STANDARD_ARGS(libsystemd DEFAULT_MSG LIBSYSTEMD_LIBRARY LIBSYSTEMD_INCLUDE_DIR) + + if(libsystemd_FOUND) + set(LIBSYSTEMD_LIBRARIES ${LIBSYSTEMD_LIBRARY}) + set(LIBSYSTEMD_INCLUDE_DIRS ${LIBSYSTEMD_INCLUDE_DIR}) + endif() + +endif() diff --git a/config.h.in b/config.h.in index 83f3ee641..e25162dd1 100644 --- a/config.h.in +++ b/config.h.in @@ -33,6 +33,7 @@ #cmakedefine HAVE_AIO_H #cmakedefine HAVE_POLL_H #cmakedefine HAVE_SYSLOG_H +#cmakedefine HAVE_JOURNALD_H #cmakedefine HAVE_PTHREAD_MUTEX_TIMEDLOCK #cmakedefine HAVE_VALGRIND_MEMCHECK_H #cmakedefine HAVE_EXECINFO_H diff --git a/winpr/include/winpr/wlog.h b/winpr/include/winpr/wlog.h index 488e893b6..6e86f0806 100644 --- a/winpr/include/winpr/wlog.h +++ b/winpr/include/winpr/wlog.h @@ -114,6 +114,7 @@ struct _wLogLayout #define WLOG_APPENDER_BINARY 2 #define WLOG_APPENDER_CALLBACK 3 #define WLOG_APPENDER_SYSLOG 4 +#define WLOG_APPENDER_JOURNALD 5 #define WLOG_PACKET_INBOUND 1 #define WLOG_PACKET_OUTBOUND 2 @@ -204,6 +205,16 @@ struct _wLogSyslogAppender }; typedef struct _wLogSyslogAppender wLogSyslogAppender; +#ifdef HAVE_JOURNALD_H +struct _wLogJournaldAppender +{ + WLOG_APPENDER_COMMON(); + FILE *stream; +}; +typedef struct _wLogJournaldAppender wLogJournaldAppender; +#endif + + /** * Filter */ diff --git a/winpr/libwinpr/utils/CMakeLists.txt b/winpr/libwinpr/utils/CMakeLists.txt index 654a321bd..a84d180f8 100644 --- a/winpr/libwinpr/utils/CMakeLists.txt +++ b/winpr/libwinpr/utils/CMakeLists.txt @@ -58,6 +58,16 @@ if (HAVE_SYSLOG_H) wlog/SyslogAppender.h ) endif() + +if (LIBSYSTEMD_FOUND) + set(JOURNALD_SRCS + wlog/JournaldAppender.c + wlog/JournaldAppender.h + ) + + winpr_include_directory_add(${LIBSYSTEMD_INCLUDE_DIR}) + winpr_library_add(${LIBSYSTEMD_LIBRARY}) +endif() set(${MODULE_PREFIX}_WLOG_SRCS wlog/wlog.c @@ -85,6 +95,7 @@ set(${MODULE_PREFIX}_WLOG_SRCS wlog/ConsoleAppender.c wlog/ConsoleAppender.h ${SYSLOG_SRCS} + ${JOURNALD_SRCS} ) diff --git a/winpr/libwinpr/utils/wlog/Appender.c b/winpr/libwinpr/utils/wlog/Appender.c index 3ca867912..8008f6df3 100644 --- a/winpr/libwinpr/utils/wlog/Appender.c +++ b/winpr/libwinpr/utils/wlog/Appender.c @@ -52,6 +52,11 @@ wLogAppender* WLog_Appender_New(wLog* log, DWORD logAppenderType) case WLOG_APPENDER_SYSLOG: appender = (wLogAppender*) WLog_SyslogAppender_New(log); break; +#endif +#ifdef HAVE_JOURNALD_H + case WLOG_APPENDER_JOURNALD: + appender = (wLogAppender*) WLog_JournaldAppender_New(log); + break; #endif default: fprintf(stderr, "%s: unknown handler type %d\n", __FUNCTION__, logAppenderType); @@ -107,6 +112,11 @@ void WLog_Appender_Free(wLog* log, wLogAppender* appender) case WLOG_APPENDER_SYSLOG: WLog_SyslogAppender_Free(log, (wLogSyslogAppender *) appender); break; +#endif +#ifdef HAVE_JOURNALD_H + case WLOG_APPENDER_JOURNALD: + WLog_JournaldAppender_Free(log, (wLogJournaldAppender *) appender); + break; #endif default: fprintf(stderr, "%s: don't know how to free appender type %d\n", __FUNCTION__, appender->Type); diff --git a/winpr/libwinpr/utils/wlog/Appender.h b/winpr/libwinpr/utils/wlog/Appender.h index 165e348b8..ccb57085a 100644 --- a/winpr/libwinpr/utils/wlog/Appender.h +++ b/winpr/libwinpr/utils/wlog/Appender.h @@ -31,6 +31,10 @@ #include "wlog/SyslogAppender.h" #endif +#ifdef HAVE_JOURNALD_H +#include "wlog/JournaldAppender.h" +#endif + void WLog_Appender_Free(wLog* log, wLogAppender* appender); #include "wlog/wlog.h" diff --git a/winpr/libwinpr/utils/wlog/JournaldAppender.c b/winpr/libwinpr/utils/wlog/JournaldAppender.c new file mode 100644 index 000000000..a1e2b1e87 --- /dev/null +++ b/winpr/libwinpr/utils/wlog/JournaldAppender.c @@ -0,0 +1,172 @@ +/** + * WinPR: Windows Portable Runtime + * WinPR Logger + * + * Copyright © 2015 Thincast Technologies GmbH + * Copyright © 2015 David FORT + * + * 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. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include + +#include +#include +#include + +#include + +#include "wlog/Message.h" +#include "wlog/JournaldAppender.h" + + +static BOOL WLog_JournaldAppender_Open(wLog* log, wLogJournaldAppender* appender) +{ + if (!log || !appender) + return FALSE; + + return TRUE; +} + +static BOOL WLog_JournaldAppender_Close(wLog* log, wLogJournaldAppender* appender) +{ + if (!log || !appender) + return FALSE; + + return TRUE; +} + +static BOOL WLog_JournaldAppender_WriteMessage(wLog* log, wLogJournaldAppender* appender, wLogMessage* message) +{ + char *formatStr; + + if (!log || !appender || !message) + return FALSE; + + switch (message->Level) + { + case WLOG_TRACE: + case WLOG_DEBUG: + formatStr = "<7>%s\n"; + break; + case WLOG_INFO: + formatStr = "<6>%s\n"; + break; + case WLOG_WARN: + formatStr = "<4>%s\n"; + break; + case WLOG_ERROR: + formatStr = "<3>%s\n"; + break; + case WLOG_FATAL: + formatStr = "<2>%s\n"; + break; + case WLOG_OFF: + return TRUE; + default: + fprintf(stderr, "%s: unknown level %d\n", __FUNCTION__, message->Level); + return FALSE; + } + + fprintf(appender->stream, formatStr, message->TextString); + return TRUE; +} + +static BOOL WLog_JournaldAppender_WriteDataMessage(wLog* log, wLogJournaldAppender* appender, wLogMessage* message) +{ + if (!log || !appender || !message) + return FALSE; + + return TRUE; +} + +static BOOL WLog_JournaldAppender_WriteImageMessage(wLog* log, wLogJournaldAppender* appender, wLogMessage* message) +{ + if (!log || !appender || !message) + return FALSE; + + + return TRUE; +} + +wLogJournaldAppender* WLog_JournaldAppender_New(wLog* log) +{ + wLogJournaldAppender* appender; + DWORD nSize; + LPSTR env = NULL; + LPCSTR name; + int fd; + + appender = (wLogJournaldAppender*) calloc(1, sizeof(wLogJournaldAppender)); + if (!appender) + return NULL; + + appender->Type = WLOG_APPENDER_JOURNALD; + + appender->Open = (WLOG_APPENDER_OPEN_FN) WLog_JournaldAppender_Open; + appender->Close = (WLOG_APPENDER_OPEN_FN) WLog_JournaldAppender_Close; + appender->WriteMessage = + (WLOG_APPENDER_WRITE_MESSAGE_FN) WLog_JournaldAppender_WriteMessage; + appender->WriteDataMessage = + (WLOG_APPENDER_WRITE_DATA_MESSAGE_FN) WLog_JournaldAppender_WriteDataMessage; + appender->WriteImageMessage = + (WLOG_APPENDER_WRITE_IMAGE_MESSAGE_FN) WLog_JournaldAppender_WriteImageMessage; + + name = "WLOG_JOURNALD_ID"; + nSize = GetEnvironmentVariableA(name, NULL, 0); + if (nSize) + { + env = (LPSTR) malloc(nSize); + if (!env) + goto error_env_malloc; + + GetEnvironmentVariableA(name, env, nSize); + } + else + { + env = _strdup("winpr"); + } + + fd = sd_journal_stream_fd(env, LOG_INFO, 1); + if (fd < 0) + goto error_journal_fd; + + appender->stream = fdopen(fd, "w"); + if (!appender->stream) + goto error_stream_open; + return appender; + +error_stream_open: + close(fd); +error_journal_fd: + free(env); +error_env_malloc: + free(appender); + return NULL; +} + +void WLog_JournaldAppender_Free(wLog* log, wLogJournaldAppender* appender) +{ + if (appender) + { + if (appender->stream) + fclose(appender->stream); + free(appender); + } +} diff --git a/winpr/libwinpr/utils/wlog/JournaldAppender.h b/winpr/libwinpr/utils/wlog/JournaldAppender.h new file mode 100644 index 000000000..f3606eb03 --- /dev/null +++ b/winpr/libwinpr/utils/wlog/JournaldAppender.h @@ -0,0 +1,35 @@ +/** + * Copyright © 2015 Thincast Technologies GmbH + * Copyright © 2015 David FORT + * + * Permission to use, copy, modify, distribute, and sell this software and + * its documentation for any purpose is hereby granted without fee, provided + * that the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of the copyright holders not be used in + * advertising or publicity pertaining to distribution of the software + * without specific, written prior permission. The copyright holders make + * no representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS + * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY + * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER + * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF + * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef WINPR_LIBWINPR_UTILS_WLOG_JOURNALDAPPENDER_H_ +#define WINPR_LIBWINPR_UTILS_WLOG_JOURNALDAPPENDER_H_ + +#include + +#include "wlog/wlog.h" + +WINPR_API wLogJournaldAppender* WLog_JournaldAppender_New(wLog* log); +WINPR_API void WLog_JournaldAppender_Free(wLog* log, wLogJournaldAppender* appender); + + +#endif /* WINPR_LIBWINPR_UTILS_WLOG_JOURNALDAPPENDER_H_ */ diff --git a/winpr/libwinpr/utils/wlog/wlog.c b/winpr/libwinpr/utils/wlog/wlog.c index 1dbbda2c0..06bfa3ce8 100644 --- a/winpr/libwinpr/utils/wlog/wlog.c +++ b/winpr/libwinpr/utils/wlog/wlog.c @@ -702,6 +702,10 @@ wLog* WLog_GetRoot() else if (_stricmp(env, "SYSLOG") == 0) logAppenderType = WLOG_APPENDER_SYSLOG; #endif /* HAVE_SYSLOG_H */ +#ifdef HAVE_JOURNALD_H + else if (_stricmp(env, "SYSTEMD") == 0) + logAppenderType = WLOG_APPENDER_JOURNALD; +#endif free(env); }