diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000000..c2658d7d1b --- /dev/null +++ b/.dockerignore @@ -0,0 +1 @@ +node_modules/ diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000000..603a6182f0 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,25 @@ +FROM node:6 + +RUN apt-get update +RUN apt-get install --yes python2.7 git-all pkg-config libncurses5-dev libssl-dev libnss3-dev libexpat-dev libc6 + +WORKDIR /usr/src/app + +COPY package.json /usr/src/app/package.json + +RUN npm install +RUN npm install wrtc + +COPY . /usr/src/app + +ENV IPFS_WRTC_LINUX_WINDOWS=1 +ENV IPFS_BOOTSTRAP=1 +ENV IPFS_MONITORING=1 +ENV IPFS_PATH=/root/.jsipfs + +EXPOSE 4002 +EXPOSE 4003 +EXPOSE 5002 +EXPOSE 9090 + +CMD ./init-and-daemon.sh diff --git a/README.md b/README.md index 4246f24749..843d14916c 100644 --- a/README.md +++ b/README.md @@ -520,6 +520,20 @@ src # Main source code folder └── ... ``` +### Monitoring + +The HTTP API exposed with js-ipfs can also be used for exposing metrics about +the running js-ipfs node and other nodejs metrics. + +To enable it, you need to set the environment variable `IPFS_MONITORING` (any value) + +Once environment variable is set and the js-ipfs daemon is running, you can get +the metrics (in prometheus format) by making a GET request to the following endpoint: + +``` +http://localhost:5002/debug/metrics/prometheus +``` + ### IPFS Core Architecture ![](/img/core.png) diff --git a/init-and-daemon.sh b/init-and-daemon.sh new file mode 100755 index 0000000000..a01721e436 --- /dev/null +++ b/init-and-daemon.sh @@ -0,0 +1,6 @@ +#! /bin/sh -e +node src/cli/bin.js init + +sed -i.bak 's/127.0.0.1/0.0.0.0/g' $IPFS_PATH/config + +node src/cli/bin.js daemon diff --git a/package.json b/package.json index be5c0cfef3..63e0dc705b 100644 --- a/package.json +++ b/package.json @@ -153,6 +153,10 @@ "update-notifier": "^2.2.0", "yargs": "8.0.2" }, + "optionalDependencies": { + "prom-client": "^10.0.2", + "prometheus-gc-stats": "^0.5.0" + }, "contributors": [ "Andrew de Andrade ", "CHEVALAY JOSSELIN ", @@ -161,7 +165,6 @@ "Daniel J. O'Quinn ", "Daniela Borges Matos de Carvalho ", "David Dias ", - "Dzmitry Das ", "Enrico Marino ", "Felix Yan ", "Francisco Baio Dias ", @@ -171,12 +174,10 @@ "Greenkeeper ", "Haad ", "Harsh Vakharia ", - "Johannes Wikner ", "Jon Schlinkert ", "João Antunes ", "Kevin Wang ", "Lars Gierth ", - "Maciej Krüger ", "Marius Darila ", "Michelle Lee ", "Mikeal Rogers ", @@ -185,7 +186,6 @@ "Oskar Nyberg ", "Pau Ramon Revilla ", "Pedro Teixeira ", - "RasmusErik Voel Jensen ", "Richard Littauer ", "Rod Keys ", "Sid Harder ", @@ -193,9 +193,7 @@ "Stephen Whitmore ", "Stephen Whitmore ", "Terence Pae ", - "Uroš Jurglič ", "Xiao Liang ", - "bitspill ", "haad ", "jbenet ", "kumavis ", @@ -204,4 +202,4 @@ "tcme ", "ᴠɪᴄᴛᴏʀ ʙᴊᴇʟᴋʜᴏʟᴍ " ] -} \ No newline at end of file +} diff --git a/src/http-api/index.js b/src/http-api/index.js index a0d849e9d2..834ee49844 100644 --- a/src/http-api/index.js +++ b/src/http-api/index.js @@ -23,6 +23,15 @@ function HttpApi (repo, config, cliArgs) { this.log = debug('jsipfs:http-api') this.log.error = debug('jsipfs:http-api:error') + if (process.env.IPFS_MONITORING) { + // Setup debug metrics collection + const prometheusClient = require('prom-client') + const prometheusGcStats = require('prometheus-gc-stats') + const collectDefaultMetrics = prometheusClient.collectDefaultMetrics + collectDefaultMetrics({ timeout: 5000 }) + prometheusGcStats(prometheusClient.register)() + } + this.start = (init, callback) => { if (typeof init === 'function') { callback = init @@ -41,6 +50,8 @@ function HttpApi (repo, config, cliArgs) { try { wrtc = require('wrtc') } catch (err) {} if (wrtc || electronWebRTC) { + const using = wrtc ? 'wrtc' : 'electron-webrtc' + console.log(`Using ${using} for webrtc support`) const wstar = new WStar({ wrtc: (wrtc || electronWebRTC) }) libp2p.modules.transport = [wstar] libp2p.modules.discovery = [wstar.discovery] diff --git a/src/http-api/routes/debug.js b/src/http-api/routes/debug.js new file mode 100644 index 0000000000..d5ae1e434d --- /dev/null +++ b/src/http-api/routes/debug.js @@ -0,0 +1,31 @@ +'use strict' + +const register = require('prom-client').register +const client = require('prom-client') + +// Endpoint for handling debug metrics +module.exports = (server) => { + const api = server.select('API') + // Clear the register to make sure we're not registering multiple ones + register.clear() + const gauge = new client.Gauge({ name: 'number_of_peers', help: 'the_number_of_currently_connected_peers' }) + + api.route({ + method: 'GET', + path: '/debug/metrics/prometheus', + handler: (request, reply) => { + if (!process.env.IPFS_MONITORING) { + return reply('Monitoring is disabled. Enable it by setting environment variable IPFS_MONITORING') + .code(501) // 501 = Not Implemented + } + server.app.ipfs.swarm.peers((err, res) => { + if (err) { + return reply(err).code(500) + } + const count = res.length + gauge.set(count) + reply(register.metrics()).header('Content-Type', register.contentType) + }) + } + }) +} diff --git a/src/http-api/routes/index.js b/src/http-api/routes/index.js index 7b0afa885d..c317db6de7 100644 --- a/src/http-api/routes/index.js +++ b/src/http-api/routes/index.js @@ -12,4 +12,5 @@ module.exports = (server) => { require('./bitswap')(server) require('./files')(server) require('./pubsub')(server) + require('./debug')(server) }