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

Uploaded CPython 3.13Windows x86-64

nexuslog-0.2.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.2.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.2.0-cp313-cp313-macosx_11_0_arm64.whl (350.5 kB view details)

Uploaded CPython 3.13macOS 11.0+ ARM64

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

Uploaded CPython 3.13macOS 10.12+ x86-64

nexuslog-0.2.0-cp312-cp312-win_amd64.whl (215.7 kB view details)

Uploaded CPython 3.12Windows x86-64

nexuslog-0.2.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (395.0 kB view details)

Uploaded CPython 3.12manylinux: glibc 2.17+ x86-64

nexuslog-0.2.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (394.7 kB view details)

Uploaded CPython 3.12manylinux: glibc 2.17+ ARM64

nexuslog-0.2.0-cp312-cp312-macosx_11_0_arm64.whl (350.8 kB view details)

Uploaded CPython 3.12macOS 11.0+ ARM64

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

Uploaded CPython 3.12macOS 10.12+ x86-64

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

Uploaded CPython 3.11Windows x86-64

nexuslog-0.2.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (398.1 kB view details)

Uploaded CPython 3.11manylinux: glibc 2.17+ x86-64

nexuslog-0.2.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.2.0-cp311-cp311-macosx_11_0_arm64.whl (352.2 kB view details)

Uploaded CPython 3.11macOS 11.0+ ARM64

nexuslog-0.2.0-cp311-cp311-macosx_10_12_x86_64.whl (357.8 kB view details)

Uploaded CPython 3.11macOS 10.12+ x86-64

File details

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

File metadata

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

File hashes

Hashes for nexuslog-0.2.0.tar.gz
Algorithm Hash digest
SHA256 776250cf3d34d0f2f753b40c9c8ec5a49c742483d292766b01fc04e762ffca2d
MD5 fa982f9c9f1ddcc77bf7c3b8c478680f
BLAKE2b-256 97283250d7de73d380f37c84c0d62566d4e81e19adb46a6d5438bed5cb3dd26a

See more details on using hashes here.

File details

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

File metadata

  • Download URL: nexuslog-0.2.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.2.0-cp313-cp313-win_amd64.whl
Algorithm Hash digest
SHA256 6e9371e89c75f7957b1b457ecd1abbf78f03fb3f686f4b97aa4be9c3f19a2f7c
MD5 8270b74aa948c37c364b768c59922dd7
BLAKE2b-256 e06b48a6364091bd4692f040477b1aa883098fc2c7870a12271f55c402316d21

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for nexuslog-0.2.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 4e2bc31d03911df71d486add14bc52b403bcf6b3fa9c254c367e73cf411ead61
MD5 3b584189c249f15eb5f13850b061f196
BLAKE2b-256 5ae07a1f662225870c3fc0cc9b8fbc66e8b7d6f44d3c5236d2f7a845bc1313ee

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for nexuslog-0.2.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 4864707908301b20dff2842c0b1808a6608d2823852205d7bc536a205477aa4b
MD5 16d1e3b76eb724577d1dc9ba6f67fcf5
BLAKE2b-256 f315d4bb9f468a7126cdbed7893716d68133c8c4a7e9aa0ea2dc7c88d3f13d96

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for nexuslog-0.2.0-cp313-cp313-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 cc01d345c35f72c67ab0fdcf1a2a69929bc8b4ccccc63127b9db5f6c77ef641b
MD5 5fc04a48dad287e0909bdde59c5f4916
BLAKE2b-256 43eb7084ae454de6a529283e2e973e6811c23b37eaf53b8a625a2de446351247

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for nexuslog-0.2.0-cp313-cp313-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 f794edef867c1e7416df3b42c4cac6fd40122f9a453b51c8d19f3a989e299ce8
MD5 7c6b5435df1a2ed3cafd9ea723e12619
BLAKE2b-256 5a3197480cca9123906ff7027e8c1ee1cf577145d25ab46843a918ecd00ec262

