You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@qpid.apache.org by GitBox <gi...@apache.org> on 2022/08/25 13:21:37 UTC

[GitHub] [qpid-proton] astitcher commented on a diff in pull request #355: PROTON-2487: [cpp] Implement distributed tracing using OpenTelemetry

astitcher commented on code in PR #355:
URL: https://github.com/apache/qpid-proton/pull/355#discussion_r954946349


##########
cpp/CMakeLists.txt:
##########
@@ -36,6 +36,19 @@ else()
   set(CONNECT_CONFIG_SRC src/connect_config_dummy.cpp)
 endif()
 
+# Check for OPENTELEMETRY-CPP for distributed tracing
+find_package(opentelemetry-cpp)
+option(ENABLE_OPENTELEMETRYCPP "Use opentelemetry for distributed tracing" ${OPENTELEMETRY-CPP_FOUND})
+
+if (ENABLE_OPENTELEMETRYCPP)
+  include_directories(${OPENTELEMETRY_CPP_INCLUDE_DIRS})
+  set(TRACING_SRC src/tracing_opentelemetry.cpp src/tracing_stub.cpp)
+  set(TRACING_LIBS opentelemetry-cpp::trace opentelemetry-cpp::jaeger_trace_exporter opentelemetry-cpp::ostream_span_exporter)

Review Comment:
   might not need any of the exporters here



##########
cpp/CMakeLists.txt:
##########
@@ -36,6 +36,19 @@ else()
   set(CONNECT_CONFIG_SRC src/connect_config_dummy.cpp)
 endif()
 
+# Check for OPENTELEMETRY-CPP for distributed tracing
+find_package(opentelemetry-cpp)
+option(ENABLE_OPENTELEMETRYCPP "Use opentelemetry for distributed tracing" ${OPENTELEMETRY-CPP_FOUND})
+
+if (ENABLE_OPENTELEMETRYCPP)
+  include_directories(${OPENTELEMETRY_CPP_INCLUDE_DIRS})
+  set(TRACING_SRC src/tracing_opentelemetry.cpp src/tracing_stub.cpp)
+  set(TRACING_LIBS opentelemetry-cpp::trace opentelemetry-cpp::jaeger_trace_exporter opentelemetry-cpp::ostream_span_exporter)
+  find_package(CURL REQUIRED)

Review Comment:
   Not needed now with otel 1.5.1



