EventService功能是Redfish規范中定義的一種事件日志的發送方式。用戶可以設置訂閱者信息(通常是一個web服務器),當產生事件日志時,OpenBMC可以根據用戶設置的訂閱者信息與對日志的篩選設置,將事件日志發送到訂閱者。
相比于傳統的SNMPTrap日志發送機制,EventService發送機制具有如下的優點:
Redfish EventService:
- 基于 RESTful API:使用 HTTP/HTTPS 協議,天然支持現代 Web 技術棧(如 JSON、OData)
- 結構化數據:事件內容以 JSON 格式傳輸,字段清晰、可擴展性強(如包含資源鏈接、時間戳、上下文信息)
- 自描述性:事件中直接關聯資源的 URI(如 OriginOfCondition),便于快速定位問題來源
SNMP Trap:
- 基于 UDP:無連接協議,存在丟包風險,且安全性較低(傳統 SNMPv1/v2c 依賴社區字符串明文傳輸)
- 二進制編碼(BER):數據格式復雜,需依賴 MIB 文件解析,跨系統兼容性差。
- 信息有限:通常僅傳遞 OID 和簡單數值,缺乏上下文關聯(如無法直接定位故障設備的具體資源路徑)。
而通過EventService發送事件,可以選擇syslog或SMTP協議發送,這樣通過EventService接口可以實現統一的日志發送管理。由此可見通過EventService進行日志發送相比傳統方式具有很大優勢。
最近從OpenBMC代碼中導入這部分功能,其主要思路在于bmcweb進程監控dbus上xyz.openbmc_project.Logging進程的InterfacesAdded信號,該信號表示產生了新日志,此時bmcweb進程讀取日志內容,并通過EventService進行發送。
const std::string propertiesMatchString =sdbusplus::bus::match::rules::type::signal() +sdbusplus::bus::match::rules::sender("xyz.openbmc_project.Logging") +sdbusplus::bus::match::rules::interface("org.freedesktop.DBus.ObjectManager") +sdbusplus::bus::match::rules::path("/xyz/openbmc_project/logging") +sdbusplus::bus::match::rules::member("InterfacesAdded");DbusEventLogMonitor::DbusEventLogMonitor() :dbusEventLogMonitor(*crow::connections::systemBus, propertiesMatchString,onDbusEventLogCreated)
驗證此項功能,需要搭建一個簡單的web服務器,可以通過js代碼來實現。
首先生成自簽名證書(僅供測試使用)。
- 新建文件 san.cnf,內容如下:
[req]
default_bits = 4096
prompt = no
default_md = sha256
distinguished_name = dn
x509_extensions = v3_req[dn]
C = CN # 國家代碼(如CN/US)
ST = Beijing # 省份/州
L = Beijing # 城市
O = MyCompany # 組織名稱
OU = DevOps # 部門
CN = example.com # 域名或IP(主名稱)[v3_req]
subjectAltName = @alt_names[alt_names]
DNS.1 = example.com # 支持的域名
DNS.2 = www.example.com
IP.1 = 192.168.1.100 # 用于搭建web服務器的PC的IP
- 生成證書,執行如下命令:
openssl req -x509 -newkey rsa:4096 -nodes \-keyout server.key -out server.crt \-days 365 -config san.cnf -extensions v3_req
- 查看證書內容:
openssl x509 -in server.crt -text -noout
主要檢查有效期與是否包含預期的IP或域名。
接下來就可以使用生成的自簽名證書啟動web服務器,將如下代碼保存為server.js,與生成的證書server.crt,server.key文件放在同一個目錄下
const https = require('https');
const fs = require('fs');
const url = require('url');// 讀取 SSL 證書和私鑰
const options = {key: fs.readFileSync('server.key'),cert: fs.readFileSync('server.crt')
};// 創建 HTTPS 服務器
const server = https.createServer(options, (req, res) => {const { method, url: reqUrl } = req;// 只處理 POST 請求if (method === 'POST' && reqUrl === '/bmc-data') {let body = '';// 接收請求體數據req.on('data', chunk => {body += chunk.toString();});// 請求結束時處理數據req.on('end', () => {console.log('Received data:', body);// 返回成功響應res.writeHead(200, { 'Content-Type': 'application/json' });res.end(JSON.stringify({ status: 'success', data: body }));});} else {// 返回 404 錯誤res.writeHead(404, { 'Content-Type': 'text/plain' });res.end('Not Found');}
});// 綁定端口并啟動服務器
const PORT = 8443; // 可以更改為其他端口
server.listen(PORT, () => {console.log(`HTTPS server running on port ${PORT}`);
});
根據需要可以修改端口號,這里選擇了8443。使用node server.js
命令即可啟動web服務器:
通過ssh登錄openBMC,使用curl命令向web服務器發送HTTPS請求進行驗證,發現產生如下報錯:
這是由于OpenBMC沒有信任自簽名證書導致的,需要將自簽名證書添加到信任。首先將server.crt證書文件上傳到OpenBMC的/usr/share/ca-certificates目錄下,然后將證書名添加到/etc/ca-certifacates.conf文件中。最后運行update-ca-certificate程序即可將自簽名證書添加到信任。
如果產生如下報錯,則表明BMC時間與證書的有效時間不匹配
可以設置BMC時間解決:
通過curl命令發送HTTPS請求正常后,觸發EventService發送測試日志,也可以正常收到: