From ac3ca061ac4dcf107f3b0f60bb58d40b199458d8 Mon Sep 17 00:00:00 2001 From: Dan Engelbrecht Date: Mon, 12 Feb 2024 14:50:46 +0100 Subject: Added --copy-log, --copy-cache-log and copy-http-log option to zen logs command (#651) * be safe and use ToText() rather than AsText() when getting http responses * Added `--copy-log`, `--copy-cache-log` and `copy-http-log` option to zen logs command to copy logs from a local running zen server instance --- src/zen/cmds/admin_cmd.cpp | 72 ++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 64 insertions(+), 8 deletions(-) (limited to 'src/zen/cmds/admin_cmd.cpp') diff --git a/src/zen/cmds/admin_cmd.cpp b/src/zen/cmds/admin_cmd.cpp index 1bde785c7..15a729c78 100644 --- a/src/zen/cmds/admin_cmd.cpp +++ b/src/zen/cmds/admin_cmd.cpp @@ -59,11 +59,11 @@ ScrubCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** argv) ZEN_ERROR("scrub start failed: {}: {} ({})", (int)Response.StatusCode, ReasonStringForHttpResultCode((int)Response.StatusCode), - Response.AsText()); + Response.ToText()); } else { - ZEN_ERROR("scrub start failed: {}", Response.AsText()); + ZEN_ERROR("scrub start failed: {}", Response.ToText()); } return 1; @@ -358,7 +358,7 @@ JobCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** argv) } else if (HttpClient::Response Result = Http.Get(Url, HttpClient::Accept(ZenContentType::kJSON))) { - ZEN_CONSOLE("{}", Result.AsText()); + ZEN_CONSOLE("{}", Result.ToText()); } else { @@ -379,6 +379,24 @@ LoggingCommand::LoggingCommand() m_Options.add_option("", "", "cache-access-log", "Enable cache access logging", cxxopts::value(m_CacheAccessLog), ""); m_Options .add_option("", "", "set-log-level", "Set zenserver log level", cxxopts::value(m_SetLogLevel), ""); + m_Options.add_option("", + "", + "copy-log", + "Copy the server log file from a local zenserver instance", + cxxopts::value(m_ServerLogTarget), + ""); + m_Options.add_option("", + "", + "copy-cache-log", + "Copy the server cache log file from a local zenserver instance", + cxxopts::value(m_CacheLogTarget), + ""); + m_Options.add_option("", + "", + "copy-http-log", + "Copy the server http log file from a local zenserver instance", + cxxopts::value(m_HttpLogTarget), + ""); } LoggingCommand::~LoggingCommand() = default; @@ -447,9 +465,47 @@ LoggingCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** argv) if ((*Parameters).empty()) { - if (HttpClient::Response Result = Http.Get("/admin/logs", HttpClient::Accept(ZenContentType::kJSON))) + if (HttpClient::Response Result = Http.Get("/admin/logs", HttpClient::Accept(ZenContentType::kCbObject))) { - ZEN_CONSOLE("{}", Result.AsText()); + ZEN_CONSOLE("{}", Result.ToText()); + const CbObject LogsResponse = Result.AsObject(); + + auto CopyLog = [](std::string_view SourceName, std::string_view SourcePath, std::string_view TargetPath) -> bool { + if (SourcePath.empty()) + { + ZEN_ERROR("Failed to retrieve {} log path", SourceName); + return false; + } + if (!CopyFile(SourcePath, TargetPath, {})) + { + ZEN_ERROR("Failed to copy {} log file {} to output file '{}'", SourceName, SourcePath, TargetPath); + return false; + } + return true; + }; + + if (!m_ServerLogTarget.empty()) + { + if (!CopyLog("server", LogsResponse["Logfile"].AsString(), m_ServerLogTarget)) + { + return 1; + } + } + + if (!m_CacheLogTarget.empty()) + { + if (!CopyLog("cache", LogsResponse["cache"].AsObjectView()["Logfile"].AsString(), m_CacheLogTarget)) + { + return 1; + } + } + if (!m_HttpLogTarget.empty()) + { + if (!CopyLog("http", LogsResponse["http"].AsObjectView()["Logfile"].AsString(), m_HttpLogTarget)) + { + return 1; + } + } } else { @@ -460,7 +516,7 @@ LoggingCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** argv) } if (HttpClient::Response Result = Http.Post("/admin/logs", HttpClient::KeyValueMap{}, Parameters)) { - ZEN_CONSOLE("{}", Result.AsText()); + ZEN_CONSOLE("{}", Result.ToText()); } else { @@ -511,11 +567,11 @@ FlushCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** argv) ZEN_ERROR("flush failed: {}: {} ({})", (int)Response.StatusCode, ReasonStringForHttpResultCode((int)Response.StatusCode), - Response.AsText()); + Response.ToText()); } else { - ZEN_ERROR("flush failed: {}", Response.AsText()); + ZEN_ERROR("flush failed: {}", Response.ToText()); } return 1; -- cgit v1.2.3