欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

rust 一個(gè)日志緩存記錄的通用實(shí)現(xiàn)方法

 更新時(shí)間:2024年04月02日 10:20:33   作者:會(huì)編程的大白熊  
本文給出了一個(gè)通用的設(shè)計(jì)模式,通過建造者模式實(shí)例化記錄對象,可自定義格式化器將實(shí)例化后的記錄對象寫入到指定的緩存對象中,這篇文章主要介紹了rust 一個(gè)日志緩存記錄的通用實(shí)現(xiàn)方法,需要的朋友可以參考下

本文給出了一個(gè)通用的設(shè)計(jì)模式,通過建造者模式實(shí)例化記錄對象,可自定義格式化器將實(shí)例化后的記錄對象寫入到指定的緩存對象中。

定義記錄對象

use chrono::prelude::*;
use std::{
    cell::RefCell, ffi::OsStr, fmt, io, io::Write, path::Path, rc::Rc, str,
    time::SystemTime,
};
const DATETIME_FORMAT: &str = "%Y-%m-%d %H:%M:%S";
/// 將 SystemTime 格式的時(shí)間轉(zhuǎn)換為指定格式的字符串
fn format_system_time(st: SystemTime) -> String {
    let local_datetime: DateTime<Local> = st.clone().into();
    local_datetime.format(DATETIME_FORMAT).to_string()
}
/// 定義需要構(gòu)造的協(xié)議
#[derive(Debug, Default, Clone)]
struct Record<'a> {
    event_time: Option<SystemTime>,
    var_a: Option<String>,
    var_b: Option<&'a Path>,
    var_c: Option<i32>,
    var_d: Option<&'a OsStr>,
}
/// Record -> RecordBuilder
impl<'a> Record<'a> {
    /// Returns a new builder.
    #[inline]
    fn builder() -> RecordBuilder<'a> {
        RecordBuilder::new()
    }
    #[inline]
    fn event_time(&self) -> Option<SystemTime> {
        self.event_time
    }
    #[inline]
    fn var_a(&self) -> &Option<String> {
        &self.var_a
    }
    #[inline]
    fn var_b(&self) -> Option<&'a Path> {
        self.var_b
    }
    #[inline]
    fn var_c(&self) -> Option<i32> {
        self.var_c
    }
    #[inline]
    fn var_d(&self) -> Option<&'a OsStr> {
        self.var_d
    }
}

定義對象的建造者

用于根據(jù)需求創(chuàng)建不同的記錄對象

/// 用于構(gòu)造協(xié)議,通過 Record 和 RecordBuidler 將協(xié)議的讀寫分離
#[derive(Debug)]
struct RecordBuilder<'a> {
    record: Record<'a>,
}
impl<'a> RecordBuilder<'a> {
    /// Construct new `RecordBuilder`.
    #[inline]
    fn new() -> RecordBuilder<'a> {
        RecordBuilder { record: Record::default() }
    }
    #[inline]
    fn event_time(
        &mut self,
        event_time: Option<SystemTime>,
    ) -> &mut RecordBuilder<'a> {
        self.record.event_time = event_time;
        self
    }
    #[inline]
    fn var_a(&mut self, var_a: Option<String>) -> &mut RecordBuilder<'a> {
        self.record.var_a = var_a;
        self
    }
    #[inline]
    fn var_b(&mut self, var_b: Option<&'a Path>) -> &mut RecordBuilder<'a> {
        self.record.var_b = var_b;
        self
    }
    #[inline]
    fn var_c(&mut self, var_c: Option<i32>) -> &mut RecordBuilder<'a> {
        self.record.var_c = var_c;
        self
    }
    #[inline]
    fn var_d(&mut self, var_d: Option<&'a OsStr>) -> &mut RecordBuilder<'a> {
        self.record.var_d = var_d;
        self
    }
    /// Invoke the builder and return a `Record`
    #[inline]
    fn build(&mut self) -> Record<'a> {
        // todo 添加業(yè)務(wù)邏輯
        self.record.clone()
    }
}
impl<'a> Default for RecordBuilder<'a> {
    fn default() -> Self {
        Self::new()
    }
}

定義寫緩存對象

指定記錄對象的寫入緩存

/// 定義一個(gè)寫緩存
#[derive(Debug)]
struct Buffer(Vec<u8>);
impl Buffer {
    /// 初始化緩存
    fn new() -> Self {
        Self(vec![])
    }
    /// 清空緩存
    fn clear(&mut self) {
        self.0.clear();
    }
    /// 寫緩存
    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
        self.0.extend(buf);
        Ok(buf.len())
    }
    /// 刷新緩存
    fn flush(&mut self) -> io::Result<()> {
        Ok(())
    }
    /// 獲得緩存的內(nèi)容
    fn bytes(&self) -> &[u8] {
        &self.0
    }
}
impl Default for Buffer {
    fn default() -> Self {
        Self::new()
    }
}

定義用于格式化器的寫緩存

