phosphor logging provides mechanism for common event and logging creation based on information from the journal log.
To build this package, do the following steps: 1. ./bootstrap.sh 2. ./configure ${CONFIGURE_FLAGS} 3. make To clean the repository run `./bootstrap.sh clean`.
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/
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
curl -b cjar -k \ https://<BMC IP address>/xyz/openbmc_project/logging/config/remote
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
Remote logging can be disabled by writing 0 to the port, or an empty string("") to the IP.
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.
Reference
Modify Makefile.am to export newly added error YAML to shared location
yamldir = ${datadir}/phosphor-dbus-yaml/yaml nobase_yaml_DATA = \ org/open_power/Host.errors.yaml
# Generate phosphor-logging/elog-errors.hpp if GEN_ERRORS ELOG_MAKO ?= elog-gen-template.mako.hpp ELOG_DIR ?= ${OECORE_NATIVE_SYSROOT}${datadir}/phosphor-logging/elog ELOG_GEN_DIR ?= ${ELOG_DIR}/tools/ ELOG_MAKO_DIR ?= ${ELOG_DIR}/tools/phosphor-logging/templates/ YAML_DIR ?= ${OECORE_NATIVE_SYSROOT}${datadir}/phosphor-dbus-yaml/yaml phosphor-logging/elog-errors.hpp: @mkdir -p ${YAML_DIR}/org/open_power/ @cp ${top_srcdir}/org/open_power/Host.errors.yaml \ ${YAML_DIR}/org/open_power/Host.errors.yaml @mkdir -p `dirname $@` @chmod 777 $(ELOG_GEN_DIR)/elog-gen.py $(AM_V_at)$(PYTHON) $(ELOG_GEN_DIR)/elog-gen.py -y ${YAML_DIR} \ -t ${ELOG_MAKO_DIR} -m ${ELOG_MAKO} -o $@ endif
if GEN_ERRORS nobase_nodist_include_HEADERS += \ phosphor-logging/elog-errors.hpp endif if GEN_ERRORS BUILT_SOURCES += phosphor-logging/elog-errors.hpp endif
if !INSTALL_ERROR_YAML endif
Reference
Install error yaml option(argument) is enabled for native recipe build and disabled for bitbake build.
When install error yaml option is disabled do not check for target specific packages in autotools configure script.
AC_ARG_ENABLE([install_error_yaml], AS_HELP_STRING([--enable-install_error_yaml], [Enable installing error yaml file]),[], [install_error_yaml=no]) AM_CONDITIONAL([INSTALL_ERROR_YAML], [test "x$enable_install_error_yaml" = "xyes"]) AS_IF([test "x$enable_install_error_yaml" != "xyes"], [ .. .. ])
AC_ARG_ENABLE([gen_errors], AS_HELP_STRING([--enable-gen_errors], [Enable elog-errors.hpp generation ]), [],[gen_errors=yes]) AM_CONDITIONAL([GEN_ERRORS], [test "x$enable_gen_errors" != "xno"])
Reference
BBCLASSEXTEND += "native nativesdk"
DEPENDS_remove_class-native = "phosphor-logging"
DEPENDS_remove_class-nativesdk = "phosphor-logging"
PACKAGECONFIG ??= "install_error_yaml" PACKAGECONFIG[install_error_yaml] = " \ --enable-install_error_yaml, \ --disable-install_error_yaml, ,\ "
PACKAGECONFIG_add_class-native = "install_error_yaml" PACKAGECONFIG_add_class-nativesdk = "install_error_yaml"
PACKAGECONFIG_remove_class-target = "install_error_yaml"
XTRA_OECONF += "--disable-gen_errors"
The extension concept is a way to allow code that creates other formats of error logs besides phosphor-logging's event logs to still reside in the phosphor-log-manager application.
The extension code lives in the extensions/<extension>
subdirectories, and is enabled with a --enable-<extension>
configure flag. The extension code won't compile unless enabled with this flag.
Extensions can register themselves to have functions called at the following points using the REGISTER_EXTENSION_FUNCTION macro.
Using these callback points, they can create their own event log for each OpenBMC event log that is created, and delete these logs when the corresponding OpenBMC event log is deleted.
In addition, an extension has the option of disabling phosphor-logging's default error log capping policy so that it can use its own. The macro DISABLE_LOG_ENTRY_CAPS() is used for that.
The reason for adding support for extensions inside the phosphor-log-manager daemon as opposed to just creating new daemons that listen for D-Bus signals is to allow interactions that would be complicated or expensive if just done over D-Bus, such as:
AC_ARG_ENABLE([foo-extension], AS_HELP_STRING([--enable-foo-extension], [Create Foo logs])) AM_CONDITIONAL([ENABLE_FOO_EXTENSION], [test "x$enable_foo_extension" == "xyes"])
extensions/<extension>/
.phosphor_log_manager_SOURCES += \ extensions/foo/foo.cpp
extensions/extensions.mk
, add the makefile include:if ENABLE_FOO_EXTENSION include extensions/foo/foo.mk endif
DISABLE_LOG_ENTRY_CAPS(); void fooStartup(internal::Manager& manager) { // Initialize } REGISTER_EXTENSION_FUNCTION(fooStartup); void fooCreate(const std::string& message, uint32_t id, uint64_t timestamp, Entry::Level severity, const AdditionalDataArg& additionalData, const AssociationEndpointsArg& assocs) { // Create a different type of error log based on 'entry'. } REGISTER_EXTENSION_FUNCTION(fooCreate); void fooRemove(uint32_t id) { // Delete the extension error log that corresponds to 'id'. } REGISTER_EXTENSION_FUNCTION(fooRemove);
Reference