elastic / apm-agent-nodejs

https://www.elastic.co/guide/en/apm/agent/nodejs/current/index.html
BSD 2-Clause "Simplified" License
584 stars 225 forks source link

Error when elasticsearch config hosts property is an array #1762

Open bgardner87 opened 4 years ago

bgardner87 commented 4 years ago

Describe the bug

When you have an elasticsearch config similar to this:

 elasticsearch: {
        host: [
            {
                host: process.env.ELASTIC_HOST,
                auth: process.env.ELASTIC_AUTHENTICATION,
                protocol: process.env.ELASTIC_PROTOCOL,
                port: process.env.ELASTIC_PORT
            }
        ],
        log: 'error',
        requestTimeout: 60000
    }

The updated APM code crashes because it's not anticipating the array for the host property.

Issue was introduced in this commit: https://github.com/elastic/apm-agent-nodejs/commit/aa8eb56a8486b53802e378638920d44248ce64dc#diff-daccb535f6ab4446fed3816cc2a6dc92

Specifically this bit of code in the elasticsearch module:

// get the remote host information from elasticsearch Transport options
const transportConfig = this._config
let host, port
if (typeof transportConfig === 'object' && transportConfig.host) {
    [host, port] = transportConfig.host.split(':')
}
span.setDestinationContext(getDBDestination(span, host, port))

The host.split is where the error occurs: "TypeError: transportConfig.host.split is not a function or its return value is not iterable"

To Reproduce

Steps to reproduce the behavior:

  1. Use an array to specify one or more hosts for the elasticsearch client
  2. Use the latest release of the apm client.

Expected behavior

APM should be able to handle host specified as an array.

Environment (please complete the following information)

How are you starting the agent? (please tick one of the boxes)

bgardner87 commented 4 years ago

I may have time soon to pick this up and work on it, and I'm also noticing that this only applies to the legacy version of the elasticsearch javascript client.

AnkurThakur commented 4 years ago

I can confirm the same at my end. Below is an example Stack trace:

TypeError: transportConfig.host.split is not a function or its return value is not iterable

at Transport.wrappedRequest [as request] (/mnt/docker-disk/applications/myapp/node_modules/elastic-apm-node/lib/instrumentation/modules/elasticsearch.js:45:49)
at exec (/mnt/docker-disk/applications/myapp/node_modules/elasticsearch/src/lib/client_action.js:361:20)
at EsApiClient.action [as search] (/mnt/docker-disk/applications/myapp/node_modules/elasticsearch/src/lib/client_action.js:61:16)
iamhowardtheduck commented 4 years ago

Same on my end:

ERROR - /sessions.json error TypeError: transportConfig.host.split is not a function or its return value is not iterable -at Transport.wrappedRequest [as request] (/data/moloch/viewer/node_modules/elastic-apm-node/lib/instrumentation/modules/elasticsearch.js:45:49) -at exec (/data/moloch/node_modules/elasticsearch/src/lib/client_action.js:403:20) -at EsApiClient.action [as search] (/data/moloch/node_modules/elasticsearch/src/lib/client_action.js:61:16)

thijsvandergugten commented 3 years ago

Possible workaround: use the key hosts instead of host. According to https://www.elastic.co/guide/en/elasticsearch/client/javascript-api/16.x/config-options.html, (this is the legacy-client) this is possible, and this has solved the problem for me.