Metadata-Version: 2.1
Name: insightoslog
Version: 1.0.10
Summary: InsightOS Log SDK - Unified log collection SDK
Home-page: https://gitee.com/hong-zhenhuang/InsightOsLogSDK
Author: InsightOS Team
Author-email: team@insightos.org
License: UNKNOWN
Platform: UNKNOWN
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: Apache Software License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.7
Classifier: Programming Language :: Python :: 3.8
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Software Development :: Libraries
Requires-Python: >=3.7
Description-Content-Type: text/markdown

# InsightOS Log SDK 统一日志接口

InsightOS Log SDK 是一个跨语言的结构化日志 SDK，支持 C++、Go、Python 三种语言。提供统一 JSON 格式输出、链路追踪（Trace/Span）、跨线程/协程上下文传播、异步日志等功能。

---

## 目录

- [快速开始](#快速开始)
  - [C++ SDK](#1-c-sdk)
  - [Go SDK](#2-go-sdk)
  - [Python SDK](#3-python-sdk)
- [示例代码](#示例代码)
  - [C++ 示例](#c-示例)
  - [Go 示例](#go-示例)
  - [Python 示例](#python-示例)
- [功能特性](#功能特性)
- [日志结构](#日志结构)
- [配置文件](#配置文件)
- [API 参考](#api-参考)
- [输出模式](#输出模式)
- [文件滚动策略](#文件滚动策略)
- [依赖说明](#依赖说明)
- [打包发布](#打包发布)

---

## 快速开始

### 1. C++ SDK

#### 安装

**方式一：APT 在线安装（推荐）**

```bash
# 添加 APT 源（amd64）
echo "deb [trusted=yes arch=amd64] https://cdn.jsdelivr.net/gh/HongZH-XMU/insightoslog-apt@main/ stable main" | \
  sudo tee /etc/apt/sources.list.d/insightos.list

# 更新并安装
sudo apt update
sudo apt install libinsightoslog-dev
```

> arm64 架构：将上面 `arch=amd64` 改为 `arch=arm64` 即可。

**方式二：手动下载 deb 安装**

```bash
curl -LO https://cdn.jsdelivr.net/gh/HongZH-XMU/insightoslog-apt@main/pool/main/l/libinsightoslog-dev/libinsightoslog-dev_1.0.9_amd64.deb
sudo dpkg -i libinsightoslog-dev_amd64.deb
sudo apt install -f
```

**方式三：源码编译**

```bash
cd cpp
xmake f -m release
xmake
```

#### 编译运行

安装后直接编译，无需额外参数：

```bash
g++ -std=c++17 main.cpp -linsightoslog-log -lpthread -ldl -o myapp
./myapp
```

> 安装后需运行 `sudo ldconfig` 更新动态库缓存。

---

### 2. Go SDK

#### 安装

```bash
go env -w GOPROXY=https://goproxy.cn,direct
go env -w GOSUMDB=off
go get gitee.com/hong-zhenhuang/InsightOsLogSDK/go@v1.0.4
```

#### 编译运行

```bash
go build -o myapp main.go
./myapp
```

---

### 3. Python SDK

#### 安装

```bash
pip install insightoslog
```

#### 运行

```bash
python main.py
```

---

## 示例代码

### C++ 示例

用户代码只需包含一个头文件，使用两种调用风格：

```cpp
#include <insightoslog/wrapper/wrapper.hpp>

using namespace insightoslog;

int main() {
    // 初始化
    InitParam config;
    config.level = LogLevel::INFO;
    config.service_name = "MyService";
    config.output = "stdout";
    Logger::Init(config);

    // 开启链路
    Logger::StartNewTrace();

    // 方式一：IOSLOG_* 宏（推荐，带 caller：file/line/function）
    IOSLOG_INFO("服务启动成功");
    IOSLOG_INFO("用户 {} 登录了系统", "alice");
    IOSLOG_WARN("警告：value={} 超过阈值", 100);
    IOSLOG_ERROR("错误码: {}, 错误信息: {}", 5001, "Connection refused");

    // 方式二：LogBuilder 链式调用（带 caller）
    Logger::GetCurrentContext().log().info("处理请求")
        .on_request({{"method", "POST"}, {"path", "/api/users"}})
        .with_data(params, result)
        .latency(50)
        .send();

    // 方式三：Logger::Info 系列（不带 caller，适用于不需要 caller 信息的场景）
    Logger::Info("收到请求");

    // HTTP Header 传播
    auto headers = Logger::GetPropagationHeaders();
    // 将 headers.trace_id / headers.span_id 放到 HTTP Header 中传递给下游

    // 关闭
    Logger::Shutdown();
    return 0;
}
```

完整示例见 [`examples/cpp/main.cpp`](examples/cpp/main.cpp)。

---

### Go 示例

```go
package main

import (
    log "gitee.com/hong-zhenhuang/InsightOsLogSDK/go"
)

func main() {
    // 初始化
    log.Init(log.InitParam{
        ServiceName: "MyService",
        Level:       log.LevelInfo,
        Output:      "stdout",
    })

    // 开启链路
    log.StartNewTrace()

    // 方式一：直接函数调用（推荐）
    log.Info("服务启动成功")
    log.Infof("用户 %s 登录了系统", "alice")

    // 方式二：Logger 类封装
    logger := log.NewLogger(log.LoggerInitParam{ServiceName: "MyService"})
    logger.Info("收到请求")

    // 方式三：建造者模式
    ctx := log.GetCurrentContext()
    ctx.Info("处理请求").
        OnRequest(log.EventRequest{Method: "POST", Path: "/api/users", LatencyMs: 50}).
        WithData(map[string]interface{}{"user": "alice"}, nil).
        Send()

    // HTTP Header 传播
    headers := log.GetPropagationHeaders()
    // 将 headers.TraceID / headers.SpanID 放到 HTTP Header 中传递给下游

    log.Shutdown()
}
```

完整示例见 [`examples/go/main.go`](examples/go/main.go)。

---

### Python 示例

```python
import insightoslog as log

# 初始化
log.init({"service_name": "MyService", "level": "info", "output": "stdout"})

# 开启链路
log.start_new_trace()

# 方式一：直接函数调用（推荐）
log.info("服务启动成功")
log.info("用户 {} 登录了系统".format("alice"))

# 方式二：Logger 类封装
log.Logger.info("收到请求")

# 方式三：建造者模式
ctx = log.current_context()
ctx.info("处理请求") \
    .on_request({"method": "POST", "path": "/api/users"}) \
    .with_data({"user": "alice"}, None) \
    .latency(50) \
    .send()

# 方式四：上下文管理器
with log.Trace.start_new_trace():
    log.info("请求开始")
    # ... 业务逻辑 ...
    log.info("请求结束")

# HTTP Header 传播
headers = log.Trace.get_propagation_headers()
# 将 headers["trace_id"] / headers["span_id"] 放到 HTTP Header 中传递给下游

log.shutdown()
```

完整示例见 [`examples/python/main.py`](examples/python/main.py)。

---

## 功能特性

| 特性 | 说明 |
|------|------|
| **结构化 JSON 日志** | 按域组织的 JSON 输出，支持 `meta`、`resource`、`context`、`event`、`data`、`error`、`caller` 等域 |
| **链路追踪** | 自动生成 `trace_id` 和 `span_id`，支持 HTTP Header 传播和跨线程/协程自动继承 |
| **Caller 信息** | 编译时宏展开捕获调用点 file/line/function，精确到用户代码行 |
| **stdout 颜色输出** | 终端输出带 ANSI 颜色高亮，按日志级别着色，整条日志同一颜色 |
| **域过滤** | stdout 可按需过滤输出域（如只显示 `event`），文件输出全量域 |
| **异步日志** | 内存缓冲区 + 定时刷新，大幅提升高并发场景性能 |
| **敏感信息过滤** | 自动过滤密码、Token、API Key 等敏感信息 |
| **建造者模式** | 链式调用支持 `on_request`、`with_data`、`with_error`、`latency` 等方法 |
| **多语言统一** | C++ / Go / Python 三种语言 API 风格一致 |
| **文件滚动** | 按大小自动滚动，支持配置最大文件和单文件大小 |

---

## 日志结构

终端输出格式（stdout）：

```
LEVEL YYYY-MM-DDTHH:MM:SS.sss+08:00 [PID] {"event":{"msg":"..."}}
```

完整 JSON 结构：

```json
{
  "meta": {
    "level": "INFO",
    "time": "2026-03-11T10:00:00.000+08:00"
  },
  "resource": {
    "type": "ability",
    "name": "MyService",
    "instance_id": "abc-123",
    "pid": 12345
  },
  "context": {
    "trace_id": "550436d474944d77a6833ba578d53e6d",
    "span_id": "767461a9d8ea41f29c3defe40a755ede",
    "parent_span_id": ""
  },
  "event": {
    "msg": "Ability onStart",
    "request": { "method": "POST", "latency_ms": 50 }
  },
  "data": {
    "param": {"key": "value"},
    "result": {"status": "ok"}
  },
  "error": {
    "type": "RuntimeError",
    "message": "connection failed"
  },
  "caller": {
    "file": "main.cpp",
    "line": 42,
    "function": "main"
  }
}
```

**stdout vs 文件输出区别：**

| 域 | stdout | 文件 |
|----|--------|------|
| `meta` | - | ✅ |
| `resource` | - | ✅ |
| `context` | - | ✅ |
| `event` | ✅（默认） | ✅ |
| `data` | - | ✅ |
| `error` | - | ✅ |
| `caller` | ✅（默认） | ✅ |

可通过 `stdout_fields` 配置覆盖默认行为。

---

## 配置文件

所有 SDK 均支持 `InsightOSLogConfig.yaml` 配置文件：

```yaml
level: INFO
service_type: "ability"
service_name: "MyService"
instance_id: "instance-001"
log_root: "/var/log/insightos"
output: "stdout"               # stdout 或 rotate_file

file:
  max_size: 5242880           # 单文件最大字节数 (5MB)
  max_files: 3                # 保留的旧日志文件数量

async:
  buffer_size: 4096           # 异步队列大小 (字节)
  flush_interval: 2            # 刷新间隔 (秒)

enable_tracing: true
stdout_fields: ["event", "caller"]  # stdout 输出域（可选）
```

---

## API 参考

### 初始化

| C++ | Go | Python |
|-----|-----|--------|
| `Logger::Init(config)` | `log.Init(param)` | `log.init(param)` |
| `Logger::InitFromConfig(path)` | `log.InitFromConfig(path)` | `log.init_from_config(path)` |
| `Logger::Shutdown()` | `log.Shutdown()` | `log.shutdown()` |
| `Logger::Flush()` | `log.Flush()` | `log.flush()` |
| `set_level(level)` | `log.SetLevel(level)` | `log.set_level(level)` |
| `get_level()` | `log.GetLevel()` | `log.get_level()` |

### 日志记录（便捷函数）

| 级别 | C++ | Go | Python |
|------|-----|-----|--------|
| TRACE | `IOSLOG_TRACE(msg, ...)` | `log.Trace(msg)` | `log.trace(msg)` |
| DEBUG | `IOSLOG_DEBUG(msg, ...)` | `log.Debug(msg)` | `log.debug(msg)` |
| INFO | `IOSLOG_INFO(msg, ...)` | `log.Info(msg)` | `log.info(msg)` |
| WARN | `IOSLOG_WARN(msg, ...)` | `log.Warn(msg)` | `log.warn(msg)` |
| ERROR | `IOSLOG_ERROR(msg, ...)` | `log.Error(msg)` | `log.error(msg)` |
| FATAL | `IOSLOG_FATAL(msg, ...)` | `log.Fatal(msg)` | `log.fatal(msg)` |

### 链路追踪

| 功能 | C++ | Go | Python |
|------|-----|-----|--------|
| 开启新链路 | `Logger::StartNewTrace()` | `log.StartNewTrace()` | `log.start_new_trace()` |
| 继续链路 | `Logger::ContinueTrace(trace_id, span_id)` | `log.ContinueTrace(trace_id, span_id)` | `log.continue_trace(trace_id, span_id)` |
| 注入链路 | `Logger::Inject(trace_id, span_id, parent_span_id)` | `log.Inject(trace_id, span_id, parent_span_id)` | `log.inject(trace_id, span_id, parent_span_id)` |
| 获取 Headers | `Logger::GetPropagationHeaders()` | `log.GetPropagationHeaders()` | `log.get_propagation_headers()` |
| 从 Header 提取 | `Logger::ExtractFromHeaders(headers)` | `log.ExtractFromHeaders(...)` | `log.extract_from_headers(...)` |
| 获取当前 Context | `Logger::GetCurrentContext()` | `log.GetCurrentContext()` | `log.current_context()` |
| 获取 TraceID | `Logger::GetTraceID()` | `log.GetTraceID()` | `log.get_trace_id()` |
| 获取 SpanID | `Logger::GetSpanID()` | `log.GetSpanID()` | `log.get_span_id()` |
| 生成 ID | `GenerateTraceID()` / `GenerateSpanID()` | `log.GenerateTraceID()` / `log.GenerateSpanID()` | `log.generate_trace_id()` / `log.generate_span_id()` |

### 上下文传播（跨线程/协程）

| 功能 | C++ | Go | Python |
|------|-----|-----|--------|
| 准备子线程 | `Logger::PrepareForChildThread()` | `log.PrepareForChildThread()` | `log.prepare_for_child_thread()` |
| 子线程继承 | `Logger::InheritFromPrepared()` | `log.InheritFromPrepared()` | `log.inherit_from_prepared()` |
| 自动继承 | `Logger::InheritFromParent()` | `log.InheritFromParent()` | `log.inherit_from_parent()` |

### 建造者模式

```cpp
// C++
ctx.log().info("msg")
    .on_request({...})
    .with_params({...})
    .with_result({...})
    .with_error({...})
    .latency(50)
    .truncate(true)
    .send();
```

```go
// Go
ctx.Info("msg").
    OnRequest(req).
    WithData(params, result).
    WithError(err).
    Latency(50).
    Send()
```

```python
# Python
ctx.info("msg") \
    .on_request(req) \
    .with_data(params, result) \
    .with_error(err) \
    .latency(50) \
    .send()
```

### 数据结构

| C++ | Go | Python |
|-----|-----|--------|
| `LogLevel` | `LogLevel` | `LogLevel` |
| `InitParam` | `InitParam` / `LoggerInitParam` | `InitParam` |
| `Context` | `Context` | `Context` / `LogContext` |
| `Resource` | `Resource` | `Resource` |
| `Caller` | `Caller` | `Caller` |
| `LogBuilder` | `LogBuilder` | `LogBuilder` |
| `Header::TRACE_ID` | `Header.TRACE_ID` | `HEADER_TRACE_ID` |

---

## 输出模式

| 模式 | 说明 | 颜色 | 格式化 |
|------|------|------|--------|
| `stdout` | 输出到终端 | ✅ 按级别着色 | 紧凑格式（可配置过滤域） |
| `rotate_file` | 输出到滚动日志文件 | ❌ | 完整 JSON（所有域） |

---

## 文件滚动策略

| 参数 | C++ | Go | Python | 默认值 |
|------|-----|-----|--------|--------|
| 单文件最大字节数 | `config.file.max_size` | `config.File.MaxSize` | `config.max_bytes` | 5MB |
| 保留文件数量 | `config.file.max_files` | `config.File.MaxFiles` | `config.backup_count` | 3 |

日志文件路径：`{log_root}/{service_type}/{service_name}.log`

---

## 依赖说明

| 语言 | 依赖 | 说明 |
|------|------|------|
| **C++** | spdlog, nlohmann_json, stduuid, fmt | APT 安装时自动拉取 |
| **Go** | google/uuid, uber-go/zap | go get 时自动拉取 |
| **Python** | 无外部依赖 | 使用标准库 |

---

## 测试覆盖

### C++ 测试 (`test/cpp/`)

| # | 测试 | 说明 |
|---|------|------|
| 1 | 基础初始化 | SDK 初始化测试 |
| 2 | 便捷宏 | `IOSLOG_INFO` 等宏 |
| 3 | fmt 格式化 | 格式化日志消息 |
| 4 | 建造者模式 | 链式调用 API |
| 5 | 请求/数据 | `on_request` / `with_data` |
| 6 | 错误日志 | 错误信息记录 |
| 7 | HTTP Header 传播 | 链路信息 Header 传播 |
| 8 | 跨线程传播 | Context 跨线程继承 |
| 9 | 嵌套 Span | 多级服务调用链路 |
| 10 | make_context | 手动创建 Context |
| 11 | LogBuilder 详细 | `truncate` / `latency` / `with_result` 等 |
| 12 | 多线程日志 | 并发写入测试 |
| 13 | ID 生成 | Trace ID / Span ID 生成 |
| 14 | Header 常量 | HTTP Header 常量验证 |
| 15 | 全局 Resource | Resource 信息测试 |
| 16 | 文件输出 | rotate_file 模式测试 |
| 17 | 异步日志 | 异步队列测试 |
| 18 | 配置文件加载 | InsightOSLogConfig.yaml 加载 |
| 19 | RefreshPID | PID 刷新测试 |
| 20 | stdout 域过滤 | `stdout_fields` 配置测试 |

运行测试：
```bash
cd test/cpp
xmake
xmake run test
```

### Go 测试 (`test/go/`)

**23 个测试用例**：Init、便捷宏、fmt 格式化、HTTP Header 传播、跨 goroutine 传播、Context 函数、多 goroutine 日志、全局 Resource、文件输出、异步日志、RefreshPID、配置加载、所有日志级别、LogBuilder、Context 链式方法、SetLevel/GetLevel、全局资源操作、Logger/Trace 类封装、Error 对象、敏感信息过滤。

运行测试：
```bash
cd test/go
go test -v
```

### Python 测试 (`test/python/`)

**20 个测试函数**：基础初始化、日志级别、格式化、建造者模式、上下文管理器、错误日志、Context 传播、跨线程传播、ID 生成、Context 函数、嵌套 Span、多线程并发、Header 常量、全局 Resource、文件输出、异步日志、RefreshPID、敏感信息过滤、数据结构、LogLevel 类。

运行测试：
```bash
cd test/python
python3 test_main.py
```

---

## 打包发布

使用 `build_package.sh` 一键打包三个 SDK 并发布。

### 用法

```bash
# 默认版本，仅构建
./build_package.sh

# 指定版本
./build_package.sh 2.0.0

# 构建并发布到 PyPI
PYPI_TOKEN=xxx ./build_package.sh 1.0.0

# 构建并推送 APT 仓库
APT_REPO_REMOTE="git@github.com:HongZH-XMU/insightoslog-apt.git" \
  ./build_package.sh 1.0.0
```

### 发布方式

| 语言 | 平台 | 安装命令 |
|------|------|---------|
| **C++** | APT 在线仓库（jsDelivr） | `apt install libinsightoslog-dev` |
| **Go** | Go 官方模块代理 | `go get gitee.com/.../go@latest` |
| **Python** | PyPI | `pip install insightoslog` |

### 输出结构

```
dist/{VERSION}/
├── cpp/
│   └── libinsightoslog-dev_{VERSION}_{ARCH}.deb
├── go/
│   ├── logging_sdk.go     # 根模块入口
│   ├── go.mod             # 含 replace 指令
│   ├── impl/              # 核心实现子模块
│   └── wrapper/           # 面向对象封装子模块
└── python/
    └── insightoslog-{VERSION}-py3-none-any.whl
```

---

## 许可证

MIT License


