Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/master' into upgrade-vega
Browse files Browse the repository at this point in the history
  • Loading branch information
wylieconlon committed Apr 7, 2020
2 parents 5c989bd + 5e1708f commit 9cfbf6a
Show file tree
Hide file tree
Showing 58 changed files with 2,102 additions and 1,018 deletions.
Binary file added docs/apm/images/service-maps-java.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/apm/images/service-maps.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
48 changes: 48 additions & 0 deletions docs/apm/service-maps.asciidoc
@@ -0,0 +1,48 @@
[[service-maps]]
=== Service maps

beta::[]

A service map is a real-time diagram of the interactions occurring in your application’s architecture.
It allows you to easily visualize data flow and high-level statistics, like average transaction duration,
requests per minute, errors per minute, and metrics, allowing you to quickly assess the status of your services.

Our beta offering creates two types of service maps:

* Global: All services and connections are shown.
* Service-specific: Selecting a specific service will highlight it's connections.

[role="screenshot"]
image::apm/images/service-maps.png[Example view of service maps in the APM app in Kibana]

[float]
[[visualize-your-architecture]]
=== Visualize your architecture

Select the **Service Map** tab to get started.
By default, all services and connections are shown.
Whether your onboarding a new engineer, or just trying to grasp the big picture,
click around, zoom in and out, and begin to visualize how your services are connected.

If there's a specific service that interests you, select that service to highlight its connections.
Clicking **Focus map** will refocus the map on that specific service and lock the connection highlighting.
From here, select **Service Details**, or click on the **Transaction** tab to jump to the Transaction overview.
You can also use the tabs at the top of the page to easily jump to the **Errors** or **Metrics** overview.

While it's not possible to query in service maps, it is possible to filter by environment.
This can be useful if you have two or more services, in separate environments, but with the same name.
Use the environment drop down to only see the data you're interested in, like `dev` or `production`.

[role="screenshot"]
image::apm/images/service-maps-java.png[Example view of service maps with Java highlighted in the APM app in Kibana]

[float]
[[service-maps-legend]]
=== Legend

Nodes appear on the map in one of two shapes:

* **Circle**: Instrumented services. Interior icons are based on the language of the agent used.
* **Diamond**: Databases, external, and messaging. Interior icons represent the generic type,
with specific icons for known entities, like Elasticsearch.
Type and subtype are based on `span.type`, and `span.subtype`.
2 changes: 2 additions & 0 deletions docs/apm/using-the-apm-ui.asciidoc
Expand Up @@ -31,6 +31,8 @@ include::transactions.asciidoc[]

include::spans.asciidoc[]

include::service-maps.asciidoc[]

include::errors.asciidoc[]

