Skip to main content

Fast async logger with Python bindings

Project description

NexusLog - 超高性能异步日志库

一个用 Rust 实现的超高速异步日志库,提供 Python 绑定。比标准 Python 日志快 33 倍,比 picologging 快 12 倍

Note: 支持 Python 3.11 - 3.14。基准测试中的 picologging 目前仅支持到 Python 3.12。

性能基准

使用 1,000,000 条日志消息的基准测试结果:

------------------------------------------------------------
Logger               Time (s)     Msgs/sec        Log size    
------------------------------------------------------------
Python logging       5.141        194,517         81,888,890 bytes
picologging          1.950        512,691         80,888,880 bytes
NexusLogger          0.158        6,346,027       97,888,890 bytes
------------------------------------------------------------

✨ NexusLogger is 32.62x faster than Python logging
✨ NexusLogger is 12.38x faster than picologging

功能特性

  • 🚀 极速性能 - 异步非阻塞日志记录
  • 🔄 自动轮转 - 每日自动按日期轮转日志文件
  • 🐍 Python 绑定 - 通过 PyO3 实现
  • 📝 多日志级别 - Trace、Debug、Info、Warn、Error
  • 🎯 零拷贝时间戳 - 线程本地缓存减少系统调用
  • 💾 智能内存管理 - 小消息 inline 存储,避免堆分配
  • 🔗 共享资源 - 多个日志实例自动复用底层 worker 线程

快速开始

Python 使用

from nexuslog import Logger, Level, basicConfig

# 可选:配置默认日志文件
basicConfig(log_file="/var/log/app.log")

# 创建日志实例
logger = Logger("my_app", path="/var/log/app", level=Level.Info)

# 记录日志
logger.info("Application started")
logger.debug("Debug message")
logger.warn("Warning message")
logger.error("Error occurred")

# 完成时关闭
logger.shutdown()

Rust 使用

use nexuslog::{init, info, error, Level};

fn main() {
    let mut handle = init("my_app", Some("logs/app"), Level::Info);
    
    info!("Application started");
    error!("An error occurred");
    
    handle.stop();
}

核心优化

1. 线程本地时间戳缓存

问题: 每次日志调用都需要获取系统时间,频繁的系统调用是瓶颈。

优化: 使用线程本地存储缓存时间戳,利用 std::time::Instant 进行增量计算。

thread_local! {
    static TS_CACHE: RefCell<ThreadTimestampCache> =
        RefCell::new(ThreadTimestampCache::new());
}

struct ThreadTimestampCache {
    base_instant: Instant,
    base_secs: u64,
    base_micros: u32,
}

// 仅在经过1秒后才重新调用系统时间
fn now(&mut self) -> Timestamp {
    let elapsed = self.base_instant.elapsed();
    if elapsed >= Duration::from_secs(1) {
        return self.refresh();  // 系统调用
    }
    // 增量计算时间戳
    let elapsed_micros = elapsed.as_micros() as u64;
    let total_micros = self.base_micros as u64 + elapsed_micros;
    Timestamp {
        secs: self.base_secs + (total_micros / 1_000_000),
        micros: (total_micros % 1_000_000) as u32,
    }
}

效果: 将时间戳获取从 O(系统调用) 降低到 O(1) 内存读取。


2. ArrayString 内联存储

问题: 每条日志消息都需要堆分配,这会造成内存碎片和 GC 压力。

优化: 对于小消息(≤256 字符),在栈上使用 ArrayString 存储,避免堆分配。

const INLINE_MSG_CAP: usize = 256;

enum LogMessage {
    Inline(ArrayString<INLINE_MSG_CAP>),  // 栈存储
    Heap(String),                          // 仅大消息
}

// 在日志处理中
let msg = {
    let mut inline = ArrayString::<INLINE_MSG_CAP>::new();
    use std::fmt::Write as _;
    if write!(&mut inline, "{}", record.args()).is_ok() {
        LogMessage::Inline(inline)  // 成功内联
    } else {
        LogMessage::Heap(record.args().to_string())  // 降级到堆
    }
};

效果:

  • 大多数日志消息(256 字符)避免堆分配
  • 减少 GC 压力
  • 更好的 CPU 缓存局部性

3. 异步非阻塞架构

