diff --git a/docs/metrics.md b/docs/metrics.md
index 4a797ef6ee2..dbed6a590b1 100644
--- a/docs/metrics.md
+++ b/docs/metrics.md
@@ -77,3 +77,56 @@ Otherwise, if the path points to a normal file, you can simply do:
```shell script
cat metrics.file
```
+
+## Metrics emitted by Firecracker
+
+The metrics emitted by Firecracker are in JSON format.
+Below are the keys present in each metrics json object emitted by Firecracker:
+
+```
+"api_server"
+"balloon"
+"block"
+"deprecated_api"
+"entropy"
+"get_api_requests"
+"i8042"
+"latencies_us"
+"logger"
+"mmds"
+"net"
+"patch_api_requests"
+"put_api_requests"
+"rtc"
+"seccomp"
+"signals"
+"uart"
+"vcpu"
+"vhost_user_block"
+"vmm"
+"vsock"
+```
+
+Below table explains where Firecracker metrics are defined :
+
+| Metrics key | Device | Additional comments |
+|-------|-------|-------|
+| balloon | [BalloonDeviceMetrics](../src/vmm/src/devices/virtio/balloon/metrics.rs) | Respresent metrics for the Balloon device.|
+| block | [BlockDeviceMetrics](../src/vmm/src/devices/virtio/virtio_block/metrics.rs) | Respresent aggregate metrics for Virtio Block device.|
+| block_{block_drive_id} | [BlockDeviceMetrics](../src/vmm/src/devices/virtio/virtio_block/metrics.rs) | Respresent Virtio Block device metrics for the endpoint `"/drives/{drive_id}"` e.g. `"block_rootfs":` represent metrics for the endpoint `"/drives/rootfs"`|
+| i8042 | [I8042DeviceMetrics](../src/vmm/src/devices/legacy/i8042.rs) | Respresent Metrics specific to the i8042 device.|
+| net | [NetDeviceMetrics](../src/vmm/src/devices/virtio/net/metrics.rs) | Respresent aggregate metrics for Virtio Net device.|
+| net_{iface_id} | [NetDeviceMetrics](../src/vmm/src/devices/virtio/net/metrics.rs) | Respresent Virtio Net device metrics for the endpoint `"/network-interfaces/{iface_id}"` e.g. `net_eth0` represent metrics for the endpoint `"/network-interfaces/eth0"`|
+| rtc | [RTCDeviceMetrics](../src/vmm/src/devices/legacy/serial.rs) | Respresent Metrics specific to the RTC device. `Note`: this is emitted only on `aarch64`.|
+| uart | [SerialDeviceMetrics](../src/vmm/src/devices/legacy/serial.rs) | Respresent Metrics specific to the serial device.|
+| vhost_user_{dev}_{dev_id} | [VhostUserDeviceMetrics](../src/vmm/src/devices/virtio/vhost_user_metrics.rs) | Respresent Vhost-user device metrics for the device `dev` and device id `dev_id`. e.g. `"vhost_user_block_rootfs":` represent metrics for vhost-user block device having the endpoint `"/drives/rootfs"`|
+| vsock | [VsockDeviceMetrics](../src/vmm/src/devices/virtio/vsock/metrics.rs) | Respresent Metrics specific to the vsock device.|
+| entropy | [EntropyDeviceMetrics](../src/vmm/src/devices/virtio/rng/metrics.rs) | Respresent Metrics specific to the entropy device.|
+| "api_server"
"deprecated_api"
"get_api_requests"
"latencies_us"
"logger"
"mmds"
"patch_api_requests"
"put_api_requests"
"seccomp"
"signals"
"vcpu"
"vmm" | [metrics.rs](../src/vmm/src/logger/metrics.rs) | Rest of the metrics are defined in the same file metrics.rs.|
+
+Note:
+Firecracker emits all the above metrics regardless of the presense of
+that component i.e. even if `vsock` device is not attached to the
+Microvm, Firecracker will still emit the Vsock metrics with key as
+`vsock` and value of all metrics defined in `VsockDeviceMetrics` as
+`0`.
diff --git a/tests/host_tools/fcmetrics.py b/tests/host_tools/fcmetrics.py
index 8a5ea4d8a47..44471d0b680 100644
--- a/tests/host_tools/fcmetrics.py
+++ b/tests/host_tools/fcmetrics.py
@@ -14,6 +14,7 @@
from threading import Thread
import jsonschema
+import pytest
def validate_fc_metrics(metrics):
@@ -283,38 +284,28 @@ def validate_missing_metrics(metrics):
# remove some metrics and confirm that fields and not just top level metrics
# are validated.
temp_pop_metrics = metrics["api_server"].pop("process_startup_time_us")
- try:
+ with pytest.raises(
+ jsonschema.ValidationError,
+ match="'process_startup_time_us' is a required property",
+ ):
jsonschema.validate(instance=metrics, schema=firecracker_metrics_schema)
- except jsonschema.exceptions.ValidationError as error:
- if (
- error.message.strip()
- == "'process_startup_time_us' is a required property"
- ):
- pass
- else:
- raise error
metrics["api_server"]["process_startup_time_us"] = temp_pop_metrics
if platform.machine() == "aarch64":
temp_pop_metrics = metrics["rtc"].pop("error_count")
- try:
+ with pytest.raises(
+ jsonschema.ValidationError, match="'error_count' is a required property"
+ ):
jsonschema.validate(instance=metrics, schema=firecracker_metrics_schema)
- except jsonschema.exceptions.ValidationError as error:
- if error.message.strip() == "'error_count' is a required property":
- pass
- else:
- raise error
metrics["rtc"]["error_count"] = temp_pop_metrics
for vhost_user_dev in vhost_user_devices:
temp_pop_metrics = metrics[vhost_user_dev].pop("activate_time_us")
- try:
+ with pytest.raises(
+ jsonschema.ValidationError,
+ match="'activate_time_us' is a required property",
+ ):
jsonschema.validate(instance=metrics, schema=firecracker_metrics_schema)
- except jsonschema.exceptions.ValidationError as error:
- if error.message.strip() == "'activate_time_us' is a required property":
- pass
- else:
- raise error
metrics[vhost_user_dev]["activate_time_us"] = temp_pop_metrics
validate_missing_metrics(metrics)