aboutsummaryrefslogtreecommitdiff
path: root/src/zenserver/diag/otlphttp.h
blob: 64b3dbc879df14df8996a027a7a4c842d94e0b1c (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
// Copyright Epic Games, Inc. All Rights Reserved.

#pragma once

#include <zencore/logging/sink.h>
#include <zencore/zencore.h>
#include <zenhttp/httpclient.h>
#include <zentelemetry/otlpencoder.h>
#include <zentelemetry/otlptrace.h>

#include <atomic>

#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<Formatter>) override {}

	void RecordSpans(zen::otel::TraceId Trace, std::span<const zen::otel::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<const zen::otel::Span*> Spans) override;

		OtelHttpProtobufSink* m_Sink;
	};

	static constexpr uint32_t kMaxReportedFailures = 5;

	RwLock				  m_Lock;
	std::atomic<uint32_t> m_ConsecutivePostFailures{0};
	HttpClient			  m_OtelHttp;
	OtlpEncoder			  m_Encoder;
	Ref<TraceRecorder>	  m_TraceRecorder;
};

}  // namespace zen::logging

#endif