和往常一樣,OpenBMC中官方對Redfish 的Log 機制已經有很詳細的介紹,所以這篇是結合一些額外的資料來看整個LogService 的架構和原理 (*如果之後OpenBMC架構有變,這邊不會再更新)
docs/redfish-logging-in-bmcweb.md at master · openbmc/docs · GitHub
LogService
在Redfish 還沒問世之前,BMC的世界中會將有問題的事件紀錄成System Event Log (SEL),SEL 在IPMI中是用16 Byte來表示,IPMItool 等工具會將其轉換為可讀性高的文字,而在Redfish 協議中,系統事件的紀錄(開關機,溫度異常等)是由LogServices來負責監控和配置這些事件,OpenBMC將這些系統事件稱Event Log (LogServices 不只有系統事件,還有包含audit log, crashdump 等,這篇文章只會介紹EventLog)
Journal - Systemd日誌
Systemd has its own logging system called the journal; running a separate logging daemon is not required systemd/Journal - ArchWiki (archlinux.org)
Journal是systemd本身自帶的日誌系統,它的log分類是根據Syslog協定,透過 "journalctl"指令可以讀取系統日誌,透過設定檔 /etc/systemd/journald.conf 可以更改Journal 設定
//透過 "journalctl"指令可以讀取系統日誌
> journalctl
Jun 25 08:41:09 intel-obmc bmcweb[370]: pam_succeed_if(webserver:auth): requirement "user ingroup redfish" was met by user "root"
//加上-o json可以將所有filed用json格式印出來,可以看到"PRIORITY" 這樣就算一個filed,我們也可以自己定義想要的filed,filed的數量並沒有規定,名字可以自定義的
> journalctl -o json
{
"_SOURCE_REALTIME_TIMESTAMP": "1624610486273832",
"PRIORITY": "6",
"_BOOT_ID": "7f34e1dd99bd4d82add8c4f627da6d2c",
"_SYSTEMD_INVOCATION_ID": "3fb0bea4b7ef4285bda15cde5c400b56",
"SYSLOG_FACILITY": "10",
"MESSAGE": "pam_succeed_if(webserver:auth): requirement \"user ingroup redfish\" was met by user \"root\"",
"__MONOTONIC_TIMESTAMP": "105559270358",
"_CMDLINE": "/usr/bin/bmcweb",
"SYSLOG_IDENTIFIER": "bmcweb",
"_CAP_EFFECTIVE": "1ffffffffff",
"__CURSOR": "s=7ece329c23f3447497b13bfd083c9ab9;i=534;b=7f34e1dd99bd4d82add8c4f627da6d2c;m=1893d2a3d6;t=5c5931aeec754;x=a43f04e856ee1bf",
"_HOSTNAME": "intel-obmc",
"_SYSTEMD_SLICE": "system.slice",
"_COMM": "bmcweb",
"_GID": "0",
"_SYSTEMD_UNIT": "bmcweb.service",
"_UID": "0",
"SYSLOG_TIMESTAMP": "Jun 25 08:41:26 ",
"_TRANSPORT": "syslog",
"_MACHINE_ID": "0c1eaebf149d400b851c027c0a218f06",
"_EXE": "/usr/bin/bmcweb",
"__REALTIME_TIMESTAMP": "1624610486273876",
"_SYSTEMD_CGROUP": "/system.slice/bmcweb.service",
"_PID": "370"
}
openbmc/rsyslog.conf at master · openbmc/openbmc · GitHub
# Template for Redfish messages
# "<timestamp> <MessageId>,<MessageArgs>"
template(name="RedfishTemplate" type="list") {
property(name="timereported" dateFormat="rfc3339")
constant(value=" ")
property(name="$!REDFISH_MESSAGE_ID")
constant(value=",")
property(name="$!REDFISH_MESSAGE_ARGS")
constant(value="\n")
}
# If the journal entry has a Redfish MessageId, save as a Redfish event
if ($!REDFISH_MESSAGE_ID != "") then {
action(type="omfile" file="/var/log/redfish" template="RedfishTemplate")
}
分類步驟
1. 判斷log有無REDFISH_MESSAGE_ID這個filed
# If the journal entry has a Redfish MessageId, save as a Redfish event
if ($!REDFISH_MESSAGE_ID != "") then {
action(type="omfile" file="/var/log/redfish" template="RedfishTemplate")
}
2. 用redfishtemplate格式存入/var/log/redfish中
template(name="RedfishTemplate" type="list") {
property(name="timereported" dateFormat="rfc3339")
constant(value=" ")
property(name="!REDFISHMESSAGEID")constant(value=",")property(name="!REDFISH_MESSAGE_ARGS")
constant(value="\n")
}
3. redfish會去/var/log/redfish中撈資料 (GET: /redfish/v1/Systems/system/LogServices/EventLog/Entries/)
// redfish-core\lib\log_services.hpp static bool getRedfishLogFiles(std::vector<std::filesystem::path>& redfishLogFiles) { static const std::filesystem::path redfishLogDir = "/var/log"; static const std::string redfishLogFilename = "redfish"; ... } inline void requestRoutesJournalEventLogEntryCollection(App& app) { BMCWEB_ROUTE(app, "/redfish/v1/Systems/system/LogServices/EventLog/Entries/") .privileges(redfish::privileges::getLogEntryCollection) .methods(boost::beast::http::verb::get)( ... getRedfishLogFiles(redfishLogFiles); ...) }
sd_journal_send("MESSAGE=%s", "journal text", "PRIORITY=%i", <LOG_LEVEL>, "REDFISH_MESSAGE_ID=%s", "ResourceEvent.1.0.ResourceErrorThresholdExceeded", "REDFISH_MESSAGE_ARGS=%s,%d", "Property Name", propertyValue, NULL);
Message Registry
REDFISH_MESSAGE_ID 和 REDFISH_MESSAGE_ARGS要填的內容就要參考Message registry
我們先來看一個registry的範例 [GET] /redfish/v1/Registries/OpenBMC/OpenBMC
bmcweb/openbmc_message_registry.hpp at master · openbmc/bmcweb · GitHub
{ "@Redfish.Copyright": "Copyright 2018 OpenBMC. All rights reserved.", "@odata.type": "#MessageRegistry.v1_4_0.MessageRegistry", "Description": "This registry defines the base messages for OpenBMC.", "Id": "OpenBMC.0.1.0", "Language": "en", "Messages": { "SystemPowerOnFailed": { "Description": "Indicates that the system failed to power on.", "Message": "System Power-On Failed.", "MessageSeverity": "Critical", "NumberOfArgs": 0, "Resolution": "None.", "Severity": "Critical" }}, "VoltageRegulatorOverheated": { "Description": "Indicates that the specified voltage regulator overheated.", "Message": "%1 Voltage Regulator Overheated.", "MessageSeverity": "Critical", "NumberOfArgs": 1, "ParamTypes": ["string"], "Resolution": "None.", "Severity": "Critical" } }, "Name": "OpenBMC Message Registry", "OwningEntity": "OpenBMC", "RegistryPrefix": "OpenBMC", "RegistryVersion": "0.1.0" }
一個MessageId組成對應registry大概如下
如果想要記個 VoltageRegulatorOverheated的event,
- REDFISH_MESSAGE_ID = OpenBMC.0.1.VoltageRegulatorOverheated
- REDFISH_MESSAGE_ARGS可以帶"CPU 0"
程式碼寫法如下
sd_journal_send("MESSAGE=%s", "journal text", "PRIORITY=%i", <LOG_LEVEL>,
"REDFISH_MESSAGE_ID=%s",
"OpenBMC.0.1.VoltageRegulatorOverheated",
"REDFISH_MESSAGE_ARGS=%s", "CPU 0", NULL);
cat /var/log/redfish
1970-01-01T00:00:15.077204+00:00 OpenBMC.0.1.VoltageRegulatorOverheated,CPU 0
Redfish 會透過REDFISH_MESSAGE_ID 將Event log翻譯成可讀性高的文字訊息,其中log的一些property是可以和剛剛上面提的message prefix相對應的
{
"@odata.id": "/redfish/v1/Systems/system/LogServices/EventLog/Entries/15_2",
"@odata.type": "#LogEntry.v1_4_0.LogEntry",
"Created": "1970-01-01T00:00:15+00:00",
"EntryType": "Event",
"Id": "15_2",
"Message": "CPU 0 Voltage Regulator Overheated.",
"MessageArgs": [
"CPU 0"
],
"MessageId": "OpenBMC.0.1.VoltageRegulatorOverheated",
"Name": "System Event Log Entry",
"Severity": "Critical"
}
目前openBMC支援的prefix有Base, TaskEvents, ResourceEvent, OpenBMC四種,可以在source code:bmweb\redfish-core\include\registries"或透過GET /redfish/v1/Registries 看到
EventService
我們先來看EventService的架構
- RedfishEvent
- SSE
RedfishEvent
#/redfish/v1/EventService/Subscriptions/553916031
{
"@odata.id": "/redfish/v1/EventService/Subscriptions/553916031",
"@odata.type": "#EventDestination.v1_7_0.EventDestination",
"Context": "CustomText",
"DeliveryRetryPolicy": "RetryForever",
"Destination": "https://10.142.24.24:8000/",
"EventFormatType": "Event",
"HttpHeaders": [
{
"Authentication": "Splunk 49ce1-sdfoijf-wegsdfe-qwessddasd"
}
],
"Id": "553916031",
"MessageIds": [],
"MetricReportDefinitions": [],
"Name": "Event Destination 553916031",
"Protocol": "Redfish",
"RegistryPrefixes": [],
"ResourceTypes": [],
"SubscriptionType": "RedfishEvent"
}
SSE(Server-Sent Events)
{
"SSEFilterPropertiesSupported": {
"EventFormatType": true,
"MessageId": true,
"MetricReportDefinition": true,
"OriginResource": false,
"RegistryPrefix": true,
"ResourceType": false
},
}
/redfish/v1/EventService/Subscriptions/SSE?$filter=RegistryPrefix eq OpenBMC
#/redfish/v1/EventService/Subscriptions/2225775524 { "@odata.id": "/redfish/v1/EventService/Subscriptions/2225775524", "@odata.type": "#EventDestination.v1_7_0.EventDestination", "Context": "", "DeliveryRetryPolicy": "TerminateAfterRetries", "Destination": "", "EventFormatType": "Event", "HttpHeaders": [], "Id": "2225775524", "MessageIds": [], "MetricReportDefinitions": [], "Name": "Event Destination 2225775524", "Protocol": "Redfish", "RegistryPrefixes": [ "OpenBMC" ], "ResourceTypes": [], "SubscriptionType": "SSE" }
https://www.youtube.com/watch?v=_8ZnMVcMnbs
沒有留言:
張貼留言
注意:只有此網誌的成員可以留言。