Implement basic proxy functionality (daemonizing, configuration).

This commit is contained in:
Christoph Heiss 2018-02-26 18:03:04 +01:00
parent e799e7e7e2
commit fb4cc5eda0

View file

@ -7,17 +7,31 @@
//
#include <iostream>
#include <string>
#include <fstream>
#include <unistd.h>
#include <cstring>
#include <cstdlib>
#include "clipp.h"
#include "spdlog/spdlog.h"
#include "nlohmann/json.hpp"
#include "resply.h"
#include "resp.pb.h"
using json = nlohmann::json;
struct Options {
Options() : daemonize{} { }
Options() :
config_path{".proxy-conf.json"}, daemonize{}, log_path{"proxy.log"},
port{"6543"}, remote_host{"localhost:6379"} { }
std::string config_path;
bool daemonize;
std::string log_path;
std::string port;
std::string remote_host;
};
@ -27,7 +41,15 @@ static Options parse_commandline(int argc, char** argv)
bool show_help{}, show_version{};
auto cli = (
clipp::option("-c", "--conf-path").set(options.config_path)
.doc("Path to the configuration file [default: $CWD/.proxy-conf.json]"),
clipp::option("-d", "--daemonize").set(options.daemonize).doc("Fork to background."),
clipp::option("-l", "--log-path").set(options.log_path)
.doc("Path to the log file [default: $CWD/proxy.log] (Only applies when not daemonized.)"),
clipp::option("-p", "--port").set(options.port)
.doc("Port to listen on [default: 6543]"),
clipp::option("-r", "--remote-host").set(options.remote_host)
.doc("Host (redis-server) to connect to [default: localhost:6379]"),
clipp::option("--help").set(show_help).doc("Show help and exit."),
clipp::option("--version").set(show_version).doc("Show version and exit.")
);
@ -48,13 +70,84 @@ static Options parse_commandline(int argc, char** argv)
}
static void clean_up()
{
google::protobuf::ShutdownProtobufLibrary();
}
static json read_config_file(std::shared_ptr<spdlog::logger> logger, const std::string& path)
{
if (!path.length()) {
return {};
}
std::ifstream config_file{path};
json config;
if (!config_file) {
logger->warn("Configuration file not found! Using compiled-in defaults ..");
} else {
config_file >> config;
config_file.close();
}
return config;
}
static void daemonize_process(std::shared_ptr<spdlog::logger> logger)
{
pid_t pid{::fork()};
if (pid < 0) {
logger->error("Could not fork process, reason: {}", ::strerror(errno));
std::exit(1);
} else if (pid > 0) {
// Quit the parent
std::exit(0);
}
// Now only the child is still running
// Change the file mode mask
::umask(07);
// Create new process session so the daemon becomes independent of the parent
if (::setsid() < 0) {
logger->error("Could not create new process session, reason: {}", ::strerror(errno));
std::exit(2);
}
// Change iostreams
::freopen("/dev/null", "r", ::stdin);
::freopen("/dev/null", "w", ::stdout);
::freopen("/dev/null", "w", ::stderr);
}
int main(int argc, char* argv[])
{
std::atexit(clean_up);
GOOGLE_PROTOBUF_VERIFY_VERSION;
auto options{parse_commandline(argc, argv)};
auto logger{spdlog::stdout_color_mt("proxy-log")};
logger->flush_on(spdlog::level::warn);
google::protobuf::ShutdownProtobufLibrary();
json config{read_config_file(logger, options.config_path)};
if (options.daemonize) {
logger->info("Daemonizing server, logfile: {}", options.log_path);
daemonize_process(logger);
// The parent process has exited already.
logger = spdlog::rotating_logger_mt("proxy-rot-log", options.log_path,
1048576 * 10, 10);
logger->flush_on(spdlog::level::warn);
}
for (;;) {
}
return 0;
}