Skip to main content

How to Integrate APM (Application Performance Monitoring) Into Golang Server



To integrate APM (application performance monitoring) into Golang servers, you can use a third-party library such as Elastic APM or DataDog APM. Here are the basic steps you can follow:

  • Choose an APM library: There are many APM libraries available for Golang, so choose one that fits your requirements. Some popular options include Elastic APM, DataDog APM, and Instana.
  • Install the library: Once you have chosen an APM library, you will need to install it in your Golang project. This usually involves importing the library into your code and setting it up to monitor your application.
  • Configure the library: You will need to configure the APM library to monitor the specific parts of your application that you are interested in. This might include setting up tracing for specific HTTP endpoints, monitoring database queries, or tracking the performance of specific functions.
  • Start the APM agent: Once you have installed and configured the APM library, you will need to start the APM agent that will collect and transmit performance data to your APM server. This usually involves starting the agent as a separate process or thread in your application.
  • View performance data: With the APM agent running, you can now view performance data for your Golang application in your APM dashboard. This might include metrics such as request latency, error rates, and database query performance.
Overall, integrating APM into Golang servers is a great way to monitor the performance of your applications and identify potential issues before they become critical. By following these steps, you can quickly and easily set up APM monitoring for your Golang projects.

Adding The APM agent to our server

To add apm-agent-go package, download this package we can simply run:

go get go.elastic.co/apm/v2



Then add to API handler:

import (
 "context"
 "encoding/json"
 "go.elastic.co/apm/module/apmhttp/v2"
 "go.elastic.co/apm/v2"
 "net/http"
 "time"
)


2. wrap your server mux with apmhttp wrapper



http.ListenAndServe(":8080", apmhttp.Wrap(mux))



3. add an APM span for each function -

func baseHandler(w http.ResponseWriter, r *http.Request) {
 ctx := r.Context()
 span, ctx := apm.StartSpan(ctx, "baseHandler", "custom")
 defer span.End()
 // rest of the code
}

func processingRequest(ctx context.Context) {
 span, ctx := apm.StartSpan(ctx, "processingRequest", "custom")
 defer span.End()
 // rest of the code
}

func doSomething(ctx context.Context) {
 span, ctx := apm.StartSpan(ctx, "doSomething", "custom")
 defer span.End()
 // rest of the code
}


func getTodoFromAPI(ctx context.Context) (map[string]interface{}, error) {
 span, ctx := apm.StartSpan(ctx, "getTodoFromAPI", "custom")
 defer span.End()
 // rest of the code
}


Elastic APM agent traces a request transaction using Go’s context, so we are required to pass the original context while starting the span and use the returned context for further spans.



4. Final step is to let APM agent know where is APM server running. We do this by setting 2 environment variables ELASTIC_APM_SERVICE_NAME and ELASTIC_APM_SERVER_URL.

In our main function, add -


const (
 apmServer = "http://localhost:5200"
 apmName = "test-apm-1"
)

func main() {
 os.Setenv("ELASTIC_APM_SERVICE_NAME", apmName)
 os.Setenv("ELASTIC_APM_SERVER_URL", apmServer)
 mux := http.NewServeMux()
 mux.HandleFunc("/", baseHandler)
 http.ListenAndServe(":8083", apmhttp.Wrap(mux))
}

this is the complete source code for a Golang server with APM:

package main

import (
 "context"
 "encoding/json"
 "go.elastic.co/apm/module/apmhttp/v2"
 "go.elastic.co/apm/v2"
 "net/http"
 "os"
 "time"
)


const (
 apmServer = "http://localhost:7200"
 apmName = "test-apm-1"
)


func main() {
 os.Setenv("ELASTIC_APM_SERVICE_NAME", apmName)
 os.Setenv("ELASTIC_APM_SERVER_URL", apmServer)
 mux := http.NewServeMux()
 mux.HandleFunc("/", baseHandler)
 http.ListenAndServe(":8083", apmhttp.Wrap(mux))
}


func baseHandler(w http.ResponseWriter, r *http.Request) {
 ctx := r.Context()
 span, ctx := apm.StartSpan(ctx, "baseHandler", "custom")
 defer span.End()
 processingRequest(ctx)
 todo, err := getTodoFromAPI(ctx)
 if err != nil {
  w.Write([]byte(err.Error()))
  return
 }
 data, _ := json.Marshal(todo)
 w.Write(data)
}



