async def on_message(self, message): if message.content.startswith('!status'): with open('servers.json') as f: servers_config_json = json.load(f) for server in servers_config_json: if message.channel.id == int(server['status_channel_id']): log.info(f"Status request received for {server['name']}") device_status_response = connector.get_status(server) table_header = ['Origin', 'Route', 'Pos', 'Last Data'] table_contents = [] for device in device_status_response: try: datetime_from_status_json = parser.parse(device['lastProtoDateTime']) formatted_device_last_proto_time = datetime_from_status_json.strftime("%H:%M") except Exception: formatted_device_last_proto_time = 'Unknown' table_before = tabulate(table_contents, headers=table_header) table_contents.append([device['origin'], device['routemanager'], f"{device['routePos']}/{device['routeMax']}", formatted_device_last_proto_time ]) table_after = tabulate(table_contents, headers=table_header) table_before_len = len(table_before) table_after_len = len(table_after) log.debug(f"{table_before_len} and after {table_after_len}") if table_before_len > 2000: log.error("Table before exceeds 2000 word count. How did this happened?") return if table_after_len > 2000: log.info("Table size was greater than 2000. Commence table split.") log.debug(table_before) await message.channel.send( f"__**{server['name']}**__\n```{table_before}```") table_contents.clear() table_contents.append([device['origin'], device['routemanager'], f"{device['routePos']}/{device['routeMax']}", formatted_device_last_proto_time ]) log.debug(f"Sending status table for {server['name']}") table_to_send = tabulate(table_contents, headers=table_header) log.debug(table_to_send) await message.channel.send(f"__**{server['name']}**__\n```{table_to_send}```")
async def on_message(self, message): if message.content.startswith('!status'): with open('servers.json') as f: servers_config_json = json.load(f) for server in servers_config_json: error_found = False if message.channel.id == int(server['status_channel_id']): server_name = server['name'] table_header = ['Origin', 'Route', 'Pos', 'Time'] table_contents = [] log.info(f"Status request received for {server_name}") log.debug("Calling /get_status for current status") device_status_response = connector.get_status(server) for device in device_status_response or []: table_before = tabulate(table_contents, headers=table_header) routemanager = device.get( 'rmname', '') if device.get( 'rmname', 'Not Defined' ) is not None else 'Not Defined' origin = device.get('name', '') if device.get( 'rmname', '') is not None else '' route_pos = device.get( 'routePos', '?') if device.get( 'routePos', '?') is not None else '?' route_max = device.get( 'routeMax', '?') if device.get( 'routeMax', '?') is not None else '?' lastProtoDateTime = device.get( 'lastProtoDateTime', '') if device.get( 'lastProtoDateTime', '') is not None else '' number_front_chars = 6 number_end_chars = 5 try: datetime_from_status_json = datetime.fromtimestamp( lastProtoDateTime) formatted_device_last_proto_time = datetime_from_status_json.strftime( "%H:%M") latest_acceptable_datetime = ( datetime.now() - timedelta( minutes=args.duration_before_alert)) log.debug( f"{origin} Last Proto Date Time: {datetime_from_status_json}" ) log.debug( f"{origin} Last Acceptable Time: {latest_acceptable_datetime}" ) if datetime_from_status_json < latest_acceptable_datetime: error_found = True except Exception as e: error_found = True formatted_device_last_proto_time = 'Unkwn' if args.trim_table_content: if len(routemanager) > (number_front_chars + number_end_chars): routemanager = f"{routemanager[:number_front_chars]}..{routemanager[-number_end_chars:]}" if len(origin) > (number_front_chars + number_end_chars): origin = f"{origin[:number_front_chars]}..{origin[-number_end_chars:]}" table_contents.append([ origin, routemanager, f"{route_pos}/{route_max}", formatted_device_last_proto_time ]) table_after = tabulate(table_contents, headers=table_header) table_before_len = len(table_before) table_after_len = len(table_after) log.debug( f"{table_before_len} and after {table_after_len}" ) log.debug("Error" + str(error_found)) color = 0xFF6E6E if error_found is True else 0x98FB98 if table_before_len > 2000: log.error( "Table before exceeds 2000 word count. How did this happened?" ) return if table_after_len > 2000: log.info( "Table size was greater than 2000. Commence table split." ) log.debug(table_before) embed = discord.Embed(description='```' + table_before + '```', colour=color) embed.set_thumbnail(url=iconURL) embed.set_author(name=server['name'], url='', icon_url='') await message.channel.send(embed=embed) table_contents.clear() table_contents.append([ origin, routemanager, f"{route_pos}/{route_max}", formatted_device_last_proto_time ]) log.debug(f"Sending status table for {server_name}") table_to_send = tabulate(table_contents, headers=table_header) log.debug(table_to_send) # TODO Status colours embed = discord.Embed(description='```' + table_to_send + '```', colour=color) embed.set_thumbnail(url=iconURL) embed.set_author(name=server['name'], url='', icon_url='') await message.channel.send(embed=embed)
def alert_thread(): try: duration_before_alert = args.duration_before_alert delay_between_checks = args.delay_between_checks discord_post_data = { "username": "******", "avatar_url": "https://www.iconsdb.com/icons/preview/red/exclamation-xxl.png", "embeds": [{ "title": f"ERROR - No data for {duration_before_alert} minutes!", "color": 16711680, "description": "PLACEHOLDER", "footer": { "text": "PLACEHOLDER" } }] } log.info("Starting Device Checker Script") while True: with open('servers.json') as servers_json: servers_config_json = json.load(servers_json) for server in servers_config_json: description_initial = f"__**{server['name']}**__\n" description = description_initial discord_post_data['embeds'][0][ 'description'] = description_initial log.info(f"Starting check on {server['ip']}") r = connector.get_status(server) for device in r: device_origin = str(device['origin']).title() device_last_proto_datetime = device[ 'lastProtoDateTime'] routemanager = str(device['routemanager']).title() log.info(f"Checking {device_origin} device") log.debug(device) if len(device_last_proto_datetime) > 0: parsed_device_last_proto_datetime = parse( device_last_proto_datetime) latest_acceptable_datetime = ( datetime.now() - timedelta(minutes=duration_before_alert)) log.debug( f"{device_origin} Last Proto Date Time: {parsed_device_last_proto_datetime}" ) log.debug( f"{device_origin} Last Acceptable Time: {latest_acceptable_datetime}" ) if parsed_device_last_proto_datetime < latest_acceptable_datetime: log.info( f"{device_origin} breached the time threshold" ) description = description + f"{device_origin.capitalize()} - {routemanager} -> (Last Received: {parsed_device_last_proto_datetime.strftime('%H:%M')})\n" log.debug( f"Current description: {description}") else: log.info( f"{device_origin} did not breach the time threshold" ) else: description = description + f"{device_origin.capitalize()} (Last Received: Not known)\n" if len(description) > len(description_initial): if 'alert_role_id' in server: discord_post_data[ 'content'] = f"Problem on {server['name']} <@&{server['alert_role_id']}>" discord_post_data['embeds'][0][ 'description'] = description time_of_next_check = (datetime.now() + timedelta( minutes=delay_between_checks)).strftime('%H:%M') discord_post_data['embeds'][0]['footer'][ 'text'] = f"Next check will be at {time_of_next_check}" log.debug(discord_post_data) log.info( "Sending alert to Discord as one or more devices has exceeded the threshold" ) response = requests.post( server['webhook'], data=json.dumps(discord_post_data), headers={'Content-Type': 'application/json'}) log.debug(response) if response.status_code != 204: log.error( 'Post to Discord webhook returned an error %s, the response is:\n%s' % (response.status_code, response.text)) else: log.debug("Message posted to Discord with success") else: log.debug( "There is no errors to report, going to sleep..") log.info("All device checks completed, going to sleep!") time.sleep(60 * delay_between_checks) except Exception as ex: log.error('Issues in the checker tread exception was: ' + str(ex))
async def __build_status_response(message, server, return_only_failed: bool): any_error_found = False server_name = server['name'] table_header = ['Origin', 'Route', 'Pos', 'Time'] table_contents = [] log.info(f"Status request received for {server_name}") log.debug("Calling /get_status for current status") device_status_response = connector.get_status(server) # Sort by name ascending device_status_response.sort(key=get_name) for device in device_status_response or []: device_failed = False table_before = tabulate(table_contents, headers=table_header) route_manager = get_route_manager_name( device) if get_route_manager_name(device) is not None else '' origin = get_name(device) if get_name(device) is not None else '' route_pos = get_route_pos(device) if get_route_pos( device) is not None else '?' route_max = get_route_max(device) if get_route_max( device) is not None else '?' last_proto_date_time = get_last_updated( device) if get_last_updated(device) is not None else '' number_front_chars = 6 number_end_chars = 5 try: datetime_from_status_json = datetime.fromtimestamp( last_proto_date_time) formatted_device_last_proto_time = datetime_from_status_json.strftime( "%H:%M") latest_acceptable_datetime = ( datetime.now() - timedelta(minutes=args.duration_before_alert)) log.debug( f"{origin} Last Proto Date Time: {datetime_from_status_json}" ) log.debug( f"{origin} Last Acceptable Time: {latest_acceptable_datetime}" ) if datetime_from_status_json < latest_acceptable_datetime: log.info(f"{str(origin)} failed") device_failed = True any_error_found = True except Exception as e: log.info(f"{e} {origin} {route_manager}") any_error_found = True device_failed = True formatted_device_last_proto_time = 'Unkwn' if args.trim_table_content: if len(route_manager) > (number_front_chars + number_end_chars): route_manager = f"{route_manager[:number_front_chars]}..{route_manager[-number_end_chars:]}" if len(origin) > (number_front_chars + number_end_chars): origin = f"{origin[:number_front_chars]}..{origin[-number_end_chars:]}" if (return_only_failed and device_failed and route_manager.lower() != "idle") or not return_only_failed: table_contents.append([ origin, route_manager, f"{route_pos}/{route_max}", formatted_device_last_proto_time ]) table_after = tabulate(table_contents, headers=table_header) table_before_len = len(table_before) table_after_len = len(table_after) log.debug(f"{table_before_len} and after {table_after_len}") log.debug("Error found: " + str(any_error_found)) color = 0xFF6E6E if any_error_found is True else 0x98FB98 if table_before_len > 2000: log.error( "Table before exceeds 2000 word count. How did this happened?" ) return if table_after_len > 2000: log.info( "Table size was greater than 2000. Commence table split.") log.debug(table_before) embed = discord.Embed(description='```' + table_before + '```', colour=color) embed.set_thumbnail(url=iconURL) embed.set_author(name=server['name'], url='', icon_url='') await message.channel.send(embed=embed) table_contents.clear() table_contents.append([ origin, route_manager, f"{route_pos}/{route_max}", formatted_device_last_proto_time ]) log.debug(f"Sending status table for {server_name}") table_to_send = tabulate(table_contents, headers=table_header) log.debug(table_to_send) if len(table_contents) > 0: embed = discord.Embed(description='```' + table_to_send + '```', colour=color) else: embed = discord.Embed(description="No devices need your attention") embed.set_thumbnail(url=iconURL) embed.set_author(name=server['name'], url='', icon_url='') await message.channel.send(embed=embed)