44import logging
55import time
66import os
7- import sys
87import json
98import requests
10- import pygelf
11- from prometheus_client import start_http_server
12- from prometheus_client .core import REGISTRY , GaugeMetricFamily
13- from .lib import constants
149
15- LOG = logging .getLogger (__name__ )
16- logging .basicConfig (
17- stream = sys .stdout ,
18- level = os .environ .get ("LOGLEVEL" , "INFO" ),
19- format = '%(asctime)s.%(msecs)03d %(levelname)s {%(module)s} [%(funcName)s] %(message)s' ,
20- datefmt = '%Y-%m-%d %H:%M:%S'
21- )
10+ log = logging .getLogger (__package__ )
2211
23- FILENAME = os .path .splitext (sys .modules ['__main__' ].__file__ )[0 ]
24- version = f'{ constants .VERSION } -{ constants .BUILD } '
2512
26-
27- def configure_logging ():
28- """ Configures the logging """
29- gelf_enabled = False
30-
31- if os .environ .get ('GELF_HOST' ):
32- GELF = pygelf .GelfUdpHandler (
33- host = os .environ .get ('GELF_HOST' ),
34- port = int (os .environ .get ('GELF_PORT' , 12201 )),
35- debug = True ,
36- include_extra_fields = True ,
37- _ix_id = FILENAME
38- )
39- LOG .addHandler (GELF )
40- gelf_enabled = True
41- LOG .info (f'Initialized logging with GELF enabled: { gelf_enabled } ' )
42-
43-
44- class EtherscanCollector :
13+ class Etherscan :
4514 """ The EtherscanCollector class """
4615
4716 accounts = {}
@@ -62,10 +31,10 @@ def __init__(self):
6231
6332 def get_tokens (self ):
6433 """ Gets the tokens from an account """
65-
66- time .sleep (1 ) # Ensure that we don't get rate limited
34+ log .info ('Retrieving the tokens' )
6735 for account in self .accounts :
6836 for token in self .settings ['tokens' ]:
37+ log .debug (f"Retrieving the balance for { token ['short' ]} on the account { account } " )
6938 request_data = {
7039 'module' : 'account' ,
7140 'action' : 'tokenbalance' ,
@@ -77,14 +46,13 @@ def get_tokens(self):
7746 decimals = 18
7847 if token .get ('decimals' , - 1 ) >= 0 :
7948 decimals = int (token ['decimals' ])
80- LOG .debug (f"{ decimals } decimals for { token ['short' ]} " )
8149 try :
8250 req = requests .get (self .settings ['url' ], params = request_data ).json ()
8351 except (
8452 requests .exceptions .ConnectionError ,
8553 requests .exceptions .ReadTimeout ,
8654 ) as error :
87- LOG .exception (f'Exception caught: { error } ' )
55+ log .exception (f'Exception caught: { error } ' )
8856 req = {}
8957 if req .get ('result' ) and int (req ['result' ]) > 0 :
9058 self .tokens .update ({
@@ -96,79 +64,32 @@ def get_tokens(self):
9664 'value' : int (req ['result' ]) / (10 ** decimals ) if decimals > 0 else int (req ['result' ])
9765 }
9866 })
99-
100- LOG .debug (f'Tokens: { self .tokens } ' )
67+ time .sleep (1 ) # Ensure that we don't get rate limited
68+ log .debug (f'Tokens: { self .tokens } ' )
69+ return self .tokens
10170
10271 def get_balances (self ):
10372 """ Gets the current balance for an account """
73+ log .info ('Retrieving the account balances' )
10474 request_data = {
10575 'module' : 'account' ,
10676 'action' : 'balancemulti' ,
10777 'address' : self .settings ['addresses' ],
10878 'tag' : 'latest' ,
10979 'apikey' : self .settings ['api_key' ],
11080 }
111- LOG .debug (f'Request data: { request_data } ' )
11281 try :
11382 req = requests .get (self .settings ['url' ], params = request_data ).json ()
11483 except (
11584 requests .exceptions .ConnectionError ,
11685 requests .exceptions .ReadTimeout ,
11786 ) as error :
118- LOG .exception (f'Exception caught: { error } ' )
87+ log .exception (f'Exception caught: { error } ' )
11988 req = {}
12089 if req .get ('message' ) == 'OK' and req .get ('result' ):
12190 for result in req .get ('result' ):
12291 self .accounts .update ({
12392 result ['account' ]: float (result ['balance' ])/ (1000000000000000000 )
12493 })
125- LOG .debug (f'Accounts: { self .accounts } ' )
126-
127- def describe (self ):
128- """ Just a needed method, so that collect() isn't called at startup """
129- return []
130-
131- def collect (self ):
132- """The method that actually does the collecting"""
133- metrics = {
134- 'account_balance' : GaugeMetricFamily (
135- 'account_balance' ,
136- 'Account Balance' ,
137- labels = ['source_currency' , 'currency' , 'account' , 'type' ]
138- ),
139- }
140- self .get_balances ()
141- for account in self .accounts :
142- metrics ['account_balance' ].add_metric (
143- value = (self .accounts [account ]),
144- labels = [
145- 'ETH' ,
146- 'ETH' ,
147- account ,
148- 'etherscan'
149- ]
150- )
151-
152- self .get_tokens ()
153- for token in self .tokens :
154- metrics ['account_balance' ].add_metric (
155- value = (self .tokens [token ]['value' ]),
156- labels = [
157- self .tokens [token ]['name_short' ],
158- self .tokens [token ]['name_short' ],
159- self .tokens [token ]['account' ],
160- 'etherscan'
161- ]
162- )
163- for metric in metrics .values ():
164- yield metric
165-
166-
167- if __name__ == '__main__' :
168- configure_logging ()
169- port = int (os .environ .get ('PORT' , 9308 ))
170- LOG .info (f'Starting { __package__ } { version } on port { port } ' )
171- REGISTRY .register (EtherscanCollector ())
172- start_http_server (port )
173- while True :
174- time .sleep (1 )
94+ log .debug (f'Accounts: { self .accounts } ' )
95+ return self .accounts
0 commit comments