SkyAPM / go2sky

Distributed tracing and monitor SDK in Go for Apache SkyWalking APM
https://skywalking.apache.org/
Apache License 2.0
448 stars 122 forks source link

To create a exit span with one statement, not two statement #139

Closed xing393939 closed 2 years ago

xing393939 commented 2 years ago

Describe the solution you'd like I'd like to create a exit span with one statement like:

spanStartTime = time.Now()
// do same stuff
CreateExitSpan(spanStartTime)

not two statement like:

span = CreateExitSpan()
// do same stuff
span.End()

Because when your program panic after CreateExitSpan(), you never have change to call span.End(), then this trace can not be sent. this is a demo to show this.

package main

import (
    "context"
    "github.com/SkyAPM/go2sky"
    "github.com/SkyAPM/go2sky/reporter"
    "log"
    "time"
)

func doSameStuff(ctx context.Context, tracer *go2sky.Tracer) {
    subSpan, _ := tracer.CreateExitSpan(ctx, "/database/query", "db", func(k string, v string) error {
        return nil
    })
    subSpan.SetComponent(5200)

    // something wrong and panic
    var a interface{}
    println(a.(int))

    subSpan.End()
}

func run(ctx context.Context, tracer *go2sky.Tracer) {
    // create root span
    rootSpan, ctx, _ := tracer.CreateEntrySpan(ctx, "/test", func(k string) (string, error) {
        return "", nil
    })
    rootSpan.SetComponent(5200)
    rootSpan.Tag(go2sky.TagHTTPMethod, "GET")
    defer func() {
        if err := recover(); err != nil {
            log.Println(err)
        }
        rootSpan.End()
    }()

    // do same stuff
    doSameStuff(ctx, tracer)
}

func main() {
    r, err := reporter.NewLogReporter()
    tracer, err := go2sky.NewTracer("op", go2sky.WithReporter(r), go2sky.WithInstance("RTS_Test_1"))
    if err != nil {
        log.Fatal(err)
        return
    }
    run(context.Background(), tracer)
    time.Sleep(time.Second)
}
wu-sheng commented 2 years ago

Please update the issue in English, as this SDK has global users.

Also, I am not sure what you are proposing for clearing tracing context. Could you submit a pull request or demo codes to show how to do this? Also, in my mind, if you can clear the context, you could stop this span in the same place.

kagaya85 commented 2 years ago

Hi @xing393939, I think you can use recover() to catch the panic and call span.End() to report it in defer function, it may solve your problem

xing393939 commented 2 years ago

Hi @xing393939, I think you can use recover() to catch the panic and call span.End() to report it in defer function, it may solve your problem

If I do so, I need to get the span in the recover logic, the span can not got by the root span directly, so I need to do same extra work to pass the span, I do not think it is a good idea.