async def setup_prometheus_client(hass, hass_client, namespace): """Initialize an hass_client with Prometheus component.""" # Reset registry prometheus_client.REGISTRY = prometheus_client.CollectorRegistry(auto_describe=True) prometheus_client.ProcessCollector(registry=prometheus_client.REGISTRY) prometheus_client.PlatformCollector(registry=prometheus_client.REGISTRY) prometheus_client.GCCollector(registry=prometheus_client.REGISTRY) config = {} if namespace is not None: config[prometheus.CONF_PROM_NAMESPACE] = namespace assert await async_setup_component( hass, prometheus.DOMAIN, {prometheus.DOMAIN: config} ) await hass.async_block_till_done() return await hass_client()
def __init__(self): self.registry = prometheus_client.CollectorRegistry(auto_describe=True) prometheus_client.GCCollector(registry=self.registry) prometheus_client.PlatformCollector(registry=self.registry) prometheus_client.ProcessCollector(registry=self.registry) self.registry.register(self)
def main(): rcon = RecoveringRCON(os.getenv('RCON_HOST'), int(os.getenv('RCON_PORT')), os.getenv('RCON_PWD')) client = discord.Client() since_last_update = 0 async def background(): await client.wait_until_ready() channel = client.get_channel(CHANNEL) async def onmsg(msg): try: if msg['type'] == 'connected': asyncio.ensure_future( channel.send( discord.utils.escape_mentions( '*Server is online (' + msg['version'] + ')*'))) elif msg['type'] == 'disconnected': asyncio.ensure_future( channel.send( discord.utils.escape_mentions( '*Server is offline*'))) elif msg['type'] == 'chat': str = msg['name'] + ': ' + msg['message'] asyncio.ensure_future( channel.send(discord.utils.escape_mentions(str))) elif msg['type'] == 'left': p = await rcon.get_player_status() str = '*' + msg['name'] + ' left' + (' - ' + p if p else '') + '*' asyncio.ensure_future( channel.send(discord.utils.escape_mentions(str))) elif msg['type'] == 'joined': p = await rcon.get_player_status() str = '*' + msg['name'] + ' joined' + (' - ' + p if p else '') + '*' asyncio.ensure_future( channel.send(discord.utils.escape_mentions(str))) elif msg['type'] == 'died': cause = None if msg.get('cause', None) == None: cause = ' died of mysterious causes' elif msg['cause']['type'] == 'locomotive': cause = ' was squished by a rogue train' elif msg['cause']['type'] == 'character': if msg['cause']['player'] == msg['name']: cause = ' lost their will to live' else: cause = ' was brutally murdered by ' + msg[ 'cause']['player'] elif msg['cause']['type'] == 'tank': cause = ' was hiding in a tank\'s blind spot' elif msg['cause']['type'] == 'car': cause = ' was involved in a hit and run' elif msg['cause']['type'] == 'artillery-turret': cause = ' was mistaken for the enemy' else: cause = f' was killed by {msg["cause"]["type"]}' str = '*' + msg['name'] + cause + '*' asyncio.ensure_future( channel.send(discord.utils.escape_mentions(str))) elif msg['type'] == 'promoted': pass # do nothing as it fires upon player joining for first time and not at time of promotion which makes it meaningless elif msg['type'] == 'demoted': pass elif msg['type'] == 'kicked': str = '*{name} was kicked by {by_player}{r}*'.format( r=f': {msg["reason"]}' if msg.get('reason') else '', **msg) asyncio.ensure_future( channel.send(discord.utils.escape_mentions(str))) elif msg['type'] == 'banned': str = '*{name} was banned by {by_player}{r}*'.format( r=f': {msg["reason"]}' if msg.get('reason') else '', **msg) asyncio.ensure_future( channel.send(discord.utils.escape_mentions(str))) elif msg['type'] == 'unbanned': str = '*{name} was unbanned by {by_player}{r}*'.format( r=f': {msg["reason"]}' if msg.get('reason') else '', **msg) asyncio.ensure_future( channel.send(discord.utils.escape_mentions(str))) else: print(msg) except Exception: traceback.print_exc() @client.event async def on_ready(): print('Logged in as') print(client.user.name) print(client.user.id) print('------') @client.event async def on_message(message): if message.channel.id != CHANNEL: return nonlocal since_last_update since_last_update += 1 if STATUS_FREQUENCY != 0 and since_last_update > STATUS_FREQUENCY: since_last_update = 0 asyncio.ensure_future( channel.send( discord.utils.escape_mentions( '*' + await rcon.get_server_status() + '*'))) if message.author == client.user: return name = message.author.nick or message.author.name await rcon.send('/fadmin chat ' + name + '*: ' + message.clean_content) rcon.onmsg = onmsg await rcon.connect() await rcon.poll() def factorio_pid(): try: with open(os.getenv('FACTORIO_PIDFILE')) as f: return f.read() except OSError: return 'bad_pidfile' factorio_process = prometheus_client.ProcessCollector( 'factorio', factorio_pid) prometheus_client.REGISTRY.register(GameCollector(rcon, client.loop)) prometheus_client.start_http_server(int(os.getenv('PROMETHEUS_PORT')), os.getenv('PROMETHEUS_HOST')) try: task = client.loop.create_task(background()) client.loop.run_until_complete(client.start( os.getenv('DISCORD_TOKEN'))) except KeyboardInterrupt: task.cancel() client.loop.run_until_complete(client.logout()) finally: client.loop.close()
def __init__(self, listen_host: str) -> None: if not prometheus_available: raise RuntimeError("`prometheus_client` is not installed. " "Run `pip install 'afancontrol[metrics]'`.") self._listen_addr, port_str = listen_host.rsplit(":", 1) self._listen_port = int(port_str) self._http_server = None # type: Optional[HTTPServer] self._last_metrics_collect_clock = float("nan") # Create a separate registry for this instance instead of using # the default one (which is global and doesn't allow to instantiate # this class more than once due to having metrics below being # registered for a second time): self.registry = prom.CollectorRegistry(auto_describe=True) # Register some default prometheus_client metrics: prom.ProcessCollector(registry=self.registry) if hasattr(prom, "PlatformCollector"): prom.PlatformCollector(registry=self.registry) if hasattr(prom, "GCCollector"): prom.GCCollector(registry=self.registry) # Temps: self.temperature_is_failing = prom.Gauge( "temperature_is_failing", "The temperature sensor is failing (it isn't returning any data)", ["temp_name"], registry=self.registry, ) self.temperature_current = prom.Gauge( "temperature_current", "The current temperature value (in Celsius) from a temperature sensor", ["temp_name"], registry=self.registry, ) self.temperature_min = prom.Gauge( "temperature_min", "The min temperature value (in Celsius) for a temperature sensor", ["temp_name"], registry=self.registry, ) self.temperature_max = prom.Gauge( "temperature_max", "The max temperature value (in Celsius) for a temperature sensor", ["temp_name"], registry=self.registry, ) self.temperature_panic = prom.Gauge( "temperature_panic", "The panic temperature value (in Celsius) for a temperature sensor", ["temp_name"], registry=self.registry, ) self.temperature_threshold = prom.Gauge( "temperature_threshold", "The threshold temperature value (in Celsius) for a temperature sensor", ["temp_name"], registry=self.registry, ) self.temperature_is_panic = prom.Gauge( "temperature_is_panic", "Is panic temperature reached for a temperature sensor", ["temp_name"], registry=self.registry, ) self.temperature_is_threshold = prom.Gauge( "temperature_is_threshold", "Is threshold temperature reached for a temperature sensor", ["temp_name"], registry=self.registry, ) # Fans: self.fan_rpm = prom.Gauge( "fan_rpm", "Fan speed (in RPM) as reported by the fan", ["fan_name"], registry=self.registry, ) self.fan_pwm = prom.Gauge( "fan_pwm", "Current fan's PWM value (from 0 to 255)", ["fan_name"], registry=self.registry, ) self.fan_pwm_normalized = prom.Gauge( "fan_pwm_normalized", "Current fan's normalized PWM value (from 0.0 to 1.0, within " "the `fan_pwm_line_start` and `fan_pwm_line_end` interval)", ["fan_name"], registry=self.registry, ) self.fan_pwm_line_start = prom.Gauge( "fan_pwm_line_start", "PWM value where a linear correlation with RPM starts for the fan", ["fan_name"], registry=self.registry, ) self.fan_pwm_line_end = prom.Gauge( "fan_pwm_line_end", "PWM value where a linear correlation with RPM ends for the fan", ["fan_name"], registry=self.registry, ) self.fan_is_stopped = prom.Gauge( "fan_is_stopped", "Is PWM fan stopped because the corresponding temperatures " "are already low", ["fan_name"], registry=self.registry, ) self.fan_is_failing = prom.Gauge( "fan_is_failing", "Is PWM fan marked as failing (e.g. because it has jammed)", ["fan_name"], registry=self.registry, ) # Arduino boards: self.arduino_is_connected = prom.Gauge( "arduino_is_connected", "Is Arduino board connected via Serial", ["arduino_name"], registry=self.registry, ) self.arduino_status_age_seconds = prom.Gauge( "arduino_status_age_seconds", "Seconds since the last `status` message from " "the Arduino board (measured at the latest tick)", ["arduino_name"], registry=self.registry, ) # Others: self.is_panic = prom.Gauge("is_panic", "Is in panic mode", registry=self.registry) self.is_threshold = prom.Gauge("is_threshold", "Is in threshold mode", registry=self.registry) self.tick_duration = prom.Histogram( # Summary would have been better there, but prometheus_client # doesn't yet support quantiles in Summaries. # See: https://github.com/prometheus/client_python/issues/92 "tick_duration", "Duration of a single tick", buckets=(0.1, 0.25, 0.5, 0.75, 1.0, 2.5, 5.0, 10.0, float("inf")), registry=self.registry, ) last_metrics_tick_seconds_ago = prom.Gauge( "last_metrics_tick_seconds_ago", "The time in seconds since the last tick (which also updates these metrics)", registry=self.registry, ) last_metrics_tick_seconds_ago.set_function( lambda: self.last_metrics_tick_seconds_ago)
DISCORD_API_KEY = os.environ.get("DISCORD_API_KEY") METRICS_PORT = int(os.environ.get("FAUCET_METRICS_PORT")) executor = concurrent.futures.ThreadPoolExecutor(max_workers=5) client = discord.Client() faucet = Faucet() SENT_TRANSACTION_THIS_BLOCK = False # PROMETHEUS METRICS TRANSACTION_COUNT = prometheus_client.Counter( "faucet_transactions_sent", "Number of Transactions sent since the process started") TOTAL_CODA_SENT = prometheus_client.Counter( "faucet_coda_sent", "Amount of Coda sent since the process started") PROCESS_METRICS = prometheus_client.ProcessCollector(namespace='faucet') PLEASE_WAIT_ERRORS = prometheus_client.Counter( "faucet_please_wait_errors", "Number of 'Please Wait' Errors that have been issued") BLOCK_NOTIFICATIONS_RECIEVED = prometheus_client.Counter( "faucet_block_notifications_recieved", "Number of Block Notifications recieved") # This is a fix for a bug in the Daemon where the Nonce is # only incremented once per block, can be removed once it's fixed # NOTE: This means we can only send one faucet transaction per block. async def new_block_callback(message): global SENT_TRANSACTION_THIS_BLOCK SENT_TRANSACTION_THIS_BLOCK = False logger.debug("Got a block! Resetting the Boolean to {}. {}".format(