@ogcio/o11y-sdk-node 0.1.0-beta.1 → 0.1.0-beta.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +74 -0
- package/README.md +222 -0
- package/dist/index.d.ts +3 -2
- package/dist/index.js +2 -0
- package/dist/lib/exporter/console.d.ts +3 -0
- package/dist/lib/exporter/console.js +20 -0
- package/dist/lib/exporter/grpc.d.ts +3 -0
- package/dist/lib/{grpc.js → exporter/grpc.js} +15 -9
- package/dist/lib/exporter/http.d.ts +3 -0
- package/dist/lib/{http.js → exporter/http.js} +15 -9
- package/dist/lib/exporter/index.d.ts +8 -0
- package/dist/lib/index.d.ts +29 -6
- package/dist/lib/instrumentation.node.js +32 -5
- package/dist/lib/metrics.d.ts +18 -0
- package/dist/lib/metrics.js +24 -0
- package/dist/lib/processor/enrich-logger-processor.d.ts +10 -0
- package/dist/lib/processor/enrich-logger-processor.js +19 -0
- package/dist/lib/processor/enrich-span-processor.d.ts +11 -0
- package/dist/lib/processor/enrich-span-processor.js +22 -0
- package/dist/lib/resource.d.ts +7 -0
- package/dist/lib/resource.js +18 -0
- package/dist/lib/traces.d.ts +1 -0
- package/dist/lib/traces.js +4 -0
- package/dist/lib/url-sampler.d.ts +10 -0
- package/dist/lib/url-sampler.js +25 -0
- package/dist/lib/utils.d.ts +4 -2
- package/dist/lib/utils.js +8 -3
- package/dist/package.json +57 -0
- package/dist/vitest.config.js +15 -1
- package/index.ts +4 -2
- package/lib/exporter/console.ts +31 -0
- package/lib/{grpc.ts → exporter/grpc.ts} +19 -11
- package/lib/{http.ts → exporter/http.ts} +19 -11
- package/lib/exporter/index.ts +9 -0
- package/lib/index.ts +37 -5
- package/lib/instrumentation.node.ts +42 -7
- package/lib/metrics.ts +75 -0
- package/lib/processor/enrich-logger-processor.ts +34 -0
- package/lib/processor/enrich-span-processor.ts +39 -0
- package/lib/resource.ts +30 -0
- package/lib/traces.ts +5 -0
- package/lib/url-sampler.ts +52 -0
- package/lib/utils.ts +16 -4
- package/package.json +32 -25
- package/test/index.test.ts +9 -0
- package/test/integration/README.md +26 -0
- package/test/integration/integration.test.ts +58 -0
- package/test/integration/run.sh +88 -0
- package/test/metrics.test.ts +142 -0
- package/test/node-config.test.ts +70 -31
- package/test/processor/enrich-logger-processor.test.ts +58 -0
- package/test/processor/enrich-span-processor.test.ts +104 -0
- package/test/resource.test.ts +33 -0
- package/test/url-sampler.test.ts +215 -0
- package/test/utils/alloy-log-parser.ts +46 -0
- package/test/validation.test.ts +31 -0
- package/tsconfig.json +2 -1
- package/vitest.config.ts +15 -1
- package/coverage/cobertura-coverage.xml +0 -199
- package/coverage/lcov-report/base.css +0 -224
- package/coverage/lcov-report/block-navigation.js +0 -87
- package/coverage/lcov-report/favicon.png +0 -0
- package/coverage/lcov-report/index.html +0 -131
- package/coverage/lcov-report/prettify.css +0 -1
- package/coverage/lcov-report/prettify.js +0 -2
- package/coverage/lcov-report/sdk-node/index.html +0 -116
- package/coverage/lcov-report/sdk-node/index.ts.html +0 -106
- package/coverage/lcov-report/sdk-node/lib/grpc.ts.html +0 -178
- package/coverage/lcov-report/sdk-node/lib/http.ts.html +0 -190
- package/coverage/lcov-report/sdk-node/lib/index.html +0 -191
- package/coverage/lcov-report/sdk-node/lib/index.ts.html +0 -265
- package/coverage/lcov-report/sdk-node/lib/instrumentation.node.ts.html +0 -310
- package/coverage/lcov-report/sdk-node/lib/options.ts.html +0 -109
- package/coverage/lcov-report/sdk-node/lib/utils.ts.html +0 -115
- package/coverage/lcov-report/sort-arrow-sprite.png +0 -0
- package/coverage/lcov-report/sorter.js +0 -196
- package/coverage/lcov.info +0 -206
- package/dist/lib/grpc.d.ts +0 -3
- package/dist/lib/http.d.ts +0 -3
- package/dist/lib/options.d.ts +0 -7
- package/lib/options.ts +0 -8
- package/test-report.xml +0 -39
- /package/dist/lib/{options.js → exporter/index.js} +0 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,79 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [0.1.0-beta.10](https://github.com/ogcio/o11y/compare/@ogcio/o11y-sdk-node@v0.1.0-beta.9...@ogcio/o11y-sdk-node@v0.1.0-beta.10) (2025-04-09)
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
### Features
|
|
7
|
+
|
|
8
|
+
* april depedency upgrade AB[#27200](https://github.com/ogcio/o11y/issues/27200) ([#116](https://github.com/ogcio/o11y/issues/116)) ([d792fe5](https://github.com/ogcio/o11y/commit/d792fe5a783b0b495912b5bef2babfe11ef5e01d))
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
### Bug Fixes
|
|
12
|
+
|
|
13
|
+
* default attributes in resource ([#112](https://github.com/ogcio/o11y/issues/112)) ([f0f0b9d](https://github.com/ogcio/o11y/commit/f0f0b9d555ef321d31f7171e25dc4b8a5b044522))
|
|
14
|
+
|
|
15
|
+
## [0.1.0-beta.9](https://github.com/ogcio/o11y/compare/@ogcio/o11y-sdk-node@v0.1.0-beta.8...@ogcio/o11y-sdk-node@v0.1.0-beta.9) (2025-03-24)
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
### Features
|
|
19
|
+
|
|
20
|
+
* add custom log processor for span enrich ([#102](https://github.com/ogcio/o11y/issues/102)) ([bbf8334](https://github.com/ogcio/o11y/commit/bbf83340940ed651dff63bbe7aaa52881d1e8c8c))
|
|
21
|
+
* upgrade to opentelemetry 2 AB[#25863](https://github.com/ogcio/o11y/issues/25863) ([#106](https://github.com/ogcio/o11y/issues/106)) ([3ff0314](https://github.com/ogcio/o11y/commit/3ff0314fef9f4d7b5db76da3b94e9035801384c7))
|
|
22
|
+
|
|
23
|
+
## [0.1.0-beta.8](https://github.com/ogcio/o11y/compare/@ogcio/o11y-sdk-node@v0.1.0-beta.7...@ogcio/o11y-sdk-node@v0.1.0-beta.8) (2025-03-07)
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
### Features
|
|
27
|
+
|
|
28
|
+
* o11y showcase AB[#25895](https://github.com/ogcio/o11y/issues/25895) ([#84](https://github.com/ogcio/o11y/issues/84)) ([f8f10af](https://github.com/ogcio/o11y/commit/f8f10af97d9f5c188e3e65f7d62d5c673edce25a))
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
### Bug Fixes
|
|
32
|
+
|
|
33
|
+
* improve getMetric attributes types ([#76](https://github.com/ogcio/o11y/issues/76)) ([243649c](https://github.com/ogcio/o11y/commit/243649c4bfe750687a729fbd836772cce16e0cb1))
|
|
34
|
+
|
|
35
|
+
## [0.1.0-beta.7](https://github.com/ogcio/o11y/compare/@ogcio/o11y-sdk-node@v0.1.0-beta.6...@ogcio/o11y-sdk-node@v0.1.0-beta.7) (2025-02-18)
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
### Features
|
|
39
|
+
|
|
40
|
+
* **sdk-node:** add span customization AB[#25358](https://github.com/ogcio/o11y/issues/25358) ([46ba97b](https://github.com/ogcio/o11y/commit/46ba97bac4004ff326a954592f45213ce0e4d683))
|
|
41
|
+
|
|
42
|
+
## [0.1.0-beta.6](https://github.com/ogcio/o11y/compare/@ogcio/o11y-sdk-node@v0.1.0-beta.5...@ogcio/o11y-sdk-node@v0.1.0-beta.6) (2025-02-06)
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
### Features
|
|
46
|
+
|
|
47
|
+
* remove pnpm test on prepublishOnly script ([#68](https://github.com/ogcio/o11y/issues/68)) ([41f6f57](https://github.com/ogcio/o11y/commit/41f6f57fa415c4f7adc29f49f983539274ef7320))
|
|
48
|
+
|
|
49
|
+
## [0.1.0-beta.5](https://github.com/ogcio/o11y/compare/@ogcio/o11y-sdk-node@v0.1.0-beta.4...@ogcio/o11y-sdk-node@v0.1.0-beta.5) (2025-02-06)
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
### Features
|
|
53
|
+
|
|
54
|
+
* add opentelemetry sampler ([#65](https://github.com/ogcio/o11y/issues/65)) ([66793fd](https://github.com/ogcio/o11y/commit/66793fd36bf071e592e3b455f2e33ad9d5b2db37))
|
|
55
|
+
|
|
56
|
+
## [0.1.0-beta.4](https://github.com/ogcio/o11y/compare/@ogcio/o11y-sdk-node@v0.1.0-beta.3...@ogcio/o11y-sdk-node@v0.1.0-beta.4) (2025-01-29)
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
### Bug Fixes
|
|
60
|
+
|
|
61
|
+
* prepublishOnly hook ([#60](https://github.com/ogcio/o11y/issues/60)) ([9fbd3ad](https://github.com/ogcio/o11y/commit/9fbd3ad0b45a1604cf2eccc26b2f8855640417a1))
|
|
62
|
+
|
|
63
|
+
## [0.1.0-beta.3](https://github.com/ogcio/o11y/compare/@ogcio/o11y-sdk-node@0.1.0-beta.2...@ogcio/o11y-sdk-node@v0.1.0-beta.3) (2025-01-28)
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
### Features
|
|
67
|
+
|
|
68
|
+
* **sdk-node:** custom metrics ([#53](https://github.com/ogcio/o11y/issues/53)) ([3cb40b1](https://github.com/ogcio/o11y/commit/3cb40b1add3d80615c8d123d233724094559c7ff))
|
|
69
|
+
|
|
70
|
+
## [0.1.0-beta.2](https://github.com/ogcio/o11y/compare/@ogcio/o11y-sdk-node@0.1.0-beta.1...@ogcio/o11y-sdk-node@0.1.0-beta.2) (2024-11-28)
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
### Bug Fixes
|
|
74
|
+
|
|
75
|
+
* Add readme file inside submodule ([#27](https://github.com/ogcio/o11y/issues/27)) ([dc518d5](https://github.com/ogcio/o11y/commit/dc518d5dde573368443bc0f8619e80e331880c78))
|
|
76
|
+
|
|
3
77
|
## [0.1.0-beta.1](https://github.com/ogcio/o11y/compare/@ogcio/o11y-sdk-node@0.0.1-beta.1...@ogcio/o11y-sdk-node@0.1.0-beta.1) (2024-11-27)
|
|
4
78
|
|
|
5
79
|
|
package/README.md
ADDED
|
@@ -0,0 +1,222 @@
|
|
|
1
|
+
# Observability NodeJS SDK
|
|
2
|
+
|
|
3
|
+
The NodeJS observability sdk is a npm package used to setup and implement opentelemetry instrumentation.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
pnpm
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
pnpm i --save @ogcio/o11y-sdk-node
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
npm
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
npm i @ogcio/o11y-sdk-node
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
## Usage
|
|
20
|
+
|
|
21
|
+
Setup using constructor function
|
|
22
|
+
|
|
23
|
+
```javascript
|
|
24
|
+
// instrumentation.ts
|
|
25
|
+
|
|
26
|
+
import("@ogcio/o11y-sdk-node/lib/index").then((sdk) =>
|
|
27
|
+
sdk.instrumentNode({
|
|
28
|
+
serviceName: "node-microservice",
|
|
29
|
+
collectorUrl: "http://localhost:4317",
|
|
30
|
+
resourceAttributes: {
|
|
31
|
+
"team.infra.cluster": "dev-01",
|
|
32
|
+
"team.infra.pod": "01",
|
|
33
|
+
"team.service.type": "fastify",
|
|
34
|
+
},
|
|
35
|
+
spanAttributes: {
|
|
36
|
+
"signal.namespace": "documentation",
|
|
37
|
+
},
|
|
38
|
+
ignoreUrls: [{ type: "equals", url: "/api/health" }],
|
|
39
|
+
}),
|
|
40
|
+
);
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
Run your node script with instrumentation
|
|
44
|
+
|
|
45
|
+
`node --import instrumentation.js server.js`
|
|
46
|
+
|
|
47
|
+
Or setup inside your package.json
|
|
48
|
+
|
|
49
|
+
```json
|
|
50
|
+
{
|
|
51
|
+
"main": "dist/index.js",
|
|
52
|
+
"type": "module",
|
|
53
|
+
"scripts": {
|
|
54
|
+
"start": "node --env-file=.env --import ./dist/instrumentation.js dist/index.js"
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
## Span Customization
|
|
60
|
+
|
|
61
|
+
It is possible to customize spans such as traces and logs globally or in a single code statement using predefined functions.
|
|
62
|
+
|
|
63
|
+
### Global Configuration
|
|
64
|
+
|
|
65
|
+
In the SDK configuration, you can set the following properties:
|
|
66
|
+
|
|
67
|
+
- `spanAttributes` Object containing static properties or functions used to evaluate custom attributes for every logs and traces.
|
|
68
|
+
- `resourceAttributes` Object containing static properties used as resources attributes for any signal.
|
|
69
|
+
- `traceRatio` Faction value from 0 to 1, used by TraceIdRatioBasedSampler which it deterministically samples a percentage of traces that you pass in as a parameter.
|
|
70
|
+
|
|
71
|
+
```typescript
|
|
72
|
+
function generateRandomString(): string {
|
|
73
|
+
return Math.random() + "_" + Date.now();
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
instrumentNode({
|
|
77
|
+
resourceAttributes: {
|
|
78
|
+
"property.name.one": "value_one",
|
|
79
|
+
"property.name.two": "value_two",
|
|
80
|
+
},
|
|
81
|
+
spanAttributes: {
|
|
82
|
+
"custom.span.value": "example",
|
|
83
|
+
"custom.span.value_with_function": generateRandomString,
|
|
84
|
+
},
|
|
85
|
+
});
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
### Edit Active Span
|
|
89
|
+
|
|
90
|
+
Using `getActiveSpan` function, you can access to current transaction span and customize it.
|
|
91
|
+
|
|
92
|
+
You can use the function everywhere in your code, and set some custom attributes that are enabled for that single span
|
|
93
|
+
|
|
94
|
+
```typescript
|
|
95
|
+
import { getActiveSpan } from "@ogcio/o11y-sdk-node";
|
|
96
|
+
|
|
97
|
+
async function routes(app: FastifyInstance) {
|
|
98
|
+
app.get("/", async (req, reply) => {
|
|
99
|
+
// validation and business logic
|
|
100
|
+
|
|
101
|
+
// set span attribute
|
|
102
|
+
getActiveSpan()?.setAttribute("business.info", "dummy");
|
|
103
|
+
|
|
104
|
+
reply.status(200).send(response);
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
## Sending Custom Metrics
|
|
110
|
+
|
|
111
|
+
This package gives the possibility to send custom metrics and define them as desired in the code, you can choose between sync metrics and observable async metrics.
|
|
112
|
+
|
|
113
|
+
To use this functionality, you only need to import `getMetric` and enable the application instrumentation.
|
|
114
|
+
|
|
115
|
+
```typescript
|
|
116
|
+
import { getMetric } from "@ogcio/o11y-sdk-node";
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
### Sync
|
|
120
|
+
|
|
121
|
+
Sync metrics are signals sent when the function has been called.
|
|
122
|
+
|
|
123
|
+
Creating a counter, there are 2 types of counter:
|
|
124
|
+
|
|
125
|
+
- **counter** a simple counter that can only add positive numbers
|
|
126
|
+
- **updowncounter** counter that support also negative numbers
|
|
127
|
+
|
|
128
|
+
```typescript
|
|
129
|
+
const counter = getMetric("counter", {
|
|
130
|
+
attributeName: "counter",
|
|
131
|
+
metricName: "fastify-counter",
|
|
132
|
+
});
|
|
133
|
+
|
|
134
|
+
counter.add(1, {
|
|
135
|
+
my: "my",
|
|
136
|
+
custom: "custom",
|
|
137
|
+
attributes: "attributes",
|
|
138
|
+
});
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
Creating a Histogram
|
|
142
|
+
|
|
143
|
+
```typescript
|
|
144
|
+
const histogram = getMetric("histogram", {
|
|
145
|
+
metricName: "response_duration",
|
|
146
|
+
attributeName: "http_response",
|
|
147
|
+
options: {
|
|
148
|
+
advice: {
|
|
149
|
+
explicitBucketBoundaries: [0, 100, 200, 500, 1000],
|
|
150
|
+
},
|
|
151
|
+
description: "Response durations",
|
|
152
|
+
},
|
|
153
|
+
});
|
|
154
|
+
|
|
155
|
+
histogram.record(120, { path: "/home" });
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
### Async
|
|
159
|
+
|
|
160
|
+
Async metrics are called by the scraper collector to read current data using the `Observable` pattern.
|
|
161
|
+
Creating an async metric means that the application will subscribe to the observability URL and record data on call (default 60s).
|
|
162
|
+
|
|
163
|
+
_keep in mind, you can't send signals on-demand with this component_
|
|
164
|
+
|
|
165
|
+
Creating an async Gauge
|
|
166
|
+
|
|
167
|
+
```typescript
|
|
168
|
+
const asyncGauge = getMetric("async-gauge", {
|
|
169
|
+
metricName: "cpu_usage",
|
|
170
|
+
attributeName: "server_load",
|
|
171
|
+
options: { unit: "percentage" },
|
|
172
|
+
}).addCallback((observer) => {
|
|
173
|
+
observer.observe(50, { host: "server1" });
|
|
174
|
+
});
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
Creating an async Counter
|
|
178
|
+
|
|
179
|
+
```typescript
|
|
180
|
+
getMetric("async-counter", {
|
|
181
|
+
attributeName: "scraped-memory",
|
|
182
|
+
metricName: "fastify-counter",
|
|
183
|
+
}).addCallback((observer) => {
|
|
184
|
+
observer.observe(freemem(), {
|
|
185
|
+
"application.os.memory": "free-memory",
|
|
186
|
+
});
|
|
187
|
+
});
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
## API Reference
|
|
191
|
+
|
|
192
|
+
#### Protocol
|
|
193
|
+
|
|
194
|
+
protocol is a string parameter used to define how to send signals to observability infrastructure
|
|
195
|
+
|
|
196
|
+
- **grpc** Use gRPC protocol, usually default port use 4317. Is the most performant option for server side applications.
|
|
197
|
+
- **http** Use HTTP standard protocol, usually default port use 4318. Mainly used on web or UI client applications.
|
|
198
|
+
- **console** Used for debugging sending signals to observability cluster, every information will be printed to your runtime console.
|
|
199
|
+
|
|
200
|
+
#### Shared Types
|
|
201
|
+
|
|
202
|
+
```ts
|
|
203
|
+
export type SDKLogLevel =
|
|
204
|
+
| "NONE"
|
|
205
|
+
| "ERROR"
|
|
206
|
+
| "WARN"
|
|
207
|
+
| "INFO"
|
|
208
|
+
| "DEBUG"
|
|
209
|
+
| "VERBOSE"
|
|
210
|
+
| "ALL";
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
### Config
|
|
214
|
+
|
|
215
|
+
| Parameter | Type | Description |
|
|
216
|
+
| :-------------- | :---------------- | :------------------------------------------------------------------------------------------------------- |
|
|
217
|
+
| `collectorUrl` | `string` | **Required**. The opentelemetry collector entrypoint url, if null, instrumentation will not be activated |
|
|
218
|
+
| `serviceName` | `string` | Name of your application used for the collector to group logs |
|
|
219
|
+
| `diagLogLevel` | `SDKLogLevel` | Diagnostic log level for the internal runtime instrumentation |
|
|
220
|
+
| `collectorMode` | `single \| batch` | Signals sending mode, default is batch for performance |
|
|
221
|
+
| `enableFS` | `boolean` | Flag to enable or disable the tracing for node:fs module |
|
|
222
|
+
| `protocol` | `string` | Type of the protocol used to send signals |
|
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { NodeSDK } from "@opentelemetry/sdk-node";
|
|
2
|
-
import type { NodeSDKConfig } from "./lib/index.js";
|
|
3
2
|
import buildNodeInstrumentation from "./lib/instrumentation.node.js";
|
|
4
3
|
export type * from "./lib/index.js";
|
|
5
|
-
export type {
|
|
4
|
+
export type { NodeSDK };
|
|
6
5
|
export { buildNodeInstrumentation as instrumentNode };
|
|
6
|
+
export * from "./lib/metrics.js";
|
|
7
|
+
export * from "./lib/traces.js";
|
package/dist/index.js
CHANGED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { ConsoleLogRecordExporter, SimpleLogRecordProcessor, } from "@opentelemetry/sdk-logs";
|
|
2
|
+
import { metrics } from "@opentelemetry/sdk-node";
|
|
3
|
+
import { ConsoleSpanExporter, SimpleSpanProcessor, } from "@opentelemetry/sdk-trace-base";
|
|
4
|
+
import { EnrichSpanProcessor } from "../processor/enrich-span-processor.js";
|
|
5
|
+
import { EnrichLogProcessor } from "../processor/enrich-logger-processor.js";
|
|
6
|
+
export default function buildConsoleExporters(config) {
|
|
7
|
+
return {
|
|
8
|
+
spans: [
|
|
9
|
+
new SimpleSpanProcessor(new ConsoleSpanExporter()),
|
|
10
|
+
new EnrichSpanProcessor(config.spanAttributes),
|
|
11
|
+
],
|
|
12
|
+
metrics: new metrics.PeriodicExportingMetricReader({
|
|
13
|
+
exporter: new metrics.ConsoleMetricExporter(),
|
|
14
|
+
}),
|
|
15
|
+
logs: [
|
|
16
|
+
new EnrichLogProcessor(config.spanAttributes),
|
|
17
|
+
new SimpleLogRecordProcessor(new ConsoleLogRecordExporter()),
|
|
18
|
+
],
|
|
19
|
+
};
|
|
20
|
+
}
|
|
@@ -1,22 +1,28 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { metrics } from "@opentelemetry/sdk-node";
|
|
2
2
|
import { CompressionAlgorithm } from "@opentelemetry/otlp-exporter-base";
|
|
3
|
-
import { PeriodicExportingMetricReader } from "@opentelemetry/sdk-metrics";
|
|
4
|
-
import { OTLPMetricExporter } from "@opentelemetry/exporter-metrics-otlp-grpc";
|
|
5
|
-
import { OTLPLogExporter } from "@opentelemetry/exporter-logs-otlp-grpc";
|
|
6
3
|
import { OTLPTraceExporter } from "@opentelemetry/exporter-trace-otlp-grpc";
|
|
4
|
+
import { OTLPLogExporter } from "@opentelemetry/exporter-logs-otlp-grpc";
|
|
5
|
+
import { OTLPMetricExporter } from "@opentelemetry/exporter-metrics-otlp-grpc";
|
|
6
|
+
import { LogRecordProcessorMap, SpanProcessorMap } from "../utils.js";
|
|
7
|
+
import { EnrichSpanProcessor } from "../processor/enrich-span-processor.js";
|
|
8
|
+
import { EnrichLogProcessor } from "../processor/enrich-logger-processor.js";
|
|
7
9
|
export default function buildGrpcExporters(config) {
|
|
8
10
|
return {
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
11
|
+
spans: [
|
|
12
|
+
new SpanProcessorMap[config.collectorMode ?? "batch"](new OTLPTraceExporter({
|
|
13
|
+
url: `${config.collectorUrl}`,
|
|
14
|
+
compression: CompressionAlgorithm.GZIP,
|
|
15
|
+
})),
|
|
16
|
+
new EnrichSpanProcessor(config.spanAttributes),
|
|
17
|
+
],
|
|
18
|
+
metrics: new metrics.PeriodicExportingMetricReader({
|
|
14
19
|
exporter: new OTLPMetricExporter({
|
|
15
20
|
url: `${config.collectorUrl}`,
|
|
16
21
|
compression: CompressionAlgorithm.GZIP,
|
|
17
22
|
}),
|
|
18
23
|
}),
|
|
19
24
|
logs: [
|
|
25
|
+
new EnrichLogProcessor(config.spanAttributes),
|
|
20
26
|
new LogRecordProcessorMap[config.collectorMode ?? "batch"](new OTLPLogExporter({
|
|
21
27
|
url: `${config.collectorUrl}`,
|
|
22
28
|
compression: CompressionAlgorithm.GZIP,
|
|
@@ -1,25 +1,31 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { LogRecordProcessorMap } from "./utils.js";
|
|
1
|
+
import { metrics } from "@opentelemetry/sdk-node";
|
|
3
2
|
import { CompressionAlgorithm } from "@opentelemetry/otlp-exporter-base";
|
|
4
|
-
import {
|
|
5
|
-
import { OTLPMetricExporter } from "@opentelemetry/exporter-metrics-otlp-http";
|
|
3
|
+
import { OTLPTraceExporter } from "@opentelemetry/exporter-trace-otlp-http";
|
|
6
4
|
import { OTLPLogExporter } from "@opentelemetry/exporter-logs-otlp-http";
|
|
5
|
+
import { OTLPMetricExporter } from "@opentelemetry/exporter-metrics-otlp-http";
|
|
6
|
+
import { LogRecordProcessorMap, SpanProcessorMap } from "../utils.js";
|
|
7
|
+
import { EnrichSpanProcessor } from "../processor/enrich-span-processor.js";
|
|
8
|
+
import { EnrichLogProcessor } from "../processor/enrich-logger-processor.js";
|
|
7
9
|
export default function buildHttpExporters(config) {
|
|
8
10
|
if (config.collectorUrl.endsWith("/")) {
|
|
9
11
|
config.collectorUrl = config.collectorUrl.slice(0, -1);
|
|
10
12
|
}
|
|
11
13
|
return {
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
14
|
+
spans: [
|
|
15
|
+
new SpanProcessorMap[config.collectorMode ?? "batch"](new OTLPTraceExporter({
|
|
16
|
+
url: `${config.collectorUrl}/v1/traces`,
|
|
17
|
+
compression: CompressionAlgorithm.GZIP,
|
|
18
|
+
})),
|
|
19
|
+
new EnrichSpanProcessor(config.spanAttributes),
|
|
20
|
+
],
|
|
21
|
+
metrics: new metrics.PeriodicExportingMetricReader({
|
|
17
22
|
exporter: new OTLPMetricExporter({
|
|
18
23
|
url: `${config.collectorUrl}/v1/metrics`,
|
|
19
24
|
compression: CompressionAlgorithm.GZIP,
|
|
20
25
|
}),
|
|
21
26
|
}),
|
|
22
27
|
logs: [
|
|
28
|
+
new EnrichLogProcessor(config.spanAttributes),
|
|
23
29
|
new LogRecordProcessorMap[config.collectorMode ?? "batch"](new OTLPLogExporter({
|
|
24
30
|
url: `${config.collectorUrl}/v1/logs`,
|
|
25
31
|
compression: CompressionAlgorithm.GZIP,
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { LogRecordProcessor } from "@opentelemetry/sdk-logs";
|
|
2
|
+
import type { metrics } from "@opentelemetry/sdk-node";
|
|
3
|
+
import { SpanProcessor } from "@opentelemetry/sdk-trace-base";
|
|
4
|
+
export type Exporters = {
|
|
5
|
+
spans: SpanProcessor[];
|
|
6
|
+
metrics: metrics.MetricReader;
|
|
7
|
+
logs: LogRecordProcessor[];
|
|
8
|
+
};
|
package/dist/lib/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
interface
|
|
1
|
+
export interface NodeSDKConfig {
|
|
2
2
|
/**
|
|
3
3
|
* The opentelemetry collector entrypoint GRPC url.
|
|
4
4
|
* If the collectoUrl is null or undefined, the instrumentation will not be activated.
|
|
@@ -25,8 +25,27 @@ interface SDKConfig {
|
|
|
25
25
|
* @default batch
|
|
26
26
|
*/
|
|
27
27
|
collectorMode?: SDKCollectorMode;
|
|
28
|
-
|
|
29
|
-
|
|
28
|
+
/**
|
|
29
|
+
* Array of not traced urls.
|
|
30
|
+
*
|
|
31
|
+
* @type {SamplerCondition}
|
|
32
|
+
* @default []
|
|
33
|
+
*/
|
|
34
|
+
ignoreUrls?: SamplerCondition[];
|
|
35
|
+
/**
|
|
36
|
+
* Object containing static properties or functions used to evaluate custom attributes for every logs and traces.
|
|
37
|
+
*/
|
|
38
|
+
spanAttributes?: Record<string, SignalAttributeValue | (() => SignalAttributeValue)>;
|
|
39
|
+
/**
|
|
40
|
+
* Object containing static properties used as resources attributes for the Node SDK initialization.
|
|
41
|
+
*/
|
|
42
|
+
resourceAttributes?: Record<string, SignalAttributeValue>;
|
|
43
|
+
/**
|
|
44
|
+
* Faction value from 0 to 1, used by TraceIdRatioBasedSampler which it deterministically samples a percentage of traces that you pass in as a parameter.
|
|
45
|
+
*
|
|
46
|
+
* @default 1
|
|
47
|
+
*/
|
|
48
|
+
traceRatio?: number;
|
|
30
49
|
/**
|
|
31
50
|
* Flag to enable or disable the tracing for node:fs module
|
|
32
51
|
*
|
|
@@ -34,13 +53,17 @@ export interface NodeSDKConfig extends SDKConfig {
|
|
|
34
53
|
*/
|
|
35
54
|
enableFS?: boolean;
|
|
36
55
|
/**
|
|
37
|
-
*
|
|
56
|
+
* Protocol used to send signals.
|
|
38
57
|
*
|
|
39
58
|
* @default grpc
|
|
40
59
|
*/
|
|
41
60
|
protocol?: SDKProtocol;
|
|
42
61
|
}
|
|
62
|
+
export interface SamplerCondition {
|
|
63
|
+
type: "endsWith" | "includes" | "equals";
|
|
64
|
+
url: string;
|
|
65
|
+
}
|
|
66
|
+
export type SignalAttributeValue = string | number | boolean;
|
|
43
67
|
export type SDKCollectorMode = "single" | "batch";
|
|
44
|
-
export type SDKProtocol = "grpc" | "http";
|
|
68
|
+
export type SDKProtocol = "grpc" | "http" | "console";
|
|
45
69
|
export type SDKLogLevel = "NONE" | "ERROR" | "WARN" | "INFO" | "DEBUG" | "VERBOSE" | "ALL";
|
|
46
|
-
export {};
|
|
@@ -1,10 +1,13 @@
|
|
|
1
|
-
import { NodeSDK } from "@opentelemetry/sdk-node";
|
|
2
|
-
import isUrl from "is-url";
|
|
3
|
-
import buildHttpExporters from "./http.js";
|
|
4
|
-
import buildGrpcExporters from "./grpc.js";
|
|
5
1
|
import { diag, DiagConsoleLogger, DiagLogLevel } from "@opentelemetry/api";
|
|
6
2
|
import { getNodeAutoInstrumentations } from "@opentelemetry/auto-instrumentations-node";
|
|
7
3
|
import { W3CTraceContextPropagator } from "@opentelemetry/core";
|
|
4
|
+
import { NodeSDK } from "@opentelemetry/sdk-node";
|
|
5
|
+
import { AlwaysOffSampler, ParentBasedSampler, TraceIdRatioBasedSampler, } from "@opentelemetry/sdk-trace-base";
|
|
6
|
+
import buildConsoleExporters from "./exporter/console.js";
|
|
7
|
+
import buildGrpcExporters from "./exporter/grpc.js";
|
|
8
|
+
import buildHttpExporters from "./exporter/http.js";
|
|
9
|
+
import { ObservabilityResourceDetector } from "./resource.js";
|
|
10
|
+
import { UrlSampler } from "./url-sampler.js";
|
|
8
11
|
export default function buildNodeInstrumentation(config) {
|
|
9
12
|
if (!config) {
|
|
10
13
|
console.warn("observability config not set. Skipping NodeJS OpenTelemetry instrumentation.");
|
|
@@ -22,18 +25,33 @@ export default function buildNodeInstrumentation(config) {
|
|
|
22
25
|
if (config.protocol === "http") {
|
|
23
26
|
exporter = buildHttpExporters(config);
|
|
24
27
|
}
|
|
28
|
+
else if (config.protocol === "console") {
|
|
29
|
+
exporter = buildConsoleExporters(config);
|
|
30
|
+
}
|
|
25
31
|
else {
|
|
26
32
|
exporter = buildGrpcExporters(config);
|
|
27
33
|
}
|
|
34
|
+
const urlSampler = new UrlSampler(config.ignoreUrls, new TraceIdRatioBasedSampler(config.traceRatio ?? 1));
|
|
35
|
+
const mainSampler = new ParentBasedSampler({
|
|
36
|
+
root: urlSampler,
|
|
37
|
+
remoteParentSampled: urlSampler,
|
|
38
|
+
remoteParentNotSampled: new AlwaysOffSampler(),
|
|
39
|
+
localParentSampled: urlSampler,
|
|
40
|
+
localParentNotSampled: new AlwaysOffSampler(),
|
|
41
|
+
});
|
|
28
42
|
try {
|
|
29
43
|
diag.setLogger(new DiagConsoleLogger(), config.diagLogLevel
|
|
30
44
|
? DiagLogLevel[config.diagLogLevel]
|
|
31
45
|
: DiagLogLevel.INFO);
|
|
32
46
|
const sdk = new NodeSDK({
|
|
47
|
+
resourceDetectors: [
|
|
48
|
+
new ObservabilityResourceDetector(config.resourceAttributes),
|
|
49
|
+
],
|
|
50
|
+
spanProcessors: exporter.spans,
|
|
33
51
|
serviceName: config.serviceName,
|
|
34
|
-
traceExporter: exporter.traces,
|
|
35
52
|
metricReader: exporter.metrics,
|
|
36
53
|
logRecordProcessors: exporter.logs,
|
|
54
|
+
sampler: mainSampler,
|
|
37
55
|
textMapPropagator: new W3CTraceContextPropagator(),
|
|
38
56
|
instrumentations: [
|
|
39
57
|
getNodeAutoInstrumentations({
|
|
@@ -51,3 +69,12 @@ export default function buildNodeInstrumentation(config) {
|
|
|
51
69
|
console.error("Error starting NodeJS OpenTelemetry instrumentation:", error);
|
|
52
70
|
}
|
|
53
71
|
}
|
|
72
|
+
function isUrl(url) {
|
|
73
|
+
try {
|
|
74
|
+
new URL(url);
|
|
75
|
+
return true;
|
|
76
|
+
}
|
|
77
|
+
catch (_) {
|
|
78
|
+
return false;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { Counter, Gauge, Histogram, MetricOptions, ObservableCounter, ObservableGauge, ObservableUpDownCounter, UpDownCounter, Attributes } from "@opentelemetry/api";
|
|
2
|
+
type MetricTypeMap<TAttributes extends Attributes> = {
|
|
3
|
+
counter: Counter<TAttributes>;
|
|
4
|
+
histogram: Histogram<TAttributes>;
|
|
5
|
+
gauge: Gauge<TAttributes>;
|
|
6
|
+
updowncounter: UpDownCounter<TAttributes>;
|
|
7
|
+
"async-counter": ObservableCounter<TAttributes>;
|
|
8
|
+
"async-updowncounter": ObservableUpDownCounter<TAttributes>;
|
|
9
|
+
"async-gauge": ObservableGauge<TAttributes>;
|
|
10
|
+
};
|
|
11
|
+
export type MetricType = keyof MetricTypeMap<Attributes>;
|
|
12
|
+
export interface MetricsParams {
|
|
13
|
+
meterName: string;
|
|
14
|
+
metricName: string;
|
|
15
|
+
options?: MetricOptions;
|
|
16
|
+
}
|
|
17
|
+
export declare function getMetric<T extends MetricType, TAttributes extends Attributes = Attributes>(type: T, p: MetricsParams): MetricTypeMap<TAttributes>[T];
|
|
18
|
+
export {};
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { createNoopMeter, metrics, } from "@opentelemetry/api";
|
|
2
|
+
const MetricsFactoryMap = {
|
|
3
|
+
gauge: (meter) => meter.createGauge,
|
|
4
|
+
histogram: (meter) => meter.createHistogram,
|
|
5
|
+
counter: (meter) => meter.createCounter,
|
|
6
|
+
updowncounter: (meter) => meter.createUpDownCounter,
|
|
7
|
+
"async-counter": (meter) => meter.createObservableCounter,
|
|
8
|
+
"async-updowncounter": (meter) => meter.createObservableUpDownCounter,
|
|
9
|
+
"async-gauge": (meter) => meter.createObservableGauge,
|
|
10
|
+
};
|
|
11
|
+
function getMeter({ meterName }) {
|
|
12
|
+
if (!meterName) {
|
|
13
|
+
console.error("Invalid metric name!");
|
|
14
|
+
return createNoopMeter();
|
|
15
|
+
}
|
|
16
|
+
return metrics.getMeter(`custom_metric.${meterName}`);
|
|
17
|
+
}
|
|
18
|
+
export function getMetric(type, p) {
|
|
19
|
+
const meter = getMeter(p);
|
|
20
|
+
if (!MetricsFactoryMap[type]) {
|
|
21
|
+
throw new Error(`Unsupported metric type: ${type}`);
|
|
22
|
+
}
|
|
23
|
+
return MetricsFactoryMap[type](meter).bind(meter)(p.metricName, p.options);
|
|
24
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { LogRecord, LogRecordProcessor } from "@opentelemetry/sdk-logs";
|
|
2
|
+
import { Context } from "@opentelemetry/api";
|
|
3
|
+
import { SignalAttributeValue } from "../index.js";
|
|
4
|
+
export declare class EnrichLogProcessor implements LogRecordProcessor {
|
|
5
|
+
private _spanAttributes?;
|
|
6
|
+
constructor(spanAttributes?: Record<string, SignalAttributeValue | (() => SignalAttributeValue)>);
|
|
7
|
+
forceFlush(): Promise<void>;
|
|
8
|
+
onEmit(logRecord: LogRecord, _context?: Context): void;
|
|
9
|
+
shutdown(): Promise<void>;
|
|
10
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
export class EnrichLogProcessor {
|
|
2
|
+
_spanAttributes = undefined;
|
|
3
|
+
constructor(spanAttributes) {
|
|
4
|
+
this._spanAttributes = spanAttributes;
|
|
5
|
+
}
|
|
6
|
+
forceFlush() {
|
|
7
|
+
return Promise.resolve();
|
|
8
|
+
}
|
|
9
|
+
onEmit(logRecord, _context) {
|
|
10
|
+
if (this._spanAttributes) {
|
|
11
|
+
for (const [key, value] of Object.entries(this._spanAttributes)) {
|
|
12
|
+
logRecord.setAttribute(key, typeof value === "function" ? value() : value);
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
shutdown() {
|
|
17
|
+
return Promise.resolve();
|
|
18
|
+
}
|
|
19
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { Context } from "@opentelemetry/api";
|
|
2
|
+
import { ReadableSpan, Span, SpanProcessor } from "@opentelemetry/sdk-trace-base";
|
|
3
|
+
import { SignalAttributeValue } from "../index.js";
|
|
4
|
+
export declare class EnrichSpanProcessor implements SpanProcessor {
|
|
5
|
+
private _spanAttributes;
|
|
6
|
+
constructor(spanAttributes?: Record<string, SignalAttributeValue | (() => SignalAttributeValue)>);
|
|
7
|
+
forceFlush(): Promise<void>;
|
|
8
|
+
onStart(span: Span, _context: Context): void;
|
|
9
|
+
onEnd(_span: ReadableSpan): void;
|
|
10
|
+
shutdown(): Promise<void>;
|
|
11
|
+
}
|