Skip to content

Commit

Permalink
feat: creating one auto loader for instrumentation and old plugins (#…
Browse files Browse the repository at this point in the history
…1731)

* feat: creating one auto loader for instrumentation and old plugins

* feat: adding temporary tests for autoloader

* chore: adding auto loader for instrumentation and plugins

* chore: removing temporary test

* chore: reverting changes done temporary

* chore: linting

* chore: updating submodule for opentelemetry-proto

* chore: updating submodule for exporter-collector-grpc
  • Loading branch information
obecny authored Jan 7, 2021
1 parent b4c9e40 commit 89664a7
Show file tree
Hide file tree
Showing 44 changed files with 1,940 additions and 2 deletions.
5 changes: 3 additions & 2 deletions examples/tracer-web/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,10 @@
"@opentelemetry/exporter-zipkin": "^0.14.0",
"@opentelemetry/metrics": "^0.14.0",
"@opentelemetry/propagator-b3": "^0.14.0",
"@opentelemetry/plugin-document-load": "^0.9.0",
"@opentelemetry/plugin-document-load": "^0.11.0",
"@opentelemetry/plugin-fetch": "^0.14.0",
"@opentelemetry/plugin-user-interaction": "^0.9.0",
"@opentelemetry/plugin-user-interaction": "^0.11.0",
"@opentelemetry/instrumentation": "^0.14.0",
"@opentelemetry/instrumentation-xml-http-request": "^0.14.0",
"@opentelemetry/tracing": "^0.14.0",
"@opentelemetry/web": "^0.14.0"
Expand Down
2 changes: 2 additions & 0 deletions lerna.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
"lerna": "3.13.4",
"npmClient": "npm",
"packages": [
"examples/test",
"examples/tracer-web",
"benchmark/*",
"backwards-compatability/*",
"metapackages/*",
Expand Down
2 changes: 2 additions & 0 deletions packages/opentelemetry-instrumentation/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# Dependency directories
!test/node/node_modules
108 changes: 108 additions & 0 deletions packages/opentelemetry-instrumentation/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,7 @@ const myPLugin = new MyPlugin();
myPLugin.setTracerProvider(provider); // this is optional
myPLugin.setMeterProvider(meterProvider); // this is optional
myPLugin.enable();
// or use Auto Loader
```

## Usage in Web
Expand Down Expand Up @@ -154,6 +155,113 @@ const myPLugin = new MyPlugin();
myPLugin.setTracerProvider(provider);
myPLugin.setMeterProvider(meterProvider);
myPLugin.enable();
// or use Auto Loader
```

## AutoLoader

Successor of loading plugins through TracerProvider "plugins" option.
It also supersedes PluginLoader for node. The old configurations usually looks like

### NODE - old way using TracerProvider

```javascript
const { NodeTracerProvider } = require('@opentelemetry/node');
const { B3Propagator } = require('@opentelemetry/propagator-b3');
const provider = new NodeTracerProvider({
plugins: {
http: { enabled: false },
},
});
provider.register({
propagator: new B3Propagator(),
});
```

### WEB - old way using TracerProvider

```javascript
const { WebTracerProvider } = require('@opentelemetry/web');
const { UserInteractionPlugin } = require('@opentelemetry/plugin-user-interaction');
const { XMLHttpRequestInstrumentation } = require('@opentelemetry/instrumentation-xml-http-request');
const { B3Propagator } = require('@opentelemetry/propagator-b3');
const provider = new WebTracerProvider({
plugins: [
new UserInteractionPlugin(),
new XMLHttpRequestInstrumentation({
ignoreUrls: [/localhost/],
propagateTraceHeaderCorsUrls: [
'http://localhost:8090',
],
}),
],
});
provider.register({
propagator: new B3Propagator(),
});
```

After change it will look like this - mixing plugins and instrumentations together
All plugins will be bound to TracerProvider as well as instrumentations

### NODE - Auto Loader

```javascript
const { B3Propagator } = require('@opentelemetry/propagator-b3');
const { registerInstrumentations } = require('@opentelemetry/instrumentation');
const { GraphQLInstrumentation } = require('@opentelemetry/instrumentation-graphql');
const { NodeTracerProvider } = require('@opentelemetry/node');
const tracerProvider = new NodeTracerProvider();

registerInstrumentations({
instrumentations: [
new UserInteractionPlugin(),
new XMLHttpRequestInstrumentation({
ignoreUrls: [/localhost/],
propagateTraceHeaderCorsUrls: [
'http://localhost:8090',
],
}),
],
meterProvider: meterProvider,
tracerProvider: tracerProvider,
logger: new ConsoleLogger(), // optional
});

tracerProvider.register({
propagator: new B3Propagator(),
});

```

### WEB - Auto Loader

```javascript
const { B3Propagator } = require('@opentelemetry/propagator-b3');
const { registerInstrumentations } = require('@opentelemetry/instrumentation');
import { XMLHttpRequestInstrumentation } from '@opentelemetry/instrumentation-xml-http-request';
const { UserInteractionPlugin } = require('@opentelemetry/plugin-user-interaction');
const { WebTracerProvider } = require('@opentelemetry/web');
const tracerProvider = new WebTracerProvider();

registerInstrumentations({
instrumentations: [
new GraphQLInstrumentation(),
{
plugins: {
http: { enabled: false },
},
}
],
meterProvider: meterProvider,
tracerProvider: tracerProvider,
logger: new ConsoleLogger(), // optional
});

tracerProvider.register({
propagator: new B3Propagator(),
});

```

## License
Expand Down
67 changes: 67 additions & 0 deletions packages/opentelemetry-instrumentation/src/autoLoader.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
/*
* 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 * as api from '@opentelemetry/api';
import {
disableInstrumentations,
enableInstrumentations,
parseInstrumentationOptions,
} from './autoLoaderUtils';
import { loadOldPlugins } from './platform';
import { AutoLoaderOptions } from './types_internal';

/**
* It will register instrumentations and plugins
* @param options
* @return returns function to unload instrumentation and plugins that were
* registered
*/
export function registerInstrumentations(
options: AutoLoaderOptions
): () => void {
const {
instrumentations,
pluginsNode,
pluginsWeb,
} = parseInstrumentationOptions(options.instrumentations);
const tracerWithLogger = (options.tracerProvider as unknown) as {
logger: api.Logger;
};
const tracerProvider =
options.tracerProvider || api.trace.getTracerProvider();
const meterProvider = options.meterProvider || api.metrics.getMeterProvider();
const logger =
options.logger || tracerWithLogger?.logger || new api.NoopLogger();

enableInstrumentations(
instrumentations,
logger,
tracerProvider,
meterProvider
);

const unload = loadOldPlugins(
pluginsNode,
pluginsWeb,
logger,
tracerProvider
);

return () => {
unload();
disableInstrumentations(instrumentations);
};
}
94 changes: 94 additions & 0 deletions packages/opentelemetry-instrumentation/src/autoLoaderUtils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
/*
* 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 { Logger, MeterProvider, TracerProvider } from '@opentelemetry/api';
import { Instrumentation } from './types';
import { AutoLoaderResult, InstrumentationOption } from './types_internal';

import {
NodePlugins,
NodePluginsTracerConfiguration,
OldClassPlugin,
} from './types_plugin_only';

/**
* Parses the options and returns instrumentations, node plugins and
* web plugins
* @param options
*/
export function parseInstrumentationOptions(
options: InstrumentationOption[] = []
): AutoLoaderResult {
let instrumentations: Instrumentation[] = [];
let pluginsNode: NodePlugins = {};
let pluginsWeb: OldClassPlugin[] = [];
for (let i = 0, j = options.length; i < j; i++) {
const option = options[i] as any;
if (Array.isArray(option)) {
const results = parseInstrumentationOptions(option);
instrumentations = instrumentations.concat(results.instrumentations);
pluginsWeb = pluginsWeb.concat(results.pluginsWeb);
pluginsNode = Object.assign({}, pluginsNode, results.pluginsNode);
} else if ((option as NodePluginsTracerConfiguration).plugins) {
pluginsNode = Object.assign(
{},
pluginsNode,
(option as NodePluginsTracerConfiguration).plugins
);
} else if (typeof option === 'function') {
instrumentations.push(new option());
} else if ((option as Instrumentation).instrumentationName) {
instrumentations.push(option);
} else if ((option as OldClassPlugin).moduleName) {
pluginsWeb.push(option as OldClassPlugin);
}
}

return { instrumentations, pluginsNode, pluginsWeb };
}

/**
* Enable instrumentations
* @param instrumentations
* @param logger
* @param tracerProvider
* @param meterProvider
*/
export function enableInstrumentations(
instrumentations: Instrumentation[],
logger: Logger,
tracerProvider?: TracerProvider,
meterProvider?: MeterProvider
) {
for (let i = 0, j = instrumentations.length; i < j; i++) {
const instrumentation = instrumentations[i];
if (tracerProvider) {
instrumentation.setTracerProvider(tracerProvider);
}
if (meterProvider) {
instrumentation.setMeterProvider(meterProvider);
}
instrumentation.enable();
}
}

/**
* Disable instrumentations
* @param instrumentations
*/
export function disableInstrumentations(instrumentations: Instrumentation[]) {
instrumentations.forEach(instrumentation => instrumentation.disable());
}
1 change: 1 addition & 0 deletions packages/opentelemetry-instrumentation/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
* limitations under the License.
*/

export * from './autoLoader';
export * from './platform/index';
export * from './types';
export * from './utils';
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,4 @@
*/

export * from './instrumentation';
export * from './old/autoLoader';
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
/*
* 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.
*/

// This should be removed after plugins are gone

import * as api from '@opentelemetry/api';
import { NodePlugins, OldClassPlugin } from '../../../types_plugin_only';

/**
* Loads provided web plugins
* @param pluginsNode
* @param pluginsWeb
* @param logger
* @param tracerProvider
* @return returns function to disable all plugins
*/
export function loadOldPlugins(
pluginsNode: NodePlugins,
pluginsWeb: OldClassPlugin[],
logger: api.Logger,
tracerProvider: api.TracerProvider
): () => void {
pluginsWeb.forEach(plugin => {
plugin.enable([], tracerProvider, logger);
});
return () => {
pluginsWeb.forEach(plugin => {
plugin.disable();
});
};
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
* limitations under the License.
*/

export * from './old/autoLoader';
export * from './instrumentation';
export * from './instrumentationNodeModuleDefinition';
export * from './instrumentationNodeModuleFile';
Expand Down
Loading

0 comments on commit 89664a7

Please sign in to comment.