Anush Nadathur | 8f2a4d2 | 2024-02-26 03:48:13 +0530 | [diff] [blame] | 1 | /* |
| 2 | * |
| 3 | * Copyright (c) 2024 Project CHIP Authors |
| 4 | * All rights reserved. |
| 5 | * |
| 6 | * Licensed under the Apache License, Version 2.0 (the "License"); |
| 7 | * you may not use this file except in compliance with the License. |
| 8 | * You may obtain a copy of the License at |
| 9 | * |
| 10 | * http://www.apache.org/licenses/LICENSE-2.0 |
| 11 | * |
| 12 | * Unless required by applicable law or agreed to in writing, software |
| 13 | * distributed under the License is distributed on an "AS IS" BASIS, |
| 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 15 | * See the License for the specific language governing permissions and |
| 16 | * limitations under the License. |
| 17 | */ |
| 18 | #pragma once |
| 19 | |
| 20 | #include <lib/core/CHIPError.h> |
| 21 | #include <lib/support/CodeUtils.h> |
| 22 | #include <matter/tracing/build_config.h> |
| 23 | |
| 24 | #define __LOG_METRIC_CONCAT_IMPL(a, b) a##b |
| 25 | #define __LOG_METRIC_MACRO_CONCAT(a, b) __LOG_METRIC_CONCAT_IMPL(a, b) |
| 26 | |
| 27 | #if MATTER_TRACING_ENABLED |
| 28 | |
| 29 | /** |
Anush Nadathur | 9343d3a | 2024-03-13 14:19:35 -0700 | [diff] [blame] | 30 | * @def ReturnErrorOnFailureWithMetric(kMetricKey, expr) |
| 31 | * |
| 32 | * @brief |
| 33 | * This macros emits the specified metric with error code and returns the error code, |
| 34 | * if the expression returns an error. For a CHIP_ERROR expression, this means any value |
| 35 | * other than CHIP_NO_ERROR. For an integer expression, this means non-zero. |
| 36 | * |
| 37 | * Example usage: |
| 38 | * |
| 39 | * @code |
| 40 | * ReturnErrorOnFailureWithMetric(kMetricKey, channel->SendMsg(msg)); |
| 41 | * @endcode |
| 42 | * |
| 43 | * @param[in] kMetricKey Metric key for the metric event to be emitted if the expr evaluates |
| 44 | * does not evaluate to CHIP_NO_ERROR. Value of the metric is to the |
| 45 | * result of the expression. |
| 46 | * @param[in] expr An expression to be tested. |
| 47 | */ |
| 48 | #define ReturnErrorOnFailureWithMetric(kMetricKey, expr) \ |
| 49 | do \ |
| 50 | { \ |
| 51 | auto __err = (expr); \ |
| 52 | if (!::chip::ChipError::IsSuccess(__err)) \ |
| 53 | { \ |
| 54 | MATTER_LOG_METRIC(kMetricKey, __err); \ |
| 55 | return __err; \ |
| 56 | } \ |
| 57 | } while (false) |
| 58 | |
| 59 | /** |
| 60 | * @def ReturnLogErrorOnFailureWithMetric(kMetricKey, expr) |
| 61 | * |
| 62 | * @brief |
| 63 | * Returns the error code if the expression returns something different |
| 64 | * than CHIP_NO_ERROR. In addition, a metric is emitted with the specified metric key and |
| 65 | * error code as the value of the metric. |
| 66 | * |
| 67 | * Example usage: |
| 68 | * |
| 69 | * @code |
| 70 | * ReturnLogErrorOnFailureWithMetric(kMetricKey, channel->SendMsg(msg)); |
| 71 | * @endcode |
| 72 | * |
| 73 | * @param[in] kMetricKey Metric key for the metric event to be emitted if the expr evaluates |
| 74 | * does not evaluate to CHIP_NO_ERROR. Value of the metric is to the |
| 75 | * result of the expression. |
| 76 | * @param[in] expr A scalar expression to be evaluated against CHIP_NO_ERROR. |
| 77 | */ |
| 78 | #define ReturnLogErrorOnFailureWithMetric(kMetricKey, expr) \ |
| 79 | do \ |
| 80 | { \ |
| 81 | CHIP_ERROR __err = (expr); \ |
| 82 | if (__err != CHIP_NO_ERROR) \ |
| 83 | { \ |
| 84 | MATTER_LOG_METRIC(kMetricKey, __err); \ |
| 85 | ChipLogError(NotSpecified, "%s at %s:%d", ErrorStr(__err), __FILE__, __LINE__); \ |
| 86 | return __err; \ |
| 87 | } \ |
| 88 | } while (false) |
| 89 | |
| 90 | /** |
| 91 | * @def ReturnOnFailureWithMetric(kMetricKey, expr) |
| 92 | * |
| 93 | * @brief |
| 94 | * Returns if the expression returns an error. For a CHIP_ERROR expression, this means any value other |
| 95 | * than CHIP_NO_ERROR. For an integer expression, this means non-zero. If the expression evaluates to |
| 96 | * anything but CHIP_NO_ERROR, a metric with the specified key is emitted along with error as the value. |
| 97 | * |
| 98 | * Example usage: |
| 99 | * |
| 100 | * @code |
| 101 | * ReturnOnFailureWithMetric(kMetricKey, channel->SendMsg(msg)); |
| 102 | * @endcode |
| 103 | * |
| 104 | * @param[in] kMetricKey Metric key for the metric event to be emitted if the expr evaluates |
| 105 | * does not evaluate to CHIP_NO_ERROR. Value of the metric is to the |
| 106 | * result of the expression. |
| 107 | * @param[in] expr An expression to be tested. |
| 108 | */ |
| 109 | #define ReturnOnFailureWithMetric(kMetricKey, expr) \ |
| 110 | do \ |
| 111 | { \ |
| 112 | auto __err = (expr); \ |
| 113 | if (!::chip::ChipError::IsSuccess(__err)) \ |
| 114 | { \ |
| 115 | MATTER_LOG_METRIC(kMetricKey, __err); \ |
| 116 | return; \ |
| 117 | } \ |
| 118 | } while (false) |
| 119 | |
| 120 | /** |
| 121 | * @def VerifyOrReturnWithMetric(kMetricKey, expr, ...) |
| 122 | * |
| 123 | * @brief |
| 124 | * Returns from the void function if expression evaluates to false. If the expression evaluates |
| 125 | * to false, a metric with the specified key is emitted. |
| 126 | * |
| 127 | * Example usage: |
| 128 | * |
| 129 | * @code |
| 130 | * VerifyOrReturnWithMetric(kMetricKey, param != nullptr, LogError("param is nullptr")); |
| 131 | * @endcode |
| 132 | * |
| 133 | * @param[in] kMetricKey Metric key for the metric event to be emitted if the expr evaluates |
| 134 | * to false. Value of the metric is set to false. |
| 135 | * @param[in] expr A Boolean expression to be evaluated. |
| 136 | * @param[in] ... Statements to execute before returning. Optional. |
| 137 | */ |
| 138 | #define VerifyOrReturnWithMetric(kMetricKey, expr, ...) \ |
| 139 | do \ |
| 140 | { \ |
| 141 | if (!(expr)) \ |
| 142 | { \ |
| 143 | MATTER_LOG_METRIC(kMetricKey, false); \ |
| 144 | __VA_ARGS__; \ |
| 145 | return; \ |
| 146 | } \ |
| 147 | } while (false) |
| 148 | |
| 149 | /** |
| 150 | * @def VerifyOrReturnErrorWithMetric(kMetricKey, expr, code, ...) |
| 151 | * |
| 152 | * @brief |
| 153 | * Returns a specified error code if expression evaluates to false. If the expression evaluates |
| 154 | * to false, a metric with the specified key is emitted with the value set to the code. |
| 155 | * |
| 156 | * Example usage: |
| 157 | * |
| 158 | * @code |
| 159 | * VerifyOrReturnErrorWithMetric(kMetricKey, param != nullptr, CHIP_ERROR_INVALID_ARGUMENT); |
| 160 | * @endcode |
| 161 | * |
| 162 | * @param[in] kMetricKey Metric key for the metric event to be emitted if the expr evaluates |
| 163 | * to false. Value of the metric is to code. |
| 164 | * @param[in] expr A Boolean expression to be evaluated. |
| 165 | * @param[in] code A value to return if @a expr is false. |
| 166 | * @param[in] ... Statements to execute before returning. Optional. |
| 167 | */ |
| 168 | #define VerifyOrReturnErrorWithMetric(kMetricKey, expr, code, ...) \ |
| 169 | VerifyOrReturnValueWithMetric(kMetricKey, expr, code, ##__VA_ARGS__) |
| 170 | |
| 171 | /** |
| 172 | * @def VerifyOrReturnValueWithMetric(kMetricKey, expr, value, ...) |
| 173 | * |
| 174 | * @brief |
| 175 | * Returns a specified value if expression evaluates to false. If the expression evaluates |
| 176 | * to false, a metric with the specified key is emitted with the value set to value. |
| 177 | * |
| 178 | * Example usage: |
| 179 | * |
| 180 | * @code |
| 181 | * VerifyOrReturnValueWithMetric(kMetricKey, param != nullptr, Foo()); |
| 182 | * @endcode |
| 183 | * |
| 184 | * @param[in] kMetricKey Metric key for the metric event to be emitted if the expr evaluates |
| 185 | * to false. Value of the metric is to value. |
| 186 | * @param[in] expr A Boolean expression to be evaluated. |
| 187 | * @param[in] value A value to return if @a expr is false. |
| 188 | * @param[in] ... Statements to execute before returning. Optional. |
| 189 | */ |
| 190 | #define VerifyOrReturnValueWithMetric(kMetricKey, expr, value, ...) \ |
| 191 | do \ |
| 192 | { \ |
| 193 | if (!(expr)) \ |
| 194 | { \ |
| 195 | MATTER_LOG_METRIC(kMetricKey, value); \ |
| 196 | __VA_ARGS__; \ |
| 197 | return (value); \ |
| 198 | } \ |
| 199 | } while (false) |
| 200 | |
| 201 | /** |
| 202 | * @def VerifyOrReturnLogErrorWithMetric(kMetricKey, expr, code) |
| 203 | * |
| 204 | * @brief |
| 205 | * Returns and print a specified error code if expression evaluates to false. |
| 206 | * If the expression evaluates to false, a metric with the specified key is emitted |
| 207 | * with the value set to code. |
| 208 | * |
| 209 | * Example usage: |
| 210 | * |
| 211 | * @code |
| 212 | * VerifyOrReturnLogErrorWithMetric(kMetricKey, param != nullptr, CHIP_ERROR_INVALID_ARGUMENT); |
| 213 | * @endcode |
| 214 | * |
| 215 | * @param[in] kMetricKey Metric key for the metric event to be emitted if the expr evaluates |
| 216 | * to false. Value of the metric is to code. |
| 217 | * @param[in] expr A Boolean expression to be evaluated. |
| 218 | * @param[in] code A value to return if @a expr is false. |
| 219 | */ |
| 220 | #if CHIP_CONFIG_ERROR_SOURCE |
| 221 | #define VerifyOrReturnLogErrorWithMetric(kMetricKey, expr, code) \ |
| 222 | do \ |
| 223 | { \ |
| 224 | if (!(expr)) \ |
| 225 | { \ |
| 226 | MATTER_LOG_METRIC(kMetricKey, code); \ |
| 227 | ChipLogError(NotSpecified, "%s at %s:%d", ErrorStr(code), __FILE__, __LINE__); \ |
| 228 | return code; \ |
| 229 | } \ |
| 230 | } while (false) |
| 231 | #else // CHIP_CONFIG_ERROR_SOURCE |
| 232 | #define VerifyOrReturnLogErrorWithMetric(kMetricKey, expr, code) \ |
| 233 | do \ |
| 234 | { \ |
| 235 | if (!(expr)) \ |
| 236 | { \ |
| 237 | MATTER_LOG_METRIC(kMetricKey, code); \ |
| 238 | ChipLogError(NotSpecified, "%s:%d false: %" CHIP_ERROR_FORMAT, #expr, __LINE__, code.Format()); \ |
| 239 | return code; \ |
| 240 | } \ |
| 241 | } while (false) |
| 242 | #endif // CHIP_CONFIG_ERROR_SOURCE |
| 243 | |
| 244 | /** |
| 245 | * @def ReturnErrorCodeWithMetricIf(kMetricKey, expr, code) |
| 246 | * |
| 247 | * @brief |
| 248 | * Returns a specified error code if expression evaluates to true |
| 249 | * If the expression evaluates to true, a metric with the specified key is emitted |
| 250 | * with the value set to code. |
| 251 | * |
| 252 | * Example usage: |
| 253 | * |
| 254 | * @code |
| 255 | * ReturnErrorCodeWithMetricIf(kMetricKey, state == kInitialized, CHIP_NO_ERROR); |
| 256 | * ReturnErrorCodeWithMetricIf(kMetricKey, state == kInitialized, CHIP_ERROR_INCORRECT_STATE); |
| 257 | * @endcode |
| 258 | * |
| 259 | * @param[in] kMetricKey Metric key for the metric event to be emitted if the expr evaluates |
| 260 | * to true. Value of the metric is to code. |
| 261 | * @param[in] expr A Boolean expression to be evaluated. |
| 262 | * @param[in] code A value to return if @a expr is false. |
| 263 | */ |
| 264 | #define ReturnErrorCodeWithMetricIf(kMetricKey, expr, code) \ |
| 265 | do \ |
| 266 | { \ |
| 267 | if (expr) \ |
| 268 | { \ |
| 269 | MATTER_LOG_METRIC(kMetricKey, code); \ |
| 270 | return code; \ |
| 271 | } \ |
| 272 | } while (false) |
| 273 | |
| 274 | /** |
| 275 | * @def SuccessOrExitWithMetric(kMetricKey, error) |
Anush Nadathur | 8f2a4d2 | 2024-02-26 03:48:13 +0530 | [diff] [blame] | 276 | * |
| 277 | * @brief |
| 278 | * This checks for the specified error, which is expected to |
| 279 | * commonly be successful (CHIP_NO_ERROR), and branches to |
| 280 | * the local label 'exit' if the error is not success. |
Anush Nadathur | 9343d3a | 2024-03-13 14:19:35 -0700 | [diff] [blame] | 281 | * If error is not a success, a metric with key kMetricKey is emitted with |
Anush Nadathur | 8f2a4d2 | 2024-02-26 03:48:13 +0530 | [diff] [blame] | 282 | * the error code as the value of the metric. |
| 283 | * |
| 284 | * Example Usage: |
| 285 | * |
| 286 | * @code |
| 287 | * CHIP_ERROR TryHard() |
| 288 | * { |
| 289 | * CHIP_ERROR err; |
| 290 | * |
| 291 | * err = TrySomething(); |
| 292 | * SuccessOrExitWithMetric(kMetricKey, err); |
| 293 | * |
| 294 | * err = TrySomethingElse(); |
| 295 | * SuccessOrExitWithMetric(kMetricKey, err); |
| 296 | * |
| 297 | * exit: |
| 298 | * return err; |
| 299 | * } |
| 300 | * @endcode |
| 301 | * |
| 302 | * @param[in] kMetricKey Metric key for the metric event to be emitted |
| 303 | * if the condition evaluates to false. The value |
| 304 | * for the metric is result of the expression aStatus. |
| 305 | * @param[in] error A ChipError object to be evaluated against success (CHIP_NO_ERROR). |
| 306 | * |
| 307 | */ |
| 308 | #define SuccessOrExitWithMetric(kMetricKey, error) \ |
| 309 | nlEXPECT(::chip::Tracing::ErrorHandling::LogMetricIfError((kMetricKey), (error)), exit) |
| 310 | |
| 311 | /** |
| 312 | * @def VerifyOrExitWithMetric(kMetricKey, aCondition, anAction) |
| 313 | * |
| 314 | * @brief |
| 315 | * This checks for the specified condition, which is expected to |
| 316 | * commonly be true, and both executes @a anAction and branches to |
| 317 | * the local label 'exit' if the condition is false. If the condition |
| 318 | * is false a metric event with the specified key is emitted with value |
| 319 | * set to the result of the expression anAction. |
| 320 | * |
| 321 | * Example Usage: |
| 322 | * |
| 323 | * @code |
| 324 | * CHIP_ERROR MakeBuffer(const uint8_t *& buf) |
| 325 | * { |
| 326 | * CHIP_ERROR err = CHIP_NO_ERROR; |
| 327 | * |
| 328 | * buf = (uint8_t *)malloc(1024); |
| 329 | * VerifyOrExitWithMetric(kMetricKey, buf != NULL, err = CHIP_ERROR_NO_MEMORY); |
| 330 | * |
| 331 | * memset(buf, 0, 1024); |
| 332 | * |
| 333 | * exit: |
| 334 | * return err; |
| 335 | * } |
| 336 | * @endcode |
| 337 | * |
| 338 | * @param[in] kMetricKey Metric key for the metric event to be emitted |
| 339 | * if the aCondition evaluates to false. The value |
| 340 | * for the metric is result of the expression anAction. |
| 341 | * @param[in] aCondition A Boolean expression to be evaluated. |
| 342 | * @param[in] anAction An expression or block to execute when the |
| 343 | * assertion fails. |
| 344 | */ |
| 345 | #define VerifyOrExitWithMetric(kMetricKey, aCondition, anAction) \ |
| 346 | nlEXPECT_ACTION(aCondition, exit, MATTER_LOG_METRIC((kMetricKey), (anAction))) |
| 347 | |
Anush Nadathur | 9343d3a | 2024-03-13 14:19:35 -0700 | [diff] [blame] | 348 | /** |
| 349 | * @def ExitNowWithMetric(kMetricKey, ...) |
| 350 | * |
| 351 | * @brief |
| 352 | * This unconditionally executes @a ... and branches to the local |
| 353 | * label 'exit'. In addition a metric is emitted with the specified key. |
| 354 | * |
| 355 | * @note The use of this interface implies neither success nor |
| 356 | * failure for the overall exit status of the enclosing function |
| 357 | * body. |
| 358 | * |
| 359 | * Example Usage: |
| 360 | * |
| 361 | * @code |
| 362 | * CHIP_ERROR ReadAll(Reader& reader) |
| 363 | * { |
| 364 | * CHIP_ERROR err; |
| 365 | * |
| 366 | * while (true) |
| 367 | * { |
| 368 | * err = reader.ReadNext(); |
| 369 | * if (err == CHIP_ERROR_AT_END) |
| 370 | * ExitNowWithMetric(kMetricKey, err = CHIP_NO_ERROR); |
| 371 | * SuccessOrExit(err); |
| 372 | * DoSomething(); |
| 373 | * } |
| 374 | * |
| 375 | * exit: |
| 376 | * return err; |
| 377 | * } |
| 378 | * @endcode |
| 379 | * |
| 380 | * @param[in] kMetricKey Metric key for the metric event to be emitted. |
| 381 | * @param[in] ... Statements to execute. Optional. |
Anush Nadathur | 8f2a4d2 | 2024-02-26 03:48:13 +0530 | [diff] [blame] | 382 | */ |
Anush Nadathur | 9343d3a | 2024-03-13 14:19:35 -0700 | [diff] [blame] | 383 | #define ExitNowWithMetric(kMetricKey, ...) \ |
| 384 | do \ |
| 385 | { \ |
| 386 | MATTER_LOG_METRIC(kMetricKey); \ |
| 387 | __VA_ARGS__; \ |
| 388 | goto exit; \ |
| 389 | } while (0) |
| 390 | |
| 391 | /** |
| 392 | * @def LogErrorOnFailureWithMetric(kMetricKey, expr) |
| 393 | * |
| 394 | * @brief |
| 395 | * Logs a message if the expression returns something different than CHIP_NO_ERROR. |
| 396 | * In addition, a metric is emitted with the specified key and value set to result |
| 397 | * of the expression in case it evaluates to anything other than CHIP_NO_ERROR. |
| 398 | * |
| 399 | * Example usage: |
| 400 | * |
| 401 | * @code |
| 402 | * LogErrorOnFailureWithMetric(kMetricKey, channel->SendMsg(msg)); |
| 403 | * @endcode |
| 404 | * |
| 405 | * @param[in] kMetricKey Metric key for the metric event to be emitted if the expr evaluates |
| 406 | * does not evaluate to CHIP_NO_ERROR. Value of the metric is to the |
| 407 | * result of the expression. |
| 408 | * @param[in] expr A scalar expression to be evaluated against CHIP_NO_ERROR. |
| 409 | */ |
| 410 | #define LogErrorOnFailureWithMetric(kMetricKey, expr) \ |
| 411 | do \ |
| 412 | { \ |
| 413 | CHIP_ERROR __err = (expr); \ |
| 414 | if (__err != CHIP_NO_ERROR) \ |
| 415 | { \ |
| 416 | MATTER_LOG_METRIC(kMetricKey, __err); \ |
| 417 | ChipLogError(NotSpecified, "%s at %s:%d", ErrorStr(__err), __FILE__, __LINE__); \ |
| 418 | } \ |
| 419 | } while (false) |
| 420 | |
| 421 | /** |
| 422 | * @def VerifyOrDoWithMetric(kMetricKey, expr, ...) |
| 423 | * |
| 424 | * @brief |
| 425 | * Do something if expression evaluates to false. If the expression evaluates to false a metric |
| 426 | * with the specified key is emitted with value set to false. |
| 427 | * |
| 428 | * Example usage: |
| 429 | * |
| 430 | * @code |
| 431 | * VerifyOrDoWithMetric(param != nullptr, LogError("param is nullptr")); |
| 432 | * @endcode |
| 433 | * |
| 434 | * @param[in] kMetricKey Metric key for the metric event to be emitted. |
| 435 | * Value of the metric is set to false. |
| 436 | * @param[in] expr A Boolean expression to be evaluated. |
Anush Nadathur | 443bb9c | 2024-05-17 14:54:38 -0700 | [diff] [blame] | 437 | * @param[in] code Error code to emit as part of the metric. |
Anush Nadathur | 9343d3a | 2024-03-13 14:19:35 -0700 | [diff] [blame] | 438 | * @param[in] ... Statements to execute. |
| 439 | */ |
Anush Nadathur | 443bb9c | 2024-05-17 14:54:38 -0700 | [diff] [blame] | 440 | #define VerifyOrDoWithMetric(kMetricKey, expr, code, ...) \ |
Anush Nadathur | 9343d3a | 2024-03-13 14:19:35 -0700 | [diff] [blame] | 441 | do \ |
| 442 | { \ |
| 443 | if (!(expr)) \ |
| 444 | { \ |
Anush Nadathur | 443bb9c | 2024-05-17 14:54:38 -0700 | [diff] [blame] | 445 | MATTER_LOG_METRIC(kMetricKey, code); \ |
Anush Nadathur | 9343d3a | 2024-03-13 14:19:35 -0700 | [diff] [blame] | 446 | __VA_ARGS__; \ |
| 447 | } \ |
| 448 | } while (false) |
| 449 | |
| 450 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////// |
| 451 | // Utility Macros to support optional arguments for MATTER_LOG_METRIC_XYZ macros |
| 452 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////// |
Anush Nadathur | 8f2a4d2 | 2024-02-26 03:48:13 +0530 | [diff] [blame] | 453 | |
| 454 | // Utility to always return the 4th argument from macro parameters |
| 455 | #define __GET_4TH_ARG(_a1, _a2, _a3, _a4, ...) _a4 |
| 456 | |
| 457 | // Utility macro to select the macro with the correct signature based on the invoked MATTER_LOG_METRIC_XYZ macro |
| 458 | #define __SELECT_MACRO_FOR_EVENT_METRIC(...) \ |
| 459 | __GET_4TH_ARG(__VA_ARGS__, __MATTER_LOG_METRIC_3ARGS, __MATTER_LOG_METRIC_2ARGS, __MATTER_LOG_METRIC_1ARGS, ) |
| 460 | |
| 461 | // Wrapper to capture all arguments and invoke the real wrapper for logging metrics |
| 462 | #define __MATTER_LOG_METRIC(...) __SELECT_MACRO_FOR_EVENT_METRIC(__VA_ARGS__)(__VA_ARGS__) |
| 463 | |
| 464 | // Wrapper macro that accepts metric key and logs and instant event |
| 465 | #define __MATTER_LOG_METRIC_1ARGS(key) \ |
| 466 | do \ |
| 467 | { \ |
| 468 | using Type = chip::Tracing::MetricEvent::Type; \ |
| 469 | ::chip::Tracing::MetricEvent _metric_event(Type::kInstantEvent, key); \ |
| 470 | ::chip::Tracing::Internal::LogMetricEvent(_metric_event); \ |
| 471 | } while (false) |
| 472 | |
| 473 | // Wrapper macro that accepts metric type and key and logs an event corresponding to the type |
| 474 | #define __MATTER_LOG_METRIC_2ARGS(type, key) \ |
| 475 | do \ |
| 476 | { \ |
| 477 | ::chip::Tracing::MetricEvent _metric_event(type, key); \ |
| 478 | ::chip::Tracing::Internal::LogMetricEvent(_metric_event); \ |
| 479 | } while (false) |
| 480 | |
| 481 | // Wrapper macro that accepts metric type, key and value and logs the corresponding event |
| 482 | #define __MATTER_LOG_METRIC_3ARGS(type, key, value) \ |
| 483 | do \ |
| 484 | { \ |
| 485 | ::chip::Tracing::MetricEvent _metric_event(type, key, value); \ |
| 486 | ::chip::Tracing::Internal::LogMetricEvent(_metric_event); \ |
| 487 | } while (false) |
| 488 | |
| 489 | //////////////////////// |
| 490 | // Metric logging macros |
| 491 | //////////////////////// |
| 492 | |
| 493 | /** |
| 494 | * @def MATTER_LOG_METRIC |
| 495 | * |
| 496 | * @brief |
| 497 | * When tracing is enabled, this macro generates a metric event and logs it to the tracing backend. |
| 498 | * |
| 499 | * Example usage: |
| 500 | * @code |
| 501 | * MATTER_LOG_METRIC(chip::Tracing::kMetricPASESession, err); |
| 502 | * @endcode |
| 503 | * The above example generates an instant metric event with key kMetricPASESession. |
| 504 | * The metric also holds the 32 bit value corresponding to the ChipError object 'err'. |
| 505 | * |
| 506 | * @param[in] key The key representing the metric name/event. |
| 507 | * |
| 508 | * @param[in] value An optional value for the metric. This value corresponds to one of the values supported |
| 509 | * in MetricEvent::Value |
| 510 | */ |
| 511 | #define MATTER_LOG_METRIC(key, ...) __MATTER_LOG_METRIC(chip::Tracing::MetricEvent::Type::kInstantEvent, key, ##__VA_ARGS__) |
| 512 | |
| 513 | /** |
| 514 | * @def MATTER_LOG_METRIC_BEGIN |
| 515 | * |
| 516 | * @brief |
| 517 | * Generate a metric with the Begin Type |
| 518 | * |
| 519 | * Example usage: |
| 520 | * @code |
| 521 | * MATTER_LOG_METRIC_BEGIN(chip::Tracing::kMetricPASESession); |
| 522 | * @endcode |
| 523 | * The above example generates a Begin metric event with key kMetricPASESession. |
| 524 | * |
| 525 | * @param[in] key The key representing the metric name/event. |
| 526 | */ |
| 527 | #define MATTER_LOG_METRIC_BEGIN(key) __MATTER_LOG_METRIC(chip::Tracing::MetricEvent::Type::kBeginEvent, key) |
| 528 | |
| 529 | /** |
| 530 | * @def MATTER_LOG_METRIC_END |
| 531 | * |
| 532 | * @brief |
| 533 | * Generate a metric with the End Type |
| 534 | * |
| 535 | * Example usage: |
| 536 | * @code |
| 537 | * MATTER_LOG_METRIC_END(chip::Tracing::kMetricPASESession); |
| 538 | * @endcode |
| 539 | * The above example generates an End metric event with key kMetricPASESession. |
| 540 | * |
| 541 | * @param[in] key The key representing the metric name/event. |
| 542 | * |
| 543 | * @param[in] value An optional value for the metric. This value corresponds to one of the values supported |
| 544 | * in MetricEvent::Value |
| 545 | */ |
| 546 | #define MATTER_LOG_METRIC_END(key, ...) __MATTER_LOG_METRIC(chip::Tracing::MetricEvent::Type::kEndEvent, key, ##__VA_ARGS__) |
| 547 | |
| 548 | /** |
| 549 | * @def MATTER_LOG_METRIC_SCOPE |
| 550 | * |
| 551 | * @brief |
| 552 | * Generate a scoped metric tracking Begin and End within a given scope. |
| 553 | * |
| 554 | * Example usage: |
| 555 | * @code |
| 556 | * MATTER_LOG_METRIC_SCOPE(chip::Tracing::kMetricPASESession); |
| 557 | * @endcode |
| 558 | * The above example generates an Begin and the End metric using RAII. |
| 559 | * |
| 560 | * @param[in] key The key representing the metric name/event. |
| 561 | * @param[in] error Reference to a ChipError object that is used as the value of the End event. |
| 562 | */ |
| 563 | #define MATTER_LOG_METRIC_SCOPE(key, error) \ |
| 564 | ::chip::Tracing::ScopedMetricEvent __LOG_METRIC_MACRO_CONCAT(_metric_scope, __COUNTER__)(key, error) |
| 565 | |
| 566 | #else // Tracing is disabled |
| 567 | |
| 568 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////// |
| 569 | // Remap Success, Return, and Verify macros to the ones without metrics |
| 570 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////// |
| 571 | |
Anush Nadathur | 9343d3a | 2024-03-13 14:19:35 -0700 | [diff] [blame] | 572 | #define ReturnErrorOnFailureWithMetric(kMetricKey, expr) ReturnErrorOnFailure(expr) |
| 573 | |
| 574 | #define ReturnLogErrorOnFailureWithMetric(kMetricKey, expr) ReturnLogErrorOnFailure(expr) |
| 575 | |
| 576 | #define ReturnOnFailureWithMetric(kMetricKey, expr) ReturnOnFailure(expr) |
| 577 | |
| 578 | #define VerifyOrReturnWithMetric(kMetricKey, expr, ...) VerifyOrReturn(expr, ##__VA_ARGS__) |
| 579 | |
| 580 | #define VerifyOrReturnErrorWithMetric(kMetricKey, expr, code, ...) VerifyOrReturnValue(expr, code, ##__VA_ARGS__) |
| 581 | |
| 582 | #define VerifyOrReturnValueWithMetric(kMetricKey, expr, value, ...) VerifyOrReturnValue(expr, value, ##__VA_ARGS__) |
| 583 | |
| 584 | #define VerifyOrReturnLogErrorWithMetric(kMetricKey, expr, code) VerifyOrReturnLogError(expr, code) |
| 585 | |
| 586 | #define ReturnErrorCodeWithMetricIf(kMetricKey, expr, code) ReturnErrorCodeIf(expr, code) |
| 587 | |
Anush Nadathur | 8f2a4d2 | 2024-02-26 03:48:13 +0530 | [diff] [blame] | 588 | #define SuccessOrExitWithMetric(kMetricKey, aStatus) SuccessOrExit(aStatus) |
| 589 | |
| 590 | #define VerifyOrExitWithMetric(kMetricKey, aCondition, anAction) VerifyOrExit(aCondition, anAction) |
| 591 | |
Anush Nadathur | 9343d3a | 2024-03-13 14:19:35 -0700 | [diff] [blame] | 592 | #define ExitNowWithMetric(kMetricKey, ...) ExitNow(##__VA_ARGS__) |
| 593 | |
| 594 | #define LogErrorOnFailureWithMetric(kMetricKey, expr) LogErrorOnFailure(expr) |
| 595 | |
Anush Nadathur | 443bb9c | 2024-05-17 14:54:38 -0700 | [diff] [blame] | 596 | #define VerifyOrDoWithMetric(kMetricKey, expr, code, ...) VerifyOrDo(expr, ##__VA_ARGS__) |
Anush Nadathur | 9343d3a | 2024-03-13 14:19:35 -0700 | [diff] [blame] | 597 | |
Anush Nadathur | 8f2a4d2 | 2024-02-26 03:48:13 +0530 | [diff] [blame] | 598 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////// |
| 599 | // Map all MATTER_LOG_METRIC_XYZ macros to noops |
| 600 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////// |
| 601 | |
| 602 | #define __MATTER_LOG_METRIC_DISABLE(...) \ |
| 603 | do \ |
| 604 | { \ |
| 605 | } while (false) |
| 606 | |
| 607 | #define MATTER_LOG_METRIC(...) __MATTER_LOG_METRIC_DISABLE(__VA_ARGS__) |
| 608 | #define MATTER_LOG_METRIC_BEGIN(...) __MATTER_LOG_METRIC_DISABLE(__VA_ARGS__) |
| 609 | #define MATTER_LOG_METRIC_END(...) __MATTER_LOG_METRIC_DISABLE(__VA_ARGS__) |
| 610 | #define MATTER_LOG_METRIC_SCOPE(...) __MATTER_LOG_METRIC_DISABLE(__VA_ARGS__) |
| 611 | |
| 612 | #endif // MATTER_TRACING_ENABLED |