# 处理崩溃（Panic）

URL: https://caijiao.org/pingora/handling_panics
Source: docs/pingora/handling_panics.md
Description: 学习如何在 Pingora 中处理运行时崩溃（panic），确保服务稳定并记录错误日志。

在 Rust 中，**panic** 表示程序遇到不可恢复的错误。Pingora 提供了机制来捕获和处理 panic，避免服务因单个错误而完全中断。

## 默认行为

当 Pingora 内部发生 panic 时：

- 当前线程会终止；
- 异步任务可能被取消；
- 主服务进程通常会记录错误并继续运行其他线程（依赖 Tokio 异步运行时）。

## 捕获 panic

可以通过 Rust 提供的 `std::panic::set_hook` 自定义 panic 处理逻辑：

```rust
use std::panic;

fn main() {
    panic::set_hook(Box::new(|info| {
        eprintln!("Pingora 捕获到 panic: {:?}", info);
        // 可以在这里写日志、统计或报警
    }));

    // 启动 Pingora 服务
    let mut server = pingora::Server::new(None).unwrap();
    server.bootstrap();
    server.run_forever(pingora::http_proxy_service(None)).unwrap();
}
````

## 日志记录

Pingora 会将 panic 信息写入日志文件中（如果配置了 `logging.file`），方便运维排查问题。

配置示例：

```yaml
logging:
  level: error
  file: /var/log/pingora.log
```

## 进程恢复

即使某个线程 panic，Pingora 的主进程通常不会退出：

- Tokio 异步运行时会继续运行其他任务；
- 可通过 **supervisor** 或 **systemd** 监控主进程，实现自动重启。

## 最佳实践

1. **捕获关键区域的 panic**：在自定义过滤器或处理函数中使用 `catch_unwind`。
2. **记录详细日志**：包含线程信息、调用栈和上下文状态。
3. **结合 systemd 或守护进程**：确保主进程崩溃时自动重启。
4. **避免 panic**：尽量在业务逻辑中返回 `Result` 或 `Option`，将错误通过类型系统处理，而非依赖 panic。

---

通过合理捕获和记录 panic，Pingora 可以在遇到不可预期错误时保持服务稳定，同时便于后续调试和运维管理。
