]> git.proxmox.com Git - ceph.git/blame - ceph/src/jaegertracing/opentelemetry-cpp/exporters/otlp/src/otlp_grpc_log_exporter.cc
update ceph source to reef 18.1.2
[ceph.git] / ceph / src / jaegertracing / opentelemetry-cpp / exporters / otlp / src / otlp_grpc_log_exporter.cc
CommitLineData
1e59de90
TL
1// Copyright The OpenTelemetry Authors
2// SPDX-License-Identifier: Apache-2.0
3
4#ifdef ENABLE_LOGS_PREVIEW
5
6# include "opentelemetry/exporters/otlp/otlp_grpc_log_exporter.h"
7# include "opentelemetry/exporters/otlp/otlp_log_recordable.h"
8# include "opentelemetry/exporters/otlp/otlp_recordable_utils.h"
9
10// clang-format off
11
12# include "opentelemetry/exporters/otlp/protobuf_include_prefix.h"
13
14# include "opentelemetry/proto/collector/logs/v1/logs_service.pb.h"
15# include "opentelemetry/proto/collector/logs/v1/logs_service.grpc.pb.h"
16
17# include "opentelemetry/exporters/otlp/protobuf_include_suffix.h"
18
19// clang-format on
20
21# include "opentelemetry/ext/http/common/url_parser.h"
22# include "opentelemetry/sdk/common/global_log_handler.h"
23
24# include <chrono>
25# include <fstream>
26# include <memory>
27
28# include <grpcpp/grpcpp.h>
29
30OPENTELEMETRY_BEGIN_NAMESPACE
31namespace exporter
32{
33namespace otlp
34{
35
36// ----------------------------- Helper functions ------------------------------
37// TODO: move exporters shared function to OTLP common library.
38static std::string get_file_contents(const char *fpath)
39{
40 std::ifstream finstream(fpath);
41 std::string contents;
42 contents.assign((std::istreambuf_iterator<char>(finstream)), std::istreambuf_iterator<char>());
43 finstream.close();
44 return contents;
45}
46
47struct OtlpGrpcExporterOptions;
48
49/**
50 * Create gRPC channel from the exporter options.
51 */
52static std::shared_ptr<grpc::Channel> MakeGrpcChannel(const OtlpGrpcExporterOptions &options)
53{
54 std::shared_ptr<grpc::Channel> channel;
55
56 //
57 // Scheme is allowed in OTLP endpoint definition, but is not allowed for creating gRPC channel.
58 // Passing URI with scheme to grpc::CreateChannel could resolve the endpoint to some unexpected
59 // address.
60 //
61
62 ext::http::common::UrlParser url(options.endpoint);
63 if (!url.success_)
64 {
65 OTEL_INTERNAL_LOG_ERROR("[OTLP Exporter] invalid endpoint: " << options.endpoint);
66
67 return nullptr;
68 }
69
70 std::string grpc_target = url.host_ + ":" + std::to_string(static_cast<int>(url.port_));
71
72 if (options.use_ssl_credentials)
73 {
74 grpc::SslCredentialsOptions ssl_opts;
75 if (options.ssl_credentials_cacert_path.empty())
76 {
77 ssl_opts.pem_root_certs = options.ssl_credentials_cacert_as_string;
78 }
79 else
80 {
81 ssl_opts.pem_root_certs = get_file_contents((options.ssl_credentials_cacert_path).c_str());
82 }
83 channel = grpc::CreateChannel(grpc_target, grpc::SslCredentials(ssl_opts));
84 }
85 else
86 {
87 channel = grpc::CreateChannel(grpc_target, grpc::InsecureChannelCredentials());
88 }
89
90 return channel;
91}
92
93// ----------------------------- Helper functions ------------------------------
94
95/**
96 * Create log service stub to communicate with the OpenTelemetry Collector.
97 */
98std::unique_ptr<::opentelemetry::proto::collector::logs::v1::LogsService::Stub> MakeLogServiceStub(
99 const OtlpGrpcExporterOptions &options)
100{
101 return proto::collector::logs::v1::LogsService::NewStub(MakeGrpcChannel(options));
102}
103
104// -------------------------------- Constructors --------------------------------
105
106OtlpGrpcLogExporter::OtlpGrpcLogExporter() : OtlpGrpcLogExporter(OtlpGrpcExporterOptions()) {}
107
108OtlpGrpcLogExporter::OtlpGrpcLogExporter(const OtlpGrpcExporterOptions &options)
109 : options_(options), log_service_stub_(MakeLogServiceStub(options))
110{}
111
112OtlpGrpcLogExporter::OtlpGrpcLogExporter(
113 std::unique_ptr<proto::collector::logs::v1::LogsService::StubInterface> stub)
114 : options_(OtlpGrpcExporterOptions()), log_service_stub_(std::move(stub))
115{}
116
117// ----------------------------- Exporter methods ------------------------------
118
119std::unique_ptr<opentelemetry::sdk::logs::Recordable> OtlpGrpcLogExporter::MakeRecordable() noexcept
120{
121 return std::unique_ptr<opentelemetry::sdk::logs::Recordable>(
122 new exporter::otlp::OtlpLogRecordable());
123}
124
125opentelemetry::sdk::common::ExportResult OtlpGrpcLogExporter::Export(
126 const nostd::span<std::unique_ptr<opentelemetry::sdk::logs::Recordable>> &logs) noexcept
127{
128 if (isShutdown())
129 {
130 OTEL_INTERNAL_LOG_ERROR("[OTLP gRPC log] Exporting " << logs.size()
131 << " log(s) failed, exporter is shutdown");
132 return sdk::common::ExportResult::kFailure;
133 }
134 if (logs.empty())
135 {
136 return sdk::common::ExportResult::kSuccess;
137 }
138
139 proto::collector::logs::v1::ExportLogsServiceRequest request;
140 OtlpRecordableUtils::PopulateRequest(logs, &request);
141
142 grpc::ClientContext context;
143 proto::collector::logs::v1::ExportLogsServiceResponse response;
144
145 if (options_.timeout.count() > 0)
146 {
147 context.set_deadline(std::chrono::system_clock::now() + options_.timeout);
148 }
149
150 for (auto &header : options_.metadata)
151 {
152 context.AddMetadata(header.first, header.second);
153 }
154 grpc::Status status = log_service_stub_->Export(&context, request, &response);
155
156 if (!status.ok())
157 {
158 OTEL_INTERNAL_LOG_ERROR("[OTLP LOG GRPC Exporter] Export() failed: " << status.error_message());
159 return sdk::common::ExportResult::kFailure;
160 }
161 return sdk::common::ExportResult::kSuccess;
162}
163
164bool OtlpGrpcLogExporter::Shutdown(std::chrono::microseconds timeout) noexcept
165{
166 const std::lock_guard<opentelemetry::common::SpinLockMutex> locked(lock_);
167 is_shutdown_ = true;
168 return true;
169}
170
171bool OtlpGrpcLogExporter::isShutdown() const noexcept
172{
173 const std::lock_guard<opentelemetry::common::SpinLockMutex> locked(lock_);
174 return is_shutdown_;
175}
176
177} // namespace otlp
178} // namespace exporter
179OPENTELEMETRY_END_NAMESPACE
180
181#endif