ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

基于SNMP的打印机实时监控方案:原理与Python实现

2026/9/3 19:33:06 拓冰建站 浏览量
基于SNMP的打印机实时监控方案:原理与Python实现 简介面向IT运维与企业办公管理者的实时监控打印机状态资料包系统梳理从设备运行状态采集到打印报表分析的关键知识点可帮助读者理解如何利用SNMP、WMI及现有监控软件跟踪打印队列、耗材余量、作业时间与文档日志并规划故障预警和资源优化策略。资源包共106个文件主体为JSON数据文件和HTML页面另有少量ZIP压缩包整体仅2.25MB便于下载后快速浏览和复用。内容兼顾技术原理与落地实践涵盖打印状态监测、时间追踪、份数统计、敏感信息保护等议题并点出故障预警、资源优化和报表分析的常见工具思路适合正在搭建打印监控体系或希望通过轻量手段提升打印效率的管理者参考。目前已有2281人学习下载适合IT运维、行政办公及教学演示等场景作为实用参考。 搞IT最怕的就是办公室突然冒出来一句“打印机坏了”等你跑到现场一看十次里有七次是没纸了、卡纸了、机器离线路由器没给它好脸。真正主板烧了、定影组件挂掉的情况反而少见。以前我管办公室设备的时候基本都是靠行政同事跑来报修再去检查。后来发现这办法太被动员工一打印就发现缺墨、离线工作效率全耽误在这台小机器上。于是我开始琢磨怎么把“实时监控打印机状态”这件事做成一套固定系统让设备状态自己会说话该告警告警该预警预警。这篇文章就把我从需求拆解、协议选型到脚本实现、落地排障的整个过程整理出来给你一个可以直接参考复现的方案尤其适合中小企业IT、行政和运维同学。1. 为什么要做打印机实时监控需求拆解与方案选型1.1 打印机状态里藏着哪些关键信息很多人以为监控打印机就是看在线还是离线真做起来你会发现可监控的信息比想象的要多得多也实用得多。在线/离线状态设备是否可达网络是否正常。运行状态码设备是否报错处于空闲、打印中、卡纸、开门报错等状态。耗材余量墨粉、墨盒、硒鼓、废粉仓的剩余百分比。纸张与纸盒状态哪个纸盒缺纸、有没有卡纸。打印页数计数总打印页数可用于成本核算和设备维护周期判断。固件/型号信息设备型号、序列号、固件版本方便做资产台账。这些信息组合起来能解决很多实际管理问题耗材不用等用户喊“没墨了”再买设备故障可以在上班前发现打印量还能按部门统计出来做成本分摊。可以说一套状态监控系统不只是“看设备是否活着”而是一套设备健康度管理工具。1.2 商业平台、开源监控、自研脚本怎么选明确了要看哪些指标下一个问题是用什么方式实现我当时在三个方向之间犹豫过对应三种典型思路这里列个对比方案方向代表产品/技术优点缺点适合场景商业打印管理平台PaperCut、Printix、惠普智系列管理平台等功能全自带计费、权限、报表部署后很省心按设备或按用户收费小规模环境下成本高中大型企业打印量高、有计费需求的场景通用监控平台扩展Zabbix、Cacti、LibreNMS SNMP模板一套系统能顺便把网络设备、服务器一起监控生态成熟打印机专属维度少耗材、页数采集需要自己调模板已经有监控系统想直接纳管打印机的环境自研轮询脚本Python SNMP 工具灵活可控想采集什么就采集什么部署轻量需要自己维护功能相对简单打印机数量在几台到几十台预算有限的中小环境我最后选了自研脚本。原因很直接公司打印机几十台商用平台的费用比一年粉墨开支还高Zabbix虽然免费但为了几十台打印机单独维护一套监控体系有点杀鸡用牛刀而用Python写一个实时轮询脚本半小时就能跑通成本几乎为零后续按需加指标也很方便。如果打印机规模上百台那我会认真劝你直接用成熟平台采集、告警、报表都省心。2. 监控核心原理SNMP协议与打印机MIB2.1 SNMP协议基础与为什么打印机都支持自研方案里最关键的选型就是采用SNMP简单网络管理协议来采集打印机状态。为什么是SNMP而不是写个软件装在电脑上、或者解析打印机网页管理界面原因有四条原生支持不需要装客户端绝大多数支持网络打印的设备和打印机固件里自带SNMP Agent直接在网管界面打开开关就能用不需要在设备上装任何东西。跨品牌兼容性好惠普、佳能、爱普生、兄弟、富士施乐等主流厂商都实现了标准SNMP MIB尤其是Printer-MIB标准编号 1.3.6.1.2.1.43很多基础状态字段一致。轻量高效SNMP走UDP 161端口单个请求也就几百字节对打印机本身性能影响很小。生态成熟Linux下net-snmp工具链齐全写脚本、调试非常方便。原理上SNMP就是“管理端”向“被管设备”发一种类似“字典查询”的请求每个被监控的参数都对应一个唯一的对象标识符也就是OID。管理端发请求去取某个OID对应的值设备返回字符串或数字。把OID理解成设备内部参数的“门牌号”就行。2.2 高频使用的OID参考与字段含义我用到的OID不算多但都是高频且相对通用的整理成下面的表方便你直接抄用途OID返回值示例说明设备描述1.3.6.1.2.1.1.1.0STRING: HP LaserJet M428-M429设备型号、固件信息设备名称1.3.6.1.2.1.1.5.0STRING: 前台打印机打印机自定义名称运行状态1.3.6.1.2.1.25.3.2.1.5.1INTEGER: 11正常、2警告、3故障需实测确认耗材余量标准MIB1.3.6.1.2.1.43.11.1.1.9INTEGER: 80通常为百分比多个耗材时带不同索引总打印页数1.3.6.1.2.1.43.10.2.1.4.1.1Counter32: 15234累计打印计数当前任务状态1.3.6.1.2.1.43.5.1.1.5.1INTEGER: 3打印任务状态空闲/打印中/暂停注意一个坑耗材余量OID在标准Printer-MIB里定义得很好但不同厂商实现差异很大。有的机器黑色、彩色、废粉仓分别占不同的表索引有的直接用私有OID。所以实际调试时不要只盯着1.3.6.1.2.1.43.11.1.1.9这一个节点而是应该用snmpwalk把整棵子树拉出来看一遍找到真正对应的字段。后面我会详细演示。另外运行状态码1、2、3这种映射不是所有机器都一致尤其是“2”到底是缺纸还是警告不同厂商可能有差异。稳妥做法是实测先读取空闲状态的返回值再人为拔掉纸盒/打开盖子观察状态码怎么变用两次对比结果来确定告警阈值。3. 从零搭建一套可用的实时监控脚本3.1 环境准备与先用命令行验证我用来跑监控的是一台Linux服务器其实拿树莓派或者一台不关机的旧电脑也一样。以Debian/Ubuntu为例先安装net-snmp工具包sudo apt update sudo apt install -y snmp snmpwalk snmpget python3 python3-pip先别急着写代码用命令行验证一下打印机SNMP通不通这能省下大量调试时间。查设备描述和耗材余量snmpget -v2c -c public 192.168.1.100 1.3.6.1.2.1.1.1.0 snmpwalk -v2c -c public 192.168.1.100 1.3.6.1.2.1.43.11.1.1.9第一个命令看设备基本信息第二个命令会列出所有耗材节点。如果返回结果正常说明设备SNMP已经开着了如果提示Timeout在打印机网管界面里确认SNMP是否开启、community团体名默认一般是public是否匹配同时检查服务器的防火墙是否放行UDP 161。3.2 写一个多打印机轮询脚本命令行验证通过后写正式脚本。我在Python里没有用额外的SNMP库而是直接调snmpget命令行工具好处是少一层依赖问题输出解析也直观方便排障。脚本核心代码如下#!/usr/bin/env python3 import subprocess import time import requests from datetime import datetime # 打印机清单按实际情况修改 IP、community PRINTERS [ {name: 前台打印机, ip: 192.168.1.100, community: public}, {name: 财务室打印机, ip: 192.168.1.101, community: public}, {name: 设计部彩色机, ip: 192.168.1.102, community: public}, ] # 要采集的标准 OID OIDS { device_desc: 1.3.6.1.2.1.1.1.0, device_name: 1.3.6.1.2.1.1.5.0, run_status: 1.3.6.1.2.1.25.3.2.1.5.1, toner_level: 1.3.6.1.2.1.43.11.1.1.9.1.1, total_page: 1.3.6.1.2.1.43.10.2.1.4.1.1, } def snmp_get(ip, community, oid): 执行 snmpget 并返回等号后面的值 try: out subprocess.check_output( [snmpget, -v2c, -c, community, -t, 3, -r, 1, ip, oid], stderrsubprocess.STDOUT, textTrue, timeout10, ) # 输出形如 OID INTEGER: 80取等号后的内容 if in out: return out.split(, 1)[1].strip() return fUNKNOWN: {out.strip()} except subprocess.CalledProcessError as e: return fERROR: {e.output.strip()} except Exception as e: return fERROR: {str(e)} def send_dingtalk(content): 把告警消息推到钉钉机器人按需替换 webhook 地址和方法 webhook https://oapi.dingtalk.com/robot/send?access_tokenYOUR_TOKEN try: requests.post(webhook, json{ msgtype: text, text: {content: content} }, timeout5) except Exception as e: print(f[告警推送失败] {e}) def check_one_printer(p): status snmp_get(p[ip], p[community], OIDS[run_status]) toner snmp_get(p[ip], p[community], OIDS[toner_level]) now datetime.now().strftime(%Y-%m-%d %H:%M:%S) print(f[{now}] {p[name]} ({p[ip]}) 状态{status} 耗材{toner}) # 状态码或关键字包含 ERROR说明设备不可达 if ERROR in status or ERROR in toner: send_dingtalk(f⚠️ {p[name]} 可能离线或 SNMP 异常{status} / {toner}) # 耗材数值小于 15触发预警 elif toner.isdigit() and int(toner) 15: send_dingtalk(f⚠️ {p[name]} 耗材剩余 {toner}%请准备更换耗材) def main(): while True: for p in PRINTERS: check_one_printer(p) time.sleep(60) if __name__ __main__: main()代码逻辑不复杂主循环每分钟遍历所有打印机读取运行状态和耗材余量设备不可达或耗材低于阈值时通过钉钉机器人推消息。打印部分会输出到控制台方便你观察日志。如果你不想用钉钉把send_dingtalk函数里的requests.post换成SMTP邮件发送改造思路类似。这里要提醒一句上面的耗材OID我写的是1.3.6.1.2.1.43.11.1.1.9.1.1但实际打印机上耗材索引很可能不是唯一的黑色墨粉、彩色墨粉、废粉仓对应不同的最后一段数字。你拿到机器后先用snmpwalk输出真正的索引再把OID改成实际值不要直接抄默认配置。3.3 把状态变成可视化看板与数据归档轮询脚本只是第一步人不可能一直盯控制台。我后续做了两件事数据归档和可视化。数据归档很简单脚本里把每次采集结果追加到SQLite或CSV里。比如用一个printer_status.csv字段包括时间戳、打印机名、IP、运行状态、耗材余量、总页数这个文件直接就能用Excel打开月末还能拿来做打印量统计。可视化要省事的话最不需要造轮子的方案是把数据接进Grafana。社区里有现成的打印机状态看板模板只要数据源能查到SQLite、MySQL或者InfluxDB配置几分钟就能出来一个大屏在线状态、耗材趋势、打印量排行都能看。如果只想临时看个页面也可以用FastAPI或Flask写个只读接口把CSV文件里的最新状态读出来渲染成HTML够用就行。3.4 监控频率怎么定轮询策略与资源平衡有一个参数很容易被忽略但实际很重要——轮询频率。我见过有人为了“实时”把轮询间隔设成10秒结果打印机控制板CPU占满打印速度肉眼可见变慢这属于把监控做成了事故源。在线状态、运行状态建议60秒轮询一次足够满足实时感。耗材余量、打印页数变化缓慢5分钟一次就够没人需要秒级知道墨粉从80%变79.9%。告警推送建议做去重比如耗材低于15%只在首次触发时推一次否则每60秒推一遍钉钉群会炸。4. 落地部署中的常见问题与排查技巧4.1 高频坑位速查表实际部署阶段我遇到的坑几乎全都能归纳成下面这几类。整理成速查表你对照着处理就行现象可能原因排查与解决snmpget超时无响应打印机SNMP未启用登录打印机Web管理页找到“网络/SNMP”选项启用SNMP v1/v2c并确认团体名机器明明在打印但脚本报离线服务器防火墙拦截UDP 161出站或打印机ACL限制了来源IP检查服务器防火墙给打印机IP配置SNMP访问白名单允许服务器IP访问返回noSuchNameOID在该机型上不存在用snmpwalk扫描1.3.6.1.2.1.43整棵子树找到厂商实际的OID节点耗材值拿不到百分比私有MIB未按标准实现优先用snmpwalk看返回值部分机型返回值可能是页数、克数等需要自己换算百分比状态码含义和文档不一致厂商对INTEGER值的映射有差异人为制造故障拔纸、开门、卡纸对比状态码变化建立自己的映射表监控脚本跑了几天突然挂掉日志文件越来越大或Python进程被OOM杀掉用systemd服务管理脚本设置Restartalways开启logrotate切割日志打印机IP变了导致监控失效设备通过DHCP动态获取IP给打印机在路由器里设置DHCP保留或改为静态IP并绑定MAC这里单独展开一下“用snmpwalk找私有OID”的方法这是最常用的排障手段。以找耗材OID为例snmpwalk -v2c -c public 192.168.1.100 1.3.6.1.2.1.43.11.1.1.9输出里你会看到类似SNMPv2-SMI::mib-2.43.11.1.1.9.1.1 INTEGER: 80 SNMPv2-SMI::mib-2.43.11.1.1.9.1.2 INTEGER: 60两个索引值通常对应不同耗材仓。这时候逐个去测把黑墨粉取出来或者故意用低墨盒打印看哪个索引的值下降就知道哪个是黑粉仓、哪个是彩色粉仓。这个方法比翻几百页技术文档快得多。4.2 现场部署的几点实战经验最后说几条我在实际部署中非常管用的经验属于那种“文档里不会写、用起来真能救命”的细节。第一上线之前把打印机的SNMP community从默认的public改掉。虽然内部网络相对安全但公共团体名意味着同一局域网任何人都能通过snmpwalk摸清你的打印量、耗材余量一些攻击者可以利用这些信息判断设备型号和漏洞。改成不容易猜的团体名成本几乎为零。第二告警一定要设置“静默窗口”。凌晨三点的打印机关机告警没有任何意义只会把值班手机打爆。我在脚本里直接处理了这个逻辑非工作时间只记录、不发送告警工作时间才真正推送。实现不复杂用datetime判断当前时间落在哪个时间段就行。第三状态监控上线后建议先跑一个星期“只记录、不告警”。让脚本先把所有打印机的真实数据采一遍你会对设备状况有完全不同的认知——哪台机器每天掉线三次、哪台墨粉余量一直报警但实际还能打五百页、哪台总页数增长异常需要关注。摸清了这个底再逐步打开告警规则才不会第一天就被误报淹没。这套系统我实际跑了将近一年最大的感受是IT值班电话少了一大半行政批量采购耗材的时候也有了数据支撑。打印机这种设备看起来默默无闻但其实很适合用SNMP这套传统协议管理起来。你要做的只是把它加入监控名单剩下的交给脚本就行。本文还有配套的精品资源点击获取