src/agent/Shared/ApiServerUtils.h in passenger-5.1.7 vs src/agent/Shared/ApiServerUtils.h in passenger-5.1.8
- old
+ new
@@ -62,20 +62,23 @@
#include <oxt/backtrace.hpp>
#include <oxt/thread.hpp>
#include <sys/types.h>
#include <string>
#include <vector>
+#include <stdexcept>
#include <cstddef>
#include <cstring>
#include <jsoncpp/json.h>
#include <modp_b64.h>
#include <StaticString.h>
#include <Exceptions.h>
#include <DataStructures/LString.h>
#include <DataStructures/StringKeyTable.h>
#include <ServerKit/Server.h>
#include <ServerKit/HeaderTable.h>
+#include <LoggingKit/LoggingKit.h>
+#include <LoggingKit/Context.h>
#include <Utils.h>
#include <Utils/IOUtils.h>
#include <Utils/BufferedIO.h>
#include <Utils/StrIntUtils.h>
#include <Utils/VariantMap.h>
@@ -761,59 +764,74 @@
inline void
apiServerProcessReopenLogs(Server *server, Client *client, Request *req) {
if (req->method != HTTP_POST) {
apiServerRespondWith405(server, client, req);
} else if (authorizeAdminOperation(server, client, req)) {
- int e;
ServerKit::HeaderTable headers;
headers.insert(req->pool, "Content-Type", "application/json");
- string logFile = getLogFile();
- if (logFile.empty()) {
+ ConfigKit::Store config = LoggingKit::context->getConfig();
+ if (!config["target"].isMember("path")) {
server->writeSimpleResponse(client, 500, &headers, "{ \"status\": \"error\", "
"\"code\": \"NO_LOG_FILE\", "
"\"message\": \"" PROGRAM_NAME " was not configured with a log file.\" }\n");
if (!req->ended()) {
server->endRequest(&client, &req);
}
return;
}
- if (!setLogFile(logFile, &e)) {
- unsigned int bufsize = 1024;
+ LoggingKit::ConfigChangeRequest configReq;
+ vector<ConfigKit::Error> errors;
+ bool ok;
+ try {
+ ok = LoggingKit::context->prepareConfigChange(Json::objectValue,
+ errors, configReq);
+ } catch (const SystemException &e) {
+ unsigned int bufsize = 2048;
char *message = (char *) psg_pnalloc(req->pool, bufsize);
snprintf(message, bufsize, "{ \"status\": \"error\", "
- "\"code\": \"LOG_FILE_OPEN_ERROR\", "
- "\"message\": \"Cannot reopen log file %s: %s (errno=%d)\" }",
- logFile.c_str(), strerror(e), e);
+ "\"code\": \"OS_ERROR\", "
+ "\"message\": \"Cannot reopen log files: %s\" }",
+ e.what());
server->writeSimpleResponse(client, 500, &headers, message);
if (!req->ended()) {
server->endRequest(&client, &req);
}
return;
+ } catch (const std::exception &e) {
+ unsigned int bufsize = 2048;
+ char *message = (char *) psg_pnalloc(req->pool, bufsize);
+ snprintf(message, bufsize, "{ \"status\": \"error\", "
+ "\"code\": \"GENERIC_ERROR\", "
+ "\"message\": \"Cannot reopen log files: %s\" }",
+ e.what());
+ server->writeSimpleResponse(client, 500, &headers, message);
+ if (!req->ended()) {
+ server->endRequest(&client, &req);
+ }
+ return;
}
- P_NOTICE("Log file reopened.");
-
- if (hasFileDescriptorLogFile()) {
- if (!setFileDescriptorLogFile(getFileDescriptorLogFile(), &e)) {
- unsigned int bufsize = 1024;
- char *message = (char *) psg_pnalloc(req->pool, bufsize);
- snprintf(message, bufsize, "{ \"status\": \"error\", "
- "\"code\": \"FD_LOG_FILE_OPEN_ERROR\", "
- "\"message\": \"Cannot reopen file descriptor log file %s: %s (errno=%d)\" }",
- getFileDescriptorLogFile().c_str(), strerror(e), e);
- server->writeSimpleResponse(client, 500, &headers, message);
- if (!req->ended()) {
- server->endRequest(&client, &req);
- }
- return;
+ if (!ok) {
+ unsigned int bufsize = 2048;
+ char *message = (char *) psg_pnalloc(req->pool, bufsize);
+ snprintf(message, bufsize, "{ \"status\": \"error\", "
+ "\"code\": \"CONFIG_VALIDATION_ERROR\", "
+ "\"message\": \"Cannot reopen log files:"
+ " invalid logging system configuration: %s\" }",
+ ConfigKit::toString(errors).c_str());
+ server->writeSimpleResponse(client, 500, &headers, message);
+ if (!req->ended()) {
+ server->endRequest(&client, &req);
}
- P_NOTICE("File descriptor log file reopened.");
+ return;
}
- server->writeSimpleResponse(client, 200, &headers, "{ \"status\": \"ok\" }\n");
+ LoggingKit::context->commitConfigChange(configReq);
+ P_NOTICE("All log file(s) reopened.");
+ server->writeSimpleResponse(client, 200, &headers, "{ \"status\": \"ok\" }\n");
if (!req->ended()) {
server->endRequest(&client, &req);
}
} else {
apiServerRespondWith401(server, client, req);
@@ -836,11 +854,39 @@
"no log filename received in response");
return;
}
int fd = readFileDescriptorWithNegotiation(io.getFd(), &req.timeout);
- setLogFileWithFd(logFilePath, fd);
- safelyClose(fd);
+ FdGuard guard(fd, __FILE__, __LINE__);
+ P_LOG_FILE_DESCRIPTOR_PURPOSE(fd, "Reinherited log file handle");
+
+ ConfigKit::Store oldConfig = LoggingKit::context->getConfig();
+ Json::Value config;
+ vector<ConfigKit::Error> errors;
+ LoggingKit::ConfigChangeRequest configReq;
+ bool ok;
+
+ config["target"] = oldConfig["target"];
+ config["target"]["fd"] = fd;
+ try {
+ ok = LoggingKit::context->prepareConfigChange(config,
+ errors, configReq);
+ } catch (const std::exception &e) {
+ resp.status = InternalResponse::ERROR_INTERNAL;
+ resp.errorLogs.append("Error reconfiguring logging system: ");
+ resp.errorLogs.append(e.what());
+ return;
+ }
+ if (!ok) {
+ resp.status = InternalResponse::ERROR_INTERNAL;
+ resp.errorLogs.append("Error reconfiguring logging system: ");
+ resp.errorLogs.append(ConfigKit::toString(errors));
+ return;
+ }
+
+ LoggingKit::context->commitConfigChange(configReq);
+ guard.clear();
+ P_NOTICE("All log file(s) reinherited.");
}
template<typename Server, typename Client, typename Request>
inline void
_apiServerProcessReinheritLogsDone(ApiServerInternalHttpResponse<Server, Client, Request> resp) {