Skip to content
This repository was archived by the owner on Oct 31, 2024. It is now read-only.

Commit 17d63f8

Browse files
author
Amir Blum
authored
feat: add sync resource detector api and service and deployment detectors (#129)
1 parent 8a05453 commit 17d63f8

File tree

33 files changed

+492
-14
lines changed

33 files changed

+492
-14
lines changed
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
# OpenTelemetry Deployment Resource Detector for Node.js
2+
[![NPM version](https://img.shields.io/npm/v/opentelemetry-resource-detector-deployment.svg)](https://www.npmjs.com/package/opentelemetry-resource-detector-deployment)
3+
4+
This module provides automatic resource detector for [Deployment](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/resource/semantic_conventions/deployment_environment.md)
5+
6+
## Installation
7+
8+
```bash
9+
npm install --save opentelemetry-resource-detector-deployment
10+
```
11+
12+
## Usage
13+
14+
### Synchronous SDK Initialization
15+
```js
16+
import { detectSyncResources } from 'opentelemetry-resource-detector-sync-api';
17+
import { deploymentSyncDetector } from 'opentelemetry-resource-detector-deployment';
18+
19+
const resource = detectSyncResources({
20+
detectors: [deploymentSyncDetector, /* add other sync detectors here */],
21+
});
22+
const tracerProvider = new NodeTracerProvider({ resource });
23+
```
24+
25+
### Asynchronous SDK Initialization
26+
```js
27+
import { detectResources } from '@opentelemetry/resources';
28+
import { deploymentDetector } from 'opentelemetry-resource-detector-deployment';
29+
30+
( async () => {
31+
const resource = await detectResources({
32+
detectors: [deploymentDetector, /* add other async detectors here */],
33+
});
34+
const tracerProvider = new NodeTracerProvider({ resource });
35+
// Initialize auto instrumentation plugins and register provider.
36+
// Make sure you don't 'require' instrumented packages elsewhere
37+
// before they are registered here
38+
})();
39+
```
40+
41+
## Attributes
42+
| Attribute | Type | Source |
43+
| --- | --- | --- |
44+
| `deployment.environment` | string | `process.env.NODE_ENV` |
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
{
2+
"name": "opentelemetry-resource-detector-deployment",
3+
"version": "0.4.0",
4+
"description": "open telemetry resource detector for deployment",
5+
"keywords": [
6+
"opentelemetry"
7+
],
8+
"homepage": "https://github.com/aspecto-io/opentelemetry-ext-js",
9+
"license": "Apache-2.0",
10+
"main": "dist/src/index.js",
11+
"files": [
12+
"dist/src/**/*.js",
13+
"dist/src/**/*.d.ts",
14+
"LICENSE",
15+
"README.md"
16+
],
17+
"repository": {
18+
"type": "git",
19+
"url": "https://github.com/aspecto-io/opentelemetry-ext-js.git"
20+
},
21+
"scripts": {
22+
"build": "tsc",
23+
"prepare": "yarn run build",
24+
"test": "mocha",
25+
"test:jaeger": "OTEL_EXPORTER_JAEGER_AGENT_HOST=localhost mocha",
26+
"watch": "tsc -w",
27+
"version:update": "node ../../../scripts/version-update.js",
28+
"test:ci": "yarn test",
29+
"version": "yarn run version:update"
30+
},
31+
"bugs": {
32+
"url": "https://github.com/aspecto-io/opentelemetry-ext-js/issues"
33+
},
34+
"peerDependencies": {
35+
"@opentelemetry/api": "^0.20.0"
36+
},
37+
"dependencies": {
38+
"@opentelemetry/resources": "^0.20.0",
39+
"@opentelemetry/semantic-conventions": "^0.20.0",
40+
"opentelemetry-resource-detector-sync-api": "^0.4.0"
41+
},
42+
"devDependencies": {
43+
"@opentelemetry/api": "^0.20.0",
44+
"@types/mocha": "^8.2.2",
45+
"expect": "^26.6.2",
46+
"mocha": "^8.4.0",
47+
"opentelemetry-instrumentation-mocha": "0.0.1-rc.1",
48+
"ts-node": "^9.1.1",
49+
"typescript": "^4.0.5"
50+
},
51+
"mocha": {
52+
"extension": [
53+
"ts"
54+
],
55+
"spec": "test/**/*.spec.ts",
56+
"require": [
57+
"ts-node/register",
58+
"opentelemetry-instrumentation-mocha"
59+
]
60+
}
61+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import { ResourceAttributes as ResourceAttributesKeys } from '@opentelemetry/semantic-conventions';
2+
import { Resource } from '@opentelemetry/resources';
3+
import { SyncDetector, syncDetectorToDetector } from 'opentelemetry-resource-detector-sync-api';
4+
5+
class DeploymentSyncDetector implements SyncDetector {
6+
detect(): Resource {
7+
if (process.env.NODE_ENV) {
8+
return new Resource({
9+
[ResourceAttributesKeys.DEPLOYMENT_ENVIRONMENT]: process.env.NODE_ENV,
10+
});
11+
} else {
12+
return Resource.empty();
13+
}
14+
}
15+
}
16+
17+
export const deploymentSyncDetector = new DeploymentSyncDetector();
18+
export const deploymentDetector = syncDetectorToDetector(deploymentSyncDetector);
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export * from './deployment';
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
import 'mocha';
2+
import expect from 'expect';
3+
import { deploymentDetector, deploymentSyncDetector } from '../src';
4+
import { ResourceAttributes } from '@opentelemetry/semantic-conventions';
5+
6+
describe('deployment detector', () => {
7+
it('read deployment environment from environment variable', () => {
8+
process.env.NODE_ENV = 'env from testing';
9+
const resource = deploymentSyncDetector.detect();
10+
expect(resource.attributes[ResourceAttributes.DEPLOYMENT_ENVIRONMENT]).toMatch('env from testing');
11+
});
12+
13+
it('no deployment environment in environment variable', () => {
14+
delete process.env.NODE_ENV;
15+
const resource = deploymentSyncDetector.detect();
16+
expect(resource.attributes[ResourceAttributes.DEPLOYMENT_ENVIRONMENT]).toBeUndefined();
17+
});
18+
19+
it('async version', async () => {
20+
process.env.NODE_ENV = 'env from testing';
21+
const resource = await deploymentDetector.detect();
22+
expect(resource.attributes[ResourceAttributes.DEPLOYMENT_ENVIRONMENT]).toMatch('env from testing');
23+
});
24+
});
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
{
2+
"extends": "../../../tsconfig.base.json",
3+
"compilerOptions": {
4+
"rootDir": ".",
5+
"outDir": "./dist",
6+
"types": ["node"]
7+
}
8+
}
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
# OpenTelemetry Service Resource Detector for Node.js
2+
[![NPM version](https://img.shields.io/npm/v/opentelemetry-resource-detector-service.svg)](https://www.npmjs.com/package/opentelemetry-resource-detector-service)
3+
4+
This module provides automatic resource detector for [Service](https://github.com/open-telemetry/opentelemetry-specification/tree/main/specification/resource/semantic_conventions#service)
5+
6+
## Installation
7+
8+
```bash
9+
npm install --save opentelemetry-resource-detector-service
10+
```
11+
12+
## Usage
13+
14+
### Synchronous SDK Initialization
15+
```js
16+
import { detectSyncResources } from 'opentelemetry-resource-detector-sync-api';
17+
import { serviceSyncDetector } from 'opentelemetry-resource-detector-service';
18+
19+
const resource = detectSyncResources({
20+
detectors: [serviceSyncDetector, /* add other sync detectors here */],
21+
});
22+
const tracerProvider = new NodeTracerProvider({ resource });
23+
```
24+
25+
### Asynchronous SDK Initialization
26+
```js
27+
import { detectResources } from '@opentelemetry/resources';
28+
import { serviceDetector } from 'opentelemetry-resource-detector-service';
29+
30+
( async () => {
31+
const resource = await detectResources({
32+
detectors: [serviceDetector, /* add other async detectors here */],
33+
});
34+
const tracerProvider = new NodeTracerProvider({ resource });
35+
// Initialize auto instrumentation plugins and register provider.
36+
// Make sure you don't 'require' instrumented packages elsewhere
37+
// before they are registered here
38+
})();
39+
```
40+
41+
## Attributes
42+
| Attribute | Type | Source |
43+
| --- | --- | --- |
44+
| `service.name` | string | `process.env.OTEL_SERVICE_NAME`. If not set, will try to read `name` attribute from package.json. If not set will fallback to `unknown_service: concatenated with process.executable.name` (according to specification) |
45+
| `serivce.version` | string | `version` attribute from package.json |
46+
| `service.instance.id` | [string (v4 UUID)](https://en.wikipedia.org/wiki/Universally_unique_identifier#Version_4_(random)) | Automatically generated by the detector for each invocation of the service |
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
{
2+
"name": "opentelemetry-resource-detector-service",
3+
"version": "0.4.0",
4+
"description": "open telemetry resource detector for service",
5+
"keywords": [
6+
"opentelemetry"
7+
],
8+
"homepage": "https://github.com/aspecto-io/opentelemetry-ext-js",
9+
"license": "Apache-2.0",
10+
"main": "dist/src/index.js",
11+
"files": [
12+
"dist/src/**/*.js",
13+
"dist/src/**/*.d.ts",
14+
"LICENSE",
15+
"README.md"
16+
],
17+
"repository": {
18+
"type": "git",
19+
"url": "https://github.com/aspecto-io/opentelemetry-ext-js.git"
20+
},
21+
"scripts": {
22+
"build": "tsc",
23+
"prepare": "yarn run build",
24+
"test": "mocha",
25+
"test:jaeger": "OTEL_EXPORTER_JAEGER_AGENT_HOST=localhost mocha",
26+
"watch": "tsc -w",
27+
"version:update": "node ../../../scripts/version-update.js",
28+
"test:ci": "yarn test",
29+
"version": "yarn run version:update"
30+
},
31+
"bugs": {
32+
"url": "https://github.com/aspecto-io/opentelemetry-ext-js/issues"
33+
},
34+
"peerDependencies": {
35+
"@opentelemetry/api": "^0.20.0"
36+
},
37+
"dependencies": {
38+
"@opentelemetry/resources": "^0.20.0",
39+
"@opentelemetry/semantic-conventions": "^0.20.0",
40+
"opentelemetry-resource-detector-sync-api": "^0.4.0",
41+
"uuid": "^8.3.2"
42+
},
43+
"devDependencies": {
44+
"@opentelemetry/api": "^0.20.0",
45+
"@types/mocha": "^8.2.2",
46+
"expect": "^26.6.2",
47+
"mocha": "^8.4.0",
48+
"opentelemetry-instrumentation-mocha": "0.0.1-rc.1",
49+
"ts-node": "^9.1.1",
50+
"typescript": "^4.0.5"
51+
},
52+
"mocha": {
53+
"extension": [
54+
"ts"
55+
],
56+
"spec": "test/**/*.spec.ts",
57+
"require": [
58+
"ts-node/register",
59+
"opentelemetry-instrumentation-mocha"
60+
]
61+
}
62+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export * from './service';
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
import { ResourceAttributes as ResourceAttributesKeys } from '@opentelemetry/semantic-conventions';
2+
import { Resource, defaultServiceName, ResourceAttributes } from '@opentelemetry/resources';
3+
import { SyncDetector, syncDetectorToDetector } from 'opentelemetry-resource-detector-sync-api';
4+
import { v4 as uuidv4 } from 'uuid';
5+
import * as fs from 'fs';
6+
7+
// set as global to make sure it's the same on any invocation even for multiple
8+
// instances of ServiceSyncDetector
9+
const instanceId = uuidv4();
10+
11+
class ServiceSyncDetector implements SyncDetector {
12+
detect(): Resource {
13+
const packageJson = this.loadJsonFile('package.json');
14+
const attributes: ResourceAttributes = {
15+
[ResourceAttributesKeys.SERVICE_INSTANCE_ID]: instanceId,
16+
[ResourceAttributesKeys.SERVICE_NAME]: this.getServiceName(packageJson),
17+
};
18+
const serviceVersion = packageJson?.version;
19+
if (serviceVersion) {
20+
attributes[ResourceAttributesKeys.SERVICE_VERSION] = serviceVersion;
21+
}
22+
return new Resource(attributes);
23+
}
24+
25+
getServiceName(packageJson: any): string {
26+
const fromEnv = process.env.OTEL_SERVICE_NAME;
27+
if (fromEnv) return fromEnv;
28+
29+
const fromPackageJson = packageJson?.name;
30+
if (fromPackageJson) return fromPackageJson;
31+
32+
return defaultServiceName();
33+
}
34+
35+
loadJsonFile(path: string): any {
36+
try {
37+
return JSON.parse(fs.readFileSync(path).toString());
38+
} catch (err) {
39+
return null;
40+
}
41+
}
42+
}
43+
44+
export const serviceSyncDetector = new ServiceSyncDetector();
45+
export const serviceDetector = syncDetectorToDetector(serviceSyncDetector);

0 commit comments

Comments
 (0)