func processingRequest(ctx context.Context) {
 span, ctx := apm.StartSpan(ctx, "processingRequest", "custom")
 defer span.End()
 doSomething(ctx)
 // time sleep simulate some processing time

 time.Sleep(15 * time.Millisecond)
 return
}



func doSomething(ctx context.Context) {
 span, ctx := apm.StartSpan(ctx, "doSomething", "custom")
 defer span.End()
 // time sleep simulate some processing time
 time.Sleep(20 * time.Millisecond)
 return
}



func getTodoFromAPI(ctx context.Context) (map[string]interface{}, error) {
 span, ctx := apm.StartSpan(ctx, "getTodoFromAPI", "custom")
 defer span.End()
 var result map[string]interface{}
 resp, err := http.Get("https://jsonplaceholder.typicode.com/todos/1")
 if err != nil {
  return result, err
 }

 defer resp.Body.Close()
 err = json.NewDecoder(resp.Body).Decode(&result)
 if err != nil {
  return result, err
 }

 return result, err
}

Comments

Popular posts from this blog

Cara Disable Antimalware Service Executable di Windows 10

Disadari atau tidak, Windows 10 (dan juga windows-windows lainnya) hadir dengan banyak sekali aplikasi bloatware (aplikasi yang tidak perlu-perlu amat dimiliki oleh end user). Contohnya, adalah aplikasi yang seharusnya sudah tergantikan fungsinya oleh antivirus, seperti Antimalware Service Executable . Aplikasi ini dicurigai membuat Windows 10 mengalami inefisiensi memori/RAM, memakan resource yang tinggi, dengan Load yang tinggi (tanpa limit terkadang). Nah, berikut adalah cara men-disable nya: Tekan tombol Windows + I untuk membuka apliaksi Windows Setting. Pilih icon menu Update and Security Pilih lagi menu disamping kiri Windows Security Pada jendela baru yang muncul, ada pilihan Virus & Threat protection Klik ini Lalu matikan proses Real-time protection tersebut. Dengan Regedit. Buka dialog regedit, Windows + R dan ketik ‘regedit’ Cari Folder regedit ini HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender Buat sebuah DWORD baru dengan klik kanan

Setup Debian 11 Official Repository In sources.list (/etc/apt/sources.list)

When you install Debian 11 using a DVD, the OS installer sets the DVD as the source for getting packages for your system if you didn't choose to scan for network mirrors. Due to this reason, the system would ask you to insert a DVD if the disc is not present in the DVD drive when you try to install any software.  Also, the packages on DVD may not be the latest release.  So, we need to get the packages from the Internet. Media change: please insert the disc labeled 'Debian GNU/Linux 11.0.0 _Bullseye_ - Official amd64 DVD Binary-1 20210814-10:04' in the drive '/media/cdrom/' and press [Enter] The /etc/apt/sources.list file with DVD as a source would look something like below. # deb cdrom:[Debian GNU/Linux 11.0.0 _Bullseye_ - Official amd64 DVD Binary-1 20210814-10:04]/ bullseye contrib main deb cdrom:[Debian GNU/Linux 11.0.0 _Bullseye_ - Official amd64 DVD Binary-1 20210814-10:04]/ bullseye contrib main deb http://security.debian.org/debian-security bullseye-security

Cara Membuat Live USB VMWare ESXi 6.7 di Linux (Debian/CentOS)

VMWare ESXi 6.7 menyediakan satu installer dalam format CDROM ISO. Dalam tutorial kali ini kita akan membuat sebuah live USB dengan menggunakan sistem Linux, misalnya Debian dan CentOS. Untuk keperluan tutorial kali ini silakan pastikan sudah ada download installer ISO ESXi 6.7 dari https://my.vmware.com Siapkan satu USB Flashdisk dengan kapasitas lebih dari 1GB. Format dalam satu partisi dengan tool yang biasa dipakai dalam format partisi FAT32. Misal dengan FDISK: [sourcecode] fdisk /dev/sdX [/sourcecode] format ke FAT32: [sourcecode]mkfs.fvat -F 32 -n USB /dev/sdX1[/sourcecode] selanjutnya, kita buat USB tersebut bootable dengan syslinux. Bagi linuxnya belum ada syslinux, silakan install dulu (apt-get install syslinux atau yum install syslinux).