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(database monitor): handles multi-region and connection pooling #3685

Merged
merged 31 commits into from
Dec 17, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
f0b411e
feat(database monitor): handles multi-region and connection pooling
iainsproat Dec 12, 2024
264c4f2
Restore changes to unrelated components
iainsproat Dec 12, 2024
c9e5758
Fix for testing
iainsproat Dec 12, 2024
9c959c3
Merge branch 'main' into iain/db-monitor-pooling
iainsproat Dec 12, 2024
4ada3b5
Merge branch 'main' into iain/db-monitor-pooling
iainsproat Dec 13, 2024
3825b8e
refactor prometheus metrics to keep the logic for collecting for a me…
iainsproat Dec 13, 2024
0a41730
Reintroduce zod and znv as they are peer dependencies of Environment …
iainsproat Dec 13, 2024
417ca63
pass in databasename from config, simplify types
iainsproat Dec 13, 2024
64f606e
We don't have any tests, simplify the PR by removing the unused files…
iainsproat Dec 13, 2024
ce9c6f7
Merge branch 'main' into iain/db-monitor-pooling
iainsproat Dec 13, 2024
8bbfde5
fix(server): correct type in notifications helper
iainsproat Dec 13, 2024
ef5921e
ci(publish): update publish job
iainsproat Dec 13, 2024
bb8355d
rename to ensure consistent image name with existing database monitor
iainsproat Dec 13, 2024
b24c23b
Do not gitignore some bin directories
iainsproat Dec 13, 2024
e99316f
Include bin/www.js file
iainsproat Dec 13, 2024
e3c298c
All env vars are configurable via helm chart
iainsproat Dec 13, 2024
439acf1
Allows configuration of database name via env var
iainsproat Dec 13, 2024
3059df4
fix helm chart indentation
iainsproat Dec 13, 2024
3506d2f
Metrics host must be externally exposed
iainsproat Dec 13, 2024
89f924f
Express logging should be debug
iainsproat Dec 13, 2024
e2ad346
Fix issue with NaN in metrics, and allow self-signed CA certs
iainsproat Dec 13, 2024
cc464d8
Provide details about connections
iainsproat Dec 13, 2024
694dd26
Improve error handling and add more logging of edge cases
iainsproat Dec 14, 2024
f26cb64
Merge branch 'main' into iain/db-monitor-pooling
iainsproat Dec 16, 2024
efe2416
Refactor to place metrics in separate files
iainsproat Dec 16, 2024
4261e26
feat(metrics): more metrics related to replications
iainsproat Dec 16, 2024
ad18135
tidying up new metrics
iainsproat Dec 16, 2024
a69175b
Allow database monitor to configure connection timeouts
iainsproat Dec 16, 2024
32ecc36
Use aiven_extras to get replication & subscription, and protect via f…
iainsproat Dec 16, 2024
f647bed
track errors
iainsproat Dec 16, 2024
ccd6e30
Improve error handling where aiven_extras is not yet enabled
iainsproat Dec 16, 2024
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
2 changes: 0 additions & 2 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -1049,7 +1049,6 @@ jobs:
docker-build-monitor-container:
<<: *build-job
environment:
FOLDER: utils
SPECKLE_SERVER_PACKAGE: monitor-deployment

docker-build-docker-compose-ingress:
Expand Down Expand Up @@ -1119,7 +1118,6 @@ jobs:
docker-publish-monitor-container:
<<: *publish-job
environment:
FOLDER: utils
SPECKLE_SERVER_PACKAGE: monitor-deployment

docker-publish-docker-compose-ingress:
Expand Down
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,9 @@ redis-data/
.tshy-build
obj/
bin/

!packages/monitor-deployment/bin
!packages/preview-service/bin
!packages/server/bin

# Server
multiregion.json
Expand Down
2 changes: 1 addition & 1 deletion packages/fileimport-service/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ RUN chmod +x /usr/bin/tini
RUN apt-get update -y \
&& DEBIAN_FRONTEND=noninteractive apt-get install -y \
--no-install-recommends \
curl=8.5.0-2ubuntu10.5 \
curl=8.5.0-2ubuntu10.6 \
&& curl -fsSL https://deb.nodesource.com/setup_18.x | bash - \
&& DEBIAN_FRONTEND=noninteractive apt-get install -y \
--no-install-recommends \
Expand Down
16 changes: 16 additions & 0 deletions packages/monitor-deployment/.env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
PG_CONNECTION_STRING='postgres://speckle:speckle@127.0.0.1/speckle'
POSTGRES_MAX_CONNECTIONS='2'
PROMETHEUS_METRICS_PORT='9092'
LOG_LEVEL='info'
LOG_PRETTY='true'
METRICS_COLLECTION_PERIOD_SECONDS='120'
FF_WORKSPACES_MULTI_REGION_ENABLED='false'

