summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDeepak Kodihalli <dkodihal@in.ibm.com>2018-08-23 02:19:58 -0500
committerDeepak Kodihalli <dkodihal@in.ibm.com>2018-08-29 03:38:49 -0500
commitc49661925b0c59a4355aca6813a85d749c21e764 (patch)
tree65d4ecebf593f3d77cd428bf3397f7d99f762006
parent9067c077034cd92e0498646b7d7a05fba890532c (diff)
downloadphosphor-logging-c49661925b0c59a4355aca6813a85d749c21e764.zip
phosphor-logging-c49661925b0c59a4355aca6813a85d749c21e764.tar.gz
Add application to configure rsyslog
The application implements the xyz.openbmc_project.Network.Client D-Bus interface to set a remote rsyslog server's address and port in the rsyslog config file. This lets us configure rsyslog to be able to stream out logs. TODO: Exception handling and validation will be handled in subsequent commits. Change-Id: I8917daab3f0de1806d2f1aafe99cb3a872f19184 Signed-off-by: Deepak Kodihalli <dkodihal@in.ibm.com>
-rw-r--r--Makefile.am2
-rw-r--r--README.md53
-rw-r--r--configure.ac30
-rw-r--r--log_manager.cpp4
-rw-r--r--phosphor-rsyslog-config/Makefile.am20
-rw-r--r--phosphor-rsyslog-config/main.cpp23
-rw-r--r--phosphor-rsyslog-config/server-conf.cpp42
-rw-r--r--phosphor-rsyslog-config/server-conf.hpp76
-rw-r--r--phosphor-rsyslog-config/utils.hpp26
9 files changed, 270 insertions, 6 deletions
diff --git a/Makefile.am b/Makefile.am
index 4035edc..1b13af7 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -108,7 +108,7 @@ callouts-gen.hpp: $(REQ_FILES_TO_GEN)
pkgconfiglibdir = ${libdir}/pkgconfig
pkgconfiglib_DATA = phosphor-logging.pc
-SUBDIRS = test
+SUBDIRS = test phosphor-rsyslog-config
endif
# Export elog-gen parser and mako script
elogdir = ${datadir}/phosphor-logging/elog
diff --git a/README.md b/README.md
index 1d5fe13..e0ea54a 100644
--- a/README.md
+++ b/README.md
@@ -13,6 +13,59 @@ To build this package, do the following steps:
To clean the repository run `./bootstrap.sh clean`.
```
+## Remote Logging via Rsyslog
+The BMC has the ability to stream out local logs (that go to the systemd journal)
+via rsyslog (https://www.rsyslog.com/).
+
+The BMC will send everything. Any kind of filtering and appropriate storage
+will have to be managed on the rsyslog server. Various examples are available
+on the internet. Here are few pointers :
+https://www.rsyslog.com/storing-and-forwarding-remote-messages/
+https://www.rsyslog.com/doc/rsyslog%255Fconf%255Ffilter.html
+https://www.thegeekdiary.com/understanding-rsyslog-filter-options/
+
+#### Configuring rsyslog server for remote logging
+The BMC is an rsyslog client. To stream out logs, it needs to talk to an rsyslog
+server, to which there's connectivity over a network. REST API can be used to
+set the remote server's IP address and port number.
+
+The following presumes a user has logged on to the BMC (see
+https://github.com/openbmc/docs/blob/master/rest-api.md).
+
+Set the IP:
+```
+curl -b cjar -k -H "Content-Type: application/json" -X PUT \
+ -d '{"data": <IP address>}' \
+ https://<BMC IP address>/xyz/openbmc_project/logging/config/remote/attr/Address
+```
+
+Set the port:
+```
+curl -b cjar -k -H "Content-Type: application/json" -X PUT \
+ -d '{"data": <port number>}' \
+ https://<BMC IP address>/xyz/openbmc_project/logging/config/remote/attr/Port
+```
+
+#### Querying the current configuration
+```
+curl -b cjar -k \
+ https://<BMC IP address>/xyz/openbmc_project/logging/config/remote
+```
+
+#### Setting the hostname
+Rsyslog can store logs separately for each host. For this reason, it's useful to
+provide a unique hostname to each managed BMC. Here's how that can be done via a
+REST API :
+```
+curl -b cjar -k -H "Content-Type: application/json" -X PUT \
+ -d '{"data": "myHostName"}' \
+ https://<BMC IP address>//xyz/openbmc_project/network/config/attr/HostName
+```
+
+#### Changing the rsyslog server
+When switching to a new server from an existing one (i.e the address, or port,
+or both change), it is recommended to disable the existing configuration first.
+
## Adding application specific error YAML
* This document captures steps for adding application specific error YAML files
and generating local elog-errors.hpp header file for application use.
diff --git a/configure.ac b/configure.ac
index 3ae2407..ce9b8bb 100644
--- a/configure.ac
+++ b/configure.ac
@@ -118,7 +118,35 @@ AC_ARG_VAR(CLASS_VERSION, [Class version to register with Cereal])
AS_IF([test "x$CLASS_VERSION" == "x"], [CLASS_VERSION=2])
AC_DEFINE_UNQUOTED([CLASS_VERSION], [$CLASS_VERSION], [Class version to register with Cereal])
+AC_ARG_VAR(RSYSLOG_SERVER_CONFIG_FILE, \
+ [Path of config file containing server address])
+AS_IF([test "x$RSYSLOG_SERVER_CONFIG_FILE" == "x"], \
+ [RSYSLOG_SERVER_CONFIG_FILE="/etc/rsyslog.d/server.conf"])
+AC_DEFINE_UNQUOTED([RSYSLOG_SERVER_CONFIG_FILE], \
+ ["$RSYSLOG_SERVER_CONFIG_FILE"], \
+ [Path of config file containing server address])
+
+AC_ARG_VAR(BUSNAME_SYSLOG_CONFIG, \
+ [D-Bus busname of syslog config service])
+AS_IF([test "x$BUSNAME_SYSLOG_CONFIG" == "x"], \
+ [BUSNAME_SYSLOG_CONFIG="xyz.openbmc_project.Syslog.Config"])
+AC_DEFINE_UNQUOTED([BUSNAME_SYSLOG_CONFIG], \
+ ["$BUSNAME_SYSLOG_CONFIG"], \
+ [D-Bus busname of syslog config service])
+
+AC_ARG_VAR(BUSPATH_REMOTE_LOGGING_CONFIG, \
+ [D-Bus path of remote logging config object])
+AS_IF([test "x$BUSPATH_REMOTE_LOGGING_CONFIG" == "x"], \
+ [BUSPATH_REMOTE_LOGGING_CONFIG="/xyz/openbmc_project/logging/config/remote"])
+AC_DEFINE_UNQUOTED([BUSPATH_REMOTE_LOGGING_CONFIG], \
+ ["$BUSPATH_REMOTE_LOGGING_CONFIG"], \
+ [D-Bus path of remote logging config object])
+
+AC_DEFINE(SYSTEMD_BUSNAME, "org.freedesktop.systemd1", [systemd busname.])
+AC_DEFINE(SYSTEMD_PATH, "/org/freedesktop/systemd1", [systemd path.])
+AC_DEFINE(SYSTEMD_INTERFACE, "org.freedesktop.systemd1.Manager", [systemd interface.])
+
AC_CONFIG_HEADERS([config.h])
-AC_CONFIG_FILES([Makefile test/Makefile])
+AC_CONFIG_FILES([Makefile test/Makefile phosphor-rsyslog-config/Makefile])
AC_CONFIG_FILES([phosphor-logging.pc])
AC_OUTPUT
diff --git a/log_manager.cpp b/log_manager.cpp
index cbbf9a8..ad1c5d1 100644
--- a/log_manager.cpp
+++ b/log_manager.cpp
@@ -371,10 +371,6 @@ void Manager::journalSync()
{
syncRequested = true;
- constexpr auto SYSTEMD_BUSNAME = "org.freedesktop.systemd1";
- constexpr auto SYSTEMD_PATH = "/org/freedesktop/systemd1";
- constexpr auto SYSTEMD_INTERFACE =
- "org.freedesktop.systemd1.Manager";
constexpr auto JOURNAL_UNIT = "systemd-journald.service";
auto signal = SIGRTMIN + 1;
diff --git a/phosphor-rsyslog-config/Makefile.am b/phosphor-rsyslog-config/Makefile.am
new file mode 100644
index 0000000..f695946
--- /dev/null
+++ b/phosphor-rsyslog-config/Makefile.am
@@ -0,0 +1,20 @@
+noinst_HEADERS = \
+ utils.hpp \
+ server-conf.hpp
+
+sbin_PROGRAMS = phosphor-rsyslog-conf
+
+phosphor_rsyslog_conf_SOURCES = \
+ main.cpp \
+ server-conf.cpp
+
+phosphor_rsyslog_conf_LDFLAGS = \
+ $(SDBUSPLUS_LIBS) \
+ $(PHOSPHOR_LOGGING_LIBS) \
+ $(PHOSPHOR_DBUS_INTERFACES_LIBS)
+
+phosphor_rsyslog_conf_CXXFLAGS = \
+ $(SDBUSPLUS_CFLAGS) \
+ $(PHOSPHOR_LOGGING_CFLAGS) \
+ $(PHOSPHOR_DBUS_INTERFACES_CFLAGS) \
+ -flto
diff --git a/phosphor-rsyslog-config/main.cpp b/phosphor-rsyslog-config/main.cpp
new file mode 100644
index 0000000..3e4d928
--- /dev/null
+++ b/phosphor-rsyslog-config/main.cpp
@@ -0,0 +1,23 @@
+#include "config.h"
+#include "server-conf.hpp"
+#include <sdbusplus/bus.hpp>
+
+int main(int argc, char *argv[])
+{
+ auto bus = sdbusplus::bus::new_default();
+
+ phosphor::rsyslog_config::Server
+ serverConf(bus,
+ BUSPATH_REMOTE_LOGGING_CONFIG,
+ RSYSLOG_SERVER_CONFIG_FILE);
+
+ bus.request_name(BUSNAME_SYSLOG_CONFIG);
+
+ while(true)
+ {
+ bus.process_discard();
+ bus.wait();
+ }
+
+ return 0;
+}
diff --git a/phosphor-rsyslog-config/server-conf.cpp b/phosphor-rsyslog-config/server-conf.cpp
new file mode 100644
index 0000000..16c792d
--- /dev/null
+++ b/phosphor-rsyslog-config/server-conf.cpp
@@ -0,0 +1,42 @@
+#include "server-conf.hpp"
+#include "utils.hpp"
+#include <fstream>
+
+namespace phosphor
+{
+namespace rsyslog_config
+{
+
+namespace utils = phosphor::rsyslog_utils;
+
+std::string Server::address(std::string value)
+{
+ writeConfig(value, port(), configFilePath.c_str());
+ auto result = NetworkClient::address(value);
+ return result;
+}
+
+uint16_t Server::port(uint16_t value)
+{
+ writeConfig(address(), value, configFilePath.c_str());
+ auto result = NetworkClient::port(value);
+ return result;
+}
+
+void Server::writeConfig(
+ const std::string& serverAddress,
+ uint16_t serverPort,
+ const char* filePath)
+{
+ if (serverPort && !serverAddress.empty())
+ {
+ std::fstream stream(filePath, std::fstream::out);
+ // write '*.* @@remote-host:port'
+ stream << "*.* @@" << serverAddress << ":" << serverPort;
+
+ utils::restart();
+ }
+}
+
+} // namespace rsyslog_config
+} // namespace phosphor
diff --git a/phosphor-rsyslog-config/server-conf.hpp b/phosphor-rsyslog-config/server-conf.hpp
new file mode 100644
index 0000000..cb8882b
--- /dev/null
+++ b/phosphor-rsyslog-config/server-conf.hpp
@@ -0,0 +1,76 @@
+#pragma once
+
+#include <sdbusplus/bus.hpp>
+#include <sdbusplus/server/object.hpp>
+#include <string>
+#include "xyz/openbmc_project/Network/Client/server.hpp"
+
+namespace phosphor
+{
+namespace rsyslog_config
+{
+
+using NetworkClient = sdbusplus::xyz::openbmc_project::Network::server::Client;
+using Iface = sdbusplus::server::object::object<NetworkClient>;
+
+/** @class Server
+ * @brief Configuration for rsyslog server
+ * @details A concrete implementation of the
+ * xyz.openbmc_project.Network.Client API, in order to
+ * provide remote rsyslog server's address and port.
+ */
+class Server : public Iface
+{
+ public:
+ Server() = delete;
+ Server(const Server&) = delete;
+ Server& operator=(const Server&) = delete;
+ Server(Server&&) = delete;
+ Server& operator=(Server&&) = delete;
+ virtual ~Server() = default;
+
+ /** @brief Constructor to put object onto bus at a dbus path.
+ * @param[in] bus - Bus to attach to.
+ * @param[in] path - Path to attach at.
+ * @param[in] filePath - rsyslog remote logging config file
+ */
+ Server(sdbusplus::bus::bus& bus,
+ const std::string& path,
+ const char* filePath) :
+ Iface(bus, path.c_str()),
+ configFilePath(filePath)
+ {
+ }
+
+ using NetworkClient::address;
+ using NetworkClient::port;
+
+ /** @brief Override that updates rsyslog config file as well
+ * @param[in] value - remote server address
+ * @returns value of changed address
+ */
+ virtual std::string address(std::string value) override;
+
+ /** @brief Override that updates rsyslog config file as well
+ * @param[in] value - remote server port
+ * @returns value of changed port
+ */
+ virtual uint16_t port(uint16_t value) override;
+
+ private:
+ /** @brief Update remote server address and port in
+ * rsyslog config file.
+ * @param[in] serverAddress - remote server address
+ * @param[in] serverPort - remote server port
+ * @param[in] filePath - rsyslog config file path
+ */
+ void writeConfig(
+ const std::string& serverAddress,
+ uint16_t serverPort,
+ const char* filePath);
+
+ std::string configFilePath{};
+};
+
+} // namespace rsyslog_config
+} // namespace phosphor
diff --git a/phosphor-rsyslog-config/utils.hpp b/phosphor-rsyslog-config/utils.hpp
new file mode 100644
index 0000000..ea7984d
--- /dev/null
+++ b/phosphor-rsyslog-config/utils.hpp
@@ -0,0 +1,26 @@
+#pragma once
+
+#include "config.h"
+#include <sdbusplus/bus.hpp>
+
+namespace phosphor
+{
+namespace rsyslog_utils
+{
+
+/** @brief Restart rsyslog's systemd unit
+ */
+void restart()
+{
+ auto bus = sdbusplus::bus::new_default();
+ auto method = bus.new_method_call(
+ SYSTEMD_BUSNAME,
+ SYSTEMD_PATH,
+ SYSTEMD_INTERFACE,
+ "RestartUnit");
+ method.append("rsyslog.service", "replace");
+ bus.call_noreply(method);
+}
+
+} // namespace rsyslog_utils
+} // namespace phosphor
OpenPOWER on IntegriCloud