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 committed Mar 11, 2018
1 parent 9105700 commit 36bb4e3
Show file tree
Hide file tree
Showing 6 changed files with 172 additions and 3 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@
"is-ipfs": "^0.3.2",
"is-stream": "^1.1.0",
"joi": "^13.1.2",
"libp2p": "~0.18.0",
"libp2p": "libp2p/js-libp2p#09069d4",
"libp2p-circuit": "~0.1.4",
"libp2p-floodsub": "~0.14.1",
"libp2p-kad-dht": "~0.8.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`)
})
)
}
}
76 changes: 75 additions & 1 deletion src/core/components/stats.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,82 @@
'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) => {
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) => {
bandwidthStats(self, opts)
.then((stats) => callback(null, stats))
.catch((err) => callback(err))
}),
bwReadableStream: (opts) => toStream.source(_bwPullStream(opts)),
bwPullStream: _bwPullStream
}
}
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, Readable } = 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

0 comments on commit 36bb4e3

Please sign in to comment.