Skip to main content

frontend/service_config/
otlp.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 common_base::readable_size::ReadableSize;
16use common_stat::get_total_memory_readable;
17use serde::{Deserialize, Serialize};
18
19const DEFAULT_TRACE_INGEST_CHUNK_SIZE: usize = 512;
20const MIN_TRACE_AUX_CACHE_SIZE: ReadableSize = ReadableSize::mb(32);
21
22#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)]
23#[serde(default)]
24pub struct OtlpOptions {
25    pub enable: bool,
26    /// Maximum spans per trace ingest chunk. Set to 0 to disable splitting.
27    pub trace_ingest_chunk_size: usize,
28    /// Estimated memory budget for cached trace service/operation keys per frontend,
29    /// shared across all catalogs, schemas, and trace tables. Set to 0 to disable caching.
30    /// Defaults to 1/128 of the host or pod memory limit, with a minimum of 32MiB.
31    /// Uses 32MiB if memory detection is unavailable.
32    /// Excludes cache and allocator overhead; shared table names are charged per entry.
33    pub trace_aux_cache_size: ReadableSize,
34    /// Whether to synthesize the `greptime_otel_resource_info` descriptor
35    /// table from the resource attributes of OTLP metrics, so metrics-only
36    /// services reach the semantic graph. Off by default: it creates and
37    /// writes a table the user did not send.
38    pub experimental_enable_resource_info: bool,
39}
40
41impl Default for OtlpOptions {
42    fn default() -> Self {
43        Self {
44            enable: true,
45            trace_ingest_chunk_size: DEFAULT_TRACE_INGEST_CHUNK_SIZE,
46            trace_aux_cache_size: default_trace_aux_cache_size(get_total_memory_readable()),
47            experimental_enable_resource_info: false,
48        }
49    }
50}
51
52fn default_trace_aux_cache_size(memory: Option<ReadableSize>) -> ReadableSize {
53    memory
54        .map(|size| size / 128)
55        .unwrap_or_default()
56        .max(MIN_TRACE_AUX_CACHE_SIZE)
57}
58
59#[cfg(test)]
60mod tests {
61    use super::*;
62
63    #[test]
64    fn test_default_trace_aux_cache_size() {
65        for (memory, expected) in [
66            (None, ReadableSize::mb(32)),
67            (Some(ReadableSize(0)), ReadableSize::mb(32)),
68            (Some(ReadableSize::gb(1)), ReadableSize::mb(32)),
69            (Some(ReadableSize::gb(4)), ReadableSize::mb(32)),
70            (Some(ReadableSize::gb(8)), ReadableSize::mb(64)),
71            (Some(ReadableSize::gb(64)), ReadableSize::mb(512)),
72        ] {
73            assert_eq!(default_trace_aux_cache_size(memory), expected);
74        }
75    }
76
77    #[test]
78    fn test_otlp_options() {
79        let default = OtlpOptions::default();
80        assert!(default.enable);
81        assert_eq!(default.trace_ingest_chunk_size, 512);
82        assert_eq!(
83            default.trace_aux_cache_size,
84            default_trace_aux_cache_size(get_total_memory_readable())
85        );
86        assert!(!default.experimental_enable_resource_info);
87
88        let options: OtlpOptions = toml::from_str("enable = false").unwrap();
89        assert!(!options.enable);
90        assert_eq!(options.trace_aux_cache_size, default.trace_aux_cache_size);
91        assert_eq!(
92            options.trace_ingest_chunk_size,
93            DEFAULT_TRACE_INGEST_CHUNK_SIZE
94        );
95
96        let options: OtlpOptions = toml::from_str("trace_ingest_chunk_size = 0").unwrap();
97        assert!(options.enable);
98        assert_eq!(options.trace_ingest_chunk_size, 0);
99
100        let serialized = toml::to_string(&options).unwrap();
101        assert_eq!(toml::from_str::<OtlpOptions>(&serialized).unwrap(), options);
102
103        for (value, size) in [("0", ReadableSize(0)), ("\"1MiB\"", ReadableSize::mb(1))] {
104            let options: OtlpOptions =
105                toml::from_str(&format!("trace_aux_cache_size = {value}")).unwrap();
106            assert_eq!(options.trace_aux_cache_size, size);
107            let serialized = toml::to_string(&options).unwrap();
108            assert_eq!(toml::from_str::<OtlpOptions>(&serialized).unwrap(), options);
109        }
110    }
111}