xref: /openbmc/phosphor-logging/README.md (revision 3210a9f3)
1# phosphor-logging
2phosphor logging provides mechanism for common event and logging creation based
3on information from the journal log.
4
5## To Build
6```
7To build this package, do the following steps:
8
9    1. ./bootstrap.sh
10    2. ./configure ${CONFIGURE_FLAGS}
11    3. make
12
13To clean the repository run `./bootstrap.sh clean`.
14```
15
16## Remote Logging via Rsyslog
17The BMC has the ability to stream out local logs (that go to the systemd journal)
18via rsyslog (https://www.rsyslog.com/).
19
20The BMC will send everything. Any kind of filtering and appropriate storage
21will have to be managed on the rsyslog server. Various examples are available
22on the internet. Here are few pointers :
23https://www.rsyslog.com/storing-and-forwarding-remote-messages/
24https://www.rsyslog.com/doc/rsyslog%255Fconf%255Ffilter.html
25https://www.thegeekdiary.com/understanding-rsyslog-filter-options/
26
27#### Configuring rsyslog server for remote logging
28The BMC is an rsyslog client. To stream out logs, it needs to talk to an rsyslog
29server, to which there's connectivity over a network. REST API can be used to
30set the remote server's IP address and port number.
31
32The following presumes a user has logged on to the BMC (see
33https://github.com/openbmc/docs/blob/master/rest-api.md).
34
35Set the IP:
36```
37curl -b cjar -k -H "Content-Type: application/json" -X PUT \
38    -d '{"data": <IP address>}' \
39    https://<BMC IP address>/xyz/openbmc_project/logging/config/remote/attr/Address
40```
41
42Set the port:
43```
44curl -b cjar -k -H "Content-Type: application/json" -X PUT \
45    -d '{"data": <port number>}' \
46    https://<BMC IP address>/xyz/openbmc_project/logging/config/remote/attr/Port
47```
48
49#### Querying the current configuration
50```
51curl -b cjar -k \
52    https://<BMC IP address>/xyz/openbmc_project/logging/config/remote
53```
54
55#### Setting the hostname
56Rsyslog can store logs separately for each host. For this reason, it's useful to
57provide a unique hostname to each managed BMC. Here's how that can be done via a
58REST API :
59```
60curl -b cjar -k -H "Content-Type: application/json" -X PUT \
61    -d '{"data": "myHostName"}' \
62    https://<BMC IP address>//xyz/openbmc_project/network/config/attr/HostName
63```
64
65#### Disabling remote logging
66Remote logging can be disabled by writing 0 to the port, or an empty string("")
67to the IP.
68
69#### Changing the rsyslog server
70When switching to a new server from an existing one (i.e the address, or port,
71or both change), it is recommended to disable the existing configuration first.
72
73
74## Adding application specific error YAML
75* This document captures steps for adding application specific error YAML files
76  and generating local elog-errors.hpp header file for application use.
77* Should cater for continuous integration (CI) build, bitbake image build, and
78  local repository build.
79
80#### Continuous Integration (CI) build
81 * Make is called on the repository that is modified.
82 * Dependent packages are pulled based on the dependency list specified in the
83   configure.ac script.
84
85#### Recipe build
86 * Native recipes copy error YAML files to shared location.
87 * phosphor-logging builds elog-errors.hpp by parsing the error YAML files from
88   the shared location.
89
90#### Local repository build
91 * Copies local error YAML files to the shared location in SDK
92 * Make generates elog-errors.hpp by parsing the error YAML files from the
93   shared location.
94
95#### Makefile changes
96**Reference**
97 * https://github.com/openbmc/openpower-debug-collector/blob/master/Makefile.am
98
99###### Export error YAML to shared location
100*Modify Makefile.am to export newly added error YAML to shared location*
101```
102yamldir = ${datadir}/phosphor-dbus-yaml/yaml
103nobase_yaml_DATA = \
104    org/open_power/Host.errors.yaml
105```
106
107###### Generate elog-errors.hpp using elog parser from SDK location
108 * Add a conditional check "GEN_ERRORS"
109 * Disable the check for recipe bitbake image build
110 * Enable it for local repository build
111 * If "GEN_ERRORS" is enabled, build generates elog-errors.hpp header file.
112```
113  # Generate phosphor-logging/elog-errors.hpp
114  if GEN_ERRORS
115  ELOG_MAKO ?= elog-gen-template.mako.hpp
116  ELOG_DIR ?= ${OECORE_NATIVE_SYSROOT}${datadir}/phosphor-logging/elog
117  ELOG_GEN_DIR ?= ${ELOG_DIR}/tools/
118  ELOG_MAKO_DIR ?= ${ELOG_DIR}/tools/phosphor-logging/templates/
119  YAML_DIR ?= ${OECORE_NATIVE_SYSROOT}${datadir}/phosphor-dbus-yaml/yaml
120  phosphor-logging/elog-errors.hpp:
121      @mkdir -p ${YAML_DIR}/org/open_power/
122      @cp ${top_srcdir}/org/open_power/Host.errors.yaml \
123        ${YAML_DIR}/org/open_power/Host.errors.yaml
124      @mkdir -p `dirname $@`
125      @chmod 777 $(ELOG_GEN_DIR)/elog-gen.py
126      $(AM_V_at)$(PYTHON) $(ELOG_GEN_DIR)/elog-gen.py -y ${YAML_DIR} \
127        -t ${ELOG_MAKO_DIR} -m ${ELOG_MAKO} -o $@
128  endif
129```
130
131###### Update BUILT_SOURCES
132 * Append elog-errors.hpp to BUILT_SOURCES list and put it in conditional check
133   GEN_ERRORS so that the elog-errors.hpp is generated only during local
134   repository build.
135```
136    if GEN_ERRORS
137    nobase_nodist_include_HEADERS += \
138                phosphor-logging/elog-errors.hpp
139    endif
140    if GEN_ERRORS
141    BUILT_SOURCES += phosphor-logging/elog-errors.hpp
142    endif
143```
144
145###### Conditional check for native build
146 * As the same Makefile is used both for recipe image build and native recipe
147   build, add a conditional to ensure that only installation of error yaml files
148   happens during native build. It is not required to build repository during
149   native build.
150```
151   if !INSTALL_ERROR_YAML
152   endif
153```
154
155#### Autotools changes
156**Reference**
157 * https://github.com/openbmc/openpower-debug-collector/blob/master/configure.ac
158
159###### Add option(argument) to enable/disable installing error yaml file
160 * Install error yaml option(argument) is enabled for native recipe build
161   and disabled for bitbake build.
162
163 * When install error yaml option is disabled do not check for target specific
164   packages in autotools configure script.
165
166###### Add option(argument) to install error yaml files
167```
168AC_ARG_ENABLE([install_error_yaml],
169    AS_HELP_STRING([--enable-install_error_yaml],
170    [Enable installing error yaml file]),[], [install_error_yaml=no])
171AM_CONDITIONAL([INSTALL_ERROR_YAML],
172    [test "x$enable_install_error_yaml" = "xyes"])
173AS_IF([test "x$enable_install_error_yaml" != "xyes"], [
174..
175..
176])
177```
178
179###### Add option(argument) to enable/disable generating elog-errors header file
180```
181AC_ARG_ENABLE([gen_errors],
182    AS_HELP_STRING([--enable-gen_errors], [Enable elog-errors.hpp generation ]),
183    [],[gen_errors=yes])
184AM_CONDITIONAL([GEN_ERRORS], [test "x$enable_gen_errors" != "xno"])
185```
186
187#### Recipe changes
188**Reference**
189* https://github.com/openbmc/openbmc/blob/master/meta-openbmc-machines\
190/meta-openpower/common/recipes-phosphor/debug/openpower-debug-collector.bb
191
192###### Extend recipe for native and nativesdk
193* Extend the recipe for native and native SDK builds
194```
195BBCLASSEXTEND += "native nativesdk"
196```
197###### Remove dependencies for native and native SDK build
198* Native recipe caters only for copying error yaml files to shared location.
199* For native and native SDK build remove dependency on packages that recipe
200  build depends
201
202###### Remove dependency on phosphor-logging for native build
203```
204DEPENDS_remove_class-native = "phosphor-logging"
205```
206
207###### Remove dependency on phosphor-logging for native SDK build
208```
209DEPENDS_remove_class-nativesdk = "phosphor-logging"
210```
211
212###### Add install_error_yaml argument during native build
213* Add package config to enable/disable install_error_yaml feature.
214
215###### Add package config to enable/disable install_error_yaml feature
216```
217PACKAGECONFIG ??= "install_error_yaml"
218PACKAGECONFIG[install_error_yaml] = " \
219        --enable-install_error_yaml, \
220        --disable-install_error_yaml, ,\
221        "
222```
223###### Enable install_error_yaml check for native build
224```
225PACKAGECONFIG_add_class-native = "install_error_yaml"
226PACKAGECONFIG_add_class-nativesdk = "install_error_yaml"
227```
228###### Disable install_error_yaml during target build
229```
230PACKAGECONFIG_remove_class-target = "install_error_yaml"
231```
232
233###### Disable generating elog-errors.hpp for bitbake build
234* Disable gen_errors argument for bitbake image build as the application uses
235  the elog-errors.hpp generated by phosphor-logging
236* Argument is enabled by default for local repository build in the configure
237  script of the local repository.
238```
239 XTRA_OECONF += "--disable-gen_errors"
240```
241
242#### Local build
243* During local build use --prefix=/usr for the configure script.
244
245**Reference**
246* https://github.com/openbmc/openpower-debug-collector/blob/master/README.md
247
248## Event Log Extensions
249
250The extension concept is a way to allow code that creates other formats of
251error logs besides phosphor-logging's event logs to still reside in the
252phosphor-log-manager application.
253
254The extension code lives in the `extensions/<extension>` subdirectories,
255and is enabled with a `--enable-<extension>` configure flag.  The
256extension code won't compile unless enabled with this flag.
257
258Extensions can register themselves to have functions called at the following
259points using the REGISTER_EXTENSION_FUNCTION macro.
260* On startup
261   * Function type void(internal::Manager&)
262* After an event log is created
263   * Function type void(args)
264   * The args are:
265     * const std::string& - The Message property
266     * uin32_t - The event log ID
267     * uint64_t - The event log timestamp
268     * Level - The event level
269     * const AdditionalDataArg& - the additional data
270     * const AssociationEndpointsArg& - Association endpoints (callouts)
271* Before an event log is deleted, to check if it is allowed.
272   * Function type void(std::uint32_t, bool&) that takes the event ID
273* After an event log is deleted
274   * Function type void(std::uint32_t) that takes the event ID
275
276Using these callback points, they can create their own event log for each
277OpenBMC event log that is created, and delete these logs when the corresponding
278OpenBMC event log is deleted.
279
280In addition, an extension has the option of disabling phosphor-logging's
281default error log capping policy so that it can use its own.  The macro
282DISABLE_LOG_ENTRY_CAPS() is used for that.
283
284### Motivation
285
286The reason for adding support for extensions inside the phosphor-log-manager
287daemon as opposed to just creating new daemons that listen for D-Bus signals is
288to allow interactions that would be complicated or expensive if just done over
289D-Bus, such as:
290* Allowing for custom old log retention algorithms.
291* Prohibiting manual deleting of certain logs based on an extension's
292  requirements.
293
294### Creating extensions
295
2961. Add a new flag to configure.ac to enable the extension:
297```
298AC_ARG_ENABLE([foo-extension],
299              AS_HELP_STRING([--enable-foo-extension],
300                             [Create Foo logs]))
301AM_CONDITIONAL([ENABLE_FOO_EXTENSION],
302               [test "x$enable_foo_extension" == "xyes"])
303```
3042. Add the code in `extensions/<extension>/`.
3053. Create a makefile include to add the new code to phosphor-log-manager:
306```
307phosphor_log_manager_SOURCES += \
308        extensions/foo/foo.cpp
309```
3103. In `extensions/extensions.mk`, add the makefile include:
311```
312if ENABLE_FOO_EXTENSION
313include extensions/foo/foo.mk
314endif
315```
3164. In the extension code, register the functions to call and optionally disable
317   log capping using the provided macros:
318```
319DISABLE_LOG_ENTRY_CAPS();
320
321void fooStartup(internal::Manager& manager)
322{
323    // Initialize
324}
325
326REGISTER_EXTENSION_FUNCTION(fooStartup);
327
328void fooCreate(const std::string& message, uint32_t id, uint64_t timestamp,
329               Entry::Level severity, const AdditionalDataArg& additionalData,
330               const AssociationEndpointsArg& assocs)
331{
332    // Create a different type of error log based on 'entry'.
333}
334
335REGISTER_EXTENSION_FUNCTION(fooCreate);
336
337void fooRemove(uint32_t id)
338{
339    // Delete the extension error log that corresponds to 'id'.
340}
341
342REGISTER_EXTENSION_FUNCTION(fooRemove);
343```
344### Extension List
345
346The supported extensions are:
347
348* OpenPower PELs
349    * Enabled with --enable-openpower-pel-extension
350    * Detailed information can be found
351        [here](extensions/openpower-pels/README.md)
352