bin/boobank-graphite
0965a9d0
 #!/usr/bin/env python
 # -*- coding: utf-8 -*-
b3c01b16
 # Copyright © 2017-2019 Xavier G. <xavier.boobank@kindwolf.org>
d72bdf5e
 # This work is free. You can redistribute it and/or modify it under the
 # terms of the Do What The Fuck You Want To Public License, Version 2,
 # as published by Sam Hocevar. See the COPYING file for more details.
2dc79bd0
 """
 boobank-graphite takes a JSON file, as created by boobank-cacher when running
 and caching a "boobank list" command, and sends it to a Graphite instance.
 """
0965a9d0
 
 import sys
 import json
 import time
 import socket
e918c811
 import argparse
2dc79bd0
 from boobank_utils import DEFAULT_CURRENCY
0965a9d0
 
 
 def main():
2dc79bd0
     """
     Main function.
     """
e918c811
     args = parse_args()
2dc79bd0
     accounts = json.load(args.json_file)
0965a9d0
     timestamp = time.time()
2dc79bd0
     graphite_socket = graphite_connect(args.host, args.port)
0965a9d0
     for account in accounts.get('data', []):
2dc79bd0
         send_account(graphite_socket, account, timestamp)
     graphite_socket.close()
0965a9d0
 
e918c811
 def parse_args():
2dc79bd0
     """
     Parse command-line arguments.
     """
     description = 'Send the contents of a boobank-cacher JSON file to Graphite.'
     args = argparse.ArgumentParser(description=description)
     args.add_argument('-gh', '--graphite-host', dest='host', default='::1',
                       help='Graphite host; defaults to ::1.')
     args.add_argument('-gp', '--graphite-port', dest='port', default='2003', type=int,
                       help='Graphite port; defaults to 2003.')
     args.add_argument('json_file', nargs='?', type=argparse.FileType('r'), default=sys.stdin,
                       help='JSON file to send to Graphite; defaults to "-" (standard input).')
     return args.parse_args()
e918c811
 
 def graphite_connect(host, port):
2dc79bd0
     """
     Connect to the Graphite instance listening on host and port.
     """
667f9a5e
     addr_infos = socket.getaddrinfo(host, port, 0, 0, socket.IPPROTO_TCP)
     _, _, _, _, sockaddr = addr_infos[0]
     graphite_socket = socket.socket(socket.AF_INET6, socket.SOCK_STREAM, 0)
     graphite_socket.connect(sockaddr)
0965a9d0
     return graphite_socket
 
 def get_path(account):
2dc79bd0
     """
     Return the path to send to Graphite for the given bank account.
     The following scheme is used:
     bank.<bank id>.<account id>-balance-<currency>
     """
     (account_id, bank) = account['id'].split('@')
     currency = account.get('currency', DEFAULT_CURRENCY).lower()
     return 'bank.%s.%s-balance-%s' % (bank, account_id, currency)
0965a9d0
 
2dc79bd0
 def send_account(graphite_socket, account, timestamp):
     """
     Send the balance of the given bank account to Graphite over the given TCP
     socket.
     """
0965a9d0
     pattern = '%s %.2f %d\n'
1076bfa5
     values = (get_path(account), float(account['balance']), int(timestamp))
0965a9d0
     line = pattern % values
2dc79bd0
     graphite_socket.send(line)
0965a9d0
 
 if __name__ == '__main__':
     main()