class _ClientDb(_Db, IrcConnSetup):
+    connection_state: str
     client_host: str
     nickname_confirmed: bool
     user_modes: str
             except Exception as e:  # pylint: disable=broad-exception-caught
                 self._put(ExceptionEvent(CrashingException(e)))
 
-        self._log('connecting …')
+        self._db.connection_state = 'connecting'
         Thread(target=connect, daemon=True, args=(self,)).start()
 
     @abstractmethod
 
     def _on_connect(self) -> None:
         assert self.conn is not None
-        self._log('connected to server (SSL: '
-                  f'{"yes" if self.conn.ssl else "no"})',
-                  scope=LogScope.ALL)
+        self._db.connection_state = 'connected'
         self._caps.start_negotation()
         self.send(IrcMessage(verb='USER',
                              params=(getuser(), '0', '*', self._db.realname)))
 
     def close(self) -> None:
         'Close both recv Loop and socket.'
-        self._log(msg='disconnecting from server …', scope=LogScope.ALL)
+        self._db.connection_state = 'disconnected'
         if self.conn:
             self.conn.close()
         self.conn = None
 
 class _TuiClientDb(_Db, IrcConnSetup):
     caps: tuple[str]
     client_host: str
+    connection_state: str
     isupports: tuple[str]
     motd: tuple[str]
     nickname_confirmed: bool
             db = self._db.chan(chan_name)
             scope = LogScope.CHAT
             log_kwargs |= {'channel': chan_name}
+        elif key == 'connection_state':
+            scope = LogScope.ALL
         if not db.set_and_check_for_change(key, value):
             return False
         if key != CLEAR_WORD: