15 个版本 (破坏性)
0.10.0 | 2024 年 3 月 11 日 |
---|---|
0.9.0 | 2023 年 12 月 18 日 |
0.8.0 | 2023 年 9 月 26 日 |
0.7.2 | 2023 年 5 月 24 日 |
0.1.0 | 2020 年 4 月 13 日 |
#5 in #google-cloud
39,218 每月下载量
在 8 个crate中(5个直接使用) 使用
44KB
708 行
tracing-stackdriver
tracing
是一个基于异步 await
点之间可能嵌套的 Span
的上下文,发出 Event
的范围结构和诊断系统。这些属性使 tracing
非常适合与 Google Cloud Operations Suite 结构化日志(以前称为 Stackdriver)一起使用。
此crate提供了一个用于与 tracing
Registry
一起使用的 Layer
,该层将 tracing
Span 和事件格式化为适合通过 jsonPayload
字段由 Google Operations Logging 消耗的适当结构的 JSON。这包括以下行为和增强:
- 所有事件的
rfc3339
格式的时间戳 - 从
tracing
Level
导出的severity
(在LogSeverity
格式) - 从事件
target
导出的target
- 在
span
键下包含 Span 名称和自定义字段 - 自动嵌套以
http_request.
为前缀的事件字段 - 自动嵌套以
labels.
为前缀的事件字段,重写为 特殊字段。 - 自动将
insert_id
重写为 特殊字段。 - 自动将所有字段键转换为驼峰命名法(例如
field_name
->fieldName
,或field.name
->fieldName
) - 支持
valuable
,包括一个HttpRequest
辅助struct
- 支持由 OpenTelemetry Span 和 跟踪 IDs 衍生的 Cloud Trace。
示例
基本设置
use tracing_subscriber::{layer::SubscriberExt, Registry};
fn main() {
let stackdriver = tracing_stackdriver::layer(); // writes to std::io::Stdout
let subscriber = Registry::default().with(stackdriver);
tracing::subscriber::set_global_default(subscriber).expect("Could not set up global logger");
}
自定义写入位置
use tracing_subscriber::{layer::SubscriberExt, Registry};
fn main() {
let make_writer = || std::io::Stderr;
let stackdriver = tracing_stackdriver::layer().with_writer(make_writer); // writes to std::io::Stderr
let subscriber = Registry::default().with(stackdriver);
tracing::subscriber::set_global_default(subscriber).expect("Could not set up global logger");
}
带有 httpRequest
字段
查看所有可用字段 这里。
// requires working global setup (see above examples)
use hyper::Request;
fn handle_request(request: Request) {
let method = &request.method();
let uri = &request.uri();
tracing::info!(
http_request.request_method = %method,
http_request.request_url = %uri,
"Request received"
);
// jsonPayload formatted as:
// {
// "time": "some-timestamp"
// "severity": "INFO",
// "httpRequest": {
// "requestMethod": "GET",
// "requestUrl": "/some/url/from/request"
// },
// "message": "Request received"
// }
}
带有 labels
字段
将字符串化的标签映射到 logging.googleapis.com/labels
特殊字段 的键/值映射。有关 labels
的更多信息,请参阅 这里。
// requires working global setup (see above examples)
fn main() {
tracing::info!(
labels.thread_count = 3,
labels.is_production = true,
labels.note = "A short note",
"Application starting"
);
// jsonPayload formatted as:
// {
// "time": "some-timestamp"
// "message": "Application starting",
// "logging.googleapis.com/labels": {
// "threadCount": "3",
// "isProduction": "true",
// "note": "A short note",
// }
// }
}
带有 insert_id
字段
将字符串化的 insert_id
映射到 logging.googleapis.com/insertId
特殊字段。有关 insertId
的更多信息,请参阅 这里。这是一个可选字段,因为如果省略了 insert_id
,日志 API 会为该字段分配其自己的唯一标识符。
// requires working global setup (see above examples)
fn main() {
tracing::info!(
insert_id = 1234,
"Application starting"
);
// jsonPayload formatted as:
// {
// "time": "some-timestamp"
// "message": "Application starting",
// "logging.googleapis.com/insertId": "1234"
// }
}
带有更具体的 LogSeverity
级别
Google 支持的严重性级别略不同于 tracing
。将 tracing
级别自动映射到 LogSeverity
级别,但您可以通过使用提供的 LogSeverity
级别和 severity
键来自定义级别,超出了 tracing
级别和 LogSeverity
级别的交集。
use tracing_stackdriver::LogSeverity;
fn main() {
// requires working global setup (see above examples)
tracing::info!(severity = %LogSeverity::Notice, "Application starting");
// jsonPayload formatted as:
// {
// "time": "some-timestamp"
// "severity": "NOTICE",
// "message": "Application starting"
// }
}
带有 valuable
支持
tracing_stackdriver
通过 tracing
的 不稳定的 valuable
支持 支持深层嵌套的结构化日志。此外,可以使用从库中导出的 HttpRequest
辅助结构体生成 httpRequest
字段,以更好地进行字段编译时检查。
要启用 valuable
支持,请使用 valuable
功能标志,并使用以下命令编译您的项目:RUSTFLAGS="--cfg tracing_unstable"
。
// requires working global setup (see above examples)
use hyper::Request;
use tracing_stackdriver::HttpRequest;
use valuable::Valuable;
#[derive(Valuable)]
struct StructuredLog {
service: &'static str,
handler: &'static str
}
fn handle_request(request: Request) {
let http_request = HttpRequest {
request_method: request.method().into(),
request_url: request.uri().into(),
..Default::default()
};
let structured_log = StructuredLog {
service: "request_handlers",
handler: "handle_request",
};
tracing::info!(
http_request = http_request.as_value(),
structured_log = structured_log.as_value(),
"Request received"
);
// jsonPayload formatted as:
// {
// "time": "some-timestamp"
// "severity": "INFO",
// "httpRequest": {
// "requestMethod": "GET",
// "requestUrl": "/some/url/from/request"
// },
// "structuredLog": {
// "service": "request_handlers",
// "handler": "handle_request"
// },
// "message": "Request received"
// }
}
带有 Cloud Trace 支持
tracing_stackdriver
支持通过 tracing_opentelemetry 与 Cloud Trace 和 OpenTelemetry 集成,并输出 特殊的 Cloud Trace LogEntry
字段 以进行跟踪采样和日志关联。
要启用云跟踪支持,您需要启用 opentelemetry
功能标志,并将 CloudTraceConfiguration
提供给层的 with_cloud_trace
方法。
use tracing_stackdriver::CloudTraceConfiguration;
fn main() {
// You may want to configure the `tracing_opentelemetry` layer to suit your needs,
// including the use of an additional tracer or exporter.
// See `tracing_opentelemetry`'s doc for details.
let opentelemetry = tracing_opentelemetry::layer();
let stackdriver = tracing_stackdriver::layer()
.with_cloud_trace(CloudTraceConfiguration { project_id: "my-project-id" });
let subscriber = tracing_subscriber::Registry::default()
.with(opentelemetry)
.with(stackdriver);
// set up the root span to trigger Span/Trace ID generation
let root = tracing::info_span!("root");
let _root = root.enter();
tracing::info!("Application starting");
// jsonPayload formatted as:
// {
// "time": "some-timestamp"
// "severity": "INFO",
// "message": "Application starting",
// "logging.googleapis.com/spanId": "0000000000000000",
// "logging.googleapis.com/trace":"projects/my-project-id/traces/0679686673a"
// }
}
包含源位置
默认情况下,tracing_stackdriver
在发出的 LogEntry
上的特殊 SourceLocation
组合字段 中包含 tracing
事件的源位置。此行为可以通过层的 with_source_location
方法进行配置。
fn main() {
// Source Locations are enabled by default, so they must be disabled by setting the configuration
// to "false" using with_source_location()
let stackdriver = tracing_stackdriver::layer().with_source_location(false);
let subscriber = tracing_subscriber::Registry::default().with(stackdriver);
tracing::subscriber::set_global_default(subscriber).expect("Could not set up global logger");
// tracing events from this point on will have their source location omitted
}
依赖关系
~2.6-5MB
~97K SLoC