diff --git a/CMakeLists.txt b/CMakeLists.txt index 528f626..dddaa3d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -60,9 +60,7 @@ find_package(Gperftools) find_package(Doxygen) if (OPENSSL_FOUND) - list(GET OPENSSL_LIBRARIES 0 openssl_libname) - get_filename_component(OPENSSL_LIBRARY_DIR ${openssl_libname} DIRECTORY) - get_filename_component(OPENSSL_ROOT_DIR ${OPENSSL_LIBRARY_DIR} DIRECTORY) + get_filename_component(OPENSSL_ROOT_DIR ${OPENSSL_INCLUDE_DIR} DIRECTORY) if (APPLE) set (WITH_OPENSSL "--with-openssl=${OPENSSL_ROOT_DIR}") @@ -106,6 +104,12 @@ else () set (BUILD_DOCS OFF) endif () +if (GBENCH_FOUND AND RELEASE_BUILD) + set (BUILD_BENCH ON) +else () + set (BUILD_BENCH OFF) +endif () + option (WITH_CURL "Build with cURL propagation" WITH_CURL) option (WITH_GRPC "Build with gRPC propagation" WITH_GRPC) option (WITH_FPIC "Build with -fPIC for shared library" OFF) @@ -113,6 +117,7 @@ option (WITH_TCMALLOC "Build with tcmalloc library" WITH_TCMALLOC) option (WITH_PROFILER "Build with CPU profiler" WITH_PROFILER) option (SHARED_LIB "Build shared library" OFF) option (BUILD_DOCS "Build API documentation (requires Doxygen)" BUILD_DOCS) +option (BUILD_BENCH "Build benchmark (requires GBench)" BUILD_BENCH) if (RELEASE_BUILD) add_compile_options(-O2) @@ -145,6 +150,7 @@ set (zipkin_DEPENDENCIES ${GFLAGS_LIBRARIES} ${THRIFT_LIBRARIES} ${LibRDKafka_LIBRARIES} + ${LibRDKafka_C_LIBRARIES} ${ZLIB_LIBRARIES} ${OPENSSL_LIBRARIES} ${FOLLY_STATIC_LIBRARY} diff --git a/bench/BenchSpan.cpp b/bench/BenchSpan.cpp index eed35b0..86eb950 100644 --- a/bench/BenchSpan.cpp +++ b/bench/BenchSpan.cpp @@ -1,4 +1,4 @@ -#include +#include #include @@ -231,7 +231,7 @@ void bench_span_serialize_binary(benchmark::State &state) << std::make_pair(zipkin::TraceKeys::CLIENT_SEND, false) << endpoint << std::make_pair(zipkin::TraceKeys::CLIENT_SEND, L"hello world"); - boost::shared_ptr buf(new apache::thrift::transport::TMemoryBuffer()); + std::shared_ptr buf(new apache::thrift::transport::TMemoryBuffer()); apache::thrift::protocol::TBinaryProtocol protocol(buf); while (state.KeepRunning()) @@ -291,4 +291,4 @@ void bench_span_serialize_pretty_json(benchmark::State &state) BENCHMARK(bench_span_serialize_pretty_json); -BENCHMARK_MAIN(); \ No newline at end of file +BENCHMARK_MAIN(); diff --git a/bench/CMakeLists.txt b/bench/CMakeLists.txt index ccda27d..f77f68a 100644 --- a/bench/CMakeLists.txt +++ b/bench/CMakeLists.txt @@ -1,14 +1,16 @@ -set(EXTRA_CXX_FLAGS "${EXTRA_CXX_FLAGS} -std=c++11 -Wno-invalid-offsetof") -set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${EXTRA_CXX_FLAGS}") +if (BUILD_BENCH) + set(EXTRA_CXX_FLAGS "${EXTRA_CXX_FLAGS} -std=c++11 -Wno-invalid-offsetof") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${EXTRA_CXX_FLAGS}") -set (zipkin_bench_SRCS - BenchSpan.cpp - ) + set (zipkin_bench_SRCS + BenchSpan.cpp + ) -add_executable(bench ${zipkin_bench_SRCS}) + add_executable(bench ${zipkin_bench_SRCS}) -target_link_libraries(bench - zipkin - ${zipkin_DEPENDENCIES} - ${GBENCH_LIBRARY} - ) \ No newline at end of file + target_link_libraries(bench + zipkin + ${zipkin_DEPENDENCIES} + ${GBENCH_LIBRARY} + ) +endif () diff --git a/ci/Dockerfile-centos-7 b/ci/Dockerfile-centos-7 new file mode 100644 index 0000000..1ae9b85 --- /dev/null +++ b/ci/Dockerfile-centos-7 @@ -0,0 +1,180 @@ +FROM centos/devtoolset-4-toolchain-centos7 + +USER root + +RUN rpm -Uvh https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm && \ + yum repolist + +RUN yum -y update && \ + yum -y install \ + autoconf \ + autoconf-archive \ + automake \ + boost-devel \ + boost-test \ + bzip2 \ + double-conversion-devel \ + doxygen \ + gflags-devel \ + git \ + glog-devel \ + jemalloc-devel \ + libcurl-devel \ + libdwarf-devel \ + libevent-devel \ + libtool \ + libunwind-devel \ + lz4-devel \ + lzma-sdk457 \ + make \ + openssl-devel \ + scons \ + snappy-devel \ + wget \ + zlib-devel && \ + yum clean all + +RUN scl -l devtoolset-4 && \ + gcc --version && \ + g++ --version + +ENV CMAKE_DIR /cmake +ENV SRC_DIR /source +ENV DIST_DIR /dist +ENV BUILD_DIR /build +ENV EXT_DIR $BUILD_DIR/externals + +ENV CMAKE_VERSION 3.8.2 +RUN wget https://cmake.org/files/v3.8/cmake-$CMAKE_VERSION-Linux-x86_64.tar.gz && \ + mkdir -p $CMAKE_DIR && \ + tar xzvf cmake-$CMAKE_VERSION-Linux-x86_64.tar.gz -C $CMAKE_DIR --strip-components=1 && \ + rm cmake-$CMAKE_VERSION-Linux-x86_64.tar.gz + +ENV FOLLY_VERSION 2017.12.18.00 +RUN wget https://github.com/facebook/folly/archive/v$FOLLY_VERSION.tar.gz -O folly-$FOLLY_VERSION.tar.gz && \ + mkdir -p $EXT_DIR/src/Folly && \ + tar xzvf folly-$FOLLY_VERSION.tar.gz -C $EXT_DIR/src/Folly --strip-components=1 && \ + rm folly-$FOLLY_VERSION.tar.gz && \ + cd $EXT_DIR/src/Folly/folly && \ + autoreconf -vi && \ + ./configure \ + --prefix=$EXT_DIR \ + --with-pic \ + LD_LIBRARY_PATH=$EXT_DIR/lib \ + LD_RUN_PATH=$EXT_DIR/lib \ + LIBRARY_PATH=$EXT_DIR/lib \ + LDFLAGS=-L$EXT_DIR/lib \ + PKG_CONFIG_PATH=$EXT_DIR/lib/pkgconfig \ + CFLAGS=-I$EXT_DIR/include \ + CXXFLAGS=-I$EXT_DIR/include \ + CPPFLAGS=-I$EXT_DIR/include && \ + make && \ + make install && \ + make clean && \ + rm -rf $EXT_DIR/src/Folly/folly + +ENV THRIFT_VERSION_STRING 0.11.0 +RUN wget http://www-us.apache.org/dist/thrift/$THRIFT_VERSION_STRING/thrift-$THRIFT_VERSION_STRING.tar.gz && \ + mkdir -p $EXT_DIR/src/Thrift && \ + tar xzvf thrift-$THRIFT_VERSION_STRING.tar.gz -C $EXT_DIR/src/Thrift --strip-components=1 && \ + rm thrift-$THRIFT_VERSION_STRING.tar.gz && \ + cd $EXT_DIR/src/Thrift && \ + ./configure \ + --prefix=$EXT_DIR \ + --without-c_glib \ + --without-csharp \ + --without-dart \ + --without-dotnetcore \ + --without-erlang \ + --without-go \ + --without-java \ + --without-lua \ + --without-nodejs \ + --without-php \ + --without-py3 \ + --without-python \ + --without-qt4 \ + --without-qt5 \ + --without-rs \ + --without-ruby \ + --disable-tests \ + --disable-plugin && \ + make && \ + make install && \ + make clean && \ + rm -rf $EXT_DIR/src/Thrift + +ENV LibRDKafka_VERSION 0.11.3 +RUN wget https://github.com/edenhill/librdkafka/archive/v$LibRDKafka_VERSION.tar.gz -O LibRDKafka-$LibRDKafka_VERSION.tar.gz && \ + mkdir -p $EXT_DIR/src/LibRDKafka/build && \ + tar xzvf LibRDKafka-$LibRDKafka_VERSION.tar.gz -C $EXT_DIR/src/LibRDKafka --strip-components=1 && \ + rm LibRDKafka-$LibRDKafka_VERSION.tar.gz && \ + cd $EXT_DIR/src/LibRDKafka/build && \ + $CMAKE_DIR/bin/cmake \ + -DRDKAFKA_BUILD_EXAMPLES=OFF \ + -DRDKAFKA_BUILD_TESTS=OFF \ + -DCMAKE_INSTALL_PREFIX=$EXT_DIR \ + -DCMAKE_PREFIX_PATH=$EXT_DIR \ + $EXT_DIR/src/LibRDKafka/ && \ + make && \ + make install && \ + make clean && \ + rm -rf $EXT_DIR/src/LibRDKafka + +ENV RAPIDJSON_VERSION 1.1.0 +RUN wget https://github.com/miloyip/rapidjson/archive/v$RAPIDJSON_VERSION.tar.gz -O RapidJSON-$RAPIDJSON_VERSION.tar.gz && \ + mkdir -p $EXT_DIR/src/RapidJSON/build && \ + tar xzvf RapidJSON-$RAPIDJSON_VERSION.tar.gz -C $EXT_DIR/src/RapidJSON --strip-components=1 && \ + rm RapidJSON-$RAPIDJSON_VERSION.tar.gz && \ + cd $EXT_DIR/src/RapidJSON/build && \ + $CMAKE_DIR/bin/cmake \ + -DCMAKE_INSTALL_PREFIX=$EXT_DIR \ + -DCMAKE_PREFIX_PATH=$EXT_DIR \ + -DRAPIDJSON_BUILD_DOC=OFF \ + -DRAPIDJSON_BUILD_EXAMPLES=OFF \ + -DRAPIDJSON_BUILD_TESTS=OFF \ + $EXT_DIR/src/RapidJSON/ && \ + make && \ + make install && \ + make clean && \ + rm -rf $EXT_DIR/src/RapidJSON + +ENV GTEST_VERSION 1.8.0 +RUN wget https://github.com/google/googletest/archive/release-$GTEST_VERSION.tar.gz -O GTest-$GTEST_VERSION.tar.gz && \ + mkdir -p $EXT_DIR/src/GTest/build && \ + tar xzvf GTest-$GTEST_VERSION.tar.gz -C $EXT_DIR/src/GTest --strip-components=1 && \ + rm GTest-$GTEST_VERSION.tar.gz && \ + cd $EXT_DIR/src/GTest/build && \ + $CMAKE_DIR/bin/cmake \ + -DCMAKE_INSTALL_PREFIX=$EXT_DIR \ + -DCMAKE_PREFIX_PATH=$EXT_DIR \ + $EXT_DIR/src/GTest/ && \ + make && \ + make install && \ + make clean && \ + rm -rf $EXT_DIR/src/GTest + +ENV GBENCH_VERSION 1.1.0 +RUN wget https://github.com/google/benchmark/archive/v$GBENCH_VERSION.tar.gz -O GBench-$GBENCH_VERSION.tar.gz && \ + mkdir -p $EXT_DIR/src/GBench/build && \ + tar xzvf GBench-$GBENCH_VERSION.tar.gz -C $EXT_DIR/src/GBench --strip-components=1 && \ + rm GBench-$GBENCH_VERSION.tar.gz && \ + cd $EXT_DIR/src/GBench/build && \ + $CMAKE_DIR/bin/cmake \ + -DCMAKE_INSTALL_PREFIX=$EXT_DIR \ + -DCMAKE_PREFIX_PATH=$EXT_DIR \ + -DBENCHMARK_ENABLE_TESTING=OFF \ + -DBENCHMARK_ENABLE_LTO=ON \ + $EXT_DIR/src/GBench/ && \ + make && \ + make install && \ + make clean && \ + rm -rf $EXT_DIR/src/GBench + +ENV ZIPKIN_VERSION 0.3.1 + +COPY ./docker-entrypoint.sh / + +ENTRYPOINT ["/docker-entrypoint.sh"] + +CMD ["release"] diff --git a/ci/Dockerfile-ubuntu-xenial b/ci/Dockerfile-ubuntu-xenial new file mode 100644 index 0000000..d0423a9 --- /dev/null +++ b/ci/Dockerfile-ubuntu-xenial @@ -0,0 +1,177 @@ +FROM ubuntu:xenial + +RUN apt-get update && apt-get install -y --no-install-recommends \ + autoconf \ + automake \ + binutils-dev \ + bison \ + build-essential \ + ca-certificates \ + doxygen \ + flex \ + git \ + libboost-all-dev \ + libc++-dev \ + libcurl4-openssl-dev \ + libdouble-conversion-dev \ + libdwarf-dev \ + libelf-dev \ + libevent-dev \ + libgflags-dev \ + libgoogle-glog-dev \ + libiberty-dev \ + libjemalloc-dev \ + liblz4-dev \ + liblzma-dev \ + libsnappy-dev \ + libssl-dev \ + libtool \ + libunwind8-dev \ + make \ + pkg-config \ + thrift-compiler \ + tree \ + wget \ + zlib1g-dev && \ + apt-get clean && \ + rm -rf /var/lib/apt/lists/* + +ENV CMAKE_DIR /cmake +ENV SRC_DIR /source +ENV DIST_DIR /dist +ENV BUILD_DIR /build +ENV EXT_DIR $BUILD_DIR/externals + +ENV CMAKE_VERSION 3.8.2 +RUN wget https://cmake.org/files/v3.8/cmake-$CMAKE_VERSION-Linux-x86_64.tar.gz && \ + mkdir -p $CMAKE_DIR && \ + tar xzvf cmake-$CMAKE_VERSION-Linux-x86_64.tar.gz -C $CMAKE_DIR --strip-components=1 && \ + rm cmake-$CMAKE_VERSION-Linux-x86_64.tar.gz + +ENV FOLLY_VERSION 2017.12.18.00 +RUN wget https://github.com/facebook/folly/archive/v$FOLLY_VERSION.tar.gz -O folly-$FOLLY_VERSION.tar.gz && \ + mkdir -p $EXT_DIR/src/Folly && \ + tar xzvf folly-$FOLLY_VERSION.tar.gz -C $EXT_DIR/src/Folly --strip-components=1 && \ + rm folly-$FOLLY_VERSION.tar.gz && \ + cd $EXT_DIR/src/Folly/folly && \ + autoreconf -vi && \ + ./configure \ + --prefix=$EXT_DIR \ + --with-pic \ + LD_LIBRARY_PATH=$EXT_DIR/lib \ + LD_RUN_PATH=$EXT_DIR/lib \ + LIBRARY_PATH=$EXT_DIR/lib \ + LDFLAGS=-L$EXT_DIR/lib \ + PKG_CONFIG_PATH=$EXT_DIR/lib/pkgconfig \ + CFLAGS=-I$EXT_DIR/include \ + CXXFLAGS=-I$EXT_DIR/include \ + CPPFLAGS=-I$EXT_DIR/include && \ + make && \ + make install && \ + make clean && \ + rm -rf $EXT_DIR/src/Folly/folly + +ENV THRIFT_VERSION_STRING 0.11.0 +RUN wget http://www-us.apache.org/dist/thrift/$THRIFT_VERSION_STRING/thrift-$THRIFT_VERSION_STRING.tar.gz && \ + mkdir -p $EXT_DIR/src/Thrift && \ + tar xzvf thrift-$THRIFT_VERSION_STRING.tar.gz -C $EXT_DIR/src/Thrift --strip-components=1 && \ + rm thrift-$THRIFT_VERSION_STRING.tar.gz && \ + cd $EXT_DIR/src/Thrift && \ + ./configure \ + --prefix=$EXT_DIR \ + --without-c_glib \ + --without-csharp \ + --without-dart \ + --without-dotnetcore \ + --without-erlang \ + --without-go \ + --without-java \ + --without-lua \ + --without-nodejs \ + --without-php \ + --without-py3 \ + --without-python \ + --without-qt4 \ + --without-qt5 \ + --without-rs \ + --without-ruby \ + --disable-plugin && \ + make && \ + make install && \ + make clean && \ + rm -rf $EXT_DIR/src/Thrift + +ENV LibRDKafka_VERSION 0.11.3 +RUN wget https://github.com/edenhill/librdkafka/archive/v$LibRDKafka_VERSION.tar.gz -O LibRDKafka-$LibRDKafka_VERSION.tar.gz && \ + mkdir -p $EXT_DIR/src/LibRDKafka/build && \ + tar xzvf LibRDKafka-$LibRDKafka_VERSION.tar.gz -C $EXT_DIR/src/LibRDKafka --strip-components=1 && \ + rm LibRDKafka-$LibRDKafka_VERSION.tar.gz && \ + cd $EXT_DIR/src/LibRDKafka/build && \ + $CMAKE_DIR/bin/cmake \ + -DRDKAFKA_BUILD_EXAMPLES=OFF \ + -DRDKAFKA_BUILD_TESTS=OFF \ + -DCMAKE_INSTALL_PREFIX=$EXT_DIR \ + -DCMAKE_PREFIX_PATH=$EXT_DIR \ + $EXT_DIR/src/LibRDKafka/ && \ + make && \ + make install && \ + make clean && \ + rm -rf $EXT_DIR/src/LibRDKafka + +ENV RAPIDJSON_VERSION 1.1.0 +RUN wget https://github.com/miloyip/rapidjson/archive/v$RAPIDJSON_VERSION.tar.gz -O RapidJSON-$RAPIDJSON_VERSION.tar.gz && \ + mkdir -p $EXT_DIR/src/RapidJSON/build && \ + tar xzvf RapidJSON-$RAPIDJSON_VERSION.tar.gz -C $EXT_DIR/src/RapidJSON --strip-components=1 && \ + rm RapidJSON-$RAPIDJSON_VERSION.tar.gz && \ + cd $EXT_DIR/src/RapidJSON/build && \ + $CMAKE_DIR/bin/cmake \ + -DCMAKE_INSTALL_PREFIX=$EXT_DIR \ + -DCMAKE_PREFIX_PATH=$EXT_DIR \ + -DRAPIDJSON_BUILD_DOC=OFF \ + -DRAPIDJSON_BUILD_EXAMPLES=OFF \ + -DRAPIDJSON_BUILD_TESTS=OFF \ + $EXT_DIR/src/RapidJSON/ && \ + make && \ + make install && \ + make clean && \ + rm -rf $EXT_DIR/src/RapidJSON + +ENV GTEST_VERSION 1.8.0 +RUN wget https://github.com/google/googletest/archive/release-$GTEST_VERSION.tar.gz -O GTest-$GTEST_VERSION.tar.gz && \ + mkdir -p $EXT_DIR/src/GTest/build && \ + tar xzvf GTest-$GTEST_VERSION.tar.gz -C $EXT_DIR/src/GTest --strip-components=1 && \ + rm GTest-$GTEST_VERSION.tar.gz && \ + cd $EXT_DIR/src/GTest/build && \ + $CMAKE_DIR/bin/cmake \ + -DCMAKE_INSTALL_PREFIX=$EXT_DIR \ + -DCMAKE_PREFIX_PATH=$EXT_DIR \ + $EXT_DIR/src/GTest/ && \ + make && \ + make install && \ + make clean && \ + rm -rf $EXT_DIR/src/GTest + +ENV GBENCH_VERSION 1.1.0 +RUN wget https://github.com/google/benchmark/archive/v$GBENCH_VERSION.tar.gz -O GBench-$GBENCH_VERSION.tar.gz && \ + mkdir -p $EXT_DIR/src/GBench/build && \ + tar xzvf GBench-$GBENCH_VERSION.tar.gz -C $EXT_DIR/src/GBench --strip-components=1 && \ + rm GBench-$GBENCH_VERSION.tar.gz && \ + cd $EXT_DIR/src/GBench/build && \ + $CMAKE_DIR/bin/cmake \ + -DCMAKE_INSTALL_PREFIX=$EXT_DIR \ + -DCMAKE_PREFIX_PATH=$EXT_DIR \ + -DBENCHMARK_ENABLE_TESTING=OFF \ + -DBENCHMARK_ENABLE_LTO=ON \ + $EXT_DIR/src/GBench/ && \ + make && \ + make install && \ + make clean && \ + rm -rf $EXT_DIR/src/GBench + +ENV ZIPKIN_VERSION 0.3.1 + +COPY ./docker-entrypoint.sh / + +ENTRYPOINT ["/docker-entrypoint.sh"] + +CMD ["release"] diff --git a/ci/README.md b/ci/README.md new file mode 100644 index 0000000..6f2763f --- /dev/null +++ b/ci/README.md @@ -0,0 +1,70 @@ +# Developer use of CI Docker images + +Two flavors of `zipkin-cpp-build` Docker images, based on Ubuntu and CentOS Linux, are built. + +## Ubuntu image: `zipkin-cpp-build:ubuntu` + +The current build image is based on Ubuntu 16.04 (Xenial) which uses the GCC 5.4 compiler. + +## CentOS image: `zipkin-cpp-build:centos` + +The current build image is based on CentOS 7 with [devtoolset-4](https://www.softwarecollections.org/en/scls/rhscl/devtoolset-4/) which uses the GCC 5.3 compiler. + +## Building and running tests as a developer + +An example basic invocation to build a developer version of the `zipkin-cpp` library. + +```sh +$ cd ci && ./build-dist.sh git:develop +... +dist files packaged to: dist/zipkin-cpp-git-daefe03-Linux-x86_64.tar.gz +``` + +For a release version of the `zipkin-cpp` library you can run: + +```sh +$ cd ci && ./build-dist.sh release:0.3.1 +``` + +For a local version of the `zipkin-cpp` library you can run: + +```sh +$ cd ci && ./build-dist.sh local +``` + +The build script will map the local source code to `/source` folder. + +To build with the CentOS image, we need `IMAGE_TAG=centos` with previous commands. + +```sh +$ cd ci && IMAGE_TAG=centos ./build-dist.sh git:develop +``` + +The built library can be found in `dist/zipkin-cpp-0.3.1-Linux-x86_64.tar.gz`. + +## Testing changes to the build image as a developer + +While all changes to the build image should eventually be upstreamed, it can be useful to test those changes locally before sending out a pull request. To experiment with a local clone of the upstream build image you can make changes to files such as `build_image.sh` locally and then run: + +```sh +$ cd ci && ./build-image.sh # Wait patiently for quite some time + +Sending build context to Docker daemon 22.53kB +Step 1/25 : FROM ubuntu:xenial + ... +Successfully built 9f80a02eb4ef +Successfully tagged zipkin-cpp-build:ubuntu +``` + +Besides, you could build images base on CentOS 7 + +```sh +$ cd ci && IMAGE_TAG=centos ./build-image.sh # Wait patiently for quite some time +Sending build context to Docker daemon 22.53kB +Step 1/28 : FROM centos/devtoolset-4-toolchain-centos7 +... +Successfully built 419fd83e43c8 +Successfully tagged zipkin-cpp-build:centos +``` + +After the build was finished, it will be tagged with `IMAGE_TAG`. diff --git a/ci/build-dist.sh b/ci/build-dist.sh new file mode 100755 index 0000000..e8e091a --- /dev/null +++ b/ci/build-dist.sh @@ -0,0 +1,87 @@ +#!/bin/bash + +set -e + +[[ -z "${ZIPKIN_VERSION}" ]] && ZIPKIN_VERSION="0.3.1" + +BASE_DIR=`pwd`/.. +SRC_DIR=${BASE_DIR} +DIST_DIR=${BASE_DIR}/dist + +IMAGE_TAG=${IMAGE_TAG:-ubuntu} +IMAGE_NAME=zipkin-cpp-build:${IMAGE_TAG} +CONTAINER_NAME=zipkin-cpp-build-${IMAGE_TAG} + +# When running docker on a Mac, root user permissions are required. +if [[ "$OSTYPE" == "darwin"* ]]; then + USER=root + USER_GROUP=root +else + USER=$(id -u) + USER_GROUP=$(id -g) +fi + +function container_is_exists { + echo "docker ps -a -q -f \"name=${CONTAINER_NAME}\" -f \"ancestor=${IMAGE_NAME}\"" + local CONTAINER_ID=`docker ps -a -q -f "name=${CONTAINER_NAME}" -f "ancestor=${IMAGE_NAME}"` + + [[ -n $CONTAINER_ID ]] +} + +function container_is_running { + local CONTAINER_ID=`docker ps -q -f "name=${CONTAINER_NAME}" -f "ancestor=${IMAGE_NAME}"` + + [[ -n $CONTAINER_ID ]] +} + +function container_has_outdated { + local CONTAINER_ID=`docker ps -a -q -f "name=${CONTAINER_NAME}"` + + [[ -n $CONTAINER_ID ]] +} + +function run_container { + echo "run new container: ${CONTAINER_NAME}" + + if [[ $1 == 'local' ]]; then + docker run --name ${CONTAINER_NAME} -u "${USER}":"${USER_GROUP}" -v ${SRC_DIR}:/source -v ${DIST_DIR}:/dist ${IMAGE_NAME} $1 + else + docker run --name ${CONTAINER_NAME} -u "${USER}":"${USER_GROUP}" -v ${DIST_DIR}:/dist ${IMAGE_NAME} $1 + fi +} + +if container_is_exists; then + if container_is_running; then + docker logs -f ${CONTAINER_NAME} + else + echo "remove stopped container: ${CONTAINER_NAME}" + + docker rm ${CONTAINER_NAME} + + run_container $@ + fi +else + if container_has_outdated; then + echo "remove outdated container ${CONTAINER_NAME}" + + docker rm ${CONTAINER_NAME} + fi + + run_container $@ +fi + +if [[ -n $2 ]]; then + PKG_TYPE=$2 + + cd ${DIST_DIR} + + if [[ `gem list -i fpm` != 'true' ]]; then + gem install fpm -f --no-document + fi + + fpm -f --prefix /usr/local -s dir -t $PKG_TYPE -n zipkin-cpp -v ${ZIPKIN_VERSION} include lib + + if [ "$PKG_TYPE" == 'osxpkg' ]; then + pkgutil --payload-files zipkin-cpp-${ZIPKIN_VERSION}.pkg + fi +fi diff --git a/ci/build-image.sh b/ci/build-image.sh new file mode 100755 index 0000000..0c16ec8 --- /dev/null +++ b/ci/build-image.sh @@ -0,0 +1,7 @@ +#!/bin/bash + +if [[ "$IMAGE_TAG" == "centos" ]]; then + docker build -t zipkin-cpp-build:centos -f Dockerfile-centos-7 . +else + docker build -t zipkin-cpp-build:ubuntu -f Dockerfile-ubuntu-xenial . +fi diff --git a/ci/docker-entrypoint.sh b/ci/docker-entrypoint.sh new file mode 100755 index 0000000..d27d0b5 --- /dev/null +++ b/ci/docker-entrypoint.sh @@ -0,0 +1,69 @@ +#!/bin/bash + +set -e + +if [[ "$1" =~ ^release: ]]; then + if [ "${1:8}" != "" ]; then + ZIPKIN_VERSION=${1:8} + fi + + echo "zipkin-cpp release build with v${ZIPKIN_VERSION} package." + + update-ca-certificates + wget https://github.com/flier/zipkin-cpp/archive/v${ZIPKIN_VERSION}.tar.gz + mkdir -p ${SRC_DIR} + tar xzvf v${ZIPKIN_VERSION}.tar.gz -C ${SRC_DIR} --strip-components=1 + rm v${ZIPKIN_VERSION}.tar.gz +elif [[ "$1" =~ ^git: ]]; then + echo "zipkin-cpp development build with GIT source." + + git clone https://github.com/flier/zipkin-cpp.git ${SRC_DIR} + + GIT_BRANCH=${1:4-master} + + echo "checkout GIT branch: ${GIT_BRANCH}" + + cd ${SRC_DIR} && git checkout ${GIT_BRANCH} + + GIT_REVISION=`git describe --always` + ZIPKIN_VERSION="git-${GIT_REVISION}" +elif [ "$1" == 'local' ]; then + echo "zipkin-cpp development build with with local volume mapping to ${SRC_DIR}." + + cd ${SRC_DIR} + + GIT_REVISION=`git describe --always` + ZIPKIN_VERSION="git-${GIT_REVISION}" +else + exec "$@" +fi + +echo "build zipkin-cpp version ${ZIPKIN_VERSION} @ ${SRC_DIR}" +echo "install dist files to @ ${DIST_DIR}" +echo "use prebuilt projects @ ${EXT_DIR}" + +#tree ${EXT_DIR} + +mkdir -p ${BUILD_DIR} +cd ${BUILD_DIR} +${CMAKE_DIR}/bin/cmake \ + -DCMAKE_INSTALL_PREFIX=${DIST_DIR} \ + -DCMAKE_PREFIX_PATH=${EXT_DIR} \ + -DCMAKE_PROGRAM_PATH=${EXT_DIR}/bin \ + -DCMAKE_INCLUDE_PATH=${EXT_DIR}/include \ + -DCMAKE_LIBRARY_PATH=${EXT_DIR}/lib \ + -DBUILD_DOCS=OFF \ + -DBUILD_BENCH=OFF \ + ${CMAKE_OPTS} \ + ${SRC_DIR} + +make +make test +make install +make clean + +PACKAGE_FILE="zipkin-cpp-$ZIPKIN_VERSION-Linux-x86_64.tar.gz" + +tar czvf ${DIST_DIR}/${PACKAGE_FILE} --exclude *.tar.gz ${DIST_DIR}/ + +echo "dist files packaged to: dist/${PACKAGE_FILE}" diff --git a/cmake/FindLibRDKafka.cmake b/cmake/FindLibRDKafka.cmake index f0b23b0..51baae5 100644 --- a/cmake/FindLibRDKafka.cmake +++ b/cmake/FindLibRDKafka.cmake @@ -28,7 +28,7 @@ find_library(LibRDKafka_LIBRARIES find_library(LibRDKafka_C_LIBRARIES NAMES rdkafka - HINTS ${LibRDKafka_ROT_DIR}/lib + HINTS ${LibRDKafka_ROOT_DIR}/lib ) find_path(LibRDKafka_INCLUDE_DIR diff --git a/cmake/InstallCURL.cmake b/cmake/InstallCURL.cmake index d91cad9..7df1bec 100644 --- a/cmake/InstallCURL.cmake +++ b/cmake/InstallCURL.cmake @@ -1,7 +1,7 @@ if (NOT CURL_FOUND OR USE_BUNDLED_CURL) if (NOT CURL_VERSION_STRING OR USE_BUNDLED_CURL) - set (CURL_VERSION_STRING 7.54.1) - set (CURL_URL_MD5 21a6e5658fd55103a90b11de7b2a8a8c) + set (CURL_VERSION_STRING 7.57.0) + set (CURL_URL_MD5 c7aab73aaf5e883ca1d7518f93649dc2) endif () ExternalProject_Add(CURL @@ -11,6 +11,8 @@ if (NOT CURL_FOUND OR USE_BUNDLED_CURL) --prefix= --without-ssl --without-nghttp2 + --without-libidn2 + --without-winidn --disable-ldap BUILD_COMMAND make INSTALL_COMMAND make install diff --git a/cmake/InstallDoubleConversion.cmake b/cmake/InstallDoubleConversion.cmake index 601d592..2d06cf5 100644 --- a/cmake/InstallDoubleConversion.cmake +++ b/cmake/InstallDoubleConversion.cmake @@ -1,7 +1,7 @@ if (NOT DOUBLE_CONVERSION_FOUND OR USE_BUNDLED_DOUBLE_CONVERSION) if (NOT DOUBLE_CONVERSION_VERSION OR USE_BUNDLED_DOUBLE_CONVERSION) - set (DOUBLE_CONVERSION_VERSION 1.1.5) - set (DOUBLE_CONVERSION_URL_MD5 f7c62594d7ecfbc4421da32bc341a919) + set (DOUBLE_CONVERSION_VERSION 3.0.0) + set (DOUBLE_CONVERSION_URL_MD5 7c8e8bcaae6c9def83b7ee7396f18e5e) endif () ExternalProject_Add(DoubleConversion diff --git a/cmake/InstallFolly.cmake b/cmake/InstallFolly.cmake index 500933f..c4fdb74 100644 --- a/cmake/InstallFolly.cmake +++ b/cmake/InstallFolly.cmake @@ -1,7 +1,7 @@ if (NOT FOLLY_FOUND OR USE_BUNDLED_FOLLY) if (NOT FOLLY_VERSION OR USE_BUNDLED_FOLLY) - set (FOLLY_VERSION 2017.06.26.01) - set (FOLLY_URL_MD5 cf7a05081adb16913b5d7039ac62d46b) + set (FOLLY_VERSION 2017.12.18.00) + set (FOLLY_URL_MD5 6073d8fab8c54a0b6212a98244f2689b) endif() ExternalProject_Add(Folly @@ -13,7 +13,6 @@ if (NOT FOLLY_FOUND OR USE_BUNDLED_FOLLY) /folly/configure --prefix= --with-pic - --with-jemalloc ${WITH_OPENSSL} LD_LIBRARY_PATH=/lib LD_RUN_PATH=/lib diff --git a/cmake/InstallGBench.cmake b/cmake/InstallGBench.cmake index e278a3e..2b12dee 100644 --- a/cmake/InstallGBench.cmake +++ b/cmake/InstallGBench.cmake @@ -1,7 +1,7 @@ if (NOT GBENCH_FOUND OR USE_BUNDLED_GBENCH) if (NOT GBENCH_VERSION OR USE_BUNDLED_GBENCH) - set (GBENCH_VERSION 1.1.0) - set (GBENCH_URL_MD5 66b2a23076cf70739525be0092fc3ae3) + set (GBENCH_VERSION 1.3.0) + set (GBENCH_URL_MD5 19ce86516ab82d6ad3b17173cf307aac) endif () ExternalProject_Add(GBench @@ -9,6 +9,8 @@ if (NOT GBENCH_FOUND OR USE_BUNDLED_GBENCH) URL https://github.com/google/benchmark/archive/v${GBENCH_VERSION}.tar.gz URL_MD5 ${GBENCH_URL_MD5} CMAKE_ARGS -DCMAKE_INSTALL_PREFIX= + -DBENCHMARK_ENABLE_TESTING=OFF + -DBENCHMARK_ENABLE_LTO=ON TEST_COMMAND "" ) diff --git a/cmake/InstallGFlags.cmake b/cmake/InstallGFlags.cmake index 09f8531..af112de 100644 --- a/cmake/InstallGFlags.cmake +++ b/cmake/InstallGFlags.cmake @@ -1,7 +1,7 @@ if (NOT GFLAGS_FOUND OR USE_BUNDLED_GFLAGS) if (NOT GFLAGS_VERSION OR USE_BUNDLED_GFLAGS) - set (GFLAGS_VERSION 2.2.0) - set (GFLAGS_URL_MD5 b99048d9ab82d8c56e876fb1456c285e) + set (GFLAGS_VERSION 2.2.1) + set (GFLAGS_URL_MD5 b98e772b4490c84fc5a87681973f75d1) endif () ExternalProject_Add(GFlags diff --git a/cmake/InstallLibRDKafka.cmake b/cmake/InstallLibRDKafka.cmake index f679801..226ef2c 100644 --- a/cmake/InstallLibRDKafka.cmake +++ b/cmake/InstallLibRDKafka.cmake @@ -1,7 +1,7 @@ if (NOT LIBRDKAFKA_FOUND OR USE_BUNDLED_LIBRDKAFKA) if (NOT LibRDKafka_VERSION OR USE_BUNDLED_LIBRDKAFKA) - set (LibRDKafka_VERSION 0.11.0) - set (LibRDKafka_URL_MD5 68f4712491a92423c9722be9054678d8) + set (LibRDKafka_VERSION 0.11.3) + set (LibRDKafka_URL_MD5 28889585c465ee71363e9c1f35424685) endif () ExternalProject_Add(LibRDKafka @@ -20,30 +20,22 @@ if (NOT LIBRDKAFKA_FOUND OR USE_BUNDLED_LIBRDKAFKA) set (LibRDKafka_LIBRARY_DIR ${LibRDKafka_ROOT_DIR}/lib) set (LibRDKafka_INCLUDE_DIR ${LibRDKafka_ROOT_DIR}/include) set (LibRDKafka_LIBRARY_PATH ${LibRDKafka_LIBRARY_DIR}/librdkafka++.a) - set (LibRDKafka_C_LIBRARY_PATH ${LibRDKafka_LIBRARY_DIR}/librdkafka.a) - find_library(LibRDKafka_LIBRARY - NAMES rdkafka++ - PATH ${LibRDKafka_LIBRARY_DIR} - NO_DEFAULT_PATH NO_SYSTEM_ENVIRONMENT_PATH - ) find_library(LibRDKafka_C_LIBRARY NAMES rdkafka - PATH ${LibRDKafka_LIBRARY_DIR} + PATHS ${LibRDKafka_LIBRARY_DIR} NO_DEFAULT_PATH NO_SYSTEM_ENVIRONMENT_PATH ) - set (LibRDKafka_LIBRARIES ${LibRDKafka_LIBRARY_PATH} ${LibRDKafka_C_LIBRARY_PATH}) - set (LibRDKafka_C_LIBRARIES ${LibRDKafka_C_LIBRARY_PATH}) + set (LibRDKafka_LIBRARIES ${LibRDKafka_LIBRARY_PATH}) + set (LibRDKafka_C_LIBRARIES ${LibRDKafka_C_LIBRARY}) set (LibRDKafka_FOUND YES) add_library(LibRDKafka_LIBRARY_PATH STATIC IMPORTED) - add_library(LibRDKafka_C_LIBRARY_PATH STATIC IMPORTED) - add_library(LibRDKafka_LIBRARY SHARED IMPORTED) add_library(LibRDKafka_C_LIBRARY SHARED IMPORTED) add_dependencies(LibRDKafka_LIBRARY_PATH LibRDKafka) - add_dependencies(LibRDKafka_C_LIBRARY_PATH LibRDKafka) + add_dependencies(LibRDKafka_C_LIBRARY LibRDKafka) mark_as_advanced(LibRDKafka_LIBRARIES LibRDKafka_C_LIBRARIES LibRDKafka_INCLUDE_DIR) message(STATUS "Use bundled librdkafka v${LibRDKafka_VERSION}") diff --git a/cmake/InstallRapidJSON.cmake b/cmake/InstallRapidJSON.cmake index cbc3fb3..6c6d8c5 100644 --- a/cmake/InstallRapidJSON.cmake +++ b/cmake/InstallRapidJSON.cmake @@ -9,6 +9,9 @@ if (NOT RAPIDJSON_FOUND OR USE_BUNDLED_RAPIDJSON) URL https://github.com/miloyip/rapidjson/archive/v${RAPIDJSON_VERSION}.tar.gz URL_MD5 ${RAPIDJSON_URL_MD5} CMAKE_ARGS -DCMAKE_INSTALL_PREFIX= + -DRAPIDJSON_BUILD_DOC=OFF + -DRAPIDJSON_BUILD_EXAMPLES=OFF + -DRAPIDJSON_BUILD_TESTS=OFF TEST_COMMAND "" ) @@ -21,4 +24,4 @@ if (NOT RAPIDJSON_FOUND OR USE_BUNDLED_RAPIDJSON) mark_as_advanced(RAPIDJSON_INCLUDES) message(STATUS "Use bundled RapidJSON v${RAPIDJSON_VERSION}") -endif () \ No newline at end of file +endif () diff --git a/cmake/InstallThrift.cmake b/cmake/InstallThrift.cmake index 7463a56..034c5ac 100644 --- a/cmake/InstallThrift.cmake +++ b/cmake/InstallThrift.cmake @@ -1,7 +1,7 @@ if (NOT THRIFT_FOUND OR USE_BUNDLED_THRIFT) if (NOT THRIFT_VERSION_STRING OR USE_BUNDLED_THRIFT) - set (THRIFT_VERSION_STRING 0.10.0) - set (THRIFT_URL_MD5 795c5dd192e310ffff38cfd9430d6b29) + set (THRIFT_VERSION_STRING 0.11.0) + set (THRIFT_URL_MD5 0be59730ebce071eceaf6bfdb8d3a20e) endif () ExternalProject_Add(Thrift @@ -13,17 +13,20 @@ if (NOT THRIFT_FOUND OR USE_BUNDLED_THRIFT) --with-boost=${BOOST_ROOT} --without-c_glib --without-csharp - --without-python - --without-java - --without-nodejs - --without-lua - --without-ruby - --without-php + --without-dart + --without-dotnetcore --without-erlang --without-go + --without-java + --without-lua --without-nodejs + --without-php + --without-py3 + --without-python --without-qt4 --without-qt5 + --without-rs + --without-ruby --disable-plugin BUILD_COMMAND CXXFLAGS=-I/lib/cpp/src make INSTALL_COMMAND make install diff --git a/src/Collector.cpp b/src/Collector.cpp index b887764..6fa182d 100644 --- a/src/Collector.cpp +++ b/src/Collector.cpp @@ -61,7 +61,7 @@ std::shared_ptr MessageCodec::parse(const std::string &codec) return nullptr; } -size_t BinaryCodec::encode(boost::shared_ptr buf, const std::vector &spans) +size_t BinaryCodec::encode(std::shared_ptr buf, const std::vector &spans) { apache::thrift::protocol::TBinaryProtocol protocol(buf); @@ -75,7 +75,7 @@ size_t BinaryCodec::encode(boost::shared_ptr buf, const std::vector &spans) +size_t JsonCodec::encode(std::shared_ptr buf, const std::vector &spans) { rapidjson::StringBuffer buffer; @@ -95,7 +95,7 @@ size_t JsonCodec::encode(boost::shared_ptr buf, const std::vector &spans) +size_t PrettyJsonCodec::encode(std::shared_ptr buf, const std::vector &spans) { rapidjson::StringBuffer buffer; @@ -207,7 +207,8 @@ bool BaseCollector::flush(std::chrono::milliseconds timeout_ms) void BaseCollector::shutdown(std::chrono::milliseconds timeout_ms) { - if (m_terminated.exchange(true)) return; + if (m_terminated.exchange(true)) + return; if (!flush(timeout_ms) && m_worker.joinable()) { @@ -263,13 +264,17 @@ void BaseCollector::send_spans(void) std::vector spans; - m_queued_spans -= m_spans.consume_all([&spans](Span *span) { + CachedSpan *span; + + while (m_spans.pop(span)) + { spans.push_back(span); - }); + m_queued_spans--; + } if (!spans.empty()) { - boost::shared_ptr buf(new apache::thrift::transport::TMemoryBuffer()); + std::shared_ptr buf(new apache::thrift::transport::TMemoryBuffer()); VLOG(1) << "encode " << spans.size() << " spans with `" << m_conf->message_codec->name() << "` codec"; diff --git a/src/Collector.h b/src/Collector.h index 83938c3..0363dab 100644 --- a/src/Collector.h +++ b/src/Collector.h @@ -47,7 +47,7 @@ class MessageCodec virtual const std::string mime_type(void) const = 0; - virtual size_t encode(boost::shared_ptr buf, const std::vector &spans) = 0; + virtual size_t encode(std::shared_ptr buf, const std::vector &spans) = 0; static std::shared_ptr parse(const std::string &codec); @@ -66,7 +66,7 @@ class BinaryCodec : public MessageCodec virtual const std::string mime_type(void) const override { return "application/x-thrift"; } - virtual size_t encode(boost::shared_ptr buf, const std::vector &spans) override; + virtual size_t encode(std::shared_ptr buf, const std::vector &spans) override; }; /** @@ -79,7 +79,7 @@ class JsonCodec : public MessageCodec virtual const std::string mime_type(void) const override { return "application/json"; } - virtual size_t encode(boost::shared_ptr buf, const std::vector &spans) override; + virtual size_t encode(std::shared_ptr buf, const std::vector &spans) override; }; /** @@ -92,7 +92,7 @@ class PrettyJsonCodec : public MessageCodec virtual const std::string mime_type(void) const override { return "application/json"; } - virtual size_t encode(boost::shared_ptr buf, const std::vector &spans) override; + virtual size_t encode(std::shared_ptr buf, const std::vector &spans) override; }; /** @@ -191,7 +191,8 @@ class BaseCollector : public Collector virtual ~BaseCollector() { - if (!m_terminated.exchange(true)) { + if (!m_terminated.exchange(true)) + { m_worker.detach(); } } diff --git a/src/KafkaCollector.cpp b/src/KafkaCollector.cpp index 393242d..544b7a4 100644 --- a/src/KafkaCollector.cpp +++ b/src/KafkaCollector.cpp @@ -136,7 +136,7 @@ KafkaConf::KafkaConf(folly::Uri &uri) void KafkaCollector::submit(Span *span) { - boost::shared_ptr buf(new ReusableMemoryBuffer(static_cast(span))); + std::shared_ptr buf(new ReusableMemoryBuffer(static_cast(span))); std::vector spans; spans.push_back(span); diff --git a/src/ScribeCollector.h b/src/ScribeCollector.h index 5f334df..2c2c033 100644 --- a/src/ScribeCollector.h +++ b/src/ScribeCollector.h @@ -50,10 +50,10 @@ struct ScribeConf : public BaseConf class ScribeCollector : public BaseCollector { - boost::shared_ptr m_socket; - boost::shared_ptr m_transport; - boost::shared_ptr m_protocol; - boost::shared_ptr m_client; + std::shared_ptr m_socket; + std::shared_ptr m_transport; + std::shared_ptr m_protocol; + std::shared_ptr m_client; bool connected(void) const { return m_socket->isOpen(); } @@ -78,4 +78,4 @@ class ScribeCollector : public BaseCollector virtual void send_message(const uint8_t *msg, size_t size) override; }; -} // namespace zipkin \ No newline at end of file +} // namespace zipkin diff --git a/src/Tracer.h b/src/Tracer.h index 31ca6ee..4406047 100644 --- a/src/Tracer.h +++ b/src/Tracer.h @@ -95,7 +95,11 @@ class SpanCache inline void purge_all(void) { - m_spans.consume_all([](CachedSpan *span) -> void { delete span; }); + CachedSpan *span; + + while (m_spans.pop(span)) { + if (span) delete span; + } } inline CachedSpan *get(void) diff --git a/src/XRayCollector.cpp b/src/XRayCollector.cpp index b3c5e91..2207374 100644 --- a/src/XRayCollector.cpp +++ b/src/XRayCollector.cpp @@ -9,7 +9,7 @@ namespace zipkin std::shared_ptr XRayConf::xray(new XRayCodec()); -size_t XRayCodec::encode(boost::shared_ptr buf, const std::vector &spans) +size_t XRayCodec::encode(std::shared_ptr buf, const std::vector &spans) { rapidjson::StringBuffer buffer; diff --git a/src/XRayCollector.h b/src/XRayCollector.h index 4da7ac9..a6b79d3 100644 --- a/src/XRayCollector.h +++ b/src/XRayCollector.h @@ -24,7 +24,7 @@ class XRayCodec : public MessageCodec virtual const std::string mime_type(void) const override { return "application/json"; } - virtual size_t encode(boost::shared_ptr buf, const std::vector &spans) override; + virtual size_t encode(std::shared_ptr buf, const std::vector &spans) override; }; struct XRayConf : public BaseConf @@ -79,4 +79,4 @@ class XRayCollector : public BaseCollector } }; -} // namespace zipkin \ No newline at end of file +} // namespace zipkin diff --git a/test/TestMain.cpp b/test/TestMain.cpp index 11035e5..684424a 100644 --- a/test/TestMain.cpp +++ b/test/TestMain.cpp @@ -1,13 +1,19 @@ -#include #include +#include #include #include +#ifdef GFLAGS_NAMESPACE +using namespace GFLAGS_NAMESPACE; +#else +using namespace gflags; +#endif + int main(int argc, char **argv) { - ::google::ParseCommandLineFlags(&argc, &argv, false); + ParseCommandLineFlags(&argc, &argv, false); ::testing::GTEST_FLAG(throw_on_failure) = true; ::testing::InitGoogleMock(&argc, argv); return RUN_ALL_TESTS(); -} \ No newline at end of file +}