Skip to content

Commit e27ab9d

Browse files
committed
docs: add images and enhance documentation for Golang application monitoring with Prometheus and Grafana
1 parent 00149c5 commit e27ab9d

File tree

7 files changed

+84
-26
lines changed

7 files changed

+84
-26
lines changed

content/guides/go-prometheus-monitoring/_index.md

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -10,29 +10,31 @@ params:
1010
time: 45 minutes
1111
---
1212

13-
The guide teaches you how to containerize a Golang application and monitor it with Prometheus and Grafana. In this guide, you'll learn how to:
13+
The guide teaches you how to containerize a Golang application and monitor it with Prometheus and Grafana.
1414

1515
> **Acknowledgment**
1616
>
1717
> Docker would like to thank [Pradumna Saraf](https://twitter.com/pradumna_saraf) for his contribution to this guide.
1818
1919
## Overview
2020

21-
To make sure our application is working as intended, monitoring is really important. In this guide, you'll learn how to containerize a Golang application and monitor it with Prometheus and Grafana.
21+
To make sure our application is working as intended, monitoring is really important. One of the most popular monitoring tools is Prometheus. Prometheus is an open-source monitoring and alerting toolkit that is designed for reliability and scalability. It collects metrics from monitored targets by scraping metrics HTTP endpoints on these targets. To visualize the metrics, we can use Grafana. Grafana is an open-source platform for monitoring and observability that allows you to query, visualize, alert on, and understand your metrics no matter where they are stored.
2222

23-
We will create a Golang server with some endpoints to simulate a real-world application. Then we will expose metrics from the server using Prometheus. Finally, we will visualize the metrics using Grafana. We will containerize the Golang application and using the Docker Compose file, we will connect all the services- Golang, Prometheus, and Grafana.
23+
In this guide, we will be creating a Golang server with some endpoints to simulate a real-world application. Then we will expose metrics from the server using Prometheus. Finally, we will visualize the metrics using Grafana. We will containerize the Golang application and using the Docker Compose file, we will connect all the services- Golang, Prometheus, and Grafana.
2424

2525
## What will you learn?
2626

27-
* Create a Golang application with Prometheus metrics.
27+
* Create a Golang application with custom Prometheus metrics.
2828
* Containerize a Golang application.
2929
* Use Docker Compose to run multiple services and connect them together to monitor a Golang application with Prometheus and Grafana.
30-
* Visualize the metrics using Grafana.
30+
* Visualize the metrics using Grafana dashboards.
3131

3232
## Prerequisites
3333

3434
- A good understanding of Golang is assumed.
35-
- You must me familiar with Prometheus and Grafana concepts. If you are new to Prometheus and Grafana.
35+
- You must me familiar with Prometheus and creating dashboards in Grafana.
3636
- You must have familiarity with Docker concepts like containers, images, and Dockerfiles. If you are new to Docker, you can start with the [Docker basics](/get-started/docker-concepts/the-basics/what-is-a-container.md) guide.
3737

38-
Start by containerizing an existing Bun application.
38+
## Next steps
39+
40+
We will be creating a Golang server and exposing metrics using Prometheus.

content/guides/go-prometheus-monitoring/application.md

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,7 @@ aliases:
1212

1313
* You have a [Git client](https://git-scm.com/downloads). The examples in this section use a command-line based Git client, but you can use any client.
1414

15-
## Overview
16-
17-
To make sure our application is working an intended, monitoring is really important. In this guide, you'll learn how to containerize a Golang application and monitor it with Prometheus and Grafana. In this guide, you'll learn how to:
15+
We will be creating a Golang server with some endpoints to simulate a real-world application. Then we will expose metrics from the server using Prometheus.
1816

1917
## Getting the sample application
2018

@@ -34,6 +32,7 @@ go-prometheus-monitoring
3432
├── Docker
3533
│ ├── grafana.yml
3634
│ └── prometheus.yml
35+
├── dashboard.json
3736
├── Dockerfile
3837
├── LICENSE
3938
├── README.md
@@ -43,6 +42,16 @@ go-prometheus-monitoring
4342
└── main.go
4443
```
4544

45+
- **main.go** - The entry point of the application.
46+
- **go.mod and go.sum** - Go module files.
47+
- **Dockerfile** - Dockerfile used to build the app.
48+
- **Docker/** - Contains the Docker Compose configuration files for Grafana and Prometheus.
49+
- **compose.yaml** - Compose file to launch everything (Golang app, Prometheus, and Grafana).
50+
- **dashboard.json** - Grafana dashboard configuration file.
51+
- **Dockerfile** - Dockerfile used to build the Golang app.
52+
- **compose.yaml** - Docker Compose file to launch everything (Golang app, Prometheus, and Grafana).
53+
- Other files are for licensing and documentation purposes.
54+
4655
## Understanding the application
4756

4857
Below is complete logic of the application you will find in the `main.go`. Let's break this to understand code better.
@@ -217,7 +226,7 @@ Make sure you are still inside `go-prometheus-monitoring` directory in the termi
217226
Now let's check our application's metrics by accessing the `/metrics` endpoint.
218227
Open `http://localhost:8000/metrics` in your browser. You should see similar output to the one below.
219228

220-
```text
229+
```sh
221230
# HELP api_http_request_error_total Total number of errors returned by the API
222231
# TYPE api_http_request_error_total counter
223232
api_http_request_error_total{path="/",status="404"} 1
@@ -229,11 +238,10 @@ api_http_request_total{path="/health",status="200"} 2
229238
api_http_request_total{path="/v1/users",status="200"} 1
230239
```
231240

232-
In the terminal, press `ctrl`+`c` to stop the application.
241+
In the terminal, press `ctrl` + `c` to stop the application.
233242

234-
:::note
235-
If you don't want to run the application locally, and want to run it in a Docker container, skip to next page where we create a Dockerfile and containerize the application.
236-
:::
243+
> [!Note]
244+
> If you don't want to run the application locally, and want to run it in a Docker container, skip to next page where we create a Dockerfile and containerize the application.
237245
238246
## Summary
239247

content/guides/go-prometheus-monitoring/compose.md

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -151,4 +151,17 @@ The services will start running, and you can access the Golang application at `h
151151
$ docker ps
152152
```
153153

154-
Next, we will learn how to develop the Golang application with Docker Compose and monitor it with Prometheus and Grafana.
154+
## Summary
155+
156+
In this section, you learned how to connect services together using Docker Compose. You created a Docker Compose file to run multiple services together and connect them using networks. You also learned how to build and run the services using Docker Compose.
157+
158+
Related information:
159+
160+
- [Docker Compose overview](/manuals/compose/_index.md)
161+
- [Compose file reference](/reference/compose-file/_index.md)
162+
163+
Next, we will learn how to develop the Golang application with Docker Compose and monitor it with Prometheus and Grafana.
164+
165+
## Next steps
166+
167+
In the next section, you will learn how to develop the Golang application with Docker. You will also learn how to use Docker Compose Watch to rebuild the image whenever you make changes to the code. Lastly, you will test the application and visualize the metrics in Grafana using Prometheus as the datasource.

content/guides/go-prometheus-monitoring/containerize.md

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ aliases:
88
- /guides/go-prometheus-monitoring/containerize/
99
---
1010

11+
Containerization helps us bundle the application and its dependencies into a single package called a container. This package can run on any platform without worrying about the environment. In this section, we will learn how to containerize a Golang application using Docker.
12+
1113
To containerize a Golang application, we first need to create a Dockerfile. The Dockerfile contains instructions to build and run the application in a container. Also, when creating a Dockerfile, we can follow different sets of best practices to optimize the image size and make it more secure.
1214

1315
## Creating a Dockerfile
@@ -59,13 +61,13 @@ The Dockerfile consists of two stages:
5961

6062
1. **Build stage**: This stage uses the official Golang image as the base and sets the necessary environment variables. It also sets the working directory inside the container, copies the `go.mod` and `go.sum` files for dependency installation, downloads the dependencies, copies the entire application source, and builds the Go binary.
6163

62-
We use the `golang:1.24-alpine` image as the base image for the build stage. The `CGO_ENABLED=0` environment variable disables CGO, which is useful for building static binaries. We also set the `GOOS` and `GOARCH` environment variables to `linux` and `amd64`, respectively, to build the binary for the Linux platform.
64+
We use the `golang:1.24-alpine` image as the base image for the build stage. The `CGO_ENABLED=0` environment variable disables CGO, which is useful for building static binaries. We also set the `GOOS` and `GOARCH` environment variables to `linux` and `amd64`, respectively, to build the binary for the Linux platform.
6365

6466
2. **Final stage**: This stage uses the official Alpine image as the base and copies the compiled binary from the build stage. It also exposes the application's port and runs the application.
6567

66-
We use the `alpine:3.17` image as the base image for the final stage. We copy the compiled binary from the build stage to the final image. We expose the application's port using the `EXPOSE` instruction and run the application using the `CMD` instruction.
68+
We use the `alpine:3.17` image as the base image for the final stage. We copy the compiled binary from the build stage to the final image. We expose the application's port using the `EXPOSE` instruction and run the application using the `CMD` instruction.
6769

68-
Apart from the multi-stage build, the Dockerfile also follows best practices such as using the official images, setting the working directory, and copying only the necessary files to the final image. We can further optimize the Dockerfile by other best practices.
70+
Apart from the multi-stage build, the Dockerfile also follows best practices such as using the official images, setting the working directory, and copying only the necessary files to the final image. We can further optimize the Dockerfile by other best practices.
6971

7072
## Build the Docker image and run the application
7173

@@ -97,8 +99,6 @@ Related information:
9799

98100
- [Dockerfile reference](/reference/dockerfile.md)
99101
- [.dockerignore file](/reference/dockerfile.md#dockerignore-file)
100-
- [Docker Compose overview](/manuals/compose/_index.md)
101-
- [Compose file reference](/reference/compose-file/_index.md)
102102

103103
## Next steps
104104

content/guides/go-prometheus-monitoring/develop.md

Lines changed: 40 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,15 +8,19 @@ aliases:
88
- /guides/go-prometheus-monitoring/develop/
99
---
1010

11-
In the last section, we saw how using Docker Compose, we can connect our services together. In this section, we will learn how to develop the Golang application with Docker.
11+
In the last section, we saw how using Docker Compose, we can connect our services together. In this section, we will learn how to develop the Golang application with Docker. We will also see how to use Docker Compose Watch to rebuild the image whenever we make changes to the code. Lastly, we will test the application and visualize the metrics in Grafana using Prometheus as the datasource.
1212

13-
Now, if we make any changes to our golang application, it needs to reflect in the container, right? To do that, one approach is use --build flag in Docker Compose. It will rebuild all the services which have `build` instruction in the `compose.yml` file. This is how you can use it:
13+
## Developing the application
14+
15+
Now, if we make any changes to our golang application locally, it needs to reflect in the container, right? To do that, one approach is use --build flag in Docker Compose after making changes in the code. This will rebuild all the services which have `build` instruction in the `compose.yml` file, in our case, the `api` service (golang application).
1416

1517
```
1618
docker compose up --build
1719
```
1820

19-
But, this is not the best approach. It will rebuild all the services which have `build` instruction. This is not efficient. Every time you make a change in the code, we need to rebuild manually. This is not is not very good flow for development. Another approach is to use Docker Compose Watch. In the `compose.yml` file, under the service `api`, we have added the `develop` section. So, it's more like a hot reloading. Whenever we make changes to code (defined in `path`), it will rebuild the image (or restart depending on the action). This is how you can use it:
21+
But, this is not the best approach. This is not efficient. Every time we make a change in the code, we need to rebuild manually. This is not is not very good flow for development.
22+
23+
The better approach is to use Docker Compose Watch. In the `compose.yml` file, under the service `api`, we have added the `develop` section. So, it's more like a hot reloading. Whenever we make changes to code (defined in `path`), it will rebuild the image (or restart depending on the action). This is how you can use it:
2024

2125
```yaml {hl_lines="17-20",linenos=true}
2226
services:
@@ -41,11 +45,42 @@ services:
4145
action: rebuild
4246
```
4347
44-
Run the following command to run your application with Compose Watch.
48+
One you have added the `develop` section in the `compose.yml` file, you can use the following command to start the development server:
4549

4650
```console
4751
$ docker compose watch
4852
```
4953

50-
Now, if you modify your `main.go` you will see the changes in real time without re-building the image.
54+
Now, if you modify your `main.go` or any other file in the project, the `api` service will be rebuilt automatically. You will see the following output in the terminal:
55+
56+
```bash
57+
Rebuilding service(s) ["api"] after changes were detected...
58+
[+] Building 8.1s (15/15) FINISHED docker:desktop-linux
59+
=> [api internal] load build definition from Dockerfile 0.0s
60+
=> => transferring dockerfile: 704B 0.0s
61+
=> [api internal] load metadata for docker.io/library/alpine:3.17 1.1s
62+
.
63+
=> => exporting manifest list sha256:89ebc86fd51e27c1da440dc20858ff55fe42211a1930c2d51bbdce09f430c7f1 0.0s
64+
=> => naming to docker.io/library/go-api:latest 0.0s
65+
=> => unpacking to docker.io/library/go-api:latest 0.0s
66+
=> [api] resolving provenance for metadata file 0.0s
67+
service(s) ["api"] successfully built
68+
```
69+
70+
## Testing the application
71+
72+
Now that we have our application running, Let's head over to Grafana dashboard to visualize the metrics we are registering. Open your browser and navigate to `http://localhost:3000`. You will be greeted with the Grafana login page. The login credentials are the one we have provided in compose file.
73+
74+
Once you are logged in, you can create a new dashboard. While creating dashboard you will notice that is default datasource is `Prometheus`. This is because we have already configured the datasource in the `grafana.yml` file.
75+
76+
![The optional settings screen with the options specified.](../images/grafana-dash.png)
77+
78+
We can use different panels to visualize the metrics. We will not go into details of Grafana here. You can refer to the [official documentation](https://grafana.com/docs/grafana/latest/) for more information. I created a Bar Gauge panel to visualize the total number of requests from different endpoints. We used the `api_http_request_total` and `api_http_request_error_total` metrics to get the data.
79+
80+
![The optional settings screen with the options specified.](../images/grafana-panel.png)
81+
82+
We created this panel to visualize the total number of requests from different endpoints to compare the successful and failed requests. For all the good requests, the bar will be green, and for all the failed requests, the bar will be red. Plus it will also show the from which endpoint the request is coming, either it's a successful request or a failed request. If you want to use this panel, you can import the `dashboard.json` file from the repo you cloned.
83+
84+
## Summary
5185

86+
That's it! We come to the end of this guide. We learned how to develop the Golang application with Docker. We also saw how to use Docker Compose Watch to rebuild the image whenever we make changes to the code. Lastly, we tested the application and visualized the metrics in Grafana using Prometheus as the datasource.
466 KB
Loading
600 KB
Loading

0 commit comments

Comments
 (0)