Ecostack commented on code in PR #650:
URL: 
https://github.com/apache/skywalking-website/pull/650#discussion_r1377194704


##########
content/blog/2023-10-18-skywalking-toolkit-trace/index.md:
##########
@@ -0,0 +1,285 @@
+---
+title: "Detailed explanation of SkyWalking Go Toolkit Trace"
+date: 2023-10-18
+author: "Alipebt"
+description: "This article shows the introduction and usage of toolkit trace 
provided by Skywalking Go to users."
+
+---
+
+## Background
+
+SkyWalking Go is an open-source, non-intrusive Golang agent used for 
monitoring, tracing, and data collection within distributed systems. It enables 
users to observe the flow and latency of requests within the system, collect 
performance data from various system components for performance monitoring, and 
troubleshoot issues by tracing the complete path of requests.
+
+In version v0.3.0, Skywalking Go introduced the toolkit trace tool. Trace APIs 
allow users to include critical operations, functions, or services in the 
tracing scope in situations where plugins do not support them. This inclusion 
enables tracking and monitoring of these operations and can be used for fault 
analysis, diagnosis, and performance monitoring.
+
+Before diving into this, you can learn how to use the Skywalking Go agent by 
referring to the [SkyWalking Go Agent Quick Start 
Guide](https://skywalking.apache.org/zh/2023-06-01-quick-start-with-skywalking-go-agent/).
+
+The following sections will explain how to use these interfaces in specific 
scenarios.
+
+## Introducing the Trace Toolkit
+
+Execute the following command in the project's root directory:
+
+```shell
+go get github.com/apache/skywalking-go/toolkit
+```
+
+To use the toolkit trace interface, you need to import the package into your 
project:
+
+```go
+"github.com/apache/skywalking-go/toolkit/trace"
+```
+
+## Manual Tracing
+
+A Span is the fundamental unit of an operation in Tracing. It represents an 
operation within a specific timeframe, such as a request, a function call, or a 
specific action. It records essential information about a particular operation, 
including start and end times, the operation's name, tags (key-value pairs), 
and relationships between operations. Multiple Spans can form a hierarchical 
structure.
+
+In situations where Skywalking-go doesn't support a particular framework, 
users can manually create Spans to obtain tracing information.
+
+(Here, I have removed the supported frameworks for the sake of the example. 
These are only examples. You should reference this when using the APIs in 
private and/or unsupported frameworks)
+
+For example, when you need to trace an HTTP response, you can create a span 
using trace.CreateEntrySpan() within the method handling the request, and end 
the span using trace.StopSpan() after processing.
+When sending an HTTP request, use trace.CreateExitSpan() to create a span, and 
end the span after the request returns.
+
+Here are two HTTP services named `consumer` and `provider`. When a user 
accesses the `consumer` service, it receives the user's request internally and 
then accesses the provider to obtain resources.
+
+```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) {
+       // Create an HTTP request
+       req, err := http.NewRequest("GET", "http://localhost:9998/provider";, 
http.NoBody)
+       // Create an ExitSpan before sending the HTTP request.
+       trace.CreateExitSpan("GET:/provider", "localhost:9999",
+               func(headerKey, headerValue string) error {
+                       // Injector adds specific header information to the 
request.
+                       req.Header.Add(headerKey, headerValue)
+                       return nil
+               })
+       // Finish the ExitSpan and ensure it executes when the function returns 
using defer.
+       defer trace.StopSpan()
+
+       // Send the request.
+       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) {
+       // Create an EntrySpan to trace the execution of the consumerHandler 
method.
+       trace.CreateEntrySpan(r.Method+"/consumer", func(headerKey string) 
(string, error) {
+               // Extractor retrieves the header information added to the 
request.
+               return r.Header.Get(headerKey), nil
+       })
+       // Finish the EntrySpan.
+       defer trace.StopSpan()
+
+       // Prepare to send an HTTP request.
+       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) {
+       //Create an EntrySpan to trace the execution of the providerHandler 
method.
+       trace.CreateEntrySpan("GET:/provider", func(headerKey string) (string, 
error) {
+               return r.Header.Get(headerKey), nil
+       })
+       // Finish the EntrySpan.
+       defer trace.StopSpan()
+
+       _, _ = w.Write([]byte("success from provider"))
+}
+
+func main() {
+       http.HandleFunc("/provider", providerHandler)
+
+       _ = http.ListenAndServe(":9998", nil)
+}
+
+```
+
+
+
+Then, in the terminal, execute:
+
+```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
+```
+
+At this point, the UI will display the span information you created.
+
+![Trace List](./trace.png)
+
+If you need to trace methods that are executed only locally, you can use 
trace.CreateLocalSpan(). If you don't need to monitor information or states 
from the other end, you can change ExitSpan and EntrySpan to LocalSpan.
+
+The usage examples provided are for illustration purposes, and users can 
decide the tracing granularity and where in the program they need tracing.
+
+Please note that if a program ends too quickly, it may cause tracing data to 
be unable to be asynchronously sent to the SkyWalking backend.

Review Comment:
   I am not sure if it is possible but can a manual sync be forced for short 
running programs?



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: notifications-unsubscr...@skywalking.apache.org

For queries about this service, please contact Infrastructure at:
us...@infra.apache.org

Reply via email to