Skip to content

Commit 0633de2

Browse files
committed
add fee stats ETL
1 parent 9ddc33d commit 0633de2

File tree

1 file changed

+157
-0
lines changed

1 file changed

+157
-0
lines changed

scripts/feeStats.js

Lines changed: 157 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,157 @@
1+
var config = require('../config/import.config');
2+
var request = require('request-promise');
3+
var WebSocket = require('ws');
4+
var Logger = require('../lib/logger');
5+
var log = new Logger({scope : 'fee etl'});
6+
var colors = require('colors');
7+
var smoment = require('../lib/smoment');
8+
var CronJob = require('cron').CronJob;
9+
var Hbase = require('../lib/hbase/hbase-client');
10+
var hbase = new Hbase(config.get('hbase'));
11+
var nodemailer = require('nodemailer');
12+
var transporter = nodemailer.createTransport();
13+
var QUEUE_THRESHOLD = config.get('queue_threshold') || 80;
14+
var inactive = true;
15+
16+
log.info(('queue threshold: ' + QUEUE_THRESHOLD + '%').red);
17+
18+
/**
19+
* dropsToXRP
20+
*/
21+
22+
function dropsToXRP(d) {
23+
return Number(d) / 1000000;
24+
}
25+
26+
/**
27+
* getFeeStats
28+
*/
29+
30+
function getFeeStats() {
31+
var date = smoment();
32+
33+
return request({
34+
url: config.get('fee_url'),
35+
timeout: 3000,
36+
json: {
37+
method: 'fee',
38+
params: [{}]
39+
}
40+
})
41+
.then(function(d) {
42+
if (d.result.status === 'error') {
43+
throw new Error(result.error_message);
44+
}
45+
46+
// max queue size is 20x expected ledger size
47+
var max = Number(d.result.expected_ledger_size) * 20;
48+
var pct = Number(d.result.current_queue_size) / max * 100;
49+
50+
return {
51+
date: date,
52+
data: {
53+
date: date.format(),
54+
current_ledger_size: Number(d.result.current_ledger_size),
55+
expected_ledger_size: Number(d.result.expected_ledger_size),
56+
current_queue_size: Number(d.result.current_queue_size),
57+
pct_max_queue_size: pct.toFixed(2),
58+
minimum_fee: dropsToXRP(d.result.drops.minimum_fee),
59+
open_ledger_fee: dropsToXRP(d.result.drops.open_ledger_fee),
60+
median_fee: dropsToXRP(d.result.drops.median_fee)
61+
}
62+
};
63+
});
64+
}
65+
66+
/**
67+
* saveFeeStats
68+
*/
69+
70+
function saveFeeStats(d) {
71+
return hbase.putRow({
72+
table: 'fee_stats',
73+
rowkey: 'raw|' + d.date.hbaseFormatStartRow(),
74+
columns: d.data
75+
}).then(function() {
76+
log.info(d.date.format(),
77+
('ledger size:' + d.data.current_ledger_size).cyan,
78+
(d.data.pct_max_queue_size + '% of max').green);
79+
return d;
80+
});
81+
}
82+
83+
/**
84+
* checkAlerts
85+
*/
86+
87+
function checkAlerts(d) {
88+
var recipients = config.get('recipients');
89+
var pct = Number(d.data.pct_max_queue_size);
90+
var params = {};
91+
92+
if (inactive && pct >= QUEUE_THRESHOLD && recipients) {
93+
94+
//limit notifications to
95+
//no more than 1 every 5 minutes
96+
inactive = false;
97+
setTimeout(function(d) {
98+
inactive = true;
99+
}, 5 * 60 * 1000);
100+
101+
params.from = 'Ripple Fee Notification <notify@ripple.com>';
102+
params.to = recipients;
103+
params.subject = 'Pct max queue exeeded threshold: ' + pct + '%';
104+
params.html = 'The current que size exceeded ' + QUEUE_THRESHOLD + '%' +
105+
' of the max threshold size.<br>' +
106+
'<ul><li>Date: ' + d.date.format('LLLL z') + '</li>' +
107+
'<li>percent of max queue size: ' + pct + '%</li>' +
108+
'<li>current queue size: ' + d.data.current_queue_size + '</li>' +
109+
'<li>expected ledger size: ' + d.data.expected_ledger_size + '</li>' +
110+
'<ul>';
111+
112+
return new Promise(function(resolve, reject) {
113+
transporter.sendMail(params, function(err, info) {
114+
if (err) {
115+
reject(err);
116+
} else {
117+
log.info('Notification sent: ',
118+
pct + '%',
119+
'(threshold:' + QUEUE_THRESHOLD + '%)');
120+
resolve(d);
121+
}
122+
});
123+
});
124+
} else {
125+
return d;
126+
}
127+
}
128+
129+
/**
130+
* aggregate
131+
*/
132+
133+
function aggregate(d) {
134+
return d;
135+
}
136+
137+
/**
138+
* importFeeStats
139+
*/
140+
141+
function importFeeStats() {
142+
return getFeeStats()
143+
.then(saveFeeStats)
144+
.then(checkAlerts)
145+
.then(aggregate)
146+
.catch(function(e) {
147+
console.log(e);
148+
console.log(e.stack);
149+
})
150+
}
151+
152+
// setup cron job
153+
var cron = new CronJob({
154+
cronTime: '*/5 * * * * *',
155+
onTick: importFeeStats,
156+
start: true
157+
});

0 commit comments

Comments
 (0)