aboutsummaryrefslogtreecommitdiff
path: root/src/zenserver/diag/logging.cpp
blob: f3d8dbfe38fadf825bf27d3f8a5c769e7b390c1d (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
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
// Copyright Epic Games, Inc. All Rights Reserved.

#include "logging.h"

#include "config/config.h"

#include <zencore/filesystem.h>
#include <zencore/fmtutils.h>
#include <zencore/logging/broadcastsink.h>
#include <zencore/logging/logger.h>
#include <zencore/logging/registry.h>
#include <zencore/memory/llm.h>
#include <zencore/session.h>
#include <zencore/string.h>
#include <zenutil/logging.h>
#include <zenutil/logging/rotatingfilesink.h>
#include <zenutil/splitconsole/tcplogstreamsink.h>

#include "otlphttp.h"

namespace zen {

void
InitializeServerLogging(const ZenServerConfig& InOptions, bool WithCacheService)
{
	ZEN_MEMSCOPE(ELLMTag::Logging);

	const LoggingOptions LogOptions = {.IsDebug			= InOptions.IsDebug,
									   .IsVerbose		= false,
									   .IsTest			= InOptions.IsTest,
									   .NoConsoleOutput = InOptions.LoggingConfig.NoConsoleOutput,
									   .QuietConsole	= InOptions.LoggingConfig.QuietConsole,
									   .ForceColor		= InOptions.LoggingConfig.ForceColor,
									   .AbsLogFile		= InOptions.LoggingConfig.AbsLogFile,
									   .LogId			= InOptions.LoggingConfig.LogId};

	BeginInitializeLogging(LogOptions);

	// Initialize loggers

	auto FileSink = GetFileSink();

	// HTTP server request logging
	std::filesystem::path HttpLogPath = InOptions.DataDir / "logs" / "http.log";
	zen::CreateDirectories(HttpLogPath.parent_path());

	logging::SinkPtr	 HttpSink(new zen::logging::RotatingFileSink(HttpLogPath,
																 /* max size */ 128 * 1024 * 1024,
																 /* max files */ 16,
																 /* rotate on open */ true));
	Ref<logging::Logger> HttpLogger(new logging::Logger("http_requests", HttpSink));
	logging::Registry::Instance().Register(HttpLogger);

	if (WithCacheService)
	{
		// Cache request logging
		std::filesystem::path CacheLogPath = InOptions.DataDir / "logs" / "z$.log";
		zen::CreateDirectories(CacheLogPath.parent_path());

		logging::SinkPtr	 CacheSink(new zen::logging::RotatingFileSink(CacheLogPath,
																	  /* max size */ 128 * 1024 * 1024,
																	  /* max files */ 16,
																	  /* rotate on open */ false));
		Ref<logging::Logger> CacheLogger(new logging::Logger("z$", CacheSink));
		logging::Registry::Instance().Register(CacheLogger);

		// Jupiter - only log upstream HTTP traffic to file

		Ref<logging::Logger> JupiterLogger(new logging::Logger("jupiter", FileSink));
		logging::Registry::Instance().Register(JupiterLogger);

		// Zen - only log upstream HTTP traffic to file

		Ref<logging::Logger> ZenClientLogger(new logging::Logger("zenclient", FileSink));
		logging::Registry::Instance().Register(ZenClientLogger);
	}

	Ref<logging::BroadcastSink> BroadcastSink = GetDefaultBroadcastSink();

#if ZEN_WITH_OTEL
	if (BroadcastSink && !InOptions.LoggingConfig.OtelEndpointUri.empty())
	{
		// TODO: Should sanity check that endpoint is reachable? Also, a valid URI?
		logging::SinkPtr OtelSink(new zen::logging::OtelHttpProtobufSink(InOptions.LoggingConfig.OtelEndpointUri));
		BroadcastSink->AddSink(std::move(OtelSink));
	}
#endif

	if (BroadcastSink && !InOptions.LoggingConfig.LogStreamEndpoint.empty())
	{
		std::string Endpoint = InOptions.LoggingConfig.LogStreamEndpoint;
		std::string Host	 = "localhost";
		uint16_t	Port	 = 0;

		auto ColonPos = Endpoint.rfind(':');
		if (ColonPos != std::string::npos)
		{
			Host					  = Endpoint.substr(0, ColonPos);
			std::optional<uint16_t> P = ParseInt<uint16_t>(std::string_view(Endpoint).substr(ColonPos + 1));
			Port					  = P.value_or(0);
		}

		if (Port > 0)
		{
			logging::SinkPtr StreamSink(new TcpLogStreamSink(Host, Port, "zenserver"));
			BroadcastSink->AddSink(std::move(StreamSink));
		}
	}

	FinishInitializeLogging(LogOptions);

	const zen::Oid ServerSessionId = zen::GetSessionId();

	logging::Registry::Instance().ApplyAll([&](auto Logger) {
		static constinit logging::LogPoint SessionIdPoint{{}, logging::Info, "server session id: {}"};
		ZEN_MEMSCOPE(ELLMTag::Logging);
		Logger->Log(SessionIdPoint, fmt::make_format_args(ServerSessionId));
	});
}

void
ShutdownServerLogging()
{
	ZEN_MEMSCOPE(ELLMTag::Logging);

	zen::ShutdownLogging();
}

}  // namespace zen