-
Notifications
You must be signed in to change notification settings - Fork 187
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
add StringConvertibleTypeCodec and OstreamConvertibleTypeCodec
- Loading branch information
Showing
13 changed files
with
680 additions
and
9 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,139 @@ | ||
<mxfile host="app.diagrams.net" agent="Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/18.3 Safari/605.1.15" version="26.0.13"> | ||
<diagram name="Page-1" id="NHgCSlD5--Cc5E9ydP2n"> | ||
<mxGraphModel dx="2168" dy="1183" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="827" pageHeight="1169" math="0" shadow="0"> | ||
<root> | ||
<mxCell id="0" /> | ||
<mxCell id="1" parent="0" /> | ||
<mxCell id="IKCe0DnfbzoJhUQUdqvM-2" value="Is the Operation Performance Critical?" style="strokeWidth=2;html=1;shape=mxgraph.flowchart.decision;whiteSpace=wrap;" parent="1" vertex="1"> | ||
<mxGeometry x="260" y="360" width="180" height="170" as="geometry" /> | ||
</mxCell> | ||
<mxCell id="IKCe0DnfbzoJhUQUdqvM-3" value="" style="endArrow=none;html=1;rounded=0;entryX=0.5;entryY=1;entryDx=0;entryDy=0;exitX=0.5;exitY=0;exitDx=0;exitDy=0;exitPerimeter=0;entryPerimeter=0;" parent="1" source="IKCe0DnfbzoJhUQUdqvM-2" target="IKCe0DnfbzoJhUQUdqvM-8" edge="1"> | ||
<mxGeometry width="50" height="50" relative="1" as="geometry"> | ||
<mxPoint x="390" y="390" as="sourcePoint" /> | ||
<mxPoint x="390" y="290" as="targetPoint" /> | ||
</mxGeometry> | ||
</mxCell> | ||
<mxCell id="IKCe0DnfbzoJhUQUdqvM-4" value="" style="endArrow=none;html=1;rounded=0;exitX=1;exitY=0.5;exitDx=0;exitDy=0;exitPerimeter=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" parent="1" source="IKCe0DnfbzoJhUQUdqvM-2" target="IKCe0DnfbzoJhUQUdqvM-7" edge="1"> | ||
<mxGeometry width="50" height="50" relative="1" as="geometry"> | ||
<mxPoint x="390" y="650" as="sourcePoint" /> | ||
<mxPoint x="650" y="440" as="targetPoint" /> | ||
</mxGeometry> | ||
</mxCell> | ||
<mxCell id="IKCe0DnfbzoJhUQUdqvM-5" value="No (e.g., LOG_DEBUG&nbsp;<div>or during initialization)</div>" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=1;points=[];movable=1;rotatable=1;deletable=1;editable=1;locked=0;connectable=1;" parent="IKCe0DnfbzoJhUQUdqvM-4" vertex="1" connectable="0"> | ||
<mxGeometry relative="1" as="geometry"> | ||
<mxPoint x="-5" y="-25" as="offset" /> | ||
</mxGeometry> | ||
</mxCell> | ||
<mxCell id="IKCe0DnfbzoJhUQUdqvM-7" value="Convert to a String on the Hot Path" style="rounded=1;whiteSpace=wrap;html=1;absoluteArcSize=1;arcSize=14;strokeWidth=2;" parent="1" vertex="1"> | ||
<mxGeometry x="570" y="395" width="200" height="100" as="geometry" /> | ||
</mxCell> | ||
<mxCell id="IKCe0DnfbzoJhUQUdqvM-8" value="<span style="caret-color: rgb(0, 0, 0); color: rgb(0, 0, 0); font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: auto; text-align: center; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px; background-color: rgb(251, 251, 251); text-decoration: none; display: inline !important; float: none;">Logging STL or User-Defined Type</span>" style="strokeWidth=2;html=1;shape=mxgraph.flowchart.start_1;whiteSpace=wrap;" parent="1" vertex="1"> | ||
<mxGeometry x="285" y="140" width="130" height="110" as="geometry" /> | ||
</mxCell> | ||
<mxCell id="IKCe0DnfbzoJhUQUdqvM-10" value="Use StringConvertibleTypeCodec for conversion<div><br></div><div><div>&nbsp;template &lt;&gt; &nbsp;struct fmtquill::formatter&lt;UserType&gt; &nbsp;{ ... };</div><div>&nbsp;</div><div>template &lt;&gt; struct quill::Codec&lt;UserType&gt; : StringConvertibleTypeCodec&lt;UserType&gt; { };</div></div>" style="rounded=0;whiteSpace=wrap;html=1;" parent="1" vertex="1"> | ||
<mxGeometry x="860" y="380" width="540" height="130" as="geometry" /> | ||
</mxCell> | ||
<mxCell id="IKCe0DnfbzoJhUQUdqvM-11" value="Use OstreamConvertibleTypeCodec for conversion<div><br></div><div>emplate &lt;&gt; struct quill::Codec&lt;UserType&gt; : OstreamConvertibleTypeCodec&lt;UserType&gt; { };<br></div>" style="rounded=0;whiteSpace=wrap;html=1;" parent="1" vertex="1"> | ||
<mxGeometry x="861" y="220" width="540" height="130" as="geometry" /> | ||
</mxCell> | ||
<mxCell id="IKCe0DnfbzoJhUQUdqvM-12" value="Convert Explicitly e.g. using format()<br><div>User u {};<br><div>LOG_INFO(l, "{}", std::format("{}" u));</div></div>" style="rounded=0;whiteSpace=wrap;html=1;" parent="1" vertex="1"> | ||
<mxGeometry x="860" y="540" width="540" height="130" as="geometry" /> | ||
</mxCell> | ||
<mxCell id="IKCe0DnfbzoJhUQUdqvM-13" value="" style="endArrow=none;html=1;rounded=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;exitX=1;exitY=0.5;exitDx=0;exitDy=0;" parent="1" source="IKCe0DnfbzoJhUQUdqvM-7" target="IKCe0DnfbzoJhUQUdqvM-11" edge="1"> | ||
<mxGeometry width="50" height="50" relative="1" as="geometry"> | ||
<mxPoint x="240" y="390" as="sourcePoint" /> | ||
<mxPoint x="290" y="340" as="targetPoint" /> | ||
</mxGeometry> | ||
</mxCell> | ||
<mxCell id="IKCe0DnfbzoJhUQUdqvM-14" value="" style="endArrow=none;html=1;rounded=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;exitX=1;exitY=0.5;exitDx=0;exitDy=0;" parent="1" source="IKCe0DnfbzoJhUQUdqvM-7" target="IKCe0DnfbzoJhUQUdqvM-10" edge="1"> | ||
<mxGeometry width="50" height="50" relative="1" as="geometry"> | ||
<mxPoint x="720" y="450" as="sourcePoint" /> | ||
<mxPoint x="870" y="280" as="targetPoint" /> | ||
</mxGeometry> | ||
</mxCell> | ||
<mxCell id="IKCe0DnfbzoJhUQUdqvM-15" value="" style="endArrow=none;html=1;rounded=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;exitX=1;exitY=0.5;exitDx=0;exitDy=0;" parent="1" source="IKCe0DnfbzoJhUQUdqvM-7" target="IKCe0DnfbzoJhUQUdqvM-12" edge="1"> | ||
<mxGeometry width="50" height="50" relative="1" as="geometry"> | ||
<mxPoint x="720" y="450" as="sourcePoint" /> | ||
<mxPoint x="870" y="460" as="targetPoint" /> | ||
</mxGeometry> | ||
</mxCell> | ||
<mxCell id="IKCe0DnfbzoJhUQUdqvM-16" value="" style="endArrow=none;html=1;rounded=0;exitX=0.5;exitY=1;exitDx=0;exitDy=0;exitPerimeter=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;" parent="1" source="IKCe0DnfbzoJhUQUdqvM-2" target="IKCe0DnfbzoJhUQUdqvM-18" edge="1"> | ||
<mxGeometry width="50" height="50" relative="1" as="geometry"> | ||
<mxPoint x="450" y="450" as="sourcePoint" /> | ||
<mxPoint x="390" y="650" as="targetPoint" /> | ||
</mxGeometry> | ||
</mxCell> | ||
<mxCell id="IKCe0DnfbzoJhUQUdqvM-17" value="Yes" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=1;points=[];movable=1;rotatable=1;deletable=1;editable=1;locked=0;connectable=1;" parent="IKCe0DnfbzoJhUQUdqvM-16" vertex="1" connectable="0"> | ||
<mxGeometry relative="1" as="geometry"> | ||
<mxPoint x="-20" y="-100" as="offset" /> | ||
</mxGeometry> | ||
</mxCell> | ||
<mxCell id="IKCe0DnfbzoJhUQUdqvM-18" value="Pass a binary copy, deferring string conversion to the backend logging thread" style="rounded=1;whiteSpace=wrap;html=1;absoluteArcSize=1;arcSize=14;strokeWidth=2;" parent="1" vertex="1"> | ||
<mxGeometry x="250" y="750" width="200" height="100" as="geometry" /> | ||
</mxCell> | ||
<mxCell id="IKCe0DnfbzoJhUQUdqvM-19" value="TriviallyCopyableTypeCodec<div><br><div>Simplest and most efficient method for trivially copiable user defined types</div></div><div><br></div><div>&nbsp;template &lt;&gt; &nbsp;struct fmtquill::formatter&lt;UserType&gt; &nbsp;{ ... };</div><div>&nbsp;</div><div>template &lt;&gt; struct quill::Codec&lt;UserType&gt; : TriviallyCopyableTypeCodec&lt;UserType&gt; { };<br></div>" style="rounded=0;whiteSpace=wrap;html=1;" parent="1" vertex="1"> | ||
<mxGeometry x="860" y="780" width="540" height="130" as="geometry" /> | ||
</mxCell> | ||
<mxCell id="IKCe0DnfbzoJhUQUdqvM-20" value="STL Type" style="strokeWidth=2;html=1;shape=mxgraph.flowchart.decision;whiteSpace=wrap;" parent="1" vertex="1"> | ||
<mxGeometry x="300" y="950" width="100" height="100" as="geometry" /> | ||
</mxCell> | ||
<mxCell id="IKCe0DnfbzoJhUQUdqvM-21" value="" style="endArrow=none;html=1;rounded=0;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;entryPerimeter=0;" parent="1" source="IKCe0DnfbzoJhUQUdqvM-18" target="IKCe0DnfbzoJhUQUdqvM-20" edge="1"> | ||
<mxGeometry width="50" height="50" relative="1" as="geometry"> | ||
<mxPoint x="399.5" y="790" as="sourcePoint" /> | ||
<mxPoint x="350" y="870" as="targetPoint" /> | ||
</mxGeometry> | ||
</mxCell> | ||
<mxCell id="IKCe0DnfbzoJhUQUdqvM-24" value="" style="endArrow=none;html=1;rounded=0;exitX=0.5;exitY=1;exitDx=0;exitDy=0;exitPerimeter=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;" parent="1" source="IKCe0DnfbzoJhUQUdqvM-20" target="IKCe0DnfbzoJhUQUdqvM-26" edge="1"> | ||
<mxGeometry width="50" height="50" relative="1" as="geometry"> | ||
<mxPoint x="490" y="940" as="sourcePoint" /> | ||
<mxPoint x="540" y="910" as="targetPoint" /> | ||
</mxGeometry> | ||
</mxCell> | ||
<mxCell id="IKCe0DnfbzoJhUQUdqvM-25" value="Yes" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=1;points=[];movable=1;rotatable=1;deletable=1;editable=1;locked=0;connectable=1;" parent="IKCe0DnfbzoJhUQUdqvM-24" vertex="1" connectable="0"> | ||
<mxGeometry relative="1" as="geometry"> | ||
<mxPoint x="-20" y="-55" as="offset" /> | ||
</mxGeometry> | ||
</mxCell> | ||
<mxCell id="IKCe0DnfbzoJhUQUdqvM-26" value="Include header from quill/std for STL there is probably already support on how to serialise it<div><br></div><div>e.g. #include &lt;quill/std/Vector&gt;</div>" style="rounded=0;whiteSpace=wrap;html=1;" parent="1" vertex="1"> | ||
<mxGeometry x="185" y="1180" width="330" height="100" as="geometry" /> | ||
</mxCell> | ||
<mxCell id="IKCe0DnfbzoJhUQUdqvM-27" value="" style="endArrow=none;html=1;rounded=0;exitX=1;exitY=0.5;exitDx=0;exitDy=0;exitPerimeter=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" parent="1" source="IKCe0DnfbzoJhUQUdqvM-20" target="IKCe0DnfbzoJhUQUdqvM-29" edge="1"> | ||
<mxGeometry width="50" height="50" relative="1" as="geometry"> | ||
<mxPoint x="409.5" y="800" as="sourcePoint" /> | ||
<mxPoint x="590" y="910" as="targetPoint" /> | ||
</mxGeometry> | ||
</mxCell> | ||
<mxCell id="IKCe0DnfbzoJhUQUdqvM-28" value="No" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=1;points=[];movable=1;rotatable=1;deletable=1;editable=1;locked=0;connectable=1;" parent="1" vertex="1" connectable="0"> | ||
<mxGeometry x="414" y="990" as="geometry" /> | ||
</mxCell> | ||
<mxCell id="IKCe0DnfbzoJhUQUdqvM-29" value="User Defined Type Codec Required" style="rounded=1;whiteSpace=wrap;html=1;absoluteArcSize=1;arcSize=14;strokeWidth=2;" parent="1" vertex="1"> | ||
<mxGeometry x="570" y="950" width="200" height="100" as="geometry" /> | ||
</mxCell> | ||
<mxCell id="IKCe0DnfbzoJhUQUdqvM-30" value="" style="endArrow=none;html=1;rounded=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;exitX=1;exitY=0.5;exitDx=0;exitDy=0;" parent="1" source="IKCe0DnfbzoJhUQUdqvM-29" target="IKCe0DnfbzoJhUQUdqvM-19" edge="1"> | ||
<mxGeometry width="50" height="50" relative="1" as="geometry"> | ||
<mxPoint x="720" y="450" as="sourcePoint" /> | ||
<mxPoint x="870" y="280" as="targetPoint" /> | ||
</mxGeometry> | ||
</mxCell> | ||
<mxCell id="IKCe0DnfbzoJhUQUdqvM-31" value="CopyConstructibleTypeCodec: Copy Object via Copy Constructor<div><br><div>Copies the object using its copy constructor. Less efficient than copy members one by one in place using a custom codec, but still very good especially for very complex types</div></div><div><br></div><div><div>&nbsp;template &lt;&gt; &nbsp;struct fmtquill::formatter&lt;UserType&gt; &nbsp;{ ... };</div><div>&nbsp;</div><div>template &lt;&gt; struct quill::Codec&lt;UserType&gt; : CopyConstructibleTypeCodec&lt;UserType&gt; { };</div></div>" style="rounded=0;whiteSpace=wrap;html=1;" parent="1" vertex="1"> | ||
<mxGeometry x="860" y="935" width="540" height="130" as="geometry" /> | ||
</mxCell> | ||
<mxCell id="IKCe0DnfbzoJhUQUdqvM-32" value="<div>Create Custom Codec</div><div><br></div>Provide your own codec which copies all members of the class in place in the spec buffer. This is a faster alternative to CopyConstructibleCodec when for example you object has members like std::vector, avoiding any extra memory allocations of the copy constructor" style="rounded=0;whiteSpace=wrap;html=1;" parent="1" vertex="1"> | ||
<mxGeometry x="860" y="1100" width="540" height="130" as="geometry" /> | ||
</mxCell> | ||
<mxCell id="IKCe0DnfbzoJhUQUdqvM-33" value="" style="endArrow=none;html=1;rounded=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;exitX=1;exitY=0.5;exitDx=0;exitDy=0;" parent="1" source="IKCe0DnfbzoJhUQUdqvM-29" target="IKCe0DnfbzoJhUQUdqvM-31" edge="1"> | ||
<mxGeometry width="50" height="50" relative="1" as="geometry"> | ||
<mxPoint x="660" y="920" as="sourcePoint" /> | ||
<mxPoint x="870" y="850" as="targetPoint" /> | ||
</mxGeometry> | ||
</mxCell> | ||
<mxCell id="IKCe0DnfbzoJhUQUdqvM-34" value="" style="endArrow=none;html=1;rounded=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;exitX=1;exitY=0.5;exitDx=0;exitDy=0;" parent="1" source="IKCe0DnfbzoJhUQUdqvM-29" target="IKCe0DnfbzoJhUQUdqvM-32" edge="1"> | ||
<mxGeometry width="50" height="50" relative="1" as="geometry"> | ||
<mxPoint x="660" y="920" as="sourcePoint" /> | ||
<mxPoint x="870" y="1030" as="targetPoint" /> | ||
</mxGeometry> | ||
</mxCell> | ||
</root> | ||
</mxGraphModel> | ||
</diagram> | ||
</mxfile> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
53 changes: 53 additions & 0 deletions
53
examples/user_defined_types_logging_ostream_conversion.cpp
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
#include "quill/Backend.h" | ||
#include "quill/Frontend.h" | ||
#include "quill/LogMacros.h" | ||
#include "quill/Logger.h" | ||
#include "quill/codec/OstreamConvertibleTypeCodec.h" | ||
#include "quill/sinks/ConsoleSink.h" | ||
|
||
#include <cstdint> | ||
#include <sstream> | ||
#include <string> | ||
#include <utility> | ||
|
||
/** | ||
* This example illustrates logging user-defined types by converting them to string on the hot path explicitly | ||
*/ | ||
|
||
class User | ||
{ | ||
public: | ||
User(std::string name, std::string surname, uint32_t age) | ||
: name(std::move(name)), surname(std::move(surname)), age(age) {}; | ||
|
||
friend std::ostream& operator<<(std::ostream& os, User const& obj) | ||
{ | ||
os << "name: " << obj.name << ", surname: " << obj.surname << ", age: " << obj.age; | ||
return os; | ||
} | ||
|
||
private: | ||
std::string name; | ||
std::string surname; | ||
uint32_t age; | ||
}; | ||
|
||
template <> | ||
struct quill::Codec<User> : quill::OstreamConvertibleTypeCodec<User> | ||
{ | ||
}; | ||
|
||
int main() | ||
{ | ||
// Start the backend thread | ||
quill::BackendOptions backend_options; | ||
quill::Backend::start(backend_options); | ||
|
||
// Frontend | ||
auto console_sink = quill::Frontend::create_or_get_sink<quill::ConsoleSink>("sink_id_1"); | ||
quill::Logger* logger = quill::Frontend::create_or_get_logger("root", std::move(console_sink)); | ||
|
||
User user_1{"Super", "User", 1}; | ||
|
||
LOG_INFO(logger, "User is [{}]", user_1); | ||
} |
71 changes: 71 additions & 0 deletions
71
examples/user_defined_types_logging_string_convertible_type.cpp
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
#include "quill/Backend.h" | ||
#include "quill/Frontend.h" | ||
#include "quill/LogMacros.h" | ||
#include "quill/Logger.h" | ||
#include "quill/bundled/fmt/ranges.h" | ||
#include "quill/codec/StringConvertibleTypeCodec.h" | ||
#include "quill/sinks/ConsoleSink.h" | ||
|
||
#include <cstdint> | ||
#include <string> | ||
#include <utility> | ||
|
||
/** | ||
* This example illustrates logging user-defined types by implicitly converting it to a string in the hot path | ||
*/ | ||
|
||
class User | ||
{ | ||
public: | ||
User(std::string name, std::string surname, uint32_t age) | ||
: name(std::move(name)), surname(std::move(surname)), age(age) | ||
{ | ||
favorite_colors.push_back("red"); | ||
favorite_colors.push_back("blue"); | ||
favorite_colors.push_back("green"); | ||
}; | ||
|
||
std::string name; | ||
std::string surname; | ||
uint32_t age; | ||
std::vector<std::string> favorite_colors; | ||
}; | ||
|
||
/***/ | ||
template <> | ||
struct fmtquill::formatter<User> | ||
{ | ||
constexpr auto parse(format_parse_context& ctx) { return ctx.begin(); } | ||
|
||
auto format(::User const& user, format_context& ctx) const | ||
{ | ||
return fmtquill::format_to(ctx.out(), "Name: {}, Surname: {}, Age: {}, Favorite Colors: {}", | ||
user.name, user.surname, user.age, user.favorite_colors); | ||
} | ||
}; | ||
|
||
/***/ | ||
template <> | ||
struct quill::Codec<User> : quill::StringConvertibleTypeCodec<User> | ||
{ | ||
}; | ||
|
||
/***/ | ||
int main() | ||
{ | ||
// Start the backend thread | ||
quill::BackendOptions backend_options; | ||
quill::Backend::start(backend_options); | ||
|
||
// Frontend | ||
auto console_sink = quill::Frontend::create_or_get_sink<quill::ConsoleSink>("sink_id_1"); | ||
quill::Logger* logger = quill::Frontend::create_or_get_logger("root", std::move(console_sink)); | ||
|
||
User user_1{"Super", "User", 1}; | ||
|
||
LOG_INFO(logger, "User is [{}]", user_1); | ||
|
||
User user_2{"Another", "User", 12}; | ||
|
||
LOG_INFO(logger, "User is [{}]", user_2); | ||
} |
Oops, something went wrong.