Node.js - pg
You will need your project token for initializing your library. You can get your project token from Projects Page
Run the following command to install the SDK and pg if it is not installed:
npm install --save pg @metis-data/pg-interceptor
If it is the first time you set up opentelemetry, some more opentelemetry packages are required:
npm install --save @opentelemetry/api \
@opentelemetry/context-async-hooks \
@opentelemetry/instrumentation \
@opentelemetry/instrumentation-http \
@opentelemetry/resources \
@opentelemetry/sdk-trace-base \
@opentelemetry/semantic-conventions
In opentelemetry, tracing should be set before application bootstrap.
- 1.Create
tracer
file and add the following code:
TypeScript
JavaScript
1
// tracer.ts
2
import opentelemetry from '@opentelemetry/api';
3
import { registerInstrumentations } from '@opentelemetry/instrumentation';
4
import {
5
BasicTracerProvider,
6
BatchSpanProcessor,
7
ConsoleSpanExporter,
8
SimpleSpanProcessor,
9
} from '@opentelemetry/sdk-trace-base';
10
import {
11
getMetisExporter,
12
MetisHttpInstrumentation,
13
MetisPgInstrumentation,
14
getResource,
15
} from '@metis-data/pg-interceptor';
16
import { AsyncHooksContextManager } from '@opentelemetry/context-async-hooks';
17
18
let tracerProvider: BasicTracerProvider;
19
const connectionString = process.env.PG_CONNECTION_STRING;
20
21
export const startMetisInstrumentation = () => {
22
tracerProvider = new BasicTracerProvider({
23
resource: getResource(process.env.METIS_SERVICE_NAME, 'service-version'),
24
});
25
26
const metisExporter = getMetisExporter(process.env.METIS_API_KEY);
27
28
tracerProvider.addSpanProcessor(
29
new BatchSpanProcessor(metisExporter)
30
);
31
32
if (process.env.OTEL_DEBUG) {
33
tracerProvider.addSpanProcessor(
34
new SimpleSpanProcessor(new ConsoleSpanExporter())
35
);
36
}
37
38
const contextManager = new AsyncHooksContextManager();
39
40
contextManager.enable();
41
opentelemetry.context.setGlobalContextManager(contextManager);
42
43
tracerProvider.register();
44
45
// Urls regex to exclude from instrumentation
46
const excludeUrls = [/favicon.ico/];
47
registerInstrumentations({
48
instrumentations: [
49
new MetisPgInstrumentation({ connectionString }),
50
new MetisHttpInstrumentation(excludeUrls)
51
],
52
});
53
};
1
// tracer.js
2
import opentelemetry from '@opentelemetry/api';
3
import { registerInstrumentations } from '@opentelemetry/instrumentation';
4
import {
5
BasicTracerProvider,
6
BatchSpanProcessor,
7
ConsoleSpanExporter,
8
SimpleSpanProcessor,
9
} from '@opentelemetry/sdk-trace-base';
10
import {
11
getMetisExporter,
12
MetisHttpInstrumentation,
13
MetisPgInstrumentation,
14
getResource,
15
} from '@metis-data/pg-interceptor';
16
import { AsyncHooksContextManager } from '@opentelemetry/context-async-hooks';
17
18
let tracerProvider;
19
const connectionString = process.env.PG_CONNECTION_STRING;
20
21
export const startMetisInstrumentation = () => {
22
tracerProvider = new BasicTracerProvider({
23
resource: getResource(process.env.METIS_SERVICE_NAME, 'service-version'),
24
});
25
26
const metisExporter = getMetisExporter(process.env.METIS_API_KEY);
27
28
tracerProvider.addSpanProcessor(
29
new BatchSpanProcessor(metisExporter)
30
);
31
32
if (process.env.OTEL_DEBUG) {
33
tracerProvider.addSpanProcessor(
34
new SimpleSpanProcessor(new ConsoleSpanExporter())
35
);
36
}
37
38
const contextManager = new AsyncHooksContextManager();
39
40
contextManager.enable();
41
opentelemetry.context.setGlobalContextManager(contextManager);
42
43
tracerProvider.register();
44
45
// Urls regex to exclude from instrumentation
46
const excludeUrls = [/favicon.ico/];
47
registerInstrumentations({
48
instrumentations: [
49
new MetisPgInstrumentation({ connectionString }),
50
new MetisHttpInstrumentation(excludeUrls)
51
],
52
});
53
};
Setup
- Line 19 - A valid connection string is required
postgres://user:[email protected]:port/database
- Line 46 - If you wish to exclude certain incoming urls from being instrumented, it is possible to add their Regex here. For example: /favicon.ico/ will ignore this route calls.
- 2.After creating the tracer it should be called from application root where the bootstrap happens:
1
// main.ts
2
import { startMetisInstrumentation } from './tracer';
3
startMetisInstrumentation();
4
5
// imports...
6
// bootstrap()
Variable Name | Description |
---|---|
METIS_API_KEY | <String> API Key to use |
METIS_ENVIRONMENT | <String> Text used to identify the source that sends the instrumentation data. |
METIS_PLAN_MODE | <String> Can be set to one of
[none, actual, estimated] to choose which query plan to fetch, default actual. |
METIS_DISABLED | <Boolean> If True Metis Instrumentation is fully disabled. We strongly advise to disable the instrumentation when in production to prevent sensitive data from leaving your organization's database. |
METIS_SERVICE_NAME | <String> Gives ability to distinguish between services. Useful when working with Micro Services. |
OTEL_DEBUG | <Boolean> If True, console exporter is added to print incoming spans to console. |
If for any reason (like dynamic address) the connection string is not available during the tracer setup, you can define it later with the following code:
import { setPgConnection } from '@metis-data/pg-interceptor';
// When the connectionString available
setPgConnection(connectionString);
Until the connection will be defined, instrumentation will work and show the SQL queries, but won't show the queries plans and the insight derived from them.
Now you can run your application as you normally would, and interact with it in a manner that causes the server to interact with your database.
Last modified 3d ago