问题: 同步日志会阻塞应用线程等待 I/O 完成。

优化: 专用 worker 线程处理所有 I/O 操作,主线程仅负责将消息放入无锁队列。

pub struct Handle {
    tx: Sender<Action>,
    thread: Option<JoinHandle<()>>,
}

// 主线程 - 只是发送消息,立即返回
impl log::Log for Logger {
    fn log(&self, record: &Record) {
        let entry = LogEntry { /* ... */ };
        let _ = self.tx.send(Action::Write(entry));  // O(1) 无锁操作
    }
}

// Worker 线程 - 处理所有 I/O
fn worker<P: ToString + Send>(mut ctx: Context<P>) -> Result<(), std::io::Error> {
    loop {
        match ctx.rx.recv_timeout(timeout) {
            Ok(Action::Write(entry)) => {
                // 格式化、写入、轮转
            }
            Ok(Action::Flush) => {
                target.flush()?;
            }
            Ok(Action::Exit) => break,
            Err(RecvTimeoutError::Timeout) => {}
            Err(RecvTimeoutError::Disconnected) => break,
        }
    }
}

效果:

  • 应用线程不阻塞
  • 平均延迟 < 1 微秒
  • 高并发下稳定性强

4. 高效的跨线程通信

问题: Rust 标准库的 channel 可能在高吞吐量场景下有争用。

优化: 使用 crossbeam-channel 的有界 channel,容量为 65,536 条消息。

const CHANNEL_CAPACITY: usize = 65_536;

let (tx, rx) = crossbeam_channel::bounded(CHANNEL_CAPACITY);

优势:

  • 比标准库 channel 更高效
  • 容量足够应对短期突发
  • 提供优雅的背压机制

5. 时间戳格式缓存

问题: 每条消息都格式化时间戳字符串需要大量计算。

优化: 在 worker 线程中缓存已格式化的时间戳部分,每秒更新一次。

struct TimestampCache {
    last_secs: u64,
    year: i32,
    month: u32,
    day: u32,
    hour: u32,
    minute: u32,
    second: u32,
    time_prefix: String,      // 缓存格式化的时间前缀
    offset_prefix: String,    // 缓存时区和日志级别前缀
}

impl TimestampCache {
    fn update(&mut self, secs: u64) {
        if self.last_secs == secs {
            return;  // 同一秒内,直接使用缓存
        }
        // 仅在秒数改变时重新格式化
        self.time_prefix = format!(
            "time={:04}-{:02}-{:02}T{:02}:{:02}:{:02}.",
            self.year, self.month, self.day, self.hour, self.minute, self.second
        );
    }
}

// 使用缓存
let mut line = String::with_capacity(entry.msg().len() + 128);
line.push_str(&cache.time_prefix);      // O(1) 字符串拷贝
write!(&mut line, "{:06}", ts.micros)?; // 仅格式化微秒
line.push_str(&cache.offset_prefix);    // O(1) 字符串拷贝

效果: 减少每条消息的格式化成本约 80%。


6. 自动日志轮转

问题: 日志文件会无限增长。

优化: Worker 线程自动按日期检测轮转,格式为 {path}_YYYYMMDD.log

fn rotate<P: ToString + Send>(
    ctx: &Context<P>,
) -> Result<BufWriter<Box<dyn Write>>, std::io::Error> {
    match &ctx.path {
        Some(path) => {
            let postfix = ctx.date.format("_%Y%m%d.log").to_string();
            let path = path.to_string() + &postfix;
            let file = open_file(&path)?;
            Ok(BufWriter::with_capacity(1024 * 1024, Box::new(file)))
        }
        None => {
            let target = Box::new(std::io::stdout());
            Ok(BufWriter::with_capacity(1024 * 1024, target))
        }
    }
}

// 在 worker 中检测日期变化
if cache.date != ctx.date {
    ctx.date = cache.date;
    target = rotate(&ctx)?;  // 自动轮转到新文件
}

特性:

  • 零手动配置
  • 自动创建父目录
  • 支持 stdout 和文件输出

7. Python 共享资源管理

问题: 多个 Python Logger 实例创建多个 worker 线程会浪费资源。

优化: 使用全局注册表和弱引用实现资源共享。

