Name Date Size #Lines LOC

..--

callouts/H--10175

config/H--7561

dist/H--8066

docs/H--311244

extensions/H--35,02222,834

gen/H--165134

lib/H--2,1701,418

phosphor-rsyslog-config/H--507372

subprojects/H--4936

test/H--15,91711,382

tools/H--872692

yaml/xyz/openbmc_project/Logging/Internal/H--5049

.clang-formatH A D01-Feb-20253.7 KiB137135

.gitignoreH A D30-Apr-202142 43

.lcovrcH A D05-Jun-202080 43

.shellcheckHD13-Apr-20210

LICENSEH A D20-Jul-201611.1 KiB202169

OWNERSH A D22-Jul-20221.8 KiB5752

README.mdH A D10-Jun-202518.6 KiB505389

config_main.hH A D30-Sep-2024108 53

elog_block.hppH A D16-Aug-20241.7 KiB6139

elog_entry.cppH A D09-May-20253.4 KiB133107

elog_entry.hppH A D09-May-20256.1 KiB17682

elog_meta.cppH A D21-Nov-20241.7 KiB6455

elog_meta.hppH A D21-Nov-20243 KiB10170

elog_serialize.cppH A D09-May-20256 KiB176141

elog_serialize.hppH A D09-May-20251.3 KiB4517

extensions.cppH A D03-Sep-20241 KiB4637

extensions.hppH A D22-Nov-20247.8 KiB25187

log_create_main.cppH A D22-Nov-20241.6 KiB7255

log_manager.cppH A D20-Mar-202520.9 KiB724589

log_manager.hppH A D22-Nov-202413.6 KiB405153

log_manager_main.cppH A D03-Oct-20241.5 KiB6041

log_resolve_main.cppH A D23-Jan-20251.1 KiB4538

logging_test.cppH A D17-Dec-20247.8 KiB263204

meson.buildH A D09-May-20255.4 KiB238217

meson.optionsH A D14-May-20251.2 KiB5750

paths.cppH A D30-Sep-2024340 1613

paths.hppH A D09-May-2025237 148

setup.cfgH A D16-Apr-202139 21

util.cppH A D09-May-20257.3 KiB240171

util.hppH A D09-May-20251.3 KiB4717

README.md

