Skip to content

Commit

Permalink
[APM] Service inventory redesign (#76744)
Browse files Browse the repository at this point in the history
Co-authored-by: Elastic Machine <[email protected]>
  • Loading branch information
dgieselaar and elasticmachine authored Sep 14, 2020
1 parent 2e34eb2 commit 520d348
Show file tree
Hide file tree
Showing 66 changed files with 1,809 additions and 440 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
* you may not use this file except in compliance with the Elastic License.
*/

import { getSeverity, severity } from './getSeverity';
import { getSeverity, Severity } from './anomaly_detection';

describe('getSeverity', () => {
describe('when score is undefined', () => {
Expand All @@ -15,25 +15,25 @@ describe('getSeverity', () => {

describe('when score < 25', () => {
it('returns warning', () => {
expect(getSeverity(10)).toEqual(severity.warning);
expect(getSeverity(10)).toEqual(Severity.warning);
});
});

describe('when score is between 25 and 50', () => {
it('returns minor', () => {
expect(getSeverity(40)).toEqual(severity.minor);
expect(getSeverity(40)).toEqual(Severity.minor);
});
});

describe('when score is between 50 and 75', () => {
it('returns major', () => {
expect(getSeverity(60)).toEqual(severity.major);
expect(getSeverity(60)).toEqual(Severity.major);
});
});

describe('when score is 75 or more', () => {
it('returns critical', () => {
expect(getSeverity(100)).toEqual(severity.critical);
expect(getSeverity(100)).toEqual(Severity.critical);
});
});
});
77 changes: 77 additions & 0 deletions x-pack/plugins/apm/common/anomaly_detection.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
*/

import { i18n } from '@kbn/i18n';
import { EuiTheme } from '../../../legacy/common/eui_styled_components';

export interface ServiceAnomalyStats {
transactionType?: string;
Expand All @@ -13,6 +14,82 @@ export interface ServiceAnomalyStats {
jobId?: string;
}

export enum Severity {
critical = 'critical',
major = 'major',
minor = 'minor',
warning = 'warning',
}

// TODO: Replace with `getSeverity` from:
// https://github.com/elastic/kibana/blob/0f964f66916480f2de1f4b633e5afafc08cf62a0/x-pack/plugins/ml/common/util/anomaly_utils.ts#L129
export function getSeverity(score?: number) {
if (typeof score !== 'number') {
return undefined;
} else if (score < 25) {
return Severity.warning;
} else if (score >= 25 && score < 50) {
return Severity.minor;
} else if (score >= 50 && score < 75) {
return Severity.major;
} else if (score >= 75) {
return Severity.critical;
} else {
return undefined;
}
}

export function getSeverityColor(theme: EuiTheme, severity?: Severity) {
switch (severity) {
case Severity.warning:
return theme.eui.euiColorVis0;
case Severity.minor:
case Severity.major:
return theme.eui.euiColorVis5;
case Severity.critical:
return theme.eui.euiColorVis9;
default:
return;
}
}

export function getSeverityLabel(severity?: Severity) {
switch (severity) {
case Severity.critical:
return i18n.translate(
'xpack.apm.servicesTable.serviceHealthStatus.critical',
{
defaultMessage: 'Critical',
}
);

case Severity.major:
case Severity.minor:
return i18n.translate(
'xpack.apm.servicesTable.serviceHealthStatus.warning',
{
defaultMessage: 'Warning',
}
);

case Severity.warning:
return i18n.translate(
'xpack.apm.servicesTable.serviceHealthStatus.healthy',
{
defaultMessage: 'Healthy',
}
);

default:
return i18n.translate(
'xpack.apm.servicesTable.serviceHealthStatus.unknown',
{
defaultMessage: 'Unknown',
}
);
}
}

export const ML_ERRORS = {
INVALID_LICENSE: i18n.translate(
'xpack.apm.anomaly_detection.error.invalid_license',
Expand Down
12 changes: 6 additions & 6 deletions x-pack/plugins/apm/common/service_map.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { License } from '../../licensing/common/license';
import * as serviceMap from './service_map';

describe('service map helpers', () => {
describe('isValidPlatinumLicense', () => {
describe('isActivePlatinumLicense', () => {
describe('with an expired license', () => {
it('returns false', () => {
const license = new License({
Expand All @@ -22,7 +22,7 @@ describe('service map helpers', () => {
signature: 'test signature',
});

expect(serviceMap.isValidPlatinumLicense(license)).toEqual(false);
expect(serviceMap.isActivePlatinumLicense(license)).toEqual(false);
});
});

Expand All @@ -39,7 +39,7 @@ describe('service map helpers', () => {
signature: 'test signature',
});

expect(serviceMap.isValidPlatinumLicense(license)).toEqual(false);
expect(serviceMap.isActivePlatinumLicense(license)).toEqual(false);
});
});

Expand All @@ -56,7 +56,7 @@ describe('service map helpers', () => {
signature: 'test signature',
});

expect(serviceMap.isValidPlatinumLicense(license)).toEqual(true);
expect(serviceMap.isActivePlatinumLicense(license)).toEqual(true);
});
});

Expand All @@ -73,7 +73,7 @@ describe('service map helpers', () => {
signature: 'test signature',
});

expect(serviceMap.isValidPlatinumLicense(license)).toEqual(true);
expect(serviceMap.isActivePlatinumLicense(license)).toEqual(true);
});
});

Expand All @@ -90,7 +90,7 @@ describe('service map helpers', () => {
signature: 'test signature',
});

expect(serviceMap.isValidPlatinumLicense(license)).toEqual(true);
expect(serviceMap.isActivePlatinumLicense(license)).toEqual(true);
});
});
});
Expand Down
2 changes: 1 addition & 1 deletion x-pack/plugins/apm/common/service_map.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ export interface ServiceNodeStats {
avgErrorRate: number | null;
}

