// Copyright Epic Games, Inc. All Rights Reserved. #pragma once #include #include #include #include #include #include #if ZEN_WITH_OTEL namespace zen::logging { /** * OTLP/HTTP sink for logging * * Sends log messages and traces to an OpenTelemetry collector via OTLP over HTTP */ class OtelHttpProtobufSink : public Sink { public: // Note that this URI should be the base URI of the OTLP HTTP endpoint, e.g. // "http://otel-collector:4318" OtelHttpProtobufSink(const std::string_view& Uri); ~OtelHttpProtobufSink(); OtelHttpProtobufSink(const OtelHttpProtobufSink&) = delete; OtelHttpProtobufSink& operator=(const OtelHttpProtobufSink&) = delete; private: virtual void Log(const LogMessage& Msg) override; virtual void Flush() override; virtual void SetFormatter(std::unique_ptr) override {} void RecordSpans(zen::otel::TraceId Trace, std::span Spans); void CheckPostResult(const HttpClient::Response& Result, const char* Endpoint) noexcept; // This is just a thin wrapper to call back into the sink while participating in // reference counting from the OTEL trace back-end class TraceRecorder : public zen::otel::TraceRecorder { public: TraceRecorder(OtelHttpProtobufSink* InSink) : m_Sink(InSink) {} private: TraceRecorder(const TraceRecorder&) = delete; TraceRecorder& operator=(const TraceRecorder&) = delete; virtual void RecordSpans(zen::otel::TraceId Trace, std::span Spans) override; OtelHttpProtobufSink* m_Sink; }; static constexpr uint32_t kMaxReportedFailures = 5; RwLock m_Lock; std::atomic m_ConsecutivePostFailures{0}; HttpClient m_OtelHttp; OtlpEncoder m_Encoder; Ref m_TraceRecorder; }; } // namespace zen::logging #endif