libdd_trace_obfuscation/
obfuscation_config.rs1use log::{debug, error};
5use serde::Deserialize;
6use std::{collections::HashSet, env};
7
8use libdd_common::config::parse_env;
9
10use crate::{
11 replacer::{self, ReplaceRule},
12 sql::{SqlObfuscateConfig, SqlObfuscationMode},
13};
14
15#[derive(Debug, Default, Deserialize)]
16#[serde(default, deny_unknown_fields)]
17pub struct MemcachedConfig {
18 pub enabled: bool,
19 pub keep_command: bool,
20}
21
22#[derive(Debug, Default, Deserialize)]
23#[serde(default, deny_unknown_fields)]
24pub struct CreditCardConfig {
25 pub enabled: bool,
26 pub luhn: bool,
27 pub keep_values: HashSet<String>,
28}
29
30pub type JsonStringTransformer = fn(&str) -> String;
31
32#[derive(Debug, Default, Clone, Deserialize)]
33#[serde(default, deny_unknown_fields)]
34pub struct JsonObfuscatorConfig {
35 pub enabled: bool,
36 pub keep_keys: HashSet<String>,
39 #[serde(skip)]
42 pub transform_keys: HashSet<String>,
43 #[serde(skip)]
46 pub transformer: Option<JsonStringTransformer>,
47}
48
49impl JsonObfuscatorConfig {
50 #[must_use]
51 pub fn disabled() -> Self {
52 Self {
53 enabled: false,
54 ..Default::default()
55 }
56 }
57
58 #[must_use]
59 pub fn enabled() -> Self {
60 Self {
61 enabled: true,
62 ..Default::default()
63 }
64 }
65}
66
67#[derive(Debug, Default, Deserialize)]
68#[serde(default, deny_unknown_fields)]
69pub struct RedisConfig {
70 pub enabled: bool,
71 pub remove_all_args: bool,
72}
73
74#[derive(Debug, Default, Deserialize)]
75#[serde(default, deny_unknown_fields)]
76pub struct HttpConfig {
77 pub remove_query_string: bool,
79 pub remove_paths_with_digits: bool,
80}
81
82#[derive(Debug, Default, Deserialize)]
83#[serde(default, deny_unknown_fields)]
84pub struct ObfuscationConfig {
85 pub tag_replace_rules: Option<Vec<ReplaceRule>>,
86 pub http: HttpConfig,
87 pub memcached: MemcachedConfig,
88 pub redis: RedisConfig,
89 pub valkey: RedisConfig,
90 pub credit_cards: CreditCardConfig,
91 pub sql: SqlObfuscateConfig,
92 pub elasticsearch: JsonObfuscatorConfig,
93 pub opensearch: JsonObfuscatorConfig,
94 pub mongodb: JsonObfuscatorConfig,
95}
96
97#[derive(Default)]
99pub struct StatsObfuscationConfig {
100 pub sql_obfuscation_mode: SqlObfuscationMode,
101}
102
103impl ObfuscationConfig {
104 pub fn new() -> Result<Self, Box<dyn std::error::Error>> {
110 let tag_replace_rules: Option<Vec<ReplaceRule>> = match env::var("DD_APM_REPLACE_TAGS") {
111 Ok(replace_rules_str) => match replacer::parse_rules_from_string(&replace_rules_str) {
112 Ok(res) => {
113 debug!("Successfully parsed DD_APM_REPLACE_TAGS: {res:?}");
114 Some(res)
115 }
116 Err(e) => {
117 error!("Failed to parse DD_APM_REPLACE_TAGS: {e}");
118 None
119 }
120 },
121 Err(_) => None,
122 };
123 let http_remove_query_string =
124 parse_env::bool("DD_APM_OBFUSCATION_HTTP_REMOVE_QUERY_STRING").unwrap_or(false);
125 let http_remove_path_digits =
126 parse_env::bool("DD_APM_OBFUSCATION_HTTP_REMOVE_PATHS_WITH_DIGITS").unwrap_or(false);
127 let obfuscation_redis_enabled =
128 parse_env::bool("DD_APM_OBFUSCATION_REDIS_ENABLED").unwrap_or(false);
129 let obfuscation_redis_remove_all_args =
130 parse_env::bool("DD_APM_OBFUSCATION_REDIS_REMOVE_ALL_ARGS").unwrap_or(false);
131
132 let obfuscate_memcached =
133 parse_env::bool("DD_APM_OBFUSCATION_MEMCACHED_ENABLED").unwrap_or(false);
134
135 Ok(Self {
136 tag_replace_rules,
137 http: HttpConfig {
138 remove_query_string: http_remove_query_string,
139 remove_paths_with_digits: http_remove_path_digits,
140 },
141 memcached: MemcachedConfig {
142 enabled: obfuscate_memcached,
143 keep_command: true,
144 },
145 credit_cards: CreditCardConfig {
146 enabled: true,
147 luhn: true,
148 keep_values: HashSet::new(),
149 },
150 redis: RedisConfig {
151 enabled: obfuscation_redis_enabled,
152 remove_all_args: obfuscation_redis_remove_all_args,
153 },
154 ..Default::default()
155 })
156 }
157}