Name
Date
Size
#Lines
LOC

..--

callouts/H--10374

config/H--7460

dist/H--7561

docs/H--311244

extensions/H--34,74322,596

gen/H--165134

lib/H--2,1431,398

phosphor-rsyslog-config/H--506371

subprojects/H--4936

test/H--15,72011,237

tools/H--705545

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 D27-Jan-202517.8 KiB487376

config_main.hH A D30-Sep-2024108 53

elog_block.hppH A D16-Aug-20241.7 KiB6139

elog_entry.cppH A D30-Sep-20243.5 KiB134108

elog_entry.hppH A D11-Dec-20246.2 KiB17884

elog_meta.cppH A D21-Nov-20241.7 KiB6455

elog_meta.hppH A D21-Nov-20243 KiB10170

elog_serialize.cppH A D11-Dec-20245.8 KiB174136

elog_serialize.hppH A D30-Sep-20241.3 KiB4719

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 D01-Feb-202520.9 KiB724589

log_manager.hppH A D22-Nov-202413.6 KiB405153

log_manager_main.cppH A D03-Oct-20241.5 KiB6041

logging_test.cppH A D17-Dec-20247.8 KiB263204

meson.buildH A D01-Feb-20255.2 KiB205185

meson.optionsH A D01-Feb-20251.1 KiB5145

paths.cppH A D30-Sep-2024340 1613

paths.hppH A D30-Sep-2024255 159

setup.cfgH A D16-Apr-202139 21

util.cppH A D21-Nov-20247.3 KiB239170

util.hppH A D21-Nov-20241.3 KiB4818

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