diff --git a/dappnode_package.json b/dappnode_package.json index bc1b324..8fdae62 100644 --- a/dappnode_package.json +++ b/dappnode_package.json @@ -1,7 +1,7 @@ { "name": "dms.dnp.dappnode.eth", "version": "2.0.0", - "description": "This package privately and locally collects and displays metrics related to your dappnode and its packages. Based on Grafana and Prometheus. It is recommended to also install the package Node-Exporter if you want system metrics. You can find a guide on how to set up your monitoring system in the next link https://forum.dappnode.io/t/begginer-friendly-install-monitoring-system-on-dappnode-using-dms-package/623", + "description": "This package privately and locally collects and displays metrics related to your dappnode and its packages. Based on Grafana and Prometheus. It is recommended to also install the package Node-Exporter if you want system metrics.", "shortDescription": "DAppNode Monitoring Service", "type": "service", "upstream": [ @@ -22,7 +22,7 @@ }, { "repo": "grafana/grafana", - "version": "11.0.0", + "version": "11.1.0", "arg": "UPSTREAM_VERSION_GRAFANA" } ], diff --git a/docker-compose.yml b/docker-compose.yml index a6b67bd..25e0024 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,14 +1,19 @@ -version: "3.4" +version: "3.8" services: grafana: build: context: grafana args: - UPSTREAM_VERSION_GRAFANA: 11.0.0 + UPSTREAM_VERSION_GRAFANA: 11.1.0 image: "grafana.dms.dnp.dappnode.eth:1.0.1" restart: always volumes: - "grafana_data:/var/lib/grafana" + healthcheck: + test: ["CMD", "curl", "-f", "http://localhost/api/health"] + interval: 20s + timeout: 10s + retries: 5 prometheus: build: context: prometheus @@ -28,6 +33,9 @@ services: volumes: - "manager_data:/data" - "prometheus_file_sd:/prometheus_file_sd" + depends_on: + grafana: + condition: service_healthy node-exporter: build: context: node_exporter @@ -38,7 +46,7 @@ services: - "/:/host:ro,rslave" command: - "--path.rootfs=/host" - image: "node-exporter.dappnode-exporter.dnp.dappnode.eth:1.0.3" + image: "node-exporter.dms.dnp.dappnode.eth:1.0.3" cadvisor: build: context: cadvisor @@ -50,13 +58,13 @@ services: - "/var/run:/var/run:rw" - "/sys:/sys:ro" - "/var/lib/docker/:/var/lib/docker:ro" - image: "cadvisor.dappnode-exporter.dnp.dappnode.eth:1.0.3" + image: "cadvisor.dms.dnp.dappnode.eth:1.0.3" stakers-metrics: build: context: stakers-metrics dockerfile: Dockerfile restart: always - image: "stakers-metrics.dappnode-exporter.dnp.dappnode.eth:1.0.3" + image: "stakers-metrics.dms.dnp.dappnode.eth:1.0.3" environment: - DEBUG_MODE=false volumes: diff --git a/grafana/datasource.yml b/grafana/datasource.yml index 5e57969..a08624a 100644 --- a/grafana/datasource.yml +++ b/grafana/datasource.yml @@ -9,11 +9,3 @@ datasources: basicAuth: false isDefault: true editable: true - - name: loki - type: loki - access: proxy - orgId: 1 - url: http://loki:3100 - basicAuth: false - isDefault: false - editable: true diff --git a/manager/src/grafana/grafanaApiClient.ts b/manager/src/grafana/grafanaApiClient.ts index 405e6f3..f551cf7 100644 --- a/manager/src/grafana/grafanaApiClient.ts +++ b/manager/src/grafana/grafanaApiClient.ts @@ -49,20 +49,13 @@ export class GrafanaApiClient { } // GET /api/folders/:uid - /** - * WARNING! On 404 returns HTML, not a proper error code - */ - // async getFolder(uid: string): Promise { - // try { - // return await this.fetch("/api/folders/uid/" + uid, { method: "GET" }); - // } catch (e) { - // if (e.message.includes("not found")) return null; - // else throw e; - // } - // } - async getFolder(uid: string): Promise { - const folders = await this.getAllFolders(); - return folders.find(folder => folder.uid === uid) ?? null; + async getFolder(uid: string): Promise { + try { + return await this.fetch("/api/folders/" + uid, { method: "GET" }); + } catch (e) { + if (e.code === NotFoundErrorCode) return null; + else throw e; + } } // POST /api/folders diff --git a/manager/src/monitoring/index.ts b/manager/src/monitoring/index.ts index eef86fb..415652f 100644 --- a/manager/src/monitoring/index.ts +++ b/manager/src/monitoring/index.ts @@ -102,31 +102,33 @@ export class MonitoringManager { const currentDashboards = dbData?.dashboards || []; const updatedDashboards: DashboardUpdateData[] = []; - await Promise.all( - (manifest.grafanaDashboards || []).map(async (dashboard, index) => { - try { - const prevVersion = - currentDashboards.find(d => d.uid === dashboard.uid)?.version ?? - null; - const updatedDashboard = await this.grafanaClient.importDashboard({ - dashboard, - dnpName, - dnpVersion: version, - index, - prevVersion - }); - updatedDashboards.push(updatedDashboard); - } catch (e) { - if (e instanceof BadDashboardError) { - console.error( - `Ignoring bad dashboard ${dnpName} ${dashboard.uid}: ${e.message}` - ); - } else { - throw e; - } + // Import each dashboard sequentially. We do this to avoid conflicts when importing multiple + // dashboard for the same package. + for (const [index, dashboard] of (manifest.grafanaDashboards || []).entries()) { + try { + // Find previous version of the dashboard if it exists + const prevVersion = currentDashboards.find(d => d.uid === dashboard.uid)?.version ?? null; + + // Call importDashboard sequentially and wait for each to complete before continuing + const updatedDashboard = await this.grafanaClient.importDashboard({ + dashboard, + dnpName, + dnpVersion: version, + index, + prevVersion + }); + + // Add the updated dashboard to the array of updated dashboards + updatedDashboards.push(updatedDashboard); + } catch (e) { + if (e instanceof BadDashboardError) { + console.error(`Ignoring bad dashboard ${dnpName} ${dashboard.uid}: ${e.message}`); + } else { + // Rethrow the error if it's not a BadDashboardError + throw e; } - }) - ); + } + } this.db.set({ dnpName, version, dashboards: updatedDashboards }); } diff --git a/prometheus-targets.json b/prometheus-targets.json new file mode 100644 index 0000000..9d1e8e8 --- /dev/null +++ b/prometheus-targets.json @@ -0,0 +1,20 @@ +[ + { + "labels": { + "job": "nodeexporter" + }, + "targets": ["node-exporter.dms.dappnode:9100"] + }, + { + "labels": { + "job": "cadvisor" + }, + "targets": ["cadvisor.dms.dappnode:8080"] + }, + { + "labels": { + "job": "stakersmetrics" + }, + "targets": ["stakers-metrics.dms.dappnode:9090"] + } + ] \ No newline at end of file diff --git a/stakers-metrics/package.json b/stakers-metrics/package.json index 1fc87d7..baebc29 100644 --- a/stakers-metrics/package.json +++ b/stakers-metrics/package.json @@ -24,7 +24,7 @@ "@typescript-eslint/parser": "5.0.0" }, "dependencies": { - "@dappnode/types": "^0.1.31", + "@dappnode/types": "0.1.31", "@types/node": "^20.2.4", "@types/express": "^4.17.17", "axios": "^1.4.0",