Skip to content

Commit

Permalink
refactor: split logger
Browse files Browse the repository at this point in the history
  • Loading branch information
MistEO committed Oct 31, 2023
1 parent 7f0a286 commit 48e6798
Show file tree
Hide file tree
Showing 3 changed files with 187 additions and 185 deletions.
6 changes: 6 additions & 0 deletions source/include/Conf/Conf.h
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,12 @@
{
#define MAA_PLATFORM_NS_END }

#define MAA_LOG_NS MAA_NS::LogNS
#define MAA_LOG_NS_BEGIN \
namespace MAA_LOG_NS \
{
#define MAA_LOG_NS_END }

/* MaaFramwork */

#define MAA_RES_NS MAA_NS::ResourceNS
Expand Down
186 changes: 1 addition & 185 deletions source/include/Utils/Logger.h
Original file line number Diff line number Diff line change
@@ -1,176 +1,11 @@
#pragma once

#include <filesystem>
#include <fstream>
#include <iostream>
#include <mutex>
#include <source_location>
#include <thread>
#include <tuple>
#include <type_traits>

#if defined(__APPLE__) || defined(__linux__)
#include <unistd.h>
#endif

#include <meojson/json.hpp>

#include "Conf/Conf.h"
#include "MaaFramework/MaaDef.h"
#include "MaaFramework/MaaPort.h"

#include "Format.hpp"
#include "Locale.hpp"
#include "Platform.h"
#include "Ranges.hpp"
#include "Time.hpp"

#define MAA_LOG_NS MAA_NS::LogNS
#define MAA_LOG_NS_BEGIN \
namespace MAA_LOG_NS \
{
#define MAA_LOG_NS_END }
#include "LoggerUtils.h"

MAA_LOG_NS_BEGIN

#ifdef __GNUC__
std::ostream& operator<<(std::ostream& os, const std::chrono::milliseconds& ms);
#endif
template <typename T>
std::ostream& operator<<(std::ostream& os, const std::optional<T>& v);

template <typename T>
concept has_output_operator = requires { std::declval<std::ostream&>() << std::declval<T>(); };

enum class level
{
fatal = MaaLoggingLevel_Fatal,
error = MaaLoggingLevel_Error,
warn = MaaLoggingLevel_Warn,
info = MaaLoggingLevel_Info,
debug = MaaLoggingLevel_Debug,
trace = MaaLoggingLevel_Trace,
};

struct MAA_UTILS_API separator
{
constexpr separator(std::string_view s) noexcept : str(s) {}

static const separator none;
static const separator space;
static const separator tab;
static const separator newline;
static const separator comma;

std::string_view str;
};

struct StringConverter
{
template <typename T>
static constexpr bool is_convertible = std::same_as<std::filesystem::path, std::decay_t<T>> ||
std::same_as<std::wstring, std::decay_t<T>> || has_output_operator<T>;

template <typename T>
std::string operator()(T&& value) const
{
if constexpr (std::same_as<std::filesystem::path, std::decay_t<T>>) {
return path_to_utf8_string(std::forward<T>(value));
}
else if constexpr (std::same_as<std::wstring, std::decay_t<T>>) {
return from_u16(std::forward<T>(value));
}
else if constexpr (has_output_operator<T>) {
return to_stringstream(std::forward<T>(value));
}
else {
return json::serialize<true>(std::forward<T>(value), *this).to_string();
}
}

template <typename T>
std::string to_stringstream(T&& value) const
{
std::stringstream ss;
if constexpr (std::same_as<bool, std::decay_t<T>>) {
ss << std::boolalpha;
}
ss << std::forward<T>(value);
return std::move(ss).str();
}
};

class MAA_UTILS_API LogStream
{
public:
template <typename... args_t>
LogStream(std::mutex& m, std::ofstream& s, level lv, bool std_out, args_t&&... args)
: mutex_(m), stream_(s), lv_(lv), stdout_(std_out)
{
stream_props(std::forward<args_t>(args)...);
}
LogStream(const LogStream&) = delete;
LogStream(LogStream&&) noexcept = default;
~LogStream()
{
std::unique_lock<std::mutex> lock(mutex_);

if (stdout_) {
std::cout << stdout_string() << std::endl;
}
stream_ << std::move(buffer_).str() << std::endl;
}

template <typename T>
LogStream& operator<<(T&& value)
{
if constexpr (std::is_same_v<std::decay_t<T>, separator>) {
sep_ = std::forward<T>(value);
}
else {
stream(std::forward<T>(value));
}
return *this;
}

private:
template <typename T>
void stream(T&& value)
{
buffer_ << string_converter_(std::forward<T>(value)) << sep_.str;
}

template <typename... args_t>
void stream_props(args_t&&... args)
{
#ifdef _WIN32
int pid = _getpid();
#else
int pid = ::getpid();
#endif
auto tid = static_cast<unsigned short>(std::hash<std::thread::id> {}(std::this_thread::get_id()));

std::string props = MAA_FMT::format("[{}][{}][Px{}][Tx{}]", format_now(), level_str(), pid, tid);
for (auto&& arg : { args... }) {
props += MAA_FMT::format("[{}]", arg);
}
stream(props);
}

std::string stdout_string();
std::string_view level_str();

private:
std::mutex& mutex_;
std::ofstream& stream_;
const level lv_ = level::error;
const bool stdout_ = false;
const StringConverter string_converter_;

separator sep_ = separator::space;
std::stringstream buffer_;
};

class MAA_UTILS_API Logger
{
public:
Expand Down Expand Up @@ -283,25 +118,6 @@ class ScopeLeaveHelper
std::chrono::time_point<std::chrono::steady_clock> start_ = std::chrono::steady_clock::now();
};

#ifdef __GNUC__
inline std::ostream& operator<<(std::ostream& os, const std::chrono::milliseconds& ms)
{
return os << ms.count() << "ms";
}
#endif

template <typename T>
std::ostream& operator<<(std::ostream& os, const std::optional<T>& v)
{
if (v) {
os << *v;
}
else {
os << "<nullopt>";
}
return os;
}

inline constexpr std::string_view pertty_file(std::string_view file)
{
size_t pos = file.find_last_of(std::filesystem::path::preferred_separator);
Expand Down
180 changes: 180 additions & 0 deletions source/include/Utils/LoggerUtils.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,180 @@
#pragma once

#include <filesystem>
#include <fstream>
#include <iostream>
#include <mutex>
#include <thread>
#include <tuple>
#include <type_traits>

#if defined(__APPLE__) || defined(__linux__)
#include <unistd.h>
#endif

#include <meojson/json.hpp>

#include "Conf/Conf.h"
#include "MaaFramework/MaaDef.h"
#include "MaaFramework/MaaPort.h"

#include "Format.hpp"
#include "Locale.hpp"
#include "Platform.h"
#include "Ranges.hpp"
#include "Time.hpp"

MAA_LOG_NS_BEGIN

#ifdef __GNUC__
inline std::ostream& operator<<(std::ostream& os, const std::chrono::milliseconds& ms)
{
return os << ms.count() << "ms";
}
#endif

template <typename T>
inline std::ostream& operator<<(std::ostream& os, const std::optional<T>& v)
{
if (v) {
os << *v;
}
else {
os << "<nullopt>";
}
return os;
}

enum class level
{
fatal = MaaLoggingLevel_Fatal,
error = MaaLoggingLevel_Error,
warn = MaaLoggingLevel_Warn,
info = MaaLoggingLevel_Info,
debug = MaaLoggingLevel_Debug,
trace = MaaLoggingLevel_Trace,
};

struct MAA_UTILS_API separator
{
constexpr separator(std::string_view s) noexcept : str(s) {}

static const separator none;
static const separator space;
static const separator tab;
static const separator newline;
static const separator comma;

std::string_view str;
};

template <typename T>
concept has_output_operator = requires { std::declval<std::ostream&>() << std::declval<T>(); };

struct StringConverter
{
template <typename T>
static constexpr bool is_convertible = std::same_as<std::filesystem::path, std::decay_t<T>> ||
std::same_as<std::wstring, std::decay_t<T>> || has_output_operator<T>;

template <typename T>
std::string operator()(T&& value) const
{
if constexpr (std::same_as<std::filesystem::path, std::decay_t<T>>) {
return path_to_utf8_string(std::forward<T>(value));
}
else if constexpr (std::same_as<std::wstring, std::decay_t<T>>) {
return from_u16(std::forward<T>(value));
}
else if constexpr (has_output_operator<T>) {
return to_stringstream(std::forward<T>(value));
}
else {
return json::serialize<true>(std::forward<T>(value), *this).to_string();
}
}

template <typename T>
std::string to_stringstream(T&& value) const
{
std::stringstream ss;
if constexpr (std::same_as<bool, std::decay_t<T>>) {
ss << std::boolalpha;
}
ss << std::forward<T>(value);
return std::move(ss).str();
}
};

class MAA_UTILS_API LogStream
{
public:
template <typename... args_t>
LogStream(std::mutex& m, std::ofstream& s, level lv, bool std_out, args_t&&... args)
: mutex_(m), stream_(s), lv_(lv), stdout_(std_out)
{
stream_props(std::forward<args_t>(args)...);
}
LogStream(const LogStream&) = delete;
LogStream(LogStream&&) noexcept = default;
~LogStream()
{
std::unique_lock<std::mutex> lock(mutex_);

if (stdout_) {
std::cout << stdout_string() << std::endl;
}
stream_ << std::move(buffer_).str() << std::endl;
}

template <typename T>
LogStream& operator<<(T&& value)
{
if constexpr (std::is_same_v<std::decay_t<T>, separator>) {
sep_ = std::forward<T>(value);
}
else {
stream(std::forward<T>(value));
}
return *this;
}

private:
template <typename T>
void stream(T&& value)
{
buffer_ << string_converter_(std::forward<T>(value)) << sep_.str;
}

template <typename... args_t>
void stream_props(args_t&&... args)
{
#ifdef _WIN32
int pid = _getpid();
#else
int pid = ::getpid();
#endif
auto tid = static_cast<unsigned short>(std::hash<std::thread::id> {}(std::this_thread::get_id()));

std::string props = MAA_FMT::format("[{}][{}][Px{}][Tx{}]", format_now(), level_str(), pid, tid);
for (auto&& arg : { args... }) {
props += MAA_FMT::format("[{}]", arg);
}
stream(props);
}

std::string stdout_string();
std::string_view level_str();

private:
std::mutex& mutex_;
std::ofstream& stream_;
const level lv_ = level::fatal;
const bool stdout_ = false;
const StringConverter string_converter_;

separator sep_ = separator::space;
std::stringstream buffer_;
};

MAA_LOG_NS_END

0 comments on commit 48e6798

Please sign in to comment.