首页/新闻资讯/正文详情

在另一台电脑上查看 Python 程序日志:从创建到远程访问

发布时间:2026/9/26 20:27:24 来源:云帆数科 栏目:资讯中心
在另一台电脑上查看 Python 程序日志:从创建到远程访问
在 Ubuntu 上跑一个批处理脚本离开电脑后想知道它执行到哪一步通常还得重新打开终端。假如只是看几行进度没有必要为此部署一整套日志平台让程序把过程写进文件再用一个小网页读取就足够完成这次练习。本文用两个 Python 文件实现这个过程Ubuntu 生成日志Mac 浏览器通过星空组网地址查看。代码只使用标准库不装第三方包也不需要数据库。页面每隔 3 秒重新读取日志展示最新 20 行。一、登录后台让两台设备先连起来打开星空组网官网点击“后台管理”。没有账号可以先注册已有账号直接登录。本次浏览器已有有效登录状态因此复用原账号下图拍摄的是空白登录入口没有重新注册或填写密码。首次使用时进入“设备管理 → 成员列表”点击“添加成员”为 Ubuntu 和 Mac 分别准备成员账号。名称可以按设备用途填写创建后保存完整成员账号和密码再到对应客户端登录。不要让两台长期在线设备共用一个成员账号字段说明见官方设备与成员管理文档。客户端尚未安装的读者分别按 Linux 使用说明和 macOS 使用说明操作。Linux 安装完成后根据终端输出打开控制台地址登录成员账号确认在线状态和组网 IP。本文两端均已安装并登录直接沿用现有成员没有重复创建。在这里插入图片描述这次的分工和地址如下复现时换成自己客户端显示的实际值设备用途本次组网 IPUbuntu 22.04运行示例程序与日志网页192.168.188.5Mac用浏览器查看日志192.168.188.1星空组网负责两端的网络访问日志生成和网页展示由我们自己写的程序完成。后台“组网成功”是第一步后面还要实际访问网页才能确认这条路径可用。二、检查环境创建独立目录在 Ubuntu 终端执行lsb_release-dspython3--versionip-4-briefaddress show StarVPN ss-ltnsport :18093本次 Python 为 3.10.1218093没有监听记录可以用作演示端口。若有其他程序占用换一个空闲端口并同步修改启动命令和浏览器地址。虚拟网卡的UNKNOWN不应单独作为掉线结论还要结合客户端状态与实际访问判断。随后创建项目目录mkdir~/log-viewer-demo-20260925cd~/log-viewer-demo-20260925截图使用现有 root 实验会话所以路径在/root下普通用户直接在自己的家目录执行即可不需要为了这篇教程切换 root。若提示目录已存在先检查内容或换一个新目录名避免覆盖旧文件。三、准备两个 Python 文件项目的数据流很简单demo.py → demo.log → server.py → 浏览器。一个文件负责产生日志另一个负责读取两者可以分别启动和停止。先创建demo.py。下面整段复制到 Ubuntu 终端执行包括末尾单独一行的PYcatdemo.pyPY import logging import time from pathlib import Path LOG_FILE Path(__file__).with_name(demo.log) BATCH_COUNT 12 INTERVAL_SECONDS 2 def main() - None: logging.basicConfig( filenameLOG_FILE, encodingutf-8, levellogging.INFO, format%(asctime)s %(levelname)-7s %(message)s, datefmt%H:%M:%S, ) logging.info(Demo started: processing sample batches) try: for batch in range(1, BATCH_COUNT 1): time.sleep(INTERVAL_SECONDS) logging.info(Batch %02d/%d completed, batch, BATCH_COUNT) if batch 4: logging.warning(Demo warning: sample row skipped (simulated)) except KeyboardInterrupt: logging.info(Demo interrupted by user) else: logging.info(Demo finished) if __name__ __main__: main() PY它每隔 2 秒记录一个批次共执行 12 批约 24 秒后结束。第 4 批额外写入一条模拟WARNING用来观察不同日志级别并不表示服务器真的发生故障。日志追加到脚本旁边的demo.log不是写在终端里。再创建网页服务server.pycatserver.pyPY import argparse import html import ipaddress import logging from collections import deque from datetime import datetime from http.server import BaseHTTPRequestHandler, ThreadingHTTPServer from pathlib import Path LOG_FILE Path(__file__).with_name(demo.log) MAX_LINES 20 REFRESH_SECONDS 3 PAGE !doctype html html langzh-CNmeta charsetutf-8 meta nameviewport contentwidthdevice-width, initial-scale1 meta http-equivrefresh content{refresh} titlePython 程序日志/title style body {{ max-width:1040px; margin:40px auto; padding:0 24px; font:17px/1.7 system-ui,sans-serif; background:#f3f6fa; color:#21334a; }} h1 {{ font-size:32px; margin:8px 0; }} p {{ color:#52657c; }} pre {{ padding:24px; background:#132238; color:#e1ebf5; border-radius:12px; overflow:auto; font:16px/1.8 monospace; }} small {{ color:#52657c; }} /style headersmall远程查看 · 只读演示/smallh1Python 程序日志/h1 p显示 demo.log 最新 {limit} 行 · 每 {refresh} 秒刷新/p/header p页面读取时间{now}/p pre{content}/pre small示例数据由 demo.py 生成WARNING 为模拟提示。/small/html def read_tail() - str: try: with LOG_FILE.open(encodingutf-8, errorsreplace) as stream: return .join(deque(stream, maxlenMAX_LINES)) or 日志文件暂时为空。 except FileNotFoundError: return 还没有日志请在 Ubuntu 运行 python3 demo.py。 class Handler(BaseHTTPRequestHandler): def do_GET(self) - None: if self.path ! /: self.send_error(404, Not found) return try: content read_tail() except OSError: logging.exception(Cannot read demo.log) self.send_error(500, Cannot read demo.log; check server terminal) return body PAGE.format( refreshREFRESH_SECONDS, limitMAX_LINES, nowdatetime.now().astimezone().isoformat(timespecseconds), contenthtml.escape(content), ).encode(utf-8) self.send_response(200) self.send_header(Content-Type, text/html; charsetutf-8) self.send_header(Content-Length, str(len(body))) self.send_header(Cache-Control, no-store) self.send_header(X-Content-Type-Options, nosniff) self.end_headers() self.wfile.write(body) def main() - None: parser argparse.ArgumentParser() parser.add_argument(--bind, requiredTrue, typeipaddress.IPv4Address) parser.add_argument(--port, typeint, default18093) args parser.parse_args() if args.bind.is_unspecified or args.bind.is_multicast: parser.error(--bind must be one specific local IPv4 address) if not 1024 args.port 65535: parser.error(--port must be between 1024 and 65535) with ThreadingHTTPServer((str(args.bind), args.port), Handler) as server: print(fLog viewer: http://{args.bind}:{args.port}, flushTrue) print(Press CtrlC to stop., flushTrue) try: server.serve_forever() except KeyboardInterrupt: print(Log viewer stopped., flushTrue) if __name__ __main__: main() PY这里没有开放文件目录浏览也不让访问者传入任意日志路径。服务只读取固定的demo.log缺少文件时显示操作提示读取失败则返回错误并把原因留在服务终端。html.escape()用于把日志作为普通文字展示避免其中的尖括号被解释成网页标签最新 20 行只是显示范围不会删除日志文件中的旧内容。每次请求仍会顺序读取文件因此这个简版适合小型演示日志不适合直接读取几个 GB 的生产日志。完成后检查文件和语法ls-lhdemo.py server.py python3-mpy_compile demo.py server.pyechoPYTHON_SYNTAX_OK四、先启动网页再从 Mac 打开在当前 Ubuntu 终端运行python3 server.py--bind192.168.188.5--port18093--bind后面填写 Ubuntu 自己的组网 IP。不要填写 Mac 的地址也不要把它换成127.0.0.1后者只能从 Ubuntu 本机访问。本例只监听指定组网地址不监听所有网卡。保持这个终端运行在 Mac 浏览器输入完整地址http://192.168.188.5:18093/首次打开时还没有运行日志生成程序因此看到“还没有日志请在 Ubuntu 运行 python3 demo.py”是正常状态。它说明网页已经能访问只是演示文件尚未生成。页面上的“读取时间”来自 Ubuntu代表本次页面读取的时刻它与每一条日志产生的时间是两个概念。服务使用简单的整页定时刷新不是 WebSocket 推送新增内容通常在下一次刷新时出现。五、运行程序对照两端结果再打开一个连接同一台 Ubuntu、使用同一用户的终端进入刚才的目录并执行cd~/log-viewer-demo-20260925 python3 demo.py这时终端暂时没有文字输出因为内容写入了日志文件。回到 Mac 页面可以看到批次逐步增加程序结束后会出现Demo finishedUbuntu 的第二个终端也会回到命令提示符。在这个终端查看最后 5 行tail-n5demo.log再与 Mac 页面底部逐行对照本次最终运行从15:52:47开始到15:53:11完成共产生 15 行记录网页和终端中的批次、时间及完成信息一致。Mac 请求的源地址为192.168.188.1目标为192.168.188.5页面返回 HTTP 200。这证明了本次经组网地址访问日志页的结果不据此推断连接一定采用 P2P 直连。如果再次执行demo.py新内容会继续追加网页只显示文件末尾 20 行。即使程序已经结束网页读取时间仍会变化判断任务是否结束应看日志中的完成标记而不是页面时间有没有更新。六、遇到问题先查这几个位置现象优先检查启动时报地址不可用--bind是否是 Ubuntu 当前拥有的组网 IP浏览器打不开两端是否在线、服务终端是否仍在运行、IP 和端口是否一致一直提示还没有日志是否在同一台 Ubuntu、同一个项目目录运行了demo.py日志读取报错查看服务终端的异常信息确认文件权限与路径排查时先在 Ubuntu 用ss -ltn sport :18093确认服务确实监听再检查组网访问控制和主机防火墙不要为了试通而直接关闭全部防护。HTTP 请求日志与demo.log也要区分前者打印在网页服务终端后者由示例程序写入文件。七、用完停止服务保留代码先关闭 Mac 上的演示页面回到运行server.py的 Ubuntu 终端按CtrlC。看到Log viewer stopped.后检查端口ss-ltnsport :18093ls-lhdemo.py server.py demo.log本次停止后没有监听记录Mac 再次连接也被拒绝。demo.py已自行结束项目文件继续保留之后进入同一目录重新运行启动命令即可。若演示程序尚未结束也可以在它所在的终端按 CtrlC。这个页面没有额外的应用登录验证能够访问该组网地址和端口的设备可以读取展示内容因此本次只使用无敏感信息的演示日志。Python 官方文档也明确说明http.server不推荐用于生产环境。需要长期查看真实业务日志时再考虑鉴权、访问权限、日志轮转以及更合适的日志平台。

相关推荐

SolidWorks机械设计提效插件:国标自动化与API深度集成
SolidWorks机械设计提效插件:国标自动化与API深度集成

1. “大国工匠插件”不是营销噱头,而是SolidWorks生态里真正能省下200小时/年的工程工具你有没有过这种经历:在SolidWorks里画一个标准减速器箱体,光是调国标型材库、查GB/T 1804-2000公差表、手动插入12个M1240六角头螺栓并逐个添加配合关系… · 2026/9/26 20:27:24

Claude Code源码泄露后,TaoToken教你用settings.json加固AI开发工具链
Claude Code源码泄露后,TaoToken教你用settings.json加固AI开发工具链

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/26 20:27:15

tgrep架构解析:HybridIndex+LiveIndex覆盖层如何实现微秒级索引热更新
tgrep架构解析:HybridIndex+LiveIndex覆盖层如何实现微秒级索引热更新

tgrep架构解析:HybridIndexLiveIndex覆盖层如何实现微秒级索引热更新 【免费下载链接】tgrep Trigram-indexed grep with a client/server architecture for fast regex search in large codebases locally 项目地址: https://gitcode.com/gh_mirrors/tg/tgrep … · 2026/9/26 20:27:15

用PPT绘制超分辨率网络结构图:3D与2D论文配图实操指南
用PPT绘制超分辨率网络结构图:3D与2D论文配图实操指南

简介:一份面向超分辨率论文写作与配图的PPT绘图模板,适合科研人员与研究生快速绘制网络结构图。资源覆盖SRCNN、FSRCNN、EDSR、WDSR、RDN、SRMD等经典算法的结构示意,提供3D立体、3D与2D结合、纯2D平面三种风格,并含网络层、卷积、… · 2026/9/26 21:12:42

kage:一行命令把任意网站存进硬盘,还能离线打开——无头浏览器本地快照工具完整上手指南
kage:一行命令把任意网站存进硬盘,还能离线打开——无头浏览器本地快照工具完整上手指南

kage:一行命令把任意网站存进硬盘,还能离线打开——无头浏览器本地快照工具完整上手指南 【免费下载链接】kage Shadow any website for offline viewing, with the JavaScript stripped out 项目地址: https://gitcode.com/gh_mirrors/kage6/kage … · 2026/9/26 21:12:42

108个Python实战项目:从语法到独立开发的突破路径
108个Python实战项目:从语法到独立开发的突破路径

1. 为什么“108个实战项目”是突破Python瓶颈的关键路径1.1 从“看懂”到“写出来”之间隔着什么很多人学Python的经历都差不多:语法看了一遍,教程跟着敲了一遍,for循环、列表推导、字典操作都能说出个大概,但一旦面对一个空白编辑… · 2026/9/26 21:12:42

LangGraph+PostgreSQL 可恢复 Agent Runtime 实践
LangGraph+PostgreSQL 可恢复 Agent Runtime 实践

去年我做内部一个自动化客服原型时,最让我头疼的不是模型回答质量,而是一个看起来很“基础”的问题:任务跑到一半被打断了,怎么让它恢复之后还记得自己刚才在干什么。前期原型用的是最朴素的手写 Loop,模型调用、工具结… · 2026/9/26 21:12:36

自研CRM系统实战:从架构设计到部署落地的完整指南
自研CRM系统实战:从架构设计到部署落地的完整指南

DeskcommCRM这个项目,我前前后后从需求梳理到正式上线跑了将近半年。它不是一个挂着CRM名头的客户通讯录,而是一套把客户资料、销售跟进、售后服务、工单流转全部串起来的完整业务系统。当时团队就七八个人,销售、实施、客服混在一堆Excel和微… · 2026/9/26 21:12:36

50+营销Skill打包进AI Agent:开源项目实战与踩坑指南
50+营销Skill打包进AI Agent:开源项目实战与踩坑指南

最近我在 GitHub 上翻到一个很有意思的开源项目,名字起得很直白:把 50 多种营销 Skill 直接打包进 AI Agent。刷到标题的时候我第一反应是"又是个缝合怪项目",但点进去看完 README 和源码之后,我改主意了,这… · 2026/9/26 21:12:23

数据库课后习题答案别硬背:当测试用例集刷,效率翻倍
数据库课后习题答案别硬背:当测试用例集刷,效率翻倍

简介:万常选版《数据库原理与设计》课后习题答案资源,覆盖第2至6章及第9章,适合正在学习关系模型、数据库建模、关系数据理论与模式求精的本科生、自学者作为复习与自测材料。压缩包共7个文件,含3个doc参考答案、2个sql示例脚本、… · 2026/9/26 0:00:21

OpenClaw 替代品?Hermes Agent 踩坑实录:macOS 飞书接入 TaoToken 配置
OpenClaw 替代品?Hermes Agent 踩坑实录:macOS 飞书接入 TaoToken 配置

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/26 0:00:40

向下兼容与向上兼容:接口设计中的兼容性策略与工程实践
向下兼容与向上兼容:接口设计中的兼容性策略与工程实践

一次版本升级事故,是很多团队绕不过去的坎。线上环境里,服务端明明已经上线了新版接口,老的移动端还在照着旧文档传参数。请求一到网关,校验直接拒绝,用户操作失败,客服群炸了锅,开发群里开始互… · 2026/9/26 0:00:46

了解更多?预约专属演示

我们的顾问将为您一对一讲解产品与方案

企业微信二维码