Line data Source code
1 : #include "id_generator.h" 2 : 3 : #include <bitset> 4 : #include <chrono> 5 : 6 : #include "random.h" 7 : 8 : namespace datadog { 9 : namespace tracing { 10 : namespace { 11 : 12 : class DefaultIDGenerator : public IDGenerator { 13 : const bool trace_id_128_bit_; 14 : 15 : public: 16 593 : explicit DefaultIDGenerator(bool trace_id_128_bit) 17 593 : : trace_id_128_bit_(trace_id_128_bit) {} 18 : 19 82791 : TraceID trace_id(const TimePoint& start) const override { 20 82791 : TraceID result; 21 82791 : result.low = random_uint64(); 22 82791 : if (trace_id_128_bit_) { 23 : // Highest 32 bits contain a unix timestamp (the trace start time). 24 82791 : const auto since_epoch = start.wall.time_since_epoch(); 25 : const auto seconds = 26 82791 : std::chrono::duration_cast<std::chrono::seconds>(since_epoch).count(); 27 : // The farthest we'll go back is the unix epoch. 28 82791 : const std::uint64_t unsigned_seconds = seconds < 0 ? 0 : seconds; 29 82791 : result.high = unsigned_seconds << 32; 30 : } else { 31 : // In 64-bit mode, zero the most significant bit for compatibility with 32 : // older tracers that can't accept values above 33 : // `numeric_limits<int64_t>::max()`. 34 0 : std::bitset<64> bits = result.low; 35 0 : bits[63] = 0; 36 0 : result.low = bits.to_ullong(); 37 : } 38 82791 : return result; 39 : } 40 : 41 119 : std::uint64_t span_id() const override { 42 : // Zero the most significant bit for compatibility with older tracers that 43 : // can't accept values above `numeric_limits<int64_t>::max()`. 44 119 : std::bitset<64> bits = random_uint64(); 45 119 : bits[63] = 0; 46 238 : return bits.to_ullong(); 47 : } 48 : }; 49 : 50 : } // namespace 51 : 52 593 : std::shared_ptr<const IDGenerator> default_id_generator(bool trace_id_128_bit) { 53 593 : return std::make_shared<DefaultIDGenerator>(trace_id_128_bit); 54 : } 55 : 56 : } // namespace tracing 57 : } // namespace datadog