Line data Source code
1 : #include "span_data.h"
2 :
3 : #include <cassert>
4 : #include <cstddef>
5 :
6 : #include "error.h"
7 : #include "msgpack.h"
8 : #include "span_config.h"
9 : #include "span_defaults.h"
10 : #include "string_view.h"
11 : #include "tags.h"
12 :
13 : namespace datadog {
14 : namespace tracing {
15 : namespace {
16 :
17 30506 : Optional<StringView> lookup(
18 : const std::string& key,
19 : const std::unordered_map<std::string, std::string>& map) {
20 30506 : const auto found = map.find(key);
21 30506 : if (found != map.end()) {
22 30019 : return found->second;
23 : }
24 487 : return nullopt;
25 : }
26 :
27 : } // namespace
28 :
29 30500 : Optional<StringView> SpanData::environment() const {
30 30500 : return lookup(tags::environment, tags);
31 : }
32 :
33 6 : Optional<StringView> SpanData::version() const {
34 6 : return lookup(tags::version, tags);
35 : }
36 :
37 82916 : void SpanData::apply_config(const SpanDefaults& defaults,
38 : const SpanConfig& config, const Clock& clock) {
39 82916 : service = config.service.value_or(defaults.service);
40 82916 : name = config.name.value_or(defaults.name);
41 :
42 82934 : for (const auto& item : defaults.tags) {
43 18 : tags.insert(item);
44 : }
45 82916 : std::string environment = config.environment.value_or(defaults.environment);
46 82916 : if (!environment.empty()) {
47 30009 : tags.insert_or_assign(tags::environment, environment);
48 : }
49 82916 : std::string version = config.version.value_or(defaults.version);
50 82916 : if (!version.empty()) {
51 9 : tags.insert_or_assign(tags::version, version);
52 : }
53 82927 : for (const auto& [key, value] : config.tags) {
54 11 : if (!tags::is_internal(key)) {
55 11 : tags.insert_or_assign(key, value);
56 : }
57 : }
58 :
59 82916 : resource = config.resource.value_or(name);
60 82916 : service_type = config.service_type.value_or(defaults.service_type);
61 82916 : if (config.start) {
62 1 : start = *config.start;
63 : } else {
64 82915 : start = clock();
65 : }
66 82916 : }
67 :
68 419 : Expected<void> msgpack_encode(std::string& destination, const SpanData& span) {
69 : // clang-format off
70 419 : msgpack::pack_map(
71 : destination,
72 419 : "service", [&](auto& destination) {
73 419 : return msgpack::pack_string(destination, span.service);
74 : },
75 419 : "name", [&](auto& destination) {
76 419 : return msgpack::pack_string(destination, span.name);
77 : },
78 419 : "resource", [&](auto& destination) {
79 419 : return msgpack::pack_string(destination, span.resource);
80 : },
81 419 : "trace_id", [&](auto& destination) {
82 419 : msgpack::pack_integer(destination, span.trace_id.low);
83 419 : return Expected<void>{};
84 : },
85 419 : "span_id", [&](auto& destination) {
86 419 : msgpack::pack_integer(destination, span.span_id);
87 419 : return Expected<void>{};
88 : },
89 419 : "parent_id", [&](auto& destination) {
90 419 : msgpack::pack_integer(destination, span.parent_id);
91 419 : return Expected<void>{};
92 : },
93 419 : "start", [&](auto& destination) {
94 419 : msgpack::pack_integer(
95 419 : destination, std::uint64_t(std::chrono::duration_cast<std::chrono::nanoseconds>(
96 419 : span.start.wall.time_since_epoch())
97 419 : .count()));
98 419 : return Expected<void>{};
99 : },
100 419 : "duration", [&](auto& destination) {
101 419 : msgpack::pack_integer(
102 : destination,
103 419 : std::uint64_t(std::chrono::duration_cast<std::chrono::nanoseconds>(span.duration)
104 419 : .count()));
105 419 : return Expected<void>{};
106 : },
107 419 : "error", [&](auto& destination) {
108 419 : msgpack::pack_integer(destination, std::int32_t(span.error));
109 419 : return Expected<void>{};
110 : },
111 419 : "meta", [&](auto& destination) {
112 419 : return msgpack::pack_map(destination, span.tags,
113 1669 : [](std::string& destination, const auto& value) {
114 1669 : return msgpack::pack_string(destination, value);
115 419 : });
116 : }, "metrics",
117 419 : [&](auto& destination) {
118 419 : return msgpack::pack_map(destination, span.numeric_tags,
119 1249 : [](std::string& destination, const auto& value) {
120 1249 : msgpack::pack_double(destination, value);
121 1249 : return Expected<void>{};
122 419 : });
123 419 : }, "type", [&](auto& destination) {
124 419 : return msgpack::pack_string(destination, span.service_type);
125 : });
126 : // clang-format on
127 :
128 419 : return nullopt;
129 : }
130 :
131 418 : Expected<void> msgpack_encode(
132 : std::string& destination,
133 : const std::vector<std::unique_ptr<SpanData>>& spans) {
134 : return msgpack::pack_array(destination, spans,
135 419 : [](auto& destination, const auto& span_ptr) {
136 419 : assert(span_ptr);
137 419 : return msgpack_encode(destination, *span_ptr);
138 418 : });
139 : }
140 :
141 : } // namespace tracing
142 : } // namespace datadog
|