vector/
generate_schema.rs1use std::{fs, path::PathBuf};
4
5use clap::Parser;
6use serde_json::{Value, json};
7use vector_common::internal_event::{CounterName, GaugeName, HistogramName};
8use vector_lib::configurable::schema::generate_root_schema;
9
10use crate::config::ConfigBuilder;
11
12#[derive(Parser, Debug)]
13#[command(rename_all = "kebab-case")]
14pub struct Opts {
16 #[arg(short, long)]
18 pub(crate) output_path: Option<PathBuf>,
19}
20
21fn metric_enum_schema<T: vector_lib::configurable::Configurable + 'static>() -> Value {
22 generate_root_schema::<T>()
23 .map(|s| serde_json::to_value(s).unwrap_or(Value::Null))
24 .unwrap_or(Value::Null)
25}
26
27#[allow(clippy::print_stdout, clippy::print_stderr)]
29pub fn cmd(opts: &Opts) -> exitcode::ExitCode {
30 match generate_root_schema::<ConfigBuilder>() {
31 Ok(config_schema) => {
32 let mut schema = serde_json::to_value(config_schema)
34 .expect("rendering root schema to JSON should not fail");
35
36 schema["_metric_schemas"] = json!({
39 "counters": metric_enum_schema::<CounterName>(),
40 "histograms": metric_enum_schema::<HistogramName>(),
41 "gauges": metric_enum_schema::<GaugeName>(),
42 });
43
44 let json = serde_json::to_string_pretty(&schema)
45 .expect("rendering root schema to JSON should not fail");
46
47 if let Some(output_path) = &opts.output_path {
48 if output_path.exists() {
49 eprintln!("Error: Output file {output_path:?} already exists");
50 return exitcode::CANTCREAT;
51 }
52
53 return match fs::write(output_path, json) {
54 Ok(_) => {
55 println!("Schema successfully written to {output_path:?}");
56 exitcode::OK
57 }
58 Err(e) => {
59 eprintln!("Error writing to file {output_path:?}: {e:?}");
60 exitcode::IOERR
61 }
62 };
63 } else {
64 println!("{json}");
65 }
66 exitcode::OK
67 }
68 Err(e) => {
69 eprintln!("error while generating schema: {e:?}");
70 exitcode::SOFTWARE
71 }
72 }
73}