与人类交流

请务必先阅读教程中的 关于 CLI 输出的章节。该章节介绍了如何将输出写入终端,而本章将讨论输出什么

一切正常时

即使一切正常,报告应用程序的进度也很有用。在这些消息中尽量做到信息丰富且简洁。不要在日志中使用过于专业的术语。请记住:应用程序没有崩溃,因此用户没有理由查找错误。

最重要的是,在沟通风格上保持一致。使用相同的词缀和句子结构,使日志易于浏览。

尝试让您的应用程序输出讲述一个关于它在做什么以及它如何影响用户的故事。这可能包括显示所涉及步骤的时间线,甚至包括进度条和长时间运行操作的指示器。用户在任何时候都不应该感到应用程序正在做一些他们无法理解的神秘的事情。

难以判断发生了什么时

在沟通非正常状态时,保持一致性很重要。一个日志记录过多的应用程序,如果不遵循严格的日志记录级别,提供的日志信息与一个不记录日志的应用程序一样多,甚至更少。

因此,定义事件和与其相关的消息的严重程度很重要;然后为它们使用一致的日志级别。这样,用户可以通过--verbose标志或环境变量(如RUST_LOG)来选择自己的日志记录量。

常用的log crate 定义了以下级别(按严重程度递增排序)

  • trace
  • debug
  • info
  • warning
  • error

info视为默认日志级别是一个好主意。将其用于,嗯,信息性输出。(一些倾向于更安静输出风格的应用程序可能默认情况下只显示警告和错误。)

此外,始终使用类似的词缀和句子结构来编写日志消息是一个好主意,这样可以轻松使用grep之类的工具来筛选它们。一条消息应该提供足够的上下文,使其在筛选后的日志中仍然有用,但同时也不要过于冗长。

示例日志语句

error: could not find `Cargo.toml` in `/home/you/project/`
=> Downloading repository index
=> Downloading packages...

以下日志输出取自 wasm-pack

 [1/7] Adding WASM target...
 [2/7] Compiling to WASM...
 [3/7] Creating a pkg directory...
 [4/7] Writing a package.json...
 > [WARN]: Field `description` is missing from Cargo.toml. It is not necessary, but recommended
 > [WARN]: Field `repository` is missing from Cargo.toml. It is not necessary, but recommended
 > [WARN]: Field `license` is missing from Cargo.toml. It is not necessary, but recommended
 [5/7] Copying over your README...
 > [WARN]: origin crate has no README
 [6/7] Installing WASM-bindgen...
 > [INFO]: wasm-bindgen already installed
 [7/7] Running WASM-bindgen...
 Done in 1 second

出现恐慌时

一个经常被遗忘的方面是,您的程序在崩溃时也会输出一些内容。在 Rust 中,“崩溃”通常是“恐慌”(即,与“操作系统终止了进程”相比,“受控崩溃”)。默认情况下,当出现恐慌时,“恐慌处理程序”会将一些信息打印到控制台。

例如,如果您使用cargo new --bin foo创建一个新的二进制项目,并将fn main的内容替换为panic!("Hello World"),那么在运行程序时,您将看到以下内容

thread 'main' panicked at 'Hello, world!', src/main.rs:2:5
note: Run with `RUST_BACKTRACE=1` for a backtrace.

这对您,开发人员来说是有用的信息。(令人惊讶的是:程序崩溃是因为您main.rs文件中的第 2 行)。但对于没有访问源代码的用户来说,这并没有什么价值。事实上,这很可能只会让人困惑。这就是为什么添加一个自定义恐慌处理程序是一个好主意,它可以提供更多面向最终用户的输出。

有一个库可以做到这一点,叫做 human-panic。要将其添加到您的 CLI 项目中,您需要导入它并在main函数的开头调用setup_panic!()

use human_panic::setup_panic;

fn main() {
   setup_panic!();

   panic!("Hello world")
}

现在将显示一条非常友好的消息,并告诉用户他们可以做什么

Well, this is embarrassing.

foo had a problem and crashed. To help us diagnose the problem you can send us a crash report.

We have generated a report file at "/var/folders/n3/dkk459k908lcmkzwcmq0tcv00000gn/T/report-738e1bec-5585-47a4-8158-f1f7227f0168.toml". Submit an issue or email with the subject of "foo Crash Report" and include the report as an attachment.

- Authors: Your Name <[email protected]>

We take privacy seriously, and do not perform any automated error collection. In order to improve the software, we rely on people to submit reports.

Thank you kindly!