1# phosphor-logging
2
3The phosphor logging repository provides mechanisms for event and journal
4logging.
5
6## Table Of Contents
7
8- [Building](#to-build)
9- [Structured Logging](#structured-logging)
10- [Event Logs](#event-logs)
11- [Event Log Extensions](#event-log-extensions)
12- [Remote Logging](#remote-logging-via-rsyslog)
13- [Boot Fail on Hardware Errors](#boot-fail-on-hardware-errors)
14
15## To Build
16
17To build this package, do the following steps:
18
191. meson builddir
202. ninja -c builddir
21
22## Structured Logging
23
24phosphor-logging provides APIs to add program logging information to the
25systemd-journal and it is preferred that this logging data is formatted in a
26structured manner (using the facilities provided by the APIs).
27
28See [Structured Logging](./docs/structured-logging.md) for more details on this
29API.
30
31## Event Logs
32
33OpenBMC event logs are a collection of D-Bus interfaces owned by
34phosphor-log-manager that reside at `/xyz/openbmc_project/logging/entry/X`,
35where X starts at 1 and is incremented for each new log.
36
37The interfaces are:
38
39- [xyz.openbmc_project.Logging.Entry]
40  - The main event log interface.
41- [xyz.openbmc_project.Association.Definitions]
42  - Used for specifying inventory items as the cause of the event.
43  - For more information on associations, see the [associations
44    doc][associations-doc].
45- [xyz.openbmc_project.Object.Delete]
46  - Provides a Delete method to delete the event.
47- [xyz.openbmc_project.Software.Version]
48  - Stores the code version that the error occurred on.
49
50On platforms that make use of these event logs, the intent is that they are the
51common event log representation that other types of event logs can be created
52from. For example, there is code to convert these into both Redfish and IPMI
53event logs, in addition to the event log extensions mentioned
54[below](#event-log-extensions).
55
56The logging daemon has the ability to add `callout` associations to an event log
57based on text in the AdditionalData property. A callout is a link to the
58inventory item(s) that were the cause of the event log. See [callout
59doc][callout-doc] for details.
60
61### Creating Event Logs In Code
62
63The preferred method for creating event logs is specified in the project-level
64[event log design][event-log-design]. Events are defined using YAML in the
65phosphor-dbus-interfaces repository, such as the
66[Logging.Cleared][logging-cleared] event, which will generate a C++ class for
67the event. Then a call to `lg2::commit` is made on a constructed event to add it
68to the event log.
69
70```cpp
71lg2::commit(sdbusplus::event::xyz::openbmc_project::Logging::Cleared(
72    "NUMBER_OF_LOGS", count));
73```
74
75The above function will return the object path of the created log entry. This
76log-entry can be resolved with the helper `lg2::resolve` fuction.
77
78```cpp
79lg2::resolve(logPath);
80```
81
82### Event Log Filtering
83
84Vendors customizing phosphor-logging for their platforms may decide that they
85would like to prevent certain events from being added to the event log. This is
86especially true for informational / tracing events. The `lg2::commit` supports a
87compile-time event filtering mechanism that can accomplish this.
88
89The meson option `event-filter` can be used to specify a file containing
90filtering policy. When left unspecified, the [default
91policy][default-policy-json] of "allow all" is enabled. For both events and
92errors, a default policy of "allowed" or "blocked" can be specified and an
93additional set of events can be given for which the non-defaulted action should
94be taken. A JSON-Schema is available for the [policy
95JSON][filter-policy-schema].
96
97[default-policy-json]:
98  https://github.com/openbmc/phosphor-logging/blob/master/tools/phosphor-logging/default-eventfilter.json
99[filter-policy-schema]:
100  https://github.com/openbmc/phosphor-logging/blob/master/tools/phosphor-logging/schemas/eventfilter.schema.yaml
101
102### Deprecated Methods for Creating Event Logs
103
104There are two other, but now deprecated, methods to creating event logs in
105OpenBMC code. The first makes use of the systemd journal to store metadata
106needed for the log, and the second is a plain D-Bus method call.
107
108[event-log-design]:
109  https://github.com/openbmc/docs/blob/master/designs/event-logging.md#phosphor-logging
110[logging-cleared]:
111  https://github.com/openbmc/phosphor-dbus-interfaces/blob/6a8507d06e172d8d29c0459f0a0d078553d2ecc7/yaml/xyz/openbmc_project/Logging.events.yaml#L4
112
113#### Journal Based Event Log Creation [deprecated]
114
115Event logs can be created by using phosphor-logging APIs to commit sdbusplus
116exceptions. These APIs write to the journal, and then call a `Commit` D-Bus
117method on the logging daemon to create the event log using the information it
118put in the journal.
119
120The APIs are found in `<phosphor-logging/elog.hpp>`:
121
122- `elog()`: Throw an sdbusplus error.
123- `commit()`: Catch an error thrown by elog(), and commit it to create the event
124  log.
125- `report()`: Create an event log from an sdbusplus error without throwing the
126  exception first.
127
128Any errors passed into these APIs must be known to phosphor-logging, usually by
129being defined in `<phosphor-logging/elog-errors.hpp>`. The errors must also be
130known by sdbusplus, and be defined in their corresponding error.hpp. See below
131for details on how get errors into these headers.
132
133Example:
134
135```cpp
136#include <phosphor-logging/elog-errors.hpp>
137#include <phosphor-logging/elog.hpp>
138#include <xyz/openbmc_project/Common/error.hpp>
139...
140using InternalFailure =
141    sdbusplus::xyz::openbmc_project::Common::Error::InternalFailure;
142...
143if (somethingBadHappened)
144{
145    phosphor::logging::report<InternalFailure>();
146}
147
148```
149
150Alternatively, to throw, catch, and then commit the error:
151
152```cpp
153try
154{
155    phosphor::logging::elog<InternalFailure>();
156}
157catch (InternalFailure& e)
158{
159    phosphor::logging::commit<InternalFailure>();
160}
161```
162
163Metadata can be added to event logs to add debug data captured at the time of
164the event. It shows up in the AdditionalData property in the
165`xyz.openbmc_project.Logging.Entry` interface. Metadata is passed in via the
166`elog()` or `report()` functions, which write it to the journal. The metadata
167must be predefined for the error in the metadata YAML so that the daemon knows
168to look for it in the journal when it creates the event log.
169
170Example:
171
172```cpp
173#include <phosphor-logging/elog-errors.hpp>
174#include <phosphor-logging/elog.hpp>
175#include <xyz/openbmc_project/Control/Device/error.hpp>
176...
177using WriteFailure =
178    sdbusplus::xyz::openbmc_project::Control::Device::Error::WriteFailure;
179using metadata =
180    phosphor::logging::xyz::openbmc_project::Control::Device::WriteFailure;
181...
182if (somethingBadHappened)
183{
184    phosphor::logging::report<WriteFailure>(metadata::CALLOUT_ERRNO(5),
185                              metadata::CALLOUT_DEVICE_PATH("some path"));
186}
187```
188
189In the above example, the AdditionalData property would look like:
190
191```cpp
192["CALLOUT_ERRNO=5", "CALLOUT_DEVICE_PATH=some path"]
193```
194
195Note that the metadata fields must be all uppercase.
196
197##### Event Log Definition [deprecated]
198
199As mentioned above, both sdbusplus and phosphor-logging must know about the
200event logs in their header files, or the code that uses them will not even
201compile. The standard way to do this to define the event in the appropriate
202`<error-category>.errors.yaml` file, and define any metadata in the
203`<error-category>.metadata.yaml` file in the appropriate `*-dbus-interfaces`
204repository. During the build, phosphor-logging generates the elog-errors.hpp
205file for use by the calling code.
206
207In much the same way, sdbusplus uses the event log definitions to generate an
208error.hpp file that contains the specific exception. The path of the error.hpp
209matches the path of the YAML file.
210
211For example, if in phosphor-dbus-interfaces there is
212`xyz/openbmc_project/Control/Device.errors.yaml`, the errors that come from that
213file will be in the include: `xyz/openbmc_project/Control/Device/error.hpp`.
214
215In rare cases, one may want one to define their errors in the same repository
216that uses them. To do that, one must:
217
2181. Add the error and metadata YAML files to the repository.
2192. Run the sdbus++ script within the makefile to create the error.hpp and .cpp
220   files from the local YAML, and include the error.cpp file in the application
221   that uses it. See [openpower-occ-control] for an example.
2223. Tell phosphor-logging about the error:
223   1. Run phosphor-logging's `elog-gen.py` script on the local yaml to generate
224      an elog-errors.hpp file that just contains the local errors, and check
225      that into the repository and include it where the errors are needed.
226   2. Create a recipe that copies the local YAML files to a place that
227      phosphor-logging can find it during the build. See sample [LED
228      YAML][led-link] for an example.
229
230#### D-Bus Event Log Creation [deprecated]
231
232There is also a [D-Bus method][log-create-link] to create event logs:
233
234- Service: xyz.openbmc_project.Logging
235- Object Path: /xyz/openbmc_project/logging
236- Interface: xyz.openbmc_project.Logging.Create
237- Method: Create
238  - Method Arguments:
239    - Message: The `Message` string property for the
240      `xyz.openbmc_project.Logging.Entry` interface.
241    - Severity: The `severity` property for the
242      `xyz.openbmc_project.Logging.Entry` interface. An
243      `xyz.openbmc_project.Logging.Entry.Level` enum value.
244    - AdditionalData: The `AdditionalData` property for the
245      `xyz.openbmc_project.Logging.Entry` interface, but in a map instead of in
246      a vector of "KEY=VALUE" strings. Example:
247
248```cpp
249    std::map<std::string, std::string> additionalData;
250    additionalData["KEY"] = "VALUE";
251```
252
253Unlike the previous APIs where errors could also act as exceptions that could be
254thrown across D-Bus, this API does not require that the error be defined in the
255error YAML in the D-Bus interfaces repository so that sdbusplus knows about it.
256Additionally, as this method passes in everything needed to create the event
257log, the logging daemon doesn't have to know about it ahead of time either.
258
259That being said, it is recommended that users of this API still follow some
260guidelines for the message field, which is normally generated from a combination
261of the path to the error YAML file and the error name itself. For example, the
262`Timeout` error in `xyz/openbmc_project/Common.errors.yaml` will have a Message
263property of `xyz.openbmc_project.Common.Error.Timeout`.
264
265The guidelines are:
266
2671. When it makes sense, one can still use an existing error that has already
268   been defined in an error YAML file, and use the same severity and metadata
269   (AdditionalData) as in the corresponding metadata YAML file.
270
2712. If creating a new error, use the same naming scheme as other errors, which
272   starts with the domain, `xyz.openbmc_project`, `org.open_power`, etc,
273   followed by the capitalized category values, followed by `Error`, followed by
274   the capitalized error name itself, with everything separated by "."s. For
275   example: `xyz.openbmc_project.Some.Category.Error.Name`.
276
2773. If creating a new common error, still add it to the appropriate error and
278   metadata YAML files in the appropriate D-Bus interfaces repository so that
279   others can know about it and use it in the future. This can be done after the
280   fact.
281
282[xyz.openbmc_project.logging.entry]:
283  https://github.com/openbmc/phosphor-dbus-interfaces/blob/master/yaml/xyz/openbmc_project/Logging/Entry.interface.yaml
284[xyz.openbmc_project.association.definitions]:
285  https://github.com/openbmc/phosphor-dbus-interfaces/blob/master/yaml/xyz/openbmc_project/Association/Definitions.interface.yaml
286[associations-doc]:
287  https://github.com/openbmc/docs/blob/master/architecture/object-mapper.md#associations
288[callout-doc]:
289  https://github.com/openbmc/phosphor-dbus-interfaces/blob/master/yaml/xyz/openbmc_project/Common/Callout/README.md
290[xyz.openbmc_project.object.delete]:
291  https://github.com/openbmc/phosphor-dbus-interfaces/blob/master/yaml/xyz/openbmc_project/Object/Delete.interface.yaml
292[xyz.openbmc_project.software.version]:
293  https://github.com/openbmc/phosphor-dbus-interfaces/blob/master/yaml/xyz/openbmc_project/Software/Version.errors.yaml
294[openpower-occ-control]: https://github.com/openbmc/openpower-occ-control
295[led-link]:
296  https://github.com/openbmc/openbmc/tree/master/meta-phosphor/recipes-phosphor/leds
297[log-create-link]:
298  https://github.com/openbmc/phosphor-dbus-interfaces/blob/master/yaml/xyz/openbmc_project/Logging/Create.interface.yaml
299
300## Event Log Extensions
301
302The extension concept is a way to allow code that creates other formats of error
303logs besides phosphor-logging's event logs to still reside in the
304phosphor-log-manager application.
305
306The extension code lives in the `extensions/<extension>` subdirectories, and is
307enabled with a `--enable-<extension>` configure flag. The extension code won't
308compile unless enabled with this flag.
309
310Extensions can register themselves to have functions called at the following
311points using the REGISTER_EXTENSION_FUNCTION macro.
312
313- On startup
314  - Function type void(internal::Manager&)
315- After an event log is created
316  - Function type void(args)
317  - The args are:
318    - const std::string& - The Message property
319    - uin32_t - The event log ID
320    - uint64_t - The event log timestamp
321    - Level - The event level
322    - const AdditionalDataArg& - the additional data
323    - const AssociationEndpointsArg& - Association endpoints (callouts)
324- Before an event log is deleted, to check if it is allowed.
325  - Function type void(std::uint32_t, bool&) that takes the event ID
326- After an event log is deleted
327  - Function type void(std::uint32_t) that takes the event ID
328
329Using these callback points, they can create their own event log for each
330OpenBMC event log that is created, and delete these logs when the corresponding
331OpenBMC event log is deleted.
332
333In addition, an extension has the option of disabling phosphor-logging's default
334error log capping policy so that it can use its own. The macro
335DISABLE_LOG_ENTRY_CAPS() is used for that.
336
337### Motivation
338
339The reason for adding support for extensions inside the phosphor-log-manager
340daemon as opposed to just creating new daemons that listen for D-Bus signals is
341to allow interactions that would be complicated or expensive if just done over
342D-Bus, such as:
343
344- Allowing for custom old log retention algorithms.
345- Prohibiting manual deleting of certain logs based on an extension's
346  requirements.
347
348### Creating extensions
349
3501. Add a new flag to configure.ac to enable the extension:
351
352   ```autoconf
353   AC_ARG_ENABLE([foo-extension],
354                 AS_HELP_STRING([--enable-foo-extension],
355                                [Create Foo logs]))
356   AM_CONDITIONAL([ENABLE_FOO_EXTENSION],
357                  [test "x$enable_foo_extension" == "xyes"])
358   ```
359
3602. Add the code in `extensions/<extension>/`.
3613. Create a makefile include to add the new code to phosphor-log-manager:
362
363   ```make
364   phosphor_log_manager_SOURCES += \
365           extensions/foo/foo.cpp
366   ```
367
3684. In `extensions/extensions.mk`, add the makefile include:
369
370   ```make
371   if ENABLE_FOO_EXTENSION
372   include extensions/foo/foo.mk
373   endif
374   ```
375
3765. In the extension code, register the functions to call and optionally disable
377   log capping using the provided macros:
378
379   ```cpp
380   DISABLE_LOG_ENTRY_CAPS();
381
382   void fooStartup(internal::Manager& manager)
383   {
384       // Initialize
385   }
386
387   REGISTER_EXTENSION_FUNCTION(fooStartup);
388
389   void fooCreate(const std::string& message, uint32_t id, uint64_t timestamp,
390                   Entry::Level severity, const AdditionalDataArg& additionalData,
391                   const AssociationEndpointsArg& assocs)
392   {
393       // Create a different type of error log based on 'entry'.
394   }
395
396   REGISTER_EXTENSION_FUNCTION(fooCreate);
397
398   void fooRemove(uint32_t id)
399   {
400       // Delete the extension error log that corresponds to 'id'.
401   }
402
403   REGISTER_EXTENSION_FUNCTION(fooRemove);
404   ```
405
406### Extension List
407
408The supported extensions are:
409
410- OpenPower PELs
411  - Enabled with --enable-openpower-pel-extension
412  - Detailed information can be found in
413    [extensions/openpower-pels](extensions/openpower-pels/README.md).
414
415## Remote Logging via Rsyslog
416
417The BMC has the ability to stream out local logs (that go to the systemd
418journal) via rsyslog (<https://www.rsyslog.com/>).
419
420The BMC will send everything. Any kind of filtering and appropriate storage will
421have to be managed on the rsyslog server. Various examples are available on the
422internet. Here are few pointers :
423<https://www.rsyslog.com/storing-and-forwarding-remote-messages/>
424<https://www.rsyslog.com/doc/rsyslog%255Fconf%255Ffilter.html>
425<https://www.thegeekdiary.com/understanding-rsyslog-filter-options/>
426
427### Configuring rsyslog server for remote logging
428
429The BMC is an rsyslog client. To stream out logs, it needs to talk to an rsyslog
430server, to which there's connectivity over a network. REST API can be used to
431set the remote server's IP address and port number.
432
433The following presumes a user has logged on to the BMC (see
434<https://github.com/openbmc/docs/blob/master/rest-api.md>).
435
436Set the IP:
437
438```sh
439curl -b cjar -k -H "Content-Type: application/json" -X PUT \
440    -d '{"data": <IP address>}' \
441    https://<BMC IP address>/xyz/openbmc_project/logging/config/remote/attr/Address
442```
443
444Set the port:
445
446```sh
447curl -b cjar -k -H "Content-Type: application/json" -X PUT \
448    -d '{"data": <port number>}' \
449    https://<BMC IP address>/xyz/openbmc_project/logging/config/remote/attr/Port
450```
451
452#### Querying the current configuration
453
454```sh
455curl -b cjar -k \
456    https://<BMC IP address>/xyz/openbmc_project/logging/config/remote
457```
458
459#### Setting the hostname
460
461Rsyslog can store logs separately for each host. For this reason, it's useful to
462provide a unique hostname to each managed BMC. Here's how that can be done via a
463REST API :
464
465```sh
466curl -b cjar -k -H "Content-Type: application/json" -X PUT \
467    -d '{"data": "myHostName"}' \
468    https://<BMC IP address>//xyz/openbmc_project/network/config/attr/HostName
469```
470
471#### Disabling remote logging
472
473Remote logging can be disabled by writing 0 to the port, or an empty string("")
474to the IP.
475
476#### Changing the rsyslog server
477
478When switching to a new server from an existing one (i.e the address, or port,
479or both change), it is recommended to disable the existing configuration first.
480
481## Boot Fail on Hardware Errors
482
483phosphor-logging supports a setting, which when set, will result in the software
484looking at new phosphor-logging entries being created, and if a CALLOUT\* is
485found within the entry, ensuring the system will not power on. Entries with
486severities of Informational or Debug will not block boots, even if they have
487callouts.
488
489The full design for this can be found in
490[docs](https://github.com/openbmc/docs/blob/master/designs/fail-boot-on-hw-error.md).
491
492To enable this function:
493
494```sh
495busctl set-property xyz.openbmc_project.Settings /xyz/openbmc_project/logging/settings xyz.openbmc_project.Logging.Settings QuiesceOnHwError b true
496```
497
498To check if an entry is blocking the boot:
499
500```sh
501obmcutil listbootblock
502```
503
504Resolve or clear the corresponding entry to allow the system to boot.
505