export function isValidPlatinumLicense(license: ILicense) {
export function isActivePlatinumLicense(license: ILicense) {
return license.isActive && license.hasAtLeast('platinum');
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,13 @@ import { useTheme } from '../../../../hooks/useTheme';
import { fontSize, px } from '../../../../style/variables';
import { asInteger, asDuration } from '../../../../utils/formatters';
import { MLJobLink } from '../../../shared/Links/MachineLearningLinks/MLJobLink';
import { getSeverityColor, popoverWidth } from '../cytoscapeOptions';
import { popoverWidth } from '../cytoscapeOptions';
import { TRANSACTION_REQUEST } from '../../../../../common/transaction_types';
import { ServiceAnomalyStats } from '../../../../../common/anomaly_detection';
import { getSeverity } from './getSeverity';
import {
getSeverity,
getSeverityColor,
ServiceAnomalyStats,
} from '../../../../../common/anomaly_detection';

const HealthStatusTitle = styled(EuiTitle)`
display: inline;
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -11,25 +11,15 @@ import {
} from '../../../../common/elasticsearch_fieldnames';
import { EuiTheme } from '../../../../../observability/public';
import { defaultIcon, iconForNode } from './icons';
import { ServiceAnomalyStats } from '../../../../common/anomaly_detection';
import { severity, getSeverity } from './Popover/getSeverity';
import {
getSeverity,
getSeverityColor,
ServiceAnomalyStats,
Severity,
} from '../../../../common/anomaly_detection';

export const popoverWidth = 280;

export function getSeverityColor(theme: EuiTheme, nodeSeverity?: string) {
switch (nodeSeverity) {
case severity.warning:
return theme.eui.euiColorVis0;
case severity.minor:
case severity.major:
return theme.eui.euiColorVis5;
case severity.critical:
return theme.eui.euiColorVis9;
default:
return;
}
}

function getNodeSeverity(el: cytoscape.NodeSingular) {
const serviceAnomalyStats: ServiceAnomalyStats | undefined = el.data(
'serviceAnomalyStats'
Expand Down Expand Up @@ -60,7 +50,7 @@ const getBorderStyle: cytoscape.Css.MapperFunction<
cytoscape.Css.LineStyle
> = (el: cytoscape.NodeSingular) => {
const nodeSeverity = getNodeSeverity(el);
if (nodeSeverity === severity.critical) {
if (nodeSeverity === Severity.critical) {
return 'double';
} else {
return 'solid';
Expand All @@ -70,9 +60,9 @@ const getBorderStyle: cytoscape.Css.MapperFunction<
function getBorderWidth(el: cytoscape.NodeSingular) {
const nodeSeverity = getNodeSeverity(el);

if (nodeSeverity === severity.minor || nodeSeverity === severity.major) {
if (nodeSeverity === Severity.minor || nodeSeverity === Severity.major) {
return 4;
} else if (nodeSeverity === severity.critical) {
} else if (nodeSeverity === Severity.critical) {
return 8;
} else {
return 4;
Expand Down
29 changes: 2 additions & 27 deletions x-pack/plugins/apm/public/components/app/ServiceMap/icons.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,37 +5,29 @@
*/

import cytoscape from 'cytoscape';
import { getNormalizedAgentName } from '../../../../common/agent_name';
import {
AGENT_NAME,
SPAN_SUBTYPE,
SPAN_TYPE,
} from '../../../../common/elasticsearch_fieldnames';
import awsIcon from './icons/aws.svg';
import cassandraIcon from './icons/cassandra.svg';
import darkIcon from './icons/dark.svg';
import databaseIcon from './icons/database.svg';
import defaultIconImport from './icons/default.svg';
import documentsIcon from './icons/documents.svg';
import dotNetIcon from './icons/dot-net.svg';
import elasticsearchIcon from './icons/elasticsearch.svg';
import globeIcon from './icons/globe.svg';
import goIcon from './icons/go.svg';
import graphqlIcon from './icons/graphql.svg';
import grpcIcon from './icons/grpc.svg';
import handlebarsIcon from './icons/handlebars.svg';
import javaIcon from './icons/java.svg';
import kafkaIcon from './icons/kafka.svg';
import mongodbIcon from './icons/mongodb.svg';
import mysqlIcon from './icons/mysql.svg';
import nodeJsIcon from './icons/nodejs.svg';
import phpIcon from './icons/php.svg';
import postgresqlIcon from './icons/postgresql.svg';
import pythonIcon from './icons/python.svg';
import redisIcon from './icons/redis.svg';
import rubyIcon from './icons/ruby.svg';
import rumJsIcon from './icons/rumjs.svg';
import websocketIcon from './icons/websocket.svg';
import javaIcon from '../../shared/AgentIcon/icons/java.svg';
import { getAgentIcon } from '../../shared/AgentIcon/get_agent_icon';

export const defaultIcon = defaultIconImport;

Expand Down Expand Up @@ -74,23 +66,6 @@ const typeIcons: { [key: string]: { [key: string]: string } } = {
},
};

const agentIcons: { [key: string]: string } = {
dark: darkIcon,
dotnet: dotNetIcon,
go: goIcon,
java: javaIcon,
'js-base': rumJsIcon,
nodejs: nodeJsIcon,
php: phpIcon,
python: pythonIcon,
ruby: rubyIcon,
};

function getAgentIcon(agentName?: string) {
const normalizedAgentName = getNormalizedAgentName(agentName);
return normalizedAgentName && agentIcons[normalizedAgentName];
}

function getSpanIcon(type?: string, subtype?: string) {
if (!type) {
return;
Expand Down

This file was deleted.

6 changes: 3 additions & 3 deletions x-pack/plugins/apm/public/components/app/ServiceMap/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import { EuiFlexGroup, EuiFlexItem } from '@elastic/eui';
import { useTheme } from '../../../hooks/useTheme';
import {
invalidLicenseMessage,
isValidPlatinumLicense,
isActivePlatinumLicense,
} from '../../../../common/service_map';
import { useFetcher } from '../../../hooks/useFetcher';
import { useLicense } from '../../../hooks/useLicense';
Expand All @@ -36,7 +36,7 @@ export function ServiceMap({ serviceName }: ServiceMapProps) {

const { data = { elements: [] } } = useFetcher(() => {
// When we don't have a license or a valid license, don't make the request.
if (!license || !isValidPlatinumLicense(license)) {
if (!license || !isActivePlatinumLicense(license)) {
return;
}

Expand Down Expand Up @@ -66,7 +66,7 @@ export function ServiceMap({ serviceName }: ServiceMapProps) {
return null;
}

return isValidPlatinumLicense(license) ? (
return isActivePlatinumLicense(license) ? (
<div
style={{
height: height - parseInt(theme.eui.gutterTypes.gutterLarge, 10),
Expand Down
Loading

0 comments on commit 520d348

Please sign in to comment.