Commit b6087f85 authored by Ales Friedl's avatar Ales Friedl

Ticket #24582 - macro and wrappers over spdlog

parent cd17b6c9
[submodule "3rd_party/lib/fmt"]
path = 3rd_party/lib/fmt
url = https://github.com/fmtlib/fmt.git
[submodule "3rd_party/lib/spdlog"]
path = 3rd_party/lib/spdlog
url = https://github.com/gabime/spdlog.git
Subproject commit a3a74672a0c09be935b1863b5deea8c085ba2b76
Subproject commit 3adfeeec3ed0131c3f07bfc7bb1f4003bb2eb981
# Copyright (C) 2019 CZ.NIC, z. s. p. o.
#
# This file is part of FRED.
#
# FRED is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# FRED is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with FRED. If not, see <https://www.gnu.org/licenses/>.
cmake_minimum_required(VERSION 3.5)
project(liblog
......@@ -10,8 +27,16 @@ endif()
include(GNUInstallDirs)
option(LIBLOG_BUILD_TESTS "Build liblog tests" ON)
set(LIBLOG_SOURCES
src/liblog/context.cc)
src/liblog/context.cc
src/liblog/impl/to_spdlog_level.cc
src/liblog/log.cc
src/liblog/log_config.cc
src/liblog/sink/console_sink_config.cc
src/liblog/sink/file_sink_config.cc
src/liblog/sink/syslog_sink_config.cc)
add_library(log SHARED ${LIBLOG_SOURCES})
add_library(log::library ALIAS log)
......@@ -65,9 +90,6 @@ find_package(Boost 1.53.0
COMPONENTS
system
thread
date_time
regex
random
serialization
filesystem
unit_test_framework
......@@ -87,26 +109,30 @@ target_include_directories(log
${CMAKE_CURRENT_SOURCE_DIR}
${CMAKE_CURRENT_BINARY_DIR})
target_include_directories(log
BEFORE
PUBLIC
${CMAKE_CURRENT_SOURCE_DIR}/3rd_party/lib/spdlog/include)
target_include_directories(log-static
PUBLIC
${CMAKE_CURRENT_SOURCE_DIR}
${CMAKE_CURRENT_BINARY_DIR})
target_include_directories(log-static
BEFORE
PUBLIC
${CMAKE_CURRENT_SOURCE_DIR}/3rd_party/lib/spdlog/include)
target_link_libraries(log PRIVATE
Threads::Threads
${Boost_SYSTEM_LIBRARY}
${Boost_THREAD_LIBRARY}
${Boost_DATE_TIME_LIBRARY}
${Boost_RANDOM_LIBRARY}
${Boost_REGEX_LIBRARY})
${Boost_THREAD_LIBRARY})
target_link_libraries(log-static
Threads::Threads
${Boost_SYSTEM_LIBRARY}
${Boost_THREAD_LIBRARY}
${Boost_DATE_TIME_LIBRARY}
${Boost_RANDOM_LIBRARY}
${Boost_REGEX_LIBRARY})
${Boost_THREAD_LIBRARY})
install(TARGETS log
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
......@@ -118,6 +144,8 @@ install(TARGETS log-static
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/log.pc DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/pkgconfig)
if(LIBLOG_BUILD_TESTS)
add_executable(test-liblog
test/liblog/test.cc)
......@@ -132,10 +160,15 @@ target_include_directories(test-liblog
${CMAKE_CURRENT_SOURCE_DIR}
${CMAKE_CURRENT_BINARY_DIR})
target_include_directories(test-liblog
BEFORE
PUBLIC
${CMAKE_CURRENT_SOURCE_DIR}/3rd_party/lib/spdlog/include)
target_link_libraries(test-liblog PRIVATE
log::library
${Boost_DATE_TIME_LIBRARY}
${Boost_PROGRAM_OPTIONS_LIBRARY}
${Boost_REGEX_LIBRARY}
${Boost_UNIT_TEST_FRAMEWORK_LIBRARY}
${Boost_SYSTEM_LIBRARY})
endif()
# ChangeLog
## 0.1.0 (2019-08-11)
* Initial release
ChangeLog
=========
.. contents:: Releases
:backlinks: none
:local:
0.1.0 (2019-08-11)
------------------
Initial release
# liblog
FRED logging library
\ No newline at end of file
liblog
======
FRED logging library
......@@ -3,8 +3,15 @@
#define PACKAGE "@PACKAGE@"
#define VERSION "@VERSION@"
#define HAVE_BOOST_SERIALIZATION @HAVE_BOOST_SERIALIZATION@
#define FMT_STRING_ALIAS @FMT_STRING_ALIAS@
#define FMT_HEADER_ONLY 1
// SPDLOG_NO_NAME only applies to default spdlog pattern
#define SPDLOG_NO_NAME
#define SPDLOG_NO_TLS
#define SPDLOG_ACTIVE_LEVEL SPDLOG_LEVEL_TRACE
#endif
# <repository> <commitish> <clone-path>
3rd_party/lib/spdlog/ v1.x https://github.com/gabime/spdlog.git
/*
* Copyright (C) 2019 CZ.NIC, z. s. p. o.
*
* This file is part of FRED.
*
* FRED is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* FRED is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with FRED. If not, see <https://www.gnu.org/licenses/>.
*/
#ifndef COLOR_MODE_HH_388F460FBCB04276A739C6ED5E66B745
#define COLOR_MODE_HH_388F460FBCB04276A739C6ED5E66B745
namespace LibLog {
enum struct ColorMode
{
never,
automatic,
always
};
} // namespace LibLog
#endif
......@@ -17,94 +17,50 @@
* along with FRED. If not, see <https://www.gnu.org/licenses/>.
*/
#include "context.hh"
#include <boost/thread/thread.hpp>
#include <boost/thread/mutex.hpp>
#include <boost/thread/tss.hpp>
#include <iterator>
#include <ostream>
#include <sstream>
#include <vector>
#include "src/liblog/context.hh"
namespace LibLog {
namespace {
const std::string& get_ndc_separator()
{
static const std::string separator = "/";
return separator;
}
struct NDCData
{
std::string name;
std::string path;
};
typedef std::vector<NDCData> Stack;
struct PerThreadData
{
Stack stack;
};
/**
* storage init
*/
boost::thread_specific_ptr<PerThreadData> data;
PerThreadData* get_thread_data()
std::string make_context_str(const std::initializer_list<std::string> _context_hierarchy)
{
PerThreadData* const result = data.get();
if (result != nullptr)
std::string result = "";
static const std::string delimiter = "-";
for (const auto& context_element : _context_hierarchy)
{
return result;
result += delimiter + context_element;
}
data.reset(new PerThreadData());
return data.get();
return result;
}
/**
* getters for thread local context data
*/
Stack* get_thread_stack()
std::string& context()
{
return &(get_thread_data()->stack);
thread_local std::string context;
return context;
}
}//namespace LibLog::{anonymous}
Context::Context()
void set_context(const std::string& _context)
{
context() = std::move(_context);
}
Context::Context(const std::string& _name)
{
Stack* const stack = get_thread_stack();
} // namespace LibLog::{anonymous}
NDCData new_ndc;
new_ndc.name = _name;
new_ndc.path = (!stack->empty() ? stack->back().path + get_ndc_separator()
: "") + _name;
stack->push_back(new_ndc);
SetContext::SetContext(const std::initializer_list<std::string> _context_hierarchy)
: previous_context_(get_context())
{
set_context(make_context_str(_context_hierarchy));
}
Context::~Context()
SetContext::~SetContext()
{
Stack* const stack = get_thread_stack();
if (!stack->empty())
{
stack->pop_back();
}
set_context(std::move(previous_context_));
}
std::string Context::get()
const std::string& get_context()
{
Stack* const stack = get_thread_stack();
return !stack->empty() ? stack->back().path : std::string();
return context();
}
} // namespace Conext
} // namespace LibLog
......@@ -17,29 +17,34 @@
* along with FRED. If not, see <https://www.gnu.org/licenses/>.
*/
#ifndef CONTEXT_HH_9D7575A582E84A54A9BC38B48DDCFB57
#define CONTEXT_HH_9D7575A582E84A54A9BC38B48DDCFB57
#ifndef CONTEXT_HH_E45B6643C944437CB307F5445F6B5963
#define CONTEXT_HH_E45B6643C944437CB307F5445F6B5963
#include <initializer_list>
#include <string>
namespace LibLog {
class Context
class SetContext
{
public:
Context();
explicit Context(const std::string& name);
~Context();
public:
explicit SetContext(std::initializer_list<std::string> _context_hierarchy);
// Context(const Context&) = delete;
~SetContext();
// Context& operator=(const Context&) = delete;
SetContext() = delete;
SetContext(const SetContext&) = delete;
SetContext(SetContext&&) = delete;
SetContext& operator=(const SetContext&) = delete;
SetContext& operator=(SetContext&&) = delete;
static std::string get();
private:
std::string previous_context_;
};
const std::string& get_context();
} // namespace LibLog
#endif
......@@ -17,9 +17,13 @@
* along with FRED. If not, see <https://www.gnu.org/licenses/>.
*/
#ifndef LIBLOG_IMPL_HH_2312EAEE045D4C1AA659EBA1DE33A06B
#define LIBLOG_IMPL_HH_2312EAEE045D4C1AA659EBA1DE33A06B
#include "src/liblog/exceptions.hh"
#include "format.hh"
namespace LibLog {
#endif
const char* InvalidSyslogOption::what() const noexcept
{
return "Invalid syslog option";
}
} // namespace LibLog
/*
* Copyright (C) 2019 CZ.NIC, z. s. p. o.
*
* This file is part of FRED.
*
* FRED is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* FRED is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with FRED. If not, see <https://www.gnu.org/licenses/>.
*/
#ifndef EXCEPTIONS_HH_28F5C0E7B79B409FA68517A7C17C0561
#define EXCEPTIONS_HH_28F5C0E7B79B409FA68517A7C17C0561
#include <exception>
namespace LibLog {
struct InvalidSyslogOption : std::exception
{
const char* what() const noexcept override;
};
} // namespace LibLog
#endif
/*
* Copyright (C) 2019 CZ.NIC, z. s. p. o.
*
* This file is part of FRED.
*
* FRED is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* FRED is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with FRED. If not, see <https://www.gnu.org/licenses/>.
*/
#ifndef FORMAT_HH_4A0412B22E1E403AB8B9A63F866C3EAF
#define FORMAT_HH_4A0412B22E1E403AB8B9A63F866C3EAF
#include "config.h"
#include "3rd_party/lib/fmt/include/fmt/format.h"
#include "3rd_party/lib/fmt/include/fmt/ranges.h"
#include <string>
#include <iostream>
namespace LibLog {
namespace Impl {
namespace Format {
template <std::size_t O, std::size_t... Is>
std::index_sequence<(O + Is)...> add_offset(std::index_sequence<Is...>)
{
return {};
}
template <std::size_t O, std::size_t N>
auto make_index_sequence_with_offset()
{
return add_offset<O>(std::make_index_sequence<N>{});
}
template<typename Tuple, std::size_t... Is>
constexpr auto apply_format(Tuple&& t, std::index_sequence<Is...>)
{
#if defined(FMT_STRING_ALIAS) && FMT_STRING_ALIAS
return fmt::format(std::get<0>(t), std::get<Is>(t)...);
#else
return fmt::format(std::get<0>(t), std::get<Is>(t)...);
#endif
}
template<typename T>
struct render
{
static std::string argument(T);
};
template<std::size_t N>
struct render<const char(&)[N]>
{
static std::string argument(const char arg[])
{
return std::string(arg);
}
};
template<>
struct render<std::string>
{
static std::string argument(std::string&& arg)
{
return std::move(arg);
}
};
template<>
struct render<std::string&>
{
static std::string argument(const std::string& arg)
{
return arg;
}
};
template<typename... T>
struct render<std::tuple<T...>>
{
static std::string argument(std::tuple<T...>&& arg)
{
return apply_format(std::move(arg),
make_index_sequence_with_offset<1u, sizeof...(T) - 1u>());
}
};
//template<typename T>
//std::string render_argument(T&& arg)
//{
// return render<T>::argument(std::forward<T>(arg));
//}
template<typename... T>
std::string render_argument(T&&... args)
{
//auto x = std::make_tuple(std::forward<T>(args)...);
//return render<decltype(x)>::argument(std::forward<decltype(x)>(x));
//return render<decltype((std::make_tuple(std::forward<T>(args)...)))>::argument(
// std::forward<decltype(std::make_tuple(std::forward<T>(args)...))>(
// std::make_tuple(std::forward<T>(args)...)));
return render<decltype((std::make_tuple(std::forward<T>(args)...)))>::argument(
std::make_tuple(std::forward<T>(args)...));
}
//template<typename H>
//void ctx_push(Context& ctx, H&& head)
//{
// ctx.push(std::forward<H>(head), 1u);
//}
//
//template<typename H, typename... T>
//void ctx_push(Context& ctx, H&& head, T&&... tail)
//{
// ctx.push(std::forward<H>(head), sizeof...(T) + 1u);
// ctx_push(ctx, std::forward<T>(tail)...);
//}
} // namespace LibLog::Impl::Format
} // namespace LibLog::Impl
} // namespace LibLog
#endif
/*
* Copyright (C) 2019 CZ.NIC, z. s. p. o.
*
* This file is part of FRED.
*
* FRED is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* FRED is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with FRED. If not, see <https://www.gnu.org/licenses/>.
*/
#include "src/liblog/impl/to_spdlog_level.hh"
namespace LibLog {
namespace Impl {
spdlog::level::level_enum to_spdlog_level(Level _level)
{
switch (_level)
{
case Level::trace: return spdlog::level::trace;
case Level::debug: return spdlog::level::debug;
case Level::info: return spdlog::level::info;
case Level::warning: return spdlog::level::warn;
case Level::error: return spdlog::level::err;
case Level::critical: return spdlog::level::critical;
}
throw std::logic_error("invalid LibLog::Level");
};
} // namespace LibLog::Impl
} // namespace LibLog
/*
* Copyright (C) 2019 CZ.NIC, z. s. p. o.
*
* This file is part of FRED.
*
* FRED is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* FRED is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with FRED. If not, see <https://www.gnu.org/licenses/>.
*/
#ifndef TO_SPDLOG_LEVEL_HH_60C652CA688F4DC1A476FA23297430FB
#define TO_SPDLOG_LEVEL_HH_60C652CA688F4DC1A476FA23297430FB
#include "src/liblog/level.hh"
#include <spdlog/spdlog.h>
namespace LibLog {
namespace Impl {
spdlog::level::level_enum to_spdlog_level(Level _level);
} // namespace LibLog::Impl
} // namespace LibLog
#endif
/*
* Copyright (C) 2019 CZ.NIC, z. s. p. o.
*
* This file is part of FRED.
*
* FRED is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* FRED is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with FRED. If not, see <https://www.gnu.org/licenses/>.
*/
#ifndef LEVEL_HH_0377E55365504A8192047DF994EB7FC1
#define LEVEL_HH_0377E55365504A8192047DF994EB7FC1
namespace LibLog {
enum struct Level