227 lines
		
	
	
		
			9.0 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			227 lines
		
	
	
		
			9.0 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
| from __future__ import print_function, unicode_literals
 | |
| import os, time, json
 | |
| from collections import defaultdict
 | |
| import click
 | |
| from humanize import naturalsize
 | |
| from .database import get_db
 | |
| 
 | |
| def abbrev(t):
 | |
|     if t is None:
 | |
|         return "-"
 | |
|     if t > 1.0:
 | |
|         return "%.3fs" % t
 | |
|     if t > 1e-3:
 | |
|         return "%.1fms" % (t*1e3)
 | |
|     return "%.1fus" % (t*1e6)
 | |
| 
 | |
| 
 | |
| def print_event(event):
 | |
|     event_type, started, result, total_bytes, waiting_time, total_time = event
 | |
|     followthrough = None
 | |
|     if waiting_time and total_time:
 | |
|         followthrough = total_time - waiting_time
 | |
|     print("%17s: total=%7s wait=%7s ft=%7s size=%s (%s)" %
 | |
|           ("%s-%s" % (event_type, result),
 | |
|            abbrev(total_time),
 | |
|            abbrev(waiting_time),
 | |
|            abbrev(followthrough),
 | |
|            naturalsize(total_bytes),
 | |
|            time.ctime(started),
 | |
|           ))
 | |
| 
 | |
| def show_usage(args):
 | |
|     print("closed for renovation")
 | |
|     return 0
 | |
|     if not os.path.exists("relay.sqlite"):
 | |
|         raise click.UsageError(
 | |
|             "cannot find relay.sqlite, please run from the server directory"
 | |
|         )
 | |
|     oldest = None
 | |
|     newest = None
 | |
|     rendezvous_counters = defaultdict(int)
 | |
|     transit_counters = defaultdict(int)
 | |
|     total_transit_bytes = 0
 | |
|     db = get_db("relay.sqlite")
 | |
|     c = db.execute("SELECT * FROM `usage`"
 | |
|                    " ORDER BY `started` ASC LIMIT ?",
 | |
|                    (args.n,))
 | |
|     for row in c.fetchall():
 | |
|         if row["type"] == "rendezvous":
 | |
|             counters = rendezvous_counters
 | |
|         elif row["type"] == "transit":
 | |
|             counters = transit_counters
 | |
|             total_transit_bytes += row["total_bytes"]
 | |
|         else:
 | |
|             continue
 | |
|         counters["total"] += 1
 | |
|         counters[row["result"]] += 1
 | |
|         if oldest is None or row["started"] < oldest:
 | |
|             oldest = row["started"]
 | |
|         if newest is None or row["started"] > newest:
 | |
|             newest = row["started"]
 | |
|         event = (row["type"], row["started"], row["result"],
 | |
|                  row["total_bytes"], row["waiting_time"], row["total_time"])
 | |
|         print_event(event)
 | |
|     if rendezvous_counters["total"] or transit_counters["total"]:
 | |
|         print("---")
 | |
|         print("(most recent started %s ago)" % abbrev(time.time() - newest))
 | |
|     if rendezvous_counters["total"]:
 | |
|         print("rendezvous events:")
 | |
|         counters = rendezvous_counters
 | |
|         elapsed = time.time() - oldest
 | |
|         total = counters["total"]
 | |
|         print(" %d events in %s (%.2f per hour)" % (total, abbrev(elapsed),
 | |
|                                                     (3600 * total / elapsed)))
 | |
|         print("", ", ".join(["%s=%d (%d%%)" %
 | |
|                              (k, counters[k], (100.0 * counters[k] / total))
 | |
|                              for k in sorted(counters)
 | |
|                              if k != "total"]))
 | |
|     if transit_counters["total"]:
 | |
|         print("transit events:")
 | |
|         counters = transit_counters
 | |
|         elapsed = time.time() - oldest
 | |
|         total = counters["total"]
 | |
|         print(" %d events in %s (%.2f per hour)" % (total, abbrev(elapsed),
 | |
|                                                     (3600 * total / elapsed)))
 | |
|         rate = total_transit_bytes / elapsed
 | |
|         print(" %s total bytes, %sps" % (naturalsize(total_transit_bytes),
 | |
|                                          naturalsize(rate)))
 | |
|         print("", ", ".join(["%s=%d (%d%%)" %
 | |
|                              (k, counters[k], (100.0 * counters[k] / total))
 | |
|                              for k in sorted(counters)
 | |
|                              if k != "total"]))
 | |
|     return 0
 | |
| 
 | |
| def tail_usage(args):
 | |
|     if not os.path.exists("relay.sqlite"):
 | |
|         raise click.UsageError(
 | |
|             "cannot find relay.sqlite, please run from the server directory"
 | |
|         )
 | |
|     db = get_db("relay.sqlite")
 | |
|     # we don't seem to have unique row IDs, so this is an inaccurate and
 | |
|     # inefficient hack
 | |
|     seen = set()
 | |
|     try:
 | |
|         while True:
 | |
|             old = time.time() - 2*60*60
 | |
|             c = db.execute("SELECT * FROM `usage`"
 | |
|                            " WHERE `started` > ?"
 | |
|                            " ORDER BY `started` ASC", (old,))
 | |
|             for row in c.fetchall():
 | |
|                 event = (row["type"], row["started"], row["result"],
 | |
|                          row["total_bytes"], row["waiting_time"],
 | |
|                          row["total_time"])
 | |
|                 if event not in seen:
 | |
|                     print_event(event)
 | |
|                     seen.add(event)
 | |
|             time.sleep(2)
 | |
|     except KeyboardInterrupt:
 | |
|         return 0
 | |
|     return 0
 | |
| 
 | |
| def count_channels(args):
 | |
|     if not os.path.exists("relay.sqlite"):
 | |
|         raise click.UsageError(
 | |
|             "cannot find relay.sqlite, please run from the server directory"
 | |
|         )
 | |
|     db = get_db("relay.sqlite")
 | |
|     c_list = []
 | |
|     c_dict = {}
 | |
|     def add(key, value):
 | |
|         c_list.append((key, value))
 | |
|         c_dict[key] = value
 | |
|     OLD = time.time() - 10*60
 | |
|     def q(query, values=()):
 | |
|         return list(db.execute(query, values).fetchone().values())[0]
 | |
|     add("apps", q("SELECT COUNT(DISTINCT(`app_id`)) FROM `nameplates`"))
 | |
| 
 | |
|     add("total nameplates", q("SELECT COUNT() FROM `nameplates`"))
 | |
|     add("waiting nameplates", q("SELECT COUNT() FROM `nameplates`"
 | |
|                                 " WHERE `second` is null"))
 | |
|     add("connected nameplates", q("SELECT COUNT() FROM `nameplates`"
 | |
|                                   " WHERE `second` is not null"))
 | |
|     add("stale nameplates", q("SELECT COUNT() FROM `nameplates`"
 | |
|                               " where `updated` < ?", (OLD,)))
 | |
| 
 | |
|     add("total mailboxes", q("SELECT COUNT() FROM `mailboxes`"))
 | |
|     add("waiting mailboxes", q("SELECT COUNT() FROM `mailboxes`"
 | |
|                                 " WHERE `second` is null"))
 | |
|     add("connected mailboxes", q("SELECT COUNT() FROM `mailboxes`"
 | |
|                                  " WHERE `second` is not null"))
 | |
| 
 | |
|     stale_mailboxes = 0
 | |
|     for mbox_row in db.execute("SELECT * FROM `mailboxes`").fetchall():
 | |
|         newest = db.execute("SELECT `server_rx` FROM `messages`"
 | |
|                             " WHERE `app_id`=? AND `mailbox_id`=?"
 | |
|                             " ORDER BY `server_rx` DESC LIMIT 1",
 | |
|                             (mbox_row["app_id"], mbox_row["id"])).fetchone()
 | |
