### 初始化trace

#### 项目入口添加如下代码(参考pi_demo  src\server\index.ts)
```javaScript
    const initTrace = () => {
    let trace = env_var("TRACING");
    if (trace == 'true' || trace == 'TRUE') {
        const traceConfig = {
            endpoint: "https://gcwl-logs.cn-chengdu.log.aliyuncs.com:10010",
            endpoint_opentelemetry_v1: "https://gcwl-logs.cn-chengdu.log.aliyuncs.com/opentelemetry/v1/traces",
            project: "gcwl-logs",
            instance_id: "pidemo",
            ak_id: "LTAI5t6nowJdSqViaou6WAUo",
            ak_secret: "chY7jOgrt1C0BQuxPN2DhB9kGvz3n4",
            service_version: "v0.1.0",
            service_name: "pi_demo",
            service_namespace: "pi_serv",
            host_name: "localhost",
            level: 3        // 5 verbose, 4 debug, 3 info, 2 warn, 1 error, 0 none
        }
        globalThis.traceConfig = traceConfig;

        // 初始化底层
        init_trace(traceConfig.endpoint,
            traceConfig.project,
            traceConfig.instance_id,
            traceConfig.ak_id,
            traceConfig.ak_secret,
            traceConfig.service_version,
            traceConfig.service_name,
            traceConfig.service_namespace,
            traceConfig.host_name)
    }
}
initTrace();
```

#### 配置环境变量

- 开启trace应用跟踪
- TRACING=true

### rust使用

```rust
use opentelemetry::propagation::TextMapPropagator;
use pi_logger::tracing::{create_baggage, init_sls};
use std::collections::HashMap;
use std::{error::Error, thread, time::Duration};
use tracing::{self, instrument, Instrument};
use tracing_opentelemetry::OpenTelemetrySpanExt;
use tracing_subscriber::prelude::*;

// 导出baggage
{
    let propagator = create_baggage();
    // {"traceparent": "00-277656cdf4562c5892da9925ce98c697-0fa197db81558780-01", "tracestate": ""}
    let mut outgoing_req_carrier = HashMap::new();
    let root = tracing::info_span!("app_start112");
    let _enter = root.enter();
    propagator.inject_context(&root.context(), &mut outgoing_req_carrier);
    println!("traceparent:{:?}", outgoing_req_carrier.get("traceparent"));
}

// 导入父节点
{
    use opentelemetry::{global, Context};
    use opentelemetry::sdk::propagation::TraceContextPropagator;

    let propagator = TraceContextPropagator::new();

        let mut carrier = HashMap::new();
        carrier.insert(
            "traceparent".to_string(),
            "00-0af7651916cd43dd8448eb211c80319c-b7ad6b7169203331-01".to_string(),
        );
    let parent_context = propagator.extract(&carrier);

    let app_root = tracing::info_span!("app_start");
    app_root.set_parent(parent_context);
}
// 设置属性
{
    let root = tracing::info_span!("app_start", aaa=111, bbb=222);
}
// trace中添加日志
{
    tracing::info!("log test");
}

```

### ts/web

```javaScript
import { api, getTrace, getTraceInfo } from 'pi_common/opentelemetry/trace_lib';

{
    let tracer = getTraceInfo();
    // 创建span 并指定父节点
    const span = tracer.startSpan('hello pi_demo', { childOf: parentSpan });
    
    // 导出traceparent
    let headersCarrier = {};
    tracer.inject(span, "http_headers", headersCarrier);
    console.info("traceparent:", JSON.stringify(headersCarrier));

    // 设置属性
    span.setTag('alpha', '200');
    span.setTag('beta', '50');
    // 设置span状态(这个比较特殊，只接受bool)
    span.setTag('error', false);
    // 设置日志
    span.log({
        state: 'waiting'
    });

    // 完成时调用
    span.finish();
}

// 隐式传递span上下文
{
    let tracer = getTraceInfo();
    const span = tracer.startSpan('hello pi_demo');
    // 设置span上下文
    api.context.with(api.trace.setSpan(api.context.active(), span), () => {
        test()
        span.finish();
    })

    const test = () => {
        let tracer = getTrace();
        // 获取父span
        const currentSpan = api.trace.getSpan(api.context.active());
        const span = tracer.startSpan('test', { childOf: currentSpan });
        span.finish();
    }
}

```

### 特别说明

- 埋点的时候设置好trace的等级 
    - rust: info_span、debug_span、warn_span等
    - ts: getTraceInfo、getTraceWarn等
    - 以上等级对应日志的等级，也就是环境变量中设置的RUST_LOG=info