# Avail monitoring metrics
Purpose of this this doc is to outline the metrics which are required to be emitted by the monitoring tool. The metrics emitted should be in prometheus compatible format from which custom dashboards can be created. Along with the required metrics this doc also details how to get the required data from the network using RPC calls and the computation required on that data.
**Note**:- the example calls in this doc use the official Kate testnet websocket endpoint. For the tool the websocket endpoint should be taken from the user in a `config.toml` file. Also I'm using a cli binary to make queries the endpoints. This is just for testing purpose. Websocket connections and queries should be handled in code using relevant go libraries
## List of Metrics
**Version**:-
`data-avail`version of the node being queried.
ws query:- [api.rpc.system.version](https://polkadot.js.org/docs/substrate/rpc#version-text-1)
example cli query:- `polkadot-js-api rpc.system.version --ws wss://kate.avail.tools/ws`
example result:-
`{
"version": "1.6.2-bb4cc104b25"
}`
sidecar api:- http://64.227.177.52:8080/node/version
**Chain ID**:-
chain-id of the network being queried.
ws query:- [api.rpc.system.chain](https://polkadot.js.org/docs/substrate/rpc#chain-text)
example query:-
`polkadot-js-api rpc.system.chain --ws wss://kate.avail.tools/ws`
example result:-
`{
"chain": "Avail Kate Testnet"
}`
sidecar api:- http://64.227.177.52:8080/node/version
**Latest Best Block**:-
best block of the network being queried.
ws query:- [api.rpc.chain.getBlock](https://polkadot.js.org/docs/substrate/rpc#getblockhash-blockhash-signedblock)
example query:- `polkadot-js-api rpc.chain.getBlock --ws wss://kate.avail.tools/ws`
example result:- `{
"getBlock": {
"block": {
"header": {
"parentHash": "xxxx",
"number": "482,051",
"stateRoot": "xxx",
"extrinsicsRoot": "xx",
"digest": {
`
The `number` field is the desired metric.
**Latest Finalized block**:-
finalized block of the network being queried.
ws query:- `api.rpc.chain.getFinalizedHead`
example result:- `{
"getFinalizedHead": "0x304bd7e1ed709e9d9c79c17c2a054f7aae4b93990e311c929413aa790aa3c84b"
}`
The result is the hash of the finalized block. This hash should be queried to get the block details. Use the same query as the Best block one and pass the hash as an argument. From that result `number` field will bw the desired result just like best block metric.
sidecar api:- http://64.227.177.52:8080/blocks/head
**Timestamp of latest block**:-
While querying the best block, the result also includes an `extrinsics` section. ex:-
` "extrinsics": [
{
"isSigned": false,
"method": {
"args": {
"now": "1,695,719,460,000"
},
"method": "set",
"section": "timestamp"
`
`now` field is the timestamp of the best block in unix milliseconds. It first has to be converted in unix seconds and then into human readable format. Using the above result as an example, converting `1,695,719,460,000` to unix milliseconds gives us `1,695,719,460`. Converting it into [readable format](https://www.epochconverter.com/) gives us `Tuesday, September 26, 2023 2:41:00 PM GMT+05:30`
sidecar api:- Response from the finalized block query should be used to get the timestamp of the block and converted.
**Current slot**:-
current slot number.
ws query:- [api.query.babe.currentSlot](https://polkadot.js.org/docs/substrate/storage#currentslot-u64)
example result:- `{
"currentSlot": "84,786,179"
}`
sidecar api:- http://64.227.177.52:8080/pallets/babe/storage/currentSlot
**Current epoch**:-
current epoch number
ws query:- [api.query.babe.epochIndex](https://polkadot.js.org/docs/substrate/storage#epochindex-u64)
example result:- `{
"epochIndex": "2,682"
}`
sidecar api:- http://64.227.177.52:8080/pallets/babe/storage/epochIndex
**Current epoch start time**:-
Block height on which the current epoch started.
ws query:- [api.query.babe.epochStart](https://polkadot.js.org/docs/substrate/storage#epochstart-u32u32)
example result:- `{
"epochStart": [
"481,981",
"482,161"
]
}
`
First value of the array is the desired metric
sidecar api:- http://64.227.177.52:8080/pallets/babe/storage/epochStart
**Current epoch end time**:-
Block height on which the current epoch ends.
Same as the start epoch query. The second value of the array is the desired metric.
**Total tokens issued on network**:-
total number of units issued on the network till now.
ws query:- [api.query.balances.totalIssuance](https://polkadot.js.org/docs/substrate/storage#totalissuance-u128)
example result:- `{
"totalIssuance": "200,179,764,300,504,370,853,699,737,435"
}`
The result is returned in a raw format. This has to be converted into AVL token decimal format. The decimal exponent of Avail is 10^18. So adjusting the above result for decimal exponent we get `200,179,764,300.504370853699737435` AVL tokens. This is the desired metric.
sidecar api:- http://64.227.177.52:8080/pallets/balances/storage/totalIssuance
**Total bonded tokens on network**:-
ws query:- [api.query.staking.erasTotalStake](https://polkadot.js.org/docs/substrate/storage#erastotalstakeu32-u128)
example result:- `99,651,568,893,155,355,796,567,775`
Just like total tokens issued metric decimal exponent needs to be done for this result as well.
Note that this query requires an argument which has to be the current era. Value of the current era can be queried using the below metric.
sidecar api:- http://64.227.177.52:8080/pallets/staking/storage/erasTotalStake?keys[]=<current era number to be taken from next metric>
example sidecar query for era `474`:-
http://64.227.177.52:8080/pallets/staking/storage/erasTotalStake?keys[]=474
**Current Era**:-
ws query:- [api.query.staking.currentEra](https://polkadot.js.org/docs/substrate/storage#currentera-optionu32)
example result:- `{
"currentEra": "450"
}
`
sidecar api:- http://64.227.177.52:8080/pallets/staking/storage/currentEra
**Number of Bounty proposals made on the network**:-
ws query:- [api.query.bounties.bountyCount](https://polkadot.js.org/docs/substrate/storage#bountycount-u32)
example result:- `{
"bountyCount": "0"
}
`
sidecar api:- http://64.227.177.52:8080/pallets/bounties/storage/bountyCount
**Council members**:-
ws query:- [api.query.council.members](https://polkadot.js.org/docs/substrate/storage#members-vecaccountid32-1)
example result:- `{
"members": [
"5GGq94gxzxigsLZvG96XN9PeZqSGed33ea3Bw3r6T2eagofn"
]
}
`
sidecar api:- http://64.227.177.52:8080/pallets/council/storage/members
All the objects of the array should be returned. Metrics with different lables can be used to emit same metrics with different values.
**Number of total council proposals on the network**:-
ws query:- [api.query.council.proposalCount]([api.query.council.proposalCount](https://polkadot.js.org/docs/substrate/storage#proposalcount-u32-1))
example result:-
`{
"proposalCount": "1"
}
`
sidecar api:- http://64.227.177.52:8080/pallets/council/storage/proposalCount
**Number of total public proposals on the network**:-
ws query:- [query.democracy.publicPropCount](https://polkadot.js.org/docs/substrate/storage#publicpropcount-u32)
example result:-
`{
"publicPropCount": "2"
}
`
sidecar api:- http://64.227.177.52:8080/pallets/democracy/storage/publicPropCount
**Number of total public referendums on the network**:-
ws query:- [api.query.democracy.referendumCount](https://polkadot.js.org/docs/substrate/storage#referendumcount-u32)
sidecar api:- http://64.227.177.52:8080/pallets/democracy/storage/referendumCount
**Current elected members**:-
ws query:- [api.query.elections.members](https://polkadot.js.org/docs/substrate/storage#members-vecpalletelectionsphragmenseatholder)
example result:-
`{
"members": [
{
"who": "5GGq94gxzxigsLZvG96XN9PeZqSGed33ea3Bw3r6T2eagofn",
"stake": "999,999,998,610,557,872",
"deposit": "0"
}
]
}
`
`who` field of the result array are the desired metrics. If more than one object is present in the array then multiple metrics with differing labels can be used just like council members metric
sidecar api:- http://64.227.177.52:8080/pallets/elections/storage/members
**List of current validators**:-
ws query:- [api.query.session.validators](https://polkadot.js.org/docs/substrate/storage#validators-vecaccountid32)
example result:-
`{
"validators": [
"5CDBq9vbtoQDrQsmb8YX2VrhaG21wZ6wEywxZ52Dyh3XULF5",
"5CDGXH8Q9DzD3TnATTG6qm6f4yR1kbECBGUmh2XbEBQ8Jfa5",
"5CFsdp5wbk4C7htRvNq8VgmUxHLnYUnf2DaWoSPyTuApRqtQ",
"5CLy7zpbvARjGcQj6EpRpcwKreAgvNqHa3UFVceURVgE81ew",
"5CMYN`
All the objects from the array need to be emitted
sidecar api:- http://64.227.177.52:8080/pallets/session/storage/validators
**Number of nomination pools**:-
sidecar api:- http://64.227.177.52:8080/pallets/nominationPools/storage/counterForBondedPools
----------------------
**Current staking ratio**:-
(Total bonded tokens on network/Total tokens issued on network) * 100
**Total rewards claimed**:-
To get this we will have to query each reward pool and do summation of a field.
example query:-
http://64.227.177.52:8080/pallets/nominationPools/storage/rewardPools?keys[]=1
In this we are querying reward pool no 1.
We need the value of `totalRewardsClaimed` from it.
Similarly we have to query all the reward pools in a for loop and get the value of it. Total of all the fields is our desired metric. The total number of reward pools has already been calcualted in **Number of nomination pools** metric. Decimal exponent of 18 should be adjusted here as well.
**Last total nominator pool rewards**:-
Similar to the above metric but `lastRecordedRewardCounter` field has to be used for summation.
**No of active validators**:-
http://64.227.177.52:8080/pallets/session/storage/validators
This endpoint will get us the public key of all the active validators. We just need the count of the objects present in the array. That is the desired metric.
**Total rewards distributed to validator in era**:-
http://64.227.177.52:8080/pallets/staking/storage/erasRewardPoints?keys[]=598
This example is querying val rewards for era 598. It shoould be querying the current era which has been calculated in **Current Era** metric. The `total` field is the desired metric