Branch data Line data Source code
1 : : // Copyright 2026 HPActor Contributors
2 : : //
3 : : // Licensed under the Apache License, Version 2.0 (the "License");
4 : : // you may not use this file except in compliance with the License.
5 : : // You may obtain a copy of the License at
6 : : //
7 : : // http://www.apache.org/licenses/LICENSE-2.0
8 : : //
9 : : // Unless required by applicable law or agreed to in writing, software
10 : : // distributed under the License is distributed on an "AS IS" BASIS,
11 : : // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 : : // See the License for the specific language governing permissions and
13 : : // limitations under the License.
14 : :
15 : : #pragma once
16 : :
17 : : #include <array>
18 : :
19 : : #include "hpactor/hpactor_config.hpp"
20 : : #include "hpactor/log/log_category.hpp"
21 : : #include "hpactor/log/log_event.hpp"
22 : : #include "hpactor/log/log_field.hpp"
23 : : #include "hpactor/log/log_level.hpp"
24 : : #include "hpactor/types/types.hpp"
25 : :
26 : : namespace hpactor::log {
27 : :
28 : : class Logger {
29 : : public:
30 : 112 : Logger() = default;
31 : :
32 : : // Set by LogManager when logging is active
33 : : void
34 : 224 : configure(class LogRingBuffer* buffer,
35 : : const std::array<LogLevel, static_cast<size_t>(LogCategory::kCount)>* levels,
36 : : LogLevel flush_on_level = LogLevel::kError,
37 : : void (*nudge_fn)(void*) noexcept = nullptr,
38 : : void* nudge_ctx = nullptr) noexcept {
39 : 224 : buffer_ = buffer;
40 : 224 : levels_ = levels;
41 : 224 : flush_on_level_ = flush_on_level;
42 : 224 : nudge_fn_ = nudge_fn;
43 : 224 : nudge_ctx_ = nudge_ctx;
44 : 224 : }
45 : :
46 : 12183 : bool enabled(LogLevel level, LogCategory category) const noexcept {
47 : 12183 : if (!buffer_ || !levels_)
48 : 1155 : return false;
49 : 11028 : auto idx = static_cast<size_t>(category);
50 : 11028 : LogLevel threshold = (*levels_)[idx];
51 : 11028 : if (threshold == LogLevel::kOff)
52 : 2 : return false;
53 : 11026 : return static_cast<uint8_t>(level) <= static_cast<uint8_t>(threshold);
54 : : }
55 : :
56 : 0 : void nudge() noexcept {
57 : 0 : if (nudge_fn_)
58 : 0 : nudge_fn_(nudge_ctx_);
59 : 0 : }
60 : :
61 : : void emit(LogEvent event) noexcept;
62 : :
63 : : void emit(LogLevel level, LogCategory category, ActorId actor_id,
64 : : uint32_t event_id, const char* message, const LogField* fields,
65 : : uint8_t field_count, const char* file, uint32_t line) noexcept;
66 : :
67 : : uint64_t fields_dropped() const noexcept {
68 : : return fields_dropped_;
69 : : }
70 : :
71 : : private:
72 : : class LogRingBuffer* buffer_ = nullptr;
73 : : const std::array<LogLevel, static_cast<size_t>(LogCategory::kCount)>* levels_ =
74 : : nullptr;
75 : : LogLevel flush_on_level_ = LogLevel::kError;
76 : : uint64_t fields_dropped_{0};
77 : : void (*nudge_fn_)(void*) noexcept = nullptr;
78 : : void* nudge_ctx_ = nullptr;
79 : : };
80 : :
81 : : Logger& global_logger() noexcept;
82 : :
83 : : } // namespace hpactor::log
84 : :
85 : : #if HPACTOR_ENABLE_ACTOR_LOGGING
86 : :
87 : : # define HPACTOR_LOG_CRITICAL(category, actor_id, event_id, message, ...) \
88 : : do { \
89 : : auto& __hpactor_logger = ::hpactor::log::global_logger(); \
90 : : if (__hpactor_logger.enabled(::hpactor::log::LogLevel::kCritical, \
91 : : category)) { \
92 : : ::hpactor::log::LogField __hpactor_fields[] = {__VA_ARGS__}; \
93 : : __hpactor_logger.emit( \
94 : : ::hpactor::log::LogLevel::kCritical, category, actor_id, \
95 : : event_id, message, __hpactor_fields, \
96 : : static_cast<uint8_t>(sizeof(__hpactor_fields) / \
97 : : sizeof(__hpactor_fields[0])), \
98 : : __FILE__, __LINE__); \
99 : : } \
100 : : } while (0)
101 : :
102 : : # define HPACTOR_LOG_ERROR(category, actor_id, event_id, message, ...) \
103 : : do { \
104 : : auto& __hpactor_logger = ::hpactor::log::global_logger(); \
105 : : if (__hpactor_logger.enabled(::hpactor::log::LogLevel::kError, \
106 : : category)) { \
107 : : ::hpactor::log::LogField __hpactor_fields[] = {__VA_ARGS__}; \
108 : : __hpactor_logger.emit( \
109 : : ::hpactor::log::LogLevel::kError, category, actor_id, \
110 : : event_id, message, __hpactor_fields, \
111 : : static_cast<uint8_t>(sizeof(__hpactor_fields) / \
112 : : sizeof(__hpactor_fields[0])), \
113 : : __FILE__, __LINE__); \
114 : : } \
115 : : } while (0)
116 : :
117 : : # define HPACTOR_LOG_WARNING(category, actor_id, event_id, message, ...) \
118 : : do { \
119 : : auto& __hpactor_logger = ::hpactor::log::global_logger(); \
120 : : if (__hpactor_logger.enabled(::hpactor::log::LogLevel::kWarning, \
121 : : category)) { \
122 : : ::hpactor::log::LogField __hpactor_fields[] = {__VA_ARGS__}; \
123 : : __hpactor_logger.emit( \
124 : : ::hpactor::log::LogLevel::kWarning, category, actor_id, \
125 : : event_id, message, __hpactor_fields, \
126 : : static_cast<uint8_t>(sizeof(__hpactor_fields) / \
127 : : sizeof(__hpactor_fields[0])), \
128 : : __FILE__, __LINE__); \
129 : : } \
130 : : } while (0)
131 : :
132 : : # define HPACTOR_LOG_INFO(category, actor_id, event_id, message, ...) \
133 : : do { \
134 : : auto& __hpactor_logger = ::hpactor::log::global_logger(); \
135 : : if (__hpactor_logger.enabled(::hpactor::log::LogLevel::kInfo, \
136 : : category)) { \
137 : : ::hpactor::log::LogField __hpactor_fields[] = {__VA_ARGS__}; \
138 : : __hpactor_logger.emit( \
139 : : ::hpactor::log::LogLevel::kInfo, category, actor_id, \
140 : : event_id, message, __hpactor_fields, \
141 : : static_cast<uint8_t>(sizeof(__hpactor_fields) / \
142 : : sizeof(__hpactor_fields[0])), \
143 : : __FILE__, __LINE__); \
144 : : } \
145 : : } while (0)
146 : :
147 : : # define HPACTOR_LOG_DEBUG(category, actor_id, event_id, message, ...) \
148 : : do { \
149 : : auto& __hpactor_logger = ::hpactor::log::global_logger(); \
150 : : if (__hpactor_logger.enabled(::hpactor::log::LogLevel::kDebug, \
151 : : category)) { \
152 : : ::hpactor::log::LogField __hpactor_fields[] = {__VA_ARGS__}; \
153 : : __hpactor_logger.emit( \
154 : : ::hpactor::log::LogLevel::kDebug, category, actor_id, \
155 : : event_id, message, __hpactor_fields, \
156 : : static_cast<uint8_t>(sizeof(__hpactor_fields) / \
157 : : sizeof(__hpactor_fields[0])), \
158 : : __FILE__, __LINE__); \
159 : : } \
160 : : } while (0)
161 : :
162 : : # define HPACTOR_LOG_TRACE(category, actor_id, event_id, message, ...) \
163 : : do { \
164 : : auto& __hpactor_logger = ::hpactor::log::global_logger(); \
165 : : if (__hpactor_logger.enabled(::hpactor::log::LogLevel::kTrace, \
166 : : category)) { \
167 : : ::hpactor::log::LogField __hpactor_fields[] = {__VA_ARGS__}; \
168 : : __hpactor_logger.emit( \
169 : : ::hpactor::log::LogLevel::kTrace, category, actor_id, \
170 : : event_id, message, __hpactor_fields, \
171 : : static_cast<uint8_t>(sizeof(__hpactor_fields) / \
172 : : sizeof(__hpactor_fields[0])), \
173 : : __FILE__, __LINE__); \
174 : : } \
175 : : } while (0)
176 : :
177 : : #else // HPACTOR_ENABLE_ACTOR_LOGGING disabled
178 : :
179 : : # define HPACTOR_LOG_CRITICAL(category, actor_id, event_id, message, ...) \
180 : : ((void)0)
181 : : # define HPACTOR_LOG_ERROR(category, actor_id, event_id, message, ...) \
182 : : ((void)0)
183 : : # define HPACTOR_LOG_WARNING(category, actor_id, event_id, message, ...) \
184 : : ((void)0)
185 : : # define HPACTOR_LOG_INFO(category, actor_id, event_id, message, ...) \
186 : : ((void)0)
187 : : # define HPACTOR_LOG_DEBUG(category, actor_id, event_id, message, ...) \
188 : : ((void)0)
189 : : # define HPACTOR_LOG_TRACE(category, actor_id, event_id, message, ...) \
190 : : ((void)0)
191 : :
192 : : #endif // HPACTOR_ENABLE_ACTOR_LOGGING
|