fn registry() -> &'static Mutex<HashMap<PathKey, Weak<SharedWriter>>> {
    static REGISTRY: OnceLock<Mutex<HashMap<PathKey, Weak<SharedWriter>>>> = OnceLock::new();
    REGISTRY.get_or_init(|| Mutex::new(HashMap::new()))
}

fn shared_writer(path: Option<String>) -> Arc<SharedWriter> {
    let key = match path.clone() {
        Some(p) => PathKey::File(p),
        None => PathKey::Stdout,
    };

    let mut map = registry().lock().unwrap();
    if let Some(weak) = map.get(&key) {
        if let Some(writer) = weak.upgrade() {
            return writer;  // 复用现有 writer
        }
    }

    // 创建新的 writer
    let writer = Arc::new(SharedWriter::new(path));
    map.insert(key, Arc::downgrade(&writer));
    writer
}

优势:

  • 同一个日志文件路径只有一个 worker 线程
  • 自动清理无用资源
  • 内存高效
# Python 代码示例
logger1 = Logger("app", path="/var/log/app")
logger2 = Logger("db", path="/var/log/app")
# 两者共享同一个底层 worker 线程和文件句柄!

8. 带缓冲的文件写入

问题: 每条消息都直接写入文件会产生大量系统调用。

优化: 使用 BufWriter 缓冲写入,容量 1MB。

let capacity = 1024 * 1024;
Ok(BufWriter::with_capacity(capacity, Box::new(file)))

配合定时 flush:

let mut last_flush = Instant::now();
loop {
    // ... 处理消息 ...
    if last_flush.elapsed() >= Duration::from_secs(1) {
        last_flush = Instant::now();
        target.flush()?;  // 每秒 flush 一次
    }
}

效果: 将写入系统调用从每条消息 1 次降低到每秒约 1 次。


性能对比分析

优化方式 Python logging picologging NexusLog
时间戳获取 每次系统调用 缓存(1秒) 线程本地缓存(1秒)
内存分配 每条消息堆分配 每条消息堆分配 ArrayString 内联
写入方式 同步阻塞 同步阻塞 异步非阻塞
线程模型 调用线程 调用线程 专用 worker
格式化 每次完整格式化 每次完整格式化 部分缓存
文件 I/O 每条消息系统调用 每条消息系统调用 缓冲 1MB
资源管理 独立实例 独立实例 共享 worker

构建与安装

前置条件

  • Rust 1.56+
  • Python 3.11+
  • pip 和 maturin

从源代码构建

# 克隆仓库
git clone https://github.com/river-walras/nexuslogger.git
cd nexuslog

# 构建 Python wheel
pip install maturin
maturin develop

# 或构建发布版本
maturin build --release

运行性能测试

# Python 基准测试
python benches/bench_python.py

项目结构

nexuslog/
├── src/
│   └── lib.rs              # 核心 Rust 实现
├── python/
│   └── nexuslog/
│       ├── __init__.py     # Python 包入口
│       └── _logger.pyi     # 类型提示
├── benches/
│   ├── bench_python.py     # Python 基准测试
│   └── example.py          # 使用示例
├── Cargo.toml              # Rust 依赖
├── pyproject.toml          # Python 项目配置
└── README.md               # 本文件

依赖

Rust

  • chrono - 日期/时间处理
  • crossbeam-channel - 高效的跨线程通信
  • log - Rust 日志 facade
  • pyo3 - Python 绑定
  • arrayvec - 栈分配的向量/字符串

Python

  • pyo3 >= 0.27.2
  • Python >= 3.11

API 文档

Python API

basicConfig(log_file=None, level=Level.Info)

配置全局日志设置。

参数:

  • log_file (str, optional): 日志文件路径前缀
  • level (Level, optional): 全局日志级别

Logger(name, path=None, level=Level.Info)

创建日志实例。

参数:

  • name (str): 日志记录器名称,显示在每条日志中
  • path (str, optional): 文件路径前缀。若为 None,输出到 stdout
  • level (Level, optional): 最小日志级别

方法:

  • trace(message) - 记录 trace 级别日志
  • debug(message) - 记录 debug 级别日志
  • info(message) - 记录 info 级别日志
  • warn(message) - 记录 warn 级别日志
  • error(message) - 记录 error 级别日志
  • shutdown() - 关闭日志,刷新所有待写入消息

