Browse Source

- optional logging of network stats to configurable influxdb instance

- cleaner support for handling credentials (new app/defaultCredentials.js has the defaults, git-ignored app/credentials.js overwrites)
- update some dependencies
fix-133-memory-crash
Dan Janosik 6 years ago
parent
commit
8e02736222
  1. 2
      .gitignore
  2. 7
      README.md
  3. 73
      app.js
  4. 8
      app/config.js
  5. 23
      app/credentials.js
  6. 31
      app/defaultCredentials.js
  7. 178
      package-lock.json
  8. 5
      package.json

2
.gitignore

@ -59,3 +59,5 @@ typings/
public/css/radial-progress.css
app/credentials.js

7
README.md

@ -38,11 +38,10 @@ The below instructions are geared toward BTC, but can be adapted easily to other
1. Clone this repo: `git clone https://github.com/janoside/btc-rpc-explorer`
2. `npm install`
3. `npm run build`
4. Edit the "rpc" settings in [app/credentials.js](app/credentials.js) to target your node
4. Optional: Create git-ignored file [app/credentials.js](app/credentials.js) with values to overwrite those in [app/defaultCredentials.js](app/defaultCredentials.js).
5. Optional: Change the "coin" value in [app/config.js](app/config.js). Currently supported values are "BTC" and "LTC".
6. Optional: Add an ipstack.com API access key to [app/credentials.js](app/credentials.js). Doing so will add a map to the /peers page.
7. `npm start` to start the local server
8. Visit http://127.0.0.1:3002/
6. `npm start`
7. Open [http://127.0.0.1:3002/](http://127.0.0.1:3002/)
## Run via Docker

73
app.js

@ -23,6 +23,8 @@ var request = require("request");
var qrcode = require("qrcode");
var fs = require('fs');
var electrumApi = require("./app/api/electrumApi.js");
var Influx = require("influx");
var coreApi = require("./app/api/coreApi.js");
var crawlerBotUserAgentStrings = [ "Googlebot", "Bingbot", "Slurp", "DuckDuckBot", "Baiduspider", "YandexBot", "Sogou", "Exabot", "facebot", "ia_archiver" ];
@ -60,6 +62,68 @@ process.on("unhandledRejection", (reason, p) => {
});
function logNetworkStats() {
if (global.influxdb) {
var promises = [];
promises.push(coreApi.getMempoolInfo());
promises.push(coreApi.getMiningInfo());
promises.push(coreApi.getBlockchainInfo());
Promise.all(promises).then(function(promiseResults) {
var mempoolInfo = promiseResults[0];
var miningInfo = promiseResults[1];
var blockchainInfo = promiseResults[2];
//console.log("mempoolInfo: " + JSON.stringify(mempoolInfo));
//console.log("miningInfo: " + JSON.stringify(miningInfo));
//console.log("blockchainInfo: " + JSON.stringify(blockchainInfo));
var points = [];
var mempoolMapping = {size:"tx_count", bytes:"tx_vsize_total", usage:"total_memory_usage"};
for (var key in mempoolInfo) {
if (mempoolMapping[key]) {
points.push({measurement:`bitcoin.mempool.${mempoolMapping[key]}`, fields:{value:mempoolInfo[key]}})
}
}
var miningMapping = {
difficulty:{
name:"mining_difficulty",
transform:function(rawval) {return parseFloat(rawval);}
},
networkhashps:{
name:"networkhashps",
transform:function(rawval) {return parseFloat(rawval);}
}
};
for (var key in miningInfo) {
if (miningMapping[key]) {
points.push({measurement:`bitcoin.mining.${miningMapping[key].name}`, fields:{value:miningMapping[key].transform(miningInfo[key])}})
}
}
var blockchainMapping = {size_on_disk:"size_on_disk"};
for (var key in blockchainInfo) {
if (blockchainMapping[key]) {
points.push({measurement:`bitcoin.blockchain.${blockchainMapping[key]}`, fields:{value:blockchainInfo[key]}})
}
}
//console.log("Points to send to InfluxDB: " + JSON.stringify(points, null, 4));
global.influxdb.writePoints(points).catch(err => {
console.error(`Error saving data to InfluxDB: ${err.stack}`)
});
}).catch(err => {
console.log(`Error logging network stats: ${err}`);
});
}
}
app.runOnStartup = function() {
global.config = config;
@ -100,6 +164,15 @@ app.runOnStartup = function() {
});
}
if (config.credentials.influxdb.active) {
global.influxdb = new Influx.InfluxDB(config.credentials.influxdb);
console.log(`Connected to InfluxDB: ${config.credentials.influxdb.host}:${config.credentials.influxdb.port}/${config.credentials.influxdb.database}`);
logNetworkStats();
setInterval(logNetworkStats, 5 * 60000);
}
if (config.donationAddresses) {
var getDonationAddressQrCode = function(coinId) {
qrcode.toDataURL(config.donationAddresses[coinId].address, function(err, url) {

8
app/config.js

@ -1,8 +1,14 @@
var credentials = require("./credentials.js");
var coins = require("./coins.js");
var currentCoin = "BTC";
var credentials = require("./defaultCredentials.js");
var overwriteCredentials = require("./credentials.js");
for (var key in overwriteCredentials) {
credentials[key] = overwriteCredentials[key];
}
module.exports = {
cookiePassword: "0x000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f",
demoSite: true,

23
app/credentials.js

@ -1,23 +0,0 @@
module.exports = {
// Edit "rpc" below to target your node.
// You may delete this section if you wish to connect manually via the UI.
rpc: {
host:"localhost",
port:8332,
username:"username",
password:"password"
},
// optional: enter your api access key from ipstack.com below
// to include a map of the estimated locations of your node's
// peers
ipStackComApiAccessKey:"",
// optional: GA tracking code
googleAnalyticsTrackingId:"",
// optional: sentry.io error-tracking url
sentryUrl:"",
};

31
app/defaultCredentials.js

@ -0,0 +1,31 @@
module.exports = {
rpc: {
host:"127.0.0.1",
port:8332,
username:"rpc_username",
password:"rpc_password"
},
influxdb:{
active:false,
host:"127.0.0.1",
port:8086,
database:"influxdb",
username:"admin",
password:"admin"
},
// optional: enter your api access key from ipstack.com below
// to include a map of the estimated locations of your node's
// peers
// format: "ID_FROM_IPSTACK"
ipStackComApiAccessKey:null,
// optional: GA tracking code
// format: "UA-..."
googleAnalyticsTrackingId:null,
// optional: sentry.io error-tracking url
// format: "SENTRY_IO_URL"
sentryUrl:null,
};

178
package-lock.json

@ -370,9 +370,9 @@
}
},
"chalk": {
"version": "2.4.1",
"resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz",
"integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==",
"version": "2.4.2",
"resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
"integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
"dev": true,
"requires": {
"ansi-styles": "^3.2.1",
@ -421,18 +421,18 @@
"integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c="
},
"color-convert": {
"version": "1.9.2",
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.2.tgz",
"integrity": "sha512-3NUJZdhMhcdPn8vJ9v2UQJoH0qqoGUkYTgFEPZaPjEtwmmKUfNV46zZmgB2M5M4DCEQHMaCfWHCxiBflLm04Tg==",
"version": "1.9.3",
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
"integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
"dev": true,
"requires": {
"color-name": "1.1.1"
"color-name": "1.1.3"
}
},
"color-name": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.1.tgz",
"integrity": "sha1-SxQVMEz1ACjqgWQ2Q72C6gWANok=",
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
"integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=",
"dev": true
},
"combined-stream": {
@ -621,12 +621,6 @@
"nan": "^2.10.0"
}
},
"duplexer": {
"version": "0.1.1",
"resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.1.tgz",
"integrity": "sha1-rOb/gIwc5mtX0ev5eXessCM0z8E=",
"dev": true
},
"ecc-jsbn": {
"version": "0.1.2",
"resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz",
@ -683,27 +677,28 @@
}
},
"es-abstract": {
"version": "1.12.0",
"resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.12.0.tgz",
"integrity": "sha512-C8Fx/0jFmV5IPoMOFPA9P9G5NtqW+4cOPit3MIuvR2t7Ag2K15EJTpxnHAYTzL+aYQJIESYeXZmDBfOBE1HcpA==",
"version": "1.13.0",
"resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.13.0.tgz",
"integrity": "sha512-vDZfg/ykNxQVwup/8E1BZhVzFfBxs9NqMzGcvIJrqg5k2/5Za2bWo40dK2J1pgLngZ7c+Shh8lwYtLGyrwPutg==",
"dev": true,
"requires": {
"es-to-primitive": "^1.1.1",
"es-to-primitive": "^1.2.0",
"function-bind": "^1.1.1",
"has": "^1.0.1",
"is-callable": "^1.1.3",
"is-regex": "^1.0.4"
"has": "^1.0.3",
"is-callable": "^1.1.4",
"is-regex": "^1.0.4",
"object-keys": "^1.0.12"
}
},
"es-to-primitive": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.1.1.tgz",
"integrity": "sha1-RTVSSKiJeQNLZ5Lhm7gfK3l13Q0=",
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.0.tgz",
"integrity": "sha512-qZryBOJjV//LaxLTV6UC//WewneB3LcXOL9NP++ozKVXsIIIpm/2c13UDiD9Jp2eThsecw9m3jPqDwTyobcdbg==",
"dev": true,
"requires": {
"is-callable": "^1.1.1",
"is-callable": "^1.1.4",
"is-date-object": "^1.0.1",
"is-symbol": "^1.0.1"
"is-symbol": "^1.0.2"
}
},
"escape-html": {
@ -727,21 +722,6 @@
"resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz",
"integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc="
},
"event-stream": {
"version": "3.3.4",
"resolved": "http://registry.npmjs.org/event-stream/-/event-stream-3.3.4.tgz",
"integrity": "sha1-SrTJoPWlTbkzi0w02Gv86PSzVXE=",
"dev": true,
"requires": {
"duplexer": "~0.1.1",
"from": "~0",
"map-stream": "~0.1.0",
"pause-stream": "0.0.11",
"split": "0.3",
"stream-combiner": "~0.0.4",
"through": "~2.3.1"
}
},
"execa": {
"version": "0.7.0",
"resolved": "https://registry.npmjs.org/execa/-/execa-0.7.0.tgz",
@ -890,12 +870,6 @@
"resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz",
"integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac="
},
"from": {
"version": "0.1.7",
"resolved": "https://registry.npmjs.org/from/-/from-0.1.7.tgz",
"integrity": "sha1-g8YK/Fi5xWmXAH7Rp2izqzA6RP4=",
"dev": true
},
"function-bind": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
@ -965,6 +939,12 @@
"integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=",
"dev": true
},
"has-symbols": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.0.tgz",
"integrity": "sha1-uhqPGvKg/DllD1yFA2dwQSIGO0Q=",
"dev": true
},
"hash-base": {
"version": "3.0.4",
"resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.0.4.tgz",
@ -1025,6 +1005,11 @@
"wrappy": "1"
}
},
"influx": {
"version": "5.0.7",
"resolved": "https://registry.npmjs.org/influx/-/influx-5.0.7.tgz",
"integrity": "sha1-NeZfa/E8uqF2MQi1WWqAanJ6Upo="
},
"inherits": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
@ -1113,10 +1098,13 @@
"integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ="
},
"is-symbol": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.1.tgz",
"integrity": "sha1-PMWfAAJRlLarLjjbrmaJJWtmBXI=",
"dev": true
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.2.tgz",
"integrity": "sha512-HS8bZ9ox60yCJLH9snBpIwv9pYUAkcuLhSA1oero1UB5y9aiQpRA8y2ex945AOtCZL1lJDeIk3G5LthswI46Lw==",
"dev": true,
"requires": {
"has-symbols": "^1.0.0"
}
},
"is-typedarray": {
"version": "1.0.0",
@ -1295,12 +1283,6 @@
"yallist": "^2.1.2"
}
},
"map-stream": {
"version": "0.1.0",
"resolved": "https://registry.npmjs.org/map-stream/-/map-stream-0.1.0.tgz",
"integrity": "sha1-5WqpTEyAVaFkBKBnS3jyFffI4ZQ=",
"dev": true
},
"markdown-it": {
"version": "8.4.2",
"resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-8.4.2.tgz",
@ -1408,9 +1390,9 @@
}
},
"moment": {
"version": "2.22.2",
"resolved": "https://registry.npmjs.org/moment/-/moment-2.22.2.tgz",
"integrity": "sha1-PCV/mDn8DpP/UxSWMiOeuQeD/2Y="
"version": "2.24.0",
"resolved": "https://registry.npmjs.org/moment/-/moment-2.24.0.tgz",
"integrity": "sha512-bV7f+6l2QigeBBZSM/6yTNq4P2fNpSWj/0e7jQcy87A8e7o2nAfP/34/2ky5Vw4B9S446EtIhodAzkFCcR4dQg=="
},
"moment-duration-format": {
"version": "2.2.2",
@ -1463,9 +1445,9 @@
"integrity": "sha1-KzJxhOiZIQEXeyhWP7XnECrNDKk="
},
"nice-try": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.4.tgz",
"integrity": "sha512-2NpiFHqC87y/zFke0fC0spBXL3bBsoh/p5H1EFhshxjCR5+0g2d6BiXbUFz9v1sAcxsk2htp2eQnNIci2dIYcA==",
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz",
"integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==",
"dev": true
},
"normalize-package-data": {
@ -1480,17 +1462,17 @@
}
},
"npm-run-all": {
"version": "4.1.3",
"resolved": "https://registry.npmjs.org/npm-run-all/-/npm-run-all-4.1.3.tgz",
"integrity": "sha512-aOG0N3Eo/WW+q6sUIdzcV2COS8VnTZCmdji0VQIAZF3b+a3YWb0AD0vFIyjKec18A7beLGbaQ5jFTNI2bPt9Cg==",
"version": "4.1.5",
"resolved": "https://registry.npmjs.org/npm-run-all/-/npm-run-all-4.1.5.tgz",
"integrity": "sha512-Oo82gJDAVcaMdi3nuoKFavkIHBRVqQ1qvMb+9LHk/cF4P6B2m8aP04hGf7oL6wZ9BuGwX1onlLhpuoofSyoQDQ==",
"dev": true,
"requires": {
"ansi-styles": "^3.2.0",
"chalk": "^2.1.0",
"cross-spawn": "^6.0.4",
"ansi-styles": "^3.2.1",
"chalk": "^2.4.1",
"cross-spawn": "^6.0.5",
"memorystream": "^0.3.1",
"minimatch": "^3.0.4",
"ps-tree": "^1.1.0",
"pidtree": "^0.3.0",
"read-pkg": "^3.0.0",
"shell-quote": "^1.6.1",
"string.prototype.padend": "^3.0.0"
@ -1605,6 +1587,7 @@
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
"integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
"optional": true,
"requires": {
"wrappy": "1"
}
@ -1692,20 +1675,17 @@
"pify": "^2.0.0"
}
},
"pause-stream": {
"version": "0.0.11",
"resolved": "https://registry.npmjs.org/pause-stream/-/pause-stream-0.0.11.tgz",
"integrity": "sha1-/lo0sMvOErWqaitAPuLnO2AvFEU=",
"dev": true,
"requires": {
"through": "~2.3"
}
},
"performance-now": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz",
"integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns="
},
"pidtree": {
"version": "0.3.0",
"resolved": "https://registry.npmjs.org/pidtree/-/pidtree-0.3.0.tgz",
"integrity": "sha512-9CT4NFlDcosssyg8KVFltgokyKZIFjoBxw8CTGy+5F38Y1eQWrt8tRayiUOXE+zVKQnYu5BR8JjCtvK3BcnBhg==",
"dev": true
},
"pify": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
@ -1740,15 +1720,6 @@
"dev": true,
"optional": true
},
"ps-tree": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/ps-tree/-/ps-tree-1.1.0.tgz",
"integrity": "sha1-tCGyQUDWID8e08dplrRCewjowBQ=",
"dev": true,
"requires": {
"event-stream": "~3.3.0"
}
},
"pseudomap": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz",
@ -2264,15 +2235,6 @@
"resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.0.tgz",
"integrity": "sha512-2+EPwgbnmOIl8HjGBXXMd9NAu02vLjOO1nWw4kmeRDFyHn+M/ETfHxQUK0oXg8ctgVnl9t3rosNVsZ1jG61nDA=="
},
"split": {
"version": "0.3.3",
"resolved": "https://registry.npmjs.org/split/-/split-0.3.3.tgz",
"integrity": "sha1-zQ7qXmOiEd//frDwkcQTPi0N0o8=",
"dev": true,
"requires": {
"through": "2"
}
},
"sprintf-js": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz",
@ -2304,15 +2266,6 @@
"resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz",
"integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow="
},
"stream-combiner": {
"version": "0.0.4",
"resolved": "https://registry.npmjs.org/stream-combiner/-/stream-combiner-0.0.4.tgz",
"integrity": "sha1-TV5DPBhSYd3mI8o/RMWGvPXErRQ=",
"dev": true,
"requires": {
"duplexer": "~0.1.1"
}
},
"string-width": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz",
@ -2380,12 +2333,6 @@
"has-flag": "^3.0.0"
}
},
"through": {
"version": "2.3.8",
"resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz",
"integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=",
"dev": true
},
"to-fast-properties": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-1.0.3.tgz",
@ -2604,7 +2551,8 @@
"wrappy": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
"integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8="
"integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=",
"optional": true
},
"y18n": {
"version": "3.2.1",

5
package.json

@ -30,9 +30,10 @@
"electrum-client": "github:chaintools/node-electrum-client#43a999036f9c5",
"express": "^4.16.4",
"express-session": "1.15.6",
"influx": "5.0.7",
"jstransformer-markdown-it": "^2.0.0",
"lru-cache": "4.1.3",
"moment": "^2.21.0",
"moment": "^2.24.0",
"moment-duration-format": "2.2.2",
"morgan": "^1.9.1",
"pug": "2.0.1",
@ -43,6 +44,6 @@
},
"devDependencies": {
"less": "3.8.0",
"npm-run-all": "^4.1.3"
"npm-run-all": "^4.1.5"
}
}

Loading…
Cancel
Save