Add logger

This commit is contained in:
sha512sum 2024-07-02 16:28:32 +00:00 committed by sha512sum
parent adc59bcbc7
commit f3f1ac56c0
5 changed files with 136 additions and 6 deletions

View file

@ -17,9 +17,12 @@ struct SomeComponent : public cserver::server::handlers::HttpHandlerBaseWithAdde
auto main() -> int { auto main() -> int {
cserver::ServiceContextBuilder{} cserver::ServiceContextBuilder{}
.AppendConfigParam<"threads", 8>() .AppendConfigParam<"threads", 8>()
.AppendConfigParam<"logging", cserver::ConstexprConfig{}
.Append<"level">(cserver::LoggingLevel::kWarning)>()
.AppendConfigParam<"server", cserver::ConstexprConfig{} .AppendConfigParam<"server", cserver::ConstexprConfig{}
.Append<"taskProcessor">(utempl::ConstexprString{"basicTaskProcessor"}) .Append<"taskProcessor">(utempl::ConstexprString{"basicTaskProcessor"})
.Append<"port">(55555)>() .Append<"port">(55555)>()
.Append<cserver::Logging>()
.Append<cserver::server::server::Server<>>() .Append<cserver::server::server::Server<>>()
.Append<SomeComponent, "component">() .Append<SomeComponent, "component">()
.Sort() .Sort()

23
examples/src/log.cpp Normal file
View file

@ -0,0 +1,23 @@
#include <cserver/components/loggable_component_base.hpp>
struct SomeComponent : cserver::ComponentBase {
static constexpr utempl::ConstexprString kName = "component";
using cserver::ComponentBase::ComponentBase;
constexpr auto Run() -> void {
LOG_DEBUG<"Hello {}">("world!");
};
};
auto main() -> int {
cserver::ServiceContextBuilder{}
.AppendConfigParam<"threads", 8>()
.AppendConfigParam<"logging", cserver::ConstexprConfig{}
.Append<"level">(cserver::LoggingLevel::kTrace)>()
.Append<cserver::Logging>()
.Append<SomeComponent>()
.Sort()
.Run();
};

View file

@ -0,0 +1,24 @@
#pragma once
#include <cserver/components/logger.hpp>
#include <cserver/engine/components.hpp>
namespace cserver {
struct ComponentBase {
Logging& logging;
template <typename T>
constexpr ComponentBase(T& context) :
logging(context.template FindComponent<"logging">()) {};
};
#define LOG_TRACE if(this->logging.level == ::cserver::LoggingLevel::kTrace) this->logging.Trace
#define LOG_DEBUG if(this->logging.level <= ::cserver::LoggingLevel::kDebug) this->logging.Debug
#define LOG_INFO if(this->logging.level <= ::cserver::LoggingLevel::kInfo) this->logging.Info
#define LOG_WARNING if(this->logging.level <= ::cserver::LoggingLevel::kWarning) this->logging.Warning
#define LOG_ERROR if(this->logging.level <= ::cserver::LoggingLevel::kError) this->logging.Error
} // namespace cserver

View file

@ -0,0 +1,78 @@
#pragma once
#include <utempl/constexpr_string.hpp>
#include <array>
#include <fmt/compile.h>
#include <fmt/format.h>
#include <iostream>
namespace cserver {
enum class LoggingLevel {
kTrace,
kDebug,
kInfo,
kWarning,
kError
};
struct Logging {
static constexpr utempl::ConstexprString kName = "logging";
LoggingLevel level;
template <typename T>
constexpr Logging(T&) : level(T::kConfig.template Get<T::kName>().template Get<"level">()) {
std::ios::sync_with_stdio(false);
};
constexpr auto SetLoggingLevel(LoggingLevel level) {
this->level = level;
};
template <std::size_t N, std::size_t NN>
static consteval auto GetFormatStringFor(utempl::ConstexprString<N> fmt, utempl::ConstexprString<NN> level) {
constexpr auto f = FMT_COMPILE("[{}]: {}\n");
constexpr auto size = N + NN + 6;
char data[size]{};
fmt::format_to(data, f, static_cast<std::string_view>(level), static_cast<std::string_view>(fmt));
return utempl::ConstexprString<size>(data);
};
constexpr auto Log(std::string_view data) {
std::cout << data;
};
template <utempl::ConstexprString Fmt, typename... Ts>
constexpr auto Debug(Ts&&... args) {
static constexpr auto fmt = GetFormatStringFor(Fmt, utempl::ConstexprString{"DEBUG"});
Log(fmt::format(FMT_COMPILE(fmt.data.begin()), std::forward<Ts>(args)...));
};
template <utempl::ConstexprString Fmt, typename... Ts>
constexpr auto Info(Ts&&... args) {
static constexpr auto fmt = GetFormatStringFor(Fmt, utempl::ConstexprString{"INFO"});
Log(fmt::format(FMT_COMPILE(fmt.data.begin()), std::forward<Ts>(args)...));
};
template <utempl::ConstexprString Fmt, typename... Ts>
constexpr auto Trace(Ts&&... args) {
static constexpr auto fmt = GetFormatStringFor(Fmt, utempl::ConstexprString{"TRACE"});
Log(fmt::format(FMT_COMPILE(fmt.data.begin()), std::forward<Ts>(args)...));
};
template <utempl::ConstexprString Fmt, typename... Ts>
constexpr auto Error(Ts&&... args) {
static constexpr auto fmt = GetFormatStringFor(Fmt, utempl::ConstexprString{"ERROR"});
Log(fmt::format(FMT_COMPILE(fmt.data.begin()), std::forward<Ts>(args)...));
};
template <utempl::ConstexprString Fmt, typename... Ts>
constexpr auto Warning(Ts&&... args) {
static constexpr auto fmt = GetFormatStringFor(Fmt, utempl::ConstexprString{"WARNING"});
Log(fmt::format(FMT_COMPILE(fmt.data.begin()), std::forward<Ts>(args)...));
};
};
} // namespace cserver

View file

@ -4,10 +4,11 @@
#include <cserver/server/http/http_response.hpp> #include <cserver/server/http/http_response.hpp>
#include <cserver/server/http/http_stream.hpp> #include <cserver/server/http/http_stream.hpp>
#include <cserver/engine/coroutine.hpp> #include <cserver/engine/coroutine.hpp>
#include <cserver/components/loggable_component_base.hpp>
namespace cserver::server::handlers { namespace cserver::server::handlers {
struct HttpHandlerBase { struct HttpHandlerBase : ComponentBase {
template <typename T, utempl::ConstexprString name, Options Options> template <typename T, utempl::ConstexprString name, Options Options>
static consteval auto HttpHandlerAdder(const auto& context) { static consteval auto HttpHandlerAdder(const auto& context) {
return context.TransformComponents([]<typename TT>(const ComponentConfig<T::kHandlerManagerName, TT, Options>) { return context.TransformComponents([]<typename TT>(const ComponentConfig<T::kHandlerManagerName, TT, Options>) {
@ -21,9 +22,9 @@ struct HttpHandlerBase {
try { try {
co_return co_await std::forward<Self>(self).HandleRequestThrow(std::move(request)); co_return co_await std::forward<Self>(self).HandleRequestThrow(std::move(request));
} catch(const std::exception& err) { } catch(const std::exception& err) {
fmt::println("Error in handler with default name {}: {}", T::kName, err.what()); self.logging.template Warning<"Error in handler with default name {}: {}">(T::kName, err.what());
} catch(...) { } catch(...) {
fmt::println("Error in handler with default name {}: Unknown Error", T::kName); self.logging.template Warning<"Error in handler with default name {}: Unknown Error">(T::kName);
}; };
co_return http::HttpResponse{.statusCode = 500, .statusMessage = "Internal Server Error", .body = "Internal Server Error"}; co_return http::HttpResponse{.statusCode = 500, .statusMessage = "Internal Server Error", .body = "Internal Server Error"};
}; };
@ -34,13 +35,14 @@ struct HttpHandlerBase {
try { try {
co_await std::forward<Self>(self).HandleRequestStreamThrow(std::move(request), stream); co_await std::forward<Self>(self).HandleRequestStreamThrow(std::move(request), stream);
} catch(const std::exception& err) { } catch(const std::exception& err) {
fmt::println("Error in handler with default name {}: {}", T::kName, err.what()); self.logging.template Warning<"Error in handler with default name {}: {}">(T::kName, err.what());
} catch(...) { } catch(...) {
fmt::println("Error in handler with default name {}: Unknown Error", T::kName); self.logging.template Warning<"Error in handler with default name {}: Unknown Error">(T::kName);
}; };
co_await stream.Close(); co_await stream.Close();
}; };
inline constexpr HttpHandlerBase(auto&) {}; inline constexpr HttpHandlerBase(auto& context) :
ComponentBase(context) {};
}; };
template <typename T> template <typename T>
struct HttpHandlerAdderType { struct HttpHandlerAdderType {