diff --git a/main.py b/main.py
index adef5ad15e9da4c82a0dfbfaa86c09aa299f59f2..1da11b3f59f687c1cc3046c9d3e55977d2a04f25 100644
--- a/main.py
+++ b/main.py
@@ -7,6 +7,7 @@ import base64
 import flask
 import yaml
 import sys
+import logging
 
 import dash
 from dash import dcc
@@ -482,7 +483,7 @@ def append_to_mqtt_log(_n_intervals, clear_n_clicks, filter_options, topics_to_f
                 topic_match, topic = utils.topic_match(topics_to_filter, msg)
                 if topic == svg_image_topic:
                     new_svg_img_src = '/static/' + utils.parse_log_msg(msg)[2]
-                    print('found new svg: ' + new_svg_img_src)
+                    logging.info('found new svg: %s', new_svg_img_src)
                 if topic not in (option['label'] for option in filter_options):
                     filter_options.append({'label': topic, 'value': topic})
                     if topic in topics_enabled_once_seen:
@@ -557,7 +558,7 @@ def update_svg_name(name):
 def serve_image(image_path):
     image_name = '{}.svg'.format(image_path)
     image_directory = config['image_directory']
-    print('{}/{}'.format(image_directory, image_name))
+    logging.debug('%s/%s', image_directory, image_name)
     # if image_name not in list_of_images:
     #     raise Exception('"{}" is excluded from the allowed static files'.format(image_path))
     return flask.send_from_directory(image_directory, image_name)
@@ -565,14 +566,14 @@ def serve_image(image_path):
 
 def on_mqtt_connect(_client, _userdata, _flags, _rc, _properties=None):
     # Callback for mqtt client when connected
-    print(f'\nConnected to {config["mqtt_server"]} at {datetime.datetime.now().isoformat()}')
+    logging.info('Connected to %s at %s', config["mqtt_server"], datetime.datetime.now().isoformat())
     ready_event.set()
     mqttc.subscribe(topic='#')
     threading.Thread(target=publish_test_message).start()
 
 
 def on_mqtt_disconnect(_client, _userdata, _rc):
-    print('Lost connection at ' + datetime.datetime.now().isoformat())
+    logging.info('Lost connection at %s', datetime.datetime.now().isoformat())
     ready_event.clear()
 
 
@@ -608,17 +609,27 @@ def publish_test_message():
 
 
 if __name__ == '__main__':
-    print('Starting web-ros3rag')
+    logging.basicConfig(level='DEBUG',
+                        format='%(asctime)-15s %(levelname)-8s %(message)s',
+                        handlers=[
+                            logging.StreamHandler()
+                        ])
+
+    # silence logger of webserver
+    log_werkzeug = logging.getLogger('werkzeug')
+    log_werkzeug.setLevel(logging.ERROR)
+
+    logging.info('Starting web-ros3rag')
 
     try:
         with open(CONFIG_FILENAME, 'r') as fd:
             config = yaml.safe_load(fd)
     except FileNotFoundError as e:
-        print(f'Could not open {CONFIG_FILENAME}. Aborting.')
+        logging.error('Could not open %s. Aborting.', CONFIG_FILENAME)
         sys.exit(1)
 
     if not config['image_directory']:
-        print('image_directory not specified. Aborting.')
+        logging.error('image_directory not specified. Aborting.')
         sys.exit(1)
 
     dockerized = config.get('docker')
@@ -630,7 +641,7 @@ if __name__ == '__main__':
     mqttc.connect_async(config['mqtt_server'])
     mqttc.loop_start()
     if not ready_event.wait(2.0):  # wait 2 seconds
-        print(f'Could not connect to mqtt at {config["mqtt_server"]} in time!')
+        logging.warning('Could not connect to mqtt at %s in time!', config["mqtt_server"])
 
     if dockerized:
         app.run_server(host='0.0.0.0', port=8050)