Skip to content
Draft
Show file tree
Hide file tree
Changes from all 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
4 changes: 4 additions & 0 deletions .env.sample
Original file line number Diff line number Diff line change
Expand Up @@ -32,5 +32,9 @@ NO_GRAPH=true
JWT_SUBSCRIPTION_SECRET_KEY="12345678901234567890123456789012"
NEVERMINED_PROXY_URI=https://proxy.nevermined.one

# For monitoring purposes
# TELEMETRY_URI=http://localhost:4318/v1/traces
# TELEMETRY_SERVICE_NAME=node-localnet

# for testing porposes
SEED_WORDS="taxi music thumb unique chat sand crew more leg another off lamp"
2 changes: 1 addition & 1 deletion .github/workflows/testing-integration.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ jobs:
yarn run lint
- name: Check code formatting
run: yarn format:check
- uses: nevermined-io/nvm-tools-actions@v0.8.0
- uses: nevermined-io/nvm-tools-actions@v0.9.0
with:
token: ${{ secrets.API_TOKEN_GITHUB }}
estuary: 'true'
Expand Down
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,8 @@ The Nevermined Node reads the following environment variables allowing the confi
| **NEVERMINED_PROXY_URI** | The proxy address where the subscription tokens can be used. | `https://proxy.nevermined.network` |
| **SUBSCRIPTION_DEFAULT_EXPIRY_TIME** | The default subscription token expiry time in seconds to be used for unlimited subscriptions. Defaults to 2 years (63072000 seconds) | `63072000` |
| **NETWORK_AVERAGE_BLOCK_TIME** | The average block time in milliseconds for the connected network. Used to calculate the expiry time of the subscriptions token. Defaults 2100 milliseconds | `2100` |
| **TELEMETRY_URI** | Where to send open telemetry data to. | `https://monitoring.nevermiend.io` |
| **TELEMETRY_SERVICE_NAME** | The service name that will be associated with the telemetry data | `node-myapp` |

## Install and run:

Expand Down
5 changes: 5 additions & 0 deletions config/from-env.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,11 +33,16 @@ const keys = [
'COMPUTE_PROVIDER_KEYFILE',
'COMPUTE_PROVIDER_PASSWORD',

// for the subscriptions
'JWT_SUBSCRIPTION_SECRET_KEY',
'NEVERMINED_PROXY_URI',
'SUBSCRIPTION_DEFAULT_EXPIRY_TIME',
'NETWORK_AVERAGE_BLOCK_TIME',

// for monitoring
'TELEMETRY_URI',
'TELEMETRY_SERVICE_NAME',

// for testing
'SEED_WORDS',
]
Expand Down
6 changes: 5 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "node-ts",
"version": "1.1.4",
"version": "1.1.5",
"description": "Nevermined Node",
"main": "main.ts",
"scripts": {
Expand Down Expand Up @@ -37,6 +37,10 @@
"@nevermined-io/passport-nevermined": "^0.1.1",
"@nevermined-io/sdk": "1.3.0",
"@nevermined-io/sdk-dtp": "^0.4.2",
"@opentelemetry/api": "^1.4.1",
"@opentelemetry/auto-instrumentations-node": "^0.36.4",
"@opentelemetry/exporter-trace-otlp-http": "^0.36.1",
"@opentelemetry/sdk-node": "^0.36.1",
"@sideway/address": "^4.1.3",
"@sideway/formula": "^3.0.1",
"@sideway/pinpoint": "^2.0.0",
Expand Down
8 changes: 8 additions & 0 deletions src/main.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
// telemetry should be the first import
import otelSDK from './shared/logger/tracing'

import { ValidationPipe } from '@nestjs/common'
import { NestFactory, Reflector } from '@nestjs/core'
import { NestExpressApplication } from '@nestjs/platform-express'
Expand All @@ -11,6 +14,11 @@ import { ConfigService } from './shared/config/config.service'
import { Logger } from './shared/logger/logger.service'

const bootstrap = async () => {
// initialize telemetry
if (otelSDK) {
otelSDK.start()
}

const logger = new Logger(bootstrap.name)

const app = await NestFactory.create<NestExpressApplication>(ApplicationModule, {
Expand Down
22 changes: 22 additions & 0 deletions src/shared/config/config.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,11 @@ export interface SubscriptionsConfig {
averageBlockTime: number
}

export interface TelemetryConfig {
telemetryUri: string
telemetryServiceName: string
}

const configProfile = require('../../../config')

const DOTENV_SCHEMA = Joi.object({
Expand All @@ -51,6 +56,11 @@ const DOTENV_SCHEMA = Joi.object({
SUBSCRIPTION_DEFAULT_EXPIRY_TIME: Joi.string().default('100 years'),
// Used to calculate expiry time of subscriptions in milliseconds
NETWORK_AVERAGE_BLOCK_TIME: Joi.number().default(2100),

// Monitoring
TELEMETRY_URI: Joi.string(),
TELEMETRY_SERVICE_NAME: Joi.string().default('node'),

server: Joi.object({
port: Joi.number().default(3000),
}),
Expand Down Expand Up @@ -124,12 +134,15 @@ type DotenvSchemaKeys =
| 'NEVERMINED_PROXY_URI'
| 'SUBSCRIPTION_DEFAULT_EXPIRY_TIME'
| 'NETWORK_AVERAGE_BLOCK_TIME'
| 'TELEMETRY_URI'
| 'TELEMETRY_SERVICE_NAME'

export class ConfigService {
private readonly envConfig: EnvConfig
private readonly crypto: CryptoConfig
private readonly compute: ComputeConfig
private readonly subscriptions: SubscriptionsConfig
private readonly telemetry: TelemetryConfig

constructor() {
this.envConfig = this.validateInput(configProfile)
Expand Down Expand Up @@ -161,6 +174,11 @@ export class ConfigService {
defaultExpiryTime: this.get<string>('SUBSCRIPTION_DEFAULT_EXPIRY_TIME'),
averageBlockTime: this.get<number>('NETWORK_AVERAGE_BLOCK_TIME'),
}

this.telemetry = {
telemetryUri: this.get<string>('TELEMETRY_URI'),
telemetryServiceName: this.get<string>('TELEMETRY_SERVICE_NAME'),
}
}

get<T>(path: DotenvSchemaKeys): T | undefined {
Expand All @@ -183,6 +201,10 @@ export class ConfigService {
return this.subscriptions
}

telemetryConfig(): TelemetryConfig {
return this.telemetry
}

getProviderBabyjub() {
return {
x: this.envConfig.PROVIDER_BABYJUB_PUBLIC1 || '',
Expand Down
41 changes: 41 additions & 0 deletions src/shared/logger/tracing.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
//OpenTelemetry
import * as opentelemetry from '@opentelemetry/sdk-node'
import { getNodeAutoInstrumentations } from '@opentelemetry/auto-instrumentations-node'
import { OTLPTraceExporter } from '@opentelemetry/exporter-trace-otlp-http'
import { Resource } from '@opentelemetry/resources'
import { SemanticResourceAttributes } from '@opentelemetry/semantic-conventions'

let otelSDK: opentelemetry.NodeSDK

if (process.env.TELEMETRY_URI) {
console.log(`Starting with telemetry: ${process.env.TELEMETRY_URI}`)

const exporterOptions = {
url: process.env.TELEMETRY_URI,
}
const traceExporter = new OTLPTraceExporter(exporterOptions)
otelSDK = new opentelemetry.NodeSDK({
traceExporter,
instrumentations: [getNodeAutoInstrumentations()],
resource: new Resource({
[SemanticResourceAttributes.SERVICE_NAME]: process.env.TELEMETRY_SERVICE_NAME || 'node',
}),
})
} else {
console.log(
'Starting without telemetry: `TELEMETRY_URI` and `TELEMETRY_SERVICE_NAME` envs are not set',
)
}

export default otelSDK

// Shutting down gracefully
process.on('SIGTERM', () => {
otelSDK
.shutdown()
.then(
() => console.log('otelSDK shut down successfully'),
(err) => console.log('Error shutting down otelSDK', err),
)
.finally(() => process.exit(0))
})
Loading