diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 7e93602019..788982121d 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -40,7 +40,7 @@ jobs: ./ci/do_ci.sh cmake.abseil.test cmake_gcc_48_test: - name: CMake gcc 4.8 + name: CMake gcc 4.8 (without otlp exporter) runs-on: ubuntu-18.04 steps: - uses: actions/checkout@v2 @@ -59,6 +59,29 @@ jobs: CC: /usr/bin/gcc-4.8 CXX: /usr/bin/g++-4.8 + cmake_gcc_48_otlp_exporter_test: + name: CMake gcc 4.8 (with otlp exporter) + runs-on: ubuntu-18.04 + steps: + - uses: actions/checkout@v2 + with: + submodules: 'recursive' + - name: setup + run: | + sudo ./ci/setup_ci_environment.sh + sudo ./ci/install_gcc48.sh + - name: setup cmake + run: | + sudo CC=/usr/bin/gcc-4.8 CXX=/usr/bin/g++-4.8 ./ci/setup_cmake.sh + - name: setup grpc + run: | + sudo CC=/usr/bin/gcc-4.8 CXX=/usr/bin/g++-4.8 ./ci/setup_grpc.sh -v 4.8 + - name: run tests + run: ./ci/do_ci.sh cmake.legacy.exporter.otprotocol.test + env: + CC: /usr/bin/gcc-4.8 + CXX: /usr/bin/g++-4.8 + cmake_test_cxx20: name: CMake C++20 test runs-on: ubuntu-20.04 diff --git a/CHANGELOG.md b/CHANGELOG.md index 7e1b02456f..3c1c31f27c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,7 +15,27 @@ Increment the: ## [Unreleased] -* [BUILD] Allow to use local GSL +## [1.0.0-rc4] 2021-08-04 + +* [EXPORTER] `BREAKING CHANGE` Fix default HTTP port for OTLP HTTP Exporter ([#939](https://github.com/open-telemetry/opentelemetry-cpp/pull/939)) +* [API] Fix timeout calculation for Tracer::Flush() and Tracer::Close() ([#937](https://github.com/open-telemetry/opentelemetry-cpp/pull/937)) +* [API] Fix for Stack::Resize that new_capacity is not assigned to capacity_ ([#934](https://github.com/open-telemetry/opentelemetry-cpp/pull/934)) +* [SDK] Fix race condition in circular buffer simulation test ([#931](https://github.com/open-telemetry/opentelemetry-cpp/pull/931)) +* [EXPORTER] Fix error logging in Jaeger Exporter ([#930](https://github.com/open-telemetry/opentelemetry-cpp/pull/930)) +* [BUILD] Use latest grpc version (v1.39.0) for cmake build of otlp exporter ([#927](https://github.com/open-telemetry/opentelemetry-cpp/pull/927)) +* [EXPORTER] Add Jaeger Thrift HTTP exporter ([#926](https://github.com/open-telemetry/opentelemetry-cpp/pull/926)) +* [SDK] Move env-var read logic to common dir, and optional reading of env-var ([#924](https://github.com/open-telemetry/opentelemetry-cpp/pull/924)) +* [EXPORTER] Remove recordable header from CMake install rules for exporters ([#923](https://github.com/open-telemetry/opentelemetry-cpp/pull/923)) +* [EXPORTER] `BREAKING CHANGE` Rename Recordable to JaegerRecordable in Jaeger exporter ([#919](https://github.com/open-telemetry/opentelemetry-cpp/pull/919)) +* [EXPORTER] `BREAKING CHANGE` Rename Jaeger exporter target ([#918](https://github.com/open-telemetry/opentelemetry-cpp/pull/918)) +* [EXPORTER] Add Zipkin exporter example ([#917](https://github.com/open-telemetry/opentelemetry-cpp/pull/917)) +* [EXPORTER] Bazel build for Zipkin exorter ([#916](https://github.com/open-telemetry/opentelemetry-cpp/pull/916)) +* [BUILD] Allow to use local GSL ([#915](https://github.com/open-telemetry/opentelemetry-cpp/pull/915)) +* [DOCS] Document vcpkg toolchain configuration ([#913](https://github.com/open-telemetry/opentelemetry-cpp/pull/913)) +* [SDK] Fix for resource deletion after tracer provider shutdown ([#911](https://github.com/open-telemetry/opentelemetry-cpp/pull/911)) +* [BUILD] Add bazel build for grpc example ([#910](https://github.com/open-telemetry/opentelemetry-cpp/pull/910)) +* [EXPORTER] Add resource and instrumentation library support for OStreamSpanExporter ([#906](https://github.com/open-telemetry/opentelemetry-cpp/pull/906)) +* [API] Adding semantic-convention attributes for trace ([#868](https://github.com/open-telemetry/opentelemetry-cpp/pull/868)) ## [1.0.0-rc3] 2021-07-12 diff --git a/CMakeLists.txt b/CMakeLists.txt index 822e78bf37..8cbd374b3f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -152,7 +152,14 @@ option(WITH_ELASTICSEARCH option(WITH_JAEGER "Whether to include the Jaeger exporter" OFF) +option(WITH_NO_GETENV "Whether the platform supports environment variables" OFF) + option(BUILD_TESTING "Whether to enable tests" ON) + +if(WITH_NO_GENENV) + add_definitions(-DNO_GETENV) +endif() + if(WIN32) add_definitions(-DNOMINMAX) if(BUILD_TESTING) diff --git a/README.md b/README.md index 743032d17d..3677c94478 100644 --- a/README.md +++ b/README.md @@ -78,7 +78,6 @@ Approvers * [Josh Suereth](https://github.com/jsuereth), Google * [Max Golovanov](https://github.com/maxgolov), Microsoft * [Ryan Burn](https://github.com/rnburn), Lightstep -* [Tom Tan](https://github.com/ThomsonTan), Microsoft *Find more about the approver role in [community repository](https://github.com/open-telemetry/community/blob/main/community-membership.md#approver).* @@ -89,6 +88,7 @@ Maintainers * [Emil Mikulic](https://github.com/g-easy), Google * [Lalit Kumar Bhasin](https://github.com/lalitb), Microsoft * [Reiley Yang](https://github.com/reyang), Microsoft +* [Tom Tan](https://github.com/ThomsonTan), Microsoft *Find more about the maintainer role in [community repository](https://github.com/open-telemetry/community/blob/main/community-membership.md#maintainer).* diff --git a/api/include/opentelemetry/context/runtime_context.h b/api/include/opentelemetry/context/runtime_context.h index d648362cee..5cb793b23a 100644 --- a/api/include/opentelemetry/context/runtime_context.h +++ b/api/include/opentelemetry/context/runtime_context.h @@ -294,7 +294,8 @@ class ThreadLocalContextStorage : public RuntimeContextStorage } delete[] base_; } - base_ = temp; + base_ = temp; + capacity_ = new_capacity; } ~Stack() noexcept { delete[] base_; } diff --git a/api/include/opentelemetry/trace/semantic_conventions.h b/api/include/opentelemetry/trace/semantic_conventions.h new file mode 100644 index 0000000000..13c5905783 --- /dev/null +++ b/api/include/opentelemetry/trace/semantic_conventions.h @@ -0,0 +1,189 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +#pragma once + +#include "opentelemetry/common/string_util.h" +#include "opentelemetry/version.h" + +OPENTELEMETRY_BEGIN_NAMESPACE +namespace trace +{ + +#define OTEL_CPP_GET_ATTR(name) attr(OTEL_CPP_CONST_HASHCODE(name)) + +/** + * Stores the Constants for semantic kAttribute names outlined by the OpenTelemetry specifications. + * . + */ +static const struct +{ + uint32_t attribute_id; + const char *attribute_key; +} attribute_ids[] = { + // The set of constants matches the specification as of this commit. + // https://github.com/open-telemetry/opentelemetry-specification/tree/main/specification/trace/semantic_conventions + // https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/trace/semantic_conventions/exceptions.md + + // General network connection attributes + {OTEL_CPP_CONST_HASHCODE(AttrNetTransport), "net.transport"}, + {OTEL_CPP_CONST_HASHCODE(AttrNetPeerIp), "net.peer.ip"}, + {OTEL_CPP_CONST_HASHCODE(AttrNetPeerPort), "net.peer.port"}, + {OTEL_CPP_CONST_HASHCODE(AttrNetPeerName), "net.peer.name"}, + {OTEL_CPP_CONST_HASHCODE(AttrNetHostIp), "net.host.ip"}, + {OTEL_CPP_CONST_HASHCODE(AttrNetHostPort), "net.host.port"}, + {OTEL_CPP_CONST_HASHCODE(AttrNetHostName), "net.host.name"}, + + // General identity attributes + {OTEL_CPP_CONST_HASHCODE(AttrEnduserId), "enduser.id"}, + {OTEL_CPP_CONST_HASHCODE(AttrEnduserRole), "enduser.role"}, + {OTEL_CPP_CONST_HASHCODE(AttrEnduserScope), "enduser.scope"}, + + // General remote service attributes + {OTEL_CPP_CONST_HASHCODE(AttrPeerService), "peer.service"}, + + // General thread attributes + {OTEL_CPP_CONST_HASHCODE(AttrThreadId), "thread.id"}, + {OTEL_CPP_CONST_HASHCODE(AttrThreadName), "thread.name"}, + + // Source Code Attributes + {OTEL_CPP_CONST_HASHCODE(AttrCodeFunction), "code.function"}, + {OTEL_CPP_CONST_HASHCODE(AttrCodeNamespace), "code.namespace"}, + {OTEL_CPP_CONST_HASHCODE(AttrCodeFilepath), "code.filepath"}, + {OTEL_CPP_CONST_HASHCODE(AttrCodeLineno), "code.lineno"}, + + // Http Span Common Attributes + {OTEL_CPP_CONST_HASHCODE(AttrHttpMethod), "http.method"}, + {OTEL_CPP_CONST_HASHCODE(AttrHttpUrl), "http.url"}, + {OTEL_CPP_CONST_HASHCODE(AttrHttpTarget), "http.target"}, + {OTEL_CPP_CONST_HASHCODE(AttrHttpHost), "http.host"}, + {OTEL_CPP_CONST_HASHCODE(AttrHttpScheme), "http.scheme"}, + {OTEL_CPP_CONST_HASHCODE(AttrHttpStatusCode), "http.status_code"}, + {OTEL_CPP_CONST_HASHCODE(AttrHttpFlavor), "http.flavor"}, + {OTEL_CPP_CONST_HASHCODE(AttrHttpUserAgent), "http.user_agent"}, + {OTEL_CPP_CONST_HASHCODE(AttrHttpRequestContentLength), "http.request_content_length"}, + {OTEL_CPP_CONST_HASHCODE(AttrHttpRequestContentLengthUncompressed), + "http.request_content_length_uncompressed"}, + {OTEL_CPP_CONST_HASHCODE(AttrHttpResponseContentLength), "http.response_content_length"}, + {OTEL_CPP_CONST_HASHCODE(AttrHttpResponseContentLengthUncompressed), + "http.response_content_length_uncompressed"}, + + // HTTP Span Client Attributes + // One of the following combinations: + // - http.url + // - http.scheme, http.host, http.target + // - http.scheme, net.peer.name, net.peer.port, http.target + // - http.scheme, net.peer.ip, net.peer.port, http.target + + // HTTP Span Server Attributes + // One of the following combinations: + // -http.scheme, http.host, http.target + // -http.scheme, http.server_name, net.host.port, http.target + // -http.scheme, net.host.name, net.host.port, http.target + // -http.url + {OTEL_CPP_CONST_HASHCODE(AttrHttpServerName), "http.server_name"}, + {OTEL_CPP_CONST_HASHCODE(AttrHttpRoute), "http.route"}, + {OTEL_CPP_CONST_HASHCODE(AttrHttpClientIp), "http.client_ip"}, + + // DB: Connection-level attributes + {OTEL_CPP_CONST_HASHCODE(AttrDbSystem), "db.system"}, // other_sql, mssql, mysql... + {OTEL_CPP_CONST_HASHCODE(AttrDbConnectionString), "db.connection_string"}, + {OTEL_CPP_CONST_HASHCODE(AttrDbUser), "db.user"}, + // DB: Connection-level attributes for specific technologies + {OTEL_CPP_CONST_HASHCODE(AttrDbMssqlInstanceName), "db.mssql.instance_name"}, + {OTEL_CPP_CONST_HASHCODE(AttrDbJdbcDriverClassname), "db.jdbc.driver_classname"}, + // DB: Call-level attributes + {OTEL_CPP_CONST_HASHCODE(AttrDbName), "db.name"}, + {OTEL_CPP_CONST_HASHCODE(AttrDbStatement), "db.statement"}, + {OTEL_CPP_CONST_HASHCODE(AttrDbOperation), "db.operation"}, + // DB: Call-level attributes for specific technologies + {OTEL_CPP_CONST_HASHCODE(AttrDbHbaseNamespace), "db.hbase.namespace"}, + {OTEL_CPP_CONST_HASHCODE(AttrDbRedisDatabaseIndex), "db.redis.database_index"}, + {OTEL_CPP_CONST_HASHCODE(AttrDbMongodbCollection), "db.mongodb.collection"}, + + // // DB: Call-level attributes for Cassandra for clarity + {OTEL_CPP_CONST_HASHCODE(AttrDbCassandraKeyspace), "db.cassandra.keyspace"}, + {OTEL_CPP_CONST_HASHCODE(AttrDbCassandraPageSize), "db.cassandra.page_size"}, + {OTEL_CPP_CONST_HASHCODE(AttrDbCassandraConsistencyLevel), "db.cassandra.consistency_level"}, + {OTEL_CPP_CONST_HASHCODE(AttrDbCassandraTable), "db.cassandra.table"}, + {OTEL_CPP_CONST_HASHCODE(AttrDbCassandraIdempotence), "db.cassandra.idempotence"}, + {OTEL_CPP_CONST_HASHCODE(AttrDbCassandraSpeculativeExecutionCount), + "db.cassandra.speculative_execution_count"}, + {OTEL_CPP_CONST_HASHCODE(AttrDbCassandraCoordinatorId), "db.cassandra.coordinator.id"}, + {OTEL_CPP_CONST_HASHCODE(AttrDbCassandraCoordinatorDC), "db.cassandra.coordinator.dc"}, + + // Common RPC attributes + {OTEL_CPP_CONST_HASHCODE(AttrRpcSystem), "rpc.system"}, + {OTEL_CPP_CONST_HASHCODE(AttrRpcService), "rpc.service"}, + {OTEL_CPP_CONST_HASHCODE(AttrRpcMethod), "rpc.method"}, + // gRPC attributes + {OTEL_CPP_CONST_HASHCODE(AttrRpcGrpcStatusCode), "rpc.grpc.status_code"}, + // JSON-RPC attributes + {OTEL_CPP_CONST_HASHCODE(AttrRpcJsonrpcVersion), "rpc.jsonrpc.version"}, + {OTEL_CPP_CONST_HASHCODE(AttrRpcJsonrpcRequestId), "rpc.jsonrpc.request_id"}, + {OTEL_CPP_CONST_HASHCODE(AttrRpcJsonrpcErrorCode), "rpc.jsonrpc.error_code"}, + {OTEL_CPP_CONST_HASHCODE(AttrRpcJsonrpcErrorMessage), "rpc.jsonrpc.error_message"}, + + // faas: General Attributes + {OTEL_CPP_CONST_HASHCODE(AttrFaasTrigger), "faas.trigger"}, + {OTEL_CPP_CONST_HASHCODE(AttrFaasExecution), "faas.execution"}, + // faas: incoming invocations + {OTEL_CPP_CONST_HASHCODE(AttrFaasColdStart), "faas.coldstart"}, + // faas: outgoing invocations + {OTEL_CPP_CONST_HASHCODE(AttrFaasInvokedName), "faas.invoked_name"}, + {OTEL_CPP_CONST_HASHCODE(AttrFaasInvokedProvider), "faas.invoked_provider"}, + {OTEL_CPP_CONST_HASHCODE(AttrFaasInvokedRegion), "faas.invoked_region"}, + // faas: datastore trigger + {OTEL_CPP_CONST_HASHCODE(AttrFaasDocumentCollection), "faas.document.collection"}, + {OTEL_CPP_CONST_HASHCODE(AttrFaasDocumentOperation), "faas.document.operation"}, + {OTEL_CPP_CONST_HASHCODE(AttrFaasDocumentTime), "faas.document.time"}, + {OTEL_CPP_CONST_HASHCODE(AttrFaasDocumentName), "faas.document.name"}, + // faas: timer trigger + {OTEL_CPP_CONST_HASHCODE(AttrFaasTime), "faas.time"}, + {OTEL_CPP_CONST_HASHCODE(AttrFaasCron), "faas.cron"}, + + // messaging attributes + {OTEL_CPP_CONST_HASHCODE(AttrMessagingSystem), "messaging.system"}, + {OTEL_CPP_CONST_HASHCODE(AttrMessagingDestination), "messaging.destination"}, + {OTEL_CPP_CONST_HASHCODE(AttrMessagingDestinationKind), "messaging.destination_kind"}, + {OTEL_CPP_CONST_HASHCODE(AttrMessagingTempDestination), "messaging.temp_destination"}, + {OTEL_CPP_CONST_HASHCODE(AttrMessagingProtocol), "messaging.protocol"}, + {OTEL_CPP_CONST_HASHCODE(AttrMessagingProtocolVersion), "messaging.protocol_version"}, + {OTEL_CPP_CONST_HASHCODE(AttrMessagingUrl), "messaging.url"}, + {OTEL_CPP_CONST_HASHCODE(AttrMessagingMessageId), "messaging.message_id"}, + {OTEL_CPP_CONST_HASHCODE(AttrMessagingConversationId), "messaging.conversation_id"}, + {OTEL_CPP_CONST_HASHCODE(AttrMessagingPayloadSize), "messaging.message_payload_size_bytes"}, + {OTEL_CPP_CONST_HASHCODE(AttrMessagingPayloadCompressedSize), + "messaging.message_payload_compressed_size_bytes"}, + {OTEL_CPP_CONST_HASHCODE(AttrMessagingOperation), "messaging.operation"}, + // messaging attributes specific to messaging systems + {OTEL_CPP_CONST_HASHCODE(AttrMessagingRabbitMQRoutingKey), "messaging.rabbitmq.routing_key"}, + {OTEL_CPP_CONST_HASHCODE(AttrMessagingKafkaMessageKey), "messaging.kafka.message_key"}, + {OTEL_CPP_CONST_HASHCODE(AttrMessagingKafkaConsumerGroup), "messaging.kafka.consumer_group"}, + {OTEL_CPP_CONST_HASHCODE(AttrMessagingKafkaClientId), "messaging.kafka.client_id"}, + {OTEL_CPP_CONST_HASHCODE(AttrMessagingKafkaPartition), "messaging.kafka.partition"}, + {OTEL_CPP_CONST_HASHCODE(AttrMessagingKafkaTombstone), "messaging.kafka.tombstone"}, + + // Exceptions attributes + {OTEL_CPP_CONST_HASHCODE(AttrExceptionType), "exception.type"}, + {OTEL_CPP_CONST_HASHCODE(AttrExceptionMessage), "exception.message"}, + {OTEL_CPP_CONST_HASHCODE(AttrExceptionStacktrace), "exception.stacktrace"}, + {OTEL_CPP_CONST_HASHCODE(AttrExceptionEscapted), "exception.escaped"}, +}; +// function to generate hash code for semantic conventions attributes. + +#define OTEL_CPP_TRACE_ATTRIBUTES_MAX (sizeof(attribute_ids) / sizeof(attribute_ids[0])) + +inline const char *attr(uint32_t attr) +{ + for (int i = 0; i < OTEL_CPP_TRACE_ATTRIBUTES_MAX; i++) + { + if (attribute_ids[i].attribute_id == attr) + return attribute_ids[i].attribute_key; + } + return ""; +} + +} // namespace trace +OPENTELEMETRY_END_NAMESPACE diff --git a/api/include/opentelemetry/trace/tracer.h b/api/include/opentelemetry/trace/tracer.h index 57761e5f90..425e085116 100644 --- a/api/include/opentelemetry/trace/tracer.h +++ b/api/include/opentelemetry/trace/tracer.h @@ -170,8 +170,8 @@ class Tracer template void ForceFlush(std::chrono::duration timeout) noexcept { - this->ForceFlushWithMicroseconds( - static_cast(std::chrono::duration_cast(timeout))); + this->ForceFlushWithMicroseconds(static_cast( + std::chrono::duration_cast(timeout).count())); } virtual void ForceFlushWithMicroseconds(uint64_t timeout) noexcept = 0; @@ -183,8 +183,8 @@ class Tracer template void Close(std::chrono::duration timeout) noexcept { - this->CloseWithMicroseconds( - static_cast(std::chrono::duration_cast(timeout))); + this->CloseWithMicroseconds(static_cast( + std::chrono::duration_cast(timeout).count())); } virtual void CloseWithMicroseconds(uint64_t timeout) noexcept = 0; diff --git a/api/include/opentelemetry/version.h b/api/include/opentelemetry/version.h index 3b47480fd4..d5e80a799c 100644 --- a/api/include/opentelemetry/version.h +++ b/api/include/opentelemetry/version.h @@ -6,7 +6,7 @@ #include "opentelemetry/detail/preprocessor.h" #define OPENTELEMETRY_ABI_VERSION_NO 0 -#define OPENTELEMETRY_VERSION "1.0.0-rc3" +#define OPENTELEMETRY_VERSION "1.0.0-rc4" #define OPENTELEMETRY_ABI_VERSION OPENTELEMETRY_STRINGIFY(OPENTELEMETRY_ABI_VERSION_NO) // clang-format off diff --git a/ci/do_ci.sh b/ci/do_ci.sh index 483194c373..3c1be05119 100755 --- a/ci/do_ci.sh +++ b/ci/do_ci.sh @@ -92,6 +92,22 @@ elif [[ "$1" == "cmake.legacy.test" ]]; then make make test exit 0 +elif [[ "$1" == "cmake.legacy.exporter.otprotocol.test" ]]; then + cd "${BUILD_DIR}" + rm -rf * + export BUILD_ROOT="${BUILD_DIR}" + ${SRC_DIR}/tools/build-gtest.sh + ${SRC_DIR}/tools/build-benchmark.sh + cmake -DCMAKE_BUILD_TYPE=Debug \ + -DCMAKE_CXX_STANDARD=11 \ + -DWITH_OTLP=ON \ + "${SRC_DIR}" + grpc_cpp_plugin=`which grpc_cpp_plugin` + proto_make_file="CMakeFiles/opentelemetry_proto.dir/build.make" + sed -i "s~gRPC_CPP_PLUGIN_EXECUTABLE-NOTFOUND~$grpc_cpp_plugin~" ${proto_make_file} #fixme + make -j $(nproc) + cd exporters/otlp && make test + exit 0 elif [[ "$1" == "cmake.exporter.otprotocol.test" ]]; then cd "${BUILD_DIR}" rm -rf * diff --git a/ci/setup_grpc.sh b/ci/setup_grpc.sh index 98780bb943..f6c1f9885a 100755 --- a/ci/setup_grpc.sh +++ b/ci/setup_grpc.sh @@ -5,7 +5,30 @@ set -e export DEBIAN_FRONTEND=noninteractive +old_grpc_version='v1.33.2' +new_grpc_version='v1.39.0' +gcc_version_for_new_grpc='5.1' +install_grpc_version=${new_grpc_version} +grpc_version='v1.39.0' +usage() { echo "Usage: $0 -v " 1>&2; exit 1; } +while getopts ":v:" o; do + case "${o}" in + v) + gcc_version=${OPTARG} + ;; + *) + usage + ;; + esac +done +if [ -z "${gcc_version}" ]; then + gcc_version=`gcc --version | awk '/gcc/ {print $NF}'` +fi +if [[ "${gcc_version}" < "${gcc_version_for_new_grpc}" ]]; then + echo "less" + install_grpc_version=${old_grpc_version} +fi if ! type cmake > /dev/null; then #cmake not installed, exiting exit 1 @@ -13,18 +36,26 @@ fi export BUILD_DIR=/tmp/ export INSTALL_DIR=/usr/local/ pushd $BUILD_DIR -git clone --depth=1 -b v1.34.0 https://github.com/grpc/grpc -cd grpc +echo "installing grpc version: ${install_grpc_version}" +git clone --depth=1 -b ${install_grpc_version} https://github.com/grpc/grpc +pushd grpc git submodule init git submodule update --depth 1 -mkdir -p cmake/build -pushd cmake/build +mkdir -p "third_party/abseil-cpp/build" && pushd "third_party/abseil-cpp/build" +cmake -DCMAKE_BUILD_TYPE=Release \ + -DCMAKE_POSITION_INDEPENDENT_CODE=TRUE \ + -DCMAKE_INSTALL_PREFIX=$INSTALL_DIR .. +make -j${nproc} install && popd +mkdir -p build && pushd build cmake -DgRPC_INSTALL=ON \ + -DCMAKE_CXX_STANDARD=11 \ -DgRPC_BUILD_TESTS=OFF \ -DCMAKE_INSTALL_PREFIX=$INSTALL_DIR \ - ../.. + -DCMAKE_PREFIX_PATH=$INSTALL_DIR \ + .. make -j $(nproc) make install popd popd + export PATH=${INSTALL_DIR}/bin:$PATH # ensure to use the installed grpc diff --git a/docs/public/conf.py b/docs/public/conf.py index aededfa31d..ca31a83306 100644 --- a/docs/public/conf.py +++ b/docs/public/conf.py @@ -21,7 +21,7 @@ author = 'OpenTelemetry authors' # The full version, including alpha/beta/rc tags -release = '1.0.0-rc3' +release = '1.0.0-rc4' # Run sphinx on subprojects and copy output # ----------------------------------------- diff --git a/examples/grpc/client.cpp b/examples/grpc/client.cpp index 472a933b98..fc170a7c5b 100644 --- a/examples/grpc/client.cpp +++ b/examples/grpc/client.cpp @@ -8,6 +8,7 @@ #include "messages.grpc.pb.h" #endif +#include "opentelemetry/trace/semantic_conventions.h" #include "tracer_common.h" #include #include @@ -26,6 +27,7 @@ using grpc_example::GreetResponse; namespace { +using namespace opentelemetry::trace; class GreeterClient { public: @@ -44,11 +46,11 @@ class GreeterClient std::string span_name = "GreeterClient/Greet"; auto span = get_tracer("grpc")->StartSpan(span_name, - {{"rpc.system", "grpc"}, - {"rpc.service", "grpc-example.GreetService"}, - {"rpc.method", "Greet"}, - {"net.peer.ip", ip}, - {"net.peer.port", port}}, + {{OTEL_CPP_GET_ATTR(AttrRpcSystem), "grpc"}, + {OTEL_CPP_GET_ATTR(AttrRpcService), "grpc-example.GreetService"}, + {OTEL_CPP_GET_ATTR(AttrRpcMethod), "Greet"}, + {OTEL_CPP_GET_ATTR(AttrNetPeerIp), ip}, + {OTEL_CPP_GET_ATTR(AttrNetPeerPort), port}}, options); auto scope = get_tracer("grpc-client")->WithActiveSpan(span); @@ -64,7 +66,7 @@ class GreeterClient if (status.ok()) { span->SetStatus(opentelemetry::trace::StatusCode::kOk); - span->SetAttribute("rpc.grpc.status_code", status.error_code()); + span->SetAttribute(OTEL_CPP_GET_ATTR(AttrRpcGrpcStatusCode), status.error_code()); // Make sure to end your spans! span->End(); return response.response(); @@ -73,7 +75,7 @@ class GreeterClient { std::cout << status.error_code() << ": " << status.error_message() << std::endl; span->SetStatus(opentelemetry::trace::StatusCode::kError); - span->SetAttribute("rpc.grpc.status_code", status.error_code()); + span->SetAttribute(OTEL_CPP_GET_ATTR(AttrRpcGrpcStatusCode), status.error_code()); // Make sure to end your spans! span->End(); return "RPC failed"; diff --git a/examples/grpc/server.cpp b/examples/grpc/server.cpp index 6bbdfc64ba..b22ad2a6ca 100644 --- a/examples/grpc/server.cpp +++ b/examples/grpc/server.cpp @@ -5,6 +5,7 @@ #endif #include "tracer_common.h" #include "opentelemetry/trace/span_context_kv_iterable_view.h" +#include "opentelemetry/trace/semantic_conventions.h" #include #include @@ -30,6 +31,7 @@ using grpc_example::GreetResponse; using Span = opentelemetry::trace::Span; using SpanContext = opentelemetry::trace::SpanContext; +using namespace opentelemetry::trace; namespace { @@ -59,10 +61,10 @@ class GreeterServer final : public Greeter::Service std::string span_name = "GreeterService/Greet"; auto span = get_tracer("grpc") ->StartSpan(span_name, - {{"rpc.system", "grpc"}, - {"rpc.service", "GreeterService"}, - {"rpc.method", "Greet"}, - {"rpc.grpc.status_code", 0}}, + {{OTEL_CPP_GET_ATTR(AttrRpcSystem), "grpc"}, + {OTEL_CPP_GET_ATTR(AttrRpcService), "GreeterService"}, + {OTEL_CPP_GET_ATTR(AttrRpcMethod), "Greet"}, + {OTEL_CPP_GET_ATTR(AttrRpcGrpcStatusCode), 0}}, options); auto scope = get_tracer("grpc")->WithActiveSpan(span); diff --git a/examples/http/client.cc b/examples/http/client.cc index aa6bc86af7..77694815a1 100644 --- a/examples/http/client.cc +++ b/examples/http/client.cc @@ -3,11 +3,14 @@ #include "opentelemetry/ext/http/client/http_client_factory.h" #include "opentelemetry/ext/http/common/url_parser.h" +#include "opentelemetry/trace/semantic_conventions.h" #include "tracer_common.h" namespace { +using namespace opentelemetry::trace; + void sendRequest(const std::string &url) { auto http_client = opentelemetry::ext::http::client::HttpClientFactory::CreateSync(); @@ -20,9 +23,9 @@ void sendRequest(const std::string &url) std::string span_name = url_parser.path_; auto span = get_tracer("http-client") ->StartSpan(span_name, - {{"http.url", url_parser.url_}, - {"http.scheme", url_parser.scheme_}, - {"http.method", "GET"}}, + {{OTEL_CPP_GET_ATTR(AttrHttpUrl), url_parser.url_}, + {OTEL_CPP_GET_ATTR(AttrHttpScheme), url_parser.scheme_}, + {OTEL_CPP_GET_ATTR(AttrHttpMethod), "GET"}}, options); auto scope = get_tracer("http-client")->WithActiveSpan(span); @@ -38,7 +41,7 @@ void sendRequest(const std::string &url) { // set span attributes auto status_code = result.GetResponse().GetStatusCode(); - span->SetAttribute("http.status_code", status_code); + span->SetAttribute(OTEL_CPP_GET_ATTR(AttrHttpStatusCode), status_code); result.GetResponse().ForEachHeader([&span](opentelemetry::nostd::string_view header_name, opentelemetry::nostd::string_view header_value) { span->SetAttribute("http.header." + std::string(header_name.data()), header_value); diff --git a/examples/http/server.cc b/examples/http/server.cc index 8a9c437d60..6c1c9ce713 100644 --- a/examples/http/server.cc +++ b/examples/http/server.cc @@ -2,6 +2,7 @@ // SPDX-License-Identifier: Apache-2.0 #include "server.h" +#include "opentelemetry/trace/semantic_conventions.h" #include "tracer_common.h" #include @@ -9,6 +10,9 @@ namespace { + +using namespace opentelemetry::trace; +; uint16_t server_port = 8800; constexpr const char *server_name = "localhost"; @@ -31,17 +35,16 @@ class RequestHandler : public HTTP_SERVER_NS::HttpRequestCallback options.parent = opentelemetry::trace::propagation::GetSpan(new_context)->GetContext(); // start span with parent context extracted from http header - auto span = - get_tracer("http-server") - ->StartSpan( - span_name, - {{"http.server_name", server_name}, - {"net.host.port", server_port}, - {"http.method", request.method}, - {"http.scheme", "http"}, - {"http.request_content_length", static_cast(request.content.length())}, - {"http.client_ip", request.client}}, - options); + auto span = get_tracer("http-server") + ->StartSpan(span_name, + {{OTEL_CPP_GET_ATTR(AttrHttpServerName), server_name}, + {OTEL_CPP_GET_ATTR(AttrNetHostPort), server_port}, + {OTEL_CPP_GET_ATTR(AttrHttpMethod), request.method}, + {OTEL_CPP_GET_ATTR(AttrHttpScheme), "http"}, + {OTEL_CPP_GET_ATTR(AttrHttpRequestContentLength), + static_cast(request.content.length())}, + {OTEL_CPP_GET_ATTR(AttrHttpClientIp), request.client}}, + options); auto scope = get_tracer("http_server")->WithActiveSpan(span); diff --git a/examples/jaeger/main.cc b/examples/jaeger/main.cc index f3f94884ca..63ed476aad 100644 --- a/examples/jaeger/main.cc +++ b/examples/jaeger/main.cc @@ -33,7 +33,7 @@ int main(int argc, char *argv[]) { if (argc == 2) { - opts.server_addr = argv[1]; + opts.endpoint = argv[1]; } // Removing this line will leave the default noop TracerProvider in place. InitTracer(); diff --git a/exporters/elasticsearch/CMakeLists.txt b/exporters/elasticsearch/CMakeLists.txt index cad3b044ee..8f675e530a 100644 --- a/exporters/elasticsearch/CMakeLists.txt +++ b/exporters/elasticsearch/CMakeLists.txt @@ -22,7 +22,8 @@ install( DIRECTORY include/opentelemetry/exporters/elasticsearch DESTINATION include/opentelemetry/exporters/ FILES_MATCHING - PATTERN "*.h") + PATTERN "*.h" + PATTERN "es_log_recordable.h" EXCLUDE) if(BUILD_TESTING) add_executable(es_log_exporter_test test/es_log_exporter_test.cc) diff --git a/exporters/elasticsearch/src/es_log_exporter.cc b/exporters/elasticsearch/src/es_log_exporter.cc index c7201db907..777bfb9426 100644 --- a/exporters/elasticsearch/src/es_log_exporter.cc +++ b/exporters/elasticsearch/src/es_log_exporter.cc @@ -3,8 +3,11 @@ #ifdef ENABLE_LOGS_PREVIEW +# include // std::stringstream + # include "opentelemetry/exporters/elasticsearch/es_log_exporter.h" # include "opentelemetry/exporters/elasticsearch/es_log_recordable.h" +# include "opentelemetry/sdk_config.h" namespace nostd = opentelemetry::nostd; namespace sdklogs = opentelemetry::sdk::logs; @@ -74,23 +77,19 @@ class ResponseHandler : public http_client::EventHandler switch (state) { case http_client::SessionState::ConnectFailed: - if (console_debug_) - std::cout << "Connection to elasticsearch failed\n"; + OTEL_INTERNAL_LOG_ERROR("[ES Trace Exporter] Connection to elasticsearch failed"); cv_.notify_all(); break; case http_client::SessionState::SendFailed: - if (console_debug_) - std::cout << "Request failed to be sent to elasticsearch\n"; + OTEL_INTERNAL_LOG_ERROR("[ES Trace Exporter] Request failed to be sent to elasticsearch"); cv_.notify_all(); break; case http_client::SessionState::TimedOut: - if (console_debug_) - std::cout << "Request to elasticsearch timed out\n"; + OTEL_INTERNAL_LOG_ERROR("[ES Trace Exporter] Request to elasticsearch timed out"); cv_.notify_all(); break; case http_client::SessionState::NetworkError: - if (console_debug_) - std::cout << "Network error to elasticsearch\n"; + OTEL_INTERNAL_LOG_ERROR("[ES Trace Exporter] Network error to elasticsearch"); cv_.notify_all(); break; } @@ -131,11 +130,8 @@ sdk::common::ExportResult ElasticsearchLogExporter::Export( // Return failure if this exporter has been shutdown if (is_shutdown_) { - if (options_.console_debug_) - { - std::cout << "Export failed, exporter is shutdown" << std::endl; - } + OTEL_INTERNAL_LOG_ERROR("[ES Trace Exporter] Export failed, exporter is shutdown"); return sdk::common::ExportResult::kFailure; } @@ -172,8 +168,9 @@ sdk::common::ExportResult ElasticsearchLogExporter::Export( // Wait for the response to be received if (options_.console_debug_) { - std::cout << "waiting for response from Elasticsearch (timeout = " << options_.response_timeout_ - << " seconds)" << std::endl; + OTEL_INTERNAL_LOG_DEBUG( + "[ES Trace Exporter] waiting for response from Elasticsearch (timeout = " + << options_.response_timeout_ << " seconds)"); } bool write_successful = handler->waitForResponse(); @@ -191,12 +188,9 @@ sdk::common::ExportResult ElasticsearchLogExporter::Export( std::string responseBody = handler->GetResponseBody(); if (responseBody.find("\"failed\" : 0") == std::string::npos) { - if (options_.console_debug_) - { - std::cout << "Logs were not written to Elasticsearch correctly, response body:" << std::endl; - std::cout << responseBody << std::endl; - } - + OTEL_INTERNAL_LOG_ERROR( + "[ES Trace Exporter] Logs were not written to Elasticsearch correctly, response body: " + << responseBody); // TODO: Retry logic return sdk::common::ExportResult::kFailure; } diff --git a/exporters/jaeger/CMakeLists.txt b/exporters/jaeger/CMakeLists.txt index 2e99e9d438..0ae9162c61 100644 --- a/exporters/jaeger/CMakeLists.txt +++ b/exporters/jaeger/CMakeLists.txt @@ -10,15 +10,19 @@ set(JAEGER_THRIFT_GENCPP_SOURCES thrift-gen/zipkincore_types.cpp) set(JAEGER_EXPORTER_SOURCES - src/jaeger_exporter.cc src/thrift_sender.cc src/udp_transport.cc - src/recordable.cc src/TUDPTransport.cc) + src/jaeger_exporter.cc + src/thrift_sender.cc + src/udp_transport.cc + src/recordable.cc + src/TUDPTransport.cc + src/http_transport.cc + src/THttpTransport.cc) add_library(opentelemetry_exporter_jaeger_trace ${JAEGER_EXPORTER_SOURCES} ${JAEGER_THRIFT_GENCPP_SOURCES}) -set_target_properties( - opentelemetry_exporter_jaeger_trace - PROPERTIES EXPORT_NAME opentelemetry_exporter_jaeger_trace) +set_target_properties(opentelemetry_exporter_jaeger_trace + PROPERTIES EXPORT_NAME jaeger_trace_exporter) target_include_directories( opentelemetry_exporter_jaeger_trace @@ -27,7 +31,7 @@ target_include_directories( target_link_libraries( opentelemetry_exporter_jaeger_trace - PUBLIC opentelemetry_resources + PUBLIC opentelemetry_resources http_client_curl PRIVATE thrift::thrift) if(MSVC) @@ -50,7 +54,8 @@ install( DIRECTORY include/opentelemetry/exporters/jaeger DESTINATION include/opentelemetry/exporters/ FILES_MATCHING - PATTERN "*.h") + PATTERN "*.h" + PATTERN "recordable.h" EXCLUDE) if(BUILD_TESTING) add_executable(jaeger_recordable_test test/jaeger_recordable_test.cc) diff --git a/exporters/jaeger/include/opentelemetry/exporters/jaeger/jaeger_exporter.h b/exporters/jaeger/include/opentelemetry/exporters/jaeger/jaeger_exporter.h index 4e046ad7d1..31f6a8bf35 100644 --- a/exporters/jaeger/include/opentelemetry/exporters/jaeger/jaeger_exporter.h +++ b/exporters/jaeger/include/opentelemetry/exporters/jaeger/jaeger_exporter.h @@ -3,6 +3,7 @@ #pragma once +#include #include OPENTELEMETRY_BEGIN_NAMESPACE @@ -25,10 +26,11 @@ class ThriftSender; */ struct JaegerExporterOptions { - // The endpoint to export to. - std::string server_addr = "localhost"; - uint16_t server_port = 6831; TransportFormat transport_format = TransportFormat::kThriftUdpCompact; + std::string endpoint = "localhost"; + uint16_t server_port = 6831; + // Only applicable when using kThriftHttp transport. + ext::http::client::Headers headers; }; namespace trace_sdk = opentelemetry::sdk::trace; diff --git a/exporters/jaeger/src/THttpTransport.cc b/exporters/jaeger/src/THttpTransport.cc new file mode 100644 index 0000000000..cbb1b65cb2 --- /dev/null +++ b/exporters/jaeger/src/THttpTransport.cc @@ -0,0 +1,61 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +#include "THttpTransport.h" +#include "opentelemetry/ext/http/client/http_client_factory.h" + +OPENTELEMETRY_BEGIN_NAMESPACE +namespace exporter +{ +namespace jaeger +{ + +THttpTransport::THttpTransport(std::string endpoint, ext::http::client::Headers extra_headers) + : endpoint(std::move(endpoint)), + headers(std::move(extra_headers)), + client(ext::http::client::HttpClientFactory::CreateSync()) +{ + headers.insert({{"Content-Type", "application/vnd.apache.thrift.binary"}}); +} + +THttpTransport::~THttpTransport() {} + +bool THttpTransport::isOpen() const +{ + return true; +} + +uint32_t THttpTransport::read(uint8_t *buf, uint32_t len) +{ + (void)buf; + (void)len; + return 0; +} + +void THttpTransport::write(const uint8_t *buf, uint32_t len) +{ + request_buffer.insert(request_buffer.end(), buf, buf + len); +} + +bool THttpTransport::sendSpans() +{ + auto result = client->Post(endpoint, request_buffer, headers); + request_buffer.clear(); + + // TODO: Add logging once global log handling is available. + if (!result) + { + return false; + } + + if (result.GetResponse().GetStatusCode() >= 400) + { + return false; + } + + return true; +} + +} // namespace jaeger +} // namespace exporter +OPENTELEMETRY_END_NAMESPACE diff --git a/exporters/jaeger/src/THttpTransport.h b/exporters/jaeger/src/THttpTransport.h new file mode 100644 index 0000000000..9c796e67a0 --- /dev/null +++ b/exporters/jaeger/src/THttpTransport.h @@ -0,0 +1,40 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +#pragma once + +#include +#include + +#include + +OPENTELEMETRY_BEGIN_NAMESPACE +namespace exporter +{ +namespace jaeger +{ + +class THttpTransport : public apache::thrift::transport::TVirtualTransport +{ +public: + THttpTransport(std::string endpoint, ext::http::client::Headers extra_headers); + ~THttpTransport() override; + + bool isOpen() const override; + + uint32_t read(uint8_t *buf, uint32_t len); + + void write(const uint8_t *buf, uint32_t len); + + bool sendSpans(); + +private: + std::string endpoint; + ext::http::client::Headers headers; + std::shared_ptr client; + std::vector request_buffer; +}; + +} // namespace jaeger +} // namespace exporter +OPENTELEMETRY_END_NAMESPACE diff --git a/exporters/jaeger/src/TUDPTransport.cc b/exporters/jaeger/src/TUDPTransport.cc index 123ba66d96..c72881df91 100644 --- a/exporters/jaeger/src/TUDPTransport.cc +++ b/exporters/jaeger/src/TUDPTransport.cc @@ -1,7 +1,10 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 +#include // std::stringstream + #include "TUDPTransport.h" +#include "opentelemetry/sdk_config.h" OPENTELEMETRY_BEGIN_NAMESPACE namespace exporter @@ -51,7 +54,7 @@ void TUDPTransport::open() if (error) { - // TODO: log error + OTEL_INTERNAL_LOG_ERROR("Jaeger Exporter: getaddrinfo failed with error: " << error); return; } diff --git a/exporters/jaeger/src/http_transport.cc b/exporters/jaeger/src/http_transport.cc new file mode 100644 index 0000000000..f804ccc843 --- /dev/null +++ b/exporters/jaeger/src/http_transport.cc @@ -0,0 +1,37 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +#include "http_transport.h" + +#include + +OPENTELEMETRY_BEGIN_NAMESPACE +namespace exporter +{ +namespace jaeger +{ + +using TBinaryProtocol = apache::thrift::protocol::TBinaryProtocol; +using TTransport = apache::thrift::transport::TTransport; + +HttpTransport::HttpTransport(std::string endpoint, ext::http::client::Headers headers) +{ + endpoint_transport_ = std::make_shared(std::move(endpoint), std::move(headers)); + protocol_ = std::shared_ptr(new TBinaryProtocol(endpoint_transport_)); +} + +int HttpTransport::EmitBatch(const thrift::Batch &batch) +{ + batch.write(protocol_.get()); + + if (!endpoint_transport_->sendSpans()) + { + return 0; + } + + return static_cast(batch.spans.size()); +} + +} // namespace jaeger +} // namespace exporter +OPENTELEMETRY_END_NAMESPACE diff --git a/exporters/jaeger/src/http_transport.h b/exporters/jaeger/src/http_transport.h new file mode 100644 index 0000000000..8f5c9c0571 --- /dev/null +++ b/exporters/jaeger/src/http_transport.h @@ -0,0 +1,39 @@ +#pragma once + +#include "THttpTransport.h" +#include "transport.h" + +#include +#include +#include +#include + +OPENTELEMETRY_BEGIN_NAMESPACE +namespace exporter +{ +namespace jaeger +{ + +using TProtocol = apache::thrift::protocol::TProtocol; + +class HttpTransport : public Transport +{ +public: + HttpTransport(std::string endpoint, ext::http::client::Headers headers); + + int EmitBatch(const thrift::Batch &batch) override; + + uint32_t MaxPacketSize() const override + { + // Default to 4 MiB POST body size. + return 1 << 22; + } + +private: + std::shared_ptr endpoint_transport_; + std::shared_ptr protocol_; +}; + +} // namespace jaeger +} // namespace exporter +OPENTELEMETRY_END_NAMESPACE diff --git a/exporters/jaeger/src/jaeger_exporter.cc b/exporters/jaeger/src/jaeger_exporter.cc index 5546248c82..2bf181c54a 100644 --- a/exporters/jaeger/src/jaeger_exporter.cc +++ b/exporters/jaeger/src/jaeger_exporter.cc @@ -5,6 +5,7 @@ #include #include +#include "http_transport.h" #include "thrift_sender.h" #include "udp_transport.h" @@ -64,14 +65,21 @@ void JaegerExporter::InitializeEndpoint() { // TODO: do we need support any authentication mechanism? auto transport = std::unique_ptr( - static_cast(new UDPTransport(options_.server_addr, options_.server_port))); + static_cast(new UDPTransport(options_.endpoint, options_.server_port))); sender_ = std::unique_ptr(new ThriftSender(std::move(transport))); + return; } - else + + if (options_.transport_format == TransportFormat::kThriftHttp) { - // The transport format is not implemented. - assert(false); + auto transport = + std::unique_ptr(new HttpTransport(options_.endpoint, options_.headers)); + sender_ = std::unique_ptr(new ThriftSender(std::move(transport))); + return; } + + // The transport format is not implemented. + assert(false); } } // namespace jaeger diff --git a/exporters/jaeger/src/thrift_sender.cc b/exporters/jaeger/src/thrift_sender.cc index 66feb6c64c..770bb81991 100644 --- a/exporters/jaeger/src/thrift_sender.cc +++ b/exporters/jaeger/src/thrift_sender.cc @@ -79,11 +79,11 @@ int ThriftSender::Flush() batch.__set_process(process_); batch.__set_spans(span_buffer_); - transport_->EmitBatch(batch); + int spans_flushed = transport_->EmitBatch(batch); ResetBuffers(); - return static_cast(batch.spans.size()); + return spans_flushed; } void ThriftSender::Close() diff --git a/exporters/jaeger/src/transport.h b/exporters/jaeger/src/transport.h index a507d5b4a3..8121e30076 100644 --- a/exporters/jaeger/src/transport.h +++ b/exporters/jaeger/src/transport.h @@ -21,8 +21,8 @@ class Transport Transport() = default; virtual ~Transport() = default; - virtual void EmitBatch(const thrift::Batch &batch) = 0; - virtual uint32_t MaxPacketSize() const = 0; + virtual int EmitBatch(const thrift::Batch &batch) = 0; + virtual uint32_t MaxPacketSize() const = 0; }; } // namespace jaeger diff --git a/exporters/jaeger/src/udp_transport.cc b/exporters/jaeger/src/udp_transport.cc index 82624ae313..306a0e97fc 100644 --- a/exporters/jaeger/src/udp_transport.cc +++ b/exporters/jaeger/src/udp_transport.cc @@ -1,6 +1,9 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 +#include // std::stringstream + +#include "opentelemetry/sdk_config.h" #include "udp_transport.h" OPENTELEMETRY_BEGIN_NAMESPACE @@ -36,11 +39,11 @@ void UDPTransport::InitSocket() int err = WSAStartup(wVersionRequested, &wsaData); if (err != 0) { - // TODO: handle error + OTEL_INTERNAL_LOG_ERROR("Jaeger Exporter: WSAStartup failed with error: " << err); return; } - /* Confirm that the WinSock DLL supports 2.2.*/ + /* Confirm that the WinSock DLL supports 2.2. */ /* Note that if the DLL supports versions greater */ /* than 2.2 in addition to 2.2, it will still return */ /* 2.2 in wVersion since that is the version we */ @@ -48,7 +51,9 @@ void UDPTransport::InitSocket() if (LOBYTE(wsaData.wVersion) != 2 || HIBYTE(wsaData.wVersion) != 2) { - // TODO: handle error that WinSock 2.2 is not supported. + OTEL_INTERNAL_LOG_ERROR("Jaeger Exporter: winsock " << LOBYTE(wsaData.wVersion) << "." + << HIBYTE(wsaData.wVersion) + << " is not supported."); WSACleanup(); return; @@ -63,7 +68,7 @@ void UDPTransport::CleanSocket() #endif } -void UDPTransport::EmitBatch(const thrift::Batch &batch) +int UDPTransport::EmitBatch(const thrift::Batch &batch) { try { @@ -71,6 +76,8 @@ void UDPTransport::EmitBatch(const thrift::Batch &batch) } catch (...) {} + + return static_cast(batch.spans.size()); } } // namespace jaeger diff --git a/exporters/jaeger/src/udp_transport.h b/exporters/jaeger/src/udp_transport.h index b75987e4a5..0997a27c63 100644 --- a/exporters/jaeger/src/udp_transport.h +++ b/exporters/jaeger/src/udp_transport.h @@ -27,7 +27,6 @@ using TBinaryProtocol = apache::thrift::protocol::TBinaryProtocol; using TCompactProtocol = apache::thrift::protocol::TCompactProtocol; using TBufferedTransport = apache::thrift::transport::TBufferedTransport; using TProtocol = apache::thrift::protocol::TProtocol; -using TSocket = apache::thrift::transport::TSocket; using TTransport = apache::thrift::transport::TTransport; class UDPTransport : public Transport @@ -38,7 +37,7 @@ class UDPTransport : public Transport UDPTransport(const std::string &addr, uint16_t port); virtual ~UDPTransport(); - void EmitBatch(const thrift::Batch &batch) override; + int EmitBatch(const thrift::Batch &batch) override; uint32_t MaxPacketSize() const override { return max_packet_size_; } diff --git a/exporters/otlp/CMakeLists.txt b/exporters/otlp/CMakeLists.txt index 1ca788af58..27c0171774 100644 --- a/exporters/otlp/CMakeLists.txt +++ b/exporters/otlp/CMakeLists.txt @@ -52,7 +52,8 @@ install( DIRECTORY include/opentelemetry/exporters/otlp DESTINATION include/opentelemetry/exporters/ FILES_MATCHING - PATTERN "*.h") + PATTERN "*.h" + PATTERN "otlp_recordable.h" EXCLUDE) if(BUILD_TESTING) add_executable(otlp_recordable_test test/otlp_recordable_test.cc) diff --git a/exporters/otlp/include/opentelemetry/exporters/otlp/otlp_grpc_exporter.h b/exporters/otlp/include/opentelemetry/exporters/otlp/otlp_grpc_exporter.h index b3df30d259..31ad058c6d 100644 --- a/exporters/otlp/include/opentelemetry/exporters/otlp/otlp_grpc_exporter.h +++ b/exporters/otlp/include/opentelemetry/exporters/otlp/otlp_grpc_exporter.h @@ -11,26 +11,56 @@ #include "opentelemetry/sdk/trace/exporter.h" +#include "opentelemetry/sdk/common/env_variables.h" + OPENTELEMETRY_BEGIN_NAMESPACE namespace exporter { namespace otlp { + +inline const std::string GetOtlpGrpcDefaultEndpoint() +{ + constexpr char kOtlpGrpcEndpointEnv[] = "OTEL_EXPORTER_OTLP_GRPC_ENDPOINT"; + constexpr char kOtlpGrpcEndpointDefault[] = "localhost:4317"; + + auto endpoint = opentelemetry::sdk::common::GetEnvironmentVariable(kOtlpGrpcEndpointEnv); + return endpoint.size() ? endpoint : kOtlpGrpcEndpointDefault; +} + +inline const bool GetOtlpGrpcDefaultIsSslEnable() +{ + constexpr char kOtlpGrpcIsSslEnableEnv[] = "OTEL_EXPORTER_OTLP_GRPC_SSL_ENABLE"; + auto ssl_enable = opentelemetry::sdk::common::GetEnvironmentVariable(kOtlpGrpcIsSslEnableEnv); + if (ssl_enable == "True" || ssl_enable == "TRUE" || ssl_enable == "true" || ssl_enable == "1") + { + return true; + } + return false; +} + +inline const std::string GetOtlpGrpcDefaultSslCertificate() +{ + constexpr char kOtlpGrpcSslCertificate[] = "OTEL_EXPORTER_OTLP_GRPC_SSL_CERTIFICATE"; + auto ssl_cert = opentelemetry::sdk::common::GetEnvironmentVariable(kOtlpGrpcSslCertificate); + return ssl_cert.size() ? ssl_cert : ""; +} + /** * Struct to hold OTLP exporter options. */ struct OtlpGrpcExporterOptions { // The endpoint to export to. By default the OpenTelemetry Collector's default endpoint. - std::string endpoint = "localhost:4317"; + std::string endpoint = GetOtlpGrpcDefaultEndpoint(); // By default when false, uses grpc::InsecureChannelCredentials(); If true, // uses ssl_credentials_cacert_path if non-empty, else uses ssl_credentials_cacert_as_string - bool use_ssl_credentials = false; + bool use_ssl_credentials = GetOtlpGrpcDefaultIsSslEnable(); // ssl_credentials_cacert_path specifies path to .pem file to be used for SSL encryption. std::string ssl_credentials_cacert_path = ""; // ssl_credentials_cacert_as_string in-memory string representation of .pem file to be used for // SSL encryption. - std::string ssl_credentials_cacert_as_string = ""; + std::string ssl_credentials_cacert_as_string = GetOtlpGrpcDefaultSslCertificate(); }; /** diff --git a/exporters/otlp/src/otlp_grpc_exporter.cc b/exporters/otlp/src/otlp_grpc_exporter.cc index 42c0b5d300..2d522ca3cd 100644 --- a/exporters/otlp/src/otlp_grpc_exporter.cc +++ b/exporters/otlp/src/otlp_grpc_exporter.cc @@ -3,10 +3,11 @@ #include "opentelemetry/exporters/otlp/otlp_grpc_exporter.h" #include "opentelemetry/exporters/otlp/otlp_recordable.h" +#include "opentelemetry/sdk_config.h" #include #include -#include +#include // std::stringstream OPENTELEMETRY_BEGIN_NAMESPACE namespace exporter @@ -112,7 +113,8 @@ sdk::common::ExportResult OtlpGrpcExporter::Export( if (!status.ok()) { - std::cerr << "[OTLP Exporter] Export() failed: " << status.error_message() << "\n"; + + OTEL_INTERNAL_LOG_ERROR("[OTLP Exporter] Export() failed: " << status.error_message()); return sdk::common::ExportResult::kFailure; } return sdk::common::ExportResult::kSuccess; diff --git a/exporters/otlp/src/otlp_http_exporter.cc b/exporters/otlp/src/otlp_http_exporter.cc index dec5268165..80cbfa40c7 100644 --- a/exporters/otlp/src/otlp_http_exporter.cc +++ b/exporters/otlp/src/otlp_http_exporter.cc @@ -16,11 +16,12 @@ #include "opentelemetry/proto/collector/trace/v1/trace_service.pb.h" #include "opentelemetry/exporters/otlp/protobuf_include_suffix.h" +#include "opentelemetry/sdk_config.h" #include #include -#include #include +#include #include #include @@ -66,14 +67,15 @@ class ResponseHandler : public http_client::EventHandler if (console_debug_) { - std::cout << "[OTLP HTTP Exporter] Status:" << response.GetStatusCode() << std::endl - << "Header:" << std::endl; - response.ForEachHeader([](opentelemetry::nostd::string_view header_name, - opentelemetry::nostd::string_view header_value) { - std::cout << "\t" << header_name.data() << " : " << header_value.data() << std::endl; + std::stringstream ss; + ss << "[OTLP HTTP Exporter] Status:" << response.GetStatusCode() << "Header:"; + response.ForEachHeader([&ss](opentelemetry::nostd::string_view header_name, + opentelemetry::nostd::string_view header_value) { + ss << "\t" << header_name.data() << " : " << header_value.data() << ","; return true; }); - std::cout << "Body:" << std::endl << body_ << std::endl; + ss << "Body:" << body_; + OTEL_INTERNAL_LOG_DEBUG(ss.str()); } // Set the response_received_ flag to true and notify any threads waiting on this result @@ -82,7 +84,7 @@ class ResponseHandler : public http_client::EventHandler cv_.notify_all(); } - /** + /**resource * A method the user calls to block their thread until the response is received. The longest * duration is the timeout of the request, set by SetTimeoutMs() */ @@ -111,114 +113,94 @@ class ResponseHandler : public http_client::EventHandler switch (state) { case http_client::SessionState::CreateFailed: - if (console_debug_) - { - std::cerr << "[OTLP HTTP Exporter] Session state: session create failed" << std::endl; - } + OTEL_INTERNAL_LOG_ERROR("[OTLP HTTP Exporter] Session state: session create failed"); cv_.notify_all(); break; case http_client::SessionState::Created: if (console_debug_) { - std::cerr << "[OTLP HTTP Exporter] Session state: session created" << std::endl; + OTEL_INTERNAL_LOG_DEBUG("[OTLP HTTP Exporter] Session state: session created"); } break; case http_client::SessionState::Destroyed: if (console_debug_) { - std::cerr << "[OTLP HTTP Exporter] Session state: session destroyed" << std::endl; + OTEL_INTERNAL_LOG_DEBUG("[OTLP HTTP Exporter] Session state: session destroyed"); } break; case http_client::SessionState::Connecting: if (console_debug_) { - std::cerr << "[OTLP HTTP Exporter] Session state: connecting to peer" << std::endl; + OTEL_INTERNAL_LOG_DEBUG("[OTLP HTTP Exporter] Session state: connecting to peer"); } break; case http_client::SessionState::ConnectFailed: - if (console_debug_) - { - std::cerr << "[OTLP HTTP Exporter] Session state: connection failed" << std::endl; - } + OTEL_INTERNAL_LOG_ERROR("[OTLP HTTP Exporter] Session state: connection failed"); cv_.notify_all(); break; case http_client::SessionState::Connected: if (console_debug_) { - std::cerr << "[OTLP HTTP Exporter] Session state: connected" << std::endl; + OTEL_INTERNAL_LOG_DEBUG("[OTLP HTTP Exporter] Session state: connected"); } break; case http_client::SessionState::Sending: if (console_debug_) { - std::cerr << "[OTLP HTTP Exporter] Session state: sending request" << std::endl; + OTEL_INTERNAL_LOG_DEBUG("[OTLP HTTP Exporter] Session state: sending request"); } break; case http_client::SessionState::SendFailed: - if (console_debug_) - { - std::cerr << "[OTLP HTTP Exporter] Session state: request send failed" << std::endl; - } + OTEL_INTERNAL_LOG_ERROR("[OTLP HTTP Exporter] Session state: request send failed"); cv_.notify_all(); break; case http_client::SessionState::Response: if (console_debug_) { - std::cerr << "[OTLP HTTP Exporter] Session state: response received" << std::endl; + OTEL_INTERNAL_LOG_DEBUG("[OTLP HTTP Exporter] Session state: response received"); } break; case http_client::SessionState::SSLHandshakeFailed: - if (console_debug_) - { - std::cerr << "[OTLP HTTP Exporter] Session state: SSL handshake failed" << std::endl; - } + OTEL_INTERNAL_LOG_ERROR("[OTLP HTTP Exporter] Session state: SSL handshake failed"); cv_.notify_all(); break; case http_client::SessionState::TimedOut: - if (console_debug_) - { - std::cerr << "[OTLP HTTP Exporter] Session state: request time out" << std::endl; - } + OTEL_INTERNAL_LOG_ERROR("[OTLP HTTP Exporter] Session state: request time out"); cv_.notify_all(); break; case http_client::SessionState::NetworkError: - if (console_debug_) - { - std::cerr << "[OTLP HTTP Exporter] Session state: network error" << std::endl; - } + OTEL_INTERNAL_LOG_ERROR("[OTLP HTTP Exporter] Session state: network error"); cv_.notify_all(); break; case http_client::SessionState::ReadError: if (console_debug_) { - std::cerr << "[OTLP HTTP Exporter] Session state: error reading response" << std::endl; + OTEL_INTERNAL_LOG_DEBUG("[OTLP HTTP Exporter] Session state: error reading response"); } break; case http_client::SessionState::WriteError: if (console_debug_) { - std::cerr << "[OTLP HTTP Exporter] Session state: error writing request" << std::endl; + OTEL_INTERNAL_LOG_DEBUG( + "[OTLP HTTP Exporter] DEBUG:Session state: error writing request"); } break; case http_client::SessionState::Cancelled: - if (console_debug_) - { - std::cerr << "[OTLP HTTP Exporter] Session state: (manually) cancelled" << std::endl; - } + OTEL_INTERNAL_LOG_ERROR("[OTLP HTTP Exporter] Session state: (manually) cancelled\n"); cv_.notify_all(); break; @@ -612,16 +594,16 @@ sdk::common::ExportResult OtlpHttpExporter::Export( { if (options_.console_debug) { - std::cout << "[OTLP HTTP Exporter] Request body(Binary):\n" - << service_request.Utf8DebugString() << std::endl; + OTEL_INTERNAL_LOG_DEBUG( + "[OTLP HTTP Exporter] Request body(Binary): " << service_request.Utf8DebugString()); } } else { if (options_.console_debug) { - std::cout << "[OTLP HTTP Exporter] Serialize body failed(Binary):" - << service_request.InitializationErrorString() << std::endl; + OTEL_INTERNAL_LOG_DEBUG("[OTLP HTTP Exporter] Serialize body failed(Binary):" + << service_request.InitializationErrorString()); } return sdk::common::ExportResult::kFailure; } @@ -638,7 +620,7 @@ sdk::common::ExportResult OtlpHttpExporter::Export( json_request.dump(-1, ' ', false, nlohmann::detail::error_handler_t::replace); if (options_.console_debug) { - std::cout << "[OTLP HTTP Exporter] Request body(Json):\n" << post_body_json << std::endl; + OTEL_INTERNAL_LOG_DEBUG("[OTLP HTTP Exporter] Request body(Json)" << post_body_json); } body_vec.assign(post_body_json.begin(), post_body_json.end()); content_type = kHttpJsonContentType; @@ -660,8 +642,9 @@ sdk::common::ExportResult OtlpHttpExporter::Export( // Wait for the response to be received if (options_.console_debug) { - std::cout << "[OTLP HTTP Exporter] Waiting for response from " << options_.url - << " (timeout = " << options_.timeout.count() << " milliseconds)" << std::endl; + OTEL_INTERNAL_LOG_DEBUG("[OTLP HTTP Exporter] DEBUG: Waiting for response from " + << options_.url << " (timeout = " << options_.timeout.count() + << " milliseconds)"); } bool write_successful = handler->waitForResponse(); diff --git a/exporters/otlp/test/otlp_grpc_exporter_test.cc b/exporters/otlp/test/otlp_grpc_exporter_test.cc index f7e82e6a46..d2b999382a 100644 --- a/exporters/otlp/test/otlp_grpc_exporter_test.cc +++ b/exporters/otlp/test/otlp_grpc_exporter_test.cc @@ -31,6 +31,10 @@ # include +# if defined(_MSC_VER) +# define putenv _putenv +# endif + using namespace testing; OPENTELEMETRY_BEGIN_NAMESPACE @@ -129,6 +133,38 @@ TEST_F(OtlpGrpcExporterTestPeer, ConfigSslCredentialsTest) EXPECT_EQ(GetOptions(exporter).ssl_credentials_cacert_as_string, cacert_str); EXPECT_EQ(GetOptions(exporter).use_ssl_credentials, true); } + +# ifndef NO_GETENV +// Test exporter configuration options with use_ssl_credentials +TEST_F(OtlpGrpcExporterTestPeer, ConfigFromEnv) +{ + const std::string cacert_str = "--begin and end fake cert--"; + const std::string cacert_env = "OTEL_EXPORTER_OTLP_GRPC_SSL_CERTIFICATE=" + cacert_str; + putenv(const_cast(cacert_env.data())); + char ssl_enable_env[] = "OTEL_EXPORTER_OTLP_GRPC_SSL_ENABLE=True"; + putenv(ssl_enable_env); + const std::string endpoint = "http://localhost:9999"; + const std::string endpoint_env = "OTEL_EXPORTER_OTLP_GRPC_ENDPOINT=" + endpoint; + putenv(const_cast(endpoint_env.data())); + + std::unique_ptr exporter(new OtlpGrpcExporter()); + EXPECT_EQ(GetOptions(exporter).ssl_credentials_cacert_as_string, cacert_str); + EXPECT_EQ(GetOptions(exporter).use_ssl_credentials, true); + EXPECT_EQ(GetOptions(exporter).endpoint, endpoint); +# if defined(_MSC_VER) + putenv("OTEL_EXPORTER_OTLP_GRPC_ENDPOINT="); + putenv("OTEL_EXPORTER_OTLP_GRPC_SSL_CERTIFICATE="); + putenv("OTEL_EXPORTER_OTLP_GRPC_SSL_ENABLE="); + +# else + unsetenv("OTEL_EXPORTER_OTLP_GRPC_ENDPOINT"); + unsetenv("OTEL_EXPORTER_OTLP_GRPC_SSL_CERTIFICATE"); + unsetenv("OTEL_EXPORTER_OTLP_GRPC_SSL_ENABLE"); + +# endif +} +# endif + } // namespace otlp } // namespace exporter OPENTELEMETRY_END_NAMESPACE diff --git a/exporters/zipkin/CMakeLists.txt b/exporters/zipkin/CMakeLists.txt index 5f6f9887a6..2316860960 100644 --- a/exporters/zipkin/CMakeLists.txt +++ b/exporters/zipkin/CMakeLists.txt @@ -34,7 +34,8 @@ install( DIRECTORY include/opentelemetry/exporters/zipkin DESTINATION include/opentelemetry/exporters/ FILES_MATCHING - PATTERN "*.h") + PATTERN "*.h" + PATTERN "recordable.h" EXCLUDE) if(BUILD_TESTING) add_executable(zipkin_recordable_test test/zipkin_recordable_test.cc) diff --git a/exporters/zipkin/include/opentelemetry/exporters/zipkin/recordable.h b/exporters/zipkin/include/opentelemetry/exporters/zipkin/recordable.h index 628d7330a8..51f83211f0 100644 --- a/exporters/zipkin/include/opentelemetry/exporters/zipkin/recordable.h +++ b/exporters/zipkin/include/opentelemetry/exporters/zipkin/recordable.h @@ -14,12 +14,6 @@ namespace zipkin { using ZipkinSpan = nlohmann::json; -enum class TransportFormat -{ - kJson, - kProtobuf -}; - class Recordable final : public sdk::trace::Recordable { public: diff --git a/exporters/zipkin/include/opentelemetry/exporters/zipkin/zipkin_exporter.h b/exporters/zipkin/include/opentelemetry/exporters/zipkin/zipkin_exporter.h index cb244867d7..ec3f562b19 100644 --- a/exporters/zipkin/include/opentelemetry/exporters/zipkin/zipkin_exporter.h +++ b/exporters/zipkin/include/opentelemetry/exporters/zipkin/zipkin_exporter.h @@ -3,9 +3,9 @@ #pragma once -#include "opentelemetry/exporters/zipkin/recordable.h" #include "opentelemetry/ext/http/client/http_client_factory.h" #include "opentelemetry/ext/http/common/url_parser.h" +#include "opentelemetry/sdk/common/env_variables.h" #include "opentelemetry/sdk/trace/exporter.h" #include "opentelemetry/sdk/trace/span_data.h" @@ -22,25 +22,17 @@ inline const std::string GetDefaultZipkinEndpoint() const char *otel_exporter_zipkin_endpoint_env = "OTEL_EXPORTER_ZIPKIN_ENDPOINT"; const char *kZipkinEndpointDefault = "http://localhost:9411/api/v2/spans"; -#if defined(_MSC_VER) - // avoid calling std::getenv which is deprecated in MSVC. - size_t required_size = 0; - getenv_s(&required_size, nullptr, 0, otel_exporter_zipkin_endpoint_env); - const char *endpoint_from_env = nullptr; - std::unique_ptr endpoint_buffer; - if (required_size > 0) - { - endpoint_buffer = std::unique_ptr{new char[required_size]}; - getenv_s(&required_size, endpoint_buffer.get(), required_size, - otel_exporter_zipkin_endpoint_env); - endpoint_from_env = endpoint_buffer.get(); - } -#else - auto endpoint_from_env = std::getenv(otel_exporter_zipkin_endpoint_env); -#endif - return std::string{endpoint_from_env ? endpoint_from_env : kZipkinEndpointDefault}; + auto endpoint = + opentelemetry::sdk::common::GetEnvironmentVariable(otel_exporter_zipkin_endpoint_env); + return endpoint.size() ? endpoint : kZipkinEndpointDefault; } +enum class TransportFormat +{ + kJson, + kProtobuf +}; + /** * Struct to hold Zipkin exporter options. */ diff --git a/exporters/zipkin/src/zipkin_exporter.cc b/exporters/zipkin/src/zipkin_exporter.cc index 199a908b86..f09487becb 100644 --- a/exporters/zipkin/src/zipkin_exporter.cc +++ b/exporters/zipkin/src/zipkin_exporter.cc @@ -5,6 +5,7 @@ #include "opentelemetry/exporters/zipkin/recordable.h" #include "opentelemetry/ext/http/client/http_client_factory.h" #include "opentelemetry/ext/http/common/url_parser.h" +#include "opentelemetry/sdk_config.h" OPENTELEMETRY_BEGIN_NAMESPACE namespace exporter @@ -71,7 +72,7 @@ sdk::common::ExportResult ZipkinExporter::Export( { if (result.GetSessionState() == http_client::SessionState::ConnectFailed) { - // TODO -> Handle error / retries + OTEL_INTERNAL_LOG_ERROR("ZIPKIN EXPORTER] Zipkin Exporter: Connection failed"); } return sdk::common::ExportResult::kFailure; } diff --git a/ext/include/opentelemetry/ext/http/client/http_client.h b/ext/include/opentelemetry/ext/http/client/http_client.h index 4e3e9845e0..308335e492 100644 --- a/ext/include/opentelemetry/ext/http/client/http_client.h +++ b/ext/include/opentelemetry/ext/http/client/http_client.h @@ -183,8 +183,8 @@ class Result { if (response_ == nullptr) { - static NoopResponse res; - return res; + // let's not return nullptr + response_.reset(new NoopResponse()); } return *response_; } diff --git a/sdk/include/opentelemetry/sdk/common/env_variables.h b/sdk/include/opentelemetry/sdk/common/env_variables.h new file mode 100644 index 0000000000..63d16d12b5 --- /dev/null +++ b/sdk/include/opentelemetry/sdk/common/env_variables.h @@ -0,0 +1,40 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +#pragma once + +#include +#include "opentelemetry/version.h" + +OPENTELEMETRY_BEGIN_NAMESPACE +namespace sdk +{ +namespace common +{ + +// Returns the env variable set. +inline const std::string GetEnvironmentVariable(const char *env_var_name) +{ + const char *endpoint_from_env = nullptr; + +#ifndef NO_GETENV +# if defined(_MSC_VER) + // avoid calling std::getenv which is deprecated in MSVC. + size_t required_size = 0; + getenv_s(&required_size, nullptr, 0, env_var_name); + std::unique_ptr endpoint_buffer; + if (required_size > 0) + { + endpoint_buffer = std::unique_ptr{new char[required_size]}; + getenv_s(&required_size, endpoint_buffer.get(), required_size, env_var_name); + endpoint_from_env = endpoint_buffer.get(); + } +# else + endpoint_from_env = std::getenv(env_var_name); +# endif +#endif + return endpoint_from_env == nullptr ? std::string() : endpoint_from_env; +} +} // namespace common +} // namespace sdk +OPENTELEMETRY_END_NAMESPACE \ No newline at end of file diff --git a/sdk/include/opentelemetry/sdk/common/global_log_handler.h b/sdk/include/opentelemetry/sdk/common/global_log_handler.h new file mode 100644 index 0000000000..f967111e3a --- /dev/null +++ b/sdk/include/opentelemetry/sdk/common/global_log_handler.h @@ -0,0 +1,209 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +#pragma once + +#include +#include + +#include "opentelemetry/nostd/shared_ptr.h" +#include "opentelemetry/sdk/common/attribute_utils.h" +#include "opentelemetry/version.h" + +#define OTEL_INTERNAL_LOG_LEVEL_ERROR 0 +#define OTEL_INTERNAL_LOG_LEVEL_WARN 1 +#define OTEL_INTERNAL_LOG_LEVEL_INFO 2 +#define OTEL_INTERNAL_LOG_LEVEL_DEBUG 3 // to be disabled in release + +#ifndef OTEL_INTERNAL_LOG_LEVEL +# define OTEL_INTERNAL_LOG_LEVEL OTEL_INTERNAL_LOG_LEVEL_WARN // ERROR and WARN +#endif + +OPENTELEMETRY_BEGIN_NAMESPACE +namespace sdk +{ +namespace common +{ +namespace internal_log +{ + +enum class LogLevel +{ + Error = 0, + Warning, + Info, + Debug +}; + +inline std::string LevelToString(LogLevel level) +{ + switch (level) + { + case LogLevel::Error: + return "Error"; + case LogLevel::Warning: + return "Warning"; + case LogLevel::Info: + return "Info"; + case LogLevel::Debug: + return "Debug"; + } + return {}; +} + +class LogHandler +{ +public: + virtual void Handle(LogLevel level, + const char *file, + int line, + const char *msg, + const sdk::common::AttributeMap &attributes) noexcept = 0; +}; + +class DefaultLogHandler : public LogHandler +{ +public: + void Handle(LogLevel level, + const char *file, + int line, + const char *msg, + const sdk::common::AttributeMap &attributes) noexcept override + { + std::stringstream output_s; + output_s << "[" << LevelToString(level) << "] "; + if (file != nullptr) + { + output_s << "File: " << file << ":" << line; + } + if (msg != nullptr) + { + output_s << msg; + } + output_s << std::endl; + // TBD - print attributes + std::cout << output_s.str(); // thread safe. + } +}; + +class NoopLogHandler : public LogHandler +{ +public: + void Handle(LogLevel level, + const char *file, + int line, + const char *msg, + const sdk::common::AttributeMap &error_attributes) noexcept override + { + // ignore the log message + } +}; + +/** + * Stores the singleton global LogHandler. + */ +class GlobalLogHandler +{ +public: + /** + * Returns the singleton LogHandler. + * + * By default, a default LogHandler is returned. This will never return a + * nullptr LogHandler. + */ + static nostd::shared_ptr GetLogHandler() noexcept + { + return nostd::shared_ptr(GetHandler()); + } + + /** + * Changes the singleton LogHandler. + * This should be called once at the start of application before creating TracerProvider + * instance. + */ + static void SetLogHandler(nostd::shared_ptr eh) noexcept { GetHandler() = eh; } + +private: + static nostd::shared_ptr &GetHandler() noexcept + { + static nostd::shared_ptr handler(new DefaultLogHandler); + return handler; + } +}; + +} // namespace internal_log +} // namespace common +} // namespace sdk +OPENTELEMETRY_END_NAMESPACE + +#define OTEL_INTERNAL_LOG_DISPATCH(level, message, attributes) \ + do \ + { \ + using namespace opentelemetry::sdk::common::internal_log; \ + std::stringstream tmp_stream; \ + tmp_stream << message; \ + GlobalLogHandler::GetLogHandler()->Handle(level, __FILE__, __LINE__, tmp_stream.str().c_str(), \ + attributes); \ + } while (0) + +#define OTEL_INTERNAL_LOG_GET_3RD_ARG(arg1, arg2, arg3, ...) arg3 + +#if OTEL_INTERNAL_LOG_LEVEL >= OTEL_INTERNAL_LOG_LEVEL_ERROR +# define OTEL_INTERNAL_LOG_ERROR_1_ARGS(message) \ + OTEL_INTERNAL_LOG_DISPATCH(opentelemetry::sdk::common::internal_log::LogLevel::Error, message, \ + {}) +# define OTEL_INTERNAL_LOG_ERROR_2_ARGS(message, attributes) \ + OTEL_INTERNAL_LOG_DISPATCH(opentelemetry::sdk::common::internal_log::LogLevel::Error, message, \ + attributes) +# define OTEL_INTERNAL_LOG_ERROR_MACRO(...) \ + OTEL_INTERNAL_LOG_GET_3RD_ARG(__VA_ARGS__, OTEL_INTERNAL_LOG_ERROR_2_ARGS, \ + OTEL_INTERNAL_LOG_ERROR_1_ARGS) +# define OTEL_INTERNAL_LOG_ERROR(...) OTEL_INTERNAL_LOG_ERROR_MACRO(__VA_ARGS__)(__VA_ARGS__) +#else +# define OTEL_INTERNAL_LOG_ERROR(...) +#endif + +#if OTEL_INTERNAL_LOG_LEVEL >= OTEL_INTERNAL_LOG_LEVEL_WARN +# define OTEL_INTERNAL_LOG_WARN_1_ARGS(message) \ + OTEL_INTERNAL_LOG_DISPATCH(opentelemetry::sdk::common::internal_log::LogLevel::Warn, message, \ + {}) +# define OTEL_INTERNAL_LOG_WARN_2_ARGS(message, attributes) \ + OTEL_INTERNAL_LOG_DISPATCH(opentelemetry::sdk::common::internal_log::LogLevel::Warn, message, \ + attributes) +# define OTEL_INTERNAL_LOG_WARN_MACRO(...) \ + OTEL_INTERNAL_LOG_GET_3RD_ARG(__VA_ARGS__, OTEL_INTERNAL_LOG_WARN_2_ARGS, \ + OTEL_INTERNAL_LOG_WARN_1_ARGS) +# define OTEL_INTERNAL_LOG_WARN(...) OTEL_INTERNAL_LOG_WARN_MACRO(__VA_ARGS__)(__VA_ARGS__) +#else +# define OTEL_INTERNAL_LOG_ERROR(...) +#endif + +#if OTEL_INTERNAL_LOG_LEVEL >= OTEL_INTERNAL_LOG_LEVEL_DEBUG +# define OTEL_INTERNAL_LOG_DEBUG_1_ARGS(message) \ + OTEL_INTERNAL_LOG_DISPATCH(opentelemetry::sdk::common::internal_log::LogLevel::Debug, message, \ + {}) +# define OTEL_INTERNAL_LOG_DEBUG_2_ARGS(message, attributes) \ + OTEL_INTERNAL_LOG_DISPATCH(opentelemetry::sdk::common::internal_logg::LogLevel::Debug, \ + message, attributes) +# define OTEL_INTERNAL_LOG_DEBUG_MACRO(...) \ + OTEL_INTERNAL_LOG_GET_3RD_ARG(__VA_ARGS__, OTEL_INTERNAL_LOG_DEBUG_2_ARGS, \ + OTEL_INTERNAL_LOG_DEBUG_1_ARGS) +# define OTEL_INTERNAL_LOG_DEBUG(...) OTEL_INTERNAL_LOG_DEBUG_MACRO(__VA_ARGS__)(__VA_ARGS__) +#else +# define OTEL_INTERNAL_LOG_DEBUG(...) +#endif + +#if OTEL_INTERNAL_LOG_LEVEL >= OTEL_INTERNAL_LOG_LEVEL_INFO +# define OTEL_INTERNAL_LOG_INFO_1_ARGS(message) \ + OTEL_INTERNAL_LOG_DISPATCH(opentelemetry::sdk::common::internal_logger::LogLevel::Info, \ + message, {}) +# define OTEL_INTERNAL_LOG_INFO_2_ARGS(message, attributes) \ + OTEL_INTERNAL_LOG_DISPATCH(opentelemetry::sdk::common::internal_logger::LogLevel::Info, \ + message, attributes) +# define OTEL_INTERNAL_LOG_INFO_MACRO(...) \ + OTEL_INTERNAL_LOG_GET_3RD_ARG(__VA_ARGS__, OTEL_INTERNAL_LOG_ERROR_2_ARGS, \ + OTEL_INTERNAL_LOG_ERROR_1_ARGS) +# define OTEL_INTERNAL_LOG_INFO(...) OTEL_INTERNAL_LOG_INFO_MACRO(__VA_ARGS__)(__VA_ARGS__) +#else +# define OTEL_INTERNAL_LOG_INFO(...) +#endif diff --git a/sdk/include/opentelemetry/sdk/resource/semantic_conventions.h b/sdk/include/opentelemetry/sdk/resource/semantic_conventions.h index c604a5094f..693b3e108a 100644 --- a/sdk/include/opentelemetry/sdk/resource/semantic_conventions.h +++ b/sdk/include/opentelemetry/sdk/resource/semantic_conventions.h @@ -1,7 +1,5 @@ #pragma once -#include -#include #include #include @@ -20,7 +18,7 @@ static const std::unordered_map attribute_ids = { {OTEL_CPP_CONST_HASHCODE(AttrServiceName), "service.name"}, {OTEL_CPP_CONST_HASHCODE(AttrServiceNamespace), "service.namespace"}, {OTEL_CPP_CONST_HASHCODE(AttrServiceInstance), "service.instance.id"}, - {OTEL_CPP_CONST_HASHCODE(AttrServiceVersion), "service.version "}, + {OTEL_CPP_CONST_HASHCODE(AttrServiceVersion), "service.version"}, // telemetry attributes {OTEL_CPP_CONST_HASHCODE(AttrTelemetrySdkName), "telemetry.sdk.name"}, @@ -123,7 +121,7 @@ static const std::unordered_map attribute_ids = { {OTEL_CPP_CONST_HASHCODE(AttrCronjobUid), "k8s.cronjob.id"}, {OTEL_CPP_CONST_HASHCODE(AttrCronjobName), "k8s.cronjob.name"}}; -// macro and function to generate hash code for semantic conventions attributes. +// function to generate hash code for semantic conventions attributes. inline const char *attr(uint32_t attr) { return (attribute_ids.find(attr) != attribute_ids.end()) ? attribute_ids.at(attr) : ""; diff --git a/sdk/include/opentelemetry/sdk/resource/semantic_conventions_old.h b/sdk/include/opentelemetry/sdk/resource/semantic_conventions_old.h deleted file mode 100644 index 7fcdc525ad..0000000000 --- a/sdk/include/opentelemetry/sdk/resource/semantic_conventions_old.h +++ /dev/null @@ -1,136 +0,0 @@ -// Copyright The OpenTelemetry Authors -// SPDX-License-Identifier: Apache-2.0 - -#pragma once - -#include "opentelemetry/version.h" - -#define OTEL_RESOURCE_GENERATE_SEMCONV_METHOD(attribute_name, attribute_value) \ - static constexpr const char *GetAttribute##attribute_name() noexcept { return attribute_value; } - -OPENTELEMETRY_BEGIN_NAMESPACE -namespace sdk -{ -namespace resource -{ -/** - * Stores the Constants for semantic Attribute names for resources outlined by the OpenTelemetry - * specifications. . - */ - -class SemanticConventions final -{ - -public: - // service attributes - OTEL_RESOURCE_GENERATE_SEMCONV_METHOD(ServiceName, "service.name"); - OTEL_RESOURCE_GENERATE_SEMCONV_METHOD(ServiceNamespace, "service.namespace"); - OTEL_RESOURCE_GENERATE_SEMCONV_METHOD(ServiceInstance, "service.instance.id"); - OTEL_RESOURCE_GENERATE_SEMCONV_METHOD(ServiceVersion, "service.version "); - - // telemetry attributes - OTEL_RESOURCE_GENERATE_SEMCONV_METHOD(TelemetrySdkName, "telemetry.sdk.name"); - OTEL_RESOURCE_GENERATE_SEMCONV_METHOD(TelemetrySdkLanguage, "telemetry.sdk.language"); - OTEL_RESOURCE_GENERATE_SEMCONV_METHOD(TelemetrySdkVersion, "telemetry.sdk.version"); - OTEL_RESOURCE_GENERATE_SEMCONV_METHOD(TelemetryAutoVersion, "telemetry.auto.version"); - - // compute unit: container attributes - OTEL_RESOURCE_GENERATE_SEMCONV_METHOD(ContainerName, "container.name"); - OTEL_RESOURCE_GENERATE_SEMCONV_METHOD(ContainerId, "container.id"); - OTEL_RESOURCE_GENERATE_SEMCONV_METHOD(ContainerRuntime, "container.runtime"); - OTEL_RESOURCE_GENERATE_SEMCONV_METHOD(ContainerImageName, "container.image.name"); - OTEL_RESOURCE_GENERATE_SEMCONV_METHOD(ContainerImageTag, "container.image.tag"); - - // compute unit: faas attributes - OTEL_RESOURCE_GENERATE_SEMCONV_METHOD(FaasName, "faas.name"); - OTEL_RESOURCE_GENERATE_SEMCONV_METHOD(FaasId, "faas.id"); - OTEL_RESOURCE_GENERATE_SEMCONV_METHOD(FaasVersion, "faas.version"); - OTEL_RESOURCE_GENERATE_SEMCONV_METHOD(FaasInstance, "faas.instance"); - OTEL_RESOURCE_GENERATE_SEMCONV_METHOD(FaasMaxMemory, "faas.max_memory"); - - // compute unit : process attributes - OTEL_RESOURCE_GENERATE_SEMCONV_METHOD(ProcessId, "process.pid"); - OTEL_RESOURCE_GENERATE_SEMCONV_METHOD(ProcessExecutableName, "process.executable.name"); - OTEL_RESOURCE_GENERATE_SEMCONV_METHOD(ProcessExecutablePath, "process.executable.path"); - OTEL_RESOURCE_GENERATE_SEMCONV_METHOD(ProcessCommand, "process.command"); - OTEL_RESOURCE_GENERATE_SEMCONV_METHOD(ProcessCommandLine, "process.command_line"); - OTEL_RESOURCE_GENERATE_SEMCONV_METHOD(ProcessCommandArgs, "process.command_args"); - OTEL_RESOURCE_GENERATE_SEMCONV_METHOD(ProcessOwner, "process.owner"); - - // compute : process runtimes - OTEL_RESOURCE_GENERATE_SEMCONV_METHOD(ProcessRuntimeName, "process.runtime.name"); - OTEL_RESOURCE_GENERATE_SEMCONV_METHOD(ProcessRuntimeVersion, "process.runtime.version"); - OTEL_RESOURCE_GENERATE_SEMCONV_METHOD(ProcessRuntimeDescription, "process.runtime.description"); - - // compute unit : WebEngine - OTEL_RESOURCE_GENERATE_SEMCONV_METHOD(WebEngineName, "webengine.name"); - OTEL_RESOURCE_GENERATE_SEMCONV_METHOD(WebEngineVersion, "webengine.version"); - OTEL_RESOURCE_GENERATE_SEMCONV_METHOD(WebEngineDescription, "webengine.description"); - - // compute instance : host - OTEL_RESOURCE_GENERATE_SEMCONV_METHOD(HostId, "host.id"); - OTEL_RESOURCE_GENERATE_SEMCONV_METHOD(HostName, "host.name"); - OTEL_RESOURCE_GENERATE_SEMCONV_METHOD(HostType, "host.type"); - OTEL_RESOURCE_GENERATE_SEMCONV_METHOD(HostArch, "host.arch"); - OTEL_RESOURCE_GENERATE_SEMCONV_METHOD(HostImageName, "host.image.name"); - OTEL_RESOURCE_GENERATE_SEMCONV_METHOD(HostImageId, "host.image.id"); - OTEL_RESOURCE_GENERATE_SEMCONV_METHOD(HostImageVersion, "host.image.version"); - - // env os attributes - OTEL_RESOURCE_GENERATE_SEMCONV_METHOD(OsType, "os.type"); - OTEL_RESOURCE_GENERATE_SEMCONV_METHOD(OsDescription, "os.description"); - OTEL_RESOURCE_GENERATE_SEMCONV_METHOD(OsName, "os.name"); - OTEL_RESOURCE_GENERATE_SEMCONV_METHOD(OsVersion, "os.version"); - - // env device attributes - OTEL_RESOURCE_GENERATE_SEMCONV_METHOD(DeviceId, "device.id"); - OTEL_RESOURCE_GENERATE_SEMCONV_METHOD(DeviceModelIdentifier, "device.model.identifier"); - OTEL_RESOURCE_GENERATE_SEMCONV_METHOD(DeviceModelName, "device.model.name"); - - // env cloud - OTEL_RESOURCE_GENERATE_SEMCONV_METHOD(CloudProvider, "cloud.provider"); - OTEL_RESOURCE_GENERATE_SEMCONV_METHOD(CloudAccountId, "cloud.account.id"); - OTEL_RESOURCE_GENERATE_SEMCONV_METHOD(CloudRegion, "cloud.region"); - OTEL_RESOURCE_GENERATE_SEMCONV_METHOD(CloudAvailabilityZone, "cloud.availability_zone"); - OTEL_RESOURCE_GENERATE_SEMCONV_METHOD(CloudPlatform, "cloud.platform"); - - // env deployment - OTEL_RESOURCE_GENERATE_SEMCONV_METHOD(DeploymentEnvironment, "deployment.environment"); - - // env kubernetes - // - cluster - OTEL_RESOURCE_GENERATE_SEMCONV_METHOD(K8sClusterName, "k8s.cluster.name"); - // - node - OTEL_RESOURCE_GENERATE_SEMCONV_METHOD(K8sNodeName, "k8s.node.name"); - OTEL_RESOURCE_GENERATE_SEMCONV_METHOD(K8sNodeUid, "k8s.node.uid"); - // - namespace - OTEL_RESOURCE_GENERATE_SEMCONV_METHOD(K8sNamespaceName, "k8s.namespace.name"); - // - pod - OTEL_RESOURCE_GENERATE_SEMCONV_METHOD(K8sPodUid, "k8s.pod.uid"); - OTEL_RESOURCE_GENERATE_SEMCONV_METHOD(K8sPodName, "k8s.pod.name"); - // - container - OTEL_RESOURCE_GENERATE_SEMCONV_METHOD(K8sContainerName, "k8s.container.name"); - // - replicaset - OTEL_RESOURCE_GENERATE_SEMCONV_METHOD(K8sReplicaSetUid, "k8s.replicaset.uid"); - OTEL_RESOURCE_GENERATE_SEMCONV_METHOD(K8sReplicaSetName, "k8s.replicaset.name"); - // - deployment - OTEL_RESOURCE_GENERATE_SEMCONV_METHOD(K8sDeploymentUid, "k8s.deployment.uid"); - OTEL_RESOURCE_GENERATE_SEMCONV_METHOD(K8sDeploymentName, "k8s.deployment.name"); - // - stateful-set - OTEL_RESOURCE_GENERATE_SEMCONV_METHOD(K8sStatefulSetUid, "k8s.statefulset.uid"); - OTEL_RESOURCE_GENERATE_SEMCONV_METHOD(K8sStatefulSetName, "k8s.statefulset.name"); - // - daemon set - OTEL_RESOURCE_GENERATE_SEMCONV_METHOD(K8sDaemonSetUid, "k8s.daemonset.uid"); - OTEL_RESOURCE_GENERATE_SEMCONV_METHOD(K8sDaemonSetName, "k8s.daemonset.name"); - // - job - OTEL_RESOURCE_GENERATE_SEMCONV_METHOD(K8sJobUid, "k8s.job.uid"); - OTEL_RESOURCE_GENERATE_SEMCONV_METHOD(K8sJobName, "k8s.job.name"); - // - cronjob - OTEL_RESOURCE_GENERATE_SEMCONV_METHOD(CronjobUid, "k8s.cronjob.id"); - OTEL_RESOURCE_GENERATE_SEMCONV_METHOD(CronjobName, "k8s.cronjob.name"); -}; - -} // namespace resource -} // namespace sdk -OPENTELEMETRY_END_NAMESPACE diff --git a/sdk/include/opentelemetry/sdk/version/version.h b/sdk/include/opentelemetry/sdk/version/version.h index 3d61332ffe..a989cbbc5c 100644 --- a/sdk/include/opentelemetry/sdk/version/version.h +++ b/sdk/include/opentelemetry/sdk/version/version.h @@ -6,7 +6,7 @@ #include "opentelemetry/detail/preprocessor.h" #define OPENTELEMETRY_SDK_ABI_VERSION_NO 0 -#define OPENTELEMETRY_SDK_VERSION "1.0.0-rc3" +#define OPENTELEMETRY_SDK_VERSION "1.0.0-rc4" #define OPENTELEMETRY_SDK_ABI_VERSION OPENTELEMETRY_STRINGIFY(OPENTELEMETRY_SDK_ABI_VERSION_NO) // clang-format off diff --git a/sdk/include/opentelemetry/sdk_config.h b/sdk/include/opentelemetry/sdk_config.h new file mode 100644 index 0000000000..8ac72a10d5 --- /dev/null +++ b/sdk/include/opentelemetry/sdk_config.h @@ -0,0 +1,7 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +#pragma once + +#include "opentelemetry/config.h" +#include "opentelemetry/sdk/common/global_log_handler.h" \ No newline at end of file diff --git a/sdk/src/common/global_log_handler.cc b/sdk/src/common/global_log_handler.cc new file mode 100644 index 0000000000..e69de29bb2 diff --git a/sdk/src/logs/logger.cc b/sdk/src/logs/logger.cc index 970f61b7e9..fe61dd4ce8 100644 --- a/sdk/src/logs/logger.cc +++ b/sdk/src/logs/logger.cc @@ -4,6 +4,7 @@ #ifdef ENABLE_LOGS_PREVIEW # include "opentelemetry/sdk/logs/logger.h" # include "opentelemetry/sdk/logs/log_record.h" +# include "opentelemetry/sdk_config.h" # include "opentelemetry/trace/provider.h" OPENTELEMETRY_BEGIN_NAMESPACE @@ -48,7 +49,7 @@ void Logger::Log(opentelemetry::logs::Severity severity, auto recordable = processor->MakeRecordable(); if (recordable == nullptr) { - // TODO: Error diagnostics should indicate "recordable creation failed" to user + OTEL_INTERNAL_LOG_ERROR("[LOGGER] Recordable creation failed"); return; } diff --git a/sdk/src/resource/resource_detector.cc b/sdk/src/resource/resource_detector.cc index 586de79738..c60056539b 100644 --- a/sdk/src/resource/resource_detector.cc +++ b/sdk/src/resource/resource_detector.cc @@ -2,7 +2,7 @@ // SPDX-License-Identifier: Apache-2.0 #include "opentelemetry/sdk/resource/resource_detector.h" -#include +#include "opentelemetry/sdk/common/env_variables.h" #include "opentelemetry/sdk/resource/resource.h" OPENTELEMETRY_BEGIN_NAMESPACE @@ -15,20 +15,12 @@ const char *OTEL_RESOURCE_ATTRIBUTES = "OTEL_RESOURCE_ATTRIBUTES"; Resource OTELResourceDetector::Detect() noexcept { -#if defined(_MSC_VER) - size_t required_size = 0; - getenv_s(&required_size, nullptr, 0, OTEL_RESOURCE_ATTRIBUTES); - if (required_size == 0) - return Resource(); - std::unique_ptr attributes_buffer{new char[required_size]}; - getenv_s(&required_size, attributes_buffer.get(), required_size, OTEL_RESOURCE_ATTRIBUTES); - char *attributes_str = attributes_buffer.get(); -#else - char *attributes_str = std::getenv(OTEL_RESOURCE_ATTRIBUTES); - if (attributes_str == nullptr) + auto attributes_str = + opentelemetry::sdk::common::GetEnvironmentVariable(OTEL_RESOURCE_ATTRIBUTES); + if (attributes_str.size() == 0) + { return Resource(); -#endif - + } ResourceAttributes attributes; std::istringstream iss(attributes_str); std::string token; diff --git a/sdk/src/trace/tracer_provider.cc b/sdk/src/trace/tracer_provider.cc index ed6853be67..911e66c2f0 100644 --- a/sdk/src/trace/tracer_provider.cc +++ b/sdk/src/trace/tracer_provider.cc @@ -2,6 +2,7 @@ // SPDX-License-Identifier: Apache-2.0 #include "opentelemetry/sdk/trace/tracer_provider.h" +#include "opentelemetry/sdk_config.h" OPENTELEMETRY_BEGIN_NAMESPACE namespace sdk @@ -40,9 +41,10 @@ nostd::shared_ptr TracerProvider::GetTracer( { library_name = ""; } - // if (library_name == "") { - // // TODO: log invalid library_name. - // } + if (library_name == "") + { + OTEL_INTERNAL_LOG_ERROR("[TracerProvider::GetTracer] Library name is empty."); + } const std::lock_guard guard(lock_); diff --git a/sdk/src/version/version.cc b/sdk/src/version/version.cc index 2f1d1e5082..ddabd58066 100644 --- a/sdk/src/version/version.cc +++ b/sdk/src/version/version.cc @@ -11,7 +11,7 @@ namespace version const int MAJOR_VERSION = 1; const int MINOR_VERSION = 0; const int PATCH_VERSION = 0; -const char *PRE_RELEASE = "rc3"; +const char *PRE_RELEASE = "rc4"; const char *BUILD_METADATA = ""; const int COUNT_NEW_COMMITS = 0; const char *BRANCH = ""; diff --git a/sdk/test/common/circular_buffer_test.cc b/sdk/test/common/circular_buffer_test.cc index 11e64a65b5..a20c3e42aa 100644 --- a/sdk/test/common/circular_buffer_test.cc +++ b/sdk/test/common/circular_buffer_test.cc @@ -59,12 +59,11 @@ void RunNumberConsumer(CircularBuffer &buffer, { while (true) { - auto allotment = buffer.Peek(); - if (exit && allotment.empty()) + if (exit && buffer.Peek().empty()) { return; } - auto n = std::uniform_int_distribution{0, allotment.size()}(RandomNumberGenerator); + auto n = std::uniform_int_distribution{0, buffer.Peek().size()}(RandomNumberGenerator); buffer.Consume(n, [&](CircularBufferRange> range) noexcept { assert(range.size() == n); range.ForEach([&](AtomicUniquePtr &ptr) noexcept { diff --git a/sdk/test/resource/resource_test.cc b/sdk/test/resource/resource_test.cc index 0c1a17d5e3..f426c23fe3 100644 --- a/sdk/test/resource/resource_test.cc +++ b/sdk/test/resource/resource_test.cc @@ -155,6 +155,7 @@ TEST(ResourceTest, MergeEmptyString) EXPECT_EQ(received_attributes.size(), expected_attributes.size()); } +#ifndef NO_GETENV TEST(ResourceTest, OtelResourceDetector) { std::map expected_attributes = {{"k", "v"}}; @@ -175,21 +176,21 @@ TEST(ResourceTest, OtelResourceDetector) } } EXPECT_EQ(received_attributes.size(), expected_attributes.size()); -#if defined(_MSC_VER) +# if defined(_MSC_VER) putenv("OTEL_RESOURCE_ATTRIBUTES="); -#else +# else unsetenv("OTEL_RESOURCE_ATTRIBUTES"); -#endif +# endif } TEST(ResourceTest, OtelResourceDetectorEmptyEnv) { std::map expected_attributes = {}; -#if defined(_MSC_VER) +# if defined(_MSC_VER) putenv("OTEL_RESOURCE_ATTRIBUTES="); -#else +# else unsetenv("OTEL_RESOURCE_ATTRIBUTES"); -#endif +# endif OTELResourceDetector detector; auto resource = detector.Detect(); auto received_attributes = resource.GetAttributes(); @@ -204,3 +205,4 @@ TEST(ResourceTest, OtelResourceDetectorEmptyEnv) } EXPECT_EQ(received_attributes.size(), expected_attributes.size()); } +#endif