Level 枚举

  • Level.Trace
  • Level.Debug
  • Level.Info
  • Level.Warn
  • Level.Error

性能调优建议

  1. 使用专用日志文件路径 - 减少文件打开次数
  2. 合理设置日志级别 - 避免过多低级别日志
  3. 批量日志写入 - 利用缓冲机制
  4. 避免频繁调用 shutdown() - 在应用退出前调用一次即可

注意事项

  • 日志缓冲在 1 秒后自动 flush,确保消息最终会被写入
  • 应用退出时调用 logger.shutdown() 以确保所有消息被正确写入
  • 日志文件按天轮转,使用格式 {path}_YYYYMMDD.log
  • 消息最大长度建议 < 65,536 字符(channel 容量)

许可证

MIT License


贡献

欢迎提交 Issues 和 Pull Requests!


性能数据详解

为什么 NexusLog 这么快?

  1. 系统调用优化 (>60% 性能提升)

    • 时间戳获取从每条消息 1 次系统调用降到 ~1/百万
    • 文件写入从每条消息 1 次系统调用降到 ~1/秒
  2. 内存分配优化 (>20% 性能提升)

    • 避免 GC 暂停
    • 更好的缓存局部性
  3. 异步架构 (>10% 性能提升)

    • 主线程不阻塞
    • 利用多核处理器
  4. Rust vs Python (>90% 性能提升)

    • 零开销抽象
    • 编译时优化
    • 无 GC 暂停

基准测试环境

  • 消息数: 1,000,000
  • 消息大小: 平均 ~80 字符
  • 并发度: 单线程
  • 输出: 文件(每日轮转)

常见问题

Q: NexusLog 支持多线程吗? A: 是的。每个 Logger 实例在创建时都是线程安全的,多个线程可以同时调用同一个 logger。

Q: 日志会丢失吗? A: 一般不会。异步 channel 有 65,536 条消息的缓冲。在极端情况下如果 channel 满了,消息会被丢弃(返回发送错误)。

Q: 可以自定义日志格式吗? A: 当前版本格式固定为:time=YYYY-MM-DDTHH:MM:SS.MMMMMM±HH:MM level=LEVEL name=NAME msg="MESSAGE"

Q: 性能数据如何重现? A: 运行 python benches/bench_python.py 进行 Python 基准测试。

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

nexuslog-0.1.0.tar.gz (23.5 kB view details)

Uploaded Source

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

nexuslog-0.1.0-cp313-cp313-win_amd64.whl (215.3 kB view details)

Uploaded CPython 3.13Windows x86-64

nexuslog-0.1.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (394.9 kB view details)

Uploaded CPython 3.13manylinux: glibc 2.17+ x86-64

nexuslog-0.1.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (393.8 kB view details)

Uploaded CPython 3.13manylinux: glibc 2.17+ ARM64

nexuslog-0.1.0-cp313-cp313-macosx_11_0_arm64.whl (350.2 kB view details)

Uploaded CPython 3.13macOS 11.0+ ARM64

nexuslog-0.1.0-cp313-cp313-macosx_10_12_x86_64.whl (356.1 kB view details)

Uploaded CPython 3.13macOS 10.12+ x86-64

nexuslog-0.1.0-cp312-cp312-win_amd64.whl (215.3 kB view details)

Uploaded CPython 3.12Windows x86-64

nexuslog-0.1.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (394.7 kB view details)

Uploaded CPython 3.12manylinux: glibc 2.17+ x86-64

nexuslog-0.1.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (394.2 kB view details)

Uploaded CPython 3.12manylinux: glibc 2.17+ ARM64

nexuslog-0.1.0-cp312-cp312-macosx_11_0_arm64.whl (350.4 kB view details)

Uploaded CPython 3.12macOS 11.0+ ARM64

nexuslog-0.1.0-cp312-cp312-macosx_10_12_x86_64.whl (356.1 kB view details)

Uploaded CPython 3.12macOS 10.12+ x86-64

nexuslog-0.1.0-cp311-cp311-win_amd64.whl (217.0 kB view details)

Uploaded CPython 3.11Windows x86-64

nexuslog-0.1.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (397.9 kB view details)