不同的格式化器可以使用不同的緩存,這里使用上面定義的一個(gè)簡單的數(shù)組緩存來實(shí)現(xiàn)格式化器需要的緩存。

/// 定義緩存內(nèi)容的格式器
struct FormatterBuffer {
    buf: Rc<RefCell<Buffer>>, // RefCell可以修改buf,Rc可以避免使用作用域標(biāo)識(shí)
}
impl FormatterBuffer {
    fn new(buffer: Rc<RefCell<Buffer>>) -> Self {
        FormatterBuffer { buf: buffer }
    }
    fn clear(&mut self) {
        self.buf.borrow_mut().clear()
    }
    fn buf(&self) -> Rc<RefCell<Buffer>> {
        self.buf.clone()
    }
}
impl io::Write for FormatterBuffer {
    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
        self.buf.borrow_mut().write(buf)
    }
    fn flush(&mut self) -> io::Result<()> {
        self.buf.borrow_mut().flush()
    }
}
impl fmt::Debug for FormatterBuffer {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        f.debug_struct("FormatterBuffer").finish()
    }
}

定義格式化器

不同的格式化器將記錄轉(zhuǎn)換為不同的格式,寫入到緩存中。

#[derive(Debug)]
/// 格式化器
struct Format<'a> {
    buf: &'a mut FormatterBuffer, // 數(shù)據(jù)緩存
    sep: &'a str,                 // 分隔符
}
impl<'a> Format<'a> {
    /// 寫數(shù)據(jù)到緩存中
    fn write(mut self, record: &Record) -> io::Result<()> {
        let _ = self.write_event_time(record);
        let _ = self.write_var_a(record);
        let _ = self.write_var_b(record);
        let _ = self.write_var_c(record);
        let _ = self.write_var_d(record);
        Ok(())
    }
    fn write_event_time(&mut self, record: &Record) -> io::Result<()> {
        match record.event_time() {
            Some(event_time) => {
                let datetime_str = format_system_time(event_time);
                write!(self.buf, "{}{}", datetime_str, self.sep)
            }
            None => {
                write!(self.buf, "{}", self.sep)
            }
        }
    }
    fn write_var_a(&mut self, record: &Record) -> io::Result<()> {
        match record.var_a() {
            Some(var_a) => {
                write!(self.buf, "{}{}", var_a, self.sep)
            }
            None => write!(self.buf, "{}", self.sep),
        }
    }
    fn write_var_b(&mut self, record: &Record) -> io::Result<()> {
        match record.var_b() {
            Some(var_b) => {
                write!(
                    self.buf,
                    "{}{}",
                    var_b.to_string_lossy(), // 操作系統(tǒng)對路徑處理的差異性可能會(huì)丟失部分?jǐn)?shù)據(jù)
                    self.sep
                )
            }
            None => write!(self.buf, "{}", self.sep),
        }
    }
    fn write_var_c(&mut self, record: &Record) -> io::Result<()> {
        match record.var_c() {
            Some(var_c) => {
                write!(self.buf, "{}{}", var_c, self.sep)
            }
            None => write!(self.buf, "{}", self.sep),
        }
    }
    fn write_var_d(&mut self, record: &Record) -> io::Result<()> {
        match record.var_d() {
            Some(var_d) => {
                write!(
                    self.buf,
                    "{}{}",
                    var_d.to_os_string().to_str().unwrap(), // 操作系統(tǒng)對路徑處理的差異性可能會(huì)panic
                    self.sep
                )
            }
            None => write!(self.buf, "{}", self.sep),
        }
    }
}

調(diào)用示例

fn main() {
    // 創(chuàng)建緩存
    let buffer = Rc::new(RefCell::new(Buffer::default()));
    let mut format_buffer = FormatterBuffer::new(buffer.clone());
    format_buffer.clear();

    // 創(chuàng)建一個(gè)格式化器
    let format = Format { buf: &mut format_buffer, sep: "|" };

    // 構(gòu)造事件發(fā)生時(shí)間
    let no_timezone =
        NaiveDateTime::parse_from_str("2024-01-02 03:04:05", DATETIME_FORMAT)
            .unwrap();
    let event_time = Local.from_local_datetime(&no_timezone).unwrap().into();
    // 構(gòu)造路徑
    let path = Path::new("./foo/bar.txt");
    let os_str = OsStr::new("1.png");
    // 構(gòu)造記錄
    let record = Record::builder()
        .event_time(Some(event_time))
        .var_a(Some("hello world".to_string()))
        .var_b(Some(path))
        .var_c(Some(999))
        .var_d(Some(os_str))
        .build();

    // 寫記錄到緩存
    let _ = format.write(&record);

    // 獲得RefCell對象的內(nèi)部值
    let ref_cell_inner_value = buffer.borrow();
    let actual = str::from_utf8(ref_cell_inner_value.bytes()).unwrap();

    let expect = "2024-01-02 03:04:05|hello world|./foo/bar.txt|999|1.png|";
    assert_eq!(actual, expect);
}

參考

https://github.com/rust-cli/env_logger

