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/newconfig/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};
100
106template <typename Generator>
107class TagDecorator final : public BaseTagDecorator {
108 using ParentType = std::optional<std::reference_wrapper<BaseTagDecorator const>>;
109 using TagType = typename Generator::TagType;
110
111 ParentType parent_ = std::nullopt;
112 TagType tag_ = Generator::next();
113
114public:
125 explicit TagDecorator(ParentType parent = std::nullopt) : parent_{parent}
126 {
127 }
128
134 void
135 decorate(std::ostream& os) const override
136 {
137 os << "[";
138
139 if (parent_.has_value())
140 (*parent_).get().decorate(os);
141
142 os << tag_ << "] ";
143 }
144};
145
151template <>
152class TagDecorator<impl::NullTagGenerator> final : public BaseTagDecorator {
153public:
159 void
160 decorate([[maybe_unused]] std::ostream& os) const override
161 {
162 // nop
163 }
164};
165
170 using ParentType = std::optional<std::reference_wrapper<BaseTagDecorator const>>;
171
175 enum class Type {
176 NONE,
177 UUID,
178 UINT
179 };
180
181 Type type_; /*< The type of TagDecorator this factory produces */
182 ParentType parent_ = std::nullopt; /*< The parent tag decorator to bind */
183
184 static Type
185 getLogTagType(std::string_view style)
186 {
187 if (boost::iequals(style, "int") || boost::iequals(style, "uint"))
188 return TagDecoratorFactory::Type::UINT;
189
190 if (boost::iequals(style, "null") || boost::iequals(style, "none"))
191 return TagDecoratorFactory::Type::NONE;
192
193 if (boost::iequals(style, "uuid"))
194 return TagDecoratorFactory::Type::UUID;
195
196 ASSERT(false, "log_tag_style does not have valid value");
197 std::unreachable();
198 }
199
200public:
201 ~TagDecoratorFactory() = default;
202
209 : type_{getLogTagType(config.get<std::string>("log_tag_style"))}
210 {
211 }
212
213private:
214 TagDecoratorFactory(Type type, ParentType parent) noexcept : type_{type}, parent_{parent}
215 {
216 }
217
218public:
224 std::unique_ptr<BaseTagDecorator>
225 make() const;
226
234 with(ParentType parent) const noexcept;
235};
236
240class Taggable {
241 using DecoratorType = std::unique_ptr<BaseTagDecorator>;
242 DecoratorType tagDecorator_;
243
244protected:
250 explicit Taggable(util::TagDecoratorFactory const& tagFactory) : tagDecorator_{tagFactory.make()}
251 {
252 }
253
254public:
255 virtual ~Taggable() = default;
256 Taggable(Taggable&&) = default;
257
258 Taggable&
259 operator=(Taggable&&) = default;
260
266 BaseTagDecorator const&
267 tag() const
268 {
269 return *tagDecorator_;
270 }
271};
272
273} // 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
A factory for TagDecorator instantiation.
Definition Taggable.hpp:169
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:208
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:160
A decorator that decorates a string (log line) with a unique tag.
Definition Taggable.hpp:107
void decorate(std::ostream &os) const override
Implementation of the decoration. Chaining tags when parent is available.
Definition Taggable.hpp:135
TagDecorator(ParentType parent=std::nullopt)
Create a new tag decorator with an optional parent.
Definition Taggable.hpp:125
A base class that allows attaching a tag decorator to a subclass.
Definition Taggable.hpp:240
BaseTagDecorator const & tag() const
Getter for tag decorator.
Definition Taggable.hpp:267
Taggable(util::TagDecoratorFactory const &tagFactory)
New Taggable from a specified factory.
Definition Taggable.hpp:250
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