From d9c0e3de95898918c68e0dc7c9853dcb6dc03c9e Mon Sep 17 00:00:00 2001 From: Patricio Latini Date: Thu, 4 Apr 2024 10:49:58 -0300 Subject: [PATCH] Add Grafana container with Prometheus integration and basic dashboard (#293) * Add Grafana container with Prometheus integration and basic dashboard * Add Grafana container with Prometheus integration and basic dashboard - fix after restart --- .env | 3 + 4g-external-ims-deploy.yaml | 17 ++ 4g-volte-deploy.yaml | 17 ++ deploy-all.yaml | 17 ++ grafana/Dockerfile | 39 +++ grafana/grafana_init.sh | 43 ++++ grafana/open5gs_dashboard.json | 452 +++++++++++++++++++++++++++++++++ grafana/open5gs_dashboard.yml | 8 + grafana/prometheus_open5gs.yml | 6 + sa-deploy.yaml | 17 ++ sa-vonr-deploy.yaml | 17 ++ 11 files changed, 636 insertions(+) create mode 100644 grafana/Dockerfile create mode 100755 grafana/grafana_init.sh create mode 100644 grafana/open5gs_dashboard.json create mode 100644 grafana/open5gs_dashboard.yml create mode 100644 grafana/prometheus_open5gs.yml diff --git a/.env b/.env index 5358edc..38d5f28 100644 --- a/.env +++ b/.env @@ -127,6 +127,9 @@ METRICS_IP=172.22.0.36 # SRSRAN GNB SRS_GNB_IP=172.22.0.37 +# GRAFANA +GRAFANA_IP=172.22.0.39 + # UE IPv4 Subnet Range for APN=internet UE_IPV4_INTERNET=192.168.100.0/24 diff --git a/4g-external-ims-deploy.yaml b/4g-external-ims-deploy.yaml index f03a74c..a813186 100644 --- a/4g-external-ims-deploy.yaml +++ b/4g-external-ims-deploy.yaml @@ -319,6 +319,23 @@ services: networks: default: ipv4_address: ${METRICS_IP} + grafana: + build: ./grafana + image: docker_grafana + container_name: grafana + env_file: + - .env + volumes: + - ./grafana:/mnt/grafana + - /etc/timezone:/etc/timezone:ro + - /etc/localtime:/etc/localtime:ro + expose: + - "3000/tcp" + ports: + - "3000:3000/tcp" + networks: + default: + ipv4_address: ${GRAFANA_IP} networks: default: ipam: diff --git a/4g-volte-deploy.yaml b/4g-volte-deploy.yaml index 44bfc89..ba3fb83 100644 --- a/4g-volte-deploy.yaml +++ b/4g-volte-deploy.yaml @@ -455,6 +455,23 @@ services: networks: default: ipv4_address: ${METRICS_IP} + grafana: + build: ./grafana + image: docker_grafana + container_name: grafana + env_file: + - .env + volumes: + - ./grafana:/mnt/grafana + - /etc/timezone:/etc/timezone:ro + - /etc/localtime:/etc/localtime:ro + expose: + - "3000/tcp" + ports: + - "3000:3000/tcp" + networks: + default: + ipv4_address: ${GRAFANA_IP} networks: default: ipam: diff --git a/deploy-all.yaml b/deploy-all.yaml index 25d661b..2d0cf28 100644 --- a/deploy-all.yaml +++ b/deploy-all.yaml @@ -663,6 +663,23 @@ services: networks: default: ipv4_address: ${METRICS_IP} + grafana: + build: ./grafana + image: docker_grafana + container_name: grafana + env_file: + - .env + volumes: + - ./grafana:/mnt/grafana + - /etc/timezone:/etc/timezone:ro + - /etc/localtime:/etc/localtime:ro + expose: + - "3000/tcp" + ports: + - "3000:3000/tcp" + networks: + default: + ipv4_address: ${GRAFANA_IP} networks: default: ipam: diff --git a/grafana/Dockerfile b/grafana/Dockerfile new file mode 100644 index 0000000..c11e105 --- /dev/null +++ b/grafana/Dockerfile @@ -0,0 +1,39 @@ +# BSD 2-Clause License + +# Copyright (c) 2020, Supreeth Herle +# All rights reserved. + +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: + +# 1. Redistributions of source code must retain the above copyright notice, this +# list of conditions and the following disclaimer. + +# 2. Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution. + +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +FROM ubuntu:jammy + +ENV DEBIAN_FRONTEND=noninteractive + +RUN apt-get update && \ + apt-get install -y apt-transport-https software-properties-common wget && \ + mkdir -p /etc/apt/keyrings/ && \ + wget -q -O - https://apt.grafana.com/gpg.key | gpg --dearmor | tee /etc/apt/keyrings/grafana.gpg && \ + echo "deb [signed-by=/etc/apt/keyrings/grafana.gpg] https://apt.grafana.com stable main" | tee -a /etc/apt/sources.list.d/grafana.list && \ + apt-get update && \ + apt-get install -y grafana + +CMD /mnt/grafana/grafana_init.sh diff --git a/grafana/grafana_init.sh b/grafana/grafana_init.sh new file mode 100755 index 0000000..31ddbc3 --- /dev/null +++ b/grafana/grafana_init.sh @@ -0,0 +1,43 @@ +#!/bin/bash + +# BSD 2-Clause License + +# Copyright (c) 2020, Supreeth Herle +# All rights reserved. + +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: + +# 1. Redistributions of source code must retain the above copyright notice, this +# list of conditions and the following disclaimer. + +# 2. Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution. + +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +# Sync docker time +#ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone + +export GRAFANA_WORK_DIR=/usr/share/grafana + +cd $GRAFANA_WORK_DIR + +cp /mnt/grafana/prometheus_open5gs.yml ./conf/provisioning/datasources +cp /mnt/grafana/open5gs_dashboard.yml ./conf/provisioning/dashboards +mkdir -p /var/lib/grafana/dashboards +cp /mnt/grafana/open5gs_dashboard.json /var/lib/grafana/dashboards + +sed -i 's|METRICS_IP|'$METRICS_IP'|g' ./conf/provisioning/datasources/prometheus_open5gs.yml + +./bin/grafana server -homepath $GRAFANA_WORK_DIR diff --git a/grafana/open5gs_dashboard.json b/grafana/open5gs_dashboard.json new file mode 100644 index 0000000..5a78165 --- /dev/null +++ b/grafana/open5gs_dashboard.json @@ -0,0 +1,452 @@ +{ + "annotations": { + "list": [ + { + "builtIn": 1, + "datasource": { + "type": "grafana", + "uid": "-- Grafana --" + }, + "enable": true, + "hide": true, + "iconColor": "rgba(0, 211, 255, 1)", + "name": "Annotations & Alerts", + "type": "dashboard" + } + ] + }, + "editable": true, + "fiscalYearStartMonth": 0, + "graphTooltip": 0, + "links": [], + "panels": [ + { + "datasource": { + "type": "prometheus", + "uid": "PA240B69645956401" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 0, + "y": 0 + }, + "id": 5, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "single", + "sort": "none" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "PA240B69645956401" + }, + "disableTextWrap": false, + "editorMode": "builder", + "expr": "fivegs_ep_n3_gtp_indatapktn3upf", + "fullMetaSearch": false, + "includeNullMetadata": true, + "instant": false, + "legendFormat": "__auto", + "range": true, + "refId": "A", + "useBackend": false + }, + { + "datasource": { + "type": "prometheus", + "uid": "PA240B69645956401" + }, + "disableTextWrap": false, + "editorMode": "builder", + "expr": "fivegs_ep_n3_gtp_outdatapktn3upf", + "fullMetaSearch": false, + "hide": false, + "includeNullMetadata": true, + "instant": false, + "legendFormat": "__auto", + "range": true, + "refId": "B", + "useBackend": false + } + ], + "title": "UPF - GTP Packets", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "PA240B69645956401" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 12, + "y": 0 + }, + "id": 4, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "single", + "sort": "none" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "PA240B69645956401" + }, + "disableTextWrap": false, + "editorMode": "builder", + "expr": "fivegs_upffunction_upf_sessionnbr", + "fullMetaSearch": false, + "includeNullMetadata": true, + "instant": false, + "legendFormat": "__auto", + "range": true, + "refId": "A", + "useBackend": false + } + ], + "title": "UPF - Active Sessions", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "PA240B69645956401" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 0, + "y": 8 + }, + "id": 3, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "single", + "sort": "none" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "PA240B69645956401" + }, + "disableTextWrap": false, + "editorMode": "builder", + "expr": "enb", + "fullMetaSearch": false, + "includeNullMetadata": true, + "instant": false, + "legendFormat": "__auto", + "range": true, + "refId": "A", + "useBackend": false + } + ], + "title": "MME - eNBs", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "PA240B69645956401" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 12, + "y": 8 + }, + "id": 2, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "single", + "sort": "none" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "PA240B69645956401" + }, + "disableTextWrap": false, + "editorMode": "builder", + "expr": "enb_ue", + "fullMetaSearch": false, + "includeNullMetadata": true, + "instant": false, + "legendFormat": "__auto", + "range": true, + "refId": "A", + "useBackend": false + } + ], + "title": "MME - Sessions", + "type": "timeseries" + } + ], + "schemaVersion": 39, + "tags": [], + "templating": { + "list": [] + }, + "time": { + "from": "now-6h", + "to": "now" + }, + "timepicker": {}, + "timezone": "browser", + "title": "Open5Gs", + "uid": "fdg9t0npkjj7ka", + "version": 1, + "weekStart": "" +} diff --git a/grafana/open5gs_dashboard.yml b/grafana/open5gs_dashboard.yml new file mode 100644 index 0000000..1baef47 --- /dev/null +++ b/grafana/open5gs_dashboard.yml @@ -0,0 +1,8 @@ +apiVersion: 1 + +providers: + - name: Open5Gs # A uniquely identifiable name for the provider + folder: Services # The folder where to place the dashboards + type: file + options: + path: /var/lib/grafana/dashboards diff --git a/grafana/prometheus_open5gs.yml b/grafana/prometheus_open5gs.yml new file mode 100644 index 0000000..646369f --- /dev/null +++ b/grafana/prometheus_open5gs.yml @@ -0,0 +1,6 @@ +apiVersion: 1 + +datasources: + - name: Open5Gs + type: prometheus + url: http://METRICS_IP:9090 diff --git a/sa-deploy.yaml b/sa-deploy.yaml index bf000b2..ecef706 100644 --- a/sa-deploy.yaml +++ b/sa-deploy.yaml @@ -304,6 +304,23 @@ services: networks: default: ipv4_address: ${METRICS_IP} + grafana: + build: ./grafana + image: docker_grafana + container_name: grafana + env_file: + - .env + volumes: + - ./grafana:/mnt/grafana + - /etc/timezone:/etc/timezone:ro + - /etc/localtime:/etc/localtime:ro + expose: + - "3000/tcp" + ports: + - "3000:3000/tcp" + networks: + default: + ipv4_address: ${GRAFANA_IP} networks: default: ipam: diff --git a/sa-vonr-deploy.yaml b/sa-vonr-deploy.yaml index 2889040..814880b 100644 --- a/sa-vonr-deploy.yaml +++ b/sa-vonr-deploy.yaml @@ -489,6 +489,23 @@ services: networks: default: ipv4_address: ${SMSC_IP} + grafana: + build: ./grafana + image: docker_grafana + container_name: grafana + env_file: + - .env + volumes: + - ./grafana:/mnt/grafana + - /etc/timezone:/etc/timezone:ro + - /etc/localtime:/etc/localtime:ro + expose: + - "3000/tcp" + ports: + - "3000:3000/tcp" + networks: + default: + ipv4_address: ${GRAFANA_IP} networks: default: ipam: