Add multi-host support
This refactoring includes:
- added multi-host mode support;
- added support for graceful shutdown of the service;
- added support to flush the log buffer as it fills;
- D-Bus service xyz.openbmc_project.HostLogger replaced with SIGUSR1
signal handler;
- self diagnostic messages now registered via phosphor-logging;
- added unit tests;
- build system migrated from autotools to meson;
- source code aligned with OpenBMC conventions.
Change-Id: If6c1dfde278af685d8563450543a6587a282c7e4
Signed-off-by: Artem Senichev <a.senichev@yadro.com>
diff --git a/src/main.cpp b/src/main.cpp
index 89b4f58..cb8d2bc 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -1,201 +1,77 @@
-/**
- * @brief Host logger service entry point.
- *
- * This file is part of HostLogger project.
- *
- * Copyright (c) 2018 YADRO
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
+// SPDX-License-Identifier: Apache-2.0
+// Copyright (C) 2020 YADRO
#include "config.hpp"
-#include "dbus_server.hpp"
-#include "dbus_watch.hpp"
-#include "log_manager.hpp"
+#include "service.hpp"
+#include "version.hpp"
#include <getopt.h>
-#include <climits>
-#include <cstdio>
-#include <cstdlib>
-
-// Global logger configuration instance
-Config loggerConfig = {.path = LOG_OUTPUT_PATH,
- .storageSizeLimit = LOG_STORAGE_SIZE_LIMIT,
- .storageTimeLimit = LOG_STORAGE_TIME_LIMIT,
- .flushPeriod = LOG_FLUSH_PERIOD,
- .rotationLimit = LOG_ROTATION_LIMIT};
-
-/** @brief Print title with version info. */
-static void printTitle()
+/** @brief Print version info. */
+static void printVersion()
{
- printf("Host logger service " PACKAGE_VERSION ".\n");
+ puts("Host logger service rev." HOSTLOGGER_VERSION ".");
}
-/** @brief Print help usage info.
+/**
+ * @brief Print help usage info.
*
- * @param[in] app - application's file name
+ * @param[in] app application's file name
*/
static void printHelp(const char* app)
{
- printTitle();
- printf("Copyright (c) 2018 YADRO.\n");
- printf("Usage: %s [options]\n", app);
- printf(
- "Options (defaults are specified in brackets):\n"
- " -p, --path=PATH Path used to store logs [%s]\n"
- "Intermediate storage buffer capacity setup:\n"
- " -s, --szlimit=N Store up to N last messages [%i], 0=unlimited\n"
- " -t, --tmlimit=N Store messages for last N hours [%i], "
- "0=unlimited\n"
- "Flush storage buffer policy:\n"
- " -f, --flush=N Flush logs every N hours [%i]\n"
- " If this option is set to 0 flush will be called "
- "at\n"
- " every host state change event from D-Bus.\n"
- "Log files rotation policy:\n"
- " -r, --rotate=N Store up to N files in the log directory [%i],\n"
- " 0=unlimited\n"
- "Common options:\n"
- " -v, --version Print version and exit\n"
- " -h, --help Print this help and exit\n",
- loggerConfig.path, loggerConfig.storageSizeLimit,
- loggerConfig.storageTimeLimit, loggerConfig.flushPeriod,
- loggerConfig.rotationLimit);
-}
-
-/** @brief Get numeric positive value from string argument.
- *
- * @param[in] param - parameter name
- * @param[in] arg - parameter text value
- *
- * @return positive numeric value from string argument or -1 on errors
- */
-static int getNumericArg(const char* param, const char* arg)
-{
- char* ep = nullptr;
- const unsigned long val = strtoul(arg, &ep, 0);
- if (val > INT_MAX || !ep || ep == arg || *ep != 0)
- {
- fprintf(stderr, "Invalid %s param: %s, expected 0<=N<=%i\n", param, arg,
- INT_MAX);
- return -1;
- }
- return static_cast<int>(val);
+ printVersion();
+ puts("Copyright (c) 2020 YADRO.");
+ printf("Usage: %s [OPTION...]\n", app);
+ puts(" -v, --version Print version and exit");
+ puts(" -h, --help Print this help and exit");
}
/** @brief Application entry point. */
int main(int argc, char* argv[])
{
- int opt_val;
// clang-format off
- const struct option opts[] = {
- { "path", required_argument, 0, 'p' },
- { "szlimit", required_argument, 0, 's' },
- { "tmlimit", required_argument, 0, 't' },
- { "flush", required_argument, 0, 'f' },
- { "rotate", required_argument, 0, 'r' },
- { "version", no_argument, 0, 'v' },
- { "help", no_argument, 0, 'h' },
- { 0, 0, 0, 0 }
+ const struct option longOpts[] = {
+ { "version", no_argument, nullptr, 'v' },
+ { "help", no_argument, nullptr, 'h' },
+ { nullptr, 0, nullptr, 0 }
};
// clang-format on
-
- opterr = 0;
- while ((opt_val = getopt_long(argc, argv, "p:s:t:f:r:vh", opts, NULL)) !=
- -1)
+ const char* shortOpts = "vh";
+ opterr = 0; // prevent native error messages
+ int val;
+ while ((val = getopt_long(argc, argv, shortOpts, longOpts, nullptr)) != -1)
{
- switch (opt_val)
+ switch (val)
{
- case 'p':
- loggerConfig.path = optarg;
- if (*loggerConfig.path != '/')
- {
- fprintf(stderr,
- "Invalid directory: %s, expected absolute path\n",
- loggerConfig.path);
- return EXIT_FAILURE;
- }
- break;
- case 's':
- loggerConfig.storageSizeLimit =
- getNumericArg(opts[optind - 1].name, optarg);
- if (loggerConfig.storageSizeLimit < 0)
- return EXIT_FAILURE;
- break;
- case 't':
- loggerConfig.storageTimeLimit =
- getNumericArg(opts[optind - 1].name, optarg);
- if (loggerConfig.storageTimeLimit < 0)
- return EXIT_FAILURE;
- break;
- case 'f':
- loggerConfig.flushPeriod =
- getNumericArg(opts[optind - 1].name, optarg);
- if (loggerConfig.flushPeriod < 0)
- return EXIT_FAILURE;
- break;
- case 'r':
- loggerConfig.rotationLimit =
- getNumericArg(opts[optind - 1].name, optarg);
- if (loggerConfig.rotationLimit < 0)
- return EXIT_FAILURE;
- break;
case 'v':
- printTitle();
+ printVersion();
return EXIT_SUCCESS;
case 'h':
printHelp(argv[0]);
return EXIT_SUCCESS;
default:
- fprintf(stderr, "Invalid option: %s\n", argv[optind - 1]);
+ fprintf(stderr, "Invalid argument: %s\n", argv[optind - 1]);
return EXIT_FAILURE;
}
}
-
- int rc;
-
- // Initialize log manager
- LogManager logManager;
- rc = logManager.openHostLog();
- if (rc != 0)
- return rc;
-
- // Initialize D-Bus server
- sdbusplus::bus::bus bus = sdbusplus::bus::new_default();
- sd_event* event = nullptr;
- rc = sd_event_default(&event);
- if (rc < 0)
+ if (optind < argc)
{
- fprintf(stderr, "Error occurred during the sd_event_default: %i\n", rc);
+ fprintf(stderr, "Unexpected argument: %s\n", argv[optind - 1]);
return EXIT_FAILURE;
}
- EventPtr eventPtr(event);
- bus.attach_event(eventPtr.get(), SD_EVENT_PRIORITY_NORMAL);
- DbusServer dbusMgr(logManager, bus);
- bus.request_name(HOSTLOGGER_DBUS_IFACE);
-
- // Initialize D-Bus watcher
- DbusWatcher dbusWatch(logManager, bus);
- rc = dbusWatch.initialize();
- if (rc < 0)
+ try
+ {
+ Config cfg;
+ Service svc(cfg);
+ svc.run();
+ }
+ catch (const std::exception& ex)
+ {
+ fprintf(stderr, "%s\n", ex.what());
return EXIT_FAILURE;
+ }
- // D-Bus event processing
- rc = sd_event_loop(eventPtr.get());
- if (rc != 0)
- fprintf(stderr, "Error occurred during the sd_event_loop: %i\n", rc);
-
- return rc ? rc : -1; // Allways retrun an error code
+ return EXIT_SUCCESS;
}