Skip to content

Commit 13a558e

Browse files
committed
update server config module
1 parent 5cf45da commit 13a558e

File tree

8 files changed

+213
-149
lines changed

8 files changed

+213
-149
lines changed

scripts/stop_agent.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
#!/bin/bash
22

33
# 查找包含 ./target/release/agent 的进程并杀掉
4-
pids=$(pgrep -f "./target/release/agent")
4+
pids=$(pgrep -f "./target/x86_64-unknown-linux-gnu/release/deeptrace")
55
if [ -n "$pids" ]; then
66
echo "Killing agent process(es): $pids"
77
sudo kill -9 $pids

server/config/config.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@ ip = "xxx" # The external IP address of the host running t
66

77
# ========== agent1 configuration ==========
88
[[agents]]
9-
[agents.agent_info] # Basic agent information
10-
agent_name = "xxx" # Agent name
9+
[agents.agent] # Basic agent information
10+
name = "xxx" # Agent name
1111
user_name = "xxx" # Username for SSH login
1212
host_ip = "xxx" # Agent host IP address
1313
ssh_port = "xxx" # SSH port

server/config/full.toml

Lines changed: 74 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,42 +1,83 @@
11
[elastic] # Elasticsearch related configuration
22
elastic_password = "xxx" # Elasticsearch user password
3-
port = 9200 # Elasticsearch service port
4-
kibana_password = "xxx" # Kibana user password
5-
bulk_size = 1024 # Bulk write size
6-
request_timeout = 10 # Request timeout (seconds)
7-
agent_status_index = "agent_status" # Agent status index name
8-
username = "elastic" # Elasticsearch username
93

104
[server]
115
ip = "xxx" # The external IP address of the host running the DeepTrace server
12-
port = 7901 # DeepTrace server port
13-
path = "deeptrace/ws" # DeepTrace websocket path
6+
147

158
# ========== agent1 configuration ==========
169
[[agents]]
17-
[agents.agent_info] # Basic agent information
18-
agent_name = "xxx" # Agent name (unique identifier)
10+
[agents.agent]
11+
name = "xxx" # Agent name
1912
user_name = "xxx" # Username for SSH login
20-
host_ip = "xxx" # Agent host IP address
21-
ssh_port = "xxx" # SSH port
22-
host_password = "xxx" # Host password
23-
deeptrace_port = 52001 # DeepTrace service port
24-
workers = 16 # Number of worker threads
25-
26-
[agents.span]
27-
batch_size = 1024 # Batch size for span data
28-
29-
[agents.sender] # Data sending related configuration
30-
mem_buffer_size = 16 # Memory buffer size
31-
file_buffer_size = 32 # File buffer size
32-
file_size_limit = 1024 # File size limit
33-
batch_size = 1024 # Batch sending size
34-
35-
[agents.trace] # eBPF configuration
36-
pids = [3056354, 3056217, 3056210] # List of process PIDs to be traced
37-
38-
[agents.api] # Agent API service configuration
39-
port = 7899 # API service port
40-
address = "0.0.0.0" # API listening address
41-
workers = 1 # Number of API service threads
42-
ident = "deeptrace" # Service identifier
13+
host_ip = "xxx" # Agent host IP address
14+
ssh_port = "xxx" # SSH port
15+
host_password = "xxx" # Host password
16+
17+
[agents.metric]
18+
interval = 10
19+
sender = "metric"
20+
21+
[agents.sender.elastic.trace]
22+
# path to the file where metrics will be written
23+
node_url = "http://localhost:9200"
24+
username = "elastic"
25+
password = "***"
26+
request_timeout = 10
27+
index_name = "agent1"
28+
bulk_size = 64
29+
30+
[agents.sender.file.metric]
31+
# path to the file where metrics will be written
32+
path = "metrics.csv"
33+
rotate = true
34+
# max size in megabytes of the metrics file before it gets rotated
35+
max_size = 512
36+
# max time in days to retain old metrics files
37+
max_age = 6
38+
# rotate time in days to rotate the metrics file
39+
rotate_time = 11
40+
# data format
41+
data_format = "%Y%m%d"
42+
43+
# [sender.elastic]
44+
45+
[agents.trace]
46+
ebpf = "trace"
47+
sender = "trace"
48+
49+
[agents.trace.span]
50+
cleanup_interval = 30
51+
max_sockets = 1024
52+
53+
[agents.ebpf.trace]
54+
# 0 = off, 1 = debug, 3 = verbose, 4 = stats
55+
log_level = 1
56+
pids = [523094]
57+
max_buffered_events = 128
58+
enabled_probes = [
59+
"sys_enter_read",
60+
"sys_exit_read",
61+
"sys_enter_readv",
62+
"sys_exit_readv",
63+
"sys_enter_recvfrom",
64+
"sys_exit_recvfrom",
65+
"sys_enter_recvmsg",
66+
"sys_exit_recvmsg",
67+
"sys_enter_recvmmsg",
68+
"sys_exit_recvmmsg",
69+
70+
"sys_enter_write",
71+
"sys_exit_write",
72+
"sys_enter_writev",
73+
"sys_exit_writev",
74+
"sys_enter_sendto",
75+
"sys_exit_sendto",
76+
"sys_enter_sendmsg",
77+
"sys_exit_sendmsg",
78+
"sys_enter_sendmmsg",
79+
"sys_exit_sendmmsg",
80+
81+
"sys_exit_socket",
82+
"sys_enter_close"
83+
]

