@ssb-graphql/stats
Version:
Statistics GraphQL types and resolvers for the machine
131 lines (125 loc) • 3.5 kB
JavaScript
const si = require('systeminformation')
const publicIp = require('public-ip')
const stoppable = require('stoppable')
const net = require('net')
const PORT_FORWARDING_TEST_PORT = 3063
// PROBLEM this can be called multiple times so you sometimes get collisions on port 3063.
//
// TODO - change so that it doesn't start multiple at once
// track state something like:
// let checkingPortForwarding = false
// let portForwardingState = null
function portOpen (externalHost, externalPort) {
return new Promise(resolve => {
const server = stoppable(
net.createServer(socket => {
socket.end()
})
)
// var server = net.createServer()
server.on('error', e => {
console.log('error', e)
resolve(false)
server.stop()
})
server.on('listening', () => {
const socket = net.connect(externalPort, externalHost, () => {
// console.log('connected')
resolve(true)
socket.destroy()
server.stop()
})
socket.setTimeout(3000)
socket.on('timeout', () => {
resolve(false)
socket.destroy()
server.stop()
})
socket.on('error', e => {
console.log('connect error', e)
resolve(false)
socket.destroy()
server.stop()
})
})
server.listen(PORT_FORWARDING_TEST_PORT)
})
}
module.exports = function stats (ssb) {
return {
Query: {
cpuLoad: async () => {
const load = await si.currentLoad()
return load.currentLoad.toFixed(2)
},
memoryLoad: async () => {
const mem = await si.mem()
const memLoad = (mem.used * 100) / mem.total
return memLoad.toFixed(2)
},
diskUsage: async () => {
const disk = await si.fsSize()
disk.forEach(diskVal =>
Object.keys(diskVal).forEach(i => {
if (isNaN(disk[i])) {
disk[i] = 0
}
})
)
return disk
},
network: async () => {
const defaultInterface = await si.networkInterfaceDefault()
const interfaces = await si.networkInterfaces()
const interfaceInUse = interfaces.filter(
i => i.iface === defaultInterface
)[0]
const ipv4 = interfaceInUse.ip4
const ip4subnet = interfaceInUse.ip4subnet
const ipv6 = interfaceInUse.ip6
const ip6subnet = interfaceInUse.ip6subnet
const type = interfaceInUse.type
const macAddress = interfaceInUse.mac
return {
ipv4,
ip4subnet,
ipv6,
ip6subnet,
type,
macAddress
}
}
},
NetworkInfo: {
defaultGateway: async () => await si.networkGatewayDefault(),
internetLatency: async () => si.inetLatency(),
publicIpv4: async () => {
try {
return await publicIp.v4({
timeout: 3000,
fallbackUrls: ['https://ifconfig.co/ip']
})
} catch (err) {
return null
}
},
publicIpv6: async () => {
try {
return await publicIp.v6({
timeout: 3000,
fallbackUrls: ['https://ifconfig.co/ip']
})
} catch (err) {
return null
}
},
portForwarding: async () => {
const ip = await publicIp.v4({
timeout: 3000,
fallbackUrls: ['https://ifconfig.co/ip']
})
return portOpen(ip, ssb.config.port)
}
}
}
}