Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add example for metrics and dashboard #2232

Merged
merged 5 commits into from
Jun 16, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion dashboards/resource-manager/resource-manager.json
Original file line number Diff line number Diff line change
Expand Up @@ -1811,7 +1811,7 @@
},
"timepicker": {},
"timezone": "",
"title": "Resource Manager",
"title": "libp2p Resource Manager",
"uid": "MgmGIjjnj",
"version": 1,
"weekStart": ""
Expand Down
2 changes: 1 addition & 1 deletion examples/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ require (
github.com/libp2p/go-libp2p v0.28.0
github.com/libp2p/go-libp2p-kad-dht v0.20.1-0.20230209220319-6c2045abad23
github.com/multiformats/go-multiaddr v0.9.0
github.com/prometheus/client_golang v1.14.0
)

require (
Expand Down Expand Up @@ -81,7 +82,6 @@ require (
github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58 // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/polydawn/refmt v0.0.0-20201211092308-30ac6d18308e // indirect
github.com/prometheus/client_golang v1.14.0 // indirect
github.com/prometheus/client_model v0.4.0 // indirect
github.com/prometheus/common v0.42.0 // indirect
github.com/prometheus/procfs v0.9.0 // indirect
Expand Down
13 changes: 13 additions & 0 deletions examples/metrics-and-dashboards/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# Metrics and Dashboards

An example to demonstrate using Prometheus and Grafana to view go-libp2p
metrics. Sets up a Prometheus server and Grafana server via Docker compose. A
small go-libp2p dummy application is included to emit metrics.

Run it with:

```
docker compose up
```

Go to http://localhost:3000/dashboards to see the dashboards.
41 changes: 41 additions & 0 deletions examples/metrics-and-dashboards/compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
services:

prometheus-server:
image: prom/prometheus:latest
restart: unless-stopped
volumes:
- ./prometheus.yml:/etc/prometheus/prometheus.yml
command:
- '--config.file=/etc/prometheus/prometheus.yml'
- '--storage.tsdb.path=/prometheus'
- '--web.console.libraries=/etc/prometheus/console_libraries'
- '--web.console.templates=/etc/prometheus/consoles'
- '--web.enable-lifecycle'
ports:
- 9090:9090
expose:
- 9090

grafana:
# image: sha256:b4cfd1a8f2d221019265ca75b20e066b5ddd34631210441d5877914a0af2fd67
build:
dockerfile: examples/metrics-and-dashboards/grafana.Dockerfile
context: ../../
environment:
- GF_AUTH_DISABLE_LOGIN_FORM=true
- GF_AUTH_ANONYMOUS_ENABLED=true
- GF_AUTH_ANONYMOUS_ORG_ROLE=Admin
volumes:
- ./grafana-config/grafana.ini:/etc/grafana/grafana.ini
- ./grafana-config/provisioning:/etc/grafana/provisioning
ports:
- 3000:3000
sukunrt marked this conversation as resolved.
Show resolved Hide resolved

go-libp2p-node:
build:
context: .
dockerfile: go-libp2p-node.Dockerfile
ports:
- 2112:2112
expose:
- 2112
7 changes: 7 additions & 0 deletions examples/metrics-and-dashboards/go-libp2p-node.Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
FROM golang:alpine
WORKDIR /app
COPY ./main.go .
RUN go mod init example.com/m/v2
RUN go mod tidy
RUN go build main.go
ENTRYPOINT [ "/app/main" ]
5 changes: 5 additions & 0 deletions examples/metrics-and-dashboards/grafana-config/grafana.ini
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
[paths]
provisioning = /etc/grafana/provisioning

[server]
enable_gzip = true
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# config file version
apiVersion: 1

providers:
# <string> an unique provider name
- name: My Dashboard
# <int> org id. will default to orgId 1 if not specified
org_id: 1
# <string, required> name of the dashboard folder. Required
folder: ""
# <string, required> provider type. Required
type: "file"
# <bool> disable dashboard deletion
disableDeletion: false
# <bool> enable dashboard editing
editable: true
# <int> how often Grafana will scan for changed dashboards
updateIntervalSeconds: 5
# <bool> allow updating provisioned dashboards from the UI
allowUiUpdates: true
options:
# <string, required> path to dashboard files on disk. Required
path: /etc/grafana/dashboards
# <bool> use folder names from filesystem to create folders in Grafana
foldersFromFilesStructure: true
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# config file version
apiVersion: 1

datasources:
- name: Prometheus
type: prometheus
# Access mode - proxy (server in the UI) or direct (browser in the UI).
access: proxy
uid: "prometheusuid"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is neat! 👍

url: http://prometheus-server:9090
jsonData:
httpMethod: POST
manageAlerts: true
prometheusType: Prometheus
prometheusVersion: 2.43.0
10 changes: 10 additions & 0 deletions examples/metrics-and-dashboards/grafana.Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
FROM grafana/grafana

COPY ./dashboards /etc/grafana/dashboards
USER root

# Replace every instrance of ${DS_PROMETHEUS} with "prometheusuid"
# Grafana doesn't let us do this in provisioning, so we do it ourselves.
RUN sed -i 's/${DS_PROMETHEUS}/prometheusuid/g' /etc/grafana/dashboards/*/*.json
RUN cat /etc/grafana/dashboards/swarm/swarm.json
USER grafana
93 changes: 93 additions & 0 deletions examples/metrics-and-dashboards/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
package main

import (
"context"
"fmt"
"log"
"math/rand"
"net/http"
"sync"
"time"

"github.com/libp2p/go-libp2p"
"github.com/libp2p/go-libp2p/core/peer"
"github.com/libp2p/go-libp2p/p2p/protocol/ping"
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promhttp"

rcmgr "github.com/libp2p/go-libp2p/p2p/host/resource-manager"
rcmgrObs "github.com/libp2p/go-libp2p/p2p/host/resource-manager/obs"
)

const ClientCount = 32

func main() {
http.Handle("/metrics", promhttp.Handler())
go func() {
http.ListenAndServe(":2112", nil)
}()

rcmgrObs.MustRegisterWith(prometheus.DefaultRegisterer)

str, err := rcmgrObs.NewStatsTraceReporter()
if err != nil {
log.Fatal(err)
}

rmgr, err := rcmgr.NewResourceManager(rcmgr.NewFixedLimiter(rcmgr.DefaultLimits.AutoScale()), rcmgr.WithTraceReporter(str))
if err != nil {
log.Fatal(err)
}
server, err := libp2p.New(libp2p.ResourceManager(rmgr))
if err != nil {
log.Fatal(err)
}

// Make a bunch of clients that all ping the server at various times
wg := sync.WaitGroup{}
Comment on lines +46 to +47
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can we make the server ping some clients too?
I understand that is inconsistent with the "server" term but in this example the dashboard is mostly empty.
libp2p-swarm

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

*server initiate a connection with some clients.

for i := 0; i < ClientCount; i++ {
wg.Add(1)
go func(i int) {
defer wg.Done()
time.Sleep(time.Duration(i%100) * 100 * time.Millisecond)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should we make this slightly longer? this example is complete by the time I open the grafana window.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the prometheus scrape interval is 1m

newClient(peer.AddrInfo{
ID: server.ID(),
Addrs: server.Addrs(),
}, i)
}(i)
}
wg.Wait()
}

func newClient(serverInfo peer.AddrInfo, pings int) {
// Sleep some random amount of time to spread out the clients so the graphs look more interesting
time.Sleep(time.Duration(rand.Intn(100)) * time.Second)
fmt.Println("Started client", pings)

client, err := libp2p.New(
// We just want metrics from the server
libp2p.DisableMetrics(),
libp2p.NoListenAddrs,
)
defer func() {
_ = client.Close()
}()

if err != nil {
log.Fatal(err)
}

client.Connect(context.Background(), serverInfo)

p := ping.Ping(context.Background(), client, serverInfo.ID)

pingSoFar := 0
for pingSoFar < pings {
res := <-p
pingSoFar++
if res.Error != nil {
log.Fatal(res.Error)
}
time.Sleep(5 * time.Second)
}
}
15 changes: 15 additions & 0 deletions examples/metrics-and-dashboards/prometheus.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
global:
scrape_interval: 1m

scrape_configs:
- job_name: "prometheus"
scrape_interval: 1m
static_configs:
- targets: ["localhost:9090"]

- job_name: "node"
static_configs:
- targets: ["node-exporter:9100"]
- job_name: "go-libp2p"
static_configs:
- targets: ["go-libp2p-node:2112"]