mirror of
https://github.com/fawney19/Aether.git
synced 2026-09-01 17:00:21 +08:00
refactor: 拆分 gateway 单体为独立 crate,新增 systemd 部署方案
将 gateway 内部的 model-fetch、provider-transport、scheduler-core、 usage-runtime、video-tasks-core 模块提取为独立 crate;重构 gateway 内部模块结构(state/router/cache/data/query 等);移除大量遗留模块 文件;新增 systemd 二进制部署骨架及相关文档;更新前端 usage 相关 API 和组件。
This commit is contained in:
@@ -9,8 +9,11 @@ description = "Shared runtime/bootstrap helpers for Aether Rust services"
|
||||
[dependencies]
|
||||
async-stream.workspace = true
|
||||
axum = { version = "0.8" }
|
||||
chrono.workspace = true
|
||||
futures-util.workspace = true
|
||||
redis.workspace = true
|
||||
serde_json.workspace = true
|
||||
sha2.workspace = true
|
||||
thiserror.workspace = true
|
||||
tokio.workspace = true
|
||||
tracing.workspace = true
|
||||
|
||||
@@ -2,7 +2,7 @@ use crate::config::ServiceRuntimeConfig;
|
||||
use crate::error::RuntimeBootstrapError;
|
||||
|
||||
pub fn init_service_runtime(config: ServiceRuntimeConfig) -> Result<(), RuntimeBootstrapError> {
|
||||
crate::tracing::init_tracing(config)?;
|
||||
crate::tracing::init_tracing(config.clone())?;
|
||||
crate::metrics::init_metrics(config);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
use crate::observability::ServiceObservabilityConfig;
|
||||
use crate::observability::{FileLoggingConfig, LogDestination, ServiceObservabilityConfig};
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub struct ServiceRuntimeConfig {
|
||||
pub service_name: &'static str,
|
||||
pub default_log_filter: &'static str,
|
||||
@@ -21,6 +21,26 @@ impl ServiceRuntimeConfig {
|
||||
self
|
||||
}
|
||||
|
||||
pub const fn with_log_destination(mut self, log_destination: LogDestination) -> Self {
|
||||
self.observability.log_destination = log_destination;
|
||||
self
|
||||
}
|
||||
|
||||
pub fn with_file_logging(mut self, file_logging: FileLoggingConfig) -> Self {
|
||||
self.observability.file_logging = Some(file_logging);
|
||||
self
|
||||
}
|
||||
|
||||
pub fn with_node_role(mut self, node_role: impl Into<String>) -> Self {
|
||||
self.observability.node_role = Some(node_role.into());
|
||||
self
|
||||
}
|
||||
|
||||
pub fn with_instance_id(mut self, instance_id: impl Into<String>) -> Self {
|
||||
self.observability.instance_id = Some(instance_id.into());
|
||||
self
|
||||
}
|
||||
|
||||
pub const fn with_metrics_namespace(mut self, metrics_namespace: &'static str) -> Self {
|
||||
self.observability.metrics_namespace = metrics_namespace;
|
||||
self
|
||||
|
||||
@@ -7,6 +7,7 @@ mod error;
|
||||
pub mod metrics;
|
||||
mod observability;
|
||||
pub mod queue;
|
||||
pub mod redaction;
|
||||
pub mod shutdown;
|
||||
pub mod task;
|
||||
mod tracing;
|
||||
@@ -23,9 +24,14 @@ pub use distributed::{
|
||||
};
|
||||
pub use error::RuntimeBootstrapError;
|
||||
pub use metrics::{prometheus_response, service_up_sample, MetricKind, MetricLabel, MetricSample};
|
||||
pub use observability::ServiceObservabilityConfig;
|
||||
pub use observability::{
|
||||
FileLoggingConfig, LogDestination, LogRotation, ServiceObservabilityConfig,
|
||||
};
|
||||
pub use queue::{
|
||||
bounded_queue, BoundedQueueReceiver, BoundedQueueSender, QueueSendError, QueueSnapshot,
|
||||
};
|
||||
pub use redaction::{summarize_text_payload, TextPayloadSummary};
|
||||
pub use shutdown::wait_for_shutdown_signal;
|
||||
pub use tracing::{init_reloadable_tracing, LogFormat, LogReloader};
|
||||
pub use tracing::{
|
||||
init_reloadable_service_tracing, init_reloadable_tracing, LogFormat, LogReloader,
|
||||
};
|
||||
|
||||
@@ -1,9 +1,57 @@
|
||||
use crate::tracing::LogFormat;
|
||||
use std::path::PathBuf;
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
pub enum LogDestination {
|
||||
Stdout,
|
||||
File,
|
||||
Both,
|
||||
}
|
||||
|
||||
impl LogDestination {
|
||||
pub const fn needs_file_sink(self) -> bool {
|
||||
matches!(self, Self::File | Self::Both)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
pub enum LogRotation {
|
||||
Hourly,
|
||||
Daily,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub struct FileLoggingConfig {
|
||||
pub dir: PathBuf,
|
||||
pub rotation: LogRotation,
|
||||
pub retention_days: u64,
|
||||
pub max_files: usize,
|
||||
}
|
||||
|
||||
impl FileLoggingConfig {
|
||||
pub fn new(
|
||||
dir: impl Into<PathBuf>,
|
||||
rotation: LogRotation,
|
||||
retention_days: u64,
|
||||
max_files: usize,
|
||||
) -> Self {
|
||||
Self {
|
||||
dir: dir.into(),
|
||||
rotation,
|
||||
retention_days,
|
||||
max_files,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub struct ServiceObservabilityConfig {
|
||||
pub log_format: LogFormat,
|
||||
pub metrics_namespace: &'static str,
|
||||
pub log_destination: LogDestination,
|
||||
pub file_logging: Option<FileLoggingConfig>,
|
||||
pub node_role: Option<String>,
|
||||
pub instance_id: Option<String>,
|
||||
}
|
||||
|
||||
impl ServiceObservabilityConfig {
|
||||
@@ -11,6 +59,30 @@ impl ServiceObservabilityConfig {
|
||||
Self {
|
||||
log_format,
|
||||
metrics_namespace,
|
||||
log_destination: LogDestination::Stdout,
|
||||
file_logging: None,
|
||||
node_role: None,
|
||||
instance_id: None,
|
||||
}
|
||||
}
|
||||
|
||||
pub const fn with_log_destination(mut self, log_destination: LogDestination) -> Self {
|
||||
self.log_destination = log_destination;
|
||||
self
|
||||
}
|
||||
|
||||
pub fn with_file_logging(mut self, file_logging: FileLoggingConfig) -> Self {
|
||||
self.file_logging = Some(file_logging);
|
||||
self
|
||||
}
|
||||
|
||||
pub fn with_node_role(mut self, node_role: impl Into<String>) -> Self {
|
||||
self.node_role = Some(node_role.into());
|
||||
self
|
||||
}
|
||||
|
||||
pub fn with_instance_id(mut self, instance_id: impl Into<String>) -> Self {
|
||||
self.instance_id = Some(instance_id.into());
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
36
crates/aether-runtime/src/redaction.rs
Normal file
36
crates/aether-runtime/src/redaction.rs
Normal file
@@ -0,0 +1,36 @@
|
||||
use std::fmt::Write as _;
|
||||
|
||||
use sha2::{Digest, Sha256};
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub struct TextPayloadSummary {
|
||||
pub bytes: usize,
|
||||
pub sha256: String,
|
||||
}
|
||||
|
||||
pub fn summarize_text_payload(text: &str) -> TextPayloadSummary {
|
||||
let digest = Sha256::digest(text.as_bytes());
|
||||
let mut sha256 = String::with_capacity(digest.len() * 2);
|
||||
for byte in digest {
|
||||
write!(&mut sha256, "{byte:02x}").expect("writing to string should not fail");
|
||||
}
|
||||
TextPayloadSummary {
|
||||
bytes: text.len(),
|
||||
sha256,
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::summarize_text_payload;
|
||||
|
||||
#[test]
|
||||
fn summarizes_text_payload_without_exposing_content() {
|
||||
let summary = summarize_text_payload("secret-body");
|
||||
assert_eq!(summary.bytes, 11);
|
||||
assert_eq!(
|
||||
summary.sha256,
|
||||
"7c3029502007b2beae470d090221f0a8f7708be361be4662f4b649426e5767b3"
|
||||
);
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user