##########
cpp/examples/tracing_client.cpp:
##########
@@ -0,0 +1,179 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+
+#include "options.hpp"
+#include <proton/connection.hpp>
+#include <proton/container.hpp>
+#include <proton/delivery.hpp>
+#include <proton/message.hpp>
+#include <proton/messaging_handler.hpp>
+#include <proton/receiver_options.hpp>
+#include <proton/source_options.hpp>
+#include <proton/tracing.hpp>
+#include <proton/tracker.hpp>
+
+#include <iostream>
+#include <vector>
+
+// Include opentelemetry header files
+#include <opentelemetry/sdk/trace/simple_processor.h>
+#include <opentelemetry/sdk/trace/tracer_provider.h>
+#include <opentelemetry/trace/provider.h>
+#include <opentelemetry/nostd/unique_ptr.h>
+#include <opentelemetry/exporters/jaeger/jaeger_exporter.h>
+#include <opentelemetry/exporters/ostream/span_exporter.h>
+#include <opentelemetry/sdk/resource/resource.h>
+
+#include <opentelemetry/trace/span.h>
+#include <opentelemetry/trace/tracer.h>
+#include <opentelemetry/trace/context.h>
+
+using proton::receiver_options;
+using proton::source_options;
+opentelemetry::nostd::shared_ptr<opentelemetry::trace::TracerProvider> provider;
+
+class client : public proton::messaging_handler {
+  private:
+    std::string url;
+    std::vector<std::string> requests;
+    proton::sender sender;
+    proton::receiver receiver;
+
+  public:
+    client(const std::string &u, const std::vector<std::string>& r) : url(u), requests(r) {}
+
+    void on_container_start(proton::container &c) override {
+        sender = c.open_sender(url);
+        // Create a receiver requesting a dynamically created queue
+        // for the message source.
+        receiver_options opts = receiver_options().source(source_options().dynamic(true));
+        receiver = sender.connection().open_receiver("", opts);
+    }
+
+    void send_request() {
+        proton::message req;
+        req.body(requests.front());
+        req.reply_to(receiver.source().address());
+
+        // Start a span here before send.
+        opentelemetry::nostd::shared_ptr<opentelemetry::trace::Tracer> tracer = provider->GetTracer("qpid-tracer", OPENTELEMETRY_SDK_VERSION);
+        opentelemetry::nostd::shared_ptr<opentelemetry::trace::Span> span_a = tracer->StartSpan("CLIENT-before-send",
+            {{"Reply_to", req.reply_to()}});
+
+        opentelemetry::trace::Scope scope_a = tracer->WithActiveSpan(span_a);
+
+        sender.send(req);
+
+        // Start another span here after send.
+        opentelemetry::nostd::shared_ptr<opentelemetry::trace::Span> span_b = tracer->StartSpan("CLIENT-after-send",
+            {{"Reply_to", req.reply_to()}});
+
+        opentelemetry::trace::Scope scope_b = tracer->WithActiveSpan(span_b);
+    }
+
+    void on_receiver_open(proton::receiver &) override {
+        send_request();
+    }
+
+    void on_message(proton::delivery &d, proton::message &response) override {
+        if (requests.empty()) return; // Spurious extra message!
+
+        // Converting the tag in proton::binary to std::string to add it as a span attribute. Tag in binary won't be visible.
+        proton::binary tag = d.tag();
+        std::string tag_in_string = std::string(tag);
+        std::stringstream ss;
+        for (int i = 0; i < (int)tag_in_string.length(); ++i)
+            ss << std::hex << (int)tag[i];
+        std::string delivery_tag = ss.str();
+
+        // Get Tracer
+        opentelemetry::nostd::shared_ptr<opentelemetry::trace::Tracer> tracer = provider->GetTracer("qpid-tracer", OPENTELEMETRY_SDK_VERSION);
+
+        // Start span with or without attributes as required.
+        opentelemetry::nostd::shared_ptr<opentelemetry::trace::Span> s = tracer->StartSpan("CLIENT-on-message",
+            {{"Delivery_tag", delivery_tag}});
+
+        // Mark the span as active.
+        opentelemetry::trace::Scope sc = tracer->WithActiveSpan(s);
+
+        std::cout << requests.front() << " => " << response.body() << std::endl;
+        requests.erase(requests.begin());
+
+        if (!requests.empty()) {
+            send_request();
+        } else {
+            d.connection().close();
+        }
+    }
+};
+
+int main(int argc, char **argv) {
+    try {
+        std::string url("127.0.0.1:5672/examples");
+
+        // The below code is the minimum requirement to enable tracing in the proton.
+        // 1. Initialize the exporter and the provider.
+        // 2. Set the global trace provider.
+        // 3. Call proton::initOpenTelemetryTracer().
+
+        opentelemetry::exporter::jaeger::JaegerExporterOptions opts;
+
+        // Initialize Jaeger Exporter
+        std::unique_ptr<opentelemetry::sdk::trace::SpanExporter> exporter = std::unique_ptr<opentelemetry::sdk::trace::SpanExporter>(
+            new opentelemetry::exporter::jaeger::JaegerExporter(opts));
+
+        // Set service-name
+        auto resource_attributes = opentelemetry::sdk::resource::ResourceAttributes
+        {
+            {"service.name", "qpid-client"}

Review Comment:
   probably use qpid-example-client as service name



##########
cpp/examples/tracing_server.cpp:
##########
@@ -0,0 +1,148 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+
+#include "options.hpp"
+#include <proton/connection.hpp>
+#include <proton/container.hpp>
+#include <proton/message.hpp>
+#include <proton/message_id.hpp>
+#include <proton/messaging_handler.hpp>
+
+#include <proton/tracing.hpp>
+
+#include <iostream>
+#include <map>
+#include <string>
+#include <cctype>
+
+// Include opentelemetry header files
+#include <opentelemetry/sdk/trace/simple_processor.h>
+#include <opentelemetry/sdk/trace/tracer_provider.h>
+#include <opentelemetry/trace/provider.h>
+#include <opentelemetry/nostd/unique_ptr.h>
+#include <opentelemetry/exporters/jaeger/jaeger_exporter.h>
+#include <opentelemetry/exporters/ostream/span_exporter.h>
+#include <opentelemetry/sdk/resource/resource.h>
+
+#include <opentelemetry/trace/span.h>
+#include <opentelemetry/trace/tracer.h>
+#include <opentelemetry/trace/context.h>
+
+opentelemetry::nostd::shared_ptr<opentelemetry::trace::TracerProvider> provider;
+
+class server : public proton::messaging_handler {
+    std::string conn_url_;
+    std::string addr_;
+    proton::connection conn_;
+    std::map<std::string, proton::sender> senders_;
+
+  public:
+    server(const std::string& u, const std::string& a) :
+        conn_url_(u), addr_(a) {}
+
+    void on_container_start(proton::container& c) override {
+        conn_ = c.connect(conn_url_);
+        conn_.open_receiver(addr_);
+
+        std::cout << "Server connected to " << conn_url_ << std::endl;
+    }
+
+    std::string to_upper(const std::string& s) {
+        std::string uc(s);
+        size_t l = uc.size();
+
+        for (size_t i=0; i<l; i++) {
+            uc[i] = static_cast<char>(std::toupper(uc[i]));
+        }
+
+        return uc;
+    }
+
+    void on_message(proton::delivery&, proton::message& m) override {
+
+        // Start a span
+        opentelemetry::nostd::shared_ptr<opentelemetry::trace::Tracer> tracer = provider->GetTracer("qpid-tracer", OPENTELEMETRY_SDK_VERSION);
+        opentelemetry::nostd::shared_ptr<opentelemetry::trace::Span> s = tracer->StartSpan("SERVER-on-message");
+
+        opentelemetry::trace::Scope sc = tracer->WithActiveSpan(s);
+
+        std::cout << "Received " << m.body() << std::endl;
+
+        std::string reply_to = m.reply_to();
+        proton::message reply;
+
+        reply.to(reply_to);
+        reply.body(to_upper(proton::get<std::string>(m.body())));
+        reply.correlation_id(m.correlation_id());
+
+        if (!senders_[reply_to]) {
+            senders_[reply_to] = conn_.open_sender(reply_to);
+        }
+
+        senders_[reply_to].send(reply);
+    }
+};
+
+int main(int argc, char **argv) {
+    try {
+        std::string conn_url = argc > 1 ? argv[1] : "//127.0.0.1:5672";
+        std::string addr = argc > 2 ? argv[2] : "examples";
+
+        // The below code is the minimum requirement to enable tracing in the proton.
+        // 1. Initialize the exporter and the provider
+        // 2. Set the global trace provider
+        // 3. Call proton::initOpenTelemetryTracer()
+
+        // Initialize Jaeger Exporter
+        opentelemetry::exporter::jaeger::JaegerExporterOptions opts;
+        std::unique_ptr<opentelemetry::sdk::trace::SpanExporter> exporter = std::unique_ptr<opentelemetry::sdk::trace::SpanExporter>(
+            new opentelemetry::exporter::jaeger::JaegerExporter(opts));
+
+        // Set service-name
+        auto resource_attributes = opentelemetry::sdk::resource::ResourceAttributes
+        {
+            {"service.name", "qpid-server"}
+        };

Review Comment:
   qpid-example-server



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: dev-unsubscribe@qpid.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@qpid.apache.org
For additional commands, e-mail: dev-help@qpid.apache.org