From 786482755364082949f39bf60641809cf5c3a0de Mon Sep 17 00:00:00 2001 From: Filippo Vecchiato Date: Mon, 19 Aug 2024 11:01:10 +0200 Subject: [PATCH 1/9] Updates the config from env files to include metrics options --- .env.local | 1 + package.json | 3 +- src/SidecarConfig.ts | 9 +- src/Specs.ts | 50 +++- src/logging/Log.ts | 11 +- src/main.ts | 9 +- src/parseArgs.ts | 13 +- src/types/sidecar-config/CONFIG.ts | 5 + src/types/sidecar-config/MODULES.ts | 1 + src/types/sidecar-config/SidecarConfig.ts | 9 + yarn.lock | 311 +++++++++++++++++++++- 11 files changed, 401 insertions(+), 21 deletions(-) diff --git a/.env.local b/.env.local index 9cc60d328..b79f035a6 100644 --- a/.env.local +++ b/.env.local @@ -4,3 +4,4 @@ # consult the Configuration section in the README. SAS_SUBSTRATE_URL=ws://127.0.0.1:9944 +SAS_METRICS_ENABLED=false \ No newline at end of file diff --git a/package.json b/package.json index 5816aa8c3..a03e18003 100644 --- a/package.json +++ b/package.json @@ -62,7 +62,8 @@ "lru-cache": "^10.4.3", "prom-client": "^15.1.3", "rxjs": "^7.8.1", - "winston": "^3.14.1" + "winston": "^3.14.1", + "winston-loki": "^6.1.2" }, "devDependencies": { "@substrate/dev": "^0.7.1", diff --git a/src/SidecarConfig.ts b/src/SidecarConfig.ts index 5a516d865..c801a7507 100644 --- a/src/SidecarConfig.ts +++ b/src/SidecarConfig.ts @@ -1,4 +1,4 @@ -// Copyright 2017-2022 Parity Technologies (UK) Ltd. +// Copyright 2017-2024 Parity Technologies (UK) Ltd. // This file is part of Substrate API Sidecar. // // Substrate API Sidecar is free software: you can redistribute it and/or modify @@ -72,6 +72,13 @@ export class SidecarConfig { WRITE_MAX_FILE_SIZE: config.Get(MODULES.LOG, CONFIG.WRITE_MAX_FILE_SIZE) as number, WRITE_MAX_FILES: config.Get(MODULES.LOG, CONFIG.WRITE_MAX_FILES) as number, }, + METRICS: { + ENABLED: config.Get(MODULES.METRICS, CONFIG.ENABLED) as boolean, + PROM_HOST: config.Get(MODULES.METRICS, CONFIG.PROM_HOST) as string, + PROM_PORT: config.Get(MODULES.METRICS, CONFIG.PROM_PORT) as number, + LOKI_HOST: config.Get(MODULES.METRICS, CONFIG.LOKI_HOST) as string, + LOKI_PORT: config.Get(MODULES.METRICS, CONFIG.LOKI_PORT) as number, + }, }; return this._config; diff --git a/src/Specs.ts b/src/Specs.ts index 1fad45019..23c65057f 100644 --- a/src/Specs.ts +++ b/src/Specs.ts @@ -1,4 +1,4 @@ -// Copyright 2017-2022 Parity Technologies (UK) Ltd. +// Copyright 2017-2024 Parity Technologies (UK) Ltd. // This file is part of Substrate API Sidecar. // // Substrate API Sidecar is free software: you can redistribute it and/or modify @@ -32,6 +32,7 @@ export class Specs { this.appendLogSpecs(); this.appendSubstrateSpecs(); this.appendExpressSpecs(); + this.appendMetricsSpecs(); return this._specs; } @@ -242,4 +243,51 @@ export class Specs { }), ); } + + private static appendMetricsSpecs() { + if (!this._specs) { + throw APPEND_SPEC_ERROR; + } + + this._specs.appendSpec( + MODULES.METRICS, + this._specs.getSpec(CONFIG.ENABLED, 'Whether or not to enable metrics', { + default: 'false', + type: 'boolean', + regexp: /^true|false$/, + }), + ); + + this._specs.appendSpec( + MODULES.METRICS, + this._specs.getSpec(CONFIG.PROM_HOST, 'Prometheus host', { + default: '127.0.0.1', + type: 'string', + }), + ); + + this._specs.appendSpec( + MODULES.METRICS, + this._specs.getSpec(CONFIG.PROM_PORT, 'Prometheus port', { + default: 9100, + type: 'number', + regexp: /^\d{2,6}$/, + }), + ); + + this._specs.appendSpec( + MODULES.METRICS, + this._specs.getSpec(CONFIG.LOKI_HOST, 'Loki host', { + default: '127.0.0.1', + type: 'string', + }), + ); + this._specs.appendSpec( + MODULES.METRICS, + this._specs.getSpec(CONFIG.LOKI_PORT, 'Loki port', { + default: 3100, + type: 'number', + }), + ); + } } diff --git a/src/logging/Log.ts b/src/logging/Log.ts index d5e684902..502f46c05 100644 --- a/src/logging/Log.ts +++ b/src/logging/Log.ts @@ -19,12 +19,13 @@ import { ConsoleTransportInstance, FileTransportInstance } from 'winston/lib/win import { SidecarConfig } from '../SidecarConfig'; import { consoleTransport, fileTransport } from './transports'; +import LokiTransport from 'winston-loki'; /** * Access a singleton winston.Logger that will be intialized on first use. */ export class Log { - private static _transports: (ConsoleTransportInstance | FileTransportInstance)[] | undefined; + private static _transports: (ConsoleTransportInstance | FileTransportInstance | LokiTransport)[] | undefined; private static _logger: Logger | undefined; private static create(): Logger { if (this._logger) { @@ -40,6 +41,14 @@ export class Log { this._transports.push(fileTransport('logs.log')); } + if (SidecarConfig.config.METRICS.ENABLED) { + this._transports.push(new LokiTransport({ + host: `http://${SidecarConfig.config.METRICS.LOKI_HOST}:${SidecarConfig.config.METRICS.LOKI_PORT}`, + useWinstonMetaAsLabels: true, + json: true, + })) + } + this._logger = createLogger({ transports: this._transports, exitOnError: false, diff --git a/src/main.ts b/src/main.ts index 81a28636d..6c7ac2bc1 100644 --- a/src/main.ts +++ b/src/main.ts @@ -66,11 +66,12 @@ async function main() { startUpPrompt(config.SUBSTRATE.URL, chainName.toString(), implName.toString()); const preMiddlewares = [json(), middleware.httpLoggerCreate(logger)]; - if (args.prometheus) { + + if (config.METRICS.ENABLED) { // Create Metrics App - const metricsApp = new MetricsApp({ - port: 9100, - host: config.EXPRESS.HOST, + const metricsApp = new Metrics_App({ + port: config.METRICS.PROM_PORT, + host: config.METRICS.PROM_HOST, }); // Generate metrics middleware diff --git a/src/parseArgs.ts b/src/parseArgs.ts index bd8718439..91bb6a205 100644 --- a/src/parseArgs.ts +++ b/src/parseArgs.ts @@ -23,18 +23,9 @@ export const parseArgs = (): Namespace => { action: 'store_true', help: 'print substrate-api-sidecar version', }); - parser.add_argument('-p', '--prometheus', { + parser.add_argument('-mq', '--metrics_queryparams', { action: 'store_true', - help: 'enable the prometheus metrics endpoint', - }); - parser.add_argument('-pp', '--prometheus-port', { - type: 'int', - default: 9100, - help: 'specify the port number on which the prometheus metrics are exposed [default: 9100]', - }); - parser.add_argument('-pq', '--prometheus-queryparams', { - action: 'store_true', - help: 'enambles query parameters in the prometheus metrics', + help: 'enables query parameters in the prometheus metrics', }); return parser.parse_args() as Namespace; diff --git a/src/types/sidecar-config/CONFIG.ts b/src/types/sidecar-config/CONFIG.ts index 1777a2838..9cf942c25 100644 --- a/src/types/sidecar-config/CONFIG.ts +++ b/src/types/sidecar-config/CONFIG.ts @@ -34,4 +34,9 @@ export enum CONFIG { WRITE_PATH = 'WRITE_PATH', WRITE_MAX_FILE_SIZE = 'WRITE_MAX_FILE_SIZE', WRITE_MAX_FILES = 'WRITE_MAX_FILES', + ENABLED = 'ENABLED', + LOKI_HOST = 'LOKI_HOST', + PROM_PORT = 'PROM_PORT', + PROM_HOST = 'PROM_HOST', + LOKI_PORT = 'LOKI_PORT', } diff --git a/src/types/sidecar-config/MODULES.ts b/src/types/sidecar-config/MODULES.ts index 5bc91002a..ecd11a4c4 100644 --- a/src/types/sidecar-config/MODULES.ts +++ b/src/types/sidecar-config/MODULES.ts @@ -21,4 +21,5 @@ export enum MODULES { EXPRESS = 'EXPRESS', SUBSTRATE = 'SUBSTRATE', LOG = 'LOG', + METRICS = 'METRICS', } diff --git a/src/types/sidecar-config/SidecarConfig.ts b/src/types/sidecar-config/SidecarConfig.ts index f595fd9f6..179f4c4f6 100644 --- a/src/types/sidecar-config/SidecarConfig.ts +++ b/src/types/sidecar-config/SidecarConfig.ts @@ -21,6 +21,7 @@ export interface ISidecarConfig { EXPRESS: ISidecarConfigExpress; SUBSTRATE: ISidecarConfigSubstrate; LOG: ISidecarConfigLog; + METRICS: ISidecarConfigMetrics; } interface ISidecarConfigSubstrate { @@ -47,3 +48,11 @@ interface ISidecarConfigLog { WRITE_MAX_FILE_SIZE: number; WRITE_MAX_FILES: number; } + +interface ISidecarConfigMetrics { + ENABLED: boolean; + PROM_HOST: string; + PROM_PORT: number; + LOKI_HOST: string; + LOKI_PORT: number; +} diff --git a/yarn.lock b/yarn.lock index 61543357a..93ee05000 100644 --- a/yarn.lock +++ b/yarn.lock @@ -847,6 +847,97 @@ __metadata: languageName: node linkType: hard +"@napi-rs/snappy-android-arm-eabi@npm:7.2.2": + version: 7.2.2 + resolution: "@napi-rs/snappy-android-arm-eabi@npm:7.2.2" + conditions: os=android & cpu=arm + languageName: node + linkType: hard + +"@napi-rs/snappy-android-arm64@npm:7.2.2": + version: 7.2.2 + resolution: "@napi-rs/snappy-android-arm64@npm:7.2.2" + conditions: os=android & cpu=arm64 + languageName: node + linkType: hard + +"@napi-rs/snappy-darwin-arm64@npm:7.2.2": + version: 7.2.2 + resolution: "@napi-rs/snappy-darwin-arm64@npm:7.2.2" + conditions: os=darwin & cpu=arm64 + languageName: node + linkType: hard + +"@napi-rs/snappy-darwin-x64@npm:7.2.2": + version: 7.2.2 + resolution: "@napi-rs/snappy-darwin-x64@npm:7.2.2" + conditions: os=darwin & cpu=x64 + languageName: node + linkType: hard + +"@napi-rs/snappy-freebsd-x64@npm:7.2.2": + version: 7.2.2 + resolution: "@napi-rs/snappy-freebsd-x64@npm:7.2.2" + conditions: os=freebsd & cpu=x64 + languageName: node + linkType: hard + +"@napi-rs/snappy-linux-arm-gnueabihf@npm:7.2.2": + version: 7.2.2 + resolution: "@napi-rs/snappy-linux-arm-gnueabihf@npm:7.2.2" + conditions: os=linux & cpu=arm + languageName: node + linkType: hard + +"@napi-rs/snappy-linux-arm64-gnu@npm:7.2.2": + version: 7.2.2 + resolution: "@napi-rs/snappy-linux-arm64-gnu@npm:7.2.2" + conditions: os=linux & cpu=arm64 + languageName: node + linkType: hard + +"@napi-rs/snappy-linux-arm64-musl@npm:7.2.2": + version: 7.2.2 + resolution: "@napi-rs/snappy-linux-arm64-musl@npm:7.2.2" + conditions: os=linux & cpu=arm64 + languageName: node + linkType: hard + +"@napi-rs/snappy-linux-x64-gnu@npm:7.2.2": + version: 7.2.2 + resolution: "@napi-rs/snappy-linux-x64-gnu@npm:7.2.2" + conditions: os=linux & cpu=x64 + languageName: node + linkType: hard + +"@napi-rs/snappy-linux-x64-musl@npm:7.2.2": + version: 7.2.2 + resolution: "@napi-rs/snappy-linux-x64-musl@npm:7.2.2" + conditions: os=linux & cpu=x64 + languageName: node + linkType: hard + +"@napi-rs/snappy-win32-arm64-msvc@npm:7.2.2": + version: 7.2.2 + resolution: "@napi-rs/snappy-win32-arm64-msvc@npm:7.2.2" + conditions: os=win32 & cpu=arm64 + languageName: node + linkType: hard + +"@napi-rs/snappy-win32-ia32-msvc@npm:7.2.2": + version: 7.2.2 + resolution: "@napi-rs/snappy-win32-ia32-msvc@npm:7.2.2" + conditions: os=win32 & cpu=ia32 + languageName: node + linkType: hard + +"@napi-rs/snappy-win32-x64-msvc@npm:7.2.2": + version: 7.2.2 + resolution: "@napi-rs/snappy-win32-x64-msvc@npm:7.2.2" + conditions: os=win32 & cpu=x64 + languageName: node + linkType: hard + "@noble/curves@npm:^1.3.0": version: 1.3.0 resolution: "@noble/curves@npm:1.3.0" @@ -1418,6 +1509,79 @@ __metadata: languageName: node linkType: hard +"@protobufjs/aspromise@npm:^1.1.1, @protobufjs/aspromise@npm:^1.1.2": + version: 1.1.2 + resolution: "@protobufjs/aspromise@npm:1.1.2" + checksum: 10/8a938d84fe4889411296db66b29287bd61ea3c14c2d23e7a8325f46a2b8ce899857c5f038d65d7641805e6c1d06b495525c7faf00c44f85a7ee6476649034969 + languageName: node + linkType: hard + +"@protobufjs/base64@npm:^1.1.2": + version: 1.1.2 + resolution: "@protobufjs/base64@npm:1.1.2" + checksum: 10/c71b100daeb3c9bdccab5cbc29495b906ba0ae22ceedc200e1ba49717d9c4ab15a6256839cebb6f9c6acae4ed7c25c67e0a95e734f612b258261d1a3098fe342 + languageName: node + linkType: hard + +"@protobufjs/codegen@npm:^2.0.4": + version: 2.0.4 + resolution: "@protobufjs/codegen@npm:2.0.4" + checksum: 10/c6ee5fa172a8464f5253174d3c2353ea520c2573ad7b6476983d9b1346f4d8f2b44aa29feb17a949b83c1816bc35286a5ea265ed9d8fdd2865acfa09668c0447 + languageName: node + linkType: hard + +"@protobufjs/eventemitter@npm:^1.1.0": + version: 1.1.0 + resolution: "@protobufjs/eventemitter@npm:1.1.0" + checksum: 10/03af3e99f17ad421283d054c88a06a30a615922a817741b43ca1b13e7c6b37820a37f6eba9980fb5150c54dba6e26cb6f7b64a6f7d8afa83596fafb3afa218c3 + languageName: node + linkType: hard + +"@protobufjs/fetch@npm:^1.1.0": + version: 1.1.0 + resolution: "@protobufjs/fetch@npm:1.1.0" + dependencies: + "@protobufjs/aspromise": "npm:^1.1.1" + "@protobufjs/inquire": "npm:^1.1.0" + checksum: 10/67ae40572ad536e4ef94269199f252c024b66e3059850906bdaee161ca1d75c73d04d35cd56f147a8a5a079f5808e342b99e61942c1dae15604ff0600b09a958 + languageName: node + linkType: hard + +"@protobufjs/float@npm:^1.0.2": + version: 1.0.2 + resolution: "@protobufjs/float@npm:1.0.2" + checksum: 10/634c2c989da0ef2f4f19373d64187e2a79f598c5fb7991afb689d29a2ea17c14b796b29725945fa34b9493c17fb799e08ac0a7ccaae460ee1757d3083ed35187 + languageName: node + linkType: hard + +"@protobufjs/inquire@npm:^1.1.0": + version: 1.1.0 + resolution: "@protobufjs/inquire@npm:1.1.0" + checksum: 10/c09efa34a5465cb120775e1a482136f2340a58b4abce7e93d72b8b5a9324a0e879275016ef9fcd73d72a4731639c54f2bb755bb82f916e4a78892d1d840bb3d2 + languageName: node + linkType: hard + +"@protobufjs/path@npm:^1.1.2": + version: 1.1.2 + resolution: "@protobufjs/path@npm:1.1.2" + checksum: 10/bb709567935fd385a86ad1f575aea98131bbd719c743fb9b6edd6b47ede429ff71a801cecbd64fc72deebf4e08b8f1bd8062793178cdaed3713b8d15771f9b83 + languageName: node + linkType: hard + +"@protobufjs/pool@npm:^1.1.0": + version: 1.1.0 + resolution: "@protobufjs/pool@npm:1.1.0" + checksum: 10/b9c7047647f6af28e92aac54f6f7c1f7ff31b201b4bfcc7a415b2861528854fce3ec666d7e7e10fd744da905f7d4aef2205bbcc8944ca0ca7a82e18134d00c46 + languageName: node + linkType: hard + +"@protobufjs/utf8@npm:^1.1.0": + version: 1.1.0 + resolution: "@protobufjs/utf8@npm:1.1.0" + checksum: 10/131e289c57534c1d73a0e55782d6751dd821db1583cb2f7f7e017c9d6747addaebe79f28120b2e0185395d990aad347fb14ffa73ef4096fa38508d61a0e64602 + languageName: node + linkType: hard + "@scure/base@npm:^1.1.1, @scure/base@npm:^1.1.5": version: 1.1.5 resolution: "@scure/base@npm:1.1.5" @@ -1476,6 +1640,7 @@ __metadata: rxjs: "npm:^7.8.1" ts-node-dev: "npm:^2.0.0" winston: "npm:^3.14.1" + winston-loki: "npm:^6.1.2" bin: substrate-api-sidecar: ./build/src/main.js languageName: unknown @@ -1799,6 +1964,15 @@ __metadata: languageName: node linkType: hard +"@types/node@npm:>=13.7.0": + version: 22.3.0 + resolution: "@types/node@npm:22.3.0" + dependencies: + undici-types: "npm:~6.18.2" + checksum: 10/c31a798ed722a7417727f018ea6d621db038a613c626da643174cc6f3dcf4ce2fc9933a010aec289103d9564da2c2f9b054c9aa398828f00e17269a78c64d4ec + languageName: node + linkType: hard + "@types/qs@npm:*": version: 6.9.7 resolution: "@types/qs@npm:6.9.7" @@ -2215,6 +2389,13 @@ __metadata: languageName: node linkType: hard +"async-exit-hook@npm:2.0.1": + version: 2.0.1 + resolution: "async-exit-hook@npm:2.0.1" + checksum: 10/fffabbe5ef194ec8283efed48eaf8f4b7982d547de6d4cf7aadf83c8690f0f7929ad01b7cb5de99935ea8f3deb2c21fd009892d8215a43b5a2dcc55c04d42c9f + languageName: node + linkType: hard + "async@npm:^3.2.3": version: 3.2.4 resolution: "async@npm:3.2.4" @@ -2422,6 +2603,15 @@ __metadata: languageName: node linkType: hard +"btoa@npm:^1.2.1": + version: 1.2.1 + resolution: "btoa@npm:1.2.1" + bin: + btoa: bin/btoa.js + checksum: 10/29f2ca93837e10427184626bdfd5d00065dff28b604b822aa9849297dac8c8d6ad385cc96eed812ebf153d80c24a4556252afdbb97c7a712938baeaad7547705 + languageName: node + linkType: hard + "buffer-from@npm:^1.0.0": version: 1.1.2 resolution: "buffer-from@npm:1.1.2" @@ -4747,7 +4937,7 @@ __metadata: languageName: node linkType: hard -"logform@npm:^2.3.2, logform@npm:^2.6.0": +"logform@npm:^2.3.2, logform@npm:^2.6.0, logform@npm:^2.6.1": version: 2.6.1 resolution: "logform@npm:2.6.1" dependencies: @@ -4761,6 +4951,13 @@ __metadata: languageName: node linkType: hard +"long@npm:^5.0.0": + version: 5.2.3 + resolution: "long@npm:5.2.3" + checksum: 10/9167ec6947a825b827c30da169a7384eec6c0c9ec2f0b9c74da2e93d81159bbe39fb09c3f13dae9721d4b807ccfa09797a7dd1012f5d478e3e33ca3c78b608e6 + languageName: node + linkType: hard + "lru-cache@npm:*, lru-cache@npm:^10.4.3, lru-cache@npm:^9.1.1 || ^10.0.0": version: 10.4.3 resolution: "lru-cache@npm:10.4.3" @@ -5517,6 +5714,26 @@ __metadata: languageName: node linkType: hard +"protobufjs@npm:^7.2.4": + version: 7.3.2 + resolution: "protobufjs@npm:7.3.2" + dependencies: + "@protobufjs/aspromise": "npm:^1.1.2" + "@protobufjs/base64": "npm:^1.1.2" + "@protobufjs/codegen": "npm:^2.0.4" + "@protobufjs/eventemitter": "npm:^1.1.0" + "@protobufjs/fetch": "npm:^1.1.0" + "@protobufjs/float": "npm:^1.0.2" + "@protobufjs/inquire": "npm:^1.1.0" + "@protobufjs/path": "npm:^1.1.2" + "@protobufjs/pool": "npm:^1.1.0" + "@protobufjs/utf8": "npm:^1.1.0" + "@types/node": "npm:>=13.7.0" + long: "npm:^5.0.0" + checksum: 10/816604aa0649a93fd5d3ef2858ef038f482d18eebcfb4201fe85c0d3bcccc12410f9e3e73262f1219e6b5bed4f27b28c3bf7c931c409dfb1fd563a304d541d89 + languageName: node + linkType: hard + "proxy-addr@npm:~2.0.7": version: 2.0.7 resolution: "proxy-addr@npm:2.0.7" @@ -5583,7 +5800,7 @@ __metadata: languageName: node linkType: hard -"readable-stream@npm:^3.4.0, readable-stream@npm:^3.6.0": +"readable-stream@npm:^3.4.0, readable-stream@npm:^3.6.0, readable-stream@npm:^3.6.2": version: 3.6.2 resolution: "readable-stream@npm:3.6.2" dependencies: @@ -5922,6 +6139,54 @@ __metadata: languageName: node linkType: hard +"snappy@npm:^7.2.2": + version: 7.2.2 + resolution: "snappy@npm:7.2.2" + dependencies: + "@napi-rs/snappy-android-arm-eabi": "npm:7.2.2" + "@napi-rs/snappy-android-arm64": "npm:7.2.2" + "@napi-rs/snappy-darwin-arm64": "npm:7.2.2" + "@napi-rs/snappy-darwin-x64": "npm:7.2.2" + "@napi-rs/snappy-freebsd-x64": "npm:7.2.2" + "@napi-rs/snappy-linux-arm-gnueabihf": "npm:7.2.2" + "@napi-rs/snappy-linux-arm64-gnu": "npm:7.2.2" + "@napi-rs/snappy-linux-arm64-musl": "npm:7.2.2" + "@napi-rs/snappy-linux-x64-gnu": "npm:7.2.2" + "@napi-rs/snappy-linux-x64-musl": "npm:7.2.2" + "@napi-rs/snappy-win32-arm64-msvc": "npm:7.2.2" + "@napi-rs/snappy-win32-ia32-msvc": "npm:7.2.2" + "@napi-rs/snappy-win32-x64-msvc": "npm:7.2.2" + dependenciesMeta: + "@napi-rs/snappy-android-arm-eabi": + optional: true + "@napi-rs/snappy-android-arm64": + optional: true + "@napi-rs/snappy-darwin-arm64": + optional: true + "@napi-rs/snappy-darwin-x64": + optional: true + "@napi-rs/snappy-freebsd-x64": + optional: true + "@napi-rs/snappy-linux-arm-gnueabihf": + optional: true + "@napi-rs/snappy-linux-arm64-gnu": + optional: true + "@napi-rs/snappy-linux-arm64-musl": + optional: true + "@napi-rs/snappy-linux-x64-gnu": + optional: true + "@napi-rs/snappy-linux-x64-musl": + optional: true + "@napi-rs/snappy-win32-arm64-msvc": + optional: true + "@napi-rs/snappy-win32-ia32-msvc": + optional: true + "@napi-rs/snappy-win32-x64-msvc": + optional: true + checksum: 10/cc6ee627d32325c3b3a7220f57bf7f87906372431072b77dfacf5d875a21c54043df8d6f328eadf8d58bda3d9bb558b3f00e1daaa757441cfa1ec20004f715f1 + languageName: node + linkType: hard + "socks-proxy-agent@npm:^7.0.0": version: 7.0.0 resolution: "socks-proxy-agent@npm:7.0.0" @@ -6441,6 +6706,13 @@ __metadata: languageName: node linkType: hard +"undici-types@npm:~6.18.2": + version: 6.18.2 + resolution: "undici-types@npm:6.18.2" + checksum: 10/5c863f3cc65d012498cf0f8562b9d81e785c2b8b8a8d66343b9f4351ff40a3a29b500fbaea10667626fd91a32433d4c876810aafa5ab561369de702b62d4b323 + languageName: node + linkType: hard + "unique-filename@npm:^3.0.0": version: 3.0.0 resolution: "unique-filename@npm:3.0.0" @@ -6496,6 +6768,13 @@ __metadata: languageName: node linkType: hard +"url-polyfill@npm:^1.1.12": + version: 1.1.12 + resolution: "url-polyfill@npm:1.1.12" + checksum: 10/27b50354e0852228a6396a18ad6231d31b34b82b7b10d71bd48057d156178a581554c05fd6c9cf32931c1f826c67efb6b1c3881a410ef61609f502787b007416 + languageName: node + linkType: hard + "util-deprecate@npm:^1.0.1": version: 1.0.2 resolution: "util-deprecate@npm:1.0.2" @@ -6571,6 +6850,34 @@ __metadata: languageName: node linkType: hard +"winston-loki@npm:^6.1.2": + version: 6.1.2 + resolution: "winston-loki@npm:6.1.2" + dependencies: + async-exit-hook: "npm:2.0.1" + btoa: "npm:^1.2.1" + protobufjs: "npm:^7.2.4" + snappy: "npm:^7.2.2" + url-polyfill: "npm:^1.1.12" + winston-transport: "npm:^4.3.0" + dependenciesMeta: + snappy: + optional: true + checksum: 10/faad904f3a4c8e1e8de0614fdea5d435bb4ad9934d5dc28ce7f1577b5721cb3b72860f4755ce5d5f5ab3284915043bdf1802c12be9b92b51124b0ea4eeae6ea6 + languageName: node + linkType: hard + +"winston-transport@npm:^4.3.0": + version: 4.7.1 + resolution: "winston-transport@npm:4.7.1" + dependencies: + logform: "npm:^2.6.1" + readable-stream: "npm:^3.6.2" + triple-beam: "npm:^1.3.0" + checksum: 10/bc48c921ec9b4a71c1445bf274aa6b00c01089a6c26fc0b19534f8a32fa2710c6766c9e6db53a23492c20772934025d312dd9fb08df157ccb6579ad6b9dae9a7 + languageName: node + linkType: hard + "winston-transport@npm:^4.7.0": version: 4.7.0 resolution: "winston-transport@npm:4.7.0" From ac32529af144136d41ba7630bcf18cdd10f395d7 Mon Sep 17 00:00:00 2001 From: Filippo Vecchiato Date: Mon, 19 Aug 2024 11:07:48 +0200 Subject: [PATCH 2/9] updates README --- README.md | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index 334b0b0d4..7a125f801 100644 --- a/README.md +++ b/README.md @@ -170,6 +170,14 @@ For more information on our configuration manager visit its readme [here](https: - `SAS_SUBSTRATE_URL`: URL to which the RPC proxy will attempt to connect to, defaults to `ws://127.0.0.1:9944`. Accepts both a websocket, and http URL. +### Metrics Server + +- `SAS_METRICS_ENABLED`: Boolean to enable the metrics server instance with prometheus (server metrics) and loki (logging) connections. +- `SAS_METRICS_PROM_HOST`: The host of the prometheus server used to listen to metrics emitted, defaults to `127.0.0.1`. +- `SAS_METRICS_PROM_PORT`: The port of the prometheus server, defaults to `9100`. +- `SAS_METRICS_LOKI_HOST`: The host of the loki server used to pull the logs, defaults to `127.0.0.1`. +- `SAS_METRICS_LOKI_PORT`: The port of the loki server, defaults to `3100` + #### Custom substrate types Some chains require custom type definitions in order for Sidecar to know how to decode the data @@ -239,17 +247,8 @@ file you can `symlink` it with `.env.test`. For example you could run commands `ln` and `unlink` for more info.) ### Prometheus server -Prometheus metrics can be enabled by running sidecar with the following flag : - -```bash -yarn start --prometheus -``` - -You can also define a custom port by running : -```bash -yarn start --prometheus --prometheus-port= -``` +Prometheus metrics can be enabled by running sidecar with the following env configuration : `SAS_METRICS_ENABLED`=true You can also expand the metrics tracking capabilities to include query params by running: From 971dbeacfebea765dc152f9dd2615a672dd229e0 Mon Sep 17 00:00:00 2001 From: Filippo Vecchiato Date: Mon, 19 Aug 2024 14:10:45 +0200 Subject: [PATCH 3/9] update loki transport --- src/logging/Log.ts | 14 ++++++++------ src/main.ts | 2 +- 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/src/logging/Log.ts b/src/logging/Log.ts index 502f46c05..a3512960a 100644 --- a/src/logging/Log.ts +++ b/src/logging/Log.ts @@ -16,10 +16,10 @@ import { createLogger, Logger } from 'winston'; import { ConsoleTransportInstance, FileTransportInstance } from 'winston/lib/winston/transports'; +import LokiTransport from 'winston-loki'; import { SidecarConfig } from '../SidecarConfig'; import { consoleTransport, fileTransport } from './transports'; -import LokiTransport from 'winston-loki'; /** * Access a singleton winston.Logger that will be intialized on first use. @@ -42,11 +42,13 @@ export class Log { } if (SidecarConfig.config.METRICS.ENABLED) { - this._transports.push(new LokiTransport({ - host: `http://${SidecarConfig.config.METRICS.LOKI_HOST}:${SidecarConfig.config.METRICS.LOKI_PORT}`, - useWinstonMetaAsLabels: true, - json: true, - })) + this._transports.push( + new LokiTransport({ + host: `http://${SidecarConfig.config.METRICS.LOKI_HOST}:${SidecarConfig.config.METRICS.LOKI_PORT}`, + useWinstonMetaAsLabels: true, + json: true, + }), + ); } this._logger = createLogger({ diff --git a/src/main.ts b/src/main.ts index 6c7ac2bc1..ffcf7baa8 100644 --- a/src/main.ts +++ b/src/main.ts @@ -69,7 +69,7 @@ async function main() { if (config.METRICS.ENABLED) { // Create Metrics App - const metricsApp = new Metrics_App({ + const metricsApp = new MetricsApp({ port: config.METRICS.PROM_PORT, host: config.METRICS.PROM_HOST, }); From 8170d225911fa7cda6b4c1f0ba151f200be79b2c Mon Sep 17 00:00:00 2001 From: Filippo Vecchiato Date: Mon, 19 Aug 2024 16:42:06 +0200 Subject: [PATCH 4/9] update readme --- README.md | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 7a125f801..9ba8e3f5e 100644 --- a/README.md +++ b/README.md @@ -248,7 +248,7 @@ commands `ln` and `unlink` for more info.) ### Prometheus server -Prometheus metrics can be enabled by running sidecar with the following env configuration : `SAS_METRICS_ENABLED`=true +Prometheus metrics can be enabled by running sidecar with the following env configuration: `SAS_METRICS_ENABLED`=true You can also expand the metrics tracking capabilities to include query params by running: @@ -278,7 +278,17 @@ The blocks controller also includes the following route-specific metrics: - `sas_extrinsics_per_block`: type histogram and tracks the returned extrinsics per block - `sas_seconds_per_block`: type histogram and tracks the request time per block -The metrics registry is injected in the Response object when the `-prometheus` flag is selected, allowing to extend the controller based metrics to any given controller from within the controller functions. +The metrics registry is injected in the Response object when the `ENABLED` flag is true in .env, allowing to extend the controller based metrics to any given controller from within the controller functions. + +To successfully run and access the metrics and logs in Grafana (for example) the following are required: + +- prometheus server (info [here](https://prometheus.io/docs/prometheus/latest/getting_started/)) +- loki server and promtail (info [here](https://grafana.com/docs/loki/latest/setup/install/)) + +For mac users using homebrew: +```bash +brew install prometheus loki promtail +``` ## Debugging fee and staking payout calculations From d554d0f65a6804aa188bb7784a1796f7e0065674 Mon Sep 17 00:00:00 2001 From: Filippo Vecchiato Date: Tue, 20 Aug 2024 11:33:30 +0200 Subject: [PATCH 5/9] fix port number on metrics app --- src/metrics/Metrics.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/metrics/Metrics.ts b/src/metrics/Metrics.ts index 487bef264..e34ad8626 100644 --- a/src/metrics/Metrics.ts +++ b/src/metrics/Metrics.ts @@ -35,11 +35,11 @@ export default class Metrics_App { /** * @param appConfig configuration for app. */ - constructor({ host }: IAppConfiguration) { + constructor({ host, port }: IAppConfiguration) { const args = parseArgs(); this.includeQueryParams = !!args.prometheus_queryparams; - this.port = Number(args.prometheus_port); + this.port = port; this.app = express(); this.host = host; this.registry = new client.Registry(); From 5d8416c1c97d3d99bfe7e15a1b3a795faf3fcab6 Mon Sep 17 00:00:00 2001 From: Filippo Vecchiato Date: Tue, 20 Aug 2024 11:59:31 +0200 Subject: [PATCH 6/9] update query params metrics --- README.md | 6 +----- src/SidecarConfig.ts | 1 + src/Specs.ts | 9 +++++++++ src/metrics/Metrics.ts | 6 ++---- src/parseArgs.ts | 4 ---- src/types/sidecar-config/CONFIG.ts | 1 + src/types/sidecar-config/SidecarConfig.ts | 1 + 7 files changed, 15 insertions(+), 13 deletions(-) diff --git a/README.md b/README.md index 9ba8e3f5e..6ad96bdeb 100644 --- a/README.md +++ b/README.md @@ -250,11 +250,7 @@ commands `ln` and `unlink` for more info.) Prometheus metrics can be enabled by running sidecar with the following env configuration: `SAS_METRICS_ENABLED`=true -You can also expand the metrics tracking capabilities to include query params by running: - -```bash -yarn start --prometheus --prometheus-queryparams -``` +You can also expand the metrics tracking capabilities to include query params by adding to the env configuration: `INCLUDE_QUERYPARAMS`=true The metrics endpoint can then be accessed : - on the default port : `http://127.0.0.1:9100/metrics` or diff --git a/src/SidecarConfig.ts b/src/SidecarConfig.ts index c801a7507..2de419e83 100644 --- a/src/SidecarConfig.ts +++ b/src/SidecarConfig.ts @@ -78,6 +78,7 @@ export class SidecarConfig { PROM_PORT: config.Get(MODULES.METRICS, CONFIG.PROM_PORT) as number, LOKI_HOST: config.Get(MODULES.METRICS, CONFIG.LOKI_HOST) as string, LOKI_PORT: config.Get(MODULES.METRICS, CONFIG.LOKI_PORT) as number, + INCLUDE_QUERYPARAMS: config.Get(MODULES.METRICS, CONFIG.INCLUDE_QUERYPARAMS) as boolean, }, }; diff --git a/src/Specs.ts b/src/Specs.ts index 23c65057f..a8817e1d1 100644 --- a/src/Specs.ts +++ b/src/Specs.ts @@ -289,5 +289,14 @@ export class Specs { type: 'number', }), ); + + this._specs.appendSpec( + MODULES.METRICS, + this._specs.getSpec(CONFIG.INCLUDE_QUERYPARAMS, 'Include query params in the labels of the metrics', { + default: 'false', + type: 'boolean', + regexp: /^true|false$/, + }), + ); } } diff --git a/src/metrics/Metrics.ts b/src/metrics/Metrics.ts index e34ad8626..6ed76dc36 100644 --- a/src/metrics/Metrics.ts +++ b/src/metrics/Metrics.ts @@ -1,9 +1,9 @@ import express from 'express'; import { Application, Request, Response } from 'express'; import client from 'prom-client'; +import { SidecarConfig } from 'src/SidecarConfig'; import { Log } from '../logging/Log'; -import { parseArgs } from '../parseArgs'; import { IMetric, MetricType } from '../types/metrics'; import { config } from '.'; @@ -36,9 +36,7 @@ export default class Metrics_App { * @param appConfig configuration for app. */ constructor({ host, port }: IAppConfiguration) { - const args = parseArgs(); - - this.includeQueryParams = !!args.prometheus_queryparams; + this.includeQueryParams = SidecarConfig.config.METRICS.INCLUDE_QUERYPARAMS; this.port = port; this.app = express(); this.host = host; diff --git a/src/parseArgs.ts b/src/parseArgs.ts index 91bb6a205..6fb38daa6 100644 --- a/src/parseArgs.ts +++ b/src/parseArgs.ts @@ -23,10 +23,6 @@ export const parseArgs = (): Namespace => { action: 'store_true', help: 'print substrate-api-sidecar version', }); - parser.add_argument('-mq', '--metrics_queryparams', { - action: 'store_true', - help: 'enables query parameters in the prometheus metrics', - }); return parser.parse_args() as Namespace; }; diff --git a/src/types/sidecar-config/CONFIG.ts b/src/types/sidecar-config/CONFIG.ts index 9cf942c25..6b38e677a 100644 --- a/src/types/sidecar-config/CONFIG.ts +++ b/src/types/sidecar-config/CONFIG.ts @@ -39,4 +39,5 @@ export enum CONFIG { PROM_PORT = 'PROM_PORT', PROM_HOST = 'PROM_HOST', LOKI_PORT = 'LOKI_PORT', + INCLUDE_QUERYPARAMS = 'INCLUDE_QUERYPARAMS', } diff --git a/src/types/sidecar-config/SidecarConfig.ts b/src/types/sidecar-config/SidecarConfig.ts index 179f4c4f6..9601ce24a 100644 --- a/src/types/sidecar-config/SidecarConfig.ts +++ b/src/types/sidecar-config/SidecarConfig.ts @@ -55,4 +55,5 @@ interface ISidecarConfigMetrics { PROM_PORT: number; LOKI_HOST: string; LOKI_PORT: number; + INCLUDE_QUERYPARAMS: boolean; } From 3e4dcf95671fb06bbbb3d47cf1fc17843b5a9783 Mon Sep 17 00:00:00 2001 From: Filippo Vecchiato Date: Tue, 20 Aug 2024 12:00:57 +0200 Subject: [PATCH 7/9] fix import sidecarConfig --- src/metrics/Metrics.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/metrics/Metrics.ts b/src/metrics/Metrics.ts index 6ed76dc36..8dcb533b3 100644 --- a/src/metrics/Metrics.ts +++ b/src/metrics/Metrics.ts @@ -1,9 +1,9 @@ import express from 'express'; import { Application, Request, Response } from 'express'; import client from 'prom-client'; -import { SidecarConfig } from 'src/SidecarConfig'; import { Log } from '../logging/Log'; +import { SidecarConfig } from '../SidecarConfig'; import { IMetric, MetricType } from '../types/metrics'; import { config } from '.'; From 58c111428243e15b13ba47c480290d741c783881 Mon Sep 17 00:00:00 2001 From: Filippo Vecchiato Date: Wed, 21 Aug 2024 09:33:41 +0200 Subject: [PATCH 8/9] fix readme --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 6ad96bdeb..42542c377 100644 --- a/README.md +++ b/README.md @@ -250,7 +250,7 @@ commands `ln` and `unlink` for more info.) Prometheus metrics can be enabled by running sidecar with the following env configuration: `SAS_METRICS_ENABLED`=true -You can also expand the metrics tracking capabilities to include query params by adding to the env configuration: `INCLUDE_QUERYPARAMS`=true +You can also expand the metrics tracking capabilities to include query params by adding to the env configuration: `SAS_METRICS_INCLUDE_QUERYPARAMS`=true The metrics endpoint can then be accessed : - on the default port : `http://127.0.0.1:9100/metrics` or From 076eb7536024b16fe02fa2a7c604d7ee61b8627f Mon Sep 17 00:00:00 2001 From: Filippo Vecchiato Date: Wed, 21 Aug 2024 09:36:23 +0200 Subject: [PATCH 9/9] fix .env and readme --- .env.local | 3 +-- README.md | 4 ++-- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/.env.local b/.env.local index b79f035a6..980cb5787 100644 --- a/.env.local +++ b/.env.local @@ -3,5 +3,4 @@ # For more information on how to use .env files and environment variables # consult the Configuration section in the README. -SAS_SUBSTRATE_URL=ws://127.0.0.1:9944 -SAS_METRICS_ENABLED=false \ No newline at end of file +SAS_SUBSTRATE_URL=ws://127.0.0.1:9944 \ No newline at end of file diff --git a/README.md b/README.md index 42542c377..1491405a4 100644 --- a/README.md +++ b/README.md @@ -172,7 +172,7 @@ For more information on our configuration manager visit its readme [here](https: ### Metrics Server -- `SAS_METRICS_ENABLED`: Boolean to enable the metrics server instance with prometheus (server metrics) and loki (logging) connections. +- `SAS_METRICS_ENABLED`: Boolean to enable the metrics server instance with Prometheus (server metrics) and Loki (logging) connections. Defaults to false. - `SAS_METRICS_PROM_HOST`: The host of the prometheus server used to listen to metrics emitted, defaults to `127.0.0.1`. - `SAS_METRICS_PROM_PORT`: The port of the prometheus server, defaults to `9100`. - `SAS_METRICS_LOKI_HOST`: The host of the loki server used to pull the logs, defaults to `127.0.0.1`. @@ -274,7 +274,7 @@ The blocks controller also includes the following route-specific metrics: - `sas_extrinsics_per_block`: type histogram and tracks the returned extrinsics per block - `sas_seconds_per_block`: type histogram and tracks the request time per block -The metrics registry is injected in the Response object when the `ENABLED` flag is true in .env, allowing to extend the controller based metrics to any given controller from within the controller functions. +The metrics registry is injected in the Response object when the `SAS_METRICS_ENABLED` flag is set to `true` in the `.env` file, allowing to extend the controller based metrics to any given controller from within the controller functions. To successfully run and access the metrics and logs in Grafana (for example) the following are required: