< 返回版块

mike 发表于 2022-02-21 10:29

traceing 库默认的是utc时区,日志打印出来都是8小时之前的,有没有大佬知道怎么更改traceing 库输出日志的时区,示例代码如下: 好像只要修改with_timer就可以了

 tracing_subscriber::fmt()
    .with_writer(mk_writer)
    .with_max_level(Level::TRACE)
    .with_timer(tracing_subscriber::fmt::time::time())
    .init();

我在源码里找到了这个例子 https://github.com/tokio-rs/tracing/blob/master/tracing-subscriber/src/fmt/time/time_crate.rs 110 行

看文档的提示好像按照下面的写法就可以了,但是这样写会报找不到 LocalTime in `fmt::time,


   use tracing_subscriber::fmt::{self, time::LocalTime};
   use time::macros::format_description;


   let timer = LocalTime::new(format_description!("[hour]:[minute]:[second]"));
    tracing_subscriber::fmt()
    .with_writer(mk_writer)
    .with_max_level(Level::TRACE)
    .with_timer(timer)
    .init();

这是我的 cargo.toml

[package]
name = "trace-example"
version = "0.1.0"
edition = "2021"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
axum = "0.4.5"
tokio = { version = "1.0", features = ["full"] }
tracing = "0.1.*"
tracing-subscriber = "0.3.8"
tracing-appender = "0.2"
tracing-log = "0.1.2"
log ="0.4.14"
tower-http = { version = "0.2.0", features = ["trace"] }
time = { version = "0.3", features = ["formatting", "macros"] }

有没有大佬指点一下

评论区

写评论
acfuns 2024-09-18 21:05

tracing-subscriber 是支持修改本地时间的 至少在2021前,只有一个实现方法就是采用time的Localtime来解决, 但问题来了 tracing里时间格式如果不是unix,在线程就会出现 这是因为在unix系统上,时间箱拒绝在没有--cfg unsound_local_offset的情况下获取本地偏移量,这会变成一个错误,该错误会通过格式冒泡,直到到达tracing_subscriber::fmt::FmtLayer:: on_event() 只会丢弃错误并且不记录任何内容。这是很令人惊讶的错误,没有考虑到时区不同的情况,tracing作者意识到这一点就有人提了pr,把OffsetTime格式添加进去,在没有unsound_local_offset的情况下可以使用偏移时区 接下说一下解决办法:2024年

use tracing::Level;
use tracing_subscriber::fmt::time::OffsetTime;

fn main() {
    // 初始化日志记录器,设置最大日志级别为DEBUG,并使用本地时间格式化日志时间戳
    tracing_subscriber::fmt()
        .with_max_level(Level::DEBUG)
        .with_timer(OffsetTime::local_rfc_3339().expect("could not get local offset!"))
        .init();
tracing = "0.1.40"
tracing-subscriber = { version = "0.3.18", features = ["local-time"] }

tracing = "0.1.40" tracing-subscriber = { version = "0.3.18", features = ["local-time"] } ok,此贴完毕,并且一点不要去使用LocalTime::rfc_3330() 他没去做适配,虽然你发现也能用 只是你的日志都在主线程里,你单开一个线程,在这个线程里使用日志,就会出现 .

作者 mike 2022-02-22 18:56

好的,谢谢大佬指点,爱你呦~

--
👇
dlhxzb: 恐怕要放到.cargo\config.toml
https://doc.rust-lang.org/nightly/cargo/reference/config.html#configuration

dlhxzb 2022-02-22 14:32

恐怕要放到.cargo\config.toml
https://doc.rust-lang.org/nightly/cargo/reference/config.html#configuration

作者 mike 2022-02-22 10:40

大佬霸气,我试了一下这样也是可以了,学到了,谢谢大佬~ 请教大佬,RUSTFLAGS 这个玩意还没见过,能不能加到配置里面?

--
👇
dlhxzb: 我是CentOS7.5,cmd: RUSTFLAGS="--cfg unsound_local_offset" cargo run

作者 mike 2022-02-22 10:38

大佬威武,这样确实linux 下就没问题了,学到了,谢谢大佬~

--
👇
c5soft: 换一种玩法,时区手工指定,format_description用宏, Linux应该就没问题了:

use time::{macros::format_description, UtcOffset};
    use tracing_subscriber::{fmt::time::OffsetTime, EnvFilter};
    let local_time = OffsetTime::new(
        UtcOffset::from_hms(8, 0, 0).unwrap(),
        format_description!("[year]-[month]-[day] [hour]:[minute]:[second].[subsecond digits:3]"),
    );

    tracing_subscriber::fmt()
        .with_env_filter(EnvFilter::from_default_env())
        .with_timer(local_time)
        .init();

Cargo.toml依赖:

tracing = "0.1.31"
tracing-subscriber = { version = "0.3.9", features = [
    "env-filter",
    "time",
    "local-time",
] }
time = { version = "0.3.7", features = ["macros"] }
dlhxzb 2022-02-22 08:47

我是CentOS7.5,cmd: RUSTFLAGS="--cfg unsound_local_offset" cargo run

c5soft 2022-02-21 19:32

换一种玩法,时区手工指定,format_description用宏, Linux应该就没问题了:

use time::{macros::format_description, UtcOffset};
    use tracing_subscriber::{fmt::time::OffsetTime, EnvFilter};
    let local_time = OffsetTime::new(
        UtcOffset::from_hms(8, 0, 0).unwrap(),
        format_description!("[year]-[month]-[day] [hour]:[minute]:[second].[subsecond digits:3]"),
    );

    tracing_subscriber::fmt()
        .with_env_filter(EnvFilter::from_default_env())
        .with_timer(local_time)
        .init();

Cargo.toml依赖:

tracing = "0.1.31"
tracing-subscriber = { version = "0.3.9", features = [
    "env-filter",
    "time",
    "local-time",
] }
time = { version = "0.3.7", features = ["macros"] }
作者 mike 2022-02-21 19:17

大佬你是不是再windows 下编译的,我在windows下不加 RUSTFLAGS="-cfg unsound_local_offset" 编译也成功了

19:11:24 DEBUG trace: listening on 0.0.0.0:3000 19:11:24 TRACE mio::poll: registering event source with poller: token=Token(0), interests=READABLE | WRITABLE

不过也是在rockylinux8.5 下编译不显示时间,我等会回家再换个系统试试,可能是rockylinx8.5这个系统太新了 哈哈哈,我回家试试centos8.2

--
👇
dlhxzb: 试了下你的代码,好像没什么问题。。

17:57:32 DEBUG tracing_test: listening on 0.0.0.0:3000
17:57:32 TRACE mio::poll: registering event source with poller: token=Token(1), interests=READABLE | WRITABLE

作者 mike 2022-02-21 19:08

感谢大佬,这个方法可以的,我在windows 下运行成功了 2022-02-21 19:01:11.752 DEBUG trace_example: listening on 0.0.0.0:3000 2022-02-21 19:01:11.757 TRACE mio::poll: registering event source with poller: token=Token(0), interests=READABLE | WRITABL

不过我在rockylinx8.5 下编译失败了,Result::unwrap() thread 'main' panicked at 'called Result::unwrap() on an Err value: IndeterminateOffset', src/main.rs:38:47 可能跟操作系统有关,我再研究下 。。。

--
👇
c5soft: main.rs中这样写:

 use time::{format_description, UtcOffset};
    use tracing_subscriber::fmt::time::OffsetTime;
    let format = "[year]-[month]-[day] [hour]:[minute]:[second].[subsecond digits:3]";

    tracing_subscriber::fmt()
        .with_timer(OffsetTime::new(
            UtcOffset::current_local_offset().unwrap(),
            format_description::parse(format).unwrap(),
        ))
        .init();

Cargo.toml中这样写:

tracing = "0.1.31"
tracing-subscriber = { version = "0.3.9", features = [
    "env-filter",
    "time",
    "local-time",
] }
time = "0.3.7"

日期与时间格式看这里

作者 mike 2022-02-21 18:58

大佬你是把它放到环境变量里export RUSTFLAGS="-cfg unsound_local_offset" cargo r 还是 cargo run RUSTFLAGS="-cfg unsound_local_offset" cargo r 这两种我都试了日志能出来,时间是unknown time 。。。 。

--
👇
dlhxzb: 试了下你的代码,好像没什么问题。。

17:57:32 DEBUG tracing_test: listening on 0.0.0.0:3000
17:57:32 TRACE mio::poll: registering event source with poller: token=Token(1), interests=READABLE | WRITABLE

c5soft 2022-02-21 17:10

加上环境变量rust_log识别:

 use time::{format_description, UtcOffset};
    use tracing_subscriber::{fmt::time::OffsetTime, EnvFilter};
    let format = "[year]-[month]-[day] [hour]:[minute]:[second].[subsecond digits:3]";

    tracing_subscriber::fmt()
        .with_env_filter(EnvFilter::from_default_env())
        .with_timer(OffsetTime::new(
            UtcOffset::current_local_offset().unwrap(),
            format_description::parse(format).unwrap(),
        ))
        .init();

dlhxzb 2022-02-21 17:07

试了下你的代码,好像没什么问题。。

17:57:32 DEBUG tracing_test: listening on 0.0.0.0:3000
17:57:32 TRACE mio::poll: registering event source with poller: token=Token(1), interests=READABLE | WRITABLE

c5soft 2022-02-21 16:57

输出效果:

2022-02-21 16:47:20.994  INFO tiberius::client::connection: Performing a TLS handshake
2022-02-21 16:47:20.995  WARN tiberius::client::connection: Trusting the server certificate without validation.
2022-02-21 16:47:21.030  INFO tiberius::client::connection: TLS handshake successful
2022-02-21 16:47:21.033  INFO tiberius::tds::stream::token: Database change from 'gxcw60' to 'master'
2022-02-21 16:47:21.033  INFO tiberius::tds::stream::token: 已将数据库上下文更改为 'gxcw60'。
2022-02-21 16:47:21.033  INFO tiberius::tds::stream::token: SQL collation change from None to None
2022-02-21 16:47:21.034  INFO tiberius::tds::stream::token: Microsoft SQL Server version 3256025099

c5soft 2022-02-21 16:56

main.rs中这样写:

 use time::{format_description, UtcOffset};
    use tracing_subscriber::fmt::time::OffsetTime;
    let format = "[year]-[month]-[day] [hour]:[minute]:[second].[subsecond digits:3]";

    tracing_subscriber::fmt()
        .with_timer(OffsetTime::new(
            UtcOffset::current_local_offset().unwrap(),
            format_description::parse(format).unwrap(),
        ))
        .init();

Cargo.toml中这样写:

tracing = "0.1.31"
tracing-subscriber = { version = "0.3.9", features = [
    "env-filter",
    "time",
    "local-time",
] }
time = "0.3.7"

日期与时间格式看这里

作者 mike 2022-02-21 16:28

试了一下编译能通过,不过日志的时间还是消失了前面的时间变成 unknown time 我把我的全部代码贴一下,大佬有兴趣可以试下

use axum::{
    body::Bytes,
    http::{HeaderMap, Request},
    response::{Html, Response},
    routing::get,
    Router,
};
use std::{hash::Hasher, io::Write, net::SocketAddr, time::Duration};
use tower_http::trace::TraceLayer;

use time::macros::format_description;
use tracing::Level;
use tracing_appender::rolling;
use tracing_subscriber::fmt::{time::FormatTime, writer::MakeWriterExt};

use tracing_subscriber::fmt::time::LocalTime;
// use time::format_description;
// use tracing_subscriber::fmt::time::Utc;
use time::OffsetDateTime;


use time::UtcOffset;

#[tokio::main]
async fn main() {


    let info_appender = rolling::daily("/opt/logs", "info");
    let (info_appender, _info_guard) = tracing_appender::non_blocking(info_appender);

    let warn_appender = rolling::daily("/opt/logs", "warn");
    let (warn_appender, _warn_guard) = tracing_appender::non_blocking(warn_appender);

    let mk_writer = info_appender
        .with_min_level(Level::INFO)
        .and(warn_appender.with_max_level(Level::WARN))
        .and(std::io::stdout.with_max_level(tracing::Level::TRACE));


    // let timer = LocalTime::new(format_description!("[hour]:[minute]:[second]"));
    // dbg!(timer.clone());
    //let time = OffsetDateTime::now_local();
    // let timer = LocalTime::new(time::format_description::well_known::Rfc3339);
    let timer = LocalTime::new(format_description!("[hour]:[minute]:[second]"));
    
    //time::UtcOffset::from_hms(8, 0, 0)
    //let timer = LocalTime::new(UtcOffset::from_hms(8, 0, 0));
    tracing_subscriber::fmt()
        .with_writer(mk_writer)
        .with_max_level(Level::TRACE)
        .with_timer(timer)
        .init();

    let app = Router::new()
        .route("/", get(handler))
        // `TraceLayer` is provided by tower-http so you have to add that as a dependency.
        // It provides good defaults but is also very customizable.
        //
        // See https://docs.rs/tower-http/0.1.1/tower_http/trace/index.html for more details.
        .layer(TraceLayer::new_for_http());

    // If you want to customize the behavior using closures here is how
    //
    // This is just for demonstration, you don't need to add this middleware twice

    // run it
    let addr = SocketAddr::from(([0, 0, 0, 0], 3000));
    tracing::debug!("listening on {}", addr);
    axum::Server::bind(&addr)
        .serve(app.into_make_service())
        .await
        .unwrap();
}

async fn handler() -> Html<&'static str> {
    tracing::debug!("hello info");
    // log::info!("hello env log");
    Html("<h1>Hello, World!</h1>")
}




--
👇
dlhxzb: Sorry, 试试这个RUSTFLAGS="--cfg unsound_local_offset" cargo r

dlhxzb 2022-02-21 16:15

Sorry, 试试这个RUSTFLAGS="--cfg unsound_local_offset" cargo r

作者 mike 2022-02-21 15:50

cargo build 加上这个不认--cfg unsound_local_offset error: Found argument '--cfg' which wasn't expected, or isn't valid in this context 太痛苦了,tarceing 库应该挺常用的吧,感觉时区挺常见的,为什么改个时区好难啊...

--
👇
dlhxzb: > 我觉得应该跟cfg 有关,但是不知道cfg 咋用是在方法前加上 #[cfg(unsound_local_offset)] 宏还是啥

按doc说的这可能是个编译选项,在cargo build后面加--cfg unsound_local_offset

dlhxzb 2022-02-21 15:14

我觉得应该跟cfg 有关,但是不知道cfg 咋用是在方法前加上 #[cfg(unsound_local_offset)] 宏还是啥

按doc说的这可能是个编译选项,在cargo build后面加--cfg unsound_local_offset

作者 mike 2022-02-21 14:37

大佬,我是这样写的,好像不行,init 方法会报错,但是我看了init 里面包含了finish 方法 ``rust

tracing_subscriber::fmt() .with_writer(mk_writer) .with_max_level(Level::TRACE) .with_timer(UtcOffset::from_hms(8, 0, 0).unwrap()) .init();


--  
👇  
langzi.me: 
let subscriber = FmtSubscriber::builder()
        .with_writer( std::io::stdout)
        .with_timer(UtcOffset::from_hms(8, 0, 0).unwrap())
        .finish();
作者 mike 2022-02-21 14:04

大佬威武,引入 features = ["local-time"]后确实编译通过了,不过,时间却显示不出来,显示是

DEBUG trace_example: listening on 0.0.0.0:3000

我觉得应该跟cfg 有关,但是不知道cfg 咋用是在方法前加上 #[cfg(unsound_local_offset)] 宏还是啥

👇
dlhxzb: Struct tracing_subscriber::fmt::time::LocalTime

This is supported on crate feature fmt and crate feature std and unsound_local_offset and crate feature time and crate feature local-time only.

加features试试,类似

tracing-subscriber = { version = "0.3", features = ["local-time"] }

还有这个编译--cfg可能也得注意

Warning: The time crate must be compiled with --cfg unsound_local_offset in order to use local timestamps. When this cfg is not enabled, local timestamps cannot be recorded, and events will be logged without timestamps. Alternatively, OffsetTime can log with a local offset if it is initialized early.

0.2的时候用过ChronoLocal还没这么麻烦

1 2 共 23 条评论, 2 页