Clio develop
The XRP Ledger API server.
Loading...
Searching...
No Matches
Taggable.hpp
1//------------------------------------------------------------------------------
2/*
3 This file is part of clio: https://github.com/XRPLF/clio
4 Copyright (c) 2022, the clio developers.
5
6 Permission to use, copy, modify, and distribute this software for any
7 purpose with or without fee is hereby granted, provided that the above
8 copyright notice and this permission notice appear in all copies.
9
10 THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17*/
18//==============================================================================
19
20#pragma once
21
22#include "util/Assert.hpp"
23#include "util/config/ConfigDefinition.hpp"
24
25#include <boost/algorithm/string/predicate.hpp>
26#include <boost/json.hpp>
27#include <boost/json/conversion.hpp>
28#include <boost/json/value.hpp>
29#include <boost/uuid/uuid.hpp>
30#include <boost/uuid/uuid_io.hpp>
31
32#include <atomic>
33#include <functional>
34#include <memory>
35#include <optional>
36#include <ostream>
37#include <string>
38#include <string_view>
39#include <utility>
40
41namespace util {
42namespace impl {
43
47struct NullTagGenerator final {};
48
52struct UIntTagGenerator final {
53 using TagType = std::atomic_uint64_t;
54
55 static TagType
56 next();
57};
58
62struct UUIDTagGenerator final {
63 using TagType = boost::uuids::uuid;
64
65 static TagType
66 next();
67};
68
69} // namespace impl
70
75public:
76 virtual ~BaseTagDecorator() = default;
77
83 virtual void
84 decorate(std::ostream& os) const = 0;
85
93 friend std::ostream&
94 operator<<(std::ostream& os, BaseTagDecorator const& decorator)
95 {
96 decorator.decorate(os);
97 return os;
98 }
99
105 std::string
106 toString() const
107 {
108 std::ostringstream oss;
109 decorate(oss);
110 return std::move(oss).str();
111 }
112};
113
119template <typename Generator>
120class TagDecorator final : public BaseTagDecorator {
121 using ParentType = std::optional<std::reference_wrapper<BaseTagDecorator const>>;
122 using TagType = typename Generator::TagType;
123
124 ParentType parent_ = std::nullopt;
125 TagType tag_ = Generator::next();
126
127public:
138 explicit TagDecorator(ParentType parent = std::nullopt) : parent_{parent}
139 {
140 }
141
147 void
148 decorate(std::ostream& os) const override
149 {
150 os << "[";
151
152 if (parent_.has_value())
153 (*parent_).get().decorate(os);
154
155 os << tag_ << "] ";
156 }
157};
158
164template <>
165class TagDecorator<impl::NullTagGenerator> final : public BaseTagDecorator {
166public:
172 void
173 decorate([[maybe_unused]] std::ostream& os) const override
174 {
175 // nop
176 }
177};
178
183 using ParentType = std::optional<std::reference_wrapper<BaseTagDecorator const>>;
184
188 enum class Type {
189 NONE,
190 UUID,
191 UINT
192 };
193
194 Type type_; /*< The type of TagDecorator this factory produces */
195 ParentType parent_ = std::nullopt; /*< The parent tag decorator to bind */
196
197 static Type
198 getLogTagType(std::string_view style)
199 {
200 if (boost::iequals(style, "int") || boost::iequals(style, "uint"))
201 return TagDecoratorFactory::Type::UINT;
202
203 if (boost::iequals(style, "null") || boost::iequals(style, "none"))
204 return TagDecoratorFactory::Type::NONE;
205
206 if (boost::iequals(style, "uuid"))
207 return TagDecoratorFactory::Type::UUID;
208
209 ASSERT(false, "log_tag_style does not have valid value");
210 std::unreachable();
211 }
212
213public:
214 ~TagDecoratorFactory() = default;
215
222 : type_{getLogTagType(config.get<std::string>("log_tag_style"))}
223 {
224 }
225
226private:
227 TagDecoratorFactory(Type type, ParentType parent) noexcept : type_{type}, parent_{parent}
228 {
229 }
230
231public:
237 std::unique_ptr<BaseTagDecorator>
238 make() const;
239
247 with(ParentType parent) const noexcept;
248};
249
253class Taggable {
254 using DecoratorType = std::unique_ptr<BaseTagDecorator>;
255 DecoratorType tagDecorator_;
256
257protected:
263 explicit Taggable(util::TagDecoratorFactory const& tagFactory) : tagDecorator_{tagFactory.make()}
264 {
265 }
266
267public:
268 virtual ~Taggable() = default;
269 Taggable(Taggable&&) = default;
270
271 Taggable&
272 operator=(Taggable&&) = default;
273
279 BaseTagDecorator const&
280 tag() const
281 {
282 return *tagDecorator_;
283 }
284};
285
286} // namespace util
Represents any tag decorator.
Definition Taggable.hpp:74
virtual void decorate(std::ostream &os) const =0
Decorates a std::ostream.
friend std::ostream & operator<<(std::ostream &os, BaseTagDecorator const &decorator)
Support for decorating streams (boost log, cout, etc.).
Definition Taggable.hpp:94
std::string toString() const
Gets the string representation of the tag.
Definition Taggable.hpp:106
A factory for TagDecorator instantiation.
Definition Taggable.hpp:182
std::unique_ptr< BaseTagDecorator > make() const
Instantiates the TagDecorator specified by type_ with parent bound from parent_.
Definition Taggable.cpp:52
TagDecoratorFactory(util::config::ClioConfigDefinition const &config)
Instantiates a tag decorator factory from clio configuration.
Definition Taggable.hpp:221
TagDecoratorFactory with(ParentType parent) const noexcept
Creates a new tag decorator factory with a bound parent tag decorator.
Definition Taggable.cpp:66
void decorate(std::ostream &os) const override
Nop implementation for the decorator.
Definition Taggable.hpp:173
A decorator that decorates a string (log line) with a unique tag.
Definition Taggable.hpp:120
void decorate(std::ostream &os) const override
Implementation of the decoration. Chaining tags when parent is available.
Definition Taggable.hpp:148
TagDecorator(ParentType parent=std::nullopt)
Create a new tag decorator with an optional parent.
Definition Taggable.hpp:138
A base class that allows attaching a tag decorator to a subclass.
Definition Taggable.hpp:253
BaseTagDecorator const & tag() const
Getter for tag decorator.
Definition Taggable.hpp:280
Taggable(util::TagDecoratorFactory const &tagFactory)
New Taggable from a specified factory.
Definition Taggable.hpp:263
All the config data will be stored and extracted from this class.
Definition ConfigDefinition.hpp:54
This namespace contains various utilities.
Definition AccountUtils.hpp:30
A null tag generator - does nothing.
Definition Taggable.hpp:47
This strategy uses an atomic_uint64_t to remain lock free.
Definition Taggable.hpp:52
This strategy uses boost::uuids::uuid with a static random generator and a mutex.
Definition Taggable.hpp:62