Skip to content

Commit

Permalink
Merge pull request #309 from nlef/logs-uploading
Browse files Browse the repository at this point in the history
add upload_logs command
  • Loading branch information
nlef authored Mar 15, 2024
2 parents 6601fdf + f1d9e15 commit ef83981
Show file tree
Hide file tree
Showing 4 changed files with 99 additions and 14 deletions.
97 changes: 87 additions & 10 deletions bot/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import re
import signal
import socket
import subprocess
import sys
import tarfile
import time
Expand All @@ -19,6 +20,7 @@
from apscheduler.events import EVENT_JOB_ERROR # type: ignore
from apscheduler.schedulers.background import BackgroundScheduler # type: ignore
import emoji
import requests
import telegram
from telegram import (
BotCommand,
Expand Down Expand Up @@ -324,25 +326,98 @@ def send_logs(update: Update, _: CallbackContext) -> None:
update.effective_message.bot.send_chat_action(chat_id=configWrap.secrets.chat_id, action=ChatAction.UPLOAD_DOCUMENT)
update.effective_message.reply_text(text=klippy.get_versions_info(), disable_notification=notifier.silent_commands, quote=True)
logs_list: List[Union[InputMediaAudio, InputMediaDocument, InputMediaPhoto, InputMediaVideo]] = []
if Path(configWrap.bot_config.log_file).exists():
with open(configWrap.bot_config.log_file, "rb") as fh:
logs_list.append(InputMediaDocument(fh.read(), filename="telegram.log"))
if Path(f"{configWrap.bot_config.log_path}/klippy.log").exists():
with open(f"{configWrap.bot_config.log_path}/klippy.log", "rb") as fh:
logs_list.append(InputMediaDocument(fh.read(), filename="klippy.log"))
if Path(f"{configWrap.bot_config.log_path}/moonraker.log").exists():
with open(f"{configWrap.bot_config.log_path}/moonraker.log", "rb") as fh:
logs_list.append(InputMediaDocument(fh.read(), filename="moonraker.log"))
log_files_names: List[str] = ["telegram.log", "klippy.log", "moonraker.log", "crowsnest.log"]
for log_file in log_files_names:
if Path(f"{configWrap.bot_config.log_path}/{log_file}").exists():
with open(f"{configWrap.bot_config.log_path}/{log_file}", "rb") as fh:
logs_list.append(InputMediaDocument(fh.read(), caption="Upload logs to analyzer /upload_logs", filename=log_file))

if logs_list:
update.effective_message.reply_media_group(logs_list, disable_notification=notifier.silent_commands, quote=True)
else:
update.effective_message.reply_text(
text="No logs found in log_path",
text=f"No logs found in log_path `{configWrap.bot_config.log_path}`",
disable_notification=notifier.silent_commands,
quote=True,
)


def upload_logs(update: Update, _: CallbackContext) -> None:
if update.effective_message is None or update.effective_message.bot is None:
logger.warning("Undefined effective message or bot")
return

if Path(f"{configWrap.bot_config.log_path}/dmesg.txt").exists():
Path(f"{configWrap.bot_config.log_path}/dmesg.txt").unlink()

dmesg_res = subprocess.run(f"dmesg -T > {configWrap.bot_config.log_path}/dmesg.txt", shell=True, executable="/bin/bash", check=False, capture_output=True)
if dmesg_res.returncode != 0:
logger.warning("dmesg file creation error: %s %s", dmesg_res.stdout.decode("utf-8"), dmesg_res.stderr.decode("utf-8"))
update.effective_message.reply_text(
text=f'Dmesg log file creation error {dmesg_res.stderr.decode("utf-8")}',
disable_notification=notifier.silent_commands,
quote=True,
)
return

if Path(f"{configWrap.bot_config.log_path}/debug.txt").exists():
Path(f"{configWrap.bot_config.log_path}/debug.txt").unlink()

commands = [
"lsb_release -a",
"uname -a",
"find /dev/serial",
"find /dev/v4l",
"free -h",
"df -h",
"lsusb",
"systemctl status KlipperScreen",
"systemctl status klipper-mcu",
"ip --details --statistics link show dev can0",
]
for command in commands:
subprocess.run(
f'echo >> {configWrap.bot_config.log_path}/debug.txt;echo "{command}" >> {configWrap.bot_config.log_path}/debug.txt;{command} >> {configWrap.bot_config.log_path}/debug.txt',
shell=True,
executable="/bin/bash",
check=False,
)

files = ["/boot/config.txt", "/boot/cmdline.txt", "/boot/armbianEnv.txt", "/boot/orangepiEnv.txt", "/boot/BoardEnv.txt", "/boot/env.txt"]
with open(configWrap.bot_config.log_path + "/debug.txt", mode="a", encoding="utf-8") as debug_file:
for file in files:
if Path(file).exists():
debug_file.write(f"\n{file}\n")
with open(file, mode="r", encoding="utf-8") as file_obj:
debug_file.writelines(file_obj.readlines())

if Path(f"{configWrap.bot_config.log_path}/logs.tar.xz").exists():
Path(f"{configWrap.bot_config.log_path}/logs.tar.xz").unlink()

with tarfile.open(f"{configWrap.bot_config.log_path}/logs.tar.xz", "w:xz") as tar:
for file in ["telegram.log", "crowsnest.log", "moonraker.log", "klippy.log", "dmesg.txt", "debug.txt"]:
if Path(f"{configWrap.bot_config.log_path}/{file}").exists():
tar.add(Path(f"{configWrap.bot_config.log_path}/{file}"), arcname=file)

with open(f"{configWrap.bot_config.log_path}/logs.tar.xz", "rb") as log_archive_ojb:
resp = requests.post(url="https://coderus.openrepos.net/klipper_logs", files={"tarfile": log_archive_ojb}, allow_redirects=False, timeout=25)
if resp.ok:
logs_path = resp.headers["location"]
logger.info(logs_path)
update.effective_message.reply_text(
text=f"Logs are available at https://coderus.openrepos.net{logs_path}",
disable_notification=notifier.silent_commands,
quote=True,
)
else:
logger.error(resp.reason)
update.effective_message.reply_text(
text=f"Logs upload failed `{resp.reason}`",
disable_notification=notifier.silent_commands,
quote=True,
)


def restart_bot() -> None:
scheduler.shutdown(wait=False)
if ws_helper.websocket:
Expand Down Expand Up @@ -928,6 +1003,7 @@ def bot_commands() -> Dict[str, str]:
"cancel": "cancel printing",
"files": "list gcode files. you can start printing one from menu",
"logs": "get klipper, moonraker, bot logs",
"upload_logs": "get klipper, moonraker, bot logs and upload logs to the analyzer https://coderus.openrepos.net/klipper_logs",
"macros": "list all visible macros from klipper",
"gcode": 'run any gcode command, spaces are supported. "gcode G28 Z"',
"video": "will take mp4 video from camera",
Expand Down Expand Up @@ -1057,6 +1133,7 @@ def start_bot(bot_token, socks):
dispatcher.add_handler(CommandHandler("macros", get_macros, run_async=True))
dispatcher.add_handler(CommandHandler("gcode", exec_gcode, run_async=True))
dispatcher.add_handler(CommandHandler("logs", send_logs, run_async=True))
dispatcher.add_handler(CommandHandler("upload_logs", upload_logs, run_async=True))

dispatcher.add_handler(MessageHandler(Filters.command, macros_handler, run_async=True))

Expand Down
4 changes: 3 additions & 1 deletion bot/notifications.py
Original file line number Diff line number Diff line change
Expand Up @@ -226,7 +226,9 @@ def _notify(self, message: str, silent: bool, group_only: bool = False, manual:
photo.close()

# manual notification methods
def send_error(self, message: str) -> None:
def send_error(self, message: str, logs_upload: bool = False) -> None:
if logs_upload:
message += "\n Upload logs to analyzer /upload_logs"
self._sched.add_job(
self._send_message,
kwargs={
Expand Down
6 changes: 3 additions & 3 deletions bot/websocket_helper.py
Original file line number Diff line number Diff line change
Expand Up @@ -285,7 +285,7 @@ def parse_print_stats(self, message_params):
error_mess = f"Printer state change error: {print_stats_loc['state']}\n"
if "message" in print_stats_loc and print_stats_loc["message"]:
error_mess += f"{print_stats_loc['message']}\n"
self._notifier.send_error(error_mess)
self._notifier.send_error(error_mess, logs_upload=True)
elif state == "standby":
self._klippy.printing = False
self._notifier.remove_notifier_timer()
Expand Down Expand Up @@ -346,7 +346,7 @@ def websocket_to_message(self, ws_loc, ws_message):
state_message = message_result["state_message"]
if self._klippy.state_message != state_message and klippy_state != "startup":
self._klippy.state_message = state_message
self._notifier.send_error(f"Klippy changed state to {self._klippy.state}\n{self._klippy.state_message}")
self._notifier.send_error(f"Klippy changed state to {self._klippy.state}\n{self._klippy.state_message}", logs_upload=True)
else:
logger.error("UnKnown klippy state: %s", klippy_state)
self._klippy.connected = False
Expand All @@ -365,7 +365,7 @@ def websocket_to_message(self, ws_loc, ws_message):
return

if "error" in json_message:
self._notifier.send_error(f"{json_message['error']['message']}")
self._notifier.send_error(f"{json_message['error']['message']}", logs_upload=True)

else:
message_method = json_message["method"]
Expand Down
6 changes: 6 additions & 0 deletions scripts/install.sh
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,11 @@ install_packages() {
sudo apt-get install --yes ${PKGLIST}
}

fix_permissions()}{
sudo echo "kernel.dmesg_restrict = 0" > /etc/sysctl.d/51-dmesg-restrict.conf
sudo sysctl kernel.dmesg_restrict=0
}

create_virtualenv() {
report_status "Installing python virtual environment..."

Expand Down Expand Up @@ -196,6 +201,7 @@ install_instances(){
sudo systemctl stop moonraker-telegram-bot*
status_msg "Installing dependencies"
install_packages
fix_permissions
create_virtualenv

init_config_path
Expand Down

0 comments on commit ef83981

Please sign in to comment.