Refactored logging submodule

This commit is contained in:
Fabio Manganiello 2018-06-06 20:09:18 +02:00
parent c867a21104
commit 4da74b1096
51 changed files with 196 additions and 193 deletions

View File

@ -20,6 +20,8 @@ __version__ = '0.8'
#-----------# #-----------#
logger = logging.getLogger(__name__)
class Daemon(object): class Daemon(object):
""" Main class for the Platypush daemon """ """ Main class for the Platypush daemon """
@ -82,12 +84,12 @@ class Daemon(object):
and self.processed_requests >= self.requests_to_process: and self.processed_requests >= self.requests_to_process:
self.stop_app() self.stop_app()
elif isinstance(msg, Response): elif isinstance(msg, Response):
logging.info('Received response: {}'.format(msg)) logger.info('Received response: {}'.format(msg))
elif isinstance(msg, StopEvent) and msg.targets_me(): elif isinstance(msg, StopEvent) and msg.targets_me():
logging.info('Received STOP event: {}'.format(msg)) logger.info('Received STOP event: {}'.format(msg))
self.stop_app() self.stop_app()
elif isinstance(msg, Event): elif isinstance(msg, Event):
logging.info('Received event: {}'.format(msg)) logger.info('Received event: {}'.format(msg))
self.event_processor.process_event(msg) self.event_processor.process_event(msg)
return _f return _f
@ -119,7 +121,7 @@ class Daemon(object):
try: try:
self.bus.poll() self.bus.poll()
except KeyboardInterrupt as e: except KeyboardInterrupt as e:
logging.info('SIGINT received, terminating application') logger.info('SIGINT received, terminating application')
finally: finally:
self.stop_app() self.stop_app()

View File

@ -13,6 +13,7 @@ from platypush.message.event import Event, StopEvent
from platypush.message.request import Request from platypush.message.request import Request
from platypush.message.response import Response from platypush.message.response import Response
class Backend(Thread): class Backend(Thread):
""" Parent class for backends """ """ Parent class for backends """
@ -33,16 +34,17 @@ class Backend(Thread):
self.thread_id = None self.thread_id = None
self._stop = False self._stop = False
self._kwargs = kwargs self._kwargs = kwargs
self.logger = logging.getLogger(__name__)
# Internal-only, we set the request context on a backend if that # Internal-only, we set the request context on a backend if that
# backend is intended to react for a response to a specific request # backend is intended to react for a response to a specific request
self._request_context = kwargs['_req_ctx'] if '_req_ctx' in kwargs \ self._request_context = kwargs['_req_ctx'] if '_req_ctx' in kwargs \
else None else None
if 'logging' in kwargs:
self.logger.setLevel(getattr(logging, kwargs['logging'].upper()))
Thread.__init__(self) Thread.__init__(self)
logging.basicConfig(stream=sys.stdout, level=Config.get('logging')
if 'logging' not in kwargs
else getattr(logging, kwargs['logging']))
def on_message(self, msg): def on_message(self, msg):
@ -62,7 +64,7 @@ class Backend(Thread):
if not getattr(msg, 'target') or msg.target != self.device_id: if not getattr(msg, 'target') or msg.target != self.device_id:
return # Not for me return # Not for me
logging.debug('Message received on the {} backend: {}'.format( self.logger.debug('Message received on the {} backend: {}'.format(
self.__class__.__name__, msg)) self.__class__.__name__, msg))
if self._is_expected_response(msg): if self._is_expected_response(msg):
@ -73,7 +75,7 @@ class Backend(Thread):
return return
if isinstance(msg, StopEvent) and msg.targets_me(): if isinstance(msg, StopEvent) and msg.targets_me():
logging.info('Received STOP event on {}'.format(self.__class__.__name__)) self.logger.info('Received STOP event on {}'.format(self.__class__.__name__))
self._stop = True self._stop = True
else: else:
msg.backend = self # Augment message to be able to process responses msg.backend = self # Augment message to be able to process responses

View File

@ -1,4 +1,3 @@
import logging
import json import json
import os import os
import subprocess import subprocess
@ -15,6 +14,7 @@ from platypush.message.event.assistant import \
ConversationStartEvent, ConversationEndEvent, ConversationTimeoutEvent, \ ConversationStartEvent, ConversationEndEvent, ConversationTimeoutEvent, \
NoResponseEvent, SpeechRecognizedEvent NoResponseEvent, SpeechRecognizedEvent
class AssistantGoogleBackend(Backend): class AssistantGoogleBackend(Backend):
""" Class for the Google Assistant backend. It creates and event source """ Class for the Google Assistant backend. It creates and event source
that posts recognized phrases on the main bus """ that posts recognized phrases on the main bus """
@ -38,10 +38,10 @@ class AssistantGoogleBackend(Backend):
with open(self.credentials_file, 'r') as f: with open(self.credentials_file, 'r') as f:
self.credentials = google.oauth2.credentials.Credentials(token=None, self.credentials = google.oauth2.credentials.Credentials(token=None,
**json.load(f)) **json.load(f))
logging.info('Initialized Google Assistant backend') self.logger.info('Initialized Google Assistant backend')
def _process_event(self, event): def _process_event(self, event):
logging.info('Received assistant event: {}'.format(event)) self.logger.info('Received assistant event: {}'.format(event))
if event.type == EventType.ON_CONVERSATION_TURN_STARTED: if event.type == EventType.ON_CONVERSATION_TURN_STARTED:
self.bus.post(ConversationStartEvent()) self.bus.post(ConversationStartEvent())
@ -53,7 +53,7 @@ class AssistantGoogleBackend(Backend):
self.bus.post(NoResponseEvent()) self.bus.post(NoResponseEvent())
elif event.type == EventType.ON_RECOGNIZING_SPEECH_FINISHED: elif event.type == EventType.ON_RECOGNIZING_SPEECH_FINISHED:
phrase = event.args['text'].lower().strip() phrase = event.args['text'].lower().strip()
logging.info('Speech recognized: {}'.format(phrase)) self.logger.info('Speech recognized: {}'.format(phrase))
self.bus.post(SpeechRecognizedEvent(phrase=phrase)) self.bus.post(SpeechRecognizedEvent(phrase=phrase))

View File

