Skip to content

Commit

Permalink
Instrument Node.js part of Kibana with Elastic APM
Browse files Browse the repository at this point in the history
  • Loading branch information
watson committed Aug 26, 2019
1 parent 8afc486 commit ebf465e
Show file tree
Hide file tree
Showing 9 changed files with 451 additions and 6 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ disabledPlugins
webpackstats.json
/config/*
!/config/kibana.yml
!/config/apm.js
coverage
selenium
.babel_register_cache.json
Expand Down
19 changes: 19 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ A high level overview of our contributing guidelines.
- [Internationalization](#internationalization)
- [Testing and Building](#testing-and-building)
- [Debugging server code](#debugging-server-code)
- [Instrumenting with Elastic APM](#instrumenting-with-elastic-apm)
- [Debugging Unit Tests](#debugging-unit-tests)
- [Unit Testing Plugins](#unit-testing-plugins)
- [Cross-browser compatibility](#cross-browser-compatibility)
Expand Down Expand Up @@ -360,6 +361,24 @@ macOS users on a machine with a discrete graphics card may see significant speed
### Debugging Server Code
`yarn debug` will start the server with Node's inspect flag. Kibana's development mode will start three processes on ports `9229`, `9230`, and `9231`. Chrome's developer tools need to be configured to connect to all three connections. Add `localhost:<port>` for each Kibana process in Chrome's developer tools connection tab.

### Instrumenting with Elastic APM
Kibana ships with the [Elastic APM Node.js Agent](https://github.com/elastic/apm-agent-nodejs) built-in.
By default the agent is inactive, but can be enabled either in the config file [`config/apm.js`](config/apm.js), or by setting the following environment variable:

```
ELASTIC_APM_ACTIVE=true
```

When active, the agent requires a running [APM Server](https://github.com/elastic/apm-server) to send the collected data to.
By default, it will look for one on localhost, but an alternative host can be provided using either the config file [`config/apm.js`](config/apm.js), or by setting the following environment variable:

```
ELASTIC_APM_SERVER_URL=https://example.com:8200
```

Once the agent is active, it will trace all incoming HTTP requests to Kibana, monitor for errors, and collect process-level metrics.
The collected data will be sent to the APM Server and is viewable in the APM UI in Kibana.

### Unit testing frameworks
Kibana is migrating unit testing from Mocha to Jest. Legacy unit tests still
exist in Mocha but all new unit tests should be written in Jest. Mocha tests
Expand Down
71 changes: 71 additions & 0 deletions config/apm.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you 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
*
* http://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 file contains the configuration for the Elastic APM instrumentaion of
// Kibana itself.
//
// For an overview over the available configuration files, see:
// https://www.elastic.co/guide/en/apm/agent/nodejs/current/configuration.html
//
// For general information about Elastic APM, see:
// https://www.elastic.co/guide/en/apm/get-started/current/index.html

module.exports = {
// Set to `true` to instrument Kibana with Elastic APM (requires separate APM Server instance)
active: false,

// Override service name from package.json (kibana)
// Allowed characters: a-z, A-Z, 0-9, -, _, and space
serviceName: '',

// Use if APM Server requires a token
secretToken: '',

// Set custom APM Server URL (default: http://localhost:8200)
serverUrl: '',

// Global labels are applied to all transactions, spans, errors, and metrcis
globalLabels: {
kibana_version: require('../package.json').version
},

// You usually don't need to worry about the following config options
logLevel: 'info',
centralConfig: false
};

const { readFileSync } = require('fs');
const { execSync } = require('child_process');
const rev = gitRev();

if (rev !== null) {
module.exports.globalLabels.git_rev = rev;
}

try {
module.exports.globalLabels.kibana_uuid = readFileSync('../data/uuid', 'utf-8');
} catch (e) {} // eslint-disable-line no-empty

function gitRev() {
try {
return execSync('git rev-parse --short HEAD', { encoding: 'utf-8' }).trim();
} catch (e) {
return null;
}
}
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,7 @@
"d3": "3.5.17",
"d3-cloud": "1.2.5",
"del": "^4.0.0",
"elastic-apm-node": "^2.16.0",
"elasticsearch": "^16.2.0",
"elasticsearch-browser": "^16.2.0",
"encode-uri-query": "1.0.1",
Expand Down
1 change: 1 addition & 0 deletions scripts/kibana.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,5 +17,6 @@
* under the License.
*/

require('../src/apm')(process.env.ELASTIC_APM_PROXY_SERVICE_NAME || 'kibana-proxy');
require('../src/setup_node_env');
require('../src/cli/cli');
32 changes: 32 additions & 0 deletions src/apm.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you 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
*
* http://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.
*/

const { name, version, build } = require('../package.json');

module.exports = function (serviceName = name) {
if (
process.env.kbnWorkerType === 'optmzr' ||
(build && (build.distributable || build.release))
) return;

require('elastic-apm-node').start({
configFile: 'config/apm.js',
serviceName: `${serviceName}-${version.replace('.', '_')}`
});
};
1 change: 1 addition & 0 deletions src/cli/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,5 +17,6 @@
* under the License.
*/

require('../apm')();
require('../setup_node_env');
require('./cli');
3 changes: 3 additions & 0 deletions src/core/server/http/base_path_proxy_server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@
* under the License.
*/

import apm from 'elastic-apm-node';

import { ByteSizeValue } from '@kbn/config-schema';
import { Server, Request } from 'hapi';
import Url from 'url';
Expand Down Expand Up @@ -139,6 +141,7 @@ export class BasePathProxyServer {
// Before we proxy request to a target port we may want to wait until some
// condition is met (e.g. until target listener is ready).
async (request, responseToolkit) => {
apm.setTransactionName(`${request.method.toUpperCase()} /{basePath}/{kbnPath*}`);
await blockUntil();
return responseToolkit.continue;
},
Expand Down
Loading

0 comments on commit ebf465e

Please sign in to comment.