diff --git a/app_tracing.cpp b/app_tracing.cpp new file mode 100644 index 0000000..a3132ea --- /dev/null +++ b/app_tracing.cpp @@ -0,0 +1,7 @@ + +#include + +namespace opentracing { +template<> MyHotTracer* MyHotTracer::s_tracer = 0; +} + diff --git a/app_tracing.h b/app_tracing.h new file mode 100644 index 0000000..fa74198 --- /dev/null +++ b/app_tracing.h @@ -0,0 +1,36 @@ +#ifndef INCLUDED_TRACING_H +#define INCLUDED_TRACING_H + +#include +#include + +#include + +using namespace opentracing; + +// Defining two "different" tracer implementations +typedef NoopTracer ZipkinV1; +typedef NoopTracer ZipkinV2; + +// Setting up stuff... Would be nice if they weren't that many... +// is there any way `GenericTracer` to deduce those from just MyHotTracer? +typedef HotTracer MyHotTracer; +typedef HotSpan MyHotSpan; +typedef HotOptions MyHotOptions; +typedef HotContext MyHotContext; +typedef HotAdapter MyHotAdapter; + +typedef GenericTracer + GlobalTracer; + +#include + +// Now we "upgrade" the entire system to C++11. Yeiii! +typedef Cpp11Tracer Cpp11GlobalTracer; + + +#endif // INCLUDED_TRACING_H diff --git a/hot.cpp b/hot.cpp new file mode 100644 index 0000000..e69de29 diff --git a/hot.h b/hot.h new file mode 100644 index 0000000..9c34b00 --- /dev/null +++ b/hot.h @@ -0,0 +1,297 @@ +#ifndef INCLUDED_OPENTRACING_HOT_H +#define INCLUDED_OPENTRACING_HOT_H + +// -------------- Copied from noop.h -------------- + +#include +#include +#include +#include +#include +#include +#include + +namespace opentracing { + +template class HotAdapter; +template class HotContext; +template class HotOptions; +template class HotSpan; +template class HotTracer; + +template +class HotAdapter { + typedef HotContext MyHotContext; + public: + typedef MyHotContext* iterator; + typedef const MyHotContext* const_iterator; + + BaggageRef ref(const const_iterator& it) const + { + static const char empty[] = ""; + return BaggageRef(empty, empty); + } + + Baggage copy(const const_iterator& it) const + { + return Baggage("", ""); + } +}; + + +/** + * Note: VERY TRICKY. Pay attention to const-ness here. Span's context mustnn't + * be const but `extract()`'s has to be const. To be properly thought/implemented. + */ +template +class HotContext : public GenericSpanContext, HotAdapter > { + typedef typename T1::SpanContext SpanContext1; + typedef typename T2::SpanContext SpanContext2; + + const SpanContext1 * ctx1; // Note: Might be NULL + const SpanContext2 * ctx2; // Note: Might be NULL + + friend class HotTracer; + friend class HotSpan; + + HotContext(const SpanContext1 * ctx1_, const SpanContext2 * ctx2_) + : ctx1(ctx1_) + , ctx2(ctx2_) + { + } + + HotContext() + { + } + + public: + + typedef GenericSpanContext, HotAdapter > BaggageIterator; + + BaggageIterator baggageBeginImp() const + { + return baggageEndImp(); + } + BaggageIterator baggageEndImp() const + { + return BaggageIterator(this); + } + + int getBaggageImp(const StringRef&, std::string*) const + { + return 1; + } + int getBaggageImp(const StringRef&, std::vector*) const + { + return 1; + } +}; + +template +class HotOptions + : public GenericSpanOptions, HotContext, HotAdapter > { + public: + int setOperationImp(const StringRef&) + { + return 0; + } + int setStartTimeImp(const uint64_t) + { + return 0; + } + int setReferenceImp(const SpanReferenceType::Value, const HotContext&) + { + return 0; + } + + template + int setTagImp(const StringRef&, const T&) + { + return 0; + } +}; + +template +class HotSpan : public GenericSpan, HotContext, HotAdapter > { + typedef typename T1::Span SpanT1; + typedef typename T2::Span SpanT2; + + // Note: Might be NULL + SpanT1 * span1; + // Note: Might be NULL + SpanT2 * span2; + + friend class HotTracer; + + HotSpan(SpanT1 * span1_, SpanT2 * span2_) + : span1(span1_) + , span2(span2_) + { + } + + public: + + const HotContext* contextImp() const + { + return &m_context; + } + + int setOperationImp(const StringRef&) + { + return 0; + } + int setBaggageImp(const StringRef&, const StringRef&) + { + return 0; + } + + int getBaggageImp(const StringRef&, std::string*) const + { + return 1; + } + int getBaggageImp(const StringRef&, std::vector*) const + { + return 1; + } + + int finishImp() + { + return 0; + } + int finishImp(const uint64_t) + { + return 0; + } + + template + int tagImp(const StringRef&, const T&) + { + return 0; + } + + template + int logImp(const StringRef&, const T&) + { + return 0; + } + + template + int logImp(const StringRef&, const T&, const uint64_t) + { + return 0; + } + + HotContext m_context; +}; + +template +class HotTracer : public GenericTracer, + HotSpan, + HotOptions, + HotContext, + HotAdapter > { + typedef GenericTracer, + HotSpan, + HotOptions, + HotContext, + HotAdapter > Parent; + + T1 & t1; + T2 & t2; + public: + + HotTracer(T1& t1_, T2&t2_) + : t1(t1_) + , t2(t2_) + { + } + + static void installImp(HotTracer*tracer) + { + s_tracer = tracer; + } + static void uninstallImp() + { + s_tracer = 0; + } + static HotTracer* instanceImp() + { + return s_tracer; + } + + HotOptions* makeSpanOptionsImp() + { + return new HotOptions(); + } + + HotSpan* startImp(const StringRef&name) + { + typename T1::Span * sp1 = t1.start(name); // note: might be NULL + typename T2::Span * sp2 = t2.start(name); // note: might be NULL + + return new HotSpan(sp1, sp2); + } + HotSpan* startImp(const HotOptions& options) + { + typename T1::Span * sp1 = t1.start(options); // note: might be NULL + typename T2::Span * sp2 = t2.start(options); // note: might be NULL + + return new HotSpan(sp1, sp2); + } + + template + int injectImp(CARRIER* carrier, const HotSpan & span) const + { + // What happens if one of those two fails? + if (span.span1) + { + t1.inject(carrier, *span.span1); + } + + if (span.span2) + { + t2.inject(carrier, *span.span2); + } + + return 0; + } + + template + HotContext* extractImp(const CARRIER& carrier) + { + const typename T1::SpanContext* ctx1 = t1.extract(carrier); + + const typename T2::SpanContext* ctx2 = t2.extract(carrier); + + return new HotContext(ctx1, ctx2); + } + + void cleanupImp(const HotOptions* ob) + { + if (ob) + { + delete ob; + } + } + void cleanupImp(const typename Parent::Span*ob) + { + if (ob) + { + delete ob; + } + } + + void cleanupImp(const HotContext*ob) + { + if (ob) + { + delete ob; + } + } + + private: + static HotTracer* s_tracer; +}; + +} // namespace opentracing +#endif // INCLUDED_OPENTRACING_HOT_H diff --git a/main.cpp b/main.cpp new file mode 100644 index 0000000..cfa54de --- /dev/null +++ b/main.cpp @@ -0,0 +1,35 @@ +#include + +/** + * To run: + * clear && g++ -I. -D__USE_XOPEN2K8 main.cpp build/opentracing/libopentracing.a -o main && ./main + */ +int main() +{ + // Setup + ZipkinV1 t1; + ZipkinV2 t2; + + MyHotTracer imp(t1, t2); + + GlobalTracer::install(&imp); + + + { + // Application code + auto tracer = Cpp11GlobalTracer::instance(); + + auto span = tracer.start("hi"); + + std::vector pairs; + + tracer.inject(&pairs, *span); + + auto ctx = tracer.extract(pairs); + } + + // Cleanup + GlobalTracer::uninstall(); + + return 0; +} diff --git a/tracing_cpp11.h b/tracing_cpp11.h new file mode 100644 index 0000000..91fe953 --- /dev/null +++ b/tracing_cpp11.h @@ -0,0 +1,47 @@ +#include +#include + +template +class Cpp11Tracer +{ + Tracer& tracer; + + Cpp11Tracer(Tracer& tracer_) + : tracer(tracer_) + { + } + +public: + typedef typename Tracer::Span Span; + typedef typename Tracer::SpanContext SpanContext; + + template + inline std::shared_ptr start(Args & args) + { + return std::shared_ptr(tracer.start(args), [this](Span *pi) { tracer.cleanup(pi); }); + } + + template + int inject(CARRIER* carrier, const Span& span) const + { + return tracer.inject(carrier, span); + } + + template + int inject(CARRIER* carrier, const SpanContext& context) const + { + return tracer.inject(carrier, context); + } + + template + std::shared_ptr extract(const CARRIER& carrier) + { + return std::shared_ptr(tracer.extract(carrier), [this](const SpanContext *pi) { tracer.cleanup(pi); }); + } + + static Cpp11Tracer instance() + { + Tracer * tracer = Tracer::instance(); + return Cpp11Tracer(*tracer); + } +};