From 8a5150e05aad256e2f0a7cb9270619732f60f579 Mon Sep 17 00:00:00 2001 From: Ronald Holshausen Date: Wed, 4 Sep 2024 15:50:51 +1000 Subject: [PATCH] chore: Copy the in-mem logging functions to the FFI crate --- rust/pact_ffi/src/log/inmem_buffer.rs | 43 +++++++++++++++++++++++++-- 1 file changed, 41 insertions(+), 2 deletions(-) diff --git a/rust/pact_ffi/src/log/inmem_buffer.rs b/rust/pact_ffi/src/log/inmem_buffer.rs index aa97c01d1..bbf978718 100644 --- a/rust/pact_ffi/src/log/inmem_buffer.rs +++ b/rust/pact_ffi/src/log/inmem_buffer.rs @@ -1,10 +1,14 @@ //! In-memory buffer for logging output. +use std::collections::HashMap; use std::io; use std::io::Write; -use tracing_subscriber::fmt::MakeWriter; +use std::sync::Mutex; -use pact_matching::logging::write_to_log_buffer; +use bytes::{BufMut, Bytes, BytesMut}; +use lazy_static::lazy_static; +use tokio::task_local; +use tracing_subscriber::fmt::MakeWriter; /// In-memory buffer for logging output. Sends output to global static `LOG_BUFFER` in the pact_matching /// crate. If there is a task local ID found, will accumulate against that ID, otherwise will @@ -31,3 +35,38 @@ impl <'a> MakeWriter<'a> for InMemBuffer { *self } } + +lazy_static! { + /// Memory buffer for the buffer logger. This is needed here because there is no + /// way to get the logger sync from the Dispatch struct. The buffer will be emptied + /// when the contents is fetched via an FFI call. + /// + /// Accumulates the log entries against a task local ID. If the ID is not set, accumulates against + /// the "global" ID. + /// cbindgen:ignore + static ref LOG_BUFFER: Mutex> = Mutex::new(HashMap::new()); +} + +task_local! { + /// Log ID to accumulate logs against + #[allow(missing_docs)] + pub static LOG_ID: String; +} + +/// Fetches the contents from the id scoped in-memory buffer and empties the buffer. +pub fn fetch_buffer_contents(id: &str) -> Bytes { + let mut inner = LOG_BUFFER.lock().unwrap(); + let buffer = inner.entry(id.to_string()) + .or_insert_with(|| BytesMut::with_capacity(256)); + buffer.split().freeze() +} + +/// Writes the provided bytes to the task local ID scoped in-memory buffer. If there is no +/// task local ID set, will write to the "global" buffer. +pub fn write_to_log_buffer(buf: &[u8]) { + let id = LOG_ID.try_with(|id| id.clone()).unwrap_or_else(|_| "global".into()); + let mut inner = LOG_BUFFER.lock().unwrap(); + let buffer = inner.entry(id) + .or_insert_with(|| BytesMut::with_capacity(256)); + buffer.put(buf); +}