> ## Documentation Index
> Fetch the complete documentation index at: https://mw-docs.middleware.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Go

> Go APM - Setup & Installation Docs | Middleware

| Traces | Metrics | App Logs | Custom Logs | Profiling |
| :----: | :-----: | :------: | :---------: | :-------: |
|    ✅   |    ✅    |    ✖️    |      ✅      |     ✅     |

This guide walks you through setting up Application Performance Monitoring (APM) on a Go application. These instructions can also be found on the Installation page in your Middleware Account. View example code [here](https://github.com/middleware-labs/demo-apm/tree/master/golang).

# Prerequisites

<Steps>
  <Step title="Infra Agent">
    Infrastructure Agent (Infra Agent). To install the Infra Agent, see our <a href="https://docs.middleware.io/docs/agent-installation/overview"> installation guide</a>.
  </Step>

  <Step title="Go Version">
    `Go version 1.17` or above. Check your Go version with the following command:

    ```javascript Shell theme={null}
    go version
    ```
  </Step>
</Steps>

# Install

### Step 1: Install `Go` APM Package

Run the following command in your terminal.

```go Go theme={null}
go get github.com/middleware-labs/golang-apm
```

### Step 2: Import Tracker

Add the following lines to the beginning of your application code base.

```go Go theme={null}
import (
    track "github.com/middleware-labs/golang-apm/tracker"
)
```

Add the following snippet to your main function. The access token is your account key, which can be found on the Installation page. If using a Golang web framework, additional code may be required, see Step 3.

```go Go theme={null}
go track.Track(
    track.WithConfigTag("service", {APM-SERVICE-NAME}),
    track.WithConfigTag("accessToken", "<xxxxxxxxxx>"),
)
```

### Step 3: Framework-Specific Configuration

If any of the following Go web frameworks are used in your application, additional configuration is required. View additional configuration steps per framework below.

<AccordionGroup>
  <Accordion title="gin/gonic">
    Middleware APM requires Gin version 1.1.18 or higher.

    Install the Middleware APM Gin package.

    ```go Go theme={null}
    go get github.com/middleware-labs/golang-apm-gin
    ```

    Add the Middleware APM Gin package to the existing import statement from Step 2.

    ```go Go theme={null}
    import (
         track "github.com/middleware-labs/golang-apm/tracker"
         mwgin "github.com/middleware-labs/golang-apm-gin/gin"
    )
    ```

    Initialize the Middleware APM wherever the Gin package is initialized, typically in the main function.

    ```go Go theme={null}
    r := gin.Default()
    config, _ := track.Track(
         track.WithConfigTag("service","<apm-service-name>"),
         track.WithConfigTag("accessToken","<xxxxxxxxxx>"),
    )
    r.Use(mwgin.Middleware(config))
    ```
  </Accordion>

  <Accordion title="gorilla/mux">
    Middleware APM requires MUX version 1.8.0

    Install the Middleware APM MUX package.

    ```go Go theme={null}
    go get github.com/middleware-labs/golang-apm-mux
    ```

    Add the Middleware APM MUX package to the existing import statement from Step 2.

    ```go Go theme={null}
    import (
         track "github.com/middleware-labs/golang-apm/tracker"
         mwmux "github.com/middleware-labs/golang-apm-mux/mux"
    )
    ```

    Initialize the Middleware APM wherever the MUX package is initialized, typically in the main function.

    ```go Go theme={null}
    r := mux.newRouter()
    config, _ := track.Track(
         track.WithConfigTag("service", "<apm-service-name>"),
         track.WithConfigTag("accessToken", "<xxxxxxxxxx>"),
    )
    r.Use(mwmux.Middleware(config))
    ```
  </Accordion>

  <Accordion title="go-chi">
    Middleware APM requires go-chi/chi version 1.5.4 or higher.

    Install the Middleware APM go-chi package.

    ```go Go theme={null}
    go get github.com/middleware-labs/agent-apm-go-chi-legacy
    ```

    Add the Middleware APM go-chi package to the existing import statement from Step 2.

    ```go Go theme={null}
    import (
         track "github.com/middleware-labs/golang-apm/tracker"
         mwchi "github.com/middleware-labs/agent-apm-go-chi-legacy"
    )
    ```

    Initialize the Middleware APM wherever the go-chi package is initialized, typically in the main function.

    ```go Go theme={null}
    config, _ := track.Track(
         track.WithConfigTag("service", "<apm-service-name>"),
         track.WithConfigTag("accessToken", "<xxxxxxxxxx>"),
    )
    r := chi.NewRouter()
    r.Use(mwchi.Middleware("<my-server>", mwchi.WithChiRoutes(r)))
    ```
  </Accordion>

  <Accordion title="go-chi/v5">
    Middleware APM requires go-chi/chi/v5 version 5.0.8 or higher.

    Install the Middleware APM go-chi package.

    ```go Go theme={null}
    go get github.com/middleware-labs/agent-apm-go-chi
    ```

    Add the Middleware APM go-chi package to the existing import statement from Step 2.

    ```go Go theme={null}
    import (
         track "github.com/middleware-labs/golang-apm/tracker"
         mwchi "github.com/middleware-labs/agent-apm-go-chi"
    )
    ```

    Initialize the Middleware APM wherever the go-chi package is initialized, typically in the main function.

    ```go Go theme={null}
    config, _ := track.Track(
         track.WithConfigTag("service", "<apm-service-name>"),
         track.WithConfigTag("accessToken", "<xxxxxxxxxx>"),
    )
    r := chi.NewRouter()
    r.Use(mwchi.Middleware("<my-server>", mwchi.WithChiRoutes(r)))
    ```
  </Accordion>

  <Accordion title="astaxie-beego">
    Middleware APM requires astaxie/beego version 1.12.3 or higher.

    Install the Middleware APM astaxie-beego package.

    ```go Go theme={null}
    go get github.com/middleware-labs/golang-apm-beego
    ```

    Add the Middleware APM astaxie-beego package to the existing import statement from Step 2.

    ```go Go theme={null}
    import (
         track "github.com/middleware-labs/golang-apm/tracker"
         mw_beego "github.com/middleware-labs/golang-apm-beego/beego"
    )
    ```

    Initialize the Middleware APM wherever the astaxie-beego package is initialized, typically in the main function.

    ```go Golang theme={null}
    config, _ := track.Track(_
         track.WithConfigTag("service", "<apm-service-name>"),
         track.WithConfigTag("accessToken", "<xxxxxxxxxx>"),
    )
    mware := mw_beego.Middleware(config)
    ```
  </Accordion>

  <Accordion title="beego/v2">
    Middleware APM requires beego/v2 version 2.0.7 or higher.

    Install the Middleware APM astaxie-beego package.

    ```go Go theme={null}
    go get github.com/middleware-labs/golang-apm-beego
    ```

    Add the Middleware APM astaxie-beego package to the existing import statement from Step 2.

    ```go Go theme={null}
    import (
         track "github.com/middleware-labs/golang-apm/tracker"
         mw_beego "github.com/middleware-labs/golang-apm-beego/beego"
    )
    ```

    Initialize the Middleware APM wherever the astaxie-beego package is initialized, typically in the main function.

    ```go Go theme={null}
    config, _ := track.Track(_
         track.WithConfigTag("service", "<apm-service-name>"),
         track.WithConfigTag("accessToken", "<xxxxxxxxxx>"),
    )
    mware := mw_beego.Middleware(config)
    ```
  </Accordion>

  <Accordion title="database/sql">
    Middleware APM requires go-sql-driver/mysql version 1.7.1 or higher.

    Install the Middleware APM SQL package.

    ```go Go theme={null}
    go get github.com/middleware-labs/golang-apm-sql
    ```

    Add the Middleware APM SQL package to the existing import statement from Step 2.

    ```go Go theme={null}
    import (
         track "github.com/middleware-labs/golang-apm/tracker"
         mw_sql "github.com/middleware-labs/golang-apm-sql/sql"
    )
    ```

    Initialize the Middleware APM wherever the SQL package is initialized, typically in the main function.

    ```go Go theme={null}
    config, _ := track.Track(
         track.WithConfigTag("service", "<apm-service-name>"),
         track.WithConfigTag("accessToken", "<xxxxxxxxxx>"),
    )
    db, err := mw_sql.Open("mysql", "uname:password@tcp(127.0.0.1:3306)/todo")
    ```
  </Accordion>

  <Accordion title="go-pg/pg">
    Middleware APM requires go-pg/pg version 10.11.1 or higher.

    Install the Middleware APM PG package.

    ```go Go theme={null}
    go get github.com/middleware-labs/golang-apm-pg
    ```

    Add the Middleware APM PG package to the existing import statement from Step 2.

    ```go Go theme={null}
    import (
         "github.com/go-pg/pg/v10"
              track "github.com/middleware-labs/golang-apm/tracker"
              mw_pg "github.com/middleware-labs/golang-apm-pg/pg"
    )
    ```

    Initialize the Middleware APM wherever the PG package is initialized, typically in the main function.

    ```go Go theme={null}
    config, _ := track.Track(_
         track.WithConfigTag("service", "<apm-service-name>"),
         track.WithConfigTag("accessToken", "<xxxxxxxxxx>"),
    )
    db := pg.Connect(&pg.Options{
                   Addr:      ":5432",
                   User:      "postgres",
                   Password:  "postgres",
                   Database:  "dbname",
              })
    mw_pg.AddQueryHook(db)
    ```
  </Accordion>

  <Accordion title="GORM 1">
    Middleware APM requires jinzhu/gorm version 1.9.16 or higher.

    Install the Middleware APM SQL package.

    ```go Go theme={null}
    go get github.com/middleware-labs/golang-apm-sql
    ```

    Add the Middleware APM SQL package to the existing import statement from Step 2.

    ```go Go theme={null}
    import (
         track "github.com/middleware-labs/golang-apm/tracker"
         mw_sql "github.com/middleware-labs/golang-apm-sql/sql"
    )
    ```

    Initialize the Middleware APM inside the main function.

    ```go Go theme={null}
    config, _ := track.Track(_
         track.WithConfigTag("service", "<apm-service-name>"),
         track.WithConfigTag("accessToken", "<xxxxxxxxxx>"),
    )
    db, err := mw_sql.Open(driverName, dataSourceName, mw_sql.WithDBName(dbname), mw_sql.WithAttributes(tracker.String("db.system","mysql")))
    ```
  </Accordion>

  <Accordion title="GORM 2">
    Middleware APM requires gorm.io/gorm version 1.25.1 or higher.

    Install the Middleware APM GORM package.

    ```go Go theme={null}
    go get github.com/middleware-labs/go-agent-gorm
    ```

    Add the Middleware APM GORM package to the existing import statement from Step 2.

    ```go Go theme={null}
    import (
         "gorm.io/gorm"
         "gorm.io/driver/mysql"
              track "github.com/middleware-labs/golang-apm/tracker"
              mw_gorm "github.com/middleware-labs/go-agent-gorm/gorm"
    )
    ```

    Initialize the Middleware APM inside the main function.

    ```go Go theme={null}
    config, _ := track.Track(_
         track.WithConfigTag("service", "<apm-service-name>"),
         track.WithConfigTag("accessToken", "<xxxxxxxxxx>"),
    )
    db, err := gorm.Open(mysql.Open("username:password@tcp(127.0.0.1:3306)/dbname"), &gorm.Config{})
    if err != nil {
         panic(err)
    }
    if err := db.Use(mw_gorm.NewPlugin(mw.gorm.WithDBName("dbname"), mw_gorm.WithAttributes(track.String("db.system", "mysql")))); err != nil {
         panic(err)
    }
    ```

    Then use db.WithContext(ctx) to propagate the active span.

    ```go Go theme={null}
    var num int
    if err := db.WithContext(ctx).Raw("SELECT 42").Scan(&num).Error; err != nil {
         panic(err)
    }
    ```
  </Accordion>

  <Accordion title="go-pg/mongo">
    Middleware APM requires go.mongodb.org/mongo-driver version 1.12.1 or higher.

    Install the Middleware APM Mongo package.

    ```go Go theme={null}
    go get github.com/middleware-labs/golang-apm-mongo
    ```

    Add the Middleware APM Mongo package to the existing import statement from Step 2.

    ```go Go theme={null}
    import (
         "go.mongodb.org/mongo-driver/mongo/options"

         track "github.com/middleware-labs/golang-apm/tracker"
         mw_mongo "github.com/middleware-labs/golang-apm-mongo/mongo"
    )
    ```

    Initialize the Middleware APM inside the main function.

    ```go Go theme={null}
    config, _ := track.Track(_
         track.WithConfigTag("service", "<apm-service-name>"),
         track.WithConfigTag("accessToken", "<xxxxxxxxxx>"),
    )
    opts := options.Client()
    opts.Monitor = mw_mongo.NewMonitor()
    ```
  </Accordion>

  <Accordion title="gRPC">
    Middleware APM requires google.golang.org/grpc version 1.53.0 or higher.

    Install the Middleware APM gRPC package.

    ```go Go theme={null}
    go get github.com/middleware-labs/golang-apm-grpc
    ```

    Add the Middleware APM astaxie-beego package to the existing import statement from Step 2.

    ```go Go theme={null}
    import (
         track "github.com/middleware-labs/golang-apm/tracker"
         mw_grpc "github.com/middleware-labs/golang-apm-grpc/grpc"
    )
    ```

    Initialize the Middleware APM wherever the astaxie-beego package is initialized, typically in the main function.

    ```go Go theme={null}
    config, _ := track.Track(_
         track.WithConfigTag("service", "<apm-service-name>"),
         track.WithConfigTag("accessToken", "<xxxxxxxxxx>"),
    )
    mware := mwbeego.MiddleWare(config.ServiceName)
    ```
  </Accordion>
</AccordionGroup>

### Step 4: Container Variables

Applications running in a container require an additional environment variable. If your application is not running in a container, move to Step 5.

#### Docker

Add the following environment variable to your application.

```bash Shell theme={null}
MW_AGENT_SERVICE=DOCKER_BRIDGE_GATEWAY_ADDRESS
```

<Note> The `DOCKER_BRIDGE_GATEWAY_ADDRESS` is the IP address of the gateway between the Docker host and bridge network. This is `172.17.0.1` by default.
Learn more about Docker bridge networking [here](https://docs.docker.com/network/network-tutorial-standalone/) </Note>

#### Kubernetes

Run the following command to find the `mw-service` in Kubernetes:

```bash Shell theme={null}
kubectl get service --all-namespaces | grep mw-service
```

Add the following environment variable to your application deployment YAML file:

```bash Shell theme={null}
MW_AGENT_SERVICE=mw-service.mw-agent-ns.svc.cluster.local
```

### Step 5: Capture Application Data

#### Traces

Distributed tracing is automatically enabled upon completion of Step 2.

#### Custom Logs

To ingest custom logs into Middleware, utilize the following functions inside your logging method based on desired log severity levels.

```go Go theme={null}
"github.com/middleware-labs/golang-apm/logger"

....

logger.Error("Error")
logger.Info("Info")
logger.Warn("Warn")
```

#### Profiling

Application Profiling is auto-configured upon completing Step 2.

#### Stack Traces

Use the track.RecordError(ctx,error) method to record a stack trace when an error occurs. See an example of this method below.

```go Go theme={null}
app.get("/hello", (req, res) => {
    ctx := req.Context()
    try {
        throw ("error");
    } catch (error) {
        track.RecordError(ctx, error)
    }
})
```

# Continuous Profiling

Continuous profiling captures real-time performance insights from your application to enable rapid identification of resource allocation, bottlenecks, and more. Navigate to the [Continuous Profiling](https://docs.middleware.io/workflow/profiling#continuous-profiling) section to learn more about using Continuous Profiling with the Go APM.

<Note> Need assistance or want to learn more about Middleware? Contact us at support\[at]middleware.io. </Note>
