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

feat: add loki functionality to transport logs #1479

Merged
merged 9 commits into from
Aug 26, 2024
Merged
Show file tree
Hide file tree
Changes from 4 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
1 change: 1 addition & 0 deletions .env.local
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,4 @@
# consult the Configuration section in the README.

SAS_SUBSTRATE_URL=ws://127.0.0.1:9944
SAS_METRICS_ENABLED=false
filvecchiato marked this conversation as resolved.
Show resolved Hide resolved
31 changes: 20 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Imod7 marked this conversation as resolved.
Show resolved Hide resolved
filvecchiato marked this conversation as resolved.
Show resolved Hide resolved
- `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
Expand Down Expand Up @@ -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=<YOUR_CUSTOM_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:

Expand Down Expand Up @@ -279,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.
filvecchiato marked this conversation as resolved.
Show resolved Hide resolved

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

Expand Down
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
9 changes: 8 additions & 1 deletion src/SidecarConfig.ts
Original file line number Diff line number Diff line change
@@ -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
Expand Down Expand Up @@ -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;
Expand Down
50 changes: 49 additions & 1 deletion src/Specs.ts
Original file line number Diff line number Diff line change
@@ -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
Expand Down Expand Up @@ -32,6 +32,7 @@ export class Specs {
this.appendLogSpecs();
this.appendSubstrateSpecs();
this.appendExpressSpecs();
this.appendMetricsSpecs();

return this._specs;
}
Expand Down Expand Up @@ -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',
}),
);
}
}
13 changes: 12 additions & 1 deletion src/logging/Log.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@

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';
Expand All @@ -24,7 +25,7 @@ import { consoleTransport, fileTransport } from './transports';
* 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) {
Expand All @@ -40,6 +41,16 @@ 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,
Expand Down
7 changes: 4 additions & 3 deletions src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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,
port: config.METRICS.PROM_PORT,
filvecchiato marked this conversation as resolved.
Show resolved Hide resolved
host: config.METRICS.PROM_HOST,
});

// Generate metrics middleware
Expand Down
13 changes: 2 additions & 11 deletions src/parseArgs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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', {
filvecchiato marked this conversation as resolved.
Show resolved Hide resolved
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;
Expand Down
5 changes: 5 additions & 0 deletions src/types/sidecar-config/CONFIG.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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',
}
1 change: 1 addition & 0 deletions src/types/sidecar-config/MODULES.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,5 @@ export enum MODULES {
EXPRESS = 'EXPRESS',
SUBSTRATE = 'SUBSTRATE',
LOG = 'LOG',
METRICS = 'METRICS',
}
9 changes: 9 additions & 0 deletions src/types/sidecar-config/SidecarConfig.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ export interface ISidecarConfig {
EXPRESS: ISidecarConfigExpress;
SUBSTRATE: ISidecarConfigSubstrate;
LOG: ISidecarConfigLog;
METRICS: ISidecarConfigMetrics;
}

interface ISidecarConfigSubstrate {
Expand All @@ -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;
}
Loading
Loading