Uploaded CPython 3.11manylinux: glibc 2.17+ x86-64

nexuslog-0.1.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (396.7 kB view details)

Uploaded CPython 3.11manylinux: glibc 2.17+ ARM64

nexuslog-0.1.0-cp311-cp311-macosx_11_0_arm64.whl (351.8 kB view details)

Uploaded CPython 3.11macOS 11.0+ ARM64

nexuslog-0.1.0-cp311-cp311-macosx_10_12_x86_64.whl (357.5 kB view details)

Uploaded CPython 3.11macOS 10.12+ x86-64

File details

Details for the file nexuslog-0.1.0.tar.gz.

File metadata

  • Download URL: nexuslog-0.1.0.tar.gz
  • Upload date:
  • Size: 23.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: maturin/1.11.5

File hashes

Hashes for nexuslog-0.1.0.tar.gz
Algorithm Hash digest
SHA256 efc7659d6b5a96c97c886f8cd2eb38362956ae721929bf8bf00d4fdd522075f1
MD5 edaaf382eb66b31ef1631075a86478a1
BLAKE2b-256 abbd29972aac5170e47afa1a14d07c6d9bccc0cc6c060bafe19158d0e9e3bea0

See more details on using hashes here.

File details

Details for the file nexuslog-0.1.0-cp313-cp313-win_amd64.whl.

File metadata

File hashes

Hashes for nexuslog-0.1.0-cp313-cp313-win_amd64.whl
Algorithm Hash digest
SHA256 59999b4fa35168eb915c4b81ac6faedd6a96a309e2f5763a9110881873a74b51
MD5 7b91b2262690b74cee01c5970882dc30
BLAKE2b-256 d8bf0c890e5c95ba6eb2d24533f07118623383aaf760c381d289aa357392f247

See more details on using hashes here.

File details

Details for the file nexuslog-0.1.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for nexuslog-0.1.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 517717c756415756ce248d49e3dfb795f5a1f2aa6375440b6e5dd011e0a63333
MD5 d22887c72009d16488fea465b0d9f2f0
BLAKE2b-256 5c8d2dce03d8f992bbbfd3ab92b97d827661988879d04ad26a722ce938848b05

See more details on using hashes here.

File details

Details for the file nexuslog-0.1.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.

File metadata

File hashes

Hashes for nexuslog-0.1.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 fc2336fe18f532051d2432a3f7b5d8b2c65cd86eebe2063dae1d124e21bda5ef
MD5 675b5324ad154130118cb5eba4d3fae6
BLAKE2b-256 2f658f1b7aa83e713fa15122f848ba16ab2d6f333f76fc6883629a7227db4f1d

See more details on using hashes here.

File details

Details for the file nexuslog-0.1.0-cp313-cp313-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for nexuslog-0.1.0-cp313-cp313-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 01b8ac7c6d9ec6e580c851dd93e3942df601853e18dd8ae803c02bcba224b75f
MD5 b8c652e209ac84fb8476ed7367726a71
BLAKE2b-256 b9f9f80856e294f80c4641e5a434d26473a6a4783fa8c6de62180ef902389c9c

See more details on using hashes here.

File details

Details for the file nexuslog-0.1.0-cp313-cp313-macosx_10_12_x86_64.whl.

File metadata

File hashes

Hashes for nexuslog-0.1.0-cp313-cp313-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 7acea28a5e6ff8547e4693b0130b21377379edc9038e868397e93e7817f6f3ae
MD5 1fc43952feed28f20f9fd9a69b0cec9b
BLAKE2b-256 57c01cee099ab3122a0c649c81794b4b5924a170fb380b82742d894d43a76e4b

See more details on using hashes here.

File details

Details for the file nexuslog-0.1.0-cp312-cp312-win_amd64.whl.

File metadata

File hashes

Hashes for nexuslog-0.1.0-cp312-cp312-win_amd64.whl
Algorithm Hash digest
SHA256 7c1ab213565dcb71bd9fc7bc1007bb3e1b23f4b632eaf9c5face952f5e170666
MD5 a392f98589b9fc8ec8635e6b78d51313
BLAKE2b-256 a3238389b0eb150268696b4f32fcb681a0ed1bdbba2d7fd9b2d51a44eda412ee

See more details on using hashes here.

File details

