15 个不稳定版本 (3 个重大变更)
0.4.5 | 2023 年 8 月 21 日 |
---|---|
0.4.4 | 2023 年 6 月 7 日 |
0.3.2 | 2023 年 5 月 26 日 |
0.2.1 | 2022 年 10 月 6 日 |
0.1.1 | 2021 年 11 月 30 日 |
#299 in 数据库接口
38KB
777 行
Relastic
受 Serilog 启发的简单 Rust 库,用于应用程序范围内的日志记录
- 应用程序范围内的日志
- 将日志发布到 Elastic 以使用 Kibana 访问
目的
从 Rust 应用程序将日志记录到 Elastic
目标用户
所有人。在评估涉及的风险之前,不要在生产环境中使用。
主要技术
- Rust
- NixShell
可在以下位置获得
crates.io (relastic)
要求
- Rust 或 Nix 和 Direnv(这将为您安装 rust)
更多文档
cargo doc --open
或 docs.rs
本地测试
cargo test
在主文件夹中运行测试
已知问题
- 由于发送者是非阻塞的,需要在关闭发送者之前显式等待。
- 不支持从代码中创建/更新模板
- 使用 HashMap 映射值
- 我们可能不需要将发送者放在 RwLock 后面(尽管 RwLock 对读取者没有限制)
用法
fn main() {
let elastic_config = match elastic_config::ElasticConfig::new() {
Ok(x) => x,
Err(err) => panic!("Elastic not/improperly configured: {:?}", err),
};
log::setup_elastic_log(
elastic_config,
100,
);
/* ... */
log::flush();
}
与 Rocket.rs 一起使用
Rocket 默认情况下不允许在它的 Tokio
运行时中运行阻塞服务。它确实有一个功能可以在异步中运行阻塞任务,但日志服务应该优先于它;如果 Rocket 发生 panic,则记录器应该在应用程序终止之前记录此信息。
以下是设置 relastic 与 Rocket 的方法
fn main() {
let elastic_config = match elastic_config::ElasticConfig::new() {
Ok(x) => x,
Err(err) => panic!("Elastic not/improperly configured: {:?}", err),
};
log::setup_elastic_log(
elastic_config,
100,
);
// Create multi-threaded tokio runtime for rocket
let rt = tokio::runtime::Runtime::new().unwrap();
rt.block_on(async {
rocket_main().await;
});
log::flush();
}
这也使得我们不必依赖于 Rocket 特定的依赖项。
在开发环境中将日志记录到控制台
在开发过程中,您可能希望通过将日志记录到控制台来简化日志记录
use intility_cloud_lib::env_tools::{get_env, get_env_enum, Error};
use relastic::log::{self, ElasticConfig, LogEnvironment};
use std::collections::HashMap;
fn load_if_prod(name: &str, env_type: &LogEnvironment) -> Result<String, Error> {
match env_type {
LogEnvironment::Development => Ok(String::with_capacity(0)),
LogEnvironment::Production => get_env(name),
}
}
pub fn get_config() -> Result<ElasticConfig, Error> {
let env_type = get_env_enum::<LogEnvironment>("APPLICATION_ENVIRONMENT")?;
let username = load_if_prod("ELASTIC_USERNAME", &env_type)?;
let password = load_if_prod("ELASTIC_PASSWORD", &env_type)?;
let url = load_if_prod("ELASTIC_URL", &env_type)?;
let environment_string = get_env_enum::<LogEnvironment>("APPLICATION_ENVIRONMENT")?;
let application_name = get_env("APPLICATION_NAME")?;
Ok(ElasticConfig {
username,
password,
url,
environment: environment_string,
application_name,
})
}
pub fn get_config_or_log_and_panic() -> ElasticConfig {
match get_config() {
Ok(x) => x,
Err(err) => {
log::fatal(
"Elastic config is missing or is misconfigured: {err}",
HashMap::from([("err", format!("{}", err))]),
);
panic!("{}", err)
}
}
}
fn main() {
let elastic_config = get_config_or_log_and_panic();
if elastic_config.environment == LogEnvironment::Production {
log::setup_elastic_log(elastic_config.clone(), 100);
} else {
log::setup_console_log()
}
/* ... */
log::flush();
}
这样,在本地工作时,您实际上不必设置任何环境变量。
如何记录
在记录日志时,您可以直接使用日志函数,或者可以使用包含的宏来减少所需样板代码的数量。
pub fn my_fn()
{
// Logging with a macro
log_information!("Got the following message: {message}", "Hello world");
// Logging with a function:
log::information(
"Got the following message: {message}",
HashMap::from([
("message", "Hello World!".to_string())
])
);
}
贡献
欢迎您报告错误、贡献代码或打开问题。
依赖项
~5–19MB
~301K SLoC