summaryrefslogtreecommitdiffstats
path: root/src/jaegertracing/jaeger-client-cpp
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 18:45:59 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 18:45:59 +0000
commit19fcec84d8d7d21e796c7624e521b60d28ee21ed (patch)
tree42d26aa27d1e3f7c0b8bd3fd14e7d7082f5008dc /src/jaegertracing/jaeger-client-cpp
parentInitial commit. (diff)
downloadceph-upstream/16.2.11+ds.tar.xz
ceph-upstream/16.2.11+ds.zip
Adding upstream version 16.2.11+ds.upstream/16.2.11+dsupstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/jaegertracing/jaeger-client-cpp')
-rw-r--r--src/jaegertracing/jaeger-client-cpp/.appveyor.yml25
-rw-r--r--src/jaegertracing/jaeger-client-cpp/.clang-format83
-rw-r--r--src/jaegertracing/jaeger-client-cpp/.clang-tidy407
-rw-r--r--src/jaegertracing/jaeger-client-cpp/.github/ISSUE_TEMPLATE.md28
-rw-r--r--src/jaegertracing/jaeger-client-cpp/.github/PULL_REQUEST_TEMPLATE.md18
-rw-r--r--src/jaegertracing/jaeger-client-cpp/.gitignore48
-rw-r--r--src/jaegertracing/jaeger-client-cpp/.gitmodules3
-rw-r--r--src/jaegertracing/jaeger-client-cpp/.travis.yml88
-rw-r--r--src/jaegertracing/jaeger-client-cpp/.ycm_extra_conf.py104
-rw-r--r--src/jaegertracing/jaeger-client-cpp/CHANGELOG.md89
-rw-r--r--src/jaegertracing/jaeger-client-cpp/CMakeLists.txt496
-rw-r--r--src/jaegertracing/jaeger-client-cpp/CONTRIBUTING.md117
-rw-r--r--src/jaegertracing/jaeger-client-cpp/Dockerfile.plugin9
-rw-r--r--src/jaegertracing/jaeger-client-cpp/LICENSE201
-rw-r--r--src/jaegertracing/jaeger-client-cpp/README.md135
-rw-r--r--src/jaegertracing/jaeger-client-cpp/RELEASE.md10
-rw-r--r--src/jaegertracing/jaeger-client-cpp/cmake/CodeCoverage.cmake180
-rw-r--r--src/jaegertracing/jaeger-client-cpp/cmake/Config.cmake.in20
-rw-r--r--src/jaegertracing/jaeger-client-cpp/cmake/FindOpenTracing.cmake95
-rw-r--r--src/jaegertracing/jaeger-client-cpp/cmake/Findnlohmann_json.cmake55
-rw-r--r--src/jaegertracing/jaeger-client-cpp/cmake/Findthrift.cmake93
-rw-r--r--src/jaegertracing/jaeger-client-cpp/cmake/Hunter/config.cmake1
-rw-r--r--src/jaegertracing/jaeger-client-cpp/cmake/HunterGate.cmake543
-rw-r--r--src/jaegertracing/jaeger-client-cpp/cmake/toolchain.cmake5
-rw-r--r--src/jaegertracing/jaeger-client-cpp/codecov.yml31
-rw-r--r--src/jaegertracing/jaeger-client-cpp/crossdock/Dockerfile10
-rw-r--r--src/jaegertracing/jaeger-client-cpp/crossdock/Server.cpp808
-rw-r--r--src/jaegertracing/jaeger-client-cpp/crossdock/Server.h87
-rw-r--r--src/jaegertracing/jaeger-client-cpp/crossdock/docker-compose.yml68
-rw-r--r--src/jaegertracing/jaeger-client-cpp/examples/App.cpp45
-rw-r--r--src/jaegertracing/jaeger-client-cpp/examples/config.yml6
-rw-r--r--src/jaegertracing/jaeger-client-cpp/idl/.gitignore6
-rw-r--r--src/jaegertracing/jaeger-client-cpp/idl/.travis.yml10
-rw-r--r--src/jaegertracing/jaeger-client-cpp/idl/CONTRIBUTING.md117
-rw-r--r--src/jaegertracing/jaeger-client-cpp/idl/DCO37
-rw-r--r--src/jaegertracing/jaeger-client-cpp/idl/LICENSE201
-rw-r--r--src/jaegertracing/jaeger-client-cpp/idl/Makefile39
-rw-r--r--src/jaegertracing/jaeger-client-cpp/idl/README.md15
-rw-r--r--src/jaegertracing/jaeger-client-cpp/idl/swagger/zipkin2-api.yaml415
-rw-r--r--src/jaegertracing/jaeger-client-cpp/idl/thrift/agent.thrift26
-rw-r--r--src/jaegertracing/jaeger-client-cpp/idl/thrift/aggregation_validator.thrift28
-rw-r--r--src/jaegertracing/jaeger-client-cpp/idl/thrift/baggage.thrift33
-rw-r--r--src/jaegertracing/jaeger-client-cpp/idl/thrift/crossdock/tracetest.thrift64
-rw-r--r--src/jaegertracing/jaeger-client-cpp/idl/thrift/dependency.thrift37
-rw-r--r--src/jaegertracing/jaeger-client-cpp/idl/thrift/jaeger.thrift84
-rw-r--r--src/jaegertracing/jaeger-client-cpp/idl/thrift/sampling.thrift58
-rw-r--r--src/jaegertracing/jaeger-client-cpp/idl/thrift/zipkincore.thrift344
-rwxr-xr-xsrc/jaegertracing/jaeger-client-cpp/scripts/build-plugin.sh32
-rwxr-xr-xsrc/jaegertracing/jaeger-client-cpp/scripts/build.sh40
-rwxr-xr-xsrc/jaegertracing/jaeger-client-cpp/scripts/clang-format.sh21
-rwxr-xr-xsrc/jaegertracing/jaeger-client-cpp/scripts/clang-tidy.sh23
-rw-r--r--src/jaegertracing/jaeger-client-cpp/scripts/thrift-gen.patch115
-rw-r--r--src/jaegertracing/jaeger-client-cpp/scripts/update-license.py100
-rwxr-xr-xsrc/jaegertracing/jaeger-client-cpp/scripts/update-licenses.sh8
-rwxr-xr-xsrc/jaegertracing/jaeger-client-cpp/scripts/upload-coverage.sh42
-rw-r--r--src/jaegertracing/jaeger-client-cpp/src/jaegertracing/Compilers.h34
-rw-r--r--src/jaegertracing/jaeger-client-cpp/src/jaegertracing/Config.cpp67
-rw-r--r--src/jaegertracing/jaeger-client-cpp/src/jaegertracing/Config.h116
-rw-r--r--src/jaegertracing/jaeger-client-cpp/src/jaegertracing/ConfigTest.cpp195
-rw-r--r--src/jaegertracing/jaeger-client-cpp/src/jaegertracing/Constants.h43
-rw-r--r--src/jaegertracing/jaeger-client-cpp/src/jaegertracing/Constants.h.in43
-rw-r--r--src/jaegertracing/jaeger-client-cpp/src/jaegertracing/DynamicLoad.cpp54
-rw-r--r--src/jaegertracing/jaeger-client-cpp/src/jaegertracing/DynamicallyLoadTracerTest.cpp53
-rw-r--r--src/jaegertracing/jaeger-client-cpp/src/jaegertracing/LogRecord.cpp39
-rw-r--r--src/jaegertracing/jaeger-client-cpp/src/jaegertracing/LogRecord.h72
-rw-r--r--src/jaegertracing/jaeger-client-cpp/src/jaegertracing/Logging.cpp58
-rw-r--r--src/jaegertracing/jaeger-client-cpp/src/jaegertracing/Logging.h44
-rw-r--r--src/jaegertracing/jaeger-client-cpp/src/jaegertracing/Reference.cpp41
-rw-r--r--src/jaegertracing/jaeger-client-cpp/src/jaegertracing/Reference.h56
-rw-r--r--src/jaegertracing/jaeger-client-cpp/src/jaegertracing/ReferenceTest.cpp39
-rw-r--r--src/jaegertracing/jaeger-client-cpp/src/jaegertracing/Sender.cpp17
-rw-r--r--src/jaegertracing/jaeger-client-cpp/src/jaegertracing/Sender.h56
-rw-r--r--src/jaegertracing/jaeger-client-cpp/src/jaegertracing/Span.cpp221
-rw-r--r--src/jaegertracing/jaeger-client-cpp/src/jaegertracing/Span.h282
-rw-r--r--src/jaegertracing/jaeger-client-cpp/src/jaegertracing/SpanContext.cpp68
-rw-r--r--src/jaegertracing/jaeger-client-cpp/src/jaegertracing/SpanContext.h223
-rw-r--r--src/jaegertracing/jaeger-client-cpp/src/jaegertracing/SpanContextTest.cpp117
-rw-r--r--src/jaegertracing/jaeger-client-cpp/src/jaegertracing/SpanTest.cpp33
-rw-r--r--src/jaegertracing/jaeger-client-cpp/src/jaegertracing/Tag.cpp79
-rw-r--r--src/jaegertracing/jaeger-client-cpp/src/jaegertracing/Tag.h70
-rw-r--r--src/jaegertracing/jaeger-client-cpp/src/jaegertracing/TagTest.cpp40
-rw-r--r--src/jaegertracing/jaeger-client-cpp/src/jaegertracing/ThriftMethods.cpp71
-rw-r--r--src/jaegertracing/jaeger-client-cpp/src/jaegertracing/ThriftSender.cpp132
-rw-r--r--src/jaegertracing/jaeger-client-cpp/src/jaegertracing/ThriftSender.h80
-rw-r--r--src/jaegertracing/jaeger-client-cpp/src/jaegertracing/ThriftSenderTest.cpp109
-rw-r--r--src/jaegertracing/jaeger-client-cpp/src/jaegertracing/TraceID.cpp49
-rw-r--r--src/jaegertracing/jaeger-client-cpp/src/jaegertracing/TraceID.h85
-rw-r--r--src/jaegertracing/jaeger-client-cpp/src/jaegertracing/TraceIDTest.cpp30
-rw-r--r--src/jaegertracing/jaeger-client-cpp/src/jaegertracing/Tracer.cpp279
-rw-r--r--src/jaegertracing/jaeger-client-cpp/src/jaegertracing/Tracer.h317
-rw-r--r--src/jaegertracing/jaeger-client-cpp/src/jaegertracing/TracerFactory.cpp63
-rw-r--r--src/jaegertracing/jaeger-client-cpp/src/jaegertracing/TracerFactory.h45
-rw-r--r--src/jaegertracing/jaeger-client-cpp/src/jaegertracing/TracerFactoryTest.cpp138
-rw-r--r--src/jaegertracing/jaeger-client-cpp/src/jaegertracing/TracerTest.cpp555
-rw-r--r--src/jaegertracing/jaeger-client-cpp/src/jaegertracing/baggage/BaggageSetter.cpp17
-rw-r--r--src/jaegertracing/jaeger-client-cpp/src/jaegertracing/baggage/BaggageSetter.h120
-rw-r--r--src/jaegertracing/jaeger-client-cpp/src/jaegertracing/baggage/BaggageTest.cpp181
-rw-r--r--src/jaegertracing/jaeger-client-cpp/src/jaegertracing/baggage/RemoteRestrictionJSON.cpp17
-rw-r--r--src/jaegertracing/jaeger-client-cpp/src/jaegertracing/baggage/RemoteRestrictionJSON.h62
-rw-r--r--src/jaegertracing/jaeger-client-cpp/src/jaegertracing/baggage/RemoteRestrictionManager.cpp177
-rw-r--r--src/jaegertracing/jaeger-client-cpp/src/jaegertracing/baggage/RemoteRestrictionManager.h92
-rw-r--r--src/jaegertracing/jaeger-client-cpp/src/jaegertracing/baggage/Restriction.cpp17
-rw-r--r--src/jaegertracing/jaeger-client-cpp/src/jaegertracing/baggage/Restriction.h49
-rw-r--r--src/jaegertracing/jaeger-client-cpp/src/jaegertracing/baggage/RestrictionManager.cpp17
-rw-r--r--src/jaegertracing/jaeger-client-cpp/src/jaegertracing/baggage/RestrictionManager.h61
-rw-r--r--src/jaegertracing/jaeger-client-cpp/src/jaegertracing/baggage/RestrictionsConfig.cpp17
-rw-r--r--src/jaegertracing/jaeger-client-cpp/src/jaegertracing/baggage/RestrictionsConfig.h82
-rw-r--r--src/jaegertracing/jaeger-client-cpp/src/jaegertracing/metrics/Counter.cpp17
-rw-r--r--src/jaegertracing/jaeger-client-cpp/src/jaegertracing/metrics/Counter.h37
-rw-r--r--src/jaegertracing/jaeger-client-cpp/src/jaegertracing/metrics/Gauge.cpp17
-rw-r--r--src/jaegertracing/jaeger-client-cpp/src/jaegertracing/metrics/Gauge.h37
-rw-r--r--src/jaegertracing/jaeger-client-cpp/src/jaegertracing/metrics/InMemoryStatsReporter.cpp86
-rw-r--r--src/jaegertracing/jaeger-client-cpp/src/jaegertracing/metrics/InMemoryStatsReporter.h67
-rw-r--r--src/jaegertracing/jaeger-client-cpp/src/jaegertracing/metrics/Metric.cpp17
-rw-r--r--src/jaegertracing/jaeger-client-cpp/src/jaegertracing/metrics/Metric.h57
-rw-r--r--src/jaegertracing/jaeger-client-cpp/src/jaegertracing/metrics/Metrics.cpp52
-rw-r--r--src/jaegertracing/jaeger-client-cpp/src/jaegertracing/metrics/Metrics.h243
-rw-r--r--src/jaegertracing/jaeger-client-cpp/src/jaegertracing/metrics/MetricsTest.cpp111
-rw-r--r--src/jaegertracing/jaeger-client-cpp/src/jaegertracing/metrics/NullCounter.cpp17
-rw-r--r--src/jaegertracing/jaeger-client-cpp/src/jaegertracing/metrics/NullCounter.h34
-rw-r--r--src/jaegertracing/jaeger-client-cpp/src/jaegertracing/metrics/NullGauge.cpp17
-rw-r--r--src/jaegertracing/jaeger-client-cpp/src/jaegertracing/metrics/NullGauge.h34
-rw-r--r--src/jaegertracing/jaeger-client-cpp/src/jaegertracing/metrics/NullStatsFactory.cpp17
-rw-r--r--src/jaegertracing/jaeger-client-cpp/src/jaegertracing/metrics/NullStatsFactory.h67
-rw-r--r--src/jaegertracing/jaeger-client-cpp/src/jaegertracing/metrics/NullStatsFactoryTest.cpp36
-rw-r--r--src/jaegertracing/jaeger-client-cpp/src/jaegertracing/metrics/NullStatsReporter.cpp17
-rw-r--r--src/jaegertracing/jaeger-client-cpp/src/jaegertracing/metrics/NullStatsReporter.h61
-rw-r--r--src/jaegertracing/jaeger-client-cpp/src/jaegertracing/metrics/NullTimer.cpp17
-rw-r--r--src/jaegertracing/jaeger-client-cpp/src/jaegertracing/metrics/NullTimer.h34
-rw-r--r--src/jaegertracing/jaeger-client-cpp/src/jaegertracing/metrics/StatsFactory.cpp42
-rw-r--r--src/jaegertracing/jaeger-client-cpp/src/jaegertracing/metrics/StatsFactory.h58
-rw-r--r--src/jaegertracing/jaeger-client-cpp/src/jaegertracing/metrics/StatsFactoryImpl.cpp122
-rw-r--r--src/jaegertracing/jaeger-client-cpp/src/jaegertracing/metrics/StatsFactoryImpl.h63
-rw-r--r--src/jaegertracing/jaeger-client-cpp/src/jaegertracing/metrics/StatsReporter.cpp17
-rw-r--r--src/jaegertracing/jaeger-client-cpp/src/jaegertracing/metrics/StatsReporter.h62
-rw-r--r--src/jaegertracing/jaeger-client-cpp/src/jaegertracing/metrics/Timer.cpp17
-rw-r--r--src/jaegertracing/jaeger-client-cpp/src/jaegertracing/metrics/Timer.h35
-rw-r--r--src/jaegertracing/jaeger-client-cpp/src/jaegertracing/net/IPAddress.cpp206
-rw-r--r--src/jaegertracing/jaeger-client-cpp/src/jaegertracing/net/IPAddress.h209
-rw-r--r--src/jaegertracing/jaeger-client-cpp/src/jaegertracing/net/IPAddressTest.cpp54
-rw-r--r--src/jaegertracing/jaeger-client-cpp/src/jaegertracing/net/Socket.cpp84
-rw-r--r--src/jaegertracing/jaeger-client-cpp/src/jaegertracing/net/Socket.h245
-rw-r--r--src/jaegertracing/jaeger-client-cpp/src/jaegertracing/net/SocketTest.cpp74
-rw-r--r--src/jaegertracing/jaeger-client-cpp/src/jaegertracing/net/URI.cpp224
-rw-r--r--src/jaegertracing/jaeger-client-cpp/src/jaegertracing/net/URI.h96
-rw-r--r--src/jaegertracing/jaeger-client-cpp/src/jaegertracing/net/URITest.cpp118
-rw-r--r--src/jaegertracing/jaeger-client-cpp/src/jaegertracing/net/http/Error.cpp17
-rw-r--r--src/jaegertracing/jaeger-client-cpp/src/jaegertracing/net/http/Error.h46
-rw-r--r--src/jaegertracing/jaeger-client-cpp/src/jaegertracing/net/http/Header.cpp17
-rw-r--r--src/jaegertracing/jaeger-client-cpp/src/jaegertracing/net/http/Header.h98
-rw-r--r--src/jaegertracing/jaeger-client-cpp/src/jaegertracing/net/http/HeaderTest.cpp49
-rw-r--r--src/jaegertracing/jaeger-client-cpp/src/jaegertracing/net/http/Method.cpp48
-rw-r--r--src/jaegertracing/jaeger-client-cpp/src/jaegertracing/net/http/Method.h46
-rw-r--r--src/jaegertracing/jaeger-client-cpp/src/jaegertracing/net/http/MethodTest.cpp39
-rw-r--r--src/jaegertracing/jaeger-client-cpp/src/jaegertracing/net/http/Request.cpp59
-rw-r--r--src/jaegertracing/jaeger-client-cpp/src/jaegertracing/net/http/Request.h66
-rw-r--r--src/jaegertracing/jaeger-client-cpp/src/jaegertracing/net/http/Response.cpp94
-rw-r--r--src/jaegertracing/jaeger-client-cpp/src/jaegertracing/net/http/Response.h70
-rw-r--r--src/jaegertracing/jaeger-client-cpp/src/jaegertracing/net/http/ResponseTest.cpp103
-rw-r--r--src/jaegertracing/jaeger-client-cpp/src/jaegertracing/net/http/SocketReader.h48
-rw-r--r--src/jaegertracing/jaeger-client-cpp/src/jaegertracing/platform/Endian.cpp17
-rw-r--r--src/jaegertracing/jaeger-client-cpp/src/jaegertracing/platform/Endian.h83
-rw-r--r--src/jaegertracing/jaeger-client-cpp/src/jaegertracing/platform/Hostname.cpp17
-rw-r--r--src/jaegertracing/jaeger-client-cpp/src/jaegertracing/platform/Hostname.h58
-rw-r--r--src/jaegertracing/jaeger-client-cpp/src/jaegertracing/propagation/Extractor.cpp17
-rw-r--r--src/jaegertracing/jaeger-client-cpp/src/jaegertracing/propagation/Extractor.h38
-rw-r--r--src/jaegertracing/jaeger-client-cpp/src/jaegertracing/propagation/HeadersConfig.cpp17
-rw-r--r--src/jaegertracing/jaeger-client-cpp/src/jaegertracing/propagation/HeadersConfig.h107
-rw-r--r--src/jaegertracing/jaeger-client-cpp/src/jaegertracing/propagation/Injector.cpp17
-rw-r--r--src/jaegertracing/jaeger-client-cpp/src/jaegertracing/propagation/Injector.h39
-rw-r--r--src/jaegertracing/jaeger-client-cpp/src/jaegertracing/propagation/Propagator.cpp17
-rw-r--r--src/jaegertracing/jaeger-client-cpp/src/jaegertracing/propagation/Propagator.h321
-rw-r--r--src/jaegertracing/jaeger-client-cpp/src/jaegertracing/propagation/PropagatorTest.cpp72
-rw-r--r--src/jaegertracing/jaeger-client-cpp/src/jaegertracing/reporters/CompositeReporter.cpp17
-rw-r--r--src/jaegertracing/jaeger-client-cpp/src/jaegertracing/reporters/CompositeReporter.h66
-rw-r--r--src/jaegertracing/jaeger-client-cpp/src/jaegertracing/reporters/Config.cpp118
-rw-r--r--src/jaegertracing/jaeger-client-cpp/src/jaegertracing/reporters/Config.h137
-rw-r--r--src/jaegertracing/jaeger-client-cpp/src/jaegertracing/reporters/ConfigTest.cpp52
-rw-r--r--src/jaegertracing/jaeger-client-cpp/src/jaegertracing/reporters/InMemoryReporter.cpp17
-rw-r--r--src/jaegertracing/jaeger-client-cpp/src/jaegertracing/reporters/InMemoryReporter.h73
-rw-r--r--src/jaegertracing/jaeger-client-cpp/src/jaegertracing/reporters/LoggingReporter.cpp33
-rw-r--r--src/jaegertracing/jaeger-client-cpp/src/jaegertracing/reporters/LoggingReporter.h44
-rw-r--r--src/jaegertracing/jaeger-client-cpp/src/jaegertracing/reporters/NullReporter.cpp17
-rw-r--r--src/jaegertracing/jaeger-client-cpp/src/jaegertracing/reporters/NullReporter.h39
-rw-r--r--src/jaegertracing/jaeger-client-cpp/src/jaegertracing/reporters/RemoteReporter.cpp143
-rw-r--r--src/jaegertracing/jaeger-client-cpp/src/jaegertracing/reporters/RemoteReporter.h82
-rw-r--r--src/jaegertracing/jaeger-client-cpp/src/jaegertracing/reporters/Reporter.cpp17
-rw-r--r--src/jaegertracing/jaeger-client-cpp/src/jaegertracing/reporters/Reporter.h40
-rw-r--r--src/jaegertracing/jaeger-client-cpp/src/jaegertracing/reporters/ReporterTest.cpp135
-rw-r--r--src/jaegertracing/jaeger-client-cpp/src/jaegertracing/samplers/AdaptiveSampler.cpp106
-rw-r--r--src/jaegertracing/jaeger-client-cpp/src/jaegertracing/samplers/AdaptiveSampler.h73
-rw-r--r--src/jaegertracing/jaeger-client-cpp/src/jaegertracing/samplers/Config.cpp51
-rw-r--r--src/jaegertracing/jaeger-client-cpp/src/jaegertracing/samplers/Config.h190
-rw-r--r--src/jaegertracing/jaeger-client-cpp/src/jaegertracing/samplers/ConstSampler.cpp17
-rw-r--r--src/jaegertracing/jaeger-client-cpp/src/jaegertracing/samplers/ConstSampler.h61
-rw-r--r--src/jaegertracing/jaeger-client-cpp/src/jaegertracing/samplers/GuaranteedThroughputProbabilisticSampler.cpp39
-rw-r--r--src/jaegertracing/jaeger-client-cpp/src/jaegertracing/samplers/GuaranteedThroughputProbabilisticSampler.h94
-rw-r--r--src/jaegertracing/jaeger-client-cpp/src/jaegertracing/samplers/ProbabilisticSampler.cpp17
-rw-r--r--src/jaegertracing/jaeger-client-cpp/src/jaegertracing/samplers/ProbabilisticSampler.h84
-rw-r--r--src/jaegertracing/jaeger-client-cpp/src/jaegertracing/samplers/RateLimitingSampler.cpp17
-rw-r--r--src/jaegertracing/jaeger-client-cpp/src/jaegertracing/samplers/RateLimitingSampler.h67
-rw-r--r--src/jaegertracing/jaeger-client-cpp/src/jaegertracing/samplers/RemoteSamplingJSON.cpp17
-rw-r--r--src/jaegertracing/jaeger-client-cpp/src/jaegertracing/samplers/RemoteSamplingJSON.h175
-rw-r--r--src/jaegertracing/jaeger-client-cpp/src/jaegertracing/samplers/RemotelyControlledSampler.cpp213
-rw-r--r--src/jaegertracing/jaeger-client-cpp/src/jaegertracing/samplers/RemotelyControlledSampler.h99
-rw-r--r--src/jaegertracing/jaeger-client-cpp/src/jaegertracing/samplers/Sampler.cpp17
-rw-r--r--src/jaegertracing/jaeger-client-cpp/src/jaegertracing/samplers/Sampler.h52
-rw-r--r--src/jaegertracing/jaeger-client-cpp/src/jaegertracing/samplers/SamplerTest.cpp372
-rw-r--r--src/jaegertracing/jaeger-client-cpp/src/jaegertracing/samplers/SamplingStatus.cpp17
-rw-r--r--src/jaegertracing/jaeger-client-cpp/src/jaegertracing/samplers/SamplingStatus.h49
-rw-r--r--src/jaegertracing/jaeger-client-cpp/src/jaegertracing/testutils/EnvVariable.cpp17
-rw-r--r--src/jaegertracing/jaeger-client-cpp/src/jaegertracing/testutils/EnvVariable.h38
-rw-r--r--src/jaegertracing/jaeger-client-cpp/src/jaegertracing/testutils/MockAgent.cpp253
-rw-r--r--src/jaegertracing/jaeger-client-cpp/src/jaegertracing/testutils/MockAgent.h143
-rw-r--r--src/jaegertracing/jaeger-client-cpp/src/jaegertracing/testutils/MockAgentTest.cpp128
-rw-r--r--src/jaegertracing/jaeger-client-cpp/src/jaegertracing/testutils/SamplingManager.cpp17
-rw-r--r--src/jaegertracing/jaeger-client-cpp/src/jaegertracing/testutils/SamplingManager.h76
-rw-r--r--src/jaegertracing/jaeger-client-cpp/src/jaegertracing/testutils/TUDPTransport.cpp17
-rw-r--r--src/jaegertracing/jaeger-client-cpp/src/jaegertracing/testutils/TUDPTransport.h111
-rw-r--r--src/jaegertracing/jaeger-client-cpp/src/jaegertracing/testutils/TUDPTransportTest.cpp79
-rw-r--r--src/jaegertracing/jaeger-client-cpp/src/jaegertracing/testutils/TracerUtil.cpp82
-rw-r--r--src/jaegertracing/jaeger-client-cpp/src/jaegertracing/testutils/TracerUtil.h50
-rw-r--r--src/jaegertracing/jaeger-client-cpp/src/jaegertracing/thrift-gen/Agent.cpp380
-rw-r--r--src/jaegertracing/jaeger-client-cpp/src/jaegertracing/thrift-gen/Agent.h306
-rw-r--r--src/jaegertracing/jaeger-client-cpp/src/jaegertracing/thrift-gen/AggregationValidator.cpp424
-rw-r--r--src/jaegertracing/jaeger-client-cpp/src/jaegertracing/thrift-gen/AggregationValidator.h290
-rw-r--r--src/jaegertracing/jaeger-client-cpp/src/jaegertracing/thrift-gen/BaggageRestrictionManager.cpp453
-rw-r--r--src/jaegertracing/jaeger-client-cpp/src/jaegertracing/thrift-gen/BaggageRestrictionManager.h304
-rw-r--r--src/jaegertracing/jaeger-client-cpp/src/jaegertracing/thrift-gen/Collector.cpp481
-rw-r--r--src/jaegertracing/jaeger-client-cpp/src/jaegertracing/thrift-gen/Collector.h296
-rw-r--r--src/jaegertracing/jaeger-client-cpp/src/jaegertracing/thrift-gen/Dependency.cpp581
-rw-r--r--src/jaegertracing/jaeger-client-cpp/src/jaegertracing/thrift-gen/Dependency.h358
-rw-r--r--src/jaegertracing/jaeger-client-cpp/src/jaegertracing/thrift-gen/SamplingManager.cpp421
-rw-r--r--src/jaegertracing/jaeger-client-cpp/src/jaegertracing/thrift-gen/SamplingManager.h296
-rw-r--r--src/jaegertracing/jaeger-client-cpp/src/jaegertracing/thrift-gen/TracedService.cpp804
-rw-r--r--src/jaegertracing/jaeger-client-cpp/src/jaegertracing/thrift-gen/TracedService.h422
-rw-r--r--src/jaegertracing/jaeger-client-cpp/src/jaegertracing/thrift-gen/ZipkinCollector.cpp481
-rw-r--r--src/jaegertracing/jaeger-client-cpp/src/jaegertracing/thrift-gen/ZipkinCollector.h296
-rw-r--r--src/jaegertracing/jaeger-client-cpp/src/jaegertracing/thrift-gen/agent_constants.cpp17
-rw-r--r--src/jaegertracing/jaeger-client-cpp/src/jaegertracing/thrift-gen/agent_constants.h24
-rw-r--r--src/jaegertracing/jaeger-client-cpp/src/jaegertracing/thrift-gen/agent_types.cpp16
-rw-r--r--src/jaegertracing/jaeger-client-cpp/src/jaegertracing/thrift-gen/agent_types.h26
-rw-r--r--src/jaegertracing/jaeger-client-cpp/src/jaegertracing/thrift-gen/aggregation_validator_constants.cpp17
-rw-r--r--src/jaegertracing/jaeger-client-cpp/src/jaegertracing/thrift-gen/aggregation_validator_constants.h24
-rw-r--r--src/jaegertracing/jaeger-client-cpp/src/jaegertracing/thrift-gen/aggregation_validator_types.cpp131
-rw-r--r--src/jaegertracing/jaeger-client-cpp/src/jaegertracing/thrift-gen/aggregation_validator_types.h68
-rw-r--r--src/jaegertracing/jaeger-client-cpp/src/jaegertracing/thrift-gen/baggage_constants.cpp17
-rw-r--r--src/jaegertracing/jaeger-client-cpp/src/jaegertracing/thrift-gen/baggage_constants.h24
-rw-r--r--src/jaegertracing/jaeger-client-cpp/src/jaegertracing/thrift-gen/baggage_types.cpp131
-rw-r--r--src/jaegertracing/jaeger-client-cpp/src/jaegertracing/thrift-gen/baggage_types.h68
-rw-r--r--src/jaegertracing/jaeger-client-cpp/src/jaegertracing/thrift-gen/dependency_constants.cpp17
-rw-r--r--src/jaegertracing/jaeger-client-cpp/src/jaegertracing/thrift-gen/dependency_constants.h24
-rw-r--r--src/jaegertracing/jaeger-client-cpp/src/jaegertracing/thrift-gen/dependency_types.cpp266
-rw-r--r--src/jaegertracing/jaeger-client-cpp/src/jaegertracing/thrift-gen/dependency_types.h111
-rw-r--r--src/jaegertracing/jaeger-client-cpp/src/jaegertracing/thrift-gen/jaeger_constants.cpp17
-rw-r--r--src/jaegertracing/jaeger-client-cpp/src/jaegertracing/thrift-gen/jaeger_constants.h24
-rw-r--r--src/jaegertracing/jaeger-client-cpp/src/jaegertracing/thrift-gen/jaeger_types.cpp1336
-rw-r--r--src/jaegertracing/jaeger-client-cpp/src/jaegertracing/thrift-gen/jaeger_types.h465
-rw-r--r--src/jaegertracing/jaeger-client-cpp/src/jaegertracing/thrift-gen/sampling_constants.cpp17
-rw-r--r--src/jaegertracing/jaeger-client-cpp/src/jaegertracing/thrift-gen/sampling_constants.h24
-rw-r--r--src/jaegertracing/jaeger-client-cpp/src/jaegertracing/thrift-gen/sampling_types.cpp681
-rw-r--r--src/jaegertracing/jaeger-client-cpp/src/jaegertracing/thrift-gen/sampling_types.h283
-rw-r--r--src/jaegertracing/jaeger-client-cpp/src/jaegertracing/thrift-gen/tracetest_constants.cpp17
-rw-r--r--src/jaegertracing/jaeger-client-cpp/src/jaegertracing/thrift-gen/tracetest_constants.h24
-rw-r--r--src/jaegertracing/jaeger-client-cpp/src/jaegertracing/thrift-gen/tracetest_types.cpp804
-rw-r--r--src/jaegertracing/jaeger-client-cpp/src/jaegertracing/thrift-gen/tracetest_types.h316
-rw-r--r--src/jaegertracing/jaeger-client-cpp/src/jaegertracing/thrift-gen/zipkincore_constants.cpp49
-rw-r--r--src/jaegertracing/jaeger-client-cpp/src/jaegertracing/thrift-gen/zipkincore_constants.h40
-rw-r--r--src/jaegertracing/jaeger-client-cpp/src/jaegertracing/thrift-gen/zipkincore_types.cpp904
-rw-r--r--src/jaegertracing/jaeger-client-cpp/src/jaegertracing/thrift-gen/zipkincore_types.h373
-rw-r--r--src/jaegertracing/jaeger-client-cpp/src/jaegertracing/utils/EnvVariable.cpp17
-rw-r--r--src/jaegertracing/jaeger-client-cpp/src/jaegertracing/utils/EnvVariable.h65
-rw-r--r--src/jaegertracing/jaeger-client-cpp/src/jaegertracing/utils/ErrorUtil.cpp17
-rw-r--r--src/jaegertracing/jaeger-client-cpp/src/jaegertracing/utils/ErrorUtil.h55
-rw-r--r--src/jaegertracing/jaeger-client-cpp/src/jaegertracing/utils/ErrorUtilTest.cpp98
-rw-r--r--src/jaegertracing/jaeger-client-cpp/src/jaegertracing/utils/HTTPTransporter.cpp43
-rw-r--r--src/jaegertracing/jaeger-client-cpp/src/jaegertracing/utils/HTTPTransporter.h100
-rw-r--r--src/jaegertracing/jaeger-client-cpp/src/jaegertracing/utils/HTTPTransporterTest.cpp113
-rw-r--r--src/jaegertracing/jaeger-client-cpp/src/jaegertracing/utils/HexParsing.cpp17
-rw-r--r--src/jaegertracing/jaeger-client-cpp/src/jaegertracing/utils/HexParsing.h88
-rw-r--r--src/jaegertracing/jaeger-client-cpp/src/jaegertracing/utils/RateLimiter.cpp17
-rw-r--r--src/jaegertracing/jaeger-client-cpp/src/jaegertracing/utils/RateLimiter.h71
-rw-r--r--src/jaegertracing/jaeger-client-cpp/src/jaegertracing/utils/RateLimiterTest.cpp80
-rw-r--r--src/jaegertracing/jaeger-client-cpp/src/jaegertracing/utils/Transport.h52
-rw-r--r--src/jaegertracing/jaeger-client-cpp/src/jaegertracing/utils/UDPSenderTest.cpp83
-rw-r--r--src/jaegertracing/jaeger-client-cpp/src/jaegertracing/utils/UDPTransporter.cpp44
-rw-r--r--src/jaegertracing/jaeger-client-cpp/src/jaegertracing/utils/UDPTransporter.h88
-rw-r--r--src/jaegertracing/jaeger-client-cpp/src/jaegertracing/utils/YAML.cpp17
-rw-r--r--src/jaegertracing/jaeger-client-cpp/src/jaegertracing/utils/YAML.h48
289 files changed, 33192 insertions, 0 deletions
diff --git a/src/jaegertracing/jaeger-client-cpp/.appveyor.yml b/src/jaegertracing/jaeger-client-cpp/.appveyor.yml
new file mode 100644
index 000000000..f0c30e4f0
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/.appveyor.yml
@@ -0,0 +1,25 @@
+version: '{build}'
+
+image: Visual Studio 2017
+
+init:
+ - cmd: git config --global core.autocrlf true
+
+platform:
+ - x64
+
+configuration:
+ - Debug
+
+before_build:
+ - cmake -H. -Bbuild -A%PLATFORM% -DBUILD_TESTING=ON
+
+build:
+ project: build\jaegertracing.sln
+ parallel: true
+ verbosity: normal
+
+test_script:
+- ps: |
+ cd build
+ ctest -V -C $env:configuration --timeout 600 --output-on-failure \ No newline at end of file
diff --git a/src/jaegertracing/jaeger-client-cpp/.clang-format b/src/jaegertracing/jaeger-client-cpp/.clang-format
new file mode 100644
index 000000000..7e6effd2e
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/.clang-format
@@ -0,0 +1,83 @@
+Language: Cpp
+AccessModifierOffset: -2
+AlignAfterOpenBracket: Align
+AlignConsecutiveAssignments: false
+AlignConsecutiveDeclarations: false
+AlignEscapedNewlinesLeft: false
+AlignOperands: true
+AlignTrailingComments: false
+AllowAllParametersOfDeclarationOnNextLine: true
+AllowShortBlocksOnASingleLine: false
+AllowShortCaseLabelsOnASingleLine: false
+AllowShortFunctionsOnASingleLine: All
+AllowShortIfStatementsOnASingleLine: false
+AllowShortLoopsOnASingleLine: false
+AlwaysBreakAfterDefinitionReturnType: None
+AlwaysBreakAfterReturnType: None
+AlwaysBreakBeforeMultilineStrings: true
+AlwaysBreakTemplateDeclarations: true
+BinPackArguments: false
+BinPackParameters: false
+BraceWrapping:
+ AfterClass: false
+ AfterControlStatement: false
+ AfterEnum: false
+ AfterFunction: true
+ AfterNamespace: false
+ AfterStruct: false
+ AfterUnion: false
+ BeforeCatch: false
+ BeforeElse: true
+ IndentBraces: false
+BreakBeforeBinaryOperators: None
+BreakBeforeBraces: Custom
+BreakBeforeTernaryOperators: true
+BreakConstructorInitializersBeforeComma: true
+ColumnLimit: 80
+CommentPragmas: '^ IWYU pragma:'
+ConstructorInitializerAllOnOneLineOrOnePerLine: false
+ConstructorInitializerIndentWidth: 4
+ContinuationIndentWidth: 4
+Cpp11BracedListStyle: false
+DerivePointerAlignment: false
+DisableFormat: false
+ExperimentalAutoDetectBinPacking: false
+IncludeCategories:
+ - Regex: '^"(llvm|llvm-c|clang|clang-c)/'
+ Priority: 2
+ - Regex: '^(<|"(gtest|isl|json)/)'
+ Priority: 3
+ - Regex: '.*'
+ Priority: 1
+IndentCaseLabels: false
+IndentWidth: 4
+IndentWrappedFunctionNames: false
+KeepEmptyLinesAtTheStartOfBlocks: true
+MacroBlockBegin: ''
+MacroBlockEnd: ''
+MaxEmptyLinesToKeep: 1
+NamespaceIndentation: None
+ObjCBlockIndentWidth: 4
+ObjCSpaceAfterProperty: true
+ObjCSpaceBeforeProtocolList: true
+PenaltyBreakBeforeFirstCallParameter: 19
+PenaltyBreakComment: 300
+PenaltyBreakFirstLessLess: 120
+PenaltyBreakString: 1000
+PenaltyExcessCharacter: 1000000
+PenaltyReturnTypeOnItsOwnLine: 60
+PointerAlignment: Left
+ReflowComments: true
+SortIncludes: true
+SpaceAfterCStyleCast: false
+SpaceBeforeAssignmentOperators: true
+SpaceBeforeParens: ControlStatements
+SpaceInEmptyParentheses: false
+SpacesBeforeTrailingComments: 2
+SpacesInAngles: false
+SpacesInContainerLiterals: true
+SpacesInCStyleCastParentheses: false
+SpacesInParentheses: false
+SpacesInSquareBrackets: false
+Standard: Cpp11
+UseTab: Never
diff --git a/src/jaegertracing/jaeger-client-cpp/.clang-tidy b/src/jaegertracing/jaeger-client-cpp/.clang-tidy
new file mode 100644
index 000000000..895d42054
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/.clang-tidy
@@ -0,0 +1,407 @@
+Checks: 'clang-diagnostic-*,clang-analyzer-*,*'
+WarningsAsErrors: ''
+HeaderFilterRegex: ''
+AnalyzeTemporaryDtors: false
+CheckOptions:
+ - key: cert-dcl59-cpp.HeaderFileExtensions
+ value: h,hh,hpp,hxx
+ - key: cert-err09-cpp.CheckThrowTemporaries
+ value: '1'
+ - key: cert-err61-cpp.CheckThrowTemporaries
+ value: '1'
+ - key: cert-oop11-cpp.IncludeStyle
+ value: llvm
+ - key: cppcoreguidelines-pro-bounds-constant-array-index.GslHeader
+ value: ''
+ - key: cppcoreguidelines-pro-bounds-constant-array-index.IncludeStyle
+ value: '0'
+ - key: cppcoreguidelines-pro-type-member-init.IgnoreArrays
+ value: '0'
+ - key: google-build-namespaces.HeaderFileExtensions
+ value: h,hh,hpp,hxx
+ - key: google-global-names-in-headers.HeaderFileExtensions
+ value: h
+ - key: google-readability-braces-around-statements.ShortStatementLines
+ value: '1'
+ - key: google-readability-function-size.BranchThreshold
+ value: '4294967295'
+ - key: google-readability-function-size.LineThreshold
+ value: '4294967295'
+ - key: google-readability-function-size.StatementThreshold
+ value: '800'
+ - key: google-readability-namespace-comments.ShortNamespaceLines
+ value: '10'
+ - key: google-readability-namespace-comments.SpacesBeforeComments
+ value: '2'
+ - key: google-runtime-int.SignedTypePrefix
+ value: int
+ - key: google-runtime-int.TypeSuffix
+ value: ''
+ - key: google-runtime-int.UnsignedTypePrefix
+ value: uint
+ - key: google-runtime-references.WhiteListTypes
+ value: ''
+ - key: llvm-header-guard.HeaderFileExtensions
+ value: ',h,hh,hpp,hxx'
+ - key: llvm-namespace-comment.ShortNamespaceLines
+ value: '1'
+ - key: llvm-namespace-comment.SpacesBeforeComments
+ value: '1'
+ - key: misc-argument-comment.StrictMode
+ value: '0'
+ - key: misc-assert-side-effect.AssertMacros
+ value: assert
+ - key: misc-assert-side-effect.CheckFunctionCalls
+ value: '0'
+ - key: misc-dangling-handle.HandleClasses
+ value: 'std::basic_string_view;std::experimental::basic_string_view'
+ - key: misc-definitions-in-headers.HeaderFileExtensions
+ value: ',h,hh,hpp,hxx'
+ - key: misc-definitions-in-headers.UseHeaderFileExtension
+ value: '1'
+ - key: misc-misplaced-widening-cast.CheckImplicitCasts
+ value: '1'
+ - key: misc-move-constructor-init.IncludeStyle
+ value: llvm
+ - key: misc-sizeof-expression.WarnOnSizeOfCompareToConstant
+ value: '1'
+ - key: misc-sizeof-expression.WarnOnSizeOfConstant
+ value: '1'
+ - key: misc-sizeof-expression.WarnOnSizeOfThis
+ value: '1'
+ - key: misc-string-constructor.LargeLengthThreshold
+ value: '8388608'
+ - key: misc-string-constructor.WarnOnLargeLength
+ value: '1'
+ - key: misc-suspicious-enum-usage.StrictMode
+ value: '0'
+ - key: misc-suspicious-missing-comma.MaxConcatenatedTokens
+ value: '5'
+ - key: misc-suspicious-missing-comma.RatioThreshold
+ value: '0.200000'
+ - key: misc-suspicious-missing-comma.SizeThreshold
+ value: '5'
+ - key: misc-suspicious-string-compare.StringCompareLikeFunctions
+ value: ''
+ - key: misc-suspicious-string-compare.WarnOnImplicitComparison
+ value: '1'
+ - key: misc-suspicious-string-compare.WarnOnLogicalNotComparison
+ value: '0'
+ - key: misc-throw-by-value-catch-by-reference.CheckThrowTemporaries
+ value: '1'
+ - key: modernize-loop-convert.MaxCopySize
+ value: '16'
+ - key: modernize-loop-convert.MinConfidence
+ value: reasonable
+ - key: modernize-loop-convert.NamingStyle
+ value: CamelCase
+ - key: modernize-pass-by-value.IncludeStyle
+ value: llvm
+ - key: modernize-pass-by-value.ValuesOnly
+ value: '0'
+ - key: modernize-replace-auto-ptr.IncludeStyle
+ value: llvm
+ - key: modernize-use-auto.RemoveStars
+ value: '0'
+ - key: modernize-use-default-member-init.UseAssignment
+ value: '0'
+ - key: modernize-use-emplace.ContainersWithPushBack
+ value: '::std::vector;::std::list;::std::deque'
+ - key: modernize-use-emplace.SmartPointers
+ value: '::std::shared_ptr;::std::unique_ptr;::std::auto_ptr;::std::weak_ptr'
+ - key: modernize-use-nullptr.NullMacros
+ value: 'NULL'
+ - key: modernize-use-transparent-functors.SafeMode
+ value: '0'
+ - key: performance-faster-string-find.StringLikeClasses
+ value: 'std::basic_string'
+ - key: performance-for-range-copy.WarnOnAllAutoCopies
+ value: '0'
+ - key: performance-inefficient-string-concatenation.StrictMode
+ value: '0'
+ - key: performance-type-promotion-in-math-fn.IncludeStyle
+ value: llvm
+ - key: performance-unnecessary-value-param.IncludeStyle
+ value: llvm
+ - key: readability-braces-around-statements.ShortStatementLines
+ value: '0'
+ - key: readability-function-size.BranchThreshold
+ value: '4294967295'
+ - key: readability-function-size.LineThreshold
+ value: '4294967295'
+ - key: readability-function-size.StatementThreshold
+ value: '800'
+ - key: readability-identifier-naming.AbstractClassCase
+ value: aNy_CasE
+ - key: readability-identifier-naming.AbstractClassPrefix
+ value: ''
+ - key: readability-identifier-naming.AbstractClassSuffix
+ value: ''
+ - key: readability-identifier-naming.ClassCase
+ value: aNy_CasE
+ - key: readability-identifier-naming.ClassConstantCase
+ value: aNy_CasE
+ - key: readability-identifier-naming.ClassConstantPrefix
+ value: ''
+ - key: readability-identifier-naming.ClassConstantSuffix
+ value: ''
+ - key: readability-identifier-naming.ClassMemberCase
+ value: aNy_CasE
+ - key: readability-identifier-naming.ClassMemberPrefix
+ value: ''
+ - key: readability-identifier-naming.ClassMemberSuffix
+ value: ''
+ - key: readability-identifier-naming.ClassMethodCase
+ value: aNy_CasE
+ - key: readability-identifier-naming.ClassMethodPrefix
+ value: ''
+ - key: readability-identifier-naming.ClassMethodSuffix
+ value: ''
+ - key: readability-identifier-naming.ClassPrefix
+ value: ''
+ - key: readability-identifier-naming.ClassSuffix
+ value: ''
+ - key: readability-identifier-naming.ConstantCase
+ value: aNy_CasE
+ - key: readability-identifier-naming.ConstantMemberCase
+ value: aNy_CasE
+ - key: readability-identifier-naming.ConstantMemberPrefix
+ value: ''
+ - key: readability-identifier-naming.ConstantMemberSuffix
+ value: ''
+ - key: readability-identifier-naming.ConstantParameterCase
+ value: aNy_CasE
+ - key: readability-identifier-naming.ConstantParameterPrefix
+ value: ''
+ - key: readability-identifier-naming.ConstantParameterSuffix
+ value: ''
+ - key: readability-identifier-naming.ConstantPrefix
+ value: ''
+ - key: readability-identifier-naming.ConstantSuffix
+ value: ''
+ - key: readability-identifier-naming.ConstexprFunctionCase
+ value: aNy_CasE
+ - key: readability-identifier-naming.ConstexprFunctionPrefix
+ value: ''
+ - key: readability-identifier-naming.ConstexprFunctionSuffix
+ value: ''
+ - key: readability-identifier-naming.ConstexprMethodCase
+ value: aNy_CasE
+ - key: readability-identifier-naming.ConstexprMethodPrefix
+ value: ''
+ - key: readability-identifier-naming.ConstexprMethodSuffix
+ value: ''
+ - key: readability-identifier-naming.ConstexprVariableCase
+ value: aNy_CasE
+ - key: readability-identifier-naming.ConstexprVariablePrefix
+ value: ''
+ - key: readability-identifier-naming.ConstexprVariableSuffix
+ value: ''
+ - key: readability-identifier-naming.EnumCase
+ value: aNy_CasE
+ - key: readability-identifier-naming.EnumConstantCase
+ value: aNy_CasE
+ - key: readability-identifier-naming.EnumConstantPrefix
+ value: ''
+ - key: readability-identifier-naming.EnumConstantSuffix
+ value: ''
+ - key: readability-identifier-naming.EnumPrefix
+ value: ''
+ - key: readability-identifier-naming.EnumSuffix
+ value: ''
+ - key: readability-identifier-naming.FunctionCase
+ value: aNy_CasE
+ - key: readability-identifier-naming.FunctionPrefix
+ value: ''
+ - key: readability-identifier-naming.FunctionSuffix
+ value: ''
+ - key: readability-identifier-naming.GlobalConstantCase
+ value: aNy_CasE
+ - key: readability-identifier-naming.GlobalConstantPrefix
+ value: ''
+ - key: readability-identifier-naming.GlobalConstantSuffix
+ value: ''
+ - key: readability-identifier-naming.GlobalFunctionCase
+ value: aNy_CasE
+ - key: readability-identifier-naming.GlobalFunctionPrefix
+ value: ''
+ - key: readability-identifier-naming.GlobalFunctionSuffix
+ value: ''
+ - key: readability-identifier-naming.GlobalVariableCase
+ value: aNy_CasE
+ - key: readability-identifier-naming.GlobalVariablePrefix
+ value: ''
+ - key: readability-identifier-naming.GlobalVariableSuffix
+ value: ''
+ - key: readability-identifier-naming.IgnoreFailedSplit
+ value: '0'
+ - key: readability-identifier-naming.InlineNamespaceCase
+ value: aNy_CasE
+ - key: readability-identifier-naming.InlineNamespacePrefix
+ value: ''
+ - key: readability-identifier-naming.InlineNamespaceSuffix
+ value: ''
+ - key: readability-identifier-naming.LocalConstantCase
+ value: aNy_CasE
+ - key: readability-identifier-naming.LocalConstantPrefix
+ value: ''
+ - key: readability-identifier-naming.LocalConstantSuffix
+ value: ''
+ - key: readability-identifier-naming.LocalVariableCase
+ value: aNy_CasE
+ - key: readability-identifier-naming.LocalVariablePrefix
+ value: ''
+ - key: readability-identifier-naming.LocalVariableSuffix
+ value: ''
+ - key: readability-identifier-naming.MacroDefinitionCase
+ value: aNy_CasE
+ - key: readability-identifier-naming.MacroDefinitionPrefix
+ value: ''
+ - key: readability-identifier-naming.MacroDefinitionSuffix
+ value: ''
+ - key: readability-identifier-naming.MemberCase
+ value: aNy_CasE
+ - key: readability-identifier-naming.MemberPrefix
+ value: ''
+ - key: readability-identifier-naming.MemberSuffix
+ value: ''
+ - key: readability-identifier-naming.MethodCase
+ value: aNy_CasE
+ - key: readability-identifier-naming.MethodPrefix
+ value: ''
+ - key: readability-identifier-naming.MethodSuffix
+ value: ''
+ - key: readability-identifier-naming.NamespaceCase
+ value: aNy_CasE
+ - key: readability-identifier-naming.NamespacePrefix
+ value: ''
+ - key: readability-identifier-naming.NamespaceSuffix
+ value: ''
+ - key: readability-identifier-naming.ParameterCase
+ value: aNy_CasE
+ - key: readability-identifier-naming.ParameterPackCase
+ value: aNy_CasE
+ - key: readability-identifier-naming.ParameterPackPrefix
+ value: ''
+ - key: readability-identifier-naming.ParameterPackSuffix
+ value: ''
+ - key: readability-identifier-naming.ParameterPrefix
+ value: ''
+ - key: readability-identifier-naming.ParameterSuffix
+ value: ''
+ - key: readability-identifier-naming.PrivateMemberCase
+ value: aNy_CasE
+ - key: readability-identifier-naming.PrivateMemberPrefix
+ value: ''
+ - key: readability-identifier-naming.PrivateMemberSuffix
+ value: ''
+ - key: readability-identifier-naming.PrivateMethodCase
+ value: aNy_CasE
+ - key: readability-identifier-naming.PrivateMethodPrefix
+ value: ''
+ - key: readability-identifier-naming.PrivateMethodSuffix
+ value: ''
+ - key: readability-identifier-naming.ProtectedMemberCase
+ value: aNy_CasE
+ - key: readability-identifier-naming.ProtectedMemberPrefix
+ value: ''
+ - key: readability-identifier-naming.ProtectedMemberSuffix
+ value: ''
+ - key: readability-identifier-naming.ProtectedMethodCase
+ value: aNy_CasE
+ - key: readability-identifier-naming.ProtectedMethodPrefix
+ value: ''
+ - key: readability-identifier-naming.ProtectedMethodSuffix
+ value: ''
+ - key: readability-identifier-naming.PublicMemberCase
+ value: aNy_CasE
+ - key: readability-identifier-naming.PublicMemberPrefix
+ value: ''
+ - key: readability-identifier-naming.PublicMemberSuffix
+ value: ''
+ - key: readability-identifier-naming.PublicMethodCase
+ value: aNy_CasE
+ - key: readability-identifier-naming.PublicMethodPrefix
+ value: ''
+ - key: readability-identifier-naming.PublicMethodSuffix
+ value: ''
+ - key: readability-identifier-naming.StaticConstantCase
+ value: aNy_CasE
+ - key: readability-identifier-naming.StaticConstantPrefix
+ value: ''
+ - key: readability-identifier-naming.StaticConstantSuffix
+ value: ''
+ - key: readability-identifier-naming.StaticVariableCase
+ value: aNy_CasE
+ - key: readability-identifier-naming.StaticVariablePrefix
+ value: ''
+ - key: readability-identifier-naming.StaticVariableSuffix
+ value: ''
+ - key: readability-identifier-naming.StructCase
+ value: aNy_CasE
+ - key: readability-identifier-naming.StructPrefix
+ value: ''
+ - key: readability-identifier-naming.StructSuffix
+ value: ''
+ - key: readability-identifier-naming.TemplateParameterCase
+ value: aNy_CasE
+ - key: readability-identifier-naming.TemplateParameterPrefix
+ value: ''
+ - key: readability-identifier-naming.TemplateParameterSuffix
+ value: ''
+ - key: readability-identifier-naming.TemplateTemplateParameterCase
+ value: aNy_CasE
+ - key: readability-identifier-naming.TemplateTemplateParameterPrefix
+ value: ''
+ - key: readability-identifier-naming.TemplateTemplateParameterSuffix
+ value: ''
+ - key: readability-identifier-naming.TypeAliasCase
+ value: aNy_CasE
+ - key: readability-identifier-naming.TypeAliasPrefix
+ value: ''
+ - key: readability-identifier-naming.TypeAliasSuffix
+ value: ''
+ - key: readability-identifier-naming.TypeTemplateParameterCase
+ value: aNy_CasE
+ - key: readability-identifier-naming.TypeTemplateParameterPrefix
+ value: ''
+ - key: readability-identifier-naming.TypeTemplateParameterSuffix
+ value: ''
+ - key: readability-identifier-naming.TypedefCase
+ value: aNy_CasE
+ - key: readability-identifier-naming.TypedefPrefix
+ value: ''
+ - key: readability-identifier-naming.TypedefSuffix
+ value: ''
+ - key: readability-identifier-naming.UnionCase
+ value: aNy_CasE
+ - key: readability-identifier-naming.UnionPrefix
+ value: ''
+ - key: readability-identifier-naming.UnionSuffix
+ value: ''
+ - key: readability-identifier-naming.ValueTemplateParameterCase
+ value: aNy_CasE
+ - key: readability-identifier-naming.ValueTemplateParameterPrefix
+ value: ''
+ - key: readability-identifier-naming.ValueTemplateParameterSuffix
+ value: ''
+ - key: readability-identifier-naming.VariableCase
+ value: aNy_CasE
+ - key: readability-identifier-naming.VariablePrefix
+ value: ''
+ - key: readability-identifier-naming.VariableSuffix
+ value: ''
+ - key: readability-identifier-naming.VirtualMethodCase
+ value: aNy_CasE
+ - key: readability-identifier-naming.VirtualMethodPrefix
+ value: ''
+ - key: readability-identifier-naming.VirtualMethodSuffix
+ value: ''
+ - key: readability-implicit-bool-cast.AllowConditionalIntegerCasts
+ value: '0'
+ - key: readability-implicit-bool-cast.AllowConditionalPointerCasts
+ value: '0'
+ - key: readability-simplify-boolean-expr.ChainedConditionalAssignment
+ value: '0'
+ - key: readability-simplify-boolean-expr.ChainedConditionalReturn
+ value: '0'
diff --git a/src/jaegertracing/jaeger-client-cpp/.github/ISSUE_TEMPLATE.md b/src/jaegertracing/jaeger-client-cpp/.github/ISSUE_TEMPLATE.md
new file mode 100644
index 000000000..7a5851ba9
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/.github/ISSUE_TEMPLATE.md
@@ -0,0 +1,28 @@
+<!--
+Welcome to the Jaeger project! 👋🎉
+
+- Please search for existing issues to avoid creating duplicate bugs/feature requests.
+- Please be respectful and considerate of others when commenting on issues.
+- Please provide as much information as possible so we all understand the issue.
+- If you only have a question, you may get a faster response by asking in
+ - our chat room https://gitter.im/jaegertracing/Lobby, or
+ - the forum https://groups.google.com/d/forum/jaeger-tracing
+ (but please don't double post)
+-->
+
+## Requirement - what kind of business use case are you trying to solve?
+
+<!-- required section -->
+
+## Problem - what in Jaeger blocks you from solving the requirement?
+
+<!-- required section -->
+<!-- If possible, describe the impact of the problem. -->
+
+## Proposal - what do you suggest to solve the problem or improve the existing situation?
+
+<!-- It's ok if you don't have one. -->
+
+## Any open questions to address
+
+<!-- Questions that should be answered before proceeding with implementation. -->
diff --git a/src/jaegertracing/jaeger-client-cpp/.github/PULL_REQUEST_TEMPLATE.md b/src/jaegertracing/jaeger-client-cpp/.github/PULL_REQUEST_TEMPLATE.md
new file mode 100644
index 000000000..2564119cc
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/.github/PULL_REQUEST_TEMPLATE.md
@@ -0,0 +1,18 @@
+<!--
+We appreciate your contribution to the Jaeger project! 👋🎉
+
+Before creating a pull request, please make sure:
+- Your PR is solving one problem
+- You have read the guide for contributing
+ - See https://github.com/jaegertracing/jaeger/blob/master/CONTRIBUTING_GUIDELINES.md
+- You signed all your commits (otherwise we won't be able to merge the PR)
+ - See https://github.com/jaegertracing/jaeger/blob/master/CONTRIBUTING_GUIDELINES.md#sign-your-work
+- You added unit tests for the new functionality
+- You mention in the PR description which issue it is addressing, e.g. "Resolves #123"
+-->
+
+## Which problem is this PR solving?
+-
+
+## Short description of the changes
+-
diff --git a/src/jaegertracing/jaeger-client-cpp/.gitignore b/src/jaegertracing/jaeger-client-cpp/.gitignore
new file mode 100644
index 000000000..780302494
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/.gitignore
@@ -0,0 +1,48 @@
+# Build files
+/build
+/crossdock/crossdock
+/crossdock/jaeger-docker-compose.yml
+
+# vim swap files
+*.swo
+*.swp
+
+# Prerequisites
+*.d
+
+# Compiled Object files
+*.slo
+*.lo
+*.o
+*.obj
+
+# Precompiled Headers
+*.gch
+*.pch
+
+# Compiled Dynamic libraries
+*.so
+*.dylib
+*.dll
+
+# Fortran module files
+*.mod
+*.smod
+
+# Compiled Static libraries
+*.lai
+*.la
+*.a
+*.lib
+
+# Executables
+*.exe
+*.out
+*.app
+
+# Log files
+*.log
+
+# CLion folders
+cmake-build-debug
+.idea
diff --git a/src/jaegertracing/jaeger-client-cpp/.gitmodules b/src/jaegertracing/jaeger-client-cpp/.gitmodules
new file mode 100644
index 000000000..295ebcf62
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/.gitmodules
@@ -0,0 +1,3 @@
+[submodule "idl"]
+ path = idl
+ url = https://github.com/uber/jaeger-idl.git
diff --git a/src/jaegertracing/jaeger-client-cpp/.travis.yml b/src/jaegertracing/jaeger-client-cpp/.travis.yml
new file mode 100644
index 000000000..9c380d450
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/.travis.yml
@@ -0,0 +1,88 @@
+language: cpp
+sudo: true
+dist: trusty
+addons:
+ apt:
+ packages: &1
+ - lcov
+matrix:
+ include:
+ - os: linux
+ addons:
+ apt:
+ sources:
+ - ubuntu-toolchain-r-test
+ packages:
+ - *1
+ - g++-4.9
+ env:
+ - MATRIX_EVAL="CC=gcc-4.9 && CXX=g++-4.9 && CMAKE_OPTIONS='-DCMAKE_BUILD_TYPE=Debug
+ -DBUILD_SHARED_LIBS=ON -DJAEGERTRACING_COVERAGE=ON'"
+ - os: linux
+ addons:
+ apt:
+ sources:
+ - ubuntu-toolchain-r-test
+ packages:
+ - *1
+ - g++-5
+ env:
+ - MATRIX_EVAL="CC=gcc-5 && CXX=g++-5 && CMAKE_OPTIONS='-DCMAKE_BUILD_TYPE=Debug
+ -DBUILD_SHARED_LIBS=ON -DJAEGERTRACING_COVERAGE=ON'"
+ - os: linux
+ addons:
+ apt:
+ sources:
+ - ubuntu-toolchain-r-test
+ packages:
+ - *1
+ - g++-6
+ env:
+ - MATRIX_EVAL="CC=gcc-6 && CXX=g++-6 && CMAKE_OPTIONS='-DCMAKE_BUILD_TYPE=Debug
+ -DBUILD_SHARED_LIBS=ON -DJAEGERTRACING_COVERAGE=ON'"
+ - os: linux
+ addons:
+ apt:
+ sources:
+ - ubuntu-toolchain-r-test
+ packages:
+ - *1
+ - g++-7
+ env:
+ - MATRIX_EVAL="CC=gcc-7 && CXX=g++-7 && CMAKE_OPTIONS='-DCMAKE_BUILD_TYPE=Debug
+ -DBUILD_SHARED_LIBS=ON -DJAEGERTRACING_COVERAGE=ON'"
+ - os: linux
+ addons:
+ apt:
+ sources:
+ - ubuntu-toolchain-r-test
+ packages:
+ - *1
+ - g++-7
+ env:
+ - MATRIX_EVAL="CC=gcc-7 && CXX=g++-7 && CMAKE_OPTIONS='-DCMAKE_BUILD_TYPE=Release
+ -DJAEGERTRACING_PLUGIN=ON -DBUILD_TESTING=ON -DHUNTER_CONFIGURATION_TYPES=Release'"
+before_install:
+- eval "${MATRIX_EVAL}"
+- mkdir cmake-download && cd cmake-download && curl -O https://cmake.org/files/v3.10/cmake-3.10.0-rc5-Linux-x86_64.sh
+ && bash cmake-3.10.0-rc5-Linux-x86_64.sh --skip-license && cd ..
+script:
+- CMAKE_OPTIONS="${CMAKE_OPTIONS}" ./scripts/build.sh
+after_success:
+- CMAKE_OPTIONS="${CMAKE_OPTIONS}" ./scripts/upload-coverage.sh
+cache:
+ directories:
+ - "$HOME/.hunter/_Base/Cache"
+env:
+ global:
+ - LANG="en_US.UTF-8"
+ - PATH="$TRAVIS_BUILD_DIR/cmake-download/bin:$PATH"
+deploy:
+ provider: releases
+ api_key:
+ secure: Q2ZlNb0QHRfS+uZ4q9EEsWjv7s1EFqahF8aDLpoO8brSaLtImcMM5G9MHukxjh57NJnM0S9FOU6hJyAnSt8hOjmQH+7oXwvt1Uoqh5gmPXpxhmIcK753JxXeeKID6nxBImTk8JjBRV164k7Oyj401t8WqKYZB+s5PuZq4ND854Ak/kFFsZbMunsy0RX8LxrYTuxc3YBwWfa1oFXJIqxWN/J1YV6hSdCNtWuk2re796leql3vkNEogHUCHvTB/lmM4egcsF21TkpOuRrCww/DYTx4eLCjvwJKtGuLq8FKC8uMLMG5b2JgllpfFbEq5o6imqioKUjTuoS0TE0KzM4WQFgYo7itykgZRD3pvivSK8mJePjTjuDQukQ6i1PkT9wgxdkagPH/mD+JBzx+cAzy3jPgfxWFl29Yj1xsKpbUmeSjxWac87b8d3lEBfBNJ83QkfkC80ZrJufhy30RP47PTHLUNf/udiO722T6w6Zu6wEKFSjfoRqPa0Uj2Src8tonKt7Me9UDoHAJ+go0nIz27xc4haPFgg5NgxSSXDn9fAEiLlj48tQkI6bUl1U+HH1baWHoTrckUi7OpJZYU9zB4QLwhia7OhrVvNWtTIbyVF4+8OIw4uaMsEV3jsR0okREUKSH/yPGiouFvoiggVa3OIGDN+CLQ/7Pocw8msBSQ0U=
+ file: build/libjaegertracing_plugin.so
+ on:
+ repo: jaegertracing/jaeger-client-cpp
+ tags: true
+ skip_cleanup: true
diff --git a/src/jaegertracing/jaeger-client-cpp/.ycm_extra_conf.py b/src/jaegertracing/jaeger-client-cpp/.ycm_extra_conf.py
new file mode 100644
index 000000000..ad3fcc3d7
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/.ycm_extra_conf.py
@@ -0,0 +1,104 @@
+# Copyright (c) 2017-2018 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.
+
+import os
+import ycm_core
+
+
+def DirectoryOfThisScript():
+ return os.path.dirname( os.path.abspath( __file__ ) )
+
+
+project_dir = DirectoryOfThisScript()
+
+try:
+ with open('build/_3rdParty/Hunter/install-root-dir') as f:
+ hunter_install_dir = f.readline()
+except IOError:
+ # Ignore if file does not exist
+ hunter_install_dir = ''
+
+flags = [
+'-Wall',
+'-Werror',
+'-pedantic',
+'-std=c++11',
+'-x',
+'c++',
+'-DBOOST_COROUTINES_NO_DEPRECATION_WARNING=1',
+'-DGTEST_HAS_TR1_TUPLE=0',
+'-DGTEST_USE_OWN_TR1_TUPLE=0',
+'-isystem',
+'/usr/local/include',
+'-I',
+os.path.join(project_dir, 'src'),
+'-I',
+os.path.join(project_dir, 'build/src')
+]
+
+if hunter_install_dir:
+ flags += ['-I', hunter_install_dir]
+
+compilation_database_folder = os.path.join(project_dir, 'build')
+
+if os.path.exists( compilation_database_folder ):
+ database = ycm_core.CompilationDatabase( compilation_database_folder )
+else:
+ database = None
+
+SOURCE_EXTENSIONS = [ '.cpp', '.cxx', '.cc', '.c', '.m', '.mm' ]
+
+
+def IsHeaderFile( filename ):
+ extension = os.path.splitext( filename )[ 1 ]
+ return extension in [ '.h', '.hxx', '.hpp', '.hh' ]
+
+
+def GetCompilationInfoForFile( filename ):
+ # The compilation_commands.json file generated by CMake does not have entries
+ # for header files. So we do our best by asking the db for flags for a
+ # corresponding source file, if any. If one exists, the flags for that file
+ # should be good enough.
+ if IsHeaderFile( filename ):
+ basename = os.path.splitext( filename )[ 0 ]
+ for extension in SOURCE_EXTENSIONS:
+ replacement_file = basename + extension
+ if os.path.exists( replacement_file ):
+ compilation_info = database.GetCompilationInfoForFile(
+ replacement_file )
+ if compilation_info.compiler_flags_:
+ return compilation_info
+ return None
+ return database.GetCompilationInfoForFile( filename )
+
+
+def FlagsForFile( filename, **kwargs ):
+ if not database:
+ return {
+ 'flags': flags,
+ 'include_paths_relative_to_dir': DirectoryOfThisScript()
+ }
+
+ compilation_info = GetCompilationInfoForFile( filename )
+ if not compilation_info:
+ return None
+
+ # Bear in mind that compilation_info.compiler_flags_ does NOT return a
+ # python list, but a "list-like" StringVec object.
+ final_flags = list( compilation_info.compiler_flags_ )
+
+ return {
+ 'flags': final_flags,
+ 'include_paths_relative_to_dir': compilation_info.compiler_working_dir_
+ }
diff --git a/src/jaegertracing/jaeger-client-cpp/CHANGELOG.md b/src/jaegertracing/jaeger-client-cpp/CHANGELOG.md
new file mode 100644
index 000000000..da24edf1b
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/CHANGELOG.md
@@ -0,0 +1,89 @@
+Changes by Version
+==================
+
+0.6.1 (unreleased)
+------------------
+
+- Nothing yet.
+
+
+0.6.0 (2020-06-08)
+------------------
+- Support plugin configuration via environment variables (#192)
+- An extension of enum opentracing::SpanReferenceType, for a new Span. (#206)
+- Update OpenTracing to 1.6.0 (#209)
+- Fix loading of sampling endpoint address from JAEGER_SAMPLING_ENDPOINT environment variable (#200)
+- Fix sampling endpoint URL
+- Fix typo in README.md (#194)
+- Add jaeger-debug-id as a tag (#190)
+- Reuse TMemoryBuffer when calculating size of ThriftType (#185)
+- Support Tracer tags and configuration via environment variables (#181)
+- Add an HTTP Sender (#165) (#171)
+- Remove Thrift headers from Jaeger public headers (#172)
+- Update default samplingServerURL to include /sampling path (#158)
+
+
+0.5.0 (2019-09-07)
+------------------
+- Improve C++ flag handling in CMake (#128)
+- localIP: try resolving local hostname first (#130)
+- Fix deadlock if steady_clock::now() returns the same value twice (#132)
+- Implement SpanContext::Clone (#138)
+- Change sampler param sentinel value from YAML parser (#145)
+- Fix RemoteReporter test race condition (#135)
+- Add details on how to set agent & collector endpoint (#153)
+- Clarify agent/sampler address overrides in README
+- Upgrade to OpenTracing 1.5.0; Support build on Windows (#115)
+- Throw exception on invalid sampling rate (#168)
+
+
+0.4.2 (2018-08-14)
+------------------
+- Fix `tracer.Inject(..., HTTPHeadersWriter&)` (#107)
+- Upgrade dynamic loading API (#120)
+
+
+0.4.1 (2018-05-16)
+------------------
+- Add example application (#101)
+- Improve CMake installation to allow use of lib64 directory (#102)
+- Fix CMake config for OpenTracing dependency (#103)
+- Fix tracer inject for HTTP headers (#107)
+
+
+0.4.0 (2018-05-07)
+------------------
+- Build shared plugin for Linux amd64 using Docker (#82)
+- Fix UDP test compilation error (#88)
+- Fix usage of propagation headers config (#91)
+- Fix dynamic load build error (#92)
+- Use Thrift 0.11.0 (#94)
+
+
+0.3.0 (2018-04-17)
+------------------
+- Use LogRecord in Span::FinishWithOptions (#58)
+- Flush pending spans in RemoteReporter destructor (#59)
+- Add support for dynamic loading (#64)
+- Fix unhandled exception when Jaeger agent unavailable (#80)
+- Fix potential race condition in concurrent baggage access (#83)
+
+
+0.2.0 (2018-01-25)
+------------------
+- Fix bug in localIP and revert change in TR1 tuple definition (#31)
+- Add language prefix to Jaeger client version tag (#35)
+- Fix yaml-cpp issues (#39)
+
+
+0.1.0 (2017-11-29)
+------------------
+- Don't use forwarding reference (#11)
+- Fix overflow bug (#13)
+- Set default-constructed timestamp to current time in StartSpan (#18)
+
+
+0.0.8 (2017-11-20)
+------------------
+- Fix host IP formatting and improve local IP API (#4)
+- Use JSON instead of Thrift's TJSONProtocol (#12)
diff --git a/src/jaegertracing/jaeger-client-cpp/CMakeLists.txt b/src/jaegertracing/jaeger-client-cpp/CMakeLists.txt
new file mode 100644
index 000000000..42bb7a42a
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/CMakeLists.txt
@@ -0,0 +1,496 @@
+cmake_minimum_required(VERSION 3.3)
+
+list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
+
+set(CMAKE_TOOLCHAIN_FILE "${CMAKE_CURRENT_SOURCE_DIR}/cmake/toolchain.cmake"
+ CACHE FILEPATH
+ "Toolchain to use for building this package and dependencies")
+
+set(HUNTER_CONFIGURATION_TYPES "Release;Debug" CACHE STRING
+ "Configuration types used when building Hunter dependencies")
+
+include(CMakeDependentOption)
+include(HunterGate)
+
+option(HUNTER_BUILD_SHARED_LIBS "Build Shared Library" ON)
+
+HunterGate(
+ URL "https://github.com/cpp-pm/hunter/archive/v0.23.249.tar.gz"
+ SHA1 "d45d77d8bba9da13e9290a180e0477e90accd89b"
+ LOCAL # load `${CMAKE_CURRENT_LIST_DIR}/cmake/Hunter/config.cmake`
+)
+
+project(jaegertracing VERSION 0.6.1)
+
+option(JAEGERTRACING_WARNINGS_AS_ERRORS "Treat compiler warnings as errors" OFF)
+
+if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU" OR
+ CMAKE_CXX_COMPILER_ID MATCHES "Clang")
+ set(cxx_flags -Wall -pedantic)
+ if(JAEGERTRACING_WARNINGS_AS_ERRORS)
+ list(APPEND cxx_flags -Werror)
+ endif()
+endif()
+
+if(CMAKE_CXX_COMPILER_ID MATCHES "Clang")
+ list(APPEND cxx_flags -Wno-unused-private-field)
+endif()
+
+find_package( Threads )
+list(APPEND link_flags ${CMAKE_THREAD_LIBS_INIT})
+
+if(MSVC)
+ add_definitions(-D_SILENCE_CXX17_ITERATOR_BASE_CLASS_DEPRECATION_WARNING)
+
+ # https://studiofreya.com/2018/01/06/visual-studio-2017-with-cpp17-and-boost/
+ add_definitions(-DBOOST_CONFIG_SUPPRESS_OUTDATED_MESSAGE)
+ add_definitions(-D_SCL_SECURE_NO_WARNINGS)
+endif()
+
+set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
+
+if(HUNTER_ENABLED)
+ set(hunter_config "CONFIG")
+else()
+ set(hunter_config "")
+endif()
+
+set(package_deps)
+
+if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU" AND
+ CMAKE_CXX_COMPILER_VERSION VERSION_LESS "4.9")
+ message(FATAL_ERROR "Must use gcc >= 4.9")
+endif()
+
+find_package(Boost 1.70 REQUIRED)
+include_directories(${Boost_INCLUDE_DIRS})
+
+hunter_add_package(thrift)
+find_package(thrift ${hunter_config} REQUIRED)
+if(HUNTER_ENABLED)
+ list(APPEND LIBS thrift::thrift_static)
+else()
+ list(APPEND LIBS ${thrift_LIBRARIES})
+ include_directories(${thrift_INCLUDE_DIR})
+endif()
+list(APPEND package_deps thrift)
+
+
+hunter_add_package(opentracing-cpp)
+# Not `${hunter_config}` because OpenTracing provides its own
+# OpenTracingConfig.cmake file
+find_package(OpenTracing 1.6.0 REQUIRED)
+# Under Windows, link dynamically with OpenTracing
+if (WIN32)
+ list(APPEND LIBS OpenTracing::opentracing)
+ set(OPENTRACING_LIB OpenTracing::opentracing)
+else()
+ list(APPEND LIBS OpenTracing::opentracing-static)
+ set(OPENTRACING_LIB OpenTracing::opentracing-static)
+endif()
+list(APPEND package_deps OpenTracing)
+
+hunter_add_package(nlohmann_json)
+find_package(nlohmann_json 2.1.0 ${hunter_config} REQUIRED)
+include_directories(${nlohmann_json_INCLUDE_DIR})
+list(APPEND package_deps nlohmann_json)
+
+option(JAEGERTRACING_BUILD_EXAMPLES "Build examples" ON)
+
+option(JAEGERTRACING_COVERAGE "Build with coverage" $ENV{COVERAGE})
+option(JAEGERTRACING_BUILD_CROSSDOCK "Build crossdock" $ENV{CROSSDOCK})
+cmake_dependent_option(
+ JAEGERTRACING_WITH_YAML_CPP "Use yaml-cpp to parse config files" ON
+ "NOT JAEGERTRACING_BUILD_CROSSDOCK" ON)
+
+if(JAEGERTRACING_WITH_YAML_CPP)
+ hunter_add_package(yaml-cpp)
+ # Not `${hunter_config}` because yaml-cpp provides its own
+ # yaml-cpp-config.cmake file
+ find_package(yaml-cpp CONFIG REQUIRED)
+ if(HUNTER_ENABLED)
+ list(APPEND LIBS yaml-cpp::yaml-cpp)
+ else()
+ list(APPEND LIBS yaml-cpp)
+ endif()
+ list(APPEND package_deps yaml-cpp)
+endif()
+
+include(CTest)
+if(BUILD_TESTING)
+ hunter_add_package(GTest)
+ find_package(GTest ${hunter_config} REQUIRED)
+
+ if(JAEGERTRACING_COVERAGE)
+ include(CodeCoverage)
+ append_coverage_compiler_flags(cxx_flags)
+ append_coverage_compiler_flags(link_flags)
+ set(COVERAGE_EXCLUDES "${CMAKE_CURRENT_SOURCE_DIR}/src/jaegertracing/thrift-gen/*"
+ "*Test.cpp")
+ endif()
+endif()
+
+set(SRC
+ src/jaegertracing/Config.cpp
+ src/jaegertracing/DynamicLoad.cpp
+ src/jaegertracing/LogRecord.cpp
+ src/jaegertracing/Logging.cpp
+ src/jaegertracing/Reference.cpp
+ src/jaegertracing/Span.cpp
+ src/jaegertracing/SpanContext.cpp
+ src/jaegertracing/Tag.cpp
+ src/jaegertracing/TraceID.cpp
+ src/jaegertracing/Tracer.cpp
+ src/jaegertracing/TracerFactory.cpp
+ src/jaegertracing/Sender.cpp
+ src/jaegertracing/ThriftSender.cpp
+ src/jaegertracing/baggage/BaggageSetter.cpp
+ src/jaegertracing/baggage/RemoteRestrictionJSON.cpp
+ src/jaegertracing/baggage/RemoteRestrictionManager.cpp
+ src/jaegertracing/baggage/Restriction.cpp
+ src/jaegertracing/baggage/RestrictionManager.cpp
+ src/jaegertracing/baggage/RestrictionsConfig.cpp
+ src/jaegertracing/metrics/Counter.cpp
+ src/jaegertracing/metrics/Gauge.cpp
+ src/jaegertracing/metrics/InMemoryStatsReporter.cpp
+ src/jaegertracing/metrics/Metric.cpp
+ src/jaegertracing/metrics/Metrics.cpp
+ src/jaegertracing/metrics/NullCounter.cpp
+ src/jaegertracing/metrics/NullGauge.cpp
+ src/jaegertracing/metrics/NullStatsFactory.cpp
+ src/jaegertracing/metrics/NullStatsReporter.cpp
+ src/jaegertracing/metrics/NullTimer.cpp
+ src/jaegertracing/metrics/StatsFactory.cpp
+ src/jaegertracing/metrics/StatsFactoryImpl.cpp
+ src/jaegertracing/metrics/StatsReporter.cpp
+ src/jaegertracing/metrics/Timer.cpp
+ src/jaegertracing/net/IPAddress.cpp
+ src/jaegertracing/net/Socket.cpp
+ src/jaegertracing/net/URI.cpp
+ src/jaegertracing/net/http/Error.cpp
+ src/jaegertracing/net/http/Header.cpp
+ src/jaegertracing/net/http/Method.cpp
+ src/jaegertracing/net/http/Request.cpp
+ src/jaegertracing/net/http/Response.cpp
+ src/jaegertracing/platform/Endian.cpp
+ src/jaegertracing/platform/Hostname.cpp
+ src/jaegertracing/propagation/Extractor.cpp
+ src/jaegertracing/propagation/HeadersConfig.cpp
+ src/jaegertracing/propagation/Injector.cpp
+ src/jaegertracing/propagation/Propagator.cpp
+ src/jaegertracing/reporters/CompositeReporter.cpp
+ src/jaegertracing/reporters/Config.cpp
+ src/jaegertracing/reporters/InMemoryReporter.cpp
+ src/jaegertracing/reporters/LoggingReporter.cpp
+ src/jaegertracing/reporters/NullReporter.cpp
+ src/jaegertracing/reporters/RemoteReporter.cpp
+ src/jaegertracing/reporters/Reporter.cpp
+ src/jaegertracing/samplers/AdaptiveSampler.cpp
+ src/jaegertracing/samplers/Config.cpp
+ src/jaegertracing/samplers/ConstSampler.cpp
+ src/jaegertracing/samplers/GuaranteedThroughputProbabilisticSampler.cpp
+ src/jaegertracing/samplers/ProbabilisticSampler.cpp
+ src/jaegertracing/samplers/RateLimitingSampler.cpp
+ src/jaegertracing/samplers/RemoteSamplingJSON.cpp
+ src/jaegertracing/samplers/RemotelyControlledSampler.cpp
+ src/jaegertracing/samplers/Sampler.cpp
+ src/jaegertracing/samplers/SamplingStatus.cpp
+ src/jaegertracing/thrift-gen/Agent.cpp
+ src/jaegertracing/thrift-gen/AggregationValidator.cpp
+ src/jaegertracing/thrift-gen/BaggageRestrictionManager.cpp
+ src/jaegertracing/thrift-gen/Collector.cpp
+ src/jaegertracing/thrift-gen/Dependency.cpp
+ src/jaegertracing/thrift-gen/SamplingManager.cpp
+ src/jaegertracing/thrift-gen/ZipkinCollector.cpp
+ src/jaegertracing/thrift-gen/agent_constants.cpp
+ src/jaegertracing/thrift-gen/agent_types.cpp
+ src/jaegertracing/thrift-gen/aggregation_validator_constants.cpp
+ src/jaegertracing/thrift-gen/aggregation_validator_types.cpp
+ src/jaegertracing/thrift-gen/baggage_constants.cpp
+ src/jaegertracing/thrift-gen/baggage_types.cpp
+ src/jaegertracing/thrift-gen/dependency_constants.cpp
+ src/jaegertracing/thrift-gen/dependency_types.cpp
+ src/jaegertracing/thrift-gen/jaeger_constants.cpp
+ src/jaegertracing/thrift-gen/jaeger_types.cpp
+ src/jaegertracing/thrift-gen/sampling_constants.cpp
+ src/jaegertracing/thrift-gen/sampling_types.cpp
+ src/jaegertracing/thrift-gen/zipkincore_constants.cpp
+ src/jaegertracing/thrift-gen/zipkincore_types.cpp
+ src/jaegertracing/utils/ErrorUtil.cpp
+ src/jaegertracing/utils/HexParsing.cpp
+ src/jaegertracing/utils/EnvVariable.cpp
+ src/jaegertracing/utils/RateLimiter.cpp
+ src/jaegertracing/utils/UDPTransporter.cpp
+ src/jaegertracing/utils/HTTPTransporter.cpp
+ src/jaegertracing/utils/YAML.cpp
+ src/jaegertracing/ThriftMethods.cpp)
+
+if(JAEGERTRACING_BUILD_CROSSDOCK)
+ list(APPEND SRC
+ src/jaegertracing/thrift-gen/TracedService.cpp
+ src/jaegertracing/thrift-gen/tracetest_constants.cpp
+ src/jaegertracing/thrift-gen/tracetest_types.cpp)
+endif()
+
+function(add_lib_deps lib)
+ target_include_directories(${lib} PUBLIC
+ $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/src>
+ $<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}/src>)
+ target_link_libraries(${lib} PUBLIC ${link_flags} ${LIBS})
+ target_compile_options(${lib} PUBLIC ${cxx_flags})
+endfunction()
+
+function(update_path_for_test atest)
+ if(WIN32)
+ # If dependent library is a DLL we have to add location of DLL to PATH
+ set(new_path "")
+
+ foreach(LIB OpenTracing::opentracing yaml-cpp::yaml-cpp GTest::main)
+ list(APPEND new_path $<TARGET_FILE_DIR:${LIB}>)
+ endforeach()
+ list(APPEND new_path $ENV{PATH})
+ string(REPLACE ";" "\\;" new_path "${new_path}")
+
+ set_tests_properties(${atest} PROPERTIES ENVIRONMENT "PATH=${new_path}")
+ endif()
+endfunction()
+
+option(JAEGERTRACING_PLUGIN "Build dynamic plugin" OFF)
+cmake_dependent_option(BUILD_SHARED_LIBS "Build shared libraries" ON
+ "NOT JAEGERTRACING_PLUGIN" OFF)
+
+if(BUILD_SHARED_LIBS)
+ add_library(jaegertracing SHARED ${SRC})
+ if (WIN32)
+ target_compile_definitions(jaegertracing PUBLIC YAML_CPP_DLL)
+ target_link_libraries(jaegertracing PUBLIC Iphlpapi Ws2_32)
+ endif()
+ add_lib_deps(jaegertracing)
+ set_target_properties(jaegertracing PROPERTIES
+ VERSION ${PROJECT_VERSION}
+ SOVERSION ${PROJECT_VERSION_MAJOR})
+ set(JAEGERTRACING_LIB jaegertracing)
+ list(APPEND JAEGERTRACING_LIBS jaegertracing)
+endif()
+
+
+if(JAEGERTRACING_PLUGIN)
+ file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/export.map
+ "{ global: OpenTracingMakeTracerFactory; local: *; };")
+ add_library(jaegertracing_plugin MODULE ${SRC})
+ add_lib_deps(jaegertracing_plugin)
+ target_link_libraries(jaegertracing_plugin PUBLIC
+ -static-libgcc
+ -static-libstdc++
+ -Wl,--version-script=${CMAKE_CURRENT_BINARY_DIR}/export.map)
+endif()
+
+add_library(jaegertracing-static STATIC ${SRC})
+if (NOT WIN32)
+ #on windows, the shared library generate also a .lib file
+ set_target_properties(jaegertracing-static PROPERTIES OUTPUT_NAME jaegertracing)
+endif()
+
+add_lib_deps(jaegertracing-static)
+if (WIN32)
+ target_link_libraries(jaegertracing-static PUBLIC Iphlpapi Ws2_32)
+endif()
+
+if(NOT JAEGERTRACING_LIB)
+ set(JAEGERTRACING_LIB jaegertracing-static)
+endif()
+list(APPEND JAEGERTRACING_LIBS jaegertracing-static)
+
+configure_file(
+ src/jaegertracing/Constants.h.in
+ src/jaegertracing/Constants.h
+ @ONLY)
+
+if(JAEGERTRACING_BUILD_EXAMPLES)
+ add_executable(app examples/App.cpp)
+ target_link_libraries(app PUBLIC ${JAEGERTRACING_LIB})
+endif()
+
+if(BUILD_TESTING)
+ add_library(testutils
+ src/jaegertracing/testutils/TUDPTransport.cpp
+ src/jaegertracing/testutils/SamplingManager.cpp
+ src/jaegertracing/testutils/MockAgent.cpp
+ src/jaegertracing/testutils/TracerUtil.cpp)
+ target_link_libraries(testutils PUBLIC ${JAEGERTRACING_LIB})
+
+ add_executable(UnitTest
+ src/jaegertracing/ConfigTest.cpp
+ src/jaegertracing/ReferenceTest.cpp
+ src/jaegertracing/SpanContextTest.cpp
+ src/jaegertracing/SpanTest.cpp
+ src/jaegertracing/TagTest.cpp
+ src/jaegertracing/TraceIDTest.cpp
+ src/jaegertracing/TracerFactoryTest.cpp
+ src/jaegertracing/TracerTest.cpp
+ src/jaegertracing/ThriftSenderTest.cpp
+ src/jaegertracing/baggage/BaggageTest.cpp
+ src/jaegertracing/metrics/MetricsTest.cpp
+ src/jaegertracing/metrics/NullStatsFactoryTest.cpp
+ src/jaegertracing/net/IPAddressTest.cpp
+ src/jaegertracing/net/SocketTest.cpp
+ src/jaegertracing/net/URITest.cpp
+ src/jaegertracing/net/http/HeaderTest.cpp
+ src/jaegertracing/net/http/MethodTest.cpp
+ src/jaegertracing/net/http/ResponseTest.cpp
+ src/jaegertracing/propagation/PropagatorTest.cpp
+ src/jaegertracing/reporters/ConfigTest.cpp
+ src/jaegertracing/reporters/ReporterTest.cpp
+ src/jaegertracing/samplers/SamplerTest.cpp
+ src/jaegertracing/testutils/MockAgentTest.cpp
+ src/jaegertracing/testutils/TUDPTransportTest.cpp
+ src/jaegertracing/utils/ErrorUtilTest.cpp
+ src/jaegertracing/utils/RateLimiterTest.cpp
+ src/jaegertracing/utils/UDPSenderTest.cpp
+ src/jaegertracing/utils/HTTPTransporterTest.cpp)
+ target_link_libraries(
+ UnitTest PRIVATE testutils PUBLIC GTest::main ${JAEGERTRACING_LIB})
+ add_test(NAME UnitTest COMMAND UnitTest)
+
+ update_path_for_test(UnitTest)
+
+ if(TARGET jaegertracing)
+ add_executable(DynamicallyLoadTracerTest
+ src/jaegertracing/DynamicallyLoadTracerTest.cpp)
+
+ target_include_directories(DynamicallyLoadTracerTest PUBLIC
+ $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/src>
+ $<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}/src>)
+ target_link_libraries(
+ DynamicallyLoadTracerTest ${OPENTRACING_LIB} GTest::main)
+ add_test(NAME DynamicallyLoadTracerTest
+ COMMAND DynamicallyLoadTracerTest $<TARGET_FILE:jaegertracing>)
+ update_path_for_test(DynamicallyLoadTracerTest)
+ if(JAEGERTRACING_COVERAGE)
+ setup_target_for_coverage(NAME UnitTestCoverage
+ EXECUTABLE UnitTest
+ DEPENDENCIES UnitTest)
+ endif()
+ endif()
+endif()
+
+
+
+if(JAEGERTRACING_BUILD_CROSSDOCK)
+ set(CROSSDOCK_SRC crossdock/Server.cpp)
+ add_executable(crossdock ${CROSSDOCK_SRC})
+ target_include_directories(crossdock PUBLIC
+ $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/crossdock>)
+ target_link_libraries(crossdock PUBLIC ${JAEGERTRACING_LIB})
+
+ string(CONCAT JAEGER_CROSSDOCK_URL
+ "https://raw.githubusercontent.com/"
+ "jaegertracing/jaeger/master/docker-compose/jaeger-docker-compose.yml")
+ file(DOWNLOAD ${JAEGER_CROSSDOCK_URL}
+ "${CMAKE_CURRENT_SOURCE_DIR}/crossdock/jaeger-docker-compose.yml")
+ find_program(DOCKER_COMPOSE_EXE docker-compose REQUIRED)
+ set(DOCKER_COMPOSE_CMD ${DOCKER_COMPOSE_EXE}
+ -f ${CMAKE_CURRENT_SOURCE_DIR}/crossdock/docker-compose.yml
+ -f ${CMAKE_CURRENT_SOURCE_DIR}/crossdock/jaeger-docker-compose.yml)
+ add_custom_target(crossdock-kill
+ COMMAND ${DOCKER_COMPOSE_CMD} down)
+ add_custom_target(crossdock-run
+ COMMAND ${DOCKER_COMPOSE_CMD} build
+ COMMAND ${DOCKER_COMPOSE_CMD} run crossdock
+ DEPENDS crossdock-kill
+ WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})
+ add_custom_target(crossdock-fresh
+ COMMAND ${DOCKER_COMPOSE_CMD} build --pull --no-cache
+ COMMAND ${DOCKER_COMPOSE_CMD} run crossdock
+ DEPENDS crossdock-kill
+ WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})
+ add_custom_target(crossdock-logs
+ COMMAND ${DOCKER_COMPOSE_CMD} logs)
+endif()
+
+
+
+# Installation (https://github.com/forexample/package-example)
+
+# Introduce variables:
+# * CMAKE_INSTALL_LIBDIR
+# * CMAKE_INSTALL_BINDIR
+# * CMAKE_INSTALL_INCLUDEDIR
+include(GNUInstallDirs)
+
+# Layout. This works for all platforms:
+# * <prefix>/lib*/cmake/<PROJECT-NAME>
+# * <prefix>/lib*/
+# * <prefix>/include/
+set(config_install_dir "${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}")
+
+set(generated_dir "${CMAKE_CURRENT_BINARY_DIR}/generated")
+
+# Configuration
+set(version_config "${generated_dir}/${PROJECT_NAME}ConfigVersion.cmake")
+set(project_config "${generated_dir}/${PROJECT_NAME}Config.cmake")
+set(TARGETS_EXPORT_NAME "${PROJECT_NAME}Targets")
+set(namespace "${PROJECT_NAME}::")
+
+# Include module with fuction 'write_basic_package_version_file'
+include(CMakePackageConfigHelpers)
+
+# Configure '<PROJECT-NAME>ConfigVersion.cmake'
+# Use:
+# * PROJECT_VERSION
+write_basic_package_version_file(
+ "${version_config}" COMPATIBILITY SameMajorVersion
+)
+
+# Configure '<PROJECT-NAME>Config.cmake'
+# Use variables:
+# * TARGETS_EXPORT_NAME
+# * PROJECT_NAME
+configure_package_config_file(
+ "cmake/Config.cmake.in"
+ "${project_config}"
+ INSTALL_DESTINATION "${config_install_dir}"
+)
+
+# Targets:
+# * <prefix>/lib*/libjaegertracing.a
+# * <prefix>/lib*/libjaegertracing.so
+# * header location after install: <prefix>/include/jaegertracing/Tracer.h
+# * headers can be included by C++ code `#include <jaegertracing/Tracer.h>`
+install(
+ TARGETS ${JAEGERTRACING_LIBS}
+ EXPORT "${TARGETS_EXPORT_NAME}"
+ LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}"
+ ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}"
+ RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}"
+ INCLUDES DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}"
+)
+
+# Headers:
+# * src/jaegertracing/Tracer.h -> <prefix>/include/jaegertracing/Tracer.h
+install(DIRECTORY "src/jaegertracing"
+ DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}"
+ FILES_MATCHING
+ PATTERN "*.h"
+ PATTERN "testutils/*.h" EXCLUDE)
+
+# * build/src/jaegertracing/Constants.h ->
+# <prefix>/include/jaegertracing/Constants.h
+install(FILES "${CMAKE_CURRENT_BINARY_DIR}/src/jaegertracing/Constants.h"
+ DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/jaegertracing")
+
+# Config
+# * <prefix>/lib*/cmake/jaegertracing/jaegertracingConfig.cmake
+# * <prefix>/lib*/cmake/jaegertracing/jaegertracingConfigVersion.cmake
+install(
+ FILES "${project_config}" "${version_config}"
+ DESTINATION "${config_install_dir}"
+)
+
+# Config
+# * <prefix>/lib*/cmake/jaegertracing/jaegertracingTargets.cmake
+install(
+ EXPORT "${TARGETS_EXPORT_NAME}"
+ NAMESPACE "${namespace}"
+ DESTINATION "${config_install_dir}"
+)
diff --git a/src/jaegertracing/jaeger-client-cpp/CONTRIBUTING.md b/src/jaegertracing/jaeger-client-cpp/CONTRIBUTING.md
new file mode 100644
index 000000000..11d07c887
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/CONTRIBUTING.md
@@ -0,0 +1,117 @@
+# How to Contribute to Jaeger
+
+We'd love your help!
+
+Jaeger is [Apache 2.0 licensed](LICENSE) and accepts contributions via GitHub
+pull requests. This document outlines some of the conventions on development
+workflow, commit message formatting, contact points and other resources to make
+it easier to get your contribution accepted.
+
+We gratefully welcome improvements to documentation as well as to code.
+
+## Making A Change
+
+*Before making any significant changes, please [open an issue](https://github.com/jaegertracing/jaeger-client-cpp/issues).*
+Discussing your proposed changes ahead of time will make the contribution process smooth for everyone.
+
+Once we've discussed your changes and you've got your code ready, make sure
+that tests are passing and open your pull request. Your pull request is most likely to be accepted if it:
+
+* Includes tests for new functionality.
+* Follows the code style guidelines.
+* Has a [good commit message](https://chris.beams.io/posts/git-commit/):
+ * Separate subject from body with a blank line
+ * Limit the subject line to 50 characters
+ * Capitalize the subject line
+ * Do not end the subject line with a period
+ * Use the imperative mood in the subject line
+ * Wrap the body at 72 characters
+ * Use the body to explain _what_ and _why_ instead of _how_
+* Each commit is signed by the author ([see below](#sign-your-work)).
+
+## License and Certificate of Origin
+
+By contributing to this project you agree to license your contribution under the terms
+of the [Apache License](LICENSE), and you agree to the [Developer Certificate of
+Origin](https://developercertificate.org/) (DCO). This document was created
+by the Linux Kernel community and is a simple statement that you, as a
+contributor, have the legal right to make the contribution. See the [DCO](DCO)
+file for details.
+
+```
+/*
+ * Copyright (c) 2018, The Jaeger Authors
+ *
+ * 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.
+ */
+```
+
+## Sign your work
+
+The sign-off is a simple line at the end of the explanation for the
+patch, which certifies that you wrote it or otherwise have the right to
+pass it on as an open-source patch. The rules are pretty simple: if you
+can certify the below (from
+[developercertificate.org](http://developercertificate.org/)):
+
+```
+Developer Certificate of Origin
+Version 1.1
+
+Copyright (C) 2004, 2006 The Linux Foundation and its contributors.
+660 York Street, Suite 102,
+San Francisco, CA 94110 USA
+
+Everyone is permitted to copy and distribute verbatim copies of this
+license document, but changing it is not allowed.
+
+
+Developer's Certificate of Origin 1.1
+
+By making a contribution to this project, I certify that:
+
+(a) The contribution was created in whole or in part by me and I
+ have the right to submit it under the open source license
+ indicated in the file; or
+
+(b) The contribution is based upon previous work that, to the best
+ of my knowledge, is covered under an appropriate open source
+ license and I have the right under that license to submit that
+ work with modifications, whether created in whole or in part
+ by me, under the same open source license (unless I am
+ permitted to submit under a different license), as indicated
+ in the file; or
+
+(c) The contribution was provided directly to me by some other
+ person who certified (a), (b) or (c) and I have not modified
+ it.
+
+(d) I understand and agree that this project and the contribution
+ are public and that a record of the contribution (including all
+ personal information I submit with it, including my sign-off) is
+ maintained indefinitely and may be redistributed consistent with
+ this project or the open source license(s) involved.
+```
+
+then you just add a line to every git commit message:
+
+ Signed-off-by: Joe Smith <joe@gmail.com>
+
+using your real name (sorry, no pseudonyms or anonymous contributions.)
+
+You can add the sign off when creating the git commit via `git commit -s`.
+
+If you want this to be automatic you can set up some aliases:
+
+```
+git config --add alias.amend "commit -s --amend"
+git config --add alias.c "commit -s"
+```
diff --git a/src/jaegertracing/jaeger-client-cpp/Dockerfile.plugin b/src/jaegertracing/jaeger-client-cpp/Dockerfile.plugin
new file mode 100644
index 000000000..996810ed8
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/Dockerfile.plugin
@@ -0,0 +1,9 @@
+FROM debian
+RUN apt-get update
+RUN apt-get install --yes build-essential curl git
+RUN curl -L -O "https://cmake.org/files/v3.11/cmake-3.11.0-Linux-x86_64.sh" && \
+ bash cmake-3.11.0-Linux-x86_64.sh --skip-license
+
+ADD . /src/jaeger-cpp-client
+WORKDIR /src/jaeger-cpp-client
+RUN ./scripts/build-plugin.sh
diff --git a/src/jaegertracing/jaeger-client-cpp/LICENSE b/src/jaegertracing/jaeger-client-cpp/LICENSE
new file mode 100644
index 000000000..8dada3eda
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/LICENSE
@@ -0,0 +1,201 @@
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "{}"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright {yyyy} {name of copyright owner}
+
+ 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.
diff --git a/src/jaegertracing/jaeger-client-cpp/README.md b/src/jaegertracing/jaeger-client-cpp/README.md
new file mode 100644
index 000000000..566fd2481
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/README.md
@@ -0,0 +1,135 @@
+[![Build Status][ci-img]][ci] [![Coverage Status][cov-img]][cov] [![Appveyor Build][appveyor]][appveyor] [![OpenTracing 1.0 Enabled][ot-img]][ot-url]
+
+# jaeger-client-cpp
+[Jaeger](https://www.jaegertracing.io/) SDK with [OpenTracing API for C++](https://github.com/opentracing/opentracing-cpp) binding.
+
+## Contributing
+
+Please see [CONTRIBUTING.md](CONTRIBUTING.md).
+
+## Building
+
+jaeger-client-cpp is built using CMake. It will automatically download
+needed dependencies using [Hunter](https://docs.hunter.sh/en/latest/).
+
+To build:
+
+```bash
+ mkdir build
+ cd build
+ cmake ..
+ make
+```
+
+After building, the [example](./examples/App.cpp) program can be run
+with:
+
+```bash
+ ./app ../examples/config.yml
+```
+
+To run tests:
+
+```bash
+ make test
+```
+
+To install the library:
+
+```bash
+ make install
+```
+
+### Generated files
+
+This project uses Apache Thrift for wire-format protocol support code
+generation. It currently requires Thrift 0.11.0.
+
+The code can be re-generated with
+
+```bash
+ $ git submodule update --init
+ $ find idl/thrift/ -type f -name \*.thrift -exec thrift -gen cpp -out src/jaegertracing/thrift-gen {} \;
+ $ git apply scripts/thrift-gen.patch
+```
+
+### Updating Agent Host and Port
+
+The default host and port for Jaeger Agent is `127.0.0.1:6831`. When the application and Jaeger Agent are running in different containers on the same host, the application's notion of `localhost`/127.0.0.1 it restriced to its own container, so in this case it's usually necessary to override the Agent's host/port by updating your reporter configuration:
+
+YAML configuration:
+
+```yml
+reporter:
+ localAgentHostPort: jaeger-agent:6831
+```
+
+NOTE: It is not recommended to use a remote host for UDP connections.
+
+### Connecting directly to the Collector
+
+In case the client should connect directly to the collector instead of going through an agent, it's necessary update the reporter configuration
+
+```yml
+reporter:
+ endpoint: http://${collectorhost}:${collectorport}/api/traces
+```
+
+Note that if both `localAgentHostPort` and `endpoint` are specified, the `endpoint` will be used.
+
+### Updating Sampling Server URL
+
+The default sampling collector URL is `http://127.0.0.1:5778/sampling`. Similar to UDP address above, you can use a different URL by updating the sampler configuration.
+
+```yml
+sampler:
+ samplingServerURL: http://jaeger-agent.local:5778/sampling
+```
+
+### Configuration via Environment
+
+It's possible to populate the tracer configuration from the environement variables by calling `jaegertracing::Config::fromEnv`.
+
+The following property names are currently available:
+
+Property | Description
+--- | ---
+JAEGER_SERVICE_NAME | The service name
+JAEGER_DISABLED _(not recommended)_ | Instructs the Configuration to return a no-op tracer
+JAEGER_AGENT_HOST | The hostname for communicating with agent via UDP
+JAEGER_AGENT_PORT | The port for communicating with agent via UDP
+JAEGER_ENDPOINT | The traces endpoint, in case the client should connect directly to the Collector, like http://jaeger-collector:14268/api/traces
+JAEGER_REPORTER_LOG_SPANS | Whether the reporter should also log the spans
+JAEGER_REPORTER_MAX_QUEUE_SIZE | The reporter's maximum queue size
+JAEGER_REPORTER_FLUSH_INTERVAL | The reporter's flush interval (ms)
+JAEGER_SAMPLER_TYPE | The [sampler type](https://www.jaegertracing.io/docs/latest/sampling/#client-sampling-configuration)
+JAEGER_SAMPLER_PARAM | The sampler parameter (double)
+JAEGER_SAMPLING_ENDPOINT | The url for the remote sampling conf when using sampler type remote. Default is http://127.0.0.1:5778/sampling
+JAEGER_TAGS | A comma separated list of `name = value` tracer level tags, which get added to all reported spans. The value can also refer to an environment variable using the format `${envVarName:default}`, where the `:default` is optional, and identifies a value to be used if the environment variable cannot be found
+
+### SelfRef
+Jaeger Tracer supports an additional reference type call 'SelfRef'.
+It 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.
+
+Usage example:
+```
+ jaegertracing::SpanContext customCtx { {1, 2}, 3, 0, 0, jaegertracing::SpanContext::StrMap() }; // TraceId and SpanID must be != 0
+ auto span = tracer->StartSpan("spanName", { jaegertracing::SelfRef(&customCtx) });
+```
+
+## License
+
+[Apache 2.0 License](./LICENSE).
+
+[ci-img]: https://travis-ci.org/jaegertracing/jaeger-client-cpp.svg?branch=master
+[ci]: https://travis-ci.org/jaegertracing/jaeger-client-cpp
+[appveyor]: https://ci.appveyor.com/api/projects/status/bu992qd3y9bpwe7u?svg=true
+[cov-img]: https://codecov.io/gh/jaegertracing/jaeger-client-cpp/branch/master/graph/badge.svg
+[cov]: https://codecov.io/gh/jaegertracing/jaeger-client-cpp
+[ot-img]: https://img.shields.io/badge/OpenTracing--1.0-enabled-blue.svg
+[ot-url]: http://opentracing.io
diff --git a/src/jaegertracing/jaeger-client-cpp/RELEASE.md b/src/jaegertracing/jaeger-client-cpp/RELEASE.md
new file mode 100644
index 000000000..9cd2d1231
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/RELEASE.md
@@ -0,0 +1,10 @@
+# Release Process
+
+1. Create a PR "Preparing for release X.Y.Z" against master branch
+ * Alter CHANGELOG.md from `<placeholder_version> (unreleased)` to `<X.Y.Z> (YYYY-MM-DD)`
+2. Create a release "Release X.Y.Z" on Github
+ * Create Tag `vX.Y.Z`
+ * Copy CHANGELOG.md into the release notes
+3. Create a PR "Back to development" against master branch
+ * Add `<next_version> (unreleased)` to CHANGELOG.md
+ * Update project version in CMakeLists.txt to the `<next version>`
diff --git a/src/jaegertracing/jaeger-client-cpp/cmake/CodeCoverage.cmake b/src/jaegertracing/jaeger-client-cpp/cmake/CodeCoverage.cmake
new file mode 100644
index 000000000..85261fc36
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/cmake/CodeCoverage.cmake
@@ -0,0 +1,180 @@
+# Copyright (c) 2012 - 2017, Lars Bilke
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without modification,
+# are permitted provided that the following conditions are met:
+#
+# 1. Redistributions of source code must retain the above copyright notice, this
+# list of conditions and the following disclaimer.
+#
+# 2. Redistributions in binary form must reproduce the above copyright notice,
+# this list of conditions and the following disclaimer in the documentation
+# and/or other materials provided with the distribution.
+#
+# 3. Neither the name of the copyright holder nor the names of its contributors
+# may be used to endorse or promote products derived from this software without
+# specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
+# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+# ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+# CHANGES:
+#
+# 2012-01-31, Lars Bilke
+# - Enable Code Coverage
+#
+# 2013-09-17, Joakim Söderberg
+# - Added support for Clang.
+# - Some additional usage instructions.
+#
+# 2016-02-03, Lars Bilke
+# - Refactored functions to use named parameters
+#
+# 2017-06-02, Lars Bilke
+# - Merged with modified version from github.com/ufz/ogs
+#
+#
+# USAGE:
+#
+# 1. Copy this file into your cmake modules path.
+#
+# 2. Add the following line to your CMakeLists.txt:
+# include(CodeCoverage)
+#
+# 3. Append necessary compiler flags:
+# APPEND_COVERAGE_COMPILER_FLAGS()
+#
+# 4. If you need to exclude additional directories from the report, specify them
+# using the COVERAGE_EXCLUDES variable before calling SETUP_TARGET_FOR_COVERAGE.
+# Example:
+# set(COVERAGE_EXCLUDES 'dir1/*' 'dir2/*')
+#
+# 5. Use the functions described below to create a custom make target which
+# runs your test executable and produces a code coverage report.
+#
+# 6. Build a Debug build:
+# cmake -DCMAKE_BUILD_TYPE=Debug ..
+# make
+# make my_coverage_target
+#
+
+include(CMakeParseArguments)
+
+# Check prereqs
+find_program( GCOV_PATH gcov )
+find_program( LCOV_PATH lcov )
+find_program( GENHTML_PATH genhtml )
+find_program( SIMPLE_PYTHON_EXECUTABLE python )
+
+if(NOT GCOV_PATH)
+ message(FATAL_ERROR "gcov not found! Aborting...")
+endif() # NOT GCOV_PATH
+
+if("${CMAKE_CXX_COMPILER_ID}" MATCHES "(Apple)?[Cc]lang")
+ if("${CMAKE_CXX_COMPILER_VERSION}" VERSION_LESS 3)
+ message(FATAL_ERROR "Clang version must be 3.0.0 or greater! Aborting...")
+ endif()
+ list(APPEND COVERAGE_COMPILER_FLAGS -Qunused-arguments)
+elseif(NOT CMAKE_COMPILER_IS_GNUCXX)
+ message(FATAL_ERROR "Compiler is not GNU gcc! Aborting...")
+endif()
+
+list(APPEND COVERAGE_COMPILER_FLAGS
+ -g -O0 --coverage -fprofile-arcs -ftest-coverage)
+set(COVERAGE_COMPILER_FLAGS ${COVERAGE_COMPILER_FLAGS} CACHE INTERNAL "")
+
+set(CMAKE_CXX_FLAGS_COVERAGE
+ ${COVERAGE_COMPILER_FLAGS}
+ CACHE STRING "Flags used by the C++ compiler during coverage builds."
+ FORCE )
+set(CMAKE_C_FLAGS_COVERAGE
+ ${COVERAGE_COMPILER_FLAGS}
+ CACHE STRING "Flags used by the C compiler during coverage builds."
+ FORCE )
+set(CMAKE_EXE_LINKER_FLAGS_COVERAGE
+ ""
+ CACHE STRING "Flags used for linking binaries during coverage builds."
+ FORCE )
+set(CMAKE_SHARED_LINKER_FLAGS_COVERAGE
+ ""
+ CACHE STRING "Flags used by the shared libraries linker during coverage builds."
+ FORCE )
+mark_as_advanced(
+ CMAKE_CXX_FLAGS_COVERAGE
+ CMAKE_C_FLAGS_COVERAGE
+ CMAKE_EXE_LINKER_FLAGS_COVERAGE
+ CMAKE_SHARED_LINKER_FLAGS_COVERAGE )
+
+if(NOT CMAKE_BUILD_TYPE STREQUAL "Debug")
+ message(WARNING "Code coverage results with an optimised (non-Debug) build may be misleading")
+endif() # NOT CMAKE_BUILD_TYPE STREQUAL "Debug"
+
+if(CMAKE_C_COMPILER_ID STREQUAL "GNU")
+ link_libraries(gcov)
+else()
+ set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} --coverage")
+endif()
+
+# Defines a target for running and collection code coverage information
+# Builds dependencies, runs the given executable and outputs reports.
+# NOTE! The executable should always have a ZERO as exit code otherwise
+# the coverage generation will not complete.
+#
+# setup_target_for_coverage(
+# NAME testrunner_coverage # New target name
+# EXECUTABLE testrunner -j ${PROCESSOR_COUNT} # Executable in PROJECT_BINARY_DIR
+# DEPENDENCIES testrunner # Dependencies to build first
+# )
+function(setup_target_for_coverage)
+ set(options NONE)
+ set(oneValueArgs NAME)
+ set(multiValueArgs EXECUTABLE EXECUTABLE_ARGS DEPENDENCIES)
+ cmake_parse_arguments(Coverage "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
+
+ if(NOT LCOV_PATH)
+ message(FATAL_ERROR "lcov not found! Aborting...")
+ endif() # NOT LCOV_PATH
+
+ if(NOT GENHTML_PATH)
+ message(FATAL_ERROR "genhtml not found! Aborting...")
+ endif() # NOT GENHTML_PATH
+
+ # Setup target
+ add_custom_target(${Coverage_NAME}
+
+ # Cleanup lcov
+ COMMAND ${LCOV_PATH} --directory . --zerocounters
+
+ # Run tests
+ COMMAND ${Coverage_EXECUTABLE}
+
+ # Capturing lcov counters and generating report
+ COMMAND ${LCOV_PATH} --base-directory ${CMAKE_SOURCE_DIR} --directory . --capture --output-file ${Coverage_NAME}.info --no-external
+ COMMAND ${LCOV_PATH} --remove ${Coverage_NAME}.info ${COVERAGE_EXCLUDES} --output-file ${Coverage_NAME}.info.cleaned
+ COMMAND ${GENHTML_PATH} --legend --demangle-cpp -o ${Coverage_NAME} ${Coverage_NAME}.info.cleaned
+ COMMAND ${CMAKE_COMMAND} -E rename ${Coverage_NAME}.info.cleaned coverage.info
+ COMMAND ${CMAKE_COMMAND} -E remove ${Coverage_NAME}.info
+
+ WORKING_DIRECTORY ${PROJECT_BINARY_DIR}
+ DEPENDS ${Coverage_DEPENDENCIES}
+ COMMENT "Resetting code coverage counters to zero.\nProcessing code coverage counters and generating report."
+ )
+
+ # Show info where to find the report
+ add_custom_command(TARGET ${Coverage_NAME} POST_BUILD
+ COMMAND ;
+ COMMENT "Open ./${Coverage_NAME}/index.html in your browser to view the coverage report."
+ )
+endfunction() # setup_target_for_coverage
+
+function(append_coverage_compiler_flags flags_var)
+ set(${flags_var} ${${flags_var}} ${COVERAGE_COMPILER_FLAGS} PARENT_SCOPE)
+endfunction() # append_coverage_compiler_flags
diff --git a/src/jaegertracing/jaeger-client-cpp/cmake/Config.cmake.in b/src/jaegertracing/jaeger-client-cpp/cmake/Config.cmake.in
new file mode 100644
index 000000000..c2a892b04
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/cmake/Config.cmake.in
@@ -0,0 +1,20 @@
+@PACKAGE_INIT@
+
+set(package_deps @package_deps@)
+foreach(dep IN LISTS package_deps)
+ if(dep STREQUAL "OpenSSL" OR dep STREQUAL "Threads")
+ find_package(${dep} REQUIRED)
+ elseif(dep STREQUAL "OpenTracing" OR
+ dep STREQUAL "yaml-cpp")
+ find_package(${dep} CONFIG REQUIRED)
+ else()
+ find_package(${dep} @hunter_config@ REQUIRED)
+ endif()
+endforeach()
+
+set(boost_components @boost_components@)
+find_package(Boost CONFIG REQUIRED ${boost_components})
+
+check_required_components("@PROJECT_NAME@")
+
+include("${CMAKE_CURRENT_LIST_DIR}/@TARGETS_EXPORT_NAME@.cmake")
diff --git a/src/jaegertracing/jaeger-client-cpp/cmake/FindOpenTracing.cmake b/src/jaegertracing/jaeger-client-cpp/cmake/FindOpenTracing.cmake
new file mode 100644
index 000000000..79413d17e
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/cmake/FindOpenTracing.cmake
@@ -0,0 +1,95 @@
+#.rst:
+# FindOpenTracing
+# ------------
+#
+# This module finds the `OpenTracing` library.
+#
+# Imported target
+# ^^^^^^^^^^^^^^^
+#
+# This module defines the following :prop_tgt:`IMPORTED` target:
+#
+# ``OpenTracing``
+# The Opentracing library, if found
+#
+# Result variables
+# ^^^^^^^^^^^^^^^^
+#
+# This module sets the following
+#
+# ``OpenTracing_FOUND``
+# ``TRUE`` if system has OpenTracing
+# ``OpenTracing_INCLUDE_DIRS``
+# The OpenTracing include directories
+# ``OpenTracing_LIBRARIES``
+# The libraries needed to use OpenTracing
+# ``OpenTracing_VERSION_STRING``
+# The OpenTracing version
+
+#=============================================================================
+# Copyright 2018 Mania Abdi, Inc.
+# Copyright 2018 Mania Abdi
+#
+# Distributed under the OSI-approved BSD License (the "License");
+# see accompanying file Copyright.txt for details.
+#
+# This software is distributed WITHOUT ANY WARRANTY; without even the
+# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+# See the License for more information.
+#=============================================================================
+# (To distribute this file outside of CMake, substitute the full
+# License text for the above reference.)
+
+find_path(OpenTracing_INCLUDE_DIRS
+ NAMES opentracing/tracer.h
+ HINTS
+ ${OpenTracing_HOME}
+ ENV OpenTracing_HOME
+ PATH_SUFFIXES
+ include
+ )
+message(STATUS "OpenTracing_INCLUDE_DIRS ${OpenTracing_INCLUDE_DIRS}")
+find_library(OpenTracing_LIBRARIES NAMES
+ opentracing libopentracing
+ HINTS
+ ${OpenTracing_HOME}
+ ENV OpenTracing_HOME
+ PATH_SUFFIXES
+ lib lib64
+ )
+message(STATUS "opentracing libraries ${OpenTracing_LIBRARIES}")
+
+if(OpenTracing_INCLUDE_DIRS AND OpenTracing_LIBRARIES)
+
+ # will need specifically 1.5.x for successful working with Jaeger
+ set(OpenTracing_VERSION_STRING "1.6.0")
+
+ if(NOT TARGET OpenTracing::opentracing)
+ add_library(OpenTracing::opentracing SHARED IMPORTED)
+ set_target_properties(OpenTracing::opentracing PROPERTIES
+ INTERFACE_INCLUDE_DIRECTORIES "${OpenTracing_INCLUDE_DIRS}"
+ INTERFACE_LINK_LIBRARIES ${CMAKE_DL_LIBS}
+ IMPORTED_LINK_INTERFACE_LANGUAGES "C"
+ IMPORTED_LOCATION "${OpenTracing_LIBRARIES}")
+ endif()
+
+ if(NOT TARGET OpenTracing::opentracing-static)
+ add_library(OpenTracing::opentracing-static STATIC IMPORTED)
+ set_target_properties(OpenTracing::opentracing-static PROPERTIES
+ INTERFACE_INCLUDE_DIRECTORIES "${OpenTracing_INCLUDE_DIRS}"
+ INTERFACE_LINK_LIBRARIES ${CMAKE_DL_LIBS}
+ IMPORTED_LINK_INTERFACE_LANGUAGES "CXX"
+ IMPORTED_LOCATION "${OpenTracing_LIBRARIES}")
+ endif()
+ message(STATUS "include opentracing ${OpenTracing_INCLUDE_DIRS}")
+
+ # add libdl to required libraries
+ set(OpenTracing_LIBRARIES ${OpenTracing_LIBRARIES} ${CMAKE_DL_LIBS})
+endif()
+
+include(FindPackageHandleStandardArgs)
+find_package_handle_standard_args(OpenTracing FOUND_VAR OpenTracing_FOUND
+ REQUIRED_VARS OpenTracing_LIBRARIES
+ OpenTracing_INCLUDE_DIRS
+ VERSION_VAR OpenTracing_VERSION_STRING)
+mark_as_advanced(OpenTracing_LIBRARIES OpenTracing_INCLUDE_DIRS)
diff --git a/src/jaegertracing/jaeger-client-cpp/cmake/Findnlohmann_json.cmake b/src/jaegertracing/jaeger-client-cpp/cmake/Findnlohmann_json.cmake
new file mode 100644
index 000000000..c5fc8b048
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/cmake/Findnlohmann_json.cmake
@@ -0,0 +1,55 @@
+# - Try to find nlohmann_json
+#
+# The following variables are optionally searched for defaults
+# nlohmann_json_ROOT_DIR: Base directory where all GLOG components are found
+#
+# The following are set after configuration is done:
+# nlohmann_json_FOUND
+# nlohmann_json_INCLUDE_DIRS
+# nlohmann_json_LIBRARIES
+
+include(FindPackageHandleStandardArgs)
+
+# only look in default directories
+set(nlohmann_json_INCLUDE_NAME "nlohmann/json.hpp")
+
+find_path(nlohmann_json_INCLUDE_DIR
+ NAMES
+ nlohmann/json.hpp
+ PATHS /usr/local/include
+ /usr/include)
+
+if (NOT nlohmann_json_INCLUDE_DIR)
+ set(nlohmann_json_INCLUDE_NAME "json.hpp")
+ find_path(
+ nlohmann_json_INCLUDE_DIR
+ NAMES "${nlohmann_json_INCLUDE_NAME}"
+ )
+endif()
+
+
+# Version detection. Unfortunately the header doesn't expose a proper version
+# define.
+if (nlohmann_json_INCLUDE_DIR AND nlohmann_json_INCLUDE_NAME)
+ file(READ "${nlohmann_json_INCLUDE_DIR}/${nlohmann_json_INCLUDE_NAME}" NL_HDR_TXT LIMIT 1000)
+ if (NL_HDR_TXT MATCHES "version ([0-9]+\.[0-9]+\.[0-9]+)")
+ set(nlohmann_json_VERSION "${CMAKE_MATCH_1}")
+ endif()
+endif()
+
+set(nlohmann_json_VERSION "${nlohmann_json_VERSION}" CACHE STRING "nlohmann header version")
+
+# handle the QUIETLY and REQUIRED arguments and set nlohmann_json_FOUND to TRUE
+# if all listed variables are TRUE, hide their existence from configuration view
+include(FindPackageHandleStandardArgs)
+find_package_handle_standard_args(
+ nlohmann_json
+ REQUIRED_VARS nlohmann_json_INCLUDE_DIR nlohmann_json_INCLUDE_NAME
+ VERSION_VAR nlohmann_json_VERSION)
+
+if(nlohmann_json_FOUND AND NOT (TARGET nlohmann_json))
+ add_library(nlohmann_json SHARED IMPORTED)
+ set_target_properties(nlohmann_json PROPERTIES
+ INTERFACE_INCLUDE_DIRECTORIES "${nlohmann_json_INCLUDE_DIR}"
+ )
+endif()
diff --git a/src/jaegertracing/jaeger-client-cpp/cmake/Findthrift.cmake b/src/jaegertracing/jaeger-client-cpp/cmake/Findthrift.cmake
new file mode 100644
index 000000000..77c36ed97
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/cmake/Findthrift.cmake
@@ -0,0 +1,93 @@
+# https://github.com/snikulov/cmake-modules/blob/master/FindThrift.cmake
+
+# - Find Thrift (a cross platform RPC lib/tool)
+# This module defines
+# thrift_VERSION_STRING, version string of ant if found
+# thrift_LIBRARIES, libraries to link
+# thrift_INCLUDE_DIR, where to find thrift headers
+# thrift_COMPILER, thrift compiler executable
+# thrift_FOUND, If false, do not try to use ant
+# Function
+# thrift_gen_cpp(<path to thrift file> <output variable with file list>)
+#
+# Initial work was done by Cloudera https://github.com/cloudera/Impala
+# 2014 - modified by snikulov
+
+# prefer the thrift version supplied in thrift_HOME (cmake -Dthrift_HOME then environment)
+find_path(thrift_INCLUDE_DIR
+ NAMES
+ thrift/Thrift.h
+ HINTS
+ ${thrift_HOME}
+ ENV thrift_HOME
+ /usr/local
+ /opt/local
+ PATH_SUFFIXES
+ include
+)
+
+# prefer the thrift version supplied in thrift_HOME
+find_library(thrift_LIBRARIES
+ NAMES
+ thrift libthrift
+ HINTS
+ ${thrift_HOME}
+ ENV thrift_HOME
+ /usr/local
+ /opt/local
+ PATH_SUFFIXES
+ lib lib64
+)
+
+find_program(thrift_COMPILER
+ NAMES
+ thrift
+ HINTS
+ ${thrift_HOME}
+ ENV thrift_HOME
+ /usr/local
+ /opt/local
+ PATH_SUFFIXES
+ bin bin64
+)
+
+if (thrift_COMPILER)
+ exec_program(${thrift_COMPILER}
+ ARGS -version OUTPUT_VARIABLE __thrift_OUT RETURN_VALUE thrift_RETURN)
+ string(REGEX MATCH "[0-9]+.[0-9]+.[0-9]+-[a-z]+$" thrift_VERSION_STRING ${__thrift_OUT})
+
+ # define utility function to generate cpp files
+ function(thrift_gen_cpp thrift_file thrift_CPP_FILES_LIST thrift_GEN_INCLUDE_DIR)
+ set(_res)
+ set(_res_inc_path)
+ if(EXISTS ${thrift_file})
+ get_filename_component(_target_dir ${thrift_file} NAME_WE)
+ message("thrif_gen_cpp: ${thrift_file}")
+
+ if(NOT EXISTS ${CMAKE_BINARY_DIR}/${_target_dir})
+ file(MAKE_DIRECTORY ${CMAKE_BINARY_DIR}/${_target_dir})
+ endif()
+ exec_program(${thrift_COMPILER}
+ ARGS -o "${CMAKE_BINARY_DIR}/${_target_dir}" --gen cpp ${thrift_file}
+ OUTPUT_VARIABLE __thrift_OUT
+ RETURN_VALUE thrift_RETURN)
+ file(GLOB_RECURSE __result_src "${CMAKE_BINARY_DIR}/${_target_dir}/*.cpp")
+ file(GLOB_RECURSE __result_hdr "${CMAKE_BINARY_DIR}/${_target_dir}/*.h")
+ list(APPEND _res ${__result_src})
+ list(APPEND _res ${__result_hdr})
+ if(__result_hdr)
+ list(GET __result_hdr 0 _res_inc_path)
+ get_filename_component(_res_inc_path ${_res_inc_path} DIRECTORY)
+ endif()
+ else()
+ message("thrift_gen_cpp: file ${thrift_file} does not exists")
+ endif()
+ set(${thrift_CPP_FILES_LIST} "${_res}" PARENT_SCOPE)
+ set(${thrift_GEN_INCLUDE_DIR} "${_res_inc_path}" PARENT_SCOPE)
+ endfunction()
+endif ()
+
+
+include(FindPackageHandleStandardArgs)
+FIND_PACKAGE_HANDLE_STANDARD_ARGS(thrift DEFAULT_MSG thrift_LIBRARIES thrift_INCLUDE_DIR thrift_COMPILER)
+mark_as_advanced(thrift_LIBRARIES thrift_INCLUDE_DIR thrift_COMPILER thrift_VERSION_STRING)
diff --git a/src/jaegertracing/jaeger-client-cpp/cmake/Hunter/config.cmake b/src/jaegertracing/jaeger-client-cpp/cmake/Hunter/config.cmake
new file mode 100644
index 000000000..f26c8530c
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/cmake/Hunter/config.cmake
@@ -0,0 +1 @@
+hunter_config(GTest VERSION 1.8.0-hunter-p11)
diff --git a/src/jaegertracing/jaeger-client-cpp/cmake/HunterGate.cmake b/src/jaegertracing/jaeger-client-cpp/cmake/HunterGate.cmake
new file mode 100644
index 000000000..c24c0e577
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/cmake/HunterGate.cmake
@@ -0,0 +1,543 @@
+# Copyright (c) 2013-2017, Ruslan Baratov
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+#
+# * Redistributions of source code must retain the above copyright notice, this
+# list of conditions and the following disclaimer.
+#
+# * Redistributions in binary form must reproduce the above copyright notice,
+# this list of conditions and the following disclaimer in the documentation
+# and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+# This is a gate file to Hunter package manager.
+# Include this file using `include` command and add package you need, example:
+#
+# cmake_minimum_required(VERSION 3.0)
+#
+# include("cmake/HunterGate.cmake")
+# HunterGate(
+# URL "https://github.com/path/to/hunter/archive.tar.gz"
+# SHA1 "798501e983f14b28b10cda16afa4de69eee1da1d"
+# )
+#
+# project(MyProject)
+#
+# hunter_add_package(Foo)
+# hunter_add_package(Boo COMPONENTS Bar Baz)
+#
+# Projects:
+# * https://github.com/hunter-packages/gate/
+# * https://github.com/ruslo/hunter
+
+option(HUNTER_ENABLED "Enable Hunter package manager support" ON)
+if(HUNTER_ENABLED)
+ if(CMAKE_VERSION VERSION_LESS "3.0")
+ message(FATAL_ERROR "At least CMake version 3.0 required for hunter dependency management."
+ " Update CMake or set HUNTER_ENABLED to OFF.")
+ endif()
+endif()
+
+include(CMakeParseArguments) # cmake_parse_arguments
+
+option(HUNTER_STATUS_PRINT "Print working status" ON)
+option(HUNTER_STATUS_DEBUG "Print a lot info" OFF)
+option(HUNTER_TLS_VERIFY "Enable/disable TLS certificate checking on downloads" ON)
+
+set(HUNTER_WIKI "https://github.com/ruslo/hunter/wiki")
+
+function(hunter_gate_status_print)
+ foreach(print_message ${ARGV})
+ if(HUNTER_STATUS_PRINT OR HUNTER_STATUS_DEBUG)
+ message(STATUS "[hunter] ${print_message}")
+ endif()
+ endforeach()
+endfunction()
+
+function(hunter_gate_status_debug)
+ foreach(print_message ${ARGV})
+ if(HUNTER_STATUS_DEBUG)
+ string(TIMESTAMP timestamp)
+ message(STATUS "[hunter *** DEBUG *** ${timestamp}] ${print_message}")
+ endif()
+ endforeach()
+endfunction()
+
+function(hunter_gate_wiki wiki_page)
+ message("------------------------------ WIKI -------------------------------")
+ message(" ${HUNTER_WIKI}/${wiki_page}")
+ message("-------------------------------------------------------------------")
+ message("")
+ message(FATAL_ERROR "")
+endfunction()
+
+function(hunter_gate_internal_error)
+ message("")
+ foreach(print_message ${ARGV})
+ message("[hunter ** INTERNAL **] ${print_message}")
+ endforeach()
+ message("[hunter ** INTERNAL **] [Directory:${CMAKE_CURRENT_LIST_DIR}]")
+ message("")
+ hunter_gate_wiki("error.internal")
+endfunction()
+
+function(hunter_gate_fatal_error)
+ cmake_parse_arguments(hunter "" "WIKI" "" "${ARGV}")
+ string(COMPARE EQUAL "${hunter_WIKI}" "" have_no_wiki)
+ if(have_no_wiki)
+ hunter_gate_internal_error("Expected wiki")
+ endif()
+ message("")
+ foreach(x ${hunter_UNPARSED_ARGUMENTS})
+ message("[hunter ** FATAL ERROR **] ${x}")
+ endforeach()
+ message("[hunter ** FATAL ERROR **] [Directory:${CMAKE_CURRENT_LIST_DIR}]")
+ message("")
+ hunter_gate_wiki("${hunter_WIKI}")
+endfunction()
+
+function(hunter_gate_user_error)
+ hunter_gate_fatal_error(${ARGV} WIKI "error.incorrect.input.data")
+endfunction()
+
+function(hunter_gate_self root version sha1 result)
+ string(COMPARE EQUAL "${root}" "" is_bad)
+ if(is_bad)
+ hunter_gate_internal_error("root is empty")
+ endif()
+
+ string(COMPARE EQUAL "${version}" "" is_bad)
+ if(is_bad)
+ hunter_gate_internal_error("version is empty")
+ endif()
+
+ string(COMPARE EQUAL "${sha1}" "" is_bad)
+ if(is_bad)
+ hunter_gate_internal_error("sha1 is empty")
+ endif()
+
+ string(SUBSTRING "${sha1}" 0 7 archive_id)
+
+ if(EXISTS "${root}/cmake/Hunter")
+ set(hunter_self "${root}")
+ else()
+ set(
+ hunter_self
+ "${root}/_Base/Download/Hunter/${version}/${archive_id}/Unpacked"
+ )
+ endif()
+
+ set("${result}" "${hunter_self}" PARENT_SCOPE)
+endfunction()
+
+# Set HUNTER_GATE_ROOT cmake variable to suitable value.
+function(hunter_gate_detect_root)
+ # Check CMake variable
+ string(COMPARE NOTEQUAL "${HUNTER_ROOT}" "" not_empty)
+ if(not_empty)
+ set(HUNTER_GATE_ROOT "${HUNTER_ROOT}" PARENT_SCOPE)
+ hunter_gate_status_debug("HUNTER_ROOT detected by cmake variable")
+ return()
+ endif()
+
+ # Check environment variable
+ string(COMPARE NOTEQUAL "$ENV{HUNTER_ROOT}" "" not_empty)
+ if(not_empty)
+ set(HUNTER_GATE_ROOT "$ENV{HUNTER_ROOT}" PARENT_SCOPE)
+ hunter_gate_status_debug("HUNTER_ROOT detected by environment variable")
+ return()
+ endif()
+
+ # Check HOME environment variable
+ string(COMPARE NOTEQUAL "$ENV{HOME}" "" result)
+ if(result)
+ set(HUNTER_GATE_ROOT "$ENV{HOME}/.hunter" PARENT_SCOPE)
+ hunter_gate_status_debug("HUNTER_ROOT set using HOME environment variable")
+ return()
+ endif()
+
+ # Check SYSTEMDRIVE and USERPROFILE environment variable (windows only)
+ if(WIN32)
+ string(COMPARE NOTEQUAL "$ENV{SYSTEMDRIVE}" "" result)
+ if(result)
+ set(HUNTER_GATE_ROOT "$ENV{SYSTEMDRIVE}/.hunter" PARENT_SCOPE)
+ hunter_gate_status_debug(
+ "HUNTER_ROOT set using SYSTEMDRIVE environment variable"
+ )
+ return()
+ endif()
+
+ string(COMPARE NOTEQUAL "$ENV{USERPROFILE}" "" result)
+ if(result)
+ set(HUNTER_GATE_ROOT "$ENV{USERPROFILE}/.hunter" PARENT_SCOPE)
+ hunter_gate_status_debug(
+ "HUNTER_ROOT set using USERPROFILE environment variable"
+ )
+ return()
+ endif()
+ endif()
+
+ hunter_gate_fatal_error(
+ "Can't detect HUNTER_ROOT"
+ WIKI "error.detect.hunter.root"
+ )
+endfunction()
+
+macro(hunter_gate_lock dir)
+ if(NOT HUNTER_SKIP_LOCK)
+ if("${CMAKE_VERSION}" VERSION_LESS "3.2")
+ hunter_gate_fatal_error(
+ "Can't lock, upgrade to CMake 3.2 or use HUNTER_SKIP_LOCK"
+ WIKI "error.can.not.lock"
+ )
+ endif()
+ hunter_gate_status_debug("Locking directory: ${dir}")
+ file(LOCK "${dir}" DIRECTORY GUARD FUNCTION)
+ hunter_gate_status_debug("Lock done")
+ endif()
+endmacro()
+
+function(hunter_gate_download dir)
+ string(
+ COMPARE
+ NOTEQUAL
+ "$ENV{HUNTER_DISABLE_AUTOINSTALL}"
+ ""
+ disable_autoinstall
+ )
+ if(disable_autoinstall AND NOT HUNTER_RUN_INSTALL)
+ hunter_gate_fatal_error(
+ "Hunter not found in '${dir}'"
+ "Set HUNTER_RUN_INSTALL=ON to auto-install it from '${HUNTER_GATE_URL}'"
+ "Settings:"
+ " HUNTER_ROOT: ${HUNTER_GATE_ROOT}"
+ " HUNTER_SHA1: ${HUNTER_GATE_SHA1}"
+ WIKI "error.run.install"
+ )
+ endif()
+ string(COMPARE EQUAL "${dir}" "" is_bad)
+ if(is_bad)
+ hunter_gate_internal_error("Empty 'dir' argument")
+ endif()
+
+ string(COMPARE EQUAL "${HUNTER_GATE_SHA1}" "" is_bad)
+ if(is_bad)
+ hunter_gate_internal_error("HUNTER_GATE_SHA1 empty")
+ endif()
+
+ string(COMPARE EQUAL "${HUNTER_GATE_URL}" "" is_bad)
+ if(is_bad)
+ hunter_gate_internal_error("HUNTER_GATE_URL empty")
+ endif()
+
+ set(done_location "${dir}/DONE")
+ set(sha1_location "${dir}/SHA1")
+
+ set(build_dir "${dir}/Build")
+ set(cmakelists "${dir}/CMakeLists.txt")
+
+ hunter_gate_lock("${dir}")
+ if(EXISTS "${done_location}")
+ # while waiting for lock other instance can do all the job
+ hunter_gate_status_debug("File '${done_location}' found, skip install")
+ return()
+ endif()
+
+ file(REMOVE_RECURSE "${build_dir}")
+ file(REMOVE_RECURSE "${cmakelists}")
+
+ file(MAKE_DIRECTORY "${build_dir}") # check directory permissions
+
+ # Disabling languages speeds up a little bit, reduces noise in the output
+ # and avoids path too long windows error
+ file(
+ WRITE
+ "${cmakelists}"
+ "cmake_minimum_required(VERSION 3.0)\n"
+ "project(HunterDownload LANGUAGES NONE)\n"
+ "include(ExternalProject)\n"
+ "ExternalProject_Add(\n"
+ " Hunter\n"
+ " URL\n"
+ " \"${HUNTER_GATE_URL}\"\n"
+ " URL_HASH\n"
+ " SHA1=${HUNTER_GATE_SHA1}\n"
+ " DOWNLOAD_DIR\n"
+ " \"${dir}\"\n"
+ " TLS_VERIFY\n"
+ " ${HUNTER_TLS_VERIFY}\n"
+ " SOURCE_DIR\n"
+ " \"${dir}/Unpacked\"\n"
+ " CONFIGURE_COMMAND\n"
+ " \"\"\n"
+ " BUILD_COMMAND\n"
+ " \"\"\n"
+ " INSTALL_COMMAND\n"
+ " \"\"\n"
+ ")\n"
+ )
+
+ if(HUNTER_STATUS_DEBUG)
+ set(logging_params "")
+ else()
+ set(logging_params OUTPUT_QUIET)
+ endif()
+
+ hunter_gate_status_debug("Run generate")
+
+ # Need to add toolchain file too.
+ # Otherwise on Visual Studio + MDD this will fail with error:
+ # "Could not find an appropriate version of the Windows 10 SDK installed on this machine"
+ if(EXISTS "${CMAKE_TOOLCHAIN_FILE}")
+ get_filename_component(absolute_CMAKE_TOOLCHAIN_FILE "${CMAKE_TOOLCHAIN_FILE}" ABSOLUTE)
+ set(toolchain_arg "-DCMAKE_TOOLCHAIN_FILE=${absolute_CMAKE_TOOLCHAIN_FILE}")
+ else()
+ # 'toolchain_arg' can't be empty
+ set(toolchain_arg "-DCMAKE_TOOLCHAIN_FILE=")
+ endif()
+
+ string(COMPARE EQUAL "${CMAKE_MAKE_PROGRAM}" "" no_make)
+ if(no_make)
+ set(make_arg "")
+ else()
+ # Test case: remove Ninja from PATH but set it via CMAKE_MAKE_PROGRAM
+ set(make_arg "-DCMAKE_MAKE_PROGRAM=${CMAKE_MAKE_PROGRAM}")
+ endif()
+
+ execute_process(
+ COMMAND
+ "${CMAKE_COMMAND}"
+ "-H${dir}"
+ "-B${build_dir}"
+ "-G${CMAKE_GENERATOR}"
+ "${toolchain_arg}"
+ ${make_arg}
+ WORKING_DIRECTORY "${dir}"
+ RESULT_VARIABLE download_result
+ ${logging_params}
+ )
+
+ if(NOT download_result EQUAL 0)
+ hunter_gate_internal_error("Configure project failed")
+ endif()
+
+ hunter_gate_status_print(
+ "Initializing Hunter workspace (${HUNTER_GATE_SHA1})"
+ " ${HUNTER_GATE_URL}"
+ " -> ${dir}"
+ )
+ execute_process(
+ COMMAND "${CMAKE_COMMAND}" --build "${build_dir}"
+ WORKING_DIRECTORY "${dir}"
+ RESULT_VARIABLE download_result
+ ${logging_params}
+ )
+
+ if(NOT download_result EQUAL 0)
+ hunter_gate_internal_error("Build project failed")
+ endif()
+
+ file(REMOVE_RECURSE "${build_dir}")
+ file(REMOVE_RECURSE "${cmakelists}")
+
+ file(WRITE "${sha1_location}" "${HUNTER_GATE_SHA1}")
+ file(WRITE "${done_location}" "DONE")
+
+ hunter_gate_status_debug("Finished")
+endfunction()
+
+# Must be a macro so master file 'cmake/Hunter' can
+# apply all variables easily just by 'include' command
+# (otherwise PARENT_SCOPE magic needed)
+macro(HunterGate)
+ if(HUNTER_GATE_DONE)
+ # variable HUNTER_GATE_DONE set explicitly for external project
+ # (see `hunter_download`)
+ set_property(GLOBAL PROPERTY HUNTER_GATE_DONE YES)
+ endif()
+
+ # First HunterGate command will init Hunter, others will be ignored
+ get_property(_hunter_gate_done GLOBAL PROPERTY HUNTER_GATE_DONE SET)
+
+ if(NOT HUNTER_ENABLED)
+ # Empty function to avoid error "unknown function"
+ function(hunter_add_package)
+ endfunction()
+
+ set(
+ _hunter_gate_disabled_mode_dir
+ "${CMAKE_CURRENT_LIST_DIR}/cmake/Hunter/disabled-mode"
+ )
+ if(EXISTS "${_hunter_gate_disabled_mode_dir}")
+ hunter_gate_status_debug(
+ "Adding \"disabled-mode\" modules: ${_hunter_gate_disabled_mode_dir}"
+ )
+ list(APPEND CMAKE_PREFIX_PATH "${_hunter_gate_disabled_mode_dir}")
+ endif()
+ elseif(_hunter_gate_done)
+ hunter_gate_status_debug("Secondary HunterGate (use old settings)")
+ hunter_gate_self(
+ "${HUNTER_CACHED_ROOT}"
+ "${HUNTER_VERSION}"
+ "${HUNTER_SHA1}"
+ _hunter_self
+ )
+ include("${_hunter_self}/cmake/Hunter")
+ else()
+ set(HUNTER_GATE_LOCATION "${CMAKE_CURRENT_LIST_DIR}")
+
+ string(COMPARE NOTEQUAL "${PROJECT_NAME}" "" _have_project_name)
+ if(_have_project_name)
+ hunter_gate_fatal_error(
+ "Please set HunterGate *before* 'project' command. "
+ "Detected project: ${PROJECT_NAME}"
+ WIKI "error.huntergate.before.project"
+ )
+ endif()
+
+ cmake_parse_arguments(
+ HUNTER_GATE "LOCAL" "URL;SHA1;GLOBAL;FILEPATH" "" ${ARGV}
+ )
+
+ string(COMPARE EQUAL "${HUNTER_GATE_SHA1}" "" _empty_sha1)
+ string(COMPARE EQUAL "${HUNTER_GATE_URL}" "" _empty_url)
+ string(
+ COMPARE
+ NOTEQUAL
+ "${HUNTER_GATE_UNPARSED_ARGUMENTS}"
+ ""
+ _have_unparsed
+ )
+ string(COMPARE NOTEQUAL "${HUNTER_GATE_GLOBAL}" "" _have_global)
+ string(COMPARE NOTEQUAL "${HUNTER_GATE_FILEPATH}" "" _have_filepath)
+
+ if(_have_unparsed)
+ hunter_gate_user_error(
+ "HunterGate unparsed arguments: ${HUNTER_GATE_UNPARSED_ARGUMENTS}"
+ )
+ endif()
+ if(_empty_sha1)
+ hunter_gate_user_error("SHA1 suboption of HunterGate is mandatory")
+ endif()
+ if(_empty_url)
+ hunter_gate_user_error("URL suboption of HunterGate is mandatory")
+ endif()
+ if(_have_global)
+ if(HUNTER_GATE_LOCAL)
+ hunter_gate_user_error("Unexpected LOCAL (already has GLOBAL)")
+ endif()
+ if(_have_filepath)
+ hunter_gate_user_error("Unexpected FILEPATH (already has GLOBAL)")
+ endif()
+ endif()
+ if(HUNTER_GATE_LOCAL)
+ if(_have_global)
+ hunter_gate_user_error("Unexpected GLOBAL (already has LOCAL)")
+ endif()
+ if(_have_filepath)
+ hunter_gate_user_error("Unexpected FILEPATH (already has LOCAL)")
+ endif()
+ endif()
+ if(_have_filepath)
+ if(_have_global)
+ hunter_gate_user_error("Unexpected GLOBAL (already has FILEPATH)")
+ endif()
+ if(HUNTER_GATE_LOCAL)
+ hunter_gate_user_error("Unexpected LOCAL (already has FILEPATH)")
+ endif()
+ endif()
+
+ hunter_gate_detect_root() # set HUNTER_GATE_ROOT
+
+ # Beautify path, fix probable problems with windows path slashes
+ get_filename_component(
+ HUNTER_GATE_ROOT "${HUNTER_GATE_ROOT}" ABSOLUTE
+ )
+ hunter_gate_status_debug("HUNTER_ROOT: ${HUNTER_GATE_ROOT}")
+ if(NOT HUNTER_ALLOW_SPACES_IN_PATH)
+ string(FIND "${HUNTER_GATE_ROOT}" " " _contain_spaces)
+ if(NOT _contain_spaces EQUAL -1)
+ hunter_gate_fatal_error(
+ "HUNTER_ROOT (${HUNTER_GATE_ROOT}) contains spaces."
+ "Set HUNTER_ALLOW_SPACES_IN_PATH=ON to skip this error"
+ "(Use at your own risk!)"
+ WIKI "error.spaces.in.hunter.root"
+ )
+ endif()
+ endif()
+
+ string(
+ REGEX
+ MATCH
+ "[0-9]+\\.[0-9]+\\.[0-9]+[-_a-z0-9]*"
+ HUNTER_GATE_VERSION
+ "${HUNTER_GATE_URL}"
+ )
+ string(COMPARE EQUAL "${HUNTER_GATE_VERSION}" "" _is_empty)
+ if(_is_empty)
+ set(HUNTER_GATE_VERSION "unknown")
+ endif()
+
+ hunter_gate_self(
+ "${HUNTER_GATE_ROOT}"
+ "${HUNTER_GATE_VERSION}"
+ "${HUNTER_GATE_SHA1}"
+ _hunter_self
+ )
+
+ set(_master_location "${_hunter_self}/cmake/Hunter")
+ if(EXISTS "${HUNTER_GATE_ROOT}/cmake/Hunter")
+ # Hunter downloaded manually (e.g. by 'git clone')
+ set(_unused "xxxxxxxxxx")
+ set(HUNTER_GATE_SHA1 "${_unused}")
+ set(HUNTER_GATE_VERSION "${_unused}")
+ else()
+ get_filename_component(_archive_id_location "${_hunter_self}/.." ABSOLUTE)
+ set(_done_location "${_archive_id_location}/DONE")
+ set(_sha1_location "${_archive_id_location}/SHA1")
+
+ # Check Hunter already downloaded by HunterGate
+ if(NOT EXISTS "${_done_location}")
+ hunter_gate_download("${_archive_id_location}")
+ endif()
+
+ if(NOT EXISTS "${_done_location}")
+ hunter_gate_internal_error("hunter_gate_download failed")
+ endif()
+
+ if(NOT EXISTS "${_sha1_location}")
+ hunter_gate_internal_error("${_sha1_location} not found")
+ endif()
+ file(READ "${_sha1_location}" _sha1_value)
+ string(COMPARE EQUAL "${_sha1_value}" "${HUNTER_GATE_SHA1}" _is_equal)
+ if(NOT _is_equal)
+ hunter_gate_internal_error(
+ "Short SHA1 collision:"
+ " ${_sha1_value} (from ${_sha1_location})"
+ " ${HUNTER_GATE_SHA1} (HunterGate)"
+ )
+ endif()
+ if(NOT EXISTS "${_master_location}")
+ hunter_gate_user_error(
+ "Master file not found:"
+ " ${_master_location}"
+ "try to update Hunter/HunterGate"
+ )
+ endif()
+ endif()
+ include("${_master_location}")
+ set_property(GLOBAL PROPERTY HUNTER_GATE_DONE YES)
+ endif()
+endmacro()
diff --git a/src/jaegertracing/jaeger-client-cpp/cmake/toolchain.cmake b/src/jaegertracing/jaeger-client-cpp/cmake/toolchain.cmake
new file mode 100644
index 000000000..ad7a02ffd
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/cmake/toolchain.cmake
@@ -0,0 +1,5 @@
+set(CMAKE_CXX_STANDARD_REQUIRED ON)
+set(CMAKE_CXX_STANDARD 11)
+set(CMAKE_CXX_EXTENSIONS OFF)
+set(CMAKE_POSITION_INDEPENDENT_CODE ON)
+set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS ON) \ No newline at end of file
diff --git a/src/jaegertracing/jaeger-client-cpp/codecov.yml b/src/jaegertracing/jaeger-client-cpp/codecov.yml
new file mode 100644
index 000000000..f47db21f0
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/codecov.yml
@@ -0,0 +1,31 @@
+codecov:
+ notify:
+ require_ci_to_pass: yes
+
+coverage:
+ precision: 2
+ round: down
+ range: "70...100"
+
+ status:
+ project: yes
+ patch: yes
+ changes: no
+
+parsers:
+ gcov:
+ branch_detection:
+ conditional: yes
+ loop: yes
+ method: no
+ macro: no
+
+comment:
+ layout: "reach, diff, flags, files, footer"
+ behavior: default
+ require_changes: no
+
+ignore:
+ - "src/jaegertracing/thrift-gen"
+ - "**/*Test.cpp"
+ - "crossdock"
diff --git a/src/jaegertracing/jaeger-client-cpp/crossdock/Dockerfile b/src/jaegertracing/jaeger-client-cpp/crossdock/Dockerfile
new file mode 100644
index 000000000..bfca32db6
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/crossdock/Dockerfile
@@ -0,0 +1,10 @@
+FROM gcc:7.2
+
+ADD ./build/crossdock /
+
+ENV AGENT_HOST_PORT=jaeger-agent:5775
+ENV SAMPLING_SERVER_URL=http://test_driver:5778/sampling
+
+EXPOSE 8080-8082
+
+CMD ["/crossdock"]
diff --git a/src/jaegertracing/jaeger-client-cpp/crossdock/Server.cpp b/src/jaegertracing/jaeger-client-cpp/crossdock/Server.cpp
new file mode 100644
index 000000000..5ba85b743
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/crossdock/Server.cpp
@@ -0,0 +1,808 @@
+/*
+ * Copyright (c) 2017-2018 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.
+ */
+
+#include "Server.h"
+
+#include <atomic>
+#include <cstdlib>
+#include <future>
+#include <sstream>
+#include <thread>
+
+#include <nlohmann/json.hpp>
+
+#include "jaegertracing/Tracer.h"
+#include "jaegertracing/net/IPAddress.h"
+#include "jaegertracing/net/Socket.h"
+#include "jaegertracing/net/http/Request.h"
+#include "jaegertracing/net/http/Response.h"
+
+namespace jaegertracing {
+namespace crossdock {
+namespace thrift {
+
+#define JSON_FROM_FIELD(var, field) \
+ { \
+ json[#field] = var.field; \
+ }
+
+#define FIELD_FROM_JSON(var, field) \
+ { \
+ var.__set_##field(json.at(#field)); \
+ }
+
+void to_json(nlohmann::json& json, const Transport::type& transport)
+{
+ json = _Transport_VALUES_TO_NAMES.at(static_cast<int>(transport));
+}
+
+void from_json(const nlohmann::json& json, Transport::type& transport)
+{
+ const auto str = json.get<std::string>();
+ if (str == "HTTP") {
+ transport = Transport::HTTP;
+ return;
+ }
+ if (str == "TCHANNEL") {
+ transport = Transport::TCHANNEL;
+ return;
+ }
+ if (str == "DUMMY") {
+ transport = Transport::DUMMY;
+ return;
+ }
+ std::ostringstream oss;
+ oss << "Invalid transport value " << str;
+ throw std::invalid_argument(oss.str());
+}
+
+void to_json(nlohmann::json& json, const Downstream& downstream)
+{
+ JSON_FROM_FIELD(downstream, serviceName);
+ JSON_FROM_FIELD(downstream, serverRole);
+ JSON_FROM_FIELD(downstream, host);
+ JSON_FROM_FIELD(downstream, port);
+ JSON_FROM_FIELD(downstream, transport);
+ if (downstream.downstream) {
+ json["downstream"] = *downstream.downstream;
+ }
+}
+
+void from_json(const nlohmann::json& json, Downstream& downstream)
+{
+ FIELD_FROM_JSON(downstream, serviceName);
+ FIELD_FROM_JSON(downstream, serverRole);
+ FIELD_FROM_JSON(downstream, host);
+ FIELD_FROM_JSON(downstream, port);
+ downstream.__set_transport(json.at("transport").get<Transport::type>());
+ auto itr = json.find("downstream");
+ if (itr != std::end(json) && !itr->is_null()) {
+ downstream.__set_downstream(
+ std::make_shared<Downstream>(itr->get<Downstream>()));
+ }
+}
+
+void to_json(nlohmann::json& json, const StartTraceRequest& request)
+{
+ JSON_FROM_FIELD(request, serverRole);
+ JSON_FROM_FIELD(request, sampled);
+ JSON_FROM_FIELD(request, baggage);
+ JSON_FROM_FIELD(request, downstream);
+}
+
+void from_json(const nlohmann::json& json, StartTraceRequest& request)
+{
+ FIELD_FROM_JSON(request, serverRole);
+ FIELD_FROM_JSON(request, sampled);
+ FIELD_FROM_JSON(request, baggage);
+ FIELD_FROM_JSON(request, downstream);
+}
+
+void to_json(nlohmann::json& json, const JoinTraceRequest& request)
+{
+ JSON_FROM_FIELD(request, serverRole);
+ if (request.__isset.downstream) {
+ json["downstream"] = request.downstream;
+ }
+}
+
+void from_json(const nlohmann::json& json, JoinTraceRequest& request)
+{
+ FIELD_FROM_JSON(request, serverRole);
+ auto itr = json.find("downstream");
+ if (itr != std::end(json) && !itr->is_null()) {
+ request.__set_downstream(itr->get<Downstream>());
+ }
+}
+
+void to_json(nlohmann::json& json, const ObservedSpan& observedSpan)
+{
+ JSON_FROM_FIELD(observedSpan, traceId);
+ JSON_FROM_FIELD(observedSpan, sampled);
+ JSON_FROM_FIELD(observedSpan, baggage);
+}
+
+void from_json(const nlohmann::json& json, ObservedSpan& observedSpan)
+{
+ FIELD_FROM_JSON(observedSpan, traceId);
+ FIELD_FROM_JSON(observedSpan, sampled);
+ FIELD_FROM_JSON(observedSpan, baggage);
+}
+
+void to_json(nlohmann::json& json, const TraceResponse& response)
+{
+ if (response.__isset.span) {
+ JSON_FROM_FIELD(response, span);
+ }
+ if (response.downstream) {
+ json["downstream"] = *response.downstream;
+ }
+ JSON_FROM_FIELD(response, notImplementedError);
+}
+
+void from_json(const nlohmann::json& json, TraceResponse& response)
+{
+ auto itr = json.find("span");
+ if (itr != std::end(json) && !itr->is_null()) {
+ response.__set_span(itr->get<ObservedSpan>());
+ }
+ itr = json.find("downstream");
+ if (itr != std::end(json) && !itr->is_null()) {
+ response.__set_downstream(
+ std::make_shared<TraceResponse>(itr->get<TraceResponse>()));
+ }
+ FIELD_FROM_JSON(response, notImplementedError);
+}
+
+#undef FIELD_FROM_JSON
+#undef JSON_FROM_FIELD
+
+} // namespace thrift
+
+namespace {
+
+constexpr auto kBaggageKey = "crossdock-baggage-key";
+constexpr auto kDefaultTracerServiceName = "crossdock-cpp";
+
+std::string escape(const std::string& str)
+{
+ std::string result;
+ result.reserve(str.size());
+ for (auto&& ch : str) {
+ switch (ch) {
+ case '\n': {
+ result += "\\n";
+ } break;
+ case '\r': {
+ result += "\\r";
+ } break;
+ default: {
+ result += ch;
+ } break;
+ }
+ }
+ return result;
+}
+
+std::string bufferedRead(net::Socket& socket)
+{
+ constexpr auto kBufferSize = 256;
+ std::array<char, kBufferSize> buffer;
+ std::string data;
+ auto numRead = ::read(socket.handle(), &buffer[0], buffer.size());
+ data.append(&buffer[0], numRead);
+ while (numRead == kBufferSize) {
+ numRead = ::read(socket.handle(), &buffer[0], buffer.size());
+ data.append(&buffer[0], numRead);
+ }
+ return data;
+}
+
+class RequestReader : public opentracing::HTTPHeadersReader {
+ public:
+ explicit RequestReader(const net::http::Request& request)
+ : _request(request)
+ {
+ }
+
+ opentracing::expected<void> ForeachKey(
+ std::function<opentracing::expected<void>(opentracing::string_view,
+ opentracing::string_view)> f)
+ const override
+ {
+ for (auto&& header : _request.headers()) {
+ const auto result = f(header.key(), header.value());
+ if (!result) {
+ return result;
+ }
+ }
+ return opentracing::make_expected();
+ }
+
+ private:
+ const net::http::Request& _request;
+};
+
+class RequestWriter : public opentracing::HTTPHeadersWriter {
+ public:
+ explicit RequestWriter(std::ostream& requestStream)
+ : _requestStream(requestStream)
+ {
+ }
+
+ opentracing::expected<void>
+ Set(opentracing::string_view key,
+ opentracing::string_view value) const override
+ {
+ _requestStream << key << ": " << value << "\r\n";
+ return opentracing::make_expected();
+ }
+
+ private:
+ std::ostream& _requestStream;
+};
+
+thrift::ObservedSpan observeSpan(const opentracing::SpanContext& ctx)
+{
+ const auto& sc = static_cast<const SpanContext&>(ctx);
+ thrift::ObservedSpan observedSpan;
+ std::ostringstream oss;
+ oss << sc.traceID();
+ observedSpan.__set_traceId(oss.str());
+ observedSpan.__set_sampled(sc.isSampled());
+ auto itr = sc.baggage().find(kBaggageKey);
+ if (itr != std::end(sc.baggage())) {
+ observedSpan.__set_baggage(itr->second);
+ }
+ return observedSpan;
+}
+
+thrift::TraceResponse callDownstreamHTTP(const opentracing::SpanContext& ctx,
+ const thrift::Downstream& target,
+ opentracing::Tracer& tracer,
+ logging::Logger& logger)
+{
+ thrift::JoinTraceRequest request;
+ request.__set_serverRole(target.serverRole);
+ if (target.downstream) {
+ request.__set_downstream(*target.downstream);
+ }
+
+ const auto requestJSON = nlohmann::json(request).dump();
+ net::Socket socket;
+ socket.open(AF_INET, SOCK_STREAM);
+ const auto authority = target.host + ':' + target.port;
+ socket.connect("http://" + authority);
+ std::ostringstream oss;
+ oss << "POST /join_trace HTTP/1.1\r\n"
+ "Host: "
+ << authority << "\r\n";
+ RequestWriter writer(oss);
+ tracer.Inject(ctx, writer);
+ oss << "Connection: close\r\n"
+ "Content-Type: application/json\r\n"
+ "Content-Length: "
+ << requestJSON.size() << "\r\n\r\n"
+ << requestJSON;
+ const auto message = oss.str();
+ logger.info("Sending request downstream: " + escape(message));
+ const auto numWritten =
+ ::write(socket.handle(), &message[0], message.size());
+ (void)numWritten;
+
+ const auto responseStr = bufferedRead(socket);
+ logger.info("Received downstream response: " + escape(responseStr));
+ std::istringstream iss(responseStr);
+ auto response = net::http::Response::parse(iss);
+ return nlohmann::json::parse(response.body());
+}
+
+thrift::TraceResponse callDownstream(const opentracing::SpanContext& ctx,
+ const std::string& /* role */,
+ const thrift::Downstream& downstream,
+ opentracing::Tracer& tracer,
+ logging::Logger& logger)
+{
+ thrift::TraceResponse response;
+
+ switch (downstream.transport) {
+ case thrift::Transport::HTTP: {
+ response = callDownstreamHTTP(ctx, downstream, tracer, logger);
+ } break;
+ case thrift::Transport::TCHANNEL: {
+ response.__set_notImplementedError(
+ "TCHANNEL transport not implemented");
+ } break;
+ case thrift::Transport::DUMMY: {
+ response.__set_notImplementedError("DUMMY transport not implemented");
+ } break;
+ default: {
+ throw std::invalid_argument("Unrecognized protocol " +
+ std::to_string(downstream.transport));
+ } break;
+ }
+
+ return response;
+}
+
+thrift::TraceResponse prepareResponse(const opentracing::SpanContext& ctx,
+ const std::string& role,
+ const thrift::Downstream* downstream,
+ opentracing::Tracer& tracer,
+ logging::Logger& logger)
+{
+ const auto observedSpan = observeSpan(ctx);
+ thrift::TraceResponse response;
+ response.__set_span(observedSpan);
+ if (downstream) {
+ response.__set_downstream(std::make_shared<thrift::TraceResponse>(
+ callDownstream(ctx, role, *downstream, tracer, logger)));
+ }
+ return response;
+}
+
+struct GenerateTracesRequest {
+ using StrMap = std::unordered_map<std::string, std::string>;
+
+ std::string _type;
+ std::string _operation;
+ StrMap _tags;
+ int _count;
+};
+
+void from_json(const nlohmann::json& json, GenerateTracesRequest& request)
+{
+ request._type = json.at("type");
+ request._operation = json.at("operation");
+ request._tags = json.at("tags").get<GenerateTracesRequest::StrMap>();
+ request._count = json.at("count");
+}
+
+} // anonymous namespace
+
+using Handler = std::function<std::string(const net::http::Request&)>;
+
+class Server::SocketListener {
+ public:
+ SocketListener(const net::IPAddress& ip,
+ const std::shared_ptr<logging::Logger>& logger,
+ Handler handler)
+ : _ip(ip)
+ , _logger(logger)
+ , _handler(handler)
+ , _running(false)
+ {
+ assert(_logger);
+ }
+
+ ~SocketListener() { stop(); }
+
+ void start()
+ {
+ std::promise<void> started;
+ _thread = std::thread([this, &started]() { start(_ip, started); });
+ started.get_future().get();
+ }
+
+ void stop() noexcept
+ {
+ if (_running) {
+ _running = false;
+ _thread.join();
+ _socket.close();
+ }
+ }
+
+ private:
+ void start(const net::IPAddress& ip, std::promise<void>& started)
+ {
+ _socket.open(AF_INET, SOCK_STREAM);
+ const auto enable = 1;
+ ::setsockopt(_socket.handle(),
+ SOL_SOCKET,
+ SO_REUSEADDR,
+ &enable,
+ sizeof(enable));
+ _socket.bind(ip);
+ _socket.listen();
+ _running = true;
+ started.set_value();
+
+ using TaskList = std::deque<std::future<void>>;
+ TaskList tasks;
+
+ while (_running) {
+ auto client = _socket.accept();
+ auto future = std::async(
+ std::launch::async,
+ [this](net::Socket&& socket) {
+ net::Socket client(std::move(socket));
+ auto requestStr = bufferedRead(client);
+ _logger->info("Received request: " + escape(requestStr));
+
+ try {
+ std::istringstream iss(requestStr);
+ const auto request = net::http::Request::parse(iss);
+ const auto responseStr = _handler(request);
+ const auto numWritten = ::write(client.handle(),
+ &responseStr[0],
+ responseStr.size());
+ if (numWritten !=
+ static_cast<int>(responseStr.size())) {
+ std::ostringstream oss;
+ oss << "Unable to write entire response"
+ ", numWritten="
+ << numWritten
+ << ", responseSize=" << responseStr.size();
+ _logger->error(oss.str());
+ }
+ } catch (...) {
+ utils::ErrorUtil::logError(*_logger, "Server error");
+ constexpr auto message =
+ "HTTP/1.1 500 Internal Server Error\r\n\r\n";
+ constexpr auto messageSize = sizeof(message) - 1;
+ const auto numWritten =
+ ::write(client.handle(), message, messageSize);
+ (void)numWritten;
+ }
+
+ client.close();
+ },
+ std::move(client));
+ tasks.emplace_back(std::move(future));
+ }
+
+ std::for_each(std::begin(tasks),
+ std::end(tasks),
+ [](TaskList::value_type& future) { future.get(); });
+ }
+
+ net::IPAddress _ip;
+ net::Socket _socket;
+ std::shared_ptr<logging::Logger> _logger;
+ Handler _handler;
+ std::atomic<bool> _running;
+ std::thread _thread;
+};
+
+class Server::EndToEndHandler {
+ public:
+ using TracerPtr = std::shared_ptr<opentracing::Tracer>;
+
+ EndToEndHandler(const std::string& agentHostPort,
+ const std::string& collectorEndpoint,
+ const std::string& samplingServerURL)
+ : _agentHostPort(agentHostPort)
+ , _collectorEndpoint(collectorEndpoint)
+ , _samplingServerURL(samplingServerURL)
+ {
+ }
+
+ TracerPtr findOrMakeTracer(std::string samplerType)
+ {
+ if (samplerType.empty()) {
+ samplerType = kSamplerTypeRemote;
+ }
+
+ std::lock_guard<std::mutex> lock(_mutex);
+ auto itr = _tracers.find(samplerType);
+ if (itr != std::end(_tracers)) {
+ return itr->second;
+ }
+ return init(samplerType);
+ }
+
+ private:
+ Config makeEndToEndConfig(const std::string& samplerType) const
+ {
+ return Config(false,
+ samplers::Config(samplerType,
+ 1.0,
+ _samplingServerURL,
+ samplers::Config::kDefaultMaxOperations,
+ std::chrono::seconds(5)),
+ reporters::Config(reporters::Config::kDefaultQueueSize,
+ std::chrono::seconds(1),
+ false,
+ _agentHostPort,
+ _collectorEndpoint));
+ }
+
+ TracerPtr init(const std::string& samplerType)
+ {
+ const auto config = makeEndToEndConfig(samplerType);
+ auto tracer = Tracer::make(kDefaultTracerServiceName, config);
+ _tracers[config.sampler().type()] = tracer;
+ return tracer;
+ }
+
+ std::string _agentHostPort;
+ std::string _collectorEndpoint;
+ std::string _samplingServerURL;
+ std::unordered_map<std::string, TracerPtr> _tracers;
+ std::mutex _mutex;
+};
+
+Server::Server(const net::IPAddress& clientIP,
+ const net::IPAddress& serverIP,
+ const std::string& agentHostPort,
+ const std::string& collectorEndpoint,
+ const std::string& samplingServerURL)
+ : _logger(logging::consoleLogger())
+ , _tracer(Tracer::make(kDefaultTracerServiceName, Config(), _logger))
+ , _clientListener(
+ new SocketListener(clientIP,
+ _logger,
+ [this](const net::http::Request& request) {
+ return handleRequest(request);
+ }))
+ , _serverListener(
+ new SocketListener(serverIP,
+ _logger,
+ [this](const net::http::Request& request) {
+ return handleRequest(request);
+ }))
+ , _handler(new EndToEndHandler(agentHostPort, collectorEndpoint, samplingServerURL))
+{
+}
+
+Server::~Server() = default;
+
+void Server::serve()
+{
+ _clientListener->start();
+ _serverListener->start();
+}
+
+template <typename RequestType>
+std::string Server::handleJSON(
+ const net::http::Request& request,
+ std::function<thrift::TraceResponse(
+ const RequestType&, const opentracing::SpanContext&)> handler)
+{
+ RequestReader reader(request);
+ auto result = _tracer->Extract(reader);
+ if (!result) {
+ std::ostringstream oss;
+ oss << "Cannot read request body: opentracing error code "
+ << result.error().value();
+ const auto message = oss.str();
+ oss.str("");
+ oss.clear();
+ oss << "HTTP/1.1 400 Bad Request\r\n"
+ "Content-Length: "
+ << message.size() << "\r\n\r\n"
+ << message;
+ }
+
+ std::unique_ptr<opentracing::SpanContext> ctx(result->release());
+ opentracing::StartSpanOptions options;
+ options.start_system_timestamp = std::chrono::system_clock::now();
+ options.start_steady_timestamp = std::chrono::steady_clock::now();
+ if (ctx) {
+ options.references.emplace_back(std::make_pair(
+ opentracing::SpanReferenceType::ChildOfRef, ctx.get()));
+ }
+ auto span = _tracer->StartSpanWithOptions("post", options);
+
+ RequestType thriftRequest;
+ try {
+ thriftRequest = nlohmann::json::parse(request.body());
+ } catch (const std::exception& ex) {
+ std::ostringstream oss;
+ oss << "Cannot parse request JSON: " << ex.what()
+ << ", json: " << request.body();
+ const auto message = oss.str();
+ oss.str("");
+ oss.clear();
+ oss << "HTTP/1.1 500 Internal Server Error\r\n"
+ "Content-Length: "
+ << message.size() << "\r\n\r\n"
+ << message;
+ return oss.str();
+ } catch (...) {
+ std::ostringstream oss;
+ oss << "Cannot parse request JSON, json: " << request.body();
+ const auto message = oss.str();
+ oss.str("");
+ oss.clear();
+ oss << "HTTP/1.1 500 Internal Server Error\r\n"
+ "Content-Length: "
+ << message.size() << "\r\n\r\n"
+ << message;
+ return oss.str();
+ }
+
+ const auto thriftResponse = handler(thriftRequest, span->context());
+ try {
+ const auto message = nlohmann::json(thriftResponse).dump();
+ std::ostringstream oss;
+ oss << "HTTP/1.1 200 OK\r\n"
+ "Content-Type: application/json\r\n"
+ "Content-Length: "
+ << message.size() << "\r\n\r\n"
+ << message;
+ return oss.str();
+ } catch (const std::exception& ex) {
+ std::ostringstream oss;
+ oss << "Cannot marshal response to JSON: " << ex.what();
+ const auto message = oss.str();
+ oss.str("");
+ oss.clear();
+ oss << "HTTP/1.1 500 Internal Server Error\r\n"
+ "Content-Length: "
+ << message.size() << "\r\n\r\n"
+ << message;
+ return oss.str();
+ } catch (...) {
+ std::ostringstream oss;
+ oss << "Cannot marshal response to JSON";
+ const auto message = oss.str();
+ oss.str("");
+ oss.clear();
+ oss << "HTTP/1.1 500 Internal Server Error\r\n"
+ "Content-Length: "
+ << message.size() << "\r\n\r\n"
+ << message;
+ return oss.str();
+ }
+}
+
+std::string Server::handleRequest(const net::http::Request& request)
+{
+ if (request.target() == "/") {
+ return "HTTP/1.1 200 OK\r\n\r\n";
+ }
+ if (request.target() == "/start_trace") {
+ return handleJSON<thrift::StartTraceRequest>(
+ request,
+ [this](const thrift::StartTraceRequest& request,
+ const opentracing::SpanContext& /* ctx */) {
+ return startTrace(request);
+ });
+ }
+ if (request.target() == "/join_trace") {
+ return handleJSON<thrift::JoinTraceRequest>(
+ request,
+ [this](const thrift::JoinTraceRequest& request,
+ const opentracing::SpanContext& ctx) {
+ return joinTrace(request, ctx);
+ });
+ }
+ if (request.target() == "/create_traces") {
+ return generateTraces(request);
+ }
+ return "HTTP/1.1 404 Not Found\r\n\r\n";
+}
+
+thrift::TraceResponse
+Server::startTrace(const crossdock::thrift::StartTraceRequest& request)
+{
+ auto span = _tracer->StartSpan(request.serverRole);
+ if (request.sampled) {
+ span->SetTag("sampling.priority", 1);
+ }
+ span->SetBaggageItem(kBaggageKey, request.baggage);
+
+ return prepareResponse(span->context(),
+ request.serverRole,
+ &request.downstream,
+ *_tracer,
+ *_logger);
+}
+
+thrift::TraceResponse
+Server::joinTrace(const crossdock::thrift::JoinTraceRequest& request,
+ const opentracing::SpanContext& ctx)
+{
+ return prepareResponse(ctx,
+ request.serverRole,
+ request.__isset.downstream ? &request.downstream
+ : nullptr,
+ *_tracer,
+ *_logger);
+}
+
+std::string Server::generateTraces(const net::http::Request& requestHTTP)
+{
+ GenerateTracesRequest request;
+ try {
+ request = nlohmann::json::parse(requestHTTP.body());
+ } catch (const std::exception& ex) {
+ std::ostringstream oss;
+ oss << "JSON payload is invalid: " << ex.what();
+ const auto message = oss.str();
+ oss.str("");
+ oss.clear();
+ oss << "HTTP/1.1 400 Bad Request\r\n"
+ "Content-Length: "
+ << message.size() << "\r\n\r\n"
+ << message;
+ return oss.str();
+ } catch (...) {
+ const std::string message("JSON payload is invalid");
+ std::ostringstream oss;
+ oss << "HTTP/1.1 400 Bad Request\r\n"
+ "Content-Length: "
+ << message.size() << "\r\n\r\n"
+ << message;
+ return oss.str();
+ }
+
+ auto tracer = _handler->findOrMakeTracer(request._type);
+ if (!tracer) {
+ const std::string message("Tracer is not initialized");
+ std::ostringstream oss;
+ oss << "HTTP/1.1 500 Internal Server Error\r\n"
+ "Content-Length: "
+ << message.size() << "\r\n"
+ << message;
+ return oss.str();
+ }
+
+ for (auto i = 0; i < request._count; ++i) {
+ auto span = tracer->StartSpan(request._operation);
+ for (auto&& pair : request._tags) {
+ span->SetTag(pair.first, pair.second);
+ }
+ span->Finish();
+ }
+
+ return "HTTP/1.1 200 OK\r\n\r\n";
+}
+
+} // namespace crossdock
+} // namespace jaegertracing
+
+int main()
+{
+ const auto rawSenderType = std::getenv("SENDER");
+ const std::string senderType(rawSenderType ? rawSenderType : "");
+
+ if (senderType.empty()) {
+ std::cerr << "env SENDER is not specified!\n";
+ return 1;
+ }
+
+ const auto rawAgentHostPort = std::getenv("AGENT_HOST_PORT");
+ const std::string agentHostPort(rawAgentHostPort ? rawAgentHostPort : "");
+
+ if (agentHostPort.empty() && senderType == "udp") {
+ std::cerr << "env AGENT_HOST_PORT is not specified!\n";
+ return 1;
+ }
+
+ const std::string collectorEndpoint(senderType == "http" ? "http://jaeger-collector:14268/api/traces" : "");
+
+ const auto rawSamplingServerURL = std::getenv("SAMPLING_SERVER_URL");
+ const std::string samplingServerURL(
+ rawSamplingServerURL ? rawSamplingServerURL : "");
+ if (samplingServerURL.empty()) {
+ std::cerr << "env SAMPLING_SERVER_URL is not specified!\n";
+ return 1;
+ }
+
+ jaegertracing::crossdock::Server server(
+ jaegertracing::net::IPAddress::v4("0.0.0.0:8080"),
+ jaegertracing::net::IPAddress::v4("0.0.0.0:8081"),
+ agentHostPort,
+ collectorEndpoint,
+ samplingServerURL);
+ server.serve();
+
+ std::this_thread::sleep_for(std::chrono::hours(1));
+ return 0;
+}
diff --git a/src/jaegertracing/jaeger-client-cpp/crossdock/Server.h b/src/jaegertracing/jaeger-client-cpp/crossdock/Server.h
new file mode 100644
index 000000000..e02d32294
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/crossdock/Server.h
@@ -0,0 +1,87 @@
+/*
+ * 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_CROSSDOCK_SERVER_H
+#define JAEGERTRACING_CROSSDOCK_SERVER_H
+
+#include <memory>
+
+#include <opentracing/tracer.h>
+
+#include "jaegertracing/thrift-gen/tracetest_types.h"
+
+namespace jaegertracing {
+namespace logging {
+
+class Logger;
+
+} // namespace logging
+
+namespace net {
+
+class IPAddress;
+
+namespace http {
+
+class Request;
+
+} // namespace http
+} // namespace net
+
+namespace crossdock {
+
+class Server {
+ public:
+ Server(const net::IPAddress& clientIP,
+ const net::IPAddress& serverIP,
+ const std::string& agentHostPort,
+ const std::string& collectorEndpoint,
+ const std::string& samplingServerURL);
+
+ ~Server();
+
+ void serve();
+
+ private:
+ template <typename RequestType>
+ std::string handleJSON(
+ const net::http::Request& request,
+ std::function<thrift::TraceResponse(
+ const RequestType&, const opentracing::SpanContext&)> handler);
+
+ std::string handleRequest(const net::http::Request& request);
+
+ thrift::TraceResponse startTrace(const thrift::StartTraceRequest& request);
+
+ thrift::TraceResponse joinTrace(const thrift::JoinTraceRequest& request,
+ const opentracing::SpanContext& ctx);
+
+ std::string generateTraces(const net::http::Request& request);
+
+ class SocketListener;
+ class EndToEndHandler;
+
+ std::shared_ptr<logging::Logger> _logger;
+ std::shared_ptr<opentracing::Tracer> _tracer;
+ std::unique_ptr<SocketListener> _clientListener;
+ std::unique_ptr<SocketListener> _serverListener;
+ std::unique_ptr<EndToEndHandler> _handler;
+};
+
+} // namespace crossdock
+} // namespace jaegertracing
+
+#endif // JAEGERTRACING_CROSSDOCK_SERVER_H
diff --git a/src/jaegertracing/jaeger-client-cpp/crossdock/docker-compose.yml b/src/jaegertracing/jaeger-client-cpp/crossdock/docker-compose.yml
new file mode 100644
index 000000000..550f0799f
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/crossdock/docker-compose.yml
@@ -0,0 +1,68 @@
+version: '2'
+
+services:
+ crossdock:
+ image: crossdock/crossdock
+ links:
+ - test_driver
+ - go
+ - cpp-udp
+ - cpp-http
+ environment:
+ - WAIT_FOR=test_driver,go,cpp-udp,cpp-http
+ - WAIT_FOR_TIMEOUT=60s
+
+ - CALL_TIMEOUT=60s
+
+ - AXIS_CLIENT=go
+ - AXIS_S1NAME=go,cpp-udp
+ - AXIS_SAMPLED=true,false
+ - AXIS_S2NAME=go,cpp-udp
+ - AXIS_S2TRANSPORT=http
+ - AXIS_S3NAME=go,cpp-udp
+ - AXIS_S3TRANSPORT=http
+
+ - BEHAVIOR_TRACE=client,s1name,sampled,s2name,s2transport,s3name,s3transport
+
+ - AXIS_TESTDRIVER=test_driver
+ - AXIS_SERVICES=cpp-udp,cpp-http
+
+ - BEHAVIOR_ENDTOEND=testdriver,services
+
+ - REPORT=compact
+
+ go:
+ image: jaegertracing/xdock-go
+ ports:
+ - "8080-8082"
+
+ cpp-udp:
+ depends_on:
+ - test_driver
+ build:
+ context: $PWD
+ dockerfile: crossdock/Dockerfile
+ ports:
+ - "8080-8082"
+ environment:
+ - SENDER=udp
+
+ cpp-http:
+ depends_on:
+ - test_driver
+ build:
+ context: $PWD
+ dockerfile: crossdock/Dockerfile
+ ports:
+ - "8080-8082"
+ environment:
+ - SENDER=http
+
+ test_driver:
+ image: jaegertracing/test-driver
+ depends_on:
+ - jaeger-query
+ - jaeger-collector
+ - jaeger-agent
+ ports:
+ - "8080"
diff --git a/src/jaegertracing/jaeger-client-cpp/examples/App.cpp b/src/jaegertracing/jaeger-client-cpp/examples/App.cpp
new file mode 100644
index 000000000..f7df8a2af
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/examples/App.cpp
@@ -0,0 +1,45 @@
+#include <iostream>
+
+#include <yaml-cpp/yaml.h>
+
+#include <jaegertracing/Tracer.h>
+
+namespace {
+
+void setUpTracer(const char* configFilePath)
+{
+ auto configYAML = YAML::LoadFile(configFilePath);
+ auto config = jaegertracing::Config::parse(configYAML);
+ auto tracer = jaegertracing::Tracer::make(
+ "example-service", config, jaegertracing::logging::consoleLogger());
+ opentracing::Tracer::InitGlobal(
+ std::static_pointer_cast<opentracing::Tracer>(tracer));
+}
+
+void tracedSubroutine(const std::unique_ptr<opentracing::Span>& parentSpan)
+{
+ auto span = opentracing::Tracer::Global()->StartSpan(
+ "tracedSubroutine", { opentracing::ChildOf(&parentSpan->context()) });
+}
+
+void tracedFunction()
+{
+ auto span = opentracing::Tracer::Global()->StartSpan("tracedFunction");
+ tracedSubroutine(span);
+}
+
+} // anonymous namespace
+
+int main(int argc, char* argv[])
+{
+ if (argc < 2) {
+ std::cerr << "usage: " << argv[0] << " <config-yaml-path>\n";
+ return 1;
+ }
+ setUpTracer(argv[1]);
+ tracedFunction();
+ // Not stricly necessary to close tracer, but might flush any buffered
+ // spans. See more details in opentracing::Tracer::Close() documentation.
+ opentracing::Tracer::Global()->Close();
+ return 0;
+}
diff --git a/src/jaegertracing/jaeger-client-cpp/examples/config.yml b/src/jaegertracing/jaeger-client-cpp/examples/config.yml
new file mode 100644
index 000000000..340eb5110
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/examples/config.yml
@@ -0,0 +1,6 @@
+disabled: false
+reporter:
+ logSpans: true
+sampler:
+ type: const
+ param: 1
diff --git a/src/jaegertracing/jaeger-client-cpp/idl/.gitignore b/src/jaegertracing/jaeger-client-cpp/idl/.gitignore
new file mode 100644
index 000000000..5eaf37d73
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/idl/.gitignore
@@ -0,0 +1,6 @@
+.idea/
+gen-go/
+gen-java/
+gen-nodejs/
+gen-py.tornado/
+gen-cpp/
diff --git a/src/jaegertracing/jaeger-client-cpp/idl/.travis.yml b/src/jaegertracing/jaeger-client-cpp/idl/.travis.yml
new file mode 100644
index 000000000..8418b117b
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/idl/.travis.yml
@@ -0,0 +1,10 @@
+sudo: required
+
+services:
+ - docker
+
+before_install:
+ - docker version
+
+script:
+ - make test-ci
diff --git a/src/jaegertracing/jaeger-client-cpp/idl/CONTRIBUTING.md b/src/jaegertracing/jaeger-client-cpp/idl/CONTRIBUTING.md
new file mode 100644
index 000000000..088e5f7a8
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/idl/CONTRIBUTING.md
@@ -0,0 +1,117 @@
+# How to Contribute to Jaeger
+
+We'd love your help!
+
+Jaeger is [Apache 2.0 licensed](LICENSE) and accepts contributions via GitHub
+pull requests. This document outlines some of the conventions on development
+workflow, commit message formatting, contact points and other resources to make
+it easier to get your contribution accepted.
+
+We gratefully welcome improvements to documentation as well as to code.
+
+# Certificate of Origin
+
+By contributing to this project you agree to the [Developer Certificate of
+Origin](https://developercertificate.org/) (DCO). This document was created
+by the Linux Kernel community and is a simple statement that you, as a
+contributor, have the legal right to make the contribution. See the [DCO](DCO)
+file for details.
+
+## Making A Change
+
+*Before making any significant changes, please [open an
+issue](https://github.com/uber/jaeger/issues).* Discussing your proposed
+changes ahead of time will make the contribution process smooth for everyone.
+
+Once we've discussed your changes and you've got your code ready, make sure
+that tests are passing (`make test-ci`) and open your PR. Your
+pull request is most likely to be accepted if:
+
+* It has a [good commit
+ message](http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html).
+* Each commit must be signed by the author ([see below](#sign-your-work)).
+
+## License
+
+By contributing your code, you agree to license your contribution under the terms
+of the [Apache License](LICENSE).
+
+If you are adding a new file it should have a header like below.
+
+```
+# Copyright (c) 2017 The Jaeger Authors.
+#
+# 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.
+```
+
+## Sign your work
+
+The sign-off is a simple line at the end of the explanation for the
+patch, which certifies that you wrote it or otherwise have the right to
+pass it on as an open-source patch. The rules are pretty simple: if you
+can certify the below (from
+[developercertificate.org](http://developercertificate.org/)):
+
+```
+Developer Certificate of Origin
+Version 1.1
+
+Copyright (C) 2004, 2006 The Linux Foundation and its contributors.
+660 York Street, Suite 102,
+San Francisco, CA 94110 USA
+
+Everyone is permitted to copy and distribute verbatim copies of this
+license document, but changing it is not allowed.
+
+
+Developer's Certificate of Origin 1.1
+
+By making a contribution to this project, I certify that:
+
+(a) The contribution was created in whole or in part by me and I
+ have the right to submit it under the open source license
+ indicated in the file; or
+
+(b) The contribution is based upon previous work that, to the best
+ of my knowledge, is covered under an appropriate open source
+ license and I have the right under that license to submit that
+ work with modifications, whether created in whole or in part
+ by me, under the same open source license (unless I am
+ permitted to submit under a different license), as indicated
+ in the file; or
+
+(c) The contribution was provided directly to me by some other
+ person who certified (a), (b) or (c) and I have not modified
+ it.
+
+(d) I understand and agree that this project and the contribution
+ are public and that a record of the contribution (including all
+ personal information I submit with it, including my sign-off) is
+ maintained indefinitely and may be redistributed consistent with
+ this project or the open source license(s) involved.
+```
+
+then you just add a line to every git commit message:
+
+ Signed-off-by: Joe Smith <joe@gmail.com>
+
+using your real name (sorry, no pseudonyms or anonymous contributions.)
+
+You can add the sign off when creating the git commit via `git commit -s`.
+
+If you want this to be automatic you can set up some aliases:
+
+```
+git config --add alias.amend "commit -s --amend"
+git config --add alias.c "commit -s"
+```
diff --git a/src/jaegertracing/jaeger-client-cpp/idl/DCO b/src/jaegertracing/jaeger-client-cpp/idl/DCO
new file mode 100644
index 000000000..068953d4b
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/idl/DCO
@@ -0,0 +1,37 @@
+Developer Certificate of Origin
+Version 1.1
+
+Copyright (C) 2004, 2006 The Linux Foundation and its contributors.
+660 York Street, Suite 102,
+San Francisco, CA 94110 USA
+
+Everyone is permitted to copy and distribute verbatim copies of this
+license document, but changing it is not allowed.
+
+
+Developer's Certificate of Origin 1.1
+
+By making a contribution to this project, I certify that:
+
+(a) The contribution was created in whole or in part by me and I
+ have the right to submit it under the open source license
+ indicated in the file; or
+
+(b) The contribution is based upon previous work that, to the best
+ of my knowledge, is covered under an appropriate open source
+ license and I have the right under that license to submit that
+ work with modifications, whether created in whole or in part
+ by me, under the same open source license (unless I am
+ permitted to submit under a different license), as indicated
+ in the file; or
+
+(c) The contribution was provided directly to me by some other
+ person who certified (a), (b) or (c) and I have not modified
+ it.
+
+(d) I understand and agree that this project and the contribution
+ are public and that a record of the contribution (including all
+ personal information I submit with it, including my sign-off) is
+ maintained indefinitely and may be redistributed consistent with
+ this project or the open source license(s) involved.
+
diff --git a/src/jaegertracing/jaeger-client-cpp/idl/LICENSE b/src/jaegertracing/jaeger-client-cpp/idl/LICENSE
new file mode 100644
index 000000000..261eeb9e9
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/idl/LICENSE
@@ -0,0 +1,201 @@
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright [yyyy] [name of copyright owner]
+
+ 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.
diff --git a/src/jaegertracing/jaeger-client-cpp/idl/Makefile b/src/jaegertracing/jaeger-client-cpp/idl/Makefile
new file mode 100644
index 000000000..f267cdcbf
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/idl/Makefile
@@ -0,0 +1,39 @@
+
+THRIFT_VER=0.9.2
+THRIFT_IMG=thrift:$(THRIFT_VER)
+THRIFT=docker run -u $(shell id -u) -v "${PWD}:/data" $(THRIFT_IMG) thrift
+
+SWAGGER_VER=0.12.0
+SWAGGER_IMAGE=quay.io/goswagger/swagger:$(SWAGGER_VER)
+SWAGGER=docker run --rm -it -u ${shell id -u} -v "${PWD}:/go/src/${PROJECT_ROOT}" -w /go/src/${PROJECT_ROOT} $(SWAGGER_IMAGE)
+
+THRIFT_GO_ARGS=thrift_import="github.com/apache/thrift/lib/go/thrift"
+THRIFT_PY_ARGS=new_style,tornado
+THRIFT_JAVA_ARGS=private-members
+THRIFT_PHP_ARGS=psr4
+
+THRIFT_GEN=--gen go:$(THRIFT_GO_ARGS) --gen py:$(THRIFT_PY_ARGS) --gen java:$(THRIFT_JAVA_ARGS) --gen js:node --gen cpp --gen php:$(THRIFT_PHP_ARGS)
+THRIFT_CMD=$(THRIFT) -o /data $(THRIFT_GEN)
+
+THRIFT_FILES=agent.thrift jaeger.thrift sampling.thrift zipkincore.thrift crossdock/tracetest.thrift \
+ baggage.thrift dependency.thrift aggregation_validator.thrift
+
+test-ci: thrift swagger-validate
+
+swagger-validate:
+ $(SWAGGER) validate ./swagger/zipkin2-api.yaml
+
+clean:
+ rm -rf gen-* || true
+
+thrift: thrift-image clean $(THRIFT_FILES)
+
+$(THRIFT_FILES):
+ @echo Compiling $@
+ $(THRIFT_CMD) /data/thrift/$@
+
+thrift-image:
+ docker pull $(THRIFT_IMG)
+ $(THRIFT) -version
+
+.PHONY: test-ci clean thrift thrift-image $(THRIFT_FILES) swagger-validate
diff --git a/src/jaegertracing/jaeger-client-cpp/idl/README.md b/src/jaegertracing/jaeger-client-cpp/idl/README.md
new file mode 100644
index 000000000..05344439a
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/idl/README.md
@@ -0,0 +1,15 @@
+# jaeger-idl [![Build Status][ci-img]][ci]
+
+A set of shared data model definitions used by Jaeger components.
+
+## Contributing
+
+See [CONTRIBUTING](./CONTRIBUTING.md).
+
+## License
+
+[Apache 2.0 License](./LICENSE).
+
+
+[ci-img]: https://travis-ci.org/jaegertracing/jaeger-idl.svg?branch=master
+[ci]: https://travis-ci.org/jaegertracing/jaeger-idl
diff --git a/src/jaegertracing/jaeger-client-cpp/idl/swagger/zipkin2-api.yaml b/src/jaegertracing/jaeger-client-cpp/idl/swagger/zipkin2-api.yaml
new file mode 100644
index 000000000..f97c3f15b
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/idl/swagger/zipkin2-api.yaml
@@ -0,0 +1,415 @@
+swagger: "2.0"
+info:
+ version: "1.0.0"
+ title: Zipkin API
+ description: |
+ Zipkin's v2 api currently includes a POST endpoint that can receive spans.
+host: localhost:9411
+basePath: /api/v2
+schemes:
+ - http
+ - https
+consumes:
+ - application/json
+paths:
+ /services:
+ get:
+ description: |
+ Returns a list of all service names associated with span endpoints.
+ responses:
+ 200:
+ description: Succes
+ schema:
+ type: array
+ items:
+ type: string
+ 400:
+ description: Bad Request Error
+ /spans:
+ get:
+ description: Get all the span names recorded by a particular service
+ parameters:
+ - name: serviceName
+ in: query
+ required: true
+ description: |
+ Ex favstar (required) - Lower-case label of a node in the service
+ graph. The /services endpoint enumerates possible input values.
+ type: string
+ responses:
+ 200:
+ description: OK
+ schema:
+ type: array
+ items:
+ type: string
+ 400:
+ description: Bad Request Error
+ post:
+ description: |
+ Uploads a list of spans encoded per content-type, for example json.
+ consumes:
+ - application/json
+ produces: []
+ parameters:
+ - name: spans
+ in: body
+ description: A list of spans that belong to any trace.
+ required: true
+ schema:
+ $ref: "#/definitions/ListOfSpans"
+ responses:
+ 202:
+ description: Accepted
+ /traces:
+ get:
+ description: |
+ Invoking this request retrieves traces matching the below filters.
+
+ Results should be filtered against endTs, subject to limit and
+ lookback. For example, if endTs is 10:20 today, limit is 10, and
+ lookback is 7 days, traces returned should be those nearest to 10:20
+ today, not 10:20 a week ago.
+
+ Time units of endTs and lookback are milliseconds as opposed to
+ microseconds, the grain of Span.timestamp. Milliseconds is a more
+ familiar and supported granularity for query, index and windowing
+ functions
+ parameters:
+ - name: serviceName
+ in: query
+ required: false
+ description: |
+ Ex favstar (required) - Lower-case label of a node in the service
+ graph. The /services endpoint enumerates possible input values.
+ type: string
+ - name: spanName
+ in: query
+ required: false
+ description: |
+ Ex get - name of a span in a trace.
+ Only return traces that contains spans with this name.
+ type: string
+ - name: annotationQuery
+ in: query
+ type: string
+ required: false
+ description: |
+ Ex. `http.uri=/foo and retried` - If key/value (has an `=`),
+ constrains against Span.tags entres. If just a word, constrains
+ against Span.annotations[].value or Span.tags[].key. Any values are
+ AND against eachother. This means a span in the trace must match
+ all of these.
+ - name: minDuration
+ in: query
+ type: integer
+ description: |
+ Ex. 100000 (for 100ms). Only return traces whose `Span.duration` is
+ greater than or equal to minDuration microseconds.
+ - name: maxDuration
+ in: query
+ type: integer
+ description: |
+ Only return traces whose Span.duration is less than or equal to
+ `maxDuration` microseconds. Only valid with minDuration.
+ - name: endTs
+ in: query
+ type: integer
+ format: int64
+ description: |
+ Only return traces where all Span.timestamp are at or before this
+ time in epoch milliseconds. Defaults to current time.
+ - name: lookback
+ type: integer
+ format: int64
+ in: query
+ description: |
+ Only return traces where all Span.timestamp are at or after (endTs
+ - * lookback) in milliseconds. Defaults to endTs, limited to a
+ system parameter QUERY_LOOKBACK
+ - name: limit
+ in: query
+ default: 10
+ type: integer
+ description: |
+ Maximum number of traces to return. Defaults to 10
+ responses:
+ 200:
+ description: OK
+ schema:
+ $ref: "#/definitions/ListOfTraces"
+ /trace/{traceId}:
+ get:
+ parameters:
+ - name: traceId
+ in: path
+ required: true
+ type: string
+ maxLength: 32
+ minLength: 16
+ pattern: "[a-z0-9]{16,32}"
+ description: |
+ Trace identifier, set on all spans within it.
+
+ Encoded as 16 or 32 lowercase hex characters corresponding to 64 or 128 bits.
+ For example, a 128bit trace ID looks like 4e441824ec2b6a44ffdc9bb9a6453df3
+ responses:
+ 200:
+ description: OK
+ schema:
+ $ref: "#/definitions/Trace"
+ 404:
+ description: "`traceId` not found"
+ /dependencies:
+ get:
+ description: |
+ Returns service links derived from spans.
+ parameters:
+ - name: endTs
+ in: query
+ description: |
+ only return links from spans where `Span.timestamp` are at or before
+ this time in epoch milliseconds.
+ required: true
+ type: integer
+ format: int64
+ - name: lookback
+ in: query
+ description: |
+ only return links where all Span.timestamp are at or after
+ (`endTs - * lookback`) in milliseconds. Defaults to `endTs`, limited
+ to a system parameter `QUERY_LOOKBACK`
+ type: integer
+ format: int64
+ responses:
+ 200:
+ description: OK
+ schema:
+ type: array
+ title: ListOfDependencyLinks
+ items:
+ $ref: "#/definitions/DependencyLink"
+definitions:
+ Endpoint:
+ type: object
+ title: Endpoint
+ description: The network context of a node in the service graph
+ properties:
+ serviceName:
+ type: string
+ description: |
+ Lower-case label of this node in the service graph, such as "favstar". Leave
+ absent if unknown.
+
+ This is a primary label for trace lookup and aggregation, so it should be
+ intuitive and consistent. Many use a name from service discovery.
+ ipv4:
+ type: string
+ format: ipv4
+ description: |
+ The text representation of the primary IPv4 address associated with this
+ a connection. Ex. 192.168.99.100 Absent if unknown.
+ ipv6:
+ type: string
+ format: ipv6
+ description: |
+ The text representation of the primary IPv6 address associated with this
+ a connection. Ex. 2001:db8::c001 Absent if unknown.
+
+ Prefer using the ipv4 field for mapped addresses.
+ port:
+ type: integer
+ description: |
+ Depending on context, this could be a listen port or the client-side of a
+ socket. Absent if unknown
+ Annotation:
+ title: Annotation
+ type: object
+ description: |
+ Associates an event that explains latency with a timestamp.
+ Unlike log statements, annotations are often codes. Ex. "ws" for WireSend
+
+ Zipkin v1 core annotations such as "cs" and "sr" have been replaced with
+ Span.Kind, which interprets timestamp and duration.
+ properties:
+ timestamp:
+ type: integer
+ description: |
+ Epoch **microseconds** of this event.
+
+ For example, 1502787600000000 corresponds to 2017-08-15 09:00 UTC
+
+ This value should be set directly by instrumentation, using the most precise
+ value possible. For example, gettimeofday or multiplying epoch millis by 1000.
+ value:
+ type: string
+ description: |
+ Usually a short tag indicating an event, like "error"
+
+ While possible to add larger data, such as garbage collection details, low
+ cardinality event names both keep the size of spans down and also are easy
+ to search against.
+ Tags:
+ type: object
+ title: Tags
+ description: |
+ Adds context to a span, for search, viewing and analysis.
+
+ For example, a key "your_app.version" would let you lookup traces by version.
+ A tag "sql.query" isn't searchable, but it can help in debugging when viewing
+ a trace.
+ additionalProperties:
+ type: string
+ ListOfSpans:
+ title: ListOfSpans
+ description: 'A list of spans with possibly different trace ids, in no particular order'
+ type: array
+ items:
+ $ref: "#/definitions/Span"
+ Trace:
+ title: Trace
+ type: array
+ description: 'List of spans who have the same trace ID.'
+ items:
+ $ref: "#/definitions/Span"
+ ListOfTraces:
+ title: ListOfTraces
+ type: array
+ items:
+ $ref: "#/definitions/Trace"
+ Span:
+ title: Span
+ type: object
+ required:
+ - traceId
+ - id
+ properties:
+ traceId:
+ type: string
+ maxLength: 32
+ minLength: 16
+ pattern: "[a-z0-9]{16,32}"
+ description: |
+ Randomly generated, unique identifier for a trace, set on all spans within it.
+
+ Encoded as 16 or 32 lowercase hex characters corresponding to 64 or 128 bits.
+ For example, a 128bit trace ID looks like 4e441824ec2b6a44ffdc9bb9a6453df3
+ name:
+ type: string
+ description: |
+ The logical operation this span represents in lowercase (e.g. rpc method).
+ Leave absent if unknown.
+
+ As these are lookup labels, take care to ensure names are low cardinality.
+ For example, do not embed variables into the name.
+ parentId:
+ type: string
+ pattern: "[a-z0-9]{16}"
+ maxLength: 16
+ minLength: 16
+ description: 'The parent span ID or absent if this the root span in a trace.'
+ id:
+ type: string
+ pattern: "[a-z0-9]{16}"
+ maxLength: 16
+ minLength: 16
+ description: |
+ Unique 64bit identifier for this operation within the trace.
+
+ Encoded as 16 lowercase hex characters. For example ffdc9bb9a6453df3
+ kind:
+ type: string
+ enum:
+ - CLIENT
+ - SERVER
+ - PRODUCER
+ - CONSUMER
+ description: |
+ When present, clarifies timestamp, duration and remoteEndpoint. When
+ absent, the span is local or incomplete. Unlike client and server,
+ there is no direct critical path latency relationship between producer
+ and consumer spans.
+
+ * `CLIENT`
+ * timestamp - The moment a request was sent (formerly "cs")
+ * duration - When present indicates when a response was received (formerly "cr")
+ * remoteEndpoint - Represents the server. Leave serviceName absent if unknown.
+ * `SERVER`
+ * timestamp - The moment a request was received (formerly "sr")
+ * duration - When present indicates when a response was sent (formerly "ss")
+ * remoteEndpoint - Represents the client. Leave serviceName absent if unknown.
+ * `PRODUCER`
+ * timestamp - The moment a message was sent to a destination (formerly "ms")
+ * duration - When present represents delay sending the message, such as batching.
+ * remoteEndpoint - Represents the broker. Leave serviceName absent if unknown.
+ * `CONSUMER`
+ * timestamp - The moment a message was received from an origin (formerly "mr")
+ * duration - When present represents delay consuming the message, such as from backlog.
+ * remoteEndpoint - Represents the broker. Leave serviceName absent if unknown.
+ timestamp:
+ type: integer
+ format: int64
+ description: |
+ Epoch **microseconds** of the start of this span, possibly absent if incomplete.
+
+ For example, 1502787600000000 corresponds to 2017-08-15 09:00 UTC
+
+ This value should be set directly by instrumentation, using the most precise
+ value possible. For example, gettimeofday or multiplying epoch millis by 1000.
+
+ There are three known edge-cases where this could be reported absent.
+ * A span was allocated but never started (ex not yet received a timestamp)
+ * The span's start event was lost
+ * Data about a completed span (ex tags) were sent after the fact
+ duration:
+ type: integer
+ format: int64
+ minimum: 1
+ description: |
+ Duration in **microseconds** of the critical path, if known. Durations of less
+ than one are rounded up. Duration of children can be longer than their parents
+ due to asynchronous operations.
+
+ For example 150 milliseconds is 150000 microseconds.
+ debug:
+ type: boolean
+ description: |
+ True is a request to store this span even if it overrides sampling policy.
+
+ This is true when the `X-B3-Flags` header has a value of 1.
+ shared:
+ type: boolean
+ description: 'True if we are contributing to a span started by another tracer (ex on a different host).'
+ localEndpoint:
+ $ref: "#/definitions/Endpoint"
+ description: |
+ The host that recorded this span, primarily for query by service name.
+
+ Instrumentation should always record this. Usually, absent implies late data.
+ The IP address corresponding to this is usually the site local or advertised
+ service address. When present, the port indicates the listen port.
+ remoteEndpoint:
+ $ref: "#/definitions/Endpoint"
+ description: |
+ When an RPC (or messaging) span, indicates the other side of the connection.
+ annotations:
+ type: array
+ uniqueItems: true
+ items:
+ $ref: '#/definitions/Annotation'
+ description: 'Associates events that explain latency with the time they happened.'
+ tags:
+ $ref: '#/definitions/Tags'
+ description: 'Tags give your span context for search, viewing and analysis.'
+ DependencyLink:
+ title: DependencyLink
+ type: object
+ properties:
+ parent:
+ type: string
+ child:
+ type: string
+ callCount:
+ type: integer
+ errorCount:
+ type: integer \ No newline at end of file
diff --git a/src/jaegertracing/jaeger-client-cpp/idl/thrift/agent.thrift b/src/jaegertracing/jaeger-client-cpp/idl/thrift/agent.thrift
new file mode 100644
index 000000000..b7c152bda
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/idl/thrift/agent.thrift
@@ -0,0 +1,26 @@
+# Copyright (c) 2016 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.
+
+include "jaeger.thrift"
+include "zipkincore.thrift"
+
+namespace cpp jaegertracing.agent.thrift
+namespace java io.jaegertracing.agent.thrift
+namespace php Jaeger.Thrift.Agent
+namespace netcore Jaeger.Thrift.Agent
+
+service Agent {
+ oneway void emitZipkinBatch(1: list<zipkincore.Span> spans)
+ oneway void emitBatch(1: jaeger.Batch batch)
+}
diff --git a/src/jaegertracing/jaeger-client-cpp/idl/thrift/aggregation_validator.thrift b/src/jaegertracing/jaeger-client-cpp/idl/thrift/aggregation_validator.thrift
new file mode 100644
index 000000000..733d97432
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/idl/thrift/aggregation_validator.thrift
@@ -0,0 +1,28 @@
+# 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.
+
+namespace cpp jaegertracing.thrift
+namespace java io.jaegertracing.thriftjava
+namespace php Jaeger.Thrift.Agent
+namespace netcore Jaeger.Thrift.Agent
+
+# ValidateTraceResponse returns ok when a trace has been written to redis.
+struct ValidateTraceResponse {
+ 1: required bool ok
+ 2: required i64 traceCount
+}
+
+service AggregationValidator {
+ ValidateTraceResponse validateTrace(1: required string traceId)
+}
diff --git a/src/jaegertracing/jaeger-client-cpp/idl/thrift/baggage.thrift b/src/jaegertracing/jaeger-client-cpp/idl/thrift/baggage.thrift
new file mode 100644
index 000000000..56a27a128
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/idl/thrift/baggage.thrift
@@ -0,0 +1,33 @@
+# 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.
+
+namespace cpp jaegertracing.thrift
+namespace java io.jaegertracing.thriftjava
+namespace php Jaeger.Thrift.Agent
+namespace netcore Jaeger.Thrift.Agent
+
+# BaggageRestriction contains the baggage key and the maximum length of the baggage value.
+struct BaggageRestriction {
+ 1: required string baggageKey
+ 2: required i32 maxValueLength
+}
+
+service BaggageRestrictionManager {
+ /**
+ * getBaggageRestrictions retrieves the baggage restrictions for a specific service.
+ * Usually, baggageRestrictions apply to all services however there may be situations
+ * where a baggageKey might only be allowed to be set by a specific service.
+ */
+ list<BaggageRestriction> getBaggageRestrictions(1: string serviceName)
+}
diff --git a/src/jaegertracing/jaeger-client-cpp/idl/thrift/crossdock/tracetest.thrift b/src/jaegertracing/jaeger-client-cpp/idl/thrift/crossdock/tracetest.thrift
new file mode 100644
index 000000000..d923b1029
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/idl/thrift/crossdock/tracetest.thrift
@@ -0,0 +1,64 @@
+# Copyright (c) 2016 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.
+
+namespace cpp jaegertracing.crossdock.thrift
+namespace java io.jaegertracing.crossdock.thrift
+namespace php Jaeger.Thrift.Crossdock
+namespace netcore Jaeger.Thrift.Crossdock
+
+enum Transport { HTTP, TCHANNEL, DUMMY }
+
+struct Downstream {
+ 1: required string serviceName
+ 2: required string serverRole
+ 3: required string host
+ 4: required string port
+ 5: required Transport transport
+ 6: optional Downstream downstream
+}
+
+struct StartTraceRequest {
+ 1: required string serverRole // role of the server (always S1)
+ 2: required bool sampled
+ 3: required string baggage
+ 4: required Downstream downstream
+}
+
+struct JoinTraceRequest {
+ 1: required string serverRole // role of the server, S2 or S3
+ 2: optional Downstream downstream
+}
+
+struct ObservedSpan {
+ 1: required string traceId
+ 2: required bool sampled
+ 3: required string baggage
+}
+
+/**
+ * Each server must include the information about the span it observed.
+ * It can only be omitted from the response if notImplementedError field is not empty.
+ * If the server was instructed to make a downstream call, it must embed the
+ * downstream response in its own response.
+ */
+struct TraceResponse {
+ 1: optional ObservedSpan span
+ 2: optional TraceResponse downstream
+ 3: required string notImplementedError
+}
+
+service TracedService {
+ TraceResponse startTrace(1: StartTraceRequest request)
+ TraceResponse joinTrace(1: JoinTraceRequest request)
+}
diff --git a/src/jaegertracing/jaeger-client-cpp/idl/thrift/dependency.thrift b/src/jaegertracing/jaeger-client-cpp/idl/thrift/dependency.thrift
new file mode 100644
index 000000000..781e1c4a5
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/idl/thrift/dependency.thrift
@@ -0,0 +1,37 @@
+# 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.
+
+namespace cpp jaegertracing.thrift
+namespace java io.jaegertracing.thriftjava
+namespace php Jaeger.Thrift.Agent
+namespace netcore Jaeger.Thrift.Agent
+
+struct DependencyLink {
+ // parent service name (caller)
+ 1: required string parent
+ // child service name (callee)
+ 2: required string child
+ // calls made during the duration of this link
+ 4: required i64 callCount
+}
+
+// An aggregate representation of services paired with every service they call.
+struct Dependencies {
+ 1: required list<DependencyLink> links
+}
+
+service Dependency {
+ Dependencies getDependenciesForTrace(1: required string traceId)
+ oneway void saveDependencies(1: Dependencies dependencies)
+}
diff --git a/src/jaegertracing/jaeger-client-cpp/idl/thrift/jaeger.thrift b/src/jaegertracing/jaeger-client-cpp/idl/thrift/jaeger.thrift
new file mode 100644
index 000000000..96cc751d9
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/idl/thrift/jaeger.thrift
@@ -0,0 +1,84 @@
+# Copyright (c) 2016 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.
+
+namespace cpp jaegertracing.thrift
+namespace java io.jaegertracing.thriftjava
+namespace php Jaeger.Thrift
+namespace netcore Jaeger.Thrift
+
+# TagType denotes the type of a Tag's value.
+enum TagType { STRING, DOUBLE, BOOL, LONG, BINARY }
+
+# Tag is a basic strongly typed key/value pair. It has been flattened to reduce the use of pointers in golang
+struct Tag {
+ 1: required string key
+ 2: required TagType vType
+ 3: optional string vStr
+ 4: optional double vDouble
+ 5: optional bool vBool
+ 6: optional i64 vLong
+ 7: optional binary vBinary
+}
+
+# Log is a timed even with an arbitrary set of tags.
+struct Log {
+ 1: required i64 timestamp
+ 2: required list<Tag> fields
+}
+
+enum SpanRefType { CHILD_OF, FOLLOWS_FROM }
+
+# SpanRef describes causal relationship of the current span to another span (e.g. 'child-of')
+struct SpanRef {
+ 1: required SpanRefType refType
+ 2: required i64 traceIdLow
+ 3: required i64 traceIdHigh
+ 4: required i64 spanId
+}
+
+# Span represents a named unit of work performed by a service.
+struct Span {
+ 1: required i64 traceIdLow # the least significant 64 bits of a traceID
+ 2: required i64 traceIdHigh # the most significant 64 bits of a traceID; 0 when only 64bit IDs are used
+ 3: required i64 spanId # unique span id (only unique within a given trace)
+ 4: required i64 parentSpanId # since nearly all spans will have parents spans, CHILD_OF refs do not have to be explicit
+ 5: required string operationName
+ 6: optional list<SpanRef> references # causal references to other spans
+ 7: required i32 flags # a bit field used to propagate sampling decisions. 1 signifies a SAMPLED span, 2 signifies a DEBUG span.
+ 8: required i64 startTime
+ 9: required i64 duration
+ 10: optional list<Tag> tags
+ 11: optional list<Log> logs
+}
+
+# Process describes the traced process/service that emits spans.
+struct Process {
+ 1: required string serviceName
+ 2: optional list<Tag> tags
+}
+
+# Batch is a collection of spans reported out of process.
+struct Batch {
+ 1: required Process process
+ 2: required list<Span> spans
+}
+
+# BatchSubmitResponse is the response on submitting a batch.
+struct BatchSubmitResponse {
+ 1: required bool ok # The Collector's client is expected to only log (or emit a counter) when not ok equals false
+}
+
+service Collector {
+ list<BatchSubmitResponse> submitBatches(1: list<Batch> batches)
+}
diff --git a/src/jaegertracing/jaeger-client-cpp/idl/thrift/sampling.thrift b/src/jaegertracing/jaeger-client-cpp/idl/thrift/sampling.thrift
new file mode 100644
index 000000000..7215eaa71
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/idl/thrift/sampling.thrift
@@ -0,0 +1,58 @@
+# Copyright (c) 2016 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.
+
+namespace cpp jaegertracing.sampling_manager.thrift
+namespace java io.jaegertracing.thrift.sampling_manager
+namespace php Jaeger.Thrift.Agent
+namespace netcore Jaeger.Thrift.Agent
+
+enum SamplingStrategyType { PROBABILISTIC, RATE_LIMITING }
+
+// ProbabilisticSamplingStrategy randomly samples a fixed percentage of all traces.
+struct ProbabilisticSamplingStrategy {
+ 1: required double samplingRate // percentage expressed as rate (0..1]
+}
+
+// RateLimitingStrategy samples traces with a rate that does not exceed specified number of traces per second.
+// The recommended implementation approach is leaky bucket.
+struct RateLimitingSamplingStrategy {
+ 1: required i16 maxTracesPerSecond
+}
+
+// OperationSamplingStrategy defines a sampling strategy that randomly samples a fixed percentage of operation traces.
+struct OperationSamplingStrategy {
+ 1: required string operation
+ 2: required ProbabilisticSamplingStrategy probabilisticSampling
+}
+
+// PerOperationSamplingStrategies defines a sampling strategy per each operation name in the service
+// with a guaranteed lower bound per second. Once the lower bound is met, operations are randomly sampled
+// at a fixed percentage.
+struct PerOperationSamplingStrategies {
+ 1: required double defaultSamplingProbability
+ 2: required double defaultLowerBoundTracesPerSecond
+ 3: required list<OperationSamplingStrategy> perOperationStrategies
+ 4: optional double defaultUpperBoundTracesPerSecond
+}
+
+struct SamplingStrategyResponse {
+ 1: required SamplingStrategyType strategyType
+ 2: optional ProbabilisticSamplingStrategy probabilisticSampling
+ 3: optional RateLimitingSamplingStrategy rateLimitingSampling
+ 4: optional PerOperationSamplingStrategies operationSampling
+}
+
+service SamplingManager {
+ SamplingStrategyResponse getSamplingStrategy(1: string serviceName)
+}
diff --git a/src/jaegertracing/jaeger-client-cpp/idl/thrift/zipkincore.thrift b/src/jaegertracing/jaeger-client-cpp/idl/thrift/zipkincore.thrift
new file mode 100644
index 000000000..0bcc7b989
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/idl/thrift/zipkincore.thrift
@@ -0,0 +1,344 @@
+# Copyright 2012 Twitter 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.
+namespace cpp twitter.zipkin.thrift
+namespace java com.twitter.zipkin.thriftjava
+#@namespace scala com.twitter.zipkin.thriftscala
+namespace rb Zipkin
+namespace php Jaeger.Thrift.Agent.Zipkin
+namespace netcore Jaeger.Thrift.Agent.Zipkin
+
+#************** Annotation.value **************
+/**
+ * The client sent ("cs") a request to a server. There is only one send per
+ * span. For example, if there's a transport error, each attempt can be logged
+ * as a WIRE_SEND annotation.
+ *
+ * If chunking is involved, each chunk could be logged as a separate
+ * CLIENT_SEND_FRAGMENT in the same span.
+ *
+ * Annotation.host is not the server. It is the host which logged the send
+ * event, almost always the client. When logging CLIENT_SEND, instrumentation
+ * should also log the SERVER_ADDR.
+ */
+const string CLIENT_SEND = "cs"
+/**
+ * The client received ("cr") a response from a server. There is only one
+ * receive per span. For example, if duplicate responses were received, each
+ * can be logged as a WIRE_RECV annotation.
+ *
+ * If chunking is involved, each chunk could be logged as a separate
+ * CLIENT_RECV_FRAGMENT in the same span.
+ *
+ * Annotation.host is not the server. It is the host which logged the receive
+ * event, almost always the client. The actual endpoint of the server is
+ * recorded separately as SERVER_ADDR when CLIENT_SEND is logged.
+ */
+const string CLIENT_RECV = "cr"
+/**
+ * The server sent ("ss") a response to a client. There is only one response
+ * per span. If there's a transport error, each attempt can be logged as a
+ * WIRE_SEND annotation.
+ *
+ * Typically, a trace ends with a server send, so the last timestamp of a trace
+ * is often the timestamp of the root span's server send.
+ *
+ * If chunking is involved, each chunk could be logged as a separate
+ * SERVER_SEND_FRAGMENT in the same span.
+ *
+ * Annotation.host is not the client. It is the host which logged the send
+ * event, almost always the server. The actual endpoint of the client is
+ * recorded separately as CLIENT_ADDR when SERVER_RECV is logged.
+ */
+const string SERVER_SEND = "ss"
+/**
+ * The server received ("sr") a request from a client. There is only one
+ * request per span. For example, if duplicate responses were received, each
+ * can be logged as a WIRE_RECV annotation.
+ *
+ * Typically, a trace starts with a server receive, so the first timestamp of a
+ * trace is often the timestamp of the root span's server receive.
+ *
+ * If chunking is involved, each chunk could be logged as a separate
+ * SERVER_RECV_FRAGMENT in the same span.
+ *
+ * Annotation.host is not the client. It is the host which logged the receive
+ * event, almost always the server. When logging SERVER_RECV, instrumentation
+ * should also log the CLIENT_ADDR.
+ */
+const string SERVER_RECV = "sr"
+/**
+ * Message send ("ms") is a request to send a message to a destination, usually
+ * a broker. This may be the only annotation in a messaging span. If WIRE_SEND
+ * exists in the same span, it follows this moment and clarifies delays sending
+ * the message, such as batching.
+ *
+ * Unlike RPC annotations like CLIENT_SEND, messaging spans never share a span
+ * ID. For example, "ms" should always be the parent of "mr".
+ *
+ * Annotation.host is not the destination, it is the host which logged the send
+ * event: the producer. When annotating MESSAGE_SEND, instrumentation should
+ * also tag the MESSAGE_ADDR.
+ */
+const string MESSAGE_SEND = "ms"
+/**
+ * A consumer received ("mr") a message from a broker. This may be the only
+ * annotation in a messaging span. If WIRE_RECV exists in the same span, it
+ * precedes this moment and clarifies any local queuing delay.
+ *
+ * Unlike RPC annotations like SERVER_RECV, messaging spans never share a span
+ * ID. For example, "mr" should always be a child of "ms" unless it is a root
+ * span.
+ *
+ * Annotation.host is not the broker, it is the host which logged the receive
+ * event: the consumer. When annotating MESSAGE_RECV, instrumentation should
+ * also tag the MESSAGE_ADDR.
+ */
+const string MESSAGE_RECV = "mr"
+/**
+ * Optionally logs an attempt to send a message on the wire. Multiple wire send
+ * events could indicate network retries. A lag between client or server send
+ * and wire send might indicate queuing or processing delay.
+ */
+const string WIRE_SEND = "ws"
+/**
+ * Optionally logs an attempt to receive a message from the wire. Multiple wire
+ * receive events could indicate network retries. A lag between wire receive
+ * and client or server receive might indicate queuing or processing delay.
+ */
+const string WIRE_RECV = "wr"
+/**
+ * Optionally logs progress of a (CLIENT_SEND, WIRE_SEND). For example, this
+ * could be one chunk in a chunked request.
+ */
+const string CLIENT_SEND_FRAGMENT = "csf"
+/**
+ * Optionally logs progress of a (CLIENT_RECV, WIRE_RECV). For example, this
+ * could be one chunk in a chunked response.
+ */
+const string CLIENT_RECV_FRAGMENT = "crf"
+/**
+ * Optionally logs progress of a (SERVER_SEND, WIRE_SEND). For example, this
+ * could be one chunk in a chunked response.
+ */
+const string SERVER_SEND_FRAGMENT = "ssf"
+/**
+ * Optionally logs progress of a (SERVER_RECV, WIRE_RECV). For example, this
+ * could be one chunk in a chunked request.
+ */
+const string SERVER_RECV_FRAGMENT = "srf"
+
+#***** BinaryAnnotation.key ******
+/**
+ * The value of "lc" is the component or namespace of a local span.
+ *
+ * BinaryAnnotation.host adds service context needed to support queries.
+ *
+ * Local Component("lc") supports three key features: flagging, query by
+ * service and filtering Span.name by namespace.
+ *
+ * While structurally the same, local spans are fundamentally different than
+ * RPC spans in how they should be interpreted. For example, zipkin v1 tools
+ * center on RPC latency and service graphs. Root local-spans are neither
+ * indicative of critical path RPC latency, nor have impact on the shape of a
+ * service graph. By flagging with "lc", tools can special-case local spans.
+ *
+ * Zipkin v1 Spans are unqueryable unless they can be indexed by service name.
+ * The only path to a service name is by (Binary)?Annotation.host.serviceName.
+ * By logging "lc", a local span can be queried even if no other annotations
+ * are logged.
+ *
+ * The value of "lc" is the namespace of Span.name. For example, it might be
+ * "finatra2", for a span named "bootstrap". "lc" allows you to resolves
+ * conflicts for the same Span.name, for example "finatra/bootstrap" vs
+ * "finch/bootstrap". Using local component, you'd search for spans named
+ * "bootstrap" where "lc=finch"
+ */
+const string LOCAL_COMPONENT = "lc"
+
+#***** BinaryAnnotation.key where value = [1] and annotation_type = BOOL ******
+/**
+ * Indicates a client address ("ca") in a span. Most likely, there's only one.
+ * Multiple addresses are possible when a client changes its ip or port within
+ * a span.
+ */
+const string CLIENT_ADDR = "ca"
+/**
+ * Indicates a server address ("sa") in a span. Most likely, there's only one.
+ * Multiple addresses are possible when a client is redirected, or fails to a
+ * different server ip or port.
+ */
+const string SERVER_ADDR = "sa"
+/**
+ * Indicates the remote address of a messaging span, usually the broker.
+ */
+const string MESSAGE_ADDR = "ma"
+
+/**
+ * Indicates the network context of a service recording an annotation with two
+ * exceptions.
+ *
+ * When a BinaryAnnotation, and key is CLIENT_ADDR or SERVER_ADDR,
+ * the endpoint indicates the source or destination of an RPC. This exception
+ * allows zipkin to display network context of uninstrumented services, or
+ * clients such as web browsers.
+ */
+struct Endpoint {
+ /**
+ * IPv4 host address packed into 4 bytes.
+ *
+ * Ex for the ip 1.2.3.4, it would be (1 << 24) | (2 << 16) | (3 << 8) | 4
+ */
+ 1: i32 ipv4
+ /**
+ * IPv4 port
+ *
+ * Note: this is to be treated as an unsigned integer, so watch for negatives.
+ *
+ * Conventionally, when the port isn't known, port = 0.
+ */
+ 2: i16 port
+ /**
+ * Service name in lowercase, such as "memcache" or "zipkin-web"
+ *
+ * Conventionally, when the service name isn't known, service_name = "unknown".
+ */
+ 3: string service_name
+ /**
+ * IPv6 host address packed into 16 bytes. Ex Inet6Address.getBytes()
+ */
+ 4: optional binary ipv6
+}
+
+/**
+ * An annotation is similar to a log statement. It includes a host field which
+ * allows these events to be attributed properly, and also aggregatable.
+ */
+struct Annotation {
+ /**
+ * Microseconds from epoch.
+ *
+ * This value should use the most precise value possible. For example,
+ * gettimeofday or syncing nanoTime against a tick of currentTimeMillis.
+ */
+ 1: i64 timestamp
+ 2: string value // what happened at the timestamp?
+ /**
+ * Always the host that recorded the event. By specifying the host you allow
+ * rollup of all events (such as client requests to a service) by IP address.
+ */
+ 3: optional Endpoint host
+ // don't reuse 4: optional i32 OBSOLETE_duration // how long did the operation take? microseconds
+}
+
+enum AnnotationType { BOOL, BYTES, I16, I32, I64, DOUBLE, STRING }
+
+/**
+ * Binary annotations are tags applied to a Span to give it context. For
+ * example, a binary annotation of "http.uri" could the path to a resource in a
+ * RPC call.
+ *
+ * Binary annotations of type STRING are always queryable, though more a
+ * historical implementation detail than a structural concern.
+ *
+ * Binary annotations can repeat, and vary on the host. Similar to Annotation,
+ * the host indicates who logged the event. This allows you to tell the
+ * difference between the client and server side of the same key. For example,
+ * the key "http.uri" might be different on the client and server side due to
+ * rewriting, like "/api/v1/myresource" vs "/myresource. Via the host field,
+ * you can see the different points of view, which often help in debugging.
+ */
+struct BinaryAnnotation {
+ 1: string key,
+ 2: binary value,
+ 3: AnnotationType annotation_type,
+ /**
+ * The host that recorded tag, which allows you to differentiate between
+ * multiple tags with the same key. There are two exceptions to this.
+ *
+ * When the key is CLIENT_ADDR or SERVER_ADDR, host indicates the source or
+ * destination of an RPC. This exception allows zipkin to display network
+ * context of uninstrumented services, or clients such as web browsers.
+ */
+ 4: optional Endpoint host
+}
+
+/**
+ * A trace is a series of spans (often RPC calls) which form a latency tree.
+ *
+ * The root span is where trace_id = id and parent_id = Nil. The root span is
+ * usually the longest interval in the trace, starting with a SERVER_RECV
+ * annotation and ending with a SERVER_SEND.
+ */
+struct Span {
+ 1: i64 trace_id # unique trace id, use for all spans in trace
+ /**
+ * Span name in lowercase, rpc method for example
+ *
+ * Conventionally, when the span name isn't known, name = "unknown".
+ */
+ 3: string name,
+ 4: i64 id, # unique span id, only used for this span
+ 5: optional i64 parent_id, # parent span id
+ 6: list<Annotation> annotations, # all annotations/events that occured, sorted by timestamp
+ 8: list<BinaryAnnotation> binary_annotations # any binary annotations
+ 9: optional bool debug = 0 # if true, we DEMAND that this span passes all samplers
+ /**
+ * Microseconds from epoch of the creation of this span.
+ *
+ * This value should be set directly by instrumentation, using the most
+ * precise value possible. For example, gettimeofday or syncing nanoTime
+ * against a tick of currentTimeMillis.
+ *
+ * For compatibilty with instrumentation that precede this field, collectors
+ * or span stores can derive this via Annotation.timestamp.
+ * For example, SERVER_RECV.timestamp or CLIENT_SEND.timestamp.
+ *
+ * This field is optional for compatibility with old data: first-party span
+ * stores are expected to support this at time of introduction.
+ */
+ 10: optional i64 timestamp,
+ /**
+ * Measurement of duration in microseconds, used to support queries.
+ *
+ * This value should be set directly, where possible. Doing so encourages
+ * precise measurement decoupled from problems of clocks, such as skew or NTP
+ * updates causing time to move backwards.
+ *
+ * For compatibilty with instrumentation that precede this field, collectors
+ * or span stores can derive this by subtracting Annotation.timestamp.
+ * For example, SERVER_SEND.timestamp - SERVER_RECV.timestamp.
+ *
+ * If this field is persisted as unset, zipkin will continue to work, except
+ * duration query support will be implementation-specific. Similarly, setting
+ * this field non-atomically is implementation-specific.
+ *
+ * This field is i64 vs i32 to support spans longer than 35 minutes.
+ */
+ 11: optional i64 duration
+ /**
+ * Optional unique 8-byte additional identifier for a trace. If non zero, this
+ * means the trace uses 128 bit traceIds instead of 64 bit.
+ */
+ 12: optional i64 trace_id_high
+}
+
+# define TChannel service
+
+struct Response {
+ 1: required bool ok
+}
+
+service ZipkinCollector {
+ list<Response> submitZipkinBatch(1: list<Span> spans)
+}
diff --git a/src/jaegertracing/jaeger-client-cpp/scripts/build-plugin.sh b/src/jaegertracing/jaeger-client-cpp/scripts/build-plugin.sh
new file mode 100755
index 000000000..192c824d0
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/scripts/build-plugin.sh
@@ -0,0 +1,32 @@
+#!/bin/bash
+
+set -e
+
+function main() {
+ local project_dir
+ project_dir="$(git rev-parse --show-toplevel)"
+
+ mkdir -p build
+ cd build
+ export CFLAGS="$CFLAGS -march=x86-64"
+ export CXXFLAGS="$CXXFLAGS -march=x86-64"
+
+ cat <<EOF > export.map
+{
+ global:
+ OpenTracingMakeTracerFactory;
+ local: *;
+};
+EOF
+
+ cmake -DCMAKE_BUILD_TYPE=Release \
+ -DJAEGERTRACING_PLUGIN=ON \
+ -DBUILD_TESTING=ON \
+ -DHUNTER_CONFIGURATION_TYPES=Release \
+ ..
+ make -j3
+ mv libjaegertracing_plugin.so /libjaegertracing_plugin.so
+ ./DynamicallyLoadTracerTest /libjaegertracing_plugin.so
+}
+
+main
diff --git a/src/jaegertracing/jaeger-client-cpp/scripts/build.sh b/src/jaegertracing/jaeger-client-cpp/scripts/build.sh
new file mode 100755
index 000000000..e12e11c97
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/scripts/build.sh
@@ -0,0 +1,40 @@
+#!/bin/bash
+
+# Based on https://github.com/codecov/example-cpp11-cmake/blob/master/run_build.sh.
+
+set -e
+
+RED='\033[0;31m'
+BLUE='\033[0;34m'
+NO_COLOR='\033[0m'
+GREEN='\033[0;32m'
+
+function info() {
+ echo -e "${GREEN}$1${NO_COLOR}"
+}
+
+function working() {
+ echo -e "${BLUE}$1${NO_COLOR}"
+}
+
+function main() {
+ local project_dir
+ project_dir=$(git rev-parse --show-toplevel)
+ cd "$project_dir"
+
+ mkdir -p build
+ cd build
+ cmake ${CMAKE_OPTIONS} ..
+ make -j3 UnitTest
+ info "Running tests..."
+ ./UnitTest
+ working "All tests compiled and passed"
+
+ set -x
+ if ! [[ "${CMAKE_OPTIONS}" =~ "-DJAEGERTRACING_BUILD_CROSSDOCK=ON" ]]; then
+ exit 0
+ fi
+ make crossdock-fresh
+}
+
+main
diff --git a/src/jaegertracing/jaeger-client-cpp/scripts/clang-format.sh b/src/jaegertracing/jaeger-client-cpp/scripts/clang-format.sh
new file mode 100755
index 000000000..3f1a43830
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/scripts/clang-format.sh
@@ -0,0 +1,21 @@
+#!/bin/bash
+
+function main() {
+ local project_dir
+ project_dir=$(git rev-parse --show-toplevel)
+ cd "$project_dir" || exit 1
+
+ local srcs
+ srcs=$(git ls-files src crossdock |
+ grep -E -v 'thrift-gen' |
+ grep -E '\.(cpp|h)$')
+
+ local cmd
+ for src in $srcs; do
+ cmd="clang-format -i $src"
+ echo "$cmd"
+ eval "$cmd"
+ done
+}
+
+main
diff --git a/src/jaegertracing/jaeger-client-cpp/scripts/clang-tidy.sh b/src/jaegertracing/jaeger-client-cpp/scripts/clang-tidy.sh
new file mode 100755
index 000000000..2946db95c
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/scripts/clang-tidy.sh
@@ -0,0 +1,23 @@
+#!/bin/bash
+
+function main() {
+ local project_dir
+ project_dir=$(git rev-parse --show-toplevel)
+ cd "$project_dir" || exit 1
+
+ local srcs
+ srcs=$(git ls-files src crossdock |
+ grep -E -v 'thrift-gen|Test\.cpp' |
+ grep -E '\.cpp$')
+
+ local cmd
+ for src in $srcs; do
+ cmd="clang-tidy -p=build"
+ cmd+=" -checks=\"-clang-diagnostic-unused-command-line-argument\" "
+ cmd+=" $src"
+ echo "$cmd"
+ eval "$cmd"
+ done
+}
+
+main
diff --git a/src/jaegertracing/jaeger-client-cpp/scripts/thrift-gen.patch b/src/jaegertracing/jaeger-client-cpp/scripts/thrift-gen.patch
new file mode 100644
index 000000000..aa484888e
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/scripts/thrift-gen.patch
@@ -0,0 +1,115 @@
+diff --git a/src/jaegertracing/thrift-gen/tracetest_types.cpp b/src/jaegertracing/thrift-gen/tracetest_types.cpp
+index cb7199e..ceb7a20 100644
+--- a/src/jaegertracing/thrift-gen/tracetest_types.cpp
++++ b/src/jaegertracing/thrift-gen/tracetest_types.cpp
+@@ -60,7 +60,7 @@ void Downstream::__set_transport(const Transport::type val) {
+ this->transport = val;
+ }
+
+-void Downstream::__set_downstream(const Downstream& val) {
++void Downstream::__set_downstream(const std::shared_ptr<Downstream>& val) {
+ this->downstream = val;
+ __isset.downstream = true;
+ }
+@@ -141,7 +141,7 @@ uint32_t Downstream::read(::apache::thrift::protocol::TProtocol* iprot) {
+ break;
+ case 6:
+ if (ftype == ::apache::thrift::protocol::T_STRUCT) {
+- xfer += this->downstream.read(iprot);
++ xfer += this->downstream->read(iprot);
+ this->__isset.downstream = true;
+ } else {
+ xfer += iprot->skip(ftype);
+@@ -196,7 +196,7 @@ uint32_t Downstream::write(::apache::thrift::protocol::TProtocol* oprot) const {
+
+ if (this->__isset.downstream) {
+ xfer += oprot->writeFieldBegin("downstream", ::apache::thrift::protocol::T_STRUCT, 6);
+- xfer += this->downstream.write(oprot);
++ xfer += this->downstream->write(oprot);
+ xfer += oprot->writeFieldEnd();
+ }
+ xfer += oprot->writeFieldStop();
+@@ -672,7 +672,7 @@ void TraceResponse::__set_span(const ObservedSpan& val) {
+ __isset.span = true;
+ }
+
+-void TraceResponse::__set_downstream(const TraceResponse& val) {
++void TraceResponse::__set_downstream(const std::shared_ptr<TraceResponse>& val) {
+ this->downstream = val;
+ __isset.downstream = true;
+ }
+@@ -719,7 +719,7 @@ uint32_t TraceResponse::read(::apache::thrift::protocol::TProtocol* iprot) {
+ break;
+ case 2:
+ if (ftype == ::apache::thrift::protocol::T_STRUCT) {
+- xfer += this->downstream.read(iprot);
++ xfer += this->downstream->read(iprot);
+ this->__isset.downstream = true;
+ } else {
+ xfer += iprot->skip(ftype);
+@@ -759,7 +759,7 @@ uint32_t TraceResponse::write(::apache::thrift::protocol::TProtocol* oprot) cons
+ }
+ if (this->__isset.downstream) {
+ xfer += oprot->writeFieldBegin("downstream", ::apache::thrift::protocol::T_STRUCT, 2);
+- xfer += this->downstream.write(oprot);
++ xfer += this->downstream->write(oprot);
+ xfer += oprot->writeFieldEnd();
+ }
+ xfer += oprot->writeFieldBegin("notImplementedError", ::apache::thrift::protocol::T_STRING, 3);
+diff --git a/src/jaegertracing/thrift-gen/tracetest_types.h b/src/jaegertracing/thrift-gen/tracetest_types.h
+index 5a0e6c9..a44f3a3 100644
+--- a/src/jaegertracing/thrift-gen/tracetest_types.h
++++ b/src/jaegertracing/thrift-gen/tracetest_types.h
+@@ -61,7 +61,7 @@ class Downstream : public virtual ::apache::thrift::TBase {
+ std::string host;
+ std::string port;
+ Transport::type transport;
+- Downstream downstream;
++ std::shared_ptr<Downstream> downstream;
+
+ _Downstream__isset __isset;
+
+@@ -75,7 +75,7 @@ class Downstream : public virtual ::apache::thrift::TBase {
+
+ void __set_transport(const Transport::type val);
+
+- void __set_downstream(const Downstream& val);
++ void __set_downstream(const std::shared_ptr<Downstream>& val);
+
+ bool operator == (const Downstream & rhs) const
+ {
+@@ -91,7 +91,7 @@ class Downstream : public virtual ::apache::thrift::TBase {
+ return false;
+ if (__isset.downstream != rhs.__isset.downstream)
+ return false;
+- else if (__isset.downstream && !(downstream == rhs.downstream))
++ else if (__isset.downstream && !(*downstream == *rhs.downstream))
+ return false;
+ return true;
+ }
+@@ -273,14 +273,14 @@ class TraceResponse : public virtual ::apache::thrift::TBase {
+
+ virtual ~TraceResponse() throw();
+ ObservedSpan span;
+- TraceResponse downstream;
++ std::shared_ptr<TraceResponse> downstream;
+ std::string notImplementedError;
+
+ _TraceResponse__isset __isset;
+
+ void __set_span(const ObservedSpan& val);
+
+- void __set_downstream(const TraceResponse& val);
++ void __set_downstream(const std::shared_ptr<TraceResponse>& val);
+
+ void __set_notImplementedError(const std::string& val);
+
+@@ -292,7 +292,7 @@ class TraceResponse : public virtual ::apache::thrift::TBase {
+ return false;
+ if (__isset.downstream != rhs.__isset.downstream)
+ return false;
+- else if (__isset.downstream && !(downstream == rhs.downstream))
++ else if (__isset.downstream && !(*downstream == *rhs.downstream))
+ return false;
+ if (!(notImplementedError == rhs.notImplementedError))
+ return false;
diff --git a/src/jaegertracing/jaeger-client-cpp/scripts/update-license.py b/src/jaegertracing/jaeger-client-cpp/scripts/update-license.py
new file mode 100644
index 000000000..bd51168d0
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/scripts/update-license.py
@@ -0,0 +1,100 @@
+from __future__ import (
+ absolute_import, print_function, division, unicode_literals
+)
+
+import logging
+import re
+import sys
+from datetime import datetime
+
+logging.basicConfig(level=logging.DEBUG)
+logger = logging.getLogger(__name__)
+
+CURRENT_YEAR = datetime.today().year
+
+LICENSE_BLOB = """Copyright (c) %d 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.""" % CURRENT_YEAR
+
+
+def comment_block(license_blob):
+ lines = ['/*\n']
+ lines += [(' * ' + l).rstrip() + '\n'
+ for l in license_blob.split('\n')]
+ lines.append(' */\n')
+ return lines
+
+
+LICENSE_BLOB_LINES_CPP = comment_block(LICENSE_BLOB)
+
+COPYRIGHT_RE = re.compile(r'Copyright \(c\) (\d+)', re.I)
+
+
+def update_cpp_license(name, force=False):
+ with open(name) as f:
+ orig_lines = list(f)
+ lines = list(orig_lines)
+
+ found = False
+ changed = False
+ for i, line in enumerate(lines[:5]):
+ m = COPYRIGHT_RE.search(line)
+ if not m:
+ continue
+
+ found = True
+ year = int(m.group(1))
+ if year == CURRENT_YEAR:
+ break
+
+ new_line = COPYRIGHT_RE.sub('Copyright (c) %d' % CURRENT_YEAR, line)
+ assert line != new_line, ('Could not change year in: %s' % line)
+ lines[i] = new_line
+ changed = True
+ break
+
+ if not found:
+ if 'Code generated by' in lines[0]:
+ lines[1:1] = ['\n'] + LICENSE_BLOB_LINES_CPP
+ else:
+ lines[0:0] = LICENSE_BLOB_LINES_CPP + ['\n']
+ changed = True
+
+ if changed:
+ with open(name, 'w') as f:
+ for line in lines:
+ f.write(line)
+ print(name)
+
+
+def main():
+ if len(sys.argv) == 1:
+ print('USAGE: %s FILE ...' % sys.argv[0])
+ sys.exit(1)
+
+ for name in sys.argv[1:]:
+ if name.endswith('.cpp') or \
+ name.endswith('.h') or \
+ name.endswith('.h.in'):
+ try:
+ update_cpp_license(name)
+ except Exception as error:
+ logger.error('Failed to process file %s', name)
+ logger.exception(error)
+ raise error
+ else:
+ raise NotImplementedError('Unsupported file type: %s' % name)
+
+
+if __name__ == "__main__":
+ main()
diff --git a/src/jaegertracing/jaeger-client-cpp/scripts/update-licenses.sh b/src/jaegertracing/jaeger-client-cpp/scripts/update-licenses.sh
new file mode 100755
index 000000000..e912743ca
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/scripts/update-licenses.sh
@@ -0,0 +1,8 @@
+#!/bin/bash
+
+set -e
+
+python scripts/update-license.py $(git ls-files "*\.cpp" "*\.h" |
+ grep -v thrift-gen |
+ grep -v tracetest) \
+ src/jaegertracing/Constants.h.in
diff --git a/src/jaegertracing/jaeger-client-cpp/scripts/upload-coverage.sh b/src/jaegertracing/jaeger-client-cpp/scripts/upload-coverage.sh
new file mode 100755
index 000000000..a31da5772
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/scripts/upload-coverage.sh
@@ -0,0 +1,42 @@
+#!/bin/bash
+
+# Copyright (c) 2018 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.
+
+set -e
+
+function main() {
+ set -x
+ if ! [[ "${CMAKE_OPTIONS}" =~ "-DJAEGERTRACING_COVERAGE=ON" ]]; then
+ exit 0
+ fi
+ unset -x
+
+ local project_dir
+ project_dir=$(git rev-parse --show-toplevel)
+ cd "$project_dir" || exit 1
+
+ local gcov_tool
+ case "$CC" in
+ gcc*) gcov_tool=${CC/gcc/gcov}
+ ;;
+ *) gcov_tool="$project_dir/scripts/llvm-gcov.sh"
+ ;;
+ esac
+ find build -name '*.gcno' -exec "$gcov_tool" {} \;
+ bash <(curl -s https://codecov.io/bash) || \
+ echo "Codecov did not collect coverage reports"
+}
+
+main
diff --git a/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/Compilers.h b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/Compilers.h
new file mode 100644
index 000000000..9345d08ad
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/Compilers.h
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2019 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_COMPILERS_H
+#define JAEGERTRACING_COMPILERS_H
+
+#ifdef _MSC_VER
+
+#pragma warning(push)
+#pragma warning(disable : 4251)
+#pragma warning(disable : 4275)
+
+// Define NOMINMAX to inhibit definition of Macros min(a,b) and max(a,b) in
+// windows.h
+#ifndef NOMINMAX
+#define NOMINMAX
+#endif
+
+#endif // _MSC_VER
+
+#endif // JAEGERTRACING_COMPILERS_H
diff --git a/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/Config.cpp b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/Config.cpp
new file mode 100644
index 000000000..abf28bccb
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/Config.cpp
@@ -0,0 +1,67 @@
+/*
+ * 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.
+ */
+
+#include "jaegertracing/Config.h"
+#include "jaegertracing/samplers/Config.h"
+#include "jaegertracing/utils/EnvVariable.h"
+
+namespace jaegertracing {
+
+constexpr const char* Config::kJAEGER_SERVICE_NAME_ENV_PROP;
+constexpr const char* Config::kJAEGER_TAGS_ENV_PROP;
+constexpr const char* Config::kJAEGER_JAEGER_DISABLED_ENV_PROP;
+
+void Config::fromEnv()
+{
+ const auto disabled =
+ utils::EnvVariable::getBoolVariable(kJAEGER_JAEGER_DISABLED_ENV_PROP);
+ if (disabled.first) {
+ _disabled = disabled.second;
+ }
+
+ const auto serviceName =
+ utils::EnvVariable::getStringVariable(kJAEGER_SERVICE_NAME_ENV_PROP);
+ if (!serviceName.empty()) {
+ _serviceName = serviceName;
+ }
+
+ const auto tags =
+ utils::EnvVariable::getStringVariable(kJAEGER_TAGS_ENV_PROP);
+ if (!tags.empty()) {
+ std::string tag;
+ std::istringstream tagsStream(tags);
+ while (std::getline(tagsStream, tag, ',')) {
+
+ std::istringstream tagStream(tag);
+
+ std::string tagKey;
+ std::string tagValue;
+ if (std::getline(tagStream, tagKey, '=')) {
+ std::getline(tagStream, tagValue, '=');
+ if (std::getline(tagStream, tagValue, '=')) {
+ // error, should be logged somewhere
+ }
+ else {
+ _tags.emplace_back(tagKey, tagValue);
+ }
+ }
+ }
+ }
+ _reporter.fromEnv();
+ _sampler.fromEnv();
+}
+
+} // namespace jaegertracing
diff --git a/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/Config.h b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/Config.h
new file mode 100644
index 000000000..2c9f0a32f
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/Config.h
@@ -0,0 +1,116 @@
+/*
+ * 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_CONFIG_H
+#define JAEGERTRACING_CONFIG_H
+
+#include "jaegertracing/Compilers.h"
+#include "jaegertracing/Constants.h"
+#include "jaegertracing/Tag.h"
+#include "jaegertracing/baggage/RestrictionsConfig.h"
+#include "jaegertracing/propagation/HeadersConfig.h"
+#include "jaegertracing/reporters/Config.h"
+#include "jaegertracing/samplers/Config.h"
+#include "jaegertracing/utils/YAML.h"
+
+namespace jaegertracing {
+
+class Config {
+ public:
+
+ static constexpr auto kJAEGER_SERVICE_NAME_ENV_PROP = "JAEGER_SERVICE_NAME";
+ static constexpr auto kJAEGER_TAGS_ENV_PROP = "JAEGER_TAGS";
+ static constexpr auto kJAEGER_JAEGER_DISABLED_ENV_PROP = "JAEGER_DISABLED";
+
+#ifdef JAEGERTRACING_WITH_YAML_CPP
+
+ static Config parse(const YAML::Node& configYAML)
+ {
+ if (!configYAML.IsDefined() || !configYAML.IsMap()) {
+ return Config();
+ }
+
+ const auto serviceName =
+ utils::yaml::findOrDefault<std::string>(configYAML, "service_name", "");
+
+ const auto disabled =
+ utils::yaml::findOrDefault<bool>(configYAML, "disabled", false);
+ const auto samplerNode = configYAML["sampler"];
+ const auto sampler = samplers::Config::parse(samplerNode);
+ const auto reporterNode = configYAML["reporter"];
+ const auto reporter = reporters::Config::parse(reporterNode);
+ const auto headersNode = configYAML["headers"];
+ const auto headers = propagation::HeadersConfig::parse(headersNode);
+ const auto baggageRestrictionsNode = configYAML["baggage_restrictions"];
+ const auto baggageRestrictions =
+ baggage::RestrictionsConfig::parse(baggageRestrictionsNode);
+ return Config(
+ disabled, sampler, reporter, headers, baggageRestrictions, serviceName);
+ }
+
+#endif // JAEGERTRACING_WITH_YAML_CPP
+
+ explicit Config(bool disabled = false,
+ const samplers::Config& sampler = samplers::Config(),
+ const reporters::Config& reporter = reporters::Config(),
+ const propagation::HeadersConfig& headers =
+ propagation::HeadersConfig(),
+ const baggage::RestrictionsConfig& baggageRestrictions =
+ baggage::RestrictionsConfig(),
+ const std::string& serviceName = "",
+ const std::vector<Tag>& tags = std::vector<Tag>())
+ : _disabled(disabled)
+ , _serviceName(serviceName)
+ , _tags(tags)
+ , _sampler(sampler)
+ , _reporter(reporter)
+ , _headers(headers)
+ , _baggageRestrictions(baggageRestrictions)
+ {
+ }
+
+ bool disabled() const { return _disabled; }
+
+ const samplers::Config& sampler() const { return _sampler; }
+
+ const reporters::Config& reporter() const { return _reporter; }
+
+ const propagation::HeadersConfig& headers() const { return _headers; }
+
+ const baggage::RestrictionsConfig& baggageRestrictions() const
+ {
+ return _baggageRestrictions;
+ }
+
+ const std::string& serviceName() const { return _serviceName; }
+
+ const std::vector<Tag>& tags() const { return _tags; }
+
+ void fromEnv();
+
+ private:
+ bool _disabled;
+ std::string _serviceName;
+ std::vector< Tag > _tags;
+ samplers::Config _sampler;
+ reporters::Config _reporter;
+ propagation::HeadersConfig _headers;
+ baggage::RestrictionsConfig _baggageRestrictions;
+};
+
+} // namespace jaegertracing
+
+#endif // JAEGERTRACING_CONFIG_H
diff --git a/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/ConfigTest.cpp b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/ConfigTest.cpp
new file mode 100644
index 000000000..225d8e31a
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/ConfigTest.cpp
@@ -0,0 +1,195 @@
+/*
+ * 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.
+ */
+
+#include "jaegertracing/Config.h"
+#include "jaegertracing/Constants.h"
+#include "jaegertracing/propagation/HeadersConfig.h"
+#include "jaegertracing/samplers/Config.h"
+#include "jaegertracing/utils/YAML.h"
+#include "jaegertracing/testutils/EnvVariable.h"
+#include <gtest/gtest.h>
+
+#include <cstdlib>
+
+namespace jaegertracing {
+
+#ifdef JAEGERTRACING_WITH_YAML_CPP
+
+TEST(Config, testParse)
+{
+ {
+ constexpr auto kConfigYAML = R"cfg(
+disabled: true
+sampler:
+ type: probabilistic
+ param: 0.001
+reporter:
+ queueSize: 100
+ bufferFlushInterval: 10
+ logSpans: false
+ localAgentHostPort: 127.0.0.1:6831
+headers:
+ jaegerDebugHeader: debug-id
+ jaegerBaggageHeader: baggage
+ TraceContextHeaderName: trace-id
+ traceBaggageHeaderPrefix: "testctx-"
+baggage_restrictions:
+ denyBaggageOnInitializationFailure: false
+ hostPort: 127.0.0.1:5778
+ refreshInterval: 60
+)cfg";
+ const auto config = Config::parse(YAML::Load(kConfigYAML));
+ ASSERT_EQ("probabilistic", config.sampler().type());
+ ASSERT_EQ("debug-id", config.headers().jaegerDebugHeader());
+ ASSERT_EQ("baggage", config.headers().jaegerBaggageHeader());
+ ASSERT_EQ("trace-id", config.headers().traceContextHeaderName());
+ ASSERT_EQ("testctx-", config.headers().traceBaggageHeaderPrefix());
+ }
+
+ {
+ Config::parse(YAML::Load(R"cfg(
+disabled: false
+sampler: 1
+reporter: 2
+headers: 3
+baggage_restrictions: 4
+)cfg"));
+ }
+}
+
+TEST(Config, testDefaultSamplingProbability)
+{
+ ASSERT_EQ(samplers::Config::kDefaultSamplingProbability,
+ Config().sampler().param());
+}
+
+TEST(Config, testDefaultSamplingServerURL)
+{
+ ASSERT_EQ("http://127.0.0.1:5778/sampling",
+ Config().sampler().samplingServerURL());
+}
+
+TEST(Config, testZeroSamplingParam)
+{
+ {
+ constexpr auto kConfigYAML = R"cfg(
+sampler:
+ param: 0
+)cfg";
+ const auto config = Config::parse(YAML::Load(kConfigYAML));
+ ASSERT_EQ(0, config.sampler().param());
+ }
+}
+
+#endif // JAEGERTRACING_WITH_YAML_CPP
+
+TEST(Config, testFromEnv)
+{
+ std::vector<Tag> tags;
+ tags.emplace_back("hostname", std::string("foo"));
+ tags.emplace_back("my.app.version", std::string("1.2.3"));
+
+ Config config(false,
+ samplers::Config("probabilistic",
+ 0.7,
+ "http://host34:57/sampling",
+ 0,
+ samplers::Config::Clock::duration()),
+ reporters::Config(10,
+ std::chrono::milliseconds(100),
+ false,
+ "host35:77",
+ "http://host36:56568"),
+ propagation::HeadersConfig(),
+ baggage::RestrictionsConfig(),
+ "test-service",
+ tags);
+
+ config.fromEnv();
+
+ ASSERT_EQ(std::string("http://host36:56568"), config.reporter().endpoint());
+ ASSERT_EQ(std::string("host35:77"), config.reporter().localAgentHostPort());
+
+ ASSERT_EQ(10, config.reporter().queueSize());
+ ASSERT_EQ(std::chrono::milliseconds(100),
+ config.reporter().bufferFlushInterval());
+ ASSERT_EQ(false, config.reporter().logSpans());
+
+ ASSERT_EQ(.7, config.sampler().param());
+ ASSERT_EQ(std::string("probabilistic"), config.sampler().type());
+
+ testutils::EnvVariable::setEnv("JAEGER_AGENT_HOST", "host33");
+ testutils::EnvVariable::setEnv("JAEGER_AGENT_PORT", "45");
+ testutils::EnvVariable::setEnv("JAEGER_ENDPOINT", "http://host34:56567");
+
+ testutils::EnvVariable::setEnv("JAEGER_REPORTER_MAX_QUEUE_SIZE", "33");
+ testutils::EnvVariable::setEnv("JAEGER_REPORTER_FLUSH_INTERVAL", "45");
+ testutils::EnvVariable::setEnv("JAEGER_REPORTER_LOG_SPANS", "true");
+
+ testutils::EnvVariable::setEnv("JAEGER_SAMPLER_TYPE", "remote");
+ testutils::EnvVariable::setEnv("JAEGER_SAMPLER_PARAM", "0.33");
+ testutils::EnvVariable::setEnv("JAEGER_SAMPLING_ENDPOINT", "http://myagent:1234");
+
+ testutils::EnvVariable::setEnv("JAEGER_SERVICE_NAME", "AService");
+ testutils::EnvVariable::setEnv("JAEGER_TAGS", "hostname=foobar,my.app.version=4.5.6");
+
+ config.fromEnv();
+
+ ASSERT_EQ(std::string("http://host34:56567"), config.reporter().endpoint());
+ ASSERT_EQ(std::string("host33:45"), config.reporter().localAgentHostPort());
+
+ ASSERT_EQ(33, config.reporter().queueSize());
+ ASSERT_EQ(std::chrono::milliseconds(45),
+ config.reporter().bufferFlushInterval());
+ ASSERT_EQ(true, config.reporter().logSpans());
+
+ ASSERT_EQ(std::string("remote"), config.sampler().type());
+ ASSERT_EQ(0.33, config.sampler().param());
+ ASSERT_EQ(std::string("http://myagent:1234"), config.sampler().samplingServerURL());
+
+ ASSERT_EQ(std::string("AService"), config.serviceName());
+
+ std::vector<Tag> expectedTags;
+ expectedTags.emplace_back("hostname", std::string("foo"));
+ expectedTags.emplace_back("my.app.version", std::string("1.2.3"));
+ expectedTags.emplace_back("hostname", std::string("foobar"));
+ expectedTags.emplace_back("my.app.version", std::string("4.5.6"));
+ ASSERT_EQ(expectedTags, config.tags());
+
+ ASSERT_EQ(false, config.disabled());
+
+ testutils::EnvVariable::setEnv("JAEGER_DISABLED", "TRue"); // case-insensitive
+ testutils::EnvVariable::setEnv("JAEGER_AGENT_PORT", "445");
+
+ config.fromEnv();
+ ASSERT_EQ(true, config.disabled());
+ ASSERT_EQ(std::string("host33:445"),
+ config.reporter().localAgentHostPort());
+
+ testutils::EnvVariable::setEnv("JAEGER_AGENT_HOST", "");
+ testutils::EnvVariable::setEnv("JAEGER_AGENT_PORT", "");
+ testutils::EnvVariable::setEnv("JAEGER_ENDPOINT", "");
+ testutils::EnvVariable::setEnv("JAEGER_REPORTER_MAX_QUEUE_SIZE", "");
+ testutils::EnvVariable::setEnv("JAEGER_REPORTER_FLUSH_INTERVAL", "");
+ testutils::EnvVariable::setEnv("JAEGER_REPORTER_LOG_SPANS", "");
+ testutils::EnvVariable::setEnv("JAEGER_SAMPLER_PARAM", "");
+ testutils::EnvVariable::setEnv("JAEGER_SAMPLER_TYPE", "");
+ testutils::EnvVariable::setEnv("JAEGER_SERVICE_NAME", "");
+ testutils::EnvVariable::setEnv("JAEGER_TAGS", "");
+ testutils::EnvVariable::setEnv("JAEGER_DISABLED", "");
+}
+
+} // namespace jaegertracing
diff --git a/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/Constants.h b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/Constants.h
new file mode 100644
index 000000000..d79e708be
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/Constants.h
@@ -0,0 +1,43 @@
+/*
+ * 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_CONSTANTS_H
+#define JAEGERTRACING_CONSTANTS_H
+
+#define JAEGERTRACING_WITH_YAML_CPP
+
+namespace jaegertracing {
+
+static constexpr auto kJaegerClientVersion = "C++-0.6.1";
+static constexpr auto kJaegerClientVersionTagKey = "jaeger.version";
+static constexpr auto kJaegerDebugHeader = "jaeger-debug-id";
+static constexpr auto kJaegerBaggageHeader = "jaeger-baggage";
+static constexpr auto kTracerHostnameTagKey = "hostname";
+static constexpr auto kTracerIPTagKey = "ip";
+static constexpr auto kSamplerTypeTagKey = "sampler.type";
+static constexpr auto kSamplerParamTagKey = "sampler.param";
+static constexpr auto kTraceContextHeaderName = "uber-trace-id";
+static constexpr auto kTracerStateHeaderName = kTraceContextHeaderName;
+static constexpr auto kTraceBaggageHeaderPrefix = "uberctx-";
+static constexpr auto kSamplerTypeConst = "const";
+static constexpr auto kSamplerTypeRemote = "remote";
+static constexpr auto kSamplerTypeProbabilistic = "probabilistic";
+static constexpr auto kSamplerTypeRateLimiting = "ratelimiting";
+static constexpr auto kSamplerTypeLowerBound = "lowerbound";
+
+} // namespace jaegertracing
+
+#endif // JAEGERTRACING_CONSTANTS_H
diff --git a/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/Constants.h.in b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/Constants.h.in
new file mode 100644
index 000000000..c5b90f555
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/Constants.h.in
@@ -0,0 +1,43 @@
+/*
+ * 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_CONSTANTS_H
+#define JAEGERTRACING_CONSTANTS_H
+
+#cmakedefine JAEGERTRACING_WITH_YAML_CPP
+
+namespace jaegertracing {
+
+static constexpr auto kJaegerClientVersion = "C++-@PROJECT_VERSION@";
+static constexpr auto kJaegerClientVersionTagKey = "jaeger.version";
+static constexpr auto kJaegerDebugHeader = "jaeger-debug-id";
+static constexpr auto kJaegerBaggageHeader = "jaeger-baggage";
+static constexpr auto kTracerHostnameTagKey = "hostname";
+static constexpr auto kTracerIPTagKey = "ip";
+static constexpr auto kSamplerTypeTagKey = "sampler.type";
+static constexpr auto kSamplerParamTagKey = "sampler.param";
+static constexpr auto kTraceContextHeaderName = "uber-trace-id";
+static constexpr auto kTracerStateHeaderName = kTraceContextHeaderName;
+static constexpr auto kTraceBaggageHeaderPrefix = "uberctx-";
+static constexpr auto kSamplerTypeConst = "const";
+static constexpr auto kSamplerTypeRemote = "remote";
+static constexpr auto kSamplerTypeProbabilistic = "probabilistic";
+static constexpr auto kSamplerTypeRateLimiting = "ratelimiting";
+static constexpr auto kSamplerTypeLowerBound = "lowerbound";
+
+} // namespace jaegertracing
+
+#endif // JAEGERTRACING_CONSTANTS_H
diff --git a/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/DynamicLoad.cpp b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/DynamicLoad.cpp
new file mode 100644
index 000000000..6a114774a
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/DynamicLoad.cpp
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2018 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.
+ */
+#include <cassert>
+#include <cstring>
+#include <system_error>
+
+#include <opentracing/dynamic_load.h>
+
+#include "jaegertracing/Tracer.h"
+#include "jaegertracing/TracerFactory.h"
+
+static int makeTracerFactory(const char* opentracingVersion,
+ const char* opentracingABIVersion,
+ const void** errorCategory,
+ void* errorMessage,
+ void** tracerFactory)
+{
+ assert(errorCategory != nullptr);
+ assert(tracerFactory != nullptr);
+#ifndef JAEGERTRACING_WITH_YAML_CPP
+ *errorCategory =
+ static_cast<const void*>(&opentracing::dynamic_load_error_category());
+ return opentracing::dynamic_load_not_supported_error.value();
+#endif
+ if (std::strcmp(opentracingABIVersion, OPENTRACING_ABI_VERSION) != 0) {
+ *errorCategory = static_cast<const void*>(
+ &opentracing::dynamic_load_error_category());
+ return opentracing::incompatible_library_versions_error.value();
+ }
+
+ const auto jaegerTracerFactory = new (std::nothrow) jaegertracing::TracerFactory(true);
+ *tracerFactory = jaegerTracerFactory;
+ if (*tracerFactory == nullptr) {
+ *errorCategory = static_cast<const void*>(&std::generic_category());
+ return static_cast<int>(std::errc::not_enough_memory);
+ }
+
+ return 0;
+}
+
+OPENTRACING_DECLARE_IMPL_FACTORY(makeTracerFactory)
diff --git a/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/DynamicallyLoadTracerTest.cpp b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/DynamicallyLoadTracerTest.cpp
new file mode 100644
index 000000000..55db6e392
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/DynamicallyLoadTracerTest.cpp
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2018 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.
+ */
+#include <iostream>
+#include <string>
+
+#include <opentracing/dynamic_load.h>
+
+#include "jaegertracing/Constants.h"
+
+// Verify that Jaeger's shared library can be dynamically loaded and used
+// as a plugin.
+int main(int argc, char* argv[])
+{
+ if (argc != 2) {
+ std::cerr << "DynamicLoadTest <tracer-library>\n";
+ return -1;
+ }
+ const char* library = argv[1];
+ std::string errorMessage;
+ auto tracerFactoryMaybe =
+ opentracing::DynamicallyLoadTracingLibrary(library, errorMessage);
+#ifdef JAEGERTRACING_WITH_YAML_CPP
+ if (!errorMessage.empty()) {
+ std::cerr << "Failed to load tracing tracer: " << errorMessage << "\n";
+ return -1;
+ }
+ if (!tracerFactoryMaybe) {
+ std::cerr << "Failed to load tracing library: "
+ << tracerFactoryMaybe.error().message() << "\n";
+ return -1;
+ }
+#else
+ if (tracerFactoryMaybe) {
+ std::cerr << "Dynamically loading a tracing library should fail "
+ "without YAML support\n";
+ return -1;
+ }
+#endif // JAEGERTRACING_WITH_YAML_CPP
+ return 0;
+}
diff --git a/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/LogRecord.cpp b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/LogRecord.cpp
new file mode 100644
index 000000000..82748102f
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/LogRecord.cpp
@@ -0,0 +1,39 @@
+/*
+ * 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.
+ */
+
+#include "jaegertracing/LogRecord.h"
+#include "jaegertracing/thrift-gen/jaeger_types.h"
+
+namespace jaegertracing {
+void LogRecord::thrift(thrift::Log& log) const
+{
+ log.__set_timestamp(std::chrono::duration_cast<std::chrono::microseconds>(
+ _timestamp.time_since_epoch())
+ .count());
+
+ std::vector<thrift::Tag> fields;
+ fields.reserve(_fields.size());
+ std::transform(std::begin(_fields),
+ std::end(_fields),
+ std::back_inserter(fields),
+ [](const Tag& tag) {
+ thrift::Tag thriftTag;
+ tag.thrift(thriftTag);
+ return thriftTag;
+ });
+ log.__set_fields(fields);
+}
+} // namespace jaegertracing
diff --git a/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/LogRecord.h b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/LogRecord.h
new file mode 100644
index 000000000..8e67b81fd
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/LogRecord.h
@@ -0,0 +1,72 @@
+/*
+ * 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_LOGRECORD_H
+#define JAEGERTRACING_LOGRECORD_H
+
+#include "jaegertracing/Compilers.h"
+#include "jaegertracing/Tag.h"
+#include <algorithm>
+#include <chrono>
+#include <iterator>
+#include <type_traits>
+#include <vector>
+
+#include <opentracing/span.h>
+
+namespace jaegertracing {
+namespace thrift {
+class Log;
+}
+
+class LogRecord {
+ public:
+ using Clock = std::chrono::system_clock;
+
+ LogRecord()
+ : _timestamp(Clock::now())
+ {
+ }
+
+ template <typename FieldIterator>
+ LogRecord(const Clock::time_point& timestamp,
+ FieldIterator first,
+ FieldIterator last)
+ : _timestamp(timestamp)
+ , _fields(first, last)
+ {
+ }
+
+ LogRecord(const opentracing::LogRecord& other)
+ : _timestamp(other.timestamp)
+ , _fields(other.fields.begin(), other.fields.end())
+ {
+ }
+
+ const Clock::time_point& timestamp() const { return _timestamp; }
+
+ const std::vector<Tag>& fields() const { return _fields; }
+
+ void thrift(thrift::Log& log) const;
+
+ private:
+ Clock::time_point _timestamp;
+ std::vector<Tag> _fields;
+};
+
+} // namespace jaegertracing
+
+#endif // JAEGERTRACING_LOGRECORD_H
diff --git a/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/Logging.cpp b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/Logging.cpp
new file mode 100644
index 000000000..0e889b4e9
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/Logging.cpp
@@ -0,0 +1,58 @@
+/*
+ * 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.
+ */
+
+#include "jaegertracing/Logging.h"
+
+#include <iostream>
+
+namespace jaegertracing {
+namespace logging {
+namespace {
+
+class NullLogger : public Logger {
+ public:
+ void error(const std::string& /* message */) override {}
+
+ void info(const std::string& /* message */) override {}
+};
+
+class ConsoleLogger : public Logger {
+ public:
+ void error(const std::string& message) override
+ {
+ std::cerr << "ERROR: " << message << '\n';
+ }
+
+ void info(const std::string& message) override
+ {
+ std::cout << "INFO: " << message << '\n';
+ }
+};
+
+} // anonymous namespace
+
+std::unique_ptr<Logger> nullLogger()
+{
+ return std::unique_ptr<Logger>(new NullLogger());
+}
+
+std::unique_ptr<Logger> consoleLogger()
+{
+ return std::unique_ptr<Logger>(new ConsoleLogger());
+}
+
+} // namespace logging
+} // namespace jaegertracing
diff --git a/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/Logging.h b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/Logging.h
new file mode 100644
index 000000000..34b57ea52
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/Logging.h
@@ -0,0 +1,44 @@
+/*
+ * 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_LOGGING_H
+#define JAEGERTRACING_LOGGING_H
+
+#include <memory>
+#include <string>
+
+#include "jaegertracing/Compilers.h"
+
+namespace jaegertracing {
+namespace logging {
+
+class Logger {
+ public:
+ virtual ~Logger() = default;
+
+ virtual void error(const std::string& message) = 0;
+
+ virtual void info(const std::string& message) = 0;
+};
+
+std::unique_ptr<Logger> nullLogger();
+
+std::unique_ptr<Logger> consoleLogger();
+
+} // namespace logging
+} // namespace jaegertracing
+
+#endif // JAEGERTRACING_LOGGING_H
diff --git a/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/Reference.cpp b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/Reference.cpp
new file mode 100644
index 000000000..a95376a7f
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/Reference.cpp
@@ -0,0 +1,41 @@
+/*
+ * 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.
+ */
+
+#include "jaegertracing/Reference.h"
+#include "jaegertracing/thrift-gen/jaeger_types.h"
+
+namespace jaegertracing {
+void Reference::thrift(thrift::SpanRef& spanRef) const
+{
+ switch (_type) {
+ case Type::ChildOfRef: {
+ spanRef.__set_refType(thrift::SpanRefType::CHILD_OF);
+ } break;
+ case Type::FollowsFromRef: {
+ spanRef.__set_refType(thrift::SpanRefType::FOLLOWS_FROM);
+ } break;
+ default: {
+ std::ostringstream oss;
+ oss << "Invalid span reference type " << static_cast<int>(_type)
+ << ", context " << _spanContext;
+ throw std::invalid_argument(oss.str());
+ } break;
+ }
+ spanRef.__set_traceIdHigh(_spanContext.traceID().high());
+ spanRef.__set_traceIdLow(_spanContext.traceID().low());
+ spanRef.__set_spanId(_spanContext.spanID());
+}
+} // namespace jaegertracing
diff --git a/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/Reference.h b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/Reference.h
new file mode 100644
index 000000000..52277aea3
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/Reference.h
@@ -0,0 +1,56 @@
+/*
+ * 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_REFERENCE_H
+#define JAEGERTRACING_REFERENCE_H
+
+#include <sstream>
+#include <string>
+
+#include <opentracing/propagation.h>
+
+#include "jaegertracing/Compilers.h"
+#include "jaegertracing/SpanContext.h"
+
+namespace jaegertracing {
+namespace thrift {
+class SpanRef;
+}
+
+class Reference {
+ public:
+ using Type = opentracing::SpanReferenceType;
+
+ Reference(const SpanContext& spanContext, Type type)
+ : _spanContext(spanContext)
+ , _type(type)
+ {
+ }
+
+ const SpanContext& spanContext() const { return _spanContext; }
+
+ Type type() const { return _type; }
+
+ void thrift(thrift::SpanRef& spanRef) const;
+
+ private:
+ SpanContext _spanContext;
+ Type _type;
+};
+
+} // namespace jaegertracing
+
+#endif // JAEGERTRACING_REFERENCE_H
diff --git a/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/ReferenceTest.cpp b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/ReferenceTest.cpp
new file mode 100644
index 000000000..546613fa1
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/ReferenceTest.cpp
@@ -0,0 +1,39 @@
+/*
+ * 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.
+ */
+
+#include "jaegertracing/Reference.h"
+#include "jaegertracing/SpanContext.h"
+#include "jaegertracing/thrift-gen/jaeger_types.h"
+#include <gtest/gtest.h>
+#include <stdexcept>
+
+namespace jaegertracing {
+
+TEST(Reference, testThriftConversion)
+{
+ const SpanContext context;
+ const Reference childRef(context, Reference::Type::ChildOfRef);
+ thrift::SpanRef thriftChildRef;
+ ASSERT_NO_THROW(childRef.thrift(thriftChildRef));
+ const Reference followsFromRef(context, Reference::Type::FollowsFromRef);
+ thrift::SpanRef thriftFollowsFromRef;
+ ASSERT_NO_THROW(followsFromRef.thrift(thriftFollowsFromRef));
+ const Reference invalidRef(context, static_cast<Reference::Type>(-1));
+ thrift::SpanRef thriftInvalidRef;
+ ASSERT_THROW(invalidRef.thrift(thriftInvalidRef), std::invalid_argument);
+}
+
+} // namespace jaegertracing
diff --git a/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/Sender.cpp b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/Sender.cpp
new file mode 100644
index 000000000..1456bc22d
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/Sender.cpp
@@ -0,0 +1,17 @@
+/*
+ * 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.
+ */
+
+#include "jaegertracing/Sender.h"
diff --git a/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/Sender.h b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/Sender.h
new file mode 100644
index 000000000..176cfd054
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/Sender.h
@@ -0,0 +1,56 @@
+/*
+ * 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_SENDER_H
+#define JAEGERTRACING_SENDER_H
+
+#include <stdexcept>
+#include <string>
+
+#include "jaegertracing/Compilers.h"
+
+namespace jaegertracing {
+
+class Span;
+
+class Sender {
+ public:
+ class Exception : public std::runtime_error {
+ public:
+ Exception(const std::string& what, int numFailed)
+ : std::runtime_error(what)
+ , _numFailed(numFailed)
+ {
+ }
+
+ int numFailed() const { return _numFailed; }
+
+ private:
+ int _numFailed;
+ };
+
+ virtual ~Sender() = default;
+
+ virtual int append(const Span& span) = 0;
+
+ virtual int flush() = 0;
+
+ virtual void close() = 0;
+};
+
+} // namespace jaegertracing
+
+#endif //JAEGERTRACING_SENDER_H
diff --git a/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/Span.cpp b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/Span.cpp
new file mode 100644
index 000000000..3a629f4e2
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/Span.cpp
@@ -0,0 +1,221 @@
+/*
+ * 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.
+ */
+
+#include "jaegertracing/Span.h"
+#include "jaegertracing/Tracer.h"
+#include "jaegertracing/baggage/BaggageSetter.h"
+#include "jaegertracing/thrift-gen/jaeger_types.h"
+#include <cassert>
+#include <cstdint>
+#include <istream>
+#include <memory>
+#include <opentracing/value.h>
+
+namespace jaegertracing {
+namespace {
+
+struct SamplingPriorityVisitor {
+ using result_type = bool;
+
+ bool operator()(bool boolValue) const { return boolValue; }
+
+ bool operator()(double doubleValue) const { return doubleValue > 0; }
+
+ bool operator()(int64_t intValue) const { return intValue > 0; }
+
+ bool operator()(uint64_t uintValue) const { return uintValue > 0; }
+
+ bool operator()(const std::string& str) const
+ {
+ std::istringstream iss(str);
+ auto intValue = 0;
+ if (!(iss >> intValue)) {
+ return false;
+ }
+ return intValue > 0;
+ }
+
+ bool operator()(std::nullptr_t) const { return false; }
+
+ bool operator()(const char* str) const
+ {
+ return operator()(std::string(str));
+ }
+
+ template <typename OtherType>
+ bool operator()(OtherType) const
+ {
+ return false;
+ }
+};
+
+} // anonymous namespace
+
+void Span::SetBaggageItem(opentracing::string_view restrictedKey,
+ opentracing::string_view value) noexcept
+{
+ std::lock_guard<std::mutex> lock(_mutex);
+ const auto& baggageSetter = _tracer->baggageSetter();
+ auto baggage = _context.baggage();
+ baggageSetter.setBaggage(*this,
+ baggage,
+ restrictedKey,
+ value,
+ [this](std::vector<Tag>::const_iterator first,
+ std::vector<Tag>::const_iterator last) {
+ logFieldsNoLocking(SystemClock::now(), first, last);
+ });
+ _context = _context.withBaggage(baggage);
+}
+
+void Span::FinishWithOptions(
+ const opentracing::FinishSpanOptions& finishSpanOptions) noexcept
+{
+ const auto finishTimeSteady =
+ (finishSpanOptions.finish_steady_timestamp == SteadyClock::time_point())
+ ? SteadyClock::now()
+ : finishSpanOptions.finish_steady_timestamp;
+ std::shared_ptr<const Tracer> tracer;
+ {
+
+ std::lock_guard<std::mutex> lock(_mutex);
+ if (isFinished()) {
+ // Already finished, so return immediately.
+ return;
+ }
+ _duration = finishTimeSteady - _startTimeSteady;
+ if (_duration <= SteadyClock::duration()) {
+ // Enforce minimum duration of 1 tick (1ns on Linux),
+ // so isFinished() returns true
+ _duration = SteadyClock::duration(1);
+ }
+
+ tracer = _tracer;
+
+ std::copy(finishSpanOptions.log_records.begin(),
+ finishSpanOptions.log_records.end(),
+ std::back_inserter(_logs));
+ }
+
+ // Call `reportSpan` even for non-sampled traces.
+ if (tracer) {
+ tracer->reportSpan(*this);
+ }
+}
+
+const opentracing::Tracer& Span::tracer() const noexcept
+{
+ std::lock_guard<std::mutex> lock(_mutex);
+ if (_tracer) {
+ return *_tracer;
+ }
+ auto tracer = opentracing::Tracer::Global();
+ assert(tracer);
+ return *tracer;
+}
+
+std::string Span::serviceName() const noexcept
+{
+ std::lock_guard<std::mutex> lock(_mutex);
+ return serviceNameNoLock();
+}
+
+std::string Span::serviceNameNoLock() const noexcept
+{
+ if (!_tracer) {
+ return std::string();
+ }
+ return _tracer->serviceName();
+}
+
+void Span::setSamplingPriority(const opentracing::Value& value)
+{
+ SamplingPriorityVisitor visitor;
+ const auto priority = opentracing::Value::visit(value, visitor);
+
+ std::lock_guard<std::mutex> lock(_mutex);
+ auto newFlags = _context.flags();
+ if (priority) {
+ newFlags |= static_cast<unsigned char>(SpanContext::Flag::kSampled) |
+ static_cast<unsigned char>(SpanContext::Flag::kDebug);
+ }
+ else {
+ newFlags &= ~static_cast<unsigned char>(SpanContext::Flag::kSampled);
+ }
+
+ _context = SpanContext(_context.traceID(),
+ _context.spanID(),
+ _context.parentID(),
+ newFlags,
+ _context.baggage(),
+ _context.debugID());
+}
+
+void Span::thrift(thrift::Span& span) const
+{
+ std::lock_guard<std::mutex> lock(_mutex);
+ span.__set_traceIdHigh(_context.traceID().high());
+ span.__set_traceIdLow(_context.traceID().low());
+ span.__set_spanId(_context.spanID());
+ span.__set_parentSpanId(_context.parentID());
+ span.__set_operationName(_operationName);
+
+ std::vector<thrift::SpanRef> refs;
+ refs.reserve(_references.size());
+ std::transform(std::begin(_references),
+ std::end(_references),
+ std::back_inserter(refs),
+ [](const Reference& ref) {
+ thrift::SpanRef thriftRef;
+ ref.thrift(thriftRef);
+ return thriftRef;
+ });
+ span.__set_references(refs);
+
+ span.__set_flags(_context.flags());
+ span.__set_startTime(std::chrono::duration_cast<std::chrono::microseconds>(
+ _startTimeSystem.time_since_epoch())
+ .count());
+ span.__set_duration(
+ std::chrono::duration_cast<std::chrono::microseconds>(_duration)
+ .count());
+
+ std::vector<thrift::Tag> tags;
+ tags.reserve(_tags.size());
+ std::transform(std::begin(_tags),
+ std::end(_tags),
+ std::back_inserter(tags),
+ [](const Tag& tag) {
+ thrift::Tag thriftTag;
+ tag.thrift(thriftTag);
+ return thriftTag;
+ });
+ span.__set_tags(tags);
+
+ std::vector<thrift::Log> logs;
+ logs.reserve(_logs.size());
+ std::transform(std::begin(_logs),
+ std::end(_logs),
+ std::back_inserter(logs),
+ [](const LogRecord& log) {
+ thrift::Log thriftLog;
+ log.thrift(thriftLog);
+ return thriftLog;
+ });
+ span.__set_logs(logs);
+}
+
+} // namespace jaegertracing
diff --git a/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/Span.h b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/Span.h
new file mode 100644
index 000000000..1e5c7b616
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/Span.h
@@ -0,0 +1,282 @@
+/*
+ * 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_SPAN_H
+#define JAEGERTRACING_SPAN_H
+
+#include <chrono>
+#include <memory>
+#include <mutex>
+
+#include <opentracing/span.h>
+
+#include "jaegertracing/LogRecord.h"
+#include "jaegertracing/Reference.h"
+#include "jaegertracing/SpanContext.h"
+#include "jaegertracing/Tag.h"
+
+namespace jaegertracing {
+
+class Tracer;
+
+namespace thrift {
+class Span;
+}
+
+class Span : public opentracing::Span {
+ public:
+ using SteadyClock = opentracing::SteadyClock;
+ using SystemClock = opentracing::SystemClock;
+
+ explicit Span(
+ const std::shared_ptr<const Tracer>& tracer = nullptr,
+ const SpanContext& context = SpanContext(),
+ const std::string& operationName = "",
+ const SystemClock::time_point& startTimeSystem = SystemClock::now(),
+ const SteadyClock::time_point& startTimeSteady = SteadyClock::now(),
+ const std::vector<Tag>& tags = {},
+ const std::vector<Reference>& references = {})
+ : _tracer(tracer)
+ , _context(context)
+ , _operationName(operationName)
+ , _startTimeSystem(startTimeSystem)
+ , _startTimeSteady(startTimeSteady)
+ , _duration()
+ , _tags(tags)
+ , _references(references)
+ {
+ }
+
+ Span(const Span& span)
+ {
+ std::lock(_mutex, span._mutex);
+ std::lock_guard<std::mutex> lock(_mutex, std::adopt_lock);
+ std::lock_guard<std::mutex> spanLock(span._mutex, std::adopt_lock);
+
+ _tracer = span._tracer;
+ _context = span._context;
+ _operationName = span._operationName;
+ _startTimeSystem = span._startTimeSystem;
+ _startTimeSteady = span._startTimeSteady;
+ _duration = span._duration;
+ _tags = span._tags;
+ _logs = span._logs;
+ _references = span._references;
+ }
+
+ // Pass-by-value intentional to implement copy-and-swap.
+ Span& operator=(Span rhs)
+ {
+ swap(rhs);
+ return *this;
+ }
+
+ ~Span() { Finish(); }
+
+ void swap(Span& span)
+ {
+ using std::swap;
+
+ std::lock(_mutex, span._mutex);
+ std::lock_guard<std::mutex> lock(_mutex, std::adopt_lock);
+ std::lock_guard<std::mutex> spanLock(span._mutex, std::adopt_lock);
+
+ swap(_tracer, span._tracer);
+ swap(_context, span._context);
+ swap(_operationName, span._operationName);
+ swap(_startTimeSystem, span._startTimeSystem);
+ swap(_startTimeSteady, span._startTimeSteady);
+ swap(_duration, span._duration);
+ swap(_tags, span._tags);
+ swap(_logs, span._logs);
+ swap(_references, span._references);
+ }
+
+ friend void swap(Span& lhs, Span& rhs) { lhs.swap(rhs); }
+
+ void thrift(thrift::Span& span) const;
+
+ template <typename Stream>
+ void print(Stream& out) const
+ {
+ std::lock_guard<std::mutex> lock(_mutex);
+ out << _context;
+ }
+
+ std::string operationName() const
+ {
+ std::lock_guard<std::mutex> lock(_mutex);
+ return _operationName;
+ }
+
+ SystemClock::time_point startTimeSystem() const
+ {
+ std::lock_guard<std::mutex> lock(_mutex);
+ return _startTimeSystem;
+ }
+
+ SteadyClock::time_point startTimeSteady() const
+ {
+ std::lock_guard<std::mutex> lock(_mutex);
+ return _startTimeSteady;
+ }
+
+ SteadyClock::duration duration() const
+ {
+ std::lock_guard<std::mutex> lock(_mutex);
+ return _duration;
+ }
+
+ std::vector<Tag> tags() const
+ {
+ std::lock_guard<std::mutex> lock(_mutex);
+ return _tags;
+ }
+
+ template <typename... Arg>
+ void setOperationName(Arg&&... args)
+ {
+ SetOperationName(std::forward<Arg>(args)...);
+ }
+
+ void FinishWithOptions(const opentracing::FinishSpanOptions&
+ finishSpanOptions) noexcept override;
+
+ void SetOperationName(opentracing::string_view name) noexcept override
+ {
+ std::lock_guard<std::mutex> lock(_mutex);
+ if (isFinished()) {
+ return;
+ }
+ _operationName = name;
+ }
+
+ void SetTag(opentracing::string_view key,
+ const opentracing::Value& value) noexcept override
+ {
+ if (key == "sampling.priority") {
+ setSamplingPriority(value);
+ return;
+ }
+ std::lock_guard<std::mutex> lock(_mutex);
+ if (isFinished() || !_context.isSampled()) {
+ return;
+ }
+ _tags.push_back(Tag(key, value));
+ }
+
+ void SetBaggageItem(opentracing::string_view restrictedKey,
+ opentracing::string_view value) noexcept override;
+
+ std::string BaggageItem(opentracing::string_view restrictedKey) const
+ noexcept override
+ {
+ std::lock_guard<std::mutex> lock(_mutex);
+ auto itr = _context.baggage().find(restrictedKey);
+ return (itr == std::end(_context.baggage())) ? std::string()
+ : itr->second;
+ }
+
+ void Log(opentracing::SystemTime timestamp,
+ std::initializer_list<
+ std::pair<opentracing::string_view, opentracing::Value>>
+ fieldPairs) noexcept override
+ {
+ doLog(timestamp, fieldPairs);
+ }
+
+ void Log(opentracing::SystemTime timestamp,
+ const std::vector<
+ std::pair<opentracing::string_view, opentracing::Value>>&
+ fieldPairs) noexcept override
+ {
+ doLog(timestamp, fieldPairs);
+ }
+
+ void Log(std::initializer_list<
+ std::pair<opentracing::string_view, opentracing::Value>>
+ fieldPairs) noexcept override
+ {
+ doLog(SystemClock::now(), fieldPairs);
+ }
+
+ const SpanContext& context() const noexcept override
+ {
+ std::lock_guard<std::mutex> lock(_mutex);
+ return _context;
+ }
+
+ const SpanContext& contextNoLock() const noexcept { return _context; }
+
+ const opentracing::Tracer& tracer() const noexcept override;
+
+ std::string serviceName() const noexcept;
+
+ std::string serviceNameNoLock() const noexcept;
+
+ private:
+ bool isFinished() const { return _duration != SteadyClock::duration(); }
+
+ template <typename FieldIterator>
+ void logFieldsNoLocking(const std::chrono::system_clock::time_point& timestamp, FieldIterator first, FieldIterator last) noexcept
+ {
+ LogRecord log(timestamp, first, last);
+ _logs.push_back(log);
+ }
+
+ template <typename Container>
+ void doLog(opentracing::SystemTime timestamp, Container fieldPairs) noexcept
+ {
+ std::lock_guard<std::mutex> lock(_mutex);
+ if (!_context.isSampled()) {
+ return;
+ }
+
+ std::vector<Tag> fields;
+ fields.reserve(fieldPairs.size());
+ std::transform(
+ std::begin(fieldPairs),
+ std::end(fieldPairs),
+ std::back_inserter(fields),
+ [](const std::pair<opentracing::string_view, opentracing::Value>&
+ pair) { return Tag(pair.first, pair.second); });
+ logFieldsNoLocking(timestamp, std::begin(fields), std::end(fields));
+ }
+
+ void setSamplingPriority(const opentracing::Value& value);
+
+ std::shared_ptr<const Tracer> _tracer;
+ SpanContext _context;
+ std::string _operationName;
+ SystemClock::time_point _startTimeSystem;
+ SteadyClock::time_point _startTimeSteady;
+ SteadyClock::duration _duration;
+ std::vector<Tag> _tags;
+ std::vector<LogRecord> _logs;
+ std::vector<Reference> _references;
+ mutable std::mutex _mutex;
+};
+
+} // namespace jaegertracing
+
+inline std::ostream& operator<<(std::ostream& out,
+ const jaegertracing::Span& span)
+{
+ span.print(out);
+ return out;
+}
+
+#endif // JAEGERTRACING_SPAN_H
diff --git a/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/SpanContext.cpp b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/SpanContext.cpp
new file mode 100644
index 000000000..effbf11a7
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/SpanContext.cpp
@@ -0,0 +1,68 @@
+/*
+ * 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.
+ */
+
+#include "jaegertracing/SpanContext.h"
+
+#include "jaegertracing/utils/HexParsing.h"
+
+namespace jaegertracing {
+
+SpanContext SpanContext::fromStream(std::istream& in)
+{
+ SpanContext spanContext;
+ spanContext._traceID = TraceID::fromStream(in);
+ if (!spanContext._traceID.isValid()) {
+ return SpanContext();
+ }
+
+ char ch = '\0';
+ if (!in.get(ch) || ch != ':') {
+ return SpanContext();
+ }
+
+ constexpr auto kMaxUInt64Chars = static_cast<size_t>(16);
+ auto buffer = utils::HexParsing::readSegment(in, kMaxUInt64Chars, ':');
+ if (buffer.empty()) {
+ return SpanContext();
+ }
+ spanContext._spanID = utils::HexParsing::decodeHex<uint64_t>(buffer);
+
+ if (!in.get(ch) || ch != ':') {
+ return SpanContext();
+ }
+
+ buffer = utils::HexParsing::readSegment(in, kMaxUInt64Chars, ':');
+ if (buffer.empty()) {
+ return SpanContext();
+ }
+ spanContext._parentID = utils::HexParsing::decodeHex<uint64_t>(buffer);
+
+ if (!in.get(ch) || ch != ':') {
+ return SpanContext();
+ }
+
+ constexpr auto kMaxByteChars = static_cast<size_t>(2);
+ buffer = utils::HexParsing::readSegment(in, kMaxByteChars, ':');
+ if (buffer.empty()) {
+ return SpanContext();
+ }
+ spanContext._flags = utils::HexParsing::decodeHex<unsigned char>(buffer);
+
+ in.clear();
+ return spanContext;
+}
+
+} // namespace jaegertracing
diff --git a/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/SpanContext.h b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/SpanContext.h
new file mode 100644
index 000000000..295a7e91a
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/SpanContext.h
@@ -0,0 +1,223 @@
+/*
+ * 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_SPANCONTEXT_H
+#define JAEGERTRACING_SPANCONTEXT_H
+
+#include <iomanip>
+#include <iostream>
+#include <memory>
+#include <mutex>
+#include <string>
+#include <unordered_map>
+
+#include <opentracing/span.h>
+
+#include "jaegertracing/Compilers.h"
+
+#include "jaegertracing/TraceID.h"
+
+namespace jaegertracing {
+
+class SpanContext : public opentracing::SpanContext {
+ public:
+ using StrMap = std::unordered_map<std::string, std::string>;
+
+ enum class Flag : unsigned char { kSampled = 1, kDebug = 2 };
+
+ static SpanContext fromStream(std::istream& in);
+
+ SpanContext()
+ : _traceID(0, 0)
+ , _spanID(0)
+ , _parentID(0)
+ , _flags(0)
+ , _mutex()
+ {
+ }
+
+ SpanContext(const TraceID& traceID,
+ uint64_t spanID,
+ uint64_t parentID,
+ unsigned char flags,
+ const StrMap& baggage,
+ const std::string& debugID = "")
+ : _traceID(traceID)
+ , _spanID(spanID)
+ , _parentID(parentID)
+ , _flags(flags)
+ , _baggage(baggage)
+ , _debugID(debugID)
+ , _mutex()
+ {
+ }
+
+ SpanContext(const SpanContext& ctx)
+ : _traceID(ctx._traceID)
+ , _spanID(ctx._spanID)
+ , _parentID(ctx._parentID)
+ , _flags(ctx._flags)
+ , _baggage(ctx._baggage)
+ , _debugID(ctx._debugID)
+ {
+ }
+
+ SpanContext& operator=(SpanContext rhs)
+ {
+ swap(rhs);
+ return *this;
+ }
+
+ void swap(SpanContext& ctx)
+ {
+ using std::swap;
+ swap(_traceID, ctx._traceID);
+ swap(_spanID, ctx._spanID);
+ swap(_parentID, ctx._parentID);
+ swap(_flags, ctx._flags);
+ swap(_baggage, ctx._baggage);
+ swap(_debugID, ctx._debugID);
+ }
+
+ friend void swap(SpanContext& lhs, SpanContext& rhs) { lhs.swap(rhs); }
+
+ const TraceID& traceID() const { return _traceID; }
+
+ uint64_t spanID() const { return _spanID; }
+
+ uint64_t parentID() const { return _parentID; }
+
+ const StrMap& baggage() const { return _baggage; }
+
+ SpanContext withBaggage(const StrMap& baggage) const
+ {
+ std::lock_guard<std::mutex> lock(_mutex);
+ return SpanContext(
+ _traceID, _spanID, _parentID, _flags, baggage, _debugID);
+ }
+
+ template <typename Function>
+ void forEachBaggageItem(Function f) const
+ {
+ std::lock_guard<std::mutex> lock(_mutex);
+ for (auto&& pair : _baggage) {
+ if (!f(pair.first, pair.second)) {
+ break;
+ }
+ }
+ }
+
+ template <typename Function>
+ void forEachBaggageItem(Function f)
+ {
+ std::lock_guard<std::mutex> lock(_mutex);
+ for (auto&& pair : _baggage) {
+ if (!f(pair.first, pair.second)) {
+ break;
+ }
+ }
+ }
+
+ unsigned char flags() const { return _flags; }
+
+ const std::string& debugID() const { return _debugID; }
+
+ bool isSampled() const
+ {
+ return _flags & static_cast<unsigned char>(Flag::kSampled);
+ }
+
+ bool isDebug() const
+ {
+ return _flags & static_cast<unsigned char>(Flag::kDebug);
+ }
+
+ bool isDebugIDContainerOnly() const
+ {
+ return !_traceID.isValid() && !_debugID.empty();
+ }
+
+ bool isValid() const { return _traceID.isValid() && _spanID != 0; }
+
+ template <typename Stream>
+ void print(Stream& out) const
+ {
+ _traceID.print(out);
+ out << ':' << std::hex << _spanID << ':' << std::hex << _parentID << ':'
+ << std::hex << static_cast<size_t>(_flags);
+ }
+
+ void ForeachBaggageItem(
+ std::function<bool(const std::string& key, const std::string& value)> f)
+ const override
+ {
+ forEachBaggageItem(f);
+ }
+
+ std::unique_ptr<opentracing::SpanContext> Clone() const noexcept override
+ {
+ std::lock_guard<std::mutex> lock(_mutex);
+ return std::unique_ptr<opentracing::SpanContext>(
+ new SpanContext(*this));
+ }
+
+ friend bool operator==(const SpanContext& lhs, const SpanContext& rhs)
+ {
+ {
+ std::lock(lhs._mutex, rhs._mutex);
+ std::lock_guard<std::mutex> lhsLock(lhs._mutex, std::adopt_lock);
+ std::lock_guard<std::mutex> rhsLock(rhs._mutex, std::adopt_lock);
+ if (lhs._baggage != rhs._baggage) {
+ return false;
+ }
+ }
+ return lhs._traceID == rhs._traceID && lhs._spanID == rhs._spanID &&
+ lhs._parentID == rhs._parentID && lhs._flags == rhs._flags &&
+ lhs._debugID == rhs._debugID;
+ }
+
+ friend bool operator!=(const SpanContext& lhs, const SpanContext& rhs)
+ {
+ return !operator==(lhs, rhs);
+ }
+
+ private:
+ TraceID _traceID;
+ uint64_t _spanID;
+ uint64_t _parentID;
+ unsigned char _flags;
+ StrMap _baggage;
+ std::string _debugID;
+ mutable std::mutex _mutex; // Protects _baggage.
+};
+
+} // namespace jaegertracing
+
+inline std::ostream& operator<<(std::ostream& out,
+ const jaegertracing::SpanContext& spanContext)
+{
+ spanContext.print(out);
+ return out;
+}
+
+inline std::istream& operator>>(std::istream& in,
+ jaegertracing::SpanContext& spanContext)
+{
+ spanContext = jaegertracing::SpanContext::fromStream(in);
+ return in;
+}
+
+#endif // JAEGERTRACING_SPANCONTEXT_H
diff --git a/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/SpanContextTest.cpp b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/SpanContextTest.cpp
new file mode 100644
index 000000000..6eef6b3c9
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/SpanContextTest.cpp
@@ -0,0 +1,117 @@
+/*
+ * 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.
+ */
+
+#include "jaegertracing/SpanContext.h"
+#include "jaegertracing/TraceID.h"
+#include <algorithm>
+#include <gtest/gtest.h>
+#include <sstream>
+#include <string>
+
+namespace jaegertracing {
+namespace {
+
+struct FromStreamTestCase {
+ std::string _input;
+ bool _success;
+};
+
+} // anonymous namespace
+
+TEST(SpanContext, testFromStream)
+{
+ const FromStreamTestCase testCases[] = {
+ { "", false },
+ { "abcd", false },
+ { "ABCD", false },
+ { "x:1:1:1", false },
+ { "1:x:1:1", false },
+ { "1:1:x:1", false },
+ { "1:1:1:x", false },
+ { "01234567890123456789012345678901234:1:1:1", false },
+ { "01234567890123456789012345678901:1:1:1", true },
+ { "01234_67890123456789012345678901:1:1:1", false },
+ { "0123456789012345678901_345678901:1:1:1", false },
+ { "1:0123456789012345:1:1", true },
+ { "1:01234567890123456:1:1", false },
+ { "10000000000000001:1:1:1", true },
+ { "10000000000000001:1:1", false },
+ { "1:1:1:1", true }
+ };
+
+ for (auto&& testCase : testCases) {
+ SpanContext spanContext;
+ {
+ std::stringstream ss;
+ ss << testCase._input;
+ spanContext = SpanContext::fromStream(ss);
+ ASSERT_EQ(testCase._success, spanContext.isValid())
+ << "input=" << testCase._input;
+ }
+
+ SpanContext spanContextFromStreamOp;
+ {
+ std::stringstream ss;
+ ss << testCase._input;
+ ss >> spanContextFromStreamOp;
+ }
+
+ ASSERT_EQ(spanContext, spanContextFromStreamOp);
+ }
+}
+
+TEST(SpanContext, testFormatting)
+{
+ SpanContext spanContext(TraceID(255, 255), 0, 0, 0, SpanContext::StrMap());
+ std::ostringstream oss;
+ oss << spanContext;
+ ASSERT_EQ("ff00000000000000ff:0:0:0", oss.str());
+}
+
+TEST(SpanContext, testBaggage)
+{
+ const SpanContext spanContext(
+ TraceID(0, 0),
+ 0,
+ 0,
+ 0,
+ SpanContext::StrMap({ { "key1", "value1" }, { "key2", "value2" } }));
+ std::string keyCopy;
+ std::string valueCopy;
+ spanContext.ForeachBaggageItem(
+ [&keyCopy, &valueCopy](const std::string& key,
+ const std::string& value) {
+ keyCopy = key;
+ valueCopy = value;
+ return false;
+ });
+ ASSERT_TRUE(keyCopy == "key1" || keyCopy == "key2");
+ if (keyCopy == "key1") {
+ ASSERT_EQ("value1", valueCopy);
+ }
+ else {
+ ASSERT_EQ("value2", valueCopy);
+ }
+}
+
+TEST(SpanContext, testDebug)
+{
+ const SpanContext spanContext;
+ ASSERT_FALSE(spanContext.isDebug());
+ ASSERT_FALSE(spanContext.isDebugIDContainerOnly());
+}
+
+} // namespace jaegertracing
diff --git a/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/SpanTest.cpp b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/SpanTest.cpp
new file mode 100644
index 000000000..2d9a8e3d9
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/SpanTest.cpp
@@ -0,0 +1,33 @@
+/*
+ * 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.
+ */
+
+#include "jaegertracing/Span.h"
+#include "jaegertracing/thrift-gen/jaeger_types.h"
+#include <gtest/gtest.h>
+#include <string>
+
+namespace jaegertracing {
+
+TEST(Span, testThriftConversion)
+{
+ const Span span;
+ ASSERT_TRUE(span.serviceName().empty());
+ ASSERT_TRUE(span.operationName().empty());
+ thrift::Span thriftSpan;
+ ASSERT_NO_THROW(span.thrift(thriftSpan));
+}
+
+} // namespace jaegertracing
diff --git a/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/Tag.cpp b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/Tag.cpp
new file mode 100644
index 000000000..6e6c80dc4
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/Tag.cpp
@@ -0,0 +1,79 @@
+/*
+ * 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.
+ */
+
+#include "jaegertracing/Tag.h"
+#include "jaegertracing/thrift-gen/jaeger_types.h"
+
+namespace jaegertracing {
+class ThriftVisitor {
+ public:
+ using result_type = void;
+
+ explicit ThriftVisitor(thrift::Tag& tag)
+ : _tag(tag)
+ {
+ }
+
+ void operator()(const std::string& value) const { setString(value); }
+
+ void operator()(const char* value) const { setString(value); }
+
+ void operator()(double value) const
+ {
+ _tag.__set_vType(thrift::TagType::DOUBLE);
+ _tag.__set_vDouble(value);
+ }
+
+ void operator()(bool value) const
+ {
+ _tag.__set_vType(thrift::TagType::BOOL);
+ _tag.__set_vBool(value);
+ }
+
+ void operator()(int64_t value) const { setLong(value); }
+
+ void operator()(uint64_t value) const { setLong(value); }
+
+ template <typename Arg>
+ void operator()(Arg&& value) const
+ {
+ // No-op
+ }
+
+ private:
+ void setString(opentracing::string_view value) const
+ {
+ _tag.__set_vType(thrift::TagType::STRING);
+ _tag.__set_vStr(value);
+ }
+
+ void setLong(int64_t value) const
+ {
+ _tag.__set_vType(thrift::TagType::LONG);
+ _tag.__set_vLong(value);
+ }
+
+ thrift::Tag& _tag;
+};
+
+void Tag::thrift(thrift::Tag& tag) const
+{
+ tag.__set_key(_key);
+ ThriftVisitor visitor(tag);
+ opentracing::util::apply_visitor(visitor, _value);
+}
+
+} // namespace jaegertracing \ No newline at end of file
diff --git a/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/Tag.h b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/Tag.h
new file mode 100644
index 000000000..a88047038
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/Tag.h
@@ -0,0 +1,70 @@
+/*
+ * 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_TAG_H
+#define JAEGERTRACING_TAG_H
+
+#include "jaegertracing/Compilers.h"
+
+#include <algorithm>
+#include <cstdint>
+#include <opentracing/string_view.h>
+#include <opentracing/value.h>
+#include <opentracing/variant/variant.hpp>
+#include <string>
+
+namespace jaegertracing {
+namespace thrift {
+class Tag;
+}
+
+class Tag {
+ public:
+ using ValueType = opentracing::Value;
+
+ template <typename ValueArg>
+ Tag(const std::string& key, ValueArg&& value)
+ : _key(key)
+ , _value(std::forward<ValueArg>(value))
+ {
+ }
+
+ template <typename ValueArg>
+ Tag(const std::pair<std::string, ValueArg>& tag_pair)
+ : _key(tag_pair.first)
+ , _value(tag_pair.second)
+ {
+ }
+
+ bool operator==(const Tag& rhs) const
+ {
+ return _key == rhs._key && _value == rhs._value;
+ }
+
+ const std::string& key() const { return _key; }
+
+ const ValueType& value() const { return _value; }
+
+ void thrift(thrift::Tag& tag) const;
+
+ private:
+ std::string _key;
+ ValueType _value;
+};
+
+} // namespace jaegertracing
+
+#endif // JAEGERTRACING_TAG_H
diff --git a/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/TagTest.cpp b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/TagTest.cpp
new file mode 100644
index 000000000..1fc43462b
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/TagTest.cpp
@@ -0,0 +1,40 @@
+/*
+ * 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.
+ */
+
+#include "jaegertracing/Tag.h"
+#include "jaegertracing/thrift-gen/jaeger_types.h"
+#include <gtest/gtest.h>
+#include <string>
+
+namespace jaegertracing {
+
+TEST(Tag, testThriftConversion)
+{
+ const Tag tags[] = { { "testBool", true },
+ { "testDouble", 0.0 },
+ { "testInt64", 0LL },
+ { "testUint64", 0ULL },
+ { "testStr", std::string{ "test" } },
+ { "testNull", nullptr },
+ { "testCStr", "test" } };
+
+ for (auto&& tag : tags) {
+ thrift::Tag thriftTag;
+ ASSERT_NO_THROW(tag.thrift(thriftTag));
+ }
+}
+
+} // namespace jaegertracing
diff --git a/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/ThriftMethods.cpp b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/ThriftMethods.cpp
new file mode 100644
index 000000000..a1dbe1319
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/ThriftMethods.cpp
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) 2019 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.
+ */
+
+#include "jaegertracing/thrift-gen/BaggageRestrictionManager.h"
+#include "jaegertracing/thrift-gen/sampling_types.h"
+
+namespace jaegertracing {
+
+// trivial constructors of BaggageRestrictionManager thrift generated code are not generated by MSVC
+#ifdef _MSC_VER
+
+namespace thrift {
+
+BaggageRestrictionManager_getBaggageRestrictions_args::
+ BaggageRestrictionManager_getBaggageRestrictions_args(
+ const BaggageRestrictionManager_getBaggageRestrictions_args& that)
+ : serviceName(that.serviceName)
+{
+}
+
+BaggageRestrictionManager_getBaggageRestrictions_args&
+BaggageRestrictionManager_getBaggageRestrictions_args::
+operator=(const BaggageRestrictionManager_getBaggageRestrictions_args& that)
+{
+ this->serviceName = that.serviceName;
+ return *this;
+}
+
+BaggageRestrictionManager_getBaggageRestrictions_result::
+ BaggageRestrictionManager_getBaggageRestrictions_result(
+ const BaggageRestrictionManager_getBaggageRestrictions_result& that)
+ : success(that.success)
+ , __isset(that.__isset)
+{
+}
+BaggageRestrictionManager_getBaggageRestrictions_result&
+BaggageRestrictionManager_getBaggageRestrictions_result::
+operator=(const BaggageRestrictionManager_getBaggageRestrictions_result& that)
+{
+ this->success = that.success;
+ return *this;
+}
+
+} // namespace thrift
+
+#endif // MSVC
+
+namespace sampling_manager {
+namespace thrift {
+
+const std::map<int, const char*>& samplingStrategyType_VALUES_TO_NAMES()
+{
+ return _SamplingStrategyType_VALUES_TO_NAMES;
+}
+
+} // namespace thrift
+} // namespace sampling_manager
+} // namespace jaegertracing
diff --git a/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/ThriftSender.cpp b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/ThriftSender.cpp
new file mode 100644
index 000000000..f5557fe5a
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/ThriftSender.cpp
@@ -0,0 +1,132 @@
+/*
+ * Copyright (c) 2017-2018 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.
+ */
+
+#include "jaegertracing/ThriftSender.h"
+
+#include "jaegertracing/Span.h"
+#include "jaegertracing/Tag.h"
+#include "jaegertracing/Tracer.h"
+#include <algorithm>
+#include <cstdint>
+#include <iostream>
+#include <iterator>
+#include <thrift/transport/TBufferTransports.h>
+
+#ifdef _MSC_VER
+#pragma warning(disable : 4267) // Conversion from unsigned to signed. It
+ // should not be a problem here.
+#endif
+
+namespace jaegertracing {
+namespace net {
+class IPAddress;
+} // namespace net
+
+namespace {
+
+constexpr auto kEmitBatchOverhead = 30;
+
+} // anonymous namespace
+
+ThriftSender::ThriftSender(std::unique_ptr<utils::Transport>&& transporter)
+ : _transporter(std::move(transporter))
+ , _maxSpanBytes(0)
+ , _byteBufferSize(0)
+ , _processByteSize(0)
+ , _protocolFactory(_transporter->protocolFactory())
+ , _thriftBuffer(new apache::thrift::transport::TMemoryBuffer())
+{
+}
+
+int ThriftSender::append(const Span& span)
+{
+ if (_process.serviceName.empty()) {
+ const auto& tracer = static_cast<const Tracer&>(span.tracer());
+ _process.serviceName = tracer.serviceName();
+
+ const auto& tracerTags = tracer.tags();
+ std::vector<thrift::Tag> thriftTags;
+ thriftTags.reserve(tracerTags.size());
+ std::transform(std::begin(tracerTags),
+ std::end(tracerTags),
+ std::back_inserter(thriftTags),
+ [](const Tag& tag) {
+ thrift::Tag thriftTag;
+ tag.thrift(thriftTag);
+ return thriftTag;
+ });
+ _process.__set_tags(thriftTags);
+
+ _processByteSize = calcSizeOfSerializedThrift(_process);
+ _maxSpanBytes =
+ _transporter->maxPacketSize() - _processByteSize - kEmitBatchOverhead;
+ }
+ thrift::Span jaegerSpan;
+ span.thrift(jaegerSpan);
+ const auto spanSize = calcSizeOfSerializedThrift(jaegerSpan);
+ if (spanSize > _maxSpanBytes) {
+ std::ostringstream oss;
+ throw Sender::Exception("Span is too large", 1);
+ }
+
+ _byteBufferSize += spanSize;
+ if (_byteBufferSize <= _maxSpanBytes) {
+ _spanBuffer.push_back(jaegerSpan);
+ if (_byteBufferSize < _maxSpanBytes) {
+ return 0;
+ }
+ return flush();
+ }
+
+ // Flush currently full buffer, then append this span to buffer.
+ const auto flushed = flush();
+ _spanBuffer.push_back(jaegerSpan);
+ _byteBufferSize = spanSize + _processByteSize;
+ return flushed;
+}
+
+int ThriftSender::flush()
+{
+ if (_spanBuffer.empty()) {
+ return 0;
+ }
+
+ thrift::Batch batch;
+ batch.__set_process(_process);
+ batch.__set_spans(_spanBuffer);
+
+ try {
+ _transporter->emitBatch(batch);
+ } catch (const std::system_error& ex) {
+ std::ostringstream oss;
+ oss << "Could not send span " << ex.what()
+ << ", code=" << ex.code().value();
+ throw Sender::Exception(oss.str(), _spanBuffer.size());
+ } catch (const std::exception& ex) {
+ std::ostringstream oss;
+ oss << "Could not send span " << ex.what();
+ throw Sender::Exception(oss.str(), _spanBuffer.size());
+ } catch (...) {
+ throw Sender::Exception("Could not send span, unknown error",
+ _spanBuffer.size());
+ }
+
+ resetBuffers();
+
+ return batch.spans.size();
+}
+
+} // namespace jaegertracing
diff --git a/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/ThriftSender.h b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/ThriftSender.h
new file mode 100644
index 000000000..72d69eef4
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/ThriftSender.h
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 2017-2018 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_THRIFTSENDER_H
+#define JAEGERTRACING_THRIFTSENDER_H
+
+#include "jaegertracing/Compilers.h"
+#include "jaegertracing/Span.h"
+#include "jaegertracing/Sender.h"
+#include "jaegertracing/thrift-gen/jaeger_types.h"
+#include "jaegertracing/utils/Transport.h"
+#include <thrift/transport/TBufferTransports.h>
+
+namespace jaegertracing {
+
+class ThriftSender : public Sender {
+ public:
+ ThriftSender(std::unique_ptr<utils::Transport>&& transporter);
+
+ ~ThriftSender() { close(); }
+
+ int append(const Span& span) override;
+
+ int flush() override;
+
+ void close() override { _transporter->close(); }
+
+ protected:
+ void setClient(std::unique_ptr<utils::Transport>&& client)
+ {
+ _transporter = std::move(client);
+ }
+
+ private:
+ void resetBuffers()
+ {
+ _spanBuffer.clear();
+ _byteBufferSize = _processByteSize;
+ }
+
+ template <typename ThriftType>
+ int calcSizeOfSerializedThrift(const ThriftType& base)
+ {
+ _thriftBuffer->resetBuffer();
+ auto _protocol = _protocolFactory->getProtocol(_thriftBuffer);
+ base.write(_protocol.get());
+ uint8_t* data = nullptr;
+ uint32_t size = 0;
+ _thriftBuffer->getBuffer(&data, &size);
+ return size;
+ }
+
+ std::unique_ptr<utils::Transport> _transporter;
+ int _maxSpanBytes;
+ int _byteBufferSize;
+ std::vector<thrift::Span> _spanBuffer;
+ thrift::Process _process;
+ int _processByteSize;
+ std::unique_ptr<apache::thrift::protocol::TProtocolFactory> _protocolFactory;
+ // reuse buffer across serializations of different ThriftType for size
+ // calculation
+ std::shared_ptr<apache::thrift::transport::TMemoryBuffer> _thriftBuffer;
+};
+
+} // namespace jaegertracing
+
+#endif //JAEGERTRACING_THRIFTSENDER_H
diff --git a/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/ThriftSenderTest.cpp b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/ThriftSenderTest.cpp
new file mode 100644
index 000000000..b5b0b6d6b
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/ThriftSenderTest.cpp
@@ -0,0 +1,109 @@
+/*
+ * Copyright (c) 2017-2018 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.
+ */
+
+#include <gtest/gtest.h>
+
+#include "jaegertracing/Tracer.h"
+#include "jaegertracing/ThriftSender.h"
+#include "jaegertracing/testutils/TracerUtil.h"
+#include "jaegertracing/utils/ErrorUtil.h"
+
+namespace jaegertracing {
+namespace {
+
+class MockUDPSender : public utils::UDPTransporter {
+ public:
+ enum class ExceptionType { kSystemError, kException, kString };
+
+ MockUDPSender(const net::IPAddress& serverAddr,
+ int maxPacketSize,
+ ExceptionType type)
+ : UDPTransporter(serverAddr, maxPacketSize)
+ , _type(type)
+ {
+ }
+
+ private:
+ void emitBatch(const thrift::Batch& batch) override
+ {
+ switch (_type) {
+ case ExceptionType::kSystemError:
+ throw std::system_error(
+ std::make_error_code(std::errc::invalid_argument));
+ case ExceptionType::kException:
+ throw std::exception();
+ default:
+ assert(_type == ExceptionType::kString);
+ throw "error";
+ }
+ }
+
+ ExceptionType _type;
+};
+
+class MockThriftSender : public ThriftSender {
+ public:
+ MockThriftSender(const net::IPAddress& ip,
+ int maxPacketSize,
+ MockUDPSender::ExceptionType type)
+ : ThriftSender(std::unique_ptr<utils::Transport>(new MockUDPSender(ip, maxPacketSize, type)))
+ {
+ }
+};
+
+} // anonymous namespace
+
+TEST(ThriftSender, testManyMessages)
+{
+ const auto handle = testutils::TracerUtil::installGlobalTracer();
+ const auto tracer =
+ std::static_pointer_cast<const Tracer>(opentracing::Tracer::Global());
+
+ std::unique_ptr<utils::Transport> transporter(
+ new utils::UDPTransporter(handle->_mockAgent->spanServerAddress(), 0));
+ ThriftSender sender(
+ std::forward<std::unique_ptr<utils::Transport>>(transporter));
+ constexpr auto kNumMessages = 2000;
+ const auto logger = logging::consoleLogger();
+ for (auto i = 0; i < kNumMessages; ++i) {
+ Span span(tracer);
+ span.SetOperationName("test" + std::to_string(i));
+ ASSERT_NO_THROW(sender.append(span));
+ }
+}
+
+TEST(ThriftSender, testExceptions)
+{
+ const auto handle = testutils::TracerUtil::installGlobalTracer();
+ const auto tracer =
+ std::static_pointer_cast<const Tracer>(opentracing::Tracer::Global());
+
+ Span span(tracer);
+ span.SetOperationName("test");
+
+ const MockUDPSender::ExceptionType exceptionTypes[] = {
+ MockUDPSender::ExceptionType::kSystemError,
+ MockUDPSender::ExceptionType::kException,
+ MockUDPSender::ExceptionType::kString
+ };
+ for (auto type : exceptionTypes) {
+ MockThriftSender mockSender(net::IPAddress::v4("localhost", 0), 0, type);
+ mockSender.append(span);
+ ASSERT_THROW(mockSender.flush(), Sender::Exception);
+ }
+}
+
+} // namespace jaegertracing
diff --git a/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/TraceID.cpp b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/TraceID.cpp
new file mode 100644
index 000000000..59a5ceb49
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/TraceID.cpp
@@ -0,0 +1,49 @@
+/*
+ * 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.
+ */
+
+#include "jaegertracing/TraceID.h"
+#include "jaegertracing/utils/HexParsing.h"
+#include <iterator>
+#include <stddef.h>
+#include <string>
+
+namespace jaegertracing {
+
+TraceID TraceID::fromStream(std::istream& in)
+{
+ TraceID traceID;
+ constexpr auto kMaxChars = static_cast<size_t>(32);
+ auto buffer = utils::HexParsing::readSegment(in, kMaxChars, ':');
+
+ if (buffer.empty()) {
+ return TraceID();
+ }
+
+ if (buffer.size() < kMaxChars / 2) {
+ traceID._low = utils::HexParsing::decodeHex<uint64_t>(buffer);
+ }
+ else {
+ auto beginLowStr = std::end(buffer) - kMaxChars / 2;
+ const std::string highStr(std::begin(buffer), beginLowStr);
+ traceID._high = utils::HexParsing::decodeHex<uint64_t>(highStr);
+ const std::string lowStr(beginLowStr, std::end(buffer));
+ traceID._low = utils::HexParsing::decodeHex<uint64_t>(lowStr);
+ }
+
+ return traceID;
+}
+
+} // namespace jaegertracing
diff --git a/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/TraceID.h b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/TraceID.h
new file mode 100644
index 000000000..867f0c29b
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/TraceID.h
@@ -0,0 +1,85 @@
+/*
+ * 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_TRACEID_H
+#define JAEGERTRACING_TRACEID_H
+
+#include <cstdint>
+#include <iomanip>
+#include <iostream>
+
+namespace jaegertracing {
+
+class TraceID {
+ public:
+ static TraceID fromStream(std::istream& in);
+
+ TraceID()
+ : TraceID(0, 0)
+ {
+ }
+
+ TraceID(uint64_t high, uint64_t low)
+ : _high(high)
+ , _low(low)
+ {
+ }
+
+ bool isValid() const { return _high != 0 || _low != 0; }
+
+ template <typename Stream>
+ void print(Stream& out) const
+ {
+ if (_high == 0) {
+ out << std::hex << _low;
+ }
+ else {
+ out << std::hex << _high << std::setw(16) << std::setfill('0')
+ << std::hex << _low;
+ }
+ }
+
+ uint64_t high() const { return _high; }
+
+ uint64_t low() const { return _low; }
+
+ bool operator==(const TraceID& rhs) const
+ {
+ return _high == rhs._high && _low == rhs._low;
+ }
+
+ private:
+ uint64_t _high;
+ uint64_t _low;
+};
+
+} // namespace jaegertracing
+
+inline std::ostream& operator<<(std::ostream& out,
+ const jaegertracing::TraceID& traceID)
+{
+ traceID.print(out);
+ return out;
+}
+
+inline std::istream& operator<<(std::istream& in,
+ jaegertracing::TraceID& traceID)
+{
+ traceID = jaegertracing::TraceID::fromStream(in);
+ return in;
+}
+
+#endif // JAEGERTRACING_TRACEID_H
diff --git a/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/TraceIDTest.cpp b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/TraceIDTest.cpp
new file mode 100644
index 000000000..ece21cfee
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/TraceIDTest.cpp
@@ -0,0 +1,30 @@
+/*
+ * 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.
+ */
+
+#include "jaegertracing/TraceID.h"
+#include <gtest/gtest.h>
+#include <sstream>
+
+namespace jaegertracing {
+
+TEST(TraceID, testPrint)
+{
+ std::ostringstream oss;
+ oss << TraceID(0, 10);
+ ASSERT_EQ("a", oss.str());
+}
+
+} // namespace jaegertracing
diff --git a/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/Tracer.cpp b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/Tracer.cpp
new file mode 100644
index 000000000..b6037c00d
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/Tracer.cpp
@@ -0,0 +1,279 @@
+/*
+ * 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.
+ */
+
+#include "jaegertracing/Tag.h"
+#include "jaegertracing/Tracer.h"
+#include "jaegertracing/Reference.h"
+#include "jaegertracing/TraceID.h"
+#include "jaegertracing/samplers/SamplingStatus.h"
+#include <algorithm>
+#include <cassert>
+#include <chrono>
+#include <iterator>
+#include <opentracing/util.h>
+#include <tuple>
+
+namespace jaegertracing {
+namespace {
+
+using SystemClock = Tracer::SystemClock;
+using SteadyClock = Tracer::SteadyClock;
+using TimePoints = std::tuple<SystemClock::time_point, SteadyClock::time_point>;
+
+// An extension of opentracing::SpanReferenceType enum. See jaegertracing::SelfRef().
+const static int SpanReferenceType_JaegerSpecific_SelfRef = 99;
+
+TimePoints determineStartTimes(const opentracing::StartSpanOptions& options)
+{
+ if (options.start_system_timestamp == SystemClock::time_point() &&
+ options.start_steady_timestamp == SteadyClock::time_point()) {
+ return std::make_tuple(SystemClock::now(), SteadyClock::now());
+ }
+ if (options.start_system_timestamp == SystemClock::time_point()) {
+ return std::make_tuple(opentracing::convert_time_point<SystemClock>(
+ options.start_steady_timestamp),
+ options.start_steady_timestamp);
+ }
+ if (options.start_steady_timestamp == SteadyClock::time_point()) {
+ return std::make_tuple(options.start_system_timestamp,
+ opentracing::convert_time_point<SteadyClock>(
+ options.start_system_timestamp));
+ }
+ return std::make_tuple(options.start_system_timestamp,
+ options.start_steady_timestamp);
+}
+
+} // anonymous namespace
+
+using StrMap = SpanContext::StrMap;
+
+constexpr int Tracer::kGen128BitOption;
+
+std::unique_ptr<opentracing::Span>
+Tracer::StartSpanWithOptions(string_view operationName,
+ const opentracing::StartSpanOptions& options) const
+ noexcept
+{
+ try {
+ const auto result = analyzeReferences(options.references);
+ const auto* parent = result._parent;
+ const auto* self = result._self;
+ const auto& references = result._references;
+ if (self && (parent || !references.empty()))
+ {
+ throw std::invalid_argument("Self and references are exclusive. Only one of them can be specified");
+ }
+
+ std::vector<Tag> samplerTags;
+ auto newTrace = false;
+ SpanContext ctx;
+ if (!parent || !parent->isValid()) {
+ newTrace = true;
+ auto highID = static_cast<uint64_t>(0);
+ auto lowID = static_cast<uint64_t>(0);
+ if (self) {
+ highID = self->traceID().high();
+ lowID = self->traceID().low();
+ }
+ else {
+ if (_options & kGen128BitOption) {
+ highID = randomID();
+ }
+ lowID = randomID();
+ }
+ const TraceID traceID(highID, lowID);
+ const auto spanID = self ? self->spanID() : traceID.low();
+ const auto parentID = 0;
+ auto flags = static_cast<unsigned char>(0);
+ if (parent && parent->isDebugIDContainerOnly()) {
+ flags |=
+ (static_cast<unsigned char>(SpanContext::Flag::kSampled) |
+ static_cast<unsigned char>(SpanContext::Flag::kDebug));
+ samplerTags.push_back(Tag(kJaegerDebugHeader, parent->debugID()));
+ }
+ else {
+ const auto samplingStatus =
+ _sampler->isSampled(traceID, operationName);
+ if (samplingStatus.isSampled()) {
+ flags |=
+ static_cast<unsigned char>(SpanContext::Flag::kSampled);
+ samplerTags = samplingStatus.tags();
+ }
+ }
+ ctx = SpanContext(traceID, spanID, parentID, flags, StrMap());
+ }
+ else {
+ const auto traceID = parent->traceID();
+ const auto spanID = randomID();
+ const auto parentID = parent->spanID();
+ const auto flags = parent->flags();
+ ctx = SpanContext(traceID, spanID, parentID, flags, StrMap());
+ }
+
+ if (parent && !parent->baggage().empty()) {
+ ctx = ctx.withBaggage(parent->baggage());
+ }
+
+ SystemClock::time_point startTimeSystem;
+ SteadyClock::time_point startTimeSteady;
+ std::tie(startTimeSystem, startTimeSteady) =
+ determineStartTimes(options);
+ return startSpanInternal(ctx,
+ operationName,
+ startTimeSystem,
+ startTimeSteady,
+ samplerTags,
+ options.tags,
+ newTrace,
+ references);
+ } catch (const std::exception& ex) {
+ std::ostringstream oss;
+ oss << "Error occurred in Tracer::StartSpanWithOptions: " << ex.what();
+ utils::ErrorUtil::logError(*_logger, oss.str());
+ return nullptr;
+ } catch (...) {
+ utils::ErrorUtil::logError(
+ *_logger, "Error occurred in Tracer::StartSpanWithOptions");
+ return nullptr;
+ }
+}
+
+std::unique_ptr<Span>
+Tracer::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
+{
+ std::vector<Tag> spanTags;
+ spanTags.reserve(tags.size() + internalTags.size());
+ std::transform(
+ std::begin(tags),
+ std::end(tags),
+ std::back_inserter(spanTags),
+ [](const OpenTracingTag& tag) { return Tag(tag.first, tag.second); });
+ spanTags.insert(
+ std::end(spanTags), std::begin(internalTags), std::end(internalTags));
+
+ std::unique_ptr<Span> span(new Span(shared_from_this(),
+ context,
+ operationName,
+ startTimeSystem,
+ startTimeSteady,
+ spanTags,
+ references));
+
+ _metrics->spansStarted().inc(1);
+ if (span->context().isSampled()) {
+ _metrics->spansSampled().inc(1);
+ if (newTrace) {
+ _metrics->tracesStartedSampled().inc(1);
+ }
+ }
+ else {
+ _metrics->spansNotSampled().inc(1);
+ if (newTrace) {
+ _metrics->tracesStartedNotSampled().inc(1);
+ }
+ }
+
+ return span;
+}
+
+Tracer::AnalyzedReferences
+Tracer::analyzeReferences(const std::vector<OpenTracingRef>& references) const
+{
+ AnalyzedReferences result;
+ auto hasParent = false;
+ const auto* parent = result._parent;
+ for (auto&& ref : references) {
+ const auto* ctx = dynamic_cast<const SpanContext*>(ref.second);
+
+ if (!ctx) {
+ _logger->error("Reference contains invalid type of SpanReference");
+ continue;
+ }
+
+ if (!ctx->isValid() && !ctx->isDebugIDContainerOnly() &&
+ ctx->baggage().empty()) {
+ continue;
+ }
+
+ if (static_cast<int>(ref.first) == SpanReferenceType_JaegerSpecific_SelfRef)
+ {
+ result._self = ctx;
+ continue; // not a reference
+ }
+
+ result._references.emplace_back(Reference(*ctx, ref.first));
+
+ if (!hasParent) {
+ parent = ctx;
+ hasParent =
+ (ref.first == opentracing::SpanReferenceType::ChildOfRef);
+ }
+ }
+
+ if (!hasParent && parent && parent->isValid()) {
+ // Use `FollowsFromRef` in place of `ChildOfRef`.
+ hasParent = true;
+ }
+
+ if (hasParent) {
+ assert(parent);
+ result._parent = parent;
+ }
+
+ return result;
+}
+
+std::shared_ptr<opentracing::Tracer>
+Tracer::make(const std::string& serviceName,
+ const Config& config,
+ const std::shared_ptr<logging::Logger>& logger,
+ metrics::StatsFactory& statsFactory, int options)
+{
+ if (serviceName.empty()) {
+ throw std::invalid_argument("no service name provided");
+ }
+
+ if (config.disabled()) {
+ return opentracing::MakeNoopTracer();
+ }
+
+ auto metrics = std::make_shared<metrics::Metrics>(statsFactory);
+ std::shared_ptr<samplers::Sampler> sampler(
+ config.sampler().makeSampler(serviceName, *logger, *metrics));
+ std::shared_ptr<reporters::Reporter> reporter(
+ config.reporter().makeReporter(serviceName, *logger, *metrics));
+ return std::shared_ptr<Tracer>(new Tracer(serviceName,
+ sampler,
+ reporter,
+ logger,
+ metrics,
+ config.headers(),
+ config.tags(),
+ options));
+}
+
+opentracing::SpanReference SelfRef(const opentracing::SpanContext* span_context) noexcept {
+ return {static_cast<opentracing::SpanReferenceType>(SpanReferenceType_JaegerSpecific_SelfRef), span_context};
+}
+
+} // namespace jaegertracing
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
diff --git a/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/TracerFactory.cpp b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/TracerFactory.cpp
new file mode 100644
index 000000000..fcc709839
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/TracerFactory.cpp
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2018 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.
+ */
+
+#include "TracerFactory.h"
+
+#include "jaegertracing/Tracer.h"
+
+namespace jaegertracing {
+
+opentracing::expected<std::shared_ptr<opentracing::Tracer>>
+TracerFactory::MakeTracer(const char* configuration,
+ std::string& errorMessage) const noexcept try {
+#ifndef JAEGERTRACING_WITH_YAML_CPP
+ errorMessage =
+ "Failed to construct tracer: Jaeger was not build with yaml support.";
+ return opentracing::make_unexpected(
+ std::make_error_code(std::errc::not_supported));
+#else
+ YAML::Node yaml;
+ try {
+ yaml = YAML::Load(configuration);
+ } catch (const YAML::ParserException& e) {
+ errorMessage = e.what();
+ return opentracing::make_unexpected(
+ opentracing::configuration_parse_error);
+ }
+
+ auto tracerConfig = jaegertracing::Config::parse(yaml);
+
+ if (_readFromEnv) {
+ tracerConfig.fromEnv();
+ }
+
+ if (tracerConfig.serviceName().empty()) {
+ errorMessage = "`service_name` not provided";
+ return opentracing::make_unexpected(
+ opentracing::invalid_configuration_error);
+ }
+
+ return jaegertracing::Tracer::make(tracerConfig);
+#endif // JAEGERTRACING_WITH_YAML_CPP
+} catch (const std::bad_alloc&) {
+ return opentracing::make_unexpected(
+ std::make_error_code(std::errc::not_enough_memory));
+} catch (const std::exception& e) {
+ errorMessage = e.what();
+ return opentracing::make_unexpected(
+ opentracing::invalid_configuration_error);
+}
+} // namespace jaegertracing
diff --git a/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/TracerFactory.h b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/TracerFactory.h
new file mode 100644
index 000000000..90428a7d4
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/TracerFactory.h
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2018 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_FACTORY_H
+#define JAEGERTRACING_TRACER_FACTORY_H
+
+#include <opentracing/tracer_factory.h>
+
+namespace jaegertracing {
+
+class TracerFactory : public opentracing::TracerFactory {
+ public:
+ opentracing::expected<std::shared_ptr<opentracing::Tracer>>
+ MakeTracer(const char* configuration, std::string& errorMessage) const
+ noexcept override;
+
+ TracerFactory()
+ : TracerFactory(false)
+ {
+ }
+
+ TracerFactory(bool readFromEnv)
+ : _readFromEnv(readFromEnv)
+ {
+ }
+ private:
+ bool _readFromEnv;
+};
+
+} // namespace jaegertracing
+
+#endif // JAEGERTRACING_TRACER_FACTORY_H
diff --git a/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/TracerFactoryTest.cpp b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/TracerFactoryTest.cpp
new file mode 100644
index 000000000..3ce186b1c
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/TracerFactoryTest.cpp
@@ -0,0 +1,138 @@
+/*
+ * Copyright (c) 2018 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.
+ */
+
+#include "jaegertracing/Tracer.h"
+#include "jaegertracing/TracerFactory.h"
+#include "jaegertracing/Constants.h"
+#include "jaegertracing/testutils/EnvVariable.h"
+#include <gtest/gtest.h>
+
+namespace jaegertracing {
+#ifdef JAEGERTRACING_WITH_YAML_CPP
+TEST(TracerFactory, testInvalidConfig)
+{
+ const char* invalidConfigTestCases[] = { "",
+ "abc: {",
+ R"({
+ "service_name": {}
+ })" };
+ TracerFactory tracerFactory(true);
+ for (auto&& invalidConfig : invalidConfigTestCases) {
+ std::string errorMessage;
+ auto tracerMaybe =
+ tracerFactory.MakeTracer(invalidConfig, errorMessage);
+ ASSERT_FALSE(tracerMaybe);
+ ASSERT_NE(errorMessage, "");
+ }
+}
+
+TEST(TracerFactory, testValidConfig)
+{
+ const char* config = R"(
+ {
+ "service_name": "test",
+ "disabled": true,
+ "sampler": {
+ "type": "probabilistic",
+ "param": 0.001
+ },
+ "reporter": {
+ "queueSize": 100,
+ "bufferFlushInterval": 10,
+ "logSpans": false,
+ "localAgentHostPort": "127.0.0.1:6831"
+ },
+ "headers": {
+ "jaegerDebugHeader": "debug-id",
+ "jaegerBaggageHeader": "baggage",
+ "TraceContextHeaderName": "trace-id",
+ "traceBaggageHeaderPrefix": "testctx-"
+ },
+ "baggage_restrictions": {
+ "denyBaggageOnInitializationFailure": false,
+ "hostPort": "127.0.0.1:5778",
+ "refreshInterval": 60
+ }
+ })";
+ TracerFactory tracerFactory(true);
+ std::string errorMessage;
+ auto tracerMaybe = tracerFactory.MakeTracer(config, errorMessage);
+ ASSERT_EQ(errorMessage, "");
+ ASSERT_TRUE(tracerMaybe);
+}
+
+TEST(TracerFactory, testWithoutReadFromEnv)
+{
+ const char* config = "";
+ testutils::EnvVariable::setEnv("JAEGER_SERVICE_NAME", "AService");
+ TracerFactory tracerFactory(false);
+ std::string errorMessage;
+ auto tracerMaybe = tracerFactory.MakeTracer(config, errorMessage);
+ ASSERT_FALSE(tracerMaybe);
+ ASSERT_NE(errorMessage, "");
+
+ testutils::EnvVariable::setEnv("JAEGER_SERVICE_NAME", "");
+}
+
+TEST(TracerFactory, testWithReadFromEnv)
+{
+ const char* config = "";
+ testutils::EnvVariable::setEnv("JAEGER_SERVICE_NAME", "AService");
+ TracerFactory tracerFactory(true);
+ std::string errorMessage;
+ auto tracerMaybe = tracerFactory.MakeTracer(config, errorMessage);
+ ASSERT_EQ(errorMessage, "");
+ ASSERT_TRUE(tracerMaybe);
+
+ auto tracer = tracerMaybe.value();
+ const auto jaegerTracer = std::dynamic_pointer_cast<jaegertracing::Tracer>(tracer);
+ ASSERT_EQ(std::string("AService"), jaegerTracer->serviceName());
+
+ testutils::EnvVariable::setEnv("JAEGER_SERVICE_NAME", "");
+}
+
+TEST(TracerFactory, testEnvTakesPrecedence)
+{
+
+ const char* config = R"(
+ {
+ "service_name": "Ignored"
+ })";
+ testutils::EnvVariable::setEnv("JAEGER_SERVICE_NAME", "test");
+ TracerFactory tracerFactory(true);
+ std::string errorMessage;
+ auto tracerMaybe = tracerFactory.MakeTracer(config, errorMessage);
+ ASSERT_EQ(errorMessage, "");
+ ASSERT_TRUE(tracerMaybe);
+
+ auto tracer = tracerMaybe.value();
+ const auto jaegerTracer = std::dynamic_pointer_cast<jaegertracing::Tracer>(tracer);
+ ASSERT_EQ(std::string("test"), jaegerTracer->serviceName());
+
+ testutils::EnvVariable::setEnv("JAEGER_SERVICE_NAME", "");
+}
+#else
+TEST(TracerFactory, failsWithoutYAML)
+{
+ const char* config = "";
+ TracerFactory tracerFactory(true);
+ std::string errorMessage;
+ auto tracerMaybe = tracerFactory.MakeTracer(config, errorMessage);
+ ASSERT_NE(errorMessage, "");
+ ASSERT_FALSE(tracerMaybe);
+}
+#endif // JAEGERTRACING_WITH_YAML_CPP
+} // namespace jaegertracing
diff --git a/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/TracerTest.cpp b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/TracerTest.cpp
new file mode 100644
index 000000000..3d5d88893
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/TracerTest.cpp
@@ -0,0 +1,555 @@
+/*
+ * Copyright (c) 2017-2018 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.
+ */
+
+#include "jaegertracing/Config.h"
+#include "jaegertracing/Constants.h"
+#include "jaegertracing/Span.h"
+#include "jaegertracing/SpanContext.h"
+#include "jaegertracing/Tag.h"
+#include "jaegertracing/TraceID.h"
+#include "jaegertracing/Tracer.h"
+#include "jaegertracing/baggage/RestrictionsConfig.h"
+#include "jaegertracing/net/IPAddress.h"
+#include "jaegertracing/propagation/HeadersConfig.h"
+#include "jaegertracing/reporters/Config.h"
+#include "jaegertracing/samplers/Config.h"
+#include "jaegertracing/testutils/TracerUtil.h"
+#include <algorithm>
+#include <chrono>
+#include <gtest/gtest.h>
+#include <iterator>
+#include <memory>
+#include <opentracing/expected/expected.hpp>
+#include <opentracing/noop.h>
+#include <opentracing/propagation.h>
+#include <opentracing/span.h>
+#include <opentracing/string_view.h>
+#include <opentracing/tracer.h>
+#include <opentracing/util.h>
+#include <sstream>
+#include <stdexcept>
+#include <string>
+#include <utility>
+#include <vector>
+
+namespace jaegertracing {
+
+using StrMap = SpanContext::StrMap;
+
+namespace {
+
+class FakeSpanContext : public opentracing::SpanContext {
+ void ForeachBaggageItem(
+ std::function<bool(const std::string&,
+ const std::string&)> /* unused */) const override
+ {
+ // Do nothing
+ }
+
+ virtual std::unique_ptr<SpanContext> Clone() const noexcept override
+ {
+ return std::unique_ptr<FakeSpanContext>(new FakeSpanContext());
+ }
+};
+
+template <typename BaseWriter>
+struct WriterMock : public BaseWriter {
+ explicit WriterMock(StrMap& keyValuePairs)
+ : _keyValuePairs(keyValuePairs)
+ {
+ }
+
+ opentracing::expected<void>
+ Set(opentracing::string_view key,
+ opentracing::string_view value) const override
+ {
+ _keyValuePairs[key] = value;
+ return opentracing::make_expected();
+ }
+
+ StrMap& _keyValuePairs;
+};
+
+template <typename BaseReader>
+struct ReaderMock : public BaseReader {
+ using Function =
+ std::function<bool(opentracing::string_view, opentracing::string_view)>;
+
+ explicit ReaderMock(const StrMap& keyValuePairs)
+ : _keyValuePairs(keyValuePairs)
+ {
+ }
+
+ opentracing::expected<void> ForeachKey(
+ std::function<opentracing::expected<void>(opentracing::string_view,
+ opentracing::string_view)> f)
+ const override
+ {
+ for (auto&& pair : _keyValuePairs) {
+ const auto result = f(pair.first, pair.second);
+ if (!result) {
+ return result;
+ }
+ }
+ return opentracing::make_expected();
+ }
+
+ const StrMap& _keyValuePairs;
+};
+
+template <typename ClockType>
+typename ClockType::duration
+absTimeDiff(const typename ClockType::time_point& lhs,
+ const typename ClockType::time_point& rhs)
+{
+ return (rhs < lhs) ? (lhs - rhs) : (rhs - lhs);
+}
+
+} // anonymous namespace
+
+TEST(Tracer, testTracer)
+{
+ {
+
+ const auto handle = testutils::TracerUtil::installGlobalTracer();
+ const auto tracer =
+ std::static_pointer_cast<Tracer>(opentracing::Tracer::Global());
+
+ auto tagItr = std::find_if(
+ std::begin(tracer->tags()),
+ std::end(tracer->tags()),
+ [](const Tag& tag) { return tag.key() == kJaegerClientVersionTagKey; });
+ ASSERT_NE(std::end(tracer->tags()), tagItr);
+ ASSERT_TRUE(tagItr->value().is<const char*>());
+ ASSERT_EQ("C++-",
+ static_cast<std::string>(tagItr->value().get<const char*>())
+ .substr(0, 4));
+
+ opentracing::StartSpanOptions options;
+ options.tags.push_back({ "tag-key", 1.23 });
+
+ const FakeSpanContext fakeCtx;
+ options.references.emplace_back(opentracing::SpanReferenceType::ChildOfRef,
+ &fakeCtx);
+ const SpanContext emptyCtx(TraceID(), 0, 0, 0, StrMap());
+ options.references.emplace_back(opentracing::SpanReferenceType::ChildOfRef,
+ &emptyCtx);
+ const SpanContext parentCtx(
+ TraceID(0xDEAD, 0xBEEF), 0xBEEF, 1234, 0, StrMap());
+ options.references.emplace_back(opentracing::SpanReferenceType::ChildOfRef,
+ &parentCtx);
+ options.references.emplace_back(
+ opentracing::SpanReferenceType::FollowsFromRef, &parentCtx);
+ const SpanContext debugCtx(
+ TraceID(),
+ 0,
+ 0,
+ static_cast<unsigned char>(SpanContext::Flag::kSampled) |
+ static_cast<unsigned char>(SpanContext::Flag::kDebug),
+ StrMap({ { "debug-baggage-key", "debug-baggage-value" } }),
+ "123");
+ options.references.emplace_back(opentracing::SpanReferenceType::ChildOfRef,
+ &debugCtx);
+
+ const auto& tags = tracer->tags();
+ auto itr =
+ std::find_if(std::begin(tags), std::end(tags), [](const Tag& tag) {
+ return tag.key() == kTracerIPTagKey;
+ });
+ ASSERT_NE(std::end(tags), itr);
+ ASSERT_TRUE(itr->value().is<std::string>());
+ ASSERT_EQ(net::IPAddress::v4(itr->value().get<std::string>()).host(),
+ net::IPAddress::localIP(AF_INET).host());
+
+ std::unique_ptr<Span> span(static_cast<Span*>(
+ tracer->StartSpanWithOptions("test-operation", options).release()));
+ ASSERT_TRUE(static_cast<bool>(span));
+ ASSERT_EQ(static_cast<opentracing::Tracer*>(tracer.get()), &span->tracer());
+
+ span->SetOperationName("test-set-operation");
+ span->SetTag("tag-key", "tag-value");
+ span->SetBaggageItem("test-baggage-item-key", "test baggage item value");
+ ASSERT_EQ("test baggage item value",
+ span->BaggageItem("test-baggage-item-key"));
+ span->Log({ { "log-bool", true } });
+ opentracing::FinishSpanOptions foptions;
+ opentracing::LogRecord lr{};
+ lr.fields = { { "options-log", "yep" } };
+ foptions.log_records.push_back(std::move(lr));
+ lr.timestamp = opentracing::SystemClock::now();
+ span->FinishWithOptions(foptions);
+ ASSERT_GE(Span::SteadyClock::now(),
+ span->startTimeSteady() + span->duration());
+ span->SetOperationName("test-set-operation-after-finish");
+ ASSERT_EQ("test-set-operation", span->operationName());
+ span->SetTag("tagged-after-finish-key", "tagged-after-finish-value");
+
+ span.reset(static_cast<Span*>(
+ tracer->StartSpanWithOptions("test-span-with-default-options", {})
+ .release()));
+
+ options.references.clear();
+ options.references.emplace_back(
+ opentracing::SpanReferenceType::FollowsFromRef, &parentCtx);
+ span.reset(static_cast<Span*>(
+ tracer->StartSpanWithOptions("test-span-with-default-options", options)
+ .release()));
+
+ options.references.clear();
+ options.references.emplace_back(opentracing::SpanReferenceType::ChildOfRef,
+ &debugCtx);
+ span.reset(static_cast<Span*>(
+ tracer->StartSpanWithOptions("test-span-with-debug-parent", options)
+ .release()));
+
+ options.references.clear();
+ options.references.emplace_back(
+ opentracing::SpanReferenceType::FollowsFromRef, &parentCtx);
+ options.start_steady_timestamp = Tracer::SteadyClock::now();
+ span.reset(static_cast<Span*>(
+ tracer
+ ->StartSpanWithOptions("test-span-with-default-system-timestamp",
+ options)
+ .release()));
+ /*
+ TODO: https://github.com/jaegertracing/jaeger-client-cpp/issues/167
+ const auto calculatedSystemTime =
+ static_cast<Tracer::SystemClock::time_point>(
+ opentracing::convert_time_point<Tracer::SystemClock>(
+ span->startTimeSteady()));
+ ASSERT_GE(std::chrono::milliseconds(10),
+ absTimeDiff<Tracer::SystemClock>(span->startTimeSystem(),
+ calculatedSystemTime));
+ */
+ options.start_system_timestamp = Tracer::SystemClock::now();
+ span.reset(static_cast<Span*>(
+ tracer
+ ->StartSpanWithOptions("test-span-with-default-steady-timestamp",
+ options)
+ .release()));
+ const auto calculatedSteadyTime =
+ static_cast<Tracer::SteadyClock::time_point>(
+ opentracing::convert_time_point<Tracer::SteadyClock>(
+ span->startTimeSystem()));
+ /*
+ TODO: https://github.com/jaegertracing/jaeger-client-cpp/issues/167
+ ASSERT_GE(std::chrono::milliseconds(10),
+ absTimeDiff<Tracer::SteadyClock>(span->startTimeSteady(),
+ calculatedSteadyTime));
+
+*/ options.start_system_timestamp = Tracer::SystemClock::now();
+ options.start_steady_timestamp = Tracer::SteadyClock::now();
+ span.reset(static_cast<Span*>(
+ tracer->StartSpanWithOptions("test-span-with-both-timestamps", options)
+ .release()));
+ // TODO: https://github.com/jaegertracing/jaeger-client-cpp/issues/167
+
+ // ASSERT_EQ(options.start_system_timestamp, span->startTimeSystem());
+ // ASSERT_EQ(options.start_steady_timestamp, span->startTimeSteady());
+
+ span.reset();
+
+ // TODO: https://github.com/jaegertracing/jaeger-client-cpp/issues/127
+
+ // There is a problem here. After replacing the global tracer, the spans
+ // produced hold the last references to the tracer. After they are
+ // published, the tracer is destroyed. This is not the right moment to close
+ // the tracer.
+ tracer->Close();
+ opentracing::Tracer::InitGlobal(opentracing::MakeNoopTracer());
+ }
+ //std::this_thread::sleep_for(std::chrono::milliseconds(10000));
+}
+
+TEST(Tracer, testDebugSpan)
+{
+ const auto handle = testutils::TracerUtil::installGlobalTracer();
+ const auto tracer =
+ std::static_pointer_cast<Tracer>(opentracing::Tracer::Global());
+
+ // we force span sampling and require debug-id as the extracted
+ // jaeger-debug-id correlation value.
+ std::string correlationID = "debug-id";
+
+ StrMap headers ={
+ {kJaegerDebugHeader, correlationID},
+ };
+
+ WriterMock<opentracing::HTTPHeadersWriter> headerWriter(headers);
+ ReaderMock<opentracing::HTTPHeadersReader> headerReader(headers);
+
+ const FakeSpanContext fakeCtx;
+ tracer->Inject(fakeCtx, headerWriter);
+ auto ext = tracer->Extract(headerReader);
+
+ const SpanContext* ctx = dynamic_cast<SpanContext*>(ext->release());
+ opentracing::StartSpanOptions opts;
+ opts.references.emplace_back(opentracing::SpanReferenceType::ChildOfRef, ctx);
+
+ auto otspan = tracer->StartSpanWithOptions("name", opts);
+ // downcast to jaegertracing span implementation so we can inspect tags
+ const std::unique_ptr<Span> span(dynamic_cast<Span*>(otspan.release()));
+
+ const auto& spanTags = span->tags();
+ auto spanItr =
+ std::find_if(std::begin(spanTags), std::end(spanTags), [](const Tag& tag) {
+ return tag.key() == kJaegerDebugHeader;
+ });
+ ASSERT_NE(std::end(spanTags), spanItr);
+ ASSERT_TRUE(spanItr->value().is<std::string>());
+ ASSERT_EQ(spanItr->value().get<std::string>(), correlationID);
+
+ tracer->Close();
+ opentracing::Tracer::InitGlobal(opentracing::MakeNoopTracer());
+}
+
+TEST(Tracer, testConstructorFailure)
+{
+ Config config;
+ ASSERT_THROW(Tracer::make("", config), std::invalid_argument);
+}
+
+TEST(Tracer, testDisabledConfig)
+{
+ Config config(true,
+ samplers::Config(),
+ reporters::Config(),
+ propagation::HeadersConfig(),
+ baggage::RestrictionsConfig());
+ ASSERT_FALSE(static_cast<bool>(std::dynamic_pointer_cast<Tracer>(
+ Tracer::make("test-service", config))));
+}
+
+TEST(Tracer, testPropagation)
+{
+ const auto handle = testutils::TracerUtil::installGlobalTracer();
+ const auto tracer =
+ std::static_pointer_cast<Tracer>(opentracing::Tracer::Global());
+ const std::unique_ptr<Span> span(static_cast<Span*>(
+ tracer->StartSpanWithOptions("test-inject", {}).release()));
+ span->SetBaggageItem("test-baggage-item-key", "test baggage item value");
+
+ // Binary
+ {
+ std::stringstream ss;
+ ASSERT_TRUE(static_cast<bool>(tracer->Inject(span->context(), ss)));
+ auto result = tracer->Extract(ss);
+ ASSERT_TRUE(static_cast<bool>(result));
+ std::unique_ptr<const SpanContext> extractedCtx(
+ static_cast<SpanContext*>(result->release()));
+ ASSERT_TRUE(static_cast<bool>(extractedCtx));
+ ASSERT_EQ(span->context(), *extractedCtx);
+ FakeSpanContext fakeCtx;
+ ss.clear();
+ ss.str("");
+ ASSERT_FALSE(static_cast<bool>(tracer->Inject(fakeCtx, ss)));
+ }
+
+ // Text map
+ {
+ StrMap textMap;
+ WriterMock<opentracing::TextMapWriter> textWriter(textMap);
+ ASSERT_TRUE(
+ static_cast<bool>(tracer->Inject(span->context(), textWriter)));
+ ASSERT_EQ(2, textMap.size());
+ std::ostringstream oss;
+ oss << span->context();
+ ASSERT_EQ(oss.str(), textMap.at(kTraceContextHeaderName));
+ ASSERT_EQ("test baggage item value",
+ textMap.at(std::string(kTraceBaggageHeaderPrefix) +
+ "test-baggage-item-key"));
+ ReaderMock<opentracing::TextMapReader> textReader(textMap);
+ auto result = tracer->Extract(textReader);
+ ASSERT_TRUE(static_cast<bool>(result));
+ std::unique_ptr<const SpanContext> extractedCtx(
+ static_cast<SpanContext*>(result->release()));
+ ASSERT_TRUE(static_cast<bool>(extractedCtx));
+ ASSERT_EQ(span->context(), *extractedCtx);
+ }
+
+ // HTTP map
+ {
+ StrMap headerMap;
+ WriterMock<opentracing::HTTPHeadersWriter> headerWriter(headerMap);
+ ASSERT_TRUE(
+ static_cast<bool>(tracer->Inject(span->context(), headerWriter)));
+ ASSERT_EQ(2, headerMap.size());
+ std::ostringstream oss;
+ oss << span->context();
+ ASSERT_EQ(oss.str(), headerMap.at(kTraceContextHeaderName));
+ ASSERT_EQ("test%20baggage%20item%20value",
+ headerMap.at(std::string(kTraceBaggageHeaderPrefix) +
+ "test-baggage-item-key"));
+ ReaderMock<opentracing::HTTPHeadersReader> headerReader(headerMap);
+ auto result = tracer->Extract(headerReader);
+ ASSERT_TRUE(static_cast<bool>(result));
+ std::unique_ptr<const SpanContext> extractedCtx(
+ static_cast<SpanContext*>(result->release()));
+ ASSERT_TRUE(static_cast<bool>(extractedCtx));
+ ASSERT_EQ(span->context(), *extractedCtx);
+
+ // Test debug header.
+ headerMap.clear();
+ headerMap[kJaegerDebugHeader] = "yes";
+ tracer->Inject(span->context(), headerWriter);
+ result = tracer->Extract(headerReader);
+ ASSERT_TRUE(static_cast<bool>(result));
+ extractedCtx.reset(static_cast<SpanContext*>(result->release()));
+ ASSERT_TRUE(static_cast<bool>(extractedCtx));
+ ASSERT_NE(span->context(), *extractedCtx);
+ SpanContext ctx(
+ span->context().traceID(),
+ span->context().spanID(),
+ span->context().parentID(),
+ span->context().flags() |
+ static_cast<unsigned char>(SpanContext::Flag::kDebug),
+ span->context().baggage(),
+ "yes");
+ ASSERT_EQ(ctx, *extractedCtx);
+
+ // Test bad trace context.
+ headerMap.clear();
+ headerMap[kTraceContextHeaderName] = "12345678";
+ result = tracer->Extract(headerReader);
+ ASSERT_TRUE(static_cast<bool>(result));
+ extractedCtx.reset(static_cast<SpanContext*>(result->release()));
+ ASSERT_EQ(nullptr, extractedCtx.get());
+
+ // Test empty map.
+ headerMap.clear();
+ result = tracer->Extract(headerReader);
+ ASSERT_TRUE(static_cast<bool>(result));
+ extractedCtx.reset(static_cast<SpanContext*>(result->release()));
+ ASSERT_EQ(nullptr, extractedCtx.get());
+
+ // Test alternative baggage format.
+ headerMap.clear();
+ ctx = SpanContext(span->context().traceID(),
+ span->context().spanID(),
+ span->context().parentID(),
+ span->context().flags(),
+ { { "a", "x" }, { "b", "y" }, { "c", "z" } });
+ tracer->Inject(ctx, headerWriter);
+ for (auto itr = std::begin(headerMap); itr != std::end(headerMap);) {
+ if (itr->first.substr(0, std::strlen(kTraceBaggageHeaderPrefix)) ==
+ kTraceBaggageHeaderPrefix) {
+ itr = headerMap.erase(itr);
+ }
+ else {
+ ++itr;
+ }
+ }
+ headerMap[kJaegerBaggageHeader] = "a=x,b=y,c=z";
+ result = tracer->Extract(headerReader);
+ ASSERT_TRUE(static_cast<bool>(result));
+ extractedCtx.reset(static_cast<SpanContext*>(result->release()));
+ ASSERT_TRUE(static_cast<bool>(extractedCtx));
+ ASSERT_EQ(3, extractedCtx->baggage().size());
+ ASSERT_EQ(ctx, *extractedCtx);
+ }
+ tracer->Close();
+}
+
+TEST(Tracer, testTracerTags)
+{
+ std::vector<Tag> tags;
+ tags.emplace_back("hostname", std::string("foobar"));
+ tags.emplace_back("my.app.version", std::string("1.2.3"));
+
+ Config config(
+ false,
+ samplers::Config(
+ "const", 1, "", 0, samplers::Config::Clock::duration()),
+ reporters::Config(0, std::chrono::milliseconds(100), false, "", ""),
+ propagation::HeadersConfig(),
+ baggage::RestrictionsConfig(),
+ "test-service",
+ tags);
+
+ auto tracer = Tracer::make(config);
+ const auto jaegerTracer = std::static_pointer_cast<Tracer>(tracer);
+
+ ASSERT_TRUE(std::find(jaegerTracer->tags().begin(),
+ jaegerTracer->tags().end(),
+ Tag("hostname", std::string("foobar"))) !=
+ jaegerTracer->tags().end());
+
+ ASSERT_TRUE(std::find(jaegerTracer->tags().begin(),
+ jaegerTracer->tags().end(),
+ Tag("my.app.version", std::string("1.2.3"))) !=
+ jaegerTracer->tags().end());
+
+ ASSERT_EQ(std::string("test-service"), jaegerTracer->serviceName());
+}
+
+TEST(Tracer, testTracerSimpleChild)
+{
+ const auto handle = testutils::TracerUtil::installGlobalTracer();
+ const auto tracer = std::static_pointer_cast<Tracer>(opentracing::Tracer::Global());
+ {
+ auto spanRoot = tracer->StartSpan("test-simple-root");
+ ASSERT_TRUE(spanRoot);
+ auto spanChild = tracer->StartSpan("test-simple-child",
+ { opentracing::ChildOf(&spanRoot->context()) });
+ ASSERT_TRUE(spanChild);
+ }
+ tracer->Close();
+}
+
+TEST(Tracer, testTracerSpanSelfRef)
+{
+ const auto handle = testutils::TracerUtil::installGlobalTracer();
+ const auto tracer = std::static_pointer_cast<Tracer>(opentracing::Tracer::Global());
+ {
+ const jaegertracing::SpanContext spanSelfContext { {1, 2}, 3, 0, 0, jaegertracing::SpanContext::StrMap() };
+ auto spanRoot = tracer->StartSpan("test-root-self-ref", {jaegertracing::SelfRef(&spanSelfContext)});
+ ASSERT_TRUE(spanRoot);
+ auto jaegerSpanRoot = dynamic_cast<jaegertracing::Span&>(*spanRoot.get());
+ ASSERT_EQ(jaegerSpanRoot.context().traceID(), jaegertracing::TraceID(1, 2));
+ ASSERT_EQ(jaegerSpanRoot.context().spanID(), 3);
+
+ auto spanChild = tracer->StartSpan("test-child-self-ref",
+ { opentracing::ChildOf(&spanRoot->context()) });
+ ASSERT_TRUE(spanChild);
+ auto jaegerSpanChild = dynamic_cast<jaegertracing::Span&>(*spanChild.get());
+ ASSERT_EQ(jaegerSpanChild.context().traceID(), jaegertracing::TraceID(1, 2));
+ ASSERT_NE(jaegerSpanChild.context().spanID(), 3);
+ }
+ tracer->Close();
+}
+
+TEST(Tracer, testTracerSpanSelfRefWithOtherRefs)
+{
+ const auto handle = testutils::TracerUtil::installGlobalTracer();
+ const auto tracer = std::static_pointer_cast<Tracer>(opentracing::Tracer::Global());
+ {
+ const jaegertracing::SpanContext spanSelfContext { {1, 2}, 3, 0, 0, jaegertracing::SpanContext::StrMap() };
+ auto spanRoot = tracer->StartSpan("test-root-self-ref", {jaegertracing::SelfRef(&spanSelfContext)});
+ ASSERT_TRUE(spanRoot);
+ auto jaegerSpanRoot = dynamic_cast<jaegertracing::Span&>(*spanRoot.get());
+ ASSERT_EQ(jaegerSpanRoot.context().traceID(), jaegertracing::TraceID(1, 2));
+ ASSERT_EQ(jaegerSpanRoot.context().spanID(), 3);
+
+ const jaegertracing::SpanContext spanSelfContext2 { {1, 2}, 4, 0, 0, jaegertracing::SpanContext::StrMap() };
+ auto spanChild = tracer->StartSpan("test-child-self-ref",
+ { opentracing::ChildOf(&spanRoot->context()), jaegertracing::SelfRef(&spanSelfContext2) }
+ );
+ ASSERT_FALSE(spanChild);
+ }
+ tracer->Close();
+}
+
+} // namespace jaegertracing
diff --git a/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/baggage/BaggageSetter.cpp b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/baggage/BaggageSetter.cpp
new file mode 100644
index 000000000..8f6b5493c
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/baggage/BaggageSetter.cpp
@@ -0,0 +1,17 @@
+/*
+ * 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.
+ */
+
+#include "jaegertracing/baggage/BaggageSetter.h"
diff --git a/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/baggage/BaggageSetter.h b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/baggage/BaggageSetter.h
new file mode 100644
index 000000000..fb4fd56c3
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/baggage/BaggageSetter.h
@@ -0,0 +1,120 @@
+/*
+ * 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_BAGGAGE_BAGGAGESETTER_H
+#define JAEGERTRACING_BAGGAGE_BAGGAGESETTER_H
+
+#include "jaegertracing/LogRecord.h"
+#include "jaegertracing/Span.h"
+#include "jaegertracing/baggage/RestrictionManager.h"
+#include "jaegertracing/metrics/Metrics.h"
+
+namespace jaegertracing {
+namespace baggage {
+
+class BaggageSetter {
+ public:
+ BaggageSetter(RestrictionManager& restrictionManager,
+ metrics::Metrics& metrics)
+ : _restrictionManager(restrictionManager)
+ , _metrics(metrics)
+ {
+ }
+
+ template <typename LoggingFunction>
+ void setBaggage(Span& span,
+ SpanContext::StrMap& baggage,
+ const std::string& key,
+ std::string value,
+ LoggingFunction logFn) const
+ {
+ auto truncated = false;
+ const auto restriction =
+ _restrictionManager.getRestriction(span.serviceNameNoLock(), key);
+ if (!restriction.keyAllowed()) {
+ logFields(span,
+ key,
+ value,
+ std::string(),
+ truncated,
+ restriction.keyAllowed(),
+ logFn);
+ _metrics.baggageUpdateFailure().inc(1);
+ return;
+ }
+
+ if (static_cast<int>(value.size()) > restriction.maxValueLength()) {
+ truncated = true;
+ value = value.substr(0, restriction.maxValueLength());
+ _metrics.baggageTruncate().inc(1);
+ }
+
+ auto itr = baggage.find(key);
+ const auto prevItem =
+ (itr == std::end(baggage) ? std::string() : itr->second);
+ if (itr == std::end(baggage)) {
+ baggage[key] = value;
+ }
+ else {
+ itr->second = value;
+ }
+ logFields(span,
+ key,
+ value,
+ prevItem,
+ truncated,
+ restriction.keyAllowed(),
+ logFn);
+ _metrics.baggageUpdateSuccess().inc(1);
+ }
+
+ private:
+ template <typename LoggingFunction>
+ void logFields(const Span& span,
+ const std::string& key,
+ const std::string& value,
+ const std::string& prevItem,
+ bool truncated,
+ bool valid,
+ LoggingFunction logFn) const
+ {
+ if (!span.contextNoLock().isSampled()) {
+ return;
+ }
+
+ std::vector<Tag> fields(
+ { { "event", "baggage" }, { "key", key }, { "value", value } });
+ if (!prevItem.empty()) {
+ fields.push_back(Tag("override", "true"));
+ }
+ if (truncated) {
+ fields.push_back(Tag("truncated", "true"));
+ }
+ if (!valid) {
+ fields.push_back(Tag("invalid", "true"));
+ }
+
+ logFn(std::begin(fields), std::end(fields));
+ }
+
+ RestrictionManager& _restrictionManager;
+ metrics::Metrics& _metrics;
+};
+
+} // namespace baggage
+} // namespace jaegertracing
+
+#endif // JAEGERTRACING_BAGGAGE_BAGGAGESETTER_H
diff --git a/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/baggage/BaggageTest.cpp b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/baggage/BaggageTest.cpp
new file mode 100644
index 000000000..3c122cdcf
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/baggage/BaggageTest.cpp
@@ -0,0 +1,181 @@
+/*
+ * 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.
+ */
+
+#include <gtest/gtest.h>
+
+#include "jaegertracing/baggage/BaggageSetter.h"
+#include "jaegertracing/baggage/RemoteRestrictionManager.h"
+#include "jaegertracing/baggage/RestrictionManager.h"
+#include "jaegertracing/baggage/RestrictionsConfig.h"
+#include "jaegertracing/metrics/Metrics.h"
+#include "jaegertracing/metrics/InMemoryStatsReporter.h"
+#include "jaegertracing/testutils/MockAgent.h"
+
+#include <mutex>
+
+namespace jaegertracing {
+namespace baggage {
+namespace {
+
+class TestStatsReporter : public metrics::StatsReporter {
+ public:
+
+ using ValueMap = std::unordered_map<std::string, int64_t>;
+
+ virtual ~TestStatsReporter() = default;
+
+ void incCounter(const std::string& name,
+ int64_t delta,
+ const metrics::StatsReporter::TagMap& tags) override
+ {
+ std::lock_guard<std::mutex> lock(_mutex);
+
+ const auto metricName =
+ metrics::Metrics::addTagsToMetricName(name, tags);
+ auto& currentValue = _counters[metricName];
+ currentValue = currentValue + delta;
+ }
+
+ void recordTimer(const std::string& name,
+ int64_t time,
+ const metrics::StatsReporter::TagMap& tags) override
+ {
+ }
+
+ void updateGauge(const std::string& name,
+ int64_t time,
+ const metrics::StatsReporter::TagMap& tags) override
+ {
+ }
+
+ int64_t counterValue(const std::string& name,
+ const metrics::StatsReporter::TagMap& tags) const
+ {
+ std::lock_guard<std::mutex> lock(_mutex);
+
+ const auto metricName =
+ metrics::Metrics::addTagsToMetricName(name, tags);
+ return _counters[metricName];
+ }
+
+ private:
+ mutable ValueMap _counters;
+ mutable std::mutex _mutex;
+};
+
+constexpr auto kDefaultMaxValueLength = 8;
+
+class TestRestrictionManager : public RestrictionManager {
+ public:
+ ~TestRestrictionManager() { close(); }
+
+ Restriction getRestriction(const std::string&,
+ const std::string& key) override
+ {
+ const auto keyAllowed = (!key.empty() && key[0] == 'a');
+ return Restriction(keyAllowed, kDefaultMaxValueLength);
+ }
+};
+
+template <typename FieldIterator>
+void log(FieldIterator, FieldIterator)
+{
+}
+
+} // anonymous namespace
+
+TEST(Baggage, restrictionManagerTest)
+{
+ auto logFn = &log<std::vector<Tag>::const_iterator>;
+ TestRestrictionManager manager;
+ auto metrics = metrics::Metrics::makeNullMetrics();
+ BaggageSetter setter(manager, *metrics);
+ Span span(
+ nullptr,
+ SpanContext(TraceID(),
+ 123,
+ 456,
+ static_cast<unsigned char>(SpanContext::Flag::kSampled),
+ SpanContext::StrMap()));
+ auto baggage = span.context().baggage();
+ setter.setBaggage(span, baggage, "abc", "123", logFn);
+ ASSERT_EQ(1, baggage.size());
+ ASSERT_EQ("123", baggage["abc"]);
+ setter.setBaggage(span, baggage, "bcd", "234", logFn);
+ ASSERT_EQ(1, baggage.size());
+ setter.setBaggage(span, baggage, "abc", "1234567890", logFn);
+ ASSERT_EQ("12345678", baggage["abc"]);
+}
+
+TEST(Baggage, testRemoteRestrictionManagerDefaults)
+{
+ auto logger = logging::nullLogger();
+ auto metrics = metrics::Metrics::makeNullMetrics();
+ RemoteRestrictionManager manager(
+ "test-service",
+ "",
+ false,
+ RemoteRestrictionManager::Clock::duration(),
+ *logger,
+ *metrics);
+ ASSERT_EQ(RemoteRestrictionManager::defaultRefreshInterval(),
+ manager.refreshInterval());
+ ASSERT_EQ(
+ Restriction(true, RemoteRestrictionManager::kDefaultMaxValueLength),
+ manager.getRestriction("test-service", "abc"));
+}
+
+TEST(Baggage, testRemoteRestrictionManagerFunctionality)
+{
+ auto logger = logging::consoleLogger();
+
+ TestStatsReporter testReporter;
+ auto metrics = metrics::Metrics::fromStatsReporter(testReporter);
+
+ auto mockAgent = testutils::MockAgent::make();
+ mockAgent->start();
+ RemoteRestrictionManager manager(
+ "test-service",
+ mockAgent->samplingServerAddress().authority(),
+ true,
+ std::chrono::milliseconds(100),
+ *logger,
+ *metrics);
+ ASSERT_EQ(Restriction(false, 0),
+ manager.getRestriction("test-service", "abc"));
+ mockAgent->addBaggageRestriction("abc", Restriction(true, 1));
+
+ // Wait for the Update Restrictions to occur
+ // This is done by listening to the number of update published via the Metrics
+ // Typically, On Windows with Debug mode, the update happens after 700ms
+ for (int sleepIndex = 0; sleepIndex < 100; ++sleepIndex) {
+ auto counterVal = testReporter.counterValue(
+ "jaeger.baggage-restrictions-update", { { "result", "ok" } });
+ std::this_thread::sleep_for(std::chrono::milliseconds(200));
+ if (counterVal > 0) {
+ break;
+ }
+ }
+
+ ASSERT_EQ(Restriction(true, 1),
+ manager.getRestriction("test-service", "abc"));
+ ASSERT_EQ(Restriction(false, 0),
+ manager.getRestriction("test-service", "bcd"));
+ manager.close();
+}
+
+} // namespace baggage
+} // namespace jaegertracing
diff --git a/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/baggage/RemoteRestrictionJSON.cpp b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/baggage/RemoteRestrictionJSON.cpp
new file mode 100644
index 000000000..b4e387efd
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/baggage/RemoteRestrictionJSON.cpp
@@ -0,0 +1,17 @@
+/*
+ * 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.
+ */
+
+#include "jaegertracing/baggage/RemoteRestrictionJSON.h"
diff --git a/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/baggage/RemoteRestrictionJSON.h b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/baggage/RemoteRestrictionJSON.h
new file mode 100644
index 000000000..a1772d977
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/baggage/RemoteRestrictionJSON.h
@@ -0,0 +1,62 @@
+/*
+ * 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_BAGGAGE_REMOTERESTRICTIONJSON_H
+#define JAEGERTRACING_BAGGAGE_REMOTERESTRICTIONJSON_H
+
+#include <cstdint>
+#include <nlohmann/json.hpp>
+#include <string>
+#include <vector>
+
+#include "jaegertracing/Compilers.h"
+#include "jaegertracing/thrift-gen/BaggageRestrictionManager.h"
+#include "jaegertracing/thrift-gen/baggage_types.h"
+
+namespace jaegertracing {
+namespace thrift {
+
+inline void to_json(nlohmann::json& json, const BaggageRestriction& restriction)
+{
+ json["baggageKey"] = restriction.baggageKey;
+ json["maxValueLength"] = restriction.maxValueLength;
+}
+
+inline void from_json(const nlohmann::json& json,
+ BaggageRestriction& restriction)
+{
+ restriction.__set_baggageKey(json.at("baggageKey"));
+ restriction.__set_maxValueLength(json.at("maxValueLength"));
+}
+
+using BaggageRestrictionList =
+ BaggageRestrictionManager_getBaggageRestrictions_result;
+
+inline void to_json(nlohmann::json& json, const BaggageRestrictionList& list)
+{
+ json = list.success;
+}
+
+inline void from_json(const nlohmann::json& json, BaggageRestrictionList& list)
+{
+ list.success = json.get<std::vector<BaggageRestriction>>();
+ list.__isset.success = true;
+}
+
+} // namespace thrift
+} // namespace jaegertracing
+
+#endif // JAEGERTRACING_BAGGAGE_REMOTERESTRICTIONJSON_H
diff --git a/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/baggage/RemoteRestrictionManager.cpp b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/baggage/RemoteRestrictionManager.cpp
new file mode 100644
index 000000000..39024adcb
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/baggage/RemoteRestrictionManager.cpp
@@ -0,0 +1,177 @@
+/*
+ * 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.
+ */
+
+#include "jaegertracing/baggage/RemoteRestrictionManager.h"
+
+#include <sstream>
+
+#include "jaegertracing/baggage/RemoteRestrictionJSON.h"
+#include "jaegertracing/net/http/Response.h"
+#include "jaegertracing/utils/ErrorUtil.h"
+
+namespace jaegertracing {
+namespace baggage {
+namespace {
+
+constexpr auto kDefaultHostPort = "127.0.0.1:5778";
+
+} // anonymous namespace
+
+RemoteRestrictionManager::RemoteRestrictionManager(
+ const std::string& serviceName,
+ const std::string& hostPort,
+ bool denyBaggageOnInitializationFailure,
+ const Clock::duration& refreshInterval,
+ logging::Logger& logger,
+ metrics::Metrics& metrics)
+ : _serviceName(serviceName)
+ , _serverAddress(
+ net::IPAddress::v4(hostPort.empty() ? kDefaultHostPort : hostPort))
+ , _denyBaggageOnInitializationFailure(denyBaggageOnInitializationFailure)
+ , _refreshInterval(refreshInterval == Clock::duration()
+ ? defaultRefreshInterval()
+ : refreshInterval)
+ , _logger(logger)
+ , _metrics(metrics)
+ , _running(true)
+ , _initialized(false)
+ , _thread([this]() { poll(); })
+{
+}
+
+Restriction
+RemoteRestrictionManager::getRestriction(const std::string& /* service */,
+ const std::string& key)
+{
+ std::lock_guard<std::mutex> lock(_mutex);
+
+ if (!_initialized) {
+ if (_denyBaggageOnInitializationFailure) {
+ return Restriction(false, 0);
+ }
+ return Restriction(true, kDefaultMaxValueLength);
+ }
+
+ auto itr = _restrictions.find(key);
+ if (itr != std::end(_restrictions)) {
+ return itr->second;
+ }
+ return Restriction(false, 0);
+}
+
+void RemoteRestrictionManager::close() noexcept
+{
+ std::unique_lock<std::mutex> lock(_mutex);
+ if (!_running) {
+ return;
+ }
+ _running = false;
+ lock.unlock();
+ _cv.notify_one();
+ _thread.join();
+}
+
+void RemoteRestrictionManager::poll() noexcept
+{
+ net::URI remoteURI;
+ try {
+ std::ostringstream oss;
+ oss << "http://" << _serverAddress.authority()
+ << "/baggageRestrictions?service="
+ << net::URI::queryEscape(_serviceName);
+ remoteURI = net::URI::parse(oss.str());
+ updateRestrictions(remoteURI);
+ } catch (...) {
+ auto logger = logging::consoleLogger();
+ utils::ErrorUtil::logError(*logger,
+ "Failed in RemoteRestrictionManager::poll");
+ return;
+ }
+
+ Clock::time_point lastUpdateTime = Clock::now();
+ while (true) {
+ {
+ std::unique_lock<std::mutex> lock(_mutex);
+ _cv.wait_until(lock, lastUpdateTime + _refreshInterval, [this]() {
+ return !_running;
+ });
+ if (!_running) {
+ return;
+ }
+ }
+
+ if ((Clock::now() - lastUpdateTime) >= _refreshInterval) {
+ updateRestrictions(remoteURI);
+ lastUpdateTime = Clock::now();
+ }
+ }
+}
+
+void RemoteRestrictionManager::updateRestrictions(
+ const net::URI& remoteURI) noexcept
+{
+ try {
+ const auto responseHTTP = net::http::get(remoteURI);
+ if (responseHTTP.statusCode() != 200) {
+ std::ostringstream oss;
+ oss << "Received HTTP error response"
+ << ", uri=" << remoteURI
+ << ", statusCode=" << responseHTTP.statusCode()
+ << ", reason=" << responseHTTP.reason();
+ _logger.error(oss.str());
+ return;
+ }
+
+ thrift::BaggageRestrictionManager_getBaggageRestrictions_result
+ response = nlohmann::json::parse(responseHTTP.body());
+ if (response.__isset.success) {
+ KeyRestrictionMap restrictions;
+ restrictions.reserve(response.success.size());
+ std::transform(
+ std::begin(response.success),
+ std::end(response.success),
+ std::inserter(restrictions, std::end(restrictions)),
+ [](const thrift::BaggageRestriction restriction) {
+ return std::make_pair(
+ restriction.baggageKey,
+ Restriction(true, restriction.maxValueLength));
+ });
+ {
+ std::lock_guard<std::mutex> lock(_mutex);
+ _restrictions = std::move(restrictions);
+ if (!_initialized) {
+ _initialized = true;
+ }
+ }
+ _metrics.baggageRestrictionsUpdateSuccess().inc(1);
+ }
+ else {
+ std::ostringstream oss;
+ oss << "Failed to update baggage restrictions"
+ ", response="
+ << responseHTTP.body();
+ _logger.error(oss.str());
+ _metrics.baggageRestrictionsUpdateFailure().inc(1);
+ }
+ } catch (...) {
+ utils::ErrorUtil::logError(_logger,
+ "Failed to update baggage restrictions");
+ _metrics.baggageRestrictionsUpdateFailure().inc(1);
+ }
+}
+
+} // namespace baggage
+} // namespace jaegertracing
diff --git a/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/baggage/RemoteRestrictionManager.h b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/baggage/RemoteRestrictionManager.h
new file mode 100644
index 000000000..a0d44ac49
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/baggage/RemoteRestrictionManager.h
@@ -0,0 +1,92 @@
+/*
+ * 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_BAGGAGE_REMOTERESTRICTIONMANAGER_H
+#define JAEGERTRACING_BAGGAGE_REMOTERESTRICTIONMANAGER_H
+
+#include <chrono>
+#include <condition_variable>
+#include <mutex>
+#include <string>
+#include <thread>
+#include <unordered_map>
+
+#include "jaegertracing/Compilers.h"
+
+#include "jaegertracing/Logging.h"
+#include "jaegertracing/baggage/Restriction.h"
+#include "jaegertracing/baggage/RestrictionManager.h"
+#include "jaegertracing/metrics/Metrics.h"
+#include "jaegertracing/net/IPAddress.h"
+#include "jaegertracing/net/URI.h"
+#include "jaegertracing/thrift-gen/BaggageRestrictionManager.h"
+
+namespace jaegertracing {
+namespace baggage {
+
+class RemoteRestrictionManager : public RestrictionManager {
+ public:
+ using Clock = std::chrono::steady_clock;
+ using KeyRestrictionMap = std::unordered_map<std::string, Restriction>;
+
+ static constexpr auto kDefaultDenyBaggageOnInitializationFailure = false;
+ static constexpr auto kDefaultMaxValueLength =
+ DefaultRestrictionManager::kDefaultMaxValueLength;
+
+ static Clock::duration defaultRefreshInterval()
+ {
+ return std::chrono::minutes(1);
+ }
+
+ RemoteRestrictionManager(const std::string& serviceName,
+ const std::string& hostPort,
+ bool denyBaggageOnInitializationFailure,
+ const Clock::duration& refreshInterval,
+ logging::Logger& logger,
+ metrics::Metrics& metrics);
+
+ ~RemoteRestrictionManager() { close(); }
+
+ Restriction getRestriction(const std::string& /* service */,
+ const std::string& key) override;
+
+ void close() noexcept override;
+
+ const Clock::duration& refreshInterval() const { return _refreshInterval; }
+
+ private:
+ void poll() noexcept;
+
+ void updateRestrictions(const net::URI& remoteURI) noexcept;
+
+ std::string _serviceName;
+ net::IPAddress _serverAddress;
+ bool _denyBaggageOnInitializationFailure;
+ Clock::duration _refreshInterval;
+ logging::Logger& _logger;
+ metrics::Metrics& _metrics;
+ KeyRestrictionMap _restrictions;
+ bool _running;
+ bool _initialized;
+ std::thread _thread;
+ std::condition_variable _cv;
+ std::mutex _mutex;
+};
+
+} // namespace baggage
+} // namespace jaegertracing
+
+#endif // JAEGERTRACING_BAGGAGE_REMOTERESTRICTIONMANAGER_H
diff --git a/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/baggage/Restriction.cpp b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/baggage/Restriction.cpp
new file mode 100644
index 000000000..1715171b3
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/baggage/Restriction.cpp
@@ -0,0 +1,17 @@
+/*
+ * 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.
+ */
+
+#include "jaegertracing/baggage/Restriction.h"
diff --git a/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/baggage/Restriction.h b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/baggage/Restriction.h
new file mode 100644
index 000000000..502c85004
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/baggage/Restriction.h
@@ -0,0 +1,49 @@
+/*
+ * 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_BAGGAGE_RESTRICTION_H
+#define JAEGERTRACING_BAGGAGE_RESTRICTION_H
+
+namespace jaegertracing {
+namespace baggage {
+
+class Restriction {
+ public:
+ Restriction(bool keyAllowed, int maxValueLength)
+ : _keyAllowed(keyAllowed)
+ , _maxValueLength(maxValueLength)
+ {
+ }
+
+ friend bool operator==(const Restriction& lhs, const Restriction& rhs)
+ {
+ return lhs._keyAllowed == rhs._keyAllowed &&
+ lhs._maxValueLength == rhs._maxValueLength;
+ }
+
+ bool keyAllowed() const { return _keyAllowed; }
+
+ int maxValueLength() const { return _maxValueLength; }
+
+ private:
+ bool _keyAllowed;
+ int _maxValueLength;
+};
+
+} // namespace baggage
+} // namespace jaegertracing
+
+#endif // JAEGERTRACING_BAGGAGE_RESTRICTION_H
diff --git a/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/baggage/RestrictionManager.cpp b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/baggage/RestrictionManager.cpp
new file mode 100644
index 000000000..21a10eebf
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/baggage/RestrictionManager.cpp
@@ -0,0 +1,17 @@
+/*
+ * 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.
+ */
+
+#include "jaegertracing/baggage/RestrictionManager.h"
diff --git a/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/baggage/RestrictionManager.h b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/baggage/RestrictionManager.h
new file mode 100644
index 000000000..37d5e67d9
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/baggage/RestrictionManager.h
@@ -0,0 +1,61 @@
+/*
+ * 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_BAGGAGE_RESTRICTIONMANAGER_H
+#define JAEGERTRACING_BAGGAGE_RESTRICTIONMANAGER_H
+
+#include <string>
+
+#include "jaegertracing/baggage/Restriction.h"
+
+namespace jaegertracing {
+namespace baggage {
+
+class RestrictionManager {
+ public:
+ virtual ~RestrictionManager() = default;
+
+ virtual Restriction getRestriction(const std::string& service,
+ const std::string& key) = 0;
+
+ virtual void close() noexcept {}
+};
+
+class DefaultRestrictionManager : public RestrictionManager {
+ public:
+ static constexpr auto kDefaultMaxValueLength = 2048;
+
+ explicit DefaultRestrictionManager(int maxValueLength)
+ : _defaultRestriction(true,
+ maxValueLength == 0 ? kDefaultMaxValueLength
+ : maxValueLength)
+ {
+ }
+
+ Restriction getRestriction(const std::string& service,
+ const std::string& key) override
+ {
+ return _defaultRestriction;
+ }
+
+ private:
+ Restriction _defaultRestriction;
+};
+
+} // namespace baggage
+} // namespace jaegertracing
+
+#endif // JAEGERTRACING_BAGGAGE_RESTRICTIONMANAGER_H
diff --git a/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/baggage/RestrictionsConfig.cpp b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/baggage/RestrictionsConfig.cpp
new file mode 100644
index 000000000..b44aa1181
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/baggage/RestrictionsConfig.cpp
@@ -0,0 +1,17 @@
+/*
+ * 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.
+ */
+
+#include "jaegertracing/baggage/RestrictionsConfig.h"
diff --git a/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/baggage/RestrictionsConfig.h b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/baggage/RestrictionsConfig.h
new file mode 100644
index 000000000..6fe2f673d
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/baggage/RestrictionsConfig.h
@@ -0,0 +1,82 @@
+/*
+ * 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_BAGGAGE_RESTRICTIONSCONFIG_H
+#define JAEGERTRACING_BAGGAGE_RESTRICTIONSCONFIG_H
+
+#include "jaegertracing/Constants.h"
+#include "jaegertracing/utils/YAML.h"
+#include <chrono>
+#include <string>
+
+namespace jaegertracing {
+namespace baggage {
+
+class RestrictionsConfig {
+ public:
+ using Clock = std::chrono::steady_clock;
+
+#ifdef JAEGERTRACING_WITH_YAML_CPP
+
+ static RestrictionsConfig parse(const YAML::Node& configYAML)
+ {
+ if (!configYAML.IsDefined() || !configYAML.IsMap()) {
+ return RestrictionsConfig();
+ }
+
+ const auto denyBaggageOnInitializationFailure =
+ utils::yaml::findOrDefault<bool>(
+ configYAML, "denyBaggageOnInitializationFailure", false);
+ const auto hostPort =
+ utils::yaml::findOrDefault<std::string>(configYAML, "hostPort", "");
+ const auto refreshInterval = std::chrono::seconds(
+ utils::yaml::findOrDefault<int>(configYAML, "refreshInterval", 0));
+ return RestrictionsConfig(
+ denyBaggageOnInitializationFailure, hostPort, refreshInterval);
+ }
+
+#endif // JAEGERTRACING_WITH_YAML_CPP
+
+ explicit RestrictionsConfig(
+ bool denyBaggageOnInitializationFailure = false,
+ const std::string& hostPort = "",
+ const Clock::duration& refreshInterval = Clock::duration())
+ : _denyBaggageOnInitializationFailure(
+ denyBaggageOnInitializationFailure)
+ , _hostPort(hostPort)
+ , _refreshInterval(refreshInterval)
+ {
+ }
+
+ bool denyBaggageOnInitializationFailure() const
+ {
+ return _denyBaggageOnInitializationFailure;
+ }
+
+ const std::string& hostPort() const { return _hostPort; }
+
+ const Clock::duration& refreshInterval() const { return _refreshInterval; }
+
+ private:
+ bool _denyBaggageOnInitializationFailure;
+ std::string _hostPort;
+ Clock::duration _refreshInterval;
+};
+
+} // namespace baggage
+} // namespace jaegertracing
+
+#endif // JAEGERTRACING_BAGGAGE_RESTRICTIONSCONFIG_H
diff --git a/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/metrics/Counter.cpp b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/metrics/Counter.cpp
new file mode 100644
index 000000000..b26deba40
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/metrics/Counter.cpp
@@ -0,0 +1,17 @@
+/*
+ * 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.
+ */
+
+#include "jaegertracing/metrics/Counter.h"
diff --git a/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/metrics/Counter.h b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/metrics/Counter.h
new file mode 100644
index 000000000..8dff981c9
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/metrics/Counter.h
@@ -0,0 +1,37 @@
+/*
+ * 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_METRICS_COUNTER_H
+#define JAEGERTRACING_METRICS_COUNTER_H
+
+#include "jaegertracing/Compilers.h"
+
+#include <stdint.h>
+
+namespace jaegertracing {
+namespace metrics {
+
+class Counter {
+ public:
+ virtual ~Counter() = default;
+
+ virtual void inc(int64_t delta) = 0;
+};
+
+} // namespace metrics
+} // namespace jaegertracing
+
+#endif // JAEGERTRACING_METRICS_COUNTER_H
diff --git a/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/metrics/Gauge.cpp b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/metrics/Gauge.cpp
new file mode 100644
index 000000000..4b10a6f12
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/metrics/Gauge.cpp
@@ -0,0 +1,17 @@
+/*
+ * 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.
+ */
+
+#include "jaegertracing/metrics/Gauge.h"
diff --git a/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/metrics/Gauge.h b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/metrics/Gauge.h
new file mode 100644
index 000000000..fdc9718a0
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/metrics/Gauge.h
@@ -0,0 +1,37 @@
+/*
+ * 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_METRICS_GAUGE_H
+#define JAEGERTRACING_METRICS_GAUGE_H
+
+#include "jaegertracing/Compilers.h"
+
+#include <stdint.h>
+
+namespace jaegertracing {
+namespace metrics {
+
+class Gauge {
+ public:
+ virtual ~Gauge() = default;
+
+ virtual void update(int64_t amount) = 0;
+};
+
+} // namespace metrics
+} // namespace jaegertracing
+
+#endif // JAEGERTRACING_METRICS_GAUGE_H
diff --git a/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/metrics/InMemoryStatsReporter.cpp b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/metrics/InMemoryStatsReporter.cpp
new file mode 100644
index 000000000..a438f115e
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/metrics/InMemoryStatsReporter.cpp
@@ -0,0 +1,86 @@
+/*
+ * 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.
+ */
+
+#include "jaegertracing/metrics/InMemoryStatsReporter.h"
+
+#include "jaegertracing/metrics/Counter.h"
+#include "jaegertracing/metrics/Gauge.h"
+#include "jaegertracing/metrics/Metric.h"
+#include "jaegertracing/metrics/Metrics.h"
+#include "jaegertracing/metrics/Timer.h"
+
+namespace jaegertracing {
+namespace metrics {
+namespace {
+
+template <typename Function>
+void updateMap(InMemoryStatsReporter::ValueMap& map,
+ const std::string& name,
+ int64_t newValue,
+ const std::unordered_map<std::string, std::string>& tags,
+ Function f)
+{
+ const auto metricName = Metrics::addTagsToMetricName(name, tags);
+ auto& initialValue = map[metricName];
+ initialValue = f(initialValue, newValue);
+}
+
+} // anonymous namespace
+
+void InMemoryStatsReporter::incCounter(
+ const std::string& name,
+ int64_t delta,
+ const std::unordered_map<std::string, std::string>& tags)
+{
+ updateMap(_counters,
+ name,
+ delta,
+ tags,
+ [](int64_t initialValue, int64_t newValue) {
+ return initialValue + newValue;
+ });
+}
+
+void InMemoryStatsReporter::recordTimer(
+ const std::string& name,
+ int64_t time,
+ const std::unordered_map<std::string, std::string>& tags)
+{
+ updateMap(
+ _timers, name, time, tags, [](int64_t initialValue, int64_t newValue) {
+ return initialValue + newValue;
+ });
+}
+
+void InMemoryStatsReporter::updateGauge(
+ const std::string& name,
+ int64_t amount,
+ const std::unordered_map<std::string, std::string>& tags)
+{
+ updateMap(_gauges, name, amount, tags, [](int64_t, int64_t newValue) {
+ return newValue;
+ });
+}
+
+void InMemoryStatsReporter::reset()
+{
+ _counters.clear();
+ _gauges.clear();
+ _timers.clear();
+}
+
+} // namespace metrics
+} // namespace jaegertracing
diff --git a/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/metrics/InMemoryStatsReporter.h b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/metrics/InMemoryStatsReporter.h
new file mode 100644
index 000000000..98e8e39c1
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/metrics/InMemoryStatsReporter.h
@@ -0,0 +1,67 @@
+/*
+ * 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_METRICS_INMEMORYSTATSREPORTER_H
+#define JAEGERTRACING_METRICS_INMEMORYSTATSREPORTER_H
+
+#include "jaegertracing/metrics/StatsReporter.h"
+#include <cstdint>
+#include <string>
+#include <unordered_map>
+
+namespace jaegertracing {
+namespace metrics {
+
+class InMemoryStatsReporter : public StatsReporter {
+ public:
+ using ValueMap = std::unordered_map<std::string, int64_t>;
+
+ using StatsReporter::incCounter;
+ using StatsReporter::recordTimer;
+ using StatsReporter::updateGauge;
+
+ virtual ~InMemoryStatsReporter() = default;
+
+ void incCounter(const std::string& name,
+ int64_t delta,
+ const TagMap& tags) override;
+
+ void recordTimer(const std::string& name,
+ int64_t time,
+ const TagMap& tags) override;
+
+ void updateGauge(const std::string& name,
+ int64_t time,
+ const TagMap& tags) override;
+
+ void reset();
+
+ const ValueMap& counters() const { return _counters; }
+
+ const ValueMap& gauges() const { return _gauges; }
+
+ const ValueMap& timers() const { return _timers; }
+
+ private:
+ ValueMap _counters;
+ ValueMap _gauges;
+ ValueMap _timers;
+};
+
+} // namespace metrics
+} // namespace jaegertracing
+
+#endif // JAEGERTRACING_METRICS_INMEMORYSTATSREPORTER_H
diff --git a/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/metrics/Metric.cpp b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/metrics/Metric.cpp
new file mode 100644
index 000000000..34c625777
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/metrics/Metric.cpp
@@ -0,0 +1,17 @@
+/*
+ * 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.
+ */
+
+#include "jaegertracing/metrics/Metric.h"
diff --git a/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/metrics/Metric.h b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/metrics/Metric.h
new file mode 100644
index 000000000..efdbb4b43
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/metrics/Metric.h
@@ -0,0 +1,57 @@
+/*
+ * 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_METRICS_METRIC_H
+#define JAEGERTRACING_METRICS_METRIC_H
+
+#include <string>
+#include <unordered_map>
+
+#include "jaegertracing/Compilers.h"
+
+namespace jaegertracing {
+namespace metrics {
+
+class Metric {
+ public:
+ using TagMap = std::unordered_map<std::string, std::string>;
+
+ Metric(const std::string& name, const TagMap& tags)
+ : _name(name)
+ , _tags(tags)
+ {
+ }
+
+ virtual ~Metric() = default;
+
+ const std::string& name() const { return _name; }
+
+ const TagMap& tags() const { return _tags; }
+
+ protected:
+ std::string& name() { return _name; }
+
+ TagMap& tags() { return _tags; }
+
+ private:
+ std::string _name;
+ TagMap _tags;
+};
+
+} // namespace metrics
+} // namespace jaegertracing
+
+#endif // JAEGERTRACING_METRICS_METRIC_H
diff --git a/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/metrics/Metrics.cpp b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/metrics/Metrics.cpp
new file mode 100644
index 000000000..57c5c2a46
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/metrics/Metrics.cpp
@@ -0,0 +1,52 @@
+/*
+ * 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.
+ */
+
+#include "jaegertracing/metrics/Metrics.h"
+#include "jaegertracing/metrics/Counter.h"
+#include "jaegertracing/metrics/Gauge.h"
+#include "jaegertracing/metrics/NullStatsFactory.h"
+#include <iterator>
+#include <map>
+#include <sstream>
+#include <utility>
+
+namespace jaegertracing {
+namespace metrics {
+
+std::unique_ptr<Metrics> Metrics::makeNullMetrics()
+{
+ metrics::NullStatsFactory factory;
+ return std::unique_ptr<Metrics>(new Metrics(factory));
+}
+
+std::string Metrics::addTagsToMetricName(
+ const std::string& name,
+ const std::unordered_map<std::string, std::string>& tags)
+{
+ std::ostringstream buffer;
+ buffer << name;
+ const std::map<std::string, std::string> orderedMap(std::begin(tags),
+ std::end(tags));
+ for (auto&& pair : orderedMap) {
+ buffer << '.' << pair.first << '=' << pair.second;
+ }
+ return buffer.str();
+}
+
+Metrics::~Metrics() = default;
+
+} // namespace metrics
+} // namespace jaegertracing
diff --git a/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/metrics/Metrics.h b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/metrics/Metrics.h
new file mode 100644
index 000000000..5c12d052d
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/metrics/Metrics.h
@@ -0,0 +1,243 @@
+/*
+ * 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_METRICS_METRICS_H
+#define JAEGERTRACING_METRICS_METRICS_H
+
+#include <string>
+#include <unordered_map>
+
+#include "jaegertracing/Compilers.h"
+
+#include "jaegertracing/metrics/Counter.h"
+#include "jaegertracing/metrics/Gauge.h"
+#include "jaegertracing/metrics/StatsFactory.h"
+#include "jaegertracing/metrics/StatsFactoryImpl.h"
+#include "jaegertracing/metrics/StatsReporter.h"
+
+namespace jaegertracing {
+namespace metrics {
+
+class Metrics {
+ public:
+ static std::unique_ptr<Metrics> makeNullMetrics();
+
+ static std::unique_ptr<Metrics> fromStatsReporter(StatsReporter& reporter)
+ {
+ // Factory only used for constructor, so need not live past the
+ // initialization of Metrics object.
+ StatsFactoryImpl factory(reporter);
+ return std::unique_ptr<Metrics>(new Metrics(factory));
+ }
+
+ static std::string addTagsToMetricName(
+ const std::string& name,
+ const std::unordered_map<std::string, std::string>& tags);
+
+ explicit Metrics(StatsFactory& factory)
+ : _tracesStartedSampled(factory.createCounter(
+ "jaeger.traces", { { "state", "started" }, { "sampled", "y" } }))
+ , _tracesStartedNotSampled(factory.createCounter(
+ "jaeger.traces", { { "state", "started" }, { "sampled", "n" } }))
+ , _spansStarted(factory.createCounter(
+ "jaeger.spans",
+ { { "state", "started" }, { "group", "lifecycle" } }))
+ , _spansFinished(factory.createCounter(
+ "jaeger.spans",
+ { { "state", "finished" }, { "group", "lifecycle" } }))
+ , _spansSampled(factory.createCounter(
+ "jaeger.spans", { { "group", "sampling" }, { "sampled", "y" } }))
+ , _spansNotSampled(factory.createCounter(
+ "jaeger.spans", { { "group", "sampling" }, { "sampled", "n" } }))
+ , _decodingErrors(factory.createCounter("jaeger.decoding-errors"))
+ , _reporterSuccess(factory.createCounter("jaeger.reporter-spans",
+ { { "state", "success" } }))
+ , _reporterFailure(factory.createCounter("jaeger.reporter-spans",
+ { { "state", "failure" } }))
+ , _reporterDropped(factory.createCounter("jaeger.reporter-spans",
+ { { "state", "dropped" } }))
+ , _reporterQueueLength(factory.createGauge("jaeger.reporter-queue"))
+ , _samplerRetrieved(factory.createCounter("jaeger.sampler",
+ { { "state", "retrieved" } }))
+ , _samplerUpdated(factory.createCounter("jaeger.sampler",
+ { { "state", "updated" } }))
+ , _samplerUpdateFailure(factory.createCounter(
+ "jaeger.sampler",
+ { { "state", "failure" }, { "phase", "updating" } }))
+ , _samplerQueryFailure(factory.createCounter(
+ "jaeger.sampler",
+ { { "state", "failure" }, { "phase", "query" } }))
+ , _samplerParsingFailure(factory.createCounter(
+ "jaeger.sampler",
+ { { "state", "failure" }, { "phase", "parsing" } }))
+ , _baggageUpdateSuccess(factory.createCounter("jaeger.baggage-update",
+ { { "result", "ok" } }))
+ , _baggageUpdateFailure(factory.createCounter("jaeger.baggage-update",
+ { { "result", "err" } }))
+ , _baggageTruncate(factory.createCounter("jaeger.baggage-truncate"))
+ , _baggageRestrictionsUpdateSuccess(factory.createCounter(
+ "jaeger.baggage-restrictions-update", { { "result", "ok" } }))
+ , _baggageRestrictionsUpdateFailure(factory.createCounter(
+ "jaeger.baggage-restrictions-update", { { "result", "err" } }))
+ {
+ }
+
+ ~Metrics();
+
+ const Counter& tracesStartedSampled() const
+ {
+ return *_tracesStartedSampled;
+ }
+
+ Counter& tracesStartedSampled() { return *_tracesStartedSampled; }
+
+ const Counter& tracesStartedNotSampled() const
+ {
+ return *_tracesStartedNotSampled;
+ }
+
+ Counter& tracesStartedNotSampled() { return *_tracesStartedNotSampled; }
+
+ const Counter& spansStarted() const { return *_spansStarted; }
+
+ Counter& spansStarted() { return *_spansStarted; }
+
+ const Counter& spansFinished() const { return *_spansFinished; }
+
+ Counter& spansFinished() { return *_spansFinished; }
+
+ const Counter& spansSampled() const { return *_spansSampled; }
+
+ Counter& spansSampled() { return *_spansSampled; }
+
+ const Counter& spansNotSampled() const { return *_spansNotSampled; }
+
+ Counter& spansNotSampled() { return *_spansNotSampled; }
+
+ const Counter& decodingErrors() const { return *_decodingErrors; }
+
+ Counter& decodingErrors() { return *_decodingErrors; }
+
+ const Counter& reporterSuccess() const { return *_reporterSuccess; }
+
+ Counter& reporterSuccess() { return *_reporterSuccess; }
+
+ const Counter& reporterFailure() const { return *_reporterFailure; }
+
+ Counter& reporterFailure() { return *_reporterFailure; }
+
+ const Counter& reporterDropped() const { return *_reporterDropped; }
+
+ Counter& reporterDropped() { return *_reporterDropped; }
+
+ const Gauge& reporterQueueLength() const { return *_reporterQueueLength; }
+
+ Gauge& reporterQueueLength() { return *_reporterQueueLength; }
+
+ const Counter& samplerRetrieved() const { return *_samplerRetrieved; }
+
+ Counter& samplerRetrieved() { return *_samplerRetrieved; }
+
+ const Counter& samplerUpdated() const { return *_samplerUpdated; }
+
+ Counter& samplerUpdated() { return *_samplerUpdated; }
+
+ const Counter& samplerUpdateFailure() const
+ {
+ return *_samplerUpdateFailure;
+ }
+
+ Counter& samplerUpdateFailure() { return *_samplerUpdateFailure; }
+
+ const Counter& samplerQueryFailure() const { return *_samplerQueryFailure; }
+
+ Counter& samplerQueryFailure() { return *_samplerQueryFailure; }
+
+ const Counter& samplerParsingFailure() const
+ {
+ return *_samplerParsingFailure;
+ }
+
+ Counter& samplerParsingFailure() { return *_samplerParsingFailure; }
+
+ const Counter& baggageUpdateSuccess() const
+ {
+ return *_baggageUpdateSuccess;
+ }
+
+ Counter& baggageUpdateSuccess() { return *_baggageUpdateSuccess; }
+
+ const Counter& baggageUpdateFailure() const
+ {
+ return *_baggageUpdateFailure;
+ }
+
+ Counter& baggageUpdateFailure() { return *_baggageUpdateFailure; }
+
+ const Counter& baggageTruncate() const { return *_baggageTruncate; }
+
+ Counter& baggageTruncate() { return *_baggageTruncate; }
+
+ const Counter& baggageRestrictionsUpdateSuccess() const
+ {
+ return *_baggageRestrictionsUpdateSuccess;
+ }
+
+ Counter& baggageRestrictionsUpdateSuccess()
+ {
+ return *_baggageRestrictionsUpdateSuccess;
+ }
+
+ const Counter& baggageRestrictionsUpdateFailure() const
+ {
+ return *_baggageRestrictionsUpdateFailure;
+ }
+
+ Counter& baggageRestrictionsUpdateFailure()
+ {
+ return *_baggageRestrictionsUpdateFailure;
+ }
+
+ private:
+ std::unique_ptr<Counter> _tracesStartedSampled;
+ std::unique_ptr<Counter> _tracesStartedNotSampled;
+ std::unique_ptr<Counter> _tracesJoinedSampled;
+ std::unique_ptr<Counter> _tracesJoinedNotSampled;
+ std::unique_ptr<Counter> _spansStarted;
+ std::unique_ptr<Counter> _spansFinished;
+ std::unique_ptr<Counter> _spansSampled;
+ std::unique_ptr<Counter> _spansNotSampled;
+ std::unique_ptr<Counter> _decodingErrors;
+ std::unique_ptr<Counter> _reporterSuccess;
+ std::unique_ptr<Counter> _reporterFailure;
+ std::unique_ptr<Counter> _reporterDropped;
+ std::unique_ptr<Gauge> _reporterQueueLength;
+ std::unique_ptr<Counter> _samplerRetrieved;
+ std::unique_ptr<Counter> _samplerUpdated;
+ std::unique_ptr<Counter> _samplerUpdateFailure;
+ std::unique_ptr<Counter> _samplerQueryFailure;
+ std::unique_ptr<Counter> _samplerParsingFailure;
+ std::unique_ptr<Counter> _baggageUpdateSuccess;
+ std::unique_ptr<Counter> _baggageUpdateFailure;
+ std::unique_ptr<Counter> _baggageTruncate;
+ std::unique_ptr<Counter> _baggageRestrictionsUpdateSuccess;
+ std::unique_ptr<Counter> _baggageRestrictionsUpdateFailure;
+};
+
+} // namespace metrics
+} // namespace jaegertracing
+
+#endif // JAEGERTRACING_METRICS_METRICS_H
diff --git a/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/metrics/MetricsTest.cpp b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/metrics/MetricsTest.cpp
new file mode 100644
index 000000000..f9c7eeb27
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/metrics/MetricsTest.cpp
@@ -0,0 +1,111 @@
+/*
+ * 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.
+ */
+
+#include "jaegertracing/metrics/Counter.h"
+#include "jaegertracing/metrics/Gauge.h"
+#include "jaegertracing/metrics/InMemoryStatsReporter.h"
+#include "jaegertracing/metrics/Metrics.h"
+#include "jaegertracing/metrics/StatsFactoryImpl.h"
+#include "jaegertracing/metrics/Timer.h"
+#include <cstdint>
+#include <gtest/gtest.h>
+#include <iterator>
+#include <memory>
+#include <unordered_map>
+#include <utility>
+
+namespace jaegertracing {
+namespace metrics {
+
+class MetricsTest : public ::testing::Test {
+ public:
+ MetricsTest()
+ : _metricsReporter()
+ , _metrics(Metrics::fromStatsReporter(_metricsReporter))
+ {
+ }
+
+ protected:
+ InMemoryStatsReporter _metricsReporter;
+ std::unique_ptr<Metrics> _metrics;
+};
+
+TEST_F(MetricsTest, testCounter)
+{
+ constexpr auto counterValue = static_cast<int64_t>(3);
+ constexpr auto metricName = "jaeger.test-counter";
+ StatsFactoryImpl factory(_metricsReporter);
+ auto counter = factory.createCounter(metricName);
+ counter->inc(counterValue);
+ const auto& counters = _metricsReporter.counters();
+ ASSERT_EQ(1, counters.size());
+ auto itr = counters.find(metricName);
+ ASSERT_TRUE(itr != std::end(counters));
+ ASSERT_EQ(counterValue, itr->second);
+}
+
+TEST_F(MetricsTest, testGauge)
+{
+ constexpr auto gaugeValue = static_cast<int64_t>(3);
+ constexpr auto metricName = "jaeger.test-gauge";
+ StatsFactoryImpl factory(_metricsReporter);
+ auto gauge = factory.createGauge(metricName);
+ gauge->update(gaugeValue);
+ const auto& gauges = _metricsReporter.gauges();
+ ASSERT_EQ(1, gauges.size());
+ auto itr = gauges.find(metricName);
+ ASSERT_TRUE(itr != std::end(gauges));
+ ASSERT_EQ(gaugeValue, itr->second);
+}
+
+TEST_F(MetricsTest, testTimer)
+{
+ constexpr auto timeValue = static_cast<int64_t>(5);
+ constexpr auto metricName = "jaeger.test-timer";
+ StatsFactoryImpl factory(_metricsReporter);
+ auto timer = factory.createTimer(metricName);
+ timer->record(timeValue);
+ const auto& timers = _metricsReporter.timers();
+ ASSERT_EQ(1, timers.size());
+ auto itr = timers.find(metricName);
+ ASSERT_TRUE(itr != std::end(timers));
+ ASSERT_EQ(timeValue, itr->second);
+}
+
+TEST_F(MetricsTest, testReset)
+{
+ _metrics->tracesStartedSampled().inc(1);
+ const auto& counters = _metricsReporter.counters();
+ ASSERT_EQ(1, counters.size());
+
+ _metrics->reporterQueueLength().update(1);
+ const auto& gauges = _metricsReporter.gauges();
+ ASSERT_EQ(1, gauges.size());
+
+ constexpr auto time = static_cast<int64_t>(1);
+ constexpr auto timerName = "jaeger.test-timer";
+ _metricsReporter.recordTimer(timerName, time);
+ const auto& timers = _metricsReporter.timers();
+ ASSERT_EQ(1, timers.size());
+
+ _metricsReporter.reset();
+ ASSERT_TRUE(counters.empty());
+ ASSERT_TRUE(gauges.empty());
+ ASSERT_TRUE(timers.empty());
+}
+
+} // namespace metrics
+} // namespace jaegertracing
diff --git a/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/metrics/NullCounter.cpp b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/metrics/NullCounter.cpp
new file mode 100644
index 000000000..3cb68d156
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/metrics/NullCounter.cpp
@@ -0,0 +1,17 @@
+/*
+ * 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.
+ */
+
+#include "jaegertracing/metrics/NullCounter.h"
diff --git a/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/metrics/NullCounter.h b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/metrics/NullCounter.h
new file mode 100644
index 000000000..a9fc055c7
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/metrics/NullCounter.h
@@ -0,0 +1,34 @@
+/*
+ * 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_METRICS_NULLCOUNTER_H
+#define JAEGERTRACING_METRICS_NULLCOUNTER_H
+
+#include "jaegertracing/metrics/Counter.h"
+#include <cstdint>
+
+namespace jaegertracing {
+namespace metrics {
+
+class NullCounter : public Counter {
+ public:
+ void inc(int64_t) override {}
+};
+
+} // namespace metrics
+} // namespace jaegertracing
+
+#endif // JAEGERTRACING_METRICS_NULLCOUNTER_H
diff --git a/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/metrics/NullGauge.cpp b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/metrics/NullGauge.cpp
new file mode 100644
index 000000000..a4c7426ce
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/metrics/NullGauge.cpp
@@ -0,0 +1,17 @@
+/*
+ * 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.
+ */
+
+#include "jaegertracing/metrics/NullGauge.h"
diff --git a/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/metrics/NullGauge.h b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/metrics/NullGauge.h
new file mode 100644
index 000000000..22810ced5
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/metrics/NullGauge.h
@@ -0,0 +1,34 @@
+/*
+ * 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_METRICS_NULLGAUGE_H
+#define JAEGERTRACING_METRICS_NULLGAUGE_H
+
+#include "jaegertracing/metrics/Gauge.h"
+#include <cstdint>
+
+namespace jaegertracing {
+namespace metrics {
+
+class NullGauge : public Gauge {
+ public:
+ void update(int64_t) override {}
+};
+
+} // namespace metrics
+} // namespace jaegertracing
+
+#endif // JAEGERTRACING_METRICS_NULLGAUGE_H
diff --git a/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/metrics/NullStatsFactory.cpp b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/metrics/NullStatsFactory.cpp
new file mode 100644
index 000000000..ed1a77466
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/metrics/NullStatsFactory.cpp
@@ -0,0 +1,17 @@
+/*
+ * 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.
+ */
+
+#include "jaegertracing/metrics/NullStatsFactory.h"
diff --git a/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/metrics/NullStatsFactory.h b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/metrics/NullStatsFactory.h
new file mode 100644
index 000000000..5449587ef
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/metrics/NullStatsFactory.h
@@ -0,0 +1,67 @@
+/*
+ * 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_METRICS_NULLSTATSFACTORY_H
+#define JAEGERTRACING_METRICS_NULLSTATSFACTORY_H
+
+#include <memory>
+#include <string>
+#include <unordered_map>
+
+#include "jaegertracing/metrics/NullCounter.h"
+#include "jaegertracing/metrics/NullGauge.h"
+#include "jaegertracing/metrics/NullTimer.h"
+#include "jaegertracing/metrics/StatsFactory.h"
+
+namespace jaegertracing {
+namespace metrics {
+
+class Counter;
+class Gauge;
+class Timer;
+
+class NullStatsFactory : public StatsFactory {
+ public:
+ using StatsFactory::createCounter;
+ using StatsFactory::createGauge;
+ using StatsFactory::createTimer;
+
+ std::unique_ptr<Counter>
+ createCounter(const std::string&,
+ const std::unordered_map<std::string, std::string>&) override
+ {
+ return std::unique_ptr<Counter>(new NullCounter());
+ }
+
+ std::unique_ptr<Timer>
+ createTimer(const std::string&,
+ const std::unordered_map<std::string, std::string>&) override
+ {
+ return std::unique_ptr<Timer>(new NullTimer());
+ }
+
+ std::unique_ptr<Gauge>
+ createGauge(const std::string&,
+ const std::unordered_map<std::string, std::string>&) override
+ {
+ return std::unique_ptr<Gauge>(new NullGauge());
+ }
+};
+
+} // namespace metrics
+} // namespace jaegertracing
+
+#endif // JAEGERTRACING_METRICS_NULLSTATSFACTORY_H
diff --git a/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/metrics/NullStatsFactoryTest.cpp b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/metrics/NullStatsFactoryTest.cpp
new file mode 100644
index 000000000..e1afea3b4
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/metrics/NullStatsFactoryTest.cpp
@@ -0,0 +1,36 @@
+/*
+ * 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.
+ */
+
+#include "jaegertracing/metrics/Counter.h"
+#include "jaegertracing/metrics/Gauge.h"
+#include "jaegertracing/metrics/NullStatsFactory.h"
+#include "jaegertracing/metrics/Timer.h"
+#include <gtest/gtest.h>
+#include <memory>
+
+namespace jaegertracing {
+namespace metrics {
+
+TEST(NullStatsFactory, test)
+{
+ NullStatsFactory factory;
+ factory.createGauge("")->update(1);
+ factory.createTimer("")->record(1);
+ factory.createCounter("")->inc(1);
+}
+
+} // namespace metrics
+} // namespace jaegertracing
diff --git a/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/metrics/NullStatsReporter.cpp b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/metrics/NullStatsReporter.cpp
new file mode 100644
index 000000000..bad6bafae
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/metrics/NullStatsReporter.cpp
@@ -0,0 +1,17 @@
+/*
+ * 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.
+ */
+
+#include "jaegertracing/metrics/NullStatsReporter.h"
diff --git a/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/metrics/NullStatsReporter.h b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/metrics/NullStatsReporter.h
new file mode 100644
index 000000000..715ed7555
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/metrics/NullStatsReporter.h
@@ -0,0 +1,61 @@
+/*
+ * 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_METRICS_NULLSTATSREPORTER_H
+#define JAEGERTRACING_METRICS_NULLSTATSREPORTER_H
+
+#include "jaegertracing/metrics/StatsReporter.h"
+#include <cstdint>
+#include <string>
+#include <unordered_map>
+
+namespace jaegertracing {
+namespace metrics {
+
+class NullStatsReporter : public StatsReporter {
+ public:
+ using StatsReporter::incCounter;
+ using StatsReporter::recordTimer;
+ using StatsReporter::updateGauge;
+
+ ~NullStatsReporter() = default;
+
+ void
+ incCounter(const std::string&,
+ int64_t,
+ const std::unordered_map<std::string, std::string>&) override
+ {
+ }
+
+ void
+ recordTimer(const std::string&,
+ int64_t,
+ const std::unordered_map<std::string, std::string>&) override
+ {
+ }
+
+ void
+ updateGauge(const std::string&,
+ int64_t,
+ const std::unordered_map<std::string, std::string>&) override
+ {
+ }
+};
+
+} // namespace metrics
+} // namespace jaegertracing
+
+#endif // JAEGERTRACING_METRICS_NULLSTATSREPORTER_H
diff --git a/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/metrics/NullTimer.cpp b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/metrics/NullTimer.cpp
new file mode 100644
index 000000000..3e596473d
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/metrics/NullTimer.cpp
@@ -0,0 +1,17 @@
+/*
+ * 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.
+ */
+
+#include "jaegertracing/metrics/NullTimer.h"
diff --git a/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/metrics/NullTimer.h b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/metrics/NullTimer.h
new file mode 100644
index 000000000..c1979ea61
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/metrics/NullTimer.h
@@ -0,0 +1,34 @@
+/*
+ * 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_METRICS_NULLTIMER_H
+#define JAEGERTRACING_METRICS_NULLTIMER_H
+
+#include "jaegertracing/metrics/Timer.h"
+#include <cstdint>
+
+namespace jaegertracing {
+namespace metrics {
+
+class NullTimer : public Timer {
+ public:
+ void record(int64_t) override {}
+};
+
+} // namespace metrics
+} // namespace jaegertracing
+
+#endif // JAEGERTRACING_METRICS_NULLTIMER_H
diff --git a/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/metrics/StatsFactory.cpp b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/metrics/StatsFactory.cpp
new file mode 100644
index 000000000..def039690
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/metrics/StatsFactory.cpp
@@ -0,0 +1,42 @@
+/*
+ * 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.
+ */
+
+#include "jaegertracing/metrics/StatsFactory.h"
+
+#include "jaegertracing/metrics/Counter.h"
+#include "jaegertracing/metrics/Gauge.h"
+#include "jaegertracing/metrics/Timer.h"
+
+namespace jaegertracing {
+namespace metrics {
+
+std::unique_ptr<Counter> StatsFactory::createCounter(const std::string& name)
+{
+ return createCounter(name, TagMap());
+}
+
+std::unique_ptr<Timer> StatsFactory::createTimer(const std::string& name)
+{
+ return createTimer(name, TagMap());
+}
+
+std::unique_ptr<Gauge> StatsFactory::createGauge(const std::string& name)
+{
+ return createGauge(name, TagMap());
+}
+
+} // namespace metrics
+} // namespace jaegertracing
diff --git a/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/metrics/StatsFactory.h b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/metrics/StatsFactory.h
new file mode 100644
index 000000000..3dedb66f2
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/metrics/StatsFactory.h
@@ -0,0 +1,58 @@
+/*
+ * 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_METRICS_STATSFACTORY_H
+#define JAEGERTRACING_METRICS_STATSFACTORY_H
+
+#include <memory>
+#include <string>
+#include <unordered_map>
+
+#include "jaegertracing/Compilers.h"
+
+namespace jaegertracing {
+namespace metrics {
+
+class Counter;
+class Gauge;
+class Timer;
+
+class StatsFactory {
+ public:
+ using TagMap = std::unordered_map<std::string, std::string>;
+
+ virtual ~StatsFactory() = default;
+
+ std::unique_ptr<Counter> createCounter(const std::string& name);
+
+ std::unique_ptr<Timer> createTimer(const std::string& name);
+
+ std::unique_ptr<Gauge> createGauge(const std::string& name);
+
+ virtual std::unique_ptr<Counter> createCounter(const std::string& name,
+ const TagMap& tags) = 0;
+
+ virtual std::unique_ptr<Timer> createTimer(const std::string& name,
+ const TagMap& tags) = 0;
+
+ virtual std::unique_ptr<Gauge> createGauge(const std::string& name,
+ const TagMap& tags) = 0;
+};
+
+} // namespace metrics
+} // namespace jaegertracing
+
+#endif // JAEGERTRACING_METRICS_STATSFACTORY_H
diff --git a/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/metrics/StatsFactoryImpl.cpp b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/metrics/StatsFactoryImpl.cpp
new file mode 100644
index 000000000..bbd8ec29b
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/metrics/StatsFactoryImpl.cpp
@@ -0,0 +1,122 @@
+/*
+ * 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.
+ */
+
+#include "jaegertracing/metrics/StatsFactoryImpl.h"
+#include "jaegertracing/metrics/Counter.h"
+#include "jaegertracing/metrics/Gauge.h"
+#include "jaegertracing/metrics/Metric.h"
+#include "jaegertracing/metrics/StatsReporter.h"
+#include "jaegertracing/metrics/Timer.h"
+#include <cstdint>
+
+namespace jaegertracing {
+namespace metrics {
+namespace {
+
+class ReportedMetric : public Metric {
+ public:
+ ReportedMetric(StatsReporter& reporter,
+ const std::string& name,
+ const TagMap& tags)
+ : Metric(name, tags)
+ , _reporter(reporter)
+ {
+ }
+
+ virtual ~ReportedMetric() = default;
+
+ protected:
+ StatsReporter& reporter() { return _reporter; }
+
+ private:
+ StatsReporter& _reporter;
+};
+
+class CounterImpl : public ReportedMetric, public Counter {
+ public:
+ CounterImpl(StatsReporter& reporter,
+ const std::string& name,
+ const std::unordered_map<std::string, std::string>& tags)
+ : ReportedMetric(reporter, name, tags)
+ {
+ }
+
+ void inc(int64_t delta) override
+ {
+ reporter().incCounter(name(), delta, tags());
+ }
+};
+
+class TimerImpl : public ReportedMetric, public Timer {
+ public:
+ TimerImpl(StatsReporter& reporter,
+ const std::string& name,
+ const std::unordered_map<std::string, std::string>& tags)
+ : ReportedMetric(reporter, name, tags)
+ {
+ }
+
+ void record(int64_t time) override
+ {
+ reporter().recordTimer(name(), time, tags());
+ }
+};
+
+class GaugeImpl : public ReportedMetric, public Gauge {
+ public:
+ GaugeImpl(StatsReporter& reporter,
+ const std::string& name,
+ const std::unordered_map<std::string, std::string>& tags)
+ : ReportedMetric(reporter, name, tags)
+ {
+ }
+
+ void update(int64_t amount) override
+ {
+ reporter().updateGauge(name(), amount, tags());
+ }
+};
+
+} // anonymous namespace
+
+StatsFactoryImpl::StatsFactoryImpl(StatsReporter& reporter)
+ : _reporter(reporter)
+{
+}
+
+std::unique_ptr<Counter> StatsFactoryImpl::createCounter(
+ const std::string& name,
+ const std::unordered_map<std::string, std::string>& tags)
+{
+ return std::unique_ptr<Counter>(new CounterImpl(_reporter, name, tags));
+}
+
+std::unique_ptr<Timer> StatsFactoryImpl::createTimer(
+ const std::string& name,
+ const std::unordered_map<std::string, std::string>& tags)
+{
+ return std::unique_ptr<Timer>(new TimerImpl(_reporter, name, tags));
+}
+
+std::unique_ptr<Gauge> StatsFactoryImpl::createGauge(
+ const std::string& name,
+ const std::unordered_map<std::string, std::string>& tags)
+{
+ return std::unique_ptr<Gauge>(new GaugeImpl(_reporter, name, tags));
+}
+
+} // namespace metrics
+} // namespace jaegertracing
diff --git a/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/metrics/StatsFactoryImpl.h b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/metrics/StatsFactoryImpl.h
new file mode 100644
index 000000000..28e090e38
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/metrics/StatsFactoryImpl.h
@@ -0,0 +1,63 @@
+/*
+ * 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_METRICS_STATSFACTORYIMPL_H
+#define JAEGERTRACING_METRICS_STATSFACTORYIMPL_H
+
+#include <memory>
+#include <string>
+#include <unordered_map>
+
+#include "jaegertracing/metrics/StatsFactory.h"
+#include "jaegertracing/metrics/StatsReporter.h"
+
+namespace jaegertracing {
+namespace metrics {
+
+class Counter;
+class Gauge;
+class Timer;
+
+class StatsFactoryImpl : public StatsFactory {
+ public:
+ using StatsFactory::createCounter;
+ using StatsFactory::createGauge;
+ using StatsFactory::createTimer;
+
+ explicit StatsFactoryImpl(StatsReporter& reporter);
+
+ ~StatsFactoryImpl() = default;
+
+ std::unique_ptr<Counter> createCounter(
+ const std::string& name,
+ const std::unordered_map<std::string, std::string>& tags) override;
+
+ std::unique_ptr<Timer> createTimer(
+ const std::string& name,
+ const std::unordered_map<std::string, std::string>& tags) override;
+
+ std::unique_ptr<Gauge> createGauge(
+ const std::string& name,
+ const std::unordered_map<std::string, std::string>& tags) override;
+
+ private:
+ StatsReporter& _reporter;
+};
+
+} // namespace metrics
+} // namespace jaegertracing
+
+#endif // JAEGERTRACING_METRICS_STATSFACTORYIMPL_H
diff --git a/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/metrics/StatsReporter.cpp b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/metrics/StatsReporter.cpp
new file mode 100644
index 000000000..b11d641b7
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/metrics/StatsReporter.cpp
@@ -0,0 +1,17 @@
+/*
+ * 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.
+ */
+
+#include "jaegertracing/metrics/StatsReporter.h"
diff --git a/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/metrics/StatsReporter.h b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/metrics/StatsReporter.h
new file mode 100644
index 000000000..960dd5091
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/metrics/StatsReporter.h
@@ -0,0 +1,62 @@
+/*
+ * 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_METRICS_STATSREPORTER_H
+#define JAEGERTRACING_METRICS_STATSREPORTER_H
+
+#include <cstdint>
+#include <string>
+#include <unordered_map>
+
+namespace jaegertracing {
+namespace metrics {
+
+class StatsReporter {
+ public:
+ using TagMap = std::unordered_map<std::string, std::string>;
+
+ virtual ~StatsReporter() = default;
+
+ void incCounter(const std::string& name, int64_t delta)
+ {
+ incCounter(name, delta, TagMap());
+ }
+
+ void recordTimer(const std::string& name, int64_t delta)
+ {
+ recordTimer(name, delta, TagMap());
+ }
+
+ void updateGauge(const std::string& name, int64_t delta)
+ {
+ updateGauge(name, delta, TagMap());
+ }
+
+ virtual void
+ incCounter(const std::string& name, int64_t delta, const TagMap& tags) = 0;
+
+ virtual void
+ recordTimer(const std::string& name, int64_t time, const TagMap& tags) = 0;
+
+ virtual void updateGauge(const std::string& name,
+ int64_t amount,
+ const TagMap& tags) = 0;
+};
+
+} // namespace metrics
+} // namespace jaegertracing
+
+#endif // JAEGERTRACING_METRICS_STATSREPORTER_H
diff --git a/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/metrics/Timer.cpp b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/metrics/Timer.cpp
new file mode 100644
index 000000000..47ffe3fc8
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/metrics/Timer.cpp
@@ -0,0 +1,17 @@
+/*
+ * 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.
+ */
+
+#include "jaegertracing/metrics/Timer.h"
diff --git a/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/metrics/Timer.h b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/metrics/Timer.h
new file mode 100644
index 000000000..8c2298883
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/metrics/Timer.h
@@ -0,0 +1,35 @@
+/*
+ * 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_METRICS_TIMER_H
+#define JAEGERTRACING_METRICS_TIMER_H
+
+#include <stdint.h>
+
+namespace jaegertracing {
+namespace metrics {
+
+class Timer {
+ public:
+ virtual ~Timer() = default;
+
+ virtual void record(int64_t time) = 0;
+};
+
+} // namespace metrics
+} // namespace jaegertracing
+
+#endif // JAEGERTRACING_METRICS_TIMER_H
diff --git a/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/net/IPAddress.cpp b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/net/IPAddress.cpp
new file mode 100644
index 000000000..44393dfc0
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/net/IPAddress.cpp
@@ -0,0 +1,206 @@
+/*
+ * 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.
+ */
+
+#include "jaegertracing/net/IPAddress.h"
+#include "jaegertracing/platform/Hostname.h"
+#include "jaegertracing/net/Socket.h"
+
+#include <sys/types.h>
+
+#ifndef WIN32
+#include <ifaddrs.h>
+#endif
+
+namespace jaegertracing {
+namespace net {
+
+namespace {
+
+template <typename T>
+struct CDeleter : public std::function<void(T*)> {
+ void operator()(T* ifAddr) const
+ {
+#ifdef WIN32
+ free(ifAddr);
+#else
+ if (ifAddr) {
+ ::freeifaddrs(ifAddr);
+ }
+#endif
+ }
+};
+
+} // anonymous namespace
+
+#ifdef WIN32
+
+IPAddress _localIP(int family)
+{
+ DWORD size = 15032;
+ DWORD rv = GetAdaptersAddresses(
+ AF_UNSPEC, GAA_FLAG_INCLUDE_PREFIX, NULL, NULL, &size);
+ if (rv != ERROR_BUFFER_OVERFLOW) {
+ // GetAdaptersAddresses() failed...
+ return IPAddress();
+ }
+ std::unique_ptr<IP_ADAPTER_ADDRESSES, CDeleter<IP_ADAPTER_ADDRESSES>>
+ adapter_addresses((IP_ADAPTER_ADDRESSES*)malloc(size));
+
+ rv = GetAdaptersAddresses(
+ AF_UNSPEC, GAA_FLAG_INCLUDE_PREFIX, NULL, &*adapter_addresses, &size);
+ if (rv != ERROR_SUCCESS) {
+ // GetAdaptersAddresses() failed...
+ return IPAddress();
+ }
+
+ for (PIP_ADAPTER_ADDRESSES aa = &*adapter_addresses; aa != NULL;
+ aa = aa->Next) {
+ for (PIP_ADAPTER_UNICAST_ADDRESS ua = aa->FirstUnicastAddress;
+ ua != NULL;
+ ua = ua->Next) {
+ if (family == ua->Address.lpSockaddr->sa_family) {
+ char buf[BUFSIZ] = { 0 };
+ getnameinfo(ua->Address.lpSockaddr,
+ ua->Address.iSockaddrLength,
+ buf,
+ sizeof(buf),
+ NULL,
+ 0,
+ NI_NUMERICHOST);
+
+ return IPAddress(*(ua->Address.lpSockaddr),
+ (family == AF_INET) ? sizeof(::sockaddr_in)
+ : sizeof(::sockaddr_in6));
+ }
+ }
+ }
+
+ return IPAddress();
+}
+
+#else
+
+namespace {
+
+IPAddress _localIP(std::function<bool(const ifaddrs*)> filter)
+{
+ auto* ifAddrRawPtr = static_cast<ifaddrs*>(nullptr);
+ getifaddrs(&ifAddrRawPtr);
+ std::unique_ptr<ifaddrs, CDeleter<ifaddrs>> ifAddr(ifAddrRawPtr);
+ for (auto* itr = ifAddr.get(); itr; itr = itr->ifa_next) {
+ if (filter(itr)) {
+ const auto family = ifAddr->ifa_addr->sa_family;
+ const auto addrLen = (family == AF_INET) ? sizeof(::sockaddr_in)
+ : sizeof(::sockaddr_in6);
+ return IPAddress(*itr->ifa_addr, addrLen);
+ }
+ }
+ return IPAddress();
+}
+
+IPAddress _localIP(int family)
+{
+ return _localIP([family](const ifaddrs* ifAddr) {
+ return ifAddr->ifa_addr != nullptr &&
+ ifAddr->ifa_addr->sa_family == family;
+ });
+}
+
+
+} // anonymous namespace
+
+#endif
+
+IPAddress IPAddress::localIP(int family)
+{
+ try {
+ return versionFromString(platform::hostname(), 0, family);
+ } catch (...) {
+ // Fall back to returning the first matching interface
+ }
+ return _localIP(family);
+}
+
+IPAddress
+IPAddress::versionFromString(const std::string& ip, int port, int family)
+{
+ ::sockaddr_storage addrStorage;
+ std::memset(&addrStorage, 0, sizeof(addrStorage));
+
+ auto* addrBuffer = static_cast<void*>(nullptr);
+ if (family == AF_INET) {
+ ::sockaddr_in& addr = *reinterpret_cast<::sockaddr_in*>(&addrStorage);
+ addr.sin_family = family;
+ addr.sin_port = htons(port);
+ addrBuffer = &addr.sin_addr;
+ }
+ else {
+ assert(family == AF_INET6);
+ ::sockaddr_in6& addr = *reinterpret_cast<::sockaddr_in6*>(&addrStorage);
+ addr.sin6_family = family;
+ addr.sin6_port = htons(port);
+ addrBuffer = &addr.sin6_addr;
+ }
+
+ const auto returnCode = inet_pton(family, ip.c_str(), addrBuffer);
+
+ if (returnCode == 0) {
+ auto result = resolveAddress(ip, port, family);
+ assert(result);
+ std::memcpy(&addrStorage, result->ai_addr, result->ai_addrlen);
+ }
+ return IPAddress(addrStorage,
+ family == AF_INET ? sizeof(::sockaddr_in)
+ : sizeof(::sockaddr_in6));
+}
+
+std::unique_ptr<::addrinfo, AddrInfoDeleter>
+resolveAddress(const std::string& host, int port, int family, int type)
+{
+// On windows, getaddrinfo does not return an error for empty host
+#ifdef WIN32
+ if (host.empty()) {
+ throw std::runtime_error("Error resolving address: ");
+ }
+#endif
+ ::addrinfo hints;
+ std::memset(&hints, 0, sizeof(hints));
+ hints.ai_family = family;
+ hints.ai_socktype = type;
+
+ std::string service;
+ if (port != 0) {
+ service = std::to_string(port);
+ }
+
+ Socket::OSResource osResouce;
+
+ auto* servInfoPtr = static_cast<::addrinfo*>(nullptr);
+ const auto returnCode =
+ getaddrinfo(host.c_str(), service.c_str(), &hints, &servInfoPtr);
+ std::unique_ptr<::addrinfo, AddrInfoDeleter> servInfo(servInfoPtr);
+
+ if (returnCode != 0) {
+ std::ostringstream oss;
+ oss << "Error resolving address: " << gai_strerror(returnCode);
+ throw std::runtime_error(oss.str());
+ }
+
+ return servInfo;
+}
+
+} // namespace net
+} // namespace jaegertracing
diff --git a/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/net/IPAddress.h b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/net/IPAddress.h
new file mode 100644
index 000000000..46e15e899
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/net/IPAddress.h
@@ -0,0 +1,209 @@
+/*
+ * 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_NET_IPADDRESS_H
+#define JAEGERTRACING_NET_IPADDRESS_H
+
+
+#include <array>
+#include <cassert>
+#include <cstring>
+#include <functional>
+#include <memory>
+#include <sstream>
+#include <stdexcept>
+#include <system_error>
+#include <vector>
+
+#include "jaegertracing/Compilers.h"
+
+#ifdef WIN32
+#include <winsock2.h>
+#include <iphlpapi.h>
+#include <ws2tcpip.h>
+#include <windows.h>
+#else
+#include <arpa/inet.h>
+#include <netdb.h>
+#include <sys/socket.h>
+#include <sys/types.h>
+#include <unistd.h>
+#endif
+
+
+
+
+struct ifaddrs;
+
+namespace jaegertracing {
+namespace net {
+
+class IPAddress {
+ public:
+ static std::pair<std::string, int> parse(const std::string& hostPort)
+ {
+ const auto colonPos = hostPort.find(':');
+ const auto ip = hostPort.substr(0, colonPos);
+ int port = 0;
+ if (colonPos != std::string::npos) {
+ const auto portStr = hostPort.substr(colonPos + 1);
+ std::istringstream iss(portStr);
+ if (!(iss >> port)) {
+ port = 0;
+ }
+ }
+ return std::make_pair(ip, port);
+ }
+
+ static IPAddress v4(const std::string& hostPort)
+ {
+ auto result = parse(hostPort);
+ return v4(result.first, result.second);
+ }
+
+ static IPAddress v4(const std::string& ip, int port)
+ {
+ return versionFromString(ip, port, AF_INET);
+ }
+
+ static IPAddress v6(const std::string& ip, int port)
+ {
+ return versionFromString(ip, port, AF_INET6);
+ }
+
+ static IPAddress localIP(int family);
+
+ IPAddress()
+ : _addr()
+ , _addrLen(sizeof(::sockaddr_in))
+ {
+ std::memset(&_addr, 0, sizeof(_addr));
+ }
+
+ IPAddress(const ::sockaddr_storage& addr, ::socklen_t addrLen)
+ : _addr(addr)
+ , _addrLen(addrLen)
+ {
+ }
+
+ IPAddress(const ::sockaddr& addr, ::socklen_t addrLen)
+ : IPAddress()
+ {
+ std::memcpy(&_addr, &addr, addrLen);
+ }
+
+ explicit IPAddress(const ::sockaddr_in& addr)
+ : IPAddress(reinterpret_cast<const ::sockaddr&>(addr), sizeof(addr))
+ {
+ }
+
+ explicit IPAddress(const ::sockaddr_in6& addr)
+ : IPAddress(reinterpret_cast<const ::sockaddr&>(addr), sizeof(addr))
+ {
+ }
+
+ bool operator==(const IPAddress& rhs) const
+ {
+ if (_addrLen != rhs._addrLen) {
+ return false;
+ }
+ return std::memcmp(&_addr, &rhs._addr, _addrLen) == 0;
+ }
+
+ const ::sockaddr_storage& addr() const { return _addr; }
+
+ ::socklen_t addrLen() const { return _addrLen; }
+
+ void print(std::ostream& out) const
+ {
+ out << "{ family=" << family();
+ const auto addrStr = host();
+ if (!addrStr.empty()) {
+ out << ", addr=" << addrStr;
+ }
+ out << ", port=" << port() << " }";
+ }
+
+ std::string authority() const
+ {
+ const auto portNum = port();
+ if (portNum != 0) {
+ return host() + ':' + std::to_string(portNum);
+ }
+ return host();
+ }
+
+ std::string host() const
+ {
+ std::array<char, INET6_ADDRSTRLEN> buffer;
+ const auto af = family();
+ const auto* addrStr = ::inet_ntop(
+ af,
+ af == AF_INET
+ ? const_cast<void*>(
+ static_cast<const void*>(
+ &reinterpret_cast<const ::sockaddr_in&>(_addr).sin_addr))
+ : const_cast<void*>(
+ static_cast<const void*>(
+ &reinterpret_cast<const ::sockaddr_in6&>(_addr).sin6_addr)),
+ &buffer[0],
+ buffer.size());
+ return addrStr ? addrStr : "";
+ }
+
+ int port() const
+ {
+ if (family() == AF_INET) {
+ return ntohs(
+ reinterpret_cast<const ::sockaddr_in&>(_addr).sin_port);
+ }
+ return ntohs(reinterpret_cast<const ::sockaddr_in6&>(_addr).sin6_port);
+ }
+
+ int family() const
+ {
+ if (_addrLen == sizeof(::sockaddr_in)) {
+ return AF_INET;
+ }
+ assert(_addrLen == sizeof(::sockaddr_in6));
+ return AF_INET6;
+ }
+
+ private:
+ static IPAddress versionFromString(const std::string& ip, int port, int family);
+
+ ::sockaddr_storage _addr;
+ ::socklen_t _addrLen;
+};
+
+struct AddrInfoDeleter : public std::function<void(::addrinfo*)> {
+ void operator()(::addrinfo* addrInfo) const { ::freeaddrinfo(addrInfo); }
+};
+
+std::unique_ptr<::addrinfo, AddrInfoDeleter> resolveAddress(
+ const std::string& host, int port, int family, int type = SOCK_STREAM);
+
+} // namespace net
+} // namespace jaegertracing
+
+inline std::ostream& operator<<(std::ostream& out,
+ const jaegertracing::net::IPAddress& addr)
+{
+ addr.print(out);
+ return out;
+}
+
+#endif // JAEGERTRACING_NET_IPADDRESS_H
diff --git a/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/net/IPAddressTest.cpp b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/net/IPAddressTest.cpp
new file mode 100644
index 000000000..6d5300d7c
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/net/IPAddressTest.cpp
@@ -0,0 +1,54 @@
+/*
+ * 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.
+ */
+
+#include "jaegertracing/net/IPAddress.h"
+#include <gtest/gtest.h>
+#include <stdexcept>
+
+namespace jaegertracing {
+namespace net {
+
+TEST(IPAddress, testParseFail)
+{
+ ASSERT_THROW(IPAddress::v4("", 0), std::runtime_error);
+}
+
+TEST(IPAddress, testAuthority)
+{
+ ASSERT_EQ("127.0.0.1", IPAddress::v4("127.0.0.1", 0).authority());
+ ASSERT_EQ("127.0.0.1:1234", IPAddress::v4("127.0.0.1", 1234).authority());
+}
+
+TEST(IPAddress, testIPv6)
+{
+ ASSERT_EQ("2001:db8:ac10:fe01::",
+ IPAddress::v6("2001:db8:ac10:fe01::", 0).authority());
+}
+
+TEST(IPAddress, testResolveAddress)
+{
+ ASSERT_NO_THROW(resolveAddress("localhost", 80, AF_INET, SOCK_STREAM));
+#ifdef WIN32
+ ASSERT_THROW(resolveAddress("123456", 80, AF_INET, SOCK_STREAM),
+ std::runtime_error);
+#else
+ ASSERT_NO_THROW(resolveAddress("123456", 80, AF_INET, SOCK_STREAM));
+#endif
+ ASSERT_THROW(resolveAddress("localhost", 80, -1), std::runtime_error);
+}
+
+} // namespace net
+} // namespace jaegertracing
diff --git a/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/net/Socket.cpp b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/net/Socket.cpp
new file mode 100644
index 000000000..7dc0df5bd
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/net/Socket.cpp
@@ -0,0 +1,84 @@
+/*
+ * 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.
+ */
+
+#include "jaegertracing/net/Socket.h"
+
+#ifdef WIN32
+
+#include <stdio.h>
+#include <windows.h>
+#include <winsock2.h>
+#include <ws2tcpip.h>
+
+#endif
+
+namespace jaegertracing {
+namespace net {
+
+namespace {
+
+
+void initSocket()
+{
+#ifdef WIN32
+ /* Use the MAKEWORD(lowbyte, highbyte) macro declared in Windef.h */
+ WORD wVersionRequested = MAKEWORD(2, 2);
+
+ WSADATA wsaData;
+ int err = WSAStartup(wVersionRequested, &wsaData);
+ if (err != 0) {
+ std::ostringstream oss;
+ oss << "Failed to find a usable Winsock DLL. WSAStartup failed with "
+ "error "
+ << err;
+ throw std::system_error(errno, std::system_category(), oss.str());
+ }
+
+ /* Confirm that the WinSock DLL supports 2.2.*/
+ /* Note that if the DLL supports versions greater */
+ /* than 2.2 in addition to 2.2, it will still return */
+ /* 2.2 in wVersion since that is the version we */
+ /* requested. */
+
+ if (LOBYTE(wsaData.wVersion) != 2 || HIBYTE(wsaData.wVersion) != 2) {
+ WSACleanup();
+
+ std::ostringstream oss;
+ oss << "Failed to find a usable Winsock DLL. WSAStartup failed with "
+ "error "
+ << err;
+ throw std::system_error(errno, std::system_category(), oss.str());
+ }
+#endif
+}
+
+void cleanSocket()
+{
+#ifdef WIN32
+ WSACleanup();
+#endif
+}
+
+}
+
+
+Socket::OSResource::OSResource() { initSocket(); }
+
+Socket::OSResource::~OSResource() { cleanSocket(); }
+
+
+} // namespace net
+} // namespace jaegertracing
diff --git a/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/net/Socket.h b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/net/Socket.h
new file mode 100644
index 000000000..ee936fcf4
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/net/Socket.h
@@ -0,0 +1,245 @@
+/*
+ * 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_NET_SOCKET_H
+#define JAEGERTRACING_NET_SOCKET_H
+
+#include "jaegertracing/net/IPAddress.h"
+#include "jaegertracing/net/URI.h"
+#include <errno.h>
+#include <memory>
+#include <ostream>
+#include <stdexcept>
+#include <string>
+#include <system_error>
+
+#ifdef WIN32
+#include <iphlpapi.h>
+#include <windows.h>
+#include <winsock2.h>
+#include <ws2tcpip.h>
+
+typedef SOCKET HandleType;
+
+#else
+#include <arpa/inet.h>
+#include <netdb.h>
+#include <sys/socket.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+typedef int HandleType;
+
+#endif
+
+#ifdef _MSC_VER
+#pragma warning(push)
+#pragma warning(disable : 4267)
+#endif
+
+namespace jaegertracing {
+namespace net {
+
+
+
+class Socket {
+ public:
+ Socket()
+ : _handle(-1)
+ , _family(-1)
+ , _type(-1)
+ {
+ }
+
+ Socket(const Socket&) = delete;
+
+ Socket& operator=(const Socket&) = delete;
+
+ Socket(Socket&& socket)
+ : _handle(socket._handle)
+ , _family(socket._family)
+ , _type(socket._type)
+ {
+ socket._handle = -1;
+ }
+
+ Socket& operator=(Socket&& rhs)
+ {
+ _handle = rhs._handle;
+ _family = rhs._family;
+ _type = rhs._type;
+ return *this;
+ }
+
+ ~Socket()
+ {
+ close();
+ }
+
+ void open(int family, int type)
+ {
+ const auto handle = ::socket(family, type, 0);
+ if (isHandleInvalid(handle)) {
+ std::ostringstream oss;
+ oss << "Failed to open socket"
+ ", family="
+ << family << ", type=" << type;
+ throw std::system_error(errno, std::system_category(), oss.str());
+ }
+ _handle = handle;
+ _family = family;
+ _type = type;
+ }
+
+ void bind(const IPAddress& addr)
+ {
+ const auto returnCode =
+ ::bind(_handle,
+ reinterpret_cast<const ::sockaddr*>(&addr.addr()),
+ addr.addrLen());
+ if (returnCode != 0) {
+ std::ostringstream oss;
+ oss << "Failed to bind socket to address"
+ ", addr=";
+ addr.print(oss);
+ throw std::system_error(errno, std::system_category(), oss.str());
+ }
+ }
+
+ void bind(const std::string& ip, int port)
+ {
+ const auto addr = IPAddress::v4(ip, port);
+ bind(addr);
+ }
+
+ void connect(const IPAddress& serverAddr)
+ {
+ const auto returnCode =
+ ::connect(_handle,
+ reinterpret_cast<const ::sockaddr*>(&serverAddr.addr()),
+ serverAddr.addrLen());
+ if (returnCode != 0) {
+ std::ostringstream oss;
+ oss << "Cannot connect socket to remote address ";
+ serverAddr.print(oss);
+ throw std::runtime_error(oss.str());
+ }
+ }
+
+ IPAddress connect(const std::string& serverURIStr)
+ {
+ return connect(URI::parse(serverURIStr));
+ }
+
+ IPAddress connect(const URI& serverURI)
+ {
+ auto result =
+ resolveAddress(serverURI._host, serverURI._port, AF_INET, _type);
+ for (const auto* itr = result.get(); itr; itr = itr->ai_next) {
+ const auto returnCode =
+ ::connect(_handle, itr->ai_addr, itr->ai_addrlen);
+ if (returnCode == 0) {
+ return IPAddress(*itr->ai_addr, itr->ai_addrlen);
+ }
+ }
+ std::ostringstream oss;
+ oss << "Cannot connect socket to remote address ";
+ serverURI.print(oss);
+ throw std::runtime_error(oss.str());
+ }
+
+ static constexpr auto kDefaultBacklog = 128;
+
+ void listen(int backlog = kDefaultBacklog)
+ {
+ const auto returnCode = ::listen(_handle, backlog);
+ if (returnCode != 0) {
+ throw std::system_error(
+ errno, std::system_category(), "Failed to listen on socket");
+ }
+ }
+
+ Socket accept()
+ {
+ ::sockaddr_storage addrStorage;
+ ::socklen_t addrLen = sizeof(addrStorage);
+ const auto clientHandle = ::accept(
+ _handle, reinterpret_cast<::sockaddr*>(&addrStorage), &addrLen);
+
+ if (isHandleInvalid(clientHandle)) {
+ throw std::system_error(
+ errno, std::system_category(), "Failed to accept on socket");
+ }
+
+ Socket clientSocket;
+ clientSocket._handle = clientHandle;
+ clientSocket._family =
+ (addrLen == sizeof(::sockaddr_in)) ? AF_INET : AF_INET6;
+ clientSocket._type = SOCK_STREAM;
+ return clientSocket;
+ }
+
+ void close() noexcept
+ {
+ if (_handle >= 0) {
+#ifdef WIN32
+ ::closesocket(_handle);
+#else
+ ::close(_handle);
+#endif
+ _handle = -1;
+ }
+ }
+
+ HandleType handle() { return _handle; }
+ private:
+ class OSResource {
+ public:
+ OSResource();
+ ~OSResource();
+
+ OSResource(const OSResource&) = delete;
+ OSResource& operator=(const OSResource&) = delete;
+ OSResource& operator=(const OSResource&&) = delete;
+ };
+
+ OSResource _osResource;
+ HandleType _handle;
+ int _family;
+ int _type;
+
+ static bool isHandleInvalid(HandleType h)
+ {
+#ifdef WIN32
+ return (h == SOCKET_ERROR);
+#else
+ return (h < 0);
+#endif
+ }
+
+ friend class IPAddress;
+ friend std::unique_ptr<::addrinfo, AddrInfoDeleter>
+ resolveAddress(const std::string& host, int port, int family, int type);
+};
+
+} // namespace net
+} // namespace jaegertracing
+
+#ifdef _MSC_VER
+#pragma warning(pop)
+#endif
+
+#endif // JAEGERTRACING_NET_SOCKET_H
diff --git a/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/net/SocketTest.cpp b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/net/SocketTest.cpp
new file mode 100644
index 000000000..beaef6394
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/net/SocketTest.cpp
@@ -0,0 +1,74 @@
+/*
+ * 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.
+ */
+
+#include "jaegertracing/net/IPAddress.h"
+#include "jaegertracing/net/Socket.h"
+#include "jaegertracing/net/URI.h"
+#include <gtest/gtest.h>
+#include <stdexcept>
+#include <system_error>
+
+namespace jaegertracing {
+namespace net {
+
+TEST(Socket, testFailOpen)
+{
+ Socket socket;
+ ASSERT_THROW(socket.open(-5, -10), std::system_error);
+}
+
+// On Windows, the bind does not throw
+ #ifndef WIN32
+TEST(Socket, testFailBind)
+{
+ Socket socket;
+ socket.open(AF_INET, SOCK_STREAM);
+ ASSERT_THROW(socket.bind(IPAddress::v4("127.0.0.1", 1)), std::system_error);
+}
+#endif
+
+TEST(Socket, testFailConnect)
+{
+ Socket socket;
+ socket.open(AF_INET, SOCK_STREAM);
+ ASSERT_THROW(socket.connect(IPAddress::v4("127.0.0.1", 12345)),
+ std::runtime_error);
+}
+
+TEST(Socket, testFailConnectURI)
+{
+ Socket socket;
+ socket.open(AF_INET, SOCK_STREAM);
+ const auto uri = URI::parse("http://127.0.0.1:12345");
+ ASSERT_THROW(socket.connect(uri), std::runtime_error);
+}
+
+TEST(Socket, testFailListen)
+{
+ Socket socket;
+ socket.open(AF_INET, SOCK_DGRAM);
+ ASSERT_THROW(socket.listen(), std::system_error);
+}
+
+TEST(Socket, testFailAccept)
+{
+ Socket socket;
+ socket.open(AF_INET, SOCK_DGRAM);
+ ASSERT_THROW(socket.accept(), std::system_error);
+}
+
+} // namespace net
+} // namespace jaegertracing
diff --git a/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/net/URI.cpp b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/net/URI.cpp
new file mode 100644
index 000000000..b4adf18a2
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/net/URI.cpp
@@ -0,0 +1,224 @@
+/*
+ * Copyright (c) 2017-2018 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.
+ */
+
+#include "jaegertracing/net/URI.h"
+
+#include <cassert>
+#include <cstring>
+#include <iomanip>
+#include <iostream>
+#include <regex>
+#include <cctype>
+
+namespace jaegertracing {
+namespace net {
+namespace {
+
+bool isHex(char ch)
+{
+ return (ch >= '0' && ch <= '9') || (ch >= 'A' && ch <= 'F') ||
+ (ch >= 'a' && ch <= 'f');
+}
+
+int decodeHex(char ch)
+{
+ if (ch >= '0' && ch <= '9') {
+ return ch - '0';
+ }
+ if (ch >= 'A' && ch <= 'F') {
+ return ch - 'A' + 10;
+ }
+ assert(ch >= 'a' && ch <= 'f');
+ return ch - 'a' + 10;
+}
+
+bool isUnreserved(char ch)
+{
+ if (std::isalpha(ch) || std::isdigit(ch)) {
+ return true;
+ }
+
+ switch (ch) {
+ case '-':
+ case '.':
+ case '_':
+ case '~':
+ return true;
+ default:
+ return false;
+ }
+}
+
+} // anonymous namespace
+
+URI URI::parse(const std::string& uriStr)
+{
+ // See https://tools.ietf.org/html/rfc3986 for explanation.
+ URI uri;
+ std::regex uriRegex(
+ "^(([^:/?#]+):)?(//([^/?#]*))?([^?#]*)(\\?([^#]*))?(#(.*))?",
+ std::regex::extended);
+ std::smatch match;
+ std::regex_match(uriStr, match, uriRegex);
+
+ constexpr auto kSchemeIndex = 2;
+ constexpr auto kAuthorityIndex = 4;
+ constexpr auto kPathIndex = 5;
+ constexpr auto kQueryIndex = 7;
+
+ assert(match.size() >= kQueryIndex);
+
+ uri._scheme = match[kSchemeIndex].str();
+
+ const auto authority = match[kAuthorityIndex].str();
+ const auto colonPos = authority.find(':');
+ if (colonPos == std::string::npos) {
+ uri._host = authority;
+ }
+ else {
+ uri._host = authority.substr(0, colonPos);
+ const auto portStr = authority.substr(colonPos + 1);
+ std::istringstream iss(portStr);
+ iss >> uri._port;
+ }
+
+ uri._path = match[kPathIndex].str();
+ uri._query = match[kQueryIndex].str();
+
+ return uri;
+}
+
+std::string URI::queryEscape(const std::string& input)
+{
+ std::ostringstream oss;
+ for (auto&& ch : input) {
+ if (isUnreserved(ch)) {
+ oss << ch;
+ }
+ else {
+ oss << '%' << std::uppercase << std::hex << static_cast<int>(ch);
+ }
+ }
+ return oss.str();
+}
+
+std::string URI::queryUnescape(const std::string& input)
+{
+ enum class State { kDefault, kPercent, kFirstHex };
+
+ std::ostringstream oss;
+ auto hex = 0;
+ auto state = State::kDefault;
+ for (auto&& ch : input) {
+ switch (state) {
+ case State::kDefault: {
+ if (ch == '%') {
+ state = State::kPercent;
+ }
+ else {
+ oss.put(ch);
+ }
+ } break;
+ case State::kPercent: {
+ if (isHex(ch)) {
+ state = State::kFirstHex;
+ hex = (decodeHex(ch) & 0xff);
+ }
+ else {
+ state = State::kDefault;
+ oss.put('%');
+ oss.put(ch);
+ }
+ } break;
+ default: {
+ assert(state == State::kFirstHex);
+ if (isHex(ch)) {
+ hex <<= 4;
+ hex |= (decodeHex(ch) & 0xff);
+ oss.put(static_cast<char>(hex));
+ }
+ else {
+ oss.put('%');
+ oss << std::hex << hex;
+ oss.put(ch);
+ }
+ state = State::kDefault;
+ hex = 0;
+ } break;
+ }
+ }
+ return oss.str();
+}
+
+URI::QueryValueMap URI::parseQueryValues() const
+{
+ enum class State { kKey, kValue };
+
+ if (_query.empty()) {
+ return QueryValueMap();
+ }
+
+ QueryValueMap values;
+ auto state = State::kKey;
+ std::string keyBuffer;
+ std::string valueBuffer;
+ for (auto&& ch : _query) {
+ switch (state) {
+ case State::kKey: {
+ switch (ch) {
+ case '=': {
+ valueBuffer.clear();
+ state = State::kValue;
+ } break;
+ case '&': {
+ values.insert(std::make_pair(queryUnescape(keyBuffer), ""));
+ keyBuffer.clear();
+ state = State::kKey;
+ } break;
+ default: {
+ keyBuffer.push_back(ch);
+ }
+ }
+ } break;
+ default: {
+ assert(state == State::kValue);
+ if (ch == '&') {
+ values.insert(std::make_pair(queryUnescape(keyBuffer),
+ queryUnescape(valueBuffer)));
+ keyBuffer.clear();
+ state = State::kKey;
+ }
+ else {
+ valueBuffer.push_back(ch);
+ }
+ } break;
+ }
+ }
+
+ if (!keyBuffer.empty()) {
+ if (state == State::kKey) {
+ values.insert(std::make_pair(queryUnescape(keyBuffer), ""));
+ }
+ else if (state == State::kValue) {
+ values.insert(std::make_pair(queryUnescape(keyBuffer),
+ queryUnescape(valueBuffer)));
+ }
+ }
+ return values;
+}
+
+} // namespace net
+} // namespace jaegertracing
diff --git a/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/net/URI.h b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/net/URI.h
new file mode 100644
index 000000000..65743659a
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/net/URI.h
@@ -0,0 +1,96 @@
+/*
+ * 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_NET_URI_H
+#define JAEGERTRACING_NET_URI_H
+
+#include <functional>
+#include <memory>
+#include <sstream>
+#include <string>
+#include <unordered_map>
+
+#include "jaegertracing/Compilers.h"
+
+namespace jaegertracing {
+namespace net {
+
+struct URI {
+ using QueryValueMap = std::unordered_multimap<std::string, std::string>;
+
+ static URI parse(const std::string& uriStr);
+
+ static std::string queryEscape(const std::string& input);
+
+ static std::string queryUnescape(const std::string& input);
+
+ URI()
+ : _scheme()
+ , _host()
+ , _port(0)
+ , _path()
+ , _query()
+ {
+ }
+
+ std::string authority() const
+ {
+ if (_port != 0) {
+ return _host + ':' + std::to_string(_port);
+ }
+ return _host;
+ }
+
+ std::string target() const
+ {
+ auto result = _path;
+ if (result.empty()) {
+ result = "/";
+ }
+ if (!_query.empty()) {
+ result += '?' + _query;
+ }
+ return result;
+ }
+
+ template <typename Stream>
+ void print(Stream& out) const
+ {
+ out << "{ scheme=\"" << _scheme << '"' << ", host=\"" << _host << '"'
+ << ", port=" << _port << ", path=\"" << _path << '"' << ", query=\""
+ << _query << '"' << " }";
+ }
+
+ QueryValueMap parseQueryValues() const;
+
+ std::string _scheme;
+ std::string _host;
+ int _port;
+ std::string _path;
+ std::string _query;
+};
+
+} // namespace net
+} // namespace jaegertracing
+
+inline std::ostream& operator<<(std::ostream& out,
+ const jaegertracing::net::URI& uri)
+{
+ uri.print(out);
+ return out;
+}
+
+#endif // JAEGERTRACING_NET_URI_H
diff --git a/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/net/URITest.cpp b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/net/URITest.cpp
new file mode 100644
index 000000000..70628b0db
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/net/URITest.cpp
@@ -0,0 +1,118 @@
+/*
+ * 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.
+ */
+
+#include "jaegertracing/net/URI.h"
+#include <gtest/gtest.h>
+#include <iosfwd>
+#include <iterator>
+#include <string>
+#include <unordered_map>
+#include <utility>
+
+namespace jaegertracing {
+namespace net {
+
+TEST(URI, testMatch)
+{
+ ASSERT_EQ(0, URI::parse("http://localhost")._port);
+ ASSERT_EQ(80, URI::parse("http://localhost:80")._port);
+}
+
+TEST(URI, testAuthority)
+{
+ ASSERT_EQ("localhost", URI::parse("http://localhost").authority());
+ ASSERT_EQ("localhost:80", URI::parse("http://localhost:80").authority());
+}
+
+TEST(URI, testPrint)
+{
+ std::ostringstream oss;
+ oss << URI::parse("localhost");
+ ASSERT_EQ(
+ "{ scheme=\"\""
+ ", host=\"\""
+ ", port=0"
+ ", path=\"localhost\""
+ ", query=\"\" }",
+ oss.str());
+}
+
+TEST(URI, queryEscape)
+{
+ ASSERT_EQ("hello%20world", URI::queryEscape("hello world"));
+ ASSERT_EQ("hello-world", URI::queryEscape("hello-world"));
+ ASSERT_EQ("hello.world", URI::queryEscape("hello.world"));
+ ASSERT_EQ("hello_world", URI::queryEscape("hello_world"));
+ ASSERT_EQ("hello~world", URI::queryEscape("hello~world"));
+ ASSERT_EQ("hello%3Aworld", URI::queryEscape("hello:world"));
+}
+
+TEST(URI, queryUnescape)
+{
+ ASSERT_EQ("hello world", URI::queryUnescape("hello%20world"));
+ ASSERT_EQ("hello%2world", URI::queryUnescape("hello%2world"));
+ ASSERT_EQ("hello%world", URI::queryUnescape("hello%world"));
+ ASSERT_EQ("hello world", URI::queryUnescape("hello w%6Frld"));
+ ASSERT_EQ("hello world", URI::queryUnescape("hello w%6frld"));
+}
+
+TEST(URI, testParseQueryValues)
+{
+ {
+ const auto uri = URI::parse(
+ "http://example.com?test1=1&test2=%6F&test2=r&test3&test4");
+ const auto values = uri.parseQueryValues();
+ ASSERT_EQ(5, values.size());
+
+ const auto test1 = values.equal_range("test1");
+ ASSERT_EQ(1, std::distance(test1.first, test1.second));
+ ASSERT_EQ("test1", test1.first->first);
+ ASSERT_EQ("1", test1.first->second);
+
+ const auto test2 = values.equal_range("test2");
+ ASSERT_EQ(2, std::distance(test2.first, test2.second));
+ auto test2Itr = test2.first;
+ ASSERT_EQ("test2", test2Itr->first);
+ ASSERT_TRUE(test2Itr->second == "o" || test2Itr->second == "r");
+ auto nextTest2Value = (test2Itr->second == "o") ? "r" : "o";
+ ++test2Itr;
+ ASSERT_EQ("test2", test2Itr->first);
+ ASSERT_EQ(nextTest2Value, test2Itr->second);
+
+ const auto test3 = values.equal_range("test3");
+ ASSERT_EQ(1, std::distance(test3.first, test3.second));
+ ASSERT_EQ("test3", test3.first->first);
+ ASSERT_TRUE(test3.first->second.empty());
+
+ const auto test4 = values.equal_range("test4");
+ ASSERT_EQ(1, std::distance(test4.first, test4.second));
+ ASSERT_EQ("test4", test4.first->first);
+ ASSERT_TRUE(test4.first->second.empty());
+ }
+
+ ASSERT_TRUE(URI::parse("http://example.com").parseQueryValues().empty());
+
+ {
+ const auto uri = URI::parse("http://example.com?key=value");
+ const auto values = uri.parseQueryValues();
+ ASSERT_EQ(1, values.size());
+ ASSERT_EQ("key", std::begin(values)->first);
+ ASSERT_EQ("value", std::begin(values)->second);
+ }
+}
+
+} // namespace net
+} // namespace jaegertracing
diff --git a/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/net/http/Error.cpp b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/net/http/Error.cpp
new file mode 100644
index 000000000..b280f1b3c
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/net/http/Error.cpp
@@ -0,0 +1,17 @@
+/*
+ * 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.
+ */
+
+#include "jaegertracing/net/http/Error.h"
diff --git a/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/net/http/Error.h b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/net/http/Error.h
new file mode 100644
index 000000000..e38ce24cb
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/net/http/Error.h
@@ -0,0 +1,46 @@
+/*
+ * 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_NET_HTTP_ERROR_H
+#define JAEGERTRACING_NET_HTTP_ERROR_H
+
+#include <sstream>
+#include <stdexcept>
+#include <string>
+
+namespace jaegertracing {
+namespace net {
+namespace http {
+
+class ParseError : public std::invalid_argument {
+ public:
+ using invalid_argument::invalid_argument;
+
+ static ParseError make(const std::string& expected,
+ const std::string& actual)
+ {
+ std::ostringstream oss;
+ oss << "Parse error, expected " << expected << ", encountered \""
+ << actual << '"';
+ return ParseError(oss.str());
+ }
+};
+
+} // namespace http
+} // namespace net
+} // namespace jaegertracing
+
+#endif // JAEGERTRACING_NET_HTTP_ERROR_H
diff --git a/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/net/http/Header.cpp b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/net/http/Header.cpp
new file mode 100644
index 000000000..993966a52
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/net/http/Header.cpp
@@ -0,0 +1,17 @@
+/*
+ * 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.
+ */
+
+#include "jaegertracing/net/http/Header.h"
diff --git a/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/net/http/Header.h b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/net/http/Header.h
new file mode 100644
index 000000000..27d0d65bc
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/net/http/Header.h
@@ -0,0 +1,98 @@
+/*
+ * Copyright (c) 2017-2018 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_NET_HTTP_HEADER_H
+#define JAEGERTRACING_NET_HTTP_HEADER_H
+
+#include <cassert>
+#include <regex>
+#include <string>
+
+#include "jaegertracing/net/http/Error.h"
+
+namespace jaegertracing {
+namespace net {
+namespace http {
+
+class Header {
+ public:
+ Header() = default;
+
+ Header(const std::string& key, const std::string& value)
+ : _key(key)
+ , _value(value)
+ {
+ }
+
+ const std::string& key() const { return _key; }
+
+ const std::string& value() const { return _value; }
+
+ private:
+ std::string _key;
+ std::string _value;
+};
+
+inline std::istream& readLineCRLF(std::istream& in, std::string& line)
+{
+ line.clear();
+ auto ch = '\0';
+ auto sawCR = false;
+ while (in.get(ch)) {
+ if (sawCR) {
+ if (ch == '\n') {
+ break;
+ }
+ else {
+ line.push_back('\r');
+ line.push_back(ch);
+ sawCR = false;
+ }
+ }
+ else {
+ if (ch == '\r') {
+ sawCR = true;
+ }
+ else {
+ line.push_back(ch);
+ }
+ }
+ }
+
+ return in;
+}
+
+inline void readHeaders(std::istream& in, std::vector<Header>& headers)
+{
+ const std::regex headerPattern("([^:]+): (.+)$");
+ std::string line;
+ std::smatch match;
+ while (readLineCRLF(in, line)) {
+ if (line.empty()) {
+ break;
+ }
+ if (!std::regex_match(line, match, headerPattern) || match.size() < 3) {
+ throw ParseError::make("header", line);
+ }
+ headers.emplace_back(Header(match[1], match[2]));
+ }
+}
+
+} // namespace http
+} // namespace net
+} // namespace jaegertracing
+
+#endif // JAEGERTRACING_NET_HTTP_HEADER_H
diff --git a/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/net/http/HeaderTest.cpp b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/net/http/HeaderTest.cpp
new file mode 100644
index 000000000..487f46927
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/net/http/HeaderTest.cpp
@@ -0,0 +1,49 @@
+/*
+ * 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.
+ */
+
+#include "jaegertracing/net/http/Header.h"
+#include <gtest/gtest.h>
+#include <ostream>
+#include <string>
+#include <vector>
+
+namespace jaegertracing {
+namespace net {
+namespace http {
+
+class ParseError;
+
+TEST(Header, readLine)
+{
+ std::stringstream ss;
+ ss << "test\r123\r\n";
+ std::string line;
+ while (readLineCRLF(ss, line)) {
+ ASSERT_EQ("test\r123", line);
+ }
+}
+
+TEST(Header, readHeaders)
+{
+ std::stringstream ss;
+ ss << "Bad Header\r\n";
+ std::vector<Header> headers;
+ ASSERT_THROW(readHeaders(ss, headers), ParseError);
+}
+
+} // namespace http
+} // namespace net
+} // namespace jaegertracing
diff --git a/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/net/http/Method.cpp b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/net/http/Method.cpp
new file mode 100644
index 000000000..210f40b3d
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/net/http/Method.cpp
@@ -0,0 +1,48 @@
+/*
+ * 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.
+ */
+
+#include "jaegertracing/net/http/Method.h"
+#include <algorithm>
+#include <initializer_list>
+#include <iterator>
+
+namespace jaegertracing {
+namespace net {
+namespace http {
+
+Method parseMethod(const std::string& methodName)
+{
+#ifdef WIN32
+ static constexpr char* kMethodNames[] = { "OPTIONS", "GET", "HEAD",
+ "POST", "PUT", "DELETE",
+ "TRACE", "CONNECT" };
+#else
+ static auto kMethodNames = { "OPTIONS", "GET", "HEAD", "POST",
+ "PUT", "DELETE", "TRACE", "CONNECT" };
+#endif
+
+
+ auto itr =
+ std::find(std::begin(kMethodNames), std::end(kMethodNames), methodName);
+ if (itr == std::end(kMethodNames)) {
+ return Method::EXTENSION;
+ }
+ return static_cast<Method>(std::distance(std::begin(kMethodNames), itr));
+}
+
+} // namespace http
+} // namespace net
+} // namespace jaegertracing
diff --git a/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/net/http/Method.h b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/net/http/Method.h
new file mode 100644
index 000000000..223e9452f
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/net/http/Method.h
@@ -0,0 +1,46 @@
+/*
+ * 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_NET_HTTP_METHOD_H
+#define JAEGERTRACING_NET_HTTP_METHOD_H
+
+#include <string>
+
+#undef DELETE
+
+namespace jaegertracing {
+namespace net {
+namespace http {
+
+enum class Method {
+ OPTIONS,
+ GET,
+ HEAD,
+ POST,
+ PUT,
+ DELETE,
+ TRACE,
+ CONNECT,
+ EXTENSION
+};
+
+Method parseMethod(const std::string& methodName);
+
+} // namespace http
+} // namespace net
+} // namespace jaegertracing
+
+#endif // JAEGERTRACING_NET_HTTP_METHOD_H
diff --git a/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/net/http/MethodTest.cpp b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/net/http/MethodTest.cpp
new file mode 100644
index 000000000..df371e0f3
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/net/http/MethodTest.cpp
@@ -0,0 +1,39 @@
+/*
+ * 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.
+ */
+
+#include "jaegertracing/net/http/Method.h"
+#include <gtest/gtest.h>
+
+namespace jaegertracing {
+namespace net {
+namespace http {
+
+TEST(Method, testParse)
+{
+ ASSERT_EQ(Method::OPTIONS, parseMethod("OPTIONS"));
+ ASSERT_EQ(Method::GET, parseMethod("GET"));
+ ASSERT_EQ(Method::HEAD, parseMethod("HEAD"));
+ ASSERT_EQ(Method::POST, parseMethod("POST"));
+ ASSERT_EQ(Method::PUT, parseMethod("PUT"));
+ ASSERT_EQ(Method::DELETE, parseMethod("DELETE"));
+ ASSERT_EQ(Method::TRACE, parseMethod("TRACE"));
+ ASSERT_EQ(Method::CONNECT, parseMethod("CONNECT"));
+ ASSERT_EQ(Method::EXTENSION, parseMethod("post"));
+}
+
+} // namespace http
+} // namespace net
+} // namespace jaegertracing
diff --git a/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/net/http/Request.cpp b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/net/http/Request.cpp
new file mode 100644
index 000000000..bd0d75569
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/net/http/Request.cpp
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2017-2018 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.
+ */
+
+#include "jaegertracing/net/http/Request.h"
+#include "jaegertracing/net/http/SocketReader.h"
+
+#include <regex>
+
+namespace jaegertracing {
+namespace net {
+namespace http {
+
+Request Request::read(Socket & socket)
+{
+ std::string response = SocketReader::read(socket);
+ std::istringstream responseStream(response);
+ return Request::parse(responseStream);
+}
+
+Request Request::parse(std::istream& in)
+{
+ const std::regex requestLinePattern(
+ "([A-Z]+) ([^ ]+) HTTP/([0-9]\\.[0-9])$");
+ std::string line;
+ std::smatch match;
+ if (!readLineCRLF(in, line) ||
+ !std::regex_match(line, match, requestLinePattern) ||
+ match.size() < 4) {
+ throw ParseError::make("request line", line);
+ }
+ Request request;
+
+ request._method = parseMethod(match[1]);
+ request._target = match[2];
+ request._version = match[3];
+
+ readHeaders(in, request._headers);
+ request._body = std::string(std::istreambuf_iterator<char>(in),
+ std::istreambuf_iterator<char>{});
+
+ return request;
+}
+
+} // namespace http
+} // namespace net
+} // namespace jaegertracing
diff --git a/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/net/http/Request.h b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/net/http/Request.h
new file mode 100644
index 000000000..3e5f5a9c1
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/net/http/Request.h
@@ -0,0 +1,66 @@
+/*
+ * 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_NET_HTTP_REQUEST_H
+#define JAEGERTRACING_NET_HTTP_REQUEST_H
+
+#include "jaegertracing/net/URI.h"
+#include "jaegertracing/net/Socket.h"
+#include "jaegertracing/net/http/Error.h"
+#include "jaegertracing/net/http/Header.h"
+#include "jaegertracing/net/http/Method.h"
+
+namespace jaegertracing {
+namespace net {
+namespace http {
+
+class Request {
+ public:
+ static Request parse(std::istream& in);
+
+ static Request read(Socket& in);
+
+ Request()
+ : _method()
+ , _target()
+ , _version()
+ , _headers()
+ {
+ }
+
+ Method method() const { return _method; }
+
+ const std::string& target() const { return _target; }
+
+ const std::string& version() const { return _version; }
+
+ const std::vector<Header>& headers() const { return _headers; }
+
+ const std::string& body() const { return _body; }
+
+ private:
+ Method _method;
+ std::string _target;
+ std::string _version;
+ std::vector<Header> _headers;
+ std::string _body;
+};
+
+} // namespace http
+} // namespace net
+} // namespace jaegertracing
+
+#endif // JAEGERTRACING_NET_HTTP_REQUEST_H
diff --git a/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/net/http/Response.cpp b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/net/http/Response.cpp
new file mode 100644
index 000000000..6de74e746
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/net/http/Response.cpp
@@ -0,0 +1,94 @@
+/*
+ * Copyright (c) 2017-2018 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.
+ */
+
+#include "jaegertracing/net/http/Response.h"
+#include "jaegertracing/net/http/SocketReader.h"
+
+#include <regex>
+#include <sstream>
+#include <stdexcept>
+
+#include "jaegertracing/Constants.h"
+#include "jaegertracing/net/Socket.h"
+
+#ifdef _MSC_VER
+#pragma warning(disable : 4267)
+#endif
+
+namespace jaegertracing {
+namespace net {
+namespace http {
+
+Response Response::parse(std::istream& in)
+{
+ const std::regex statusLinePattern("HTTP/([0-9]\\.[0-9]) ([0-9]+) (.+)$");
+ std::string line;
+ std::smatch match;
+ if (!readLineCRLF(in, line) ||
+ !std::regex_match(line, match, statusLinePattern) || match.size() < 4) {
+ throw ParseError::make("status line", line);
+ }
+ Response response;
+ response._version = match[1];
+ std::istringstream iss(match[2]);
+ iss >> response._statusCode;
+ response._reason = match[3];
+
+ readHeaders(in, response._headers);
+
+ response._body = std::string(std::istreambuf_iterator<char>(in),
+ std::istreambuf_iterator<char>{});
+
+ return response;
+}
+
+Response read(Socket & socket)
+{
+ std::string response = SocketReader::read(socket);
+ std::istringstream responseStream(response);
+ return Response::parse(responseStream);
+}
+
+Response get(const URI& uri)
+{
+ Socket socket;
+ socket.open(AF_INET, SOCK_STREAM);
+ socket.connect(uri);
+ std::ostringstream requestStream;
+ requestStream << "GET " << uri.target() << " HTTP/1.1\r\n"
+ << "Host: " << uri.authority()
+ << "\r\n"
+ "User-Agent: jaegertracing/"
+ << kJaegerClientVersion << "\r\n\r\n";
+ const auto request = requestStream.str();
+#ifdef WIN32
+ const auto numWritten = ::send(socket.handle(), request.c_str(), request.size(), 0);
+#else
+ const auto numWritten = ::write(socket.handle(), request.c_str(), request.size());
+#endif
+ if (numWritten != static_cast<int>(request.size())) {
+ std::ostringstream oss;
+ oss << "Failed to write entire HTTP request"
+ << ", uri=" << uri << ", request=" << request;
+ throw std::system_error(errno, std::system_category(), oss.str());
+ }
+
+ return read(socket);
+}
+
+} // namespace http
+} // namespace net
+} // namespace jaegertracing
diff --git a/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/net/http/Response.h b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/net/http/Response.h
new file mode 100644
index 000000000..59a0fe9b0
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/net/http/Response.h
@@ -0,0 +1,70 @@
+/*
+ * 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_NET_HTTP_RESPONSE_H
+#define JAEGERTRACING_NET_HTTP_RESPONSE_H
+
+#include "jaegertracing/net/URI.h"
+#include "jaegertracing/net/Socket.h"
+#include "jaegertracing/net/http/Error.h"
+#include "jaegertracing/net/http/Header.h"
+#include "jaegertracing/net/http/Method.h"
+
+namespace jaegertracing {
+namespace net {
+namespace http {
+
+class Response {
+ public:
+ static Response parse(std::istream& in);
+
+ Response()
+ : _version()
+ , _statusCode(0)
+ , _reason()
+ , _headers()
+ , _body()
+ {
+ }
+
+ int statusCode() const { return _statusCode; }
+
+ const std::string& reason() const { return _reason; }
+
+ const std::vector<Header>& headers() const { return _headers; }
+
+ const std::string& body() const { return _body; }
+
+ private:
+ std::string _version;
+ int _statusCode;
+ std::string _reason;
+ std::vector<Header> _headers;
+ std::string _body;
+};
+
+Response get(const URI& uri);
+
+/**
+ * Reads http response from a socket
+ */
+Response read(Socket& socket);
+
+} // namespace http
+} // namespace net
+} // namespace jaegertracing
+
+#endif // JAEGERTRACING_NET_HTTP_RESPONSE_H
diff --git a/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/net/http/ResponseTest.cpp b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/net/http/ResponseTest.cpp
new file mode 100644
index 000000000..9227f2c41
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/net/http/ResponseTest.cpp
@@ -0,0 +1,103 @@
+/*
+ * 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.
+ */
+
+#include "jaegertracing/Constants.h"
+#include "jaegertracing/net/IPAddress.h"
+#include "jaegertracing/net/Socket.h"
+#include "jaegertracing/net/URI.h"
+#include "jaegertracing/net/http/Response.h"
+#include <array>
+#include <future>
+#include <gtest/gtest.h>
+#include <ostream>
+#include <string>
+#include <thread>
+
+#ifdef _MSC_VER
+#pragma warning(disable : 4267)
+#pragma warning(disable : 4244)
+#endif
+
+namespace jaegertracing {
+namespace net {
+namespace http {
+
+namespace {
+
+#ifdef WIN32
+#define READ_ERROR SOCKET_ERROR
+#else
+#define READ_ERROR -1
+#endif
+
+static size_t read(int socketHandle, char* buffer, size_t size)
+{
+ int returnValue = ::recv(socketHandle, buffer, size, 0);
+ return (returnValue == READ_ERROR) ? 0 : returnValue;
+}
+}
+
+TEST(Response, get)
+{
+ IPAddress serverAddress;
+ std::promise<void> started;
+
+ std::thread clientThread([&serverAddress, &started]() {
+ started.get_future().wait();
+ get(URI::parse("http://" + serverAddress.authority()));
+ });
+
+ Socket socket;
+ socket.open(AF_INET, SOCK_STREAM);
+ socket.bind(IPAddress::v4("127.0.0.1", 0));
+ socket.listen();
+
+ ::sockaddr_storage addrStorage;
+ ::socklen_t addrLen = sizeof(addrStorage);
+ const auto returnCode = ::getsockname(
+ socket.handle(), reinterpret_cast<::sockaddr*>(&addrStorage), &addrLen);
+ ASSERT_EQ(0, returnCode);
+ serverAddress = IPAddress(addrStorage, addrLen);
+
+ started.set_value();
+
+ auto clientSocket = socket.accept();
+ std::array<char, 256> buffer;
+
+ const auto numRead = read(clientSocket.handle(), &buffer[0], buffer.size());
+
+ std::ostringstream oss;
+ oss << "GET / HTTP/1.1\r\n"
+ "Host: 127.0.0.1:"
+ << serverAddress.port() << "\r\n"
+ << "User-Agent: jaegertracing/" << kJaegerClientVersion << "\r\n\r\n";
+ ASSERT_EQ(oss.str(), std::string(&buffer[0], numRead));
+
+ oss.str("");
+ oss.clear();
+
+ std::string response("HTTP/1.1 200 OK\r\n\r\n");
+ response.append(buffer.size() * 2, '0');
+ const auto numWritten =
+ ::send(clientSocket.handle(), response.c_str(), response.size(), 0);
+ ASSERT_EQ(response.size(), numWritten);
+
+ clientThread.join();
+}
+
+} // namespace http
+} // namespace net
+} // namespace jaegertracing
diff --git a/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/net/http/SocketReader.h b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/net/http/SocketReader.h
new file mode 100644
index 000000000..cbaaf21c6
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/net/http/SocketReader.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2018, The Jaeger Authors.
+ *
+ * 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_NET_HTTP_SOCKET_READER_H
+#define JAEGERTRACING_NET_HTTP_SOCKET_READER_H
+
+#include "jaegertracing/net/Socket.h"
+
+namespace jaegertracing {
+namespace net {
+namespace http {
+
+class SocketReader {
+ public:
+ static std::string read(Socket& socket) {
+ constexpr auto kBufferSize = 1024;
+ std::array<char, kBufferSize> buffer{};
+ auto numRead = ::recv(socket.handle(), &buffer[0], buffer.size(), 0);
+ std::string response;
+ while (numRead > 0) {
+ response.append(&buffer[0], numRead);
+ if (numRead < static_cast<int>(buffer.size())) {
+ break;
+ }
+ numRead = ::recv(socket.handle(), &buffer[0], buffer.size(), 0);
+ }
+ return response;
+ }
+};
+
+} // namespace http
+} // namespace net
+} // namespace jaegertracing
+
+#endif // JAEGERTRACING_NET_HTTP_SOCKET_READER_H
diff --git a/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/platform/Endian.cpp b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/platform/Endian.cpp
new file mode 100644
index 000000000..e5d0f73e6
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/platform/Endian.cpp
@@ -0,0 +1,17 @@
+/*
+ * 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.
+ */
+
+#include "jaegertracing/platform/Endian.h"
diff --git a/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/platform/Endian.h b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/platform/Endian.h
new file mode 100644
index 000000000..52754ed0e
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/platform/Endian.h
@@ -0,0 +1,83 @@
+/*
+ * 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_PLATFORM_ENDIAN_H
+#define JAEGERTRACING_PLATFORM_ENDIAN_H
+
+#include <cstdint>
+
+#if defined(__APPLE__)
+
+#include <libkern/OSByteOrder.h>
+#define htobe16(x) OSSwapHostToBigInt16(x)
+#define htobe32(x) OSSwapHostToBigInt32(x)
+#define htobe64(x) OSSwapHostToBigInt64(x)
+#define be16toh(x) OSSwapBigToHostInt16(x)
+#define be32toh(x) OSSwapBigToHostInt32(x)
+#define be64toh(x) OSSwapBigToHostInt64(x)
+
+#elif defined(__linux__)
+#include <endian.h>
+#elif defined WIN32
+#include <winsock2.h>
+
+#if BYTE_ORDER == LITTLE_ENDIAN
+
+#define htobe16(x) htons(x)
+#define be16toh(x) ntohs(x)
+
+#define htobe32(x) htonl(x)
+#define be32toh(x) ntohl(x)
+
+#define htobe64(x) htonll(x)
+#define be64toh(x) ntohll(x)
+#elif BYTE_ORDER == BIG_ENDIAN
+#define htobe16(x) (x)
+#define be16toh(x) (x)
+
+#define htobe32(x) (x)
+#define be32toh(x) (x)
+
+#define htobe64(x) (x)
+#define be64toh(x) (x)
+#else
+#error byte order not supported
+#endif
+#else
+#error "unsupported platform"
+#endif
+
+namespace jaegertracing {
+namespace platform {
+namespace endian {
+
+inline uint16_t toBigEndian(uint16_t value) { return htobe16(value); }
+
+inline uint32_t toBigEndian(uint32_t value) { return htobe32(value); }
+
+inline uint64_t toBigEndian(uint64_t value) { return htobe64(value); }
+
+inline uint16_t fromBigEndian(uint16_t value) { return be16toh(value); }
+
+inline uint32_t fromBigEndian(uint32_t value) { return be32toh(value); }
+
+inline uint64_t fromBigEndian(uint64_t value) { return be64toh(value); }
+
+} // namespace endian
+} // namespace platform
+} // namespace jaegertracing
+
+#endif // JAEGERTRACING_PLATFORM_ENDIAN_H
diff --git a/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/platform/Hostname.cpp b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/platform/Hostname.cpp
new file mode 100644
index 000000000..a0d5bebad
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/platform/Hostname.cpp
@@ -0,0 +1,17 @@
+/*
+ * 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.
+ */
+
+#include "jaegertracing/platform/Hostname.h"
diff --git a/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/platform/Hostname.h b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/platform/Hostname.h
new file mode 100644
index 000000000..d5c717798
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/platform/Hostname.h
@@ -0,0 +1,58 @@
+/*
+ * 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_PLATFORM_HOSTNAME_H
+#define JAEGERTRACING_PLATFORM_HOSTNAME_H
+
+#include <errno.h>
+#include <string>
+#include <system_error>
+
+#ifdef WIN32
+#include <Winsock2.h>
+#else
+#include <unistd.h>
+#endif
+
+#ifdef _MSC_VER
+#pragma warning(push)
+#pragma warning(disable : 4267)
+#endif
+
+namespace jaegertracing {
+namespace platform {
+
+inline std::string hostname()
+{
+ constexpr auto kBufferSize = 256;
+ std::string buffer(kBufferSize, '\0');
+ const auto returnCode = ::gethostname(&buffer[0], buffer.size());
+ if (returnCode != 0) {
+ throw std::system_error(
+ errno, std::system_category(), "Failed to get hostname");
+ }
+ const auto nullPos = buffer.find('\0');
+ return buffer.substr(0, nullPos);
+}
+
+} // namespace platform
+} // namespace jaegertracing
+
+#ifdef _MSC_VER
+#pragma warning(pop)
+#endif
+
+#endif // JAEGERTRACING_PLATFORM_HOSTNAME_H
diff --git a/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/propagation/Extractor.cpp b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/propagation/Extractor.cpp
new file mode 100644
index 000000000..67ee2e534
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/propagation/Extractor.cpp
@@ -0,0 +1,17 @@
+/*
+ * 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.
+ */
+
+#include "jaegertracing/propagation/Extractor.h"
diff --git a/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/propagation/Extractor.h b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/propagation/Extractor.h
new file mode 100644
index 000000000..236659029
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/propagation/Extractor.h
@@ -0,0 +1,38 @@
+/*
+ * 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_PROPAGATION_EXTRACTOR_H
+#define JAEGERTRACING_PROPAGATION_EXTRACTOR_H
+
+#include <opentracing/propagation.h>
+
+#include "jaegertracing/SpanContext.h"
+
+namespace jaegertracing {
+namespace propagation {
+
+template <typename Reader>
+class Extractor {
+ public:
+ virtual ~Extractor() = default;
+
+ virtual SpanContext extract(Reader reader) const = 0;
+};
+
+} // namespace propagation
+} // namespace jaegertracing
+
+#endif // JAEGERTRACING_PROPAGATION_EXTRACTOR_H
diff --git a/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/propagation/HeadersConfig.cpp b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/propagation/HeadersConfig.cpp
new file mode 100644
index 000000000..87d667d0d
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/propagation/HeadersConfig.cpp
@@ -0,0 +1,17 @@
+/*
+ * 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.
+ */
+
+#include "jaegertracing/propagation/HeadersConfig.h"
diff --git a/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/propagation/HeadersConfig.h b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/propagation/HeadersConfig.h
new file mode 100644
index 000000000..4ae213555
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/propagation/HeadersConfig.h
@@ -0,0 +1,107 @@
+/*
+ * 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_PROPAGATION_HEADERSCONFIG_H
+#define JAEGERTRACING_PROPAGATION_HEADERSCONFIG_H
+
+#include "jaegertracing/Constants.h"
+#include "jaegertracing/utils/YAML.h"
+#include <string>
+
+namespace jaegertracing {
+namespace propagation {
+
+class HeadersConfig {
+ public:
+#ifdef JAEGERTRACING_WITH_YAML_CPP
+
+ static HeadersConfig parse(const YAML::Node& configYAML)
+ {
+ if (!configYAML.IsDefined() || !configYAML.IsMap()) {
+ return HeadersConfig();
+ }
+
+ const auto jaegerDebugHeader = utils::yaml::findOrDefault<std::string>(
+ configYAML, "jaegerDebugHeader", "");
+ const auto jaegerBaggageHeader =
+ utils::yaml::findOrDefault<std::string>(
+ configYAML, "jaegerBaggageHeader", "");
+ const auto traceContextHeaderName =
+ utils::yaml::findOrDefault<std::string>(
+ configYAML, "TraceContextHeaderName", "");
+ const auto traceBaggageHeaderPrefix =
+ utils::yaml::findOrDefault<std::string>(
+ configYAML, "traceBaggageHeaderPrefix", "");
+
+ return HeadersConfig(jaegerDebugHeader,
+ jaegerBaggageHeader,
+ traceContextHeaderName,
+ traceBaggageHeaderPrefix);
+ }
+
+#endif // JAEGERTRACING_WITH_YAML_CPP
+
+ HeadersConfig()
+ : HeadersConfig("", "", "", "")
+ {
+ }
+
+ HeadersConfig(const std::string& jaegerDebugHeader,
+ const std::string& jaegerBaggageHeader,
+ const std::string& traceContextHeaderName,
+ const std::string& traceBaggageHeaderPrefix)
+ : _jaegerDebugHeader(jaegerDebugHeader.empty() ? kJaegerDebugHeader
+ : jaegerDebugHeader)
+ , _jaegerBaggageHeader(jaegerBaggageHeader.empty()
+ ? kJaegerBaggageHeader
+ : jaegerBaggageHeader)
+ , _traceContextHeaderName(traceContextHeaderName.empty()
+ ? kTraceContextHeaderName
+ : traceContextHeaderName)
+ , _traceBaggageHeaderPrefix(traceBaggageHeaderPrefix.empty()
+ ? kTraceBaggageHeaderPrefix
+ : traceBaggageHeaderPrefix)
+ {
+ }
+
+ const std::string& jaegerBaggageHeader() const
+ {
+ return _jaegerBaggageHeader;
+ }
+
+ const std::string& jaegerDebugHeader() const { return _jaegerDebugHeader; }
+
+ const std::string& traceBaggageHeaderPrefix() const
+ {
+ return _traceBaggageHeaderPrefix;
+ }
+
+ const std::string& traceContextHeaderName() const
+ {
+ return _traceContextHeaderName;
+ }
+
+ private:
+ std::string _jaegerDebugHeader;
+ std::string _jaegerBaggageHeader;
+ std::string _traceContextHeaderName;
+ std::string _traceBaggageHeaderPrefix;
+};
+
+} // namespace propagation
+} // namespace jaegertracing
+
+#endif // JAEGERTRACING_PROPAGATION_HEADERSCONFIG_H
diff --git a/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/propagation/Injector.cpp b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/propagation/Injector.cpp
new file mode 100644
index 000000000..15684103c
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/propagation/Injector.cpp
@@ -0,0 +1,17 @@
+/*
+ * 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.
+ */
+
+#include "jaegertracing/propagation/Injector.h"
diff --git a/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/propagation/Injector.h b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/propagation/Injector.h
new file mode 100644
index 000000000..f6dbb4654
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/propagation/Injector.h
@@ -0,0 +1,39 @@
+/*
+ * 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_PROPAGATION_INJECTOR_H
+#define JAEGERTRACING_PROPAGATION_INJECTOR_H
+
+#include <opentracing/propagation.h>
+
+namespace jaegertracing {
+
+class SpanContext;
+
+namespace propagation {
+
+template <typename Writer>
+class Injector {
+ public:
+ virtual ~Injector() = default;
+
+ virtual void inject(const SpanContext& ctx, Writer writer) const = 0;
+};
+
+} // namespace propagation
+} // namespace jaegertracing
+
+#endif // JAEGERTRACING_PROPAGATION_INJECTOR_H
diff --git a/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/propagation/Propagator.cpp b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/propagation/Propagator.cpp
new file mode 100644
index 000000000..f26f7a944
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/propagation/Propagator.cpp
@@ -0,0 +1,17 @@
+/*
+ * 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.
+ */
+
+#include "jaegertracing/propagation/Propagator.h"
diff --git a/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/propagation/Propagator.h b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/propagation/Propagator.h
new file mode 100644
index 000000000..bf04be81f
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/propagation/Propagator.h
@@ -0,0 +1,321 @@
+/*
+ * 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_PROPAGATION_PROPAGATOR_H
+#define JAEGERTRACING_PROPAGATION_PROPAGATOR_H
+
+#include "jaegertracing/SpanContext.h"
+#include "jaegertracing/metrics/Metrics.h"
+#include "jaegertracing/net/URI.h"
+#include "jaegertracing/platform/Endian.h"
+#include "jaegertracing/propagation/Extractor.h"
+#include "jaegertracing/propagation/HeadersConfig.h"
+#include "jaegertracing/propagation/Injector.h"
+#include <cctype>
+#include <climits>
+#include <opentracing/propagation.h>
+#include <sstream>
+
+namespace jaegertracing {
+
+class Tracer;
+
+namespace propagation {
+
+template <typename ReaderType, typename WriterType>
+class Propagator : public Extractor<ReaderType>, public Injector<WriterType> {
+ public:
+ using Reader = ReaderType;
+ using Writer = WriterType;
+ using StrMap = SpanContext::StrMap;
+
+ Propagator()
+ : _headerKeys()
+ , _metrics(metrics::Metrics::makeNullMetrics())
+ {
+ }
+
+ Propagator(const HeadersConfig& headerKeys,
+ const std::shared_ptr<metrics::Metrics>& metrics)
+ : _headerKeys(headerKeys)
+ , _metrics(metrics)
+ {
+ }
+
+ virtual ~Propagator() = default;
+
+ SpanContext extract(const Reader& reader) const override
+ {
+ SpanContext ctx;
+ StrMap baggage;
+ std::string debugID;
+ const auto result = reader.ForeachKey(
+ [this, &ctx, &debugID, &baggage](const std::string& rawKey,
+ const std::string& value) {
+ const auto key = normalizeKey(rawKey);
+ if (key == _headerKeys.traceContextHeaderName()) {
+ const auto safeValue = decodeValue(value);
+ std::istringstream iss(safeValue);
+ if (!(iss >> ctx) || ctx == SpanContext()) {
+ return opentracing::make_expected_from_error<void>(
+ opentracing::span_context_corrupted_error);
+ }
+ }
+ else if (key == _headerKeys.jaegerDebugHeader()) {
+ debugID = value;
+ }
+ else if (key == _headerKeys.jaegerBaggageHeader()) {
+ for (auto&& pair : parseCommaSeparatedMap(value)) {
+ baggage[pair.first] = pair.second;
+ }
+ }
+ else {
+ const auto prefix = _headerKeys.traceBaggageHeaderPrefix();
+ if (key.size() >= prefix.size() &&
+ key.substr(0, prefix.size()) == prefix) {
+ const auto safeKey = removeBaggageKeyPrefix(key);
+ const auto safeValue = decodeValue(value);
+ baggage[safeKey] = safeValue;
+ }
+ }
+ return opentracing::make_expected();
+ });
+
+ if (!result &&
+ result.error() == opentracing::span_context_corrupted_error) {
+ _metrics->decodingErrors().inc(1);
+ return SpanContext();
+ }
+
+ if (!ctx.traceID().isValid() && debugID.empty() && baggage.empty()) {
+ return SpanContext();
+ }
+
+ int flags = ctx.flags();
+ if (!debugID.empty()) {
+ flags |= static_cast<unsigned char>(SpanContext::Flag::kDebug) |
+ static_cast<unsigned char>(SpanContext::Flag::kSampled);
+ }
+ return SpanContext(ctx.traceID(),
+ ctx.spanID(),
+ ctx.parentID(),
+ flags,
+ baggage,
+ debugID);
+ }
+
+ void inject(const SpanContext& ctx, const Writer& writer) const override
+ {
+ std::ostringstream oss;
+ oss << ctx;
+ writer.Set(_headerKeys.traceContextHeaderName(), oss.str());
+ ctx.forEachBaggageItem(
+ [this, &writer](const std::string& key, const std::string& value) {
+ const auto safeKey = addBaggageKeyPrefix(key);
+ const auto safeValue = encodeValue(value);
+ writer.Set(safeKey, safeValue);
+ return true;
+ });
+ }
+
+ protected:
+ virtual std::string encodeValue(const std::string& str) const
+ {
+ return str;
+ }
+
+ virtual std::string decodeValue(const std::string& str) const
+ {
+ return str;
+ }
+
+ virtual std::string normalizeKey(const std::string& rawKey) const
+ {
+ return rawKey;
+ }
+
+ private:
+ static StrMap parseCommaSeparatedMap(const std::string& escapedValue)
+ {
+ StrMap map;
+ std::istringstream iss(net::URI::queryUnescape(escapedValue));
+ std::string piece;
+ while (std::getline(iss, piece, ',')) {
+ const auto eqPos = piece.find('=');
+ if (eqPos != std::string::npos) {
+ const auto key = piece.substr(0, eqPos);
+ const auto value = piece.substr(eqPos + 1);
+ map[key] = value;
+ }
+ }
+ return map;
+ }
+
+ std::string addBaggageKeyPrefix(const std::string& key) const
+ {
+ return _headerKeys.traceBaggageHeaderPrefix() + key;
+ }
+
+ std::string removeBaggageKeyPrefix(const std::string& key) const
+ {
+ return key.substr(_headerKeys.traceBaggageHeaderPrefix().size());
+ }
+
+ HeadersConfig _headerKeys;
+ std::shared_ptr<metrics::Metrics> _metrics;
+};
+
+using TextMapPropagator = Propagator<const opentracing::TextMapReader&,
+ const opentracing::TextMapWriter&>;
+
+class HTTPHeaderPropagator
+ : public Propagator<const opentracing::HTTPHeadersReader&,
+ const opentracing::HTTPHeadersWriter&> {
+ public:
+ using Propagator<Reader, Writer>::Propagator;
+
+ protected:
+ std::string encodeValue(const std::string& str) const override
+ {
+ return net::URI::queryEscape(str);
+ }
+
+ std::string decodeValue(const std::string& str) const override
+ {
+ return net::URI::queryUnescape(str);
+ }
+
+ std::string normalizeKey(const std::string& rawKey) const override
+ {
+ std::string key;
+ key.reserve(rawKey.size());
+ std::transform(std::begin(rawKey),
+ std::end(rawKey),
+ std::back_inserter(key),
+ [](char ch) { return std::tolower(ch); });
+ return key;
+ }
+};
+
+class BinaryPropagator : public Extractor<std::istream&>,
+ public Injector<std::ostream&> {
+ public:
+ using StrMap = SpanContext::StrMap;
+
+ explicit BinaryPropagator(const std::shared_ptr<metrics::Metrics>& metrics =
+ std::shared_ptr<metrics::Metrics>())
+ : _metrics(metrics == nullptr ? metrics::Metrics::makeNullMetrics()
+ : metrics)
+ {
+ }
+
+ void inject(const SpanContext& ctx, std::ostream& out) const override
+ {
+ writeBinary(out, ctx.traceID().high());
+ writeBinary(out, ctx.traceID().low());
+ writeBinary(out, ctx.spanID());
+ writeBinary(out, ctx.parentID());
+ // `flags` is a single byte, so endianness is not an issue.
+ out.put(ctx.flags());
+
+ writeBinary(out, static_cast<uint32_t>(ctx.baggage().size()));
+ for (auto&& pair : ctx.baggage()) {
+ auto&& key = pair.first;
+ writeBinary(out, static_cast<uint32_t>(key.size()));
+ out.write(key.c_str(), key.size());
+
+ auto&& value = pair.second;
+ writeBinary(out, static_cast<uint32_t>(value.size()));
+ out.write(value.c_str(), value.size());
+ }
+ }
+
+ SpanContext extract(std::istream& in) const override
+ {
+ const auto traceIDHigh = readBinary<uint64_t>(in);
+ const auto traceIDLow = readBinary<uint64_t>(in);
+ TraceID traceID(traceIDHigh, traceIDLow);
+ const auto spanID = readBinary<uint64_t>(in);
+ const auto parentID = readBinary<uint64_t>(in);
+
+ auto ch = '\0';
+ in.get(ch);
+ const auto flags = static_cast<unsigned char>(ch);
+
+ const auto numBaggageItems = readBinary<uint32_t>(in);
+ StrMap baggage;
+ baggage.reserve(numBaggageItems);
+ for (auto i = static_cast<uint32_t>(0); i < numBaggageItems; ++i) {
+ const auto keyLength = readBinary<uint32_t>(in);
+ std::string key(keyLength, '\0');
+ if (!in.read(&key[0], keyLength)) {
+ _metrics->decodingErrors().inc(1);
+ return SpanContext();
+ }
+
+ const auto valueLength = readBinary<uint32_t>(in);
+ std::string value(valueLength, '\0');
+ if (!in.read(&value[0], valueLength)) {
+ _metrics->decodingErrors().inc(1);
+ return SpanContext();
+ }
+
+ baggage[key] = value;
+ }
+
+ SpanContext ctx(traceID, spanID, parentID, flags, baggage);
+ return ctx;
+ }
+
+ private:
+ template <typename ValueType>
+ static
+ typename std::enable_if<std::is_integral<ValueType>::value, void>::type
+ writeBinary(std::ostream& out, ValueType value)
+ {
+ const ValueType outValue = platform::endian::toBigEndian(value);
+ for (auto i = static_cast<size_t>(0); i < sizeof(ValueType); ++i) {
+ const auto numShiftBits = (sizeof(ValueType) - i - 1) * CHAR_BIT;
+ const auto byte = outValue >> numShiftBits;
+ out.put(static_cast<unsigned char>(byte));
+ }
+ }
+
+ template <typename ValueType>
+ static typename std::enable_if<std::is_integral<ValueType>::value,
+ ValueType>::type
+ readBinary(std::istream& in)
+ {
+ auto value = static_cast<ValueType>(0);
+ auto ch = '\0';
+ for (auto i = static_cast<size_t>(0);
+ i < sizeof(ValueType) && in.get(ch);
+ ++i) {
+ const auto byte = static_cast<uint8_t>(ch);
+ value <<= CHAR_BIT;
+ value |= byte;
+ }
+ return platform::endian::fromBigEndian(value);
+ }
+
+ private:
+ std::shared_ptr<metrics::Metrics> _metrics;
+};
+
+} // namespace propagation
+} // namespace jaegertracing
+
+#endif // JAEGERTRACING_PROPAGATION_PROPAGATOR_H
diff --git a/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/propagation/PropagatorTest.cpp b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/propagation/PropagatorTest.cpp
new file mode 100644
index 000000000..05fc44c4f
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/propagation/PropagatorTest.cpp
@@ -0,0 +1,72 @@
+/*
+ * 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.
+ */
+
+#include "jaegertracing/propagation/Propagator.h"
+#include "jaegertracing/SpanContext.h"
+#include "jaegertracing/TraceID.h"
+#include <gtest/gtest.h>
+#include <iosfwd>
+#include <random>
+#include <stddef.h>
+#include <string>
+#include <unordered_map>
+
+namespace jaegertracing {
+namespace propagation {
+namespace {
+
+template <typename RandomGenerator>
+std::string randomStr(RandomGenerator& gen)
+{
+ constexpr auto kMaxSize = 10;
+ static constexpr char kLetters[] =
+ "abcdefghijklmnopqrstuvwxyz"
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+ "0123456789";
+ constexpr auto kNumLetters = sizeof(kLetters) - 1;
+ const auto size = gen() % kMaxSize;
+ std::string result(size, '\0');
+ for (auto i = static_cast<size_t>(0); i < size; ++i) {
+ const auto pos = gen() % kNumLetters;
+ result[i] = kLetters[pos];
+ }
+ return result;
+}
+
+} // anonymous namespace
+
+TEST(Propagator, testBinaryPropagation)
+{
+ std::stringstream ss;
+ BinaryPropagator binaryPropagator;
+ std::random_device randomDevice;
+ std::default_random_engine engine(randomDevice());
+ constexpr auto kMaxNumBaggageItems = 10;
+ const auto numBaggageItems = engine() % (kMaxNumBaggageItems - 1) + 1;
+ SpanContext::StrMap baggage;
+ for (auto i = static_cast<size_t>(0); i < numBaggageItems; ++i) {
+ const auto key = randomStr(engine);
+ const auto value = randomStr(engine);
+ baggage[key] = value;
+ }
+ SpanContext ctx(
+ TraceID(engine(), engine()), engine(), engine(), 0, baggage);
+ binaryPropagator.inject(ctx, ss);
+ ASSERT_EQ(ctx, binaryPropagator.extract(ss));
+}
+
+} // namespace propagation
+} // namespace jaegertracing
diff --git a/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/reporters/CompositeReporter.cpp b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/reporters/CompositeReporter.cpp
new file mode 100644
index 000000000..4b9806254
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/reporters/CompositeReporter.cpp
@@ -0,0 +1,17 @@
+/*
+ * 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.
+ */
+
+#include "jaegertracing/reporters/CompositeReporter.h"
diff --git a/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/reporters/CompositeReporter.h b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/reporters/CompositeReporter.h
new file mode 100644
index 000000000..02f2f77d9
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/reporters/CompositeReporter.h
@@ -0,0 +1,66 @@
+/*
+ * 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_REPORTERS_COMPOSITEREPORTER_H
+#define JAEGERTRACING_REPORTERS_COMPOSITEREPORTER_H
+
+#include "jaegertracing/reporters/Reporter.h"
+#include <algorithm>
+#include <iterator>
+#include <memory>
+#include <vector>
+
+namespace jaegertracing {
+class Span;
+} // namespace jaegertracing
+
+namespace jaegertracing {
+namespace reporters {
+
+class CompositeReporter : public Reporter {
+ public:
+ using ReporterPtr = std::shared_ptr<Reporter>;
+
+ explicit CompositeReporter(const std::vector<ReporterPtr>& reporters)
+ : _reporters(reporters)
+ {
+ }
+
+ ~CompositeReporter() { close(); }
+
+ void report(const Span& span) noexcept override
+ {
+ std::for_each(
+ std::begin(_reporters),
+ std::end(_reporters),
+ [&span](const ReporterPtr& reporter) { reporter->report(span); });
+ }
+
+ void close() noexcept override
+ {
+ std::for_each(std::begin(_reporters),
+ std::end(_reporters),
+ [](const ReporterPtr& reporter) { reporter->close(); });
+ }
+
+ private:
+ std::vector<ReporterPtr> _reporters;
+};
+
+} // namespace reporters
+} // namespace jaegertracing
+
+#endif // JAEGERTRACING_REPORTERS_COMPOSITEREPORTER_H
diff --git a/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/reporters/Config.cpp b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/reporters/Config.cpp
new file mode 100644
index 000000000..c099574ad
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/reporters/Config.cpp
@@ -0,0 +1,118 @@
+/*
+ * 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.
+ */
+
+#include <algorithm>
+
+#include "jaegertracing/reporters/Config.h"
+#include "jaegertracing/ThriftSender.h"
+#include "jaegertracing/reporters/CompositeReporter.h"
+#include "jaegertracing/reporters/LoggingReporter.h"
+#include "jaegertracing/reporters/RemoteReporter.h"
+#include "jaegertracing/utils/EnvVariable.h"
+
+namespace jaegertracing {
+namespace reporters {
+
+constexpr int Config::kDefaultQueueSize;
+constexpr const char* Config::kDefaultLocalAgentHostPort;
+constexpr const char* Config::kDefaultEndpoint;
+constexpr const char* Config::kJAEGER_AGENT_HOST_ENV_PROP;
+constexpr const char* Config::kJAEGER_AGENT_PORT_ENV_PROP;
+constexpr const char* Config::kJAEGER_ENDPOINT_ENV_PROP;
+
+constexpr const char* Config::kJAEGER_REPORTER_LOG_SPANS_ENV_PROP;
+constexpr const char* Config::kJAEGER_REPORTER_FLUSH_INTERVAL_ENV_PROP;
+constexpr const char* Config::kJAEGER_REPORTER_MAX_QUEUE_SIZE_ENV_PROP;
+
+std::unique_ptr<Reporter> Config::makeReporter(const std::string& serviceName,
+ logging::Logger& logger,
+ metrics::Metrics& metrics) const
+{
+ std::unique_ptr<utils::Transport> transporter =
+ _endpoint.empty()
+ ? (std::unique_ptr<utils::Transport>(new utils::UDPTransporter(
+ net::IPAddress::v4(_localAgentHostPort), 0)))
+ : (std::unique_ptr<utils::Transport>(
+ new utils::HTTPTransporter(net::URI::parse(_endpoint), 0)));
+
+ std::unique_ptr<ThriftSender> sender(new ThriftSender(
+ std::forward<std::unique_ptr<utils::Transport>>(transporter)));
+ std::unique_ptr<RemoteReporter> remoteReporter(new RemoteReporter(
+ _bufferFlushInterval, _queueSize, std::move(sender), logger, metrics));
+ if (_logSpans) {
+ logger.info("Initializing logging reporter");
+ return std::unique_ptr<CompositeReporter>(new CompositeReporter(
+ { std::shared_ptr<RemoteReporter>(std::move(remoteReporter)),
+ std::make_shared<LoggingReporter>(logger) }));
+ }
+ return std::unique_ptr<Reporter>(std::move(remoteReporter));
+}
+
+void Config::fromEnv()
+{
+ const auto agentHost =
+ utils::EnvVariable::getStringVariable(kJAEGER_AGENT_HOST_ENV_PROP);
+ if (!agentHost.empty()) {
+ auto agentHostPort = net::IPAddress::parse(_localAgentHostPort);
+ std::ostringstream oss;
+ oss << agentHost << ":" << agentHostPort.second;
+ _localAgentHostPort = oss.str();
+ }
+ const auto agentPort =
+ utils::EnvVariable::getStringVariable(kJAEGER_AGENT_PORT_ENV_PROP);
+ if (!agentPort.empty()) {
+ std::istringstream iss(agentPort);
+ int port = 0;
+ if (iss >> port) {
+ auto agentHostPort = net::IPAddress::parse(_localAgentHostPort);
+ std::ostringstream oss;
+ oss << agentHostPort.first << ":" << port;
+ _localAgentHostPort = oss.str();
+ }
+ }
+
+ const auto endpoint =
+ utils::EnvVariable::getStringVariable(kJAEGER_ENDPOINT_ENV_PROP);
+ if (!endpoint.empty()) {
+ _endpoint = endpoint;
+ }
+
+ const auto logSpan = utils::EnvVariable::getBoolVariable(
+ kJAEGER_REPORTER_LOG_SPANS_ENV_PROP);
+ if (logSpan.first) {
+ _logSpans = logSpan.second;
+ }
+
+ const auto flushInterval = utils::EnvVariable::getIntVariable(
+ kJAEGER_REPORTER_FLUSH_INTERVAL_ENV_PROP);
+ if (!flushInterval.first) {
+ if (flushInterval.second > 0) {
+ _bufferFlushInterval =
+ std::chrono::milliseconds(flushInterval.second);
+ }
+ }
+
+ const auto maxQueueSize = utils::EnvVariable::getIntVariable(
+ kJAEGER_REPORTER_MAX_QUEUE_SIZE_ENV_PROP);
+ if (!maxQueueSize.first) {
+ if (maxQueueSize.second > 0) {
+ _queueSize = maxQueueSize.second;
+ }
+ }
+}
+
+} // namespace reporters
+} // namespace jaegertracing
diff --git a/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/reporters/Config.h b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/reporters/Config.h
new file mode 100644
index 000000000..8f6904d2e
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/reporters/Config.h
@@ -0,0 +1,137 @@
+/*
+ * 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_REPORTERS_CONFIG_H
+#define JAEGERTRACING_REPORTERS_CONFIG_H
+
+#include <chrono>
+#include <memory>
+#include <string>
+#include <utility>
+
+#include "jaegertracing/Logging.h"
+#include "jaegertracing/metrics/Metrics.h"
+#include "jaegertracing/reporters/Reporter.h"
+#include "jaegertracing/utils/YAML.h"
+#include "jaegertracing/utils/HTTPTransporter.h"
+#include "jaegertracing/utils/UDPTransporter.h"
+
+namespace jaegertracing {
+namespace reporters {
+
+class Config {
+ public:
+ using Clock = std::chrono::steady_clock;
+
+ static constexpr auto kDefaultQueueSize = 100;
+ static constexpr auto kDefaultLocalAgentHostPort = "127.0.0.1:6831";
+ static constexpr auto kDefaultEndpoint = "";
+
+ static constexpr auto kJAEGER_AGENT_HOST_ENV_PROP = "JAEGER_AGENT_HOST";
+ static constexpr auto kJAEGER_AGENT_PORT_ENV_PROP = "JAEGER_AGENT_PORT";
+ static constexpr auto kJAEGER_ENDPOINT_ENV_PROP = "JAEGER_ENDPOINT";
+
+ static constexpr auto kJAEGER_REPORTER_LOG_SPANS_ENV_PROP = "JAEGER_REPORTER_LOG_SPANS";
+ static constexpr auto kJAEGER_REPORTER_FLUSH_INTERVAL_ENV_PROP = "JAEGER_REPORTER_FLUSH_INTERVAL";
+ static constexpr auto kJAEGER_REPORTER_MAX_QUEUE_SIZE_ENV_PROP = "JAEGER_REPORTER_MAX_QUEUE_SIZE";
+
+
+
+ static Clock::duration defaultBufferFlushInterval()
+ {
+ return std::chrono::seconds(10);
+ }
+
+#ifdef JAEGERTRACING_WITH_YAML_CPP
+
+ static Config parse(const YAML::Node& configYAML)
+ {
+ if (!configYAML.IsDefined() || !configYAML.IsMap()) {
+ return Config();
+ }
+
+ const auto queueSize =
+ utils::yaml::findOrDefault<int>(configYAML, "queueSize", 0);
+ const auto bufferFlushInterval =
+ std::chrono::seconds(utils::yaml::findOrDefault<int>(
+ configYAML, "bufferFlushInterval", 0));
+ const auto logSpans =
+ utils::yaml::findOrDefault<bool>(configYAML, "logSpans", false);
+ const auto localAgentHostPort = utils::yaml::findOrDefault<std::string>(
+ configYAML, "localAgentHostPort", "");
+ const auto endpoint = utils::yaml::findOrDefault<std::string>(
+ configYAML, "endpoint", "");
+ return Config(
+ queueSize, bufferFlushInterval, logSpans, localAgentHostPort, endpoint);
+ }
+
+#endif // JAEGERTRACING_WITH_YAML_CPP
+
+ explicit Config(
+ int queueSize = kDefaultQueueSize,
+ const Clock::duration& bufferFlushInterval =
+ defaultBufferFlushInterval(),
+ bool logSpans = false,
+ const std::string& localAgentHostPort = kDefaultLocalAgentHostPort, const std::string& endpoint = kDefaultEndpoint)
+ : _queueSize(queueSize > 0 ? queueSize : kDefaultQueueSize)
+ , _bufferFlushInterval(bufferFlushInterval.count() > 0
+ ? bufferFlushInterval
+ : defaultBufferFlushInterval())
+ , _logSpans(logSpans)
+ , _localAgentHostPort(localAgentHostPort.empty()
+ ? kDefaultLocalAgentHostPort
+ : localAgentHostPort)
+ , _endpoint(endpoint)
+ {
+ }
+
+ std::unique_ptr<Reporter> makeReporter(const std::string& serviceName,
+ logging::Logger& logger,
+ metrics::Metrics& metrics) const;
+
+ int queueSize() const { return _queueSize; }
+
+ const Clock::duration& bufferFlushInterval() const
+ {
+ return _bufferFlushInterval;
+ }
+
+ bool logSpans() const { return _logSpans; }
+
+ const std::string& localAgentHostPort() const
+ {
+ return _localAgentHostPort;
+ }
+
+ const std::string& endpoint() const
+ {
+ return _endpoint;
+ }
+
+ void fromEnv();
+
+ private:
+ int _queueSize;
+ Clock::duration _bufferFlushInterval;
+ bool _logSpans;
+ std::string _localAgentHostPort;
+ std::string _endpoint;
+};
+
+} // namespace reporters
+} // namespace jaegertracing
+
+#endif // JAEGERTRACING_REPORTERS_CONFIG_H
diff --git a/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/reporters/ConfigTest.cpp b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/reporters/ConfigTest.cpp
new file mode 100644
index 000000000..763177919
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/reporters/ConfigTest.cpp
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2019, The Jaeger Authors
+ *
+ * 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.
+ */
+
+#include <gtest/gtest.h>
+
+#include <string>
+
+#include <yaml-cpp/yaml.h>
+
+#include "jaegertracing/reporters/Config.h"
+
+namespace jaegertracing {
+namespace reporters {
+
+TEST(Config, testLoadConfig)
+{
+ std::string yamlConfig =
+ "disabled: false\n"
+ "reporter:\n"
+ " logSpans: true\n"
+ " bufferFlushInterval: 88\n"
+ " localAgentHostPort: ahost:22\n"
+ " endpoint: http://somehost:33/api/traces\n"
+ "sampler:\n"
+ " type: const\n"
+ " param: 1";
+
+ auto configYAML = YAML::Load(yamlConfig);
+ auto reporterYAML = configYAML["reporter"];
+ auto config = jaegertracing::reporters::Config::parse(reporterYAML);
+
+ ASSERT_EQ(true, config.logSpans());
+ ASSERT_EQ(std::chrono::seconds(88), config.bufferFlushInterval());
+ ASSERT_EQ(std::string("ahost:22"), config.localAgentHostPort());
+ ASSERT_EQ(std::string("http://somehost:33/api/traces"), config.endpoint());
+}
+
+} // namespace reporters
+} // namespace jaegertracing
diff --git a/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/reporters/InMemoryReporter.cpp b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/reporters/InMemoryReporter.cpp
new file mode 100644
index 000000000..dbba9cb2b
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/reporters/InMemoryReporter.cpp
@@ -0,0 +1,17 @@
+/*
+ * 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.
+ */
+
+#include "jaegertracing/reporters/InMemoryReporter.h"
diff --git a/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/reporters/InMemoryReporter.h b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/reporters/InMemoryReporter.h
new file mode 100644
index 000000000..7977ed450
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/reporters/InMemoryReporter.h
@@ -0,0 +1,73 @@
+/*
+ * 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_REPORTERS_INMEMORYREPORTER_H
+#define JAEGERTRACING_REPORTERS_INMEMORYREPORTER_H
+
+#include <mutex>
+#include <vector>
+
+#include "jaegertracing/Span.h"
+#include "jaegertracing/reporters/Reporter.h"
+
+namespace jaegertracing {
+namespace reporters {
+
+class InMemoryReporter : public Reporter {
+ public:
+ InMemoryReporter()
+ : _spans()
+ , _mutex()
+ {
+ constexpr auto kInitialCapacity = 10;
+ _spans.reserve(kInitialCapacity);
+ }
+
+ void report(const Span& span) noexcept override
+ {
+ std::lock_guard<std::mutex> lock(_mutex);
+ _spans.push_back(span);
+ }
+
+ void close() noexcept override {}
+
+ int spansSubmitted() const noexcept
+ {
+ std::lock_guard<std::mutex> lock(_mutex);
+ return _spans.size();
+ }
+
+ std::vector<Span> spans() const noexcept
+ {
+ std::lock_guard<std::mutex> lock(_mutex);
+ return _spans;
+ }
+
+ void reset() noexcept
+ {
+ std::lock_guard<std::mutex> lock(_mutex);
+ _spans.clear();
+ }
+
+ private:
+ std::vector<Span> _spans;
+ mutable std::mutex _mutex;
+};
+
+} // namespace reporters
+} // namespace jaegertracing
+
+#endif // JAEGERTRACING_REPORTERS_INMEMORYREPORTER_H
diff --git a/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/reporters/LoggingReporter.cpp b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/reporters/LoggingReporter.cpp
new file mode 100644
index 000000000..03a737454
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/reporters/LoggingReporter.cpp
@@ -0,0 +1,33 @@
+/*
+ * 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.
+ */
+
+#include "jaegertracing/reporters/LoggingReporter.h"
+#include "jaegertracing/Logging.h"
+#include "jaegertracing/Span.h"
+#include <sstream>
+
+namespace jaegertracing {
+namespace reporters {
+
+void LoggingReporter::report(const Span& span) noexcept
+{
+ std::ostringstream oss;
+ oss << "Reporting span " << span;
+ _logger.info(oss.str());
+}
+
+} // namespace reporters
+} // namespace jaegertracing
diff --git a/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/reporters/LoggingReporter.h b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/reporters/LoggingReporter.h
new file mode 100644
index 000000000..e13d56d46
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/reporters/LoggingReporter.h
@@ -0,0 +1,44 @@
+/*
+ * 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_REPORTERS_LOGGINGREPORTER_H
+#define JAEGERTRACING_REPORTERS_LOGGINGREPORTER_H
+
+#include "jaegertracing/Logging.h"
+#include "jaegertracing/reporters/Reporter.h"
+
+namespace jaegertracing {
+namespace reporters {
+
+class LoggingReporter : public Reporter {
+ public:
+ explicit LoggingReporter(logging::Logger& logger)
+ : _logger(logger)
+ {
+ }
+
+ void report(const Span& span) noexcept override;
+
+ void close() noexcept override {}
+
+ private:
+ logging::Logger& _logger;
+};
+
+} // namespace reporters
+} // namespace jaegertracing
+
+#endif // JAEGERTRACING_REPORTERS_LOGGINGREPORTER_H
diff --git a/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/reporters/NullReporter.cpp b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/reporters/NullReporter.cpp
new file mode 100644
index 000000000..2cb201b79
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/reporters/NullReporter.cpp
@@ -0,0 +1,17 @@
+/*
+ * 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.
+ */
+
+#include "jaegertracing/reporters/NullReporter.h"
diff --git a/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/reporters/NullReporter.h b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/reporters/NullReporter.h
new file mode 100644
index 000000000..87460f656
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/reporters/NullReporter.h
@@ -0,0 +1,39 @@
+/*
+ * 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_REPORTERS_NULLREPORTER_H
+#define JAEGERTRACING_REPORTERS_NULLREPORTER_H
+
+#include "jaegertracing/reporters/Reporter.h"
+
+namespace jaegertracing {
+class Span;
+} // namespace jaegertracing
+
+namespace jaegertracing {
+namespace reporters {
+
+class NullReporter : public Reporter {
+ public:
+ void report(const Span&) noexcept override {}
+
+ void close() noexcept override {}
+};
+
+} // namespace reporters
+} // namespace jaegertracing
+
+#endif // JAEGERTRACING_REPORTERS_NULLREPORTER_H
diff --git a/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/reporters/RemoteReporter.cpp b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/reporters/RemoteReporter.cpp
new file mode 100644
index 000000000..d8378df56
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/reporters/RemoteReporter.cpp
@@ -0,0 +1,143 @@
+/*
+ * 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.
+ */
+
+#include "jaegertracing/reporters/RemoteReporter.h"
+
+#include <iostream>
+#include <sstream>
+
+#include "jaegertracing/utils/ErrorUtil.h"
+
+namespace jaegertracing {
+namespace reporters {
+
+RemoteReporter::RemoteReporter(const Clock::duration& bufferFlushInterval,
+ int fixedQueueSize,
+ std::unique_ptr<Sender>&& sender,
+ logging::Logger& logger,
+ metrics::Metrics& metrics)
+ : _bufferFlushInterval(bufferFlushInterval)
+ , _fixedQueueSize(fixedQueueSize)
+ , _sender(std::move(sender))
+ , _logger(logger)
+ , _metrics(metrics)
+ , _queue()
+ , _queueLength(0)
+ , _running(true)
+ , _lastFlush(Clock::now())
+ , _cv()
+ , _mutex()
+ , _thread()
+{
+ _thread = std::thread([this]() { sweepQueue(); });
+}
+
+void RemoteReporter::report(const Span& span) noexcept
+{
+ std::unique_lock<std::mutex> lock(_mutex);
+ const auto pushed = (static_cast<int>(_queue.size()) < _fixedQueueSize);
+ if (pushed) {
+ _queue.push_back(span);
+ lock.unlock();
+ _cv.notify_one();
+ ++_queueLength;
+ }
+ else {
+ _metrics.reporterDropped().inc(1);
+ }
+}
+
+void RemoteReporter::close() noexcept
+{
+ try {
+ {
+ std::lock_guard<std::mutex> lock(_mutex);
+ if (!_running) {
+ return;
+ }
+ _running = false;
+ }
+ _cv.notify_one();
+ _thread.join();
+ flush();
+ } catch (...) {
+ utils::ErrorUtil::logError(_logger, "Failed in Reporter::close");
+ }
+}
+
+void RemoteReporter::sweepQueue() noexcept
+{
+ while (true) {
+ try {
+ std::unique_lock<std::mutex> lock(_mutex);
+ _cv.wait_until(lock, _lastFlush + _bufferFlushInterval, [this]() {
+ return !_running || !_queue.empty();
+ });
+
+ if (!_running && _queue.empty()) {
+ return;
+ }
+
+ if (!_queue.empty()) {
+ const auto span = _queue.front();
+ _queue.pop_front();
+ --_queueLength;
+ sendSpan(span);
+ }
+ else if (bufferFlushIntervalExpired()) {
+ flush();
+ }
+ } catch (...) {
+ utils::ErrorUtil::logError(_logger,
+ "Failed in Reporter::sweepQueue");
+ }
+ }
+}
+
+void RemoteReporter::sendSpan(const Span& span) noexcept
+{
+ try {
+ const auto flushed = _sender->append(span);
+ if (flushed > 0) {
+ _metrics.reporterSuccess().inc(flushed);
+ _metrics.reporterQueueLength().update(_queueLength);
+ }
+ } catch (const Sender::Exception& ex) {
+ _metrics.reporterFailure().inc(ex.numFailed());
+ std::ostringstream oss;
+ oss << "error reporting span " << span.operationName() << ": "
+ << ex.what();
+ _logger.error(oss.str());
+ }
+}
+
+void RemoteReporter::flush() noexcept
+{
+ try {
+ const auto flushed = _sender->flush();
+ if (flushed > 0) {
+ _metrics.reporterSuccess().inc(flushed);
+ }
+ } catch (const Sender::Exception& ex) {
+ _metrics.reporterFailure().inc(ex.numFailed());
+ _logger.error(ex.what());
+ }
+
+ _lastFlush = Clock::now();
+}
+
+} // namespace reporters
+} // namespace jaegertracing
diff --git a/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/reporters/RemoteReporter.h b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/reporters/RemoteReporter.h
new file mode 100644
index 000000000..e8648970f
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/reporters/RemoteReporter.h
@@ -0,0 +1,82 @@
+/*
+ * 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_REPORTERS_REMOTEREPORTER_H
+#define JAEGERTRACING_REPORTERS_REMOTEREPORTER_H
+
+#include <atomic>
+#include <condition_variable>
+#include <deque>
+#include <mutex>
+#include <thread>
+
+#include "jaegertracing/Compilers.h"
+
+#include "jaegertracing/Logging.h"
+#include "jaegertracing/Span.h"
+#include "jaegertracing/Sender.h"
+#include "jaegertracing/metrics/Metrics.h"
+#include "jaegertracing/reporters/Reporter.h"
+
+namespace jaegertracing {
+namespace reporters {
+
+class RemoteReporter : public Reporter {
+ public:
+ using Clock = std::chrono::steady_clock;
+
+ RemoteReporter(const Clock::duration& bufferFlushInterval,
+ int fixedQueueSize,
+ std::unique_ptr<Sender>&& sender,
+ logging::Logger& logger,
+ metrics::Metrics& metrics);
+
+ ~RemoteReporter() { close(); }
+
+ void report(const Span& span) noexcept override;
+
+ void close() noexcept override;
+
+ private:
+ void sweepQueue() noexcept;
+
+ void sendSpan(const Span& span) noexcept;
+
+ void flush() noexcept;
+
+ bool bufferFlushIntervalExpired() const
+ {
+ return (Clock::now() - _lastFlush) >= _bufferFlushInterval;
+ }
+
+ Clock::duration _bufferFlushInterval;
+ int _fixedQueueSize;
+ std::unique_ptr<Sender> _sender;
+ logging::Logger& _logger;
+ metrics::Metrics& _metrics;
+ std::deque<Span> _queue;
+ std::atomic<int> _queueLength;
+ bool _running;
+ Clock::time_point _lastFlush;
+ std::condition_variable _cv;
+ std::mutex _mutex;
+ std::thread _thread;
+};
+
+} // namespace reporters
+} // namespace jaegertracing
+
+#endif // JAEGERTRACING_REPORTERS_REMOTEREPORTER_H
diff --git a/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/reporters/Reporter.cpp b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/reporters/Reporter.cpp
new file mode 100644
index 000000000..81cdbe821
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/reporters/Reporter.cpp
@@ -0,0 +1,17 @@
+/*
+ * 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.
+ */
+
+#include "jaegertracing/reporters/Reporter.h"
diff --git a/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/reporters/Reporter.h b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/reporters/Reporter.h
new file mode 100644
index 000000000..cd8a64fb0
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/reporters/Reporter.h
@@ -0,0 +1,40 @@
+/*
+ * 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_REPORTERS_REPORTER_H
+#define JAEGERTRACING_REPORTERS_REPORTER_H
+
+#include "jaegertracing/Compilers.h"
+
+namespace jaegertracing {
+
+class Span;
+
+namespace reporters {
+
+class Reporter {
+ public:
+ virtual ~Reporter() = default;
+
+ virtual void report(const Span& span) noexcept = 0;
+
+ virtual void close() noexcept = 0;
+};
+
+} // namespace reporters
+} // namespace jaegertracing
+
+#endif // JAEGERTRACING_REPORTERS_REPORTER_H
diff --git a/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/reporters/ReporterTest.cpp b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/reporters/ReporterTest.cpp
new file mode 100644
index 000000000..1c5552462
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/reporters/ReporterTest.cpp
@@ -0,0 +1,135 @@
+/*
+ * 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.
+ */
+
+#include <gtest/gtest.h>
+
+#include "jaegertracing/Logging.h"
+#include "jaegertracing/Tracer.h"
+#include "jaegertracing/Sender.h"
+#include "jaegertracing/reporters/CompositeReporter.h"
+#include "jaegertracing/reporters/InMemoryReporter.h"
+#include "jaegertracing/reporters/LoggingReporter.h"
+#include "jaegertracing/reporters/NullReporter.h"
+#include "jaegertracing/reporters/RemoteReporter.h"
+#include "jaegertracing/samplers/ConstSampler.h"
+
+namespace jaegertracing {
+namespace reporters {
+namespace {
+
+class FakeTransport : public Sender {
+ public:
+ FakeTransport(std::vector<Span>& spans, std::mutex& mutex)
+ : _spans(spans)
+ , _mutex(mutex)
+ {
+ }
+
+ int append(const Span& span) override
+ {
+ std::lock_guard<std::mutex> lock(_mutex);
+ _spans.push_back(span);
+ return 1;
+ }
+
+ int flush() override { return 0; }
+
+ void close() override {}
+
+ private:
+ std::vector<Span>& _spans;
+ std::mutex& _mutex;
+};
+
+const Span span;
+
+} // anonymous namespace
+
+TEST(Reporter, testRemoteReporter)
+{
+ std::vector<Span> spans;
+ std::mutex mutex;
+ auto logger = logging::nullLogger();
+ auto metrics = metrics::Metrics::makeNullMetrics();
+ constexpr auto kFixedQueueSize = 10;
+ RemoteReporter reporter(
+ std::chrono::milliseconds(1),
+ kFixedQueueSize,
+ std::unique_ptr<Sender>(new FakeTransport(spans, mutex)),
+ *logger,
+ *metrics);
+ constexpr auto kNumReports = 100;
+ for (auto i = 0; i < kNumReports; ++i) {
+ reporter.report(span);
+ // TODO(isaachier): Find a way to make this test more rigorous.
+ std::this_thread::sleep_for(std::chrono::milliseconds(1));
+ }
+ reporter.close();
+ ASSERT_EQ(spans.size(), kNumReports);
+}
+
+TEST(Reporter, testNullReporter)
+{
+ NullReporter reporter;
+ constexpr auto kNumReports = 100;
+ for (auto i = 0; i < kNumReports; ++i) {
+ reporter.report(span);
+ }
+ reporter.close();
+}
+
+TEST(Reporter, testLoggingReporter)
+{
+ const auto logger = logging::nullLogger();
+ LoggingReporter reporter(*logger);
+ constexpr auto kNumReports = 100;
+ for (auto i = 0; i < kNumReports; ++i) {
+ reporter.report(span);
+ }
+ reporter.close();
+}
+
+TEST(Reporter, testInMemoryReporter)
+{
+ InMemoryReporter reporter;
+ constexpr auto kNumReports = 100;
+ for (auto i = 0; i < kNumReports; ++i) {
+ reporter.report(span);
+ }
+ ASSERT_EQ(kNumReports, reporter.spansSubmitted());
+ reporter.reset();
+ ASSERT_EQ(0, reporter.spansSubmitted());
+ reporter.close();
+}
+
+TEST(Reporter, testCompositeReporter)
+{
+ std::vector<std::shared_ptr<Reporter>> reporters;
+ reporters.push_back(std::make_shared<InMemoryReporter>());
+ reporters.push_back(std::make_shared<InMemoryReporter>());
+
+ CompositeReporter reporter(reporters);
+ reporter.report(span);
+ ASSERT_EQ(1,
+ std::static_pointer_cast<InMemoryReporter>(reporters[0])
+ ->spansSubmitted());
+ ASSERT_EQ(1,
+ std::static_pointer_cast<InMemoryReporter>(reporters[1])
+ ->spansSubmitted());
+}
+
+} // namespace reporters
+} // namespace jaegertracing
diff --git a/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/samplers/AdaptiveSampler.cpp b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/samplers/AdaptiveSampler.cpp
new file mode 100644
index 000000000..5468215b5
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/samplers/AdaptiveSampler.cpp
@@ -0,0 +1,106 @@
+/*
+ * 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.
+ */
+
+#include "jaegertracing/samplers/AdaptiveSampler.h"
+#include "jaegertracing/samplers/GuaranteedThroughputProbabilisticSampler.h"
+#include "jaegertracing/thrift-gen/sampling_types.h"
+#include <cassert>
+#include <iterator>
+#include <memory>
+#include <utility>
+
+namespace jaegertracing {
+class TraceID;
+} // namespace jaegertracing
+
+namespace jaegertracing {
+namespace samplers {
+namespace {
+
+AdaptiveSampler::SamplerMap samplersFromStrategies(
+ const sampling_manager::thrift::PerOperationSamplingStrategies& strategies)
+{
+ AdaptiveSampler::SamplerMap samplers;
+ for (auto&& strategy : strategies.perOperationStrategies) {
+ samplers[strategy.operation] =
+ std::make_shared<GuaranteedThroughputProbabilisticSampler>(
+ strategies.defaultLowerBoundTracesPerSecond,
+ strategy.probabilisticSampling.samplingRate);
+ }
+ return samplers;
+}
+
+} // anonymous namespace
+
+AdaptiveSampler::AdaptiveSampler(
+ const sampling_manager::thrift::PerOperationSamplingStrategies& strategies,
+ size_t maxOperations)
+ : _samplers(samplersFromStrategies(strategies))
+ , _defaultSampler(strategies.defaultSamplingProbability)
+ , _lowerBound(strategies.defaultLowerBoundTracesPerSecond)
+ , _maxOperations(maxOperations)
+ , _mutex()
+{
+}
+
+SamplingStatus AdaptiveSampler::isSampled(const TraceID& id,
+ const std::string& operation)
+{
+ std::lock_guard<std::mutex> lock(_mutex);
+ auto samplerItr = _samplers.find(operation);
+ if (samplerItr != std::end(_samplers)) {
+ return samplerItr->second->isSampled(id, operation);
+ }
+ if (_samplers.size() >= _maxOperations) {
+ return _defaultSampler.isSampled(id, operation);
+ }
+
+ auto newSampler =
+ std::make_shared<GuaranteedThroughputProbabilisticSampler>(
+ _lowerBound, _defaultSampler.samplingRate());
+ _samplers[operation] = newSampler;
+ return newSampler->isSampled(id, operation);
+}
+
+void AdaptiveSampler::close()
+{
+ std::lock_guard<std::mutex> lock(_mutex);
+ for (auto&& pair : _samplers) {
+ pair.second->close();
+ }
+}
+
+void AdaptiveSampler::update(const PerOperationSamplingStrategies& strategies)
+{
+ const auto lowerBound = strategies.defaultLowerBoundTracesPerSecond;
+ std::lock_guard<std::mutex> lock(_mutex);
+ for (auto&& strategy : strategies.perOperationStrategies) {
+ auto& sampler = _samplers[strategy.operation];
+ const auto samplingRate = strategy.probabilisticSampling.samplingRate;
+ if (sampler) {
+ sampler->update(lowerBound, samplingRate);
+ }
+ else {
+ sampler =
+ std::make_shared<GuaranteedThroughputProbabilisticSampler>(
+ lowerBound, samplingRate);
+ }
+ assert(sampler);
+ }
+}
+
+} // namespace samplers
+} // namespace jaegertracing
diff --git a/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/samplers/AdaptiveSampler.h b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/samplers/AdaptiveSampler.h
new file mode 100644
index 000000000..72154c8a6
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/samplers/AdaptiveSampler.h
@@ -0,0 +1,73 @@
+/*
+ * 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_SAMPLERS_ADAPTIVESAMPLER_H
+#define JAEGERTRACING_SAMPLERS_ADAPTIVESAMPLER_H
+
+#include <mutex>
+#include <string>
+#include <unordered_map>
+
+#include "jaegertracing/Compilers.h"
+
+#include "jaegertracing/Constants.h"
+#include "jaegertracing/samplers/GuaranteedThroughputProbabilisticSampler.h"
+#include "jaegertracing/samplers/ProbabilisticSampler.h"
+#include "jaegertracing/samplers/Sampler.h"
+
+namespace jaegertracing {
+namespace sampling_manager {
+namespace thrift {
+class PerOperationSamplingStrategies;
+}
+} // namespace sampling_manager
+
+namespace samplers {
+
+class AdaptiveSampler : public Sampler {
+ public:
+ using PerOperationSamplingStrategies =
+ sampling_manager::thrift::PerOperationSamplingStrategies;
+ using SamplerMap = std::unordered_map<
+ std::string,
+ std::shared_ptr<GuaranteedThroughputProbabilisticSampler>>;
+
+ AdaptiveSampler(const PerOperationSamplingStrategies& strategies,
+ size_t maxOperations);
+
+ ~AdaptiveSampler() { close(); }
+
+ SamplingStatus isSampled(const TraceID& id,
+ const std::string& operation) override;
+
+ void close() override;
+
+ void update(const PerOperationSamplingStrategies& strategies);
+
+ Type type() const override { return Type::kAdaptiveSampler; }
+
+ private:
+ SamplerMap _samplers;
+ ProbabilisticSampler _defaultSampler;
+ double _lowerBound;
+ size_t _maxOperations;
+ std::mutex _mutex;
+};
+
+} // namespace samplers
+} // namespace jaegertracing
+
+#endif // JAEGERTRACING_SAMPLERS_ADAPTIVESAMPLER_H
diff --git a/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/samplers/Config.cpp b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/samplers/Config.cpp
new file mode 100644
index 000000000..75f1549b9
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/samplers/Config.cpp
@@ -0,0 +1,51 @@
+/*
+ * 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.
+ */
+
+#include "jaegertracing/samplers/Config.h"
+#include "jaegertracing/utils/EnvVariable.h"
+
+namespace jaegertracing {
+namespace samplers {
+
+constexpr double Config::kDefaultSamplingProbability;
+constexpr const char* Config::kDefaultSamplingServerURL;
+
+constexpr const char* Config::kJAEGER_SAMPLER_TYPE_ENV_PROP;
+constexpr const char* Config::kJAEGER_SAMPLER_PARAM_ENV_PROP;
+
+void Config::fromEnv()
+{
+ const auto samplerType = utils::EnvVariable::getStringVariable(kJAEGER_SAMPLER_TYPE_ENV_PROP);
+ if (!samplerType.empty()) {
+ _type = samplerType;
+ }
+
+ const auto param = utils::EnvVariable::getStringVariable(kJAEGER_SAMPLER_PARAM_ENV_PROP);
+ if (!param.empty()) {
+ std::istringstream iss(param);
+ double paramVal = 0;
+ if (iss >> paramVal) {
+ _param = paramVal;
+ }
+ }
+ const auto samplingServerURL = utils::EnvVariable::getStringVariable(kJAEGER_SAMPLING_ENDPOINT_ENV_PROP);
+ if (!samplingServerURL.empty()) {
+ _samplingServerURL = samplingServerURL;
+ }
+}
+
+} // namespace samplers
+} // namespace jaegertracing
diff --git a/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/samplers/Config.h b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/samplers/Config.h
new file mode 100644
index 000000000..210feed95
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/samplers/Config.h
@@ -0,0 +1,190 @@
+/*
+ * 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_SAMPLERS_CONFIG_H
+#define JAEGERTRACING_SAMPLERS_CONFIG_H
+
+#include <cctype>
+#include <chrono>
+#include <memory>
+#include <sstream>
+#include <string>
+
+#include "jaegertracing/Constants.h"
+#include "jaegertracing/Logging.h"
+#include "jaegertracing/metrics/Metrics.h"
+#include "jaegertracing/samplers/ConstSampler.h"
+#include "jaegertracing/samplers/ProbabilisticSampler.h"
+#include "jaegertracing/samplers/RateLimitingSampler.h"
+#include "jaegertracing/samplers/RemotelyControlledSampler.h"
+#include "jaegertracing/samplers/Sampler.h"
+#include "jaegertracing/utils/YAML.h"
+
+namespace jaegertracing {
+namespace samplers {
+
+class Config {
+ public:
+ using Clock = std::chrono::steady_clock;
+
+ static constexpr auto kDefaultSamplingProbability =
+ static_cast<double>(0.001);
+ static constexpr auto kDefaultSamplingServerURL = "http://127.0.0.1:5778/sampling";
+ static constexpr auto kDefaultMaxOperations = 2000;
+
+ static constexpr auto kJAEGER_SAMPLER_TYPE_ENV_PROP = "JAEGER_SAMPLER_TYPE";
+ static constexpr auto kJAEGER_SAMPLER_PARAM_ENV_PROP = "JAEGER_SAMPLER_PARAM";
+ static constexpr auto kJAEGER_SAMPLING_ENDPOINT_ENV_PROP = "JAEGER_SAMPLING_ENDPOINT";
+
+ static Clock::duration defaultSamplingRefreshInterval()
+ {
+ return std::chrono::minutes(1);
+ }
+
+#ifdef JAEGERTRACING_WITH_YAML_CPP
+
+ static Config parse(const YAML::Node& configYAML)
+ {
+ if (!configYAML.IsDefined() || !configYAML.IsMap()) {
+ return Config();
+ }
+
+ const auto type =
+ utils::yaml::findOrDefault<std::string>(configYAML, "type", "");
+ const auto param =
+ utils::yaml::findOrDefault<double>(configYAML, "param", -1);
+ const auto samplingServerURL = utils::yaml::findOrDefault<std::string>(
+ configYAML, "samplingServerURL", "");
+ const auto maxOperations =
+ utils::yaml::findOrDefault<int>(configYAML, "maxOperations", 0);
+ const auto samplingRefreshInterval =
+ std::chrono::seconds(utils::yaml::findOrDefault<int>(
+ configYAML, "samplingRefreshInterval", 0));
+ return Config(type,
+ param,
+ samplingServerURL,
+ maxOperations,
+ samplingRefreshInterval);
+ }
+
+#endif // JAEGERTRACING_WITH_YAML_CPP
+
+ explicit Config(
+ const std::string& type = kSamplerTypeRemote,
+ double param = kDefaultSamplingProbability,
+ const std::string& samplingServerURL = kDefaultSamplingServerURL,
+ int maxOperations = kDefaultMaxOperations,
+ const Clock::duration& samplingRefreshInterval =
+ defaultSamplingRefreshInterval())
+ : _type(type.empty() ? kSamplerTypeRemote : type)
+ , _param(param == -1 ? kDefaultSamplingProbability : param)
+ , _samplingServerURL(samplingServerURL.empty()
+ ? kDefaultSamplingServerURL
+ : samplingServerURL)
+ , _maxOperations(maxOperations == 0 ? kDefaultMaxOperations
+ : maxOperations)
+ , _samplingRefreshInterval(samplingRefreshInterval.count() > 0
+ ? samplingRefreshInterval
+ : defaultSamplingRefreshInterval())
+ {
+ }
+
+ std::unique_ptr<Sampler> makeSampler(const std::string& serviceName,
+ logging::Logger& logger,
+ metrics::Metrics& metrics) const
+ {
+ std::string samplerType;
+ samplerType.reserve(_type.size());
+ std::transform(std::begin(_type),
+ std::end(_type),
+ std::back_inserter(samplerType),
+ [](const char ch) { return std::tolower(ch); });
+ if (samplerType == kSamplerTypeConst) {
+ return std::unique_ptr<ConstSampler>(new ConstSampler(_param != 0));
+ }
+
+ if (samplerType == kSamplerTypeProbabilistic) {
+ if (_param >= 0 && _param <= 1) {
+ return std::unique_ptr<ProbabilisticSampler>(
+ new ProbabilisticSampler(_param));
+ }
+ else {
+ std::ostringstream oss;
+ oss << "Invalid parameter for probabilistic sampler: " << _param
+ << ", expecting value between 0 and 1";
+ logger.error(oss.str());
+ throw std::invalid_argument("Probabilistic sampling rate should be in the interval [0, 1].");
+ return std::unique_ptr<Sampler>();
+ }
+ }
+
+ if (samplerType == kSamplerTypeRateLimiting) {
+ return std::unique_ptr<RateLimitingSampler>(
+ new RateLimitingSampler(_param));
+ }
+
+ if (samplerType == kSamplerTypeRemote || samplerType.empty()) {
+ auto config = *this;
+ config._type = kSamplerTypeProbabilistic;
+ std::shared_ptr<Sampler> initSampler(
+ config.makeSampler(serviceName, logger, metrics));
+ if (!initSampler) {
+ return std::unique_ptr<Sampler>();
+ }
+
+ return std::unique_ptr<RemotelyControlledSampler>(
+ new RemotelyControlledSampler(serviceName,
+ _samplingServerURL,
+ initSampler,
+ _maxOperations,
+ _samplingRefreshInterval,
+ logger,
+ metrics));
+ }
+
+ std::ostringstream oss;
+ oss << "Unknown sampler type " << _type;
+ logger.error(oss.str());
+ return std::unique_ptr<Sampler>();
+ }
+
+ const std::string& type() const { return _type; }
+
+ double param() const { return _param; }
+
+ const std::string& samplingServerURL() const { return _samplingServerURL; }
+
+ int maxOperations() const { return _maxOperations; }
+
+ const Clock::duration& samplingRefreshInterval() const
+ {
+ return _samplingRefreshInterval;
+ }
+
+ void fromEnv();
+
+ private:
+ std::string _type;
+ double _param;
+ std::string _samplingServerURL;
+ int _maxOperations;
+ Clock::duration _samplingRefreshInterval;
+};
+
+} // namespace samplers
+} // namespace jaegertracing
+
+#endif // JAEGERTRACING_SAMPLERS_CONFIG_H
diff --git a/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/samplers/ConstSampler.cpp b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/samplers/ConstSampler.cpp
new file mode 100644
index 000000000..a9ae6572c
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/samplers/ConstSampler.cpp
@@ -0,0 +1,17 @@
+/*
+ * 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.
+ */
+
+#include "jaegertracing/samplers/ConstSampler.h"
diff --git a/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/samplers/ConstSampler.h b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/samplers/ConstSampler.h
new file mode 100644
index 000000000..ffd80f198
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/samplers/ConstSampler.h
@@ -0,0 +1,61 @@
+/*
+ * 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_SAMPLERS_CONSTSAMPLER_H
+#define JAEGERTRACING_SAMPLERS_CONSTSAMPLER_H
+
+#include "jaegertracing/Constants.h"
+#include "jaegertracing/Tag.h"
+#include "jaegertracing/samplers/Sampler.h"
+#include "jaegertracing/samplers/SamplingStatus.h"
+#include <string>
+#include <vector>
+
+namespace jaegertracing {
+class TraceID;
+} // namespace jaegertracing
+
+namespace jaegertracing {
+namespace samplers {
+
+class ConstSampler : public Sampler {
+ public:
+ explicit ConstSampler(bool sample)
+ : _decision(sample)
+ , _tags({ { kSamplerTypeTagKey, kSamplerTypeConst },
+ { kSamplerParamTagKey, _decision } })
+ {
+ }
+
+ SamplingStatus isSampled(const TraceID& id,
+ const std::string& operation) override
+ {
+ return SamplingStatus(_decision, _tags);
+ }
+
+ void close() override {}
+
+ Type type() const override { return Type::kConstSampler; }
+
+ private:
+ bool _decision;
+ std::vector<Tag> _tags;
+};
+
+} // namespace samplers
+} // namespace jaegertracing
+
+#endif // JAEGERTRACING_SAMPLERS_CONSTSAMPLER_H
diff --git a/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/samplers/GuaranteedThroughputProbabilisticSampler.cpp b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/samplers/GuaranteedThroughputProbabilisticSampler.cpp
new file mode 100644
index 000000000..d58459dc5
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/samplers/GuaranteedThroughputProbabilisticSampler.cpp
@@ -0,0 +1,39 @@
+/*
+ * 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.
+ */
+
+#include "jaegertracing/samplers/GuaranteedThroughputProbabilisticSampler.h"
+
+namespace jaegertracing {
+namespace samplers {
+
+void GuaranteedThroughputProbabilisticSampler::update(double lowerBound,
+ double samplingRate)
+{
+ if (_samplingRate != samplingRate) {
+ _probabilisticSampler = ProbabilisticSampler(samplingRate);
+ _samplingRate = _probabilisticSampler.samplingRate();
+ _tags = { { kSamplerTypeTagKey, kSamplerTypeLowerBound },
+ { kSamplerParamTagKey, _samplingRate } };
+ }
+
+ if (_lowerBound != lowerBound) {
+ _lowerBoundSampler.reset(new RateLimitingSampler(lowerBound));
+ _lowerBound = lowerBound;
+ }
+}
+
+} // namespace samplers
+} // namespace jaegertracing
diff --git a/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/samplers/GuaranteedThroughputProbabilisticSampler.h b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/samplers/GuaranteedThroughputProbabilisticSampler.h
new file mode 100644
index 000000000..a618b307e
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/samplers/GuaranteedThroughputProbabilisticSampler.h
@@ -0,0 +1,94 @@
+/*
+ * 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_SAMPLERS_GUARANTEEDTHROUGHPUTPROBABILISTICSAMPLER_H
+#define JAEGERTRACING_SAMPLERS_GUARANTEEDTHROUGHPUTPROBABILISTICSAMPLER_H
+
+#include "jaegertracing/Compilers.h"
+#include "jaegertracing/Constants.h"
+#include "jaegertracing/Tag.h"
+#include "jaegertracing/samplers/ProbabilisticSampler.h"
+#include "jaegertracing/samplers/RateLimitingSampler.h"
+#include "jaegertracing/samplers/Sampler.h"
+#include "jaegertracing/samplers/SamplingStatus.h"
+#include <memory>
+#include <string>
+#include <vector>
+
+namespace jaegertracing {
+class TraceID;
+} // namespace jaegertracing
+
+namespace jaegertracing {
+namespace samplers {
+
+class GuaranteedThroughputProbabilisticSampler : public Sampler
+{
+ public:
+ GuaranteedThroughputProbabilisticSampler(double lowerBound,
+ double samplingRate)
+ : _probabilisticSampler(samplingRate)
+ , _samplingRate(_probabilisticSampler.samplingRate())
+ , _lowerBoundSampler(new RateLimitingSampler(lowerBound))
+ , _lowerBound(lowerBound)
+ , _tags({ { kSamplerTypeTagKey, kSamplerTypeLowerBound },
+ { kSamplerParamTagKey, _samplingRate } })
+ {
+ }
+
+ SamplingStatus isSampled(const TraceID& id,
+ const std::string& operation) override
+ {
+ const auto samplingStatus =
+ _probabilisticSampler.isSampled(id, operation);
+ if (samplingStatus.isSampled()) {
+ _lowerBoundSampler->isSampled(id, operation);
+ return samplingStatus;
+ }
+ const auto sampled =
+ _lowerBoundSampler->isSampled(id, operation).isSampled();
+ return SamplingStatus(sampled, _tags);
+ }
+
+ void close() override
+ {
+ _probabilisticSampler.close();
+ _lowerBoundSampler->close();
+ }
+
+ void update(double lowerBound, double samplingRate);
+
+ double lowerBound() const { return _lowerBound; }
+
+ double samplingRate() const { return _samplingRate; }
+
+ Type type() const override
+ {
+ return Type::kGuaranteedThroughputProbabilisticSampler;
+ }
+
+ private:
+ ProbabilisticSampler _probabilisticSampler;
+ double _samplingRate;
+ std::unique_ptr<RateLimitingSampler> _lowerBoundSampler;
+ double _lowerBound;
+ std::vector<Tag> _tags;
+};
+
+} // namespace samplers
+} // namespace jaegertracing
+
+#endif // JAEGERTRACING_SAMPLERS_GUARANTEEDTHROUGHPUTPROBABILISTICSAMPLER_H
diff --git a/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/samplers/ProbabilisticSampler.cpp b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/samplers/ProbabilisticSampler.cpp
new file mode 100644
index 000000000..c8b472b64
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/samplers/ProbabilisticSampler.cpp
@@ -0,0 +1,17 @@
+/*
+ * 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.
+ */
+
+#include "jaegertracing/samplers/ProbabilisticSampler.h"
diff --git a/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/samplers/ProbabilisticSampler.h b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/samplers/ProbabilisticSampler.h
new file mode 100644
index 000000000..ab22c8206
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/samplers/ProbabilisticSampler.h
@@ -0,0 +1,84 @@
+/*
+ * 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_SAMPLERS_PROBABILISTICSAMPLER_H
+#define JAEGERTRACING_SAMPLERS_PROBABILISTICSAMPLER_H
+
+#include "jaegertracing/Compilers.h"
+
+#include "jaegertracing/Constants.h"
+#include "jaegertracing/Tag.h"
+#include "jaegertracing/TraceID.h"
+#include "jaegertracing/samplers/Sampler.h"
+#include "jaegertracing/samplers/SamplingStatus.h"
+#include <algorithm>
+#include <cstdint>
+#include <limits>
+#include <string>
+#include <vector>
+
+namespace jaegertracing {
+namespace samplers {
+
+class ProbabilisticSampler : public Sampler {
+ public:
+ explicit ProbabilisticSampler(double samplingRate)
+ : _samplingRate(std::max(0.0, std::min(samplingRate, 1.0)))
+ , _samplingBoundary(computeSamplingBoundary(_samplingRate))
+ , _tags({ { kSamplerTypeTagKey, kSamplerTypeProbabilistic },
+ { kSamplerParamTagKey, _samplingRate } })
+ {
+ }
+
+ double samplingRate() const { return _samplingRate; }
+
+ SamplingStatus isSampled(const TraceID& id,
+ const std::string& operation) override
+ {
+ return SamplingStatus(_samplingBoundary >= id.low(), _tags);
+ }
+
+ void close() override {}
+
+ Type type() const override { return Type::kProbabilisticSampler; }
+
+ private:
+ static constexpr auto kMaxRandomNumber =
+ std::numeric_limits<uint64_t>::max();
+
+ double _samplingRate;
+ uint64_t _samplingBoundary;
+ std::vector<Tag> _tags;
+
+ static uint64_t computeSamplingBoundary(long double samplingRate)
+ {
+ const auto maxRandNumber = static_cast<long double>(kMaxRandomNumber);
+ const auto samplingBoundary = samplingRate * maxRandNumber;
+
+ // Protect against overflow in case samplingBoundary rounds
+ // higher than kMaxRandNumber.
+ if (samplingBoundary == maxRandNumber) {
+ return kMaxRandomNumber;
+ }
+
+ return static_cast<uint64_t>(samplingBoundary);
+ }
+};
+
+} // namespace samplers
+} // namespace jaegertracing
+
+#endif // JAEGERTRACING_SAMPLERS_PROBABILISTICSAMPLER_H
diff --git a/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/samplers/RateLimitingSampler.cpp b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/samplers/RateLimitingSampler.cpp
new file mode 100644
index 000000000..f1f9f2d62
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/samplers/RateLimitingSampler.cpp
@@ -0,0 +1,17 @@
+/*
+ * 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.
+ */
+
+#include "jaegertracing/samplers/RateLimitingSampler.h"
diff --git a/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/samplers/RateLimitingSampler.h b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/samplers/RateLimitingSampler.h
new file mode 100644
index 000000000..c164ae176
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/samplers/RateLimitingSampler.h
@@ -0,0 +1,67 @@
+/*
+ * 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_SAMPLERS_RATELIMITINGSAMPLER_H
+#define JAEGERTRACING_SAMPLERS_RATELIMITINGSAMPLER_H
+
+#include "jaegertracing/Compilers.h"
+
+#include "jaegertracing/Constants.h"
+#include "jaegertracing/Tag.h"
+#include "jaegertracing/samplers/Sampler.h"
+#include "jaegertracing/samplers/SamplingStatus.h"
+#include "jaegertracing/utils/RateLimiter.h"
+#include <algorithm>
+#include <string>
+#include <vector>
+
+namespace jaegertracing {
+class TraceID;
+} // namespace jaegertracing
+
+namespace jaegertracing {
+namespace samplers {
+
+class RateLimitingSampler : public Sampler {
+ public:
+ explicit RateLimitingSampler(double maxTracesPerSecond)
+ : _maxTracesPerSecond(maxTracesPerSecond)
+ , _rateLimiter(_maxTracesPerSecond, std::max(_maxTracesPerSecond, 1.0))
+ , _tags({ { kSamplerTypeTagKey, kSamplerTypeRateLimiting },
+ { kSamplerParamTagKey, maxTracesPerSecond } })
+ {
+ }
+
+ SamplingStatus isSampled(const TraceID& id,
+ const std::string& operation) override
+ {
+ return SamplingStatus(_rateLimiter.checkCredit(1), _tags);
+ }
+
+ void close() override {}
+
+ Type type() const override { return Type::kRateLimitingSampler; }
+
+ private:
+ double _maxTracesPerSecond;
+ utils::RateLimiter<> _rateLimiter;
+ std::vector<Tag> _tags;
+};
+
+} // namespace samplers
+} // namespace jaegertracing
+
+#endif // JAEGERTRACING_SAMPLERS_RATELIMITINGSAMPLER_H
diff --git a/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/samplers/RemoteSamplingJSON.cpp b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/samplers/RemoteSamplingJSON.cpp
new file mode 100644
index 000000000..8925ed6ae
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/samplers/RemoteSamplingJSON.cpp
@@ -0,0 +1,17 @@
+/*
+ * 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.
+ */
+
+#include "jaegertracing/samplers/RemoteSamplingJSON.h" \ No newline at end of file
diff --git a/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/samplers/RemoteSamplingJSON.h b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/samplers/RemoteSamplingJSON.h
new file mode 100644
index 000000000..2f5872310
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/samplers/RemoteSamplingJSON.h
@@ -0,0 +1,175 @@
+/*
+ * 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_SAMPLERS_REMOTESAMPLINGJSON_H
+#define JAEGERTRACING_SAMPLERS_REMOTESAMPLINGJSON_H
+
+#include "jaegertracing/Compilers.h"
+
+#include "jaegertracing/thrift-gen/sampling_types.h"
+#include <cstdint>
+#include <iterator>
+#include <map>
+#include <nlohmann/json.hpp>
+#include <sstream>
+#include <stdexcept>
+#include <string>
+#include <vector>
+
+namespace jaegertracing {
+namespace sampling_manager {
+namespace thrift {
+
+const std::map<int, const char*>& samplingStrategyType_VALUES_TO_NAMES();
+
+#define JSON_FROM_FIELD(var, field) \
+ { \
+ json[#field] = var.field; \
+ }
+
+#define FIELD_FROM_JSON(var, field) \
+ { \
+ var.__set_##field(json.at(#field)); \
+ }
+
+inline void to_json(nlohmann::json& json,
+ const SamplingStrategyType::type& type)
+{
+ json = samplingStrategyType_VALUES_TO_NAMES().at(static_cast<int>(type));
+}
+
+inline void from_json(const nlohmann::json& json,
+ SamplingStrategyType::type& type)
+{
+ const auto str = json.get<std::string>();
+ if (str == "PROBABILISTIC") {
+ type = SamplingStrategyType::PROBABILISTIC;
+ return;
+ }
+ if (str == "RATE_LIMITING") {
+ type = SamplingStrategyType::RATE_LIMITING;
+ return;
+ }
+ std::ostringstream oss;
+ oss << "Invalid sampling strategy type " << str;
+ throw std::invalid_argument(oss.str());
+}
+
+inline void to_json(nlohmann::json& json,
+ const ProbabilisticSamplingStrategy& strategy)
+{
+ JSON_FROM_FIELD(strategy, samplingRate);
+}
+
+inline void from_json(const nlohmann::json& json,
+ ProbabilisticSamplingStrategy& strategy)
+{
+ FIELD_FROM_JSON(strategy, samplingRate);
+}
+
+inline void to_json(nlohmann::json& json,
+ const RateLimitingSamplingStrategy& strategy)
+{
+ JSON_FROM_FIELD(strategy, maxTracesPerSecond);
+}
+
+inline void from_json(const nlohmann::json& json,
+ RateLimitingSamplingStrategy& strategy)
+{
+ FIELD_FROM_JSON(strategy, maxTracesPerSecond);
+}
+
+inline void to_json(nlohmann::json& json,
+ const OperationSamplingStrategy& strategy)
+{
+ JSON_FROM_FIELD(strategy, operation);
+ JSON_FROM_FIELD(strategy, probabilisticSampling);
+}
+
+inline void from_json(const nlohmann::json& json,
+ OperationSamplingStrategy& strategy)
+{
+ FIELD_FROM_JSON(strategy, operation);
+ FIELD_FROM_JSON(strategy, probabilisticSampling);
+}
+
+inline void to_json(nlohmann::json& json,
+ const PerOperationSamplingStrategies& strategies)
+{
+ JSON_FROM_FIELD(strategies, defaultSamplingProbability);
+ JSON_FROM_FIELD(strategies, defaultLowerBoundTracesPerSecond);
+ JSON_FROM_FIELD(strategies, perOperationStrategies);
+ if (strategies.__isset.defaultUpperBoundTracesPerSecond) {
+ JSON_FROM_FIELD(strategies, defaultUpperBoundTracesPerSecond);
+ }
+}
+
+inline void from_json(const nlohmann::json& json,
+ PerOperationSamplingStrategies& strategies)
+{
+ FIELD_FROM_JSON(strategies, defaultSamplingProbability);
+ FIELD_FROM_JSON(strategies, defaultLowerBoundTracesPerSecond);
+ FIELD_FROM_JSON(strategies, perOperationStrategies);
+ auto itr = json.find("defaultUpperBoundTracesPerSecond");
+ if (itr != std::end(json)) {
+ strategies.__set_defaultUpperBoundTracesPerSecond(itr->get<double>());
+ }
+}
+
+inline void to_json(nlohmann::json& json,
+ const SamplingStrategyResponse& response)
+{
+ JSON_FROM_FIELD(response, strategyType);
+ if (response.__isset.probabilisticSampling) {
+ JSON_FROM_FIELD(response, probabilisticSampling);
+ }
+ if (response.__isset.rateLimitingSampling) {
+ JSON_FROM_FIELD(response, rateLimitingSampling);
+ }
+ if (response.__isset.operationSampling) {
+ JSON_FROM_FIELD(response, operationSampling);
+ }
+}
+
+inline void from_json(const nlohmann::json& json,
+ SamplingStrategyResponse& response)
+{
+ FIELD_FROM_JSON(response, strategyType);
+ auto itr = json.find("probabilisticSampling");
+ if (itr != std::end(json)) {
+ response.__set_probabilisticSampling(
+ itr->get<ProbabilisticSamplingStrategy>());
+ }
+ itr = json.find("rateLimitingSampling");
+ if (itr != std::end(json)) {
+ response.__set_rateLimitingSampling(
+ itr->get<RateLimitingSamplingStrategy>());
+ }
+ itr = json.find("operationSampling");
+ if (itr != std::end(json)) {
+ response.__set_operationSampling(
+ itr->get<PerOperationSamplingStrategies>());
+ }
+}
+
+#undef FIELD_FROM_JSON
+#undef JSON_FROM_FIELD
+
+} // namespace thrift
+} // namespace sampling_manager
+} // namespace jaegertracing
+
+#endif // JAEGERTRACING_SAMPLERS_REMOTESAMPLINGJSON_H
diff --git a/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/samplers/RemotelyControlledSampler.cpp b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/samplers/RemotelyControlledSampler.cpp
new file mode 100644
index 000000000..544ff9046
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/samplers/RemotelyControlledSampler.cpp
@@ -0,0 +1,213 @@
+/*
+ * 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.
+ */
+
+#include "jaegertracing/samplers/RemotelyControlledSampler.h"
+
+#include <cassert>
+#include <sstream>
+
+#include "jaegertracing/metrics/Counter.h"
+#include "jaegertracing/metrics/Gauge.h"
+#include "jaegertracing/net/IPAddress.h"
+#include "jaegertracing/net/Socket.h"
+#include "jaegertracing/net/URI.h"
+#include "jaegertracing/net/http/Response.h"
+#include "jaegertracing/samplers/AdaptiveSampler.h"
+#include "jaegertracing/samplers/RemoteSamplingJSON.h"
+#include "jaegertracing/thrift-gen/SamplingManager.h"
+#include "jaegertracing/utils/ErrorUtil.h"
+
+namespace jaegertracing {
+namespace samplers {
+namespace {
+
+class HTTPSamplingManager : public sampling_manager::thrift::SamplingManagerIf {
+ public:
+ using SamplingStrategyResponse =
+ sampling_manager::thrift::SamplingStrategyResponse;
+
+ HTTPSamplingManager(const std::string& serverURL, logging::Logger& logger)
+ : _serverURI(net::URI::parse(serverURL))
+ , _logger(logger)
+ {
+ try {
+ net::Socket socket;
+ socket.open(AF_INET, SOCK_STREAM);
+ _serverAddr = socket.connect(serverURL);
+ } catch (...) {
+ utils::ErrorUtil::logError(_logger, "cannot connect to socket");
+ }
+ }
+
+ void getSamplingStrategy(SamplingStrategyResponse& result,
+ const std::string& serviceName) override
+ {
+ if (_serverAddr == net::IPAddress()) {
+ return;
+ }
+ auto uri = _serverURI;
+ uri._query = "service=" + net::URI::queryEscape(serviceName);
+ const auto responseHTTP = net::http::get(uri);
+ if (responseHTTP.statusCode() != 200) {
+ std::ostringstream oss;
+ oss << "Received HTTP error response"
+ ", uri="
+ << uri << ", statusCode=" << responseHTTP.statusCode()
+ << ", reason=" << responseHTTP.reason();
+ _logger.error(oss.str());
+ return;
+ }
+
+ result = nlohmann::json::parse(responseHTTP.body());
+ }
+
+ private:
+ net::URI _serverURI;
+ net::IPAddress _serverAddr;
+ logging::Logger& _logger;
+};
+
+} // anonymous namespace
+
+RemotelyControlledSampler::RemotelyControlledSampler(
+ const std::string& serviceName,
+ const std::string& samplingServerURL,
+ const std::shared_ptr<Sampler>& sampler,
+ int maxOperations,
+ const Clock::duration& samplingRefreshInterval,
+ logging::Logger& logger,
+ metrics::Metrics& metrics)
+ : _serviceName(serviceName)
+ , _samplingServerURL(samplingServerURL)
+ , _sampler(sampler)
+ , _maxOperations(maxOperations)
+ , _samplingRefreshInterval(samplingRefreshInterval)
+ , _logger(logger)
+ , _metrics(metrics)
+ , _manager(
+ std::make_shared<HTTPSamplingManager>(_samplingServerURL, _logger))
+ , _running(true)
+ , _mutex()
+ , _shutdownCV()
+ , _thread([this]() { pollController(); })
+{
+ assert(_sampler);
+}
+
+SamplingStatus
+RemotelyControlledSampler::isSampled(const TraceID& id,
+ const std::string& operation)
+{
+ std::lock_guard<std::mutex> lock(_mutex);
+ assert(_sampler);
+ return _sampler->isSampled(id, operation);
+}
+
+void RemotelyControlledSampler::close()
+{
+ {
+ std::unique_lock<std::mutex> lock(_mutex);
+ if (!_running) {
+ return;
+ }
+ _running = false;
+ lock.unlock();
+ _shutdownCV.notify_one();
+ }
+ _thread.join();
+}
+
+void RemotelyControlledSampler::pollController()
+{
+ while (_running) {
+ updateSampler();
+ std::unique_lock<std::mutex> lock(_mutex);
+ _shutdownCV.wait_for(
+ lock, _samplingRefreshInterval, [this]() { return !_running; });
+ }
+}
+
+void RemotelyControlledSampler::updateSampler()
+{
+ assert(_manager);
+ sampling_manager::thrift::SamplingStrategyResponse response;
+ try {
+ assert(_manager);
+ _manager->getSamplingStrategy(response, _serviceName);
+ } catch (const std::exception& ex) {
+ _metrics.samplerQueryFailure().inc(1);
+ return;
+ } catch (...) {
+ _metrics.samplerQueryFailure().inc(1);
+ return;
+ }
+
+ std::lock_guard<std::mutex> lock(_mutex);
+ _metrics.samplerRetrieved().inc(1);
+
+ if (response.__isset.operationSampling) {
+ updateAdaptiveSampler(response.operationSampling);
+ }
+ else {
+ try {
+ updateRateLimitingOrProbabilisticSampler(response);
+ } catch (const std::exception& ex) {
+ _metrics.samplerUpdateFailure().inc(1);
+ return;
+ } catch (...) {
+ _metrics.samplerUpdateFailure().inc(1);
+ return;
+ }
+ }
+ _metrics.samplerUpdated().inc(1);
+}
+
+void RemotelyControlledSampler::updateAdaptiveSampler(
+ const PerOperationSamplingStrategies& strategies)
+{
+ auto sampler = _sampler;
+ assert(sampler);
+ if (sampler->type() == Type::kAdaptiveSampler) {
+ static_cast<AdaptiveSampler&>(*sampler).update(strategies);
+ }
+ else {
+ _sampler =
+ std::make_shared<AdaptiveSampler>(strategies, _maxOperations);
+ }
+}
+
+void RemotelyControlledSampler::updateRateLimitingOrProbabilisticSampler(
+ const SamplingStrategyResponse& response)
+{
+ std::shared_ptr<Sampler> sampler;
+ if (response.__isset.probabilisticSampling) {
+ sampler = std::make_shared<ProbabilisticSampler>(
+ response.probabilisticSampling.samplingRate);
+ }
+ else if (response.__isset.rateLimitingSampling) {
+ sampler = std::make_shared<RateLimitingSampler>(
+ response.rateLimitingSampling.maxTracesPerSecond);
+ }
+ else {
+ std::ostringstream oss;
+ oss << "Unsupported sampling strategy type " << response.strategyType;
+ throw std::runtime_error(oss.str());
+ }
+ _sampler = sampler;
+}
+
+} // namespace samplers
+} // namespace jaegertracing
diff --git a/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/samplers/RemotelyControlledSampler.h b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/samplers/RemotelyControlledSampler.h
new file mode 100644
index 000000000..8f1d50bd8
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/samplers/RemotelyControlledSampler.h
@@ -0,0 +1,99 @@
+/*
+ * 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_SAMPLERS_REMOTELYCONTROLLEDSAMPLER_H
+#define JAEGERTRACING_SAMPLERS_REMOTELYCONTROLLEDSAMPLER_H
+
+#include <chrono>
+#include <condition_variable>
+#include <mutex>
+#include <thread>
+
+#include "jaegertracing/Compilers.h"
+
+#include "jaegertracing/Constants.h"
+#include "jaegertracing/Logging.h"
+#include "jaegertracing/metrics/Metrics.h"
+#include "jaegertracing/samplers/ProbabilisticSampler.h"
+#include "jaegertracing/samplers/Sampler.h"
+
+namespace jaegertracing {
+
+namespace sampling_manager {
+namespace thrift {
+class PerOperationSamplingStrategies;
+class SamplingStrategyResponse;
+class SamplingManagerIf;
+} // namespace thrift
+} // namespace sampling_manager
+
+namespace samplers {
+
+class RemotelyControlledSampler : public Sampler {
+ public:
+ using Clock = std::chrono::steady_clock;
+
+ RemotelyControlledSampler(const std::string& serviceName,
+ const std::string& samplingServerURL,
+ const std::shared_ptr<Sampler>& sampler,
+ int maxOperations,
+ const Clock::duration& samplingRefreshInterval,
+ logging::Logger& logger,
+ metrics::Metrics& metrics);
+
+ ~RemotelyControlledSampler() { close(); }
+
+ SamplingStatus isSampled(const TraceID& id,
+ const std::string& operation) override;
+
+ void close() override;
+
+ Type type() const override { return Type::kRemotelyControlledSampler; }
+
+ private:
+ using PerOperationSamplingStrategies =
+ sampling_manager::thrift::PerOperationSamplingStrategies;
+ using SamplingStrategyResponse =
+ sampling_manager::thrift::SamplingStrategyResponse;
+
+ void pollController();
+
+ void updateSampler();
+
+ void
+ updateAdaptiveSampler(const PerOperationSamplingStrategies& strategies);
+
+ void updateRateLimitingOrProbabilisticSampler(
+ const SamplingStrategyResponse& response);
+
+ std::string _serviceName;
+ std::string _samplingServerURL;
+ std::shared_ptr<Sampler> _sampler;
+ int _maxOperations;
+ Clock::duration _samplingRefreshInterval;
+ logging::Logger& _logger;
+ metrics::Metrics& _metrics;
+ std::shared_ptr<sampling_manager::thrift::SamplingManagerIf> _manager;
+ bool _running;
+ std::mutex _mutex;
+ std::condition_variable _shutdownCV;
+ std::thread _thread;
+};
+
+} // namespace samplers
+} // namespace jaegertracing
+
+#endif // JAEGERTRACING_SAMPLERS_REMOTELYCONTROLLEDSAMPLER_H
diff --git a/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/samplers/Sampler.cpp b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/samplers/Sampler.cpp
new file mode 100644
index 000000000..9ce93618d
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/samplers/Sampler.cpp
@@ -0,0 +1,17 @@
+/*
+ * 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.
+ */
+
+#include "jaegertracing/samplers/Sampler.h"
diff --git a/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/samplers/Sampler.h b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/samplers/Sampler.h
new file mode 100644
index 000000000..61375c8c2
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/samplers/Sampler.h
@@ -0,0 +1,52 @@
+/*
+ * 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_SAMPLERS_SAMPLER_H
+#define JAEGERTRACING_SAMPLERS_SAMPLER_H
+
+#include "jaegertracing/Compilers.h"
+
+#include "jaegertracing/TraceID.h"
+#include "jaegertracing/samplers/SamplingStatus.h"
+
+namespace jaegertracing {
+namespace samplers {
+
+class Sampler {
+ public:
+ enum class Type {
+ kAdaptiveSampler,
+ kConstSampler,
+ kGuaranteedThroughputProbabilisticSampler,
+ kProbabilisticSampler,
+ kRateLimitingSampler,
+ kRemotelyControlledSampler
+ };
+
+ virtual ~Sampler() = default;
+
+ virtual SamplingStatus isSampled(const TraceID& id,
+ const std::string& operation) = 0;
+
+ virtual void close() = 0;
+
+ virtual Type type() const = 0;
+};
+
+} // namespace samplers
+} // namespace jaegertracing
+
+#endif // JAEGERTRACING_SAMPLERS_SAMPLER_H
diff --git a/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/samplers/SamplerTest.cpp b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/samplers/SamplerTest.cpp
new file mode 100644
index 000000000..3c082d322
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/samplers/SamplerTest.cpp
@@ -0,0 +1,372 @@
+/*
+ * 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.
+ */
+
+#include <random>
+
+#include <gtest/gtest.h>
+
+#include "jaegertracing/Constants.h"
+#include "jaegertracing/Tag.h"
+#include "jaegertracing/samplers/AdaptiveSampler.h"
+#include "jaegertracing/samplers/Config.h"
+#include "jaegertracing/samplers/ConstSampler.h"
+#include "jaegertracing/samplers/GuaranteedThroughputProbabilisticSampler.h"
+#include "jaegertracing/samplers/ProbabilisticSampler.h"
+#include "jaegertracing/samplers/RateLimitingSampler.h"
+#include "jaegertracing/samplers/RemotelyControlledSampler.h"
+#include "jaegertracing/samplers/Sampler.h"
+#include "jaegertracing/samplers/SamplingStatus.h"
+#include "jaegertracing/testutils/MockAgent.h"
+#include "jaegertracing/testutils/TUDPTransport.h"
+#include "jaegertracing/thrift-gen/jaeger_types.h"
+
+namespace jaegertracing {
+namespace samplers {
+namespace {
+
+constexpr auto kTestOperationName = "op";
+constexpr auto kTestFirstTimeOperationName = "firstTimeOp";
+constexpr auto kTestDefaultSamplingProbability = 0.5;
+constexpr auto kTestMaxID = std::numeric_limits<uint64_t>::max() / 2 + 1;
+constexpr auto kTestDefaultMaxOperations = 10;
+
+const Tag testProbablisticExpectedTags[] = {
+ { "sampler.type", "probabilistic" }, { "sampler.param", 0.5 }
+};
+
+const Tag testLowerBoundExpectedTags[] = { { "sampler.type", "lowerbound" },
+ { "sampler.param", 0.5 } };
+
+#define CMP_TAGS(tagArr, tagVec) \
+ { \
+ ASSERT_EQ(sizeof(tagArr) / sizeof(Tag), (tagVec).size()); \
+ for (auto i = static_cast<size_t>(0); i < (tagVec).size(); ++i) { \
+ jaegertracing::thrift::Tag thriftTagArr; \
+ jaegertracing::thrift::Tag thriftTagVec; \
+ (tagArr)[i].thrift(thriftTagArr); \
+ (tagVec)[i].thrift(thriftTagVec); \
+ ASSERT_EQ(thriftTagArr, thriftTagVec); \
+ } \
+ }
+
+} // anonymous namespace
+
+TEST(Sampler, testSamplerTags)
+{
+ ConstSampler constTrue(true);
+ ConstSampler constFalse(false);
+ ProbabilisticSampler prob(0.1);
+ RateLimitingSampler rate(0.1);
+
+ const struct {
+ Sampler& _sampler;
+ std::string _samplerType;
+ Tag::ValueType _samplerParam;
+ } tests[] = { { constTrue, "const", true },
+ { constFalse, "const", false },
+ { prob, "probabilistic", 0.1 },
+ { rate, "ratelimiting", 0.1 } };
+
+ for (auto&& test : tests) {
+ const auto tags =
+ test._sampler.isSampled(TraceID(), kTestOperationName).tags();
+ auto count = 0;
+ for (auto&& tag : tags) {
+ if (tag.key() == kSamplerTypeTagKey) {
+ ASSERT_TRUE(tag.value().is<const char*>());
+ ASSERT_EQ(test._samplerType, tag.value().get<const char*>());
+ ++count;
+ }
+ else if (tag.key() == kSamplerParamTagKey) {
+ ASSERT_EQ(test._samplerParam, tag.value());
+ ++count;
+ }
+ }
+ ASSERT_EQ(2, count);
+ }
+}
+
+TEST(Sampler, testProbabilisticSamplerErrors)
+{
+ ProbabilisticSampler sampler(-0.1);
+ ASSERT_LE(0, sampler.samplingRate());
+ ASSERT_GE(1, sampler.samplingRate());
+ sampler = ProbabilisticSampler(1.1);
+ ASSERT_LE(0, sampler.samplingRate());
+ ASSERT_GE(1, sampler.samplingRate());
+}
+
+TEST(Sampler, testProbabilisticSampler)
+{
+ {
+ ProbabilisticSampler sampler(0.5);
+ auto result =
+ sampler.isSampled(TraceID(0, kTestMaxID + 10), kTestOperationName);
+ ASSERT_FALSE(result.isSampled());
+ CMP_TAGS(testProbablisticExpectedTags, result.tags());
+
+ result =
+ sampler.isSampled(TraceID(0, kTestMaxID - 20), kTestOperationName);
+ ASSERT_TRUE(result.isSampled());
+ CMP_TAGS(testProbablisticExpectedTags, result.tags());
+ }
+ {
+ ProbabilisticSampler sampler(1.0);
+ auto result =
+ sampler.isSampled(TraceID(0, kTestMaxID), kTestOperationName);
+ ASSERT_TRUE(result.isSampled());
+
+ result =
+ sampler.isSampled(TraceID(0, kTestMaxID - 20), kTestOperationName);
+ ASSERT_TRUE(result.isSampled());
+ }
+}
+
+TEST(Sampler, testProbabilisticSamplerPerformance)
+{
+ constexpr auto kNumSamples = static_cast<uint64_t>(10000);
+
+ ProbabilisticSampler sampler(0.001);
+ std::random_device randomDevice;
+ std::default_random_engine randomGenerator(randomDevice());
+ std::uniform_int_distribution<uint64_t> distribution;
+ auto count = static_cast<uint64_t>(0);
+ for (auto i = static_cast<uint64_t>(0); i < kNumSamples; ++i) {
+ TraceID id(0, distribution(randomGenerator));
+ if (sampler.isSampled(id, kTestOperationName).isSampled()) {
+ ++count;
+ }
+ }
+ const auto rate = static_cast<double>(count) / kNumSamples;
+ std::cout << "Sampled: " << count << " rate=" << rate << '\n';
+}
+
+TEST(Sampler, testProbabilisticSamplerInvalidRate)
+{
+ Config samplerConfig1(kSamplerTypeProbabilistic,
+ 1.1,
+ "",
+ 0,
+ samplers::Config::Clock::duration());
+ Config samplerConfig2(kSamplerTypeProbabilistic,
+ -0.1,
+ "",
+ 0,
+ samplers::Config::Clock::duration());
+ auto logger = logging::nullLogger();
+ auto metrics = metrics::Metrics::makeNullMetrics();
+ ASSERT_THROW(samplerConfig1.makeSampler("test-service", *logger, *metrics),
+ std::invalid_argument);
+ ASSERT_THROW(samplerConfig2.makeSampler("test-service", *logger, *metrics),
+ std::invalid_argument);
+}
+
+TEST(Sampler, testRateLimitingSampler)
+{
+ {
+ RateLimitingSampler sampler(2);
+ auto result = sampler.isSampled(TraceID(), kTestOperationName);
+ ASSERT_TRUE(result.isSampled());
+ result = sampler.isSampled(TraceID(), kTestOperationName);
+ ASSERT_TRUE(result.isSampled());
+ result = sampler.isSampled(TraceID(), kTestOperationName);
+ ASSERT_FALSE(result.isSampled());
+ }
+
+ {
+ RateLimitingSampler sampler(0.1);
+ auto result = sampler.isSampled(TraceID(), kTestOperationName);
+ ASSERT_TRUE(result.isSampled());
+ result = sampler.isSampled(TraceID(), kTestOperationName);
+ ASSERT_FALSE(result.isSampled());
+ }
+}
+
+TEST(Sampler, testGuaranteedThroughputProbabilisticSamplerUpdate)
+{
+ auto lowerBound = 2.0;
+ auto samplingRate = 0.5;
+ GuaranteedThroughputProbabilisticSampler sampler(lowerBound, samplingRate);
+ ASSERT_EQ(lowerBound, sampler.lowerBound());
+ ASSERT_EQ(samplingRate, sampler.samplingRate());
+
+ auto newLowerBound = 1.0;
+ auto newSamplingRate = 0.6;
+ sampler.update(newLowerBound, newSamplingRate);
+ ASSERT_EQ(newLowerBound, sampler.lowerBound());
+ ASSERT_EQ(newSamplingRate, sampler.samplingRate());
+
+ newSamplingRate = 1.1;
+ sampler.update(newLowerBound, newSamplingRate);
+ ASSERT_EQ(1.0, sampler.samplingRate());
+}
+
+TEST(Sampler, testAdaptiveSampler)
+{
+ namespace thriftgen = sampling_manager::thrift;
+
+ thriftgen::OperationSamplingStrategy strategy;
+ strategy.__set_operation(kTestOperationName);
+ thriftgen::ProbabilisticSamplingStrategy probabilisticSampling;
+ probabilisticSampling.__set_samplingRate(kTestDefaultSamplingProbability);
+ strategy.__set_probabilisticSampling(probabilisticSampling);
+
+ thriftgen::PerOperationSamplingStrategies strategies;
+ strategies.__set_defaultSamplingProbability(
+ kTestDefaultSamplingProbability);
+ strategies.__set_defaultLowerBoundTracesPerSecond(1.0);
+ strategies.__set_perOperationStrategies({ strategy });
+
+ AdaptiveSampler sampler(strategies, kTestDefaultMaxOperations);
+ auto result =
+ sampler.isSampled(TraceID(0, kTestMaxID + 10), kTestOperationName);
+ ASSERT_TRUE(result.isSampled());
+ CMP_TAGS(testLowerBoundExpectedTags, result.tags());
+
+ result = sampler.isSampled(TraceID(0, kTestMaxID - 20), kTestOperationName);
+ ASSERT_TRUE(result.isSampled());
+ CMP_TAGS(testProbablisticExpectedTags, result.tags());
+
+ result = sampler.isSampled(TraceID(0, kTestMaxID + 10), kTestOperationName);
+ ASSERT_FALSE(result.isSampled());
+
+ result = sampler.isSampled(TraceID(0, kTestMaxID - 20),
+ kTestFirstTimeOperationName);
+ ASSERT_TRUE(result.isSampled());
+ CMP_TAGS(testProbablisticExpectedTags, result.tags());
+}
+
+TEST(Sampler, testAdaptiveSamplerErrors)
+{
+ namespace thriftgen = sampling_manager::thrift;
+
+ thriftgen::OperationSamplingStrategy strategy;
+ strategy.__set_operation(kTestOperationName);
+ thriftgen::ProbabilisticSamplingStrategy probabilisticSampling;
+ probabilisticSampling.__set_samplingRate(-0.1);
+ strategy.__set_probabilisticSampling(probabilisticSampling);
+
+ thriftgen::PerOperationSamplingStrategies strategies;
+ strategies.__set_defaultSamplingProbability(
+ kTestDefaultSamplingProbability);
+ strategies.__set_defaultLowerBoundTracesPerSecond(2.0);
+ strategies.__set_perOperationStrategies({ strategy });
+
+ {
+ AdaptiveSampler sampler(strategies, kTestDefaultMaxOperations);
+ }
+
+ {
+ strategies.perOperationStrategies.at(0)
+ .probabilisticSampling.__set_samplingRate(1.1);
+ AdaptiveSampler sampler(strategies, kTestDefaultMaxOperations);
+ }
+}
+
+TEST(Sampler, testAdaptiveSamplerUpdate)
+{
+ namespace thriftgen = sampling_manager::thrift;
+
+ constexpr auto kSamplingRate = 0.1;
+ constexpr auto kLowerBound = 2.0;
+
+ thriftgen::OperationSamplingStrategy strategy;
+ strategy.__set_operation(kTestOperationName);
+ thriftgen::ProbabilisticSamplingStrategy probabilisticSampling;
+ probabilisticSampling.__set_samplingRate(kSamplingRate);
+ strategy.__set_probabilisticSampling(probabilisticSampling);
+
+ thriftgen::PerOperationSamplingStrategies strategies;
+ strategies.__set_defaultSamplingProbability(
+ kTestDefaultSamplingProbability);
+ strategies.__set_defaultLowerBoundTracesPerSecond(kLowerBound);
+ strategies.__set_perOperationStrategies({ strategy });
+
+ AdaptiveSampler sampler(strategies, kTestDefaultMaxOperations);
+
+ constexpr auto kNewSamplingRate = 0.2;
+ constexpr auto kNewLowerBound = 3.0;
+ constexpr auto kNewDefaultSamplingProbability = 0.1;
+
+ // Updated kTestOperationName strategy.
+ thriftgen::OperationSamplingStrategy updatedStrategy;
+ updatedStrategy.__set_operation(kTestOperationName);
+ thriftgen::ProbabilisticSamplingStrategy updatedProbabilisticSampling;
+ updatedProbabilisticSampling.__set_samplingRate(kNewSamplingRate);
+ updatedStrategy.__set_probabilisticSampling(updatedProbabilisticSampling);
+
+ // New kTestFirstTimeOperationName strategy.
+ thriftgen::OperationSamplingStrategy newStrategy;
+ newStrategy.__set_operation(kTestFirstTimeOperationName);
+ thriftgen::ProbabilisticSamplingStrategy newProbabilisticSampling;
+ newProbabilisticSampling.__set_samplingRate(kNewSamplingRate);
+ newStrategy.__set_probabilisticSampling(newProbabilisticSampling);
+
+ thriftgen::PerOperationSamplingStrategies newStrategies;
+ newStrategies.__set_defaultSamplingProbability(
+ kNewDefaultSamplingProbability);
+ newStrategies.__set_defaultLowerBoundTracesPerSecond(kNewLowerBound);
+ newStrategies.__set_perOperationStrategies(
+ { updatedStrategy, newStrategy });
+
+ sampler.update(newStrategies);
+}
+
+TEST(Sampler, testRemotelyControlledSampler)
+{
+ const auto mockAgent = testutils::MockAgent::make();
+ mockAgent->start();
+ const auto logger = logging::nullLogger();
+ const auto metrics = metrics::Metrics::makeNullMetrics();
+
+ // Make sure remote sampling probability is 1
+ sampling_manager::thrift::SamplingStrategyResponse config;
+ config.__set_strategyType(
+ sampling_manager::thrift::SamplingStrategyType::PROBABILISTIC);
+ sampling_manager::thrift::ProbabilisticSamplingStrategy probaStrategy;
+ probaStrategy.__set_samplingRate(1.0);
+ config.__set_probabilisticSampling(probaStrategy);
+ mockAgent->addSamplingStrategy("test-service", config);
+
+ // Default probability of 0.5, switches to 1 when downloaded
+ RemotelyControlledSampler sampler(
+ "test-service",
+ "http://" + mockAgent->samplingServerAddress().authority(),
+ std::make_shared<ProbabilisticSampler>(kTestDefaultSamplingProbability),
+ kTestDefaultMaxOperations,
+ std::chrono::milliseconds(100),
+ *logger,
+ *metrics);
+
+ // Wait a bit for remote config download to be done
+ std::this_thread::sleep_for(std::chrono::milliseconds(100));
+ std::random_device device;
+ std::mt19937_64 rng;
+ rng.seed(device());
+ for (auto startTime = RemotelyControlledSampler::Clock::now();
+ std::chrono::duration_cast<std::chrono::seconds>(
+ RemotelyControlledSampler::Clock::now() - startTime)
+ .count() < 1;) {
+ TraceID traceID(rng(), rng());
+ // If probability was 0.5 we could reasonnably assume one of 50 samples fail
+ ASSERT_TRUE(sampler.isSampled(traceID, kTestOperationName).isSampled());
+ std::this_thread::sleep_for(std::chrono::milliseconds(20));
+ }
+ sampler.close();
+}
+
+} // namespace samplers
+} // namespace jaegertracing
diff --git a/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/samplers/SamplingStatus.cpp b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/samplers/SamplingStatus.cpp
new file mode 100644
index 000000000..1dafffa9f
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/samplers/SamplingStatus.cpp
@@ -0,0 +1,17 @@
+/*
+ * 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.
+ */
+
+#include "jaegertracing/samplers/SamplingStatus.h"
diff --git a/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/samplers/SamplingStatus.h b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/samplers/SamplingStatus.h
new file mode 100644
index 000000000..a0ea3e4ed
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/samplers/SamplingStatus.h
@@ -0,0 +1,49 @@
+/*
+ * 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_SAMPLERS_SAMPLINGSTATUS_H
+#define JAEGERTRACING_SAMPLERS_SAMPLINGSTATUS_H
+
+#include <vector>
+
+#include "jaegertracing/Compilers.h"
+
+#include "jaegertracing/Tag.h"
+
+namespace jaegertracing {
+namespace samplers {
+
+class SamplingStatus {
+ public:
+ SamplingStatus(bool isSampled, const std::vector<Tag>& tags)
+ : _isSampled(isSampled)
+ , _tags(tags)
+ {
+ }
+
+ bool isSampled() const { return _isSampled; }
+
+ const std::vector<Tag>& tags() const { return _tags; }
+
+ private:
+ bool _isSampled;
+ std::vector<Tag> _tags;
+};
+
+} // namespace samplers
+} // namespace jaegertracing
+
+#endif // JAEGERTRACING_SAMPLERS_SAMPLINGSTATUS_H
diff --git a/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/testutils/EnvVariable.cpp b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/testutils/EnvVariable.cpp
new file mode 100644
index 000000000..726bbb23f
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/testutils/EnvVariable.cpp
@@ -0,0 +1,17 @@
+/*
+ * Copyright (c) 2019 The Jaeger Authors.
+ *
+ * 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.
+ */
+
+#include "jaegertracing/testutils/EnvVariable.h"
diff --git a/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/testutils/EnvVariable.h b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/testutils/EnvVariable.h
new file mode 100644
index 000000000..ec6121406
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/testutils/EnvVariable.h
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2019 The Jaeger Authors.
+ *
+ * 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_TESTUTILS_ENVVARIABLE_H
+#define JAEGERTRACING_TESTUTILS_ENVVARIABLE_H
+
+#include <string>
+
+namespace jaegertracing {
+namespace testutils {
+namespace EnvVariable {
+
+inline void setEnv(const char *variable, const char *value) {
+#ifdef WIN32
+ _putenv_s(variable, value);
+#else
+ setenv(variable, value, true);
+#endif
+}
+
+} // namespace EnvVariable
+} // namespace testutils
+} // namespace jaegertracing
+
+#endif // JAEGERTRACING_TESTUTILS_ENVVARIABLE_H
diff --git a/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/testutils/MockAgent.cpp b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/testutils/MockAgent.cpp
new file mode 100644
index 000000000..3af881b02
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/testutils/MockAgent.cpp
@@ -0,0 +1,253 @@
+/*
+ * Copyright (c) 2017-2018 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.
+ */
+
+#include "jaegertracing/testutils/MockAgent.h"
+
+#include <regex>
+#include <thread>
+
+#include <thrift/protocol/TCompactProtocol.h>
+#include <thrift/transport/TBufferTransports.h>
+
+#include "jaegertracing/Logging.h"
+#include "jaegertracing/baggage/RemoteRestrictionJSON.h"
+#include "jaegertracing/net/http/Error.h"
+#include "jaegertracing/net/http/Request.h"
+#include "jaegertracing/net/http/Response.h"
+#include "jaegertracing/samplers/RemoteSamplingJSON.h"
+#include "jaegertracing/utils/ErrorUtil.h"
+#include "jaegertracing/utils/UDPTransporter.h"
+
+#ifdef _MSC_VER
+#pragma warning(disable : 4267)
+#pragma warning(disable : 4244)
+#endif
+
+namespace jaegertracing {
+namespace testutils {
+namespace {
+
+#ifdef WIN32
+#define READ_ERROR SOCKET_ERROR
+#else
+#define READ_ERROR -1
+#endif
+
+static size_t read(int socketHandle, char* buffer, size_t size)
+{
+ int returnValue = ::recv(socketHandle, buffer, size, 0);
+ return (returnValue == READ_ERROR) ? 0 : returnValue;
+}
+
+bool startsWith(const std::string& str, const std::string& prefix)
+{
+ if (str.size() < prefix.size()) {
+ return false;
+ }
+ return std::equal(std::begin(prefix), std::end(prefix), std::begin(str));
+}
+
+} // anonymous namespace
+
+MockAgent::~MockAgent() { close(); }
+
+void MockAgent::start()
+{
+ std::promise<void> startedUDP;
+ std::promise<void> startedHTTP;
+ _udpThread = std::thread([this, &startedUDP]() { serveUDP(startedUDP); });
+ _httpThread =
+ std::thread([this, &startedHTTP]() { serveHTTP(startedHTTP); });
+ startedUDP.get_future().wait();
+ startedHTTP.get_future().wait();
+}
+
+void MockAgent::close()
+{
+ if (_servingUDP) {
+ _servingUDP = false;
+ _transport.close();
+ _udpThread.join();
+ }
+
+ if (_servingHTTP) {
+ _servingHTTP = false;
+ _httpThread.join();
+ }
+}
+
+void MockAgent::emitBatch(const thrift::Batch& batch)
+{
+ std::lock_guard<std::mutex> lock(_mutex);
+ _batches.push_back(batch);
+}
+
+MockAgent::MockAgent()
+ : _transport(net::IPAddress::v4("127.0.0.1", 0))
+ , _servingUDP(false)
+{
+}
+
+void MockAgent::serveUDP(std::promise<void>& started)
+{
+ using TCompactProtocolFactory =
+ apache::thrift::protocol::TCompactProtocolFactory;
+ using TMemoryBuffer = apache::thrift::transport::TMemoryBuffer;
+
+ auto iface = shared_from_this();
+ agent::thrift::AgentProcessor handler(iface);
+ TCompactProtocolFactory protocolFactory;
+ std::shared_ptr<TMemoryBuffer> trans(
+ new TMemoryBuffer(utils::UDPTransporter::kUDPPacketMaxLength));
+
+ // Notify main thread that setup is done.
+ _servingUDP = true;
+ started.set_value();
+
+ std::array<uint8_t, utils::UDPTransporter::kUDPPacketMaxLength> buffer;
+ while (isServingUDP()) {
+ try {
+ const auto numRead =
+ _transport.read(&buffer[0], utils::UDPTransporter::kUDPPacketMaxLength);
+ if (numRead > 0) {
+ trans->write(&buffer[0], numRead);
+ auto protocol = protocolFactory.getProtocol(trans);
+ handler.process(protocol, protocol, nullptr);
+ }
+ } catch (...) {
+ auto logger = logging::consoleLogger();
+ utils::ErrorUtil::logError(
+ *logger, "An error occurred in MockAgent::serveUDP");
+ }
+ }
+}
+
+void MockAgent::serveHTTP(std::promise<void>& started)
+{
+ net::Socket socket;
+ socket.open(AF_INET, SOCK_STREAM);
+ socket.bind(net::IPAddress::v4("127.0.0.1", 0));
+ socket.listen();
+ ::sockaddr_storage addrStorage;
+ ::socklen_t addrLen = sizeof(addrStorage);
+ const auto returnCode = ::getsockname(
+ socket.handle(), reinterpret_cast<sockaddr*>(&addrStorage), &addrLen);
+ if (returnCode != 0) {
+ throw std::system_error(errno,
+ std::generic_category(),
+ "Failed to get HTTP address from socket");
+ }
+ _httpAddress = net::IPAddress(addrStorage, addrLen);
+
+ _servingHTTP = true;
+ started.set_value();
+
+ const std::regex servicePattern("[?&]service=([^?&]+)");
+ while (isServingHTTP()) {
+ constexpr auto kBufferSize = 256;
+ std::array<char, kBufferSize> buffer;
+ std::string requestStr;
+ auto clientSocket = socket.accept();
+ auto numRead = read(
+ clientSocket.handle(), &buffer[0], buffer.size());
+ while (numRead > 0) {
+ requestStr.append(&buffer[0], numRead);
+ if (numRead < static_cast<int>(buffer.size())) {
+ break;
+ }
+ numRead = read(
+ clientSocket.handle(), &buffer[0], buffer.size());
+ }
+
+ try {
+ enum class Resource { kSampler, kBaggage };
+
+ std::istringstream iss(requestStr);
+ const auto request = net::http::Request::parse(iss);
+ const auto target = request.target();
+
+ auto resource = Resource::kSampler;
+ if (startsWith(target, "/baggageRestrictions") ||
+ startsWith(target,
+ _httpAddress.authority() + "/baggageRestrictions")) {
+ resource = Resource::kBaggage;
+ }
+ std::smatch match;
+ if (!std::regex_search(target, match, servicePattern)) {
+ throw net::http::ParseError("no 'service' parameter");
+ }
+ if (std::regex_search(match.suffix().str(), servicePattern)) {
+ throw net::http::ParseError(
+ "'service' parameter must occur only once");
+ }
+ const auto serviceName = match[1].str();
+
+ std::string responseJSON;
+ switch (resource) {
+ case Resource::kSampler: {
+ sampling_manager::thrift::SamplingStrategyResponse response;
+ _samplingMgr.getSamplingStrategy(response, serviceName);
+ responseJSON = nlohmann::json(response).dump();
+ } break;
+ default: {
+ assert(resource == Resource::kBaggage);
+ thrift::BaggageRestrictionManager_getBaggageRestrictions_result
+ response;
+ std::vector<thrift::BaggageRestriction> restrictions;
+ restrictions.reserve(_restrictions.size());
+ std::transform(std::begin(_restrictions),
+ std::end(_restrictions),
+ std::back_inserter(restrictions),
+ [](const KeyRestrictionMap::value_type& pair) {
+ thrift::BaggageRestriction restriction;
+ restriction.__set_baggageKey(pair.first);
+ restriction.__set_maxValueLength(
+ pair.second.maxValueLength());
+ return restriction;
+ });
+ response.success = std::move(restrictions);
+ response.__isset.success = true;
+ responseJSON = nlohmann::json(response).dump();
+ } break;
+ }
+ std::ostringstream oss;
+ oss << "HTTP/1.1 200 OK\r\n"
+ "Content-Type: application/json\r\n\r\n"
+ << responseJSON;
+ const auto responseStr = oss.str();
+ const auto numWritten = ::send(
+ clientSocket.handle(), responseStr.c_str(), responseStr.size(), 0);
+ (void)numWritten;
+ } catch (const net::http::ParseError& ex) {
+ std::ostringstream oss;
+ oss << "HTTP/1.1 400 Bad Request\r\n\r\n" << ex.what();
+ const auto response = oss.str();
+ const auto numWritten = ::send(
+ clientSocket.handle(), response.c_str(), response.size(), 0);
+ (void)numWritten;
+ } catch (const std::exception& ex) {
+ std::ostringstream oss;
+ oss << "HTTP/1.1 500 Internal Server Error\r\n\r\n" << ex.what();
+ const auto response = oss.str();
+ const auto numWritten = ::send(
+ clientSocket.handle(), response.c_str(), response.size(), 0);
+ (void)numWritten;
+ }
+ }
+}
+
+} // namespace testutils
+} // namespace jaegertracing
diff --git a/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/testutils/MockAgent.h b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/testutils/MockAgent.h
new file mode 100644
index 000000000..6a761ada7
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/testutils/MockAgent.h
@@ -0,0 +1,143 @@
+/*
+ * 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_TESTUTILS_MOCKAGENT_H
+#define JAEGERTRACING_TESTUTILS_MOCKAGENT_H
+
+#include "jaegertracing/Compilers.h"
+
+#include "jaegertracing/baggage/RemoteRestrictionManager.h"
+#include "jaegertracing/net/IPAddress.h"
+#include "jaegertracing/testutils/SamplingManager.h"
+#include "jaegertracing/testutils/TUDPTransport.h"
+#include "jaegertracing/thrift-gen/Agent.h"
+#include "jaegertracing/thrift-gen/jaeger_types.h"
+#include "jaegertracing/utils/UDPTransporter.h"
+#include <atomic>
+#include <future>
+#include <memory>
+#include <mutex>
+#include <stdexcept>
+#include <string>
+#include <thread>
+#include <type_traits>
+#include <utility>
+#include <vector>
+
+namespace jaegertracing {
+namespace baggage {
+class Restriction;
+} // namespace baggage
+} // namespace jaegertracing
+namespace twitter {
+namespace zipkin {
+namespace thrift {
+class Span;
+} // namespace thrift
+} // namespace zipkin
+} // namespace twitter
+
+namespace jaegertracing {
+namespace testutils {
+
+class MockAgent : public agent::thrift::AgentIf,
+ public std::enable_shared_from_this<MockAgent> {
+ public:
+ using KeyRestrictionMap =
+ baggage::RemoteRestrictionManager::KeyRestrictionMap;
+
+ static std::shared_ptr<MockAgent> make()
+ {
+ // Avoid `make_shared` when `weak_ptr` might be used.
+ std::shared_ptr<MockAgent> newInstance(new MockAgent());
+ return newInstance;
+ }
+
+ ~MockAgent();
+
+ void start();
+
+ void close();
+
+ void
+ emitZipkinBatch(const std::vector<twitter::zipkin::thrift::Span>&) override
+ {
+ throw std::logic_error("emitZipkinBatch not implemented");
+ }
+
+ void emitBatch(const thrift::Batch& batch) override;
+
+ bool isServingUDP() const { return _servingUDP; }
+
+ bool isServingHTTP() const { return _servingHTTP; }
+
+ template <typename... Args>
+ void addSamplingStrategy(Args&&... args)
+ {
+ _samplingMgr.addSamplingStrategy(std::forward<Args>(args)...);
+ }
+
+ void addBaggageRestriction(const std::string& key,
+ const baggage::Restriction& restriction)
+ {
+ _restrictions.insert(std::make_pair(key, restriction));
+ }
+
+ std::vector<thrift::Batch> batches() const
+ {
+ std::lock_guard<std::mutex> lock(_mutex);
+ return _batches;
+ }
+
+ net::IPAddress spanServerAddress() const { return _transport.addr(); }
+
+ std::unique_ptr<utils::Transport> spanServerClient()
+ {
+ return std::unique_ptr<utils::Transport>(
+ new utils::UDPTransporter(spanServerAddress(), 0));
+ }
+
+ net::IPAddress samplingServerAddress() const { return _httpAddress; }
+
+ void resetBatches()
+ {
+ std::lock_guard<std::mutex> lock(_mutex);
+ _batches.clear();
+ }
+
+ private:
+ MockAgent();
+
+ void serveUDP(std::promise<void>& started);
+
+ void serveHTTP(std::promise<void>& started);
+
+ TUDPTransport _transport;
+ std::vector<thrift::Batch> _batches;
+ std::atomic<bool> _servingUDP;
+ std::atomic<bool> _servingHTTP;
+ SamplingManager _samplingMgr;
+ KeyRestrictionMap _restrictions;
+ mutable std::mutex _mutex;
+ std::thread _udpThread;
+ std::thread _httpThread;
+ net::IPAddress _httpAddress;
+};
+
+} // namespace testutils
+} // namespace jaegertracing
+
+#endif // JAEGERTRACING_TESTUTILS_MOCKAGENT_H
diff --git a/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/testutils/MockAgentTest.cpp b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/testutils/MockAgentTest.cpp
new file mode 100644
index 000000000..a9b3d2981
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/testutils/MockAgentTest.cpp
@@ -0,0 +1,128 @@
+/*
+ * 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.
+ */
+
+#include <sstream>
+
+#include <gtest/gtest.h>
+#include <nlohmann/json.hpp>
+
+#include "jaegertracing/baggage/RemoteRestrictionJSON.h"
+#include "jaegertracing/net/http/Response.h"
+#include "jaegertracing/samplers/RemoteSamplingJSON.h"
+#include "jaegertracing/testutils/MockAgent.h"
+
+namespace jaegertracing {
+namespace testutils {
+
+TEST(MockAgent, testSpanServer)
+{
+ std::shared_ptr<MockAgent> mockAgent = MockAgent::make();
+ mockAgent->start();
+
+ auto client = mockAgent->spanServerClient();
+
+ constexpr auto kBiggestBatch = 5;
+ for (auto i = 1; i < kBiggestBatch; ++i) {
+ thrift::Batch batch;
+ batch.spans.resize(i);
+ for (auto j = 0; j < i; ++j) {
+ std::string operationName("span-");
+ operationName += std::to_string(j);
+ batch.spans[j].__set_operationName(operationName);
+ }
+
+ client->emitBatch(batch);
+
+ constexpr auto kNumTries = 100;
+ for (auto k = 0; k < kNumTries; ++k) {
+ std::this_thread::sleep_for(std::chrono::milliseconds(1));
+ const auto batches = mockAgent->batches();
+ if (!batches.empty() &&
+ static_cast<int>(batches[0].spans.size()) == i) {
+ break;
+ }
+ }
+
+ const auto batches = mockAgent->batches();
+ ASSERT_FALSE(batches.empty());
+ ASSERT_EQ(i, static_cast<int>(batches[0].spans.size()));
+ for (auto j = 0; j < i; ++j) {
+ std::string operationName("span-");
+ operationName += std::to_string(j);
+ ASSERT_EQ(operationName, batches[0].spans[j].operationName);
+ }
+ mockAgent->resetBatches();
+ }
+}
+
+TEST(MockAgent, testSamplingManager)
+{
+ auto mockAgent = MockAgent::make();
+ mockAgent->start();
+
+ {
+ std::ostringstream oss;
+ oss << "http://" << mockAgent->samplingServerAddress().authority()
+ << '/';
+ const auto uriStr = oss.str();
+ const auto uri = net::URI::parse(uriStr);
+ const auto response = net::http::get(uri);
+ ASSERT_EQ("no 'service' parameter", response.body());
+ }
+ {
+ std::ostringstream oss;
+ oss << "http://" << mockAgent->samplingServerAddress().authority()
+ << "/?service=a&service=b";
+ const auto uriStr = oss.str();
+ const auto uri = net::URI::parse(uriStr);
+ const auto response = net::http::get(uri);
+ ASSERT_EQ("'service' parameter must occur only once", response.body());
+ }
+ {
+ std::ostringstream oss;
+ oss << "http://" << mockAgent->samplingServerAddress().authority()
+ << "/?service=something";
+ const auto uriStr = oss.str();
+ const auto uri = net::URI::parse(uriStr);
+ const auto responseHTTP = net::http::get(uri);
+ sampling_manager::thrift::SamplingStrategyResponse response;
+ response = nlohmann::json::parse(responseHTTP.body());
+ ASSERT_EQ(sampling_manager::thrift::SamplingStrategyType::PROBABILISTIC,
+ response.strategyType);
+ }
+ {
+ sampling_manager::thrift::SamplingStrategyResponse config;
+ config.__set_strategyType(
+ sampling_manager::thrift::SamplingStrategyType::RATE_LIMITING);
+ sampling_manager::thrift::RateLimitingSamplingStrategy rateLimiting;
+ rateLimiting.__set_maxTracesPerSecond(123);
+ config.__set_rateLimitingSampling(rateLimiting);
+ mockAgent->addSamplingStrategy("service123", config);
+
+ std::ostringstream oss;
+ oss << "http://" << mockAgent->samplingServerAddress().authority()
+ << "/?service=service123";
+ const auto uriStr = oss.str();
+ const auto uri = net::URI::parse(uriStr);
+ const auto responseHTTP = net::http::get(uri);
+ sampling_manager::thrift::SamplingStrategyResponse response;
+ response = nlohmann::json::parse(responseHTTP.body());
+ ASSERT_EQ(config, response);
+ }
+}
+
+} // namespace testutils
+} // namespace jaegertracing
diff --git a/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/testutils/SamplingManager.cpp b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/testutils/SamplingManager.cpp
new file mode 100644
index 000000000..ee6c53fed
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/testutils/SamplingManager.cpp
@@ -0,0 +1,17 @@
+/*
+ * 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.
+ */
+
+#include "jaegertracing/testutils/SamplingManager.h"
diff --git a/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/testutils/SamplingManager.h b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/testutils/SamplingManager.h
new file mode 100644
index 000000000..f1cca89d7
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/testutils/SamplingManager.h
@@ -0,0 +1,76 @@
+/*
+ * 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_TESTUTILS_SAMPLINGMANAGER_H
+#define JAEGERTRACING_TESTUTILS_SAMPLINGMANAGER_H
+
+#include "jaegertracing/Compilers.h"
+
+#include "jaegertracing/thrift-gen/SamplingManager.h"
+#include "jaegertracing/thrift-gen/sampling_types.h"
+#include <iterator>
+#include <mutex>
+#include <string>
+#include <unordered_map>
+#include <utility>
+
+namespace jaegertracing {
+namespace testutils {
+
+class SamplingManager : public sampling_manager::thrift::SamplingManagerIf {
+ public:
+ using Response = sampling_manager::thrift::SamplingStrategyResponse;
+
+ void getSamplingStrategy(Response& response,
+ const std::string& service) override
+ {
+ using ProbabilisticSamplingStrategy =
+ sampling_manager::thrift::ProbabilisticSamplingStrategy;
+ using SamplingStrategyType =
+ sampling_manager::thrift::SamplingStrategyType;
+
+ std::lock_guard<std::mutex> lock(_mutex);
+ auto responseItr = _sampling.find(service);
+ if (responseItr != std::end(_sampling)) {
+ response = responseItr->second;
+ return;
+ }
+
+ constexpr auto kSamplingRate = 0.01;
+ ProbabilisticSamplingStrategy probabilisticSampling;
+ probabilisticSampling.__set_samplingRate(kSamplingRate);
+ response.__set_strategyType(SamplingStrategyType::PROBABILISTIC);
+ response.__set_probabilisticSampling(probabilisticSampling);
+ }
+
+ void addSamplingStrategy(const std::string& serviceName,
+ const Response& response)
+ {
+ std::lock_guard<std::mutex> lock(_mutex);
+ _sampling[serviceName] = response;
+ }
+
+ private:
+ using StrategyMap = std::unordered_map<std::string, Response>;
+
+ StrategyMap _sampling;
+ std::mutex _mutex;
+};
+
+} // namespace testutils
+} // namespace jaegertracing
+
+#endif // JAEGERTRACING_TESTUTILS_SAMPLINGMANAGER_H
diff --git a/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/testutils/TUDPTransport.cpp b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/testutils/TUDPTransport.cpp
new file mode 100644
index 000000000..275d1a444
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/testutils/TUDPTransport.cpp
@@ -0,0 +1,17 @@
+/*
+ * 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.
+ */
+
+#include "jaegertracing/testutils/TUDPTransport.h"
diff --git a/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/testutils/TUDPTransport.h b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/testutils/TUDPTransport.h
new file mode 100644
index 000000000..ceee2815c
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/testutils/TUDPTransport.h
@@ -0,0 +1,111 @@
+/*
+ * 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_TESTUTILS_TUDPTRANSPORT_H
+#define JAEGERTRACING_TESTUTILS_TUDPTRANSPORT_H
+
+#include "jaegertracing/Compilers.h"
+
+#ifdef WIN32
+#include <winsock2.h>
+#else
+#include <sys/socket.h>
+#endif
+
+#include <thrift/transport/TVirtualTransport.h>
+
+#include "jaegertracing/utils/UDPTransporter.h"
+
+namespace jaegertracing {
+namespace testutils {
+
+class TUDPTransport
+ : public apache::thrift::transport::TVirtualTransport<TUDPTransport> {
+ public:
+ explicit TUDPTransport(const net::IPAddress& addr)
+ : _socket()
+ , _serverAddr(addr)
+ {
+ _socket.open(AF_INET, SOCK_DGRAM);
+ _socket.bind(_serverAddr);
+ if (_serverAddr.port() == 0) {
+ ::sockaddr_storage addrStorage;
+ ::socklen_t addrLen = sizeof(addrStorage);
+ const auto returnCode =
+ ::getsockname(_socket.handle(),
+ reinterpret_cast<::sockaddr*>(&addrStorage),
+ &addrLen);
+ if (returnCode == 0) {
+ _serverAddr = net::IPAddress(addrStorage, addrLen);
+ }
+ }
+ }
+
+ bool isOpen() override { return _socket.handle() >= 0; }
+
+ void open() override {}
+
+ void close() override { _socket.close(); }
+
+ net::IPAddress addr() const { return _serverAddr; }
+
+ uint32_t read(uint8_t* buf, uint32_t len)
+ {
+ ::sockaddr_storage clientAddr;
+ auto clientAddrLen = static_cast<::socklen_t>(sizeof(clientAddr));
+ const auto numRead =
+ ::recvfrom(_socket.handle(),
+#ifdef WIN32
+ reinterpret_cast<char*>(buf), // this cast is safe
+#else
+ buf,
+#endif
+ len,
+ 0,
+ reinterpret_cast<::sockaddr*>(&clientAddr),
+ &clientAddrLen);
+ _clientAddr = net::IPAddress(clientAddr, clientAddrLen);
+ // the return value conrreponds to the size of the data read from the
+ // socket. upon error, recvfrom return -1. In this case, we return 0 to
+ // say that noothing was read.
+ return std::max<long>(0, numRead);
+ }
+
+ void write(const uint8_t* buf, uint32_t len)
+ {
+ ::sendto(_socket.handle(),
+#ifdef WIN32
+ reinterpret_cast<const char*>(buf), // this cast is safe
+#else
+ buf,
+#endif
+ len,
+ 0,
+ reinterpret_cast<const ::sockaddr*>(&_clientAddr.addr()),
+ _clientAddr.addrLen());
+ }
+
+ private:
+ net::Socket _socket;
+ net::IPAddress _serverAddr;
+ net::IPAddress _clientAddr;
+ ::socklen_t _clientAddrLen;
+};
+
+} // namespace testutils
+} // namespace jaegertracing
+
+#endif // JAEGERTRACING_TESTUTILS_TUDPTRANSPORT_H
diff --git a/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/testutils/TUDPTransportTest.cpp b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/testutils/TUDPTransportTest.cpp
new file mode 100644
index 000000000..b0c87c1e7
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/testutils/TUDPTransportTest.cpp
@@ -0,0 +1,79 @@
+/*
+ * 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.
+ */
+
+#include "jaegertracing/net/IPAddress.h"
+#include "jaegertracing/net/Socket.h"
+#include "jaegertracing/testutils/TUDPTransport.h"
+#include <array>
+#include <cstdint>
+#include <gtest/gtest.h>
+#include <string>
+#include <thread>
+
+#ifdef _MSC_VER
+#pragma warning(disable : 4267)
+#endif
+
+namespace jaegertracing {
+namespace testutils {
+namespace {
+
+constexpr auto kBufferSize = 256;
+
+} // anonymous namespace
+
+TEST(TUDPTransport, testUDPTransport)
+{
+ const std::string message("test");
+
+ TUDPTransport server(net::IPAddress::v4("127.0.0.1", 0));
+ server.open(); // Not necessary. Just making sure this is called.
+ ASSERT_TRUE(server.isOpen());
+
+ const auto serverAddr = server.addr();
+ std::thread clientThread([serverAddr, message]() {
+ net::Socket connUDP;
+ connUDP.open(AF_INET, SOCK_DGRAM);
+ const auto numWritten =
+ ::sendto(connUDP.handle(),
+ message.c_str(),
+ message.size(),
+ 0,
+ reinterpret_cast<const ::sockaddr*>(&serverAddr.addr()),
+ serverAddr.addrLen());
+ ASSERT_EQ(numWritten, message.size());
+
+ std::array<char, kBufferSize> buffer;
+ const auto numRead = ::recvfrom(
+ connUDP.handle(), &buffer[0], buffer.size(), 0, nullptr, 0);
+ const std::string received(&buffer[0], &buffer[numRead]);
+ ASSERT_EQ(message.size(), numRead);
+ ASSERT_EQ(message, received);
+
+ connUDP.close();
+ });
+
+ std::array<uint8_t, kBufferSize> buffer;
+ const auto numRead = server.readAll(&buffer[0], message.size());
+ ASSERT_LT(0, numRead);
+ server.write(&buffer[0], numRead);
+
+ clientThread.join();
+ server.close();
+}
+
+} // namespace testutils
+} // namespace jaegertracing
diff --git a/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/testutils/TracerUtil.cpp b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/testutils/TracerUtil.cpp
new file mode 100644
index 000000000..ffa65c1f5
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/testutils/TracerUtil.cpp
@@ -0,0 +1,82 @@
+/*
+ * 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.
+ */
+
+#include "jaegertracing/testutils/TracerUtil.h"
+#include "jaegertracing/Config.h"
+#include "jaegertracing/Logging.h"
+#include "jaegertracing/Tracer.h"
+#include "jaegertracing/baggage/RestrictionsConfig.h"
+#include "jaegertracing/net/IPAddress.h"
+#include "jaegertracing/propagation/HeadersConfig.h"
+#include "jaegertracing/reporters/Config.h"
+#include "jaegertracing/samplers/Config.h"
+#include <memory>
+#include <ostream>
+#include <string>
+
+namespace jaegertracing {
+namespace testutils {
+namespace TracerUtil {
+
+std::shared_ptr<ResourceHandle> installGlobalTracer()
+{
+ std::unique_ptr<ResourceHandle> handle(new ResourceHandle());
+ handle->_mockAgent->start();
+ std::ostringstream samplingServerURLStream;
+ samplingServerURLStream
+ << "http://" << handle->_mockAgent->samplingServerAddress().authority();
+ Config config(
+ false,
+ samplers::Config("const",
+ 1,
+ samplingServerURLStream.str(),
+ 0,
+ samplers::Config::Clock::duration()),
+ reporters::Config(0,
+ reporters::Config::Clock::duration(),
+ false,
+ handle->_mockAgent->spanServerAddress().authority()),
+ propagation::HeadersConfig(),
+ baggage::RestrictionsConfig());
+
+ auto tracer = Tracer::make("test-service", config, logging::nullLogger());
+ opentracing::Tracer::InitGlobal(tracer);
+ return std::move(handle);
+}
+
+std::shared_ptr<opentracing::Tracer> buildTracer(const std::string& endpoint)
+{
+ std::ostringstream samplingServerURLStream;
+ Config config(
+ false,
+ samplers::Config("const",
+ 1,
+ samplingServerURLStream.str(),
+ 0,
+ samplers::Config::Clock::duration()),
+ reporters::Config(0,
+ std::chrono::milliseconds(100),
+ false, "", endpoint),
+ propagation::HeadersConfig(),
+ baggage::RestrictionsConfig());
+
+ auto tracer = Tracer::make("test-service", config, logging::nullLogger());
+ return tracer;
+}
+
+} // namespace TracerUtil
+} // namespace testutils
+} // namespace jaegertracing
diff --git a/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/testutils/TracerUtil.h b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/testutils/TracerUtil.h
new file mode 100644
index 000000000..a61e57006
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/testutils/TracerUtil.h
@@ -0,0 +1,50 @@
+/*
+ * 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_TESTUTILS_TRACERUTIL_H
+#define JAEGERTRACING_TESTUTILS_TRACERUTIL_H
+
+#include <string>
+
+#include "jaegertracing/Tracer.h"
+#include "jaegertracing/testutils/MockAgent.h"
+
+namespace jaegertracing {
+namespace testutils {
+namespace TracerUtil {
+
+struct ResourceHandle {
+ ResourceHandle()
+ : _mockAgent(testutils::MockAgent::make())
+ {
+ }
+
+ ~ResourceHandle()
+ {
+ opentracing::Tracer::InitGlobal(opentracing::MakeNoopTracer());
+ }
+
+ std::shared_ptr<MockAgent> _mockAgent;
+};
+
+std::shared_ptr<ResourceHandle> installGlobalTracer();
+std::shared_ptr<opentracing::Tracer> buildTracer(const std::string& endpoint);
+
+} // namespace TracerUtil
+} // namespace testutils
+} // namespace jaegertracing
+
+#endif // JAEGERTRACING_TESTUTILS_TRACERUTIL_H
diff --git a/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/thrift-gen/Agent.cpp b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/thrift-gen/Agent.cpp
new file mode 100644
index 000000000..db05c0004
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/thrift-gen/Agent.cpp
@@ -0,0 +1,380 @@
+/**
+ * Autogenerated by Thrift Compiler (0.11.0)
+ *
+ * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
+ * @generated
+ */
+#include "Agent.h"
+
+namespace jaegertracing { namespace agent { namespace thrift {
+
+
+Agent_emitZipkinBatch_args::~Agent_emitZipkinBatch_args() throw() {
+}
+
+
+uint32_t Agent_emitZipkinBatch_args::read(::apache::thrift::protocol::TProtocol* iprot) {
+
+ ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
+ uint32_t xfer = 0;
+ std::string fname;
+ ::apache::thrift::protocol::TType ftype;
+ int16_t fid;
+
+ xfer += iprot->readStructBegin(fname);
+
+ using ::apache::thrift::protocol::TProtocolException;
+
+
+ while (true)
+ {
+ xfer += iprot->readFieldBegin(fname, ftype, fid);
+ if (ftype == ::apache::thrift::protocol::T_STOP) {
+ break;
+ }
+ switch (fid)
+ {
+ case 1:
+ if (ftype == ::apache::thrift::protocol::T_LIST) {
+ {
+ this->spans.clear();
+ uint32_t _size0;
+ ::apache::thrift::protocol::TType _etype3;
+ xfer += iprot->readListBegin(_etype3, _size0);
+ this->spans.resize(_size0);
+ uint32_t _i4;
+ for (_i4 = 0; _i4 < _size0; ++_i4)
+ {
+ xfer += this->spans[_i4].read(iprot);
+ }
+ xfer += iprot->readListEnd();
+ }
+ this->__isset.spans = true;
+ } else {
+ xfer += iprot->skip(ftype);
+ }
+ break;
+ default:
+ xfer += iprot->skip(ftype);
+ break;
+ }
+ xfer += iprot->readFieldEnd();
+ }
+
+ xfer += iprot->readStructEnd();
+
+ return xfer;
+}
+
+uint32_t Agent_emitZipkinBatch_args::write(::apache::thrift::protocol::TProtocol* oprot) const {
+ uint32_t xfer = 0;
+ ::apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
+ xfer += oprot->writeStructBegin("Agent_emitZipkinBatch_args");
+
+ xfer += oprot->writeFieldBegin("spans", ::apache::thrift::protocol::T_LIST, 1);
+ {
+ xfer += oprot->writeListBegin(::apache::thrift::protocol::T_STRUCT, static_cast<uint32_t>(this->spans.size()));
+ std::vector< ::twitter::zipkin::thrift::Span> ::const_iterator _iter5;
+ for (_iter5 = this->spans.begin(); _iter5 != this->spans.end(); ++_iter5)
+ {
+ xfer += (*_iter5).write(oprot);
+ }
+ xfer += oprot->writeListEnd();
+ }
+ xfer += oprot->writeFieldEnd();
+
+ xfer += oprot->writeFieldStop();
+ xfer += oprot->writeStructEnd();
+ return xfer;
+}
+
+
+Agent_emitZipkinBatch_pargs::~Agent_emitZipkinBatch_pargs() throw() {
+}
+
+
+uint32_t Agent_emitZipkinBatch_pargs::write(::apache::thrift::protocol::TProtocol* oprot) const {
+ uint32_t xfer = 0;
+ ::apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
+ xfer += oprot->writeStructBegin("Agent_emitZipkinBatch_pargs");
+
+ xfer += oprot->writeFieldBegin("spans", ::apache::thrift::protocol::T_LIST, 1);
+ {
+ xfer += oprot->writeListBegin(::apache::thrift::protocol::T_STRUCT, static_cast<uint32_t>((*(this->spans)).size()));
+ std::vector< ::twitter::zipkin::thrift::Span> ::const_iterator _iter6;
+ for (_iter6 = (*(this->spans)).begin(); _iter6 != (*(this->spans)).end(); ++_iter6)
+ {
+ xfer += (*_iter6).write(oprot);
+ }
+ xfer += oprot->writeListEnd();
+ }
+ xfer += oprot->writeFieldEnd();
+
+ xfer += oprot->writeFieldStop();
+ xfer += oprot->writeStructEnd();
+ return xfer;
+}
+
+
+Agent_emitBatch_args::~Agent_emitBatch_args() throw() {
+}
+
+
+uint32_t Agent_emitBatch_args::read(::apache::thrift::protocol::TProtocol* iprot) {
+
+ ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
+ uint32_t xfer = 0;
+ std::string fname;
+ ::apache::thrift::protocol::TType ftype;
+ int16_t fid;
+
+ xfer += iprot->readStructBegin(fname);
+
+ using ::apache::thrift::protocol::TProtocolException;
+
+
+ while (true)
+ {
+ xfer += iprot->readFieldBegin(fname, ftype, fid);
+ if (ftype == ::apache::thrift::protocol::T_STOP) {
+ break;
+ }
+ switch (fid)
+ {
+ case 1:
+ if (ftype == ::apache::thrift::protocol::T_STRUCT) {
+ xfer += this->batch.read(iprot);
+ this->__isset.batch = true;
+ } else {
+ xfer += iprot->skip(ftype);
+ }
+ break;
+ default:
+ xfer += iprot->skip(ftype);
+ break;
+ }
+ xfer += iprot->readFieldEnd();
+ }
+
+ xfer += iprot->readStructEnd();
+
+ return xfer;
+}
+
+uint32_t Agent_emitBatch_args::write(::apache::thrift::protocol::TProtocol* oprot) const {
+ uint32_t xfer = 0;
+ ::apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
+ xfer += oprot->writeStructBegin("Agent_emitBatch_args");
+
+ xfer += oprot->writeFieldBegin("batch", ::apache::thrift::protocol::T_STRUCT, 1);
+ xfer += this->batch.write(oprot);
+ xfer += oprot->writeFieldEnd();
+
+ xfer += oprot->writeFieldStop();
+ xfer += oprot->writeStructEnd();
+ return xfer;
+}
+
+
+Agent_emitBatch_pargs::~Agent_emitBatch_pargs() throw() {
+}
+
+
+uint32_t Agent_emitBatch_pargs::write(::apache::thrift::protocol::TProtocol* oprot) const {
+ uint32_t xfer = 0;
+ ::apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
+ xfer += oprot->writeStructBegin("Agent_emitBatch_pargs");
+
+ xfer += oprot->writeFieldBegin("batch", ::apache::thrift::protocol::T_STRUCT, 1);
+ xfer += (*(this->batch)).write(oprot);
+ xfer += oprot->writeFieldEnd();
+
+ xfer += oprot->writeFieldStop();
+ xfer += oprot->writeStructEnd();
+ return xfer;
+}
+
+void AgentClient::emitZipkinBatch(const std::vector< ::twitter::zipkin::thrift::Span> & spans)
+{
+ send_emitZipkinBatch(spans);
+}
+
+void AgentClient::send_emitZipkinBatch(const std::vector< ::twitter::zipkin::thrift::Span> & spans)
+{
+ int32_t cseqid = 0;
+ oprot_->writeMessageBegin("emitZipkinBatch", ::apache::thrift::protocol::T_ONEWAY, cseqid);
+
+ Agent_emitZipkinBatch_pargs args;
+ args.spans = &spans;
+ args.write(oprot_);
+
+ oprot_->writeMessageEnd();
+ oprot_->getTransport()->writeEnd();
+ oprot_->getTransport()->flush();
+}
+
+void AgentClient::emitBatch(const ::jaegertracing::thrift::Batch& batch)
+{
+ send_emitBatch(batch);
+}
+
+void AgentClient::send_emitBatch(const ::jaegertracing::thrift::Batch& batch)
+{
+ int32_t cseqid = 0;
+ oprot_->writeMessageBegin("emitBatch", ::apache::thrift::protocol::T_ONEWAY, cseqid);
+
+ Agent_emitBatch_pargs args;
+ args.batch = &batch;
+ args.write(oprot_);
+
+ oprot_->writeMessageEnd();
+ oprot_->getTransport()->writeEnd();
+ oprot_->getTransport()->flush();
+}
+
+bool AgentProcessor::dispatchCall(::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, const std::string& fname, int32_t seqid, void* callContext) {
+ ProcessMap::iterator pfn;
+ pfn = processMap_.find(fname);
+ if (pfn == processMap_.end()) {
+ iprot->skip(::apache::thrift::protocol::T_STRUCT);
+ iprot->readMessageEnd();
+ iprot->getTransport()->readEnd();
+ ::apache::thrift::TApplicationException x(::apache::thrift::TApplicationException::UNKNOWN_METHOD, "Invalid method name: '"+fname+"'");
+ oprot->writeMessageBegin(fname, ::apache::thrift::protocol::T_EXCEPTION, seqid);
+ x.write(oprot);
+ oprot->writeMessageEnd();
+ oprot->getTransport()->writeEnd();
+ oprot->getTransport()->flush();
+ return true;
+ }
+ (this->*(pfn->second))(seqid, iprot, oprot, callContext);
+ return true;
+}
+
+void AgentProcessor::process_emitZipkinBatch(int32_t, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol*, void* callContext)
+{
+ void* ctx = NULL;
+ if (this->eventHandler_.get() != NULL) {
+ ctx = this->eventHandler_->getContext("Agent.emitZipkinBatch", callContext);
+ }
+ ::apache::thrift::TProcessorContextFreer freer(this->eventHandler_.get(), ctx, "Agent.emitZipkinBatch");
+
+ if (this->eventHandler_.get() != NULL) {
+ this->eventHandler_->preRead(ctx, "Agent.emitZipkinBatch");
+ }
+
+ Agent_emitZipkinBatch_args args;
+ args.read(iprot);
+ iprot->readMessageEnd();
+ uint32_t bytes = iprot->getTransport()->readEnd();
+
+ if (this->eventHandler_.get() != NULL) {
+ this->eventHandler_->postRead(ctx, "Agent.emitZipkinBatch", bytes);
+ }
+
+ try {
+ iface_->emitZipkinBatch(args.spans);
+ } catch (const std::exception&) {
+ if (this->eventHandler_.get() != NULL) {
+ this->eventHandler_->handlerError(ctx, "Agent.emitZipkinBatch");
+ }
+ return;
+ }
+
+ if (this->eventHandler_.get() != NULL) {
+ this->eventHandler_->asyncComplete(ctx, "Agent.emitZipkinBatch");
+ }
+
+ return;
+}
+
+void AgentProcessor::process_emitBatch(int32_t, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol*, void* callContext)
+{
+ void* ctx = NULL;
+ if (this->eventHandler_.get() != NULL) {
+ ctx = this->eventHandler_->getContext("Agent.emitBatch", callContext);
+ }
+ ::apache::thrift::TProcessorContextFreer freer(this->eventHandler_.get(), ctx, "Agent.emitBatch");
+
+ if (this->eventHandler_.get() != NULL) {
+ this->eventHandler_->preRead(ctx, "Agent.emitBatch");
+ }
+
+ Agent_emitBatch_args args;
+ args.read(iprot);
+ iprot->readMessageEnd();
+ uint32_t bytes = iprot->getTransport()->readEnd();
+
+ if (this->eventHandler_.get() != NULL) {
+ this->eventHandler_->postRead(ctx, "Agent.emitBatch", bytes);
+ }
+
+ try {
+ iface_->emitBatch(args.batch);
+ } catch (const std::exception&) {
+ if (this->eventHandler_.get() != NULL) {
+ this->eventHandler_->handlerError(ctx, "Agent.emitBatch");
+ }
+ return;
+ }
+
+ if (this->eventHandler_.get() != NULL) {
+ this->eventHandler_->asyncComplete(ctx, "Agent.emitBatch");
+ }
+
+ return;
+}
+
+::std::shared_ptr< ::apache::thrift::TProcessor > AgentProcessorFactory::getProcessor(const ::apache::thrift::TConnectionInfo& connInfo) {
+ ::apache::thrift::ReleaseHandler< AgentIfFactory > cleanup(handlerFactory_);
+ ::std::shared_ptr< AgentIf > handler(handlerFactory_->getHandler(connInfo), cleanup);
+ ::std::shared_ptr< ::apache::thrift::TProcessor > processor(new AgentProcessor(handler));
+ return processor;
+}
+
+void AgentConcurrentClient::emitZipkinBatch(const std::vector< ::twitter::zipkin::thrift::Span> & spans)
+{
+ send_emitZipkinBatch(spans);
+}
+
+void AgentConcurrentClient::send_emitZipkinBatch(const std::vector< ::twitter::zipkin::thrift::Span> & spans)
+{
+ int32_t cseqid = 0;
+ ::apache::thrift::async::TConcurrentSendSentry sentry(&this->sync_);
+ oprot_->writeMessageBegin("emitZipkinBatch", ::apache::thrift::protocol::T_ONEWAY, cseqid);
+
+ Agent_emitZipkinBatch_pargs args;
+ args.spans = &spans;
+ args.write(oprot_);
+
+ oprot_->writeMessageEnd();
+ oprot_->getTransport()->writeEnd();
+ oprot_->getTransport()->flush();
+
+ sentry.commit();
+}
+
+void AgentConcurrentClient::emitBatch(const ::jaegertracing::thrift::Batch& batch)
+{
+ send_emitBatch(batch);
+}
+
+void AgentConcurrentClient::send_emitBatch(const ::jaegertracing::thrift::Batch& batch)
+{
+ int32_t cseqid = 0;
+ ::apache::thrift::async::TConcurrentSendSentry sentry(&this->sync_);
+ oprot_->writeMessageBegin("emitBatch", ::apache::thrift::protocol::T_ONEWAY, cseqid);
+
+ Agent_emitBatch_pargs args;
+ args.batch = &batch;
+ args.write(oprot_);
+
+ oprot_->writeMessageEnd();
+ oprot_->getTransport()->writeEnd();
+ oprot_->getTransport()->flush();
+
+ sentry.commit();
+}
+
+}}} // namespace
+
diff --git a/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/thrift-gen/Agent.h b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/thrift-gen/Agent.h
new file mode 100644
index 000000000..daa567896
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/thrift-gen/Agent.h
@@ -0,0 +1,306 @@
+/**
+ * Autogenerated by Thrift Compiler (0.11.0)
+ *
+ * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
+ * @generated
+ */
+#ifndef Agent_H
+#define Agent_H
+
+#include <thrift/TDispatchProcessor.h>
+#include <thrift/async/TConcurrentClientSyncInfo.h>
+#include "agent_types.h"
+
+namespace jaegertracing { namespace agent { namespace thrift {
+
+#ifdef _MSC_VER
+ #pragma warning( push )
+ #pragma warning (disable : 4250 ) //inheriting methods via dominance
+#endif
+
+class AgentIf {
+ public:
+ virtual ~AgentIf() {}
+ virtual void emitZipkinBatch(const std::vector< ::twitter::zipkin::thrift::Span> & spans) = 0;
+ virtual void emitBatch(const ::jaegertracing::thrift::Batch& batch) = 0;
+};
+
+class AgentIfFactory {
+ public:
+ typedef AgentIf Handler;
+
+ virtual ~AgentIfFactory() {}
+
+ virtual AgentIf* getHandler(const ::apache::thrift::TConnectionInfo& connInfo) = 0;
+ virtual void releaseHandler(AgentIf* /* handler */) = 0;
+};
+
+class AgentIfSingletonFactory : virtual public AgentIfFactory {
+ public:
+ AgentIfSingletonFactory(const ::std::shared_ptr<AgentIf>& iface) : iface_(iface) {}
+ virtual ~AgentIfSingletonFactory() {}
+
+ virtual AgentIf* getHandler(const ::apache::thrift::TConnectionInfo&) {
+ return iface_.get();
+ }
+ virtual void releaseHandler(AgentIf* /* handler */) {}
+
+ protected:
+ ::std::shared_ptr<AgentIf> iface_;
+};
+
+class AgentNull : virtual public AgentIf {
+ public:
+ virtual ~AgentNull() {}
+ void emitZipkinBatch(const std::vector< ::twitter::zipkin::thrift::Span> & /* spans */) {
+ return;
+ }
+ void emitBatch(const ::jaegertracing::thrift::Batch& /* batch */) {
+ return;
+ }
+};
+
+typedef struct _Agent_emitZipkinBatch_args__isset {
+ _Agent_emitZipkinBatch_args__isset() : spans(false) {}
+ bool spans :1;
+} _Agent_emitZipkinBatch_args__isset;
+
+class Agent_emitZipkinBatch_args {
+ public:
+
+ Agent_emitZipkinBatch_args(const Agent_emitZipkinBatch_args&);
+ Agent_emitZipkinBatch_args& operator=(const Agent_emitZipkinBatch_args&);
+ Agent_emitZipkinBatch_args() {
+ }
+
+ virtual ~Agent_emitZipkinBatch_args() throw();
+ std::vector< ::twitter::zipkin::thrift::Span> spans;
+
+ _Agent_emitZipkinBatch_args__isset __isset;
+
+ void __set_spans(const std::vector< ::twitter::zipkin::thrift::Span> & val);
+
+ bool operator == (const Agent_emitZipkinBatch_args & rhs) const
+ {
+ if (!(spans == rhs.spans))
+ return false;
+ return true;
+ }
+ bool operator != (const Agent_emitZipkinBatch_args &rhs) const {
+ return !(*this == rhs);
+ }
+
+ bool operator < (const Agent_emitZipkinBatch_args & ) const;
+
+ uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
+ uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;
+
+};
+
+
+class Agent_emitZipkinBatch_pargs {
+ public:
+
+
+ virtual ~Agent_emitZipkinBatch_pargs() throw();
+ const std::vector< ::twitter::zipkin::thrift::Span> * spans;
+
+ uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;
+
+};
+
+typedef struct _Agent_emitBatch_args__isset {
+ _Agent_emitBatch_args__isset() : batch(false) {}
+ bool batch :1;
+} _Agent_emitBatch_args__isset;
+
+class Agent_emitBatch_args {
+ public:
+
+ Agent_emitBatch_args(const Agent_emitBatch_args&);
+ Agent_emitBatch_args& operator=(const Agent_emitBatch_args&);
+ Agent_emitBatch_args() {
+ }
+
+ virtual ~Agent_emitBatch_args() throw();
+ ::jaegertracing::thrift::Batch batch;
+
+ _Agent_emitBatch_args__isset __isset;
+
+ void __set_batch(const ::jaegertracing::thrift::Batch& val);
+
+ bool operator == (const Agent_emitBatch_args & rhs) const
+ {
+ if (!(batch == rhs.batch))
+ return false;
+ return true;
+ }
+ bool operator != (const Agent_emitBatch_args &rhs) const {
+ return !(*this == rhs);
+ }
+
+ bool operator < (const Agent_emitBatch_args & ) const;
+
+ uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
+ uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;
+
+};
+
+
+class Agent_emitBatch_pargs {
+ public:
+
+
+ virtual ~Agent_emitBatch_pargs() throw();
+ const ::jaegertracing::thrift::Batch* batch;
+
+ uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;
+
+};
+
+class AgentClient : virtual public AgentIf {
+ public:
+ AgentClient(std::shared_ptr< ::apache::thrift::protocol::TProtocol> prot) {
+ setProtocol(prot);
+ }
+ AgentClient(std::shared_ptr< ::apache::thrift::protocol::TProtocol> iprot, std::shared_ptr< ::apache::thrift::protocol::TProtocol> oprot) {
+ setProtocol(iprot,oprot);
+ }
+ private:
+ void setProtocol(std::shared_ptr< ::apache::thrift::protocol::TProtocol> prot) {
+ setProtocol(prot,prot);
+ }
+ void setProtocol(std::shared_ptr< ::apache::thrift::protocol::TProtocol> iprot, std::shared_ptr< ::apache::thrift::protocol::TProtocol> oprot) {
+ piprot_=iprot;
+ poprot_=oprot;
+ iprot_ = iprot.get();
+ oprot_ = oprot.get();
+ }
+ public:
+ std::shared_ptr< ::apache::thrift::protocol::TProtocol> getInputProtocol() {
+ return piprot_;
+ }
+ std::shared_ptr< ::apache::thrift::protocol::TProtocol> getOutputProtocol() {
+ return poprot_;
+ }
+ void emitZipkinBatch(const std::vector< ::twitter::zipkin::thrift::Span> & spans);
+ void send_emitZipkinBatch(const std::vector< ::twitter::zipkin::thrift::Span> & spans);
+ void emitBatch(const ::jaegertracing::thrift::Batch& batch);
+ void send_emitBatch(const ::jaegertracing::thrift::Batch& batch);
+ protected:
+ std::shared_ptr< ::apache::thrift::protocol::TProtocol> piprot_;
+ std::shared_ptr< ::apache::thrift::protocol::TProtocol> poprot_;
+ ::apache::thrift::protocol::TProtocol* iprot_;
+ ::apache::thrift::protocol::TProtocol* oprot_;
+};
+
+class AgentProcessor : public ::apache::thrift::TDispatchProcessor {
+ protected:
+ ::std::shared_ptr<AgentIf> iface_;
+ virtual bool dispatchCall(::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, const std::string& fname, int32_t seqid, void* callContext);
+ private:
+ typedef void (AgentProcessor::*ProcessFunction)(int32_t, ::apache::thrift::protocol::TProtocol*, ::apache::thrift::protocol::TProtocol*, void*);
+ typedef std::map<std::string, ProcessFunction> ProcessMap;
+ ProcessMap processMap_;
+ void process_emitZipkinBatch(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext);
+ void process_emitBatch(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext);
+ public:
+ AgentProcessor(::std::shared_ptr<AgentIf> iface) :
+ iface_(iface) {
+ processMap_["emitZipkinBatch"] = &AgentProcessor::process_emitZipkinBatch;
+ processMap_["emitBatch"] = &AgentProcessor::process_emitBatch;
+ }
+
+ virtual ~AgentProcessor() {}
+};
+
+class AgentProcessorFactory : public ::apache::thrift::TProcessorFactory {
+ public:
+ AgentProcessorFactory(const ::std::shared_ptr< AgentIfFactory >& handlerFactory) :
+ handlerFactory_(handlerFactory) {}
+
+ ::std::shared_ptr< ::apache::thrift::TProcessor > getProcessor(const ::apache::thrift::TConnectionInfo& connInfo);
+
+ protected:
+ ::std::shared_ptr< AgentIfFactory > handlerFactory_;
+};
+
+class AgentMultiface : virtual public AgentIf {
+ public:
+ AgentMultiface(std::vector<std::shared_ptr<AgentIf> >& ifaces) : ifaces_(ifaces) {
+ }
+ virtual ~AgentMultiface() {}
+ protected:
+ std::vector<std::shared_ptr<AgentIf> > ifaces_;
+ AgentMultiface() {}
+ void add(::std::shared_ptr<AgentIf> iface) {
+ ifaces_.push_back(iface);
+ }
+ public:
+ void emitZipkinBatch(const std::vector< ::twitter::zipkin::thrift::Span> & spans) {
+ size_t sz = ifaces_.size();
+ size_t i = 0;
+ for (; i < (sz - 1); ++i) {
+ ifaces_[i]->emitZipkinBatch(spans);
+ }
+ ifaces_[i]->emitZipkinBatch(spans);
+ }
+
+ void emitBatch(const ::jaegertracing::thrift::Batch& batch) {
+ size_t sz = ifaces_.size();
+ size_t i = 0;
+ for (; i < (sz - 1); ++i) {
+ ifaces_[i]->emitBatch(batch);
+ }
+ ifaces_[i]->emitBatch(batch);
+ }
+
+};
+
+// The 'concurrent' client is a thread safe client that correctly handles
+// out of order responses. It is slower than the regular client, so should
+// only be used when you need to share a connection among multiple threads
+class AgentConcurrentClient : virtual public AgentIf {
+ public:
+ AgentConcurrentClient(std::shared_ptr< ::apache::thrift::protocol::TProtocol> prot) {
+ setProtocol(prot);
+ }
+ AgentConcurrentClient(std::shared_ptr< ::apache::thrift::protocol::TProtocol> iprot, std::shared_ptr< ::apache::thrift::protocol::TProtocol> oprot) {
+ setProtocol(iprot,oprot);
+ }
+ private:
+ void setProtocol(std::shared_ptr< ::apache::thrift::protocol::TProtocol> prot) {
+ setProtocol(prot,prot);
+ }
+ void setProtocol(std::shared_ptr< ::apache::thrift::protocol::TProtocol> iprot, std::shared_ptr< ::apache::thrift::protocol::TProtocol> oprot) {
+ piprot_=iprot;
+ poprot_=oprot;
+ iprot_ = iprot.get();
+ oprot_ = oprot.get();
+ }
+ public:
+ std::shared_ptr< ::apache::thrift::protocol::TProtocol> getInputProtocol() {
+ return piprot_;
+ }
+ std::shared_ptr< ::apache::thrift::protocol::TProtocol> getOutputProtocol() {
+ return poprot_;
+ }
+ void emitZipkinBatch(const std::vector< ::twitter::zipkin::thrift::Span> & spans);
+ void send_emitZipkinBatch(const std::vector< ::twitter::zipkin::thrift::Span> & spans);
+ void emitBatch(const ::jaegertracing::thrift::Batch& batch);
+ void send_emitBatch(const ::jaegertracing::thrift::Batch& batch);
+ protected:
+ std::shared_ptr< ::apache::thrift::protocol::TProtocol> piprot_;
+ std::shared_ptr< ::apache::thrift::protocol::TProtocol> poprot_;
+ ::apache::thrift::protocol::TProtocol* iprot_;
+ ::apache::thrift::protocol::TProtocol* oprot_;
+ ::apache::thrift::async::TConcurrentClientSyncInfo sync_;
+};
+
+#ifdef _MSC_VER
+ #pragma warning( pop )
+#endif
+
+}}} // namespace
+
+#endif
diff --git a/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/thrift-gen/AggregationValidator.cpp b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/thrift-gen/AggregationValidator.cpp
new file mode 100644
index 000000000..516ef9a28
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/thrift-gen/AggregationValidator.cpp
@@ -0,0 +1,424 @@
+/**
+ * Autogenerated by Thrift Compiler (0.11.0)
+ *
+ * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
+ * @generated
+ */
+#include "AggregationValidator.h"
+
+namespace jaegertracing { namespace thrift {
+
+
+AggregationValidator_validateTrace_args::~AggregationValidator_validateTrace_args() throw() {
+}
+
+
+uint32_t AggregationValidator_validateTrace_args::read(::apache::thrift::protocol::TProtocol* iprot) {
+
+ ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
+ uint32_t xfer = 0;
+ std::string fname;
+ ::apache::thrift::protocol::TType ftype;
+ int16_t fid;
+
+ xfer += iprot->readStructBegin(fname);
+
+ using ::apache::thrift::protocol::TProtocolException;
+
+ bool isset_traceId = false;
+
+ while (true)
+ {
+ xfer += iprot->readFieldBegin(fname, ftype, fid);
+ if (ftype == ::apache::thrift::protocol::T_STOP) {
+ break;
+ }
+ switch (fid)
+ {
+ case 1:
+ if (ftype == ::apache::thrift::protocol::T_STRING) {
+ xfer += iprot->readString(this->traceId);
+ isset_traceId = true;
+ } else {
+ xfer += iprot->skip(ftype);
+ }
+ break;
+ default:
+ xfer += iprot->skip(ftype);
+ break;
+ }
+ xfer += iprot->readFieldEnd();
+ }
+
+ xfer += iprot->readStructEnd();
+
+ if (!isset_traceId)
+ throw TProtocolException(TProtocolException::INVALID_DATA);
+ return xfer;
+}
+
+uint32_t AggregationValidator_validateTrace_args::write(::apache::thrift::protocol::TProtocol* oprot) const {
+ uint32_t xfer = 0;
+ ::apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
+ xfer += oprot->writeStructBegin("AggregationValidator_validateTrace_args");
+
+ xfer += oprot->writeFieldBegin("traceId", ::apache::thrift::protocol::T_STRING, 1);
+ xfer += oprot->writeString(this->traceId);
+ xfer += oprot->writeFieldEnd();
+
+ xfer += oprot->writeFieldStop();
+ xfer += oprot->writeStructEnd();
+ return xfer;
+}
+
+
+AggregationValidator_validateTrace_pargs::~AggregationValidator_validateTrace_pargs() throw() {
+}
+
+
+uint32_t AggregationValidator_validateTrace_pargs::write(::apache::thrift::protocol::TProtocol* oprot) const {
+ uint32_t xfer = 0;
+ ::apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
+ xfer += oprot->writeStructBegin("AggregationValidator_validateTrace_pargs");
+
+ xfer += oprot->writeFieldBegin("traceId", ::apache::thrift::protocol::T_STRING, 1);
+ xfer += oprot->writeString((*(this->traceId)));
+ xfer += oprot->writeFieldEnd();
+
+ xfer += oprot->writeFieldStop();
+ xfer += oprot->writeStructEnd();
+ return xfer;
+}
+
+
+AggregationValidator_validateTrace_result::~AggregationValidator_validateTrace_result() throw() {
+}
+
+
+uint32_t AggregationValidator_validateTrace_result::read(::apache::thrift::protocol::TProtocol* iprot) {
+
+ ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
+ uint32_t xfer = 0;
+ std::string fname;
+ ::apache::thrift::protocol::TType ftype;
+ int16_t fid;
+
+ xfer += iprot->readStructBegin(fname);
+
+ using ::apache::thrift::protocol::TProtocolException;
+
+
+ while (true)
+ {
+ xfer += iprot->readFieldBegin(fname, ftype, fid);
+ if (ftype == ::apache::thrift::protocol::T_STOP) {
+ break;
+ }
+ switch (fid)
+ {
+ case 0:
+ if (ftype == ::apache::thrift::protocol::T_STRUCT) {
+ xfer += this->success.read(iprot);
+ this->__isset.success = true;
+ } else {
+ xfer += iprot->skip(ftype);
+ }
+ break;
+ default:
+ xfer += iprot->skip(ftype);
+ break;
+ }
+ xfer += iprot->readFieldEnd();
+ }
+
+ xfer += iprot->readStructEnd();
+
+ return xfer;
+}
+
+uint32_t AggregationValidator_validateTrace_result::write(::apache::thrift::protocol::TProtocol* oprot) const {
+
+ uint32_t xfer = 0;
+
+ xfer += oprot->writeStructBegin("AggregationValidator_validateTrace_result");
+
+ if (this->__isset.success) {
+ xfer += oprot->writeFieldBegin("success", ::apache::thrift::protocol::T_STRUCT, 0);
+ xfer += this->success.write(oprot);
+ xfer += oprot->writeFieldEnd();
+ }
+ xfer += oprot->writeFieldStop();
+ xfer += oprot->writeStructEnd();
+ return xfer;
+}
+
+
+AggregationValidator_validateTrace_presult::~AggregationValidator_validateTrace_presult() throw() {
+}
+
+
+uint32_t AggregationValidator_validateTrace_presult::read(::apache::thrift::protocol::TProtocol* iprot) {
+
+ ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
+ uint32_t xfer = 0;
+ std::string fname;
+ ::apache::thrift::protocol::TType ftype;
+ int16_t fid;
+
+ xfer += iprot->readStructBegin(fname);
+
+ using ::apache::thrift::protocol::TProtocolException;
+
+
+ while (true)
+ {
+ xfer += iprot->readFieldBegin(fname, ftype, fid);
+ if (ftype == ::apache::thrift::protocol::T_STOP) {
+ break;
+ }
+ switch (fid)
+ {
+ case 0:
+ if (ftype == ::apache::thrift::protocol::T_STRUCT) {
+ xfer += (*(this->success)).read(iprot);
+ this->__isset.success = true;
+ } else {
+ xfer += iprot->skip(ftype);
+ }
+ break;
+ default:
+ xfer += iprot->skip(ftype);
+ break;
+ }
+ xfer += iprot->readFieldEnd();
+ }
+
+ xfer += iprot->readStructEnd();
+
+ return xfer;
+}
+
+void AggregationValidatorClient::validateTrace(ValidateTraceResponse& _return, const std::string& traceId)
+{
+ send_validateTrace(traceId);
+ recv_validateTrace(_return);
+}
+
+void AggregationValidatorClient::send_validateTrace(const std::string& traceId)
+{
+ int32_t cseqid = 0;
+ oprot_->writeMessageBegin("validateTrace", ::apache::thrift::protocol::T_CALL, cseqid);
+
+ AggregationValidator_validateTrace_pargs args;
+ args.traceId = &traceId;
+ args.write(oprot_);
+
+ oprot_->writeMessageEnd();
+ oprot_->getTransport()->writeEnd();
+ oprot_->getTransport()->flush();
+}
+
+void AggregationValidatorClient::recv_validateTrace(ValidateTraceResponse& _return)
+{
+
+ int32_t rseqid = 0;
+ std::string fname;
+ ::apache::thrift::protocol::TMessageType mtype;
+
+ iprot_->readMessageBegin(fname, mtype, rseqid);
+ if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
+ ::apache::thrift::TApplicationException x;
+ x.read(iprot_);
+ iprot_->readMessageEnd();
+ iprot_->getTransport()->readEnd();
+ throw x;
+ }
+ if (mtype != ::apache::thrift::protocol::T_REPLY) {
+ iprot_->skip(::apache::thrift::protocol::T_STRUCT);
+ iprot_->readMessageEnd();
+ iprot_->getTransport()->readEnd();
+ }
+ if (fname.compare("validateTrace") != 0) {
+ iprot_->skip(::apache::thrift::protocol::T_STRUCT);
+ iprot_->readMessageEnd();
+ iprot_->getTransport()->readEnd();
+ }
+ AggregationValidator_validateTrace_presult result;
+ result.success = &_return;
+ result.read(iprot_);
+ iprot_->readMessageEnd();
+ iprot_->getTransport()->readEnd();
+
+ if (result.__isset.success) {
+ // _return pointer has now been filled
+ return;
+ }
+ throw ::apache::thrift::TApplicationException(::apache::thrift::TApplicationException::MISSING_RESULT, "validateTrace failed: unknown result");
+}
+
+bool AggregationValidatorProcessor::dispatchCall(::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, const std::string& fname, int32_t seqid, void* callContext) {
+ ProcessMap::iterator pfn;
+ pfn = processMap_.find(fname);
+ if (pfn == processMap_.end()) {
+ iprot->skip(::apache::thrift::protocol::T_STRUCT);
+ iprot->readMessageEnd();
+ iprot->getTransport()->readEnd();
+ ::apache::thrift::TApplicationException x(::apache::thrift::TApplicationException::UNKNOWN_METHOD, "Invalid method name: '"+fname+"'");
+ oprot->writeMessageBegin(fname, ::apache::thrift::protocol::T_EXCEPTION, seqid);
+ x.write(oprot);
+ oprot->writeMessageEnd();
+ oprot->getTransport()->writeEnd();
+ oprot->getTransport()->flush();
+ return true;
+ }
+ (this->*(pfn->second))(seqid, iprot, oprot, callContext);
+ return true;
+}
+
+void AggregationValidatorProcessor::process_validateTrace(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext)
+{
+ void* ctx = NULL;
+ if (this->eventHandler_.get() != NULL) {
+ ctx = this->eventHandler_->getContext("AggregationValidator.validateTrace", callContext);
+ }
+ ::apache::thrift::TProcessorContextFreer freer(this->eventHandler_.get(), ctx, "AggregationValidator.validateTrace");
+
+ if (this->eventHandler_.get() != NULL) {
+ this->eventHandler_->preRead(ctx, "AggregationValidator.validateTrace");
+ }
+
+ AggregationValidator_validateTrace_args args;
+ args.read(iprot);
+ iprot->readMessageEnd();
+ uint32_t bytes = iprot->getTransport()->readEnd();
+
+ if (this->eventHandler_.get() != NULL) {
+ this->eventHandler_->postRead(ctx, "AggregationValidator.validateTrace", bytes);
+ }
+
+ AggregationValidator_validateTrace_result result;
+ try {
+ iface_->validateTrace(result.success, args.traceId);
+ result.__isset.success = true;
+ } catch (const std::exception& e) {
+ if (this->eventHandler_.get() != NULL) {
+ this->eventHandler_->handlerError(ctx, "AggregationValidator.validateTrace");
+ }
+
+ ::apache::thrift::TApplicationException x(e.what());
+ oprot->writeMessageBegin("validateTrace", ::apache::thrift::protocol::T_EXCEPTION, seqid);
+ x.write(oprot);
+ oprot->writeMessageEnd();
+ oprot->getTransport()->writeEnd();
+ oprot->getTransport()->flush();
+ return;
+ }
+
+ if (this->eventHandler_.get() != NULL) {
+ this->eventHandler_->preWrite(ctx, "AggregationValidator.validateTrace");
+ }
+
+ oprot->writeMessageBegin("validateTrace", ::apache::thrift::protocol::T_REPLY, seqid);
+ result.write(oprot);
+ oprot->writeMessageEnd();
+ bytes = oprot->getTransport()->writeEnd();
+ oprot->getTransport()->flush();
+
+ if (this->eventHandler_.get() != NULL) {
+ this->eventHandler_->postWrite(ctx, "AggregationValidator.validateTrace", bytes);
+ }
+}
+
+::std::shared_ptr< ::apache::thrift::TProcessor > AggregationValidatorProcessorFactory::getProcessor(const ::apache::thrift::TConnectionInfo& connInfo) {
+ ::apache::thrift::ReleaseHandler< AggregationValidatorIfFactory > cleanup(handlerFactory_);
+ ::std::shared_ptr< AggregationValidatorIf > handler(handlerFactory_->getHandler(connInfo), cleanup);
+ ::std::shared_ptr< ::apache::thrift::TProcessor > processor(new AggregationValidatorProcessor(handler));
+ return processor;
+}
+
+void AggregationValidatorConcurrentClient::validateTrace(ValidateTraceResponse& _return, const std::string& traceId)
+{
+ int32_t seqid = send_validateTrace(traceId);
+ recv_validateTrace(_return, seqid);
+}
+
+int32_t AggregationValidatorConcurrentClient::send_validateTrace(const std::string& traceId)
+{
+ int32_t cseqid = this->sync_.generateSeqId();
+ ::apache::thrift::async::TConcurrentSendSentry sentry(&this->sync_);
+ oprot_->writeMessageBegin("validateTrace", ::apache::thrift::protocol::T_CALL, cseqid);
+
+ AggregationValidator_validateTrace_pargs args;
+ args.traceId = &traceId;
+ args.write(oprot_);
+
+ oprot_->writeMessageEnd();
+ oprot_->getTransport()->writeEnd();
+ oprot_->getTransport()->flush();
+
+ sentry.commit();
+ return cseqid;
+}
+
+void AggregationValidatorConcurrentClient::recv_validateTrace(ValidateTraceResponse& _return, const int32_t seqid)
+{
+
+ int32_t rseqid = 0;
+ std::string fname;
+ ::apache::thrift::protocol::TMessageType mtype;
+
+ // the read mutex gets dropped and reacquired as part of waitForWork()
+ // The destructor of this sentry wakes up other clients
+ ::apache::thrift::async::TConcurrentRecvSentry sentry(&this->sync_, seqid);
+
+ while(true) {
+ if(!this->sync_.getPending(fname, mtype, rseqid)) {
+ iprot_->readMessageBegin(fname, mtype, rseqid);
+ }
+ if(seqid == rseqid) {
+ if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
+ ::apache::thrift::TApplicationException x;
+ x.read(iprot_);
+ iprot_->readMessageEnd();
+ iprot_->getTransport()->readEnd();
+ sentry.commit();
+ throw x;
+ }
+ if (mtype != ::apache::thrift::protocol::T_REPLY) {
+ iprot_->skip(::apache::thrift::protocol::T_STRUCT);
+ iprot_->readMessageEnd();
+ iprot_->getTransport()->readEnd();
+ }
+ if (fname.compare("validateTrace") != 0) {
+ iprot_->skip(::apache::thrift::protocol::T_STRUCT);
+ iprot_->readMessageEnd();
+ iprot_->getTransport()->readEnd();
+
+ // in a bad state, don't commit
+ using ::apache::thrift::protocol::TProtocolException;
+ throw TProtocolException(TProtocolException::INVALID_DATA);
+ }
+ AggregationValidator_validateTrace_presult result;
+ result.success = &_return;
+ result.read(iprot_);
+ iprot_->readMessageEnd();
+ iprot_->getTransport()->readEnd();
+
+ if (result.__isset.success) {
+ // _return pointer has now been filled
+ sentry.commit();
+ return;
+ }
+ // in a bad state, don't commit
+ throw ::apache::thrift::TApplicationException(::apache::thrift::TApplicationException::MISSING_RESULT, "validateTrace failed: unknown result");
+ }
+ // seqid != rseqid
+ this->sync_.updatePending(fname, mtype, rseqid);
+
+ // this will temporarily unlock the readMutex, and let other clients get work done
+ this->sync_.waitForWork(seqid);
+ } // end while(true)
+}
+
+}} // namespace
+
diff --git a/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/thrift-gen/AggregationValidator.h b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/thrift-gen/AggregationValidator.h
new file mode 100644
index 000000000..5510ecfac
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/thrift-gen/AggregationValidator.h
@@ -0,0 +1,290 @@
+/**
+ * Autogenerated by Thrift Compiler (0.11.0)
+ *
+ * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
+ * @generated
+ */
+#ifndef AggregationValidator_H
+#define AggregationValidator_H
+
+#include <thrift/TDispatchProcessor.h>
+#include <thrift/async/TConcurrentClientSyncInfo.h>
+#include "aggregation_validator_types.h"
+
+namespace jaegertracing { namespace thrift {
+
+#ifdef _MSC_VER
+ #pragma warning( push )
+ #pragma warning (disable : 4250 ) //inheriting methods via dominance
+#endif
+
+class AggregationValidatorIf {
+ public:
+ virtual ~AggregationValidatorIf() {}
+ virtual void validateTrace(ValidateTraceResponse& _return, const std::string& traceId) = 0;
+};
+
+class AggregationValidatorIfFactory {
+ public:
+ typedef AggregationValidatorIf Handler;
+
+ virtual ~AggregationValidatorIfFactory() {}
+
+ virtual AggregationValidatorIf* getHandler(const ::apache::thrift::TConnectionInfo& connInfo) = 0;
+ virtual void releaseHandler(AggregationValidatorIf* /* handler */) = 0;
+};
+
+class AggregationValidatorIfSingletonFactory : virtual public AggregationValidatorIfFactory {
+ public:
+ AggregationValidatorIfSingletonFactory(const ::std::shared_ptr<AggregationValidatorIf>& iface) : iface_(iface) {}
+ virtual ~AggregationValidatorIfSingletonFactory() {}
+
+ virtual AggregationValidatorIf* getHandler(const ::apache::thrift::TConnectionInfo&) {
+ return iface_.get();
+ }
+ virtual void releaseHandler(AggregationValidatorIf* /* handler */) {}
+
+ protected:
+ ::std::shared_ptr<AggregationValidatorIf> iface_;
+};
+
+class AggregationValidatorNull : virtual public AggregationValidatorIf {
+ public:
+ virtual ~AggregationValidatorNull() {}
+ void validateTrace(ValidateTraceResponse& /* _return */, const std::string& /* traceId */) {
+ return;
+ }
+};
+
+
+class AggregationValidator_validateTrace_args {
+ public:
+
+ AggregationValidator_validateTrace_args(const AggregationValidator_validateTrace_args&);
+ AggregationValidator_validateTrace_args& operator=(const AggregationValidator_validateTrace_args&);
+ AggregationValidator_validateTrace_args() : traceId() {
+ }
+
+ virtual ~AggregationValidator_validateTrace_args() throw();
+ std::string traceId;
+
+ void __set_traceId(const std::string& val);
+
+ bool operator == (const AggregationValidator_validateTrace_args & rhs) const
+ {
+ if (!(traceId == rhs.traceId))
+ return false;
+ return true;
+ }
+ bool operator != (const AggregationValidator_validateTrace_args &rhs) const {
+ return !(*this == rhs);
+ }
+
+ bool operator < (const AggregationValidator_validateTrace_args & ) const;
+
+ uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
+ uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;
+
+};
+
+
+class AggregationValidator_validateTrace_pargs {
+ public:
+
+
+ virtual ~AggregationValidator_validateTrace_pargs() throw();
+ const std::string* traceId;
+
+ uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;
+
+};
+
+typedef struct _AggregationValidator_validateTrace_result__isset {
+ _AggregationValidator_validateTrace_result__isset() : success(false) {}
+ bool success :1;
+} _AggregationValidator_validateTrace_result__isset;
+
+class AggregationValidator_validateTrace_result {
+ public:
+
+ AggregationValidator_validateTrace_result(const AggregationValidator_validateTrace_result&);
+ AggregationValidator_validateTrace_result& operator=(const AggregationValidator_validateTrace_result&);
+ AggregationValidator_validateTrace_result() {
+ }
+
+ virtual ~AggregationValidator_validateTrace_result() throw();
+ ValidateTraceResponse success;
+
+ _AggregationValidator_validateTrace_result__isset __isset;
+
+ void __set_success(const ValidateTraceResponse& val);
+
+ bool operator == (const AggregationValidator_validateTrace_result & rhs) const
+ {
+ if (!(success == rhs.success))
+ return false;
+ return true;
+ }
+ bool operator != (const AggregationValidator_validateTrace_result &rhs) const {
+ return !(*this == rhs);
+ }
+
+ bool operator < (const AggregationValidator_validateTrace_result & ) const;
+
+ uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
+ uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;
+
+};
+
+typedef struct _AggregationValidator_validateTrace_presult__isset {
+ _AggregationValidator_validateTrace_presult__isset() : success(false) {}
+ bool success :1;
+} _AggregationValidator_validateTrace_presult__isset;
+
+class AggregationValidator_validateTrace_presult {
+ public:
+
+
+ virtual ~AggregationValidator_validateTrace_presult() throw();
+ ValidateTraceResponse* success;
+
+ _AggregationValidator_validateTrace_presult__isset __isset;
+
+ uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
+
+};
+
+class AggregationValidatorClient : virtual public AggregationValidatorIf {
+ public:
+ AggregationValidatorClient(std::shared_ptr< ::apache::thrift::protocol::TProtocol> prot) {
+ setProtocol(prot);
+ }
+ AggregationValidatorClient(std::shared_ptr< ::apache::thrift::protocol::TProtocol> iprot, std::shared_ptr< ::apache::thrift::protocol::TProtocol> oprot) {
+ setProtocol(iprot,oprot);
+ }
+ private:
+ void setProtocol(std::shared_ptr< ::apache::thrift::protocol::TProtocol> prot) {
+ setProtocol(prot,prot);
+ }
+ void setProtocol(std::shared_ptr< ::apache::thrift::protocol::TProtocol> iprot, std::shared_ptr< ::apache::thrift::protocol::TProtocol> oprot) {
+ piprot_=iprot;
+ poprot_=oprot;
+ iprot_ = iprot.get();
+ oprot_ = oprot.get();
+ }
+ public:
+ std::shared_ptr< ::apache::thrift::protocol::TProtocol> getInputProtocol() {
+ return piprot_;
+ }
+ std::shared_ptr< ::apache::thrift::protocol::TProtocol> getOutputProtocol() {
+ return poprot_;
+ }
+ void validateTrace(ValidateTraceResponse& _return, const std::string& traceId);
+ void send_validateTrace(const std::string& traceId);
+ void recv_validateTrace(ValidateTraceResponse& _return);
+ protected:
+ std::shared_ptr< ::apache::thrift::protocol::TProtocol> piprot_;
+ std::shared_ptr< ::apache::thrift::protocol::TProtocol> poprot_;
+ ::apache::thrift::protocol::TProtocol* iprot_;
+ ::apache::thrift::protocol::TProtocol* oprot_;
+};
+
+class AggregationValidatorProcessor : public ::apache::thrift::TDispatchProcessor {
+ protected:
+ ::std::shared_ptr<AggregationValidatorIf> iface_;
+ virtual bool dispatchCall(::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, const std::string& fname, int32_t seqid, void* callContext);
+ private:
+ typedef void (AggregationValidatorProcessor::*ProcessFunction)(int32_t, ::apache::thrift::protocol::TProtocol*, ::apache::thrift::protocol::TProtocol*, void*);
+ typedef std::map<std::string, ProcessFunction> ProcessMap;
+ ProcessMap processMap_;
+ void process_validateTrace(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext);
+ public:
+ AggregationValidatorProcessor(::std::shared_ptr<AggregationValidatorIf> iface) :
+ iface_(iface) {
+ processMap_["validateTrace"] = &AggregationValidatorProcessor::process_validateTrace;
+ }
+
+ virtual ~AggregationValidatorProcessor() {}
+};
+
+class AggregationValidatorProcessorFactory : public ::apache::thrift::TProcessorFactory {
+ public:
+ AggregationValidatorProcessorFactory(const ::std::shared_ptr< AggregationValidatorIfFactory >& handlerFactory) :
+ handlerFactory_(handlerFactory) {}
+
+ ::std::shared_ptr< ::apache::thrift::TProcessor > getProcessor(const ::apache::thrift::TConnectionInfo& connInfo);
+
+ protected:
+ ::std::shared_ptr< AggregationValidatorIfFactory > handlerFactory_;
+};
+
+class AggregationValidatorMultiface : virtual public AggregationValidatorIf {
+ public:
+ AggregationValidatorMultiface(std::vector<std::shared_ptr<AggregationValidatorIf> >& ifaces) : ifaces_(ifaces) {
+ }
+ virtual ~AggregationValidatorMultiface() {}
+ protected:
+ std::vector<std::shared_ptr<AggregationValidatorIf> > ifaces_;
+ AggregationValidatorMultiface() {}
+ void add(::std::shared_ptr<AggregationValidatorIf> iface) {
+ ifaces_.push_back(iface);
+ }
+ public:
+ void validateTrace(ValidateTraceResponse& _return, const std::string& traceId) {
+ size_t sz = ifaces_.size();
+ size_t i = 0;
+ for (; i < (sz - 1); ++i) {
+ ifaces_[i]->validateTrace(_return, traceId);
+ }
+ ifaces_[i]->validateTrace(_return, traceId);
+ return;
+ }
+
+};
+
+// The 'concurrent' client is a thread safe client that correctly handles
+// out of order responses. It is slower than the regular client, so should
+// only be used when you need to share a connection among multiple threads
+class AggregationValidatorConcurrentClient : virtual public AggregationValidatorIf {
+ public:
+ AggregationValidatorConcurrentClient(std::shared_ptr< ::apache::thrift::protocol::TProtocol> prot) {
+ setProtocol(prot);
+ }
+ AggregationValidatorConcurrentClient(std::shared_ptr< ::apache::thrift::protocol::TProtocol> iprot, std::shared_ptr< ::apache::thrift::protocol::TProtocol> oprot) {
+ setProtocol(iprot,oprot);
+ }
+ private:
+ void setProtocol(std::shared_ptr< ::apache::thrift::protocol::TProtocol> prot) {
+ setProtocol(prot,prot);
+ }
+ void setProtocol(std::shared_ptr< ::apache::thrift::protocol::TProtocol> iprot, std::shared_ptr< ::apache::thrift::protocol::TProtocol> oprot) {
+ piprot_=iprot;
+ poprot_=oprot;
+ iprot_ = iprot.get();
+ oprot_ = oprot.get();
+ }
+ public:
+ std::shared_ptr< ::apache::thrift::protocol::TProtocol> getInputProtocol() {
+ return piprot_;
+ }
+ std::shared_ptr< ::apache::thrift::protocol::TProtocol> getOutputProtocol() {
+ return poprot_;
+ }
+ void validateTrace(ValidateTraceResponse& _return, const std::string& traceId);
+ int32_t send_validateTrace(const std::string& traceId);
+ void recv_validateTrace(ValidateTraceResponse& _return, const int32_t seqid);
+ protected:
+ std::shared_ptr< ::apache::thrift::protocol::TProtocol> piprot_;
+ std::shared_ptr< ::apache::thrift::protocol::TProtocol> poprot_;
+ ::apache::thrift::protocol::TProtocol* iprot_;
+ ::apache::thrift::protocol::TProtocol* oprot_;
+ ::apache::thrift::async::TConcurrentClientSyncInfo sync_;
+};
+
+#ifdef _MSC_VER
+ #pragma warning( pop )
+#endif
+
+}} // namespace
+
+#endif
diff --git a/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/thrift-gen/BaggageRestrictionManager.cpp b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/thrift-gen/BaggageRestrictionManager.cpp
new file mode 100644
index 000000000..b929fbbd3
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/thrift-gen/BaggageRestrictionManager.cpp
@@ -0,0 +1,453 @@
+/**
+ * Autogenerated by Thrift Compiler (0.11.0)
+ *
+ * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
+ * @generated
+ */
+#include "BaggageRestrictionManager.h"
+
+namespace jaegertracing { namespace thrift {
+
+
+BaggageRestrictionManager_getBaggageRestrictions_args::~BaggageRestrictionManager_getBaggageRestrictions_args() throw() {
+}
+
+
+uint32_t BaggageRestrictionManager_getBaggageRestrictions_args::read(::apache::thrift::protocol::TProtocol* iprot) {
+
+ ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
+ uint32_t xfer = 0;
+ std::string fname;
+ ::apache::thrift::protocol::TType ftype;
+ int16_t fid;
+
+ xfer += iprot->readStructBegin(fname);
+
+ using ::apache::thrift::protocol::TProtocolException;
+
+
+ while (true)
+ {
+ xfer += iprot->readFieldBegin(fname, ftype, fid);
+ if (ftype == ::apache::thrift::protocol::T_STOP) {
+ break;
+ }
+ switch (fid)
+ {
+ case 1:
+ if (ftype == ::apache::thrift::protocol::T_STRING) {
+ xfer += iprot->readString(this->serviceName);
+ this->__isset.serviceName = true;
+ } else {
+ xfer += iprot->skip(ftype);
+ }
+ break;
+ default:
+ xfer += iprot->skip(ftype);
+ break;
+ }
+ xfer += iprot->readFieldEnd();
+ }
+
+ xfer += iprot->readStructEnd();
+
+ return xfer;
+}
+
+uint32_t BaggageRestrictionManager_getBaggageRestrictions_args::write(::apache::thrift::protocol::TProtocol* oprot) const {
+ uint32_t xfer = 0;
+ ::apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
+ xfer += oprot->writeStructBegin("BaggageRestrictionManager_getBaggageRestrictions_args");
+
+ xfer += oprot->writeFieldBegin("serviceName", ::apache::thrift::protocol::T_STRING, 1);
+ xfer += oprot->writeString(this->serviceName);
+ xfer += oprot->writeFieldEnd();
+
+ xfer += oprot->writeFieldStop();
+ xfer += oprot->writeStructEnd();
+ return xfer;
+}
+
+
+BaggageRestrictionManager_getBaggageRestrictions_pargs::~BaggageRestrictionManager_getBaggageRestrictions_pargs() throw() {
+}
+
+
+uint32_t BaggageRestrictionManager_getBaggageRestrictions_pargs::write(::apache::thrift::protocol::TProtocol* oprot) const {
+ uint32_t xfer = 0;
+ ::apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
+ xfer += oprot->writeStructBegin("BaggageRestrictionManager_getBaggageRestrictions_pargs");
+
+ xfer += oprot->writeFieldBegin("serviceName", ::apache::thrift::protocol::T_STRING, 1);
+ xfer += oprot->writeString((*(this->serviceName)));
+ xfer += oprot->writeFieldEnd();
+
+ xfer += oprot->writeFieldStop();
+ xfer += oprot->writeStructEnd();
+ return xfer;
+}
+
+
+BaggageRestrictionManager_getBaggageRestrictions_result::~BaggageRestrictionManager_getBaggageRestrictions_result() throw() {
+}
+
+
+uint32_t BaggageRestrictionManager_getBaggageRestrictions_result::read(::apache::thrift::protocol::TProtocol* iprot) {
+
+ ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
+ uint32_t xfer = 0;
+ std::string fname;
+ ::apache::thrift::protocol::TType ftype;
+ int16_t fid;
+
+ xfer += iprot->readStructBegin(fname);
+
+ using ::apache::thrift::protocol::TProtocolException;
+
+
+ while (true)
+ {
+ xfer += iprot->readFieldBegin(fname, ftype, fid);
+ if (ftype == ::apache::thrift::protocol::T_STOP) {
+ break;
+ }
+ switch (fid)
+ {
+ case 0:
+ if (ftype == ::apache::thrift::protocol::T_LIST) {
+ {
+ this->success.clear();
+ uint32_t _size2;
+ ::apache::thrift::protocol::TType _etype5;
+ xfer += iprot->readListBegin(_etype5, _size2);
+ this->success.resize(_size2);
+ uint32_t _i6;
+ for (_i6 = 0; _i6 < _size2; ++_i6)
+ {
+ xfer += this->success[_i6].read(iprot);
+ }
+ xfer += iprot->readListEnd();
+ }
+ this->__isset.success = true;
+ } else {
+ xfer += iprot->skip(ftype);
+ }
+ break;
+ default:
+ xfer += iprot->skip(ftype);
+ break;
+ }
+ xfer += iprot->readFieldEnd();
+ }
+
+ xfer += iprot->readStructEnd();
+
+ return xfer;
+}
+
+uint32_t BaggageRestrictionManager_getBaggageRestrictions_result::write(::apache::thrift::protocol::TProtocol* oprot) const {
+
+ uint32_t xfer = 0;
+
+ xfer += oprot->writeStructBegin("BaggageRestrictionManager_getBaggageRestrictions_result");
+
+ if (this->__isset.success) {
+ xfer += oprot->writeFieldBegin("success", ::apache::thrift::protocol::T_LIST, 0);
+ {
+ xfer += oprot->writeListBegin(::apache::thrift::protocol::T_STRUCT, static_cast<uint32_t>(this->success.size()));
+ std::vector<BaggageRestriction> ::const_iterator _iter7;
+ for (_iter7 = this->success.begin(); _iter7 != this->success.end(); ++_iter7)
+ {
+ xfer += (*_iter7).write(oprot);
+ }
+ xfer += oprot->writeListEnd();
+ }
+ xfer += oprot->writeFieldEnd();
+ }
+ xfer += oprot->writeFieldStop();
+ xfer += oprot->writeStructEnd();
+ return xfer;
+}
+
+
+BaggageRestrictionManager_getBaggageRestrictions_presult::~BaggageRestrictionManager_getBaggageRestrictions_presult() throw() {
+}
+
+
+uint32_t BaggageRestrictionManager_getBaggageRestrictions_presult::read(::apache::thrift::protocol::TProtocol* iprot) {
+
+ ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
+ uint32_t xfer = 0;
+ std::string fname;
+ ::apache::thrift::protocol::TType ftype;
+ int16_t fid;
+
+ xfer += iprot->readStructBegin(fname);
+
+ using ::apache::thrift::protocol::TProtocolException;
+
+
+ while (true)
+ {
+ xfer += iprot->readFieldBegin(fname, ftype, fid);
+ if (ftype == ::apache::thrift::protocol::T_STOP) {
+ break;
+ }
+ switch (fid)
+ {
+ case 0:
+ if (ftype == ::apache::thrift::protocol::T_LIST) {
+ {
+ (*(this->success)).clear();
+ uint32_t _size8;
+ ::apache::thrift::protocol::TType _etype11;
+ xfer += iprot->readListBegin(_etype11, _size8);
+ (*(this->success)).resize(_size8);
+ uint32_t _i12;
+ for (_i12 = 0; _i12 < _size8; ++_i12)
+ {
+ xfer += (*(this->success))[_i12].read(iprot);
+ }
+ xfer += iprot->readListEnd();
+ }
+ this->__isset.success = true;
+ } else {
+ xfer += iprot->skip(ftype);
+ }
+ break;
+ default:
+ xfer += iprot->skip(ftype);
+ break;
+ }
+ xfer += iprot->readFieldEnd();
+ }
+
+ xfer += iprot->readStructEnd();
+
+ return xfer;
+}
+
+void BaggageRestrictionManagerClient::getBaggageRestrictions(std::vector<BaggageRestriction> & _return, const std::string& serviceName)
+{
+ send_getBaggageRestrictions(serviceName);
+ recv_getBaggageRestrictions(_return);
+}
+
+void BaggageRestrictionManagerClient::send_getBaggageRestrictions(const std::string& serviceName)
+{
+ int32_t cseqid = 0;
+ oprot_->writeMessageBegin("getBaggageRestrictions", ::apache::thrift::protocol::T_CALL, cseqid);
+
+ BaggageRestrictionManager_getBaggageRestrictions_pargs args;
+ args.serviceName = &serviceName;
+ args.write(oprot_);
+
+ oprot_->writeMessageEnd();
+ oprot_->getTransport()->writeEnd();
+ oprot_->getTransport()->flush();
+}
+
+void BaggageRestrictionManagerClient::recv_getBaggageRestrictions(std::vector<BaggageRestriction> & _return)
+{
+
+ int32_t rseqid = 0;
+ std::string fname;
+ ::apache::thrift::protocol::TMessageType mtype;
+
+ iprot_->readMessageBegin(fname, mtype, rseqid);
+ if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
+ ::apache::thrift::TApplicationException x;
+ x.read(iprot_);
+ iprot_->readMessageEnd();
+ iprot_->getTransport()->readEnd();
+ throw x;
+ }
+ if (mtype != ::apache::thrift::protocol::T_REPLY) {
+ iprot_->skip(::apache::thrift::protocol::T_STRUCT);
+ iprot_->readMessageEnd();
+ iprot_->getTransport()->readEnd();
+ }
+ if (fname.compare("getBaggageRestrictions") != 0) {
+ iprot_->skip(::apache::thrift::protocol::T_STRUCT);
+ iprot_->readMessageEnd();
+ iprot_->getTransport()->readEnd();
+ }
+ BaggageRestrictionManager_getBaggageRestrictions_presult result;
+ result.success = &_return;
+ result.read(iprot_);
+ iprot_->readMessageEnd();
+ iprot_->getTransport()->readEnd();
+
+ if (result.__isset.success) {
+ // _return pointer has now been filled
+ return;
+ }
+ throw ::apache::thrift::TApplicationException(::apache::thrift::TApplicationException::MISSING_RESULT, "getBaggageRestrictions failed: unknown result");
+}
+
+bool BaggageRestrictionManagerProcessor::dispatchCall(::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, const std::string& fname, int32_t seqid, void* callContext) {
+ ProcessMap::iterator pfn;
+ pfn = processMap_.find(fname);
+ if (pfn == processMap_.end()) {
+ iprot->skip(::apache::thrift::protocol::T_STRUCT);
+ iprot->readMessageEnd();
+ iprot->getTransport()->readEnd();
+ ::apache::thrift::TApplicationException x(::apache::thrift::TApplicationException::UNKNOWN_METHOD, "Invalid method name: '"+fname+"'");
+ oprot->writeMessageBegin(fname, ::apache::thrift::protocol::T_EXCEPTION, seqid);
+ x.write(oprot);
+ oprot->writeMessageEnd();
+ oprot->getTransport()->writeEnd();
+ oprot->getTransport()->flush();
+ return true;
+ }
+ (this->*(pfn->second))(seqid, iprot, oprot, callContext);
+ return true;
+}
+
+void BaggageRestrictionManagerProcessor::process_getBaggageRestrictions(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext)
+{
+ void* ctx = NULL;
+ if (this->eventHandler_.get() != NULL) {
+ ctx = this->eventHandler_->getContext("BaggageRestrictionManager.getBaggageRestrictions", callContext);
+ }
+ ::apache::thrift::TProcessorContextFreer freer(this->eventHandler_.get(), ctx, "BaggageRestrictionManager.getBaggageRestrictions");
+
+ if (this->eventHandler_.get() != NULL) {
+ this->eventHandler_->preRead(ctx, "BaggageRestrictionManager.getBaggageRestrictions");
+ }
+
+ BaggageRestrictionManager_getBaggageRestrictions_args args;
+ args.read(iprot);
+ iprot->readMessageEnd();
+ uint32_t bytes = iprot->getTransport()->readEnd();
+
+ if (this->eventHandler_.get() != NULL) {
+ this->eventHandler_->postRead(ctx, "BaggageRestrictionManager.getBaggageRestrictions", bytes);
+ }
+
+ BaggageRestrictionManager_getBaggageRestrictions_result result;
+ try {
+ iface_->getBaggageRestrictions(result.success, args.serviceName);
+ result.__isset.success = true;
+ } catch (const std::exception& e) {
+ if (this->eventHandler_.get() != NULL) {
+ this->eventHandler_->handlerError(ctx, "BaggageRestrictionManager.getBaggageRestrictions");
+ }
+
+ ::apache::thrift::TApplicationException x(e.what());
+ oprot->writeMessageBegin("getBaggageRestrictions", ::apache::thrift::protocol::T_EXCEPTION, seqid);
+ x.write(oprot);
+ oprot->writeMessageEnd();
+ oprot->getTransport()->writeEnd();
+ oprot->getTransport()->flush();
+ return;
+ }
+
+ if (this->eventHandler_.get() != NULL) {
+ this->eventHandler_->preWrite(ctx, "BaggageRestrictionManager.getBaggageRestrictions");
+ }
+
+ oprot->writeMessageBegin("getBaggageRestrictions", ::apache::thrift::protocol::T_REPLY, seqid);
+ result.write(oprot);
+ oprot->writeMessageEnd();
+ bytes = oprot->getTransport()->writeEnd();
+ oprot->getTransport()->flush();
+
+ if (this->eventHandler_.get() != NULL) {
+ this->eventHandler_->postWrite(ctx, "BaggageRestrictionManager.getBaggageRestrictions", bytes);
+ }
+}
+
+::std::shared_ptr< ::apache::thrift::TProcessor > BaggageRestrictionManagerProcessorFactory::getProcessor(const ::apache::thrift::TConnectionInfo& connInfo) {
+ ::apache::thrift::ReleaseHandler< BaggageRestrictionManagerIfFactory > cleanup(handlerFactory_);
+ ::std::shared_ptr< BaggageRestrictionManagerIf > handler(handlerFactory_->getHandler(connInfo), cleanup);
+ ::std::shared_ptr< ::apache::thrift::TProcessor > processor(new BaggageRestrictionManagerProcessor(handler));
+ return processor;
+}
+
+void BaggageRestrictionManagerConcurrentClient::getBaggageRestrictions(std::vector<BaggageRestriction> & _return, const std::string& serviceName)
+{
+ int32_t seqid = send_getBaggageRestrictions(serviceName);
+ recv_getBaggageRestrictions(_return, seqid);
+}
+
+int32_t BaggageRestrictionManagerConcurrentClient::send_getBaggageRestrictions(const std::string& serviceName)
+{
+ int32_t cseqid = this->sync_.generateSeqId();
+ ::apache::thrift::async::TConcurrentSendSentry sentry(&this->sync_);
+ oprot_->writeMessageBegin("getBaggageRestrictions", ::apache::thrift::protocol::T_CALL, cseqid);
+
+ BaggageRestrictionManager_getBaggageRestrictions_pargs args;
+ args.serviceName = &serviceName;
+ args.write(oprot_);
+
+ oprot_->writeMessageEnd();
+ oprot_->getTransport()->writeEnd();
+ oprot_->getTransport()->flush();
+
+ sentry.commit();
+ return cseqid;
+}
+
+void BaggageRestrictionManagerConcurrentClient::recv_getBaggageRestrictions(std::vector<BaggageRestriction> & _return, const int32_t seqid)
+{
+
+ int32_t rseqid = 0;
+ std::string fname;
+ ::apache::thrift::protocol::TMessageType mtype;
+
+ // the read mutex gets dropped and reacquired as part of waitForWork()
+ // The destructor of this sentry wakes up other clients
+ ::apache::thrift::async::TConcurrentRecvSentry sentry(&this->sync_, seqid);
+
+ while(true) {
+ if(!this->sync_.getPending(fname, mtype, rseqid)) {
+ iprot_->readMessageBegin(fname, mtype, rseqid);
+ }
+ if(seqid == rseqid) {
+ if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
+ ::apache::thrift::TApplicationException x;
+ x.read(iprot_);
+ iprot_->readMessageEnd();
+ iprot_->getTransport()->readEnd();
+ sentry.commit();
+ throw x;
+ }
+ if (mtype != ::apache::thrift::protocol::T_REPLY) {
+ iprot_->skip(::apache::thrift::protocol::T_STRUCT);
+ iprot_->readMessageEnd();
+ iprot_->getTransport()->readEnd();
+ }
+ if (fname.compare("getBaggageRestrictions") != 0) {
+ iprot_->skip(::apache::thrift::protocol::T_STRUCT);
+ iprot_->readMessageEnd();
+ iprot_->getTransport()->readEnd();
+
+ // in a bad state, don't commit
+ using ::apache::thrift::protocol::TProtocolException;
+ throw TProtocolException(TProtocolException::INVALID_DATA);
+ }
+ BaggageRestrictionManager_getBaggageRestrictions_presult result;
+ result.success = &_return;
+ result.read(iprot_);
+ iprot_->readMessageEnd();
+ iprot_->getTransport()->readEnd();
+
+ if (result.__isset.success) {
+ // _return pointer has now been filled
+ sentry.commit();
+ return;
+ }
+ // in a bad state, don't commit
+ throw ::apache::thrift::TApplicationException(::apache::thrift::TApplicationException::MISSING_RESULT, "getBaggageRestrictions failed: unknown result");
+ }
+ // seqid != rseqid
+ this->sync_.updatePending(fname, mtype, rseqid);
+
+ // this will temporarily unlock the readMutex, and let other clients get work done
+ this->sync_.waitForWork(seqid);
+ } // end while(true)
+}
+
+}} // namespace
+
diff --git a/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/thrift-gen/BaggageRestrictionManager.h b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/thrift-gen/BaggageRestrictionManager.h
new file mode 100644
index 000000000..442dc12a5
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/thrift-gen/BaggageRestrictionManager.h
@@ -0,0 +1,304 @@
+/**
+ * Autogenerated by Thrift Compiler (0.11.0)
+ *
+ * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
+ * @generated
+ */
+#ifndef BaggageRestrictionManager_H
+#define BaggageRestrictionManager_H
+
+#include <thrift/TDispatchProcessor.h>
+#include <thrift/async/TConcurrentClientSyncInfo.h>
+#include "baggage_types.h"
+
+namespace jaegertracing { namespace thrift {
+
+#ifdef _MSC_VER
+ #pragma warning( push )
+ #pragma warning (disable : 4250 ) //inheriting methods via dominance
+#endif
+
+class BaggageRestrictionManagerIf {
+ public:
+ virtual ~BaggageRestrictionManagerIf() {}
+
+ /**
+ * getBaggageRestrictions retrieves the baggage restrictions for a specific service.
+ * Usually, baggageRestrictions apply to all services however there may be situations
+ * where a baggageKey might only be allowed to be set by a specific service.
+ *
+ * @param serviceName
+ */
+ virtual void getBaggageRestrictions(std::vector<BaggageRestriction> & _return, const std::string& serviceName) = 0;
+};
+
+class BaggageRestrictionManagerIfFactory {
+ public:
+ typedef BaggageRestrictionManagerIf Handler;
+
+ virtual ~BaggageRestrictionManagerIfFactory() {}
+
+ virtual BaggageRestrictionManagerIf* getHandler(const ::apache::thrift::TConnectionInfo& connInfo) = 0;
+ virtual void releaseHandler(BaggageRestrictionManagerIf* /* handler */) = 0;
+};
+
+class BaggageRestrictionManagerIfSingletonFactory : virtual public BaggageRestrictionManagerIfFactory {
+ public:
+ BaggageRestrictionManagerIfSingletonFactory(const ::std::shared_ptr<BaggageRestrictionManagerIf>& iface) : iface_(iface) {}
+ virtual ~BaggageRestrictionManagerIfSingletonFactory() {}
+
+ virtual BaggageRestrictionManagerIf* getHandler(const ::apache::thrift::TConnectionInfo&) {
+ return iface_.get();
+ }
+ virtual void releaseHandler(BaggageRestrictionManagerIf* /* handler */) {}
+
+ protected:
+ ::std::shared_ptr<BaggageRestrictionManagerIf> iface_;
+};
+
+class BaggageRestrictionManagerNull : virtual public BaggageRestrictionManagerIf {
+ public:
+ virtual ~BaggageRestrictionManagerNull() {}
+ void getBaggageRestrictions(std::vector<BaggageRestriction> & /* _return */, const std::string& /* serviceName */) {
+ return;
+ }
+};
+
+typedef struct _BaggageRestrictionManager_getBaggageRestrictions_args__isset {
+ _BaggageRestrictionManager_getBaggageRestrictions_args__isset() : serviceName(false) {}
+ bool serviceName :1;
+} _BaggageRestrictionManager_getBaggageRestrictions_args__isset;
+
+class BaggageRestrictionManager_getBaggageRestrictions_args {
+ public:
+
+ BaggageRestrictionManager_getBaggageRestrictions_args(const BaggageRestrictionManager_getBaggageRestrictions_args&);
+ BaggageRestrictionManager_getBaggageRestrictions_args& operator=(const BaggageRestrictionManager_getBaggageRestrictions_args&);
+ BaggageRestrictionManager_getBaggageRestrictions_args() : serviceName() {
+ }
+
+ virtual ~BaggageRestrictionManager_getBaggageRestrictions_args() throw();
+ std::string serviceName;
+
+ _BaggageRestrictionManager_getBaggageRestrictions_args__isset __isset;
+
+ void __set_serviceName(const std::string& val);
+
+ bool operator == (const BaggageRestrictionManager_getBaggageRestrictions_args & rhs) const
+ {
+ if (!(serviceName == rhs.serviceName))
+ return false;
+ return true;
+ }
+ bool operator != (const BaggageRestrictionManager_getBaggageRestrictions_args &rhs) const {
+ return !(*this == rhs);
+ }
+
+ bool operator < (const BaggageRestrictionManager_getBaggageRestrictions_args & ) const;
+
+ uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
+ uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;
+
+};
+
+
+class BaggageRestrictionManager_getBaggageRestrictions_pargs {
+ public:
+
+
+ virtual ~BaggageRestrictionManager_getBaggageRestrictions_pargs() throw();
+ const std::string* serviceName;
+
+ uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;
+
+};
+
+typedef struct _BaggageRestrictionManager_getBaggageRestrictions_result__isset {
+ _BaggageRestrictionManager_getBaggageRestrictions_result__isset() : success(false) {}
+ bool success :1;
+} _BaggageRestrictionManager_getBaggageRestrictions_result__isset;
+
+class BaggageRestrictionManager_getBaggageRestrictions_result {
+ public:
+
+ BaggageRestrictionManager_getBaggageRestrictions_result(const BaggageRestrictionManager_getBaggageRestrictions_result&);
+ BaggageRestrictionManager_getBaggageRestrictions_result& operator=(const BaggageRestrictionManager_getBaggageRestrictions_result&);
+ BaggageRestrictionManager_getBaggageRestrictions_result() {
+ }
+
+ virtual ~BaggageRestrictionManager_getBaggageRestrictions_result() throw();
+ std::vector<BaggageRestriction> success;
+
+ _BaggageRestrictionManager_getBaggageRestrictions_result__isset __isset;
+
+ void __set_success(const std::vector<BaggageRestriction> & val);
+
+ bool operator == (const BaggageRestrictionManager_getBaggageRestrictions_result & rhs) const
+ {
+ if (!(success == rhs.success))
+ return false;
+ return true;
+ }
+ bool operator != (const BaggageRestrictionManager_getBaggageRestrictions_result &rhs) const {
+ return !(*this == rhs);
+ }
+
+ bool operator < (const BaggageRestrictionManager_getBaggageRestrictions_result & ) const;
+
+ uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
+ uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;
+
+};
+
+typedef struct _BaggageRestrictionManager_getBaggageRestrictions_presult__isset {
+ _BaggageRestrictionManager_getBaggageRestrictions_presult__isset() : success(false) {}
+ bool success :1;
+} _BaggageRestrictionManager_getBaggageRestrictions_presult__isset;
+
+class BaggageRestrictionManager_getBaggageRestrictions_presult {
+ public:
+
+
+ virtual ~BaggageRestrictionManager_getBaggageRestrictions_presult() throw();
+ std::vector<BaggageRestriction> * success;
+
+ _BaggageRestrictionManager_getBaggageRestrictions_presult__isset __isset;
+
+ uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
+
+};
+
+class BaggageRestrictionManagerClient : virtual public BaggageRestrictionManagerIf {
+ public:
+ BaggageRestrictionManagerClient(std::shared_ptr< ::apache::thrift::protocol::TProtocol> prot) {
+ setProtocol(prot);
+ }
+ BaggageRestrictionManagerClient(std::shared_ptr< ::apache::thrift::protocol::TProtocol> iprot, std::shared_ptr< ::apache::thrift::protocol::TProtocol> oprot) {
+ setProtocol(iprot,oprot);
+ }
+ private:
+ void setProtocol(std::shared_ptr< ::apache::thrift::protocol::TProtocol> prot) {
+ setProtocol(prot,prot);
+ }
+ void setProtocol(std::shared_ptr< ::apache::thrift::protocol::TProtocol> iprot, std::shared_ptr< ::apache::thrift::protocol::TProtocol> oprot) {
+ piprot_=iprot;
+ poprot_=oprot;
+ iprot_ = iprot.get();
+ oprot_ = oprot.get();
+ }
+ public:
+ std::shared_ptr< ::apache::thrift::protocol::TProtocol> getInputProtocol() {
+ return piprot_;
+ }
+ std::shared_ptr< ::apache::thrift::protocol::TProtocol> getOutputProtocol() {
+ return poprot_;
+ }
+ void getBaggageRestrictions(std::vector<BaggageRestriction> & _return, const std::string& serviceName);
+ void send_getBaggageRestrictions(const std::string& serviceName);
+ void recv_getBaggageRestrictions(std::vector<BaggageRestriction> & _return);
+ protected:
+ std::shared_ptr< ::apache::thrift::protocol::TProtocol> piprot_;
+ std::shared_ptr< ::apache::thrift::protocol::TProtocol> poprot_;
+ ::apache::thrift::protocol::TProtocol* iprot_;
+ ::apache::thrift::protocol::TProtocol* oprot_;
+};
+
+class BaggageRestrictionManagerProcessor : public ::apache::thrift::TDispatchProcessor {
+ protected:
+ ::std::shared_ptr<BaggageRestrictionManagerIf> iface_;
+ virtual bool dispatchCall(::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, const std::string& fname, int32_t seqid, void* callContext);
+ private:
+ typedef void (BaggageRestrictionManagerProcessor::*ProcessFunction)(int32_t, ::apache::thrift::protocol::TProtocol*, ::apache::thrift::protocol::TProtocol*, void*);
+ typedef std::map<std::string, ProcessFunction> ProcessMap;
+ ProcessMap processMap_;
+ void process_getBaggageRestrictions(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext);
+ public:
+ BaggageRestrictionManagerProcessor(::std::shared_ptr<BaggageRestrictionManagerIf> iface) :
+ iface_(iface) {
+ processMap_["getBaggageRestrictions"] = &BaggageRestrictionManagerProcessor::process_getBaggageRestrictions;
+ }
+
+ virtual ~BaggageRestrictionManagerProcessor() {}
+};
+
+class BaggageRestrictionManagerProcessorFactory : public ::apache::thrift::TProcessorFactory {
+ public:
+ BaggageRestrictionManagerProcessorFactory(const ::std::shared_ptr< BaggageRestrictionManagerIfFactory >& handlerFactory) :
+ handlerFactory_(handlerFactory) {}
+
+ ::std::shared_ptr< ::apache::thrift::TProcessor > getProcessor(const ::apache::thrift::TConnectionInfo& connInfo);
+
+ protected:
+ ::std::shared_ptr< BaggageRestrictionManagerIfFactory > handlerFactory_;
+};
+
+class BaggageRestrictionManagerMultiface : virtual public BaggageRestrictionManagerIf {
+ public:
+ BaggageRestrictionManagerMultiface(std::vector<std::shared_ptr<BaggageRestrictionManagerIf> >& ifaces) : ifaces_(ifaces) {
+ }
+ virtual ~BaggageRestrictionManagerMultiface() {}
+ protected:
+ std::vector<std::shared_ptr<BaggageRestrictionManagerIf> > ifaces_;
+ BaggageRestrictionManagerMultiface() {}
+ void add(::std::shared_ptr<BaggageRestrictionManagerIf> iface) {
+ ifaces_.push_back(iface);
+ }
+ public:
+ void getBaggageRestrictions(std::vector<BaggageRestriction> & _return, const std::string& serviceName) {
+ size_t sz = ifaces_.size();
+ size_t i = 0;
+ for (; i < (sz - 1); ++i) {
+ ifaces_[i]->getBaggageRestrictions(_return, serviceName);
+ }
+ ifaces_[i]->getBaggageRestrictions(_return, serviceName);
+ return;
+ }
+
+};
+
+// The 'concurrent' client is a thread safe client that correctly handles
+// out of order responses. It is slower than the regular client, so should
+// only be used when you need to share a connection among multiple threads
+class BaggageRestrictionManagerConcurrentClient : virtual public BaggageRestrictionManagerIf {
+ public:
+ BaggageRestrictionManagerConcurrentClient(std::shared_ptr< ::apache::thrift::protocol::TProtocol> prot) {
+ setProtocol(prot);
+ }
+ BaggageRestrictionManagerConcurrentClient(std::shared_ptr< ::apache::thrift::protocol::TProtocol> iprot, std::shared_ptr< ::apache::thrift::protocol::TProtocol> oprot) {
+ setProtocol(iprot,oprot);
+ }
+ private:
+ void setProtocol(std::shared_ptr< ::apache::thrift::protocol::TProtocol> prot) {
+ setProtocol(prot,prot);
+ }
+ void setProtocol(std::shared_ptr< ::apache::thrift::protocol::TProtocol> iprot, std::shared_ptr< ::apache::thrift::protocol::TProtocol> oprot) {
+ piprot_=iprot;
+ poprot_=oprot;
+ iprot_ = iprot.get();
+ oprot_ = oprot.get();
+ }
+ public:
+ std::shared_ptr< ::apache::thrift::protocol::TProtocol> getInputProtocol() {
+ return piprot_;
+ }
+ std::shared_ptr< ::apache::thrift::protocol::TProtocol> getOutputProtocol() {
+ return poprot_;
+ }
+ void getBaggageRestrictions(std::vector<BaggageRestriction> & _return, const std::string& serviceName);
+ int32_t send_getBaggageRestrictions(const std::string& serviceName);
+ void recv_getBaggageRestrictions(std::vector<BaggageRestriction> & _return, const int32_t seqid);
+ protected:
+ std::shared_ptr< ::apache::thrift::protocol::TProtocol> piprot_;
+ std::shared_ptr< ::apache::thrift::protocol::TProtocol> poprot_;
+ ::apache::thrift::protocol::TProtocol* iprot_;
+ ::apache::thrift::protocol::TProtocol* oprot_;
+ ::apache::thrift::async::TConcurrentClientSyncInfo sync_;
+};
+
+#ifdef _MSC_VER
+ #pragma warning( pop )
+#endif
+
+}} // namespace
+
+#endif
diff --git a/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/thrift-gen/Collector.cpp b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/thrift-gen/Collector.cpp
new file mode 100644
index 000000000..795264fc2
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/thrift-gen/Collector.cpp
@@ -0,0 +1,481 @@
+/**
+ * Autogenerated by Thrift Compiler (0.11.0)
+ *
+ * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
+ * @generated
+ */
+#include "Collector.h"
+
+namespace jaegertracing { namespace thrift {
+
+
+Collector_submitBatches_args::~Collector_submitBatches_args() throw() {
+}
+
+
+uint32_t Collector_submitBatches_args::read(::apache::thrift::protocol::TProtocol* iprot) {
+
+ ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
+ uint32_t xfer = 0;
+ std::string fname;
+ ::apache::thrift::protocol::TType ftype;
+ int16_t fid;
+
+ xfer += iprot->readStructBegin(fname);
+
+ using ::apache::thrift::protocol::TProtocolException;
+
+
+ while (true)
+ {
+ xfer += iprot->readFieldBegin(fname, ftype, fid);
+ if (ftype == ::apache::thrift::protocol::T_STOP) {
+ break;
+ }
+ switch (fid)
+ {
+ case 1:
+ if (ftype == ::apache::thrift::protocol::T_LIST) {
+ {
+ this->batches.clear();
+ uint32_t _size52;
+ ::apache::thrift::protocol::TType _etype55;
+ xfer += iprot->readListBegin(_etype55, _size52);
+ this->batches.resize(_size52);
+ uint32_t _i56;
+ for (_i56 = 0; _i56 < _size52; ++_i56)
+ {
+ xfer += this->batches[_i56].read(iprot);
+ }
+ xfer += iprot->readListEnd();
+ }
+ this->__isset.batches = true;
+ } else {
+ xfer += iprot->skip(ftype);
+ }
+ break;
+ default:
+ xfer += iprot->skip(ftype);
+ break;
+ }
+ xfer += iprot->readFieldEnd();
+ }
+
+ xfer += iprot->readStructEnd();
+
+ return xfer;
+}
+
+uint32_t Collector_submitBatches_args::write(::apache::thrift::protocol::TProtocol* oprot) const {
+ uint32_t xfer = 0;
+ ::apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
+ xfer += oprot->writeStructBegin("Collector_submitBatches_args");
+
+ xfer += oprot->writeFieldBegin("batches", ::apache::thrift::protocol::T_LIST, 1);
+ {
+ xfer += oprot->writeListBegin(::apache::thrift::protocol::T_STRUCT, static_cast<uint32_t>(this->batches.size()));
+ std::vector<Batch> ::const_iterator _iter57;
+ for (_iter57 = this->batches.begin(); _iter57 != this->batches.end(); ++_iter57)
+ {
+ xfer += (*_iter57).write(oprot);
+ }
+ xfer += oprot->writeListEnd();
+ }
+ xfer += oprot->writeFieldEnd();
+
+ xfer += oprot->writeFieldStop();
+ xfer += oprot->writeStructEnd();
+ return xfer;
+}
+
+
+Collector_submitBatches_pargs::~Collector_submitBatches_pargs() throw() {
+}
+
+
+uint32_t Collector_submitBatches_pargs::write(::apache::thrift::protocol::TProtocol* oprot) const {
+ uint32_t xfer = 0;
+ ::apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
+ xfer += oprot->writeStructBegin("Collector_submitBatches_pargs");
+
+ xfer += oprot->writeFieldBegin("batches", ::apache::thrift::protocol::T_LIST, 1);
+ {
+ xfer += oprot->writeListBegin(::apache::thrift::protocol::T_STRUCT, static_cast<uint32_t>((*(this->batches)).size()));
+ std::vector<Batch> ::const_iterator _iter58;
+ for (_iter58 = (*(this->batches)).begin(); _iter58 != (*(this->batches)).end(); ++_iter58)
+ {
+ xfer += (*_iter58).write(oprot);
+ }
+ xfer += oprot->writeListEnd();
+ }
+ xfer += oprot->writeFieldEnd();
+
+ xfer += oprot->writeFieldStop();
+ xfer += oprot->writeStructEnd();
+ return xfer;
+}
+
+
+Collector_submitBatches_result::~Collector_submitBatches_result() throw() {
+}
+
+
+uint32_t Collector_submitBatches_result::read(::apache::thrift::protocol::TProtocol* iprot) {
+
+ ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
+ uint32_t xfer = 0;
+ std::string fname;
+ ::apache::thrift::protocol::TType ftype;
+ int16_t fid;
+
+ xfer += iprot->readStructBegin(fname);
+
+ using ::apache::thrift::protocol::TProtocolException;
+
+
+ while (true)
+ {
+ xfer += iprot->readFieldBegin(fname, ftype, fid);
+ if (ftype == ::apache::thrift::protocol::T_STOP) {
+ break;
+ }
+ switch (fid)
+ {
+ case 0:
+ if (ftype == ::apache::thrift::protocol::T_LIST) {
+ {
+ this->success.clear();
+ uint32_t _size59;
+ ::apache::thrift::protocol::TType _etype62;
+ xfer += iprot->readListBegin(_etype62, _size59);
+ this->success.resize(_size59);
+ uint32_t _i63;
+ for (_i63 = 0; _i63 < _size59; ++_i63)
+ {
+ xfer += this->success[_i63].read(iprot);
+ }
+ xfer += iprot->readListEnd();
+ }
+ this->__isset.success = true;
+ } else {
+ xfer += iprot->skip(ftype);
+ }
+ break;
+ default:
+ xfer += iprot->skip(ftype);
+ break;
+ }
+ xfer += iprot->readFieldEnd();
+ }
+
+ xfer += iprot->readStructEnd();
+
+ return xfer;
+}
+
+uint32_t Collector_submitBatches_result::write(::apache::thrift::protocol::TProtocol* oprot) const {
+
+ uint32_t xfer = 0;
+
+ xfer += oprot->writeStructBegin("Collector_submitBatches_result");
+
+ if (this->__isset.success) {
+ xfer += oprot->writeFieldBegin("success", ::apache::thrift::protocol::T_LIST, 0);
+ {
+ xfer += oprot->writeListBegin(::apache::thrift::protocol::T_STRUCT, static_cast<uint32_t>(this->success.size()));
+ std::vector<BatchSubmitResponse> ::const_iterator _iter64;
+ for (_iter64 = this->success.begin(); _iter64 != this->success.end(); ++_iter64)
+ {
+ xfer += (*_iter64).write(oprot);
+ }
+ xfer += oprot->writeListEnd();
+ }
+ xfer += oprot->writeFieldEnd();
+ }
+ xfer += oprot->writeFieldStop();
+ xfer += oprot->writeStructEnd();
+ return xfer;
+}
+
+
+Collector_submitBatches_presult::~Collector_submitBatches_presult() throw() {
+}
+
+
+uint32_t Collector_submitBatches_presult::read(::apache::thrift::protocol::TProtocol* iprot) {
+
+ ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
+ uint32_t xfer = 0;
+ std::string fname;
+ ::apache::thrift::protocol::TType ftype;
+ int16_t fid;
+
+ xfer += iprot->readStructBegin(fname);
+
+ using ::apache::thrift::protocol::TProtocolException;
+
+
+ while (true)
+ {
+ xfer += iprot->readFieldBegin(fname, ftype, fid);
+ if (ftype == ::apache::thrift::protocol::T_STOP) {
+ break;
+ }
+ switch (fid)
+ {
+ case 0:
+ if (ftype == ::apache::thrift::protocol::T_LIST) {
+ {
+ (*(this->success)).clear();
+ uint32_t _size65;
+ ::apache::thrift::protocol::TType _etype68;
+ xfer += iprot->readListBegin(_etype68, _size65);
+ (*(this->success)).resize(_size65);
+ uint32_t _i69;
+ for (_i69 = 0; _i69 < _size65; ++_i69)
+ {
+ xfer += (*(this->success))[_i69].read(iprot);
+ }
+ xfer += iprot->readListEnd();
+ }
+ this->__isset.success = true;
+ } else {
+ xfer += iprot->skip(ftype);
+ }
+ break;
+ default:
+ xfer += iprot->skip(ftype);
+ break;
+ }
+ xfer += iprot->readFieldEnd();
+ }
+
+ xfer += iprot->readStructEnd();
+
+ return xfer;
+}
+
+void CollectorClient::submitBatches(std::vector<BatchSubmitResponse> & _return, const std::vector<Batch> & batches)
+{
+ send_submitBatches(batches);
+ recv_submitBatches(_return);
+}
+
+void CollectorClient::send_submitBatches(const std::vector<Batch> & batches)
+{
+ int32_t cseqid = 0;
+ oprot_->writeMessageBegin("submitBatches", ::apache::thrift::protocol::T_CALL, cseqid);
+
+ Collector_submitBatches_pargs args;
+ args.batches = &batches;
+ args.write(oprot_);
+
+ oprot_->writeMessageEnd();
+ oprot_->getTransport()->writeEnd();
+ oprot_->getTransport()->flush();
+}
+
+void CollectorClient::recv_submitBatches(std::vector<BatchSubmitResponse> & _return)
+{
+
+ int32_t rseqid = 0;
+ std::string fname;
+ ::apache::thrift::protocol::TMessageType mtype;
+
+ iprot_->readMessageBegin(fname, mtype, rseqid);
+ if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
+ ::apache::thrift::TApplicationException x;
+ x.read(iprot_);
+ iprot_->readMessageEnd();
+ iprot_->getTransport()->readEnd();
+ throw x;
+ }
+ if (mtype != ::apache::thrift::protocol::T_REPLY) {
+ iprot_->skip(::apache::thrift::protocol::T_STRUCT);
+ iprot_->readMessageEnd();
+ iprot_->getTransport()->readEnd();
+ }
+ if (fname.compare("submitBatches") != 0) {
+ iprot_->skip(::apache::thrift::protocol::T_STRUCT);
+ iprot_->readMessageEnd();
+ iprot_->getTransport()->readEnd();
+ }
+ Collector_submitBatches_presult result;
+ result.success = &_return;
+ result.read(iprot_);
+ iprot_->readMessageEnd();
+ iprot_->getTransport()->readEnd();
+
+ if (result.__isset.success) {
+ // _return pointer has now been filled
+ return;
+ }
+ throw ::apache::thrift::TApplicationException(::apache::thrift::TApplicationException::MISSING_RESULT, "submitBatches failed: unknown result");
+}
+
+bool CollectorProcessor::dispatchCall(::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, const std::string& fname, int32_t seqid, void* callContext) {
+ ProcessMap::iterator pfn;
+ pfn = processMap_.find(fname);
+ if (pfn == processMap_.end()) {
+ iprot->skip(::apache::thrift::protocol::T_STRUCT);
+ iprot->readMessageEnd();
+ iprot->getTransport()->readEnd();
+ ::apache::thrift::TApplicationException x(::apache::thrift::TApplicationException::UNKNOWN_METHOD, "Invalid method name: '"+fname+"'");
+ oprot->writeMessageBegin(fname, ::apache::thrift::protocol::T_EXCEPTION, seqid);
+ x.write(oprot);
+ oprot->writeMessageEnd();
+ oprot->getTransport()->writeEnd();
+ oprot->getTransport()->flush();
+ return true;
+ }
+ (this->*(pfn->second))(seqid, iprot, oprot, callContext);
+ return true;
+}
+
+void CollectorProcessor::process_submitBatches(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext)
+{
+ void* ctx = NULL;
+ if (this->eventHandler_.get() != NULL) {
+ ctx = this->eventHandler_->getContext("Collector.submitBatches", callContext);
+ }
+ ::apache::thrift::TProcessorContextFreer freer(this->eventHandler_.get(), ctx, "Collector.submitBatches");
+
+ if (this->eventHandler_.get() != NULL) {
+ this->eventHandler_->preRead(ctx, "Collector.submitBatches");
+ }
+
+ Collector_submitBatches_args args;
+ args.read(iprot);
+ iprot->readMessageEnd();
+ uint32_t bytes = iprot->getTransport()->readEnd();
+
+ if (this->eventHandler_.get() != NULL) {
+ this->eventHandler_->postRead(ctx, "Collector.submitBatches", bytes);
+ }
+
+ Collector_submitBatches_result result;
+ try {
+ iface_->submitBatches(result.success, args.batches);
+ result.__isset.success = true;
+ } catch (const std::exception& e) {
+ if (this->eventHandler_.get() != NULL) {
+ this->eventHandler_->handlerError(ctx, "Collector.submitBatches");
+ }
+
+ ::apache::thrift::TApplicationException x(e.what());
+ oprot->writeMessageBegin("submitBatches", ::apache::thrift::protocol::T_EXCEPTION, seqid);
+ x.write(oprot);
+ oprot->writeMessageEnd();
+ oprot->getTransport()->writeEnd();
+ oprot->getTransport()->flush();
+ return;
+ }
+
+ if (this->eventHandler_.get() != NULL) {
+ this->eventHandler_->preWrite(ctx, "Collector.submitBatches");
+ }
+
+ oprot->writeMessageBegin("submitBatches", ::apache::thrift::protocol::T_REPLY, seqid);
+ result.write(oprot);
+ oprot->writeMessageEnd();
+ bytes = oprot->getTransport()->writeEnd();
+ oprot->getTransport()->flush();
+
+ if (this->eventHandler_.get() != NULL) {
+ this->eventHandler_->postWrite(ctx, "Collector.submitBatches", bytes);
+ }
+}
+
+::std::shared_ptr< ::apache::thrift::TProcessor > CollectorProcessorFactory::getProcessor(const ::apache::thrift::TConnectionInfo& connInfo) {
+ ::apache::thrift::ReleaseHandler< CollectorIfFactory > cleanup(handlerFactory_);
+ ::std::shared_ptr< CollectorIf > handler(handlerFactory_->getHandler(connInfo), cleanup);
+ ::std::shared_ptr< ::apache::thrift::TProcessor > processor(new CollectorProcessor(handler));
+ return processor;
+}
+
+void CollectorConcurrentClient::submitBatches(std::vector<BatchSubmitResponse> & _return, const std::vector<Batch> & batches)
+{
+ int32_t seqid = send_submitBatches(batches);
+ recv_submitBatches(_return, seqid);
+}
+
+int32_t CollectorConcurrentClient::send_submitBatches(const std::vector<Batch> & batches)
+{
+ int32_t cseqid = this->sync_.generateSeqId();
+ ::apache::thrift::async::TConcurrentSendSentry sentry(&this->sync_);
+ oprot_->writeMessageBegin("submitBatches", ::apache::thrift::protocol::T_CALL, cseqid);
+
+ Collector_submitBatches_pargs args;
+ args.batches = &batches;
+ args.write(oprot_);
+
+ oprot_->writeMessageEnd();
+ oprot_->getTransport()->writeEnd();
+ oprot_->getTransport()->flush();
+
+ sentry.commit();
+ return cseqid;
+}
+
+void CollectorConcurrentClient::recv_submitBatches(std::vector<BatchSubmitResponse> & _return, const int32_t seqid)
+{
+
+ int32_t rseqid = 0;
+ std::string fname;
+ ::apache::thrift::protocol::TMessageType mtype;
+
+ // the read mutex gets dropped and reacquired as part of waitForWork()
+ // The destructor of this sentry wakes up other clients
+ ::apache::thrift::async::TConcurrentRecvSentry sentry(&this->sync_, seqid);
+
+ while(true) {
+ if(!this->sync_.getPending(fname, mtype, rseqid)) {
+ iprot_->readMessageBegin(fname, mtype, rseqid);
+ }
+ if(seqid == rseqid) {
+ if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
+ ::apache::thrift::TApplicationException x;
+ x.read(iprot_);
+ iprot_->readMessageEnd();
+ iprot_->getTransport()->readEnd();
+ sentry.commit();
+ throw x;
+ }
+ if (mtype != ::apache::thrift::protocol::T_REPLY) {
+ iprot_->skip(::apache::thrift::protocol::T_STRUCT);
+ iprot_->readMessageEnd();
+ iprot_->getTransport()->readEnd();
+ }
+ if (fname.compare("submitBatches") != 0) {
+ iprot_->skip(::apache::thrift::protocol::T_STRUCT);
+ iprot_->readMessageEnd();
+ iprot_->getTransport()->readEnd();
+
+ // in a bad state, don't commit
+ using ::apache::thrift::protocol::TProtocolException;
+ throw TProtocolException(TProtocolException::INVALID_DATA);
+ }
+ Collector_submitBatches_presult result;
+ result.success = &_return;
+ result.read(iprot_);
+ iprot_->readMessageEnd();
+ iprot_->getTransport()->readEnd();
+
+ if (result.__isset.success) {
+ // _return pointer has now been filled
+ sentry.commit();
+ return;
+ }
+ // in a bad state, don't commit
+ throw ::apache::thrift::TApplicationException(::apache::thrift::TApplicationException::MISSING_RESULT, "submitBatches failed: unknown result");
+ }
+ // seqid != rseqid
+ this->sync_.updatePending(fname, mtype, rseqid);
+
+ // this will temporarily unlock the readMutex, and let other clients get work done
+ this->sync_.waitForWork(seqid);
+ } // end while(true)
+}
+
+}} // namespace
+
diff --git a/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/thrift-gen/Collector.h b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/thrift-gen/Collector.h
new file mode 100644
index 000000000..4cca6550c
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/thrift-gen/Collector.h
@@ -0,0 +1,296 @@
+/**
+ * Autogenerated by Thrift Compiler (0.11.0)
+ *
+ * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
+ * @generated
+ */
+#ifndef Collector_H
+#define Collector_H
+
+#include <thrift/TDispatchProcessor.h>
+#include <thrift/async/TConcurrentClientSyncInfo.h>
+#include "jaeger_types.h"
+
+namespace jaegertracing { namespace thrift {
+
+#ifdef _MSC_VER
+ #pragma warning( push )
+ #pragma warning (disable : 4250 ) //inheriting methods via dominance
+#endif
+
+class CollectorIf {
+ public:
+ virtual ~CollectorIf() {}
+ virtual void submitBatches(std::vector<BatchSubmitResponse> & _return, const std::vector<Batch> & batches) = 0;
+};
+
+class CollectorIfFactory {
+ public:
+ typedef CollectorIf Handler;
+
+ virtual ~CollectorIfFactory() {}
+
+ virtual CollectorIf* getHandler(const ::apache::thrift::TConnectionInfo& connInfo) = 0;
+ virtual void releaseHandler(CollectorIf* /* handler */) = 0;
+};
+
+class CollectorIfSingletonFactory : virtual public CollectorIfFactory {
+ public:
+ CollectorIfSingletonFactory(const ::std::shared_ptr<CollectorIf>& iface) : iface_(iface) {}
+ virtual ~CollectorIfSingletonFactory() {}
+
+ virtual CollectorIf* getHandler(const ::apache::thrift::TConnectionInfo&) {
+ return iface_.get();
+ }
+ virtual void releaseHandler(CollectorIf* /* handler */) {}
+
+ protected:
+ ::std::shared_ptr<CollectorIf> iface_;
+};
+
+class CollectorNull : virtual public CollectorIf {
+ public:
+ virtual ~CollectorNull() {}
+ void submitBatches(std::vector<BatchSubmitResponse> & /* _return */, const std::vector<Batch> & /* batches */) {
+ return;
+ }
+};
+
+typedef struct _Collector_submitBatches_args__isset {
+ _Collector_submitBatches_args__isset() : batches(false) {}
+ bool batches :1;
+} _Collector_submitBatches_args__isset;
+
+class Collector_submitBatches_args {
+ public:
+
+ Collector_submitBatches_args(const Collector_submitBatches_args&);
+ Collector_submitBatches_args& operator=(const Collector_submitBatches_args&);
+ Collector_submitBatches_args() {
+ }
+
+ virtual ~Collector_submitBatches_args() throw();
+ std::vector<Batch> batches;
+
+ _Collector_submitBatches_args__isset __isset;
+
+ void __set_batches(const std::vector<Batch> & val);
+
+ bool operator == (const Collector_submitBatches_args & rhs) const
+ {
+ if (!(batches == rhs.batches))
+ return false;
+ return true;
+ }
+ bool operator != (const Collector_submitBatches_args &rhs) const {
+ return !(*this == rhs);
+ }
+
+ bool operator < (const Collector_submitBatches_args & ) const;
+
+ uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
+ uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;
+
+};
+
+
+class Collector_submitBatches_pargs {
+ public:
+
+
+ virtual ~Collector_submitBatches_pargs() throw();
+ const std::vector<Batch> * batches;
+
+ uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;
+
+};
+
+typedef struct _Collector_submitBatches_result__isset {
+ _Collector_submitBatches_result__isset() : success(false) {}
+ bool success :1;
+} _Collector_submitBatches_result__isset;
+
+class Collector_submitBatches_result {
+ public:
+
+ Collector_submitBatches_result(const Collector_submitBatches_result&);
+ Collector_submitBatches_result& operator=(const Collector_submitBatches_result&);
+ Collector_submitBatches_result() {
+ }
+
+ virtual ~Collector_submitBatches_result() throw();
+ std::vector<BatchSubmitResponse> success;
+
+ _Collector_submitBatches_result__isset __isset;
+
+ void __set_success(const std::vector<BatchSubmitResponse> & val);
+
+ bool operator == (const Collector_submitBatches_result & rhs) const
+ {
+ if (!(success == rhs.success))
+ return false;
+ return true;
+ }
+ bool operator != (const Collector_submitBatches_result &rhs) const {
+ return !(*this == rhs);
+ }
+
+ bool operator < (const Collector_submitBatches_result & ) const;
+
+ uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
+ uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;
+
+};
+
+typedef struct _Collector_submitBatches_presult__isset {
+ _Collector_submitBatches_presult__isset() : success(false) {}
+ bool success :1;
+} _Collector_submitBatches_presult__isset;
+
+class Collector_submitBatches_presult {
+ public:
+
+
+ virtual ~Collector_submitBatches_presult() throw();
+ std::vector<BatchSubmitResponse> * success;
+
+ _Collector_submitBatches_presult__isset __isset;
+
+ uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
+
+};
+
+class CollectorClient : virtual public CollectorIf {
+ public:
+ CollectorClient(std::shared_ptr< ::apache::thrift::protocol::TProtocol> prot) {
+ setProtocol(prot);
+ }
+ CollectorClient(std::shared_ptr< ::apache::thrift::protocol::TProtocol> iprot, std::shared_ptr< ::apache::thrift::protocol::TProtocol> oprot) {
+ setProtocol(iprot,oprot);
+ }
+ private:
+ void setProtocol(std::shared_ptr< ::apache::thrift::protocol::TProtocol> prot) {
+ setProtocol(prot,prot);
+ }
+ void setProtocol(std::shared_ptr< ::apache::thrift::protocol::TProtocol> iprot, std::shared_ptr< ::apache::thrift::protocol::TProtocol> oprot) {
+ piprot_=iprot;
+ poprot_=oprot;
+ iprot_ = iprot.get();
+ oprot_ = oprot.get();
+ }
+ public:
+ std::shared_ptr< ::apache::thrift::protocol::TProtocol> getInputProtocol() {
+ return piprot_;
+ }
+ std::shared_ptr< ::apache::thrift::protocol::TProtocol> getOutputProtocol() {
+ return poprot_;
+ }
+ void submitBatches(std::vector<BatchSubmitResponse> & _return, const std::vector<Batch> & batches);
+ void send_submitBatches(const std::vector<Batch> & batches);
+ void recv_submitBatches(std::vector<BatchSubmitResponse> & _return);
+ protected:
+ std::shared_ptr< ::apache::thrift::protocol::TProtocol> piprot_;
+ std::shared_ptr< ::apache::thrift::protocol::TProtocol> poprot_;
+ ::apache::thrift::protocol::TProtocol* iprot_;
+ ::apache::thrift::protocol::TProtocol* oprot_;
+};
+
+class CollectorProcessor : public ::apache::thrift::TDispatchProcessor {
+ protected:
+ ::std::shared_ptr<CollectorIf> iface_;
+ virtual bool dispatchCall(::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, const std::string& fname, int32_t seqid, void* callContext);
+ private:
+ typedef void (CollectorProcessor::*ProcessFunction)(int32_t, ::apache::thrift::protocol::TProtocol*, ::apache::thrift::protocol::TProtocol*, void*);
+ typedef std::map<std::string, ProcessFunction> ProcessMap;
+ ProcessMap processMap_;
+ void process_submitBatches(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext);
+ public:
+ CollectorProcessor(::std::shared_ptr<CollectorIf> iface) :
+ iface_(iface) {
+ processMap_["submitBatches"] = &CollectorProcessor::process_submitBatches;
+ }
+
+ virtual ~CollectorProcessor() {}
+};
+
+class CollectorProcessorFactory : public ::apache::thrift::TProcessorFactory {
+ public:
+ CollectorProcessorFactory(const ::std::shared_ptr< CollectorIfFactory >& handlerFactory) :
+ handlerFactory_(handlerFactory) {}
+
+ ::std::shared_ptr< ::apache::thrift::TProcessor > getProcessor(const ::apache::thrift::TConnectionInfo& connInfo);
+
+ protected:
+ ::std::shared_ptr< CollectorIfFactory > handlerFactory_;
+};
+
+class CollectorMultiface : virtual public CollectorIf {
+ public:
+ CollectorMultiface(std::vector<std::shared_ptr<CollectorIf> >& ifaces) : ifaces_(ifaces) {
+ }
+ virtual ~CollectorMultiface() {}
+ protected:
+ std::vector<std::shared_ptr<CollectorIf> > ifaces_;
+ CollectorMultiface() {}
+ void add(::std::shared_ptr<CollectorIf> iface) {
+ ifaces_.push_back(iface);
+ }
+ public:
+ void submitBatches(std::vector<BatchSubmitResponse> & _return, const std::vector<Batch> & batches) {
+ size_t sz = ifaces_.size();
+ size_t i = 0;
+ for (; i < (sz - 1); ++i) {
+ ifaces_[i]->submitBatches(_return, batches);
+ }
+ ifaces_[i]->submitBatches(_return, batches);
+ return;
+ }
+
+};
+
+// The 'concurrent' client is a thread safe client that correctly handles
+// out of order responses. It is slower than the regular client, so should
+// only be used when you need to share a connection among multiple threads
+class CollectorConcurrentClient : virtual public CollectorIf {
+ public:
+ CollectorConcurrentClient(std::shared_ptr< ::apache::thrift::protocol::TProtocol> prot) {
+ setProtocol(prot);
+ }
+ CollectorConcurrentClient(std::shared_ptr< ::apache::thrift::protocol::TProtocol> iprot, std::shared_ptr< ::apache::thrift::protocol::TProtocol> oprot) {
+ setProtocol(iprot,oprot);
+ }
+ private:
+ void setProtocol(std::shared_ptr< ::apache::thrift::protocol::TProtocol> prot) {
+ setProtocol(prot,prot);
+ }
+ void setProtocol(std::shared_ptr< ::apache::thrift::protocol::TProtocol> iprot, std::shared_ptr< ::apache::thrift::protocol::TProtocol> oprot) {
+ piprot_=iprot;
+ poprot_=oprot;
+ iprot_ = iprot.get();
+ oprot_ = oprot.get();
+ }
+ public:
+ std::shared_ptr< ::apache::thrift::protocol::TProtocol> getInputProtocol() {
+ return piprot_;
+ }
+ std::shared_ptr< ::apache::thrift::protocol::TProtocol> getOutputProtocol() {
+ return poprot_;
+ }
+ void submitBatches(std::vector<BatchSubmitResponse> & _return, const std::vector<Batch> & batches);
+ int32_t send_submitBatches(const std::vector<Batch> & batches);
+ void recv_submitBatches(std::vector<BatchSubmitResponse> & _return, const int32_t seqid);
+ protected:
+ std::shared_ptr< ::apache::thrift::protocol::TProtocol> piprot_;
+ std::shared_ptr< ::apache::thrift::protocol::TProtocol> poprot_;
+ ::apache::thrift::protocol::TProtocol* iprot_;
+ ::apache::thrift::protocol::TProtocol* oprot_;
+ ::apache::thrift::async::TConcurrentClientSyncInfo sync_;
+};
+
+#ifdef _MSC_VER
+ #pragma warning( pop )
+#endif
+
+}} // namespace
+
+#endif
diff --git a/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/thrift-gen/Dependency.cpp b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/thrift-gen/Dependency.cpp
new file mode 100644
index 000000000..d34f55c5a
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/thrift-gen/Dependency.cpp
@@ -0,0 +1,581 @@
+/**
+ * Autogenerated by Thrift Compiler (0.11.0)
+ *
+ * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
+ * @generated
+ */
+#include "Dependency.h"
+
+namespace jaegertracing { namespace thrift {
+
+
+Dependency_getDependenciesForTrace_args::~Dependency_getDependenciesForTrace_args() throw() {
+}
+
+
+uint32_t Dependency_getDependenciesForTrace_args::read(::apache::thrift::protocol::TProtocol* iprot) {
+
+ ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
+ uint32_t xfer = 0;
+ std::string fname;
+ ::apache::thrift::protocol::TType ftype;
+ int16_t fid;
+
+ xfer += iprot->readStructBegin(fname);
+
+ using ::apache::thrift::protocol::TProtocolException;
+
+ bool isset_traceId = false;
+
+ while (true)
+ {
+ xfer += iprot->readFieldBegin(fname, ftype, fid);
+ if (ftype == ::apache::thrift::protocol::T_STOP) {
+ break;
+ }
+ switch (fid)
+ {
+ case 1:
+ if (ftype == ::apache::thrift::protocol::T_STRING) {
+ xfer += iprot->readString(this->traceId);
+ isset_traceId = true;
+ } else {
+ xfer += iprot->skip(ftype);
+ }
+ break;
+ default:
+ xfer += iprot->skip(ftype);
+ break;
+ }
+ xfer += iprot->readFieldEnd();
+ }
+
+ xfer += iprot->readStructEnd();
+
+ if (!isset_traceId)
+ throw TProtocolException(TProtocolException::INVALID_DATA);
+ return xfer;
+}
+
+uint32_t Dependency_getDependenciesForTrace_args::write(::apache::thrift::protocol::TProtocol* oprot) const {
+ uint32_t xfer = 0;
+ ::apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
+ xfer += oprot->writeStructBegin("Dependency_getDependenciesForTrace_args");
+
+ xfer += oprot->writeFieldBegin("traceId", ::apache::thrift::protocol::T_STRING, 1);
+ xfer += oprot->writeString(this->traceId);
+ xfer += oprot->writeFieldEnd();
+
+ xfer += oprot->writeFieldStop();
+ xfer += oprot->writeStructEnd();
+ return xfer;
+}
+
+
+Dependency_getDependenciesForTrace_pargs::~Dependency_getDependenciesForTrace_pargs() throw() {
+}
+
+
+uint32_t Dependency_getDependenciesForTrace_pargs::write(::apache::thrift::protocol::TProtocol* oprot) const {
+ uint32_t xfer = 0;
+ ::apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
+ xfer += oprot->writeStructBegin("Dependency_getDependenciesForTrace_pargs");
+
+ xfer += oprot->writeFieldBegin("traceId", ::apache::thrift::protocol::T_STRING, 1);
+ xfer += oprot->writeString((*(this->traceId)));
+ xfer += oprot->writeFieldEnd();
+
+ xfer += oprot->writeFieldStop();
+ xfer += oprot->writeStructEnd();
+ return xfer;
+}
+
+
+Dependency_getDependenciesForTrace_result::~Dependency_getDependenciesForTrace_result() throw() {
+}
+
+
+uint32_t Dependency_getDependenciesForTrace_result::read(::apache::thrift::protocol::TProtocol* iprot) {
+
+ ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
+ uint32_t xfer = 0;
+ std::string fname;
+ ::apache::thrift::protocol::TType ftype;
+ int16_t fid;
+
+ xfer += iprot->readStructBegin(fname);
+
+ using ::apache::thrift::protocol::TProtocolException;
+
+
+ while (true)
+ {
+ xfer += iprot->readFieldBegin(fname, ftype, fid);
+ if (ftype == ::apache::thrift::protocol::T_STOP) {
+ break;
+ }
+ switch (fid)
+ {
+ case 0:
+ if (ftype == ::apache::thrift::protocol::T_STRUCT) {
+ xfer += this->success.read(iprot);
+ this->__isset.success = true;
+ } else {
+ xfer += iprot->skip(ftype);
+ }
+ break;
+ default:
+ xfer += iprot->skip(ftype);
+ break;
+ }
+ xfer += iprot->readFieldEnd();
+ }
+
+ xfer += iprot->readStructEnd();
+
+ return xfer;
+}
+
+uint32_t Dependency_getDependenciesForTrace_result::write(::apache::thrift::protocol::TProtocol* oprot) const {
+
+ uint32_t xfer = 0;
+
+ xfer += oprot->writeStructBegin("Dependency_getDependenciesForTrace_result");
+
+ if (this->__isset.success) {
+ xfer += oprot->writeFieldBegin("success", ::apache::thrift::protocol::T_STRUCT, 0);
+ xfer += this->success.write(oprot);
+ xfer += oprot->writeFieldEnd();
+ }
+ xfer += oprot->writeFieldStop();
+ xfer += oprot->writeStructEnd();
+ return xfer;
+}
+
+
+Dependency_getDependenciesForTrace_presult::~Dependency_getDependenciesForTrace_presult() throw() {
+}
+
+
+uint32_t Dependency_getDependenciesForTrace_presult::read(::apache::thrift::protocol::TProtocol* iprot) {
+
+ ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
+ uint32_t xfer = 0;
+ std::string fname;
+ ::apache::thrift::protocol::TType ftype;
+ int16_t fid;
+
+ xfer += iprot->readStructBegin(fname);
+
+ using ::apache::thrift::protocol::TProtocolException;
+
+
+ while (true)
+ {
+ xfer += iprot->readFieldBegin(fname, ftype, fid);
+ if (ftype == ::apache::thrift::protocol::T_STOP) {
+ break;
+ }
+ switch (fid)
+ {
+ case 0:
+ if (ftype == ::apache::thrift::protocol::T_STRUCT) {
+ xfer += (*(this->success)).read(iprot);
+ this->__isset.success = true;
+ } else {
+ xfer += iprot->skip(ftype);
+ }
+ break;
+ default:
+ xfer += iprot->skip(ftype);
+ break;
+ }
+ xfer += iprot->readFieldEnd();
+ }
+
+ xfer += iprot->readStructEnd();
+
+ return xfer;
+}
+
+
+Dependency_saveDependencies_args::~Dependency_saveDependencies_args() throw() {
+}
+
+
+uint32_t Dependency_saveDependencies_args::read(::apache::thrift::protocol::TProtocol* iprot) {
+
+ ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
+ uint32_t xfer = 0;
+ std::string fname;
+ ::apache::thrift::protocol::TType ftype;
+ int16_t fid;
+
+ xfer += iprot->readStructBegin(fname);
+
+ using ::apache::thrift::protocol::TProtocolException;
+
+
+ while (true)
+ {
+ xfer += iprot->readFieldBegin(fname, ftype, fid);
+ if (ftype == ::apache::thrift::protocol::T_STOP) {
+ break;
+ }
+ switch (fid)
+ {
+ case 1:
+ if (ftype == ::apache::thrift::protocol::T_STRUCT) {
+ xfer += this->dependencies.read(iprot);
+ this->__isset.dependencies = true;
+ } else {
+ xfer += iprot->skip(ftype);
+ }
+ break;
+ default:
+ xfer += iprot->skip(ftype);
+ break;
+ }
+ xfer += iprot->readFieldEnd();
+ }
+
+ xfer += iprot->readStructEnd();
+
+ return xfer;
+}
+
+uint32_t Dependency_saveDependencies_args::write(::apache::thrift::protocol::TProtocol* oprot) const {
+ uint32_t xfer = 0;
+ ::apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
+ xfer += oprot->writeStructBegin("Dependency_saveDependencies_args");
+
+ xfer += oprot->writeFieldBegin("dependencies", ::apache::thrift::protocol::T_STRUCT, 1);
+ xfer += this->dependencies.write(oprot);
+ xfer += oprot->writeFieldEnd();
+
+ xfer += oprot->writeFieldStop();
+ xfer += oprot->writeStructEnd();
+ return xfer;
+}
+
+
+Dependency_saveDependencies_pargs::~Dependency_saveDependencies_pargs() throw() {
+}
+
+
+uint32_t Dependency_saveDependencies_pargs::write(::apache::thrift::protocol::TProtocol* oprot) const {
+ uint32_t xfer = 0;
+ ::apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
+ xfer += oprot->writeStructBegin("Dependency_saveDependencies_pargs");
+
+ xfer += oprot->writeFieldBegin("dependencies", ::apache::thrift::protocol::T_STRUCT, 1);
+ xfer += (*(this->dependencies)).write(oprot);
+ xfer += oprot->writeFieldEnd();
+
+ xfer += oprot->writeFieldStop();
+ xfer += oprot->writeStructEnd();
+ return xfer;
+}
+
+void DependencyClient::getDependenciesForTrace(Dependencies& _return, const std::string& traceId)
+{
+ send_getDependenciesForTrace(traceId);
+ recv_getDependenciesForTrace(_return);
+}
+
+void DependencyClient::send_getDependenciesForTrace(const std::string& traceId)
+{
+ int32_t cseqid = 0;
+ oprot_->writeMessageBegin("getDependenciesForTrace", ::apache::thrift::protocol::T_CALL, cseqid);
+
+ Dependency_getDependenciesForTrace_pargs args;
+ args.traceId = &traceId;
+ args.write(oprot_);
+
+ oprot_->writeMessageEnd();
+ oprot_->getTransport()->writeEnd();
+ oprot_->getTransport()->flush();
+}
+
+void DependencyClient::recv_getDependenciesForTrace(Dependencies& _return)
+{
+
+ int32_t rseqid = 0;
+ std::string fname;
+ ::apache::thrift::protocol::TMessageType mtype;
+
+ iprot_->readMessageBegin(fname, mtype, rseqid);
+ if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
+ ::apache::thrift::TApplicationException x;
+ x.read(iprot_);
+ iprot_->readMessageEnd();
+ iprot_->getTransport()->readEnd();
+ throw x;
+ }
+ if (mtype != ::apache::thrift::protocol::T_REPLY) {
+ iprot_->skip(::apache::thrift::protocol::T_STRUCT);
+ iprot_->readMessageEnd();
+ iprot_->getTransport()->readEnd();
+ }
+ if (fname.compare("getDependenciesForTrace") != 0) {
+ iprot_->skip(::apache::thrift::protocol::T_STRUCT);
+ iprot_->readMessageEnd();
+ iprot_->getTransport()->readEnd();
+ }
+ Dependency_getDependenciesForTrace_presult result;
+ result.success = &_return;
+ result.read(iprot_);
+ iprot_->readMessageEnd();
+ iprot_->getTransport()->readEnd();
+
+ if (result.__isset.success) {
+ // _return pointer has now been filled
+ return;
+ }
+ throw ::apache::thrift::TApplicationException(::apache::thrift::TApplicationException::MISSING_RESULT, "getDependenciesForTrace failed: unknown result");
+}
+
+void DependencyClient::saveDependencies(const Dependencies& dependencies)
+{
+ send_saveDependencies(dependencies);
+}
+
+void DependencyClient::send_saveDependencies(const Dependencies& dependencies)
+{
+ int32_t cseqid = 0;
+ oprot_->writeMessageBegin("saveDependencies", ::apache::thrift::protocol::T_ONEWAY, cseqid);
+
+ Dependency_saveDependencies_pargs args;
+ args.dependencies = &dependencies;
+ args.write(oprot_);
+
+ oprot_->writeMessageEnd();
+ oprot_->getTransport()->writeEnd();
+ oprot_->getTransport()->flush();
+}
+
+bool DependencyProcessor::dispatchCall(::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, const std::string& fname, int32_t seqid, void* callContext) {
+ ProcessMap::iterator pfn;
+ pfn = processMap_.find(fname);
+ if (pfn == processMap_.end()) {
+ iprot->skip(::apache::thrift::protocol::T_STRUCT);
+ iprot->readMessageEnd();
+ iprot->getTransport()->readEnd();
+ ::apache::thrift::TApplicationException x(::apache::thrift::TApplicationException::UNKNOWN_METHOD, "Invalid method name: '"+fname+"'");
+ oprot->writeMessageBegin(fname, ::apache::thrift::protocol::T_EXCEPTION, seqid);
+ x.write(oprot);
+ oprot->writeMessageEnd();
+ oprot->getTransport()->writeEnd();
+ oprot->getTransport()->flush();
+ return true;
+ }
+ (this->*(pfn->second))(seqid, iprot, oprot, callContext);
+ return true;
+}
+
+void DependencyProcessor::process_getDependenciesForTrace(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext)
+{
+ void* ctx = NULL;
+ if (this->eventHandler_.get() != NULL) {
+ ctx = this->eventHandler_->getContext("Dependency.getDependenciesForTrace", callContext);
+ }
+ ::apache::thrift::TProcessorContextFreer freer(this->eventHandler_.get(), ctx, "Dependency.getDependenciesForTrace");
+
+ if (this->eventHandler_.get() != NULL) {
+ this->eventHandler_->preRead(ctx, "Dependency.getDependenciesForTrace");
+ }
+
+ Dependency_getDependenciesForTrace_args args;
+ args.read(iprot);
+ iprot->readMessageEnd();
+ uint32_t bytes = iprot->getTransport()->readEnd();
+
+ if (this->eventHandler_.get() != NULL) {
+ this->eventHandler_->postRead(ctx, "Dependency.getDependenciesForTrace", bytes);
+ }
+
+ Dependency_getDependenciesForTrace_result result;
+ try {
+ iface_->getDependenciesForTrace(result.success, args.traceId);
+ result.__isset.success = true;
+ } catch (const std::exception& e) {
+ if (this->eventHandler_.get() != NULL) {
+ this->eventHandler_->handlerError(ctx, "Dependency.getDependenciesForTrace");
+ }
+
+ ::apache::thrift::TApplicationException x(e.what());
+ oprot->writeMessageBegin("getDependenciesForTrace", ::apache::thrift::protocol::T_EXCEPTION, seqid);
+ x.write(oprot);
+ oprot->writeMessageEnd();
+ oprot->getTransport()->writeEnd();
+ oprot->getTransport()->flush();
+ return;
+ }
+
+ if (this->eventHandler_.get() != NULL) {
+ this->eventHandler_->preWrite(ctx, "Dependency.getDependenciesForTrace");
+ }
+
+ oprot->writeMessageBegin("getDependenciesForTrace", ::apache::thrift::protocol::T_REPLY, seqid);
+ result.write(oprot);
+ oprot->writeMessageEnd();
+ bytes = oprot->getTransport()->writeEnd();
+ oprot->getTransport()->flush();
+
+ if (this->eventHandler_.get() != NULL) {
+ this->eventHandler_->postWrite(ctx, "Dependency.getDependenciesForTrace", bytes);
+ }
+}
+
+void DependencyProcessor::process_saveDependencies(int32_t, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol*, void* callContext)
+{
+ void* ctx = NULL;
+ if (this->eventHandler_.get() != NULL) {
+ ctx = this->eventHandler_->getContext("Dependency.saveDependencies", callContext);
+ }
+ ::apache::thrift::TProcessorContextFreer freer(this->eventHandler_.get(), ctx, "Dependency.saveDependencies");
+
+ if (this->eventHandler_.get() != NULL) {
+ this->eventHandler_->preRead(ctx, "Dependency.saveDependencies");
+ }
+
+ Dependency_saveDependencies_args args;
+ args.read(iprot);
+ iprot->readMessageEnd();
+ uint32_t bytes = iprot->getTransport()->readEnd();
+
+ if (this->eventHandler_.get() != NULL) {
+ this->eventHandler_->postRead(ctx, "Dependency.saveDependencies", bytes);
+ }
+
+ try {
+ iface_->saveDependencies(args.dependencies);
+ } catch (const std::exception&) {
+ if (this->eventHandler_.get() != NULL) {
+ this->eventHandler_->handlerError(ctx, "Dependency.saveDependencies");
+ }
+ return;
+ }
+
+ if (this->eventHandler_.get() != NULL) {
+ this->eventHandler_->asyncComplete(ctx, "Dependency.saveDependencies");
+ }
+
+ return;
+}
+
+::std::shared_ptr< ::apache::thrift::TProcessor > DependencyProcessorFactory::getProcessor(const ::apache::thrift::TConnectionInfo& connInfo) {
+ ::apache::thrift::ReleaseHandler< DependencyIfFactory > cleanup(handlerFactory_);
+ ::std::shared_ptr< DependencyIf > handler(handlerFactory_->getHandler(connInfo), cleanup);
+ ::std::shared_ptr< ::apache::thrift::TProcessor > processor(new DependencyProcessor(handler));
+ return processor;
+}
+
+void DependencyConcurrentClient::getDependenciesForTrace(Dependencies& _return, const std::string& traceId)
+{
+ int32_t seqid = send_getDependenciesForTrace(traceId);
+ recv_getDependenciesForTrace(_return, seqid);
+}
+
+int32_t DependencyConcurrentClient::send_getDependenciesForTrace(const std::string& traceId)
+{
+ int32_t cseqid = this->sync_.generateSeqId();
+ ::apache::thrift::async::TConcurrentSendSentry sentry(&this->sync_);
+ oprot_->writeMessageBegin("getDependenciesForTrace", ::apache::thrift::protocol::T_CALL, cseqid);
+
+ Dependency_getDependenciesForTrace_pargs args;
+ args.traceId = &traceId;
+ args.write(oprot_);
+
+ oprot_->writeMessageEnd();
+ oprot_->getTransport()->writeEnd();
+ oprot_->getTransport()->flush();
+
+ sentry.commit();
+ return cseqid;
+}
+
+void DependencyConcurrentClient::recv_getDependenciesForTrace(Dependencies& _return, const int32_t seqid)
+{
+
+ int32_t rseqid = 0;
+ std::string fname;
+ ::apache::thrift::protocol::TMessageType mtype;
+
+ // the read mutex gets dropped and reacquired as part of waitForWork()
+ // The destructor of this sentry wakes up other clients
+ ::apache::thrift::async::TConcurrentRecvSentry sentry(&this->sync_, seqid);
+
+ while(true) {
+ if(!this->sync_.getPending(fname, mtype, rseqid)) {
+ iprot_->readMessageBegin(fname, mtype, rseqid);
+ }
+ if(seqid == rseqid) {
+ if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
+ ::apache::thrift::TApplicationException x;
+ x.read(iprot_);
+ iprot_->readMessageEnd();
+ iprot_->getTransport()->readEnd();
+ sentry.commit();
+ throw x;
+ }
+ if (mtype != ::apache::thrift::protocol::T_REPLY) {
+ iprot_->skip(::apache::thrift::protocol::T_STRUCT);
+ iprot_->readMessageEnd();
+ iprot_->getTransport()->readEnd();
+ }
+ if (fname.compare("getDependenciesForTrace") != 0) {
+ iprot_->skip(::apache::thrift::protocol::T_STRUCT);
+ iprot_->readMessageEnd();
+ iprot_->getTransport()->readEnd();
+
+ // in a bad state, don't commit
+ using ::apache::thrift::protocol::TProtocolException;
+ throw TProtocolException(TProtocolException::INVALID_DATA);
+ }
+ Dependency_getDependenciesForTrace_presult result;
+ result.success = &_return;
+ result.read(iprot_);
+ iprot_->readMessageEnd();
+ iprot_->getTransport()->readEnd();
+
+ if (result.__isset.success) {
+ // _return pointer has now been filled
+ sentry.commit();
+ return;
+ }
+ // in a bad state, don't commit
+ throw ::apache::thrift::TApplicationException(::apache::thrift::TApplicationException::MISSING_RESULT, "getDependenciesForTrace failed: unknown result");
+ }
+ // seqid != rseqid
+ this->sync_.updatePending(fname, mtype, rseqid);
+
+ // this will temporarily unlock the readMutex, and let other clients get work done
+ this->sync_.waitForWork(seqid);
+ } // end while(true)
+}
+
+void DependencyConcurrentClient::saveDependencies(const Dependencies& dependencies)
+{
+ send_saveDependencies(dependencies);
+}
+
+void DependencyConcurrentClient::send_saveDependencies(const Dependencies& dependencies)
+{
+ int32_t cseqid = 0;
+ ::apache::thrift::async::TConcurrentSendSentry sentry(&this->sync_);
+ oprot_->writeMessageBegin("saveDependencies", ::apache::thrift::protocol::T_ONEWAY, cseqid);
+
+ Dependency_saveDependencies_pargs args;
+ args.dependencies = &dependencies;
+ args.write(oprot_);
+
+ oprot_->writeMessageEnd();
+ oprot_->getTransport()->writeEnd();
+ oprot_->getTransport()->flush();
+
+ sentry.commit();
+}
+
+}} // namespace
+
diff --git a/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/thrift-gen/Dependency.h b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/thrift-gen/Dependency.h
new file mode 100644
index 000000000..648198b1a
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/thrift-gen/Dependency.h
@@ -0,0 +1,358 @@
+/**
+ * Autogenerated by Thrift Compiler (0.11.0)
+ *
+ * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
+ * @generated
+ */
+#ifndef Dependency_H
+#define Dependency_H
+
+#include <thrift/TDispatchProcessor.h>
+#include <thrift/async/TConcurrentClientSyncInfo.h>
+#include "dependency_types.h"
+
+namespace jaegertracing { namespace thrift {
+
+#ifdef _MSC_VER
+ #pragma warning( push )
+ #pragma warning (disable : 4250 ) //inheriting methods via dominance
+#endif
+
+class DependencyIf {
+ public:
+ virtual ~DependencyIf() {}
+ virtual void getDependenciesForTrace(Dependencies& _return, const std::string& traceId) = 0;
+ virtual void saveDependencies(const Dependencies& dependencies) = 0;
+};
+
+class DependencyIfFactory {
+ public:
+ typedef DependencyIf Handler;
+
+ virtual ~DependencyIfFactory() {}
+
+ virtual DependencyIf* getHandler(const ::apache::thrift::TConnectionInfo& connInfo) = 0;
+ virtual void releaseHandler(DependencyIf* /* handler */) = 0;
+};
+
+class DependencyIfSingletonFactory : virtual public DependencyIfFactory {
+ public:
+ DependencyIfSingletonFactory(const ::std::shared_ptr<DependencyIf>& iface) : iface_(iface) {}
+ virtual ~DependencyIfSingletonFactory() {}
+
+ virtual DependencyIf* getHandler(const ::apache::thrift::TConnectionInfo&) {
+ return iface_.get();
+ }
+ virtual void releaseHandler(DependencyIf* /* handler */) {}
+
+ protected:
+ ::std::shared_ptr<DependencyIf> iface_;
+};
+
+class DependencyNull : virtual public DependencyIf {
+ public:
+ virtual ~DependencyNull() {}
+ void getDependenciesForTrace(Dependencies& /* _return */, const std::string& /* traceId */) {
+ return;
+ }
+ void saveDependencies(const Dependencies& /* dependencies */) {
+ return;
+ }
+};
+
+
+class Dependency_getDependenciesForTrace_args {
+ public:
+
+ Dependency_getDependenciesForTrace_args(const Dependency_getDependenciesForTrace_args&);
+ Dependency_getDependenciesForTrace_args& operator=(const Dependency_getDependenciesForTrace_args&);
+ Dependency_getDependenciesForTrace_args() : traceId() {
+ }
+
+ virtual ~Dependency_getDependenciesForTrace_args() throw();
+ std::string traceId;
+
+ void __set_traceId(const std::string& val);
+
+ bool operator == (const Dependency_getDependenciesForTrace_args & rhs) const
+ {
+ if (!(traceId == rhs.traceId))
+ return false;
+ return true;
+ }
+ bool operator != (const Dependency_getDependenciesForTrace_args &rhs) const {
+ return !(*this == rhs);
+ }
+
+ bool operator < (const Dependency_getDependenciesForTrace_args & ) const;
+
+ uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
+ uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;
+
+};
+
+
+class Dependency_getDependenciesForTrace_pargs {
+ public:
+
+
+ virtual ~Dependency_getDependenciesForTrace_pargs() throw();
+ const std::string* traceId;
+
+ uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;
+
+};
+
+typedef struct _Dependency_getDependenciesForTrace_result__isset {
+ _Dependency_getDependenciesForTrace_result__isset() : success(false) {}
+ bool success :1;
+} _Dependency_getDependenciesForTrace_result__isset;
+
+class Dependency_getDependenciesForTrace_result {
+ public:
+
+ Dependency_getDependenciesForTrace_result(const Dependency_getDependenciesForTrace_result&);
+ Dependency_getDependenciesForTrace_result& operator=(const Dependency_getDependenciesForTrace_result&);
+ Dependency_getDependenciesForTrace_result() {
+ }
+
+ virtual ~Dependency_getDependenciesForTrace_result() throw();
+ Dependencies success;
+
+ _Dependency_getDependenciesForTrace_result__isset __isset;
+
+ void __set_success(const Dependencies& val);
+
+ bool operator == (const Dependency_getDependenciesForTrace_result & rhs) const
+ {
+ if (!(success == rhs.success))
+ return false;
+ return true;
+ }
+ bool operator != (const Dependency_getDependenciesForTrace_result &rhs) const {
+ return !(*this == rhs);
+ }
+
+ bool operator < (const Dependency_getDependenciesForTrace_result & ) const;
+
+ uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
+ uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;
+
+};
+
+typedef struct _Dependency_getDependenciesForTrace_presult__isset {
+ _Dependency_getDependenciesForTrace_presult__isset() : success(false) {}
+ bool success :1;
+} _Dependency_getDependenciesForTrace_presult__isset;
+
+class Dependency_getDependenciesForTrace_presult {
+ public:
+
+
+ virtual ~Dependency_getDependenciesForTrace_presult() throw();
+ Dependencies* success;
+
+ _Dependency_getDependenciesForTrace_presult__isset __isset;
+
+ uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
+
+};
+
+typedef struct _Dependency_saveDependencies_args__isset {
+ _Dependency_saveDependencies_args__isset() : dependencies(false) {}
+ bool dependencies :1;
+} _Dependency_saveDependencies_args__isset;
+
+class Dependency_saveDependencies_args {
+ public:
+
+ Dependency_saveDependencies_args(const Dependency_saveDependencies_args&);
+ Dependency_saveDependencies_args& operator=(const Dependency_saveDependencies_args&);
+ Dependency_saveDependencies_args() {
+ }
+
+ virtual ~Dependency_saveDependencies_args() throw();
+ Dependencies dependencies;
+
+ _Dependency_saveDependencies_args__isset __isset;
+
+ void __set_dependencies(const Dependencies& val);
+
+ bool operator == (const Dependency_saveDependencies_args & rhs) const
+ {
+ if (!(dependencies == rhs.dependencies))
+ return false;
+ return true;
+ }
+ bool operator != (const Dependency_saveDependencies_args &rhs) const {
+ return !(*this == rhs);
+ }
+
+ bool operator < (const Dependency_saveDependencies_args & ) const;
+
+ uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
+ uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;
+
+};
+
+
+class Dependency_saveDependencies_pargs {
+ public:
+
+
+ virtual ~Dependency_saveDependencies_pargs() throw();
+ const Dependencies* dependencies;
+
+ uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;
+
+};
+
+class DependencyClient : virtual public DependencyIf {
+ public:
+ DependencyClient(std::shared_ptr< ::apache::thrift::protocol::TProtocol> prot) {
+ setProtocol(prot);
+ }
+ DependencyClient(std::shared_ptr< ::apache::thrift::protocol::TProtocol> iprot, std::shared_ptr< ::apache::thrift::protocol::TProtocol> oprot) {
+ setProtocol(iprot,oprot);
+ }
+ private:
+ void setProtocol(std::shared_ptr< ::apache::thrift::protocol::TProtocol> prot) {
+ setProtocol(prot,prot);
+ }
+ void setProtocol(std::shared_ptr< ::apache::thrift::protocol::TProtocol> iprot, std::shared_ptr< ::apache::thrift::protocol::TProtocol> oprot) {
+ piprot_=iprot;
+ poprot_=oprot;
+ iprot_ = iprot.get();
+ oprot_ = oprot.get();
+ }
+ public:
+ std::shared_ptr< ::apache::thrift::protocol::TProtocol> getInputProtocol() {
+ return piprot_;
+ }
+ std::shared_ptr< ::apache::thrift::protocol::TProtocol> getOutputProtocol() {
+ return poprot_;
+ }
+ void getDependenciesForTrace(Dependencies& _return, const std::string& traceId);
+ void send_getDependenciesForTrace(const std::string& traceId);
+ void recv_getDependenciesForTrace(Dependencies& _return);
+ void saveDependencies(const Dependencies& dependencies);
+ void send_saveDependencies(const Dependencies& dependencies);
+ protected:
+ std::shared_ptr< ::apache::thrift::protocol::TProtocol> piprot_;
+ std::shared_ptr< ::apache::thrift::protocol::TProtocol> poprot_;
+ ::apache::thrift::protocol::TProtocol* iprot_;
+ ::apache::thrift::protocol::TProtocol* oprot_;
+};
+
+class DependencyProcessor : public ::apache::thrift::TDispatchProcessor {
+ protected:
+ ::std::shared_ptr<DependencyIf> iface_;
+ virtual bool dispatchCall(::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, const std::string& fname, int32_t seqid, void* callContext);
+ private:
+ typedef void (DependencyProcessor::*ProcessFunction)(int32_t, ::apache::thrift::protocol::TProtocol*, ::apache::thrift::protocol::TProtocol*, void*);
+ typedef std::map<std::string, ProcessFunction> ProcessMap;
+ ProcessMap processMap_;
+ void process_getDependenciesForTrace(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext);
+ void process_saveDependencies(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext);
+ public:
+ DependencyProcessor(::std::shared_ptr<DependencyIf> iface) :
+ iface_(iface) {
+ processMap_["getDependenciesForTrace"] = &DependencyProcessor::process_getDependenciesForTrace;
+ processMap_["saveDependencies"] = &DependencyProcessor::process_saveDependencies;
+ }
+
+ virtual ~DependencyProcessor() {}
+};
+
+class DependencyProcessorFactory : public ::apache::thrift::TProcessorFactory {
+ public:
+ DependencyProcessorFactory(const ::std::shared_ptr< DependencyIfFactory >& handlerFactory) :
+ handlerFactory_(handlerFactory) {}
+
+ ::std::shared_ptr< ::apache::thrift::TProcessor > getProcessor(const ::apache::thrift::TConnectionInfo& connInfo);
+
+ protected:
+ ::std::shared_ptr< DependencyIfFactory > handlerFactory_;
+};
+
+class DependencyMultiface : virtual public DependencyIf {
+ public:
+ DependencyMultiface(std::vector<std::shared_ptr<DependencyIf> >& ifaces) : ifaces_(ifaces) {
+ }
+ virtual ~DependencyMultiface() {}
+ protected:
+ std::vector<std::shared_ptr<DependencyIf> > ifaces_;
+ DependencyMultiface() {}
+ void add(::std::shared_ptr<DependencyIf> iface) {
+ ifaces_.push_back(iface);
+ }
+ public:
+ void getDependenciesForTrace(Dependencies& _return, const std::string& traceId) {
+ size_t sz = ifaces_.size();
+ size_t i = 0;
+ for (; i < (sz - 1); ++i) {
+ ifaces_[i]->getDependenciesForTrace(_return, traceId);
+ }
+ ifaces_[i]->getDependenciesForTrace(_return, traceId);
+ return;
+ }
+
+ void saveDependencies(const Dependencies& dependencies) {
+ size_t sz = ifaces_.size();
+ size_t i = 0;
+ for (; i < (sz - 1); ++i) {
+ ifaces_[i]->saveDependencies(dependencies);
+ }
+ ifaces_[i]->saveDependencies(dependencies);
+ }
+
+};
+
+// The 'concurrent' client is a thread safe client that correctly handles
+// out of order responses. It is slower than the regular client, so should
+// only be used when you need to share a connection among multiple threads
+class DependencyConcurrentClient : virtual public DependencyIf {
+ public:
+ DependencyConcurrentClient(std::shared_ptr< ::apache::thrift::protocol::TProtocol> prot) {
+ setProtocol(prot);
+ }
+ DependencyConcurrentClient(std::shared_ptr< ::apache::thrift::protocol::TProtocol> iprot, std::shared_ptr< ::apache::thrift::protocol::TProtocol> oprot) {
+ setProtocol(iprot,oprot);
+ }
+ private:
+ void setProtocol(std::shared_ptr< ::apache::thrift::protocol::TProtocol> prot) {
+ setProtocol(prot,prot);
+ }
+ void setProtocol(std::shared_ptr< ::apache::thrift::protocol::TProtocol> iprot, std::shared_ptr< ::apache::thrift::protocol::TProtocol> oprot) {
+ piprot_=iprot;
+ poprot_=oprot;
+ iprot_ = iprot.get();
+ oprot_ = oprot.get();
+ }
+ public:
+ std::shared_ptr< ::apache::thrift::protocol::TProtocol> getInputProtocol() {
+ return piprot_;
+ }
+ std::shared_ptr< ::apache::thrift::protocol::TProtocol> getOutputProtocol() {
+ return poprot_;
+ }
+ void getDependenciesForTrace(Dependencies& _return, const std::string& traceId);
+ int32_t send_getDependenciesForTrace(const std::string& traceId);
+ void recv_getDependenciesForTrace(Dependencies& _return, const int32_t seqid);
+ void saveDependencies(const Dependencies& dependencies);
+ void send_saveDependencies(const Dependencies& dependencies);
+ protected:
+ std::shared_ptr< ::apache::thrift::protocol::TProtocol> piprot_;
+ std::shared_ptr< ::apache::thrift::protocol::TProtocol> poprot_;
+ ::apache::thrift::protocol::TProtocol* iprot_;
+ ::apache::thrift::protocol::TProtocol* oprot_;
+ ::apache::thrift::async::TConcurrentClientSyncInfo sync_;
+};
+
+#ifdef _MSC_VER
+ #pragma warning( pop )
+#endif
+
+}} // namespace
+
+#endif
diff --git a/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/thrift-gen/SamplingManager.cpp b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/thrift-gen/SamplingManager.cpp
new file mode 100644
index 000000000..0da5d87cd
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/thrift-gen/SamplingManager.cpp
@@ -0,0 +1,421 @@
+/**
+ * Autogenerated by Thrift Compiler (0.11.0)
+ *
+ * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
+ * @generated
+ */
+#include "SamplingManager.h"
+
+namespace jaegertracing { namespace sampling_manager { namespace thrift {
+
+
+SamplingManager_getSamplingStrategy_args::~SamplingManager_getSamplingStrategy_args() throw() {
+}
+
+
+uint32_t SamplingManager_getSamplingStrategy_args::read(::apache::thrift::protocol::TProtocol* iprot) {
+
+ ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
+ uint32_t xfer = 0;
+ std::string fname;
+ ::apache::thrift::protocol::TType ftype;
+ int16_t fid;
+
+ xfer += iprot->readStructBegin(fname);
+
+ using ::apache::thrift::protocol::TProtocolException;
+
+
+ while (true)
+ {
+ xfer += iprot->readFieldBegin(fname, ftype, fid);
+ if (ftype == ::apache::thrift::protocol::T_STOP) {
+ break;
+ }
+ switch (fid)
+ {
+ case 1:
+ if (ftype == ::apache::thrift::protocol::T_STRING) {
+ xfer += iprot->readString(this->serviceName);
+ this->__isset.serviceName = true;
+ } else {
+ xfer += iprot->skip(ftype);
+ }
+ break;
+ default:
+ xfer += iprot->skip(ftype);
+ break;
+ }
+ xfer += iprot->readFieldEnd();
+ }
+
+ xfer += iprot->readStructEnd();
+
+ return xfer;
+}
+
+uint32_t SamplingManager_getSamplingStrategy_args::write(::apache::thrift::protocol::TProtocol* oprot) const {
+ uint32_t xfer = 0;
+ ::apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
+ xfer += oprot->writeStructBegin("SamplingManager_getSamplingStrategy_args");
+
+ xfer += oprot->writeFieldBegin("serviceName", ::apache::thrift::protocol::T_STRING, 1);
+ xfer += oprot->writeString(this->serviceName);
+ xfer += oprot->writeFieldEnd();
+
+ xfer += oprot->writeFieldStop();
+ xfer += oprot->writeStructEnd();
+ return xfer;
+}
+
+
+SamplingManager_getSamplingStrategy_pargs::~SamplingManager_getSamplingStrategy_pargs() throw() {
+}
+
+
+uint32_t SamplingManager_getSamplingStrategy_pargs::write(::apache::thrift::protocol::TProtocol* oprot) const {
+ uint32_t xfer = 0;
+ ::apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
+ xfer += oprot->writeStructBegin("SamplingManager_getSamplingStrategy_pargs");
+
+ xfer += oprot->writeFieldBegin("serviceName", ::apache::thrift::protocol::T_STRING, 1);
+ xfer += oprot->writeString((*(this->serviceName)));
+ xfer += oprot->writeFieldEnd();
+
+ xfer += oprot->writeFieldStop();
+ xfer += oprot->writeStructEnd();
+ return xfer;
+}
+
+
+SamplingManager_getSamplingStrategy_result::~SamplingManager_getSamplingStrategy_result() throw() {
+}
+
+
+uint32_t SamplingManager_getSamplingStrategy_result::read(::apache::thrift::protocol::TProtocol* iprot) {
+
+ ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
+ uint32_t xfer = 0;
+ std::string fname;
+ ::apache::thrift::protocol::TType ftype;
+ int16_t fid;
+
+ xfer += iprot->readStructBegin(fname);
+
+ using ::apache::thrift::protocol::TProtocolException;
+
+
+ while (true)
+ {
+ xfer += iprot->readFieldBegin(fname, ftype, fid);
+ if (ftype == ::apache::thrift::protocol::T_STOP) {
+ break;
+ }
+ switch (fid)
+ {
+ case 0:
+ if (ftype == ::apache::thrift::protocol::T_STRUCT) {
+ xfer += this->success.read(iprot);
+ this->__isset.success = true;
+ } else {
+ xfer += iprot->skip(ftype);
+ }
+ break;
+ default:
+ xfer += iprot->skip(ftype);
+ break;
+ }
+ xfer += iprot->readFieldEnd();
+ }
+
+ xfer += iprot->readStructEnd();
+
+ return xfer;
+}
+
+uint32_t SamplingManager_getSamplingStrategy_result::write(::apache::thrift::protocol::TProtocol* oprot) const {
+
+ uint32_t xfer = 0;
+
+ xfer += oprot->writeStructBegin("SamplingManager_getSamplingStrategy_result");
+
+ if (this->__isset.success) {
+ xfer += oprot->writeFieldBegin("success", ::apache::thrift::protocol::T_STRUCT, 0);
+ xfer += this->success.write(oprot);
+ xfer += oprot->writeFieldEnd();
+ }
+ xfer += oprot->writeFieldStop();
+ xfer += oprot->writeStructEnd();
+ return xfer;
+}
+
+
+SamplingManager_getSamplingStrategy_presult::~SamplingManager_getSamplingStrategy_presult() throw() {
+}
+
+
+uint32_t SamplingManager_getSamplingStrategy_presult::read(::apache::thrift::protocol::TProtocol* iprot) {
+
+ ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
+ uint32_t xfer = 0;
+ std::string fname;
+ ::apache::thrift::protocol::TType ftype;
+ int16_t fid;
+
+ xfer += iprot->readStructBegin(fname);
+
+ using ::apache::thrift::protocol::TProtocolException;
+
+
+ while (true)
+ {
+ xfer += iprot->readFieldBegin(fname, ftype, fid);
+ if (ftype == ::apache::thrift::protocol::T_STOP) {
+ break;
+ }
+ switch (fid)
+ {
+ case 0:
+ if (ftype == ::apache::thrift::protocol::T_STRUCT) {
+ xfer += (*(this->success)).read(iprot);
+ this->__isset.success = true;
+ } else {
+ xfer += iprot->skip(ftype);
+ }
+ break;
+ default:
+ xfer += iprot->skip(ftype);
+ break;
+ }
+ xfer += iprot->readFieldEnd();
+ }
+
+ xfer += iprot->readStructEnd();
+
+ return xfer;
+}
+
+void SamplingManagerClient::getSamplingStrategy(SamplingStrategyResponse& _return, const std::string& serviceName)
+{
+ send_getSamplingStrategy(serviceName);
+ recv_getSamplingStrategy(_return);
+}
+
+void SamplingManagerClient::send_getSamplingStrategy(const std::string& serviceName)
+{
+ int32_t cseqid = 0;
+ oprot_->writeMessageBegin("getSamplingStrategy", ::apache::thrift::protocol::T_CALL, cseqid);
+
+ SamplingManager_getSamplingStrategy_pargs args;
+ args.serviceName = &serviceName;
+ args.write(oprot_);
+
+ oprot_->writeMessageEnd();
+ oprot_->getTransport()->writeEnd();
+ oprot_->getTransport()->flush();
+}
+
+void SamplingManagerClient::recv_getSamplingStrategy(SamplingStrategyResponse& _return)
+{
+
+ int32_t rseqid = 0;
+ std::string fname;
+ ::apache::thrift::protocol::TMessageType mtype;
+
+ iprot_->readMessageBegin(fname, mtype, rseqid);
+ if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
+ ::apache::thrift::TApplicationException x;
+ x.read(iprot_);
+ iprot_->readMessageEnd();
+ iprot_->getTransport()->readEnd();
+ throw x;
+ }
+ if (mtype != ::apache::thrift::protocol::T_REPLY) {
+ iprot_->skip(::apache::thrift::protocol::T_STRUCT);
+ iprot_->readMessageEnd();
+ iprot_->getTransport()->readEnd();
+ }
+ if (fname.compare("getSamplingStrategy") != 0) {
+ iprot_->skip(::apache::thrift::protocol::T_STRUCT);
+ iprot_->readMessageEnd();
+ iprot_->getTransport()->readEnd();
+ }
+ SamplingManager_getSamplingStrategy_presult result;
+ result.success = &_return;
+ result.read(iprot_);
+ iprot_->readMessageEnd();
+ iprot_->getTransport()->readEnd();
+
+ if (result.__isset.success) {
+ // _return pointer has now been filled
+ return;
+ }
+ throw ::apache::thrift::TApplicationException(::apache::thrift::TApplicationException::MISSING_RESULT, "getSamplingStrategy failed: unknown result");
+}
+
+bool SamplingManagerProcessor::dispatchCall(::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, const std::string& fname, int32_t seqid, void* callContext) {
+ ProcessMap::iterator pfn;
+ pfn = processMap_.find(fname);
+ if (pfn == processMap_.end()) {
+ iprot->skip(::apache::thrift::protocol::T_STRUCT);
+ iprot->readMessageEnd();
+ iprot->getTransport()->readEnd();
+ ::apache::thrift::TApplicationException x(::apache::thrift::TApplicationException::UNKNOWN_METHOD, "Invalid method name: '"+fname+"'");
+ oprot->writeMessageBegin(fname, ::apache::thrift::protocol::T_EXCEPTION, seqid);
+ x.write(oprot);
+ oprot->writeMessageEnd();
+ oprot->getTransport()->writeEnd();
+ oprot->getTransport()->flush();
+ return true;
+ }
+ (this->*(pfn->second))(seqid, iprot, oprot, callContext);
+ return true;
+}
+
+void SamplingManagerProcessor::process_getSamplingStrategy(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext)
+{
+ void* ctx = NULL;
+ if (this->eventHandler_.get() != NULL) {
+ ctx = this->eventHandler_->getContext("SamplingManager.getSamplingStrategy", callContext);
+ }
+ ::apache::thrift::TProcessorContextFreer freer(this->eventHandler_.get(), ctx, "SamplingManager.getSamplingStrategy");
+
+ if (this->eventHandler_.get() != NULL) {
+ this->eventHandler_->preRead(ctx, "SamplingManager.getSamplingStrategy");
+ }
+
+ SamplingManager_getSamplingStrategy_args args;
+ args.read(iprot);
+ iprot->readMessageEnd();
+ uint32_t bytes = iprot->getTransport()->readEnd();
+
+ if (this->eventHandler_.get() != NULL) {
+ this->eventHandler_->postRead(ctx, "SamplingManager.getSamplingStrategy", bytes);
+ }
+
+ SamplingManager_getSamplingStrategy_result result;
+ try {
+ iface_->getSamplingStrategy(result.success, args.serviceName);
+ result.__isset.success = true;
+ } catch (const std::exception& e) {
+ if (this->eventHandler_.get() != NULL) {
+ this->eventHandler_->handlerError(ctx, "SamplingManager.getSamplingStrategy");
+ }
+
+ ::apache::thrift::TApplicationException x(e.what());
+ oprot->writeMessageBegin("getSamplingStrategy", ::apache::thrift::protocol::T_EXCEPTION, seqid);
+ x.write(oprot);
+ oprot->writeMessageEnd();
+ oprot->getTransport()->writeEnd();
+ oprot->getTransport()->flush();
+ return;
+ }
+
+ if (this->eventHandler_.get() != NULL) {
+ this->eventHandler_->preWrite(ctx, "SamplingManager.getSamplingStrategy");
+ }
+
+ oprot->writeMessageBegin("getSamplingStrategy", ::apache::thrift::protocol::T_REPLY, seqid);
+ result.write(oprot);
+ oprot->writeMessageEnd();
+ bytes = oprot->getTransport()->writeEnd();
+ oprot->getTransport()->flush();
+
+ if (this->eventHandler_.get() != NULL) {
+ this->eventHandler_->postWrite(ctx, "SamplingManager.getSamplingStrategy", bytes);
+ }
+}
+
+::std::shared_ptr< ::apache::thrift::TProcessor > SamplingManagerProcessorFactory::getProcessor(const ::apache::thrift::TConnectionInfo& connInfo) {
+ ::apache::thrift::ReleaseHandler< SamplingManagerIfFactory > cleanup(handlerFactory_);
+ ::std::shared_ptr< SamplingManagerIf > handler(handlerFactory_->getHandler(connInfo), cleanup);
+ ::std::shared_ptr< ::apache::thrift::TProcessor > processor(new SamplingManagerProcessor(handler));
+ return processor;
+}
+
+void SamplingManagerConcurrentClient::getSamplingStrategy(SamplingStrategyResponse& _return, const std::string& serviceName)
+{
+ int32_t seqid = send_getSamplingStrategy(serviceName);
+ recv_getSamplingStrategy(_return, seqid);
+}
+
+int32_t SamplingManagerConcurrentClient::send_getSamplingStrategy(const std::string& serviceName)
+{
+ int32_t cseqid = this->sync_.generateSeqId();
+ ::apache::thrift::async::TConcurrentSendSentry sentry(&this->sync_);
+ oprot_->writeMessageBegin("getSamplingStrategy", ::apache::thrift::protocol::T_CALL, cseqid);
+
+ SamplingManager_getSamplingStrategy_pargs args;
+ args.serviceName = &serviceName;
+ args.write(oprot_);
+
+ oprot_->writeMessageEnd();
+ oprot_->getTransport()->writeEnd();
+ oprot_->getTransport()->flush();
+
+ sentry.commit();
+ return cseqid;
+}
+
+void SamplingManagerConcurrentClient::recv_getSamplingStrategy(SamplingStrategyResponse& _return, const int32_t seqid)
+{
+
+ int32_t rseqid = 0;
+ std::string fname;
+ ::apache::thrift::protocol::TMessageType mtype;
+
+ // the read mutex gets dropped and reacquired as part of waitForWork()
+ // The destructor of this sentry wakes up other clients
+ ::apache::thrift::async::TConcurrentRecvSentry sentry(&this->sync_, seqid);
+
+ while(true) {
+ if(!this->sync_.getPending(fname, mtype, rseqid)) {
+ iprot_->readMessageBegin(fname, mtype, rseqid);
+ }
+ if(seqid == rseqid) {
+ if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
+ ::apache::thrift::TApplicationException x;
+ x.read(iprot_);
+ iprot_->readMessageEnd();
+ iprot_->getTransport()->readEnd();
+ sentry.commit();
+ throw x;
+ }
+ if (mtype != ::apache::thrift::protocol::T_REPLY) {
+ iprot_->skip(::apache::thrift::protocol::T_STRUCT);
+ iprot_->readMessageEnd();
+ iprot_->getTransport()->readEnd();
+ }
+ if (fname.compare("getSamplingStrategy") != 0) {
+ iprot_->skip(::apache::thrift::protocol::T_STRUCT);
+ iprot_->readMessageEnd();
+ iprot_->getTransport()->readEnd();
+
+ // in a bad state, don't commit
+ using ::apache::thrift::protocol::TProtocolException;
+ throw TProtocolException(TProtocolException::INVALID_DATA);
+ }
+ SamplingManager_getSamplingStrategy_presult result;
+ result.success = &_return;
+ result.read(iprot_);
+ iprot_->readMessageEnd();
+ iprot_->getTransport()->readEnd();
+
+ if (result.__isset.success) {
+ // _return pointer has now been filled
+ sentry.commit();
+ return;
+ }
+ // in a bad state, don't commit
+ throw ::apache::thrift::TApplicationException(::apache::thrift::TApplicationException::MISSING_RESULT, "getSamplingStrategy failed: unknown result");
+ }
+ // seqid != rseqid
+ this->sync_.updatePending(fname, mtype, rseqid);
+
+ // this will temporarily unlock the readMutex, and let other clients get work done
+ this->sync_.waitForWork(seqid);
+ } // end while(true)
+}
+
+}}} // namespace
+
diff --git a/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/thrift-gen/SamplingManager.h b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/thrift-gen/SamplingManager.h
new file mode 100644
index 000000000..1d67c618c
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/thrift-gen/SamplingManager.h
@@ -0,0 +1,296 @@
+/**
+ * Autogenerated by Thrift Compiler (0.11.0)
+ *
+ * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
+ * @generated
+ */
+#ifndef SamplingManager_H
+#define SamplingManager_H
+
+#include <thrift/TDispatchProcessor.h>
+#include <thrift/async/TConcurrentClientSyncInfo.h>
+#include "sampling_types.h"
+
+namespace jaegertracing { namespace sampling_manager { namespace thrift {
+
+#ifdef _MSC_VER
+ #pragma warning( push )
+ #pragma warning (disable : 4250 ) //inheriting methods via dominance
+#endif
+
+class SamplingManagerIf {
+ public:
+ virtual ~SamplingManagerIf() {}
+ virtual void getSamplingStrategy(SamplingStrategyResponse& _return, const std::string& serviceName) = 0;
+};
+
+class SamplingManagerIfFactory {
+ public:
+ typedef SamplingManagerIf Handler;
+
+ virtual ~SamplingManagerIfFactory() {}
+
+ virtual SamplingManagerIf* getHandler(const ::apache::thrift::TConnectionInfo& connInfo) = 0;
+ virtual void releaseHandler(SamplingManagerIf* /* handler */) = 0;
+};
+
+class SamplingManagerIfSingletonFactory : virtual public SamplingManagerIfFactory {
+ public:
+ SamplingManagerIfSingletonFactory(const ::std::shared_ptr<SamplingManagerIf>& iface) : iface_(iface) {}
+ virtual ~SamplingManagerIfSingletonFactory() {}
+
+ virtual SamplingManagerIf* getHandler(const ::apache::thrift::TConnectionInfo&) {
+ return iface_.get();
+ }
+ virtual void releaseHandler(SamplingManagerIf* /* handler */) {}
+
+ protected:
+ ::std::shared_ptr<SamplingManagerIf> iface_;
+};
+
+class SamplingManagerNull : virtual public SamplingManagerIf {
+ public:
+ virtual ~SamplingManagerNull() {}
+ void getSamplingStrategy(SamplingStrategyResponse& /* _return */, const std::string& /* serviceName */) {
+ return;
+ }
+};
+
+typedef struct _SamplingManager_getSamplingStrategy_args__isset {
+ _SamplingManager_getSamplingStrategy_args__isset() : serviceName(false) {}
+ bool serviceName :1;
+} _SamplingManager_getSamplingStrategy_args__isset;
+
+class SamplingManager_getSamplingStrategy_args {
+ public:
+
+ SamplingManager_getSamplingStrategy_args(const SamplingManager_getSamplingStrategy_args&);
+ SamplingManager_getSamplingStrategy_args& operator=(const SamplingManager_getSamplingStrategy_args&);
+ SamplingManager_getSamplingStrategy_args() : serviceName() {
+ }
+
+ virtual ~SamplingManager_getSamplingStrategy_args() throw();
+ std::string serviceName;
+
+ _SamplingManager_getSamplingStrategy_args__isset __isset;
+
+ void __set_serviceName(const std::string& val);
+
+ bool operator == (const SamplingManager_getSamplingStrategy_args & rhs) const
+ {
+ if (!(serviceName == rhs.serviceName))
+ return false;
+ return true;
+ }
+ bool operator != (const SamplingManager_getSamplingStrategy_args &rhs) const {
+ return !(*this == rhs);
+ }
+
+ bool operator < (const SamplingManager_getSamplingStrategy_args & ) const;
+
+ uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
+ uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;
+
+};
+
+
+class SamplingManager_getSamplingStrategy_pargs {
+ public:
+
+
+ virtual ~SamplingManager_getSamplingStrategy_pargs() throw();
+ const std::string* serviceName;
+
+ uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;
+
+};
+
+typedef struct _SamplingManager_getSamplingStrategy_result__isset {
+ _SamplingManager_getSamplingStrategy_result__isset() : success(false) {}
+ bool success :1;
+} _SamplingManager_getSamplingStrategy_result__isset;
+
+class SamplingManager_getSamplingStrategy_result {
+ public:
+
+ SamplingManager_getSamplingStrategy_result(const SamplingManager_getSamplingStrategy_result&);
+ SamplingManager_getSamplingStrategy_result& operator=(const SamplingManager_getSamplingStrategy_result&);
+ SamplingManager_getSamplingStrategy_result() {
+ }
+
+ virtual ~SamplingManager_getSamplingStrategy_result() throw();
+ SamplingStrategyResponse success;
+
+ _SamplingManager_getSamplingStrategy_result__isset __isset;
+
+ void __set_success(const SamplingStrategyResponse& val);
+
+ bool operator == (const SamplingManager_getSamplingStrategy_result & rhs) const
+ {
+ if (!(success == rhs.success))
+ return false;
+ return true;
+ }
+ bool operator != (const SamplingManager_getSamplingStrategy_result &rhs) const {
+ return !(*this == rhs);
+ }
+
+ bool operator < (const SamplingManager_getSamplingStrategy_result & ) const;
+
+ uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
+ uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;
+
+};
+
+typedef struct _SamplingManager_getSamplingStrategy_presult__isset {
+ _SamplingManager_getSamplingStrategy_presult__isset() : success(false) {}
+ bool success :1;
+} _SamplingManager_getSamplingStrategy_presult__isset;
+
+class SamplingManager_getSamplingStrategy_presult {
+ public:
+
+
+ virtual ~SamplingManager_getSamplingStrategy_presult() throw();
+ SamplingStrategyResponse* success;
+
+ _SamplingManager_getSamplingStrategy_presult__isset __isset;
+
+ uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
+
+};
+
+class SamplingManagerClient : virtual public SamplingManagerIf {
+ public:
+ SamplingManagerClient(std::shared_ptr< ::apache::thrift::protocol::TProtocol> prot) {
+ setProtocol(prot);
+ }
+ SamplingManagerClient(std::shared_ptr< ::apache::thrift::protocol::TProtocol> iprot, std::shared_ptr< ::apache::thrift::protocol::TProtocol> oprot) {
+ setProtocol(iprot,oprot);
+ }
+ private:
+ void setProtocol(std::shared_ptr< ::apache::thrift::protocol::TProtocol> prot) {
+ setProtocol(prot,prot);
+ }
+ void setProtocol(std::shared_ptr< ::apache::thrift::protocol::TProtocol> iprot, std::shared_ptr< ::apache::thrift::protocol::TProtocol> oprot) {
+ piprot_=iprot;
+ poprot_=oprot;
+ iprot_ = iprot.get();
+ oprot_ = oprot.get();
+ }
+ public:
+ std::shared_ptr< ::apache::thrift::protocol::TProtocol> getInputProtocol() {
+ return piprot_;
+ }
+ std::shared_ptr< ::apache::thrift::protocol::TProtocol> getOutputProtocol() {
+ return poprot_;
+ }
+ void getSamplingStrategy(SamplingStrategyResponse& _return, const std::string& serviceName);
+ void send_getSamplingStrategy(const std::string& serviceName);
+ void recv_getSamplingStrategy(SamplingStrategyResponse& _return);
+ protected:
+ std::shared_ptr< ::apache::thrift::protocol::TProtocol> piprot_;
+ std::shared_ptr< ::apache::thrift::protocol::TProtocol> poprot_;
+ ::apache::thrift::protocol::TProtocol* iprot_;
+ ::apache::thrift::protocol::TProtocol* oprot_;
+};
+
+class SamplingManagerProcessor : public ::apache::thrift::TDispatchProcessor {
+ protected:
+ ::std::shared_ptr<SamplingManagerIf> iface_;
+ virtual bool dispatchCall(::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, const std::string& fname, int32_t seqid, void* callContext);
+ private:
+ typedef void (SamplingManagerProcessor::*ProcessFunction)(int32_t, ::apache::thrift::protocol::TProtocol*, ::apache::thrift::protocol::TProtocol*, void*);
+ typedef std::map<std::string, ProcessFunction> ProcessMap;
+ ProcessMap processMap_;
+ void process_getSamplingStrategy(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext);
+ public:
+ SamplingManagerProcessor(::std::shared_ptr<SamplingManagerIf> iface) :
+ iface_(iface) {
+ processMap_["getSamplingStrategy"] = &SamplingManagerProcessor::process_getSamplingStrategy;
+ }
+
+ virtual ~SamplingManagerProcessor() {}
+};
+
+class SamplingManagerProcessorFactory : public ::apache::thrift::TProcessorFactory {
+ public:
+ SamplingManagerProcessorFactory(const ::std::shared_ptr< SamplingManagerIfFactory >& handlerFactory) :
+ handlerFactory_(handlerFactory) {}
+
+ ::std::shared_ptr< ::apache::thrift::TProcessor > getProcessor(const ::apache::thrift::TConnectionInfo& connInfo);
+
+ protected:
+ ::std::shared_ptr< SamplingManagerIfFactory > handlerFactory_;
+};
+
+class SamplingManagerMultiface : virtual public SamplingManagerIf {
+ public:
+ SamplingManagerMultiface(std::vector<std::shared_ptr<SamplingManagerIf> >& ifaces) : ifaces_(ifaces) {
+ }
+ virtual ~SamplingManagerMultiface() {}
+ protected:
+ std::vector<std::shared_ptr<SamplingManagerIf> > ifaces_;
+ SamplingManagerMultiface() {}
+ void add(::std::shared_ptr<SamplingManagerIf> iface) {
+ ifaces_.push_back(iface);
+ }
+ public:
+ void getSamplingStrategy(SamplingStrategyResponse& _return, const std::string& serviceName) {
+ size_t sz = ifaces_.size();
+ size_t i = 0;
+ for (; i < (sz - 1); ++i) {
+ ifaces_[i]->getSamplingStrategy(_return, serviceName);
+ }
+ ifaces_[i]->getSamplingStrategy(_return, serviceName);
+ return;
+ }
+
+};
+
+// The 'concurrent' client is a thread safe client that correctly handles
+// out of order responses. It is slower than the regular client, so should
+// only be used when you need to share a connection among multiple threads
+class SamplingManagerConcurrentClient : virtual public SamplingManagerIf {
+ public:
+ SamplingManagerConcurrentClient(std::shared_ptr< ::apache::thrift::protocol::TProtocol> prot) {
+ setProtocol(prot);
+ }
+ SamplingManagerConcurrentClient(std::shared_ptr< ::apache::thrift::protocol::TProtocol> iprot, std::shared_ptr< ::apache::thrift::protocol::TProtocol> oprot) {
+ setProtocol(iprot,oprot);
+ }
+ private:
+ void setProtocol(std::shared_ptr< ::apache::thrift::protocol::TProtocol> prot) {
+ setProtocol(prot,prot);
+ }
+ void setProtocol(std::shared_ptr< ::apache::thrift::protocol::TProtocol> iprot, std::shared_ptr< ::apache::thrift::protocol::TProtocol> oprot) {
+ piprot_=iprot;
+ poprot_=oprot;
+ iprot_ = iprot.get();
+ oprot_ = oprot.get();
+ }
+ public:
+ std::shared_ptr< ::apache::thrift::protocol::TProtocol> getInputProtocol() {
+ return piprot_;
+ }
+ std::shared_ptr< ::apache::thrift::protocol::TProtocol> getOutputProtocol() {
+ return poprot_;
+ }
+ void getSamplingStrategy(SamplingStrategyResponse& _return, const std::string& serviceName);
+ int32_t send_getSamplingStrategy(const std::string& serviceName);
+ void recv_getSamplingStrategy(SamplingStrategyResponse& _return, const int32_t seqid);
+ protected:
+ std::shared_ptr< ::apache::thrift::protocol::TProtocol> piprot_;
+ std::shared_ptr< ::apache::thrift::protocol::TProtocol> poprot_;
+ ::apache::thrift::protocol::TProtocol* iprot_;
+ ::apache::thrift::protocol::TProtocol* oprot_;
+ ::apache::thrift::async::TConcurrentClientSyncInfo sync_;
+};
+
+#ifdef _MSC_VER
+ #pragma warning( pop )
+#endif
+
+}}} // namespace
+
+#endif
diff --git a/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/thrift-gen/TracedService.cpp b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/thrift-gen/TracedService.cpp
new file mode 100644
index 000000000..d38e019c0
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/thrift-gen/TracedService.cpp
@@ -0,0 +1,804 @@
+/**
+ * Autogenerated by Thrift Compiler (0.11.0)
+ *
+ * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
+ * @generated
+ */
+#include "TracedService.h"
+
+namespace jaegertracing { namespace crossdock { namespace thrift {
+
+
+TracedService_startTrace_args::~TracedService_startTrace_args() throw() {
+}
+
+
+uint32_t TracedService_startTrace_args::read(::apache::thrift::protocol::TProtocol* iprot) {
+
+ ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
+ uint32_t xfer = 0;
+ std::string fname;
+ ::apache::thrift::protocol::TType ftype;
+ int16_t fid;
+
+ xfer += iprot->readStructBegin(fname);
+
+ using ::apache::thrift::protocol::TProtocolException;
+
+
+ while (true)
+ {
+ xfer += iprot->readFieldBegin(fname, ftype, fid);
+ if (ftype == ::apache::thrift::protocol::T_STOP) {
+ break;
+ }
+ switch (fid)
+ {
+ case 1:
+ if (ftype == ::apache::thrift::protocol::T_STRUCT) {
+ xfer += this->request.read(iprot);
+ this->__isset.request = true;
+ } else {
+ xfer += iprot->skip(ftype);
+ }
+ break;
+ default:
+ xfer += iprot->skip(ftype);
+ break;
+ }
+ xfer += iprot->readFieldEnd();
+ }
+
+ xfer += iprot->readStructEnd();
+
+ return xfer;
+}
+
+uint32_t TracedService_startTrace_args::write(::apache::thrift::protocol::TProtocol* oprot) const {
+ uint32_t xfer = 0;
+ ::apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
+ xfer += oprot->writeStructBegin("TracedService_startTrace_args");
+
+ xfer += oprot->writeFieldBegin("request", ::apache::thrift::protocol::T_STRUCT, 1);
+ xfer += this->request.write(oprot);
+ xfer += oprot->writeFieldEnd();
+
+ xfer += oprot->writeFieldStop();
+ xfer += oprot->writeStructEnd();
+ return xfer;
+}
+
+
+TracedService_startTrace_pargs::~TracedService_startTrace_pargs() throw() {
+}
+
+
+uint32_t TracedService_startTrace_pargs::write(::apache::thrift::protocol::TProtocol* oprot) const {
+ uint32_t xfer = 0;
+ ::apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
+ xfer += oprot->writeStructBegin("TracedService_startTrace_pargs");
+
+ xfer += oprot->writeFieldBegin("request", ::apache::thrift::protocol::T_STRUCT, 1);
+ xfer += (*(this->request)).write(oprot);
+ xfer += oprot->writeFieldEnd();
+
+ xfer += oprot->writeFieldStop();
+ xfer += oprot->writeStructEnd();
+ return xfer;
+}
+
+
+TracedService_startTrace_result::~TracedService_startTrace_result() throw() {
+}
+
+
+uint32_t TracedService_startTrace_result::read(::apache::thrift::protocol::TProtocol* iprot) {
+
+ ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
+ uint32_t xfer = 0;
+ std::string fname;
+ ::apache::thrift::protocol::TType ftype;
+ int16_t fid;
+
+ xfer += iprot->readStructBegin(fname);
+
+ using ::apache::thrift::protocol::TProtocolException;
+
+
+ while (true)
+ {
+ xfer += iprot->readFieldBegin(fname, ftype, fid);
+ if (ftype == ::apache::thrift::protocol::T_STOP) {
+ break;
+ }
+ switch (fid)
+ {
+ case 0:
+ if (ftype == ::apache::thrift::protocol::T_STRUCT) {
+ xfer += this->success.read(iprot);
+ this->__isset.success = true;
+ } else {
+ xfer += iprot->skip(ftype);
+ }
+ break;
+ default:
+ xfer += iprot->skip(ftype);
+ break;
+ }
+ xfer += iprot->readFieldEnd();
+ }
+
+ xfer += iprot->readStructEnd();
+
+ return xfer;
+}
+
+uint32_t TracedService_startTrace_result::write(::apache::thrift::protocol::TProtocol* oprot) const {
+
+ uint32_t xfer = 0;
+
+ xfer += oprot->writeStructBegin("TracedService_startTrace_result");
+
+ if (this->__isset.success) {
+ xfer += oprot->writeFieldBegin("success", ::apache::thrift::protocol::T_STRUCT, 0);
+ xfer += this->success.write(oprot);
+ xfer += oprot->writeFieldEnd();
+ }
+ xfer += oprot->writeFieldStop();
+ xfer += oprot->writeStructEnd();
+ return xfer;
+}
+
+
+TracedService_startTrace_presult::~TracedService_startTrace_presult() throw() {
+}
+
+
+uint32_t TracedService_startTrace_presult::read(::apache::thrift::protocol::TProtocol* iprot) {
+
+ ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
+ uint32_t xfer = 0;
+ std::string fname;
+ ::apache::thrift::protocol::TType ftype;
+ int16_t fid;
+
+ xfer += iprot->readStructBegin(fname);
+
+ using ::apache::thrift::protocol::TProtocolException;
+
+
+ while (true)
+ {
+ xfer += iprot->readFieldBegin(fname, ftype, fid);
+ if (ftype == ::apache::thrift::protocol::T_STOP) {
+ break;
+ }
+ switch (fid)
+ {
+ case 0:
+ if (ftype == ::apache::thrift::protocol::T_STRUCT) {
+ xfer += (*(this->success)).read(iprot);
+ this->__isset.success = true;
+ } else {
+ xfer += iprot->skip(ftype);
+ }
+ break;
+ default:
+ xfer += iprot->skip(ftype);
+ break;
+ }
+ xfer += iprot->readFieldEnd();
+ }
+
+ xfer += iprot->readStructEnd();
+
+ return xfer;
+}
+
+
+TracedService_joinTrace_args::~TracedService_joinTrace_args() throw() {
+}
+
+
+uint32_t TracedService_joinTrace_args::read(::apache::thrift::protocol::TProtocol* iprot) {
+
+ ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
+ uint32_t xfer = 0;
+ std::string fname;
+ ::apache::thrift::protocol::TType ftype;
+ int16_t fid;
+
+ xfer += iprot->readStructBegin(fname);
+
+ using ::apache::thrift::protocol::TProtocolException;
+
+
+ while (true)
+ {
+ xfer += iprot->readFieldBegin(fname, ftype, fid);
+ if (ftype == ::apache::thrift::protocol::T_STOP) {
+ break;
+ }
+ switch (fid)
+ {
+ case 1:
+ if (ftype == ::apache::thrift::protocol::T_STRUCT) {
+ xfer += this->request.read(iprot);
+ this->__isset.request = true;
+ } else {
+ xfer += iprot->skip(ftype);
+ }
+ break;
+ default:
+ xfer += iprot->skip(ftype);
+ break;
+ }
+ xfer += iprot->readFieldEnd();
+ }
+
+ xfer += iprot->readStructEnd();
+
+ return xfer;
+}
+
+uint32_t TracedService_joinTrace_args::write(::apache::thrift::protocol::TProtocol* oprot) const {
+ uint32_t xfer = 0;
+ ::apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
+ xfer += oprot->writeStructBegin("TracedService_joinTrace_args");
+
+ xfer += oprot->writeFieldBegin("request", ::apache::thrift::protocol::T_STRUCT, 1);
+ xfer += this->request.write(oprot);
+ xfer += oprot->writeFieldEnd();
+
+ xfer += oprot->writeFieldStop();
+ xfer += oprot->writeStructEnd();
+ return xfer;
+}
+
+
+TracedService_joinTrace_pargs::~TracedService_joinTrace_pargs() throw() {
+}
+
+
+uint32_t TracedService_joinTrace_pargs::write(::apache::thrift::protocol::TProtocol* oprot) const {
+ uint32_t xfer = 0;
+ ::apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
+ xfer += oprot->writeStructBegin("TracedService_joinTrace_pargs");
+
+ xfer += oprot->writeFieldBegin("request", ::apache::thrift::protocol::T_STRUCT, 1);
+ xfer += (*(this->request)).write(oprot);
+ xfer += oprot->writeFieldEnd();
+
+ xfer += oprot->writeFieldStop();
+ xfer += oprot->writeStructEnd();
+ return xfer;
+}
+
+
+TracedService_joinTrace_result::~TracedService_joinTrace_result() throw() {
+}
+
+
+uint32_t TracedService_joinTrace_result::read(::apache::thrift::protocol::TProtocol* iprot) {
+
+ ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
+ uint32_t xfer = 0;
+ std::string fname;
+ ::apache::thrift::protocol::TType ftype;
+ int16_t fid;
+
+ xfer += iprot->readStructBegin(fname);
+
+ using ::apache::thrift::protocol::TProtocolException;
+
+
+ while (true)
+ {
+ xfer += iprot->readFieldBegin(fname, ftype, fid);
+ if (ftype == ::apache::thrift::protocol::T_STOP) {
+ break;
+ }
+ switch (fid)
+ {
+ case 0:
+ if (ftype == ::apache::thrift::protocol::T_STRUCT) {
+ xfer += this->success.read(iprot);
+ this->__isset.success = true;
+ } else {
+ xfer += iprot->skip(ftype);
+ }
+ break;
+ default:
+ xfer += iprot->skip(ftype);
+ break;
+ }
+ xfer += iprot->readFieldEnd();
+ }
+
+ xfer += iprot->readStructEnd();
+
+ return xfer;
+}
+
+uint32_t TracedService_joinTrace_result::write(::apache::thrift::protocol::TProtocol* oprot) const {
+
+ uint32_t xfer = 0;
+
+ xfer += oprot->writeStructBegin("TracedService_joinTrace_result");
+
+ if (this->__isset.success) {
+ xfer += oprot->writeFieldBegin("success", ::apache::thrift::protocol::T_STRUCT, 0);
+ xfer += this->success.write(oprot);
+ xfer += oprot->writeFieldEnd();
+ }
+ xfer += oprot->writeFieldStop();
+ xfer += oprot->writeStructEnd();
+ return xfer;
+}
+
+
+TracedService_joinTrace_presult::~TracedService_joinTrace_presult() throw() {
+}
+
+
+uint32_t TracedService_joinTrace_presult::read(::apache::thrift::protocol::TProtocol* iprot) {
+
+ ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
+ uint32_t xfer = 0;
+ std::string fname;
+ ::apache::thrift::protocol::TType ftype;
+ int16_t fid;
+
+ xfer += iprot->readStructBegin(fname);
+
+ using ::apache::thrift::protocol::TProtocolException;
+
+
+ while (true)
+ {
+ xfer += iprot->readFieldBegin(fname, ftype, fid);
+ if (ftype == ::apache::thrift::protocol::T_STOP) {
+ break;
+ }
+ switch (fid)
+ {
+ case 0:
+ if (ftype == ::apache::thrift::protocol::T_STRUCT) {
+ xfer += (*(this->success)).read(iprot);
+ this->__isset.success = true;
+ } else {
+ xfer += iprot->skip(ftype);
+ }
+ break;
+ default:
+ xfer += iprot->skip(ftype);
+ break;
+ }
+ xfer += iprot->readFieldEnd();
+ }
+
+ xfer += iprot->readStructEnd();
+
+ return xfer;
+}
+
+void TracedServiceClient::startTrace(TraceResponse& _return, const StartTraceRequest& request)
+{
+ send_startTrace(request);
+ recv_startTrace(_return);
+}
+
+void TracedServiceClient::send_startTrace(const StartTraceRequest& request)
+{
+ int32_t cseqid = 0;
+ oprot_->writeMessageBegin("startTrace", ::apache::thrift::protocol::T_CALL, cseqid);
+
+ TracedService_startTrace_pargs args;
+ args.request = &request;
+ args.write(oprot_);
+
+ oprot_->writeMessageEnd();
+ oprot_->getTransport()->writeEnd();
+ oprot_->getTransport()->flush();
+}
+
+void TracedServiceClient::recv_startTrace(TraceResponse& _return)
+{
+
+ int32_t rseqid = 0;
+ std::string fname;
+ ::apache::thrift::protocol::TMessageType mtype;
+
+ iprot_->readMessageBegin(fname, mtype, rseqid);
+ if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
+ ::apache::thrift::TApplicationException x;
+ x.read(iprot_);
+ iprot_->readMessageEnd();
+ iprot_->getTransport()->readEnd();
+ throw x;
+ }
+ if (mtype != ::apache::thrift::protocol::T_REPLY) {
+ iprot_->skip(::apache::thrift::protocol::T_STRUCT);
+ iprot_->readMessageEnd();
+ iprot_->getTransport()->readEnd();
+ }
+ if (fname.compare("startTrace") != 0) {
+ iprot_->skip(::apache::thrift::protocol::T_STRUCT);
+ iprot_->readMessageEnd();
+ iprot_->getTransport()->readEnd();
+ }
+ TracedService_startTrace_presult result;
+ result.success = &_return;
+ result.read(iprot_);
+ iprot_->readMessageEnd();
+ iprot_->getTransport()->readEnd();
+
+ if (result.__isset.success) {
+ // _return pointer has now been filled
+ return;
+ }
+ throw ::apache::thrift::TApplicationException(::apache::thrift::TApplicationException::MISSING_RESULT, "startTrace failed: unknown result");
+}
+
+void TracedServiceClient::joinTrace(TraceResponse& _return, const JoinTraceRequest& request)
+{
+ send_joinTrace(request);
+ recv_joinTrace(_return);
+}
+
+void TracedServiceClient::send_joinTrace(const JoinTraceRequest& request)
+{
+ int32_t cseqid = 0;
+ oprot_->writeMessageBegin("joinTrace", ::apache::thrift::protocol::T_CALL, cseqid);
+
+ TracedService_joinTrace_pargs args;
+ args.request = &request;
+ args.write(oprot_);
+
+ oprot_->writeMessageEnd();
+ oprot_->getTransport()->writeEnd();
+ oprot_->getTransport()->flush();
+}
+
+void TracedServiceClient::recv_joinTrace(TraceResponse& _return)
+{
+
+ int32_t rseqid = 0;
+ std::string fname;
+ ::apache::thrift::protocol::TMessageType mtype;
+
+ iprot_->readMessageBegin(fname, mtype, rseqid);
+ if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
+ ::apache::thrift::TApplicationException x;
+ x.read(iprot_);
+ iprot_->readMessageEnd();
+ iprot_->getTransport()->readEnd();
+ throw x;
+ }
+ if (mtype != ::apache::thrift::protocol::T_REPLY) {
+ iprot_->skip(::apache::thrift::protocol::T_STRUCT);
+ iprot_->readMessageEnd();
+ iprot_->getTransport()->readEnd();
+ }
+ if (fname.compare("joinTrace") != 0) {
+ iprot_->skip(::apache::thrift::protocol::T_STRUCT);
+ iprot_->readMessageEnd();
+ iprot_->getTransport()->readEnd();
+ }
+ TracedService_joinTrace_presult result;
+ result.success = &_return;
+ result.read(iprot_);
+ iprot_->readMessageEnd();
+ iprot_->getTransport()->readEnd();
+
+ if (result.__isset.success) {
+ // _return pointer has now been filled
+ return;
+ }
+ throw ::apache::thrift::TApplicationException(::apache::thrift::TApplicationException::MISSING_RESULT, "joinTrace failed: unknown result");
+}
+
+bool TracedServiceProcessor::dispatchCall(::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, const std::string& fname, int32_t seqid, void* callContext) {
+ ProcessMap::iterator pfn;
+ pfn = processMap_.find(fname);
+ if (pfn == processMap_.end()) {
+ iprot->skip(::apache::thrift::protocol::T_STRUCT);
+ iprot->readMessageEnd();
+ iprot->getTransport()->readEnd();
+ ::apache::thrift::TApplicationException x(::apache::thrift::TApplicationException::UNKNOWN_METHOD, "Invalid method name: '"+fname+"'");
+ oprot->writeMessageBegin(fname, ::apache::thrift::protocol::T_EXCEPTION, seqid);
+ x.write(oprot);
+ oprot->writeMessageEnd();
+ oprot->getTransport()->writeEnd();
+ oprot->getTransport()->flush();
+ return true;
+ }
+ (this->*(pfn->second))(seqid, iprot, oprot, callContext);
+ return true;
+}
+
+void TracedServiceProcessor::process_startTrace(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext)
+{
+ void* ctx = NULL;
+ if (this->eventHandler_.get() != NULL) {
+ ctx = this->eventHandler_->getContext("TracedService.startTrace", callContext);
+ }
+ ::apache::thrift::TProcessorContextFreer freer(this->eventHandler_.get(), ctx, "TracedService.startTrace");
+
+ if (this->eventHandler_.get() != NULL) {
+ this->eventHandler_->preRead(ctx, "TracedService.startTrace");
+ }
+
+ TracedService_startTrace_args args;
+ args.read(iprot);
+ iprot->readMessageEnd();
+ uint32_t bytes = iprot->getTransport()->readEnd();
+
+ if (this->eventHandler_.get() != NULL) {
+ this->eventHandler_->postRead(ctx, "TracedService.startTrace", bytes);
+ }
+
+ TracedService_startTrace_result result;
+ try {
+ iface_->startTrace(result.success, args.request);
+ result.__isset.success = true;
+ } catch (const std::exception& e) {
+ if (this->eventHandler_.get() != NULL) {
+ this->eventHandler_->handlerError(ctx, "TracedService.startTrace");
+ }
+
+ ::apache::thrift::TApplicationException x(e.what());
+ oprot->writeMessageBegin("startTrace", ::apache::thrift::protocol::T_EXCEPTION, seqid);
+ x.write(oprot);
+ oprot->writeMessageEnd();
+ oprot->getTransport()->writeEnd();
+ oprot->getTransport()->flush();
+ return;
+ }
+
+ if (this->eventHandler_.get() != NULL) {
+ this->eventHandler_->preWrite(ctx, "TracedService.startTrace");
+ }
+
+ oprot->writeMessageBegin("startTrace", ::apache::thrift::protocol::T_REPLY, seqid);
+ result.write(oprot);
+ oprot->writeMessageEnd();
+ bytes = oprot->getTransport()->writeEnd();
+ oprot->getTransport()->flush();
+
+ if (this->eventHandler_.get() != NULL) {
+ this->eventHandler_->postWrite(ctx, "TracedService.startTrace", bytes);
+ }
+}
+
+void TracedServiceProcessor::process_joinTrace(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext)
+{
+ void* ctx = NULL;
+ if (this->eventHandler_.get() != NULL) {
+ ctx = this->eventHandler_->getContext("TracedService.joinTrace", callContext);
+ }
+ ::apache::thrift::TProcessorContextFreer freer(this->eventHandler_.get(), ctx, "TracedService.joinTrace");
+
+ if (this->eventHandler_.get() != NULL) {
+ this->eventHandler_->preRead(ctx, "TracedService.joinTrace");
+ }
+
+ TracedService_joinTrace_args args;
+ args.read(iprot);
+ iprot->readMessageEnd();
+ uint32_t bytes = iprot->getTransport()->readEnd();
+
+ if (this->eventHandler_.get() != NULL) {
+ this->eventHandler_->postRead(ctx, "TracedService.joinTrace", bytes);
+ }
+
+ TracedService_joinTrace_result result;
+ try {
+ iface_->joinTrace(result.success, args.request);
+ result.__isset.success = true;
+ } catch (const std::exception& e) {
+ if (this->eventHandler_.get() != NULL) {
+ this->eventHandler_->handlerError(ctx, "TracedService.joinTrace");
+ }
+
+ ::apache::thrift::TApplicationException x(e.what());
+ oprot->writeMessageBegin("joinTrace", ::apache::thrift::protocol::T_EXCEPTION, seqid);
+ x.write(oprot);
+ oprot->writeMessageEnd();
+ oprot->getTransport()->writeEnd();
+ oprot->getTransport()->flush();
+ return;
+ }
+
+ if (this->eventHandler_.get() != NULL) {
+ this->eventHandler_->preWrite(ctx, "TracedService.joinTrace");
+ }
+
+ oprot->writeMessageBegin("joinTrace", ::apache::thrift::protocol::T_REPLY, seqid);
+ result.write(oprot);
+ oprot->writeMessageEnd();
+ bytes = oprot->getTransport()->writeEnd();
+ oprot->getTransport()->flush();
+
+ if (this->eventHandler_.get() != NULL) {
+ this->eventHandler_->postWrite(ctx, "TracedService.joinTrace", bytes);
+ }
+}
+
+::std::shared_ptr< ::apache::thrift::TProcessor > TracedServiceProcessorFactory::getProcessor(const ::apache::thrift::TConnectionInfo& connInfo) {
+ ::apache::thrift::ReleaseHandler< TracedServiceIfFactory > cleanup(handlerFactory_);
+ ::std::shared_ptr< TracedServiceIf > handler(handlerFactory_->getHandler(connInfo), cleanup);
+ ::std::shared_ptr< ::apache::thrift::TProcessor > processor(new TracedServiceProcessor(handler));
+ return processor;
+}
+
+void TracedServiceConcurrentClient::startTrace(TraceResponse& _return, const StartTraceRequest& request)
+{
+ int32_t seqid = send_startTrace(request);
+ recv_startTrace(_return, seqid);
+}
+
+int32_t TracedServiceConcurrentClient::send_startTrace(const StartTraceRequest& request)
+{
+ int32_t cseqid = this->sync_.generateSeqId();
+ ::apache::thrift::async::TConcurrentSendSentry sentry(&this->sync_);
+ oprot_->writeMessageBegin("startTrace", ::apache::thrift::protocol::T_CALL, cseqid);
+
+ TracedService_startTrace_pargs args;
+ args.request = &request;
+ args.write(oprot_);
+
+ oprot_->writeMessageEnd();
+ oprot_->getTransport()->writeEnd();
+ oprot_->getTransport()->flush();
+
+ sentry.commit();
+ return cseqid;
+}
+
+void TracedServiceConcurrentClient::recv_startTrace(TraceResponse& _return, const int32_t seqid)
+{
+
+ int32_t rseqid = 0;
+ std::string fname;
+ ::apache::thrift::protocol::TMessageType mtype;
+
+ // the read mutex gets dropped and reacquired as part of waitForWork()
+ // The destructor of this sentry wakes up other clients
+ ::apache::thrift::async::TConcurrentRecvSentry sentry(&this->sync_, seqid);
+
+ while(true) {
+ if(!this->sync_.getPending(fname, mtype, rseqid)) {
+ iprot_->readMessageBegin(fname, mtype, rseqid);
+ }
+ if(seqid == rseqid) {
+ if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
+ ::apache::thrift::TApplicationException x;
+ x.read(iprot_);
+ iprot_->readMessageEnd();
+ iprot_->getTransport()->readEnd();
+ sentry.commit();
+ throw x;
+ }
+ if (mtype != ::apache::thrift::protocol::T_REPLY) {
+ iprot_->skip(::apache::thrift::protocol::T_STRUCT);
+ iprot_->readMessageEnd();
+ iprot_->getTransport()->readEnd();
+ }
+ if (fname.compare("startTrace") != 0) {
+ iprot_->skip(::apache::thrift::protocol::T_STRUCT);
+ iprot_->readMessageEnd();
+ iprot_->getTransport()->readEnd();
+
+ // in a bad state, don't commit
+ using ::apache::thrift::protocol::TProtocolException;
+ throw TProtocolException(TProtocolException::INVALID_DATA);
+ }
+ TracedService_startTrace_presult result;
+ result.success = &_return;
+ result.read(iprot_);
+ iprot_->readMessageEnd();
+ iprot_->getTransport()->readEnd();
+
+ if (result.__isset.success) {
+ // _return pointer has now been filled
+ sentry.commit();
+ return;
+ }
+ // in a bad state, don't commit
+ throw ::apache::thrift::TApplicationException(::apache::thrift::TApplicationException::MISSING_RESULT, "startTrace failed: unknown result");
+ }
+ // seqid != rseqid
+ this->sync_.updatePending(fname, mtype, rseqid);
+
+ // this will temporarily unlock the readMutex, and let other clients get work done
+ this->sync_.waitForWork(seqid);
+ } // end while(true)
+}
+
+void TracedServiceConcurrentClient::joinTrace(TraceResponse& _return, const JoinTraceRequest& request)
+{
+ int32_t seqid = send_joinTrace(request);
+ recv_joinTrace(_return, seqid);
+}
+
+int32_t TracedServiceConcurrentClient::send_joinTrace(const JoinTraceRequest& request)
+{
+ int32_t cseqid = this->sync_.generateSeqId();
+ ::apache::thrift::async::TConcurrentSendSentry sentry(&this->sync_);
+ oprot_->writeMessageBegin("joinTrace", ::apache::thrift::protocol::T_CALL, cseqid);
+
+ TracedService_joinTrace_pargs args;
+ args.request = &request;
+ args.write(oprot_);
+
+ oprot_->writeMessageEnd();
+ oprot_->getTransport()->writeEnd();
+ oprot_->getTransport()->flush();
+
+ sentry.commit();
+ return cseqid;
+}
+
+void TracedServiceConcurrentClient::recv_joinTrace(TraceResponse& _return, const int32_t seqid)
+{
+
+ int32_t rseqid = 0;
+ std::string fname;
+ ::apache::thrift::protocol::TMessageType mtype;
+
+ // the read mutex gets dropped and reacquired as part of waitForWork()
+ // The destructor of this sentry wakes up other clients
+ ::apache::thrift::async::TConcurrentRecvSentry sentry(&this->sync_, seqid);
+
+ while(true) {
+ if(!this->sync_.getPending(fname, mtype, rseqid)) {
+ iprot_->readMessageBegin(fname, mtype, rseqid);
+ }
+ if(seqid == rseqid) {
+ if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
+ ::apache::thrift::TApplicationException x;
+ x.read(iprot_);
+ iprot_->readMessageEnd();
+ iprot_->getTransport()->readEnd();
+ sentry.commit();
+ throw x;
+ }
+ if (mtype != ::apache::thrift::protocol::T_REPLY) {
+ iprot_->skip(::apache::thrift::protocol::T_STRUCT);
+ iprot_->readMessageEnd();
+ iprot_->getTransport()->readEnd();
+ }
+ if (fname.compare("joinTrace") != 0) {
+ iprot_->skip(::apache::thrift::protocol::T_STRUCT);
+ iprot_->readMessageEnd();
+ iprot_->getTransport()->readEnd();
+
+ // in a bad state, don't commit
+ using ::apache::thrift::protocol::TProtocolException;
+ throw TProtocolException(TProtocolException::INVALID_DATA);
+ }
+ TracedService_joinTrace_presult result;
+ result.success = &_return;
+ result.read(iprot_);
+ iprot_->readMessageEnd();
+ iprot_->getTransport()->readEnd();
+
+ if (result.__isset.success) {
+ // _return pointer has now been filled
+ sentry.commit();
+ return;
+ }
+ // in a bad state, don't commit
+ throw ::apache::thrift::TApplicationException(::apache::thrift::TApplicationException::MISSING_RESULT, "joinTrace failed: unknown result");
+ }
+ // seqid != rseqid
+ this->sync_.updatePending(fname, mtype, rseqid);
+
+ // this will temporarily unlock the readMutex, and let other clients get work done
+ this->sync_.waitForWork(seqid);
+ } // end while(true)
+}
+
+}}} // namespace
+
diff --git a/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/thrift-gen/TracedService.h b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/thrift-gen/TracedService.h
new file mode 100644
index 000000000..3da73420d
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/thrift-gen/TracedService.h
@@ -0,0 +1,422 @@
+/**
+ * Autogenerated by Thrift Compiler (0.11.0)
+ *
+ * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
+ * @generated
+ */
+#ifndef TracedService_H
+#define TracedService_H
+
+#include <thrift/TDispatchProcessor.h>
+#include <thrift/async/TConcurrentClientSyncInfo.h>
+#include "tracetest_types.h"
+
+namespace jaegertracing { namespace crossdock { namespace thrift {
+
+#ifdef _MSC_VER
+ #pragma warning( push )
+ #pragma warning (disable : 4250 ) //inheriting methods via dominance
+#endif
+
+class TracedServiceIf {
+ public:
+ virtual ~TracedServiceIf() {}
+ virtual void startTrace(TraceResponse& _return, const StartTraceRequest& request) = 0;
+ virtual void joinTrace(TraceResponse& _return, const JoinTraceRequest& request) = 0;
+};
+
+class TracedServiceIfFactory {
+ public:
+ typedef TracedServiceIf Handler;
+
+ virtual ~TracedServiceIfFactory() {}
+
+ virtual TracedServiceIf* getHandler(const ::apache::thrift::TConnectionInfo& connInfo) = 0;
+ virtual void releaseHandler(TracedServiceIf* /* handler */) = 0;
+};
+
+class TracedServiceIfSingletonFactory : virtual public TracedServiceIfFactory {
+ public:
+ TracedServiceIfSingletonFactory(const ::std::shared_ptr<TracedServiceIf>& iface) : iface_(iface) {}
+ virtual ~TracedServiceIfSingletonFactory() {}
+
+ virtual TracedServiceIf* getHandler(const ::apache::thrift::TConnectionInfo&) {
+ return iface_.get();
+ }
+ virtual void releaseHandler(TracedServiceIf* /* handler */) {}
+
+ protected:
+ ::std::shared_ptr<TracedServiceIf> iface_;
+};
+
+class TracedServiceNull : virtual public TracedServiceIf {
+ public:
+ virtual ~TracedServiceNull() {}
+ void startTrace(TraceResponse& /* _return */, const StartTraceRequest& /* request */) {
+ return;
+ }
+ void joinTrace(TraceResponse& /* _return */, const JoinTraceRequest& /* request */) {
+ return;
+ }
+};
+
+typedef struct _TracedService_startTrace_args__isset {
+ _TracedService_startTrace_args__isset() : request(false) {}
+ bool request :1;
+} _TracedService_startTrace_args__isset;
+
+class TracedService_startTrace_args {
+ public:
+
+ TracedService_startTrace_args(const TracedService_startTrace_args&);
+ TracedService_startTrace_args& operator=(const TracedService_startTrace_args&);
+ TracedService_startTrace_args() {
+ }
+
+ virtual ~TracedService_startTrace_args() throw();
+ StartTraceRequest request;
+
+ _TracedService_startTrace_args__isset __isset;
+
+ void __set_request(const StartTraceRequest& val);
+
+ bool operator == (const TracedService_startTrace_args & rhs) const
+ {
+ if (!(request == rhs.request))
+ return false;
+ return true;
+ }
+ bool operator != (const TracedService_startTrace_args &rhs) const {
+ return !(*this == rhs);
+ }
+
+ bool operator < (const TracedService_startTrace_args & ) const;
+
+ uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
+ uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;
+
+};
+
+
+class TracedService_startTrace_pargs {
+ public:
+
+
+ virtual ~TracedService_startTrace_pargs() throw();
+ const StartTraceRequest* request;
+
+ uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;
+
+};
+
+typedef struct _TracedService_startTrace_result__isset {
+ _TracedService_startTrace_result__isset() : success(false) {}
+ bool success :1;
+} _TracedService_startTrace_result__isset;
+
+class TracedService_startTrace_result {
+ public:
+
+ TracedService_startTrace_result(const TracedService_startTrace_result&);
+ TracedService_startTrace_result& operator=(const TracedService_startTrace_result&);
+ TracedService_startTrace_result() {
+ }
+
+ virtual ~TracedService_startTrace_result() throw();
+ TraceResponse success;
+
+ _TracedService_startTrace_result__isset __isset;
+
+ void __set_success(const TraceResponse& val);
+
+ bool operator == (const TracedService_startTrace_result & rhs) const
+ {
+ if (!(success == rhs.success))
+ return false;
+ return true;
+ }
+ bool operator != (const TracedService_startTrace_result &rhs) const {
+ return !(*this == rhs);
+ }
+
+ bool operator < (const TracedService_startTrace_result & ) const;
+
+ uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
+ uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;
+
+};
+
+typedef struct _TracedService_startTrace_presult__isset {
+ _TracedService_startTrace_presult__isset() : success(false) {}
+ bool success :1;
+} _TracedService_startTrace_presult__isset;
+
+class TracedService_startTrace_presult {
+ public:
+
+
+ virtual ~TracedService_startTrace_presult() throw();
+ TraceResponse* success;
+
+ _TracedService_startTrace_presult__isset __isset;
+
+ uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
+
+};
+
+typedef struct _TracedService_joinTrace_args__isset {
+ _TracedService_joinTrace_args__isset() : request(false) {}
+ bool request :1;
+} _TracedService_joinTrace_args__isset;
+
+class TracedService_joinTrace_args {
+ public:
+
+ TracedService_joinTrace_args(const TracedService_joinTrace_args&);
+ TracedService_joinTrace_args& operator=(const TracedService_joinTrace_args&);
+ TracedService_joinTrace_args() {
+ }
+
+ virtual ~TracedService_joinTrace_args() throw();
+ JoinTraceRequest request;
+
+ _TracedService_joinTrace_args__isset __isset;
+
+ void __set_request(const JoinTraceRequest& val);
+
+ bool operator == (const TracedService_joinTrace_args & rhs) const
+ {
+ if (!(request == rhs.request))
+ return false;
+ return true;
+ }
+ bool operator != (const TracedService_joinTrace_args &rhs) const {
+ return !(*this == rhs);
+ }
+
+ bool operator < (const TracedService_joinTrace_args & ) const;
+
+ uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
+ uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;
+
+};
+
+
+class TracedService_joinTrace_pargs {
+ public:
+
+
+ virtual ~TracedService_joinTrace_pargs() throw();
+ const JoinTraceRequest* request;
+
+ uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;
+
+};
+
+typedef struct _TracedService_joinTrace_result__isset {
+ _TracedService_joinTrace_result__isset() : success(false) {}
+ bool success :1;
+} _TracedService_joinTrace_result__isset;
+
+class TracedService_joinTrace_result {
+ public:
+
+ TracedService_joinTrace_result(const TracedService_joinTrace_result&);
+ TracedService_joinTrace_result& operator=(const TracedService_joinTrace_result&);
+ TracedService_joinTrace_result() {
+ }
+
+ virtual ~TracedService_joinTrace_result() throw();
+ TraceResponse success;
+
+ _TracedService_joinTrace_result__isset __isset;
+
+ void __set_success(const TraceResponse& val);
+
+ bool operator == (const TracedService_joinTrace_result & rhs) const
+ {
+ if (!(success == rhs.success))
+ return false;
+ return true;
+ }
+ bool operator != (const TracedService_joinTrace_result &rhs) const {
+ return !(*this == rhs);
+ }
+
+ bool operator < (const TracedService_joinTrace_result & ) const;
+
+ uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
+ uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;
+
+};
+
+typedef struct _TracedService_joinTrace_presult__isset {
+ _TracedService_joinTrace_presult__isset() : success(false) {}
+ bool success :1;
+} _TracedService_joinTrace_presult__isset;
+
+class TracedService_joinTrace_presult {
+ public:
+
+
+ virtual ~TracedService_joinTrace_presult() throw();
+ TraceResponse* success;
+
+ _TracedService_joinTrace_presult__isset __isset;
+
+ uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
+
+};
+
+class TracedServiceClient : virtual public TracedServiceIf {
+ public:
+ TracedServiceClient(std::shared_ptr< ::apache::thrift::protocol::TProtocol> prot) {
+ setProtocol(prot);
+ }
+ TracedServiceClient(std::shared_ptr< ::apache::thrift::protocol::TProtocol> iprot, std::shared_ptr< ::apache::thrift::protocol::TProtocol> oprot) {
+ setProtocol(iprot,oprot);
+ }
+ private:
+ void setProtocol(std::shared_ptr< ::apache::thrift::protocol::TProtocol> prot) {
+ setProtocol(prot,prot);
+ }
+ void setProtocol(std::shared_ptr< ::apache::thrift::protocol::TProtocol> iprot, std::shared_ptr< ::apache::thrift::protocol::TProtocol> oprot) {
+ piprot_=iprot;
+ poprot_=oprot;
+ iprot_ = iprot.get();
+ oprot_ = oprot.get();
+ }
+ public:
+ std::shared_ptr< ::apache::thrift::protocol::TProtocol> getInputProtocol() {
+ return piprot_;
+ }
+ std::shared_ptr< ::apache::thrift::protocol::TProtocol> getOutputProtocol() {
+ return poprot_;
+ }
+ void startTrace(TraceResponse& _return, const StartTraceRequest& request);
+ void send_startTrace(const StartTraceRequest& request);
+ void recv_startTrace(TraceResponse& _return);
+ void joinTrace(TraceResponse& _return, const JoinTraceRequest& request);
+ void send_joinTrace(const JoinTraceRequest& request);
+ void recv_joinTrace(TraceResponse& _return);
+ protected:
+ std::shared_ptr< ::apache::thrift::protocol::TProtocol> piprot_;
+ std::shared_ptr< ::apache::thrift::protocol::TProtocol> poprot_;
+ ::apache::thrift::protocol::TProtocol* iprot_;
+ ::apache::thrift::protocol::TProtocol* oprot_;
+};
+
+class TracedServiceProcessor : public ::apache::thrift::TDispatchProcessor {
+ protected:
+ ::std::shared_ptr<TracedServiceIf> iface_;
+ virtual bool dispatchCall(::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, const std::string& fname, int32_t seqid, void* callContext);
+ private:
+ typedef void (TracedServiceProcessor::*ProcessFunction)(int32_t, ::apache::thrift::protocol::TProtocol*, ::apache::thrift::protocol::TProtocol*, void*);
+ typedef std::map<std::string, ProcessFunction> ProcessMap;
+ ProcessMap processMap_;
+ void process_startTrace(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext);
+ void process_joinTrace(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext);
+ public:
+ TracedServiceProcessor(::std::shared_ptr<TracedServiceIf> iface) :
+ iface_(iface) {
+ processMap_["startTrace"] = &TracedServiceProcessor::process_startTrace;
+ processMap_["joinTrace"] = &TracedServiceProcessor::process_joinTrace;
+ }
+
+ virtual ~TracedServiceProcessor() {}
+};
+
+class TracedServiceProcessorFactory : public ::apache::thrift::TProcessorFactory {
+ public:
+ TracedServiceProcessorFactory(const ::std::shared_ptr< TracedServiceIfFactory >& handlerFactory) :
+ handlerFactory_(handlerFactory) {}
+
+ ::std::shared_ptr< ::apache::thrift::TProcessor > getProcessor(const ::apache::thrift::TConnectionInfo& connInfo);
+
+ protected:
+ ::std::shared_ptr< TracedServiceIfFactory > handlerFactory_;
+};
+
+class TracedServiceMultiface : virtual public TracedServiceIf {
+ public:
+ TracedServiceMultiface(std::vector<std::shared_ptr<TracedServiceIf> >& ifaces) : ifaces_(ifaces) {
+ }
+ virtual ~TracedServiceMultiface() {}
+ protected:
+ std::vector<std::shared_ptr<TracedServiceIf> > ifaces_;
+ TracedServiceMultiface() {}
+ void add(::std::shared_ptr<TracedServiceIf> iface) {
+ ifaces_.push_back(iface);
+ }
+ public:
+ void startTrace(TraceResponse& _return, const StartTraceRequest& request) {
+ size_t sz = ifaces_.size();
+ size_t i = 0;
+ for (; i < (sz - 1); ++i) {
+ ifaces_[i]->startTrace(_return, request);
+ }
+ ifaces_[i]->startTrace(_return, request);
+ return;
+ }
+
+ void joinTrace(TraceResponse& _return, const JoinTraceRequest& request) {
+ size_t sz = ifaces_.size();
+ size_t i = 0;
+ for (; i < (sz - 1); ++i) {
+ ifaces_[i]->joinTrace(_return, request);
+ }
+ ifaces_[i]->joinTrace(_return, request);
+ return;
+ }
+
+};
+
+// The 'concurrent' client is a thread safe client that correctly handles
+// out of order responses. It is slower than the regular client, so should
+// only be used when you need to share a connection among multiple threads
+class TracedServiceConcurrentClient : virtual public TracedServiceIf {
+ public:
+ TracedServiceConcurrentClient(std::shared_ptr< ::apache::thrift::protocol::TProtocol> prot) {
+ setProtocol(prot);
+ }
+ TracedServiceConcurrentClient(std::shared_ptr< ::apache::thrift::protocol::TProtocol> iprot, std::shared_ptr< ::apache::thrift::protocol::TProtocol> oprot) {
+ setProtocol(iprot,oprot);
+ }
+ private:
+ void setProtocol(std::shared_ptr< ::apache::thrift::protocol::TProtocol> prot) {
+ setProtocol(prot,prot);
+ }
+ void setProtocol(std::shared_ptr< ::apache::thrift::protocol::TProtocol> iprot, std::shared_ptr< ::apache::thrift::protocol::TProtocol> oprot) {
+ piprot_=iprot;
+ poprot_=oprot;
+ iprot_ = iprot.get();
+ oprot_ = oprot.get();
+ }
+ public:
+ std::shared_ptr< ::apache::thrift::protocol::TProtocol> getInputProtocol() {
+ return piprot_;
+ }
+ std::shared_ptr< ::apache::thrift::protocol::TProtocol> getOutputProtocol() {
+ return poprot_;
+ }
+ void startTrace(TraceResponse& _return, const StartTraceRequest& request);
+ int32_t send_startTrace(const StartTraceRequest& request);
+ void recv_startTrace(TraceResponse& _return, const int32_t seqid);
+ void joinTrace(TraceResponse& _return, const JoinTraceRequest& request);
+ int32_t send_joinTrace(const JoinTraceRequest& request);
+ void recv_joinTrace(TraceResponse& _return, const int32_t seqid);
+ protected:
+ std::shared_ptr< ::apache::thrift::protocol::TProtocol> piprot_;
+ std::shared_ptr< ::apache::thrift::protocol::TProtocol> poprot_;
+ ::apache::thrift::protocol::TProtocol* iprot_;
+ ::apache::thrift::protocol::TProtocol* oprot_;
+ ::apache::thrift::async::TConcurrentClientSyncInfo sync_;
+};
+
+#ifdef _MSC_VER
+ #pragma warning( pop )
+#endif
+
+}}} // namespace
+
+#endif
diff --git a/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/thrift-gen/ZipkinCollector.cpp b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/thrift-gen/ZipkinCollector.cpp
new file mode 100644
index 000000000..035bd7095
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/thrift-gen/ZipkinCollector.cpp
@@ -0,0 +1,481 @@
+/**
+ * Autogenerated by Thrift Compiler (0.11.0)
+ *
+ * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
+ * @generated
+ */
+#include "ZipkinCollector.h"
+
+namespace twitter { namespace zipkin { namespace thrift {
+
+
+ZipkinCollector_submitZipkinBatch_args::~ZipkinCollector_submitZipkinBatch_args() throw() {
+}
+
+
+uint32_t ZipkinCollector_submitZipkinBatch_args::read(::apache::thrift::protocol::TProtocol* iprot) {
+
+ ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
+ uint32_t xfer = 0;
+ std::string fname;
+ ::apache::thrift::protocol::TType ftype;
+ int16_t fid;
+
+ xfer += iprot->readStructBegin(fname);
+
+ using ::apache::thrift::protocol::TProtocolException;
+
+
+ while (true)
+ {
+ xfer += iprot->readFieldBegin(fname, ftype, fid);
+ if (ftype == ::apache::thrift::protocol::T_STOP) {
+ break;
+ }
+ switch (fid)
+ {
+ case 1:
+ if (ftype == ::apache::thrift::protocol::T_LIST) {
+ {
+ this->spans.clear();
+ uint32_t _size23;
+ ::apache::thrift::protocol::TType _etype26;
+ xfer += iprot->readListBegin(_etype26, _size23);
+ this->spans.resize(_size23);
+ uint32_t _i27;
+ for (_i27 = 0; _i27 < _size23; ++_i27)
+ {
+ xfer += this->spans[_i27].read(iprot);
+ }
+ xfer += iprot->readListEnd();
+ }
+ this->__isset.spans = true;
+ } else {
+ xfer += iprot->skip(ftype);
+ }
+ break;
+ default:
+ xfer += iprot->skip(ftype);
+ break;
+ }
+ xfer += iprot->readFieldEnd();
+ }
+
+ xfer += iprot->readStructEnd();
+
+ return xfer;
+}
+
+uint32_t ZipkinCollector_submitZipkinBatch_args::write(::apache::thrift::protocol::TProtocol* oprot) const {
+ uint32_t xfer = 0;
+ ::apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
+ xfer += oprot->writeStructBegin("ZipkinCollector_submitZipkinBatch_args");
+
+ xfer += oprot->writeFieldBegin("spans", ::apache::thrift::protocol::T_LIST, 1);
+ {
+ xfer += oprot->writeListBegin(::apache::thrift::protocol::T_STRUCT, static_cast<uint32_t>(this->spans.size()));
+ std::vector<Span> ::const_iterator _iter28;
+ for (_iter28 = this->spans.begin(); _iter28 != this->spans.end(); ++_iter28)
+ {
+ xfer += (*_iter28).write(oprot);
+ }
+ xfer += oprot->writeListEnd();
+ }
+ xfer += oprot->writeFieldEnd();
+
+ xfer += oprot->writeFieldStop();
+ xfer += oprot->writeStructEnd();
+ return xfer;
+}
+
+
+ZipkinCollector_submitZipkinBatch_pargs::~ZipkinCollector_submitZipkinBatch_pargs() throw() {
+}
+
+
+uint32_t ZipkinCollector_submitZipkinBatch_pargs::write(::apache::thrift::protocol::TProtocol* oprot) const {
+ uint32_t xfer = 0;
+ ::apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
+ xfer += oprot->writeStructBegin("ZipkinCollector_submitZipkinBatch_pargs");
+
+ xfer += oprot->writeFieldBegin("spans", ::apache::thrift::protocol::T_LIST, 1);
+ {
+ xfer += oprot->writeListBegin(::apache::thrift::protocol::T_STRUCT, static_cast<uint32_t>((*(this->spans)).size()));
+ std::vector<Span> ::const_iterator _iter29;
+ for (_iter29 = (*(this->spans)).begin(); _iter29 != (*(this->spans)).end(); ++_iter29)
+ {
+ xfer += (*_iter29).write(oprot);
+ }
+ xfer += oprot->writeListEnd();
+ }
+ xfer += oprot->writeFieldEnd();
+
+ xfer += oprot->writeFieldStop();
+ xfer += oprot->writeStructEnd();
+ return xfer;
+}
+
+
+ZipkinCollector_submitZipkinBatch_result::~ZipkinCollector_submitZipkinBatch_result() throw() {
+}
+
+
+uint32_t ZipkinCollector_submitZipkinBatch_result::read(::apache::thrift::protocol::TProtocol* iprot) {
+
+ ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
+ uint32_t xfer = 0;
+ std::string fname;
+ ::apache::thrift::protocol::TType ftype;
+ int16_t fid;
+
+ xfer += iprot->readStructBegin(fname);
+
+ using ::apache::thrift::protocol::TProtocolException;
+
+
+ while (true)
+ {
+ xfer += iprot->readFieldBegin(fname, ftype, fid);
+ if (ftype == ::apache::thrift::protocol::T_STOP) {
+ break;
+ }
+ switch (fid)
+ {
+ case 0:
+ if (ftype == ::apache::thrift::protocol::T_LIST) {
+ {
+ this->success.clear();
+ uint32_t _size30;
+ ::apache::thrift::protocol::TType _etype33;
+ xfer += iprot->readListBegin(_etype33, _size30);
+ this->success.resize(_size30);
+ uint32_t _i34;
+ for (_i34 = 0; _i34 < _size30; ++_i34)
+ {
+ xfer += this->success[_i34].read(iprot);
+ }
+ xfer += iprot->readListEnd();
+ }
+ this->__isset.success = true;
+ } else {
+ xfer += iprot->skip(ftype);
+ }
+ break;
+ default:
+ xfer += iprot->skip(ftype);
+ break;
+ }
+ xfer += iprot->readFieldEnd();
+ }
+
+ xfer += iprot->readStructEnd();
+
+ return xfer;
+}
+
+uint32_t ZipkinCollector_submitZipkinBatch_result::write(::apache::thrift::protocol::TProtocol* oprot) const {
+
+ uint32_t xfer = 0;
+
+ xfer += oprot->writeStructBegin("ZipkinCollector_submitZipkinBatch_result");
+
+ if (this->__isset.success) {
+ xfer += oprot->writeFieldBegin("success", ::apache::thrift::protocol::T_LIST, 0);
+ {
+ xfer += oprot->writeListBegin(::apache::thrift::protocol::T_STRUCT, static_cast<uint32_t>(this->success.size()));
+ std::vector<Response> ::const_iterator _iter35;
+ for (_iter35 = this->success.begin(); _iter35 != this->success.end(); ++_iter35)
+ {
+ xfer += (*_iter35).write(oprot);
+ }
+ xfer += oprot->writeListEnd();
+ }
+ xfer += oprot->writeFieldEnd();
+ }
+ xfer += oprot->writeFieldStop();
+ xfer += oprot->writeStructEnd();
+ return xfer;
+}
+
+
+ZipkinCollector_submitZipkinBatch_presult::~ZipkinCollector_submitZipkinBatch_presult() throw() {
+}
+
+
+uint32_t ZipkinCollector_submitZipkinBatch_presult::read(::apache::thrift::protocol::TProtocol* iprot) {
+
+ ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
+ uint32_t xfer = 0;
+ std::string fname;
+ ::apache::thrift::protocol::TType ftype;
+ int16_t fid;
+
+ xfer += iprot->readStructBegin(fname);
+
+ using ::apache::thrift::protocol::TProtocolException;
+
+
+ while (true)
+ {
+ xfer += iprot->readFieldBegin(fname, ftype, fid);
+ if (ftype == ::apache::thrift::protocol::T_STOP) {
+ break;
+ }
+ switch (fid)
+ {
+ case 0:
+ if (ftype == ::apache::thrift::protocol::T_LIST) {
+ {
+ (*(this->success)).clear();
+ uint32_t _size36;
+ ::apache::thrift::protocol::TType _etype39;
+ xfer += iprot->readListBegin(_etype39, _size36);
+ (*(this->success)).resize(_size36);
+ uint32_t _i40;
+ for (_i40 = 0; _i40 < _size36; ++_i40)
+ {
+ xfer += (*(this->success))[_i40].read(iprot);
+ }
+ xfer += iprot->readListEnd();
+ }
+ this->__isset.success = true;
+ } else {
+ xfer += iprot->skip(ftype);
+ }
+ break;
+ default:
+ xfer += iprot->skip(ftype);
+ break;
+ }
+ xfer += iprot->readFieldEnd();
+ }
+
+ xfer += iprot->readStructEnd();
+
+ return xfer;
+}
+
+void ZipkinCollectorClient::submitZipkinBatch(std::vector<Response> & _return, const std::vector<Span> & spans)
+{
+ send_submitZipkinBatch(spans);
+ recv_submitZipkinBatch(_return);
+}
+
+void ZipkinCollectorClient::send_submitZipkinBatch(const std::vector<Span> & spans)
+{
+ int32_t cseqid = 0;
+ oprot_->writeMessageBegin("submitZipkinBatch", ::apache::thrift::protocol::T_CALL, cseqid);
+
+ ZipkinCollector_submitZipkinBatch_pargs args;
+ args.spans = &spans;
+ args.write(oprot_);
+
+ oprot_->writeMessageEnd();
+ oprot_->getTransport()->writeEnd();
+ oprot_->getTransport()->flush();
+}
+
+void ZipkinCollectorClient::recv_submitZipkinBatch(std::vector<Response> & _return)
+{
+
+ int32_t rseqid = 0;
+ std::string fname;
+ ::apache::thrift::protocol::TMessageType mtype;
+
+ iprot_->readMessageBegin(fname, mtype, rseqid);
+ if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
+ ::apache::thrift::TApplicationException x;
+ x.read(iprot_);
+ iprot_->readMessageEnd();
+ iprot_->getTransport()->readEnd();
+ throw x;
+ }
+ if (mtype != ::apache::thrift::protocol::T_REPLY) {
+ iprot_->skip(::apache::thrift::protocol::T_STRUCT);
+ iprot_->readMessageEnd();
+ iprot_->getTransport()->readEnd();
+ }
+ if (fname.compare("submitZipkinBatch") != 0) {
+ iprot_->skip(::apache::thrift::protocol::T_STRUCT);
+ iprot_->readMessageEnd();
+ iprot_->getTransport()->readEnd();
+ }
+ ZipkinCollector_submitZipkinBatch_presult result;
+ result.success = &_return;
+ result.read(iprot_);
+ iprot_->readMessageEnd();
+ iprot_->getTransport()->readEnd();
+
+ if (result.__isset.success) {
+ // _return pointer has now been filled
+ return;
+ }
+ throw ::apache::thrift::TApplicationException(::apache::thrift::TApplicationException::MISSING_RESULT, "submitZipkinBatch failed: unknown result");
+}
+
+bool ZipkinCollectorProcessor::dispatchCall(::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, const std::string& fname, int32_t seqid, void* callContext) {
+ ProcessMap::iterator pfn;
+ pfn = processMap_.find(fname);
+ if (pfn == processMap_.end()) {
+ iprot->skip(::apache::thrift::protocol::T_STRUCT);
+ iprot->readMessageEnd();
+ iprot->getTransport()->readEnd();
+ ::apache::thrift::TApplicationException x(::apache::thrift::TApplicationException::UNKNOWN_METHOD, "Invalid method name: '"+fname+"'");
+ oprot->writeMessageBegin(fname, ::apache::thrift::protocol::T_EXCEPTION, seqid);
+ x.write(oprot);
+ oprot->writeMessageEnd();
+ oprot->getTransport()->writeEnd();
+ oprot->getTransport()->flush();
+ return true;
+ }
+ (this->*(pfn->second))(seqid, iprot, oprot, callContext);
+ return true;
+}
+
+void ZipkinCollectorProcessor::process_submitZipkinBatch(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext)
+{
+ void* ctx = NULL;
+ if (this->eventHandler_.get() != NULL) {
+ ctx = this->eventHandler_->getContext("ZipkinCollector.submitZipkinBatch", callContext);
+ }
+ ::apache::thrift::TProcessorContextFreer freer(this->eventHandler_.get(), ctx, "ZipkinCollector.submitZipkinBatch");
+
+ if (this->eventHandler_.get() != NULL) {
+ this->eventHandler_->preRead(ctx, "ZipkinCollector.submitZipkinBatch");
+ }
+
+ ZipkinCollector_submitZipkinBatch_args args;
+ args.read(iprot);
+ iprot->readMessageEnd();
+ uint32_t bytes = iprot->getTransport()->readEnd();
+
+ if (this->eventHandler_.get() != NULL) {
+ this->eventHandler_->postRead(ctx, "ZipkinCollector.submitZipkinBatch", bytes);
+ }
+
+ ZipkinCollector_submitZipkinBatch_result result;
+ try {
+ iface_->submitZipkinBatch(result.success, args.spans);
+ result.__isset.success = true;
+ } catch (const std::exception& e) {
+ if (this->eventHandler_.get() != NULL) {
+ this->eventHandler_->handlerError(ctx, "ZipkinCollector.submitZipkinBatch");
+ }
+
+ ::apache::thrift::TApplicationException x(e.what());
+ oprot->writeMessageBegin("submitZipkinBatch", ::apache::thrift::protocol::T_EXCEPTION, seqid);
+ x.write(oprot);
+ oprot->writeMessageEnd();
+ oprot->getTransport()->writeEnd();
+ oprot->getTransport()->flush();
+ return;
+ }
+
+ if (this->eventHandler_.get() != NULL) {
+ this->eventHandler_->preWrite(ctx, "ZipkinCollector.submitZipkinBatch");
+ }
+
+ oprot->writeMessageBegin("submitZipkinBatch", ::apache::thrift::protocol::T_REPLY, seqid);
+ result.write(oprot);
+ oprot->writeMessageEnd();
+ bytes = oprot->getTransport()->writeEnd();
+ oprot->getTransport()->flush();
+
+ if (this->eventHandler_.get() != NULL) {
+ this->eventHandler_->postWrite(ctx, "ZipkinCollector.submitZipkinBatch", bytes);
+ }
+}
+
+::std::shared_ptr< ::apache::thrift::TProcessor > ZipkinCollectorProcessorFactory::getProcessor(const ::apache::thrift::TConnectionInfo& connInfo) {
+ ::apache::thrift::ReleaseHandler< ZipkinCollectorIfFactory > cleanup(handlerFactory_);
+ ::std::shared_ptr< ZipkinCollectorIf > handler(handlerFactory_->getHandler(connInfo), cleanup);
+ ::std::shared_ptr< ::apache::thrift::TProcessor > processor(new ZipkinCollectorProcessor(handler));
+ return processor;
+}
+
+void ZipkinCollectorConcurrentClient::submitZipkinBatch(std::vector<Response> & _return, const std::vector<Span> & spans)
+{
+ int32_t seqid = send_submitZipkinBatch(spans);
+ recv_submitZipkinBatch(_return, seqid);
+}
+
+int32_t ZipkinCollectorConcurrentClient::send_submitZipkinBatch(const std::vector<Span> & spans)
+{
+ int32_t cseqid = this->sync_.generateSeqId();
+ ::apache::thrift::async::TConcurrentSendSentry sentry(&this->sync_);
+ oprot_->writeMessageBegin("submitZipkinBatch", ::apache::thrift::protocol::T_CALL, cseqid);
+
+ ZipkinCollector_submitZipkinBatch_pargs args;
+ args.spans = &spans;
+ args.write(oprot_);
+
+ oprot_->writeMessageEnd();
+ oprot_->getTransport()->writeEnd();
+ oprot_->getTransport()->flush();
+
+ sentry.commit();
+ return cseqid;
+}
+
+void ZipkinCollectorConcurrentClient::recv_submitZipkinBatch(std::vector<Response> & _return, const int32_t seqid)
+{
+
+ int32_t rseqid = 0;
+ std::string fname;
+ ::apache::thrift::protocol::TMessageType mtype;
+
+ // the read mutex gets dropped and reacquired as part of waitForWork()
+ // The destructor of this sentry wakes up other clients
+ ::apache::thrift::async::TConcurrentRecvSentry sentry(&this->sync_, seqid);
+
+ while(true) {
+ if(!this->sync_.getPending(fname, mtype, rseqid)) {
+ iprot_->readMessageBegin(fname, mtype, rseqid);
+ }
+ if(seqid == rseqid) {
+ if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
+ ::apache::thrift::TApplicationException x;
+ x.read(iprot_);
+ iprot_->readMessageEnd();
+ iprot_->getTransport()->readEnd();
+ sentry.commit();
+ throw x;
+ }
+ if (mtype != ::apache::thrift::protocol::T_REPLY) {
+ iprot_->skip(::apache::thrift::protocol::T_STRUCT);
+ iprot_->readMessageEnd();
+ iprot_->getTransport()->readEnd();
+ }
+ if (fname.compare("submitZipkinBatch") != 0) {
+ iprot_->skip(::apache::thrift::protocol::T_STRUCT);
+ iprot_->readMessageEnd();
+ iprot_->getTransport()->readEnd();
+
+ // in a bad state, don't commit
+ using ::apache::thrift::protocol::TProtocolException;
+ throw TProtocolException(TProtocolException::INVALID_DATA);
+ }
+ ZipkinCollector_submitZipkinBatch_presult result;
+ result.success = &_return;
+ result.read(iprot_);
+ iprot_->readMessageEnd();
+ iprot_->getTransport()->readEnd();
+
+ if (result.__isset.success) {
+ // _return pointer has now been filled
+ sentry.commit();
+ return;
+ }
+ // in a bad state, don't commit
+ throw ::apache::thrift::TApplicationException(::apache::thrift::TApplicationException::MISSING_RESULT, "submitZipkinBatch failed: unknown result");
+ }
+ // seqid != rseqid
+ this->sync_.updatePending(fname, mtype, rseqid);
+
+ // this will temporarily unlock the readMutex, and let other clients get work done
+ this->sync_.waitForWork(seqid);
+ } // end while(true)
+}
+
+}}} // namespace
+
diff --git a/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/thrift-gen/ZipkinCollector.h b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/thrift-gen/ZipkinCollector.h
new file mode 100644
index 000000000..005290ce6
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/thrift-gen/ZipkinCollector.h
@@ -0,0 +1,296 @@
+/**
+ * Autogenerated by Thrift Compiler (0.11.0)
+ *
+ * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
+ * @generated
+ */
+#ifndef ZipkinCollector_H
+#define ZipkinCollector_H
+
+#include <thrift/TDispatchProcessor.h>
+#include <thrift/async/TConcurrentClientSyncInfo.h>
+#include "zipkincore_types.h"
+
+namespace twitter { namespace zipkin { namespace thrift {
+
+#ifdef _MSC_VER
+ #pragma warning( push )
+ #pragma warning (disable : 4250 ) //inheriting methods via dominance
+#endif
+
+class ZipkinCollectorIf {
+ public:
+ virtual ~ZipkinCollectorIf() {}
+ virtual void submitZipkinBatch(std::vector<Response> & _return, const std::vector<Span> & spans) = 0;
+};
+
+class ZipkinCollectorIfFactory {
+ public:
+ typedef ZipkinCollectorIf Handler;
+
+ virtual ~ZipkinCollectorIfFactory() {}
+
+ virtual ZipkinCollectorIf* getHandler(const ::apache::thrift::TConnectionInfo& connInfo) = 0;
+ virtual void releaseHandler(ZipkinCollectorIf* /* handler */) = 0;
+};
+
+class ZipkinCollectorIfSingletonFactory : virtual public ZipkinCollectorIfFactory {
+ public:
+ ZipkinCollectorIfSingletonFactory(const ::std::shared_ptr<ZipkinCollectorIf>& iface) : iface_(iface) {}
+ virtual ~ZipkinCollectorIfSingletonFactory() {}
+
+ virtual ZipkinCollectorIf* getHandler(const ::apache::thrift::TConnectionInfo&) {
+ return iface_.get();
+ }
+ virtual void releaseHandler(ZipkinCollectorIf* /* handler */) {}
+
+ protected:
+ ::std::shared_ptr<ZipkinCollectorIf> iface_;
+};
+
+class ZipkinCollectorNull : virtual public ZipkinCollectorIf {
+ public:
+ virtual ~ZipkinCollectorNull() {}
+ void submitZipkinBatch(std::vector<Response> & /* _return */, const std::vector<Span> & /* spans */) {
+ return;
+ }
+};
+
+typedef struct _ZipkinCollector_submitZipkinBatch_args__isset {
+ _ZipkinCollector_submitZipkinBatch_args__isset() : spans(false) {}
+ bool spans :1;
+} _ZipkinCollector_submitZipkinBatch_args__isset;
+
+class ZipkinCollector_submitZipkinBatch_args {
+ public:
+
+ ZipkinCollector_submitZipkinBatch_args(const ZipkinCollector_submitZipkinBatch_args&);
+ ZipkinCollector_submitZipkinBatch_args& operator=(const ZipkinCollector_submitZipkinBatch_args&);
+ ZipkinCollector_submitZipkinBatch_args() {
+ }
+
+ virtual ~ZipkinCollector_submitZipkinBatch_args() throw();
+ std::vector<Span> spans;
+
+ _ZipkinCollector_submitZipkinBatch_args__isset __isset;
+
+ void __set_spans(const std::vector<Span> & val);
+
+ bool operator == (const ZipkinCollector_submitZipkinBatch_args & rhs) const
+ {
+ if (!(spans == rhs.spans))
+ return false;
+ return true;
+ }
+ bool operator != (const ZipkinCollector_submitZipkinBatch_args &rhs) const {
+ return !(*this == rhs);
+ }
+
+ bool operator < (const ZipkinCollector_submitZipkinBatch_args & ) const;
+
+ uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
+ uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;
+
+};
+
+
+class ZipkinCollector_submitZipkinBatch_pargs {
+ public:
+
+
+ virtual ~ZipkinCollector_submitZipkinBatch_pargs() throw();
+ const std::vector<Span> * spans;
+
+ uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;
+
+};
+
+typedef struct _ZipkinCollector_submitZipkinBatch_result__isset {
+ _ZipkinCollector_submitZipkinBatch_result__isset() : success(false) {}
+ bool success :1;
+} _ZipkinCollector_submitZipkinBatch_result__isset;
+
+class ZipkinCollector_submitZipkinBatch_result {
+ public:
+
+ ZipkinCollector_submitZipkinBatch_result(const ZipkinCollector_submitZipkinBatch_result&);
+ ZipkinCollector_submitZipkinBatch_result& operator=(const ZipkinCollector_submitZipkinBatch_result&);
+ ZipkinCollector_submitZipkinBatch_result() {
+ }
+
+ virtual ~ZipkinCollector_submitZipkinBatch_result() throw();
+ std::vector<Response> success;
+
+ _ZipkinCollector_submitZipkinBatch_result__isset __isset;
+
+ void __set_success(const std::vector<Response> & val);
+
+ bool operator == (const ZipkinCollector_submitZipkinBatch_result & rhs) const
+ {
+ if (!(success == rhs.success))
+ return false;
+ return true;
+ }
+ bool operator != (const ZipkinCollector_submitZipkinBatch_result &rhs) const {
+ return !(*this == rhs);
+ }
+
+ bool operator < (const ZipkinCollector_submitZipkinBatch_result & ) const;
+
+ uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
+ uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;
+
+};
+
+typedef struct _ZipkinCollector_submitZipkinBatch_presult__isset {
+ _ZipkinCollector_submitZipkinBatch_presult__isset() : success(false) {}
+ bool success :1;
+} _ZipkinCollector_submitZipkinBatch_presult__isset;
+
+class ZipkinCollector_submitZipkinBatch_presult {
+ public:
+
+
+ virtual ~ZipkinCollector_submitZipkinBatch_presult() throw();
+ std::vector<Response> * success;
+
+ _ZipkinCollector_submitZipkinBatch_presult__isset __isset;
+
+ uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
+
+};
+
+class ZipkinCollectorClient : virtual public ZipkinCollectorIf {
+ public:
+ ZipkinCollectorClient(std::shared_ptr< ::apache::thrift::protocol::TProtocol> prot) {
+ setProtocol(prot);
+ }
+ ZipkinCollectorClient(std::shared_ptr< ::apache::thrift::protocol::TProtocol> iprot, std::shared_ptr< ::apache::thrift::protocol::TProtocol> oprot) {
+ setProtocol(iprot,oprot);
+ }
+ private:
+ void setProtocol(std::shared_ptr< ::apache::thrift::protocol::TProtocol> prot) {
+ setProtocol(prot,prot);
+ }
+ void setProtocol(std::shared_ptr< ::apache::thrift::protocol::TProtocol> iprot, std::shared_ptr< ::apache::thrift::protocol::TProtocol> oprot) {
+ piprot_=iprot;
+ poprot_=oprot;
+ iprot_ = iprot.get();
+ oprot_ = oprot.get();
+ }
+ public:
+ std::shared_ptr< ::apache::thrift::protocol::TProtocol> getInputProtocol() {
+ return piprot_;
+ }
+ std::shared_ptr< ::apache::thrift::protocol::TProtocol> getOutputProtocol() {
+ return poprot_;
+ }
+ void submitZipkinBatch(std::vector<Response> & _return, const std::vector<Span> & spans);
+ void send_submitZipkinBatch(const std::vector<Span> & spans);
+ void recv_submitZipkinBatch(std::vector<Response> & _return);
+ protected:
+ std::shared_ptr< ::apache::thrift::protocol::TProtocol> piprot_;
+ std::shared_ptr< ::apache::thrift::protocol::TProtocol> poprot_;
+ ::apache::thrift::protocol::TProtocol* iprot_;
+ ::apache::thrift::protocol::TProtocol* oprot_;
+};
+
+class ZipkinCollectorProcessor : public ::apache::thrift::TDispatchProcessor {
+ protected:
+ ::std::shared_ptr<ZipkinCollectorIf> iface_;
+ virtual bool dispatchCall(::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, const std::string& fname, int32_t seqid, void* callContext);
+ private:
+ typedef void (ZipkinCollectorProcessor::*ProcessFunction)(int32_t, ::apache::thrift::protocol::TProtocol*, ::apache::thrift::protocol::TProtocol*, void*);
+ typedef std::map<std::string, ProcessFunction> ProcessMap;
+ ProcessMap processMap_;
+ void process_submitZipkinBatch(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext);
+ public:
+ ZipkinCollectorProcessor(::std::shared_ptr<ZipkinCollectorIf> iface) :
+ iface_(iface) {
+ processMap_["submitZipkinBatch"] = &ZipkinCollectorProcessor::process_submitZipkinBatch;
+ }
+
+ virtual ~ZipkinCollectorProcessor() {}
+};
+
+class ZipkinCollectorProcessorFactory : public ::apache::thrift::TProcessorFactory {
+ public:
+ ZipkinCollectorProcessorFactory(const ::std::shared_ptr< ZipkinCollectorIfFactory >& handlerFactory) :
+ handlerFactory_(handlerFactory) {}
+
+ ::std::shared_ptr< ::apache::thrift::TProcessor > getProcessor(const ::apache::thrift::TConnectionInfo& connInfo);
+
+ protected:
+ ::std::shared_ptr< ZipkinCollectorIfFactory > handlerFactory_;
+};
+
+class ZipkinCollectorMultiface : virtual public ZipkinCollectorIf {
+ public:
+ ZipkinCollectorMultiface(std::vector<std::shared_ptr<ZipkinCollectorIf> >& ifaces) : ifaces_(ifaces) {
+ }
+ virtual ~ZipkinCollectorMultiface() {}
+ protected:
+ std::vector<std::shared_ptr<ZipkinCollectorIf> > ifaces_;
+ ZipkinCollectorMultiface() {}
+ void add(::std::shared_ptr<ZipkinCollectorIf> iface) {
+ ifaces_.push_back(iface);
+ }
+ public:
+ void submitZipkinBatch(std::vector<Response> & _return, const std::vector<Span> & spans) {
+ size_t sz = ifaces_.size();
+ size_t i = 0;
+ for (; i < (sz - 1); ++i) {
+ ifaces_[i]->submitZipkinBatch(_return, spans);
+ }
+ ifaces_[i]->submitZipkinBatch(_return, spans);
+ return;
+ }
+
+};
+
+// The 'concurrent' client is a thread safe client that correctly handles
+// out of order responses. It is slower than the regular client, so should
+// only be used when you need to share a connection among multiple threads
+class ZipkinCollectorConcurrentClient : virtual public ZipkinCollectorIf {
+ public:
+ ZipkinCollectorConcurrentClient(std::shared_ptr< ::apache::thrift::protocol::TProtocol> prot) {
+ setProtocol(prot);
+ }
+ ZipkinCollectorConcurrentClient(std::shared_ptr< ::apache::thrift::protocol::TProtocol> iprot, std::shared_ptr< ::apache::thrift::protocol::TProtocol> oprot) {
+ setProtocol(iprot,oprot);
+ }
+ private:
+ void setProtocol(std::shared_ptr< ::apache::thrift::protocol::TProtocol> prot) {
+ setProtocol(prot,prot);
+ }
+ void setProtocol(std::shared_ptr< ::apache::thrift::protocol::TProtocol> iprot, std::shared_ptr< ::apache::thrift::protocol::TProtocol> oprot) {
+ piprot_=iprot;
+ poprot_=oprot;
+ iprot_ = iprot.get();
+ oprot_ = oprot.get();
+ }
+ public:
+ std::shared_ptr< ::apache::thrift::protocol::TProtocol> getInputProtocol() {
+ return piprot_;
+ }
+ std::shared_ptr< ::apache::thrift::protocol::TProtocol> getOutputProtocol() {
+ return poprot_;
+ }
+ void submitZipkinBatch(std::vector<Response> & _return, const std::vector<Span> & spans);
+ int32_t send_submitZipkinBatch(const std::vector<Span> & spans);
+ void recv_submitZipkinBatch(std::vector<Response> & _return, const int32_t seqid);
+ protected:
+ std::shared_ptr< ::apache::thrift::protocol::TProtocol> piprot_;
+ std::shared_ptr< ::apache::thrift::protocol::TProtocol> poprot_;
+ ::apache::thrift::protocol::TProtocol* iprot_;
+ ::apache::thrift::protocol::TProtocol* oprot_;
+ ::apache::thrift::async::TConcurrentClientSyncInfo sync_;
+};
+
+#ifdef _MSC_VER
+ #pragma warning( pop )
+#endif
+
+}}} // namespace
+
+#endif
diff --git a/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/thrift-gen/agent_constants.cpp b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/thrift-gen/agent_constants.cpp
new file mode 100644
index 000000000..f6a9d94ef
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/thrift-gen/agent_constants.cpp
@@ -0,0 +1,17 @@
+/**
+ * Autogenerated by Thrift Compiler (0.11.0)
+ *
+ * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
+ * @generated
+ */
+#include "agent_constants.h"
+
+namespace jaegertracing { namespace agent { namespace thrift {
+
+const agentConstants g_agent_constants;
+
+agentConstants::agentConstants() {
+}
+
+}}} // namespace
+
diff --git a/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/thrift-gen/agent_constants.h b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/thrift-gen/agent_constants.h
new file mode 100644
index 000000000..31302545f
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/thrift-gen/agent_constants.h
@@ -0,0 +1,24 @@
+/**
+ * Autogenerated by Thrift Compiler (0.11.0)
+ *
+ * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
+ * @generated
+ */
+#ifndef agent_CONSTANTS_H
+#define agent_CONSTANTS_H
+
+#include "agent_types.h"
+
+namespace jaegertracing { namespace agent { namespace thrift {
+
+class agentConstants {
+ public:
+ agentConstants();
+
+};
+
+extern const agentConstants g_agent_constants;
+
+}}} // namespace
+
+#endif
diff --git a/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/thrift-gen/agent_types.cpp b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/thrift-gen/agent_types.cpp
new file mode 100644
index 000000000..c06f58dc0
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/thrift-gen/agent_types.cpp
@@ -0,0 +1,16 @@
+/**
+ * Autogenerated by Thrift Compiler (0.11.0)
+ *
+ * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
+ * @generated
+ */
+#include "agent_types.h"
+
+#include <algorithm>
+#include <ostream>
+
+#include <thrift/TToString.h>
+
+namespace jaegertracing { namespace agent { namespace thrift {
+
+}}} // namespace
diff --git a/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/thrift-gen/agent_types.h b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/thrift-gen/agent_types.h
new file mode 100644
index 000000000..772f3c1ab
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/thrift-gen/agent_types.h
@@ -0,0 +1,26 @@
+/**
+ * Autogenerated by Thrift Compiler (0.11.0)
+ *
+ * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
+ * @generated
+ */
+#ifndef agent_TYPES_H
+#define agent_TYPES_H
+
+#include <iosfwd>
+
+#include <thrift/Thrift.h>
+#include <thrift/TApplicationException.h>
+#include <thrift/TBase.h>
+#include <thrift/protocol/TProtocol.h>
+#include <thrift/transport/TTransport.h>
+
+#include "jaeger_types.h"
+#include "zipkincore_types.h"
+
+
+namespace jaegertracing { namespace agent { namespace thrift {
+
+}}} // namespace
+
+#endif
diff --git a/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/thrift-gen/aggregation_validator_constants.cpp b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/thrift-gen/aggregation_validator_constants.cpp
new file mode 100644
index 000000000..727fcd22e
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/thrift-gen/aggregation_validator_constants.cpp
@@ -0,0 +1,17 @@
+/**
+ * Autogenerated by Thrift Compiler (0.11.0)
+ *
+ * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
+ * @generated
+ */
+#include "aggregation_validator_constants.h"
+
+namespace jaegertracing { namespace thrift {
+
+const aggregation_validatorConstants g_aggregation_validator_constants;
+
+aggregation_validatorConstants::aggregation_validatorConstants() {
+}
+
+}} // namespace
+
diff --git a/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/thrift-gen/aggregation_validator_constants.h b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/thrift-gen/aggregation_validator_constants.h
new file mode 100644
index 000000000..45d93b64d
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/thrift-gen/aggregation_validator_constants.h
@@ -0,0 +1,24 @@
+/**
+ * Autogenerated by Thrift Compiler (0.11.0)
+ *
+ * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
+ * @generated
+ */
+#ifndef aggregation_validator_CONSTANTS_H
+#define aggregation_validator_CONSTANTS_H
+
+#include "aggregation_validator_types.h"
+
+namespace jaegertracing { namespace thrift {
+
+class aggregation_validatorConstants {
+ public:
+ aggregation_validatorConstants();
+
+};
+
+extern const aggregation_validatorConstants g_aggregation_validator_constants;
+
+}} // namespace
+
+#endif
diff --git a/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/thrift-gen/aggregation_validator_types.cpp b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/thrift-gen/aggregation_validator_types.cpp
new file mode 100644
index 000000000..85454e87e
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/thrift-gen/aggregation_validator_types.cpp
@@ -0,0 +1,131 @@
+/**
+ * Autogenerated by Thrift Compiler (0.11.0)
+ *
+ * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
+ * @generated
+ */
+#include "aggregation_validator_types.h"
+
+#include <algorithm>
+#include <ostream>
+
+#include <thrift/TToString.h>
+
+namespace jaegertracing { namespace thrift {
+
+
+ValidateTraceResponse::~ValidateTraceResponse() throw() {
+}
+
+
+void ValidateTraceResponse::__set_ok(const bool val) {
+ this->ok = val;
+}
+
+void ValidateTraceResponse::__set_traceCount(const int64_t val) {
+ this->traceCount = val;
+}
+std::ostream& operator<<(std::ostream& out, const ValidateTraceResponse& obj)
+{
+ obj.printTo(out);
+ return out;
+}
+
+
+uint32_t ValidateTraceResponse::read(::apache::thrift::protocol::TProtocol* iprot) {
+
+ ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
+ uint32_t xfer = 0;
+ std::string fname;
+ ::apache::thrift::protocol::TType ftype;
+ int16_t fid;
+
+ xfer += iprot->readStructBegin(fname);
+
+ using ::apache::thrift::protocol::TProtocolException;
+
+ bool isset_ok = false;
+ bool isset_traceCount = false;
+
+ while (true)
+ {
+ xfer += iprot->readFieldBegin(fname, ftype, fid);
+ if (ftype == ::apache::thrift::protocol::T_STOP) {
+ break;
+ }
+ switch (fid)
+ {
+ case 1:
+ if (ftype == ::apache::thrift::protocol::T_BOOL) {
+ xfer += iprot->readBool(this->ok);
+ isset_ok = true;
+ } else {
+ xfer += iprot->skip(ftype);
+ }
+ break;
+ case 2:
+ if (ftype == ::apache::thrift::protocol::T_I64) {
+ xfer += iprot->readI64(this->traceCount);
+ isset_traceCount = true;
+ } else {
+ xfer += iprot->skip(ftype);
+ }
+ break;
+ default:
+ xfer += iprot->skip(ftype);
+ break;
+ }
+ xfer += iprot->readFieldEnd();
+ }
+
+ xfer += iprot->readStructEnd();
+
+ if (!isset_ok)
+ throw TProtocolException(TProtocolException::INVALID_DATA);
+ if (!isset_traceCount)
+ throw TProtocolException(TProtocolException::INVALID_DATA);
+ return xfer;
+}
+
+uint32_t ValidateTraceResponse::write(::apache::thrift::protocol::TProtocol* oprot) const {
+ uint32_t xfer = 0;
+ ::apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
+ xfer += oprot->writeStructBegin("ValidateTraceResponse");
+
+ xfer += oprot->writeFieldBegin("ok", ::apache::thrift::protocol::T_BOOL, 1);
+ xfer += oprot->writeBool(this->ok);
+ xfer += oprot->writeFieldEnd();
+
+ xfer += oprot->writeFieldBegin("traceCount", ::apache::thrift::protocol::T_I64, 2);
+ xfer += oprot->writeI64(this->traceCount);
+ xfer += oprot->writeFieldEnd();
+
+ xfer += oprot->writeFieldStop();
+ xfer += oprot->writeStructEnd();
+ return xfer;
+}
+
+void swap(ValidateTraceResponse &a, ValidateTraceResponse &b) {
+ using ::std::swap;
+ swap(a.ok, b.ok);
+ swap(a.traceCount, b.traceCount);
+}
+
+ValidateTraceResponse::ValidateTraceResponse(const ValidateTraceResponse& other0) {
+ ok = other0.ok;
+ traceCount = other0.traceCount;
+}
+ValidateTraceResponse& ValidateTraceResponse::operator=(const ValidateTraceResponse& other1) {
+ ok = other1.ok;
+ traceCount = other1.traceCount;
+ return *this;
+}
+void ValidateTraceResponse::printTo(std::ostream& out) const {
+ using ::apache::thrift::to_string;
+ out << "ValidateTraceResponse(";
+ out << "ok=" << to_string(ok);
+ out << ", " << "traceCount=" << to_string(traceCount);
+ out << ")";
+}
+
+}} // namespace
diff --git a/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/thrift-gen/aggregation_validator_types.h b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/thrift-gen/aggregation_validator_types.h
new file mode 100644
index 000000000..26b943289
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/thrift-gen/aggregation_validator_types.h
@@ -0,0 +1,68 @@
+/**
+ * Autogenerated by Thrift Compiler (0.11.0)
+ *
+ * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
+ * @generated
+ */
+#ifndef aggregation_validator_TYPES_H
+#define aggregation_validator_TYPES_H
+
+#include <iosfwd>
+
+#include <thrift/Thrift.h>
+#include <thrift/TApplicationException.h>
+#include <thrift/TBase.h>
+#include <thrift/protocol/TProtocol.h>
+#include <thrift/transport/TTransport.h>
+
+
+
+
+namespace jaegertracing { namespace thrift {
+
+class ValidateTraceResponse;
+
+
+class ValidateTraceResponse : public virtual ::apache::thrift::TBase {
+ public:
+
+ ValidateTraceResponse(const ValidateTraceResponse&);
+ ValidateTraceResponse& operator=(const ValidateTraceResponse&);
+ ValidateTraceResponse() : ok(0), traceCount(0) {
+ }
+
+ virtual ~ValidateTraceResponse() throw();
+ bool ok;
+ int64_t traceCount;
+
+ void __set_ok(const bool val);
+
+ void __set_traceCount(const int64_t val);
+
+ bool operator == (const ValidateTraceResponse & rhs) const
+ {
+ if (!(ok == rhs.ok))
+ return false;
+ if (!(traceCount == rhs.traceCount))
+ return false;
+ return true;
+ }
+ bool operator != (const ValidateTraceResponse &rhs) const {
+ return !(*this == rhs);
+ }
+
+ bool operator < (const ValidateTraceResponse & ) const;
+
+ uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
+ uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;
+
+ virtual void printTo(std::ostream& out) const;
+};
+
+void swap(ValidateTraceResponse &a, ValidateTraceResponse &b);
+
+std::ostream& operator<<(std::ostream& out, const ValidateTraceResponse& obj);
+
+}} // namespace
+
+#endif
diff --git a/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/thrift-gen/baggage_constants.cpp b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/thrift-gen/baggage_constants.cpp
new file mode 100644
index 000000000..1d5b2ffa8
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/thrift-gen/baggage_constants.cpp
@@ -0,0 +1,17 @@
+/**
+ * Autogenerated by Thrift Compiler (0.11.0)
+ *
+ * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
+ * @generated
+ */
+#include "baggage_constants.h"
+
+namespace jaegertracing { namespace thrift {
+
+const baggageConstants g_baggage_constants;
+
+baggageConstants::baggageConstants() {
+}
+
+}} // namespace
+
diff --git a/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/thrift-gen/baggage_constants.h b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/thrift-gen/baggage_constants.h
new file mode 100644
index 000000000..985347140
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/thrift-gen/baggage_constants.h
@@ -0,0 +1,24 @@
+/**
+ * Autogenerated by Thrift Compiler (0.11.0)
+ *
+ * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
+ * @generated
+ */
+#ifndef baggage_CONSTANTS_H
+#define baggage_CONSTANTS_H
+
+#include "baggage_types.h"
+
+namespace jaegertracing { namespace thrift {
+
+class baggageConstants {
+ public:
+ baggageConstants();
+
+};
+
+extern const baggageConstants g_baggage_constants;
+
+}} // namespace
+
+#endif
diff --git a/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/thrift-gen/baggage_types.cpp b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/thrift-gen/baggage_types.cpp
new file mode 100644
index 000000000..73b8526bc
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/thrift-gen/baggage_types.cpp
@@ -0,0 +1,131 @@
+/**
+ * Autogenerated by Thrift Compiler (0.11.0)
+ *
+ * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
+ * @generated
+ */
+#include "baggage_types.h"
+
+#include <algorithm>
+#include <ostream>
+
+#include <thrift/TToString.h>
+
+namespace jaegertracing { namespace thrift {
+
+
+BaggageRestriction::~BaggageRestriction() throw() {
+}
+
+
+void BaggageRestriction::__set_baggageKey(const std::string& val) {
+ this->baggageKey = val;
+}
+
+void BaggageRestriction::__set_maxValueLength(const int32_t val) {
+ this->maxValueLength = val;
+}
+std::ostream& operator<<(std::ostream& out, const BaggageRestriction& obj)
+{
+ obj.printTo(out);
+ return out;
+}
+
+
+uint32_t BaggageRestriction::read(::apache::thrift::protocol::TProtocol* iprot) {
+
+ ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
+ uint32_t xfer = 0;
+ std::string fname;
+ ::apache::thrift::protocol::TType ftype;
+ int16_t fid;
+
+ xfer += iprot->readStructBegin(fname);
+
+ using ::apache::thrift::protocol::TProtocolException;
+
+ bool isset_baggageKey = false;
+ bool isset_maxValueLength = false;
+
+ while (true)
+ {
+ xfer += iprot->readFieldBegin(fname, ftype, fid);
+ if (ftype == ::apache::thrift::protocol::T_STOP) {
+ break;
+ }
+ switch (fid)
+ {
+ case 1:
+ if (ftype == ::apache::thrift::protocol::T_STRING) {
+ xfer += iprot->readString(this->baggageKey);
+ isset_baggageKey = true;
+ } else {
+ xfer += iprot->skip(ftype);
+ }
+ break;
+ case 2:
+ if (ftype == ::apache::thrift::protocol::T_I32) {
+ xfer += iprot->readI32(this->maxValueLength);
+ isset_maxValueLength = true;
+ } else {
+ xfer += iprot->skip(ftype);
+ }
+ break;
+ default:
+ xfer += iprot->skip(ftype);
+ break;
+ }
+ xfer += iprot->readFieldEnd();
+ }
+
+ xfer += iprot->readStructEnd();
+
+ if (!isset_baggageKey)
+ throw TProtocolException(TProtocolException::INVALID_DATA);
+ if (!isset_maxValueLength)
+ throw TProtocolException(TProtocolException::INVALID_DATA);
+ return xfer;
+}
+
+uint32_t BaggageRestriction::write(::apache::thrift::protocol::TProtocol* oprot) const {
+ uint32_t xfer = 0;
+ ::apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
+ xfer += oprot->writeStructBegin("BaggageRestriction");
+
+ xfer += oprot->writeFieldBegin("baggageKey", ::apache::thrift::protocol::T_STRING, 1);
+ xfer += oprot->writeString(this->baggageKey);
+ xfer += oprot->writeFieldEnd();
+
+ xfer += oprot->writeFieldBegin("maxValueLength", ::apache::thrift::protocol::T_I32, 2);
+ xfer += oprot->writeI32(this->maxValueLength);
+ xfer += oprot->writeFieldEnd();
+
+ xfer += oprot->writeFieldStop();
+ xfer += oprot->writeStructEnd();
+ return xfer;
+}
+
+void swap(BaggageRestriction &a, BaggageRestriction &b) {
+ using ::std::swap;
+ swap(a.baggageKey, b.baggageKey);
+ swap(a.maxValueLength, b.maxValueLength);
+}
+
+BaggageRestriction::BaggageRestriction(const BaggageRestriction& other0) {
+ baggageKey = other0.baggageKey;
+ maxValueLength = other0.maxValueLength;
+}
+BaggageRestriction& BaggageRestriction::operator=(const BaggageRestriction& other1) {
+ baggageKey = other1.baggageKey;
+ maxValueLength = other1.maxValueLength;
+ return *this;
+}
+void BaggageRestriction::printTo(std::ostream& out) const {
+ using ::apache::thrift::to_string;
+ out << "BaggageRestriction(";
+ out << "baggageKey=" << to_string(baggageKey);
+ out << ", " << "maxValueLength=" << to_string(maxValueLength);
+ out << ")";
+}
+
+}} // namespace
diff --git a/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/thrift-gen/baggage_types.h b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/thrift-gen/baggage_types.h
new file mode 100644
index 000000000..934b17304
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/thrift-gen/baggage_types.h
@@ -0,0 +1,68 @@
+/**
+ * Autogenerated by Thrift Compiler (0.11.0)
+ *
+ * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
+ * @generated
+ */
+#ifndef baggage_TYPES_H
+#define baggage_TYPES_H
+
+#include <iosfwd>
+
+#include <thrift/Thrift.h>
+#include <thrift/TApplicationException.h>
+#include <thrift/TBase.h>
+#include <thrift/protocol/TProtocol.h>
+#include <thrift/transport/TTransport.h>
+
+
+
+
+namespace jaegertracing { namespace thrift {
+
+class BaggageRestriction;
+
+
+class BaggageRestriction : public virtual ::apache::thrift::TBase {
+ public:
+
+ BaggageRestriction(const BaggageRestriction&);
+ BaggageRestriction& operator=(const BaggageRestriction&);
+ BaggageRestriction() : baggageKey(), maxValueLength(0) {
+ }
+
+ virtual ~BaggageRestriction() throw();
+ std::string baggageKey;
+ int32_t maxValueLength;
+
+ void __set_baggageKey(const std::string& val);
+
+ void __set_maxValueLength(const int32_t val);
+
+ bool operator == (const BaggageRestriction & rhs) const
+ {
+ if (!(baggageKey == rhs.baggageKey))
+ return false;
+ if (!(maxValueLength == rhs.maxValueLength))
+ return false;
+ return true;
+ }
+ bool operator != (const BaggageRestriction &rhs) const {
+ return !(*this == rhs);
+ }
+
+ bool operator < (const BaggageRestriction & ) const;
+
+ uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
+ uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;
+
+ virtual void printTo(std::ostream& out) const;
+};
+
+void swap(BaggageRestriction &a, BaggageRestriction &b);
+
+std::ostream& operator<<(std::ostream& out, const BaggageRestriction& obj);
+
+}} // namespace
+
+#endif
diff --git a/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/thrift-gen/dependency_constants.cpp b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/thrift-gen/dependency_constants.cpp
new file mode 100644
index 000000000..fcfb77fb2
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/thrift-gen/dependency_constants.cpp
@@ -0,0 +1,17 @@
+/**
+ * Autogenerated by Thrift Compiler (0.11.0)
+ *
+ * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
+ * @generated
+ */
+#include "dependency_constants.h"
+
+namespace jaegertracing { namespace thrift {
+
+const dependencyConstants g_dependency_constants;
+
+dependencyConstants::dependencyConstants() {
+}
+
+}} // namespace
+
diff --git a/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/thrift-gen/dependency_constants.h b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/thrift-gen/dependency_constants.h
new file mode 100644
index 000000000..bc7a0f7d1
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/thrift-gen/dependency_constants.h
@@ -0,0 +1,24 @@
+/**
+ * Autogenerated by Thrift Compiler (0.11.0)
+ *
+ * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
+ * @generated
+ */
+#ifndef dependency_CONSTANTS_H
+#define dependency_CONSTANTS_H
+
+#include "dependency_types.h"
+
+namespace jaegertracing { namespace thrift {
+
+class dependencyConstants {
+ public:
+ dependencyConstants();
+
+};
+
+extern const dependencyConstants g_dependency_constants;
+
+}} // namespace
+
+#endif
diff --git a/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/thrift-gen/dependency_types.cpp b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/thrift-gen/dependency_types.cpp
new file mode 100644
index 000000000..65fb208fc
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/thrift-gen/dependency_types.cpp
@@ -0,0 +1,266 @@
+/**
+ * Autogenerated by Thrift Compiler (0.11.0)
+ *
+ * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
+ * @generated
+ */
+#include "dependency_types.h"
+
+#include <algorithm>
+#include <ostream>
+
+#include <thrift/TToString.h>
+
+namespace jaegertracing { namespace thrift {
+
+
+DependencyLink::~DependencyLink() throw() {
+}
+
+
+void DependencyLink::__set_parent(const std::string& val) {
+ this->parent = val;
+}
+
+void DependencyLink::__set_child(const std::string& val) {
+ this->child = val;
+}
+
+void DependencyLink::__set_callCount(const int64_t val) {
+ this->callCount = val;
+}
+std::ostream& operator<<(std::ostream& out, const DependencyLink& obj)
+{
+ obj.printTo(out);
+ return out;
+}
+
+
+uint32_t DependencyLink::read(::apache::thrift::protocol::TProtocol* iprot) {
+
+ ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
+ uint32_t xfer = 0;
+ std::string fname;
+ ::apache::thrift::protocol::TType ftype;
+ int16_t fid;
+
+ xfer += iprot->readStructBegin(fname);
+
+ using ::apache::thrift::protocol::TProtocolException;
+
+ bool isset_parent = false;
+ bool isset_child = false;
+ bool isset_callCount = false;
+
+ while (true)
+ {
+ xfer += iprot->readFieldBegin(fname, ftype, fid);
+ if (ftype == ::apache::thrift::protocol::T_STOP) {
+ break;
+ }
+ switch (fid)
+ {
+ case 1:
+ if (ftype == ::apache::thrift::protocol::T_STRING) {
+ xfer += iprot->readString(this->parent);
+ isset_parent = true;
+ } else {
+ xfer += iprot->skip(ftype);
+ }
+ break;
+ case 2:
+ if (ftype == ::apache::thrift::protocol::T_STRING) {
+ xfer += iprot->readString(this->child);
+ isset_child = true;
+ } else {
+ xfer += iprot->skip(ftype);
+ }
+ break;
+ case 4:
+ if (ftype == ::apache::thrift::protocol::T_I64) {
+ xfer += iprot->readI64(this->callCount);
+ isset_callCount = true;
+ } else {
+ xfer += iprot->skip(ftype);
+ }
+ break;
+ default:
+ xfer += iprot->skip(ftype);
+ break;
+ }
+ xfer += iprot->readFieldEnd();
+ }
+
+ xfer += iprot->readStructEnd();
+
+ if (!isset_parent)
+ throw TProtocolException(TProtocolException::INVALID_DATA);
+ if (!isset_child)
+ throw TProtocolException(TProtocolException::INVALID_DATA);
+ if (!isset_callCount)
+ throw TProtocolException(TProtocolException::INVALID_DATA);
+ return xfer;
+}
+
+uint32_t DependencyLink::write(::apache::thrift::protocol::TProtocol* oprot) const {
+ uint32_t xfer = 0;
+ ::apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
+ xfer += oprot->writeStructBegin("DependencyLink");
+
+ xfer += oprot->writeFieldBegin("parent", ::apache::thrift::protocol::T_STRING, 1);
+ xfer += oprot->writeString(this->parent);
+ xfer += oprot->writeFieldEnd();
+
+ xfer += oprot->writeFieldBegin("child", ::apache::thrift::protocol::T_STRING, 2);
+ xfer += oprot->writeString(this->child);
+ xfer += oprot->writeFieldEnd();
+
+ xfer += oprot->writeFieldBegin("callCount", ::apache::thrift::protocol::T_I64, 4);
+ xfer += oprot->writeI64(this->callCount);
+ xfer += oprot->writeFieldEnd();
+
+ xfer += oprot->writeFieldStop();
+ xfer += oprot->writeStructEnd();
+ return xfer;
+}
+
+void swap(DependencyLink &a, DependencyLink &b) {
+ using ::std::swap;
+ swap(a.parent, b.parent);
+ swap(a.child, b.child);
+ swap(a.callCount, b.callCount);
+}
+
+DependencyLink::DependencyLink(const DependencyLink& other0) {
+ parent = other0.parent;
+ child = other0.child;
+ callCount = other0.callCount;
+}
+DependencyLink& DependencyLink::operator=(const DependencyLink& other1) {
+ parent = other1.parent;
+ child = other1.child;
+ callCount = other1.callCount;
+ return *this;
+}
+void DependencyLink::printTo(std::ostream& out) const {
+ using ::apache::thrift::to_string;
+ out << "DependencyLink(";
+ out << "parent=" << to_string(parent);
+ out << ", " << "child=" << to_string(child);
+ out << ", " << "callCount=" << to_string(callCount);
+ out << ")";
+}
+
+
+Dependencies::~Dependencies() throw() {
+}
+
+
+void Dependencies::__set_links(const std::vector<DependencyLink> & val) {
+ this->links = val;
+}
+std::ostream& operator<<(std::ostream& out, const Dependencies& obj)
+{
+ obj.printTo(out);
+ return out;
+}
+
+
+uint32_t Dependencies::read(::apache::thrift::protocol::TProtocol* iprot) {
+
+ ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
+ uint32_t xfer = 0;
+ std::string fname;
+ ::apache::thrift::protocol::TType ftype;
+ int16_t fid;
+
+ xfer += iprot->readStructBegin(fname);
+
+ using ::apache::thrift::protocol::TProtocolException;
+
+ bool isset_links = false;
+
+ while (true)
+ {
+ xfer += iprot->readFieldBegin(fname, ftype, fid);
+ if (ftype == ::apache::thrift::protocol::T_STOP) {
+ break;
+ }
+ switch (fid)
+ {
+ case 1:
+ if (ftype == ::apache::thrift::protocol::T_LIST) {
+ {
+ this->links.clear();
+ uint32_t _size2;
+ ::apache::thrift::protocol::TType _etype5;
+ xfer += iprot->readListBegin(_etype5, _size2);
+ this->links.resize(_size2);
+ uint32_t _i6;
+ for (_i6 = 0; _i6 < _size2; ++_i6)
+ {
+ xfer += this->links[_i6].read(iprot);
+ }
+ xfer += iprot->readListEnd();
+ }
+ isset_links = true;
+ } else {
+ xfer += iprot->skip(ftype);
+ }
+ break;
+ default:
+ xfer += iprot->skip(ftype);
+ break;
+ }
+ xfer += iprot->readFieldEnd();
+ }
+
+ xfer += iprot->readStructEnd();
+
+ if (!isset_links)
+ throw TProtocolException(TProtocolException::INVALID_DATA);
+ return xfer;
+}
+
+uint32_t Dependencies::write(::apache::thrift::protocol::TProtocol* oprot) const {
+ uint32_t xfer = 0;
+ ::apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
+ xfer += oprot->writeStructBegin("Dependencies");
+
+ xfer += oprot->writeFieldBegin("links", ::apache::thrift::protocol::T_LIST, 1);
+ {
+ xfer += oprot->writeListBegin(::apache::thrift::protocol::T_STRUCT, static_cast<uint32_t>(this->links.size()));
+ std::vector<DependencyLink> ::const_iterator _iter7;
+ for (_iter7 = this->links.begin(); _iter7 != this->links.end(); ++_iter7)
+ {
+ xfer += (*_iter7).write(oprot);
+ }
+ xfer += oprot->writeListEnd();
+ }
+ xfer += oprot->writeFieldEnd();
+
+ xfer += oprot->writeFieldStop();
+ xfer += oprot->writeStructEnd();
+ return xfer;
+}
+
+void swap(Dependencies &a, Dependencies &b) {
+ using ::std::swap;
+ swap(a.links, b.links);
+}
+
+Dependencies::Dependencies(const Dependencies& other8) {
+ links = other8.links;
+}
+Dependencies& Dependencies::operator=(const Dependencies& other9) {
+ links = other9.links;
+ return *this;
+}
+void Dependencies::printTo(std::ostream& out) const {
+ using ::apache::thrift::to_string;
+ out << "Dependencies(";
+ out << "links=" << to_string(links);
+ out << ")";
+}
+
+}} // namespace
diff --git a/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/thrift-gen/dependency_types.h b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/thrift-gen/dependency_types.h
new file mode 100644
index 000000000..3361ea01a
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/thrift-gen/dependency_types.h
@@ -0,0 +1,111 @@
+/**
+ * Autogenerated by Thrift Compiler (0.11.0)
+ *
+ * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
+ * @generated
+ */
+#ifndef dependency_TYPES_H
+#define dependency_TYPES_H
+
+#include <iosfwd>
+
+#include <thrift/Thrift.h>
+#include <thrift/TApplicationException.h>
+#include <thrift/TBase.h>
+#include <thrift/protocol/TProtocol.h>
+#include <thrift/transport/TTransport.h>
+
+
+
+
+namespace jaegertracing { namespace thrift {
+
+class DependencyLink;
+
+class Dependencies;
+
+
+class DependencyLink : public virtual ::apache::thrift::TBase {
+ public:
+
+ DependencyLink(const DependencyLink&);
+ DependencyLink& operator=(const DependencyLink&);
+ DependencyLink() : parent(), child(), callCount(0) {
+ }
+
+ virtual ~DependencyLink() throw();
+ std::string parent;
+ std::string child;
+ int64_t callCount;
+
+ void __set_parent(const std::string& val);
+
+ void __set_child(const std::string& val);
+
+ void __set_callCount(const int64_t val);
+
+ bool operator == (const DependencyLink & rhs) const
+ {
+ if (!(parent == rhs.parent))
+ return false;
+ if (!(child == rhs.child))
+ return false;
+ if (!(callCount == rhs.callCount))
+ return false;
+ return true;
+ }
+ bool operator != (const DependencyLink &rhs) const {
+ return !(*this == rhs);
+ }
+
+ bool operator < (const DependencyLink & ) const;
+
+ uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
+ uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;
+
+ virtual void printTo(std::ostream& out) const;
+};
+
+void swap(DependencyLink &a, DependencyLink &b);
+
+std::ostream& operator<<(std::ostream& out, const DependencyLink& obj);
+
+
+class Dependencies : public virtual ::apache::thrift::TBase {
+ public:
+
+ Dependencies(const Dependencies&);
+ Dependencies& operator=(const Dependencies&);
+ Dependencies() {
+ }
+
+ virtual ~Dependencies() throw();
+ std::vector<DependencyLink> links;
+
+ void __set_links(const std::vector<DependencyLink> & val);
+
+ bool operator == (const Dependencies & rhs) const
+ {
+ if (!(links == rhs.links))
+ return false;
+ return true;
+ }
+ bool operator != (const Dependencies &rhs) const {
+ return !(*this == rhs);
+ }
+
+ bool operator < (const Dependencies & ) const;
+
+ uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
+ uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;
+
+ virtual void printTo(std::ostream& out) const;
+};
+
+void swap(Dependencies &a, Dependencies &b);
+
+std::ostream& operator<<(std::ostream& out, const Dependencies& obj);
+
+}} // namespace
+
+#endif
diff --git a/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/thrift-gen/jaeger_constants.cpp b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/thrift-gen/jaeger_constants.cpp
new file mode 100644
index 000000000..97ed94305
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/thrift-gen/jaeger_constants.cpp
@@ -0,0 +1,17 @@
+/**
+ * Autogenerated by Thrift Compiler (0.11.0)
+ *
+ * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
+ * @generated
+ */
+#include "jaeger_constants.h"
+
+namespace jaegertracing { namespace thrift {
+
+const jaegerConstants g_jaeger_constants;
+
+jaegerConstants::jaegerConstants() {
+}
+
+}} // namespace
+
diff --git a/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/thrift-gen/jaeger_constants.h b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/thrift-gen/jaeger_constants.h
new file mode 100644
index 000000000..dc857da11
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/thrift-gen/jaeger_constants.h
@@ -0,0 +1,24 @@
+/**
+ * Autogenerated by Thrift Compiler (0.11.0)
+ *
+ * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
+ * @generated
+ */
+#ifndef jaeger_CONSTANTS_H
+#define jaeger_CONSTANTS_H
+
+#include "jaeger_types.h"
+
+namespace jaegertracing { namespace thrift {
+
+class jaegerConstants {
+ public:
+ jaegerConstants();
+
+};
+
+extern const jaegerConstants g_jaeger_constants;
+
+}} // namespace
+
+#endif
diff --git a/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/thrift-gen/jaeger_types.cpp b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/thrift-gen/jaeger_types.cpp
new file mode 100644
index 000000000..eaac975a1
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/thrift-gen/jaeger_types.cpp
@@ -0,0 +1,1336 @@
+/**
+ * Autogenerated by Thrift Compiler (0.11.0)
+ *
+ * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
+ * @generated
+ */
+#include "jaeger_types.h"
+
+#include <algorithm>
+#include <ostream>
+
+#include <thrift/TToString.h>
+
+namespace jaegertracing { namespace thrift {
+
+int _kTagTypeValues[] = {
+ TagType::STRING,
+ TagType::DOUBLE,
+ TagType::BOOL,
+ TagType::LONG,
+ TagType::BINARY
+};
+const char* _kTagTypeNames[] = {
+ "STRING",
+ "DOUBLE",
+ "BOOL",
+ "LONG",
+ "BINARY"
+};
+const std::map<int, const char*> _TagType_VALUES_TO_NAMES(::apache::thrift::TEnumIterator(5, _kTagTypeValues, _kTagTypeNames), ::apache::thrift::TEnumIterator(-1, NULL, NULL));
+
+std::ostream& operator<<(std::ostream& out, const TagType::type& val) {
+ std::map<int, const char*>::const_iterator it = _TagType_VALUES_TO_NAMES.find(val);
+ if (it != _TagType_VALUES_TO_NAMES.end()) {
+ out << it->second;
+ } else {
+ out << static_cast<int>(val);
+ }
+ return out;
+}
+
+int _kSpanRefTypeValues[] = {
+ SpanRefType::CHILD_OF,
+ SpanRefType::FOLLOWS_FROM
+};
+const char* _kSpanRefTypeNames[] = {
+ "CHILD_OF",
+ "FOLLOWS_FROM"
+};
+const std::map<int, const char*> _SpanRefType_VALUES_TO_NAMES(::apache::thrift::TEnumIterator(2, _kSpanRefTypeValues, _kSpanRefTypeNames), ::apache::thrift::TEnumIterator(-1, NULL, NULL));
+
+std::ostream& operator<<(std::ostream& out, const SpanRefType::type& val) {
+ std::map<int, const char*>::const_iterator it = _SpanRefType_VALUES_TO_NAMES.find(val);
+ if (it != _SpanRefType_VALUES_TO_NAMES.end()) {
+ out << it->second;
+ } else {
+ out << static_cast<int>(val);
+ }
+ return out;
+}
+
+
+Tag::~Tag() throw() {
+}
+
+
+void Tag::__set_key(const std::string& val) {
+ this->key = val;
+}
+
+void Tag::__set_vType(const TagType::type val) {
+ this->vType = val;
+}
+
+void Tag::__set_vStr(const std::string& val) {
+ this->vStr = val;
+__isset.vStr = true;
+}
+
+void Tag::__set_vDouble(const double val) {
+ this->vDouble = val;
+__isset.vDouble = true;
+}
+
+void Tag::__set_vBool(const bool val) {
+ this->vBool = val;
+__isset.vBool = true;
+}
+
+void Tag::__set_vLong(const int64_t val) {
+ this->vLong = val;
+__isset.vLong = true;
+}
+
+void Tag::__set_vBinary(const std::string& val) {
+ this->vBinary = val;
+__isset.vBinary = true;
+}
+std::ostream& operator<<(std::ostream& out, const Tag& obj)
+{
+ obj.printTo(out);
+ return out;
+}
+
+
+uint32_t Tag::read(::apache::thrift::protocol::TProtocol* iprot) {
+
+ ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
+ uint32_t xfer = 0;
+ std::string fname;
+ ::apache::thrift::protocol::TType ftype;
+ int16_t fid;
+
+ xfer += iprot->readStructBegin(fname);
+
+ using ::apache::thrift::protocol::TProtocolException;
+
+ bool isset_key = false;
+ bool isset_vType = false;
+
+ while (true)
+ {
+ xfer += iprot->readFieldBegin(fname, ftype, fid);
+ if (ftype == ::apache::thrift::protocol::T_STOP) {
+ break;
+ }
+ switch (fid)
+ {
+ case 1:
+ if (ftype == ::apache::thrift::protocol::T_STRING) {
+ xfer += iprot->readString(this->key);
+ isset_key = true;
+ } else {
+ xfer += iprot->skip(ftype);
+ }
+ break;
+ case 2:
+ if (ftype == ::apache::thrift::protocol::T_I32) {
+ int32_t ecast0;
+ xfer += iprot->readI32(ecast0);
+ this->vType = (TagType::type)ecast0;
+ isset_vType = true;
+ } else {
+ xfer += iprot->skip(ftype);
+ }
+ break;
+ case 3:
+ if (ftype == ::apache::thrift::protocol::T_STRING) {
+ xfer += iprot->readString(this->vStr);
+ this->__isset.vStr = true;
+ } else {
+ xfer += iprot->skip(ftype);
+ }
+ break;
+ case 4:
+ if (ftype == ::apache::thrift::protocol::T_DOUBLE) {
+ xfer += iprot->readDouble(this->vDouble);
+ this->__isset.vDouble = true;
+ } else {
+ xfer += iprot->skip(ftype);
+ }
+ break;
+ case 5:
+ if (ftype == ::apache::thrift::protocol::T_BOOL) {
+ xfer += iprot->readBool(this->vBool);
+ this->__isset.vBool = true;
+ } else {
+ xfer += iprot->skip(ftype);
+ }
+ break;
+ case 6:
+ if (ftype == ::apache::thrift::protocol::T_I64) {
+ xfer += iprot->readI64(this->vLong);
+ this->__isset.vLong = true;
+ } else {
+ xfer += iprot->skip(ftype);
+ }
+ break;
+ case 7:
+ if (ftype == ::apache::thrift::protocol::T_STRING) {
+ xfer += iprot->readBinary(this->vBinary);
+ this->__isset.vBinary = true;
+ } else {
+ xfer += iprot->skip(ftype);
+ }
+ break;
+ default:
+ xfer += iprot->skip(ftype);
+ break;
+ }
+ xfer += iprot->readFieldEnd();
+ }
+
+ xfer += iprot->readStructEnd();
+
+ if (!isset_key)
+ throw TProtocolException(TProtocolException::INVALID_DATA);
+ if (!isset_vType)
+ throw TProtocolException(TProtocolException::INVALID_DATA);
+ return xfer;
+}
+
+uint32_t Tag::write(::apache::thrift::protocol::TProtocol* oprot) const {
+ uint32_t xfer = 0;
+ ::apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
+ xfer += oprot->writeStructBegin("Tag");
+
+ xfer += oprot->writeFieldBegin("key", ::apache::thrift::protocol::T_STRING, 1);
+ xfer += oprot->writeString(this->key);
+ xfer += oprot->writeFieldEnd();
+
+ xfer += oprot->writeFieldBegin("vType", ::apache::thrift::protocol::T_I32, 2);
+ xfer += oprot->writeI32((int32_t)this->vType);
+ xfer += oprot->writeFieldEnd();
+
+ if (this->__isset.vStr) {
+ xfer += oprot->writeFieldBegin("vStr", ::apache::thrift::protocol::T_STRING, 3);
+ xfer += oprot->writeString(this->vStr);
+ xfer += oprot->writeFieldEnd();
+ }
+ if (this->__isset.vDouble) {
+ xfer += oprot->writeFieldBegin("vDouble", ::apache::thrift::protocol::T_DOUBLE, 4);
+ xfer += oprot->writeDouble(this->vDouble);
+ xfer += oprot->writeFieldEnd();
+ }
+ if (this->__isset.vBool) {
+ xfer += oprot->writeFieldBegin("vBool", ::apache::thrift::protocol::T_BOOL, 5);
+ xfer += oprot->writeBool(this->vBool);
+ xfer += oprot->writeFieldEnd();
+ }
+ if (this->__isset.vLong) {
+ xfer += oprot->writeFieldBegin("vLong", ::apache::thrift::protocol::T_I64, 6);
+ xfer += oprot->writeI64(this->vLong);
+ xfer += oprot->writeFieldEnd();
+ }
+ if (this->__isset.vBinary) {
+ xfer += oprot->writeFieldBegin("vBinary", ::apache::thrift::protocol::T_STRING, 7);
+ xfer += oprot->writeBinary(this->vBinary);
+ xfer += oprot->writeFieldEnd();
+ }
+ xfer += oprot->writeFieldStop();
+ xfer += oprot->writeStructEnd();
+ return xfer;
+}
+
+void swap(Tag &a, Tag &b) {
+ using ::std::swap;
+ swap(a.key, b.key);
+ swap(a.vType, b.vType);
+ swap(a.vStr, b.vStr);
+ swap(a.vDouble, b.vDouble);
+ swap(a.vBool, b.vBool);
+ swap(a.vLong, b.vLong);
+ swap(a.vBinary, b.vBinary);
+ swap(a.__isset, b.__isset);
+}
+
+Tag::Tag(const Tag& other1) {
+ key = other1.key;
+ vType = other1.vType;
+ vStr = other1.vStr;
+ vDouble = other1.vDouble;
+ vBool = other1.vBool;
+ vLong = other1.vLong;
+ vBinary = other1.vBinary;
+ __isset = other1.__isset;
+}
+Tag& Tag::operator=(const Tag& other2) {
+ key = other2.key;
+ vType = other2.vType;
+ vStr = other2.vStr;
+ vDouble = other2.vDouble;
+ vBool = other2.vBool;
+ vLong = other2.vLong;
+ vBinary = other2.vBinary;
+ __isset = other2.__isset;
+ return *this;
+}
+void Tag::printTo(std::ostream& out) const {
+ using ::apache::thrift::to_string;
+ out << "Tag(";
+ out << "key=" << to_string(key);
+ out << ", " << "vType=" << to_string(vType);
+ out << ", " << "vStr="; (__isset.vStr ? (out << to_string(vStr)) : (out << "<null>"));
+ out << ", " << "vDouble="; (__isset.vDouble ? (out << to_string(vDouble)) : (out << "<null>"));
+ out << ", " << "vBool="; (__isset.vBool ? (out << to_string(vBool)) : (out << "<null>"));
+ out << ", " << "vLong="; (__isset.vLong ? (out << to_string(vLong)) : (out << "<null>"));
+ out << ", " << "vBinary="; (__isset.vBinary ? (out << to_string(vBinary)) : (out << "<null>"));
+ out << ")";
+}
+
+
+Log::~Log() throw() {
+}
+
+
+void Log::__set_timestamp(const int64_t val) {
+ this->timestamp = val;
+}
+
+void Log::__set_fields(const std::vector<Tag> & val) {
+ this->fields = val;
+}
+std::ostream& operator<<(std::ostream& out, const Log& obj)
+{
+ obj.printTo(out);
+ return out;
+}
+
+
+uint32_t Log::read(::apache::thrift::protocol::TProtocol* iprot) {
+
+ ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
+ uint32_t xfer = 0;
+ std::string fname;
+ ::apache::thrift::protocol::TType ftype;
+ int16_t fid;
+
+ xfer += iprot->readStructBegin(fname);
+
+ using ::apache::thrift::protocol::TProtocolException;
+
+ bool isset_timestamp = false;
+ bool isset_fields = false;
+
+ while (true)
+ {
+ xfer += iprot->readFieldBegin(fname, ftype, fid);
+ if (ftype == ::apache::thrift::protocol::T_STOP) {
+ break;
+ }
+ switch (fid)
+ {
+ case 1:
+ if (ftype == ::apache::thrift::protocol::T_I64) {
+ xfer += iprot->readI64(this->timestamp);
+ isset_timestamp = true;
+ } else {
+ xfer += iprot->skip(ftype);
+ }
+ break;
+ case 2:
+ if (ftype == ::apache::thrift::protocol::T_LIST) {
+ {
+ this->fields.clear();
+ uint32_t _size3;
+ ::apache::thrift::protocol::TType _etype6;
+ xfer += iprot->readListBegin(_etype6, _size3);
+ this->fields.resize(_size3);
+ uint32_t _i7;
+ for (_i7 = 0; _i7 < _size3; ++_i7)
+ {
+ xfer += this->fields[_i7].read(iprot);
+ }
+ xfer += iprot->readListEnd();
+ }
+ isset_fields = true;
+ } else {
+ xfer += iprot->skip(ftype);
+ }
+ break;
+ default:
+ xfer += iprot->skip(ftype);
+ break;
+ }
+ xfer += iprot->readFieldEnd();
+ }
+
+ xfer += iprot->readStructEnd();
+
+ if (!isset_timestamp)
+ throw TProtocolException(TProtocolException::INVALID_DATA);
+ if (!isset_fields)
+ throw TProtocolException(TProtocolException::INVALID_DATA);
+ return xfer;
+}
+
+uint32_t Log::write(::apache::thrift::protocol::TProtocol* oprot) const {
+ uint32_t xfer = 0;
+ ::apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
+ xfer += oprot->writeStructBegin("Log");
+
+ xfer += oprot->writeFieldBegin("timestamp", ::apache::thrift::protocol::T_I64, 1);
+ xfer += oprot->writeI64(this->timestamp);
+ xfer += oprot->writeFieldEnd();
+
+ xfer += oprot->writeFieldBegin("fields", ::apache::thrift::protocol::T_LIST, 2);
+ {
+ xfer += oprot->writeListBegin(::apache::thrift::protocol::T_STRUCT, static_cast<uint32_t>(this->fields.size()));
+ std::vector<Tag> ::const_iterator _iter8;
+ for (_iter8 = this->fields.begin(); _iter8 != this->fields.end(); ++_iter8)
+ {
+ xfer += (*_iter8).write(oprot);
+ }
+ xfer += oprot->writeListEnd();
+ }
+ xfer += oprot->writeFieldEnd();
+
+ xfer += oprot->writeFieldStop();
+ xfer += oprot->writeStructEnd();
+ return xfer;
+}
+
+void swap(Log &a, Log &b) {
+ using ::std::swap;
+ swap(a.timestamp, b.timestamp);
+ swap(a.fields, b.fields);
+}
+
+Log::Log(const Log& other9) {
+ timestamp = other9.timestamp;
+ fields = other9.fields;
+}
+Log& Log::operator=(const Log& other10) {
+ timestamp = other10.timestamp;
+ fields = other10.fields;
+ return *this;
+}
+void Log::printTo(std::ostream& out) const {
+ using ::apache::thrift::to_string;
+ out << "Log(";
+ out << "timestamp=" << to_string(timestamp);
+ out << ", " << "fields=" << to_string(fields);
+ out << ")";
+}
+
+
+SpanRef::~SpanRef() throw() {
+}
+
+
+void SpanRef::__set_refType(const SpanRefType::type val) {
+ this->refType = val;
+}
+
+void SpanRef::__set_traceIdLow(const int64_t val) {
+ this->traceIdLow = val;
+}
+
+void SpanRef::__set_traceIdHigh(const int64_t val) {
+ this->traceIdHigh = val;
+}
+
+void SpanRef::__set_spanId(const int64_t val) {
+ this->spanId = val;
+}
+std::ostream& operator<<(std::ostream& out, const SpanRef& obj)
+{
+ obj.printTo(out);
+ return out;
+}
+
+
+uint32_t SpanRef::read(::apache::thrift::protocol::TProtocol* iprot) {
+
+ ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
+ uint32_t xfer = 0;
+ std::string fname;
+ ::apache::thrift::protocol::TType ftype;
+ int16_t fid;
+
+ xfer += iprot->readStructBegin(fname);
+
+ using ::apache::thrift::protocol::TProtocolException;
+
+ bool isset_refType = false;
+ bool isset_traceIdLow = false;
+ bool isset_traceIdHigh = false;
+ bool isset_spanId = false;
+
+ while (true)
+ {
+ xfer += iprot->readFieldBegin(fname, ftype, fid);
+ if (ftype == ::apache::thrift::protocol::T_STOP) {
+ break;
+ }
+ switch (fid)
+ {
+ case 1:
+ if (ftype == ::apache::thrift::protocol::T_I32) {
+ int32_t ecast11;
+ xfer += iprot->readI32(ecast11);
+ this->refType = (SpanRefType::type)ecast11;
+ isset_refType = true;
+ } else {
+ xfer += iprot->skip(ftype);
+ }
+ break;
+ case 2:
+ if (ftype == ::apache::thrift::protocol::T_I64) {
+ xfer += iprot->readI64(this->traceIdLow);
+ isset_traceIdLow = true;
+ } else {
+ xfer += iprot->skip(ftype);
+ }
+ break;
+ case 3:
+ if (ftype == ::apache::thrift::protocol::T_I64) {
+ xfer += iprot->readI64(this->traceIdHigh);
+ isset_traceIdHigh = true;
+ } else {
+ xfer += iprot->skip(ftype);
+ }
+ break;
+ case 4:
+ if (ftype == ::apache::thrift::protocol::T_I64) {
+ xfer += iprot->readI64(this->spanId);
+ isset_spanId = true;
+ } else {
+ xfer += iprot->skip(ftype);
+ }
+ break;
+ default:
+ xfer += iprot->skip(ftype);
+ break;
+ }
+ xfer += iprot->readFieldEnd();
+ }
+
+ xfer += iprot->readStructEnd();
+
+ if (!isset_refType)
+ throw TProtocolException(TProtocolException::INVALID_DATA);
+ if (!isset_traceIdLow)
+ throw TProtocolException(TProtocolException::INVALID_DATA);
+ if (!isset_traceIdHigh)
+ throw TProtocolException(TProtocolException::INVALID_DATA);
+ if (!isset_spanId)
+ throw TProtocolException(TProtocolException::INVALID_DATA);
+ return xfer;
+}
+
+uint32_t SpanRef::write(::apache::thrift::protocol::TProtocol* oprot) const {
+ uint32_t xfer = 0;
+ ::apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
+ xfer += oprot->writeStructBegin("SpanRef");
+
+ xfer += oprot->writeFieldBegin("refType", ::apache::thrift::protocol::T_I32, 1);
+ xfer += oprot->writeI32((int32_t)this->refType);
+ xfer += oprot->writeFieldEnd();
+
+ xfer += oprot->writeFieldBegin("traceIdLow", ::apache::thrift::protocol::T_I64, 2);
+ xfer += oprot->writeI64(this->traceIdLow);
+ xfer += oprot->writeFieldEnd();
+
+ xfer += oprot->writeFieldBegin("traceIdHigh", ::apache::thrift::protocol::T_I64, 3);
+ xfer += oprot->writeI64(this->traceIdHigh);
+ xfer += oprot->writeFieldEnd();
+
+ xfer += oprot->writeFieldBegin("spanId", ::apache::thrift::protocol::T_I64, 4);
+ xfer += oprot->writeI64(this->spanId);
+ xfer += oprot->writeFieldEnd();
+
+ xfer += oprot->writeFieldStop();
+ xfer += oprot->writeStructEnd();
+ return xfer;
+}
+
+void swap(SpanRef &a, SpanRef &b) {
+ using ::std::swap;
+ swap(a.refType, b.refType);
+ swap(a.traceIdLow, b.traceIdLow);
+ swap(a.traceIdHigh, b.traceIdHigh);
+ swap(a.spanId, b.spanId);
+}
+
+SpanRef::SpanRef(const SpanRef& other12) {
+ refType = other12.refType;
+ traceIdLow = other12.traceIdLow;
+ traceIdHigh = other12.traceIdHigh;
+ spanId = other12.spanId;
+}
+SpanRef& SpanRef::operator=(const SpanRef& other13) {
+ refType = other13.refType;
+ traceIdLow = other13.traceIdLow;
+ traceIdHigh = other13.traceIdHigh;
+ spanId = other13.spanId;
+ return *this;
+}
+void SpanRef::printTo(std::ostream& out) const {
+ using ::apache::thrift::to_string;
+ out << "SpanRef(";
+ out << "refType=" << to_string(refType);
+ out << ", " << "traceIdLow=" << to_string(traceIdLow);
+ out << ", " << "traceIdHigh=" << to_string(traceIdHigh);
+ out << ", " << "spanId=" << to_string(spanId);
+ out << ")";
+}
+
+
+Span::~Span() throw() {
+}
+
+
+void Span::__set_traceIdLow(const int64_t val) {
+ this->traceIdLow = val;
+}
+
+void Span::__set_traceIdHigh(const int64_t val) {
+ this->traceIdHigh = val;
+}
+
+void Span::__set_spanId(const int64_t val) {
+ this->spanId = val;
+}
+
+void Span::__set_parentSpanId(const int64_t val) {
+ this->parentSpanId = val;
+}
+
+void Span::__set_operationName(const std::string& val) {
+ this->operationName = val;
+}
+
+void Span::__set_references(const std::vector<SpanRef> & val) {
+ this->references = val;
+__isset.references = true;
+}
+
+void Span::__set_flags(const int32_t val) {
+ this->flags = val;
+}
+
+void Span::__set_startTime(const int64_t val) {
+ this->startTime = val;
+}
+
+void Span::__set_duration(const int64_t val) {
+ this->duration = val;
+}
+
+void Span::__set_tags(const std::vector<Tag> & val) {
+ this->tags = val;
+__isset.tags = true;
+}
+
+void Span::__set_logs(const std::vector<Log> & val) {
+ this->logs = val;
+__isset.logs = true;
+}
+std::ostream& operator<<(std::ostream& out, const Span& obj)
+{
+ obj.printTo(out);
+ return out;
+}
+
+
+uint32_t Span::read(::apache::thrift::protocol::TProtocol* iprot) {
+
+ ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
+ uint32_t xfer = 0;
+ std::string fname;
+ ::apache::thrift::protocol::TType ftype;
+ int16_t fid;
+
+ xfer += iprot->readStructBegin(fname);
+
+ using ::apache::thrift::protocol::TProtocolException;
+
+ bool isset_traceIdLow = false;
+ bool isset_traceIdHigh = false;
+ bool isset_spanId = false;
+ bool isset_parentSpanId = false;
+ bool isset_operationName = false;
+ bool isset_flags = false;
+ bool isset_startTime = false;
+ bool isset_duration = false;
+
+ while (true)
+ {
+ xfer += iprot->readFieldBegin(fname, ftype, fid);
+ if (ftype == ::apache::thrift::protocol::T_STOP) {
+ break;
+ }
+ switch (fid)
+ {
+ case 1:
+ if (ftype == ::apache::thrift::protocol::T_I64) {
+ xfer += iprot->readI64(this->traceIdLow);
+ isset_traceIdLow = true;
+ } else {
+ xfer += iprot->skip(ftype);
+ }
+ break;
+ case 2:
+ if (ftype == ::apache::thrift::protocol::T_I64) {
+ xfer += iprot->readI64(this->traceIdHigh);
+ isset_traceIdHigh = true;
+ } else {
+ xfer += iprot->skip(ftype);
+ }
+ break;
+ case 3:
+ if (ftype == ::apache::thrift::protocol::T_I64) {
+ xfer += iprot->readI64(this->spanId);
+ isset_spanId = true;
+ } else {
+ xfer += iprot->skip(ftype);
+ }
+ break;
+ case 4:
+ if (ftype == ::apache::thrift::protocol::T_I64) {
+ xfer += iprot->readI64(this->parentSpanId);
+ isset_parentSpanId = true;
+ } else {
+ xfer += iprot->skip(ftype);
+ }
+ break;
+ case 5:
+ if (ftype == ::apache::thrift::protocol::T_STRING) {
+ xfer += iprot->readString(this->operationName);
+ isset_operationName = true;
+ } else {
+ xfer += iprot->skip(ftype);
+ }
+ break;
+ case 6:
+ if (ftype == ::apache::thrift::protocol::T_LIST) {
+ {
+ this->references.clear();
+ uint32_t _size14;
+ ::apache::thrift::protocol::TType _etype17;
+ xfer += iprot->readListBegin(_etype17, _size14);
+ this->references.resize(_size14);
+ uint32_t _i18;
+ for (_i18 = 0; _i18 < _size14; ++_i18)
+ {
+ xfer += this->references[_i18].read(iprot);
+ }
+ xfer += iprot->readListEnd();
+ }
+ this->__isset.references = true;
+ } else {
+ xfer += iprot->skip(ftype);
+ }
+ break;
+ case 7:
+ if (ftype == ::apache::thrift::protocol::T_I32) {
+ xfer += iprot->readI32(this->flags);
+ isset_flags = true;
+ } else {
+ xfer += iprot->skip(ftype);
+ }
+ break;
+ case 8:
+ if (ftype == ::apache::thrift::protocol::T_I64) {
+ xfer += iprot->readI64(this->startTime);
+ isset_startTime = true;
+ } else {
+ xfer += iprot->skip(ftype);
+ }
+ break;
+ case 9:
+ if (ftype == ::apache::thrift::protocol::T_I64) {
+ xfer += iprot->readI64(this->duration);
+ isset_duration = true;
+ } else {
+ xfer += iprot->skip(ftype);
+ }
+ break;
+ case 10:
+ if (ftype == ::apache::thrift::protocol::T_LIST) {
+ {
+ this->tags.clear();
+ uint32_t _size19;
+ ::apache::thrift::protocol::TType _etype22;
+ xfer += iprot->readListBegin(_etype22, _size19);
+ this->tags.resize(_size19);
+ uint32_t _i23;
+ for (_i23 = 0; _i23 < _size19; ++_i23)
+ {
+ xfer += this->tags[_i23].read(iprot);
+ }
+ xfer += iprot->readListEnd();
+ }
+ this->__isset.tags = true;
+ } else {
+ xfer += iprot->skip(ftype);
+ }
+ break;
+ case 11:
+ if (ftype == ::apache::thrift::protocol::T_LIST) {
+ {
+ this->logs.clear();
+ uint32_t _size24;
+ ::apache::thrift::protocol::TType _etype27;
+ xfer += iprot->readListBegin(_etype27, _size24);
+ this->logs.resize(_size24);
+ uint32_t _i28;
+ for (_i28 = 0; _i28 < _size24; ++_i28)
+ {
+ xfer += this->logs[_i28].read(iprot);
+ }
+ xfer += iprot->readListEnd();
+ }
+ this->__isset.logs = true;
+ } else {
+ xfer += iprot->skip(ftype);
+ }
+ break;
+ default:
+ xfer += iprot->skip(ftype);
+ break;
+ }
+ xfer += iprot->readFieldEnd();
+ }
+
+ xfer += iprot->readStructEnd();
+
+ if (!isset_traceIdLow)
+ throw TProtocolException(TProtocolException::INVALID_DATA);
+ if (!isset_traceIdHigh)
+ throw TProtocolException(TProtocolException::INVALID_DATA);
+ if (!isset_spanId)
+ throw TProtocolException(TProtocolException::INVALID_DATA);
+ if (!isset_parentSpanId)
+ throw TProtocolException(TProtocolException::INVALID_DATA);
+ if (!isset_operationName)
+ throw TProtocolException(TProtocolException::INVALID_DATA);
+ if (!isset_flags)
+ throw TProtocolException(TProtocolException::INVALID_DATA);
+ if (!isset_startTime)
+ throw TProtocolException(TProtocolException::INVALID_DATA);
+ if (!isset_duration)
+ throw TProtocolException(TProtocolException::INVALID_DATA);
+ return xfer;
+}
+
+uint32_t Span::write(::apache::thrift::protocol::TProtocol* oprot) const {
+ uint32_t xfer = 0;
+ ::apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
+ xfer += oprot->writeStructBegin("Span");
+
+ xfer += oprot->writeFieldBegin("traceIdLow", ::apache::thrift::protocol::T_I64, 1);
+ xfer += oprot->writeI64(this->traceIdLow);
+ xfer += oprot->writeFieldEnd();
+
+ xfer += oprot->writeFieldBegin("traceIdHigh", ::apache::thrift::protocol::T_I64, 2);
+ xfer += oprot->writeI64(this->traceIdHigh);
+ xfer += oprot->writeFieldEnd();
+
+ xfer += oprot->writeFieldBegin("spanId", ::apache::thrift::protocol::T_I64, 3);
+ xfer += oprot->writeI64(this->spanId);
+ xfer += oprot->writeFieldEnd();
+
+ xfer += oprot->writeFieldBegin("parentSpanId", ::apache::thrift::protocol::T_I64, 4);
+ xfer += oprot->writeI64(this->parentSpanId);
+ xfer += oprot->writeFieldEnd();
+
+ xfer += oprot->writeFieldBegin("operationName", ::apache::thrift::protocol::T_STRING, 5);
+ xfer += oprot->writeString(this->operationName);
+ xfer += oprot->writeFieldEnd();
+
+ if (this->__isset.references) {
+ xfer += oprot->writeFieldBegin("references", ::apache::thrift::protocol::T_LIST, 6);
+ {
+ xfer += oprot->writeListBegin(::apache::thrift::protocol::T_STRUCT, static_cast<uint32_t>(this->references.size()));
+ std::vector<SpanRef> ::const_iterator _iter29;
+ for (_iter29 = this->references.begin(); _iter29 != this->references.end(); ++_iter29)
+ {
+ xfer += (*_iter29).write(oprot);
+ }
+ xfer += oprot->writeListEnd();
+ }
+ xfer += oprot->writeFieldEnd();
+ }
+ xfer += oprot->writeFieldBegin("flags", ::apache::thrift::protocol::T_I32, 7);
+ xfer += oprot->writeI32(this->flags);
+ xfer += oprot->writeFieldEnd();
+
+ xfer += oprot->writeFieldBegin("startTime", ::apache::thrift::protocol::T_I64, 8);
+ xfer += oprot->writeI64(this->startTime);
+ xfer += oprot->writeFieldEnd();
+
+ xfer += oprot->writeFieldBegin("duration", ::apache::thrift::protocol::T_I64, 9);
+ xfer += oprot->writeI64(this->duration);
+ xfer += oprot->writeFieldEnd();
+
+ if (this->__isset.tags) {
+ xfer += oprot->writeFieldBegin("tags", ::apache::thrift::protocol::T_LIST, 10);
+ {
+ xfer += oprot->writeListBegin(::apache::thrift::protocol::T_STRUCT, static_cast<uint32_t>(this->tags.size()));
+ std::vector<Tag> ::const_iterator _iter30;
+ for (_iter30 = this->tags.begin(); _iter30 != this->tags.end(); ++_iter30)
+ {
+ xfer += (*_iter30).write(oprot);
+ }
+ xfer += oprot->writeListEnd();
+ }
+ xfer += oprot->writeFieldEnd();
+ }
+ if (this->__isset.logs) {
+ xfer += oprot->writeFieldBegin("logs", ::apache::thrift::protocol::T_LIST, 11);
+ {
+ xfer += oprot->writeListBegin(::apache::thrift::protocol::T_STRUCT, static_cast<uint32_t>(this->logs.size()));
+ std::vector<Log> ::const_iterator _iter31;
+ for (_iter31 = this->logs.begin(); _iter31 != this->logs.end(); ++_iter31)
+ {
+ xfer += (*_iter31).write(oprot);
+ }
+ xfer += oprot->writeListEnd();
+ }
+ xfer += oprot->writeFieldEnd();
+ }
+ xfer += oprot->writeFieldStop();
+ xfer += oprot->writeStructEnd();
+ return xfer;
+}
+
+void swap(Span &a, Span &b) {
+ using ::std::swap;
+ swap(a.traceIdLow, b.traceIdLow);
+ swap(a.traceIdHigh, b.traceIdHigh);
+ swap(a.spanId, b.spanId);
+ swap(a.parentSpanId, b.parentSpanId);
+ swap(a.operationName, b.operationName);
+ swap(a.references, b.references);
+ swap(a.flags, b.flags);
+ swap(a.startTime, b.startTime);
+ swap(a.duration, b.duration);
+ swap(a.tags, b.tags);
+ swap(a.logs, b.logs);
+ swap(a.__isset, b.__isset);
+}
+
+Span::Span(const Span& other32) {
+ traceIdLow = other32.traceIdLow;
+ traceIdHigh = other32.traceIdHigh;
+ spanId = other32.spanId;
+ parentSpanId = other32.parentSpanId;
+ operationName = other32.operationName;
+ references = other32.references;
+ flags = other32.flags;
+ startTime = other32.startTime;
+ duration = other32.duration;
+ tags = other32.tags;
+ logs = other32.logs;
+ __isset = other32.__isset;
+}
+Span& Span::operator=(const Span& other33) {
+ traceIdLow = other33.traceIdLow;
+ traceIdHigh = other33.traceIdHigh;
+ spanId = other33.spanId;
+ parentSpanId = other33.parentSpanId;
+ operationName = other33.operationName;
+ references = other33.references;
+ flags = other33.flags;
+ startTime = other33.startTime;
+ duration = other33.duration;
+ tags = other33.tags;
+ logs = other33.logs;
+ __isset = other33.__isset;
+ return *this;
+}
+void Span::printTo(std::ostream& out) const {
+ using ::apache::thrift::to_string;
+ out << "Span(";
+ out << "traceIdLow=" << to_string(traceIdLow);
+ out << ", " << "traceIdHigh=" << to_string(traceIdHigh);
+ out << ", " << "spanId=" << to_string(spanId);
+ out << ", " << "parentSpanId=" << to_string(parentSpanId);
+ out << ", " << "operationName=" << to_string(operationName);
+ out << ", " << "references="; (__isset.references ? (out << to_string(references)) : (out << "<null>"));
+ out << ", " << "flags=" << to_string(flags);
+ out << ", " << "startTime=" << to_string(startTime);
+ out << ", " << "duration=" << to_string(duration);
+ out << ", " << "tags="; (__isset.tags ? (out << to_string(tags)) : (out << "<null>"));
+ out << ", " << "logs="; (__isset.logs ? (out << to_string(logs)) : (out << "<null>"));
+ out << ")";
+}
+
+
+Process::~Process() throw() {
+}
+
+
+void Process::__set_serviceName(const std::string& val) {
+ this->serviceName = val;
+}
+
+void Process::__set_tags(const std::vector<Tag> & val) {
+ this->tags = val;
+__isset.tags = true;
+}
+std::ostream& operator<<(std::ostream& out, const Process& obj)
+{
+ obj.printTo(out);
+ return out;
+}
+
+
+uint32_t Process::read(::apache::thrift::protocol::TProtocol* iprot) {
+
+ ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
+ uint32_t xfer = 0;
+ std::string fname;
+ ::apache::thrift::protocol::TType ftype;
+ int16_t fid;
+
+ xfer += iprot->readStructBegin(fname);
+
+ using ::apache::thrift::protocol::TProtocolException;
+
+ bool isset_serviceName = false;
+
+ while (true)
+ {
+ xfer += iprot->readFieldBegin(fname, ftype, fid);
+ if (ftype == ::apache::thrift::protocol::T_STOP) {
+ break;
+ }
+ switch (fid)
+ {
+ case 1:
+ if (ftype == ::apache::thrift::protocol::T_STRING) {
+ xfer += iprot->readString(this->serviceName);
+ isset_serviceName = true;
+ } else {
+ xfer += iprot->skip(ftype);
+ }
+ break;
+ case 2:
+ if (ftype == ::apache::thrift::protocol::T_LIST) {
+ {
+ this->tags.clear();
+ uint32_t _size34;
+ ::apache::thrift::protocol::TType _etype37;
+ xfer += iprot->readListBegin(_etype37, _size34);
+ this->tags.resize(_size34);
+ uint32_t _i38;
+ for (_i38 = 0; _i38 < _size34; ++_i38)
+ {
+ xfer += this->tags[_i38].read(iprot);
+ }
+ xfer += iprot->readListEnd();
+ }
+ this->__isset.tags = true;
+ } else {
+ xfer += iprot->skip(ftype);
+ }
+ break;
+ default:
+ xfer += iprot->skip(ftype);
+ break;
+ }
+ xfer += iprot->readFieldEnd();
+ }
+
+ xfer += iprot->readStructEnd();
+
+ if (!isset_serviceName)
+ throw TProtocolException(TProtocolException::INVALID_DATA);
+ return xfer;
+}
+
+uint32_t Process::write(::apache::thrift::protocol::TProtocol* oprot) const {
+ uint32_t xfer = 0;
+ ::apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
+ xfer += oprot->writeStructBegin("Process");
+
+ xfer += oprot->writeFieldBegin("serviceName", ::apache::thrift::protocol::T_STRING, 1);
+ xfer += oprot->writeString(this->serviceName);
+ xfer += oprot->writeFieldEnd();
+
+ if (this->__isset.tags) {
+ xfer += oprot->writeFieldBegin("tags", ::apache::thrift::protocol::T_LIST, 2);
+ {
+ xfer += oprot->writeListBegin(::apache::thrift::protocol::T_STRUCT, static_cast<uint32_t>(this->tags.size()));
+ std::vector<Tag> ::const_iterator _iter39;
+ for (_iter39 = this->tags.begin(); _iter39 != this->tags.end(); ++_iter39)
+ {
+ xfer += (*_iter39).write(oprot);
+ }
+ xfer += oprot->writeListEnd();
+ }
+ xfer += oprot->writeFieldEnd();
+ }
+ xfer += oprot->writeFieldStop();
+ xfer += oprot->writeStructEnd();
+ return xfer;
+}
+
+void swap(Process &a, Process &b) {
+ using ::std::swap;
+ swap(a.serviceName, b.serviceName);
+ swap(a.tags, b.tags);
+ swap(a.__isset, b.__isset);
+}
+
+Process::Process(const Process& other40) {
+ serviceName = other40.serviceName;
+ tags = other40.tags;
+ __isset = other40.__isset;
+}
+Process& Process::operator=(const Process& other41) {
+ serviceName = other41.serviceName;
+ tags = other41.tags;
+ __isset = other41.__isset;
+ return *this;
+}
+void Process::printTo(std::ostream& out) const {
+ using ::apache::thrift::to_string;
+ out << "Process(";
+ out << "serviceName=" << to_string(serviceName);
+ out << ", " << "tags="; (__isset.tags ? (out << to_string(tags)) : (out << "<null>"));
+ out << ")";
+}
+
+
+Batch::~Batch() throw() {
+}
+
+
+void Batch::__set_process(const Process& val) {
+ this->process = val;
+}
+
+void Batch::__set_spans(const std::vector<Span> & val) {
+ this->spans = val;
+}
+std::ostream& operator<<(std::ostream& out, const Batch& obj)
+{
+ obj.printTo(out);
+ return out;
+}
+
+
+uint32_t Batch::read(::apache::thrift::protocol::TProtocol* iprot) {
+
+ ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
+ uint32_t xfer = 0;
+ std::string fname;
+ ::apache::thrift::protocol::TType ftype;
+ int16_t fid;
+
+ xfer += iprot->readStructBegin(fname);
+
+ using ::apache::thrift::protocol::TProtocolException;
+
+ bool isset_process = false;
+ bool isset_spans = false;
+
+ while (true)
+ {
+ xfer += iprot->readFieldBegin(fname, ftype, fid);
+ if (ftype == ::apache::thrift::protocol::T_STOP) {
+ break;
+ }
+ switch (fid)
+ {
+ case 1:
+ if (ftype == ::apache::thrift::protocol::T_STRUCT) {
+ xfer += this->process.read(iprot);
+ isset_process = true;
+ } else {
+ xfer += iprot->skip(ftype);
+ }
+ break;
+ case 2:
+ if (ftype == ::apache::thrift::protocol::T_LIST) {
+ {
+ this->spans.clear();
+ uint32_t _size42;
+ ::apache::thrift::protocol::TType _etype45;
+ xfer += iprot->readListBegin(_etype45, _size42);
+ this->spans.resize(_size42);
+ uint32_t _i46;
+ for (_i46 = 0; _i46 < _size42; ++_i46)
+ {
+ xfer += this->spans[_i46].read(iprot);
+ }
+ xfer += iprot->readListEnd();
+ }
+ isset_spans = true;
+ } else {
+ xfer += iprot->skip(ftype);
+ }
+ break;
+ default:
+ xfer += iprot->skip(ftype);
+ break;
+ }
+ xfer += iprot->readFieldEnd();
+ }
+
+ xfer += iprot->readStructEnd();
+
+ if (!isset_process)
+ throw TProtocolException(TProtocolException::INVALID_DATA);
+ if (!isset_spans)
+ throw TProtocolException(TProtocolException::INVALID_DATA);
+ return xfer;
+}
+
+uint32_t Batch::write(::apache::thrift::protocol::TProtocol* oprot) const {
+ uint32_t xfer = 0;
+ ::apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
+ xfer += oprot->writeStructBegin("Batch");
+
+ xfer += oprot->writeFieldBegin("process", ::apache::thrift::protocol::T_STRUCT, 1);
+ xfer += this->process.write(oprot);
+ xfer += oprot->writeFieldEnd();
+
+ xfer += oprot->writeFieldBegin("spans", ::apache::thrift::protocol::T_LIST, 2);
+ {
+ xfer += oprot->writeListBegin(::apache::thrift::protocol::T_STRUCT, static_cast<uint32_t>(this->spans.size()));
+ std::vector<Span> ::const_iterator _iter47;
+ for (_iter47 = this->spans.begin(); _iter47 != this->spans.end(); ++_iter47)
+ {
+ xfer += (*_iter47).write(oprot);
+ }
+ xfer += oprot->writeListEnd();
+ }
+ xfer += oprot->writeFieldEnd();
+
+ xfer += oprot->writeFieldStop();
+ xfer += oprot->writeStructEnd();
+ return xfer;
+}
+
+void swap(Batch &a, Batch &b) {
+ using ::std::swap;
+ swap(a.process, b.process);
+ swap(a.spans, b.spans);
+}
+
+Batch::Batch(const Batch& other48) {
+ process = other48.process;
+ spans = other48.spans;
+}
+Batch& Batch::operator=(const Batch& other49) {
+ process = other49.process;
+ spans = other49.spans;
+ return *this;
+}
+void Batch::printTo(std::ostream& out) const {
+ using ::apache::thrift::to_string;
+ out << "Batch(";
+ out << "process=" << to_string(process);
+ out << ", " << "spans=" << to_string(spans);
+ out << ")";
+}
+
+
+BatchSubmitResponse::~BatchSubmitResponse() throw() {
+}
+
+
+void BatchSubmitResponse::__set_ok(const bool val) {
+ this->ok = val;
+}
+std::ostream& operator<<(std::ostream& out, const BatchSubmitResponse& obj)
+{
+ obj.printTo(out);
+ return out;
+}
+
+
+uint32_t BatchSubmitResponse::read(::apache::thrift::protocol::TProtocol* iprot) {
+
+ ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
+ uint32_t xfer = 0;
+ std::string fname;
+ ::apache::thrift::protocol::TType ftype;
+ int16_t fid;
+
+ xfer += iprot->readStructBegin(fname);
+
+ using ::apache::thrift::protocol::TProtocolException;
+
+ bool isset_ok = false;
+
+ while (true)
+ {
+ xfer += iprot->readFieldBegin(fname, ftype, fid);
+ if (ftype == ::apache::thrift::protocol::T_STOP) {
+ break;
+ }
+ switch (fid)
+ {
+ case 1:
+ if (ftype == ::apache::thrift::protocol::T_BOOL) {
+ xfer += iprot->readBool(this->ok);
+ isset_ok = true;
+ } else {
+ xfer += iprot->skip(ftype);
+ }
+ break;
+ default:
+ xfer += iprot->skip(ftype);
+ break;
+ }
+ xfer += iprot->readFieldEnd();
+ }
+
+ xfer += iprot->readStructEnd();
+
+ if (!isset_ok)
+ throw TProtocolException(TProtocolException::INVALID_DATA);
+ return xfer;
+}
+
+uint32_t BatchSubmitResponse::write(::apache::thrift::protocol::TProtocol* oprot) const {
+ uint32_t xfer = 0;
+ ::apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
+ xfer += oprot->writeStructBegin("BatchSubmitResponse");
+
+ xfer += oprot->writeFieldBegin("ok", ::apache::thrift::protocol::T_BOOL, 1);
+ xfer += oprot->writeBool(this->ok);
+ xfer += oprot->writeFieldEnd();
+
+ xfer += oprot->writeFieldStop();
+ xfer += oprot->writeStructEnd();
+ return xfer;
+}
+
+void swap(BatchSubmitResponse &a, BatchSubmitResponse &b) {
+ using ::std::swap;
+ swap(a.ok, b.ok);
+}
+
+BatchSubmitResponse::BatchSubmitResponse(const BatchSubmitResponse& other50) {
+ ok = other50.ok;
+}
+BatchSubmitResponse& BatchSubmitResponse::operator=(const BatchSubmitResponse& other51) {
+ ok = other51.ok;
+ return *this;
+}
+void BatchSubmitResponse::printTo(std::ostream& out) const {
+ using ::apache::thrift::to_string;
+ out << "BatchSubmitResponse(";
+ out << "ok=" << to_string(ok);
+ out << ")";
+}
+
+}} // namespace
diff --git a/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/thrift-gen/jaeger_types.h b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/thrift-gen/jaeger_types.h
new file mode 100644
index 000000000..6e8e7fba6
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/thrift-gen/jaeger_types.h
@@ -0,0 +1,465 @@
+/**
+ * Autogenerated by Thrift Compiler (0.11.0)
+ *
+ * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
+ * @generated
+ */
+#ifndef jaeger_TYPES_H
+#define jaeger_TYPES_H
+
+#include <iosfwd>
+
+#include <thrift/Thrift.h>
+#include <thrift/TApplicationException.h>
+#include <thrift/TBase.h>
+#include <thrift/protocol/TProtocol.h>
+#include <thrift/transport/TTransport.h>
+
+namespace jaegertracing { namespace thrift {
+
+struct TagType {
+ enum type {
+ STRING = 0,
+ DOUBLE = 1,
+ BOOL = 2,
+ LONG = 3,
+ BINARY = 4
+ };
+};
+
+extern const std::map<int, const char*> _TagType_VALUES_TO_NAMES;
+
+std::ostream& operator<<(std::ostream& out, const TagType::type& val);
+
+struct SpanRefType {
+ enum type {
+ CHILD_OF = 0,
+ FOLLOWS_FROM = 1
+ };
+};
+
+extern const std::map<int, const char*> _SpanRefType_VALUES_TO_NAMES;
+
+std::ostream& operator<<(std::ostream& out, const SpanRefType::type& val);
+
+class Tag;
+
+class Log;
+
+class SpanRef;
+
+class Span;
+
+class Process;
+
+class Batch;
+
+class BatchSubmitResponse;
+
+typedef struct _Tag__isset {
+ _Tag__isset() : vStr(false), vDouble(false), vBool(false), vLong(false), vBinary(false) {}
+ bool vStr :1;
+ bool vDouble :1;
+ bool vBool :1;
+ bool vLong :1;
+ bool vBinary :1;
+} _Tag__isset;
+
+class Tag : public virtual ::apache::thrift::TBase {
+ public:
+
+ Tag(const Tag&);
+ Tag& operator=(const Tag&);
+ Tag() : key(), vType((TagType::type)0), vStr(), vDouble(0), vBool(0), vLong(0), vBinary() {
+ }
+
+ virtual ~Tag() throw();
+ std::string key;
+ TagType::type vType;
+ std::string vStr;
+ double vDouble;
+ bool vBool;
+ int64_t vLong;
+ std::string vBinary;
+
+ _Tag__isset __isset;
+
+ void __set_key(const std::string& val);
+
+ void __set_vType(const TagType::type val);
+
+ void __set_vStr(const std::string& val);
+
+ void __set_vDouble(const double val);
+
+ void __set_vBool(const bool val);
+
+ void __set_vLong(const int64_t val);
+
+ void __set_vBinary(const std::string& val);
+
+ bool operator == (const Tag & rhs) const
+ {
+ if (!(key == rhs.key))
+ return false;
+ if (!(vType == rhs.vType))
+ return false;
+ if (__isset.vStr != rhs.__isset.vStr)
+ return false;
+ else if (__isset.vStr && !(vStr == rhs.vStr))
+ return false;
+ if (__isset.vDouble != rhs.__isset.vDouble)
+ return false;
+ else if (__isset.vDouble && !(vDouble == rhs.vDouble))
+ return false;
+ if (__isset.vBool != rhs.__isset.vBool)
+ return false;
+ else if (__isset.vBool && !(vBool == rhs.vBool))
+ return false;
+ if (__isset.vLong != rhs.__isset.vLong)
+ return false;
+ else if (__isset.vLong && !(vLong == rhs.vLong))
+ return false;
+ if (__isset.vBinary != rhs.__isset.vBinary)
+ return false;
+ else if (__isset.vBinary && !(vBinary == rhs.vBinary))
+ return false;
+ return true;
+ }
+ bool operator != (const Tag &rhs) const {
+ return !(*this == rhs);
+ }
+
+ bool operator < (const Tag & ) const;
+
+ uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
+ uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;
+
+ virtual void printTo(std::ostream& out) const;
+};
+
+void swap(Tag &a, Tag &b);
+
+std::ostream& operator<<(std::ostream& out, const Tag& obj);
+
+
+class Log : public virtual ::apache::thrift::TBase {
+ public:
+
+ Log(const Log&);
+ Log& operator=(const Log&);
+ Log() : timestamp(0) {
+ }
+
+ virtual ~Log() throw();
+ int64_t timestamp;
+ std::vector<Tag> fields;
+
+ void __set_timestamp(const int64_t val);
+
+ void __set_fields(const std::vector<Tag> & val);
+
+ bool operator == (const Log & rhs) const
+ {
+ if (!(timestamp == rhs.timestamp))
+ return false;
+ if (!(fields == rhs.fields))
+ return false;
+ return true;
+ }
+ bool operator != (const Log &rhs) const {
+ return !(*this == rhs);
+ }
+
+ bool operator < (const Log & ) const;
+
+ uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
+ uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;
+
+ virtual void printTo(std::ostream& out) const;
+};
+
+void swap(Log &a, Log &b);
+
+std::ostream& operator<<(std::ostream& out, const Log& obj);
+
+
+class SpanRef : public virtual ::apache::thrift::TBase {
+ public:
+
+ SpanRef(const SpanRef&);
+ SpanRef& operator=(const SpanRef&);
+ SpanRef() : refType((SpanRefType::type)0), traceIdLow(0), traceIdHigh(0), spanId(0) {
+ }
+
+ virtual ~SpanRef() throw();
+ SpanRefType::type refType;
+ int64_t traceIdLow;
+ int64_t traceIdHigh;
+ int64_t spanId;
+
+ void __set_refType(const SpanRefType::type val);
+
+ void __set_traceIdLow(const int64_t val);
+
+ void __set_traceIdHigh(const int64_t val);
+
+ void __set_spanId(const int64_t val);
+
+ bool operator == (const SpanRef & rhs) const
+ {
+ if (!(refType == rhs.refType))
+ return false;
+ if (!(traceIdLow == rhs.traceIdLow))
+ return false;
+ if (!(traceIdHigh == rhs.traceIdHigh))
+ return false;
+ if (!(spanId == rhs.spanId))
+ return false;
+ return true;
+ }
+ bool operator != (const SpanRef &rhs) const {
+ return !(*this == rhs);
+ }
+
+ bool operator < (const SpanRef & ) const;
+
+ uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
+ uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;
+
+ virtual void printTo(std::ostream& out) const;
+};
+
+void swap(SpanRef &a, SpanRef &b);
+
+std::ostream& operator<<(std::ostream& out, const SpanRef& obj);
+
+typedef struct _Span__isset {
+ _Span__isset() : references(false), tags(false), logs(false) {}
+ bool references :1;
+ bool tags :1;
+ bool logs :1;
+} _Span__isset;
+
+class Span : public virtual ::apache::thrift::TBase {
+ public:
+
+ Span(const Span&);
+ Span& operator=(const Span&);
+ Span() : traceIdLow(0), traceIdHigh(0), spanId(0), parentSpanId(0), operationName(), flags(0), startTime(0), duration(0) {
+ }
+
+ virtual ~Span() throw();
+ int64_t traceIdLow;
+ int64_t traceIdHigh;
+ int64_t spanId;
+ int64_t parentSpanId;
+ std::string operationName;
+ std::vector<SpanRef> references;
+ int32_t flags;
+ int64_t startTime;
+ int64_t duration;
+ std::vector<Tag> tags;
+ std::vector<Log> logs;
+
+ _Span__isset __isset;
+
+ void __set_traceIdLow(const int64_t val);
+
+ void __set_traceIdHigh(const int64_t val);
+
+ void __set_spanId(const int64_t val);
+
+ void __set_parentSpanId(const int64_t val);
+
+ void __set_operationName(const std::string& val);
+
+ void __set_references(const std::vector<SpanRef> & val);
+
+ void __set_flags(const int32_t val);
+
+ void __set_startTime(const int64_t val);
+
+ void __set_duration(const int64_t val);
+
+ void __set_tags(const std::vector<Tag> & val);
+
+ void __set_logs(const std::vector<Log> & val);
+
+ bool operator == (const Span & rhs) const
+ {
+ if (!(traceIdLow == rhs.traceIdLow))
+ return false;
+ if (!(traceIdHigh == rhs.traceIdHigh))
+ return false;
+ if (!(spanId == rhs.spanId))
+ return false;
+ if (!(parentSpanId == rhs.parentSpanId))
+ return false;
+ if (!(operationName == rhs.operationName))
+ return false;
+ if (__isset.references != rhs.__isset.references)
+ return false;
+ else if (__isset.references && !(references == rhs.references))
+ return false;
+ if (!(flags == rhs.flags))
+ return false;
+ if (!(startTime == rhs.startTime))
+ return false;
+ if (!(duration == rhs.duration))
+ return false;
+ if (__isset.tags != rhs.__isset.tags)
+ return false;
+ else if (__isset.tags && !(tags == rhs.tags))
+ return false;
+ if (__isset.logs != rhs.__isset.logs)
+ return false;
+ else if (__isset.logs && !(logs == rhs.logs))
+ return false;
+ return true;
+ }
+ bool operator != (const Span &rhs) const {
+ return !(*this == rhs);
+ }
+
+ bool operator < (const Span & ) const;
+
+ uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
+ uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;
+
+ virtual void printTo(std::ostream& out) const;
+};
+
+void swap(Span &a, Span &b);
+
+std::ostream& operator<<(std::ostream& out, const Span& obj);
+
+typedef struct _Process__isset {
+ _Process__isset() : tags(false) {}
+ bool tags :1;
+} _Process__isset;
+
+class Process : public virtual ::apache::thrift::TBase {
+ public:
+
+ Process(const Process&);
+ Process& operator=(const Process&);
+ Process() : serviceName() {
+ }
+
+ virtual ~Process() throw();
+ std::string serviceName;
+ std::vector<Tag> tags;
+
+ _Process__isset __isset;
+
+ void __set_serviceName(const std::string& val);
+
+ void __set_tags(const std::vector<Tag> & val);
+
+ bool operator == (const Process & rhs) const
+ {
+ if (!(serviceName == rhs.serviceName))
+ return false;
+ if (__isset.tags != rhs.__isset.tags)
+ return false;
+ else if (__isset.tags && !(tags == rhs.tags))
+ return false;
+ return true;
+ }
+ bool operator != (const Process &rhs) const {
+ return !(*this == rhs);
+ }
+
+ bool operator < (const Process & ) const;
+
+ uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
+ uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;
+
+ virtual void printTo(std::ostream& out) const;
+};
+
+void swap(Process &a, Process &b);
+
+std::ostream& operator<<(std::ostream& out, const Process& obj);
+
+
+class Batch : public virtual ::apache::thrift::TBase {
+ public:
+
+ Batch(const Batch&);
+ Batch& operator=(const Batch&);
+ Batch() {
+ }
+
+ virtual ~Batch() throw();
+ Process process;
+ std::vector<Span> spans;
+
+ void __set_process(const Process& val);
+
+ void __set_spans(const std::vector<Span> & val);
+
+ bool operator == (const Batch & rhs) const
+ {
+ if (!(process == rhs.process))
+ return false;
+ if (!(spans == rhs.spans))
+ return false;
+ return true;
+ }
+ bool operator != (const Batch &rhs) const {
+ return !(*this == rhs);
+ }
+
+ bool operator < (const Batch & ) const;
+
+ uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
+ uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;
+
+ virtual void printTo(std::ostream& out) const;
+};
+
+void swap(Batch &a, Batch &b);
+
+std::ostream& operator<<(std::ostream& out, const Batch& obj);
+
+
+class BatchSubmitResponse : public virtual ::apache::thrift::TBase {
+ public:
+
+ BatchSubmitResponse(const BatchSubmitResponse&);
+ BatchSubmitResponse& operator=(const BatchSubmitResponse&);
+ BatchSubmitResponse() : ok(0) {
+ }
+
+ virtual ~BatchSubmitResponse() throw();
+ bool ok;
+
+ void __set_ok(const bool val);
+
+ bool operator == (const BatchSubmitResponse & rhs) const
+ {
+ if (!(ok == rhs.ok))
+ return false;
+ return true;
+ }
+ bool operator != (const BatchSubmitResponse &rhs) const {
+ return !(*this == rhs);
+ }
+
+ bool operator < (const BatchSubmitResponse & ) const;
+
+ uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
+ uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;
+
+ virtual void printTo(std::ostream& out) const;
+};
+
+void swap(BatchSubmitResponse &a, BatchSubmitResponse &b);
+
+std::ostream& operator<<(std::ostream& out, const BatchSubmitResponse& obj);
+
+}} // namespace
+
+#endif
diff --git a/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/thrift-gen/sampling_constants.cpp b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/thrift-gen/sampling_constants.cpp
new file mode 100644
index 000000000..02ea4941e
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/thrift-gen/sampling_constants.cpp
@@ -0,0 +1,17 @@
+/**
+ * Autogenerated by Thrift Compiler (0.11.0)
+ *
+ * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
+ * @generated
+ */
+#include "sampling_constants.h"
+
+namespace jaegertracing { namespace sampling_manager { namespace thrift {
+
+const samplingConstants g_sampling_constants;
+
+samplingConstants::samplingConstants() {
+}
+
+}}} // namespace
+
diff --git a/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/thrift-gen/sampling_constants.h b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/thrift-gen/sampling_constants.h
new file mode 100644
index 000000000..94637e039
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/thrift-gen/sampling_constants.h
@@ -0,0 +1,24 @@
+/**
+ * Autogenerated by Thrift Compiler (0.11.0)
+ *
+ * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
+ * @generated
+ */
+#ifndef sampling_CONSTANTS_H
+#define sampling_CONSTANTS_H
+
+#include "sampling_types.h"
+
+namespace jaegertracing { namespace sampling_manager { namespace thrift {
+
+class samplingConstants {
+ public:
+ samplingConstants();
+
+};
+
+extern const samplingConstants g_sampling_constants;
+
+}}} // namespace
+
+#endif
diff --git a/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/thrift-gen/sampling_types.cpp b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/thrift-gen/sampling_types.cpp
new file mode 100644
index 000000000..afde445bb
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/thrift-gen/sampling_types.cpp
@@ -0,0 +1,681 @@
+/**
+ * Autogenerated by Thrift Compiler (0.11.0)
+ *
+ * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
+ * @generated
+ */
+#include "sampling_types.h"
+
+#include <algorithm>
+#include <ostream>
+
+#include <thrift/TToString.h>
+
+namespace jaegertracing { namespace sampling_manager { namespace thrift {
+
+int _kSamplingStrategyTypeValues[] = {
+ SamplingStrategyType::PROBABILISTIC,
+ SamplingStrategyType::RATE_LIMITING
+};
+const char* _kSamplingStrategyTypeNames[] = {
+ "PROBABILISTIC",
+ "RATE_LIMITING"
+};
+const std::map<int, const char*> _SamplingStrategyType_VALUES_TO_NAMES(::apache::thrift::TEnumIterator(2, _kSamplingStrategyTypeValues, _kSamplingStrategyTypeNames), ::apache::thrift::TEnumIterator(-1, NULL, NULL));
+
+std::ostream& operator<<(std::ostream& out, const SamplingStrategyType::type& val) {
+ std::map<int, const char*>::const_iterator it = _SamplingStrategyType_VALUES_TO_NAMES.find(val);
+ if (it != _SamplingStrategyType_VALUES_TO_NAMES.end()) {
+ out << it->second;
+ } else {
+ out << static_cast<int>(val);
+ }
+ return out;
+}
+
+
+ProbabilisticSamplingStrategy::~ProbabilisticSamplingStrategy() throw() {
+}
+
+
+void ProbabilisticSamplingStrategy::__set_samplingRate(const double val) {
+ this->samplingRate = val;
+}
+std::ostream& operator<<(std::ostream& out, const ProbabilisticSamplingStrategy& obj)
+{
+ obj.printTo(out);
+ return out;
+}
+
+
+uint32_t ProbabilisticSamplingStrategy::read(::apache::thrift::protocol::TProtocol* iprot) {
+
+ ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
+ uint32_t xfer = 0;
+ std::string fname;
+ ::apache::thrift::protocol::TType ftype;
+ int16_t fid;
+
+ xfer += iprot->readStructBegin(fname);
+
+ using ::apache::thrift::protocol::TProtocolException;
+
+ bool isset_samplingRate = false;
+
+ while (true)
+ {
+ xfer += iprot->readFieldBegin(fname, ftype, fid);
+ if (ftype == ::apache::thrift::protocol::T_STOP) {
+ break;
+ }
+ switch (fid)
+ {
+ case 1:
+ if (ftype == ::apache::thrift::protocol::T_DOUBLE) {
+ xfer += iprot->readDouble(this->samplingRate);
+ isset_samplingRate = true;
+ } else {
+ xfer += iprot->skip(ftype);
+ }
+ break;
+ default:
+ xfer += iprot->skip(ftype);
+ break;
+ }
+ xfer += iprot->readFieldEnd();
+ }
+
+ xfer += iprot->readStructEnd();
+
+ if (!isset_samplingRate)
+ throw TProtocolException(TProtocolException::INVALID_DATA);
+ return xfer;
+}
+
+uint32_t ProbabilisticSamplingStrategy::write(::apache::thrift::protocol::TProtocol* oprot) const {
+ uint32_t xfer = 0;
+ ::apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
+ xfer += oprot->writeStructBegin("ProbabilisticSamplingStrategy");
+
+ xfer += oprot->writeFieldBegin("samplingRate", ::apache::thrift::protocol::T_DOUBLE, 1);
+ xfer += oprot->writeDouble(this->samplingRate);
+ xfer += oprot->writeFieldEnd();
+
+ xfer += oprot->writeFieldStop();
+ xfer += oprot->writeStructEnd();
+ return xfer;
+}
+
+void swap(ProbabilisticSamplingStrategy &a, ProbabilisticSamplingStrategy &b) {
+ using ::std::swap;
+ swap(a.samplingRate, b.samplingRate);
+}
+
+ProbabilisticSamplingStrategy::ProbabilisticSamplingStrategy(const ProbabilisticSamplingStrategy& other0) {
+ samplingRate = other0.samplingRate;
+}
+ProbabilisticSamplingStrategy& ProbabilisticSamplingStrategy::operator=(const ProbabilisticSamplingStrategy& other1) {
+ samplingRate = other1.samplingRate;
+ return *this;
+}
+void ProbabilisticSamplingStrategy::printTo(std::ostream& out) const {
+ using ::apache::thrift::to_string;
+ out << "ProbabilisticSamplingStrategy(";
+ out << "samplingRate=" << to_string(samplingRate);
+ out << ")";
+}
+
+
+RateLimitingSamplingStrategy::~RateLimitingSamplingStrategy() throw() {
+}
+
+
+void RateLimitingSamplingStrategy::__set_maxTracesPerSecond(const int16_t val) {
+ this->maxTracesPerSecond = val;
+}
+std::ostream& operator<<(std::ostream& out, const RateLimitingSamplingStrategy& obj)
+{
+ obj.printTo(out);
+ return out;
+}
+
+
+uint32_t RateLimitingSamplingStrategy::read(::apache::thrift::protocol::TProtocol* iprot) {
+
+ ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
+ uint32_t xfer = 0;
+ std::string fname;
+ ::apache::thrift::protocol::TType ftype;
+ int16_t fid;
+
+ xfer += iprot->readStructBegin(fname);
+
+ using ::apache::thrift::protocol::TProtocolException;
+
+ bool isset_maxTracesPerSecond = false;
+
+ while (true)
+ {
+ xfer += iprot->readFieldBegin(fname, ftype, fid);
+ if (ftype == ::apache::thrift::protocol::T_STOP) {
+ break;
+ }
+ switch (fid)
+ {
+ case 1:
+ if (ftype == ::apache::thrift::protocol::T_I16) {
+ xfer += iprot->readI16(this->maxTracesPerSecond);
+ isset_maxTracesPerSecond = true;
+ } else {
+ xfer += iprot->skip(ftype);
+ }
+ break;
+ default:
+ xfer += iprot->skip(ftype);
+ break;
+ }
+ xfer += iprot->readFieldEnd();
+ }
+
+ xfer += iprot->readStructEnd();
+
+ if (!isset_maxTracesPerSecond)
+ throw TProtocolException(TProtocolException::INVALID_DATA);
+ return xfer;
+}
+
+uint32_t RateLimitingSamplingStrategy::write(::apache::thrift::protocol::TProtocol* oprot) const {
+ uint32_t xfer = 0;
+ ::apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
+ xfer += oprot->writeStructBegin("RateLimitingSamplingStrategy");
+
+ xfer += oprot->writeFieldBegin("maxTracesPerSecond", ::apache::thrift::protocol::T_I16, 1);
+ xfer += oprot->writeI16(this->maxTracesPerSecond);
+ xfer += oprot->writeFieldEnd();
+
+ xfer += oprot->writeFieldStop();
+ xfer += oprot->writeStructEnd();
+ return xfer;
+}
+
+void swap(RateLimitingSamplingStrategy &a, RateLimitingSamplingStrategy &b) {
+ using ::std::swap;
+ swap(a.maxTracesPerSecond, b.maxTracesPerSecond);
+}
+
+RateLimitingSamplingStrategy::RateLimitingSamplingStrategy(const RateLimitingSamplingStrategy& other2) {
+ maxTracesPerSecond = other2.maxTracesPerSecond;
+}
+RateLimitingSamplingStrategy& RateLimitingSamplingStrategy::operator=(const RateLimitingSamplingStrategy& other3) {
+ maxTracesPerSecond = other3.maxTracesPerSecond;
+ return *this;
+}
+void RateLimitingSamplingStrategy::printTo(std::ostream& out) const {
+ using ::apache::thrift::to_string;
+ out << "RateLimitingSamplingStrategy(";
+ out << "maxTracesPerSecond=" << to_string(maxTracesPerSecond);
+ out << ")";
+}
+
+
+OperationSamplingStrategy::~OperationSamplingStrategy() throw() {
+}
+
+
+void OperationSamplingStrategy::__set_operation(const std::string& val) {
+ this->operation = val;
+}
+
+void OperationSamplingStrategy::__set_probabilisticSampling(const ProbabilisticSamplingStrategy& val) {
+ this->probabilisticSampling = val;
+}
+std::ostream& operator<<(std::ostream& out, const OperationSamplingStrategy& obj)
+{
+ obj.printTo(out);
+ return out;
+}
+
+
+uint32_t OperationSamplingStrategy::read(::apache::thrift::protocol::TProtocol* iprot) {
+
+ ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
+ uint32_t xfer = 0;
+ std::string fname;
+ ::apache::thrift::protocol::TType ftype;
+ int16_t fid;
+
+ xfer += iprot->readStructBegin(fname);
+
+ using ::apache::thrift::protocol::TProtocolException;
+
+ bool isset_operation = false;
+ bool isset_probabilisticSampling = false;
+
+ while (true)
+ {
+ xfer += iprot->readFieldBegin(fname, ftype, fid);
+ if (ftype == ::apache::thrift::protocol::T_STOP) {
+ break;
+ }
+ switch (fid)
+ {
+ case 1:
+ if (ftype == ::apache::thrift::protocol::T_STRING) {
+ xfer += iprot->readString(this->operation);
+ isset_operation = true;
+ } else {
+ xfer += iprot->skip(ftype);
+ }
+ break;
+ case 2:
+ if (ftype == ::apache::thrift::protocol::T_STRUCT) {
+ xfer += this->probabilisticSampling.read(iprot);
+ isset_probabilisticSampling = true;
+ } else {
+ xfer += iprot->skip(ftype);
+ }
+ break;
+ default:
+ xfer += iprot->skip(ftype);
+ break;
+ }
+ xfer += iprot->readFieldEnd();
+ }
+
+ xfer += iprot->readStructEnd();
+
+ if (!isset_operation)
+ throw TProtocolException(TProtocolException::INVALID_DATA);
+ if (!isset_probabilisticSampling)
+ throw TProtocolException(TProtocolException::INVALID_DATA);
+ return xfer;
+}
+
+uint32_t OperationSamplingStrategy::write(::apache::thrift::protocol::TProtocol* oprot) const {
+ uint32_t xfer = 0;
+ ::apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
+ xfer += oprot->writeStructBegin("OperationSamplingStrategy");
+
+ xfer += oprot->writeFieldBegin("operation", ::apache::thrift::protocol::T_STRING, 1);
+ xfer += oprot->writeString(this->operation);
+ xfer += oprot->writeFieldEnd();
+
+ xfer += oprot->writeFieldBegin("probabilisticSampling", ::apache::thrift::protocol::T_STRUCT, 2);
+ xfer += this->probabilisticSampling.write(oprot);
+ xfer += oprot->writeFieldEnd();
+
+ xfer += oprot->writeFieldStop();
+ xfer += oprot->writeStructEnd();
+ return xfer;
+}
+
+void swap(OperationSamplingStrategy &a, OperationSamplingStrategy &b) {
+ using ::std::swap;
+ swap(a.operation, b.operation);
+ swap(a.probabilisticSampling, b.probabilisticSampling);
+}
+
+OperationSamplingStrategy::OperationSamplingStrategy(const OperationSamplingStrategy& other4) {
+ operation = other4.operation;
+ probabilisticSampling = other4.probabilisticSampling;
+}
+OperationSamplingStrategy& OperationSamplingStrategy::operator=(const OperationSamplingStrategy& other5) {
+ operation = other5.operation;
+ probabilisticSampling = other5.probabilisticSampling;
+ return *this;
+}
+void OperationSamplingStrategy::printTo(std::ostream& out) const {
+ using ::apache::thrift::to_string;
+ out << "OperationSamplingStrategy(";
+ out << "operation=" << to_string(operation);
+ out << ", " << "probabilisticSampling=" << to_string(probabilisticSampling);
+ out << ")";
+}
+
+
+PerOperationSamplingStrategies::~PerOperationSamplingStrategies() throw() {
+}
+
+
+void PerOperationSamplingStrategies::__set_defaultSamplingProbability(const double val) {
+ this->defaultSamplingProbability = val;
+}
+
+void PerOperationSamplingStrategies::__set_defaultLowerBoundTracesPerSecond(const double val) {
+ this->defaultLowerBoundTracesPerSecond = val;
+}
+
+void PerOperationSamplingStrategies::__set_perOperationStrategies(const std::vector<OperationSamplingStrategy> & val) {
+ this->perOperationStrategies = val;
+}
+
+void PerOperationSamplingStrategies::__set_defaultUpperBoundTracesPerSecond(const double val) {
+ this->defaultUpperBoundTracesPerSecond = val;
+__isset.defaultUpperBoundTracesPerSecond = true;
+}
+std::ostream& operator<<(std::ostream& out, const PerOperationSamplingStrategies& obj)
+{
+ obj.printTo(out);
+ return out;
+}
+
+
+uint32_t PerOperationSamplingStrategies::read(::apache::thrift::protocol::TProtocol* iprot) {
+
+ ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
+ uint32_t xfer = 0;
+ std::string fname;
+ ::apache::thrift::protocol::TType ftype;
+ int16_t fid;
+
+ xfer += iprot->readStructBegin(fname);
+
+ using ::apache::thrift::protocol::TProtocolException;
+
+ bool isset_defaultSamplingProbability = false;
+ bool isset_defaultLowerBoundTracesPerSecond = false;
+ bool isset_perOperationStrategies = false;
+
+ while (true)
+ {
+ xfer += iprot->readFieldBegin(fname, ftype, fid);
+ if (ftype == ::apache::thrift::protocol::T_STOP) {
+ break;
+ }
+ switch (fid)
+ {
+ case 1:
+ if (ftype == ::apache::thrift::protocol::T_DOUBLE) {
+ xfer += iprot->readDouble(this->defaultSamplingProbability);
+ isset_defaultSamplingProbability = true;
+ } else {
+ xfer += iprot->skip(ftype);
+ }
+ break;
+ case 2:
+ if (ftype == ::apache::thrift::protocol::T_DOUBLE) {
+ xfer += iprot->readDouble(this->defaultLowerBoundTracesPerSecond);
+ isset_defaultLowerBoundTracesPerSecond = true;
+ } else {
+ xfer += iprot->skip(ftype);
+ }
+ break;
+ case 3:
+ if (ftype == ::apache::thrift::protocol::T_LIST) {
+ {
+ this->perOperationStrategies.clear();
+ uint32_t _size6;
+ ::apache::thrift::protocol::TType _etype9;
+ xfer += iprot->readListBegin(_etype9, _size6);
+ this->perOperationStrategies.resize(_size6);
+ uint32_t _i10;
+ for (_i10 = 0; _i10 < _size6; ++_i10)
+ {
+ xfer += this->perOperationStrategies[_i10].read(iprot);
+ }
+ xfer += iprot->readListEnd();
+ }
+ isset_perOperationStrategies = true;
+ } else {
+ xfer += iprot->skip(ftype);
+ }
+ break;
+ case 4:
+ if (ftype == ::apache::thrift::protocol::T_DOUBLE) {
+ xfer += iprot->readDouble(this->defaultUpperBoundTracesPerSecond);
+ this->__isset.defaultUpperBoundTracesPerSecond = true;
+ } else {
+ xfer += iprot->skip(ftype);
+ }
+ break;
+ default:
+ xfer += iprot->skip(ftype);
+ break;
+ }
+ xfer += iprot->readFieldEnd();
+ }
+
+ xfer += iprot->readStructEnd();
+
+ if (!isset_defaultSamplingProbability)
+ throw TProtocolException(TProtocolException::INVALID_DATA);
+ if (!isset_defaultLowerBoundTracesPerSecond)
+ throw TProtocolException(TProtocolException::INVALID_DATA);
+ if (!isset_perOperationStrategies)
+ throw TProtocolException(TProtocolException::INVALID_DATA);
+ return xfer;
+}
+
+uint32_t PerOperationSamplingStrategies::write(::apache::thrift::protocol::TProtocol* oprot) const {
+ uint32_t xfer = 0;
+ ::apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
+ xfer += oprot->writeStructBegin("PerOperationSamplingStrategies");
+
+ xfer += oprot->writeFieldBegin("defaultSamplingProbability", ::apache::thrift::protocol::T_DOUBLE, 1);
+ xfer += oprot->writeDouble(this->defaultSamplingProbability);
+ xfer += oprot->writeFieldEnd();
+
+ xfer += oprot->writeFieldBegin("defaultLowerBoundTracesPerSecond", ::apache::thrift::protocol::T_DOUBLE, 2);
+ xfer += oprot->writeDouble(this->defaultLowerBoundTracesPerSecond);
+ xfer += oprot->writeFieldEnd();
+
+ xfer += oprot->writeFieldBegin("perOperationStrategies", ::apache::thrift::protocol::T_LIST, 3);
+ {
+ xfer += oprot->writeListBegin(::apache::thrift::protocol::T_STRUCT, static_cast<uint32_t>(this->perOperationStrategies.size()));
+ std::vector<OperationSamplingStrategy> ::const_iterator _iter11;
+ for (_iter11 = this->perOperationStrategies.begin(); _iter11 != this->perOperationStrategies.end(); ++_iter11)
+ {
+ xfer += (*_iter11).write(oprot);
+ }
+ xfer += oprot->writeListEnd();
+ }
+ xfer += oprot->writeFieldEnd();
+
+ if (this->__isset.defaultUpperBoundTracesPerSecond) {
+ xfer += oprot->writeFieldBegin("defaultUpperBoundTracesPerSecond", ::apache::thrift::protocol::T_DOUBLE, 4);
+ xfer += oprot->writeDouble(this->defaultUpperBoundTracesPerSecond);
+ xfer += oprot->writeFieldEnd();
+ }
+ xfer += oprot->writeFieldStop();
+ xfer += oprot->writeStructEnd();
+ return xfer;
+}
+
+void swap(PerOperationSamplingStrategies &a, PerOperationSamplingStrategies &b) {
+ using ::std::swap;
+ swap(a.defaultSamplingProbability, b.defaultSamplingProbability);
+ swap(a.defaultLowerBoundTracesPerSecond, b.defaultLowerBoundTracesPerSecond);
+ swap(a.perOperationStrategies, b.perOperationStrategies);
+ swap(a.defaultUpperBoundTracesPerSecond, b.defaultUpperBoundTracesPerSecond);
+ swap(a.__isset, b.__isset);
+}
+
+PerOperationSamplingStrategies::PerOperationSamplingStrategies(const PerOperationSamplingStrategies& other12) {
+ defaultSamplingProbability = other12.defaultSamplingProbability;
+ defaultLowerBoundTracesPerSecond = other12.defaultLowerBoundTracesPerSecond;
+ perOperationStrategies = other12.perOperationStrategies;
+ defaultUpperBoundTracesPerSecond = other12.defaultUpperBoundTracesPerSecond;
+ __isset = other12.__isset;
+}
+PerOperationSamplingStrategies& PerOperationSamplingStrategies::operator=(const PerOperationSamplingStrategies& other13) {
+ defaultSamplingProbability = other13.defaultSamplingProbability;
+ defaultLowerBoundTracesPerSecond = other13.defaultLowerBoundTracesPerSecond;
+ perOperationStrategies = other13.perOperationStrategies;
+ defaultUpperBoundTracesPerSecond = other13.defaultUpperBoundTracesPerSecond;
+ __isset = other13.__isset;
+ return *this;
+}
+void PerOperationSamplingStrategies::printTo(std::ostream& out) const {
+ using ::apache::thrift::to_string;
+ out << "PerOperationSamplingStrategies(";
+ out << "defaultSamplingProbability=" << to_string(defaultSamplingProbability);
+ out << ", " << "defaultLowerBoundTracesPerSecond=" << to_string(defaultLowerBoundTracesPerSecond);
+ out << ", " << "perOperationStrategies=" << to_string(perOperationStrategies);
+ out << ", " << "defaultUpperBoundTracesPerSecond="; (__isset.defaultUpperBoundTracesPerSecond ? (out << to_string(defaultUpperBoundTracesPerSecond)) : (out << "<null>"));
+ out << ")";
+}
+
+
+SamplingStrategyResponse::~SamplingStrategyResponse() throw() {
+}
+
+
+void SamplingStrategyResponse::__set_strategyType(const SamplingStrategyType::type val) {
+ this->strategyType = val;
+}
+
+void SamplingStrategyResponse::__set_probabilisticSampling(const ProbabilisticSamplingStrategy& val) {
+ this->probabilisticSampling = val;
+__isset.probabilisticSampling = true;
+}
+
+void SamplingStrategyResponse::__set_rateLimitingSampling(const RateLimitingSamplingStrategy& val) {
+ this->rateLimitingSampling = val;
+__isset.rateLimitingSampling = true;
+}
+
+void SamplingStrategyResponse::__set_operationSampling(const PerOperationSamplingStrategies& val) {
+ this->operationSampling = val;
+__isset.operationSampling = true;
+}
+std::ostream& operator<<(std::ostream& out, const SamplingStrategyResponse& obj)
+{
+ obj.printTo(out);
+ return out;
+}
+
+
+uint32_t SamplingStrategyResponse::read(::apache::thrift::protocol::TProtocol* iprot) {
+
+ ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
+ uint32_t xfer = 0;
+ std::string fname;
+ ::apache::thrift::protocol::TType ftype;
+ int16_t fid;
+
+ xfer += iprot->readStructBegin(fname);
+
+ using ::apache::thrift::protocol::TProtocolException;
+
+ bool isset_strategyType = false;
+
+ while (true)
+ {
+ xfer += iprot->readFieldBegin(fname, ftype, fid);
+ if (ftype == ::apache::thrift::protocol::T_STOP) {
+ break;
+ }
+ switch (fid)
+ {
+ case 1:
+ if (ftype == ::apache::thrift::protocol::T_I32) {
+ int32_t ecast14;
+ xfer += iprot->readI32(ecast14);
+ this->strategyType = (SamplingStrategyType::type)ecast14;
+ isset_strategyType = true;
+ } else {
+ xfer += iprot->skip(ftype);
+ }
+ break;
+ case 2:
+ if (ftype == ::apache::thrift::protocol::T_STRUCT) {
+ xfer += this->probabilisticSampling.read(iprot);
+ this->__isset.probabilisticSampling = true;
+ } else {
+ xfer += iprot->skip(ftype);
+ }
+ break;
+ case 3:
+ if (ftype == ::apache::thrift::protocol::T_STRUCT) {
+ xfer += this->rateLimitingSampling.read(iprot);
+ this->__isset.rateLimitingSampling = true;
+ } else {
+ xfer += iprot->skip(ftype);
+ }
+ break;
+ case 4:
+ if (ftype == ::apache::thrift::protocol::T_STRUCT) {
+ xfer += this->operationSampling.read(iprot);
+ this->__isset.operationSampling = true;
+ } else {
+ xfer += iprot->skip(ftype);
+ }
+ break;
+ default:
+ xfer += iprot->skip(ftype);
+ break;
+ }
+ xfer += iprot->readFieldEnd();
+ }
+
+ xfer += iprot->readStructEnd();
+
+ if (!isset_strategyType)
+ throw TProtocolException(TProtocolException::INVALID_DATA);
+ return xfer;
+}
+
+uint32_t SamplingStrategyResponse::write(::apache::thrift::protocol::TProtocol* oprot) const {
+ uint32_t xfer = 0;
+ ::apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
+ xfer += oprot->writeStructBegin("SamplingStrategyResponse");
+
+ xfer += oprot->writeFieldBegin("strategyType", ::apache::thrift::protocol::T_I32, 1);
+ xfer += oprot->writeI32((int32_t)this->strategyType);
+ xfer += oprot->writeFieldEnd();
+
+ if (this->__isset.probabilisticSampling) {
+ xfer += oprot->writeFieldBegin("probabilisticSampling", ::apache::thrift::protocol::T_STRUCT, 2);
+ xfer += this->probabilisticSampling.write(oprot);
+ xfer += oprot->writeFieldEnd();
+ }
+ if (this->__isset.rateLimitingSampling) {
+ xfer += oprot->writeFieldBegin("rateLimitingSampling", ::apache::thrift::protocol::T_STRUCT, 3);
+ xfer += this->rateLimitingSampling.write(oprot);
+ xfer += oprot->writeFieldEnd();
+ }
+ if (this->__isset.operationSampling) {
+ xfer += oprot->writeFieldBegin("operationSampling", ::apache::thrift::protocol::T_STRUCT, 4);
+ xfer += this->operationSampling.write(oprot);
+ xfer += oprot->writeFieldEnd();
+ }
+ xfer += oprot->writeFieldStop();
+ xfer += oprot->writeStructEnd();
+ return xfer;
+}
+
+void swap(SamplingStrategyResponse &a, SamplingStrategyResponse &b) {
+ using ::std::swap;
+ swap(a.strategyType, b.strategyType);
+ swap(a.probabilisticSampling, b.probabilisticSampling);
+ swap(a.rateLimitingSampling, b.rateLimitingSampling);
+ swap(a.operationSampling, b.operationSampling);
+ swap(a.__isset, b.__isset);
+}
+
+SamplingStrategyResponse::SamplingStrategyResponse(const SamplingStrategyResponse& other15) {
+ strategyType = other15.strategyType;
+ probabilisticSampling = other15.probabilisticSampling;
+ rateLimitingSampling = other15.rateLimitingSampling;
+ operationSampling = other15.operationSampling;
+ __isset = other15.__isset;
+}
+SamplingStrategyResponse& SamplingStrategyResponse::operator=(const SamplingStrategyResponse& other16) {
+ strategyType = other16.strategyType;
+ probabilisticSampling = other16.probabilisticSampling;
+ rateLimitingSampling = other16.rateLimitingSampling;
+ operationSampling = other16.operationSampling;
+ __isset = other16.__isset;
+ return *this;
+}
+void SamplingStrategyResponse::printTo(std::ostream& out) const {
+ using ::apache::thrift::to_string;
+ out << "SamplingStrategyResponse(";
+ out << "strategyType=" << to_string(strategyType);
+ out << ", " << "probabilisticSampling="; (__isset.probabilisticSampling ? (out << to_string(probabilisticSampling)) : (out << "<null>"));
+ out << ", " << "rateLimitingSampling="; (__isset.rateLimitingSampling ? (out << to_string(rateLimitingSampling)) : (out << "<null>"));
+ out << ", " << "operationSampling="; (__isset.operationSampling ? (out << to_string(operationSampling)) : (out << "<null>"));
+ out << ")";
+}
+
+}}} // namespace
diff --git a/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/thrift-gen/sampling_types.h b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/thrift-gen/sampling_types.h
new file mode 100644
index 000000000..49c63d6f7
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/thrift-gen/sampling_types.h
@@ -0,0 +1,283 @@
+/**
+ * Autogenerated by Thrift Compiler (0.11.0)
+ *
+ * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
+ * @generated
+ */
+#ifndef sampling_TYPES_H
+#define sampling_TYPES_H
+
+#include <iosfwd>
+
+#include <thrift/Thrift.h>
+#include <thrift/TApplicationException.h>
+#include <thrift/TBase.h>
+#include <thrift/protocol/TProtocol.h>
+#include <thrift/transport/TTransport.h>
+
+
+
+
+namespace jaegertracing { namespace sampling_manager { namespace thrift {
+
+struct SamplingStrategyType {
+ enum type {
+ PROBABILISTIC = 0,
+ RATE_LIMITING = 1
+ };
+};
+
+extern const std::map<int, const char*> _SamplingStrategyType_VALUES_TO_NAMES;
+
+std::ostream& operator<<(std::ostream& out, const SamplingStrategyType::type& val);
+
+class ProbabilisticSamplingStrategy;
+
+class RateLimitingSamplingStrategy;
+
+class OperationSamplingStrategy;
+
+class PerOperationSamplingStrategies;
+
+class SamplingStrategyResponse;
+
+
+class ProbabilisticSamplingStrategy : public virtual ::apache::thrift::TBase {
+ public:
+
+ ProbabilisticSamplingStrategy(const ProbabilisticSamplingStrategy&);
+ ProbabilisticSamplingStrategy& operator=(const ProbabilisticSamplingStrategy&);
+ ProbabilisticSamplingStrategy() : samplingRate(0) {
+ }
+
+ virtual ~ProbabilisticSamplingStrategy() throw();
+ double samplingRate;
+
+ void __set_samplingRate(const double val);
+
+ bool operator == (const ProbabilisticSamplingStrategy & rhs) const
+ {
+ if (!(samplingRate == rhs.samplingRate))
+ return false;
+ return true;
+ }
+ bool operator != (const ProbabilisticSamplingStrategy &rhs) const {
+ return !(*this == rhs);
+ }
+
+ bool operator < (const ProbabilisticSamplingStrategy & ) const;
+
+ uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
+ uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;
+
+ virtual void printTo(std::ostream& out) const;
+};
+
+void swap(ProbabilisticSamplingStrategy &a, ProbabilisticSamplingStrategy &b);
+
+std::ostream& operator<<(std::ostream& out, const ProbabilisticSamplingStrategy& obj);
+
+
+class RateLimitingSamplingStrategy : public virtual ::apache::thrift::TBase {
+ public:
+
+ RateLimitingSamplingStrategy(const RateLimitingSamplingStrategy&);
+ RateLimitingSamplingStrategy& operator=(const RateLimitingSamplingStrategy&);
+ RateLimitingSamplingStrategy() : maxTracesPerSecond(0) {
+ }
+
+ virtual ~RateLimitingSamplingStrategy() throw();
+ int16_t maxTracesPerSecond;
+
+ void __set_maxTracesPerSecond(const int16_t val);
+
+ bool operator == (const RateLimitingSamplingStrategy & rhs) const
+ {
+ if (!(maxTracesPerSecond == rhs.maxTracesPerSecond))
+ return false;
+ return true;
+ }
+ bool operator != (const RateLimitingSamplingStrategy &rhs) const {
+ return !(*this == rhs);
+ }
+
+ bool operator < (const RateLimitingSamplingStrategy & ) const;
+
+ uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
+ uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;
+
+ virtual void printTo(std::ostream& out) const;
+};
+
+void swap(RateLimitingSamplingStrategy &a, RateLimitingSamplingStrategy &b);
+
+std::ostream& operator<<(std::ostream& out, const RateLimitingSamplingStrategy& obj);
+
+
+class OperationSamplingStrategy : public virtual ::apache::thrift::TBase {
+ public:
+
+ OperationSamplingStrategy(const OperationSamplingStrategy&);
+ OperationSamplingStrategy& operator=(const OperationSamplingStrategy&);
+ OperationSamplingStrategy() : operation() {
+ }
+
+ virtual ~OperationSamplingStrategy() throw();
+ std::string operation;
+ ProbabilisticSamplingStrategy probabilisticSampling;
+
+ void __set_operation(const std::string& val);
+
+ void __set_probabilisticSampling(const ProbabilisticSamplingStrategy& val);
+
+ bool operator == (const OperationSamplingStrategy & rhs) const
+ {
+ if (!(operation == rhs.operation))
+ return false;
+ if (!(probabilisticSampling == rhs.probabilisticSampling))
+ return false;
+ return true;
+ }
+ bool operator != (const OperationSamplingStrategy &rhs) const {
+ return !(*this == rhs);
+ }
+
+ bool operator < (const OperationSamplingStrategy & ) const;
+
+ uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
+ uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;
+
+ virtual void printTo(std::ostream& out) const;
+};
+
+void swap(OperationSamplingStrategy &a, OperationSamplingStrategy &b);
+
+std::ostream& operator<<(std::ostream& out, const OperationSamplingStrategy& obj);
+
+typedef struct _PerOperationSamplingStrategies__isset {
+ _PerOperationSamplingStrategies__isset() : defaultUpperBoundTracesPerSecond(false) {}
+ bool defaultUpperBoundTracesPerSecond :1;
+} _PerOperationSamplingStrategies__isset;
+
+class PerOperationSamplingStrategies : public virtual ::apache::thrift::TBase {
+ public:
+
+ PerOperationSamplingStrategies(const PerOperationSamplingStrategies&);
+ PerOperationSamplingStrategies& operator=(const PerOperationSamplingStrategies&);
+ PerOperationSamplingStrategies() : defaultSamplingProbability(0), defaultLowerBoundTracesPerSecond(0), defaultUpperBoundTracesPerSecond(0) {
+ }
+
+ virtual ~PerOperationSamplingStrategies() throw();
+ double defaultSamplingProbability;
+ double defaultLowerBoundTracesPerSecond;
+ std::vector<OperationSamplingStrategy> perOperationStrategies;
+ double defaultUpperBoundTracesPerSecond;
+
+ _PerOperationSamplingStrategies__isset __isset;
+
+ void __set_defaultSamplingProbability(const double val);
+
+ void __set_defaultLowerBoundTracesPerSecond(const double val);
+
+ void __set_perOperationStrategies(const std::vector<OperationSamplingStrategy> & val);
+
+ void __set_defaultUpperBoundTracesPerSecond(const double val);
+
+ bool operator == (const PerOperationSamplingStrategies & rhs) const
+ {
+ if (!(defaultSamplingProbability == rhs.defaultSamplingProbability))
+ return false;
+ if (!(defaultLowerBoundTracesPerSecond == rhs.defaultLowerBoundTracesPerSecond))
+ return false;
+ if (!(perOperationStrategies == rhs.perOperationStrategies))
+ return false;
+ if (__isset.defaultUpperBoundTracesPerSecond != rhs.__isset.defaultUpperBoundTracesPerSecond)
+ return false;
+ else if (__isset.defaultUpperBoundTracesPerSecond && !(defaultUpperBoundTracesPerSecond == rhs.defaultUpperBoundTracesPerSecond))
+ return false;
+ return true;
+ }
+ bool operator != (const PerOperationSamplingStrategies &rhs) const {
+ return !(*this == rhs);
+ }
+
+ bool operator < (const PerOperationSamplingStrategies & ) const;
+
+ uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
+ uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;
+
+ virtual void printTo(std::ostream& out) const;
+};
+
+void swap(PerOperationSamplingStrategies &a, PerOperationSamplingStrategies &b);
+
+std::ostream& operator<<(std::ostream& out, const PerOperationSamplingStrategies& obj);
+
+typedef struct _SamplingStrategyResponse__isset {
+ _SamplingStrategyResponse__isset() : probabilisticSampling(false), rateLimitingSampling(false), operationSampling(false) {}
+ bool probabilisticSampling :1;
+ bool rateLimitingSampling :1;
+ bool operationSampling :1;
+} _SamplingStrategyResponse__isset;
+
+class SamplingStrategyResponse : public virtual ::apache::thrift::TBase {
+ public:
+
+ SamplingStrategyResponse(const SamplingStrategyResponse&);
+ SamplingStrategyResponse& operator=(const SamplingStrategyResponse&);
+ SamplingStrategyResponse() : strategyType((SamplingStrategyType::type)0) {
+ }
+
+ virtual ~SamplingStrategyResponse() throw();
+ SamplingStrategyType::type strategyType;
+ ProbabilisticSamplingStrategy probabilisticSampling;
+ RateLimitingSamplingStrategy rateLimitingSampling;
+ PerOperationSamplingStrategies operationSampling;
+
+ _SamplingStrategyResponse__isset __isset;
+
+ void __set_strategyType(const SamplingStrategyType::type val);
+
+ void __set_probabilisticSampling(const ProbabilisticSamplingStrategy& val);
+
+ void __set_rateLimitingSampling(const RateLimitingSamplingStrategy& val);
+
+ void __set_operationSampling(const PerOperationSamplingStrategies& val);
+
+ bool operator == (const SamplingStrategyResponse & rhs) const
+ {
+ if (!(strategyType == rhs.strategyType))
+ return false;
+ if (__isset.probabilisticSampling != rhs.__isset.probabilisticSampling)
+ return false;
+ else if (__isset.probabilisticSampling && !(probabilisticSampling == rhs.probabilisticSampling))
+ return false;
+ if (__isset.rateLimitingSampling != rhs.__isset.rateLimitingSampling)
+ return false;
+ else if (__isset.rateLimitingSampling && !(rateLimitingSampling == rhs.rateLimitingSampling))
+ return false;
+ if (__isset.operationSampling != rhs.__isset.operationSampling)
+ return false;
+ else if (__isset.operationSampling && !(operationSampling == rhs.operationSampling))
+ return false;
+ return true;
+ }
+ bool operator != (const SamplingStrategyResponse &rhs) const {
+ return !(*this == rhs);
+ }
+
+ bool operator < (const SamplingStrategyResponse & ) const;
+
+ uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
+ uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;
+
+ virtual void printTo(std::ostream& out) const;
+};
+
+void swap(SamplingStrategyResponse &a, SamplingStrategyResponse &b);
+
+std::ostream& operator<<(std::ostream& out, const SamplingStrategyResponse& obj);
+
+}}} // namespace
+
+#endif
diff --git a/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/thrift-gen/tracetest_constants.cpp b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/thrift-gen/tracetest_constants.cpp
new file mode 100644
index 000000000..8738dd2c8
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/thrift-gen/tracetest_constants.cpp
@@ -0,0 +1,17 @@
+/**
+ * Autogenerated by Thrift Compiler (0.11.0)
+ *
+ * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
+ * @generated
+ */
+#include "tracetest_constants.h"
+
+namespace jaegertracing { namespace crossdock { namespace thrift {
+
+const tracetestConstants g_tracetest_constants;
+
+tracetestConstants::tracetestConstants() {
+}
+
+}}} // namespace
+
diff --git a/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/thrift-gen/tracetest_constants.h b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/thrift-gen/tracetest_constants.h
new file mode 100644
index 000000000..96bf29048
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/thrift-gen/tracetest_constants.h
@@ -0,0 +1,24 @@
+/**
+ * Autogenerated by Thrift Compiler (0.11.0)
+ *
+ * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
+ * @generated
+ */
+#ifndef tracetest_CONSTANTS_H
+#define tracetest_CONSTANTS_H
+
+#include "tracetest_types.h"
+
+namespace jaegertracing { namespace crossdock { namespace thrift {
+
+class tracetestConstants {
+ public:
+ tracetestConstants();
+
+};
+
+extern const tracetestConstants g_tracetest_constants;
+
+}}} // namespace
+
+#endif
diff --git a/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/thrift-gen/tracetest_types.cpp b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/thrift-gen/tracetest_types.cpp
new file mode 100644
index 000000000..ceb7a204d
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/thrift-gen/tracetest_types.cpp
@@ -0,0 +1,804 @@
+/**
+ * Autogenerated by Thrift Compiler (0.11.0)
+ *
+ * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
+ * @generated
+ */
+#include "tracetest_types.h"
+
+#include <algorithm>
+#include <ostream>
+
+#include <thrift/TToString.h>
+
+namespace jaegertracing { namespace crossdock { namespace thrift {
+
+int _kTransportValues[] = {
+ Transport::HTTP,
+ Transport::TCHANNEL,
+ Transport::DUMMY
+};
+const char* _kTransportNames[] = {
+ "HTTP",
+ "TCHANNEL",
+ "DUMMY"
+};
+const std::map<int, const char*> _Transport_VALUES_TO_NAMES(::apache::thrift::TEnumIterator(3, _kTransportValues, _kTransportNames), ::apache::thrift::TEnumIterator(-1, NULL, NULL));
+
+std::ostream& operator<<(std::ostream& out, const Transport::type& val) {
+ std::map<int, const char*>::const_iterator it = _Transport_VALUES_TO_NAMES.find(val);
+ if (it != _Transport_VALUES_TO_NAMES.end()) {
+ out << it->second;
+ } else {
+ out << static_cast<int>(val);
+ }
+ return out;
+}
+
+
+Downstream::~Downstream() throw() {
+}
+
+
+void Downstream::__set_serviceName(const std::string& val) {
+ this->serviceName = val;
+}
+
+void Downstream::__set_serverRole(const std::string& val) {
+ this->serverRole = val;
+}
+
+void Downstream::__set_host(const std::string& val) {
+ this->host = val;
+}
+
+void Downstream::__set_port(const std::string& val) {
+ this->port = val;
+}
+
+void Downstream::__set_transport(const Transport::type val) {
+ this->transport = val;
+}
+
+void Downstream::__set_downstream(const std::shared_ptr<Downstream>& val) {
+ this->downstream = val;
+__isset.downstream = true;
+}
+std::ostream& operator<<(std::ostream& out, const Downstream& obj)
+{
+ obj.printTo(out);
+ return out;
+}
+
+
+uint32_t Downstream::read(::apache::thrift::protocol::TProtocol* iprot) {
+
+ ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
+ uint32_t xfer = 0;
+ std::string fname;
+ ::apache::thrift::protocol::TType ftype;
+ int16_t fid;
+
+ xfer += iprot->readStructBegin(fname);
+
+ using ::apache::thrift::protocol::TProtocolException;
+
+ bool isset_serviceName = false;
+ bool isset_serverRole = false;
+ bool isset_host = false;
+ bool isset_port = false;
+ bool isset_transport = false;
+
+ while (true)
+ {
+ xfer += iprot->readFieldBegin(fname, ftype, fid);
+ if (ftype == ::apache::thrift::protocol::T_STOP) {
+ break;
+ }
+ switch (fid)
+ {
+ case 1:
+ if (ftype == ::apache::thrift::protocol::T_STRING) {
+ xfer += iprot->readString(this->serviceName);
+ isset_serviceName = true;
+ } else {
+ xfer += iprot->skip(ftype);
+ }
+ break;
+ case 2:
+ if (ftype == ::apache::thrift::protocol::T_STRING) {
+ xfer += iprot->readString(this->serverRole);
+ isset_serverRole = true;
+ } else {
+ xfer += iprot->skip(ftype);
+ }
+ break;
+ case 3:
+ if (ftype == ::apache::thrift::protocol::T_STRING) {
+ xfer += iprot->readString(this->host);
+ isset_host = true;
+ } else {
+ xfer += iprot->skip(ftype);
+ }
+ break;
+ case 4:
+ if (ftype == ::apache::thrift::protocol::T_STRING) {
+ xfer += iprot->readString(this->port);
+ isset_port = true;
+ } else {
+ xfer += iprot->skip(ftype);
+ }
+ break;
+ case 5:
+ if (ftype == ::apache::thrift::protocol::T_I32) {
+ int32_t ecast0;
+ xfer += iprot->readI32(ecast0);
+ this->transport = (Transport::type)ecast0;
+ isset_transport = true;
+ } else {
+ xfer += iprot->skip(ftype);
+ }
+ break;
+ case 6:
+ if (ftype == ::apache::thrift::protocol::T_STRUCT) {
+ xfer += this->downstream->read(iprot);
+ this->__isset.downstream = true;
+ } else {
+ xfer += iprot->skip(ftype);
+ }
+ break;
+ default:
+ xfer += iprot->skip(ftype);
+ break;
+ }
+ xfer += iprot->readFieldEnd();
+ }
+
+ xfer += iprot->readStructEnd();
+
+ if (!isset_serviceName)
+ throw TProtocolException(TProtocolException::INVALID_DATA);
+ if (!isset_serverRole)
+ throw TProtocolException(TProtocolException::INVALID_DATA);
+ if (!isset_host)
+ throw TProtocolException(TProtocolException::INVALID_DATA);
+ if (!isset_port)
+ throw TProtocolException(TProtocolException::INVALID_DATA);
+ if (!isset_transport)
+ throw TProtocolException(TProtocolException::INVALID_DATA);
+ return xfer;
+}
+
+uint32_t Downstream::write(::apache::thrift::protocol::TProtocol* oprot) const {
+ uint32_t xfer = 0;
+ ::apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
+ xfer += oprot->writeStructBegin("Downstream");
+
+ xfer += oprot->writeFieldBegin("serviceName", ::apache::thrift::protocol::T_STRING, 1);
+ xfer += oprot->writeString(this->serviceName);
+ xfer += oprot->writeFieldEnd();
+
+ xfer += oprot->writeFieldBegin("serverRole", ::apache::thrift::protocol::T_STRING, 2);
+ xfer += oprot->writeString(this->serverRole);
+ xfer += oprot->writeFieldEnd();
+
+ xfer += oprot->writeFieldBegin("host", ::apache::thrift::protocol::T_STRING, 3);
+ xfer += oprot->writeString(this->host);
+ xfer += oprot->writeFieldEnd();
+
+ xfer += oprot->writeFieldBegin("port", ::apache::thrift::protocol::T_STRING, 4);
+ xfer += oprot->writeString(this->port);
+ xfer += oprot->writeFieldEnd();
+
+ xfer += oprot->writeFieldBegin("transport", ::apache::thrift::protocol::T_I32, 5);
+ xfer += oprot->writeI32((int32_t)this->transport);
+ xfer += oprot->writeFieldEnd();
+
+ if (this->__isset.downstream) {
+ xfer += oprot->writeFieldBegin("downstream", ::apache::thrift::protocol::T_STRUCT, 6);
+ xfer += this->downstream->write(oprot);
+ xfer += oprot->writeFieldEnd();
+ }
+ xfer += oprot->writeFieldStop();
+ xfer += oprot->writeStructEnd();
+ return xfer;
+}
+
+void swap(Downstream &a, Downstream &b) {
+ using ::std::swap;
+ swap(a.serviceName, b.serviceName);
+ swap(a.serverRole, b.serverRole);
+ swap(a.host, b.host);
+ swap(a.port, b.port);
+ swap(a.transport, b.transport);
+ swap(a.downstream, b.downstream);
+ swap(a.__isset, b.__isset);
+}
+
+Downstream::Downstream(const Downstream& other1) {
+ serviceName = other1.serviceName;
+ serverRole = other1.serverRole;
+ host = other1.host;
+ port = other1.port;
+ transport = other1.transport;
+ downstream = other1.downstream;
+ __isset = other1.__isset;
+}
+Downstream& Downstream::operator=(const Downstream& other2) {
+ serviceName = other2.serviceName;
+ serverRole = other2.serverRole;
+ host = other2.host;
+ port = other2.port;
+ transport = other2.transport;
+ downstream = other2.downstream;
+ __isset = other2.__isset;
+ return *this;
+}
+void Downstream::printTo(std::ostream& out) const {
+ using ::apache::thrift::to_string;
+ out << "Downstream(";
+ out << "serviceName=" << to_string(serviceName);
+ out << ", " << "serverRole=" << to_string(serverRole);
+ out << ", " << "host=" << to_string(host);
+ out << ", " << "port=" << to_string(port);
+ out << ", " << "transport=" << to_string(transport);
+ out << ", " << "downstream="; (__isset.downstream ? (out << to_string(downstream)) : (out << "<null>"));
+ out << ")";
+}
+
+
+StartTraceRequest::~StartTraceRequest() throw() {
+}
+
+
+void StartTraceRequest::__set_serverRole(const std::string& val) {
+ this->serverRole = val;
+}
+
+void StartTraceRequest::__set_sampled(const bool val) {
+ this->sampled = val;
+}
+
+void StartTraceRequest::__set_baggage(const std::string& val) {
+ this->baggage = val;
+}
+
+void StartTraceRequest::__set_downstream(const Downstream& val) {
+ this->downstream = val;
+}
+std::ostream& operator<<(std::ostream& out, const StartTraceRequest& obj)
+{
+ obj.printTo(out);
+ return out;
+}
+
+
+uint32_t StartTraceRequest::read(::apache::thrift::protocol::TProtocol* iprot) {
+
+ ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
+ uint32_t xfer = 0;
+ std::string fname;
+ ::apache::thrift::protocol::TType ftype;
+ int16_t fid;
+
+ xfer += iprot->readStructBegin(fname);
+
+ using ::apache::thrift::protocol::TProtocolException;
+
+ bool isset_serverRole = false;
+ bool isset_sampled = false;
+ bool isset_baggage = false;
+ bool isset_downstream = false;
+
+ while (true)
+ {
+ xfer += iprot->readFieldBegin(fname, ftype, fid);
+ if (ftype == ::apache::thrift::protocol::T_STOP) {
+ break;
+ }
+ switch (fid)
+ {
+ case 1:
+ if (ftype == ::apache::thrift::protocol::T_STRING) {
+ xfer += iprot->readString(this->serverRole);
+ isset_serverRole = true;
+ } else {
+ xfer += iprot->skip(ftype);
+ }
+ break;
+ case 2:
+ if (ftype == ::apache::thrift::protocol::T_BOOL) {
+ xfer += iprot->readBool(this->sampled);
+ isset_sampled = true;
+ } else {
+ xfer += iprot->skip(ftype);
+ }
+ break;
+ case 3:
+ if (ftype == ::apache::thrift::protocol::T_STRING) {
+ xfer += iprot->readString(this->baggage);
+ isset_baggage = true;
+ } else {
+ xfer += iprot->skip(ftype);
+ }
+ break;
+ case 4:
+ if (ftype == ::apache::thrift::protocol::T_STRUCT) {
+ xfer += this->downstream.read(iprot);
+ isset_downstream = true;
+ } else {
+ xfer += iprot->skip(ftype);
+ }
+ break;
+ default:
+ xfer += iprot->skip(ftype);
+ break;
+ }
+ xfer += iprot->readFieldEnd();
+ }
+
+ xfer += iprot->readStructEnd();
+
+ if (!isset_serverRole)
+ throw TProtocolException(TProtocolException::INVALID_DATA);
+ if (!isset_sampled)
+ throw TProtocolException(TProtocolException::INVALID_DATA);
+ if (!isset_baggage)
+ throw TProtocolException(TProtocolException::INVALID_DATA);
+ if (!isset_downstream)
+ throw TProtocolException(TProtocolException::INVALID_DATA);
+ return xfer;
+}
+
+uint32_t StartTraceRequest::write(::apache::thrift::protocol::TProtocol* oprot) const {
+ uint32_t xfer = 0;
+ ::apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
+ xfer += oprot->writeStructBegin("StartTraceRequest");
+
+ xfer += oprot->writeFieldBegin("serverRole", ::apache::thrift::protocol::T_STRING, 1);
+ xfer += oprot->writeString(this->serverRole);
+ xfer += oprot->writeFieldEnd();
+
+ xfer += oprot->writeFieldBegin("sampled", ::apache::thrift::protocol::T_BOOL, 2);
+ xfer += oprot->writeBool(this->sampled);
+ xfer += oprot->writeFieldEnd();
+
+ xfer += oprot->writeFieldBegin("baggage", ::apache::thrift::protocol::T_STRING, 3);
+ xfer += oprot->writeString(this->baggage);
+ xfer += oprot->writeFieldEnd();
+
+ xfer += oprot->writeFieldBegin("downstream", ::apache::thrift::protocol::T_STRUCT, 4);
+ xfer += this->downstream.write(oprot);
+ xfer += oprot->writeFieldEnd();
+
+ xfer += oprot->writeFieldStop();
+ xfer += oprot->writeStructEnd();
+ return xfer;
+}
+
+void swap(StartTraceRequest &a, StartTraceRequest &b) {
+ using ::std::swap;
+ swap(a.serverRole, b.serverRole);
+ swap(a.sampled, b.sampled);
+ swap(a.baggage, b.baggage);
+ swap(a.downstream, b.downstream);
+}
+
+StartTraceRequest::StartTraceRequest(const StartTraceRequest& other3) {
+ serverRole = other3.serverRole;
+ sampled = other3.sampled;
+ baggage = other3.baggage;
+ downstream = other3.downstream;
+}
+StartTraceRequest& StartTraceRequest::operator=(const StartTraceRequest& other4) {
+ serverRole = other4.serverRole;
+ sampled = other4.sampled;
+ baggage = other4.baggage;
+ downstream = other4.downstream;
+ return *this;
+}
+void StartTraceRequest::printTo(std::ostream& out) const {
+ using ::apache::thrift::to_string;
+ out << "StartTraceRequest(";
+ out << "serverRole=" << to_string(serverRole);
+ out << ", " << "sampled=" << to_string(sampled);
+ out << ", " << "baggage=" << to_string(baggage);
+ out << ", " << "downstream=" << to_string(downstream);
+ out << ")";
+}
+
+
+JoinTraceRequest::~JoinTraceRequest() throw() {
+}
+
+
+void JoinTraceRequest::__set_serverRole(const std::string& val) {
+ this->serverRole = val;
+}
+
+void JoinTraceRequest::__set_downstream(const Downstream& val) {
+ this->downstream = val;
+__isset.downstream = true;
+}
+std::ostream& operator<<(std::ostream& out, const JoinTraceRequest& obj)
+{
+ obj.printTo(out);
+ return out;
+}
+
+
+uint32_t JoinTraceRequest::read(::apache::thrift::protocol::TProtocol* iprot) {
+
+ ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
+ uint32_t xfer = 0;
+ std::string fname;
+ ::apache::thrift::protocol::TType ftype;
+ int16_t fid;
+
+ xfer += iprot->readStructBegin(fname);
+
+ using ::apache::thrift::protocol::TProtocolException;
+
+ bool isset_serverRole = false;
+
+ while (true)
+ {
+ xfer += iprot->readFieldBegin(fname, ftype, fid);
+ if (ftype == ::apache::thrift::protocol::T_STOP) {
+ break;
+ }
+ switch (fid)
+ {
+ case 1:
+ if (ftype == ::apache::thrift::protocol::T_STRING) {
+ xfer += iprot->readString(this->serverRole);
+ isset_serverRole = true;
+ } else {
+ xfer += iprot->skip(ftype);
+ }
+ break;
+ case 2:
+ if (ftype == ::apache::thrift::protocol::T_STRUCT) {
+ xfer += this->downstream.read(iprot);
+ this->__isset.downstream = true;
+ } else {
+ xfer += iprot->skip(ftype);
+ }
+ break;
+ default:
+ xfer += iprot->skip(ftype);
+ break;
+ }
+ xfer += iprot->readFieldEnd();
+ }
+
+ xfer += iprot->readStructEnd();
+
+ if (!isset_serverRole)
+ throw TProtocolException(TProtocolException::INVALID_DATA);
+ return xfer;
+}
+
+uint32_t JoinTraceRequest::write(::apache::thrift::protocol::TProtocol* oprot) const {
+ uint32_t xfer = 0;
+ ::apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
+ xfer += oprot->writeStructBegin("JoinTraceRequest");
+
+ xfer += oprot->writeFieldBegin("serverRole", ::apache::thrift::protocol::T_STRING, 1);
+ xfer += oprot->writeString(this->serverRole);
+ xfer += oprot->writeFieldEnd();
+
+ if (this->__isset.downstream) {
+ xfer += oprot->writeFieldBegin("downstream", ::apache::thrift::protocol::T_STRUCT, 2);
+ xfer += this->downstream.write(oprot);
+ xfer += oprot->writeFieldEnd();
+ }
+ xfer += oprot->writeFieldStop();
+ xfer += oprot->writeStructEnd();
+ return xfer;
+}
+
+void swap(JoinTraceRequest &a, JoinTraceRequest &b) {
+ using ::std::swap;
+ swap(a.serverRole, b.serverRole);
+ swap(a.downstream, b.downstream);
+ swap(a.__isset, b.__isset);
+}
+
+JoinTraceRequest::JoinTraceRequest(const JoinTraceRequest& other5) {
+ serverRole = other5.serverRole;
+ downstream = other5.downstream;
+ __isset = other5.__isset;
+}
+JoinTraceRequest& JoinTraceRequest::operator=(const JoinTraceRequest& other6) {
+ serverRole = other6.serverRole;
+ downstream = other6.downstream;
+ __isset = other6.__isset;
+ return *this;
+}
+void JoinTraceRequest::printTo(std::ostream& out) const {
+ using ::apache::thrift::to_string;
+ out << "JoinTraceRequest(";
+ out << "serverRole=" << to_string(serverRole);
+ out << ", " << "downstream="; (__isset.downstream ? (out << to_string(downstream)) : (out << "<null>"));
+ out << ")";
+}
+
+
+ObservedSpan::~ObservedSpan() throw() {
+}
+
+
+void ObservedSpan::__set_traceId(const std::string& val) {
+ this->traceId = val;
+}
+
+void ObservedSpan::__set_sampled(const bool val) {
+ this->sampled = val;
+}
+
+void ObservedSpan::__set_baggage(const std::string& val) {
+ this->baggage = val;
+}
+std::ostream& operator<<(std::ostream& out, const ObservedSpan& obj)
+{
+ obj.printTo(out);
+ return out;
+}
+
+
+uint32_t ObservedSpan::read(::apache::thrift::protocol::TProtocol* iprot) {
+
+ ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
+ uint32_t xfer = 0;
+ std::string fname;
+ ::apache::thrift::protocol::TType ftype;
+ int16_t fid;
+
+ xfer += iprot->readStructBegin(fname);
+
+ using ::apache::thrift::protocol::TProtocolException;
+
+ bool isset_traceId = false;
+ bool isset_sampled = false;
+ bool isset_baggage = false;
+
+ while (true)
+ {
+ xfer += iprot->readFieldBegin(fname, ftype, fid);
+ if (ftype == ::apache::thrift::protocol::T_STOP) {
+ break;
+ }
+ switch (fid)
+ {
+ case 1:
+ if (ftype == ::apache::thrift::protocol::T_STRING) {
+ xfer += iprot->readString(this->traceId);
+ isset_traceId = true;
+ } else {
+ xfer += iprot->skip(ftype);
+ }
+ break;
+ case 2:
+ if (ftype == ::apache::thrift::protocol::T_BOOL) {
+ xfer += iprot->readBool(this->sampled);
+ isset_sampled = true;
+ } else {
+ xfer += iprot->skip(ftype);
+ }
+ break;
+ case 3:
+ if (ftype == ::apache::thrift::protocol::T_STRING) {
+ xfer += iprot->readString(this->baggage);
+ isset_baggage = true;
+ } else {
+ xfer += iprot->skip(ftype);
+ }
+ break;
+ default:
+ xfer += iprot->skip(ftype);
+ break;
+ }
+ xfer += iprot->readFieldEnd();
+ }
+
+ xfer += iprot->readStructEnd();
+
+ if (!isset_traceId)
+ throw TProtocolException(TProtocolException::INVALID_DATA);
+ if (!isset_sampled)
+ throw TProtocolException(TProtocolException::INVALID_DATA);
+ if (!isset_baggage)
+ throw TProtocolException(TProtocolException::INVALID_DATA);
+ return xfer;
+}
+
+uint32_t ObservedSpan::write(::apache::thrift::protocol::TProtocol* oprot) const {
+ uint32_t xfer = 0;
+ ::apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
+ xfer += oprot->writeStructBegin("ObservedSpan");
+
+ xfer += oprot->writeFieldBegin("traceId", ::apache::thrift::protocol::T_STRING, 1);
+ xfer += oprot->writeString(this->traceId);
+ xfer += oprot->writeFieldEnd();
+
+ xfer += oprot->writeFieldBegin("sampled", ::apache::thrift::protocol::T_BOOL, 2);
+ xfer += oprot->writeBool(this->sampled);
+ xfer += oprot->writeFieldEnd();
+
+ xfer += oprot->writeFieldBegin("baggage", ::apache::thrift::protocol::T_STRING, 3);
+ xfer += oprot->writeString(this->baggage);
+ xfer += oprot->writeFieldEnd();
+
+ xfer += oprot->writeFieldStop();
+ xfer += oprot->writeStructEnd();
+ return xfer;
+}
+
+void swap(ObservedSpan &a, ObservedSpan &b) {
+ using ::std::swap;
+ swap(a.traceId, b.traceId);
+ swap(a.sampled, b.sampled);
+ swap(a.baggage, b.baggage);
+}
+
+ObservedSpan::ObservedSpan(const ObservedSpan& other7) {
+ traceId = other7.traceId;
+ sampled = other7.sampled;
+ baggage = other7.baggage;
+}
+ObservedSpan& ObservedSpan::operator=(const ObservedSpan& other8) {
+ traceId = other8.traceId;
+ sampled = other8.sampled;
+ baggage = other8.baggage;
+ return *this;
+}
+void ObservedSpan::printTo(std::ostream& out) const {
+ using ::apache::thrift::to_string;
+ out << "ObservedSpan(";
+ out << "traceId=" << to_string(traceId);
+ out << ", " << "sampled=" << to_string(sampled);
+ out << ", " << "baggage=" << to_string(baggage);
+ out << ")";
+}
+
+
+TraceResponse::~TraceResponse() throw() {
+}
+
+
+void TraceResponse::__set_span(const ObservedSpan& val) {
+ this->span = val;
+__isset.span = true;
+}
+
+void TraceResponse::__set_downstream(const std::shared_ptr<TraceResponse>& val) {
+ this->downstream = val;
+__isset.downstream = true;
+}
+
+void TraceResponse::__set_notImplementedError(const std::string& val) {
+ this->notImplementedError = val;
+}
+std::ostream& operator<<(std::ostream& out, const TraceResponse& obj)
+{
+ obj.printTo(out);
+ return out;
+}
+
+
+uint32_t TraceResponse::read(::apache::thrift::protocol::TProtocol* iprot) {
+
+ ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
+ uint32_t xfer = 0;
+ std::string fname;
+ ::apache::thrift::protocol::TType ftype;
+ int16_t fid;
+
+ xfer += iprot->readStructBegin(fname);
+
+ using ::apache::thrift::protocol::TProtocolException;
+
+ bool isset_notImplementedError = false;
+
+ while (true)
+ {
+ xfer += iprot->readFieldBegin(fname, ftype, fid);
+ if (ftype == ::apache::thrift::protocol::T_STOP) {
+ break;
+ }
+ switch (fid)
+ {
+ case 1:
+ if (ftype == ::apache::thrift::protocol::T_STRUCT) {
+ xfer += this->span.read(iprot);
+ this->__isset.span = true;
+ } else {
+ xfer += iprot->skip(ftype);
+ }
+ break;
+ case 2:
+ if (ftype == ::apache::thrift::protocol::T_STRUCT) {
+ xfer += this->downstream->read(iprot);
+ this->__isset.downstream = true;
+ } else {
+ xfer += iprot->skip(ftype);
+ }
+ break;
+ case 3:
+ if (ftype == ::apache::thrift::protocol::T_STRING) {
+ xfer += iprot->readString(this->notImplementedError);
+ isset_notImplementedError = true;
+ } else {
+ xfer += iprot->skip(ftype);
+ }
+ break;
+ default:
+ xfer += iprot->skip(ftype);
+ break;
+ }
+ xfer += iprot->readFieldEnd();
+ }
+
+ xfer += iprot->readStructEnd();
+
+ if (!isset_notImplementedError)
+ throw TProtocolException(TProtocolException::INVALID_DATA);
+ return xfer;
+}
+
+uint32_t TraceResponse::write(::apache::thrift::protocol::TProtocol* oprot) const {
+ uint32_t xfer = 0;
+ ::apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
+ xfer += oprot->writeStructBegin("TraceResponse");
+
+ if (this->__isset.span) {
+ xfer += oprot->writeFieldBegin("span", ::apache::thrift::protocol::T_STRUCT, 1);
+ xfer += this->span.write(oprot);
+ xfer += oprot->writeFieldEnd();
+ }
+ if (this->__isset.downstream) {
+ xfer += oprot->writeFieldBegin("downstream", ::apache::thrift::protocol::T_STRUCT, 2);
+ xfer += this->downstream->write(oprot);
+ xfer += oprot->writeFieldEnd();
+ }
+ xfer += oprot->writeFieldBegin("notImplementedError", ::apache::thrift::protocol::T_STRING, 3);
+ xfer += oprot->writeString(this->notImplementedError);
+ xfer += oprot->writeFieldEnd();
+
+ xfer += oprot->writeFieldStop();
+ xfer += oprot->writeStructEnd();
+ return xfer;
+}
+
+void swap(TraceResponse &a, TraceResponse &b) {
+ using ::std::swap;
+ swap(a.span, b.span);
+ swap(a.downstream, b.downstream);
+ swap(a.notImplementedError, b.notImplementedError);
+ swap(a.__isset, b.__isset);
+}
+
+TraceResponse::TraceResponse(const TraceResponse& other9) {
+ span = other9.span;
+ downstream = other9.downstream;
+ notImplementedError = other9.notImplementedError;
+ __isset = other9.__isset;
+}
+TraceResponse& TraceResponse::operator=(const TraceResponse& other10) {
+ span = other10.span;
+ downstream = other10.downstream;
+ notImplementedError = other10.notImplementedError;
+ __isset = other10.__isset;
+ return *this;
+}
+void TraceResponse::printTo(std::ostream& out) const {
+ using ::apache::thrift::to_string;
+ out << "TraceResponse(";
+ out << "span="; (__isset.span ? (out << to_string(span)) : (out << "<null>"));
+ out << ", " << "downstream="; (__isset.downstream ? (out << to_string(downstream)) : (out << "<null>"));
+ out << ", " << "notImplementedError=" << to_string(notImplementedError);
+ out << ")";
+}
+
+}}} // namespace
diff --git a/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/thrift-gen/tracetest_types.h b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/thrift-gen/tracetest_types.h
new file mode 100644
index 000000000..90c0b9666
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/thrift-gen/tracetest_types.h
@@ -0,0 +1,316 @@
+/**
+ * Autogenerated by Thrift Compiler (0.11.0)
+ *
+ * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
+ * @generated
+ */
+#ifndef tracetest_TYPES_H
+#define tracetest_TYPES_H
+
+#include <iosfwd>
+
+#include <thrift/Thrift.h>
+#include <thrift/TApplicationException.h>
+#include <thrift/TBase.h>
+#include <thrift/protocol/TProtocol.h>
+#include <thrift/transport/TTransport.h>
+
+namespace jaegertracing { namespace crossdock { namespace thrift {
+
+struct Transport {
+ enum type {
+ HTTP = 0,
+ TCHANNEL = 1,
+ DUMMY = 2
+ };
+};
+
+extern const std::map<int, const char*> _Transport_VALUES_TO_NAMES;
+
+std::ostream& operator<<(std::ostream& out, const Transport::type& val);
+
+class Downstream;
+
+class StartTraceRequest;
+
+class JoinTraceRequest;
+
+class ObservedSpan;
+
+class TraceResponse;
+
+typedef struct _Downstream__isset {
+ _Downstream__isset() : downstream(false) {}
+ bool downstream :1;
+} _Downstream__isset;
+
+class Downstream : public virtual ::apache::thrift::TBase {
+ public:
+
+ Downstream(const Downstream&);
+ Downstream& operator=(const Downstream&);
+ Downstream() : serviceName(), serverRole(), host(), port(), transport((Transport::type)0) {
+ }
+
+ virtual ~Downstream() throw();
+ std::string serviceName;
+ std::string serverRole;
+ std::string host;
+ std::string port;
+ Transport::type transport;
+ std::shared_ptr<Downstream> downstream;
+
+ _Downstream__isset __isset;
+
+ void __set_serviceName(const std::string& val);
+
+ void __set_serverRole(const std::string& val);
+
+ void __set_host(const std::string& val);
+
+ void __set_port(const std::string& val);
+
+ void __set_transport(const Transport::type val);
+
+ void __set_downstream(const std::shared_ptr<Downstream>& val);
+
+ bool operator == (const Downstream & rhs) const
+ {
+ if (!(serviceName == rhs.serviceName))
+ return false;
+ if (!(serverRole == rhs.serverRole))
+ return false;
+ if (!(host == rhs.host))
+ return false;
+ if (!(port == rhs.port))
+ return false;
+ if (!(transport == rhs.transport))
+ return false;
+ if (__isset.downstream != rhs.__isset.downstream)
+ return false;
+ else if (__isset.downstream && !(*downstream == *rhs.downstream))
+ return false;
+ return true;
+ }
+ bool operator != (const Downstream &rhs) const {
+ return !(*this == rhs);
+ }
+
+ bool operator < (const Downstream & ) const;
+
+ uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
+ uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;
+
+ virtual void printTo(std::ostream& out) const;
+};
+
+void swap(Downstream &a, Downstream &b);
+
+std::ostream& operator<<(std::ostream& out, const Downstream& obj);
+
+
+class StartTraceRequest : public virtual ::apache::thrift::TBase {
+ public:
+
+ StartTraceRequest(const StartTraceRequest&);
+ StartTraceRequest& operator=(const StartTraceRequest&);
+ StartTraceRequest() : serverRole(), sampled(0), baggage() {
+ }
+
+ virtual ~StartTraceRequest() throw();
+ std::string serverRole;
+ bool sampled;
+ std::string baggage;
+ Downstream downstream;
+
+ void __set_serverRole(const std::string& val);
+
+ void __set_sampled(const bool val);
+
+ void __set_baggage(const std::string& val);
+
+ void __set_downstream(const Downstream& val);
+
+ bool operator == (const StartTraceRequest & rhs) const
+ {
+ if (!(serverRole == rhs.serverRole))
+ return false;
+ if (!(sampled == rhs.sampled))
+ return false;
+ if (!(baggage == rhs.baggage))
+ return false;
+ if (!(downstream == rhs.downstream))
+ return false;
+ return true;
+ }
+ bool operator != (const StartTraceRequest &rhs) const {
+ return !(*this == rhs);
+ }
+
+ bool operator < (const StartTraceRequest & ) const;
+
+ uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
+ uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;
+
+ virtual void printTo(std::ostream& out) const;
+};
+
+void swap(StartTraceRequest &a, StartTraceRequest &b);
+
+std::ostream& operator<<(std::ostream& out, const StartTraceRequest& obj);
+
+typedef struct _JoinTraceRequest__isset {
+ _JoinTraceRequest__isset() : downstream(false) {}
+ bool downstream :1;
+} _JoinTraceRequest__isset;
+
+class JoinTraceRequest : public virtual ::apache::thrift::TBase {
+ public:
+
+ JoinTraceRequest(const JoinTraceRequest&);
+ JoinTraceRequest& operator=(const JoinTraceRequest&);
+ JoinTraceRequest() : serverRole() {
+ }
+
+ virtual ~JoinTraceRequest() throw();
+ std::string serverRole;
+ Downstream downstream;
+
+ _JoinTraceRequest__isset __isset;
+
+ void __set_serverRole(const std::string& val);
+
+ void __set_downstream(const Downstream& val);
+
+ bool operator == (const JoinTraceRequest & rhs) const
+ {
+ if (!(serverRole == rhs.serverRole))
+ return false;
+ if (__isset.downstream != rhs.__isset.downstream)
+ return false;
+ else if (__isset.downstream && !(downstream == rhs.downstream))
+ return false;
+ return true;
+ }
+ bool operator != (const JoinTraceRequest &rhs) const {
+ return !(*this == rhs);
+ }
+
+ bool operator < (const JoinTraceRequest & ) const;
+
+ uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
+ uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;
+
+ virtual void printTo(std::ostream& out) const;
+};
+
+void swap(JoinTraceRequest &a, JoinTraceRequest &b);
+
+std::ostream& operator<<(std::ostream& out, const JoinTraceRequest& obj);
+
+
+class ObservedSpan : public virtual ::apache::thrift::TBase {
+ public:
+
+ ObservedSpan(const ObservedSpan&);
+ ObservedSpan& operator=(const ObservedSpan&);
+ ObservedSpan() : traceId(), sampled(0), baggage() {
+ }
+
+ virtual ~ObservedSpan() throw();
+ std::string traceId;
+ bool sampled;
+ std::string baggage;
+
+ void __set_traceId(const std::string& val);
+
+ void __set_sampled(const bool val);
+
+ void __set_baggage(const std::string& val);
+
+ bool operator == (const ObservedSpan & rhs) const
+ {
+ if (!(traceId == rhs.traceId))
+ return false;
+ if (!(sampled == rhs.sampled))
+ return false;
+ if (!(baggage == rhs.baggage))
+ return false;
+ return true;
+ }
+ bool operator != (const ObservedSpan &rhs) const {
+ return !(*this == rhs);
+ }
+
+ bool operator < (const ObservedSpan & ) const;
+
+ uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
+ uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;
+
+ virtual void printTo(std::ostream& out) const;
+};
+
+void swap(ObservedSpan &a, ObservedSpan &b);
+
+std::ostream& operator<<(std::ostream& out, const ObservedSpan& obj);
+
+typedef struct _TraceResponse__isset {
+ _TraceResponse__isset() : span(false), downstream(false) {}
+ bool span :1;
+ bool downstream :1;
+} _TraceResponse__isset;
+
+class TraceResponse : public virtual ::apache::thrift::TBase {
+ public:
+
+ TraceResponse(const TraceResponse&);
+ TraceResponse& operator=(const TraceResponse&);
+ TraceResponse() : notImplementedError() {
+ }
+
+ virtual ~TraceResponse() throw();
+ ObservedSpan span;
+ std::shared_ptr<TraceResponse> downstream;
+ std::string notImplementedError;
+
+ _TraceResponse__isset __isset;
+
+ void __set_span(const ObservedSpan& val);
+
+ void __set_downstream(const std::shared_ptr<TraceResponse>& val);
+
+ void __set_notImplementedError(const std::string& val);
+
+ bool operator == (const TraceResponse & rhs) const
+ {
+ if (__isset.span != rhs.__isset.span)
+ return false;
+ else if (__isset.span && !(span == rhs.span))
+ return false;
+ if (__isset.downstream != rhs.__isset.downstream)
+ return false;
+ else if (__isset.downstream && !(*downstream == *rhs.downstream))
+ return false;
+ if (!(notImplementedError == rhs.notImplementedError))
+ return false;
+ return true;
+ }
+ bool operator != (const TraceResponse &rhs) const {
+ return !(*this == rhs);
+ }
+
+ bool operator < (const TraceResponse & ) const;
+
+ uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
+ uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;
+
+ virtual void printTo(std::ostream& out) const;
+};
+
+void swap(TraceResponse &a, TraceResponse &b);
+
+std::ostream& operator<<(std::ostream& out, const TraceResponse& obj);
+
+}}} // namespace
+
+#endif
diff --git a/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/thrift-gen/zipkincore_constants.cpp b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/thrift-gen/zipkincore_constants.cpp
new file mode 100644
index 000000000..3b463710a
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/thrift-gen/zipkincore_constants.cpp
@@ -0,0 +1,49 @@
+/**
+ * Autogenerated by Thrift Compiler (0.11.0)
+ *
+ * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
+ * @generated
+ */
+#include "zipkincore_constants.h"
+
+namespace twitter { namespace zipkin { namespace thrift {
+
+const zipkincoreConstants g_zipkincore_constants;
+
+zipkincoreConstants::zipkincoreConstants() {
+ CLIENT_SEND = "cs";
+
+ CLIENT_RECV = "cr";
+
+ SERVER_SEND = "ss";
+
+ SERVER_RECV = "sr";
+
+ MESSAGE_SEND = "ms";
+
+ MESSAGE_RECV = "mr";
+
+ WIRE_SEND = "ws";
+
+ WIRE_RECV = "wr";
+
+ CLIENT_SEND_FRAGMENT = "csf";
+
+ CLIENT_RECV_FRAGMENT = "crf";
+
+ SERVER_SEND_FRAGMENT = "ssf";
+
+ SERVER_RECV_FRAGMENT = "srf";
+
+ LOCAL_COMPONENT = "lc";
+
+ CLIENT_ADDR = "ca";
+
+ SERVER_ADDR = "sa";
+
+ MESSAGE_ADDR = "ma";
+
+}
+
+}}} // namespace
+
diff --git a/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/thrift-gen/zipkincore_constants.h b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/thrift-gen/zipkincore_constants.h
new file mode 100644
index 000000000..b759e0695
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/thrift-gen/zipkincore_constants.h
@@ -0,0 +1,40 @@
+/**
+ * Autogenerated by Thrift Compiler (0.11.0)
+ *
+ * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
+ * @generated
+ */
+#ifndef zipkincore_CONSTANTS_H
+#define zipkincore_CONSTANTS_H
+
+#include "zipkincore_types.h"
+
+namespace twitter { namespace zipkin { namespace thrift {
+
+class zipkincoreConstants {
+ public:
+ zipkincoreConstants();
+
+ std::string CLIENT_SEND;
+ std::string CLIENT_RECV;
+ std::string SERVER_SEND;
+ std::string SERVER_RECV;
+ std::string MESSAGE_SEND;
+ std::string MESSAGE_RECV;
+ std::string WIRE_SEND;
+ std::string WIRE_RECV;
+ std::string CLIENT_SEND_FRAGMENT;
+ std::string CLIENT_RECV_FRAGMENT;
+ std::string SERVER_SEND_FRAGMENT;
+ std::string SERVER_RECV_FRAGMENT;
+ std::string LOCAL_COMPONENT;
+ std::string CLIENT_ADDR;
+ std::string SERVER_ADDR;
+ std::string MESSAGE_ADDR;
+};
+
+extern const zipkincoreConstants g_zipkincore_constants;
+
+}}} // namespace
+
+#endif
diff --git a/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/thrift-gen/zipkincore_types.cpp b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/thrift-gen/zipkincore_types.cpp
new file mode 100644
index 000000000..de44dbbbc
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/thrift-gen/zipkincore_types.cpp
@@ -0,0 +1,904 @@
+/**
+ * Autogenerated by Thrift Compiler (0.11.0)
+ *
+ * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
+ * @generated
+ */
+#include "zipkincore_types.h"
+
+#include <algorithm>
+#include <ostream>
+
+#include <thrift/TToString.h>
+
+namespace twitter { namespace zipkin { namespace thrift {
+
+int _kAnnotationTypeValues[] = {
+ AnnotationType::BOOL,
+ AnnotationType::BYTES,
+ AnnotationType::I16,
+ AnnotationType::I32,
+ AnnotationType::I64,
+ AnnotationType::DOUBLE,
+ AnnotationType::STRING
+};
+const char* _kAnnotationTypeNames[] = {
+ "BOOL",
+ "BYTES",
+ "I16",
+ "I32",
+ "I64",
+ "DOUBLE",
+ "STRING"
+};
+const std::map<int, const char*> _AnnotationType_VALUES_TO_NAMES(::apache::thrift::TEnumIterator(7, _kAnnotationTypeValues, _kAnnotationTypeNames), ::apache::thrift::TEnumIterator(-1, NULL, NULL));
+
+std::ostream& operator<<(std::ostream& out, const AnnotationType::type& val) {
+ std::map<int, const char*>::const_iterator it = _AnnotationType_VALUES_TO_NAMES.find(val);
+ if (it != _AnnotationType_VALUES_TO_NAMES.end()) {
+ out << it->second;
+ } else {
+ out << static_cast<int>(val);
+ }
+ return out;
+}
+
+
+Endpoint::~Endpoint() throw() {
+}
+
+
+void Endpoint::__set_ipv4(const int32_t val) {
+ this->ipv4 = val;
+}
+
+void Endpoint::__set_port(const int16_t val) {
+ this->port = val;
+}
+
+void Endpoint::__set_service_name(const std::string& val) {
+ this->service_name = val;
+}
+
+void Endpoint::__set_ipv6(const std::string& val) {
+ this->ipv6 = val;
+__isset.ipv6 = true;
+}
+std::ostream& operator<<(std::ostream& out, const Endpoint& obj)
+{
+ obj.printTo(out);
+ return out;
+}
+
+
+uint32_t Endpoint::read(::apache::thrift::protocol::TProtocol* iprot) {
+
+ ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
+ uint32_t xfer = 0;
+ std::string fname;
+ ::apache::thrift::protocol::TType ftype;
+ int16_t fid;
+
+ xfer += iprot->readStructBegin(fname);
+
+ using ::apache::thrift::protocol::TProtocolException;
+
+
+ while (true)
+ {
+ xfer += iprot->readFieldBegin(fname, ftype, fid);
+ if (ftype == ::apache::thrift::protocol::T_STOP) {
+ break;
+ }
+ switch (fid)
+ {
+ case 1:
+ if (ftype == ::apache::thrift::protocol::T_I32) {
+ xfer += iprot->readI32(this->ipv4);
+ this->__isset.ipv4 = true;
+ } else {
+ xfer += iprot->skip(ftype);
+ }
+ break;
+ case 2:
+ if (ftype == ::apache::thrift::protocol::T_I16) {
+ xfer += iprot->readI16(this->port);
+ this->__isset.port = true;
+ } else {
+ xfer += iprot->skip(ftype);
+ }
+ break;
+ case 3:
+ if (ftype == ::apache::thrift::protocol::T_STRING) {
+ xfer += iprot->readString(this->service_name);
+ this->__isset.service_name = true;
+ } else {
+ xfer += iprot->skip(ftype);
+ }
+ break;
+ case 4:
+ if (ftype == ::apache::thrift::protocol::T_STRING) {
+ xfer += iprot->readBinary(this->ipv6);
+ this->__isset.ipv6 = true;
+ } else {
+ xfer += iprot->skip(ftype);
+ }
+ break;
+ default:
+ xfer += iprot->skip(ftype);
+ break;
+ }
+ xfer += iprot->readFieldEnd();
+ }
+
+ xfer += iprot->readStructEnd();
+
+ return xfer;
+}
+
+uint32_t Endpoint::write(::apache::thrift::protocol::TProtocol* oprot) const {
+ uint32_t xfer = 0;
+ ::apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
+ xfer += oprot->writeStructBegin("Endpoint");
+
+ xfer += oprot->writeFieldBegin("ipv4", ::apache::thrift::protocol::T_I32, 1);
+ xfer += oprot->writeI32(this->ipv4);
+ xfer += oprot->writeFieldEnd();
+
+ xfer += oprot->writeFieldBegin("port", ::apache::thrift::protocol::T_I16, 2);
+ xfer += oprot->writeI16(this->port);
+ xfer += oprot->writeFieldEnd();
+
+ xfer += oprot->writeFieldBegin("service_name", ::apache::thrift::protocol::T_STRING, 3);
+ xfer += oprot->writeString(this->service_name);
+ xfer += oprot->writeFieldEnd();
+
+ if (this->__isset.ipv6) {
+ xfer += oprot->writeFieldBegin("ipv6", ::apache::thrift::protocol::T_STRING, 4);
+ xfer += oprot->writeBinary(this->ipv6);
+ xfer += oprot->writeFieldEnd();
+ }
+ xfer += oprot->writeFieldStop();
+ xfer += oprot->writeStructEnd();
+ return xfer;
+}
+
+void swap(Endpoint &a, Endpoint &b) {
+ using ::std::swap;
+ swap(a.ipv4, b.ipv4);
+ swap(a.port, b.port);
+ swap(a.service_name, b.service_name);
+ swap(a.ipv6, b.ipv6);
+ swap(a.__isset, b.__isset);
+}
+
+Endpoint::Endpoint(const Endpoint& other0) {
+ ipv4 = other0.ipv4;
+ port = other0.port;
+ service_name = other0.service_name;
+ ipv6 = other0.ipv6;
+ __isset = other0.__isset;
+}
+Endpoint& Endpoint::operator=(const Endpoint& other1) {
+ ipv4 = other1.ipv4;
+ port = other1.port;
+ service_name = other1.service_name;
+ ipv6 = other1.ipv6;
+ __isset = other1.__isset;
+ return *this;
+}
+void Endpoint::printTo(std::ostream& out) const {
+ using ::apache::thrift::to_string;
+ out << "Endpoint(";
+ out << "ipv4=" << to_string(ipv4);
+ out << ", " << "port=" << to_string(port);
+ out << ", " << "service_name=" << to_string(service_name);
+ out << ", " << "ipv6="; (__isset.ipv6 ? (out << to_string(ipv6)) : (out << "<null>"));
+ out << ")";
+}
+
+
+Annotation::~Annotation() throw() {
+}
+
+
+void Annotation::__set_timestamp(const int64_t val) {
+ this->timestamp = val;
+}
+
+void Annotation::__set_value(const std::string& val) {
+ this->value = val;
+}
+
+void Annotation::__set_host(const Endpoint& val) {
+ this->host = val;
+__isset.host = true;
+}
+std::ostream& operator<<(std::ostream& out, const Annotation& obj)
+{
+ obj.printTo(out);
+ return out;
+}
+
+
+uint32_t Annotation::read(::apache::thrift::protocol::TProtocol* iprot) {
+
+ ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
+ uint32_t xfer = 0;
+ std::string fname;
+ ::apache::thrift::protocol::TType ftype;
+ int16_t fid;
+
+ xfer += iprot->readStructBegin(fname);
+
+ using ::apache::thrift::protocol::TProtocolException;
+
+
+ while (true)
+ {
+ xfer += iprot->readFieldBegin(fname, ftype, fid);
+ if (ftype == ::apache::thrift::protocol::T_STOP) {
+ break;
+ }
+ switch (fid)
+ {
+ case 1:
+ if (ftype == ::apache::thrift::protocol::T_I64) {
+ xfer += iprot->readI64(this->timestamp);
+ this->__isset.timestamp = true;
+ } else {
+ xfer += iprot->skip(ftype);
+ }
+ break;
+ case 2:
+ if (ftype == ::apache::thrift::protocol::T_STRING) {
+ xfer += iprot->readString(this->value);
+ this->__isset.value = true;
+ } else {
+ xfer += iprot->skip(ftype);
+ }
+ break;
+ case 3:
+ if (ftype == ::apache::thrift::protocol::T_STRUCT) {
+ xfer += this->host.read(iprot);
+ this->__isset.host = true;
+ } else {
+ xfer += iprot->skip(ftype);
+ }
+ break;
+ default:
+ xfer += iprot->skip(ftype);
+ break;
+ }
+ xfer += iprot->readFieldEnd();
+ }
+
+ xfer += iprot->readStructEnd();
+
+ return xfer;
+}
+
+uint32_t Annotation::write(::apache::thrift::protocol::TProtocol* oprot) const {
+ uint32_t xfer = 0;
+ ::apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
+ xfer += oprot->writeStructBegin("Annotation");
+
+ xfer += oprot->writeFieldBegin("timestamp", ::apache::thrift::protocol::T_I64, 1);
+ xfer += oprot->writeI64(this->timestamp);
+ xfer += oprot->writeFieldEnd();
+
+ xfer += oprot->writeFieldBegin("value", ::apache::thrift::protocol::T_STRING, 2);
+ xfer += oprot->writeString(this->value);
+ xfer += oprot->writeFieldEnd();
+
+ if (this->__isset.host) {
+ xfer += oprot->writeFieldBegin("host", ::apache::thrift::protocol::T_STRUCT, 3);
+ xfer += this->host.write(oprot);
+ xfer += oprot->writeFieldEnd();
+ }
+ xfer += oprot->writeFieldStop();
+ xfer += oprot->writeStructEnd();
+ return xfer;
+}
+
+void swap(Annotation &a, Annotation &b) {
+ using ::std::swap;
+ swap(a.timestamp, b.timestamp);
+ swap(a.value, b.value);
+ swap(a.host, b.host);
+ swap(a.__isset, b.__isset);
+}
+
+Annotation::Annotation(const Annotation& other2) {
+ timestamp = other2.timestamp;
+ value = other2.value;
+ host = other2.host;
+ __isset = other2.__isset;
+}
+Annotation& Annotation::operator=(const Annotation& other3) {
+ timestamp = other3.timestamp;
+ value = other3.value;
+ host = other3.host;
+ __isset = other3.__isset;
+ return *this;
+}
+void Annotation::printTo(std::ostream& out) const {
+ using ::apache::thrift::to_string;
+ out << "Annotation(";
+ out << "timestamp=" << to_string(timestamp);
+ out << ", " << "value=" << to_string(value);
+ out << ", " << "host="; (__isset.host ? (out << to_string(host)) : (out << "<null>"));
+ out << ")";
+}
+
+
+BinaryAnnotation::~BinaryAnnotation() throw() {
+}
+
+
+void BinaryAnnotation::__set_key(const std::string& val) {
+ this->key = val;
+}
+
+void BinaryAnnotation::__set_value(const std::string& val) {
+ this->value = val;
+}
+
+void BinaryAnnotation::__set_annotation_type(const AnnotationType::type val) {
+ this->annotation_type = val;
+}
+
+void BinaryAnnotation::__set_host(const Endpoint& val) {
+ this->host = val;
+__isset.host = true;
+}
+std::ostream& operator<<(std::ostream& out, const BinaryAnnotation& obj)
+{
+ obj.printTo(out);
+ return out;
+}
+
+
+uint32_t BinaryAnnotation::read(::apache::thrift::protocol::TProtocol* iprot) {
+
+ ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
+ uint32_t xfer = 0;
+ std::string fname;
+ ::apache::thrift::protocol::TType ftype;
+ int16_t fid;
+
+ xfer += iprot->readStructBegin(fname);
+
+ using ::apache::thrift::protocol::TProtocolException;
+
+
+ while (true)
+ {
+ xfer += iprot->readFieldBegin(fname, ftype, fid);
+ if (ftype == ::apache::thrift::protocol::T_STOP) {
+ break;
+ }
+ switch (fid)
+ {
+ case 1:
+ if (ftype == ::apache::thrift::protocol::T_STRING) {
+ xfer += iprot->readString(this->key);
+ this->__isset.key = true;
+ } else {
+ xfer += iprot->skip(ftype);
+ }
+ break;
+ case 2:
+ if (ftype == ::apache::thrift::protocol::T_STRING) {
+ xfer += iprot->readBinary(this->value);
+ this->__isset.value = true;
+ } else {
+ xfer += iprot->skip(ftype);
+ }
+ break;
+ case 3:
+ if (ftype == ::apache::thrift::protocol::T_I32) {
+ int32_t ecast4;
+ xfer += iprot->readI32(ecast4);
+ this->annotation_type = (AnnotationType::type)ecast4;
+ this->__isset.annotation_type = true;
+ } else {
+ xfer += iprot->skip(ftype);
+ }
+ break;
+ case 4:
+ if (ftype == ::apache::thrift::protocol::T_STRUCT) {
+ xfer += this->host.read(iprot);
+ this->__isset.host = true;
+ } else {
+ xfer += iprot->skip(ftype);
+ }
+ break;
+ default:
+ xfer += iprot->skip(ftype);
+ break;
+ }
+ xfer += iprot->readFieldEnd();
+ }
+
+ xfer += iprot->readStructEnd();
+
+ return xfer;
+}
+
+uint32_t BinaryAnnotation::write(::apache::thrift::protocol::TProtocol* oprot) const {
+ uint32_t xfer = 0;
+ ::apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
+ xfer += oprot->writeStructBegin("BinaryAnnotation");
+
+ xfer += oprot->writeFieldBegin("key", ::apache::thrift::protocol::T_STRING, 1);
+ xfer += oprot->writeString(this->key);
+ xfer += oprot->writeFieldEnd();
+
+ xfer += oprot->writeFieldBegin("value", ::apache::thrift::protocol::T_STRING, 2);
+ xfer += oprot->writeBinary(this->value);
+ xfer += oprot->writeFieldEnd();
+
+ xfer += oprot->writeFieldBegin("annotation_type", ::apache::thrift::protocol::T_I32, 3);
+ xfer += oprot->writeI32((int32_t)this->annotation_type);
+ xfer += oprot->writeFieldEnd();
+
+ if (this->__isset.host) {
+ xfer += oprot->writeFieldBegin("host", ::apache::thrift::protocol::T_STRUCT, 4);
+ xfer += this->host.write(oprot);
+ xfer += oprot->writeFieldEnd();
+ }
+ xfer += oprot->writeFieldStop();
+ xfer += oprot->writeStructEnd();
+ return xfer;
+}
+
+void swap(BinaryAnnotation &a, BinaryAnnotation &b) {
+ using ::std::swap;
+ swap(a.key, b.key);
+ swap(a.value, b.value);
+ swap(a.annotation_type, b.annotation_type);
+ swap(a.host, b.host);
+ swap(a.__isset, b.__isset);
+}
+
+BinaryAnnotation::BinaryAnnotation(const BinaryAnnotation& other5) {
+ key = other5.key;
+ value = other5.value;
+ annotation_type = other5.annotation_type;
+ host = other5.host;
+ __isset = other5.__isset;
+}
+BinaryAnnotation& BinaryAnnotation::operator=(const BinaryAnnotation& other6) {
+ key = other6.key;
+ value = other6.value;
+ annotation_type = other6.annotation_type;
+ host = other6.host;
+ __isset = other6.__isset;
+ return *this;
+}
+void BinaryAnnotation::printTo(std::ostream& out) const {
+ using ::apache::thrift::to_string;
+ out << "BinaryAnnotation(";
+ out << "key=" << to_string(key);
+ out << ", " << "value=" << to_string(value);
+ out << ", " << "annotation_type=" << to_string(annotation_type);
+ out << ", " << "host="; (__isset.host ? (out << to_string(host)) : (out << "<null>"));
+ out << ")";
+}
+
+
+Span::~Span() throw() {
+}
+
+
+void Span::__set_trace_id(const int64_t val) {
+ this->trace_id = val;
+}
+
+void Span::__set_name(const std::string& val) {
+ this->name = val;
+}
+
+void Span::__set_id(const int64_t val) {
+ this->id = val;
+}
+
+void Span::__set_parent_id(const int64_t val) {
+ this->parent_id = val;
+__isset.parent_id = true;
+}
+
+void Span::__set_annotations(const std::vector<Annotation> & val) {
+ this->annotations = val;
+}
+
+void Span::__set_binary_annotations(const std::vector<BinaryAnnotation> & val) {
+ this->binary_annotations = val;
+}
+
+void Span::__set_debug(const bool val) {
+ this->debug = val;
+__isset.debug = true;
+}
+
+void Span::__set_timestamp(const int64_t val) {
+ this->timestamp = val;
+__isset.timestamp = true;
+}
+
+void Span::__set_duration(const int64_t val) {
+ this->duration = val;
+__isset.duration = true;
+}
+
+void Span::__set_trace_id_high(const int64_t val) {
+ this->trace_id_high = val;
+__isset.trace_id_high = true;
+}
+std::ostream& operator<<(std::ostream& out, const Span& obj)
+{
+ obj.printTo(out);
+ return out;
+}
+
+
+uint32_t Span::read(::apache::thrift::protocol::TProtocol* iprot) {
+
+ ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
+ uint32_t xfer = 0;
+ std::string fname;
+ ::apache::thrift::protocol::TType ftype;
+ int16_t fid;
+
+ xfer += iprot->readStructBegin(fname);
+
+ using ::apache::thrift::protocol::TProtocolException;
+
+
+ while (true)
+ {
+ xfer += iprot->readFieldBegin(fname, ftype, fid);
+ if (ftype == ::apache::thrift::protocol::T_STOP) {
+ break;
+ }
+ switch (fid)
+ {
+ case 1:
+ if (ftype == ::apache::thrift::protocol::T_I64) {
+ xfer += iprot->readI64(this->trace_id);
+ this->__isset.trace_id = true;
+ } else {
+ xfer += iprot->skip(ftype);
+ }
+ break;
+ case 3:
+ if (ftype == ::apache::thrift::protocol::T_STRING) {
+ xfer += iprot->readString(this->name);
+ this->__isset.name = true;
+ } else {
+ xfer += iprot->skip(ftype);
+ }
+ break;
+ case 4:
+ if (ftype == ::apache::thrift::protocol::T_I64) {
+ xfer += iprot->readI64(this->id);
+ this->__isset.id = true;
+ } else {
+ xfer += iprot->skip(ftype);
+ }
+ break;
+ case 5:
+ if (ftype == ::apache::thrift::protocol::T_I64) {
+ xfer += iprot->readI64(this->parent_id);
+ this->__isset.parent_id = true;
+ } else {
+ xfer += iprot->skip(ftype);
+ }
+ break;
+ case 6:
+ if (ftype == ::apache::thrift::protocol::T_LIST) {
+ {
+ this->annotations.clear();
+ uint32_t _size7;
+ ::apache::thrift::protocol::TType _etype10;
+ xfer += iprot->readListBegin(_etype10, _size7);
+ this->annotations.resize(_size7);
+ uint32_t _i11;
+ for (_i11 = 0; _i11 < _size7; ++_i11)
+ {
+ xfer += this->annotations[_i11].read(iprot);
+ }
+ xfer += iprot->readListEnd();
+ }
+ this->__isset.annotations = true;
+ } else {
+ xfer += iprot->skip(ftype);
+ }
+ break;
+ case 8:
+ if (ftype == ::apache::thrift::protocol::T_LIST) {
+ {
+ this->binary_annotations.clear();
+ uint32_t _size12;
+ ::apache::thrift::protocol::TType _etype15;
+ xfer += iprot->readListBegin(_etype15, _size12);
+ this->binary_annotations.resize(_size12);
+ uint32_t _i16;
+ for (_i16 = 0; _i16 < _size12; ++_i16)
+ {
+ xfer += this->binary_annotations[_i16].read(iprot);
+ }
+ xfer += iprot->readListEnd();
+ }
+ this->__isset.binary_annotations = true;
+ } else {
+ xfer += iprot->skip(ftype);
+ }
+ break;
+ case 9:
+ if (ftype == ::apache::thrift::protocol::T_BOOL) {
+ xfer += iprot->readBool(this->debug);
+ this->__isset.debug = true;
+ } else {
+ xfer += iprot->skip(ftype);
+ }
+ break;
+ case 10:
+ if (ftype == ::apache::thrift::protocol::T_I64) {
+ xfer += iprot->readI64(this->timestamp);
+ this->__isset.timestamp = true;
+ } else {
+ xfer += iprot->skip(ftype);
+ }
+ break;
+ case 11:
+ if (ftype == ::apache::thrift::protocol::T_I64) {
+ xfer += iprot->readI64(this->duration);
+ this->__isset.duration = true;
+ } else {
+ xfer += iprot->skip(ftype);
+ }
+ break;
+ case 12:
+ if (ftype == ::apache::thrift::protocol::T_I64) {
+ xfer += iprot->readI64(this->trace_id_high);
+ this->__isset.trace_id_high = true;
+ } else {
+ xfer += iprot->skip(ftype);
+ }
+ break;
+ default:
+ xfer += iprot->skip(ftype);
+ break;
+ }
+ xfer += iprot->readFieldEnd();
+ }
+
+ xfer += iprot->readStructEnd();
+
+ return xfer;
+}
+
+uint32_t Span::write(::apache::thrift::protocol::TProtocol* oprot) const {
+ uint32_t xfer = 0;
+ ::apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
+ xfer += oprot->writeStructBegin("Span");
+
+ xfer += oprot->writeFieldBegin("trace_id", ::apache::thrift::protocol::T_I64, 1);
+ xfer += oprot->writeI64(this->trace_id);
+ xfer += oprot->writeFieldEnd();
+
+ xfer += oprot->writeFieldBegin("name", ::apache::thrift::protocol::T_STRING, 3);
+ xfer += oprot->writeString(this->name);
+ xfer += oprot->writeFieldEnd();
+
+ xfer += oprot->writeFieldBegin("id", ::apache::thrift::protocol::T_I64, 4);
+ xfer += oprot->writeI64(this->id);
+ xfer += oprot->writeFieldEnd();
+
+ if (this->__isset.parent_id) {
+ xfer += oprot->writeFieldBegin("parent_id", ::apache::thrift::protocol::T_I64, 5);
+ xfer += oprot->writeI64(this->parent_id);
+ xfer += oprot->writeFieldEnd();
+ }
+ xfer += oprot->writeFieldBegin("annotations", ::apache::thrift::protocol::T_LIST, 6);
+ {
+ xfer += oprot->writeListBegin(::apache::thrift::protocol::T_STRUCT, static_cast<uint32_t>(this->annotations.size()));
+ std::vector<Annotation> ::const_iterator _iter17;
+ for (_iter17 = this->annotations.begin(); _iter17 != this->annotations.end(); ++_iter17)
+ {
+ xfer += (*_iter17).write(oprot);
+ }
+ xfer += oprot->writeListEnd();
+ }
+ xfer += oprot->writeFieldEnd();
+
+ xfer += oprot->writeFieldBegin("binary_annotations", ::apache::thrift::protocol::T_LIST, 8);
+ {
+ xfer += oprot->writeListBegin(::apache::thrift::protocol::T_STRUCT, static_cast<uint32_t>(this->binary_annotations.size()));
+ std::vector<BinaryAnnotation> ::const_iterator _iter18;
+ for (_iter18 = this->binary_annotations.begin(); _iter18 != this->binary_annotations.end(); ++_iter18)
+ {
+ xfer += (*_iter18).write(oprot);
+ }
+ xfer += oprot->writeListEnd();
+ }
+ xfer += oprot->writeFieldEnd();
+
+ if (this->__isset.debug) {
+ xfer += oprot->writeFieldBegin("debug", ::apache::thrift::protocol::T_BOOL, 9);
+ xfer += oprot->writeBool(this->debug);
+ xfer += oprot->writeFieldEnd();
+ }
+ if (this->__isset.timestamp) {
+ xfer += oprot->writeFieldBegin("timestamp", ::apache::thrift::protocol::T_I64, 10);
+ xfer += oprot->writeI64(this->timestamp);
+ xfer += oprot->writeFieldEnd();
+ }
+ if (this->__isset.duration) {
+ xfer += oprot->writeFieldBegin("duration", ::apache::thrift::protocol::T_I64, 11);
+ xfer += oprot->writeI64(this->duration);
+ xfer += oprot->writeFieldEnd();
+ }
+ if (this->__isset.trace_id_high) {
+ xfer += oprot->writeFieldBegin("trace_id_high", ::apache::thrift::protocol::T_I64, 12);
+ xfer += oprot->writeI64(this->trace_id_high);
+ xfer += oprot->writeFieldEnd();
+ }
+ xfer += oprot->writeFieldStop();
+ xfer += oprot->writeStructEnd();
+ return xfer;
+}
+
+void swap(Span &a, Span &b) {
+ using ::std::swap;
+ swap(a.trace_id, b.trace_id);
+ swap(a.name, b.name);
+ swap(a.id, b.id);
+ swap(a.parent_id, b.parent_id);
+ swap(a.annotations, b.annotations);
+ swap(a.binary_annotations, b.binary_annotations);
+ swap(a.debug, b.debug);
+ swap(a.timestamp, b.timestamp);
+ swap(a.duration, b.duration);
+ swap(a.trace_id_high, b.trace_id_high);
+ swap(a.__isset, b.__isset);
+}
+
+Span::Span(const Span& other19) {
+ trace_id = other19.trace_id;
+ name = other19.name;
+ id = other19.id;
+ parent_id = other19.parent_id;
+ annotations = other19.annotations;
+ binary_annotations = other19.binary_annotations;
+ debug = other19.debug;
+ timestamp = other19.timestamp;
+ duration = other19.duration;
+ trace_id_high = other19.trace_id_high;
+ __isset = other19.__isset;
+}
+Span& Span::operator=(const Span& other20) {
+ trace_id = other20.trace_id;
+ name = other20.name;
+ id = other20.id;
+ parent_id = other20.parent_id;
+ annotations = other20.annotations;
+ binary_annotations = other20.binary_annotations;
+ debug = other20.debug;
+ timestamp = other20.timestamp;
+ duration = other20.duration;
+ trace_id_high = other20.trace_id_high;
+ __isset = other20.__isset;
+ return *this;
+}
+void Span::printTo(std::ostream& out) const {
+ using ::apache::thrift::to_string;
+ out << "Span(";
+ out << "trace_id=" << to_string(trace_id);
+ out << ", " << "name=" << to_string(name);
+ out << ", " << "id=" << to_string(id);
+ out << ", " << "parent_id="; (__isset.parent_id ? (out << to_string(parent_id)) : (out << "<null>"));
+ out << ", " << "annotations=" << to_string(annotations);
+ out << ", " << "binary_annotations=" << to_string(binary_annotations);
+ out << ", " << "debug="; (__isset.debug ? (out << to_string(debug)) : (out << "<null>"));
+ out << ", " << "timestamp="; (__isset.timestamp ? (out << to_string(timestamp)) : (out << "<null>"));
+ out << ", " << "duration="; (__isset.duration ? (out << to_string(duration)) : (out << "<null>"));
+ out << ", " << "trace_id_high="; (__isset.trace_id_high ? (out << to_string(trace_id_high)) : (out << "<null>"));
+ out << ")";
+}
+
+
+Response::~Response() throw() {
+}
+
+
+void Response::__set_ok(const bool val) {
+ this->ok = val;
+}
+std::ostream& operator<<(std::ostream& out, const Response& obj)
+{
+ obj.printTo(out);
+ return out;
+}
+
+
+uint32_t Response::read(::apache::thrift::protocol::TProtocol* iprot) {
+
+ ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
+ uint32_t xfer = 0;
+ std::string fname;
+ ::apache::thrift::protocol::TType ftype;
+ int16_t fid;
+
+ xfer += iprot->readStructBegin(fname);
+
+ using ::apache::thrift::protocol::TProtocolException;
+
+ bool isset_ok = false;
+
+ while (true)
+ {
+ xfer += iprot->readFieldBegin(fname, ftype, fid);
+ if (ftype == ::apache::thrift::protocol::T_STOP) {
+ break;
+ }
+ switch (fid)
+ {
+ case 1:
+ if (ftype == ::apache::thrift::protocol::T_BOOL) {
+ xfer += iprot->readBool(this->ok);
+ isset_ok = true;
+ } else {
+ xfer += iprot->skip(ftype);
+ }
+ break;
+ default:
+ xfer += iprot->skip(ftype);
+ break;
+ }
+ xfer += iprot->readFieldEnd();
+ }
+
+ xfer += iprot->readStructEnd();
+
+ if (!isset_ok)
+ throw TProtocolException(TProtocolException::INVALID_DATA);
+ return xfer;
+}
+
+uint32_t Response::write(::apache::thrift::protocol::TProtocol* oprot) const {
+ uint32_t xfer = 0;
+ ::apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
+ xfer += oprot->writeStructBegin("Response");
+
+ xfer += oprot->writeFieldBegin("ok", ::apache::thrift::protocol::T_BOOL, 1);
+ xfer += oprot->writeBool(this->ok);
+ xfer += oprot->writeFieldEnd();
+
+ xfer += oprot->writeFieldStop();
+ xfer += oprot->writeStructEnd();
+ return xfer;
+}
+
+void swap(Response &a, Response &b) {
+ using ::std::swap;
+ swap(a.ok, b.ok);
+}
+
+Response::Response(const Response& other21) {
+ ok = other21.ok;
+}
+Response& Response::operator=(const Response& other22) {
+ ok = other22.ok;
+ return *this;
+}
+void Response::printTo(std::ostream& out) const {
+ using ::apache::thrift::to_string;
+ out << "Response(";
+ out << "ok=" << to_string(ok);
+ out << ")";
+}
+
+}}} // namespace
diff --git a/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/thrift-gen/zipkincore_types.h b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/thrift-gen/zipkincore_types.h
new file mode 100644
index 000000000..25afde91d
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/thrift-gen/zipkincore_types.h
@@ -0,0 +1,373 @@
+/**
+ * Autogenerated by Thrift Compiler (0.11.0)
+ *
+ * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
+ * @generated
+ */
+#ifndef zipkincore_TYPES_H
+#define zipkincore_TYPES_H
+
+#include <iosfwd>
+
+#include <thrift/Thrift.h>
+#include <thrift/TApplicationException.h>
+#include <thrift/TBase.h>
+#include <thrift/protocol/TProtocol.h>
+#include <thrift/transport/TTransport.h>
+
+
+
+
+namespace twitter { namespace zipkin { namespace thrift {
+
+struct AnnotationType {
+ enum type {
+ BOOL = 0,
+ BYTES = 1,
+ I16 = 2,
+ I32 = 3,
+ I64 = 4,
+ DOUBLE = 5,
+ STRING = 6
+ };
+};
+
+extern const std::map<int, const char*> _AnnotationType_VALUES_TO_NAMES;
+
+std::ostream& operator<<(std::ostream& out, const AnnotationType::type& val);
+
+class Endpoint;
+
+class Annotation;
+
+class BinaryAnnotation;
+
+class Span;
+
+class Response;
+
+typedef struct _Endpoint__isset {
+ _Endpoint__isset() : ipv4(false), port(false), service_name(false), ipv6(false) {}
+ bool ipv4 :1;
+ bool port :1;
+ bool service_name :1;
+ bool ipv6 :1;
+} _Endpoint__isset;
+
+class Endpoint : public virtual ::apache::thrift::TBase {
+ public:
+
+ Endpoint(const Endpoint&);
+ Endpoint& operator=(const Endpoint&);
+ Endpoint() : ipv4(0), port(0), service_name(), ipv6() {
+ }
+
+ virtual ~Endpoint() throw();
+ int32_t ipv4;
+ int16_t port;
+ std::string service_name;
+ std::string ipv6;
+
+ _Endpoint__isset __isset;
+
+ void __set_ipv4(const int32_t val);
+
+ void __set_port(const int16_t val);
+
+ void __set_service_name(const std::string& val);
+
+ void __set_ipv6(const std::string& val);
+
+ bool operator == (const Endpoint & rhs) const
+ {
+ if (!(ipv4 == rhs.ipv4))
+ return false;
+ if (!(port == rhs.port))
+ return false;
+ if (!(service_name == rhs.service_name))
+ return false;
+ if (__isset.ipv6 != rhs.__isset.ipv6)
+ return false;
+ else if (__isset.ipv6 && !(ipv6 == rhs.ipv6))
+ return false;
+ return true;
+ }
+ bool operator != (const Endpoint &rhs) const {
+ return !(*this == rhs);
+ }
+
+ bool operator < (const Endpoint & ) const;
+
+ uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
+ uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;
+
+ virtual void printTo(std::ostream& out) const;
+};
+
+void swap(Endpoint &a, Endpoint &b);
+
+std::ostream& operator<<(std::ostream& out, const Endpoint& obj);
+
+typedef struct _Annotation__isset {
+ _Annotation__isset() : timestamp(false), value(false), host(false) {}
+ bool timestamp :1;
+ bool value :1;
+ bool host :1;
+} _Annotation__isset;
+
+class Annotation : public virtual ::apache::thrift::TBase {
+ public:
+
+ Annotation(const Annotation&);
+ Annotation& operator=(const Annotation&);
+ Annotation() : timestamp(0), value() {
+ }
+
+ virtual ~Annotation() throw();
+ int64_t timestamp;
+ std::string value;
+ Endpoint host;
+
+ _Annotation__isset __isset;
+
+ void __set_timestamp(const int64_t val);
+
+ void __set_value(const std::string& val);
+
+ void __set_host(const Endpoint& val);
+
+ bool operator == (const Annotation & rhs) const
+ {
+ if (!(timestamp == rhs.timestamp))
+ return false;
+ if (!(value == rhs.value))
+ return false;
+ if (__isset.host != rhs.__isset.host)
+ return false;
+ else if (__isset.host && !(host == rhs.host))
+ return false;
+ return true;
+ }
+ bool operator != (const Annotation &rhs) const {
+ return !(*this == rhs);
+ }
+
+ bool operator < (const Annotation & ) const;
+
+ uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
+ uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;
+
+ virtual void printTo(std::ostream& out) const;
+};
+
+void swap(Annotation &a, Annotation &b);
+
+std::ostream& operator<<(std::ostream& out, const Annotation& obj);
+
+typedef struct _BinaryAnnotation__isset {
+ _BinaryAnnotation__isset() : key(false), value(false), annotation_type(false), host(false) {}
+ bool key :1;
+ bool value :1;
+ bool annotation_type :1;
+ bool host :1;
+} _BinaryAnnotation__isset;
+
+class BinaryAnnotation : public virtual ::apache::thrift::TBase {
+ public:
+
+ BinaryAnnotation(const BinaryAnnotation&);
+ BinaryAnnotation& operator=(const BinaryAnnotation&);
+ BinaryAnnotation() : key(), value(), annotation_type((AnnotationType::type)0) {
+ }
+
+ virtual ~BinaryAnnotation() throw();
+ std::string key;
+ std::string value;
+ AnnotationType::type annotation_type;
+ Endpoint host;
+
+ _BinaryAnnotation__isset __isset;
+
+ void __set_key(const std::string& val);
+
+ void __set_value(const std::string& val);
+
+ void __set_annotation_type(const AnnotationType::type val);
+
+ void __set_host(const Endpoint& val);
+
+ bool operator == (const BinaryAnnotation & rhs) const
+ {
+ if (!(key == rhs.key))
+ return false;
+ if (!(value == rhs.value))
+ return false;
+ if (!(annotation_type == rhs.annotation_type))
+ return false;
+ if (__isset.host != rhs.__isset.host)
+ return false;
+ else if (__isset.host && !(host == rhs.host))
+ return false;
+ return true;
+ }
+ bool operator != (const BinaryAnnotation &rhs) const {
+ return !(*this == rhs);
+ }
+
+ bool operator < (const BinaryAnnotation & ) const;
+
+ uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
+ uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;
+
+ virtual void printTo(std::ostream& out) const;
+};
+
+void swap(BinaryAnnotation &a, BinaryAnnotation &b);
+
+std::ostream& operator<<(std::ostream& out, const BinaryAnnotation& obj);
+
+typedef struct _Span__isset {
+ _Span__isset() : trace_id(false), name(false), id(false), parent_id(false), annotations(false), binary_annotations(false), debug(true), timestamp(false), duration(false), trace_id_high(false) {}
+ bool trace_id :1;
+ bool name :1;
+ bool id :1;
+ bool parent_id :1;
+ bool annotations :1;
+ bool binary_annotations :1;
+ bool debug :1;
+ bool timestamp :1;
+ bool duration :1;
+ bool trace_id_high :1;
+} _Span__isset;
+
+class Span : public virtual ::apache::thrift::TBase {
+ public:
+
+ Span(const Span&);
+ Span& operator=(const Span&);
+ Span() : trace_id(0), name(), id(0), parent_id(0), debug(false), timestamp(0), duration(0), trace_id_high(0) {
+ }
+
+ virtual ~Span() throw();
+ int64_t trace_id;
+ std::string name;
+ int64_t id;
+ int64_t parent_id;
+ std::vector<Annotation> annotations;
+ std::vector<BinaryAnnotation> binary_annotations;
+ bool debug;
+ int64_t timestamp;
+ int64_t duration;
+ int64_t trace_id_high;
+
+ _Span__isset __isset;
+
+ void __set_trace_id(const int64_t val);
+
+ void __set_name(const std::string& val);
+
+ void __set_id(const int64_t val);
+
+ void __set_parent_id(const int64_t val);
+
+ void __set_annotations(const std::vector<Annotation> & val);
+
+ void __set_binary_annotations(const std::vector<BinaryAnnotation> & val);
+
+ void __set_debug(const bool val);
+
+ void __set_timestamp(const int64_t val);
+
+ void __set_duration(const int64_t val);
+
+ void __set_trace_id_high(const int64_t val);
+
+ bool operator == (const Span & rhs) const
+ {
+ if (!(trace_id == rhs.trace_id))
+ return false;
+ if (!(name == rhs.name))
+ return false;
+ if (!(id == rhs.id))
+ return false;
+ if (__isset.parent_id != rhs.__isset.parent_id)
+ return false;
+ else if (__isset.parent_id && !(parent_id == rhs.parent_id))
+ return false;
+ if (!(annotations == rhs.annotations))
+ return false;
+ if (!(binary_annotations == rhs.binary_annotations))
+ return false;
+ if (__isset.debug != rhs.__isset.debug)
+ return false;
+ else if (__isset.debug && !(debug == rhs.debug))
+ return false;
+ if (__isset.timestamp != rhs.__isset.timestamp)
+ return false;
+ else if (__isset.timestamp && !(timestamp == rhs.timestamp))
+ return false;
+ if (__isset.duration != rhs.__isset.duration)
+ return false;
+ else if (__isset.duration && !(duration == rhs.duration))
+ return false;
+ if (__isset.trace_id_high != rhs.__isset.trace_id_high)
+ return false;
+ else if (__isset.trace_id_high && !(trace_id_high == rhs.trace_id_high))
+ return false;
+ return true;
+ }
+ bool operator != (const Span &rhs) const {
+ return !(*this == rhs);
+ }
+
+ bool operator < (const Span & ) const;
+
+ uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
+ uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;
+
+ virtual void printTo(std::ostream& out) const;
+};
+
+void swap(Span &a, Span &b);
+
+std::ostream& operator<<(std::ostream& out, const Span& obj);
+
+
+class Response : public virtual ::apache::thrift::TBase {
+ public:
+
+ Response(const Response&);
+ Response& operator=(const Response&);
+ Response() : ok(0) {
+ }
+
+ virtual ~Response() throw();
+ bool ok;
+
+ void __set_ok(const bool val);
+
+ bool operator == (const Response & rhs) const
+ {
+ if (!(ok == rhs.ok))
+ return false;
+ return true;
+ }
+ bool operator != (const Response &rhs) const {
+ return !(*this == rhs);
+ }
+
+ bool operator < (const Response & ) const;
+
+ uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
+ uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;
+
+ virtual void printTo(std::ostream& out) const;
+};
+
+void swap(Response &a, Response &b);
+
+std::ostream& operator<<(std::ostream& out, const Response& obj);
+
+}}} // namespace
+
+#endif
diff --git a/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/utils/EnvVariable.cpp b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/utils/EnvVariable.cpp
new file mode 100644
index 000000000..69459bc96
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/utils/EnvVariable.cpp
@@ -0,0 +1,17 @@
+/*
+ * Copyright (c) 2019 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.
+ */
+
+#include "jaegertracing/utils/EnvVariable.h"
diff --git a/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/utils/EnvVariable.h b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/utils/EnvVariable.h
new file mode 100644
index 000000000..dc34f8237
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/utils/EnvVariable.h
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2019 The Jaeger Authors.
+ *
+ * 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_UTILS_ENV_VARIABLE_H
+#define JAEGERTRACING_UTILS_ENV_VARIABLE_H
+
+#include <string>
+#include <sstream>
+#include <algorithm>
+
+namespace jaegertracing {
+namespace utils {
+namespace EnvVariable {
+
+inline std::string getStringVariable(const char* envVar)
+{
+ const auto rawVariable = std::getenv(envVar);
+ return std::string(rawVariable ? rawVariable : "");
+}
+
+inline std::pair<bool, int> getIntVariable(const char* envVar)
+{
+ const auto rawVariable = std::getenv(envVar);
+ const std::string variable(rawVariable ? rawVariable : "");
+ if (!variable.empty()) {
+ std::istringstream iss(variable);
+ int intVal = 0;
+ if (iss >> intVal) {
+ return std::make_pair(false, intVal);
+ }
+ }
+ return std::make_pair(false, 0);
+}
+
+inline std::pair<bool, bool> getBoolVariable(const char* envVar)
+{
+ const auto rawVariable = std::getenv(envVar);
+ std::string variable(rawVariable ? rawVariable : "");
+
+ if (!variable.empty()) {
+ std::transform(
+ variable.begin(), variable.end(), variable.begin(), ::tolower);
+ return std::make_pair(true, (variable == "true"));
+ }
+ return std::make_pair(false, false);
+}
+
+} // namespace EnvVariable
+} // namespace utils
+} // namespace jaegertracing
+
+#endif // JAEGERTRACING_UTILS_ENV_VARIABLE_H
diff --git a/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/utils/ErrorUtil.cpp b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/utils/ErrorUtil.cpp
new file mode 100644
index 000000000..f166cdf4e
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/utils/ErrorUtil.cpp
@@ -0,0 +1,17 @@
+/*
+ * 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.
+ */
+
+#include "jaegertracing/utils/ErrorUtil.h"
diff --git a/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/utils/ErrorUtil.h b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/utils/ErrorUtil.h
new file mode 100644
index 000000000..d61e1c065
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/utils/ErrorUtil.h
@@ -0,0 +1,55 @@
+/*
+ * 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_UTILS_ERRORUTIL_H
+#define JAEGERTRACING_UTILS_ERRORUTIL_H
+
+#include "jaegertracing/Logging.h"
+#include "jaegertracing/Sender.h"
+#include <sstream>
+#include <string>
+#include <system_error>
+
+namespace jaegertracing {
+namespace utils {
+namespace ErrorUtil {
+
+inline void logError(logging::Logger& logger, const std::string& message)
+{
+ try {
+ throw;
+ } catch (const Sender::Exception& ex) {
+ std::ostringstream oss;
+ oss << message << ": " << ex.what() << ", numFailed=" << ex.numFailed();
+ logger.error(oss.str());
+ } catch (const std::system_error& ex) {
+ std::ostringstream oss;
+ oss << message << ": " << ex.what() << ", code=" << ex.code().value();
+ logger.error(oss.str());
+ } catch (const std::exception& ex) {
+ std::ostringstream oss;
+ oss << message << ": " << ex.what();
+ logger.error(oss.str());
+ } catch (...) {
+ logger.error(message);
+ }
+}
+
+} // namespace ErrorUtil
+} // namespace utils
+} // namespace jaegertracing
+
+#endif // JAEGERTRACING_UTILS_ERRORUTIL_H
diff --git a/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/utils/ErrorUtilTest.cpp b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/utils/ErrorUtilTest.cpp
new file mode 100644
index 000000000..02a64c7ae
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/utils/ErrorUtilTest.cpp
@@ -0,0 +1,98 @@
+/*
+ * 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.
+ */
+
+#include "jaegertracing/Logging.h"
+#include "jaegertracing/Sender.h"
+#include "jaegertracing/utils/ErrorUtil.h"
+#include <algorithm>
+#include <gtest/gtest.h>
+#include <iosfwd>
+#include <iterator>
+#include <stdexcept>
+#include <string>
+#include <system_error>
+
+namespace jaegertracing {
+namespace utils {
+namespace {
+
+class TestLogger : public logging::Logger {
+ public:
+ void info(const std::string&) override {}
+
+ void error(const std::string& message) override { _message = message; }
+
+ const std::string& str() const { return _message; }
+
+ private:
+ std::string _message;
+};
+
+bool endsWith(const std::string& str, const std::string& suffix)
+{
+ if (str.size() < suffix.size()) {
+ return false;
+ }
+
+ return std::equal(
+ std::begin(suffix), std::end(suffix), std::end(str) - suffix.size());
+}
+
+} // anonymous namespace
+
+TEST(ErrorUtil, test)
+{
+ std::ostringstream oss;
+ TestLogger logger;
+ std::runtime_error stdEx("runtime error");
+ std::system_error sysEx(-1, std::generic_category());
+ Sender::Exception transportEx("test", 5);
+ for (auto i = 0; i < 4; ++i) {
+ try {
+ switch (i) {
+ case 0:
+ throw stdEx;
+ case 1:
+ throw sysEx;
+ case 2:
+ throw transportEx;
+ default:
+ ASSERT_EQ(3, i);
+ throw 5;
+ }
+ } catch (...) {
+ ErrorUtil::logError(logger, "test");
+ switch (i) {
+ case 0: {
+ ASSERT_EQ("test: runtime error", logger.str());
+ } break;
+ case 1: {
+ ASSERT_TRUE(endsWith(logger.str(), ", code=-1"));
+ } break;
+ case 2: {
+ ASSERT_EQ("test: test, numFailed=5", logger.str());
+ } break;
+ default: {
+ ASSERT_EQ(3, i);
+ ASSERT_EQ("test", logger.str());
+ } break;
+ }
+ }
+ }
+}
+
+} // namespace utils
+} // namespace jaegertracing
diff --git a/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/utils/HTTPTransporter.cpp b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/utils/HTTPTransporter.cpp
new file mode 100644
index 000000000..4a3a1c375
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/utils/HTTPTransporter.cpp
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2019, The Jaeger Authors
+ *
+ * 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.
+ */
+
+#include "jaegertracing/utils/HTTPTransporter.h"
+#include <thrift/protocol/TBinaryProtocol.h>
+#include <thrift/protocol/TProtocol.h>
+
+namespace jaegertracing {
+namespace utils {
+
+HTTPTransporter::HTTPTransporter(const net::URI& endpoint, int maxPacketSize)
+ : Transport(maxPacketSize == 0 ? kHttpPacketMaxLength : maxPacketSize)
+ , _buffer(new apache::thrift::transport::TMemoryBuffer(_maxPacketSize))
+ , _serverAddr(net::IPAddress::v4(endpoint._host, endpoint._port))
+ , _httpClient(new ::apache::thrift::transport::THttpClient(
+ _buffer, endpoint._host, endpoint._path + "?format=jaeger.thrift"))
+{
+ using TProtocolFactory = apache::thrift::protocol::TProtocolFactory;
+ using TBinaryProtocolFactory =
+ apache::thrift::protocol::TBinaryProtocolFactory;
+
+ _socket.open(AF_INET, SOCK_STREAM);
+ _socket.connect(_serverAddr);
+ std::shared_ptr<TProtocolFactory> protocolFactory(
+ new TBinaryProtocolFactory());
+ _protocol = protocolFactory->getProtocol(_httpClient);
+}
+
+} // namespace utils
+} // namespace jaegertracing
diff --git a/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/utils/HTTPTransporter.h b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/utils/HTTPTransporter.h
new file mode 100644
index 000000000..5340d2421
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/utils/HTTPTransporter.h
@@ -0,0 +1,100 @@
+/*
+ * Copyright (c) 2019, The Jaeger Authors
+ *
+ * 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_UTILS_UDPCLIENT5_H
+#define JAEGERTRACING_UTILS_UDPCLIENT5_H
+
+#include <iostream>
+#include <sstream>
+#include <stdexcept>
+#include <system_error>
+
+#include "jaegertracing/Compilers.h"
+
+#include "jaegertracing/utils/Transport.h"
+
+#include "jaegertracing/net/IPAddress.h"
+#include "jaegertracing/net/Socket.h"
+#include "jaegertracing/net/http/Response.h"
+
+#include <thrift/protocol/TBinaryProtocol.h>
+#include <thrift/transport/TBufferTransports.h>
+#include <thrift/transport/THttpClient.h>
+
+namespace jaegertracing {
+namespace utils {
+
+class HTTPTransporter : public Transport {
+ public:
+ HTTPTransporter(const net::URI& endpoint, int maxPacketSize);
+
+ ~HTTPTransporter() { close(); }
+
+ void emitBatch(const thrift::Batch& batch) override
+ {
+ // Resets the buffer to write a new batch
+ _buffer->resetBuffer();
+
+ // Does the serialisation to Thrift
+ auto oprot = _protocol.get();
+ batch.write(oprot);
+ oprot->writeMessageEnd();
+ oprot->getTransport()->writeEnd();
+ oprot->getTransport()->flush();
+
+ uint8_t* data = nullptr;
+ uint32_t size = 0;
+ _buffer->getBuffer(&data, &size);
+
+ // Sends the HTTP message
+ const auto numWritten = ::send(_socket.handle(), reinterpret_cast<char*>(data), sizeof(uint8_t) * size, 0);
+
+ if (static_cast<unsigned>(numWritten) != size) {
+ std::ostringstream oss;
+ oss << "Failed to write message, numWritten=" << numWritten << ", size=" << size;
+ throw std::system_error(errno, std::system_category(), oss.str());
+ }
+
+ // Waits for response. Check that the server acknowledged
+ // and returned a green status [200, 201, 202, 203, 204]
+ net::http::Response response = net::http::read(_socket);
+ if (response.statusCode() < 200 && response.statusCode() > 204) {
+ std::ostringstream oss;
+ oss << "Failed to write message, HTTP error " << response.statusCode() << response.reason();
+ throw std::system_error(errno, std::system_category(), oss.str());
+ }
+ }
+
+ std::unique_ptr<apache::thrift::protocol::TProtocolFactory>
+ protocolFactory() const override
+ {
+ return std::unique_ptr<apache::thrift::protocol::TProtocolFactory>(
+ new apache::thrift::protocol::TBinaryProtocolFactory());
+ }
+
+ private:
+ std::shared_ptr<apache::thrift::transport::TMemoryBuffer> _buffer;
+ net::IPAddress _serverAddr;
+ std::shared_ptr<::apache::thrift::transport::THttpClient> _httpClient;
+ std::shared_ptr<apache::thrift::protocol::TProtocol> _protocol;
+
+ static constexpr auto kHttpPacketMaxLength = 1024 * 1024; // 1MB
+};
+
+} // namespace utils
+} // namespace jaegertracing
+
+#endif // JAEGERTRACING_UTILS_UDPCLIENT_H
diff --git a/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/utils/HTTPTransporterTest.cpp b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/utils/HTTPTransporterTest.cpp
new file mode 100644
index 000000000..1bc5501b4
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/utils/HTTPTransporterTest.cpp
@@ -0,0 +1,113 @@
+/*
+ * 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.
+ */
+
+#include "jaegertracing/net/IPAddress.h"
+#include "jaegertracing/testutils/TracerUtil.h"
+#include <gtest/gtest.h>
+#include <iterator>
+#include <memory>
+#include <opentracing/string_view.h>
+#include <opentracing/tracer.h>
+#include <stdexcept>
+#include <string>
+#include <utility>
+
+#include "jaegertracing/net/Socket.h"
+#include "jaegertracing/net/http/Request.h"
+#include "jaegertracing/net/http/Response.h"
+#include <future>
+#include <thread>
+
+namespace jaegertracing {
+
+namespace utils {
+
+TEST(HTTPTransporter, testSpanReporting)
+{
+ net::IPAddress serverAddr;
+ std::promise<void> started;
+
+ std::string target;
+ net::http::Method method;
+ std::string contentType;
+ std::string acceptType;
+
+ std::thread serverThread(
+ [&serverAddr, &started, &target, &method, &contentType, &acceptType]() {
+ net::Socket socket;
+ socket.open(AF_INET, SOCK_STREAM);
+ socket.bind(net::IPAddress::v4("127.0.0.1", 0));
+ ::sockaddr_storage addrStorage;
+ ::socklen_t addrLen = sizeof(addrStorage);
+ const auto returnCode =
+ ::getsockname(socket.handle(),
+ reinterpret_cast<::sockaddr*>(&addrStorage),
+ &addrLen);
+ ASSERT_EQ(0, returnCode);
+ serverAddr = net::IPAddress(addrStorage, addrLen);
+
+ // Listening to the port
+ socket.listen();
+
+ // Unblocking the client
+ started.set_value();
+
+ // Waiting for the client to connect
+ auto clientSocket = socket.accept();
+
+ net::http::Request request = net::http::Request::read(clientSocket);
+
+ target = request.target();
+ method = request.method();
+
+ for (auto header : request.headers()) {
+ if (header.key() == "Content-Type") {
+ contentType = header.value();
+ }
+
+ if (header.key() == "Accept") {
+ acceptType = header.value();
+ }
+ }
+
+ std::string answer(
+ "HTTP/1.1 202 Accepted\r\nDate: Tue, 10 Sep 2019 09:03:26 "
+ "GMT\r\nContent-Length: 0\r\n\r\n");
+
+ ::send(clientSocket.handle(), answer.c_str(), answer.size(), 0);
+ });
+
+ started.get_future().wait();
+
+ std::ostringstream oss;
+ oss << "http://127.0.0.1:" << serverAddr.port() << "/api/traces";
+ std::shared_ptr<opentracing::Tracer> tracer =
+ ::jaegertracing::testutils::TracerUtil::buildTracer(oss.str());
+
+ {
+ auto span1 = tracer->StartSpan("tracedFunction");
+ }
+
+ serverThread.join();
+
+ ASSERT_EQ(std::string("/api/traces?format=jaeger.thrift"), target);
+ ASSERT_EQ(net::http::Method::POST, method);
+ ASSERT_EQ(std::string("application/x-thrift"), contentType);
+ ASSERT_EQ(std::string("application/x-thrift"), acceptType);
+}
+
+} // namespace utils
+} // namespace jaegertracing
diff --git a/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/utils/HexParsing.cpp b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/utils/HexParsing.cpp
new file mode 100644
index 000000000..234a64687
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/utils/HexParsing.cpp
@@ -0,0 +1,17 @@
+/*
+ * 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.
+ */
+
+#include "jaegertracing/utils/HexParsing.h"
diff --git a/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/utils/HexParsing.h b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/utils/HexParsing.h
new file mode 100644
index 000000000..b4753792d
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/utils/HexParsing.h
@@ -0,0 +1,88 @@
+/*
+ * 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_UTILS_HEXPARSING_H
+#define JAEGERTRACING_UTILS_HEXPARSING_H
+
+#include <cassert>
+#include <iomanip>
+#include <iostream>
+#include <cctype>
+
+namespace jaegertracing {
+namespace utils {
+namespace HexParsing {
+
+inline bool isHex(char ch)
+{
+ return (ch >= '0' && ch <= '9') || (ch >= 'A' && ch <= 'F') ||
+ (ch >= 'a' && ch <= 'f');
+}
+
+inline std::string readSegment(std::istream& in, size_t maxChars, char delim)
+{
+ std::string buffer;
+ auto ch = '\0';
+ for (auto i = static_cast<size_t>(0); i < maxChars && in.get(ch); ++i) {
+ if (!isHex(ch)) {
+ if (ch == delim) {
+ in.putback(ch);
+ break;
+ }
+ else {
+ return "";
+ }
+ }
+
+ buffer.push_back(ch);
+ }
+ return buffer;
+}
+
+template <typename ResultType>
+ResultType decodeHex(const std::string& str)
+{
+ auto first = std::begin(str);
+ auto last = std::end(str);
+ ResultType result = 0;
+ for (; first != last; ++first) {
+ const auto ch = *first;
+
+ // This condition is guaranteed by `readSegment`.
+ assert(isHex(ch));
+
+ auto hexDigit = 0;
+ if (std::isdigit(ch)) {
+ hexDigit = (ch - '0');
+ }
+ else if (std::isupper(ch)) {
+ hexDigit = (ch - 'A') + 10;
+ }
+ else {
+ hexDigit = (ch - 'a') + 10;
+ }
+
+ result = (result << 4) | hexDigit;
+ }
+
+ return result;
+}
+
+} // namespace HexParsing
+} // namespace utils
+} // namespace jaegertracing
+
+#endif // JAEGERTRACING_UTILS_HEXPARSING_H
diff --git a/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/utils/RateLimiter.cpp b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/utils/RateLimiter.cpp
new file mode 100644
index 000000000..7c1a27d66
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/utils/RateLimiter.cpp
@@ -0,0 +1,17 @@
+/*
+ * 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.
+ */
+
+#include "jaegertracing/utils/RateLimiter.h"
diff --git a/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/utils/RateLimiter.h b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/utils/RateLimiter.h
new file mode 100644
index 000000000..7001de0cc
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/utils/RateLimiter.h
@@ -0,0 +1,71 @@
+/*
+ * 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_UTILS_RATELIMITER_H
+#define JAEGERTRACING_UTILS_RATELIMITER_H
+
+#include <chrono>
+#include <mutex>
+
+namespace jaegertracing {
+namespace utils {
+
+template <typename ClockType = std::chrono::steady_clock>
+class RateLimiter {
+ public:
+ using Clock = ClockType;
+
+ RateLimiter(double creditsPerSecond, double maxBalance)
+ : _creditsPerSecond(creditsPerSecond)
+ , _maxBalance(maxBalance)
+ , _balance(_maxBalance)
+ , _lastTick(Clock::now())
+ {
+ }
+
+ bool checkCredit(double itemCost)
+ {
+ std::lock_guard<std::mutex> lock(_mutex);
+ const auto currentTime = Clock::now();
+ const auto elapsedTime =
+ std::chrono::duration<double>(currentTime - _lastTick);
+ _lastTick = currentTime;
+
+ _balance += elapsedTime.count() * _creditsPerSecond;
+ if (_balance > _maxBalance) {
+ _balance = _maxBalance;
+ }
+
+ if (_balance >= itemCost) {
+ _balance -= itemCost;
+ return true;
+ }
+
+ return false;
+ }
+
+ private:
+ double _creditsPerSecond;
+ double _maxBalance;
+ double _balance;
+ typename Clock::time_point _lastTick;
+ std::mutex _mutex;
+};
+
+} // namespace utils
+} // namespace jaegertracing
+
+#endif // JAEGERTRACING_UTILS_RATELIMITER_H
diff --git a/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/utils/RateLimiterTest.cpp b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/utils/RateLimiterTest.cpp
new file mode 100644
index 000000000..015b325f0
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/utils/RateLimiterTest.cpp
@@ -0,0 +1,80 @@
+/*
+ * 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.
+ */
+
+#include "jaegertracing/utils/RateLimiter.h"
+#include <chrono>
+#include <gtest/gtest.h>
+
+namespace jaegertracing {
+namespace utils {
+namespace {
+
+std::chrono::steady_clock::time_point currentTime;
+
+class MockClock {
+ public:
+ using rep = std::chrono::steady_clock::rep;
+ using period = std::chrono::steady_clock::period;
+ using duration = std::chrono::steady_clock::duration;
+ using time_point = std::chrono::steady_clock::time_point;
+
+ static const bool is_steady() { return false; }
+
+ static time_point now() { return currentTime; }
+};
+
+} // anonymous namespace
+
+TEST(RateLimiter, testRateLimiter)
+{
+ const auto timestamp = std::chrono::steady_clock::now();
+ currentTime = timestamp;
+ RateLimiter<MockClock> limiter(2, 2);
+
+ ASSERT_TRUE(limiter.checkCredit(1));
+ ASSERT_TRUE(limiter.checkCredit(1));
+ ASSERT_FALSE(limiter.checkCredit(1));
+
+ currentTime = timestamp + std::chrono::milliseconds(250);
+ ASSERT_FALSE(limiter.checkCredit(1));
+
+ currentTime = timestamp + std::chrono::milliseconds(750);
+ ASSERT_TRUE(limiter.checkCredit(1));
+ ASSERT_FALSE(limiter.checkCredit(1));
+
+ currentTime = timestamp + std::chrono::seconds(5);
+ ASSERT_TRUE(limiter.checkCredit(1));
+ ASSERT_TRUE(limiter.checkCredit(1));
+ ASSERT_FALSE(limiter.checkCredit(1));
+ ASSERT_FALSE(limiter.checkCredit(1));
+ ASSERT_FALSE(limiter.checkCredit(1));
+}
+
+TEST(RateLimiter, testMaxBalance)
+{
+ const auto timestamp = std::chrono::steady_clock::now();
+ currentTime = timestamp;
+ RateLimiter<MockClock> limiter(0.1, 1.0);
+
+ ASSERT_TRUE(limiter.checkCredit(1.0));
+
+ currentTime = timestamp + std::chrono::seconds(20);
+ ASSERT_TRUE(limiter.checkCredit(1.0));
+ ASSERT_FALSE(limiter.checkCredit(1.0));
+}
+
+} // namespace utils
+} // namespace jaegertracing
diff --git a/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/utils/Transport.h b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/utils/Transport.h
new file mode 100644
index 000000000..8f057068a
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/utils/Transport.h
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2019, The Jaeger Authors
+ *
+ * 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_UTILS_SENDER_H
+#define JAEGERTRACING_UTILS_SENDER_H
+
+#include "jaegertracing/net/Socket.h"
+#include "jaegertracing/thrift-gen/jaeger_types.h"
+
+namespace jaegertracing {
+namespace utils {
+
+class Transport {
+ public:
+ Transport(int maxPacketSize)
+ : _maxPacketSize(maxPacketSize)
+ {
+ }
+
+ virtual ~Transport() { close(); }
+
+ virtual void emitBatch(const thrift::Batch& batch) = 0;
+
+ int maxPacketSize() const { return _maxPacketSize; }
+
+ void close() { _socket.close(); }
+
+ virtual std::unique_ptr<apache::thrift::protocol::TProtocolFactory>
+ protocolFactory() const = 0;
+
+ protected:
+ int _maxPacketSize;
+ net::Socket _socket;
+};
+
+} // namespace utils
+} // namespace jaegertracing
+
+#endif // JAEGERTRACING_UTILS_SENDER_H
diff --git a/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/utils/UDPSenderTest.cpp b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/utils/UDPSenderTest.cpp
new file mode 100644
index 000000000..f59586b4c
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/utils/UDPSenderTest.cpp
@@ -0,0 +1,83 @@
+/*
+ * 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.
+ */
+
+#include "jaegertracing/net/IPAddress.h"
+#include "jaegertracing/net/Socket.h"
+#include "jaegertracing/thrift-gen/jaeger_types.h"
+#include "jaegertracing/thrift-gen/zipkincore_types.h"
+#include "jaegertracing/utils/UDPTransporter.h"
+#include <future>
+#include <gtest/gtest.h>
+#include <stdexcept>
+#include <thread>
+#include <vector>
+
+namespace jaegertracing {
+namespace utils {
+
+TEST(UDPSender, testZipkinMessage)
+{
+ net::IPAddress serverAddr;
+ std::promise<void> started;
+ std::thread serverThread([&serverAddr, &started]() {
+ net::Socket socket;
+ socket.open(AF_INET, SOCK_DGRAM);
+ socket.bind(net::IPAddress::v4("127.0.0.1", 0));
+ ::sockaddr_storage addrStorage;
+ ::socklen_t addrLen = sizeof(addrStorage);
+ const auto returnCode =
+ ::getsockname(socket.handle(),
+ reinterpret_cast<::sockaddr*>(&addrStorage),
+ &addrLen);
+ ASSERT_EQ(0, returnCode);
+ serverAddr = net::IPAddress(addrStorage, addrLen);
+ started.set_value();
+ });
+
+ started.get_future().wait();
+ UDPTransporter udpClient(serverAddr, 0);
+ using ZipkinBatch = std::vector<twitter::zipkin::thrift::Span>;
+ ASSERT_THROW(udpClient.emitZipkinBatch(ZipkinBatch()), std::logic_error);
+ serverThread.join();
+}
+
+TEST(UDPSender, testBigMessage)
+{
+ net::IPAddress serverAddr;
+ std::promise<void> started;
+ std::thread serverThread([&serverAddr, &started]() {
+ net::Socket socket;
+ socket.open(AF_INET, SOCK_DGRAM);
+ socket.bind(net::IPAddress::v4("127.0.0.1", 0));
+ ::sockaddr_storage addrStorage;
+ ::socklen_t addrLen = sizeof(addrStorage);
+ const auto returnCode =
+ ::getsockname(socket.handle(),
+ reinterpret_cast<::sockaddr*>(&addrStorage),
+ &addrLen);
+ ASSERT_EQ(0, returnCode);
+ serverAddr = net::IPAddress(addrStorage, addrLen);
+ started.set_value();
+ });
+
+ started.get_future().wait();
+ UDPTransporter udpClient(serverAddr, 1);
+ ASSERT_THROW(udpClient.emitBatch(thrift::Batch()), std::logic_error);
+ serverThread.join();
+}
+
+} // namespace utils
+} // namespace jaegertracing
diff --git a/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/utils/UDPTransporter.cpp b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/utils/UDPTransporter.cpp
new file mode 100644
index 000000000..d8bbeda3a
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/utils/UDPTransporter.cpp
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2017-2018 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.
+ */
+
+#include "jaegertracing/utils/UDPTransporter.h"
+#include <thrift/protocol/TCompactProtocol.h>
+#include <thrift/protocol/TProtocol.h>
+
+namespace jaegertracing {
+namespace utils {
+
+UDPTransporter::UDPTransporter(const net::IPAddress& serverAddr, int maxPacketSize)
+ : Transport(maxPacketSize == 0 ? kUDPPacketMaxLength
+ : maxPacketSize)
+ , _buffer(new apache::thrift::transport::TMemoryBuffer(_maxPacketSize))
+ , _serverAddr(serverAddr)
+ , _client()
+{
+ using TProtocolFactory = apache::thrift::protocol::TProtocolFactory;
+ using TCompactProtocolFactory =
+ apache::thrift::protocol::TCompactProtocolFactory;
+
+ _socket.open(AF_INET, SOCK_DGRAM);
+ _socket.connect(_serverAddr);
+ std::shared_ptr<TProtocolFactory> protocolFactory(
+ new TCompactProtocolFactory());
+ auto protocol = protocolFactory->getProtocol(_buffer);
+ _client.reset(new agent::thrift::AgentClient(protocol));
+}
+
+} // namespace utils
+} // namespace jaegertracing
diff --git a/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/utils/UDPTransporter.h b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/utils/UDPTransporter.h
new file mode 100644
index 000000000..dfd642476
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/utils/UDPTransporter.h
@@ -0,0 +1,88 @@
+/*
+ * Copyright (c) 2017-2018 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_UTILS_UDPCLIENT_H
+#define JAEGERTRACING_UTILS_UDPCLIENT_H
+
+#include <iostream>
+#include <sstream>
+#include <stdexcept>
+#include <system_error>
+
+#include "jaegertracing/Compilers.h"
+
+#include <thrift/protocol/TCompactProtocol.h>
+#include <thrift/transport/TBufferTransports.h>
+
+#include "jaegertracing/utils/Transport.h"
+
+#include "jaegertracing/net/IPAddress.h"
+#include "jaegertracing/thrift-gen/Agent.h"
+
+namespace jaegertracing {
+namespace utils {
+
+class UDPTransporter : public Transport {
+ public:
+ static constexpr auto kUDPPacketMaxLength = 65000;
+
+ UDPTransporter(const net::IPAddress& serverAddr, int maxPacketSize);
+
+ void emitZipkinBatch(
+ const std::vector<twitter::zipkin::thrift::Span>& spans)
+ {
+ throw std::logic_error("emitZipkinBatch not implemented");
+ }
+
+ void emitBatch(const thrift::Batch& batch) override
+ {
+ _buffer->resetBuffer();
+ _client->emitBatch(batch);
+ uint8_t* data = nullptr;
+ uint32_t size = 0;
+ _buffer->getBuffer(&data, &size);
+ if (static_cast<int>(size) > _maxPacketSize) {
+ std::ostringstream oss;
+ oss << "Data does not fit within one UDP packet"
+ ", size "
+ << size << ", max " << _maxPacketSize << ", spans "
+ << batch.spans.size();
+ throw std::logic_error(oss.str());
+ }
+ const auto numWritten = ::send(_socket.handle(), reinterpret_cast<char*>(data), sizeof(uint8_t) * size, 0);
+ if (static_cast<unsigned>(numWritten) != size) {
+ std::ostringstream oss;
+ oss << "Failed to write message"
+ ", numWritten="
+ << numWritten << ", size=" << size;
+ throw std::system_error(errno, std::system_category(), oss.str());
+ }
+ }
+
+ std::unique_ptr< apache::thrift::protocol::TProtocolFactory > protocolFactory() const override {
+ return std::unique_ptr<apache::thrift::protocol::TProtocolFactory>(new apache::thrift::protocol::TCompactProtocolFactory());
+ }
+
+ private:
+ std::shared_ptr<apache::thrift::transport::TMemoryBuffer> _buffer;
+ net::IPAddress _serverAddr;
+ std::unique_ptr<agent::thrift::AgentClient> _client;
+};
+
+} // namespace utils
+} // namespace jaegertracing
+
+#endif // JAEGERTRACING_UTILS_UDPCLIENT_H
diff --git a/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/utils/YAML.cpp b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/utils/YAML.cpp
new file mode 100644
index 000000000..1040fd91d
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/utils/YAML.cpp
@@ -0,0 +1,17 @@
+/*
+ * 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.
+ */
+
+#include "jaegertracing/utils/YAML.h"
diff --git a/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/utils/YAML.h b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/utils/YAML.h
new file mode 100644
index 000000000..5ca72ec9d
--- /dev/null
+++ b/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/utils/YAML.h
@@ -0,0 +1,48 @@
+/*
+ * 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_UTILS_YAML_H
+#define JAEGERTRACING_UTILS_YAML_H
+
+#include "jaegertracing/Constants.h"
+
+#ifdef JAEGERTRACING_WITH_YAML_CPP
+
+#include <yaml-cpp/yaml.h>
+
+namespace jaegertracing {
+namespace utils {
+namespace yaml {
+
+template <typename ValueType, typename KeyType, typename DefaultValueType>
+ValueType findOrDefault(const YAML::Node& node,
+ const KeyType& key,
+ const DefaultValueType& defaultValue)
+{
+ const auto valueNode = node[key];
+ if (!valueNode.IsDefined()) {
+ return defaultValue;
+ }
+ return valueNode.template as<ValueType>();
+}
+
+} // namespace yaml
+} // namespace utils
+} // namespace jaegertracing
+
+#endif // JAEGERTRACING_WITH_YAML_CPP
+
+#endif // JAEGERTRACING_UTILS_YAML_H