Skip to content

Commit

Permalink
feat: process resource detector
Browse files Browse the repository at this point in the history
  • Loading branch information
mihirsoni committed Sep 14, 2020
1 parent f824195 commit beff0e0
Show file tree
Hide file tree
Showing 6 changed files with 212 additions and 1 deletion.
21 changes: 21 additions & 0 deletions packages/opentelemetry-resources/src/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -116,3 +116,24 @@ export const SERVICE_RESOURCE = {
/** The version string of the service API or implementation. */
VERSION: 'service.version',
};

/** Attributes describing a Process service. */
export const PROCESS_RESOURCE = {
/** A command which launced this proces. */
COMMAND: 'process.command',

/** The full command with arguments as string. */
COMMAND_LINE: 'process.command_line',

/** A name given to currently running porcess defaults to executable else set as process.title . */
NAME: 'process.executable.name',

/** An owner of currently running process. */
OWNER: 'process.owner',

/** The full path to the process executable. */
PATH: 'process.executable.path',

/** Process identifier of currently running process. */
PID: 'process.id',
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
/*
* Copyright The OpenTelemetry Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

import {
Detector,
Resource,
PROCESS_RESOURCE,
ResourceDetectionConfigWithLogger,
} from '../../../';
import { ResourceAttributes } from '../../../types';

/**
* ProcessDetector will be used to detect the resoureces related current process running
* and being instumented from the NodeJS Process module.
*/
class ProcessDetector implements Detector {
async detect(config: ResourceDetectionConfigWithLogger): Promise<Resource> {
const processResource: ResourceAttributes = {
[PROCESS_RESOURCE.PID]: process.pid || '',
[PROCESS_RESOURCE.NAME]: process.title || '',
[PROCESS_RESOURCE.COMMAND]: process.argv[1] || '',
[PROCESS_RESOURCE.COMMAND_LINE]: process.argv.join(' ') || '',
};
return this._getResourceAttributes(processResource, config);
}
/**
* Validates process resource attribute map from process varaibls
*
* @param processResource The unsantized resource attributes from process as key/value pairs.
* @param config: Config
* @returns The sanitized resource attributes.
*/
private _getResourceAttributes(
processResource: ResourceAttributes,
config: ResourceDetectionConfigWithLogger
) {
if (processResource[PROCESS_RESOURCE.PID] === '') {
config.logger.debug(
'ProcessDetector failed: unable to locate pid for currently running process'
);
return Resource.empty();
} else if (
processResource[PROCESS_RESOURCE.NAME] === '' ||
processResource[PROCESS_RESOURCE.PATH] === '' ||
processResource[PROCESS_RESOURCE.COMMAND] === '' ||
processResource[PROCESS_RESOURCE.COMMAND_LINE] === ''
) {
config.logger.debug(
'ProcessDetector failed: Unable to find required process resources. '
);
return Resource.empty();
} else {
return new Resource({
...processResource,
});
}
}
}

export const processDetector = new ProcessDetector();
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,4 @@
*/

export * from './EnvDetector';
export * from './ProcessDetector';
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
/*
* Copyright The OpenTelemetry Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

import { processDetector, Resource } from '../../src';
import {
assertProcessResource,
assertEmptyResource,
} from '../util/resource-assertions';
import { NoopLogger } from '@opentelemetry/core';

describe('processDetector()', () => {
it('should return resource information from process', async () => {
Object.defineProperty(process, 'pid', {
value: 1234,
});
Object.defineProperty(process, 'title', {
value: 'otProcess',
});
Object.defineProperty(process, 'argv', {
value: ['/tmp/node', '/home/ot/test.js', 'arg1', 'arg2'],
});
const resource: Resource = await processDetector.detect({
logger: new NoopLogger(),
});
assertProcessResource(resource, {
pid: 1234,
name: 'otProcess',
command: '/home/ot/test.js',
commandLine: '/tmp/node /home/ot/test.js arg1 arg2',
});
});
it('should return empty resources if title, command and commondLine is missing', async () => {
Object.defineProperty(process, 'pid', {
value: 1234,
});
Object.defineProperty(process, 'title', {
value: undefined,
});
Object.defineProperty(process, 'argv', {
value: [],
});
const resource: Resource = await processDetector.detect({
logger: new NoopLogger(),
});
assertEmptyResource(resource);
});
it('should return empty resources if pid is missing', async () => {
Object.defineProperty(process, 'pid', {
value: undefined,
});
Object.defineProperty(process, 'title', {
value: 'otProcess',
});
Object.defineProperty(process, 'argv', {
value: ['/tmp/node', '/home/ot/test.js', 'arg1', 'arg2'],
});
const resource: Resource = await processDetector.detect({
logger: new NoopLogger(),
});
assertEmptyResource(resource);
});
});
40 changes: 40 additions & 0 deletions packages/opentelemetry-resources/test/util/resource-assertions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import {
K8S_RESOURCE,
TELEMETRY_SDK_RESOURCE,
SERVICE_RESOURCE,
PROCESS_RESOURCE,
} from '../../src/constants';

/**
Expand Down Expand Up @@ -260,6 +261,45 @@ export const assertServiceResource = (
);
};

/**
* Test utility method to validate an process resource
*
* @param resource the Resource to validate
* @param validations validations for the resource attributes
*/
export const assertProcessResource = (
resource: Resource,
validations: {
pid?: number;
name?: string;
command?: string;
commandLine?: string;
}
) => {
assert.strictEqual(
resource.attributes[PROCESS_RESOURCE.PID],
validations.pid
);
if (validations.name) {
assert.strictEqual(
resource.attributes[PROCESS_RESOURCE.NAME],
validations.name
);
}
if (validations.command) {
assert.strictEqual(
resource.attributes[PROCESS_RESOURCE.COMMAND],
validations.command
);
}
if (validations.commandLine) {
assert.strictEqual(
resource.attributes[PROCESS_RESOURCE.COMMAND_LINE],
validations.commandLine
);
}
};

/**
* Test utility method to validate an empty resource
*
Expand Down
3 changes: 2 additions & 1 deletion packages/opentelemetry-sdk-node/src/sdk.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import {
Resource,
ResourceDetectionConfig,
envDetector,
processDetector,
} from '@opentelemetry/resources';
import { BatchSpanProcessor, SpanProcessor } from '@opentelemetry/tracing';
import { NodeSDKConfiguration } from './types';
Expand Down Expand Up @@ -128,7 +129,7 @@ export class NodeSDK {
/** Detect resource attributes */
public async detectResources(config?: ResourceDetectionConfig) {
const internalConfig: ResourceDetectionConfig = {
detectors: [awsEc2Detector, gcpDetector, envDetector],
detectors: [awsEc2Detector, gcpDetector, envDetector, processDetector],
...config,
};

Expand Down

0 comments on commit beff0e0

Please sign in to comment.