RAVENNAKIT
Loading...
Searching...
No Matches
log.hpp
Go to the documentation of this file.
1// SPDX-License-Identifier: AGPL-3.0-or-later
2/*
3 * Project: RAVENNAKIT (RAVENNA / AES67 / ST2110-30 SDK)
4 * Copyright (c) 2024-2025 Sound on Digital
5 *
6 * This file is part of RAVENNAKIT.
7 *
8 * RAVENNAKIT is dual-licensed:
9 * 1) Under the terms of the GNU Affero General Public License as published by
10 * the Free Software Foundation, either version 3 of the License, or
11 * (at your option) any later version (the "AGPL License"); and
12 * 2) Under a commercial license from Sound on Digital, for customers who
13 * cannot (or do not wish to) comply with the AGPL License terms.
14 *
15 * If you obtained this file under the AGPL License, you may redistribute it
16 * and/or modify it under the terms of the AGPL License. See the LICENSE
17 * file in the project root for details.
18 *
19 * For commercial licensing, support, and other inquiries, please visit:
20 *
21 * https://ravennakit.com
22 *
23 */
24
25#pragma once
26
27#include "platform.hpp"
28#include "env.hpp"
29#include "string.hpp"
30
31#include <atomic>
32#include <cstdlib>
33
34#ifndef RAV_ENABLE_SPDLOG
35 #define RAV_ENABLE_SPDLOG 0
36#endif
37
38#if RAV_ENABLE_SPDLOG
39
40 #define SPDLOG_ACTIVE_LEVEL SPDLOG_LEVEL_TRACE
41
42 #if RAV_MACOS
43 #define SPDLOG_FUNCTION __PRETTY_FUNCTION__
44 #endif
45
46 #include <spdlog/spdlog.h>
47
48 #ifndef RAV_LOG_TRACE
49 #define RAV_LOG_TRACE(...) SPDLOG_TRACE(__VA_ARGS__)
50 #endif
51
52 #ifndef RAV_LOG_DEBUG
53 #define RAV_LOG_DEBUG(...) SPDLOG_DEBUG(__VA_ARGS__)
54 #endif
55
56 #ifndef RAV_LOG_CRITICAL
57 #define RAV_LOG_CRITICAL(...) SPDLOG_CRITICAL(__VA_ARGS__)
58 #endif
59
60 #ifndef RAV_LOG_ERROR
61 #define RAV_LOG_ERROR(...) SPDLOG_ERROR(__VA_ARGS__)
62 #endif
63
64 #ifndef RAV_LOG_WARNING
65 #define RAV_LOG_WARNING(...) SPDLOG_WARN(__VA_ARGS__)
66 #endif
67
68 #ifndef RAV_LOG_INFO
69 #define RAV_LOG_INFO(...) SPDLOG_INFO(__VA_ARGS__)
70 #endif
71
72 #ifndef RAV_LOG
73 #define RAV_LOG(...) SPDLOG_INFO(__VA_ARGS__)
74 #endif
75
76#else
77
79
81
82inline std::atomic log_level = LogLevel::info;
83
84 #ifndef RAV_LOG_TRACE
85 #define RAV_LOG_TRACE(...) \
86 if (log_level.load() >= LogLevel::trace) { \
87 fmt::println("[T] " __VA_ARGS__); \
88 }
89 #endif
90
91 #ifndef RAV_LOG_DEBUG
92 #define RAV_LOG_DEBUG(...) \
93 if (log_level.load() >= LogLevel::debug) { \
94 fmt::println("[D] " __VA_ARGS__); \
95 }
96 #endif
97
98 #ifndef RAV_LOG_CRITICAL
99 #define RAV_LOG_CRITICAL(...) \
100 if (log_level.load() >= LogLevel::critical) { \
101 fmt::println("[C] " __VA_ARGS__); \
102 }
103 #endif
104
105 #ifndef RAV_LOG_ERROR
106 #define RAV_LOG_ERROR(...) \
107 if (log_level.load() >= LogLevel::error) { \
108 fmt::println("[E] " __VA_ARGS__); \
109 }
110 #endif
111
112 #ifndef RAV_LOG_WARNING
113 #define RAV_LOG_WARNING(...) \
114 if (log_level.load() >= LogLevel::warning) { \
115 fmt::println("[W] " __VA_ARGS__); \
116 }
117 #endif
118
119 #ifndef RAV_LOG_INFO
120 #define RAV_LOG_INFO(...) \
121 if (log_level.load() >= LogLevel::info) { \
122 fmt::println("[I] " __VA_ARGS__); \
123 }
124 #endif
125
126 #ifndef RAV_LOG
127 #define RAV_LOG(...) \
128 if (log_level.load() >= LogLevel::trace) { \
129 fmt::println("[L] " __VA_ARGS__); \
130 }
131 #endif
132
133#endif
134
135#define CATCH_LOG_UNCAUGHT_EXCEPTIONS \
136 catch (const rav::Exception& e) { \
137 RAV_LOG_CRITICAL("rav::Exception caught: {} - please handle your exceptions before reaching this point.", e.what()); \
138 } \
139 catch (const std::exception& e) { \
140 RAV_LOG_CRITICAL("std::exception caucght: {} - please handle your exceptions before reaching this point.", e.what()); \
141 } \
142 catch (...) { \
143 RAV_LOG_CRITICAL("unknown exception caucght - please handle your exceptions before reaching this point."); \
144 }
145
146namespace rav {
147
160inline void set_log_level(const char* level) {
161#if RAV_ENABLE_SPDLOG
162 if (string_compare_case_insensitive(level, "TRACE")) {
163 spdlog::set_level(spdlog::level::trace);
164 } else if (string_compare_case_insensitive(level, "DEBUG")) {
165 spdlog::set_level(spdlog::level::debug);
166 } else if (string_compare_case_insensitive(level, "INFO")) {
167 spdlog::set_level(spdlog::level::info);
168 } else if (string_compare_case_insensitive(level, "WARN")) {
169 spdlog::set_level(spdlog::level::warn);
170 } else if (string_compare_case_insensitive(level, "ERROR")) {
171 spdlog::set_level(spdlog::level::err);
172 } else if (string_compare_case_insensitive(level, "CRITICAL")) {
173 spdlog::set_level(spdlog::level::critical);
174 } else if (string_compare_case_insensitive(level, "OFF")) {
175 spdlog::set_level(spdlog::level::off);
176 } else {
177 fmt::println("Invalid log level: {}. Setting log level to info.", level);
178 spdlog::set_level(spdlog::level::info);
179 }
180#else
181 if (string_compare_case_insensitive(level, "TRACE")) {
183 } else if (string_compare_case_insensitive(level, "DEBUG")) {
185 } else if (string_compare_case_insensitive(level, "INFO")) {
187 } else if (string_compare_case_insensitive(level, "WARN")) {
189 } else if (string_compare_case_insensitive(level, "ERROR")) {
191 } else if (string_compare_case_insensitive(level, "CRITICAL")) {
193 } else if (string_compare_case_insensitive(level, "OFF")) {
195 } else {
196 fmt::println("Invalid log level: {}. Setting log level to info.", level);
198 }
199#endif
200}
201
216inline void set_log_level_from_env(const char* env_var = "RAV_LOG_LEVEL") {
217 if (const auto env_value = get_env(env_var)) {
218 set_log_level(env_value->c_str());
219 } else {
220 set_log_level("INFO");
221 }
222}
223
224} // namespace rav
std::atomic log_level
Definition log.hpp:82
LogLevel
Definition log.hpp:80
@ trace
Definition log.hpp:80
@ off
Definition log.hpp:80
@ warning
Definition log.hpp:80
@ critical
Definition log.hpp:80
@ debug
Definition log.hpp:80
@ info
Definition log.hpp:80
@ error
Definition log.hpp:80
void set_log_level_from_env(const char *env_var="RAV_LOG_LEVEL")
Tries to find given environment variable and set the log level accordingly.
Definition log.hpp:216
std::optional< std::string > get_env(const char *name)
Gets the value of an environment variable.
Definition env.hpp:45
void set_log_level(const char *level)
Sets the log level for the application based on the given string.
Definition log.hpp:160
bool string_compare_case_insensitive(const std::string_view lhs, const std::string_view rhs)
Compares 2 strings case-insensitively.
Definition string.hpp:430