server/config/k8s_tag_map.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{}

server/config/parse_config.py

Lines changed: 84 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
1+
2+
import copy
13
import toml
24

35
config_path = './config/config.toml'
6+
default_path = './config/full.toml'
47

58
def read_db_config():
69
with open(config_path, "r") as f:
@@ -14,65 +17,91 @@ def read_db_config():
1417

1518
return elastic_pwd, server_ip
1619

20+
def _deep_merge(default: dict, override: dict) -> dict:
21+
"""
22+
递归合并:override 中的值覆盖 default。list/primitive 类型直接替换。
23+
"""
24+
result = copy.deepcopy(default) if default is not None else {}
25+
for k, v in (override or {}).items():
26+
if k in result and isinstance(result[k], dict) and isinstance(v, dict):
27+
result[k] = _deep_merge(result[k], v)
28+
else:
29+
result[k] = copy.deepcopy(v)
30+
return result
31+
1732
def load_agents():
1833
from controller.src.agent import Agent
34+
35+
# 读取默认模板和用户配置
36+
default_conf = {}
37+
38+
with open(default_path, 'r') as f:
39+
default_conf = toml.load(f)
40+
1941
with open(config_path, 'r') as f:
20-
config = toml.load(f)
21-
elastic_config = config.get('elastic', {})
22-
if 'port' not in elastic_config:
23-
elastic_config['port'] = 9200
24-
if 'username' not in elastic_config:
25-
elastic_config['username'] = 'elastic'
26-
if 'request_timeout' not in elastic_config:
27-
elastic_config['request_timeout'] = 10
28-
if 'bulk_size' not in elastic_config:
29-
elastic_config['bulk_size'] = 10
30-
if 'agent_status_index' not in elastic_config:
31-
elastic_config['agent_status_index'] = 'agent_status'
32-
server_config = config.get('server', {})
42+
user_conf = toml.load(f)
43+
44+
45+
server_config = user_conf.get('server', {})
46+
47+
# elastic defaults (保留 elastic 部分默认项)
48+
elastic_config = user_conf.get('elastic', {})
49+
elastic_config['address'] = server_config.get('ip', 'localhost')
50+
elastic_config.setdefault('port', 9200)
51+
elastic_config.setdefault('username', 'elastic')
52+
elastic_config.setdefault('request_timeout', 10)
53+
elastic_config.setdefault('bulk_size', 10)
54+
3355
agent_dict = {}
34-
if 'path' not in server_config:
35-
server_config['path'] = 'deeptrace/ws'
36-
if 'port' not in server_config:
37-
server_config['port'] = 7901
38-
for agent_config in config.get('agents', []):
39-
if 'deeptrace_port' not in agent_config['agent_info']:
40-
agent_config['agent_info']['deeptrace_port'] = 52001
41-
if 'workers' not in agent_config['agent_info']:
42-
agent_config['agent_info']['workers'] = 16
43-
if 'span' not in agent_config:
44-
agent_config['span'] = {'batch_size': 10}
45-
if 'sender' not in agent_config:
46-
agent_config['sender'] = {'index_name': f"spans_{agent_config['agent_info']['agent_name']}",
47-
'mem_buffer_size': 1,
48-
'file_buffer_size': 32,
49-
'file_size_limit': 1024,
50-
'batch_size': 10}
51-
else:
52-
if 'index_name' not in agent_config['sender']:
53-
agent_config['sender']['index_name'] = f"spans_{agent_config['agent_info']['agent_name']}"
54-
if 'mem_buffer_size' not in agent_config['sender']:
55-
agent_config['sender']['mem_buffer_size'] = 1
56-
if 'file_buffer_size' not in agent_config['sender']:
57-
agent_config['sender']['file_buffer_size'] = 32
58-
if 'file_size_limit' not in agent_config['sender']:
59-
agent_config['sender']['file_size_limit'] = 1024
60-
if 'batch_size' not in agent_config['sender']:
61-
agent_config['sender']['batch_size'] = 1024
62-
if 'trace' not in agent_config:
63-
agent_config['trace'] = {'pids': []}
64-
if 'api' not in agent_config:
65-
agent_config['api'] = {'port': 7899, 'address': '0.0.0.0', 'workers': 1, 'ident': 'deeptrace'}
66-
else:
67-
if 'port' not in agent_config['api']:
68-
agent_config['api']['port'] = 7899
69-
if 'address' not in agent_config['api']:
70-
agent_config['api']['address'] = '0.0.0.0'
71-
if 'workers' not in agent_config['api']:
72-
agent_config['api']['workers'] = 1
73-
if 'ident' not in agent_config['api']:
74-
agent_config['api']['ident'] = 'deeptrace'
75-
agent_dict[agent_config['agent_info']['agent_name']] = Agent(agent_config, elastic_config, server_config)
56+
57+
# 选择默认模板中的第一个 agents 项作为模板(如果存在)
58+
default_agents = default_conf.get('agents', [])
59+
default_template = default_agents[0] if default_agents else {}
60+
61+
for user_item in user_conf.get('agents', []):
62+
# 用户项必须包含 agent 区块
63+
if 'agent' not in user_item:
64+
raise KeyError(f"每个 [[agents]] 项必须包含 [agents.agent] 区块,问题项:{user_item}")
65+
66+
# 合并:基于默认模板合并用户项(用户覆盖默认)
67+
merged_item = _deep_merge(default_template, user_item)
68+
69+
raw_agent = merged_item.get('agent', {})
70+
# 名称支持 agent_name 或 name
71+
agent_name = raw_agent.get('agent_name') or raw_agent.get('name')
72+
host_password = raw_agent.get('host_password')
73+
host_ip = raw_agent.get('host_ip')
74+
75+
# 必填字段检查
76+
if not agent_name:
77+
raise KeyError(f"agents 配置缺少必填字段 agent_name/name: {raw_agent}")
78+
if not host_password:
79+
raise KeyError(f"agents 配置缺少必填字段 host_password: {raw_agent}")
80+
if not host_ip:
81+
raise KeyError(f"agents 配置缺少必填字段 host_ip: {raw_agent}")
82+
83+
# 构造 agent_info(使用合并后的值)
84+
agent_info = {
85+
'agent_name': agent_name,
86+
'host_password': host_password,
87+
'host_ip': host_ip,
88+
}
89+
if 'user_name' in raw_agent:
90+
agent_info['user_name'] = raw_agent['user_name']
91+
if 'ssh_port' in raw_agent:
92+
try:
93+
agent_info['ssh_port'] = int(raw_agent['ssh_port'])
94+
except Exception:
95+
agent_info['ssh_port'] = raw_agent['ssh_port']
96+
97+
# 组装 agent_config:从合并后的 item 中保留存在的区块(metric/sender/trace/ebpf/span/api)
98+
agent_config = {'agent_info': agent_info}
99+
for key in ('metric', 'sender', 'trace', 'ebpf', 'api', 'span'):
100+
if key in merged_item:
101+
agent_config[key] = merged_item[key]
102+
103+
agent_dict[agent_name] = Agent(agent_config, elastic_config, server_config)
104+
76105
return agent_dict
77106

78107
def get_server_mode():

server/config/test.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
from config.parse_config import load_agents
2+
3+
4+
5+
if __name__ == "__main__":
6+
agents = load_agents()
7+
for name, agent in agents.items():
8+
print(f"Agent Name: {name}")
9+
print(f' server_config: {agent.server_config}')
10+
print(f' agent_config: {agent.agent_config}')
11+
print(f' elastic_config: {agent.elastic_config}')
12+
print(f' code_path: {agent.code_path}')
13+
print(f' agent_info: {agent.agent_info}')
14+
print(f"Total agents loaded: {len(agents)}")

0 commit comments

Comments
 (0)