Skip to content

Commit

Permalink
[APM] Service overview dependencies table
Browse files Browse the repository at this point in the history
  • Loading branch information
dgieselaar committed Nov 16, 2020
1 parent 253495b commit 44a2203
Show file tree
Hide file tree
Showing 34 changed files with 957 additions and 124 deletions.
5 changes: 5 additions & 0 deletions x-pack/plugins/apm/common/elasticsearch_fieldnames.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,11 @@ export const SPAN_NAME = 'span.name';
export const SPAN_ID = 'span.id';
export const SPAN_DESTINATION_SERVICE_RESOURCE =
'span.destination.service.resource';
export const SPAN_DESTINATION_SERVICE_RESPONSE_TIME_COUNT =
'span.destination.service.response_time.count';

export const SPAN_DESTINATION_SERVICE_RESPONSE_TIME_SUM =
'span.destination.service.response_time.sum.us';

// Parent ID for a transaction or span
export const PARENT_ID = 'parent.id';
Expand Down
28 changes: 25 additions & 3 deletions x-pack/plugins/apm/common/utils/formatters/duration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@

import { i18n } from '@kbn/i18n';
import moment from 'moment';
import { memoize } from 'lodash';
import { memoize, isNumber } from 'lodash';
import { NOT_AVAILABLE_LABEL } from '../../../common/i18n';
import { asDecimalOrInteger, asInteger } from './formatters';
import { asDecimalOrInteger, asInteger, asDecimal } from './formatters';
import { TimeUnit } from './datetime';
import { Maybe } from '../../../typings/common';

Expand Down Expand Up @@ -143,6 +143,29 @@ export const getDurationFormatter: TimeFormatterBuilder = memoize(
}
);

export function asTransactionRate(value: Maybe<number>) {
if (!isNumber(value)) {
return NOT_AVAILABLE_LABEL;
}

let displayedValue: string;

if (value === 0) {
displayedValue = '0';
} else if (value <= 0.1) {
displayedValue = '< 0.1';
} else {
displayedValue = asDecimal(value);
}

return i18n.translate('xpack.apm.transactionRateLabel', {
defaultMessage: `{value} tpm`,
values: {
value: displayedValue,
},
});
}

/**
* Converts value and returns it formatted - 00 unit
*/
Expand All @@ -157,7 +180,6 @@ export function asDuration(
const formatter = getDurationFormatter(value);
return formatter(value, { defaultValue }).formatted;
}

