Documentation
## OpenTelemetry 


- OpenTelemetry是 CNCF 的一个可观测性项目,旨在提供可观测性领域的标准化方案,解决观测数据的数据模型、采集、处理、导出等的标准化问题,提供与三方 vendor 无关的服务。
- OpenTelemetry 是什么?
    - OpenTelemetry 是一组标准和工具的集合,旨在管理观测类数据,如 trace、metrics、logs 等 (未来可能有新的观测类数据类型出现)。
    - OpenTelemetry 提供与 vendor 无关的实现,根据用户的需要将观测类数据导出到不同的后端,如开源的 Prometheus、Jaeger 或云厂商的服务中。
- OpenTelemetry 不是什么
    - 即 OpenTelemetry 不提供与可观测性相关的后端服务,这类后端服务通常提供的是存储、查询、可视化等服务。
    - 通过下述抽象图可以简单理解 OpenTelemetry 的工作范围:
    - ![png]https://ucc.alicdn.com/pic/developer-ecology/2541b8c5a42e4bffb2fea28926f70715.png


### trace


- opentelemetry中的trace由多个span定义,可以将trace视为span的有向无环图, 其中span间的边定义为父/子关系。
```


Causal relationships between Spans in a single Trace

        [Span A]  ←←←(the root span)
            |
     +------+------+
     |             |
 [Span B]      [Span C] ←←←(Span C is a `child` of Span A)
     |             |
 [Span D]      +---+-------+
               |           |
           [Span E]    [Span F]

```

- 更直观的查看方式,通过时间轴查看trace

```

Temporal relationships between Spans in a single Trace

––|–––––––|–––––––|–––––––|–––––––|–––––––|–––––––|–––––––|–> time

 [Span A···················································]
   [Span B··········································]
      [Span D······································]
    [Span C····················································]
         [Span E·······]        [Span F··]

```
- 一个Span代表一个工作或操作单元包含如下字段
    - Name
    - Parent span ID (empty for root spans)
    - Start and End Timestamps
    - Span Context
    - Attributes
    - Span Events
    - Span Links
    - Span Status
- SpanContext 表示标识跟踪中的 Span 的所有信息
    - TraceId 跟踪ID,表示一个跟踪链,需要全局唯一
    - SpanId 跨度标识,需要在跟踪链中唯一
    - TraceFlags 跟踪标志,用于外部觉得是否需要应用跟踪
    - [Tracestate]https://w3c.github.io/trace-context/#tracestate-field 跟踪状态,分布式跟踪是一组事件,跨应用程序的各个组件进行合并
- Span Links
    - span可以链接到零个或多个其他因果相关的span

### Baggage 跨多端采集


- 实现标准 [w3c trace-context]https://www.w3.org/TR/trace-context/
    + traceparent: 00-0af7651916cd43dd8448eb211c80319c-b7ad6b7169203331-01
        - version: 2hex 版本
        - trace-id: 32hex  应该跟踪ID,全局唯一
        - parent-id: 16hex  父spanid
        - trace-flags: 2hex   抽样标志 00表示需要记录,01表示采样
    + tracestate(可选)
        - 跨不同的分布式跟踪系统提供额外的供应商特定的跟踪标识信息,它还传达有关请求在多个分布式跟踪图中的位置的信息
        - 格式:标头名称保持小写。标头名称是一个没有任何分隔符的单词,例如 vendorname1=opaqueValue1,vendorname2=opaqueValue2

### rust 采集演示


``` RUST
fn work() {
    let root = tracing::info_span!("child work");
    let _enter = root.enter();
}

async fn work_async() {
    let root = tracing::info_span!("child work async");
    let _enter = root.enter();
}

// 自动创建span方法
#[instrument]

#[inline]

async fn expensive_work() {
    tracing::span!(tracing::Level::INFO, "expensive_step_1")
        .in_scope(|| thread::sleep(Duration::from_millis(25)));
    tracing::span!(tracing::Level::INFO, "expensive_step_2")
        .in_scope(|| thread::sleep(Duration::from_millis(25)));
}

#[tokio::test(flavor = "multi_thread")]

async fn test() -> Result<(), Box<dyn Error + Send + Sync + 'static>> {
    let root = tracing::info_span!("app_start");
    let _enter = root.enter();
    // 同步调用
    work();
    // 异步调用
    work_async()
        .instrument(tracing::info_span!("child work async root"))
        .await;
    // 自动创建span方法
    expensive_work().await;
}
    
```
![](http://ser.yinengyun.com:10082/tech/img/uploads/b7890ae31d173aace3a870ea11dd9cad/20221107175920.png)
- [instrument官方说明文档]https://tracing-rs.netlify.app/tracing/attr.instrument.html

### ts 采集演示


```
import { getTrace } from "pi_common/opentelemetry/trace_lib";

let tracer = getTrace();

// Baggage导出
// {"traceparent": "00-277656cdf4562c5892da9925ce98c697-0fa197db81558780-01", "tracestate": ""}
// 还原父span
const parentSpan = tracer.extract(
    "http_headers", {
    traceparent
});
const span = tracer.startSpan('listener_pid', {
    childOf: parentSpan,
});

// 添加属性
span.setTag('alpha', '200');
span.setTag('beta', '50');
// 添加事件
span.log({
    state: 'waiting'
});


span.finish();

```

#### 阿里云demo演示