Skip to content

Commit

Permalink
Merge pull request #594 from pinheadmz/grafana-default
Browse files Browse the repository at this point in the history
Deploy default grafana dashboard automatically
  • Loading branch information
m3dwards authored Sep 13, 2024
2 parents 46ad555 + d6473fe commit 023421e
Show file tree
Hide file tree
Showing 10 changed files with 99 additions and 70 deletions.
29 changes: 8 additions & 21 deletions docs/logging_monitoring.md
Original file line number Diff line number Diff line change
Expand Up @@ -62,10 +62,11 @@ aggregate logs and data from Bitcoin RPC queries into a web-based dashboard.
## Connect to logging dashboard

The logging stack including the user interface web server runs inside the kubernetes cluster.
To access that from a local web browser, you must use kubernetes port-forwarding.
Warnet will forward port `2019` locally from the cluster, and the landing page for all
web based interfaces will be available at `localhost:2019`.

This page can also be opened quickly with the command [`warnet dashboard`](/docs/warnet.md#warnet-dashboard)

Run the script `./resources/scripts/connect_logging.sh` to forward port 3000.
The Grafana dashboard will then be available locally at `localhost:3000`.

### Prometheus

Expand Down Expand Up @@ -122,21 +123,7 @@ web-based interface.
#### Dashboards
To view the default metrics in the included default dashboard, upload the dashboard
JSON file to the Grafana server:
```sh
curl localhost:3000/api/dashboards/db \
-H "Content-Type: application/json" \
--data "{\"dashboard\": $(cat resources/configs/grafana/default_dashboard.json)}"
```

Note the URL in the reply from the server (example):

```sh
{"folderUid":"","id":2,"slug":"default-warnet-dashboard","status":"success","uid":"fdu0pda1z6a68b","url":"/d/fdu0pda1z6a68b/default-warnet-dashboard","version":1}(
```
Open the dashboard in your browser (example):
`http://localhost:3000/d/fdu0pda1z6a68b/default-warnet-dashboard`
Grafana dashboards are described in JSON files. A default Warnet dashboard
is included and any other json files in the `/resources/charts/grafana-dashboards/files` directory
will also be deployed to the web server. The Grafana UI itself also has an API
for creating, exporting, and importing other dashboard files.
23 changes: 23 additions & 0 deletions resources/charts/grafana-dashboards/.helmignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# Patterns to ignore when building packages.
# This supports shell glob matching, relative path matching, and
# negation (prefixed with !). Only one pattern per line.
.DS_Store
# Common VCS dirs
.git/
.gitignore
.bzr/
.bzrignore
.hg/
.hgignore
.svn/
# Common backup files
*.swp
*.bak
*.tmp
*.orig
*~
# Various IDEs
.project
.idea/
*.tmproj
.vscode/
24 changes: 24 additions & 0 deletions resources/charts/grafana-dashboards/Chart.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
apiVersion: v2
name: grafana-dashboards
description: A Helm chart for Kubernetes

# A chart can be either an 'application' or a 'library' chart.
#
# Application charts are a collection of templates that can be packaged into versioned archives
# to be deployed.
#
# Library charts provide useful utilities or functions for the chart developer. They're included as
# a dependency of application charts to inject those utilities and functions into the rendering
# pipeline. Library charts do not define any templates and therefore cannot be deployed.
type: application

# This is the chart version. This version number should be incremented each time you make changes
# to the chart and its templates, including the app version.
# Versions are expected to follow Semantic Versioning (https://semver.org/)
version: 0.1.0

# This is the version number of the application being deployed. This version number should be
# incremented each time you make changes to the application. Versions are not expected to
# follow Semantic Versioning. They should reflect the version the application is using.
# It is recommended to use it with quotes.
appVersion: "1.16.0"
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,8 @@
],
"title": "Outbound connections",
"type": "timeseries",
"gridPos": {
"gridPos":
{
"h": 8,
"w": 24,
"x": 0,
Expand Down Expand Up @@ -52,7 +53,8 @@
],
"title": "Inbound connections",
"type": "timeseries",
"gridPos": {
"gridPos":
{
"h": 8,
"w": 24,
"x": 0,
Expand Down Expand Up @@ -80,7 +82,8 @@
],
"title": "Mempool size",
"type": "timeseries",
"gridPos": {
"gridPos":
{
"h": 8,
"w": 24,
"x": 0,
Expand Down Expand Up @@ -108,7 +111,8 @@
],
"title": "Blocks",
"type": "timeseries",
"gridPos": {
"gridPos":
{
"h": 8,
"w": 24,
"x": 0,
Expand Down
1 change: 1 addition & 0 deletions resources/charts/grafana-dashboards/templates/NOTES.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Grafana dashboards deployed
10 changes: 10 additions & 0 deletions resources/charts/grafana-dashboards/templates/configmap.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
apiVersion: v1
kind: ConfigMap
metadata:
name: grafana-dashboards-config
data:
{{- $files := .Files.Glob "files/*.json" }}
{{- range $path, $file := $files }}
{{ base $path }}: |-
{{ $file | toString | indent 4 }}
{{- end }}
19 changes: 19 additions & 0 deletions resources/manifests/grafana_values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,25 @@ datasources:
- name: Loki
type: loki
url: http://loki-gateway.warnet-logging:80
dashboardProviders:
dashboardproviders.yaml:
apiVersion: 1
providers:
- name: 'default'
orgId: 1
folder: ''
type: file
disableDeletion: false
editable: true
options:
path: /var/lib/grafana/dashboards/default
extraVolumeMounts:
- name: grafana-dashboards-volume
mountPath: /var/lib/grafana/dashboards/default
extraVolumes:
- name: grafana-dashboards-volume
configMap:
name: grafana-dashboards-config
grafana.ini:
auth:
disable_login_form: true
Expand Down
17 changes: 0 additions & 17 deletions resources/scripts/connect_logging.sh

This file was deleted.

1 change: 1 addition & 0 deletions src/warnet/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -95,5 +95,6 @@
f"helm upgrade --install --namespace warnet-logging --create-namespace --values {MANIFESTS_DIR}/loki_values.yaml loki grafana/loki --version 5.47.2",
"helm upgrade --install --namespace warnet-logging promtail grafana/promtail",
"helm upgrade --install --namespace warnet-logging prometheus prometheus-community/kube-prometheus-stack --namespace warnet-logging --set grafana.enabled=false",
f"helm upgrade --install grafana-dashboards {CHARTS_DIR}/grafana-dashboards --namespace warnet-logging",
f"helm upgrade --install --namespace warnet-logging loki-grafana grafana/grafana --values {MANIFESTS_DIR}/grafana_values.yaml",
]
33 changes: 5 additions & 28 deletions test/logging_test.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,8 @@
#!/usr/bin/env python3

import logging
import os
import threading
from datetime import datetime
from pathlib import Path
from subprocess import PIPE, Popen

import requests
from test_base import TestBase
Expand All @@ -18,39 +15,15 @@ def __init__(self):
super().__init__()
self.network_dir = Path(os.path.dirname(__file__)) / "data" / "logging"
self.scripts_dir = Path(os.path.dirname(__file__)) / ".." / "resources" / "scripts"
self.connect_logging_process = None
self.connect_logging_thread = None
self.connect_logging_logger = logging.getLogger("cnct_log")

def run_test(self):
try:
self.setup_network()
self.start_logging()
self.wait_for_endpoint_ready()
self.test_prometheus_and_grafana()
finally:
if self.connect_logging_process is not None:
self.log.info("Terminating background connect_logging.sh process...")
self.connect_logging_process.terminate()
self.cleanup()

def start_logging(self):
# Stays alive in background
self.connect_logging_process = Popen(
[f"{self.scripts_dir / 'connect_logging.sh'}"],
stdout=PIPE,
stderr=PIPE,
bufsize=1,
universal_newlines=True,
)
self.log.info("connect_logging.sh started...")
self.connect_logging_thread = threading.Thread(
target=self.output_reader,
args=(self.connect_logging_process.stdout, self.connect_logging_logger.info),
)
self.connect_logging_thread.daemon = True
self.connect_logging_thread.start()
self.wait_for_endpoint_ready()

def setup_network(self):
self.log.info("Setting up network")
self.log.info(self.warnet(f"deploy {self.network_dir}"))
Expand Down Expand Up @@ -118,6 +91,10 @@ def get_five_values_for_metric(metric):
self.wait_for_predicate(lambda: get_five_values_for_metric("blocks"))
self.wait_for_predicate(lambda: get_five_values_for_metric("txrate"))

# Verify default dashboard exists
dbs = requests.get(f"{GRAFANA_URL}api/search").json()
assert dbs[0]["title"] == "Default Warnet Dashboard"


if __name__ == "__main__":
test = LoggingTest()
Expand Down

0 comments on commit 023421e

Please sign in to comment.