summaryrefslogtreecommitdiffstats
path: root/README.md
diff options
context:
space:
mode:
Diffstat (limited to 'README.md')
-rw-r--r--README.md322
1 files changed, 320 insertions, 2 deletions
diff --git a/README.md b/README.md
index f8ab729..bb5c649 100644
--- a/README.md
+++ b/README.md
@@ -1,6 +1,13 @@
# phosphor-logging
-phosphor logging provides mechanism for common event and logging creation based
-on information from the journal log.
+The phosphor logging repository provides mechanisms for event and journal
+logging.
+
+## Table Of Contents
+* [Building](#to-build)
+* [Remote Logging](#remote-logging-via-rsyslog)
+* [Event Logs](#event-logs)
+* [Application Specific Error YAML](#adding-application-specific-error-yaml)
+* [Event Log Extensions](#event-log-extensions)
## To Build
```
@@ -70,6 +77,212 @@ 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.
+## Event Logs
+OpenBMC event logs are a collection of D-Bus interfaces owned by
+phosphor-log-manager that reside at `/xyz/openbmc_project/logging/entry/X`,
+where X starts at 1 and is incremented for each new log.
+
+The interfaces are:
+* [xyz.openbmc_project.Logging.Entry]
+ * The main event log interface.
+* [xyz.openbmc_project.Association.Definitions]
+ * Used for specifying inventory items as the cause of the event.
+ * For more information on associations, see [here][associations-doc].
+* [xyz.openbmc_project.Object.Delete]
+ * Provides a Delete method to delete the event.
+* [xyz.openbmc_project.Software.Version]
+ * Stores the code version that the error occurred on.
+
+On platforms that make use of these event logs, the intent is that they are
+the common event log representation that other types of event logs can be
+created from. For example, there is code to convert these into both Redfish
+and IPMI event logs, in addition to the event log extensions mentioned
+[below](#event-log-extensions).
+
+The logging daemon has the ability to add `callout` associations to an event
+log based on text in the AdditionalData property. A callout is a link to the
+inventory item(s) that were the cause of the event log. See [here][callout-doc]
+for details.
+
+### Creating Event Logs In Code
+There are two approaches to creating event logs in OpenBMC code. The first
+makes use of the systemd journal to store metadata needed for the log, and the
+second is a plain D-Bus method call.
+
+#### Journal Based Event Log Creation
+Event logs can be created by using phosphor-logging APIs to commit sdbusplus
+exceptions. These APIs write to the journal, and then call a `Commit`
+D-Bus method on the logging daemon to create the event log using the information
+it put in the journal.
+
+The APIs are found in `<phosphor-logging/elog.hpp>`:
+* `elog()`: Throw an sdbusplus error.
+* `commit()`: Catch an error thrown by elog(), and commit it to create the
+ event log.
+* `report()`: Create an event log from an sdbusplus error without throwing the
+ exception first.
+
+Any errors passed into these APIs must be known to phosphor-logging, usually
+by being defined in `<phosphor-logging/elog-errors.hpp>`. The errors must
+also be known by sdbusplus, and be defined in their corresponding error.hpp.
+See below for details on how get errors into these headers.
+
+Example:
+```
+#include <phosphor-logging/elog-errors.hpp>
+#include <phosphor-logging/elog.hpp>
+#include <xyz/openbmc_project/Common/error.hpp>
+...
+using InternalFailure =
+ sdbusplus::xyz::openbmc_project::Common::Error::InternalFailure;
+...
+if (somethingBadHappened)
+{
+ phosphor::logging::report<InternalFailure>();
+}
+
+```
+Alternatively, to throw, catch, and then commit the error:
+```
+try
+{
+ phosphor::logging::elog<InternalFailure>();
+}
+catch (InternalFailure& e)
+{
+ phosphor::logging::commit<InternalFailure>();
+}
+```
+
+Metadata can be added to event logs to add debug data captured at the time of
+the event. It shows up in the AdditionalData property in the
+`xyz.openbmc_project.Logging.Entry` interface. Metadata is passed in via the
+`elog()` or `report()` functions, which write it to the journal. The metadata
+must be predefined for the error in the [metadata YAML](#event-log-definition)
+so that the daemon knows to look for it in the journal when it creates the
+event log.
+
+Example:
+```
+#include <phosphor-logging/elog-errors.hpp>
+#include <phosphor-logging/elog.hpp>
+#include <xyz/openbmc_project/Control/Device/error.hpp>
+...
+using WriteFailure =
+ sdbusplus::xyz::openbmc_project::Control::Device::Error::WriteFailure;
+using metadata =
+ xyz::openbmc_project::Control::Device::WriteFailure;
+...
+if (somethingBadHappened)
+{
+ phosphor::logging::report<WriteFailure>(metadata::CALLOUT_ERRNO(5),
+ metadata::CALLOUT_DEVICE_PATH("some path"));
+}
+```
+In the above example, the AdditionalData property would look like:
+```
+["CALLOUT_ERRNO=5", "CALLOUT_DEVICE_PATH=some path"]
+```
+Note that the metadata fields must be all uppercase.
+
+##### Event Log Definition
+As mentioned above, both sdbusplus and phosphor-logging must know about the
+event logs in their header files, or the code that uses them will not even
+compile. The standard way to do this to define the event in the appropriate
+`<error-category>.errors.yaml` file, and define any metadata in the
+`<error-category>.metadata.yaml` file in the appropriate `*-dbus-interfaces`
+repository. During the build, phosphor-logging generates the elog-errors.hpp
+file for use by the calling code.
+
+In much the same way, sdbusplus uses the event log definitions to generate an
+error.hpp file that contains the specific exception. The path of the error.hpp
+matches the path of the YAML file.
+
+For example, if in phosphor-dbus-interfaces there is
+`xyz/openbmc_project/Control/Device.errors.yaml`, the errors that come from
+that file will be in the include:
+`xyz/openbmc_project/Control/Device/error.hpp`.
+
+In rare cases, one may want one to define their errors in the same repository
+that uses them. To do that, one must:
+
+1. Add the error and metadata YAML files to the repository.
+2. Run the sdbus++ script within the makefile to create the error.hpp and .cpp
+ files from the local YAML, and include the error.cpp file in the application
+ that uses it. See [openpower-occ-control] for an example.
+3. Tell phosphor-logging about the error. This is done by either:
+ * Following the [directions](#adding-application-specific-error-yaml)
+ defined in this README, or
+ * Running the script yourself:
+ 1. Run phosphor-logging\'s `elog-gen.py` script on the local yaml to
+ generate an elog-errors.hpp file that just contains the local errors,
+ and check that into the repository and include it where the errors are
+ needed.
+ 2. Create a recipe that copies the local YAML files to a place that
+ phosphor-logging can find it during the build. See [here][led-link]
+ for an example.
+
+#### D-Bus Event Log Creation
+There is also a [D-Bus method][log-create-link] to create event logs:
+* Service: xyz.openbmc_project.Logging
+* Object Path: /xyz/openbmc_project/logging
+* Interface: xyz.openbmc_project.Logging.Create
+* Method: Create
+ * Method Arguments:
+ * Message: The `Message` string property for the
+ `xyz.openbmc_project.Logging.Entry` interface.
+ * Severity: The `severity` property for the
+ `xyz.openbmc_project.Logging.Entry` interface.
+ An `xyz.openbmc_project.Logging.Entry.Level` enum value.
+ * AdditionalData: The `AdditionalData` property for the
+ `xyz.openbmc_project.Logging.Entry` interface, but in a map
+ instead of in a vector of "KEY=VALUE" strings.
+ Example:
+```
+ std::map<std::string, std::string> additionalData;
+ additionalData["KEY"] = "VALUE";
+```
+
+
+Unlike the previous APIs where errors could also act as exceptions that could
+be thrown across D-Bus, this API does not require that the error be defined in
+the error YAML in the D-Bus interfaces repository so that sdbusplus knows about
+it. Additionally, as this method passes in everything needed to create the
+event log, the logging daemon doesn't have to know about it ahead of time
+either.
+
+That being said, it is recommended that users of this API still follow some
+guidelines for the message field, which is normally generated from a
+combination of the path to the error YAML file and the error name itself. For
+example, the `Timeout` error in `xyz/openbmc_project/Common.errors.yaml` will
+have a Message property of `xyz.openbmc_project.Common.Error.Timeout`.
+
+The guidelines are:
+1. When it makes sense, one can still use an existing error that has already
+ been defined in an error YAML file, and use the same severity and metadata
+ (AdditionalData) as in the corresponding metadata YAML file.
+
+2. If creating a new error, use the same naming scheme as other errors, which
+ starts with the domain, `xyz.openbmc_project`, `org.open_power`, etc,
+ followed by the capitalized category values, followed by `Error`, followed
+ by the capitalized error name itself, with everything separated by "."s.
+ For example: `xyz.openbmc_project.Some.Category.Error.Name`.
+
+3. If creating a new common error, still add it to the appropriate error and
+ metadata YAML files in the appropriate D-Bus interfaces repository so that
+ others can know about it and use it in the future. This can be done after
+ the fact.
+
+[xyz.openbmc_project.Logging.Entry]: https://github.com/openbmc/phosphor-dbus-interfaces/blob/master/xyz/openbmc_project/Logging/Entry.interface.yaml
+[xyz.openbmc_project.Association.Definitions]: https://github.com/openbmc/phosphor-dbus-interfaces/blob/master/xyz/openbmc_project/Association/Definitions.interface.yaml
+[associations-doc]: https://github.com/openbmc/docs/blob/master/architecture/object-mapper.md#associations
+[callout-doc]: https://github.com/openbmc/phosphor-dbus-interfaces/blob/master/xyz/openbmc_project/Common/Callout/README.md
+[xyz.openbmc_project.Object.Delete]: https://github.com/openbmc/phosphor-dbus-interfaces/blob/master/xyz/openbmc_project/Object/Delete.interface.yaml
+[xyz.openbmc_project.Software.Version]: https://github.com/openbmc/phosphor-dbus-interfaces/blob/master/xyz/openbmc_project/Software/Version.errors.yaml
+[elog-errors.hpp]: https://github.com/openbmc/phosphor-logging/blob/master/phosphor-logging/elog.hpp
+[openpower-occ-control]: https://github.com/openbmc/openpower-occ-control
+[led-link]: https://github.com/openbmc/openbmc/tree/master/meta-phosphor/recipes-phosphor/leds
+[log-create-link]: https://github.com/openbmc/phosphor-dbus-interfaces/blob/master/xyz/openbmc_project/Logging/Create.interface.yaml
## Adding application specific error YAML
* This document captures steps for adding application specific error YAML files
@@ -244,3 +457,108 @@ PACKAGECONFIG_remove_class-target = "install_error_yaml"
**Reference**
* https://github.com/openbmc/openpower-debug-collector/blob/master/README.md
+
+## Event Log Extensions
+
+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.
+* On startup
+ * Function type void(internal::Manager&)
+* After an event log is created
+ * Function type void(args)
+ * The args are:
+ * const std::string& - The Message property
+ * uin32_t - The event log ID
+ * uint64_t - The event log timestamp
+ * Level - The event level
+ * const AdditionalDataArg& - the additional data
+ * const AssociationEndpointsArg& - Association endpoints (callouts)
+* Before an event log is deleted, to check if it is allowed.
+ * Function type void(std::uint32_t, bool&) that takes the event ID
+* After an event log is deleted
+ * Function type void(std::uint32_t) that takes the event ID
+
+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.
+
+### Motivation
+
+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:
+* Allowing for custom old log retention algorithms.
+* Prohibiting manual deleting of certain logs based on an extension's
+ requirements.
+
+### Creating extensions
+
+1. Add a new flag to configure.ac to enable the extension:
+```
+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"])
+```
+2. Add the code in `extensions/<extension>/`.
+3. Create a makefile include to add the new code to phosphor-log-manager:
+```
+phosphor_log_manager_SOURCES += \
+ extensions/foo/foo.cpp
+```
+3. In `extensions/extensions.mk`, add the makefile include:
+```
+if ENABLE_FOO_EXTENSION
+include extensions/foo/foo.mk
+endif
+```
+4. In the extension code, register the functions to call and optionally disable
+ log capping using the provided macros:
+```
+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);
+```
+### Extension List
+
+The supported extensions are:
+
+* OpenPower PELs
+ * Enabled with --enable-openpower-pel-extension
+ * Detailed information can be found
+ [here](extensions/openpower-pels/README.md)
OpenPOWER on IntegriCloud