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.3.0.tar.gz (24.0 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.3.0-cp313-cp313-win_amd64.whl (215.6 kB view details)

Uploaded CPython 3.13Windows x86-64

nexuslog-0.3.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (395.2 kB view details)

Uploaded CPython 3.13manylinux: glibc 2.17+ x86-64

nexuslog-0.3.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (394.2 kB view details)

Uploaded CPython 3.13manylinux: glibc 2.17+ ARM64

nexuslog-0.3.0-cp313-cp313-macosx_11_0_arm64.whl (350.5 kB view details)

Uploaded CPython 3.13macOS 11.0+ ARM64

nexuslog-0.3.0-cp313-cp313-macosx_10_12_x86_64.whl (356.5 kB view details)

Uploaded CPython 3.13macOS 10.12+ x86-64

nexuslog-0.3.0-cp312-cp312-win_amd64.whl (215.6 kB view details)

Uploaded CPython 3.12Windows x86-64

nexuslog-0.3.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (395.1 kB view details)

Uploaded CPython 3.12manylinux: glibc 2.17+ x86-64

nexuslog-0.3.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (394.6 kB view details)

Uploaded CPython 3.12manylinux: glibc 2.17+ ARM64

nexuslog-0.3.0-cp312-cp312-macosx_11_0_arm64.whl (350.7 kB view details)

Uploaded CPython 3.12macOS 11.0+ ARM64

nexuslog-0.3.0-cp312-cp312-macosx_10_12_x86_64.whl (356.3 kB view details)

Uploaded CPython 3.12macOS 10.12+ x86-64

nexuslog-0.3.0-cp311-cp311-win_amd64.whl (217.3 kB view details)

Uploaded CPython 3.11Windows x86-64

nexuslog-0.3.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (398.2 kB view details)

Uploaded CPython 3.11manylinux: glibc 2.17+ x86-64

nexuslog-0.3.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (397.3 kB view details)

Uploaded CPython 3.11manylinux: glibc 2.17+ ARM64

nexuslog-0.3.0-cp311-cp311-macosx_11_0_arm64.whl (352.1 kB view details)

Uploaded CPython 3.11macOS 11.0+ ARM64

nexuslog-0.3.0-cp311-cp311-macosx_10_12_x86_64.whl (357.9 kB view details)

Uploaded CPython 3.11macOS 10.12+ x86-64

File details

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

File metadata

  • Download URL: nexuslog-0.3.0.tar.gz
  • Upload date:
  • Size: 24.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for nexuslog-0.3.0.tar.gz
Algorithm Hash digest
SHA256 14523495c1ecc859e6bc9dd94a5cddf7c8b0d492410def336c7ef6cf41e7af4e
MD5 9386831f22646866e695482f893cf3dd
BLAKE2b-256 4dc8d5b3e6d1fe2a49b72fafb11f8d6bbe399fb12a3cbacb0729d1dedb4a2852

See more details on using hashes here.

File details

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

File metadata

  • Download URL: nexuslog-0.3.0-cp313-cp313-win_amd64.whl
  • Upload date:
  • Size: 215.6 kB
  • Tags: CPython 3.13, Windows x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for nexuslog-0.3.0-cp313-cp313-win_amd64.whl
Algorithm Hash digest
SHA256 d8db81b95a67d4022002c1c4fb4e950e1b337b28ff0dd90090068d75c4bd87a4
MD5 a9279353d585111b34be691da080f063
BLAKE2b-256 16f7d2932c386476e07dcd4e047eb33e2e9285933368d43735e2f1f87cbdc1b7

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for nexuslog-0.3.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 3d6646b24a81c54c56bd97caad05ddac27e7c3c206de1f11c011f2b14969b55e
MD5 789abed33cff9bb4bd9d8244be671b69
BLAKE2b-256 a4b3978473a6a8833633f589cd0dfe6643055ec4ab3786a12ecdfed76ab5a796

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for nexuslog-0.3.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 cfac0d2ae66a281466e1b38ca9ccdfdfbdfbccc78eea91f323c6bef8dbb7a62d
MD5 92729e30917da6338c325bccfc9f9726
BLAKE2b-256 d6878dc1ea352dbadb1e25bd2e09bb7a30193b66c91672fbe56eabb0d436c7ac

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for nexuslog-0.3.0-cp313-cp313-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 93fed3eacc8a65954f7bfe298c73c15aa2e695e35751cc6d73663e5aaaed80a8
MD5 046c505e97052feef65309ec072ab5ac
BLAKE2b-256 9c689959f986c0422d861ca8645610db37cacb017210a0c6ad3e92298ba8f19f

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for nexuslog-0.3.0-cp313-cp313-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 42825f5c0c8f4ef84369259ef45162c83cfa226f009ea6a4bd1393632a923d2d
MD5 9bb0693bacbb6c0e92e5ab98d2dcbc9a
BLAKE2b-256 2a3f8eb6285dac9d5202c7bdce6bb5de3237d006f4184ef19f2a505606c35dbd

See more details on using hashes here.

File details

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

File metadata

  • Download URL: nexuslog-0.3.0-cp312-cp312-win_amd64.whl
  • Upload date:
  • Size: 215.6 kB
  • Tags: CPython 3.12, Windows x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for nexuslog-0.3.0-cp312-cp312-win_amd64.whl
Algorithm Hash digest
SHA256 cec3ec1a98327b23a060eb4c0198954b3af30f344a0a49b196fb043d0e9531af
MD5 cfbdd0587eef427e34cbb924f5daa736
BLAKE2b-256 ac78a78d9aa9d84bd0993df5056c5477e16f5e2b54191b0ef45fd34c1a7055df

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for nexuslog-0.3.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 224f721284789f55c897f02050233337122d3b7c43dcf6dfe6472797e5eb0fe9
MD5 d1c3689aa8604d4924a848a7fc99ad51
BLAKE2b-256 9c832431d5a463cfc74d3821cc9c7a2c027de4506774b539be4133b88e1ac1f0

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for nexuslog-0.3.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 249bd177d902d60840a7d34d40fc55cbf1a8ecabbdd739581ab84279e0a52a62
MD5 b81ea10097bd0bddb14dd11c19bdccfb
BLAKE2b-256 b09925f1e60883eef43528dda61926048effd9caef986b57b693700772e23ae1

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for nexuslog-0.3.0-cp312-cp312-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 21c40cf439ed8f5e307d667157eecf26fed7a0c660a16fc1099fad6584e64c32
MD5 a78cba719bd74667d7cf289793d5ab56
BLAKE2b-256 723316f0aa1ac6f040d017c454aaab9460483d5ce284ad08a912f1d04f3a91a1

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for nexuslog-0.3.0-cp312-cp312-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 7e4d1d199ff7dda6b0048fc85eaf91865a5eb4e672cef6c5da949b9c10b9b38b
MD5 6fd8dfb318a36bc744b9f8f059d3b5b4
BLAKE2b-256 d3f0ff6f071b9694fdaf1a56dee4de9d08e1ca4532bb83294244a4a323b2c5ef

See more details on using hashes here.

File details

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

File metadata

  • Download URL: nexuslog-0.3.0-cp311-cp311-win_amd64.whl
  • Upload date:
  • Size: 217.3 kB
  • Tags: CPython 3.11, Windows x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for nexuslog-0.3.0-cp311-cp311-win_amd64.whl
Algorithm Hash digest
SHA256 717853a2938c00135675f7989489816b7d79ad277aacb333716e90319b65ea98
MD5 e450baa263450d117a4503a84868dde1
BLAKE2b-256 1ec031f6976e869e2dab905684a8387a3846d2050a62e523c97c1f0f41c6969b

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for nexuslog-0.3.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 678270c3a145f3bb6edacc590f2221558be1af22eb2c1f560b8fb3182c738a11
MD5 3e6e970dd83c918f7a94e8d2ace95a28
BLAKE2b-256 d9dc585780352b38c5c2278fc17bc546f91b7e8997846e94bce3d42343627fba

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for nexuslog-0.3.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 8f16e95531cc7a6b5a3da88ce68cb8876834b5bd8daeecb0a0c24b8160fab47a
MD5 66fdce0385664b16a40e5d9db385e0f4
BLAKE2b-256 2f0a137062206d3f25004210d0c3d94b3191110d988940444ef28c72e03ff718

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for nexuslog-0.3.0-cp311-cp311-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 71037d4556107a0ce07f8071bff96f86be11e9a42e3e53eaf3fe273882804bb6
MD5 bfe612f5b5d4e0fbc4a1e81d361f1e52
BLAKE2b-256 947d67410096514faf925f4f392741f1018c43877ac09438384d9efebda6c085

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for nexuslog-0.3.0-cp311-cp311-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 e78914e715480509f94e88f420a197ba13c27d8ca41da3c091ef42ac31e6f8c6
MD5 a69e58539ed79e2718edb70b81fade99
BLAKE2b-256 79190440c13ac5ce852d57f6e4b733bbff73ab0d014495d0a2677a0fea90aeed

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