def connection(self) -> HTTP20Connection: """ Open an apple connection requires a ssl context :return: an hyper.http20.connection.HTTP20Connection object """ host = self.url_push port = self.port ssl_context = self.ssl_context connection = HTTP20Connection(host=host, port=port, ssl_context=ssl_context, force_proto=tls.H2C_PROTOCOL) cert_file_name = self.cert_file.split('/')[-1] key_file_name = self.key_file.split('/')[-1] if self.key_file else None if key_file_name: msg = f'{self.app_name.capitalize()} app: Connecting to {host}:{port} ' \ f'using {cert_file_name} certificate ' \ f'and {key_file_name} key files' else: msg = f'{self.app_name.capitalize()} app: Connecting to {host}:{port} ' \ f'using {cert_file_name} certificate' log_event(loggers=self.loggers, msg=msg, level='deb') return connection
def query_tokens(key): username, domain = key.split('@', 1) tokens = {} try: for device in PushTokens.objects(PushTokens.username == username, PushTokens.domain == domain): tokens[f'{device.app_id}-{device.device_id}'] = {'device_id': device.device_id, 'token': device.device_token, 'background_token': device.background_token, 'platform': device.platform, 'app_id': device.app_id, 'silent': bool(int(device.silent))} except CQLEngineException as e: log_event(loggers=settings.params.loggers, msg=f'Get token(s) failed: {e}', level='error') raise StorageError return tokens
def add(self, account, contact_params): username, domain = account.split('@', 1) try: (token, background_token) = contact_params.token.split('#') except ValueError: token = contact_params.token background_token = None try: PushTokens.create(username=username, domain=domain, device_id=contact_params.device_id, device_token=token, background_token=background_token, platform=contact_params.platform, silent=str(int(contact_params.silent is True)), app_id=contact_params.app_id, user_agent=contact_params.user_agent) except (CQLEngineException, InvalidRequest) as e: log_event(loggers=settings.params.loggers, msg=f'Storing token failed: {e}', level='error') raise StorageError try: OpenSips.create(opensipskey=account, opensipsval='1') except (CQLEngineException, InvalidRequest) as e: log_event(loggers=settings.params.loggers, msg=e, level='error') raise StorageError
def log_request(self, path: str) -> None: """ Write in log information about push notification, using log_event function :param path: `str`, path where push notification will be sent. :param app_name: `str` for friendly log. :param platform: `str`, 'apple' or 'firebase'. :param request_id: `str`, request ID generated on request event. :param headers: `json`, of push notification. :param payload: `json`, of push notification. :param loggers: `dict` global logging instances to write messages (params.loggers) """ # log_app_name = app_name.capitalize() log_platform = self.platform.capitalize() log_path = path if path else self.path level = 'info' msg = f'outgoing {log_platform} request {self.request_id} to {log_path}' log_event(loggers=self.loggers, msg=msg, level=level) msg = f'outgoing {log_platform} request {self.request_id} headers: {self.headers}' log_event(loggers=self.loggers, msg=msg, level='deb') msg = f'outgoing {log_platform} request {self.request_id} body: {self.payload}' log_event(loggers=self.loggers, msg=msg, level='deb')
def log_results(self): """ Log to journal system the result of push notification """ body = self.results['body'] code = self.results['code'] reason = self.results['reason'] url = self.results['url'] level = 'info' body = json.dumps(body) msg = f"outgoing {self.platform.title()} response for request " \ f"{self.request_id} body: {body}" log_event(loggers=self.loggers, msg=msg, level='deb') if code == 200: msg = f"outgoing {self.platform.title()} response for request " \ f"{self.request_id}: push notification sent successfully" log_event(loggers=self.loggers, msg=msg, level=level) else: msg = f"outgoing {self.platform.title()} response for " \ f"{self.request_id}, push failed with code {code}: {reason}" log_event(loggers=self.loggers, msg=msg, level='error') body = {'incoming_body': self.wp_request.__dict__, 'outgoing_headers': self.headers, 'outgoing_body': self.payload } if self.log_remote.get('log_urls'): self.log_remotely(body=body, code=code, reason=reason, url=url)
def __new__(self): configuration = CassandraConfig.__cfgtype__(CassandraConfig.__cfgfile__) if configuration.files: msg='Reading storage configuration from {}'.format(', '.join(configuration.files)) log_event(loggers=settings.params.loggers, msg=msg, level='info') makedirs(ServerConfig.spool_dir.normalized) if CASSANDRA_MODULES_AVAILABLE and CassandraConfig.cluster_contact_points: if CassandraConfig.debug: logging.getLogger('cassandra').setLevel(logging.DEBUG) else: logging.getLogger('cassandra').setLevel(logging.INFO) log_event(loggers=settings.params.loggers, msg='Using Cassandra for token storage', level='info') return CassandraStorage() else: log_event(loggers=settings.params.loggers, msg='Using pickle file for token storage', level='info') return FileStorage()
async def push_requests(account: str, request: Request, push_request: PushRequest, background_tasks: BackgroundTasks, device: Optional[str] = None): host, port = request.client.host, request.client.port code, description, data = '', '', [] if check_host(host, settings.params.allowed_pool): request_id = f"{push_request.event}-{account}-{push_request.call_id}" if not settings.params.return_async: background_tasks.add_task(log_push_request, task='log_request', host=host, loggers=settings.params.loggers, request_id=request_id, body=push_request.__dict__) background_tasks.add_task(log_incoming_request, task='log_success', host=host, loggers=settings.params.loggers, request_id=request_id, body=push_request.__dict__) background_tasks.add_task(task_push, account=account, push_request=push_request, request_id=request_id, host=host, device=device) status_code, code = status.HTTP_202_ACCEPTED, 202 description, data = 'accepted for delivery', {} try: return JSONResponse(status_code=status_code, content={ 'code': code, 'description': description, 'data': data }) except json.decoder.JSONDecodeError: return JSONResponse(status_code=status_code, content={ 'code': code, 'description': description, 'data': {} }) else: storage = TokenStorage() try: storage_data = storage[account] except StorageError: error = HTTPException(status_code=500, detail="Internal error: storage") log_push_request( task='log_failure', host=host, loggers=settings.params.loggers, request_id=request_id, body=push_request.__dict__, error_msg=f'500: {{\"detail\": \"{error.detail}\"}}') raise error expired_devices = [] log_push_request(task='log_request', host=host, loggers=settings.params.loggers, request_id=request_id, body=push_request.__dict__) if not storage_data: description, data = 'Push request was not sent: user not found', { "account": account } return JSONResponse(status_code=status.HTTP_404_NOT_FOUND, content={ 'code': 404, 'description': description, 'data': data }) for device_key, push_parameters in storage_data.items(): if device is not None and device != push_parameters[ 'device_id']: continue push_parameters.update(push_request.__dict__) reversed_push_parameters = {} for item in push_parameters.keys(): value = push_parameters[item] if item in ('sip_to', 'sip_from'): item = item.split('_')[1] else: item = item.replace('_', '-') reversed_push_parameters[item] = value # Use background_token for cancel if push_parameters['event'] == 'cancel' and push_parameters[ 'background_token'] is not None: reversed_push_parameters['token'] = push_parameters[ 'background_token'] try: wp = WakeUpRequest(**reversed_push_parameters) except ValidationError as e: error_msg = e.errors()[0]['msg'] log_push_request(task='log_failure', host=host, loggers=settings.params.loggers, request_id=request_id, body=push_request.__dict__, error_msg=error_msg) content = jsonable_encoder({ 'code': 400, 'description': error_msg, 'data': '' }) return JSONResponse( status_code=status.HTTP_400_BAD_REQUEST, content=content) log_incoming_request(task='log_success', host=host, loggers=settings.params.loggers, request_id=request_id, body=wp.__dict__) results = handle_request(wp, request_id=request_id) code = results.get('code') if code == 410: expired_devices.append((push_parameters['app_id'], push_parameters['device_id'])) code = 200 description = 'push notification responses' data.append(results) for expired_device in expired_devices: msg = f'Removing {expired_device[1]} from {account}' log_event(loggers=settings.params.loggers, msg=msg, level='info') storage.remove(account, *expired_device) if code == '': description, data = 'Push request was not sent: device not found', { "device_id": push_parameters['device_id'] } content = {'code': 404, 'description': description, 'data': data} log_push_request(task='log_failure', host=host, loggers=settings.params.loggers, request_id=request_id, body=push_request.__dict__, error_msg=f'{content}') return JSONResponse(status_code=status.HTTP_404_NOT_FOUND, content=content) else: msg = f'incoming request from {host} is denied' log_event(loggers=settings.params.loggers, msg=msg, level='deb') code = 403 description = 'access denied by access list' data = {} log_event(loggers=settings.params.loggers, sg=msg, level='deb') return JSONResponse(status_code=code, content={ 'code': code, 'description': description, 'data': data })
async def add_requests(account: str, request: Request, add_request: AddRequest, background_tasks: BackgroundTasks): add_request.platform = fix_platform_name(add_request.platform) host, port = request.client.host, request.client.port code, description, data = '', '', {} if check_host(host, settings.params.allowed_pool): request_id = f"{account}-{add_request.app_id}-{add_request.device_id}" if not settings.params.return_async: background_tasks.add_task(log_add_request, task='log_request', host=host, loggers=settings.params.loggers, request_id=request_id, body=add_request.__dict__) background_tasks.add_task(log_add_request, task='log_success', host=host, loggers=settings.params.loggers, request_id=request_id, body=add_request.__dict__) storage = TokenStorage() background_tasks.add_task(storage.add, account, add_request) return add_request else: log_add_request(task='log_request', host=host, loggers=settings.params.loggers, request_id=request_id, body=add_request.__dict__) storage = TokenStorage() try: storage.add(account, add_request) except StorageError: error = HTTPException(status_code=500, detail="Internal error: storage") log_add_request( task='log_failure', host=host, loggers=settings.params.loggers, request_id=request_id, body=add_request.__dict__, error_msg=f'500: {{\"detail\": \"{error.detail}\"}}') raise error log_add_request(task='log_success', host=host, loggers=settings.params.loggers, request_id=request_id, body=add_request.__dict__) return add_request else: msg = f'incoming request from {host} is denied' log_event(loggers=settings.params.loggers, msg=msg, level='deb') code = 403 description = 'access denied by access list' data = {} log_event(loggers=settings.params.loggers, msg=msg, level='deb') return JSONResponse(status_code=code, content={ 'code': code, 'description': description, 'data': data })
def log_error(self): level = 'error' msg = f"outgoing {self.platform.title()} response for " \ f"{self.request_id}, push failed: " \ f"{self.error}" log_event(loggers=self.loggers, msg=msg, level=level)
def log_remotely(self, body: dict, code: str, reason: str, url: str) -> None: """ Fork a log of a payload incoming request to a remote url :param body: `dict` response to push request :param code: `int` of response to push request :param reason: `str` of response to push request """ push_response = {'code': code, 'description': reason, 'push_url': url} headers = {'Content-Type': 'application/json'} server_ip = self.server_ip('1.2.3.4') now = datetime.datetime.now() timestamp = now.strftime("%Y-%m-%d %H:%M:%S") payload = {'request': body, 'response': push_response, 'server_ip': server_ip,'timestamp': timestamp} task = 'log remote' log_key = self.log_remote.get('log_key') log_time_out = self.log_remote.get('log_time_out') results = [] for log_url in self.log_remote['log_urls']: msg = f'{task} request {self.request_id} to {log_url}' log_event(loggers=self.loggers, msg=msg, level='deb') msg = f'{task} request {self.request_id} to {log_url} headers: {headers}' log_event(loggers=self.loggers, msg=msg, level='deb') msg = f'{task} request {self.request_id} to {log_url} body: {payload}' log_event(loggers=self.loggers, msg=msg, level='deb') try: with concurrent.futures.ThreadPoolExecutor(max_workers=10) as executor: futures = [ executor.submit( lambda: requests.post(url=log_url, json=payload, headers=headers, timeout=log_time_out or 2) ) for log_url in self.log_remote['log_urls'] ] results = [ f.result() for f in futures ] except requests.exceptions.ConnectionError as exc: msg = f'{task} for {self.request_id}: connection error {exc}' log_event(loggers=self.loggers, msg=msg, level='error') except requests.exceptions.ReadTimeout as exc: msg = f'{task} for {self.request_id}: connection error {exc}' log_event(loggers=self.loggers, msg=msg, level='error') if not results: return for url, result in list(zip(self.log_remote['log_urls'], results)): code = result.status_code text = result.text[:500] if log_key: try: result = result.json() value = result.get(log_key) except (json.decoder.JSONDecodeError, AttributeError): value = {} if value: msg = f'{task} response for request {self.request_id} from {url} - ' \ f'{code} {log_key}: {value}' log_event(loggers=self.loggers, msg=msg, level='deb') else: msg = f'{task} response for request {self.request_id} - ' \ f'code: {code}, key not found' log_event(loggers=self.loggers, msg=msg, level='error') else: msg = f'{task} response for request {self.request_id} ' \ f'from {url}: {code} {text}' log_event(loggers=self.loggers, msg=msg, level='deb')
async def push_requests(request: Request, wp_request: WakeUpRequest, background_tasks: BackgroundTasks): wp_request.platform = fix_platform_name(wp_request.platform) host, port = request.client.host, request.client.port code, description, data = '', '', {} if check_host(host, settings.params.allowed_pool): request_id = f"{wp_request.event}-{wp_request.app_id}-{wp_request.call_id}" if not settings.params.return_async: background_tasks.add_task(log_incoming_request, task='log_request', host=host, loggers=settings.params.loggers, request_id=request_id, body=wp_request.__dict__) background_tasks.add_task(log_incoming_request, task='log_success', host=host, loggers=settings.params.loggers, request_id=request_id, body=wp_request.__dict__) background_tasks.add_task(handle_request, wp_request=wp_request, request_id=request_id) status_code, code = status.HTTP_202_ACCEPTED, 202 description, data = 'accepted for delivery', {} try: return JSONResponse(status_code=status_code, content={ 'code': code, 'description': description, 'data': data }) except json.decoder.JSONDecodeError: return JSONResponse(status_code=status_code, content={ 'code': code, 'description': description, 'data': {} }) else: log_incoming_request(task='log_request', host=host, loggers=settings.params.loggers, request_id=request_id, body=wp_request.__dict__) log_incoming_request(task='log_success', host=host, loggers=settings.params.loggers, request_id=request_id, body=wp_request.__dict__) results = handle_request(wp_request, request_id=request_id) code = results.get('code') description = 'push notification response' data = results else: msg = f'incoming request from {host} is denied' log_event(loggers=settings.params.loggers, msg=msg, level='deb') code = 403 description = 'access denied by access list' data = {} log_event(loggers=settings.params.loggers, msg=msg, level='deb') return JSONResponse(status_code=code, content={ 'code': code, 'description': description, 'data': data })
def send_fcm_notification(self) -> dict: """ Send a native Firebase push notification """ if self.error: self.log_error() return {'code': 500, 'body': {}, 'reason': 'Internal server error'} n_retries, backoff_factor = self.retries_params( self.wp_request.media_type) counter = 0 error = False code = 200 response = None body = None reason = None while counter <= n_retries: self.log_request(path=self.pns.url_push) try: response = messaging.send(self.payload['fcm']) break except Exception as e: error = True response = f'connection failed: {e}' counter += 1 timer = backoff_factor * (2**(counter - 1)) conde = 500 time.sleep(timer) if counter == n_retries: reason = "maximum retries reached" elif error: try: response = self.requests_retry_session(counter). \ post(self.pns.url_push, self.payload, headers=self.headers) except Exception as x: level = 'error' msg = f"outgoing {self.platform.title()} response for " \ f"{self.request_id}, push failed: " \ f"an error occurred in {x.__class__.__name__}" log_event(loggers=self.loggers, msg=msg, level=level) body = {'response': response} results = { 'body': body, 'code': code, 'reason': reason, 'url': self.pns.url_push, 'platform': 'firebase', 'call_id': self.wp_request.call_id, 'token': self.token } self.results = results self.log_results() # Request is missing required authentication credential. # Expected OAuth 2 access token, login cookie or other valid authentication # credential. UNAUTHENTICATED code = results.get('code') reason = results.get('reason') if not got401 and code == 401 and reason == 'Unauthorized': if not self.pns.get('refreshed_token'): level = 'warn' msg = f"outgoing {self.platform.title()} response for request " \ f"{self.request_id} need a new access token - " \ f"server will refresh it and try again" log_event(loggers=self.loggers, msg=msg, level=level, to_file=True) # retry with a new Fireplace access token self.pns.access_token = self.pns.set_access_token() level = 'warn' msg = f"outgoing {self.platform.title()} response for request " \ f"{self.request_id} a new access token was generated - " \ f"trying again" log_event(loggers=self.loggers, msg=msg, level=level, to_file=True) self.results = self.send_notification() return results
def send_http_notification(self) -> dict: """ Send a Firebase push notification over HTTP """ if self.error: self.log_error() return {'code': 500, 'body': {}, 'reason': 'Internal server error'} n_retries, backoff_factor = self.retries_params( self.wp_request.media_type) counter = 0 error = False code = 500 reason = "" body = None response = None while counter <= n_retries: self.log_request(path=self.pns.url_push) try: response = requests.post(self.pns.url_push, self.payload, headers=self.headers) break except requests.exceptions.RequestException as e: error = True reason = f'connection failed: {e}' counter += 1 timer = backoff_factor * (2**(counter - 1)) time.sleep(timer) if counter == n_retries: reason = "maximum retries reached" elif error: try: response = self.requests_retry_session(counter). \ post(self.pns.url_push, self.payload, headers=self.headers) except Exception as x: level = 'error' msg = f"outgoing {self.platform.title()} response for " \ f"{self.request_id}, push failed: " \ f"an error occurred in {x.__class__.__name__}" log_event(loggers=self.loggers, msg=msg, level=level) try: body = response.__dict__ except (TypeError, ValueError): code = 500 reason = 'cannot parse response body' body = {} else: reason = body.get('reason') code = response.status_code for k in ('raw', 'request', 'connection', 'cookies', 'elapsed'): try: del body[k] except KeyError: pass except TypeError: break body = json.dumps(fix_non_serializable_types(body)) if isinstance(body, str): body = json.loads(body) if code == 200: description = 'OK' try: failure = body['_content']['failure'] except KeyError: pass else: if failure == 1: description = body['_content']['results'][0]['error'] code = 410 else: try: reason = body['reason'] except KeyError: reason = None try: details = body['_content']['error']['message'] except KeyError: details = None try: internal_code = body['_content']['error']['code'] except KeyError: internal_code = None if internal_code == 400 and 'not a valid FCM registration token' in details: code = 410 elif internal_code == 404: code = 410 if reason and details: description = "%s %s" % (reason, details) elif reason: description = reason elif details: error_description = details else: description = 'unknown failure reason' keys = list(body.keys()) for key in keys: if not body[key]: del body[key] results = { 'body': body, 'code': code, 'reason': description, 'url': self.pns.url_push, 'platform': 'firebase', 'call_id': self.wp_request.call_id, 'token': self.token } self.results = results self.log_results() return results
def load(self): try: connection.setup(CassandraConfig.cluster_contact_points, CassandraConfig.keyspace, load_balancing_policy=DCAwareRoundRobinPolicy(), protocol_version=4, connection_class=asyncioreactor.AsyncioConnection) except NoHostAvailable: msg='Not able to connect to any of the Cassandra contact points' log_event(loggers=settings.params.loggers, msg=msg, level='error')
async def task_push(account: str, push_request: PushRequest, request_id: str, host: str, device: Optional[str] = None): code, description, data = '', '', [] storage = TokenStorage() try: storage_data = storage[account] except StorageError: log_remove_request( task='log_failure', host=host, loggers=settings.params.loggers, request_id=request_id, body=push_request.__dict__, error_msg=f'500: {{\"detail\": \"{error.detail}\"}}') return expired_devices = [] if not storage_data: # Push request was not sent: user not found return for device_key, push_parameters in storage_data.items(): if device is not None and device != push_parameters['device_id']: continue push_parameters.update(push_request.__dict__) reversed_push_parameters = {} for item in push_parameters.keys(): value = push_parameters[item] if item in ('sip_to', 'sip_from'): item = item.split('_')[1] else: item = item.replace('_', '-') reversed_push_parameters[item] = value # Use background_token for cancel if push_parameters['event'] == 'cancel' and push_parameters[ 'background_token'] is not None: reversed_push_parameters['token'] = push_parameters[ 'background_token'] try: wp = WakeUpRequest(**reversed_push_parameters) except ValidationError as e: error_msg = e.errors()[0]['msg'] log_push_request(task='log_failure', host=host, loggers=settings.params.loggers, request_id=request_id, body=push_request.__dict__, error_msg=error_msg) return log_incoming_request(task='log_success', host=host, loggers=settings.params.loggers, request_id=request_id, body=wp.__dict__) results = handle_request(wp, request_id=request_id) code = results.get('code') if code == 410: expired_devices.append( (push_parameters.app_id, push_parameters.device_id)) code = 200 description = 'push notification responses' data.append(results) for device in expired_devices: msg = f'Removing {device[1]} from {account}' log_event(loggers=settings.params.loggers, msg=msg, level='deb') storage.remove(account, *device) if code == '': description, data = 'Push request was not sent: device not found', { "device_id": push_parameters['device_id'] } log_event(loggers=settings.params.loggers, msg=f'{description} {data}', level='warn') else: log_event(loggers=settings.params.loggers, msg=f'{description} {data}', level='deb')
async def remove_requests(account: str, request: Request, rm_request: RemoveRequest, background_tasks: BackgroundTasks): host, port = request.client.host, request.client.port code, description, data = '', '', {} if check_host(host, settings.params.allowed_pool): request_id = f"{account}-{rm_request.app_id}-{rm_request.device_id}" if not settings.params.return_async: background_tasks.add_task(log_remove_request, task='log_request', host=host, loggers=settings.params.loggers, request_id=request_id, body=rm_request.__dict__) background_tasks.add_task(log_remove_request, task='log_success', host=host, loggers=settings.params.loggers, request_id=request_id, body=rm_request.__dict__) storage = TokenStorage() background_tasks.add_task(storage.remove, account, rm_request.app_id, rm_request.device_id) return rm_request else: log_remove_request(task='log_request', host=host, loggers=settings.params.loggers, request_id=request_id, body=rm_request.__dict__) storage = TokenStorage() try: storage_data = storage[account] except StorageError: error = HTTPException(status_code=500, detail="Internal error: storage") log_remove_request(task='log_failure', host=host, loggers=settings.params.loggers, request_id=request_id, body=rm_request.__dict__, error_msg=f'500: {{\"detail\": \"{error.detail}\"}}') raise error if not storage_data: log_remove_request(task='log_failure', host=host, loggers=settings.params.loggers, request_id=request_id, body=rm_request.__dict__, error_msg="User not found in token storage") return JSONResponse( status_code=status.HTTP_404_NOT_FOUND, content={'result': 'User not found'} ) device_id = f"{rm_request.app_id}-{rm_request.device_id}" try: device = storage_data[device_id] except KeyError: log_remove_request(task='log_failure', host=host, loggers=settings.params.loggers, request_id=request_id, body=rm_request.__dict__, error_msg="Device or app_id not found in token storage") return JSONResponse( status_code=status.HTTP_404_NOT_FOUND, content={'result': 'Not found'} ) else: storage.remove(account, rm_request.app_id, rm_request.device_id) log_remove_request(task='log_success', host=host, loggers=settings.params.loggers, request_id=request_id, body=rm_request.__dict__) msg = f'Removing {device}' log_event(loggers=settings.params.loggers, msg=msg, level='deb') return rm_request else: msg = f'incoming request from {host} is denied' log_event(loggers=settings.params.loggers, msg=msg, level='deb') code = 403 description = 'access denied by access list' data = {} log_event(loggers=settings.params.loggers, msg=msg, level='deb') return JSONResponse(status_code=code, content={'code': code, 'description': description, 'data': data})
async def start_server() -> None: asyncio.create_task(autoreload_read_config(wait_for=wait_for)) level = 'info' loggers = settings.params.loggers register = settings.params.register pns_register = register['pns_register'] if settings.params.apps['path']: msg = f"Loaded {len(pns_register)} applications from " \ f"{settings.params.apps['path']}:" else: msg = f"Loaded {len(pns_register)} applications" log_event(loggers=loggers, msg=msg, level=level) for app in pns_register.keys(): app_id, platform = app name = pns_register[app]['name'] msg = f"Loaded {platform.capitalize()} "\ f"{name.capitalize()} app {app_id}" \ log_event(loggers=loggers, msg=msg, level=level) headers_class = pns_register[app]['headers_class'] payload_class = pns_register[app]['payload_class'] msg = f"{name.capitalize()} app {app_id} classes: " \ f"{headers_class.__name__}, {payload_class.__name__}" log_event(loggers=loggers, msg=msg, level='deb') log_remote = pns_register[app]['log_remote'] if log_remote['error']: msg = f"{name.capitalize()} loading of log remote settings failed: " \ f"{log_remote['error']}" log_event(loggers=loggers, msg=msg, level='warn') elif log_remote.get('log_remote_urls'): log_settings = '' for k, v in log_remote.items(): if k == 'error': continue if k == 'log_urls': v = ', '.join(v) if k == 'log_remote_key' and not v: continue if k == 'log_remote_timeout' and not v: continue log_settings += f'{k}: {v} ' msg = f'{name.capitalize()} log remote settings: {log_settings}' log_event(loggers=loggers, msg=msg, level='deb') invalid_apps = register['invalid_apps'] for app in invalid_apps.keys(): app_id, platform = app[0], app[1] name = invalid_apps[app]['name'] reason = invalid_apps[app]['reason'] msg = f"{name.capitalize()} app with {app_id} id for {platform} platform " \ f"will not be available, reason: {reason}" log_event(loggers=loggers, msg=msg, level='warn') pnses = register['pnses'] if len(pnses) == 0: msg = f'Loaded {len(pnses)} Push notification services' else: msg = f'Loaded {len(pnses)} Push notification services: ' \ f'{", ".join(pnses)}' log_event(loggers=loggers, msg=msg, level='deb') for pns in pnses: msg = f"{pns.split('PNS')[0]} Push Notification Service - " \ f"{pns} class" log_event(loggers=loggers, msg=msg, level='deb') if settings.params.allowed_pool: nets = [net.with_prefixlen for net in settings.params.allowed_pool] msg = f"Allowed hosts: " \ f"{', '.join(nets)}" log_event(loggers=loggers, msg=msg, level=level) msg = 'Server is now ready to answer requests' log_event(loggers=loggers, msg=msg, level='deb') ip, port = settings.params.server['host'], settings.params.server['port'] msg = f'Sylk Pushserver listening on http://{ip}:{port}' log_event(loggers=loggers, msg=msg, level='info') await asyncio.sleep(wait_for)