Skip to content

Commit be30611

Browse files
authored
ARROW-14958: [C++][Python][FlightRPC] Implement Flight middleware for OpenTelemetry propagation (apache#11920)
Adds a client middleware that sends span/trace ID to the server, and a server middleware that gets the span/trace ID and starts a child span. The middleware are available in builds without OpenTelemetry, they simply do nothing. Authored-by: David Li <li.davidm96@gmail.com> Signed-off-by: David Li <li.davidm96@gmail.com>
1 parent f941118 commit be30611

13 files changed

Lines changed: 726 additions & 22 deletions

‎cpp/src/arrow/flight/CMakeLists.txt‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -184,10 +184,13 @@ set(ARROW_FLIGHT_SRCS
184184
"${CMAKE_CURRENT_BINARY_DIR}/Flight.pb.cc"
185185
client.cc
186186
client_cookie_middleware.cc
187+
client_tracing_middleware.cc
187188
cookie_internal.cc
189+
middleware.cc
188190
serialization_internal.cc
189191
server.cc
190192
server_auth.cc
193+
server_tracing_middleware.cc
191194
transport.cc
192195
transport_server.cc
193196
# Bundle the gRPC impl with libarrow_flight

‎cpp/src/arrow/flight/api.h‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,10 @@
2020
#include "arrow/flight/client.h"
2121
#include "arrow/flight/client_auth.h"
2222
#include "arrow/flight/client_middleware.h"
23+
#include "arrow/flight/client_tracing_middleware.h"
2324
#include "arrow/flight/middleware.h"
2425
#include "arrow/flight/server.h"
2526
#include "arrow/flight/server_auth.h"
2627
#include "arrow/flight/server_middleware.h"
28+
#include "arrow/flight/server_tracing_middleware.h"
2729
#include "arrow/flight/types.h"
Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
// Licensed to the Apache Software Foundation (ASF) under one
2+
// or more contributor license agreements. See the NOTICE file
3+
// distributed with this work for additional information
4+
// regarding copyright ownership. The ASF licenses this file
5+
// to you under the Apache License, Version 2.0 (the
6+
// "License"); you may not use this file except in compliance
7+
// with the License. You may obtain a copy of the License at
8+
//
9+
// http://www.apache.org/licenses/LICENSE-2.0
10+
//
11+
// Unless required by applicable law or agreed to in writing,
12+
// software distributed under the License is distributed on an
13+
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14+
// KIND, either express or implied. See the License for the
15+
// specific language governing permissions and limitations
16+
// under the License.
17+
18+
#include "arrow/flight/client_tracing_middleware.h"
19+
20+
#include <memory>
21+
#include <string>
22+
#include <utility>
23+
#include <vector>
24+
25+
#include "arrow/util/tracing_internal.h"
26+
27+
#ifdef ARROW_WITH_OPENTELEMETRY
28+
#include <opentelemetry/context/propagation/global_propagator.h>
29+
#include <opentelemetry/context/propagation/text_map_propagator.h>
30+
#endif
31+
32+
namespace arrow {
33+
namespace flight {
34+
35+
namespace {
36+
#ifdef ARROW_WITH_OPENTELEMETRY
37+
namespace otel = opentelemetry;
38+
class FlightClientCarrier : public otel::context::propagation::TextMapCarrier {
39+
public:
40+
FlightClientCarrier() = default;
41+
42+
otel::nostd::string_view Get(otel::nostd::string_view key) const noexcept override {
43+
return "";
44+
}
45+
46+
void Set(otel::nostd::string_view key,
47+
otel::nostd::string_view value) noexcept override {
48+
context_.emplace_back(key, value);
49+
}
50+
51+
std::vector<std::pair<std::string, std::string>> context_;
52+
};
53+
54+
class TracingClientMiddleware : public ClientMiddleware {
55+
public:
56+
explicit TracingClientMiddleware(FlightClientCarrier carrier)
57+
: carrier_(std::move(carrier)) {}
58+
virtual ~TracingClientMiddleware() = default;
59+
60+
void SendingHeaders(AddCallHeaders* outgoing_headers) override {
61+
// The exact headers added are not arbitrary and are defined in
62+
// the OpenTelemetry specification (see
63+
// open-telemetry/opentelemetry-specification api-propagators.md)
64+
for (const auto& pair : carrier_.context_) {
65+
outgoing_headers->AddHeader(pair.first, pair.second);
66+
}
67+
}
68+
void ReceivedHeaders(const CallHeaders&) override {}
69+
void CallCompleted(const Status&) override {}
70+
71+
private:
72+
FlightClientCarrier carrier_;
73+
};
74+
75+
class TracingClientMiddlewareFactory : public ClientMiddlewareFactory {
76+
public:
77+
virtual ~TracingClientMiddlewareFactory() = default;
78+
void StartCall(const CallInfo& info,
79+
std::unique_ptr<ClientMiddleware>* middleware) override {
80+
FlightClientCarrier carrier;
81+
auto context = otel::context::RuntimeContext::GetCurrent();
82+
auto propagator =
83+
otel::context::propagation::GlobalTextMapPropagator::GetGlobalPropagator();
84+
propagator->Inject(carrier, context);
85+
*middleware = std::make_unique<TracingClientMiddleware>(std::move(carrier));
86+
}
87+
};
88+
#else
89+
class TracingClientMiddlewareFactory : public ClientMiddlewareFactory {
90+
public:
91+
virtual ~TracingClientMiddlewareFactory() = default;
92+
void StartCall(const CallInfo&, std::unique_ptr<ClientMiddleware>*) override {}
93+
};
94+
#endif
95+
} // namespace
96+
97+
std::shared_ptr<ClientMiddlewareFactory> MakeTracingClientMiddlewareFactory() {
98+
return std::make_shared<TracingClientMiddlewareFactory>();
99+
}
100+
101+
} // namespace flight
102+
} // namespace arrow
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
// Licensed to the Apache Software Foundation (ASF) under one
2+
// or more contributor license agreements. See the NOTICE file
3+
// distributed with this work for additional information
4+
// regarding copyright ownership. The ASF licenses this file
5+
// to you under the Apache License, Version 2.0 (the
6+
// "License"); you may not use this file except in compliance
7+
// with the License. You may obtain a copy of the License at
8+
//
9+
// http://www.apache.org/licenses/LICENSE-2.0
10+
//
11+
// Unless required by applicable law or agreed to in writing,
12+
// software distributed under the License is distributed on an
13+
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14+
// KIND, either express or implied. See the License for the
15+
// specific language governing permissions and limitations
16+
// under the License.
17+
18+
// Middleware implementation for propagating OpenTelemetry spans.
19+
20+
#pragma once
21+
22+
#include <memory>
23+
24+
#include "arrow/flight/client_middleware.h"
25+
26+
namespace arrow {
27+
namespace flight {
28+
29+
/// \brief Returns a ClientMiddlewareFactory that handles sending OpenTelemetry spans.
30+
ARROW_FLIGHT_EXPORT std::shared_ptr<ClientMiddlewareFactory>
31+
MakeTracingClientMiddlewareFactory();
32+
33+
} // namespace flight
34+
} // namespace arrow

0 commit comments

Comments
 (0)