Skip to content
This repository has been archived by the owner on Feb 12, 2024. It is now read-only.

feat: .stats.bw* - Bandwidth Stats #1230

Merged
merged 3 commits into from
Mar 16, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -74,9 +74,8 @@
"form-data": "^2.3.2",
"go-ipfs-dep": "^0.4.13",
"hat": "0.0.3",
"interface-ipfs-core": "~0.56.5",
"ipfsd-ctl": "~0.30.1",
"left-pad": "^1.2.0",
"interface-ipfs-core": "~0.57.0",
"lodash": "^4.17.5",
"mocha": "^5.0.4",
"ncp": "^2.0.0",
Expand Down
48 changes: 48 additions & 0 deletions src/cli/commands/stats/bw.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
'use strict'

const pull = require('pull-stream')

module.exports = {
command: 'bw',

describe: 'Get bandwidth information.',

builder: {
peer: {
type: 'string',
default: ''
},
proto: {
type: 'string',
default: ''
},
poll: {
type: 'boolean',
default: false
},
interval: {
type: 'string',
default: '1s'
}
},

handler (argv) {
const stream = argv.ipfs.stats.bwPullStream({
peer: argv.peer,
proto: argv.proto,
poll: argv.poll,
interval: argv.interval
})

pull(
stream,
pull.drain((chunk) => {
console.log(`bandwidth status
total in: ${chunk.totalIn}B
total out: ${chunk.totalOut}B
rate in: ${chunk.rateIn}B/s
rate out: ${chunk.rateOut}B/s`)
})
)
}
}
82 changes: 81 additions & 1 deletion src/core/components/stats.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,88 @@
'use strict'

const promisify = require('promisify-es6')
const Big = require('big.js')
const Pushable = require('pull-pushable')
const human = require('human-to-milliseconds')
const toStream = require('pull-stream-to-stream')

function bandwidthStats (self, opts) {
return new Promise((resolve, reject) => {
let stats

if (opts.peer) {
stats = self._libp2pNode.stats.forPeer(opts.peer)
} else if (opts.proto) {
stats = self._libp2pNode.stats.forProtocol(opts.proto)
} else {
stats = self._libp2pNode.stats.global
}

if (!stats) {
resolve({
totalIn: new Big(0),
totalOut: new Big(0),
rateIn: new Big(0),
rateOut: new Big(0)
})
return
}

resolve({
totalIn: stats.snapshot.dataReceived,
totalOut: stats.snapshot.dataSent,
rateIn: new Big(stats.movingAverages.dataReceived['60000'].movingAverage() / 60),
rateOut: new Big(stats.movingAverages.dataSent['60000'].movingAverage() / 60)
})
})
}

module.exports = function stats (self) {
const _bwPullStream = (opts) => {
opts = opts || {}
let interval = null
let stream = Pushable(true, () => {
if (interval) {
clearInterval(interval)
}
})

if (opts.poll) {
human(opts.interval || '1s', (err, value) => {
if (err) throw err

interval = setInterval(() => {
bandwidthStats(self, opts)
.then((stats) => stream.push(stats))
.catch((err) => stream.end(err))
}, value)
})
} else {
bandwidthStats(self, opts)
.then((stats) => {
stream.push(stats)
stream.end()
})
.catch((err) => stream.end(err))
}

return stream.source
}

return {
bitswap: require('./bitswap')(self).stat,
repo: require('./repo')(self).stat
repo: require('./repo')(self).stat,
bw: promisify((opts, callback) => {
if (typeof opts === 'function') {
callback = opts
opts = {}
}

bandwidthStats(self, opts)
.then((stats) => callback(null, stats))
.catch((err) => callback(err))
}),
bwReadableStream: (opts) => toStream.source(_bwPullStream(opts)),
bwPullStream: _bwPullStream
}
}
1 change: 1 addition & 0 deletions src/core/components/swarm.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
const multiaddr = require('multiaddr')
const promisify = require('promisify-es6')
const values = require('lodash.values')
const PeerId = require('peer-id')

const OFFLINE_ERROR = require('../utils').OFFLINE_ERROR

Expand Down
39 changes: 39 additions & 0 deletions src/http/api/resources/stats.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,46 @@
'use strict'

const { Transform } = require('readable-stream')

const transformBandwidth = (stat) => {
return {
TotalIn: stat.totalIn,
TotalOut: stat.totalOut,
RateIn: stat.rateIn,
RateOut: stat.rateOut
}
}

exports = module.exports

exports.bitswap = require('./bitswap').stat

exports.repo = require('./repo').stat

exports.bw = (request, reply) => {
const ipfs = request.server.app.ipfs
const options = {
peer: request.query.peer,
proto: request.query.proto,
poll: request.query.poll === 'true',
interval: request.query.interval || '1s'
}

const res = ipfs.stats.bwReadableStream(options)
const output = new Transform({
writableObjectMode: true,
transform (chunk, encoding, cb) {
this.push(JSON.stringify(transformBandwidth(chunk)) + '\n')
cb()
}
})

request.on('disconnect', () => {
res.destroy()
})

res.pipe(output)
reply(output)
.header('content-type', 'application/json')
.header('x-chunked-output', '1')
}
8 changes: 8 additions & 0 deletions src/http/api/routes/stats.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,12 @@ module.exports = (server) => {
handler: resources.stats.repo
}
})

api.route({
method: '*',
path: '/api/v0/stats/bw',
config: {
handler: resources.stats.bw
}
})
}
2 changes: 1 addition & 1 deletion test/cli/commands.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
const expect = require('chai').expect
const runOnAndOff = require('../utils/on-and-off')

const commandCount = 72
const commandCount = 73
describe('commands', () => runOnAndOff((thing) => {
let ipfs

Expand Down