This is an automated email from the ASF dual-hosted git repository.

wusheng pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/skywalking-website.git


The following commit(s) were added to refs/heads/master by this push:
     new 6febe89a246 Add blog: Detailed explanation of SkyWalking Go Toolkit 
Trace (zh)  (#651)
6febe89a246 is described below

commit 6febe89a246be323abfeb6a3cd6dead6b9f2f86b
Author: Alipebt <1160756...@qq.com>
AuthorDate: Wed Nov 1 17:15:21 2023 +0800

    Add blog: Detailed explanation of SkyWalking Go Toolkit Trace (zh)  (#651)
---
 .../correlation.png                                | Bin 0 -> 73267 bytes
 .../2023-10-18-skywalking-toolkit-trace/index.md   | 287 +++++++++++++++++++++
 .../2023-10-18-skywalking-toolkit-trace/trace.png  | Bin 0 -> 79274 bytes
 3 files changed, 287 insertions(+)

diff --git a/content/zh/2023-10-18-skywalking-toolkit-trace/correlation.png 
b/content/zh/2023-10-18-skywalking-toolkit-trace/correlation.png
new file mode 100644
index 00000000000..a1b6fe3df1b
Binary files /dev/null and 
b/content/zh/2023-10-18-skywalking-toolkit-trace/correlation.png differ
diff --git a/content/zh/2023-10-18-skywalking-toolkit-trace/index.md 
b/content/zh/2023-10-18-skywalking-toolkit-trace/index.md
new file mode 100644
index 00000000000..1a66531fe27
--- /dev/null
+++ b/content/zh/2023-10-18-skywalking-toolkit-trace/index.md
@@ -0,0 +1,287 @@
+---
+title: "SkyWalking Go Toolkit Trace 详解"
+date: 2023-10-18
+author: "Alipebt"
+description: "本文展示了 Skywalking Go 中 toolkit trace 的介绍和用法"
+
+---
+
+## 背景介绍
+
+SkyWalking 
Go是一个开源的非侵入式Golang代理程序,用于监控、追踪和在分布式系统中进行数据收集。它使用户能够观察系统内请求的流程和延迟,从各个系统组件收集性能数据以进行性能监控,并通过追踪请求的完整路径来解决问题。
+
+在版本v0.3.0中,Skywalking Go引入了 toolkit-trace 工具。Trace APIs 
允许用户在插件不支持的情况下将关键操作、函数或服务添加到追踪范围。从而实现追踪和监控这些操作,并可用于故障分析、诊断和性能监控。
+
+在深入了解之前,您可以参考[SkyWalking Go 
Agent快速开始指南](https://skywalking.apache.org/zh/2023-06-01-quick-start-with-skywalking-go-agent/)来学习如何使用SkyWalking
 Go Agent。
+
+下面将会介绍如何在特定场景中使用这些接口。
+
+## 导入 Trace Toolkit
+
+在项目的根目录中执行以下命令:
+
+```shell
+go get github.com/apache/skywalking-go/toolkit
+```
+
+使用 toolkit trace 接口前,需要将该包导入到您的项目中:
+
+```go
+"github.com/apache/skywalking-go/toolkit/trace"
+```
+
+## 手动追踪
+
+Span 是 Tracing 
中单个操作的基本单元。它代表在特定时间范围内的操作,比如一个请求、一个函数调用或特定动作。Span记录了特定操作的关键信息,包括开始和结束时间、操作名称、标签(键-值对)以及操作之间的关系。多个
 Span 可以形成层次结构。
+
+在遇到 Skywalking Go 不支持的框架的情况下,用户可以手动创建 Span 以获取追踪信息。
+
+(为了作为示例,我删除了已支持的框架。以下仅为示例。请在使用私有或不支持的框架的 API 时参考)
+
+例如,当需要追踪HTTP响应时,可以在处理请求的方法内部使用 `trace.CreateEntrySpan() `来创建一个 span,在处理完成后使用 
`trace.StopSpan()` 来结束这个 span。在发送HTTP请求时,使用 `trace.CreateExitSpan()` 来创建一个 
span,在请求返回后结束这个 span。
+
+这里有两个名为 consumer 和 provider 的HTTP服务。当用户访问 consumer 服务时,它在内部接收用户的请求,然后访问 
provider 以获取资源。
+
+```go
+// consumer.go
+package main
+
+import (
+       "io"
+       "net/http"
+
+       _ "github.com/apache/skywalking-go"
+       "github.com/apache/skywalking-go/toolkit/trace"
+)
+
+func getProvider() (*http.Response, error) {
+       // 新建 HTTP 请求
+       req, err := http.NewRequest("GET", "http://localhost:9998/provider";, 
http.NoBody)
+       // 在发送 HTTP 请求之前创建 ExitSpan
+       trace.CreateExitSpan("GET:/provider", "localhost:9999",
+               func(headerKey, headerValue string) error {
+                       // Injector 向请求中添加特定的 header 信息
+                       req.Header.Add(headerKey, headerValue)
+                       return nil
+               })
+       // 结束 ExitSpan,使用 defer 确保在函数返回时执行
+       defer trace.StopSpan()
+
+       // 发送请求
+       client := &http.Client{}
+       resp, err := client.Do(req)
+       if err != nil {
+               return nil, err
+       }
+       return resp, nil
+}
+
+func consumerHandler(w http.ResponseWriter, r *http.Request) {
+       // 创建 EntrySpan 来追踪 consumerHandler 方法的执行
+       trace.CreateEntrySpan(r.Method+"/consumer", func(headerKey string) 
(string, error) {
+               // Extractor 获取请求中添加的 header 信息
+               return r.Header.Get(headerKey), nil
+       })
+       // 结束 EntrySpan
+       defer trace.StopSpan()
+
+       // 准备发送 HTTP 请求
+       resp, err := getProvider()
+
+       body, err := io.ReadAll(resp.Body)
+       if err != nil {
+               return
+       }
+       _, _ = w.Write(body)
+}
+
+func main() {
+       http.HandleFunc("/consumer", consumerHandler)
+
+       _ = http.ListenAndServe(":9999", nil)
+}
+```
+
+```go
+// provider.go
+package main
+
+import (
+       "net/http"
+
+       _ "github.com/apache/skywalking-go"
+       "github.com/apache/skywalking-go/toolkit/trace"
+)
+
+func providerHandler(w http.ResponseWriter, r *http.Request) {
+       // 创建 EntrySpan 来追踪 providerHandler 方法的执行
+       trace.CreateEntrySpan("GET:/provider", func(headerKey string) (string, 
error) {
+               return r.Header.Get(headerKey), nil
+       })
+       // 结束 EntrySpan
+       defer trace.StopSpan()
+
+       _, _ = w.Write([]byte("success from provider"))
+}
+
+func main() {
+       http.HandleFunc("/provider", providerHandler)
+
+       _ = http.ListenAndServe(":9998", nil)
+}
+
+```
+
+
+
+然后中终端中执行:
+
+```shell
+go build -toolexec="/path/to/go-agent" -a -o consumer ./consumer.go
+./consumer
+```
+
+```shell
+go build -toolexec="/path/to/go-agent" -a -o provider ./provider.go
+./provider
+```
+
+```shell
+curl 127.0.0.1:9999/consumer
+```
+
+此时 UI 中将会显示你所创建的span信息
+
+![Trace List](./trace.png)
+
+如果需要追踪仅在本地执行的方法,可以使用 `trace.CreateLocalSpan()`。如果不需要监控来自另一端的信息或状态,可以将 
`ExitSpan` 和 `EntrySpan` 更改为 `LocalSpan`。
+
+以上方法仅作为示例,用户可以决定追踪的粒度以及程序中需要进行追踪的位置。
+
+注意,如果程序结束得太快,可能会导致 Tracing 数据无法异步发送到 SkyWalking 后端。
+
+## 填充 Span
+
+当需要记录额外信息时,包括创建/更新标签、追加日志和设置当前被追踪 Span 
的新操作名称时,可以使用这些API。这些操作用于增强追踪信息,提供更详细的上下文描述,有助于更好地理解被追踪的事件或操作。
+
+Toolkit trace APIs 提供了一种简便的方式来访问和操作 Trace 数据:
+
+- 设置标签:`SetTag()`
+- 添加日志:`AddLog()`
+- 设置 Span 名称:`SetOperationName()`
+- 获取各种ID:`GetTraceID()`, `GetSegmentID()`, `GetSpanID()`
+
+例如,如果需要在一个 Span 中记录HTTP状态码,就可以在 Span 未结束时调用以下接口:
+
+```go
+trace.CreateExitSpan("GET:/provider", "localhost:9999", func(headerKey, 
headerValue string) error {
+       r.Header.Add(headerKey, headerValue)
+       return nil
+})
+resp, err := http.Get("http://localhost:9999/provider";)
+trace.SetTag("status_code", fmt.Sprintf("%d", resp.StatusCode))
+spanID := trace.GetSpanID()
+trace.StopSpan()
+```
+
+在调用这些方法时,当前线程需要有正在活跃的 span。
+
+## 异步 APIs
+
+异步API 用于跨 goroutines 操作 spans。包括以下情况:
+
+- 包含多个 goroutines 的程序,需要在不同上下文中中操作 Span。
+- 在异步操作时更新或记录 Span 的信息。
+- 延迟结束 Span。
+
+按照以下步骤使用:
+
+- 获取 `CreateSpan` 的返回值 `SpanRef`。
+- 调用 `spanRef.PrepareAsync()` ,准备在另一个 goroutine 中执行操作。
+- 当前 goroutine 工作结束后,调用 `trace.StopSpan()` 结束该 span(仅影响当前 goroutine)。
+- 将 `spanRef` 传递给另一个 goroutine。
+- 完成工作后在任意 goroutine 中调用 `spanRef.AsyncFinish()`。
+
+以下为示例:
+
+```go
+spanRef, err := trace.CreateLocalSpan("LocalSpan")
+if err != nil {
+       return
+}
+spanRef.PrepareAsync()
+go func(){
+       // some work
+       spanRef.AsyncFinish()
+}()
+// some work
+trace.StopSpan()
+```
+
+## Correlation Context
+
+Correlation Context 用于在 Span 间传递参数,父 Span 会把 Correlation Context 递给其所有子 
Spans。它允许在不同应用程序的 spans 之间传输信息。Correlation Context 的默认元素个数为3,其内容长度不能超过128字节。
+
+Correlation Context 通常用于以下等情况:
+
+- `在 Spans 之间传递信息`:它允许关键信息在不同 Span 之间传输,使上游和下游 Spans 能够获取彼此之间的关联和上下文。
+- `传递业务参数`:在业务场景中,涉及在不同 Span 之间传输特定参数或信息,如认证令牌、交易ID等。
+
+用户可以使用 `trace.SetCorrelation(key, value)` 设置 Correlation Context ,并可以使用 `value 
:= trace.GetCorrelation(key)` 在下游 spans 中获取相应的值。
+
+例如在下面的代码中,我们将值存储在 span 的标签中,以便观察结果:
+
+```go
+package main
+
+import (
+       _ "github.com/apache/skywalking-go"
+       "github.com/apache/skywalking-go/toolkit/trace"
+       "net/http"
+)
+
+func providerHandler(w http.ResponseWriter, r *http.Request) {
+       ctxValue := trace.GetCorrelation("key")
+       trace.SetTag("result", ctxValue)
+}
+
+func consumerHandler(w http.ResponseWriter, r *http.Request) {
+       trace.SetCorrelation("key", "value")
+       _, err := http.Get("http://localhost:9999/provider";)
+       if err != nil {
+               return
+       }
+}
+
+func main() {
+       http.HandleFunc("/provider", providerHandler)
+
+       http.HandleFunc("/consumer", consumerHandler)
+
+       _ = http.ListenAndServe(":9999", nil)
+}
+```
+
+然后在终端执行:
+
+```shell
+export SW_AGENT_NAME=server
+go build -toolexec="/path/to/go-agent" -a -o server ./server.go
+./server
+```
+
+```shell
+curl 127.0.0.1:9999/consumer
+```
+
+最后在 `providerHandler()` 的 Span 中找到了 Correlation Context 的信息:
+
+![Correlation Value](./correlation.png)
+
+## 总结
+
+本文讲述了Skywalking Go的 Trace APIs 及其应用。它为用户提供了自定义追踪的功能。
+
+更多关于该接口的介绍见文档:[Tracing 
APIs](https://skywalking.apache.org/docs/skywalking-go/next/en/advanced-features/manual-apis/toolkit-trace/)。
+
+欢迎大家来使用新版本。
\ No newline at end of file
diff --git a/content/zh/2023-10-18-skywalking-toolkit-trace/trace.png 
b/content/zh/2023-10-18-skywalking-toolkit-trace/trace.png
new file mode 100644
index 00000000000..ae8e2744bc6
Binary files /dev/null and 
b/content/zh/2023-10-18-skywalking-toolkit-trace/trace.png differ

Reply via email to