强曰为道
与天地相似,故不违。知周乎万物,而道济天下,故不过。旁行而不流,乐天知命,故不忧.
文档目录

CUPS 打印服务完全指南 / 第 11 章:故障排查

第 11 章:故障排查

打印服务出现故障时,快速准确地定位和解决问题至关重要。本章将系统地介绍 CUPS 故障排查的方法、工具和最佳实践。


11.1 故障排查流程

11.1.1 通用排查流程

┌─────────────────────────────────────────────────┐
│              CUPS 故障排查流程                    │
│                                                 │
│  1. 症状确认                                     │
│     └── 用户报告什么问题?                        │
│                                                 │
│  2. 基本检查                                     │
│     ├── CUPS 服务是否运行?                       │
│     ├── 打印机是否在线?                          │
│     └── 网络是否连通?                            │
│                                                 │
│  3. 日志分析                                     │
│     ├── error_log (错误日志)                     │
│     ├── access_log (访问日志)                    │
│     └── page_log (页面日志)                      │
│                                                 │
│  4. 配置检查                                     │
│     ├── cupsd.conf 配置                         │
│     ├── printers.conf 打印机配置                 │
│     └── PPD 文件                                │
│                                                 │
│  5. 诊断工具                                     │
│     ├── lpstat                                  │
│     ├── lpinfo                                  │
│     ├── cupsfilter                              │
│     └── ipptool                                 │
│                                                 │
│  6. 解决问题                                     │
│     └── 修复配置/重启服务/更换驱动                │
└─────────────────────────────────────────────────┘

11.1.2 快速诊断清单

#!/bin/bash
# quick-diag.sh - CUPS 快速诊断脚本

echo "=== CUPS 快速诊断 ==="
echo ""

# 1. 检查 CUPS 服务状态
echo "1. CUPS 服务状态"
if systemctl is-active cups > /dev/null 2>&1; then
    echo "   ✅ CUPS 服务正在运行"
else
    echo "   ❌ CUPS 服务未运行"
    echo "   修复: sudo systemctl start cups"
fi
echo ""

# 2. 检查 cupsd 进程
echo "2. cupsd 进程"
if pgrep cupsd > /dev/null; then
    echo "   ✅ cupsd 进程存在 (PID: $(pgrep cupsd))"
else
    echo "   ❌ cupsd 进程不存在"
fi
echo ""

# 3. 检查端口监听
echo "3. 端口监听"
if ss -tlnp | grep -q ":631"; then
    echo "   ✅ 端口 631 正在监听"
else
    echo "   ❌ 端口 631 未监听"
fi
echo ""

# 4. 检查打印机状态
echo "4. 打印机状态"
printer_count=$(lpstat -p 2>/dev/null | wc -l)
if [ "$printer_count" -gt 0 ]; then
    echo "   ✅ 共有 $printer_count 台打印机"
    lpstat -p | head -5
else
    echo "   ⚠️  没有配置打印机"
fi
echo ""

# 5. 检查打印队列
echo "5. 打印队列"
queue_count=$(lpstat -o 2>/dev/null | wc -l)
if [ "$queue_count" -gt 0 ]; then
    echo "   ⚠️  队列中有 $queue_count 个任务"
    lpstat -o | head -5
else
    echo "   ✅ 队列为空"
fi
echo ""

# 6. 检查最近错误
echo "6. 最近错误 (error_log)"
if [ -f /var/log/cups/error_log ]; then
    errors=$(grep -i "error" /var/log/cups/error_log | tail -5)
    if [ -n "$errors" ]; then
        echo "   ⚠️  发现错误:"
        echo "$errors" | sed 's/^/   /'
    else
        echo "   ✅ 没有发现错误"
    fi
else
    echo "   ⚠️  error_log 文件不存在"
fi
echo ""

# 7. 检查磁盘空间
echo "7. 磁盘空间"
spool_usage=$(du -sh /var/spool/cups 2>/dev/null | awk '{print $1}')
echo "   打印队列使用: ${spool_usage:-未知}"
echo ""

# 8. 检查配置文件语法
echo "8. 配置文件语法"
if cupsd -t 2>/dev/null; then
    echo "   ✅ 配置文件语法正确"
