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

Commit

Permalink
feat: .stats.bw*
Browse files Browse the repository at this point in the history
  • Loading branch information
hacdias authored and daviddias committed Mar 16, 2018
1 parent e174866 commit 0239f58
Show file tree
Hide file tree
Showing 8 changed files with 184 additions and 4 deletions.
1 change: 1 addition & 0 deletions bw
@@ -0,0 +1 @@
{"TotalIn":"0","TotalOut":"0","RateIn":"0","RateOut":"0"}
7 changes: 5 additions & 2 deletions package.json
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": "ipfs/interface-ipfs-core#cf1cd29",
"lodash": "^4.17.5",
"mocha": "^5.0.4",
"ncp": "^2.0.0",
Expand Down Expand Up @@ -123,7 +122,11 @@
"joi-browser": "^13.0.1",
"joi-multiaddr": "^1.0.1",
"libp2p": "~0.19.0",
<<<<<<< HEAD
"libp2p-circuit": "~0.1.5",
=======
"libp2p-circuit": "~0.1.4",
>>>>>>> feat: .stats.bw*
"libp2p-floodsub": "~0.14.1",
"libp2p-kad-dht": "~0.9.0",
"libp2p-keychain": "~0.3.1",
Expand Down
48 changes: 48 additions & 0 deletions src/cli/commands/stats/bw.js
@@ -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
@@ -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
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
@@ -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
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
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

0 comments on commit 0239f58

Please sign in to comment.