[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PATCH v2 1/3] qmp: Support for querying stats
From: |
Mark Kanda |
Subject: |
[PATCH v2 1/3] qmp: Support for querying stats |
Date: |
Fri, 19 Nov 2021 13:51:51 -0600 |
Introduce qmp support for querying stats. Provide a framework for
adding new stats and support for the following commands:
- query-stats
Returns a list of all stats, with options for specifying a stat
name and schema type. A schema type is the set of stats associated
with a given component (e.g. vm or vcpu).
- query-stats-schemas
Returns a list of stats included in each schema type, with an
option for specifying the schema name.
- query-stats-instances
Returns a list of stat instances and their associated schema type.
The framework provides a method to register callbacks for these qmp
commands.
The first usecase will be for fd-based KVM stats (in an upcoming
patch).
Examples (with fd-based KVM stats):
{ "execute": "query-stats" }
{ "return": [
{ "name": "vcpu_1",
"type": "kvm-vcpu",
"stats": [
{ "name": "guest_mode",
"unit": "none",
"base": 10,
"val": [ 0 ],
"exponent": 0,
"type": "instant" },
{ "name": "directed_yield_successful",
"unit": "none",
"base": 10,
"val": [ 0 ],
"exponent": 0,
"type": "cumulative" },
...
},
{ "name": "vcpu_0",
"type": "kvm-vcpu",
"stats": ...
...
},
{ "name": "vm",
"type": "kvm-vm",
"stats": [
{ "name": "max_mmu_page_hash_collisions",
"unit": "none",
"base": 10,
"val": [ 0 ],
"exponent": 0,
"type": "peak" },
...
{ "execute": "query-stats-schemas" }
{ "return": [
{ "type": "kvm-vcpu",
"stats": [
{ "name": "guest_mode" },
{ "name": "directed_yield_successful" },
...
},
{ "type": "kvm-vm",
"stats": [
{ "name": "max_mmu_page_hash_collisions" },
{ "name": "max_mmu_rmap_size" },
...
{ "execute": "query-stats-instances" }
{ "return": [
{ "name": "vcpu_1",
"type": "kvm-vcpu" },
{ "name": "vcpu_0",
"type": "kvm-vcpu" },
{ "name": "vm",
"type": "kvm-vm" } ]
}
Signed-off-by: Mark Kanda <mark.kanda@oracle.com>
---
include/monitor/monitor.h | 27 ++++++++
monitor/qmp-cmds.c | 71 +++++++++++++++++++
qapi/misc.json | 142 ++++++++++++++++++++++++++++++++++++++
3 files changed, 240 insertions(+)
diff --git a/include/monitor/monitor.h b/include/monitor/monitor.h
index 12d395d62d..14d3432ade 100644
--- a/include/monitor/monitor.h
+++ b/include/monitor/monitor.h
@@ -56,4 +56,31 @@ void monitor_register_hmp(const char *name, bool info,
void monitor_register_hmp_info_hrt(const char *name,
HumanReadableText *(*handler)(Error
**errp));
+/*
+ * Add qmp stats callbacks to the stats_callbacks list.
+ *
+ * @name: name of stats callbacks
+ * @stats_fn: routine to query stats - with options for name and type:
+ * StatsList *(*stats_fn)(StatsList *list_tail, bool has_name,
+ * const char *name, bool has_type, const char *type, Error **errp)
+ *
+ * @schema_fn: routine to query stat schemas - with an option for type:
+ * StatsSchemaList *(*schemas_fn)(StatsSchemaList *list tail, bool has_type,
+ * const char *type, Error **errp)
+ *
+ * @instance_fn: routine to query stat instances:
+ * StatsInstanceList *(*instances_fn)(StatsInstanceList *list_tail,
+ * Error **errp)
+ */
+void add_stats_callbacks(const char *name,
+ StatsList *(*stats_fn)(StatsList *,
+ bool, const char *,
+ bool, const char *,
+ Error **),
+ StatsSchemaList *(*schemas_fn)(StatsSchemaList *,
+ bool, const char *,
+ Error **),
+ StatsInstanceList *(*instances_fn)(StatsInstanceList
*,
+ Error **));
+
#endif /* MONITOR_H */
diff --git a/monitor/qmp-cmds.c b/monitor/qmp-cmds.c
index 343353e27a..c7bdff1e1c 100644
--- a/monitor/qmp-cmds.c
+++ b/monitor/qmp-cmds.c
@@ -466,3 +466,74 @@ HumanReadableText *qmp_x_query_irq(Error **errp)
return human_readable_text_from_str(buf);
}
+
+typedef struct StatsCallbacks {
+ char *name;
+ StatsList *(*stats_cb)(StatsList *, bool, const char *, bool,
+ const char *, Error **);
+ StatsSchemaList *(*schemas_cb)(StatsSchemaList *, bool, const char *,
+ Error **);
+ StatsInstanceList *(*instances_cb)(StatsInstanceList *, Error **);
+ QTAILQ_ENTRY(StatsCallbacks) next;
+} StatsCallbacks;
+
+static QTAILQ_HEAD(, StatsCallbacks) stats_callbacks =
+ QTAILQ_HEAD_INITIALIZER(stats_callbacks);
+
+void add_stats_callbacks(const char *name,
+ StatsList *(*stats_fn)(StatsList *,
+ bool, const char *,
+ bool, const char *,
+ Error **),
+ StatsSchemaList *(*schemas_fn)(StatsSchemaList *,
+ bool, const char *,
+ Error **),
+ StatsInstanceList *(*instances_fn)(StatsInstanceList
*,
+ Error **))
+{
+ StatsCallbacks *entry = g_malloc0(sizeof(*entry));
+ entry->name = strdup(name);
+ entry->stats_cb = stats_fn;
+ entry->schemas_cb = schemas_fn;
+ entry->instances_cb = instances_fn;
+
+ QTAILQ_INSERT_TAIL(&stats_callbacks, entry, next);
+}
+
+StatsList *qmp_query_stats(bool has_name, const char *name, bool has_type,
+ const char *type, Error **errp) {
+ StatsList *list_tail = NULL;
+ StatsCallbacks *entry;
+
+ QTAILQ_FOREACH(entry, &stats_callbacks, next) {
+ list_tail = entry->stats_cb(list_tail, has_name, name,
+ has_type, type, errp);
+ }
+
+ return list_tail;
+}
+
+StatsSchemaList *qmp_query_stats_schemas(bool has_type, const char *type,
+ Error **errp)
+{
+ StatsSchemaList *list_tail = NULL;
+ StatsCallbacks *entry;
+
+ QTAILQ_FOREACH(entry, &stats_callbacks, next) {
+ list_tail = entry->schemas_cb(list_tail, has_type, type, errp);
+ }
+
+ return list_tail;
+}
+
+StatsInstanceList *qmp_query_stats_instances(Error **errp)
+{
+ StatsInstanceList *list_tail = NULL;
+ StatsCallbacks *entry;
+
+ QTAILQ_FOREACH(entry, &stats_callbacks, next) {
+ list_tail = entry->instances_cb(list_tail, errp);
+ }
+
+ return list_tail;
+}
diff --git a/qapi/misc.json b/qapi/misc.json
index 358548abe1..a0a07ef0b1 100644
--- a/qapi/misc.json
+++ b/qapi/misc.json
@@ -527,3 +527,145 @@
'data': { '*option': 'str' },
'returns': ['CommandLineOptionInfo'],
'allow-preconfig': true }
+
+##
+# @StatType:
+#
+# Enumeration of stat types
+# @cumulative: stat is cumulative; value can only increase.
+# @instant: stat is instantaneous; value can increase or decrease.
+# @peak: stat is the peak value; value can only increase.
+#
+# Since: 7.0
+##
+{ 'enum' : 'StatType',
+ 'data' : [ 'cumulative', 'instant', 'peak' ] }
+
+##
+# @StatUnit:
+#
+# Enumeration of stat units
+# @bytes: stat reported in bytes.
+# @seconds: stat reported in seconds.
+# @cycles: stat reported in clock cycles.
+# @none: no unit for this stat.
+#
+# Since: 7.0
+##
+{ 'enum' : 'StatUnit',
+ 'data' : [ 'bytes', 'seconds', 'cycles', 'none' ] }
+
+##
+# @StatData:
+#
+# Individual stat
+# @name: Stat name
+# @type: @StatType
+# @unit: @StatUnit
+# @base: Exponent base (2 or 10)
+# @exponent: Used together with @base
+# @val: List of uint64 values
+#
+# Since: 7.0
+##
+{ 'struct': 'StatData',
+ 'data': { 'name': 'str',
+ 'type': 'StatType',
+ 'unit': 'StatUnit',
+ 'base': 'uint8',
+ 'exponent': 'int16',
+ 'val': [ 'uint64' ] } }
+
+##
+# @Stats:
+#
+# Stats per resource (e.g. vm or vcpu)
+# @name: Resource name
+# @stats: List of @StatData
+#
+# Since: 7.0
+##
+{ 'struct': 'Stats',
+ 'data': {'name': 'str',
+ 'type': 'StatSchemaType',
+ 'stats': [ 'StatData' ] } }
+
+##
+# @query-stats:
+#
+# @name: Stat name (optional)
+# @type: Type name (optional)
+# Returns: List of @Stats
+#
+# Since: 7.0
+##
+{ 'command': 'query-stats',
+ 'data': { '*name': 'str', '*type': 'str' },
+ 'returns': [ 'Stats' ] }
+
+##
+# @StatSchemaType:
+#
+# Enumeration of stats schema types
+#
+# Since: 7.0
+##
+{ 'enum' : 'StatSchemaType',
+ 'data' : [ ] }
+
+##
+# @StatSchemaEntry:
+#
+# Individual stat in a schema type
+#
+# Since: 7.0
+##
+{ 'struct': 'StatSchemaEntry',
+ 'data': { 'name': 'str' } }
+
+##
+# @StatsSchema:
+#
+# Stats per @StatSchemaType
+# @type: @StatSchemaType
+# @stats: @StatCchemaName
+#
+# Since: 7.0
+##
+{ 'struct': 'StatsSchema',
+ 'data': { 'type': 'StatSchemaType',
+ 'stats': [ 'StatSchemaEntry' ] } }
+
+##
+# @query-stats-schemas:
+#
+# @type: type name (optional)
+# Returns: List of @StatsSchema
+#
+# Since: 7.0
+##
+{ 'command': 'query-stats-schemas',
+ 'data': { '*type': 'str' },
+ 'returns': [ 'StatsSchema' ] }
+
+##
+# @StatsInstance:
+#
+# @name: resource name
+# @type: @StatSchemaType
+#
+# Since: 7.0
+##
+{ 'struct': 'StatsInstance',
+ 'data': { 'name': 'str',
+ 'type': 'StatSchemaType' } }
+
+##
+# @query-stats-instances:
+#
+# Returns list of @StatsInstance
+#
+# Since: 7.0
+##
+{ 'command': 'query-stats-instances',
+ 'returns': [ 'StatsInstance' ] }
--
2.26.2