cmd/options.rs
1// Copyright 2023 Greptime Team
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15use clap::Parser;
16use common_config::Configurable;
17use common_options::plugin_options::PluginOptionsDeserializer;
18use common_runtime::global::RuntimeOptions;
19use plugins::PluginOptions;
20use plugins::options::PluginOptionsDeserializerImpl;
21use serde::{Deserialize, Serialize};
22use serde_json::Value;
23
24#[derive(Parser, Default, Debug, Clone)]
25pub struct GlobalOptions {
26 #[clap(long, value_name = "LOG_DIR")]
27 #[arg(global = true)]
28 pub log_dir: Option<String>,
29
30 #[clap(long, value_name = "LOG_LEVEL")]
31 #[arg(global = true)]
32 pub log_level: Option<String>,
33
34 #[cfg(feature = "tokio-console")]
35 #[clap(long, value_name = "TOKIO_CONSOLE_ADDR")]
36 #[arg(global = true)]
37 pub tokio_console_addr: Option<String>,
38}
39
40// TODO(LFC): Move logging and tracing options into global options, like the runtime options.
41/// All the options of GreptimeDB.
42#[derive(Clone, Debug, Default, Serialize, Deserialize, PartialEq)]
43#[serde(default)]
44pub struct GreptimeOptions<T> {
45 /// The runtime options.
46 pub runtime: RuntimeOptions,
47 /// The plugin options.
48 ///
49 /// Deserialized leniently via [`deserialize_plugin_options`]: plugin
50 /// options not recognized by the current build are dropped (with a deferred
51 /// warning) instead of aborting startup, while malformed payloads for known
52 /// variants still error.
53 #[serde(default, deserialize_with = "deserialize_plugin_options")]
54 pub plugins: Vec<PluginOptions>,
55
56 /// The options of each component (like Datanode or Standalone) of GreptimeDB.
57 #[serde(flatten)]
58 pub component: T,
59}
60
61impl<T> Configurable for GreptimeOptions<T>
62where
63 T: Configurable,
64{
65 fn env_list_keys() -> Option<&'static [&'static str]> {
66 T::env_list_keys()
67 }
68
69 fn env_tagged_seq_keys() -> Option<&'static [&'static str]> {
70 T::env_tagged_seq_keys()
71 }
72}
73
74/// A serde `deserialize_with` helper that parses the `plugins` field leniently.
75///
76/// It delegates to the plugin crate's deserializer (`PluginOptionsDeserializerImpl`),
77/// which knows the recognized variants: unknown options are dropped while
78/// malformed known options still error. Keeping the variant-aware logic in the
79/// `plugins` crate avoids duplicating it and avoids introducing a new symbol on
80/// the replaceable `plugins` crate.
81fn deserialize_plugin_options<'de, D>(deserializer: D) -> Result<Vec<PluginOptions>, D::Error>
82where
83 D: serde::Deserializer<'de>,
84{
85 let values = Vec::<Value>::deserialize(deserializer)?;
86 if values.is_empty() {
87 return Ok(vec![]);
88 }
89 let payload = serde_json::to_string(&values).map_err(serde::de::Error::custom)?;
90 PluginOptionsDeserializerImpl
91 .deserialize(&payload)
92 .map_err(serde::de::Error::custom)
93}
94
95/// Emits the plugin options that were dropped during config loading (because
96/// they were not recognized by the current build) as warnings.
97///
98/// Config loading runs before the global tracing subscriber is installed, so
99/// the warnings are buffered and must be flushed once logging is initialized.
100/// Each server's `build` method calls this right after initializing logging.
101pub(crate) fn flush_dropped_plugin_warnings() {
102 let tags = common_options::plugin_options::take_dropped_plugin_warnings();
103 for tag in tags {
104 common_telemetry::warn!(
105 "Ignoring unrecognized plugin option `{tag}` in the config; \
106 it likely belongs to a plugin that is not compiled into this build."
107 );
108 }
109}