Skip to content

Commit

Permalink
struct logger to datalogger end to end
Browse files Browse the repository at this point in the history
  • Loading branch information
gbin committed May 29, 2024
1 parent 45fc647 commit 03188fd
Show file tree
Hide file tree
Showing 11 changed files with 125 additions and 92 deletions.
14 changes: 13 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,3 +1,15 @@
[workspace]
members = ["copper", "copper_log_test", "copper_derive", "copper_derive_test", "copper_log", "examples/config_gen", "examples/pluginload", "examples/simplelogger", "examples/v4lsrc", "copper_log_runtime", "copper_datalogger", "copper_clock"]
members = ["copper",
"copper_log_test",
"copper_derive",
"copper_derive_test",
"copper_log",
"examples/config_gen",
"examples/pluginload",
"examples/simplelogger",
"examples/v4lsrc",
"copper_log_runtime",
"copper_datalogger",
"copper_clock",
"copper_traits"]
resolver = "2"
7 changes: 2 additions & 5 deletions copper/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,6 @@ serde = { version = "1.0", features = ["derive"] }
serde_derive = "1.0"
uom = { version = "0.36.0", features = ["rational"] }
ron = "0.8.1"
copper-traits = { path = "../copper_traits" }
copper-log = { path = "../copper_log" }
copper-log-runtime = { path = "../copper_log_runtime" }
bincode = "2.0.0-rc.3"



copper-log-runtime = { path = "../copper_log_runtime" }
57 changes: 1 addition & 56 deletions copper/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,59 +5,4 @@ pub mod cutask;
pub mod monitoring;
pub mod serde;

use bincode::Encode;
use std::error::Error;
use std::fmt::{Debug, Display, Formatter};

// Copper common error type.

#[derive(Debug)]
pub struct CuError {
message: String,
context: Option<String>,
}

impl Display for CuError {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
let context_str = match &self.context {
Some(c) => format!("{}", c),
None => "None".to_string(),
};
write!(f, "{}\n context:{}", self.message, context_str)?;
Ok(())
}
}

impl Error for CuError {}

impl From<&str> for CuError {
fn from(s: &str) -> CuError {
CuError {
message: s.to_string(),
context: None,
}
}
}

impl From<String> for CuError {
fn from(s: String) -> CuError {
CuError {
message: s,
context: None,
}
}
}

impl CuError {
pub fn add_context(mut self, context: &str) -> CuError {
self.context = Some(context.into());
self
}
}

pub type CuResult<T> = Result<T, CuError>;

/// Defines a basic write, append only stream trait to be able to log or send serializable objects.
pub trait Stream {
fn log(&mut self, obj: &impl Encode);
}
pub use copper_traits::*;
2 changes: 1 addition & 1 deletion copper_datalogger/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
[package]
name = "copper_datalogger"
name = "copper-datalogger"
version = "0.1.0"
edition = "2021"

Expand Down
13 changes: 10 additions & 3 deletions copper_datalogger/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ use bincode::{decode_from_reader, decode_from_slice};
use bincode_derive::Decode as dDecode;
use bincode_derive::Encode as dEncode;

use copper::Stream;
use copper::{CuError, CuResult, Stream};

const MAIN_MAGIC: [u8; 4] = [0xB4, 0xA5, 0x50, 0xFF];

Expand Down Expand Up @@ -70,7 +70,7 @@ impl MmapStream {
}

