a653rs_linux/
partition.rs1use std::cmp::min;
2
3#[cfg(feature = "socket")]
4use std::{
5 fmt::Display,
6 io,
7 net::{TcpStream, UdpSocket},
8};
9
10use a653rs::prelude::{ApexErrorP4Ext, MAX_ERROR_MESSAGE_SIZE};
11use a653rs_linux_core::error::SystemError;
12use a653rs_linux_core::health_event::PartitionCall;
13use log::{set_logger, set_max_level, LevelFilter, Record, SetLoggerError};
14
15use crate::{CONSTANTS, SENDER};
16
17#[cfg(feature = "socket")]
18use crate::{TCP_SOCKETS, UDP_SOCKETS};
19
20#[derive(Debug, Clone, Copy)]
22pub struct ApexLinuxPartition;
23
24impl ApexLinuxPartition {
25 pub fn get_partition_name() -> String {
26 CONSTANTS.name.clone()
27 }
28
29 #[cfg(feature = "socket")]
30 pub fn get_udp_socket(sockaddr: &str) -> Result<Option<UdpSocket>, ApexLinuxError> {
31 for stored in UDP_SOCKETS.iter() {
32 if stored.local_addr()?.to_string() == sockaddr {
33 let socket = stored.try_clone()?;
34 return Ok(Some(socket));
35 }
36 }
37 Ok(None)
38 }
39
40 #[cfg(feature = "socket")]
41 pub fn get_tcp_stream(sockaddr: &str) -> Result<Option<TcpStream>, ApexLinuxError> {
42 for stored in TCP_SOCKETS.iter() {
43 if stored.peer_addr()?.to_string() == sockaddr {
44 let socket = stored.try_clone()?;
45 return Ok(Some(socket));
46 }
47 }
48 Ok(None)
49 }
50
51 pub(crate) fn raise_system_error(error: SystemError) {
52 if let Err(e) = SENDER.try_send(&PartitionCall::Error(error)) {
53 panic!("Could not send SystemError event {error:?}. {e:?}")
54 };
55 }
56}
57
58#[cfg(feature = "socket")]
59#[derive(Debug, Clone)]
60pub enum ApexLinuxError {
61 SocketError,
62}
63
64#[cfg(feature = "socket")]
65impl Display for ApexLinuxError {
66 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
67 match self {
68 ApexLinuxError::SocketError => f.write_str("Failed to get socket"),
69 }
70 }
71}
72
73#[cfg(feature = "socket")]
74impl From<io::Error> for ApexLinuxError {
75 fn from(_value: io::Error) -> Self {
76 ApexLinuxError::SocketError
77 }
78}
79
80static APEX_LOGGER: ApexLogger = ApexLogger();
81
82#[derive(Debug, Clone, Copy)]
83pub struct ApexLogger();
84
85impl ApexLogger {
86 pub fn install_logger(level: LevelFilter) -> Result<(), SetLoggerError> {
87 set_logger(&APEX_LOGGER).map(|()| set_max_level(level))
88 }
89
90 pub fn install_panic_hook() {
91 std::panic::set_hook(Box::new(|panic_info| error!("{panic_info:#?}")));
92 }
93}
94
95impl log::Log for ApexLogger {
96 fn enabled(&self, _meta: &log::Metadata) -> bool {
97 true
98 }
99
100 fn log(&self, record: &Record) {
101 let level = record.level() as usize;
102 for line in record.args().to_string().lines() {
103 let msg = if line.len() < MAX_ERROR_MESSAGE_SIZE {
104 format!("{level}{line}")
105 } else {
106 format!("{level}{}..", &line[..(MAX_ERROR_MESSAGE_SIZE - 3)])
107 };
108 let max = min(MAX_ERROR_MESSAGE_SIZE, msg.len());
109 ApexLinuxPartition::report_application_message(&msg.as_bytes()[0..max]).ok();
110 }
111 }
112
113 fn flush(&self) {}
114}