diff --git a/cutelog/serial.py b/cutelog/serial.py
index 4f2d46c28e5105593ea88df851623e57d448419f..4a228de5ac7d9f5a577508a7e14163fb95167be2 100644
--- a/cutelog/serial.py
+++ b/cutelog/serial.py
@@ -2,7 +2,8 @@ import serial
 import pickle
 import struct
 import re
-import sys
+import logging
+import time
 from datetime import datetime
 
 from qtpy.QtCore import QThread, Signal
@@ -10,93 +11,146 @@ from qtpy.QtNetwork import QHostAddress, QTcpSocket
 
 from .config import CONFIG
 
+
 class SerialConnection(QThread):
     disconnected = False
-    re_line = re.compile(r"(?P<tsmin>\d{2,}):(?P<tssec>\d{2}.\d{3}) (?P<file>[\dA-Za-z/_\-.]+):(?P<line>\d+) (?P<func>[\dA-Za-z/_\-\.]+) (?P<level>[A-Za-z\d]+) \[(?P<name>[\dA-Za-z/_\-.]+)\] (?P<msg>.*)")
+    crit_words = ["fault"]
+    warn_words = ["miosix v"]
+    ser = None
+
+    logger = logging.getLogger("SerialConn")
+    # logging.Formatter("{message}", style='{')
+
+    re_line = re.compile(
+        r"(?P<tsmin>\d{2,}):(?P<tssec>\d{2}.\d{3}) (?P<file>[\dA-Za-z/_\-.]+):"
+        r"(?P<line>\d+) (?P<func>[\dA-Za-z/_\-\.]+) (?P<level>[A-Za-z\d]+) "
+        r"\[(?P<name>[\dA-Za-z/_\-.]+)\] (?P<msg>.*)"
+    )
 
     def __init__(self, parent, port, baud):
         super().__init__(parent)
-        print("Opening serial port {}:{}".format(port, baud))
+        self.logger.info("Opening serial port {}:{}".format(port, baud))
+
+        self.port = port
+        self.baud = baud
 
-        self.ser = serial.Serial(port, baud, timeout=1)
         _, self.tcp_port = CONFIG.listen_address
         self.tcp_host = QHostAddress("127.0.0.1")
-        
+
         self.start()
-        print("thread started")
+        self.logger.debug("thread started")
 
     def onDisconnect(self):
-        disconnect = True
-        print("on disconnect")
+        self.disconnected = True
+        self.logger.debug("on disconnect")
+
+    def readSerial(self):
+        try:
+            logline = self.ser.readline().decode("ascii").strip("\n\r")
+            if len(logline) > 2:
+                return logline
+            else:
+                self.logger.debug("Ignored line as it is too short: '{}'".format(logline))
+                return ""
+        except serial.SerialException as err:
+            self.logger.error(err.strerror)
+            return None
+        except Exception as err:
+            self.logger.error(err.strerror)
+            return ""
+
+    def forwardLog(self, sock, logline: str):
+        match = self.re_line.fullmatch(logline)
+
+        if match is None:
+            level = logging.DEBUG
+            for s in self.warn_words:
+                if logline.lower().find(s) > -1:
+                    level = logging.WARNING
+                    break
+            for s in self.crit_words:
+                if logline.lower().find(s) > -1:
+                    level = logging.CRITICAL
+                    break
+
+            d = {
+                "args": None,
+                "created": datetime.now().timestamp(),
+                "exc_info": None,
+                "filename": "",
+                "funcName": "",
+                "levelname": logging.getLevelName(level),
+                "levelno": level,
+                "lineno": 0,
+                "module": "",
+                "msecs": 0,
+                "msg": logline,
+                "name": "raw_serial",
+                "pathname": "",
+                "process": 0,
+                "processName": "",
+                "relativeCreated": 0,
+                "stack_info": None,
+                "thread": 0,
+                "threadName": "",
+                "extra_column": "",
+            }
+        else:
+            d = {
+                "args": None,
+                "created": int(match.group("tsmin")) * 60 * 1000 + float(match.group("tssec")) * 1000,
+                "exc_info": None,
+                "filename": match.group("file"),
+                "funcName": match.group("func"),
+                "levelname": match.group("level"),
+                "levelno": 10,
+                "lineno": match.group("line"),
+                "module": "serial",
+                "msecs": 0,
+                "msg": match.group("msg"),
+                "name": match.group("name"),
+                "pathname": match.group("file"),
+                "process": 0,
+                "processName": "",
+                "relativeCreated": 0,
+                "stack_info": None,
+                "thread": 0,
+                "threadName": "",
+                "extra_column": "",
+            }
+
+        s = pickle.dumps(d)
+
+        sock.write(struct.pack(">L", len(s)))
+        sock.write(s)
+        sock.flush()
 
     def run(self):
         sock = QTcpSocket(None)
         sock.connectToHost(self.tcp_host, self.tcp_port)
         sock.disconnected.connect(self.onDisconnect)
+
         if not sock.waitForConnected():
-            print("Socket error!")
-            print(sock.errorString())
+            self.logger.error("Socket error! {}".format(sock.errorString()))
             return
-        
-        if self.ser is None:
-            print("Error opening serial port")
-            return
-        
-        while True:
-            logline = self.ser.readline().decode("utf-8").strip("\n\r")
-                
-            match = self.re_line.fullmatch(logline)
-
-            if match is None:
-                d = {'args': None,
-                    'created': datetime.now().timestamp(),
-                    'exc_info': None,
-                    'filename': '',
-                    'funcName': '',
-                    'levelname': 'DEBUG',
-                    'levelno': 0,
-                    'lineno': 0,
-                    'module': '',
-                    'msecs': 0,
-                    'msg': logline,
-                    'name': 'raw_serial',
-                    'pathname': '',
-                    'process': 0,
-                    'processName': '',
-                    'relativeCreated': 0,
-                    'stack_info': None,
-                    'thread': 0,
-                    'threadName': '',
-                    'extra_column': ''}
-            else:         
-                d = {'args': None,
-                    'created': int(match.group('tsmin'))*60*1000 + float(match.group('tssec'))*1000,
-                    'exc_info': None,
-                    'filename': match.group('file'),
-                    'funcName': match.group('func'),
-                    'levelname': match.group('level'),
-                    'levelno': 10,
-                    'lineno': match.group('line'),
-                    'module': 'serial',
-                    'msecs': 0,
-                    'msg': match.group('msg'),
-                    'name': match.group('name'),
-                    'pathname': match.group('file'),
-                    'process': 0,
-                    'processName': '',
-                    'relativeCreated': 0,
-                    'stack_info': None,
-                    'thread': 0,
-                    'threadName': '',
-                    'extra_column': ''}
-            
-            s = pickle.dumps(d)
-
-            sock.write(struct.pack(">L", len(s)))
-            sock.write(s)
-            sock.flush()
 
+        while True:
+            if self.ser is not None:
+                logline = self.readSerial()
+                if logline is None:
+                    self.logger.error("Serial port error")
+                    self.ser.close()
+                    self.ser = None
+                elif len(logline) > 0:
+                    self.forwardLog(sock, logline)
+            else:
+                try:
+                    self.ser = serial.Serial(self.port, self.baud, timeout=1)
+                except serial.SerialException as err:
+                    time.sleep(1)
+                    self.logger.error(str(err))
+      
             if sock.state() != QTcpSocket.SocketState.ConnectedState:
-                print("thread stop")
+                self.logger.debug("thread stop")
                 self.ser.close()
-                break
\ No newline at end of file
+                break