Skip to content

Commit 5695c72

Browse files
committed
monitoring added
1 parent 38f9458 commit 5695c72

File tree

4 files changed

+386
-21
lines changed

4 files changed

+386
-21
lines changed

docs/src/project_structure.md

Lines changed: 33 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -2,40 +2,52 @@
22

33
This workspace is organized into several purpose-specific crates to provide a modular, maintainable API for eCAL:
44

5-
| Crate | Description |
6-
|---------------------------|----------------------------------------------------------|
5+
| Crate | Description |
6+
|---------------------------|-----------------------------------------------------------------------------|
77
| `rustecal` | **Meta‑crate**: re‑exports core, pub/sub, and service APIs via feature flags (`pubsub`, `service`) |
8-
| `rustecal-core` | eCAL initialization, shutdown, and shared common types |
9-
| `rustecal-pubsub` | Typed and untyped Publisher/Subscriber API |
10-
| `rustecal-service` | RPC Service server & client API |
11-
| `rustecal-sys` | Low‑level FFI bindings to the eCAL C API |
12-
| `rustecal-types-string` | Helper: UTF-8 string message wrapper for typed pub/sub |
13-
| `rustecal-types-bytes` | Helper: raw byte vector message wrapper |
14-
| `rustecal-types-protobuf` | Helper: Protobuf message wrapper (using `prost`) |
15-
| `rustecal-samples` | Example binaries demonstrating pub/sub and RPC usage |
8+
| `rustecal-core` | Core lifecycle management, logging, monitoring, and shared type definitions |
9+
| `rustecal-pubsub` | Typed and untyped Publisher/Subscriber API |
10+
| `rustecal-service` | RPC Service server & client API |
11+
| `rustecal-sys` | Low‑level FFI bindings to the eCAL C API |
12+
| `rustecal-types-string` | Helper: UTF-8 string message wrapper for typed pub/sub |
13+
| `rustecal-types-bytes` | Helper: raw byte vector message wrapper |
14+
| `rustecal-types-protobuf` | Helper: Protobuf message wrapper (using `prost`) |
15+
| `rustecal-samples` | Example binaries demonstrating pub/sub, RPC, logging, and monitoring |
1616

1717
## Workspace Layout
1818

