#log-line #logging #syslog #inject #stdout #pass #level

ceethane

一个日志包,旨在简化向日志行注入和传递上下文信息的操作

1个不稳定版本

使用旧的Rust 2015

0.1.0 2018年3月25日

#19 in #log-line

MIT/Apache

18KB
274

Ceethane

Ceethane是Rust中实现上下文感知(也称为键值)日志的一种方式。它的日志行首先可由机器读取。它与Rust语言基金会日志API有很大不同。相反,它专注于提供一个可注入到底层的logger trait,它解决的问题是在函数调用过程中逐步构建日志的上下文。

默认情况下,Ceethane通过cee日志格式与syslog通信,这是大多数日志聚合器(包括Elasticsearch)能够解析的。它还以JSON格式向STDOUT输出日志,这对于大多数12因素应用(包括heroku)来说应该是足够的。

用法

首先,在Cargo.toml中配置ceethane,如下所示

[dependencies]
ceethane = "0.1"
# Optional, but needed for convenience macros
serde_json="1.0"

然后,将其添加到rust文件中,如下所示

#[macro_use]
extern crate ceethane;

#[macro_use]
extern crate serde_json;

use ceethane::logger::Logger;
use ceethane::Level;

fn main() {
    // ll stands for 'local logger'
    let mut ll = ceethane::default(Level::Info);
    ll = ll.kvs(logf!(
            "user_id" => 1337,
    ));

    ll.info("hello");
}

然后,运行cargo run,你会得到以下输出(时间戳可能会有所不同)

{"msg":"hello","user_id":1337,"level":"info","syslog_program":"basic","time":"2018-03-24T13:57:18.000+00:00"}

使用ceethane的一个好方法是安装humanlog并运行cargo run | humanlog。Humanlog将解析JSON输出为易于阅读的格式。

日志级别

Ceethane logger提供了6个日志级别(从低到高)

  • debug
  • info
  • warn
  • error
  • fatal
  • panic
#[macro_use]
extern crate ceethane;

#[macro_use]
extern crate serde_json;

use ceethane::logger::Logger;
use ceethane::Level;

fn main() {
    let mut ll = ceethane::default(Level::Info);
    ll = ll.kvs(logf!(
            "user_id" => 1337,
    ));

    ll.debug("hello");
    ll.info("hello");
    ll.warn("hello");
    ll.error("hello");
    ll.fatal("hello");
    ll.panic("hello");
}

panic级别是特殊的,因为它会在调用时使进程崩溃。

KVs

Ceethane logger上的kvs方法正是库提供实用程序的地方。从上面的基本示例中,你可以看到它允许向Ceethane发出的结构化日志中添加字段。重要的是要注意,kvs返回一个新的logger实例,并将前一个实例的所有值复制过去。这意味着可以使用它来随着应用程序的进展逐步构建上下文。

这一点的玩具示例可以在fake_web_app.rs中看到。

快速浏览我们的用法

在我们的主函数中,我们创建了一个logger并将其放入我们的web服务器中


fn main() {
    let mut ll = ceethane::default(Level::Info);
    ll = ll.kvs(logf!(
            "environment" => "development",
    ));

    ll.info("program booted");

    WebServer::new(ll).put_score(32, 32);
}

当web服务器接收到请求时,我们添加请求的上下文并记录

fn put_score(&mut self, user_id: i32, score: i32) -> Result<(), Error> {
    let ll = &self.ll;                                                  ```
    let mut ll = ll.kvs(logf!(
        "user_id" => user_id,
        "action" => "put_score",
    ));
    ll.info("started");

当结果从数据库返回时,根据是否出现错误,也进行日志记录。

    let res = self.db.put_user_score(&mut ll, user_id, score);
    match res {
        Ok(_) => {
            ll.info("succeeded");
            Ok(())
        },
        Err(e) => {
            ll.err(&e).error("couldn't persist user score to DB");
            ll.info("failed");
            Err(e)
        }
    }

注意:我们将本地记录器传递给数据库结构体,并对其进行记录。通常你不会这样做,因为在最低级别进行记录是不推荐的,因为数据库通常更像是“库”而不是应用程序代码。但通常应用程序也有多个应用程序代码层,所以 ¯_()_/¯

错误

err方法用于向日志行添加错误上下文,例如。

#[macro_use]
extern crate ceethane;

#[macro_use]
extern crate serde_json;

use std::io::{Error, ErrorKind};

use ceethane::logger::Logger;
use ceethane::Level;

fn main() {
    let mut ll = ceethane::default(Level::Info);
    ll = ll.kvs(logf!(
            "user_id" => 1337,
    ));

    let err = Error::new(ErrorKind::Other, "oh no!");

    ll.err(&err).error("something went wrong doing IO");
}

将打印

{"err":"Error { repr: Custom(Custom { kind: Other, error: StringError(\"oh no!\") }) }","user_id":1337,"msg":"something went wrong doing IO","level":"error","syslog_program":"err","time":"2018-03-24T14:45:12.000+00:00"}

系统日志配置

默认情况下,ceethane会将系统日志帧输出到系统的默认系统日志套接字。它支持标准环境变量以覆盖此设置

环境变量 默认值 用法
SYSLOG_SOCKET /dev/log在Linux上 哪个文件描述符应该用作系统日志数据报的目标套接字
SYSLOG_PROGRAM 最后一个由“/”分隔的部分 $0 记录器应该报告给系统日志的程序名称

依赖关系

~1–1.7MB
~31K SLoC