Skip to content

1120: Add support for MetricDefinition scheme (#1088) #1284

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 4 commits into
base: 1120
Choose a base branch
from

Conversation

rfrandse
Copy link
Collaborator

@rfrandse rfrandse commented May 9, 2025

1120: Add support for MetricDefinition scheme (1110 PR: #1088)

* Add support for MetricDefinition scheme

Added MetricDefinition node to Redfish code. Now user is able to list
all available metrics in OpenBMC that are supported by Telemetry
service. Metrics are grouped by reading type.

MetricDefinitions contains all physical sensors supported by redfish,
algorithm iterates through all chassis and collects results for each
node available in that chassis (Power, Thermal, Sensors).

When BMCWEB_NEW_POWERSUBSYSTEM_THERMALSUBSYSTEM will be enabled by
default (meson option redfish-new-powersubsystem-thermalsubsystem) it
will be possible to optimize this algorithm to only get sensors from
Sensors node. Currently Sensors node doesn't contain all available
sensors.

Removal of ResourceNotFound in sensors.hpp to fix MetricDefinition
Collection REST Get call.

Tested:
 - MetricDefinitions response is filled with existing sensors, it works
   with and without Telemetry service
 - Validated a presence of MetricDefinition members and its attributes
 - Successfully passed RedfishServiceValidator.py using witherspoon
   image on QEMU
 - Tested using following GET,POST requests

GET /redfish/v1/TelemetryService/MetricDefinitions
{
  "@odata.id": "/redfish/v1/TelemetryService/MetricDefinitions",
  "@odata.type": "#MetricDefinitionCollection.MetricDefinitionCollection",
  "Members": [
    {
      "@odata.id": "/redfish/v1/TelemetryService/MetricDefinitions/Fan_Pwm"
    },
    {
      "@odata.id": "/redfish/v1/TelemetryService/MetricDefinitions/Fan_Tach"
    },
    {
      "@odata.id": "/redfish/v1/TelemetryService/MetricDefinitions/HostCpuUtilization"
    },
    {
      "@odata.id": "/redfish/v1/TelemetryService/MetricDefinitions/HostMemoryBandwidthUtilization"
    },
    {
      "@odata.id": "/redfish/v1/TelemetryService/MetricDefinitions/HostPciBandwidthUtilization"
    },
    {
      "@odata.id": "/redfish/v1/TelemetryService/MetricDefinitions/Inlet_BRD_Temp"
    },
    {
      "@odata.id": "/redfish/v1/TelemetryService/MetricDefinitions/Left_Rear_Board_Temp"
    }
  ],
  "Members@odata.count": 7,
  "Name": "Metric Definition Collection"
}

GET /redfish/v1/TelemetryService/MetricDefinitions/Fan_Tach
{
  "@odata.id": "/redfish/v1/TelemetryService/MetricDefinitions/Fan_Tach",
  "@odata.type": "#MetricDefinition.v1_0_3.MetricDefinition",
  "Id": "Fan_Tach",
  "IsLinear": true,
  "MaxReadingRange": 25000.0,
  "MetricDataType": "Decimal",
  "MetricProperties": [
    "/redfish/v1/Chassis/AC_Baseboard/Thermal#/Fans/0/Reading",
    "/redfish/v1/Chassis/AC_Baseboard/Thermal#/Fans/1/Reading",
    "/redfish/v1/Chassis/AC_Baseboard/Thermal#/Fans/2/Reading",
    "/redfish/v1/Chassis/AC_Baseboard/Thermal#/Fans/3/Reading",
    "/redfish/v1/Chassis/AC_Baseboard/Thermal#/Fans/4/Reading",
    "/redfish/v1/Chassis/AC_Baseboard/Thermal#/Fans/5/Reading",
    "/redfish/v1/Chassis/AC_Baseboard/Thermal#/Fans/6/Reading",
    "/redfish/v1/Chassis/AC_Baseboard/Thermal#/Fans/7/Reading",
    "/redfish/v1/Chassis/AC_Baseboard/Thermal#/Fans/8/Reading",
    "/redfish/v1/Chassis/AC_Baseboard/Thermal#/Fans/9/Reading"
  ],
  "MetricType": "Gauge",
  "MinReadingRange": 0.0,
  "Name": "Fan_Tach",
  "Units": "RPM"
}

POST redfish/v1/TelemetryService/MetricReportDefinitions, body:
{
  "Id": "TestReport",
  "Metrics": [
    {
      "MetricId": "TestMetric",
      "MetricProperties": [
        "/redfish/v1/Chassis/Chassis0/Thermal#/Fans/3/Reading",
      ]
    }
  ],
  "MetricReportDefinitionType": "OnRequest",
  "ReportActions": [
    "RedfishEvent",
    "LogToMetricReportsCollection"
  ]
}
{
  "@Message.ExtendedInfo": [
    {
      "@odata.type": "#Message.v1_1_1.Message",
      "Message": "The resource has been created successfully",
      "MessageArgs": [],
      "MessageId": "Base.1.8.1.Created",
      "MessageSeverity": "OK",
      "Resolution": "None"
    }
  ]
}

Signed-off-by: Wludzik, Jozef <jozef.wludzik@intel.com>
Signed-off-by: Krzysztof Grobelny <krzysztof.grobelny@intel.com>
Change-Id: I3086e1302e1ba2e5442d1367939fd5507a0cbc00
Signed-off-by: Ali Ahmed <ama213000@gmail.com>

* Review feedback changes

* review updates 2

---------

Signed-off-by: Wludzik, Jozef <jozef.wludzik@intel.com>
Signed-off-by: Krzysztof Grobelny <krzysztof.grobelny@intel.com>
Signed-off-by: Ali Ahmed <ama213000@gmail.com>
Co-authored-by: Krzysztof Grobelny <krzysztof.grobelny@intel.com>```

* Add support for MetricDefinition scheme

Added MetricDefinition node to Redfish code. Now user is able to list
all available metrics in OpenBMC that are supported by Telemetry
service. Metrics are grouped by reading type.

MetricDefinitions contains all physical sensors supported by redfish,
algorithm iterates through all chassis and collects results for each
node available in that chassis (Power, Thermal, Sensors).

When BMCWEB_NEW_POWERSUBSYSTEM_THERMALSUBSYSTEM will be enabled by
default (meson option redfish-new-powersubsystem-thermalsubsystem) it
will be possible to optimize this algorithm to only get sensors from
Sensors node. Currently Sensors node doesn't contain all available
sensors.

Removal of ResourceNotFound in sensors.hpp to fix MetricDefinition
Collection REST Get call.

Tested:
 - MetricDefinitions response is filled with existing sensors, it works
   with and without Telemetry service
 - Validated a presence of MetricDefinition members and its attributes
 - Successfully passed RedfishServiceValidator.py using witherspoon
   image on QEMU
 - Tested using following GET,POST requests

GET /redfish/v1/TelemetryService/MetricDefinitions
{
  "@odata.id": "/redfish/v1/TelemetryService/MetricDefinitions",
  "@odata.type": "#MetricDefinitionCollection.MetricDefinitionCollection",
  "Members": [
    {
      "@odata.id": "/redfish/v1/TelemetryService/MetricDefinitions/Fan_Pwm"
    },
    {
      "@odata.id": "/redfish/v1/TelemetryService/MetricDefinitions/Fan_Tach"
    },
    {
      "@odata.id": "/redfish/v1/TelemetryService/MetricDefinitions/HostCpuUtilization"
    },
    {
      "@odata.id": "/redfish/v1/TelemetryService/MetricDefinitions/HostMemoryBandwidthUtilization"
    },
    {
      "@odata.id": "/redfish/v1/TelemetryService/MetricDefinitions/HostPciBandwidthUtilization"
    },
    {
      "@odata.id": "/redfish/v1/TelemetryService/MetricDefinitions/Inlet_BRD_Temp"
    },
    {
      "@odata.id": "/redfish/v1/TelemetryService/MetricDefinitions/Left_Rear_Board_Temp"
    }
  ],
  "Members@odata.count": 7,
  "Name": "Metric Definition Collection"
}

GET /redfish/v1/TelemetryService/MetricDefinitions/Fan_Tach
{
  "@odata.id": "/redfish/v1/TelemetryService/MetricDefinitions/Fan_Tach",
  "@odata.type": "#MetricDefinition.v1_0_3.MetricDefinition",
  "Id": "Fan_Tach",
  "IsLinear": true,
  "MaxReadingRange": 25000.0,
  "MetricDataType": "Decimal",
  "MetricProperties": [
    "/redfish/v1/Chassis/AC_Baseboard/Thermal#/Fans/0/Reading",
    "/redfish/v1/Chassis/AC_Baseboard/Thermal#/Fans/1/Reading",
    "/redfish/v1/Chassis/AC_Baseboard/Thermal#/Fans/2/Reading",
    "/redfish/v1/Chassis/AC_Baseboard/Thermal#/Fans/3/Reading",
    "/redfish/v1/Chassis/AC_Baseboard/Thermal#/Fans/4/Reading",
    "/redfish/v1/Chassis/AC_Baseboard/Thermal#/Fans/5/Reading",
    "/redfish/v1/Chassis/AC_Baseboard/Thermal#/Fans/6/Reading",
    "/redfish/v1/Chassis/AC_Baseboard/Thermal#/Fans/7/Reading",
    "/redfish/v1/Chassis/AC_Baseboard/Thermal#/Fans/8/Reading",
    "/redfish/v1/Chassis/AC_Baseboard/Thermal#/Fans/9/Reading"
  ],
  "MetricType": "Gauge",
  "MinReadingRange": 0.0,
  "Name": "Fan_Tach",
  "Units": "RPM"
}

POST redfish/v1/TelemetryService/MetricReportDefinitions, body:
{
  "Id": "TestReport",
  "Metrics": [
    {
      "MetricId": "TestMetric",
      "MetricProperties": [
        "/redfish/v1/Chassis/Chassis0/Thermal#/Fans/3/Reading",
      ]
    }
  ],
  "MetricReportDefinitionType": "OnRequest",
  "ReportActions": [
    "RedfishEvent",
    "LogToMetricReportsCollection"
  ]
}
{
  "@Message.ExtendedInfo": [
    {
      "@odata.type": "#Message.v1_1_1.Message",
      "Message": "The resource has been created successfully",
      "MessageArgs": [],
      "MessageId": "Base.1.8.1.Created",
      "MessageSeverity": "OK",
      "Resolution": "None"
    }
  ]
}

Signed-off-by: Wludzik, Jozef <jozef.wludzik@intel.com>
Signed-off-by: Krzysztof Grobelny <krzysztof.grobelny@intel.com>
Change-Id: I3086e1302e1ba2e5442d1367939fd5507a0cbc00
Signed-off-by: Ali Ahmed <ama213000@gmail.com>

* Review feedback changes

* review updates 2

---------

Signed-off-by: Wludzik, Jozef <jozef.wludzik@intel.com>
Signed-off-by: Krzysztof Grobelny <krzysztof.grobelny@intel.com>
Signed-off-by: Ali Ahmed <ama213000@gmail.com>
Co-authored-by: Krzysztof Grobelny <krzysztof.grobelny@intel.com>
@rfrandse rfrandse force-pushed the 1120-metricDefinition branch 9 times, most recently from 0c0291e to d3e8d6e Compare May 15, 2025 19:26
@rfrandse rfrandse force-pushed the 1120-metricDefinition branch 4 times, most recently from 836ac1a to b29d627 Compare May 16, 2025 22:38
@rfrandse rfrandse force-pushed the 1120-metricDefinition branch from b29d627 to 84fefdc Compare May 17, 2025 00:10
@gtmills gtmills changed the title 1120: 1110: Add support for MetricDefinition scheme (#1088) 1120: Add support for MetricDefinition scheme (#1088) May 19, 2025
@rfrandse rfrandse requested a review from gtmills May 19, 2025 16:00
@gtmills gtmills requested a review from baemyung May 19, 2025 16:41

inline void requestRoutesMetricDefinition(App& app)
{
BMCWEB_ROUTE(app, "/redfish/v1/TelemetryService/MetricDefinitions/<str>/")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The new way to do this is these ROUTEs sit below and then a function for each route
e.g. https://github.com/openbmc/bmcweb/blob/master/redfish-core/lib/power_supply.hpp#L594

It would make this more readable


inline void requestRoutesMetricDefinitionCollection(App& app)
{
BMCWEB_ROUTE(app, "/redfish/v1/TelemetryService/MetricDefinitions/")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The new way to do this is these ROUTEs sit below and then a function for each route
e.g. https://github.com/openbmc/bmcweb/blob/master/redfish-core/lib/power_supply.hpp#L594

It would make this more readable

@gtmills
Copy link
Contributor

gtmills commented May 19, 2025

Might also be good to combine those 3 commits into 1 for tracking later in the spreadsheet

@rfrandse
Copy link
Collaborator Author

rfrandse commented May 19, 2025

Might also be good to combine those 3 commits into 1 for tracking later in the spreadsheet

I plan on merging the 3 commits together when the review is done. I thought it would be helpful to leave them separate for the review.

{

template <typename F>
inline void getChassisNames(F&& cb)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we add this function in redfish-core/include/utils/chassis_utils.hpp, and make the function without template ?

inline void getChassisNames(const boost::system::error_code& ec, 
                const std::vector<std::string>& chassisNames)
{
...
}


crow::connections::systemBus->async_method_call(
[callback = std::forward<F>(
cb)](const boost::system::error_code ec,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

const boost::system::error_code& ec

},
"xyz.openbmc_project.ObjectMapper",
"/xyz/openbmc_project/object_mapper",
"xyz.openbmc_project.ObjectMapper", "GetSubTreePaths",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

dbus::utility::getSubTreePaths()


callback(ec, value);
},
service2, path, "org.freedesktop.DBus.Properties", "Get",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

dbus::utility::getProperty(std::string>(...)

},
"xyz.openbmc_project.ObjectMapper",
"/xyz/openbmc_project/object_mapper",
"xyz.openbmc_project.ObjectMapper", "GetSubTree",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

dbus::utility::getSubTree()

{
sdbusplus::message::object_path sensorObjectPath{sensorPath};

const auto* const it = std::find_if(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

std::ranges::find_if(metricDefinitionMapping, 
                                 [&sensorObjectPath](const auto& item) {
            return item.first == sensorObjectPath.parent_path().filename();
        });

[](const crow::Request&,
const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
telemetry::mapRedfishUriToDbusPath(
[asyncResp](boost::system::error_code ec,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

const boost::system::error_code& ec,

}

template <class Callback>
inline void mapRedfishUriToDbusPath(Callback&& callback)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this can be more clearer without using template like

inline void mapRedfishUriToDbusPath(
         std::function<void (const boost::system::error_code& ec,
            const boost::container::flat_map<
                  std::string, std::string>& uriToDbus)>&& callback)
{
...
}

const std::shared_ptr<
bmcweb::AsyncResp>& asyncResp,
const std::string& name) {
telemetry::mapRedfishUriToDbusPath(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lambda body is long. It may be better to make it as a separate function

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants