summaryrefslogtreecommitdiffstats
path: root/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/Tracer.h
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/jaegertracing/jaeger-client-cpp/src/jaegertracing/Tracer.h317
1 files changed, 317 insertions, 0 deletions
diff --git a/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/Tracer.h b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/Tracer.h
new file mode 100644
index 000000000..8d204267f
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/Tracer.h
@@ -0,0 +1,317 @@
+/*
+ * Copyright (c) 2017 Uber Technologies, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef JAEGERTRACING_TRACER_H
+#define JAEGERTRACING_TRACER_H
+
+#include <chrono>
+#include <memory>
+#include <random>
+#include <vector>
+
+#include <opentracing/noop.h>
+#include <opentracing/tracer.h>
+
+#include "jaegertracing/Compilers.h"
+#include "jaegertracing/Config.h"
+#include "jaegertracing/Constants.h"
+#include "jaegertracing/Logging.h"
+#include "jaegertracing/Span.h"
+#include "jaegertracing/Tag.h"
+#include "jaegertracing/baggage/BaggageSetter.h"
+#include "jaegertracing/baggage/RestrictionManager.h"
+#include "jaegertracing/metrics/Metrics.h"
+#include "jaegertracing/metrics/NullStatsFactory.h"
+#include "jaegertracing/net/IPAddress.h"
+#include "jaegertracing/platform/Hostname.h"
+#include "jaegertracing/propagation/Propagator.h"
+#include "jaegertracing/reporters/Reporter.h"
+#include "jaegertracing/samplers/Sampler.h"
+#include "jaegertracing/utils/ErrorUtil.h"
+
+namespace jaegertracing {
+
+class Tracer : public opentracing::Tracer,
+ public std::enable_shared_from_this<Tracer> {
+ public:
+ using SteadyClock = Span::SteadyClock;
+ using SystemClock = Span::SystemClock;
+ using string_view = opentracing::string_view;
+
+ static constexpr auto kGen128BitOption = 1;
+
+ static std::shared_ptr<opentracing::Tracer> make(const Config& config)
+ {
+ return make(config.serviceName(),
+ config,
+ std::shared_ptr<logging::Logger>(logging::nullLogger()));
+ }
+
+ static std::shared_ptr<opentracing::Tracer>
+ make(const std::string& serviceName, const Config& config)
+ {
+ return make(serviceName,
+ config,
+ std::shared_ptr<logging::Logger>(logging::nullLogger()));
+ }
+
+ static std::shared_ptr<opentracing::Tracer>
+ make(const std::string& serviceName,
+ const Config& config,
+ const std::shared_ptr<logging::Logger>& logger)
+ {
+ metrics::NullStatsFactory factory;
+ return make(serviceName, config, logger, factory);
+ }
+ static std::shared_ptr<opentracing::Tracer>
+ make(const std::string& serviceName,
+ const Config& config,
+ const std::shared_ptr<logging::Logger>& logger,
+ metrics::StatsFactory& statsFactory)
+ {
+ return make(serviceName, config, logger, statsFactory, 0);
+ }
+ static std::shared_ptr<opentracing::Tracer>
+ make(const std::string& serviceName,
+ const Config& config,
+ const std::shared_ptr<logging::Logger>& logger,
+ metrics::StatsFactory& statsFactory,
+ int options);
+
+ ~Tracer() { Close(); }
+
+ std::unique_ptr<opentracing::Span>
+ StartSpanWithOptions(string_view operationName,
+ const opentracing::StartSpanOptions& options) const
+ noexcept override;
+
+ opentracing::expected<void> Inject(const opentracing::SpanContext& ctx,
+ std::ostream& writer) const override
+ {
+ const auto* jaegerCtx = dynamic_cast<const SpanContext*>(&ctx);
+ if (!jaegerCtx) {
+ return opentracing::make_expected_from_error<void>(
+ opentracing::invalid_span_context_error);
+ }
+ _binaryPropagator.inject(*jaegerCtx, writer);
+ return opentracing::make_expected();
+ }
+
+ opentracing::expected<void>
+ Inject(const opentracing::SpanContext& ctx,
+ const opentracing::TextMapWriter& writer) const override
+ {
+ const auto* jaegerCtx = dynamic_cast<const SpanContext*>(&ctx);
+ if (!jaegerCtx) {
+ return opentracing::make_expected_from_error<void>(
+ opentracing::invalid_span_context_error);
+ }
+ _textPropagator.inject(*jaegerCtx, writer);
+ return opentracing::make_expected();
+ }
+
+ opentracing::expected<void>
+ Inject(const opentracing::SpanContext& ctx,
+ const opentracing::HTTPHeadersWriter& writer) const override
+ {
+ const auto* jaegerCtx = dynamic_cast<const SpanContext*>(&ctx);
+ if (!jaegerCtx) {
+ return opentracing::make_expected_from_error<void>(
+ opentracing::invalid_span_context_error);
+ }
+ _httpHeaderPropagator.inject(*jaegerCtx, writer);
+ return opentracing::make_expected();
+ }
+
+ opentracing::expected<std::unique_ptr<opentracing::SpanContext>>
+ Extract(std::istream& reader) const override
+ {
+ const auto spanContext = _binaryPropagator.extract(reader);
+ if (spanContext == SpanContext()) {
+ return std::unique_ptr<opentracing::SpanContext>();
+ }
+ return std::unique_ptr<opentracing::SpanContext>(
+ new SpanContext(spanContext));
+ }
+
+ opentracing::expected<std::unique_ptr<opentracing::SpanContext>>
+ Extract(const opentracing::TextMapReader& reader) const override
+ {
+ const auto spanContext = _textPropagator.extract(reader);
+ if (spanContext == SpanContext()) {
+ return std::unique_ptr<opentracing::SpanContext>();
+ }
+ return std::unique_ptr<opentracing::SpanContext>(
+ new SpanContext(spanContext));
+ }
+
+ opentracing::expected<std::unique_ptr<opentracing::SpanContext>>
+ Extract(const opentracing::HTTPHeadersReader& reader) const override
+ {
+ const auto spanContext = _httpHeaderPropagator.extract(reader);
+ if (spanContext == SpanContext()) {
+ return std::unique_ptr<opentracing::SpanContext>();
+ }
+ return std::unique_ptr<opentracing::SpanContext>(
+ new SpanContext(spanContext));
+ }
+
+ void Close() noexcept override
+ {
+ try {
+ _reporter->close();
+ _sampler->close();
+ _restrictionManager->close();
+ } catch (...) {
+ utils::ErrorUtil::logError(*_logger,
+ "Error occurred in Tracer::Close");
+ }
+ }
+
+ void close() noexcept { Close(); }
+
+ const std::string& serviceName() const { return _serviceName; }
+
+ const std::vector<Tag>& tags() const { return _tags; }
+
+ const baggage::BaggageSetter& baggageSetter() const
+ {
+ return _baggageSetter;
+ }
+
+ void reportSpan(const Span& span) const
+ {
+ _metrics->spansFinished().inc(1);
+ if (span.context().isSampled()) {
+ _reporter->report(span);
+ }
+ }
+
+ private:
+ Tracer(const std::string& serviceName,
+ const std::shared_ptr<samplers::Sampler>& sampler,
+ const std::shared_ptr<reporters::Reporter>& reporter,
+ const std::shared_ptr<logging::Logger>& logger,
+ const std::shared_ptr<metrics::Metrics>& metrics,
+ const propagation::HeadersConfig& headersConfig,
+ const std::vector<Tag>& tags,
+ int options)
+ : _serviceName(serviceName)
+ , _hostIPv4(net::IPAddress::localIP(AF_INET))
+ , _sampler(sampler)
+ , _reporter(reporter)
+ , _metrics(metrics)
+ , _logger(logger)
+ , _randomNumberGenerator()
+ , _textPropagator(headersConfig, _metrics)
+ , _httpHeaderPropagator(headersConfig, _metrics)
+ , _binaryPropagator(_metrics)
+ , _tags()
+ , _restrictionManager(new baggage::DefaultRestrictionManager(0))
+ , _baggageSetter(*_restrictionManager, *_metrics)
+ , _options(options)
+ {
+ _tags.push_back(Tag(kJaegerClientVersionTagKey, kJaegerClientVersion));
+
+ try {
+ _tags.push_back(Tag(kTracerHostnameTagKey, platform::hostname()));
+ } catch (const std::system_error&) {
+ // Ignore hostname error.
+ }
+
+ if (_hostIPv4 == net::IPAddress()) {
+ _logger->error("Unable to determine this host's IP address");
+ }
+ else {
+ _tags.push_back(Tag(kTracerIPTagKey, _hostIPv4.host()));
+ }
+
+ std::copy(tags.cbegin(), tags.cend(), std::back_inserter(_tags));
+
+ std::random_device device;
+ _randomNumberGenerator.seed(device());
+ }
+
+ uint64_t randomID() const
+ {
+ std::lock_guard<std::mutex> lock(_randomMutex);
+ auto value = _randomNumberGenerator();
+ while (value == 0) {
+ value = _randomNumberGenerator();
+ }
+ return value;
+ }
+
+ using OpenTracingTag = std::pair<std::string, opentracing::Value>;
+
+ std::unique_ptr<Span>
+ startSpanInternal(const SpanContext& context,
+ const std::string& operationName,
+ const SystemClock::time_point& startTimeSystem,
+ const SteadyClock::time_point& startTimeSteady,
+ const std::vector<Tag>& internalTags,
+ const std::vector<OpenTracingTag>& tags,
+ bool newTrace,
+ const std::vector<Reference>& references) const;
+
+ using OpenTracingRef = std::pair<opentracing::SpanReferenceType,
+ const opentracing::SpanContext*>;
+
+ struct AnalyzedReferences {
+ AnalyzedReferences()
+ : _parent(nullptr)
+ , _self(nullptr)
+ , _references()
+ {
+ }
+
+ const SpanContext* _parent;
+ const SpanContext* _self;
+ std::vector<Reference> _references;
+ };
+
+ AnalyzedReferences
+ analyzeReferences(const std::vector<OpenTracingRef>& references) const;
+
+ std::string _serviceName;
+ net::IPAddress _hostIPv4;
+ std::shared_ptr<samplers::Sampler> _sampler;
+ std::shared_ptr<reporters::Reporter> _reporter;
+ std::shared_ptr<metrics::Metrics> _metrics;
+ std::shared_ptr<logging::Logger> _logger;
+ mutable std::mt19937_64 _randomNumberGenerator;
+ mutable std::mutex _randomMutex;
+ propagation::TextMapPropagator _textPropagator;
+ propagation::HTTPHeaderPropagator _httpHeaderPropagator;
+ propagation::BinaryPropagator _binaryPropagator;
+ std::vector<Tag> _tags;
+ std::unique_ptr<baggage::RestrictionManager> _restrictionManager;
+ baggage::BaggageSetter _baggageSetter;
+ int _options;
+};
+
+
+// jaegertracing::SelfRef() returns an opentracing::SpanReference which can be passed to Tracer::StartSpan
+// to influence the SpanContext of the newly created span. Specifically, the new span inherits the traceID
+// and spanID from the passed SELF reference. It can be used to pass externally generated IDs to the tracer,
+// with the purpose of recording spans from data generated elsewhere (e.g. from logs), or by augmenting the
+// data of the existing span (Jaeger backend will merge multiple instances of the spans with the same IDs).
+// Must be the lone reference, can be used only for root spans
+opentracing::SpanReference SelfRef(const opentracing::SpanContext* span_context) noexcept;
+
+} // namespace jaegertracing
+
+#endif // JAEGERTRACING_TRACER_H