/**
* Convert a microsecond value to decimal milliseconds. Normally we use
* `asDuration`, but this is used in places like tables where we always want
Expand Down
30 changes: 25 additions & 5 deletions x-pack/plugins/apm/common/utils/join_by_key/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,21 +26,41 @@ type JoinedReturnType<
T extends Record<string, any>,
U extends UnionToIntersection<T>,
V extends keyof T & keyof U
> = Array<Partial<U> & Record<V, U[V]>>;
> = Array<
Partial<U> &
{
[k in keyof T]: T[k];
}
>;

export function joinByKey<
T extends Record<string, any>,
U extends UnionToIntersection<T>,
V extends keyof T & keyof U
>(items: T[], key: V): JoinedReturnType<T, U, V> {
return items.reduce<JoinedReturnType<T, U, V>>((prev, current) => {
>(items: T[], key: V): JoinedReturnType<T, U, V>;

export function joinByKey<
T extends Record<string, any>,
U extends UnionToIntersection<T>,
V extends keyof T & keyof U,
W extends JoinedReturnType<T, U, V>,
X extends (a: T, b: T) => ValuesType<W>
>(items: T[], key: V, mergeFn: X): W;

export function joinByKey(
items: Array<Record<string, any>>,
key: string,
mergeFn: Function = (a: Record<string, any>, b: Record<string, any>) =>
Object.assign(a, b)
) {
return items.reduce<Array<Record<string, any>>>((prev, current) => {
let item = prev.find((prevItem) => isEqual(prevItem[key], current[key]));

if (!item) {
item = { ...current } as ValuesType<JoinedReturnType<T, U, V>>;
item = { ...current };
prev.push(item);
} else {
Object.assign(item, current);
item = mergeFn(item, current);
}

return prev;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import {
ServiceHealthStatus,
} from '../../../../common/service_health_status';
import { FETCH_STATUS } from '../../../hooks/useFetcher';
import { defaultIcon, iconForNode } from './icons';
import { iconForNode } from './icons';

export const popoverWidth = 280;

Expand Down Expand Up @@ -116,9 +116,7 @@ const getStyle = (theme: EuiTheme): cytoscape.Stylesheet[] => {
'background-color': theme.eui.euiColorGhost,
// The DefinitelyTyped definitions don't specify that a function can be
// used here.
'background-image': isIE11
? undefined
: (el: cytoscape.NodeSingular) => iconForNode(el) ?? defaultIcon,
'background-image': (el: cytoscape.NodeSingular) => iconForNode(el),
'background-height': (el: cytoscape.NodeSingular) =>
isService(el) ? '60%' : '40%',
'background-width': (el: cytoscape.NodeSingular) =>
Expand Down
67 changes: 1 addition & 66 deletions x-pack/plugins/apm/public/components/app/ServiceMap/icons.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,73 +10,8 @@ import {
SPAN_SUBTYPE,
SPAN_TYPE,
} from '../../../../common/elasticsearch_fieldnames';
import awsIcon from './icons/aws.svg';
import cassandraIcon from './icons/cassandra.svg';
import databaseIcon from './icons/database.svg';
import defaultIconImport from './icons/default.svg';
import documentsIcon from './icons/documents.svg';
import elasticsearchIcon from './icons/elasticsearch.svg';
import globeIcon from './icons/globe.svg';
import graphqlIcon from './icons/graphql.svg';
import grpcIcon from './icons/grpc.svg';
import handlebarsIcon from './icons/handlebars.svg';
import kafkaIcon from './icons/kafka.svg';
import mongodbIcon from './icons/mongodb.svg';
import mysqlIcon from './icons/mysql.svg';
import postgresqlIcon from './icons/postgresql.svg';
import redisIcon from './icons/redis.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;

const defaultTypeIcons: { [key: string]: string } = {
cache: databaseIcon,
db: databaseIcon,
ext: globeIcon,
external: globeIcon,
messaging: documentsIcon,
resource: globeIcon,
};

const typeIcons: { [key: string]: { [key: string]: string } } = {
aws: {
servicename: awsIcon,
},
db: {
cassandra: cassandraIcon,
elasticsearch: elasticsearchIcon,
mongodb: mongodbIcon,
mysql: mysqlIcon,
postgresql: postgresqlIcon,
redis: redisIcon,
},
external: {
graphql: graphqlIcon,
grpc: grpcIcon,
websocket: websocketIcon,
},
messaging: {
jms: javaIcon,
kafka: kafkaIcon,
},
template: {
handlebars: handlebarsIcon,
},
};

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

const types = type ? typeIcons[type] : {};
if (subtype && types && subtype in types) {
return types[subtype];
}
return defaultTypeIcons[type] || defaultIcon;
}
import { defaultIcon, getSpanIcon } from '../../shared/span_icon/get_span_icon';

// IE 11 does not properly load some SVGs, which causes a runtime error and the
// map to not work at all. We would prefer to do some kind of feature detection
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,10 @@ import { useTrackPageview } from '../../../../../observability/public';
import { isRumAgentName } from '../../../../common/agent_name';
import { ChartsSyncContextProvider } from '../../../context/charts_sync_context';
import { TransactionErrorRateChart } from '../../shared/charts/transaction_error_rate_chart';
import { ServiceMapLink } from '../../shared/Links/apm/ServiceMapLink';
import { TransactionOverviewLink } from '../../shared/Links/apm/TransactionOverviewLink';
import { SearchBar } from '../../shared/search_bar';
import { ServiceOverviewErrorsTable } from './service_overview_errors_table';
import { ServiceOverviewDependenciesTable } from './service_overview_dependencies_table';
import { TableLinkFlexItem } from './table_link_flex_item';

const rowHeight = 310;
Expand Down Expand Up @@ -148,30 +148,7 @@ export function ServiceOverview({
</EuiFlexItem>
<EuiFlexItem grow={6}>
<EuiPanel>
<EuiFlexGroup>
<EuiFlexItem>
<EuiTitle size="xs">
<h2>
{i18n.translate(
'xpack.apm.serviceOverview.dependenciesTableTitle',
{
defaultMessage: 'Dependencies',
}
)}
</h2>
</EuiTitle>
</EuiFlexItem>
<TableLinkFlexItem>
<ServiceMapLink serviceName={serviceName}>
{i18n.translate(
'xpack.apm.serviceOverview.dependenciesTableLinkText',
{
defaultMessage: 'View service map',
}
)}
</ServiceMapLink>
</TableLinkFlexItem>
</EuiFlexGroup>
<ServiceOverviewDependenciesTable serviceName={serviceName} />
</EuiPanel>
</EuiFlexItem>
</EuiFlexGroup>
Expand Down
Loading

0 comments on commit 44a2203

Please sign in to comment.