diff options
author | Trygve Aaberge <trygveaa@gmail.com> | 2023-10-15 15:35:26 +0200 |
---|---|---|
committer | Trygve Aaberge <trygveaa@gmail.com> | 2024-02-18 11:32:54 +0100 |
commit | 094868a40f22aa09b412ef8db4ea2eb885433e0c (patch) | |
tree | 5bcdcb86756d2dd4dd32d35737c922f6da12be11 | |
parent | f8fc75bc34565364591515eb8c87cacc8ddeb35f (diff) | |
download | wee-slack-094868a40f22aa09b412ef8db4ea2eb885433e0c.tar.gz |
Use one debug buffer for all debug logging
I will implement filtering like the /server raw buffer, instead of
having multiple debug buffers.
-rw-r--r-- | slack/commands.py | 10 | ||||
-rw-r--r-- | slack/http.py | 12 | ||||
-rw-r--r-- | slack/log.py | 63 | ||||
-rw-r--r-- | slack/shared.py | 3 | ||||
-rw-r--r-- | slack/slack_workspace.py | 47 |
5 files changed, 79 insertions, 56 deletions
diff --git a/slack/commands.py b/slack/commands.py index 476c4ba..67c214a 100644 --- a/slack/commands.py +++ b/slack/commands.py @@ -10,7 +10,7 @@ from typing import Callable, Dict, List, Optional, Tuple import weechat from slack.error import SlackError, SlackRtmError, UncaughtError -from slack.log import print_error +from slack.log import open_debug_buffer, print_error from slack.python_compatibility import format_exception, removeprefix, removesuffix from slack.shared import shared from slack.slack_buffer import SlackBuffer @@ -297,7 +297,7 @@ def print_uncaught_error( print_error("This error does not have any data") -@weechat_command("tasks|buffer|open_ws_buffer|errors|error", split_all_args=True) +@weechat_command("tasks|buffer|open_buffer|errors|error", split_all_args=True) def command_slack_debug( buffer: str, args: List[str], options: Dict[str, Optional[str]] ): @@ -316,10 +316,8 @@ def command_slack_debug( "", f"Conversation id: {slack_buffer.parent.conversation.id}, Thread ts: {slack_buffer.parent.thread_ts}, Thread hash: {slack_buffer.parent.hash}", ) - elif args[0] == "open_ws_buffer": - slack_buffer = shared.buffers.get(buffer) - if slack_buffer: - slack_buffer.workspace.open_debug_ws_buffer() + elif args[0] == "open_buffer": + open_debug_buffer() elif args[0] == "errors": num_arg = int(args[1]) if len(args) > 1 and args[1].isdecimal() else 5 num = min(num_arg, len(shared.uncaught_errors)) diff --git a/slack/http.py b/slack/http.py index 85c9be3..f4e70ab 100644 --- a/slack/http.py +++ b/slack/http.py @@ -8,7 +8,7 @@ from typing import Dict, Tuple import weechat from slack.error import HttpError -from slack.log import LogLevel, log +from slack.log import DebugMessageType, LogLevel, log from slack.task import FutureProcess, FutureUrl, sleep, weechat_task_cb from slack.util import get_callback_name @@ -25,6 +25,7 @@ async def hook_process_hashtable( future = FutureProcess() log( LogLevel.DEBUG, + DebugMessageType.LOG, f"hook_process_hashtable calling ({future.id}): command: {command}", ) while available_file_descriptors() < 10: @@ -42,6 +43,7 @@ async def hook_process_hashtable( _, return_code, out, err = await next_future log( LogLevel.TRACE, + DebugMessageType.LOG, f"hook_process_hashtable intermediary response ({next_future.id}): command: {command}", ) stdout.write(out) @@ -51,6 +53,7 @@ async def hook_process_hashtable( err = stderr.getvalue().strip() log( LogLevel.DEBUG, + DebugMessageType.LOG, f"hook_process_hashtable response ({future.id}): command: {command}, " f"return_code: {return_code}, response length: {len(out)}" + (f", error: {err}" if err else ""), @@ -111,6 +114,11 @@ async def http_request_url( async def http_request( url: str, options: Dict[str, str], timeout: int, max_retries: int = 5 ) -> str: + log( + LogLevel.DEBUG, + DebugMessageType.HTTP_REQUEST, + f"requesting: {url}, {options.get('postfields')}", + ) try: if hasattr(weechat, "hook_url"): http_status, headers, body = await http_request_url(url, options, timeout) @@ -122,6 +130,7 @@ async def http_request( if max_retries > 0: log( LogLevel.INFO, + DebugMessageType.LOG, f"HTTP error, retrying (max {max_retries} times): " f"return_code: {e.return_code}, error: {e.error}, url: {url}", ) @@ -137,6 +146,7 @@ async def http_request( retry_after = int(value.strip()) log( LogLevel.INFO, + DebugMessageType.LOG, f"HTTP ratelimit, retrying in {retry_after} seconds, url: {url}", ) await sleep(retry_after * 1000) diff --git a/slack/log.py b/slack/log.py index 4b8bbe1..9abc1ad 100644 --- a/slack/log.py +++ b/slack/log.py @@ -1,14 +1,15 @@ from __future__ import annotations +import time +from dataclasses import dataclass from enum import IntEnum -from typing import Set +from typing import List, Set import weechat from slack.error import store_and_format_exception from slack.shared import shared - -printed_exceptions: Set[BaseException] = set() +from slack.util import get_callback_name class LogLevel(IntEnum): @@ -20,6 +21,25 @@ class LogLevel(IntEnum): FATAL = 6 +class DebugMessageType(IntEnum): + WEBSOCKET_SEND = 1 + WEBSOCKET_RECV = 2 + HTTP_REQUEST = 3 + LOG = 4 + + +@dataclass +class DebugMessage: + time: float + level: LogLevel + message_type: DebugMessageType + message: str + + +debug_messages: List[DebugMessage] = [] +printed_exceptions: Set[BaseException] = set() + + # TODO: Figure out what to do with print_error vs log def print_error(message: str): weechat.prnt("", f"{weechat.prefix('error')}{shared.SCRIPT_NAME}: {message}") @@ -31,7 +51,42 @@ def print_exception_once(e: BaseException): printed_exceptions.add(e) -def log(level: LogLevel, message: str): +def log(level: LogLevel, message_type: DebugMessageType, message: str): if level >= LogLevel.INFO: prefix = weechat.prefix("error") if level >= LogLevel.ERROR else "\t" weechat.prnt("", f"{prefix}{shared.SCRIPT_NAME} {level.name}: {message}") + + debug_message = DebugMessage(time.time(), level, message_type, message) + debug_messages.append(debug_message) + print_debug_buffer(debug_message) + + +def _close_debug_buffer_cb(data: str, buffer: str): + shared.debug_buffer_pointer = None + return weechat.WEECHAT_RC_OK + + +def open_debug_buffer(): + if shared.debug_buffer_pointer: + weechat.buffer_set(shared.debug_buffer_pointer, "display", "1") + return + + name = f"{shared.SCRIPT_NAME}.debug" + shared.debug_buffer_pointer = weechat.buffer_new_props( + name, + {"display": "1"}, + "", + "", + get_callback_name(_close_debug_buffer_cb), + "", + ) + for message in debug_messages: + print_debug_buffer(message) + + +def print_debug_buffer(debug_message: DebugMessage): + if shared.debug_buffer_pointer: + message = f"{debug_message.level.name} - {debug_message.message_type.name}\t{debug_message.message}" + weechat.prnt_date_tags( + shared.debug_buffer_pointer, int(debug_message.time), "", message + ) diff --git a/slack/shared.py b/slack/shared.py index 32bad27..0e278ca 100644 --- a/slack/shared.py +++ b/slack/shared.py @@ -1,7 +1,7 @@ from __future__ import annotations from collections import defaultdict -from typing import TYPE_CHECKING, Callable, Dict, List, Union +from typing import TYPE_CHECKING, Callable, Dict, List, Optional, Union if TYPE_CHECKING: from slack.config import SlackConfig @@ -31,6 +31,7 @@ class Shared: self.standard_emojis: Dict[str, Emoji] self.standard_emojis_inverse: Dict[str, Emoji] self.highlight_tag = "highlight" + self.debug_buffer_pointer: Optional[str] = None shared = Shared() diff --git a/slack/slack_workspace.py b/slack/slack_workspace.py index 0f9ddfb..d059b04 100644 --- a/slack/slack_workspace.py +++ b/slack/slack_workspace.py @@ -5,18 +5,7 @@ import socket import ssl import time from abc import ABC, abstractmethod -from typing import ( - TYPE_CHECKING, - Dict, - Generic, - Iterable, - List, - Optional, - Set, - Tuple, - Type, - TypeVar, -) +from typing import TYPE_CHECKING, Dict, Generic, Iterable, Optional, Set, Type, TypeVar import weechat from websocket import ( @@ -32,7 +21,7 @@ from slack.error import ( SlackRtmError, store_and_format_exception, ) -from slack.log import print_error +from slack.log import DebugMessageType, LogLevel, log, print_error from slack.proxy import Proxy from slack.shared import shared from slack.slack_api import SlackApi @@ -187,7 +176,6 @@ class SlackWorkspace: self._connect_task: Optional[Task[None]] = None self._ws: Optional[WebSocket] = None self._hook_ws_fd: Optional[str] = None - self._ws_messages: List[Tuple[float, SlackRtmMessage]] = [] self._debug_ws_buffer_pointer: Optional[str] = None self.conversations = SlackConversations(self) self.open_conversations: Dict[str, SlackConversation] = {} @@ -329,10 +317,8 @@ class SlackWorkspace: run_async(self._ws_recv(json.loads(recv_data.decode()))) async def _ws_recv(self, data: SlackRtmMessage): - epoch = time.time() # TODO: Remove old messages - self._ws_messages.append((epoch, data)) - self.print_debug_ws_buffer(epoch, data) + log(LogLevel.DEBUG, DebugMessageType.WEBSOCKET_RECV, json.dumps(data)) try: if data["type"] == "hello": @@ -453,33 +439,6 @@ class SlackWorkspace: msg["thread_ts"] = buffer.parent.ts self._ws.send(json.dumps(msg)) - def _close_debug_ws_buffer_cb(self, data: str, buffer: str): - self._debug_ws_buffer_pointer = None - return weechat.WEECHAT_RC_OK - - def open_debug_ws_buffer(self): - if self._debug_ws_buffer_pointer: - weechat.buffer_set(self._debug_ws_buffer_pointer, "display", "1") - return - - name = f"{shared.SCRIPT_NAME}.debug.ws.{self.name}" - self._debug_ws_buffer_pointer = weechat.buffer_new_props( - name, - {"display": "1"}, - "", - "", - get_callback_name(self._close_debug_ws_buffer_cb), - "", - ) - for epoch, message in self._ws_messages: - self.print_debug_ws_buffer(epoch, message) - - def print_debug_ws_buffer(self, epoch: float, message: SlackRtmMessage): - if self._debug_ws_buffer_pointer: - weechat.prnt_date_tags( - self._debug_ws_buffer_pointer, int(epoch), "", json.dumps(message) - ) - async def reconnect(self): self.disconnect() await self.connect() |