Metadata-Version: 2.1
Name: insightoslog
Version: 1.0.13
Summary: InsightOS Log SDK - Unified log collection SDK
Home-page: https://git.insightos.cn/hzh/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 统一日志接口

[![版本](https://img.shields.io/badge/version-1.0.13-blue.svg)](https://github.com/HongZH-XMU/InsightOSLogSDK)
[![许可证](https://img.shields.io/badge/license-MIT-green.svg)](LICENSE)
[![C++](https://img.shields.io/badge/C++-17-orange.svg)](cpp/)
[![Go](https://img.shields.io/badge/Go-1.21+-88CCEE.svg)](go/)
[![Python](https://img.shields.io/badge/Python-3.8+-FFD700.svg)](python/)

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

---

## 架构概览

```
┌─────────────────────────────────────────────────────────────────────────────────────────────┐
│                              InsightOS Log SDK 架构                              │
├─────────────────────────────────────────────────────────────────────────────────────┤
│                                                                                  │
│  ┌─────────────────────────────────────────────────────────────────────────┐    │
│  │                            用户代码层                                     │    │
│  │  ┌──────────────┐  ┌──────────────┐  ┌──────────────┐                  │    │
│  │  │   C++ 用户    │  │   Go 用户     │  │  Python 用户  │                  │    │
│  │  │  main.cpp    │  │   main.go    │  │   main.py   │                  │    │
│  │  └──────┬───────┘  └──────┬───────┘  └──────┬───────┘                  │    │
│  │         │                │                │                            │    │
│  │  ┌──────▼───────┐  ┌──────▼───────┐  ┌──────▼───────┐                  │    │
│  │  │ IOSLOG_INFO  │  │  log.Info()  │  │  log.info() │                  │    │
│  │  │    宏        │  │    函数      │  │    函数     │                  │    │
│  │  └──────┬───────┘  └──────┬───────┘  └──────┬───────┘                  │    │
│  └─────────┼────────────────┼────────────────┼────────────────────────────┘    │
│            │                │                │                                  │
│  ┌─────────▼────────────────▼────────────────▼────────────────────────────┐      │
│  │                            统一 API 层                                  │      │
│  │  ┌──────────────┐  ┌──────────────┐  ┌──────────────┐                │      │
│  │  │  LogBuilder   │  │  LogBuilder   │  │  LogBuilder  │                │      │
│  │  │  链式调用      │  │  链式调用     │  │  链式调用    │                │      │
│  │  └──────┬───────┘  └──────┬───────┘  └──────┬───────┘                │      │
│  └─────────┼────────────────┼────────────────┼────────────────────────────┘      │
│            │                │                │                                  │
│  ┌─────────▼────────────────▼────────────────▼────────────────────────────┐      │
│  │                          核心日志引擎                                  │      │
│  │                                                                           │      │
│  │  ┌─────────────────────────────────────────────────────────────────┐  │      │
│  │  │                      Context 管理器                              │  │      │
│  │  │  • 线程局部存储 (Thread-Local Storage)                          │  │      │
│  │  │  • Trace ID / Span ID 生成与传播                                 │  │      │
│  │  │  • 跨线程/协程 上下文继承                                         │  │      │
│  │  └─────────────────────────────────────────────────────────────────┘  │      │
│  │                                                                           │      │
│  │  ┌─────────────────────────────────────────────────────────────────┐  │      │
│  │  │                      敏感信息过滤器                              │  │      │
│  │  │  • password, token, api_key, secret 等关键字段自动脱敏           │  │      │
│  │  └─────────────────────────────────────────────────────────────────┘  │      │
│  │                                                                           │      │
│  └──────────────────────────────────────┬───────────────────────────────┘      │
│                                         │                                      │
│  ┌──────────────────────────────────────▼───────────────────────────────┐      │
│  │                          输出适配器层                                 │      │
│  │                                                                           │      │
│  │      ┌────────────────────────┐     ┌────────────────────────┐       │      │
│  │      │      stdout 输出       │     │    rotate_file 输出     │       │      │
│  │      │   • ANSI 颜色高亮      │     │   • 文件滚动策略         │       │      │
│  │      │   • 域过滤（可选）      │     │   • 异步队列缓冲        │       │      │
│  │      │   • 紧凑格式输出        │     │   • 定时刷新磁盘        │       │      │
│  │      └────────────────────────┘     └────────────────────────┘       │      │
│  │                                                                           │      │
│  └───────────────────────────────────────────────────────────────────────────┘    │
│                                                                                  │
│  ┌───────────────────────────────────────────────────────────────────────────┐    │
│  │                           日志输出格式                                    │    │
│  │                                                                           │    │
│  │  stdout:  LEVEL YYYY-MM-DDTHH:MM:SS.sss+08:00 [PID] {"event":{"msg":"..."}}  │    │
│  │                                                                           │    │
│  │  file:                                                                    │    │
│  │  {                                                                         │    │
│  │    "meta": {"level": "INFO", "time": "..."},                               │    │
│  │    "resource": {"type": "...", "name": "...", "instance_id": "...", "pid":..│    │
│  │    "context": {"trace_id": "...", "span_id": "...", "parent_span_id": "..."}│    │
│  │    "event": {"msg": "...", "request": {...}},                              │    │
│  │    "data": {"param": {...}, "result": {...}},                             │    │
│  │    "error": {"type": "...", "message": "..."},                            │    │
│  │    "caller": {"file": "...", "line": 42, "function": "..."}               │    │
│  │  }                                                                         │    │
│  └───────────────────────────────────────────────────────────────────────────┘      │
│                                                                                  │
└──────────────────────────────────────────────────────────────────────────────────┘
```

---

## 目录

- [快速开始](#快速开始)
  - [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

#### 安装

**下载 deb 包安装（推荐）**

```bash
# 安装系统依赖
sudo apt install nlohmann-json3-dev libfmt-dev

# 下载并安装 deb 包（amd64）
curl -LO 'https://git.insightos.cn:40080/api/v4/projects/255/uploads/060eadcd69a6f4f1269b501731839819/libinsightoslog-dev_1.0.13_amd64.deb' -H 'PRIVATE-TOKEN: ****'
sudo dpkg -i libinsightoslog-dev_1.0.13_amd64.deb
sudo apt install -f
```

> arm64 架构：将 `amd64` 改为 `arm64` 即可。


---

### 2. Go SDK

#### 安装

```bash
git config --global url."ssh://git@git.insightos.cn:40080/".insteadOf "git.insightos.cn/"
git config --global url."https://git.insightos.cn:40080/".insteadOf "https://git.insightos.cn/"
go get git.insightos.cn/hzh/InsightOSLogSDK/go@v1.0.13
```

#### 编译运行

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

---

### 3. Python SDK

#### 安装

```bash
pip install insightoslog
```

#### 运行

```bash
python main.py
```

---

## 示例代码

### C++ 示例

用户代码只需包含一个头文件，支持三种调用风格和三种输出模式：

**输出模式配置**

```cpp
config.output = "stdout";    // 仅终端输出
config.output = "rotate_file";  // 仅文件输出
config.output = "dual";      // 同时输出到终端和文件（推荐开发模式）
```

```cpp
#include <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）
    auto params = nlohmann::json{{"user_id", 12345}};
    auto result = nlohmann::json{{"status", "ok"}};
    Logger::GetCurrentContext().log().info("处理请求")
        .on_request({{"method", "POST"}, {"path", "/api/users"}})
        .with_data(params, result)
        .latency(50)
        .send();

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

    // 方式四：RAII 上下文管理器（自动恢复上下文）
    {
        auto guard = WithContext("custom-trace-id", "custom-span-id");
        IOSLOG_INFO("在临时上下文中记录的日志");
    } // 离开作用域，自动恢复旧上下文

    // 方式五：闭包风格
    WithContext("closure-trace-id", "closure-span-id", []() {
        IOSLOG_INFO("闭包风格日志");
    }); // 自动恢复

    // 方式六：从已有 Context 创建上下文管理器
    auto existingCtx = Logger::GetCurrentContext();
    auto guard2 = WithContextFromCtx(existingCtx);
    IOSLOG_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 "git.insightos.cn/hzh/InsightOSLogSDK/go"
)

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

    // 开启链路
    log.StartNewTrace()

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

    // 方式二：Logger2/Trace2 类封装（面向对象风格）
    log.Logger2.Init(log.LoggerInitParam{ServiceName: "MyService"})
    log.Logger2.Info("Logger2 日志")
    log.Trace2.StartNewTrace()

    // 方式三：ContextLog 链式日志
    ctx := log.GetCurrentContext()
    log.ContextLog(ctx).Info("处理请求").
        WithParams(map[string]interface{}{"user_id": 12345}).
        WithResult(map[string]interface{}{"status": "ok"}).
        Latency(50).
        Send()

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

    // 方式五：RAII 上下文管理器
    // defer 手动释放
    guard := log.WithContext("custom-trace-id", "custom-span-id")
    defer guard.Close()
    log.Info("在临时上下文中记录的日志")
    // 函数结束时 defer 自动恢复

    // 方式六：闭包风格（自动恢复上下文）
    log.WithContextFunc("closure-trace-id", "closure-span-id", func() {
        log.Info("闭包风格日志")
    })

    // 方式七：从已有 Context 创建
    existingCtx := log.Context{TraceID: "existing-trace", SpanID: "existing-span"}
    guard2 := log.WithContextFromCtx(existingCtx)
    defer guard2.Release()
    log.Info("从已有上下文创建的日志")

    // 方式八：带错误对象的日志
    ctx.Error("请求失败").
        WithParams(map[string]interface{}{"endpoint": "/api/users"}).
        WithError(log.LogError{
            Type:       "NullPointerException",
            Message:    "user repository is nil",
            Stacktrace: "at UserService.create(UserService.java:42)",
        }).
        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"))

# 方式二：Logger2/Trace2 类封装（面向对象风格）
log.Logger2.init({"service_name": "MyService"})
log.Logger2.info("Logger2 日志")
log.Trace2.start_new_trace()

# 方式三：建造者模式
ctx = log.current_context()
ctx.info("处理请求") \
    .with_params({"user_id": 12345}) \
    .with_result({"status": "ok"}) \
    .latency(50) \
    .send()

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

# 方式五：with_context 上下文管理器（RAII 风格）
guard = log.with_context("custom-trace-id", "custom-span-id")
log.info("在临时上下文中记录的日志")
del guard  # 显式释放

# 方式六：带错误对象的日志
ctx.error("请求失败") \
    .with_params({"endpoint": "/api/users"}) \
    .with_error(log.LogError("NullPointerException", "user repository is nil")) \
    .send()

# 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 风格一致 |
| **文件滚动** | 按大小自动滚动，支持配置最大文件和单文件大小 |
| **上下文管理器** | C++/Go/Python 均支持 RAII 风格的 `with` 语句，自动恢复旧上下文 |
| **全局资源** | 支持设置全局 Resource 信息，所有日志自动附加 |
| **配置文件** | 支持 YAML 配置文件加载，便于部署管理 |
| **ContextLog 链式日志** | Go/Python 支持 `ctx.Info().WithParams().Send()` 链式调用 |
| **Logger/Trace 类封装** | Go/Python 提供面向对象的 Logger2/Trace2 全局实例 |
| **错误对象日志** | 支持带错误类型、消息、堆栈的完整错误日志 |
| **嵌套 WithContext** | 支持多层嵌套的上下文管理器，自动按层级恢复 |

---

## 日志结构

终端输出格式（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 / dual（同时输出终端和文件）

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()` |
| `is_initialized()` | `IsInitialized()` | `is_initialized()` |
| `global_resource()` | `GlobalResource()` | `global_resource()` |
| `set_global_resource(resource)` | `SetGlobalResource(resource)` | `set_global_resource(resource)` |
| `refresh_pid()` | `RefreshPID()` | `refresh_pid()` |
| `make_context(...)` | `MakeContext(...)` | `make_context(...)` |

### Logger/Trace 类封装

| 功能 | Go | Python |
|------|-----|--------|
| 全局 Logger 实例 | `log.Logger2` | `log.Logger2` |
| 全局 Trace 实例 | `log.Trace2` | `log.Trace2` |
| 初始化 | `Logger2.Init(param)` | `Logger2.init(param)` |
| 记录日志 | `Logger2.Info(msg)` | `Logger2.info(msg)` |
| 开始链路 | `Trace2.StartNewTrace()` | `Trace2.start_new_trace()` |
| 注入上下文 | `Trace2.Inject(tid, sid, psid)` | `Trace2.inject(tid, sid, psid)` |
| 获取 Headers | `Trace2.GetPropagationHeaders()` | `Trace2.get_propagation_headers()` |
| 清除上下文 | `Trace2.ClearContext()` | `Trace2.clear_context()` |

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

| 级别 | 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()` |

### 上下文管理器（RAII）

| 功能 | C++ | Go | Python |
|------|------|-----|--------|
| 创建上下文管理器 | `WithContext(trace_id, span_id)` | `WithContext(traceID, spanID)` | `with_context(traceID, spanID)` |
| 创建完整上下文 | `WithContext(trace_id, span_id, parent_span_id)` | `WithContextFull(traceID, spanID, parentSpanID)` | `with_context(traceID, spanID, parentSpanID)` |
| 从已有 Context 创建 | `WithContextFromCtx(ctx)` | `WithContextFromCtx(ctx)` | `with_context_from_ctx(ctx)` |
| 闭包风格 | `WithContext(tid, sid, [](...) {})` | `WithContextFunc(tid, sid, func() {})` | `with_context(tid, sid, func)` |
| 释放/恢复上下文 | `guard.Release()` 或析构 | `guard.Close()` / `guard.Release()` | 自动 (`with` 语句) |
| 获取保存的上下文 | `guard.GetContext()` | - | - |

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

| 功能 | 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` |
| `LogError` | `LogError` | `LogError` |
| `ContextGuard` | `ContextWithLog` | `ContextWithLog` |
| `Header::TRACE_ID` | `Header.TRACE_ID` | `HEADER_TRACE_ID` |

### 错误日志

```go
// Go - 带错误对象的日志
ctx.Error("请求失败").
    WithParams(map[string]interface{}{"endpoint": "/api/users"}).
    WithError(LogError{
        Type:       "NullPointerException",
        Message:    "user repository is nil",
        Stacktrace: "at UserService.create(UserService.java:42)",
    }).
    Send()
```

```python
# Python - 带错误对象的日志
ctx.error("请求失败") \
    .with_params({"endpoint": "/api/users"}) \
    .with_error(LogError("NullPointerException", "user repository is nil")) \
    .send()
```

```cpp
// C++ - 带错误对象的日志
ctx.log().error("请求失败")
    .with_params({{"endpoint", "/api/users"}})
    .with_error({{"type", "NullPointerException"}, {"message", "user repository is nil"}})
    .send();
```

---

## 输出模式

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

> `dual` 模式同时支持终端实时查看和文件持久化，文件日志文件名格式：`insightos-YYYY-MM-DD-HHMMSS.log`

---

## 文件滚动策略

| 参数 | 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 | 安装 deb 包时自动拉取 |
| **Go** | google/uuid, uber-go/zap | go get 时自动拉取 |
| **Python** | pyyaml（可选） | 仅在使用配置文件加载时需要 |

> Python 可通过 `pip install insightoslog[yaml]` 安装带 YAML 支持的版本

---

## 测试覆盖

### 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` 配置测试 |
| 21 | ContextGuard | RAII 上下文管理器基础功能 |
| 22 | 嵌套 WithContext | 嵌套作用域测试 |
| 23 | Trace WithContext | Trace 类的 WithContext 支持 |
| 24 | dual 模式基础 | 同时输出到终端和文件测试 |
| 25 | dual 模式轮转 | dual 模式文件轮转测试 |
| 26 | dual 模式多线程 | dual 模式多线程并发测试 |

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

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

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

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

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

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

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

---

## 打包发布

使用 `build_package.sh` 一键构建并打包。

### 用法

```bash
# 指定版本构建打包
./build_package.sh 1.0.13
```

### 发布方式

| 语言 | 平台 | 安装命令 |
|------|------|---------|
| **C++** | GitLab 直接下载 | 下载 deb 包后 `dpkg -i` 安装 |
| **Go** | Go 官方模块代理 | `go get gitee.com/.../go@latest` |
| **Python** | PyPI | `pip install insightoslog` |

### 输出结构

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

### C++ 安装

```bash
# 安装系统依赖
sudo apt install nlohmann-json3-dev libfmt-dev

# 下载并安装 deb 包（amd64）
curl -LO https://git.insightos.cn:40080/hzh/InsightOSLogSDK/-/raw/main/dist/{VERSION}/releases/libinsightoslog-dev_{VERSION}_amd64.deb
sudo dpkg -i libinsightoslog-dev_{VERSION}_amd64.deb
sudo apt install -f
```


## 贡献指南

欢迎贡献代码！请遵循以下步骤：

### 开发环境

**C++**
- GCC 9+ 或 Clang 12+
- CMake 3.15+ 或 XMake
- C++17 标准

**Go**
- Go 1.21+

**Python**
- Python 3.8+

### 分支管理

```
main          # 稳定版本
develop       # 开发分支
feature/*     # 功能分支
bugfix/*      # 修复分支
```

### 提交流程

1. **Fork** 本仓库
2. 创建功能分支：`git checkout -b feature/your-feature`
3. 提交更改：`git commit -m 'Add some feature'`
4. 推送分支：`git push origin feature/your-feature`
5. 创建 **Pull Request**

### 代码规范

- C++：遵循 Google C++ Style Guide
- Go：遵循 Go Code Review Comments
- Python：遵循 PEP 8

### 测试要求

- 所有新增功能必须附带测试用例
- 所有测试通过后才能合并
- 保持测试覆盖率不下降

```bash
# 运行所有测试
cd test/cpp && xmake && xmake run test
cd test/go && go test -v
cd test/python && python3 test_main.py
```

---

## 许可证

MIT License

Copyright (c) 2026 InsightOS Team

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.


