mirror of
https://github.com/aljazceru/plugins.git
synced 2025-12-23 16:14:20 +01:00
summary: adds 72hr availability measurement
this applies a 72hr exponential smoothed sliding window to the online/offline availability state of a peer.
This commit is contained in:
committed by
Christian Decker
parent
e484db385a
commit
14ad827fb8
@@ -2,6 +2,7 @@
|
|||||||
from pyln.client import Plugin, Millisatoshi
|
from pyln.client import Plugin, Millisatoshi
|
||||||
from packaging import version
|
from packaging import version
|
||||||
from collections import namedtuple
|
from collections import namedtuple
|
||||||
|
from datetime import datetime
|
||||||
import pyln.client
|
import pyln.client
|
||||||
from math import floor, log10
|
from math import floor, log10
|
||||||
import requests
|
import requests
|
||||||
@@ -29,6 +30,59 @@ summary_description = "Gets summary information about this node.\n"\
|
|||||||
"Pass a list of scids to the {exclude} parameter"\
|
"Pass a list of scids to the {exclude} parameter"\
|
||||||
" to exclude some channels from the outputs."
|
" to exclude some channels from the outputs."
|
||||||
|
|
||||||
|
# Global state to measure online% and last_seen
|
||||||
|
peerstate = {}
|
||||||
|
|
||||||
|
|
||||||
|
# ensure an rpc peer is added
|
||||||
|
def addpeer(p):
|
||||||
|
pid = p['id']
|
||||||
|
if not pid in peerstate:
|
||||||
|
peerstate[pid] = {
|
||||||
|
'connected' : p['connected'],
|
||||||
|
'last_seen' : datetime.now() if p['connected'] else None,
|
||||||
|
'availability' : 1.0 if p['connected'] else 0.0
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class PeerThread(threading.Thread):
|
||||||
|
def __init__(self):
|
||||||
|
super().__init__()
|
||||||
|
self.daemon = True
|
||||||
|
|
||||||
|
def run(self):
|
||||||
|
interval = 5 * 60 # collect peer state once in a while
|
||||||
|
window = 3 * 24 * 60 * 60 # 72hr availability window
|
||||||
|
count = 0
|
||||||
|
|
||||||
|
# delay initial execution, so peers have a chance to connect on startup
|
||||||
|
time.sleep(interval)
|
||||||
|
|
||||||
|
while True:
|
||||||
|
count += 1
|
||||||
|
leadwin = max(min(window, count * interval), interval)
|
||||||
|
samples = leadwin / interval
|
||||||
|
alpha = 1.0 / samples
|
||||||
|
beta = 1.0 - alpha
|
||||||
|
|
||||||
|
try:
|
||||||
|
peers = plugin.rpc.listpeers()
|
||||||
|
for p in peers['peers']:
|
||||||
|
pid = p['id']
|
||||||
|
addpeer(p)
|
||||||
|
|
||||||
|
if p['connected']:
|
||||||
|
peerstate[pid]['last_seen'] = datetime.now()
|
||||||
|
peerstate[pid]['connected'] = True
|
||||||
|
peerstate[pid]['availability'] = 1.0 * alpha + peerstate[pid]['availability'] * beta
|
||||||
|
else:
|
||||||
|
peerstate[pid]['connected'] = False
|
||||||
|
peerstate[pid]['availability'] = 0.0 * alpha + peerstate[pid]['availability'] * beta
|
||||||
|
except Exception as ex:
|
||||||
|
plugin.log("[PeerThread] " + str(ex), 'error')
|
||||||
|
time.sleep(interval)
|
||||||
|
|
||||||
|
|
||||||
class PriceThread(threading.Thread):
|
class PriceThread(threading.Thread):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
super().__init__()
|
super().__init__()
|
||||||
@@ -87,7 +141,7 @@ def msat_to_approx_str(msat, digits: int = 3):
|
|||||||
# appends an output table header that explains fields and capacity
|
# appends an output table header that explains fields and capacity
|
||||||
def append_header(table, max_msat):
|
def append_header(table, max_msat):
|
||||||
short_str = msat_to_approx_str(Millisatoshi(max_msat))
|
short_str = msat_to_approx_str(Millisatoshi(max_msat))
|
||||||
table.append("%c%-13sOUT/OURS %c IN/THEIRS%12s%c SCID FLAG ALIAS"
|
table.append("%c%-13sOUT/OURS %c IN/THEIRS%12s%c SCID FLAG AVAIL ALIAS"
|
||||||
% (draw.left, short_str, draw.mid, short_str, draw.right))
|
% (draw.left, short_str, draw.mid, short_str, draw.right))
|
||||||
|
|
||||||
|
|
||||||
@@ -122,6 +176,8 @@ def summary(plugin, exclude=''):
|
|||||||
reply['num_connected'] = 0
|
reply['num_connected'] = 0
|
||||||
reply['num_gossipers'] = 0
|
reply['num_gossipers'] = 0
|
||||||
for p in peers['peers']:
|
for p in peers['peers']:
|
||||||
|
pid = p['id']
|
||||||
|
addpeer(p)
|
||||||
active_channel = False
|
active_channel = False
|
||||||
for c in p['channels']:
|
for c in p['channels']:
|
||||||
if c['state'] != 'CHANNELD_NORMAL':
|
if c['state'] != 'CHANNELD_NORMAL':
|
||||||
@@ -145,7 +201,15 @@ def summary(plugin, exclude=''):
|
|||||||
to_them = Millisatoshi(0)
|
to_them = Millisatoshi(0)
|
||||||
avail_in += to_them
|
avail_in += to_them
|
||||||
reply['num_channels'] += 1
|
reply['num_channels'] += 1
|
||||||
chans.append((c['total_msat'], to_us, to_them, p['id'], c['private'], p['connected'], c['short_channel_id']))
|
chans.append((
|
||||||
|
c['total_msat'],
|
||||||
|
to_us, to_them,
|
||||||
|
p['id'],
|
||||||
|
c['private'],
|
||||||
|
p['connected'],
|
||||||
|
c['short_channel_id'],
|
||||||
|
peerstate[pid]['availability']
|
||||||
|
))
|
||||||
|
|
||||||
if not active_channel and p['connected']:
|
if not active_channel and p['connected']:
|
||||||
reply['num_gossipers'] += 1
|
reply['num_gossipers'] += 1
|
||||||
@@ -203,6 +267,10 @@ def summary(plugin, exclude=''):
|
|||||||
extra += '_'
|
extra += '_'
|
||||||
s += '[{}] '.format(extra)
|
s += '[{}] '.format(extra)
|
||||||
|
|
||||||
|
# append 24hr availability
|
||||||
|
s += '{:4.0%} '.format(c[7])
|
||||||
|
|
||||||
|
# append alias or id
|
||||||
node = plugin.rpc.listnodes(c[3])['nodes']
|
node = plugin.rpc.listnodes(c[3])['nodes']
|
||||||
if len(node) != 0 and 'alias' in node[0]:
|
if len(node) != 0 and 'alias' in node[0]:
|
||||||
s += node[0]['alias']
|
s += node[0]['alias']
|
||||||
@@ -222,6 +290,8 @@ def init(options, configuration, plugin):
|
|||||||
plugin.fiat_per_btc = 0
|
plugin.fiat_per_btc = 0
|
||||||
info = plugin.rpc.getinfo()
|
info = plugin.rpc.getinfo()
|
||||||
|
|
||||||
|
# Measure availability
|
||||||
|
PeerThread().start()
|
||||||
# Try to grab conversion price
|
# Try to grab conversion price
|
||||||
PriceThread().start()
|
PriceThread().start()
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user