Skip to content

Commit

Permalink
release(nodemapper) 1.0.2 better error handling and logging
Browse files Browse the repository at this point in the history
  • Loading branch information
lalanza808 committed Sep 18, 2024
1 parent d61fa3a commit bbd4b7e
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 30 deletions.
67 changes: 39 additions & 28 deletions dockerfiles/nodemapper.py
Original file line number Diff line number Diff line change
@@ -1,17 +1,18 @@
#!/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
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
from typing import Union

import requests
import geoip2.database
from geoip2.models import City
from geoip2.errors import AddressNotFoundError
from flask import Flask, make_response

Expand All @@ -23,42 +24,52 @@
NODE_PORT = env.get('NODE_PORT', 18083)


def get_geoip(ip):
"""Takes an IP address and determines GeoIP data"""
def get_geoip(ip) -> Union[City, None]:
"""Takes an IP address and determines GeoIP data if possible"""
try:
with geoip2.database.Reader("./geoip.mmdb") as reader:
return reader.city(ip)
except AddressNotFoundError:
print(f"{ip} not found in GeoIP database")
return None
except Exception as e:
print(f"Error getting GeoIP data for {ip}: {e}")
return None

def generate_prometheus_line(ip, status) -> Union[str, None]:
"""Generate a Prometheus formatted line for a given peer given an IP and status with GeoIP data included"""
geo = get_geoip(ip)
if geo is None or 'en' not in geo.continent.names:
return None

geostr = 'geoip{{latitude="{lat}", longitude="{lon}", country_code="{country_code}", country_name="{country_name}", status="{status}"}} 1'
# print(f"Found GeoIP for {ip}: {geostr}")
return geostr.format(
lat=geo.location.latitude,
lon=geo.location.longitude,
country_code=geo.continent.code,
country_name=geo.continent.names['en'],
status=status
)

@app.route("/metrics")
def nodes():
"""Return all nodes"""
peers = list()
"""Get peer list from monerod and generate Prometheus endpoint output"""
peers_found = list()
prom_lines = list()
peer_list = requests.get(f'http://{NODE_HOST}:{NODE_PORT}/get_peer_list').json()
def add_peer(host, status):
geo = get_geoip(host)
if geo is None:
return

geostr = 'geoip{{latitude="{lat}", longitude="{lon}", country_code="{country_code}", country_name="{country_name}", status="{status}"}} 1'
if geostr not in peers:
if 'en' in geo.continent.names:
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
))
if not peer_list:
return ""
for peer in peer_list['gray_list']:
if peer.get('host'):
add_peer(peer['host'], 'gray')
peer['status'] = 'gray'
peers_found.append(peer)
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)
peer['status'] = 'white'
peers_found.append(peer)
for peer in peers_found:
prom = generate_prometheus_line(peer['host'], peer['status'])
if prom:
prom_lines.append(prom)
response = make_response('\n'.join(prom_lines), 200)
response.mimetype = "text/plain"
return response
4 changes: 2 additions & 2 deletions release.sh
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#!/bin/bash

# Build and tag container images for each service based upon passed argument; monerod, nodemapper, or exporter
# Build and tag container images for each service based upon passed argument; monerod, nodemapper, or exporter
# All are manually tagged since some do not update as frequently as others. Bump the script
# to bump the image stored on Dockerhub.

Expand All @@ -12,7 +12,7 @@ MONEROD_VERSION=v0.18.3.2
MONEROD_BASE=${DH_USER}/monerod
EXPORTER_VERSION=1.0.0
EXPORTER_BASE=${DH_USER}/exporter
NODEMAPPER_VERSION=1.0.1
NODEMAPPER_VERSION=1.0.2
NODEMAPPER_BASE=${DH_USER}/nodemapper

if [[ "${IMAGE}" == "nodemapper" ]]
Expand Down

0 comments on commit bbd4b7e

Please sign in to comment.