pax_global_header00006660000000000000000000000064141321457230014514gustar00rootroot0000000000000052 comment=d1b715edc4d84faff090b0a3cf795b3256c949df opentracing-c-wrapper-1.1.3/000077500000000000000000000000001413214572300157255ustar00rootroot00000000000000opentracing-c-wrapper-1.1.3/.gitignore000066400000000000000000000004171413214572300177170ustar00rootroot00000000000000Makefile Makefile.in aclocal.m4 config.log config.status config/ configure core libtool m4/libtool.m4 m4/ltoptions.m4 m4/ltsugar.m4 m4/ltversion.m4 m4/lt~obsolete.m4 package stamp-h1 test/ot-c-wrapper-test* version.h .deps/ .libs/ *.la *.lo *.o *.orig *.pc *.rej *.so _* opentracing-c-wrapper-1.1.3/AUTHORS000066400000000000000000000000501413214572300167700ustar00rootroot00000000000000Miroslav Zagorac opentracing-c-wrapper-1.1.3/COPYING000066400000000000000000000000441413214572300167560ustar00rootroot00000000000000Copyright 2020 HAProxy Technologies opentracing-c-wrapper-1.1.3/ChangeLog000066400000000000000000000001341413214572300174750ustar00rootroot00000000000000Wed Jun 9 15:47:38 CEST 2021 - added functions otc_tracer_load() and otc_tracer_start() opentracing-c-wrapper-1.1.3/INSTALL000066400000000000000000000366141413214572300167700ustar00rootroot00000000000000Installation Instructions ************************* Copyright (C) 1994-1996, 1999-2002, 2004-2016 Free Software Foundation, Inc. Copying and distribution of this file, with or without modification, are permitted in any medium without royalty provided the copyright notice and this notice are preserved. This file is offered as-is, without warranty of any kind. Basic Installation ================== Briefly, the shell command './configure && make && make install' should configure, build, and install this package. The following more-detailed instructions are generic; see the 'README' file for instructions specific to this package. Some packages provide this 'INSTALL' file but do not implement all of the features documented below. The lack of an optional feature in a given package is not necessarily a bug. More recommendations for GNU packages can be found in *note Makefile Conventions: (standards)Makefile Conventions. The 'configure' shell script attempts to guess correct values for various system-dependent variables used during compilation. It uses those values to create a 'Makefile' in each directory of the package. It may also create one or more '.h' files containing system-dependent definitions. Finally, it creates a shell script 'config.status' that you can run in the future to recreate the current configuration, and a file 'config.log' containing compiler output (useful mainly for debugging 'configure'). It can also use an optional file (typically called 'config.cache' and enabled with '--cache-file=config.cache' or simply '-C') that saves the results of its tests to speed up reconfiguring. Caching is disabled by default to prevent problems with accidental use of stale cache files. If you need to do unusual things to compile the package, please try to figure out how 'configure' could check whether to do them, and mail diffs or instructions to the address given in the 'README' so they can be considered for the next release. If you are using the cache, and at some point 'config.cache' contains results you don't want to keep, you may remove or edit it. The file 'configure.ac' (or 'configure.in') is used to create 'configure' by a program called 'autoconf'. You need 'configure.ac' if you want to change it or regenerate 'configure' using a newer version of 'autoconf'. The simplest way to compile this package is: 1. 'cd' to the directory containing the package's source code and type './configure' to configure the package for your system. Running 'configure' might take a while. While running, it prints some messages telling which features it is checking for. 2. Type 'make' to compile the package. 3. Optionally, type 'make check' to run any self-tests that come with the package, generally using the just-built uninstalled binaries. 4. Type 'make install' to install the programs and any data files and documentation. When installing into a prefix owned by root, it is recommended that the package be configured and built as a regular user, and only the 'make install' phase executed with root privileges. 5. Optionally, type 'make installcheck' to repeat any self-tests, but this time using the binaries in their final installed location. This target does not install anything. Running this target as a regular user, particularly if the prior 'make install' required root privileges, verifies that the installation completed correctly. 6. You can remove the program binaries and object files from the source code directory by typing 'make clean'. To also remove the files that 'configure' created (so you can compile the package for a different kind of computer), type 'make distclean'. There is also a 'make maintainer-clean' target, but that is intended mainly for the package's developers. If you use it, you may have to get all sorts of other programs in order to regenerate files that came with the distribution. 7. Often, you can also type 'make uninstall' to remove the installed files again. In practice, not all packages have tested that uninstallation works correctly, even though it is required by the GNU Coding Standards. 8. Some packages, particularly those that use Automake, provide 'make distcheck', which can by used by developers to test that all other targets like 'make install' and 'make uninstall' work correctly. This target is generally not run by end users. Compilers and Options ===================== Some systems require unusual options for compilation or linking that the 'configure' script does not know about. Run './configure --help' for details on some of the pertinent environment variables. You can give 'configure' initial values for configuration parameters by setting variables in the command line or in the environment. Here is an example: ./configure CC=c99 CFLAGS=-g LIBS=-lposix *Note Defining Variables::, for more details. Compiling For Multiple Architectures ==================================== You can compile the package for more than one kind of computer at the same time, by placing the object files for each architecture in their own directory. To do this, you can use GNU 'make'. 'cd' to the directory where you want the object files and executables to go and run the 'configure' script. 'configure' automatically checks for the source code in the directory that 'configure' is in and in '..'. This is known as a "VPATH" build. With a non-GNU 'make', it is safer to compile the package for one architecture at a time in the source code directory. After you have installed the package for one architecture, use 'make distclean' before reconfiguring for another architecture. On MacOS X 10.5 and later systems, you can create libraries and executables that work on multiple system types--known as "fat" or "universal" binaries--by specifying multiple '-arch' options to the compiler but only a single '-arch' option to the preprocessor. Like this: ./configure CC="gcc -arch i386 -arch x86_64 -arch ppc -arch ppc64" \ CXX="g++ -arch i386 -arch x86_64 -arch ppc -arch ppc64" \ CPP="gcc -E" CXXCPP="g++ -E" This is not guaranteed to produce working output in all cases, you may have to build one architecture at a time and combine the results using the 'lipo' tool if you have problems. Installation Names ================== By default, 'make install' installs the package's commands under '/usr/local/bin', include files under '/usr/local/include', etc. You can specify an installation prefix other than '/usr/local' by giving 'configure' the option '--prefix=PREFIX', where PREFIX must be an absolute file name. You can specify separate installation prefixes for architecture-specific files and architecture-independent files. If you pass the option '--exec-prefix=PREFIX' to 'configure', the package uses PREFIX as the prefix for installing programs and libraries. Documentation and other data files still use the regular prefix. In addition, if you use an unusual directory layout you can give options like '--bindir=DIR' to specify different values for particular kinds of files. Run 'configure --help' for a list of the directories you can set and what kinds of files go in them. In general, the default for these options is expressed in terms of '${prefix}', so that specifying just '--prefix' will affect all of the other directory specifications that were not explicitly provided. The most portable way to affect installation locations is to pass the correct locations to 'configure'; however, many packages provide one or both of the following shortcuts of passing variable assignments to the 'make install' command line to change installation locations without having to reconfigure or recompile. The first method involves providing an override variable for each affected directory. For example, 'make install prefix=/alternate/directory' will choose an alternate location for all directory configuration variables that were expressed in terms of '${prefix}'. Any directories that were specified during 'configure', but not in terms of '${prefix}', must each be overridden at install time for the entire installation to be relocated. The approach of makefile variable overrides for each directory variable is required by the GNU Coding Standards, and ideally causes no recompilation. However, some platforms have known limitations with the semantics of shared libraries that end up requiring recompilation when using this method, particularly noticeable in packages that use GNU Libtool. The second method involves providing the 'DESTDIR' variable. For example, 'make install DESTDIR=/alternate/directory' will prepend '/alternate/directory' before all installation names. The approach of 'DESTDIR' overrides is not required by the GNU Coding Standards, and does not work on platforms that have drive letters. On the other hand, it does better at avoiding recompilation issues, and works well even when some directory options were not specified in terms of '${prefix}' at 'configure' time. Optional Features ================= If the package supports it, you can cause programs to be installed with an extra prefix or suffix on their names by giving 'configure' the option '--program-prefix=PREFIX' or '--program-suffix=SUFFIX'. Some packages pay attention to '--enable-FEATURE' options to 'configure', where FEATURE indicates an optional part of the package. They may also pay attention to '--with-PACKAGE' options, where PACKAGE is something like 'gnu-as' or 'x' (for the X Window System). The 'README' should mention any '--enable-' and '--with-' options that the package recognizes. For packages that use the X Window System, 'configure' can usually find the X include and library files automatically, but if it doesn't, you can use the 'configure' options '--x-includes=DIR' and '--x-libraries=DIR' to specify their locations. Some packages offer the ability to configure how verbose the execution of 'make' will be. For these packages, running './configure --enable-silent-rules' sets the default to minimal output, which can be overridden with 'make V=1'; while running './configure --disable-silent-rules' sets the default to verbose, which can be overridden with 'make V=0'. Particular systems ================== On HP-UX, the default C compiler is not ANSI C compatible. If GNU CC is not installed, it is recommended to use the following options in order to use an ANSI C compiler: ./configure CC="cc -Ae -D_XOPEN_SOURCE=500" and if that doesn't work, install pre-built binaries of GCC for HP-UX. HP-UX 'make' updates targets which have the same time stamps as their prerequisites, which makes it generally unusable when shipped generated files such as 'configure' are involved. Use GNU 'make' instead. On OSF/1 a.k.a. Tru64, some versions of the default C compiler cannot parse its '' header file. The option '-nodtk' can be used as a workaround. If GNU CC is not installed, it is therefore recommended to try ./configure CC="cc" and if that doesn't work, try ./configure CC="cc -nodtk" On Solaris, don't put '/usr/ucb' early in your 'PATH'. This directory contains several dysfunctional programs; working variants of these programs are available in '/usr/bin'. So, if you need '/usr/ucb' in your 'PATH', put it _after_ '/usr/bin'. On Haiku, software installed for all users goes in '/boot/common', not '/usr/local'. It is recommended to use the following options: ./configure --prefix=/boot/common Specifying the System Type ========================== There may be some features 'configure' cannot figure out automatically, but needs to determine by the type of machine the package will run on. Usually, assuming the package is built to be run on the _same_ architectures, 'configure' can figure that out, but if it prints a message saying it cannot guess the machine type, give it the '--build=TYPE' option. TYPE can either be a short name for the system type, such as 'sun4', or a canonical name which has the form: CPU-COMPANY-SYSTEM where SYSTEM can have one of these forms: OS KERNEL-OS See the file 'config.sub' for the possible values of each field. If 'config.sub' isn't included in this package, then this package doesn't need to know the machine type. If you are _building_ compiler tools for cross-compiling, you should use the option '--target=TYPE' to select the type of system they will produce code for. If you want to _use_ a cross compiler, that generates code for a platform different from the build platform, you should specify the "host" platform (i.e., that on which the generated programs will eventually be run) with '--host=TYPE'. Sharing Defaults ================ If you want to set default values for 'configure' scripts to share, you can create a site shell script called 'config.site' that gives default values for variables like 'CC', 'cache_file', and 'prefix'. 'configure' looks for 'PREFIX/share/config.site' if it exists, then 'PREFIX/etc/config.site' if it exists. Or, you can set the 'CONFIG_SITE' environment variable to the location of the site script. A warning: not all 'configure' scripts look for a site script. Defining Variables ================== Variables not defined in a site shell script can be set in the environment passed to 'configure'. However, some packages may run configure again during the build, and the customized values of these variables may be lost. In order to avoid this problem, you should set them in the 'configure' command line, using 'VAR=value'. For example: ./configure CC=/usr/local2/bin/gcc causes the specified 'gcc' to be used as the C compiler (unless it is overridden in the site shell script). Unfortunately, this technique does not work for 'CONFIG_SHELL' due to an Autoconf limitation. Until the limitation is lifted, you can use this workaround: CONFIG_SHELL=/bin/bash ./configure CONFIG_SHELL=/bin/bash 'configure' Invocation ====================== 'configure' recognizes the following options to control how it operates. '--help' '-h' Print a summary of all of the options to 'configure', and exit. '--help=short' '--help=recursive' Print a summary of the options unique to this package's 'configure', and exit. The 'short' variant lists options used only in the top level, while the 'recursive' variant lists options also present in any nested packages. '--version' '-V' Print the version of Autoconf used to generate the 'configure' script, and exit. '--cache-file=FILE' Enable the cache: use and save the results of the tests in FILE, traditionally 'config.cache'. FILE defaults to '/dev/null' to disable caching. '--config-cache' '-C' Alias for '--cache-file=config.cache'. '--quiet' '--silent' '-q' Do not print messages saying which checks are being made. To suppress all normal output, redirect it to '/dev/null' (any error messages will still be shown). '--srcdir=DIR' Look for the package's source code in directory DIR. Usually 'configure' can determine that directory automatically. '--prefix=DIR' Use DIR as the installation prefix. *note Installation Names:: for more details, including other options available for fine-tuning the installation locations. '--no-create' '-n' Run the configure checks, but stop before creating any output files. 'configure' also accepts some other, not widely useful, options. Run 'configure --help' for more details. opentracing-c-wrapper-1.1.3/LICENSE000066400000000000000000000261271413214572300167420ustar00rootroot00000000000000 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 2020 HAProxy Technologies Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. opentracing-c-wrapper-1.1.3/MAINTAINERS000066400000000000000000000000501413214572300174150ustar00rootroot00000000000000Miroslav Zagorac opentracing-c-wrapper-1.1.3/Makefile.am000066400000000000000000000003451413214572300177630ustar00rootroot00000000000000## Process this file with automake to produce Makefile.in ## SUBDIRS = src test DIST_SUBDIRS = src test DISTCLEANFILES = _* *~ CLEANFILES = a.out core gmon.out ACLOCAL_AMFLAGS = -I m4 ## ## Makefile.am ends here opentracing-c-wrapper-1.1.3/NEWS000066400000000000000000000000001413214572300164120ustar00rootroot00000000000000opentracing-c-wrapper-1.1.3/README000066400000000000000000000257031413214572300166140ustar00rootroot00000000000000 ------------------------------------------------------------- C wrapper for the C++ implementation of the OpenTracing API ------------------------------------------------------------- Summary ------------------------------------------------------------------------ 1. Introduction 2. Build instructions 3. Testing the operation of the library 4. Basic concepts in the OpenTracing 5. Tracing example 6. Known bugs and limitations 1. Introduction ------------------------------------------------------------------------ OpenTracing C Wrapper library was created due to the need to use distributed tracing within C programs. The OpenTracing project (https://opentracing.io/) has published a C-language implementation on https://github.com/opentracing/opentracing-c but that implementation is incomplete, with the last update on Jun 27th 2018 This library takes inspiration from the header files in that project but implements the proposed functionality fully by wrapping the functional C++ library. 2. Build instructions ------------------------------------------------------------------------ Prerequisites for configuring and compiling the OpenTracing C Wrapper: ---------------------------------------------------------------------- * GNU GCC Compiler and Development Environment The main components of this system are C standard library, C and C++ compilers, make and cmake utilities and other development tools that are not explicitly listed because they depend on the system on which we want to compile the OpenTracing C Wrapper. The program itself is very likely possible to compile with another C compiler (non-GCC), but I'm not sure about the other required libraries. On debian-like linux systems it is necessary to run the following, in order to install development packages: # apt-get install automake autoconf make cmake libc6-dev gcc g++ binutils libtool pkgconf gawk git * GNU autoconf https://www.gnu.org/software/autoconf/ * GNU automake https://www.gnu.org/software/automake/ * POSIX threads library * C++ implementation of the OpenTracing API http://opentracing.io https://github.com/opentracing/opentracing-cpp * the tracing plugins (one of the following may be used): * Jaeger SDK with OpenTracing API for C++ binding https://github.com/jaegertracing/jaeger-client-cpp * the LightStep distributed tracing library for C++ https://github.com/lightstep/lightstep-tracer-cpp * OpenTracing implementation for Zipkin in C++ https://github.com/rnburn/zipkin-cpp-opentracing * Datadog OpenTracing C++ Client https://github.com/DataDog/dd-opentracing-cpp Note: prompt '%' indicates that the command is executed under a unprivileged user, while prompt '#' indicates that the command is executed under the root user. Compiling and installing the opentracing-cpp library: ----------------------------------------------------- The assumption is that we want to install the library in the /opt directory. % wget https://github.com/opentracing/opentracing-cpp/archive/v1.5.0.tar.gz % tar xf v1.5.0.tar.gz % cd opentracing-cpp-1.5.0 % mkdir build % cd build % cmake -DCMAKE_INSTALL_PREFIX=/opt .. % make # make install Of course, we can take another version of the library (or download the master branch via git). For example, this version is used here due to compatibility with the Jaeger plugin, which I mostly used when testing the operation of the program. Compiling and installing the opentracing-c-wrapper library: ----------------------------------------------------------- We will also install this library in the /opt directory, and when configuring the library we must specify where the opentracing-cpp library is located. In this example we will install two builds of the library, first the release version and then the debug version. % git clone https://github.com/haproxytech/opentracing-c-wrapper.git % cd opentracing-c-wrapper % ./scripts/bootstrap % ./configure --prefix=/opt --with-opentracing=/opt % make # make install % ./scripts/distclean % ./scripts/bootstrap % ./configure --prefix=/opt --enable-debug --with-opentracing=/opt % make # make install Compiling the Jaeger tracing plugin: ------------------------------------ We will use the 1.5.0 version of the plugin, a newer one can be taken (or the git master branch) if you want to try it (as is the case with previous libraries, you can try a newer version). Important note: the GCC version must be at least 4.9 or later. % wget https://github.com/jaegertracing/jaeger-client-cpp/archive/v0.5.0.tar.gz % tar xf v0.5.0.tar.gz % cd jaeger-client-cpp-0.5.0 % mkdir build % cd build % cmake -DCMAKE_INSTALL_PREFIX=/opt -DJAEGERTRACING_PLUGIN=ON -DHUNTER_CONFIGURATION_TYPES=Release -DHUNTER_BUILD_SHARED_LIBS=OFF .. % make After the plugin is compiled, it will be in the current directory. The name of the plugin is libjaegertracing_plugin.so. Of course, we can download the precompiled version of the Jaeger plugin (unfortunately, the latest version that can be downloaded is 0.4.2). % wget https://github.com/jaegertracing/jaeger-client-cpp/releases/download/v0.4.2/libjaegertracing_plugin.linux_amd64.so 3. Testing the operation of the library ------------------------------------------------------------------------ Testing of the library can be done through the test program, which is located in the eponymous directory 'test'. In this directory there is also a script with which we can download opentracing plugins from all supported tracers. As a script argument we can specify the directory to which the plugins are downloaded. If we do not specify this argument then the download is done to the current directory. In our example we will place the downloaded plugins in the 'test' directory: % ./test/get-opentracing-plugins.sh test The options supported by the test program can be found using the '-h' option: % ./test/ot-c-wrapper-test_dbg -h --- help output ------- Usage: ot-c-wrapper-test_dbg { -h --help } ot-c-wrapper-test_dbg { -V --version } ot-c-wrapper-test_dbg { [ -R --runcount=VALUE ] | [ -r --runtime=TIME ] } [OPTION]... Options are: -c, --config=FILE Specify the configuration for the used tracer. -d, --debug=LEVEL Enable and specify the debug mode level (default: 0). -h, --help Show this text. -p, --plugin=FILE Specify the OpenTracing compatible plugin library. -R, --runcount=VALUE Execute this program a certain number of passes (0 = unlimited). -r, --runtime=TIME Run this program for a certain amount of time (ms, 0 = unlimited). -t, --threads=VALUE Specify the number of threads (default: 1000). -V, --version Show program version. Copyright 2020 HAProxy Technologies SPDX-License-Identifier: Apache-2.0 --- help output ------- In case we did not use the '--enable-debug' option when configuring the library, the test program will be named ot-c-wrapper-test. Example of using the test program: % ./test/ot-c-wrapper-test -r 10000 -c test/cfg-jaeger.yml -p test/libjaeger_opentracing_plugin-0.4.2.so '-r' is the option that must be specified when launching a program. It is used to prevent the test program from starting unnecessarily when testing the program options, or printing the test program help. In addition, with this option, the test program runtime is set. If the time is set to 0, the test program runtime is unlimited. In the example above, the runtime is set to 10 seconds. With the '-c' option, we specify the configuration of the used tracer (in this case it is Jeager); while the '-p' option selects the plugin library that the selected tracer uses. The test directory contains several configurations prepared for supported tracers: - cfg-dd.json - Datadog tracer - cfg-jaeger.yml - Jaeger tracer - cfg-zipkin.json - Zipkin tracer Jaeger docker image installation: --------------------------------- Installation instructions can be found on the website https://www.jaegertracing.io/download/. For the impatient, here we will list how the image to test the operation of the tracer system can be installed without much reading of the documentation. # docker pull jaegertracing/all-in-one:latest # docker run -d --name jaeger -e COLLECTOR_ZIPKIN_HTTP_PORT=9411 -p 5775:5775/udp -p 6831:6831/udp -p 6832:6832/udp -p 5778:5778 -p 16686:16686 -p 14268:14268 -p 9411:9411 jaegertracing/all-in-one:latest The last command will also initialize and run the Jaeger container. If we want to use that container later, it can be started and stopped in the classic way, using the 'docker container start/stop' commands. 4. Basic concepts in the OpenTracing ------------------------------------------------------------------------ Basic concepts of the OpenTracing can be read on the OpenTracing documentation website https://opentracing.io/docs/overview/. Here we will list only the most important elements of distributed tracing and these are 'trace', 'span' and 'span context'. Trace is a description of the complete transaction we want to record in the tracing system. A span is an operation that represents a unit of work that is recorded in a tracing system. Span context is a group of information related to a particular span that is passed on to the system (from service to service). Using this context, we can add new spans to already open trace (or supplement data in already open spans). An individual span may contain one or more tags, logs and baggage items. The tag is a key-value element that is valid for the entire span. Log is a key-value element that allows you to write some data at a certain time, it can be used for debugging. A baggage item is a key-value data pair that can be used for the duration of an entire trace, from the moment it is added to the span. 5. Tracing example ------------------------------------------------------------------------ In the example, whose source is in the 'test' directory, the operation of the OpenTracing C Wrapper is checked. 5 spans are created in which tags, logs and baggage are placed; and data propagation via text map, http header and binary data is checked. root span |------------------------------------------------------------------| span #1 |----------------------------------------------------------| text map propagation |--------------------------------------------------| http headers propagation |------------------------------------------| binary data propagation |----------------------------------| 6. Known bugs and limitations ------------------------------------------------------------------------ The library does not know whether the data was sent to the tracer or not, because sending is done in a separate thread that does not affect the operation of the rest of the program. One should not exaggerate with the number of competing threads that send data to their tracers as this can slow down the sending of data to the tracer. opentracing-c-wrapper-1.1.3/TODO000066400000000000000000000000001413214572300164030ustar00rootroot00000000000000opentracing-c-wrapper-1.1.3/VERSION000066400000000000000000000000561413214572300167760ustar00rootroot00000000000000Package Version: 1.1.3 Library Version: 1:1:1 opentracing-c-wrapper-1.1.3/configure.ac000066400000000000000000000055531413214572300202230ustar00rootroot00000000000000dnl Process this file with autoconf to produce a configure script. dnl dnl configure.ac - Miroslav Zagorac AC_PREREQ([2.69]) AC_COPYRIGHT([Copyright (C) 2020 HAProxy Technologies]) AC_INIT(m4_esyscmd_s([basename ${PWD}]), m4_esyscmd_s([awk '/Package/ { print $3 }' VERSION]), [mzagorac@haproxy.com]) AC_CONFIG_MACRO_DIR([m4]) AX_VARIABLE_SET([LIB_VERSION], m4_esyscmd_s([awk '/Library/ { print $3 }' VERSION])) echo "*** configuring for ${PACKAGE_NAME} v${PACKAGE_VERSION}, lib v${LIB_VERSION} ***" AC_PREFIX_DEFAULT([/usr]) AC_CONFIG_AUX_DIR([config]) AM_INIT_AUTOMAKE([1.13]) AX_VARIABLES_INIT AM_SILENT_RULES([yes]) AX_HOST dnl Check for source directory. dnl AC_CONFIG_SRCDIR([src/tracer.cpp]) AC_CONFIG_HEADERS([config/config.h]) AX_PROG_PKGCONFIG PKG_INSTALLDIR dnl Set the compiler, preprocessor, and file extensions. dnl AC_LANG([C]) dnl Checking command line options. dnl AX_ENABLE_DEBUG AX_ENABLE_GPROF AX_ENABLE_THREADS dnl dnl Misc dnl AX_WITH_OPENTRACING dnl Checks for programs. dnl AC_PROG_CXX AC_PROG_CC AC_PROG_INSTALL dnl Initialize libtool dnl LT_INIT dnl Checks for header files. dnl AC_CHECK_HEADERS([fcntl.h inttypes.h malloc.h stdint.h stdlib.h string.h sys/time.h unistd.h]) dnl Checks for typedefs, structures, and compiler characteristics. dnl AC_CHECK_HEADER_STDBOOL AC_TYPE_UINT8_T AC_TYPE_INT64_T AC_TYPE_UINT64_T AC_TYPE_OFF_T AC_TYPE_SIZE_T AC_TYPE_SSIZE_T dnl Checks for libraries. dnl dnl Checks for library functions. dnl AC_FUNC_ERROR_AT_LINE AC_FUNC_STRERROR_R AC_CHECK_FUNCS([clock_gettime gettimeofday memmove memset strchr strdup strndup]) AC_CHECK_FUNCS([mallinfo]) dnl Set the compiler flags dnl AX_PROG_CC_SET([]) AX_PROG_CXX_SET([]) AM_CONDITIONAL([WANT_DEBUG], [test "${enable_debug}" = "yes"]) AX_VARIABLES_SET AX_VARIABLE_SET([OPENTRACING_C_WRAPPER_CPPFLAGS], [ ${OPENTRACING_CPPFLAGS} ${THREADS_CPPFLAGS} ]) AX_VARIABLE_SET([OPENTRACING_C_WRAPPER_CFLAGS], [ ${OPENTRACING_CFLAGS} ${THREADS_CFLAGS} ]) AX_VARIABLE_SET([OPENTRACING_C_WRAPPER_CXXFLAGS], [ ${OPENTRACING_CXXFLAGS} ${THREADS_CXXFLAGS} ]) AX_VARIABLE_SET([OPENTRACING_C_WRAPPER_LDFLAGS], [ ${OPENTRACING_LDFLAGS} ${THREADS_LDFLAGS} ]) AX_VARIABLE_SET([OPENTRACING_C_WRAPPER_LIBS], [ ${OPENTRACING_LIBS} ${THREADS_LIBS} ]) AC_SUBST([OPENTRACING_C_WRAPPER_CPPFLAGS]) AC_SUBST([OPENTRACING_C_WRAPPER_CFLAGS]) AC_SUBST([OPENTRACING_C_WRAPPER_CXXFLAGS]) AC_SUBST([OPENTRACING_C_WRAPPER_LDFLAGS]) AC_SUBST([OPENTRACING_C_WRAPPER_LIBS]) dnl version.h dnl CONFIGURE_OPTIONS="${ac_configure_args}" AC_SUBST([DATE]) AC_SUBST([PACKAGE_VERSION]) AC_SUBST([LIB_VERSION]) AC_SUBST([CONFIGURE_OPTIONS]) AC_CONFIG_FILES([Makefile src/Makefile test/Makefile include/version.h opentracing-c-wrapper.pc opentracing-c-wrapper_dbg.pc]) AC_OUTPUT AX_SHOW_CONFIG AH_TOP([ #ifndef _COMMON_CONFIG_H #define _COMMON_CONFIG_H ]) AH_BOTTOM([ #endif /* _COMMON_CONFIG_H */ ]) opentracing-c-wrapper-1.1.3/include/000077500000000000000000000000001413214572300173505ustar00rootroot00000000000000opentracing-c-wrapper-1.1.3/include/dbg_malloc.h000066400000000000000000000040631413214572300216070ustar00rootroot00000000000000/*** * Copyright 2020 HAProxy Technologies * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT 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 _OPENTRACING_C_WRAPPER_DBG_MALLOC_H_ #define _OPENTRACING_C_WRAPPER_DBG_MALLOC_H_ #ifdef HAVE_MALLOC_H # include #endif #define DBG_MEM(l,s,f, ...) \ do { \ if (dbg_mem == nullptr) \ /* Do nothing. */; \ else if (!(l) || (dbg_mem->level & (1 << (l)))) \ (void)fprintf((s), f "\n", ##__VA_ARGS__); \ } while (0) #define DBG_MEM_ERR(f, ...) DBG_MEM(0, stderr, "MEM_ERROR: " f, ##__VA_ARGS__) #define DBG_MEM_INFO(l,f, ...) DBG_MEM((l), stdout, f, ##__VA_ARGS__) /* 8 bytes - dBgM (dBgM ^ 0xffffffff) */ #define DBG_MEM_MAGIC UINT64_C(0x6442674d9bbd98b2) #define DBG_MEM_SIZE(n) ((n) + sizeof(struct otc_dbg_mem_metadata)) #define DBG_MEM_PTR(p) DBG_MEM_SIZE(OT_CAST_TYPEOF(uint8_t *, (p))) #define DBG_MEM_DATA(p) OT_CAST_TYPEOF(struct otc_dbg_mem_metadata *, OT_CAST_TYPEOF(uint8_t *, (p)) - DBG_MEM_SIZE(0)) #define DBG_MEM_RETURN(p) (((p) == nullptr) ? nullptr : DBG_MEM_PTR(p)) struct otc_dbg_mem_metadata { struct otc_dbg_mem_data *data; uint64_t magic; }; #ifdef __sun #define PRI_MI "lu" #else #define PRI_MI "d" #endif #endif /* _OPENTRACING_C_WRAPPER_DBG_MALLOC_H_ */ /* * Local variables: * c-indent-level: 8 * c-basic-offset: 8 * End: * * vi: noexpandtab shiftwidth=8 tabstop=8 */ opentracing-c-wrapper-1.1.3/include/define.h000066400000000000000000000047411413214572300207610ustar00rootroot00000000000000/*** * Copyright 2020 HAProxy Technologies * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT 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 _OPENTRACING_C_WRAPPER_DEFINE_H_ #define _OPENTRACING_C_WRAPPER_DEFINE_H_ #undef OT_THREADS_NO_LOCKING #ifdef USE_THREADS # define __THR __thread #else # define __THR #endif #ifdef DEBUG # define OTC_DBG_MEM # define OT_IFDEF_DBG(a,b) a # define OT_EXT_MALLOC(s) otc_ext_malloc(__func__, __LINE__, (s)) # define OT_EXT_FREE_CLEAR(a) do { if ((a) != nullptr) { otc_ext_free(__func__, __LINE__, a); (a) = nullptr; } } while (0) #else # define OT_IFDEF_DBG(a,b) b # define OT_EXT_MALLOC(s) otc_ext_malloc(s) # define OT_EXT_FREE_CLEAR(a) do { if ((a) != nullptr) { otc_ext_free(a); (a) = nullptr; } } while (0) #endif #define OT_FREE(a) do { if ((a) != nullptr) OTC_DBG_FREE(a); } while (0) #define OT_FREE_CLEAR(a) do { if ((a) != nullptr) { OTC_DBG_FREE(a); (a) = nullptr; } } while (0) #define OT_IN_RANGE(v,a,b) (((v) >= (a)) && ((v) <= (b))) #define OT_SPAN_KEY_IS_VALID(a) OT_IN_RANGE((a)->idx, 0, ot_span.key - 1) #define OT_SPAN_IS_VALID(a) (((a) != nullptr) && OT_SPAN_KEY_IS_VALID(a)) #define OT_CTX_KEY_IS_VALID(a) OT_IN_RANGE((a)->idx, 0, ot_span_context.key - 1) #define OT_CTX_IS_VALID(a) (((a) != nullptr) && (OT_SPAN_IS_VALID((a)->span) || OT_CTX_KEY_IS_VALID(a))) #define OT_CAST_CONST(t,e) const_cast(e) #define OT_CAST_STAT(t,e) static_cast(e) #define OT_CAST_REINTERPRET(t,e) reinterpret_cast(e) #define OT_CAST_TYPEOF(t,e) OT_CAST_REINTERPRET(typeof(t), (e)) #ifdef __cplusplus # define __CPLUSPLUS_DECL_BEGIN extern "C" { # define __CPLUSPLUS_DECL_END } #else # define __CPLUSPLUS_DECL_BEGIN # define __CPLUSPLUS_DECL_END #endif #endif /* _OPENTRACING_C_WRAPPER_DEFINE_H_ */ /* * Local variables: * c-indent-level: 8 * c-basic-offset: 8 * End: * * vi: noexpandtab shiftwidth=8 tabstop=8 */ opentracing-c-wrapper-1.1.3/include/include.h000066400000000000000000000027551413214572300211550ustar00rootroot00000000000000/*** * Copyright 2020 HAProxy Technologies * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT 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 _OPENTRACING_C_WRAPPER_INCLUDE_H_ #define _OPENTRACING_C_WRAPPER_INCLUDE_H_ #include #include #include #include #include #include #include #include "config.h" #include "define.h" #ifdef DEBUG # include "dbg_malloc.h" #endif #include "opentracing-c-wrapper/define.h" #include "opentracing-c-wrapper/dbg_malloc.h" #include "opentracing-c-wrapper/common.h" #include "opentracing-c-wrapper/util.h" #include "opentracing-c-wrapper/value.h" #include "opentracing-c-wrapper/span.h" #include "opentracing-c-wrapper/propagation.h" #include "opentracing-c-wrapper/tracer.h" #include "span.h" #include "tracer.h" #include "util.h" #endif /* _OPENTRACING_C_WRAPPER_INCLUDE_H_ */ /* * Local variables: * c-indent-level: 8 * c-basic-offset: 8 * End: * * vi: noexpandtab shiftwidth=8 tabstop=8 */ opentracing-c-wrapper-1.1.3/include/opentracing-c-wrapper/000077500000000000000000000000001413214572300235575ustar00rootroot00000000000000opentracing-c-wrapper-1.1.3/include/opentracing-c-wrapper/common.h000066400000000000000000000022541413214572300252230ustar00rootroot00000000000000/*** * Copyright 2020 HAProxy Technologies * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT 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 OPENTRACING_C_WRAPPER_COMMON_H #define OPENTRACING_C_WRAPPER_COMMON_H __CPLUSPLUS_DECL_BEGIN /*** * boolean type */ typedef enum { otc_false = 0, otc_true = 1, } otc_bool_t; /*** * duration type for calculating intervals (monotonic) */ struct otc_duration { struct timespec value; }; /*** * timestamp type for absolute time */ struct otc_timestamp { struct timespec value; }; __CPLUSPLUS_DECL_END #endif /* OPENTRACING_C_WRAPPER_COMMON_H */ /* * Local variables: * c-indent-level: 8 * c-basic-offset: 8 * End: * * vi: noexpandtab shiftwidth=8 tabstop=8 */ opentracing-c-wrapper-1.1.3/include/opentracing-c-wrapper/dbg_malloc.h000066400000000000000000000056551413214572300260260ustar00rootroot00000000000000/*** * Copyright 2020 HAProxy Technologies * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT 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 OPENTRACING_C_WRAPPER_DBG_MALLOC_H #define OPENTRACING_C_WRAPPER_DBG_MALLOC_H __CPLUSPLUS_DECL_BEGIN #ifdef OTC_DBG_MEM #define OTC_DBG_MALLOC(s) otc_dbg_malloc(__func__, __LINE__, (s)) #define OTC_DBG_CALLOC(n,e) otc_dbg_calloc(__func__, __LINE__, (n), (e)) #define OTC_DBG_REALLOC(p,s) otc_dbg_realloc(__func__, __LINE__, (p), (s)) #define OTC_DBG_FREE(p) otc_dbg_free(__func__, __LINE__, (p)) #define OTC_DBG_STRDUP(s) otc_dbg_strdup(__func__, __LINE__, (s)) #define OTC_DBG_STRNDUP(s,n) otc_dbg_strndup(__func__, __LINE__, (s), (n)) #define OTC_DBG_MEMDUP(s,n) otc_dbg_memdup(__func__, __LINE__, (s), (n)) #define OTC_DBG_MEMINFO() otc_dbg_mem_info() struct otc_dbg_mem_data { const void *ptr; size_t size; char func[63]; bool used; } __attribute__((packed)); struct otc_dbg_mem { struct otc_dbg_mem_data *data; size_t count; size_t unused; size_t reused; uint64_t size; uint64_t op_cnt[4]; uint8_t level; pthread_mutex_t mutex; }; void *otc_dbg_malloc(const char *func, int line, size_t size); void *otc_dbg_calloc(const char *func, int line, size_t nelem, size_t elsize); void *otc_dbg_realloc(const char *func, int line, void *ptr, size_t size); void otc_dbg_free(const char *func, int line, void *ptr); char *otc_dbg_strdup(const char *func, int line, const char *s); char *otc_dbg_strndup(const char *func, int line, const char *s, size_t size); void *otc_dbg_memdup(const char *func, int line, const void *s, size_t size); int otc_dbg_mem_init(struct otc_dbg_mem *mem, struct otc_dbg_mem_data *data, size_t count, uint8_t level); void otc_dbg_mem_disable(void); void otc_dbg_mem_info(void); #else #define OTC_DBG_MALLOC(s) malloc(s) #define OTC_DBG_CALLOC(n,e) calloc((n), (e)) #define OTC_DBG_REALLOC(p,s) realloc((p), (s)) #define OTC_DBG_FREE(p) free(p) #define OTC_DBG_STRDUP(s) strdup(s) #define OTC_DBG_STRNDUP(s,n) strndup((s), (n)) #define OTC_DBG_MEMDUP(s,n) mem_dup((s), (n)) #define OTC_DBG_MEMINFO() while (0) #endif /* OTC_DBG_MEM */ __CPLUSPLUS_DECL_END #endif /* OPENTRACING_C_WRAPPER_DBG_MALLOC_H */ /* * Local variables: * c-indent-level: 8 * c-basic-offset: 8 * End: * * vi: noexpandtab shiftwidth=8 tabstop=8 */ opentracing-c-wrapper-1.1.3/include/opentracing-c-wrapper/define.h000066400000000000000000000024121413214572300251610ustar00rootroot00000000000000/*** * Copyright 2020 HAProxy Technologies * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT 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 OPENTRACING_C_WRAPPER_DEFINE_H #define OPENTRACING_C_WRAPPER_DEFINE_H #define OTC_MAXLOGFIELDS 8 #ifdef __cplusplus # define __CPLUSPLUS_DECL_BEGIN extern "C" { # define __CPLUSPLUS_DECL_END } #else # define __CPLUSPLUS_DECL_BEGIN # define __CPLUSPLUS_DECL_END #endif #ifdef __GNUC__ # define OTC_NONNULL(...) __attribute__((nonnull(__VA_ARGS__))) # define OTC_NONNULL_ALL __attribute__((nonnull)) #else # define OTC_NONNULL(...) # define OTC_NONNULL_ALL #endif #endif /* OPENTRACING_C_WRAPPER_DEFINE_H */ /* * Local variables: * c-indent-level: 8 * c-basic-offset: 8 * End: * * vi: noexpandtab shiftwidth=8 tabstop=8 */ opentracing-c-wrapper-1.1.3/include/opentracing-c-wrapper/include.h000066400000000000000000000023041413214572300253520ustar00rootroot00000000000000/*** * Copyright 2020 HAProxy Technologies * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT 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 OPENTRACING_C_WRAPPER_INCLUDE_H #define OPENTRACING_C_WRAPPER_INCLUDE_H #include #include #include #include #include #include #include #include #include #endif /* OPENTRACING_C_WRAPPER_INCLUDE_H */ /* * Local variables: * c-indent-level: 8 * c-basic-offset: 8 * End: * * vi: noexpandtab shiftwidth=8 tabstop=8 */ opentracing-c-wrapper-1.1.3/include/opentracing-c-wrapper/propagation.h000066400000000000000000000116051413214572300262560ustar00rootroot00000000000000/*** * Copyright 2020 HAProxy Technologies * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT 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 OPENTRACING_C_WRAPPER_PROPAGATION_H #define OPENTRACING_C_WRAPPER_PROPAGATION_H __CPLUSPLUS_DECL_BEGIN /*** * span context propagation error codes */ typedef enum { /*** * success */ otc_propagation_error_code_success = 0, /*** * not enough information to extract a span context */ otc_propagation_error_code_span_context_not_found = -2, /*** * invalid/incompatible span context */ otc_propagation_error_code_invalid_span_context = -3, /*** * invalid carrier */ otc_propagation_error_code_invalid_carrier = -4, /*** * corrupted carrier */ otc_propagation_error_code_span_context_corrupted = -5, /*** * unknown error */ otc_propagation_error_code_unknown = -6, /*** * tracer not initialized */ otc_propagation_error_code_invalid_tracer = -7, } otc_propagation_error_code_t; /*** * Used to set information into a span context for propagation, entries * are strings in a map of string pointers * * set and get implementations should use the same convention * for naming the keys they manipulate */ struct otc_text_map_writer { struct otc_text_map text_map; /*** * NAME * set - * * ARGUMENTS * writer - writer instance * key - string key * value - string value * * DECRTIPTION * set a key-value pair * * RETURN VALUE * otc_propagation_error_code_t - indicates success or failure */ otc_propagation_error_code_t (*set)(struct otc_text_map_writer *writer, const char *key, const char *value) OTC_NONNULL(1); }; /*** * Used to get information from a propagated span context * * set and get implementations should use the same convention * for naming the keys they manipulate */ struct otc_text_map_reader { struct otc_text_map text_map; /*** * NAME * foreach_key - * * ARGUMENTS * reader - reader instance * handler - handler function for each key-value pair * arg - user-defined contents * * DESCRIPTION * gets map entries by colling the handler function repeatedly. Returns immediately upon first error * * RETURN VALUE * - error code indicating success or failure. */ otc_propagation_error_code_t (*foreach_key)(struct otc_text_map_reader *reader, otc_propagation_error_code_t (*handler)(void *arg, const char *key, const char *value), void *arg) OTC_NONNULL(1, 2); }; /*** * Used to set HTTP headers */ struct otc_http_headers_writer { struct otc_text_map text_map; otc_propagation_error_code_t (*set)(struct otc_http_headers_writer *writer, const char *key, const char *value) OTC_NONNULL(1); }; /*** * USed to get HTTP headers */ struct otc_http_headers_reader { struct otc_text_map text_map; otc_propagation_error_code_t (*foreach_key)(struct otc_http_headers_reader *reader, otc_propagation_error_code_t (*handler)(void *arg, const char *key, const char *value), void *arg) OTC_NONNULL(1, 2); }; /*** * Set/write to a custom format */ struct otc_custom_carrier_writer { struct otc_binary_data binary_data; /*** * NAME * inject - * * ARGUMENTS * writer - writer instance * tracer - tracer instance * span_context - span context to write * DESCRIPTION * write a span context into a custom format * * RETURN VALUE * - error code indicating success or failure */ otc_propagation_error_code_t (*inject)(struct otc_custom_carrier_writer *writer, const struct otc_tracer *tracer, const struct otc_span_context *span_context) OTC_NONNULL_ALL; }; /*** * Get from a custom format */ struct otc_custom_carrier_reader { struct otc_binary_data binary_data; /*** * NAME * extract - * * ARGUMENTS * reader - reader instance * tracer - tracer instance * span_context - span context pointer to return the decoded * span (can be NULL if propagation failed * or OOM) * * DESCRIPTION * - get a span context from a custom format * * RETURN VALUE * - error code indicating success or failure */ otc_propagation_error_code_t (*extract)(struct otc_custom_carrier_reader *reader, const struct otc_tracer *tracer, struct otc_span_context **span_context) OTC_NONNULL_ALL; }; __CPLUSPLUS_DECL_END #endif /* OPENTRACING_C_WRAPPER_PROPAGATION_H */ /* * Local variables: * c-indent-level: 8 * c-basic-offset: 8 * End: * * vi: noexpandtab shiftwidth=8 tabstop=8 */ opentracing-c-wrapper-1.1.3/include/opentracing-c-wrapper/span.h000066400000000000000000000132061413214572300246730ustar00rootroot00000000000000/*** * Copyright 2020 HAProxy Technologies * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT 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 OPENTRACING_C_WRAPPER_SPAN_H #define OPENTRACING_C_WRAPPER_SPAN_H __CPLUSPLUS_DECL_BEGIN /*** * Encode a key-value for logging */ struct otc_log_field { /*** * key string */ const char *key; /*** * representation of the value */ struct otc_value value; }; /*** * A log entry for events that occured during the span lifetime */ struct otc_log_record { /*** * event timestamp */ struct otc_timestamp timestamp; /*** * array of log fields */ struct otc_log_field *fields; /*** * number of log fields, must be set to zero if fields is NULL */ int num_fields; }; typedef enum { /*** * parent span that created and also depends on the child span */ otc_span_reference_child_of = 1, /*** * parent span that doesn't dpeend on the child span * * more details in http://opentracing.io/spec/ */ otc_span_reference_follows_from = 2 } otc_span_reference_type_t; struct otc_span_reference { otc_span_reference_type_t type; struct otc_span_context *referenced_context; }; struct otc_finish_span_options { /*** * time when the span finished (monotonic clock) */ struct otc_duration finish_time; /*** * array with otc_log_record entries */ const struct otc_log_record *log_records; /*** * number of log records, must be set to zero if fields is NULL */ int num_log_records; }; /*** * The span interface */ struct otc_span { int64_t idx; /*** * NAME * finish - * * ARGUMENTS * span - span instance * * DESCRIPTION * sets the ending timestamp and finalizes span. Must be the last call for a span instance (except calls to context) */ void (*finish)(struct otc_span *span) OTC_NONNULL_ALL; /*** * NAME * finish_with_options - * * ARGUMENTS * span - span instance * options - override span completion with these options * * DESCRIPTION * finalizes the span but allows for customizing the timestamp and log data */ void (*finish_with_options)(struct otc_span *span, const struct otc_finish_span_options *options) OTC_NONNULL(1); /*** * NAME * otc_span_context - * * ARGUMENTS * span - span instance * * DESCRIPTION * returns an otc_span_context for the span * * RETURN VALUE * span - context for this span */ struct otc_span_context *(*span_context)(struct otc_span *span) OTC_NONNULL_ALL; /*** * NAME * set_operation_name - * * ARGUMENTS * span - span instance * operation_name - new operation name * * DESCRIPTION * set or change the operation name */ void (*set_operation_name)(struct otc_span *span, const char *operation_name) OTC_NONNULL_ALL; /*** * NAME * set_tag * * ARGUMENTS * span - span instance * key - tag key to copy into the span * value - tag value to copy into the span * * DESCRIPTION * add a tag to a span, overwriting any existing tag with the * same key. Tag values supported are strings, numbers and bools */ void (*set_tag)(struct otc_span *span, const char *key, const struct otc_value *value) OTC_NONNULL_ALL; /*** * NAME * log_fields - * * ARGUMENTS * span - span instance * fields - log fields as an array, values should be copied by the implementation * num_fields - number of log fields in the log field array * * DESCRIPTION * store log data for a span */ void (*log_fields)(struct otc_span *span, const struct otc_log_field *fields, int num_fields) OTC_NONNULL(1); /*** * NAME * set_baggage_item - * * ARGUMENTS * span - span instance * key - baggage key * value - baggage value * * DESCRIPTION * store a key-value pair to this span and the associated span * context, also propagating to descendents */ void (*set_baggage_item)(struct otc_span *span, const char *key, const char *value) OTC_NONNULL_ALL; /*** * NAME * baggage_item - * * ARGUMENTS * span - span instance * key - baggage key * * DESCRIPTION * get the baggage for a baggage key * * RETURN VALUE * baggage value for the key, or empty string if the key doesn't exist */ const char *(*baggage_item)(const struct otc_span *span, const char *key) OTC_NONNULL_ALL; /*** * NAME * tracer - * * ARGUMENTS * span - span instance * * DESCRIPTION * returns the tracer that created the span * * RETURN VALUE * tracer instance that creaated the span */ struct otc_tracer *(*tracer)(const struct otc_span *span) OTC_NONNULL_ALL; /*** * NAME * destroy - * * ARGUMENTS * span - span instance */ void (*destroy)(struct otc_span **span) OTC_NONNULL_ALL; }; /*** * interface for span context */ struct otc_span_context { int64_t idx; const struct otc_span *span; /*** * NAME * destroy - * * ARGUMENTS * context - instance of span context */ void (*destroy)(struct otc_span_context **context) OTC_NONNULL_ALL; }; __CPLUSPLUS_DECL_END #endif /* OPENTRACING_C_WRAPPER_SPAN_H */ /* * Local variables: * c-indent-level: 8 * c-basic-offset: 8 * End: * * vi: noexpandtab shiftwidth=8 tabstop=8 */ opentracing-c-wrapper-1.1.3/include/opentracing-c-wrapper/tracer.h000066400000000000000000000071231413214572300252130ustar00rootroot00000000000000/*** * Copyright 2020 HAProxy Technologies * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT 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 OPENTRACING_C_WRAPPER_TRACER_H #define OPENTRACING_C_WRAPPER_TRACER_H __CPLUSPLUS_DECL_BEGIN struct otc_tag { const char *key; struct otc_value value; }; struct otc_start_span_options { struct otc_duration start_time_steady; struct otc_timestamp start_time_system; const struct otc_span_reference *references; int num_references; const struct otc_tag *tags; int num_tags; }; /*** * tracer interface */ struct otc_tracer { void (*close)(struct otc_tracer *tracer) OTC_NONNULL_ALL; struct otc_span *(*start_span)(struct otc_tracer *tracer, const char *operation_name) OTC_NONNULL_ALL; struct otc_span *(*start_span_with_options)(struct otc_tracer *tracer, const char *operation_name, const struct otc_start_span_options *options) OTC_NONNULL(1, 2); otc_propagation_error_code_t (*inject_text_map)(struct otc_tracer *tracer, struct otc_text_map_writer *carrier, const struct otc_span_context *span_context) OTC_NONNULL_ALL; otc_propagation_error_code_t (*inject_http_headers)(struct otc_tracer *tracer, struct otc_http_headers_writer *carrier, const struct otc_span_context *span_context) OTC_NONNULL_ALL; otc_propagation_error_code_t (*inject_binary)(struct otc_tracer *tracer, struct otc_custom_carrier_writer *carrier, const struct otc_span_context *span_context) OTC_NONNULL_ALL; otc_propagation_error_code_t (*inject_custom)(struct otc_tracer *tracer, struct otc_custom_carrier_writer *carrier, const struct otc_span_context *span_context) OTC_NONNULL_ALL; otc_propagation_error_code_t (*extract_text_map)(struct otc_tracer *tracer, const struct otc_text_map_reader *carrier, struct otc_span_context **span_context) OTC_NONNULL_ALL; otc_propagation_error_code_t (*extract_http_headers)(struct otc_tracer *tracer, const struct otc_http_headers_reader *carrier, struct otc_span_context **span_context) OTC_NONNULL_ALL; otc_propagation_error_code_t (*extract_binary)(struct otc_tracer *tracer, const struct otc_custom_carrier_reader *carrier, struct otc_span_context **span_context) OTC_NONNULL_ALL; otc_propagation_error_code_t (*extract_custom)(struct otc_tracer *tracer, const struct otc_custom_carrier_reader *carrier, struct otc_span_context **span_context) OTC_NONNULL_ALL; void (*destroy)(struct otc_tracer **tracer) OTC_NONNULL_ALL; }; struct otc_tracer *otc_tracer_init(const char *library, const char *cfgfile, const char *cfgbuf, char *errbuf, int errbufsiz); struct otc_tracer *otc_tracer_load(const char *library, char *errbuf, int errbufsiz); int otc_tracer_start(const char *cfgfile, const char *cfgbuf, char *errbuf, int errbufsiz); void otc_tracer_global(struct otc_tracer *tracer); void otc_tracer_init_global(struct otc_tracer *tracer); __CPLUSPLUS_DECL_END #endif /* OPENTRACING_C_WRAPPER_TRACER_H */ /* * Local variables: * c-indent-level: 8 * c-basic-offset: 8 * End: * * vi: noexpandtab shiftwidth=8 tabstop=8 */ opentracing-c-wrapper-1.1.3/include/opentracing-c-wrapper/util.h000066400000000000000000000071071413214572300247120ustar00rootroot00000000000000/*** * Copyright 2020 HAProxy Technologies * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT 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 OPENTRACING_C_WRAPPER_UTIL_H #define OPENTRACING_C_WRAPPER_UTIL_H __CPLUSPLUS_DECL_BEGIN typedef enum { OTC_TEXT_MAP_DUP_KEY = 0x01, /* Duplicate the key data. */ OTC_TEXT_MAP_DUP_VALUE = 0x02, /* Duplicate the value data. */ OTC_TEXT_MAP_FREE_KEY = 0x04, /* Release the key data. */ OTC_TEXT_MAP_FREE_VALUE = 0x08, /* Release the value data. */ } otc_text_map_flags_t; struct otc_text_map { char **key; char **value; size_t count; size_t size; bool is_dynamic; }; struct otc_binary_data { void *data; size_t size; bool is_dynamic; }; /* * Jaeger Trace/Span Identity * uber-trace-id: {trace-id}:{span-id}:{parent-span-id}:{flags} * uberctx-{baggage-key}: {value} * * Zipkin * x-b3-traceid: {trace-id} * x-b3-spanid: {span-id} * x-b3-parentspanid: {parent-span-id} * x-b3-flags: {flags} * x-b3-sampled: {value} * ot-baggage-{baggage-key}: {value} * * DataDog * x-datadog-trace-id: {trace-id} * x-datadog-parent-id: {parent-id} * x-datadog-sampling-priority: {value} * ot-baggage-{baggage-key}: {value} */ struct otc_jaeger_trace_context { uint64_t trace_id[2]; /* 128-bit random number, value of 0 is not valid. */ uint64_t span_id; /* 64-bit random number, value of 0 is not valid. */ uint64_t parent_span_id; /* 64-bit parent span id, 0 value is valid and means 'root span' */ uint8_t flags; /* 8-bit bitmap, only bits 0 and 1 are used. */ uint8_t baggage[0]; } __attribute__((packed)); struct otc_zipkin_trace_context { uint8_t data[0]; } __attribute__((packed)); struct otc_dd_trace_context { uint8_t data[0]; } __attribute__((packed)); #ifdef OTC_DBG_MEM typedef void *(*otc_ext_malloc_t)(const char *, int, size_t); typedef void (*otc_ext_free_t)(const char *, int, void *); #else typedef void *(*otc_ext_malloc_t)(size_t); typedef void (*otc_ext_free_t)(void *); #endif void otc_ext_init(otc_ext_malloc_t func_malloc, otc_ext_free_t func_free); struct otc_text_map *otc_text_map_new(struct otc_text_map *text_map, size_t size); int otc_text_map_add(struct otc_text_map *text_map, const char *key, size_t key_len, const char *value, size_t value_len, otc_text_map_flags_t flags); void otc_text_map_destroy(struct otc_text_map **text_map, otc_text_map_flags_t flags); struct otc_binary_data *otc_binary_data_new(struct otc_binary_data *binary_data, const void *data, size_t size); void otc_binary_data_destroy(struct otc_binary_data **binary_data); char *otc_file_read(const char *filename, const char *comment, char *errbuf, int errbufsiz); void otc_statistics(char *buffer, size_t bufsiz); __CPLUSPLUS_DECL_END #endif /* OPENTRACING_C_WRAPPER_UTIL_H */ /* * Local variables: * c-indent-level: 8 * c-basic-offset: 8 * End: * * vi: noexpandtab shiftwidth=8 tabstop=8 */ opentracing-c-wrapper-1.1.3/include/opentracing-c-wrapper/value.h000066400000000000000000000024451413214572300250510ustar00rootroot00000000000000/*** * Copyright 2020 HAProxy Technologies * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT 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 OPENTRACING_C_WRAPPER_VALUE_H #define OPENTRACING_C_WRAPPER_VALUE_H __CPLUSPLUS_DECL_BEGIN /*** * value types */ typedef enum { otc_value_bool = 0, otc_value_double, otc_value_int64, otc_value_uint64, otc_value_string, otc_value_null, } otc_value_type_t; /*** * union for representing various value types */ struct otc_value { otc_value_type_t type; union { otc_bool_t bool_value; double double_value; int64_t int64_value; uint64_t uint64_value; const char *string_value; } value; }; __CPLUSPLUS_DECL_END #endif /* OPENTRACING_C_WRAPPER_VALUE_H */ /* * Local variables: * c-indent-level: 8 * c-basic-offset: 8 * End: * * vi: noexpandtab shiftwidth=8 tabstop=8 */ opentracing-c-wrapper-1.1.3/include/span.h000066400000000000000000000051741413214572300204710ustar00rootroot00000000000000/*** * Copyright 2020 HAProxy Technologies * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT 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 _OPENTRACING_C_WRAPPER_SPAN_H_ #define _OPENTRACING_C_WRAPPER_SPAN_H_ #define OT_LF(a) { fields[a].key, str_value[a] } class otc_hash { public: size_t operator() (int64_t key) const { return key; } }; class otc_equal_to { public: bool operator() (int64_t a, int64_t b) const { return a == b; } }; # ifdef OT_THREADS_NO_LOCKING template using Handle = std::unordered_map< int64_t, std::unique_ptr, otc_hash, otc_equal_to >; struct HandleData { int64_t key; int64_t alloc_fail_cnt; int64_t erase_cnt; int64_t destroy_cnt; }; # define OT_LOCK_GUARD(a,...) # define OT_LOCK(a,b) extern thread_local Handle ot_span_handle; extern thread_local Handle ot_span_context_handle; extern struct HandleData ot_span; extern struct HandleData ot_span_context; # else template struct Handle { std::unordered_map< int64_t, std::unique_ptr, otc_hash, otc_equal_to > handle; int64_t key; int64_t alloc_fail_cnt; int64_t erase_cnt; int64_t destroy_cnt; std::mutex mutex; }; # define ot_span_handle ot_span.handle # define ot_span_context_handle ot_span_context.handle # define OT_LOCK_GUARD(a,...) const std::lock_guard guard_##a(ot_##a.mutex, ##__VA_ARGS__) # define OT_LOCK(a,b) std::lock(ot_##a.mutex, ot_##b.mutex); OT_LOCK_GUARD(a, std::adopt_lock); OT_LOCK_GUARD(b, std::adopt_lock); extern struct Handle ot_span; extern struct Handle ot_span_context; # endif /* OT_THREADS_NO_LOCKING */ struct otc_span *ot_span_new(void); void ot_nolock_span_destroy(struct otc_span **span); struct otc_span_context *ot_span_context_new(const struct otc_span *span); #endif /* _OPENTRACING_C_WRAPPER_SPAN_H_ */ /* * Local variables: * c-indent-level: 8 * c-basic-offset: 8 * End: * * vi: noexpandtab shiftwidth=8 tabstop=8 */ opentracing-c-wrapper-1.1.3/include/tracer.h000066400000000000000000000075431413214572300210120ustar00rootroot00000000000000/*** * Copyright 2020 HAProxy Technologies * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT 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 _OPENTRACING_C_WRAPPER_TRACER_H_ #define _OPENTRACING_C_WRAPPER_TRACER_H_ using TextMap = std::unordered_map; class TextMapCarrier : public opentracing::TextMapReader, public opentracing::TextMapWriter { public: TextMapCarrier(TextMap &text_map) : tm_data(text_map) {} /*** * TextMapWriter: Set a key:value pair to the carrier. Multiple calls * to Set() for the same key leads to undefined behavior. */ opentracing::expected Set(opentracing::string_view key, opentracing::string_view value) const override { tm_data[key] = value; return {}; } /*** * TextMapReader: LookupKey() returns the value for the specified * key if available. If no such key is present, it returns * key_not_found_error. */ opentracing::expected LookupKey(opentracing::string_view key) const override { auto iter = tm_data.find(key); if (iter != tm_data.end()) return opentracing::string_view{iter->second}; return opentracing::make_unexpected(opentracing::key_not_found_error); } /*** * TextMapReader: ForeachKey() returns TextMap contents via repeated * calls to the f() function. If any call to f() returns an error, * ForeachKey() terminates and returns that error. */ opentracing::expected ForeachKey(std::function(opentracing::string_view key, opentracing::string_view value)> f) const override { for (const auto &text_map : tm_data) { auto result = f(text_map.first, text_map.second); if (!result) return result; } return {}; } private: TextMap &tm_data; }; class HTTPHeadersCarrier : public opentracing::HTTPHeadersReader, public opentracing::HTTPHeadersWriter { public: HTTPHeadersCarrier(TextMap &text_map) : tm_data(text_map) {} /*** * HTTPHeadersWriter: Set a key:value pair to the carrier. Multiple calls * to Set() for the same key leads to undefined behavior. */ opentracing::expected Set(opentracing::string_view key, opentracing::string_view value) const override { tm_data[key] = value; return {}; } /*** * HTTPHeadersReader: LookupKey() returns the value for the specified * key if available. If no such key is present, it returns * key_not_found_error. */ opentracing::expected LookupKey(opentracing::string_view key) const override { auto iter = tm_data.find(key); if (iter != tm_data.end()) return opentracing::string_view{iter->second}; return opentracing::make_unexpected(opentracing::key_not_found_error); } /*** * HTTPHeadersReader: ForeachKey() returns TextMap contents via repeated * calls to the f() function. If any call to f() returns an error, * ForeachKey() terminates and returns that error. */ opentracing::expected ForeachKey(std::function(opentracing::string_view key, opentracing::string_view value)> f) const override { for (const auto &text_map : tm_data) { auto result = f(text_map.first, text_map.second); if (!result) return result; } return {}; } private: TextMap &tm_data; }; struct otc_tracer *ot_tracer_new(void); #endif /* _OPENTRACING_C_WRAPPER_TRACER_H_ */ /* * Local variables: * c-indent-level: 8 * c-basic-offset: 8 * End: * * vi: noexpandtab shiftwidth=8 tabstop=8 */ opentracing-c-wrapper-1.1.3/include/util.h000066400000000000000000000025131413214572300204770ustar00rootroot00000000000000/*** * Copyright 2020 HAProxy Technologies * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT 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 _OPENTRACING_C_WRAPPER_UTIL_H_ #define _OPENTRACING_C_WRAPPER_UTIL_H_ #include #include #include #include /* Parameter 'p' must not be in parentheses! */ #define OT_TEXT_MAP_SIZE(p,n) (sizeof(text_map->p) * (text_map->size + (n))) extern otc_ext_malloc_t otc_ext_malloc; extern otc_ext_free_t otc_ext_free; std::chrono::microseconds timespec_to_duration_us(const struct timespec *ts); std::chrono::nanoseconds timespec_to_duration(const struct timespec *ts); const char *otc_strerror(int errnum); #endif /* _OPENTRACING_C_WRAPPER_UTIL_H_ */ /* * Local variables: * c-indent-level: 8 * c-basic-offset: 8 * End: * * vi: noexpandtab shiftwidth=8 tabstop=8 */ opentracing-c-wrapper-1.1.3/include/version.h.in000066400000000000000000000010271413214572300216130ustar00rootroot00000000000000#ifndef _OPENTRACING_C_WRAPPER_VERSION_H_ #define _OPENTRACING_C_WRAPPER_VERSION_H_ #define PACKAGE_AUTHOR "Miroslav Zagorac " #define PACKAGE_CPP_FLAGS "@CPPFLAGS@" #define PACKAGE_DEFS "@DEFS@" #define PACKAGE_C_FLAGS "@CFLAGS@" #define PACKAGE_CONFIGURE_OPTIONS "@CONFIGURE_OPTIONS@" #endif /* _OPENTRACING_C_WRAPPER_VERSION_H_ */ /* * Local variables: * c-indent-level: 8 * c-basic-offset: 8 * End: * * vi: noexpandtab shiftwidth=8 tabstop=8 */ opentracing-c-wrapper-1.1.3/m4/000077500000000000000000000000001413214572300162455ustar00rootroot00000000000000opentracing-c-wrapper-1.1.3/m4/am-common.m4000066400000000000000000000220251413214572300203730ustar00rootroot00000000000000dnl am-common.m4 by Miroslav Zagorac dnl AC_DEFUN([AX_TYPE_BOOL_T], [AC_CHECK_TYPE([bool_t], [unsigned char])]) AC_DEFUN([AX_TYPE_UNCHAR], [AC_CHECK_TYPE([unchar], [unsigned char])]) AC_DEFUN([AX_TYPE_USHORT], [AC_CHECK_TYPE([ushort], [unsigned short])]) AC_DEFUN([AX_TYPE_ULONG], [AC_CHECK_TYPE([ulong], [unsigned long])]) AC_DEFUN([AX_TYPE_UINT], [AC_CHECK_TYPE([uint], [unsigned int])]) AC_DEFUN([AX_VARIABLES_STORE], [ _saved_cppflags="${CPPFLAGS}" _saved_cflags="${CFLAGS}" _saved_cxxflags="${CXXFLAGS}" _saved_ldflags="${LDFLAGS}" _saved_libs="${LIBS}" ]) AC_DEFUN([AX_VARIABLES_RESTORE], [ CPPFLAGS="${_saved_cppflags}" CFLAGS="${_saved_cflags}" CXXFLAGS="${_saved_cxxflags}" LDFLAGS="${_saved_ldflags}" LIBS="${_saved_libs}" ]) AC_DEFUN([AX_VARIABLES_INIT], [ SET_CPPFLAGS= SET_CFLAGS= SET_CXXFLAGS= SET_LDFLAGS= SET_LIBS= ]) AC_DEFUN([AX_VARIABLES_SET], [ CPPFLAGS="${CPPFLAGS} ${SET_CPPFLAGS}" CFLAGS="${CFLAGS} ${SET_CFLAGS}" CXXFLAGS="${CXXFLAGS} ${SET_CXXFLAGS}" LDFLAGS="${LDFLAGS} ${SET_LDFLAGS}" LIBS="${LIBS} ${SET_LIBS}" ]) dnl Check which options the C compiler supports. dnl AC_DEFUN([AX_PROG_CC_SET], [ _var_cflags= _loop_cflags= AX_VARIABLES_STORE case "${CC}" in *gcc*) _var_cflags="\ -Wall \ -Wextra \ -Waggregate-return \ -Wbad-function-cast \ -Wcast-align \ -Wchar-subscripts \ -Wcomment \ -Wfloat-equal \ -Wimplicit \ -Winline \ -Wmain \ -Wmissing-braces \ -Wmissing-declarations \ -Wmissing-noreturn \ -Wmissing-prototypes \ -Wnested-externs \ -Wparentheses \ -Wpointer-arith \ -Wreturn-type \ -Wsequence-point \ -Wshadow \ -Wstrict-prototypes \ -Wswitch \ -Wtrigraphs \ -Wundef \ -Wuninitialized \ -Wunused \ -Wwrite-strings" if test "${enable_debug}" = "yes"; then _var_cflags="${_var_cflags} \ -Wformat=2" else _var_cflags="${_var_cflags} \ -Wformat-security \ -Wformat-y2k" fi ;; cc|clang) case "${host_os}" in *solaris*) _var_cflags="-xCC" ;; *freebsd1?.*) _var_cflags= ;; esac ;; esac TMP_CFLAGS="${CFLAGS}" AC_LANG_PUSH([C]) for _loop_cflags in ${_var_cflags} $1; do AC_MSG_CHECKING([whether ${CC} accepts ${_loop_cflags}]) CFLAGS="${TMP_CFLAGS} ${_loop_cflags}" AC_TRY_COMPILE([], [], [AC_MSG_RESULT([ yes]) SET_CFLAGS="${SET_CFLAGS} ${_loop_cflags}"], [AC_MSG_RESULT([ no])] ) done AC_LANG_POP([C]) CFLAGS="${TMP_CFLAGS}" AX_VARIABLES_RESTORE ]) dnl Check which options the C++ compiler supports. dnl AC_DEFUN([AX_PROG_CXX_SET], [ _var_cxxflags= _loop_cxxflags= AX_VARIABLES_STORE case "${CXX}" in c++|clang++) case "${host_os}" in *freebsd1?.*) _var_cxxflags="-Wno-extern-c-compat" ;; esac ;; *g++*) _var_cxxflags="\ -Wall \ -Wextra \ -Wcast-align \ -Wchar-subscripts \ -Wcomment \ -Wfloat-equal \ -Winline \ -Wmain \ -Wmissing-braces \ -Wmissing-declarations \ -Wmissing-noreturn \ -Wparentheses \ -Wpointer-arith \ -Wreturn-type \ -Wsequence-point \ -Wshadow \ -Wswitch \ -Wtrigraphs \ -Wundef \ -Wuninitialized \ -Wunused \ -Wwrite-strings \ \ -Wconditionally-supported \ -Wnamespaces \ -Wno-invalid-offsetof \ -Wno-terminate \ -Wnoexcept \ -Wold-style-cast \ -Woverloaded-virtual \ -Wsign-promo \ -Wsized-deallocation \ -Wstrict-null-sentinel \ -Wuseless-cast \ -Wvirtual-inheritance \ -Wzero-as-null-pointer-constant" if test "${enable_debug}" = "yes"; then _var_cxxflags="${_var_cxxflags} \ -Waggregate-return \ -Wformat=2 \ -Wmultiple-inheritance \ -Wtemplates" else _var_cxxflags="${_var_cxxflags} \ -Wformat-security \ -Wformat-y2k" fi ;; CC) case "${host_os}" in *solaris*) _var_cxxflags= ;; esac ;; esac TMP_CXXFLAGS="${CXXFLAGS}" AC_LANG_PUSH([C++]) for _loop_cxxflags in ${_var_cxxflags} $1; do AC_MSG_CHECKING([whether ${CXX} accepts ${_loop_cxxflags}]) CXXFLAGS="${TMP_CXXFLAGS} ${_loop_cxxflags}" AC_TRY_COMPILE([], [], [AC_MSG_RESULT([ yes]) SET_CXXFLAGS="${SET_CXXFLAGS} ${_loop_cxxflags}"], [AC_MSG_RESULT([ no])] ) done AC_LANG_POP([C++]) CXXFLAGS="${TMP_CXXFLAGS}" AX_VARIABLES_RESTORE ]) dnl Check whether the C++ compiler has noexcept specifier. dnl AC_DEFUN([AX_CHECK_NOEXCEPT], [ AC_MSG_CHECKING([whether the C++ compiler (${CXX}) has noexcept specifier]) AC_LANG_PUSH([C++]) AC_TRY_COMPILE([], [void (*fp)() noexcept(false);], [AC_MSG_RESULT([ yes])], [CXXFLAGS="-std=gnu++11" AC_MSG_RESULT([ no])] ) AC_LANG_POP([C++]) ]) dnl Check whether the C compiler has __DATE__ macro. dnl AC_DEFUN([AX_CHECK___DATE__], [ AC_MSG_CHECKING([whether the C compiler (${CC}) has __DATE__ macro]) AC_TRY_COMPILE([], [char *test=__DATE__;], [AC_MSG_RESULT([ yes])], [AC_DEFINE_UNQUOTED([__DATE__], ["`date`"], [Define if your C compiled doesn't have __DATE__ macro.]) AC_MSG_RESULT([ no])] ) ]) dnl Check whether the C compiler has __func__ variable. dnl AC_DEFUN([AX_CHECK___FUNC__], [ AC_MSG_CHECKING([whether the C compiler (${CC}) has __func__ variable]) AC_TRY_COMPILE([#include ], [printf ("%s", __func__);], [AC_MSG_RESULT([ yes])], [AC_DEFINE_UNQUOTED([__func__], ["__unknown__"], [Define if your C compiler doesn't have __func__ variable.]) AC_MSG_RESULT([ no])] ) ]) dnl Check whether the C compiler defines __STDC__. dnl AC_DEFUN([AX_CHECK___STDC__], [ AC_MSG_CHECKING([whether the C compiler (${CC}) defines __STDC__]) AC_TRY_COMPILE([], [#ifndef __STDC__ test_stdc (); #endif], [AC_MSG_RESULT([ yes]) AC_DEFINE_UNQUOTED([ANSI_FUNC], [1], [Define if you use an ANSI C compiler.]) stdc_defined="yes"], [AC_MSG_RESULT([ no])] ) ]) dnl dnl AC_DEFUN([AX_PROG_PKGCONFIG], [ AC_CHECK_PROG(PKG_CONFIG, [pkg-config], [yes], [no], [], []) test "${PKG_CONFIG}" = "no" && AC_MSG_ERROR([pkg-config not found]) ]) dnl dnl AC_DEFUN([AX_PATH_PKGCONFIG], [ PKG_CONFIG_PATH= _pc_prefix="${ac_default_prefix}" # ovdje se ne smije zamijeniti $n sa ${n} jer su to argumenti m4 funkcije AX_PATH_PKGCONFIG test "$1" = "yes" -o "$1" = "check" || _pc_prefix="$1" for _loop_path in \ ${_pc_prefix}/lib \ ${_pc_prefix}/lib/i386-linux-gnu \ ${_pc_prefix}/lib/x86_64-linux-gnu \ ${_pc_prefix}/amd64 \ ${_pc_prefix}/lib32 \ ${_pc_prefix}/lib64 \ ${_pc_prefix}/share do test -d "${_loop_path}/pkgconfig" && \ PKG_CONFIG_PATH="${PKG_CONFIG_PATH}${PKG_CONFIG_PATH:+:}${_loop_path}/pkgconfig" done AC_MSG_NOTICE([PKG_CONFIG_PATH=${PKG_CONFIG_PATH}]) ]) dnl Check whether the C compiler has __attribute__ keyword. dnl AC_DEFUN([AX_CHECK___ATTRIBUTE__], [ AC_MSG_CHECKING([whether the C compiler (${CC}) has __attribute__ keyword]) AC_TRY_COMPILE([void t1 () __attribute__ ((noreturn)); void t1 () { return; };], [t1 ();], [AC_MSG_RESULT([ yes]) AC_DEFINE_UNQUOTED([__ATTRIBUTE__], [1], [Define if your C compiler has __attribute__ keyword.])], [AC_MSG_RESULT([ no])] ) ]) AC_DEFUN([AX_ENABLE_DEBUG], [ AC_ARG_ENABLE([debug], [AS_HELP_STRING([--enable-debug], [compile with debugging symbols/functions])], [if test "${enableval}" = "yes"; then AC_DEFINE([DEBUG], [1], [Define to 1 if you want to include debugging options.]) CFLAGS="${CFLAGS} -g -O0" CXXFLAGS="${CXXFLAGS} -g -O0" fi] ) ]) AC_DEFUN([AX_ENABLE_GPROF], [ AC_ARG_ENABLE([gprof], [AS_HELP_STRING([--enable-gprof], [enable profiling with gprof])], [if test "${enableval}" = "yes"; then AC_DEFINE([GPROF], [1], [Define to 1 if you want to enable profiling with gprof.]) CFLAGS="${CFLAGS} -pg" CXXFLAGS="${CXXFLAGS} -pg" LDFLAGS="${LDFLAGS} -pg" fi] ) ]) AC_DEFUN([AX_VARIABLE_SET], [ _am_cache_test () { _c= if test -n "${2}"; then for _c in ${2}; do test "${_c}" = "${3}" && return 1; done eval "${1}=\"${2} ${3}\"" else eval "${1}=\"${3}\"" fi } _am_var_resolved= # ovdje se ne smije zamijeniti $n sa ${n} jer su to argumenti m4 funkcije AX_VARIABLE_SET for _am_var_loop in $2; do _am_cache_test _am_var_resolved "${_am_var_resolved}" "${_am_var_loop}" done $1=${_am_var_resolved} ]) AC_DEFUN([AX_SHOW_CONFIG], [ eval "bindir=${bindir}" eval "datadir=${datadir}" eval "sysconfdir=${sysconfdir}" eval "mandir=${mandir}" echo echo "${PACKAGE_NAME} configuration:" echo "--------------------------------------------------" echo " package version : ${PACKAGE_VERSION}" echo " library version : ${LIB_VERSION}" echo " host operating system : ${host}" echo " source code location : ${srcdir}" echo " C compiler : ${CC}" echo " C++ compiler : ${CXX}" echo " preprocessor flags : ${CPPFLAGS}" echo " C compiler flags : ${CFLAGS}" echo " C++ compiler flags : ${CXXFLAGS}" echo " linker flags : ${LDFLAGS}" echo " libraries : ${LIBS}" echo " configure options : ${ac_configure_args}" echo " binary install path : ${bindir}" echo " data install path : ${datadir}" echo " configuration file path : ${sysconfdir}" echo " man page install path : ${mandir}" echo ]) opentracing-c-wrapper-1.1.3/m4/am-enable-threads.m4000066400000000000000000000024311413214572300217600ustar00rootroot00000000000000dnl am-enable-threads.m4 by Miroslav Zagorac dnl AC_DEFUN([AX_ENABLE_THREADS], [ AC_ARG_ENABLE([threads], [AS_HELP_STRING([--enable-threads], [enable threads @<:@default=yes@:>@])], [enable_threads="${enableval}"], [enable_threads=yes] ) if test "${enable_threads}" != "no"; then HAVE_THREADS= THREADS_CFLAGS= THREADS_CPPFLAGS= THREADS_LDFLAGS= THREADS_LIBS= AX_VARIABLES_STORE LDFLAGS="${LDFLAGS} ${THREADS_LDFLAGS}" CPPFLAGS="${CPPFLAGS} ${THREADS_CPPFLAGS}" AC_CHECK_LIB([pthread], [pthread_create], [], [AC_MSG_ERROR([THREADS library not found])]) AC_CHECK_HEADER([pthread.h], [], [AC_MSG_ERROR([THREADS library headers not found])]) HAVE_THREADS=yes THREADS_LIBS="-lpthread" AC_DEFINE([USE_THREADS], [1], [Define to 1 for multi-thread support.]) AC_DEFINE([_REENTRANT], [1], [Define to 1 for multi-thread support.]) AX_VARIABLES_RESTORE AC_MSG_NOTICE([THREADS environment variables:]) AC_MSG_NOTICE([ THREADS_CFLAGS=${THREADS_CFLAGS}]) AC_MSG_NOTICE([ THREADS_CPPFLAGS=${THREADS_CPPFLAGS}]) AC_MSG_NOTICE([ THREADS_LDFLAGS=${THREADS_LDFLAGS}]) AC_MSG_NOTICE([ THREADS_LIBS=${THREADS_LIBS}]) AC_SUBST([THREADS_CFLAGS]) AC_SUBST([THREADS_CPPFLAGS]) AC_SUBST([THREADS_LDFLAGS]) AC_SUBST([THREADS_LIBS]) fi ]) opentracing-c-wrapper-1.1.3/m4/am-host.m4000066400000000000000000000021031413214572300200530ustar00rootroot00000000000000dnl am-host.m4 by Miroslav Zagorac dnl AC_DEFUN([AX_HOST], [ dnl Get current date and time. dnl DATE=`date` dnl Get cannonical host. dnl AC_CANONICAL_HOST AC_DEFINE_UNQUOTED([OSTYPE], ["${host}"], [Guessed OS type.]) dnl Posix variants dnl AC_USE_SYSTEM_EXTENSIONS dnl because ${${host_os%-*}##*-} does not work on stupid bash... dnl _host_os=${host_os%-*} _host_os=${_host_os##*-} case "${host_os}" in *osf*) test "${stdc_defined}" = "yes" || \ AC_DEFINE([__STDC__], [1], [Define to 1 if you use ANSI C compiler.]) AC_DEFINE([_REENTRANT], [1], [Define to 1 only for OSF Unix.]) AC_DEFINE([ANSI_FUNC], [1], [Define to 1 if you use ANSI C compiler.]) AC_DEFINE([OSF], [1], [Define to 1 for OSF Unix.]) ;; *solaris*) AC_DEFINE([ANSI_FUNC], [1], [Define to 1 if you use ANSI C compiler.]) AC_DEFINE([SOLARIS], [1], [Define to 1 for Solaris UNIX system.]) ;; *sunos*) AC_DEFINE([SUNOS], [1], [Define to 1 for SUNOS UNIX system.]) ;; *linux*) AC_DEFINE([LINUX], [1], [Define to 1 for Linux system.]) ;; esac ]) opentracing-c-wrapper-1.1.3/m4/am-with-opentracing.m4000066400000000000000000000044361413214572300223730ustar00rootroot00000000000000dnl am-with-opentracing.m4 by Miroslav Zagorac dnl AC_DEFUN([AX_WITH_OPENTRACING], [ AC_ARG_WITH([opentracing], [AS_HELP_STRING([--with-opentracing@<:@=DIR@:>@], [use OPENTRACING library @<:@default=yes@:>@])], [with_opentracing="${withval}"], [with_opentracing=yes] ) AX_CHECK_NOEXCEPT([]) if test "${with_opentracing}" != "no"; then HAVE_OPENTRACING= OPENTRACING_CFLAGS= OPENTRACING_CXXFLAGS= OPENTRACING_CPPFLAGS= OPENTRACING_LDFLAGS= OPENTRACING_LIBS="-lopentracing" if test -n "${with_opentracing}" -a "${with_opentracing}" != "yes" -a "${with_opentracing}" != "yes"; then OPENTRACING_CPPFLAGS="-I${with_opentracing}/include" if test "${with_opentracing}" != "/usr"; then if test "`uname`" = "Linux"; then OPENTRACING_LDFLAGS="-L${with_opentracing}/lib -Wl,--rpath,${with_opentracing}/lib" elif test "`uname`" = "FreeBSD"; then OPENTRACING_LDFLAGS="-L${with_opentracing}/lib -Wl,-rpath -Wl,${with_opentracing}/lib" else OPENTRACING_LDFLAGS="-L${with_opentracing}/lib -R${with_opentracing}/lib" fi fi fi AX_VARIABLES_STORE LIBS="${LDFLAGS} ${OPENTRACING_LIBS}" LDFLAGS="${LDFLAGS} ${OPENTRACING_LDFLAGS}" CFLAGS="${CFLAGS} ${OPENTRACING_CFLAGS}" CXXFLAGS="${CXXFLAGS} ${OPENTRACING_CXXFLAGS}" CPPFLAGS="${CPPFLAGS} ${OPENTRACING_CPPFLAGS}" AC_LANG_PUSH([C++]) AC_LINK_IFELSE([ AC_LANG_PROGRAM( [[#include ]], [[std::string e;] [auto a = opentracing::DynamicallyLoadTracingLibrary("", e);]] )], [], [AC_MSG_ERROR([OPENTRACING library not found])] ) AC_CHECK_HEADER([opentracing/version.h], [], [AC_MSG_ERROR([OPENTRACING library headers not found])]) AC_LANG_POP([C++]) HAVE_OPENTRACING=yes AX_VARIABLES_RESTORE AC_MSG_NOTICE([OPENTRACING environment variables:]) AC_MSG_NOTICE([ OPENTRACING_CFLAGS=${OPENTRACING_CFLAGS}]) AC_MSG_NOTICE([ OPENTRACING_CXXFLAGS=${OPENTRACING_CXXFLAGS}]) AC_MSG_NOTICE([ OPENTRACING_CPPFLAGS=${OPENTRACING_CPPFLAGS}]) AC_MSG_NOTICE([ OPENTRACING_LDFLAGS=${OPENTRACING_LDFLAGS}]) AC_MSG_NOTICE([ OPENTRACING_LIBS=${OPENTRACING_LIBS}]) AC_SUBST([OPENTRACING_CFLAGS]) AC_SUBST([OPENTRACING_CXXFLAGS]) AC_SUBST([OPENTRACING_CPPFLAGS]) AC_SUBST([OPENTRACING_LDFLAGS]) AC_SUBST([OPENTRACING_LIBS]) fi ]) opentracing-c-wrapper-1.1.3/opentracing-c-wrapper.pc.in000066400000000000000000000004251413214572300230660ustar00rootroot00000000000000prefix=@prefix@ exec_prefix=@exec_prefix@ libdir=@libdir@ includedir=@includedir@ Name: opentracing-c-wrapper Description: The OpenTracing C wrapper library. Version: @VERSION@ Requires: Libs: -L${libdir} -Wl,--rpath,${libdir} -lopentracing-c-wrapper Cflags: -I${includedir} opentracing-c-wrapper-1.1.3/opentracing-c-wrapper_dbg.pc.in000066400000000000000000000005121413214572300236770ustar00rootroot00000000000000prefix=@prefix@ exec_prefix=@exec_prefix@ libdir=@libdir@ includedir=@includedir@ Name: opentracing-c-wrapper_dbg Description: The OpenTracing C wrapper library with debugging support enabled. Version: @VERSION@ Requires: Libs: -L${libdir} -Wl,--rpath,${libdir} -lopentracing-c-wrapper_dbg Cflags: -I${includedir} -DOTC_DBG_MEM opentracing-c-wrapper-1.1.3/scripts/000077500000000000000000000000001413214572300174145ustar00rootroot00000000000000opentracing-c-wrapper-1.1.3/scripts/bootstrap000077500000000000000000000002721413214572300213600ustar00rootroot00000000000000#!/bin/sh -x # # bootstrap by Miroslav Zagorac # mkdir -p config libtoolize aclocal -I m4 autoheader automake --add-missing --copy autoconf rm -rf autom4te.cache opentracing-c-wrapper-1.1.3/scripts/distclean000077500000000000000000000004371413214572300213140ustar00rootroot00000000000000#!/bin/sh # # distclean Miroslav Zagorac # test -f Makefile && make maintainer-clean rm -rf autom4te.cache config package _* rm -f autoscan.log configure.scan aclocal.m4 config.log config.status configure rm -f Makefile.in */Makefile.in m4/l* src/.source-md5sums opentracing-c-wrapper-1.1.3/src/000077500000000000000000000000001413214572300165145ustar00rootroot00000000000000opentracing-c-wrapper-1.1.3/src/Makefile.am000066400000000000000000000034211413214572300205500ustar00rootroot00000000000000## Process this file with automake to produce Makefile.in ## ## AM_CPPFLAGS = @OPENTRACING_C_WRAPPER_CPPFLAGS@ AM_CFLAGS = @OPENTRACING_C_WRAPPER_CFLAGS@ AM_CXXFLAGS = @OPENTRACING_C_WRAPPER_CXXFLAGS@ AM_LDFLAGS = @OPENTRACING_C_WRAPPER_LDFLAGS@ LIBS = @LIBS@ @OPENTRACING_C_WRAPPER_LIBS@ if WANT_DEBUG lib_LTLIBRARIES = libopentracing-c-wrapper_dbg.la pkgconfig_DATA = ../opentracing-c-wrapper_dbg.pc libopentracing_c_wrapper_dbg_la_CPPFLAGS = $(AM_CPPFLAGS) -I$(srcdir)/../include libopentracing_c_wrapper_dbg_la_CFLAGS = $(AM_CFLAGS) libopentracing_c_wrapper_dbg_la_CXXFLAGS = $(AM_CXXFLAGS) libopentracing_c_wrapper_dbg_la_LDFLAGS = $(AM_LDFLAGS) -version-info @LIB_VERSION@ -Wl,--version-script=$(srcdir)/export_dbg.map libopentracing_c_wrapper_dbg_la_SOURCES = \ dbg_malloc.cpp \ span.cpp \ tracer.cpp \ util.cpp else lib_LTLIBRARIES = libopentracing-c-wrapper.la pkgconfig_DATA = ../opentracing-c-wrapper.pc libopentracing_c_wrapper_la_CPPFLAGS = $(AM_CPPFLAGS) -I$(srcdir)/../include libopentracing_c_wrapper_la_CFLAGS = $(AM_CFLAGS) libopentracing_c_wrapper_la_CXXFLAGS = $(AM_CXXFLAGS) libopentracing_c_wrapper_la_LDFLAGS = $(AM_LDFLAGS) -version-info @LIB_VERSION@ -Wl,--version-script=$(srcdir)/export.map libopentracing_c_wrapper_la_SOURCES = \ span.cpp \ tracer.cpp \ util.cpp endif pkginclude_HEADERS = \ ../include/opentracing-c-wrapper/common.h \ ../include/opentracing-c-wrapper/dbg_malloc.h \ ../include/opentracing-c-wrapper/define.h \ ../include/opentracing-c-wrapper/include.h \ ../include/opentracing-c-wrapper/propagation.h \ ../include/opentracing-c-wrapper/span.h \ ../include/opentracing-c-wrapper/tracer.h \ ../include/opentracing-c-wrapper/util.h \ ../include/opentracing-c-wrapper/value.h CLEANFILES = a.out ## ## Makefile.am ends here opentracing-c-wrapper-1.1.3/src/dbg_malloc.cpp000066400000000000000000000333661413214572300213160ustar00rootroot00000000000000/*** * Copyright 2020 HAProxy Technologies * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT 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 "include.h" static struct otc_dbg_mem *dbg_mem = nullptr; /*** * NAME * otc_dbg_set_metadata - * * ARGUMENTS * ptr - the real address of the allocated data * data - * * DESCRIPTION * - * * RETURN VALUE * This function does not return a value. */ static void otc_dbg_set_metadata(void *ptr, struct otc_dbg_mem_data *data) { struct otc_dbg_mem_metadata *metadata; if (ptr == nullptr) return; metadata = OT_CAST_TYPEOF(metadata, ptr); metadata->data = (data == nullptr) ? OT_CAST_TYPEOF(data, metadata) : data; metadata->magic = DBG_MEM_MAGIC; } /*** * NAME * otc_dbg_mem_add - * * ARGUMENTS * func - * line - * ptr - the real address of the allocated data * size - * data - * op_idx - * * DESCRIPTION * - * * RETURN VALUE * This function does not return a value. */ static void otc_dbg_mem_add(const char *func, int line, void *ptr, size_t size, struct otc_dbg_mem_data *data, int op_idx) { (void)snprintf(data->func, sizeof(data->func), "%s:%d", func, line); data->ptr = ptr; data->size = size; data->used = 1; dbg_mem->size += size; dbg_mem->op_cnt[op_idx]++; otc_dbg_set_metadata(ptr, data); } /*** * NAME * otc_dbg_mem_alloc - * * ARGUMENTS * func - * line - * old_ptr - the address of the data returned to the program * ptr - the real address of the allocated data * size - * * DESCRIPTION * - * * RETURN VALUE * This function does not return a value. */ static void otc_dbg_mem_alloc(const char *func, int line, void *old_ptr, void *ptr, size_t size) { size_t i = 0; int rc; if (dbg_mem == nullptr) { return; } else if (ptr == nullptr) { DBG_MEM_ERR("invalid memory address: %p", ptr); return; } if ((rc = pthread_mutex_lock(&(dbg_mem->mutex))) != 0) { DBG_MEM_ERR("cannot lock mutex: %s", otc_strerror(rc)); return; } if (old_ptr != nullptr) { /* Reallocating memory. */ struct otc_dbg_mem_metadata *metadata = OT_CAST_TYPEOF(metadata, ptr); if (metadata == nullptr) { DBG_MEM_ERR("no metadata: MEM_REALLOC %s:%d(%p -> %p %zu)", func, line, old_ptr, DBG_MEM_PTR(ptr), size); } else if (metadata->data == nullptr) { DBG_MEM_ERR("invalid metadata: MEM_REALLOC %s:%d(%p -> %p %zu)", func, line, old_ptr, DBG_MEM_PTR(ptr), size); } else if (metadata->data == OT_CAST_TYPEOF(metadata->data, metadata)) { DBG_MEM_ERR("unset metadata: MEM_REALLOC %s:%d(%p -> %p %zu)", func, line, old_ptr, DBG_MEM_PTR(ptr), size); } else if (metadata->magic != DBG_MEM_MAGIC) { DBG_MEM_ERR("invalid magic: MEM_REALLOC %s:%d(%p -> %p %zu) 0x%016" PRIu64, func, line, old_ptr, DBG_MEM_PTR(ptr), size, metadata->magic); } else if (metadata->data->used && (metadata->data->ptr == DBG_MEM_DATA(old_ptr))) { DBG_MEM_INFO(1, "MEM_REALLOC: %s:%d(%p %zu -> %p %zu)", func, line, old_ptr, metadata->data->size, DBG_MEM_PTR(ptr), size); dbg_mem->size -= metadata->data->size; otc_dbg_mem_add(func, line, ptr, size, metadata->data, 1); } } else { otc_dbg_set_metadata(ptr, nullptr); /* * The first attempt is to find a location that has not been * used at all so far. If such is not found, an attempt is * made to find the first available location. */ if (dbg_mem->unused < dbg_mem->count) { i = dbg_mem->unused++; } else { do { if (dbg_mem->reused >= dbg_mem->count) dbg_mem->reused = 0; if (!dbg_mem->data[dbg_mem->reused].used) { i = dbg_mem->reused++; break; } dbg_mem->reused++; } while (++i <= dbg_mem->count); } if (i < dbg_mem->count) { DBG_MEM_INFO(1, "MEM_ALLOC: %s:%d(%p %zu %zu)", func, line, DBG_MEM_PTR(ptr), size, i); otc_dbg_mem_add(func, line, ptr, size, dbg_mem->data + i, 0); } } if ((rc = pthread_mutex_unlock(&(dbg_mem->mutex))) != 0) { DBG_MEM_ERR("cannot unlock mutex: %s", otc_strerror(rc)); return; } if (i >= dbg_mem->count) DBG_MEM_ERR("alloc overflow: %s:%d(%p -> %p %zu)", func, line, old_ptr, DBG_MEM_PTR(ptr), size); } /*** * NAME * otc_dbg_mem_release - * * ARGUMENTS * func - * line - * ptr - the address of the data returned to the program * op_idx - * * DESCRIPTION * - * * RETURN VALUE * This function does not return a value. */ static void otc_dbg_mem_release(const char *func, int line, void *ptr, int op_idx) { struct otc_dbg_mem_metadata *metadata; bool flag_invalid = 0; size_t i; int rc; if (dbg_mem == nullptr) { return; } else if (ptr == nullptr) { DBG_MEM_ERR("invalid memory address: %p", ptr); return; } if ((rc = pthread_mutex_lock(&(dbg_mem->mutex))) != 0) { DBG_MEM_ERR("cannot lock mutex: %s", otc_strerror(rc)); return; } metadata = DBG_MEM_DATA(ptr); if (metadata == nullptr) { DBG_MEM_ERR("no metadata: MEM_%s %s:%d(%p)", (op_idx == 2) ? "FREE" : "RELEASE", func, line, ptr); } else if (metadata->data == nullptr) { DBG_MEM_ERR("invalid metadata: MEM_%s %s:%d(%p)", (op_idx == 2) ? "FREE" : "RELEASE", func, line, ptr); } else if (metadata->data == OT_CAST_TYPEOF(metadata->data, metadata)) { DBG_MEM_ERR("unset metadata: MEM_%s %s:%d(%p)", (op_idx == 2) ? "FREE" : "RELEASE", func, line, ptr); } else if (metadata->magic != DBG_MEM_MAGIC) { DBG_MEM_ERR("invalid magic: MEM_%s %s:%d(%p) 0x%016" PRIu64, (op_idx == 2) ? "FREE" : "RELEASE", func, line, ptr, metadata->magic); } else if (metadata->data->used && (metadata->data->ptr == metadata)) { DBG_MEM_INFO(1, "MEM_%s: %s:%d(%p %zu)", (op_idx == 2) ? "FREE" : "RELEASE", func, line, ptr, metadata->data->size); metadata->data->used = 0; dbg_mem->size -= metadata->data->size; dbg_mem->op_cnt[op_idx]++; } else { flag_invalid = 1; } if ((rc = pthread_mutex_unlock(&(dbg_mem->mutex))) != 0) { DBG_MEM_ERR("cannot unlock mutex: %s", otc_strerror(rc)); return; } if (flag_invalid) { DBG_MEM_ERR("invalid ptr: %s:%d(%p)", func, line, ptr); if (metadata != nullptr) for (i = 0; i < dbg_mem->count; i++) if (dbg_mem->data[i].ptr == metadata) DBG_MEM_ERR("possible previous use: %s %hhu", dbg_mem->data[i].func, dbg_mem->data[i].used); } } /*** * NAME * otc_dbg_malloc - * * ARGUMENTS * func - * line - * size - * * DESCRIPTION * - * * RETURN VALUE * - */ void *otc_dbg_malloc(const char *func, int line, size_t size) { void *retptr; retptr = malloc(DBG_MEM_SIZE(size)); otc_dbg_mem_alloc(func, line, nullptr, retptr, size); return DBG_MEM_RETURN(retptr); } /*** * NAME * otc_dbg_calloc - * * ARGUMENTS * func - * line - * nelem - * elsize - * * DESCRIPTION * - * * RETURN VALUE * - */ void *otc_dbg_calloc(const char *func, int line, size_t nelem, size_t elsize) { void *retptr; retptr = malloc(DBG_MEM_SIZE(nelem * elsize)); if (retptr != nullptr) (void)memset(retptr, 0, DBG_MEM_SIZE(nelem * elsize)); otc_dbg_mem_alloc(func, line, nullptr, retptr, nelem * elsize); return DBG_MEM_RETURN(retptr); } /*** * NAME * otc_dbg_realloc - * * ARGUMENTS * func - * line - * ptr - * size - * * DESCRIPTION * - * * RETURN VALUE * - */ void *otc_dbg_realloc(const char *func, int line, void *ptr, size_t size) { void *retptr; if (ptr == nullptr) { retptr = malloc(DBG_MEM_SIZE(size)); otc_dbg_mem_alloc(func, line, nullptr, retptr, size); } else { struct otc_dbg_mem_metadata *metadata = DBG_MEM_DATA(ptr); /* * If memory is not allocated via these debug functions, it * must not be reallocated via them either. */ if ((metadata == nullptr) || (metadata->data == nullptr) || (metadata->magic != DBG_MEM_MAGIC)) { retptr = realloc(ptr, size); return retptr; } else { retptr = realloc(DBG_MEM_DATA(ptr), DBG_MEM_SIZE(size)); otc_dbg_mem_alloc(func, line, ptr, retptr, size); } } return DBG_MEM_RETURN(retptr); } /*** * NAME * otc_dbg_free - * * ARGUMENTS * func - * line - * ptr - * * DESCRIPTION * - * * RETURN VALUE * This function does not return a value. */ void otc_dbg_free(const char *func, int line, void *ptr) { struct otc_dbg_mem_metadata *metadata; otc_dbg_mem_release(func, line, ptr, 2); metadata = DBG_MEM_DATA(ptr); if ((metadata == nullptr) || (metadata->data == nullptr) || (metadata->magic != DBG_MEM_MAGIC)) free(ptr); else free(DBG_MEM_DATA(ptr)); } /*** * NAME * otc_dbg_strdup - * * ARGUMENTS * func - * line - * s - * * DESCRIPTION * - * * RETURN VALUE * - */ char *otc_dbg_strdup(const char *func, int line, const char *s) { size_t len = 0; char *retptr = nullptr; if (s != nullptr) { len = strlen(s) + 1; retptr = OT_CAST_TYPEOF(retptr, malloc(DBG_MEM_SIZE(len))); if (retptr != nullptr) (void)memcpy(DBG_MEM_PTR(retptr), s, len); } otc_dbg_mem_alloc(func, line, nullptr, retptr, len); return OT_CAST_TYPEOF(retptr, DBG_MEM_RETURN(retptr)); } /*** * NAME * otc_dbg_strndup - * * ARGUMENTS * func - * line - * s - * size - * * DESCRIPTION * - * * RETURN VALUE * - */ char *otc_dbg_strndup(const char *func, int line, const char *s, size_t size) { size_t len = 0; char *retptr = nullptr; if (s != nullptr) { len = strlen(s); len = (len < size) ? len : size; retptr = OT_CAST_TYPEOF(retptr, malloc(DBG_MEM_SIZE(len + 1))); if (retptr != nullptr) { (void)memcpy(DBG_MEM_PTR(retptr), s, len); DBG_MEM_PTR(retptr)[len] = '\0'; } } otc_dbg_mem_alloc(func, line, nullptr, retptr, len + 1); return OT_CAST_TYPEOF(retptr, DBG_MEM_RETURN(retptr)); } /*** * NAME * otc_dbg_mem_init - * * ARGUMENTS * mem - * data - * count - * level - * * DESCRIPTION * - * * RETURN VALUE * - */ int otc_dbg_mem_init(struct otc_dbg_mem *mem, struct otc_dbg_mem_data *data, size_t count, uint8_t level) { pthread_mutexattr_t attr; int rc, retval = -1; if ((mem == nullptr) || (data == nullptr) || (count == 0)) return retval; (void)memset(mem, 0, sizeof(*mem)); (void)memset(data, 0, sizeof(*data) * count); dbg_mem = mem; dbg_mem->data = data; dbg_mem->count = count; dbg_mem->level = level; if ((rc = pthread_mutexattr_init(&attr)) == 0) if ((rc = pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE)) == 0) if ((rc = pthread_mutex_init(&(dbg_mem->mutex), &attr)) == 0) retval = 0; return retval; } /*** * NAME * otc_dbg_mem_disable - * * ARGUMENTS * This function takes no arguments. * * DESCRIPTION * - * * RETURN VALUE * This function does not return a value. */ void otc_dbg_mem_disable(void) { if (dbg_mem == nullptr) return; (void)pthread_mutex_destroy(&(dbg_mem->mutex)); dbg_mem = nullptr; } /*** * NAME * otc_dbg_mem_info - * * ARGUMENTS * This function takes no arguments. * * DESCRIPTION * - * * RETURN VALUE * This function does not return a value. */ void otc_dbg_mem_info(void) { #ifdef HAVE_MALLINFO struct mallinfo mi; #endif size_t i, n = 0; uint64_t size = 0; if (dbg_mem == nullptr) return; DBG_MEM_INFO(0, "--- Memory info -------------------------------------"); DBG_MEM_INFO(0, " alloc/realloc: %" PRIu64 "/%" PRIu64 ", free/release: %" PRIu64 "/%" PRIu64, dbg_mem->op_cnt[0], dbg_mem->op_cnt[1], dbg_mem->op_cnt[2], dbg_mem->op_cnt[3]); DBG_MEM_INFO(0, " unused: %zu, reused: %zu, count: %zu", dbg_mem->unused, dbg_mem->reused, dbg_mem->count); for (i = 0; i < dbg_mem->count; i++) if (dbg_mem->data[i].used) { DBG_MEM_INFO(0, " %zu %s(%p %zu)", n, dbg_mem->data[i].func, dbg_mem->data[i].ptr, dbg_mem->data[i].size); size += dbg_mem->data[i].size; n++; } if (n > 0) DBG_MEM_INFO(0, " allocated %zu byte(s) in %zu chunk(s)", size, n); if (dbg_mem->size != size) DBG_MEM_INFO(0, " size does not match: %zu != %zu", dbg_mem->size, size); #ifdef HAVE_MALLINFO mi = mallinfo(); DBG_MEM_INFO(0, "--- Memory space usage ------------------------------"); DBG_MEM_INFO(0, " Total non-mmapped bytes: %" PRI_MI, mi.arena); DBG_MEM_INFO(0, " # of free chunks: %" PRI_MI, mi.ordblks); DBG_MEM_INFO(0, " # of free fastbin blocks: %" PRI_MI, mi.smblks); DBG_MEM_INFO(0, " Bytes in mapped regions: %" PRI_MI, mi.hblkhd); DBG_MEM_INFO(0, " # of mapped regions: %" PRI_MI, mi.hblks); DBG_MEM_INFO(0, " Max. total allocated space: %" PRI_MI, mi.usmblks); DBG_MEM_INFO(0, " Free bytes held in fastbins: %" PRI_MI, mi.fsmblks); DBG_MEM_INFO(0, " Total allocated space: %" PRI_MI, mi.uordblks); DBG_MEM_INFO(0, " Total free space: %" PRI_MI, mi.fordblks); DBG_MEM_INFO(0, " Topmost releasable block: %" PRI_MI, mi.keepcost); #endif } /*** * NAME * otc_dbg_memdup - * * ARGUMENTS * func - * line - * s - * size - * * DESCRIPTION * - * * RETURN VALUE * - */ void *otc_dbg_memdup(const char *func, int line, const void *s, size_t size) { void *retptr = nullptr; if (s != nullptr) { retptr = malloc(DBG_MEM_SIZE(size + 1)); if (retptr != nullptr) { (void)memcpy(DBG_MEM_PTR(retptr), s, size); DBG_MEM_PTR(retptr)[size] = '\0'; } } otc_dbg_mem_alloc(func, line, nullptr, retptr, size); return DBG_MEM_RETURN(retptr); } /* * Local variables: * c-indent-level: 8 * c-basic-offset: 8 * End: * * vi: noexpandtab shiftwidth=8 tabstop=8 */ opentracing-c-wrapper-1.1.3/src/export.map000066400000000000000000000004311413214572300205320ustar00rootroot00000000000000{ global: otc_tracer_init; otc_tracer_load; otc_tracer_start; otc_tracer_global; otc_tracer_init_global; otc_text_map_new; otc_text_map_add; otc_text_map_destroy; otc_binary_data_new; otc_binary_data_destroy; otc_ext_init; otc_file_read; otc_statistics; local: *; }; opentracing-c-wrapper-1.1.3/src/export_dbg.map000066400000000000000000000007151413214572300213530ustar00rootroot00000000000000{ global: otc_tracer_init; otc_tracer_load; otc_tracer_start; otc_tracer_global; otc_tracer_init_global; otc_text_map_new; otc_text_map_add; otc_text_map_destroy; otc_binary_data_new; otc_binary_data_destroy; otc_ext_init; otc_file_read; otc_statistics; otc_dbg_calloc; otc_dbg_free; otc_dbg_malloc; otc_dbg_mem_disable; otc_dbg_mem_info; otc_dbg_mem_init; otc_dbg_memdup; otc_dbg_realloc; otc_dbg_strdup; otc_dbg_strndup; local: *; }; opentracing-c-wrapper-1.1.3/src/span.cpp000066400000000000000000000307471413214572300201740ustar00rootroot00000000000000/*** * Copyright 2020 HAProxy Technologies * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT 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 "include.h" #ifdef OT_THREADS_NO_LOCKING thread_local Handle ot_span_handle; thread_local Handle ot_span_context_handle; struct HandleData ot_span; struct HandleData ot_span_context; #else struct Handle ot_span; struct Handle ot_span_context; #endif /* OT_THREADS_NO_LOCKING */ /*** * NAME * ot_span_finish_with_options - * * ARGUMENTS * span - * options - * * DESCRIPTION * - * * RETURN VALUE * This function does not return a value. */ static void ot_span_finish_with_options(struct otc_span *span, const struct otc_finish_span_options *options) { OT_LOCK_GUARD(span); if (!OT_SPAN_IS_VALID(span)) return; if (options == nullptr) { ot_span_handle.at(span->idx)->Finish(); } else { struct opentracing::FinishSpanOptions span_options; if (options->finish_time.value.tv_sec > 0) { auto dt = timespec_to_duration(&(options->finish_time.value)); span_options.finish_steady_timestamp = std::chrono::time_point(dt); } if (options->log_records != nullptr) { for (int i = 0; i < options->num_log_records; i++) { struct opentracing::LogRecord record; if (options->log_records[i].timestamp.value.tv_sec > 0) { #ifdef __clang__ auto dt = timespec_to_duration_us(&(options->log_records[i].timestamp.value)); #else auto dt = timespec_to_duration(&(options->log_records[i].timestamp.value)); #endif record.timestamp = std::chrono::time_point(dt); } for (int j = 0; j < options->log_records[i].num_fields; j++) if (options->log_records[i].fields[j].value.type == otc_value_bool) { record.fields.push_back(std::make_pair(options->log_records[i].fields[j].key, options->log_records[i].fields[j].value.value.bool_value)); } else if (options->log_records[i].fields[j].value.type == otc_value_double) { record.fields.push_back(std::make_pair(options->log_records[i].fields[j].key, options->log_records[i].fields[j].value.value.double_value)); } else if (options->log_records[i].fields[j].value.type == otc_value_int64) { record.fields.push_back(std::make_pair(options->log_records[i].fields[j].key, options->log_records[i].fields[j].value.value.int64_value)); } else if (options->log_records[i].fields[j].value.type == otc_value_uint64) { record.fields.push_back(std::make_pair(options->log_records[i].fields[j].key, options->log_records[i].fields[j].value.value.uint64_value)); } else if (options->log_records[i].fields[j].value.type == otc_value_string) { std::string str_value = options->log_records[i].fields[j].value.value.string_value; record.fields.push_back(std::make_pair(options->log_records[i].fields[j].key, str_value)); } else if (options->log_records[i].fields[j].value.type == otc_value_null) { record.fields.push_back(std::make_pair(options->log_records[i].fields[j].key, nullptr)); } span_options.log_records.push_back(record); } } ot_span_handle.at(span->idx)->FinishWithOptions(span_options); } ot_nolock_span_destroy(&span); } /*** * NAME * ot_span_finish - * * ARGUMENTS * span - * * DESCRIPTION * - * * RETURN VALUE * This function does not return a value. */ static void ot_span_finish(struct otc_span *span) { ot_span_finish_with_options(span, nullptr); } /*** * NAME * ot_span_get_context - * * ARGUMENTS * span - * * DESCRIPTION * - * * RETURN VALUE * - */ static struct otc_span_context *ot_span_get_context(struct otc_span *span) { OT_LOCK(span, span_context); if (!OT_SPAN_IS_VALID(span)) return nullptr; return ot_span_context_new(span); } /*** * NAME * ot_span_set_operation_name - * * ARGUMENTS * span - * operation_name - * * DESCRIPTION * - * * RETURN VALUE * This function does not return a value. */ static void ot_span_set_operation_name(struct otc_span *span, const char *operation_name) { OT_LOCK_GUARD(span); if (!OT_SPAN_IS_VALID(span) || (operation_name == nullptr)) return; ot_span_handle.at(span->idx)->SetOperationName(operation_name); } /*** * NAME * ot_span_set_tag - * * ARGUMENTS * span - * key - * value - * * DESCRIPTION * - * * RETURN VALUE * This function does not return a value. */ static void ot_span_set_tag(struct otc_span *span, const char *key, const struct otc_value *value) { OT_LOCK_GUARD(span); if (!OT_SPAN_IS_VALID(span) || (key == nullptr) || (value == nullptr)) return; if (value->type == otc_value_bool) { ot_span_handle.at(span->idx)->SetTag(key, value->value.bool_value); } else if (value->type == otc_value_double) { ot_span_handle.at(span->idx)->SetTag(key, value->value.double_value); } else if (value->type == otc_value_int64) { ot_span_handle.at(span->idx)->SetTag(key, value->value.int64_value); } else if (value->type == otc_value_uint64) { ot_span_handle.at(span->idx)->SetTag(key, value->value.uint64_value); } else if (value->type == otc_value_string) { std::string str_value = value->value.string_value; ot_span_handle.at(span->idx)->SetTag(key, str_value); } else if (value->type == otc_value_null) { ot_span_handle.at(span->idx)->SetTag(key, nullptr); } else { /* Do nothing. */ } } /*** * NAME * ot_span_log_fields - * * ARGUMENTS * span - * fields - * num_fields - * * DESCRIPTION * - * * RETURN VALUE * This function does not return a value. */ static void ot_span_log_fields(struct otc_span *span, const struct otc_log_field *fields, int num_fields) { OT_LOCK_GUARD(span); std::string str_value[OTC_MAXLOGFIELDS]; if (!OT_SPAN_IS_VALID(span) || (fields == nullptr) || !OT_IN_RANGE(num_fields, 1, OTC_MAXLOGFIELDS)) return; /* XXX The only data type supported in this function is string. */ for (int i = 0; (i < num_fields) && (i < OTC_MAXLOGFIELDS); i++) { if (fields[i].value.type != otc_value_string) str_value[i] = "invalid data type"; else if (fields[i].value.value.string_value != nullptr) str_value[i] = fields[i].value.value.string_value; else str_value[i] = ""; } if (num_fields == 1) ot_span_handle.at(span->idx)->Log({ OT_LF(0) }); else if (num_fields == 2) ot_span_handle.at(span->idx)->Log({ OT_LF(0), OT_LF(1) }); else if (num_fields == 3) ot_span_handle.at(span->idx)->Log({ OT_LF(0), OT_LF(1), OT_LF(2) }); else if (num_fields == 4) ot_span_handle.at(span->idx)->Log({ OT_LF(0), OT_LF(1), OT_LF(2), OT_LF(3) }); else if (num_fields == 5) ot_span_handle.at(span->idx)->Log({ OT_LF(0), OT_LF(1), OT_LF(2), OT_LF(3), OT_LF(4) }); else if (num_fields == 6) ot_span_handle.at(span->idx)->Log({ OT_LF(0), OT_LF(1), OT_LF(2), OT_LF(3), OT_LF(4), OT_LF(5) }); else if (num_fields == 7) ot_span_handle.at(span->idx)->Log({ OT_LF(0), OT_LF(1), OT_LF(2), OT_LF(3), OT_LF(4), OT_LF(5), OT_LF(6) }); else ot_span_handle.at(span->idx)->Log({ OT_LF(0), OT_LF(1), OT_LF(2), OT_LF(3), OT_LF(4), OT_LF(5), OT_LF(6), OT_LF(7) }); } /*** * NAME * ot_span_set_baggage_item - * * ARGUMENTS * span - * key - * value - * * DESCRIPTION * - * * RETURN VALUE * This function does not return a value. */ static void ot_span_set_baggage_item(struct otc_span *span, const char *key, const char *value) { OT_LOCK_GUARD(span); if (!OT_SPAN_IS_VALID(span) || (key == nullptr) || (value == nullptr)) return; ot_span_handle.at(span->idx)->SetBaggageItem(key, value); } /*** * NAME * ot_span_baggage_item - * * ARGUMENTS * span - * key - * * DESCRIPTION * - * * RETURN VALUE * - */ static const char *ot_span_baggage_item(const struct otc_span *span, const char *key) { OT_LOCK_GUARD(span); const char *retptr = ""; if (!OT_SPAN_IS_VALID(span) || (key == nullptr)) return retptr; auto baggage = ot_span_handle.at(span->idx)->BaggageItem(key); if (!baggage.empty()) retptr = OTC_DBG_STRDUP(baggage.c_str()); return retptr; } /*** * NAME * ot_span_tracer - * * ARGUMENTS * span - NOT USED * * DESCRIPTION * - NOT IMPLEMENTED * * RETURN VALUE * - */ static struct otc_tracer *ot_span_tracer(const struct otc_span *span) { struct otc_tracer *retptr = nullptr; if (!OT_SPAN_IS_VALID(span)) return retptr; return retptr; } /*** * NAME * ot_nolock_span_destroy - * * ARGUMENTS * span - * * DESCRIPTION * - * * RETURN VALUE * This function does not return a value. */ void ot_nolock_span_destroy(struct otc_span **span) { if ((span == nullptr) || ((*span) == nullptr)) return; if (OT_SPAN_KEY_IS_VALID(*span)) { ot_span_handle.erase((*span)->idx); ot_span.erase_cnt++; } ot_span.destroy_cnt++; OT_EXT_FREE_CLEAR(*span); } /*** * NAME * ot_span_destroy - * * ARGUMENTS * span - * * DESCRIPTION * - * * RETURN VALUE * This function does not return a value. */ static void ot_span_destroy(struct otc_span **span) { OT_LOCK_GUARD(span); ot_nolock_span_destroy(span); } /*** * NAME * ot_span_new - * * ARGUMENTS * This function takes no arguments. * * DESCRIPTION * - * * RETURN VALUE * - */ struct otc_span *ot_span_new(void) { const static struct otc_span span_init = { .idx = 0, .finish = ot_span_finish, /* lock span */ .finish_with_options = ot_span_finish_with_options, /* lock span */ .span_context = ot_span_get_context, /* lock span and span_context */ .set_operation_name = ot_span_set_operation_name, /* lock span */ .set_tag = ot_span_set_tag, /* lock span */ .log_fields = ot_span_log_fields, /* lock span */ .set_baggage_item = ot_span_set_baggage_item, /* lock span */ .baggage_item = ot_span_baggage_item, /* lock span */ .tracer = ot_span_tracer, /* NOT IMPLEMENTED */ .destroy = ot_span_destroy /* lock span */ }; int64_t idx = ot_span.key++; struct otc_span *retptr; if (idx == 0) { ot_span_handle.clear(); ot_span_handle.reserve(8192); } if ((retptr = OT_CAST_TYPEOF(retptr, OT_EXT_MALLOC(sizeof(*retptr)))) != nullptr) { (void)memcpy(retptr, &span_init, sizeof(*retptr)); retptr->idx = idx; } else { ot_span.alloc_fail_cnt++; } return retptr; } /*** * NAME * ot_nolock_span_context_destroy - * * ARGUMENTS * context - * * DESCRIPTION * - * * RETURN VALUE * This function does not return a value. */ static void ot_nolock_span_context_destroy(struct otc_span_context **context) { if ((context == nullptr) || (*context == nullptr)) return; if (OT_CTX_KEY_IS_VALID(*context)) { ot_span_context_handle.erase((*context)->idx); ot_span_context.erase_cnt++; } ot_span_context.destroy_cnt++; OT_EXT_FREE_CLEAR(*context); } /*** * NAME * ot_span_context_destroy - * * ARGUMENTS * context - * * DESCRIPTION * - * * RETURN VALUE * This function does not return a value. */ static void ot_span_context_destroy(struct otc_span_context **context) { OT_LOCK_GUARD(span_context); ot_nolock_span_context_destroy(context); } /*** * NAME * ot_span_context_new - * * ARGUMENTS * span - * * DESCRIPTION * - * * RETURN VALUE * - */ struct otc_span_context *ot_span_context_new(const struct otc_span *span) { int64_t idx = ot_span_context.key++; struct otc_span_context *retptr; if (idx == 0) { ot_span_context_handle.clear(); ot_span_context_handle.reserve(8192); } if ((retptr = OT_CAST_TYPEOF(retptr, OT_EXT_MALLOC(sizeof(*retptr)))) == nullptr) { ot_span_context.alloc_fail_cnt++; return retptr; } retptr->idx = (span == nullptr) ? idx : -1; retptr->span = span; retptr->destroy = ot_span_context_destroy; /* lock span_context */ return retptr; } /* * Local variables: * c-indent-level: 8 * c-basic-offset: 8 * End: * * vi: noexpandtab shiftwidth=8 tabstop=8 */ opentracing-c-wrapper-1.1.3/src/tracer.cpp000066400000000000000000000544311413214572300205070ustar00rootroot00000000000000/*** * Copyright 2020 HAProxy Technologies * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT 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 "include.h" static std::unique_ptr ot_dynlib = nullptr; static std::shared_ptr ot_tracer = nullptr; /*** * NAME * ot_tracer_load - * * ARGUMENTS * library - * errbuf - * errbufsiz - * handle - * * DESCRIPTION * - * * RETURN VALUE * - */ static int ot_tracer_load(const char *library, char *errbuf, int errbufsiz, opentracing::DynamicTracingLibraryHandle &handle) { std::string errmsg; /* Load the tracer library. */ auto handle_maybe = opentracing::DynamicallyLoadTracingLibrary(library, errmsg); if (!handle_maybe) { (void)snprintf(errbuf, errbufsiz, "Failed to load tracing library: %s", errmsg.empty() ? handle_maybe.error().message().c_str() : errmsg.c_str()); return -1; } handle = std::move(*handle_maybe); return 0; } /*** * NAME * ot_tracer_start - * * ARGUMENTS * config - * errbuf - * errbufsiz - * tracer - * * DESCRIPTION * - * * RETURN VALUE * - */ static int ot_tracer_start(const char *config, char *errbuf, int errbufsiz, std::shared_ptr &tracer) { std::string errmsg; auto &tracer_factory = ot_dynlib->tracer_factory(); /* Create a tracer with the requested configuration. */ auto tracer_maybe = tracer_factory.MakeTracer(config, errmsg); if (!tracer_maybe) { (void)snprintf(errbuf, errbufsiz, "Failed to construct tracer: %s", errmsg.empty() ? tracer_maybe.error().message().c_str() : errmsg.c_str()); return -1; } tracer = std::move(*tracer_maybe); return 0; } /*** * NAME * ot_tracer_close - * * ARGUMENTS * tracer - * * DESCRIPTION * - * * RETURN VALUE * This function does not return a value. */ static void ot_tracer_close(struct otc_tracer *tracer) { if (tracer == nullptr) return; if (ot_dynlib == nullptr) return; if (ot_tracer != nullptr) ot_tracer->Close(); tracer->destroy(&tracer); } /*** * NAME * ot_tracer_start_span_with_options - * * ARGUMENTS * tracer - NOT USED * operation_name - * options - * * DESCRIPTION * - * * RETURN VALUE * - */ static struct otc_span *ot_tracer_start_span_with_options(struct otc_tracer *tracer, const char *operation_name, const struct otc_start_span_options *options) { OT_LOCK_GUARD(span); std::unique_ptr span_maybe = nullptr; struct otc_span *retptr = nullptr; if (ot_tracer == nullptr) return retptr; else if ((tracer == nullptr) || (operation_name == nullptr)) return retptr; /* Allocating memory for the span. */ if ((retptr = ot_span_new()) == nullptr) return retptr; if (options == nullptr) { span_maybe = ot_tracer->StartSpan(operation_name); } else { struct opentracing::StartSpanOptions span_options; if (options->start_time_steady.value.tv_sec > 0) { auto dt = timespec_to_duration(&(options->start_time_steady.value)); span_options.start_steady_timestamp = std::chrono::time_point(dt); } if (options->start_time_system.value.tv_sec > 0) { #ifdef __clang__ auto dt = timespec_to_duration_us(&(options->start_time_system.value)); #else auto dt = timespec_to_duration(&(options->start_time_system.value)); #endif span_options.start_system_timestamp = std::chrono::time_point(dt); } if (options->references != nullptr) { int lock_cnt = 0; for (int i = 0; i < options->num_references; i++) { const opentracing::SpanContext *context = nullptr; if (OT_SPAN_IS_VALID(options->references[i].referenced_context->span)) { context = &(ot_span_handle.at(options->references[i].referenced_context->span->idx)->context()); } else if (OT_CTX_KEY_IS_VALID(options->references[i].referenced_context)) { #ifdef OT_THREADS_NO_LOCKING lock_cnt++; #else if (lock_cnt++ == 0) ot_span_context.mutex.lock(); #endif context = ot_span_context_handle.at(options->references[i].referenced_context->idx).get(); } if (options->references[i].type == otc_span_reference_child_of) span_options.references.push_back(std::make_pair(opentracing::SpanReferenceType::ChildOfRef, context)); else if (options->references[i].type == otc_span_reference_follows_from) span_options.references.push_back(std::make_pair(opentracing::SpanReferenceType::FollowsFromRef, context)); } #ifndef OT_THREADS_NO_LOCKING if (lock_cnt > 0) ot_span_context.mutex.unlock(); #endif } if (options->tags != nullptr) { for (int i = 0; i < options->num_tags; i++) if (options->tags[i].value.type == otc_value_bool) { span_options.tags.push_back(std::make_pair(options->tags[i].key, options->tags[i].value.value.bool_value)); } else if (options->tags[i].value.type == otc_value_double) { span_options.tags.push_back(std::make_pair(options->tags[i].key, options->tags[i].value.value.double_value)); } else if (options->tags[i].value.type == otc_value_int64) { span_options.tags.push_back(std::make_pair(options->tags[i].key, options->tags[i].value.value.int64_value)); } else if (options->tags[i].value.type == otc_value_uint64) { span_options.tags.push_back(std::make_pair(options->tags[i].key, options->tags[i].value.value.uint64_value)); } else if (options->tags[i].value.type == otc_value_string) { std::string str_value = options->tags[i].value.value.string_value; span_options.tags.push_back(std::make_pair(options->tags[i].key, str_value)); } else if (options->tags[i].value.type == otc_value_null) { span_options.tags.push_back(std::make_pair(options->tags[i].key, nullptr)); } } span_maybe = ot_tracer->StartSpanWithOptions(operation_name, span_options); } if (span_maybe != nullptr) ot_span_handle.emplace(retptr->idx, std::move(span_maybe)); else ot_nolock_span_destroy(&retptr); return retptr; } /*** * NAME * ot_tracer_start_span - * * ARGUMENTS * tracer - NOT USED * operation_name - * * DESCRIPTION * - * * RETURN VALUE * - */ static struct otc_span *ot_tracer_start_span(struct otc_tracer *tracer, const char *operation_name) { return ot_tracer_start_span_with_options(tracer, operation_name, nullptr); } /*** * NAME * ot_tracer_inject_text_map - * * ARGUMENTS * tracer - NOT USED * carrier - * span_context - * * DESCRIPTION * - * * RETURN VALUE * - */ static otc_propagation_error_code_t ot_tracer_inject_text_map(struct otc_tracer *tracer, struct otc_text_map_writer *carrier, const struct otc_span_context *span_context) { TextMap text_map; TextMapCarrier text_map_carrier(text_map); opentracing::expected rc; if (ot_tracer == nullptr) return otc_propagation_error_code_invalid_tracer; else if ((tracer == nullptr) || (carrier == nullptr)) return otc_propagation_error_code_invalid_carrier; else if (!OT_CTX_IS_VALID(span_context)) return otc_propagation_error_code_span_context_corrupted; if (OT_SPAN_IS_VALID(span_context->span)) { OT_LOCK_GUARD(span); rc = ot_tracer->Inject(ot_span_handle.at(span_context->span->idx)->context(), text_map_carrier); } else if (OT_CTX_KEY_IS_VALID(span_context)) { OT_LOCK_GUARD(span_context); rc = ot_tracer->Inject(*(ot_span_context_handle.at(span_context->idx)), text_map_carrier); } if (!rc) return otc_propagation_error_code_unknown; else if (text_map.empty()) return otc_propagation_error_code_unknown; else if (otc_text_map_new(&(carrier->text_map), text_map.size()) == nullptr) return otc_propagation_error_code_unknown; for (auto const &it : text_map) if (carrier->set != nullptr) { otc_propagation_error_code_t retval = carrier->set(carrier, it.first.c_str(), it.second.c_str()); if (retval != otc_propagation_error_code_success) return retval; } else if (otc_text_map_add(&(carrier->text_map), it.first.c_str(), 0, it.second.c_str(), 0, OT_CAST_STAT(otc_text_map_flags_t, OTC_TEXT_MAP_DUP_KEY | OTC_TEXT_MAP_DUP_VALUE)) == -1) return otc_propagation_error_code_unknown; return otc_propagation_error_code_success; } /*** * NAME * ot_tracer_inject_http_headers - * * ARGUMENTS * tracer - NOT USED * carrier - * span_context - * * DESCRIPTION * - * * RETURN VALUE * - */ static otc_propagation_error_code_t ot_tracer_inject_http_headers(struct otc_tracer *tracer, struct otc_http_headers_writer *carrier, const struct otc_span_context *span_context) { TextMap text_map; HTTPHeadersCarrier http_headers_carrier(text_map); opentracing::expected rc; if (ot_tracer == nullptr) return otc_propagation_error_code_invalid_tracer; else if ((tracer == nullptr) || (carrier == nullptr)) return otc_propagation_error_code_invalid_carrier; else if (!OT_CTX_IS_VALID(span_context)) return otc_propagation_error_code_span_context_corrupted; if (OT_SPAN_IS_VALID(span_context->span)) { OT_LOCK_GUARD(span); rc = ot_tracer->Inject(ot_span_handle.at(span_context->span->idx)->context(), http_headers_carrier); } else if (OT_CTX_KEY_IS_VALID(span_context)) { OT_LOCK_GUARD(span_context); rc = ot_tracer->Inject(*(ot_span_context_handle.at(span_context->idx)), http_headers_carrier); } if (!rc) return otc_propagation_error_code_unknown; else if (text_map.empty()) return otc_propagation_error_code_unknown; else if (otc_text_map_new(&(carrier->text_map), text_map.size()) == nullptr) return otc_propagation_error_code_unknown; for (auto const &it : text_map) if (carrier->set != nullptr) { otc_propagation_error_code_t retval = carrier->set(carrier, it.first.c_str(), it.second.c_str()); if (retval != otc_propagation_error_code_success) return retval; } else if (otc_text_map_add(&(carrier->text_map), it.first.c_str(), 0, it.second.c_str(), 0, OT_CAST_STAT(otc_text_map_flags_t, OTC_TEXT_MAP_DUP_KEY | OTC_TEXT_MAP_DUP_VALUE)) == -1) return otc_propagation_error_code_unknown; return otc_propagation_error_code_success; } /*** * NAME * ot_tracer_inject_binary - * * ARGUMENTS * tracer - NOT USED * carrier - * span_context - * * DESCRIPTION * - * * RETURN VALUE * - */ static otc_propagation_error_code_t ot_tracer_inject_binary(struct otc_tracer *tracer, struct otc_custom_carrier_writer *carrier, const struct otc_span_context *span_context) { std::ostringstream oss(std::ios::binary); opentracing::expected rc; if (ot_tracer == nullptr) return otc_propagation_error_code_invalid_tracer; else if ((tracer == nullptr) || (carrier == nullptr)) return otc_propagation_error_code_invalid_carrier; else if (!OT_CTX_IS_VALID(span_context)) return otc_propagation_error_code_span_context_corrupted; if (OT_SPAN_IS_VALID(span_context->span)) { OT_LOCK_GUARD(span); rc = ot_tracer->Inject(ot_span_handle.at(span_context->span->idx)->context(), oss); } else if (OT_CTX_KEY_IS_VALID(span_context)) { OT_LOCK_GUARD(span_context); rc = ot_tracer->Inject(*(ot_span_context_handle.at(span_context->idx)), oss); } if (rc) if (otc_binary_data_new(&(carrier->binary_data), oss.str().c_str(), oss.str().size()) != nullptr) return otc_propagation_error_code_success; return otc_propagation_error_code_unknown; } /*** * NAME * ot_tracer_inject_custom - * * ARGUMENTS * tracer - NOT USED * carrier - NOT USED * span_context - NOT USED * * DESCRIPTION * - NOT IMPLEMENTED * * RETURN VALUE * - */ static otc_propagation_error_code_t ot_tracer_inject_custom(struct otc_tracer *tracer, struct otc_custom_carrier_writer *carrier, const struct otc_span_context *span_context) { if ((tracer == nullptr) || (carrier == nullptr)) return otc_propagation_error_code_invalid_carrier; else if (!OT_CTX_IS_VALID(span_context)) return otc_propagation_error_code_span_context_corrupted; return otc_propagation_error_code_success; } /*** * NAME * ot_span_context_add - * * ARGUMENTS * span_context - * span_context_maybe - * * DESCRIPTION * - * * RETURN VALUE * - */ static otc_propagation_error_code_t ot_span_context_add(struct otc_span_context **span_context, std::unique_ptr &span_context_maybe) { OT_LOCK_GUARD(span_context); if ((*span_context = ot_span_context_new(nullptr)) == nullptr) { span_context_maybe.reset(nullptr); return otc_propagation_error_code_unknown; } ot_span_context_handle.emplace((*span_context)->idx, std::move(span_context_maybe)); return otc_propagation_error_code_success; } /*** * NAME * ot_tracer_text_map_add - * * ARGUMENTS * arg - * key - * value - * * DESCRIPTION * - * * RETURN VALUE * - */ static otc_propagation_error_code_t ot_tracer_text_map_add(void *arg, const char *key, const char *value) { TextMap *text_map = OT_CAST_REINTERPRET(TextMap *, arg); if ((arg == nullptr) || (key == nullptr) || (value == nullptr)) return otc_propagation_error_code_unknown; text_map->emplace(key, value); return otc_propagation_error_code_success; } /*** * NAME * ot_tracer_extract_text_map - * * ARGUMENTS * tracer - NOT USED * carrier - * span_context - * * DESCRIPTION * - * * RETURN VALUE * - */ static otc_propagation_error_code_t ot_tracer_extract_text_map(struct otc_tracer *tracer, const struct otc_text_map_reader *carrier, struct otc_span_context **span_context) { TextMap text_map; TextMapCarrier text_map_carrier(text_map); if (ot_tracer == nullptr) return otc_propagation_error_code_invalid_tracer; else if ((tracer == nullptr) || (carrier == nullptr)) return otc_propagation_error_code_invalid_carrier; else if (span_context == nullptr) return otc_propagation_error_code_invalid_span_context; if (carrier->foreach_key != nullptr) { otc_propagation_error_code_t rc = carrier->foreach_key(OT_CAST_CONST(struct otc_text_map_reader *, carrier), ot_tracer_text_map_add, &text_map); if (rc != otc_propagation_error_code_success) return rc; } else { for (size_t i = 0; i < carrier->text_map.count; i++) text_map[carrier->text_map.key[i]] = carrier->text_map.value[i]; } auto span_context_maybe = ot_tracer->Extract(text_map_carrier); if (!span_context_maybe) return otc_propagation_error_code_span_context_not_found; return ot_span_context_add(span_context, *span_context_maybe); } /*** * NAME * ot_tracer_extract_http_headers - * * ARGUMENTS * tracer - NOT USED * carrier - * span_context - * * DESCRIPTION * - * * RETURN VALUE * - */ static otc_propagation_error_code_t ot_tracer_extract_http_headers(struct otc_tracer *tracer, const struct otc_http_headers_reader *carrier, struct otc_span_context **span_context) { TextMap text_map; HTTPHeadersCarrier http_headers_carrier(text_map); if (ot_tracer == nullptr) return otc_propagation_error_code_invalid_tracer; else if ((tracer == nullptr) || (carrier == nullptr)) return otc_propagation_error_code_invalid_carrier; else if (span_context == nullptr) return otc_propagation_error_code_invalid_span_context; if (carrier->foreach_key != nullptr) { otc_propagation_error_code_t rc = carrier->foreach_key(OT_CAST_CONST(struct otc_http_headers_reader *, carrier), ot_tracer_text_map_add, &text_map); if (rc != otc_propagation_error_code_success) return rc; } else { for (size_t i = 0; i < carrier->text_map.count; i++) text_map[carrier->text_map.key[i]] = carrier->text_map.value[i]; } auto span_context_maybe = ot_tracer->Extract(http_headers_carrier); if (!span_context_maybe) return otc_propagation_error_code_span_context_not_found; return ot_span_context_add(span_context, *span_context_maybe); } /*** * NAME * ot_tracer_extract_binary - * * ARGUMENTS * tracer - NOT USED * carrier - * span_context - * * DESCRIPTION * - * * RETURN VALUE * - */ static otc_propagation_error_code_t ot_tracer_extract_binary(struct otc_tracer *tracer, const struct otc_custom_carrier_reader *carrier, struct otc_span_context **span_context) { if (ot_tracer == nullptr) return otc_propagation_error_code_invalid_tracer; else if ((tracer == nullptr) || (carrier == nullptr)) return otc_propagation_error_code_invalid_carrier; else if (span_context == nullptr) return otc_propagation_error_code_invalid_span_context; if ((carrier->binary_data.data == nullptr) || (carrier->binary_data.size == 0)) return otc_propagation_error_code_invalid_carrier; std::string iss_data(OT_CAST_REINTERPRET(const char *, carrier->binary_data.data), carrier->binary_data.size); std::istringstream iss(iss_data, std::ios::binary); auto span_context_maybe = ot_tracer->Extract(iss); if (!span_context_maybe) return otc_propagation_error_code_span_context_not_found; return ot_span_context_add(span_context, *span_context_maybe); } /*** * NAME * ot_tracer_extract_custom - * * ARGUMENTS * tracer - NOT USED * carrier - NOT USED * span_context - NOT USED * * DESCRIPTION * - NOT IMPLEMENTED * * RETURN VALUE * - */ static otc_propagation_error_code_t ot_tracer_extract_custom(struct otc_tracer *tracer, const struct otc_custom_carrier_reader *carrier, struct otc_span_context **span_context) { if ((tracer == nullptr) || (carrier == nullptr) || (span_context == nullptr)) return otc_propagation_error_code_unknown; return otc_propagation_error_code_success; } /*** * NAME * ot_tracer_destroy - * * ARGUMENTS * tracer - * * DESCRIPTION * - * * RETURN VALUE * This function does not return a value. */ static void ot_tracer_destroy(struct otc_tracer **tracer) { if ((tracer == nullptr) || (*tracer == nullptr)) return; OT_FREE_CLEAR(*tracer); } /*** * NAME * ot_tracer_new - * * ARGUMENTS * This function takes no arguments. * * DESCRIPTION * - * * RETURN VALUE * - */ struct otc_tracer *ot_tracer_new(void) { const static struct otc_tracer tracer_init = { .close = ot_tracer_close, /* lock not required */ .start_span = ot_tracer_start_span, /* lock span */ .start_span_with_options = ot_tracer_start_span_with_options, /* lock span */ .inject_text_map = ot_tracer_inject_text_map, /* lock span and/or span_context */ .inject_http_headers = ot_tracer_inject_http_headers, /* lock span and/or span_context */ .inject_binary = ot_tracer_inject_binary, /* lock span and/or span_context */ .inject_custom = ot_tracer_inject_custom, /* NOT IMPLEMENTED */ .extract_text_map = ot_tracer_extract_text_map, /* lock span_context */ .extract_http_headers = ot_tracer_extract_http_headers, /* lock span_context */ .extract_binary = ot_tracer_extract_binary, /* lock span_context */ .extract_custom = ot_tracer_extract_custom, /* NOT IMPLEMENTED */ .destroy = ot_tracer_destroy /* lock not required */ }; struct otc_tracer *retptr; if ((retptr = OT_CAST_TYPEOF(retptr, OTC_DBG_CALLOC(1, sizeof(*retptr)))) != nullptr) (void)memcpy(retptr, &tracer_init, sizeof(*retptr)); return retptr; } /*** * NAME * otc_tracer_load - * * ARGUMENTS * library - * errbuf - * errbufsiz - * * DESCRIPTION * - * * RETURN VALUE * - */ struct otc_tracer *otc_tracer_load(const char *library, char *errbuf, int errbufsiz) { std::unique_ptr handle { new opentracing::DynamicTracingLibraryHandle {} }; std::shared_ptr tracer; struct otc_tracer *retptr = nullptr; if ((retptr = ot_tracer_new()) == nullptr) { /* Do nothing. */; } else if (ot_tracer_load(library, errbuf, errbufsiz, *handle) == -1) { retptr->destroy(&retptr); } else { ot_dynlib = std::move(handle); } return retptr; } /*** * NAME * otc_tracer_start - * * ARGUMENTS * cfgfile - * cfgbuf - * errbuf - * errbufsiz - * * DESCRIPTION * - * * RETURN VALUE * - */ int otc_tracer_start(const char *cfgfile, const char *cfgbuf, char *errbuf, int errbufsiz) { std::shared_ptr tracer; char *config = OT_CAST_CONST(char *, cfgbuf); int retval = -1; if (cfgfile != nullptr) { config = otc_file_read(cfgfile, "#", errbuf, errbufsiz); if (config == nullptr) return retval; } if (ot_tracer_start(config, errbuf, errbufsiz, tracer) == -1) { /* Do nothing. */; } else { ot_tracer = std::move(tracer); (void)opentracing::Tracer::InitGlobal(ot_tracer); retval = 0; } if (config != cfgbuf) OT_FREE(config); return retval; } /*** * NAME * otc_tracer_init - * * ARGUMENTS * library - * cfgfile - * cfgbuf - * errbuf - * errbufsiz - * * DESCRIPTION * - * * RETURN VALUE * - */ struct otc_tracer *otc_tracer_init(const char *library, const char *cfgfile, const char *cfgbuf, char *errbuf, int errbufsiz) { struct otc_tracer *retptr = nullptr; if ((retptr = otc_tracer_load(library, errbuf, errbufsiz)) != nullptr) if (otc_tracer_start(cfgfile, cfgbuf, errbuf, errbufsiz) == -1) retptr->destroy(&retptr); return retptr; } /*** * NAME * otc_tracer_global - * * ARGUMENTS * tracer - NOT USED * * DESCRIPTION * - NOT IMPLEMENTED * * RETURN VALUE * This function does not return a value. */ void otc_tracer_global(struct otc_tracer *tracer) { if (tracer == nullptr) return; } /*** * NAME * otc_tracer_init_global - * * ARGUMENTS * tracer - NOT USED * * DESCRIPTION * - NOT IMPLEMENTED * * RETURN VALUE * This function does not return a value. */ void otc_tracer_init_global(struct otc_tracer *tracer) { if (tracer == nullptr) return; } /* * Local variables: * c-indent-level: 8 * c-basic-offset: 8 * End: * * vi: noexpandtab shiftwidth=8 tabstop=8 */ opentracing-c-wrapper-1.1.3/src/util.cpp000066400000000000000000000237351413214572300202070ustar00rootroot00000000000000/*** * Copyright 2020 HAProxy Technologies * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT 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 "include.h" otc_ext_malloc_t otc_ext_malloc = OT_IFDEF_DBG(otc_dbg_malloc, malloc); otc_ext_free_t otc_ext_free = OT_IFDEF_DBG(otc_dbg_free, free); /*** * NAME * timespec_to_duration_us - * * ARGUMENTS * ts - * * DESCRIPTION * - * * RETURN VALUE * - */ std::chrono::microseconds timespec_to_duration_us(const struct timespec *ts) { auto duration = std::chrono::seconds{ts->tv_sec} + std::chrono::microseconds{ts->tv_nsec / 1000}; return std::chrono::duration_cast(duration); } /*** * NAME * timespec_to_duration - * * ARGUMENTS * ts - * * DESCRIPTION * - * * RETURN VALUE * - */ std::chrono::nanoseconds timespec_to_duration(const struct timespec *ts) { auto duration = std::chrono::seconds{ts->tv_sec} + std::chrono::nanoseconds{ts->tv_nsec}; return std::chrono::duration_cast(duration); } /*** * NAME * otc_ext_init - * * ARGUMENTS * func_malloc - * func_free - * * DESCRIPTION * - * * RETURN VALUE * This function does not return a value. */ void otc_ext_init(otc_ext_malloc_t func_malloc, otc_ext_free_t func_free) { otc_ext_malloc = (func_malloc != nullptr) ? func_malloc : OT_IFDEF_DBG(otc_dbg_malloc, malloc); otc_ext_free = (func_free != nullptr) ? func_free : OT_IFDEF_DBG(otc_dbg_free, free); } /*** * NAME * otc_text_map_new - * * ARGUMENTS * text_map - * size - * * DESCRIPTION * - * * RETURN VALUE * - */ struct otc_text_map *otc_text_map_new(struct otc_text_map *text_map, size_t size) { struct otc_text_map *retptr = text_map; if (retptr == nullptr) retptr = OT_CAST_TYPEOF(retptr, OTC_DBG_CALLOC(1, sizeof(*retptr))); if (retptr != nullptr) { retptr->count = 0; retptr->size = size; retptr->is_dynamic = text_map == nullptr; if (size == 0) /* Do nothing. */; else if ((retptr->key = OT_CAST_TYPEOF(retptr->key, OTC_DBG_CALLOC(size, sizeof(*(retptr->key))))) == nullptr) otc_text_map_destroy(&retptr, OT_CAST_STAT(otc_text_map_flags_t, 0)); else if ((retptr->value = OT_CAST_TYPEOF(retptr->value, OTC_DBG_CALLOC(size, sizeof(*(retptr->value))))) == nullptr) otc_text_map_destroy(&retptr, OT_CAST_STAT(otc_text_map_flags_t, 0)); } return retptr; } /*** * NAME * otc_text_map_add - * * ARGUMENTS * text_map - * key - * key_len - * value - * value_len - * flags - * * DESCRIPTION * - * * RETURN VALUE * - */ int otc_text_map_add(struct otc_text_map *text_map, const char *key, size_t key_len, const char *value, size_t value_len, otc_text_map_flags_t flags) { int retval = -1; if ((text_map == nullptr) || (key == nullptr) || (value == nullptr)) return retval; /* * Check if it is necessary to increase the number of key/value pairs. * The number of pairs is increased by half the current number of pairs * (for example: 8 -> 12 -> 18 -> 27 -> 40 -> 60 ...). */ if (text_map->count >= text_map->size) { typeof(text_map->key) ptr_key; typeof(text_map->value) ptr_value; size_t size_add = (text_map->size > 1) ? (text_map->size / 2) : 1; if ((ptr_key = OT_CAST_TYPEOF(ptr_key, OTC_DBG_REALLOC(text_map->key, OT_TEXT_MAP_SIZE(key, size_add)))) == nullptr) return retval; text_map->key = ptr_key; (void)memset(text_map->key + OT_TEXT_MAP_SIZE(key, 0), 0, sizeof(*(text_map->key)) * size_add); if ((ptr_value = OT_CAST_TYPEOF(ptr_value, OTC_DBG_REALLOC(text_map->value, OT_TEXT_MAP_SIZE(value, size_add)))) == nullptr) return retval; text_map->value = ptr_value; (void)memset(text_map->value + OT_TEXT_MAP_SIZE(value, 0), 0, sizeof(*(text_map->value)) * size_add); text_map->size += size_add; } text_map->key[text_map->count] = (flags & OTC_TEXT_MAP_DUP_KEY) ? ((key_len > 0) ? OTC_DBG_STRNDUP(key, key_len) : OTC_DBG_STRDUP(key)) : OT_CAST_CONST(char *, key); text_map->value[text_map->count] = (flags & OTC_TEXT_MAP_DUP_VALUE) ? ((value_len > 0) ? OTC_DBG_STRNDUP(value, value_len) : OTC_DBG_STRDUP(value)) : OT_CAST_CONST(char *, value); if ((text_map->key[text_map->count] != nullptr) && (text_map->value[text_map->count] != nullptr)) retval = text_map->count; text_map->count++; return retval; } /*** * NAME * otc_text_map_destroy - * * ARGUMENTS * text_map - * flags - * * DESCRIPTION * - * * RETURN VALUE * This function does not return a value. */ void otc_text_map_destroy(struct otc_text_map **text_map, otc_text_map_flags_t flags) { if ((text_map == nullptr) || (*text_map == nullptr)) return; if ((*text_map)->key != nullptr) { if (flags & OTC_TEXT_MAP_FREE_KEY) for (size_t i = 0; i < (*text_map)->count; i++) OT_FREE((*text_map)->key[i]); OT_FREE_CLEAR((*text_map)->key); } if ((*text_map)->value != nullptr) { if (flags & OTC_TEXT_MAP_FREE_VALUE) for (size_t i = 0; i < (*text_map)->count; i++) OT_FREE((*text_map)->value[i]); OT_FREE_CLEAR((*text_map)->value); } if ((*text_map)->is_dynamic) { OT_FREE_CLEAR(*text_map); } else { (*text_map)->count = 0; (*text_map)->size = 0; } } /*** * NAME * otc_binary_data_new - * * ARGUMENTS * binary_data - * data - * size - * * DESCRIPTION * - * * RETURN VALUE * - */ struct otc_binary_data *otc_binary_data_new(struct otc_binary_data *binary_data, const void *data, size_t size) { struct otc_binary_data *retptr = binary_data; if (retptr == nullptr) retptr = OT_CAST_TYPEOF(retptr, OTC_DBG_CALLOC(1, sizeof(*retptr))); if (retptr != nullptr) { retptr->size = size; retptr->is_dynamic = binary_data == nullptr; if ((data == nullptr) || (size == 0)) /* Do nothing. */; else if ((retptr->data = OTC_DBG_MALLOC(size)) != nullptr) (void)memcpy(retptr->data, data, size); else otc_binary_data_destroy(&retptr); } return retptr; } /*** * NAME * otc_binary_data_destroy - * * ARGUMENTS * binary_data - * * DESCRIPTION * - * * RETURN VALUE * This function does not return a value. */ void otc_binary_data_destroy(struct otc_binary_data **binary_data) { if ((binary_data == nullptr) || (*binary_data == nullptr)) return; OT_FREE_CLEAR((*binary_data)->data); if ((*binary_data)->is_dynamic) OT_FREE_CLEAR(*binary_data); else (*binary_data)->size = 0; } /*** * NAME * otc_strerror - * * ARGUMENTS * errnum - * * DESCRIPTION * - * * RETURN VALUE * - */ const char *otc_strerror(int errnum) { static __THR char retbuf[1024]; const char *retptr = retbuf; errno = 0; (void)strerror_r(errnum, retbuf, sizeof(retbuf)); if (errno != 0) retptr = "Unknown error"; return retptr; } /*** * NAME * otc_file_read - * * ARGUMENTS * filename - * comment - * errbuf - * errbufsiz - * * DESCRIPTION * - * * RETURN VALUE * - */ char *otc_file_read(const char *filename, const char *comment, char *errbuf, int errbufsiz) { struct stat statbuf; char *retptr = nullptr; int fd, rc; if (filename == nullptr) return retptr; if ((fd = open(filename, O_RDONLY)) == -1) { (void)snprintf(errbuf, errbufsiz, "'%s': %s", filename, otc_strerror(errno)); } else if ((rc = fstat(fd, &statbuf)) == -1) { (void)snprintf(errbuf, errbufsiz, "'%s': %s", filename, otc_strerror(errno)); } else if ((retptr = OT_CAST_TYPEOF(retptr, OTC_DBG_MALLOC(statbuf.st_size + 1))) == nullptr) { (void)snprintf(errbuf, errbufsiz, "cannot allocate memory: %s", otc_strerror(errno)); } else { char *buf = retptr; off_t size = statbuf.st_size; while (size > 0) { ssize_t n; if ((n = read(fd, buf, size)) > 0) { size -= n; buf += n; } else if (n == -1) { if ((errno == EAGAIN) || (errno == EWOULDBLOCK)) { break; } else if (errno != EINTR) { (void)snprintf(errbuf, errbufsiz, "'%s': %s", filename, otc_strerror(errno)); OT_FREE_CLEAR(retptr); break; } } else { break; } } if (comment != nullptr) { off_t i = 0, c = -1, n = statbuf.st_size; for (i = 0; i < n; i++) if (c < 0) { /* Remember the starting position of the comment line. */ if ((strchr(comment, retptr[i]) != nullptr) && ((i == 0) || (retptr[i - 1] == '\n'))) c = i; } else if ((retptr[i] == '\n') && ((i + 1) < n)) { /* Delete the entire comment line. */ (void)memmove(retptr + c, retptr + i + 1, n - i - 1); n -= i + 1 - c; i = c - 1; c = -1; } /* If a comment remains in the last line, delete it. */ if (c >= 0) { n -= i - c; i = c; } retptr[i] = '\0'; } else if (size != 0) OT_FREE_CLEAR(retptr); } (void)close(fd); return retptr; } /*** * NAME * otc_statistics - * * ARGUMENTS * buffer - * bufsiz - * * DESCRIPTION * - * * RETURN VALUE * This function does not return a value. */ void otc_statistics(char *buffer, size_t bufsiz) { if ((buffer == nullptr) || (bufsiz < 24)) return; (void)snprintf(buffer, bufsiz, "span: %" PRId64 "/%" PRId64 "+%" PRId64 "(%" PRId64 ")/%" PRId64 ", context: %" PRId64 "/%" PRId64 "+%" PRId64 "(%" PRId64 ")/%" PRId64, ot_span.key, ot_span_handle.size(), ot_span.erase_cnt, ot_span.destroy_cnt, ot_span.alloc_fail_cnt, ot_span_context.key, ot_span_context_handle.size(), ot_span_context.erase_cnt, ot_span_context.destroy_cnt, ot_span_context.alloc_fail_cnt); } /* * Local variables: * c-indent-level: 8 * c-basic-offset: 8 * End: * * vi: noexpandtab shiftwidth=8 tabstop=8 */ opentracing-c-wrapper-1.1.3/test/000077500000000000000000000000001413214572300167045ustar00rootroot00000000000000opentracing-c-wrapper-1.1.3/test/Makefile.am000066400000000000000000000016201413214572300207370ustar00rootroot00000000000000## Process this file with automake to produce Makefile.in ## AM_CPPFLAGS = -I\$(top_builddir)/include -I$(srcdir)/../include @OPENTRACING_C_WRAPPER_CPPFLAGS@ AM_CFLAGS = @OPENTRACING_C_WRAPPER_CFLAGS@ AM_LDFLAGS = @OPENTRACING_C_WRAPPER_LDFLAGS@ if WANT_DEBUG bin_PROGRAMS = ot-c-wrapper-test_dbg ot_c_wrapper_test_dbg_SOURCES = opentracing.c test.c util.c ot_c_wrapper_test_dbg_LDADD = -lstdc++ -lm @OPENTRACING_C_WRAPPER_LIBS@ $(top_builddir)/src/libopentracing-c-wrapper_dbg.la ot_c_wrapper_test_dbg_LDFLAGS = @OPENTRACING_C_WRAPPER_LDFLAGS@ else bin_PROGRAMS = ot-c-wrapper-test ot_c_wrapper_test_SOURCES = opentracing.c test.c util.c ot_c_wrapper_test_LDADD = -lstdc++ -lm @OPENTRACING_C_WRAPPER_LIBS@ $(top_builddir)/src/libopentracing-c-wrapper.la ot_c_wrapper_test_LDFLAGS = @OPENTRACING_C_WRAPPER_LDFLAGS@ endif CLEANFILES = a.out ## ## Makefile.am ends here opentracing-c-wrapper-1.1.3/test/cfg-dd.json000066400000000000000000000001521413214572300207210ustar00rootroot00000000000000{ "service": "opentracing-c-wrapper-test", "agent_host": "localhost", "agent_port": 8126 } opentracing-c-wrapper-1.1.3/test/cfg-jaeger.yml000066400000000000000000000025661413214572300214320ustar00rootroot00000000000000service_name: opentracing-c-wrapper-test ### # When using configuration object to instantiate the tracer, the type of # sampling can be selected via sampler.type and sampler.param properties. # Jaeger libraries support the following samplers: # # - Constant (sampler.type=const) sampler always makes the same decision for # all traces. It either samples all traces (sampler.param=1) or none of # them (sampler.param=0). # # - Probabilistic (sampler.type=probabilistic) sampler makes a random sampling # decision with the probability of sampling equal to the value of # sampler.param property. For example, with sampler.param=0.1 approximately # 1 in 10 traces will be sampled. # # - Rate Limiting (sampler.type=ratelimiting) sampler uses a leaky bucket rate # limiter to ensure that traces are sampled with a certain constant rate. # For example, when sampler.param=2.0 it will sample requests with the rate # of 2 traces per second. # # - Remote (sampler.type=remote, which is also the default) sampler consults # Jaeger agent for the appropriate sampling strategy to use in the current # service. This allows controlling the sampling strategies in the services # from a central configuration in Jaeger backend, or even dynamically. # sampler: type: ratelimiting param: 10.0 reporter: logSpans: true localAgentHostPort: localhost:6831 opentracing-c-wrapper-1.1.3/test/cfg-zipkin.json000066400000000000000000000001321413214572300216340ustar00rootroot00000000000000{ "service_name": "opentracing-c-wrapper-test", "collector_host": "localhost" } opentracing-c-wrapper-1.1.3/test/debug.h000066400000000000000000000035241413214572300201470ustar00rootroot00000000000000/*** * Copyright 2020 HAProxy Technologies * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT 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 TEST_DEBUG_H #define TEST_DEBUG_H #define OT_LOG(f,...) (void)printf("[%4d] " f "\n", thread_id(), ##__VA_ARGS__) #ifdef DEBUG enum DBG_LEVEL_enum { DBG_LEVEL_FUNC = 0, /* Function debug level. */ DBG_LEVEL_INFO, /* Generic info level. */ DBG_LEVEL_DEBUG, /* Generic debug level. */ DBG_LEVEL_OT, /* OpenTracing debug level. */ DBG_LEVEL_WORKER, /* Worker debug level. */ DBG_LEVEL_ENABLED, /* This have to be the last entry. */ }; # define OT_FUNC(f,...) \ do { \ if (_nNULL(cfg_debug_level) && (*cfg_debug_level > 0)) \ OT_LOG("%s(" f ")", __func__, ##__VA_ARGS__); \ } while (0) # define OT_DBG(l,f,...) \ do { \ if (_nNULL(cfg_debug_level) && (*cfg_debug_level & (1 << DBG_LEVEL_##l))) \ OT_LOG(" " f, ##__VA_ARGS__); \ } while (0) extern uint8_t *cfg_debug_level; #else # define OT_FUNC(...) do { } while (0) # define OT_DBG(...) do { } while (0) #endif /* DEBUG */ #endif /* TEST_DEBUG_H */ /* * Local variables: * c-indent-level: 8 * c-basic-offset: 8 * End: * * vi: noexpandtab shiftwidth=8 tabstop=8 */ opentracing-c-wrapper-1.1.3/test/define.h000066400000000000000000000035241413214572300203130ustar00rootroot00000000000000/*** * Copyright 2020 HAProxy Technologies * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT 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 TEST_DEFINE_H #define TEST_DEFINE_H #ifdef DEBUG # define OTC_DBG_MEM #endif #ifndef PACKAGE_BUILD # define PACKAGE_BUILD 0 #endif #define OT_USE_INJECT_CB #define OT_USE_EXTRACT_CB #ifdef __linux__ # define PRI_PIDT "d" # define PRI_PTHREADT "lu" #else # define PRI_PIDT "ld" # define PRI_PTHREADT "u" #endif #ifndef MIN # define MIN(a,b) (((a) < (b)) ? (a) : (b)) #endif #define _NULL(a) ((a) == NULL) #define _nNULL(a) ((a) != NULL) #define TABLESIZE(a) ((int)(sizeof(a) / sizeof((a)[0]))) #define IN_RANGE(v,a,b) (((v) >= (a)) && ((v) <= (b))) #define TIMEVAL_DIFF_MS(a,b) (((a)->tv_sec - (b)->tv_sec) * 1000ULL + ((a)->tv_usec - (b)->tv_usec + 500) / 1000) #define TIMEVAL_DIFF_US(a,b) (((a)->tv_sec - (b)->tv_sec) * 1000000ULL + (a)->tv_usec - (b)->tv_usec) #define NIBBLE_TO_HEX(a) ((a) + (((a) < 10) ? '0' : ('a' - 10))) #define SWAP(a,b) do { typeof(a) _a = (a); (a) = (b); (b) = _a; } while (0) #define OT_VARGS(t,v) otc_value_##t, (v) #endif /* TEST_DEFINE_H */ /* * Local variables: * c-indent-level: 8 * c-basic-offset: 8 * End: * * vi: noexpandtab shiftwidth=8 tabstop=8 */ opentracing-c-wrapper-1.1.3/test/get-opentracing-plugins.sh000077500000000000000000000026261413214572300240160ustar00rootroot00000000000000#!/bin/sh # _ARG_DIR="${1:-.}" get () { local _arg_tracer="${1}" local _arg_version="${2}" local _arg_url="${3}" local _arg_file="${4}" local _var_tmpfile="_tmpfile_" local _var_plugin="lib${_arg_tracer}_opentracing_plugin-${_arg_version}.so" test -e "${_var_plugin}" && return 0 wget "https://github.com/${_arg_url}/releases/download/v${_arg_version}/${_arg_file}" -O "${_var_tmpfile}" || { rm "${_var_tmpfile}" return 1 } case "$(file ${_var_tmpfile})" in *shared\ object*) mv "${_var_tmpfile}" "${_var_plugin}" ;; *gzip\ compressed\ data*) gzip -cd "${_var_tmpfile}" > "${_var_plugin}" rm "${_var_tmpfile}" ;; esac } mkdir -p "${_ARG_DIR}" && cd "${_ARG_DIR}" || exit 1 get dd 1.1.2 DataDog/dd-opentracing-cpp linux-amd64-libdd_opentracing_plugin.so.gz get dd 1.2.0 DataDog/dd-opentracing-cpp linux-amd64-libdd_opentracing_plugin.so.gz get jaeger 0.4.2 jaegertracing/jaeger-client-cpp libjaegertracing_plugin.linux_amd64.so #et jaeger 0.5.0 jaegertracing/jaeger-client-cpp libjaegertracing_plugin.linux_amd64.so #et jaeger 0.6.0 jaegertracing/jaeger-client-cpp libjaegertracing_plugin.linux_amd64.so get lightstep 0.12.0 lightstep/lightstep-tracer-cpp linux-amd64-liblightstep_tracer_plugin.so.gz get lightstep 0.13.0 lightstep/lightstep-tracer-cpp linux-amd64-liblightstep_tracer_plugin.so.gz get zipkin 0.5.2 rnburn/zipkin-cpp-opentracing linux-amd64-libzipkin_opentracing_plugin.so.gz opentracing-c-wrapper-1.1.3/test/include.h000066400000000000000000000032341413214572300205020ustar00rootroot00000000000000/*** * Copyright 2020 HAProxy Technologies * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT 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 TEST_INCLUDE_H #define TEST_INCLUDE_H #define _GNU_SOURCE #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #ifdef __linux__ # include #endif #include "config.h" #include "define.h" #include "opentracing-c-wrapper/define.h" #include "opentracing-c-wrapper/dbg_malloc.h" #include "opentracing-c-wrapper/common.h" #include "opentracing-c-wrapper/util.h" #include "opentracing-c-wrapper/value.h" #include "opentracing-c-wrapper/span.h" #include "opentracing-c-wrapper/propagation.h" #include "opentracing-c-wrapper/tracer.h" #include "version.h" #include "debug.h" #include "opentracing.h" #include "util.h" #endif /* TEST_INCLUDE_H */ /* * Local variables: * c-indent-level: 8 * c-basic-offset: 8 * End: * * vi: noexpandtab shiftwidth=8 tabstop=8 */ opentracing-c-wrapper-1.1.3/test/opentracing.c000066400000000000000000000442141413214572300213660ustar00rootroot00000000000000/*** * Copyright 2020 HAProxy Technologies * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT 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 "include.h" static void ot_text_map_show(const struct otc_text_map *text_map) { OT_FUNC("%p", text_map); if (_NULL(text_map)) return; OT_DBG(OT, "%p:{ %p %p %zu/%zu %hhu }", text_map, text_map->key, text_map->value, text_map->count, text_map->size, text_map->is_dynamic); if (_nNULL(text_map->key) && _nNULL(text_map->value) && (text_map->count > 0)) { size_t i; for (i = 0; i < text_map->count; i++) OT_DBG(OT, " \"%s\" -> \"%s\"", text_map->key[i], text_map->value[i]); } } /*** * NAME * ot_span_init - * * ARGUMENTS * operation_name - * ref_type - * ref_ctx_idx - * ref_span - * * DESCRIPTION * - * * RETURN VALUE * - */ struct otc_span *ot_span_init(struct otc_tracer *tracer, const char *operation_name, int ref_type, int ref_ctx_idx, const struct otc_span *ref_span) { struct otc_start_span_options options; struct otc_span_context context = { .idx = ref_ctx_idx, .span = ref_span }; struct otc_span_reference references = { ref_type, &context }; struct otc_span *retptr = NULL; OT_FUNC("%p, \"%s\", %d, %d, %p", tracer, operation_name, ref_type, ref_ctx_idx, ref_span); (void)memset(&options, 0, sizeof(options)); if (IN_RANGE(ref_type, otc_span_reference_child_of, otc_span_reference_follows_from)) { options.references = &references; options.num_references = 1; } retptr = tracer->start_span_with_options(tracer, operation_name, &options); if (_NULL(retptr)) OT_DBG(OT, "cannot init new span"); else OT_DBG(OT, "span %p:%zu initialized", retptr, retptr->idx); return retptr; } /*** * NAME * ot_span_tag - * * ARGUMENTS * span - * key - * type - * value - * * DESCRIPTION * - * * RETURN VALUE * - */ int ot_span_tag(struct otc_span *span, const char *key, int type, ...) { va_list ap; struct otc_value ot_value; int retval = -1; OT_FUNC("%p, \"%s\", %d, ...", span, key, type); if (_NULL(span)) return retval; va_start(ap, type); for (retval = 0; _nNULL(key) && IN_RANGE(type, otc_value_bool, otc_value_null); retval++) { ot_value.type = type; if (type == otc_value_bool) ot_value.value.bool_value = va_arg(ap, typeof(ot_value.value.bool_value)); else if (type == otc_value_double) ot_value.value.double_value = va_arg(ap, typeof(ot_value.value.double_value)); else if (type == otc_value_int64) ot_value.value.int64_value = va_arg(ap, typeof(ot_value.value.int64_value)); else if (type == otc_value_uint64) ot_value.value.uint64_value = va_arg(ap, typeof(ot_value.value.uint64_value)); else if (type == otc_value_string) ot_value.value.string_value = va_arg(ap, typeof(ot_value.value.string_value)); else if (type == otc_value_null) ot_value.value.string_value = va_arg(ap, typeof(ot_value.value.string_value)); span->set_tag(span, key, &ot_value); if (_nNULL(key = va_arg(ap, typeof(key)))) type = va_arg(ap, typeof(type)); } va_end(ap); return retval; } /*** * NAME * ot_span_set_baggage - * * ARGUMENTS * span - * key - * value - * * DESCRIPTION * - * * RETURN VALUE * - */ int ot_span_set_baggage(struct otc_span *span, const char *key, const char *value, ...) { va_list ap; int retval = -1; OT_FUNC("%p, \"%s\", \"%s\", ...", span, key, value); if (_NULL(span)) return retval; va_start(ap, value); for (retval = 0; _nNULL(key); retval++) { OT_DBG(OT, "set baggage: \"%s\" \"%s\"", key, value); span->set_baggage_item(span, key, value); if (_nNULL(key = va_arg(ap, typeof(key)))) value = va_arg(ap, typeof(value)); } va_end(ap); return retval; } /*** * NAME * ot_span_baggage - * * ARGUMENTS * span - * key - * * DESCRIPTION * - * * RETURN VALUE * - */ struct otc_text_map *ot_span_baggage(const struct otc_span *span, const char *key, ...) { va_list ap; struct otc_text_map *retptr = NULL; int i, n; OT_FUNC("%p, \"%s\", ...", span, key); if (_NULL(span) || _NULL(key)) return retptr; va_start(ap, key); for (n = 1; _nNULL(va_arg(ap, typeof(key))); n++); va_end(ap); if (_NULL(retptr = otc_text_map_new(NULL, n))) return retptr; va_start(ap, key); for (i = 0; (i < n) && _nNULL(key); i++) { char *value; if (_nNULL(value = (char *)span->baggage_item(span, key))) { (void)otc_text_map_add(retptr, key, 0, value, 0, OTC_TEXT_MAP_DUP_KEY); OT_DBG(OT, "get baggage[%d]: \"%s\" -> \"%s\"", i, retptr->key[i], retptr->value[i]); } else { OT_DBG(OT, "get baggage[%d]: \"%s\" -> invalid key", i, key); } key = va_arg(ap, typeof(key)); } va_end(ap); return retptr; } /*** * NAME * ot_span_log_kv - * * ARGUMENTS * span - * key - * value - * * DESCRIPTION * - * * RETURN VALUE * - */ int ot_span_log_kv(struct otc_span *span, const char *key, const char *value, ...) { va_list ap; struct otc_log_field log_data[OTC_MAXLOGFIELDS]; int retval = -1; OT_FUNC("%p, \"%s\", \"%s\", ...", span, key, value); if (_NULL(span) || _NULL(key) || _NULL(value)) return retval; va_start(ap, value); for (retval = 0; (retval < TABLESIZE(log_data)) && _nNULL(key); retval++) { log_data[retval].key = key; log_data[retval].value.type = otc_value_string; log_data[retval].value.value.string_value = value; if (_nNULL(key = va_arg(ap, typeof(key)))) value = va_arg(ap, typeof(value)); } va_end(ap); span->log_fields(span, log_data, retval); return retval; } /*** * NAME * ot_span_log - * * ARGUMENTS * span - * key - * format - * * DESCRIPTION * - * * RETURN VALUE * - */ int ot_span_log(struct otc_span *span, const char *key, const char *format, ...) { va_list ap; char value[BUFSIZ]; OT_FUNC("%p, \"%s\", \"%s\", ...", span, key, format); if (_NULL(span) || _NULL(key) || _NULL(format)) return -1; va_start(ap, format); (void)vsnprintf(value, sizeof(value), format, ap); va_end(ap); return ot_span_log_kv(span, key, value, NULL); } #ifdef OT_USE_INJECT_CB /*** * NAME * ot_text_map_writer_set_cb - * * ARGUMENTS * writer - * key - * value - * * DESCRIPTION * - * * RETURN VALUE * - */ static otc_propagation_error_code_t ot_text_map_writer_set_cb(struct otc_text_map_writer *writer, const char *key, const char *value) { otc_propagation_error_code_t retval = otc_propagation_error_code_success; OT_FUNC("%p, \"%s\", \"%s\"", writer, key, value); if (otc_text_map_add(&(writer->text_map), key, 0, value, 0, OTC_TEXT_MAP_DUP_KEY | OTC_TEXT_MAP_DUP_VALUE) == -1) retval = otc_propagation_error_code_unknown; return retval; } #endif /* OT_USE_INJECT_CB */ #ifdef OT_USE_EXTRACT_CB /*** * NAME * ot_text_map_reader_foreach_key_cb - * * ARGUMENTS * reader - * handler - * arg - * * DESCRIPTION * - * * RETURN VALUE * - */ static otc_propagation_error_code_t ot_text_map_reader_foreach_key_cb(struct otc_text_map_reader *reader, otc_propagation_error_code_t (*handler)(void *arg, const char *key, const char *value), void *arg) { size_t i; otc_propagation_error_code_t retval = otc_propagation_error_code_success; OT_FUNC("%p, %p, %p", reader, handler, arg); for (i = 0; (retval == otc_propagation_error_code_success) && (i < reader->text_map.count); i++) { OT_DBG(OT, "\"%s\" -> \"%s\"", reader->text_map.key[i], reader->text_map.value[i]); retval = handler(arg, reader->text_map.key[i], reader->text_map.value[i]); } return retval; } #endif /* OT_USE_EXTRACT_CB */ /*** * NAME * ot_inject_text_map - * * ARGUMENTS * tracer - * span - * carrier - * * DESCRIPTION * - * * RETURN VALUE * - */ struct otc_span_context *ot_inject_text_map(struct otc_tracer *tracer, const struct otc_span *span, struct otc_text_map_writer *carrier) { struct otc_span_context *retptr = NULL; int rc; OT_FUNC("%p, %p, %p", tracer, span, carrier); if (_NULL(span)) return retptr; if (_NULL(retptr = span->span_context((struct otc_span *)span))) return retptr; (void)memset(carrier, 0, sizeof(*carrier)); #ifdef OT_USE_INJECT_CB carrier->set = ot_text_map_writer_set_cb; #endif rc = tracer->inject_text_map(tracer, carrier, retptr); if (rc != otc_propagation_error_code_success) { OT_LOG(" ERROR: inject_text_map() failed: %d", rc); OTC_DBG_FREE(retptr); } else { OT_DBG(OT, "context %p: { %" PRId64 " %p %p }", retptr, retptr->idx, retptr->span, retptr->destroy); } OT_DBG(OT, "carrier %p: { { %p %p %zu/%zu %hhu } %p }", carrier, carrier->text_map.key, carrier->text_map.value, carrier->text_map.count, carrier->text_map.size, carrier->text_map.is_dynamic, carrier->set); ot_text_map_show(&(carrier->text_map)); return retptr; } /*** * NAME * ot_extract_text_map - * * ARGUMENTS * tracer - * carrier - * text_map - * * DESCRIPTION * - * * RETURN VALUE * - */ struct otc_span_context *ot_extract_text_map(struct otc_tracer *tracer, struct otc_text_map_reader *carrier, const struct otc_text_map *text_map) { struct otc_span_context *retptr = NULL; int rc; OT_FUNC("%p, %p, %p", tracer, carrier, text_map); (void)memset(carrier, 0, sizeof(*carrier)); #ifdef OT_USE_EXTRACT_CB carrier->foreach_key = ot_text_map_reader_foreach_key_cb; #endif if (_nNULL(text_map)) (void)memcpy(&(carrier->text_map), text_map, sizeof(carrier->text_map)); OT_DBG(OT, "carrier %p: { { %p %p %zu/%zu %hhu } }", carrier, carrier->text_map.key, carrier->text_map.value, carrier->text_map.count, carrier->text_map.size, carrier->text_map.is_dynamic); rc = tracer->extract_text_map(tracer, carrier, &retptr); if (rc != otc_propagation_error_code_success) { OT_LOG(" ERROR: extract_text_map() failed: %d", rc); OTC_DBG_FREE(retptr); } else if (_nNULL(retptr)) { OT_DBG(OT, "context %p: { %" PRId64 " %p %p }", retptr, retptr->idx, retptr->span, retptr->destroy); } return retptr; } #ifdef OT_USE_INJECT_CB /*** * NAME * ot_http_headers_writer_set_cb - * * ARGUMENTS * writer - * key - * value - * * DESCRIPTION * - * * RETURN VALUE * - */ static otc_propagation_error_code_t ot_http_headers_writer_set_cb(struct otc_http_headers_writer *writer, const char *key, const char *value) { otc_propagation_error_code_t retval = otc_propagation_error_code_success; OT_FUNC("%p, \"%s\", \"%s\"", writer, key, value); if (otc_text_map_add(&(writer->text_map), key, 0, value, 0, OTC_TEXT_MAP_DUP_KEY | OTC_TEXT_MAP_DUP_VALUE) == -1) retval = otc_propagation_error_code_unknown; return retval; } #endif /* OT_USE_INJECT_CB */ #ifdef OT_USE_EXTRACT_CB /*** * NAME * ot_http_headers_reader_foreach_key_cb - * * ARGUMENTS * reader - * handler - * arg - * * DESCRIPTION * - * * RETURN VALUE * - */ static otc_propagation_error_code_t ot_http_headers_reader_foreach_key_cb(struct otc_http_headers_reader *reader, otc_propagation_error_code_t (*handler)(void *arg, const char *key, const char *value), void *arg) { size_t i; otc_propagation_error_code_t retval = otc_propagation_error_code_success; OT_FUNC("%p, %p, %p", reader, handler, arg); for (i = 0; (retval == otc_propagation_error_code_success) && (i < reader->text_map.count); i++) { OT_DBG(OT, "\"%s\" -> \"%s\"", reader->text_map.key[i], reader->text_map.value[i]); retval = handler(arg, reader->text_map.key[i], reader->text_map.value[i]); } return retval; } #endif /* OT_USE_EXTRACT_CB */ /*** * NAME * ot_inject_http_headers - * * ARGUMENTS * tracer - * span - * carrier - * * DESCRIPTION * - * * RETURN VALUE * - */ struct otc_span_context *ot_inject_http_headers(struct otc_tracer *tracer, const struct otc_span *span, struct otc_http_headers_writer *carrier) { struct otc_span_context *retptr = NULL; int rc; OT_FUNC("%p, %p, %p", tracer, span, carrier); if (_NULL(span)) return retptr; if (_NULL(retptr = span->span_context((struct otc_span *)span))) return retptr; (void)memset(carrier, 0, sizeof(*carrier)); #ifdef OT_USE_INJECT_CB carrier->set = ot_http_headers_writer_set_cb; #endif rc = tracer->inject_http_headers(tracer, carrier, retptr); if (rc != otc_propagation_error_code_success) { OT_LOG(" ERROR: inject_http_headers() failed: %d", rc); OTC_DBG_FREE(retptr); } else { OT_DBG(OT, "context %p: { %" PRId64 " %p %p }", retptr, retptr->idx, retptr->span, retptr->destroy); } OT_DBG(OT, "carrier %p: { { %p %p %zu/%zu %hhu } %p }", carrier, carrier->text_map.key, carrier->text_map.value, carrier->text_map.count, carrier->text_map.size, carrier->text_map.is_dynamic, carrier->set); ot_text_map_show(&(carrier->text_map)); return retptr; } /*** * NAME * ot_extract_http_headers - * * ARGUMENTS * tracer - * carrier - * text_map - * * DESCRIPTION * - * * RETURN VALUE * - */ struct otc_span_context *ot_extract_http_headers(struct otc_tracer *tracer, struct otc_http_headers_reader *carrier, const struct otc_text_map *text_map) { struct otc_span_context *retptr = NULL; int rc; OT_FUNC("%p, %p, %p", tracer, carrier, text_map); (void)memset(carrier, 0, sizeof(*carrier)); #ifdef OT_USE_EXTRACT_CB carrier->foreach_key = ot_http_headers_reader_foreach_key_cb; #endif if (_nNULL(text_map)) (void)memcpy(&(carrier->text_map), text_map, sizeof(carrier->text_map)); OT_DBG(OT, "carrier %p: { { %p %p %zu/%zu %hhu } }", carrier, carrier->text_map.key, carrier->text_map.value, carrier->text_map.count, carrier->text_map.size, carrier->text_map.is_dynamic); rc = tracer->extract_http_headers(tracer, carrier, &retptr); if (rc != otc_propagation_error_code_success) { OT_LOG(" ERROR: extract_http_headers() failed: %d", rc); OTC_DBG_FREE(retptr); } else if (_nNULL(retptr)) { OT_DBG(OT, "context %p: { %" PRId64 " %p %p }", retptr, retptr->idx, retptr->span, retptr->destroy); } return retptr; } /*** * NAME * ot_inject_binary - * * ARGUMENTS * tracer - * span - * carrier - * * DESCRIPTION * - * * RETURN VALUE * - */ struct otc_span_context *ot_inject_binary(struct otc_tracer *tracer, const struct otc_span *span, struct otc_custom_carrier_writer *carrier) { struct otc_span_context *retptr = NULL; int rc; OT_FUNC("%p, %p, %p", tracer, span, carrier); if (_NULL(span)) return retptr; if (_NULL(retptr = span->span_context((struct otc_span *)span))) return retptr; (void)memset(carrier, 0, sizeof(*carrier)); rc = tracer->inject_binary(tracer, carrier, retptr); if (rc != otc_propagation_error_code_success) { OT_LOG(" ERROR: inject_binary() failed: %d", rc); OTC_DBG_FREE(retptr); } else { OT_DBG(OT, "context %p: { %" PRId64 " %p %p }", retptr, retptr->idx, retptr->span, retptr->destroy); } OT_DBG(OT, "carrier %p: { { %p %zu %hhu } %p }", carrier, carrier->binary_data.data, carrier->binary_data.size, carrier->binary_data.is_dynamic, carrier->inject); #ifdef DEBUG if (carrier->binary_data.data != NULL) { struct otc_jaeger_trace_context *ctx_jaeger = carrier->binary_data.data; struct otc_dd_trace_context *ctx_dd = carrier->binary_data.data; OT_DBG(OT, "Jaeger trace context: %016" PRIx64 "%016" PRIx64 ":%016" PRIx64 ":%016" PRIx64 ":%02hhx <%s> <%s>", ctx_jaeger->trace_id[0], ctx_jaeger->trace_id[1], ctx_jaeger->span_id, ctx_jaeger->parent_span_id, ctx_jaeger->flags, str_hex(ctx_jaeger->baggage, carrier->binary_data.size - sizeof(*ctx_jaeger)), str_ctrl(ctx_jaeger->baggage, carrier->binary_data.size - sizeof(*ctx_jaeger))); OT_DBG(OT, "DataDog trace context: <%s> <%s>", str_hex(ctx_dd->data, carrier->binary_data.size), str_ctrl(ctx_dd->data, carrier->binary_data.size)); } #endif /* DEBUG */ return retptr; } /*** * NAME * ot_extract_binary - * * ARGUMENTS * tracer - * carrier - * binary_data - * * DESCRIPTION * - * * RETURN VALUE * - */ struct otc_span_context *ot_extract_binary(struct otc_tracer *tracer, struct otc_custom_carrier_reader *carrier, const struct otc_binary_data *binary_data) { struct otc_span_context *retptr = NULL; int rc; OT_FUNC("%p, %p, %p", tracer, carrier, binary_data); (void)memset(carrier, 0, sizeof(*carrier)); if (_nNULL(binary_data) && _nNULL(binary_data->data) && (binary_data->size > 0)) (void)memcpy(&(carrier->binary_data), binary_data, sizeof(carrier->binary_data)); OT_DBG(OT, "carrier %p: { { %p %zu %hhu } %p }", carrier, carrier->binary_data.data, carrier->binary_data.size, carrier->binary_data.is_dynamic, carrier->extract); rc = tracer->extract_binary(tracer, carrier, &retptr); if (rc != otc_propagation_error_code_success) { OT_LOG(" ERROR: extract_binary() failed: %d", rc); OTC_DBG_FREE(retptr); } else if (_nNULL(retptr)) { OT_DBG(OT, "context %p: { %" PRId64 " %p %p }", retptr, retptr->idx, retptr->span, retptr->destroy); } return retptr; } /*** * NAME * ot_span_finish - * * ARGUMENTS * span - * ts_finish - * * DESCRIPTION * - * * RETURN VALUE * This function does not return a value. */ void ot_span_finish(struct otc_span **span, const struct timespec *ts_finish) { struct otc_finish_span_options options; OT_FUNC("%p, %p", span, ts_finish); if (_NULL(span) || _NULL(*span)) return; (void)memset(&options, 0, sizeof(options)); if (_nNULL(ts_finish)) (void)memcpy(&(options.finish_time.value), ts_finish, sizeof(options.finish_time.value)); OT_DBG(OT, "span %p:%zu finished", *span, (*span)->idx); (*span)->finish_with_options(*span, &options); *span = NULL; } /* * Local variables: * c-indent-level: 8 * c-basic-offset: 8 * End: * * vi: noexpandtab shiftwidth=8 tabstop=8 */ opentracing-c-wrapper-1.1.3/test/opentracing.h000066400000000000000000000046411413214572300213730ustar00rootroot00000000000000/*** * Copyright 2020 HAProxy Technologies * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT 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 TEST_OPENTRACING_H #define TEST_OPENTRACING_H struct otc_span *ot_span_init(struct otc_tracer *tracer, const char *operation_name, int ref_type, int ref_ctx_idx, const struct otc_span *ref_span); int ot_span_tag(struct otc_span *span, const char *key, int type, ...); int ot_span_set_baggage(struct otc_span *span, const char *key, const char *value, ...); struct otc_text_map *ot_span_baggage(const struct otc_span *span, const char *key, ...); int ot_span_log_kv(struct otc_span *span, const char *key, const char *value, ...); int ot_span_log(struct otc_span *span, const char *key, const char *format, ...); struct otc_span_context *ot_inject_text_map(struct otc_tracer *tracer, const struct otc_span *span, struct otc_text_map_writer *carrier); struct otc_span_context *ot_extract_text_map(struct otc_tracer *tracer, struct otc_text_map_reader *carrier, const struct otc_text_map *text_map); struct otc_span_context *ot_inject_http_headers(struct otc_tracer *tracer, const struct otc_span *span, struct otc_http_headers_writer *carrier); struct otc_span_context *ot_extract_http_headers(struct otc_tracer *tracer, struct otc_http_headers_reader *carrier, const struct otc_text_map *text_map); struct otc_span_context *ot_inject_binary(struct otc_tracer *tracer, const struct otc_span *span, struct otc_custom_carrier_writer *carrier); struct otc_span_context *ot_extract_binary(struct otc_tracer *tracer, struct otc_custom_carrier_reader *carrier, const struct otc_binary_data *binary_data); void ot_span_finish(struct otc_span **span, const struct timespec *ts_finish); #endif /* TEST_OPENTRACING_H */ /* * Local variables: * c-indent-level: 8 * c-basic-offset: 8 * End: * * vi: noexpandtab shiftwidth=8 tabstop=8 */ opentracing-c-wrapper-1.1.3/test/test.c000066400000000000000000000321221413214572300200270ustar00rootroot00000000000000/*** * Copyright 2020 HAProxy Technologies * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT 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 "include.h" #define DEFAULT_DEBUG_LEVEL 0 #define DEFAULT_THREADS_COUNT 1000 typedef unsigned char bool_t; enum FLAG_OPT_enum { FLAG_OPT_HELP = 0x01, FLAG_OPT_VERSION = 0x02, }; static struct { uint8_t debug_level; uint8_t opt_flags; int runcount; int runtime_ms; int threads; const char *ot_config; const char *ot_plugin; struct otc_tracer *ot_tracer; } cfg = { .debug_level = DEFAULT_DEBUG_LEVEL, .runtime_ms = -1, .threads = DEFAULT_THREADS_COUNT, }; enum OT_SPAN_enum { OT_SPAN_ROOT = 0, OP_SPAN_BAGGAGE, OT_SPAN_PROP_TM, OT_SPAN_PROP_HH, OT_SPAN_PROP_BD, OT_SPAN_MAX, }; struct worker { pthread_t thread; int id; struct otc_span *ot_span[OT_SPAN_MAX]; int ot_state; uint64_t count; }; static struct { const char *name; struct timeval start_time; struct worker worker[8192]; volatile bool_t flag_run; } prg; uint8_t *cfg_debug_level = &(cfg.debug_level); /*** * NAME * thread_id - * * ARGUMENTS * This function takes no arguments. * * DESCRIPTION * - * * RETURN VALUE * - */ int thread_id(void) { pthread_t id; int i; id = pthread_self(); for (i = 0; i < MIN(cfg.threads, TABLESIZE(prg.worker)); i++) if (pthread_equal(prg.worker[i].thread, id)) return i + 1; return 0; } /*** * NAME * worker_finish_all_spans - * * ARGUMENTS * worker - * * DESCRIPTION * - * * RETURN VALUE * - */ static void worker_finish_all_spans(struct worker *worker) { struct timespec ts; int i; OT_FUNC("%p", worker); (void)clock_gettime(CLOCK_MONOTONIC, &ts); for (i = 0; i < TABLESIZE(worker->ot_span); i++) if (_nNULL(worker->ot_span[i])) ot_span_finish(worker->ot_span + i, &ts); } /*** * NAME * worker_thread - * * ARGUMENTS * data - * * DESCRIPTION * - * * RETURN VALUE * - */ __attribute__((noreturn)) static void *worker_thread(void *data) { struct otc_text_map_writer tm_wr; struct otc_http_headers_writer hh_wr; struct otc_custom_carrier_writer cc_wr; struct otc_span_context *context; struct timeval now; char name[16]; struct worker *worker = data; #ifdef DEBUG int n = 0; #endif OT_FUNC("%p", data); #ifdef __linux__ OT_DBG(WORKER, "Worker started, thread id: %" PRI_PTHREADT, syscall(SYS_gettid)); #else OT_DBG(WORKER, "Worker started, thread id: %" PRI_PTHREADT, worker->thread); #endif (void)gettimeofday(&now, NULL); (void)srandom(now.tv_usec); (void)snprintf(name, sizeof(name), "test/wrk: %d", worker->id); (void)pthread_setname_np(worker->thread, name); while (!prg.flag_run) { nsleep(0, 10000000); #ifdef DEBUG n++; #endif } OT_DBG(DEBUG, "waiting loop count: %d", n); for ( ; 1; worker->ot_state++) { if (worker->ot_state != 0) /* Do nothing. */; else if ((cfg.runtime_ms > 0) && (TIMEVAL_DIFF_MS(&now, &(prg.start_time)) >= (uint)cfg.runtime_ms)) break; else if ((cfg.runcount > 0) && ((uint)cfg.runcount <= worker->count)) break; if (worker->ot_state == 0) { worker->ot_span[OT_SPAN_ROOT] = ot_span_init(cfg.ot_tracer, "root span", -1, -1, NULL); } else if (worker->ot_state == 1) { worker->ot_span[OP_SPAN_BAGGAGE] = ot_span_init(cfg.ot_tracer, "span #1", otc_span_reference_child_of, -1, worker->ot_span[OT_SPAN_ROOT]); } else if (worker->ot_state == 2) { (void)ot_span_set_baggage(worker->ot_span[OP_SPAN_BAGGAGE], "baggage_1", "value_1", "baggage_2", "value_2", NULL); } else if (worker->ot_state == 3) { if (_nNULL(context = ot_inject_text_map(cfg.ot_tracer, worker->ot_span[OP_SPAN_BAGGAGE], &tm_wr))) context->destroy(&context); } else if (worker->ot_state == 4) { struct otc_text_map_reader tm_rd; struct otc_text_map *text_map = &(tm_wr.text_map); if (_nNULL(context = ot_extract_text_map(cfg.ot_tracer, &tm_rd, text_map))) { worker->ot_span[OT_SPAN_PROP_TM] = ot_span_init(cfg.ot_tracer, "text map propagation", otc_span_reference_child_of, context->idx, NULL); context->destroy(&context); } otc_text_map_destroy(&text_map, OTC_TEXT_MAP_FREE_KEY | OTC_TEXT_MAP_FREE_VALUE); } else if (worker->ot_state == 5) { struct otc_text_map *baggage = ot_span_baggage(worker->ot_span[OP_SPAN_BAGGAGE], "baggage_1", "baggage_2", NULL); otc_text_map_destroy(&baggage, OTC_TEXT_MAP_FREE_KEY | OTC_TEXT_MAP_FREE_VALUE); } else if (worker->ot_state == 6) { if (_nNULL(context = ot_inject_http_headers(cfg.ot_tracer, worker->ot_span[OP_SPAN_BAGGAGE], &hh_wr))) context->destroy(&context); } else if (worker->ot_state == 7) { struct otc_http_headers_reader hh_rd; struct otc_text_map *text_map = &(hh_wr.text_map); if (_nNULL(context = ot_extract_http_headers(cfg.ot_tracer, &hh_rd, text_map))) { worker->ot_span[OT_SPAN_PROP_HH] = ot_span_init(cfg.ot_tracer, "http headers propagation", otc_span_reference_child_of, context->idx, NULL); context->destroy(&context); } otc_text_map_destroy(&text_map, OTC_TEXT_MAP_FREE_KEY | OTC_TEXT_MAP_FREE_VALUE); } else if (worker->ot_state == 8) { if (_nNULL(context = ot_inject_binary(cfg.ot_tracer, worker->ot_span[OP_SPAN_BAGGAGE], &cc_wr))) context->destroy(&context); } else if (worker->ot_state == 9) { struct otc_custom_carrier_reader cc_rd; struct otc_binary_data *binary_data = &(cc_wr.binary_data); if (_nNULL(context = ot_extract_binary(cfg.ot_tracer, &cc_rd, binary_data))) { worker->ot_span[OT_SPAN_PROP_BD] = ot_span_init(cfg.ot_tracer, "binary data propagation", otc_span_reference_child_of, context->idx, NULL); context->destroy(&context); } otc_binary_data_destroy(&binary_data); } else if (worker->ot_state == 10) { (void)ot_span_tag(worker->ot_span[OT_SPAN_ROOT], "tag_1", OT_VARGS(string, "value_1"), "tag_2", OT_VARGS(string, "value_2"), NULL); } else if (worker->ot_state == 11) { (void)ot_span_log_kv(worker->ot_span[OT_SPAN_PROP_TM], "log_1", "content_1", "log_2", "content_2", NULL); } else { worker_finish_all_spans(worker); worker->ot_state = -1; worker->count++; } nsleep(0, ((random() % 100) + 1) * 10000); (void)gettimeofday(&now, NULL); } pthread_exit(NULL); } /*** * NAME * worker_run - * * ARGUMENTS * This function takes no arguments. * * DESCRIPTION * - * * RETURN VALUE * - */ static int worker_run(void) { struct timeval now; char ot_infbuf[BUFSIZ]; uint64_t total_count = 0; int i, num_threads = 0, retval = EX_OK; OT_FUNC(""); (void)pthread_setname_np(pthread_self(), "test/wrk: main"); for (i = 0; i < cfg.threads; i++) { prg.worker[i].id = i + 1; if (pthread_create(&(prg.worker[i].thread), NULL, worker_thread, prg.worker + i) != 0) (void)fprintf(stderr, "ERROR: Failed to start thread for worker %d: %m\n", prg.worker[i].id); else num_threads++; } prg.flag_run = 1; (void)gettimeofday(&now, NULL); OT_DBG(WORKER, "%d threads started in %llu ms", num_threads, TIMEVAL_DIFF_MS(&now, &(prg.start_time))); for (i = 0; i < cfg.threads; i++) { if (pthread_join(prg.worker[i].thread, NULL) != 0) (void)fprintf(stderr, "ERROR: Failed to join worker thread %d: %m\n", prg.worker[i].id); else OT_LOG("worker %d count: %" PRIu64, i, prg.worker[i].count); total_count += prg.worker[i].count; } OT_LOG("%d worker(s) total count: %" PRIu64, cfg.threads, total_count); cfg.ot_tracer->close(cfg.ot_tracer); otc_statistics(ot_infbuf, sizeof(ot_infbuf)); OT_LOG("OpenTracing statistics: %s", ot_infbuf); return retval; } /*** * NAME * usage - * * ARGUMENTS * program_name - * flag_verbose - * * DESCRIPTION * - * * RETURN VALUE * This function does not return a value. */ static void usage(const char *program_name, bool_t flag_verbose) { (void)printf("\nUsage: %s { -h --help }\n", program_name); (void)printf(" %s { -V --version }\n", program_name); (void)printf(" %s { [ -R --runcount=VALUE ] | [ -r --runtime=TIME ] } [OPTION]...\n\n", program_name); if (flag_verbose) { (void)printf("Options are:\n"); (void)printf(" -c, --config=FILE Specify the configuration for the used tracer.\n"); #ifdef DEBUG (void)printf(" -d, --debug=LEVEL Enable and specify the debug mode level (default: %d).\n", DEFAULT_DEBUG_LEVEL); #endif (void)printf(" -h, --help Show this text.\n"); (void)printf(" -p, --plugin=FILE Specify the OpenTracing compatible plugin library.\n"); (void)printf(" -R, --runcount=VALUE Execute this program a certain number of passes (0 = unlimited).\n"); (void)printf(" -r, --runtime=TIME Run this program for a certain amount of time (ms, 0 = unlimited).\n"); (void)printf(" -t, --threads=VALUE Specify the number of threads (default: %d).\n", DEFAULT_THREADS_COUNT); (void)printf(" -V, --version Show program version.\n\n"); (void)printf("Copyright 2020 HAProxy Technologies\n"); (void)printf("SPDX-License-Identifier: Apache-2.0\n\n"); } else { (void)printf("For help type: %s -h\n\n", program_name); } } int main(int argc, char **argv) { static const struct option longopts[] = { { "config", required_argument, NULL, 'c' }, #ifdef DEBUG { "debug", required_argument, NULL, 'd' }, #endif { "help", no_argument, NULL, 'h' }, { "plugin", required_argument, NULL, 'p' }, { "runcount", required_argument, NULL, 'R' }, { "runtime", required_argument, NULL, 'r' }, { "threads", required_argument, NULL, 't' }, { "version", no_argument, NULL, 'V' }, { NULL, 0, NULL, 0 } }; #ifdef OTC_DBG_MEM static struct otc_dbg_mem_data dbg_mem_data[1000000]; struct otc_dbg_mem dbg_mem; #endif const char *shortopts = "c:d:hp:R:r:t:V"; struct timeval now; int c, longopts_idx = -1, retval = EX_OK; bool_t flag_error = 0; char ot_errbuf[BUFSIZ]; (void)gettimeofday(&(prg.start_time), NULL); prg.name = basename(argv[0]); #ifdef OTC_DBG_MEM retval = otc_dbg_mem_init(&dbg_mem, dbg_mem_data, TABLESIZE(dbg_mem_data), 0xff); if (retval == -1) { (void)fprintf(stderr, "ERROR: cannot initialize memory debugger\n"); return retval; } #endif while ((c = getopt_long(argc, argv, shortopts, longopts, &longopts_idx)) != EOF) { if (c == 'c') cfg.ot_config = optarg; #ifdef DEBUG else if (c == 'd') cfg.debug_level = atoi(optarg) & UINT8_C(0xff); #endif else if (c == 'h') cfg.opt_flags |= FLAG_OPT_HELP; else if (c == 'p') cfg.ot_plugin = optarg; else if (c == 'R') cfg.runcount = atoi(optarg); else if (c == 'r') cfg.runtime_ms = atoi(optarg); else if (c == 't') cfg.threads = atoi(optarg); else if (c == 'V') cfg.opt_flags |= FLAG_OPT_VERSION; else retval = EX_USAGE; } if (cfg.opt_flags & FLAG_OPT_HELP) { usage(prg.name, 1); } else if (cfg.opt_flags & FLAG_OPT_VERSION) { (void)printf("\n%s v%s [build %d] by %s, %s\n\n", prg.name, PACKAGE_VERSION, PACKAGE_BUILD, PACKAGE_AUTHOR, __DATE__); } else { if ((cfg.runcount < 0) && (cfg.runtime_ms < 0)) { (void)fprintf(stderr, "ERROR: run count/time value not set\n"); flag_error = 1; } if (!IN_RANGE(cfg.threads, 1, TABLESIZE(prg.worker))) { (void)fprintf(stderr, "ERROR: invalid number of threads '%d'\n", cfg.threads); flag_error = 1; } if (_NULL(cfg.ot_plugin) || _NULL(cfg.ot_config)) { (void)fprintf(stderr, "ERROR: the OpenTracing configuration not set\n"); flag_error = 1; } if (flag_error) usage(prg.name, 0); } cfg_debug_level = &(cfg.debug_level); OT_FUNC("%d, %p", argc, argv); if (flag_error || (cfg.opt_flags & (FLAG_OPT_HELP | FLAG_OPT_VERSION))) return flag_error ? EX_USAGE : EX_OK; if (_NULL(cfg.ot_tracer = otc_tracer_load(cfg.ot_plugin, ot_errbuf, sizeof(ot_errbuf)))) { (void)fprintf(stderr, "ERROR: %s\n", (*ot_errbuf == '\0') ? "Unable to load tracing library" : ot_errbuf); retval = EX_SOFTWARE; } else if (otc_tracer_start(cfg.ot_config, NULL, ot_errbuf, sizeof(ot_errbuf)) == -1) { (void)fprintf(stderr, "ERROR: %s\n", (*ot_errbuf == '\0') ? "Unable to start tracing" : ot_errbuf); retval = EX_SOFTWARE; } else { retval = worker_run(); } (void)gettimeofday(&now, NULL); OT_DBG(INFO, "Program runtime: %llu ms", TIMEVAL_DIFF_MS(&now, &(prg.start_time))); OTC_DBG_MEMINFO(); return retval; } /* * Local variables: * c-indent-level: 8 * c-basic-offset: 8 * End: * * vi: noexpandtab shiftwidth=8 tabstop=8 */ opentracing-c-wrapper-1.1.3/test/util.c000066400000000000000000000042001413214572300200210ustar00rootroot00000000000000/*** * Copyright 2020 HAProxy Technologies * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT 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 "include.h" /*** * NAME * nsleep - * * ARGUMENTS * sec - * nsec - * * DESCRIPTION * - * * RETURN VALUE * This function does not return a value. */ void nsleep (uint sec, uint nsec) { struct timespec ts1 = { sec, nsec }, ts2, *req = &ts1, *rem = &ts2; while ((nanosleep (req, rem) == -1) && (errno == EINTR)) SWAP(req, rem); } /*** * NAME * str_hex - * * ARGUMENTS * data - * size - * * DESCRIPTION * - * * RETURN VALUE * - */ const char *str_hex(const void *data, size_t size) { static __thread char retbuf[BUFSIZ]; const uint8_t *ptr = data; size_t i; if (_NULL(data)) return "(null)"; else if (size == 0) return "()"; for (i = 0, size <<= 1; (i < (sizeof(retbuf) - 2)) && (i < size); ptr++) { retbuf[i++] = NIBBLE_TO_HEX(*ptr >> 4); retbuf[i++] = NIBBLE_TO_HEX(*ptr & 0x0f); } retbuf[i] = '\0'; return retbuf; } /*** * NAME * str_ctrl - * * ARGUMENTS * data - * size - * * DESCRIPTION * - * * RETURN VALUE * - */ const char *str_ctrl(const void *data, size_t size) { static __thread char retbuf[BUFSIZ]; const uint8_t *ptr = data; size_t i, n = 0; if (_NULL(data)) return "(null)"; else if (size == 0) return "()"; for (i = 0; (n < (sizeof(retbuf) - 1)) && (i < size); i++) retbuf[n++] = IN_RANGE(ptr[i], 0x20, 0x7e) ? ptr[i] : '.'; retbuf[n] = '\0'; return retbuf; } /* * Local variables: * c-indent-level: 8 * c-basic-offset: 8 * End: * * vi: noexpandtab shiftwidth=8 tabstop=8 */ opentracing-c-wrapper-1.1.3/test/util.h000066400000000000000000000017161413214572300200370ustar00rootroot00000000000000/*** * Copyright 2020 HAProxy Technologies * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT 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 TEST_UTIL_H #define TEST_UTIL_H int thread_id(void); void nsleep (uint sec, uint nsec); const char *str_hex(const void *data, size_t size); const char *str_ctrl(const void *data, size_t size); #endif /* TEST_UTIL_H */ /* * Local variables: * c-indent-level: 8 * c-basic-offset: 8 * End: * * vi: noexpandtab shiftwidth=8 tabstop=8 */