use std::marker::PhantomData;
use std::sync::{Arc, Mutex};
use std::{str};
use crate::formatters::DefaultSyslogFormatter;
use crate::sync::{LogItems, SyStream, SyStreamPri, SyStreamSyslogApi};
use crate::{formatters::SyslogFormatter};
use crate::{DefaultLocalSyslogDestination, SyslogDestination, common::*};
use crate::error::SyRes;
use crate::sync::syslog_sync_internal::{SyslogSocketLockless};
#[derive(Debug, Clone)]
pub struct SyncSyslog<F = DefaultSyslogFormatter, D = DefaultLocalSyslogDestination>
where
F: SyslogFormatter,
D: SyslogDestination,
{
log_items: Arc<Mutex<LogItems>>,
stream: Arc<Mutex<SyslogSocketLockless<D>>>,
_p: PhantomData<F>,
}
unsafe impl<F: SyslogFormatter, D: SyslogDestination> Send for SyncSyslog<F, D>
{}
impl SyncSyslog
{
pub
fn openlog(ident: Option<&str>, logstat: LogStat, facility: LogFacility,
net_tap_prov: DefaultLocalSyslogDestination) -> SyRes<Self>
{
return Ok(
Self
{
log_items:
Arc::new(
Mutex::new(
LogItems::new(ident, 0xff, logstat, facility)
)
),
stream:
Arc::new(
Mutex::new(
SyslogSocketLockless::<DefaultLocalSyslogDestination>::new(logstat, net_tap_prov)?
)
),
_p:
PhantomData,
}
);
}
}
impl<F: SyslogFormatter, D: SyslogDestination> SyncSyslog<F, D>
{
pub
fn openlog_with(ident: Option<&str>, logstat: LogStat, facility: LogFacility, net_tap_prov: D) -> SyRes<Self>
{
return Ok(
Self
{
log_items:
Arc::new(
Mutex::new(
LogItems::new(ident, 0xff, logstat, facility)
)
),
stream:
Arc::new(
Mutex::new(
SyslogSocketLockless::<D>::new(logstat, net_tap_prov)?
)
),
_p:
PhantomData,
}
);
}
}
impl<F: SyslogFormatter, D: SyslogDestination> SyncSyslog<F, D>
{
pub
fn connectlog(&self) -> SyRes<()>
{
return
self
.stream
.lock()
.unwrap()
.connectlog();
}
pub
fn setlogmask(&self, logmask: i32) -> SyRes<i32>
{
let pri =
self
.log_items
.lock()
.unwrap()
.set_logmask(logmask);
return Ok(pri);
}
pub
fn closelog(&self) -> SyRes<()>
{
return
self
.stream
.lock()
.unwrap()
.disconnectlog();
}
#[inline]
pub
fn syslog(&self, pri: Priority, fmt: F) -> SyRes<()>
{
let Some((formatted_msg, logstat)) =
self.log_items.lock().unwrap().vsyslog1_msg::<F, D>(pri, &fmt)
else { return Ok(()) };
self.stream.lock().unwrap().vsyslog1(logstat, formatted_msg)
}
pub
fn change_identity(&self, ident: Option<&str>) -> SyRes<()>
{
self
.log_items
.lock()
.unwrap()
.set_identity(ident);
return Ok(());
}
pub
fn reconnect(&self) -> SyRes<()>
{
return
self
.stream
.lock()
.unwrap()
.reconnectlog();
}
pub
fn update_tap_data(&self, tap_data: D) -> SyRes<()>
{
return
self
.stream
.lock()
.unwrap()
.update_tap_data(tap_data);
}
}
impl<F, D> SyncSyslog<F, D>
where F: SyslogFormatter, D: SyslogDestination
{
pub
fn get_stream<'t, PRI>(&'t self) -> SyStream<'t, PRI, D, F, &'t Self>
where PRI: SyStreamPri
{
SyStream
{
s: Some(self),
_p: PhantomData,
_p1: PhantomData,
_p2: PhantomData
}
}
}
impl<F: SyslogFormatter, D: SyslogDestination> SyStreamSyslogApi<F, D>
for &SyncSyslog<F, D>
{
type SYSLOG<'t> = &'t SyncSyslog<F, D>;
fn syslog<'t>(syslog: Self::SYSLOG<'t>, pri: Priority, fmt: F) -> SyRes<()>
{
syslog.syslog(pri, fmt)
}
}