1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165
|
/*
* Copyright (C) 2005-2018 Team Kodi
* This file is part of Kodi - https://kodi.tv
*
* SPDX-License-Identifier: GPL-2.0-or-later
* See LICENSES/README.md for more information.
*/
#pragma once
// spdlog specific defines
// clang-format off
#include <string_view>
#define SPDLOG_LEVEL_NAMES \
{ \
std::string_view{"TRACE"}, \
std::string_view{"DEBUG"}, \
std::string_view{"INFO"}, \
std::string_view{"WARNING"}, \
std::string_view{"ERROR"}, \
std::string_view{"FATAL"}, \
std::string_view{"OFF"} \
};
// clang-format on
#include "commons/ilog.h"
#include "settings/lib/ISettingCallback.h"
#include "settings/lib/ISettingsHandler.h"
#include "settings/lib/SettingDefinitions.h"
#include "utils/IPlatformLog.h"
#include "utils/logtypes.h"
#include <string>
#include <vector>
#include <spdlog/spdlog.h>
namespace spdlog
{
namespace sinks
{
class sink;
template<typename Mutex>
class dist_sink;
} // namespace sinks
} // namespace spdlog
#if FMT_VERSION >= 100000
using fmt::enums::format_as;
namespace fmt
{
template<typename T, typename Char>
struct formatter<std::atomic<T>, Char> : formatter<T, Char>
{
};
} // namespace fmt
#endif
class CLog : public ISettingsHandler, public ISettingCallback
{
public:
CLog();
~CLog();
// implementation of ISettingsHandler
void OnSettingsLoaded() override;
// implementation of ISettingCallback
void OnSettingChanged(const std::shared_ptr<const CSetting>& setting) override;
void Initialize(const std::string& path);
void UnregisterFromSettings();
void Deinitialize();
void SetLogLevel(int level);
int GetLogLevel() { return m_logLevel; }
bool IsLogLevelLogged(int loglevel);
bool CanLogComponent(uint32_t component) const;
static void SettingOptionsLoggingComponentsFiller(const std::shared_ptr<const CSetting>& setting,
std::vector<IntegerSettingOption>& list,
int& current,
void* data);
Logger GetLogger(const std::string& loggerName);
template<typename... Args>
static inline void Log(int level, const std::string_view& format, Args&&... args)
{
Log(MapLogLevel(level), format, std::forward<Args>(args)...);
}
template<typename... Args>
static inline void Log(int level,
uint32_t component,
const std::string_view& format,
Args&&... args)
{
if (!GetInstance().CanLogComponent(component))
return;
Log(level, format, std::forward<Args>(args)...);
}
template<typename... Args>
static inline void Log(spdlog::level::level_enum level,
const std::string_view& format,
Args&&... args)
{
GetInstance().FormatAndLogInternal(level, format, std::forward<Args>(args)...);
}
template<typename... Args>
static inline void Log(spdlog::level::level_enum level,
uint32_t component,
const std::string_view& format,
Args&&... args)
{
if (!GetInstance().CanLogComponent(component))
return;
Log(level, format, std::forward<Args>(args)...);
}
#define LogF(level, format, ...) Log((level), ("{}: " format), __FUNCTION__, ##__VA_ARGS__)
#define LogFC(level, component, format, ...) \
Log((level), (component), ("{}: " format), __FUNCTION__, ##__VA_ARGS__)
private:
static CLog& GetInstance();
static spdlog::level::level_enum MapLogLevel(int level);
template<typename... Args>
inline void FormatAndLogInternal(spdlog::level::level_enum level,
const std::string_view& format,
Args&&... args)
{
auto message = fmt::format(format, std::forward<Args>(args)...);
// fixup newline alignment, number of spaces should equal prefix length
FormatLineBreaks(message);
m_defaultLogger->log(level, message);
}
Logger CreateLogger(const std::string& loggerName);
void SetComponentLogLevel(const std::vector<CVariant>& components);
void FormatLineBreaks(std::string& message);
std::unique_ptr<IPlatformLog> m_platform;
std::shared_ptr<spdlog::sinks::dist_sink<std::mutex>> m_sinks;
Logger m_defaultLogger;
std::shared_ptr<spdlog::sinks::sink> m_fileSink;
int m_logLevel;
bool m_componentLogEnabled = false;
uint32_t m_componentLogLevels = 0;
};
|