include::metrics.asciidoc[]
Expand Down
Expand Up @@ -90,6 +90,7 @@ function FormRow({
<EuiFieldNumber
placeholder={setting.placeholder}
value={(amount as unknown) as number}
min={'min' in setting ? setting.min : 1}
onChange={e =>
onChange(
setting.key,
Expand Down
Expand Up @@ -3,14 +3,26 @@
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
import React from 'react';
import { EuiLink, EuiText } from '@elastic/eui';
import Mustache from 'mustache';
import React from 'react';
import styled from 'styled-components';
import { CustomLink } from '../../../../../../../../plugins/apm/common/custom_link/custom_link_types';
import { Transaction } from '../../../../../../../../plugins/apm/typings/es_schemas/ui/transaction';
import {
SectionLinks,
SectionLink
} from '../../../../../../../../plugins/observability/public';
import { px, truncate, units } from '../../../../style/variables';

const LinkContainer = styled.li`
margin-top: ${px(units.half)};
&:first-of-type {
margin-top: 0;
}
`;

const TruncateText = styled(EuiText)`
font-weight: 500;
line-height: ${px(units.unit)};
${truncate(px(units.unit * 25))}
`;

export const CustomLinkSection = ({
customLinks,
Expand All @@ -19,7 +31,7 @@ export const CustomLinkSection = ({
customLinks: CustomLink[];
transaction: Transaction;
}) => (
<SectionLinks>
<ul>
{customLinks.map(link => {
let href = link.url;
try {
Expand All @@ -28,13 +40,12 @@ export const CustomLinkSection = ({
// ignores any error that happens
}
return (
<SectionLink
key={link.id}
label={link.label}
href={href}
target="_blank"
/>
<LinkContainer key={link.id}>
<EuiLink href={href} target="_blank">
<TruncateText size="s">{link.label}</TruncateText>
</EuiLink>
</LinkContainer>
);
})}
</SectionLinks>
</ul>
);
Expand Up @@ -7,15 +7,15 @@ import { applyTemplateStrings } from '../../i18n/templates';

import darkTemplate from './theme_dark.json';
import lightTemplate from './theme_light.json';
import pitchTemplate from './pitch_presentation.json';
// import pitchTemplate from './pitch_presentation.json';
import statusTemplate from './status_report.json';
import summaryTemplate from './summary_report.json';

// Registry expects a function that returns a spec object
export const templateSpecs = applyTemplateStrings([
darkTemplate,
lightTemplate,
pitchTemplate,
// pitchTemplate,
statusTemplate,
summaryTemplate,
]);
19 changes: 11 additions & 8 deletions x-pack/legacy/plugins/canvas/i18n/templates/template_strings.ts
Expand Up @@ -37,14 +37,6 @@ export const getTemplateStrings = (): TemplateStringDict => ({
defaultMessage: 'Light color themed presentation deck',
}),
},
Pitch: {
name: i18n.translate('xpack.canvas.templates.pitchName', {
defaultMessage: 'Pitch',
}),
help: i18n.translate('xpack.canvas.templates.pitchHelp', {
defaultMessage: 'Branded presentation with large photos',
}),
},
Status: {
name: i18n.translate('xpack.canvas.templates.statusName', {
defaultMessage: 'Status',
Expand All @@ -62,3 +54,14 @@ export const getTemplateStrings = (): TemplateStringDict => ({
}),
},
});

export const getUnusedTemplateStrings = (): TemplateStringDict => ({
Pitch: {
name: i18n.translate('xpack.canvas.templates.pitchName', {
defaultMessage: 'Pitch',
}),
help: i18n.translate('xpack.canvas.templates.pitchHelp', {
defaultMessage: 'Branded presentation with large photos',
}),
},
});
8 changes: 6 additions & 2 deletions x-pack/legacy/plugins/monitoring/common/constants.ts
Expand Up @@ -239,11 +239,15 @@ export const ALERT_TYPE_PREFIX = 'monitoring_';
* This is the alert type id for the license expiration alert
*/
export const ALERT_TYPE_LICENSE_EXPIRATION = `${ALERT_TYPE_PREFIX}alert_type_license_expiration`;
/**
* This is the alert type id for the cluster state alert
*/
export const ALERT_TYPE_CLUSTER_STATE = `${ALERT_TYPE_PREFIX}alert_type_cluster_state`;

/**
* A listing of all alert types
*/
export const ALERT_TYPES = [ALERT_TYPE_LICENSE_EXPIRATION];
export const ALERT_TYPES = [ALERT_TYPE_LICENSE_EXPIRATION, ALERT_TYPE_CLUSTER_STATE];

/**
* Matches the id for the built-in in email action type
Expand All @@ -254,7 +258,7 @@ export const ALERT_ACTION_TYPE_EMAIL = '.email';
/**
* The number of alerts that have been migrated
*/
export const NUMBER_OF_MIGRATED_ALERTS = 1;
export const NUMBER_OF_MIGRATED_ALERTS = 2;

/**
* The advanced settings config name for the email address
Expand Down
44 changes: 27 additions & 17 deletions x-pack/legacy/plugins/monitoring/public/components/alerts/alerts.js
Expand Up @@ -6,10 +6,15 @@

import React from 'react';
import chrome from '../../np_imports/ui/chrome';
import { capitalize } from 'lodash';
import { capitalize, get } from 'lodash';
import { formatDateTimeLocal } from '../../../common/formatting';
import { formatTimestampToDuration } from '../../../common';
import { CALCULATE_DURATION_SINCE, EUI_SORT_DESCENDING } from '../../../common/constants';
import {
CALCULATE_DURATION_SINCE,
EUI_SORT_DESCENDING,
ALERT_TYPE_LICENSE_EXPIRATION,
ALERT_TYPE_CLUSTER_STATE,
} from '../../../common/constants';
import { mapSeverity } from './map_severity';
import { FormattedAlert } from 'plugins/monitoring/components/alerts/formatted_alert';
import { EuiMonitoringTable } from 'plugins/monitoring/components/table';
Expand All @@ -21,6 +26,8 @@ const linkToCategories = {
'elasticsearch/indices': 'Elasticsearch Indices',
'kibana/instances': 'Kibana Instances',
'logstash/instances': 'Logstash Nodes',
[ALERT_TYPE_LICENSE_EXPIRATION]: 'License expiration',
[ALERT_TYPE_CLUSTER_STATE]: 'Cluster state',
};
const getColumns = (kbnUrl, scope, timezone) => [
{
Expand Down Expand Up @@ -94,19 +101,22 @@ const getColumns = (kbnUrl, scope, timezone) => [
}),
field: 'message',
sortable: true,
render: (message, alert) => (
<FormattedAlert
prefix={alert.prefix}
suffix={alert.suffix}
message={message}
metadata={alert.metadata}
changeUrl={target => {
scope.$evalAsync(() => {
kbnUrl.changePath(target);
});
}}
/>
),
render: (_message, alert) => {
const message = get(alert, 'message.text', get(alert, 'message', ''));
return (
<FormattedAlert
prefix={alert.prefix}
suffix={alert.suffix}
message={message}
metadata={alert.metadata}
changeUrl={target => {
scope.$evalAsync(() => {
kbnUrl.changePath(target);
});
}}
/>
);
},
},
{
name: i18n.translate('xpack.monitoring.alerts.categoryColumnTitle', {
Expand Down Expand Up @@ -148,8 +158,8 @@ const getColumns = (kbnUrl, scope, timezone) => [
export const Alerts = ({ alerts, angular, sorting, pagination, onTableChange }) => {
const alertsFlattened = alerts.map(alert => ({
...alert,
status: alert.metadata.severity,
category: alert.metadata.link,
status: get(alert, 'metadata.severity', get(alert, 'severity', 0)),
category: get(alert, 'metadata.link', get(alert, 'type', null)),
}));

const injector = chrome.dangerouslyGetActiveInjector();
Expand Down
Expand Up @@ -8,7 +8,7 @@ import React from 'react';
import { shallow } from 'enzyme';
import { kfetch } from 'ui/kfetch';
import { AlertsStatus, AlertsStatusProps } from './status';
import { ALERT_TYPE_PREFIX } from '../../../common/constants';
import { ALERT_TYPES } from '../../../common/constants';
import { getSetupModeState } from '../../lib/setup_mode';
import { mockUseEffects } from '../../jest.helpers';

Expand Down Expand Up @@ -63,11 +63,7 @@ describe('Status', () => {

it('should render a success message if all alerts have been migrated and in setup mode', async () => {
(kfetch as jest.Mock).mockReturnValue({
data: [
{
alertTypeId: ALERT_TYPE_PREFIX,
},
],
data: ALERT_TYPES.map(type => ({ alertTypeId: type })),
});

(getSetupModeState as jest.Mock).mockReturnValue({
Expand Down
Expand Up @@ -142,7 +142,7 @@ export const AlertsStatus: React.FC<AlertsStatusProps> = (props: AlertsStatusPro
);
}

const allMigrated = kibanaAlerts.length === NUMBER_OF_MIGRATED_ALERTS;
const allMigrated = kibanaAlerts.length >= NUMBER_OF_MIGRATED_ALERTS;
if (allMigrated) {
if (setupModeEnabled) {
return (
Expand Down

0 comments on commit 9cfbf6a

Please sign in to comment.