Flow 1.0.1
Flow project: Full implementation reference.
buffer_logger.hpp
Go to the documentation of this file.
1/* Flow
2 * Copyright 2023 Akamai Technologies, Inc.
3 *
4 * Licensed under the Apache License, Version 2.0 (the
5 * "License"); you may not use this file except in
6 * compliance with the License. You may obtain a copy
7 * of the License at
8 *
9 * https://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in
12 * writing, software distributed under the License is
13 * distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
14 * CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing
16 * permissions and limitations under the License. */
17
18/// @file
19#pragma once
20
22#include "flow/log/log.hpp"
25
26namespace flow::log
27{
28
29/**
30 * An implementation of Logger that logs messages to an internal `std::string` buffer
31 * and provides read-only access to this buffer (for example, if one wants to write out its contents
32 * when exiting program).
33 *
34 * ### Thread safety ###
35 * Simultaneous logging from multiple threads is safe from output corruption, in that
36 * simultaneous do_log() calls for the same Logger will log serially to each other.
37 * buffer_str_copy() is also safe. However, buffer_str() may not be thread-safe; see its doc header
38 * for more information.
39 *
40 * See thread safety notes and to-dos regarding #m_config in Simple_ostream_logger doc header. These apply here also.
41 *
42 * There are no other mutable data (state), so that's that.
43 */
45 public Logger
46{
47public:
48 // Constructors/destructor.
49
50 /**
51 * Constructs logger to subsequently log to a newly constructed internal `std::string` buffer.
52 *
53 * @param config
54 * Controls behavior of this Logger. In particular, it affects should_log() logic (verbosity default and
55 * per-component) and output format (such as time stamp format). See thread safety notes in class doc header.
56 * This is saved in #m_config.
57 */
58 explicit Buffer_logger(Config* config);
59
60 // Methods.
61
62 /**
63 * Implements interface method by returning `true` if the severity and component (which is allowed to be null)
64 * indicate it should. As of this writing not thread-safe against changes to `*m_config`.
65 *
66 * @param sev
67 * Severity of the message.
68 * @param component
69 * Component of the message. Reminder: `component.empty() == true` is allowed.
70 * @return See above.
71 */
72 bool should_log(Sev sev, const Component& component) const override;
73
74 /**
75 * Implements interface method by returning `false`, indicating that this Logger will not need the contents of
76 * `*metadata` and `msg` passed to do_log(), as the latter will output them synchronously.
77 *
78 * @return See above.
79 */
80 bool logs_asynchronously() const override;
81
82 /**
83 * Implements interface method by synchronously logging the message and some subset of the metadata in a fashion
84 * controlled by #m_config.
85 *
86 * Internally, this will involve a possible allocation (to enlarge an internal buffer when
87 * needed) and essentially copying of the `msg` and `*metadata` payloads onto the end of the buffer. This does not
88 * block (in the classic I/O sense) the calling thread. Needless to say, memory use may become a concern depending
89 * on the verbosity of the logging.
90 *
91 * @param metadata
92 * All information to potentially log in addition to `msg`.
93 * @param msg
94 * The message.
95 */
96 void do_log(Msg_metadata* metadata, util::String_view msg) override;
97
98 /**
99 * Read-only access to the buffer string containing the messages logged thus far.
100 *
101 * @warning While high-performance, this is not thread-safe, in that other threads logging to
102 * `*this` may cause the returned string to be subsequently accessed mid-write and therefore possibly
103 * in an undefined state. Take care to access the result only when you know no other thread
104 * is logging (e.g., when exiting program).
105 *
106 * @return Read-only reference.
107 */
108 const std::string& buffer_str() const;
109
110 /**
111 * Returns a copy of `buffer_str()` in thread-safe fashion. However, this may be quite slow if done frequently.
112 *
113 * @return Newly created string.
114 */
115 const std::string buffer_str_copy() const;
116
117 // Data. (Public!)
118
119 /// Reference to the config object passed to constructor. Note that object is mutable; see notes on thread safety.
121
122private:
123 // Data.
124
125 /// Like `ostringstream` but allows for fast access directly into its internal string buffer.
127
128 /// Wrapper around #m_os that will take care of prefacing each message with time stamp, etc.
130
131 /**
132 * Mutex protecting against log messages being logged, accessing #m_os concurrently and thus corrupting (or at best
133 * garbling) the output string `m_os.str()`.
134 */
136}; // class Buffer_logger
137
138} // namespace flow::log
An implementation of Logger that logs messages to an internal std::string buffer and provides read-on...
util::String_ostream m_os
Like ostringstream but allows for fast access directly into its internal string buffer.
const std::string & buffer_str() const
Read-only access to the buffer string containing the messages logged thus far.
void do_log(Msg_metadata *metadata, util::String_view msg) override
Implements interface method by synchronously logging the message and some subset of the metadata in a...
Buffer_logger(Config *config)
Constructs logger to subsequently log to a newly constructed internal std::string buffer.
Ostream_log_msg_writer m_os_writer
Wrapper around m_os that will take care of prefacing each message with time stamp,...
Config *const m_config
Reference to the config object passed to constructor. Note that object is mutable; see notes on threa...
util::Mutex_non_recursive m_log_mutex
Mutex protecting against log messages being logged, accessing m_os concurrently and thus corrupting (...
bool should_log(Sev sev, const Component &component) const override
Implements interface method by returning true if the severity and component (which is allowed to be n...
bool logs_asynchronously() const override
Implements interface method by returning false, indicating that this Logger will not need the content...
const std::string buffer_str_copy() const
Returns a copy of buffer_str() in thread-safe fashion.
A light-weight class, each object storing a component payload encoding an enum value from enum type o...
Definition: log.hpp:840
Class used to configure the filtering and logging behavior of Loggers; its use in your custom Loggers...
Definition: config.hpp:200
Interface that the user should implement, passing the implementing Logger into logging classes (Flow'...
Definition: log.hpp:1291
Utility class, each object of which wraps a given ostream and outputs discrete messages to it adorned...
Similar to ostringstream but allows fast read-only access directly into the std::string being written...
Flow module providing logging functionality.
Sev
Enumeration containing one of several message severity levels, ordered from highest to lowest.
Definition: log_fwd.hpp:224
boost::mutex Mutex_non_recursive
Short-hand for non-reentrant, exclusive mutex. ("Reentrant" = one can lock an already-locked-in-that-...
Definition: util_fwd.hpp:215
Basic_string_view< char > String_view
Commonly used char-based Basic_string_view. See its doc header.
Simple data store containing all of the information generated at every logging call site by flow::log...
Definition: log.hpp:1048