From 8ee6a08100f7b4edc7fd26b375d3af595a86055a Mon Sep 17 00:00:00 2001 From: David Luna Date: Tue, 17 Sep 2024 14:52:03 +0200 Subject: [PATCH 1/2] docs: add migration guide --- .../docs/migration-from-apm-agent.md | 193 ++++++++++++++++++ 1 file changed, 193 insertions(+) create mode 100644 packages/opentelemetry-node/docs/migration-from-apm-agent.md diff --git a/packages/opentelemetry-node/docs/migration-from-apm-agent.md b/packages/opentelemetry-node/docs/migration-from-apm-agent.md new file mode 100644 index 00000000..8e0ac04a --- /dev/null +++ b/packages/opentelemetry-node/docs/migration-from-apm-agent.md @@ -0,0 +1,193 @@ + + +# Migration from Elastic APM Node.js Agent + +This guide shows you how to _migrate_ a service instrumented with Elastic APM Node.js Agent +(classic Agent) with a basic setup to Elastic Distribution of OpenTelemetry Node.js (EDOT Node.js). If your +application is not instrumented with the classic agent please visit +our [get started](./get-started.md) guide in this documentation. + + + +## Prerequisites + +Before getting started, you'll need to save a minimal set of configuration options from the classic Agent, so +EDOT Node.js can send data to the same deployment of [Elastic Observability](https://www.elastic.co/observability) using the same service name. + +The mininmal set of options required for the migration are: + +- [server url](https://www.elastic.co/guide/en/apm/agent/nodejs/4.x/configuration.html#server-url) +- [api key](https://www.elastic.co/guide/en/apm/agent/nodejs/4.x/configuration.html#api-key) or [secret token](https://www.elastic.co/guide/en/apm/agent/nodejs/4.x/configuration.html#secret-token) +- [service name](https://www.elastic.co/guide/en/apm/agent/nodejs/4.x/configuration.html#service-name) (optional) + + + + +## Migration process + +If the service being instrumented is not using any advanced feature like [Agent's APIs](https://www.elastic.co/guide/en/apm/agent/nodejs/4.x/api.html) the +migration process is straight-forward. This section will focus on this scenario and instructions for advanced usage +will be given in futeher sections. + +### Uninstall Elastic APM Node.js Agent + +Uninstall the `elastic-apm-node` package: + +```sh +npm uninstall --save elastic-apm-node +``` + +Once the pacakge is removed you should proceed to remove any setup made to start the classic agent along with your service. + +- remove Node.js `--require` CLI option `NODE_OPTIONS` or the start command if your service is using [Node.js CLI option](https://www.elastic.co/guide/en/apm/agent/nodejs/4.x/starting-the-agent.html#start-option-node-require-opt) start method. +- remove start snippet if your service is starting the agent with one of this options + * [require('elastic-apm-node').start(...)](https://www.elastic.co/guide/en/apm/agent/nodejs/4.x/starting-the-agent.html#start-option-require-and-start) + * [require('elastic-apm-node/start')](https://www.elastic.co/guide/en/apm/agent/nodejs/4.x/starting-the-agent.html#start-option-require-start-module) +- remove the APM module if your service is using [separate APM init module](https://www.elastic.co/guide/en/apm/agent/nodejs/4.x/starting-the-agent.html#start-option-separate-init-module) + +### 2. Install EDOT Node.js + +Install the `@elastic/opentelemetry-node` package: + +```sh +npm install --save @elastic/opentelemetry-node +``` + +Like Elastic APM Node.js Agent EDOT Node.js is a single package that includes all the +OpenTelemetry JS packages that are needed for most cases. + +Once you have the package installed is time to setup the start proces. The recommended way +of starting EDOT Node.js along your application is via `--require` CLI option. + +```sh +node --require @elastic/opentelemetry-node my-service.js +``` + + +## Configuration of EDOT Node.js + +Once you're done with the changes described in the section above it is time to migrate the configuration. EDOT Node.js is +typically configured with `OTEL_*` environment variables defined by the OpenTelemetry spec. Environment variables +are read at startup and can be used to configure EDOT Node.js. + +For the minimal configuration mentioned in [prerequisites](#prerequisites) section there are `OTEL_*` variables +from OpenTelemetry spec that fit. + +- `OTEL_EXPORTER_OTLP_ENDPOINT` will hold the value of `server_url` configuration option +- `OTEL_EXPORTER_OTLP_HEADERS` will hold the value of `api_key` or `secret_token` + * the value should be `Authorization=Bearer {secret_token}` if `secret_token` was used + * the value should be `Authorization=ApiKEy {api_key}` if `api_key` was used + +If you want more information about configuration you may visit [configuration options](./configure.md) page. + + + +## Advanced + +There might be some cases where the instrumentation + +### Using classic Agent's APIs + +If you are doing manual instrumentation of some modules of your service through the [classic Agent's API](https://www.elastic.co/guide/en/apm/agent/nodejs/4.x/api.html) +you will need to refactor it to use `@opentelemetry/api` methods. + +Either if you're using `apm.startTransaction` or `apm.startSpan` APIs both could be refactor to the same instrumentation +code using `@opentelemetry/api`. The anatomy of a manual instrumentation using the classig Agent consists in +using `apm.startTransaction` or `apm.startSpan` to mark the beginning of a transaction/span and mark the end +by calling the `.end` API of the transaction or spans returned before. + +Example: +```js +// file: my-service.js +// +// NOTE: we're assuming this app is started using Node.js --require CLI option +// node --require elastic-apm-agent my-service.js +const http = require('http'); +const apm = require('elastic-apm-agent'); + +const server = http.createServer(function onRequest(req, res) { + // Start of manual instrumentation + const span = apm.startSpan('Custom Span') + + console.log('incoming request: %s %s %s', req.method, req.url, req.headers); + req.resume(); + req.on('end', function () { + const body = 'pong'; + res.writeHead(200, { + 'content-type': 'text/plain', + 'content-length': Buffer.byteLength(body), + }); + res.end(body); + // Instrumentation end + span.end(); + }); +}); + +server.listen(3000, '127.0.0.1', function () { + console.log('listening at', server.address()); +}); +``` + +To migrate this code to use `@opentelemetry/api` instead you should: + +- remove the require call of `elastic-apm-node` +- require `@opentelemetry/api` and get a tracer +- replace usage of the classic Agent's API with call to the tracer API + +```js +// file: my-service.js +// +// NOTE: we're assuming this app is started using Node.js --require CLI option +// node --require @elastic/otel-node my-service.js + +const http = require('http'); +// Require OTEL API +const api = require('@opentelemetry/api'); +// Get a tracer for our manual instrumentation +const tracer = api.tracer.getTracer(); + +const server = http.createServer(function onRequest(req, res) { + // Start of manual instrumentation. In OTEL is always starting an Span + tracer.startActiveSpan('Custom Span', function (span) { // <-- the measured logic should be wrapped in this callback + console.log('incoming request: %s %s %s', req.method, req.url, req.headers); + req.resume(); + req.on('end', function () { + const body = 'pong'; + res.writeHead(200, { + 'content-type': 'text/plain', + 'content-length': Buffer.byteLength(body), + }); + res.end(body); + // Instrumentation end + span.end(); + }); + }); +}); + +server.listen(3000, '127.0.0.1', function () { + console.log('listening at', server.address()); +}); +``` + + +### Extensive use of config options + +TODO: review classic agent config options and add here the ones that can be migrated to OTEL env vars + + +## FAQ + +- Will I get the same traces and metrics once the servie is migrated to EDOT Node.js? + +TODO: point to supported technologies and metrics documents + +- ???? From 21cab71f78efcad7c3d7f482520de376252b8e8f Mon Sep 17 00:00:00 2001 From: David Luna Date: Fri, 20 Sep 2024 17:29:12 +0200 Subject: [PATCH 2/2] chore: update migration docs --- .../docs/migration-from-apm-agent.md | 43 ++++++++++++++++++- 1 file changed, 41 insertions(+), 2 deletions(-) diff --git a/packages/opentelemetry-node/docs/migration-from-apm-agent.md b/packages/opentelemetry-node/docs/migration-from-apm-agent.md index 8e0ac04a..3a243e43 100644 --- a/packages/opentelemetry-node/docs/migration-from-apm-agent.md +++ b/packages/opentelemetry-node/docs/migration-from-apm-agent.md @@ -72,7 +72,7 @@ of starting EDOT Node.js along your application is via `--require` CLI option. node --require @elastic/opentelemetry-node my-service.js ``` - + ## Configuration of EDOT Node.js Once you're done with the changes described in the section above it is time to migrate the configuration. EDOT Node.js is @@ -181,7 +181,46 @@ server.listen(3000, '127.0.0.1', function () { ### Extensive use of config options -TODO: review classic agent config options and add here the ones that can be migrated to OTEL env vars +TODO: finish review of options +TODO: put this subsection 1st + + + +There are other configuration options that can be migrated from `elastic-apm-node` to EDOT Node.js. ... + +#### Log Level + +The [logLevel](https://www.elastic.co/guide/en/apm/agent/nodejs/current/configuration.html#log-level) option has a direct migration to +OTEL configuration via `OTEL_LOG_LEVEL` environment variable. The possible values change a bit but they represent similar levels. The following +table shows the equivalent values of log levels between `elastic-apm-node` and EDOT Node.js + +| ELASTIC_APM_LOG_LEVEL | OTEL_LOG_LEVEL | +| --------------------- | -------------- | +| `off` | `none` | +| `error` | `error` | +| `warn` | `warn` | +| `info` | `info` | +| `debug` | `debug` | +| `trace` | `verbose` | +| `trace` | `all` | + +#### Active + +The [active](https://www.elastic.co/guide/en/apm/agent/nodejs/current/configuration.html#active) config option has the equivalent in OTEL via the environment variable named `OTEL_SDK_DISABLED`. Notice this it has the opposite meanig so to to disable the agent you shouls set +this condfiguration to the string "true". Any other value will be considered false. + + +#### Disable instrumentations + +There is a couple of ways to migrate [disableInstrumentations](https://www.elastic.co/guide/en/apm/agent/nodejs/current/configuration.html#disable-instrumentations) since the [specification](https://opentelemetry.io/docs/zero-code/js/configuration/) for Node.js defines two environment variables: + +- `OTEL_NODE_ENABLED_INSTRUMENTATIONS`: instrumentations listed in this var will be enabled +- `OTEL_NODE_DISABLED_INSTRUMENTATIONS`: instrumentations listed in this var will be disaabled + +The quickest way to migrate `disableInstrumentations` is to migrate the list to `OTEL_NODE_DISABLED_INSTRUMENTATIONS` variable. You can check which instrumentations are included in EDOT Node.js in [supported technologies](./supported-technologies.md). + + +TODO: environment could be set as a resource attrib using `OTEL_RESOURCE_ATTRIBUTES`??? ## FAQ