到此這篇關(guān)于rust 一個(gè)日志緩存記錄的通用實(shí)現(xiàn)的文章就介紹到這了,更多相關(guān)rust日志緩存內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 如何使用Rust的向量存儲(chǔ)值列表

    如何使用Rust的向量存儲(chǔ)值列表

    本文介紹了在Rust中使用向量存儲(chǔ)值列表的方法,包括創(chuàng)建、更新、讀取、遍歷、存儲(chǔ)多種類型以及內(nèi)存釋放等方面,向量是Rust中常用且強(qiáng)大的集合類型,熟練掌握其用法有助于編寫高效且安全的代碼
    2025-02-02
  • Rust如何使用線程同時(shí)運(yùn)行代碼

    Rust如何使用線程同時(shí)運(yùn)行代碼

    Rust使用1:1線程模型,通過std::thread::spawn創(chuàng)建線程,返回JoinHandle用于等待線程完成,閉包默認(rèn)借用外部變量,使用move關(guān)鍵字轉(zhuǎn)移所有權(quán),多線程共享數(shù)據(jù)時(shí)需使用并發(fā)原語,如Mutex、RwLock、Arc等,以避免競態(tài)條件
    2025-02-02
  • rust?創(chuàng)建多線程web?server的詳細(xì)過程

    rust?創(chuàng)建多線程web?server的詳細(xì)過程

    web?server?中主要的兩個(gè)協(xié)議是?http?和?tcp,tcp?是底層協(xié)議,http?是構(gòu)建在?tcp?之上的,本篇文章重點(diǎn)給大家介紹rust?創(chuàng)建多線程web?server的詳細(xì)過程,感興趣的朋友跟隨小編一起看看吧
    2023-11-11
  • Rust語言之使用Polar權(quán)限管理方法詳解

    Rust語言之使用Polar權(quán)限管理方法詳解

    權(quán)限管理 (Permission Management) 是一個(gè)涵蓋了系統(tǒng)或網(wǎng)絡(luò)中用戶權(quán)限控制和管理的系統(tǒng),本文將詳細(xì)給大家介紹Rust語言中如何使用Polar權(quán)限管理,需要的朋友可以參考下
    2023-11-11
  • rust多個(gè)mod文件引用和文件夾mod使用注意事項(xiàng)小結(jié)

    rust多個(gè)mod文件引用和文件夾mod使用注意事項(xiàng)小結(jié)

    在 Rust 項(xiàng)目中,可以使用 mod 關(guān)鍵字將一個(gè)文件夾或一個(gè) rs 文件作為一個(gè)模塊引入到當(dāng)前文件中,本文給大家介紹rust多個(gè)mod文件引用和文件夾mod使用注意事項(xiàng)小結(jié),感興趣的朋友跟隨小編一起看看吧
    2024-03-03
  • Rust中使用Serde對json數(shù)據(jù)進(jìn)行反序列化

    Rust中使用Serde對json數(shù)據(jù)進(jìn)行反序列化

    JSON作為目前流行的數(shù)據(jù)格式之一,被大家廣泛使用,在日常的開發(fā)實(shí)踐中,將JSON數(shù)據(jù)反序列化為對應(yīng)的類型具有重要的意義,在Rust中,Serde幾乎成了JSON數(shù)據(jù)解析的事實(shí)標(biāo)準(zhǔn),本文將給大家介紹Rust中使用Serde對json數(shù)據(jù)進(jìn)行反序列化,需要的朋友可以參考下
    2024-01-01
  • 深入了解Rust中的枚舉和模式匹配

    深入了解Rust中的枚舉和模式匹配

    這篇文章主要為大家詳細(xì)介紹了Rust中的枚舉和模式匹配的相關(guān)知識(shí),文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2024-01-01
  • rust中trait的使用方法詳解

    rust中trait的使用方法詳解

    trait用中文來講就是特征,它就是一個(gè)標(biāo)記,只不過這個(gè)標(biāo)記被用在特定的地方,也就是類型參數(shù)的后面,下面我們就來學(xué)習(xí)一下trait的具體使用方法吧
    2023-12-12
  • libbpf和Rust開發(fā)ebpf程序?qū)崙?zhàn)示例

    libbpf和Rust開發(fā)ebpf程序?qū)崙?zhàn)示例

    這篇文章主要為大家介紹了libbpf和Rust開發(fā)ebpf程序?qū)崙?zhàn)示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-12-12
  • Rust語言之Prometheus系統(tǒng)監(jiān)控工具包的使用詳解

    Rust語言之Prometheus系統(tǒng)監(jiān)控工具包的使用詳解

    Prometheus?是一個(gè)開源的系統(tǒng)監(jiān)控和警報(bào)工具包,最初是由SoundCloud構(gòu)建的,隨著時(shí)間的發(fā)展,Prometheus已經(jīng)具有適用于各種使用場景的版本,為了開發(fā)者方便開發(fā),更是有各種語言版本的Prometheus的開發(fā)工具包,本文主要介紹Rust版本的Prometheus開發(fā)工具包
    2023-10-10

最新評論