Details for the file nexuslog-0.1.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for nexuslog-0.1.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 b214414c292b5f0b800bf09764961587605c4980838dd652456370150b9146a8
MD5 cbc8cfee70b36db2b3907b526a3031f8
BLAKE2b-256 cf264e9aaa0aea768fee955c0a6c6b021f5b58b9a86dd2345e524f587329f0ab

See more details on using hashes here.

File details

Details for the file nexuslog-0.1.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.

File metadata

File hashes

Hashes for nexuslog-0.1.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 974480dc4594ca6622c4e1a5bca3160255917d6bfdbc35cde50f05cb83d10530
MD5 0e4030b95a6b46027f3b170d2448fab8
BLAKE2b-256 d528e22f91db0cdf8ed95eea5e57900d33820f815709f500adf01e53e716a690

See more details on using hashes here.

File details

Details for the file nexuslog-0.1.0-cp312-cp312-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for nexuslog-0.1.0-cp312-cp312-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 513378a1d1d9198bb9918d4099be54da394989d87a1aaac274d35ff5cd7a566f
MD5 7b4e8df55628fc9f352ad5ac1cab577f
BLAKE2b-256 f4be6122f8993a6756072697aeb4fa261954f35e451d6f4aa3bfe989c48e8923

See more details on using hashes here.

File details

Details for the file nexuslog-0.1.0-cp312-cp312-macosx_10_12_x86_64.whl.

File metadata

File hashes

Hashes for nexuslog-0.1.0-cp312-cp312-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 3a362aec3e9f3a0ed20a27225020406f689cbc5463d5e945fe8c373df96b64bb
MD5 45a6a4e22ea9092ec5dd9a9a20095a3e
BLAKE2b-256 6192c90cc302e801b47f5145e466b906e1288db2440015833218137ccd739571

See more details on using hashes here.

File details

Details for the file nexuslog-0.1.0-cp311-cp311-win_amd64.whl.

File metadata

File hashes

Hashes for nexuslog-0.1.0-cp311-cp311-win_amd64.whl
Algorithm Hash digest
SHA256 176b25dd62c6c0c445c7d2e1e538d4b05c99ce4db849ca4c4647b8ce54e83b26
MD5 2e4a3dc0e1fbf498e9afbb4d9da6f179
BLAKE2b-256 6144bd066127e9f21ea2ee2270ae2cdcfc68d209193a0a5c3afad601634df581

See more details on using hashes here.

File details

Details for the file nexuslog-0.1.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for nexuslog-0.1.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 f2efdc4ee09f67ff8a661590403059812d912f8edc8d76744e5844627a0b3b4a
MD5 8de0433bf83df13fd9e60586c11fb79f
BLAKE2b-256 f67443d143173fc1900749852ec0e59b5b7be92a6194057f7e1160b170986ea2

See more details on using hashes here.

File details

Details for the file nexuslog-0.1.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.

File metadata

File hashes

Hashes for nexuslog-0.1.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 4536a71f09a2c9109e3faeb1200499b8e63148c1576c057db62c2e17b267b4ee
MD5 cd9f2a0e875b737b059e23a098333a4b
BLAKE2b-256 89ed993e44d144c9fbf412a6e8966cad003c517678fc88d8c5f4a2036345a07f

See more details on using hashes here.

File details

Details for the file nexuslog-0.1.0-cp311-cp311-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for nexuslog-0.1.0-cp311-cp311-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 3b6235ed79ae202d2013e8ffaa91713132684044dd6e0397d776b6ca71c46ea0
MD5 83cadb5477b0a48636ee1a02c65a4480
BLAKE2b-256 9df650dc9c8ad0fbf9004f2236b7165b9cf66dc4f8d828de5eb5bdbdee340480

See more details on using hashes here.

File details

Details for the file nexuslog-0.1.0-cp311-cp311-macosx_10_12_x86_64.whl.

File metadata

File hashes

Hashes for nexuslog-0.1.0-cp311-cp311-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 77cee998cc85f208fe0123124289899381caeaac942c2f851b7e0257665c9032
MD5 99b8071352249cc565140bd63681f1b5
BLAKE2b-256 b76b0adacae2f998a57ff59569cc9cf72e0378bbc5763e054070ffd0d882af4d

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page