Skip to content

Commit b63737a

Browse files
author
Tony Crisci
committed
add logging to aio connection
1 parent 25c913c commit b63737a

File tree

1 file changed

+56
-17
lines changed

1 file changed

+56
-17
lines changed

i3ipc/aio/connection.py

Lines changed: 56 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
from Xlib.error import DisplayError
1212
import struct
1313
import socket
14+
import logging
1415

1516
import asyncio
1617
from asyncio.subprocess import PIPE
@@ -22,6 +23,7 @@
2223
_struct_header = f'={len(_MAGIC)}sII'
2324
_struct_header_size = struct.calcsize(_struct_header)
2425

26+
logger = logging.getLogger(__name__)
2527

2628
class _AIOPubSub(PubSub):
2729
def queue_handler(self, handler, data=None):
@@ -173,16 +175,23 @@ async def _find_socket_path() -> Optional[str]:
173175
def exists(path):
174176
if not path:
175177
return False
176-
return os.path.exists(path)
178+
result = os.path.exists(path)
179+
if not result:
180+
logger.info('file not found: %s', socket_path)
181+
return result
177182

178183
# first try environment variables
179184
socket_path = os.environ.get('I3SOCK')
180-
if exists(socket_path):
181-
return socket_path
185+
if socket_path:
186+
logger.info('got socket path from I3SOCK env variable: %s', socket_path)
187+
if exists(socket_path):
188+
return socket_path
182189

183190
socket_path = os.environ.get('SWAYSOCK')
184-
if exists(socket_path):
185-
return socket_path
191+
if socket_path:
192+
logger.info('got socket path from SWAYSOCK env variable: %s', socket_path)
193+
if exists(socket_path):
194+
return socket_path
186195

187196
# next try the root window property
188197
try:
@@ -192,11 +201,14 @@ def exists(path):
192201
prop = root.get_full_property(atom, X.AnyPropertyType)
193202
if prop and prop.value:
194203
socket_path = prop.value.decode()
195-
except DisplayError:
204+
except DisplayError as e:
205+
logger.info('could not get i3 socket path from root atom', exc_info=e)
196206
pass
197207

198-
if exists(socket_path):
199-
return socket_path
208+
if socket_path:
209+
logger.info('got socket path from root atom: %s', socket_path)
210+
if exists(socket_path):
211+
return socket_path
200212

201213
# finally try the binaries
202214
for binary in ('i3', 'sway'):
@@ -205,17 +217,23 @@ def exists(path):
205217
'--get-socketpath',
206218
stdout=PIPE,
207219
stderr=PIPE)
208-
except Exception:
209-
continue
210220

211-
stdout, stderr = await process.communicate()
221+
stdout, stderr = await process.communicate()
222+
223+
if process.returncode == 0 and stdout:
224+
socket_path = stdout.decode().strip()
225+
if socket_path:
226+
logger.info('got socket path from `%s` binary: %s', binary, socket_path)
227+
if exists(socket_path):
228+
return socket_path
229+
else:
230+
logger.info('could not get socket path from `%s` binary: returncode=%d, stdout=%s, stderr=%s', process.returncode, stdout, stderr)
212231

213-
if process.returncode == 0 and stdout:
214-
socket_path = stdout.decode().strip()
215-
if exists(socket_path):
216-
return socket_path
232+
except Exception as e:
233+
logger.info('could not get i3 socket path from `%s` binary', binary, exc_info=e)
234+
continue
217235

218-
# could not find the socket path
236+
logger.info('could not find i3 socket path')
219237
return None
220238

221239

@@ -298,6 +316,7 @@ def _read_message(self):
298316
self._loop.remove_reader(self._sub_fd)
299317

300318
if self._auto_reconnect:
319+
logger.info('could not read message, reconnecting', exc_info=error)
301320
asyncio.ensure_future(self._reconnect())
302321
else:
303322
if error is not None:
@@ -309,14 +328,16 @@ def _read_message(self):
309328

310329
magic, message_length, event_type = _unpack_header(buf)
311330
assert magic == _MAGIC
312-
message = json.loads(self._sub_socket.recv(message_length))
331+
raw_message = self._sub_socket.recv(message_length)
332+
message = json.loads(raw_message)
313333

314334
# events have the highest bit set
315335
if not event_type & (1 << 31):
316336
# a reply
317337
return
318338

