BDE 4.14.0 Production release
Loading...
Searching...
No Matches
ball_recordjsonformatter.h
Go to the documentation of this file.
1/// @file ball_recordjsonformatter.h
2///
3/// The content of this file has been pre-processed for Doxygen.
4///
5
6
7// ball_recordjsonformatter.h -*-C++-*-
8
9#ifndef INCLUDED_BALL_RECORDJSONFORMATTER
10#define INCLUDED_BALL_RECORDJSONFORMATTER
11
12#include <bsls_ident.h>
13BSLS_IDENT("$Id: $")
14
15/// @defgroup ball_recordjsonformatter ball_recordjsonformatter
16/// @brief Provide a formatter for log records that renders output in JSON.
17/// @addtogroup bal
18/// @{
19/// @addtogroup ball
20/// @{
21/// @addtogroup ball_recordjsonformatter
22/// @{
23///
24/// <h1> Outline </h1>
25/// * <a href="#ball_recordjsonformatter-purpose"> Purpose</a>
26/// * <a href="#ball_recordjsonformatter-classes"> Classes </a>
27/// * <a href="#ball_recordjsonformatter-description"> Description </a>
28/// * <a href="#ball_recordjsonformatter-record-format-specification"> Record Format Specification </a>
29/// * <a href="#ball_recordjsonformatter-field-format-specification"> Field Format Specification </a>
30/// * <a href="#ball_recordjsonformatter-verifying-the-format-specification-for-setformat"> Verifying the Format Specification for setFormat </a>
31/// * <a href="#ball_recordjsonformatter-the-timestamp-field-format"> The "timestamp" field format </a>
32/// * <a href="#ball_recordjsonformatter-the-pid-field-format"> The "pid" (process Id) field format </a>
33/// * <a href="#ball_recordjsonformatter-the-tid-field-format"> The "tid" (thread Id) field format </a>
34/// * <a href="#ball_recordjsonformatter-the-file-field-format"> The "file" field format </a>
35/// * <a href="#ball_recordjsonformatter-the-line-field-format"> The "line" field format </a>
36/// * <a href="#ball_recordjsonformatter-the-category-field-format"> The "category" field format </a>
37/// * <a href="#ball_recordjsonformatter-the-severity-field-format"> The "severity" field format </a>
38/// * <a href="#ball_recordjsonformatter-the-message-field-format"> The "message" field format </a>
39/// * <a href="#ball_recordjsonformatter-the-attributes-format"> The "attributes" format </a>
40/// * <a href="#ball_recordjsonformatter-a-user-defined-attribute-format"> A user-defined attribute format </a>
41/// * <a href="#ball_recordjsonformatter-the-record-separator"> The Record Separator </a>
42/// * <a href="#ball_recordjsonformatter-usage"> Usage </a>
43/// * <a href="#ball_recordjsonformatter-example-format-log-records-as-json-and-render-them-to-stdout"> Example: Format log records as JSON and render them to stdout </a>
44///
45/// # Purpose {#ball_recordjsonformatter-purpose}
46/// Provide a formatter for log records that renders output in JSON.
47///
48/// # Classes {#ball_recordjsonformatter-classes}
49///
50/// - ball::RecordJsonFormatter: formatter for rendering log records in JSON
51///
52/// @see ball_record, ball_recordattributes
53///
54/// # Description {#ball_recordjsonformatter-description}
55/// This component provides a function object class,
56/// `ball::RecorJsonFormatter`, that formats a log record as JSON text elements
57/// according to a format specification (see {`Record Format Specification`}).
58/// `ball::RecordJsonFormatter` is designed to match the function signature
59/// expected by many concrete `ball::Observer` implementations that publish log
60/// records (for example, see `ball::FileObserver2::setLogFileFunctor`).
61///
62/// NOTE: `ball::RecorJsonFormatter` renders individual log records as JSON,
63/// but, for example, a resulting log file would contain a sequence of JSON
64/// strings, which is not itself valid JSON text.
65///
66/// ## Record Format Specification {#ball_recordjsonformatter-record-format-specification}
67///
68///
69/// A format specification is, itself, a JSON array, supplied to a
70/// `RecordJsonFormatter` object by the `setFormat` function. If no format is
71/// specified, the default format is used. Each array element specifies the
72/// format of a log record field or a user-defined attribute. Here is a simple
73/// example:
74/// @code
75/// [{"timestamp":{"format":"iso8601"}}, "pid", "tid", "severity", "message"]
76/// @endcode
77/// would a result in a log record like:
78/// @code
79/// { "timestamp": "2020-08-28T14:43:50.375Z",
80/// "pid": 2313,
81/// "tid": 12349388604,
82/// "severity": "INFO",
83/// "message": "Hello, world!"
84/// }
85/// @endcode
86/// Again, the format specification is a JSON array, each element of which can
87/// be one of the following:
88///
89/// * A string containing the name of the fixed record field or the name of the
90/// user-defined attribute, in which case the field or attribute will be
91/// published in the default format. For example, `[timestamp]`, would
92/// display the timestamp as: `{"timestamp": "2020-08-28T14:43:50.375Z"}`.
93/// * A JSON object having the name of the fixed field or user-defined
94/// attribute and a set of key-values pairs used to customize the output
95/// format. For example,
96/// `[{"timestamp": {"name": "My Time", "format": "bdePrint"}}]`, would
97/// display the timestamp as: `{"My Time": "28AUG2020_14:43:50.375"}`.
98///
99/// ### Field Format Specification {#ball_recordjsonformatter-field-format-specification}
100///
101///
102/// The following table lists the predefined string values for each fixed field
103/// and user-defined attributes in the log record:
104/// @code
105/// Tag Description Example
106/// -------------- ------------------------- -------------
107/// "timestamp" creation date and time ["timestamp"]
108/// "pid" process id of creator ["pid"]
109/// "tid" thread id of creator ["tid"]
110/// "file" file where created (__FILE__) ["file"]
111/// "line" line number in file (__LINE__) ["line"]
112/// "category" category of logged record ["category"]
113/// "severity" severity of logged record ["severity"]
114/// "message" log message text ["message"]
115/// "attributes" all user-defined attributes ["attributes"]
116/// <attribute name> specific user-defined attribute ["bas.uuid"]
117/// @endcode
118/// The output format of each field can be customized by replacing a string
119/// value in the JSON array with a JSON object having the same name and a set of
120/// key-value pairs (attributes).
121///
122/// ### Verifying the Format Specification for setFormat {#ball_recordjsonformatter-verifying-the-format-specification-for-setformat}
123///
124///
125/// The sections that follow describe the set of fields that can be provided in
126/// the format specification supplied to `setFormat`.
127/// `RecordJsonFormatter::setFormat` will ignore fields in the provided format
128/// specification that are unknown, but will report an error if a known field
129/// contains a property that is not supported. For example: a format
130/// specification '["pid", { "timestamp" : {"unknown field!": "value"} }] will
131/// be accepted, but `["pid", {"timestamp": {"format": "unknown format" }}]`
132/// will produce an error.
133///
134/// Each key-value pair of a JSON object that specifies a format of an output of
135/// a fixed record field or a user-defined attribute has the following
136/// constrains:
137///
138/// * The key is a string of known value listed in the column "Key" in the
139/// tables below. Any string that does not match the listed values is
140/// ignored.
141/// * The value is a string of known value (except for the "name" key) in the
142/// column "Value Constraint" in the tables below. If the value does not
143/// match the string values specified in the tables, the format specification
144/// is considered to be inconsistent with the expected schema, and is
145/// rejected by the `RecordJsonFormatter::setFormat` method.
146///
147/// #### The "timestamp" field format {#ball_recordjsonformatter-the-timestamp-field-format}
148///
149///
150/// The format attributes of the "timestamp" object are given in the following
151/// table:
152/// @code
153/// Value Default
154/// Key Description Constraint Value
155/// ------------------------ ---------------- ----------- ------------
156/// "name" name by which JSON string "timestamp"
157/// "timestamp" will
158/// be published
159///
160/// "format" datetime format "iso8601", "iso8601"
161/// "bdePrint"
162/// (*Note*)
163///
164/// "fractionalSecPrecision" second precision "none", "microseconds"
165/// "milliseconds",
166/// "microseconds"
167///
168/// "timeZone" time zone "utc", "utc"
169/// "local"
170/// @endcode
171/// *Note*: The default "bdePrint" format denotes the following datetime format:
172/// @code
173/// DDMonYYYY_HH:MM:SS.mmm
174/// @endcode
175/// For example, the following record format specification:
176/// @code
177/// [ { "timestamp": { "name": "Time",
178/// "fractionalSecPrecision": "microseconds",
179/// "timeZone": "local" } }
180/// ]
181/// @endcode
182/// would a result in a log record like:
183/// @code
184/// { "Time": "28AUG2020_17:43:50.375345" }
185/// @endcode
186///
187/// #### The "pid" (process Id) field format {#ball_recordjsonformatter-the-pid-field-format}
188///
189///
190/// The format attributes of the process Id field are given in the following
191/// table:
192/// @code
193/// Value Default
194/// Key Description Constraint Value
195/// ------ ------------------------------------- ----------- -------
196/// "name" name by which "pid" will be published JSON string "pid"
197/// @endcode
198/// For example, the following record format specification:
199/// @code
200/// [ { "pid": { "name": "Process Id" } } ]
201/// @endcode
202/// would a result in a log record like:
203/// @code
204/// { "Process Id": 2313 }
205/// @endcode
206///
207/// #### The "tid" (thread Id) field format {#ball_recordjsonformatter-the-tid-field-format}
208///
209///
210/// The format attributes of the thread Id field are given in the following
211/// table:
212/// @code
213/// Value Default
214/// Key Description Constraint Value
215/// -------- ------------------------------------- ----------- ---------
216/// "name" name by which "tid" will be published JSON string "tid"
217///
218/// "format" output format "decimal", "decimal"
219/// "hex"
220/// @endcode
221/// For example, the following record format specification:
222/// @code
223/// [ { "tid": { "name": "Thread Id",
224/// "format": "hex" } }
225/// ]
226/// @endcode
227/// would a result in a log record like:
228/// @code
229/// { "Thread Id": 0xA7654EFF3540 }
230/// @endcode
231///
232/// #### The "file" field format {#ball_recordjsonformatter-the-file-field-format}
233///
234///
235/// The format attributes of the "file" field are given in the following
236/// table:
237/// @code
238/// Default
239/// Key Description Value Constraint Value
240/// ------ -------------------- ----------------------------- -------
241/// "name" name by which "file" JSON string "file"
242/// will be published
243///
244/// "path" file path "full" (__FILE__), "full"
245/// "file" (basename of __FILE__)
246/// @endcode
247/// For example, the following record format specification:
248/// @code
249/// [ { "file": { "name": "File",
250/// "path": "file" } }
251/// ]
252/// @endcode
253/// would a result in a log record like:
254/// @code
255/// { "File": "test.cpp" }
256/// @endcode
257///
258/// #### The "line" field format {#ball_recordjsonformatter-the-line-field-format}
259///
260///
261/// The format attributes of the "line" field are given in the following
262/// table:
263/// @code
264/// Value Default
265/// Key Description Constraint Value
266/// ------ --------------------------------------- ----------- -------
267/// "name" name by which "line" will be published JSON string "line"
268/// @endcode
269/// For example, the following record format specification:
270/// @code
271/// [ { "line": { "name": "Line" } } ]
272/// @endcode
273/// would a result in a log record like:
274/// @code
275/// { "Line": 512 }
276/// @endcode
277///
278/// #### The "category" field format {#ball_recordjsonformatter-the-category-field-format}
279///
280///
281/// The format attributes of the "category" field are given in the following
282/// table:
283/// @code
284/// Value Default
285/// Key Description Constraint Value
286/// ------ ------------------------------------------ ----------- ----------
287/// "name" name by which "category" will be published JSON string "category"
288/// @endcode
289/// For example, the following record format specification:
290/// @code
291/// [ { "category": { "name": "Category" } } ]
292/// @endcode
293/// would a result in a log record like:
294/// @code
295/// { "category": "Server" }
296/// @endcode
297///
298/// #### The "severity" field format {#ball_recordjsonformatter-the-severity-field-format}
299///
300///
301/// The format attributes of the "severity" field are given in the following
302/// table:
303/// @code
304/// Value Default
305/// Key Description Constraint Value
306/// ------ ------------------------------------------ ----------- ----------
307/// "name" name by which "severity" will be published JSON string "severity"
308/// @endcode
309/// For example, the following record format specification:
310/// @code
311/// [ { "severity": { "name": "severity" } } ]
312/// @endcode
313/// would a result in a log record like:
314/// @code
315/// { "Severity": "ERROR" }
316/// @endcode
317///
318/// #### The "message" field format {#ball_recordjsonformatter-the-message-field-format}
319///
320///
321/// A message is a JSON string which is a sequence of zero or more Unicode
322/// characters, wrapped in double quotes, using backslash escapes: (\", \\, \/,
323/// \b, \f, \n, \r, \t, \u{4 hex digits}).
324///
325/// The format attributes of the "message" field are given in the following
326/// table:
327/// @code
328/// Value Default
329/// Key Description Constraint Value
330/// ------ ----------------------------------------- ----------- ---------
331/// "name" name by which "message" will be published JSON string "message"
332/// @endcode
333/// For example, the following record format specification:
334/// @code
335/// [ { "message": { "name": "msg" } } ]
336/// @endcode
337/// would a result in a log record like:
338/// @code
339/// { "msg": "Log message" }
340/// @endcode
341///
342/// #### The "attributes" format {#ball_recordjsonformatter-the-attributes-format}
343///
344///
345/// The "attributes" JSON object has no attributes. For example, the following
346/// record format specification:
347/// @code
348/// [ "attributes" ]
349/// @endcode
350/// would (assuming their are two attributes "bas.requestid" and
351/// "mylib.security") result in a log record like:
352/// @code
353/// { "bas.requestid": 12345, "mylib.security": "My Security" }
354/// @endcode
355///
356/// #### A user-defined attribute format {#ball_recordjsonformatter-a-user-defined-attribute-format}
357///
358///
359/// Each user-defined attribute has a single "name" attribute that can be used
360/// to rename the user-defined attribute:
361/// @code
362/// Value Default
363/// Key Description Constraint Value
364/// ------ ---------------------------- ----------- -------
365/// "name" name by which a user-defined JSON string none
366/// attribute will be published
367/// @endcode
368/// For example, the following record format specification:
369/// @code
370/// [ { "bas.uuid": { "name": "BAS.UUID" } } ]
371/// @endcode
372/// would a result in a log record like:
373/// @code
374/// { "BAS.UUID": 3593 }
375/// @endcode
376///
377/// ## The Record Separator {#ball_recordjsonformatter-the-record-separator}
378///
379///
380/// The record separator is a string that is printed after each formatted
381/// record. The default value of the record separator is a single newline, but
382/// it can be set to any string of the user's choice using the
383/// `RecordJsonFormatter::setRecordSeparator` function.
384///
385/// ## Usage {#ball_recordjsonformatter-usage}
386///
387///
388/// This section illustrates intended use of this component.
389///
390/// ### Example: Format log records as JSON and render them to stdout {#ball_recordjsonformatter-example-format-log-records-as-json-and-render-them-to-stdout}
391///
392///
393/// Suppose an application needs to format log records as JSON and output them
394/// to `stdout`.
395///
396/// First we instantiate a JSON record formatter:
397/// @code
398/// ball::RecordJsonFormatter formatter;
399/// @endcode
400/// Next we set a format specification to the newly created `formatter`:
401/// @code
402/// int rc = formatter.setFormat("[\"tid\",\"message\"]");
403/// assert(0 == rc); (void)rc;
404/// @endcode
405/// The chosen format specification indicates that, when a record is formatted
406/// using `formatter`, the thread Id attribute of the record will be output
407/// followed by the message attribute of the record.
408///
409/// Then we create a default `ball::Record` and set the thread Id and message
410/// attributes of the record to dummy values:
411/// @code
412/// ball::Record record;
413///
414/// record.fixedFields().setThreadID(6);
415/// record.fixedFields().setMessage("Hello, World!");
416/// @endcode
417/// Next, invocation of the `formatter` function object to format `record` to
418/// `bsl::cout`:
419/// @code
420/// formatter(bsl::cout, record);
421/// @endcode
422/// yields this output, which is terminated by a single newline:
423/// @code
424/// {"tid":6,"message":"Hello, World!"}
425/// @endcode
426/// Finally, we change the record separator and format the same record again:
427/// @code
428/// formatter.setFormat("\n\n");
429/// formatter(bsl::cout, record);
430/// @endcode
431/// The record is printed in the same format, but now terminated by two
432/// newlines:
433/// @code
434/// {"tid":6,"message":"Hello, World!"}
435///
436/// @endcode
437/// @}
438/** @} */
439/** @} */
440
441/** @addtogroup bal
442 * @{
443 */
444/** @addtogroup ball
445 * @{
446 */
447/** @addtogroup ball_recordjsonformatter
448 * @{
449 */
450
451#include <balscm_version.h>
452
453#include <bslma_allocator.h>
454#include <bslma_bslallocator.h>
456
458#include <bslmf_movableref.h>
460
461#include <bsls_keyword.h>
462
463#include <bsl_functional.h>
464#include <bsl_iosfwd.h>
465#include <bsl_string.h>
466#include <bsl_vector.h>
467
468#include <bsl_ostream.h>
469
470
471namespace baljsn { class SimpleFormatter; }
472namespace ball {
473
474class Record;
475class RecordAttributes;
476class RecordJsonFormatter_FieldFormatter;
477
478 // =========================
479 // class RecordJsonFormatter
480 // =========================
481
482/// This class provides a function object that formats a log record as JSON
483/// text elements and renders them to an output stream. The overloaded
484/// `operator()` provided by the class formats log record according to JSON
485/// message format specification supplied at construction (either by the
486/// `setFormat` manipulator or by default) and outputs the result to the
487/// stream. This functor type is designed to match the function signature
488/// expected by many concrete `ball::Observer` implementations that publish
489/// log records (for example, see `ball::FileObserver2::setLogFileFunctor`).
490///
491/// See @ref ball_recordjsonformatter
493
494 // PRIVATE TYPES
495
496 /// `MoveUtil` is an alias for `bslmf::MovableRefUtil`.
498
499 public:
500 // TYPES
501
502 /// `FieldFormatters` is an alias for a vector of the
503 /// `RecordJsonFormatter_FieldFormatter` objects, each of which is
504 /// initialized from the format specification and responsible for
505 /// rendering one field of a `ball::Record` to the output JSON stream.
507
509
510 private:
511 // DATA
512 bsl::string d_formatSpec; // format specification (in JSON)
513
514 bsl::string d_recordSeparator; // string to print after each record
515
516 FieldFormatters d_fieldFormatters; // field formatters configured
517 // according to the format
518 // specification
519
520 // CLASS METHODS
521
522 /// Destroy the field formatters contained in the specified
523 /// `formatters`.
524 static
525 void releaseFieldFormatters(FieldFormatters *formatters);
526
527 public:
528 // CREATORS
529
530 /// Create a record JSON formatter having a default format specification
531 /// and record separator. Optionally specify an `allocator` (e.g., the
532 /// address of a `bslma::Allocator` object) to supply memory; otherwise,
533 /// the allocator is used. The default format specification is:
534 /// @code
535 /// ["timestamp", "processId", "threadId", "severity", "file", "line",
536 /// "category", "message", "attributes"]
537 /// @endcode
538 /// The default record separator is "\n".
541
542 /// Create a record JSON formatter initialized to the value of the
543 /// specified `original` record formatter. Optionally specify an
544 /// `allocator` (e.g., the address of a `bslma::Allocator` object) to
545 /// supply memory; otherwise, the default allocator is used.
547 const RecordJsonFormatter& original,
549
550 /// Create a record JSON formatter having the same format specification
551 /// and record separator as in the specified `original` formatter, and
552 /// adopting all outstanding memory allocations and the allocator
553 /// associated with the `original` formatter. `original` is left in a
554 /// valid but unspecified state.
557
558 /// Create a record JSON formatter, having the same format specification
559 /// and record separator as in the specified `original` formatter. The
560 /// format specification of `original` is moved to the new object, and
561 /// all outstanding memory allocations and the specified `allocator` are
562 /// adopted if `allocator == original.get_allocator()`. `original` is
563 /// left in a valid but unspecified state.
566
567 /// Destroy this object.
569
570 // MANIPULATORS
571
572 /// Assign to this object the value of the specified `rhs` object, and
573 /// return a reference providing modifiable access to this object.
575
576 /// Assign to this object the format specification and record separator
577 /// of the specified `rhs` object, and return a reference providing
578 /// modifiable access to this object. The format specification and
579 /// record separator of `rhs` are moved to this object, and all
580 /// outstanding memory allocations and the allocator associated with
581 /// `rhs` are adopted if `get_allocator() == rhs.get_allocator()`.
582 /// `rhs` is left in a valid but unspecified state.
584
585 /// Set the message format specification (see
586 /// {`Record Format Specification`}) of this record JSON formatter to
587 /// the specified `format`. Return 0 on success, and a non-zero value
588 /// otherwise (if `format` is not valid JSON *or* not a JSON conforming
589 /// to the expected schema).
591
592 /// Set the record separator for this record JSON formatter to the
593 /// specified `recordSeparator`. The `recordSeparator` will be printed
594 /// by each invocation of `operator()` after the formatted record. The
595 /// default is a single newline character, "\n".
597
598 // ACCESSORS
599
600 /// Format the specified `record` according to the current `format` and
601 /// `recordSeparator` to the specified `stream`.
602 void operator()(bsl::ostream& stream, const Record& record) const;
603
604 /// Return the message format specification of this record JSON
605 /// formatter. See {`Record Format Specification`}.
606 const bsl::string& format() const;
607
608 /// Return the record separator of this record JSON formatter.
609 const bsl::string& recordSeparator() const;
610
611 // Aspects
612
613 /// @deprecated Use @ref get_allocator().mechanism() instead.
616
617 /// Return the allocator used by this object to supply memory.
619
620};
621
622// FREE OPERATORS
623
624/// Return `true` if the specified `lhs` and `rhs` record formatters have
625/// the same value, and `false` otherwise. Two record formatters have the
626/// same value if they have the same format specification and record
627/// separator.
628bool operator==(const RecordJsonFormatter& lhs,
629 const RecordJsonFormatter& rhs);
630
631/// Return `true` if the specified `lhs` and `rhs` record formatters do not
632/// have the same value, and `false` otherwise. Two record formatters
633/// differ in value if their format specifications or record separators
634/// differ.
635bool operator!=(const RecordJsonFormatter& lhs,
636 const RecordJsonFormatter& rhs);
637
638// ============================================================================
639// INLINE DEFINITIONS
640// ============================================================================
641
642 // -------------------------
643 // class RecordJsonFormatter
644 // -------------------------
645
646// CREATORS
647inline
649 const allocator_type& allocator)
650: d_formatSpec(original.d_formatSpec, allocator)
651, d_recordSeparator(original.d_recordSeparator, allocator)
652, d_fieldFormatters(allocator)
653{
654 int rc = setFormat(d_formatSpec);
655 (void) rc;
656 BSLS_ASSERT(0 == rc);
657}
658
659inline
662: d_formatSpec(MoveUtil::move(MoveUtil::access(original).d_formatSpec)),
663 d_recordSeparator(
664 MoveUtil::move(MoveUtil::access(original).d_recordSeparator)),
665 d_fieldFormatters(
666 MoveUtil::move(MoveUtil::access(original).d_fieldFormatters))
667{
668}
669
670inline
673 const allocator_type& allocator)
674: d_formatSpec(MoveUtil::move(MoveUtil::access(original).d_formatSpec),
675 allocator)
676, d_recordSeparator(
677 MoveUtil::move(MoveUtil::access(original).d_recordSeparator),
678 allocator)
679, d_fieldFormatters(allocator)
680{
681 if (MoveUtil::access(original).get_allocator() == allocator) {
682 d_fieldFormatters = MoveUtil::move(
683 MoveUtil::access(original).d_fieldFormatters);
684 }
685 else {
686 int rc = setFormat(d_formatSpec);
687 (void) rc;
688 BSLS_ASSERT(0 == rc);
689 }
690}
691
692// MANIPULATORS
693inline
696{
697 if (this != &MoveUtil::access(rhs)) {
698 d_recordSeparator = MoveUtil::move(
699 MoveUtil::access(rhs).d_recordSeparator);
701 releaseFieldFormatters(&d_fieldFormatters);
702 d_formatSpec = MoveUtil::move(
703 MoveUtil::access(rhs).d_formatSpec);
704 d_fieldFormatters = MoveUtil::move(
705 MoveUtil::access(rhs).d_fieldFormatters);
706 }
707 else {
708 int rc = setFormat(MoveUtil::access(rhs).d_formatSpec);
709 (void) rc;
710 BSLS_ASSERT(0 == rc);
711 }
712 }
713
714 return *this;
715}
716
717inline
719 const bsl::string_view& recordSeparator)
720{
721 d_recordSeparator = recordSeparator;
722}
723
724// ACCESSORS
725inline
727{
728 return d_formatSpec;
729}
730
731inline
733{
734 return d_recordSeparator;
735}
736
737 // Aspects
738
739inline
741{
742 return d_formatSpec.get_allocator().mechanism();
743}
744
745inline
748{
749 return d_formatSpec.get_allocator();
750}
751
752} // close package namespace
753
754// FREE OPERATORS
755inline
756bool ball::operator==(const RecordJsonFormatter& lhs,
757 const RecordJsonFormatter& rhs)
758{
759 return lhs.format() == rhs.format() &&
760 lhs.recordSeparator() == rhs.recordSeparator();
761}
762
763inline
764bool ball::operator!=(const RecordJsonFormatter& lhs,
765 const RecordJsonFormatter& rhs)
766{
767 return !(lhs == rhs);
768}
769
770
771
772#endif
773
774// ----------------------------------------------------------------------------
775// Copyright 2020 Bloomberg Finance L.P.
776//
777// Licensed under the Apache License, Version 2.0 (the "License");
778// you may not use this file except in compliance with the License.
779// You may obtain a copy of the License at
780//
781// http://www.apache.org/licenses/LICENSE-2.0
782//
783// Unless required by applicable law or agreed to in writing, software
784// distributed under the License is distributed on an "AS IS" BASIS,
785// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
786// See the License for the specific language governing permissions and
787// limitations under the License.
788// ----------------------------- END-OF-FILE ----------------------------------
789
790/** @} */
791/** @} */
792/** @} */
Definition ball_recordjsonformatter.h:492
const bsl::string & recordSeparator() const
Return the record separator of this record JSON formatter.
Definition ball_recordjsonformatter.h:732
~RecordJsonFormatter()
Destroy this object.
int setFormat(const bsl::string_view &format)
void operator()(bsl::ostream &stream, const Record &record) const
allocator_type get_allocator() const
Return the allocator used by this object to supply memory.
Definition ball_recordjsonformatter.h:747
bsl::allocator allocator_type
Definition ball_recordjsonformatter.h:508
RecordJsonFormatter & operator=(const RecordJsonFormatter &rhs)
bsl::vector< RecordJsonFormatter_FieldFormatter * > FieldFormatters
Definition ball_recordjsonformatter.h:506
BSLS_DEPRECATE bslma::Allocator * allocator() const
Definition ball_recordjsonformatter.h:740
const bsl::string & format() const
Definition ball_recordjsonformatter.h:726
RecordJsonFormatter(const allocator_type &allocator=allocator_type())
void setRecordSeparator(const bsl::string_view &recordSeparator)
Definition ball_recordjsonformatter.h:718
Definition ball_record.h:178
Definition bslma_bslallocator.h:580
BloombergLP::bslma::Allocator * mechanism() const
Definition bslma_bslallocator.h:1126
Definition bslstl_stringview.h:441
Definition bslstl_string.h:1281
allocator_type get_allocator() const BSLS_KEYWORD_NOEXCEPT
Return the allocator used by this string to supply memory.
Definition bslstl_string.h:6723
Definition bslstl_vector.h:1025
Definition bslma_allocator.h:457
Definition bslmf_movableref.h:751
#define BSLS_ASSERT(X)
Definition bsls_assert.h:1804
#define BSLS_DEPRECATE
Definition bsls_deprecate.h:720
#define BSLS_IDENT(str)
Definition bsls_ident.h:195
#define BSLS_KEYWORD_NOEXCEPT
Definition bsls_keyword.h:632
Definition baljsn_datumdecoderoptions.h:113
Definition ball_administration.h:214
bool operator!=(const Attribute &lhs, const Attribute &rhs)
bool operator==(const Attribute &lhs, const Attribute &rhs)
Definition bslmf_movableref.h:791
static MovableRef< t_TYPE > move(t_TYPE &reference) BSLS_KEYWORD_NOEXCEPT
Definition bslmf_movableref.h:1060
static t_TYPE & access(t_TYPE &ref) BSLS_KEYWORD_NOEXCEPT
Definition bslmf_movableref.h:1032