|         if newest and newest[0] < OLD:
 | |
|             stale_mailboxes += 1
 | |
|     add("stale mailboxes", stale_mailboxes)
 | |
| 
 | |
|     add("messages", q("SELECT COUNT() FROM `messages`"))
 | |
| 
 | |
|     if args.json:
 | |
|         print(json.dumps(c_dict))
 | |
|     else:
 | |
|         for (key, value) in c_list:
 | |
|             print(key, value)
 | |
|     return 0
 | |
| 
 | |
| def count_events(args):
 | |
|     if not os.path.exists("relay.sqlite"):
 | |
|         raise click.UsageError(
 | |
|             "cannot find relay.sqlite, please run from the server directory"
 | |
|         )
 | |
|     db = get_db("relay.sqlite")
 | |
|     c_list = []
 | |
|     c_dict = {}
 | |
|     def add(key, value):
 | |
|         c_list.append((key, value))
 | |
|         c_dict[key] = value
 | |
|     def q(query, values=()):
 | |
|         return list(db.execute(query, values).fetchone().values())[0]
 | |
| 
 | |
|     add("apps", q("SELECT COUNT(DISTINCT(`app_id`)) FROM `nameplate_usage`"))
 | |
| 
 | |
|     add("total nameplates", q("SELECT COUNT() FROM `nameplate_usage`"))
 | |
|     add("happy nameplates", q("SELECT COUNT() FROM `nameplate_usage`"
 | |
|                               " WHERE `result`='happy'"))
 | |
|     add("lonely nameplates", q("SELECT COUNT() FROM `nameplate_usage`"
 | |
|                                " WHERE `result`='lonely'"))
 | |
|     add("pruney nameplates", q("SELECT COUNT() FROM `nameplate_usage`"
 | |
|                                " WHERE `result`='pruney'"))
 | |
|     add("crowded nameplates", q("SELECT COUNT() FROM `nameplate_usage`"
 | |
|                                 " WHERE `result`='crowded'"))
 | |
| 
 | |
|     add("total mailboxes", q("SELECT COUNT() FROM `mailbox_usage`"))
 | |
|     add("happy mailboxes", q("SELECT COUNT() FROM `mailbox_usage`"
 | |
|                              " WHERE `result`='happy'"))
 | |
|     add("scary mailboxes", q("SELECT COUNT() FROM `mailbox_usage`"
 | |
|                              " WHERE `result`='scary'"))
 | |
|     add("lonely mailboxes", q("SELECT COUNT() FROM `mailbox_usage`"
 | |
|                               " WHERE `result`='lonely'"))
 | |
|     add("errory mailboxes", q("SELECT COUNT() FROM `mailbox_usage`"
 | |
|                               " WHERE `result`='errory'"))
 | |
|     add("pruney mailboxes", q("SELECT COUNT() FROM `mailbox_usage`"
 | |
|                               " WHERE `result`='pruney'"))
 | |
|     add("crowded mailboxes", q("SELECT COUNT() FROM `mailbox_usage`"
 | |
|                                " WHERE `result`='crowded'"))
 | |
| 
 | |
|     add("total transit", q("SELECT COUNT() FROM `transit_usage`"))
 | |
|     add("happy transit", q("SELECT COUNT() FROM `transit_usage`"
 | |
|                            " WHERE `result`='happy'"))
 | |
|     add("lonely transit", q("SELECT COUNT() FROM `transit_usage`"
 | |
|                             " WHERE `result`='lonely'"))
 | |
|     add("errory transit", q("SELECT COUNT() FROM `transit_usage`"
 | |
|                             " WHERE `result`='errory'"))
 | |
| 
 | |
|     add("transit bytes", q("SELECT SUM(`total_bytes`) FROM `transit_usage`"))
 | |
| 
 | |
|     if args.json:
 | |
|         print(json.dumps(c_dict))
 | |
|     else:
 | |
|         for (key, value) in c_list:
 | |
|             print(key, value)
 | |
|     return 0
 |