else
    echo "   ❌ 配置文件语法错误"
fi
echo ""

echo "=== 诊断完成 ==="

11.2 常见问题及解决方案

11.2.1 打印机无法识别

症状:打印机未出现在打印机列表中

排查步骤

# 1. 检查 USB 连接
lsusb | grep -i "printer\|hp\|canon\|epson\|brother"

# 2. 检查 CUPS 后端
lpinfo -v | grep -i usb

# 3. 检查后端权限
ls -la /usr/lib/cups/backend/

# 4. 检查设备文件
ls -la /dev/usb/lp*

# 5. 检查内核模块
lsmod | grep usblp

# 6. 检查 udev 规则
ls /etc/udev/rules.d/ | grep -i cups

解决方案

# 加载 usblp 模块
sudo modprobe usblp

# 修复后端权限
sudo chmod 755 /usr/lib/cups/backend/*
sudo chmod 700 /usr/lib/cups/backend/usb

# 重新检测打印机
sudo lpinfo -v

# 如果使用 HP 打印机
hp-probe

11.2.2 打印任务卡在队列中

症状:打印任务显示为 “processing” 但不打印

排查步骤

# 1. 查看任务状态
lpstat -o

# 2. 查看任务详情
lpstat -l -o myprinter-123

# 3. 查看错误日志
grep "myprinter-123" /var/log/cups/error_log

# 4. 检查打印机状态
lpstat -p myprinter

解决方案

# 取消卡住的任务
cancel myprinter-123

# 取消所有任务
cancel -a myprinter

# 重启打印机
sudo cupsdisable myprinter
sudo cupsenable myprinter

# 重启 CUPS 服务
sudo systemctl restart cups

# 如果问题持续,检查打印机硬件
# - 检查纸张
# - 检查墨粉/墨水
# - 检查错误指示灯

11.2.3 打印质量差

症状:打印输出模糊、颜色偏差、有条纹

排查步骤

# 1. 打印测试页
sudo lp -d myprinter /usr/share/cups/data/testprint

# 2. 检查打印选项
lpoptions -p myprinter -l | grep -i "resolution\|quality"

# 3. 检查 PPD 配置
grep -i "resolution" /etc/cups/ppd/myprinter.ppd

# 4. 检查驱动
lpstat -p myprinter -l

解决方案

# 调整打印质量
lp -d myprinter -o Resolution=600dpi document.pdf

# 调整颜色设置
lp -d myprinter -o ColorModel=RGB document.pdf

# 清洁打印头(HP 打印机)
hp-clean -p myprinter

# 校准打印头(HP 打印机)
hp-align -p myprinter

# 更换驱动(如果问题持续)
# 尝试使用不同的 PPD 文件
sudo lpadmin -p myprinter -P /path/to/alternative.ppd

11.2.4 网络打印机连接失败

症状:无法连接到网络打印机

排查步骤

# 1. 测试网络连通性
ping 192.168.1.100

# 2. 测试端口连通性
telnet 192.168.1.100 9100    # Socket
telnet 192.168.1.100 631     # IPP

# 3. 使用 nmap 扫描
nmap -p 9100,631 192.168.1.100

# 4. 测试 IPP 连接
ipptool -tv ipp://192.168.1.100/ipp/print get-printer-attributes.test

# 5. 检查 DNS 解析
nslookup printer-hostname

解决方案

# 使用 IP 地址而不是主机名
sudo lpadmin -p myprinter -v socket://192.168.1.100:9100

# 检查防火墙
sudo ufw status
sudo iptables -L -n

# 开放打印端口
sudo ufw allow 9100/tcp
sudo ufw allow 631/tcp

# 测试不同协议
# 尝试 Socket
sudo lpadmin -p myprinter -v socket://192.168.1.100:9100

# 尝试 IPP
sudo lpadmin -p myprinter -v ipp://192.168.1.100/ipp/print

# 尝试 LPD
sudo lpadmin -p myprinter -v lpd://192.168.1.100/PASSTHRU

11.2.5 驱动不兼容

症状:打印输出乱码、错误页面

排查步骤

# 1. 查看当前驱动
lpstat -p myprinter -v

# 2. 查看 PPD 文件
head -20 /etc/cups/ppd/myprinter.ppd

# 3. 查看支持的驱动
lpinfo -m | grep -i "打印机型号"

# 4. 测试不同驱动
# 使用通用 PostScript 驱动
sudo lpadmin -p myprinter -P /usr/share/ppd/Generic/PostScript.ppd

解决方案

# 安装正确的驱动
sudo apt install -y printer-driver-gutenprint
sudo apt install -y hplip
sudo apt install -y printer-driver-foo2zjs

# 使用 IPP Everywhere(无驱动)
sudo lpadmin -p myprinter -m "everywhere" \
  -v "ipp://192.168.1.100/ipp/print"

# 使用通用 PCL 驱动
sudo lpadmin -p myprinter -m "HP LaserJet Series" \
  -v socket://192.168.1.100:9100

# 使用 Raw 队列(不做任何处理)
sudo lpadmin -p myprinter -m raw \
  -v socket://192.168.1.100:9100

11.2.6 Web 界面无法访问

症状:浏览器无法打开 http://localhost:631

排查步骤

# 1. 检查 CUPS 服务
sudo systemctl status cups

# 2. 检查端口监听
ss -tlnp | grep 631

# 3. 检查防火墙
sudo ufw status
sudo iptables -L -n

# 4. 检查配置文件
grep "Listen" /etc/cups/cupsd.conf

解决方案

# 重启 CUPS 服务
sudo systemctl restart cups

# 检查监听地址
# 如果只监听 localhost,修改为所有接口
sudo vim /etc/cups/cupsd.conf
# 修改: Listen 0.0.0.0:631

# 开放防火墙端口
sudo ufw allow 631/tcp

# 检查 SELinux/AppArmor
getenforce
sudo aa-status

# 检查 WebInterface 配置
sudo cupsctl WebInterface=yes

11.3 日志分析

11.3.1 日志文件说明

日志文件 内容 位置
error_log 错误和调试信息 /var/log/cups/error_log
access_log HTTP 访问记录 /var/log/cups/access_log
page_log 打印页面记录 /var/log/cups/page_log

11.3.2 错误日志分析

# 查看最新错误
tail -f /var/log/cups/error_log

# 搜索特定错误
grep -i "error" /var/log/cups/error_log

# 搜索特定打印机错误
grep "myprinter" /var/log/cups/error_log | grep -i "error"

# 搜索特定时间范围的错误
awk '/May 10 09:/' /var/log/cups/error_log | grep -i "error"

# 统计错误类型
grep -i "error" /var/log/cups/error_log | \
  awk '{print $NF}' | sort | uniq -c | sort -rn | head -10

常见错误信息

错误信息 含义 解决方案
Unable to connect to printer 无法连接打印机 检查网络/USB 连接
Printer not responding 打印机无响应 检查打印机电源和网络
Filter failed 过滤器执行失败 检查过滤器和依赖
Job canceled 任务被取消 查看取消原因
Out of memory 内存不足 增加系统内存或减小任务
Permission denied 权限拒绝 检查文件权限
No such device 设备不存在 检查打印机连接

11.3.3 访问日志分析

# 查看最新访问
tail -f /var/log/cups/access_log

# 统计访问 IP
awk '{print $1}' /var/log/cups/access_log | sort | uniq -c | sort -rn | head -10

# 统计 HTTP 状态码
awk '{print $9}' /var/log/cups/access_log | sort | uniq -c | sort -rn

# 统计请求的打印机
grep "POST /printers/" /var/log/cups/access_log | \
  awk '{print $7}' | sort | uniq -c | sort -rn

# 查看认证失败
grep "401\|403" /var/log/cups/access_log

11.3.4 页面日志分析

# 查看最新打印记录
tail -f /var/log/cups/page_log

# 统计每个用户的打印量
awk '{print $2}' /var/log/cups/page_log | sort | uniq -c | sort -rn

# 统计每个打印机的打印量
awk '{print $1}' /var/log/cups/page_log | sort | uniq -c | sort -rn

# 统计每日打印量
awk -F'[:/]' '{print $1"/"$2"/"$3}' /var/log/cups/page_log | \
  sort | uniq -c

# 统计打印页数
awk '{sum += $6} END {print sum}' /var/log/cups/page_log

11.3.5 日志分析脚本

#!/bin/bash
# cups-log-report.sh - CUPS 日志报告生成脚本

REPORT_DATE=${1:-$(date +%Y-%m-%d)}
ACCESS_LOG="/var/log/cups/access_log"
ERROR_LOG="/var/log/cups/error_log"
PAGE_LOG="/var/log/cups/page_log"

echo "=========================================="
echo "  CUPS 日志报告 - $REPORT_DATE"
echo "=========================================="
echo ""

# 1. 概览
echo "1. 概览"
echo "----------------------------------------"
echo "总访问次数: $(grep "$REPORT_DATE" $ACCESS_LOG | wc -l)"
echo "错误数量: $(grep "$REPORT_DATE" $ERROR_LOG | grep -i error | wc -l)"
echo "打印任务数: $(grep "$REPORT_DATE" $PAGE_LOG | wc -l)"
echo "打印页数: $(grep "$REPORT_DATE" $PAGE_LOG | awk '{sum+=$6}END{print sum}')"
echo ""

# 2. 热门打印机
echo "2. 热门打印机 (Top 5)"
echo "----------------------------------------"
grep "$REPORT_DATE" $PAGE_LOG | awk '{print $1}' | sort | uniq -c | sort -rn | head -5
echo ""

# 3. 活跃用户
echo "3. 活跃用户 (Top 10)"
echo "----------------------------------------"
grep "$REPORT_DATE" $PAGE_LOG | awk '{print $2}' | sort | uniq -c | sort -rn | head -10
echo ""

# 4. 错误统计
echo "4. 错误统计"
echo "----------------------------------------"
grep "$REPORT_DATE" $ERROR_LOG | grep -i error | \
  sed 's/.*error: //' | cut -d: -f1 | sort | uniq -c | sort -rn | head -5
echo ""

# 5. 安全事件
echo "5. 安全事件"
echo "----------------------------------------"
auth_failures=$(grep "$REPORT_DATE" $ACCESS_LOG | grep -c "401\|403")
echo "认证失败次数: $auth_failures"
echo ""

# 6. 性能指标
echo "6. 性能指标"
echo "----------------------------------------"
echo "平均每任务页数: $(grep "$REPORT_DATE" $PAGE_LOG | awk '{sum+=$6; n++}END{if(n>0)print sum/n; else print 0}')"
echo ""

echo "=========================================="
echo "  报告生成完成"
echo "=========================================="

11.4 调试模式

11.4.1 启用调试日志

# 方法 1: 修改配置文件
sudo vim /etc/cups/cupsd.conf
# 修改 LogLevel 为 debug 或 debug2
LogLevel debug

# 重启 CUPS
sudo systemctl restart cups

# 方法 2: 使用 cupsctl 命令
sudo cupsctl --debug-logging

# 方法 3: 前台调试模式
sudo cupsd -f -c /etc/cups/cupsd.conf
# 所有日志输出到终端

11.4.2 调试日志级别

级别 说明 使用场景
none 无日志 生产环境
emerg 紧急 系统不可用
alert 警报 需要立即处理
crit 严重 严重错误
error 错误 一般错误
warn 警告 潜在问题
notice 通知 重要事件
info 信息 一般信息(默认)
debug 调试 详细调试信息
debug2 详细调试 非常详细的调试信息
# 设置调试级别
sudo cupsctl --debug-logging          # debug
sudo cupsctl --debug2-logging         # debug2

# 恢复正常日志
sudo cupsctl --no-debug-logging       # 恢复到 info

11.4.3 过滤器调试

# 测试过滤器
cupsfilter -v -m application/postscript document.pdf 2>&1

# 详细调试
cupsfilter -vv -m application/postscript document.pdf 2>&1

# 测试特定打印机
cupsfilter -d myprinter -v document.pdf 2>&1

# 查看过滤器链
cupsfilter -t application/pdf 2>&1

11.4.4 IPP 调试

# 使用 ipptool 调试 IPP 通信
ipptool -tv ipp://localhost/printers/myprinter get-printer-attributes.test

# 测试远程打印机
ipptool -tv ipp://192.168.1.100/ipp/print get-printer-attributes.test

# 测试打印任务
ipptool -tv ipp://localhost/printers/myprinter \
  -d /usr/share/cups/data/testprint \
  print-job.test

# 使用 curl 调试 IPP
curl -v -X POST \
  -H "Content-Type: application/ipp" \
  --data-binary @request.ipp \
  http://localhost:631/printers/myprinter

11.4.5 后端调试

# 测试后端发现
/usr/lib/cups/backend/socket
/usr/lib/cups/backend/ipp
/usr/lib/cups/backend/dnssd

# 测试特定后端
/usr/lib/cups/backend/socket 1 1 user "test" 1 "" /dev/null

# 查看后端输出
lpinfo -v 2>&1

11.5 性能问题排查

11.5.1 打印速度慢

可能原因

原因 检查方法 解决方案
高分辨率设置 查看打印选项 降低分辨率
大文件 检查文件大小 压缩文件
网络延迟 ping 打印机 优化网络
过滤器效率 查看日志 使用更高效的过滤器
打印机内存 打印机规格 减少每页数据量
# 检查打印任务大小
ls -lh /var/spool/cups/

# 检查网络延迟
ping -c 10 192.168.1.100

# 检查过滤器处理时间
time cupsfilter document.pdf > /dev/null

# 优化建议
# 1. 使用较低分辨率
lp -o Resolution=300dpi document.pdf

# 2. 使用灰度模式
lp -o ColorModel=Gray document.pdf

# 3. 使用原始格式(跳过过滤器)
lp -o raw document.ps

11.5.2 CUPS 服务响应慢

# 检查 CUPS 进程状态
ps aux | grep cupsd

# 检查内存使用
free -h

# 检查 CPU 使用
top -p $(pgrep cupsd)

# 检查磁盘 I/O
iostat -x 1

# 检查队列大小
lpstat -o | wc -l

# 清理旧任务
sudo cancel -a
sudo cupsctl --purge-jobs

# 限制并发任务
# 在 cupsd.conf 中设置
# MaxClients 50

11.6 高级诊断工具

11.6.1 使用 strace 调试

# 跟踪 CUPS 系统调用
sudo strace -f -p $(pgrep cupsd) -o /tmp/cups-strace.log

# 跟踪特定操作
sudo strace -e trace=open,read,write -p $(pgrep cupsd)

# 跟踪打印任务
sudo strace -f -p $(pgrep cupsd) 2>&1 | grep "myprinter"

11.6.2 使用 tcpdump 抓包

# 捕获 IPP 流量
sudo tcpdump -i eth0 port 631 -w /tmp/ipp-traffic.pcap

# 捕获网络打印流量
sudo tcpdump -i eth0 port 9100 -w /tmp/print-traffic.pcap

# 实时查看
sudo tcpdump -i eth0 port 631 -A

11.6.3 使用 Wireshark 分析

# 1. 使用 tcpdump 捕获流量
sudo tcpdump -i eth0 port 631 -w /tmp/cups.pcap

# 2. 在 Wireshark 中打开
wireshark /tmp/cups.pcap

# 3. 过滤 IPP 协议
# 过滤器: ipp

# 4. 分析 IPP 操作
# 可以看到 Print-Job, Get-Printer-Attributes 等操作

11.7 自动化监控

11.7.1 监控脚本

#!/bin/bash
# cups-monitor.sh - CUPS 监控脚本

ALERT_EMAIL="admin@example.com"
CUPS_LOG="/var/log/cups/error_log"
QUEUE_THRESHOLD=10

# 检查 CUPS 服务
if ! systemctl is-active cups > /dev/null 2>&1; then
    echo "ALERT: CUPS service is down" | mail -s "CUPS Alert" "$ALERT_EMAIL"
    systemctl restart cups
fi

# 检查打印队列
queue_count=$(lpstat -o 2>/dev/null | wc -l)
if [ "$queue_count" -gt "$QUEUE_THRESHOLD" ]; then
    echo "ALERT: Print queue has $queue_count jobs (threshold: $QUEUE_THRESHOLD)" | \
      mail -s "CUPS Queue Alert" "$ALERT_EMAIL"
fi

# 检查最近错误
recent_errors=$(tail -100 "$CUPS_LOG" | grep -i "error" | wc -l)
if [ "$recent_errors" -gt 10 ]; then
    echo "ALERT: $recent_errors errors in last 100 log entries" | \
      mail -s "CUPS Error Alert" "$ALERT_EMAIL"
fi

# 检查磁盘空间
spool_usage=$(df /var/spool/cups | tail -1 | awk '{print $5}' | sed 's/%//')
if [ "$spool_usage" -gt 90 ]; then
    echo "ALERT: Spool disk usage at ${spool_usage}%" | \
      mail -s "CUPS Disk Alert" "$ALERT_EMAIL"
fi

11.7.2 Prometheus 监控

# prometheus.yml
scrape_configs:
  - job_name: 'cups'
    static_configs:
      - targets: ['localhost:9102']
    metrics_path: /metrics

# cups-exporter 配置
# 需要安装 cups-prometheus-exporter
# pip install cups-prometheus-exporter

11.8 业务场景

11.8.1 场景一:批量打印故障

# 症状:大批量打印时打印机卡住

# 1. 暂停打印机
sudo cupsdisable myprinter

# 2. 清理队列
cancel -a myprinter

# 3. 重启打印机
sudo cupsenable myprinter

# 4. 分批打印
split -l 100 large-file.txt chunk_
for chunk in chunk_*; do
    lp -d myprinter "$chunk"
    sleep 5  # 等待 5 秒
done

11.8.2 场景二:驱动冲突

# 症状:升级系统后打印机不工作

# 1. 检查驱动
lpinfo -m | grep "旧驱动名称"

# 2. 重新安装驱动
sudo apt install --reinstall printer-driver-gutenprint

# 3. 重新配置打印机
sudo lpadmin -p myprinter -P /usr/share/ppd/new-driver.ppd

# 4. 测试打印
lp -d myprinter /usr/share/cups/data/testprint

11.8.3 场景三:网络打印中断

# 症状:网络打印机间歇性断连

# 1. 检查网络稳定性
ping -c 100 192.168.1.100 | tail -5

# 2. 配置后备后端
sudo lpadmin -p myprinter \
  -v "beh:/3/5/socket/socket://192.168.1.100:9100"

# 3. 增加超时设置
# 在 cupsd.conf 中
# JobRetryTimeout 30

# 4. 监控脚本
while true; do
    if ! ping -c 1 192.168.1.100 > /dev/null 2>&1; then
        echo "Printer offline at $(date)" >> /var/log/printer-monitor.log
    fi
    sleep 60
done

11.9 扩展阅读

资源 链接
CUPS 故障排查 https://www.cups.org/doc/troubleshooting.html
CUPS 错误代码 https://www.cups.org/doc/ipp-status-codes.html
Linux 打印故障排查 https://wiki.archlinux.org/title/CUPS/Troubleshooting
Wireshark https://www.wireshark.org/

11.10 本章小结

主题 关键要点
排查流程 症状确认 → 基本检查 → 日志分析 → 配置检查 → 解决
常见问题 打印机识别、队列卡住、打印质量、网络连接、驱动兼容
日志分析 error_log/access_log/page_log 三种日志
调试模式 LogLevel debug/debug2、cupsfilter -v、ipptool -tv
性能优化 降低分辨率、灰度模式、清理队列、优化网络
监控 自动化监控脚本、Prometheus 集成

下一章预告:我们将学习 CUPS 最佳实践,包括运维规范、监控策略、安全基线和生产环境部署。


11.11 练习题

  1. 诊断题:使用快速诊断脚本检查你的 CUPS 环境,列出发现的问题。

  2. 日志题:分析 error_log 中的错误,找出最常见的 3 种错误类型及其原因。

  3. 调试题:启用 CUPS 调试模式,执行一次打印操作,分析调试日志。

  4. 监控题:编写监控脚本,当打印队列超过 20 个任务时发送告警。

  5. 场景题:一个用户报告打印输出是乱码,请列出你的排查步骤和解决方案。