32
32
namespace beast {
33
33
34
34
std::optional<Journal::JsonLogAttributes> Journal::globalLogAttributes_;
35
+ std::optional<std::string> Journal::globalLogAttributesJson_;
36
+
35
37
std::mutex Journal::globalLogAttributesMutex_;
36
38
bool Journal::m_jsonLogsEnabled = false ;
37
39
thread_local Journal::JsonLogContext Journal::currentJsonLogContext_{};
@@ -169,11 +171,44 @@ Journal::JsonLogAttributes::combine(
169
171
}
170
172
}
171
173
174
+ Journal::Journal (
175
+ Journal const & other,
176
+ std::optional<JsonLogAttributes> attributes)
177
+ : m_attributes(other.m_attributes), m_sink(other.m_sink)
178
+ {
179
+ if (attributes.has_value ())
180
+ {
181
+ if (m_attributes)
182
+ m_attributes->combine (attributes->contextValues_ );
183
+ else
184
+ m_attributes = std::move (attributes);
185
+ }
186
+ rebuildAttributeJson ();
187
+ }
188
+
189
+ void
190
+ Journal::addGlobalAttributes (JsonLogAttributes globalLogAttributes)
191
+ {
192
+ std::lock_guard lock (globalLogAttributesMutex_);
193
+ if (!globalLogAttributes_)
194
+ {
195
+ globalLogAttributes_ = JsonLogAttributes{};
196
+ }
197
+ globalLogAttributes_->combine (globalLogAttributes.contextValues ());
198
+
199
+ rapidjson::StringBuffer buffer;
200
+ rapidjson::Writer writer{buffer};
201
+
202
+ globalLogAttributes_->contextValues ().Accept (writer);
203
+
204
+ globalLogAttributesJson_ = {buffer.GetString ()};
205
+ }
206
+
172
207
void
173
208
Journal::JsonLogContext::reset (
174
209
std::source_location location,
175
210
severities::Severity severity,
176
- std::optional<JsonLogAttributes > const & attributes ) noexcept
211
+ std::optional<std::string > const & journalAttributesJson ) noexcept
177
212
{
178
213
struct ThreadIdStringInitializer
179
214
{
@@ -187,67 +222,37 @@ Journal::JsonLogContext::reset(
187
222
};
188
223
thread_local ThreadIdStringInitializer const threadId;
189
224
190
- attributes_.SetObject ();
191
- if (globalLogAttributes_.has_value ())
192
- {
193
- attributes_.CopyFrom (globalLogAttributes_->contextValues (), allocator_);
194
- if (attributes.has_value ())
195
- {
196
- for (auto const & [key, value] :
197
- attributes->contextValues ().GetObject ())
198
- {
199
- attributes_.RemoveMember (key);
200
-
201
- rapidjson::Value jsonValue;
202
- jsonValue.CopyFrom (value, allocator_);
203
-
204
- attributes_.AddMember (
205
- rapidjson::Value{key, allocator_},
206
- rapidjson::Value{value, allocator_},
207
- allocator_);
208
- }
209
- }
210
- }
211
- else if (attributes.has_value ())
212
- {
213
- attributes_.CopyFrom (attributes->contextValues (), allocator_);
214
- }
225
+ journalAttributesJson_ = journalAttributesJson;
226
+
227
+ messageParams_.SetObject ();
215
228
216
- attributes_.RemoveMember (" Function" );
217
- attributes_.AddMember (
229
+ messageParams_.AddMember (
218
230
rapidjson::StringRef (" Function" ),
219
231
rapidjson::Value{location.function_name (), allocator_},
220
232
allocator_);
221
233
222
- attributes_.RemoveMember (" File" );
223
- attributes_.AddMember (
234
+ messageParams_.AddMember (
224
235
rapidjson::StringRef (" File" ),
225
236
rapidjson::Value{location.file_name (), allocator_},
226
237
allocator_);
227
238
228
- attributes_.RemoveMember (" Line" );
229
- attributes_.AddMember (
239
+ messageParams_.AddMember (
230
240
rapidjson::StringRef (" Line" ),
231
241
location.line (),
232
242
allocator_);
233
- attributes_. RemoveMember ( " ThreadId " );
234
- attributes_ .AddMember (
243
+
244
+ messageParams_ .AddMember (
235
245
rapidjson::StringRef (" ThreadId" ),
236
246
rapidjson::Value{threadId.value .c_str (), allocator_},
237
247
allocator_);
238
- attributes_.RemoveMember (" Params" );
239
- attributes_.AddMember (
240
- rapidjson::StringRef (" Params" ),
241
- rapidjson::Value{rapidjson::kObjectType },
242
- allocator_);
248
+
243
249
auto severityStr = to_string (severity);
244
- attributes_.RemoveMember (" Level" );
245
- attributes_.AddMember (
250
+ messageParams_.AddMember (
246
251
rapidjson::StringRef (" Level" ),
247
252
rapidjson::Value{severityStr.c_str (), allocator_},
248
253
allocator_);
249
- attributes_. RemoveMember ( " Time " );
250
- attributes_ .AddMember (
254
+
255
+ messageParams_ .AddMember (
251
256
rapidjson::StringRef (" Time" ),
252
257
std::chrono::duration_cast<std::chrono::milliseconds>(
253
258
std::chrono::system_clock::now ().time_since_epoch ())
@@ -260,7 +265,7 @@ Journal::initMessageContext(
260
265
std::source_location location,
261
266
severities::Severity severity) const
262
267
{
263
- currentJsonLogContext_.reset (location, severity, m_attributes );
268
+ currentJsonLogContext_.reset (location, severity, m_attributesJson );
264
269
}
265
270
266
271
std::string
@@ -271,23 +276,59 @@ Journal::formatLog(std::string&& message)
271
276
return message;
272
277
}
273
278
274
- auto & attributes = currentJsonLogContext_.attributes ();
275
-
276
- attributes.RemoveMember (" Message" );
277
- attributes.AddMember (
278
- rapidjson::StringRef (" Message" ),
279
- rapidjson::Value{rapidjson::StringRef (message.c_str ()), currentJsonLogContext_.allocator ()},
280
- currentJsonLogContext_.allocator ()
281
- );
279
+ auto & messageParams = currentJsonLogContext_.messageParams ();
282
280
283
281
rapidjson::StringBuffer buffer;
284
282
rapidjson::Writer writer (buffer);
285
283
286
- attributes.Accept (writer);
284
+ writer.StartObject ();
285
+ if (globalLogAttributesJson_.has_value ())
286
+ {
287
+ writer.Key (" GlobalParams" );
288
+ writer.RawValue (
289
+ globalLogAttributesJson_->c_str (),
290
+ globalLogAttributesJson_->length (),
291
+ rapidjson::kObjectType );
292
+ }
293
+
294
+ if (currentJsonLogContext_.journalAttributesJson ().has_value ())
295
+ {
296
+ writer.Key (" JournalParams" );
297
+ writer.RawValue (
298
+ currentJsonLogContext_.journalAttributesJson ()->c_str (),
299
+ currentJsonLogContext_.journalAttributesJson ()->length (),
300
+ rapidjson::kObjectType );
301
+ }
302
+
303
+ writer.Key (" MessageParams" );
304
+ messageParams.Accept (writer);
305
+
306
+ writer.Key (" Message" );
307
+ writer.String (message.c_str (), message.length ());
308
+
309
+ writer.EndObject ();
287
310
288
311
return {buffer.GetString ()};
289
312
}
290
313
314
+ void
315
+ Journal::rebuildAttributeJson ()
316
+ {
317
+ if (m_attributes.has_value ())
318
+ {
319
+ rapidjson::StringBuffer buffer;
320
+ rapidjson::Writer writer{buffer};
321
+
322
+ m_attributes->contextValues ().Accept (writer);
323
+
324
+ m_attributesJson = {buffer.GetString ()};
325
+ }
326
+ else
327
+ {
328
+ m_attributesJson = {};
329
+ }
330
+ }
331
+
291
332
void
292
333
Journal::enableStructuredJournal ()
293
334
{
0 commit comments