@ -1,4 +1,3 @@
import logging
import json import json
import os import os
import threading import threading
@ -23,6 +22,7 @@ from platypush.backend import Backend
from platypush.message.event.assistant import \ from platypush.message.event.assistant import \
ConversationStartEvent, ConversationEndEvent, SpeechRecognizedEvent ConversationStartEvent, ConversationEndEvent, SpeechRecognizedEvent
class AssistantGooglePushtotalkBackend(Backend): class AssistantGooglePushtotalkBackend(Backend):
""" Google Assistant pushtotalk backend. Instead of listening for """ Google Assistant pushtotalk backend. Instead of listening for
the "OK Google" hotword like the assistant.google backend, the "OK Google" hotword like the assistant.google backend,
@ -82,15 +82,15 @@ class AssistantGooglePushtotalkBackend(Backend):
http_request = google.auth.transport.requests.Request() http_request = google.auth.transport.requests.Request()
credentials.refresh(http_request) credentials.refresh(http_request)
except: except:
logging.error('Error loading credentials: %s', e) logger.error('Error loading credentials: %s', e)
logging.error('Run google-oauthlib-tool to initialize ' logger.error('Run google-oauthlib-tool to initialize '
'new OAuth 2.0 credentials.') 'new OAuth 2.0 credentials.')
raise raise
# Create an authorized gRPC channel. # Create an authorized gRPC channel.
self.grpc_channel = google.auth.transport.grpc.secure_authorized_channel( self.grpc_channel = google.auth.transport.grpc.secure_authorized_channel(
credentials, http_request, self.api_endpoint) credentials, http_request, self.api_endpoint)
logging.info('Connecting to %s', self.api_endpoint) logger.info('Connecting to %s', self.api_endpoint)
# Configure audio source and sink. # Configure audio source and sink.
audio_device = None audio_device = None
@ -158,7 +158,7 @@ class AssistantGooglePushtotalkBackend(Backend):
with open(self.conversation_start_fifo, 'r') as f: with open(self.conversation_start_fifo, 'r') as f:
for line in f: pass for line in f: pass
logging.info('Received conversation start event') logger.info('Received conversation start event')
continue_conversation = True continue_conversation = True
user_request = None user_request = None
@ -228,7 +228,7 @@ class SampleAssistant(object):
def is_grpc_error_unavailable(e): def is_grpc_error_unavailable(e):
is_grpc_error = isinstance(e, grpc.RpcError) is_grpc_error = isinstance(e, grpc.RpcError)
if is_grpc_error and (e.code() == grpc.StatusCode.UNAVAILABLE): if is_grpc_error and (e.code() == grpc.StatusCode.UNAVAILABLE):
logging.error('grpc unavailable error: %s', e) logger.error('grpc unavailable error: %s', e)
return True return True
return False return False
@ -243,7 +243,7 @@ class SampleAssistant(object):
device_actions_futures = [] device_actions_futures = []
self.conversation_stream.start_recording() self.conversation_stream.start_recording()
logging.info('Recording audio request.') logger.info('Recording audio request.')
if self.on_conversation_start: if self.on_conversation_start:
self.on_conversation_start() self.on_conversation_start()
@ -262,27 +262,27 @@ class SampleAssistant(object):
self.deadline): self.deadline):
assistant_helpers.log_assist_response_without_audio(resp) assistant_helpers.log_assist_response_without_audio(resp)
if resp.event_type == self.END_OF_UTTERANCE: if resp.event_type == self.END_OF_UTTERANCE:
logging.info('End of audio request detected') logger.info('End of audio request detected')
self.conversation_stream.stop_recording() self.conversation_stream.stop_recording()
if resp.speech_results: if resp.speech_results:
user_request = ' '.join( user_request = ' '.join(
r.transcript for r in resp.speech_results) r.transcript for r in resp.speech_results)
logging.info('Transcript of user request: "%s".', user_request) logger.info('Transcript of user request: "%s".', user_request)
logging.info('Playing assistant response.') logger.info('Playing assistant response.')
if len(resp.audio_out.audio_data) > 0: if len(resp.audio_out.audio_data) > 0:
self.conversation_stream.write(resp.audio_out.audio_data) self.conversation_stream.write(resp.audio_out.audio_data)
if resp.dialog_state_out.conversation_state: if resp.dialog_state_out.conversation_state:
conversation_state = resp.dialog_state_out.conversation_state conversation_state = resp.dialog_state_out.conversation_state
logging.debug('Updating conversation state.') logger.debug('Updating conversation state.')
self.conversation_state = conversation_state self.conversation_state = conversation_state
if resp.dialog_state_out.volume_percentage != 0: if resp.dialog_state_out.volume_percentage != 0:
volume_percentage = resp.dialog_state_out.volume_percentage volume_percentage = resp.dialog_state_out.volume_percentage
logging.info('Setting volume to %s%%', volume_percentage) logger.info('Setting volume to %s%%', volume_percentage)
self.conversation_stream.volume_percentage = volume_percentage self.conversation_stream.volume_percentage = volume_percentage
if resp.dialog_state_out.microphone_mode == self.DIALOG_FOLLOW_ON: if resp.dialog_state_out.microphone_mode == self.DIALOG_FOLLOW_ON:
continue_conversation = True continue_conversation = True
logging.info('Expecting follow-on query from user.') logger.info('Expecting follow-on query from user.')
elif resp.dialog_state_out.microphone_mode == self.CLOSE_MICROPHONE: elif resp.dialog_state_out.microphone_mode == self.CLOSE_MICROPHONE:
continue_conversation = False continue_conversation = False
if resp.device_action.device_request_json: if resp.device_action.device_request_json:
@ -294,10 +294,10 @@ class SampleAssistant(object):
device_actions_futures.extend(fs) device_actions_futures.extend(fs)
if len(device_actions_futures): if len(device_actions_futures):
logging.info('Waiting for device executions to complete.') logger.info('Waiting for device executions to complete.')
concurrent.futures.wait(device_actions_futures) concurrent.futures.wait(device_actions_futures)
logging.info('Finished playing assistant response.') logger.info('Finished playing assistant response.')
try: try:
self.conversation_stream.stop_playback() self.conversation_stream.stop_playback()
@ -317,7 +317,7 @@ class SampleAssistant(object):
conversation_state=b'' conversation_state=b''
) )
if self.conversation_state: if self.conversation_state:
logging.debug('Sending conversation state.') logger.debug('Sending conversation state.')
dialog_state_in.conversation_state = self.conversation_state dialog_state_in.conversation_state = self.conversation_state
config = embedded_assistant_pb2.AssistConfig( config = embedded_assistant_pb2.AssistConfig(
audio_in_config=embedded_assistant_pb2.AudioInConfig( audio_in_config=embedded_assistant_pb2.AudioInConfig(

View File

@ -1,4 +1,3 @@
import logging
import json import json
import os import os
import subprocess import subprocess
@ -37,7 +36,7 @@ class AssistantSnowboyBackend(Backend):
self.voice_model_file, sensitivity=self.sensitivity, self.voice_model_file, sensitivity=self.sensitivity,
audio_gain=self.audio_gain) audio_gain=self.audio_gain)
logging.info('Initialized Snowboy hotword detection') self.logger.info('Initialized Snowboy hotword detection')
def send_message(self, msg): def send_message(self, msg):
pass pass

View File

@ -1,5 +1,4 @@
import importlib import importlib
import logging
from enum import Enum from enum import Enum
from threading import Timer from threading import Timer
@ -33,7 +32,7 @@ class ButtonFlicBackend(Backend):
self._down_pressed_time = None self._down_pressed_time = None
self._cur_sequence = [] self._cur_sequence = []
logging.info('Initialized Flic buttons backend on {}'.format(self.server)) self.logger.info('Initialized Flic buttons backend on {}'.format(self.server))
def _got_button(self): def _got_button(self):
def _f(bd_addr): def _f(bd_addr):
@ -53,7 +52,7 @@ class ButtonFlicBackend(Backend):
def _on_btn_timeout(self): def _on_btn_timeout(self):
def _f(): def _f():
logging.info('Flic event triggered from {}: {}'.format( self.logger.info('Flic event triggered from {}: {}'.format(
self._btn_addr, self._cur_sequence)) self._btn_addr, self._cur_sequence))
self.bus.post(FlicButtonEvent( self.bus.post(FlicButtonEvent(

View File

@ -1,10 +1,10 @@
import logging
import socket import socket
import time import time
import picamera import picamera
from platypush.backend import Backend from platypush.backend import Backend
class CameraPiBackend(Backend): class CameraPiBackend(Backend):
def __init__(self, listen_port, x_resolution=640, y_resolution=480, def __init__(self, listen_port, x_resolution=640, y_resolution=480,
framerate=24, hflip=False, vflip=False, framerate=24, hflip=False, vflip=False,
@ -42,7 +42,7 @@ class CameraPiBackend(Backend):
self.camera.rotation = rotation self.camera.rotation = rotation
self.camera.crop = crop self.camera.crop = crop
logging.info('Initialized Pi camera backend') self.logger.info('Initialized Pi camera backend')
def send_message(self, msg): def send_message(self, msg):
pass pass

View File

@ -1,6 +1,5 @@
import asyncio import asyncio
import inspect import inspect
import logging
import json import json
import os import os
import re import re
@ -47,11 +46,11 @@ class HttpBackend(Backend):
def send_message(self, msg): def send_message(self, msg):
logging.warning('Use cURL or any HTTP client to query the HTTP backend') self.logger.warning('Use cURL or any HTTP client to query the HTTP backend')
def stop(self): def stop(self):
logging.info('Received STOP event on HttpBackend') self.logger.info('Received STOP event on HttpBackend')
if self.server_proc: if self.server_proc:
self.server_proc.terminate() self.server_proc.terminate()
@ -70,7 +69,7 @@ class HttpBackend(Backend):
try: try:
loop.run_until_complete(send_event(websocket)) loop.run_until_complete(send_event(websocket))
except websockets.exceptions.ConnectionClosed: except websockets.exceptions.ConnectionClosed:
logging.info('Client connection lost') self.logger.info('Client connection lost')
def redis_poll(self): def redis_poll(self):
@ -94,11 +93,11 @@ class HttpBackend(Backend):
if token != self.token: abort(401) if token != self.token: abort(401)
msg = Message.build(args) msg = Message.build(args)
logging.info('Received message on the HTTP backend: {}'.format(msg)) self.logger.info('Received message on the HTTP backend: {}'.format(msg))
if isinstance(msg, Request): if isinstance(msg, Request):
response = msg.execute(async=False) response = msg.execute(async=False)
logging.info('Processing response on the HTTP backend: {}'.format(msg)) self.logger.info('Processing response on the HTTP backend: {}'.format(msg))
return str(response) return str(response)
elif isinstance(msg, Event): elif isinstance(msg, Event):
self.redis.rpush(self.redis_queue, msg) self.redis.rpush(self.redis_queue, msg)
@ -148,13 +147,13 @@ class HttpBackend(Backend):
import websockets import websockets
async def register_websocket(websocket, path): async def register_websocket(websocket, path):
logging.info('New websocket connection from {}'.format(websocket.remote_address[0])) self.logger.info('New websocket connection from {}'.format(websocket.remote_address[0]))
self.active_websockets.add(websocket) self.active_websockets.add(websocket)
try: try:
await websocket.recv() await websocket.recv()
except websockets.exceptions.ConnectionClosed: except websockets.exceptions.ConnectionClosed:
logging.info('Websocket client {} closed connection'.format(websocket.remote_address[0])) self.logger.info('Websocket client {} closed connection'.format(websocket.remote_address[0]))
self.active_websockets.remove(websocket) self.active_websockets.remove(websocket)
loop = asyncio.new_event_loop() loop = asyncio.new_event_loop()
@ -166,7 +165,7 @@ class HttpBackend(Backend):
def run(self): def run(self):
super().run() super().run()
logging.info('Initialized HTTP backend on port {}'.format(self.port)) self.logger.info('Initialized HTTP backend on port {}'.format(self.port))
webserver = self.webserver() webserver = self.webserver()
self.server_proc = Process(target=webserver.run, kwargs={ self.server_proc = Process(target=webserver.run, kwargs={

View File

@ -1,7 +1,6 @@
import datetime import datetime
import enum import enum
import feedparser import feedparser
import logging
import os import os
import requests import requests
import time import time
@ -68,11 +67,11 @@ class RssUpdates(HttpRequest):
response = None response = None
try: try:
logging.info('Parsing content for {}'.format(link)) self.logger.info('Parsing content for {}'.format(link))
response = requests.get('https://mercury.postlight.com/parser', response = requests.get('https://mercury.postlight.com/parser',
params = {'url': link}, params = {'url': link},
headers = {'x-api-key': self.mercury_api_key }) headers = {'x-api-key': self.mercury_api_key })
except Exception as e: logging.exception(e) except Exception as e: self.logger.exception(e)
return response.json()['content'] if response and response.ok else None return response.json()['content'] if response and response.ok else None
@ -104,7 +103,7 @@ class RssUpdates(HttpRequest):
datetime.datetime.now().strftime('%d %B %Y, %H:%M') datetime.datetime.now().strftime('%d %B %Y, %H:%M')
) )
logging.info('Parsed {:d} items from RSS feed <{}>' self.logger.info('Parsed {:d} items from RSS feed <{}>'
.format(len(feed.entries), self.url)) .format(len(feed.entries), self.url))
for entry in feed.entries: for entry in feed.entries:
@ -115,7 +114,7 @@ class RssUpdates(HttpRequest):
if latest_update is None \ if latest_update is None \
or entry_timestamp > latest_update: or entry_timestamp > latest_update:
logging.info('Processed new item from RSS feed <{}>: "{}"' self.logger.info('Processed new item from RSS feed <{}>: "{}"'
.format(self.url, entry.title)) .format(self.url, entry.title))
entry.summary = entry.summary if hasattr(entry, 'summary') else None entry.summary = entry.summary if hasattr(entry, 'summary') else None
@ -148,7 +147,7 @@ class RssUpdates(HttpRequest):
digest_filename = None digest_filename = None
if entries: if entries:
logging.info('Parsed {} new entries from the RSS feed {}'.format( self.logger.info('Parsed {} new entries from the RSS feed {}'.format(
len(entries), self.title)) len(entries), self.title))
if self.digest_format: if self.digest_format:
@ -173,10 +172,10 @@ class RssUpdates(HttpRequest):
filename=digest_filename) filename=digest_filename)
session.add(digest_entry) session.add(digest_entry)
logging.info('{} digest ready: {}'.format(self.digest_format, digest_filename)) self.logger.info('{} digest ready: {}'.format(self.digest_format, digest_filename))
session.commit() session.commit()
logging.info('Parsing RSS feed {}: completed'.format(self.title)) self.logger.info('Parsing RSS feed {}: completed'.format(self.title))
return NewFeedEvent(request=dict(self), response=entries, return NewFeedEvent(request=dict(self), response=entries,
source_id=source_record.id, title=self.title, source_id=source_record.id, title=self.title,

View File

@ -1,11 +1,11 @@
import os import os
import logging
import inotify.adapters import inotify.adapters
from platypush.backend import Backend from platypush.backend import Backend
from platypush.message.event.path import PathCreateEvent, PathDeleteEvent, \ from platypush.message.event.path import PathCreateEvent, PathDeleteEvent, \
PathOpenEvent, PathModifyEvent, PathPermissionsChangeEvent, PathCloseEvent PathOpenEvent, PathModifyEvent, PathPermissionsChangeEvent, PathCloseEvent
class InotifyBackend(Backend): class InotifyBackend(Backend):
inotify_watch = None inotify_watch = None
@ -34,7 +34,7 @@ class InotifyBackend(Backend):
for path in self.watch_paths: for path in self.watch_paths:
self.inotify_watch.add_watch(path) self.inotify_watch.add_watch(path)
logging.info('Initialized inotify file monitoring backend, monitored resources: {}' self.logger.info('Initialized inotify file monitoring backend, monitored resources: {}'
.format(self.watch_paths)) .format(self.watch_paths))
try: try:

View File

@ -1,11 +1,12 @@
import logging
import json import json
import logging
import time import time
from kafka import KafkaConsumer, KafkaProducer from kafka import KafkaConsumer, KafkaProducer
from .. import Backend from .. import Backend
class KafkaBackend(Backend): class KafkaBackend(Backend):
_conn_retry_secs = 5 _conn_retry_secs = 5
@ -17,6 +18,7 @@ class KafkaBackend(Backend):
self.topic = self._topic_by_device_id(self.device_id) self.topic = self._topic_by_device_id(self.device_id)
self.producer = None self.producer = None
# Kafka can be veryyyy noisy
logging.getLogger('kafka').setLevel(logging.ERROR) logging.getLogger('kafka').setLevel(logging.ERROR)
def _on_record(self, record): def _on_record(self, record):
@ -25,9 +27,9 @@ class KafkaBackend(Backend):
try: try:
msg = json.loads(record.value.decode('utf-8')) msg = json.loads(record.value.decode('utf-8'))
except Exception as e: except Exception as e:
logging.exception(e) self.logger.exception(e)
logging.debug('Received message on Kafka backend: {}'.format(msg)) self.logger.debug('Received message on Kafka backend: {}'.format(msg))
self.on_message(msg) self.on_message(msg)
def _init_producer(self): def _init_producer(self):
@ -54,14 +56,14 @@ class KafkaBackend(Backend):
if self.consumer: if self.consumer:
self.consumer.close() self.consumer.close()
except Exception as e: except Exception as e:
logging.warning('Exception occurred while closing Kafka connection') self.logger.warning('Exception occurred while closing Kafka connection')
logging.exception(e) self.logger.exception(e)
def run(self): def run(self):
super().run() super().run()
self.consumer = KafkaConsumer(self.topic, bootstrap_servers=self.server) self.consumer = KafkaConsumer(self.topic, bootstrap_servers=self.server)
logging.info('Initialized kafka backend - server: {}, topic: {}' self.logger.info('Initialized kafka backend - server: {}, topic: {}'
.format(self.server, self.topic)) .format(self.server, self.topic))
try: try:
@ -69,9 +71,9 @@ class KafkaBackend(Backend):
self._on_record(msg) self._on_record(msg)
if self.should_stop(): break if self.should_stop(): break
except Exception as e: except Exception as e:
logging.warning('Kafka connection error, reconnecting in {} seconds'. self.logger.warning('Kafka connection error, reconnecting in {} seconds'.
format(self._conn_retry_secs)) format(self._conn_retry_secs))
logging.exception(e) self.logger.exception(e)
time.sleep(self._conn_retry_secs) time.sleep(self._conn_retry_secs)
# vim:sw=4:ts=4:et: # vim:sw=4:ts=4:et:

View File

@ -1,4 +1,3 @@
import logging
import json import json
import os import os
import time import time
@ -11,6 +10,7 @@ from platypush.message.event import StopEvent
from platypush.message.request import Request from platypush.message.request import Request
from platypush.message.response import Response from platypush.message.response import Response
class LocalBackend(Backend): class LocalBackend(Backend):
""" """
Sends and receive messages on two distinct local FIFOs, one for Sends and receive messages on two distinct local FIFOs, one for
@ -63,7 +63,7 @@ class LocalBackend(Backend):
def run(self): def run(self):
super().run() super().run()
logging.info('Initialized local backend on {} and {}'. self.logger.info('Initialized local backend on {} and {}'.
format(self.request_fifo, self.response_fifo)) format(self.request_fifo, self.response_fifo))
while not self.should_stop(): while not self.should_stop():
@ -71,11 +71,11 @@ class LocalBackend(Backend):
msg = self._get_next_message() msg = self._get_next_message()
if not msg: continue if not msg: continue
except Exception as e: except Exception as e:
logging.exception(e) self.logger.exception(e)
time.sleep(0.2) time.sleep(0.2)
continue continue
logging.debug('Received message on the local backend: {}, thread_id: '.format(msg, self.thread_id)) self.logger.debug('Received message on the local backend: {}, thread_id: '.format(msg, self.thread_id))
if self.should_stop(): break if self.should_stop(): break
self.on_message(msg) self.on_message(msg)

View File

@ -1,4 +1,3 @@
import logging
import json import json
import time import time
@ -9,8 +8,6 @@ from threading import Timer
from platypush.backend import Backend from platypush.backend import Backend
from platypush.message.event.midi import MidiMessageEvent from platypush.message.event.midi import MidiMessageEvent
logger = logging.getLogger(__name__)
class MidiBackend(Backend): class MidiBackend(Backend):
""" """
@ -69,7 +66,7 @@ class MidiBackend(Backend):
def _on_midi_message(self): def _on_midi_message(self):
def flush_midi_message(message): def flush_midi_message(message):
def _f(): def _f():
logger.info('Flushing throttled MIDI message {} to the bus'.format(message)) self.logger.info('Flushing throttled MIDI message {} to the bus'.format(message))
delay = time.time() - self.last_trigger_event_time delay = time.time() - self.last_trigger_event_time
self.bus.post(MidiMessageEvent(message=message, delay=delay)) self.bus.post(MidiMessageEvent(message=message, delay=delay))
return _f return _f
@ -83,7 +80,7 @@ class MidiBackend(Backend):
if self.midi_throttle_time and self.last_trigger_event_time: if self.midi_throttle_time and self.last_trigger_event_time:
event_delta = time.time() - self.last_trigger_event_time event_delta = time.time() - self.last_trigger_event_time
if event_delta < self.midi_throttle_time: if event_delta < self.midi_throttle_time:
logger.debug('Skipping throttled message {}'.format(message)) self.logger.debug('Skipping throttled message {}'.format(message))
if self.midi_flush_timeout: if self.midi_flush_timeout:
self.midi_flush_timeout.cancel() self.midi_flush_timeout.cancel()
@ -104,14 +101,14 @@ class MidiBackend(Backend):
super().run() super().run()
self.midi.open_port(self.port_number) self.midi.open_port(self.port_number)
logger.info('Initialized MIDI backend, listening for events on device {}'. self.logger.info('Initialized MIDI backend, listening for events on device {}'.
format(self.device_name)) format(self.device_name))
while not self.should_stop(): while not self.should_stop():
try: try:
time.sleep(1) time.sleep(1)
except Exception as e: except Exception as e:
logging.exception(e) self.logger.exception(e)
if self.midi: if self.midi:
self.midi.close_port(self.port_number) self.midi.close_port(self.port_number)

View File

@ -1,4 +1,3 @@
import logging
import json import json
import paho.mqtt.client as mqtt import paho.mqtt.client as mqtt
@ -43,7 +42,7 @@ class MqttBackend(Backend):
except: except:
pass pass
logging.info('Received message on the MQTT backend: {}'.format(msg)) self.logger.info('Received message on the MQTT backend: {}'.format(msg))
self.bus.post(msg) self.bus.post(msg)
super().run() super().run()
@ -51,7 +50,7 @@ class MqttBackend(Backend):
client.on_connect = on_connect client.on_connect = on_connect
client.on_message = on_message client.on_message = on_message
client.connect(self.host, self.port, 60) client.connect(self.host, self.port, 60)
logging.info('Initialized MQTT backend on host {}:{}, topic {}'. self.logger.info('Initialized MQTT backend on host {}:{}, topic {}'.
format(self.host, self.port, self.topic)) format(self.host, self.port, self.topic))
client.loop_forever() client.loop_forever()

View File

@ -1,4 +1,3 @@
import logging
import re import re
import time import time
@ -41,8 +40,8 @@ class MusicMpdBackend(Backend):
playlist = status['playlist'] playlist = status['playlist']
success = True success = True
except Exception as e: except Exception as e:
logging.exception(e) self.logger.exception(e)
logging.info('Reloading crashed MPD plugin') self.logger.info('Reloading crashed MPD plugin')
plugin = get_plugin('music.mpd', reload=True) plugin = get_plugin('music.mpd', reload=True)
time.sleep(self.poll_seconds) time.sleep(self.poll_seconds)

View File

@ -1,4 +1,3 @@
import logging
import json import json
import requests import requests
import time import time
@ -10,6 +9,7 @@ from platypush.message.event.pushbullet import PushbulletEvent
from .. import Backend from .. import Backend
class PushbulletBackend(Backend): class PushbulletBackend(Backend):
def __init__(self, token, device, **kwargs): def __init__(self, token, device, **kwargs):
super().__init__(**kwargs) super().__init__(**kwargs)
@ -39,7 +39,7 @@ class PushbulletBackend(Backend):
response = response.json() response = response.json()
except Exception as e: except Exception as e:
logging.exception(e) self.logger.exception(e)
raise e raise e
if 'pushes' in response and response['pushes']: if 'pushes' in response and response['pushes']:
@ -59,7 +59,7 @@ class PushbulletBackend(Backend):
and time.time() - last_msg['time'] <= 2: and time.time() - last_msg['time'] <= 2:
# Duplicate message sent on the Pushbullet socket within # Duplicate message sent on the Pushbullet socket within
# two seconds, ignore it # two seconds, ignore it
logging.debug('Ignoring duplicate message received on the socket') self.logger.debug('Ignoring duplicate message received on the socket')
is_duplicate = True is_duplicate = True
self._last_received_msg[msg['type']] = { self._last_received_msg[msg['type']] = {
@ -75,7 +75,7 @@ class PushbulletBackend(Backend):
try: try:
data = json.loads(data) if isinstance(data, str) else push data = json.loads(data) if isinstance(data, str) else push
except Exception as e: except Exception as e:
logging.exception(e) self.logger.exception(e)
return return
# If it's a push, get it # If it's a push, get it
@ -91,7 +91,7 @@ class PushbulletBackend(Backend):
self.on_message(event) self.on_message(event)
if 'body' not in push: return if 'body' not in push: return
logging.debug('Received push: {}'.format(push)) self.logger.debug('Received push: {}'.format(push))
body = push['body'] body = push['body']
try: body = json.loads(body) try: body = json.loads(body)
@ -100,15 +100,15 @@ class PushbulletBackend(Backend):
if not self._should_skip_last_received_msg(body): if not self._should_skip_last_received_msg(body):
self.on_message(body) self.on_message(body)
except Exception as e: except Exception as e:
logging.exception(e) self.logger.exception(e)
return return
return _f return _f
def on_error(self): def on_error(self):
def _f(ws, e): def _f(ws, e):
logging.exception(e) self.logger.exception(e)
logging.info('Restarting PushBullet backend') self.logger.info('Restarting PushBullet backend')
ws.close() ws.close()
self._init_socket() self._init_socket()
@ -153,7 +153,7 @@ class PushbulletBackend(Backend):
super().run() super().run()
self._init_socket() self._init_socket()
logging.info('Initialized Pushbullet backend - device_id: {}' self.logger.info('Initialized Pushbullet backend - device_id: {}'
.format(self.device_name)) .format(self.device_name))
self.ws.run_forever() self.ws.run_forever()

View File

@ -1,4 +1,3 @@
import logging
import json import json
from redis import Redis from redis import Redis
@ -37,7 +36,7 @@ class RedisBackend(Backend):
def run(self): def run(self):
super().run() super().run()
logging.info('Initialized Redis backend on queue {} with arguments {}'. self.logger.info('Initialized Redis backend on queue {} with arguments {}'.
format(self.queue, self.redis_args)) format(self.queue, self.redis_args))
while not self.should_stop(): while not self.should_stop():
@ -50,10 +49,10 @@ class RedisBackend(Backend):
import ast import ast
msg = Message.build(ast.literal_eval(msg)) msg = Message.build(ast.literal_eval(msg))
logging.info('Received message on the Redis backend: {}'.format(msg)) self.logger.info('Received message on the Redis backend: {}'.format(msg))
self.bus.post(msg) self.bus.post(msg)
except Exception as e: except Exception as e:
logging.exception(e) self.logger.exception(e)
# vim:sw=4:ts=4:et: # vim:sw=4:ts=4:et:

View File

@ -1,4 +1,3 @@
import logging
import json import json
from smartcard.CardType import AnyCardType, ATRCardType from smartcard.CardType import AnyCardType, ATRCardType
@ -49,7 +48,7 @@ class ScardBackend(Backend):
def run(self): def run(self):
super().run() super().run()
logging.info('Initialized smart card reader backend - ATR filter: {}'. self.logger.info('Initialized smart card reader backend - ATR filter: {}'.
format(self.ATRs)) format(self.ATRs))
prev_atr = None prev_atr = None
@ -65,7 +64,7 @@ class ScardBackend(Backend):
atr = toHexString(cardservice.connection.getATR()) atr = toHexString(cardservice.connection.getATR())
if atr != prev_atr: if atr != prev_atr:
logging.info('Smart card detected on reader {}, ATR: {}'. self.logger.info('Smart card detected on reader {}, ATR: {}'.
format(reader, atr)) format(reader, atr))
self.bus.post(SmartCardDetectedEvent(atr=atr, reader=reader)) self.bus.post(SmartCardDetectedEvent(atr=atr, reader=reader))
@ -74,7 +73,7 @@ class ScardBackend(Backend):
if isinstance(e, NoCardException) or isinstance(e, CardConnectionException): if isinstance(e, NoCardException) or isinstance(e, CardConnectionException):
self.bus.post(SmartCardRemovedEvent(atr=prev_atr, reader=reader)) self.bus.post(SmartCardRemovedEvent(atr=prev_atr, reader=reader))
else: else:
logging.exception(e) self.logger.exception(e)
prev_atr = None prev_atr = None

View File

@ -1,4 +1,3 @@
import logging
import time import time
import platypush.plugins.gpio.zeroborg.lib as ZeroBorg import platypush.plugins.gpio.zeroborg.lib as ZeroBorg
@ -6,6 +5,7 @@ import platypush.plugins.gpio.zeroborg.lib as ZeroBorg
from platypush.backend import Backend from platypush.backend import Backend
from platypush.message.event.sensor.ir import IrKeyUpEvent, IrKeyDownEvent from platypush.message.event.sensor.ir import IrKeyUpEvent, IrKeyDownEvent
class SensorIrZeroborgBackend(Backend): class SensorIrZeroborgBackend(Backend):
last_message =None last_message =None
last_message_timestamp = None last_message_timestamp = None
@ -15,7 +15,7 @@ class SensorIrZeroborgBackend(Backend):
self.no_message_timeout = no_message_timeout self.no_message_timeout = no_message_timeout
self.zb = ZeroBorg.ZeroBorg() self.zb = ZeroBorg.ZeroBorg()
self.zb.Init() self.zb.Init()
logging.info('Initialized Zeroborg infrared sensor backend') self.logger.info('Initialized Zeroborg infrared sensor backend')
def send_message(self, message): def send_message(self, message):
@ -31,17 +31,17 @@ class SensorIrZeroborgBackend(Backend):
if self.zb.HasNewIrMessage(): if self.zb.HasNewIrMessage():
message = self.zb.GetIrMessage() message = self.zb.GetIrMessage()
if message != self.last_message: if message != self.last_message:
logging.info('Received key down event on the IR sensor: {}'.format(message)) self.logger.info('Received key down event on the IR sensor: {}'.format(message))
self.bus.post(IrKeyDownEvent(message=message)) self.bus.post(IrKeyDownEvent(message=message))
self.last_message = message self.last_message = message
self.last_message_timestamp = time.time() self.last_message_timestamp = time.time()
except OSError as e: except OSError as e:
logging.warning('Failed reading IR sensor status') self.logger.warning('Failed reading IR sensor status')
if self.last_message_timestamp and \ if self.last_message_timestamp and \
time.time() - self.last_message_timestamp > self.no_message_timeout: time.time() - self.last_message_timestamp > self.no_message_timeout:
logging.info('Received key up event on the IR sensor') self.logger.info('Received key up event on the IR sensor')
self.bus.post(IrKeyUpEvent(message=self.last_message)) self.bus.post(IrKeyUpEvent(message=self.last_message))
self.last_message = None self.last_message = None

View File

@ -1,4 +1,3 @@
import logging
import time import time
import Leap import Leap
@ -50,7 +49,7 @@ class SensorLeapBackend(Backend):
'device connected and is leapd running?') 'device connected and is leapd running?')
controller.add_listener(listener) controller.add_listener(listener)
logging.info('Leap Motion backend initialized') self.logger.info('Leap Motion backend initialized')
try: try:
while not self.should_stop(): while not self.should_stop():
@ -71,7 +70,7 @@ class LeapListener(Leap.Listener):
def send_event(self, event): def send_event(self, event):
backend = get_backend('redis') backend = get_backend('redis')
if not backend: if not backend:
logging.warning('Redis backend not configured, I cannot propagate the following event: {}'.format(event)) self.logger.warning('Redis backend not configured, I cannot propagate the following event: {}'.format(event))
return return
backend.send_message(event) backend.send_message(event)
@ -79,20 +78,20 @@ class LeapListener(Leap.Listener):
def on_init(self, controller): def on_init(self, controller):
self.prev_frame = None self.prev_frame = None
logging.info('Leap controller listener initialized') self.logger.info('Leap controller listener initialized')
def on_connect(self, controller): def on_connect(self, controller):
logging.info('Leap controller connected') self.logger.info('Leap controller connected')
self.prev_frame = None self.prev_frame = None
self.send_event(LeapConnectEvent()) self.send_event(LeapConnectEvent())
def on_disconnect(self, controller): def on_disconnect(self, controller):
logging.info('Leap controller disconnected') self.logger.info('Leap controller disconnected')
self.prev_frame = None self.prev_frame = None
self.send_event(LeapDisconnectEvent()) self.send_event(LeapDisconnectEvent())
def on_exit(self, controller): def on_exit(self, controller):
logging.info('Leap listener terminated') self.logger.info('Leap listener terminated')
def on_frame(self, controller): def on_frame(self, controller):
frame = controller.frame() frame = controller.frame()

View File

@ -1,4 +1,3 @@
import logging
import time import time
import RPi.GPIO as gpio import RPi.GPIO as gpio
@ -28,7 +27,7 @@ class SensorLightBackend(Backend):
gpio.setmode(gpio.BCM) gpio.setmode(gpio.BCM)
gpio.setup(self.pin, gpio.IN) gpio.setup(self.pin, gpio.IN)
logging.info('Initialized light sensor backend on pin {}'.format(self.pin)) self.logger.info('Initialized light sensor backend on pin {}'.format(self.pin))
try: try:
while not self.should_stop(): while not self.should_stop():

View File

@ -1,4 +1,3 @@
import logging
import time import time
from platypush.backend import Backend from platypush.backend import Backend
@ -13,7 +12,7 @@ class SensorMcp3008Backend(Backend):
def __init__(self, poll_seconds, *args, **kwargs): def __init__(self, poll_seconds, *args, **kwargs):
super().__init__(*args, **kwargs) super().__init__(*args, **kwargs)
self.poll_seconds = poll_seconds self.poll_seconds = poll_seconds
logging.info('Initialized MCP3008 analog sensors backend') self.logger.info('Initialized MCP3008 analog sensors backend')
def send_message(self, msg): def send_message(self, msg):

View File

@ -1,10 +1,10 @@
import logging
import serial import serial
from platypush.backend import Backend from platypush.backend import Backend
from platypush.context import get_plugin from platypush.context import get_plugin
from platypush.message.event.serial import SerialDataEvent from platypush.message.event.serial import SerialDataEvent
class SerialBackend(Backend): class SerialBackend(Backend):
def __init__(self, **kwargs): def __init__(self, **kwargs):
super().__init__(**kwargs) super().__init__(**kwargs)
@ -19,7 +19,7 @@ class SerialBackend(Backend):
def run(self): def run(self):
super().run() super().run()
logging.info('Initialized serial backend') self.logger.info('Initialized serial backend')
while not self.should_stop(): while not self.should_stop():
new_data = self.get_data() new_data = self.get_data()

View File

@ -1,4 +1,3 @@
import logging
import time import time
from platypush.backend import Backend from platypush.backend import Backend
@ -6,6 +5,7 @@ from platypush.context import get_plugin
from platypush.plugins.weather.forecast import WeatherForecastPlugin from platypush.plugins.weather.forecast import WeatherForecastPlugin
from platypush.message.event.weather import NewWeatherConditionEvent from platypush.message.event.weather import NewWeatherConditionEvent
class WeatherForecastBackend(Backend): class WeatherForecastBackend(Backend):
def __init__(self, poll_seconds, **kwargs): def __init__(self, poll_seconds, **kwargs):
super().__init__(**kwargs) super().__init__(**kwargs)
@ -18,7 +18,7 @@ class WeatherForecastBackend(Backend):
def run(self): def run(self):
super().run() super().run()
weather = get_plugin('weather.forecast') weather = get_plugin('weather.forecast')
logging.info('Initialized weather forecast backend') self.logger.info('Initialized weather forecast backend')
while not self.should_stop(): while not self.should_stop():
current_weather = weather.get_current_weather().output current_weather = weather.get_current_weather().output

View File

@ -10,6 +10,9 @@ from queue import Queue
from platypush.config import Config from platypush.config import Config
from platypush.message.event import Event, StopEvent from platypush.message.event import Event, StopEvent
logger = logging.getLogger(__name__)
class Bus(object): class Bus(object):
""" Main local bus where the daemon will listen for new messages """ """ Main local bus where the daemon will listen for new messages """
@ -40,7 +43,7 @@ class Bus(object):
""" """
if not self.on_message: if not self.on_message:
logging.warning('No message handlers installed, cannot poll') logger.warning('No message handlers installed, cannot poll')
return return
stop=False stop=False
@ -49,7 +52,7 @@ class Bus(object):
self.on_message(msg) self.on_message(msg)
if isinstance(msg, StopEvent) and msg.targets_me(): if isinstance(msg, StopEvent) and msg.targets_me():
logging.info('Received STOP event on the bus') logger.info('Received STOP event on the bus')
stop=True stop=True

View File

@ -72,13 +72,19 @@ class Config(object):
if 'logging' in self._config: if 'logging' in self._config:
for (k,v) in self._config['logging'].items(): for (k,v) in self._config['logging'].items():
logging_config[k] = v
if k == 'filename': if k == 'filename':
logfile = os.path.expanduser(v) logfile = os.path.expanduser(v)
logdir = os.path.dirname(logfile) logdir = os.path.dirname(logfile)
os.makedirs(logdir, exist_ok=True) os.makedirs(logdir, exist_ok=True)
logging_config[k] = logfile v = logfile
del logging_config['stream'] del logging_config['stream']
elif k == 'level':
try:
v = int(v)
except ValueError:
v = getattr(logging, v.upper())
logging_config[k] = v
self._config['logging'] = logging_config self._config['logging'] = logging_config

View File

@ -3,6 +3,8 @@ import logging
from ..config import Config from ..config import Config
logger = logging.getLogger(__name__)
# Map: backend_name -> backend_instance # Map: backend_name -> backend_instance
backends = {} backends = {}
@ -44,7 +46,7 @@ def register_backends(bus=None, global_scope=False, **kwargs):
b = getattr(module, cls_name)(bus=bus, **cfg, **kwargs) b = getattr(module, cls_name)(bus=bus, **cfg, **kwargs)
backends[name] = b backends[name] = b
except AttributeError as e: except AttributeError as e:
logging.warning('No such class in {}: {}'.format( logger.warning('No such class in {}: {}'.format(
module.__name__, cls_name)) module.__name__, cls_name))
raise RuntimeError(e) raise RuntimeError(e)
@ -68,7 +70,7 @@ def get_plugin(plugin_name, reload=False):
try: try:
plugin = importlib.import_module('platypush.plugins.' + plugin_name) plugin = importlib.import_module('platypush.plugins.' + plugin_name)
except ImportError as e: except ImportError as e:
logging.warning('No such plugin: {}'.format(plugin_name)) logger.warning('No such plugin: {}'.format(plugin_name))
raise RuntimeError(e) raise RuntimeError(e)
# e.g. plugins.music.mpd main class: MusicMpdPlugin # e.g. plugins.music.mpd main class: MusicMpdPlugin
@ -85,7 +87,7 @@ def get_plugin(plugin_name, reload=False):
plugin = plugin_class(**plugin_conf) plugin = plugin_class(**plugin_conf)
plugins[plugin_name] = plugin plugins[plugin_name] = plugin
except AttributeError as e: except AttributeError as e:
logging.warning('No such class in {}: {}'.format(plugin_name, cls_name)) logger.warning('No such class in {}: {}'.format(plugin_name, cls_name))
raise RuntimeError(e) raise RuntimeError(e)
plugins[plugin_name] = plugin plugins[plugin_name] = plugin

View File

@ -7,6 +7,9 @@ from threading import Thread
from platypush.event.hook import EventAction from platypush.event.hook import EventAction
logger = logging.getLogger(__name__)
class Cronjob(Thread): class Cronjob(Thread):
def __init__(self, name, cron_expression, actions, *args, **kwargs): def __init__(self, name, cron_expression, actions, *args, **kwargs):
super().__init__() super().__init__()
@ -19,13 +22,13 @@ class Cronjob(Thread):
def run(self): def run(self):
logging.info('Running cronjob {}'.format(self.name)) logger.info('Running cronjob {}'.format(self.name))
response = None response = None
context = {} context = {}
for action in self.actions: for action in self.actions:
response = action.execute(async=False, **context) response = action.execute(async=False, **context)
logging.info('Response from cronjob {}: {}'.format(self.name, response)) logger.info('Response from cronjob {}: {}'.format(self.name, response))
def should_run(self): def should_run(self):
@ -56,7 +59,7 @@ class CronScheduler(Thread):
def __init__(self, jobs, *args, **kwargs): def __init__(self, jobs, *args, **kwargs):
super().__init__() super().__init__()
self.jobs_config = jobs self.jobs_config = jobs
logging.info('Cron scheduler initialized with {} jobs' logger.info('Cron scheduler initialized with {} jobs'
.format(len(self.jobs_config.keys()))) .format(len(self.jobs_config.keys())))
@ -71,7 +74,7 @@ class CronScheduler(Thread):
def run(self): def run(self):
logging.info('Running cron scheduler') logger.info('Running cron scheduler')
while True: while True:
for (job_name, job_config) in self.jobs_config.items(): for (job_name, job_config) in self.jobs_config.items():

View File

@ -8,6 +8,8 @@ from platypush.message.event import Event, EventMatchResult
from platypush.message.request import Request from platypush.message.request import Request
from platypush.utils import get_event_class_by_type from platypush.utils import get_event_class_by_type
logger = logging.getLogger(__name__)
def parse(msg): def parse(msg):
""" Builds a dict given another dictionary or """ Builds a dict given another dictionary or
@ -19,7 +21,7 @@ def parse(msg):
try: try:
msg = json.loads(msg.strip()) msg = json.loads(msg.strip())
except: except:
logging.warning('Invalid JSON message: {}'.format(msg)) logger.warning('Invalid JSON message: {}'.format(msg))
return None return None
return msg return msg
@ -142,7 +144,7 @@ class EventHook(object):
result = self.matches_event(event) result = self.matches_event(event)
if result.is_match: if result.is_match:
logging.info('Running hook {} triggered by an event'.format(self.name)) logger.info('Running hook {} triggered by an event'.format(self.name))
for action in self.actions: for action in self.actions:
a = EventAction.build(action) a = EventAction.build(action)

View File

@ -2,6 +2,8 @@ import logging
import inspect import inspect
import json import json
logger = logging.getLogger(__name__)
class Message(object): class Message(object):
""" Message generic class """ """ Message generic class """
@ -43,7 +45,7 @@ class Message(object):
try: try:
msg = json.loads(msg.strip()) msg = json.loads(msg.strip())
except: except:
logging.warning('Invalid JSON message: {}'.format(msg)) logger.warning('Invalid JSON message: {}'.format(msg))
assert isinstance(msg, dict) assert isinstance(msg, dict)
return msg return msg

View File

@ -4,6 +4,9 @@ import re
from platypush.context import get_backend from platypush.context import get_backend
from platypush.message.event import Event, EventMatchResult from platypush.message.event import Event, EventMatchResult
logger = logging.getLogger(__name__)
class AssistantEvent(Event): class AssistantEvent(Event):
""" Base class for assistant events """ """ Base class for assistant events """
@ -15,7 +18,7 @@ class AssistantEvent(Event):
try: try:
self._assistant = get_backend('assistant.google.pushtotalk') self._assistant = get_backend('assistant.google.pushtotalk')
except KeyError as e: except KeyError as e:
logging.warning('google.assistant backend not configured/initialized') logger.warning('google.assistant backend not configured/initialized')
self._assistant = None self._assistant = None

View File

@ -13,6 +13,9 @@ from platypush.message import Message
from platypush.message.response import Response from platypush.message.response import Response
from platypush.utils import get_module_and_method_from_action from platypush.utils import get_module_and_method_from_action
logger = logging.getLogger(__name__)
class Request(Message): class Request(Message):
""" Request message class """ """ Request message class """
@ -59,7 +62,7 @@ class Request(Message):
from platypush.config import Config from platypush.config import Config
from platypush.procedure import Procedure from platypush.procedure import Procedure
logging.info('Executing procedure request: {}'.format(self.action)) logger.info('Executing procedure request: {}'.format(self.action))
proc_name = self.action.split('.')[-1] proc_name = self.action.split('.')[-1]
proc_config = Config.get_procedures()[proc_name] proc_config = Config.get_procedures()[proc_name]
proc = Procedure.build(name=proc_name, requests=proc_config['actions'], proc = Procedure.build(name=proc_name, requests=proc_config['actions'],
@ -120,7 +123,7 @@ class Request(Message):
if isinstance(context_value, datetime.date): if isinstance(context_value, datetime.date):
context_value = context_value.isoformat() context_value = context_value.isoformat()
except Exception as e: except Exception as e:
logging.exception(e) logger.exception(e)
context_value = expr context_value = expr
parsed_value += prefix + ( parsed_value += prefix + (
@ -140,7 +143,7 @@ class Request(Message):
if self.backend and self.origin: if self.backend and self.origin:
self.backend.send_response(response=response, request=self) self.backend.send_response(response=response, request=self)
else: else:
logging.info('Response whose request has no ' + logger.info('Response whose request has no ' +
'origin attached: {}'.format(response)) 'origin attached: {}'.format(response))
@ -177,14 +180,14 @@ class Request(Message):
if response and response.is_error(): if response and response.is_error():
raise RuntimeError('Response processed with errors: {}'.format(response)) raise RuntimeError('Response processed with errors: {}'.format(response))
logging.info('Processed response from plugin {}: {}'. logger.info('Processed response from plugin {}: {}'.
format(plugin, response)) format(plugin, response))
except Exception as e: except Exception as e:
# Retry mechanism # Retry mechanism
response = Response(output=None, errors=[str(e), traceback.format_exc()]) response = Response(output=None, errors=[str(e), traceback.format_exc()])
logging.exception(e) logger.exception(e)
if n_tries: if n_tries:
logging.info('Reloading plugin {} and retrying'.format(module_name)) logger.info('Reloading plugin {} and retrying'.format(module_name))
get_plugin(module_name, reload=True) get_plugin(module_name, reload=True)
response = _thread_func(n_tries-1) response = _thread_func(n_tries-1)
finally: finally:

View File

@ -4,13 +4,14 @@ import logging
from platypush.config import Config from platypush.config import Config
from platypush.message.response import Response from platypush.message.response import Response
class Plugin(object): class Plugin(object):
""" Base plugin class """ """ Base plugin class """
def __init__(self, **kwargs): def __init__(self, **kwargs):
logging.basicConfig(stream=sys.stdout, level=Config.get('logging') self.logger = logging.getLogger(__name__)
if 'logging' not in kwargs if 'logging' in kwargs:
else getattr(logging, kwargs['logging'])) self.logger.setLevel(getattr(logging, kwargs['logging'].upper()))
def run(self, method, *args, **kwargs): def run(self, method, *args, **kwargs):
return getattr(self, method)(*args, **kwargs) return getattr(self, method)(*args, **kwargs)

View File

@ -1,6 +1,5 @@
import dateutil.parser import dateutil.parser
import importlib import importlib
import logging
from abc import ABCMeta, abstractmethod from abc import ABCMeta, abstractmethod
@ -46,7 +45,7 @@ class CalendarPlugin(Plugin, CalendarInterface):
for calendar in calendars: for calendar in calendars:
if 'type' not in calendar: if 'type' not in calendar:
logging.warning("Invalid calendar with no type specified: {}".format(calendar)) self.logger.warning("Invalid calendar with no type specified: {}".format(calendar))
continue continue
cal_type = calendar.pop('type') cal_type = calendar.pop('type')

View File

@ -67,7 +67,7 @@ class IcalCalendarPlugin(Plugin, CalendarInterface):
or not only_participating): or not only_participating):
events.append(event) events.append(event)
else: else:
logging.error("HTTP error while getting {}: {}".format(self.url, response)) self.logger.error("HTTP error while getting {}: {}".format(self.url, response))
return Response(output=events) return Response(output=events)

View File

@ -1,5 +1,3 @@
import logging
from sqlalchemy import create_engine, Table, MetaData from sqlalchemy import create_engine, Table, MetaData
from platypush.message.response import Response from platypush.message.response import Response

View File

@ -1,5 +1,4 @@
import json import json
import logging
import requests import requests
from platypush.message.response import Response from platypush.message.response import Response
@ -30,7 +29,7 @@ class GoogleMapsPlugin(GooglePlugin):
if 'results' in response and response['results']: if 'results' in response and response['results']:
result = response['results'][0] result = response['results'][0]
logging.info('Google Maps geocode response for latlng ({},{}): {}'. self.logger.info('Google Maps geocode response for latlng ({},{}): {}'.
format(latitude, longitude, result)) format(latitude, longitude, result))
address['address'] = result['formatted_address'].split(',')[0] address['address'] = result['formatted_address'].split(',')[0]

View File

@ -1,4 +1,3 @@
import logging
import threading import threading
import time import time

View File

@ -1,4 +1,3 @@
import logging
import threading import threading
import time import time
@ -20,7 +19,7 @@ class GpioSensorDistancePlugin(GpioSensorPlugin):
gpio.setup(self.trigger_pin, gpio.OUT) gpio.setup(self.trigger_pin, gpio.OUT)
gpio.setup(self.echo_pin, gpio.IN) gpio.setup(self.echo_pin, gpio.IN)
logging.info('Resetting trigger sensor on GPIO pin {}'.format(self.trigger_pin)) self.logger.info('Resetting trigger sensor on GPIO pin {}'.format(self.trigger_pin))
gpio.output(self.trigger_pin, False) gpio.output(self.trigger_pin, False)
@ -40,7 +39,7 @@ class GpioSensorDistancePlugin(GpioSensorPlugin):
while gpio.input(self.echo_pin) == 0: while gpio.input(self.echo_pin) == 0:
pulse_on = time.time() pulse_on = time.time()
if pulse_on - pulse_start > 0.5: if pulse_on - pulse_start > 0.5:
logging.warning('Distance sensor echo timeout: 0') self.logger.warning('Distance sensor echo timeout: 0')
read_timeout = True read_timeout = True
break break
@ -51,7 +50,7 @@ class GpioSensorDistancePlugin(GpioSensorPlugin):
while gpio.input(self.echo_pin) == 1: while gpio.input(self.echo_pin) == 1:
pulse_off = time.time() pulse_off = time.time()
if pulse_off - pulse_end > 0.5: if pulse_off - pulse_end > 0.5:
logging.warning('Distance sensor echo timeout: 1') self.logger.warning('Distance sensor echo timeout: 1')
read_timeout = True read_timeout = True
break break

View File

@ -1,5 +1,4 @@
import enum import enum
import logging
import time import time
import Adafruit_GPIO.SPI as SPI import Adafruit_GPIO.SPI as SPI

View File

@ -1,5 +1,4 @@
import enum import enum
import logging
import threading import threading
import time import time
@ -68,7 +67,7 @@ class GpioZeroborgPlugin(Plugin):
elif 'below_threshold_direction' in sensor: elif 'below_threshold_direction' in sensor:
direction = sensor['below_threshold_direction'] direction = sensor['below_threshold_direction']
logging.info('Sensor: {}\tMeasurement: {}\tDirection: {}' self.logger.info('Sensor: {}\tMeasurement: {}\tDirection: {}'
.format(sensor['plugin'], value, direction)) .format(sensor['plugin'], value, direction))
return direction return direction
@ -79,7 +78,7 @@ class GpioZeroborgPlugin(Plugin):
self._can_run = True self._can_run = True
self._direction = direction.lower() self._direction = direction.lower()
logging.info('Received ZeroBorg drive command: {}'.format(direction)) self.logger.info('Received ZeroBorg drive command: {}'.format(direction))
def _run(): def _run():
while self._can_run and self._direction: while self._can_run and self._direction:
@ -108,7 +107,7 @@ class GpioZeroborgPlugin(Plugin):
motor_3_power = self.directions[self._direction]['motor_3_power'] motor_3_power = self.directions[self._direction]['motor_3_power']
motor_4_power = self.directions[self._direction]['motor_4_power'] motor_4_power = self.directions[self._direction]['motor_4_power']
elif self._direction: elif self._direction:
logging.warning('Invalid direction {}, stopping motors'.format(self._direction)) self.logger.warning('Invalid direction {}, stopping motors'.format(self._direction))
self.zb.SetMotor1(motor_1_power) self.zb.SetMotor1(motor_1_power)
self.zb.SetMotor2(motor_2_power) self.zb.SetMotor2(motor_2_power)

View File

@ -1,4 +1,3 @@
import logging
import time import time
from phue import Bridge from phue import Bridge
@ -26,7 +25,7 @@ class LightHuePlugin(LightPlugin):
self.bridge_address = bridge self.bridge_address = bridge
self.bridge = None self.bridge = None
logging.info('Initializing Hue lights plugin - bridge: "{}"'. self.logger.info('Initializing Hue lights plugin - bridge: "{}"'.
format(self.bridge_address)) format(self.bridge_address))
self.connect() self.connect()
@ -40,7 +39,7 @@ class LightHuePlugin(LightPlugin):
else: else:
self.lights = [l.name for l in self.bridge.lights] self.lights = [l.name for l in self.bridge.lights]
logging.info('Configured lights: "{}"'. format(self.lights)) self.logger.info('Configured lights: "{}"'. format(self.lights))
def _expand_groups(self): def _expand_groups(self):
groups = [g for g in self.bridge.groups if g.name in self.groups] groups = [g for g in self.bridge.groups if g.name in self.groups]
@ -51,7 +50,7 @@ class LightHuePlugin(LightPlugin):
# Lazy init # Lazy init
if not self.bridge: if not self.bridge:
self.bridge = Bridge(self.bridge_address) self.bridge = Bridge(self.bridge_address)
logging.info('Bridge connected') self.logger.info('Bridge connected')
self.get_scenes() self.get_scenes()
@ -61,7 +60,7 @@ class LightHuePlugin(LightPlugin):
# self.bridge.connect() # self.bridge.connect()
# self.bridge.get_api() # self.bridge.get_api()
else: else:
logging.info('Bridge already connected') self.logger.info('Bridge already connected')
def get_scenes(self): def get_scenes(self):

View File

@ -1,4 +1,3 @@
import logging
import rtmidi import rtmidi
import time import time
@ -24,10 +23,10 @@ class MidiPlugin(Plugin):
if available_ports: if available_ports:
self.midiout.open_port(0) self.midiout.open_port(0)
logging.info('Initialized MIDI plugin on port 0') self.logger.info('Initialized MIDI plugin on port 0')
else: else:
self.open_virtual_port(self.device_name) self.open_virtual_port(self.device_name)
logging.info('Initialized MIDI plugin on virtual device {}'. self.logger.info('Initialized MIDI plugin on virtual device {}'.
format(self.device_name)) format(self.device_name))

View File

@ -1,5 +1,3 @@
import logging
import paho.mqtt.publish as publisher import paho.mqtt.publish as publisher
from platypush.message.response import Response from platypush.message.response import Response

View File

@ -1,5 +1,3 @@
import logging
from redis import Redis from redis import Redis
from platypush.message.response import Response from platypush.message.response import Response

View File

@ -1,4 +1,3 @@
import logging
import struct import struct
import subprocess import subprocess
import time import time

View File

@ -1,4 +1,3 @@
import logging
import json import json
from ouimeaux.environment import Environment, UnknownDevice from ouimeaux.environment import Environment, UnknownDevice
@ -16,7 +15,7 @@ class SwitchWemoPlugin(SwitchPlugin):
self.refresh_devices() self.refresh_devices()
def refresh_devices(self): def refresh_devices(self):
logging.info('Starting WeMo discovery') self.logger.info('Starting WeMo discovery')
self.env.discover(seconds=self.discovery_seconds) self.env.discover(seconds=self.discovery_seconds)
self.devices = self.env.devices self.devices = self.env.devices
@ -42,7 +41,7 @@ class SwitchWemoPlugin(SwitchPlugin):
if device not in self.devices: if device not in self.devices:
raise RuntimeError('Device {} not found'.format(device)) raise RuntimeError('Device {} not found'.format(device))
logging.info('{} -> {}'.format(device, method)) self.logger.info('{} -> {}'.format(device, method))
dev = self.devices[device] dev = self.devices[device]
getattr(dev, method)(*args, **kwargs) getattr(dev, method)(*args, **kwargs)

View File

@ -1,5 +1,4 @@
import json import json
import logging
import os import os
import re import re
import subprocess import subprocess
@ -66,27 +65,27 @@ class VideoOmxplayerPlugin(Plugin):
resource = self.videos_queue.pop(0) resource = self.videos_queue.pop(0)
else: else:
error = 'Unable to download torrent {}'.format(resource) error = 'Unable to download torrent {}'.format(resource)
logging.warning(error) self.logger.warning(error)
return Response(errors=[error]) return Response(errors=[error])
logging.info('Playing {}'.format(resource)) self.logger.info('Playing {}'.format(resource))
if self.player: if self.player:
try: try:
self.player.stop() self.player.stop()
self.player = None self.player = None
except Exception as e: except Exception as e:
logging.exception(e) self.logger.exception(e)
logging.warning('Unable to stop a previously running instance ' + self.logger.warning('Unable to stop a previously running instance ' +
'of OMXPlayer, trying to play anyway') 'of OMXPlayer, trying to play anyway')
try: try:
self.player = OMXPlayer(resource, args=self.args) self.player = OMXPlayer(resource, args=self.args)
self._init_player_handlers() self._init_player_handlers()
except DBusException as e: except DBusException as e:
logging.warning('DBus connection failed: you will probably not ' + self.logger.warning('DBus connection failed: you will probably not ' +
'be able to control the media') 'be able to control the media')
logging.exception(e) self.logger.exception(e)
return self.status() return self.status()
@ -263,7 +262,7 @@ class VideoOmxplayerPlugin(Plugin):
query_tokens = [_.lower() for _ in re.split('\s+', query.strip())] query_tokens = [_.lower() for _ in re.split('\s+', query.strip())]
for media_dir in self.media_dirs: for media_dir in self.media_dirs:
logging.info('Scanning {} for "{}"'.format(media_dir, query)) self.logger.info('Scanning {} for "{}"'.format(media_dir, query))
for path, dirs, files in os.walk(media_dir): for path, dirs, files in os.walk(media_dir):
for f in files: for f in files:
if not self._is_video_file(f): if not self._is_video_file(f):
@ -286,7 +285,7 @@ class VideoOmxplayerPlugin(Plugin):
return Response(output=results) return Response(output=results)
def youtube_search(self, query): def youtube_search(self, query):
logging.info('Searching YouTube for "{}"'.format(query)) self.logger.info('Searching YouTube for "{}"'.format(query))
query = urllib.parse.quote(query) query = urllib.parse.quote(query)
url = "https://www.youtube.com/results?search_query=" + query url = "https://www.youtube.com/results?search_query=" + query
@ -306,7 +305,7 @@ class VideoOmxplayerPlugin(Plugin):
else: else:
html = '' html = ''
logging.info('{} YouTube video results for the search query "{}"' self.logger.info('{} YouTube video results for the search query "{}"'
.format(len(results), query)) .format(len(results), query))
return Response(output=results) return Response(output=results)
@ -323,7 +322,7 @@ class VideoOmxplayerPlugin(Plugin):
return proc.stdout.read().decode("utf-8", "strict")[:-1] return proc.stdout.read().decode("utf-8", "strict")[:-1]
def torrent_search(self, query): def torrent_search(self, query):
logging.info('Searching matching movie torrents for "{}"'.format(query)) self.logger.info('Searching matching movie torrents for "{}"'.format(query))
request = urllib.request.urlopen(urllib.request.Request( request = urllib.request.urlopen(urllib.request.Request(
'https://api.apidomain.info/list?' + urllib.parse.urlencode({ 'https://api.apidomain.info/list?' + urllib.parse.urlencode({
'sort': 'relevance', 'sort': 'relevance',
@ -358,7 +357,7 @@ class VideoOmxplayerPlugin(Plugin):
ses.listen_on(*self.torrent_ports) ses.listen_on(*self.torrent_ports)
info = lt.parse_magnet_uri(magnet) info = lt.parse_magnet_uri(magnet)
logging.info('Downloading "{}" to "{}" from [{}]' self.logger.info('Downloading "{}" to "{}" from [{}]'
.format(info['name'], self.download_dir, magnet)) .format(info['name'], self.download_dir, magnet))
params = { params = {
@ -392,7 +391,7 @@ class VideoOmxplayerPlugin(Plugin):
self.torrent_state['num_peers'] = status.num_peers self.torrent_state['num_peers'] = status.num_peers
self.torrent_state['state'] = status.state self.torrent_state['state'] = status.state
logging.info(('Torrent download: {:.2f}% complete (down: {:.1f} kb/s ' + self.logger.info(('Torrent download: {:.2f}% complete (down: {:.1f} kb/s ' +
'up: {:.1f} kB/s peers: {} state: {})') 'up: {:.1f} kB/s peers: {} state: {})')
.format(status.progress * 100, .format(status.progress * 100,
status.download_rate / 1000, status.download_rate / 1000,

View File

@ -1,4 +1,3 @@
import logging
import json import json
import urllib3 import urllib3
import urllib.request import urllib.request
@ -62,12 +61,12 @@ class VideoTorrentcastPlugin(Plugin):
def search_and_play(self, query): def search_and_play(self, query):
response = self.search(query) response = self.search(query)
if not response.output['MovieList']: if not response.output['MovieList']:
logging.info('No torrent results found for {}'.format(query)) self.logger.info('No torrent results found for {}'.format(query))
return Response() return Response()
item = response.output['MovieList'][0] item = response.output['MovieList'][0]
magnet = item['items'][0]['torrent_magnet'] magnet = item['items'][0]['torrent_magnet']
logging.info('Playing torrent "{}" from {}' self.logger.info('Playing torrent "{}" from {}'
.format(item['title'], magnet)) .format(item['title'], magnet))
return self.play(magnet) return self.play(magnet)

View File

@ -5,6 +5,9 @@ from ..config import Config
from ..message.request import Request from ..message.request import Request
from ..message.response import Response from ..message.response import Response
logger = logging.getLogger(__name__)
class Procedure(object): class Procedure(object):
""" Procedure class. A procedure is a pre-configured list of requests """ """ Procedure class. A procedure is a pre-configured list of requests """
@ -94,7 +97,7 @@ class Procedure(object):
n_tries -- Number of tries in case of failure before raising a RuntimeError n_tries -- Number of tries in case of failure before raising a RuntimeError
""" """
logging.info('Executing request {}'.format(self.name)) logger.info('Executing request {}'.format(self.name))
response = Response() response = Response()
for request in self.requests: for request in self.requests:

View File

@ -4,6 +4,7 @@ import logging
import os import os
import signal import signal
logger = logging.getLogger(__name__)
def get_module_and_method_from_action(action): def get_module_and_method_from_action(action):
""" Input : action=music.mpd.play """ Input : action=music.mpd.play
@ -21,7 +22,7 @@ def get_message_class_by_type(msgtype):
try: try:
module = importlib.import_module('platypush.message.' + msgtype) module = importlib.import_module('platypush.message.' + msgtype)
except ImportError as e: except ImportError as e:
logging.warning('Unsupported message type {}'.format(msgtype)) logger.warning('Unsupported message type {}'.format(msgtype))
raise RuntimeError(e) raise RuntimeError(e)
cls_name = msgtype[0].upper() + msgtype[1:] cls_name = msgtype[0].upper() + msgtype[1:]
@ -29,7 +30,7 @@ def get_message_class_by_type(msgtype):
try: try:
msgclass = getattr(module, cls_name) msgclass = getattr(module, cls_name)
except AttributeError as e: except AttributeError as e:
logging.warning('No such class in {}: {}'.format( logger.warning('No such class in {}: {}'.format(
module.__name__, cls_name)) module.__name__, cls_name))
raise RuntimeError(e) raise RuntimeError(e)