rsflow/
config.rs

1//! 配置模块
2//!
3//! 提供流处理引擎的配置管理功能
4
5use serde::{Deserialize, Serialize};
6use toml;
7
8use crate::{
9    Error,
10    buffer::BufferConfig,
11    input::InputConfig,
12    output::OutputConfig,
13    processor::ProcessorConfig,
14    stream::StreamConfig,
15};
16
17/// 配置文件格式
18#[derive(Debug, Clone, Copy)]
19pub enum ConfigFormat {
20    /// YAML格式
21    YAML,
22    /// JSON格式
23    JSON,
24    /// TOML格式
25    TOML,
26}
27
28/// 日志配置
29#[derive(Debug, Clone, Serialize, Deserialize)]
30pub struct LoggingConfig {
31    /// 日志级别
32    pub level: String,
33    /// 是否输出到文件
34    pub file_output: Option<bool>,
35    /// 日志文件路径
36    pub file_path: Option<String>,
37}
38
39/// 引擎配置
40#[derive(Debug, Clone, Serialize, Deserialize)]
41pub struct EngineConfig {
42    /// 流配置
43    pub streams: Vec<StreamConfig>,
44    /// 全局HTTP服务器配置(可选)
45    pub http: Option<HttpServerConfig>,
46    /// 指标收集配置(可选)
47    pub metrics: Option<MetricsConfig>,
48    /// 日志配置(可选)
49    pub logging: Option<LoggingConfig>,
50}
51
52/// HTTP服务器配置
53#[derive(Debug, Clone, Serialize, Deserialize)]
54pub struct HttpServerConfig {
55    /// 监听地址
56    pub address: String,
57    /// 是否启用CORS
58    pub cors_enabled: bool,
59    /// 是否启用健康检查端点
60    pub health_enabled: bool,
61}
62
63/// 指标收集配置
64#[derive(Debug, Clone, Serialize, Deserialize)]
65pub struct MetricsConfig {
66    /// 是否启用指标收集
67    pub enabled: bool,
68    /// 指标类型(prometheus, statsd等)
69    pub type_name: String,
70    /// 指标前缀
71    pub prefix: Option<String>,
72    /// 指标标签(键值对)
73    pub tags: Option<std::collections::HashMap<String, String>>,
74}
75
76impl EngineConfig {
77    /// 从文件加载配置
78    pub fn from_file(path: &str) -> Result<Self, Error> {
79        let content = std::fs::read_to_string(path)
80            .map_err(|e| Error::Config(format!("无法读取配置文件: {}", e)))?;
81        
82        // 根据文件后缀名判断格式
83        if let Some(format) = get_format_from_path(path) {
84            match format {
85                ConfigFormat::YAML => {
86                    return serde_yaml::from_str(&content)
87                        .map_err(|e| Error::Config(format!("YAML解析错误: {}", e)));
88                },
89                ConfigFormat::JSON => {
90                    return serde_json::from_str(&content)
91                        .map_err(|e| Error::Config(format!("JSON解析错误: {}", e)));
92                },
93                ConfigFormat::TOML => {
94                    return toml::from_str(&content)
95                        .map_err(|e| Error::Config(format!("TOML解析错误: {}", e)));
96                },
97            }
98        }
99        
100        // 如果无法从文件名判断格式,则尝试所有格式
101        Self::from_string(&content)
102    }
103    
104    /// 从字符串加载配置
105    pub fn from_string(content: &str) -> Result<Self, Error> {
106        // 尝试解析为YAML
107        if let Ok(config) = serde_yaml::from_str(content) {
108            return Ok(config);
109        }
110        
111        // 尝试解析为TOML
112        if let Ok(config) = toml::from_str(content) {
113            return Ok(config);
114        }
115        
116        // 尝试解析为JSON
117        if let Ok(config) = serde_json::from_str(content) {
118            return Ok(config);
119        }
120        
121        // 所有格式都解析失败
122        Err(Error::Config(format!("无法解析配置文件,支持的格式为:YAML、TOML、JSON")))
123    }
124    
125    /// 保存配置到文件
126    pub fn save_to_file(&self, path: &str) -> Result<(), Error> {
127        let content = toml::to_string_pretty(self)
128            .map_err(|e| Error::Config(format!("无法序列化配置: {}", e)))?;
129        
130        std::fs::write(path, content)
131            .map_err(|e| Error::Config(format!("无法写入配置文件: {}", e)))
132    }
133}
134
135/// 创建默认配置
136pub fn default_config() -> EngineConfig {
137    EngineConfig {
138        streams: vec![],
139        http: Some(HttpServerConfig {
140            address: "0.0.0.0:8000".to_string(),
141            cors_enabled: false,
142            health_enabled: true,
143        }),
144        metrics: Some(MetricsConfig {
145            enabled: true,
146            type_name: "prometheus".to_string(),
147            prefix: Some("benthos".to_string()),
148            tags: None,
149        }),
150        logging: Some(LoggingConfig {
151            level: "info".to_string(),
152            file_output: None,
153            file_path: None,
154        }),
155    }
156}
157
158/// 从文件路径获取配置格式
159fn get_format_from_path(path: &str) -> Option<ConfigFormat> {
160    let path = path.to_lowercase();
161    if path.ends_with(".yaml") || path.ends_with(".yml") {
162        Some(ConfigFormat::YAML)
163    } else if path.ends_with(".json") {
164        Some(ConfigFormat::JSON)
165    } else if path.ends_with(".toml") {
166        Some(ConfigFormat::TOML)
167    } else {
168        None
169    }
170}