319339
event_type = EventType(1 << (event_type & 0x7f))
340+
logger.info('got message on subscription socket: type=%s, message=%s', event_type, raw_message)
320341

321342
if event_type == EventType.WORKSPACE:
322343
event = WorkspaceEvent(message, self, _Con=Con)
@@ -349,6 +370,9 @@ async def connect(self) -> 'Connection':
349370
:returns: The ``Connection``.
350371
:rtype: :class:`~.Connection`
351372
"""
373+
if self._socket_path:
374+
logger.info('using user provided socket path: {}', self._socket_path)
375+
352376
if not self._socket_path:
353377
self._socket_path = await _find_socket_path()
354378

@@ -402,6 +426,8 @@ async def _message(self, message_type: MessageType, payload: str = '') -> bytes:
402426
if message_type is MessageType.SUBSCRIBE:
403427
raise Exception('cannot subscribe on the command socket')
404428

429+
logger.info('sending message: type=%s, payload=%s', message_type, payload)
430+
405431
for tries in range(0, 5):
406432
try:
407433
await self._loop.sock_sendall(self._cmd_socket, _pack(message_type, payload))
@@ -411,6 +437,7 @@ async def _message(self, message_type: MessageType, payload: str = '') -> bytes:
411437
if not self._auto_reconnect:
412438
raise e
413439

440+
logger.info('got connection error, attempting to reconnect', exc_info=e)
414441
await self._reconnect()
415442

416443
if not buf:
@@ -427,6 +454,7 @@ async def _message(self, message_type: MessageType, payload: str = '') -> bytes:
427454
asyncio.ensure_future(self._reconnect())
428455
raise e
429456

457+
logger.info('got message reply: %s', message)
430458
return message
431459

432460
async def subscribe(self, events: Union[List[Event], List[str]], force: bool = False):
@@ -458,15 +486,21 @@ async def subscribe(self, events: Union[List[Event], List[str]], force: bool = F
458486
f'only nondetailed events are subscribable (use Event.{correct_event})')
459487
subscriptions.add(e)
460488

489+
logger.info('subscribing to events: %s', subscriptions)
490+
logger.info('current subscriptions: %s', self._subscriptions)
491+
461492
if not force:
462493
subscriptions = subscriptions.difference(self._subscriptions)
463494
if not subscriptions:
495+
logger.info('no new subscriptions')
464496
return
465497

466498
self._subscriptions.update(subscriptions)
467499

468500
payload = json.dumps([s.value for s in subscriptions])
469501

502+
logger.info('sending SUBSCRIBE message with payload: %s', payload)
503+
470504
await self._loop.sock_sendall(self._sub_socket, _pack(MessageType.SUBSCRIBE, payload))
471505

472506
def on(self, event: Union[Event, str], handler: Callable[['Connection', IpcBaseEvent], None]):
@@ -488,6 +522,8 @@ def on(self, event: Union[Event, str], handler: Callable[['Connection', IpcBaseE
488522
else:
489523
base_event = event
490524

525+
logger.info('adding event handler: event=%s, handler=%s', event, handler)
526+
491527
self._pubsub.subscribe(event, handler)
492528
asyncio.ensure_future(self.subscribe([base_event]))
493529

@@ -498,6 +534,7 @@ def off(self, handler: Callable[['Connection', IpcBaseEvent], None]):
498534
:func:`on()`.
499535
:type handler: :class:`Callable`
500536
"""
537+
logger.info('removing event handler: handler=%s', handler)
501538
self._pubsub.unsubscribe(handler)
502539

503540
async def command(self, cmd: str) -> List[CommandReply]:
@@ -648,6 +685,7 @@ async def get_seats(self) -> List[SeatReply]:
648685

649686
def main_quit(self, _error=None):
650687
"""Quits the running main loop for this connection."""
688+
logger.info('quitting the main loop', exc_info=_error)
651689
if self._main_future is not None:
652690
if _error:
653691
self._main_future.set_exception(_error)
@@ -660,5 +698,6 @@ async def main(self):
660698
"""Starts the main loop for this connection to start handling events."""
661699
if self._main_future is not None:
662700
raise Exception('the main loop is already running')
701+
logger.info('starting the main loop')
663702
self._main_future = self._loop.create_future()
664703
await self._main_future

0 commit comments

Comments
 (0)