added logging support

pull/1/head
Falk Werner 4 years ago
parent b5943bd7b6
commit 03dc713649

@ -52,6 +52,7 @@ add_library(webfused-static STATIC
src/webfused/daemon.c
src/webfused/config/config.c
src/webfused/config/factory.c
src/webfused/log/logger.c
)
add_executable(webfused
@ -105,6 +106,7 @@ pkg_check_modules(GMOCK gmock)
add_executable(alltests
test/test_config.cc
test/test_log.cc
)
target_include_directories(alltests PRIVATE

@ -0,0 +1,58 @@
#ifndef WFD_LOG_H
#define WFD_LOG_H
#ifndef __cplusplus
#include <stdarg.h>
#else
#include <cstdarg>
#endif
#ifdef __cplusplus
extern "C"
{
#endif
#ifndef WFD_LOGLEVEL
#define WFD_LOGLEVEL WFD_LOGLEVEL_ALL
#endif
#define WFD_LOGLEVEL_FATAL 1
#define WFD_LOGLEVEL_ERROR 3
#define WFD_LOGLEVEL_WARN 4
#define WFD_LOGLEVEL_INFO 5
#define WFD_LOGLEVEL_DEBUG 7
#define WFD_LOGLEVEL_ALL 8
#define WFD_FATAL(...) \
WFD_LOG(WFD_LOGLEVEL_FATAL, __VA_ARGS__)
#define WFD_ERROR(...) \
WFD_LOG(WFD_LOGLEVEL_ERROR, __VA_ARGS__)
#define WFD_WARN(...) \
WFD_LOG(WFD_LOGLEVEL_WARN, __VA_ARGS__)
#define WFD_INFO(...) \
WFD_LOG(WFD_LOGLEVEL_INFO, __VA_ARGS__)
#define WFD_DEBUG(...) \
WFD_LOG(WFD_LOGLEVEL_DEBUG, __VA_ARGS__)
#define WFD_LOG(level, ...) \
do { \
if (WFD_LOGLEVEL >= (level)) { \
wfd_log((level), __VA_ARGS__); \
} \
} while (0)
extern void
wfd_log(
int level,
char const * format,
...);
#ifdef __cplusplus
}
#endif
#endif

@ -0,0 +1,86 @@
#include "webfused/log/logger.h"
#include "webfused/log/log.h"
#include <stddef.h>
struct wfd_logger
{
int level;
wfd_logger_log_fn * log;
wfd_logger_onclose_fn * onclose;
void * user_data;
};
static void wfd_logger_default_log(
void * user_data,
int level,
char const * format,
va_list args);
static struct wfd_logger g_wfd_logger =
{
.level = WFD_LOGLEVEL_ALL,
.log = &wfd_logger_default_log,
.onclose = NULL,
.user_data = NULL
};
void
wfd_logger_init(
int level,
wfd_logger_log_fn * log,
wfd_logger_onclose_fn * onclose,
void * user_data)
{
wfd_logger_close();
g_wfd_logger.level = level;
g_wfd_logger.log = log;
g_wfd_logger.onclose = onclose;
g_wfd_logger.user_data = user_data;
}
void
wfd_logger_close(void)
{
if (NULL != g_wfd_logger.onclose)
{
g_wfd_logger.onclose(g_wfd_logger.user_data);
}
g_wfd_logger.level = WFD_LOGLEVEL_ALL;
g_wfd_logger.log = &wfd_logger_default_log;
g_wfd_logger.onclose = NULL;
g_wfd_logger.user_data = NULL;
}
void
wfd_log(
int level,
char const * format,
...)
{
if (g_wfd_logger.level >= level)
{
va_list args;
va_start(args, format);
g_wfd_logger.log(
g_wfd_logger.user_data,
level,
format,
args);
va_end(args);
}
}
static void wfd_logger_default_log(
void * user_data,
int level,
char const * format,
va_list args)
{
(void) user_data;
(void) level;
(void) format;
(void) args;
}

@ -0,0 +1,40 @@
#ifndef WFD_LOGGER_H
#define WFD_LOGGER_H
#ifndef __cplusplus
#include <stdarg.h>
#else
#include <cstdarg>
#endif
#ifdef __cplusplus
extern "C"
{
#endif
typedef void
wfd_logger_log_fn(
void * user_data,
int level,
char const * format,
va_list args);
typedef void
wfd_logger_onclose_fn(
void * user_data);
extern void
wfd_logger_init(
int level,
wfd_logger_log_fn * log,
wfd_logger_onclose_fn * onclose,
void * user_data);
extern void
wfd_logger_close(void);
#ifdef __cplusplus
}
#endif
#endif

@ -0,0 +1,152 @@
#include <gtest/gtest.h>
#include <gmock/gmock.h>
#include "webfused/log/logger.h"
#include "webfused/log/log.h"
using ::testing::_;
using ::testing::StrEq;
namespace
{
class ILogger
{
public:
virtual ~ILogger() = default;
virtual void log(int level, char const * format, va_list args) = 0;
virtual void onclose() = 0;
};
class MockLogger: public ILogger
{
public:
MOCK_METHOD3(log, void(int level, char const * format, va_list args));
MOCK_METHOD0(onclose, void(void));
void * getUserData()
{
ILogger * logger = this;
return reinterpret_cast<void*>(logger);
}
};
}
extern "C"
{
static void MockLogger_log(
void * user_data,
int level,
char const * format,
va_list args)
{
ILogger * logger = reinterpret_cast<ILogger*>(user_data);
logger->log(level, format, args);
}
static void MockLogger_onclose(
void * user_data)
{
ILogger * logger = reinterpret_cast<ILogger*>(user_data);
logger->onclose();
}
}
TEST(log, fatal)
{
MockLogger logger;
EXPECT_CALL(logger, log(WFD_LOGLEVEL_FATAL, StrEq("too bad"), _)).Times(1);
EXPECT_CALL(logger, onclose()).Times(1);
wfd_logger_init(WFD_LOGLEVEL_ALL, &MockLogger_log, &MockLogger_onclose, logger.getUserData());
WFD_FATAL("too bad");
wfd_logger_close();
}
TEST(log, error)
{
MockLogger logger;
EXPECT_CALL(logger, log(WFD_LOGLEVEL_ERROR, StrEq("too bad"), _)).Times(1);
EXPECT_CALL(logger, onclose()).Times(1);
wfd_logger_init(WFD_LOGLEVEL_ALL, &MockLogger_log, &MockLogger_onclose, logger.getUserData());
WFD_ERROR("too bad");
wfd_logger_close();
}
TEST(log, warn)
{
MockLogger logger;
EXPECT_CALL(logger, log(WFD_LOGLEVEL_WARN, StrEq("too bad"), _)).Times(1);
EXPECT_CALL(logger, onclose()).Times(1);
wfd_logger_init(WFD_LOGLEVEL_ALL, &MockLogger_log, &MockLogger_onclose, logger.getUserData());
WFD_WARN("too bad");
wfd_logger_close();
}
TEST(log, info)
{
MockLogger logger;
EXPECT_CALL(logger, log(WFD_LOGLEVEL_INFO, StrEq("too bad"), _)).Times(1);
EXPECT_CALL(logger, onclose()).Times(1);
wfd_logger_init(WFD_LOGLEVEL_ALL, &MockLogger_log, &MockLogger_onclose, logger.getUserData());
WFD_INFO("too bad");
wfd_logger_close();
}
TEST(log, debug)
{
MockLogger logger;
EXPECT_CALL(logger, log(WFD_LOGLEVEL_DEBUG, StrEq("too bad"), _)).Times(1);
EXPECT_CALL(logger, onclose()).Times(1);
wfd_logger_init(WFD_LOGLEVEL_ALL, &MockLogger_log, &MockLogger_onclose, logger.getUserData());
WFD_DEBUG("too bad");
wfd_logger_close();
}
TEST(log, respect_loglevel)
{
MockLogger logger;
EXPECT_CALL(logger, log(_, _, _)).Times(0);
EXPECT_CALL(logger, onclose()).Times(1);
wfd_logger_init(WFD_LOGLEVEL_WARN, &MockLogger_log, &MockLogger_onclose, logger.getUserData());
WFD_DEBUG("too bad");
wfd_logger_close();
}
TEST(log, log_same_loglevel)
{
MockLogger logger;
EXPECT_CALL(logger, log(WFD_LOGLEVEL_WARN, StrEq("too bad"), _)).Times(1);
EXPECT_CALL(logger, onclose()).Times(1);
wfd_logger_init(WFD_LOGLEVEL_WARN, &MockLogger_log, &MockLogger_onclose, logger.getUserData());
WFD_WARN("too bad");
wfd_logger_close();
}
TEST(log, omit_onclose_if_nullptr)
{
MockLogger logger;
EXPECT_CALL(logger, log(WFD_LOGLEVEL_WARN, StrEq("too bad"), _)).Times(1);
EXPECT_CALL(logger, onclose()).Times(0);
wfd_logger_init(WFD_LOGLEVEL_WARN, &MockLogger_log, nullptr, logger.getUserData());
WFD_WARN("too bad");
wfd_logger_close();
}
Loading…
Cancel
Save