-
Notifications
You must be signed in to change notification settings - Fork 1.2k
feat: stats API (stats.bitswap and stats.repo) #1198
Conversation
Now I need to develop some kind of bandwidth metrics and I already know it is related to I was wondering if any of you (@diasdavid @dignifiedquire @pgte) could point me to the right direction since you are more into this project than I😄 |
Regarding bandwidth, you'll have to look into js-ipfs-bitswap. If you want per second, you can use a moving average. You have moving averages for 1, 5 and 15 minutes (this is configurable if you want to add a new interval). There are no API docs (there is an issue about this somewhere), but here are the tests for this functionality: https://github.com/ipfs/js-ipfs-bitswap/blob/feat/benchmarks/test/bitswap-stats.js#L137-L145 Please tell me if you need more pointers. |
Thanks @pgte! Another question: when we have this on the API how should we do the response on the HTTP API? I tried this:
but it didn't work |
@pgte could you take a look here? It seems to always print 0 for every field. And how should I get the stats for specific peers and protocols? Ref.: Go implementation |
What is the client expecting? Is it a new-line delimited JSON stream?
If so, you will need to also output “\n” after each entry.
…On 30 Jan 2018, 17:46 +0000, Henrique Dias ***@***.***>, wrote:
Thanks @pgte!
Another question: when we have this on the API how should we do the response on the HTTP API? I tried this:
const stream = Readable()
reply(stream)
stream.push(Buffer.from(JSON.stringify({
TotalIn: stat.totalIn,
TotalOut: stat.totalOut,
RateIn: stat.rateIn,
RateOut: stat.rateOut,
})))
but it didn't work
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub, or mute the thread.
|
@pgte after digging into the source code I noticed we are using two funny special header |
@hacdias are you still getting problems with the stats? Regarding peer-specific stats: currently, js-ipfs-bitswap doesn't keep stats per peer. |
@pgte the stats always have zero values: bw: promisify((options, callback) => {
if (typeof options === 'function') {
callback = options
options = {}
}
options = Object.assign({
peer: '',
proto: '',
poll: false,
interval: '1s'
}, options)
let stats
if (options.peer) {
// TODO: stats for a specific peer
} else if (options.proto) {
// TODO: stats for a specific proto
} else {
const stat = self._bitswap.stat()
const snapshot = stat.snapshot
const movingAverages = stat.movingAverages
stats = {
totalIn: snapshot.dataReceived,
totalOut: snapshot.dataSent,
rateIn: movingAverages.dataReceived[60000].movingAverage() / 60, // Bytes per second
rateOut: movingAverages.dataSent[60000].movingAverage() / 60 // Bytes per second
}
}
callback(null, stats)
}) That code always gives me a |
@hacdias this may be a timing issue. I don't know if it helps, but, like exemplified in the test, the stat object emits an |
and, of course, opening an issue on js-ipfs-bitswap (preferably with a reproducible problem if you can :) ) if you're not able to get values. |
@pgte I just added this: to the place where bitswap is initialized. It seems that it never gets called (at least waiting 10 mins). I'm running |
@hacdias I think you'll have to enable stats like this. |
... which I think may have to become a default setting in js-ipfs. |
I will also be needing per-peer stats because of ipfs-inactive/dynamic-data-and-capabilities#3 (comment). I opened bitswap issue here: ipfs/js-ipfs-bitswap#165 @hacdias could you state your requirements there? |
@hacdias any luck enabling stats? |
@pgte not really, they are always 0. |
@hacdias are the stats tests passing?:
They are for me, and they test for > 0 values. (also, keep in mind that values are Big: https://github.com/MikeMcl/big.js#readme |
Took a stab at documenting current stats API: Hope this + tests help. |
Since libp2p/js-libp2p#157 might take a bit, I suggest to move |
@hacdias js-ipfs-api was released. You should be able to finish this PR now :) |
@diasdavid there is still one thing missing: we need to merge ipfs-inactive/interface-js-ipfs-core#216 in order to finish this PR. |
merging #1216 first and then back at this one :) |
OKay, as soon as you merge it, I'll finish this PR, but I'll still need ipfs-inactive/interface-js-ipfs-core#216 to be merged. |
@hacdias do it like this:
|
- [repo](https://github.com/ipfs/interface-ipfs-core/tree/master/SPEC/) | ||
- `ipfs.repo.init` | ||
- `ipfs.repo.version` | ||
- `ipfs.repo.gc` (not implemented, yet!) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why move these to the Graph section??
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would agree if moved to the Node Management Section
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's on the Node Management section
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nvm, I got fooled twice by GH interface. all good :)
wantlist [${stats.wantlist.length} keys] | ||
${stats.wantlist.join('\n ')} | ||
partners [${stats.peers.length}] | ||
${stats.peers.join('\n ')}`) | ||
}) | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
After Rebase, enable the CLI Bitswap test stat
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done and it works!!
src/core/components/bitswap.js
Outdated
if (!self.isOnline()) { | ||
throw new Error(OFFLINE_ERROR) | ||
callback(new Error(OFFLINE_ERROR)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This needs two things:
- Be wrapped with a setImmediate from the
async
module - Have a
return
, otherwise the rest of the function will be executed.
src/core/components/start.js
Outdated
self._peerInfoBook | ||
Object.assign({ | ||
statsEnabled: true | ||
}, self._peerInfoBook) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is weird. Are you saying that in order to enable stats on Bitswap there is a variable on PeerBook that needs to be true? This Object Assign is also probably messing with the fact that PeerBook is a Object from Class and not an Object Literal. //cc @pgte
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We need to have the stats enabled and this was the best way I found to do that.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@pgte could you comment here given that you implemented stats on Bitswap
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see. the thing is that bitswap doesn't need access to the PeerInfoBook at all. You can just pass the object options.
b8cd672
to
bb5eece
Compare
@diasdavid the related tests to this PR seem to be working here 😄 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you @hacdias <3
Right now,
js-ipfs
doesn't implement any of the STATS spec and it is required to make IPFS Desktop work with js-ipfs.Prerequisites and related PRs
stats.bitswap
tobitswap.stat
and linkstats.bitswap
tobitswap.stat
stats.repo
torepo.stat
and linkstats.repo
torepo.stat
bitswap.stat
equal tostats.bitswap
stat
command.package.json
package.json
js-ipfs
ToDos
bitswap.stat
must implement the SPECstats.bitswap
just points tobitswap.stat
repo.stat
must implement the SPECstats.repo
just points torepo.stat
Not Fundamental, but also done in this PR
/api/v0/repo/version
ipfs repo version
ipfs.repo.version()
Closes #1197
Closes #1116