diff --git a/src/core_plugins/kibana/common/tutorials/instruction_variant.js b/src/core_plugins/kibana/common/tutorials/instruction_variant.js
index 909def999d2b8..2a47728fcb32e 100644
--- a/src/core_plugins/kibana/common/tutorials/instruction_variant.js
+++ b/src/core_plugins/kibana/common/tutorials/instruction_variant.js
@@ -6,7 +6,10 @@ export const INSTRUCTION_VARIANT = {
WINDOWS: 'windows',
NODE: 'node',
DJANGO: 'django',
- FLASK: 'flask'
+ FLASK: 'flask',
+ RAILS: 'rails',
+ RACK: 'rack',
+ JS: 'js',
};
const DISPLAY_MAP = {
@@ -18,6 +21,9 @@ const DISPLAY_MAP = {
[INSTRUCTION_VARIANT.NODE]: 'Node.js',
[INSTRUCTION_VARIANT.DJANGO]: 'Django',
[INSTRUCTION_VARIANT.FLASK]: 'Flask',
+ [INSTRUCTION_VARIANT.RAILS]: 'Ruby on Rails',
+ [INSTRUCTION_VARIANT.RACK]: 'Rack',
+ [INSTRUCTION_VARIANT.JS]: 'JS',
};
/**
diff --git a/src/core_plugins/kibana/common/tutorials/tutorial_category.js b/src/core_plugins/kibana/common/tutorials/tutorial_category.js
index e112b3d36d251..f864b0629e9f2 100644
--- a/src/core_plugins/kibana/common/tutorials/tutorial_category.js
+++ b/src/core_plugins/kibana/common/tutorials/tutorial_category.js
@@ -1,5 +1,6 @@
export const TUTORIAL_CATEGORY = {
LOGGING: 'logging',
SECURITY: 'security',
- METRICS: 'metrics'
+ METRICS: 'metrics',
+ OTHER: 'other',
};
diff --git a/src/core_plugins/kibana/common/tutorials/tutorial_schema.js b/src/core_plugins/kibana/common/tutorials/tutorial_schema.js
index f506d3805aa60..d27c036448e66 100644
--- a/src/core_plugins/kibana/common/tutorials/tutorial_schema.js
+++ b/src/core_plugins/kibana/common/tutorials/tutorial_schema.js
@@ -65,10 +65,10 @@ export const tutorialSchema = {
onPrem: instructionsSchema.required(),
// kibana and elastic cluster running in elastic's cloud
- elasticCloud: instructionsSchema.required(),
+ elasticCloud: instructionsSchema,
// kibana running on prem and elastic cluster running in elastic's cloud
- onPremElasticCloud: instructionsSchema.required(),
+ onPremElasticCloud: instructionsSchema,
// Elastic stack artifacts produced by product when it is setup and run.
artifacts: artifactsSchema,
diff --git a/src/core_plugins/kibana/public/home/components/home.js b/src/core_plugins/kibana/public/home/components/home.js
index cffdfaab7d7c0..7b70e02da7366 100644
--- a/src/core_plugins/kibana/public/home/components/home.js
+++ b/src/core_plugins/kibana/public/home/components/home.js
@@ -28,7 +28,7 @@ import { FeatureCatalogueCategory } from 'ui/registry/feature_catalogue';
import chrome from 'ui/chrome';
const kbnBaseUrl = chrome.getInjected('kbnBaseUrl');
-export function Home({ addBasePath, directories }) {
+export function Home({ addBasePath, directories, isCloudEnabled }) {
const renderDirectories = (category) => {
return directories
@@ -54,9 +54,43 @@ export function Home({ addBasePath, directories }) {
width: '250px',
'minWidth': '200px'
};
+
+ let apmCard;
+ if (!isCloudEnabled) {
+ apmCard = (
+
+
+
+
+
+ APM
+
+
+
+
+ APM automatically collects in-depth performance metrics and errors from inside your applications.
+
+
+
+
+
+ Add APM
+
+
+
+ );
+ }
return (
+
+ {apmCard}
+
@@ -243,5 +277,6 @@ Home.propTypes = {
path: PropTypes.string.isRequired,
showOnHomePage: PropTypes.bool.isRequired,
category: PropTypes.string.isRequired
- }))
+ })),
+ isCloudEnabled: PropTypes.bool.isRequired,
};
diff --git a/src/core_plugins/kibana/public/home/components/home_app.js b/src/core_plugins/kibana/public/home/components/home_app.js
index 4256f9a94f713..6dd3e9daaea3b 100644
--- a/src/core_plugins/kibana/public/home/components/home_app.js
+++ b/src/core_plugins/kibana/public/home/components/home_app.js
@@ -15,11 +15,14 @@ import chrome from 'ui/chrome';
export function HomeApp({ addBasePath, directories }) {
+ const isCloudEnabled = chrome.getInjected('isCloudEnabled', false);
+
const renderTutorialDirectory = (props) => {
return (
);
};
@@ -28,7 +31,7 @@ export function HomeApp({ addBasePath, directories }) {
return (
diff --git a/src/core_plugins/kibana/public/home/components/tutorial/__snapshots__/tutorial.test.js.snap b/src/core_plugins/kibana/public/home/components/tutorial/__snapshots__/tutorial.test.js.snap
index 8f40f1838e3f8..f8c62ed720795 100644
--- a/src/core_plugins/kibana/public/home/components/tutorial/__snapshots__/tutorial.test.js.snap
+++ b/src/core_plugins/kibana/public/home/components/tutorial/__snapshots__/tutorial.test.js.snap
@@ -1,6 +1,6 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
-exports[`should render ELASTIC_CLOUD instructions when isCloudEnabled is true 1`] = `
+exports[`isCloudEnabled is false should not render instruction toggle when ON_PREM_ELASTIC_CLOUD instructions are not provided 1`] = `
@@ -48,7 +48,7 @@ exports[`should render ELASTIC_CLOUD instructions when isCloudEnabled is true 1`
"id": "platform id",
"instructions": Array [
Object {
- "title": "elasticCloud instructions",
+ "title": "onPrem instructions",
},
],
},
@@ -66,7 +66,7 @@ exports[`should render ELASTIC_CLOUD instructions when isCloudEnabled is true 1`
`;
-exports[`should render ON_PREM instructions with instructions cloud toggle when isCloudEnabled is false 1`] = `
+exports[`isCloudEnabled is false should render ON_PREM instructions with instruction toggle 1`] = `
@@ -149,3 +149,69 @@ exports[`should render ON_PREM instructions with instructions cloud toggle when
`;
+
+exports[`should render ELASTIC_CLOUD instructions when isCloudEnabled is true 1`] = `
+
+
+ Home
+
+ /
+
+ Add Data
+
+
+
+
+`;
diff --git a/src/core_plugins/kibana/public/home/components/tutorial/replace_template_strings.js b/src/core_plugins/kibana/public/home/components/tutorial/replace_template_strings.js
index 9c2bd557b2528..3247b9e3e4a88 100644
--- a/src/core_plugins/kibana/public/home/components/tutorial/replace_template_strings.js
+++ b/src/core_plugins/kibana/public/home/components/tutorial/replace_template_strings.js
@@ -21,6 +21,10 @@ mustacheWriter.escapedValue = function escapedValue(token, context) {
export function replaceTemplateStrings(text, params = {}) {
const variables = {
+ // '{' and '}' can not be used in template since they are used as template tags.
+ // Must use '{curlyOpen}'' and '{curlyClose}'
+ curlyOpen: '{',
+ curlyClose: '}',
config: {
cloud: {
id: chrome.getInjected('cloudId')
diff --git a/src/core_plugins/kibana/public/home/components/tutorial/tutorial.js b/src/core_plugins/kibana/public/home/components/tutorial/tutorial.js
index f99208fc7bdad..01d63f9fb49f4 100644
--- a/src/core_plugins/kibana/public/home/components/tutorial/tutorial.js
+++ b/src/core_plugins/kibana/public/home/components/tutorial/tutorial.js
@@ -112,7 +112,7 @@ export class Tutorial extends React.Component {
}
renderInstructionSetsToggle = () => {
- if (!this.props.isCloudEnabled) {
+ if (!this.props.isCloudEnabled && this.state.tutorial.onPremElasticCloud) {
const radioButtons = [
{ onClick: this.onPrem, label: 'On premise', dataTestSubj: 'onPremBtn' },
{ onClick: this.onPremElasticCloud, label: 'Elastic Cloud', dataTestSubj: 'onPremElasticCloudBtn' },
diff --git a/src/core_plugins/kibana/public/home/components/tutorial/tutorial.test.js b/src/core_plugins/kibana/public/home/components/tutorial/tutorial.test.js
index c20f83e272f41..240be93bf0588 100644
--- a/src/core_plugins/kibana/public/home/components/tutorial/tutorial.test.js
+++ b/src/core_plugins/kibana/public/home/components/tutorial/tutorial.test.js
@@ -43,18 +43,60 @@ const replaceTemplateStrings = (text) => {
return text;
};
-test('should render ON_PREM instructions with instructions cloud toggle when isCloudEnabled is false', () => {
- const component = shallow();
- loadTutorialPromise.then(() => {
- component.update();
- expect(component).toMatchSnapshot(); // eslint-disable-line
+describe('isCloudEnabled is false', () => {
+
+ test('should render ON_PREM instructions with instruction toggle', () => {
+ const component = shallow();
+ loadTutorialPromise.then(() => {
+ component.update();
+ expect(component).toMatchSnapshot(); // eslint-disable-line
+ });
});
+
+ test('should not render instruction toggle when ON_PREM_ELASTIC_CLOUD instructions are not provided', () => {
+ const loadBasicTutorialPromise = Promise.resolve({
+ name: 'jest test tutorial',
+ longDescription: 'tutorial used to drive jest tests',
+ elasticCloud: buildInstructionSet('elasticCloud'),
+ onPrem: buildInstructionSet('onPrem')
+ });
+ const getBasicTutorial = () => {
+ return loadBasicTutorialPromise;
+ };
+ const component = shallow();
+ loadBasicTutorialPromise.then(() => {
+ component.update();
+ expect(component).toMatchSnapshot(); // eslint-disable-line
+ });
+ });
+
+ test('should display ON_PREM_ELASTIC_CLOUD instructions when toggle is clicked', () => {
+ const component = mount();
+ loadTutorialPromise.then(() => {
+ component.update();
+ findTestSubject(component, 'onPremElasticCloudBtn').simulate('click');
+ expect(component.state('visibleInstructions')).toBe('onPremElasticCloud');
+ });
+ });
+
});
test('should render ELASTIC_CLOUD instructions when isCloudEnabled is true', () => {
@@ -70,18 +112,3 @@ test('should render ELASTIC_CLOUD instructions when isCloudEnabled is true', ()
expect(component).toMatchSnapshot(); // eslint-disable-line
});
});
-
-test('should display ON_PREM_ELASTIC_CLOUD instructions when cloud toggle is clicked', () => {
- const component = mount();
- loadTutorialPromise.then(() => {
- component.update();
- findTestSubject(component, 'onPremElasticCloudBtn').simulate('click');
- expect(component.state('visibleInstructions')).toBe('onPremElasticCloud');
- });
-});
diff --git a/src/core_plugins/kibana/public/home/components/tutorial_directory.js b/src/core_plugins/kibana/public/home/components/tutorial_directory.js
index 030624d59e889..cfb9fbd80982c 100644
--- a/src/core_plugins/kibana/public/home/components/tutorial_directory.js
+++ b/src/core_plugins/kibana/public/home/components/tutorial_directory.js
@@ -1,3 +1,4 @@
+import _ from 'lodash';
import React from 'react';
import PropTypes from 'prop-types';
import { Synopsis } from './synopsis';
@@ -47,7 +48,12 @@ export class TutorialDirectory extends React.Component {
}
async componentWillMount() {
- const tutorials = await getTutorials();
+ let tutorials = await getTutorials();
+ if (this.props.isCloudEnabled) {
+ tutorials = tutorials.filter(tutorial => {
+ return _.has(tutorial, 'elasticCloud');
+ });
+ }
tutorials.sort((a, b) => {
return a.name.toLowerCase().localeCompare(b.name.toLowerCase());
});
@@ -126,5 +132,6 @@ export class TutorialDirectory extends React.Component {
TutorialDirectory.propTypes = {
addBasePath: PropTypes.func.isRequired,
- openTab: PropTypes.string
+ openTab: PropTypes.string,
+ isCloudEnabled: PropTypes.bool.isRequired,
};
diff --git a/src/core_plugins/kibana/server/tutorials/apm/apm_client_instructions.js b/src/core_plugins/kibana/server/tutorials/apm/apm_client_instructions.js
new file mode 100644
index 0000000000000..4bd1bd81d6b7d
--- /dev/null
+++ b/src/core_plugins/kibana/server/tutorials/apm/apm_client_instructions.js
@@ -0,0 +1,189 @@
+export const NODE_CLIENT_INSTRUCTIONS = [
+ {
+ title: 'Install the APM agent',
+ textPre: 'Install the APM agent for Node.js as a dependency to your application.',
+ commands: [
+ 'npm install elastic-apm-node --save'
+ ]
+ },
+ {
+ title: 'Configure the agent',
+ textPre: 'Agents are libraries that run inside of your application process.' +
+ ' APM services are created programmatically based on the `serviceName`.' +
+ ' This agent supports Express, Koa, hapi, and custom Node.js.',
+ commands: [
+ `// Add this to the VERY top of the first file loaded in your app`,
+ `var apm = require('elastic-apm-node').start({curlyOpen}`,
+ ` // Set required service name (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: ''`,
+ `{curlyClose})`,
+ ],
+ textPost: 'See [the documentation]({config.docs.base_url}guide/en/apm/agent/nodejs/1.x/index.html)' +
+ ' for advanced usage. Babel users, please refer to [the documentation]' +
+ '({config.docs.base_url}guide/en/apm/agent/nodejs/1.x/advanced-setup.html#es-modules).'
+ }
+];
+
+export const DJANGO_CLIENT_INSTRUCTIONS = [
+ {
+ title: 'Install the APM agent',
+ textPre: 'Install the APM agent for Python as a dependency.',
+ commands: [
+ '$ pip install elastic-apm'
+ ]
+ },
+ {
+ title: 'Configure the agent',
+ textPre: 'Agents are libraries that run inside of your application process.' +
+ ' APM services are created programmatically based on the `SERVICE_NAME`.',
+ commands: [
+ `# Add the agent to the installed apps`,
+ `INSTALLED_APPS = (`,
+ ` 'elasticapm.contrib.django',`,
+ ` # ...`,
+ `)`,
+ ` `,
+ `# Choose a service name and optionally a secret token`,
+ `ELASTIC_APM = {curlyOpen}`,
+ ` 'SERVICE_NAME': '',`,
+ ` 'SECRET_TOKEN': '',`,
+ `{curlyClose}`,
+ ` `,
+ `# To send performance metrics, add our tracing middleware:`,
+ `MIDDLEWARE = (`,
+ ` 'elasticapm.contrib.django.middleware.TracingMiddleware',`,
+ ` #...`,
+ `)`
+ ],
+ textPost: 'See the [documentation]' +
+ '({config.docs.base_url}guide/en/apm/agent/python/2.x/django-support.html) for advanced usage.'
+ }
+];
+
+export const FLASK_CLIENT_INSTRUCTIONS = [
+ {
+ title: 'Install the APM agent',
+ textPre: 'Install the APM agent for Python as a dependency.',
+ commands: [
+ '$ pip install elastic-apm[flask]'
+ ]
+ },
+ {
+ title: 'Configure the agent',
+ textPre: 'Agents are libraries that run inside of your application process.' +
+ ' APM services are created programmatically based on the `SERVICE_NAME`.',
+ commands: [
+ `# initialize using environment variables`,
+ `from elasticapm.contrib.flask import ElasticAPM`,
+ `app = Flask(__name__)`,
+ `apm = ElasticAPM(app)`,
+ ` `,
+ `# or configure to use ELASTIC_APM in your application's settings`,
+ `from elasticapm.contrib.flask import ElasticAPM`,
+ `app.config['ELASTIC_APM'] = {curlyOpen}`,
+ ` # allowed characters in SERVICE_NAME: a-z, A-Z, 0-9, -, _, and space`,
+ ` 'SERVICE_NAME': '',`,
+ ` 'SECRET_TOKEN': '',`,
+ `{curlyClose}`,
+ ` `,
+ `apm = ElasticAPM(app)`,
+ ],
+ textPost: 'See the [documentation]' +
+ '({config.docs.base_url}guide/en/apm/agent/python/2.x/flask-support.html) for advanced usage.'
+ }
+];
+
+export const RAILS_CLIENT_INSTRUCTIONS = [
+ {
+ title: 'Install the APM agent',
+ textPre: 'Add the agent to your Gemfile.',
+ commands: [
+ `gem 'elastic-apm'`
+ ]
+ },
+ {
+ title: 'Configure the agent',
+ textPre: 'APM is automatically installed. Configure the agent, by creating the config file `config/elastic_apm.yml`',
+ commands: [
+ `# config/elastic_apm.yml`,
+ `server_url: 'http://localhost:8200'`,
+ ],
+ textPost: 'See the [documentation]' +
+ '({config.docs.base_url}guide/en/apm/agent/ruby/1.x/index.html) for configuration options and advanced usage.\n\n' +
+ '**Warning: The Ruby agent is currently in Beta and not meant for production use.**'
+ }
+];
+
+export const RACK_CLIENT_INSTRUCTIONS = [
+ {
+ title: 'Install the APM agent',
+ textPre: 'Add the agent to your Gemfile.',
+ commands: [
+ `gem 'elastic-apm'`
+ ]
+ },
+ {
+ title: 'Configure the agent',
+ textPre: 'Rack or compatible framework (like Sinatra). Include the middleware in your app and start the agent',
+ commands: [
+ `# config.ru`,
+ `require 'sinatra/base'`,
+ `class MySinatraApp < Sinatra::Base`,
+ ` use ElasticAPM::Middleware`,
+ ` `,
+ ` # ...`,
+ `end`,
+ `# Takes optional ElasticAPM::Config values`,
+ `ElasticAPM.start(`,
+ ` app: MySinatraApp, # required`,
+ ` server_url: 'http://localhost:8200'`,
+ `)`,
+ `run MySinatraApp`,
+ `at_exit {curlyOpen} ElasticAPM.stop {curlyClose}`,
+ ],
+ textPost: 'See the [documentation]' +
+ '({config.docs.base_url}guide/en/apm/agent/ruby/1.x/index.html) for configuration options and advanced usage.\n\n' +
+ '**Warning: The Rack agent is currently in Beta and not meant for production use.**'
+ }
+];
+
+export const JS_CLIENT_INSTRUCTIONS = [
+ {
+ title: 'Enable experimental frontend support in the APM server',
+ textPre: 'Please refer to [the documentation]({config.docs.base_url}guide/en/apm/server/{config.docs.version}/frontend.html).'
+ },
+ {
+ title: 'Install the APM agent',
+ textPre: 'Install the APM agent for JavaScript as a dependency to your application:',
+ commands: [
+ `npm install elastic-apm-js-base --save`
+ ]
+ },
+ {
+ title: 'Configure the agent',
+ textPre: 'Agents are libraries that run inside of your application.',
+ commands: [
+ `import {curlyOpen} init as initApm {curlyClose} from 'elastic-apm-js-base'`,
+ `var apm = initApm({curlyOpen}`,
+ ` `,
+ ` // Set custom APM Server URL (default: http://localhost:8200)`,
+ ` serverUrl: 'http://localhost:8200',`,
+ ` `,
+ ` // Set required service name`,
+ ` serviceName: 'service-name',`,
+ ` `,
+ ` // Set service version (required for sourcemap feature)`,
+ ` serviceVersion: 'service-version'`,
+ `{curlyClose})`,
+ ],
+ textPost: 'See the [documentation]' +
+ '({config.docs.base_url}guide/en/apm/agent/js-base/0.x/index.html) for advanced usage.\n\n' +
+ '**Warning: The JS agent is currently in Alpha and not meant for production use.**'
+ }
+];
diff --git a/src/core_plugins/kibana/server/tutorials/apm/apm_server_instructions.js b/src/core_plugins/kibana/server/tutorials/apm/apm_server_instructions.js
new file mode 100644
index 0000000000000..ea38747daca5c
--- /dev/null
+++ b/src/core_plugins/kibana/server/tutorials/apm/apm_server_instructions.js
@@ -0,0 +1,65 @@
+const EDIT_CONFIG = {
+ title: 'Edit the configuration',
+ textPre: `If you're using an X-Pack secured version of Elastic Stack, you need to specify` +
+ `credentials in the apm-server.yml config file.`,
+ commands: [
+ 'output.elasticsearch:',
+ ' hosts: [""]',
+ ' username: ',
+ ' password: '
+ ]
+};
+
+const IMPORT_DASHBOARD = {
+ title: 'Import dashboards',
+ textPre: 'APM Server ships with pre-configured dashboards'
+};
+
+const START_SERVER = {
+ title: 'Start APM Server',
+ textPre: 'The server processes and stores application performance metrics in Elasticsearch'
+};
+
+export const DOWNLOAD_SERVER = {
+ title: 'Download and unpack APM Server',
+};
+
+export const UNIX_FAMILY_SERVER_INSTRUCTIONS = [
+ {
+ ...IMPORT_DASHBOARD,
+ commands: [
+ './apm-server setup'
+ ]
+ },
+ EDIT_CONFIG,
+ {
+ ...START_SERVER,
+ commands: [
+ './apm-server -e'
+ ]
+ }
+];
+
+export const WINDOWS_SERVER_INSTRUCTIONS = [
+ {
+ ...DOWNLOAD_SERVER,
+ commands: [
+ 'curl -L -O https://artifacts.elastic.co/downloads/apm-server/apm-server-6.2.0-windows-x86_64.zip',
+ 'sudo dpkg -i apm-server-6.2.0-windows-x86_64.zip'
+ ],
+ textPost: 'Looking for the 32 bits packages? See the [Download page]({config.docs.base_url}downloads/apm/apm-server).'
+ },
+ {
+ ...IMPORT_DASHBOARD,
+ commands: [
+ 'apm-server.exe setup'
+ ]
+ },
+ EDIT_CONFIG,
+ {
+ ...START_SERVER,
+ commands: [
+ 'apm-server.exe -e'
+ ]
+ }
+];
diff --git a/src/core_plugins/kibana/server/tutorials/apm/index.js b/src/core_plugins/kibana/server/tutorials/apm/index.js
new file mode 100644
index 0000000000000..636969d342d49
--- /dev/null
+++ b/src/core_plugins/kibana/server/tutorials/apm/index.js
@@ -0,0 +1,29 @@
+import { TUTORIAL_CATEGORY } from '../../../common/tutorials/tutorial_category';
+import { ON_PREM_INSTRUCTIONS } from './on_prem';
+
+export function apmSpecProvider() {
+ return {
+ id: 'apm',
+ name: 'APM',
+ category: TUTORIAL_CATEGORY.OTHER,
+ shortDescription: 'APM (Application Performance Monitoring) automatically collects in-depth' +
+ ' performance metrics and errors from inside your applications.',
+ longDescription: 'APM consists of three components - the Agents, the Server, and the UI:\n' +
+ '* The Agents are libraries in your application that run inside of your application process.\n' +
+ '* The Server processes data from agents and stores the application data in Elasticsearch.\n' +
+ '* The UI is the dedicated APM UI (X-Pack Basic) and preconfigured dashboards.\n\n' +
+ 'For more information, [please see our documentation]' +
+ '({config.docs.base_url}guide/en/apm/get-started/{config.docs.version}/index.html).' +
+ ' To get started, follow the steps below.',
+ artifacts: {
+ dashboards: [
+ {
+ title: '[APM] Services',
+ linkLabel: 'APM Services dashboard',
+ isOverview: true
+ }
+ ]
+ },
+ onPrem: ON_PREM_INSTRUCTIONS,
+ };
+}
diff --git a/src/core_plugins/kibana/server/tutorials/apm/on_prem.js b/src/core_plugins/kibana/server/tutorials/apm/on_prem.js
new file mode 100644
index 0000000000000..12d9dbe180ace
--- /dev/null
+++ b/src/core_plugins/kibana/server/tutorials/apm/on_prem.js
@@ -0,0 +1,99 @@
+import { INSTRUCTION_VARIANT } from '../../../common/tutorials/instruction_variant';
+import {
+ DOWNLOAD_SERVER,
+ WINDOWS_SERVER_INSTRUCTIONS,
+ UNIX_FAMILY_SERVER_INSTRUCTIONS
+} from './apm_server_instructions';
+import {
+ NODE_CLIENT_INSTRUCTIONS,
+ DJANGO_CLIENT_INSTRUCTIONS,
+ FLASK_CLIENT_INSTRUCTIONS,
+ RAILS_CLIENT_INSTRUCTIONS,
+ RACK_CLIENT_INSTRUCTIONS,
+ JS_CLIENT_INSTRUCTIONS,
+} from './apm_client_instructions';
+
+export const ON_PREM_INSTRUCTIONS = {
+ instructionSets: [
+ {
+ title: 'APM Server',
+ instructionVariants: [
+ {
+ id: INSTRUCTION_VARIANT.OSX,
+ instructions: [
+ {
+ ...DOWNLOAD_SERVER,
+ commands: [
+ 'curl -L -O https://artifacts.elastic.co/downloads/apm-server/apm-server-6.2.0-darwin-x86_64.tar.gz',
+ 'tar xzvf apm-server-6.2.0-darwin-x86_64.tar.gz',
+ 'cd apm-server-6.2.0-darwin-x86_64/',
+ ]
+ },
+ ...UNIX_FAMILY_SERVER_INSTRUCTIONS
+ ]
+ },
+ {
+ id: INSTRUCTION_VARIANT.DEB,
+ instructions: [
+ {
+ ...DOWNLOAD_SERVER,
+ commands: [
+ 'curl -L -O https://artifacts.elastic.co/downloads/apm-server/apm-server-6.2.0-amd64.deb',
+ 'sudo dpkg -i apm-server-6.2.0-amd64.deb',
+ ],
+ textPost: 'Looking for the 32 bits packages? See the [Download page]({config.docs.base_url}downloads/apm/apm-server).'
+ },
+ ...UNIX_FAMILY_SERVER_INSTRUCTIONS
+ ]
+ },
+ {
+ id: INSTRUCTION_VARIANT.RPM,
+ instructions: [
+ {
+ ...DOWNLOAD_SERVER,
+ commands: [
+ 'curl -L -O https://artifacts.elastic.co/downloads/apm-server/apm-server-6.2.0-x86_64.rpm',
+ 'sudo dpkg -i apm-server-6.2.0-x86_64.rpm'
+ ],
+ textPost: 'Looking for the 32 bits packages? See the [Download page]({config.docs.base_url}downloads/apm/apm-server).'
+ },
+ ...UNIX_FAMILY_SERVER_INSTRUCTIONS
+ ]
+ },
+ {
+ id: INSTRUCTION_VARIANT.WINDOWS,
+ instructions: WINDOWS_SERVER_INSTRUCTIONS
+ }
+ ]
+ },
+ {
+ title: 'APM Client',
+ instructionVariants: [
+ {
+ id: INSTRUCTION_VARIANT.NODE,
+ instructions: NODE_CLIENT_INSTRUCTIONS
+ },
+ {
+ id: INSTRUCTION_VARIANT.DJANGO,
+ instructions: DJANGO_CLIENT_INSTRUCTIONS
+ },
+ {
+ id: INSTRUCTION_VARIANT.FLASK,
+ instructions: FLASK_CLIENT_INSTRUCTIONS
+ },
+ {
+ id: INSTRUCTION_VARIANT.RAILS,
+ instructions: RAILS_CLIENT_INSTRUCTIONS
+ },
+ {
+ id: INSTRUCTION_VARIANT.RACK,
+ instructions: RACK_CLIENT_INSTRUCTIONS
+ },
+ {
+ id: INSTRUCTION_VARIANT.JS,
+ instructions: JS_CLIENT_INSTRUCTIONS
+ }
+ ]
+ }
+ ]
+};
diff --git a/src/core_plugins/kibana/server/tutorials/register.js b/src/core_plugins/kibana/server/tutorials/register.js
index 3399ff80df171..ca4ed62b1ba6e 100644
--- a/src/core_plugins/kibana/server/tutorials/register.js
+++ b/src/core_plugins/kibana/server/tutorials/register.js
@@ -11,6 +11,7 @@ import { redisMetricsSpecProvider } from './redis_metrics';
import { dockerMetricsSpecProvider } from './docker_metrics';
import { kubernetesMetricsSpecProvider } from './kubernetes_metrics';
import { netflowSpecProvider } from './netflow';
+import { apmSpecProvider } from './apm';
export function registerTutorials(server) {
server.registerTutorial(systemLogsSpecProvider);
@@ -26,4 +27,5 @@ export function registerTutorials(server) {
server.registerTutorial(dockerMetricsSpecProvider);
server.registerTutorial(kubernetesMetricsSpecProvider);
server.registerTutorial(netflowSpecProvider);
+ server.registerTutorial(apmSpecProvider);
}