You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

63 lines
1.8 KiB
Python

#!/usr/bin/env python3
"""
This is a lightweight web service which will retrieve a peer list
from a Monero node, determine GeoIP information, and return
a list of metrics in a Prometheus compatible structure.
Use it to start plotting maps of active node connections.
"""
import socket, struct
from os import environ as env
import requests
import geoip2.database
from flask import Flask, make_response
app = Flask(__name__)
NODE_HOST = env.get('NODE_HOST', 'wownerod')
NODE_PORT = env.get('NODE_PORT', 34570)
def ipfi(i: int) -> str:
"""Takes an unsigned integer and converts it to an IP address. """
ip = socket.inet_ntoa(struct.pack('!L', i))
return ip
def get_geoip(ip):
"""Takes an IP address and determines GeoIP data"""
with geoip2.database.Reader("./geoip.mmdb") as reader:
return reader.city(ip)
@app.route("/metrics")
def nodes():
"""Return all nodes"""
peers = list()
peer_list = requests.get(f'http://{NODE_HOST}:{NODE_PORT}/get_peer_list').json()
def add_peer(host, status):
geo = get_geoip(host)
geostr = 'geoip{{latitude="{lat}", longitude="{lon}", country_code="{country_code}", country_name="{country_name}", status="{status}"}} 1'
if geostr not in peers:
peers.append(geostr.format(
lat=geo.location.latitude,
lon=geo.location.longitude,
country_code=geo.continent.code,
country_name=geo.continent.names['en'],
status=status
))
for peer in peer_list['gray_list']:
if peer.get('host'):
add_peer(peer['host'], 'gray')
for peer in peer_list['white_list']:
if peer.get('host'):
add_peer(peer['host'], 'white')
data = '\n'.join(peers)
response = make_response(data, 200)
response.mimetype = "text/plain"
return response