#non-blocking #logger #async-io #disk-logger

disk_log

disk_log 是一个 高性能,非阻塞 的基于磁盘的日志记录器

2 个版本 (1 个稳定版)

1.0.0 2022年5月1日
0.1.0 2022年5月1日

#680并发 中排名

Apache-2.0

21KB
366

disk_log

disk_log 是一个 高性能,非阻塞 的基于磁盘的日志记录器

为什么需要 disk_log ?

  • 非阻塞 - 优化了 tokio,不会阻塞调度器进行IO操作

  • 分页 - disk_log 通过 total_page_size 在页面/文件之间分配日志记录

  • 迭代器 - 提供异步函数 get_page,然后可以迭代整个页面 (当 disk_log 写入时,其并发读取是安全的)

  • 高并发 disk_log 不需要 Mutex/RwLock 在线程之间共享,其是完全安全的

  • 技术上 - disk_log 受到 erlang disk_log 的启发,它在 erlang 中被广泛使用,由 mnesia 数据库Logger (Logger 是 Elixir 的生产级 Logger) 使用

示例


#[tokio::main]
async fn main() {

  let path = ".";
  let name = "service";
  let total_page_size = 1000;

  // Run DiskLog and get session
  let sess = DiskLog::open(path, name, total_page_size)
                             .unwrap()
                             .run_service();
                             


  // Log to page (don't block your scheduler)

  let _ = sess.log(b"Serialized data ......".to_vec()).await;

  let _ = sess.log(b"Serialized data ......".to_vec()).await;



  // very lightweight, just increment counter (mpsc::sender::clone)
  let sess1 = sess.clone();
  
  
  // Spawn task 
  tokio::spawn(async move {              
   
    // log by another task
    let _ = sess1.log(b"Serialized data ......".to_vec()).await;
  });



  // ---------------------------------------------------------------------
  // asynchronous get page
  let page = sess.get_page(1).await;
  
  match page {
       Err(e) => println!("==> {:?}", e),
       // if exist page
       Ok(mut lf) => {
           lf.iter(..)
             .unwrap()
             .for_each(|_record| {
               // consumer record
             })
       }    
   }

}

作者

  • DanyalMh

许可证

根据 Apache License, Version 2.0 许可证(“许可证”);除非适用法律要求或经书面同意,否则不得使用此文件,除非符合许可证。您可以在 https://www.apache.org/licenses/LICENSE-2.0 获取许可证副本。

除非适用法律要求或经书面同意,否则在许可证下分发的软件按“原样”提供,不提供任何明示或暗示的保证或条件。有关许可证的具体语言,请参阅许可证。

依赖关系

~3–5MB
~81K SLoC