diff options
| author | Per Larsson <[email protected]> | 2021-11-18 18:50:09 +0100 |
|---|---|---|
| committer | Per Larsson <[email protected]> | 2021-11-18 18:50:09 +0100 |
| commit | 78ef39fdfa3c7ccf6531c3ff77baf2ca7e8a42ff (patch) | |
| tree | 8b0419f93d8a0b6002dd856222ffd998d51f71c4 /zenserver/diag/diagsvcs.cpp | |
| parent | Change error code for failed upsteam apply (diff) | |
| download | zen-78ef39fdfa3c7ccf6531c3ff77baf2ca7e8a42ff.tar.xz zen-78ef39fdfa3c7ccf6531c3ff77baf2ca7e8a42ff.zip | |
Extended Health endpoint with support for returning build version and log file.
Diffstat (limited to 'zenserver/diag/diagsvcs.cpp')
| -rw-r--r-- | zenserver/diag/diagsvcs.cpp | 113 |
1 files changed, 113 insertions, 0 deletions
diff --git a/zenserver/diag/diagsvcs.cpp b/zenserver/diag/diagsvcs.cpp new file mode 100644 index 000000000..edd9b782e --- /dev/null +++ b/zenserver/diag/diagsvcs.cpp @@ -0,0 +1,113 @@ +// Copyright Epic Games, Inc. All Rights Reserved. + +#include "diagsvcs.h" + +#include <zencore/compactbinary.h> +#include <zencore/compactbinarybuilder.h> +#include <zencore/filesystem.h> +#include <zencore/logging.h> +#include <zencore/string.h> +#include <fstream> +#include <sstream> + +#include <json11.hpp> + +namespace zen { + +using namespace std::literals; + +bool +ReadFile(const std::string& Path, StringBuilderBase& Out) +{ + try + { + constexpr auto ReadSize = std::size_t{4096}; + auto FileStream = std::ifstream{Path}; + + std::string Buf(ReadSize, '\0'); + while (FileStream.read(&Buf[0], ReadSize)) + { + Out.Append(std::string_view(&Buf[0], FileStream.gcount())); + } + Out.Append(std::string_view(&Buf[0], FileStream.gcount())); + + return true; + } + catch (std::exception&) + { + Out.Reset(); + return false; + } +} + +HttpHealthService::HttpHealthService() +{ + m_Router.RegisterRoute( + "", + [this](HttpRouterRequest& RoutedReq) { + HttpServerRequest& HttpReq = RoutedReq.ServerRequest(); + HttpReq.WriteResponse(HttpResponseCode::OK, HttpContentType::kText, u8"OK!"sv); + }, + HttpVerb::kGet); + + m_Router.RegisterRoute( + "info", + [this](HttpRouterRequest& RoutedReq) { + HttpServerRequest& HttpReq = RoutedReq.ServerRequest(); + + CbObjectWriter Writer; + Writer << "DataRoot"sv << m_HealthInfo.DataRoot.string(); + Writer << "AbsLogPath"sv << m_HealthInfo.AbsLogPath.string(); + Writer << "BuildVersion"sv << m_HealthInfo.BuildVersion; + Writer << "HttpServerClass"sv << m_HealthInfo.HttpServerClass; + + ExtendableStringBuilder<256> Sb; + HttpReq.WriteResponse(HttpResponseCode::OK, HttpContentType::kJSON, Writer.Save().ToJson(Sb).ToView()); + }, + HttpVerb::kGet); + + m_Router.RegisterRoute( + "log", + [this](HttpRouterRequest& RoutedReq) { + HttpServerRequest& HttpReq = RoutedReq.ServerRequest(); + + zen::Log().flush(); + + std::filesystem::path Path = + m_HealthInfo.AbsLogPath.empty() ? m_HealthInfo.DataRoot / "logs/zenserver.log" : m_HealthInfo.AbsLogPath; + + ExtendableStringBuilder<4096> Sb; + if (ReadFile(Path.string(), Sb) && Sb.Size() > 0) + { + HttpReq.WriteResponse(HttpResponseCode::OK, HttpContentType::kText, Sb.ToView()); + } + else + { + HttpReq.WriteResponse(HttpResponseCode::NotFound); + } + }, + HttpVerb::kGet); +} + +void +HttpHealthService::SetHealthInfo(HealthServiceInfo&& Info) +{ + m_HealthInfo = std::move(Info); +} + +const char* +HttpHealthService::BaseUri() const +{ + return "/health/"; +} + +void +HttpHealthService::HandleRequest(HttpServerRequest& Request) +{ + if (!m_Router.HandleRequest(Request)) + { + Request.WriteResponse(HttpResponseCode::OK, HttpContentType::kText, u8"OK!"sv); + } +} + +} // namespace zen |