See more details on using hashes here.

File details

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

File metadata

  • Download URL: nexuslog-0.2.0-cp312-cp312-win_amd64.whl
  • Upload date:
  • Size: 215.7 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.2.0-cp312-cp312-win_amd64.whl
Algorithm Hash digest
SHA256 a46ef1b3098fc0fd0395eae7e27197d44bd304d892a6c60766eeb4898f223a8b
MD5 6b5f49105cfaf42324530c533b09915d
BLAKE2b-256 228b87b3b393765171d7e8ce08b2f9a9ce1306e91e130a92a44675b5f02aa172

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for nexuslog-0.2.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 419dfcfa15d2bf935b8f06dd6882c2619230311ff22141bd67513639575d668b
MD5 4bfe9c934107a5505f3573d04118dc74
BLAKE2b-256 0f784904a27971d7fdfc0d243f2d645f607c237c31fd26ba5b169ab38b3cf61f

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for nexuslog-0.2.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 157695e4a5b3c38447ae5cc5be24751cf6cc2ec31a1e87d61db230881b5ec458
MD5 bb06bcf77885c458fac31588b61557de
BLAKE2b-256 b21858ea66fe0ed193e2cf4b16a88bf0b43b20ac25e5c1dc3cddc788583198c5

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for nexuslog-0.2.0-cp312-cp312-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 b5e9bf90dd5d00dd18d28e0265e2624a10149f0696d8d0890084ade6e3b51584
MD5 d5b7c113c6c03eb80e6490dc5b54e5a1
BLAKE2b-256 c651fef881da137aa1c4c5b052285721055c53b5536483f7a91c813bca11e879

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for nexuslog-0.2.0-cp312-cp312-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 96787ff4620ef1b03ce2ca837acf69f6994836693fd68bae500bc355365fe822
MD5 c9dc9188780b4829bccd8fd2d0c16671
BLAKE2b-256 71c2e81d50705edde63939bc9494f57990bd69e50893ebfae1b0bf70aac81449

See more details on using hashes here.

File details

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

File metadata

  • Download URL: nexuslog-0.2.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.2.0-cp311-cp311-win_amd64.whl
Algorithm Hash digest
SHA256 47c4e929ea078025d41141b71a80c6102fa03af87150f385459f523745edd862
MD5 83997fe58c6946553a9717d8bb10099c
BLAKE2b-256 c258e7e6a8f37d3caec1b06a7b6db5f72bad6ef2f759f33dc0fbf3c429140074

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for nexuslog-0.2.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 67e8d6ec7a1f2a849f8070b485e791980d47e068ff32e4499214871c51e39b59
MD5 2e7c579794356672f9ae6dc5d0fc79ce
BLAKE2b-256 1632a108c4334a6b897fe4e5adc5e29bc7a6ab35e1710447e687357382d110ca

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for nexuslog-0.2.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 e187b16c12bf33a4f8d3f48663365a2511f108e5ac76d49961dc069add8f066e
MD5 92facea9fe5b910a1a8d0273df814f82
BLAKE2b-256 1c60d933b6bb672e6c2a33613c4ce209e83bd590edc389e7fc2d08bf29de084a

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for nexuslog-0.2.0-cp311-cp311-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 ba8c63d05300d4adae126a9991df77b5a0ea93413f423712a2ee480be1545d3e
MD5 4aaaab08a33fa9bdf9cb5f3ea407cbf3
BLAKE2b-256 a593b9f3b222f67124144bcff4d523fa5d02af3a1e16d699d6184bdf97ed0654

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for nexuslog-0.2.0-cp311-cp311-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 02526252a030e02c269068973bb29988a4f9e21e920e20b647b851745fd31199
MD5 02c34b568b263a89d0551cc9360083e5
BLAKE2b-256 43387a914fe9f3d518b2fefcf2656f8877d8b32368b03c41267ecc3c3832f29d

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