1919
```text
2020
your_workspace/
21-
├── Cargo.toml # workspace manifest
22-
├── rustecal/ # meta‑crate (feature‑gated)
23-
├── rustecal-core/ # core init + types
24-
├── rustecal-pubsub/ # pub/sub API
25-
├── rustecal-service/ # service RPC API
26-
├── rustecal-sys/ # raw C bindings
21+
├── Cargo.toml # workspace manifest
22+
├── rustecal/ # meta‑crate (feature‑gated)
23+
├── rustecal-core/ # core init + logging + monitoring + shared types
24+
│ ├── src/
25+
│ │ ├── core.rs
26+
│ │ ├── log.rs
27+
│ │ ├── monitoring.rs
28+
│ │ ├── log_level.rs
29+
│ │ ├── core_types/
30+
│ │ │ ├── mod.rs
31+
│ │ │ ├── logging.rs
32+
│ │ │ └── monitoring.rs
33+
├── rustecal-pubsub/ # pub/sub API
34+
├── rustecal-service/ # service RPC API
35+
├── rustecal-sys/ # raw C bindings
2736
├── rustecal-types-string/
2837
├── rustecal-types-bytes/
2938
├── rustecal-types-protobuf/
30-
└── rustecal-samples/ # examples
39+
└── rustecal-samples/ # examples
3140
├── pubsub/
3241
│ ├── hello_send/
3342
│ ├── hello_receive/
3443
│ ├── blob_send/
3544
│ ├── blob_receive/
3645
│ ├── person_send/
3746
│ └── person_receive/
38-
└── service/
39-
├── mirror_server/
40-
├── mirror_client/
41-
└── mirror_client_instances/
47+
├── service/
48+
│ ├── mirror_server/
49+
│ ├── mirror_client/
50+
│ └── mirror_client_instances/
51+
└── core/
52+
├── logging_snapshot/ # example using `Log::get_logging`
53+
└── monitoring_snapshot/ # example using `Monitoring::get_snapshot`
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
//! Common eCAL types shared across pubsub and service layers.
22
3+
pub mod monitoring;
34
pub mod logging;
Lines changed: 270 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,270 @@
1+
//! Rust-safe wrappers for `eCAL_Monitoring_SMonitoring` and related types.
2+
//!
3+
//! These types represent the full monitoring snapshot of the eCAL runtime system.
4+
5+
use crate::types::DataTypeInfo;
6+
use std::ffi::CStr;
7+
use std::os::raw::c_char;
8+
9+
/// Helper to safely convert C string pointers.
10+
fn cstr(ptr: *const c_char) -> String {
11+
if ptr.is_null() {
12+
String::new()
13+
} else {
14+
unsafe { CStr::from_ptr(ptr).to_string_lossy().into_owned() }
15+
}
16+
}
17+
18+
/// Transport layer type.
19+
#[derive(Debug, Clone)]
20+
pub enum TransportLayerType {
21+
None,
22+
UdpMulticast,
23+
Shm,
24+
Tcp,
25+
Unknown(i32),
26+
}
27+
28+
/// A single transport layer entry.
29+
#[derive(Debug, Clone)]
30+
pub struct TransportLayer {
31+
pub transport_type: TransportLayerType,
32+
pub version: i32,
33+
pub active: bool,
34+
}
35+
36+
/// Full snapshot of monitoring information from the eCAL runtime.
37+
#[derive(Debug, Clone)]
38+
pub struct MonitoringSnapshot {
39+
pub processes: Vec<ProcessInfo>,
40+
pub publishers: Vec<TopicInfo>,
41+
pub subscribers: Vec<TopicInfo>,
42+
pub servers: Vec<ServerInfo>,
43+
pub clients: Vec<ClientInfo>,
44+
}
45+
46+
/// A monitored eCAL process.
47+
#[derive(Debug, Clone)]
48+
pub struct ProcessInfo {
49+
pub registration_clock: i32,
50+
pub host_name: String,
51+
pub shm_transport_domain: String,
52+
pub process_id: i32,
53+
pub process_name: String,
54+
pub unit_name: String,
55+
pub process_parameter: String,
56+
pub state_severity: i32,
57+
pub state_severity_level: i32,
58+
pub state_info: String,
59+
pub time_sync_state: i32,
60+
pub time_sync_module_name: String,
61+
pub component_init_state: i32,
62+
pub component_init_info: String,
63+
pub runtime_version: String,
64+
pub config_file_path: String,
65+
}
66+
67+
/// A monitored topic (publisher or subscriber).
68+
#[derive(Debug, Clone)]
69+
pub struct TopicInfo {
70+
pub registration_clock: i32,
71+
pub host_name: String,
72+
pub shm_transport_domain: String,
73+
pub process_id: i32,
74+
pub process_name: String,
75+
pub unit_name: String,
76+
pub topic_id: i64,
77+
pub topic_name: String,
78+
pub direction: String,
79+
pub data_type: DataTypeInfo,
80+
pub transport_layers: Vec<TransportLayer>,
81+
pub topic_size: i32,
82+
pub connections_local: i32,
83+
pub connections_external: i32,
84+
pub message_drops: i32,
85+
pub data_id: i64,
86+
pub data_clock: i64,
87+
pub data_frequency: i32,
88+
}
89+
90+
/// A method entry of a service.
91+
#[derive(Debug, Clone)]
92+
pub struct MethodInfo {
93+
pub method_name: String,
94+
pub request_type: DataTypeInfo,
95+
pub response_type: DataTypeInfo,
96+
pub call_count: i64,
97+
}
98+
99+
/// A monitored service server.
100+
#[derive(Debug, Clone)]
101+
pub struct ServerInfo {
102+
pub registration_clock: i32,
103+
pub host_name: String,
104+
pub process_name: String,
105+
pub unit_name: String,
106+
pub process_id: i32,
107+
pub service_name: String,
108+
pub service_id: i64,
109+
pub version: u32,
110+
pub tcp_port_v0: u32,
111+
pub tcp_port_v1: u32,
112+
pub methods: Vec<MethodInfo>,
113+
}
114+
115+
/// A monitored service client.
116+
#[derive(Debug, Clone)]
117+
pub struct ClientInfo {
118+
pub registration_clock: i32,
119+
pub host_name: String,
120+
pub process_name: String,
121+
pub unit_name: String,
122+
pub process_id: i32,
123+
pub service_name: String,
124+
pub service_id: i64,
125+
pub version: u32,
126+
pub methods: Vec<MethodInfo>,
127+
}
128+
129+
// -----------------------------------------------------------------------------
130+
// FFI Conversions
131+
// -----------------------------------------------------------------------------
132+
133+
impl From<i32> for TransportLayerType {
134+
fn from(value: i32) -> Self {
135+
match value {
136+
0 => TransportLayerType::None,
137+
1 => TransportLayerType::UdpMulticast,
138+
4 => TransportLayerType::Shm,
139+
5 => TransportLayerType::Tcp,
140+
_ => TransportLayerType::Unknown(value),
141+
}
142+
}
143+
}
144+
145+
impl From<rustecal_sys::eCAL_Monitoring_STransportLayer> for TransportLayer {
146+
fn from(raw: rustecal_sys::eCAL_Monitoring_STransportLayer) -> Self {
147+
Self {
148+
transport_type: raw.type_.into(),
149+
version: raw.version,
150+
active: raw.active != 0,
151+
}
152+
}
153+
}
154+
155+
impl From<rustecal_sys::eCAL_Monitoring_STopic> for TopicInfo {
156+
fn from(raw: rustecal_sys::eCAL_Monitoring_STopic) -> Self {
157+
let transport_layers = unsafe {
158+
std::slice::from_raw_parts(raw.transport_layer, raw.transport_layer_length)
159+
.iter()
160+
.cloned()
161+
.map(TransportLayer::from)
162+
.collect()
163+
};
164+
165+
Self {
166+
registration_clock: raw.registration_clock,
167+
host_name: cstr(raw.host_name),
168+
shm_transport_domain: cstr(raw.shm_transport_domain),
169+
process_id: raw.process_id,
170+
process_name: cstr(raw.process_name),
171+
unit_name: cstr(raw.unit_name),
172+
topic_id: raw.topic_id,
173+
topic_name: cstr(raw.topic_name),
174+
direction: cstr(raw.direction),
175+
data_type: DataTypeInfo::from(raw.datatype_information),
176+
transport_layers,
177+
topic_size: raw.topic_size,
178+
connections_local: raw.connections_local,
179+
connections_external: raw.connections_external,
180+
message_drops: raw.message_drops,
181+
data_id: raw.data_id,
182+
data_clock: raw.data_clock,
183+
data_frequency: raw.data_frequency,
184+
}
185+
}
186+
}
187+
188+
impl From<rustecal_sys::eCAL_Monitoring_SProcess> for ProcessInfo {
189+
fn from(raw: rustecal_sys::eCAL_Monitoring_SProcess) -> Self {
190+
Self {
191+
registration_clock: raw.registration_clock,
192+
host_name: cstr(raw.host_name),
193+
shm_transport_domain: cstr(raw.shm_transport_domain),
194+
process_id: raw.process_id,
195+
process_name: cstr(raw.process_name),
196+
unit_name: cstr(raw.unit_name),
197+
process_parameter: cstr(raw.process_parameter),
198+
state_severity: raw.state_severity,
199+
state_severity_level: raw.state_severity_level,
200+
state_info: cstr(raw.state_info),
201+
time_sync_state: raw.time_sync_state,
202+
time_sync_module_name: cstr(raw.time_sync_module_name),
203+
component_init_state: raw.component_init_state,
204+
component_init_info: cstr(raw.component_init_info),
205+
runtime_version: cstr(raw.ecal_runtime_version),
206+
config_file_path: cstr(raw.config_file_path),
207+
}
208+
}
209+
}
210+
211+
impl From<rustecal_sys::eCAL_Monitoring_SMethod> for MethodInfo {
212+
fn from(raw: rustecal_sys::eCAL_Monitoring_SMethod) -> Self {
213+
Self {
214+
method_name: cstr(raw.method_name),
215+
request_type: DataTypeInfo::from(raw.request_datatype_information),
216+
response_type: DataTypeInfo::from(raw.response_datatype_information),
217+
call_count: raw.call_count,
218+
}
219+
}
220+
}
221+
222+
impl From<rustecal_sys::eCAL_Monitoring_SServer> for ServerInfo {
223+
fn from(raw: rustecal_sys::eCAL_Monitoring_SServer) -> Self {
224+
let methods = unsafe {
225+
std::slice::from_raw_parts(raw.methods, raw.methods_length)
226+
.iter()
227+
.cloned()
228+
.map(MethodInfo::from)
229+
.collect()
230+
};
231+
232+
Self {
233+
registration_clock: raw.registration_clock,
234+
host_name: cstr(raw.host_name),
235+
process_name: cstr(raw.process_name),
236+
unit_name: cstr(raw.unit_name),
237+
process_id: raw.process_id,
238+
service_name: cstr(raw.service_name),
239+
service_id: raw.service_id,
240+
version: raw.version,
241+
tcp_port_v0: raw.tcp_port_v0,
242+
tcp_port_v1: raw.tcp_port_v1,
243+
methods,
244+
}
245+
}
246+
}
247+
248+
impl From<rustecal_sys::eCAL_Monitoring_SClient> for ClientInfo {
249+
fn from(raw: rustecal_sys::eCAL_Monitoring_SClient) -> Self {
250+
let methods = unsafe {
251+
std::slice::from_raw_parts(raw.methods, raw.methods_length)
252+
.iter()
253+
.cloned()
254+
.map(MethodInfo::from)
255+
.collect()
256+
};
257+
258+
Self {
259+
registration_clock: raw.registration_clock,
260+
host_name: cstr(raw.host_name),
261+
process_name: cstr(raw.process_name),
262+
unit_name: cstr(raw.unit_name),
263+
process_id: raw.process_id,
264+
service_name: cstr(raw.service_name),
265+
service_id: raw.service_id,
266+
version: raw.version,
267+
methods,
268+
}
269+
}
270+
}

0 commit comments

Comments
 (0)