# Do you support APM link tracking for Websocket?

**URL:** <https://discuss.elastic.co/t/do-you-support-apm-link-tracking-for-websocket/212087>\
**Category:** APM\
**Tags:** go\
**Created:** [December 17, 2019, 3:41am UTC](https://discuss.elastic.co/t/do-you-support-apm-link-tracking-for-websocket/212087 "2019-12-17T03:41:00Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![EDDYCJY](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/eddycjy/32/54324_2.png) [@EDDYCJY](https://discuss.elastic.co/u/EDDYCJY)\
**Post date:** [December 17, 2019, 3:41am UTC](https://discuss.elastic.co/t/do-you-support-apm-link-tracking-for-websocket/212087/1 "2019-12-17T03:41:01Z")

</div>

**Kibana version** :  
v7.4.2

**Elasticsearch version** :  
v7.4.2

**APM Server version** :  
v7.4.2

**APM Agent language and version** :  
apm-agent-go v1.5.0

**Question：**  
I am using net/http and [github.com/gorilla/websocket](http://github.com/gorilla/websocket) for websocket development, but I find that as long as I upgrade websocket, I cannot collect data and link information of the API interface on APM.

Why is that, thank you

---

<div class="post-metadata">

**Author:** ![EDDYCJY](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/eddycjy/32/54324_2.png) [@EDDYCJY](https://discuss.elastic.co/u/EDDYCJY)\
**Post date:** [December 17, 2019, 3:42am UTC](https://discuss.elastic.co/t/do-you-support-apm-link-tracking-for-websocket/212087/2 "2019-12-17T03:42:43Z")

</div>

@axw 😀Can you help me, thank you.

---

<div class="post-metadata">

**Author:** ![axw](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/axw/32/28197_2.png) [@axw](https://discuss.elastic.co/u/axw)\
**Post date:** [December 17, 2019, 5:17am UTC](https://discuss.elastic.co/t/do-you-support-apm-link-tracking-for-websocket/212087/3 "2019-12-17T05:17:42Z")

</div>

Hi @EDDYCJY!

The Go agent does not support WebSockets, so you will have to add some custom code.

How are you using WebSockets? What are you expecting the agent to do?

---

<div class="post-metadata">

**Author:** ![EDDYCJY](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/eddycjy/32/54324_2.png) [@EDDYCJY](https://discuss.elastic.co/u/EDDYCJY)\
**Post date:** [December 17, 2019, 6:53am UTC](https://discuss.elastic.co/t/do-you-support-apm-link-tracking-for-websocket/212087/4 "2019-12-17T06:53:47Z")

</div>

@axw This demo is probably consistent with the address: [https://github.com/gorilla/websocket/blob/master/examples/echo/server.go#L22-L42](https://github.com/gorilla/websocket/blob/master/examples/echo/server.go#L22-L42).

I hope to see at least every link invocation in APM.

---

<div class="post-metadata">

**Author:** ![axw](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/axw/32/28197_2.png) [@axw](https://discuss.elastic.co/u/axw)\
**Post date:** [December 17, 2019, 7:53am UTC](https://discuss.elastic.co/t/do-you-support-apm-link-tracking-for-websocket/212087/5 "2019-12-17T07:53:50Z")

</div>

So you want to trace from ReadRequest to WriteMessage? e.g. you might have a connection session that goes like this:

1. Client connects
2. Client sends message, waits for response  
2.1. Server receives message  
2.2. Server does some work...  
2.3. Server sends response
3. Repeat step 2
4. Client disconnects

If that's the case then you could trace it using `apm.StartTransaction`, like this:

```auto
func echo(w http.ResponseWriter, r *http.Request) {
    c, err := upgrader.Upgrade(w, r, nil)
    if err != nil {
        return
    }
    defer c.Close()

    for {
        if err := handleMessage(c); err != nil {
            break
        }
    }
}

func handleMessage(c *websocket.Conn) error {
    mt, message, err := c.ReadMessage()
    if err != nil {
        break
    }
    tx := apm.DefaultTracer.StartTransaction("echo", "request")
    defer tx.End()
    // Do some work...
    return c.WriteMessage(mt, message)
}

```

If you want _distributed_ tracing, originating from the WebSocket client, that's more difficult. You can't rely on the HTTP headers because those are for the original HTTP request, and not related to each individual message sent to the WebSocket. Instead you would have to add the trace context to the messages you send over the WebSocket.

---

<div class="post-metadata">

**Author:** ![EDDYCJY](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/eddycjy/32/54324_2.png) [@EDDYCJY](https://discuss.elastic.co/u/EDDYCJY)\
**Post date:** [December 17, 2019, 9:16am UTC](https://discuss.elastic.co/t/do-you-support-apm-link-tracking-for-websocket/212087/6 "2019-12-17T09:16:20Z")

</div>

@axw I also thought about this solution, and it can be solved, but the problem is that I can't find a place where apm.DefaultTracer can set the context. In this way, how can I ensure that it can be connected to other tracing (HTTP, MySQL ...) in the request?

--

I might make other HTTP, SQL calls in the handleMessage method.

---

<div class="post-metadata">

**Author:** ![axw](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/axw/32/28197_2.png) [@axw](https://discuss.elastic.co/u/axw)\
**Post date:** [December 17, 2019, 9:52am UTC](https://discuss.elastic.co/t/do-you-support-apm-link-tracking-for-websocket/212087/7 "2019-12-17T09:52:50Z")

</div>

You will need to create a new `context` object when you start a transaction (receive a message), and add the transaction to it using `apm.ContextWithTransaction`. Like this:

```auto
func handleMessage(c *websocket.Conn) error {
    mt, message, err := c.ReadMessage()
    if err != nil {
        break
    }
    tx := apm.DefaultTracer.StartTransaction("echo", "request")
    defer tx.End()
    // Create a new context for the transaction
    ctx := apm.ContextWithTransaction(context.Background(), tx)
    // Do some work...
    rows, err := db.QueryContext(ctx, "SELECT ...")
    // Do some more work...
    return c.WriteMessage(mt, message)
}

```

---

<div class="post-metadata">

**Author:** ![EDDYCJY](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/eddycjy/32/54324_2.png) [@EDDYCJY](https://discuss.elastic.co/u/EDDYCJY)\
**Post date:** [December 17, 2019, 10:08am UTC](https://discuss.elastic.co/t/do-you-support-apm-link-tracking-for-websocket/212087/8 "2019-12-17T10:08:55Z")

</div>

Thanks @axw for the reply, I think I need to take a closer look at godoc and redesign my program ...

I had been looking at the documentation [https://www.elastic.co/guide/en/apm/agent/go/current/instrumenting-source.html](https://www.elastic.co/guide/en/apm/agent/go/current/instrumenting-source.html) before, but I found that he didn't seem to be complete enough that I understood it wrong.

---

<div class="post-metadata">

**Author:** ![system](https://us1.discourse-cdn.com/elastic/original/3X/1/a/1ac57faf039f6b580b3f104ef42a2a89e41014de.png) [@system](https://discuss.elastic.co/u/system)\
**Post date:** [January 7, 2020, 6:08am UTC](https://discuss.elastic.co/t/do-you-support-apm-link-tracking-for-websocket/212087/9 "2020-01-07T06:08:58Z")

</div>

This topic was automatically closed 20 days after the last reply. New replies are no longer allowed.
