# Monitor Elasticsearch HTTP in Golang \[APM\]

**URL:** <https://discuss.elastic.co/t/monitor-elasticsearch-http-in-golang-apm/270716>\
**Category:** APM\
**Tags:** go\
**Created:** [April 20, 2021, 1:45pm UTC](https://discuss.elastic.co/t/monitor-elasticsearch-http-in-golang-apm/270716 "2021-04-20T13:45:32Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![RdrgPorto](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/rdrgporto/32/13278_2.png) [@RdrgPorto](https://discuss.elastic.co/u/RdrgPorto)\
**Post date:** [April 20, 2021, 1:45pm UTC](https://discuss.elastic.co/t/monitor-elasticsearch-http-in-golang-apm/270716/1 "2021-04-20T13:45:32Z")

</div>

**Kibana version** : 7.9.2

**Elasticsearch version** : 7.9.2

**APM Server version** : 7.9.2

**APM Agent language and version** : Golang 1.11.0

**Original install method (e.g. download page, yum, deb, from source, etc.) and version**: Docker image on Kubernetes

**Fresh install or upgraded from other version?** : Fresh install

**Is there anything special in your setup?** : APM Server --\> Kafka --\> Logstash --\> Elasticsearch

Hi, everyone

I have been working with **APM** and **Golang** in order to monitor **HTTP connections to Elasticsearch**.

On the code, I have tried to manage **output requests** by using [HTTP wrapped client](https://www.elastic.co/guide/en/apm/agent/go/current/builtin-modules.html#builtin-modules-apmhttp). Also, sending the **method request** ( **GET** , **POST** , and so on) by using `golang.org/x/net/context/ctxhttp` library. Moreover, I have guaranteed of closing the response properly.

In despite of this configuration and even though the request is being properly processed, **APM server** does not show any information. In order to solve this issue I have had to open a **specific transaction for every call**

Here you are my code:

```auto
transaction := apm.DefaultTracer.StartTransaction("POST "+queryPath, "request")
defer transaction.End()
transaction.Result = "HTTP 2xx"
transaction.Context.SetLabel("type", "elastic POST")
transaction.Context.SetLabel("uri", config.ElasticsearchURL+queryPath)
ctx := apm.ContextWithTransaction(context.Background(), transaction)
apmRequest := request.WithContext(ctx)
response, err = ctxhttp.Do(ctx, HTTPClient, apmRequest)

```

Is it right ? Is there another way to configure it?

Thanks in advance,

Rodrigo

---

<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:** [April 21, 2021, 2:02am UTC](https://discuss.elastic.co/t/monitor-elasticsearch-http-in-golang-apm/270716/2 "2021-04-21T02:02:27Z")

</div>

It's correct that you must first create a transaction for a span to be reported, though you don't necessarily need to create a transaction for every Elasticsearch request.

A [transaction](https://www.elastic.co/guide/en/apm/get-started/current/transactions.html) is something like an incoming HTTP request, or a periodic background task, while a [span](https://www.elastic.co/guide/en/apm/get-started/current/transaction-spans.html) measures an operation within a transaction, such as a database request or external HTTP request.

If you can tell us a little more about how your application works (What initiates the Elasticsearch requests? Is it an HTTP service? Is it a periodic task?), then we may be able to provide some more guidance.

By the way, you should probably use [apmelasticsearch](http://go.elastic.co/apm/module/apmelasticsearch) for instrumenting the outgoing Elasticsearch requests, rather than apmhttp.

---

<div class="post-metadata">

**Author:** ![RdrgPorto](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/rdrgporto/32/13278_2.png) [@RdrgPorto](https://discuss.elastic.co/u/RdrgPorto)\
**Post date:** [April 21, 2021, 3:09pm UTC](https://discuss.elastic.co/t/monitor-elasticsearch-http-in-golang-apm/270716/3 "2021-04-21T15:09:42Z")

</div>

Hi, @axw

My application executes scheduled requests in order to run queries on **Elasticsearch** indices.

I can not use " **module/apmelasticsearch**" because of our implementation is based on " **net/http**". Moreover, I do not use neither " **go-elasticsearch**" nor " **olivere/elastic**". It could be a future improvement but for the moment.

I have also tried to wrap the client like this:

```auto
span, ctx := apm.StartSpan(request.Context(), "elastic-request", "custom")
defer span.End()
var HTTPClient = apmhttp.WrapClient(http.DefaultClient)
response, err = HTTPClient.Do(request.WithContext(ctx))

```

But it does not work (that is, it does not show anything on **APM** ) without creating a **transaction**.

Is there another **easier way** to create this **transaction**?

Thanks in advance,

Rodrigo

---

<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:** [April 22, 2021, 5:57am UTC](https://discuss.elastic.co/t/monitor-elasticsearch-http-in-golang-apm/270716/4 "2021-04-22T05:57:08Z")

</div>

> [@RdrgPorto](#):
>
> I can not use " **module/apmelasticsearch**" because of our implementation is based on " **net/http**". Moreover, I do not use neither " **go-elasticsearch**" nor " **olivere/elastic**". It could be a future improvement but for the moment.

It may still be possible, as apmelasticsearch instruments at the net/http level anyway. Anyway, it was just a side note, maybe it's not practical for you.

> Is there another **easier way** to create this **transaction**?

I can't say whether or not there's an _easier_ way without seeing code, but if you're scheduling requests in a background goroutine, then most likely the right approach would be to start a transaction when the goroutine receives its signal to do its work. Something like:

```go
go func() {
    for range time.Tick(time.Minute) {
      backgroundJob()
    }
}()

func backgroundJob() {
  tx := apm.DefaultTracer.StartTransaction("background job", "scheduled")
  defer tx.End()
  ctx := apm.ContextWithBackground(context.Background(), tx)
  results, err := queryElasticsearch(ctx)
  ...
}

func queryElasticsearch(ctx context.Context) {
  span, ctx := apm.StartSpan(ctx, "elastic-request", "app")
  defer span.End()

  request := ...
  var HTTPClient = apmhttp.WrapClient(http.DefaultClient)
  response, err = HTTPClient.Do(request.WithContext(ctx))
  ...
}

```

The transaction relates to the "scheduled job" (whatever that might be), which happens to involve an Elasticsearch request which will be represented as a span. Presumably your scheduled job does something other than just query Elasticsearch, so you might create additional spans representing those other tasks.

---

<div class="post-metadata">

**Author:** ![RdrgPorto](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/rdrgporto/32/13278_2.png) [@RdrgPorto](https://discuss.elastic.co/u/RdrgPorto)\
**Post date:** [April 22, 2021, 6:55am UTC](https://discuss.elastic.co/t/monitor-elasticsearch-http-in-golang-apm/270716/5 "2021-04-22T06:55:04Z")

</div>

Hi, @axw

Thanks a lot for your support 😃 .

Regards 🖖

---

<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:** [May 13, 2021, 2:56am UTC](https://discuss.elastic.co/t/monitor-elasticsearch-http-in-golang-apm/270716/6 "2021-05-13T02:56:04Z")

</div>

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