1use opcua_types::DateTime;
10
11use crate::{
12 comms::transport::{Transport, TransportState},
13 config,
14 diagnostics::ServerDiagnostics,
15 server,
16 state::ServerState,
17 subscriptions::subscriptions,
18};
19
20#[derive(Serialize)]
21pub struct ServerMetrics {
22 pub server: Server,
23 pub diagnostics: ServerDiagnostics,
24 pub config: Option<config::ServerConfig>,
25 pub connections: Vec<Connection>,
26 pub runtime_components: Vec<String>,
27}
28
29#[derive(Serialize)]
30pub struct Server {
31 pub start_time: String,
32 pub uptime_ms: i64,
33}
34
35#[derive(Serialize)]
36pub struct Connection {
37 pub sessions: Vec<Session>,
38 pub client_address: String,
41 pub transport_state: String,
42}
43
44#[derive(Serialize)]
45pub struct Session {
46 pub id: String,
47 pub session_activated: bool,
48 pub session_terminated: bool,
49 pub session_terminated_at: String,
50 pub subscriptions: subscriptions::Metrics,
51}
52
53impl Default for ServerMetrics {
54 fn default() -> Self {
55 Self {
57 server: Server {
58 start_time: String::new(),
59 uptime_ms: 0,
60 },
61 diagnostics: ServerDiagnostics::default(),
62 config: None,
63 connections: Vec::new(),
64 runtime_components: Vec::new(),
65 }
66 }
67}
68
69impl ServerMetrics {
70 pub fn new() -> ServerMetrics {
71 Self::default()
72 }
73
74 pub fn set_server_info(&mut self, server: &server::Server) {
75 let server_state = server.server_state();
76 let config = {
77 let server_state = trace_read_lock!(server_state);
78 server_state.config.clone()
79 };
80 let mut config = {
81 let config = trace_read_lock!(config);
82 config.clone()
83 };
84 config.user_tokens.clear();
86 config.user_tokens.insert(
87 String::new(),
88 config::ServerUserToken {
89 user: String::from("User identity tokens have been removed"),
90 pass: None,
91 x509: None,
92 thumbprint: None,
93 },
94 );
95 self.config = Some(config);
96 }
97
98 pub fn update_from_server_state(&mut self, server_state: &ServerState) {
100 let start_time = &server_state.start_time;
101 let now = DateTime::now();
102
103 self.server.start_time = start_time.as_chrono().to_rfc3339();
104
105 {
107 let diagnostics = trace_read_lock!(server_state.diagnostics);
108 self.diagnostics = diagnostics.clone();
109 }
110
111 let elapsed = now
112 .as_chrono()
113 .signed_duration_since(start_time.as_chrono());
114 self.server.uptime_ms = elapsed.num_milliseconds();
115 }
116
117 pub fn update_from_connections(&mut self, connections: server::Connections) {
119 self.runtime_components = runtime_components!();
120 self.connections = connections
121 .iter()
122 .map(|c| {
123 let (client_address, transport_state, session_manager) = {
125 let connection = trace_read_lock!(c);
126 let client_address =
127 if let Some(ref client_address) = connection.client_address() {
128 format!("{:?}", client_address)
129 } else {
130 String::new()
131 };
132 let transport_state = match connection.state() {
133 TransportState::New => "New".to_string(),
134 TransportState::WaitingHello => "WaitingHello".to_string(),
135 TransportState::ProcessMessages => "ProcessMessages".to_string(),
136 TransportState::Finished(status_code) => {
137 format!("Finished({})", status_code)
138 }
139 };
140 (
141 client_address,
142 transport_state,
143 connection.session_manager(),
144 )
145 };
146 let session_manager = trace_read_lock!(session_manager);
147 let sessions = session_manager
148 .sessions
149 .iter()
150 .map(|(_, session)| {
151 let session = trace_read_lock!(session);
152 let id = session.session_id().to_string();
153 let session_activated = session.is_activated();
154 let session_terminated = session.is_terminated();
155 let session_terminated_at = if session.is_terminated() {
156 session.terminated_at().to_rfc3339()
157 } else {
158 String::new()
159 };
160 let subscriptions = session.subscriptions().metrics();
161 Session {
162 id,
163 session_activated,
164 session_terminated,
165 session_terminated_at,
166 subscriptions,
167 }
168 })
169 .collect();
170
171 Connection {
173 client_address,
174 transport_state,
175 sessions,
176 }
177 })
178 .collect();
179 }
180}