diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 18:45:59 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 18:45:59 +0000 |
commit | 19fcec84d8d7d21e796c7624e521b60d28ee21ed (patch) | |
tree | 42d26aa27d1e3f7c0b8bd3fd14e7d7082f5008dc /src/jaegertracing/jaeger-client-cpp | |
parent | Initial commit. (diff) | |
download | ceph-19fcec84d8d7d21e796c7624e521b60d28ee21ed.tar.xz ceph-19fcec84d8d7d21e796c7624e521b60d28ee21ed.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 '')
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 |