# Enable this if you want to use a custom CA certificate for the connection to the database
# You also have to save it in a file and set NODE_EXTRA_CA_CERTS when running `yarn start` or `yarn dev``
# POSTGRES_CA_CERTIFICATE='-----BEGIN CERTIFICATE-----
# XXXX
# -----END CERTIFICATE-----'

# Used if the database name to be queried is different from the path in the connection string, which is the case for connection pools
# POSTGRES_DATABASE='speckle'
51 changes: 51 additions & 0 deletions packages/monitor-deployment/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
# NOTE: Docker context must be the git root directory, to include the shared directory
ARG NODE_ENV=production

FROM node:18-bookworm-slim@sha256:408f8cbbb7b33a5bb94bdb8862795a94d2b64c2d516856824fd86c4a5594a443 AS build-stage

WORKDIR /speckle-server

# Download tini
ARG TINI_VERSION=v0.19.0
ENV TINI_VERSION=${TINI_VERSION}
ADD https://github.com/krallin/tini/releases/download/${TINI_VERSION}/tini ./tini
RUN chmod +x ./tini

ARG NODE_ENV
ENV NODE_ENV=${NODE_ENV}

WORKDIR /speckle-server

COPY .yarnrc.yml .
COPY .yarn ./.yarn
COPY package.json yarn.lock ./

# Only copy in the relevant package.json files for the dependencies
COPY packages/shared/package.json ./packages/shared/
COPY packages/monitor-deployment/package.json ./packages/monitor-deployment/

RUN yarn workspaces focus -A && yarn install

# Only copy in the relevant source files for the dependencies
COPY packages/shared ./packages/shared/
COPY packages/monitor-deployment ./packages/monitor-deployment/

RUN yarn workspaces foreach -W run build

WORKDIR /speckle-server/packages/monitor-deployment
RUN yarn workspaces focus --production

FROM gcr.io/distroless/nodejs18-debian12:nonroot@sha256:afdea027580f7afcaf1f316b2b3806690c297cb3ce6ddc5cf6a15804dc1c790f AS production-stage

ARG NODE_ENV
ENV NODE_ENV=${NODE_ENV}

WORKDIR /speckle-server
COPY --from=build-stage /speckle-server/tini /usr/bin/tini
COPY --from=build-stage /speckle-server/packages/shared ./packages/shared
COPY --from=build-stage /speckle-server/packages/monitor-deployment ./packages/monitor-deployment
COPY --from=build-stage /speckle-server/node_modules ./node_modules

WORKDIR /speckle-server/packages/monitor-deployment

ENTRYPOINT [ "tini", "--", "/nodejs/bin/node", "--loader=./dist/src/aliasLoader.js", "bin/www.js" ]
23 changes: 23 additions & 0 deletions packages/monitor-deployment/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# Database Monitor

Responsible for querying all databases and generating metrics.

Metrics are available at `/metrics` endpoint and are in Prometheus format.

## Development

```bash
yarn dev
```

## Databases with self-signed certificates

Add the self-signed CA certificate to a file at `packages/monitor-deployment/ca-certificate.crt`

Run `NODE_EXTRA_CA_CERTS=./ca-certificate.crt yarn dev` or `NODE_EXTRA_CA_CERTS=./ca-certificate.crt yarn start`

## Production

```bash
yarn start
```
2 changes: 2 additions & 0 deletions packages/monitor-deployment/bin/www.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
#!/usr/bin/env node
import '../dist/src/bin.js'
61 changes: 61 additions & 0 deletions packages/monitor-deployment/eslint.config.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
import tseslint from 'typescript-eslint'
import {
baseConfigs,
getESMDirname,
globals,
prettierConfig
} from '../../eslint.config.mjs'

const configs = [
...baseConfigs,
{
ignores: ['dist', 'public', 'docs']
},
{
files: ['**/*.js'],
ignores: ['**/*.mjs'],
languageOptions: {
sourceType: 'module',
globals: {
...globals.node
}
}
},
{
files: ['bin/www'],
languageOptions: {
sourceType: 'module',
globals: {
...globals.node
}
}
},
...tseslint.configs.recommendedTypeChecked.map((c) => ({
...c,
files: [...(c.files || []), '**/*.ts', '**/*.d.ts']
})),
{
files: ['**/*.ts', '**/*.d.ts'],
languageOptions: {
parserOptions: {
tsconfigRootDir: getESMDirname(import.meta.url),
project: './tsconfig.json'
}
},
rules: {
'@typescript-eslint/no-explicit-any': 'error',
'@typescript-eslint/no-unsafe-return': 'error'
}
},
{
files: ['**/*.spec.{js,ts}'],
languageOptions: {
globals: {
...globals.node
}
}
},
prettierConfig
]