impl Stream for MmapStream {
fn log(&mut self, obj: &impl Encode) {
fn log(&mut self, obj: &impl Encode) -> CuResult<()> {
let result = encode_into_slice(
obj,
&mut self.current_slice[self.current_position..],
Expand All @@ -79,6 +79,7 @@ impl Stream for MmapStream {
match result {
Ok(nb_bytes) => {
self.current_position += nb_bytes;
Ok(())
}
Err(e) => match e {
EncodeError::UnexpectedEnd => {
Expand All @@ -91,8 +92,14 @@ impl Stream for MmapStream {
self.current_slice = unsafe {
from_raw_parts_mut(underlying_slice.as_mut_ptr(), underlying_slice.len())
};
Ok(())
}
_ => {
let err =
<&str as Into<CuError>>::into("Unexpected error while encoding object.")
.add_context(e.to_string().as_str());
Err(err)
}
_ => panic!("Unexpected error while encoding object: {:?}", e),
},
}
}
Expand Down
5 changes: 3 additions & 2 deletions copper_log_runtime/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,12 @@ edition = "2021"

[dependencies]
copper-value = { path = "../copper_value" }
lazy_static = "1.4.0"
copper-traits = { path = "../copper_traits" }
serde = { version = "1.0.202", features = ["derive"] }
bincode = { version = "2.0.0-rc.3", features = ["serde"] }
bincode_derive = "2.0.0-rc.3"
pretty-hex = "0.4.1"
ctor = "0.2.8"
ctrlc = { version = "3.4.4", features = ["termination"] }
kanal = { version = "0.1.0-pre8" }
kanal = { version = "0.1.0-pre8" }
once_cell = "1.19.0"
45 changes: 22 additions & 23 deletions copper_log_runtime/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,15 +1,18 @@
use bincode::enc::write::Writer;
use bincode_derive::{Decode, Encode};
use copper_traits::{CuResult, Stream};
pub use copper_value as value; // Part of the API, do not remove.
use copper_value::Value;
use kanal::{bounded, Sender};
use lazy_static::lazy_static;
use pretty_hex::pretty_hex;
use once_cell::sync::OnceCell;
use std::fmt::Display;
use std::io::{stdout, Write};
use std::sync::{Arc, Mutex};
use std::thread;

// The logging system is basically a global queue.
static QUEUE: OnceCell<Sender<CuLogEntry>> = OnceCell::new();

#[allow(dead_code)]
pub const ANONYMOUS: u32 = 0;

Expand Down Expand Up @@ -45,21 +48,22 @@ impl CuLogEntry {
}
}

lazy_static! {
static ref QUEUE: Sender<CuLogEntry> = initialize_queue();
}

/// The lifetime of this struct is the lifetime of the logger.
pub struct LoggerRuntime {}

impl LoggerRuntime {
pub fn init() -> Self {
lazy_static::initialize(&QUEUE);
pub fn init(destination: impl Stream + 'static) -> Self {
QUEUE
.set(initialize_queue(destination))
.expect("Failed to initialize the logger queue.");
LoggerRuntime {}
}

pub fn close(&self) {
QUEUE.close();
QUEUE
.get()
.expect("Logger Runtime closed before beeing open.")
.close();
}
}

Expand All @@ -69,14 +73,13 @@ impl Drop for LoggerRuntime {
}
}

fn initialize_queue() -> Sender<CuLogEntry> {
fn initialize_queue(mut destination: impl Stream + 'static) -> Sender<CuLogEntry> {
let (sender, receiver) = bounded::<CuLogEntry>(100);
let config = bincode::config::standard();

let handle = thread::spawn(move || loop {
if let Ok(data) = receiver.recv() {
let binary = bincode::encode_to_vec(&data, config).unwrap();
println!("{}", pretty_hex(&binary.as_slice()));
destination.log(&data);
} else {
break;
}
Expand All @@ -97,16 +100,12 @@ fn initialize_queue() -> Sender<CuLogEntry> {

/// Function called from generated code to log data.
#[inline]
pub fn log(entry: CuLogEntry) {
// If the queue is closed, we just drop the data.
if QUEUE.send(entry).is_err() {
if !QUEUE.is_closed() {
eprintln!("Copper: Failed to send data to the logger, some data got dropped.");
if QUEUE.is_full() {
eprintln!(
"Copper: The logger queue is full, consider increasing the size of the queue."
);
}
}
pub fn log(entry: CuLogEntry) -> CuResult<()> {
if let Some(queue) = QUEUE.get() {
queue
.send(entry)
.map_err(|_| "Failed to send data to the logger.".into())
} else {
Err("Logger not initialized.".into())
}
}
1 change: 1 addition & 0 deletions copper_log_test/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ edition = "2021"
copper = { path = "../copper" }
copper-log = { path = "../copper_log" }
copper-log-runtime = { path = "../copper_log_runtime" }
copper-datalogger = { path = "../copper_datalogger" }
copper-value = { path = "../copper_value" }
serde = { version = "1.0.202", features = ["derive"] }

Expand Down
10 changes: 9 additions & 1 deletion copper_log_test/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,18 @@
use copper_datalogger::{stream, DataLogger, EntryType};
use copper_log::debug;
use copper_log_runtime::LoggerRuntime;
use copper_value::to_value;
use serde::Serialize;
use std::path::PathBuf;
use std::sync::{Arc, Mutex};

fn main() {
let rt = LoggerRuntime {};
let path: PathBuf = PathBuf::from("/tmp/teststructlog.copper");
let data_logger = Arc::new(Mutex::new(
DataLogger::new(path.as_path(), Some(100000)).expect("Failed to create logger"),
));
let mut stream = stream(data_logger.clone(), EntryType::StructuredLogLine, 1024);
let rt = LoggerRuntime::init(stream);
#[derive(Serialize)]
struct Test {
a: i32,
Expand Down
7 changes: 7 additions & 0 deletions copper_traits/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
[package]
name = "copper-traits"
version = "0.1.0"
edition = "2021"

[dependencies]
bincode = "2.0.0-rc.3"
56 changes: 56 additions & 0 deletions copper_traits/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
use bincode::Encode;
use std::error::Error;
use std::fmt::{Display, Formatter};

/// Common copper Error type.
#[derive(Debug)]
pub struct CuError {
message: String,
context: Option<String>,
}

impl Display for CuError {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
let context_str = match &self.context {
Some(c) => format!("{}", c),
None => "None".to_string(),
};
write!(f, "{}\n context:{}", self.message, context_str)?;
Ok(())
}
}

impl Error for CuError {}

impl From<&str> for CuError {
fn from(s: &str) -> CuError {
CuError {
message: s.to_string(),
context: None,
}
}
}

impl From<String> for CuError {
fn from(s: String) -> CuError {
CuError {
message: s,
context: None,
}
}
}

impl CuError {
pub fn add_context(mut self, context: &str) -> CuError {
self.context = Some(context.into());
self
}
}

// Generic Result type for copper.
pub type CuResult<T> = Result<T, CuError>;

/// Defines a basic write, append only stream trait to be able to log or send serializable objects.
pub trait Stream: Sync + Send {
fn log(&mut self, obj: &impl Encode) -> CuResult<()>;
}

0 comments on commit 03188fd

Please sign in to comment.