export default configs
34 changes: 34 additions & 0 deletions packages/monitor-deployment/multiregion.example.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
{
"main": {
"postgres": {
"connectionUri": "postgresql://speckle:speckle@127.0.0.1:5432/speckle",
"privateConnectionUri": "postgresql://speckle:speckle@postgres:5432/speckle",
"databaseName": "speckle"
},
"blobStorage": {
"accessKey": "minioadmin",
"secretKey": "minioadmin",
"bucket": "speckle-server",
"createBucketIfNotExists": true,
"endpoint": "http://127.0.0.1:9000",
"s3Region": "us-east-1"
}
},
"regions": {
"region1": {
"postgres": {
"connectionUri": "postgresql://speckle:speckle@127.0.0.1:5401/speckle",
"privateConnectionUri": "postgresql://speckle:speckle@postgres-region1:5432/speckle",
"databaseName": "speckle"
},
"blobStorage": {
"accessKey": "minioadmin",
"secretKey": "minioadmin",
"bucket": "speckle-server",
"createBucketIfNotExists": true,
"endpoint": "http://127.0.0.1:9020",
"s3Region": "us-east-1"
}
}
}
}
67 changes: 67 additions & 0 deletions packages/monitor-deployment/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
{
"name": "@speckle/monitor-deployment",
"private": true,
"version": "2.5.4",
"description": "Query connected databases and generate metrics.",
"main": "bin/www",
"homepage": "https://speckle.systems",
"repository": {
"type": "git",
"url": "https://github.com/specklesystems/speckle-server.git",
"directory": "packages/monitor-deployment"
},
"type": "module",
"engines": {
"node": "^18.19.0"
},
"scripts": {
"build:tsc:watch": "tsc -p ./tsconfig.build.json --watch",
"run:watch": "NODE_ENV=development LOG_PRETTY=true LOG_LEVEL=debug nodemon --exec \"yarn start\" --trace-deprecation --watch ./bin/www.js --watch ./dist",
"dev": "concurrently \"npm:build:tsc:watch\" \"npm:run:watch\"",
"dev:headed": "yarn dev",
"build:tsc": "rimraf ./dist/src && tsc -p ./tsconfig.build.json",
"build": "yarn build:tsc",
"lint": "yarn lint:tsc && yarn lint:eslint",
"lint:ci": "yarn lint:tsc",
"lint:tsc": "tsc --noEmit",
"lint:eslint": "eslint .",
"start": "node --loader=./dist/src/aliasLoader.js ./bin/www.js",
"test": "NODE_ENV=test LOG_LEVEL=silent LOG_PRETTY=true vitest run --sequence.shuffle"
},
"dependencies": {
"@speckle/shared": "workspace:^",
"crypto": "^1.0.1",
"dotenv": "^16.4.5",
"esm-module-alias": "^2.2.0",
"express": "^4.19.2",
"http-errors": "~1.6.3",
"knex": "^2.4.1",
"lodash": "^4.17.21",
"lodash-es": "^4.17.21",
"pg": "^8.7.3",
"pino": "^8.7.0",
"pino-http": "^8.2.1",
"pino-pretty": "^9.1.1",
"prom-client": "^14.0.1",
"znv": "^0.4.0",
"zod": "^3.24.1"
},
"devDependencies": {
"@types/express": "^4.17.13",
"@types/http-errors": "^2.0.4",
"@types/lodash-es": "^4.17.6",
"@types/node": "^18.19.38",
"@vitest/coverage-istanbul": "^1.6.0",
"concurrently": "^8.2.2",
"crypto-random-string": "^5.0.0",
"eslint": "^9.4.0",
"eslint-config-prettier": "^9.1.0",
"eslint-plugin-vitest": "^0.5.4",
"nodemon": "^2.0.20",
"prettier": "^2.5.1",
"rimraf": "^5.0.7",
"typescript": "^4.6.4",
"typescript-eslint": "^7.12.0",
"vitest": "^1.6.0"
}
}
6 changes: 6 additions & 0 deletions packages/monitor-deployment/src/aliasLoader.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import generateAliasesResolver from 'esm-module-alias'
import { srcRoot } from './root.js'

export const resolve = generateAliasesResolver({
'@': srcRoot
})
9 changes: 9 additions & 0 deletions packages/monitor-deployment/src/bin.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import '@/bootstrap.js' // This has side-effects and has to be imported first

import { startServer } from '@/server/server.js'

const start = () => {
startServer()
}

start()
2 changes: 2 additions & 0 deletions packages/monitor-deployment/src/bootstrap.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
import dotenv from 'dotenv'
dotenv.config()
Loading
Loading